first commit

This commit is contained in:
Yangtao
2025-11-18 17:48:20 +08:00
commit 6e56cab848
196 changed files with 65809 additions and 0 deletions

144
pkg/helper/AliAudio.go Normal file
View File

@ -0,0 +1,144 @@
package helper
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/spf13/viper"
)
func TransAudioToText(fileUrl string) (result string, err error) {
// 地域ID固定值。
const REGION_ID string = "cn-shanghai"
const ENDPOINT_NAME string = "cn-shanghai"
const PRODUCT string = "nls-filetrans"
const DOMAIN string = "filetrans.cn-shanghai.aliyuncs.com"
const API_VERSION string = "2018-08-17"
const POST_REQUEST_ACTION string = "SubmitTask"
const GET_REQUEST_ACTION string = "GetTaskResult"
// 请求参数
const KEY_APP_KEY string = "appkey" //此处appkey无需替换。
const KEY_FILE_LINK string = "file_link"
const KEY_VERSION string = "version"
const KEY_ENABLE_WORDS string = "enable_words"
// 响应参数
const KEY_TASK string = "Task"
const KEY_TASK_ID string = "TaskId"
const KEY_STATUS_TEXT string = "StatusText"
const KEY_RESULT string = "Result"
// 状态值
const STATUS_SUCCESS string = "SUCCESS"
const STATUS_RUNNING string = "RUNNING"
const STATUS_QUEUEING string = "QUEUEING"
var accessKeyId string = viper.GetString("aliyun.audio.accessKeyId")
var accessKeySecret string = viper.GetString("aliyun.audio.accessKeySecret")
var appKey string = viper.GetString("aliyun.audio.appKey")
var fileLink string = fileUrl
c := sdk.NewConfig()
credential := credentials.NewAccessKeyCredential(accessKeyId, accessKeySecret)
client, err := sdk.NewClientWithOptions(REGION_ID, c, credential)
if err != nil {
panic(err)
}
postRequest := requests.NewCommonRequest()
postRequest.Domain = DOMAIN
postRequest.Version = API_VERSION
postRequest.Product = PRODUCT
postRequest.ApiName = POST_REQUEST_ACTION
postRequest.Method = "POST"
mapTask := make(map[string]string)
mapTask[KEY_APP_KEY] = appKey
mapTask[KEY_FILE_LINK] = fileLink
// 新接入请使用4.0版本已接入默认2.0)如需维持现状,请注释掉该参数设置。
mapTask[KEY_VERSION] = "4.0"
// 设置是否输出词信息默认为false。开启时需要设置version为4.0。
mapTask[KEY_ENABLE_WORDS] = "false"
mapTask["enable_sample_rate_adaptive"] = "true" //大于
task, err := json.Marshal(mapTask)
if err != nil {
panic(err)
}
postRequest.FormParams[KEY_TASK] = string(task)
postResponse, err := client.ProcessCommonRequest(postRequest)
if err != nil {
panic(err)
}
postResponseContent := postResponse.GetHttpContentString()
fmt.Println(postResponseContent)
if postResponse.GetHttpStatus() != 200 {
fmt.Println("录音文件识别请求失败Http错误码: ", postResponse.GetHttpStatus())
return
}
var postMapResult map[string]interface{}
err = json.Unmarshal([]byte(postResponseContent), &postMapResult)
if err != nil {
panic(err)
}
var taskId string = ""
var statusText string = ""
statusText = postMapResult[KEY_STATUS_TEXT].(string)
if statusText == STATUS_SUCCESS {
fmt.Println("录音文件识别请求成功响应!")
taskId = postMapResult[KEY_TASK_ID].(string)
} else {
fmt.Println("录音文件识别请求失败!")
err = errors.New("录音文件识别请求失败")
return
}
getRequest := requests.NewCommonRequest()
getRequest.Domain = DOMAIN
getRequest.Version = API_VERSION
getRequest.Product = PRODUCT
getRequest.ApiName = GET_REQUEST_ACTION
getRequest.Method = "GET"
getRequest.QueryParams[KEY_TASK_ID] = taskId
statusText = ""
for {
getResponse, err := client.ProcessCommonRequest(getRequest)
if err != nil {
panic(err)
}
getResponseContent := getResponse.GetHttpContentString()
fmt.Println("识别查询结果:", getResponseContent)
if getResponse.GetHttpStatus() != 200 {
fmt.Println("识别结果查询请求失败Http错误码", getResponse.GetHttpStatus())
break
}
var getMapResult map[string]interface{}
err = json.Unmarshal([]byte(getResponseContent), &getMapResult)
if err != nil {
panic(err)
}
statusText = getMapResult[KEY_STATUS_TEXT].(string)
if statusText == STATUS_RUNNING || statusText == STATUS_QUEUEING {
time.Sleep(10 * time.Second)
} else if statusText == STATUS_SUCCESS {
var resResult = getMapResult[KEY_RESULT].(map[string]interface{})
fmt.Println("result", resResult["Sentences"].([]interface{}))
ss := resResult["Sentences"].([]interface{})
for _, seg := range ss {
item := seg.(map[string]interface{})
result += item["Text"].(string)
}
break
} else {
break
}
}
if statusText == STATUS_SUCCESS {
fmt.Println("录音文件识别成功!", result)
} else {
fmt.Println("录音文件识别失败!")
}
return
}

