kefu/wechathook/service/tool.go

362 lines
9.0 KiB
Go
Raw Permalink Normal View History

2024-12-10 02:50:12 +00:00
package service
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
)
// PostJSON 发送HTTP POST请求并发送JSON数据
func PostJSON(url string, jsonData interface{}) ([]byte, error) {
// 将JSON数据转换为字节切片
jsonBytes, err := json.Marshal(jsonData)
if err != nil {
return nil, err
}
// 创建一个HTTP请求
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBytes))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
// 发送HTTP请求并获取响应
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// 读取响应的内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return respBody, nil
}
/*
*
去除html标签过滤html标签
*/
func TrimHtml(src string) string {
//将HTML标签全转换成小写
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllStringFunc(src, strings.ToLower)
//去除STYLE
re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
src = re.ReplaceAllString(src, "")
//去除SCRIPT
re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
src = re.ReplaceAllString(src, "")
//去除所有尖括号内的HTML代码并换成换行符
re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllString(src, "\n")
//去除连续的换行符
re, _ = regexp.Compile("\\s{2,}")
src = re.ReplaceAllString(src, "\n")
return strings.TrimSpace(src)
}
// GetIDCardFromText 从文本中提取身份证号
func GetIDCardFromText(str string) (string, error) {
// 正则表达式匹配18位或15位的身份证号
// 18位身份证号格式: XXXXXXYYYYMMDDXXXXXX
// 15位身份证号格式: XXXXXXYYYYMMDDXXX
// 其中X表示数字
var idCardRegex = regexp.MustCompile(`\d{17}[\dXx]|\d{15}`)
matches := idCardRegex.FindAllString(str, -1)
if len(matches) == 0 {
return "", errors.New("没有找到身份证号")
}
// 如果有多个身份证号,返回第一个找到的
// 或者根据具体需求可以返回所有匹配的身份证号
return matches[0], nil
}
// 根据输入的字符串参数决定返回的随机数。如果参数包含 -,则将其解析为范围,并返回该范围内的随机整数。如果参数不包含 -,则将其解析为整数并直接返回
func GetRandomValue(input string) (int, error) {
if strings.Contains(input, "-") {
ranges := strings.Split(input, "-")
if len(ranges) != 2 {
return 0, fmt.Errorf("invalid input format")
}
min, err := strconv.Atoi(ranges[0])
if err != nil {
return 0, fmt.Errorf("invalid minimum value")
}
max, err := strconv.Atoi(ranges[1])
if err != nil {
return 0, fmt.Errorf("invalid maximum value")
}
if min >= max {
return 0, fmt.Errorf("minimum value must be less than maximum value")
}
return rand.Intn(max-min+1) + min, nil
} else {
val, err := strconv.Atoi(input)
if err != nil {
return 0, fmt.Errorf("invalid integer value")
}
return val, nil
}
}
// isWindowsPath 判断字符串是否是有效的Windows文件路径
func IsWindowsPath(path string) bool {
// 检查路径是否以驱动器号开头,如 "C:\"
if len(path) > 2 && path[1] == ':' && path[2] == filepath.Separator {
// 检查路径中是否包含反斜杠
for i := 3; i < len(path); i++ {
if path[i] == filepath.Separator {
return true
}
}
}
return false
}
// isImagePath 判断字符串是否可能是一个图片路径
func IsImagePath(path string) bool {
// 定义常见的图片文件扩展名
imageExtensions := []string{".jpg", ".jpeg", ".png", ".gif", ".bmp"}
// 获取路径的文件名部分
fileName := filepath.Base(path)
// 检查文件名是否以这些扩展名之一结尾
for _, ext := range imageExtensions {
if strings.ToLower(strings.TrimPrefix(fileName, ext)) == fileName {
return true
}
}
// 如果没有匹配的扩展名,则不是图片路径
return false
}
// 正则提取
func GetOneStringByRegex(str, rule string) (string, error) {
reg, err := regexp.Compile(rule)
if reg == nil || err != nil {
return "", errors.New("正则MustCompile错误:" + err.Error())
}
//提取关键信息
result := reg.FindStringSubmatch(str)
if len(result) < 1 {
return "", errors.New("没有获取到子字符串")
}
return result[1], nil
}
func ParseImgMessage(str string) string {
var url string
url, _ = GetOneStringByRegex(str, "img\\[(.*?)\\]")
return url
}
// 下载一个网络文件并保存到本地
func DownloadFile(url string, filename string) error {
// 创建一个HTTP客户端
client := &http.Client{}
// 发送GET请求
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
// 发送请求并获取响应
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// 检查HTTP响应状态码
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("服务器返回状态码: %d", resp.StatusCode)
}
// 创建文件并写入响应体内容
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
// 将响应体内容写入文件
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
// 定义一个结构体来存储图片的路径和描述
type MarkdownImage struct {
Path string
Desc string
}
// 定义一个函数来提取Markdown中的图片路径和描述
func ExtractMarkdownImagePaths(markdown string) []MarkdownImage {
// 正则表达式匹配Markdown图片路径和描述
// 组1: 图片描述组2: 图片路径
re := regexp.MustCompile(`!\[(.*?)\]\((.*?)\)`)
// 使用FindAllStringSubmatch查找所有匹配的图片路径和描述
matches := re.FindAllStringSubmatch(markdown, -1)
// 初始化一个切片来存储MarkdownImage结构体
images := make([]MarkdownImage, len(matches))
// 提取图片路径和描述
for i, match := range matches {
if len(match) < 3 { // 确保有足够的匹配组
continue
}
images[i] = MarkdownImage{
Path: match[2], // 索引2是图片路径
Desc: match[1], // 索引1是图片描述
}
}
return images
}
// 获取当前日期格式化为年月日的字符串
func GetCurrentDateDir() string {
currentTime := time.Now() // 获取当前时间
// 格式化为年月日,例如 "20240624"
dateStr := currentTime.Format("20060102")
return dateStr
}
// 创建按照当前年月日命名的目录
func CreateDateDir(baseDir, dateStr string) error {
dirPath := filepath.Join(baseDir, dateStr) // 构建目录路径
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
// 如果目录不存在,则创建目录
err := os.MkdirAll(dirPath, 0755)
if err != nil {
return err
}
}
return nil
}
// 从URL中提取文件名和扩展名
func ExtractFilenameAndExt(url string) (string, string) {
// 提取URL中的最后一个路径部分作为文件名
filename := filepath.Base(url)
// 分割文件名和扩展名
ext := filepath.Ext(filename)
// 如果没有扩展名,返回空字符串
if ext == filename {
ext = ""
} else {
// 移除点号,只保留扩展名
ext = ext[1:]
}
return filename, ext
}
// 下载图片到按照当前年月日创建的目录
func DownloadImageToDailyDir(url, baseResourceDir, filename string) (string, error) {
// 从URL中提取文件名和扩展名
fileNameWithoutExt, ext := ExtractFilenameAndExt(url)
// 如果提供的filename为空则使用从URL中提取的文件名
if filename == "" {
filename = fileNameWithoutExt
}
// 如果文件名没有扩展名则添加从URL中提取的扩展名
if !strings.Contains(filename, "."+ext) {
filename += "." + ext
}
// 获取当前日期目录名
dateDir := GetCurrentDateDir()
// 创建基础目录和日期目录
if err := CreateDateDir(baseResourceDir, dateDir); err != nil {
return "", err
}
// 构建文件路径
filePath := filepath.Join(baseResourceDir, dateDir, filename)
// 下载图片
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("http status code: %d", resp.StatusCode)
}
// 创建文件并打开文件句柄
file, err := os.Create(filePath)
if err != nil {
return "", err
}
defer file.Close()
// 将响应体的内容写入文件
_, err = io.Copy(file, resp.Body)
if err != nil {
return "", err
}
return filePath, nil
}
// 判断文件文件夹不存在
func IsFileNotExist(path string) (bool, error) {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return true, nil
}
return false, err
}
// 获取程序执行目录
func GetRunPath2() string {
file, _ := exec.LookPath(os.Args[0])
path, _ := filepath.Abs(file)
index := strings.LastIndex(path, string(os.PathSeparator))
ret := path[:index]
return ret
}
// 获取程序根目录
func GetRootPath() string {
rootPath, _ := os.Getwd()
if notExist, _ := IsFileNotExist(rootPath); notExist {
rootPath = GetRunPath2()
if notExist, _ := IsFileNotExist(rootPath); notExist {
rootPath = "."
}
}
return rootPath
}