diff --git a/README.md b/README.md index 5b54547..3bb10ba 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ # zbputils ZeroBot-Plugin 的工具库 + +swag初始化 + +``` +swag init -g control/web/gui.go -o control/web/docs/ +``` \ No newline at end of file diff --git a/control/web/controller/job.go b/control/web/controller/job.go new file mode 100644 index 0000000..a7788a2 --- /dev/null +++ b/control/web/controller/job.go @@ -0,0 +1,115 @@ +package controller + +import ( + "net/http" + + "github.com/FloatTech/zbputils/control/web/types" + "github.com/FloatTech/zbputils/job" + "github.com/gin-gonic/gin" +) + +// JobList 任务列表 +// +// @Tags 任务 +// @Summary 任务列表 +// @Description 任务列表 +// @Router /api/job/list [get] +// @Success 200 {object} types.Response{result=[]job.Job} "成功" +func JobList(context *gin.Context) { + rsp, err := job.List() + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: rsp, + Message: "", + ResponseType: "ok", + }) +} + +// JobAdd 添加任务 +// +// @Tags 任务 +// @Summary 添加任务 +// @Description 添加任务 +// @Router /api/job/add [post] +// @Param object body job.Job false "添加任务入参" +// @Success 200 {object} types.Response "成功" +func JobAdd(context *gin.Context) { + var ( + j job.Job + ) + err := context.ShouldBind(&j) + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + err = job.Add(&j) + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", + }) +} + +// JobDelete 删除任务 +// +// @Tags 任务 +// @Summary 删除任务 +// @Description 删除任务 +// @Router /api/job/delete [post] +// @Param object body job.DeleteReq false "删除任务的入参" +// @Success 200 {object} types.Response "成功" +func JobDelete(context *gin.Context) { + var ( + req job.DeleteReq + ) + err := context.ShouldBind(&req) + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + err = job.Delete(&req) + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", + }) +} diff --git a/control/web/controller/manage.go b/control/web/controller/manage.go index e255765..fcab5e9 100644 --- a/control/web/controller/manage.go +++ b/control/web/controller/manage.go @@ -63,7 +63,7 @@ func init() { } err := MsgConn.WriteJSON(mi) if err != nil { - log.Errorln("[gui] 推送消息发送错误:", err) + log.Errorln("[gui] 连接前端ws失败:", err) return } } @@ -75,39 +75,45 @@ func init() { } // logWriter -type logWriter struct { - // 日志连接 -} +type logWriter struct{} // GetBotList 获取机器人qq号 -// @Description 获取机器人qq号 -// @Router /api/getBotList [get] +// +// @Tags 通用 +// @Summary 获取机器人qq号 +// @Description 获取机器人qq号 +// @Router /api/getBotList [get] +// @Success 200 {object} types.Response "成功" func GetBotList(context *gin.Context) { var bots []int64 zero.RangeBot(func(id int64, ctx *zero.Ctx) bool { bots = append(bots, id) return true }) - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": bots, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: bots, + Message: "", + ResponseType: "ok", }) } // GetFriendList 获取好友列表 -// @Description 获取好友列表 -// @Router /api/getFriendList [get] -// @Param selfId query integer false "机器人qq号" default(123456) +// +// @Tags 通用 +// @Summary 获取好友列表 +// @Description 获取好友列表 +// @Router /api/getFriendList [get] +// @Param selfId query int false "机器人qq" +// @Success 200 {object} types.Response "成功" func GetFriendList(context *gin.Context) { _, bot, err := getBot(context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } @@ -115,34 +121,81 @@ func GetFriendList(context *gin.Context) { list := bot.GetFriendList().String() err = json.Unmarshal(binary.StringToBytes(list), &resp) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: resp, + Message: "", + ResponseType: "ok", + }) +} + +// GetGroupMemberList 获取群成员列表 +// +// @Tags 通用 +// @Summary 获取群成员列表 +// @Description 获取群成员列表,groupId为0的时候拉取好友信息 +// @Router /api/getGroupMemberList [get] +// @Param selfId query int false "机器人qq" +// @Param groupId query int false "群聊id" +// @Success 200 {object} types.Response "成功" +func GetGroupMemberList(context *gin.Context) { + var ( + d types.GetGroupMemberListReq + bot *zero.Ctx + ) + err := bind(&d, context) + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": resp, - "message": "", - "type": "ok", + if d.SelfID == 0 { + zero.RangeBot(func(id int64, ctx *zero.Ctx) bool { + bot = ctx + return false + }) + } else { + bot = zero.GetBot(d.SelfID) + } + var resp []any + list := bot.GetGroupMemberList(d.GroupID).String() + _ = json.Unmarshal(binary.StringToBytes(list), &resp) + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: resp, + Message: "", + ResponseType: "ok", }) } // GetGroupList 获取群列表 -// @Description 获取群列表 -// @Router /api/getGroupList [get] -// @Param selfId query integer false "机器人qq号" default(123456) +// +// @Tags 通用 +// @Summary 获取群列表 +// @Description 获取群列表 +// @Router /api/getGroupList [get] +// @Param selfId query int false "机器人qq" +// @Success 200 {object} types.Response "成功" func GetGroupList(context *gin.Context) { _, bot, err := getBot(context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } @@ -150,35 +203,88 @@ func GetGroupList(context *gin.Context) { list := bot.GetGroupList().String() err = json.Unmarshal(binary.StringToBytes(list), &resp) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", + }) + return + } + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: resp, + Message: "", + ResponseType: "ok", + }) +} + +// DeleteGroup 删除群聊或好友 +// +// @Tags 通用 +// @Summary 删除群聊或好友 +// @Description 删除群聊或好友 +// @Router /api/deleteGroup [get] +// @Param object body types.DeleteGroupParams false "删除群聊或好友入参" +// @Success 200 {object} types.Response "成功" +func DeleteGroup(context *gin.Context) { + var ( + d types.DeleteGroupParams + bot *zero.Ctx + gid int64 + ) + err := bind(&d, context) + if err != nil { + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": resp, - "message": "", - "type": "ok", + if d.SelfID == 0 { + zero.RangeBot(func(id int64, ctx *zero.Ctx) bool { + bot = ctx + return false + }) + } else { + bot = zero.GetBot(d.SelfID) + } + if d.GroupID >= 0 { + gid = d.GroupID + bot.SetGroupLeave(gid, false) + } else { + gid = -d.GroupID + bot.CallAction("delete_friend", zero.Params{ + "user_id": gid, + }) + } + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", }) } // GetAllPlugin 获取所有插件的状态 -// @Description 获取所有插件的状态 -// @Router /api/manage/getAllPlugin [get] -// @Param groupId query integer false "群号" default(0) +// +// @Tags 插件 +// @Summary 获取所有插件的状态 +// @Description 获取所有插件的状态 +// @Router /api/manage/getAllPlugin [get] +// @Param object body types.AllPluginParams false "获取所有插件的状态入参" +// @Success 200 {object} types.Response{result=[]types.PluginVo} "成功" func GetAllPlugin(context *gin.Context) { var d types.AllPluginParams err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } @@ -196,38 +302,41 @@ func GetAllPlugin(context *gin.Context) { pluginVoList = append(pluginVoList, p) return true }) - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": pluginVoList, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: pluginVoList, + Message: "", + ResponseType: "ok", }) } // GetPlugin 获取某个插件的状态 -// @Description 获取某个插件的状态 -// @Router /api/manage/getPlugin [get] -// @Param groupId query integer false "群号" default(0) -// @Param name query string false "插件名" default(antibuse) +// +// @Tags 插件 +// @Summary 获取某个插件的状态 +// @Description 获取某个插件的状态 +// @Router /api/manage/getPlugin [get] +// @Param object body types.PluginParams false "获取某个插件的状态入参" +// @Success 200 {object} types.Response{result=types.PluginVo} "成功" func GetPlugin(context *gin.Context) { var d types.PluginParams err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } con, b := control.Lookup(d.Name) if !b { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": d.Name + "服务不存在", - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: d.Name + "服务不存在", + ResponseType: "error", }) return } @@ -239,37 +348,41 @@ func GetPlugin(context *gin.Context) { PluginStatus: con.IsEnabledIn(d.GroupID), ResponseStatus: control.CanResponse(d.GroupID), } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": p, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: p, + Message: "", + ResponseType: "ok", }) } // UpdatePluginStatus 更改某一个插件状态 -// @Description 更改某一个插件状态 -// @Router /api/manage/updatePluginStatus [post] -// @Param object body types.PluginStatusParams false "修改插件状态入参" +// +// @Tags 插件 +// @Summary 更改某一个插件状态 +// @Description 更改某一个插件状态 +// @Router /api/manage/updatePluginStatus [post] +// @Param object body types.PluginStatusParams false "修改插件状态入参" +// @Success 200 {object} types.Response "成功" func UpdatePluginStatus(context *gin.Context) { var d types.PluginStatusParams err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } con, b := control.Lookup(d.Name) if !b { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": d.Name + "服务不存在", - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: d.Name + "服务不存在", + ResponseType: "error", }) return } @@ -282,27 +395,31 @@ func UpdatePluginStatus(context *gin.Context) { con.Reset(d.GroupID) default: } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": nil, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", }) } // UpdateResponseStatus 更改某一个群响应 -// @Description 更改某一个群响应 -// @Router /api/manage/updateResponseStatus [post] -// @Param object body types.ResponseStatusParams false "修改群响应入参" +// +// @Tags 响应 +// @Summary 更改某一个群响应 +// @Description 更改某一个群响应 +// @Router /api/manage/updateResponseStatus [post] +// @Param object body types.ResponseStatusParams false "修改群响应入参" +// @Success 200 {object} types.Response "成功" func UpdateResponseStatus(context *gin.Context) { var d types.ResponseStatusParams err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } @@ -312,63 +429,76 @@ func UpdateResponseStatus(context *gin.Context) { err = control.Silence(d.GroupID) } if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": nil, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", }) } // UpdateAllPluginStatus 更改某群所有插件状态 -// @Description 更改某群所有插件状态 -// @Router /api/manage/updateAllPluginStatus [post] -// @Param object body types.AllPluginStatusParams false "修改插件状态入参" +// +// @Tags 响应 +// @Summary 更改某群所有插件状态 +// @Description 更改某群所有插件状态 +// @Router /api/manage/updateAllPluginStatus [post] +// @Param object body types.AllPluginStatusParams false "修改插件状态入参" +// @Success 200 {object} types.Response "成功" func UpdateAllPluginStatus(context *gin.Context) { var d types.AllPluginStatusParams err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } - if d.Status == 1 { + switch d.Status { + case 0: + control.ForEachByPrio(func(i int, manager *ctrl.Control[*zero.Ctx]) bool { + manager.Disable(d.GroupID) + return true + }) + case 1: control.ForEachByPrio(func(i int, manager *ctrl.Control[*zero.Ctx]) bool { manager.Enable(d.GroupID) return true }) - } else { + case 2: control.ForEachByPrio(func(i int, manager *ctrl.Control[*zero.Ctx]) bool { - manager.Disable(d.GroupID) + manager.Reset(d.GroupID) return true }) + default: } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": nil, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", }) } // HandleRequest 处理一个请求 -// @Description 处理一个请求 -// @Router /api/handleRequest [post] -// @Param flag formData string true "事件id" default(abc) -// @Param reason formData string false "原因" default(abc) -// @Param approve formData bool false "是否同意" default(true) +// +// @Tags 通用 +// @Summary 处理一个请求 +// @Description 处理一个请求 +// @Router /api/handleRequest [post] +// @Param object body types.HandleRequestParams false "处理一个请求入参" +// @Success 200 {object} types.Response "成功" func HandleRequest(context *gin.Context) { var ( d types.HandleRequestParams @@ -376,21 +506,21 @@ func HandleRequest(context *gin.Context) { ) err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } r, ok := requestData.LoadAndDelete(d.Flag) if !ok { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": "flag not found", - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: "flag not found", + ResponseType: "error", }) return } @@ -407,26 +537,30 @@ func HandleRequest(context *gin.Context) { } } log.Debugln("[gui] 已处理", r.UserID, "的"+typeName) - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": nil, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", }) } // GetRequestList 获取所有的请求 -// @Description 获取所有的请求 -// @Router /api/getRequestList [get] -// @Param selfId query integer false "机器人qq号" default(123456) +// +// @Tags 通用 +// @Summary 获取所有的请求 +// @Description 获取所有的请求 +// @Router /api/getRequestList [get] +// @Param object body types.BotParams false "获取所有的请求入参" +// @Success 200 {object} types.Response{result=[]types.RequestVo} "成功" func GetRequestList(context *gin.Context) { d, bot, err := getBot(context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } @@ -448,11 +582,11 @@ func GetRequestList(context *gin.Context) { }) return true }) - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": data, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: data, + Message: "", + ResponseType: "ok", }) } @@ -475,9 +609,13 @@ func Upgrade(context *gin.Context) { } // SendMsg 前端调用发送信息 -// @Description 前端调用发送信息 -// @Router /api/sendMsg [post] -// @Param object body types.SendMsgParams false "发消息参数" +// +// @Tags 通用 +// @Summary 前端调用发送信息 +// @Description 前端调用发送信息 +// @Router /api/sendMsg [post] +// @Param object body types.SendMsgParams false "发消息参数" +// @Success 200 {object} types.Response{result=int} "成功" func SendMsg(context *gin.Context) { var ( d types.SendMsgParams @@ -485,27 +623,58 @@ func SendMsg(context *gin.Context) { ) err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } bot := zero.GetBot(d.SelfID) + all := false + for _, gid := range d.GIDList { + if gid == 0 { + all = true + break + } + } + // 避免机器人之间发消息 + botMap := make(map[int64]struct{}, 4) + zero.RangeBot(func(id int64, ctx *zero.Ctx) bool { + botMap[id] = struct{}{} + return true + }) + // 检查是否有全部群聊 + if all { + // 添加私聊 + r := make([]int64, 0, 16) + for _, v := range d.GIDList { + if v < 0 { + r = append(r, v) + } + } + d.GIDList = r + // 添加全部群聊 + for _, v := range bot.GetGroupList().Array() { + d.GIDList = append(d.GIDList, v.Get("group_id").Int()) + } + } for _, gid := range d.GIDList { if gid > 0 { msgID = bot.SendGroupMessage(gid, message.UnescapeCQCodeText(d.Message)) } else if gid < 0 { - msgID = bot.SendPrivateMessage(-gid, message.UnescapeCQCodeText(d.Message)) + _, ok := botMap[-gid] + if !ok { + msgID = bot.SendPrivateMessage(-gid, message.UnescapeCQCodeText(d.Message)) + } } } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": msgID, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: msgID, + Message: "", + ResponseType: "ok", }) } @@ -520,30 +689,33 @@ func (l logWriter) Write(p []byte) (n int, err error) { return len(p), nil } -// Login 登录接口 -// @Description 前端登录 -// @Router /api/login [post] -// @Param username formData string true "用户名" default(xiaoguofan) -// @Param password formData string true "密码" default(123456) +// Login 前端登录 +// +// @Tags 用户 +// @Summary 前端登录 +// @Description 前端登录 +// @Router /api/login [post] +// @Param object body types.LoginParams false "前端登录" +// @Success 200 {object} types.Response{result=types.LoginResultVo} "成功" func Login(context *gin.Context) { var d types.LoginParams err := bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } user, err := model.FindUser(d.Username, d.Password) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } @@ -562,17 +734,21 @@ func Login(context *gin.Context) { UserID: int(user.ID), Username: user.Username, } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": r, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: r, + Message: "", + ResponseType: "ok", }) } // GetUserInfo 获得用户信息 -// @Description 获得用户信息 -// @Router /api/getUserInfo [get] +// +// @Tags 用户 +// @Summary 获得用户信息 +// @Description 获得用户信息 +// @Router /api/getUserInfo [get] +// @Success 200 {object} types.Response{result=types.UserInfoVo} "成功" func GetUserInfo(context *gin.Context) { token := context.Request.Header.Get("Authorization") i, _ := middleware.LoginCache.Get(token) @@ -594,50 +770,58 @@ func GetUserInfo(context *gin.Context) { Username: user.Username, Avatar: "https://q1.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(qq, 10) + "&s=640", } - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": r, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: r, + Message: "", + ResponseType: "ok", }) } // Logout 登出 -// @Description 登出 -// @Router /api/logout [get] +// +// @Tags 用户 +// @Summary 登出 +// @Description 登出 +// @Router /api/logout [get] +// @Success 200 {object} types.Response "成功" func Logout(context *gin.Context) { token := context.Request.Header.Get("Authorization") middleware.LoginCache.Delete(token) - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": nil, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: nil, + Message: "", + ResponseType: "ok", }) } // GetPermCode 授权码 -// @Description 授权码 -// @Router /api/getPermCode [get] +// +// @Tags 用户 +// @Summary 授权码 +// @Description 授权码 +// @Router /api/getPermCode [get] +// @Success 200 {object} types.Response{result=[]string} "成功" func GetPermCode(context *gin.Context) { r := []string{"1000", "3000", "5000"} // 先写死接口 - context.JSON(http.StatusOK, gin.H{ - "code": 0, - "result": r, - "message": "", - "type": "ok", + context.JSON(http.StatusOK, types.Response{ + Code: 0, + Result: r, + Message: "", + ResponseType: "ok", }) } func getBot(context *gin.Context) (d types.BotParams, bot *zero.Ctx, err error) { err = bind(&d, context) if err != nil { - context.JSON(http.StatusOK, gin.H{ - "code": -1, - "result": nil, - "message": err.Error(), - "type": "error", + context.JSON(http.StatusOK, types.Response{ + Code: -1, + Result: nil, + Message: err.Error(), + ResponseType: "error", }) return } diff --git a/control/web/docs/docs.go b/control/web/docs/docs.go index cda320f..42b8ef2 100644 --- a/control/web/docs/docs.go +++ b/control/web/docs/docs.go @@ -15,169 +15,491 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/api/deleteGroup": { + "get": { + "description": "删除群聊或好友", + "tags": [ + "通用" + ], + "summary": "删除群聊或好友", + "parameters": [ + { + "description": "删除群聊或好友入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.DeleteGroupParams" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, "/api/getBotList": { "get": { "description": "获取机器人qq号", - "responses": {} + "tags": [ + "通用" + ], + "summary": "获取机器人qq号", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/getFriendList": { "get": { "description": "获取好友列表", + "tags": [ + "通用" + ], + "summary": "获取好友列表", "parameters": [ { "type": "integer", - "default": 123456, - "description": "机器人qq号", + "description": "机器人qq", "name": "selfId", "in": "query" } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/getGroupList": { "get": { "description": "获取群列表", + "tags": [ + "通用" + ], + "summary": "获取群列表", "parameters": [ { "type": "integer", - "default": 123456, - "description": "机器人qq号", + "description": "机器人qq", "name": "selfId", "in": "query" } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/getGroupMemberList": { + "get": { + "description": "获取群成员列表,groupId为0的时候拉取好友信息", + "tags": [ + "通用" + ], + "summary": "获取群成员列表", + "parameters": [ + { + "type": "integer", + "description": "机器人qq", + "name": "selfId", + "in": "query" + }, + { + "type": "integer", + "description": "群聊id", + "name": "groupId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/getPermCode": { "get": { "description": "授权码", - "responses": {} + "tags": [ + "用户" + ], + "summary": "授权码", + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + ] + } + } + } } }, "/api/getRequestList": { "get": { "description": "获取所有的请求", + "tags": [ + "通用" + ], + "summary": "获取所有的请求", "parameters": [ { - "type": "integer", - "default": 123456, - "description": "机器人qq号", - "name": "selfId", - "in": "query" + "description": "获取所有的请求入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.BotParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "$ref": "#/definitions/types.RequestVo" + } + } + } + } + ] + } + } + } } }, "/api/getUserInfo": { "get": { "description": "获得用户信息", - "responses": {} + "tags": [ + "用户" + ], + "summary": "获得用户信息", + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/types.UserInfoVo" + } + } + } + ] + } + } + } } }, "/api/handleRequest": { "post": { "description": "处理一个请求", + "tags": [ + "通用" + ], + "summary": "处理一个请求", "parameters": [ { - "type": "string", - "default": "abc", - "description": "事件id", - "name": "flag", - "in": "formData", - "required": true - }, + "description": "处理一个请求入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.HandleRequestParams" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/job/add": { + "post": { + "description": "添加任务", + "tags": [ + "任务" + ], + "summary": "添加任务", + "parameters": [ { - "type": "string", - "default": "abc", - "description": "原因", - "name": "reason", - "in": "formData" - }, + "description": "添加任务入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/job.Job" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/job/delete": { + "post": { + "description": "删除任务", + "tags": [ + "任务" + ], + "summary": "删除任务", + "parameters": [ { - "type": "boolean", - "default": true, - "description": "是否同意", - "name": "approve", - "in": "formData" + "description": "删除任务的入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/job.DeleteReq" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/job/list": { + "get": { + "description": "任务列表", + "tags": [ + "任务" + ], + "summary": "任务列表", + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "$ref": "#/definitions/job.Job" + } + } + } + } + ] + } + } + } } }, "/api/login": { "post": { "description": "前端登录", + "tags": [ + "用户" + ], + "summary": "前端登录", "parameters": [ { - "type": "string", - "default": "xiaoguofan", - "description": "用户名", - "name": "username", - "in": "formData", - "required": true - }, - { - "type": "string", - "default": "123456", - "description": "密码", - "name": "password", - "in": "formData", - "required": true + "description": "前端登录", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.LoginParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/types.LoginResultVo" + } + } + } + ] + } + } + } } }, "/api/logout": { "get": { "description": "登出", - "responses": {} + "tags": [ + "用户" + ], + "summary": "登出", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/manage/getAllPlugin": { "get": { "description": "获取所有插件的状态", + "tags": [ + "插件" + ], + "summary": "获取所有插件的状态", "parameters": [ { - "type": "integer", - "default": 0, - "description": "群号", - "name": "groupId", - "in": "query" + "description": "获取所有插件的状态入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.AllPluginParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "$ref": "#/definitions/types.PluginVo" + } + } + } + } + ] + } + } + } } }, "/api/manage/getPlugin": { "get": { "description": "获取某个插件的状态", + "tags": [ + "插件" + ], + "summary": "获取某个插件的状态", "parameters": [ { - "type": "integer", - "default": 0, - "description": "群号", - "name": "groupId", - "in": "query" - }, - { - "type": "string", - "default": "antibuse", - "description": "插件名", - "name": "name", - "in": "query" + "description": "获取某个插件的状态入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.PluginParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/types.PluginVo" + } + } + } + ] + } + } + } } }, "/api/manage/updateAllPluginStatus": { "post": { "description": "更改某群所有插件状态", + "tags": [ + "响应" + ], + "summary": "更改某群所有插件状态", "parameters": [ { "description": "修改插件状态入参", @@ -188,12 +510,23 @@ const docTemplate = `{ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/manage/updatePluginStatus": { "post": { "description": "更改某一个插件状态", + "tags": [ + "插件" + ], + "summary": "更改某一个插件状态", "parameters": [ { "description": "修改插件状态入参", @@ -204,12 +537,23 @@ const docTemplate = `{ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/manage/updateResponseStatus": { "post": { "description": "更改某一个群响应", + "tags": [ + "响应" + ], + "summary": "更改某一个群响应", "parameters": [ { "description": "修改群响应入参", @@ -220,12 +564,23 @@ const docTemplate = `{ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/sendMsg": { "post": { "description": "前端调用发送信息", + "tags": [ + "通用" + ], + "summary": "前端调用发送信息", "parameters": [ { "description": "发消息参数", @@ -236,66 +591,431 @@ const docTemplate = `{ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "integer" + } + } + } + ] + } + } + } } } }, "definitions": { + "job.DeleteReq": { + "description": "删除任务的入参", + "type": "object", + "properties": { + "idList": { + "description": "任务id", + "type": "array", + "items": { + "type": "string" + } + }, + "selfId": { + "description": "机器人qq", + "type": "integer" + } + } + }, + "job.Job": { + "description": "添加任务的入参", + "type": "object", + "properties": { + "answerType": { + "description": "回答类型, jobType=3使用的参数, 1=文本消息, 2=注入消息", + "type": "integer" + }, + "fullMatchType": { + "description": "指令别名类型, jobType=1使用的参数, 1=无状态消息, 2=主人消息", + "type": "integer" + }, + "groupId": { + "description": "群聊id, jobType=2,3使用的参数, jobType=2且私聊, group_id=0", + "type": "integer" + }, + "handler": { + "description": "执行内容", + "type": "string" + }, + "id": { + "description": "任务id", + "type": "string" + }, + "jobType": { + "description": "任务类型,1-指令别名,2-定时任务,3-你问我答", + "type": "integer" + }, + "matcher": { + "description": "当jobType=1时 为指令别名,当jobType=2时 为cron表达式,当jobType=3时 为正则表达式", + "type": "string" + }, + "questionType": { + "description": "问题类型, jobType=3使用的参数, 1=单独问, 2=所有人问", + "type": "integer" + }, + "selfId": { + "description": "机器人id", + "type": "integer" + }, + "userId": { + "description": "用户id, jobType=2,3使用的参数, 当jobType=3, QuestionType=2,userId=0", + "type": "integer" + } + } + }, + "types.AllPluginParams": { + "description": "GetAllPlugin的入参", + "type": "object", + "properties": { + "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", + "type": "integer" + } + } + }, "types.AllPluginStatusParams": { + "description": "UpdateAllPluginStatus的入参", "type": "object", "properties": { "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" }, "status": { + "description": "插件状态,0=禁用,1=启用,2=还原", + "type": "integer" + } + } + }, + "types.BotParams": { + "description": "GetGroupList,GetFriendList的入参", + "type": "object", + "properties": { + "selfId": { + "description": "机器人qq", + "type": "integer" + } + } + }, + "types.DeleteGroupParams": { + "description": "退群或删除好友的入参", + "type": "object", + "properties": { + "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", + "type": "integer" + }, + "selfId": { + "description": "机器人qq", + "type": "integer" + } + } + }, + "types.HandleRequestParams": { + "description": "处理事件的入参", + "type": "object", + "properties": { + "approve": { + "description": "是否同意, true=同意,false=拒绝", + "type": "boolean" + }, + "flag": { + "description": "事件的flag", + "type": "string" + }, + "reason": { + "description": "事件的原因, 拒绝的时候需要填", + "type": "string" + } + } + }, + "types.LoginParams": { + "description": "登录参数", + "type": "object", + "properties": { + "password": { + "description": "密码", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "types.LoginResultVo": { + "description": "登录返回参数", + "type": "object", + "properties": { + "desc": { + "description": "描述", + "type": "string" + }, + "realName": { + "description": "实际名", + "type": "string" + }, + "roles": { + "description": "角色", + "type": "array", + "items": { + "$ref": "#/definitions/types.RoleInfo" + } + }, + "token": { + "description": "token", + "type": "string" + }, + "userId": { + "description": "用户id", + "type": "integer" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "types.PluginParams": { + "description": "GetPlugin的入参", + "type": "object", + "properties": { + "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" + }, + "name": { + "description": "插件名", + "type": "string" } } }, "types.PluginStatusParams": { + "description": "UpdatePluginStatus的入参", "type": "object", "required": [ "name" ], "properties": { "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" }, "name": { + "description": "插件名", "type": "string" }, "status": { + "description": "插件状态,0=禁用,1=启用,2=还原", + "type": "integer" + } + } + }, + "types.PluginVo": { + "description": "全部插件的返回", + "type": "object", + "properties": { + "banner": { + "description": "头像", + "type": "string" + }, + "brief": { + "description": "简述", + "type": "string" + }, + "id": { + "description": "插件序号", + "type": "integer" + }, + "name": { + "description": "插件名", + "type": "string" + }, + "pluginStatus": { + "description": "插件状态,false=禁用,true=启用", + "type": "boolean" + }, + "responseStatus": { + "description": "响应状态, false=沉默,true=响应", + "type": "boolean" + }, + "usage": { + "description": "用法", + "type": "string" + } + } + }, + "types.RequestVo": { + "description": "请求返回", + "type": "object", + "properties": { + "comment": { + "description": "注释", + "type": "string" + }, + "flag": { + "description": "请求flag", + "type": "string" + }, + "groupId": { + "description": "群id", + "type": "integer" + }, + "groupName": { + "description": "群名", + "type": "string" + }, + "nickname": { + "description": "昵称", + "type": "string" + }, + "requestType": { + "description": "请求类型", + "type": "string" + }, + "selfId": { + "description": "机器人qq", + "type": "integer" + }, + "subType": { + "description": "请求子类型", + "type": "string" + }, + "userId": { + "description": "用户id", + "type": "integer" + } + } + }, + "types.Response": { + "description": "包装返回体", + "type": "object", + "properties": { + "code": { + "description": "错误码", "type": "integer" + }, + "message": { + "description": "错误信息", + "type": "string" + }, + "result": { + "description": "数据" + }, + "type": { + "description": "待定", + "type": "string" } } }, "types.ResponseStatusParams": { + "description": "UpdateResponseStatus的入参", "type": "object", "properties": { "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" }, "status": { + "description": "响应状态,0=沉默,1=响应", "type": "integer" } } }, + "types.RoleInfo": { + "description": "角色参数", + "type": "object", + "properties": { + "roleName": { + "description": "角色名", + "type": "string" + }, + "value": { + "description": "角色值", + "type": "string" + } + } + }, "types.SendMsgParams": { + "description": "处理事件的入参", "type": "object", "properties": { "gidList": { + "description": "群聊数组", "type": "array", "items": { "type": "integer" } }, "message": { + "description": "CQ码格式的消息", "type": "string" }, "selfId": { + "description": "机器人qq", "type": "integer" } } + }, + "types.UserInfoVo": { + "description": "用户信息", + "type": "object", + "properties": { + "avatar": { + "description": "头像", + "type": "string" + }, + "desc": { + "description": "描述", + "type": "string" + }, + "homePath": { + "description": "主页路径", + "type": "string" + }, + "password": { + "description": "密码", + "type": "string" + }, + "realName": { + "description": "实际名", + "type": "string" + }, + "roles": { + "description": "角色", + "type": "array", + "items": { + "$ref": "#/definitions/types.RoleInfo" + } + }, + "token": { + "description": "token", + "type": "string" + }, + "userId": { + "description": "用户id", + "type": "integer" + }, + "username": { + "description": "用户名", + "type": "string" + } + } } } }` diff --git a/control/web/docs/swagger.json b/control/web/docs/swagger.json index 4135102..9e7aaea 100644 --- a/control/web/docs/swagger.json +++ b/control/web/docs/swagger.json @@ -9,169 +9,491 @@ "host": "127.0.0.1:3000", "basePath": "/", "paths": { + "/api/deleteGroup": { + "get": { + "description": "删除群聊或好友", + "tags": [ + "通用" + ], + "summary": "删除群聊或好友", + "parameters": [ + { + "description": "删除群聊或好友入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.DeleteGroupParams" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, "/api/getBotList": { "get": { "description": "获取机器人qq号", - "responses": {} + "tags": [ + "通用" + ], + "summary": "获取机器人qq号", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/getFriendList": { "get": { "description": "获取好友列表", + "tags": [ + "通用" + ], + "summary": "获取好友列表", "parameters": [ { "type": "integer", - "default": 123456, - "description": "机器人qq号", + "description": "机器人qq", "name": "selfId", "in": "query" } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/getGroupList": { "get": { "description": "获取群列表", + "tags": [ + "通用" + ], + "summary": "获取群列表", "parameters": [ { "type": "integer", - "default": 123456, - "description": "机器人qq号", + "description": "机器人qq", "name": "selfId", "in": "query" } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/getGroupMemberList": { + "get": { + "description": "获取群成员列表,groupId为0的时候拉取好友信息", + "tags": [ + "通用" + ], + "summary": "获取群成员列表", + "parameters": [ + { + "type": "integer", + "description": "机器人qq", + "name": "selfId", + "in": "query" + }, + { + "type": "integer", + "description": "群聊id", + "name": "groupId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/getPermCode": { "get": { "description": "授权码", - "responses": {} + "tags": [ + "用户" + ], + "summary": "授权码", + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + ] + } + } + } } }, "/api/getRequestList": { "get": { "description": "获取所有的请求", + "tags": [ + "通用" + ], + "summary": "获取所有的请求", "parameters": [ { - "type": "integer", - "default": 123456, - "description": "机器人qq号", - "name": "selfId", - "in": "query" + "description": "获取所有的请求入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.BotParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "$ref": "#/definitions/types.RequestVo" + } + } + } + } + ] + } + } + } } }, "/api/getUserInfo": { "get": { "description": "获得用户信息", - "responses": {} + "tags": [ + "用户" + ], + "summary": "获得用户信息", + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/types.UserInfoVo" + } + } + } + ] + } + } + } } }, "/api/handleRequest": { "post": { "description": "处理一个请求", + "tags": [ + "通用" + ], + "summary": "处理一个请求", "parameters": [ { - "type": "string", - "default": "abc", - "description": "事件id", - "name": "flag", - "in": "formData", - "required": true - }, + "description": "处理一个请求入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.HandleRequestParams" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/job/add": { + "post": { + "description": "添加任务", + "tags": [ + "任务" + ], + "summary": "添加任务", + "parameters": [ { - "type": "string", - "default": "abc", - "description": "原因", - "name": "reason", - "in": "formData" - }, + "description": "添加任务入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/job.Job" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/job/delete": { + "post": { + "description": "删除任务", + "tags": [ + "任务" + ], + "summary": "删除任务", + "parameters": [ { - "type": "boolean", - "default": true, - "description": "是否同意", - "name": "approve", - "in": "formData" + "description": "删除任务的入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/job.DeleteReq" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } + } + }, + "/api/job/list": { + "get": { + "description": "任务列表", + "tags": [ + "任务" + ], + "summary": "任务列表", + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "$ref": "#/definitions/job.Job" + } + } + } + } + ] + } + } + } } }, "/api/login": { "post": { "description": "前端登录", + "tags": [ + "用户" + ], + "summary": "前端登录", "parameters": [ { - "type": "string", - "default": "xiaoguofan", - "description": "用户名", - "name": "username", - "in": "formData", - "required": true - }, - { - "type": "string", - "default": "123456", - "description": "密码", - "name": "password", - "in": "formData", - "required": true + "description": "前端登录", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.LoginParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/types.LoginResultVo" + } + } + } + ] + } + } + } } }, "/api/logout": { "get": { "description": "登出", - "responses": {} + "tags": [ + "用户" + ], + "summary": "登出", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/manage/getAllPlugin": { "get": { "description": "获取所有插件的状态", + "tags": [ + "插件" + ], + "summary": "获取所有插件的状态", "parameters": [ { - "type": "integer", - "default": 0, - "description": "群号", - "name": "groupId", - "in": "query" + "description": "获取所有插件的状态入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.AllPluginParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "array", + "items": { + "$ref": "#/definitions/types.PluginVo" + } + } + } + } + ] + } + } + } } }, "/api/manage/getPlugin": { "get": { "description": "获取某个插件的状态", + "tags": [ + "插件" + ], + "summary": "获取某个插件的状态", "parameters": [ { - "type": "integer", - "default": 0, - "description": "群号", - "name": "groupId", - "in": "query" - }, - { - "type": "string", - "default": "antibuse", - "description": "插件名", - "name": "name", - "in": "query" + "description": "获取某个插件的状态入参", + "name": "object", + "in": "body", + "schema": { + "$ref": "#/definitions/types.PluginParams" + } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/types.PluginVo" + } + } + } + ] + } + } + } } }, "/api/manage/updateAllPluginStatus": { "post": { "description": "更改某群所有插件状态", + "tags": [ + "响应" + ], + "summary": "更改某群所有插件状态", "parameters": [ { "description": "修改插件状态入参", @@ -182,12 +504,23 @@ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/manage/updatePluginStatus": { "post": { "description": "更改某一个插件状态", + "tags": [ + "插件" + ], + "summary": "更改某一个插件状态", "parameters": [ { "description": "修改插件状态入参", @@ -198,12 +531,23 @@ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/manage/updateResponseStatus": { "post": { "description": "更改某一个群响应", + "tags": [ + "响应" + ], + "summary": "更改某一个群响应", "parameters": [ { "description": "修改群响应入参", @@ -214,12 +558,23 @@ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/types.Response" + } + } + } } }, "/api/sendMsg": { "post": { "description": "前端调用发送信息", + "tags": [ + "通用" + ], + "summary": "前端调用发送信息", "parameters": [ { "description": "发消息参数", @@ -230,66 +585,431 @@ } } ], - "responses": {} + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.Response" + }, + { + "type": "object", + "properties": { + "result": { + "type": "integer" + } + } + } + ] + } + } + } } } }, "definitions": { + "job.DeleteReq": { + "description": "删除任务的入参", + "type": "object", + "properties": { + "idList": { + "description": "任务id", + "type": "array", + "items": { + "type": "string" + } + }, + "selfId": { + "description": "机器人qq", + "type": "integer" + } + } + }, + "job.Job": { + "description": "添加任务的入参", + "type": "object", + "properties": { + "answerType": { + "description": "回答类型, jobType=3使用的参数, 1=文本消息, 2=注入消息", + "type": "integer" + }, + "fullMatchType": { + "description": "指令别名类型, jobType=1使用的参数, 1=无状态消息, 2=主人消息", + "type": "integer" + }, + "groupId": { + "description": "群聊id, jobType=2,3使用的参数, jobType=2且私聊, group_id=0", + "type": "integer" + }, + "handler": { + "description": "执行内容", + "type": "string" + }, + "id": { + "description": "任务id", + "type": "string" + }, + "jobType": { + "description": "任务类型,1-指令别名,2-定时任务,3-你问我答", + "type": "integer" + }, + "matcher": { + "description": "当jobType=1时 为指令别名,当jobType=2时 为cron表达式,当jobType=3时 为正则表达式", + "type": "string" + }, + "questionType": { + "description": "问题类型, jobType=3使用的参数, 1=单独问, 2=所有人问", + "type": "integer" + }, + "selfId": { + "description": "机器人id", + "type": "integer" + }, + "userId": { + "description": "用户id, jobType=2,3使用的参数, 当jobType=3, QuestionType=2,userId=0", + "type": "integer" + } + } + }, + "types.AllPluginParams": { + "description": "GetAllPlugin的入参", + "type": "object", + "properties": { + "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", + "type": "integer" + } + } + }, "types.AllPluginStatusParams": { + "description": "UpdateAllPluginStatus的入参", "type": "object", "properties": { "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" }, "status": { + "description": "插件状态,0=禁用,1=启用,2=还原", + "type": "integer" + } + } + }, + "types.BotParams": { + "description": "GetGroupList,GetFriendList的入参", + "type": "object", + "properties": { + "selfId": { + "description": "机器人qq", + "type": "integer" + } + } + }, + "types.DeleteGroupParams": { + "description": "退群或删除好友的入参", + "type": "object", + "properties": { + "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", + "type": "integer" + }, + "selfId": { + "description": "机器人qq", + "type": "integer" + } + } + }, + "types.HandleRequestParams": { + "description": "处理事件的入参", + "type": "object", + "properties": { + "approve": { + "description": "是否同意, true=同意,false=拒绝", + "type": "boolean" + }, + "flag": { + "description": "事件的flag", + "type": "string" + }, + "reason": { + "description": "事件的原因, 拒绝的时候需要填", + "type": "string" + } + } + }, + "types.LoginParams": { + "description": "登录参数", + "type": "object", + "properties": { + "password": { + "description": "密码", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "types.LoginResultVo": { + "description": "登录返回参数", + "type": "object", + "properties": { + "desc": { + "description": "描述", + "type": "string" + }, + "realName": { + "description": "实际名", + "type": "string" + }, + "roles": { + "description": "角色", + "type": "array", + "items": { + "$ref": "#/definitions/types.RoleInfo" + } + }, + "token": { + "description": "token", + "type": "string" + }, + "userId": { + "description": "用户id", + "type": "integer" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "types.PluginParams": { + "description": "GetPlugin的入参", + "type": "object", + "properties": { + "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" + }, + "name": { + "description": "插件名", + "type": "string" } } }, "types.PluginStatusParams": { + "description": "UpdatePluginStatus的入参", "type": "object", "required": [ "name" ], "properties": { "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" }, "name": { + "description": "插件名", "type": "string" }, "status": { + "description": "插件状态,0=禁用,1=启用,2=还原", + "type": "integer" + } + } + }, + "types.PluginVo": { + "description": "全部插件的返回", + "type": "object", + "properties": { + "banner": { + "description": "头像", + "type": "string" + }, + "brief": { + "description": "简述", + "type": "string" + }, + "id": { + "description": "插件序号", + "type": "integer" + }, + "name": { + "description": "插件名", + "type": "string" + }, + "pluginStatus": { + "description": "插件状态,false=禁用,true=启用", + "type": "boolean" + }, + "responseStatus": { + "description": "响应状态, false=沉默,true=响应", + "type": "boolean" + }, + "usage": { + "description": "用法", + "type": "string" + } + } + }, + "types.RequestVo": { + "description": "请求返回", + "type": "object", + "properties": { + "comment": { + "description": "注释", + "type": "string" + }, + "flag": { + "description": "请求flag", + "type": "string" + }, + "groupId": { + "description": "群id", + "type": "integer" + }, + "groupName": { + "description": "群名", + "type": "string" + }, + "nickname": { + "description": "昵称", + "type": "string" + }, + "requestType": { + "description": "请求类型", + "type": "string" + }, + "selfId": { + "description": "机器人qq", + "type": "integer" + }, + "subType": { + "description": "请求子类型", + "type": "string" + }, + "userId": { + "description": "用户id", + "type": "integer" + } + } + }, + "types.Response": { + "description": "包装返回体", + "type": "object", + "properties": { + "code": { + "description": "错误码", "type": "integer" + }, + "message": { + "description": "错误信息", + "type": "string" + }, + "result": { + "description": "数据" + }, + "type": { + "description": "待定", + "type": "string" } } }, "types.ResponseStatusParams": { + "description": "UpdateResponseStatus的入参", "type": "object", "properties": { "groupId": { + "description": "群id, gid\u003e0为群聊,gid\u003c0为私聊,gid=0为全部群聊", "type": "integer" }, "status": { + "description": "响应状态,0=沉默,1=响应", "type": "integer" } } }, + "types.RoleInfo": { + "description": "角色参数", + "type": "object", + "properties": { + "roleName": { + "description": "角色名", + "type": "string" + }, + "value": { + "description": "角色值", + "type": "string" + } + } + }, "types.SendMsgParams": { + "description": "处理事件的入参", "type": "object", "properties": { "gidList": { + "description": "群聊数组", "type": "array", "items": { "type": "integer" } }, "message": { + "description": "CQ码格式的消息", "type": "string" }, "selfId": { + "description": "机器人qq", "type": "integer" } } + }, + "types.UserInfoVo": { + "description": "用户信息", + "type": "object", + "properties": { + "avatar": { + "description": "头像", + "type": "string" + }, + "desc": { + "description": "描述", + "type": "string" + }, + "homePath": { + "description": "主页路径", + "type": "string" + }, + "password": { + "description": "密码", + "type": "string" + }, + "realName": { + "description": "实际名", + "type": "string" + }, + "roles": { + "description": "角色", + "type": "array", + "items": { + "$ref": "#/definitions/types.RoleInfo" + } + }, + "token": { + "description": "token", + "type": "string" + }, + "userId": { + "description": "用户id", + "type": "integer" + }, + "username": { + "description": "用户名", + "type": "string" + } + } } } } \ No newline at end of file diff --git a/control/web/docs/swagger.yaml b/control/web/docs/swagger.yaml index a2fa660..797cacd 100644 --- a/control/web/docs/swagger.yaml +++ b/control/web/docs/swagger.yaml @@ -1,40 +1,295 @@ basePath: / definitions: + job.DeleteReq: + description: 删除任务的入参 + properties: + idList: + description: 任务id + items: + type: string + type: array + selfId: + description: 机器人qq + type: integer + type: object + job.Job: + description: 添加任务的入参 + properties: + answerType: + description: 回答类型, jobType=3使用的参数, 1=文本消息, 2=注入消息 + type: integer + fullMatchType: + description: 指令别名类型, jobType=1使用的参数, 1=无状态消息, 2=主人消息 + type: integer + groupId: + description: 群聊id, jobType=2,3使用的参数, jobType=2且私聊, group_id=0 + type: integer + handler: + description: 执行内容 + type: string + id: + description: 任务id + type: string + jobType: + description: 任务类型,1-指令别名,2-定时任务,3-你问我答 + type: integer + matcher: + description: 当jobType=1时 为指令别名,当jobType=2时 为cron表达式,当jobType=3时 为正则表达式 + type: string + questionType: + description: 问题类型, jobType=3使用的参数, 1=单独问, 2=所有人问 + type: integer + selfId: + description: 机器人id + type: integer + userId: + description: 用户id, jobType=2,3使用的参数, 当jobType=3, QuestionType=2,userId=0 + type: integer + type: object + types.AllPluginParams: + description: GetAllPlugin的入参 + properties: + groupId: + description: 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + type: integer + type: object types.AllPluginStatusParams: + description: UpdateAllPluginStatus的入参 properties: groupId: + description: 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 type: integer status: + description: 插件状态,0=禁用,1=启用,2=还原 + type: integer + type: object + types.BotParams: + description: GetGroupList,GetFriendList的入参 + properties: + selfId: + description: 机器人qq + type: integer + type: object + types.DeleteGroupParams: + description: 退群或删除好友的入参 + properties: + groupId: + description: 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + type: integer + selfId: + description: 机器人qq + type: integer + type: object + types.HandleRequestParams: + description: 处理事件的入参 + properties: + approve: + description: 是否同意, true=同意,false=拒绝 + type: boolean + flag: + description: 事件的flag + type: string + reason: + description: 事件的原因, 拒绝的时候需要填 + type: string + type: object + types.LoginParams: + description: 登录参数 + properties: + password: + description: 密码 + type: string + username: + description: 用户名 + type: string + type: object + types.LoginResultVo: + description: 登录返回参数 + properties: + desc: + description: 描述 + type: string + realName: + description: 实际名 + type: string + roles: + description: 角色 + items: + $ref: '#/definitions/types.RoleInfo' + type: array + token: + description: token + type: string + userId: + description: 用户id type: integer + username: + description: 用户名 + type: string + type: object + types.PluginParams: + description: GetPlugin的入参 + properties: + groupId: + description: 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + type: integer + name: + description: 插件名 + type: string type: object types.PluginStatusParams: + description: UpdatePluginStatus的入参 properties: groupId: + description: 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 type: integer name: + description: 插件名 type: string status: + description: 插件状态,0=禁用,1=启用,2=还原 type: integer required: - name type: object + types.PluginVo: + description: 全部插件的返回 + properties: + banner: + description: 头像 + type: string + brief: + description: 简述 + type: string + id: + description: 插件序号 + type: integer + name: + description: 插件名 + type: string + pluginStatus: + description: 插件状态,false=禁用,true=启用 + type: boolean + responseStatus: + description: 响应状态, false=沉默,true=响应 + type: boolean + usage: + description: 用法 + type: string + type: object + types.RequestVo: + description: 请求返回 + properties: + comment: + description: 注释 + type: string + flag: + description: 请求flag + type: string + groupId: + description: 群id + type: integer + groupName: + description: 群名 + type: string + nickname: + description: 昵称 + type: string + requestType: + description: 请求类型 + type: string + selfId: + description: 机器人qq + type: integer + subType: + description: 请求子类型 + type: string + userId: + description: 用户id + type: integer + type: object + types.Response: + description: 包装返回体 + properties: + code: + description: 错误码 + type: integer + message: + description: 错误信息 + type: string + result: + description: 数据 + type: + description: 待定 + type: string + type: object types.ResponseStatusParams: + description: UpdateResponseStatus的入参 properties: groupId: + description: 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 type: integer status: + description: 响应状态,0=沉默,1=响应 type: integer type: object + types.RoleInfo: + description: 角色参数 + properties: + roleName: + description: 角色名 + type: string + value: + description: 角色值 + type: string + type: object types.SendMsgParams: + description: 处理事件的入参 properties: gidList: + description: 群聊数组 items: type: integer type: array message: + description: CQ码格式的消息 type: string selfId: + description: 机器人qq + type: integer + type: object + types.UserInfoVo: + description: 用户信息 + properties: + avatar: + description: 头像 + type: string + desc: + description: 描述 + type: string + homePath: + description: 主页路径 + type: string + password: + description: 密码 + type: string + realName: + description: 实际名 + type: string + roles: + description: 角色 + items: + $ref: '#/definitions/types.RoleInfo' + type: array + token: + description: token + type: string + userId: + description: 用户id type: integer + username: + description: 用户名 + type: string type: object host: 127.0.0.1:3000 info: @@ -43,115 +298,292 @@ info: title: zbp api version: "1.0" paths: + /api/deleteGroup: + get: + description: 删除群聊或好友 + parameters: + - description: 删除群聊或好友入参 + in: body + name: object + schema: + $ref: '#/definitions/types.DeleteGroupParams' + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 删除群聊或好友 + tags: + - 通用 /api/getBotList: get: description: 获取机器人qq号 - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 获取机器人qq号 + tags: + - 通用 /api/getFriendList: get: description: 获取好友列表 parameters: - - default: 123456 - description: 机器人qq号 + - description: 机器人qq in: query name: selfId type: integer - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 获取好友列表 + tags: + - 通用 /api/getGroupList: get: description: 获取群列表 parameters: - - default: 123456 - description: 机器人qq号 + - description: 机器人qq in: query name: selfId type: integer - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 获取群列表 + tags: + - 通用 + /api/getGroupMemberList: + get: + description: 获取群成员列表,groupId为0的时候拉取好友信息 + parameters: + - description: 机器人qq + in: query + name: selfId + type: integer + - description: 群聊id + in: query + name: groupId + type: integer + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 获取群成员列表 + tags: + - 通用 /api/getPermCode: get: description: 授权码 - responses: {} + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + items: + type: string + type: array + type: object + summary: 授权码 + tags: + - 用户 /api/getRequestList: get: description: 获取所有的请求 parameters: - - default: 123456 - description: 机器人qq号 - in: query - name: selfId - type: integer - responses: {} + - description: 获取所有的请求入参 + in: body + name: object + schema: + $ref: '#/definitions/types.BotParams' + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + items: + $ref: '#/definitions/types.RequestVo' + type: array + type: object + summary: 获取所有的请求 + tags: + - 通用 /api/getUserInfo: get: description: 获得用户信息 - responses: {} + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + $ref: '#/definitions/types.UserInfoVo' + type: object + summary: 获得用户信息 + tags: + - 用户 /api/handleRequest: post: description: 处理一个请求 parameters: - - default: abc - description: 事件id - in: formData - name: flag - required: true - type: string - - default: abc - description: 原因 - in: formData - name: reason - type: string - - default: true - description: 是否同意 - in: formData - name: approve - type: boolean - responses: {} + - description: 处理一个请求入参 + in: body + name: object + schema: + $ref: '#/definitions/types.HandleRequestParams' + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 处理一个请求 + tags: + - 通用 + /api/job/add: + post: + description: 添加任务 + parameters: + - description: 添加任务入参 + in: body + name: object + schema: + $ref: '#/definitions/job.Job' + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 添加任务 + tags: + - 任务 + /api/job/delete: + post: + description: 删除任务 + parameters: + - description: 删除任务的入参 + in: body + name: object + schema: + $ref: '#/definitions/job.DeleteReq' + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 删除任务 + tags: + - 任务 + /api/job/list: + get: + description: 任务列表 + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + items: + $ref: '#/definitions/job.Job' + type: array + type: object + summary: 任务列表 + tags: + - 任务 /api/login: post: description: 前端登录 parameters: - - default: xiaoguofan - description: 用户名 - in: formData - name: username - required: true - type: string - - default: "123456" - description: 密码 - in: formData - name: password - required: true - type: string - responses: {} + - description: 前端登录 + in: body + name: object + schema: + $ref: '#/definitions/types.LoginParams' + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + $ref: '#/definitions/types.LoginResultVo' + type: object + summary: 前端登录 + tags: + - 用户 /api/logout: get: description: 登出 - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 登出 + tags: + - 用户 /api/manage/getAllPlugin: get: description: 获取所有插件的状态 parameters: - - default: 0 - description: 群号 - in: query - name: groupId - type: integer - responses: {} + - description: 获取所有插件的状态入参 + in: body + name: object + schema: + $ref: '#/definitions/types.AllPluginParams' + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + items: + $ref: '#/definitions/types.PluginVo' + type: array + type: object + summary: 获取所有插件的状态 + tags: + - 插件 /api/manage/getPlugin: get: description: 获取某个插件的状态 parameters: - - default: 0 - description: 群号 - in: query - name: groupId - type: integer - - default: antibuse - description: 插件名 - in: query - name: name - type: string - responses: {} + - description: 获取某个插件的状态入参 + in: body + name: object + schema: + $ref: '#/definitions/types.PluginParams' + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + $ref: '#/definitions/types.PluginVo' + type: object + summary: 获取某个插件的状态 + tags: + - 插件 /api/manage/updateAllPluginStatus: post: description: 更改某群所有插件状态 @@ -161,7 +593,14 @@ paths: name: object schema: $ref: '#/definitions/types.AllPluginStatusParams' - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 更改某群所有插件状态 + tags: + - 响应 /api/manage/updatePluginStatus: post: description: 更改某一个插件状态 @@ -171,7 +610,14 @@ paths: name: object schema: $ref: '#/definitions/types.PluginStatusParams' - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 更改某一个插件状态 + tags: + - 插件 /api/manage/updateResponseStatus: post: description: 更改某一个群响应 @@ -181,7 +627,14 @@ paths: name: object schema: $ref: '#/definitions/types.ResponseStatusParams' - responses: {} + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/types.Response' + summary: 更改某一个群响应 + tags: + - 响应 /api/sendMsg: post: description: 前端调用发送信息 @@ -191,5 +644,17 @@ paths: name: object schema: $ref: '#/definitions/types.SendMsgParams' - responses: {} + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/types.Response' + - properties: + result: + type: integer + type: object + summary: 前端调用发送信息 + tags: + - 通用 swagger: "2.0" diff --git a/control/web/gui.go b/control/web/gui.go index bfd2881..6236b08 100644 --- a/control/web/gui.go +++ b/control/web/gui.go @@ -44,23 +44,29 @@ func init() { Handle(func(ctx *zero.Ctx) { args := ctx.State["args"].(string) args = strings.TrimSpace(args) - listenCtrlChan <- args == "启动" - ctx.SendChain(message.Text("webui" + args + "成功")) + isSuccess := args == "启动" + listenCtrlChan <- isSuccess + if isSuccess { + ctx.SendChain(message.Text("成功, webui启动")) + } else { + ctx.SendChain(message.Text("成功, webui停止")) + } + }) } // RunGui 运行webui -// @title zbp api -// @version 1.0 -// @description zbp restful api document -// @host 127.0.0.1:3000 -// @BasePath / +// @title zbp api +// @version 1.0 +// @description zbp restful api document +// @host 127.0.0.1:3000 +// @BasePath / func RunGui(addr string) { defer func() { err := recover() if err != nil { log.Errorln("[gui] ZeroBot-Plugin-Webui出现不可恢复的错误") - log.Errorln("[gui] err:", err, ",stack:", debug.Stack()) + log.Errorln("[gui] err:", err, ", stack:", debug.Stack()) } }() @@ -82,6 +88,11 @@ func RunGui(addr string) { }), Addr: addr, } + log.Infoln("[gui] the webui is running on", "http://"+addr) + log.Infoln("[gui] you can see api by http://" + addr + "/swagger/index.html") + if err := server.ListenAndServe(); err != nil { + log.Errorln("[gui] server listen err: ", err.Error()) + } for canrun := range listenCtrlChan { if canrun { if err := server.Shutdown(context.TODO()); err != nil { diff --git a/control/web/router/router.go b/control/web/router/router.go index 8d02092..b618cd8 100644 --- a/control/web/router/router.go +++ b/control/web/router/router.go @@ -17,15 +17,24 @@ func SetRouters(engine *gin.Engine) { // 支持跨域 engine.Use(middleware.Cors(), gin.Logger()) + // 通用接口 apiRoute := engine.Group("/api") apiRoute.Use(middleware.TokenMiddle()) apiRoute.GET("/getFriendList", controller.GetFriendList) apiRoute.GET("/getGroupList", controller.GetGroupList) + apiRoute.GET("/getGroupMemberList", controller.GetGroupMemberList) apiRoute.GET("/getRequestList", controller.GetRequestList) apiRoute.POST("/handleRequest", controller.HandleRequest) apiRoute.POST("/sendMsg", controller.SendMsg) apiRoute.GET("/getUserInfo", controller.GetUserInfo) + // 任务相关接口 + jobRoute := apiRoute.Group("/job") + jobRoute.GET("/list", controller.JobList) + jobRoute.POST("/add", controller.JobAdd) + jobRoute.POST("/delete", controller.JobDelete) + + // 管理相关接口 manageRoute := apiRoute.Group("/manage") manageRoute.GET("/getPlugin", controller.GetPlugin) manageRoute.GET("/getAllPlugin", controller.GetAllPlugin) diff --git a/control/web/types/types.go b/control/web/types/types.go index b3ed09f..3456a25 100644 --- a/control/web/types/types.go +++ b/control/web/types/types.go @@ -1,121 +1,159 @@ // Package types 结构体 package types +// Response 包装返回体 +// @Description 包装返回体 +type Response struct { + Code int `json:"code"` // 错误码 + Message string `json:"message"` // 错误信息 + Result interface{} `json:"result"` // 数据 + ResponseType string `json:"type"` // 待定 +} + // BotParams GetGroupList,GetFriendList的入参 +// @Description GetGroupList,GetFriendList的入参 type BotParams struct { - SelfID int64 `json:"selfId" form:"selfId"` + SelfID int64 `json:"selfId" form:"selfId"` // 机器人qq +} + +// GetGroupMemberListReq 获得群成员的入参 +// @Description 获得群成员的入参 +type GetGroupMemberListReq struct { + SelfID int64 `json:"selfId" form:"selfId"` // 机器人qq + GroupID int64 `json:"groupId" form:"groupId"` // 群id } // AllPluginParams GetAllPlugin的入参 +// @Description GetAllPlugin的入参 type AllPluginParams struct { - GroupID int64 `json:"groupId" form:"groupId"` + GroupID int64 `json:"groupId" form:"groupId"` // 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 +} + +// DeleteGroupParams 退群或删除好友的入参 +// @Description 退群或删除好友的入参 +type DeleteGroupParams struct { + SelfID int64 `json:"selfId" form:"selfId"` // 机器人qq + GroupID int64 `json:"groupId" form:"groupId"` // 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 } // PluginParams GetPlugin的入参 +// @Description GetPlugin的入参 type PluginParams struct { - GroupID int64 `json:"groupId" form:"groupId"` - Name string `json:"name" form:"name"` + GroupID int64 `json:"groupId" form:"groupId"` // 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + Name string `json:"name" form:"name"` // 插件名 } -// PluginStatusParams UpdatePluginStatus的入参, Status,0=禁用,1=启用,2=还原 +// PluginStatusParams UpdatePluginStatus的入参 +// @Description UpdatePluginStatus的入参 type PluginStatusParams struct { - GroupID int64 `json:"groupId" form:"groupId"` - Name string `json:"name" form:"name" validate:"required"` - Status int `json:"status" form:"status"` + GroupID int64 `json:"groupId" form:"groupId"` // 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + Name string `json:"name" form:"name" validate:"required"` // 插件名 + Status int `json:"status" form:"status"` // 插件状态,0=禁用,1=启用,2=还原 } -// ResponseStatusParams UpdateResponseStatus的入参, Status,0=沉默,1=响应 +// ResponseStatusParams UpdateResponseStatus的入参 +// @Description UpdateResponseStatus的入参 type ResponseStatusParams struct { - GroupID int64 `json:"groupId" form:"groupId"` - Status int `json:"status" form:"status"` + GroupID int64 `json:"groupId" form:"groupId"` // 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + Status int `json:"status" form:"status"` // 响应状态,0=沉默,1=响应 } // AllPluginStatusParams UpdateAllPluginStatus的入参 +// @Description UpdateAllPluginStatus的入参 type AllPluginStatusParams struct { - GroupID int64 `json:"groupId" form:"groupId"` - Status int `json:"status" form:"status"` + GroupID int64 `json:"groupId" form:"groupId"` // 群id, gid>0为群聊,gid<0为私聊,gid=0为全部群聊 + Status int `json:"status" form:"status"` // 插件状态,0=禁用,1=启用,2=还原 } // HandleRequestParams 处理事件的入参 +// @Description 处理事件的入参 type HandleRequestParams struct { - Flag string `json:"flag" form:"flag"` - Reason string `json:"reason" form:"reason"` - Approve bool `json:"approve" form:"approve"` + Flag string `json:"flag" form:"flag"` // 事件的flag + Reason string `json:"reason" form:"reason"` // 事件的原因, 拒绝的时候需要填 + Approve bool `json:"approve" form:"approve"` // 是否同意, true=同意,false=拒绝 } // SendMsgParams 发送消息的入参 +// @Description 处理事件的入参 type SendMsgParams struct { - SelfID int64 `json:"selfId" form:"selfId"` - GIDList []int64 `json:"gidList" form:"gidList"` - Message string `json:"message" form:"message"` + SelfID int64 `json:"selfId" form:"selfId"` // 机器人qq + GIDList []int64 `json:"gidList" form:"gidList"` // 群聊数组 + Message string `json:"message" form:"message"` // CQ码格式的消息 } // LoginParams 登录参数 +// @Description 登录参数 type LoginParams struct { - Username string `json:"username" form:"username"` - Password string `json:"password" form:"password"` + Username string `json:"username" form:"username"` // 用户名 + Password string `json:"password" form:"password"` // 密码 } // LoginResultVo 登录返回参数 +// @Description 登录返回参数 type LoginResultVo struct { - UserID int `json:"userId"` - Username string `json:"username"` - RealName string `json:"realName"` - Desc string `json:"desc"` - Token string `json:"token"` - Roles []RoleInfo `json:"roles"` + UserID int `json:"userId"` // 用户id + Username string `json:"username"` // 用户名 + RealName string `json:"realName"` // 实际名 + Desc string `json:"desc"` // 描述 + Token string `json:"token"` // token + Roles []RoleInfo `json:"roles"` // 角色 } // RoleInfo 角色参数 +// @Description 角色参数 type RoleInfo struct { - RoleName string `json:"roleName"` - Value string `json:"value"` + RoleName string `json:"roleName"` // 角色名 + Value string `json:"value"` // 角色值 } // UserInfoVo 用户信息 +// @Description 用户信息 type UserInfoVo struct { - UserID int `json:"userId"` - Username string `json:"username"` - RealName string `json:"realName"` - Desc string `json:"desc"` - Token string `json:"token"` - Roles []RoleInfo `json:"roles"` - Avatar string `json:"avatar"` - HomePath string `json:"homePath"` - Password string `json:"password"` + UserID int `json:"userId"` // 用户id + Username string `json:"username"` // 用户名 + RealName string `json:"realName"` // 实际名 + Desc string `json:"desc"` // 描述 + Token string `json:"token"` // token + Roles []RoleInfo `json:"roles"` // 角色 + Avatar string `json:"avatar"` // 头像 + HomePath string `json:"homePath"` // 主页路径 + Password string `json:"password"` // 密码 } // MessageInfo 消息信息 +// @Description 消息信息 type MessageInfo struct { - MessageType string `json:"message_type"` - MessageID interface{} `json:"message_id"` - GroupID int64 `json:"group_id"` - GroupName string `json:"group_name"` - UserID int64 `json:"user_id"` - Nickname string `json:"nickname"` - RawMessage string `json:"raw_message"` + MessageType string `json:"message_type"` // 消息类型, group为群聊,private为私聊 + MessageID interface{} `json:"message_id"` // 消息id + GroupID int64 `json:"group_id"` // 群id + GroupName string `json:"group_name"` // 群名 + UserID int64 `json:"user_id"` // 用户名 + Nickname string `json:"nickname"` // 昵称 + RawMessage string `json:"raw_message"` // 初始消息 } // PluginVo 全部插件的返回 +// @Description 全部插件的返回 type PluginVo struct { - ID int `json:"id"` - Name string `json:"name"` - Brief string `json:"brief"` - Usage string `json:"usage"` - Banner string `json:"banner"` - PluginStatus bool `json:"pluginStatus"` - ResponseStatus bool `json:"responseStatus"` + ID int `json:"id"` // 插件序号 + Name string `json:"name"` // 插件名 + Brief string `json:"brief"` // 简述 + Usage string `json:"usage"` // 用法 + Banner string `json:"banner"` // 头像 + PluginStatus bool `json:"pluginStatus"` // 插件状态,false=禁用,true=启用 + ResponseStatus bool `json:"responseStatus"` // 响应状态, false=沉默,true=响应 } -// RequestVo 返回 +// RequestVo 请求返回 +// @Description 请求返回 type RequestVo struct { - Flag string `json:"flag"` - RequestType string `json:"requestType"` - SubType string `json:"subType"` - Comment string `json:"comment"` - GroupID int64 `json:"groupId"` - GroupName string `json:"groupName"` - UserID int64 `json:"userId"` - Nickname string `json:"nickname"` - SelfID int64 `json:"selfId"` + Flag string `json:"flag"` // 请求flag + RequestType string `json:"requestType"` // 请求类型 + SubType string `json:"subType"` // 请求子类型 + Comment string `json:"comment"` // 注释 + GroupID int64 `json:"groupId"` // 群id + GroupName string `json:"groupName"` // 群名 + UserID int64 `json:"userId"` // 用户id + Nickname string `json:"nickname"` // 昵称 + SelfID int64 `json:"selfId"` // 机器人qq } diff --git a/go.mod b/go.mod index 3f98f50..16ec90d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/FloatTech/zbputils go 1.19 require ( - github.com/FloatTech/ZeroBot-Plugin-Webui v1.0.1-0.20230307153523-5c33f1700c1a + github.com/FloatTech/ZeroBot-Plugin-Webui v1.0.1-0.20230412164529-cfe878675931 github.com/FloatTech/floatbox v0.0.0-20230331064925-9af336a84944 github.com/FloatTech/gg v1.1.2 github.com/FloatTech/imgfactory v0.2.2-0.20230315152233-49741fc994f9 diff --git a/go.sum b/go.sum index 3cac1f4..ed99b52 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/FloatTech/ZeroBot-Plugin-Webui v1.0.1-0.20230307153523-5c33f1700c1a h1:4SXwRYniDBhGuC8/c5Pbg4wdcZRwmejI5xD2AWMK+oc= -github.com/FloatTech/ZeroBot-Plugin-Webui v1.0.1-0.20230307153523-5c33f1700c1a/go.mod h1:Se2A9vnC4eSYF7vR2LNSayV7rvbFcpgVs1ZN4sEYMyg= +github.com/FloatTech/ZeroBot-Plugin-Webui v1.0.1-0.20230412164529-cfe878675931 h1:jTc1mb2sG1krnxpgD75SMojeOMIl6bGX5t3YGIRKkHI= +github.com/FloatTech/ZeroBot-Plugin-Webui v1.0.1-0.20230412164529-cfe878675931/go.mod h1:Se2A9vnC4eSYF7vR2LNSayV7rvbFcpgVs1ZN4sEYMyg= github.com/FloatTech/floatbox v0.0.0-20230331064925-9af336a84944 h1:/eQoMa6Aj3coF5F7yhzZe1+SzX6SItul7MW8//pl18o= github.com/FloatTech/floatbox v0.0.0-20230331064925-9af336a84944/go.mod h1:FwQm6wk+b4wuW54KCKn3zccMX47Q5apnHD/Yakzv0fI= github.com/FloatTech/gg v1.1.2 h1:YolgOYg3uDHc1+g0bLtt6QuRA/pvLn+b9IBCIhOOX88= diff --git a/job/web.go b/job/web.go new file mode 100644 index 0000000..0c37f5e --- /dev/null +++ b/job/web.go @@ -0,0 +1,445 @@ +package job + +import ( + "encoding/json" + "errors" + "regexp" + "strconv" + "strings" + + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/process" + "github.com/sirupsen/logrus" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +type ( + // Type 任务类型,1=指令别名,2=定时任务,3=你问我答 + Type uint8 + // FullMatchType 指令别名类型, jobType=1使用的参数, 1=无状态消息, 2=主人消息 + FullMatchType uint8 + // QuestionType 问题类型, jobType=3使用的参数, 1=单独问, 2=所有人问 + QuestionType uint8 + // AnswerType 回答类型, jobType=3使用的参数, 1=文本消息, 2=注入消息 + AnswerType uint8 +) + +const ( + // FullMatchJob 指令别名 + FullMatchJob Type = iota + 1 + // CronJob 定时任务 + CronJob + // RegexpJob 你问我答 + RegexpJob +) + +const ( + // NoStateMsg 无状态消息 + NoStateMsg FullMatchType = iota + 1 + // SuperMsg 主人消息 + SuperMsg +) + +const ( + // OneQuestion 单独问 + OneQuestion QuestionType = iota + 1 + // AllQuestion 所有人问 + AllQuestion +) + +const ( + // TextMsg 文本消息 + TextMsg AnswerType = iota + 1 + // InjectMsg 注入消息 + InjectMsg +) + +// Job 添加任务的入参 +// +// @Description 添加任务的入参 +type Job struct { + ID string `json:"id"` // 任务id + SelfID int64 `json:"selfId"` // 机器人id + JobType Type `json:"jobType"` // 任务类型,1-指令别名,2-定时任务,3-你问我答 + Matcher string `json:"matcher"` // 当jobType=1时 为指令别名,当jobType=2时 为cron表达式,当jobType=3时 为正则表达式 + Handler string `json:"handler"` // 执行内容 + FullMatchType FullMatchType `json:"fullMatchType"` // 指令别名类型, jobType=1使用的参数, 1=无状态消息, 2=主人消息 + QuestionType QuestionType `json:"questionType"` // 问题类型, jobType=3使用的参数, 1=单独问, 2=所有人问 + AnswerType AnswerType `json:"answerType"` // 回答类型, jobType=3使用的参数, 1=文本消息, 2=注入消息 + GroupID int64 `json:"groupId"` // 群聊id, jobType=2,3使用的参数, jobType=2且私聊, group_id=0 + UserID int64 `json:"userId"` // 用户id, jobType=2,3使用的参数, 当jobType=3, QuestionType=2,userId=0 +} + +// List 任务列表 +func List() (jobList []Job, err error) { + jobList = make([]Job, 0, 16) + zero.RangeBot(func(id int64, ctx *zero.Ctx) bool { + c := &cmd{} + ids := strconv.FormatInt(id, 36) + _ = db.FindFor(ids, c, "", func() error { + var j Job + var e zero.Event + j.SelfID = id + j.ID = strconv.FormatInt(c.ID, 10) + if len(c.Cron) >= 3 { + switch c.Cron[:3] { + case "sm:": + j.JobType = FullMatchJob + j.FullMatchType = SuperMsg + j.Matcher = c.Cron[3:] + err = json.Unmarshal(binary.StringToBytes(c.Cmd), &e) + if err != nil { + return err + } + j.Handler = e.RawMessage + case "fm:": + j.JobType = FullMatchJob + j.FullMatchType = NoStateMsg + j.Matcher = c.Cron[3:] + j.Handler = c.Cmd + case "rm:": + j.JobType = RegexpJob + j.QuestionType = AllQuestion + j.AnswerType = TextMsg + j.Handler = message.UnescapeCQCodeText(c.Cmd) + cutList := strings.SplitN(c.Cron, ":", 3) + if len(cutList) == 3 { + j.GroupID, err = strconv.ParseInt(cutList[len(cutList)-2], 36, 64) + if err != nil { + return err + } + j.Matcher = cutList[len(cutList)-1] + } + case "rp:": + j.JobType = RegexpJob + j.QuestionType = OneQuestion + j.AnswerType = TextMsg + j.Handler = message.UnescapeCQCodeText(c.Cmd) + cutList := strings.SplitN(c.Cron, ":", 4) + if len(cutList) == 4 { + j.UserID, err = strconv.ParseInt(cutList[len(cutList)-3], 36, 64) + if err != nil { + return err + } + j.GroupID, err = strconv.ParseInt(cutList[len(cutList)-2], 36, 64) + if err != nil { + return err + } + j.Matcher = cutList[len(cutList)-1] + } + case "im:": + j.JobType = RegexpJob + j.QuestionType = AllQuestion + j.AnswerType = InjectMsg + j.Handler = message.UnescapeCQCodeText(c.Cmd) + cutList := strings.SplitN(c.Cron, ":", 3) + if len(cutList) == 3 { + j.GroupID, err = strconv.ParseInt(cutList[len(cutList)-2], 36, 64) + if err != nil { + return err + } + j.Matcher = cutList[len(cutList)-1] + } + case "ip:": + j.JobType = RegexpJob + j.QuestionType = OneQuestion + j.AnswerType = InjectMsg + j.Handler = message.UnescapeCQCodeText(c.Cmd) + cutList := strings.SplitN(c.Cron, ":", 4) + if len(cutList) == 4 { + j.UserID, err = strconv.ParseInt(cutList[len(cutList)-3], 36, 64) + if err != nil { + return err + } + j.GroupID, err = strconv.ParseInt(cutList[len(cutList)-2], 36, 64) + if err != nil { + return err + } + j.Matcher = cutList[len(cutList)-1] + } + default: + j.JobType = CronJob + j.Matcher = c.Cron + err = json.Unmarshal(binary.StringToBytes(c.Cmd), &e) + if err != nil { + return err + } + j.Handler = e.RawMessage + j.GroupID = e.GroupID + j.UserID = e.UserID + } + } + jobList = append(jobList, j) + return nil + }) + // 不能打断循环 + if err != nil { + logrus.Errorln("jobList: ", err) + } + return true + }) + return +} + +// Add 添加任务 +func Add(j *Job) (err error) { + var ( + c cmd + bot *zero.Ctx + b []byte + compiled *regexp.Regexp + ) + bot = zero.GetBot(j.SelfID) + bot.Event = &zero.Event{ + SelfID: j.SelfID, + } + switch j.JobType { + case FullMatchJob: + if j.FullMatchType == 1 { + c.Cron = "fm:" + j.Matcher + c.Cmd = binary.BytesToString(json.RawMessage("\"" + j.Handler + "\"")) + } else { + c.Cron = "sm:" + j.Matcher + var e zero.Event + if len(zero.BotConfig.SuperUsers) > 0 { + e.UserID = zero.BotConfig.SuperUsers[0] + e.Sender = &zero.User{ + ID: zero.BotConfig.SuperUsers[0], + } + e.RawMessage = j.Handler + e.NativeMessage = json.RawMessage("\"" + j.Handler + "\"") + } + b, err = json.Marshal(&e) + if err != nil { + return + } + c.Cmd = binary.BytesToString(b) + } + c.ID = idof(c.Cron, c.Cmd) + err = registercmd(j.SelfID, &c) + if err != nil { + return + } + case CronJob: + var e zero.Event + e.UserID = j.UserID + e.Sender = &zero.User{ + ID: j.UserID, + } + e.SelfID = j.SelfID + e.RawMessage = j.Handler + e.NativeMessage = json.RawMessage("\"" + j.Handler + "\"") + e.GroupID = j.GroupID + e.PostType = "message" + if e.GroupID > 0 { + e.MessageType = "group" + } else { + e.MessageType = "private" + e.TargetID = j.SelfID + } + b, err = json.Marshal(&e) + if err != nil { + return + } + c.Cmd = binary.BytesToString(b) + c.Cron = j.Matcher + c.ID = idof(c.Cron, c.Cmd) + err = addcmd(bot, &c) + if err != nil { + return + } + case RegexpJob: + all := false + isInject := false + gid := j.GroupID + uid := j.UserID + switch { + case j.QuestionType == AllQuestion && j.AnswerType == InjectMsg: + all = true + isInject = true + c.Cron = "im:" + strconv.FormatInt(gid, 36) + ":" + j.Matcher + case j.QuestionType == AllQuestion && j.AnswerType == TextMsg: + all = true + isInject = false + c.Cron = "rm:" + strconv.FormatInt(gid, 36) + ":" + j.Matcher + case j.QuestionType == OneQuestion && j.AnswerType == InjectMsg: + all = false + isInject = true + c.Cron = "ip:" + strconv.FormatInt(uid, 36) + ":" + strconv.FormatInt(gid, 36) + ":" + j.Matcher + case j.QuestionType == OneQuestion && j.AnswerType == TextMsg: + all = false + isInject = false + c.Cron = "rp:" + strconv.FormatInt(uid, 36) + ":" + strconv.FormatInt(gid, 36) + ":" + j.Matcher + default: + } + c.Cmd = message.EscapeCQCodeText(j.Handler) + c.ID = idof(c.Cron, c.Cmd) + pattern := j.Matcher + template := message.EscapeCQCodeText(j.Handler) + if global.group[gid] == nil { + global.group[gid] = ®exGroup{ + Private: make(map[int64][]inst), + } + } + if global.group[gid].Private == nil { + global.group[gid].Private = make(map[int64][]inst) + } + compiled, err = regexp.Compile(transformPattern(pattern)) + if err != nil { + return + } + regexInst := inst{ + regex: compiled, + Pattern: pattern, + Template: template, + IsInject: isInject, + } + rg := global.group[gid] + if all { + if isInject { + err = saveInjectRegex(gid, 0, strconv.FormatInt(j.SelfID, 36), pattern, template) + } else { + err = saveRegex(gid, 0, strconv.FormatInt(j.SelfID, 36), pattern, template) + } + if err == nil { + rg.All = append(rg.All, regexInst) + } + } else { + if isInject { + err = saveInjectRegex(gid, uid, strconv.FormatInt(j.SelfID, 36), pattern, template) + } else { + err = saveRegex(gid, uid, strconv.FormatInt(j.SelfID, 36), pattern, template) + } + if err == nil { + rg.Private[uid] = append(rg.Private[uid], regexInst) + } + } + if err != nil { + return + } + default: + err = errors.New("不存在的任务类型") + return + } + return +} + +// DeleteReq 删除任务的入参 +// +// @Description 删除任务的入参 +type DeleteReq struct { + IDList []string `json:"idList" form:"idList"` // 任务id + SelfID int64 `json:"selfId" form:"selfId"` // 机器人qq +} + +// Delete 删除任务 +func Delete(req *DeleteReq) (err error) { + var ( + c cmd + ) + mu.Lock() + defer mu.Unlock() + bots := strconv.FormatInt(req.SelfID, 36) + var delcmd []string + err = db.FindFor(bots, &c, "WHERE id in ( "+strings.Join(req.IDList, ",")+" )", func() error { + switch { + case len(c.Cron) >= 3 && (c.Cron[:3] == "fm:" || c.Cron[:3] == "sm:"): + m, ok := matchers[c.ID] + if ok { + m.Delete() + delete(matchers, c.ID) + } + case len(c.Cron) >= 3 && (c.Cron[:3] == "ip:" || c.Cron[:3] == "rp:" || c.Cron[:3] == "rm:" || c.Cron[:3] == "im:"): + var ( + all bool + gid int64 + uid int64 + pattern string + ) + if len(c.Cron) >= 3 && (c.Cron[:3] == "ip:" || c.Cron[:3] == "rp:") { + cutList := strings.SplitN(c.Cron, ":", 4) + if len(cutList) == 4 { + uid, err = strconv.ParseInt(cutList[len(cutList)-3], 36, 64) + if err != nil { + return err + } + gid, err = strconv.ParseInt(cutList[len(cutList)-2], 36, 64) + if err != nil { + return err + } + pattern = cutList[len(cutList)-1] + } + all = false + } else { + cutList := strings.SplitN(c.Cron, ":", 3) + if len(cutList) == 3 { + gid, err = strconv.ParseInt(cutList[len(cutList)-2], 36, 64) + if err != nil { + return err + } + } + all = true + pattern = cutList[len(cutList)-1] + } + escapedpattern := message.UnescapeCQCodeText(pattern) + if pattern == escapedpattern { + escapedpattern = "" + } + rg := global.group[gid] + if rg == nil { + return nil + } + var deleteInst func(insts []inst) ([]inst, error) + if escapedpattern == "" { + deleteInst = func(insts []inst) ([]inst, error) { + for i := range insts { + if insts[i].Pattern == pattern { + insts[i] = insts[len(insts)-1] + insts = insts[:len(insts)-1] + return insts, nil + } + } + return insts, errors.New("没有找到对应的问答词条") + } + } else { + deleteInst = func(insts []inst) ([]inst, error) { + for i := range insts { + if insts[i].Pattern == pattern || insts[i].Pattern == escapedpattern { + insts[i] = insts[len(insts)-1] + insts = insts[:len(insts)-1] + return insts, nil + } + } + return insts, errors.New("没有找到对应的问答词条") + } + } + if all { + rg.All, err = deleteInst(rg.All) + } else { + rg.Private[uid], err = deleteInst(rg.Private[uid]) + } + if err != nil { + return err + } + default: + eid, ok := entries[c.ID] + if ok { + process.CronTab.Remove(eid) + delete(entries, c.ID) + } + } + delcmd = append(delcmd, "id="+strconv.FormatInt(c.ID, 10)) + return nil + }) + if err != nil { + return + } + if len(delcmd) > 0 { + err = db.Del(bots, "WHERE "+strings.Join(delcmd, " or ")) + if err != nil { + return + } + } + return +}