FE 批次任务契约(F1~F4)与协作规程 v1.3
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# F1 · 登录页与个人页
|
||||
|
||||
> 分支:`task/f1-fe` | worktree:`G:\meida-app-f1` | 只改:`app/entry/src/main/ets/pages/LoginPage.ets`、`pages/ProfilePage.ets`(填桩)、`ets/components/f1/`(可自建)
|
||||
> 先读《README-FE批次.md》(协作规程 + ArkTS 铁律 + API 速查),严格遵守。
|
||||
|
||||
## 目标
|
||||
|
||||
登录闭环与个人中心:dev-token 登录页(含 baseUrl 设置)+ 个人页(用户信息、配额卡片、登出)。
|
||||
|
||||
## LoginPage 要求
|
||||
|
||||
1. 品牌区("美搭"标题 + 一句 slogan)+ 设备标识输入框(默认值随机生成一次并 @State 记住,可改)+「进入美搭」按钮
|
||||
2. **服务器地址设置**:折叠区("高级设置")显示当前 `AuthStore.getBaseUrl()`,可编辑保存(`setBaseUrl`)——真机连开发机靠它
|
||||
3. 登录流程:按钮 loading 态 → `AuthStore.loginByDevToken(deviceKey)` → 成功 `router.replaceUrl({url:'pages/HomePage'})`;失败 catch ApiError 展示 message+hint(错误横幅/对话框)
|
||||
4. 已登录态进入本页时 aboutToAppear 直接跳 HomePage
|
||||
|
||||
## ProfilePage 要求
|
||||
|
||||
1. 顶部:用户 ID(`AuthStore.getUserId()`,脱敏显示前 6 后 4)、登出按钮(确认弹窗 → `AuthStore.logout()` → 回 LoginPage)
|
||||
2. **配额卡片**:并行拉 `agent_chat`、`tryon`、`report_basic` 三个 `GET /api/v1/quota`(具名 interface 对齐速查结构;`reset_at` 显示"明日恢复"或日期,null=终身/月度文案区分)
|
||||
3. 进度条展示 `used/(limit_value+bonus_granted)`,剩余数大字
|
||||
4. 「最近流水」:`GET /api/v1/quota/ledger?limit=10` 列表(tx_type 中文映射:consume=消耗/refund=退还/system_grant=奖励;status 颜色区分)
|
||||
5. 下拉刷新(Refresh 组件)可加分但非必须
|
||||
|
||||
## 验收
|
||||
|
||||
1. 构建门禁 `BUILD SUCCESSFUL`(见规程 §1 命令)
|
||||
2. 无 ArkTS 铁律违规(规程 §3 逐条自查)
|
||||
3. 请求全部走 `ApiClient`/`AuthStore`(不直接碰 http)
|
||||
4. 单次提交,信息:`feat(app): login page with dev-token flow and profile with quota cards(F1)` + 正文中文说明 + 偏差说明
|
||||
@@ -0,0 +1,32 @@
|
||||
# F2 · 应用壳(Tabs)与首页
|
||||
|
||||
> 分支:`task/f2-fe` | worktree:`G:\meida-app-f2` | 只改:`app/entry/src/main/ets/pages/HomePage.ets`(填桩)、`ets/components/f2/`(自建)
|
||||
> 先读《README-FE批次.md》,严格遵守。**禁止 import 其它页面文件**(规程铁律 2)。
|
||||
|
||||
## 目标
|
||||
|
||||
应用主壳:底部 Tabs(首页/报告/AI/我的)+ 首页内容 + 两个通用组件。
|
||||
|
||||
## HomePage 要求
|
||||
|
||||
1. `@Entry @Component struct HomePage` + 底部 `Tabs`(TabContent × 4,barMode 固定四项、图标用 SymbolGlyph 或简单 Text、中文标签)
|
||||
2. **Tab1 首页**(本页实现):
|
||||
- 问候区("你好,美搭" + 日期)
|
||||
- 功能入口卡 ×2:「生成我的形象报告」「AI 穿搭顾问」——点击 `router.pushUrl({url:'pages/ReportCreatePage'})` / `'pages/ChatPage'`(路径跳转,不 import)
|
||||
- 「今日额度」小卡:`GET /api/v1/quota?quota_key=agent_chat` 显示"AI 对话剩余 N 次"(失败静默显示占位"—",不打扰首页)
|
||||
3. **Tab2 报告 / Tab4 我的**:占位内容 + 居中按钮跳 `pages/ReportCreatePage` / `pages/ProfilePage`(真页面是独立路由页;后续迭代再决定嵌组件还是跳页,本批先跳页)
|
||||
4. **Tab3 AI**:占位说明 + 跳 `pages/ChatPage` 按钮
|
||||
- 备选方案:若你能在**不 import ChatPage 文件**的前提下用 `builder` 占位则更好;做不到就跳页,别破铁律
|
||||
5. 返回键处理:Tab 页内再按返回应退出应用(onBackPress 返回 false 走默认)——不加复杂逻辑,注释说明即可
|
||||
|
||||
## 通用组件(`ets/components/f2/`)
|
||||
|
||||
1. `LoadingView`:居中 LoadingProgress + 可选文案;props 用 `@Prop`
|
||||
2. `ErrorView`:错误图标/文案 + `message` + `hint` + 「重试」按钮回调(`onRetry?: () => void`)——**这是 NFR-UX-02「失败态有原因+下一步指引」的落地组件**,其它任务后续会移用(目录带 f2 前缀,移动由协调者做)
|
||||
|
||||
## 验收
|
||||
|
||||
1. 构建门禁 `BUILD SUCCESSFUL`
|
||||
2. 四 Tab 可切换、三个跳转按钮路径正确(跳转目标页面是桩也没关系)
|
||||
3. ArkTS 铁律自查零违规;请求只走 ApiClient
|
||||
4. 单次提交:`feat(app): app shell tabs with home entries and common loading/error views(F2)`
|
||||
@@ -0,0 +1,31 @@
|
||||
# F3 · 报告流(提交 → 轮询 → 32 维结果展示)
|
||||
|
||||
> 分支:`task/f3-fe` | worktree:`G:\meida-app-f3` | 只改:`pages/ReportCreatePage.ets`、`pages/ReportResultPage.ets`(填桩)、`ets/components/f3/`(自建)
|
||||
> 先读《README-FE批次.md》,严格遵守(diagnosis 结构见其 §4,**恒 32 项、skipped 显式**)。
|
||||
|
||||
## ReportCreatePage(问卷 + 模拟照片 + 提交轮询)
|
||||
|
||||
1. **问卷表单**(必填项做前端校验):性别(单选 女/男/不便告知)、身高 cm(TextInput 数字)、体重 kg、生日(DatePicker)、核心诉求(多选:显高/显瘦/显白/显气质/遮肉/修饰肩颈,至少 1 项)、心理风格(9 型单选:戏剧/睿智/自然/古典/优雅/浪漫/前卫/少女/少年)
|
||||
2. **照片(模拟)**:TextInput 填 `photo_object_key`,输入框上方显式灰字说明"V1 骨架:COS 直传未接入,此处模拟对象键"(键格式提示 `report_photo/...jpg`;留空时自动生成 `report_photo/{userId}/{随机}.jpg`)
|
||||
3. 提交:组装 `questionnaire` Record(键名对齐:`gender,height_cm,weight_kg,birthday,core_goals[],psych_style`)+ `photo_object_key` + `request_key`(随机 hex)→ `POST /api/v1/reports`
|
||||
- 40920(本期已生成)→ 对话框提示并给「查看我的报告」按钮跳结果页(携带最近 reportId——无则提示稍后在任务中心看)
|
||||
- 成功 → 进入**轮询态**:`GET /api/v1/tasks/{task_id}` 每 3s 一次(`setInterval` 或递归 setTimeout,页面销毁清理),进度条 + stage_text 展示;SUCCEEDED → `router.replaceUrl` 结果页(params 带 reportId);FAILED → ErrorView + 重试(重新提交同 request_key 即幂等重放,注释说明)
|
||||
4. 轮询期间允许返回(清定时器)
|
||||
|
||||
## ReportResultPage(结果展示)
|
||||
|
||||
1. `GET /api/v1/reports/{id}`(reportId 从 `router.getParams()` 取)
|
||||
2. **文案区**:`result.copy.summary` + sections 渲染(title + paragraphs);`result.validation.degraded === true` 时顶部黄条提示"本报告由规则引擎直接生成"(透明化降级)
|
||||
3. **32 维诊断区**(核心):`result.diagnosis.dimensions`
|
||||
- 按 `basic_coverage` 分组思路简化为:**已分析**(status=ok)与**未覆盖**(skipped,灰色 + evidence 作为原因文案)两组
|
||||
- 每维卡片:name_cn + value(数组 join '、')+ 来源标签(中文映射:questionnaire=你填写/vision=照片分析/rule=规则推导/derived=推导/kb=知识库)+ 置信度(百分比);confidence < 0.7 加"仅供参考"小标(NFR-UX-05)
|
||||
- rule_hits 非空时折叠显示"依据规则 N 条"
|
||||
4. 顶部状态:version、status、completed_at;「重新生成」按钮 → `POST /api/v1/reports/{id}/regenerate` → 成功后拿新 task_id 回到轮询态(同页复用轮询逻辑或跳回 Create 页携带参数——选实现简单者,注释说明)
|
||||
5. 加载态 LoadingView / 失败态 ErrorView(含重试)
|
||||
|
||||
## 验收
|
||||
|
||||
1. 构建门禁 `BUILD SUCCESSFUL`
|
||||
2. 32 维渲染对空值/skipped/数组 value/低置信度四种形态都有处理(本地构造假数据自查 UI 分支,不依赖后端也能看——用临时默认 @State 假数据再删,提交里不留假数据)
|
||||
3. 轮询有清理、40920/FAILED/降级三条异常路径有 UI
|
||||
4. 单次提交:`feat(app): report flow with polling and 32-dimension result view(F3)`
|
||||
@@ -0,0 +1,23 @@
|
||||
# F4 · AI 穿搭对话页
|
||||
|
||||
> 分支:`task/f4-fe` | worktree:`G:\meida-app-f4` | 只改:`pages/ChatPage.ets`(填桩)、`ets/components/f4/`(自建)
|
||||
> 先读《README-FE批次.md》,严格遵守(chat 响应结构见其 §4)。
|
||||
|
||||
## ChatPage 要求
|
||||
|
||||
1. **消息列表**:`@State messages: ChatMsg[]`(本地内存态,V1 不做会话持久化——后端 ag_conversation 属后续任务,注释说明);List + ForEach 渲染,气泡样式区分用户/AI(左右对齐 + 配色)
|
||||
2. `ChatMsg` 具名 interface:`{role: 'user'|'ai', text: string, meta?: string}`(meta 存"模型 · 耗时"小字)
|
||||
3. **发送流程**:底部输入框(TextInput,回车/按钮发送)→ push 用户消息 → AI 侧显示"正在思考…"占位气泡 → `POST /api/v1/agent/chat` `{message}` → 成功替换为 reply,meta 拼接 `{model} · {latency_ms}ms`,并在顶部薄条更新 `quota_remaining`("今日剩余 N 次")
|
||||
4. **失败态**(只 catch ApiError):
|
||||
- 40301(额度用尽):AI 气泡位显示 e.message(后端文案无价格字样)+ e.hint 次行小字;输入框保留可重试
|
||||
- 60003(今日服务上限)/ 其它:同样气泡位展示 message+hint;"正在思考…"占位必须撤掉
|
||||
5. 发送中禁用输入框防连点;空消息不发送
|
||||
6. 顶部栏:标题"AI 穿搭顾问" + 返回(router.back)
|
||||
7. 首次进入自动插入一条 AI 欢迎语(本地静态文案,不调接口):"你好,我是你的穿搭顾问,可以问我面试怎么穿、约会怎么搭~"
|
||||
|
||||
## 验收
|
||||
|
||||
1. 构建门禁 `BUILD SUCCESSFUL`
|
||||
2. 发送/思考/成功/四种失败展示(40301、60003、网络错)路径齐全;思考占位在失败时一定被撤掉
|
||||
3. ArkTS 铁律零违规;只走 ApiClient;无第三方依赖
|
||||
4. 单次提交:`feat(app): AI chat page with quota hint and error states(F4)`
|
||||
@@ -0,0 +1,52 @@
|
||||
# FE 批次·多 Agent 协作规程(第五批 F1~F4)
|
||||
|
||||
> 版本:v1.3 | 2026-08-15 | 适用:**鸿蒙 FE 批次(F1~F4)**——仓库是 Windows 侧 `G:\meida`(本仓库),工程在 `app/`。后端仓库的规程(v1.2)仍适用其后端任务,不适用本批。
|
||||
> **每个 agent 开工前必须先读本文件,再读自己的任务文档。**
|
||||
|
||||
## 1. 环境操作手册(纯 Windows,无 WSL)
|
||||
|
||||
| 任务 | worktree | 分支 |
|
||||
| --- | --- | --- |
|
||||
| F1 | `G:\meida-app-f1` | `task/f1-fe` |
|
||||
| F2 | `G:\meida-app-f2` | `task/f2-fe` |
|
||||
| F3 | `G:\meida-app-f3` | `task/f3-fe` |
|
||||
| F4 | `G:\meida-app-f4` | `task/f4-fe` |
|
||||
|
||||
- 读写文件:Read/Write/Edit 工具直接用 Windows 路径(如 `G:\meida-app-f1\app\entry\src\main\ets\pages\...`)
|
||||
- **构建门禁(唯一验收命令)**:
|
||||
```
|
||||
cd G:/meida-app-f1/app && export DEVECO_SDK_HOME="C:/Program Files/Huawei/DevEco Studio/sdk" && "C:/Program Files/Huawei/DevEco Studio/tools/node/node.exe" "C:/Program Files/Huawei/DevEco Studio/tools/hvigor/bin/hvigorw.js" --mode module -p module=entry@default assembleHap --analyze=false --daemon=false
|
||||
```
|
||||
(把 f1 换成你的编号;`BUILD SUCCESSFUL` = 通过。未签名 WARN 正常忽略。)
|
||||
|
||||
## 2. 冲突隔离铁律
|
||||
|
||||
1. **只改自己任务文档允许的文件**。`app/entry/src/main/ets/core/**`、`module.json5`、`main_pages.json`、`app/README.md`、`oh-package*.json5`、`hvigor*` 全部禁改(core 已就绪,路由已全注册)。
|
||||
2. **页面间跳转一律 `router.pushUrl({ url: 'pages/XxxPage' })`**,**禁止 import 其它页面文件**——七个页面都已注册,按路径跳不需要 import,这是本批零冲突的根本。
|
||||
3. 组件复用:在自己页面文件内声明 `@Component`;确实通用的放 `ets/components/<你的任务名>/`(如 `components/f2/`),**目录名带任务前缀**。
|
||||
4. 不引任何第三方 ohpm 包;不动 resources(字符串/颜色硬编码,i18n 后置)。
|
||||
5. 提交:构建绿后**单次提交**(信息格式见任务文档),禁止 push、禁止切分支。
|
||||
|
||||
## 3. ArkTS 严格模式铁律(协调者实测踩坑,违反必炸编译)
|
||||
|
||||
1. **泛型调用必须显式类型参数**:`ApiClient.post<void>(...)`、`ApiClient.get<MyResp>(...)`——裸 `post(...)` 直接报 `arkts-no-inferred-generic-params`
|
||||
2. **请求体用具型 Record 字面量**:`const req: Record<string, Object> = { 'k': v }`——不允许 interface→Record 强转(无索引签名)、不允许内联对象类型 `{a:string}(...)` 做泛型参数
|
||||
3. **wire 响应类型用具名 interface**(文件内声明,字段名对齐后端 JSON),`resp.result as ApiEnvelope<T>` 之后再 `data` 层转具体类型
|
||||
4. **throw 只抛 ApiError**:catch 里 `if (e instanceof ApiError) throw e`,未知异常包 `new ApiError(50000, '请求失败,请检查网络', '请稍后重试')`
|
||||
5. **对象字面量必须有具名声明的对应类型**(Record/接口/class 皆可,裸字面量赋 var 会报错);async 逻辑放**具名方法**而不是复杂箭头链(泛型推断限制)
|
||||
6. UI 惯例:`@Entry @Component struct XxxPage`、`@State` 状态、`aboutToAppear` 里 async 初始化(用 `.then` 或 fire-and-forget + `@State` 驱动刷新)、异常只 catch `ApiError` 展示 `e.message + e.hint`
|
||||
|
||||
## 4. 后端 API 速查(baseUrl 默认 `http://127.0.0.1:8000`,信封 `{code,message,data,hint}`)
|
||||
|
||||
- 登录:`POST /api/v1/auth/dev-token` `{device_key}` → `{access_token,refresh_token,expires_in,refresh_expires_in,user_id}`(AuthStore 已封装)
|
||||
- 配额:`GET /api/v1/quota?quota_key=agent_chat|tryon|...` → `{quota_key,used,limit_value,bonus_granted,remaining,reset_at}`
|
||||
- 流水:`GET /api/v1/quota/ledger?limit=20` → `[{tx_id,delta,tx_type,status,quota_key,balance_after,created_at}]`
|
||||
- 对话:`POST /api/v1/agent/chat` `{message}` → `{reply,provider,model,prompt_id,prompt_version,call_id,usage{tokens_in,tokens_out,tokens_cached,latency_ms,cost_cents},quota_remaining}`
|
||||
- 任务:`GET /api/v1/tasks/{id}` → `{task_id,status,progress,stage_text,...}`(status: PENDING/RUNNING/SUCCEEDED/FAILED)
|
||||
- 报告:`POST /api/v1/reports` `{questionnaire:{...},photo_object_key,request_key?}` → `{report_id,task_id,status,version}`;`GET /api/v1/reports/{id}` → `{report_id,status,version,result{vision,diagnosis,copy,validation},created_at,completed_at}`;`POST /api/v1/reports/{id}/regenerate` `{request_key?}`
|
||||
- diagnosis 结构:`{dimensions:[{number,key,name_cn,value,confidence,source,evidence,rule_hits,status}](恒 32 项), coverage:{basic_full,total}}`;copy:`{summary,sections:[{title,paragraphs[]}],model,...}`;validation:`{passed,degraded?,checks{pejorative,absolute,consistency}}`
|
||||
- 常见错误码:40100 未登录 / 40301 额度用尽(文案已无价格字样)/ 40920 本期报告已生成 / 60003 AI 服务今日上限 / 50003 配置异常
|
||||
|
||||
## 5. 运行验证说明(agent 不做)
|
||||
|
||||
构建绿即可提交;真机/模拟器运行由用户在 DevEco Studio 里做(连本机后端:模拟器 127.0.0.1 直连,真机改登录页 baseUrl 为开发机局域网 IP)。
|
||||
Reference in New Issue
Block a user