weaver-work-cli 0.1.29 → 0.1.31

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 (185) hide show
  1. package/dist/chunks/archive-U766FTFH.js +2537 -0
  2. package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
  3. package/dist/chunks/asset-TCR7VDEV.js +2109 -0
  4. package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
  5. package/dist/chunks/blog-EVZWGDVM.js +2157 -0
  6. package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
  7. package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
  8. package/dist/chunks/chunk-2DUV44UX.js +15606 -0
  9. package/dist/chunks/chunk-324YPTC2.js +1607 -0
  10. package/dist/chunks/chunk-65QMVWHS.js +231 -0
  11. package/dist/chunks/chunk-6V7ZLF34.js +387 -0
  12. package/dist/chunks/chunk-AC7KJWC5.js +358 -0
  13. package/dist/chunks/chunk-AJ62BGAW.js +29 -0
  14. package/dist/chunks/chunk-BUSC6UAE.js +43 -0
  15. package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
  16. package/dist/chunks/chunk-D4LTJSJD.js +477 -0
  17. package/dist/chunks/chunk-EG6ZU444.js +654 -0
  18. package/dist/chunks/chunk-EZALDOQH.js +383 -0
  19. package/dist/chunks/chunk-FMPJJYYI.js +106 -0
  20. package/dist/chunks/chunk-G2JSIUWF.js +769 -0
  21. package/dist/chunks/chunk-GCG2NMWR.js +703 -0
  22. package/dist/chunks/chunk-GPMFD4RD.js +75 -0
  23. package/dist/chunks/chunk-H3WDBYJW.js +508 -0
  24. package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
  25. package/dist/chunks/chunk-J7RJTZSV.js +5556 -0
  26. package/dist/chunks/chunk-LUSPKZKY.js +53 -0
  27. package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
  28. package/dist/chunks/chunk-NOODWMCL.js +584 -0
  29. package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
  30. package/dist/chunks/chunk-P26ZWSKU.js +73 -0
  31. package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
  32. package/dist/chunks/chunk-R2IJAK7T.js +464 -0
  33. package/dist/chunks/chunk-R7O5PUWO.js +205 -0
  34. package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
  35. package/dist/chunks/chunk-VZTXRG6X.js +403 -0
  36. package/dist/chunks/chunk-WHD4XMRP.js +161 -0
  37. package/dist/chunks/chunk-YLCYX7LE.js +371 -0
  38. package/dist/chunks/chunk-ZEDWSH32.js +68 -0
  39. package/dist/chunks/continuation-2CKSBLA6.js +11 -0
  40. package/dist/chunks/continuation-HZIZRZBX.js +13 -0
  41. package/dist/chunks/continuation-NLECEJPX.js +11 -0
  42. package/dist/chunks/ebuilder-form-NJ4YK6CC.js +2276 -0
  43. package/dist/chunks/ehr-MMYN36VA.js +5241 -0
  44. package/dist/chunks/employee-SAK2QYXX.js +11 -0
  45. package/dist/chunks/esb-HIWHOU7Q.js +141 -0
  46. package/dist/chunks/fna-KBACQTA5.js +1444 -0
  47. package/dist/chunks/host-3OHS5QUX.js +21 -0
  48. package/dist/chunks/host-IG6KEH5Q.js +19 -0
  49. package/dist/chunks/host-KQL5N4HO.js +23 -0
  50. package/dist/chunks/host-LLSZQCWR.js +17 -0
  51. package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
  52. package/dist/chunks/im-RN2UKAEU.js +252 -0
  53. package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
  54. package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
  55. package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
  56. package/dist/chunks/mail-LNQLTF6L.js +2695 -0
  57. package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
  58. package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
  59. package/dist/chunks/okr-TMWTIU2K.js +2482 -0
  60. package/dist/chunks/plan-A2FSFA7T.js +2025 -0
  61. package/dist/chunks/project-T26QLBQF.js +1361 -0
  62. package/dist/chunks/registry-2VLUAESA.js +14 -0
  63. package/dist/chunks/registry-JCFEYXOE.js +18 -0
  64. package/dist/chunks/registry-NYPYMZXG.js +16 -0
  65. package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
  66. package/dist/chunks/registry-ZJMJVWFA.js +19 -0
  67. package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
  68. package/dist/chunks/schedule-5L2PM4M6.js +24 -0
  69. package/dist/chunks/state-Y2XBP6YE.js +15 -0
  70. package/dist/chunks/workflow-TR6PG2SL.js +245 -0
  71. package/dist/cmd/argv.js +45 -0
  72. package/dist/cmd/docs/index.js +3 -3
  73. package/dist/cmd/lazy-dispatch.js +20 -0
  74. package/dist/cmd/root.js +2 -4
  75. package/dist/cmd/setup/index.js +2 -2
  76. package/dist/cmd/skills/index.js +2 -2
  77. package/dist/core/package-paths.js +47 -0
  78. package/dist/index.js +163 -7
  79. package/dist/internal/e10/auth/xiaoe.js +3 -3
  80. package/dist/internal/e10/request-runtime.js +18 -62
  81. package/dist/internal/skills/detector.js +2 -2
  82. package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
  83. package/dist/shortcuts/contract/host.js +91 -35
  84. package/dist/shortcuts/contract/index.js +213 -0
  85. package/dist/shortcuts/contract/manifest.js +928 -0
  86. package/dist/shortcuts/contract/ooxml/docx.js +295 -0
  87. package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
  88. package/dist/shortcuts/contract/ooxml/zip.js +158 -0
  89. package/dist/shortcuts/contract/operations/assistant.js +1156 -0
  90. package/dist/shortcuts/contract/operations/clause-library.js +522 -0
  91. package/dist/shortcuts/contract/operations/compare.js +193 -0
  92. package/dist/shortcuts/contract/operations/credit-page.js +34 -0
  93. package/dist/shortcuts/contract/operations/flow.js +98 -0
  94. package/dist/shortcuts/contract/operations/page.js +66 -0
  95. package/dist/shortcuts/contract/operations/performance.js +733 -0
  96. package/dist/shortcuts/contract/operations/quote.js +557 -0
  97. package/dist/shortcuts/contract/operations/recommend.js +78 -0
  98. package/dist/shortcuts/contract/operations/registry.js +18 -0
  99. package/dist/shortcuts/contract/operations/review.js +83 -0
  100. package/dist/shortcuts/contract/operations/shared.js +37 -0
  101. package/dist/shortcuts/contract/operations/upload.js +108 -0
  102. package/dist/shortcuts/contract/operations/write.js +3 -2
  103. package/dist/shortcuts/index.js +140 -40
  104. package/dist/shortcuts/invoice/manifest.js +34 -11
  105. package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
  106. package/dist/shortcuts/invoice/operations/reim.js +81 -5
  107. package/dist/shortcuts/invoice/operations/shared.js +12 -5
  108. package/dist/shortcuts/meeting/host.js +45 -3
  109. package/dist/shortcuts/meeting/invitation/docx.js +442 -0
  110. package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
  111. package/dist/shortcuts/meeting/operations/attachment.js +442 -0
  112. package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
  113. package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
  114. package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
  115. package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
  116. package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
  117. package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
  118. package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
  119. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
  120. package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
  121. package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
  122. package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
  123. package/dist/shortcuts/meeting/operations/invitation.js +458 -0
  124. package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
  125. package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
  126. package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
  127. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  128. package/dist/shortcuts/meeting/operations/registry.js +18 -0
  129. package/dist/shortcuts/meeting/operations/summary.js +276 -0
  130. package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
  131. package/dist/shortcuts/meeting/operations.js +42 -1
  132. package/dist/shortcuts/meeting/qr/encoder.js +427 -0
  133. package/dist/shortcuts/meeting/qr/render.js +103 -0
  134. package/dist/shortcuts/workflow/operations/form.js +17 -5
  135. package/docs/contract.md +39 -4
  136. package/docs/invoice.md +5 -5
  137. package/package.json +3 -2
  138. package/scripts/bundle.mjs +63 -0
  139. package/skill-template/business-info.json +25 -4
  140. package/skill-template/domains/jinchengda.md +16 -3
  141. package/skill-template/domains/yepiaotong.md +1 -1
  142. package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
  143. package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
  144. package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
  145. package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
  146. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
  147. package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
  148. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
  149. package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
  150. package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
  151. package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
  152. package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
  153. package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
  154. package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
  155. package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
  156. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
  157. package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
  158. package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
  159. package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
  160. package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
  161. package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
  162. package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
  163. package/skills/weaver-e10-meeting/SKILL.md +493 -17
  164. package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
  165. package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
  166. package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
  167. package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
  168. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
  169. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
  170. package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
  171. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
  172. package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
  173. package/skills/weaver-e10-meeting.zip +0 -0
  174. package/skills/weaver-e10-yepiaotong/SKILL.md +9 -5
  175. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
  176. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
  177. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
  178. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
  179. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
  180. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
  181. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
  182. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
  183. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
  184. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +6 -0
  185. package/templates/meeting/invitation.docx +0 -0
