mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-08-28 00:51:13 +08:00
模块化上传驱动,使用泛型优化工具库降低冗余
This commit is contained in:
@@ -9,41 +9,11 @@ import (
|
||||
"crypto/rand"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/utility/convert"
|
||||
r "math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SplitMemberIds 从截取字串符中读取用户ID
|
||||
func SplitMemberIds(str, pos string) (memberIds []int64) {
|
||||
receiver := strings.Split(strings.TrimSpace(str), pos)
|
||||
if len(receiver) == 0 {
|
||||
return memberIds
|
||||
}
|
||||
if len(receiver) == 1 && strings.TrimSpace(receiver[0]) == "" {
|
||||
return memberIds
|
||||
}
|
||||
|
||||
for _, memberId := range receiver {
|
||||
memberIds = append(memberIds, gconv.Int64(strings.TrimSpace(memberId)))
|
||||
}
|
||||
return convert.UniqueSliceInt64(memberIds)
|
||||
}
|
||||
|
||||
// GetMapKeysByString 获取map的所有key,字串符类型
|
||||
func GetMapKeysByString(m map[string]string) []string {
|
||||
// 数组默认长度为map长度,后面append时,不需要重新申请内存和拷贝,效率很高
|
||||
j := 0
|
||||
keys := make([]string, len(m))
|
||||
for k := range m {
|
||||
keys[j] = k
|
||||
j++
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// RandomCreateBytes 生成随机字串符
|
||||
func RandomCreateBytes(n int, alphabets ...byte) []byte {
|
||||
if len(alphabets) == 0 {
|
||||
@@ -51,13 +21,12 @@ func RandomCreateBytes(n int, alphabets ...byte) []byte {
|
||||
}
|
||||
var bytes = make([]byte, n)
|
||||
var randBy bool
|
||||
r.Seed(time.Now().UnixNano())
|
||||
if num, err := rand.Read(bytes); num != n || err != nil {
|
||||
randBy = true
|
||||
}
|
||||
for i, b := range bytes {
|
||||
if randBy {
|
||||
bytes[i] = alphabets[r.Intn(len(alphabets))]
|
||||
bytes[i] = alphabets[r.New(r.NewSource(time.Now().UnixNano())).Intn(len(alphabets))]
|
||||
} else {
|
||||
bytes[i] = alphabets[b%byte(len(alphabets))]
|
||||
}
|
||||
|
@@ -17,23 +17,21 @@ var (
|
||||
fieldTags = []string{"json"} // 实体字段名称映射
|
||||
)
|
||||
|
||||
// UniqueSliceInt64 切片去重
|
||||
func UniqueSliceInt64(languages []int64) []int64 {
|
||||
result := make([]int64, 0, len(languages))
|
||||
temp := map[int64]struct{}{}
|
||||
for _, item := range languages {
|
||||
if _, ok := temp[item]; !ok {
|
||||
temp[item] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
// GetMapKeys 获取map的所有key
|
||||
func GetMapKeys[K comparable](m map[K]any) []K {
|
||||
j := 0
|
||||
keys := make([]K, len(m))
|
||||
for k := range m {
|
||||
keys[j] = k
|
||||
j++
|
||||
}
|
||||
return result
|
||||
return keys
|
||||
}
|
||||
|
||||
// UniqueSliceString 切片去重
|
||||
func UniqueSliceString(languages []string) []string {
|
||||
result := make([]string, 0, len(languages))
|
||||
temp := map[string]struct{}{}
|
||||
// UniqueSlice 切片去重
|
||||
func UniqueSlice[K comparable](languages []K) []K {
|
||||
result := make([]K, 0, len(languages))
|
||||
temp := map[K]struct{}{}
|
||||
for _, item := range languages {
|
||||
if _, ok := temp[item]; !ok {
|
||||
temp[item] = struct{}{}
|
||||
@@ -121,19 +119,19 @@ func reflectTag(reflectType reflect.Type, filterTags []string, tags []string) ([
|
||||
|
||||
// reflectTagName 解析实体中的描述标签,优先级:description > dc > json > Name
|
||||
func reflectTagName(field reflect.StructField, filterTags []string, isDef bool) string {
|
||||
if validate.InSliceString(filterTags, "description") {
|
||||
if validate.InSlice(filterTags, "description") {
|
||||
if description, ok := field.Tag.Lookup("description"); ok && description != "" {
|
||||
return description
|
||||
}
|
||||
}
|
||||
|
||||
if validate.InSliceString(filterTags, "dc") {
|
||||
if validate.InSlice(filterTags, "dc") {
|
||||
if dc, ok := field.Tag.Lookup("dc"); ok && dc != "" {
|
||||
return dc
|
||||
}
|
||||
}
|
||||
|
||||
if validate.InSliceString(filterTags, "json") {
|
||||
if validate.InSlice(filterTags, "json") {
|
||||
if jsonName, ok := field.Tag.Lookup("json"); ok && jsonName != "" {
|
||||
return jsonName
|
||||
}
|
||||
|
@@ -12,12 +12,6 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const ( //文件大小单位
|
||||
_ = iota
|
||||
KB = 1 << (10 * iota)
|
||||
MB
|
||||
)
|
||||
|
||||
type fileInfo struct { //文件信息
|
||||
name string
|
||||
size int64
|
||||
|
@@ -1,142 +0,0 @@
|
||||
// Package file
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package file
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"io"
|
||||
"path"
|
||||
)
|
||||
|
||||
// 文件分类
|
||||
const (
|
||||
KindImg = "images" // 图片
|
||||
KindDoc = "document" // 文档
|
||||
KindAudio = "audio" // 音频
|
||||
KindVideo = "video" // 视频
|
||||
KindOther = "other" // 其他
|
||||
)
|
||||
|
||||
var (
|
||||
// 图片类型
|
||||
imgType = g.MapStrStr{
|
||||
"jpeg": "image/jpeg",
|
||||
"jpg": "image/jpeg",
|
||||
"png": "image/png",
|
||||
"gif": "image/gif",
|
||||
"webp": "image/webp",
|
||||
"cr2": "image/x-canon-cr2",
|
||||
"tif": "image/tiff",
|
||||
"bmp": "image/bmp",
|
||||
"heif": "image/heif",
|
||||
"jxr": "image/vnd.ms-photo",
|
||||
"psd": "image/vnd.adobe.photoshop",
|
||||
"ico": "image/vnd.microsoft.icon",
|
||||
"dwg": "image/vnd.dwg",
|
||||
}
|
||||
|
||||
// 文档类型
|
||||
docType = g.MapStrStr{
|
||||
"doc": "application/msword",
|
||||
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"xls": "application/vnd.ms-excel",
|
||||
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"ppt": "application/vnd.ms-powerpoint",
|
||||
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
}
|
||||
|
||||
// 音频类型
|
||||
audioType = g.MapStrStr{
|
||||
"mid": "audio/midi",
|
||||
"mp3": "audio/mpeg",
|
||||
"m4a": "audio/mp4",
|
||||
"ogg": "audio/ogg",
|
||||
"flac": "audio/x-flac",
|
||||
"wav": "audio/x-wav",
|
||||
"amr": "audio/amr",
|
||||
"aac": "audio/aac",
|
||||
"aiff": "audio/x-aiff",
|
||||
}
|
||||
|
||||
// 视频类型
|
||||
videoType = g.MapStrStr{
|
||||
"mp4": "video/mp4",
|
||||
"m4v": "video/x-m4v",
|
||||
"mkv": "video/x-matroska",
|
||||
"webm": "video/webm",
|
||||
"mov": "video/quicktime",
|
||||
"avi": "video/x-msvideo",
|
||||
"wmv": "video/x-ms-wmv",
|
||||
"mpg": "video/mpeg",
|
||||
"flv": "video/x-flv",
|
||||
"3gp": "video/3gpp",
|
||||
}
|
||||
)
|
||||
|
||||
// IsImgType 判断是否为图片
|
||||
func IsImgType(ext string) bool {
|
||||
_, ok := imgType[ext]
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetImgType 获取图片类型
|
||||
func GetImgType(ext string) (string, error) {
|
||||
if mime, ok := imgType[ext]; ok {
|
||||
return mime, nil
|
||||
}
|
||||
return "", gerror.New("Invalid image type")
|
||||
}
|
||||
|
||||
// GetFileType 获取文件类型
|
||||
func GetFileType(ext string) (string, error) {
|
||||
if mime, ok := imgType[ext]; ok {
|
||||
return mime, nil
|
||||
}
|
||||
if mime, ok := docType[ext]; ok {
|
||||
return mime, nil
|
||||
}
|
||||
if mime, ok := audioType[ext]; ok {
|
||||
return mime, nil
|
||||
}
|
||||
if mime, ok := videoType[ext]; ok {
|
||||
return mime, nil
|
||||
}
|
||||
return "", gerror.Newf("Invalid file type:%v", ext)
|
||||
}
|
||||
|
||||
// GetFileKind 获取文件所属分类
|
||||
func GetFileKind(ext string) string {
|
||||
if _, ok := imgType[ext]; ok {
|
||||
return KindImg
|
||||
}
|
||||
if _, ok := docType[ext]; ok {
|
||||
return KindDoc
|
||||
}
|
||||
if _, ok := audioType[ext]; ok {
|
||||
return KindAudio
|
||||
}
|
||||
if _, ok := videoType[ext]; ok {
|
||||
return KindVideo
|
||||
}
|
||||
return KindOther
|
||||
}
|
||||
|
||||
// Ext 获取文件后缀
|
||||
func Ext(baseName string) string {
|
||||
return gstr.StrEx(path.Ext(baseName), ".")
|
||||
}
|
||||
|
||||
// UploadFileByte 获取上传文件的byte
|
||||
func UploadFileByte(file *ghttp.UploadFile) ([]byte, error) {
|
||||
open, err := file.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return io.ReadAll(open)
|
||||
}
|
@@ -7,40 +7,67 @@ package format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Round2String 四舍五入保留小数,默认2位
|
||||
func Round2String(value float64, args ...interface{}) (v string) {
|
||||
func Round2String(value float64, args ...interface{}) string {
|
||||
var places = 2
|
||||
if len(args) > 0 {
|
||||
places = gconv.Int(args[0])
|
||||
}
|
||||
|
||||
cDig := strconv.Itoa(places)
|
||||
val := fmt.Sprintf("%0."+cDig+"f", value)
|
||||
return val
|
||||
return fmt.Sprintf("%0."+strconv.Itoa(places)+"f", value)
|
||||
}
|
||||
|
||||
// Round2Float64 四舍五入保留小数,默认2位
|
||||
func Round2Float64(value float64, args ...interface{}) (v float64) {
|
||||
func Round2Float64(value float64, args ...interface{}) float64 {
|
||||
return gconv.Float64(Round2String(value, args...))
|
||||
}
|
||||
|
||||
// FileSize 字节的单位转换 保留两位小数
|
||||
func FileSize(fileSize int64) (size string) {
|
||||
if fileSize < 1024 {
|
||||
return fmt.Sprintf("%.2fB", float64(fileSize)/float64(1))
|
||||
} else if fileSize < (1024 * 1024) {
|
||||
return fmt.Sprintf("%.2fKB", float64(fileSize)/float64(1024))
|
||||
} else if fileSize < (1024 * 1024 * 1024) {
|
||||
return fmt.Sprintf("%.2fMB", float64(fileSize)/float64(1024*1024))
|
||||
} else if fileSize < (1024 * 1024 * 1024 * 1024) {
|
||||
return fmt.Sprintf("%.2fGB", float64(fileSize)/float64(1024*1024*1024))
|
||||
} else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) {
|
||||
return fmt.Sprintf("%.2fTB", float64(fileSize)/float64(1024*1024*1024*1024))
|
||||
} else {
|
||||
return fmt.Sprintf("%.2fEB", float64(fileSize)/float64(1024*1024*1024*1024*1024))
|
||||
func FileSize(data int64) string {
|
||||
var factor float64 = 1024
|
||||
res := float64(data)
|
||||
for _, unit := range []string{"", "K", "M", "G", "T", "P"} {
|
||||
if res < factor {
|
||||
return fmt.Sprintf("%.2f%sB", res, unit)
|
||||
}
|
||||
res /= factor
|
||||
}
|
||||
return fmt.Sprintf("%.2f%sB", res, "P")
|
||||
}
|
||||
|
||||
// AgoTime 多久以前
|
||||
func AgoTime(gt *gtime.Time) string {
|
||||
if gt == nil {
|
||||
return ""
|
||||
}
|
||||
n := gtime.Now().Timestamp()
|
||||
t := gt.Timestamp()
|
||||
|
||||
var ys int64 = 31536000
|
||||
var ds int64 = 86400
|
||||
var hs int64 = 3600
|
||||
var ms int64 = 60
|
||||
var ss int64 = 1
|
||||
var rs string
|
||||
|
||||
d := n - t
|
||||
switch {
|
||||
case d > ys:
|
||||
rs = fmt.Sprintf("%d年前", int(d/ys))
|
||||
case d > ds:
|
||||
rs = fmt.Sprintf("%d天前", int(d/ds))
|
||||
case d > hs:
|
||||
rs = fmt.Sprintf("%d小时前", int(d/hs))
|
||||
case d > ms:
|
||||
rs = fmt.Sprintf("%d分钟前", int(d/ms))
|
||||
case d > ss:
|
||||
rs = fmt.Sprintf("%d秒前", int(d/ss))
|
||||
default:
|
||||
rs = "刚刚"
|
||||
}
|
||||
return rs
|
||||
}
|
||||
|
@@ -1,56 +0,0 @@
|
||||
// Package signal
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package signal
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type StopSignal int32
|
||||
|
||||
type exitWait struct {
|
||||
mutex sync.Mutex
|
||||
wg *sync.WaitGroup
|
||||
deferFuns []func()
|
||||
stopSignList []chan StopSignal
|
||||
}
|
||||
|
||||
var exitWaitHandler *exitWait
|
||||
|
||||
func init() {
|
||||
exitWaitHandler = &exitWait{
|
||||
wg: &sync.WaitGroup{},
|
||||
}
|
||||
}
|
||||
|
||||
// ExitWaitFunDo 退出后等待处理完成
|
||||
func ExitWaitFunDo(doFun func()) {
|
||||
exitWaitHandler.wg.Add(1)
|
||||
defer exitWaitHandler.wg.Done()
|
||||
if doFun != nil {
|
||||
doFun()
|
||||
}
|
||||
}
|
||||
|
||||
// AppDefer 应用退出后置操作
|
||||
func AppDefer(deferFun ...func()) {
|
||||
exitWaitHandler.mutex.Lock()
|
||||
defer exitWaitHandler.mutex.Unlock()
|
||||
for _, funcItem := range deferFun {
|
||||
if funcItem != nil {
|
||||
exitWaitHandler.deferFuns = append(exitWaitHandler.deferFuns, funcItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ListenStop 订阅app退出信号
|
||||
func ListenStop(stopSig chan StopSignal) {
|
||||
exitWaitHandler.mutex.Lock()
|
||||
defer exitWaitHandler.mutex.Unlock()
|
||||
|
||||
exitWaitHandler.stopSignList = append(exitWaitHandler.stopSignList, stopSig)
|
||||
}
|
51
server/utility/simple/event.go
Normal file
51
server/utility/simple/event.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package simple
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type EventFunc func(ctx context.Context, args ...interface{})
|
||||
|
||||
type sEvent struct {
|
||||
sync.Mutex
|
||||
list map[string][]EventFunc // 所有事件的列表
|
||||
}
|
||||
|
||||
var event *sEvent
|
||||
|
||||
// InstanceEvent 事件实例
|
||||
func InstanceEvent() *sEvent {
|
||||
if event == nil {
|
||||
event = &sEvent{
|
||||
list: make(map[string][]EventFunc),
|
||||
}
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
// Register 往一个分组中注册事件
|
||||
func (e *sEvent) Register(group string, callback EventFunc) {
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
e.list[group] = append(e.list[group], callback)
|
||||
}
|
||||
|
||||
// Call 回调一个分组的事件
|
||||
func (e *sEvent) Call(group string, ctx context.Context, args ...interface{}) {
|
||||
if events, ok := e.list[group]; ok {
|
||||
for _, f := range events {
|
||||
f(ctx, args...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove 移动一个分组的事件
|
||||
func (e *sEvent) Remove(group string) {
|
||||
delete(e.list, group)
|
||||
}
|
||||
|
||||
// Clear 清空事件列表
|
||||
func (e *sEvent) Clear() {
|
||||
e.list = make(map[string][]EventFunc)
|
||||
}
|
@@ -8,35 +8,40 @@ package useragent
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"hotgo/internal/consts"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetOs 获取OS名称
|
||||
func GetOs(userAgent string) string {
|
||||
osName := "Unknown"
|
||||
osName := consts.Unknown
|
||||
if userAgent == "" {
|
||||
return osName
|
||||
}
|
||||
|
||||
strRe, _ := regexp.Compile(`(?i:\((.*?)\))`)
|
||||
userAgent = strRe.FindString(userAgent)
|
||||
var (
|
||||
strRe, _ = regexp.Compile(`(?i:\((.*?)\))`)
|
||||
levelNames = ":micromessenger:dart:Windows NT:Windows Mobile:Windows Phone:Windows Phone OS:Macintosh|Macintosh:Mac OS:CrOS|CrOS:iPhone OS:iPad|iPad:OS:Android:Linux:blackberry:hpwOS:Series:Symbian:PalmOS:SymbianOS:J2ME:Sailfish:Bada:MeeGo:webOS|hpwOS:Maemo:"
|
||||
namesArr = strings.Split(strings.Trim(levelNames, ":"), ":")
|
||||
regStrArr = make([]string, len(namesArr))
|
||||
)
|
||||
|
||||
levelNames := ":micromessenger:dart:Windows NT:Windows Mobile:Windows Phone:Windows Phone OS:Macintosh|Macintosh:Mac OS:CrOS|CrOS:iPhone OS:iPad|iPad:OS:Android:Linux:blackberry:hpwOS:Series:Symbian:PalmOS:SymbianOS:J2ME:Sailfish:Bada:MeeGo:webOS|hpwOS:Maemo:"
|
||||
var regStrArr []string
|
||||
namesArr := strings.Split(strings.Trim(levelNames, ":"), ":")
|
||||
for _, name := range namesArr {
|
||||
regStrArr = append(regStrArr, fmt.Sprintf("(%s[\\s?\\/XxSs0-9_.]+)", name))
|
||||
for k, name := range namesArr {
|
||||
regStrArr[k] = fmt.Sprintf("(%s[\\s?\\/XxSs0-9_.]+)", name)
|
||||
}
|
||||
regexpStr := fmt.Sprintf("(?i:%s)", strings.Join(regStrArr, "|"))
|
||||
nameRe, _ := regexp.Compile(regexpStr)
|
||||
|
||||
names := nameRe.FindAllString(userAgent, -1)
|
||||
name := ""
|
||||
userAgent = strRe.FindString(userAgent)
|
||||
var (
|
||||
nameRe, _ = regexp.Compile(fmt.Sprintf("(?i:%s)", strings.Join(regStrArr, "|")))
|
||||
names = nameRe.FindAllString(userAgent, -1)
|
||||
name = ""
|
||||
)
|
||||
|
||||
for _, s := range names {
|
||||
if name == "" {
|
||||
if len(name) == 0 {
|
||||
name = strings.TrimSpace(s)
|
||||
} else if len(name) > 0 {
|
||||
} else {
|
||||
if strings.Contains(name, "Macintosh") && s != "" {
|
||||
name = strings.TrimSpace(s)
|
||||
} else if strings.Contains(name, s) {
|
||||
@@ -62,30 +67,32 @@ func GetOs(userAgent string) string {
|
||||
if name != "" {
|
||||
osName = name
|
||||
}
|
||||
|
||||
return osName
|
||||
}
|
||||
|
||||
// GetBrowser 获取浏览器名称
|
||||
func GetBrowser(userAgent string) string {
|
||||
deviceName := "Unknown"
|
||||
var (
|
||||
deviceName = consts.Unknown
|
||||
levelNames = ":VivoBrowser:QQDownload:QQBrowser:QQ:MQQBrowser:MicroMessenger:TencentTraveler:LBBROWSER:TaoBrowser:BrowserNG:UCWEB:TwonkyBeamBrowser:NokiaBrowser:OviBrowser:NF-Browser:OneBrowser:Obigo:DiigoBrowser:baidubrowser:baiduboxapp:xiaomi:Redmi:MI:Lumia:Micromax:MSIEMobile:IEMobile:EdgiOS:Yandex:Mercury:Openwave:TouchPad:UBrowser:Presto:Maxthon:MetaSr:Trident:Opera:IEMobile:Edge:Chrome:Chromium:OPR:CriOS:Firefox:FxiOS:fennec:CrMo:Safari:Nexus One:Nexus S:Nexus:Blazer:teashark:bolt:HTC:Dell:Motorola:Samsung:LG:Sony:SonyST:SonyLT:SonyEricsson:Asus:Palm:Vertu:Pantech:Fly:Wiko:i-mobile:Alcatel:Nintendo:Amoi:INQ:ONEPLUS:Tapatalk:PDA:Novarra-Vision:NetFront:Minimo:FlyFlow:Dolfin:Nokia:Series:AppleWebKit:Mobile:Mozilla:Version:"
|
||||
namesArr = strings.Split(strings.Trim(levelNames, ":"), ":")
|
||||
regStrArr []string
|
||||
)
|
||||
|
||||
levelNames := ":VivoBrowser:QQDownload:QQBrowser:QQ:MQQBrowser:MicroMessenger:TencentTraveler:LBBROWSER:TaoBrowser:BrowserNG:UCWEB:TwonkyBeamBrowser:NokiaBrowser:OviBrowser:NF-Browser:OneBrowser:Obigo:DiigoBrowser:baidubrowser:baiduboxapp:xiaomi:Redmi:MI:Lumia:Micromax:MSIEMobile:IEMobile:EdgiOS:Yandex:Mercury:Openwave:TouchPad:UBrowser:Presto:Maxthon:MetaSr:Trident:Opera:IEMobile:Edge:Chrome:Chromium:OPR:CriOS:Firefox:FxiOS:fennec:CrMo:Safari:Nexus One:Nexus S:Nexus:Blazer:teashark:bolt:HTC:Dell:Motorola:Samsung:LG:Sony:SonyST:SonyLT:SonyEricsson:Asus:Palm:Vertu:Pantech:Fly:Wiko:i-mobile:Alcatel:Nintendo:Amoi:INQ:ONEPLUS:Tapatalk:PDA:Novarra-Vision:NetFront:Minimo:FlyFlow:Dolfin:Nokia:Series:AppleWebKit:Mobile:Mozilla:Version:"
|
||||
|
||||
var regStrArr []string
|
||||
namesArr := strings.Split(strings.Trim(levelNames, ":"), ":")
|
||||
for _, name := range namesArr {
|
||||
regStrArr = append(regStrArr, fmt.Sprintf("(%s[\\s?\\/0-9.]+)", name))
|
||||
}
|
||||
regexpStr := fmt.Sprintf("(?i:%s)", strings.Join(regStrArr, "|"))
|
||||
nameRe, _ := regexp.Compile(regexpStr)
|
||||
names := nameRe.FindAllString(userAgent, -1)
|
||||
|
||||
level := 0
|
||||
var (
|
||||
regexpStr = fmt.Sprintf("(?i:%s)", strings.Join(regStrArr, "|"))
|
||||
nameRe, _ = regexp.Compile(regexpStr)
|
||||
names = nameRe.FindAllString(userAgent, -1)
|
||||
level = 0
|
||||
)
|
||||
|
||||
for _, name := range names {
|
||||
replaceRe, _ := regexp.Compile(`(?i:[\s?\/0-9.]+)`)
|
||||
n := replaceRe.ReplaceAllString(name, "")
|
||||
l := strings.Index(levelNames, fmt.Sprintf(":%s:", n))
|
||||
l := strings.Index(levelNames, fmt.Sprintf(":%s:", replaceRe.ReplaceAllString(name, "")))
|
||||
if level == 0 {
|
||||
deviceName = strings.TrimSpace(name)
|
||||
}
|
||||
@@ -95,7 +102,6 @@ func GetBrowser(userAgent string) string {
|
||||
deviceName = strings.TrimSpace(name)
|
||||
}
|
||||
}
|
||||
|
||||
return deviceName
|
||||
}
|
||||
|
||||
@@ -119,6 +125,5 @@ func getWinOsNameWithWinNT(sName string) string {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return osName
|
||||
}
|
||||
|
@@ -3,18 +3,16 @@
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package validate
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// 包含判断
|
||||
|
||||
// InSliceExistStr 判断字符或切片字符是否存在指定字符
|
||||
func InSliceExistStr(elems interface{}, search string) bool {
|
||||
func InSliceExistStr(elems any, search string) bool {
|
||||
switch elems.(type) {
|
||||
case []string:
|
||||
elem := gconv.Strings(elems)
|
||||
@@ -26,35 +24,15 @@ func InSliceExistStr(elems interface{}, search string) bool {
|
||||
default:
|
||||
return gconv.String(elems) == search
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// InSliceInt64 元素是否存在于切片中
|
||||
func InSliceInt64(slice []int64, key int64) bool {
|
||||
if len(slice) == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(slice); i++ {
|
||||
if slice[i] == key {
|
||||
// InSlice 元素是否存在于切片中
|
||||
func InSlice[K comparable](slice []K, key K) bool {
|
||||
for _, v := range slice {
|
||||
if v == key {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func InSliceInt(slice []int, key int) bool {
|
||||
if len(slice) == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(slice); i++ {
|
||||
if slice[i] == key {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func InSliceString(slice []string, key string) bool {
|
||||
return gstr.InArray(slice, key)
|
||||
}
|
||||
|
Reference in New Issue
Block a user