管理端(web)
web/ 是医馆日常运转的主工作台:Ant Design Pro + Umi(@umijs/max)工程,Node.js 24 / pnpm,中文界面。
已实装界面截图(数据为虚构演示,石墨×古金主题取自品牌 logo,另有松烟绿 / 朱砂 / 黛蓝三套可切换主题色):

更多分页原型(接诊诊疗单 / 每日报表 / 卡项 / 订单 / 广告屏 / 外观设置)见文档站首页产品预览与仓库 docs/design/mockups/。
运行方式
cd web
pnpm install
pnpm dev # dev 模式:MOCK=none,代理到本机服务端- 开发地址
http://localhost:8000,/api代理到http://127.0.0.1:2347(config/proxy.ts)。 pnpm build产出dist/,交由 Nginx 托管;pnpm lint代码检查、pnpm jest单测。
工程结构
| 位置 | 内容 |
|---|---|
config/config.ts | 站点标题、布局(side)、国际化(zh-CN 默认)、插件与 openAPI 配置 |
config/routes.ts | 路由表(页面注册) |
config/proxy.ts | dev / test / pre 环境代理 |
src/pages/ | 页面组件,按业务域分目录 |
src/services/ant-design-pro/ | 接口定义(与服务端 /api/v1/** 一一对应) |
src/access.ts | 运行时权限:canAdmin(管理层)、canUser(已登录) |
src/app.tsx | 启动时拉取当前用户、未登录重定向 |
src/requestErrorConfig.ts | 从 localStorage.jwt 注入 Authorization: Bearer,统一错误提示;401 清凭证并跳转 /user/login(登录请求自身豁免,不回环) |
src/locales/ | 菜单等文案多语言 |
页面与任务对照
登录后默认落地 每日报表(/dash/day)。医馆主流程沿「顾客建档 → 接诊(诊断) → 卡项 → 复盘回访」展开,按任务找页面:
预约系统(/appointment)
主流程「预约 → 到店接待 → 发起接诊」的第一环。列表工作台 + 按日时段网格两种视图(对齐 docs/design/mockups/admin-booking.html)。
| 路径 | 页面 | 做什么 |
|---|---|---|
/appointment/schedule | 排班视图 | 按日看医师×时段占用(9:00–18:00 整点网格,列按医师名册(staffs.title 职务语义:在职且职务含「医师」;名册空回退当日有约;名册按名医等级降序 famousLevel 高者在前、同等级按创建时间升序,接口 GET /api/v1/staff/page)并班表联动——当日(staff_shifts 按星期)在班医师列在前、无班次名册医师列头弱化标注「今日无班次」):空格虚线「可预约」,有约显示顾客/项目与状态标(待到店/已到店/过号/已取消),待到店格内一键「接待」(0→1);右栏「今日预约」四格统计(总数/已到店/待到店/过号)+「待到店」列表(时段·顾客·项目·医师 + 接待)+「小程序联动」规划说明,日期前后翻页与「今天」;格位与待到店行带就诊标记:疗程卡标记优先(同项目第 N 张卡按购入先后=第 N 疗程,GET /card/customers 按顾客批量拉齐);无卡项按就诊记录标复诊/首诊(GET /treat/visited?ids= 批量查 treats 聚合计数,有记录=复诊、无=首诊;treats 无项目维度,按顾客口径) |
/appointment/query | 预约排班 | 今日/全部切换 + 状态 tab(待到店/已接待/过号/已取消带计数);行操作:到店接待(0→1)、过号(0→8)、取消(0→9)、已接待后「发起接诊」跳 /treat/create?customerId=、已取消可删 |
/appointment/create | 新建预约 | 按手机号定位顾客(未建档提示先建档)→ 时段(日期时间 + 时长 30/60/90 分钟)→ 项目/员工/备注选填;提交发带时区偏移的时间串(服务端 Jackson 默认 UTC,无偏移会平移 8 小时) |
排班口径:同一时段不冲突校验(演示边界),一格落多条时取第一条并标 +N;时段网格只覆盖 9:00–18:00 整点,非整点开始的预约会归到所在小时格。
顾客系统(/customer)
| 路径 | 页面 | 做什么 |
|---|---|---|
/customer/create | 顾客建案 | 建档:姓名/年龄/性别/手机/住址/会员等级/生日 |
/customer/query | 顾客查询 | 分页检索顾客,行操作:创建诊断、更新、诊断历史、回访计划、删除 |
/customer/update | 顾客档案 | 回填顾客信息并保存;头卡显示建档月份与最近到店;病史栏逐条记录过敏史/既往史(过敏/既往切换 + 内容 ≤200 字,可删除);持卡栏显示每张次卡「已用 X/N 次」进度与「购入日期 · 有效期至」(发卡可选有效期,空=长期有效),可发卡/停用/恢复,「核销记录」弹层按次列出(第几次/时间/服务员工/订单号,历史补录无单号);有效卡可「加次」(1-99 次 + 理由 ≤100 字)与「转卡」(搜索目标顾客、手机号打码、排除本卡顾客),「调整记录」弹层留痕(赠次/转卡、理由、操作人、转入顾客名) |
诊断系统(/treat)
| 路径 | 页面 | 做什么 |
|---|---|---|
/treat/create | 创建诊断 | 诊疗单大表单:主诉、问/望/切、脉象(左右手 寸/关/尺分部 三格 ×2 + 总述与补充)、五行(五行生克定位图:火心/木肝/土脾/金肺/水肾五节点,中宫脾高亮 + 本/克/难经/缓急四指标随录入联动)、取穴(按穴位字典选穴追加,仍可自由写)、针灸处方(针法/灸法/留针分钟/手法/疗程频次 + 「套用外治模板」一键带出方法/取穴/疗程建议,回填后随单自由改)、诊断、方案、饮食、调理;支持 ?customerId= 预载、?treatId= 复诊回填;接诊医师署名(选填 staffId 随单落库,服务端按 staffs 回显 staffName,近三次诊疗/顾客档案时间线按署名医师显示、未署名如实标注「未署名」);顾客条持卡余次显示实卡数据(无卡如实标注)并带疗程标记(同项目第 N 张卡=第 N 疗程,无卡项不标)、今日接诊计数真实;「收款去向」卡内链收费结算台(按订单计应收+小票打印,本页不做开单试算),开单表项目行为规划域预留(无假按钮),打印/扫码计数无埋点数据源标注规划;页顶外设状态条显示扫码枪/80mm 小票机/处方笺打印机连接态——桌面工作站壳内经 peripheral_status 命令取真实状态(30 秒轮询+扫码事件即时刷新),浏览器端如实标注「需桌面工作站」,查询不到不伪造(见 desktop D10) |
/treat/query | 模糊查询 | 按 id / 姓名 / 年龄 / 手机号检索诊断单 |
/treat/acupoints | 穴位字典 | 经络穴位参考库维护页:收录/编辑/删除,穴名唯一;按穴名或拼音码检索(如「足三」/「zusanli」);接诊页「取穴」检索选中即追加进取穴文本 |
/treat/history | 诊断历史 | 某顾客的历史诊疗记录(按时间倒序) |
创建诊断页已实装界面截图(四诊、脉象、取穴、五行生克、调理方案):

卡项系统(/item)
| 路径 | 页面 | 做什么 |
|---|---|---|
/item/create | 创建卡项 | 名称 / 价格 / 时长(分钟,选填,展示用)/ 描述,支持 ?itemId= 回填(编辑复用此页,带 id 提交走 PUT /api/v1/item/ 真实更新,不带 id 新建) |
/item/query | 卡项查询 | 分页检索与删除,编辑操作跳转 /item/create?itemId= 回填 |
反馈系统(/review)——复盘与回访
| 路径 | 页面 | 做什么 |
|---|---|---|
/review/day | 每日总结 | 填写 / 查看当天做得好的与待改进 |
/review/staff | 员工总结 | 批量维护员工日复盘 |
/review/customer | 顾客反馈 | 批量维护顾客回访记录 |
/review/plan | 回访计划 | 为顾客设定回访日、最近到店与回访原因(存回访记录 advice;档案页据此显示下次回访与回访提醒) |
报表系统(/dash)
| 路径 | 页面 | 做什么 |
|---|---|---|
/dash/day | 每日报表 | 默认首页:员工总结表、今日回访、今日总结三块拼版 |
/dash/month | 月度收费报表 | 月份选择器 + 当月实收/结算单数/次卡核销三统计卡 + 近 6 月趋势双柱图(实收墨柱/接诊淡柱,逐月标注「N 诊 / N 单」,当月高亮)+ 支付方式构成 + 逐日明细(单数/实收);数据来自收费结算,次卡核销实收 0 单列 |
诊所运营(/staff,员工与考勤)
员工账号维护、上 / 下班签到与考勤统计,属诊所运营辅助:
| 路径 | 页面 | 做什么 | 权限 |
|---|---|---|---|
/staff/create | 创建员工 | 新建员工账号(含职务 title,自由文本;排班页医师名册=在职且职务含「医师」;名医等级 famousLevel 0 普通 / 1-3 名医,仅影响列表排序与标识徽章) | 仅 canAdmin |
/staff/query | 员工查询 | 分页检索(列含名医等级,0 普通 / 一级·二级·三级名医徽章)与删除员工 | 仅 canAdmin |
/staff/update | 员工更新 | 回填并保存(含职务 title、名医等级 famousLevel) | - |
/staff/sign、/staff/sign/timesheet/today、/staff/timesheet/list | 签到 / 今日考勤 / 考勤列表 | 上 / 下班打卡、本人今日时长、按月全员考勤矩阵 | 已登录 / - |
/staff/leave | 员工请假 | 左侧登记表单(员工选择/类型 病假·事假/起止时间/事由)+ 右侧近期请假记录(可删除);接口 POST /api/v1/staff/leave/,记录口径不改登录状态、无审批流 | 已登录 |
/staff/shifts | 员工班表 | 周期班表周矩阵(行=员工、列=周一~周日,格内 HH:mm–HH:mm 班次);「加排班」弹层选员工/星期/时段(30 分钟步进,下班须晚于上班),点击时段调整、✕ 删除;同员工同星期仅一条班次,考勤打卡仍以签到记录为准;接口 /api/v1/shift | 仅 canAdmin |
/staff/timesheet/week | 周班次对照 | 员工 × 7 天(周一至周日):「应」= 班表计划、「实」= 当日打卡(最早上班/最晚下班、整小时);选日期看所在周,「本周」一键回当前;接口 /api/v1/staff/timesheet/week | 仅 canAdmin |
订单系统(/order)
| 路径 | 页面 | 做什么 |
|---|---|---|
/order/create | 前台下单 | 按手机号定位顾客 → 多选卡项(每行可改数量,价格取卡项现价快照,多行合计落单)与建单人(选填)→ 下单落「待接待」;适用于到店临时加项 |
/order/query | 订单管理 | 顾客 Kiosk 下的单与前台建的单在这里接待:接单 → 完成,未接待可取消;删除仅限已取消的单;已完成/已取消可「查看」详情(明细行 单价/数量/小计、合计、整单备注、支付方式、下单时间、来源);业务单号 YYYYMMDD-NNN,列表新单在前 |
订单来自门店自助机(kiosk)或前台建单,前台在此接单;不做在线支付,到店结算。
已实装界面截图(订单管理):

收费结算(/billing)
自助机/前台单据的收款环节(对齐 docs/design/mockups/admin-billing.html 的结算台形态)。
| 路径 | 页面 | 做什么 |
|---|---|---|
/billing/settle | 结算台 | 左侧待结算队列(订单状态 0/1,自助机/前台 来源标签,业务单号 YYYYMMDD-NNN,项目「名 ×数量」串)+ 最近结算记录(每条可补打小票、可退单:理由必填 ≤100 字弹窗单向确认,已退款示标记;订单退款后回队列可重收);选单后展示结算明细多行表(项目/数量/小计,多品项订单联 order_item 明细)与整单备注(琥珀备忘块,≤200 字失焦保存);选支付方式收款:储值卡(显示实时余额,余额不足可填额充值后一并收款)、微信、支付宝(选中出示商户收款码供顾客扫码,缺码 404 如实提示未配置)、现金、次卡(显示本单卡项有效余次,选中即扣 1 次、实收记 0,明细表追加「卡项抵扣 ¥0」行);收款成功订单转「已完成」并落结算单 |
/billing/reconciliation | 日对账 | 按自然日对账:日期选择(默认今天,禁选未来)+ 统计卡(实收/退款/净额/现金净额/充值单列)+ 收款构成表 + 充值、退款两张明细表(联顾客/操作人名,退款行带理由与原支付方式);接口 /api/v1/settlement/reconciliation |
结算口径:实收取订单价格快照(多品项单为各行小计合计,order_item 存名称/单价快照),储值支付自动扣减余额(流水合计);次卡抵扣扣持卡余 1 次、实收记 0,并在同一事务落核销流水(顾客档案持卡栏可查);微信/支付宝为到店扫码收款:结算台出示商户收款码(/api/v1/pay-qrcode/{method} 出图,缺图 404 如实提示未配置、可扫台卡纸质码过渡),顾客扫码支付在系统外完成,系统只按所选方式记账(不接支付网关,到账以商户账单为准);小票走服务端套打 GET /api/v1/print/receipt/{settlementId}(80mm HTML,收款成功后可打印、最近结算可补打);处方饮片行进结算裁定不做——收费以卡项订单结算为准,处方计价为试算/提示口径。退单原路退回(储值补回余额、次卡回补次数、现金当面退回),日对账页 /billing/reconciliation 按自然日三段核对。
已实装界面截图(收费结算台:储值/充值与次卡抵扣已实装;原型里的处方饮片行进结算裁定不做):

处方系统(/prescription)
| 路径 | 页面 | 做什么 |
|---|---|---|
/prescription/create | 开方 | 处方笺头(顾客 性别·年龄·掩码手机 / 医师·日期·诊号=接诊单 / 处方编号预览 Rx-YYYYMMDD-编号,编号开方后生成)→ 按手机号定位顾客 → 带出最近接诊单的辨证摘要条(辨证=接诊单诊断、治法/方案=接诊单方案,可切换接诊单,随处方落 treatId;无接诊单显示建档提示)→ 「套用模板」按病症一键带出药味/剂数/用法(可选)、「方剂库」按方名/拼音带出全方 → 写药味(药名/克数/炮制/煎法,可增删行)+ 「从饮片目录添加」下拉(中文名或拼音首字母检索如 zz/fs/gcao,选中填入空行或追加行,选项带每克单价;pinyin-pro 本地计算+缓存)+ 特殊煎法提醒(扫药味煎法备注命中 先煎/后下/包煎/烊化/冲服/另煎 计「N 味需标注」)+ 剂量上限提示(POST /api/v1/prescription/dose-check 防抖 500ms:药味单剂克数严格大于该药材 dose_max 即提示、等值不提示,不拦截由医师判断;上限由诊所自录——药典权威量属医学参考数据仓内不硬编码,同库存上下限口径)+ 类型(汤剂/膏方,膏方选收膏方式)+ 用法三格(剂数/煎法/服法)+ 备注 + 签名行(选填开方医师 / 药师审核 / 调配复核);勾「代煎 N 袋」出领取方式(自取 / 同城配送运费 ¥6.00,运费仍为提示口径)与取药窗口提示(今日 17:00 前可取,加急 2 小时);计价面板按原型三行账:饮片 N 味 × 付数 + 代煎服务(¥3/袋,2026-10-12 拍板入应收合计)→ 应收=两者之和,实际收费仍以卡项订单结算为准;底部三键:存方并收费(提交)· 存入我的方剂库(当前方随病症名存为启用模板)· 打印处方笺(只出处方笺主卡) |
/prescription/query | 处方查询 | 已开处方笺一览(顾客/医师/药味/剂数/类型/代煎/膏方状态/煎法服法/开方时间/实时计价),「详情」抽屉看整方药味(炮制/煎法列)与计价明细、煎法/服法分列、代煎与膏方各自流转领取、发药状态与快捷确认发药(带备注走药房工作台),可删除 |
/prescription/dispensary | 药房工作台 | 待发药/已发药/全部三态切换带计数 + 顾客姓名/手机检索;列表=处方号/顾客(姓名+脱敏手机)/类型/剂数/药味数/代煎/膏方/发药状态与时间/开方时间;行操作「发药」弹窗带可选备注(≤100 字)单向确认,已发药行只读;代煎/膏方「已取」领取自动发药无需重复点;接口 /api/v1/prescription/dispense/page |
/prescription/templates | 病症模板 | 病症处方模板库维护页:新建/编辑(药味行内增删)/删除/上架开关,病症名唯一;模板只存建议值,套用后随处方自由增减不写回 |
/prescription/therapy-templates | 外治模板 | 外治处方模板库维护页:新建/编辑/删除/上架开关,模板名唯一(1–20 字)+ 外治方法(≤10 字,如 耳穴压豆/穴位贴敷/艾灸/拔罐)+ 建议取穴部位/疗程频次/注意事项;接诊页「套用外治模板」下拉(仅上架模板)回填针法/疗程与取穴文本,回填后随单自由改不写回模板;接口 /api/v1/therapy-template |
/prescription/formulas | 方剂库 | 经典方剂参考库维护页:收录/编辑(药味行内增删)/删除,方名唯一;按方名或拼音码检索(如「逍遥」/「xiaoyao」);药味克数为文献常用量口径,开方页带出后随处方自由增减不写回 |
/prescription/herbs | 药材字典 | 处方计价比价依据的维护页:收录/改价/删除,名称唯一精确匹配,价格为每克分价(页内以元展示);可维护库存上下限(stockMin/stockMax 克,可空=不预警)与单剂上限(doseMax 克/剂,可空=不预警,开方页剂量校验依据) |
/prescription/herb-stock | 饮片库存 | 库存余额看板(克 + 最早未消耗批次效期 + 到期预警,阈值 30/60/90 天可切 + 库存线预警列:低于下限/高于上限)+ 出入库登记(药材/类型/数量/效期/供货方/备注,出库不填效期)+ 流水分页可删除;库存=入合计-出合计,出库按效期 FEFO 消耗;接口 /api/v1/herb-stock |
药材名为自由文本;配伍审方(十八反/十九畏)、过敏提示与实时计价已实装——开方页随写随查(审方提示不拦截;定位顾客后按其过敏史原文比对药味,命中时列出 药味 + 记录原文,无命中不占位;计价按药材字典精确同名比价、未收录药名不计费);代煎已实装——开方页勾选「代煎 N 袋」(袋数=剂数,服务费 ¥3/袋 仅提示,可再选领取方式 自取/同城配送随方存档),查询页列表出代煎状态、详情抽屉流转领取(待煎→可取→已取);膏方已实装——开方页类型选「膏方」并选收膏方式(炼蜜/清膏/糖膏/阿胶收膏,可清空),开方落「待制作」(膏方按料计不勾代煎),查询页列表出膏方状态、详情抽屉流转(待制作→可取→已取);病症模板已实装——开方页「套用模板」下拉(仅上架模板),带出后一切可改,另可「存入我的方剂库」把当前方随病症名存为启用模板;方剂库已实装——开方页「方剂库」下拉按方名/拼音检索一键带出全方(药味带出、剂数不变),带出后一切可改。
已实装界面截图(中药处方笺:开方/查询/配伍审方/过敏提示/实时计价/代煎与膏方领取/辨证摘要联动):

广告屏系统(/ads)
候诊区展示屏(tablet)的素材、排期、屏幕注册与叫号记录管理:
| 路径 | 页面 | 做什么 |
|---|---|---|
/ads/materials | 素材管理 | 广告素材(视频 / 图片)上传、分类子标题(如「门店活动」,选填)、启用停用、排序;叠加层文案四项(眉题 / 大标题 / 文案 / 价格行,均可空,全空即纯素材播放),随 playlist 下发平板排版层(原型 tablet-screen 整版设计的适配版:媒体铺满舞台、文案左下渐变底叠加) |
/ads/schedules | 排期管理 | 排期名(选填)+ 素材按星期与时间段排到屏幕 |
/ads/screens | 屏幕管理 | Kiosk 屏注册、在线状态(正在播 排期名 + 轮播条数)、绑定排期 |
/ads/calls | 叫号操作 | 前台叫号后,定向屏(或全部屏)在 3 秒内全屏提示号码与诊室;预约接待(0→1)会自动叫号(服务端联动,最近叫号列表可见,散客仍手动叫) |
已实装界面截图(素材管理 + 屏幕状态 + 快捷叫号):

外观设置(/appearance)
站点主题与品牌呈现(设计稿见文档站首页「主题切换」):
| 路径 | 页面 | 做什么 |
|---|---|---|
/appearance | 外观设置 | 四套主题色即点即换:石墨×古金(默认,取自品牌 logo)/ 松烟绿 / 朱砂 / 黛蓝;选择即时生效并记忆,全站 tokens.css 变量组切换 |
公众号(/wx)
| 路径 | 页面 | 做什么 |
|---|---|---|
/wx | 公众号工作台 | 五个 tab(行为口径见公众号设计稿与 wx 接口组):公众号账号 账号列表 + 仅 ADMIN 的新建/编辑(密钥回显有存量掩码 ****、无存量 null;编辑留空=保持既有值;写入需 WX_OA_CREDENTIAL_KEY);自动回复规则 subscribe/keyword/fallback 规则与匹配方式、优先级(每账号同时至多一条启用的 subscribe/fallback);自定义菜单 两级草稿菜单,名称/结构校验 + 推送到微信按钮(真实出网凭据门控);消息流水 方向/结果过滤 + 已绑定顾客姓名;素材台账 只读台账 + 图片预览(上传/删除仅在 API 层,页面未建)。规则/菜单/粉丝相关页的账号下拉来自账号列表,能力受限的操作按能力矩阵(GET /wx/capabilities/{accountId})显隐;路由本身以 canAdmin(MANAGER+)门禁 |
未登录入口:/user/login 登录页(账号密码登录,登录后按角色落对应首页;无注册入口——账号由管理员创建,见 api 鉴权约定)。
权限与角色
canAdmin:管理层——/api/v1/user/current返回的currentUser.access在服务端role < 10时即为admin(StaffEntity.getAccess():ADMIN + MANAGER),员工管理页与/wx都用它门禁;员工管理写接口仍仅 ADMIN(role == 0,@PreAuthorize),MANAGER 能进员工管理页但写入得 403;canUser:签到与今日考勤入口(任何已登录员工);- 服务端方法级权限已强制:员工管理写接口(
POST/PUT/DELETE/api/v1/staff)加@PreAuthorize("hasRole('ADMIN')"),与页面级canAdmin同口径;服务端角色映射role 0 → ADMIN、1-9 管理层 → MANAGER、≥10 普通员工 → USER(StaffEntity.getAuthorities),越权写返回 403(ResponseExceptionAdvice 对 AccessDeniedException 出 403,不落 500;回归 StaffPermissionHttpTest)。其余业务接口仍为登录即可用(未按方法分权)。
前端遗留项(如实说明)
- 品牌口径已定(2026-10-12 拍板):站点品牌即「Youngs 医馆」——logo 养字标 + 全部界面原型 + youngs.fun 自有域名共同证实,非脚手架残留;登录页标题、Footer 文案、
src/manifest.json品牌值已统一到此口径(Footer 保留 youngs.fun 业务链接;PWA manifest 尚未接线——config 无引用、不进构建产物,品牌值已就位备接线); config/oneapi.json仍为脚手架模板 schema(含/api/rule等模板端点),保留备查——pro 插件预置的 openAPI 代码生成 + requestRecord 录制已移除(其依赖链携带无补丁版本的 mockjs),src/services/ant-design-pro/服务层手写维护。
已清理:脚手架残留页面
src/pages/Welcome.tsx、Admin.tsx、TableList/(不在路由,无引用);petstore 示例服务src/services/swagger/(config.tsopenAPI 第二入口一并移除);卡项占位页/item/spread、/item/update(表单实为createItem建新卡项的误用隐患,已连同路由移除,编辑统一走/item/create?itemId=,2026-10-12 起带 id 提交走updateItemPUT 真实更新;spread「扩散」在原型 admin-items.html 无对应设计,按脚手架残留裁定不补)。