View File

@ -0,0 +1,11 @@
package helper
import (
"fmt"
"testing"
)
func TestTransAudioToText(t *testing.T) {
gotResult, err := TransAudioToText("https://check.dongdongdianjing.com/videos/20250606/d69960523fe2756076f1f8d7c37fa742.mp4")
fmt.Sprintf("%+v %+v", gotResult, err)
}

156
pkg/helper/Helper.go Normal file
View File

@ -0,0 +1,156 @@
package helper
import (
"crypto/md5"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"sort"
"strconv"
"strings"
"time"
"github.com/spf13/viper"
)
// 生成header
func GenerateApiHeader(jsonBody string) map[string]string {
sign := GenerateSign(jsonBody)
headerMap := getCommonHeaderMap()
headerMap["Signature"] = sign
return headerMap
}
// 根据body生成签名
func GenerateSign(jsonBody string) string {
var mapRequest map[string]string
err := json.Unmarshal([]byte(jsonBody), &mapRequest)
if err != nil {
return ""
}
commonHeaderMap := getCommonHeaderMap()
for k, v := range commonHeaderMap {
mapRequest[k] = v
}
sign := createSign(mapRequest)
return sign
}
// 获取公共的header字段
func getCommonHeaderMap() map[string]string {
headerMap := make(map[string]string, 0)
headerMap["ClientVersion"] = "1.0.1"
headerMap["DeviceId"] = "MWEB"
headerMap["Platform"] = "H5"
headerMap["MarketChannel"] = ""
headerMap["DeviceModel"] = "MWEB"
headerMap["ApiVersionNum"] = viper.GetString("api-num")
headerMap["TimeStamp"] = strconv.Itoa(time.Now().Second())
headerMap["BundleId"] = "meetalkH5"
headerMap["OsVersion"] = "10.01"
headerMap["INNER-TOKEN"] = "b028c52286c95de48a1c773d7ed02d04"
return headerMap
}
func createSign(params map[string]string) string {
keys := make([]string, 20)
for key, _ := range params {
if key == "Signature" {
continue
}
keys = append(keys, key)
}
//按key升序
sort.Strings(keys)
//把KEY值合并为字符串
waitSignString := ""
for _, value := range keys {
waitSignString += base64.StdEncoding.EncodeToString([]byte(params[value]))
}
//加上密钥
appSecret := "x63363eacf804b4394a120aea240fd9a"
waitSignString += appSecret
//sha1加密
t := sha1.New()
io.WriteString(t, waitSignString)
sign := t.Sum(nil)
return hex.EncodeToString(sign)
}
// 复杂http请求
func HttpDo(httpMethod string, url string, headerMap map[string]string, rawBody string) (remoteResponse string, err error) {
client := &http.Client{}
req, err0 := http.NewRequest(httpMethod, url, strings.NewReader(rawBody))
if err0 != nil {
err = err0
return
}
if len(headerMap) > 0 {
for k, v := range headerMap {
req.Header.Set(k, v)
}
}
resp, err1 := client.Do(req)
if err1 != nil {
err = err1
return
}
defer resp.Body.Close()
body, err2 := ioutil.ReadAll(resp.Body)
if err2 != nil {
err = err2
return
}
remoteResponse = string(body)
return
}
func StringToMD5(waitMD5string string) string {
h := md5.New()
h.Write([]byte(waitMD5string))
cipherStr := h.Sum(nil)
result := hex.EncodeToString(cipherStr)
return result
}
// SHA1加密
func StringToSHA1(waitMD5string string) string {
h := sha1.New()
h.Write([]byte(waitMD5string))
cipherStr := h.Sum(nil)
result := hex.EncodeToString(cipherStr)
return result
}

