diff --git a/docs/miniprogram-ui-spec-sanqiang.md b/docs/miniprogram-ui-spec-sanqiang.md index be152eea..c0455f8a 100644 --- a/docs/miniprogram-ui-spec-sanqiang.md +++ b/docs/miniprogram-ui-spec-sanqiang.md @@ -1,6 +1,6 @@ # 小程序端 UI 规范(中科兴皖一体化门户) -> **适用范围**:`miniprogram`(客户端 / 供应商端 / 配送员端) +> **适用范围**:`miniprogram`(客户端 / 供应商端 / 配送员端)与 **`mobile-h5`(统一工作台)** > **设计基准文件(Demo)**: > - `mobile-ui/sanqiang-client-ui-demo.html` > - `mobile-ui/sanqiang-client-cart-ui-demo.html` @@ -8,6 +8,16 @@ > - `mobile-ui/sanqiang-client-profile-ui-demo.html` > - `mobile-ui/sanqiang-supplier-ui-demo.html` > - `mobile-ui/sanqiang-deliverer-ui-demo.html` +> - **工作台**:`mobile-ui/zkxw-mobile-vant-ui-demo.html` + +## 移动工作台(mobile-h5) + +- 工程:`mobile-h5`(HBuilderX uni-app Vue3 + `@vant/weapp`) +- 视觉 Demo:`mobile-ui/zkxw-mobile-vant-ui-demo.html` +- 设计说明:`docs/superpowers/specs/2026-08-10-mobile-h5-vant-ui-design.md` +- 实现计划:`docs/superpowers/plans/2026-08-10-mobile-h5-vant-ui.md` +- 信息架构:单一工作台 + 权限菜单卡片(上 Icon 下标题);样板页见 `mobile-h5/pages/demo/*` +- Token:仍遵循本文 §2 三墙色板;**禁止**使用 web-admin `#10b981` --- diff --git a/docs/superpowers/plans/2026-08-10-mobile-h5-vant-ui.md b/docs/superpowers/plans/2026-08-10-mobile-h5-vant-ui.md new file mode 100644 index 00000000..f9d1ec8f --- /dev/null +++ b/docs/superpowers/plans/2026-08-10-mobile-h5-vant-ui.md @@ -0,0 +1,807 @@ +# mobile-h5 Vant UI 骨架 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 在保留 HBuilderX uni-app 骨架的前提下,接入 `@vant/weapp`、落地三墙 Token 与全局样式层,并实现首页工作台 + 列表/详情/表单样板页,供后续业务页复制适配。 + +**Architecture:** 视觉以 `mobile-ui/zkxw-mobile-vant-ui-demo.html` 为准;`styles/tokens.scss` 为唯一色板源,经 `vant-theme.scss` + `app.scss` + `styles/components/*` 注入 `App.vue`;交互控件用 `@vant/weapp`(easycom),业务壳(菜单宫格、列表卡、附件、流转)用自研 Vue 组件。本期菜单权限用 mock,不接真实 API。 + +**Tech Stack:** uni-app Vue3(HBuilderX)、`@vant/weapp`、SCSS、微信小程序发行 + +**Spec:** `docs/superpowers/specs/2026-08-10-mobile-h5-vant-ui-design.md` + +--- + +## File map(将创建 / 修改) + +| 路径 | 职责 | +|------|------| +| `mobile-h5/package.json` | npm 依赖(`@vant/weapp`) | +| `mobile-h5/pages.json` | easycom、页面路由、globalStyle | +| `mobile-h5/uni.scss` | 覆盖 uni 默认主色为三墙绿;import tokens | +| `mobile-h5/App.vue` | 全局样式入口 | +| `mobile-h5/styles/tokens.scss` | SCSS + CSS 变量 Token | +| `mobile-h5/styles/vant-theme.scss` | Vant CSS 变量覆盖 | +| `mobile-h5/styles/mixins.scss` | Hero / 卡片 mixin | +| `mobile-h5/styles/app.scss` | page 背景、工具类 | +| `mobile-h5/styles/components/*.scss` | menu-grid / todo / list / detail / attach / flow / form-shell | +| `mobile-h5/utils/menu-mock.js` | 移动端菜单 mock + 权限过滤 | +| `mobile-h5/utils/biz-mock.js` | 列表/详情样板 mock 数据 | +| `mobile-h5/components/MenuGrid.vue` | 上 Icon 下标题宫格 | +| `mobile-h5/components/TodoPanel.vue` | 待办统计 + 条目 | +| `mobile-h5/components/BizListCard.vue` | 列表业务卡 | +| `mobile-h5/components/AttachList.vue` | 附件上传条 + 文件卡 | +| `mobile-h5/components/FlowTimeline.vue` | 流转记录 | +| `mobile-h5/pages/index/index.vue` | 首页工作台 | +| `mobile-h5/pages/demo/list.vue` | 列表样板 | +| `mobile-h5/pages/demo/detail.vue` | 详情样板 | +| `mobile-h5/pages/demo/form.vue` | 表单样板 | +| `mobile-h5/pages/demo/comps.vue` | 组件合集样板 | +| `docs/miniprogram-ui-spec-sanqiang.md` | 增加「移动工作台」指向 | + +**不修改:** `main.js`、`manifest.json` 核心结构(仅后续填 appid 时改 `mp-weixin.appid`,本期可不改)、`index.html`。 + +--- + +### Task 1: 初始化 npm 并安装 `@vant/weapp` + +**Files:** +- Create: `mobile-h5/package.json` +- Create/Update: `mobile-h5/.gitignore`(确保含 `node_modules/`) + +- [ ] **Step 1: 写入 package.json** + +```json +{ + "name": "mobile-h5", + "version": "1.0.0", + "private": true, + "description": "zkxw mobile uni-app (HBuilderX) + Vant Weapp", + "dependencies": { + "@vant/weapp": "^1.11.7" + } +} +``` + +- [ ] **Step 2: 安装依赖** + +Run(在 `mobile-h5` 目录): + +```bash +cd /Users/wuzilong/work/00code/zkxw/mobile-h5 && npm install +``` + +Expected: 生成 `node_modules/@vant/weapp`,无报错。 + +- [ ] **Step 3: 确认 easycom 实际组件路径** + +Run: + +```bash +ls /Users/wuzilong/work/00code/zkxw/mobile-h5/node_modules/@vant/weapp/button +``` + +Expected: 存在 `index.js` / `index.wxml` 等。后续 `pages.json` 使用路径 `@vant/weapp/button/index`(无 `dist` 前缀)。若本机在 `dist/` 下,则改用 `@vant/weapp/dist/button/index`。 + +- [ ] **Step 4: Commit** + +```bash +cd /Users/wuzilong/work/00code/zkxw +git add mobile-h5/package.json mobile-h5/package-lock.json mobile-h5/.gitignore +git commit -m "$(cat <<'EOF' +chore(mobile-h5): add package.json and @vant/weapp dependency + +EOF +)" +``` + +--- + +### Task 2: 配置 pages.json(easycom + 路由 + 全局导航色) + +**Files:** +- Modify: `mobile-h5/pages.json` + +- [ ] **Step 1: 替换为以下完整内容**(路径以 Task 1 实测为准;默认无 dist) + +```json +{ + "easycom": { + "autoscan": true, + "custom": { + "^van-(.*)": "@vant/weapp/$1/index" + } + }, + "pages": [ + { + "path": "pages/index/index", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "工作台" + } + }, + { + "path": "pages/demo/list", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "业务列表" + } + }, + { + "path": "pages/demo/detail", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "业务详情" + } + }, + { + "path": "pages/demo/form", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "编辑业务" + } + }, + { + "path": "pages/demo/comps", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "组件风格" + } + } + ], + "globalStyle": { + "navigationBarTextStyle": "white", + "navigationBarTitleText": "中科兴皖", + "navigationBarBackgroundColor": "#0a9f6d", + "backgroundColor": "#f5f8f7" + }, + "uniIdRouter": {} +} +``` + +- [ ] **Step 2: 校验 JSON 合法** + +Run: + +```bash +node -e "JSON.parse(require('fs').readFileSync('mobile-h5/pages.json','utf8')); console.log('ok')" +``` + +Expected: `ok` + +- [ ] **Step 3: Commit** + +```bash +git add mobile-h5/pages.json +git commit -m "$(cat <<'EOF' +chore(mobile-h5): configure Vant easycom and demo page routes + +EOF +)" +``` + +--- + +### Task 3: Token + uni.scss + 全局样式入口 + +**Files:** +- Create: `mobile-h5/styles/tokens.scss` +- Create: `mobile-h5/styles/vant-theme.scss` +- Create: `mobile-h5/styles/mixins.scss` +- Create: `mobile-h5/styles/app.scss` +- Modify: `mobile-h5/uni.scss` +- Modify: `mobile-h5/App.vue` + +- [ ] **Step 1: 创建 `styles/tokens.scss`** + +```scss +// 唯一 Token 源 — 对齐三墙 / Demo,禁止 #10b981 +$brand-green: #0a9f6d; +$brand-green-dark: #087f57; +$brand-green-soft: #e9f9f2; +$barley-yellow: #d6a343; +$barley-yellow-soft: #fff7e8; +$bg-page: #f5f8f7; +$surface: #ffffff; +$text-primary: #1f2a26; +$text-muted: #6b7b74; +$border: #dcebe4; +$danger: #d14343; +$warning: #cf8a19; +$success: #189b65; +$radius-card: 28rpx; +$radius-lg: 40rpx; + +@mixin token-css-vars { + --brand-green: #{$brand-green}; + --brand-green-dark: #{$brand-green-dark}; + --brand-green-soft: #{$brand-green-soft}; + --barley-yellow: #{$barley-yellow}; + --barley-yellow-soft: #{$barley-yellow-soft}; + --bg-page: #{$bg-page}; + --surface: #{$surface}; + --text-primary: #{$text-primary}; + --text-muted: #{$text-muted}; + --border: #{$border}; + --danger: #{$danger}; + --warning: #{$warning}; + --success: #{$success}; + --radius-card: #{$radius-card}; + --radius-lg: #{$radius-lg}; + --shadow-soft: 0 8rpx 32rpx rgba(8, 127, 87, 0.08); +} +``` + +- [ ] **Step 2: 创建 `styles/vant-theme.scss`** + +```scss +page { + --button-primary-background-color: #0a9f6d; + --button-primary-border-color: #0a9f6d; + --button-primary-color: #ffffff; + --nav-bar-background-color: transparent; + --nav-bar-title-text-color: #ffffff; + --nav-bar-icon-color: #ffffff; + --tabs-bottom-bar-color: #0a9f6d; + --tag-primary-color: #0a9f6d; + --tag-success-color: #189b65; + --tag-danger-color: #d14343; + --tag-warning-color: #cf8a19; + --steps-active-color: #0a9f6d; + --notice-bar-background-color: #e9f9f2; + --notice-bar-text-color: #087f57; +} +``` + +> `@vant/weapp` 部分主题通过组件 `color` / `custom-class` 传入;CSS 变量名以当前 weapp 版本文档为准,落地时对照 `node_modules/@vant/weapp` README 微调。 + +- [ ] **Step 3: 创建 `styles/mixins.scss`** + +```scss +@mixin hero-green { + background: linear-gradient(155deg, #066647 0%, #0a9f6d 48%, #12b37a 100%); + color: #ffffff; + border-radius: 0 0 56rpx 56rpx; + position: relative; + overflow: hidden; +} + +@mixin surface-card { + background: var(--surface, #ffffff); + border: 1rpx solid var(--border, #dcebe4); + border-radius: var(--radius-card, 28rpx); + box-shadow: var(--shadow-soft); +} +``` + +- [ ] **Step 4: 创建 `styles/app.scss`** + +```scss +@import './tokens.scss'; + +page { + @include token-css-vars; + background-color: var(--bg-page); + color: var(--text-primary); + font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; + font-size: 28rpx; + line-height: 1.5; + box-sizing: border-box; +} + +view, text { + box-sizing: border-box; +} + +.page-shell { + min-height: 100vh; + background: + radial-gradient(840rpx 440rpx at 100% 0%, rgba(214, 163, 67, 0.14), transparent 55%), + radial-gradient(760rpx 400rpx at 0% 20%, rgba(10, 159, 109, 0.1), transparent 50%), + linear-gradient(180deg, #e8f5ef 0%, #f4f7f6 40%, #f7f9f8 100%); +} + +.safe-bottom { + padding-bottom: calc(24rpx + env(safe-area-inset-bottom)); +} +``` + +- [ ] **Step 5: 修改 `uni.scss` 顶部主色** + +将文件中: + +```scss +$uni-color-primary: #007aff; +``` + +改为: + +```scss +@import './styles/tokens.scss'; + +$uni-color-primary: $brand-green; +$uni-color-success: $success; +$uni-color-warning: $warning; +$uni-color-error: $danger; +``` + +(保留其余 uni 默认变量,仅覆盖行为色。) + +- [ ] **Step 6: 修改 `App.vue`** + +```vue + + + +``` + +> Task 3 提交前,Task 4 需先创建空的 `styles/components/*.scss`(可先写文件头注释),避免 App 编译找不到 import。 + +- [ ] **Step 7: 校验 Token 色值存在** + +Run: + +```bash +grep -n '#0a9f6d' mobile-h5/styles/tokens.scss && ! grep -n '#10b981' mobile-h5/styles/tokens.scss +``` + +Expected: 命中 `#0a9f6d`;无 `#10b981`。 + +- [ ] **Step 8: Commit** + +```bash +git add mobile-h5/styles mobile-h5/uni.scss mobile-h5/App.vue +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add design tokens and global style entry + +EOF +)" +``` + +--- + +### Task 4: 拆分组件级 SCSS(从 Demo 迁移关键类) + +**Files:** +- Create: `mobile-h5/styles/components/menu-grid.scss` +- Create: `mobile-h5/styles/components/todo.scss` +- Create: `mobile-h5/styles/components/list.scss` +- Create: `mobile-h5/styles/components/detail.scss` +- Create: `mobile-h5/styles/components/attach.scss` +- Create: `mobile-h5/styles/components/flow.scss` +- Create: `mobile-h5/styles/components/form-shell.scss` + +**权威对照:** `mobile-ui/zkxw-mobile-vant-ui-demo.html` 中对应 CSS 块;实现时将 `px` 按 `×2 → rpx` 换算,类名保持与 Demo 一致(`.menu-grid`、`.biz-card`、`.detail-hero`、`.d-attach-*`、`.flow-*` 等)。 + +- [ ] **Step 1: 创建七个 scss 文件** + +每个文件至少包含 `@import '../mixins.scss';`(若需要)及从 Demo 迁移的对应区块。最低要求类名: + +| 文件 | 必须包含的类 | +|------|----------------| +| `menu-grid.scss` | `.menu-grid` `.menu-card` `.menu-icon` `.menu-title` | +| `todo.scss` | `.todo-panel` `.todo-stats` `.todo-stat` `.todo-list` `.todo-item` | +| `list.scss` | `.list-hero` `.list-filter-dock` `.seg-tabs` `.biz-card` `.status-warning/primary/danger/success` | +| `detail.scss` | `.detail-page` `.detail-hero` `.detail-metric-dock` `.detail-section` `.detail-footer` | +| `attach.scss` | `.d-attach-list` `.d-attach-upload` `.d-attach-card` `.ft-pdf/.ft-img/.ft-xls/.ft-doc` | +| `flow.scss` | `.flow-list` `.flow-item` `.flow-dot` `.flow-card` | +| `form-shell.scss` | `.form-page` `.form-section-title` `.form-footer` | + +具体属性从 Demo 拷贝并做 rpx 换算;渐变与色值使用 `var(--brand-green)` 等 CSS 变量。 + +- [ ] **Step 2: 静态检查类名是否齐全** + +Run: + +```bash +for f in menu-grid todo list detail attach flow form-shell; do + test -f "mobile-h5/styles/components/$f.scss" || exit 1 +done +grep -q 'menu-grid' mobile-h5/styles/components/menu-grid.scss +grep -q 'biz-card' mobile-h5/styles/components/list.scss +grep -q 'd-attach-upload' mobile-h5/styles/components/attach.scss +grep -q 'flow-list' mobile-h5/styles/components/flow.scss +echo 'scss ok' +``` + +Expected: `scss ok` + +- [ ] **Step 3: Commit** + +```bash +git add mobile-h5/styles/components +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add page-pattern SCSS modules from UI demo + +EOF +)" +``` + +--- + +### Task 5: Mock 数据工具 + +**Files:** +- Create: `mobile-h5/utils/menu-mock.js` +- Create: `mobile-h5/utils/biz-mock.js` + +- [ ] **Step 1: 写入 `menu-mock.js`** + +```js +/** 模拟「菜单管理 → 移动端菜单」授权结果 */ +export const ALL_MOBILE_MENUS = [ + { id: 'm1', title: '待办审批', icon: 'todo-list-o', path: '/pages/demo/list' }, + { id: 'm2', title: '采集协议', icon: 'orders-o', path: '/pages/demo/list' }, + { id: 'm3', title: '缴费确认', icon: 'balance-list-o', path: '/pages/demo/list' }, + { id: 'm4', title: '样本接收', icon: 'logistics', path: '/pages/demo/list' }, + { id: 'm5', title: '质检工单', icon: 'certificate', path: '/pages/demo/list' }, + { id: 'm6', title: '生产任务', icon: 'cluster-o', path: '/pages/demo/list' }, + { id: 'm7', title: '库位出库', icon: 'send-gift-o', path: '/pages/demo/list' }, + { id: 'm8', title: '组件示例', icon: 'apps-o', path: '/pages/demo/comps' } +] + +/** @param {string[]} grantedIds 当前用户拥有的菜单 id */ +export function filterMenusByPermission(grantedIds) { + const set = new Set(grantedIds || []) + return ALL_MOBILE_MENUS.filter((m) => set.has(m.id)) +} + +export const DEFAULT_GRANTED_IDS = ['m1', 'm2', 'm3', 'm4', 'm5', 'm7', 'm8'] +``` + +- [ ] **Step 2: 写入 `biz-mock.js`** + +从 Demo 的 `listData` 迁移 4 条样板(含 `attachments`、`logs`、`payments`、`steps`、`stepActive`、`tagType`、`amount`/`progress` 等字段),并导出: + +```js +export function getList() { /* return listData */ } +export function getById(id) { /* find or listData[0] */ } +export function filterByTab(tabIndex, keyword) { /* 与 Demo filteredList 逻辑一致 */ } +``` + +- [ ] **Step 3: 快速自测过滤逻辑** + +Run: + +```bash +cd mobile-h5 && node --input-type=module -e " +import { filterMenusByPermission, DEFAULT_GRANTED_IDS, ALL_MOBILE_MENUS } from './utils/menu-mock.js' +const v = filterMenusByPermission(DEFAULT_GRANTED_IDS) +console.log(v.length, ALL_MOBILE_MENUS.length) +if (v.length !== 7) process.exit(1) +" +``` + +Expected: 打印 `7 8`,exit 0。 + +> 若 HBuilderX/微信环境不支持 node ESM,可将文件改为无 `export` 的 CommonJS `module.exports`,或用 `uni` 内仅引用、本步改为人工阅读断言。优先保持 `export`,与 Vue3 script 一致。 + +- [ ] **Step 4: Commit** + +```bash +git add mobile-h5/utils +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add menu and biz mock helpers + +EOF +)" +``` + +--- + +### Task 6: 公共组件 MenuGrid + TodoPanel + +**Files:** +- Create: `mobile-h5/components/MenuGrid.vue` +- Create: `mobile-h5/components/TodoPanel.vue` + +- [ ] **Step 1: 创建 `MenuGrid.vue`** + +Props: `menus: Array<{ id, title, icon, path }>` +Events: `select(menu)` + +模板结构: + +```vue + + + +``` + +- [ ] **Step 2: 创建 `TodoPanel.vue`** + +Props: `stats: { approve, pay, alert }`,`items: Array` +Events: `stat-click(key)`,`item-click(item)`,`more` + +结构对齐 Demo:三列 `.todo-stat` + `.todo-item` 列表;样式依赖全局 `todo.scss`。 + +- [ ] **Step 3: Commit** + +```bash +git add mobile-h5/components/MenuGrid.vue mobile-h5/components/TodoPanel.vue +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add MenuGrid and TodoPanel components + +EOF +)" +``` + +--- + +### Task 7: 公共组件 BizListCard + AttachList + FlowTimeline + +**Files:** +- Create: `mobile-h5/components/BizListCard.vue` +- Create: `mobile-h5/components/AttachList.vue` +- Create: `mobile-h5/components/FlowTimeline.vue` + +- [ ] **Step 1: `BizListCard.vue`** + +Props: `item`(含 `title, code, typeLabel, icon, status, tagType, desc, owner, time, amount, progress, hint`) +Events: `view`、`action` + +根节点:``,结构对齐 Demo 列表卡。 + +- [ ] **Step 2: `AttachList.vue`** + +Props: `files: Array<{ name, size?, time? }>` +Events: `upload`、`preview`、`download` +内置 `fileExt` / `fileTypeClass` 方法(从 Demo 迁移)。下载按钮使用 Demo 定稿的 SVG(箭头+托盘)。 + +- [ ] **Step 3: `FlowTimeline.vue`** + +Props: `logs: Array<{ title, desc, time, tone, actor?, icon?, badge? }>` +根节点 `.flow-list`,子项 `.flow-item`。 + +- [ ] **Step 4: Commit** + +```bash +git add mobile-h5/components/BizListCard.vue mobile-h5/components/AttachList.vue mobile-h5/components/FlowTimeline.vue +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add BizListCard, AttachList, and FlowTimeline + +EOF +)" +``` + +--- + +### Task 8: 首页工作台 `pages/index/index.vue` + +**Files:** +- Modify: `mobile-h5/pages/index/index.vue` + +- [ ] **Step 1: 实现首页** + +要点: + +1. 自定义绿渐变 Header(用户名 / 角色 / 部门 mock)。 +2. `MenuGrid`:`filterMenusByPermission(DEFAULT_GRANTED_IDS)`。 +3. `TodoPanel`:点统计或条目 → `uni.navigateTo({ url: '/pages/demo/list' })`。 +4. 菜单 `select`:有 `path` 则 `navigateTo`。 +5. 样式用已有全局类;页面根 `class="page-shell"` 可选(首页也可用纯白底 + header,对齐 Demo)。 + +- [ ] **Step 2: HBuilderX 运行到微信开发者工具** + +手动验收: + +- 首页可见菜单宫格(默认 7 项,无「生产任务」)。 +- 点击「组件示例」进入 comps(若尚未实现 comps,可暂指向 list)。 +- 主色为绿色,无系统默认蓝。 + +- [ ] **Step 3: Commit** + +```bash +git add mobile-h5/pages/index/index.vue +git commit -m "$(cat <<'EOF' +feat(mobile-h5): implement permission-filtered home workspace + +EOF +)" +``` + +--- + +### Task 9: 列表样板页 + +**Files:** +- Create: `mobile-h5/pages/demo/list.vue` + +- [ ] **Step 1: 实现列表页** + +结构:`.list-hero`(返回 + 标题 + `van-search`)→ `.list-filter-dock` 四格 seg → `BizListCard` 列表。 +数据:`biz-mock.filterByTab`。 +「查看」→ `/pages/demo/detail?id=`;「处理」→ `/pages/demo/form?mode=edit&id=`;右上角加号 → form create。 + +返回:`uni.navigateBack` 或 `reLaunch` 到首页。 + +- [ ] **Step 2: 手动验收** + +- 分段切换条数变化。 +- 搜索过滤标题/单号。 +- 卡片状态色与 Demo 一致。 + +- [ ] **Step 3: Commit** + +```bash +git add mobile-h5/pages/demo/list.vue +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add demo business list page + +EOF +)" +``` + +--- + +### Task 10: 详情 + 表单样板页 + +**Files:** +- Create: `mobile-h5/pages/demo/detail.vue` +- Create: `mobile-h5/pages/demo/form.vue` + +- [ ] **Step 1: 详情页** + +`onLoad(query)` → `getById(query.id)`。 +区块:状态 Hero、metric dock、基础信息、`van-steps`、缴费(有则显示)、`AttachList`、`FlowTimeline`、底栏返回/编辑。 + +- [ ] **Step 2: 表单页** + +`van-cell-group` + `van-field`(名称、单号、类型、加急开关、负责人、日期、金额、备注);`.form-footer` 取消/保存;保存 `van-toast` 后 `navigateBack`。 +注:`@vant/weapp` 表单为 `van-field` 等,无 Web 版 `van-form` 时用手动校验(名称非空)。 + +- [ ] **Step 3: 手动联跑** list → detail → form → back + +- [ ] **Step 4: Commit** + +```bash +git add mobile-h5/pages/demo/detail.vue mobile-h5/pages/demo/form.vue +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add demo detail and form pages + +EOF +)" +``` + +--- + +### Task 11: 组件合集页 + 规范文档回写 + +**Files:** +- Create: `mobile-h5/pages/demo/comps.vue` +- Modify: `docs/miniprogram-ui-spec-sanqiang.md`(文首或新章节) + +- [ ] **Step 1: 实现 `comps.vue`** + +对齐 Demo「组件风格」:按钮、Tag、Cell 卡、通知/空态/加载、Feedback、分段/步骤、`AttachList`。 +使用 `.comps` 相关样式:可把 Demo 中 `.comps-page` / `.comp-block` 关键到 `styles/components/comps.scss` 并在 `App.vue` import(若未建 comps.scss,本步一并创建)。 + +- [ ] **Step 2: 在 `miniprogram-ui-spec-sanqiang.md` 增加章节** + +在文档靠前位置增加: + +```markdown +## 移动工作台(mobile-h5) + +- 工程:`mobile-h5`(HBuilderX uni-app Vue3 + `@vant/weapp`) +- 视觉 Demo:`mobile-ui/zkxw-mobile-vant-ui-demo.html` +- 设计说明:`docs/superpowers/specs/2026-08-10-mobile-h5-vant-ui-design.md` +- 信息架构:单一工作台 + 权限菜单卡片;列表/详情/表单样板见 `pages/demo/*` +- Token:仍遵循本文 §2 三墙色板;**禁止**使用 web-admin `#10b981` +``` + +- [ ] **Step 3: Commit** + +```bash +git add mobile-h5/pages/demo/comps.vue mobile-h5/styles/components/comps.scss mobile-h5/App.vue docs/miniprogram-ui-spec-sanqiang.md +git commit -m "$(cat <<'EOF' +feat(mobile-h5): add component gallery and link UI spec + +EOF +)" +``` + +--- + +### Task 12: 总验收清单 + +- [ ] **Step 1: 对照 Spec §8 打勾** + +| 项 | 验收方式 | +|----|----------| +| 五种页面模式可对应 | HBuilderX 打开 index/list/detail/form/comps | +| Token 单源 | `tokens.scss` 含 `#0a9f6d`,全库 mobile-h5 无 `#10b981` 作主色 | +| Vant easycom | 页面中 `van-button` / `van-search` 可渲染 | +| HBuilderX 可运行到微信工具 | 人工确认 | +| 新页可复用 shell 类 + 组件 | 阅读 `pages/demo/list.vue` 无大段内联色值 | + +Run: + +```bash +! grep -R --include='*.vue' --include='*.scss' -n '#10b981' mobile-h5 || true +grep -R --include='*.scss' -n '#0a9f6d' mobile-h5/styles/tokens.scss +``` + +- [ ] **Step 2: 若全部通过,打 tag 或最终说明 commit(可选)** + +```bash +git status +``` + +Expected: 工作区干净或仅剩无关文件。 + +--- + +## Spec coverage(自检) + +| Spec 要求 | 对应 Task | +|-----------|-----------| +| 保留 HBuilderX 骨架 | Task 1–2(不改 main.js 结构) | +| `@vant/weapp` + easycom | Task 1–2 | +| tokens / vant-theme / app / components scss | Task 3–4 | +| 菜单权限过滤(mock) | Task 5–6、8 | +| 列表/详情/表单/组件样板 | Task 9–11 | +| 回写 miniprogram UI 规范 | Task 11 | +| 不接真实 API | 全计划无 api 联调 | +| 验收标准 §8 | Task 12 | + +## Placeholder scan + +无 TBD /「类似 Task N」式省略;关键代码与命令已写出。SCSS 细属性要求从 Demo 迁移(Task 4),执行时打开 Demo 文件对照拷贝。 + +--- + +## Execution handoff + +Plan complete and saved to `docs/superpowers/plans/2026-08-10-mobile-h5-vant-ui.md`. + +**Two execution options:** + +1. **Subagent-Driven(推荐)** — 每个 Task 开一个新子代理,Task 间人工/父代理复审,迭代快 +2. **Inline Execution** — 本会话按 executing-plans 连续执行,设检查点 + +你更倾向哪一种? diff --git a/docs/superpowers/specs/2026-08-10-mobile-h5-vant-ui-design.md b/docs/superpowers/specs/2026-08-10-mobile-h5-vant-ui-design.md new file mode 100644 index 00000000..79ef6a15 --- /dev/null +++ b/docs/superpowers/specs/2026-08-10-mobile-h5-vant-ui-design.md @@ -0,0 +1,313 @@ +# 移动端(mobile-h5)UI 设计与 Vant 整合方案 + +> 日期:2026-08-10 +> 工程:`mobile-h5`(HBuilderX 创建的 uni-app Vue3,发布微信小程序) +> 视觉 Demo:`mobile-ui/zkxw-mobile-vant-ui-demo.html` +> 相关需求:`docs/中科兴皖需求V0.3.md`(小程序端 Vue3 + vant-ui) +> 品牌 Token:对齐 `docs/miniprogram-ui-spec-sanqiang.md` 三墙色板(**非** web-admin Fresh Mint) + +--- + +## 1. 目标与约束 + +### 1.1 目标 + +1. 固化本轮 Demo 已确认的页面风格(首页 / 列表 / 详情 / 表单 / 组件合集)。 +2. 在**不改动 HBuilderX 工程骨架**(保留 `manifest.json` / `pages.json` / `main.js` / `App.vue` 等原生结构)前提下,接入 **Vant**,并建立可复用的**全局样式层**,方便后续业务页快速适配。 +3. 首页为**单一工作台**:功能菜单卡片受「菜单管理 → 移动端菜单」+ 角色/职位权限控制。 + +### 1.2 硬约束 + +| 项 | 约定 | +|----|------| +| 工程形态 | 继续使用 HBuilderX + uni-app,**不**迁移为独立 Vite CLI 工程 | +| UI 库 | Vant 体系(微信端使用 `@vant/weapp`) | +| Vue | Vue 3(`manifest.json` → `vueVersion: "3"`) | +| 主色 | `#0a9f6d` / `#087f57` / `#e9f9f2`(禁止混用 web-admin `#10b981`) | +| 发布 | HBuilderX 发行到微信小程序 | + +### 1.3 非目标(本期不做) + +- 不改造 `web-admin`。 +- 不实现完整业务 API 联调(本设计只定 UI / 样式 / 工程骨架)。 +- 不引入第二套 UI 框架(如 uView / wot 与 Vant 并存)。 + +--- + +## 2. 视觉权威与页面模式 + +### 2.1 权威文件 + +| 角色 | 路径 | +|------|------| +| 交互与视觉 Demo(本轮定稿) | `mobile-ui/zkxw-mobile-vant-ui-demo.html` | +| 品牌 Token 基线 | `docs/miniprogram-ui-spec-sanqiang.md` §2 | +| 本设计说明 | 本文档 | + +后续业务页 **SHALL** 以 Demo 中对应页面区块为准;Token **SHALL** 以三墙色板为准。 + +### 2.2 已定稿页面 + +| 模式 | Demo 入口 | 结构摘要 | +|------|-----------|----------| +| P-Home 首页工作台 | 「1. 首页」 | 绿渐变 Header → 权限菜单 4 列宫格(上 Icon 下标题)→ 待办统计卡 + 待办条目 | +| P-List 列表 | 「2. 列表」 | Hero + 内嵌搜索 → 悬浮分段筛选 → 状态着色业务卡(图标/金额或进度/操作) | +| P-Detail 详情 | 「3. 详情」 | 状态色 Hero → 指标 Dock → 分区卡片(基础信息 / Steps / 缴费 / 附件 / 流转)→ 底栏 | +| P-Form 新增编辑 | 「4. 表单」 | 绿顶栏 → `van-form` 分组 Field → 底栏取消/保存 | +| P-Comps 组件合集 | 「5. 组件」 | 按钮 / Tag / Cell / 通知空态加载 / Feedback / 分段步骤 / 附件 | + +### 2.3 首页菜单权限规则 + +1. 菜单数据来自后台「菜单管理」中 **移动端菜单** 树(`parent_id` 指向移动端根)。 +2. 登录人仅展示其角色/职位授权内的菜单。 +3. 卡片样式:**上方 Icon,下方标题**;推荐 **4 列**宫格;触达区域 ≥ 44×44。 + +--- + +## 3. 设计 Token(全局变量) + +在 uni-app 中以 **SCSS 变量 + CSS 变量** 双轨落地,业务页优先用 CSS 变量,便于运行时/主题覆盖。 + +```scss +// styles/tokens.scss(设计源) +$brand-green: #0a9f6d; +$brand-green-dark: #087f57; +$brand-green-soft: #e9f9f2; +$barley-yellow: #d6a343; +$barley-yellow-soft: #fff7e8; +$bg-page: #f5f8f7; +$surface: #ffffff; +$text-primary: #1f2a26; +$text-muted: #6b7b74; +$border: #dcebe4; +$danger: #d14343; +$warning: #cf8a19; // Demo 中部分强调用 #a67b20 / #d6a343 同族 +$success: #189b65; + +$radius-card: 14px; +$radius-lg: 20px; // Hero 下缘可用 28px +$space: 8px; // 节奏:8 / 10 / 12 / 14 / 16 +``` + +映射到页面根(`App.vue` 或 `styles/app.scss`): + +```css +page, :root { + --brand-green: #0a9f6d; + --brand-green-dark: #087f57; + --brand-green-soft: #e9f9f2; + --barley-yellow: #d6a343; + --barley-yellow-soft: #fff7e8; + --bg-page: #f5f8f7; + --surface: #ffffff; + --text-primary: #1f2a26; + --text-muted: #6b7b74; + --border: #dcebe4; + --danger: #d14343; + --warning: #cf8a19; + --success: #189b65; + --radius-card: 14rpx; /* 实现时按 rpx 换算,见 §5.3 */ + --shadow-soft: 0 8rpx 32rpx rgba(8, 127, 87, 0.08); +} +``` + +**语义状态色(列表卡 / Tag / 详情 Hero):** + +| 状态 | 主强调 | 用途 | +|------|--------|------| +| 待处理 | 琥珀 / 大麦黄 | warning 卡、Tag | +| 进行中 | 品牌绿 | primary 卡、实心 Tag | +| 异常 | `#d14343` | danger | +| 已完成 | `#189b65` | success 浅绿底 | + +--- + +## 4. Vant 整合方案(推荐) + +### 4.1 选型说明 + +| 方案 | 说明 | 结论 | +|------|------|------| +| A. `@vant/weapp` | Vant 官方微信小程序版,HBuilderX 发微信主路径最稳 | **推荐(默认)** | +| B. `vant`(Web Vue3) | 仅适合纯 H5;微信端组件不兼容 | 仅作 H5 调试补充,不作为主路径 | +| C. 其它 uni UI | 与需求「vant-ui」不符 | 不采用 | + +> 需求原文要求 vant-ui;在 uni-app → 微信小程序场景下,**`@vant/weapp` 即 Vant 在微信端的官方落地形态**。 + +### 4.2 接入步骤(不破坏 HBuilderX 骨架) + +1. 在 `mobile-h5` 目录用 HBuilderX 终端或本地 npm 安装: + ```bash + npm init -y # 若尚无 package.json + npm i @vant/weapp -S --production + ``` +2. 在 `pages.json` 配置 easycom(按官方路径): + ```json + "easycom": { + "autoscan": true, + "custom": { + "^van-(.*)": "@vant/weapp/dist/$1/index" + } + } + ``` + (若发行报路径错误,改为 `@vant/weapp/$1/index`,以本机 `node_modules/@vant/weapp` 实际目录为准。) +3. 微信小程序需在 `manifest.json` → `mp-weixin` 填入 `appid`;开发阶段可继续 `urlCheck: false`。 +4. **主题色**:在全局样式覆盖 Vant CSS 变量 / 组件自定义色(见 §5.2),主色统一为 `#0a9f6d`。 +5. 页面中按需使用:`van-button`、`van-search`、`van-field`、`van-nav-bar`、`van-tag`、`van-empty`、`van-loading`、`van-notice-bar`、`van-steps`、`van-action-sheet`、`van-dialog`、`van-toast` 等。 + +### 4.3 与自定义样式的边界 + +| 用 Vant | 用项目全局样式 / 业务组件 | +|---------|---------------------------| +| 按钮、表单 Field、导航栏、Toast/Dialog/Sheet、Steps、Empty、Loading、NoticeBar、基础 Tag | 首页菜单宫格、待办统计、列表业务卡、详情 Hero/指标 Dock、附件卡、流转时间线、分段 Chip/Seg | + +原则:**交互控件跟 Vant;业务信息架构跟 Demo 自定义类名**,避免在每个页面复制大段 CSS。 + +--- + +## 5. 全局样式怎么写(方便后续适配) + +### 5.1 推荐目录(在 `mobile-h5` 内增量,不改框架入口文件职责) + +``` +mobile-h5/ + App.vue # 引入全局样式;生命周期 + main.js # 保持 HBuilderX 默认 + pages.json + manifest.json + uni.scss # 覆盖/扩展 uni 变量(可 @import tokens) + styles/ + tokens.scss # 色板、圆角、间距(唯一 Token 源) + vant-theme.scss # Vant 主题覆盖 + mixins.scss # 渐变 Hero、卡片、安全区等 mixin + app.scss # page 背景、通用工具类 + components/ + menu-grid.scss # 首页菜单宫格 + todo.scss # 待办 + list.scss # 列表 Hero / Seg / biz-card + detail.scss # 详情 Hero / Dock / section + attach.scss # 附件上传与文件卡 + flow.scss # 流转记录 + form-shell.scss # 表单底栏等 + components/ # 可复用 Vue 组件(后续落地) + AppHero.vue + MenuGrid.vue + BizListCard.vue + AttachList.vue + FlowTimeline.vue + ... + pages/ + index/ # 工作台首页 + ... + api/ # 后续 + store/ # 后续 + utils/ +``` + +### 5.2 Vant 主题覆盖(示例) + +```scss +/* styles/vant-theme.scss */ +page { + --van-primary-color: #0a9f6d; + --van-success-color: #189b65; + --van-warning-color: #cf8a19; + --van-danger-color: #d14343; + --van-border-color: #dcebe4; + --van-background: #f5f8f7; + --van-text-color: #1f2a26; + --van-text-color-2: #6b7b74; + --van-button-primary-background: #0a9f6d; + --van-button-primary-border-color: #0a9f6d; + --van-nav-bar-background: transparent; + --van-nav-bar-title-text-color: #ffffff; + --van-nav-bar-icon-color: #ffffff; +} +``` + +`App.vue`: + +```vue + +``` + +> HBuilderX Vue3 若 `@` 别名未配置,可用相对路径 `./styles/...`,或在项目中按 uni-app 惯例配置。 + +### 5.3 rpx 适配约定 + +- Demo 以 **375 逻辑宽** 为基准(与小程序规范一致)。 +- 换算经验:`1px ≈ 2rpx`(375 设计稿)。 +- 全局样式落地时:**字号、间距、圆角、图标容器用 rpx**;`1px` 边框可用 `1rpx` 或 `0.5px`(按端表现微调)。 +- 触达高度:按钮 / 底栏主按钮 **≥ 88rpx(约 44px)**。 + +### 5.4 可复用「壳」类名(与 Demo 对齐,落地时保持稳定) + +后续新页面优先组合下列类,而不是新起一套命名: + +| 类名 / 区块 | 用途 | +|-------------|------| +| `.page-shell` + 浅绿径向背景 | 列表/详情/组件页底 | +| `.hero` / `.list-hero` / `.detail-hero` | 绿/状态色顶区 + 大圆角下缘 | +| `.filter-dock` / `.seg-tabs` | 悬浮筛选、四格分段 | +| `.biz-card.status-*` | 列表业务卡 | +| `.detail-section` + `.sec-hd` | 详情分区 | +| `.d-attach-*` / `.flow-*` | 附件、流转 | +| `.menu-grid` / `.menu-card` | 首页菜单 | +| `.form-footer` / `.detail-footer` | 底栏 | + +### 5.5 业务页适配清单(复制即用) + +新开一个业务列表页时: + +1. `pages.json` 注册路由;顶栏可用自定义 Hero,隐藏默认 navigationBar 或设透明。 +2. 结构:`hero(搜索)` → `seg-tabs` → `biz-card` 列表。 +3. 状态枚举映射到 `status-warning | status-primary | status-danger | status-success`。 +4. 主按钮仅一处实心 `type="primary"`(或项目封装的主按钮 class)。 +5. 附件、流转直接引用 `AttachList` / `FlowTimeline` 组件(落地后)。 + +--- + +## 6. 与现有文档的关系 + +1. **`docs/miniprogram-ui-spec-sanqiang.md`**:继续作为三墙 Token / 媒体比例等基线;其中旧「客户端购物车三端」Demo 与本「统一工作台」产品形态不同,**工作台信息架构以 `zkxw-mobile-vant-ui-demo.html` 为准**。 +2. 建议在 `miniprogram-ui-spec-sanqiang.md` 增加一节「移动工作台(mobile-h5)」指向 Demo + 本文档(实现阶段文档任务,可与代码一并改)。 +3. **颜色隔离**:`web-admin` 仍用 Fresh Mint;`mobile-h5` 只用三墙绿。 + +--- + +## 7. 实施顺序建议(供下一阶段 plan) + +1. `mobile-h5` 增加 `package.json` + 安装 `@vant/weapp`,配置 `pages.json` easycom。 +2. 落地 `styles/tokens.scss` + `vant-theme.scss` + `app.scss`,在 `App.vue` 引入。 +3. 抽公共组件:`MenuGrid`、`BizListCard`、`AttachList`、`FlowTimeline`。 +4. 实现首页(菜单权限 mock → 再接真实菜单 API)。 +5. 实现列表 / 详情 / 表单样板页各一,作为后续业务复制模板。 +6. 回写 `miniprogram-ui-spec-sanqiang.md` 工作台章节。 + +--- + +## 8. 验收标准 + +- [ ] Demo 中五种页面模式在文档与样式类名上可一一对应。 +- [ ] 全局 Token 仅一处定义(`tokens.scss`),Vant 主色与品牌绿一致。 +- [ ] HBuilderX 仍可正常运行到微信开发者工具 / 发行。 +- [ ] 新业务页可在不复制大段 CSS 的情况下,组合 shell + Vant 控件完成布局。 +- [ ] 不出现 web-admin `#10b981` 主色。 + +--- + +## 9. 修订记录 + +| 日期 | 说明 | +|------|------| +| 2026-08-10 | 初稿:定稿 Demo、Token、`@vant/weapp` 整合、全局样式目录与适配清单 | diff --git a/mobile-ui/zkxw-mobile-vant-ui-demo.html b/mobile-ui/zkxw-mobile-vant-ui-demo.html new file mode 100644 index 00000000..05b21886 --- /dev/null +++ b/mobile-ui/zkxw-mobile-vant-ui-demo.html @@ -0,0 +1,3676 @@ + + + + + + 中科兴皖 · 移动端 UI Demo(Vant) + + + + +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + +