weaver-work-cli 0.1.25 → 0.1.28

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.
Files changed (173) hide show
  1. package/README.md +35 -30
  2. package/dist/cmd/root.js +1 -0
  3. package/dist/cmd/setup/index.js +1 -1
  4. package/dist/core/runtime-agent.js +19 -0
  5. package/dist/internal/e10/auth/commands.js +48 -33
  6. package/dist/internal/e10/auth/messages.js +3 -0
  7. package/dist/internal/e10/auth/session.js +8 -0
  8. package/dist/internal/e10/auth/xiaoe.js +62 -43
  9. package/dist/internal/e10/auth-recovery.js +148 -0
  10. package/dist/internal/e10/client.js +47 -15
  11. package/dist/internal/e10/context.js +9 -31
  12. package/dist/internal/e10/index.js +1 -0
  13. package/dist/internal/e10/request-runtime.js +51 -9
  14. package/dist/shortcuts/archive/host.js +3 -2
  15. package/dist/shortcuts/archive/manifest.js +1 -1
  16. package/dist/shortcuts/archive-oa/constants.js +66 -0
  17. package/dist/shortcuts/archive-oa/continuation.js +70 -0
  18. package/dist/shortcuts/archive-oa/errors.js +53 -0
  19. package/dist/shortcuts/archive-oa/host.js +158 -0
  20. package/dist/shortcuts/archive-oa/index.js +225 -0
  21. package/dist/shortcuts/archive-oa/manifest.js +62 -0
  22. package/dist/shortcuts/archive-oa/operations/borrow-car.js +159 -0
  23. package/dist/shortcuts/archive-oa/operations/borrow-url.js +108 -0
  24. package/dist/shortcuts/archive-oa/operations/confirm.js +48 -0
  25. package/dist/shortcuts/archive-oa/operations/contract.js +120 -0
  26. package/dist/shortcuts/archive-oa/operations/locate.js +50 -0
  27. package/dist/shortcuts/archive-oa/operations/registry.js +40 -0
  28. package/dist/shortcuts/archive-oa/operations/shared.js +181 -0
  29. package/dist/shortcuts/archive-oa/operations/types.js +45 -0
  30. package/dist/shortcuts/archive-oa/operations.js +13 -0
  31. package/dist/shortcuts/asset/host.js +7 -6
  32. package/dist/shortcuts/blog/host.js +4 -3
  33. package/dist/shortcuts/caizhilian/host.js +3 -2
  34. package/dist/shortcuts/caizhilian/manifest.js +1 -1
  35. package/dist/shortcuts/calendar/host.js +2 -1
  36. package/dist/shortcuts/contract/host.js +34 -59
  37. package/dist/shortcuts/ehr/host.js +2 -1
  38. package/dist/shortcuts/esb/host.js +2 -1
  39. package/dist/shortcuts/fna/host.js +6 -3
  40. package/dist/shortcuts/fna/manifest.js +10 -5
  41. package/dist/shortcuts/fna/operations/expense-chart.js +162 -0
  42. package/dist/shortcuts/fna/operations/registry.js +2 -0
  43. package/dist/shortcuts/hrm/host.js +2 -1
  44. package/dist/shortcuts/im/host.js +3 -2
  45. package/dist/shortcuts/index.js +2 -0
  46. package/dist/shortcuts/invoice/host.js +9 -7
  47. package/dist/shortcuts/invoice/manifest.js +38 -47
  48. package/dist/shortcuts/invoice/operations/issuing-qys.js +328 -0
  49. package/dist/shortcuts/invoice/operations/registry.js +2 -3
  50. package/dist/shortcuts/jiuchuanhui/host.js +2 -1
  51. package/dist/shortcuts/mail/host.js +2 -1
  52. package/dist/shortcuts/meeting/host.js +2 -1
  53. package/dist/shortcuts/meeting/operations/eb/conflict.js +78 -12
  54. package/dist/shortcuts/okr/host.js +2 -1
  55. package/dist/shortcuts/plan/host.js +2 -1
  56. package/dist/shortcuts/project/host.js +2 -1
  57. package/dist/shortcuts/workflow/endpoints.js +11 -0
  58. package/dist/shortcuts/workflow/host.js +5 -7
  59. package/dist/shortcuts/workflow/index.js +6 -36
  60. package/dist/shortcuts/workflow/operations/chatscene.js +252 -0
  61. package/dist/shortcuts/workflow/operations/form.js +1047 -191
  62. package/dist/shortcuts/workflow/operations/read.js +137 -8
  63. package/dist/shortcuts/workflow/operations/sign-input.js +106 -0
  64. package/dist/shortcuts/workflow/operations/write.js +9 -1
  65. package/dist/shortcuts/workflow/stdout-compact.js +16 -1
  66. package/docs/SKILL.md +1 -1
  67. package/docs/_catalog.md +1 -1
  68. package/docs/agent-invoice.md +1 -1
  69. package/docs/archive-oa.md +79 -0
  70. package/docs/caizhilian.md +1 -1
  71. package/docs/e10-auth.md +7 -6
  72. package/docs/fna.md +7 -3
  73. package/docs/invoice.md +4 -6
  74. package/package.json +1 -1
  75. package/skill-template/business-info.json +20 -1
  76. package/skill-template/domains/archive-oa.md +19 -0
  77. package/skill-template/domains/caizhilian.md +2 -1
  78. package/skill-template/domains/qiyecheng.md +1 -0
  79. package/skill-template/domains/yepiaotong.md +8 -4
  80. package/skill-template/skill-template.md +1 -0
  81. package/skills/weaver-e10-archive-oa/SKILL.md +159 -0
  82. package/skills/weaver-e10-archive-oa/references/archive-locate.md +49 -0
  83. package/skills/weaver-e10-archive-oa/references/borrow-car.md +76 -0
  84. package/skills/weaver-e10-archive-oa/references/borrow-flow.md +53 -0
  85. package/skills/weaver-e10-archive-oa/references/contract-search.md +63 -0
  86. package/skills/weaver-e10-archive-oa/references/disabled-capabilities.md +29 -0
  87. package/skills/weaver-e10-archive-oa/references/qys-contract-search.md +47 -0
  88. package/skills/weaver-e10-archive-oa/references/source-manifest.json +400 -0
  89. package/skills/weaver-e10-blog/SKILL.md +6 -1
  90. package/skills/weaver-e10-blog/references/blog-query.md +3 -1
  91. package/skills/weaver-e10-builder/SKILL.md +22 -0
  92. package/skills/weaver-e10-caizhilian/SKILL.md +47 -16
  93. package/skills/weaver-e10-caizhilian/references/action-flow.md +70 -0
  94. package/skills/weaver-e10-caizhilian/references/agent-entry.md +12 -4
  95. package/skills/weaver-e10-caizhilian/references/auth-and-install.md +207 -0
  96. package/skills/weaver-e10-caizhilian/references/collaboration.md +5 -3
  97. package/skills/weaver-e10-caizhilian/references/document.md +33 -11
  98. package/skills/weaver-e10-caizhilian/references/file-collection.md +57 -54
  99. package/skills/weaver-e10-caizhilian/references/file-upload.md +5 -6
  100. package/skills/weaver-e10-caizhilian/references/files.md +9 -3
  101. package/skills/weaver-e10-caizhilian/references/folder.md +48 -16
  102. package/skills/weaver-e10-caizhilian/references/host-executor-prompt.md +32 -0
  103. package/skills/weaver-e10-caizhilian/references/host-platform-integration.md +46 -0
  104. package/skills/weaver-e10-caizhilian/references/rule-index.md +56 -0
  105. package/skills/weaver-e10-caizhilian/references/setting-attach.md +17 -54
  106. package/skills/weaver-e10-caizhilian/references/setting-backup.md +16 -63
  107. package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +24 -64
  108. package/skills/weaver-e10-caizhilian/references/setting-storage-docs-summary.md +126 -0
  109. package/skills/weaver-e10-caizhilian/references/setting-storage-field-map.md +57 -0
  110. package/skills/weaver-e10-caizhilian/references/setting-storage.md +143 -548
  111. package/skills/weaver-e10-caizhilian/references/source-manifest.json +7 -7
  112. package/skills/weaver-e10-caizhilian/references/task-workflow.md +87 -0
  113. package/skills/weaver-e10-caizhilian/references/withheld.md +21 -45
  114. package/skills/weaver-e10-caizhilian/references/write-protocol.md +7 -0
  115. package/skills/weaver-e10-calendar/SKILL.md +6 -1
  116. package/skills/weaver-e10-esb/SKILL.md +8 -0
  117. package/skills/weaver-e10-esb/references/input-format.md +3 -1
  118. package/skills/weaver-e10-esb/references/source-manifest.json +5 -5
  119. package/skills/weaver-e10-hrm/SKILL.md +6 -1
  120. package/skills/weaver-e10-hrm/references/employee.md +1 -1
  121. package/skills/weaver-e10-hrm/references/org.md +1 -1
  122. package/skills/weaver-e10-hrm/references/position.md +1 -1
  123. package/skills/weaver-e10-jinchengda/SKILL.md +2 -1
  124. package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +1 -1
  125. package/skills/weaver-e10-jiuchuanhui/SKILL.md +6 -1
  126. package/skills/weaver-e10-jucailin/SKILL.md +6 -1
  127. package/skills/weaver-e10-jucailin/references/hr-contact.md +1 -1
  128. package/skills/weaver-e10-jucailin/references/salary.md +1 -1
  129. package/skills/weaver-e10-mail/SKILL.md +6 -1
  130. package/skills/weaver-e10-meeting/SKILL.md +11 -6
  131. package/skills/weaver-e10-meeting/references/meeting-eb.md +7 -3
  132. package/skills/weaver-e10-meeting/references/meeting-queries.md +3 -1
  133. package/skills/weaver-e10-meeting/references/meeting-verification.md +4 -2
  134. package/skills/weaver-e10-okr/SKILL.md +6 -1
  135. package/skills/weaver-e10-okr/references/source-manifest.json +5 -5
  136. package/skills/weaver-e10-plan/SKILL.md +6 -1
  137. package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +3 -1
  138. package/skills/weaver-e10-plan/references/plan-report-query.md +3 -1
  139. package/skills/weaver-e10-plan/references/source-manifest.json +7 -7
  140. package/skills/weaver-e10-qiyecheng/SKILL.md +16 -6
  141. package/skills/weaver-e10-qiyecheng/references/catalog.md +6 -3
  142. package/skills/weaver-e10-qiyecheng/references/expense-center.md +2 -0
  143. package/skills/weaver-e10-qiyecheng/references/expense-chart.md +78 -0
  144. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +87 -33
  145. package/skills/weaver-e10-shared/SKILL.md +53 -28
  146. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +22 -20
  147. package/skills/weaver-e10-shared/references/non-interactive-environment.md +13 -13
  148. package/skills/weaver-e10-shared/references/weaver-e10-installation.md +3 -1
  149. package/skills/weaver-e10-wenshuding/SKILL.md +6 -1
  150. package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
  151. package/skills/weaver-e10-workflow/references/source-manifest.json +33 -24
  152. package/skills/weaver-e10-workflow/references/workflow-create.md +41 -26
  153. package/skills/weaver-e10-yepiaotong/SKILL.md +23 -18
  154. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +87 -45
  155. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +152 -0
  156. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +210 -0
  157. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +59 -36
  158. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +63 -512
  159. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +205 -346
  160. package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -5
  161. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +231 -344
  162. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +5 -5
  163. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +201 -162
  164. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +121 -145
  165. package/skills/weaver-e10-yimiaoban/SKILL.md +9 -2
  166. package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +1 -1
  167. package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -1
  168. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +9 -9
  169. package/skills/weaver-e10-ziguanjia/SKILL.md +6 -1
  170. package/dist/shortcuts/invoice/operations/issuing.js +0 -198
  171. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-field-rules.md +0 -161
  172. package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +0 -107
  173. package/skills/weaver-e10-yepiaotong/references/reim-fast-path.md +0 -119