68
pkg/helper/NetHelper.go Normal file
View File

@ -0,0 +1,68 @@
package helper
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"time"
"github.com/spf13/viper"
)
func Url(url string) string {
return viper.GetString("service.host.api") + url
}
// 发送GET请求
// url:请求地址
// response:请求返回的内容
func Get(url string) (response string) {
client := http.Client{Timeout: 30 * time.Second}
resp, e := client.Get(url)
if e != nil {
panic(e)
}
defer resp.Body.Close()
var buffer [512]byte
result := bytes.NewBuffer(nil)
for {
n, err := resp.Body.Read(buffer[0:])
result.Write(buffer[0:n])
if err != nil && err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
response = result.String()
return
}
// 发送POST请求
// url:请求地址data:POST请求提交的数据,contentType:请求体格式application/json
// response:请求返回的内容
func Post(url string, data interface{}, header map[string]string) (response string) {
jsonStr, _ := json.Marshal(data)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
if err != nil {
panic(err)
}
req.Header.Add("content-type", "application/json")
for key := range header {
req.Header.Add(key, header[key])
}
defer req.Body.Close()
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
result, _ := ioutil.ReadAll(resp.Body)
response = string(result)
return
}

371
pkg/helper/NumberHelper.go Normal file
View File

@ -0,0 +1,371 @@
package helper
import (
"encoding/json"
"github.com/anxpp/beego/logs"
"strconv"
"strings"
)
type NumberInfo struct {
Level int
Rule map[string]bool
}
// 计算号码的登记
func Calc(src int64) NumberInfo {
level := 0
rule := make(map[string]bool)
number := strconv.FormatInt(src, 10)
length := len(number)
// 尾号AAA
checkEndAAA := length >= 3 && number[length-1] == number[length-2] && number[length-2] == number[length-3]
if checkEndAAA {
level++
}
rule["EndAAA"] = checkEndAAA
// 尾号ABAB
checkABAB := length >= 4 && number[length-4] == number[length-2] && number[length-3] == number[length-1]
if checkABAB {
level++
}
rule["EndABAB"] = checkABAB
// 尾号AABB
checkAABB := length >= 4 && number[length-4] == number[length-3] && number[length-2] == number[length-1]
if checkAABB {
level++
}
rule["EndAABB"] = checkAABB
// 520
check520 := strings.HasSuffix(number, "520")
if check520 {
level++
}
rule["520"] = check520
// 1314
check1314 := strings.HasSuffix(number, "1314")
if check1314 {
level++
}
rule["1314"] = check1314
// 5201314
check5201314 := strings.HasSuffix(number, "5201314")
if check5201314 {
level++
}
rule["5201314"] = check5201314
// AAA
checkAAA := _checkRepeat(number, 3)
if checkAAA {
level++
}
rule["AAA"] = checkAAA
// AAAA
checkAAAA := _checkRepeat(number, 4)
if checkAAAA {
level++
}
rule["AAAA"] = checkAAAA
// AAAAA
checkAAAAA := _checkRepeat(number, 5)
if checkAAAAA {
level++
level++
}
rule["AAAAA"] = checkAAAAA
// AAAAAA
checkAAAAAA := _checkRepeat(number, 6)
if checkAAAAAA {
level++
}
rule["AAAAAA"] = checkAAAAAA
// AAAAAAA
checkAAAAAAA := _checkRepeat(number, 7)
if checkAAAAAAA {
level++
}
rule["AAAAAAA"] = checkAAAAAAA
// AAAAAAA
checkAAAAAAAA := _checkRepeat(number, 8)
if checkAAAAAAAA {
level++
}
rule["AAAAAAAA"] = checkAAAAAAAA
// ABCABC
checkABCABC := _checkABCABC(number)
if checkABCABC {
level++
}
rule["ABCABC"] = checkABCABC
// AABBCC
checkAABBCC := _checkAABBCC(number)
if checkAABBCC {
level++
}
rule["AABBCC"] = checkAABBCC
// ABABAB
checkABABAB := _checkABABAB(number)
if checkABABAB {
level++
}
rule["ABABAB"] = checkABABAB
// AAABBB
checkAAABBB := _checkAAABBB(number)
if checkAAABBB {
level++
}
rule["AAABBB"] = checkAAABBB
// ABBABB
checkABBABB := _checkABBABB(number)
if checkABBABB {
level++
}
rule["ABBABB"] = checkABBABB
// ABBCBB
checkABBCBB := _checkABBCBB(number)
if checkABBCBB {
level++
}
rule["ABBCBB"] = checkABBCBB
// BBCBBA
checkBBCBBA := _checkBBCBBA(number)
if checkBBCBBA {
level++
}
rule["BBCBBA"] = checkBBCBBA
// AABAAB
checkAABAAB := _checkAABAAB(number)
if checkAABAAB {
level++
}
rule["AABAAB"] = checkAABAAB
// 102030
check102030 := _check102030(number)
if check102030 {
level++
}
rule["102030"] = check102030
// 010203
check010203 := _check010203(number)
if check010203 {
level++
}
rule["010203"] = check010203
// AABBB
checkAABBB := _checkAABBB(number)
if checkAABBB {
level++
}
rule["AABBB"] = checkAABBB
// 123
check123 := _checkIncrease(number, 3)
if check123 {
level++
}
rule["123"] = check123
// 123
check1234 := _checkIncrease(number, 4)
if check1234 {
level++
}
rule["1234"] = check1234
// 123
check12345 := _checkIncrease(number, 5)
if check12345 {
level++
}
rule["12345"] = check12345
// 123
check123456 := _checkIncrease(number, 6)
if check123456 {
level++
}
rule["123456"] = check123456
// 123
check1234567 := _checkIncrease(number, 7)
if check1234567 {
level++
}
rule["1234567"] = check1234567
info := NumberInfo{level, rule}
bytes, _ := json.Marshal(info)
if src%100000 == 0 {
logs.Info(number + ": " + string(bytes))
}
return info
}
func _checkRepeat(number string, length int) bool {
count := 1
old := ' '
for _, ch := range number {
if ch == old {
count++
if count == length {
return true
}
continue
}
old = ch
count = 1
}
return false
}
func _checkIncrease(number string, length int) bool {
count := 0
old := ' '
for _, ch := range number {
if count <= 0 {
count++
if count == length {
return true
}
old = ch
continue
}
if ch == old+1 {
count++
if count == length {
return true
}
old = ch
continue
}
old = ch
count = 0
}
return false
}
func _checkABCABC(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i] && number[i-2] == number[i+1] && number[i-1] == number[i+2] {
return true
}
}
}
return false
}
func _checkABBABB(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i] && number[i-2] == number[i+1] && number[i-1] == number[i+2] && number[i-2] == number[i-1] {
return true
}
}
}
return false
}
func _checkABBCBB(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-2] == number[i-1] && number[i-1] == number[i+1] && number[i+1] == number[i+2] {
return true
}
}
}
return false
}
func _checkBBCBBA(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i-2] && number[i-2] == number[i] && number[i] == number[i+1] {
return true
}
}
}
return false
}
func _checkAABAAB(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i] && number[i-3] == number[i-2] && number[i-2] == number[i+1] && number[i-1] == number[i+2] {
return true
}
}
}
return false
}
func _check102030(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-2] == number[i] && number[i] == number[i+2] && number[i-3]-number[i-1] == number[i-1]-number[i+1] {
return true
}
}
}
return false
}
func _check010203(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-2]-number[i] == number[i]-number[i+2] && number[i-3] == number[i-1] && number[i-1] == number[i+1] {
return true
}
}
}
return false
}
func _checkAABBCC(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i-2] && number[i-1] == number[i] && number[i+1] == number[i+2] {
return true
}
}
}
return false
}
func _checkABABAB(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i-1] && number[i-1] == number[i+1] && number[i-2] == number[i] && number[i] == number[i+2] {
return true
}
}
}
return false
}
func _checkAAABBB(number string) bool {
length := len(number)
if length >= 6 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i-2] && number[i-2] == number[i-1] && number[i] == number[i+1] && number[i+1] == number[i+2] {
return true
}
}
}
return false
}
func _checkAABBB(number string) bool {
length := len(number)
if length >= 5 {
for i := 3; i < length-2; i++ {
if number[i-3] == number[i-2] && number[i-1] == number[i] && number[i] == number[i+1] {
return true
}
}
}
return false
}

