Compare commits

...

3 Commits

40 changed files with 96 additions and 78 deletions

View File

@ -3,7 +3,7 @@ package app
import (
"github.com/gin-gonic/gin"
"go-wechat/client"
"go-wechat/entity"
"go-wechat/model/entity"
"gorm.io/gorm"
"log"
"net/http"
@ -20,7 +20,7 @@ type changeStatusParam struct {
// @description: 修改使用的AI模型用的参数集
type changeUseAiModelParam struct {
WxId string `json:"wxid" binding:"required"` // 群Id或微信Id
Model string `json:"model"` // 模型代码
Model string `json:"dto"` // 模型代码
}
// autoClearMembers

View File

@ -1,14 +1,14 @@
package current
import (
"go-wechat/model"
plugin "go-wechat/plugin"
"go-wechat/model/dto"
"go-wechat/plugin"
)
// robotInfo
// @description: 机器人信息
type robotInfo struct {
info model.RobotUserInfo
info dto.RobotUserInfo
MessageHandler plugin.MessageHandler // 启用的插件
}
@ -18,14 +18,14 @@ var ri robotInfo
// SetRobotInfo
// @description: 设置机器人信息
// @param info
func SetRobotInfo(info model.RobotUserInfo) {
func SetRobotInfo(info dto.RobotUserInfo) {
ri.info = info
}
// GetRobotInfo
// @description: 获取机器人信息
// @return model.RobotUserInfo
func GetRobotInfo() model.RobotUserInfo {
// @return dto.RobotUserInfo
func GetRobotInfo() dto.RobotUserInfo {
return ri.info
}

View File

@ -4,7 +4,7 @@ package config
// @description: AI配置
type ai struct {
Enable bool `json:"enable" yaml:"enable"` // 是否启用AI
Model string `json:"model" yaml:"model"` // 模型
Model string `json:"dto" yaml:"dto"` // 模型
SummaryModel string `json:"summaryModel" yaml:"summaryModel"` // 总结模型
ApiKey string `json:"apiKey" yaml:"apiKey"` // API Key
BaseUrl string `json:"baseUrl" yaml:"baseUrl"` // API地址
@ -15,6 +15,6 @@ type ai struct {
// aiModel
// @description: AI模型
type aiModel struct {
Name string `json:"name" yaml:"name"` // 模型名称
Model string `json:"model" yaml:"model"` // 模型代码
Name string `json:"name" yaml:"name"` // 模型名称
Model string `json:"dto" yaml:"dto"` // 模型代码
}

View File

@ -2,7 +2,7 @@ package initialization
import (
"go-wechat/common/current"
"go-wechat/model"
"go-wechat/model/dto"
plugin "go-wechat/plugin"
"go-wechat/plugin/plugins"
"go-wechat/service"
@ -19,25 +19,25 @@ func Plugin() {
// 注册插件
// 保存消息进数据库
dispatcher.RegisterHandler(func(*model.Message) bool {
dispatcher.RegisterHandler(func(*dto.Message) bool {
return true
}, plugins.SaveToDb)
// 私聊指令消息
dispatcher.RegisterHandler(func(m *model.Message) bool {
dispatcher.RegisterHandler(func(m *dto.Message) bool {
// 私聊消息 或 群聊艾特机器人并且以/开头的消息
isGroupAt := m.IsAt() && !m.IsAtAll()
return (m.IsPrivateText() || isGroupAt) && m.CleanContentStartWith("/") && service.CheckIsEnableCommand(m.FromUser)
}, plugins.Command)
// AI消息插件
dispatcher.RegisterHandler(func(m *model.Message) bool {
dispatcher.RegisterHandler(func(m *dto.Message) bool {
// 群内@或者私聊文字消息
return (m.IsAt() && !m.IsAtAll()) || m.IsPrivateText()
}, plugins.AI)
// 欢迎新成员
dispatcher.RegisterHandler(func(m *model.Message) bool {
dispatcher.RegisterHandler(func(m *dto.Message) bool {
return m.IsNewUserJoin()
}, plugins.WelcomeNew)

View File

@ -4,7 +4,7 @@ import (
"github.com/go-resty/resty/v2"
"go-wechat/common/current"
"go-wechat/config"
"go-wechat/model"
"go-wechat/model/dto"
"log"
)
@ -12,7 +12,7 @@ import (
// @description: 初始化微信机器人信息
func InitWechatRobotInfo() {
// 获取数据
var base model.Response[model.RobotUserInfo]
var base dto.Response[dto.RobotUserInfo]
_, err := resty.New().R().
SetHeader("Content-Type", "application/json;chartset=utf-8").
SetResult(&base).

View File

@ -1,4 +1,4 @@
package model
package dto
// FriendItem
// @description: 好友列表数据

View File

@ -1,4 +1,4 @@
package model
package dto
// LeiGodLoginResp
// @description: 雷神登录返回

View File

@ -1,4 +1,4 @@
package model
package dto
import (
"encoding/xml"

View File

@ -1,4 +1,4 @@
package model
package dto
// MorningPost
// @description: 每日早报返回结构体

View File

@ -1,4 +1,4 @@
package model
package dto
// Response
// @description: 基础返回结构体

View File

@ -1,4 +1,4 @@
package model
package dto
// RobotUserInfo
// @description: 机器人用户信息

View File

@ -14,7 +14,7 @@ type AiAssistant struct {
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:'使用的模型'"`
Model string `json:"dto" gorm:"type:varchar(50);not null;comment:'使用的模型'"`
Enable bool `json:"enable" gorm:"type:tinyint(1);not null;default:1;comment:'是否启用'"`
}

View File

@ -22,6 +22,7 @@ type Friend struct {
EnableNews bool `json:"enableNews" gorm:"type:tinyint(1) default 0 not null"` // 是否启用新闻
ClearMember int `json:"clearMember"` // 清理成员配置(多少天未活跃的)
IsOk bool `json:"isOk" gorm:"type:tinyint(1) default 0 not null"` // 是否正常
UsedTokens int `json:"usedTokens"` // 已使用的AI Token数量
}
func (Friend) TableName() string {

View File

@ -4,7 +4,7 @@ import (
"encoding/json"
"go-wechat/common/current"
"go-wechat/config"
"go-wechat/model"
"go-wechat/model/dto"
"go-wechat/types"
"go-wechat/utils"
"log"
@ -15,7 +15,7 @@ import (
// @description: 解析消息
// @param msg
func parse(msg []byte) {
var m model.Message
var m dto.Message
if err := json.Unmarshal(msg, &m); err != nil {
log.Printf("消息解析失败: %v", err)
log.Printf("消息内容: %d -> %v", len(msg), string(msg))

View File

@ -1,21 +1,21 @@
package plugin
import (
"go-wechat/model"
"go-wechat/model/dto"
)
// MessageHandler 消息处理函数
type MessageHandler func(msg *model.Message)
type MessageHandler func(msg *dto.Message)
// MessageDispatcher 消息分发处理接口
// 跟 DispatchMessage 结合封装成 MessageHandler
type MessageDispatcher interface {
Dispatch(msg *model.Message)
Dispatch(msg *dto.Message)
}
// DispatchMessage 跟 MessageDispatcher 结合封装成 MessageHandler
func DispatchMessage(dispatcher MessageDispatcher) func(msg *model.Message) {
return func(msg *model.Message) { dispatcher.Dispatch(msg) }
func DispatchMessage(dispatcher MessageDispatcher) func(msg *dto.Message) {
return func(msg *dto.Message) { dispatcher.Dispatch(msg) }
}
// MessageDispatcher impl
@ -30,7 +30,7 @@ type MessageContext struct {
index int
abortIndex int
messageHandlers MessageContextHandlerGroup
*model.Message
*dto.Message
}
// Next 主动调用下一个消息处理函数(或开始调用)
@ -65,11 +65,11 @@ func (c *MessageContext) AbortHandler() MessageContextHandler {
}
// MatchFunc 消息匹配函数,返回为true则表示匹配
type MatchFunc func(*model.Message) bool
type MatchFunc func(*dto.Message) bool
// MatchFuncList 将多个MatchFunc封装成一个MatchFunc
func MatchFuncList(matchFuncs ...MatchFunc) MatchFunc {
return func(message *model.Message) bool {
return func(message *dto.Message) bool {
for _, matchFunc := range matchFuncs {
if !matchFunc(message) {
return false
@ -89,7 +89,7 @@ type matchNodes []*matchNode
// MessageMatchDispatcher impl MessageDispatcher interface
//
// dispatcher := NewMessageMatchDispatcher()
// dispatcher.OnText(func(msg *model.Message){
// dispatcher.OnText(func(msg *dto.Message){
// msg.ReplyText("hello")
// })
// bot := DefaultBot()
@ -113,7 +113,7 @@ func (m *MessageMatchDispatcher) SetAsync(async bool) {
// 遍历 MessageMatchDispatcher 所有的消息处理函数
// 获取所有匹配上的函数
// 执行处理的消息处理方法
func (m *MessageMatchDispatcher) Dispatch(msg *model.Message) {
func (m *MessageMatchDispatcher) Dispatch(msg *dto.Message) {
var group MessageContextHandlerGroup
for _, node := range m.matchNodes {
if node.matchFunc(msg) {

View File

@ -8,7 +8,7 @@ import (
"go-wechat/client"
"go-wechat/common/current"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/plugin"
"go-wechat/service"
"go-wechat/types"
@ -137,11 +137,14 @@ func AI(m *plugin.MessageContext) {
}
// 返回消息为空
if resp.Choices[0].Message.Content == "" {
if len(resp.Choices) == 0 || resp.Choices[0].Message.Content == "" {
utils.SendMessage(m.FromUser, m.GroupUser, "AI似乎抽风了没有告诉我你需要的回答~", 0)
return
}
// 异步更新一下已使用的AI次数
go service.UpdateUsedAiTokens(m.FromUser, resp.Usage.TotalTokens)
// 保存一下AI 返回的消息,消息 Id 使用传入 Id 的负数
var replyMessage entity.Message
replyMessage.MsgId = -m.MsgId

View File

@ -3,7 +3,7 @@ package command
import (
"fmt"
"go-wechat/client"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/utils"
"log"
"strings"

View File

@ -5,10 +5,10 @@ import (
"errors"
"fmt"
"go-wechat/client"
"go-wechat/entity"
"go-wechat/model"
"go-wechat/model/dto"
"go-wechat/model/entity"
"go-wechat/model/vo"
"go-wechat/utils"
"go-wechat/vo"
"gorm.io/gorm"
"log"
"strings"
@ -156,7 +156,7 @@ func (l leiGod) info() (replyMsg string) {
if err = lgu.Login(); err != nil {
return "登录失败: " + err.Error()
}
var ui model.LeiGodUserInfoResp
var ui dto.LeiGodUserInfoResp
if ui, err = lgu.Info(); err != nil {
return "获取详情失败: " + err.Error()
}

View File

@ -1,7 +1,7 @@
package plugins
import (
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/plugin"
"go-wechat/service"
"time"

View File

@ -3,7 +3,7 @@ package plugins
import (
"go-wechat/client"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/plugin"
"go-wechat/utils"
)

View File

@ -24,7 +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/dto", app.ChangeUseAiModel) // 修改使用的AI模型
api.POST("/ai/assistant", app.ChangeUseAiAssistant) // 修改使用的AI助手
api.PUT("/welcome/status", app.ChangeEnableWelcomeStatus) // 修改是否开启迎新状态
api.PUT("/command/status", app.ChangeEnableCommandStatus) // 修改是否开启指令状态

View File

@ -2,7 +2,7 @@ package service
import (
"go-wechat/client"
"go-wechat/entity"
"go-wechat/model/entity"
)
// GetAllAiAssistant

View File

@ -2,8 +2,9 @@ package service
import (
"go-wechat/client"
"go-wechat/entity"
"go-wechat/vo"
"go-wechat/model/entity"
"go-wechat/model/vo"
"gorm.io/gorm"
"log"
"strings"
)
@ -119,3 +120,16 @@ func updateLastActive(msg entity.Message) {
log.Printf("更新群或者好友活跃时间失败, 错误信息: %v", err)
}
}
// UpdateUsedAiTokens
// @description: 更新已使用的AI次数
// @param wxId 微信好友或者群聊Id
// @param tokens 新增的tokens额度
func UpdateUsedAiTokens(wxId string, tokens int) {
err := client.MySQL.Model(&entity.Friend{}).
Where("wxid = ?", wxId).
Update("`used_tokens`", gorm.Expr(" `used_tokens` + ?", tokens)).Error
if err != nil {
log.Printf("更新AI使用次数失败, 错误信息: %v", err)
}
}

View File

@ -2,7 +2,7 @@ package service
import (
"go-wechat/client"
"go-wechat/vo"
"go-wechat/model/vo"
)
// GetGroupUsersByGroupId

View File

@ -2,8 +2,8 @@ package service
import (
"go-wechat/client"
"go-wechat/entity"
"go-wechat/vo"
"go-wechat/model/entity"
"go-wechat/model/vo"
"log"
"os"
"strconv"

View File

@ -3,7 +3,7 @@ package cleargroupuser
import (
"fmt"
"go-wechat/client"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/service"
"go-wechat/utils"
"log"

View File

@ -6,8 +6,8 @@ import (
"go-wechat/client"
"go-wechat/common/constant"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model"
"go-wechat/model/dto"
"go-wechat/model/entity"
"go-wechat/utils"
"gorm.io/gorm"
"log"
@ -24,7 +24,7 @@ var hc = resty.New()
// Sync
// @description: 同步好友列表
func Sync() {
var base model.Response[[]model.FriendItem]
var base dto.Response[[]dto.FriendItem]
resp, err := hc.R().
SetHeader("Content-Type", "application/json;chartset=utf-8").
@ -155,7 +155,7 @@ func Sync() {
// @description: 同步群成员
// @param gid
func syncGroupUsers(tx *gorm.DB, gid string) {
var baseResp model.Response[model.GroupUser]
var baseResp dto.Response[dto.GroupUser]
// 组装参数
param := map[string]any{
@ -242,8 +242,8 @@ func syncGroupUsers(tx *gorm.DB, gid string) {
// @param wxid
// @return ent
// @return err
func getContactProfile(wxid string) (ent model.ContactProfile, err error) {
var baseResp model.Response[model.ContactProfile]
func getContactProfile(wxid string) (ent dto.ContactProfile, err error) {
var baseResp dto.Response[dto.ContactProfile]
// 组装参数
param := map[string]any{

View File

@ -5,9 +5,9 @@ import (
"fmt"
"github.com/sashabaranov/go-openai"
"go-wechat/config"
"go-wechat/model/vo"
"go-wechat/service"
"go-wechat/utils"
"go-wechat/vo"
"log"
"strings"
)

View File

@ -4,7 +4,7 @@ import (
"fmt"
"go-wechat/client"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/service"
"go-wechat/utils"
"log"

View File

@ -4,7 +4,7 @@ import (
"fmt"
"go-wechat/client"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/service"
"go-wechat/utils"
"log"

View File

@ -4,7 +4,7 @@ import (
"fmt"
"go-wechat/client"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/service"
"go-wechat/utils"
"log"

View File

@ -4,7 +4,7 @@ import (
"fmt"
"go-wechat/client"
"go-wechat/config"
"go-wechat/entity"
"go-wechat/model/entity"
"go-wechat/service"
"go-wechat/utils"
"log"

View File

@ -4,7 +4,7 @@ import (
"encoding/json"
"go-wechat/common/current"
"go-wechat/config"
"go-wechat/model"
"go-wechat/model/dto"
"go-wechat/types"
"go-wechat/utils"
"log"
@ -16,7 +16,7 @@ import (
// @description: 解析消息
// @param msg
func parse(remoteAddr net.Addr, msg []byte) {
var m model.Message
var m dto.Message
if err := json.Unmarshal(msg, &m); err != nil {
log.Printf("[%s]消息解析失败: %v", remoteAddr, err)
log.Printf("[%s]消息内容: %d -> %v", remoteAddr, len(msg), string(msg))

View File

@ -6,16 +6,16 @@ import (
"errors"
"fmt"
"github.com/go-resty/resty/v2"
"go-wechat/model"
"go-wechat/model/dto"
"log"
)
// LeiGod
// @description: 雷神加速器相关接口
type LeiGod interface {
Login() error // 登录
Info() (model.LeiGodUserInfoResp, error) // 获取用户信息
Pause() error // 暂停加速
Login() error // 登录
Info() (dto.LeiGodUserInfoResp, error) // 获取用户信息
Pause() error // 暂停加速
}
type leiGod struct {
@ -59,7 +59,7 @@ func (l *leiGod) Login() (err error) {
}
pbs, _ := json.Marshal(param)
var loginResp model.Response[any]
var loginResp dto.Response[any]
var resp *resty.Response
res := resty.New()
@ -84,7 +84,7 @@ func (l *leiGod) Login() (err error) {
return
}
var loginInfo model.LeiGodLoginResp
var loginInfo dto.LeiGodLoginResp
if err = json.Unmarshal(bs, &loginInfo); err != nil {
return
}
@ -100,7 +100,7 @@ func (l *leiGod) Login() (err error) {
// @description: 获取用户信息
// @receiver l
// @return string
func (l *leiGod) Info() (ui model.LeiGodUserInfoResp, err error) {
func (l *leiGod) Info() (ui dto.LeiGodUserInfoResp, err error) {
// 组装参数
param := map[string]any{
"account_token": l.token,
@ -109,7 +109,7 @@ func (l *leiGod) Info() (ui model.LeiGodUserInfoResp, err error) {
}
pbs, _ := json.Marshal(param)
var userInfoResp model.Response[model.LeiGodUserInfoResp]
var userInfoResp dto.Response[dto.LeiGodUserInfoResp]
var resp *resty.Response
res := resty.New()
@ -145,7 +145,7 @@ func (l *leiGod) Pause() (err error) {
}
pbs, _ := json.Marshal(param)
var pauseResp model.Response[any]
var pauseResp dto.Response[any]
var resp *resty.Response
res := resty.New()

View File

@ -3,7 +3,7 @@ package utils
import (
"github.com/go-resty/resty/v2"
"go-wechat/config"
"go-wechat/model"
"go-wechat/model/dto"
"log"
)
@ -29,7 +29,7 @@ func NewsUtil() News {
// @receiver news
// @return records
func (news) MorningPost() (records []string) {
var newsResp model.MorningPost
var newsResp dto.MorningPost
res := resty.New()
resp, err := res.R().