@@ -1,198 +0,0 @@
1
- import { invoiceConfirmationError, invoicePartialError, invoiceValidationError, isInvoiceNetworkError } from '../errors.js';
2
- import { asNonEmptyString, asObject, assertBusinessSuccess, objectFingerprint, sessionMatches, workflow, } from './shared.js';
3
- const SELLER_TAX_NO = '9131000070322836XD';
4
- const SELLER_NAME = '上海泛微网络科技股份有限公司';
5
- const TAX_RATES = new Set([0, 0.01, 0.03, 0.05, 0.06, 0.09, 0.13]);
6
- function optionalText(value, name) {
7
- if (value === undefined || value === null || value === '')
8
- return undefined;
9
- return asNonEmptyString(value, name);
10
- }
11
- function money(value, name) {
12
- if (typeof value === 'number') {
13
- if (!Number.isFinite(value) || value < 0)
14
- throw invoiceValidationError('input_invalid', `${name} 必须是非负金额`);
15
- return value;
16
- }
17
- if (typeof value !== 'string' || !/^\d+(?:\.\d+)?$/u.test(value)) {
18
- throw invoiceValidationError('input_invalid', `${name} 必须是非负金额`);
19
- }
20
- return value;
21
- }
22
- function taxRate(value, name) {
23
- const parsed = typeof value === 'number' ? value : Number(value);
24
- if (!Number.isFinite(parsed) || !TAX_RATES.has(parsed)) {
25
- throw invoiceValidationError('input_invalid', `${name} 必须是合法税率:0、0.01、0.03、0.05、0.06、0.09 或 0.13`);
26
- }
27
- return typeof value === 'number' ? value : String(value);
28
- }
29
- function taxNo(value, name, { required = false } = {}) {
30
- const text = optionalText(value, name);
31
- if (text === undefined) {
32
- if (required)
33
- throw invoiceValidationError('input_invalid', `${name} 必填`);
34
- return undefined;
35
- }
36
- if (!/^[0-9A-Z]{15,20}$/u.test(text)) {
37
- throw invoiceValidationError('input_invalid', `${name} 必须是 15-20 位数字或大写字母`);
38
- }
39
- return text;
40
- }
41
- function normalizeMode(value) {
42
- if (value !== 'issue' && value !== 'ledger') {
43
- throw invoiceValidationError('input_invalid', 'mode 必须是 issue 或 ledger');
44
- }
45
- return value;
46
- }
47
- function normalizeDetail(value, index) {
48
- const detail = structuredClone(asObject(value, `payload.details[${index}]`));
49
- detail.goodsName = asNonEmptyString(detail.goodsName, `payload.details[${index}].goodsName`);
50
- detail.taxRate = taxRate(detail.taxRate, `payload.details[${index}].taxRate`);
51
- detail.amount = money(detail.amount, `payload.details[${index}].amount`);
52
- detail.amountWithTax = money(detail.amountWithTax, `payload.details[${index}].amountWithTax`);
53
- if (detail.taxAmount !== undefined)
54
- detail.taxAmount = money(detail.taxAmount, `payload.details[${index}].taxAmount`);
55
- if (detail.revenueCode !== undefined && !/^\d{4,19}$/u.test(String(detail.revenueCode))) {
56
- throw invoiceValidationError('input_invalid', `payload.details[${index}].revenueCode 必须是数字编码`);
57
- }
58
- for (const key of ['quantity', 'unitPrice', 'unit', 'specification']) {
59
- if (detail[key] !== undefined && detail[key] !== null)
60
- detail[key] = String(detail[key]);
61
- }
62
- return detail;
63
- }
64
- function normalizeMakeInvoicePayload(rawPayload, mode) {
65
- const payload = structuredClone(asObject(rawPayload, 'payload'));
66
- const purchaserName = asNonEmptyString(payload.purchaserName, 'payload.purchaserName');
67
- const invoiceType = asNonEmptyString(payload.invoiceType, 'payload.invoiceType');
68
- if (!['7', '8', '9', '10'].includes(invoiceType)) {
69
- throw invoiceValidationError('input_invalid', 'payload.invoiceType 必须是 7、8、9 或 10');
70
- }
71
- const specialInvoice = invoiceType === '8' || invoiceType === '10';
72
- const purchaserTaxNo = taxNo(payload.purchaserTaxNo, 'payload.purchaserTaxNo', { required: specialInvoice });
73
- if (!Array.isArray(payload.details) || !payload.details.length) {
74
- throw invoiceValidationError('input_invalid', 'payload.details 必须是非空数组');
75
- }
76
- const details = payload.details.map((item, index) => normalizeDetail(item, index));
77
- const normalized = {
78
- ...payload,
79
- taxNo: SELLER_TAX_NO,
80
- sellerName: SELLER_NAME,
81
- billingType: payload.billingType || '0',
82
- invoiceType,
83
- externalDocumentNo: asNonEmptyString(payload.externalDocumentNo, 'payload.externalDocumentNo'),
84
- sourceType: payload.sourceType || '4',
85
- asyncCallFlag: payload.asyncCallFlag || '1',
86
- invoiceMethod: payload.invoiceMethod || '5',
87
- taxSign: payload.taxSign || '1',
88
- personLogo: payload.personLogo || (purchaserTaxNo ? '0' : '1'),
89
- purchaserName,
90
- details,
91
- totalAmount: money(payload.totalAmount, 'payload.totalAmount'),
92
- taxAmount: money(payload.taxAmount, 'payload.taxAmount'),
93
- totalAmountWithTax: money(payload.totalAmountWithTax, 'payload.totalAmountWithTax'),
94
- };
95
- if (purchaserTaxNo !== undefined)
96
- normalized.purchaserTaxNo = purchaserTaxNo;
97
- for (const key of ['purchaserAddress', 'purchaserTel', 'purchaserBankName', 'purchaserBankAccount', 'remark', 'invoiceDate']) {
98
- if (payload[key] !== undefined && payload[key] !== null)
99
- normalized[key] = String(payload[key]);
100
- }
101
- if (mode === 'ledger')
102
- normalized.operateType = '5';
103
- else
104
- delete normalized.operateType;
105
- return normalized;
106
- }
107
- function makeInvoicePreview(payload, mode) {
108
- return {
109
- mode,
110
- purchaserName: payload.purchaserName,
111
- purchaserTaxNo: payload.purchaserTaxNo || '',
112
- invoiceType: payload.invoiceType,
113
- externalDocumentNo: payload.externalDocumentNo,
114
- totalAmount: payload.totalAmount,
115
- taxAmount: payload.taxAmount,
116
- totalAmountWithTax: payload.totalAmountWithTax,
117
- detailCount: Array.isArray(payload.details) ? payload.details.length : 0,
118
- };
119
- }
120
- export class InvoiceIssuingMakePrepareOperation {
121
- name = 'invoice.issuing.make.prepare';
122
- async execute(input, { host, continuation }) {
123
- const mode = normalizeMode(input.mode);
124
- const payload = normalizeMakeInvoicePayload(input.payload, mode);
125
- const session = await host.getSession();
126
- const preview = makeInvoicePreview(payload, mode);
127
- const continuationToken = await continuation.issue({
128
- operation: 'invoice.issuing.make.apply',
129
- workflow: workflow('invoice.issuing.make', 'AWAITING_CONFIRMATION'),
130
- baseUrl: session.baseUrl,
131
- profile: session.profile,
132
- userId: session.userId,
133
- mode,
134
- fingerprint: objectFingerprint(payload),
135
- preview,
136
- });
137
- return {
138
- status: 'AWAITING_CONFIRMATION',
139
- data: {
140
- preview,
141
- normalizedPayload: payload,
142
- continuation: continuationToken,
143
- expiresInSeconds: 600,
144
- workflow: workflow('invoice.issuing.make', 'AWAITING_CONFIRMATION'),
145
- },
146
- };
147
- }
148
- }
149
- export class InvoiceIssuingMakeApplyOperation {
150
- name = 'invoice.issuing.make.apply';
151
- async execute(input, { host, continuation }) {
152
- if (input.confirm !== true)
153
- throw invoiceConfirmationError('invoice.issuing.make.apply', { hint: '重新调用时传入 confirm=true' });
154
- const lease = await continuation.verify(input.continuation, 'invoice.issuing.make.apply');
155
- const mode = normalizeMode(lease.mode);
156
- const payload = normalizeMakeInvoicePayload(input.payload, mode);
157
- if (typeof lease.fingerprint !== 'string')
158
- throw invoiceValidationError('continuation_invalid', '开票 continuation 缺少 payload 指纹');
159
- if (objectFingerprint(payload) !== lease.fingerprint)
160
- throw invoiceValidationError('target_changed', '开票载荷与确认时不一致,请重新准备');
161
- const session = await host.getSession();
162
- if (!sessionMatches(lease, session))
163
- throw invoiceValidationError('context_mismatch', '确认上下文已变化,请重新准备开票');
164
- let result;
165
- try {
166
- result = await host.invoiceRequest({ path: '/api/inc/book/open/makeInvoice', method: 'POST', body: payload, operation: this.name, timeoutMs: 90_000 });
167
- }
168
- catch (error) {
169
- if (isInvoiceNetworkError(error)) {
170
- throw invoicePartialError('开票请求发送后连接中断,结果不确定,禁止自动重试', {
171
- preview: lease.preview,
172
- workflow: workflow('invoice.issuing.make', 'EXECUTING'),
173
- }, { stage: 'issuing-make' });
174
- }
175
- throw error;
176
- }
177
- assertBusinessSuccess(result, 'issuing_make_failed', '开票或存台账失败');
178
- const data = result?.data || {};
179
- if (!data.serialNo && !data.orderNo && mode === 'issue') {
180
- throw invoicePartialError('开票接口返回成功但缺少流水号,结果不确定', {
181
- preview: lease.preview,
182
- result,
183
- workflow: workflow('invoice.issuing.make', 'VERIFYING'),
184
- }, { stage: 'issuing-make-response' });
185
- }
186
- return {
187
- status: 'COMPLETE',
188
- data: {
189
- mode,
190
- serialNo: data.serialNo,
191
- orderNo: data.orderNo,
192
- ledgerOnly: mode === 'ledger',
193
- result,
194
- workflow: workflow('invoice.issuing.make', 'COMPLETE'),
195
- },
196
- };
197
- }
198
- }
@@ -1,161 +0,0 @@
1
- # 开票字段提取规则
2
-
3
- ## 什么时候读取
4
-
5
- AI 需要从用户输入中推断税率、计算金额、校验字段格式,或判断发票类型时读取本文件。
6
-
7
- ---
8
-
9
- ## 税率推断规则
10
-
11
- ### 13% — 销售货物、有形动产租赁
12
-
13
- | 关键词 | 典型商品 |
14
- |--------|---------|
15
- | 货物/商品/材料/配件/零件 | 各类实物商品 |
16
- | 设备/机器/仪器/电子产品 | 机械设备、电器 |
17
- | 食品/饮料/酒水/药品 | 食品医药 |
18
- | 服装/家具/钢材/水泥/建材 | 服装建材 |
19
- | 动产租赁/设备租赁 | 有形动产经营租赁 |
20
-
21
- ### 9% — 建筑服务、交通运输、不动产
22
-
23
- | 关键词 | 典型服务 |
24
- |--------|---------|
25
- | 建筑/施工/装修/安装/工程 | 建筑安装 |
26
- | 运输/物流/快递/搬运 | 交通运输 |
27
- | 不动产/房屋/房租/土地 | 不动产 |
28
- | 农产品/自来水/天然气 | 农产品等 |
29
-
30
- ### 6% — 现代服务、生活服务
31
-
32
- | 关键词 | 典型服务 |
33
- |--------|---------|
34
- | 咨询/顾问/策划/技术/研发 | 咨询技术 |
35
- | 软件/系统/SaaS/信息/数据 | 信息技术 |
36
- | 设计/广告/营销/培训 | 文化创意 |
37
- | 餐饮/住宿/旅游/物业 | 生活服务 |
38
- | 会计/审计/法律/检测 | 鉴证服务 |
39
- | 金融/保险/代理/中介 | 金融经纪 |
40
-
41
- ### 3% — 小规模纳税人
42
-
43
- 用户明确说"3%"或"小规模"时使用。
44
-
45
- ### 推断优先级
46
-
47
- 1. 用户明确指定的税率 → 最高优先
48
- 2. 商品名称关键词匹配 → 按上表
49
- 3. 多关键词冲突 → 取最相关(如"建筑材料"→13% 因为是货物销售)
50
- 4. 无法确定 → 展示常见选项让用户选
51
-
52
- ### 展示格式
53
-
54
- ```
55
- 根据商品名称"{goods_name}",AI 推断:
56
- - 适用税率:{X}%
57
- 其他常见税率:13%(货物)| 9%(建筑/交通)| 6%(服务)| 3%(小规模)
58
- 如税率不正确请告知,否则将按 {X}% 计算。
59
- ```
60
-
61
- 多个明细行时每行独立推断,一次性展示所有。
62
-
63
- ---
64
-
65
- ## 金额计算规则
66
-
67
- ### 已知含税金额
68
-
69
- ```
70
- 不含税金额 = round(含税金额 / (1 + 税率), 2)
71
- 税额 = 含税金额 - 不含税金额
72
- ```
73
-
74
- ### 已知不含税金额
75
-
76
- ```
77
- 税额 = round(不含税金额 × 税率, 2)
78
- 含税金额 = 不含税金额 + 税额
79
- ```
80
-
81
- ### 单价计算
82
-
83
- ```
84
- 不含税单价 = round(不含税金额 / 数量, 合理精度)
85
- ```
86
-
87
- ### 合计
88
-
89
- ```
90
- totalAmount = sum(每行 amount)
91
- taxAmount = sum(每行 taxAmount)
92
- totalAmountWithTax = sum(每行 amountWithTax)
93
- ```
94
-
95
- ### 尾差处理
96
-
97
- ```
98
- 允许尾差 = |amountWithTax - amount - taxAmount| <= 0.06
99
- ```
100
-
101
- 超出范围提示用户核实。
102
-
103
- ---
104
-
105
- ## 校验规则
106
-
107
- | 规则 | 说明 |
108
- |------|------|
109
- | 购方名称必填 | 所有发票类型 |
110
- | 购方税号 | 专票必填;普票可选;无税号时强制普票 |
111
- | 税号格式 | 15/18/20位,数字+大写字母。正则:`^[0-9A-Z]{15}$\|^[0-9A-Z]{18}$\|^[0-9A-Z]{20}$` |
112
- | 明细至少一行 | details 不能为空 |
113
- | 税率合法性 | 0 / 0.01 / 0.03 / 0.05 / 0.06 / 0.09 / 0.13 |
114
- | 金额平衡 | amountWithTax = amount + taxAmount(允许尾差 ≤ 0.06) |
115
- | 合计平衡 | 明细行 amount 之和 = totalAmount |
116
-
117
- ---
118
-
119
- ## 购方信息提取模式
120
-
121
- | 用户表述 | 提取目标 |
122
- |---------|---------|
123
- | "给XX公司开票" / "购方XX" | purchaserName |
124
- | "税号XXXX" / "纳税人识别号XXXX" | purchaserTaxNo |
125
- | "地址:XX路XX号" | purchaserAddress |
126
- | "电话XXX" | purchaserTel |
127
- | "开户行XX银行" | purchaserBankName |
128
- | "账号XXXX" | purchaserBankAccount |
129
-
130
- ### 从文档/图片提取
131
-
132
- | 位置 | 提取目标 |
133
- |------|---------|
134
- | 合同甲方/乙方/购买方 | purchaserName |
135
- | 统一社会信用代码 | purchaserTaxNo |
136
- | 联系地址/通讯地址 | purchaserAddress |
137
- | 联系电话 | purchaserTel |
138
- | 开户银行 | purchaserBankName |
139
- | 银行账号 | purchaserBankAccount |
140
-
141
- ---
142
-
143
- ## 商品明细提取
144
-
145
- ### 从 Excel 表头匹配
146
-
147
- | 表头关键词 | 映射字段 |
148
- |-----------|---------|
149
- | 商品名称/品名/项目名称 | goods_name |
150
- | 规格/规格型号 | specification |
151
- | 单位/计量单位 | unit |
152
- | 数量 | quantity |
153
- | 单价/不含税单价 | unit_price |
154
- | 金额/不含税金额/含税金额 | amount_raw |
155
- | 税率 | tax_rate |
156
-
157
- ### externalDocumentNo 生成规则
158
-
159
- 用户未提供时自动生成:`AI-{YYYYMMDD}-{HHmmss}-{4位随机}`
160
-
161
- 用户提供合同号/订单号时优先使用。
@@ -1,107 +0,0 @@
1
- # 智能开票与存台账
2
-
3
- ## 什么时候读取
4
-
5
- 用户要求开票、开发票、开专票、开普票、填开发票、存台账,或已经给出开票字段并要求提交到业票通时读取本文件。
6
-
7
- ## Operation
8
-
9
- | 阶段 | Operation | 风险 |
10
- | --- | --- | --- |
11
- | 准备开票或存台账 | `invoice.issuing.make.prepare` | read-before-write |
12
- | 确认提交 | `invoice.issuing.make.apply` | high-risk-write |
13
-
14
- ## 输入要点
15
-
16
- `mode` 必填:
17
-
18
- - `issue`:正式开票,CLI 会确保 `operateType` 不传。
19
- - `ledger`:仅存入待开台账,CLI 会固定 `operateType="5"`。
20
-
21
- `payload` 是已整理好的 `MakeInvoiceReqDTO`。核心字段至少包括购方名称、发票类型、外部单号、金额合计和一条商品明细。专票或全电纸质专票必须提供购方税号。
22
-
23
- ### 购方信息补齐
24
-
25
- 修正后的资料包没有提供客户档案查询 operation。组装 payload 前,Agent 只能从用户输入、附件内容或对话上下文提取购方信息;资料不足时必须追问用户补齐,不要调用 `invoice.customer.*` 或绕过 CLI 查询原始接口。
26
-
27
- - 个人普票:`invoiceType="7"`,`personLogo="1"`,无需税号。
28
- - 企业专票或需要企业抬头时:必须由用户或附件提供购方名称、税号;地址、电话、开户行和账号有明确来源时才填入,没有来源不要编造。
29
- - 从附件提取购方信息前,必须先提醒用户文件内容可能进入当前大模型上下文,并可能发送到解析服务,等待明确确认后再处理。
30
-
31
- 销方为 CLI 内置固定值(当前版本固定为销方名称 `上海泛微网络科技股份有限公司`、销方税号 `9131000070322836XD`,非按当前 E10 租户动态解析),Agent 无需也不应自行构造或改写销方字段;CLI 会一并补齐 `billingType="0"`、`sourceType="4"`、`asyncCallFlag="1"`、`invoiceMethod="5"`、`taxSign="1"`。Agent 不要把 Cookie、ETEAMSID、业务 Token 或认证字段放入 payload。
32
-
33
- ## 命令
34
-
35
- 简单 payload 可直接传 `--input-json`。
36
-
37
- Windows PowerShell:
38
-
39
- ```powershell
40
- weaver-work-cli --json invoice run invoice.issuing.make.prepare --input-json '{"mode":"ledger","payload":{"invoiceType":"8","externalDocumentNo":"AI-EXAMPLE-001","purchaserName":"XX科技有限公司","purchaserTaxNo":"91310000MA1234AB56","totalAmount":100,"taxAmount":6,"totalAmountWithTax":106,"details":[{"goodsName":"信息技术咨询服务","revenueCode":"3040205","taxRate":0.06,"amount":100,"amountWithTax":106,"taxAmount":6,"quantity":"1","unit":"项"}]}}'
41
- ```
42
-
43
- macOS/Linux(bash/zsh):
44
-
45
- ```bash
46
- weaver-work-cli --json invoice run invoice.issuing.make.prepare --input-json '{"mode":"ledger","payload":{"invoiceType":"8","externalDocumentNo":"AI-EXAMPLE-001","purchaserName":"XX科技有限公司","purchaserTaxNo":"91310000MA1234AB56","totalAmount":100,"taxAmount":6,"totalAmountWithTax":106,"details":[{"goodsName":"信息技术咨询服务","revenueCode":"3040205","taxRate":0.06,"amount":100,"amountWithTax":106,"taxAmount":6,"quantity":"1","unit":"项"}]}}'
47
- ```
48
-
49
- 复杂 payload 建议保存为 UTF-8 JSON 文件。
50
-
51
- Windows PowerShell:
52
-
53
- ```powershell
54
- Set-Content -Encoding utf8 -LiteralPath .\issuing.json -Value @'
55
- {
56
- "mode": "issue",
57
- "payload": {
58
- "invoiceType": "8",
59
- "externalDocumentNo": "AI-EXAMPLE-001",
60
- "purchaserName": "XX科技有限公司",
61
- "purchaserTaxNo": "91310000MA1234AB56",
62
- "totalAmount": 100,
63
- "taxAmount": 6,
64
- "totalAmountWithTax": 106,
65
- "details": [{"goodsName":"信息技术咨询服务","taxRate":0.06,"amount":100,"amountWithTax":106,"taxAmount":6,"quantity":"1","unit":"项"}]
66
- }
67
- }
68
- '@
69
- weaver-work-cli --json invoice run invoice.issuing.make.prepare --input .\issuing.json
70
- ```
71
-
72
- macOS/Linux(bash/zsh):
73
-
74
- ```bash
75
- cat > ./issuing.json <<'JSON'
76
- {
77
- "mode": "issue",
78
- "payload": {
79
- "invoiceType": "8",
80
- "externalDocumentNo": "AI-EXAMPLE-001",
81
- "purchaserName": "XX科技有限公司",
82
- "purchaserTaxNo": "91310000MA1234AB56",
83
- "totalAmount": 100,
84
- "taxAmount": 6,
85
- "totalAmountWithTax": 106,
86
- "details": [{"goodsName":"信息技术咨询服务","taxRate":0.06,"amount":100,"amountWithTax":106,"taxAmount":6,"quantity":"1","unit":"项"}]
87
- }
88
- }
89
- JSON
90
- weaver-work-cli --json invoice run invoice.issuing.make.prepare --input ./issuing.json
91
- ```
92
-
93
- ## 确认链
94
-
95
- `.prepare` 返回 `preview`、`normalizedPayload`、`continuation` 和 `workflow.state="AWAITING_CONFIRMATION"`。向用户展示发票类型、购方名称、税号、外部单号、明细数量、合计不含税、税额和价税合计;用户明确确认开票或存台账后,再用相同 payload、continuation 和 `confirm=true` 调用 `.apply`。
96
-
97
- ## 输出处理
98
-
99
- `.apply` 成功返回 `mode`、`serialNo`、`orderNo`、`ledgerOnly` 和原始响应。正式开票时说明申请已提交;存台账时说明已保存为待开台账。接口失败时展示业务错误原因,不自动重试。
100
-
101
- ## 注意
102
-
103
- 正式开票是高风险且不可逆的业务写入。同一 continuation 只服务一次确认场景;如果用户修改购方、金额、税率或明细,必须重新 prepare。
104
-
105
- 字段提取、税率推断和金额计算由 Agent 在调用 CLI 前完成。原始税号、金额、名称、编码等值必须逐字符保留;不要为了“补齐位数”或“格式化”改写用户或接口给出的 ID、日期和金额。
106
-
107
- 如果用户提供 Excel、Word、TXT、图片或截图来提取开票字段,解析前必须先提醒用户:文件内容可能进入当前大模型上下文,并可能发送到解析服务;必须等待明确确认。
@@ -1,119 +0,0 @@
1
- # 报销快速路径(0.1.13 新增 operation)
2
-
3
- > 三个新 operation 把「查票 → 分类 → 组 payload → prepare」压成两步,人工只保留确认 + apply。
4
- > 固化映射来自 2026-09-14 / 2026-09-21 两次真实 apply 成功的「总部费用报销」单据,只覆盖该流程。
5
-
6
- ## 1. `invoice.reim.candidates.list`(read)— 票夹候选分类
7
-
8
- 自动翻页拉取未报销(sreim=3)发票,并按 `oreim.list_reim` / 红冲状态分成三组,**不再需要手动翻页和逐条剔重**:
9
-
10
- macOS/Linux(bash):
11
-
12
- ```bash
13
- weaver-work-cli --json invoice run invoice.reim.candidates.list --input-json '{"date_begin":"2026-09-14","date_end":"2026-09-21"}'
14
- ```
15
-
16
- Windows PowerShell:
17
-
18
- ```powershell
19
- weaver-work-cli --json invoice run invoice.reim.candidates.list --input-json '{"date_begin":"2026-09-14","date_end":"2026-09-21"}'
20
- ```
21
-
22
- - 入参(全部可选):`date_begin`/`date_end`(YYYY-MM-DD,开票日期范围)、`page_size`(10-200,默认 50)、`max_items`(1-500,默认 200,超出截断并产生 warning)、`include_red_reversed`(默认 `false`)。
23
- - **红冲票默认已过滤**:全额红冲发票(`status=8`)不可报销,默认**不出现在结果里任何一组**,被过滤的张数由 `summary.filteredRedReversedCount` 告知(不会静默丢弃)。需要看红冲票时传 `include_red_reversed: true`,此时它们进 `redReversed` 组。
24
- - 过滤发生在翻页循环内部:即使某一页全是红冲票也会继续翻页,直到凑够 `max_items` 张**可用**发票或数据取完,因此 `fetched` 只计保留下来的发票数、`total` 仍是接口返回的符合条件的总张数。
25
- - 输出:`available` / `assigned` / `redReversed` 三组(后一组默认恒为空),每组元素含 `fid`、`number`、`date`、`total`、`buyer`、`payer`、`typeName`、`status`、`valid`、`reimRequests`;`summary` 给出三组的张数与金额合计,外加 `filteredRedReversedCount`;`warnings` 含截断与金额解析告警。
26
- - **报销范围永远从 `available` 里选**;`assigned` 是已挂单的(重复提交 = 重复报销)。
27
- - **⚠️ 关于"两次连续查询之间 assigned↔available 翻转"(2026-09-21 已定位,结论:分类是准的,不是误判)**:同一天内观察到 25 张发票从 `assigned` 翻到 `available`,一度被怀疑是 `oreim.list_reim` 缓存滞后。最终用 `workflow.detail` 逐个复核 requestId 后定案:`1313947830149185538`(报销单 2026-09-11)、`1314910388070170941`(2026-09-14)、`1317591500119752761`(当天新建)**均返回"流程已被删除"**,10+15+2 张发票随之释放。⇒ **翻转的根因是报销单被删除,发票真实释放,`candidates.list` 的三分类如实反映了状态变化。**
28
- - **因此不要每次报销都对每张入选票再跑一次 `invoice.get` 复核 `oreim.list_reim`** —— 那会让快速路径失去意义。只有在**观察到异常翻转**(或对某张票的归属存疑)时才做核实,正确顺序是:`weaver-work-cli workflow run workflow.detail --input-json '{"requestId":"<id>"}'` 查单据是否还存在(被删的单会明确返回"流程已被删除")→ 再用 `invoice.get` 看 `oreim.list_reim`。
29
- - **已知局限**:`list_reim` 元素只有报销单**名称**(无 requestId、无单号、无单据状态),`reimRequests` 里拿不到能直接喂给 `workflow.detail` 的 id。要核实只能先按名称用 `workflow.search` 找 requestId —— 注意**被删除的单在 `workflow.search` 里搜不到**,这本身就是一个"单可能已被删"的信号,但无法区分"从未存在"与"已被删除"。
30
- - 另一个易踩点:`sreim="3"`(未报销)**不会**把挂单中的发票排除掉(实测 13 张挂单票仍出现在 `sreim=3` 的 39 张结果里),所以不能靠 `sreim` 判断是否已挂单,分类必须看 `list_reim`。
31
-
32
- ## 2. `invoice.reim.template.build`(read)— 固化模板组装 payload
33
-
34
- 输入发票 ID 列表 + 标题,一条命令产出完整 `payload`(19 个主表字段 + N 行明细)。内部自动完成:取上级(`directSuperior`)→ 解析候选工作流(或用传入 `workflowId`)→ 取表单结构并**按名称定位「费用明细」子表** → 批量取发票详情与行预填。
35
-
36
- macOS/Linux(bash):
37
-
38
- ```bash
39
- weaver-work-cli --json invoice run invoice.reim.template.build --input-json '{"invoiceIds":["1317524773561163780","1317524747581644831"],"requestName":"烧烤调料及托盘采购报销-龚为明-2026-09-21(共2笔)","relatedCustomerId":"100504500000311504","contractNo":"20260999"}'
40
- ```
41
-
42
- Windows PowerShell:
43
-
44
- ```powershell
45
- weaver-work-cli --json invoice run invoice.reim.template.build --input-json '{"invoiceIds":["1317524773561163780","1317524747581644831"],"requestName":"烧烤调料及托盘采购报销-龚为明-2026-09-21(共2笔)","relatedCustomerId":"100504500000311504","contractNo":"20260999"}'
46
- ```
47
-
48
- - 入参:`invoiceIds`(必填,1-100 个,顺序 = 明细行顺序)、`requestName`(必填,≤100 字);可选 `workflowId`(不传则自动解析唯一候选流程)、`reason`(报销事由,缺省用 requestName)、`relatedCustomerId`、`relatedCustomerName`、`contractNo`(**默认值 `"20260999"`,视为必传**)。
49
- - **⚠️ `contractNo` 默认填 `"20260999"`,不能省略**:主表 `合同号(100003720000001376)` 只有在入参给了 `contractNo` 时才写进 `payload.main_fields`(不传时该字段**整条缺失**,实测同一票同参数:不传 18 个主表字段,传 `"contractNo":"20260999"` 后 19 个),报销单里它会留空**且 `warnings` 不会提示**,属于静默漏填。
50
- - **默认值口径与 [`reim-form-fill-rules.md`](reim-form-fill-rules.md) 的主表字段映射表一致**:合同编号 = 固定值 `"20260999"`。**除非用户明确给出别的合同号,否则一律填 `"20260999"`** —— 快速路径也必须遵守这条,不能因为「入参可选」就留空。
51
- - 用户另有指定时以用户指定为准;用户明确说"不填合同号"时才允许留空。
52
- - 输出:`payload`(可直接喂给 `flow.create.prepare` / apply)、`preview`、`labels`、`warnings`。
53
- - `preview.mainFields[]` / `preview.detailRows[]`:**已把字典类 ID 渲染成「中文(id)」,预览直接展示这两项即可,不必再查名**(详见 `reim-workflow.md` Step 4.7)。
54
- - `labels`:`employees` / `subjects` / `currencies` / `customers` / `selectOptions` / `customer` / `detailSubForm` / `workflow` 字典;`labels.unresolved` 为没取到中文名的 ID 清单,非空时如实展示并提醒用户核对。
55
- - 相关客户只给名称也行:传 `relatedCustomerName`(不传 ID 时 CLI 反查 ID;ID + 名称同传则不额外请求,仅用于渲染)。
56
- - 行为细节(与 2026-09 实测口径一致):
57
- - 报销人上级 / 承担人直接上级 = `directSuperior.id`(**不是 allSuperiors[0]**);承担人所有上级 = allSuperiors 全部 id 逗号拼接。
58
- - 费用明细子表优先按名称「费用明细」匹配,兜底按「相关发票」字段结构签名匹配。
59
- - 费用说明自动去掉 `*`;科目缺省「日常消费」;币种人民币;报销方式银行(optionValue "7")。
60
- - 发票已挂单 → warning;发票全额红冲(status=8)或金额合计为 0 → **直接报错拒绝组装**。
61
- - `relatedCustomerId` 不传会留空并产生 warning(E10 apply 时可能因必填校验失败,非出差场景建议传)。
62
- - 模板只固化了「总部费用报销」(`100003460000000060`) 的字段映射。若解析到的候选流程不是它,字段映射可能不适用 —— 此时**改走 `reim-workflow.md` 的手工组装路径**。
63
-
64
- ## 3. `invoice.reim.flow.create.auto-prepare`(read-before-write)— 一站式 prepare
65
-
66
- 与 `template.build` 相同的入参,组装 payload 后**直接签发 `flow.create.apply` 的 continuation**,一步到 `AWAITING_CONFIRMATION`:
67
-
68
- macOS/Linux(bash):
69
-
70
- ```bash
71
- weaver-work-cli --json invoice run invoice.reim.flow.create.auto-prepare --input-json '{"invoiceIds":["1317524773561163780","1317524747581644831"],"requestName":"烧烤调料及托盘采购报销-龚为明-2026-09-21(共2笔)","relatedCustomerId":"100504500000311504","contractNo":"20260999"}'
72
- ```
73
-
74
- Windows PowerShell:
75
-
76
- ```powershell
77
- weaver-work-cli --json invoice run invoice.reim.flow.create.auto-prepare --input-json '{"invoiceIds":["1317524773561163780","1317524747581644831"],"requestName":"烧烤调料及托盘采购报销-龚为明-2026-09-21(共2笔)","relatedCustomerId":"100504500000311504","contractNo":"20260999"}'
78
- ```
79
-
80
- 输出含 `payload` + `preview` + `labels` + `continuation` + `expiresInSeconds: 600`。**用户确认后**,把 payload 的字段**展开到顶层**(即 `work_flow_id` / `mainFormId` / `request_name` / `main_fields` / `detail_rows` / `need_user_confirm` / `unable_to_fill`),再补 `continuation` 与 `confirm: true`,交给 `invoice.reim.flow.create.apply` 提交。**不要写成 `{"payload": {...}, "continuation": ...}` 的嵌套结构**(`reim-api-reference.md` 第 7 节已明确「不要再包一层通用 payload」)。
81
-
82
- ## 推荐流程(快速路径)
83
-
84
- ```
85
- candidates.list(选 available)
86
- → 向用户展示汇总并确认范围
87
- → auto-prepare(或 template.build + flow.create.prepare) ← 必带 relatedCustomerId + contractNo:"20260999"(用户另有指定时用其值)
88
- → 展示 preview + warnings(**ID 一律带中文名,见 `reim-workflow.md` Step 4.7**),等用户确认
89
- → flow.create.apply(展开 payload 到顶层 + continuation + confirm=true)
90
- → 回查验证(candidates.list 或 invoice.list)
91
- ```
92
-
93
- 人工确认环节不可跳过:apply 是 high-risk-write,金额、抬头、明细、上级必须经过用户核对。
94
-
95
- > **apply 入参改用 `--input <path>` 时的解析坑(0.1.18 实测)**:stdout 会在 JSON **之前多出一行** `[weaver-work-cli] 使用 --input <path> 读取 JSON 文件;多步传递请优先用 --input-ref,简单数据请用 --input-json。`。脚本解析必须先定位第一个 `{` 再 `JSON.parse`,直接解析会抛 `Unexpected token 'w'`。
96
-
97
- > **continuation 只有 600 秒有效期**:`prepare` / `auto-prepare` 签发后要尽快 `apply`,中间不要插入文档查询、多轮确认或其它耗时命令,否则会返回 `validation/continuation_expired`。遇到过期**重新 `prepare` 后立即 `apply`** 即可(用户已确认过的内容无需重新征询),**不要重放旧 continuation**。
98
-
99
- ## 快速路径适用判断
100
-
101
- Agent 在决定走快速路径还是手工路径时,按以下规则判断:
102
-
103
- | 条件 | 走快速路径 | 走手工路径 |
104
- |------|------------|------------|
105
- | `workflow.resolve` 返回的 workFlowId = `100003460000000060`(总部费用报销) | ✅ | — |
106
- | workFlowId 不是 `100003460000000060` | — | ✅ |
107
- | `template.build` 返回 error 含 `structure_invalid` 或字段映射异常 | — | ✅(自动回退) |
108
- | 需要逐字段精细控制(如手动指定某行的费用科目) | — | ✅ |
109
- | 有事前申请需要绑定 | — | ✅(模板不做事前绑定) |
110
- | 无事前申请 + 总部费用报销流程 | ✅(优先) | — |
111
-
112
- > **⚠️ 快速路径的 `template.build` 和 `auto-prepare` 已内置挂单检查**:如果某张发票已挂在其他报销单上,`warnings` 会明确告知"继续组装存在重复报销风险",Agent 应展示给用户确认。
113
-
114
- > **⚠️ 0.1.19 起 `contractNo` 默认值**:CLI 未收到 `contractNo` 入参时自动使用 `"20260999"` 并产生 warning,不再静默缺失。但仍建议显式传入以确保意图明确。
115
-
116
- ## 与手工路径的关系
117
-
118
- - `invoice.reim.requests.list`(事前申请匹配)仍按 `reim-matching-rules.md` 走,模板不做事前申请绑定。
119
- - 其他流程(出差报销等)或需要逐字段精细控制的场景,仍走 `reim-workflow.md` / `reim-form-fill-rules.md` 的手工组装路径。