ai_scheduler/doc/AI_DEV_GUIDE.md

27 KiB
Raw Blame History

AI 数字销售助手 — AI 开发者快速指南

本文档面向 AI 编程助手,帮助你在最短时间内理解项目全貌并高效开发。 完整接口清单与数据模型详见根目录 README.md。


🎯 项目终极目标(最重要,务必理解)

构建一个能完全模仿真人销售在微信上与客户对话的 AI 系统。

这不是一个普通的客服机器人。它的核心差异在于:

  1. 数字销售分身:通过上传销售本人的真实聊天记录,AI 提取其个人风格(方言、句式、语气、性格),构建一个"数字分身"——回复风格与销售本人高度一致。

  2. 四大维度画像驱动:AI 不是简单回复,而是基于四大维度画像(销售风格 / 项目资料 / 聊天技巧 / 客户画像)综合理解场景后生成回复,就像一个真正的销售在思考。

  3. 自主运营能力:

    • 自动回复:根据客户等级(熟客/意向/沉睡/非客户)采取不同策略
    • 主动触达:生日祝福、活动推送、新盘推荐
    • 画像自迭代:每次对话后自动分析并完善客户画像
    • 等级评估:定期重新评估客户等级,动态调整运营策略
  4. 最终愿景:销售人员只需处理 AI 搞不定的关键对话,日常客户维护、跟进、促单全部由 AI 代劳——让一个销售能有效服务 10 倍于现在的客户数量。

理解这个目标后,你写的每一行代码都应该服务于:让 AI 更像那个销售、更懂那个客户、更专业地推进销售进程。


项目目录结构

