131 lines
18 KiB
Markdown
131 lines
18 KiB
Markdown
# Admin Web Instructions
|
|
|
|
## 项目定位
|
|
|
|
- 本项目是虫虫出海内部运营与管理后台,仅服务平台员工。
|
|
- 当前范围包括工作台、客户管理、头程订单、仓储与国内出仓协同、财务管理、内部用户、角色管理和菜单权限。
|
|
- 不在本项目承载企业客户自助流程、品牌官网、微信小程序、独立 APP 或仓库 PDA 作业。
|
|
|
|
## 技术基线
|
|
|
|
- 使用 Vue 3、TypeScript、Vite、Vue Router、Pinia、Element Plus、Axios 和 Lucide Vue。
|
|
- TypeScript 保持严格模式;不要使用 `any` 绕过业务模型,优先从 `@chongchong/shared` 复用跨项目类型。
|
|
- 使用现有 `@` 别名引用 `src/`。保持 ES Module 和现有无分号代码风格。
|
|
- Element Plus 组件使用现有自动导入配置;`ref`、`computed` 等 Vue API 必须显式导入。`src/auto-imports.d.ts` 与 `src/components.d.ts` 属于生成声明,不手工维护业务内容。
|
|
- 不更换框架、路由、状态管理、组件库或构建工具,除非任务明确要求并完成影响评估。
|
|
|
|
## 目录与职责
|
|
|
|
- `src/app/`:应用装配层,包含布局、根路由、全局守卫和启动入口;不承载具体业务或被业务模块反向依赖。
|
|
- `src/core/`:认证会话、访问控制、导航配置、未保存工作保护和路由安全工具等全应用基础能力;可以被 `app` 和业务模块使用,但不得依赖业务模块。
|
|
- `src/modules/`:按客户、仓库、头程订单、主数据、下载中心、IAM 等稳定业务领域组织页面、API、类型、组件和路由。新增业务页面必须进入对应模块,不再建立根级 `views/`。
|
|
- `src/shared/`:与具体业务无关的后台公共 HTTP、组件和工具。模块专属能力先留在模块内部,只有被无关模块真实复用时才上移。
|
|
- `src/prototype/`:未纳入当前迭代的原型页面和原型路由;正式模块不得依赖原型代码。
|
|
- `src/modules/*/pages/`:路由级页面和业务编排;复杂展示、表单、抽屉和交互下沉到同模块组件或 composable。
|
|
- `src/modules/*/routes.ts`:模块路由片段;由 `src/app/router/index.ts` 统一装配。新增模块时同步维护 `src/core/navigation/adminNavigation.ts`。
|
|
- `src/core/*/` 与 `src/modules/*/stores/`:前者只放全应用基础状态,后者放领域状态;仅页面局部使用的状态留在页面或 composable。
|
|
- `src/modules/*/api/`:领域接口适配;公共 Axios 客户端位于 `src/shared/api/http.ts`,页面与组件不得散落创建 Axios 实例。
|
|
- `VITE_API_BASE_URL` 控制浏览器请求前缀,`API_PROXY_TARGET` 控制 Vite 开发代理上游;后者只由开发服务器读取,不进入客户端构建。新增或变更环境变量时同步更新 `.env.example`,不得提交真实密钥或环境专属凭据。
|
|
- 模块专属类型放在对应模块;本应用多个模块稳定复用的前端类型和工具放到应用内 `shared/`。不要链接应用目录之外的 TypeScript 包,服务端契约以 `baiyue-firstleg` Controller/OpenAPI 为准。
|
|
- `src/styles/`:设计令牌和全局样式;优先复用现有 `--cc-*` 变量和组件样式。
|
|
|
|
依赖方向保持为 `app -> modules/core/shared`、`modules -> core/shared`、`core -> shared`、`shared -> 无上层依赖`。模块间确需调用时只能引用对方根入口公开的 API 或契约,不得引用其他模块的页面、内部组件或内部目录。
|
|
|
|
## 开发环境样式验收
|
|
|
|
- 默认验收身份:`platform_admin`,用于“后台管理”的样式、路由、权限展示和交互验收。
|
|
- 密码不写入仓库;从本机未提交环境变量 `CHONGCHONG_ADMIN_ACCEPTANCE_PASSWORD` 或 `C:/Users/BY-OY/.codex/chongchong-global-dev-acceptance.env` 读取。若凭据不存在,再向用户索取,不重复询问账号名。
|
|
- 该身份仅适用于开发环境。不要把密码、Token 或真实接口地址写入源码、测试快照、日志或 `AGENTS.md`;开发环境变更时只更新本机凭据。
|
|
- 样式验收优先使用该身份进入真实页面,并按原型还原规则检查加载、空态、错误态、权限态和窄屏布局。
|
|
|
|
## 模块快速查询
|
|
|
|
进入模块后按 `routes.ts → pages/ → api/、types/、stores/ 或 composables/` 查询;没有对应目录时再查相邻代码,不先扫描全部 `src/`。
|
|
|
|
| 业务 | 模块入口 | 联查模块或服务端 |
|
|
|---|---|---|
|
|
| 工作台与业务总览 | `modules/dashboard/` | 按具体指标联查其所属业务模块和服务端,不在工作台复制领域契约 |
|
|
| 客户、企业审核 | `modules/customers/` | `iam/`、`file/` |
|
|
| 平台用户与 RBAC | `modules/iam/`、`core/access/` | `auth/`、`iam/` |
|
|
| 平台消息管理、模板与我的消息 | `modules/notifications/` | Backend `iam/src/main/java/com/baiyue/iam/notification/`;接口契约 `iam/src/main/resources/openapi/notification-v1.yaml`,触发消息的业务事件仍联查对应业务服务 |
|
|
| 导航与原型菜单图标 | `core/navigation/adminNavigation.ts`、`core/navigation/prototypeMenuIcons.ts` | 菜单结构、权限与路由同步核对;已有原型图标优先使用映射资源 |
|
|
| 平台仓库与仓储资源 | `modules/warehouses/`、`modules/warehouse-resources/` | `warehouse/` |
|
|
| 订单列表、详情与入库费用 | `modules/unified-orders/`、`modules/first-leg-orders/`;费用入口 `modules/unified-orders/components/InboundFeeDetailManager.vue`、`modules/unified-orders/api/inboundFeeDetails.ts` | `order/`、`firstleg/`;费用来源审核发布联查 `firstleg/AGENTS.md` |
|
|
| 入库、测量和计费工作流 | `modules/inbounds/`、`modules/fba-pricing/`、`modules/dimension-config/`、`modules/fee-items/` | `firstleg/`、`file/`、`integration-service/` |
|
|
| 财务账户、账单、收款与成本 | `modules/finance/` | `finance/`;费用来源与柜次成本快照联查 `firstleg/`,凭证联查 `file/` |
|
|
| 货柜与智能排柜 | `modules/container-loading/` | `firstleg/loading/`、`firstleg/split/` |
|
|
| 预装详情、装柜清单与柜次费用 | `modules/loading-lists/pages/PreloadPlanDetailView.vue`、`modules/loading-lists/components/LoadingListDetailDrawer.vue`、`modules/loading-lists/components/ContainerFeesPanel.vue`、`modules/loading-lists/api/containerFees.ts` | `firstleg/loading/`、`firstleg` 柜次费用、`finance/` 成本分摊、`file/`、`warehouse/` |
|
|
| 海运订舱与船期 | `modules/ocean-bookings/`、`modules/port-schedules/` | `firstleg/oceanbooking/`、`firstleg/portschedule/`、`integration-service/` |
|
|
| 拖车预约 | `modules/trucking/` | `firstleg/outbound/dispatch/`、`firstleg/` |
|
|
| 报关协同 | `modules/customs/` | `firstleg/customs/`、`file/` |
|
|
| 国内出仓确认 | `modules/outbound-dispatch/` | `firstleg/outbound/dispatch/` |
|
|
| 主数据与下载 | `modules/master-data/`、`modules/downloads/` | `warehouse/`、`file/` |
|
|
|
|
## Admin 全量验收快速索引
|
|
|
|
当前按全量业务闭环验收。阶段文档仍用于核对功能来源和验收证据,不再限制本次验收的模块范围;按“模块目录 → `routes.ts`/页面 → `api`/类型”定位。本表只描述 Admin 页面、路由和前端契约,不替代后端模块指引。
|
|
|
|
| 验收域 | Admin 范围与入口 | 核对重点 |
|
|
|---|---|---|
|
|
| 一期:头程订单闭环 | `modules/auth/` 登录;`customers/` 客户与企业审核;`iam/` 内部用户、角色、权限;`warehouses/` 平台收货仓;`master-data/` 快递公司、往来单位;`first-leg-orders/` 头程订单;`dashboard/` 工作台 | 企业审核归客户列表,平台 RBAC 仅维护平台员工与平台权限资源 |
|
|
| 二期及三期履约 | `modules/inbounds/`、`warehouse-resources/`、`fba-pricing/`、`dimension-config/`、`fee-items/`、`unified-orders/`、`container-loading/`、`loading-lists/`、`ocean-bookings/`、`port-schedules/`、`trucking/`、`customs/`、`outbound-dispatch/` | 按真实服务端契约核对全链路状态、权限、异常和证据 |
|
|
|
|
阶段文档入口(路径相对本文件所在目录):按验收业务选择 `../../docs/一期/`、`../../docs/二期/`、`../../docs/三期/` 或 `../../docs/财务管理/` 的需求确认、契约和验收规则;进度、排期或验收状态问题再读取相应进度表和验收报告。
|
|
|
|
## 业务与安全约束
|
|
|
|
- 当前产品层级只有平台和客户(企业)两级;Admin 不把“租户”作为用户可见概念,不新增租户选择器、目标租户文案或依赖租户上下文才能使用的页面流程。多租户产品能力后续单独设计。
|
|
- 平台仓库是公共主数据,不与客户绑定。托盘、库位等仓储资源页面必须能够独立查询全部客户和全部仓库,选择客户不得缩小、清空或禁用仓库候选。
|
|
- 后端兼容字段 `tenantId` 仅留在 API 适配层和内部类型中,不在页面文案或交互中暴露;需要客户范围的写操作仍显式选择客户,长整型客户 ID 按字符串透传。
|
|
|
|
- 菜单隐藏和前端路由守卫只改善体验,不能替代服务端鉴权。新增操作必须使用稳定的权限编码,并与 API 权限保持一致。
|
|
- 认证统一经过 `src/core/auth/auth.ts` 和 `src/shared/api/http.ts`;不要在页面中复制令牌读写或手工拼装 `Authorization`。
|
|
- 当前登录和部分数据仍可能是模拟实现。接入 `baiyue-firstleg` Gateway 真实接口时删除对应模拟路径,不允许让生产逻辑静默回退到假数据。
|
|
- 删除、停用、改权限等高风险操作必须有明确确认、处理中、成功和失败反馈;失败时保留用户上下文,避免误以为已生效。
|
|
- 日志、提示和示例数据不得包含真实账号、令牌、客户隐私或生产数据。
|
|
- Admin 维护客户专属数据时,必须通过平台客户列表显式选择目标客户,不得从本地存储推断客户。平台仓库等公共主数据不要求先选择客户;切换客户时不得保留上一客户的编辑、详情或导入上下文。
|
|
|
|
## UI 与交互
|
|
|
|
- 修改已有 Admin 原型页面前先读 `../../docs/Admin-Client前端原型还原验收规则.md`,按页面和操作形成原型核对矩阵;本节维护 Admin 的实现约束,不复制跨前端验收文档全文。
|
|
- 已向客户讲解或确认过的产品原型是页面视觉与布局实现的直接事实来源。字段顺序、字段分组、字段摆放、列宽、控件宽高、对齐方式、换行方式、区块层级、上下左右边距、内边距、间隙、留白、圆角、边框、阴影、背景色、文字颜色和字号均必须按原型还原,不得只参考大致风格后自行重新排版。
|
|
- 原型中的按钮位置、顺序、尺寸、圆角、边框、背景色、文字色、图标、悬停态、激活态、禁用态和危险语义必须直接按原型实现;不得擅自改为文字链接、不同颜色、不同按钮类型、折叠菜单或自创交互效果,也不得增加原型没有的上浮、缩放、渐变线、装饰图标或其他视觉元素。
|
|
- 原型已经给出明确图标、字符图标、图片资源或按钮内图标时,直接使用原型中的同一方案和资源,不得以 Lucide、Element Plus 默认图标、手绘图标或个人偏好替换。仅当原型没有定义对应图标时,才按本节的默认图标语义补齐。
|
|
- 上述原型还原规则优先于本文件中“延续现有视觉体系”、默认组件样式和默认图标库等一般性规则。只有用户当前明确要求、阶段范围、真实字段长度、响应式、可访问性或接口事实与原型冲突时才允许做最小调整,并须在修改前说明具体差异、原因和影响范围;不得以技术实现方便为由偏离原型。
|
|
- 详情、新增、编辑、审核等操作采用独立页面、居中弹框、侧滑面板或其他承载方式,必须逐页面按对应原型确认,不得全局写死为某一种容器。原型为独立页面时使用正式路由和页面布局;原型为居中弹框时使用模态弹框;只有原型明确为侧滑面板时才使用抽屉。不得因为已有公共组件或改动方便,把原型中的独立页面改成弹框、把弹框改成抽屉,或反向替换。
|
|
- 延续现有后台视觉体系:克制的企业级界面、清晰的信息层级和高密度但可扫描的数据展示。
|
|
- 路由级页面标题和说明统一由 `AppLayout` 顶部 `page-heading` 根据路由 `meta.title`、`meta.description` 展示。标准列表页正文不得重复渲染 `PageToolbar`、页面标题或说明,只保留查询区与表格区。`QueryToolbar` 只承载筛选项及其内置查询、重置按钮,不把新增、导入、导出或批量操作放入其 `actions` 插槽;重新执行查询即刷新当前结果,标准列表页任何位置都不得再提供独立刷新按钮。新增、导入、导出和批量操作统一放入 `DataTable` 的 `toolbar-actions` 插槽并靠表格工具栏右侧展示。仅没有查询组件的实时工作台或详情页在业务确实需要主动重载时,才可保留刷新;仅详情页或工作台在路由明确设置 `showPageHeading: false` 时,才可在正文使用独立详情头。
|
|
- 标准列表页的查询面板与表格面板使用 `ListPageLayout` 保持单一 `16px` 间距,不再叠加页面级 margin、空白操作区或额外容器间距。`DataTable` 必须位于连续的 `surface-panel table-panel` 中,使右侧业务按钮、列设置、表头和分页属于同一表格面板;不得使用 `toolbar-start` 重复显示列表标题、数量或说明,数量统一放在 `pagination-left`。当工具栏只有右侧操作和列设置时使用紧凑高度,不保留空白的左侧标题区域。
|
|
- 操作按钮统一使用 Lucide 图标和固定语义:详情/查看 `Eye`、编辑 `Pencil`、更多 `MoreHorizontal`、新增 `Plus`、删除 `Trash2`、启停 `Power`、刷新 `RefreshCw`、导入 `FileUp`、导出/下载 `Download`、返回 `ArrowLeft`、保存 `Save`、复制 `Copy`。表格高频操作使用“图标 + 文案”,更多操作使用仅图标按钮并提供 `aria-label` 与悬停提示;同一语义不得在不同页面混用其他图标、纯文字按钮或手绘 SVG。危险操作继续使用明确文案、危险色和确认流程,不能只显示图标。
|
|
- 表格单行操作不超过 3 个时全部直接展示“图标 + 文案”;从第 4 个操作开始才使用仅图标的 `MoreHorizontal` 更多菜单,并优先直接保留详情、编辑、下载等高频操作。进入更多菜单的启停、删除等危险操作仍须显示明确文案和危险语义,并沿用原确认流程;不得为了布局方便把仅有 1-3 个操作提前折叠到更多菜单。
|
|
- 优先使用 Element Plus 与现有复用组件;图标使用 Lucide,不用表情符号充当功能图标。
|
|
- 表格、筛选、抽屉和表单应按实际语义覆盖适用的加载、空数据、错误、禁用和无权限状态,不为不适用的组件机械增加状态。
|
|
- 保持键盘可操作、可见焦点、表单标签和足够的颜色对比度;不要只用颜色表达状态。
|
|
- 新页面至少适配现有 320px 最小宽度策略,并检查侧栏、表格、抽屉和表单在窄屏下的退化方式。
|
|
|
|
## 公共前端组件复用
|
|
|
|
- 开发或重构页面前,先检查 `src/shared/components/`,不得在业务页面重复实现已有的查询栏、数据表格、批量导入、弹窗、抽屉、加载错误、状态和复制交互。公共组件无法满足时,先判断能力是否具有跨模块复用价值:通用能力扩展公共组件并补测试;纯业务特例留在所属模块,不用页面级 CSS 覆盖破坏公共组件契约。
|
|
- 查询与筛选统一使用 `src/shared/components/QueryToolbar.vue`。通过 `fields` 配置 `input`、`select`、`date`、`daterange`,使用 `v-model` 管理查询模型,并监听 `search`、`reset`;额外操作放入 `actions` 插槽。不要在每个列表页重新编写筛选容器、查询/重置按钮和移动端换行样式。
|
|
- 业务数据列表统一使用 `src/shared/components/DataTable.vue`。通过 `columns` 和命名插槽定义列,使用 `v-model:page`、`v-model:page-size` 及 `total` 接入分页;无需分页时可省略 `total`。不得重复拼装 `el-table` 与分页器;“操作”列仍须遵守仓库根规则,放在第一列,固定时固定在左侧。
|
|
- 标准 XLSX 批量导入/上传统一使用 `src/shared/components/BatchImportDialog.vue`。页面只维护弹窗开关,传入标题、实体名称、模板文件名、`downloadTemplate` 和 `importFile`,并在 `success` 后刷新列表;文件格式和大小校验、模板下载、提交状态、接口错误、整批校验结果、CSV 错误报告及响应式样式由组件负责。不要在页面内重复创建文件输入框、上传状态、错误报告逻辑或导入弹窗 CSS。
|
|
- 普通模态框和侧滑编辑/详情优先使用 `src/shared/components/AppDialog.vue`、`AppDrawer.vue`,复用提交锁定、加载态、底部按钮和窄屏约束;仅当业务交互与其契约明显不同时直接使用 Element Plus 原始容器。
|
|
- 列表或详情加载失败优先组合 `src/shared/components/LoadErrorState.vue` 与 `ApiErrorMeta.vue`,保留重试入口及 `requestId`、`traceId`;状态展示和复制操作分别优先使用 `StatusBadge.vue`、`CopyButton.vue`。
|
|
- 公共组件的使用示例优先参考已接入页面:查询和表格见 `modules/master-data/express-companies/pages/ExpressCompaniesView.vue`,批量导入见该页面及 `modules/master-data/counterparties/pages/PartnersView.vue`,抽屉见 `modules/downloads/pages/DownloadCenterView.vue`。扩展公共组件时同步检查所有现有消费者,并至少运行组件测试和直接受影响页面测试。
|
|
|
|
## 本地命令与质量门禁
|
|
|
|
在 `apps/admin-web` 目录执行:
|
|
|
|
```bash
|
|
pnpm install
|
|
pnpm dev
|
|
pnpm test
|
|
pnpm typecheck
|
|
pnpm build
|
|
```
|
|
|
|
- 日常变更至少运行 `pnpm typecheck` 和受影响测试;交付前运行 `pnpm test` 与 `pnpm build`,后者也会执行类型检查。
|
|
- 当前项目未声明 lint 脚本,不要声称 lint 已通过。若任务新增或变更质量脚本,应同时更新 `package.json`、`README.md` 和本文件。
|
|
- 不手工修改 `dist/` 或 `node_modules/`;依赖变更必须同步当前项目的 `package.json` 与锁文件。
|