|
|
@@ -0,0 +1,398 @@
|
|
|
+# 市场五模块小程序与 Web 功能对齐 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:** 让市场专员、地区经理在小程序中的预签约订单、协议单、缴费信息、催缴信息、运费信息与对应 Web 页面具备相同信息元素和允许业务能力,同时保持既有角色数据范围和移动端交互。
|
|
|
+
|
|
|
+**Architecture:** 继续使用 `mobile-oa-h5` 的共享市场页面壳,以模块契约描述筛选、卡片、详情和表单;复杂协议/预签交互使用专用组件。后端市场路由只适配 DTO 与权限,查询和写入复用现有业务 service/CRUD,并在每个入口重新验证租户、角色现场范围和业务状态。
|
|
|
+
|
|
|
+**Tech Stack:** Vue 3、Vant 4、原生 Node test runner、FastAPI、SQLAlchemy、Pydantic v2、pytest、MySQL 5.7。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 文件结构
|
|
|
+
|
|
|
+### 新建
|
|
|
+
|
|
|
+- `mobile-oa-h5/src/market/list-filters.js`:筛选默认值、请求参数和已选数量的纯函数。
|
|
|
+- `mobile-oa-h5/src/market/list-filters.test.js`:五模块筛选契约测试。
|
|
|
+- `mobile-oa-h5/src/market/components/MarketFilterSheet.vue`:移动端多条件筛选弹层。
|
|
|
+- `docs/superpowers/specs/2026-10-13-market-five-module-mobile-parity-completion.md`:最终逐项完成矩阵与环境验收清单。
|
|
|
+
|
|
|
+### 修改
|
|
|
+
|
|
|
+- `mobile-oa-h5/src/views/market/MarketModuleList.vue`:接入通用筛选弹层,移除审核 UI,增加协议批量选择/删除的移动交互。
|
|
|
+- `mobile-oa-h5/src/views/market/MarketModuleDetail.vue`:只呈现允许动作;协议、缴费、催缴跨模块跳转与刷新。
|
|
|
+- `mobile-oa-h5/src/views/market/MarketModuleForm.vue`:收敛当前协议单样本、运输、客户、缴费、转账在制改动。
|
|
|
+- `mobile-oa-h5/src/market/modules/{presign,protocol,payment-chase,payment,freight}.js`:定义完整筛选、字段、详情与动作契约。
|
|
|
+- `mobile-oa-h5/src/market/list-presenter.js`:补齐 Web 列表字段、语义标签和动作名称。
|
|
|
+- `mobile-oa-h5/src/market/action-policy.js`:删除协议审核白名单,保留明确开放动作。
|
|
|
+- `mobile-oa-h5/src/api/market.js`:删除审核映射,保留协议删除及五模块 API 封装。
|
|
|
+- `mobile-oa-h5/src/styles/market.css`:筛选弹层、批量选择、复杂卡片移动样式。
|
|
|
+- `backend/app/api/market_mobile.py`:补齐筛选 Query 参数,移除市场协议审核路由。
|
|
|
+- `backend/app/services/market_protocol.py`:协议状态、创建时间、采集时间过滤;完成当前协议 DTO/详情改动。
|
|
|
+- `backend/app/services/market_payment.py`:缴费进度、应缴日期过滤和详情字段对齐。
|
|
|
+- `backend/app/services/market_freight.py`:创建时间过滤和完整可见行字段。
|
|
|
+- `backend/app/services/market_support.py`:动作白名单、表单选项和只读详情补齐。
|
|
|
+- `backend/app/schemas/market_mobile.py`:完成协议样本/运费/缴费写 DTO。
|
|
|
+- 对应 `backend/tests/test_market_*.py` 与 `mobile-oa-h5/src/market/*.test.js`:回归和契约测试。
|
|
|
+
|
|
|
+## Task 1:收敛当前协议单在制改动与动作边界
|
|
|
+
|
|
|
+- [ ] **Step 1:把“不开放审核”写成失败测试**
|
|
|
+
|
|
|
+修改 `mobile-oa-h5/src/market/module-actions.test.js`:
|
|
|
+
|
|
|
+```js
|
|
|
+test('protocol never exposes management-only actions', () => {
|
|
|
+ const actions = moduleActions('protocol', 'specialist')
|
|
|
+ assert.deepEqual(actions, ['view', 'create', 'edit', 'delete'])
|
|
|
+ for (const denied of ['audit', 'status-change', 'refund', 'invoice', 'finance-confirm', 'finance-reject']) {
|
|
|
+ assert.equal(actions.includes(denied), false)
|
|
|
+ }
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+修改 `backend/tests/test_market_mobile_permissions.py`,断言 FastAPI 路由表不存在 `/mini/market/{role}/protocols/{protocol_id}/audit`,而 DELETE 路由存在。
|
|
|
+
|
|
|
+- [ ] **Step 2:运行测试并确认按预期失败**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/module-actions.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_mobile_permissions.py tests/test_market_protocol_api.py -q
|
|
|
+```
|
|
|
+
|
|
|
+预期:前端审核白名单或后端审核路由断言失败;已有 `test_protocol_audit_and_delete_recheck_scoped_access_before_crud` 与新边界冲突。
|
|
|
+
|
|
|
+- [ ] **Step 3:实现最小动作边界修正**
|
|
|
+
|
|
|
+- 从 `backend/app/api/market_mobile.py` 删除两个角色注册出的协议审核 endpoint。
|
|
|
+- `market_support.allowed_actions('protocol', ...)` 不再返回 `audit`。
|
|
|
+- 从 `MarketModuleList.vue` 删除审核 action sheet、状态和处理函数。
|
|
|
+- 从 `market.js` 删除协议 `audit` path 分支,只保留 `delete`。
|
|
|
+- 将旧审核 service 单测改为只验证删除的 scope 复核;Web 自身审核 API 和 service 不做删除。
|
|
|
+
|
|
|
+- [ ] **Step 4:运行协议定向测试**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/module-actions.test.js src/market/api-contract.test.js src/market/mobile-parity-ui.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_mobile_permissions.py tests/test_market_protocol_api.py tests/test_market_support_api.py -q
|
|
|
+```
|
|
|
+
|
|
|
+预期:全部通过,且不再出现“当前状态不可审核”的旧市场端测试失败。
|
|
|
+
|
|
|
+- [ ] **Step 5:提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+git add backend/app/api/market_mobile.py backend/app/services/market_support.py backend/tests/test_market_mobile_permissions.py backend/tests/test_market_protocol_api.py mobile-oa-h5/src/api/market.js mobile-oa-h5/src/market/action-policy.js mobile-oa-h5/src/market/module-actions.test.js mobile-oa-h5/src/market/api-contract.test.js mobile-oa-h5/src/market/mobile-parity-ui.test.js mobile-oa-h5/src/views/market/MarketModuleList.vue
|
|
|
+git commit -m "fix: keep mobile protocol management actions restricted to web"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 2:建立五模块通用移动筛选能力
|
|
|
+
|
|
|
+- [ ] **Step 1:新增筛选纯函数失败测试**
|
|
|
+
|
|
|
+创建 `mobile-oa-h5/src/market/list-filters.test.js`,覆盖:
|
|
|
+
|
|
|
+```js
|
|
|
+test('maps every web-equivalent filter to backend query names', () => {
|
|
|
+ assert.deepEqual(buildListParams('protocol', {
|
|
|
+ source: 'cell_storage', protocolStatus: 'sxz',
|
|
|
+ createTimeRange: ['2026-10-01', '2026-10-13'],
|
|
|
+ sampleCollectTimeRange: ['2026-09-01', '2026-09-30']
|
|
|
+ }), {
|
|
|
+ source: 'cell_storage', protocolStatus: 'sxz',
|
|
|
+ createTimeStart: '2026-10-01', createTimeEnd: '2026-10-13',
|
|
|
+ sampleCollectTimeStart: '2026-09-01', sampleCollectTimeEnd: '2026-09-30'
|
|
|
+ })
|
|
|
+ assert.deepEqual(buildListParams('payment', {
|
|
|
+ payMode: 'fq', progressStatus: 'bfyj', dueDateRange: ['2026-10-01', '2026-10-31']
|
|
|
+ }), {
|
|
|
+ payMode: 'fq', progressStatus: 'bfyj',
|
|
|
+ installmentDueDateStart: '2026-10-01', installmentDueDateEnd: '2026-10-31'
|
|
|
+ })
|
|
|
+ assert.deepEqual(buildListParams('payment-chase', { chaseType: 'overdue', payMode: 'dj' }), {
|
|
|
+ chaseType: 'overdue', payMode: 'dj'
|
|
|
+ })
|
|
|
+ assert.deepEqual(buildListParams('freight', {
|
|
|
+ transportMode: 'cold_chain', sampleSource: 'cell_storage',
|
|
|
+ createTimeRange: ['2026-10-01', '2026-10-13']
|
|
|
+ }), {
|
|
|
+ transportMode: 'cold_chain', sampleSource: 'cell_storage',
|
|
|
+ createTimeStart: '2026-10-01', createTimeEnd: '2026-10-13', includeItems: true
|
|
|
+ })
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2:运行测试并确认模块不存在**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/list-filters.test.js
|
|
|
+```
|
|
|
+
|
|
|
+预期:FAIL,`list-filters.js` 尚不存在。
|
|
|
+
|
|
|
+- [ ] **Step 3:实现纯函数和模块筛选契约**
|
|
|
+
|
|
|
+`list-filters.js` 导出 `createListFilters(module, source)`、`buildListParams(module, filters)`、`activeFilterCount(filters)`。五个模块增加 `filterFields`:
|
|
|
+
|
|
|
+```js
|
|
|
+// payment.js
|
|
|
+filterFields: [
|
|
|
+ { key: 'payMode', label: '缴费方式', type: 'select', options: PAY_MODE_OPTIONS },
|
|
|
+ { key: 'progressStatus', label: '缴费进度', type: 'select', options: PROGRESS_OPTIONS },
|
|
|
+ { key: 'dueDateRange', label: '应缴费时间', type: 'date-range' }
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+协议使用 `protocolStatus/createTimeRange/sampleCollectTimeRange`;催缴使用 `chaseType/payMode`;运费使用 `transportMode/sampleSource/createTimeRange`;预签约使用 `orderStatus`。
|
|
|
+
|
|
|
+- [ ] **Step 4:实现 `MarketFilterSheet.vue` 并接入列表**
|
|
|
+
|
|
|
+组件 props 为 `modelValue/fields/options`,事件为 `update:modelValue/apply/reset`。`MarketModuleList.vue` 保存一份草稿和一份已应用筛选;只有 Apply 才发请求,Reset 清空筛选并重新加载第一页。运输方式选项通过 `fetchMarketFormOptions` 获取。
|
|
|
+
|
|
|
+- [ ] **Step 5:运行筛选与 UI 契约测试**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/list-filters.test.js src/market/module-contracts.test.js src/market/mobile-parity-ui.test.js src/market/request-state.test.js
|
|
|
+```
|
|
|
+
|
|
|
+预期:全部通过。
|
|
|
+
|
|
|
+- [ ] **Step 6:提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+git add mobile-oa-h5/src/market/list-filters.js mobile-oa-h5/src/market/list-filters.test.js mobile-oa-h5/src/market/components/MarketFilterSheet.vue mobile-oa-h5/src/market/modules mobile-oa-h5/src/views/market/MarketModuleList.vue mobile-oa-h5/src/styles/market.css mobile-oa-h5/src/market/module-contracts.test.js mobile-oa-h5/src/market/mobile-parity-ui.test.js
|
|
|
+git commit -m "feat: add web-equivalent mobile filters for market modules"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 3:补齐后端列表筛选契约
|
|
|
+
|
|
|
+- [ ] **Step 1:先写两个角色的 API 失败测试**
|
|
|
+
|
|
|
+在现有测试中新增参数透传和真实查询断言:
|
|
|
+
|
|
|
+```python
|
|
|
+@pytest.mark.parametrize('role', ['specialist', 'manager'])
|
|
|
+def test_market_list_filters_match_web_contract(client, role, auth_headers):
|
|
|
+ cases = [
|
|
|
+ ('protocols', {'source': 'cell_storage', 'protocolStatus': 'sxz', 'createTimeStart': '2026-10-01', 'createTimeEnd': '2026-10-13'}),
|
|
|
+ ('payments', {'payMode': 'fq', 'progressStatus': 'bfyj', 'installmentDueDateStart': '2026-10-01', 'installmentDueDateEnd': '2026-10-31'}),
|
|
|
+ ('payment-chase', {'chaseType': 'overdue', 'payMode': 'fq'}),
|
|
|
+ ('freights', {'sampleSource': 'cell_storage', 'createTimeStart': '2026-10-01', 'createTimeEnd': '2026-10-13'}),
|
|
|
+ ]
|
|
|
+ for resource, params in cases:
|
|
|
+ response = client.get(f'/api/mini/market/{role}/{resource}', params=params, headers=auth_headers(role))
|
|
|
+ assert response.status_code == 200
|
|
|
+```
|
|
|
+
|
|
|
+服务层测试分别创建命中和不命中的行,并断言 `total/list` 只包含命中项。
|
|
|
+
|
|
|
+- [ ] **Step 2:运行并确认缺少 Query 参数或过滤行为**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_protocol_api.py tests/test_market_payment_api.py tests/test_market_freight_scope.py -q
|
|
|
+```
|
|
|
+
|
|
|
+预期:新增用例失败。
|
|
|
+
|
|
|
+- [ ] **Step 3:实现路由与 service 过滤**
|
|
|
+
|
|
|
+- 协议:`protocolStatus/createTimeStart/createTimeEnd/sampleCollectTimeStart/sampleCollectTimeEnd`。
|
|
|
+- 缴费:`progressStatus/installmentDueDateStart/installmentDueDateEnd`;进度按与 Web 相同的已缴/欠缴聚合口径过滤。
|
|
|
+- 运费:`createTimeStart/createTimeEnd`。
|
|
|
+- 催缴、预签约已有参数保持并补测试。
|
|
|
+- 所有日期输入解析失败返回 400,不静默扩大结果集;结束日期按当天 23:59:59 或左闭右开次日处理。
|
|
|
+
|
|
|
+- [ ] **Step 4:运行后端市场列表测试**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_presign_api.py tests/test_market_protocol_api.py tests/test_market_payment_api.py tests/test_market_freight_scope.py tests/test_market_field_scope.py -q
|
|
|
+```
|
|
|
+
|
|
|
+预期:全部通过。
|
|
|
+
|
|
|
+- [ ] **Step 5:提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+git add backend/app/api/market_mobile.py backend/app/services/market_protocol.py backend/app/services/market_payment.py backend/app/services/market_freight.py backend/tests/test_market_presign_api.py backend/tests/test_market_protocol_api.py backend/tests/test_market_payment_api.py backend/tests/test_market_freight_scope.py
|
|
|
+git commit -m "feat: align mobile market list filters with web queries"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 4:完成协议单复杂表单、详情与删除能力
|
|
|
+
|
|
|
+- [ ] **Step 1:运行当前协议相关测试,保留真实失败清单**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/protocol-*.test.js src/market/form-payload.test.js src/market/module-contracts.test.js src/market/mobile-parity-ui.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_protocol_api.py tests/test_market_support_api.py -q
|
|
|
+```
|
|
|
+
|
|
|
+当前基线:前端 176 项市场测试通过;后端协议/支撑定向测试 105 项中 1 项旧审核预期失败。Task 1 修正后,本步骤必须为全绿。
|
|
|
+
|
|
|
+- [ ] **Step 2:补写协议完整闭环失败测试**
|
|
|
+
|
|
|
+覆盖:客户档案检索与绑定、身份证出生年月联动、样本字段、运费新建/关联/取消、按样本缴费、协议总金额跟随、转账新增/编辑/提交/撤回、五类附件、只读储存证/保险/审核/状态记录、单条删除和批量删除。契约测试必须断言 §2.2 管理按钮不存在。
|
|
|
+
|
|
|
+- [ ] **Step 3:完成现有在制代码并修复失败测试**
|
|
|
+
|
|
|
+收敛以下文件中的既有改动,不重写已通过逻辑:
|
|
|
+
|
|
|
+```text
|
|
|
+backend/app/{api/market_mobile.py,schemas/market_mobile.py,services/market_protocol.py,services/market_support.py,crud/sample_freight.py}
|
|
|
+mobile-oa-h5/src/market/components/{ProtocolCustomerSearchField.vue,ProtocolSampleTransportPanel.vue,ProtocolSamplePaymentPanel.vue}
|
|
|
+mobile-oa-h5/src/market/{protocol-customer-link.js,protocol-sample-transport.js,protocol-sample-payment.js,protocol-sample-transfer.js}
|
|
|
+mobile-oa-h5/src/views/market/MarketModuleForm.vue
|
|
|
+```
|
|
|
+
|
|
|
+协议删除使用后端软删除;批量删除在移动端逐条调用已授权 DELETE,任一失败时停止并刷新列表,成功/失败数量明确展示,不新增绕过单条 scope 校验的批量后端口。
|
|
|
+
|
|
|
+- [ ] **Step 4:验证协议前后端**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/protocol-*.test.js src/market/form-payload.test.js src/market/module-contracts.test.js src/market/mobile-parity-ui.test.js
|
|
|
+cd mobile-oa-h5 && npm run build
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_protocol_api.py tests/test_market_support_api.py tests/test_market_freight_scope.py tests/test_market_payment_api.py -q
|
|
|
+```
|
|
|
+
|
|
|
+预期:全部测试和构建通过。
|
|
|
+
|
|
|
+- [ ] **Step 5:提交协议在制改动**
|
|
|
+
|
|
|
+仅添加上述协议相关文件及对应测试,不提交无关工作区文件。提交信息:
|
|
|
+
|
|
|
+```bash
|
|
|
+git commit -m "feat: complete mobile collection protocol parity for market roles"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 5:复核并补齐预签约订单
|
|
|
+
|
|
|
+- [ ] **Step 1:写缺口失败测试**
|
|
|
+
|
|
|
+在 `presign-form-view.test.js`、`presign-detail-actions.test.js`、`presign-list-model.test.js` 中断言 Web 字段全集、订单删除/转正式、五个转账动作、附件即时上传、状态锁定及返回刷新。
|
|
|
+
|
|
|
+- [ ] **Step 2:运行定向测试**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/presign/*.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_presign_api.py tests/test_market_presign_mobile_actions.py -q
|
|
|
+```
|
|
|
+
|
|
|
+现有能力若已满足则新增测试直接通过;只有失败项才进入实现。
|
|
|
+
|
|
|
+- [ ] **Step 3:按失败项最小补齐**
|
|
|
+
|
|
|
+修改范围限定在 `views/market/presign/`、`market/presign/`、`modules/presign.js`、`services/market_presign.py` 和对应测试。不得更改财务确认/拒绝边界。
|
|
|
+
|
|
|
+- [ ] **Step 4:复验并提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/presign/*.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_presign_api.py tests/test_market_presign_mobile_actions.py -q
|
|
|
+git commit -m "fix: close remaining mobile presign parity gaps"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 6:完成缴费信息与催缴信息对齐
|
|
|
+
|
|
|
+- [ ] **Step 1:写列表和详情失败测试**
|
|
|
+
|
|
|
+`list-presenter.test.js` 断言缴费卡包含 Web 基础列、6 期 × 5 列和汇总列;催缴卡包含 13 个 Web 字段及催缴状态。`module-contracts.test.js` 断言催缴可跳协议和缴费期次详情,缴费仅开放登记/编辑/提交/撤回。
|
|
|
+
|
|
|
+- [ ] **Step 2:写后端过滤及 DTO 失败测试**
|
|
|
+
|
|
|
+`test_market_payment_api.py` 创建不同进度和应缴日期的方案,验证 Web 同口径过滤,并断言每一期返回 `dueAmount/dueDate/displayPaidAmount/payDate/arrearsAmount/transfers`。
|
|
|
+
|
|
|
+- [ ] **Step 3:运行并确认失败点**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/list-presenter.test.js src/market/module-contracts.test.js src/market/module-actions.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_payment_api.py -q
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 4:实现共享期次/转账展示**
|
|
|
+
|
|
|
+补齐 `_payment_dict` 和 `_period_dict`,让列表与详情使用同一 DTO;`payment.js` 显式展示所有转账字段和状态;催缴行的“已缴金额”可进入限定 `scheduleId` 的缴费详情,“协议单”进入协议只读详情。市场端仍不提供财务确认/拒绝、退费、开票和修改应缴计划。
|
|
|
+
|
|
|
+- [ ] **Step 5:验证并提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/list-presenter.test.js src/market/module-contracts.test.js src/market/module-actions.test.js src/market/api-contract.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_payment_api.py tests/test_market_field_scope.py -q
|
|
|
+git commit -m "feat: align mobile payment and payment chase with web"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 7:完成运费信息对齐
|
|
|
+
|
|
|
+- [ ] **Step 1:写失败测试**
|
|
|
+
|
|
|
+前端断言卡片与详情包含 Web 字段、筛选包含创建时间、编辑/关联/取消关联使用后端授权。后端创建包含范围内/范围外明细的共享批次,断言列表不泄露隐藏数量或人员,批次头编辑被拒绝但可对可见样本执行关联/取消。
|
|
|
+
|
|
|
+- [ ] **Step 2:运行定向测试**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/list-presenter.test.js src/market/module-contracts.test.js src/market/form-view-lifecycle.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_freight_scope.py -q
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 3:补齐字段和交互**
|
|
|
+
|
|
|
+`freight.js` 详情补齐创建/更新时间、备注和全部可见样本卡;`MarketModuleForm.vue` 保持新增、编辑、关联、取消四种模式;取消关联从详情完整 items 选择,不依赖全局第一页。后端 `sample_freight.py` 与 `market_freight.py` 继续软删除关联行并执行锁后 scope 复核。
|
|
|
+
|
|
|
+- [ ] **Step 4:验证并提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5 && node --test src/market/list-presenter.test.js src/market/module-contracts.test.js src/market/form-view-lifecycle.test.js
|
|
|
+cd backend && venv/bin/python -m pytest tests/test_market_freight_scope.py tests/test_market_field_scope.py -q
|
|
|
+git commit -m "feat: complete mobile freight parity without scope leakage"
|
|
|
+```
|
|
|
+
|
|
|
+## Task 8:全量验证、知识图谱与完成矩阵
|
|
|
+
|
|
|
+- [ ] **Step 1:运行前端市场全量测试和构建**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd mobile-oa-h5
|
|
|
+node --test src/market/**/*.test.js src/market/*.test.js
|
|
|
+npm run build
|
|
|
+```
|
|
|
+
|
|
|
+预期:0 failed,Vite exit 0;既有 chunk 大小 warning 可记录但不能把错误当 warning 忽略。
|
|
|
+
|
|
|
+- [ ] **Step 2:运行后端市场全量测试和静态检查**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd backend
|
|
|
+venv/bin/python -m pytest tests/test_market_*.py -q
|
|
|
+venv/bin/python -m compileall -q app
|
|
|
+venv/bin/python scripts/check_field_consistency.py
|
|
|
+```
|
|
|
+
|
|
|
+预期:pytest 0 failed、compileall exit 0;字段一致性无新增 error,既有 warning 单独记录。
|
|
|
+
|
|
|
+- [ ] **Step 3:更新并验证后端知识图谱**
|
|
|
+
|
|
|
+```bash
|
|
|
+./scripts/update-graph.sh backend
|
|
|
+```
|
|
|
+
|
|
|
+检查 `backend/graphify-out/GRAPH_REPORT.md`、`graph.json` 和 manifest 已随最终源码更新。
|
|
|
+
|
|
|
+- [ ] **Step 4:运行仓库差异检查**
|
|
|
+
|
|
|
+```bash
|
|
|
+git diff --check
|
|
|
+git status --short
|
|
|
+```
|
|
|
+
|
|
|
+预期:`git diff --check` 无输出;状态中只包含本目标相关文件。
|
|
|
+
|
|
|
+- [ ] **Step 5:写完成矩阵**
|
|
|
+
|
|
|
+创建 `docs/superpowers/specs/2026-10-13-market-five-module-mobile-parity-completion.md`,逐模块列出 Web 字段、移动实现位置、后端字段来源、自动化测试证据和仍需测试环境执行的 375/390/430px 双角色验收项。不得把未执行的真实账号/微信 WebView 验收写成已通过。
|
|
|
+
|
|
|
+- [ ] **Step 6:最终提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+git add backend/graphify-out docs/superpowers/specs/2026-10-13-market-five-module-mobile-parity-completion.md
|
|
|
+git commit -m "docs: record verified mobile market parity completion"
|
|
|
+```
|