You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

15 KiB

AGENTS.md — IGG4 微信小程序

项目概述

愈见昕生(原 gMG给力加油站/重症肌无力加油站)— MG 患者社区微信小程序。两种用户角色:患者(loginType=1)和医生(loginType=2)。基于 TypeScript + SCSS 构建,无测试框架。

信达小程序项目位置 C:\Users\kola\project\xinda-miniprogram

技术栈

类别 技术
语言 TypeScript + SCSS + WXML
包管理 pnpm(非 npm/yarn)
UI 库 Vant Weapp (@vant/weapp)
图表 ECharts(ec-canvas 组件)+ F2(JSX 语法,Babel 转译)
日期 dayjs(中文 locale + relativeTime 插件)
工具库 miniprogram-licia(curry、debounce 等)
富文本 mp-html
精度计算 number-precision
代码规范 @antfu/eslint-config + prettier(无分号、单引号、尾逗号、120 字符宽度)

命令

  • pnpm install — 安装依赖(使用 pnpm,非 npm/yarn)
  • pnpm run lint:fix — eslint 自动修复(使用 @antfu/eslint-config + prettier,stylistic 已禁用)
  • pnpm run beforeCompile — babel 转译 src/pages 中的 .jsx 文件(通过 project.config.json scripts 在微信开发者工具编译/预览/上传前自动执行)

buildtesttypecheck 脚本。类型检查和编译由微信开发者工具处理。

