🔥 代码结构调整
This commit is contained in:
36
model/dto/friend.go
Normal file
36
model/dto/friend.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package dto
|
||||
|
||||
// FriendItem
|
||||
// @description: 好友列表数据
|
||||
type FriendItem struct {
|
||||
CustomAccount string `json:"customAccount"` // 微信号
|
||||
EncryptName string `json:"encryptName"` // 不知道
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
Pinyin string `json:"pinyin"` // 昵称拼音大写首字母
|
||||
PinyinAll string `json:"pinyinAll"` // 昵称全拼
|
||||
Reserved1 int `json:"reserved1"` // 未知
|
||||
Reserved2 int `json:"reserved2"` // 未知
|
||||
Type int `json:"type"` // 类型
|
||||
VerifyFlag int `json:"verifyFlag"` // 未知
|
||||
Wxid string `json:"wxid"` // 微信原始Id
|
||||
}
|
||||
|
||||
// GroupUser
|
||||
// @description: 群成员返回结果
|
||||
type GroupUser struct {
|
||||
Admin string `json:"admin"` // 群主微信
|
||||
AdminNickname string `json:"adminNickname"` // 群主昵称
|
||||
ChatRoomId string `json:"chatRoomId"` // 群Id
|
||||
MemberNickname string `json:"memberNickname"` // 成员昵称 `^G`切割
|
||||
Members string `json:"members"` // 成员Id `^G`切割
|
||||
}
|
||||
|
||||
// ContactProfile
|
||||
// @description: 好友资料
|
||||
type ContactProfile struct {
|
||||
Account string `json:"account"` // 账号
|
||||
HeadImage string `json:"headImage"` // 头像
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
V3 string `json:"v3"` // v3
|
||||
Wxid string `json:"wxid"` // 微信Id
|
||||
}
|
||||
73
model/dto/leigod.go
Normal file
73
model/dto/leigod.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package dto
|
||||
|
||||
// LeiGodLoginResp
|
||||
// @description: 雷神登录返回
|
||||
type LeiGodLoginResp struct {
|
||||
LoginInfo struct {
|
||||
AccountToken string `json:"account_token"` // Token
|
||||
ExpiryTime string `json:"expiry_time"` // 有效期
|
||||
NnToken string `json:"nn_token"`
|
||||
} `json:"login_info"`
|
||||
UserInfo struct {
|
||||
Nickname string `json:"nickname"`
|
||||
Email string `json:"email"`
|
||||
Mobile string `json:"mobile"`
|
||||
Avatar string `json:"avatar"`
|
||||
RegionCode int `json:"region_code"`
|
||||
} `json:"user_info"`
|
||||
}
|
||||
|
||||
// LeiGodUserInfoResp
|
||||
// @description: 雷神用户信息返回
|
||||
type LeiGodUserInfoResp struct {
|
||||
UserPauseTime int `json:"user_pause_time"`
|
||||
Nickname string `json:"nickname"`
|
||||
Email string `json:"email"`
|
||||
CountryCode string `json:"country_code"`
|
||||
Mobile string `json:"mobile"`
|
||||
UserName string `json:"user_name"`
|
||||
MasterAccount string `json:"master_account"`
|
||||
Birthday string `json:"birthday"`
|
||||
PublicIp string `json:"public_ip"`
|
||||
Sex string `json:"sex"`
|
||||
LastLoginTime string `json:"last_login_time"`
|
||||
LastLoginIp string `json:"last_login_ip"`
|
||||
PauseStatus string `json:"pause_status"` // 暂停状态
|
||||
PauseStatusId int `json:"pause_status_id"` // 暂停状态 0未暂停1已暂停
|
||||
LastPauseTime string `json:"last_pause_time"` // 最后一次暂停时间
|
||||
VipLevel string `json:"vip_level"`
|
||||
Avatar string `json:"avatar"`
|
||||
AvatarNew string `json:"avatar_new"`
|
||||
PackageId string `json:"package_id"`
|
||||
IsSwitchPackage int `json:"is_switch_package"`
|
||||
PackageTitle string `json:"package_title"`
|
||||
PackageLevel string `json:"package_level"`
|
||||
BillingType string `json:"billing_type"`
|
||||
Lang string `json:"lang"`
|
||||
StopedRemaining string `json:"stoped_remaining"`
|
||||
ExpiryTime string `json:"expiry_time"` // 剩余时长
|
||||
ExpiryTimeSamp int `json:"expiry_time_samp"` // 剩余时长秒数
|
||||
Address string `json:"address"`
|
||||
MobileContactType string `json:"mobile_contact_type"`
|
||||
MobileContactNumber string `json:"mobile_contact_number"`
|
||||
MobileContactTitle string `json:"mobile_contact_title"`
|
||||
RegionCode int `json:"region_code"`
|
||||
IsPayUser string `json:"is_pay_user"`
|
||||
WallLogSwitch string `json:"wall_log_switch"`
|
||||
IsSetAdminPass int `json:"is_set_admin_pass"`
|
||||
ExpiredExperienceTime string `json:"expired_experience_time"`
|
||||
ExperienceExpiryTime string `json:"experience_expiry_time"`
|
||||
ExperienceTime int `json:"experience_time"`
|
||||
FirstInvoiceDiscount int `json:"first_invoice_discount"`
|
||||
NnNumber string `json:"nn_number"`
|
||||
UserSignature string `json:"user_signature"`
|
||||
MobileExpiryTime string `json:"mobile_expiry_time"`
|
||||
MobileExpiryTimeSamp int `json:"mobile_expiry_time_samp"`
|
||||
MobilePauseStatus int `json:"mobile_pause_status"`
|
||||
BlackExpiredTime string `json:"black_expired_time"`
|
||||
MobileExperienceTime string `json:"mobile_experience_time"`
|
||||
SuperTime string `json:"super_time"`
|
||||
NowDate string `json:"now_date"`
|
||||
NowTimeSamp int `json:"now_time_samp"`
|
||||
UserEarnMinutes string `json:"user_earn_minutes"`
|
||||
}
|
||||
215
model/dto/message.go
Normal file
215
model/dto/message.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
"go-wechat/types"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Message
|
||||
// @description: 消息
|
||||
type Message struct {
|
||||
MsgId int64 `json:"msgId"`
|
||||
CreateTime int `json:"createTime"`
|
||||
Content string `json:"content"`
|
||||
DisplayFullContent string `json:"displayFullContent"`
|
||||
FromUser string `json:"fromUser"`
|
||||
GroupUser string `json:"-"`
|
||||
MsgSequence int `json:"msgSequence"`
|
||||
Pid int `json:"pid"`
|
||||
Signature string `json:"signature"`
|
||||
ToUser string `json:"toUser"`
|
||||
Type types.MessageType `json:"type"`
|
||||
Raw string `json:"raw"`
|
||||
}
|
||||
|
||||
// systemMsgDataXml
|
||||
// @description: 微信系统消息的xml结构
|
||||
type systemMsgDataXml struct {
|
||||
SysMsg sysMsg `xml:"sysmsg"`
|
||||
Type string `xml:"type,attr"`
|
||||
}
|
||||
|
||||
// appMsgDataXml
|
||||
// @description: 微信app消息的xml结构
|
||||
type appMsgDataXml struct {
|
||||
XMLName xml.Name `xml:"msg"`
|
||||
Text string `xml:",chardata"`
|
||||
AppMsg struct {
|
||||
Text string `xml:",chardata"`
|
||||
Appid string `xml:"appid,attr"`
|
||||
SdkVer string `xml:"sdkver,attr"`
|
||||
Title string `xml:"title"`
|
||||
Des string `xml:"des"`
|
||||
Action string `xml:"action"`
|
||||
Type string `xml:"type"`
|
||||
ShowType string `xml:"showtype"`
|
||||
Content string `xml:"content"`
|
||||
URL string `xml:"url"`
|
||||
ThumbUrl string `xml:"thumburl"`
|
||||
LowUrl string `xml:"lowurl"`
|
||||
AppAttach struct {
|
||||
Text string `xml:",chardata"`
|
||||
TotalLen string `xml:"totallen"`
|
||||
AttachId string `xml:"attachid"`
|
||||
FileExt string `xml:"fileext"`
|
||||
} `xml:"appattach"`
|
||||
ExtInfo string `xml:"extinfo"`
|
||||
} `xml:"appmsg"`
|
||||
AppInfo struct {
|
||||
Text string `xml:",chardata"`
|
||||
Version string `xml:"version"`
|
||||
AppName string `xml:"appname"`
|
||||
} `xml:"appinfo"`
|
||||
}
|
||||
|
||||
// atMsgDataXml
|
||||
// @description: 微信@消息的xml结构
|
||||
type atMsgDataXml struct {
|
||||
XMLName xml.Name `xml:"msgsource"`
|
||||
Text string `xml:",chardata"`
|
||||
AtUserList string `xml:"atuserlist"`
|
||||
Silence string `xml:"silence"`
|
||||
MemberCount string `xml:"membercount"`
|
||||
Signature string `xml:"signature"`
|
||||
TmpNode struct {
|
||||
Text string `xml:",chardata"`
|
||||
PublisherID string `xml:"publisher-id"`
|
||||
} `xml:"tmp_node"`
|
||||
}
|
||||
|
||||
// sysMsg
|
||||
// @description: 消息主体
|
||||
type sysMsg struct{}
|
||||
|
||||
func (m Message) IsGroup() bool {
|
||||
return strings.HasSuffix(m.FromUser, "@chatroom")
|
||||
}
|
||||
|
||||
// IsPat
|
||||
// @description: 是否是拍一拍消息
|
||||
// @receiver m
|
||||
// @return bool
|
||||
func (m Message) IsPat() bool {
|
||||
// 解析xml
|
||||
var d systemMsgDataXml
|
||||
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return m.Type == types.MsgTypeRecalled && d.Type == "pat"
|
||||
}
|
||||
|
||||
// IsRevokeMsg
|
||||
// @description: 是否是撤回消息
|
||||
// @receiver m
|
||||
// @return bool
|
||||
func (m Message) IsRevokeMsg() bool {
|
||||
// 解析xml
|
||||
var d systemMsgDataXml
|
||||
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return m.Type == types.MsgTypeRecalled && d.Type == "revokemsg"
|
||||
}
|
||||
|
||||
// IsNewUserJoin
|
||||
// @description: 是否是新人入群
|
||||
// @receiver m
|
||||
// @return bool
|
||||
func (m Message) IsNewUserJoin() bool {
|
||||
if m.Type != types.MsgTypeSys {
|
||||
return false
|
||||
}
|
||||
|
||||
isInvitation := strings.Contains(m.Content, "\"邀请\"") && strings.Contains(m.Content, "\"加入了群聊")
|
||||
isScanQrCode := strings.Contains(m.Content, "通过扫描") && strings.Contains(m.Content, "加入群聊")
|
||||
sysFlag := isInvitation || isScanQrCode
|
||||
if sysFlag {
|
||||
return true
|
||||
}
|
||||
// 解析另一种情况
|
||||
var d systemMsgDataXml
|
||||
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
|
||||
return false
|
||||
}
|
||||
return d.Type == "delchatroommember"
|
||||
}
|
||||
|
||||
// IsAt
|
||||
// @description: 是否是At机器人的消息
|
||||
// @receiver m
|
||||
// @return bool
|
||||
func (m Message) IsAt() bool {
|
||||
return strings.HasSuffix(m.DisplayFullContent, "在群聊中@了你")
|
||||
}
|
||||
|
||||
// IsAtAll
|
||||
// @description: 是否是At所有人的消息
|
||||
// @receiver m
|
||||
// @return bool
|
||||
func (m Message) IsAtAll() bool {
|
||||
// 解析raw里面的xml
|
||||
var d atMsgDataXml
|
||||
if err := xml.Unmarshal([]byte(m.Signature), &d); err != nil {
|
||||
return false
|
||||
}
|
||||
// 转换@用户列表为数组
|
||||
atUserList := strings.Split(d.AtUserList, ",")
|
||||
// 判断是否包含@所有人
|
||||
return slice.Contain(atUserList, "notify@all")
|
||||
}
|
||||
|
||||
// IsPrivateText
|
||||
// @description: 是否是私聊消息
|
||||
// @receiver m
|
||||
// @return bool
|
||||
func (m Message) IsPrivateText() bool {
|
||||
// 发信人不以@chatroom结尾且消息类型为文本
|
||||
return !strings.HasSuffix(m.FromUser, "chatroom") && m.Type == types.MsgTypeText
|
||||
}
|
||||
|
||||
// CleanContentStartWith
|
||||
// @description: 判断是否包含指定消息前缀
|
||||
// @receiver m
|
||||
// @param prefix
|
||||
// @return bool
|
||||
func (m Message) CleanContentStartWith(prefix string) bool {
|
||||
content := m.Content
|
||||
|
||||
// 如果是@消息,过滤掉@的内容
|
||||
if m.IsAt() {
|
||||
re := regexp.MustCompile(`@([^ | ]+)`)
|
||||
matches := re.FindStringSubmatch(content)
|
||||
if len(matches) > 0 {
|
||||
// 过滤掉第一个匹配到的
|
||||
content = strings.Replace(content, matches[0], "", 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 去掉最前面的空格
|
||||
content = strings.TrimLeft(content, " ")
|
||||
content = strings.TrimLeft(content, " ")
|
||||
|
||||
return strings.HasPrefix(content, prefix)
|
||||
}
|
||||
|
||||
// IsInvitationJoinGroup
|
||||
// @description: 是否是邀请入群消息
|
||||
// @receiver m
|
||||
// @return bool 是否是邀请入群消息
|
||||
// @return string 邀请入群消息内容
|
||||
func (m Message) IsInvitationJoinGroup() (flag bool, str string) {
|
||||
if m.Type == types.MsgTypeApp {
|
||||
// 解析xml
|
||||
var md appMsgDataXml
|
||||
if err := xml.Unmarshal([]byte(m.Content), &md); err != nil {
|
||||
return
|
||||
}
|
||||
return md.AppMsg.Type == "5" && strings.Contains(md.AppMsg.Content, "邀请你加入群聊"), md.AppMsg.Des
|
||||
}
|
||||
return
|
||||
}
|
||||
18
model/dto/news.go
Normal file
18
model/dto/news.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package dto
|
||||
|
||||
// MorningPost
|
||||
// @description: 每日早报返回结构体
|
||||
type MorningPost struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Date string `json:"date"` // 新闻日期
|
||||
News []string `json:"news"` // 新闻标题文字版
|
||||
WeiYu string `json:"weiyu"` // 微语,就是一句屁话
|
||||
Image string `json:"image"` // 早报完整图片
|
||||
HeadImage string `json:"head_image"` // 早报头部图片
|
||||
} `json:"data"`
|
||||
Time int `json:"time"`
|
||||
Usage int `json:"usage"`
|
||||
LogId string `json:"log_id"`
|
||||
}
|
||||
9
model/dto/response.go
Normal file
9
model/dto/response.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package dto
|
||||
|
||||
// Response
|
||||
// @description: 基础返回结构体
|
||||
type Response[T any] struct {
|
||||
Code int `json:"code"` // 状态码
|
||||
Data T `json:"data"` // 数据
|
||||
Msg string `json:"msg"` // 消息
|
||||
}
|
||||
18
model/dto/userinfo.go
Normal file
18
model/dto/userinfo.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package dto
|
||||
|
||||
// RobotUserInfo
|
||||
// @description: 机器人用户信息
|
||||
type RobotUserInfo struct {
|
||||
WxId string `json:"wxid"` // 微信Id
|
||||
Account string `json:"account"` // 微信号
|
||||
Name string `json:"name"` // 昵称
|
||||
HeadImage string `json:"headImage"` // 头像
|
||||
Mobile string `json:"mobile"` // 手机
|
||||
Signature string `json:"signature"` // 个人签名
|
||||
Country string `json:"country"` // 国家
|
||||
Province string `json:"province"` // 省
|
||||
City string `json:"city"` // 城市
|
||||
CurrentDataPath string `json:"currentDataPath"` // 当前数据目录,登录的账号目录
|
||||
DataSavePath string `json:"dataSavePath"` // 微信保存目录
|
||||
DbKey string `json:"dbKey"` // 数据库的SQLCipher的加密key,可以使用该key配合decrypt.py解密数据库
|
||||
}
|
||||
Reference in New Issue
Block a user