ai_scheduler/
├── cmd/server/                  # 程序入口
│   ├── main.go                  # 启动入口
│   ├── wire.go                  # Wire DI 声明(//go:build wireinject)
│   └── wire_gen.go              # Wire 自动生成(禁止手动编辑)
├── config/                      # 配置文件
│   ├── config.yaml              # 主配置(MySQL/Mongo/Redis/JWT/微信协议地址等)
│   └── config_env.yaml          # 环境变量覆盖
├── internal/
│   ├── biz/                     # ★ 业务逻辑层(最核心的开发区域)
│   │   ├── advice_wx.go         #   微信回调处理 + 消息流水 + 会话聚合查询
│   │   ├── advice_wx_send.go    #   微信消息发送
│   │   ├── advice_strategy.go   #   智能策略(四级回复/主动对话)
│   │   ├── advice_client.go     #   客户管理 + 等级评估 + 互动时间
│   │   ├── advice_advicer.go    #   销售管理
│   │   ├── advice_project.go    #   项目管理
│   │   ├── advice_skill.go      #   聊天技巧
│   │   ├── advice_chat.go       #   AI 对话(LLM 调用)
│   │   ├── advice_evaluate.go   #   客户等级评估
│   │   ├── advice_iterate.go    #   画像自迭代
│   │   ├── advice_proactive.go  #   主动触达(生日/活动推送)
│   │   ├── advice_activity.go   #   产品活动
│   │   ├── advice_model_sup.go  #   LLM 模型配置
│   │   ├── advice_customer_new.go # ★ 微信好友 CRUD + 差集对比(ai_advice_customer)
│   │   ├── advicer_admin.go     #   管理员账号
│   │   ├── advicer_industry.go  #   行业模板
│   │   ├── provider_set.go      #   Wire Provider 集合
│   │   ├── handle/              #   ⚠️ 历史遗留死代码,可忽略
│   │   └── llm_service/         #   ⚠️ 历史遗留死代码,可忽略
│   ├── services/advice/         # ★ HTTP Handler 适配层
│   │   ├── wxhook.go            #   回调 + 会话接口 Handler
│   │   ├── wx_proxy.go          #   微信 API 代理(分发到 wxDispatchMap)
│   │   ├── wx_ws_hub.go         #   WebSocket Hub(实时推送新消息/在线状态)
│   │   ├── customer_new.go      #   ★ 微信好友 CRUD Handler(Add/List/Del/Diff/BatchAdd)
│   │   ├── advicer.go           #   销售/项目/技巧等 Handler
│   │   ├── client.go            #   客户 Handler
│   │   ├── smart.go             #   智能策略 Handler
│   │   └── provider_set.go      #   Wire Provider 集合
│   ├── server/                  # HTTP 服务器
│   │   ├── router/
│   │   │   ├── router.go        #   ★ 路由总装 + registerCommon 响应包装中间件 + WebSocket 路由
│   │   │   └── advicer.go       #   ★ 全部业务路由注册(~80 个接口)
│   │   ├── http.go              #   Fiber 服务器创建(NewHTTPServer 参数列表需同步)
│   │   └── server.go            #   服务器生命周期
│   ├── entitys/                 # ★ 请求/响应 DTO
│   │   ├── advicer_data.go      #   ★ 核心 DTO(~500 行,最频繁修改)
│   │   ├── advicer.go           #   销售相关 DTO
│   │   ├── advicer_admin.go     #   管理员 DTO
│   │   └── response.go          #   通用响应结构
│   ├── data/
│   │   ├── mongo_model/         # ★ MongoDB 集合模型
│   │   │   ├── advicer_wx_msg.go        #   微信消息流水
│   │   │   ├── advicer_version.go       #   销售版本(画像维度)
│   │   │   ├── advicer_client.go        #   客户(MongoDB 侧)
│   │   │   ├── advicer_project.go       #   项目资料
│   │   │   ├── advicer_talk_skill.go    #   聊天技巧
│   │   │   ├── advicer_activity.go      #   活动
│   │   │   ├── advicer_proactive_log.go #   主动触达记录
│   │   │   ├── advicer_chat_his.go      #   AI 对话历史
│   │   │   ├── advicer_project_data.go  #   项目资料(新版)
│   │   │   ├── common.go                #   公共结构(*Item 包装)
│   │   │   └── provider_set.go          #   Wire Provider
│   │   ├── model/               #   MySQL GORM 模型(*.gen.go 禁止手动编辑)
│   │   │   └── ai_advice_customer.gen.go # ★ 微信好友表模型
│   │   ├── impl/                #   MySQL GORM 数据访问实现
│   │   │   ├── advice_customer_impl.go # ★ 微信好友 Impl(含 BatchInsert)
│   │   │   └── provider_set.go  #   Wire Provider 集合
│   │   ├── constants/           #   常量(Prompt 模板、模型映射)
│   │   └── error/               #   错误码
│   ├── config/config.go         # 配置结构体
│   ├── middleware/               # JWT 认证中间件
│   ├── jobs/advice_task.go      # 定时任务(cron)
│   └── pkg/                     # 工具包
│       ├── wx/                  #   ★ 微信协议封装
│       │   ├── api.go           #     API 端点注册
│       │   ├── request.go       #     HTTP 请求封装
│       │   ├── callback.go      #     回调报文解析(CallbackEvent 结构 + 消息过滤)
│       │   ├── qs_*.go          #     各类型请求/响应结构体
│       │   └── apidoc/          #     上游 API 文档
│       ├── utils_mongo/         #   MongoDB 工具
│       ├── utils_oss/           #   OSS 文件存储
│       └── ...                  #   其他工具包
├── web/                         # ★ 前端(零构建,静态托管)
│   ├── project.html             #   项目后台入口(★ 版本号管理)
│   ├── admin.html               #   管理后台入口
│   ├── index.html               #   首页
│   └── assets/
│       ├── css/theme.css        #   深色科技风设计系统
│       └── js/
│           ├── core.js          #   ★ 核心库(API/Toast/Modal/Store)
│           ├── wx.js            #   ★ 微信工作台-核心(状态/生命周期/通讯录/WS/AI设置)
│           ├── wx_login.js      #   ★ 微信工作台-登录模块(二维码/在线检测/登出)
│           ├── wx_chat.js       #   ★ 微信工作台-聊天模块(会话/消息/联系人详情)
│           ├── project.js       #   项目后台主入口(VIEWS 注册表)
│           ├── project_data.js  #   数据中心(销售/项目/技巧/客户编辑)
│           ├── project_detail.js #  项目设置
│           ├── project_list.js  #   项目列表
│           ├── project_analysis.js # 聊天记录分析
│           ├── project_activity.js # 活动管理
│           ├── project_drill.js #   AI 演练
│           ├── project_smart.js #   智能策略
│           ├── project_modelsup.js # 模型配置
│           ├── admin.js         #   管理后台主入口
│           ├── admin_admin.js   #   管理员管理
│           ├── admin_industry.js #  行业模板管理
│           └── admin_modelsup.js #  模型配置管理
├── sql/                         # 数据库初始化脚本
│   ├── 01_ai_advice_project_template.sql
│   ├── 02_advicer_mongo_init.js
│   ├── 03_advicer_join_date.sql
│   ├── 03_advicer_wx_token.sql
│   └── 04_ai_advice_customer.sql  # ★ 微信好友表 DDL
├── tmpl/                        # Excel 模板文件
├── go.mod / go.sum              # Go 模块依赖
├── Makefile                     # 构建命令
└── Dockerfile                   # Docker 部署

