From a098da39ee706abf398e12bc123a1245184e3b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AF=BB=E6=AC=A2?= Date: Mon, 17 Jun 2024 17:30:50 +0800 Subject: [PATCH 1/5] =?UTF-8?q?:new:=20=E4=BF=AE=E6=94=B9=E5=A5=BD?= =?UTF-8?q?=E5=8F=8B=E5=88=97=E8=A1=A8=E8=AE=BE=E7=BD=AEAI=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E4=B8=BA=E6=95=B0=E6=8D=AE=E5=BA=93=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/friend.go | 22 ++++++++++++++++++++++ app/pages.go | 2 ++ entity/aiassistant.go | 39 +++++++++++++++++++++++++++++++++++++++ router/router.go | 1 + service/aiassistant.go | 14 ++++++++++++++ views/friend.html | 18 ++++++++++++++++++ views/static/js/index.js | 23 +++++++++++++++++++++++ vo/friend.go | 1 + 8 files changed, 120 insertions(+) create mode 100644 entity/aiassistant.go create mode 100644 service/aiassistant.go diff --git a/app/friend.go b/app/friend.go index 0789420..3849f2b 100644 --- a/app/friend.go +++ b/app/friend.go @@ -67,6 +67,28 @@ func ChangeUseAiModel(ctx *gin.Context) { ctx.String(http.StatusOK, "操作成功") } +// ChangeUseAiAssistant +// @description: 修改使用的AI助手 +// @param ctx +func ChangeUseAiAssistant(ctx *gin.Context) { + // 此处复用一下结构体 + var p changeUseAiModelParam + if err := ctx.ShouldBind(&p); err != nil { + ctx.String(http.StatusBadRequest, "参数错误") + return + } + err := client.MySQL.Model(&entity.Friend{}). + Where("wxid = ?", p.WxId). + Update("`prompt`", p.Model).Error + if err != nil { + log.Printf("修改【%s】的AI助手失败:%s", p.WxId, err) + ctx.String(http.StatusInternalServerError, "操作失败: %s", err) + return + } + + ctx.String(http.StatusOK, "操作成功") +} + // ChangeEnableGroupRankStatus // @description: 修改是否开启水群排行榜 // @param ctx diff --git a/app/pages.go b/app/pages.go index 13d5fc7..2770588 100644 --- a/app/pages.go +++ b/app/pages.go @@ -66,6 +66,7 @@ func Friend(ctx *gin.Context) { result["friends"] = friends result["vnc"] = config.Conf.Wechat.VncUrl result["aiModels"] = config.Conf.Ai.Models + result["assistant"], _ = service.GetAllAiAssistant() // 渲染页面 ctx.HTML(http.StatusOK, "friend.html", result) } @@ -85,6 +86,7 @@ func Group(ctx *gin.Context) { result["groups"] = groups result["vnc"] = config.Conf.Wechat.VncUrl result["aiModels"] = config.Conf.Ai.Models + result["assistant"], _ = service.GetAllAiAssistant() // 渲染页面 ctx.HTML(http.StatusOK, "group.html", result) diff --git a/entity/aiassistant.go b/entity/aiassistant.go new file mode 100644 index 0000000..61cd66b --- /dev/null +++ b/entity/aiassistant.go @@ -0,0 +1,39 @@ +package entity + +import ( + "github.com/google/uuid" + "go-wechat/common/types" + "gorm.io/gorm" + "strings" +) + +// AiAssistant +// @description: AI助手表 +type AiAssistant struct { + Id string `json:"id" gorm:"type:varchar(32);primarykey"` + CreatedAt types.DateTime `json:"createdAt"` + Name string `json:"name" gorm:"type:varchar(10);not null;comment:'名称'"` + Personality string `json:"personality" gorm:"type:varchar(999);not null;comment:'人设'"` + Model string `json:"model" gorm:"type:varchar(50);not null;comment:'使用的模型'"` + Enable bool `json:"enable" gorm:"type:tinyint(1);not null;default:1;comment:'是否启用'"` +} + +// TableName +// @description: 表名 +// @receiver AiAssistant +// @return string +func (AiAssistant) TableName() string { + return "t_ai_assistant" +} + +// BeforeCreate +// @description: 创建数据库对象之前生成UUID +// @receiver m +// @param *gorm.DB +// @return err +func (m *AiAssistant) BeforeCreate(*gorm.DB) (err error) { + if m.Id == "" { + m.Id = strings.ReplaceAll(uuid.New().String(), "-", "") + } + return +} diff --git a/router/router.go b/router/router.go index f10f30a..3b606c2 100644 --- a/router/router.go +++ b/router/router.go @@ -24,6 +24,7 @@ func Init(g *gin.Engine) { api := g.Group("/api") api.PUT("/ai/status", app.ChangeEnableAiStatus) // 修改是否开启AI状态 api.POST("/ai/model", app.ChangeUseAiModel) // 修改使用的AI模型 + api.POST("/ai/assistant", app.ChangeUseAiAssistant) // 修改使用的AI助手 api.PUT("/welcome/status", app.ChangeEnableWelcomeStatus) // 修改是否开启迎新状态 api.PUT("/command/status", app.ChangeEnableCommandStatus) // 修改是否开启指令状态 api.PUT("/news/status", app.ChangeEnableNewsStatus) // 修改是否开启早报状态 diff --git a/service/aiassistant.go b/service/aiassistant.go new file mode 100644 index 0000000..f5608fe --- /dev/null +++ b/service/aiassistant.go @@ -0,0 +1,14 @@ +package service + +import ( + "go-wechat/client" + "go-wechat/entity" +) + +// GetAllAiAssistant +// @description: 取出所有AI助手 +// @return records +func GetAllAiAssistant() (records []entity.AiAssistant, err error) { + err = client.MySQL.Order("created_at DESC").Find(&records).Error + return +} diff --git a/views/friend.html b/views/friend.html index d301e91..e97c719 100644 --- a/views/friend.html +++ b/views/friend.html @@ -76,6 +76,24 @@ + +
+
AI角色
+
+ +
+
{{ end }}
diff --git a/views/static/js/index.js b/views/static/js/index.js index 5bb8fd2..688936f 100644 --- a/views/static/js/index.js +++ b/views/static/js/index.js @@ -213,3 +213,26 @@ function aiModelChange(event, wxid) { window.location.reload(); }) } + +// AI角色变动 +function aiAssistantChange(event, wxid) { + // 取出变动后的值 + const assistantStr = event.target.value; + console.log("AI角色变动: ", wxid, assistantStr) + axios({ + method: 'post', + url: '/api/ai/assistant', + data: { + wxid: wxid, + model: assistantStr + } + }).then(function (response) { + console.log(`返回结果: ${JSON.stringify(response)}`); + alert(`${response.data}`) + }).catch(function (error) { + console.log(`错误信息: ${error}`); + alert("修改失败") + }).finally(function () { + window.location.reload(); + }) +} diff --git a/vo/friend.go b/vo/friend.go index dbca7af..c948a4e 100644 --- a/vo/friend.go +++ b/vo/friend.go @@ -15,6 +15,7 @@ type FriendItem struct { LastActive types.DateTime // 最后活跃时间 EnableAi bool // 是否使用AI AiModel string // AI模型 + Prompt string // AI助手或者自定义提示词 EnableChatRank bool // 是否使用聊天排行 EnableWelcome bool // 是否使用迎新 EnableCommand bool // 是否启用指令 From bc2893fad1f3a03446e677486aab3574c4832216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AF=BB=E6=AC=A2?= Date: Tue, 18 Jun 2024 14:43:15 +0800 Subject: [PATCH 2/5] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=A0=E9=99=A4=E7=BE=A4=E6=88=90=E5=91=98=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/send.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/send.go b/utils/send.go index 7c4e1ed..5fe16bd 100644 --- a/utils/send.go +++ b/utils/send.go @@ -148,7 +148,9 @@ func DeleteGroupMember(chatRoomId, memberIds string, retryCount int) { log.Printf("删除群成员失败: %s", err.Error()) // 休眠五秒后重新发送 time.Sleep(5 * time.Second) - SendImage(chatRoomId, memberIds, retryCount+1) + DeleteGroupMember(chatRoomId, memberIds, retryCount+1) } log.Printf("删除群成员结果: %s", resp.String()) + // 这个逼接口要调用两次,第一次调用成功,第二次调用才会真正删除 + DeleteGroupMember(chatRoomId, memberIds, 5) } From b024600ef06b67f6b2a9ec02bc085476b28d0242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AF=BB=E6=AC=A2?= Date: Tue, 18 Jun 2024 16:23:09 +0800 Subject: [PATCH 3/5] =?UTF-8?q?:new:=20=E4=BF=AE=E6=94=B9=E7=BE=A4?= =?UTF-8?q?=E7=BB=84=E9=A1=B5=E9=9D=A2=E4=B8=BA=E5=8D=A1=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/friend.go | 30 ++++++ router/router.go | 1 + views/components.html | 4 +- views/group.html | 200 ++++++++++++++++++++----------------- views/static/css/index.css | 12 ++- views/static/js/index.js | 30 ++++++ 6 files changed, 180 insertions(+), 97 deletions(-) diff --git a/app/friend.go b/app/friend.go index 3849f2b..71a4212 100644 --- a/app/friend.go +++ b/app/friend.go @@ -23,6 +23,13 @@ type changeUseAiModelParam struct { Model string `json:"model" binding:"required"` // 模型代码 } +// autoClearMembers +// @description: 自动清理群成员 +type autoClearMembers struct { + WxId string `json:"wxid" binding:"required"` // 群Id + Days int `json:"days"` // 多少天未发言 +} + // ChangeEnableAiStatus // @description: 修改是否开启AI // @param ctx @@ -227,3 +234,26 @@ func ChangeEnableNewsStatus(ctx *gin.Context) { ctx.String(http.StatusOK, "操作成功") } + +// AutoClearMembers +// @description: 自动清理群成员 +// @param ctx +func AutoClearMembers(ctx *gin.Context) { + var p autoClearMembers + if err := ctx.ShouldBindJSON(&p); err != nil { + ctx.String(http.StatusBadRequest, "参数错误") + return + } + log.Printf("待修改的Id:%s", p.WxId) + + err := client.MySQL.Model(&entity.Friend{}). + Where("wxid = ?", p.WxId). + Update("`clear_member`", p.Days).Error + if err != nil { + log.Printf("修改自动清理群成员阈值失败:%s", err) + ctx.String(http.StatusInternalServerError, "操作失败: %s", err) + return + } + + ctx.String(http.StatusOK, "操作成功") +} diff --git a/router/router.go b/router/router.go index 3b606c2..950d9c4 100644 --- a/router/router.go +++ b/router/router.go @@ -32,4 +32,5 @@ func Init(g *gin.Engine) { api.PUT("/grouprank/skip", app.ChangeSkipGroupRankStatus) // 修改是否跳过水群排行榜状态 api.GET("/group/users", app.GetGroupUsers) // 获取群成员列表 api.PUT("/summary/status", app.ChangeEnableSummaryStatus) // 修改是否开启群聊总结状态 + api.PUT("/clearmembers", app.AutoClearMembers) // 自动清理群成员 } diff --git a/views/components.html b/views/components.html index a25cbce..96ebc1e 100644 --- a/views/components.html +++ b/views/components.html @@ -197,9 +197,9 @@ {{define "flagTag"}} {{ if eq . true }} + class="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">在通讯录 {{ else }} + class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/20">不在通讯录 {{ end }} {{end}} diff --git a/views/group.html b/views/group.html index 5d41d94..05f0c2a 100644 --- a/views/group.html +++ b/views/group.html @@ -21,101 +21,113 @@
- - - - - - - - - - - - - - - - - +
    {{ range .groups }} -
