diff --git a/README.md b/README.md index 87918e4..92bda21 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [一期文档](一期/README.md):一期范围、开发进度和头程订单最小闭环。 - [二期文档](二期/README.md):预约取货、到仓收货、实测差异和指定库位闭环。 - [三期文档](三期/README.md):智能排柜、订舱、拖车、PDA 拣货、报关协同和国内出仓闭环。 +- [独立任务协作登记](独立任务协作登记.md):登记独立 Codex 任务 ID,并作为总控下发、通信和汇总的唯一寻址索引。 ## 跨阶段参考 diff --git a/墨家设备测量上传接口说明-V3.md b/墨家设备测量上传接口说明-V3.md index 480990c..c8adf9a 100644 --- a/墨家设备测量上传接口说明-V3.md +++ b/墨家设备测量上传接口说明-V3.md @@ -8,7 +8,7 @@ 墨家设备扫描当前箱上的两张标签并上传测量结果: - 柏悦唛头二维码,扫描结果作为 `boxCode`; -- 客户从 Amazon FBA 下载并贴在箱上的 FBA 标签,扫描其中的 Shipment ID,作为 `shipment_id`。 +- 如果当前箱贴有客户从 Amazon FBA 下载的 FBA 标签,则扫描其中的 Shipment ID,作为 `shipment_id`;非 FBA 货物可以不传。 每次请求对应一次设备测量,不需要传订单内部字段,也不需要关心柏悦后续如何处理数据。 @@ -20,7 +20,7 @@ PCHK2608040174#19-1 设备不需要解析或修改 `boxCode`。 -`shipment_id` 不是柏悦生成的内容,也不能从 `boxCode` 推导。设备必须从当前箱的 Amazon FBA 标签实际扫描并原样上传。 +`shipment_id` 不是柏悦生成的内容,也不能从 `boxCode` 推导。当前箱存在 Amazon FBA 标签时,设备应实际扫描并原样上传;不存在时可以省略或传空字符串。 ## 2. 接口地址 @@ -63,7 +63,7 @@ POST /openapi/v1/inbound-measurements | 字段 | 必填 | 说明 | |---|---|---| | `boxCode` | 是 | 扫描得到的唛头二维码文本,必须原样传输 | -| `shipment_id` | 是 | 从当前箱 Amazon FBA 标签实际扫描得到的 Shipment ID,必须原样传输;兼容字段名 `shipmentId` | +| `shipment_id` | 否 | 当前箱存在 Amazon FBA 标签时,上传实际扫描得到的 Shipment ID;非 FBA 货物可省略或传空;兼容字段名 `shipmentId` | | `length` | 是 | 当前箱长度,单位 cm | | `width` | 是 | 当前箱宽度,单位 cm | | `height` | 是 | 当前箱高度,单位 cm | @@ -91,13 +91,13 @@ data:image/jpeg;base64, 网络超时或未收到响应时,设备可以重试同一次上传。当前按 `boxCode` 保存最新结果,同一个箱号重试不会新增多条当前记录。 -同一个 `boxCode` 后续再次上传时,以最新一次设备上传的测量结果和实扫 `shipment_id` 为准,设备无需额外传版本号。 +同一个 `boxCode` 后续再次上传时,以最新一次设备上传的测量结果为准;本次传了 `shipment_id` 则保存实扫值,未传则保存为空。设备无需额外传版本号。 ## 7. 待墨家确认 -1. 是否可以同时扫描柏悦唛头和 Amazon FBA 标签,并分别上传 `boxCode`、`shipment_id`。 +1. 当前箱存在 Amazon FBA 标签时,是否可以同时扫描柏悦唛头和 Amazon FBA 标签,并分别上传 `boxCode`、`shipment_id`。 2. `boxCode` 是否可以原样上传完整二维码文本,例如 `PCHK2608040174#19-1`。 -3. `shipment_id` 是否可以原样上传,例如 `FBA19L5KMY2CU000002`。 +3. 有 Amazon FBA 标签时,`shipment_id` 是否可以原样上传,例如 `FBA19L5KMY2CU000002`;非 FBA 货物允许不传。 4. `picture` 是否可以按 `data:image/jpeg;base64,...` 格式上传。 5. `weight` 的单位、精度和是否必传。 6. `machineNo` 是否每台机器固定且唯一。 diff --git a/独立任务协作登记.md b/独立任务协作登记.md new file mode 100644 index 0000000..3732d0f --- /dev/null +++ b/独立任务协作登记.md @@ -0,0 +1,39 @@ +# 独立任务协作登记 + +> 本表只登记用户可独立打开和查看的 Codex 任务/对话,不登记子代理。任务 ID 是唯一寻址键,名称只是展示标签。 + +## 登记规则 + +- 独立任务创建成功并获得平台返回的稳定 ID 后,立即登记;没有稳定 ID 不得写入临时名称或自行生成替代 ID。 +- 总控下发、追问、催办、读取、汇总和关闭任务时,一律使用 `task_id`/平台返回的任务 ID;不得根据任务名称、主题相似度或创建顺序寻址。 +- 下发前先按范围、模块和状态检索本表;已有可复用任务时继续向该 ID 通信,不重复创建独立任务。 +- 任务名称可以修改,`task_id` 不得复用、改写或转给另一项工作。任务完成后保留记录并标记 `completed`,不要删除历史 ID。 +- 跨任务共享契约由总控记录在登记表备注中;独立任务回复必须带回自身 `task_id`、状态、变更文件、验证结果和阻断项,便于按 ID 汇总。 + +## 状态值 + +`planned`、`active`、`blocked`、`completed`、`archived`。 + +## 当前登记 + +| task_id | display_name | scope | owner | status | worktree/branch | last_update | notes | +|---|---|---|---|---|---|---|---| +| 019feb17-b5de-7d63-a0e4-5a8c2181e323 | PDA 后端 S0500 修复 | `baiyue-firstleg/firstleg` PDA 拣货事务、库位结算和相关测试 | 三期总控 | active | 后端 `test` | 2026-08-11 | 当前发布阻断;已部署 3bfc11a 后仍需继续定位第二个真实 S0500 | +| 019feb17-c56c-7e02-8f9c-0b74f960df34 | 三期验收 fixture 审计 | `baiyue-firstleg/scripts/admin-test-env-modules` | 三期总控 | completed | 后端 `test` | 2026-08-10 | 无代码变更;确认 fixture 顺序和真实失败级联正确 | +| 019feb17-d3c2-7480-802a-498db11c7d3c | Admin 装柜清单页面 | `apps/admin-web` 智能装柜、预装清单、装柜清单 | 三期总控 | completed | Admin `release/test` | 2026-08-10 | b593d72 已推送并部署,8/8 定向、typecheck、build 通过 | +| 019feb2a-419b-7161-8174-5aed7e84a047 | PDA 原子批量提交契约 | PDA 后端 Controller/DTO/OpenAPI/调用方只读契约梳理 | 三期总控 | completed | 后端 `test` | 2026-08-10 | 只读阶段完成;等待 S0500 修复后进入实现 | +| 019feb29-ef52-7f83-96d7-42d963d2ae34 | PDA uni-app 前端验收 | `apps/pda-uniapp` 登录、领取、广播扫码、设备草稿、批量提交、证据和真实 API 映射 | 三期总控 | active | PDA 当前工作区 | 2026-08-11 | 只读验收;必须区分代码/Node 测试与 HBuilderX/Android 真机验证 | + +## 通信与汇总格式 + +总控下发消息至少包含: + +```text +task_id: <已登记 ID> +目标: <单一交付目标> +范围: <目录/模块> +共享契约: <依赖的接口、模型或文件> +回传: <状态、变更文件、验证命令/结果、阻断项> +``` + +汇总时按 `task_id` 聚合,不按 display_name 聚合;同一 ID 的最新状态覆盖旧状态,但保留重要阻断和验证记录。 diff --git a/财务管理/openapi/finance-f1-manual-v1.yaml b/财务管理/openapi/finance-f1-manual-v1.yaml index 5ee9203..b7479d6 100644 --- a/财务管理/openapi/finance-f1-manual-v1.yaml +++ b/财务管理/openapi/finance-f1-manual-v1.yaml @@ -6,18 +6,31 @@ info: servers: - url: /api paths: + /platform/finance/v1/customers/{tenantId}/terms: + get: + summary: 查询客户账期 + x-permission: platform:finance:customer-terms:view + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/TenantId'}] + responses: {'200': {$ref: '#/components/responses/SuccessObject'}, '403': {$ref: '#/components/responses/BusinessError'}} + put: + summary: 保存客户账期 + x-permission: platform:finance:customer-terms:update + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CustomerTermsRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessObject'}, '403': {$ref: '#/components/responses/BusinessError'}} /platform/finance/v1/bills: get: summary: 查询平台账单 + x-permission: platform:finance:bill:view security: [{platformFinance: []}] parameters: - - {$ref: '#/components/parameters/CustomerId'} - - {name: status, in: query, schema: {$ref: '#/components/schemas/BillStatus'}} - - {name: page, in: query, schema: {type: integer, minimum: 1, default: 1}} - - {name: pageSize, in: query, schema: {type: integer, minimum: 1, maximum: 100, default: 20}} - responses: {'200': {$ref: '#/components/responses/SuccessPage'}} + - {$ref: '#/components/parameters/RequiredCustomerId'} + responses: {'200': {$ref: '#/components/responses/SuccessList'}} post: summary: 创建账单草稿 + x-permission: platform:finance:bill:create security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateBillRequest'}}}} @@ -25,11 +38,13 @@ paths: /platform/finance/v1/bills/{billId}: get: summary: 查询平台账单详情 + x-permission: platform:finance:bill:view security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/BillId'}] responses: {'200': {$ref: '#/components/responses/SuccessBill'}} put: summary: 更新账单草稿 + x-permission: platform:finance:bill:update security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/UpdateBillRequest'}}}} @@ -37,6 +52,7 @@ paths: /platform/finance/v1/bills/{billId}/issue: post: summary: 出账并冻结账单 + x-permission: platform:finance:bill:issue security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/VersionRequest'}}}} @@ -44,6 +60,7 @@ paths: /platform/finance/v1/bills/{billId}/adjust: post: summary: 出账后调整并生成新版本 + x-permission: platform:finance:bill:adjust security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/AdjustBillRequest'}}}} @@ -51,6 +68,7 @@ paths: /platform/finance/v1/bills/{billId}/void: post: summary: 作废账单 + x-permission: platform:finance:bill:void security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ReasonRequest'}}}} @@ -58,73 +76,92 @@ paths: /platform/finance/v1/receipts: post: summary: 人工登记收款并分配账单 + x-permission: platform:finance:receipt:create security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateReceiptRequest'}}}} responses: {'200': {$ref: '#/components/responses/SuccessReceipt'}} get: summary: 查询收款记录 + x-permission: platform:finance:receipt:view security: [{platformFinance: []}] - responses: {'200': {$ref: '#/components/responses/SuccessPage'}} + parameters: [{$ref: '#/components/parameters/OptionalCustomerId'}] + responses: {'200': {$ref: '#/components/responses/SuccessList'}} /platform/finance/v1/cost-entries: post: summary: 人工登记单票或整柜成本 + x-permission: platform:finance:cost:create security: [{platformFinance: []}] parameters: [{$ref: '#/components/parameters/IdempotencyKey'}] requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateCostRequest'}}}} responses: {'200': {$ref: '#/components/responses/SuccessCost'}} get: summary: 查询成本记录 + x-permission: platform:finance:cost:view security: [{platformFinance: []}] - responses: {'200': {$ref: '#/components/responses/SuccessPage'}} + parameters: [{$ref: '#/components/parameters/OptionalCustomerId'}] + responses: {'200': {$ref: '#/components/responses/SuccessList'}} /client/finance/v1/bills: get: summary: 客户只读查询账单 + x-permission: merchant:finance:statement:list security: [{customerFinanceRead: []}] - responses: {'200': {$ref: '#/components/responses/SuccessPage'}, '403': {$ref: '#/components/responses/BusinessError'}} + responses: {'200': {$ref: '#/components/responses/SuccessList'}, '403': {$ref: '#/components/responses/BusinessError'}} /client/finance/v1/bills/{billId}: get: summary: 客户只读查看账单详情 + x-permission: merchant:finance:statement:view security: [{customerFinanceRead: []}] parameters: [{$ref: '#/components/parameters/BillId'}] responses: {'200': {$ref: '#/components/responses/SuccessBill'}, '403': {$ref: '#/components/responses/BusinessError'}} /client/finance/v1/receipts: get: summary: 客户只读查询收款记录 + x-permission: merchant:finance:statement:view security: [{customerFinanceRead: []}] - responses: {'200': {$ref: '#/components/responses/SuccessPage'}, '403': {$ref: '#/components/responses/BusinessError'}} + responses: {'200': {$ref: '#/components/responses/SuccessList'}, '403': {$ref: '#/components/responses/BusinessError'}} components: securitySchemes: platformFinance: {type: http, scheme: bearer} customerFinanceRead: {type: http, scheme: bearer} parameters: BillId: {name: billId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}} - CustomerId: {name: customerId, in: query, required: false, schema: {type: string, pattern: '^[1-9][0-9]*$'}} + TenantId: {name: tenantId, in: path, required: true, description: 后端兼容字段,对应产品中的客户 ID, schema: {type: string, pattern: '^[1-9][0-9]*$'}} + RequiredCustomerId: {name: customerId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}} + OptionalCustomerId: {name: customerId, in: query, required: false, schema: {type: string, pattern: '^[1-9][0-9]*$'}} IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}} schemas: + CustomerTermsRequest: + type: object + required: [creditDays] + properties: + customerName: {type: string, maxLength: 200, description: 客户名称快照;未传时由服务端按客户主数据补齐} + creditDays: {type: integer, minimum: 0, maximum: 3650, default: 30, description: 自然日账期} CreateBillRequest: type: object required: [customerId, billDate, lines] properties: - customerId: {type: string} + customerId: {type: string, pattern: '^[1-9][0-9]*$'} billDate: {type: string, format: date} lines: {type: array, minItems: 1, items: {$ref: '#/components/schemas/BillLineInput'}} UpdateBillRequest: - allOf: - - {$ref: '#/components/schemas/CreateBillRequest'} - - type: object - required: [expectedVersion] - properties: {expectedVersion: {type: integer, minimum: 0}} + type: object + required: [customerId, billDate, expectedVersion, lines] + properties: + customerId: {type: string, pattern: '^[1-9][0-9]*$'} + billDate: {type: string, format: date} + expectedVersion: {type: integer, minimum: 0} + lines: {type: array, minItems: 1, items: {$ref: '#/components/schemas/BillLineInput'}} BillLineInput: type: object required: [sourceFeeId, sourceFeeVersion, amount] properties: - sourceFeeId: {type: string} + sourceFeeId: {type: string, pattern: '^[1-9][0-9]*$'} sourceFeeVersion: {type: integer, minimum: 1} - orderId: {type: string} - inboundId: {type: string} + orderId: {type: string, pattern: '^[1-9][0-9]*$'} + inboundId: {type: string, pattern: '^[1-9][0-9]*$'} feeItemName: {type: string} - amount: {type: number, format: double, minimum: 0} + amount: {type: number, minimum: 0, multipleOf: 0.000001} VersionRequest: type: object required: [expectedVersion] @@ -145,9 +182,9 @@ components: type: object required: [customerId, receivedDate, amount, paymentMethod, voucherFileIds, allocations] properties: - customerId: {type: string} + customerId: {type: string, pattern: '^[1-9][0-9]*$'} receivedDate: {type: string, format: date} - amount: {type: number, format: double, minimum: 0, exclusiveMinimum: true} + amount: {type: number, minimum: 0, exclusiveMinimum: true, multipleOf: 0.000001} currency: {type: string, enum: [CNY], default: CNY} paymentMethod: {type: string, enum: [BANK_TRANSFER, CASH, OTHER]} voucherFileIds: {type: array, minItems: 1, items: {type: string}} @@ -168,17 +205,19 @@ components: type: object required: [billId, amount] properties: - billId: {type: string} - amount: {type: number, format: double, minimum: 0, exclusiveMinimum: true} + billId: {type: string, pattern: '^[1-9][0-9]*$'} + amount: {type: number, minimum: 0, exclusiveMinimum: true, multipleOf: 0.000001} CreateCostRequest: type: object - required: [costType, amount, expenseName, voucherFileIds] + description: SINGLE_ORDER 必须提供 orderId;CONTAINER_SHARED 必须提供 containerId,并按柜内有效票体积分摊。 + required: [customerId, costType, amount, expenseName, voucherFileIds] properties: + customerId: {type: string, pattern: '^[1-9][0-9]*$'} costType: {type: string, enum: [SINGLE_ORDER, CONTAINER_SHARED]} - orderId: {type: string} - containerId: {type: string} + orderId: {type: string, pattern: '^[1-9][0-9]*$'} + containerId: {type: string, pattern: '^[1-9][0-9]*$'} expenseName: {type: string, minLength: 1, maxLength: 100} - amount: {type: number, format: double, minimum: 0, exclusiveMinimum: true} + amount: {type: number, minimum: 0, exclusiveMinimum: true, multipleOf: 0.000001} currency: {type: string, enum: [CNY], default: CNY} voucherFileIds: {type: array, minItems: 1, items: {type: string}} remark: {type: string, maxLength: 500} @@ -191,6 +230,14 @@ components: message: {type: string} data: {type: object, additionalProperties: true} requestId: {type: string} + ApiListEnvelope: + type: object + required: [code, message, data] + properties: + code: {type: string, example: '200'} + message: {type: string} + data: {type: array, items: {type: object, additionalProperties: true}} + requestId: {type: string} ErrorEnvelope: type: object required: [code, message] @@ -199,5 +246,6 @@ components: SuccessBill: {description: Bill result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} SuccessReceipt: {description: Receipt result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} SuccessCost: {description: Cost result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} - SuccessPage: {description: Paged result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} + SuccessObject: {description: Object result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} + SuccessList: {description: Non-paged list result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiListEnvelope'}}}} BusinessError: {description: Business error, content: {application/json: {schema: {$ref: '#/components/schemas/ErrorEnvelope'}}}}