架构

  • 源码根目录src/(在 project.config.json 中设为 miniprogramRoot
  • 入口src/app.ts + src/app.json
  • 路径别名@/* 映射到 src/*(tsconfig paths + app.json resolveAlias)
  • 自定义 Page 包装器src/utils/page.tsapp.ts onLaunch 时全局替换 Page() — 注入 imageUrl/Timestamp/theme 数据、滚动导航栏变色、默认分享行为、handleMakePhoneCall。所有页面都经过此包装器。
  • HTTP 请求src/api/request.tswx.request 封装为 wx.ajax(通过 licia.curry 柯里化基础 URL)。所有 API 调用使用 wx.ajax(),而非 wx.request()。自动在 header 和 body 中注入 loginState
  • npm 包:由微信开发者工具构建到 src/miniprogram_npm/(packNpmManually 配置)。不要直接编辑 miniprogram_npm。

主题系统(DRUG / PATIENT)

用药患者(VIP,UserType >= 4)使用紫色 DRUG 主题,非用药患者使用绿色 PATIENT 主题。

  • app.getTheme():异步获取用户主题,返回 'DRUG''PATIENT'。内部轮询等待 userInfo 加载完成。
  • page.ts 全局注入:在 setImageParams 中为所有非医生端页面注入 data.theme,初始值 'PATIENT',异步通过 getTheme() 更新为 'DRUG'(如适用)。医生端页面不注入 theme
  • 页面根元素 id:所有患者端 WXML 页面根 <view> 添加 id="{{theme === 'DRUG' && 'drug-page'}}",用药患者时 id 为 drug-page,非用药患者时 id 为空。
  • CSS 覆盖方式:在 SCSS 中通过 #drug-page 选择器覆盖用药患者样式,无需修改原有绿色样式。

用药患者(DRUG)主题色值

类型 色值
文字色 rgba(89, 86, 233, 1)
按钮渐变 linear-gradient(270deg, #5956E9 0%, #B384F4 100%)
浅色背景 rgba(89, 86, 233, 0.1)

主题使用示例(SCSS)

.btn { background: #0eb66d; }
#drug-page .btn { background: linear-gradient(270deg, #5956E9 0%, #B384F4 100%); }

.text { color: #0eb66d; }
#drug-page .text { color: rgba(89, 86, 233, 1); }

主题使用示例(WXML)

<image src="{{imageUrl}}{{theme === 'DRUG' ? 'bg22' : 'bg15'}}.png?t={{Timestamp}}" />

登录与权限系统(app.ts)

  • 登录流程onShowstartLogin()wx.login 获取 code → 后端 init-login 返回 loginState
  • 用户等级UserType):
    • 1:空白用户 → 跳转登录页
    • 2:已注册用户 → 需完善资料
    • 3:已确诊患者 → 需上传认证
    • 4:已用药患者(VIP)→ 完整权限,使用 DRUG 主题
  • 路由守卫verifySys(pub) 检查登录状态和角色,自动重定向:
    • 未登录 + 医生端页面 → 医生登录页
    • 未登录 + 患者端页面 → 患者登录页(若 anyWhere 为 true 则"随便看看"模式)
    • 患者访问医生端页面 → 重定向到患者首页
    • 医生访问患者端页面 → 重定向到医生中转页
  • 权限校验permissionVerification(grade, registChannel, backPage, regBusinessId) 按等级拦截
  • 注册验证registrationVerification(callback, loginPage) 根据审核状态引导用户(AuditStatus: 0=无证书, 1=审核中, 2=已拒绝)
  • 关键全局变量loginState(令牌)、isLogin(0/1)、isRegloginType(1=患者, 2=医生)、anyWhere(免登录浏览模式)、first(首次启动标志)

数据监听机制

  • app.watch(key, method) — 通过 Object.defineProperty 监听 globalData 变化
  • app.registerListener(fn) / app.triggerListeners() — 全局事件监听模式(custom-tab-bar 等使用)
  • setWatcher(page)(来自 utils/watch.ts)— 页面级 watch 支持

自定义 TabBar(5 个 Tab)

Tab 页面路径 名称
1 /pages/index/index 首页
2 /pages/repository/index MG全知道
3 /pages/live/index 周三大咖说
4 /pages/story/index 向往的生活
5 /pages/my/index 我的
  • 患者端 TabBarsrc/custom-tab-bar/):使用 Vant van-tabbar 组件,额外包含"用药提醒"自定义按钮(item.custom=true),仅 theme === 'DRUG' 时展示
  • 医生端 TabBarsrc/doctor/components/tabbar/):自定义组件(非 Vant),纯 HTML/CSS 实现
  • Tab 4(向往的生活)在 anyWhere 为 true 时隐藏(浏览模式)
  • Tab 2(MG全知道)在 config.picTextEbookStatus === 1 时可能重定向到 webview
  • Tab 5(我的)需要 permissionVerification(grade=2)
  • 患者 TabBar 通过 app.registerListener 监听全局事件更新 theme

医患互动消息类型

互动页面(d_interactive/d_interactiveDoctor/interactivePatient)仅支持以下消息类型:

msgContentType 类型 说明
1 文本(患者发送) 患者发送的标准消息
2 出诊时间 医生出诊时间信息
5 欢迎语 欢迎引导消息
10 ADL ADL 评估相关消息
11 文本(患者) 患者文本消息
12 文本(医生自定义) 医生自定义文本回复

已移除的类型:audio(4)、info(6)、info(7)、referral(8)、referral-replay(9)。

HTTP 响应约定(api/request.ts)

  • 成功:code === 0 → 返回 data 字段
  • 错误且 showMsg=true(默认):显示 toast 错误提示
  • isJSON=true:返回完整响应(不仅仅是 data)
  • loading=true:显示/隐藏加载遮罩
  • 错误信息提取顺序:datamsgerrMsgdetail.errMsg → "未知错误"

分包

分包 路径 页面数 说明
主包 src/pages/ 55+ 患者端核心页面
gift src/gift/ 20 积分商城、健康档案、皮损记录
doctor src/doctor/ 22 医生端完整功能(含独立 tabbar 组件)
public src/public/ 3 知情同意流程
doc src/doc/ 2 文档页面
resource src/resource/ 0 独立分包(当前为空)

主包页面(src/pages/)

按功能分类:

  • 认证流程startloginvipLoginvipLoginRejectstartRejectstartPendinggetUserInfo
  • 注册enterInfouploadCertcertReslovecertPending
  • 首页index
  • 知识库repositoryrepositoryDetailrepositoryVideoDetail
  • 直播/会议liveliveDetailliveResultmyLive
  • 故事storystoryDetailstoryEnterstoryEnterResultstoryListstoryGuidepublishStoryDetail
  • ADL 评估adladlShareadlTestadlResult
  • 个人中心mymySavepersonalInformationchangePhonechangeUsercancellation
  • 家庭familyfamilyListfamilyScan
  • 医疗hospitaldoctordoctorDetaildrugRecordinfusionCenternrdlnrdlDetailnrdlTable
  • 互动interactivePatient
  • 其他thePublicprivacyAgreementtaskAgreementcomInssignInsmallPagewebviewreferraldemoqaForm

医生端分包页面(src/doctor/)

  • 认证d_login
  • 首页d_home
  • 患者管理d_patientd_patientDetaild_patientList
  • 任务d_taskListd_taskDetaild_createTask
  • 互动d_interactived_interactiveDoctor
  • 个人d_myd_userInfod_changePhoned_changeDoctor
  • 邀请d_invite
  • 导出d_exportListd_customExportd_customExportMiddle
  • 转诊d_transferd_transferLogd_transferDetail
  • 路由中转d_trans(医生访问患者端页面的中转页)

礼品分包页面(src/gift/)

  • 积分商城giftListgiftDetailconformOrder
  • 订单orderEndorderDetail
  • 地址siteListsiteEdit
  • 积分myGiftpriceDetailscoreRule
  • 健康档案myHealthRecordmyHealthRecordChart
  • VIPvipCertvipRejectvipPendingvipStartPending
  • DTPdtpDurg
  • 皮损cutaneouscutaneousDetailcutaneousVideo

全局组件(src/components/)

组件 说明
calendar 日历选择器
customPoster 自定义海报生成
customTable 自定义数据表格
ec-canvas ECharts 画布包装器
freeAudio 音频播放
loginNavbar 登录页导航栏
navBar 通用导航栏
pageNavbar 页面级导航栏
pagination 分页组件(在 app.json 中全局注册)
pickerArea 地区选择器
referralFrom 转诊来源选择器
star 星级评分
text-expandsion 文本展开/收起
timeOut 倒计时
toast 自定义弹窗提示
uploadFile 文件上传
viewFile 文件查看
viewVideo 视频播放器

医生端组件(src/doctor/components/)

组件 说明
tabbar 医生端自定义 TabBar(非 Vant,纯 HTML/CSS)

工具函数(src/utils/)

文件 说明
page.ts Page() 全局替换:注入 imageUrl/Timestamp/theme、滚动导航栏变色、默认分享、handleMakePhoneCall。医生端页面不注入 theme。
util.ts formatTime、formatNumber、getCurrentPageUrl、getCurrentPageUrlWithArgs、parseScene
promisify.ts 基于 Proxy 的 wx API Promise 化(同步方法保留,异步方法返回 Promise)
watch.ts 基于 Object.defineProperty 的页面级数据监听(setWatcher)
doctorPatientTask.ts 医生端患者筛选列定义(ADL、激素剂量、抗体类型等)
tools.wxs WXS 模板工具
dayjs/ dayjs 插件(中文 locale、relativeTime)

类型定义(typings/index.d.ts)

  • IAppOption — App 实例接口,包含 globalData 结构和方法签名(含 getTheme()
  • IAgaxParams — 扩展的请求选项,含 showMsgloadingisJSON
  • Response<T> — 通用 API 响应结构
  • globalSystemInfo — 扩展的系统信息,含胶囊按钮位置
  • WechatMiniprogram.Wx.ajax — wx.ajax 的类型增强

页面结构

每个页面是一个目录,包含 4 个文件:index.tsindex.wxmlindex.scssindex.json。组件遵循相同的 4 文件模式。

新增页面

  1. 在对应分包下创建目录(如 src/pages/myPage/
  2. 创建 4 个文件:index.tsindex.wxmlindex.scssindex.json
  3. src/app.json 中注册:
    • 主包页面 → pages 数组
    • 分包页面 → subpackages 中对应分包的 pages 数组
  4. 如页面使用组件,在页面的 index.jsonusingComponents 中注册
  5. 患者端页面:根 <view> 需添加 id="{{theme === 'DRUG' && 'drug-page'}}" 以支持 DRUG 主题覆盖

新增组件

  1. src/components/ 下创建目录(医生端在 src/doctor/components/
  2. 创建 4 个文件:index.tsindex.wxmlindex.scssindex.json
  3. 在页面的 index.json 中注册:"usingComponents": { "my-comp": "/components/myComp/index" }
  4. 全局注册则在 app.jsonusingComponents 中添加

关键约定

  • 品牌名称:项目品牌名"愈见昕生",不再使用"重症肌无力加油站"或"gMG给力加油站"
  • JSX/F2 图表:Babel 插件 @babel/plugin-transform-react-jsxjsxImportSource: "@antv/f2" — 页面中的 .jsx 文件使用 F2 图表语法,由 beforeCompile 脚本转译
  • 微信全局变量wxAppPageComponentgetCurrentPagesgetApp 已在 ESLint globals 中声明
  • CSS 单位:使用 rpx(微信响应式像素),布局中不用 px
  • 图片:存储在 src/images/,通过 SVN 部署(非 git,图片已 gitignore)。使用 dist.ps1/dist.sh/dist.nu 脚本部署
  • noImplicitAny: false — 允许隐式 any
  • removeComments: true(tsconfig)— 编译输出移除注释
  • Prettier:无分号、单引号、尾逗号、120 字符宽度;.wxml 按 HTML 解析,.wxss 按 CSS 解析,.wxs 按 babel 解析
  • API URL 格式:所有 API 调用使用 ?r=模块/动作 格式(如 ?r=zd/user/init-login?r=zd/account/info
  • 默认分享:患者端页面分享到 /pages/index/index,医生端页面分享到 /doctor/pages/d_home/index,标题:"愈见昕生,重拾生活掌控感!"
  • 客服电话:全局 handleMakePhoneCall 拨打 4008102299
  • 医生端页面禁止调用 getTheme()getTheme() 仅在 page.ts 和患者端组件(如 custom-tab-bar)中使用
  • 患者端页面禁止重复调用 getTheme()page.ts 已全局注入 theme,页面中无需再次调用

环境 / 部署

  • 开发环境 API:https://m.igg4.hbraas.com(在 app.ts globalData 中硬编码)
  • 生产环境 API:https://m.igg4.hbsaas.com(已注释,部署时切换)
  • 上传 URL 与 API 同域名,末尾加 /
  • 图片 URL:{domain}/igg4/
  • 开发 AppID:wxc3cdb3c4d4f62cea,生产 AppID:wx96f45ca4f1fa36ec
  • 微信开发者工具负责编译、npm 构建、预览和上传
  • project.private.config.json 本地覆盖 project.config.json
  • 切换环境:取消 app.ts globalData 中生产 URL 的注释 + 修改 project.config.json 中的 appid
  • 图片通过 project.config.json 中的 packOptions.ignore 排除上传