362 lines
9.0 KiB
Go
362 lines
9.0 KiB
Go
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
|
||
}
|