85
pkg/helper/QiNiuHelper.go Normal file
View File

@ -0,0 +1,85 @@
package helper
import (
"encoding/base64"
"fmt"
"strings"
"github.com/anxpp/beego/logs"
"github.com/qiniu/go-sdk/v7/auth"
"github.com/qiniu/go-sdk/v7/storage"
"github.com/spf13/viper"
)
//{"id":"z0.0A2234420A3600F3365DD1FA282B440D","pipeline":"1381904061.XZVideoToImagesQueue","code":0,
// "desc":"The fop was completed successfully","reqid":"Ry0AAMB45er_HtgV","inputBucket":"media","inputKey":"shot/xingzuan_appstore_video.mp4_000001.jpg",
// "items":[{"cmd":"animate/duration/5/merge/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDAyLmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDAzLmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDA0LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDA1LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDA2LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDA3LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDA4LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDA5LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDEwLmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDExLmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDEyLmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDEzLmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDE0LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDE1LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDE2LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDE3LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDE4LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDE5LmpwZw==/key/c2hvdC94aW5nenVhbl9hcHBzdG9yZV92aWRlby5tcDRfMDAwMDIwLmpwZw==/effect/0",
// "code":0,"desc":"The fop was completed successfully","hash":"lmW7N4-x40al165ufZj2SJGbut6L","key":"-KqubldLD_opMcwnpcOJ2FOml7M=/Ftq7oAVtIsQ-hOdz1amflU4f0mxO","returnOld":0}]}
type QiNiuVideoToImagesParam struct {
Id string `json:"id"`
Pipeline string `json:"pipeline"`
Code int `json:"code"`
Desc string `json:"desc"`
Reqid string `json:"reqid"`
InputBucket string `json:"inputBucket"`
InputKey string `json:"inputKey"`
Items []QiNiuVideoToImagesParamItem `json:"items"`
}
type QiNiuVideoToImagesParamItem struct {
Cmd string `json:"cmd"`
Code int `json:"code"`
Desc string `json:"desc"`
Keys []string `json:"keys"`
Key string `json:"key"`
Hash string `json:"hash"`
ReturnOld int `json:"returnOld"`
}
// 获取视频抽帧的token
// 第2秒开始每秒10张抽20张
func QiNiuVideoToImages(key string) (persistentId string) {
mac := auth.New(viper.GetString("qiniu.key"), viper.GetString("qiniu.secret"))
cfg := storage.Config{UseHTTPS: true}
operationManager := storage.NewOperationManager(mac, &cfg)
saveBucket := "dddjmedia"
// 处理指令集合
// vsample/<Format>/ss/<StartTime>/t/<Duration>/s/<Resolution>/rotate/<Degree>/interval/<Interval>/pattern/<Pattern>
// /ss/<StartTime> 是 指定截取视频的开始时刻,单位:秒,精度为 100ms。例如 /ss/1.1
// /t/<Duration> 是 采样总时长,单位:秒,精度为 100ms。例如 t/1.1
// /s/<Resolution> 缩略图分辨率单位像素px格式<Width>x<Height>宽度取值范围为1-1920高度取值范围为1-1080。 默认为原始视频分辨率。
// /rotate/<Degree> 指定顺时针旋转的度数可取值为90、180、270、auto。 默认为不旋转。
// /interval/<Interval> 指定采样间隔,单元:秒。 默认为5秒,精度为 100ms例如/interval/0.1
// /pattern/<Pattern> 是 指定各张截图的资源名格式,支持如下魔法变量: $(count) :六个占位符的数字串,不足位的填充前导零即%06d如 000001
fopVSample := fmt.Sprintf("vsample/png/ss/2/t/2/interval/0.1/pattern/%s", base64.URLEncoding.EncodeToString([]byte("shot/"+key+"_$(count).jpg")))
fopBatch := []string{fopVSample}
fops := strings.Join(fopBatch, ";")
persistentId, err := operationManager.Pfop(saveBucket, key, fops, "FYVideoToImagesQueue", viper.GetString("open.notify.qiniuVideoShot"), true)
if err != nil {
logs.Error(err.Error(), " ", persistentId, "", key)
}
return persistentId
}
func QiNiuImagesToGif(keys []string) (persistentId string) {
mac := auth.New(viper.GetString("qiniu.key"), viper.GetString("qiniu.secret"))
cfg := storage.Config{UseHTTPS: true}
operationManager := storage.NewOperationManager(mac, &cfg)
saveBucket := "dddjmedia"
an := "animate/duration/5/merge"
for i := 1; i < len(keys); i++ {
an += "/key/" + base64.URLEncoding.EncodeToString([]byte(keys[i]))
}
an += "/effect/0"
logs.Info("result of img merge", an)
fopBatch := []string{an}
fops := strings.Join(fopBatch, ";")
persistentId, err := operationManager.Pfop(saveBucket, keys[0], fops, "FYVideoToImagesQueue", viper.GetString("open.notify.qiniuImgMergeShot"), true)
if err != nil {
fmt.Println(err)
logs.Error(err.Error())
}
return persistentId
}

