From 72c1ad35b73febc6a2dfb3cc335eaff45fa7c49e Mon Sep 17 00:00:00 2001 From: jjxu <428192774@qq.com> Date: Thu, 12 Jun 2025 19:31:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9B=9E=E5=A4=8D=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 16 +- go.sum | 7 +- pkg/common/jwt/common.go | 63 +++++- pkg/common/ws/wsMessageHandle.go | 3 +- pkg/e/chatCode.go | 2 + pkg/e/fileType.go | 56 +++++ pkg/router/router.go | 7 +- .../asChat/chatAutoReplyRulerHandler.go | 90 ++++++++ pkg/service/asChat/dto.go | 8 +- pkg/service/asChat/handler.go | 195 +++++++++--------- pkg/service/base.go | 14 ++ pkg/utils/requestDataToProto.go | 51 +++++ pkg/utils/stime/common.go | 90 ++++++++ pkg/utils/stime/getTime.go | 128 ++++++++++++ pkg/utils/stime/getTimeExt.go | 101 +++++++++ pkg/utils/stime/getTimeExt_test.go | 12 ++ pkg/utils/stime/timeTranslate.go | 64 ++++++ pkg/utils/stime/timeTranslate_test.go | 26 +++ pkg/utils/stime/week.go | 52 +++++ pkg/utils/stime/week_test.go | 20 ++ 20 files changed, 888 insertions(+), 117 deletions(-) create mode 100644 pkg/e/fileType.go create mode 100644 pkg/service/asChat/chatAutoReplyRulerHandler.go create mode 100644 pkg/utils/requestDataToProto.go create mode 100644 pkg/utils/stime/common.go create mode 100644 pkg/utils/stime/getTime.go create mode 100644 pkg/utils/stime/getTimeExt.go create mode 100644 pkg/utils/stime/getTimeExt_test.go create mode 100644 pkg/utils/stime/timeTranslate.go create mode 100644 pkg/utils/stime/timeTranslate_test.go create mode 100644 pkg/utils/stime/week.go create mode 100644 pkg/utils/stime/week_test.go diff --git a/go.mod b/go.mod index 98af807..a21d92f 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,14 @@ module fonchain-fiee -go 1.18 +go 1.21.3 + +toolchain go1.23.6 replace ( - github.com/fonchain_enterprise/utils/aes => ../utils/aes - github.com/fonchain_enterprise/utils/objstorage => ../utils/objstorage //github.com/fonchain_enterprise/utils/objstorage => ../../tyfon-新/utils/objstorage github.com/fonchain/utils/voice => ../utils/voice + github.com/fonchain_enterprise/utils/aes => ../utils/aes + github.com/fonchain_enterprise/utils/objstorage => ../utils/objstorage ) // @@ -47,11 +49,11 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.11.2 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.2 github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.0 github.com/jinzhu/copier v0.3.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/k0kubun/pp v3.0.1+incompatible // indirect @@ -102,6 +104,7 @@ require ( github.com/BurntSushi/toml v1.2.1 github.com/PuerkitoBio/goquery v1.8.1 github.com/disintegration/imaging v1.6.2 + github.com/fonchain/utils/voice v0.0.0-00010101000000-000000000000 github.com/fonchain_enterprise/utils/objstorage v0.0.0-00010101000000-000000000000 github.com/gin-contrib/pprof v1.4.0 github.com/go-redis/redis v6.15.9+incompatible @@ -117,7 +120,7 @@ require ( cloud.google.com/go v0.65.0 // indirect github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect github.com/alibaba/sentinel-golang v1.0.4 // indirect - github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.61.1376 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect github.com/aws/aws-sdk-go v1.38.20 // indirect github.com/baidubce/bce-sdk-go v0.9.123 // indirect @@ -129,6 +132,7 @@ require ( github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/dorlolo/simpleRequest v1.2.7 // indirect github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 // indirect github.com/emicklei/go-restful/v3 v3.7.4 // indirect github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect diff --git a/go.sum b/go.sum index dd87352..df423dc 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,9 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alibaba/sentinel-golang v1.0.4 h1:i0wtMvNVdy7vM4DdzYrlC4r/Mpk1OKUUBurKKkWhEo8= github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk= -github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1376 h1:lExo7heZgdFn5AbaNJEllbA0KSJ/Z8T7MphvMREJOOo= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1376/go.mod h1:9CMdKNL3ynIGPpfTcdwTvIm8SGuAZYYC4jFVSSvE1YQ= github.com/aliyun/aliyun-oss-go-sdk v2.2.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible h1:KXeJoM1wo9I/6xPTyt6qCxoSZnmASiAjlrr0dyTUKt8= github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= @@ -187,6 +188,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +github.com/dorlolo/simpleRequest v1.2.7 h1:I6AlEhMBSZPNQ4QjpCevhpxsPRDa3lgDOxJYYfmPTU8= +github.com/dorlolo/simpleRequest v1.2.7/go.mod h1:koVT8DQu+JK40UoMNBQjt+zomlCW8FqE0ffEzjTOWYY= github.com/dubbogo/go-zookeeper v1.0.3/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 h1:XoR8SSVziXe698dt4uZYDfsmHpKLemqAgFyndQsq5Kw= github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= @@ -284,6 +287,7 @@ github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -1365,6 +1369,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= diff --git a/pkg/common/jwt/common.go b/pkg/common/jwt/common.go index 3ab76d8..3691777 100644 --- a/pkg/common/jwt/common.go +++ b/pkg/common/jwt/common.go @@ -7,18 +7,71 @@ package jwt import ( + "context" + "fonchain-fiee/api/account" + "fonchain-fiee/api/accountFiee" "fonchain-fiee/pkg/config" + "fonchain-fiee/pkg/e" + "fonchain-fiee/pkg/service" + "fonchain-fiee/pkg/utils/secret" "github.com/gin-gonic/gin" ) -func ParseCommonTokenInfo(c *gin.Context) { - domain, exist := c.Get("domain") - if !exist { - domain = config.Domain +// ParseToChatUser 将token信息转换为聊天室用户信息 +func ParseToChatUser(c *gin.Context) (chatUserInfo *accountFiee.ChatUserData, code e.ErrorCodeType) { + domain := config.Domain + domainAny, exist := c.Get("domain") + if exist { + domain = domainAny.(string) } + var err error + token := c.GetHeader(e.Authorization) + if token == "" { + code = e.NotLogin + return + } + + ctx := context.Background() + var originId int64 = 0 switch domain { case config.Domain: + //fiee token校验 + token, err = secret.GetJwtFromStr(token) + if err != nil { + code = e.NotLogin + return + } + var fieeJwtInfo *accountFiee.DecryptJwtResponse + fieeJwtInfo, err = service.AccountFieeProvider.DecryptJwt(ctx, &accountFiee.DecryptJwtRequest{Token: token, Domain: domain}) + if err != nil || fieeJwtInfo.IsOffline { + return + } + originId = int64(fieeJwtInfo.ID) case "fontree": - + //erp token校验 + token, err = secret.GetJwtFromStr(token) + if err != nil { + code = e.NotLogin + return + } + var fontreeJwtInfo *account.DecryptJwtResponse + fontreeJwtInfo, err = service.AccountProvider.DecryptJwt(ctx, &account.DecryptJwtRequest{Token: token, Domain: domain}) + if err != nil || fontreeJwtInfo.IsOffline { + code = e.NotLogin + return + } + originId = int64(fontreeJwtInfo.ID) } + var userQueryRes *accountFiee.GetChatUserListResp + userQueryRes, err = service.AccountFieeProvider.GetChatUserList(c, &accountFiee.GetChatUserListRequest{ + Query: &accountFiee.ChatUserData{Origin: domain, OriginId: originId}, + Page: 1, + PageSize: 1, + }) + if err != nil || userQueryRes.Total == 0 { + code = e.ErrorNotExistUser + return + } + chatUserInfo = userQueryRes.List[0] + return } diff --git a/pkg/common/ws/wsMessageHandle.go b/pkg/common/ws/wsMessageHandle.go index 9f96c5c..8c921e3 100644 --- a/pkg/common/ws/wsMessageHandle.go +++ b/pkg/common/ws/wsMessageHandle.go @@ -74,7 +74,8 @@ func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData, //如果找不到聊天用户则创建 if err != nil || chatUserQuery.Total > 0 { //注册客服 - createUserRes, err := service.AccountFieeProvider.CreateChatUser(ctx, &accountFiee.ChatUserData{ + var createUserRes *accountFiee.CreateChatUserResp + createUserRes, err = service.AccountFieeProvider.CreateChatUser(ctx, &accountFiee.ChatUserData{ NickName: accountInfo.NickName, Account: accountInfo.Account, Role: 2, diff --git a/pkg/e/chatCode.go b/pkg/e/chatCode.go index 3c54475..29cd1a3 100644 --- a/pkg/e/chatCode.go +++ b/pkg/e/chatCode.go @@ -58,4 +58,6 @@ var msgFlags = map[ErrorCodeType]string{ ErrUnRegistered: "未注册客户端", PermissionDenied: "拒绝访问", ErrChatSendErr: "消息发送失败", + NotLogin: "请先登录", + ErrorNotExistUser: "用户不存在", } diff --git a/pkg/e/fileType.go b/pkg/e/fileType.go new file mode 100644 index 0000000..bca1641 --- /dev/null +++ b/pkg/e/fileType.go @@ -0,0 +1,56 @@ +package e + +import "strings" + +type FileType int + +// 定义文件类型值 +const ( + Video FileType = 1 + Audio FileType = 2 + Image FileType = 3 + File FileType = 4 + Other FileType = 5 +) + +// 根据扩展名映射到文件类型值 +var extensionToType = map[string]FileType{ + // 视频文件 + ".3g2": Video, ".3gp": Video, ".asf": Video, ".avi": Video, ".divx": Video, ".drc": Video, + ".flv": Video, ".h261": Video, ".h264": Video, ".mkv": Video, ".mov": Video, ".mp4": Video, ".mpg": Video, + ".mpeg": Video, ".mpv": Video, ".mxf": Video, ".nuv": Video, ".qt": Video, ".rm": Video, + ".rmvb": Video, ".srt": Video, ".swf": Video, ".vob": Video, ".vp6": Video, ".vp8": Video, ".webm": Video, + ".wmv": Video, ".xesc": Video, + + // 音频文件 + ".aac": Audio, ".aax": Audio, ".ac3": Audio, ".act": Audio, ".au": Audio, ".flac": Audio, + ".m4a": Audio, ".m4p": Audio, ".m4r": Audio, ".mid": Audio, ".midi": Audio, ".mp2": Audio, + ".mp3": Audio, ".mpa": Audio, ".mpc": Audio, ".ogg": Audio, ".wav": Audio, ".wma": Audio, ".wv": Audio, + + // 图像文件 + ".bmp": Image, ".gif": Image, ".ico": Image, ".jpeg": Image, ".jpg": Image, ".jpe": Image, + ".png": Image, ".psd": Image, ".tiff": Image, ".webp": Image, + + // 普通文件 + ".a": File, ".abw": File, ".azw": File, ".bin": File, ".bz2": File, ".c": File, ".cab": File, + ".class": File, ".conf": File, ".crt": File, ".css": File, ".csv": File, ".dat": File, ".deb": File, + ".dll": File, ".dms": File, ".doc": File, ".docx": File, ".eot": File, ".eps": File, ".exe": File, + ".gz": File, ".h": File, ".htm": File, ".html": File, ".iso": File, ".jar": File, + ".js": File, ".json": File, ".log": File, ".m3u": File, ".m3u8": File, ".md": File, ".msi": File, + ".otf": File, ".pcap": File, ".pdf": File, ".ppt": File, ".pptx": File, ".rar": File, ".rpm": File, + ".rss": File, ".run": File, ".sh": File, ".sql": File, ".svg": File, ".tar": File, ".tgz": File, + ".ttf": File, ".txt": File, ".vsd": File, ".weba": File, + ".wps": File, ".xml": File, ".xpi": File, ".zip": File, ".z": File, + + // 未知文件扩展名 + "": Other, +} + +// DetectFileTypeByExtension 通过文件扩展名判断文件类型并返回对应的值 +func DetectFileTypeByExtension(extension string) FileType { + extension = strings.ToLower(extension) + if fileType, exists := extensionToType[extension]; exists { + return fileType + } + return Other +} diff --git a/pkg/router/router.go b/pkg/router/router.go index 80fdfe2..58c37b5 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -121,7 +121,12 @@ func NewRouter() *gin.Engine { v1.POST("aschat/message/list", asChat.ChatHandlerIns.MessageList) v1.POST("aschat/user/stat", asChat.ChatHandlerIns.UserMessageStat) v1.POST("aschat/voicetotext", asChat.ChatHandlerIns.VoiceToText) - v1.POST("aschat/artistDetail", asChat.ChatHandlerIns.ArtistDetail) + //v1.POST("aschat/artistDetail", asChat.ChatHandlerIns.ArtistDetail) + v1.POST("aschat/autoReplyRuler/create", asChat.Handler.CreateChatAutoReplyRuler) + v1.POST("aschat/autoReplyRuler/delete", asChat.Handler.DeleteChatAutoReplyRuler) + v1.POST("aschat/autoReplyRuler/update", asChat.Handler.UpdateChatAutoReplyRuler) + v1.POST("aschat/autoReplyRuler/detail", asChat.Handler.GetChatAutoReplyRulerDetail) + v1.POST("aschat/autoReplyRuler/query", asChat.Handler.GetChatAutoReplyRulerList) } //静态文件 diff --git a/pkg/service/asChat/chatAutoReplyRulerHandler.go b/pkg/service/asChat/chatAutoReplyRulerHandler.go new file mode 100644 index 0000000..7905472 --- /dev/null +++ b/pkg/service/asChat/chatAutoReplyRulerHandler.go @@ -0,0 +1,90 @@ +package asChat + +import ( + "fonchain-fiee/api/accountFiee" + "fonchain-fiee/pkg/service" + "fonchain-fiee/pkg/utils" + "github.com/gin-gonic/gin" +) + +var Handler = &ChatAutoReplyRulerHandler{} + +type ChatAutoReplyRulerHandler struct { +} + +// 创建自动回复规则 +func (a *ChatAutoReplyRulerHandler) CreateChatAutoReplyRuler(c *gin.Context) { + var req accountFiee.ChatAutoReplyRulerData + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + _, err := service.AccountFieeProvider.CreateChatAutoReplyRuler(c, &req) + if err != nil { + service.Error(c, err) + return + } + service.Success(c) +} + +// 删除自动回复规则 +func (a *ChatAutoReplyRulerHandler) DeleteChatAutoReplyRuler(c *gin.Context) { + var req accountFiee.DeleteChatAutoReplyRulerRequest + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + _, err := service.AccountFieeProvider.DeleteChatAutoReplyRuler(c, &req) + if err != nil { + service.Error(c, err) + return + } + service.Success(c) +} + +// 更新自动回复规则 +func (a *ChatAutoReplyRulerHandler) UpdateChatAutoReplyRuler(c *gin.Context) { + var req accountFiee.ChatAutoReplyRulerData + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + _, err := service.AccountFieeProvider.UpdateChatAutoReplyRuler(c, &req) + if err != nil { + service.Error(c, err) + return + } + service.Success(c) +} + +// 使用id查询自动回复规则 +func (a *ChatAutoReplyRulerHandler) GetChatAutoReplyRulerDetail(c *gin.Context) { + var req accountFiee.GetChatAutoReplyRulerByIdRequest + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + resp, err := service.AccountFieeProvider.GetChatAutoReplyRulerDetail(c, &req) + if err != nil { + service.Error(c, err) + return + } + service.Success(c, resp) +} + +// 批量查询自动回复规则 +func (a *ChatAutoReplyRulerHandler) GetChatAutoReplyRulerList(c *gin.Context) { + var req GetChatAutoReplyRulerListRequest + if err := c.ShouldBindJSON(&req); err != nil { + service.Error(c, err) + return + } + var protoReq = accountFiee.GetChatAutoReplyRulerListRequest{Query: &accountFiee.ChatAutoReplyRulerData{}} + utils.RequestDataConvert(&req, &protoReq) + resp, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(c, &protoReq) + if err != nil { + service.Error(c, err) + return + } + service.Success(c, resp.List) +} diff --git a/pkg/service/asChat/dto.go b/pkg/service/asChat/dto.go index fc1b763..5afc57b 100644 --- a/pkg/service/asChat/dto.go +++ b/pkg/service/asChat/dto.go @@ -97,7 +97,7 @@ func (m *MessageListType) ToJson() string { type UserMsgStatic struct { UserId int64 `json:"userId"` //用户id Name string `json:"name"` //名称 - ArtistUid string `json:"artistUid"` + ArtistUid string `json:"artistUid,omitempty"` SessionId string `json:"sessionId"` //会话id Total int64 `json:"total"` //新消息数量 //NewMessageTime string `json:"newMessageTime"` //最新消息的创建时间 @@ -128,3 +128,9 @@ type ArtistInfo struct { TelNum string `json:"telNum"` RecentPhoto string `json:"recentPhoto"` } + +type GetChatAutoReplyRulerListRequest struct { + Page int64 `json:"page"` + PageSize int64 `json:"pageSize"` + accountFiee.ChatAutoReplyRulerData +} diff --git a/pkg/service/asChat/handler.go b/pkg/service/asChat/handler.go index e82dd6c..97d0d4b 100644 --- a/pkg/service/asChat/handler.go +++ b/pkg/service/asChat/handler.go @@ -13,13 +13,14 @@ import ( "encoding/hex" "errors" "fmt" - "fonchain-fiee/api/account" "fonchain-fiee/api/accountFiee" + "fonchain-fiee/pkg/common/jwt" "fonchain-fiee/pkg/common/ws" "fonchain-fiee/pkg/e" "fonchain-fiee/pkg/service" "fonchain-fiee/pkg/service/upload" "fonchain-fiee/pkg/utils" + "fonchain-fiee/pkg/utils/stime" "github.com/fonchain/utils/voice" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" @@ -116,31 +117,21 @@ func (cr ChatHandler) NewMessage(c *gin.Context) { } fmt.Println("NewMessage 1111111111111111111111111111111") //获取用户信息 - tokenResult := asAccount.GetUserInfoWithTokenV2(c) - if tokenResult.Err != nil { - service.Error(c, errors.New("未登录")) + chatUser, code := jwt.ParseToChatUser(c) + if code != 0 { + service.ErrWithCode(c, code) return } fmt.Println("NewMessage 22222222222222222222222222222222222") //存储入库 - var userName = "未知" - if request.Waiter { - accountDetail, err := service.AccountProvider.Info(c, &account.InfoRequest{ID: uint64(tokenResult.UserInfo.MgmtAccId), Domain: config.Domain}) - if err != nil { - service.Error(c, errors.New("用户信息获取失败")) - return - } - userName = accountDetail.Info.NickName - } else { - if tokenResult.UserInfo.RealNameInfo != nil { - userName = tokenResult.UserInfo.RealNameInfo.Name - } + if chatUser.NickName != "" { + chatUser.NickName = fmt.Sprintf("未知用户(%d)", chatUser.ID) } fmt.Println("NewMessage 3333333333333333333333333333333333") var data = accountFiee.ChatRecordData{ SessionId: request.SessionId, - UserId: tokenResult.UserInfo.ID, - Name: userName, + UserId: chatUser.ID, + Name: chatUser.NickName, Avatar: "", MsgType: request.MsgType, Content: request.Message.Text, @@ -169,7 +160,7 @@ func (cr ChatHandler) NewMessage(c *gin.Context) { } fmt.Println("NewMessage 5 消息数量+1") //新消息数量统计+1 - noticeUserId := ChatRoom.GetUserIdInSession(request.SessionId, tokenResult.UserInfo.ID) + noticeUserId := ChatRoom.GetUserIdInSession(request.SessionId, chatUser.ID) fmt.Println("NewMessage 5.1 消息数量配置结束") fmt.Printf("noticeUserId %+v\n", noticeUserId) for _, userId := range noticeUserId { @@ -181,35 +172,35 @@ func (cr ChatHandler) NewMessage(c *gin.Context) { var notice = MessageListType{} notice.BuildMessage(resp.Data) fmt.Printf("ws消息提醒:%+v\n", notice) - _, err = ChatRoom.SendSessionMessage(tokenResult.UserInfo.ID, request.SessionId, ws.NewChatMsgType, notice) + _, err = ChatRoom.SendSessionMessage(chatUser.ID, request.SessionId, ws.NewChatMsgType, notice) if err != nil { log.Fatal("发送新消息通知失败", zap.Error(err), zap.Any("notice", notice)) } fmt.Println("NewMessage 7 -end") //发送app推送(无横幅推送) - go func() { - omitMessage := "" - switch request.MsgType { - case accountFiee.MsgType_TextMsgType: - runMsg := []rune(request.Text) - if len(runMsg) > 15 { - omitMessage = string(runMsg[:15]) + "..." - } else { - omitMessage = request.Text - } - case accountFiee.MsgType_ImageMsgType: - omitMessage = "[图片]" - case accountFiee.MsgType_AudioMsgType: - omitMessage = "[音频]" - case accountFiee.MsgType_VideoMsgType: - omitMessage = "[视频]" - default: - omitMessage = "新消息请查收" - } - for _, userId := range noticeUserId { - _ = asPusher.NewArtistinfoUniPush().NewChatMessageNotice(userId, omitMessage) - } - }() + //go func() { + // omitMessage := "" + // switch request.MsgType { + // case accountFiee.MsgType_TextMsgType: + // runMsg := []rune(request.Text) + // if len(runMsg) > 15 { + // omitMessage = string(runMsg[:15]) + "..." + // } else { + // omitMessage = request.Text + // } + // case accountFiee.MsgType_ImageMsgType: + // omitMessage = "[图片]" + // case accountFiee.MsgType_AudioMsgType: + // omitMessage = "[音频]" + // case accountFiee.MsgType_VideoMsgType: + // omitMessage = "[视频]" + // default: + // omitMessage = "新消息请查收" + // } + // for _, userId := range noticeUserId { + // _ = asPusher.NewArtistinfoUniPush().NewChatMessageNotice(userId, omitMessage) + // } + //}() service.Success(c) } @@ -237,9 +228,9 @@ func (cr ChatHandler) MessageList(c *gin.Context) { service.Success(c, resp) return } - tokenResult := asAccount.GetUserInfoWithTokenV2(c) - if tokenResult.Err != nil { - service.ErrorWeb(c, e.NotLogin, tokenResult.Err.Error()) + chatUser, code := jwt.ParseToChatUser(c) + if code != 0 { + service.ErrWithCode(c, code) return } //if request.SessionId == "" { @@ -255,7 +246,7 @@ func (cr ChatHandler) MessageList(c *gin.Context) { defer func() { //获取最新数据时,重置新消息数量统计 if request.Direction == 2 || request.Recent { - cr.cache.ResetNewMessageTotal(tokenResult.UserInfo.ID, request.SessionId) + cr.cache.ResetNewMessageTotal(chatUser.ID, request.SessionId) } //设置消息已被客服阅读,当客服重新通过通过websocket连接时,这些消息将不被纳入新消息数量统计 if len(returnDataIdList) > 0 && domain == "fontree" { @@ -362,9 +353,9 @@ func (cr ChatHandler) MessageList(c *gin.Context) { func (cr ChatHandler) Upload(c *gin.Context) { fmt.Println("111111111111") //获取用户信息 - accInfo := asAccount.GetUserInfoWithTokenV2(c) - if accInfo.Err != nil { - service.Error(c, accInfo.Err.Error()) + chatUser, code := jwt.ParseToChatUser(c) + if code != 0 { + service.ErrWithCode(c, code) return } //获取文件对象 @@ -421,7 +412,7 @@ func (cr ChatHandler) Upload(c *gin.Context) { defer tmp.Close() fileBuffer := bytes.NewBuffer(fileContent) var bosUrl string - bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("%d/%v%v", accInfo.UserInfo.MgmtAccId, filename, fileExt)) + bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("%d/%v%v", chatUser.ID, filename, fileExt)) if err != nil { service.Error(c, err) return @@ -445,19 +436,19 @@ func (cr ChatHandler) Upload(c *gin.Context) { func (cr ChatHandler) UserMessageStat(c *gin.Context) { //获取用户信息 - tokenResult := asAccount.GetUserInfoWithTokenV2(c) - if tokenResult.Err != nil { - service.Error(c, errors.New("未登录")) + chatUser, code := jwt.ParseToChatUser(c) + if code != 0 { + service.ErrWithCode(c, code) return } - result := cr.cache.GetNewMessageStat(c, tokenResult.UserInfo.ID) + result := cr.cache.GetNewMessageStat(c, chatUser.ID) if len(result) == 0 { service.Success(c, result) return } fmt.Printf("cache stat:%+v\n", result) //获取实名信息 - var protoReq = accountFiee.GetChatUserListRequest{ + var protoReq = accountFiee.GetChatUserListRequest2{ Page: 1, PageSize: int64(len(result)), } @@ -470,7 +461,7 @@ func (cr ChatHandler) UserMessageStat(c *gin.Context) { protoReq.UserIdIn = append(protoReq.UserIdIn, item.UserId) } fmt.Printf("protoReq.UserIdIn:%+v\n", protoReq.UserIdIn) - listRes, err := service.AccountFieeProvider.GetChatUserList(c, &protoReq) + listRes, err := service.AccountFieeProvider.GetChatUserList2(c, &protoReq) if err != nil { service.Error(c, err) return @@ -481,7 +472,7 @@ func (cr ChatHandler) UserMessageStat(c *gin.Context) { if item.UserId == user.UserId { user := user result[i].Name = user.Name - result[i].ArtistUid = user.ArtistUid + //result[i].ArtistUid = user.ArtistUid break } } @@ -524,50 +515,50 @@ func (cr ChatHandler) VoiceToText(c *gin.Context) { service.Success(c, map[string]string{"convText": detail.ConvText}) } -func (cr ChatHandler) ArtistDetail(c *gin.Context) { - var req ArtistInfoRequest - if err := c.ShouldBindJSON(&req); err != nil { - service.Error(c, err) - return - } - if req.UserId == 0 { - service.Success(c, ArtistInfo{}) - return - } - detail, err := service.GrpcArtistInfoUserImpl.FindUsersUserView(c, &artistInfoUser.FindUsersRequest{UserId: req.UserId}) - if err != nil { - service.Error(c, err) - return - } - var ( - tnum string - artistName string - age int64 - sex string - nativePlace string - telNum string - recentPhoto string - ) - if len(detail.Data) > 0 { - tnum = detail.Data[0].Tnum - artistName = beautifulZeroName(detail.Data[0].RealName, req.UserId) - age = detail.Data[0].Age - sex = detail.Data[0].Sex - nativePlace = detail.Data[0].NativePlace - telNum = detail.Data[0].TelNum - recentPhoto = detail.Data[0].Photo - } - resp := ArtistInfo{ - Tnum: tnum, - ArtistName: artistName, - Age: age, - Sex: sex, - NativePlace: nativePlace, - TelNum: telNum, - RecentPhoto: recentPhoto, - } - service.Success(c, resp) -} +//func (cr ChatHandler) ArtistDetail(c *gin.Context) { +// var req ArtistInfoRequest +// if err := c.ShouldBindJSON(&req); err != nil { +// service.Error(c, err) +// return +// } +// if req.UserId == 0 { +// service.Success(c, ArtistInfo{}) +// return +// } +// detail, err := service.GrpcArtistInfoUserImpl.FindUsersUserView(c, &artistInfoUser.FindUsersRequest{UserId: req.UserId}) +// if err != nil { +// service.Error(c, err) +// return +// } +// var ( +// tnum string +// artistName string +// age int64 +// sex string +// nativePlace string +// telNum string +// recentPhoto string +// ) +// if len(detail.Data) > 0 { +// tnum = detail.Data[0].Tnum +// artistName = beautifulZeroName(detail.Data[0].RealName, req.UserId) +// age = detail.Data[0].Age +// sex = detail.Data[0].Sex +// nativePlace = detail.Data[0].NativePlace +// telNum = detail.Data[0].TelNum +// recentPhoto = detail.Data[0].Photo +// } +// resp := ArtistInfo{ +// Tnum: tnum, +// ArtistName: artistName, +// Age: age, +// Sex: sex, +// NativePlace: nativePlace, +// TelNum: telNum, +// RecentPhoto: recentPhoto, +// } +// service.Success(c, resp) +//} // 对没有名字的name进行优化 func beautifulZeroName(name string, userId int64) string { diff --git a/pkg/service/base.go b/pkg/service/base.go index ff35e97..8025db9 100644 --- a/pkg/service/base.go +++ b/pkg/service/base.go @@ -189,3 +189,17 @@ func translateErrorMessage(c *gin.Context, message string) string { return common.EnMessages[message] } } + +func ErrWithCode(c *gin.Context, code e.ErrorCodeType, newMsg ...string) { + msg := e.GetCodeMsg(code) + if newMsg != nil { + msg = newMsg[0] + } + + c.JSON(e.Success, serializer.Response{ + Code: code, + Status: 1, + Msg: msg, + Data: nil, + }) +} diff --git a/pkg/utils/requestDataToProto.go b/pkg/utils/requestDataToProto.go new file mode 100644 index 0000000..a71ed68 --- /dev/null +++ b/pkg/utils/requestDataToProto.go @@ -0,0 +1,51 @@ +// Package utils ----------------------------- +// @file : requestDataToProto.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2023/8/28 17:57 +// ------------------------------------------- +package utils + +import ( + "reflect" + "strings" +) + +// http请求转proto请求 +func RequestDataConvert(from interface{}, to interface{}) { + var proxyField = "Query" + fromValue := reflect.ValueOf(from) + toValue := reflect.ValueOf(to) + toType := reflect.TypeOf(to) + + // 获取From结构体的字段信息 + fromType := fromValue.Type().Elem() + for i := 0; i < fromType.NumField(); i++ { + // 获取字段名和字段值 + fieldName := fromType.Field(i).Name + fieldValue := fromValue.Elem().FieldByName(fieldName) + if fieldName != proxyField { + _, exists := toType.Elem().FieldByName(fieldName) + if exists { + // 设置To结构体中相应字段的值 + toValue.Elem().FieldByName(fieldName).Set(fieldValue) + } + } + } + queryField, exists := toType.Elem().FieldByName(proxyField) + if exists { + var queryFieldTypeName string + // 指针类型额外处理,拿到真实的数据类型 + if queryField.Type.Kind() == reflect.Ptr { + queryFieldTypeName = queryField.Type.Elem().String() + } else { + queryFieldTypeName = queryField.Type.Kind().String() + } + //处理拿到的结构体类型如 utils.xxxx的类型,去掉utils.这部分 + if strings.Contains(queryFieldTypeName, ".") { + queryFieldTypeName = strings.Split(queryFieldTypeName, ".")[1] + } + fromQueryValue := fromValue.Elem().FieldByName(queryFieldTypeName) + toValue.Elem().FieldByName(proxyField).Set(fromQueryValue.Addr()) + } +} diff --git a/pkg/utils/stime/common.go b/pkg/utils/stime/common.go new file mode 100644 index 0000000..21930d8 --- /dev/null +++ b/pkg/utils/stime/common.go @@ -0,0 +1,90 @@ +// Package stime ----------------------------- +// @file : common.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2022/10/21 00:19:04 +// ------------------------------------------- +package stime + +import ( + "time" +) + +var Loc loc + +type loc time.Location + +func (l loc) Shanghai() *time.Location { + var shanghai, err = time.LoadLocation("Asia/Shanghai") + if err != nil { + shanghai = time.FixedZone("CST", 8*3600) + } + return shanghai +} + +const ( + //常规时间格式(日期带横杠) + Format_Normal_YMDhms = "2006-01-02 15:04:05" + Format_Normal_YMDh = "2006-01-02 15:04" + Format_Normal_YMD = "2006-01-02" + Format_Normal_hms = "15:04:05" + Format_Normal_hm = "15:04" + Format_Normal_YM = "2006-01" + Format_Dot_YMD = "2006.01.02" + //带斜杠的时间格式 + Format_Slash_YMDhms = "2006/01/02 15:04:05" + Format_Slash_YMD = "2006/01/02" + //无间隔符 + Format_NoSpacer_YMDhms = "20060102150405" + Format_NoSpacer_YMD = "20060102" + Format_ChinaChar_YMD = "2006年01月02日" +) + +var MonthStrMap = map[string]string{ + "January": "01", + "February": "02", + "March": "03", + "April": "04", + "May": "05", + "June": "06", + "July": "07", + "August": "08", + "September": "09", + "October": "10", + "November": "11", + "December": "12", +} +var MonthIntMap = map[string]int{ + "January": 1, + "February": 2, + "March": 3, + "April": 4, + "May": 5, + "June": 6, + "July": 7, + "August": 8, + "September": 9, + "October": 10, + "November": 11, + "December": 12, +} + +var WeekIntMap = map[string]int{ + "Monday": 1, + "Tuesday": 2, + "Wednesday": 3, + "Thursday": 4, + "Friday": 5, + "Saturday": 6, + "Sunday": 7, +} + +var WeekStrMap = map[string]string{ + "Monday": "一", + "Tuesday": "二", + "Wednesday": "三", + "Thursday": "四", + "Friday": "五", + "Saturday": "六", + "Sunday": "日", +} diff --git a/pkg/utils/stime/getTime.go b/pkg/utils/stime/getTime.go new file mode 100644 index 0000000..db69c22 --- /dev/null +++ b/pkg/utils/stime/getTime.go @@ -0,0 +1,128 @@ +/* + * @FileName: getTime.go + * @Author: JJXu + * @CreateTime: 2022/3/1 下午6:35 + * @Description: + */ + +package stime + +import ( + "fmt" + "time" +) + +func StrNowDate() string { + return TimeToString(time.Now(), Format_Normal_YMD) +} + +func StrNowYearMonth() string { + return TimeToString(time.Now(), Format_Normal_YM) +} + +//ThisMorming 今天凌晨 +func ThisMorming(format string) (strTime string) { + thisTime := time.Now() + year := thisTime.Year() + month := MonthStrMap[thisTime.Month().String()] + day := fmt.Sprintf("%02d", thisTime.Day()) + strTime = fmt.Sprintf("%v-%v-%v 00:00:00", year, month, day) + if format != Format_Normal_YMDhms { + t1, _ := time.ParseInLocation(Format_Normal_YMDhms, strTime, Loc.Shanghai()) + strTime = t1.Format(format) + } + return strTime +} + +//ThisMorningUnix 获取当日凌晨的时间戳 +func ThisMorningToUnix() int64 { + thist := time.Now() + zero_tm := time.Date(thist.Year(), thist.Month(), thist.Day(), 0, 0, 0, 0, thist.Location()).Unix() + return zero_tm +} + +//TomorrowMorning 第二天凌晨 +func TomorrowMorning(baseTime time.Time) *time.Time { + year := baseTime.Year() + month := MonthStrMap[baseTime.Month().String()] + day := fmt.Sprintf("%02d", baseTime.Day()+1) + strTime := fmt.Sprintf("%v-%v-%v 00:00:00", year, month, day) + res, _ := StringToTime(strTime) + return res +} + +//ThisTimeUnix 获取当前时间的时间戳 +func CurrentimeToUnix() int64 { + return time.Now().Unix() +} + +//Currentime 获取当前时间 +func Currentime(format string) (strTime string) { + strTime = time.Now().Format(format) + return +} + +//HoursAgo 若干小时之前的时间 +func HoursAgo(hours time.Duration, format string) (lastTimeStr string) { + lastStamp := time.Now().Unix() - int64((time.Hour * hours).Seconds()) + lastTime := time.Unix(lastStamp, 0).In(Loc.Shanghai()) + lastTimeStr = lastTime.Format(format) + return +} + +//TimeToString 时间转字符串 +func TimeToString(t time.Time, format string) string { + return t.Format(format) +} + +//计算指定月份的天数 +func YearMonthToDayNumber(year int, month int) int { + // 有31天的月份 + day31 := map[int]bool{ + 1: true, + 3: true, + 5: true, + 7: true, + 8: true, + 10: true, + 12: true, + } + if day31[month] == true { + return 31 + } + // 有30天的月份 + day30 := map[int]bool{ + 4: true, + 6: true, + 9: true, + 11: true, + } + if day30[month] == true { + return 30 + } + // 计算是平年还是闰年 + if (year%4 == 0 && year%100 != 0) || year%400 == 0 { + // 得出2月的天数 + return 29 + } + // 得出2月的天数 + return 28 +} + +// 求时间差(返回一个数字,该数字单位由传过来的unit决定。若unit为60,则单位是分钟。) +func GetDiffTime(start_time string, end_time string, unit int64) int64 { + // 转成时间戳 + if len(start_time) == 10 { + start_time = fmt.Sprintf("%v 00:00:00", start_time) + } + if len(end_time) == 10 { + end_time = fmt.Sprintf("%v 00:00:00", end_time) + } + startUnix, _ := time.ParseInLocation("2006-01-02 15:04:05", start_time, Loc.Shanghai()) + endUnix, _ := time.ParseInLocation("2006-01-02 15:04:05", end_time, Loc.Shanghai()) + startTime := startUnix.Unix() + endTime := endUnix.Unix() + // 求相差天数 + date := (endTime - startTime) / unit + return date +} diff --git a/pkg/utils/stime/getTimeExt.go b/pkg/utils/stime/getTimeExt.go new file mode 100644 index 0000000..166b173 --- /dev/null +++ b/pkg/utils/stime/getTimeExt.go @@ -0,0 +1,101 @@ +package stime + +import ( + "fmt" + "strconv" + "time" +) + +// 根据指定时间获取后面的若干天工作日列表 +// param baseOn 指定基准时间 +// param daysNum 获取工作日的数量 +func GetWorkDayList(baseOn *time.Time, daysNum int) []time.Time { + var timeList []time.Time + var basCount = 1 + var workDay time.Time + for { + if len(timeList) == daysNum { + break + } + workDay = baseOn.AddDate(0, 0, basCount) + switch workDay.Weekday() { + case time.Saturday: + basCount += 2 + continue + case time.Sunday: + basCount++ + continue + default: + timeList = append(timeList, workDay) + basCount++ + } + } + return timeList +} + +// 根据指定时间获取后面的若干天工作日列表 +// param baseOn 指定基准时间 +// param daysNum 获取工作日的数量 +func GetWorkDayStrList(baseOn *time.Time, daysNum int) []string { + var timeList []string + var basCount = 1 + var workDay time.Time + for { + if len(timeList) == daysNum { + break + } + workDay = baseOn.AddDate(0, 0, basCount) + switch workDay.Weekday() { + case time.Saturday: + basCount += 2 + continue + case time.Sunday: + basCount++ + continue + default: + timeList = append(timeList, TimeToString(workDay, Format_Normal_YMD)) + basCount++ + } + } + return timeList +} + +// 获取时间差文字描述 +func GetTimeDifferenceDesc(now *time.Time, before *time.Time) string { + if before == nil { + return "" + } + if now.After(*before) { + subTimestamp := now.Unix() - before.Unix() + day := subTimestamp / (3600 * 24) + hour := (subTimestamp - day*3600*24) / 3600 + minute := (subTimestamp - day*3600*24 - hour*3600) / 60 + second := subTimestamp - day*3600*24 - hour*3600 - minute*60 + + switch { + case day > 0: + if hour > 0 { + return fmt.Sprintf("%d天%d小时", day, hour) + } else { + return fmt.Sprintf("%d天", day) + } + case hour > 0: + if minute < 10 { + return fmt.Sprintf("%d小时", hour) + } else { + return fmt.Sprintf("%d小时%d", hour, minute) + } + case hour == 0 && minute > 0: + return fmt.Sprintf("%d分钟", minute) + case hour == 0 && minute == 0: + return fmt.Sprintf("%d秒", second) + } + } + return "" +} + +// TimeStampToBytes 时间戳转字节 +func TimeStampToBytes(stamp int64) []byte { + timeStr := strconv.FormatInt(stamp, 2) + return []byte(timeStr) +} diff --git a/pkg/utils/stime/getTimeExt_test.go b/pkg/utils/stime/getTimeExt_test.go new file mode 100644 index 0000000..52d4d41 --- /dev/null +++ b/pkg/utils/stime/getTimeExt_test.go @@ -0,0 +1,12 @@ +package stime + +import ( + "testing" + "time" +) + +func TestGetWorkDayStrList(t *testing.T) { + now := time.Now() + result := GetWorkDayStrList(&now, 5) + t.Log(result) +} diff --git a/pkg/utils/stime/timeTranslate.go b/pkg/utils/stime/timeTranslate.go new file mode 100644 index 0000000..2197e02 --- /dev/null +++ b/pkg/utils/stime/timeTranslate.go @@ -0,0 +1,64 @@ +/* + * @Author: immortal + * @Date: 2022-03-11 20:55:38 + * @LastEditors: immortal + * @LastEditTime: 2022-03-12 14:26:42 + * @Description: + * @FilePath: \monitor_env\utils\simpletime\timeTranslate.go + */ +/** + * @Author Puzzle + * @Date 2021/11/18 1:36 下午 + **/ + +package stime + +import ( + "time" +) + +func GetTimestampMillisecond() int64 { + now := time.Now() + return now.UnixNano() / 1e6 +} + +func StringToTime(strTime string) (*time.Time, error) { + const TIME_LAYOUT = "2006-01-02 15:04:05" //此时间不可更改 + timeobj, err := time.ParseInLocation(TIME_LAYOUT, strTime, Loc.Shanghai()) + return &timeobj, err +} + +func StringToTimeWithFormat(strTime string, timeFormat string) (*time.Time, error) { + timeobj, err := time.ParseInLocation(timeFormat, strTime, Loc.Shanghai()) + return &timeobj, err +} + +// 去除精确时间后面的小数点 +func NowTimeToTime(layout string) *time.Time { + otime := time.Now().Format(layout) //"2006-01-02 15:04:05" and so on + tt, _ := StringToTime(otime) + return tt +} + +// 时间之间的转换 +func TimeStampToString(timestamp int64, format string) string { + t := time.Unix(timestamp, 0) + return t.Format(format) +} + +func GetAge(birthday time.Time) int { + if birthday.IsZero() { + return 0 + } + now := time.Now() + year, month, day := now.Date() + if year == 0 || month == 0 || day == 0 { + return 0 + } + age := year - birthday.Year() - 1 + //判断年龄 + if birthday.Month() < month || birthday.Month() == month && birthday.Day() <= day { + age++ + } + return age +} diff --git a/pkg/utils/stime/timeTranslate_test.go b/pkg/utils/stime/timeTranslate_test.go new file mode 100644 index 0000000..20b2a50 --- /dev/null +++ b/pkg/utils/stime/timeTranslate_test.go @@ -0,0 +1,26 @@ +/* + * @FileName: time_test.go + * @Author: JJXu + * @CreateTime: 2022/2/25 下午2:37 + * @Description: + */ + +package stime + +import ( + "fmt" + "testing" + "time" +) + +func TestTime(t *testing.T) { + result := NowTimeToTime(Format_Normal_YMDhms) + fmt.Println(result) +} +func TestGetAge(t *testing.T) { + age := GetAge(time.Date(1991, 3, 6, 0, 0, 0, 0, Loc.Shanghai())) + fmt.Println(age) + if age != 31 { + t.Errorf("want 31 but get %v", age) + } +} diff --git a/pkg/utils/stime/week.go b/pkg/utils/stime/week.go new file mode 100644 index 0000000..e99e85d --- /dev/null +++ b/pkg/utils/stime/week.go @@ -0,0 +1,52 @@ +/** + * @Author Puzzle + * @Date 2022/5/20 12:54 下午 + **/ + +package stime + +import "time" + +func NowWeekDay() string { + var weekday = [7]string{"七", "一", "二", "三", "四", "五", "六"} + week := int(time.Now().Weekday()) + return weekday[week] +} + +// 获取按年算的周数 +func GetYearWeek(t *time.Time) int { + yearDay := t.YearDay() + yearFirstDay := t.AddDate(0, 0, -yearDay+1) + firstDayInWeek := int(yearFirstDay.Weekday()) + + //今年第一周有几天 + firstWeekDays := 1 + if firstDayInWeek != 0 { + firstWeekDays = 7 - firstDayInWeek + 1 + } + var week int + if yearDay <= firstWeekDays { + week = 1 + } else { + week = (yearDay-firstWeekDays)/7 + 2 + } + return week +} + +// GetWeekDate 获取基准时间范围最最近的某个星期时间 +// +// param baseOn: 基准时间 +// param weekNum: 中国星期数 1~7 +// return *time.Time +func GetWeekDate(baseOn time.Time, weekNum int) *time.Time { + if baseOn.IsZero() || (weekNum <= 0 || weekNum > 7) { + return nil + } + baseDate := time.Date(baseOn.Year(), baseOn.Month(), baseOn.Day(), 0, 0, 0, 0, Loc.Shanghai()) + var ( + w = int(baseOn.Weekday()) + weekDate time.Time + ) + weekDate = baseDate.AddDate(0, 0, weekNum-w) + return &weekDate +} diff --git a/pkg/utils/stime/week_test.go b/pkg/utils/stime/week_test.go new file mode 100644 index 0000000..5242248 --- /dev/null +++ b/pkg/utils/stime/week_test.go @@ -0,0 +1,20 @@ +// Package simpletime ----------------------------- +// @file : week_test.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2022/8/31 14:57 +// ------------------------------------------- +package stime + +import ( + "testing" + "time" +) + +func TestGetYearWeek(t *testing.T) { + now := time.Now() + t.Log(GetYearWeek(&now)) + var w = int(now.Weekday()) + t.Log(now.AddDate(0, 0, -w+1).Weekday()) + t.Log(now.AddDate(0, 0, 7-w).Weekday()) +}