@@ -0,0 +1,2357 @@
1
+ import { createRequire as __esbuildCreateRequire } from 'node:module';
2
+ const require = __esbuildCreateRequire(import.meta.url);
3
+ import {
4
+ CliError
5
+ } from "./chunk-LUSPKZKY.js";
6
+
7
+ // src/shortcuts/meeting/errors.ts
8
+ var MeetingCliError = class extends CliError {
9
+ type;
10
+ subtype;
11
+ code;
12
+ retryable;
13
+ stage;
14
+ details;
15
+ partialData;
16
+ constructor(type, subtype, message, options = {}) {
17
+ super(message, options.exitCode ?? 5 /* InternalError */);
18
+ this.name = "MeetingCliError";
19
+ this.type = type;
20
+ this.subtype = subtype;
21
+ this.code = options.code;
22
+ this.retryable = options.retryable ?? false;
23
+ this.stage = options.stage;
24
+ this.details = options.details;
25
+ this.partialData = options.partialData;
26
+ }
27
+ };
28
+ function meetingValidationError(subtype, message, details) {
29
+ return new MeetingCliError("validation", subtype, message, {
30
+ details,
31
+ exitCode: 2 /* UsageError */
32
+ });
33
+ }
34
+ function meetingAuthError(subtype, message, details) {
35
+ return new MeetingCliError("authentication", subtype, message, {
36
+ details,
37
+ exitCode: 3 /* AuthError */
38
+ });
39
+ }
40
+ function meetingNetworkError(subtype, message, options = {}) {
41
+ return new MeetingCliError("network", subtype, message, {
42
+ ...options,
43
+ retryable: options.retryable ?? true,
44
+ exitCode: 4 /* NetworkError */
45
+ });
46
+ }
47
+ function meetingConfirmationError(action, details) {
48
+ return new MeetingCliError("confirmation", "required", "\u8BE5\u64CD\u4F5C\u9700\u8981\u660E\u786E\u786E\u8BA4", {
49
+ details: { action, ...details },
50
+ exitCode: 10 /* ConfirmationRequired */
51
+ });
52
+ }
53
+ function meetingPartialError(message, partialData, details) {
54
+ return new MeetingCliError("partial", "write_uncertain", message, {
55
+ details,
56
+ partialData,
57
+ exitCode: 11 /* Partial */
58
+ });
59
+ }
60
+ function meetingConflictError(subtype, message, details) {
61
+ return new MeetingCliError("policy", subtype, message, {
62
+ details,
63
+ exitCode: 10 /* ConfirmationRequired */
64
+ });
65
+ }
66
+
67
+ // src/shortcuts/meeting/operations/types.ts
68
+ function meetingSuccess(action, data, options = {}) {
69
+ const payload = { ok: true, action, data };
70
+ if (options.meta && Object.keys(options.meta).length > 0) payload.meta = options.meta;
71
+ if (options.warnings && options.warnings.length > 0) payload.warnings = options.warnings;
72
+ return payload;
73
+ }
74
+ function schemaOf(properties, options = {}) {
75
+ return {
76
+ type: "object",
77
+ additionalProperties: false,
78
+ properties,
79
+ ...options.required?.length ? { required: options.required } : {},
80
+ ...options.description ? { description: options.description } : {}
81
+ };
82
+ }
83
+ var SCHEMA_ID = { oneOf: [{ type: "integer" }, { type: "string", pattern: "^\\d+$" }] };
84
+ var SCHEMA_ID_LIST = { type: "array", items: SCHEMA_ID };
85
+ var SCHEMA_DATETIME_MINUTE = { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$" };
86
+ var SCHEMA_DATE = { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$" };
87
+
88
+ // src/shortcuts/meeting/operations/eb/factory.ts
89
+ import { createHash } from "node:crypto";
90
+
91
+ // src/shortcuts/meeting/operations/shared.ts
92
+ var FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
93
+ "cookie",
94
+ "eteamsid",
95
+ "eteam_sid",
96
+ "token",
97
+ "authorization",
98
+ "appkey",
99
+ "app_secret",
100
+ "appsecret"
101
+ ]);
102
+ function asObject(value) {
103
+ return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
104
+ }
105
+ function assertNoForbiddenKeys(input) {
106
+ for (const key of Object.keys(input)) {
107
+ if (FORBIDDEN_KEYS.has(key.toLowerCase())) {
108
+ throw meetingValidationError("forbidden_input_key", `\u8F93\u5165\u4E0D\u5141\u8BB8\u643A\u5E26\u8BA4\u8BC1\u5B57\u6BB5\uFF1A${key}`);
109
+ }
110
+ }
111
+ }
112
+ function assertDateTimeMinute(value, label) {
113
+ if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(value)) {
114
+ throw meetingValidationError("datetime_invalid", `${label} \u5FC5\u987B\u662F yyyy-MM-dd HH:mm \u683C\u5F0F`);
115
+ }
116
+ return value;
117
+ }
118
+ function assertDateTimeSecond(value, label) {
119
+ if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(value)) {
120
+ throw meetingValidationError("datetime_invalid", `${label} \u5FC5\u987B\u662F yyyy-MM-dd HH:mm:ss \u683C\u5F0F\uFF08\u5E26\u79D2\uFF09`);
121
+ }
122
+ return value;
123
+ }
124
+ function assertDate(value, label) {
125
+ if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) {
126
+ throw meetingValidationError("date_invalid", `${label} \u5FC5\u987B\u662F yyyy-MM-dd \u683C\u5F0F`);
127
+ }
128
+ return value;
129
+ }
130
+ function toIdString(value, label) {
131
+ if (typeof value === "number") {
132
+ if (!Number.isSafeInteger(value)) {
133
+ throw meetingValidationError("id_invalid", `${label} \u8D85\u8FC7\u5B89\u5168\u6574\u6570\u8303\u56F4\uFF0C\u5FC5\u987B\u7528\u5B57\u7B26\u4E32\u4F20`);
134
+ }
135
+ return String(value);
136
+ }
137
+ if (typeof value === "string" && /^\d+$/.test(value)) return value;
138
+ throw meetingValidationError("id_invalid", `${label} \u5FC5\u987B\u662F\u6570\u5B57 id\uFF08\u8D85\u957F id \u7528\u5B57\u7B26\u4E32\uFF09`);
139
+ }
140
+ function pickBusinessInput(args) {
141
+ const out = {};
142
+ for (const [key, value] of Object.entries(args)) {
143
+ if (key === "confirm" || key === "continuation") continue;
144
+ if (value === void 0) continue;
145
+ out[key] = value;
146
+ }
147
+ return out;
148
+ }
149
+ function mergeSnapshot(snapshot, args) {
150
+ const base = snapshot && typeof snapshot === "object" ? { ...snapshot } : {};
151
+ return { ...base, ...pickBusinessInput(args) };
152
+ }
153
+ function toIdCsv(value, label) {
154
+ if (value === void 0 || value === null || value === "") return void 0;
155
+ const parts = Array.isArray(value) ? value : String(value).split(",");
156
+ return parts.map((item) => toIdString(item, label).trim()).filter(Boolean).join(",");
157
+ }
158
+ function extractRows(value) {
159
+ const data = value?.data ?? value;
160
+ if (Array.isArray(data?.displayData)) {
161
+ return { rows: data.displayData, total: data.total };
162
+ }
163
+ if (Array.isArray(data?.data?.rows)) {
164
+ return { rows: data.data.rows, total: data.data.count ?? data.total };
165
+ }
166
+ if (Array.isArray(data?.rows)) {
167
+ return { rows: data.rows, total: data.count ?? data.total };
168
+ }
169
+ if (Array.isArray(data?.data)) {
170
+ return { rows: data.data, total: data.total };
171
+ }
172
+ if (Array.isArray(data?.datas)) {
173
+ return { rows: data.datas, total: data.total };
174
+ }
175
+ return { rows: [], total: 0 };
176
+ }
177
+ function extractConflict(value) {
178
+ const payload = value?.data ?? value ?? {};
179
+ const cansubRaw = payload.cansub ?? payload.canSub;
180
+ const cansub = typeof cansubRaw === "boolean" ? cansubRaw : void 0;
181
+ const message = [payload.conflictMsg, payload.conflictmsg, payload.message, payload.msg].find((item) => typeof item === "string" && item.trim()) || "";
182
+ return { cansub, message };
183
+ }
184
+ async function assertMeetingExists(id, host, operation) {
185
+ try {
186
+ await host.request({
187
+ method: "GET",
188
+ path: "/api/meeting/detail/getMeetingDetailField",
189
+ operation,
190
+ query: { id }
191
+ });
192
+ } catch (error) {
193
+ throw meetingValidationError(
194
+ "meeting_not_operable",
195
+ `\u672A\u80FD\u786E\u8BA4\u4F1A\u8BAE ${id} \u5B58\u5728\u6216\u53EF\u8BFB\uFF08getMeetingDetailField \u67E5\u8BE2\u5931\u8D25\uFF09\uFF1A${error instanceof Error ? error.message : String(error)}`
196
+ );
197
+ }
198
+ }
199
+
200
+ // src/shortcuts/meeting/operations/eb/attendance-summary.ts
201
+ function toText(value) {
202
+ return value === void 0 || value === null ? "" : String(value).trim();
203
+ }
204
+ function rate(part, whole) {
205
+ if (whole <= 0) return "0.0%";
206
+ return `${(part / whole * 100).toFixed(1)}%`;
207
+ }
208
+ function normalizeSignState(isSign, signTime) {
209
+ const text = toText(isSign);
210
+ if (text === "") {
211
+ return toText(signTime) === "" ? "notSigned" : "normal";
212
+ }
213
+ if (text.includes("\u6B63\u5E38")) return "normal";
214
+ if (text.includes("\u8BF7\u5047")) return "leave";
215
+ if (text.includes("\u8FDF\u5230\u65E9\u9000")) return "lateAndEarlyLeave";
216
+ if (text.includes("\u8FDF\u5230\u672A\u7B7E\u9000")) return "lateAndNotSignedOut";
217
+ if (text.includes("\u8FDF\u5230")) return "late";
218
+ if (text.includes("\u65E9\u9000")) return "earlyLeave";
219
+ if (text.includes("\u672A\u7B7E\u9000")) return "notSignedOut";
220
+ if (text === "0" || text.includes("\u7F3A\u5E2D")) return "absent";
221
+ switch (text) {
222
+ case "1":
223
+ return "normal";
224
+ case "2":
225
+ return "leave";
226
+ case "3":
227
+ return "late";
228
+ case "4":
229
+ return "earlyLeave";
230
+ case "5":
231
+ return "notSignedOut";
232
+ case "6":
233
+ return "lateAndNotSignedOut";
234
+ case "7":
235
+ return "lateAndEarlyLeave";
236
+ default:
237
+ return "unknown";
238
+ }
239
+ }
240
+ var SIGN_STATES = [
241
+ "normal",
242
+ "leave",
243
+ "late",
244
+ "earlyLeave",
245
+ "notSignedOut",
246
+ "lateAndNotSignedOut",
247
+ "lateAndEarlyLeave",
248
+ "absent",
249
+ "notSigned",
250
+ "unknown"
251
+ ];
252
+ function summarizeSignRows(rows) {
253
+ const byState = Object.fromEntries(SIGN_STATES.map((key) => [key, 0]));
254
+ const items = rows.map((row) => {
255
+ const main = row?.mainTable ?? row ?? {};
256
+ const state = normalizeSignState(main.is_sign, main.sign_time);
257
+ byState[state] += 1;
258
+ return {
259
+ id: toText(main.id),
260
+ userId: toText(main.user_id),
261
+ mtRef: toText(main.mt_id),
262
+ state,
263
+ signTime: toText(main.sign_time),
264
+ signBackTime: toText(main.signback_time),
265
+ signOutStatus: toText(main.sign_out_status)
266
+ };
267
+ });
268
+ const total = items.length;
269
+ const notSigned = byState.notSigned;
270
+ const signed = total - notSigned;
271
+ return {
272
+ summary: {
273
+ total,
274
+ signed,
275
+ notSigned,
276
+ signedOut: items.filter((item) => item.signOutStatus === "0").length,
277
+ // 出席率按"已签到"口径(未签到 = 没来),比把"缺席"也算作出席更直观。
278
+ attendanceRate: rate(signed, total),
279
+ byState
280
+ },
281
+ items
282
+ };
283
+ }
284
+ function normalizeReceiptState(raw) {
285
+ const text = toText(raw);
286
+ if (text === "") return "noReply";
287
+ if (text === "1" || text.includes("\u53C2\u52A0") && !text.includes("\u4E0D\u53C2\u52A0")) return "attend";
288
+ if (text === "0" || text.includes("\u4E0D\u53C2\u52A0")) return "decline";
289
+ return "unknown";
290
+ }
291
+ function summarizeReceiptRows(rows) {
292
+ const byMemberType = { attendee: 0, customer: 0, other: 0, unknown: 0 };
293
+ const items = rows.map((row) => {
294
+ const main = row?.mainTable ?? row ?? {};
295
+ const memberType = toText(main.member_type);
296
+ if (memberType === "1") byMemberType.attendee += 1;
297
+ else if (memberType === "2") byMemberType.customer += 1;
298
+ else if (memberType === "3") byMemberType.other += 1;
299
+ else byMemberType.unknown += 1;
300
+ return {
301
+ id: toText(main.id),
302
+ memberId: toText(main.member_id),
303
+ mtRef: toText(main.mt_id),
304
+ state: normalizeReceiptState(main.attend_status),
305
+ memberType,
306
+ attendStatus: toText(main.attend_status),
307
+ bookRoom: toText(main.book_room),
308
+ bookTicket: toText(main.book_ticket)
309
+ };
310
+ });
311
+ const total = items.length;
312
+ const attend = items.filter((item) => item.state === "attend").length;
313
+ const decline = items.filter((item) => item.state === "decline").length;
314
+ const replied = attend + decline;
315
+ return {
316
+ summary: {
317
+ total,
318
+ attend,
319
+ decline,
320
+ noReply: total - replied,
321
+ replyRate: rate(replied, total),
322
+ attendRate: rate(attend, total),
323
+ byMemberType,
324
+ bookRoom: items.filter((item) => item.bookRoom !== "").length,
325
+ bookTicket: items.filter((item) => item.bookTicket !== "").length
326
+ },
327
+ items
328
+ };
329
+ }
330
+
331
+ // src/shortcuts/meeting/operations/eb/room-summary.ts
332
+ var ROOM_STATUS = {
333
+ "0": "\u6B63\u5E38",
334
+ "1": "\u5C01\u5B58"
335
+ };
336
+ var ROOM_ATTR = {
337
+ "0": "\u5B9E\u4F53",
338
+ "1": "\u865A\u62DF",
339
+ "2": "\u7EC4\u5408"
340
+ };
341
+ function toText2(value) {
342
+ if (value === void 0 || value === null) return "";
343
+ if (typeof value === "object") {
344
+ const obj = value;
345
+ if (typeof obj.name === "string") return obj.name;
346
+ if (typeof obj.value === "string") return obj.value;
347
+ if (typeof obj.id === "string") return obj.id;
348
+ return "";
349
+ }
350
+ return String(value).trim();
351
+ }
352
+ function normalizeRoomStatus(raw) {
353
+ const text = toText2(raw);
354
+ if (text === "" || text === "0" || text === "\u6B63\u5E38") {
355
+ return { code: text === "" ? "" : "0", text: text === "" ? "\u672A\u8BBE\u7F6E" : "\u6B63\u5E38" };
356
+ }
357
+ if (text === "1" || text === "\u5C01\u5B58") return { code: "1", text: "\u5C01\u5B58" };
358
+ return { code: text, text };
359
+ }
360
+ function normalizeRoomAttr(raw) {
361
+ const text = toText2(raw);
362
+ if (text === "") return "\u672A\u8BBE\u7F6E";
363
+ return ROOM_ATTR[text] ?? text;
364
+ }
365
+ function summarizeRoomRows(rows) {
366
+ const byStatus = { \u6B63\u5E38: 0, \u5C01\u5B58: 0, \u672A\u8BBE\u7F6E: 0 };
367
+ const items = rows.map((row) => {
368
+ const main = row?.mainTable ?? row ?? {};
369
+ const status = normalizeRoomStatus(main.status);
370
+ byStatus[status.text] = (byStatus[status.text] ?? 0) + 1;
371
+ return {
372
+ id: toText2(main.id),
373
+ roomName: toText2(main.room_name),
374
+ status: status.code,
375
+ statusText: status.text,
376
+ roomAttr: toText2(main.room_attr),
377
+ roomAttrText: normalizeRoomAttr(main.room_attr),
378
+ allowMinNum: toText2(main.allow_minnum),
379
+ allowMaxNum: toText2(main.allow_maxnum),
380
+ place: toText2(main.place),
381
+ equipments: toText2(main.equipments)
382
+ };
383
+ });
384
+ return {
385
+ /** 语义字典:`0`=正常(可用)、`1`=封存(不可用)。写进返回体,避免被读反。 */
386
+ legend: {
387
+ status: ROOM_STATUS,
388
+ roomAttr: ROOM_ATTR,
389
+ note: 'status\uFF1A0 = \u6B63\u5E38\uFF08\u53EF\u7528\uFF09\uFF0C1 = \u5C01\u5B58\uFF08\u4E0D\u53EF\u7528\uFF09\uFF1B\u4E0D\u8981\u8BFB\u6210"\u542F\u7528/\u505C\u7528"'
390
+ },
391
+ summary: {
392
+ total: items.length,
393
+ byStatus,
394
+ /** 当前页里"封存/未设置"的房间名,便于直接提示用户哪些不可用。 */
395
+ unusable: items.filter((item) => item.statusText !== "\u6B63\u5E38").map((item) => item.roomName)
396
+ },
397
+ items
398
+ };
399
+ }
400
+
401
+ // src/shortcuts/meeting/operations/eb/task-progress.ts
402
+ function toText3(value) {
403
+ return value === void 0 || value === null ? "" : String(value);
404
+ }
405
+ function normalizeFinishStatus(raw) {
406
+ const text = toText3(raw).trim();
407
+ if (text === "") return "pending";
408
+ if (text === "1" || text.includes("\u5DF2\u5B8C\u6210") || text === "\u5B8C\u6210") return "done";
409
+ if (text === "2" || text.includes("\u5EF6\u671F")) return "overdue";
410
+ return "pending";
411
+ }
412
+ function toPeople(raw) {
413
+ const list = raw === void 0 || raw === null ? [] : Array.isArray(raw) ? raw : [raw];
414
+ const out = [];
415
+ const seen = /* @__PURE__ */ new Set();
416
+ for (const item of list) {
417
+ if (item === void 0 || item === null) continue;
418
+ if (typeof item === "object") {
419
+ const id = toText3(item.id).trim();
420
+ if (id === "" || seen.has(id)) continue;
421
+ seen.add(id);
422
+ out.push({ id, name: toText3(item.name) });
423
+ } else {
424
+ const id = toText3(item).trim();
425
+ if (id === "" || seen.has(id)) continue;
426
+ seen.add(id);
427
+ out.push({ id, name: "" });
428
+ }
429
+ }
430
+ return out;
431
+ }
432
+ function summarizeRow(row) {
433
+ const main = row?.mainTable ?? row ?? {};
434
+ const mt = main.mt_id ?? {};
435
+ const followed = /* @__PURE__ */ new Map();
436
+ const details = Array.isArray(row?.detail1) ? row.detail1 : [];
437
+ for (const item of details) {
438
+ const who = toPeople(item?.executor)[0];
439
+ if (!who) continue;
440
+ followed.set(who.id, {
441
+ status: normalizeFinishStatus(item?.finish_status),
442
+ finishDate: toText3(item?.finish_date)
443
+ });
444
+ }
445
+ const members = toPeople(main.executors).map((person) => {
446
+ const hit = followed.get(person.id);
447
+ return {
448
+ executorId: person.id,
449
+ executorName: person.name,
450
+ status: hit ? hit.status : "pending",
451
+ finishDate: hit ? hit.finishDate : ""
452
+ };
453
+ });
454
+ if (members.length === 0) {
455
+ for (const [id, hit] of followed) {
456
+ members.push({ executorId: id, executorName: "", status: hit.status, finishDate: hit.finishDate });
457
+ }
458
+ }
459
+ const done = members.filter((item) => item.status === "done").length;
460
+ const overdue = members.filter((item) => item.status === "overdue").length;
461
+ const pending = members.length - done - overdue;
462
+ const status = members.length === 0 ? "pending" : done === members.length ? "done" : overdue > 0 ? "overdue" : done > 0 ? "inProgress" : "pending";
463
+ return {
464
+ id: toText3(main.id),
465
+ title: toText3(main.decision_title),
466
+ mtId: toText3(mt.id),
467
+ mtName: toText3(mt.name),
468
+ plan: { begin: toText3(main.begin_datetime), end: toText3(main.end_datetime) },
469
+ progress: { total: members.length, done, overdue, pending, status, members }
470
+ };
471
+ }
472
+ function summarizeTaskProgress(rows) {
473
+ const items = rows.map((row) => summarizeRow(row ?? {}));
474
+ return {
475
+ summary: {
476
+ total: items.length,
477
+ done: items.filter((item) => item.progress.status === "done").length,
478
+ overdue: items.filter((item) => item.progress.status === "overdue").length,
479
+ inProgress: items.filter((item) => item.progress.status === "inProgress").length,
480
+ pending: items.filter((item) => item.progress.status === "pending").length
481
+ },
482
+ items
483
+ };
484
+ }
485
+
486
+ // src/shortcuts/meeting/operations/eb/catalog.ts
487
+ var MEETING_FIELDS_CREATE = [
488
+ "mt_creator",
489
+ "mt_name",
490
+ "begin_datetime",
491
+ "end_datetime",
492
+ "mt_status",
493
+ "operate_type",
494
+ "is_decision",
495
+ "mt_type",
496
+ "caller",
497
+ "contacter",
498
+ "mt_format",
499
+ "mt_desc",
500
+ "mt_hours",
501
+ "address",
502
+ "customize_address",
503
+ "org_members",
504
+ "hrm_members",
505
+ "total_member",
506
+ "inviters",
507
+ "topic_presenter",
508
+ "project",
509
+ "mt_address_hrms",
510
+ "quicktimedesc",
511
+ "video_url",
512
+ "with_secauth",
513
+ "project_files",
514
+ "mt_accessorys",
515
+ "all_day",
516
+ "other_members",
517
+ "crm_members",
518
+ "crm_total_member",
519
+ "next_occur_date",
520
+ "repeat_status",
521
+ "repeat_id",
522
+ "request_id",
523
+ "attend_user",
524
+ "attending_units",
525
+ "reporting_user",
526
+ "reporting_unit",
527
+ "other_remark"
528
+ ];
529
+ var MEETING_FIELDS_CHANGE = [
530
+ "id",
531
+ "operate_type",
532
+ "mt_creator",
533
+ "inviters",
534
+ "topic_presenter",
535
+ "project",
536
+ "mt_address_hrms",
537
+ "mt_name",
538
+ "decision_Id",
539
+ "quicktimedesc",
540
+ "is_decision",
541
+ "mt_type",
542
+ "video_url",
543
+ "with_secauth",
544
+ "caller",
545
+ "contacter",
546
+ "project_files",
547
+ "mt_format",
548
+ "mt_desc",
549
+ "mt_accessorys",
550
+ "begin_datetime",
551
+ "end_datetime",
552
+ "all_day",
553
+ "mt_hours",
554
+ "address",
555
+ "customize_address",
556
+ "org_members",
557
+ "hrm_members",
558
+ "total_member",
559
+ "other_members",
560
+ "crm_members",
561
+ "crm_total_member",
562
+ "next_occur_date",
563
+ "repeat_status",
564
+ "repeat_id",
565
+ "request_id",
566
+ "mt_status",
567
+ "attend_user",
568
+ "attending_units",
569
+ "reporting_user",
570
+ "reporting_unit",
571
+ "other_remark"
572
+ ];
573
+ var TOPIC_FIELDS_V2 = [
574
+ "topic_title",
575
+ "topic_presenter",
576
+ "allow_repeat",
577
+ "urgency",
578
+ "topic_type",
579
+ "topic_num",
580
+ "proposal_person",
581
+ "proposal_dept",
582
+ "proposal_date",
583
+ "related_materials",
584
+ "topic_status",
585
+ "tel",
586
+ "remark",
587
+ "topic_content",
588
+ "topic_text",
589
+ "request_id",
590
+ "mt_id",
591
+ "attend_num"
592
+ ];
593
+ var MEETING_TOPIC_DETAIL = [
594
+ {
595
+ node: "detail1",
596
+ fields: [
597
+ "relate_topic",
598
+ "topic_no",
599
+ "topic_type",
600
+ "topic_subject",
601
+ "topic_presenter",
602
+ "topic_hrmid",
603
+ "duration",
604
+ "start_time",
605
+ "end_time",
606
+ "topic_materials",
607
+ "topic_status",
608
+ "is_open",
609
+ "attend_user",
610
+ "attending_units",
611
+ "reporting_user",
612
+ "reporting_unit"
613
+ ],
614
+ dateFields: ["start_time", "end_time"],
615
+ enumFields: { topic_status: ["0", "1", "2"], is_open: ["0", "1"] },
616
+ purpose: "\u8BAE\u9898\u660E\u7EC6\uFF1A\u6BCF\u6761 = \u4E00\u4E2A\u8BAE\u9898\uFF08duration \u8BA1\u5212\u65F6\u957F\uFF0C\u5355\u4F4D\u5206\u949F\uFF09"
617
+ }
618
+ ];
619
+ var TOPIC_FIELDS_CREATE = [...TOPIC_FIELDS_V2];
620
+ var TOPIC_FIELDS_UPDATE = ["id", ...TOPIC_FIELDS_V2];
621
+ var SIGN_FIELDS_CREATE = [
622
+ "mt_id",
623
+ "hylx",
624
+ "site",
625
+ "sign_flag",
626
+ "user_id",
627
+ "attend_type",
628
+ "sign_time",
629
+ "sign_reson",
630
+ "is_sign",
631
+ "longitude",
632
+ "latitude",
633
+ "sign_remark",
634
+ "signback_time",
635
+ "backsite",
636
+ "map_type",
637
+ "map_typeback",
638
+ "signback_longitude",
639
+ "signback_latitude",
640
+ "allow_late_time",
641
+ "sign_out_status",
642
+ "external_flag",
643
+ "external_name",
644
+ "external_email",
645
+ "external_phone",
646
+ "external_remark",
647
+ "sub_dept",
648
+ "department"
649
+ ];
650
+ var SIGN_FIELDS_UPDATE = ["id", ...SIGN_FIELDS_CREATE];
651
+ var ROOM_FIELDS = [
652
+ "id",
653
+ "room_name",
654
+ "hrm_ids",
655
+ "org_id",
656
+ "status",
657
+ "mr_type",
658
+ "place",
659
+ "room_attr",
660
+ "allow_minnum",
661
+ "allow_maxnum",
662
+ "rs_style",
663
+ "room_desc",
664
+ "equipments",
665
+ "dsporder",
666
+ "images",
667
+ "work_place",
668
+ "vrm_check",
669
+ "slaver_rooms",
670
+ "arrange_seat",
671
+ "min_numchk",
672
+ "min_numchk_type",
673
+ "max_numchk",
674
+ "max_numchk_type",
675
+ "can_orderday",
676
+ "only_workday",
677
+ "max_orderday"
678
+ ];
679
+ var EB_ENDPOINTS = [
680
+ {
681
+ domain: "meeting",
682
+ operation: "meeting.eb.meeting.list",
683
+ kind: "list",
684
+ interfacePk: "query_mtDetail_list",
685
+ countPk: "query_mtDetail_count",
686
+ queryParams: [
687
+ "mt_id",
688
+ "creator",
689
+ "mt_name",
690
+ "mt_status",
691
+ "mt_type",
692
+ "caller",
693
+ "contacter",
694
+ "enddatetime",
695
+ "begindatetime",
696
+ "address",
697
+ "hrmmember",
698
+ "attend_user",
699
+ "reporting_user",
700
+ "topic_presenter",
701
+ "request_id"
702
+ ],
703
+ summary: "EB \u7248\u4F1A\u8BAE\u5217\u8868\uFF08query_mtDetail_list + count\uFF09\uFF1AURL query \u4F20\u7B5B\u9009\u6761\u4EF6\uFF0Cbody \u5E26 datajson",
704
+ notes: [
705
+ "hrmmember \u7B49\u4EBA\u5458\u53C2\u6570\u5FC5\u987B\u4F20\u5458\u5DE5 id\uFF0C\u4E0D\u80FD\u4F20\u59D3\u540D\u6587\u672C\u3002",
706
+ "mt_status\uFF1A0\u8349\u7A3F/1\u5BA1\u6279\u4E2D/2\u672A\u5F00\u59CB/3\u9000\u56DE/4\u53D6\u6D88/5\u63D0\u524D\u7ED3\u675F/6\u5220\u9664/7\u9501\u5B9A/8\u7ED3\u675F/9\u8FDB\u884C\u4E2D/10\u5BA1\u6279\u4E2D(\u53D8\u66F4)/11\u5BA1\u6279\u4E2D(\u53D6\u6D88)\u3002",
707
+ "enddatetime=\u5F00\u59CB\u65F6\u95F4<(lt)\u3001begindatetime=\u7ED3\u675F\u65F6\u95F4>(gt)\u3002"
708
+ ]
709
+ },
710
+ {
711
+ domain: "meeting",
712
+ operation: "meeting.eb.meeting.detail",
713
+ kind: "detail",
714
+ interfacePk: "query_mtDetail_info",
715
+ summary: "EB \u7248\u4F1A\u8BAE\u8BE6\u60C5\uFF08query_mtDetail_info\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09\uFF1A\u4E3B\u8868 50 \u5B57\u6BB5 + detail1 \u8BAE\u9898\u660E\u7EC6",
716
+ notes: [
717
+ "\u2705 2026-10-28 \u8D77\u8FD4\u56DE\u4F53\u542B `details.detail1`\uFF08\u4F1A\u8BAE\u8BAE\u9898\u660E\u7EC6\u884C\uFF1Atopic_no / topic_subject / topic_presenter / duration / start_time / end_time / topic_status \u7B49\uFF09\u2014\u2014\u63A5\u53E3\u914D\u7F6E\u4E86\u8FD4\u56DE\u660E\u7EC6\uFF0C\u6B64\u524D CLI \u8BEF\u4E22\u5F03\u4E86\u884C\u5185 mainTable \u4EE5\u5916\u7684\u8282\u70B9\uFF0C\u73B0\u5DF2\u539F\u6837\u900F\u51FA\u5230 `data.details`\u3002",
718
+ "`relate_topic` \u5728\u660E\u7EC6\u884C\u91CC**\u56DE\u663E\u4E3A\u6807\u9898\u6587\u672C**\uFF08eBuilder \u5173\u8054\u5B57\u6BB5\u884C\u4E3A\uFF09\uFF0C\u5199\u65F6\u4F20\u8BAE\u9898\u5E93 id\u3002",
719
+ "\u660E\u7EC6\u884C `topic_status` \u662F**\u4F1A\u4E2D\u8FDB\u5EA6**\u8BED\u4E49\uFF1A0 \u5F85\u5F00\u59CB / 1 \u8FDB\u884C\u4E2D / 2 \u5DF2\u7ED3\u675F\u2014\u2014\u4E0E\u8BAE\u9898\u5E93\u7684 1 \u5448\u6279\u4E2D / 2 \u5F85\u4E0A\u4F1A / 3 \u5DF2\u4E0A\u4F1A\u662F\u4E24\u5957\u53D6\u503C\uFF0C\u4E0D\u8981\u6DF7\u7528\u3002",
720
+ '\u8981\u786E\u8BA4"\u4F1A\u8BAE\u6302\u4E86\u54EA\u4E9B\u8BAE\u9898"\uFF0C\u4F18\u5148\u7528\u672C\u63A5\u53E3\u7684 `details.detail1`\uFF1B`meeting.eb.topic.list` \u4F20 `mt_id` \u662F\u300C\u8BAE\u9898\u5E93 \u2192 \u4F1A\u8BAE\u300D\u7684\u53CD\u5411\u5173\u8054\uFF0C\u53EF\u4F5C\u4EA4\u53C9\u9A8C\u8BC1\u3002',
721
+ '\u26A0\uFE0F \u4E3B\u8868 `topic_presenter` / `attend_user` / `reporting_user` \u7B49\u300C\u6C47\u603B\u660E\u7EC6\u300D\u5B57\u6BB5\u7531**\u9875\u9762\u4FDD\u5B58**\u65F6\u56DE\u5199\uFF0C\u8D70\u63A5\u53E3\u5199 detail1 **\u4E0D\u4F1A**\u5237\u65B0\u5B83\u4EEC\u3002\u5B83\u4EEC\u4E3A\u7A7A\u7684**\u4E0D\u80FD**\u8BC1\u660E"\u660E\u7EC6\u6CA1\u5199\u8FDB\u53BB"\uFF082026-10-27 \u5DEE\u70B9\u636E\u6B64\u8BEF\u5224\uFF09\u3002'
722
+ ]
723
+ },
724
+ {
725
+ domain: "meeting",
726
+ operation: "meeting.eb.meeting.create",
727
+ kind: "create",
728
+ interfacePk: "create_meeting",
729
+ fields: MEETING_FIELDS_CREATE,
730
+ requiredFields: ["mt_creator", "mt_name", "begin_datetime", "end_datetime", "mt_status", "operate_type"],
731
+ dateFields: ["begin_datetime", "end_datetime"],
732
+ details: MEETING_TOPIC_DETAIL,
733
+ summary: "EB \u7248\u65B0\u5EFA\u4F1A\u8BAE\uFF08create_meeting\uFF09\uFF1Adatas[].mainTable \u4F20\u5B57\u6BB5\uFF0C\u4E0D\u4F20 id",
734
+ notes: [
735
+ "caller/contacter \u672A\u6307\u660E\u65F6\u9ED8\u8BA4\u5F53\u524D\u64CD\u4F5C\u4EBA\u3002",
736
+ "mt_hours \u7531 CLI \u6309 begin/end \u81EA\u52A8\u8BA1\u7B97\uFF08\u5C0F\u65F6\uFF0C\u652F\u6301\u5C0F\u6570\uFF09\u3002",
737
+ "detail1 = \u8BAE\u9898\u660E\u7EC6\uFF0C\u521B\u5EFA\u65F6\u5373\u53EF\u4E00\u5E76\u5199\u5165\uFF08\u6BCF\u6761\u4E00\u4E2A\u8BAE\u9898\uFF0Cduration \u5355\u4F4D\u5206\u949F\uFF09\u3002"
738
+ ]
739
+ },
740
+ {
741
+ domain: "meeting",
742
+ operation: "meeting.eb.meeting.change",
743
+ kind: "update",
744
+ interfacePk: "change_meeting",
745
+ fields: MEETING_FIELDS_CHANGE,
746
+ requiredFields: ["id", "operate_type"],
747
+ dateFields: ["begin_datetime", "end_datetime", "next_occur_date"],
748
+ // 主键必须走 URL(updateFormData 端点统一要求,2026-09-21 真机实测)
749
+ pkQueryParam: "id",
750
+ details: MEETING_TOPIC_DETAIL,
751
+ // 议题明细支持整组替换:变更会议时用 detail1Mode=cover 可避免重复追加
752
+ detailCover: true,
753
+ summary: "EB \u7248\u53D8\u66F4\u4F1A\u8BAE\uFF08change_meeting\uFF09\uFF1A\u5FC5\u4F20 id + operate_type\uFF1B\u53D6\u6D88\u4F1A\u8BAE\u4E5F\u7528\u672C\u63A5\u53E3",
754
+ notes: [
755
+ "\u53D8\u66F4\u7528 CHANGE\uFF1B\u53D6\u6D88\u7528 CANCEL \u5E76\u7F6E mt_status=4\u3002",
756
+ '\u26D4 detail1 \u9ED8\u8BA4\u300C\u8FFD\u52A0\u300D\u4E0D\u662F\u8986\u76D6\uFF1A\u91CD\u590D\u6267\u884C\u4F1A\u591A\u51FA\u9898\u76EE\u884C\u3002\u8981\u66FF\u6362\u6574\u7EC4\u8BAE\u9898\u5FC5\u987B\u4F20 `detail1Mode: "cover"`\u3002',
757
+ "\u53EA\u6302\u8BAE\u9898\u3001\u4E0D\u52A8\u4F1A\u8BAE\u5176\u5B83\u5B57\u6BB5\u65F6\uFF1A\u4F20 id + operate_type=CHANGE + detail1 \u5373\u53EF\u3002",
758
+ "\u2605 detail1 \u5B57\u6BB5\u53E3\u5F84\uFF1A`relate_topic` \u5FC5\u987B\u5B58**\u8BAE\u9898\u5E93 id**\uFF08\u8DE8\u8868\u5355\u5173\u8054\u952E\uFF0C\u4E0D\u662F\u6807\u9898\u6587\u672C\uFF09\uFF1B`topic_subject` / `topic_no` \u662F\u6587\u672C\uFF1B`duration` \u5355\u4F4D\u5206\u949F\uFF08Number\uFF09\uFF1B`start_time` / `end_time` \u4E3A `yyyy-MM-dd HH:mm`\uFF0C\u7531\u4F1A\u8BAE\u5F00\u59CB\u65F6\u95F4\u6309\u5404\u8BAE\u9898\u65F6\u957F\u987A\u6B21\u63A8\u7B97\u3002",
759
+ '\u26A0\uFE0F \u672C\u63A5\u53E3\u53EA\u56DE `dataIds` + `status:true`\uFF0C**\u4E0D\u56DE\u5199\u3001\u4E5F\u65E0\u6CD5\u56DE\u8BFB\u660E\u7EC6**\uFF08\u89C1 `meeting.eb.meeting.detail` \u7684\u8BF4\u660E\uFF09\u3002\u670D\u52A1\u7AEF\u5BF9\u660E\u7EC6\u5B57\u6BB5**\u4E0D\u505A\u6821\u9A8C**\uFF08\u4F20\u4E0D\u5B58\u5728\u7684\u5B57\u6BB5\u4E5F\u8FD4\u56DE\u6210\u529F\uFF09\uFF0C\u6240\u4EE5"\u8FD4\u56DE true"\u2260"\u660E\u7EC6\u5DF2\u843D\u5E93"\u3002',
760
+ "\u26D4 \u5199 detail1 \u4F1A**\u91CD\u7F6E\u8BAE\u9898\u7684 mt_id**\uFF08ESB \u8054\u52A8\u526F\u4F5C\u7528\uFF09\uFF1A\u6B63\u786E\u987A\u5E8F\u662F\u300C\u5148\u5199 detail1 \u2192 \u518D\u7528 `meeting.eb.topic.update` \u8865\u56DE mt_id\u300D\u3002"
761
+ ]
762
+ },
763
+ {
764
+ domain: "meeting",
765
+ operation: "meeting.eb.meeting.delete",
766
+ kind: "delete",
767
+ interfacePk: "delete_mtDetail",
768
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\uFF08delete_mtDetail\uFF09\uFF1A\u4EC5\u4F20 id"
769
+ },
770
+ {
771
+ domain: "room",
772
+ operation: "meeting.eb.room.list",
773
+ kind: "list",
774
+ interfacePk: "query_meeting_room_list",
775
+ countPk: "query_meeting_room_count",
776
+ queryParams: ["manager", "departmentId", "mr_type", "room_attr"],
777
+ summarizeRows: summarizeRoomRows,
778
+ summary: "EB \u7248\u4F1A\u8BAE\u5BA4\u5217\u8868\uFF08query_meeting_room_list + count\uFF09\uFF1A\u81EA\u5E26 statusText \u4E0E\u72B6\u6001\u5B57\u5178",
779
+ notes: [
780
+ '**status\uFF1A`0` = \u6B63\u5E38\uFF08\u53EF\u7528\uFF09\u3001`1` = \u5C01\u5B58\uFF08\u4E0D\u53EF\u7528\uFF09** \u2014\u2014 \u4E0D\u662F"\u542F\u7528/\u505C\u7528"\uFF0C`0` \u624D\u662F\u6B63\u5E38\u3002',
781
+ "\u660E\u7EC6\u5728 `data.progress.items[]`\uFF1A`statusText` \u5DF2\u628A\u7F16\u7801\u7FFB\u6210\u4E2D\u6587\uFF0C`summary.unusable` \u76F4\u63A5\u5217\u51FA\u4E0D\u53EF\u7528\u7684\u623F\u95F4\u540D\uFF1B\u9700\u8981\u539F\u59CB\u7F16\u7801\u65F6\u770B `status`\u3002",
782
+ "room_attr\uFF1A0\u5B9E\u4F53/1\u865A\u62DF/2\u7EC4\u5408\uFF08`progress.legend.roomAttr` \u540C\u6E90\uFF09\u3002"
783
+ ]
784
+ },
785
+ {
786
+ domain: "room",
787
+ operation: "meeting.eb.room.detail",
788
+ kind: "detail",
789
+ interfacePk: "query_room_info",
790
+ summary: "EB \u7248\u4F1A\u8BAE\u5BA4\u8BE6\u60C5\uFF08query_room_info\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09"
791
+ },
792
+ {
793
+ domain: "room",
794
+ operation: "meeting.eb.room.create",
795
+ kind: "create",
796
+ interfacePk: "create_room",
797
+ fields: ROOM_FIELDS,
798
+ requiredFields: ["room_name", "hrm_ids", "org_id"],
799
+ // 漏传 status 会落成「封存」(接口配置默认值),等于建了一间用不了的会议室。
800
+ fieldDefaults: { status: "0", room_attr: "0" },
801
+ summary: "EB \u7248\u65B0\u5EFA\u4F1A\u8BAE\u5BA4\uFF08create_room\uFF09\uFF1A\u5FC5\u586B room_name / hrm_ids / org_id\uFF1Bstatus \u9ED8\u8BA4\u300C\u6B63\u5E38\u300D",
802
+ notes: [
803
+ '**status \u662F Select\uFF1A`0` = \u6B63\u5E38\u3001`1` = \u5C01\u5B58**\uFF08\u4E0D\u662F"\u542F\u7528/\u505C\u7528"\uFF09\u3002CLI \u5728\u672A\u4F20\u65F6\u81EA\u52A8\u8865 `0`\uFF0C\u907F\u514D\u5EFA\u51FA"\u5C01\u5B58"\u7684\u4F1A\u8BAE\u5BA4\uFF082026-10-27 \u771F\u673A\u8E29\u5230\u8FC7\uFF09\u3002',
804
+ "`room_attr` \u540C\u7406\u9ED8\u8BA4 `0`\uFF08\u5B9E\u4F53\uFF09\uFF1A0\u5B9E\u4F53 / 1\u865A\u62DF / 2\u7EC4\u5408\uFF1B\u6F0F\u4F20\u4F1A\u8BA9\u5217\u8868\u91CC\u5C5E\u6027\u4E3A\u7A7A\u3002",
805
+ "equipments\uFF1A0\u7535\u89C6/1\u7535\u8BDD/2\u6295\u5F71\u4EEA/3\u767D\u677F/4\u89C6\u9891\u4F1A\u8BAE\uFF0C\u9017\u53F7\u5206\u9694\u3002",
806
+ '\u26D4 \u4E0D\u8981\u628A `status=0` \u8BFB\u6210"\u505C\u7528/\u7981\u7528"\uFF1A`0` \u624D\u662F\u6B63\u5E38\u53EF\u7528\uFF0C`1` \u624D\u662F\u5C01\u5B58\u4E0D\u53EF\u7528\u3002'
807
+ ]
808
+ },
809
+ {
810
+ domain: "room",
811
+ operation: "meeting.eb.room.update",
812
+ kind: "update",
813
+ interfacePk: "update_room",
814
+ fields: ROOM_FIELDS,
815
+ requiredFields: ["id"],
816
+ // 主键必须走 URL(updateFormData 端点统一要求)
817
+ pkQueryParam: "id",
818
+ summary: "EB \u7248\u66F4\u65B0\u4F1A\u8BAE\u5BA4\uFF08update_room\uFF09\uFF1A\u4EC5 id \u5FC5\u586B"
819
+ },
820
+ {
821
+ domain: "room",
822
+ operation: "meeting.eb.room.delete",
823
+ kind: "delete",
824
+ interfacePk: "delete_room",
825
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\u5BA4\uFF08delete_room\uFF09\uFF1A\u4EC5\u4F20 id"
826
+ },
827
+ {
828
+ domain: "roomUsage",
829
+ operation: "meeting.eb.roomUsage.list",
830
+ kind: "list",
831
+ interfacePk: "query_roomusage_list",
832
+ countPk: "query_roomusage_count",
833
+ queryParams: ["mt_id", "address", "enddatetime", "begindatetime"],
834
+ summary: "EB \u7248\u4F1A\u8BAE\u5BA4\u5360\u7528\u5217\u8868\uFF08query_roomusage_list + count\uFF09"
835
+ },
836
+ {
837
+ domain: "roomUsage",
838
+ operation: "meeting.eb.roomUsage.detail",
839
+ kind: "detail",
840
+ interfacePk: "query_roomusage",
841
+ summary: "EB \u7248\u4F1A\u8BAE\u5BA4\u5360\u7528\u8BE6\u60C5\uFF08query_roomusage\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09"
842
+ },
843
+ {
844
+ domain: "roomUsage",
845
+ operation: "meeting.eb.roomUsage.create",
846
+ kind: "create",
847
+ interfacePk: "create_roomusage",
848
+ fields: ["mt_id", "room_id", "startdate", "enddate", "from_module", "agenda_id"],
849
+ requiredFields: ["mt_id"],
850
+ dateFields: ["startdate", "enddate"],
851
+ summary: "EB \u7248\u65B0\u5EFA\u4F1A\u8BAE\u5BA4\u5360\u7528\uFF08create_roomusage\uFF09\uFF1A\u5FC5\u586B mt_id"
852
+ },
853
+ {
854
+ domain: "roomUsage",
855
+ operation: "meeting.eb.roomUsage.delete",
856
+ kind: "delete",
857
+ interfacePk: "delete_roomusage",
858
+ // ⚠️ 按会议批量删,不是按 id
859
+ batchDeleteFields: ["mt_id"],
860
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\u5BA4\u5360\u7528\uFF08delete_roomusage\uFF09\uFF1A\u6309 mt_id **\u6279\u91CF\u5220\u9664\u8BE5\u4F1A\u8BAE\u7684\u5168\u90E8\u5360\u7528**\uFF08\u4E0D\u662F\u6309 id\uFF09",
861
+ notes: [
862
+ "2026-10-27 \u771F\u673A\uFF1A\u4F20 `id` \u62A5\u300C\u6279\u91CF\u64CD\u4F5C\u6570\u636E\u6761\u4EF6\u4E0D\u80FD\u4E3A\u7A7A\u300D\uFF1B\u4F20 `mt_id` \u6210\u529F\uFF0C\u5E76\u5220\u6389\u8BE5\u4F1A\u8BAE\u4E0B\u7684**\u6240\u6709**\u5360\u7528\uFF08\u4E00\u6B21\u5220\u4E86 2 \u6761\uFF09\u3002\u53D6\u6D88\u4F1A\u8BAE\u91CA\u653E\u5360\u7528\u5C31\u662F\u8D70\u8FD9\u4E2A\u8BED\u4E49\u3002",
863
+ "\u53EA\u60F3\u53BB\u6389\u67D0\u4E00\u6761\u5360\u7528\uFF0C\u76EE\u524D\u6CA1\u6709\u6309 id \u7684\u63A5\u53E3 \u2014\u2014 \u8981\u4E48\u6574\u4F1A\u91CD\u6392\uFF0C\u8981\u4E48\u9875\u9762\u64CD\u4F5C\u3002"
864
+ ]
865
+ },
866
+ {
867
+ domain: "sign",
868
+ operation: "meeting.eb.sign.list",
869
+ kind: "list",
870
+ interfacePk: "query_meeting_sign_list",
871
+ countPk: "query_meeting_sign_count",
872
+ queryParams: ["mt_id", "signMember", "sign_status", "sign_back_status"],
873
+ summary: "EB \u7248\u7B7E\u5230\u5217\u8868\uFF08query_meeting_sign_list + count\uFF09",
874
+ // 附带出席汇总(data.progress):各状态人数 / 已签退 / 出席率;原始 rows 原样保留。
875
+ summarizeRows: summarizeSignRows,
876
+ notes: [
877
+ "sign_status\uFF1A0\u7F3A\u5E2D/1\u6B63\u5E38/2\u8BF7\u5047/3\u8FDF\u5230/4\u65E9\u9000/5\u672A\u7B7E\u9000/6\u8FDF\u5230\u672A\u7B7E\u9000/7\u8FDF\u5230\u65E9\u9000\uFF1Bsign_back_status\uFF1A0\u5DF2\u7B7E\u9000/1\u672A\u7B7E\u9000/2\u65E9\u9000\u3002",
878
+ "\u672A\u7B7E\u5230\u5224\u65AD\uFF1Asign_time \u4E3A\u7A7A\u6216\u67E5\u4E0D\u5230\u8BB0\u5F55\u3002",
879
+ "\u5DF2\u77E5\u5076\u53D1\uFF1Afields \u540C\u65F6\u542B sign_flag \u4E0E attend_type \u53EF\u80FD\u89E6\u53D1\u540E\u7AEF 500\u3002"
880
+ ]
881
+ },
882
+ {
883
+ domain: "sign",
884
+ operation: "meeting.eb.sign.detail",
885
+ kind: "detail",
886
+ interfacePk: "query_meeting_sign_info",
887
+ summary: "EB \u7248\u7B7E\u5230\u8BE6\u60C5\uFF08query_meeting_sign_info\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09"
888
+ },
889
+ {
890
+ domain: "sign",
891
+ operation: "meeting.eb.sign.create",
892
+ kind: "create",
893
+ interfacePk: "create_meeting_sign",
894
+ fields: SIGN_FIELDS_CREATE,
895
+ requiredFields: ["mt_id"],
896
+ // 签到表时间字段**必须带秒**(真机实测:传 yyyy-MM-dd HH:mm 被拒,要求 yyyy-MM-dd HH:mm:ss)
897
+ secondDateFields: ["sign_time", "signback_time", "allow_late_time"],
898
+ summary: "EB \u7248\u65B0\u5EFA\u7B7E\u5230\u8BB0\u5F55\uFF08create_meeting_sign\uFF09\uFF1A\u5FC5\u586B mt_id",
899
+ notes: [
900
+ "\u4EC5\u7528\u4E8E\u300C\u5EFA\u4F1A\u540E\u521D\u59CB\u5316\u7B7E\u5230\u8BB0\u5F55\u300D\u7B49**\u8BE5\u4F1A\u8BAE\u5C1A\u65E0\u7B7E\u5230\u8BB0\u5F55**\u7684\u573A\u666F\u3002",
901
+ "\u26A0\uFE0F **\u8865\u7B7E\u4E0D\u662F\u672C\u63A5\u53E3**\uFF1A\u5DF2\u6709\u8BB0\u5F55\u518D create \u4F1A\u4EA7\u751F\u91CD\u590D\u7B7E\u5230\u6570\u636E\uFF0C\u8865\u7B7E\u8BF7\u7528 meeting.eb.sign.mark\u3002"
902
+ ]
903
+ },
904
+ {
905
+ domain: "sign",
906
+ operation: "meeting.eb.sign.update",
907
+ kind: "update",
908
+ interfacePk: "update_meeting_sign_info",
909
+ fields: SIGN_FIELDS_UPDATE,
910
+ requiredFields: ["id", "mt_id"],
911
+ // 同 create:签到时间字段必须带秒(yyyy-MM-dd HH:mm:ss)
912
+ secondDateFields: ["sign_time", "signback_time", "allow_late_time"],
913
+ // 主键必须走 URL(真机实测:只在 body 里传 id 会报「主键传入不能为空」)
914
+ pkQueryParam: "id",
915
+ summary: "EB \u7248\u66F4\u65B0\u7B7E\u5230\u8BB0\u5F55\uFF08update_meeting_sign_info\uFF09\uFF1A\u5FC5\u4F20 id + mt_id",
916
+ notes: [
917
+ "**\u8865\u7B7E / \u8865\u7B7E\u9000\u7684\u6B63\u786E\u5165\u53E3**\uFF08`meeting.eb.sign.mark` \u5373\u5C01\u88C5\u672C\u63A5\u53E3\uFF09\u3002",
918
+ "\u5FC5\u4F20 id = **\u7B7E\u5230\u8BB0\u5F55 id**\uFF08\u4ECE meeting.eb.sign.list \u7684 rows[].mainTable.id \u53D6\uFF09\uFF0C\u4E0D\u662F\u4F1A\u8BAE id\uFF1Bmt_id \u4E5F\u8981\u5E26\u3002",
919
+ "is_sign\uFF1A0\u7F3A\u5E2D/1\u6B63\u5E38/2\u8BF7\u5047/3\u8FDF\u5230/4\u65E9\u9000/5\u672A\u7B7E\u9000/6\u8FDF\u5230\u672A\u7B7E\u9000/7\u8FDF\u5230\u65E9\u9000\uFF1Bsign_out_status \u5BF9\u5E94\u7B7E\u9000\u72B6\u6001\u3002"
920
+ ]
921
+ },
922
+ {
923
+ domain: "receipt",
924
+ operation: "meeting.eb.receipt.list",
925
+ kind: "list",
926
+ interfacePk: "query_meeting_receipt_list",
927
+ countPk: "query_meeting_receipt_count",
928
+ queryParams: ["mt_id", "hrmmember", "is_attend"],
929
+ summary: "EB \u7248\u56DE\u6267\u5217\u8868\uFF08query_meeting_receipt_list + count\uFF09",
930
+ // 附带出席汇总(data.progress):参加 / 不参加 / 未回执、回执率、人员类型分布;原始 rows 原样保留。
931
+ summarizeRows: summarizeReceiptRows,
932
+ notes: ["is_attend\uFF1A0\u5426/1\u662F\uFF08URL query \u7B5B\u9009\uFF09\uFF1B`attend_status` \u7A7A = \u672A\u56DE\u6267\uFF0C`0` = \u4E0D\u53C2\u52A0\u3001`1` = \u53C2\u52A0\u3002"]
933
+ },
934
+ {
935
+ domain: "receipt",
936
+ operation: "meeting.eb.receipt.detail",
937
+ kind: "detail",
938
+ interfacePk: "query_meeting_receipt",
939
+ summary: "EB \u7248\u56DE\u6267\u8BE6\u60C5\uFF08query_meeting_receipt\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09"
940
+ },
941
+ {
942
+ domain: "receipt",
943
+ operation: "meeting.eb.receipt.create",
944
+ kind: "create",
945
+ interfacePk: "create_meeting_receipt",
946
+ fields: [
947
+ "mt_id",
948
+ "member_type",
949
+ "member_id",
950
+ "member_manager",
951
+ "attend_status",
952
+ "book_room",
953
+ "room_stander",
954
+ "book_ticket",
955
+ "ticket_stander",
956
+ "other_member",
957
+ "remark",
958
+ "ticket_type",
959
+ "request_id",
960
+ "invite_person",
961
+ "arrive_date_time",
962
+ "return_date_time",
963
+ "crm_member_id",
964
+ "crm_member",
965
+ "msg_id"
966
+ ],
967
+ requiredFields: ["mt_id", "member_type", "member_id", "member_manager"],
968
+ dateFields: ["arrive_date_time", "return_date_time"],
969
+ summary: "EB \u7248\u65B0\u5EFA\u56DE\u6267\uFF08create_meeting_receipt\uFF09\uFF1Amember_manager \u53D6\u503C\u7B49\u4E8E member_id",
970
+ notes: ["member_type\uFF1A1\u53C2\u4F1A\u4EBA\u5458/2\u53C2\u4F1A\u5BA2\u6237/3\u5176\u4ED6\u4EBA\u5458\u3002"]
971
+ },
972
+ {
973
+ domain: "receipt",
974
+ operation: "meeting.eb.receipt.update",
975
+ kind: "update",
976
+ interfacePk: "update_meeting_receipt",
977
+ fields: [
978
+ "id",
979
+ "mt_id",
980
+ "member_type",
981
+ "member_id",
982
+ "member_manager",
983
+ "attend_status",
984
+ "book_room",
985
+ "room_stander",
986
+ "book_ticket",
987
+ "ticket_stander",
988
+ "other_member",
989
+ "remark",
990
+ "ticket_type",
991
+ "request_id",
992
+ "invite_person",
993
+ "arrive_date_time",
994
+ "return_date_time",
995
+ "crm_member_id",
996
+ "crm_member",
997
+ "msg_id"
998
+ ],
999
+ requiredFields: ["id", "mt_id", "member_id", "attend_status"],
1000
+ dateFields: ["arrive_date_time", "return_date_time"],
1001
+ // 主键必须走 URL(updateFormData 端点统一要求)
1002
+ pkQueryParam: "id",
1003
+ summary: "EB \u7248\u66F4\u65B0\u56DE\u6267\uFF08update_meeting_receipt\uFF09\uFF1Aattend_status 0\u5426/1\u662F"
1004
+ },
1005
+ {
1006
+ domain: "minute",
1007
+ operation: "meeting.eb.minute.list",
1008
+ kind: "list",
1009
+ interfacePk: "query_meeting_minute_list",
1010
+ countPk: "query_meeting_minute_count",
1011
+ queryParams: ["mt_id"],
1012
+ summary: "EB \u7248\u4F1A\u8BAE\u7EAA\u8981\u5217\u8868\uFF08query_meeting_minute_list + count\uFF0C\u6309 mt_id \u67E5\uFF09",
1013
+ notes: [
1014
+ "\u7EAA\u8981\u4ECE 2026-10-23 \u8D77\u5DF2\u6709\u81EA\u5B9A\u4E49\u5199\u63A5\u53E3\uFF1Acreate_mt_minute / update_mt_minute / delete_mt_minute\uFF08\u4E0D\u518D\u662F\u53EA\u80FD\u8D70 OpenAPI\uFF09\u3002",
1015
+ "\u5217\u8868\u63A5\u53E3\uFF08\u53D7\u63A7\uFF09\u73B0\u8FD4\u56DE `minutes_content`\uFF08\u7EAA\u8981\u6587\u6848\uFF09\u4E0E `parse_content`\uFF08\u5185\u5BB9\u89E3\u6790\uFF09\u7B49\u5168\u90E8\u5B57\u6BB5\u2014\u20142026-10-23 \u7528\u6237\u66F4\u65B0\u63A5\u53E3\u540E\u5B9E\u6D4B\u53EF\u8BFB\u3002",
1016
+ "\u26A0\uFE0F \u8BE5\u63A5\u53E3\u662F**\u53D7\u63A7\u63A5\u53E3**\uFF1A\u53EA\u8FD4\u56DE\u5F53\u524D\u8D26\u53F7\u6709\u6743\u770B\u5230\u7684\u7EAA\u8981\u3002",
1017
+ "\u4E3B\u8868\u5B57\u6BB5\uFF1Amt_minutes_subject\uFF08\u6807\u9898\uFF09/ minutes_content / parse_content / mt_minutes_no\uFF08\u7F16\u53F7\uFF0C\u81EA\u52A8\u751F\u6210\uFF09/ file_type / doc_file / video_file / minutes_status / video_taskId / video_taskResult / mt_minutes_ai_page\u3002"
1018
+ ]
1019
+ },
1020
+ {
1021
+ domain: "minute",
1022
+ operation: "meeting.eb.minute.detail",
1023
+ kind: "detail",
1024
+ interfacePk: "query_mt_minute_info",
1025
+ summary: "EB \u7248\u4F1A\u8BAE\u7EAA\u8981\u8BE6\u60C5\uFF08query_mt_minute_info\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09",
1026
+ notes: [
1027
+ "id = \u7EAA\u8981 id\uFF08minute.list \u7684 rows[].mainTable.id \u6216 create \u8FD4\u56DE\u7684 dataIds[0]\uFF09\u3002",
1028
+ "\u9700\u8981\u5355\u6761\u7EAA\u8981\u7684\u5B8C\u6574\u5185\u5BB9\uFF08\u542B minutes_content / parse_content \u5168\u6587\uFF09\u65F6\u7528\u5B83\uFF0C\u6BD4 list \u66F4\u76F4\u63A5\u3002"
1029
+ ]
1030
+ },
1031
+ // ---------------------------------------------------------------------------
1032
+ // 会议纪要写操作(2026-10-23 用户新增自定义接口,来源:RestfulDocumentation (7))
1033
+ // ---------------------------------------------------------------------------
1034
+ {
1035
+ domain: "minute",
1036
+ operation: "meeting.eb.minute.create",
1037
+ kind: "create",
1038
+ interfacePk: "create_mt_minute",
1039
+ fields: [
1040
+ "id",
1041
+ "mt_id",
1042
+ "minutes_content",
1043
+ "mt_minutes_ai_page",
1044
+ "parse_content",
1045
+ "mt_minutes_no",
1046
+ "mt_minutes_subject",
1047
+ "video_mt_id",
1048
+ "begin_datetime",
1049
+ "end_datetime",
1050
+ "hrm_members",
1051
+ "org_members",
1052
+ "mt_minutes",
1053
+ "file_type",
1054
+ "doc_file",
1055
+ "video_file",
1056
+ "minutes_status",
1057
+ "video_taskId",
1058
+ "video_taskResult"
1059
+ ],
1060
+ requiredFields: ["mt_id", "mt_minutes_subject"],
1061
+ dateFields: ["begin_datetime", "end_datetime"],
1062
+ summary: "EB \u7248\u65B0\u5EFA\u4F1A\u8BAE\u7EAA\u8981\uFF08create_mt_minute\uFF09\uFF1A\u5FC5\u586B mt_id + mt_minutes_subject",
1063
+ notes: [
1064
+ "\u2605 \u8FD4\u56DE `datajson.dataIds[0]` \u5373\u65B0\u7EAA\u8981 id\uFF08\u540E\u7EED update/delete \u7528\u5B83\uFF09\u3002",
1065
+ "mt_id \u5173\u8054\u4F1A\u8BAE\uFF08\u957F id \u7528\u5B57\u7B26\u4E32\uFF09\uFF1Bmt_minutes_subject \u662F\u7EAA\u8981\u6807\u9898\uFF0C\u670D\u52A1\u7AEF\u5FC5\u586B\u3002",
1066
+ "\u26A0\uFE0F `mt_minutes_no`\uFF08\u7EAA\u8981\u7F16\u53F7\uFF09\u901A\u5E38\u7531\u670D\u52A1\u7AEF\u751F\u6210\uFF0C\u4E00\u822C\u4E0D\u8981\u4F20\u3002",
1067
+ "file_type\uFF1A0 \u6587\u6863 / 1 \u97F3\u9891\u6587\u4EF6\uFF1B\u6587\u6863\u4F20 `doc_file`\u3001\u97F3\u9891\u4F20 `video_file`\uFF0C\u503C\u90FD\u662F**\u6587\u4EF6 id**\u3002",
1068
+ "minutes_status\uFF1A0 \u89E3\u6790\u4E2D / 1 \u751F\u6210\u4E2D / 2 \u5DF2\u5B8C\u6210 / 3 \u6587\u5B57\u63D0\u53D6\u4E2D / 4 \u6587\u5B57\u63D0\u53D6\u5B8C\u6210\u3002\u4EC5\u767B\u8BB0\u5DF2\u6709\u5185\u5BB9\u65F6\u5EFA\u8BAE\u76F4\u63A5\u4F20 2\uFF0C\u907F\u514D\u670D\u52A1\u7AEF\u518D\u53BB\u89E3\u6790\u3002",
1069
+ "video_taskResult\uFF1A0 \u751F\u6210\u4E2D / 1 \u751F\u6210\u6210\u529F / 2 \u751F\u6210\u5931\u8D25\uFF08\u97F3\u9891\u89E3\u6790\u7528\uFF0C\u4E00\u822C\u4E0D\u7528\u624B\u5DE5\u5199\uFF09\u3002",
1070
+ "`hrm_members`\uFF08\u4EBA\u5458\uFF09\u4E0E `org_members`\uFF08\u90E8\u95E8\uFF09\u6309 eBuilder \u9009\u9879\u503C\u4F20\uFF1B`parse_content` \u662F\u5BCC\u6587\u672C\u5185\u5BB9\u3002"
1071
+ ]
1072
+ },
1073
+ {
1074
+ domain: "minute",
1075
+ operation: "meeting.eb.minute.update",
1076
+ kind: "update",
1077
+ interfacePk: "update_mt_minute",
1078
+ // 2026-10-23 二次核(RestfulDocumentation (8)):接口已把全部字段选中,
1079
+ // 与 create 对齐 19 个字段;必填 = id(主键)+ mt_id。
1080
+ fields: [
1081
+ "id",
1082
+ "mt_id",
1083
+ "minutes_content",
1084
+ "mt_minutes_ai_page",
1085
+ "parse_content",
1086
+ "mt_minutes_no",
1087
+ "mt_minutes_subject",
1088
+ "video_mt_id",
1089
+ "begin_datetime",
1090
+ "end_datetime",
1091
+ "hrm_members",
1092
+ "org_members",
1093
+ "mt_minutes",
1094
+ "file_type",
1095
+ "doc_file",
1096
+ "video_file",
1097
+ "minutes_status",
1098
+ "video_taskId",
1099
+ "video_taskResult"
1100
+ ],
1101
+ requiredFields: ["id", "mt_id"],
1102
+ dateFields: ["begin_datetime", "end_datetime"],
1103
+ pkQueryParam: "id",
1104
+ summary: "EB \u7248\u66F4\u65B0\u4F1A\u8BAE\u7EAA\u8981\uFF08update_mt_minute\uFF09\uFF1A\u5FC5\u4F20 id + mt_id\uFF0C\u53EF\u6539\u5185\u5BB9/\u72B6\u6001/\u9644\u4EF6",
1105
+ notes: [
1106
+ "id = \u7EAA\u8981 id\uFF08minute.list \u7684 rows[].mainTable.id \u6216 create \u8FD4\u56DE\u7684 dataIds[0]\uFF09\uFF1B`mt_id` \u670D\u52A1\u7AEF\u4E5F\u662F\u5FC5\u586B\u3002",
1107
+ "\u53EF\u66F4\u65B0\u5B57\u6BB5\u4E0E create \u4E00\u81F4\uFF1Aminutes_content / parse_content / mt_minutes_subject / minutes_status / file_type / doc_file / video_file \u7B49\u3002",
1108
+ "minutes_status\uFF1A0 \u89E3\u6790\u4E2D / 1 \u751F\u6210\u4E2D / 2 \u5DF2\u5B8C\u6210 / 3 \u6587\u5B57\u63D0\u53D6\u4E2D / 4 \u6587\u5B57\u63D0\u53D6\u5B8C\u6210\u3002",
1109
+ "\u26A0\uFE0F \u4E3B\u952E\u8D70 URL\uFF08`?id=`\uFF09\uFF0C\u53EA\u653E body \u4F1A\u62A5\u300C\u4E3B\u952E\u4F20\u5165\u4E0D\u80FD\u4E3A\u7A7A\u300D\u2014\u2014CLI \u5DF2\u81EA\u52A8\u5904\u7406\u3002",
1110
+ "\u26A0\uFE0F EB \u5199\u63A5\u53E3\u62A5\u9519\u4E0D\u4EE3\u8868\u6CA1\u5199\u5165\uFF0C\u6539\u5B8C\u5EFA\u8BAE\u56DE\u67E5 minute.list \u786E\u8BA4\u3002"
1111
+ ]
1112
+ },
1113
+ {
1114
+ domain: "minute",
1115
+ operation: "meeting.eb.minute.delete",
1116
+ kind: "delete",
1117
+ interfacePk: "delete_mt_minute",
1118
+ fields: ["id"],
1119
+ requiredFields: ["id"],
1120
+ pkQueryParam: "id",
1121
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\u7EAA\u8981\uFF08delete_mt_minute\uFF09\uFF1A\u4EC5\u4F20 id\uFF08\u7EAA\u8981 id\uFF09",
1122
+ notes: [
1123
+ "id = \u7EAA\u8981 id\uFF08minute.list \u7684 rows[].mainTable.id\uFF0C\u6216 create \u8FD4\u56DE\u7684 dataIds[0]\uFF09\uFF0C\u4E0D\u662F\u4F1A\u8BAE id\u3002",
1124
+ "\u8FD4\u56DE\u4F53\u542B `datajson.status`\uFF08true/false\uFF09\u4E0E `message`\uFF0CCLI \u7EDF\u4E00\u5224\u5B9A\u3002"
1125
+ ]
1126
+ },
1127
+ {
1128
+ domain: "type",
1129
+ operation: "meeting.eb.type.list",
1130
+ kind: "list",
1131
+ interfacePk: "query_mt_type_list",
1132
+ countPk: "query_mt_type_count",
1133
+ queryParams: ["mt_type_name"],
1134
+ summary: "EB \u7248\u4F1A\u8BAE\u7C7B\u578B\u5217\u8868\uFF08query_mt_type_list + count\uFF09"
1135
+ },
1136
+ {
1137
+ domain: "type",
1138
+ operation: "meeting.eb.type.create",
1139
+ kind: "create",
1140
+ interfacePk: "create_mt_type",
1141
+ fields: ["type_name", "dsporder", "org_id", "room_range"],
1142
+ requiredFields: ["type_name"],
1143
+ summary: "EB \u7248\u65B0\u5EFA\u4F1A\u8BAE\u7C7B\u578B\uFF08create_mt_type\uFF09\uFF1A\u5FC5\u586B type_name",
1144
+ notes: ["caller_range/member_range \u4E0D\u652F\u6301\u65B0\u5EFA/\u66F4\u65B0\u3002"]
1145
+ },
1146
+ {
1147
+ domain: "type",
1148
+ operation: "meeting.eb.type.delete",
1149
+ kind: "delete",
1150
+ interfacePk: "delete_mt_type",
1151
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\u7C7B\u578B\uFF08delete_mt_type\uFF09\uFF1A\u4EC5\u4F20 id"
1152
+ },
1153
+ {
1154
+ domain: "topicType",
1155
+ operation: "meeting.eb.topicType.list",
1156
+ kind: "list",
1157
+ interfacePk: "query_mt_topicType_list",
1158
+ countPk: "query_mt_topicType_count",
1159
+ queryParams: [],
1160
+ summary: "EB \u7248\u8BAE\u9898\u7C7B\u578B\u5217\u8868\uFF08query_mt_topicType_list + count\uFF09"
1161
+ },
1162
+ {
1163
+ domain: "topicType",
1164
+ operation: "meeting.eb.topicType.detail",
1165
+ kind: "detail",
1166
+ interfacePk: "query_mt_topicType_info",
1167
+ summary: "EB \u7248\u8BAE\u9898\u7C7B\u578B\u8BE6\u60C5\uFF08query_mt_topicType_info\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09"
1168
+ },
1169
+ {
1170
+ domain: "topicType",
1171
+ operation: "meeting.eb.topicType.update",
1172
+ kind: "update",
1173
+ interfacePk: "update_mt_topicType_info",
1174
+ fields: ["id", "name", "topic_type_num", "topic_type_name", "data_status"],
1175
+ requiredFields: ["id"],
1176
+ // 主键必须走 URL(updateFormData 端点统一要求)
1177
+ pkQueryParam: "id",
1178
+ summary: "EB \u7248\u66F4\u65B0\u8BAE\u9898\u7C7B\u578B\uFF08update_mt_topicType_info\uFF09\uFF1A\u5FC5\u4F20 id"
1179
+ },
1180
+ {
1181
+ domain: "topicType",
1182
+ operation: "meeting.eb.topicType.delete",
1183
+ kind: "delete",
1184
+ interfacePk: "delete_mt_topicType_info",
1185
+ summary: "EB \u7248\u5220\u9664\u8BAE\u9898\u7C7B\u578B\uFF08delete_mt_topicType_info\uFF09\uFF1A\u4EC5\u4F20 id"
1186
+ },
1187
+ {
1188
+ domain: "topic",
1189
+ operation: "meeting.eb.topic.list",
1190
+ kind: "list",
1191
+ interfacePk: "query_mt_topic_list",
1192
+ // 2026-10-27 17:50:旧 query_mt_topic_count 已废弃,计数改走 *_new
1193
+ countPk: "query_mt_topic_count_new",
1194
+ // 2026-10-23 真机验证:该接口支持 URL query 传 `mt_id` 过滤
1195
+ // (不带参数返回 1 条、带无关参数仍返回 1 条、带 mt_id 返回 0 条 ⇒ 过滤真实生效)。
1196
+ queryParams: ["mt_id"],
1197
+ summary: "EB \u7248\u4F1A\u8BAE\u8BAE\u9898\u5217\u8868\uFF08query_mt_topic_list + count\uFF0C\u53EF\u6309 mt_id \u8FC7\u6EE4\uFF09",
1198
+ notes: [
1199
+ '\u8BAE\u9898\u8868 uf_mt_topic \u5728\u90E8\u5206\u79DF\u6237\u672A\u6CE8\u518C\uFF08\u6216\u4F1A\u8BAE\u672C\u8EAB\u6CA1\u6392\u8BAE\u9898\uFF09\uFF0C\u8FD4\u56DE\u7A7A\u6570\u7EC4\u5C5E\u6B63\u5E38\uFF0C\u8C03\u7528\u65B9\u9700\u6309"\u65E0\u8BAE\u9898"\u5904\u7406\u3002',
1200
+ "\u6309\u4F1A\u8BAE\u53D6\u8BAE\u9898\u8BF7\u4F20 `mt_id`\uFF1B\u4E0D\u4F20\u4F1A\u8FD4\u56DE\u5168\u5E93\u8BAE\u9898\u3002"
1201
+ ]
1202
+ },
1203
+ {
1204
+ domain: "topic",
1205
+ operation: "meeting.eb.topic.detail",
1206
+ kind: "detail",
1207
+ interfacePk: "query_mt_topic_info_new",
1208
+ summary: "EB \u7248\u4F1A\u8BAE\u8BAE\u9898\u8BE6\u60C5\uFF08query_mt_topic_info_new\uFF0Cbody \u9876\u5C42 mainTable \u4F20 id\uFF09",
1209
+ notes: [
1210
+ "\u65E7\u7684 `query_mt_topic_info` \u5DF2\u4E8E 2026-10-27 \u5E9F\u5F03\uFF08\u6309 id \u6052\u8FD4\u56DE\u7A7A `datas:[]`\uFF09\uFF0C\u8FD9\u91CC\u8D70 `_new`\u3002",
1211
+ "2026-10-27 17:50 \u771F\u673A\u9A8C\u8BC1\uFF1A\u6309 id \u8FD4\u56DE\u5B8C\u6574\u65B0\u7248\u5B57\u6BB5\uFF08\u542B `topic_title` / `remark` / `topic_num` \u7B49\uFF09\u3002"
1212
+ ]
1213
+ },
1214
+ {
1215
+ domain: "topic",
1216
+ operation: "meeting.eb.topic.create",
1217
+ kind: "create",
1218
+ interfacePk: "create_mt_topic",
1219
+ fields: TOPIC_FIELDS_CREATE,
1220
+ requiredFields: ["topic_title"],
1221
+ dateOnlyFields: ["proposal_date"],
1222
+ summary: "EB \u7248\u521B\u5EFA\u8BAE\u9898\uFF08create_mt_topic\uFF09\uFF1A\u5FC5\u586B topic_title\uFF1B\u8981\u6302\u5230\u4F1A\u8BAE\u8BF7\u4F20 mt_id",
1223
+ notes: [
1224
+ "\u4EBA\u5458\u5B57\u6BB5\u4F20 **HRM \u5458\u5DE5 id**\uFF08`topic_presenter` / `proposal_person`\uFF09\uFF0C\u5355\u4F4D\u4F20**\u90E8\u95E8 id**\uFF08`proposal_dept`\uFF09\u3002",
1225
+ "\u2B50 `proposal_person` / `proposal_dept` \u6F0F\u4F20\u65F6**\u81EA\u52A8\u8865\u9ED8\u8BA4\u503C**\uFF082026-10-28 \u7528\u6237\u53E3\u5F84\uFF09\uFF1A\u63D0\u8BAE\u4EBA\u5458=\u5F53\u524D\u64CD\u4F5C\u4EBA\u3001\u63D0\u8BAE\u5355\u4F4D=\u64CD\u4F5C\u4EBA\u6240\u5C5E\u90E8\u95E8 id\uFF08`hrm.employee.batch` \u7684 `departmentId`\uFF0C\u67E5\u4E0D\u5230\u7559\u7A7A\uFF09\u3002",
1226
+ "`topic_content` = \u8BAE\u9898\u5185\u5BB9\u6982\u8981\u2014\u2014\u9080\u8BF7\u51FD\u8BAE\u7A0B\u8868\u7684\u300C\u8BAE\u7A0B\u5185\u5BB9\u300D\u5217\u53D6\u5B83\uFF0C\u5EFA\u8BAE\u9898\u65F6\u5EFA\u8BAE\u586B\u4E0A\u3002",
1227
+ "`topic_type` \u4F20\u8BAE\u9898\u7C7B\u578B id\uFF08\u7528 `meeting.eb.topicType.list` \u53D6\uFF09\u3002",
1228
+ "Select \u7C7B\uFF08`urgency` / `topic_status` / `allow_repeat`\uFF09\u6309\u79DF\u6237\u8868\u5355\u914D\u7F6E\u4F20\u5BF9\u5E94\u6570\u5B57\u503C\uFF0CCLI \u4E0D\u505A\u679A\u4E3E\u6821\u9A8C \u2014\u2014 \u5404\u79DF\u6237\u914D\u7F6E\u4E0D\u540C\uFF0C\u786C\u7F16\u7801\u4F1A\u628A\u5408\u6CD5\u503C\u62E6\u6389\u3002",
1229
+ "`name` \u4E0D\u8981\u4F20\uFF1A\u670D\u52A1\u7AEF\u81EA\u52A8\u751F\u6210\uFF08\u5F62\u5982\u300C\u8BAE\u9898\u5E93-\u674E\u56DB 2026-10-23 15:29:00\u300D\uFF09\u3002",
1230
+ "`topic_num` \u4E00\u822C\u7559\u7A7A\u7531\u670D\u52A1\u7AEF\u7F16\u53F7\uFF08\u771F\u673A\u6837\u4F8B `0002`\uFF09\u3002"
1231
+ ]
1232
+ },
1233
+ {
1234
+ domain: "topic",
1235
+ operation: "meeting.eb.topic.update",
1236
+ kind: "update",
1237
+ interfacePk: "update_mt_topic_info_new",
1238
+ fields: TOPIC_FIELDS_UPDATE,
1239
+ requiredFields: ["id"],
1240
+ dateOnlyFields: ["proposal_date"],
1241
+ // 主键必须走 URL(updateFormData 端点统一要求)
1242
+ pkQueryParam: "id",
1243
+ summary: "EB \u7248\u66F4\u65B0\u4F1A\u8BAE\u8BAE\u9898\uFF08update_mt_topic_info_new\uFF09\uFF1A\u5FC5\u4F20 id\uFF1B\u5B57\u6BB5\u4E3A\u65B0\u7248\u8868\u5355\u53E3\u5F84",
1244
+ notes: [
1245
+ '\u65E7\u7684 `update_mt_topic_info` \u5DF2\u4E8E 2026-10-27 \u5E9F\u5F03\uFF08\u8BA4\u8001\u5B57\u6BB5\u3001\u6309 id \u62A5"\u6CA1\u6709\u6EE1\u8DB3\u66F4\u65B0\u6761\u4EF6\u7684\u6570\u636E"\uFF09\uFF0C\u8FD9\u91CC\u8D70 `_new`\u3002',
1246
+ "2026-10-27 17:50 \u771F\u673A\u9A8C\u8BC1\uFF1A\u4F20 `id + remark` \u2192 \u6210\u529F\uFF1B`query_mt_topic_info_new` \u56DE\u8BFB\u5230\u65B0\u503C\u3002",
1247
+ "\u5B57\u6BB5\u53EA\u7528**\u65B0\u7248\u8868\u5355**\uFF08`topic_title` / `remark` / `urgency` / `proposal_date` \u2026\uFF09\u3002\u8001\u7248\u7684 `relate_topic` / `topic_no` / `start_time` / `end_time` / `data_status` \u5DF2\u4E0D\u5728\u767D\u540D\u5355\uFF0C\u4F1A\u88AB\u5165\u53E3\u62E6\u4E0B\u3002",
1248
+ "`topic_status` \u7684\u679A\u4E3E\u503C\u4EE5\u79DF\u6237\u8868\u5355\u914D\u7F6E\u4E3A\u51C6\uFF08`1\u5448\u6279\u4E2D / 2\u5F85\u4E0A\u4F1A / 3\u5DF2\u4E0A\u4F1A`\uFF09\u3002",
1249
+ "`proposal_date` \u53EA\u63A5\u53D7\u65E5\u671F `yyyy-MM-dd`\uFF08\u771F\u673A\u5B58\u7684\u5C31\u662F `2026-10-27`\uFF09\u3002"
1250
+ ]
1251
+ },
1252
+ {
1253
+ domain: "topic",
1254
+ operation: "meeting.eb.topic.delete",
1255
+ kind: "delete",
1256
+ interfacePk: "delete_mt_topic_info_new",
1257
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\u8BAE\u9898\uFF08delete_mt_topic_info_new\uFF09\uFF1A\u4EC5\u4F20 id",
1258
+ notes: [
1259
+ "\u65E7\u7684 `delete_mt_topic_info` \u5DF2\u5E9F\u5F03\uFF0C\u8FD9\u91CC\u8D70 `_new`\uFF082026-10-27 17:50 \u771F\u673A\uFF1A\u5220\u5B8C\u8BE6\u60C5\u8FD4\u56DE\u7A7A `datas:[]`\uFF09\u3002"
1260
+ ]
1261
+ },
1262
+ {
1263
+ domain: "baseSet",
1264
+ operation: "meeting.eb.baseSet.get",
1265
+ kind: "get",
1266
+ interfacePk: "query_meeting_baseset",
1267
+ summary: "EB \u7248\u4F1A\u8BAE\u5E94\u7528\u8BBE\u7F6E\uFF08query_meeting_baseset\uFF0C\u8FD4\u56DE 1 \u6761\uFF0C\u591A\u6761\u53D6\u7B2C\u4E00\u6761\uFF09",
1268
+ notes: [
1269
+ "\u5173\u952E\u5B57\u6BB5\uFF1Aopen_mt_approve / only_flow_create / mt_new_wf / mt_approve_cancel / mt_approve_change\u3002",
1270
+ "\u636E\u6B64\u5224\u65AD EB \u7248\u5EFA\u4F1A\u662F\u5426\u9700\u8D70\u6D41\u7A0B\uFF08\u5BA1\u6279\u5F00\u542F \u2192 \u8D70 workflow\uFF0C\u4E0D\u7531 CLI \u76F4\u63A5\u5EFA\u4F1A\uFF09\u3002"
1271
+ ]
1272
+ },
1273
+ // ---------------------------------------------------------------------------
1274
+ // 会议决议(决议概述表 + 决议任务表)—— 2026-09-21 新增
1275
+ // 链路:create_mt_decision 写「概述 + 明细」→ 用户配置的 ESB 联动按明细生成决议任务
1276
+ // → update_mt_isdecision 把会议标记为已决议(is_decision=2 + decision_Id + mt_status)
1277
+ // → 后续用 decisionTask.* 查进度、更新完成状态
1278
+ // ---------------------------------------------------------------------------
1279
+ {
1280
+ domain: "decision",
1281
+ operation: "meeting.eb.decision.list",
1282
+ kind: "list",
1283
+ interfacePk: "query_mt_decision_list",
1284
+ countPk: "query_mt_decision_count",
1285
+ queryParams: ["mt_id", "name", "creator", "data_status"],
1286
+ summary: "EB \u7248\u4F1A\u8BAE\u51B3\u8BAE\u5217\u8868\uFF08query_mt_decision_list + count\uFF09",
1287
+ notes: [
1288
+ "\u4E00\u4E2A\u4F1A\u8BAE**\u53EA\u6709\u4E00\u4E2A**\u51B3\u8BAE\u6982\u8FF0\uFF08\u6309 mt_id \u67E5\u5373\u53EF\uFF09\u3002",
1289
+ "\u4E3B\u8868\u4E3A\u6982\u8FF0\uFF08mt_content \u4E3A\u51B3\u8BAE\u6982\u8FF0\u6587\u672C\uFF09\uFF0Cdetail1 \u4E3A\u51B3\u8BAE\u660E\u7EC6\u3002"
1290
+ ]
1291
+ },
1292
+ {
1293
+ domain: "decision",
1294
+ operation: "meeting.eb.decision.detail",
1295
+ kind: "detail",
1296
+ interfacePk: "query_mt_decision_info",
1297
+ summary: "EB \u7248\u4F1A\u8BAE\u51B3\u8BAE\u8BE6\u60C5\uFF08query_mt_decision_info\uFF09\uFF1A\u542B detail1 \u51B3\u8BAE\u660E\u7EC6"
1298
+ },
1299
+ {
1300
+ domain: "decision",
1301
+ operation: "meeting.eb.decision.create",
1302
+ kind: "create",
1303
+ interfacePk: "create_mt_decision",
1304
+ // ⚠️ data_status **不在**写入字段内:2026-09-21 真机实测该接口拒绝它
1305
+ // (DataError:dataKey:data_status,该字段不存在);提交状态由系统自动置为 1(回查列表 data_status=1)。
1306
+ fields: ["mt_id", "mt_content"],
1307
+ requiredFields: ["mt_id", "mt_content"],
1308
+ summary: "EB \u7248\u521B\u5EFA\u4F1A\u8BAE\u51B3\u8BAE\uFF08create_mt_decision\uFF09\uFF1A\u4E3B\u8868\u6982\u8FF0 + detail1 \u51B3\u8BAE\u660E\u7EC6",
1309
+ notes: [
1310
+ "mt_id \u5173\u8054\u4F1A\u8BAE\uFF1Bmt_content \u4E3A\u6982\u8FF0\u6587\u672C\uFF08\u7531\u8C03\u7528\u65B9\u7ED3\u5408\u8BAE\u9898 / \u7EAA\u8981 / \u6750\u6599\u6C47\u603B\u540E\u4F20\u5165\uFF09\u3002",
1311
+ "**\u4E0D\u8981\u4F20 data_status**\uFF1A\u8BE5\u63A5\u53E3\u4E0D\u63A5\u53D7\u8BE5\u5B57\u6BB5\uFF08\u771F\u673A\u62A5 DataError:\u8BE5\u5B57\u6BB5\u4E0D\u5B58\u5728\uFF09\uFF0C\u63D0\u4EA4\u72B6\u6001\u7531\u7CFB\u7EDF\u81EA\u52A8\u7F6E 1\u3002",
1312
+ "detail1 \u81F3\u5C11 1 \u6761\uFF1AESB \u6309\u660E\u7EC6\u9010\u6761\u751F\u6210\u51B3\u8BAE\u4EFB\u52A1\uFF1B`rummager`\uFF08\u68C0\u67E5\u4EBA\uFF09\u5DF2\u6539\u4E3A\u975E\u5FC5\u586B\u3002",
1313
+ "decision_status \u9ED8\u8BA4 0\uFF08\u672A\u5B8C\u6210\uFF09\u3001related_type \u9ED8\u8BA4 0\uFF08\u672A\u5173\u8054\uFF09\uFF1Bexecutors \u5FC5\u987B\u662F**\u5458\u5DE5 id**\u3002"
1314
+ ],
1315
+ details: [
1316
+ {
1317
+ node: "detail1",
1318
+ fields: [
1319
+ "sort_number",
1320
+ "decision_title",
1321
+ "executors",
1322
+ "rummager",
1323
+ "begin_datetime",
1324
+ "end_datetime",
1325
+ "related_type",
1326
+ "relate_agenda",
1327
+ "decision_status",
1328
+ "relate_task"
1329
+ ],
1330
+ requiredFields: ["decision_title", "executors", "begin_datetime", "end_datetime", "decision_status"],
1331
+ dateFields: ["begin_datetime", "end_datetime"],
1332
+ // 0未完成 / 1已完成 / 2已延期(非法值 EB 常静默忽略,故入口拦下)
1333
+ enumFields: { decision_status: ["0", "1", "2"] },
1334
+ minRows: 1,
1335
+ purpose: "\u51B3\u8BAE\u660E\u7EC6\uFF1A\u6BCF\u6761 = \u4E00\u9879\u5F85\u529E\u4EFB\u52A1"
1336
+ }
1337
+ ]
1338
+ },
1339
+ {
1340
+ domain: "decision",
1341
+ operation: "meeting.eb.decision.delete",
1342
+ kind: "delete",
1343
+ interfacePk: "delete_mt_decision",
1344
+ summary: "EB \u7248\u5220\u9664\u4F1A\u8BAE\u51B3\u8BAE\uFF08delete_mt_decision\uFF09\uFF1A\u4EC5\u4F20 id\uFF08\u6982\u8FF0 id\uFF09",
1345
+ notes: ["\u5220\u9664\u6982\u8FF0**\u4E0D\u4F1A**\u81EA\u52A8\u56DE\u6536\u5DF2\u751F\u6210\u7684\u51B3\u8BAE\u4EFB\u52A1\uFF0C\u9700\u8981\u65F6\u53E6\u884C\u5904\u7406\u3002"]
1346
+ },
1347
+ {
1348
+ domain: "decision",
1349
+ operation: "meeting.eb.decision.update",
1350
+ kind: "update",
1351
+ interfacePk: "update_mt_decision",
1352
+ // 主表只放概述:`mt_content` 改文本,`mt_id` 可重新挂会议(一般不动)
1353
+ fields: ["id", "mt_content", "mt_id"],
1354
+ requiredFields: ["id"],
1355
+ pkQueryParam: "id",
1356
+ // 文档示例里 operateType.detail1 支持 cover(整组覆盖),默认是更新追加
1357
+ detailCover: true,
1358
+ summary: "EB \u7248\u66F4\u65B0\u4F1A\u8BAE\u51B3\u8BAE\uFF08update_mt_decision\uFF09\uFF1A\u6539\u6982\u8FF0\u6587\u672C + \u51B3\u8BAE\u660E\u7EC6\uFF082026-10-27 \u65B0\u589E\u63A5\u53E3\uFF09",
1359
+ notes: [
1360
+ "`id` = **\u51B3\u8BAE\u6982\u8FF0 id**\uFF08`decision.list` \u7684 rows[].mainTable.id\uFF09\uFF0C\u4E0D\u662F\u4F1A\u8BAE id\u3002",
1361
+ "\u53EA\u6539\u6982\u8FF0\u6587\u672C\uFF1A\u4F20 `id` + `mt_content` \u5373\u53EF\uFF0C\u4E0D\u5FC5\u5E26 detail1\uFF08\u771F\u673A\uFF1A\u660E\u7EC6\u539F\u6837\u4FDD\u7559\uFF09\u3002",
1362
+ '\u26D4 **\u9ED8\u8BA4\u5199\u5165\u662F\u300C\u8FFD\u52A0\u300D\uFF0C\u4E0D\u662F"\u6309 sort_number \u6539"**\uFF1A\u771F\u673A\u4F20 `detail1:[{sort_number:"1",...}]`\uFF0C\u7ED3\u679C\u662F**\u53C8\u52A0\u4E86\u4E00\u884C**\uFF08\u660E\u7EC6 2 \u2192 3\uFF0C\u4E24\u884C sort_number \u90FD\u662F 1\uFF09\u3002\u60F3\u771F\u6B63\u66FF\u6362\u660E\u7EC6\u5FC5\u987B\u4F20 `detail1Mode: "cover"`\u3002',
1363
+ '`detail1Mode: "cover"` = \u6574\u7EC4\u66FF\u6362\uFF08\u771F\u673A\uFF1A3 \u884C \u2192 \u4F20 2 \u884C\u540E\u6B63\u597D\u5269 2 \u884C\uFF0C\u660E\u7EC6 id \u5168\u6362\u65B0\uFF09\u3002\u26A0\uFE0F \u5220\u9664\u5F0F\u8986\u76D6\uFF1A\u4F20\u51E0\u884C\u5C31\u53EA\u5269\u51E0\u884C\uFF0C\u6F0F\u884C\u5373\u4E22\u6570\u636E\uFF1B\u4E0D\u4F20 detail1 \u65F6 CLI \u76F4\u63A5\u62E6\u4E0B\uFF0C\u4E0D\u4F1A"\u6E05\u7A7A\u660E\u7EC6"\u3002',
1364
+ "`begin_datetime` / `end_datetime` \u5230\u5206\u949F\uFF1B`decision_status` 0\u672A\u5B8C\u6210/1\u5DF2\u5B8C\u6210/2\u5DF2\u5EF6\u671F\uFF1B`related_type` 0\u672A\u5173\u8054/1\u65E5\u7A0B/2\u4EFB\u52A1\u3002",
1365
+ "\u2605 **\u6539\u51B3\u8BAE\u4E0D\u4F1A\u540C\u6B65\u5DF2\u751F\u6210\u7684\u51B3\u8BAE\u4EFB\u52A1**\uFF08\u771F\u673A\uFF1A\u6982\u8FF0\u4E0E\u660E\u7EC6\u90FD\u6539\u4E86\uFF0C\u4EFB\u52A1\u4ECD\u662F\u65E7\u6807\u9898\u65E7\u65F6\u95F4\uFF0C\u4EFB\u52A1\u6570\u4E5F\u6CA1\u53D8\uFF09\u3002\u4EFB\u52A1\u8981\u8DDF\u7740\u6539\uFF0C\u53EA\u80FD `decisionTask.delete` \u5220\u6389\u518D\u7528 `decisionTask.create` \u91CD\u5EFA\uFF08create \u5C5E\u515C\u5E95\uFF0C\u6CE8\u610F\u522B\u91CD\u590D\uFF09\u3002",
1366
+ "\u2605 \u66F4\u65B0**\u4E0D\u4F1A**\u89E6\u53D1 ESB \u518D\u751F\u6210\u4EFB\u52A1\uFF08\u771F\u673A\u4E24\u6B21\u66F4\u65B0\u540E\u4EFB\u52A1\u6570\u59CB\u7EC8 2\uFF09\uFF0C\u53EF\u4EE5\u653E\u5FC3\u6539\u6587\u672C\uFF0C\u4E0D\u4F1A\u7CCA\u51FA\u91CD\u590D\u4EFB\u52A1\u3002"
1367
+ ],
1368
+ details: [
1369
+ {
1370
+ node: "detail1",
1371
+ fields: [
1372
+ "sort_number",
1373
+ "decision_title",
1374
+ "executors",
1375
+ "rummager",
1376
+ "begin_datetime",
1377
+ "end_datetime",
1378
+ "related_type",
1379
+ "relate_agenda",
1380
+ "decision_status",
1381
+ "relate_task"
1382
+ ],
1383
+ dateFields: ["begin_datetime", "end_datetime"],
1384
+ enumFields: { decision_status: ["0", "1", "2"], related_type: ["0", "1", "2"] },
1385
+ purpose: "\u51B3\u8BAE\u660E\u7EC6\uFF1A\u9ED8\u8BA4\u6309 sort_number \u66F4\u65B0\uFF0Cdetail1Mode=cover \u65F6\u6574\u7EC4\u66FF\u6362"
1386
+ }
1387
+ ]
1388
+ },
1389
+ {
1390
+ domain: "decisionTask",
1391
+ operation: "meeting.eb.decisionTask.list",
1392
+ kind: "list",
1393
+ interfacePk: "query_mt_decision_task_list",
1394
+ countPk: "query_mt_decision_task_count",
1395
+ queryParams: ["mt_id", "relate_decision", "decision_status", "executors", "decision_title"],
1396
+ summary: "EB \u7248\u51B3\u8BAE\u4EFB\u52A1\u5217\u8868\uFF08query_mt_decision_task_list + count\uFF09\uFF1A\u4E00\u6761\u4EFB\u52A1 = \u4E00\u6761\u51B3\u8BAE\u660E\u7EC6",
1397
+ // 声明式进度汇总:结果进 `data.progress`(原始 rows 原样保留),实现见 task-progress.ts。
1398
+ summarizeRows: summarizeTaskProgress,
1399
+ notes: [
1400
+ "\u2605 **`data.progress` \u5DF2\u76F4\u63A5\u7ED9\u51FA\u8FDB\u5EA6\u4E0E\u5EF6\u8BEF**\uFF0C\u4E0D\u9700\u8981\u81EA\u5DF1\u89E3\u6790 detail1\uFF1A`progress.summary` \u662F\u6574\u9875\u6C47\u603B\uFF08total/done/overdue/inProgress/pending\uFF09\uFF1B`progress.items[]` \u9010\u4EFB\u52A1\u7ED9\u51FA `progress.status`\uFF08done \u5168\u5458\u5B8C\u6210 / overdue \u6709\u4EBA\u5EF6\u671F / inProgress \u90E8\u5206\u5B8C\u6210 / pending \u5C1A\u672A\u5F00\u59CB\uFF09\u4E0E `members[]`\uFF08\u6BCF\u4EBA executorId / executorName / status / finishDate\uFF09\u3002",
1401
+ "\u4EFB\u52A1\u7531\u7528\u6237\u914D\u7F6E\u7684 **ESB \u8054\u52A8**\u751F\u6210\uFF1A\u4E00\u6761**\u51B3\u8BAE\u660E\u7EC6**\u751F\u6210**\u4E00\u4E2A\u4EFB\u52A1**\uFF1B\u660E\u7EC6\u91CC\u5199\u591A\u4E2A\u6267\u884C\u4EBA \u21D2 \u8BE5\u4EFB\u52A1**\u591A\u4EBA\u5171\u540C\u8DDF\u8FDB**\uFF08\u771F\u673A\u5B9E\u6D4B\uFF1A1 \u660E\u7EC6 + 2 \u6267\u884C\u4EBA \u2192 \u4EC5 1 \u4E2A\u4EFB\u52A1\uFF09\u3002",
1402
+ "\u770B\u67D0\u4F1A\u8BAE\u7684\u5168\u90E8\u4EFB\u52A1 \u2192 \u4F20 mt_id\uFF1B\u770B\u67D0\u4EBA\u7684\u4EFB\u52A1 \u2192 \u4F20 executors\uFF08\u5458\u5DE5 id\uFF09\uFF1B\u5206\u9875\u7528 pageNo/pageSize\uFF08\u5206\u9875\u5FC5\u987B\u8D70 body.pageInfo\uFF0CCLI \u5DF2\u5904\u7406\uFF09\u3002",
1403
+ "\u2605 **\u8BFB\u8FDB\u5EA6\u8BF7\u770B `detail1`**\uFF1A\u6BCF\u6761 = \u4E00\u4E2A\u6267\u884C\u4EBA\u7684\u8DDF\u8FDB\u8BB0\u5F55\uFF0C\u542B `finish_status`\uFF08\u672A\u5B8C\u6210/\u5DF2\u5B8C\u6210/\u5DF2\u5EF6\u671F\uFF09\u3001`finish_date`\u3001`executor`\uFF1B**\u540C\u4E00\u6267\u884C\u4EBA\u91CD\u590D\u66F4\u65B0\u4F1A\u8986\u76D6\u5176\u8BB0\u5F55\uFF0C\u4E0D\u540C\u6267\u884C\u4EBA\u662F\u8FFD\u52A0**\uFF08\u771F\u673A\u5B9E\u6D4B\u4E92\u4E0D\u8986\u76D6\uFF09\u3002",
1404
+ "\u26A0\uFE0F **`mainTable.decision_status` \u4E0D\u80FD\u4F5C\u4E3A\u8FDB\u5EA6\u4F9D\u636E**\uFF1A\u771F\u673A\u5B9E\u6D4B\u5B83**\u59CB\u7EC8\u4E3A\u300C\u672A\u5B8C\u6210\u300D**\uFF0C\u65E2\u4E0D\u968F detail1 \u53D8\u5316\uFF0C\u4E5F\u65E0\u6CD5\u7ECF `update_mt_decision_task` \u5199\u5165\uFF08\u8BE5\u63A5\u53E3\u53EA\u6620\u5C04 detail1\uFF09\uFF0C\u6545 catalog \u672A\u66B4\u9732\u8BE5\u5B57\u6BB5\u3002",
1405
+ "\u4EFB\u52A1\u7531\u660E\u7EC6\u5E26\u51FA `begin_datetime`/`end_datetime`/`decision_title`\uFF0C\u53EF\u7528\u4E8E\u5C55\u793A\u8BA1\u5212\u5468\u671F\u3002"
1406
+ ]
1407
+ },
1408
+ {
1409
+ domain: "decisionTask",
1410
+ operation: "meeting.eb.decisionTask.create",
1411
+ kind: "create",
1412
+ interfacePk: "create_mt_decision_task",
1413
+ // ⚠️ 主表只放"任务本身"的字段;`executor` / `finish_status` / `finish_date` 属于 **detail1 子表**,
1414
+ // 放到 mainTable 会报 `DataError:dataKey:executor,该字段不存在`(2026-10-27 我本人踩过并误判成"表单缺字段")。
1415
+ fields: [
1416
+ "mt_id",
1417
+ "relate_decision",
1418
+ "decision_title",
1419
+ "executors",
1420
+ "rummager",
1421
+ "begin_datetime",
1422
+ "end_datetime",
1423
+ "decision_status",
1424
+ "related_type",
1425
+ "relate_agenda",
1426
+ "relate_task",
1427
+ "sort_number",
1428
+ "mt_video_id",
1429
+ "decision_rowid"
1430
+ ],
1431
+ requiredFields: ["mt_id", "decision_title", "executors", "rummager", "begin_datetime", "end_datetime"],
1432
+ dateFields: ["begin_datetime", "end_datetime"],
1433
+ summary: "EB \u7248\u76F4\u5EFA\u51B3\u8BAE\u4EFB\u52A1\uFF08create_mt_decision_task\uFF09\uFF1A\u26A0\uFE0F \u5E38\u89C4\u4E0D\u7528 \u2014\u2014 \u51B3\u8BAE\u540E ESB \u4F1A\u81EA\u52A8\u751F\u6210\uFF0C\u91CD\u590D\u5EFA\u4F1A\u4EA7\u751F\u91CD\u590D\u4EFB\u52A1",
1434
+ notes: [
1435
+ "\u2605 **\u5148\u770B\u6E05\u695A\uFF1A\u6B63\u5E38\u94FE\u8DEF\u4E0D\u9700\u8981\u8C03\u672C\u63A5\u53E3\u3002** `meeting.eb.decision.publish`\uFF08\u5199\u51B3\u8BAE\u6982\u8FF0 + \u6807\u8BB0\u5DF2\u51B3\u8BAE\uFF09\u4E4B\u540E\uFF0CESB \u4F1A\u6309**\u6BCF\u6761\u51B3\u8BAE\u660E\u7EC6**\u81EA\u52A8\u751F\u6210\u4E00\u4E2A\u4EFB\u52A1\uFF082026-10-27 \u771F\u673A\u518D\u6B21\u786E\u8BA4\uFF1A\u4EFB\u52A1\u7684 `relate_decision` \u6307\u5411\u6982\u8FF0\u3001`create_time` \u4E0E\u51B3\u8BAE\u540C\u79D2\uFF09\u3002\u518D\u624B\u5DE5\u5EFA\u4E00\u6761 \u21D2 \u540C\u4E00\u4EF6\u4E8B\u51FA\u73B0\u4E24\u4E2A\u4EFB\u52A1\u3002",
1436
+ "\u672C\u63A5\u53E3\u53EA\u7528\u4E8E **ESB \u6CA1\u89E6\u53D1 / \u4E34\u65F6\u8FFD\u52A0** \u7684\u8865\u5EFA\uFF1B\u5EFA\u5B8C\u8BF7\u7528 `decisionTask.list` \u56DE\u67E5\uFF0C\u907F\u514D\u91CD\u590D\u3002",
1437
+ "`mt_id` \u6302\u4F1A\u8BAE\uFF0C`relate_decision` \u6302\u51B3\u8BAE\u6982\u8FF0 id\uFF08`decision.list` \u7684 rows[].mainTable.id\uFF09\u3002",
1438
+ '\u2605 **`executor` \u5FC5\u987B\u653E\u5728 `detail1` \u91CC**\uFF08\u6267\u884C\u4EBA\u8DDF\u8FDB\u5B50\u8868\uFF09\uFF0C\u4E0D\u662F mainTable\uFF1A`detail1: [{ executor: "<\u5458\u5DE5id>", finish_status: "0" }]`\u3002`executors`\uFF08\u4E3B\u8868\uFF0C\u6267\u884C\u4EBA\u96C6\u5408\uFF09\u4E0E `detail1[].executor` \u8981\u4E00\u81F4\uFF0C\u4E24\u5904\u90FD\u662F**\u5458\u5DE5 id**\u3002',
1439
+ "`finish_status`\uFF1A0\u672A\u5B8C\u6210 / 1\u5DF2\u5B8C\u6210 / 2\u5DF2\u5EF6\u671F\uFF1B`finish_date` \u82E5\u4F20\u5FC5\u987B `yyyy-MM-dd HH:mm:ss`\u3002",
1440
+ "`begin_datetime` / `end_datetime` \u5230\u5206\u949F\u3002",
1441
+ '\u2705 2026-10-27 16:00 \u771F\u673A\u5DF2\u8DD1\u901A\uFF1A`{mt_id, relate_decision, decision_title, executors, rummager, begin/end} + detail1:[{executor, finish_status}]` \u2192 `dataIds:["1330957\u2026"]`\uFF0C\u5217\u8868\u53EF\u89C1\uFF08\u968F\u540E\u5DF2\u7528 delete \u6E05\u6389\uFF09\u3002'
1442
+ ],
1443
+ details: [
1444
+ {
1445
+ node: "detail1",
1446
+ fields: ["executor", "finish_status", "finish_date"],
1447
+ requiredFields: ["executor"],
1448
+ enumFields: { finish_status: ["0", "1", "2"] },
1449
+ secondDateFields: ["finish_date"],
1450
+ minRows: 1,
1451
+ purpose: "\u6267\u884C\u4EBA\u8DDF\u8FDB\u884C\uFF1Aexecutor \u5FC5\u987B\u5728\u8FD9\u91CC\u4F20\uFF08\u653E\u4E3B\u8868\u4F1A\u62A5\u5B57\u6BB5\u4E0D\u5B58\u5728\uFF09"
1452
+ }
1453
+ ]
1454
+ },
1455
+ {
1456
+ domain: "decisionTask",
1457
+ operation: "meeting.eb.decisionTask.delete",
1458
+ kind: "delete",
1459
+ interfacePk: "delete_mt_decision_task",
1460
+ summary: "EB \u7248\u5220\u9664\u51B3\u8BAE\u4EFB\u52A1\uFF08delete_mt_decision_task\uFF09\uFF1A\u4EC5\u4F20 id",
1461
+ notes: [
1462
+ "id = **\u4EFB\u52A1 id**\uFF08decisionTask.list \u7684 rows[].mainTable.id\uFF09\uFF0C\u4E0D\u662F\u4F1A\u8BAE id / \u51B3\u8BAE id\u3002",
1463
+ "\u5220\u9664\u4EFB\u52A1**\u4E0D\u4F1A**\u5F71\u54CD\u51B3\u8BAE\u6982\u8FF0\uFF08`delete_mt_decision` \u4E5F\u4E0D\u56DE\u6536\u4EFB\u52A1\uFF09\uFF0C\u4E24\u8FB9\u72EC\u7ACB\u5220\u3002"
1464
+ ]
1465
+ },
1466
+ {
1467
+ domain: "decisionTask",
1468
+ operation: "meeting.eb.decisionTask.update",
1469
+ kind: "update",
1470
+ interfacePk: "update_mt_decision_task",
1471
+ // ⚠️ 只开放 id:真机实测即使传主表 `decision_status`,接口返回成功但**值不生效**
1472
+ // (该接口只映射 detail1 明细),故不暴露它以免误导。
1473
+ fields: ["id"],
1474
+ requiredFields: ["id"],
1475
+ // 主键必须走 URL(updateFormData 端点统一要求)
1476
+ pkQueryParam: "id",
1477
+ summary: "EB \u7248\u66F4\u65B0\u51B3\u8BAE\u4EFB\u52A1\u5B8C\u6210\u72B6\u6001\uFF08update_mt_decision_task\uFF09\uFF1A\u6309\u6267\u884C\u4EBA\u66F4\u65B0 detail1",
1478
+ notes: [
1479
+ "id = **\u4EFB\u52A1 id**\uFF08decisionTask.list \u7684 rows[].mainTable.id\uFF09\uFF0C\u4E0D\u662F\u4F1A\u8BAE id\u3001\u4E0D\u662F\u51B3\u8BAE id\u3002",
1480
+ "detail1 \u4F20 executor\uFF08\u5458\u5DE5 id\uFF09+ finish_status\uFF080\u672A\u5B8C\u6210/1\u5DF2\u5B8C\u6210/2\u5DF2\u5EF6\u671F\uFF09+ finish_date\uFF08**\u5E26\u79D2**\uFF1Ayyyy-MM-dd HH:mm:ss\uFF09\u3002",
1481
+ "\u26A0\uFE0F **finish_date \u662F\u670D\u52A1\u7AEF\u5FC5\u586B**\uFF08\u771F\u673A\uFF1A\u4E0D\u4F20\u62A5\u300C\u5B58\u4E3A\u672A\u586B\u5199\u7684\u5FC5\u586B\u5B57\u6BB5: finish_date\u300D\uFF09\uFF1B\u628A\u4EFB\u52A1\u6539\u56DE\u300C\u672A\u5B8C\u6210\u300D\u65F6\u4F20\u4E00\u4E2A**\u7A7A\u683C**\u5373\u53EF\u663E\u5F0F\u6E05\u7A7A\uFF08CLI \u4F1A\u843D\u5E93\u4E3A\u7A7A\u4E32\uFF0C\u4E0E\u9875\u9762\u751F\u6210\u7684\u672A\u5B8C\u6210\u8BB0\u5F55\u4E00\u81F4\uFF09\u3002",
1482
+ "\u4E0D\u4F20 operationinfo.operateType \u65F6\u4E3A\u300C\u66F4\u65B0\u8FFD\u52A0\u300D\uFF0C\u4E0D\u4F1A\u8986\u76D6\u5176\u4ED6\u6267\u884C\u4EBA\u7684\u8BB0\u5F55 \u2014\u2014 \u771F\u673A\u5B9E\u6D4B\uFF1A\u540C\u4E00\u4EFB\u52A1\u4E0A\u4E24\u4EBA\u5206\u522B\u8DDF\u8FDB\u540E\uFF0Cdetail1 \u4FDD\u7559**\u4E24\u6761**\u8BB0\u5F55\u3002",
1483
+ "\u26A0\uFE0F **\u4EFB\u52A1\u4E3B\u8868\u7684 decision_status \u4E0D\u968F detail1 \u53D8\u5316**\uFF08\u771F\u673A\u5B9E\u6D4B\u59CB\u7EC8\u4E3A\u300C\u672A\u5B8C\u6210\u300D\uFF09\uFF1B\u67E5\u4EFB\u52A1\u8FDB\u5EA6\u8BF7\u770B detail1 \u7684 finish_status\u3002",
1484
+ "\u5199\u5165\u540E\u5EFA\u8BAE\u56DE\u67E5 decisionTask.list \u786E\u8BA4\uFF1BEB \u5199\u63A5\u53E3\u62A5\u9519**\u4E0D\u4EE3\u8868\u6CA1\u6709\u5199\u5165**\u3002"
1485
+ ],
1486
+ details: [
1487
+ {
1488
+ node: "detail1",
1489
+ fields: ["executor", "finish_status", "finish_date"],
1490
+ // finish_date 服务端也是必填;「未完成」时传空格显式清空(见 factory 的 normalizeDetailRow)。
1491
+ requiredFields: ["executor", "finish_status", "finish_date"],
1492
+ // 0未完成 / 1已完成 / 2已延期(非法值 EB 常静默忽略,故入口拦下并提示可选值)
1493
+ enumFields: { finish_status: ["0", "1", "2"] },
1494
+ // finish_date 必须**带秒**:真机实测传 "2026-09-21 18:30" 被拒(要求 yyyy-MM-dd HH:mm:ss)。
1495
+ secondDateFields: ["finish_date"],
1496
+ minRows: 1,
1497
+ purpose: "\u6267\u884C\u4EBA\u8DDF\u8FDB\uFF1A\u540C\u4E00\u4EFB\u52A1\u7684\u6BCF\u4E2A\u6267\u884C\u4EBA\u5206\u522B\u8BB0\u5F55\u5B8C\u6210\u72B6\u6001"
1498
+ }
1499
+ ]
1500
+ },
1501
+ {
1502
+ domain: "meeting",
1503
+ operation: "meeting.eb.meeting.markDecided",
1504
+ kind: "update",
1505
+ interfacePk: "update_mt_isdecision",
1506
+ fields: ["id", "decision_Id", "is_decision", "mt_status"],
1507
+ requiredFields: ["id", "is_decision"],
1508
+ // 主键必须走 URL(updateFormData 端点统一要求)
1509
+ pkQueryParam: "id",
1510
+ summary: "EB \u7248\u628A\u4F1A\u8BAE\u6807\u8BB0\u4E3A\u5DF2\u51B3\u8BAE\uFF08update_mt_isdecision\uFF09\uFF1A\u5199\u56DE\u5173\u8054\u51B3\u8BAE + \u51B3\u8BAE\u72B6\u6001 + \u4F1A\u8BAE\u72B6\u6001",
1511
+ notes: [
1512
+ "is_decision\uFF1A0\u672A\u51B3\u8BAE / 1\u51B3\u8BAE\u4E34\u65F6\u4FDD\u5B58 / **2\u51B3\u8BAE\u63D0\u4EA4\u5B8C\u6210**\u3002",
1513
+ "decision_Id\uFF1A\u5173\u8054\u7684\u51B3\u8BAE\u6982\u8FF0 id\uFF08decision.create \u7684 dataIds[0]\uFF09\u3002",
1514
+ "mt_status\uFF1A**8\u7ED3\u675F**\uFF08\u4EA7\u751F\u51B3\u8BAE\u5373\u89C6\u4E3A\u4F1A\u8BAE\u7ED3\u675F\uFF09\uFF0C\u4E5F\u53EF\u6309\u9700\u4F20 9\u8FDB\u884C\u4E2D \u7B49\u3002",
1515
+ "detail1\uFF08\u6C47\u62A5\u4EBA\uFF09/ detail2\uFF08\u670D\u52A1\u9879\u76EE\uFF09\u5DF2\u7531\u63A5\u53E3\u914D\u7F6E\u6E05\u7A7A\uFF0C**\u65E0\u9700\u4F20**\u3002"
1516
+ ]
1517
+ }
1518
+ ];
1519
+ function isWriteKind(kind) {
1520
+ return kind === "create" || kind === "update" || kind === "delete";
1521
+ }
1522
+
1523
+ // src/shortcuts/meeting/operations/eb/factory.ts
1524
+ var EB_BASE = "/api/ebuilder/form/formdata/v2";
1525
+ var EB_READ_OP = { list: "getFormDataList", detail: "getFormDataByPk", get: "getFormDataList" };
1526
+ var EB_WRITE_OP = { create: "saveFormData", update: "updateFormData", delete: "deleteFormData" };
1527
+ var CONTINUATION_TTL_SECONDS = 600;
1528
+ function ebBusinessSuccess(value) {
1529
+ if (!value || typeof value !== "object") return false;
1530
+ if (value.code !== void 0 && value.code !== null) return Number(value.code) === 200;
1531
+ if (value.datajson && typeof value.datajson === "object") {
1532
+ const status = value.datajson.status;
1533
+ return status !== false;
1534
+ }
1535
+ return value.status === true;
1536
+ }
1537
+ function stableStringify(value) {
1538
+ if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
1539
+ if (value && typeof value === "object") {
1540
+ const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
1541
+ return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(",")}}`;
1542
+ }
1543
+ return JSON.stringify(value ?? null);
1544
+ }
1545
+ function fingerprint(value) {
1546
+ return createHash("sha256").update(stableStringify(value)).digest("hex").slice(0, 32);
1547
+ }
1548
+ function requireConfirm(args, action) {
1549
+ if (args.confirm !== true) {
1550
+ throw meetingConfirmationError(action, { hint: "\u91CD\u65B0\u8C03\u7528\u65F6\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation" });
1551
+ }
1552
+ }
1553
+ async function verifyLease(args, action, env) {
1554
+ const lease = await env.continuation.verify(args.continuation, action);
1555
+ const session = await env.host.getSession();
1556
+ if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
1557
+ throw meetingValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
1558
+ }
1559
+ return lease;
1560
+ }
1561
+ function isNetworkError(error) {
1562
+ return error instanceof Error && error.type === "network";
1563
+ }
1564
+ function queryBody(userId, page) {
1565
+ return {
1566
+ datajson: {
1567
+ mainTable: {},
1568
+ // ⚠️ 分页必须放在 body 的 pageInfo 里(值为字符串):只放 URL query 时 EB 会忽略,
1569
+ // 恒定返回首页 10 条(2026-09-21 真机暴露:pageSize=60 仍只回 10 条)。
1570
+ ...page ? { pageInfo: { pageNo: String(page.pageNo), pageSize: String(page.pageSize) } } : {},
1571
+ header: { operator: userId }
1572
+ }
1573
+ };
1574
+ }
1575
+ function detailBody(userId, id) {
1576
+ return { datajson: { mainTable: { id }, header: { operator: userId } } };
1577
+ }
1578
+ function writeBody(userId, payload) {
1579
+ const datas = { mainTable: payload.mainTable, ...payload.details };
1580
+ const operationinfo = { printCost: false, asyncPostProcess: false, asyncMark: false };
1581
+ if (Object.keys(payload.operateType).length > 0) operationinfo.operateType = payload.operateType;
1582
+ return {
1583
+ datajson: {
1584
+ operationinfo,
1585
+ datas: [datas],
1586
+ header: { operator: userId }
1587
+ }
1588
+ };
1589
+ }
1590
+ function extractEbRows(response) {
1591
+ const value = response;
1592
+ const dj = value?.datajson ?? value?.data ?? {};
1593
+ const raw = dj?.datas ?? dj?.data ?? dj?.displayData ?? (Array.isArray(dj) ? dj : void 0);
1594
+ if (Array.isArray(raw)) {
1595
+ const total = typeof dj?.total === "number" ? dj.total : typeof value?.total === "number" ? value.total : void 0;
1596
+ return { rows: raw, ...total === void 0 ? {} : { total } };
1597
+ }
1598
+ if (raw !== null && typeof raw === "object") {
1599
+ return { rows: [raw] };
1600
+ }
1601
+ return { rows: [] };
1602
+ }
1603
+ function extractEbCount(response) {
1604
+ const value = response;
1605
+ const dj = value?.datajson ?? value?.data ?? {};
1606
+ const raw = dj?.datas ?? dj?.total ?? value?.total;
1607
+ if (typeof raw === "number") return raw;
1608
+ if (typeof raw === "string" && /^\d+$/u.test(raw)) return Number(raw);
1609
+ if (Array.isArray(raw)) return raw.length;
1610
+ return void 0;
1611
+ }
1612
+ function buildReadInputSchema(endpoint) {
1613
+ const properties = {};
1614
+ if (endpoint.kind === "detail") {
1615
+ properties.id = { ...SCHEMA_ID, description: "\u6570\u636E\u4E3B\u952E id" };
1616
+ } else if (endpoint.kind === "list") {
1617
+ for (const param of endpoint.queryParams ?? []) {
1618
+ properties[param] = { type: "string", description: `EB \u7B5B\u9009\u53C2\u6570\uFF08URL \u5360\u4F4D\u7B26\u540D ${param}\uFF09` };
1619
+ }
1620
+ properties.pageNo = { type: "integer", minimum: 1, description: "\u9875\u7801\uFF0C\u9ED8\u8BA4 1" };
1621
+ properties.pageSize = { type: "integer", minimum: 1, maximum: 200, description: "\u6BCF\u9875\u6761\u6570\uFF0C\u9ED8\u8BA4 20" };
1622
+ if (endpoint.countPk) {
1623
+ properties.withCount = { type: "boolean", description: "\u662F\u5426\u5148\u67E5\u603B\u6570\uFF08\u9ED8\u8BA4 true\uFF0C\u6761\u4EF6\u4E0E\u5217\u8868\u4E00\u81F4\uFF09" };
1624
+ }
1625
+ }
1626
+ return {
1627
+ type: "object",
1628
+ additionalProperties: false,
1629
+ properties,
1630
+ ...endpoint.kind === "detail" ? { required: ["id"] } : {}
1631
+ };
1632
+ }
1633
+ function buildReadOperation(endpoint) {
1634
+ const readOp = EB_READ_OP[endpoint.kind];
1635
+ const capability = `eb.${endpoint.domain}`;
1636
+ return {
1637
+ name: endpoint.operation,
1638
+ resource: "eb",
1639
+ method: endpoint.operation,
1640
+ action: endpoint.operation,
1641
+ summary: endpoint.summary,
1642
+ capability,
1643
+ risk: "read",
1644
+ inputSchema: buildReadInputSchema(endpoint),
1645
+ handler: async (args, env) => {
1646
+ const session = await env.host.getSession();
1647
+ const acceptBusiness = ebBusinessSuccess;
1648
+ const path = `${EB_BASE}/${readOp}/${endpoint.interfacePk}`;
1649
+ if (endpoint.kind === "detail") {
1650
+ const id = toIdString(args.id, "id");
1651
+ const response2 = await env.host.request({
1652
+ method: "POST",
1653
+ path,
1654
+ operation: endpoint.operation,
1655
+ body: detailBody(session.userId, id),
1656
+ acceptBusiness
1657
+ });
1658
+ const { rows: rows2 } = extractEbRows(response2);
1659
+ const row = rows2[0] ?? null;
1660
+ const data = row?.mainTable ?? response2?.datajson?.mainTable ?? null;
1661
+ if (data === void 0 || data === null) {
1662
+ throw meetingValidationError(
1663
+ "not_found",
1664
+ `${endpoint.interfacePk} \u672A\u627E\u5230 id=${id} \u7684\u6570\u636E\uFF08\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\uFF0C\u6216\u5F53\u524D\u8D26\u53F7\u65E0\u6743\u9650\uFF09`,
1665
+ { id, interfacePk: endpoint.interfacePk }
1666
+ );
1667
+ }
1668
+ const detailNodes = {};
1669
+ if (row) {
1670
+ for (const [key, value] of Object.entries(row)) {
1671
+ if (key !== "mainTable") detailNodes[key] = value;
1672
+ }
1673
+ }
1674
+ return meetingSuccess(
1675
+ endpoint.operation,
1676
+ { id, data, ...Object.keys(detailNodes).length > 0 ? { details: detailNodes } : {} },
1677
+ endpoint.notes ? { meta: { notes: endpoint.notes } } : {}
1678
+ );
1679
+ }
1680
+ const query = {};
1681
+ for (const param of endpoint.queryParams ?? []) {
1682
+ const value = args[param];
1683
+ if (value !== void 0 && value !== null && value !== "") query[param] = value;
1684
+ }
1685
+ if (endpoint.kind === "get") {
1686
+ const response2 = await env.host.request({
1687
+ method: "POST",
1688
+ path,
1689
+ operation: endpoint.operation,
1690
+ body: queryBody(session.userId),
1691
+ acceptBusiness
1692
+ });
1693
+ const { rows: rows2 } = extractEbRows(response2);
1694
+ const data = rows2[0] ?? response2?.datajson ?? null;
1695
+ return meetingSuccess(endpoint.operation, { data, count: rows2.length }, endpoint.notes ? { meta: { notes: endpoint.notes } } : {});
1696
+ }
1697
+ const pageNo = typeof args.pageNo === "number" ? args.pageNo : 1;
1698
+ const pageSize = typeof args.pageSize === "number" ? args.pageSize : 20;
1699
+ let total;
1700
+ if (endpoint.countPk && args.withCount !== false) {
1701
+ const countResponse = await env.host.request({
1702
+ method: "POST",
1703
+ path: `${EB_BASE}/getFormDataCount/${endpoint.countPk}`,
1704
+ operation: endpoint.operation,
1705
+ query,
1706
+ body: queryBody(session.userId),
1707
+ acceptBusiness
1708
+ });
1709
+ total = extractEbCount(countResponse);
1710
+ }
1711
+ const response = await env.host.request({
1712
+ method: "POST",
1713
+ path,
1714
+ operation: endpoint.operation,
1715
+ query: { ...query, pageNo, pageSize },
1716
+ // 分页同时进 body.pageInfo:EB 只认 body 里的 pageInfo,仅放 URL query 会被忽略。
1717
+ body: queryBody(session.userId, { pageNo, pageSize }),
1718
+ acceptBusiness
1719
+ });
1720
+ const { rows, total: listTotal } = extractEbRows(response);
1721
+ const resolvedTotal = total ?? listTotal ?? rows.length;
1722
+ const pageMeta = {
1723
+ pageNo,
1724
+ pageSize,
1725
+ pageCount: rows.length,
1726
+ total: Math.max(resolvedTotal, rows.length)
1727
+ };
1728
+ const summarized = endpoint.summarizeRows ? endpoint.summarizeRows(rows, {
1729
+ pageCount: rows.length,
1730
+ total: pageMeta.total,
1731
+ pageNo,
1732
+ pageSize
1733
+ }) : void 0;
1734
+ const progress = summarized === void 0 ? void 0 : summarized !== null && typeof summarized === "object" ? { ...summarized, page: pageMeta } : { value: summarized, page: pageMeta };
1735
+ const effectiveTotal = Math.max(resolvedTotal, rows.length);
1736
+ const pageWarnings = [];
1737
+ if (effectiveTotal > rows.length) {
1738
+ const missing = effectiveTotal - rows.length;
1739
+ pageWarnings.push(
1740
+ `\u672C\u9875\u8FD4\u56DE ${rows.length} \u6761\uFF0C\u5171 ${effectiveTotal} \u6761\uFF1A\u8FD8\u6709 ${missing} \u6761\u672A\u53D6\u5230\u3002\u9700\u8981\u5168\u91CF\u8BF7\u7FFB\u9875\uFF08pageNo=${pageNo + 1} \u8D77\uFF09\u6216\u52A0\u5927 pageSize\uFF0C\u6216\u6536\u7A84\u7B5B\u9009\u6761\u4EF6`
1741
+ );
1742
+ }
1743
+ return meetingSuccess(
1744
+ endpoint.operation,
1745
+ {
1746
+ total: effectiveTotal,
1747
+ pageNo,
1748
+ pageSize,
1749
+ count: rows.length,
1750
+ ...progress ? { progress } : {},
1751
+ rows,
1752
+ filters: query
1753
+ },
1754
+ {
1755
+ ...endpoint.notes ? { meta: { notes: endpoint.notes } } : {},
1756
+ ...pageWarnings.length > 0 ? { warnings: pageWarnings } : {}
1757
+ }
1758
+ );
1759
+ }
1760
+ };
1761
+ }
1762
+ function writePkQuery(endpoint, payload) {
1763
+ if (endpoint.kind === "delete" && endpoint.batchDeleteFields) return void 0;
1764
+ const param = endpoint.pkQueryParam ?? (endpoint.kind === "delete" ? "id" : void 0);
1765
+ if (!param) return void 0;
1766
+ const value = payload.mainTable.id;
1767
+ if (value === void 0 || value === null || value === "") return void 0;
1768
+ return { [param]: value };
1769
+ }
1770
+ function pathWithPk(endpoint, basePath, payload) {
1771
+ const query = writePkQuery(endpoint, payload);
1772
+ if (!query) return basePath;
1773
+ const search = new URLSearchParams(Object.entries(query).map(([key, item]) => [key, String(item)])).toString();
1774
+ return `${basePath}?${search}`;
1775
+ }
1776
+ function diffHours(begin, end) {
1777
+ const parse = (text) => {
1778
+ const matched = text.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/u);
1779
+ if (!matched) return void 0;
1780
+ const [, y, mo, d, h, mi] = matched;
1781
+ return Date.UTC(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi));
1782
+ };
1783
+ const from = parse(begin);
1784
+ const to = parse(end);
1785
+ if (from === void 0 || to === void 0) return void 0;
1786
+ const hours = (to - from) / 36e5;
1787
+ return hours > 0 ? Math.round(hours * 100) / 100 : void 0;
1788
+ }
1789
+ function normalizeDetailRow(spec, row, index) {
1790
+ if (!row || typeof row !== "object" || Array.isArray(row)) {
1791
+ throw meetingValidationError(
1792
+ "invalid_detail_row",
1793
+ `${spec.node}[${index}] \u5FC5\u987B\u662F\u5BF9\u8C61`,
1794
+ { node: spec.node, index }
1795
+ );
1796
+ }
1797
+ const source = row;
1798
+ const out = {};
1799
+ for (const field of spec.fields) {
1800
+ const value = source[field];
1801
+ if (value === void 0 || value === null) continue;
1802
+ const isDateField = (spec.dateFields ?? []).includes(field) || (spec.secondDateFields ?? []).includes(field);
1803
+ if (isDateField && typeof value === "string" && value.trim() === "") {
1804
+ out[field] = "";
1805
+ continue;
1806
+ }
1807
+ if (value === "") continue;
1808
+ out[field] = (spec.dateFields ?? []).includes(field) ? assertDateTimeMinute(value, `${spec.node}[${index}].${field}`) : (spec.secondDateFields ?? []).includes(field) ? assertDateTimeSecond(value, `${spec.node}[${index}].${field}`) : value;
1809
+ }
1810
+ for (const [field, allowed] of Object.entries(spec.enumFields ?? {})) {
1811
+ const value = out[field];
1812
+ if (value === void 0) continue;
1813
+ if (!allowed.includes(String(value))) {
1814
+ throw meetingValidationError(
1815
+ "invalid_enum",
1816
+ `${spec.node} \u7B2C ${index + 1} \u6761 ${field} \u53D6\u503C\u975E\u6CD5\uFF1A${String(value)}\uFF08\u53EF\u9009\uFF1A${allowed.join(" / ")}\uFF09`,
1817
+ { node: spec.node, index, field, value: String(value), allowed }
1818
+ );
1819
+ }
1820
+ }
1821
+ const missing = (spec.requiredFields ?? []).filter((field) => out[field] === void 0);
1822
+ if (missing.length > 0) {
1823
+ throw meetingValidationError(
1824
+ "missing_required_field",
1825
+ `${spec.node} \u7B2C ${index + 1} \u6761\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5\uFF1A${missing.join(", ")}`,
1826
+ { node: spec.node, index, missing }
1827
+ );
1828
+ }
1829
+ return out;
1830
+ }
1831
+ function normalizeEbWrite(endpoint, args, userId) {
1832
+ const fields = endpoint.kind === "delete" ? endpoint.batchDeleteFields ?? ["id"] : endpoint.fields ?? [];
1833
+ const mainTable = {};
1834
+ for (const field of fields) {
1835
+ const value = args[field];
1836
+ if (value === void 0 || value === null || value === "") continue;
1837
+ if ((endpoint.dateFields ?? []).includes(field)) {
1838
+ mainTable[field] = assertDateTimeMinute(value, field);
1839
+ } else if ((endpoint.secondDateFields ?? []).includes(field)) {
1840
+ mainTable[field] = assertDateTimeSecond(value, field);
1841
+ } else if ((endpoint.dateOnlyFields ?? []).includes(field)) {
1842
+ mainTable[field] = assertDate(value, field);
1843
+ } else {
1844
+ mainTable[field] = value;
1845
+ }
1846
+ }
1847
+ if (endpoint.kind === "create" && endpoint.fieldDefaults) {
1848
+ for (const [field, value] of Object.entries(endpoint.fieldDefaults)) {
1849
+ if (mainTable[field] === void 0) mainTable[field] = value;
1850
+ }
1851
+ }
1852
+ if (endpoint.interfacePk === "create_meeting") {
1853
+ if (mainTable.caller === void 0) mainTable.caller = userId;
1854
+ if (mainTable.contacter === void 0) mainTable.contacter = userId;
1855
+ const hours = typeof mainTable.begin_datetime === "string" && typeof mainTable.end_datetime === "string" ? diffHours(mainTable.begin_datetime, mainTable.end_datetime) : void 0;
1856
+ if (hours !== void 0) mainTable.mt_hours = hours;
1857
+ }
1858
+ const required = endpoint.kind === "delete" ? endpoint.batchDeleteFields ?? ["id"] : endpoint.requiredFields ?? [];
1859
+ const missing = required.filter((field) => mainTable[field] === void 0);
1860
+ if (missing.length > 0) {
1861
+ throw meetingValidationError("missing_required_field", `\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5\uFF1A${missing.join(", ")}`, { missing });
1862
+ }
1863
+ const details = {};
1864
+ for (const spec of endpoint.details ?? []) {
1865
+ const raw = args[spec.node];
1866
+ const minRows = spec.minRows ?? 0;
1867
+ if (raw === void 0 || raw === null) {
1868
+ if (minRows > 0) {
1869
+ throw meetingValidationError(
1870
+ "missing_required_field",
1871
+ `\u7F3A\u5C11\u5FC5\u586B\u660E\u7EC6\uFF1A${spec.node} \u81F3\u5C11 ${minRows} \u6761${spec.purpose ? `\uFF08${spec.purpose}\uFF09` : ""}`,
1872
+ { node: spec.node, minRows }
1873
+ );
1874
+ }
1875
+ continue;
1876
+ }
1877
+ if (!Array.isArray(raw)) {
1878
+ throw meetingValidationError(
1879
+ "invalid_detail",
1880
+ `${spec.node} \u5FC5\u987B\u662F\u6570\u7EC4\uFF0C\u6BCF\u4E2A\u5143\u7D20\u4E3A\u4E00\u6761\u660E\u7EC6\u5BF9\u8C61`,
1881
+ { node: spec.node }
1882
+ );
1883
+ }
1884
+ const rows = raw.map((row, index) => normalizeDetailRow(spec, row, index));
1885
+ if (rows.length < minRows) {
1886
+ throw meetingValidationError(
1887
+ "missing_required_field",
1888
+ `${spec.node} \u81F3\u5C11 ${minRows} \u6761\u660E\u7EC6\uFF08\u5F53\u524D ${rows.length} \u6761\uFF09`,
1889
+ { node: spec.node, minRows, actual: rows.length }
1890
+ );
1891
+ }
1892
+ if (rows.length > 0) details[spec.node] = rows;
1893
+ }
1894
+ const operateType = {};
1895
+ const detailMode = args.detail1Mode;
1896
+ if (detailMode !== void 0 && detailMode !== null && detailMode !== "") {
1897
+ if (!endpoint.detailCover) {
1898
+ throw meetingValidationError(
1899
+ "unsupported_detail_mode",
1900
+ `${endpoint.interfacePk} \u4E0D\u652F\u6301 detail1Mode\uFF08\u8BE5\u63A5\u53E3\u672A\u58F0\u660E\u660E\u7EC6\u8986\u76D6\u80FD\u529B\uFF09\uFF0C\u8BF7\u53BB\u6389\u8BE5\u53C2\u6570\u6309\u9ED8\u8BA4\u8FFD\u52A0\u5199\u5165`,
1901
+ { interfacePk: endpoint.interfacePk }
1902
+ );
1903
+ }
1904
+ if (detailMode !== "append" && detailMode !== "cover") {
1905
+ throw meetingValidationError(
1906
+ "invalid_detail_mode",
1907
+ `detail1Mode \u53EA\u80FD\u662F append\uFF08\u8FFD\u52A0\uFF0C\u9ED8\u8BA4\uFF09\u6216 cover\uFF08\u8986\u76D6\uFF1A\u4F20\u51E0\u884C\u5C31\u53EA\u5269\u51E0\u884C\uFF09`,
1908
+ { detail1Mode: String(detailMode) }
1909
+ );
1910
+ }
1911
+ if (detailMode === "cover") {
1912
+ if (Object.keys(details).length === 0) {
1913
+ throw meetingValidationError(
1914
+ "invalid_detail_mode",
1915
+ "detail1Mode=cover \u65F6\u5FC5\u987B\u540C\u65F6\u4F20 detail1\uFF08\u81F3\u5C11 1 \u884C\uFF09\uFF1Acover \u4F1A\u8986\u76D6\u6574\u7EC4\u660E\u7EC6\uFF0C\u7A7A\u6570\u7EC4\u7B49\u4E8E\u628A\u660E\u7EC6\u5168\u5220\u6389",
1916
+ { node: "detail1" }
1917
+ );
1918
+ }
1919
+ for (const node of Object.keys(details)) operateType[node] = "cover";
1920
+ }
1921
+ }
1922
+ return { mainTable, details, operateType };
1923
+ }
1924
+ function buildWriteInputSchema(endpoint, includeConfirm) {
1925
+ const properties = {};
1926
+ if (includeConfirm) {
1927
+ properties.confirm = { const: true };
1928
+ properties.continuation = { type: "string", minLength: 1 };
1929
+ }
1930
+ if (endpoint.kind === "delete") {
1931
+ if (endpoint.batchDeleteFields && endpoint.batchDeleteFields.length > 0) {
1932
+ for (const field of endpoint.batchDeleteFields) {
1933
+ properties[field] = { type: "string", description: `${field}\uFF08\u5220\u9664\u6761\u4EF6\uFF0C\u8BE5\u63A5\u53E3\u6309\u5B83\u6279\u91CF\u5220\u9664\uFF09` };
1934
+ }
1935
+ } else {
1936
+ properties.id = { ...SCHEMA_ID, description: "\u6570\u636E\u4E3B\u952E id\uFF08\u5FC5\u586B\uFF09" };
1937
+ }
1938
+ } else {
1939
+ for (const field of endpoint.fields ?? []) {
1940
+ const isDate = (endpoint.dateFields ?? []).includes(field);
1941
+ const isSecondDate = (endpoint.secondDateFields ?? []).includes(field);
1942
+ const required = (endpoint.requiredFields ?? []).includes(field);
1943
+ properties[field] = isDate ? { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$", description: `${field}\uFF08yyyy-MM-dd HH:mm\uFF0C\u4E0D\u5E26\u79D2\uFF09` } : isSecondDate ? { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$", description: `${field}\uFF08yyyy-MM-dd HH:mm:ss\uFF0C\u5E26\u79D2\uFF09` } : { type: "string", description: `${field}${required ? "\uFF08\u5FC5\u586B\uFF09" : ""}` };
1944
+ }
1945
+ for (const spec of endpoint.details ?? []) {
1946
+ const requiredFields = spec.requiredFields ?? [];
1947
+ properties[spec.node] = {
1948
+ type: "array",
1949
+ description: `${spec.purpose ?? `${spec.node} \u660E\u7EC6`}\uFF1B\u6BCF\u6761\u5B57\u6BB5\uFF1A${spec.fields.join(", ")}${requiredFields.length > 0 ? `\uFF1B\u6BCF\u6761\u5FC5\u586B\uFF1A${requiredFields.join(", ")}` : ""}${(spec.minRows ?? 0) > 0 ? `\uFF1B\u6700\u5C11 ${spec.minRows} \u6761` : ""}`,
1950
+ items: {
1951
+ type: "object",
1952
+ additionalProperties: false,
1953
+ properties: Object.fromEntries(
1954
+ spec.fields.map((field) => [
1955
+ field,
1956
+ (spec.dateFields ?? []).includes(field) ? { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$", description: `${field}\uFF08yyyy-MM-dd HH:mm\uFF09` } : (spec.secondDateFields ?? []).includes(field) ? { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$", description: `${field}\uFF08yyyy-MM-dd HH:mm:ss\uFF0C\u5E26\u79D2\uFF09` } : { type: "string", description: `${field}${requiredFields.includes(field) ? "\uFF08\u5FC5\u586B\uFF09" : ""}` }
1957
+ ])
1958
+ ),
1959
+ required: requiredFields
1960
+ }
1961
+ };
1962
+ }
1963
+ if (endpoint.detailCover) {
1964
+ properties.detail1Mode = {
1965
+ type: "string",
1966
+ enum: ["append", "cover"],
1967
+ description: "\u660E\u7EC6\u5199\u5165\u6A21\u5F0F\uFF1Aappend=\u8FFD\u52A0\uFF08\u9ED8\u8BA4\uFF0C\u8001\u660E\u7EC6\u4FDD\u7559\uFF09\uFF0Fcover=\u8986\u76D6\uFF08\u6574\u7EC4\u66FF\u6362\uFF0C\u4F20\u51E0\u884C\u5C31\u53EA\u5269\u51E0\u884C\uFF09"
1968
+ };
1969
+ }
1970
+ }
1971
+ const requiredBase = endpoint.kind === "delete" ? endpoint.batchDeleteFields ?? ["id"] : [
1972
+ ...endpoint.requiredFields ?? [],
1973
+ ...(endpoint.details ?? []).filter((spec) => (spec.minRows ?? 0) > 0).map((spec) => spec.node)
1974
+ ];
1975
+ return {
1976
+ type: "object",
1977
+ additionalProperties: false,
1978
+ properties,
1979
+ // apply(includeConfirm=true)只要求确认票据:业务字段已在 prepare 时写入 continuation 快照,
1980
+ // 由 apply 从快照取用(properties 仍保留业务字段,允许调用方冗余传入)。
1981
+ required: includeConfirm ? ["confirm", "continuation"] : requiredBase
1982
+ };
1983
+ }
1984
+ async function lookupEmployeeDepartmentId(env, userId) {
1985
+ try {
1986
+ const { hrmEmployeeOperations } = await import("./employee-SAK2QYXX.js");
1987
+ const batch = hrmEmployeeOperations.find((operation) => operation.name === "hrm.employee.batch");
1988
+ if (!batch) return null;
1989
+ const result = await batch.handler({ ids: [userId] }, env);
1990
+ const row = (result?.data?.rows ?? [])[0];
1991
+ const deptId = String(row?.departmentId ?? "").trim();
1992
+ return deptId || null;
1993
+ } catch {
1994
+ return null;
1995
+ }
1996
+ }
1997
+ function buildWriteOperations(endpoint, preflight, afterWrite) {
1998
+ const prepareName = `${endpoint.operation}.prepare`;
1999
+ const applyName = `${endpoint.operation}.apply`;
2000
+ const writeOp = EB_WRITE_OP[endpoint.kind];
2001
+ const path = `${EB_BASE}/${writeOp}/${endpoint.interfacePk}`;
2002
+ const capability = `eb.${endpoint.domain}`;
2003
+ const acceptBusiness = ebBusinessSuccess;
2004
+ const prepare = {
2005
+ name: prepareName,
2006
+ resource: "eb",
2007
+ method: prepareName,
2008
+ action: prepareName,
2009
+ summary: `\u51C6\u5907${endpoint.summary}\uFF08\u751F\u6210\u786E\u8BA4\u9884\u89C8\uFF0C\u4E0D\u5199\u5165\uFF09`,
2010
+ capability,
2011
+ risk: "read-before-write",
2012
+ requiresConfirmation: true,
2013
+ inputSchema: buildWriteInputSchema(endpoint, false),
2014
+ handler: async (args, env) => {
2015
+ const session = await env.host.getSession();
2016
+ const payload = normalizeEbWrite(endpoint, args, session.userId);
2017
+ if (endpoint.interfacePk === "create_mt_topic") {
2018
+ if (payload.mainTable.proposal_person === void 0) payload.mainTable.proposal_person = session.userId;
2019
+ if (payload.mainTable.proposal_dept === void 0) {
2020
+ const deptId = await lookupEmployeeDepartmentId(env, session.userId);
2021
+ if (deptId) payload.mainTable.proposal_dept = deptId;
2022
+ }
2023
+ }
2024
+ const extras = {};
2025
+ const warnings = preflight ? await preflight({ endpoint, args, payload, env, extras }) : [];
2026
+ if (endpoint.detailCover && Object.keys(payload.details).length > 0 && payload.operateType.detail1 !== "cover") {
2027
+ warnings.push(
2028
+ 'detail1 \u9ED8\u8BA4\u662F\u300C\u66F4\u65B0\u8FFD\u52A0\u300D\uFF1A\u672C\u6B21\u4F1A\u65B0\u589E\u660E\u7EC6\u884C\uFF0C**\u4E0D\u4F1A**\u8986\u76D6 sort_number \u76F8\u540C\u7684\u65E7\u884C\uFF08\u771F\u673A\u5B9E\u6D4B\uFF1A2 \u884C \u2192 \u4F20 1 \u884C \u2192 \u53D8 3 \u884C\uFF09\u3002\u8981\u6574\u7EC4\u66FF\u6362\u8BF7\u4F20 detail1Mode: "cover"'
2029
+ );
2030
+ }
2031
+ const token = await env.continuation.issue(
2032
+ {
2033
+ operation: applyName,
2034
+ baseUrl: session.baseUrl,
2035
+ profile: session.profile,
2036
+ userId: session.userId,
2037
+ payload,
2038
+ fingerprint: fingerprint(payload)
2039
+ },
2040
+ CONTINUATION_TTL_SECONDS * 1e3
2041
+ );
2042
+ return meetingSuccess(
2043
+ prepareName,
2044
+ {
2045
+ status: "AWAITING_CONFIRMATION",
2046
+ preview: {
2047
+ interfacePk: endpoint.interfacePk,
2048
+ kind: endpoint.kind,
2049
+ body: payload,
2050
+ path: pathWithPk(endpoint, path, payload),
2051
+ notes: endpoint.notes ?? []
2052
+ },
2053
+ ...Object.keys(extras).length > 0 ? { decisions: extras } : {},
2054
+ continuation: token,
2055
+ expiresInSeconds: CONTINUATION_TTL_SECONDS
2056
+ },
2057
+ warnings.length > 0 ? { warnings } : {}
2058
+ );
2059
+ }
2060
+ };
2061
+ const apply = {
2062
+ name: applyName,
2063
+ resource: "eb",
2064
+ method: applyName,
2065
+ action: applyName,
2066
+ summary: `\u63D0\u4EA4${endpoint.summary}\uFF08${writeOp}\uFF0Cbody \u7528 datas \u6570\u7EC4\uFF09\uFF1B\u5FC5\u987B\u5728\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u8C03\u7528`,
2067
+ capability,
2068
+ risk: "high-risk-write",
2069
+ requiresConfirmation: true,
2070
+ inputSchema: buildWriteInputSchema(endpoint, true),
2071
+ handler: async (args, env) => {
2072
+ requireConfirm(args, applyName);
2073
+ const lease = await verifyLease(args, applyName, env);
2074
+ const session = await env.host.getSession();
2075
+ const payload = lease.payload;
2076
+ if (lease.fingerprint !== fingerprint(payload)) {
2077
+ throw meetingValidationError(
2078
+ "target_changed",
2079
+ "\u63D0\u4EA4\u5185\u5BB9\u4E0E prepare \u65F6\u7684\u5FEB\u7167\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare",
2080
+ { expected: lease.payload, actual: payload }
2081
+ );
2082
+ }
2083
+ const pkQuery = writePkQuery(endpoint, payload);
2084
+ let response;
2085
+ try {
2086
+ response = await env.host.request({
2087
+ method: "POST",
2088
+ path,
2089
+ operation: applyName,
2090
+ ...pkQuery ? { query: pkQuery } : {},
2091
+ body: writeBody(session.userId, payload),
2092
+ acceptBusiness
2093
+ });
2094
+ } catch (error) {
2095
+ if (isNetworkError(error)) {
2096
+ const written = endpoint.kind === "delete" ? "\u5220\u9664" : "\u5199\u5165";
2097
+ throw meetingPartialError(
2098
+ `${endpoint.interfacePk} ${written}\u8BF7\u6C42\u53D1\u9001\u540E\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u662F\u5426\u5DF2\u751F\u6548\u4E0D\u786E\u5B9A\uFF0C\u7981\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u56DE\u67E5\u786E\u8BA4\u540E\u518D\u51B3\u5B9A`,
2099
+ { attempted: { interfacePk: endpoint.interfacePk, body: payload } },
2100
+ { stage: endpoint.operation }
2101
+ );
2102
+ }
2103
+ throw error;
2104
+ }
2105
+ const dj = response?.datajson ?? {};
2106
+ if (dj.status === false) {
2107
+ throw meetingValidationError(
2108
+ "eb_write_not_applied",
2109
+ `${endpoint.interfacePk} \u8FD4\u56DE status=false\uFF0C\u670D\u52A1\u7AEF\u672A\u751F\u6548\uFF0C\u8BF7\u6838\u5BF9\u5B57\u6BB5\u4E0E\u6743\u9650\u540E\u91CD\u8BD5`
2110
+ );
2111
+ }
2112
+ const rawIds = dj.dataIds ?? dj.ids;
2113
+ const dataIds = (Array.isArray(rawIds) ? rawIds : []).map((item) => String(item));
2114
+ const association = afterWrite ? await afterWrite({ endpoint, payload, dataIds, env }) : void 0;
2115
+ return meetingSuccess(applyName, {
2116
+ status: "COMPLETE",
2117
+ interfacePk: endpoint.interfacePk,
2118
+ dataIds: rawIds ?? void 0,
2119
+ ...association ? { association } : {},
2120
+ result: response
2121
+ });
2122
+ }
2123
+ };
2124
+ return [prepare, apply];
2125
+ }
2126
+ function buildEbOperations(endpoints, options = {}) {
2127
+ return endpoints.flatMap((endpoint) => isWriteKind(endpoint.kind) ? buildWriteOperations(endpoint, options.preflight, options.afterWrite) : [buildReadOperation(endpoint)]);
2128
+ }
2129
+
2130
+ // src/shortcuts/meeting/operations/env.ts
2131
+ import { existsSync } from "node:fs";
2132
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2133
+ import { homedir } from "node:os";
2134
+ import { resolve } from "node:path";
2135
+ var EB_SMOKE_PATH = "/api/ebuilder/form/formdata/v2/getFormDataList/query_meeting_baseset";
2136
+ var STD_CALENDAR_PATH = "/api/meeting/detail/getCalendarBaseData";
2137
+ function stateRoot(ctx) {
2138
+ const configured = ctx?.config?.path();
2139
+ if (configured) return resolve(configured, "..");
2140
+ return process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve(homedir(), ".weaver-work-cli");
2141
+ }
2142
+ function meetingStateDir(ctx) {
2143
+ return resolve(stateRoot(ctx), "meeting");
2144
+ }
2145
+ function cacheFile(ctx) {
2146
+ return resolve(stateRoot(ctx), "meeting", "env-mode.json");
2147
+ }
2148
+ function emptyCache() {
2149
+ return { schemaVersion: 1, environments: {} };
2150
+ }
2151
+ async function readCache(ctx) {
2152
+ const file = cacheFile(ctx);
2153
+ if (!existsSync(file)) return emptyCache();
2154
+ try {
2155
+ const parsed = JSON.parse(await readFile(file, "utf8"));
2156
+ if (!parsed || typeof parsed !== "object" || !parsed.environments) return emptyCache();
2157
+ return parsed;
2158
+ } catch {
2159
+ return emptyCache();
2160
+ }
2161
+ }
2162
+ async function writeCache(ctx, baseUrl, mode, smokePath) {
2163
+ try {
2164
+ const file = cacheFile(ctx);
2165
+ await mkdir(resolve(file, ".."), { recursive: true });
2166
+ const cache = await readCache(ctx);
2167
+ cache.environments[baseUrl] = { mode, smokePath, detectedAt: (/* @__PURE__ */ new Date()).toISOString() };
2168
+ await writeFile(file, JSON.stringify(cache, null, 2), "utf8");
2169
+ return void 0;
2170
+ } catch (error) {
2171
+ return `\u73AF\u5883\u6A21\u5F0F\u7F13\u5B58\u5199\u5165\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u672C\u6B21\u7ED3\u679C\uFF0C\u4E0B\u6B21\u4F1A\u91CD\u65B0\u5192\u70DF\uFF09\uFF1A${error instanceof Error ? error.message : String(error)}`;
2172
+ }
2173
+ }
2174
+ async function resolveMeetingEnvMode(host, ctx, options = {}) {
2175
+ const session = await host.getSession();
2176
+ if (options.refresh !== true) {
2177
+ const cache = await readCache(ctx);
2178
+ const cached = cache.environments[session.baseUrl];
2179
+ if (cached && (cached.mode === "eb" || cached.mode === "standard")) {
2180
+ return {
2181
+ mode: cached.mode,
2182
+ smokePath: cached.smokePath,
2183
+ fromCache: true,
2184
+ detectedAt: cached.detectedAt
2185
+ };
2186
+ }
2187
+ }
2188
+ let ebError;
2189
+ try {
2190
+ await host.request({
2191
+ method: "POST",
2192
+ path: EB_SMOKE_PATH,
2193
+ operation: "meeting.env.detect",
2194
+ // EB list 的 datajson 内必须出现 mainTable 节点(空对象即可):缺失时服务端报
2195
+ // “mainTable解析异常,请参照文档修正数据格式”,冒烟会**假失败**并把 EB 环境误判为
2196
+ // 标准版(2026-09-20 真机复现)。
2197
+ body: { datajson: { mainTable: {}, header: { operator: session.userId } } },
2198
+ // EB 响应不含 code/status(形如 {datajson:{datas:[...]}}),默认的 isBusinessSuccess
2199
+ // 会判为 false → 冒烟假失败 → EB 环境被误判为标准版。
2200
+ acceptBusiness: ebBusinessSuccess
2201
+ });
2202
+ const warning = await writeCache(ctx, session.baseUrl, "eb", EB_SMOKE_PATH);
2203
+ return { mode: "eb", smokePath: EB_SMOKE_PATH, fromCache: false, warning };
2204
+ } catch (error) {
2205
+ ebError = error;
2206
+ }
2207
+ try {
2208
+ await host.request({
2209
+ method: "GET",
2210
+ path: STD_CALENDAR_PATH,
2211
+ operation: "meeting.env.detect"
2212
+ });
2213
+ const ebDetail = ebError instanceof Error ? `${ebError.type ?? "api"}/${ebError.subtype ?? "error"}: ${ebError.message}` : String(ebError);
2214
+ const warning = await writeCache(ctx, session.baseUrl, "standard", STD_CALENDAR_PATH);
2215
+ return {
2216
+ mode: "standard",
2217
+ smokePath: STD_CALENDAR_PATH,
2218
+ fromCache: false,
2219
+ ebSmokeFailed: true,
2220
+ ebSmokeError: ebDetail,
2221
+ warning
2222
+ };
2223
+ } catch (stdError) {
2224
+ throw meetingValidationError(
2225
+ "env_unavailable",
2226
+ "\u5F53\u524D\u73AF\u5883 EB \u7248\u4E0E\u6807\u51C6\u7248\u4F1A\u8BAE\u63A5\u53E3\u5192\u70DF\u5747\u672A\u901A\u8FC7\uFF0C\u8BF7\u786E\u8BA4\u4F1A\u8BAE\u5E94\u7528\u5DF2\u5B89\u88C5\u4E14\u63A5\u53E3\u5DF2\u914D\u7F6E\u5B8C\u6574",
2227
+ {
2228
+ eb: ebError instanceof Error ? ebError.message : String(ebError),
2229
+ standard: stdError instanceof Error ? stdError.message : String(stdError)
2230
+ }
2231
+ );
2232
+ }
2233
+ }
2234
+ var meetingEnvDetect = {
2235
+ name: "meeting.env.detect",
2236
+ resource: "env",
2237
+ method: "detect",
2238
+ action: "meeting.env.detect",
2239
+ summary: "\u63A2\u6D4B\u5F53\u524D\u73AF\u5883\u4F1A\u8BAE\u6A21\u5F0F\uFF1A\u9ED8\u8BA4\u6309 baseUrl \u8BFB\u7F13\u5B58\uFF1B\u672A\u547D\u4E2D\u6216 refresh=true \u65F6 EB \u7248\u5192\u70DF\u4F18\u5148\u3001\u5931\u8D25\u56DE\u9000\u6807\u51C6\u7248\uFF0C\u6210\u529F\u540E\u56FA\u5316\u7F13\u5B58",
2240
+ capability: "env",
2241
+ risk: "read",
2242
+ inputSchema: {
2243
+ type: "object",
2244
+ additionalProperties: false,
2245
+ properties: {
2246
+ refresh: { type: "boolean", description: 'true=\u5FFD\u7565\u7F13\u5B58\u5F3A\u5236\u91CD\u65B0\u5192\u70DF\u5E76\u66F4\u65B0\u7F13\u5B58\uFF08\u7528\u6237\u8BF4"\u91CD\u65B0\u63A2\u6D4B/\u5237\u65B0\u6A21\u5F0F"\u65F6\u4F7F\u7528\uFF09' },
2247
+ profileId: SCHEMA_ID
2248
+ }
2249
+ },
2250
+ handler: async (args, { host, ctx }) => {
2251
+ const result = await resolveMeetingEnvMode(host, ctx, { refresh: args.refresh === true });
2252
+ const { warning, ...data } = result;
2253
+ return meetingSuccess(
2254
+ "meeting.env.detect",
2255
+ data,
2256
+ warning ? { warnings: [warning] } : void 0
2257
+ );
2258
+ }
2259
+ };
2260
+ var meetingCalendarBase = {
2261
+ name: "meeting.calendar.base",
2262
+ resource: "env",
2263
+ method: "calendar.base",
2264
+ action: "meeting.calendar.base",
2265
+ summary: "\u67E5\u8BE2\u65E5\u5386/\u5EFA\u4F1A\u57FA\u7840\u4FE1\u606F\uFF08getCalendarBaseData\uFF09\uFF1AonlyFlowCreate / workFlowBaseIds / repeatWorkFlowBaseIds / existWorkFlow",
2266
+ capability: "env",
2267
+ risk: "read",
2268
+ inputSchema: { type: "object", additionalProperties: false, properties: {} },
2269
+ handler: async (_args, { host }) => {
2270
+ const response = await host.request({
2271
+ method: "GET",
2272
+ path: STD_CALENDAR_PATH,
2273
+ operation: "meeting.calendar.base"
2274
+ });
2275
+ const createBaseData = response?.data?.createBaseData ?? response?.createBaseData ?? null;
2276
+ return meetingSuccess("meeting.calendar.base", { createBaseData, raw: response });
2277
+ }
2278
+ };
2279
+ var meetingDetailField = {
2280
+ name: "meeting.detail.field",
2281
+ resource: "meeting",
2282
+ method: "detail.field",
2283
+ action: "meeting.detail.field",
2284
+ summary: "\u67E5\u8BE2\u4F1A\u8BAE\u8BE6\u60C5\u8868\u5355\u7ED3\u6784\u4E0E options\uFF08getMeetingDetailField\uFF09\uFF1Aid / operateType / fromWorkflow / isReadOnly",
2285
+ capability: "meeting",
2286
+ risk: "read",
2287
+ inputSchema: {
2288
+ type: "object",
2289
+ additionalProperties: false,
2290
+ properties: {
2291
+ id: SCHEMA_ID,
2292
+ operateType: { type: "string", description: "\u64CD\u4F5C\u7C7B\u578B\uFF0C\u5982 SUBMIT/UPDATE/CHANGE" },
2293
+ fromWorkflow: { type: "integer", enum: [0, 1] },
2294
+ isReadOnly: { type: "integer", enum: [0, 1] }
2295
+ },
2296
+ required: ["id"]
2297
+ },
2298
+ handler: async (args, { host }) => {
2299
+ const query = { id: String(args.id) };
2300
+ if (args.operateType !== void 0) query.operateType = args.operateType;
2301
+ if (args.fromWorkflow !== void 0) query.fromWorkflow = args.fromWorkflow;
2302
+ if (args.isReadOnly !== void 0) query.isReadOnly = args.isReadOnly;
2303
+ const response = await host.request({
2304
+ method: "GET",
2305
+ path: "/api/meeting/detail/getMeetingDetailField",
2306
+ operation: "meeting.detail.field",
2307
+ query
2308
+ });
2309
+ return meetingSuccess("meeting.detail.field", { data: response?.data ?? response });
2310
+ }
2311
+ };
2312
+ var meetingEnvOperations = [
2313
+ meetingEnvDetect,
2314
+ meetingCalendarBase,
2315
+ meetingDetailField
2316
+ ];
2317
+
2318
+ export {
2319
+ MeetingCliError,
2320
+ meetingValidationError,
2321
+ meetingAuthError,
2322
+ meetingNetworkError,
2323
+ meetingConfirmationError,
2324
+ meetingPartialError,
2325
+ meetingConflictError,
2326
+ meetingSuccess,
2327
+ schemaOf,
2328
+ SCHEMA_ID,
2329
+ SCHEMA_ID_LIST,
2330
+ SCHEMA_DATETIME_MINUTE,
2331
+ SCHEMA_DATE,
2332
+ asObject,
2333
+ assertNoForbiddenKeys,
2334
+ assertDateTimeMinute,
2335
+ assertDate,
2336
+ toIdString,
2337
+ pickBusinessInput,
2338
+ mergeSnapshot,
2339
+ toIdCsv,
2340
+ extractRows,
2341
+ extractConflict,
2342
+ assertMeetingExists,
2343
+ EB_ENDPOINTS,
2344
+ EB_BASE,
2345
+ ebBusinessSuccess,
2346
+ fingerprint,
2347
+ requireConfirm,
2348
+ verifyLease,
2349
+ queryBody,
2350
+ writeBody,
2351
+ extractEbRows,
2352
+ normalizeEbWrite,
2353
+ buildEbOperations,
2354
+ meetingStateDir,
2355
+ resolveMeetingEnvMode,
2356
+ meetingEnvOperations
2357
+ };