diff --git a/cmd/server/wire.go b/cmd/server/wire.go index f134ef9..b20df54 100644 --- a/cmd/server/wire.go +++ b/cmd/server/wire.go @@ -5,6 +5,7 @@ package main import ( "ai_scheduler/internal/biz" + "ai_scheduler/internal/biz/handle/dingtalk" "ai_scheduler/internal/config" "ai_scheduler/internal/data/impl" "ai_scheduler/internal/pkg" @@ -29,6 +30,7 @@ func InitializeApp(*config.Config, log.AllLogger) (*server.Servers, func(), erro impl.ProviderImpl, utils.ProviderUtils, tools_bot.ProviderSetBotTools, + dingtalk.ProviderSetDingTalk, )) } diff --git a/internal/biz/ding_talk_bot.go b/internal/biz/ding_talk_bot.go index 74f2a47..d39eaf0 100644 --- a/internal/biz/ding_talk_bot.go +++ b/internal/biz/ding_talk_bot.go @@ -2,6 +2,7 @@ package biz import ( "ai_scheduler/internal/biz/do" + "ai_scheduler/internal/biz/handle/dingtalk" "ai_scheduler/internal/data/constants" "ai_scheduler/internal/data/impl" "ai_scheduler/internal/data/model" @@ -22,6 +23,7 @@ type DingTalkBotBiz struct { botConfigImpl *impl.BotConfigImpl replier *chatbot.ChatbotReplier log log.Logger + dingTalkUser *dingtalk.User } // NewDingTalkBotBiz @@ -29,12 +31,15 @@ func NewDingTalkBotBiz( do *do.Do, handle *do.Handle, botConfigImpl *impl.BotConfigImpl, + dingTalkUser *dingtalk.User, + ) *DingTalkBotBiz { return &DingTalkBotBiz{ do: do, handle: handle, botConfigImpl: botConfigImpl, replier: chatbot.NewChatbotReplier(), + dingTalkUser: dingTalkUser, } } @@ -65,8 +70,8 @@ func (d *DingTalkBotBiz) InitRequire(ctx context.Context, data *chatbot.BotCallb } entitys.ResLog(requireData.Ch, "recognize_start", "收到消息,正在处理中,请稍等") - requireData.Sys, err = d.do.GetSysInfoForDingTalkBot(requireData) - requireData.Tasks, err = d.do.GetTasks(requireData.Sys.SysID) + requireData.UserInfo, err = d.dingTalkUser.GetUserInfo(ctx, data.SenderStaffId, dingtalk.WithId(1)) + return } diff --git a/internal/biz/do/ctx.go b/internal/biz/do/ctx.go index d252c47..da0d7ae 100644 --- a/internal/biz/do/ctx.go +++ b/internal/biz/do/ctx.go @@ -225,7 +225,7 @@ func (d *Do) GetSysInfo(requireData *entitys.RequireData) (sysInfo model.AiSy, e func (d *Do) GetSysInfoForDingTalkBot(requireData *entitys.RequireDataDingTalkBot) (sysInfo model.AiSy, err error) { cond := builder.NewCond() - cond = cond.And(builder.Eq{"app_key": requireData.Key}) + cond = cond.And(builder.Eq{"app_key": requireData.Auth}) cond = cond.And(builder.IsNull{"delete_at"}) cond = cond.And(builder.Eq{"status": 1}) err = d.sysImpl.GetOneBySearchToStrut(&cond, &sysInfo) diff --git a/internal/biz/handle/dingtalk/auth.go b/internal/biz/handle/dingtalk/auth.go index 8ddd0c1..45fa566 100644 --- a/internal/biz/handle/dingtalk/auth.go +++ b/internal/biz/handle/dingtalk/auth.go @@ -3,25 +3,33 @@ package dingtalk import ( "ai_scheduler/internal/config" "ai_scheduler/internal/data/constants" + "ai_scheduler/internal/data/impl" + "ai_scheduler/internal/data/model" + "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg/l_request" + "ai_scheduler/utils" "context" "encoding/json" "errors" "net/http" "time" + "github.com/gofiber/fiber/v2/log" "github.com/redis/go-redis/v9" + "xorm.io/builder" ) type Auth struct { - redis *redis.Client - cfg *config.Config + redis *redis.Client + cfg *config.Config + botConfigImpl *impl.BotConfigImpl } -func NewAuth(cfg *config.Config, redis *redis.Client) *Auth { +func NewAuth(cfg *config.Config, redis *utils.Rdb, botConfigImpl *impl.BotConfigImpl) *Auth { return &Auth{ - redis: redis, - cfg: cfg, + redis: redis.Rdb, + cfg: cfg, + botConfigImpl: botConfigImpl, } } @@ -29,13 +37,16 @@ func (a *Auth) GetAccessToken(ctx context.Context, clientId string, clientSecret if clientId == "" { return "", errors.New("clientId is empty") } - token := a.redis.Get(ctx, a.getKey(clientId)).String() - if token == "" { + accessToken = a.redis.Get(ctx, a.getKey(clientId)).Val() + if accessToken == "" { authInfo, _err := a.getNewAccessToken(ctx, clientId, clientSecret) if _err != nil { return "", _err } - a.redis.SetEx(ctx, a.getKey(clientId), authInfo.AccessToken, time.Duration(authInfo.ExpiresIn-3600)*time.Second) + err = a.redis.SetEx(ctx, a.getKey(clientId), authInfo.AccessToken, time.Duration(authInfo.ExpireIn-3600)*time.Second).Err() + if err != nil { + return + } accessToken = authInfo.AccessToken } return @@ -53,10 +64,10 @@ func (a *Auth) getNewAccessToken(ctx context.Context, clientId string, clientSec req := l_request.Request{ Method: http.MethodPost, - Url: constants.GetDingTalkRequestUrl(constants.RequestUrlGetAccessToken, nil), - Data: map[string]string{ - "appkey": clientId, - "appsecret": clientSecret, + Url: "https://api.dingtalk.com/v1.0/oauth2/accessToken", + Json: map[string]interface{}{ + "appKey": clientId, + "appSecret": clientSecret, }, } res, err := req.Send() @@ -67,3 +78,36 @@ func (a *Auth) getNewAccessToken(ctx context.Context, clientId string, clientSec return } + +func (a *Auth) GetTokenFromBotOption(ctx context.Context, botOption ...BotOption) (token string, err error) { + botInfo := &Bot{} + for _, option := range botOption { + option(botInfo) + } + + if botInfo.id == 0 && botInfo.botConfig == nil { + err = errors.New("botInfo is nil") + return + } + if botInfo.botConfig == nil { + var botConfigDo model.AiBotConfig + cond := builder.NewCond() + cond = cond.And(builder.Eq{"bot_id": botInfo.id}) + err = a.botConfigImpl.GetOneBySearchToStrut(&cond, &botConfigDo) + if err != nil { + return + } + if botConfigDo.BotID == 0 { + return "", errors.New("未找到机器人服务配置") + } + botInfo.botConfig = &botConfigDo + } + var botConfig entitys.DingTalkBot + err = json.Unmarshal([]byte(botInfo.botConfig.BotConfig), &botConfig) + if err != nil { + log.Infof("初始化“%s”失败:%s", botInfo.botConfig.BotName, err.Error()) + return + } + return a.GetAccessToken(ctx, botConfig.ClientId, botConfig.ClientSecret) + +} diff --git a/internal/biz/handle/dingtalk/dept.go b/internal/biz/handle/dingtalk/dept.go index 14327c9..3ae1a36 100644 --- a/internal/biz/handle/dingtalk/dept.go +++ b/internal/biz/handle/dingtalk/dept.go @@ -1,35 +1,111 @@ package dingtalk import ( + "ai_scheduler/internal/data/constants" "ai_scheduler/internal/data/impl" + "ai_scheduler/internal/data/model" "ai_scheduler/internal/entitys" - "database/sql" - "errors" + "ai_scheduler/internal/pkg" + "ai_scheduler/internal/pkg/l_request" + "context" + "encoding/json" + "fmt" + "net/http" + + "xorm.io/builder" ) type Dept struct { - dingUserImpl *impl.BotUserImpl + dingDeptImpl *impl.BotDeptImpl + auth *Auth } -func NewDept(dingUserImpl *impl.BotUserImpl) *User { - return &User{ - dingUserImpl: dingUserImpl, +func NewDept(dingDeptImpl *impl.BotDeptImpl, auth *Auth) *Dept { + return &Dept{ + dingDeptImpl: dingDeptImpl, + auth: auth, } } -func (u *User) GetDeptInfo(userId string) (userInfo *entitys.DingTalkUserInfo, err error) { - if len(userId) == 0 { +func (d *Dept) GetDeptInfoByDeptIds(ctx context.Context, deptIds []int) (depts []*entitys.Dept, err error) { + if len(deptIds) == 0 { return } - user, err := u.dingUserImpl.GetByStaffId(userId) + deptsInfo := make([]model.AiBotDept, 0) + cond := builder.NewCond() + cond = cond.And(builder.Eq{"dingtalk_dept_id": deptIds}) + err = d.dingDeptImpl.GetRangeToMapStruct(&cond, deptsInfo) if err != nil { - if !errors.Is(err, sql.ErrNoRows) { - return + return + } + var existDept = make([]int, len(deptsInfo), 0) + for _, dept := range deptsInfo { + depts = append(depts, &entitys.Dept{ + DeptId: int(dept.DeptID), + Name: dept.Name, + }) + existDept = append(existDept, int(dept.DeptID)) + } + diff := pkg.Difference(deptIds, existDept) + if len(diff) > 0 { + deptDo := make([]model.AiBotDept, 0) + for _, deptId := range diff { + deptInfo, err := d.GetDeptInfoFromDingTalk(ctx, deptId) + if err != nil { + return nil, err + } + depts = append(depts, &entitys.Dept{ + DeptId: deptInfo.DeptId, + Name: deptInfo.Name, + }) + deptDo = append(deptDo, model.AiBotDept{ + DingtalkDeptID: int32(deptInfo.DeptId), + Name: deptInfo.Name, + }) + } + if len(deptDo) > 0 { + _, err = d.dingDeptImpl.Add(deptDo) + if err != nil { + return nil, err + } } } - //如果没有找到,则新增 - if user == nil { - } return } + +func (d *Dept) GetDeptInfoFromDingTalk(ctx context.Context, deptId int, botOption ...BotOption) (depts DeptResResult, err error) { + if deptId == 0 { + return + } + token, err := d.auth.GetTokenFromBotOption(ctx, botOption...) + if err != nil { + return + } + + req := l_request.Request{ + Method: http.MethodPost, + Url: constants.GetDingTalkRequestUrl(constants.RequestUrlGetDeptGet, map[string]string{ + "access_token": token, + }), + Json: map[string]interface{}{ + "dept_id": deptId, + }, + } + res, _err := req.Send() + if _err != nil { + err = _err + return + } + var deptInfo DeptRes + + err = json.Unmarshal(res.Content, &deptInfo) + if err != nil { + return + } + if deptInfo.Errcode != 0 { + fmt.Errorf("钉钉请求报错:%s", deptInfo.Errmsg) + } + return deptInfo.DeptResResult, err + +} diff --git a/internal/biz/handle/dingtalk/provider_set.go b/internal/biz/handle/dingtalk/provider_set.go new file mode 100644 index 0000000..579d464 --- /dev/null +++ b/internal/biz/handle/dingtalk/provider_set.go @@ -0,0 +1,11 @@ +package dingtalk + +import ( + "github.com/google/wire" +) + +var ProviderSetDingTalk = wire.NewSet( + NewUser, + NewAuth, + NewDept, +) diff --git a/internal/biz/handle/dingtalk/types.go b/internal/biz/handle/dingtalk/types.go index 1e9fe76..275010c 100644 --- a/internal/biz/handle/dingtalk/types.go +++ b/internal/biz/handle/dingtalk/types.go @@ -1,59 +1,78 @@ package dingtalk +import "time" + type AuthInfo struct { AccessToken string `json:"accessToken"` - ExpiresIn int64 `json:"expiresIn"` + ExpireIn int64 `json:"expireIn"` +} + +type UserInfoRes struct { + Errcode int `json:"errcode"` + Errmsg string `json:"errmsg"` + Result UserInfoResResult `json:"result"` + RequestId string `json:"request_id"` } type UserInfoResResult struct { - Errcode string `json:"errcode"` - Result Result `json:"result"` - Errmsg string `json:"errmsg"` -} -type Result struct { - Extension string `json:"extension"` - Unionid string `json:"unionid"` - Boss string `json:"boss"` - RoleList struct { - GroupName string `json:"group_name"` - Name string `json:"name"` - Id string `json:"id"` - } `json:"role_list"` - ExclusiveAccount bool `json:"exclusive_account"` - ManagerUserid string `json:"manager_userid"` - Admin string `json:"admin"` - Remark string `json:"remark"` - Title string `json:"title"` - HiredDate int `json:"hired_date"` - Userid string `json:"userid"` - WorkPlace string `json:"work_place"` - DeptOrderList struct { - DeptId string `json:"dept_id"` - Order string `json:"order"` + Active bool `json:"active"` + Admin bool `json:"admin"` + Avatar string `json:"avatar"` + Boss bool `json:"boss"` + CreateTime time.Time `json:"create_time"` + DeptIdList []int `json:"dept_id_list"` + DeptOrderList []struct { + DeptId int `json:"dept_id"` + Order int64 `json:"order"` } `json:"dept_order_list"` - RealAuthed string `json:"real_authed"` - DeptIdList string `json:"dept_id_list"` - JobNumber string `json:"job_number"` - Email string `json:"email"` - LeaderInDept struct { - Leader string `json:"leader"` - DeptId string `json:"dept_id"` + ExclusiveAccount bool `json:"exclusive_account"` + HideMobile bool `json:"hide_mobile"` + HiredDate int64 `json:"hired_date"` + JobNumber string `json:"job_number"` + LeaderInDept []struct { + DeptId int `json:"dept_id"` + Leader bool `json:"leader"` } `json:"leader_in_dept"` - Mobile string `json:"mobile"` - Active string `json:"active"` - OrgEmail string `json:"org_email"` - Telephone string `json:"telephone"` - Avatar string `json:"avatar"` - HideMobile string `json:"hide_mobile"` - Senior string `json:"senior"` - Name string `json:"name"` - UnionEmpExt struct { - UnionEmpMapList struct { - Userid string `json:"userid"` - CorpId string `json:"corp_id"` - } `json:"union_emp_map_list"` - Userid string `json:"userid"` - CorpId string `json:"corp_id"` - } `json:"union_emp_ext"` - StateCode string `json:"state_code"` + ManagerUserid string `json:"manager_userid"` + Name string `json:"name"` + RealAuthed bool `json:"real_authed"` + RoleList []struct { + GroupName string `json:"group_name"` + Id int `json:"id"` + Name string `json:"name"` + } `json:"role_list"` + Senior bool `json:"senior"` + Title string `json:"title"` + Unionid string `json:"unionid"` + Userid string `json:"userid"` +} + +type DeptRes struct { + Errcode int `json:"errcode"` + Errmsg string `json:"errmsg"` + DeptResResult DeptResResult `json:"result"` + RequestId string `json:"request_id"` +} + +type DeptResResult struct { + DeptPermits []int `json:"dept_permits"` + OuterPermitUsers []string `json:"outer_permit_users"` + DeptManagerUseridList []string `json:"dept_manager_userid_list"` + OrgDeptOwner string `json:"org_dept_owner"` + OuterDept bool `json:"outer_dept"` + DeptGroupChatId string `json:"dept_group_chat_id"` + GroupContainSubDept bool `json:"group_contain_sub_dept"` + AutoAddUser bool `json:"auto_add_user"` + HideDept bool `json:"hide_dept"` + Name string `json:"name"` + OuterPermitDepts []int `json:"outer_permit_depts"` + UserPermits []interface{} `json:"user_permits"` + DeptId int `json:"dept_id"` + CreateDeptGroup bool `json:"create_dept_group"` + Order int `json:"order"` + Code string `json:"code"` + UnionDeptExt struct { + CorpId string `json:"corp_id"` + DeptId int `json:"dept_id"` + } `json:"union_dept_ext"` } diff --git a/internal/biz/handle/dingtalk/user.go b/internal/biz/handle/dingtalk/user.go index 7d213c2..cf860f1 100644 --- a/internal/biz/handle/dingtalk/user.go +++ b/internal/biz/handle/dingtalk/user.go @@ -15,29 +15,24 @@ import ( "net/http" "strings" "time" - - "github.com/gofiber/fiber/v2/log" - "xorm.io/builder" ) type User struct { dingUserImpl *impl.BotUserImpl botConfigImpl *impl.BotConfigImpl auth *Auth - logger log.Logger + dept *Dept } func NewUser( dingUserImpl *impl.BotUserImpl, - botConfig *impl.BotConfigImpl, auth *Auth, - logger log.Logger, + dept *Dept, ) *User { return &User{ - dingUserImpl: dingUserImpl, - botConfigImpl: botConfig, - logger: logger, - auth: auth, + dingUserImpl: dingUserImpl, + auth: auth, + dept: dept, } } @@ -53,63 +48,58 @@ func (u *User) GetUserInfo(ctx context.Context, staffId string, botOption ...Bot } //如果没有找到,则新增 if user == nil { - DingUserInfo, _err := u.GetUserInfoFromDingTalkWithBot(ctx, staffId, botOption...) + DingUserInfo, _err := u.getUserInfoFromDingTalkWithBot(ctx, staffId, botOption...) if _err != nil { return nil, _err } - dingUserDo := &model.AiBotUser{ - StaffID: DingUserInfo.Userid, - Name: DingUserInfo.Name, - Title: DingUserInfo.Title, - Extension: DingUserInfo.Extension, - DeptIDList: DingUserInfo.DeptIdList, - IsBoss: int32(pkg.Ter(DingUserInfo.Boss == "true", constants.IsBossTrue, constants.IsBossFalse)), - IsSenior: int32(pkg.Ter(DingUserInfo.Boss == "true", constants.IsSeniorTrue, constants.IsSeniorFalse)), - HiredDate: time.Unix(int64(DingUserInfo.HiredDate), 0), + user = &model.AiBotUser{ + StaffID: DingUserInfo.Userid, + Name: DingUserInfo.Name, + Title: DingUserInfo.Title, + //Extension: DingUserInfo.Extension, + DeptIDList: strings.Join(pkg.SliceIntToString(DingUserInfo.DeptIdList), ","), + IsBoss: int32(pkg.Ter(DingUserInfo.Boss, constants.IsBossTrue, constants.IsBossFalse)), + IsSenior: int32(pkg.Ter(DingUserInfo.Senior, constants.IsSeniorTrue, constants.IsSeniorFalse)), + HiredDate: time.Unix(DingUserInfo.HiredDate, 0), } - //deptIdList, _err := pkg.StringToSlice(DingUserInfo.DeptIdList) - //if err != nil { - // return nil, _err - //} - dingUserDo.DeptIDList = strings.Trim(dingUserDo.DeptIDList, "[]") - } - return -} -func (u *User) GetUserInfoFromDingTalkWithBot(ctx context.Context, staffId string, botOption ...BotOption) (userInfo Result, err error) { - botInfo := &Bot{} - for _, option := range botOption { - option(botInfo) - } - - if botInfo.id == 0 && botInfo.botConfig == nil { - err = errors.New("botInfo is nil") - return - } - if botInfo.botConfig == nil { - cond := builder.NewCond() - cond = cond.And(builder.Eq{"bot_id": botInfo.id}) - err = u.botConfigImpl.GetOneBySearchToStrut(&cond, botInfo.botConfig) + _, err = u.dingUserImpl.Add(user) if err != nil { return } - } - var config entitys.DingTalkBot - err = json.Unmarshal([]byte(botInfo.botConfig.BotConfig), &config) - if err != nil { - log.Infof("初始化“%s”失败:%s", botInfo.botConfig.BotName, err.Error()) - return + userInfo = &entitys.DingTalkUserInfo{ + UserId: int(user.UserID), + StaffId: user.StaffID, + Name: user.Name, + IsBoss: constants.IsBoss(user.IsBoss), + IsSenior: constants.IsSenior(user.IsSenior), + HiredDate: user.HiredDate, + Extension: user.Extension, } - token, err := u.auth.GetAccessToken(ctx, config.ClientId, config.ClientSecret) - if err != nil { - return + if len(user.DeptIDList) > 0 { + deptIdList := pkg.SliceStringToInt(strings.Split(user.DeptIDList, ",")) + depts, _err := u.dept.GetDeptInfoByDeptIds(ctx, deptIdList) + if _err != nil { + return nil, err + } + for _, dept := range depts { + userInfo.Dept = append(userInfo.Dept, dept) + } } - return u.GetUserInfoFromDingTalk(ctx, token, staffId) + return userInfo, nil } -func (u *User) GetUserInfoFromDingTalk(ctx context.Context, token string, staffId string) (user Result, err error) { +func (u *User) getUserInfoFromDingTalkWithBot(ctx context.Context, staffId string, botOption ...BotOption) (userInfo UserInfoResResult, err error) { + token, err := u.auth.GetTokenFromBotOption(ctx, botOption...) + if err != nil { + return + } + return u.getUserInfoFromDingTalk(ctx, token, staffId) +} + +func (u *User) getUserInfoFromDingTalk(ctx context.Context, token string, staffId string) (user UserInfoResResult, err error) { if token == "" && staffId == "" { err = errors.New("获取钉钉用户信息的必要参数不足") return @@ -128,13 +118,13 @@ func (u *User) GetUserInfoFromDingTalk(ctx context.Context, token string, staffI if err != nil { return } - var userInfoResResult UserInfoResResult - err = json.Unmarshal(res.Content, &userInfoResResult) + var userInfoRes UserInfoRes + err = json.Unmarshal(res.Content, &userInfoRes) if err != nil { return } - if userInfoResResult.Errcode != "0" { - fmt.Errorf("钉钉请求报错:%s", userInfoResResult.Errmsg) + if userInfoRes.Errcode != 0 { + fmt.Errorf("钉钉请求报错:%s", userInfoRes.Errmsg) } - return userInfoResResult.Result, err + return userInfoRes.Result, err } diff --git a/internal/data/constants/dingtalk.go b/internal/data/constants/dingtalk.go index dd730cc..5c9de89 100644 --- a/internal/data/constants/dingtalk.go +++ b/internal/data/constants/dingtalk.go @@ -7,8 +7,8 @@ const DingTalkBseUrl = "https://oapi.dingtalk.com" type RequestUrl string const ( - RequestUrlGetAccessToken RequestUrl = "/v1.0/oauth2/accessToken" - RequestUrlGetUserGet RequestUrl = "/topapi/v2/user/get" + RequestUrlGetUserGet RequestUrl = "/topapi/v2/user/get" + RequestUrlGetDeptGet RequestUrl = "/topapi/v2/department/get" ) func GetDingTalkRequestUrl(path RequestUrl, query map[string]string) string { diff --git a/internal/data/impl/bot_dept.go b/internal/data/impl/bot_dept.go new file mode 100644 index 0000000..8ae0e4b --- /dev/null +++ b/internal/data/impl/bot_dept.go @@ -0,0 +1,17 @@ +package impl + +import ( + "ai_scheduler/internal/data/model" + "ai_scheduler/tmpl/dataTemp" + "ai_scheduler/utils" +) + +type BotDeptImpl struct { + dataTemp.DataTemp +} + +func NewBotDeptImpl(db *utils.Db) *BotDeptImpl { + return &BotDeptImpl{ + DataTemp: *dataTemp.NewDataTemp(db, new(model.AiBotDept)), + } +} diff --git a/internal/data/impl/bot_user.go b/internal/data/impl/bot_user.go index 25d0d16..46d8442 100644 --- a/internal/data/impl/bot_user.go +++ b/internal/data/impl/bot_user.go @@ -18,7 +18,7 @@ func NewBotUserImpl(db *utils.Db) *BotUserImpl { } func (k BotUserImpl) GetByStaffId(staffId string) (data *model.AiBotUser, err error) { - data = &model.AiBotUser{} + err = k.Db.Model(k.Model).Where("staff_id = ?", staffId).Find(data).Error if data == nil { err = sql.ErrNoRows diff --git a/internal/data/impl/provider_set.go b/internal/data/impl/provider_set.go index 53d389c..1563258 100644 --- a/internal/data/impl/provider_set.go +++ b/internal/data/impl/provider_set.go @@ -10,4 +10,7 @@ var ProviderImpl = wire.NewSet( NewTaskImpl, NewChatHisImpl, NewBotConfigImpl, + NewBotDeptImpl, + NewBotUserImpl, + NewBotChatHisImpl, ) diff --git a/internal/entitys/bot.go b/internal/entitys/bot.go index 3e59b0d..af92ba8 100644 --- a/internal/entitys/bot.go +++ b/internal/entitys/bot.go @@ -9,7 +9,7 @@ import ( type RequireDataDingTalkBot struct { Histories []model.AiChatHi - SessionInfo model.AiSession + UserInfo *DingTalkUserInfo Tasks []model.AiTask Match *Match Req *chatbot.BotCallbackDataModel diff --git a/internal/entitys/dingtalk.go b/internal/entitys/dingtalk.go index bddf9b4..3595bf3 100644 --- a/internal/entitys/dingtalk.go +++ b/internal/entitys/dingtalk.go @@ -1,17 +1,22 @@ package entitys +import ( + "ai_scheduler/internal/data/constants" + "time" +) + type DingTalkUserInfo struct { - UserId string `json:"user_id"` - StaffId string `json:"staff_id"` - Name string `json:"name"` - Dept []Dept `json:"dept"` - IsBoss int `json:"is_boss"` - IsSenior int `json:"is_senior"` - HiredDate int `json:"hired_date"` - Extension string `json:"extension"` + UserId int `json:"user_id"` + StaffId string `json:"staff_id"` + Name string `json:"name"` + Dept []*Dept `json:"dept"` + IsBoss constants.IsBoss `json:"is_boss"` + IsSenior constants.IsSenior `json:"is_senior"` + HiredDate time.Time `json:"hired_date"` + Extension string `json:"extension"` } type Dept struct { - DeptName string `json:"dept_name"` - DeptId int `json:"dept_id"` + Name string `json:"name"` + DeptId int `json:"dept_id"` } diff --git a/internal/entitys/recognize.go b/internal/entitys/recognize.go index 45d9fcc..46aef01 100644 --- a/internal/entitys/recognize.go +++ b/internal/entitys/recognize.go @@ -28,7 +28,11 @@ type RecognizeUserContent struct { type FileData []byte type RecognizeFile struct { + File Files + FileUrl []string // 文件下载链接 +} + +type Files struct { File []FileData // 文件数据(二进制格式) - FileUrl string // 文件下载链接 FileType constants.Caller // 文件类型(文件类型,能填最好填,可以跳过一层判断) } diff --git a/internal/pkg/func.go b/internal/pkg/func.go index 2197726..3e6e5b7 100644 --- a/internal/pkg/func.go +++ b/internal/pkg/func.go @@ -94,3 +94,43 @@ func StringToSlice(s string) ([]int, error) { } return result, nil } + +// Difference 差集 +func Difference[T comparable](a, b []T) []T { + // 创建 b 的映射(T 必须是可比较的类型) + bMap := make(map[T]struct{}, len(b)) + for _, item := range b { + bMap[item] = struct{}{} + } + + var diff []T // 修正为 []T 而非 []int + for _, item := range a { + if _, found := bMap[item]; !found { + diff = append(diff, item) + } + } + return diff +} + +// SliceStringToInt []string=>[]int +func SliceStringToInt(strSlice []string) []int { + numSlice := make([]int, len(strSlice), 0) + for _, str := range strSlice { + num, err := strconv.Atoi(str) + if err != nil { + return nil + } + numSlice = append(numSlice, num) + } + return numSlice +} + +// SliceIntToString []int=>[]string +func SliceIntToString(slice []int) []string { + numSlice := make([]string, len(slice), 0) + for _, str := range slice { + + numSlice = append(numSlice, strconv.Itoa(str)) + } + return numSlice +} diff --git a/utils/rds.go b/utils/rds.go index 57b89f1..874eb3e 100644 --- a/utils/rds.go +++ b/utils/rds.go @@ -13,10 +13,10 @@ type Rdb struct { var rdb *Rdb -func NewRdb(c *config.Redis) *Rdb { +func NewRdb(c *config.Config) *Rdb { if rdb == nil { //构建 redis - rdbBuild := buildRdb(c) + rdbBuild := buildRdb(&c.Redis) //退出时清理资源 rdb = &Rdb{Rdb: rdbBuild} }