Files
SkyJourneyandClaude Opus 4.6 c8a18c9ec3 切换到 pnpm 工作流,补齐 .gitignore 与 vendor 拆分
- 根目录、zhican/、miniprogram/ 三层 .gitignore 就位
- 删除 package-lock.json,仓库统一追踪 pnpm-lock.yaml
- vite.config.ts 拆出 vue-vendor(vue/vue-router/pinia);
  ant-design-vue 体积~1MB,继续按路由 code-split,不入 manualChunks
- 新增根 CLAUDE.md 记录仓库结构、常用命令、antd 类型陷阱、
  构建门禁、vendor 拆分策略等

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 17:25:26 +08:00

9.2 KiB
Raw Permalink Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

仓库结构

这是一个多端单仓项目,git 根目录下包含:

  • tcm-diagnosis.html — 独立的中医诊断单页 HTML(与下面项目无依赖关系)
  • zhican/ — 智能餐养系统主项目,使用 npm workspaces 管理
    • admin/ — Vue 3 + Vite + TypeScript 后台管理端(workspace 成员)
    • miniprogram/ — 原生微信小程序(无构建步骤,由微信开发者工具直接打开 project.config.json

注意:执行 npm 脚本前必须先 cd zhican/,根目录没有 package.json

常用命令

包管理器统一使用 pnpmpackage-lock.json 已被 .gitignore,禁止提交 npm/yarn 锁文件。仓库追踪的锁文件是 zhican/admin/pnpm-lock.yaml

进入 zhican/admin/ 目录执行(推荐):

pnpm install               # 安装依赖
pnpm run dev               # 启动开发服务器(vite,端口 3000)
pnpm run build             # 类型检查 + 构建(vue-tsc --noEmit && vite build),产物在 dist/
pnpm run preview           # 本地预览构建产物

也可在 zhican/ 根目录用 workspace 命令 pnpm run admin:dev / admin:build

由于 zhican/package.json 用的是 npm workspaces 字段而非 pnpm-workspace.yaml,跨 workspace 命令的稳定性不如直接进 admin 子目录。一般操作建议进 zhican/admin/

小程序端无构建步骤,使用微信开发者工具导入 zhican/miniprogram/ 目录调试。

部署形态(H5 构建能力)

  • admin:标准 Vite 项目,npm run admin:build 输出 admin/dist/index.html + 静态 chunk),可直接部署到任意静态服务器/Nginx/对象存储
  • miniprogram原生微信小程序,无法直接构建为 H5。它使用 .wxml / .wxss / wx.* API 和 app.json tabBar,运行时绑定在微信宿主上。要得到浏览器可访问的 H5 版本必须迁移到 uni-app / Taro 等跨端框架重写,不是"加个构建脚本"就能完成
  • tcm-diagnosis.html:单文件 HTML,无构建,直接打开或托管即可

admin 后台架构

技术栈:Vue 3 (<script setup>) + Vite 6 + TypeScript + Pinia + vue-router 4 + Ant Design Vue 4。

自动导入与按需组件

vite.config.ts 配置了两个 unplugin

  • unplugin-auto-import:自动注入 vue / vue-router / pinia 的 APIrefuseRouterdefineStore 等无需手动 import),类型声明写入 src/auto-imports.d.ts
  • unplugin-vue-components + AntDesignVueResolver:按需注册 ant-design-vue 组件,类型声明写入 src/components.d.tsimportStyle: false,依赖 antd 自带样式)

新增第三方库的全局 API 时需要在 vite.config.tsimports 数组里登记,否则 TS 会报未定义。

路径与代理

  • 别名 @src(在 vite.config.tstsconfig.json 同步配置)
  • dev server 代理 /apihttp://localhost:8080,所以前端请求都写相对路径
  • vendor 拆分build.rollupOptions.output.manualChunks 仅把 vue 全家桶(vue/vue-router/pinia)单独打包成 vue-vendor,其余依赖(尤其是 ant-design-vue)维持按路由代码分割。不要把 ant-design-vue 写进 manualChunks——它体积约 1MB,强行单 chunk 会拖累首屏;按路由懒加载更优

路由组织(关键)