- - - - - - - - - - - - - {{ end }} - -
群名称 - - 最后活跃时间 - - 是否在通讯录 - - AI - - 排行榜 - - 总结 - - 迎新 - - 早报 - - 指令 - - 末位淘汰(天) - - 操作 -
-
{{ .Nickname }}
-
{{ .Wxid }}
-
- {{ if eq .LastActive.IsNil true }} - 无数据 - {{ else }} - {{ .LastActive }} - {{ end }} - - {{ template "flagTag" .IsOk }} - - {{ template "ai" . }} - - {{ if eq .EnableAi true }} - - {{ end }} - - {{ template "chatRank" . }} - - {{ template "summary" . }} - - {{ template "welcome" . }} - - {{ template "news" . }} - - {{ template "command" . }} - - {{ .ClearMember }} - - -
+
  • +
    + Tuple +
    +
    {{ .Nickname }}
    +
    {{ .Wxid }}
    + {{ template "flagTag" .IsOk }} + +
    +
    + +
    + +
    +
    最后活跃时间
    +
    + {{ if eq .LastActive.IsNil true }} + 无活跃数据 + {{ else }} + + {{ end }} +
    +
    + +
    +
    AI
    +
    +
    + {{ template "ai" . }} +
    + {{ if eq .EnableAi true }} +
    + +
    + {{ end }} +
    +
    + +
    +
    水群排行榜
    +
    + {{ template "chatRank" . }} +
    +
    + +
    +
    群聊总结
    +
    + {{ template "summary" . }} +
    +
    + +
    +
    迎新
    +
    + {{ template "welcome" . }} +
    +
    + +
    +
    早报
    +
    + {{ template "news" . }} +
    +
    + +
    +
    迎新
    +
    + {{ template "command" . }} +
    +
    + +
    +
    末位淘汰
    +
    +
    + +
    + +
    +
    +
    +
    +
    + {{ end }} +
  • diff --git a/views/static/css/index.css b/views/static/css/index.css index 0e725a8..09ecab4 100644 --- a/views/static/css/index.css +++ b/views/static/css/index.css @@ -1,4 +1,14 @@ /* 隐藏滚动条 */ ::-webkit-scrollbar { display: none; -} \ No newline at end of file +} + +/* 隐藏input输入数字时的箭头 */ +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} +input[type=number] { + -moz-appearance:textfield; +} diff --git a/views/static/js/index.js b/views/static/js/index.js index 688936f..ee7014c 100644 --- a/views/static/js/index.js +++ b/views/static/js/index.js @@ -236,3 +236,33 @@ function aiAssistantChange(event, wxid) { window.location.reload(); }) } + +// 修改清理群成员值 +function changeClearMember(wxid, oldVal, newVal) { + oldVal = Number(oldVal) + newVal = Number(newVal) + + if (oldVal === newVal) { + return + } + if (newVal < 0) { + alert('不活跃天数的值不能小于0') + } + // 请求接口 + axios({ + method: 'put', + url: '/api/clearmembers', + data: { + wxid: wxid, + days: Number(newVal) + } + }).then(function (response) { + console.log(`返回结果: ${JSON.stringify(response)}`); + alert(`${response.data}`) + }).catch(function (error) { + console.log(`错误信息: ${error}`); + alert("修改失败") + }).finally(function () { + window.location.reload(); + }) +} From b14dbe0d1dce2f22da791d350cade1305d222927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AF=BB=E6=AC=A2?= Date: Tue, 18 Jun 2024 17:02:37 +0800 Subject: [PATCH 4/5] =?UTF-8?q?:new:=20=E6=96=B0=E5=A2=9EAI=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E7=AE=A1=E7=90=86(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assistant.go | 14 +++++++ app/pages.go | 15 ++++++++ main.go | 2 + router/router.go | 9 +++-- views/assistant.html | 89 ++++++++++++++++++++++++++++++++++++++++++++ views/head.html | 1 + 6 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 app/assistant.go create mode 100644 views/assistant.html diff --git a/app/assistant.go b/app/assistant.go new file mode 100644 index 0000000..b1c12a6 --- /dev/null +++ b/app/assistant.go @@ -0,0 +1,14 @@ +package app + +import ( + "github.com/gin-gonic/gin" +) + +// SaveAssistant +// @description: 保存AI助手 +// @param ctx +func SaveAssistant(ctx *gin.Context) { + + //ctx.String(http.StatusOK, "操作成功") + ctx.Redirect(302, "/assistant.html") +} diff --git a/app/pages.go b/app/pages.go index 2770588..1c8d5c8 100644 --- a/app/pages.go +++ b/app/pages.go @@ -92,6 +92,21 @@ func Group(ctx *gin.Context) { ctx.HTML(http.StatusOK, "group.html", result) } +// Assistant +// @description: AI角色 +// @param ctx +func Assistant(ctx *gin.Context) { + var result = gin.H{ + "msg": "success", + } + + result["aiModels"] = config.Conf.Ai.Models + result["assistant"], _ = service.GetAllAiAssistant() + + // 渲染页面 + ctx.HTML(http.StatusOK, "assistant.html", result) +} + // PageNotFound // @description: 404页面 // @param ctx diff --git a/main.go b/main.go index 5eb07dd..0ca0fbe 100644 --- a/main.go +++ b/main.go @@ -48,6 +48,8 @@ func main() { return "群组列表" case "index": return "首页" + case "assistant": + return "AI角色" default: return "其他页面" } diff --git a/router/router.go b/router/router.go index 950d9c4..d216360 100644 --- a/router/router.go +++ b/router/router.go @@ -14,9 +14,10 @@ func Init(g *gin.Engine) { ctx.Redirect(302, "/index.html") }) - g.GET("/index.html", app.Index) // 首页 - g.GET("/friend.html", app.Friend) // 好友列表 - g.GET("/group.html", app.Group) // 群组列表 + g.GET("/index.html", app.Index) // 首页 + g.GET("/friend.html", app.Friend) // 好友列表 + g.GET("/group.html", app.Group) // 群组列表 + g.GET("/assistant.html", app.Assistant) // AI角色 g.GET("/404.html", app.PageNotFound) // 群组列表 @@ -33,4 +34,6 @@ func Init(g *gin.Engine) { api.GET("/group/users", app.GetGroupUsers) // 获取群成员列表 api.PUT("/summary/status", app.ChangeEnableSummaryStatus) // 修改是否开启群聊总结状态 api.PUT("/clearmembers", app.AutoClearMembers) // 自动清理群成员 + + api.POST("/assistant", app.SaveAssistant) // 保存AI助手 } diff --git a/views/assistant.html b/views/assistant.html new file mode 100644 index 0000000..e1f1796 --- /dev/null +++ b/views/assistant.html @@ -0,0 +1,89 @@ + + + + + + 水群助手 + + + + + + + + + + + +
    + {{ template "head.html" "assistant" }} + +
    +
    +
    +
      + {{ range .assistant }} +
    • + + + + + + + + + +
      +
      +
      +
      +
      + +
      +
      + +
      +
      +
      + +
      + +
      + +
      +
      + +
      + +
      + +
      +
      +
      +
      +
      + +
      + +
      +
      +
    • + {{ end }} +
    +
    +
    +
    + + {{ template "footer.html" }} + + {{ template "groupuser.html" }} +
    + + diff --git a/views/head.html b/views/head.html index ce5dbe4..e121fae 100644 --- a/views/head.html +++ b/views/head.html @@ -13,6 +13,7 @@ 好友 群组 + AI角色
    From c0dcffce9de3d9fe692899db44ec37bc1f666155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AF=BB=E6=AC=A2?= Date: Tue, 18 Jun 2024 17:14:46 +0800 Subject: [PATCH 5/5] =?UTF-8?q?:art:=20=E7=BE=A4=E7=BB=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- views/group.html | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/views/group.html b/views/group.html index 05f0c2a..8b21de7 100644 --- a/views/group.html +++ b/views/group.html @@ -21,7 +21,7 @@
    -
      +
        {{ range .groups }}
      • @@ -49,26 +49,42 @@
        -
        AI
        -
        +
        AI(模型可选默认或者指定模型)
        +
        {{ template "ai" . }}
        {{ if eq .EnableAi true }}
        - + {{$useModel := .AiModel}} + {{ range $.aiModels }} + + {{ end }} + + +
        +
        + +
        {{ end }} @@ -111,7 +127,7 @@
        末位淘汰
        -
        +