技术栈

Go 1.26 + Fiber v2 + GORM(MySQL) + MongoDB + Redis + Wire DI + 原生前端(零构建)

调用链

HTTP → Fiber中间件(CORS/JWT) → Router(Vali校验) → Service → Biz → Impl/Mongo → LLM
                                                                    ↓
                                              registerCommon 统一包装 {code, message, data}

Wire 依赖注入

  • cmd/server/wire.go 声明依赖关系(//go:build wireinject)
  • cmd/server/wire_gen.go 由 wire 工具自动生成(禁止手动编辑)
  • 各层通过 provider_set.go 暴露 Wire Provider
  • 新增模块后必须:
    1. 在各层 provider_set.go 添加新 Provider
    2. 在 http.go 的 NewHTTPServer 参数列表添加新 Service
    3. 在 router.go 的 SetupRoutes 参数列表添加新 Service
    4. 在 advicer.go 的 AdvicerRouterRegist 参数列表添加新 Service
    5. 执行 wire 命令重新生成 wire_gen.go

数据库概览

MySQL 表(GORM 管理,*.gen.go 禁止手动编辑)

表名 说明
ai_advice_admin 管理员账号
ai_advice_advicer 销售基本信息(含 wx_device_id 微信设备标识)
ai_advice_advicer_version 销售版本(画像维度 JSON)
ai_advice_client 客户基本信息
ai_advice_customer ★ 微信好友列表(self_wxid + user_name 联合唯一键)
ai_advice_industry_temp 行业模板
ai_advice_model_sup LLM 模型配置
ai_advice_project 项目信息(含项目级 wx_token)
ai_advice_session AI 对话会话
ai_advice_talk 聊天技巧

MongoDB 集合

集合名 说明 关键字段
advicer_wx_msg ★ 微信消息流水(回调+发送) appId, wxid, selfWxid, direction, msgType, content, read, createAt
advicer_version 销售画像维度 dialectFeatures, sentencePatterns, toneTags, personalityTags
advicer_project 项目资料维度 regionValue, competitionComparison, coreSellingPoints
advicer_talk_skill 聊天技巧维度 needsMining, painPointResponse, valueBuilding, closingTechniques
advicer_client 客户画像 clientLevel, personalInfo, purchasePurpose, coreDemands
advicer_activity 产品活动 name, content, startAt, endAt, status
advicer_proactive_log 主动触达记录 clientId, wxid, type, content
advicer_chat_his AI 对话历史 sessionId, messages
advicer_project_data 项目资料(新版) sections[]

命名差异

层 命名风格 示例
MySQL 蛇形 project_id
MongoDB 驼峰(bson tag) projectId
前端 JS 驼峰 projectId

核心数据模型:四大维度

系统的一切围绕四个独立维度展开,每个维度有独立的 MySQL 配置 + MongoDB 数据:

维度 含义 MongoDB 集合 关键字段
advicer (销售) 个人风格:方言/句式/语气/性格/标志性对话 advicer_version dialectFeatures, sentencePatterns, toneTags, personalityTags, signatureDialogues
project (项目) 产品资料:区域价值/竞品对比/卖点/配套/背书 advicer_project regionValue, competitionComparison, coreSellingPoints...
skill (技巧) 聊天策略:需求挖掘/痛点应对/价值塑造/促单/节奏 advicer_talk_skill needsMining, painPointResponse, valueBuilding, closingTechniques...
client (客户) 客户画像:身份/需求/顾虑/等级/决策链 advicer_client clientLevel, personalInfo, purchasePurpose, coreDemands, concerns[]

客户等级:unknown → regular(熟客) / intent(意向) / sleeping(沉睡) / non(非客户) — 等级决定 AI 行为策略。


前端架构

页面结构

页面 文件 用途
首页 index.html 登录 + 项目选择
管理后台 admin.html 全局配置(管理员/行业模板/LLM模型)
项目后台 project.html ★ 主要工作区(项目管理/微信工作台/智能策略等)

前端模块加载机制

  1. 零构建:所有 JS 通过 <script> 标签在 HTML 中按序引入,无打包工具
  2. IIFE 模式:每个 JS 文件用 (function(global){...})(window) 包裹
  3. 版本号缓存:<script src="assets/js/xxx.js?v=42"> — 修改 JS 后必须更新版本号
  4. 全局命名空间:window.Core(核心库)、window.WxN(微信模块共享)、window.Wx(微信挂载点)

微信工作台模块拆分(WxN 命名空间模式)

微信工作台拆分为三个文件,通过 window.WxN 共享命名空间交互:

文件 职责 导出(WxN.xxx)
wx.js 核心:state 管理/生命周期/通讯录/WebSocket/AI 设置/好友差集同步 loadProfile, loadContacts, renderContacts, connectWs, openAiConfig
wx_login.js 登录:二维码/在线检测/登出/回调设置 renderLoginCard, checkOnline, checkOnlineLoop, doLogout, resetToOffline
wx_chat.js 聊天:会话列表/消息渲染/发送/联系人详情 loadConversations, openConversationChat, renderChat, doSend, handleNewMessage

架构要点:

  • wx.js 创建 WxN 命名空间并通过 Object.defineProperty 暴露 state getter
  • 子模块通过 WxN.state 访问最新状态(避免闭包捕获旧 state 引用)
  • 子模块通过 WxN.xxx = fn 导出函数供其他模块调用
  • 加载顺序:wx.js → wx_login.js → wx_chat.js

Core.js API 速查

// HTTP 请求
Core.api(path, params)        // 管理后台 API(POST JSON,自动 JWT,自动解包 data)
                              // 完整路径:/api/v1/admin/advice/admin/{path}
Core.wxApi(path, params)      // 微信代理 API(自动注入 projectId,解包 {code, data})
                              // 完整路径:/api/v1/admin/advice/admin/wx/{path}

// UI
Core.toast(msg, type)         // 提示(type: "ok"|"err"|"warn"|"info")
Core.modal({title, body, footer, width}) // 模态框,返回 {root, body, close}
Core.confirm(msg, title)      // 确认对话框,返回 Promise<boolean>
Core.loading(show, text)      // 全屏加载遮罩

// 工具
Core.esc(str)                 // HTML 转义
Core.store(key, val)          // localStorage 读写
Core.initial(name)            // 取姓名首字
Core.nowTime()                // 当前时间字符串
Core.sleep(ms)                // Promise 延迟
Core.splitBubbles(text)       // 拆分长消息为多条气泡

// 常量
Core.KEYS.wxApp               // localStorage key: 微信登录态
Core.KEYS.wxBrief             // localStorage key: 联系人简要信息缓存
Core.KEYS.token               // localStorage key: JWT token

项目后台视图注册

新增模块在 project_*.js 定义 renderXxx(),在 project.js 的 VIEWS 中用延迟包装注册:

render: function () { renderXxx(); }  // ✓ 正确
render: renderXxx                     // ✗ 错误(函数提升时序问题)

后端开发约定

响应格式

普通 API:    前端 Core.api() → 后端 HandleResponse → registerCommon 包装 → {code:0, data:..., message:"success"}
微信代理 API:前端 Core.wxApi() → wx_proxy.Proxy → c.Locals("skip_response_wrap", true) → {code:0, data:..., message:"ok"}

⚠️ 重要:registerCommon 中间件会包装所有响应。微信代理已自行包装,必须设置 skip_response_wrap 避免双层嵌套。

  • 成功:{code: 0, message: "success", data: <业务数据>}
  • 成功兼容:{code: 200, ...}(前端同时接受 0 和 200)
  • 分页:data 内含 {list, total, page, pageSize}
  • 失败:{code: <错误码>, message: <错误信息>, data: null}

DataTemp 通用 CRUD 基类模式

MySQL CRUD 模块遵循 DataTemp 模板模式:

  • impl 继承 dataTemp.DataTempBase[T],自动获得 Add/Update/Del/GetListToStruct/GetRangeToMapStruct 等方法
  • 查询条件使用 *builder.Cond 指针参数(不是接口值)
  • 分页使用 dataTemp.ReqPageBo{Page: n, Limit: n}(注意字段是 Limit 不是 PageSize)

Mongo 列表接口必须用 *Item 包装

type XxxItem struct {
    Id       primitive.ObjectID `bson:"_id" json:"id"`
    XxxMongo `bson:",inline"`
}

前端编辑/删除依赖此 id 字段。

微信代理新增 API

  1. 在 internal/pkg/wx/qs_*.go 定义 Req/Res 结构体
  2. 在 internal/pkg/wx/api.go 注册端点 var Xxx = Api[XxxReq, XxxResData]{Path: "xxx/yyy"}
  3. 在 internal/services/advice/wx_proxy.go 的 wxDispatchMap 添加映射
  4. 前端通过 Core.wxApi("xxx/yyy", payload) 调用

微信工作台模块(当前活跃开发区域)

架构要点

  • 前端:wx.js + wx_login.js + wx_chat.js,通过 WxN 命名空间协作
  • 后端代理:wx_proxy.go 将前端请求分发到上游微信协议服务(100+ API 端点)
  • 消息回调:上游推送客户消息 → /api/v1/advicer/wx/callback → advice_wx.go 处理入库 MongoDB
  • 实时通信:WebSocket(/api/v1/advicer/ws)推送新消息和在线状态变化
  • 好友同步:前端 syncCustomerDiff() → 后端 customer/diff + customer/batch_add → MySQL ai_advice_customer

初始化流程(重要)

页面加载/刷新 → mount() → freshState()
  → 从 URL hash 解析 wx-advicer=advicerId
  → fetchDeviceAndCheck(advicerId)
    → Core.api("advicer/info", {advicerId}) 获取最新 wx_device_id
    → state.app = { appId: wx_device_id }    ← 始终从 API 获取,不缓存
    → checkOnline()
      → 在线 → checkOnlineLoop()  ← 内部调用 connectWs() 建立 WebSocket
               loadProfile()      ← 获取 wxid/nickName 等
                 .then(loadConversations())  ← 需要 wxid 作为 selfWxid
               loadContacts()     ← 拉取通讯录
                 .then(syncCustomerDiff())  ← 好友差集同步
      → 离线 → getQrCode() 显示二维码

关键要点:

  • state.app.appId 始终从 advicer/info API 实时获取,不使用 localStorage 缓存
  • checkOnlineLoop() 内部已调用 connectWs(),不要额外调用
  • loadProfile() 先于 loadConversations() 完成,因为会话查询需要 selfWxid
  • loadProfile() 返回 Promise,依赖 state.app.wxid 的操作必须在其 .then() 中执行

QR 码登录流程

getQrCode() → 选择地区 → login/getLoginQrCode → 返回 {uuid, appId, qrImgBase64}
  → 更新销售 wx_device_id(Core.api("advicer/wx_device/update"))
  → startLoginPolling() 每 10 秒轮询 login/checkLogin
  → status=2(登录成功)→ state.app = {appId, wxid, nickName, ...}
    → checkOnlineLoop()  ← 内部调用 connectWs()
    → loadProfile().then(loadConversations())
    → loadContacts()

WebSocket 实时通信机制

前端 connectWs()
  → 创建 WebSocket 到 /api/v1/advicer/ws?token=JWT
  → onopen 发送 {"action":"subscribe","appId": state.app.appId}
  → 后端 WxWsHub 设置 client.appId = 订阅的 appId

后端 Broadcast(appId, event, data)
  → 遍历所有已连接 client
  → 匹配 client.appId == appId → 推送 JSON 事件

前端 onmessage → handleWsEvent(msg)
  → "new_message"  → WxN.handleNewMessage(data)   ← 定义在 wx_chat.js
  → "online_status" → WxN.handleOnlineStatus(data) ← 定义在 wx_login.js

appId 匹配:前端订阅的 appId = wx_device_id(来自 advicer/info API),后端广播的 appId = 回调事件中的 Appid 字段(来自上游微信协议服务)。两者必须一致。

消息回调处理流程

上游协议服务 → POST /api/v1/advicer/wx/callback
  → advice_wx.go.HandleCallback()
    → 解析 AddMsg 事件 → 提取消息字段
    → 过滤:gh_ 开头的 wxid(公众号消息)→ 忽略
    → 过滤:msgType 为 "other" → 忽略
    → 去重(AppId + NewMsgId)
    → 入库 MongoDB advicer_wx_msg
    → WebSocket 广播 new_message 事件(按 appId 匹配推送)
    → 触发智能策略(客户文本消息异步 AI 决策)

会话查询流程

前端 loadConversations()
  → POST wx/conversation/list { selfWxid }     ← 不再传 appId
  → MongoDB 聚合管道:$match(selfWxid) → $sort → $group by wxid → 分页
  → 返回会话列表(每个 wxid 的最新消息预览 + 未读数)

前端 openConversationChat(wxid)
  → POST wx/conversation/msgs { selfWxid, wxid }  ← 不再传 appId
  → MongoDB 查询:filter(selfWxid+wxid) → sort(createAt:1) → 分页
  → 返回消息列表 → 渲染聊天气泡

前端 markConvAsRead(wxid)
  → POST wx/conversation/read { selfWxid, wxid }  ← 不再传 appId
  → MongoDB 更新:filter(wxid+direction=customer+read=false) → set read=true

好友差集同步流程

前端 loadContacts() 获取通讯录 {friends, chatrooms}
  → syncCustomerDiff()
    → POST advicer/customer/diff { selfWxid, userNames: friends }
    → 后端返回 { list: [已有好友记录], diff: [缺失的 userName] }
    → 用 list 填充 state.brief(联系人简要信息)
    → diff 不为空时:
      → 分批(每批 20 个)调用 getBriefInfo(带 3 次重试,间隔 2 秒)
      → 组装入库数据 → POST advicer/customer/batch_add { list: records }
      → 同时更新 state.brief 并刷新渲染
群聊仍通过 loadBriefInfoForChatrooms() 单独拉取 brief info

定时任务概览

任务 频率 作用
客户等级评估 每天凌晨 重新评估所有客户等级
熟客超时兜底 每 2 分钟 熟客消息超 10 分钟无人工回复 → AI 礼貌回复
画像自迭代 每 10 分钟 对话闲置超 30 分钟 → 分析新消息完善画像
主动触达 每小时 生日祝福 / 活动推送(9:00-21:00,受 auto_reply 总开关控制)

所有任务使用 cron.SkipIfStillRunning 防堆积。


常见开发场景速查

新增一个 MySQL CRUD 模块(参考 ai_advice_customer 模块):

  1. sql/04_xxx.sql 建表 DDL
  2. data/model/xxx.gen.go 定义 GORM 模型
  3. data/impl/xxx_impl.go 继承 DataTemp 实现数据访问
  4. data/impl/provider_set.go 注册 Wire Provider
  5. entitys/advicer_data.go 定义请求/响应结构体
  6. biz/xxx.go 实现业务逻辑
  7. biz/provider_set.go 注册 Wire Provider
  8. services/advice/xxx.go 实现 Handler
  9. services/advice/provider_set.go 注册 Wire Provider
  10. server/http.go + router/router.go + router/advicer.go 添加参数 + 注册路由
  11. 执行 wire 重新生成 wire_gen.go
  12. go build ./cmd/server 编译验证

新增一个 MongoDB 集合:

  1. data/mongo_model/xxx.go 定义模型 + *Item 包装
  2. data/mongo_model/provider_set.go 注册 Wire Provider
  3. biz/advice_xxx.go 实现 CRUD 业务
  4. 前端 project_data.js 添加编辑界面

新增一个微信代理 API:

  1. pkg/wx/qs_*.go 定义 Req/Res
  2. pkg/wx/api.go 注册端点
  3. services/advice/wx_proxy.go 的 wxDispatchMap 添加映射
  4. 前端 Core.wxApi("path", payload) 调用

修改 AI 分析提示词:

  • data/constants/prompt.go(BasePrompt 基础提示词)
  • data/constants/advicer.go(Prompt 模板 + 维度映射)

修改前端微信工作台:

  • 核心状态/通讯录/WS → wx.js
  • 登录/在线检测/登出 → wx_login.js
  • 会话/消息/发送/详情 → wx_chat.js
  • 样式 → theme.css
  • 修改后必须更新 project.html 中的 ?v=N 版本号

⚠️ 避坑清单

  1. *.gen.go 和 wire_gen.go 禁止手动编辑——它们由工具自动生成
  2. Mongo 全量更新是 $set 语义——务必"先读后合并再写",否则清空未提交字段
  3. 微信代理响应必须设 skip_response_wrap——否则被 registerCommon 二次包装
  4. 前端修改必须更新版本号——?v=N 控制浏览器缓存,不更新则浏览器用旧缓存
  5. 历史遗留代码(internal/biz/handle、llm_service 等)是死代码,可忽略
  6. 新增无需登录的接口须在 router.go 的 AuthMiddleware 白名单中追加
  7. loadProfile() 返回 Promise——依赖 state.app.wxid 的操作必须在其 .then() 回调中执行
  8. 子模块通过 WxN.state 访问状态——不要在闭包中缓存 state 引用,始终通过 getter 获取最新值
  9. state.app.appId 不缓存——每次进入工作台都从 advicer/info API 实时获取 wx_device_id
  10. checkOnlineLoop() 已内含 connectWs()——不要在其外部再调 connectWs(),否则导致连接级联断开
  11. builder.Cond 查询用指针——DataTemp 方法接受 *builder.Cond 指针参数,传 &cond 而非 cond
  12. dataTemp.ReqPageBo 分页字段是 Limit——不是 PageSize
  13. 新增 Service 后需同步三个文件——http.go、router.go、advicer.go 的函数签名都要加参数
  14. 会话/消息查询不传 appId——appId 会变,用 selfWxid 作为筛选依据
  15. WebSocket 订阅 appId 必须与广播 appId 一致——前端订阅用 wx_device_id,后端广播用回调的 Appid 字段

编译与部署

# 编译(忽略历史死代码)
go build ./cmd/server/

# 仅验证业务代码
go build ./internal/entitys/ ./internal/services/advice/

# 本地运行
go run cmd/server/main.go

# Wire 重新生成(修改依赖后执行)
cd cmd/server && wire

# Docker 部署
docker-compose up -d

最后更新:2026-09-24 · 完整文档见 README.md