weaver-work-cli 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -30
- package/dist/cmd/root.js +1 -0
- package/dist/core/runtime-agent.js +19 -0
- package/dist/internal/e10/auth/commands.js +47 -27
- package/dist/internal/e10/auth/xiaoe.js +62 -43
- package/dist/internal/e10/context.js +5 -27
- package/dist/shortcuts/archive-oa/constants.js +66 -0
- package/dist/shortcuts/archive-oa/continuation.js +70 -0
- package/dist/shortcuts/archive-oa/errors.js +53 -0
- package/dist/shortcuts/archive-oa/host.js +157 -0
- package/dist/shortcuts/archive-oa/index.js +225 -0
- package/dist/shortcuts/archive-oa/manifest.js +62 -0
- package/dist/shortcuts/archive-oa/operations/borrow-car.js +159 -0
- package/dist/shortcuts/archive-oa/operations/borrow-url.js +108 -0
- package/dist/shortcuts/archive-oa/operations/confirm.js +48 -0
- package/dist/shortcuts/archive-oa/operations/contract.js +120 -0
- package/dist/shortcuts/archive-oa/operations/locate.js +50 -0
- package/dist/shortcuts/archive-oa/operations/registry.js +40 -0
- package/dist/shortcuts/archive-oa/operations/shared.js +181 -0
- package/dist/shortcuts/archive-oa/operations/types.js +45 -0
- package/dist/shortcuts/archive-oa/operations.js +13 -0
- package/dist/shortcuts/index.js +2 -0
- package/dist/shortcuts/invoice/host.js +2 -1
- package/dist/shortcuts/invoice/manifest.js +111 -0
- package/dist/shortcuts/invoice/operations/issuing-qys.js +361 -0
- package/dist/shortcuts/invoice/operations/issuing.js +5 -5
- package/dist/shortcuts/invoice/operations/registry.js +4 -0
- package/dist/shortcuts/workflow/endpoints.js +11 -0
- package/dist/shortcuts/workflow/host.js +2 -2
- package/dist/shortcuts/workflow/index.js +6 -36
- package/dist/shortcuts/workflow/operations/chatscene.js +270 -0
- package/dist/shortcuts/workflow/operations/form.js +899 -158
- package/dist/shortcuts/workflow/operations/read.js +111 -6
- package/dist/shortcuts/workflow/operations/sign-input.js +106 -0
- package/dist/shortcuts/workflow/operations/write.js +9 -1
- package/dist/shortcuts/workflow/stdout-compact.js +9 -1
- package/docs/archive-oa.md +79 -0
- package/docs/e10-auth.md +7 -6
- package/package.json +1 -1
- package/skill-template/business-info.json +16 -0
- package/skill-template/domains/archive-oa.md +19 -0
- package/skill-template/domains/yepiaotong.md +2 -2
- package/skills/weaver-e10-archive-oa/SKILL.md +159 -0
- package/skills/weaver-e10-archive-oa/references/archive-locate.md +49 -0
- package/skills/weaver-e10-archive-oa/references/borrow-car.md +76 -0
- package/skills/weaver-e10-archive-oa/references/borrow-flow.md +53 -0
- package/skills/weaver-e10-archive-oa/references/contract-search.md +63 -0
- package/skills/weaver-e10-archive-oa/references/disabled-capabilities.md +29 -0
- package/skills/weaver-e10-archive-oa/references/qys-contract-search.md +47 -0
- package/skills/weaver-e10-archive-oa/references/source-manifest.json +400 -0
- package/skills/weaver-e10-builder/SKILL.md +22 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +37 -15
- package/skills/weaver-e10-caizhilian/references/agent-entry.md +7 -3
- package/skills/weaver-e10-caizhilian/references/collaboration.md +5 -3
- package/skills/weaver-e10-caizhilian/references/document.md +33 -11
- package/skills/weaver-e10-caizhilian/references/file-collection.md +4 -3
- package/skills/weaver-e10-caizhilian/references/file-upload.md +2 -3
- package/skills/weaver-e10-caizhilian/references/files.md +9 -3
- package/skills/weaver-e10-caizhilian/references/folder.md +48 -16
- package/skills/weaver-e10-caizhilian/references/setting-attach.md +13 -39
- package/skills/weaver-e10-caizhilian/references/setting-backup.md +13 -51
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +20 -51
- package/skills/weaver-e10-caizhilian/references/setting-storage.md +82 -147
- package/skills/weaver-e10-caizhilian/references/withheld.md +20 -44
- package/skills/weaver-e10-shared/SKILL.md +22 -20
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +14 -15
- package/skills/weaver-e10-shared/references/non-interactive-environment.md +10 -10
- package/skills/weaver-e10-workflow/references/source-manifest.json +32 -22
- package/skills/weaver-e10-workflow/references/workflow-create.md +68 -28
- package/skills/weaver-e10-yepiaotong/SKILL.md +10 -7
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +49 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-qys-ledger.md +66 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +59 -36
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +54 -509
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +182 -345
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -5
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +153 -345
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +5 -5
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +182 -154
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +96 -0
- package/skills/weaver-e10-yepiaotong/references/reim-fast-path.md +0 -119
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 报销表单填值规则(对接 `workflow.createRequest`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
本文档定义如何根据发票数据、事前申请数据和 `workflow.createForm` 返回的字段清单,组装 `workflow.createRequest` 的 `data`。
|
|
4
4
|
|
|
5
5
|
> **⚠️ 数据完整性规则适用于本文档所有操作,详见 [reim-workflow.md 顶部](reim-workflow.md#️️️-最高优先级规则严禁篡改任何原始数据值-️️️)。**
|
|
6
|
+
> 报销单的创建与修改统一走 `weaver-e10-workflow` 技能的发起/修改能力,命令契约、返回处置以 [`../../weaver-e10-workflow/references/workflow-create.md`](../../weaver-e10-workflow/references/workflow-create.md) 为准;本文档只规定**报销业务字段填什么值**。
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
@@ -10,62 +11,43 @@
|
|
|
10
11
|
|
|
11
12
|
```json
|
|
12
13
|
{
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"dataIndex": 1,
|
|
23
|
-
"subFormId": "明细表ID",
|
|
24
|
-
"invoiceId": "对应发票ID",
|
|
25
|
-
"fields": [
|
|
26
|
-
{"fieldId": "xxx", "value": "值或ID", "fieldName": "字段名"},
|
|
27
|
-
{"fieldId": "xxx", "optionValue": "选项值", "fieldName": "字段名"}
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
"need_user_confirm": [
|
|
32
|
-
{
|
|
33
|
-
"fieldId": "xxx",
|
|
34
|
-
"fieldName": "字段名",
|
|
35
|
-
"dataIndex": null,
|
|
36
|
-
"reason": "模糊搜索返回多个候选",
|
|
37
|
-
"candidates": [{"id": "xxx", "name": "xxx"}]
|
|
38
|
-
}
|
|
39
|
-
],
|
|
40
|
-
"unable_to_fill": [
|
|
41
|
-
{
|
|
42
|
-
"fieldId": "xxx",
|
|
43
|
-
"fieldName": "字段名",
|
|
44
|
-
"reason": "无法填写的原因"
|
|
45
|
-
}
|
|
46
|
-
]
|
|
14
|
+
"main": {
|
|
15
|
+
"<主表字段id>": "<值>"
|
|
16
|
+
},
|
|
17
|
+
"details": {
|
|
18
|
+
"<费用明细 subFormId>": [
|
|
19
|
+
{"<明细字段id>": "<值>"},
|
|
20
|
+
{"<明细字段id>": "<值>"}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
47
23
|
}
|
|
48
24
|
```
|
|
49
25
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
26
|
+
- **键只能取 `workflow.createForm` 返回的 `fields[].id`**:按 `fields[].name` 定位业务字段,取它的 `id`;明细字段的 `subFormId` 就是 `details` 的键。
|
|
27
|
+
- **`fields` 里没有的字段一律不传**:`fields` 只下发可写字段。实报金额、人民币金额、附件数、报销人上级、承担人直接上级、承担人所有上级、人员ID、提单人员、报销总金额等由表单自身计算或联动带出,不在可写清单里,传了整单会被拒(`notEditable`)。
|
|
28
|
+
- **带 `initialValue` 的字段默认不传**:CLI 会自动并入表单默认值;只有本文档规则要求的值与默认值不同,或用户本次明确改写时才传。**例外:明细「币种」每行必传**(见「费用明细字段规则」)。
|
|
29
|
+
- `details` 每个数组元素是一行明细,**顺序 = 明细行顺序**,一张发票一行。
|
|
30
|
+
- 流程标题用 `createRequest` 的 `requestName` 参数传(见下方「流程标题」)。
|
|
53
31
|
|
|
54
|
-
|
|
32
|
+
---
|
|
55
33
|
|
|
56
|
-
|
|
34
|
+
## 值的写法(按 `componentKey`)
|
|
57
35
|
|
|
58
|
-
|
|
|
59
|
-
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
36
|
+
| componentKey | 值写法 | 示例 |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `Text` / `TextArea` | 文本字符串,**禁止包含 `*` 号** | `"仁济医院南院-浦江瑞和城"` |
|
|
39
|
+
| `DateComponent` | `yyyy-MM-dd`(CLI 会按字段格式归一化) | `"2026-07-30"` |
|
|
40
|
+
| `NumberComponent` / `Money` | 数字字符串,原样使用发票金额 | `"108.2"` |
|
|
41
|
+
| `Select` | **选项名称**(不是 optionValue) | `"银行(个人报销)"` |
|
|
42
|
+
| `Employee` / `Department` / `RelateBrowser` / `Ebuilder` / `Workflow` 等浏览按钮(`isBrowser`) | **`名称(ID)`**;只有名称没有 ID 时传名称(多个说法用英文逗号并列) | `"交通费-管理费用(100502270000000173)"` |
|
|
43
|
+
| `EinvoiceComponent`(`isEinvoice`) | **发票对象数组**,对象取自 `invoice.browse-field.data`;**每个发票字段只放 1 个对象** | `[{"optionId":"1295366637717012482","id":"1295366637717012482","fid":"1295366637717012482", "...":"..."}]` |
|
|
63
44
|
|
|
64
|
-
|
|
45
|
+
> **浏览按钮不支持裸 ID**:只写数字会被当名称去查,查不到就是 `NOT_FOUND`。上下文已有 ID 时一律写成 `名称(ID)`,括号内是纯数字时 CLI 直接按 ID 用。
|
|
46
|
+
> **发票字段不能传文本或裸 ID**:必须先用 `invoice.browse-field.data` 按 `fids` 批量取对象,再按行放进对应字段。
|
|
65
47
|
|
|
66
|
-
|
|
48
|
+
---
|
|
67
49
|
|
|
68
|
-
|
|
50
|
+
## 流程标题(`requestName`)
|
|
69
51
|
|
|
70
52
|
| 场景 | 格式 | 示例 |
|
|
71
53
|
|------|------|------|
|
|
@@ -73,47 +55,20 @@
|
|
|
73
55
|
| 无事前申请 | `{费用类型汇总}报销-{用户名}-{日期}(共N笔)` | `"交通费+住宿费报销-张三-2026-08-04(共3笔)"` |
|
|
74
56
|
| 单张发票 | `{费用类型}报销-{用户名}-{日期}` | `"交通费报销-张三-2026-08-04"` |
|
|
75
57
|
|
|
76
|
-
-
|
|
77
|
-
- N = 明细行总数(发票数量)
|
|
58
|
+
- 日期使用当前日期;N = 明细行总数(发票数量)
|
|
78
59
|
- 从事前申请标题中提取核心关键词(去掉"申请"后缀)
|
|
79
60
|
- 标题不超过 30 个字
|
|
61
|
+
- 用户名取 `createForm` 返回的「申请人」默认值(即当前用户)
|
|
80
62
|
|
|
81
63
|
---
|
|
82
64
|
|
|
83
|
-
##
|
|
84
|
-
|
|
85
|
-
来自 `invoice.reim.form.structure` 返回的 `mainFields`,逐个字段推断值。
|
|
65
|
+
## 明细行前置处理
|
|
86
66
|
|
|
87
|
-
|
|
67
|
+
### 1. 过滤红冲发票
|
|
88
68
|
|
|
89
|
-
|
|
90
|
-
{"fieldId": "xxx", "value": "值或ID", "fieldName": "字段名称"}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
或(Select 下拉选项型):
|
|
94
|
-
|
|
95
|
-
```json
|
|
96
|
-
{"fieldId": "xxx", "optionValue": "选项值", "fieldName": "字段名称"}
|
|
97
|
-
```
|
|
69
|
+
获取到发票列表后,**必须先过滤掉全额红冲发票**(`info.comm_info.pro.status == 8`),这类发票不允许报销。
|
|
98
70
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## detail_rows 填充规则
|
|
104
|
-
|
|
105
|
-
来自 `invoice.reim.form.structure` 返回的明细表列表 `subTables`。**不要机械取 `subTables[0]`** —— 部分流程(如总部费用报销 `100003460000000060`)返回多个明细表,`subTables[0]` 可能是「外包订单」等其他表。
|
|
106
|
-
|
|
107
|
-
- **必须先定位「费用明细」表**:优先按名称匹配(总部费用报销的「费用明细」`subFormId` = `100003690000000011`,排在 `subTables` 第 3 位);名称拿不准时,取含 `EinvoiceComponent` 类型字段、且字段构成符合费用行(金额/日期/费用说明/相关发票)的明细表
|
|
108
|
-
- **只填写定位到的「费用明细」表的字段,其他明细表(外包订单等)不用填值**
|
|
109
|
-
- `dataIndex` 从 1 开始递增
|
|
110
|
-
- `subFormId` = 费用明细表自身的 `subFormId`(按上面的定位结果取,**不是** `subTables[0].subFormId`)
|
|
111
|
-
|
|
112
|
-
### 过滤红冲发票(前置处理第一步)
|
|
113
|
-
|
|
114
|
-
获取到发票列表后,**必须先过滤掉全额红冲发票**(`info.comm_info.pro.status == 8`),这类发票不允许报销。过滤后的发票才进入后续分类。
|
|
115
|
-
|
|
116
|
-
### 发票与相关凭证分类(前置处理第二步)
|
|
71
|
+
### 2. 发票与相关凭证分类
|
|
117
72
|
|
|
118
73
|
过滤后的发票列表,**按 `invoiceTypeCode`(即 `info.comm_info.pro.type`)分类**,再组装明细行。
|
|
119
74
|
|
|
@@ -121,238 +76,96 @@
|
|
|
121
76
|
|
|
122
77
|
| 分类 | invoiceTypeCode | 示例 | 填单行为 |
|
|
123
78
|
|------|-----------------|------|----------|
|
|
124
|
-
| **发票** | 除 17/18/57/58 以外 | 增值税发票(1/2/3/4)、电子发票(28/32/33)、火车票(12/47)、出租车发票(9) 等 | 每张发票 =
|
|
125
|
-
| **相关凭证** | 17, 18, 57, 58 | 小票/水单(17)、滴滴行程单(18)、支付凭证(57)、其他票据凭证(58) |
|
|
79
|
+
| **发票** | 除 17/18/57/58 以外 | 增值税发票(1/2/3/4)、电子发票(28/32/33)、火车票(12/47)、出租车发票(9) 等 | 每张发票 = 一行明细,放「相关发票」 |
|
|
80
|
+
| **相关凭证** | 17, 18, 57, 58 | 小票/水单(17)、滴滴行程单(18)、支付凭证(57)、其他票据凭证(58) | **不能独立成行**,放进配对发票那一行的「相关凭证」 |
|
|
126
81
|
|
|
127
82
|
> **注意区分**:type=18 是滴滴的支付行程凭证(不能独立成行);滴滴开具的增值税电子普通发票 type=3,是正式发票,可独立成行。
|
|
128
83
|
|
|
129
|
-
###
|
|
130
|
-
|
|
131
|
-
相关凭证必须找到对应的发票,配对后放入同一行明细。
|
|
132
|
-
|
|
133
|
-
> **⚠️ 前提条件:相关凭证的金额不能比对应发票的金额大(凭证 `amount` ≤ 发票 `amount`),不满足此条件的不能配对。**
|
|
84
|
+
### 3. 凭证与发票配对
|
|
134
85
|
|
|
135
|
-
|
|
86
|
+
| 来源优先级 | 规则 |
|
|
87
|
+
|------------|------|
|
|
88
|
+
| 1. `invoice.reim.row-info` 返回的 `itinerary` | 有值就直接作为该行的配对凭证,**替代下面的 AI 配对** |
|
|
89
|
+
| 2. AI 配对 | 凭证 `amount` ≤ 发票 `amount`(前提,不满足不能配对)→ 金额一致或接近 → 开票日期前后 7 天内 → 销方相同或同一平台 → 费用类型同类 |
|
|
136
90
|
|
|
137
|
-
1
|
|
138
|
-
|
|
139
|
-
3. **销方匹配**:凭证 `sellerName` 与发票 `sellerName` 相同或相关(如同一交通平台)
|
|
140
|
-
4. **费用类型匹配**:凭证 `expenseType` 与发票 `expenseType` 同属一类
|
|
91
|
+
- **每行最多挂 1 张凭证**:「相关凭证」字段只接受 1 个发票对象(传多个会返回 `MULTIPLICITY` 歧义)。`itinerary` 逗号分隔返回多个时,按上面 AI 配对的优先级选最匹配的 1 张,其余在确认预览里列为「未挂上的凭证」提示用户。
|
|
92
|
+
- 凭证找不到可配对的发票 → 跳过该凭证(不单独成行),并在确认预览里提示用户。
|
|
141
93
|
|
|
142
|
-
|
|
94
|
+
### 4. 取发票对象
|
|
143
95
|
|
|
144
|
-
|
|
96
|
+
把所有入选发票和配对凭证的 `fid` 一次传给 `invoice.browse-field.data`(`{"fids":[...]}`),按 `fid` 把返回对象放进对应行:
|
|
145
97
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
|
149
|
-
|
|
150
|
-
| **相关发票** | `EinvoiceComponent` | `false` | 发票的 `invoiceId`(**必填**) |
|
|
151
|
-
| **相关凭证** | `EinvoiceComponent` | `true` | 配对凭证的 `invoiceId`(**有则必填,无则不填**) |
|
|
152
|
-
|
|
153
|
-
### 填值规则
|
|
154
|
-
|
|
155
|
-
| 场景 | 相关发票(single=false) | 相关凭证(single=true) |
|
|
156
|
-
|------|------------------------|----------------------|
|
|
157
|
-
| 发票有配对凭证 | 发票的 `invoiceId` | 凭证的 `invoiceId`(**必填**) |
|
|
158
|
-
| 发票无配对凭证 | 发票的 `invoiceId` | **不填此字段** |
|
|
159
|
-
|
|
160
|
-
### 示例:有配对凭证
|
|
161
|
-
|
|
162
|
-
```json
|
|
163
|
-
{
|
|
164
|
-
"dataIndex": 1,
|
|
165
|
-
"subFormId": "100003690000000011",
|
|
166
|
-
"invoiceId": "1298798990831517697",
|
|
167
|
-
"fields": [
|
|
168
|
-
{"fieldId": "100003720000000228", "value": "100.0", "fieldName": "实报金额"},
|
|
169
|
-
{"fieldId": "100003720000000419", "value": "2026-07-29", "fieldName": "费用日期"},
|
|
170
|
-
{"fieldId": "100003720000052200", "value": "100001050000000001", "fieldName": "币种"},
|
|
171
|
-
{"fieldId": "100003720000077896", "value": "1298798990831517697", "fieldName": "相关发票"},
|
|
172
|
-
{"fieldId": "100003720000077897", "value": "1298798990831518001", "fieldName": "相关凭证"}
|
|
173
|
-
]
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### 示例:无配对凭证(只填相关发票,不填相关凭证)
|
|
178
|
-
|
|
179
|
-
```json
|
|
180
|
-
{
|
|
181
|
-
"dataIndex": 1,
|
|
182
|
-
"subFormId": "100003690000000011",
|
|
183
|
-
"invoiceId": "1298798990831517697",
|
|
184
|
-
"fields": [
|
|
185
|
-
{"fieldId": "100003720000000228", "value": "100.0", "fieldName": "实报金额"},
|
|
186
|
-
{"fieldId": "100003720000000419", "value": "2026-07-29", "fieldName": "费用日期"},
|
|
187
|
-
{"fieldId": "100003720000052200", "value": "100001050000000001", "fieldName": "币种"},
|
|
188
|
-
{"fieldId": "100003720000077896", "value": "1298798990831517697", "fieldName": "相关发票"}
|
|
189
|
-
]
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### invoiceId 必须出现的位置
|
|
194
|
-
|
|
195
|
-
> 1. `detail_rows` 的顶层 `invoiceId` 字段 — 填发票(非凭证)的 ID
|
|
196
|
-
> 2. `fields` 中 `EinvoiceComponent`+`single=false` 的字段 — 填发票的 `invoiceId`(必填)
|
|
197
|
-
> 3. `fields` 中 `EinvoiceComponent`+`single=true` 的字段 — 有配对凭证时填凭证的 `invoiceId`,无凭证则不填
|
|
198
|
-
>
|
|
199
|
-
> 位置 1 和 2 必须有值,位置 3 仅在有配对凭证时才填!
|
|
98
|
+
| 明细字段 | 值 |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| 相关发票(`EinvoiceComponent`) | `[该行发票的对象]`(**必填**) |
|
|
101
|
+
| 相关凭证(`EinvoiceComponent`) | `[配对凭证的对象]`;**无凭证则不传此字段** |
|
|
200
102
|
|
|
201
103
|
---
|
|
202
104
|
|
|
203
|
-
##
|
|
204
|
-
|
|
205
|
-
### 策略1:marked=false 且有 options(下拉选项型)
|
|
206
|
-
|
|
207
|
-
从 `options` 列表中选择最匹配的 `optionValue`,用 `optionValue` 字段输出。
|
|
105
|
+
## 主表字段规则
|
|
208
106
|
|
|
209
|
-
|
|
210
|
-
输入:fieldName="报销方式", options=[{optionName:"银行(个人报销)",optionValue:"7"}, ...]
|
|
211
|
-
推断:默认选"银行(个人报销)" → optionValue = "7"
|
|
212
|
-
输出:{"fieldId":"xxx", "optionValue":"7", "fieldName":"报销方式"}
|
|
213
|
-
```
|
|
107
|
+
按 `fields[].name` 关键词匹配;没有出现在 `fields` 里的字段直接跳过。
|
|
214
108
|
|
|
215
|
-
|
|
109
|
+
| fieldName 关键词 | 怎么填 |
|
|
110
|
+
|------------------|--------|
|
|
111
|
+
| 承担主体 | **用户给了合同号 → 不传,以合同联动为准**(见下方)。否则为**当前用户**:表单默认带出当前用户时**不传**;`fields` 里该字段没有 `initialValue` 时填 `{currentEmployee.name}({currentEmployee.id})`(来自 `invoice.reim.employee-superiors`)。不能留空 |
|
|
112
|
+
| 申请人 / 报销人 / 提单人员 | 同上:默认带出当前用户时不传 |
|
|
113
|
+
| 部门 / 报销部门 | 默认带出时不传 |
|
|
114
|
+
| 报销人直接上级 / 报销人上级 / 承担人直接上级 | 默认带出时不传;没有默认值时填 `{directSuperior.name}({directSuperior.id})`(**不是 `allSuperiors[0]`**) |
|
|
115
|
+
| 承担人所有上级 | 可写且没有默认值时填 `allSuperiors` 每项的 `名称(ID)` 组成的数组;不在 `fields` 里就不传 |
|
|
116
|
+
| **合同号 / 合同编号** | **固定 `"20260999"`**(共享常量)。表单默认值已是 `20260999` 时不传;默认值为空或不同时显式传 `"20260999"`;**用户当次明确给出别的合同号时传用户的,并按下方「用户给了合同号:以合同联动为准」处理承担主体 / 相关客户 / 相关项目** |
|
|
117
|
+
| 报销方式 | 默认「银行(个人报销)」;表单默认值已是它时不传,否则传选项名 `"银行(个人报销)"` |
|
|
118
|
+
| 报销事由 / 摘要 | AI 生成:`"{日期} {费用类型} - {销方简称}"`,**禁止包含 `*` 号** |
|
|
119
|
+
| 事前申请流程 / 相关流程(主表) | 有匹配到的事前申请时填 `{requestname}({requestid})`;无则不传 |
|
|
120
|
+
| **相关客户** | **用户给了合同号 → 不传,以合同联动为准**(见下方)。否则:**非出差**:固定 `"泛微上海(100504500000311504)"`。**出差流程**:填用户提供的客户名称(可带多个写法,英文逗号分隔),由 CLI 解析,见下方「出差流程相关客户」 |
|
|
121
|
+
| 相关项目 | **用户给了合同号 → 不传,以合同联动为准**。否则:事前申请 `requestnametitle` 里「相关项目:」有值时填该名称;否则不传 |
|
|
122
|
+
| 费用承担公司 | 用户说了才填;否则按 `workflow-create.md`「历史流程数据参考规则」判断(历史取值一致可采用);仍定不了就不传,交给 `missingFields` |
|
|
123
|
+
| 申请日期 / 报销日期 | 默认带出时不传;没有默认值时填当天 `yyyy-MM-dd` |
|
|
124
|
+
| 附件 / 抄送人 | 用户本次给了才填(附件按 `workflow-create.md` 的上传口径),否则不传 |
|
|
125
|
+
| 申请金额 / 人民币金额(主表,可写时) | 默认所有**发票**(不含凭证)`amount` 之和;话费报销为各行实报金额之和 |
|
|
216
126
|
|
|
217
|
-
|
|
127
|
+
> **以下字段在报销单里绝不能是空值**:承担主体、报销人上级/承担人直接上级/承担人所有上级、合同号、相关客户、每行费用类型(科目)。它们要么由表单默认值带出,要么按上表显式传;若 `createRequest` 仍在 `missingFields` 里列出它们,按上表来源补上后用同一 `context` 重发,**不要问用户要 ID**。
|
|
218
128
|
|
|
219
|
-
|
|
129
|
+
### 用户给了合同号:以合同联动为准
|
|
220
130
|
|
|
221
|
-
|
|
222
|
-
|-----------|------------|------|
|
|
223
|
-
| DateComponent | yyyy-MM-dd | `"2026-08-04"` |
|
|
224
|
-
| Text | 文本字符串 | `"差旅报销说明"` |
|
|
225
|
-
| TextArea | 文本字符串 | `"2026-07-31 交通费 - 滴滴出行"` |
|
|
226
|
-
| Money | 数字字符串 | `"108.20"` |
|
|
227
|
-
| NumberComponent | 数字字符串 | `"1"` |
|
|
131
|
+
总部费用报销的「合同号」配置了字段联动:合同号一变,表单按合同重算**承担主体、相关客户、相关项目**(以及承担人直接上级 / 部门、费用承担机构)。联动结果会覆盖 `data` 里同名字段的值,**包括用户明确指定的值**。
|
|
228
132
|
|
|
229
|
-
|
|
133
|
+
用户当次给出了不同于 `20260999` 的合同号时:
|
|
230
134
|
|
|
231
|
-
|
|
135
|
+
1. 传用户的合同号;**承担主体、相关客户、相关项目都不传**,交给合同联动带出——即使用户同时口头指定了承担主体,也以合同联动为准(不传,不在创建后改回)。
|
|
136
|
+
2. 「相关客户」不再套用非出差固定值「泛微上海」;出差流程也不再要求用户另报客户(合同联动带出的客户即具体客户)。
|
|
137
|
+
3. 预览里这三项写「由合同 {合同号} 联动带出」,不要写成用户口述的值或默认值。
|
|
138
|
+
4. 创建后从返回的 `linkageResult`(「字段联动带出:…」)读出实际带出的承担主体 / 相关客户 / 相关项目告诉用户;用户口头指定的承担主体与联动结果不同时,一句话说明「已按合同联动为准」。
|
|
139
|
+
5. 联动没带出某一项(`linkageResult` 里没有、或 `missingFields` 列出)→ 该项回到上表的常规规则补值,用同一 `context` 重发(已创建的单子走 `workflow.edit*` 补)。
|
|
232
140
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
来源(上下文已有 ID):
|
|
236
|
-
|
|
237
|
-
| 字段 | ID 来源 | 是否必填 |
|
|
238
|
-
|------|---------|----------|
|
|
239
|
-
| 报销人/申请人/提单人员/人员ID | 事前申请的 `creatorId`,或当前用户 ID | 有数据就填 |
|
|
240
|
-
| 部门/报销部门/部门ID/承担人部门 | 事前申请的 `creatorDepartmentId`,或当前用户部门 ID | 有数据就填 |
|
|
241
|
-
| 相关流程/事前申请 | 事前申请的 `requestid` | 有数据就填 |
|
|
242
|
-
| **承担主体** | **当前用户 ID(`creatorId`)** | **⚠️ 必填,永远不能为空** |
|
|
243
|
-
| **报销人上级** | **`invoice.reim.employee-superiors` 返回的 `directSuperior.id`(直接上级 ID,直接赋值;取值口径见 [reim-workflow.md](reim-workflow.md#报销共享常量所有-reference-统一引用本节))** | **⚠️ 必填,永远不能为空** |
|
|
244
|
-
| **承担人直接上级** | **`invoice.reim.employee-superiors` 返回的 `directSuperior.id`(直接上级 ID,直接赋值;取值口径见 [reim-workflow.md](reim-workflow.md#报销共享常量所有-reference-统一引用本节))** | **⚠️ 必填,永远不能为空** |
|
|
245
|
-
| **承担人所有上级** | **`invoice.reim.employee-superiors` 返回的 `allSuperiors` 所有 `id` 用逗号拼接(如 `"id1,id2,id3"`)** | **⚠️ 必填,永远不能为空** |
|
|
246
|
-
| **费用类型(科目)** | **优先 `invoice.reim.row-info` 返回的 `subjectId`;为空时按 [expense-subject-rules.md](reim-expense-subject-rules.md) 匹配,匹配不到用兜底 `"100502270000000104"`** | **⚠️ 必填,永远不能为空** |
|
|
247
|
-
| 相关发票 | `invoiceId` | 必填 |
|
|
248
|
-
| **相关客户(主表)** | **非出差**:固定值 `"100504500000311504"`(泛微上海);**出差流程**:必须由用户提供具体客户,见下方「出差流程相关客户」 | **⚠️ 必填;出差流程未提供则不允许报销** |
|
|
249
|
-
| 币种 | 固定 `"100001050000000001"`(人民币) | 必填 |
|
|
250
|
-
| 上下文中找不到 ID 的其他字段 | 放入 `unable_to_fill` | — |
|
|
251
|
-
|
|
252
|
-
> **⚠️ 以下字段绝不放入 `unable_to_fill`,必须有值:**
|
|
253
|
-
> - **费用类型(科目)**:按科目匹配规则匹配,所有策略都无法匹配时用兜底科目 `"100502270000000104"`(其他-管理费用)
|
|
254
|
-
> - **相关客户(非出差)**:固定填 `"100504500000311504"`(泛微上海)
|
|
255
|
-
> - **相关客户(出差流程)**:必须由用户提供具体客户后再填,未提供则**暂停且不允许调用 `invoice.reim.flow.create.prepare/apply`**,不能用固定值顶替
|
|
256
|
-
> - **合同编号**:固定填 `"20260999"`,不需要从其他来源提取
|
|
257
|
-
> - **承担主体**:使用当前用户 ID(`creatorId`)
|
|
258
|
-
> - **报销人上级**:`invoice.reim.employee-superiors` 返回的 `directSuperior.id`
|
|
259
|
-
> - **承担人直接上级**:`invoice.reim.employee-superiors` 返回的 `directSuperior.id`
|
|
260
|
-
> - **承担人所有上级**:`invoice.reim.employee-superiors` 返回的 `allSuperiors` 所有 `id` 用逗号拼接
|
|
261
|
-
|
|
262
|
-
### 出差流程相关客户(硬拦截)
|
|
263
|
-
|
|
264
|
-
> **出差报销必须由用户填写具体相关客户。未提供则不允许报销,禁止调用 `invoice.reim.flow.create.prepare/apply`。**
|
|
265
|
-
|
|
266
|
-
**如何判断是出差流程(满足任一即可):**
|
|
267
|
-
|
|
268
|
-
| 判断依据 | 条件 |
|
|
269
|
-
|----------|------|
|
|
270
|
-
| 报销工作流名称 `workFlowName` | 含「差旅」或「出差」 |
|
|
271
|
-
| 事前申请名称 `requestname` | 含「出差」或「差旅」 |
|
|
272
|
-
| 用户表述 | 明确说「出差报销」「差旅报销」 |
|
|
273
|
-
|
|
274
|
-
**填单规则:**
|
|
275
|
-
|
|
276
|
-
| 流程类型 | 相关客户怎么填 | 未提供时 |
|
|
277
|
-
|----------|----------------|----------|
|
|
278
|
-
| **出差 / 差旅** | 暂停询问用户具体客户名称;用户给出后用 `invoice.reim.field.search` 搜索 ID,唯一结果直接填,多候选让用户选 | **不允许报销**,不创建报销单 |
|
|
279
|
-
| **非出差** | 固定填 `"100504500000311504"`(泛微上海) | 不适用 |
|
|
280
|
-
|
|
281
|
-
**出差流程操作步骤:**
|
|
141
|
+
---
|
|
282
142
|
|
|
283
|
-
|
|
284
|
-
2. 明确提醒用户:「当前为出差报销,必须填写相关客户。请提供具体客户名称,否则无法继续报销。」
|
|
285
|
-
3. 用户给出客户名称 → 调用 `invoice.reim.field.search` 搜索 ID → 填入主表和明细表的「相关客户」字段
|
|
286
|
-
4. 用户拒绝、取消、或不提供具体客户 → **结束报销流程,禁止调用 `invoice.reim.flow.create.prepare/apply`**
|
|
287
|
-
5. **禁止**用固定值 `"100504500000311504"` 顶替出差的相关客户
|
|
288
|
-
6. **禁止**把出差相关客户放入 `unable_to_fill` 后继续创建报销单
|
|
143
|
+
## 费用明细字段规则
|
|
289
144
|
|
|
290
|
-
|
|
145
|
+
> **定位明细表**:用 `fields` 里带「相关发票」(`EinvoiceComponent`)字段的那个 `subFormId`,只填这一张明细表;其他明细表(外包订单等)不填。
|
|
146
|
+
> 标注「`row-info` 优先」的字段:先取 `invoice.reim.row-info`(多张用 `invoice.reim.row-info-batch`)的返回值,为空/null 时才回退。
|
|
291
147
|
|
|
292
|
-
|
|
148
|
+
| fieldName 关键词 | 怎么填 |
|
|
149
|
+
|------------------|--------|
|
|
150
|
+
| 费用日期 / 发生日期 | **`row-info` 优先**:`date`;回退发票 `invoiceDate` |
|
|
151
|
+
| **申请金额 / 实报金额 / 报销金额 / 人民币金额 / 含税金额**(凡可写的金额字段) | 该行发票 `amount`;**话费报销**改填 [reim-phone-subsidy-rules.md](reim-phone-subsidy-rules.md) 算出的实报金额 |
|
|
152
|
+
| 费用说明 / 摘要 | **交通类**:只填 `{出发地精简}-{目的地精简}`;**其他**:`row-info` 优先 `fysm`,回退从 `consumeContent` 提取。**必须去掉所有 `*` 号,不能包含逗号** |
|
|
153
|
+
| **费用类型(科目)** | **`row-info` 优先**:`{subjectName}({subjectId})`;`subjectId` 为空时按 [reim-expense-subject-rules.md](reim-expense-subject-rules.md) 匹配;全部未命中填兜底 `"其他-管理费用(100502270000000104)"`。**必须有值** |
|
|
154
|
+
| 相关流程(明细) | 该行发票绑定的事前申请 `{requestname}({requestid})`;未绑定则不传 |
|
|
155
|
+
| 相关客户(明细,若可写) | 与主表一致 |
|
|
156
|
+
| 相关项目(明细,若可写) | 与主表一致 |
|
|
157
|
+
| **币种** | **每行都显式传 `"人民币(100001050000000001)"`,即使表单已默认带出**。不传时 CLI 会把无行号的明细默认值塞进联动请求,服务端联动报错并静默返回空结果,「申请金额」联动带不出实报金额 / 人民币金额 / 报销总金额 |
|
|
158
|
+
| 附件数(若可写) | `"1"` |
|
|
159
|
+
| **相关发票** | `[该行发票对象]`(**必填**) |
|
|
160
|
+
| **相关凭证** | `[配对凭证对象]`;无凭证不传 |
|
|
293
161
|
|
|
294
|
-
|
|
162
|
+
> **⚠️ 明细金额字段**:遍历该行可写字段时,`componentKey` 为 `Money` / `NumberComponent` 且名称含"金额"的,**默认全部统一填该行发票的 `amount`**,不要因为字段名不是"实报金额"就跳过。例外只有话费报销。
|
|
295
163
|
|
|
296
|
-
|
|
164
|
+
### 交通类发票费用说明
|
|
297
165
|
|
|
298
|
-
|
|
166
|
+
判断条件(满足任一):`expenseType` 含"交通"/"出行"/"打车",或 `consumeContent` 含"客运服务费"/"运输服务",或 `sellerName` 含"滴滴"/"享道"/"高德"/"曹操"等。
|
|
299
167
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## 字段名称 → 数据来源映射表
|
|
305
|
-
|
|
306
|
-
### 主表字段映射
|
|
307
|
-
|
|
308
|
-
| fieldName 关键词 | 数据来源 | value 取值 |
|
|
309
|
-
|------------------|----------|------------|
|
|
310
|
-
| 申请人/报销人/创建人 | 事前申请 | `creatorId` |
|
|
311
|
-
| 部门/报销部门/申请人部门 | 事前申请 | `creatorDepartmentId` |
|
|
312
|
-
| 报销日期/申请日期 | 系统当前日期 | 当天日期 yyyy-MM-dd |
|
|
313
|
-
| 报销方式 | options 默认选项 | 默认选"银行(个人报销)"的 optionValue |
|
|
314
|
-
| 报销事由/摘要 | AI生成 | `"{日期} {费用类型} - {销方简称}"`(**禁止包含 `*` 号**) |
|
|
315
|
-
| 相关流程/事前申请 | 事前申请 | `requestid`(marked=true) |
|
|
316
|
-
| 相关人员 | 事前申请 | `creatorName` |
|
|
317
|
-
| **相关客户** | **按是否出差分流** | **非出差**:固定填 `"100504500000311504"`(泛微上海)。**出差流程**:必须提醒用户填写具体客户,拿到客户名称后搜索 ID 再填;用户未提供则不允许报销 |
|
|
318
|
-
| **合同编号** | **固定值** | **固定填 `"20260999"`,不从其他来源提取,不能留空或放入 unable_to_fill** |
|
|
319
|
-
| **承担主体** | **事前申请/当前用户** | **`creatorId`(marked=true),不能留空或放入 unable_to_fill** |
|
|
320
|
-
| **报销人上级** | **`invoice.reim.employee-superiors`** | **`directSuperior.id`(直接上级 ID,直接赋值;取值口径见 [reim-workflow.md](reim-workflow.md#报销共享常量所有-reference-统一引用本节)),不能留空或放入 unable_to_fill** |
|
|
321
|
-
| **承担人直接上级** | **`invoice.reim.employee-superiors`** | **`directSuperior.id`(直接上级 ID,直接赋值;取值口径见 [reim-workflow.md](reim-workflow.md#报销共享常量所有-reference-统一引用本节)),不能留空或放入 unable_to_fill** |
|
|
322
|
-
| **承担人所有上级** | **`invoice.reim.employee-superiors`** | **`allSuperiors` 所有 `id` 用逗号拼接赋值(如 `"id1,id2,id3"`),不能留空或放入 unable_to_fill** |
|
|
323
|
-
| 币种 | options 默认选项 | 默认选"人民币"的 optionValue |
|
|
324
|
-
| 申请金额/人民币金额 | 发票 | 默认:发票金额合计(所有**发票**的 `amount` 之和,不含相关凭证)。**话费报销**:各行按 [reim-phone-subsidy-rules.md](reim-phone-subsidy-rules.md) 算出的实报金额之和 |
|
|
325
|
-
|
|
326
|
-
### 明细表字段映射
|
|
327
|
-
|
|
328
|
-
> **⚠️ 标注"`invoice.reim.row-info` 优先"的字段:先取 `invoice.reim.row-info` 返回值,为空/null 时才回退到 AI 推断。**
|
|
329
|
-
|
|
330
|
-
| fieldName 关键词 | 数据来源 | value 取值 |
|
|
331
|
-
|------------------|----------|------------|
|
|
332
|
-
| 费用日期/发生日期 | **`invoice.reim.row-info` 优先** → 发票 | 优先 `invoice.reim.row-info` 返回的 `date`,回退 `invoiceDate` |
|
|
333
|
-
| 实报金额 | 发票 | `amount` |
|
|
334
|
-
| **申请金额** | **发票** | **`amount`(与实报金额一致,不能遗漏)** |
|
|
335
|
-
| 报销金额/人民币金额/含税金额及其他 `fieldType="Money"` 字段 | 发票 | `amount` |
|
|
336
|
-
| 费用说明/摘要 | **`invoice.reim.row-info` 优先** → 发票 | **交通类发票**:只填 `{出发地精简}-{目的地精简}`,见下方规则;**其他发票**:优先 `invoice.reim.row-info` 返回的 `fysm`,回退从 `consumeContent` 提取(**必须去掉所有 `*` 号**,如 `*交通运输服务*客运服务费` → `交通运输服务客运服务费`),**不能包含逗号和 `*` 号** |
|
|
337
|
-
| **费用类型/费用科目** | **`invoice.reim.row-info` 优先** → 发票+事前申请 | 优先 `invoice.reim.row-info` 返回的 `subjectId`,回退按 [expense-subject-rules.md](reim-expense-subject-rules.md) 匹配,**必须填值,匹配不到用兜底 `"100502270000000104"`** |
|
|
338
|
-
| **相关客户** | **按是否出差分流** | **非出差**:固定填 `"100504500000311504"`。**出差流程**:与主表一致,填用户确认后的客户 ID;用户未提供则不允许报销 |
|
|
339
|
-
| 相关项目 | 事前申请标题 | marked=true时搜索提取的项目名称获取ID |
|
|
340
|
-
| 相关流程 | 匹配绑定关系 | 该发票绑定的 `preApprovalId`(requestid) |
|
|
341
|
-
| 币种 | 默认固定值 | `"100001050000000001"`(人民币) |
|
|
342
|
-
| 附件数 | 默认 | `"1"` |
|
|
343
|
-
| **相关发票**(`EinvoiceComponent`, `single=false`) | **发票** | **发票的 `invoiceId`(必填)** |
|
|
344
|
-
| **相关凭证**(`EinvoiceComponent`, `single=true`) | **`invoice.reim.row-info` 优先** → 凭证配对 | 优先 `invoice.reim.row-info` 返回的 `itinerary`,回退到凭证配对逻辑;**无凭证则不填** |
|
|
345
|
-
|
|
346
|
-
> **⚠️ 明细行金额字段填写规则(重要,容易遗漏):**
|
|
347
|
-
> 明细表中 `fieldType="Money"` 的字段,无论 `fieldName` 叫什么名字(实报金额、报销金额、申请金额、人民币金额、含税金额等),**默认全部统一填该行发票的 `amount`**。
|
|
348
|
-
> 遍历 `subFields` 时,只要 `fieldType="Money"`,就填金额,不要因为字段名不是"实报金额"就跳过。
|
|
349
|
-
> **例外:** 话费补贴 / 话费报销必须改填 [reim-phone-subsidy-rules.md](reim-phone-subsidy-rules.md) 算出的实报金额,不能填发票原价。
|
|
350
|
-
|
|
351
|
-
### 交通类发票费用说明特殊规则
|
|
352
|
-
|
|
353
|
-
当发票为交通类时(判断条件:`expenseType` 含"交通"/"出行"/"打车",或 `consumeContent` 含"客运服务费"/"运输服务",或 `sellerName` 含"滴滴"/"享道"/"高德"/"曹操"等),需要**额外调用 `invoice.get`** 获取出发地和目的地(详见 [reim-api-reference.md](reim-api-reference.md#57-获取发票详情交通类发票行程信息)),然后将精简后的行程拼入费用说明。
|
|
354
|
-
|
|
355
|
-
**费用说明格式**:`{出发地精简}-{目的地精简}`(交通类发票**只填行程**,不需要前面的费用类型描述)
|
|
168
|
+
需**额外调用 `invoice.get`** 获取出发地和目的地(详见 [reim-api-reference.md](reim-api-reference.md#57-获取发票详情交通类发票行程信息)),费用说明**只填** `{出发地精简}-{目的地精简}`,忽略 `row-info` 的 `fysm`。`invoice.get` 未返回 from/to 时回退常规费用说明逻辑。
|
|
356
169
|
|
|
357
170
|
### 地名精简规则
|
|
358
171
|
|
|
@@ -367,7 +180,7 @@
|
|
|
367
180
|
|
|
368
181
|
**4. 长度控制**:每个地名精简后控制在 10 字以内
|
|
369
182
|
|
|
370
|
-
|
|
183
|
+
**精简快速参考表**:
|
|
371
184
|
|
|
372
185
|
| 原始地址 | 精简结果 | 处理说明 |
|
|
373
186
|
|----------|----------|----------|
|
|
@@ -380,7 +193,7 @@
|
|
|
380
193
|
| 泛微网络科技股份有限公司(北方大区业务运营中心) | 泛微网络(北方运营中心) | 去企业后缀,括号内精简保留 |
|
|
381
194
|
| 北京南站 | 北京南站 | 已够短,原样保留 |
|
|
382
195
|
| 上海南站地铁站2号出入口 | 上海南站 | 去"地铁站"、"出入口" |
|
|
383
|
-
| 杭州萧山国际机场T3航站楼国内出发 | 萧山机场T3 |
|
|
196
|
+
| 杭州萧山国际机场T3航站楼国内出发 | 萧山机场T3 | 去城市名、"国际"、"国内出发" |
|
|
384
197
|
| 上海市浦东新区世纪大道100号环球金融中心 | 环球金融中心 | 去地址前缀,保留标志性建筑名 |
|
|
385
198
|
| 中国人民解放军海军军医大学第一附属医院(长海医院) | 长海医院 | 括号内是通用简称→用简称 |
|
|
386
199
|
| 上海火车站(北广场)东北侧 | 上海火车站 | 去广场方位和方向后缀 |
|
|
@@ -390,79 +203,74 @@
|
|
|
390
203
|
| 边界场景 | 处理方式 |
|
|
391
204
|
|----------|----------|
|
|
392
205
|
| from/to 只有经纬度或地址代码,无可读地名 | 跳过精简,回退到 `fysm` 或 `consumeContent` |
|
|
393
|
-
| 精简后 from 和 to 相同(同一地点上下车) |
|
|
206
|
+
| 精简后 from 和 to 相同(同一地点上下车) | 写成 `{地点}` 而非 `{地点}-{地点}` |
|
|
394
207
|
| from 或 to 为空 | 只写有值的那个,不加 `-` 分隔符 |
|
|
395
208
|
| 地名含英文(如 Costco、IKEA) | 原样保留英文品牌名,不翻译 |
|
|
396
209
|
|
|
397
|
-
> **注意**:交通类发票的费用说明**忽略** `invoice.reim.row-info` 返回的 `fysm` 和 `consumeContent`,只使用 `{出发地精简}-{目的地精简}`。如果 `invoice.get` 未返回 from/to,则回退到常规费用说明逻辑。
|
|
398
|
-
|
|
399
210
|
---
|
|
400
211
|
|
|
401
|
-
##
|
|
212
|
+
## 出差流程相关客户(硬拦截)
|
|
213
|
+
|
|
214
|
+
> **出差报销必须由用户填写具体相关客户。未提供则不允许报销,禁止调用 `workflow.createRequest`。**
|
|
215
|
+
|
|
216
|
+
**如何判断是出差流程(满足任一即可):**
|
|
402
217
|
|
|
403
|
-
|
|
|
404
|
-
|
|
405
|
-
|
|
|
406
|
-
|
|
|
218
|
+
| 判断依据 | 条件 |
|
|
219
|
+
|----------|------|
|
|
220
|
+
| 报销工作流名称 `workFlowName` | 含「差旅」或「出差」 |
|
|
221
|
+
| 事前申请名称 `requestname` | 含「出差」或「差旅」 |
|
|
222
|
+
| 用户表述 | 明确说「出差报销」「差旅报销」 |
|
|
407
223
|
|
|
408
|
-
|
|
224
|
+
**操作步骤:**
|
|
409
225
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
226
|
+
0. 用户给了合同号 → 相关客户由合同联动带出,本节拦截不适用(见「用户给了合同号:以合同联动为准」)
|
|
227
|
+
1. 识别为出差后,**在调用 `workflow.createRequest` 之前必须暂停**
|
|
228
|
+
2. 明确提醒用户:「当前为出差报销,必须填写相关客户。请提供具体客户名称,否则无法继续报销。」
|
|
229
|
+
3. 用户给出客户名称 → 原样(可补全称/简称等写法,英文逗号并列)填进主表和明细的「相关客户」,由 `createRequest` 解析;返回 `NEEDS_CONFIRMATION`(`MULTIPLE_MATCHES` / `NOT_FOUND`)时按 `workflow-create.md` 的浏览按钮口径让用户选或重给名称
|
|
230
|
+
4. 用户拒绝、取消、或不提供具体客户 → **结束报销流程,禁止调用 `workflow.createRequest`**
|
|
231
|
+
5. **禁止**用固定值「泛微上海」顶替出差的相关客户
|
|
413
232
|
|
|
414
233
|
---
|
|
415
234
|
|
|
416
|
-
##
|
|
235
|
+
## 话费补贴 / 话费报销(硬拦截)
|
|
236
|
+
|
|
237
|
+
> **命中「话费补贴标准审批流程」或「话费报销」时,必须按 [reim-phone-subsidy-rules.md](reim-phone-subsidy-rules.md) 计算实报金额,禁止按发票原价填金额字段。**
|
|
238
|
+
|
|
239
|
+
**如何判断(满足任一即可):** `workFlowName` 含「话费补贴标准审批流程」或「话费报销」;事前申请名称含「话费补贴」或「话费报销」;用户明确说话费报销 / 话费补贴。
|
|
240
|
+
|
|
241
|
+
**填单前必须齐备:** 本人实名制当月手机账单截图、账单构成、用户岗位对应的月度上限。缺任一则暂停,不允许调用 `workflow.createRequest`。
|
|
417
242
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
| 模糊搜索无结果 | `"搜索'XX'无匹配结果"` |
|
|
422
|
-
| 数据不匹配 | `"发票数据中无对应信息"` |
|
|
423
|
-
| 需要用户输入 | `"无历史数据,需人工输入"` |
|
|
243
|
+
**实报金额:** 先从账单构成中剔除「手机设备赠送套餐」「家庭宽带套餐」,再按 `min(可报销账单金额, 岗位月度上限)` 支付。
|
|
244
|
+
|
|
245
|
+
**金额字段覆盖:** 本场景下明细/主表所有可写金额字段填上述实报金额,不填发票 `amount`。发票原始金额只用于核对,不得改写发票数据。
|
|
424
246
|
|
|
425
247
|
---
|
|
426
248
|
|
|
427
|
-
##
|
|
428
|
-
|
|
429
|
-
> **⚠️
|
|
430
|
-
|
|
431
|
-
0.
|
|
432
|
-
1.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
- 返回的 `date`、`fysm`、`itinerary`、`subjectId` **优先使用**,只有返回为空/null时才回退到 AI 推断
|
|
441
|
-
5. 每张**发票**(非凭证)= 一行明细(`dataIndex` 从 1 递增),**完整遍历费用明细表(按上面规则定位)的 `subFields` 每个字段**推断值
|
|
442
|
-
6. **每行必须填写**:费用类型(科目)、所有金额字段、费用日期、费用说明、相关发票等
|
|
443
|
-
7. **每行必须将发票 `invoiceId` 赋值到 `EinvoiceComponent`+`single=false` 的字段**
|
|
444
|
-
8. **相关凭证**:优先使用 `invoice.reim.row-info` 返回的 `itinerary`;如无返回,使用原有凭证配对逻辑
|
|
445
|
-
9. `marked=true` 字段从上下文取 ID,取不到放 `unable_to_fill`(不调用 `invoice.reim.field.search`)
|
|
446
|
-
10. **⚠️ 最终检查**:检查每行明细的"费用类型(科目)"字段是否有值,如果为空,**立即填 `"100502270000000104"`**
|
|
447
|
-
11. 返回完整 JSON
|
|
448
|
-
|
|
449
|
-
> **`invoice.reim.row-info` 返回值优先级规则**:
|
|
450
|
-
>
|
|
451
|
-
> | 明细字段 | `invoice.reim.row-info` 返回字段 | 有值时 | 为空/null时 |
|
|
452
|
-
> |----------|-------------------|--------|-------------|
|
|
453
|
-
> | 费用日期 | `date` | **直接使用** | 回退到发票 `invoiceDate` |
|
|
454
|
-
> | 费用说明 | `fysm` | **直接使用** | 回退到 AI 从 `consumeContent` 提取(**去掉所有 `*` 号**) |
|
|
455
|
-
> | 相关凭证 | `itinerary` | **直接使用**(多值逗号分隔) | 回退到原有凭证配对逻辑 |
|
|
456
|
-
> | 费用类型(科目) | `subjectId` | **直接使用** | 回退到 [expense-subject-rules.md](reim-expense-subject-rules.md) 匹配,匹配不到用兜底 |
|
|
457
|
-
>
|
|
458
|
-
> **⚠️ 费用类型(科目)是强制保底:无论来源是 `invoice.reim.row-info` 还是 AI 推断,最终都不能为空,匹配不到直接填 `"100502270000000104"`。**
|
|
249
|
+
## 组装流程(核心逻辑)
|
|
250
|
+
|
|
251
|
+
> **⚠️ 创建多个报销单时,每个报销单都必须独立执行以下完整流程(各自一次 `createForm` → 一次 `createRequest`),不能省略任何步骤或字段。**
|
|
252
|
+
|
|
253
|
+
0. **过滤红冲发票**:过滤 `info.comm_info.pro.status == 8`
|
|
254
|
+
1. **分类配对**:按 `invoiceTypeCode` 分为发票和相关凭证(17/18/57/58),凭证与发票配对(`itinerary` 优先)
|
|
255
|
+
2. **禁止 `*` 号**:所有文本值(费用说明、报销事由等)先去掉 `*`
|
|
256
|
+
3. **出差拦截**:出差/差旅流程先拿到用户提供的相关客户,否则停止
|
|
257
|
+
4. **话费拦截**:按 [reim-phone-subsidy-rules.md](reim-phone-subsidy-rules.md) 核对材料并算实报金额,否则停止
|
|
258
|
+
5. **主表**:按「主表字段规则」逐个落值;带默认值且无需改写的字段不传
|
|
259
|
+
6. **明细**:每张发票一行,按「费用明细字段规则」逐个落值;每行必须有费用日期、金额、费用说明、费用类型(科目)、相关发票、币种
|
|
260
|
+
7. **最终检查**:每行「费用类型(科目)」有值,没有就填 `"其他-管理费用(100502270000000104)"`;`data` 里没有 `fields` 之外的字段 id
|
|
261
|
+
8. 交给 [reim-workflow.md](reim-workflow.md) Step 5 展示预览、确认后调用 `workflow.createRequest`
|
|
459
262
|
|
|
460
263
|
---
|
|
461
264
|
|
|
462
265
|
## 补充说明
|
|
463
266
|
|
|
464
|
-
###
|
|
465
|
-
|
|
267
|
+
### `createRequest` 返回需要补值时
|
|
268
|
+
|
|
269
|
+
| 返回 | 处理 |
|
|
270
|
+
| --- | --- |
|
|
271
|
+
| `NEEDS_INPUT`(`missingFields`) | 缺的是上面"绝不能为空"的字段 → 按本文档来源补上、同一 `context` 重发;其余缺项按 `workflow-create.md` 原样粘贴 `finalMarkdown` 一次问齐用户 |
|
|
272
|
+
| `NEEDS_CONFIRMATION`(`ambiguities`) | 浏览按钮多候选/查不到 → 按 `workflow-create.md` 的浏览按钮口径让用户选;`MULTIPLICITY` → 该字段只留 1 个值后重发 |
|
|
273
|
+
|
|
274
|
+
### 用户修改已创建的报销单
|
|
466
275
|
|
|
467
|
-
|
|
468
|
-
必须填数据 ID,不能填名称文本。**自动填单时**从上下文取 ID,取不到放 `unable_to_fill`。**用户修改时**(`invoice.reim.flow.update.prepare/apply` 场景)才调用 `invoice.reim.field.search` 将文本转 ID。
|
|
276
|
+
走 `workflow.editLoad` → `workflow.editPrepare` → 用户确认 → `workflow.editApply`(见 [`../../weaver-e10-workflow/references/workflow-edit.md`](../../weaver-e10-workflow/references/workflow-edit.md)),`data` 的写法与本文档相同,只传要改的字段。
|