13
pkg/helper/WxHelper.go Normal file
View File

@ -0,0 +1,13 @@
package helper
import "strings"
//是否使用微信打开
func IsWeiXinBrowser(httpUserAgent string) bool {
wxAgentKey := "MicroMessenger"
if strings.Contains(httpUserAgent, wxAgentKey) {
return true
}
return false
}

View File

@ -0,0 +1,23 @@
package helper
import (
"crypto/md5"
"encoding/hex"
"math/rand"
"strconv"
"time"
)
// 获取随机盐值
func PasswordSalt() string {
randInt := rand.New(rand.NewSource(time.Now().UnixNano()))
return strconv.Itoa(randInt.Int() % 10000)
}
// 计算加密后的密码
func PasswordWithMd5(password, salt string) string {
h := md5.New()
h.Write([]byte(password + salt))
cipherStr := h.Sum(nil)
return hex.EncodeToString(cipherStr)
}

144
pkg/helper/string_util.go Normal file
View File

@ -0,0 +1,144 @@
package helper
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"regexp"
"sort"
"strconv"
"strings"
"time"
)
const (
PhotoDomainUrl = "https://photo-app.ddegame.cn/"
TimeLayout = "2006-01-02 15:04:05"
DateLayout = "2006-01-02"
DateLayoutShort = "20060102"
)
func FullPhotoUrl(path string) string {
if len(path) == 0 {
return ""
}
if strings.Index(path, "http") == 0 {
return path
}
return PhotoDomainUrl + path
}
func Md5ForList(s ...string) string {
sort.Strings(s)
h := md5.New()
h.Write([]byte(strings.Join(s, "")))
return hex.EncodeToString(h.Sum(nil))
}
func StringToInt(source string) int {
target, _ := strconv.Atoi(source)
return target
}
func StringToInt64(source string) int64 {
target, _ := strconv.Atoi(source)
return int64(target)
}
func StringToFloat(source string) float64 {
target, _ := strconv.ParseFloat(source, 64)
return target
}
func StringIntPlus(s1, s2 string) string {
return strconv.Itoa(StringToInt(s1) + StringToInt(s2))
}
func StringIntMultiply(s1, s2 string) string {
return strconv.Itoa(StringToInt(s1) * StringToInt(s2))
}
func StringIntSub(s1, s2 string) string {
return strconv.Itoa(StringToInt(s1) - StringToInt(s2))
}
func StringFloatSub(s1, s2 string) string {
return strconv.FormatFloat(StringToFloat(s1)-StringToFloat(s2), 'f', -1, 64)
}
func ListToSet(list []string) (set []string) {
m := make(map[string]bool, 0)
for i := range list {
m[list[i]] = true
}
for k := range m {
set = append(set, k)
}
return
}
func ToJson(source interface{}) []byte {
b, _ := json.Marshal(source)
return b
}
func NowTimeToString() string {
return time.Now().Format(TimeLayout)
}
func NowTimeIncreaseString(t time.Duration) string {
now := time.Now()
now.Add(t)
return now.Format(TimeLayout)
}
func NowDateToString() string {
return time.Now().Format(DateLayout)
}
func NowDateToStringShort() string {
return time.Now().Format(DateLayoutShort)
}
func Md5(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
func ZeroFillByStr(str string, resultLen int, reverse bool) string {
if len(str) > resultLen || resultLen <= 0 {
return str
}
if reverse {
return fmt.Sprintf("%0*s", resultLen, str) //不足前置补零
}
result := str
for i := 0; i < resultLen-len(str); i++ {
result += "0"
}
return result
}
func IsMobile(no string) bool {
return regexp.MustCompile("^1[3456789]\\d{9}$").MatchString(no)
}
func IsEmail(email string) bool {
pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
return regexp.MustCompile(pattern).MatchString(email)
}
func LegalUsername(source string) bool {
return regexp.MustCompile("^\\D[\\w-]{5,17}$").MatchString(source)
}
func LegalShortUsername(source string) bool {
return regexp.MustCompile("^[a-zA-Z][\\w-]{2,17}$").MatchString(source)
}
func LegalPassword(source string) bool {
return regexp.MustCompile("^[a-zA-Z0-9,.!@#$%^&*()_-]{6,18}$").MatchString(source)
}