初始化本地仓库

This commit is contained in:
2026-08-31 11:33:59 +08:00
commit 663f74b633
2390 changed files with 402918 additions and 0 deletions
@@ -0,0 +1,248 @@
---
name: frontend-app-common
description: scanapp 移动端公共开发规范,基于 uni-app、Vue 和 uView Pro,覆盖页面组织、路由、组件、扫码交互、视觉字号和交付检查
globs:
- "frontend/scanapp/**/*.vue"
- "frontend/scanapp/**/*.js"
- "frontend/scanapp/pages.json"
---
## 技术基线
当前 APP 位于 `frontend/scanapp/`,使用以下技术约定:
- uni-app 页面运行模式。
- 页面采用 Vue 单文件组件(`.vue`)。
- `main.js` 注册 `@/uni_modules/uview-pro`,并注入全局主题 mixin;每个页面可直接通过 `themeMode` 获取 `light`/`dark`,根容器必须绑定 `:class="`theme-${themeMode}`"`。
- 全局主题状态由 `utils/theme.js` 管理:`applyAppTheme(mode)` 会持久化 `scanapp_theme_mode`、同步导航栏颜色并广播 `scanapp-theme-change`;设置页切换主题时必须调用它,不能只修改本页 class。
- `pages.json` 开启 uView Pro Easycom 自动组件扫描。
- uView Pro 组件使用 `u-*` 命名,例如 `u-icon`、`u-input`、`u-form`、`u-button`、`u-switch`。
- 兼容 Vue 2 和 Vue 3 入口,新增页面优先遵循现有 Options API 写法,除非项目整体迁移。
## 目录与页面组织
```text
frontend/scanapp/
├── App.vue
├── main.js
├── pages.json
├── uni.scss
├── pages/
│ ├── auth/
│ │ ├── login.vue
│ │ └── register.vue
│ ├── entry/
│ │ ├── order.vue
│ │ └── machine.vue
│ ├── exception/
│ │ └── index.vue
│ ├── repair/
│ │ ├── index.vue
│ │ └── tasks.vue
│ ├── query/
│ │ ├── index.vue
│ │ ├── index copy.vue
│ │ └── index.vue
│ ├── settings/
│ │ └── index.vue
│ ├── statistics/
│ │ └── index.vue
│ └── index/
│ └── index.vue
└── uni_modules/
```
新增页面时:
1. 页面文件放入 `pages/<module>/`。
2. 页面入口优先使用 `index.vue`,业务模式页面可使用明确名称,例如 `entry/order.vue`。
3. 必须在 `pages.json` 的 `pages` 数组中注册路由。
4. `pages.json` 中的路径不带 `.vue` 后缀,例如 `pages/settings/index`;设置模块也允许使用与路由同名的平铺页面文件,例如 `pages/settings/feedback.vue` 对应 `pages/settings/feedback`。
5. 页面导航标题通过路由项的 `style.navigationBarTitleText` 配置。
6. 不要把未注册的副本页面当作运行页面维护;例如 `index copy.vue` 不属于正式路由。
7. `pages.json` 的首项保持为 `pages/index/index`,APP 启动默认进入首页,不把登录页放在最前面。
## 页面结构规范
页面组件按以下顺序组织:
1. `<template>`:页面结构和交互绑定。
2. `<script>`:`data`、`computed`、`watch`、`methods` 和生命周期。
3. `<style lang="scss" scoped>`:页面局部样式。
页面模板建议采用以下结构:
- 页面根节点使用语义化页面类名,例如 `.settings-page`、`.query-page`、`.entry-page`。
- 页面按业务区块拆分为卡片、列表、表单和操作区域。
- 重复数据使用 `v-for`,并使用稳定的业务字段作为 `:key`。
- 交互统一使用 `@tap` 或现有组件支持的事件写法。
- 对话框、提示和扫码等平台能力统一通过 `uni.*` API 调用。
## 组件使用规范
优先使用项目已有的 uView Pro 组件,不重复实现同类基础控件:
| 场景 | 组件或能力 |
|------|------------|
| 图标 | `u-icon` |
| 文本输入 | `u-input` |
| 表单 | `u-form`、`u-form-item` |
| 按钮 | `u-button` |
| 开关 | `u-switch` |
| 空状态 | `u-empty` |
| 页面提示 | `uni.showToast` |
| 操作选择 | `uni.showActionSheet` |
| 页面跳转 | `uni.navigateTo`、`uni.navigateBack`、`uni.reLaunch` |
| 基础相机扫码 | `uni.scanCode` |
| 相册识图 / 原生扫码体验 | `@/uni_modules/mas-code-scan` 的 `openCodeScan`(仅 App-Plus) |
使用 uView Pro 组件时:
- 通过 Easycom 直接使用 `u-*` 标签,不在页面内重复注册组件。
- 沿用项目当前属性命名和事件写法。
- 按钮、输入框、表单等控件保持页面间的尺寸、圆角和状态表现一致。
- 图标使用 `u-icon`,不手写重复的 SVG 图标。
## 页面交互规范
### 页面跳转
使用 `uni` 导航 API,并与 `pages.json` 中已注册路径保持一致:
```js
uni.navigateTo({
url: '/pages/settings/index'
})
```
APP 默认允许直接进入首页和访问普通页面;登录页只在用户点击需要登录的能力时出现。需要登录的入口先检查本地登录态,未登录时使用 `uni.showModal` 提示,再跳转 `/pages/auth/login?redirect=<目标页>`;登录成功后写入登录态并使用 `uni.redirectTo` 回到 `redirect` 指定页面。普通功能页之间使用 `uni.navigateTo`。
### 扫码
基础相机扫码可使用 `uni.scanCode`:
```js
uni.scanCode({
onlyFromCamera: true,
scanType: ['barCode', 'qrCode'],
success: (res) => {
this.form.code = String(res.result || '').trim()
},
fail: () => {
uni.showToast({ title: '未完成扫码', icon: 'none' })
}
})
```
要求:
- 扫码结果先转为字符串并去除首尾空格。
- 同时支持条码和二维码时使用 `['barCode', 'qrCode']`。
- 扫码失败必须给出中文提示。
- 扫码后的结果应回填当前字段,不要跨页面隐式修改无关状态。
- 若业务需要相册识图、图片预览加载态、智能变焦或多码点选,使用 `@/uni_modules/mas-code-scan` 的 `openCodeScan`,并以 `// #ifdef APP-PLUS` 包裹导入与调用;`success` 中读取 `result.content` 后回填字段,`9021003` 视为用户取消不提示,其他错误显示中文提示。
- 有效识别区域通过 `options.scanRegion` 传给 `openCodeScan`,结构为 `fullScreen` 或 `width`、`height`、`centerX`、`centerY` 的 0~1 比例;业务页面统一调用 `@/utils/scan-settings.js` 的 `getScanRegionSetting()`,设置按 `scanapp_settings_<userCode>` 持久化。未配置时返回空对象,保持插件原有整帧识别行为。
- APP-PLUS Android 原生 `uni.showModal` 的按钮视觉顺序与 H5 不一致时,统一由 `main.js` 的平台适配层交换显示文本,并还原 `success`/Promise 的 `confirm`、`cancel` 语义;业务页面继续按标准语义编写,不要逐个页面交换按钮或回调判断。
### 表单与提示
- 提交前先执行页面级校验。
- 校验失败通过 `uni.showToast({ title, icon: 'none' })` 提示。
- 提交期间使用 `loading` 或 `submitting` 状态防止重复提交。
- 成功、失败和异常状态使用明确的中文提示。
- 原型阶段可以使用本地 mock 数据,但要保持数据结构与真实业务字段一致,并将接口接入限制在 service/API 层,不在模板中直接拼接请求。
### 接口封装
- scanapp 对接后端时统一通过 `frontend/scanapp/utils/request.js` 发起 `uni.request`,页面中不要直接调用 `uni.request`。
- 请求配置集中放在 `frontend/scanapp/config/index.js`,当前生产插件 APP 业务端默认 `baseURL` 为 `/appapi`;主项目系统 API(例如 `/file/image` 上传)实际注册在 `/api`,调用时必须显式传入 `baseURL: config.apiBaseURL`,不能沿用默认基址。
- 业务接口按模块放入 `frontend/scanapp/api/<module>/`,例如生产扫码接口放在 `api/produce/data-entry.js`。
- API 函数命名按页面语义表达,例如 `getProcessOptions`、`submitOrderRecord`、`getOrderStatistics`,页面只调用这些函数。
- 业务表单中的图片统一采用“本地预览、提交时上传”:选图后仅保存 `tempFilePaths` 用于立即预览;提交时调用 `@/api/upload.js` 的 `uploadImage(filePath, subDir)`,将返回的服务器 URL 放入业务请求。上传失败时中止提交并保留本地图片,便于用户重试。
- 图片上传使用 `/api/file/image` 和 `config.apiBaseURL`;公共 `normalizeImageUrl()` 会将后端本地存储返回的 `127.0.0.1` / `localhost` URL 改写为配置的局域网后端地址,避免 Android 真机将回环地址解析为手机自身。历史记录中的服务器图片地址也必须经过该方法规范化。
- 响应格式沿用后端 `Json::success` / `Json::fail`:`code === 0` 时默认返回 `data`,失败使用 `msg` 做中文提示。
- token 从本地 `scanapp_token` 读取并写入 `Authorization` 请求头;后续接真实登录接口时替换原型 token 来源,不改页面调用方式。
## 样式与视觉规范
### 基础单位
- 移动端尺寸统一使用 `rpx`。
- 不在同一页面混用无必要的 `px`、`rem` 和 `rpx`。
- 页面根节点设置 `min-height: 100vh`,并统一使用 `box-sizing: border-box`。
- 卡片、按钮和输入区域的尺寸应保持稳定,避免文字变化造成布局跳动。
### 字号层级
正式运行页面统一使用以下字号档位,不新增其他字号:
| 字号 | 使用场景 |
|------|----------|
| `38rpx` | 页面主标题、品牌主标题 |
| `32rpx` | 核心数据、关键数字、弹层主编号 |
| `28rpx` | 区块标题、记录主标题、主要设置项 |
| `26rpx` | 字段值、重点内容、次级编号 |
| `24rpx` | 操作文字、重要次级内容 |
| `22rpx` | 正文、按钮文字、表单标签 |
| `20rpx` | 说明文字、筛选项、辅助信息 |
| `18rpx` | 状态、时间、标签、脚注 |
字号要求:
- 最大字号不得超过 `38rpx`。
- 最小字号不得低于 `18rpx`。
- 不使用 `23rpx`、`30rpx`、`34rpx`、`36rpx`、`40rpx` 等非标准档位。
- 同一语义在不同页面使用相同字号,例如所有页面的卡片标题统一为 `28rpx`。
- 只因字号调整而产生的视觉问题,优先调整容器宽度或换行,不随意增加新的字号档位。
### 颜色与层级
沿用当前 APP 的清爽生产工具风格:
- 页面背景使用浅色中性背景,例如 `#f4f6fb`、`#f5f7fb`。
- 内容卡片使用白色背景和轻量阴影。
- 主色优先使用项目现有蓝色 `#1677ff` 或 `#2f6cf6`。
- 成功状态使用绿色,失败或危险状态使用红色,警告状态使用橙色或黄色。
- 文字颜色按主标题、正文、说明、辅助信息分级,不使用过多高饱和颜色。
- 不在单个页面引入与现有页面不一致的主题色、渐变方向或状态颜色。
### 布局一致性
- 页面内容使用统一的左右内边距和卡片间距,除非现场扫码等业务场景确实需要特殊布局。
- 卡片圆角、边框、阴影应与同类页面保持一致。
- 列表项使用分隔线或稳定卡片层级,不将多个卡片无意义地嵌套。
- 右侧操作统一使用开关、值文本、箭头或图标表达,不重复增加装饰性按钮。
- 小屏幕上长单号、商品编码等业务文本允许换行或使用 `word-break: break-all`。
- 安卓端需要控制图标、文字、开关之间的横向距离时,优先使用显式 `margin-left` / `margin-right` 或固定 `flex-shrink: 0`,不要把关键间距只交给 `gap`;涉及 `u-switch`、自定义开关和扫码结果卡片时尤其如此。
- 如果同一行里有图标+文字+开关这类组合,先确认安卓端真机表现,再决定是否保留 `gap`,默认把分离距离写在紧邻元素上。
## 状态与数据规范
- 页面临时状态放在当前页面 `data` 中;跨页面共享状态需要先确认项目是否已有 store 方案。
- 加载、空数据、提交中、成功、失败和禁用状态必须有明确表现。
- mock 数据仅用于原型展示,不应伪装成已接入后端。
- 不在本次样式任务中删除已有功能、字段、交互或路由。
- 修改中心样式或公共能力前,先搜索所有页面调用方。
## 维护与演进规则
当项目实际实现与本技能不一致时:
1. 先读取真实入口、路由、组件配置和页面调用方式。
2. 以项目代码为准,不强行套用旧模板。
3. 将已验证的新约定同步到本技能文件。
4. 技能更新只描述确认过的差异,不进行无关重写。
## 开发检查清单
- [ ] 页面文件位于 `frontend/scanapp/pages/` 合适目录。
- [ ] 新页面已注册到 `pages.json`。
- [ ] 导航路径与 `pages.json` 完全一致。
- [ ] 已复用 uView Pro 组件和现有 `uni.*` 能力。
- [ ] 扫码结果已清理空格,并处理成功和失败状态。
- [ ] 表单已处理空值、重复提交和失败提示。
- [ ] 字号只使用 `18/20/22/24/26/28/32/38rpx`。
- [ ] 页面没有超过 `38rpx` 或低于 `18rpx` 的字号。
- [ ] 同类页面的标题、正文、说明、状态字号一致。
- [ ] 未修改与需求无关的功能、数据和路由。
- [ ] 真机或移动端预览已检查长文本、空状态、弹层和底部操作区域。