kefu/wechathook/service/tool.go

362 lines
9.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}