src/router/index.ts 采用扁平注册:所有业务页平铺在 modules 数组里,按注释分为 5 大业务域:

  • 数据概览(dashboard / business-flow
  • 绿色种采(land-env、planting-monitor、harvest-storage、supplier-mgmt、procurement-mgmt
  • 卫生供应(hygiene-test、raw-storage、clean-process、clean-storage、clean-internal、clean-external
  • 健康生产(food-safety、recipe-plan、clean-order、clean-cabinet、clean-assemble、cook-by-order、serving-monitor、surplus-disposal、production-stats
  • 营养用餐(nutrition-test、food-composition、dish-inventory、algorithm-standard、recipe-mgmt、nutrition-order、user-mgmt、meal-line、pickup-mgmt、consumption-mgmt、nutrition-mgmt、ingredient-benefit、terminal-mgmt、model-mgmt、flavor-innovation
  • 系统管理(org-structure、employee-mgmt、role-mgmt、canteen-mgmt

所有业务页都是 MainLayout.vue 的子路由,路径无前缀(/dashboard 而非 /green-planting/land-env)。每条路由通过 meta.menuKey 与侧边栏菜单联动,meta.title 用于 document.title

新增页面流程

  1. src/views/<业务域>/<功能>/index.vue 创建组件
  2. src/router/index.tsmodules 数组中追加一行(保持按业务域注释分组)
  3. 同步在 MainLayout.vue 的菜单结构里加入对应 menuKey

路由守卫与登录

router.beforeEach 检查 localStorage.token,未登录访问非 login 页则重定向到 /login。token 由 src/stores/user.ts 管理。

数据来源现状(重要)

当前项目是纯交互原型,没有任何真实后端调用。各 view 全部使用 src/mock/data.ts 的静态数据驱动界面。原本预留的 src/utils/request.tsaxios 封装)和 src/api/index.ts(业务 API 聚合)已经清除——它们当时未被任何 view 引用,属于无主死代码。

登录流程也是原型:router.beforeEach 只检查 localStorage.token 是否存在,没有真正的鉴权请求。

未来对接后端时:建议沿用以下契约(这是被删除的脚手架原本约定的,可作为参考):

  • 统一 axios 封装放 src/utils/request.tsbaseURL /api(配合 vite server.proxylocalhost:8080),自动注入 Bearer token
  • 响应拦截器统一解包后端格式 { code, msg, data }code === 0 时直接返回 data,否则 message.error(msg) 并 rejectHTTP 401 清 token + 跳 /login
  • API 按业务域聚合到 src/api/<域>.tsview 里 import { xxxApi } from '@/api/...'不要在 view 里直接 import request,也不要.data.data 解包(拦截器已经解一次)

antd-vue 4.x 类型陷阱(踩坑警示)

vue-tsc 在严格模式下与 antd-vue 4.x 有几个高频冲突,新增页面时请提前避开:

  1. a-tablecolumns 必须显式注解fixed: 'left' | 'right' 字面量字段不加类型会被推为宽 string 类型,匹配不上 antd 的 FixedType。规范写法:

    import type { ColumnsType } from 'ant-design-vue/es/table'
    const columns: ColumnsType<any> = [ /* ... */ ]
    
  2. a-treetree-data 即使配了 field-names 映射,静态类型也仍然要求 DataNode 形状(必须有 key。这是 antd-vue 类型限制,运行时 fieldNames 是有效的。已采用的解法:在绑定处加 as any 断言(:tree-data="(myData as any)"),不要去污染数据结构

  3. a-tree@select 回调签名(keys: Key[], info) => void,其中 Key = string | number。若声明 (keys: string[]) => void 会编译失败,需要 Array<string | number> 并按需 String(keys[0])

  4. a-range-picker / a-date-pickerv-model 不要用 null 初值。antd 类型是 [Dayjs, Dayjs] | undefined 而非 | null,写 ref<...>(null) 会编译失败。规范写法:const dateRange = ref<[Dayjs, Dayjs]>(),表单字段用 entryDate: undefined as Dayjs | undefined

  5. a-progressformat 回调参数是 percent?: number,必须接受 undefined。写 (p: number) => ... 会失败,应写 (p?: number) => (p ?? 0) + '...'

构建质量门禁

  • vue-tsc --noEmit 是构建管线的硬性步骤pnpm run build 会在 vite build 之前先跑),这意味着任何类型错误都会阻止构建。新增/修改代码后请本地跑一遍构建确认
  • git 钩子:仓库根目录配置了 .githooks/pre-commit,当本次暂存的文件涉及 zhican/admin/ 时自动运行 pnpm run build首次 clone 仓库后需要手动启用一次
    cd <repo-root> && git config core.hooksPath .githooks
    
    钩子若检测不到 pnpm 会跳过(不阻塞提交),但会在 stderr 提醒。Windows 用户需用 Git Bash 或确保 bash 可用

自动生成的类型声明(不要提交)

src/auto-imports.d.tssrc/components.d.ts 由 unplugin 在 dev/build 时重新生成,已加入 .gitignore。它们会随业务代码变化频繁更新,提交进 git 会反复制造无意义 diff 和合并冲突。如果发现这两个文件被意外提交,使用 git rm --cached 移除追踪。

miniprogram 小程序

原生微信小程序结构(无构建链)。app.json 定义 4 个 tabBar 页面:吃 (eat) / 问 (ask) / 做 (cook) / 我 (profile),对应 pages/<name>/index.{js,wxml,wxss,json}

小程序端目前也是纯交互原型,无任何真实接口调用。原本预留的 utils/request.js 同样属于无主死代码已清除。

业务上下文

「智能餐养系统」覆盖从种植采购到用餐消费的全链路:绿色种采 → 卫生供应(净菜加工) → 健康生产(按单烹制) → 营养用餐(点餐、取餐、营养分析)。理解某个页面的职责时优先按这条业务流向上下游追溯。