weaver-work-cli 0.1.36 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/chunks/{archive-XBVH7JU7.js → archive-ENZYBBME.js} +559 -68
- package/dist/chunks/{archive-oa-MZM3EKFQ.js → archive-oa-YWLEC5V4.js} +4 -3
- package/dist/chunks/{asset-4XO7UOUW.js → asset-OOV6DWPA.js} +8 -7
- package/dist/chunks/asset-idle-RE632MY5.js +670 -0
- package/dist/chunks/{attachment-content-VXSWANAC.js → attachment-content-RWN2FCLL.js} +3 -3
- package/dist/chunks/{blog-PGZKOPSC.js → blog-PEPOJAL7.js} +5 -4
- package/dist/chunks/{caizhilian-BH4ZVGUN.js → caizhilian-WYIQDVPJ.js} +5 -4
- package/dist/chunks/{calendar-MXEMTIO4.js → calendar-CIARBAOX.js} +4 -3
- package/dist/chunks/{chunk-NCOVUAZK.js → chunk-36DIFZAH.js} +4 -3
- package/dist/chunks/{chunk-I6QGIBDM.js → chunk-BJGXMFGD.js} +4 -3
- package/dist/chunks/{chunk-TC6MZAO3.js → chunk-CQHGNCK2.js} +52 -2
- package/dist/chunks/{chunk-WXFPWCXG.js → chunk-EINRJHQ3.js} +3 -3
- package/dist/chunks/{chunk-JUXVYKII.js → chunk-EZGFHJFW.js} +201 -19
- package/dist/chunks/{chunk-VPUTVEMC.js → chunk-F2EQXUEE.js} +436 -290
- package/dist/chunks/{chunk-JYKABYCV.js → chunk-GVPJZXJ2.js} +3 -3
- package/dist/chunks/{chunk-6LLJFKJE.js → chunk-HJYVHXUQ.js} +1 -1
- package/dist/chunks/{chunk-T72N74ZT.js → chunk-I2HB737U.js} +5 -4
- package/dist/chunks/{chunk-VPXOPQJI.js → chunk-K3RUEEOL.js} +4 -2
- package/dist/chunks/{chunk-HXJQI5NM.js → chunk-KTCB5R5H.js} +3 -2
- package/dist/chunks/{chunk-XMGSYD6S.js → chunk-L4N7B7ZD.js} +4 -4
- package/dist/chunks/{chunk-QYGO5EE2.js → chunk-MUQUHKPG.js} +4 -3
- package/dist/chunks/{chunk-QHFANTX7.js → chunk-NLK2RZKG.js} +1348 -90
- package/dist/chunks/{chunk-F746NKNF.js → chunk-P2DAISYW.js} +1 -1
- package/dist/chunks/{chunk-BPE37FPB.js → chunk-T7JDJJ7H.js} +3 -3
- package/dist/chunks/{chunk-JNG42JKG.js → chunk-XXJOSZTQ.js} +6 -6
- package/dist/chunks/{chunk-5DQEEGCC.js → chunk-YS5DPN4T.js} +1 -1
- package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
- package/dist/chunks/{chunk-JCSN3JGM.js → chunk-ZXRNHZTE.js} +7 -6
- package/dist/chunks/{conflict-JAB2LJEZ.js → conflict-DRMDOL56.js} +2 -2
- package/dist/chunks/{contract-XI2EEIZU.js → contract-73MERZWN.js} +4 -3
- package/dist/chunks/{cowork-SCPGLBA4.js → cowork-HNGBPD7A.js} +4 -3
- package/dist/chunks/{ebuilder-form-EYLHNOTA.js → ebuilder-form-OY6DVNRK.js} +3 -3
- package/dist/chunks/{ehr-EAP77IMT.js → ehr-RAQNEQO7.js} +4 -3
- package/dist/chunks/{esb-2TGGXEE7.js → esb-6XV7C7YV.js} +4 -4
- package/dist/chunks/{fna-2X7ZE7BU.js → fna-XTSRB7G7.js} +4 -3
- package/dist/chunks/{host-Q4LZGCRU.js → host-3F5UM5GN.js} +3 -3
- package/dist/chunks/{host-XCLDDXKQ.js → host-A7J6GDUP.js} +3 -3
- package/dist/chunks/{host-I4NRK4MX.js → host-VGPVP7YF.js} +3 -3
- package/dist/chunks/{host-C6EL2RKL.js → host-YAQAPYNP.js} +3 -3
- package/dist/chunks/{host-UEI5FGDM.js → host-YMBXWFWX.js} +3 -3
- package/dist/chunks/{hrm-YXERJM76.js → hrm-TLHKC545.js} +3 -3
- package/dist/chunks/{im-A4VZN2TQ.js → im-YOUCFMUK.js} +3 -3
- package/dist/chunks/{invoice-2Z6YPMIS.js → invoice-WNBS2B4C.js} +3 -3
- package/dist/chunks/{jiuchuanhui-AR5GMKZB.js → jiuchuanhui-XABWS5RN.js} +4 -3
- package/dist/chunks/{lazy-dispatch-QXW7P4X3.js → lazy-dispatch-NLZ5UQQI.js} +5 -5
- package/dist/chunks/{mail-7GZ6CPBJ.js → mail-LRYMBFNL.js} +4 -3
- package/dist/chunks/{meeting-3NMGA3MB.js → meeting-ESXL6MFI.js} +13 -12
- package/dist/chunks/{okr-BZ6XUOAG.js → okr-EOV65SSF.js} +4 -3
- package/dist/chunks/{plan-DR5CMUYP.js → plan-YFPVKW6Y.js} +4 -3
- package/dist/chunks/{project-6J63MK33.js → project-MDVZUYQW.js} +4 -3
- package/dist/chunks/{registry-VRTNC6UR.js → registry-QCLZEDAP.js} +8 -8
- package/dist/chunks/{registry-KDD7DHNK.js → registry-VT5Y2HLA.js} +4 -4
- package/dist/chunks/{registry-TKX2E7C7.js → registry-YX4CSEMD.js} +3 -3
- package/dist/chunks/{room-recommend-XCWRMB5P.js → room-recommend-L3MWH4JW.js} +4 -4
- package/dist/chunks/{schedule-IVBICP32.js → schedule-UASAVDVD.js} +4 -4
- package/dist/chunks/{workflow-D74NFK3C.js → workflow-KDGIUCNW.js} +9 -6
- package/dist/core/output.js +16 -6
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/messages.js +1 -0
- package/dist/internal/e10/auth-recovery.js +127 -7
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/context.js +16 -3
- package/dist/internal/e10/request-runtime.js +106 -8
- package/dist/shortcuts/archive/host.js +5 -2
- package/dist/shortcuts/archive/manifest.js +1 -1
- package/dist/shortcuts/archive/operations/borrow-list.js +13 -1
- package/dist/shortcuts/archive/operations/flow-url.js +1 -1
- package/dist/shortcuts/archive/operations/prelib.js +472 -0
- package/dist/shortcuts/archive/operations/registry.js +2 -0
- package/dist/shortcuts/archive/operations/upload.js +1 -1
- package/dist/shortcuts/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- package/dist/shortcuts/asset-idle/errors.js +44 -0
- package/dist/shortcuts/asset-idle/host.js +161 -0
- package/dist/shortcuts/asset-idle/index.js +114 -0
- package/dist/shortcuts/asset-idle/manifest.js +159 -0
- package/dist/shortcuts/asset-idle/operations/idle.js +47 -0
- package/dist/shortcuts/asset-idle/operations/registry.js +33 -0
- package/dist/shortcuts/asset-idle/operations/shared.js +142 -0
- package/dist/shortcuts/asset-idle/operations/types.js +9 -0
- package/dist/shortcuts/asset-idle/operations.js +15 -0
- package/dist/shortcuts/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +2 -1
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +2 -1
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1073 -50
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +60 -1
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/invitation.js +122 -9
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/host.js +3 -0
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/form.js +44 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +77 -26
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +6 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +59 -117
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +44 -7
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +37 -29
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +20 -6
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +22 -18
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +34 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +9 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +110 -20
- package/docs/_catalog.md +3 -0
- package/docs/asset-idle.md +45 -0
- package/docs/e10-auth.md +1 -1
- package/docs/todo-smart-convert/subgroup-rules.md +1 -1
- package/package.json +1 -1
- package/scripts/package-skill.mjs +2 -0
- package/skill-template/business-info.json +14 -1
- package/skill-template/domains/asset-idle.md +13 -0
- package/skill-template/domains/wenshuding.md +3 -0
- package/skills/weaver-e10-archive-oa/SKILL.md +1 -0
- package/skills/weaver-e10-archive-oa/references/my-borrow.md +49 -0
- package/skills/weaver-e10-asset-idle/SKILL.md +73 -0
- package/skills/weaver-e10-asset-idle/references/idle-list.md +62 -0
- package/skills/weaver-e10-asset-idle/references/idle-stats-and-charts.md +65 -0
- package/skills/weaver-e10-asset-idle/references/source-manifest.json +193 -0
- package/skills/weaver-e10-asset-idle/references/widget-style.md +205 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +29 -11
- package/skills/weaver-e10-caizhilian/references/auth-and-install.md +12 -0
- package/skills/weaver-e10-caizhilian/references/files.md +1 -1
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +1 -1
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +45 -45
- package/skills/weaver-e10-cowork/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +1 -1
- package/skills/weaver-e10-mail/SKILL.md +3 -0
- package/skills/weaver-e10-meeting/SKILL.md +250 -301
- package/skills/weaver-e10-meeting/references/meeting-eb.md +203 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +37 -5
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-shared/SKILL.md +5 -5
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +3 -3
- package/skills/weaver-e10-wenshuding/SKILL.md +29 -6
- package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +14 -0
- package/skills/weaver-e10-wenshuding/references/archive-download.md +2 -0
- package/skills/weaver-e10-wenshuding/references/archive-flow.md +1 -1
- package/skills/weaver-e10-wenshuding/references/archive-prelib-arrange.md +76 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-list.md +107 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-open.md +59 -0
- package/skills/weaver-e10-wenshuding/references/archive-upload.md +4 -1
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +108 -65
- package/skills/weaver-e10-workflow/SKILL.md +5 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +154 -19
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +59 -27
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +113 -25
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +292 -42
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
|
@@ -5,26 +5,27 @@ import {
|
|
|
5
5
|
loadRooms,
|
|
6
6
|
recommendRooms,
|
|
7
7
|
rememberFrequentRoom
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-T7JDJJ7H.js";
|
|
9
9
|
import {
|
|
10
10
|
meetingEbScheduleOperations
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-L4N7B7ZD.js";
|
|
12
12
|
import {
|
|
13
13
|
ebMeetingWritePreflight,
|
|
14
14
|
fetchEbAppSettings,
|
|
15
15
|
findCommonFreeSlots,
|
|
16
16
|
meetingEbConflictOperations
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-EINRJHQ3.js";
|
|
18
18
|
import {
|
|
19
|
+
PENDING_MARK,
|
|
19
20
|
listMeetingAttachments,
|
|
20
21
|
meetingAttachmentContentOperations,
|
|
21
22
|
renderDocx
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-KTCB5R5H.js";
|
|
23
24
|
import {
|
|
24
25
|
meetingEnvOperations,
|
|
25
26
|
meetingStateDir,
|
|
26
27
|
resolveMeetingEnvMode
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-YS5DPN4T.js";
|
|
28
29
|
import {
|
|
29
30
|
EB_BASE,
|
|
30
31
|
EB_ENDPOINTS,
|
|
@@ -56,7 +57,7 @@ import {
|
|
|
56
57
|
toIdString,
|
|
57
58
|
verifyLease,
|
|
58
59
|
writeBody
|
|
59
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-CQHGNCK2.js";
|
|
60
61
|
|
|
61
62
|
// src/shortcuts/meeting/operations/meetings.ts
|
|
62
63
|
function overlapsDate(beginDatetime, endDatetime, date) {
|
|
@@ -2222,7 +2223,7 @@ var meetingAttachmentAttach = {
|
|
|
2222
2223
|
if (mode === "append" && existingIds.length === 0) {
|
|
2223
2224
|
existingIds.push(...beforeIds);
|
|
2224
2225
|
}
|
|
2225
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
2226
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
2226
2227
|
const list = getMeetingOperation2("meeting.eb.meeting.list");
|
|
2227
2228
|
let fileId = incomingFileId;
|
|
2228
2229
|
let name = String(args.name ?? "").trim();
|
|
@@ -2310,7 +2311,7 @@ function textOf(value) {
|
|
|
2310
2311
|
return value === void 0 || value === null ? "" : String(value);
|
|
2311
2312
|
}
|
|
2312
2313
|
async function readMinute(env, id) {
|
|
2313
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
2314
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
2314
2315
|
const detail = getMeetingOperation2("meeting.eb.minute.detail");
|
|
2315
2316
|
const result = await detail.handler({ id }, env);
|
|
2316
2317
|
const row = result?.data?.data;
|
|
@@ -2389,7 +2390,7 @@ var meetingMinuteWriteContent = {
|
|
|
2389
2390
|
} else {
|
|
2390
2391
|
statusReason = "\u4EC5\u6E05\u7A7A\u5185\u5BB9\uFF0C\u672A\u6539\u72B6\u6001";
|
|
2391
2392
|
}
|
|
2392
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
2393
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
2393
2394
|
const prepare = getMeetingOperation2("meeting.eb.minute.update.prepare");
|
|
2394
2395
|
const apply = getMeetingOperation2("meeting.eb.minute.update.apply");
|
|
2395
2396
|
const prepared = await prepare.handler({ id, mt_id: mtId, ...patch }, env);
|
|
@@ -2747,7 +2748,7 @@ var meetingMinuteFromGroupChat = {
|
|
|
2747
2748
|
const mtId = textOf2(args.mt_id).trim();
|
|
2748
2749
|
if (!mtId) throw meetingValidationError("mt_id_required", "\u5FC5\u987B\u63D0\u4F9B\u4F1A\u8BAE id\uFF08mt_id\uFF09");
|
|
2749
2750
|
const pipeline = ["text", "minutes", "document"].includes(args.pipeline) ? args.pipeline : "text";
|
|
2750
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
2751
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
2751
2752
|
const ctx = env.ctx;
|
|
2752
2753
|
let stepStart = Date.now();
|
|
2753
2754
|
const listed = await getMeetingOperation2("meeting.eb.meeting.list").handler(
|
|
@@ -2771,7 +2772,7 @@ var meetingMinuteFromGroupChat = {
|
|
|
2771
2772
|
}
|
|
2772
2773
|
mark("readMeeting", stepStart);
|
|
2773
2774
|
const pullStart = Date.now();
|
|
2774
|
-
const { createImHost } = await import("./host-
|
|
2775
|
+
const { createImHost } = await import("./host-3F5UM5GN.js");
|
|
2775
2776
|
const { createImContinuationSigner } = await import("./continuation-2CKSBLA6.js");
|
|
2776
2777
|
const { getImOperation } = await import("./registry-OZSMDVPP.js");
|
|
2777
2778
|
const imEnv = { ctx, host: createImHost(ctx), continuation: createImContinuationSigner(ctx) };
|
|
@@ -2841,7 +2842,7 @@ var meetingMinuteFromGroupChat = {
|
|
|
2841
2842
|
try {
|
|
2842
2843
|
const { readFile: readFile5 } = await import("node:fs/promises");
|
|
2843
2844
|
const buffer = await readFile5(file);
|
|
2844
|
-
const { extractText } = await import("./attachment-content-
|
|
2845
|
+
const { extractText } = await import("./attachment-content-RWN2FCLL.js");
|
|
2845
2846
|
const extracted = extractText(buffer, file, "");
|
|
2846
2847
|
if (extracted.text.trim()) {
|
|
2847
2848
|
extraSections.push(`\u3010\u6750\u6599\uFF1A${file.split(/[\\/]/).pop() ?? file}\u3011
|
|
@@ -2968,9 +2969,9 @@ ${groupTranscript}` : ""
|
|
|
2968
2969
|
if (!employeeId) {
|
|
2969
2970
|
warnings.push("\u672A\u53D6\u5230 ESB \u89E6\u53D1\u4EBA id\uFF08employeeId\uFF09\uFF0C\u5DF2\u8DF3\u8FC7\u540E\u7EED ESB \u8C03\u7528");
|
|
2970
2971
|
} else {
|
|
2971
|
-
const { createEsbHost } = await import("./host-
|
|
2972
|
+
const { createEsbHost } = await import("./host-VGPVP7YF.js");
|
|
2972
2973
|
const { createEsbContinuationSigner } = await import("./continuation-NLECEJPX.js");
|
|
2973
|
-
const { getEsbOperation } = await import("./registry-
|
|
2974
|
+
const { getEsbOperation } = await import("./registry-VT5Y2HLA.js");
|
|
2974
2975
|
const esbEnv = { ctx, host: createEsbHost(ctx), continuation: createEsbContinuationSigner(ctx) };
|
|
2975
2976
|
const prepareOp = getEsbOperation("esb.trigger.prepare");
|
|
2976
2977
|
const applyOp = getEsbOperation("esb.trigger.apply");
|
|
@@ -3154,7 +3155,7 @@ var meetingDecisionNotifyGroup = {
|
|
|
3154
3155
|
const warnings = [];
|
|
3155
3156
|
const mtId = textOf3(args.mt_id).trim();
|
|
3156
3157
|
if (!mtId) throw meetingValidationError("mt_id_required", "\u5FC5\u987B\u63D0\u4F9B\u4F1A\u8BAE id\uFF08mt_id\uFF09");
|
|
3157
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
3158
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
3158
3159
|
const ctx = env.ctx;
|
|
3159
3160
|
const listed = await getMeetingOperation2("meeting.eb.meeting.list").handler(
|
|
3160
3161
|
{ mt_id: mtId, pageNo: 1, pageSize: 1 },
|
|
@@ -3218,7 +3219,7 @@ var meetingDecisionNotifyGroup = {
|
|
|
3218
3219
|
charCount: formatted.text.length,
|
|
3219
3220
|
text: formatted.text
|
|
3220
3221
|
};
|
|
3221
|
-
const { createImHost } = await import("./host-
|
|
3222
|
+
const { createImHost } = await import("./host-3F5UM5GN.js");
|
|
3222
3223
|
const imHost = createImHost(ctx);
|
|
3223
3224
|
let displayText = formatted.text;
|
|
3224
3225
|
let wireText = formatted.text;
|
|
@@ -3456,7 +3457,7 @@ var meetingPipelineRun = {
|
|
|
3456
3457
|
const needsConfirm = level === "tasks" || level === "notify";
|
|
3457
3458
|
const confirmed = args.confirm === true;
|
|
3458
3459
|
const executedLevel = needsConfirm && !confirmed ? "document" : level;
|
|
3459
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
3460
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
3460
3461
|
const ctx = env.ctx;
|
|
3461
3462
|
let stepStart = Date.now();
|
|
3462
3463
|
const reuseMinuteId = textOf4(args.minuteId).trim();
|
|
@@ -3525,7 +3526,7 @@ var meetingPipelineRun = {
|
|
|
3525
3526
|
]);
|
|
3526
3527
|
}
|
|
3527
3528
|
stepStart = Date.now();
|
|
3528
|
-
const { createHrmHost } = await import("./host-
|
|
3529
|
+
const { createHrmHost } = await import("./host-A7J6GDUP.js");
|
|
3529
3530
|
const { getHrmOperation } = await import("./registry-NYPYMZXG.js");
|
|
3530
3531
|
const hrmEnv = { ctx, host: createHrmHost(ctx) };
|
|
3531
3532
|
const queryOp = getHrmOperation("hrm.employee.query");
|
|
@@ -3726,6 +3727,59 @@ import { existsSync as existsSync2 } from "node:fs";
|
|
|
3726
3727
|
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
3727
3728
|
import { dirname, join, resolve as resolve3 } from "node:path";
|
|
3728
3729
|
import { fileURLToPath } from "node:url";
|
|
3730
|
+
|
|
3731
|
+
// src/shortcuts/meeting/invitation/text.ts
|
|
3732
|
+
function cell(value) {
|
|
3733
|
+
return String(value ?? "").replace(/\|/g, "/").replace(/\s*\r?\n\s*/g, " ").trim();
|
|
3734
|
+
}
|
|
3735
|
+
function renderInvitationMarkdown(resolver, agendaRows, options = {}) {
|
|
3736
|
+
const pending = /* @__PURE__ */ new Set();
|
|
3737
|
+
const val = (key) => {
|
|
3738
|
+
const rendered = resolver(key);
|
|
3739
|
+
if (rendered.pending) {
|
|
3740
|
+
pending.add(key);
|
|
3741
|
+
return PENDING_MARK;
|
|
3742
|
+
}
|
|
3743
|
+
return String(rendered.text ?? "").trim();
|
|
3744
|
+
};
|
|
3745
|
+
const lines = [];
|
|
3746
|
+
lines.push("# \u9080\u8BF7\u51FD");
|
|
3747
|
+
lines.push("");
|
|
3748
|
+
lines.push(`**\u5C0A\u656C\u7684 ${val("guest_org")}\uFF1A**`);
|
|
3749
|
+
lines.push("");
|
|
3750
|
+
lines.push(`${val("caller")} \u8BDA\u9080\u60A8\u53C2\u52A0\u300C${val("mt_name")}\u300D\uFF0C\u73B0\u5C06\u4F1A\u8BAE\u5B89\u6392\u901A\u77E5\u5982\u4E0B\uFF1A`);
|
|
3751
|
+
lines.push("");
|
|
3752
|
+
lines.push(`- **\u4F1A\u8BAE\u540D\u79F0**\uFF1A${val("mt_name")}`);
|
|
3753
|
+
lines.push(`- **\u4F1A\u8BAE\u65F6\u95F4**\uFF1A${val("begin_datetime")}~${val("end_datetime")}`);
|
|
3754
|
+
lines.push(`- **\u4F1A\u8BAE\u5730\u70B9**\uFF1A${val("address")}`);
|
|
3755
|
+
lines.push(`- **\u53C2\u4F1A\u4EBA\u5458**\uFF1A${val("hrm_members")}`);
|
|
3756
|
+
lines.push(`- **\u4F1A\u8BAE\u5185\u5BB9**\uFF1A${val("mt_desc")}`);
|
|
3757
|
+
lines.push("");
|
|
3758
|
+
lines.push(`**${val("begin_date")}\u4F1A\u8BAE\u8BAE\u7A0B\u5B89\u6392\uFF1A**`);
|
|
3759
|
+
lines.push("");
|
|
3760
|
+
lines.push("| \u8BAE\u7A0B\u5B89\u6392 | \u8BAE\u7A0B\u5185\u5BB9 | \u8BAE\u7A0B\u65F6\u95F4 |");
|
|
3761
|
+
lines.push("| --- | --- | --- |");
|
|
3762
|
+
if (agendaRows.length === 0) {
|
|
3763
|
+
lines.push("| \u2014 | \u6682\u65E0\u8BAE\u7A0B | \u2014 |");
|
|
3764
|
+
} else {
|
|
3765
|
+
for (const [name, content, timeRange] of agendaRows) {
|
|
3766
|
+
lines.push(`| ${cell(name) || "\u2014"} | ${cell(content) || "\u2014"} | ${cell(timeRange) || "\u2014"} |`);
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
lines.push("");
|
|
3770
|
+
lines.push(val("company_name"));
|
|
3771
|
+
lines.push("");
|
|
3772
|
+
lines.push(val("issue_date"));
|
|
3773
|
+
lines.push("");
|
|
3774
|
+
lines.push("> \u6CE8\uFF1A\u4EE5\u4E0A\u4E3A\u62DF\u5B9A\u4F1A\u8BAE\u5B89\u6392\uFF0C\u5177\u4F53\u4F1A\u8BAE\u65F6\u95F4\u4E0E\u8BAE\u7A0B\u9700\u6839\u636E\u5B9E\u9645\u60C5\u51B5\u786E\u8BA4\u3002");
|
|
3775
|
+
if (options.pendingHint !== false && pending.size > 0) {
|
|
3776
|
+
lines.push("");
|
|
3777
|
+
lines.push(`> \u26A0\uFE0F \u6807 ${PENDING_MARK} \u7684\u5B57\u6BB5\u4F1A\u8BAE\u91CC\u6CA1\u6709\u503C\uFF0C\u9700\u8981\u4EBA\u5DE5\u8865\uFF1B\u8865\u5B8C\u53EF\u7528 mtId \u91CD\u65B0\u751F\u6210\u3002`);
|
|
3778
|
+
}
|
|
3779
|
+
return { markdown: lines.join("\n"), pendingFields: [...pending] };
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3782
|
+
// src/shortcuts/meeting/operations/invitation.ts
|
|
3729
3783
|
function templatePath() {
|
|
3730
3784
|
const override = process.env.WEAVER_MEETING_INVITATION_TEMPLATE;
|
|
3731
3785
|
if (override) return resolve3(override);
|
|
@@ -3775,7 +3829,7 @@ function formatTimeRange(start, end) {
|
|
|
3775
3829
|
}
|
|
3776
3830
|
async function loadAgendaFromTopics(env, mtId) {
|
|
3777
3831
|
try {
|
|
3778
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
3832
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
3779
3833
|
const operation = getMeetingOperation2("meeting.eb.topic.list");
|
|
3780
3834
|
const result = await operation.handler({ mt_id: mtId, pageNo: 1, pageSize: 200 }, env);
|
|
3781
3835
|
const rows = result.data?.rows ?? [];
|
|
@@ -3872,6 +3926,65 @@ async function resolveIssuerOrganization(env, creatorId) {
|
|
|
3872
3926
|
return null;
|
|
3873
3927
|
}
|
|
3874
3928
|
}
|
|
3929
|
+
async function resolveSessionUserName(env) {
|
|
3930
|
+
try {
|
|
3931
|
+
const session = await env.host.getSession();
|
|
3932
|
+
const userId = String(session?.userId ?? "").trim();
|
|
3933
|
+
if (!userId) return "";
|
|
3934
|
+
const { hrmEmployeeOperations } = await import("./employee-SAK2QYXX.js");
|
|
3935
|
+
const batch = hrmEmployeeOperations.find((operation) => operation.name === "hrm.employee.batch");
|
|
3936
|
+
if (!batch) return "";
|
|
3937
|
+
const result = await batch.handler({ ids: [userId] }, env);
|
|
3938
|
+
const row = (result?.data?.rows ?? [])[0];
|
|
3939
|
+
return String(row?.name ?? "").trim();
|
|
3940
|
+
} catch {
|
|
3941
|
+
return "";
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3944
|
+
var DETAIL_FALLBACK_KEYS = [
|
|
3945
|
+
"hrm_members",
|
|
3946
|
+
"mt_desc",
|
|
3947
|
+
"total_member",
|
|
3948
|
+
"caller",
|
|
3949
|
+
"contacter",
|
|
3950
|
+
"begin_datetime",
|
|
3951
|
+
"end_datetime",
|
|
3952
|
+
"other_members",
|
|
3953
|
+
"mt_creator",
|
|
3954
|
+
"topic_presenter",
|
|
3955
|
+
"mt_format",
|
|
3956
|
+
"mt_type",
|
|
3957
|
+
"video_url",
|
|
3958
|
+
"org_members",
|
|
3959
|
+
"with_secauth"
|
|
3960
|
+
];
|
|
3961
|
+
async function supplementRowFromDetail(row, mtId, env) {
|
|
3962
|
+
const isBlank = (value) => {
|
|
3963
|
+
if (value === void 0 || value === null) return true;
|
|
3964
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
3965
|
+
return String(value).trim() === "";
|
|
3966
|
+
};
|
|
3967
|
+
const missing = DETAIL_FALLBACK_KEYS.filter((key) => isBlank(row[key]));
|
|
3968
|
+
if (missing.length === 0) return { row, filled: [] };
|
|
3969
|
+
try {
|
|
3970
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
3971
|
+
const detailOperation = getMeetingOperation2("meeting.eb.meeting.detail");
|
|
3972
|
+
const result = await detailOperation.handler({ id: mtId }, env);
|
|
3973
|
+
const flat = result?.data?.data ?? result?.data ?? {};
|
|
3974
|
+
const merged = { ...row };
|
|
3975
|
+
const filled = [];
|
|
3976
|
+
for (const key of missing) {
|
|
3977
|
+
const value = flat[key];
|
|
3978
|
+
if (!isBlank(value)) {
|
|
3979
|
+
merged[key] = value;
|
|
3980
|
+
filled.push(key);
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
return { row: merged, filled };
|
|
3984
|
+
} catch {
|
|
3985
|
+
return { row, filled: [] };
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3875
3988
|
function buildResolver(row, extra, issuerOrg) {
|
|
3876
3989
|
const begin = parseDateTime(row.begin_datetime);
|
|
3877
3990
|
const end = parseDateTime(row.end_datetime);
|
|
@@ -3909,6 +4022,9 @@ function buildResolver(row, extra, issuerOrg) {
|
|
|
3909
4022
|
org_members: orgMembers,
|
|
3910
4023
|
// 落款公司全称:`extra.company_name` 可覆盖(对外开放时客户传自己的公司名)
|
|
3911
4024
|
company_name: String(extra.company_name ?? "").trim() || DEFAULT_COMPANY_NAME,
|
|
4025
|
+
// 客户单位(「尊敬的 XXX」):先看 extra(建会时由 create.flow 把参会客户名带进来),
|
|
4026
|
+
// 再看会议主表的 crm_members(部分租户会存),都没有才留【待补充】
|
|
4027
|
+
guest_org: String(extra.guest_org ?? "").trim() || flattenFieldValue(row.crm_members) || "",
|
|
3912
4028
|
// 单独暴露上级公司,模板需要「公司级落款」时可直接用
|
|
3913
4029
|
issuer_company: issuerCompany,
|
|
3914
4030
|
other_members: humanizeMembers(row.other_members),
|
|
@@ -3931,7 +4047,10 @@ function buildResolver(row, extra, issuerOrg) {
|
|
|
3931
4047
|
};
|
|
3932
4048
|
const lookup = (key) => {
|
|
3933
4049
|
if (key in derived) return derived[key];
|
|
3934
|
-
if (key in standard)
|
|
4050
|
+
if (key in standard) {
|
|
4051
|
+
const standardValue = standard[key];
|
|
4052
|
+
if (String(standardValue ?? "").trim() !== "") return standardValue;
|
|
4053
|
+
}
|
|
3935
4054
|
if (key.startsWith("extra.") && key.slice(6) in extra) return extra[key.slice(6)];
|
|
3936
4055
|
if (key in extra) return extra[key];
|
|
3937
4056
|
const raw = row[key];
|
|
@@ -3955,7 +4074,7 @@ var meetingInvitationRender = {
|
|
|
3955
4074
|
resource: "invitation",
|
|
3956
4075
|
method: "render",
|
|
3957
4076
|
action: "meeting.invitation.render",
|
|
3958
|
-
summary: "\u6309\u4F1A\u8BAE\u771F\u5B9E\u6570\u636E\u751F\u6210\u9080\u8BF7\u51FD
|
|
4077
|
+
summary: "\u6309\u4F1A\u8BAE\u771F\u5B9E\u6570\u636E\u751F\u6210\u9080\u8BF7\u51FD\uFF08\u53EA\u8BFB\uFF0C\u4E0D\u53D1\u9001\uFF09\uFF1A**\u540C\u65F6\u8FD4\u56DE docx \u4E0E\u5BF9\u8BDD\u5185\u53EF\u5C55\u793A\u7684 Markdown \u5168\u6587**\uFF08`text` \u5B57\u6BB5\uFF09\uFF0C\u4F1A\u8BDD\u91CC\u5E94\u76F4\u63A5\u628A `text` \u8D34\u51FA\u6765\uFF0C\u4E0D\u8981\u53EA\u7ED9\u6587\u4EF6\u540D\u8BA9\u4EBA\u81EA\u5DF1\u4E0B\u8F7D\uFF1B\u6570\u636E\u53D6 meeting.eb.meeting.list \u5355\u67E5\uFF1B\u8BAE\u7A0B\u6709\u8BAE\u9898\u5C31\u6309\u8BAE\u9898\u81EA\u52A8\u586B\u3001\u6CA1\u6709\u5219\u4FDD\u7559\u6A21\u677F\u793A\u4F8B\u884C\uFF1B\u53D6\u4E0D\u5230\u7684\u5B57\u6BB5\u6E32\u67D3\u6210\u3010\u5F85\u8865\u5145\u3011\uFF08docx \u91CC\u662F\u9EC4\u8272\u9AD8\u4EAE\uFF09\uFF1B\u79DF\u6237\u81EA\u5B9A\u4E49\u5B57\u6BB5\u7528 extra \u4F20\u5165",
|
|
3959
4078
|
capability: "invitation",
|
|
3960
4079
|
risk: "read",
|
|
3961
4080
|
inputSchema: {
|
|
@@ -3995,6 +4114,7 @@ var meetingInvitationRender = {
|
|
|
3995
4114
|
}
|
|
3996
4115
|
let row;
|
|
3997
4116
|
let dataSource = "meeting";
|
|
4117
|
+
let detailSupplementary = [];
|
|
3998
4118
|
if (!mtId) {
|
|
3999
4119
|
const mtName = String(args.mt_name ?? "").trim();
|
|
4000
4120
|
const beginText = String(args.begin_datetime ?? "").trim();
|
|
@@ -4021,7 +4141,7 @@ var meetingInvitationRender = {
|
|
|
4021
4141
|
};
|
|
4022
4142
|
dataSource = "payload";
|
|
4023
4143
|
} else {
|
|
4024
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
4144
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
4025
4145
|
const listOperation = getMeetingOperation2("meeting.eb.meeting.list");
|
|
4026
4146
|
try {
|
|
4027
4147
|
const listed = await listOperation.handler({ mt_id: mtId, pageNo: 1, pageSize: 1 }, env);
|
|
@@ -4037,6 +4157,17 @@ var meetingInvitationRender = {
|
|
|
4037
4157
|
if (!row) {
|
|
4038
4158
|
throw meetingValidationError("not_found", `\u672A\u627E\u5230\u4F1A\u8BAE id=${mtId}\uFF0C\u6216\u5F53\u524D\u8D26\u53F7\u65E0\u6743\u9650\u67E5\u770B`, { mtId });
|
|
4039
4159
|
}
|
|
4160
|
+
const supplement = await supplementRowFromDetail(row, mtId, env);
|
|
4161
|
+
row = supplement.row;
|
|
4162
|
+
detailSupplementary = supplement.filled;
|
|
4163
|
+
}
|
|
4164
|
+
let callerFromSession = false;
|
|
4165
|
+
if (!String(row.caller ?? "").trim() && !String(row.mt_creator ?? "").trim()) {
|
|
4166
|
+
const sessionName = await resolveSessionUserName(env);
|
|
4167
|
+
if (sessionName) {
|
|
4168
|
+
row = { ...row, caller: sessionName };
|
|
4169
|
+
callerFromSession = true;
|
|
4170
|
+
}
|
|
4040
4171
|
}
|
|
4041
4172
|
const creatorId = String(row.creator ?? "").trim();
|
|
4042
4173
|
const needsIssuerOrg = !String(row.org_members ?? "").trim() && creatorId !== "";
|
|
@@ -4064,6 +4195,7 @@ var meetingInvitationRender = {
|
|
|
4064
4195
|
const rendered = renderDocx(template, resolver, {
|
|
4065
4196
|
agenda: { headerKeyword: AGENDA_HEADER_KEYWORD, rows: agendaRows }
|
|
4066
4197
|
});
|
|
4198
|
+
const textVersion = renderInvitationMarkdown(resolver, agendaRows);
|
|
4067
4199
|
const begin = parseDateTime(row.begin_datetime);
|
|
4068
4200
|
const dateTag = begin ? `${begin.getFullYear()}${pad(begin.getMonth() + 1)}${pad(begin.getDate())}` : "\u672A\u77E5\u65E5\u671F";
|
|
4069
4201
|
const fileName = `\u9080\u8BF7\u51FD-${safeFileName(String(row.mt_name ?? ""))}-${dateTag}.docx`;
|
|
@@ -4104,12 +4236,17 @@ var meetingInvitationRender = {
|
|
|
4104
4236
|
meetingName: String(row.mt_name ?? ""),
|
|
4105
4237
|
// meeting=按真实会议数据;payload=按申请单字段预生成(会议可能还没生成,属预置函)
|
|
4106
4238
|
dataSource,
|
|
4239
|
+
// 列表单查丢字段时,用 detail 补回来的字段名(有值 = 邀请函用的是合并后的数据)
|
|
4240
|
+
detailSupplemented: detailSupplementary,
|
|
4241
|
+
// 对话内展示用的 Markdown 全文(与 docx 同源)。上层应直接把这段贴进回复正文,
|
|
4242
|
+
// ⛔ 不要只丢一个 filePath 让用户自己去本地打开看内容。
|
|
4243
|
+
text: textVersion.markdown,
|
|
4107
4244
|
filledFields: rendered.filled,
|
|
4108
4245
|
pendingFields: rendered.pending,
|
|
4109
4246
|
// 落款单位的实际来源,便于调用方判断是否需要人工改写
|
|
4110
4247
|
orgSource,
|
|
4111
|
-
// 召集人来源:meeting.caller=会议自己填的 / meeting.mt_creator=回落到创建人 / none=都没有
|
|
4112
|
-
callerSource: String(row.caller ?? "").trim() ? "meeting.caller" : String(row.mt_creator ?? "").trim() ? "meeting.mt_creator" : "none",
|
|
4248
|
+
// 召集人来源:meeting.caller=会议自己填的 / meeting.mt_creator=回落到创建人 / session.user=回落到发起人本人 / none=都没有
|
|
4249
|
+
callerSource: callerFromSession ? "session.user" : String(row.caller ?? "").trim() ? "meeting.caller" : String(row.mt_creator ?? "").trim() ? "meeting.mt_creator" : "none",
|
|
4113
4250
|
// 议程来源:meeting.topic=按议题自动填 / extra=调用方传入 / template=保留模板示例行
|
|
4114
4251
|
agendaSource,
|
|
4115
4252
|
agendaRows: agendaRows.length,
|
|
@@ -4758,7 +4895,7 @@ var meetingSummaryGet = {
|
|
|
4758
4895
|
const mtId = textOf5(args.mt_id).trim();
|
|
4759
4896
|
if (!mtId) throw meetingValidationError("mt_id_required", "\u5FC5\u987B\u63D0\u4F9B\u4F1A\u8BAE id\uFF08mt_id\uFF09");
|
|
4760
4897
|
const ctx = env.ctx;
|
|
4761
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
4898
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
4762
4899
|
const warnings = [];
|
|
4763
4900
|
const timings = {};
|
|
4764
4901
|
const include = Array.isArray(args.include) && args.include.length > 0 ? args.include.filter((item) => ALL_SECTIONS.includes(item)) : ALL_SECTIONS;
|
|
@@ -4894,7 +5031,7 @@ var meetingSummaryGet = {
|
|
|
4894
5031
|
warnings.push("\u8BE5\u4F1A\u8BAE\u6CA1\u6709\u5173\u8054\u7FA4\u804A\uFF08imchat_groupid \u4E3A\u7A7A\uFF09\uFF0Cchat \u6BB5\u4E3A null");
|
|
4895
5032
|
} else {
|
|
4896
5033
|
try {
|
|
4897
|
-
const { createImHost } = await import("./host-
|
|
5034
|
+
const { createImHost } = await import("./host-3F5UM5GN.js");
|
|
4898
5035
|
const { createImContinuationSigner } = await import("./continuation-2CKSBLA6.js");
|
|
4899
5036
|
const { getImOperation } = await import("./registry-OZSMDVPP.js");
|
|
4900
5037
|
const imEnv = {
|
|
@@ -5020,7 +5157,7 @@ var meetingFormFields = {
|
|
|
5020
5157
|
hint: "\u6CA1\u89E3\u6790\u5230\u8BE5\u8868\u7684 objId\uFF08\u53EF\u80FD\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u8FD9\u5F20\u8868\uFF0C\u6216\u8D26\u53F7\u65E0\u6743\u9650\uFF09"
|
|
5021
5158
|
}, { warnings: resolved.warnings });
|
|
5022
5159
|
}
|
|
5023
|
-
const { createEbuilderFormHost } = await import("./host-
|
|
5160
|
+
const { createEbuilderFormHost } = await import("./host-YMBXWFWX.js");
|
|
5024
5161
|
const { createEbuilderFormContinuationSigner } = await import("./continuation-RN6PZN2M.js");
|
|
5025
5162
|
const { executeEbuilderFormOperation } = await import("./operations-5QL3AECO.js");
|
|
5026
5163
|
const formEnv = {
|
|
@@ -5080,7 +5217,7 @@ var MT_STATUS_OVER = "8";
|
|
|
5080
5217
|
var CANCELLED_MARK_DELAY_MS = 800;
|
|
5081
5218
|
async function isCancelledMeeting(env, mtId) {
|
|
5082
5219
|
try {
|
|
5083
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
5220
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
5084
5221
|
const listed = await getMeetingOperation2("meeting.eb.meeting.list").handler(
|
|
5085
5222
|
// withCount:false —— 这里只要一行状态,不必额外请求 count(少一次往返,也便于测试替身)
|
|
5086
5223
|
{ mt_id: mtId, pageNo: 1, pageSize: 1, withCount: false },
|
|
@@ -5601,6 +5738,378 @@ var ebMeetingAssociation = async (ctx) => {
|
|
|
5601
5738
|
};
|
|
5602
5739
|
};
|
|
5603
5740
|
|
|
5741
|
+
// src/shortcuts/meeting/operations/eb/crm-search.ts
|
|
5742
|
+
var DEFAULT_CRM_FLOW_ID = "904205116264026112";
|
|
5743
|
+
var DEFAULT_KEYWORD_FIELD = "custom_name";
|
|
5744
|
+
var KEYWORD_FIELD_HINTS = [
|
|
5745
|
+
"custom_name",
|
|
5746
|
+
"mc",
|
|
5747
|
+
"sjmc",
|
|
5748
|
+
"khmc",
|
|
5749
|
+
"customerName",
|
|
5750
|
+
"customer_name",
|
|
5751
|
+
"clientName",
|
|
5752
|
+
"name",
|
|
5753
|
+
"keyword",
|
|
5754
|
+
"keywordName",
|
|
5755
|
+
"searchKey"
|
|
5756
|
+
];
|
|
5757
|
+
var ID_KEYS = ["sjID", "sjid", "sj_id", "sjjId", "customerId", "custId", "clientId", "id"];
|
|
5758
|
+
var NAME_KEYS = ["mc", "sjmc", "sj_name", "customerName", "custName", "clientName", "name"];
|
|
5759
|
+
var LIST_KEYS = [
|
|
5760
|
+
"detail1",
|
|
5761
|
+
"detail2",
|
|
5762
|
+
"detail3",
|
|
5763
|
+
"detail",
|
|
5764
|
+
"details",
|
|
5765
|
+
"detailList",
|
|
5766
|
+
"list",
|
|
5767
|
+
"rows",
|
|
5768
|
+
"items",
|
|
5769
|
+
"data",
|
|
5770
|
+
"records",
|
|
5771
|
+
"result",
|
|
5772
|
+
"customers",
|
|
5773
|
+
"sjList"
|
|
5774
|
+
];
|
|
5775
|
+
function asRecord(value) {
|
|
5776
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
5777
|
+
}
|
|
5778
|
+
function pickFirst(row, keys) {
|
|
5779
|
+
for (const key of keys) {
|
|
5780
|
+
const value = row[key];
|
|
5781
|
+
if (value === void 0 || value === null) continue;
|
|
5782
|
+
if (typeof value === "object") {
|
|
5783
|
+
const nested = asRecord(value);
|
|
5784
|
+
if (nested) {
|
|
5785
|
+
const inner = pickFirst(nested, keys) || pickFirst(nested, ["id", "name"]);
|
|
5786
|
+
if (inner) return inner;
|
|
5787
|
+
}
|
|
5788
|
+
continue;
|
|
5789
|
+
}
|
|
5790
|
+
const text = String(value).trim();
|
|
5791
|
+
if (text !== "") return text;
|
|
5792
|
+
}
|
|
5793
|
+
return "";
|
|
5794
|
+
}
|
|
5795
|
+
function unwrapRow(value) {
|
|
5796
|
+
const record = asRecord(value);
|
|
5797
|
+
if (!record) return null;
|
|
5798
|
+
const main = asRecord(record.mainTable);
|
|
5799
|
+
return main ?? record;
|
|
5800
|
+
}
|
|
5801
|
+
function collectCandidateLists(customData) {
|
|
5802
|
+
const found = [];
|
|
5803
|
+
const main = asRecord(customData.mainTable);
|
|
5804
|
+
if (main) {
|
|
5805
|
+
found.push({ source: "customData.mainTable", rows: [main] });
|
|
5806
|
+
for (const key of LIST_KEYS) {
|
|
5807
|
+
const value = main[key];
|
|
5808
|
+
if (Array.isArray(value)) found.push({ source: `customData.mainTable.${key}`, rows: value });
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5811
|
+
for (const key of LIST_KEYS) {
|
|
5812
|
+
const value = customData[key];
|
|
5813
|
+
if (Array.isArray(value)) found.push({ source: `customData.${key}`, rows: value });
|
|
5814
|
+
}
|
|
5815
|
+
return found;
|
|
5816
|
+
}
|
|
5817
|
+
var CONTACT_LIST_KEYS = ["lxr", "contacts", "contactList", "lxrList"];
|
|
5818
|
+
var ADDRESS_LIST_KEYS = ["khdz", "addresses", "addressList", "dz"];
|
|
5819
|
+
var CONTACT_NAME_KEYS = ["field_1173221220888062706", "xm", "lxrxm", "contactName", "name"];
|
|
5820
|
+
var CONTACT_MOBILE_KEYS = ["field_1173221220888062708", "sjhm", "mobile", "phone", "tel", "lxrdh"];
|
|
5821
|
+
var CONTACT_DEPT_KEYS = ["field_1173221220888062707", "bm", "dept", "department", "bmmc"];
|
|
5822
|
+
var MOBILE_RE = /^[+\d][\d\s-]{6,}$/;
|
|
5823
|
+
var DEPT_RE = /(部|科|处|室|中心|事业部|分公司|集团|公司)$/;
|
|
5824
|
+
function pickRawList(row, keys) {
|
|
5825
|
+
for (const key of keys) {
|
|
5826
|
+
if (Array.isArray(row[key])) return row[key];
|
|
5827
|
+
}
|
|
5828
|
+
return void 0;
|
|
5829
|
+
}
|
|
5830
|
+
function parseCrmContacts(raw) {
|
|
5831
|
+
if (!Array.isArray(raw)) return [];
|
|
5832
|
+
const out = [];
|
|
5833
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5834
|
+
for (const item of raw) {
|
|
5835
|
+
const row = asRecord(item);
|
|
5836
|
+
if (!row) continue;
|
|
5837
|
+
const entries = Object.entries(row).filter(([key, value]) => !key.startsWith("subForm") && value !== null && value !== void 0 && String(value).trim() !== "");
|
|
5838
|
+
if (entries.length === 0) continue;
|
|
5839
|
+
const pick = (keys) => {
|
|
5840
|
+
for (const key of keys) {
|
|
5841
|
+
const hit = entries.find(([k]) => k === key);
|
|
5842
|
+
if (hit) return String(hit[1]).trim();
|
|
5843
|
+
}
|
|
5844
|
+
return "";
|
|
5845
|
+
};
|
|
5846
|
+
let name = pick(CONTACT_NAME_KEYS);
|
|
5847
|
+
let mobile = pick(CONTACT_MOBILE_KEYS);
|
|
5848
|
+
let dept = pick(CONTACT_DEPT_KEYS);
|
|
5849
|
+
for (const [, value] of entries) {
|
|
5850
|
+
const text = String(value).trim();
|
|
5851
|
+
if (text === "") continue;
|
|
5852
|
+
if (!mobile && MOBILE_RE.test(text)) {
|
|
5853
|
+
mobile = text;
|
|
5854
|
+
continue;
|
|
5855
|
+
}
|
|
5856
|
+
if (!name && !DEPT_RE.test(text) && !/^\d+$/.test(text)) {
|
|
5857
|
+
name = text;
|
|
5858
|
+
continue;
|
|
5859
|
+
}
|
|
5860
|
+
if (!dept && DEPT_RE.test(text)) dept = text;
|
|
5861
|
+
}
|
|
5862
|
+
if (name === "" && mobile === "") continue;
|
|
5863
|
+
const dedupeKey = `${name}|${mobile}`;
|
|
5864
|
+
if (seen.has(dedupeKey)) continue;
|
|
5865
|
+
seen.add(dedupeKey);
|
|
5866
|
+
out.push({ name, mobile, ...dept === "" ? {} : { dept } });
|
|
5867
|
+
}
|
|
5868
|
+
return out;
|
|
5869
|
+
}
|
|
5870
|
+
function parseCrmAddresses(raw) {
|
|
5871
|
+
if (!Array.isArray(raw)) return [];
|
|
5872
|
+
const out = [];
|
|
5873
|
+
for (const item of raw) {
|
|
5874
|
+
const row = asRecord(item);
|
|
5875
|
+
if (!row) continue;
|
|
5876
|
+
const parts = Object.entries(row).filter(([key, value]) => !key.startsWith("subForm") && value !== null && value !== void 0 && String(value).trim() !== "").map(([, value]) => String(value).trim());
|
|
5877
|
+
if (parts.length > 0) out.push(parts.join(" "));
|
|
5878
|
+
}
|
|
5879
|
+
return out;
|
|
5880
|
+
}
|
|
5881
|
+
function normalizeCustomers(rows, limit) {
|
|
5882
|
+
const seen = /* @__PURE__ */ new Map();
|
|
5883
|
+
for (const raw of rows) {
|
|
5884
|
+
const row = unwrapRow(raw);
|
|
5885
|
+
if (!row) continue;
|
|
5886
|
+
const customerId = pickFirst(row, ID_KEYS);
|
|
5887
|
+
const name = pickFirst(row, NAME_KEYS);
|
|
5888
|
+
if (customerId === "" && name === "") continue;
|
|
5889
|
+
const key = customerId !== "" ? customerId : `name:${name}`;
|
|
5890
|
+
if (seen.has(key)) continue;
|
|
5891
|
+
const contacts = parseCrmContacts(pickRawList(row, CONTACT_LIST_KEYS));
|
|
5892
|
+
const addresses = parseCrmAddresses(pickRawList(row, ADDRESS_LIST_KEYS));
|
|
5893
|
+
seen.set(key, {
|
|
5894
|
+
customerId,
|
|
5895
|
+
name,
|
|
5896
|
+
...contacts.length > 0 ? { contacts } : {},
|
|
5897
|
+
...addresses.length > 0 ? { addresses } : {}
|
|
5898
|
+
});
|
|
5899
|
+
}
|
|
5900
|
+
const all = [...seen.values()];
|
|
5901
|
+
const total = all.length;
|
|
5902
|
+
return { items: limit > 0 ? all.slice(0, limit) : all, total };
|
|
5903
|
+
}
|
|
5904
|
+
function parseCrmSearchPayload(actionData, options) {
|
|
5905
|
+
const action = asRecord(actionData) ?? {};
|
|
5906
|
+
const responseData = asRecord(action.responseData) ?? {};
|
|
5907
|
+
const customData = asRecord(responseData.customData) ?? {};
|
|
5908
|
+
const rawHasData = action.hasData;
|
|
5909
|
+
const hasData = rawHasData === void 0 || rawHasData === null ? null : Number(rawHasData) > 0;
|
|
5910
|
+
const templateFields = options.templateFields ?? [];
|
|
5911
|
+
const base = {
|
|
5912
|
+
keyword: options.keyword,
|
|
5913
|
+
limit: options.limit,
|
|
5914
|
+
total: 0,
|
|
5915
|
+
items: [],
|
|
5916
|
+
truncated: false,
|
|
5917
|
+
source: "customData",
|
|
5918
|
+
hasData,
|
|
5919
|
+
exact: false,
|
|
5920
|
+
singleBestMatch: false,
|
|
5921
|
+
message: "",
|
|
5922
|
+
templateFields,
|
|
5923
|
+
keywordField: options.keywordField ?? null
|
|
5924
|
+
};
|
|
5925
|
+
if (options.templateBlocked === true) {
|
|
5926
|
+
return {
|
|
5927
|
+
...base,
|
|
5928
|
+
blocked: "esb_template_empty",
|
|
5929
|
+
message: "\u52A8\u4F5C\u6D41\u914D\u4E86\u300C\u81EA\u5B9A\u4E49\u5165\u53C2\u6A21\u677F\u300D\u4F46\u4E3B\u8868\u5B57\u6BB5\u4E3A\u7A7A\uFF08customParams.mainTable = {}\uFF09\uFF0C\u89E6\u53D1\u65F6\u4F20\u5165\u7684\u67E5\u8BE2\u6761\u4EF6\u4F1A\u88AB\u4E22\u5F03\uFF0C\u56E0\u6B64\u67E5\u4E0D\u5230\u5BA2\u6237\u3002\u9700\u8981\u5148\u5728 ESB \u8BBE\u8BA1\u5668\u91CC\u7ED9\u8BE5\u52A8\u4F5C\u6D41\u8865\u5165\u53C2\uFF08`custom_name` \u5BA2\u6237\u540D\u79F0\uFF09\u540E\u518D\u67E5\u3002"
|
|
5930
|
+
};
|
|
5931
|
+
}
|
|
5932
|
+
const lists = collectCandidateLists(customData);
|
|
5933
|
+
const best = lists.map((item) => ({ ...item, normalized: normalizeCustomers(item.rows, options.limit) })).sort((a, b) => b.normalized.total - a.normalized.total)[0];
|
|
5934
|
+
if (!best) {
|
|
5935
|
+
return {
|
|
5936
|
+
...base,
|
|
5937
|
+
message: "\u52A8\u4F5C\u6D41\u8FD4\u56DE\u91CC\u6CA1\u6709\u53EF\u8BC6\u522B\u7684\u5BA2\u6237\u7ED3\u6784\uFF08\u65E2\u6CA1\u6709 mainTable \u884C\uFF0C\u4E5F\u6CA1\u6709 detail/list \u4E4B\u7C7B\u7684\u5217\u8868\uFF09\uFF0C\u8BF7\u68C0\u67E5\u52A8\u4F5C\u6D41\u7684\u8F93\u51FA\u6A21\u677F\u662F\u5426\u4ECD\u8F93\u51FA sjID/mc"
|
|
5938
|
+
};
|
|
5939
|
+
}
|
|
5940
|
+
if (best.normalized.total === 0) {
|
|
5941
|
+
return {
|
|
5942
|
+
...base,
|
|
5943
|
+
source: best.source,
|
|
5944
|
+
message: `\u6309\u300C${options.keyword}\u300D\u6CA1\u6709\u5339\u914D\u5230\u5BA2\u6237\uFF08\u52A8\u4F5C\u6D41\u8FD4\u56DE\u7A7A\u884C\uFF09`
|
|
5945
|
+
};
|
|
5946
|
+
}
|
|
5947
|
+
const items = best.normalized.items;
|
|
5948
|
+
const singleBestMatch = best.normalized.total === 1;
|
|
5949
|
+
const exact = singleBestMatch && items[0].name === options.keyword;
|
|
5950
|
+
const rawAddress = pickRawList(best.rows[0], ADDRESS_LIST_KEYS);
|
|
5951
|
+
const addressHint = Array.isArray(rawAddress) && rawAddress.length > 0 && (items[0].addresses?.length ?? 0) === 0 ? `\u52A8\u4F5C\u6D41\u7684\u300C\u5BA2\u6237\u5730\u5740\u300D\uFF08khdz\uFF09\u53EA\u56DE\u4E86 ${rawAddress.length} \u6761\u660E\u7EC6\u884C id\uFF0C\u6CA1\u6709\u5730\u5740\u6587\u672C \u2014\u2014 \u9700\u8981\u5728 ESB \u8F93\u51FA\u6A21\u677F\u91CC\u8865\u4E0A\u5730\u5740\u5B57\u6BB5\uFF08\u5982 \u8BE6\u7EC6\u5730\u5740/\u7701\u5E02\u533A\uFF09\uFF0C\u5426\u5219\u9080\u8BF7\u51FD\u548C\u660E\u7EC6\u8868\u91CC\u62FF\u4E0D\u5230\u5730\u5740\u3002` : void 0;
|
|
5952
|
+
return {
|
|
5953
|
+
...base,
|
|
5954
|
+
items,
|
|
5955
|
+
total: best.normalized.total,
|
|
5956
|
+
truncated: best.normalized.total > options.limit,
|
|
5957
|
+
source: best.source,
|
|
5958
|
+
exact,
|
|
5959
|
+
singleBestMatch,
|
|
5960
|
+
...addressHint ? { addressHint } : {},
|
|
5961
|
+
message: exact ? `\u7CBE\u786E\u547D\u4E2D\u5BA2\u6237\u300C${items[0].name}\u300D\uFF08${items[0].customerId}\uFF09` : `\u6309\u300C${options.keyword}\u300D\u6A21\u7CCA\u547D\u4E2D ${best.normalized.total} \u4E2A\u5BA2\u6237` + (singleBestMatch ? "\uFF08\u52A8\u4F5C\u6D41\u53EA\u56DE\u9996\u4E2A\u5339\u914D\uFF09" : "") + (best.normalized.total > options.limit ? `\uFF0C\u5DF2\u6309 limit=${options.limit} \u622A\u65AD` : "")
|
|
5962
|
+
};
|
|
5963
|
+
}
|
|
5964
|
+
function pickKeywordField(templateMainTable) {
|
|
5965
|
+
const keys = Object.keys(templateMainTable ?? {});
|
|
5966
|
+
if (keys.length === 0) return null;
|
|
5967
|
+
for (const hint of KEYWORD_FIELD_HINTS) {
|
|
5968
|
+
const hit = keys.find((key) => key.toLowerCase() === hint.toLowerCase());
|
|
5969
|
+
if (hit) return hit;
|
|
5970
|
+
}
|
|
5971
|
+
return keys.length === 1 ? keys[0] : null;
|
|
5972
|
+
}
|
|
5973
|
+
function pickLimitField(templateMainTable) {
|
|
5974
|
+
const keys = Object.keys(templateMainTable ?? {});
|
|
5975
|
+
const hints = ["pageSize", "pagesize", "limit", "rows", "size", "num"];
|
|
5976
|
+
for (const hint of hints) {
|
|
5977
|
+
const hit = keys.find((key) => key.toLowerCase() === hint.toLowerCase());
|
|
5978
|
+
if (hit) return hit;
|
|
5979
|
+
}
|
|
5980
|
+
return null;
|
|
5981
|
+
}
|
|
5982
|
+
async function runCrmSearchFlow(env, input) {
|
|
5983
|
+
const session = await env.host.getSession();
|
|
5984
|
+
const employeeId = String(input.employeeId ?? session?.userId ?? "").trim();
|
|
5985
|
+
if (!employeeId) {
|
|
5986
|
+
throw meetingValidationError("crm_employee_required", "\u53D6\u4E0D\u5230\u5F53\u524D\u767B\u5F55\u7528\u6237 id\uFF0C\u65E0\u6CD5\u89E6\u53D1 ESB \u5BA2\u6237\u67E5\u8BE2");
|
|
5987
|
+
}
|
|
5988
|
+
const { createEsbHost } = await import("./host-VGPVP7YF.js");
|
|
5989
|
+
const { createEsbContinuationSigner } = await import("./continuation-NLECEJPX.js");
|
|
5990
|
+
const { getEsbOperation } = await import("./registry-VT5Y2HLA.js");
|
|
5991
|
+
const esbEnv = {
|
|
5992
|
+
ctx: env.ctx,
|
|
5993
|
+
host: createEsbHost(env.ctx),
|
|
5994
|
+
continuation: createEsbContinuationSigner(env.ctx)
|
|
5995
|
+
};
|
|
5996
|
+
const templateOp = getEsbOperation("esb.input-format");
|
|
5997
|
+
const prepareOp = getEsbOperation("esb.trigger.prepare");
|
|
5998
|
+
const applyOp = getEsbOperation("esb.trigger.apply");
|
|
5999
|
+
let templateMainTable = null;
|
|
6000
|
+
let customParamsTemplate = null;
|
|
6001
|
+
let templateReadOk = false;
|
|
6002
|
+
try {
|
|
6003
|
+
const template = await templateOp.handler({ applicationId: input.flowId }, esbEnv);
|
|
6004
|
+
customParamsTemplate = asRecord(template?.data?.customParams);
|
|
6005
|
+
templateMainTable = asRecord(customParamsTemplate?.mainTable);
|
|
6006
|
+
templateReadOk = true;
|
|
6007
|
+
} catch {
|
|
6008
|
+
}
|
|
6009
|
+
const templateFields = Object.keys(templateMainTable ?? {});
|
|
6010
|
+
const templateBlocked = templateReadOk && customParamsTemplate !== null && templateFields.length === 0;
|
|
6011
|
+
const keywordField = pickKeywordField(templateMainTable) ?? DEFAULT_KEYWORD_FIELD;
|
|
6012
|
+
const limitField = pickLimitField(templateMainTable);
|
|
6013
|
+
const mainTable = {};
|
|
6014
|
+
mainTable[keywordField] = input.keyword;
|
|
6015
|
+
if (limitField) mainTable[limitField] = input.limit;
|
|
6016
|
+
const pre = await prepareOp.handler(
|
|
6017
|
+
{
|
|
6018
|
+
esbFlowId: input.flowId,
|
|
6019
|
+
employeeId,
|
|
6020
|
+
customParams: { mainTable }
|
|
6021
|
+
},
|
|
6022
|
+
esbEnv
|
|
6023
|
+
);
|
|
6024
|
+
const applied = await applyOp.handler(
|
|
6025
|
+
{ continuation: pre?.data?.continuation, confirm: true },
|
|
6026
|
+
esbEnv
|
|
6027
|
+
);
|
|
6028
|
+
const actionData = applied?.data?.actionData;
|
|
6029
|
+
const parsed = parseCrmSearchPayload(actionData, {
|
|
6030
|
+
keyword: input.keyword,
|
|
6031
|
+
limit: input.limit,
|
|
6032
|
+
templateFields,
|
|
6033
|
+
keywordField,
|
|
6034
|
+
templateBlocked
|
|
6035
|
+
});
|
|
6036
|
+
if (actionData && typeof actionData === "object") {
|
|
6037
|
+
const reminder = actionData.reminder;
|
|
6038
|
+
const reminderText = reminder === void 0 || reminder === null ? "" : String(reminder);
|
|
6039
|
+
if (reminderText !== "" && reminderText !== "0") parsed.actionMessage = reminderText;
|
|
6040
|
+
}
|
|
6041
|
+
return { result: parsed, raw: applied?.data };
|
|
6042
|
+
}
|
|
6043
|
+
var ebCrmSearch = {
|
|
6044
|
+
name: "meeting.eb.crm.search",
|
|
6045
|
+
resource: "eb",
|
|
6046
|
+
method: "meeting.eb.crm.search",
|
|
6047
|
+
action: "meeting.eb.crm.search",
|
|
6048
|
+
summary: "\u6309\u5BA2\u6237\u540D\u79F0\u67E5\u8BE2 CRM \u5BA2\u6237\uFF08ESB \u52A8\u4F5C\u6D41 904205116264026112\uFF0C\u5165\u53C2 custom_name\uFF0C\u51FA\u53C2 sjID/mc\uFF09\uFF1B\u52A8\u4F5C\u6D41\u4E00\u6B21\u53EA\u56DE\u9996\u4E2A\u5339\u914D\uFF0C\u540D\u79F0\u4E0D\u5B8C\u5168\u4E00\u81F4\u65F6\u987B\u56DE\u95EE\u7528\u6237\u786E\u8BA4",
|
|
6049
|
+
capability: "eb.crm",
|
|
6050
|
+
risk: "read",
|
|
6051
|
+
inputSchema: schemaOf(
|
|
6052
|
+
{
|
|
6053
|
+
keyword: {
|
|
6054
|
+
type: "string",
|
|
6055
|
+
minLength: 1,
|
|
6056
|
+
description: "\u5BA2\u6237\u540D\u79F0\uFF0C\u8D70\u52A8\u4F5C\u6D41\u5165\u53C2 custom_name\uFF08\u5305\u542B\u5339\u914D\uFF09\uFF1A\u7ED9\u5168\u79F0\u6700\u7A33\uFF0C\u7247\u6BB5\u53EA\u56DE\u9996\u4E2A\u5339\u914D"
|
|
6057
|
+
},
|
|
6058
|
+
limit: { type: "number", description: "\u8FD4\u56DE\u6761\u6570\u4E0A\u9650\uFF0C\u9ED8\u8BA4 10\uFF08\u5F53\u524D\u52A8\u4F5C\u6D41\u4E00\u6B21\u53EA\u56DE 1 \u6761\uFF0C\u4EC5\u4F5C\u517C\u5BB9\uFF09" },
|
|
6059
|
+
flowId: { type: "string", description: "\u8986\u76D6 ESB \u52A8\u4F5C\u6D41 id\uFF08\u9ED8\u8BA4 904205116264026112\uFF09" },
|
|
6060
|
+
employeeId: { type: "string", description: "\u8986\u76D6\u89E6\u53D1\u4EBA\u5458 id\uFF08\u9ED8\u8BA4\u5F53\u524D\u767B\u5F55\u7528\u6237\uFF09" },
|
|
6061
|
+
includeRaw: { type: "boolean", description: "true=\u9644\u5E26 ESB \u539F\u59CB\u8FD4\u56DE\uFF0C\u4FBF\u4E8E\u6392\u67E5\u8F93\u51FA\u7ED3\u6784" }
|
|
6062
|
+
},
|
|
6063
|
+
{ required: ["keyword"] }
|
|
6064
|
+
),
|
|
6065
|
+
handler: async (args, env) => {
|
|
6066
|
+
const keyword = String(args.keyword ?? "").trim();
|
|
6067
|
+
if (!keyword) {
|
|
6068
|
+
throw meetingValidationError("crm_keyword_required", "keyword \u4E0D\u80FD\u4E3A\u7A7A\uFF08\u5BA2\u6237\u540D\u79F0\u5173\u952E\u5B57\uFF09");
|
|
6069
|
+
}
|
|
6070
|
+
const limitRaw = Number(args.limit ?? 10);
|
|
6071
|
+
const limit = Number.isFinite(limitRaw) && limitRaw > 0 ? Math.min(Math.floor(limitRaw), 100) : 10;
|
|
6072
|
+
const { result, raw } = await runCrmSearchFlow(env, {
|
|
6073
|
+
keyword,
|
|
6074
|
+
limit,
|
|
6075
|
+
flowId: String(args.flowId ?? "").trim() || DEFAULT_CRM_FLOW_ID,
|
|
6076
|
+
...args.employeeId ? { employeeId: String(args.employeeId) } : {}
|
|
6077
|
+
});
|
|
6078
|
+
const warnings = [];
|
|
6079
|
+
if (result.blocked === "esb_template_empty") {
|
|
6080
|
+
warnings.push(result.message);
|
|
6081
|
+
warnings.push("\u26D4 \u4E0D\u8981\u56DE\u590D\u300C\u6CA1\u6709\u8FD9\u4E2A\u5BA2\u6237\u300D\uFF1A\u8FD9\u662F\u52A8\u4F5C\u6D41\u5165\u53C2\u6A21\u677F\u672A\u914D\u7F6E\uFF0C\u5C5E\u4E8E\u914D\u7F6E\u95EE\u9898\u3002");
|
|
6082
|
+
} else if (result.items.length === 0) {
|
|
6083
|
+
warnings.push(`\u6309\u300C${keyword}\u300D\u6CA1\u6709\u5339\u914D\u5230\u5BA2\u6237\uFF1B\u53EF\u6362\u66F4\u77ED\u7684\u5173\u952E\u5B57\uFF08\u53BB\u6389\u5730\u57DF/\u540E\u7F00\uFF09\uFF0C\u6216\u786E\u8BA4\u8BE5\u5BA2\u6237\u662F\u5426\u5DF2\u5728 CRM \u5EFA\u6863\uFF08\u8FD9\u662F\u300C\u67E5\u65E0\u300D\uFF0C\u53EF\u4EE5\u5982\u5B9E\u56DE\u590D\u7528\u6237\uFF09\u3002`);
|
|
6084
|
+
} else if (!result.exact) {
|
|
6085
|
+
warnings.push(`\u52A8\u4F5C\u6D41\u4E00\u6B21\u53EA\u56DE\u9996\u4E2A\u5339\u914D\uFF1A\u300C${result.items[0].name}\u300D\uFF08${result.items[0].customerId}\uFF09\uFF0C\u4E0E\u300C${keyword}\u300D\u4E0D\u5B8C\u5168\u4E00\u81F4\u3002\u8BF7\u628A**\u547D\u4E2D\u5168\u540D\u539F\u6837\u5FF5\u51FA\u6765\u95EE"\u662F\u8FD9\u5BB6\u5417"**\uFF0C\u7528\u6237\u8BA4\u4E86\u518D\u628A\u8BE5 id \u5199\u8FDB create.flow.prepare \u7684 crm_members\uFF0C\u4E0D\u8981\u731C\u3002\u26D4 \u4E0D\u8981\u95EE\u6210"\u586B\u8FDB\u53C2\u4F1A\u5BA2\u6237\u5B57\u6BB5\u8FD8\u662F\u53EA\u5199\u8FDB\u4F1A\u8BAE\u5185\u5BB9\u5907\u6CE8"\u8FD9\u79CD\u9009\u62E9\u9898 \u2014\u2014 \u5BA2\u6237\u4E00\u5F8B\u8981\u5173\u8054\u5BA2\u6237\u6863\u6848\uFF0C"\u53EA\u5199\u5907\u6CE8"\u662F\u660E\u4EE4\u7981\u6B62\u7684\u505A\u6CD5\u3002`);
|
|
6086
|
+
}
|
|
6087
|
+
if (result.items.some((item) => item.name === "")) {
|
|
6088
|
+
warnings.push("\u6709\u5BA2\u6237\u53EA\u8FD4\u56DE\u4E86 sjID \u6CA1\u8FD4\u56DE mc\uFF08\u540D\u79F0\uFF09\uFF0C\u8BF7\u8BA9\u52A8\u4F5C\u6D41\u8F93\u51FA mc \u5B57\u6BB5\u3002");
|
|
6089
|
+
}
|
|
6090
|
+
const firstCustomer = result.items[0];
|
|
6091
|
+
if (firstCustomer) {
|
|
6092
|
+
const contacts = firstCustomer.contacts ?? [];
|
|
6093
|
+
if (contacts.length > 0) {
|
|
6094
|
+
warnings.push(
|
|
6095
|
+
`\u8BE5\u5BA2\u6237\u6709 ${contacts.length} \u4F4D\u8054\u7CFB\u4EBA\uFF1A` + contacts.map((c) => `${c.name}${c.dept ? `\uFF08${c.dept}\uFF09` : ""} ${c.mobile || "\u65E0\u624B\u673A\u53F7"}`).join("\u3001") + '\u3002\u5EFA\u4F1A\u65F6\u4F20 `crm_members` \u5C31\u4F1A\u628A\u8FD9**\u5168\u90E8\u8054\u7CFB\u4EBA\u81EA\u52A8\u5199\u6210\u300C\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6\u300D\u884C**\uFF08\u4E00\u4EBA\u4E00\u884C\uFF09\uFF0C\u26D4 \u4E0D\u8981\u95EE\u7528\u6237"\u9009\u54EA\u4F4D"\u3001\u4E5F\u4E0D\u8981\u53EA\u5E26\u5176\u4E2D\u4E00\u4F4D\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8BF4"\u53EA\u5199\u67D0\u67D0"\u65F6\u624D\u7528 crm_member_details:[{"xm":"<\u59D3\u540D>","sjhm":"<\u624B\u673A\u53F7>","zw":"<\u90E8\u95E8\u6216\u804C\u4F4D>"}] \u8986\u76D6\u3002'
|
|
6096
|
+
);
|
|
6097
|
+
} else {
|
|
6098
|
+
warnings.push(
|
|
6099
|
+
'\u8BE5\u5BA2\u6237**\u6CA1\u6709\u8054\u7CFB\u4EBA**\uFF08\u52A8\u4F5C\u6D41\u672A\u8F93\u51FA lxr\uFF0C\u6216\u8BE5\u5BA2\u6237\u6CA1\u5EFA\u6863\u8054\u7CFB\u4EBA\uFF09\u2014\u2014 \u8FD9\u662F\u552F\u4E00\u9700\u8981\u95EE\u8054\u7CFB\u4EBA\u7684\u573A\u666F\u3002\u53EF\u4EE5\u95EE\u7528\u6237\u300C\u8981\u4E0D\u8981\u8865\u4E00\u4E0B\u8054\u7CFB\u4EBA\u59D3\u540D\u548C\u624B\u673A\u53F7\uFF08\u65B9\u4FBF\u7684\u8BDD\u518D\u7ED9\u804C\u4F4D\uFF09\u300D\uFF0C\u518D\u4EE5 crm_member_details:[{"xm":"\u5F20\u4E09","sjhm":"13800000000"}] \u4F20\u7ED9 create.flow.prepare/quick\uFF1B\u7528\u6237\u8BF4"\u6CA1\u6709"\u5C31\u7559\u7A7A\uFF0C\u4E0D\u8981\u786C\u7F16\u3002'
|
|
6100
|
+
);
|
|
6101
|
+
}
|
|
6102
|
+
if (result.addressHint) warnings.push(result.addressHint);
|
|
6103
|
+
}
|
|
6104
|
+
return meetingSuccess(
|
|
6105
|
+
"meeting.eb.crm.search",
|
|
6106
|
+
{ ...result, ...args.includeRaw === true ? { raw } : {} },
|
|
6107
|
+
warnings.length > 0 ? { warnings } : {}
|
|
6108
|
+
);
|
|
6109
|
+
}
|
|
6110
|
+
};
|
|
6111
|
+
var meetingEbCrmOperations = [ebCrmSearch];
|
|
6112
|
+
|
|
5604
6113
|
// src/shortcuts/meeting/operations/eb/create-flow.ts
|
|
5605
6114
|
import { existsSync as existsSync3 } from "node:fs";
|
|
5606
6115
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
|
|
@@ -5615,18 +6124,22 @@ var FIELD_ALIASES = {
|
|
|
5615
6124
|
customize_address: ["\u81EA\u5B9A\u4E49\u4F1A\u8BAE\u5730\u70B9", "\u81EA\u5B9A\u4E49\u5730\u70B9"],
|
|
5616
6125
|
hrm_members: ["\u53C2\u4F1A\u4EBA\u5458", "\u53C2\u4F1A\u4EBA"],
|
|
5617
6126
|
total_member: ["\u53C2\u4F1A\u4EBA\u6570", "\u4EBA\u6570"],
|
|
6127
|
+
/** 参会客户(CustomerComponent 客户浏览按钮):值是客户 id 列表,不是客户名称文本。 */
|
|
6128
|
+
crm_members: ["\u53C2\u4F1A\u5BA2\u6237", "\u5BA2\u6237"],
|
|
6129
|
+
crm_member_count: ["\u5E94\u5230\u5BA2\u6237\u6570", "\u5BA2\u6237\u6570"],
|
|
5618
6130
|
caller: ["\u53EC\u96C6\u4EBA", "\u53D1\u8D77\u4EBA"],
|
|
5619
6131
|
contacter: ["\u8054\u7CFB\u4EBA"],
|
|
5620
6132
|
mt_type: ["\u4F1A\u8BAE\u7C7B\u578B"],
|
|
5621
6133
|
other_remark: ["\u5907\u6CE8", "\u5176\u4ED6\u8BF4\u660E"]
|
|
5622
6134
|
};
|
|
6135
|
+
var PERSON_FIELD_LABELS = { caller: "\u53EC\u96C6\u4EBA", contacter: "\u8054\u7CFB\u4EBA" };
|
|
5623
6136
|
function workflowEnv(env) {
|
|
5624
6137
|
return env;
|
|
5625
6138
|
}
|
|
5626
6139
|
async function loadCreateForm(env, workflowId) {
|
|
5627
|
-
const { createWorkflowHost } = await import("./host-
|
|
6140
|
+
const { createWorkflowHost } = await import("./host-YAQAPYNP.js");
|
|
5628
6141
|
const { createWorkflowContinuationSigner } = await import("./continuation-HZIZRZBX.js");
|
|
5629
|
-
const { getWorkflowOperation } = await import("./registry-
|
|
6142
|
+
const { getWorkflowOperation } = await import("./registry-YX4CSEMD.js");
|
|
5630
6143
|
const wfEnv = {
|
|
5631
6144
|
...workflowEnv(env),
|
|
5632
6145
|
host: createWorkflowHost(env.ctx),
|
|
@@ -5670,28 +6183,111 @@ async function resolveEmployeeNames(env, ids) {
|
|
|
5670
6183
|
}
|
|
5671
6184
|
return map;
|
|
5672
6185
|
}
|
|
5673
|
-
async function
|
|
6186
|
+
async function resolvePersonTokens(env, tokens) {
|
|
6187
|
+
const map = /* @__PURE__ */ new Map();
|
|
6188
|
+
const unique = [...new Set(tokens.map((token) => String(token).trim()).filter((token) => token !== ""))];
|
|
6189
|
+
if (unique.length === 0) return map;
|
|
6190
|
+
const idLike = unique.filter((token) => /^\d{8,}$/.test(token));
|
|
6191
|
+
const nameLike = unique.filter((token) => !/^\d{8,}$/.test(token));
|
|
6192
|
+
if (idLike.length > 0) {
|
|
6193
|
+
const names = await resolveEmployeeNames(env, idLike);
|
|
6194
|
+
for (const id of idLike) map.set(id, { id, name: names.get(id) ?? id });
|
|
6195
|
+
}
|
|
6196
|
+
if (nameLike.length > 0) {
|
|
6197
|
+
try {
|
|
6198
|
+
const { hrmEmployeeOperations } = await import("./employee-SAK2QYXX.js");
|
|
6199
|
+
const query = hrmEmployeeOperations.find((operation) => operation.name === "hrm.employee.query");
|
|
6200
|
+
for (const name of nameLike) {
|
|
6201
|
+
if (!query) break;
|
|
6202
|
+
const found = await query.handler({ keyword: name, pageSize: 10 }, env).catch(() => null);
|
|
6203
|
+
const rows = found?.data?.rows ?? [];
|
|
6204
|
+
const exact = rows.find((row) => String(row.name ?? "").trim() === name);
|
|
6205
|
+
const hit = exact ?? (rows.length === 1 ? rows[0] : void 0);
|
|
6206
|
+
const id = String(hit?.id ?? "").trim();
|
|
6207
|
+
if (id === "") continue;
|
|
6208
|
+
map.set(name, { id, name: String(hit?.name ?? name) });
|
|
6209
|
+
}
|
|
6210
|
+
} catch {
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
return map;
|
|
6214
|
+
}
|
|
6215
|
+
async function resolveSelfPerson(env) {
|
|
6216
|
+
let session = null;
|
|
6217
|
+
try {
|
|
6218
|
+
session = await env.host?.getSession?.();
|
|
6219
|
+
} catch {
|
|
6220
|
+
return null;
|
|
6221
|
+
}
|
|
6222
|
+
const id = String(session?.userId ?? "").trim();
|
|
6223
|
+
if (id === "" || id === "unknown") return null;
|
|
6224
|
+
const names = await resolveEmployeeNames(env, [id]);
|
|
6225
|
+
const name = String(names.get(id) ?? "").trim();
|
|
6226
|
+
if (name === "") return null;
|
|
6227
|
+
return { id, name };
|
|
6228
|
+
}
|
|
6229
|
+
function applySelfPersonDefaults(args, self) {
|
|
6230
|
+
const filled = [];
|
|
6231
|
+
const missing = ["caller", "contacter"].filter((field) => String(args[field] ?? "").trim() === "");
|
|
6232
|
+
if (missing.length === 0) return { filled, warning: "" };
|
|
6233
|
+
if (!self) {
|
|
6234
|
+
return {
|
|
6235
|
+
filled,
|
|
6236
|
+
warning: missing.length === 2 ? "\u26A0\uFE0F \u6CA1\u80FD\u786E\u8BA4\u5F53\u524D\u767B\u5F55\u7528\u6237\u5BF9\u5E94\u7684\u5458\u5DE5 \u2014\u2014\u300C\u53EC\u96C6\u4EBA\u300D\u300C\u8054\u7CFB\u4EBA\u300D\u4F1A\u7559\u7A7A\uFF0C\u8BF7\u663E\u5F0F\u4F20 caller / contacter\uFF08\u5458\u5DE5 id \u6216\u59D3\u540D\uFF09\u3002" : ""
|
|
6237
|
+
};
|
|
6238
|
+
}
|
|
6239
|
+
for (const field of missing) {
|
|
6240
|
+
args[field] = self.id;
|
|
6241
|
+
filled.push({ field, id: self.id, name: self.name });
|
|
6242
|
+
}
|
|
6243
|
+
return { filled, warning: "" };
|
|
6244
|
+
}
|
|
6245
|
+
function parseRoomRef(input) {
|
|
6246
|
+
const text = String(input ?? "").trim();
|
|
6247
|
+
if (!text) return {};
|
|
6248
|
+
const withId = /^(.*?)[((]\s*(\d{4,})\s*[))]$/.exec(text);
|
|
6249
|
+
if (withId) {
|
|
6250
|
+
const name = withId[1].trim();
|
|
6251
|
+
const id = withId[2];
|
|
6252
|
+
return name ? { id, name } : { id };
|
|
6253
|
+
}
|
|
6254
|
+
if (/^\d+$/.test(text)) return { id: text };
|
|
6255
|
+
return { name: text };
|
|
6256
|
+
}
|
|
6257
|
+
async function resolveAddressRoom(env, input) {
|
|
5674
6258
|
const text = String(input ?? "").trim();
|
|
5675
6259
|
if (!text) return null;
|
|
5676
|
-
const
|
|
6260
|
+
const ref = parseRoomRef(text);
|
|
6261
|
+
const { loadRooms: loadRooms2 } = await import("./room-recommend-L3MWH4JW.js");
|
|
6262
|
+
let rooms = [];
|
|
5677
6263
|
try {
|
|
5678
|
-
|
|
5679
|
-
const byId = rooms.find((room) => room.id === text);
|
|
5680
|
-
if (byId) return { id: byId.id, name: byId.name };
|
|
5681
|
-
const byName = rooms.find((room) => room.name === text);
|
|
5682
|
-
if (byName) return { id: byName.id, name: byName.name };
|
|
6264
|
+
rooms = (await loadRooms2(env, {})).rooms;
|
|
5683
6265
|
} catch {
|
|
6266
|
+
return { id: ref.id ?? "", name: ref.name ?? text, status: "unknown", lookupFailed: true };
|
|
5684
6267
|
}
|
|
5685
|
-
|
|
6268
|
+
const hit = (ref.id ? rooms.find((room) => room.id === ref.id) : void 0) ?? (ref.name ? rooms.find((room) => room.name === ref.name) : void 0);
|
|
6269
|
+
if (hit) return { id: hit.id, name: hit.name, status: hit.status, statusText: hit.statusText };
|
|
6270
|
+
if (ref.id) return { id: ref.id, name: ref.name ?? "", status: "unknown" };
|
|
6271
|
+
return null;
|
|
6272
|
+
}
|
|
6273
|
+
async function resolveRoomValue(env, input) {
|
|
6274
|
+
const text = String(input ?? "").trim();
|
|
6275
|
+
if (!text) return null;
|
|
6276
|
+
const resolved = await resolveAddressRoom(env, text).catch(() => null);
|
|
6277
|
+
if (resolved?.id && !resolved.lookupFailed) {
|
|
6278
|
+
return { id: resolved.id, name: resolved.name || resolved.id };
|
|
6279
|
+
}
|
|
6280
|
+
const ref = parseRoomRef(text);
|
|
6281
|
+
if (ref.id) {
|
|
5686
6282
|
try {
|
|
5687
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
5688
|
-
const detail = await getMeetingOperation2("meeting.eb.room.detail").handler({ id:
|
|
6283
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6284
|
+
const detail = await getMeetingOperation2("meeting.eb.room.detail").handler({ id: ref.id }, env);
|
|
5689
6285
|
const main = detail?.data?.mainTable ?? detail?.data?.data?.mainTable ?? {};
|
|
5690
|
-
const name = String(main.room_name ?? "").trim();
|
|
5691
|
-
if (name) return { id:
|
|
6286
|
+
const name = String(main.room_name ?? "").trim() || ref.name || "";
|
|
6287
|
+
if (name) return { id: ref.id, name };
|
|
5692
6288
|
} catch {
|
|
5693
6289
|
}
|
|
5694
|
-
return { id:
|
|
6290
|
+
return { id: ref.id, name: ref.name || ref.id };
|
|
5695
6291
|
}
|
|
5696
6292
|
return null;
|
|
5697
6293
|
}
|
|
@@ -5718,9 +6314,9 @@ async function shapeBrowserValues(env, values) {
|
|
|
5718
6314
|
idPool.push(...ids);
|
|
5719
6315
|
}
|
|
5720
6316
|
if (idPool.length > 0) {
|
|
5721
|
-
const
|
|
5722
|
-
const toObject = (
|
|
5723
|
-
const toName = (
|
|
6317
|
+
const people = await resolvePersonTokens(env, idPool);
|
|
6318
|
+
const toObject = (token) => people.get(token) ?? { id: token, name: token };
|
|
6319
|
+
const toName = (token) => people.get(token)?.name ?? token;
|
|
5724
6320
|
if (shaped.hrm_members !== void 0 && shaped.hrm_members !== "") {
|
|
5725
6321
|
const ids = String(shaped.hrm_members).split(/[,;,;\s]+/).map((item) => item.trim()).filter((item) => item !== "");
|
|
5726
6322
|
shaped.hrm_members = ids.map(toObject);
|
|
@@ -5737,6 +6333,94 @@ async function shapeBrowserValues(env, values) {
|
|
|
5737
6333
|
shaped.contacter = toObject(id);
|
|
5738
6334
|
readable.contacter = toName(id);
|
|
5739
6335
|
}
|
|
6336
|
+
const unresolved = [...new Set(idPool)].filter((token) => !people.has(token));
|
|
6337
|
+
if (unresolved.length > 0) {
|
|
6338
|
+
notes.push(
|
|
6339
|
+
`\u26A0\uFE0F \u6709 ${unresolved.length} \u4E2A\u4EBA\u5458\u6CA1\u89E3\u6790\u5230\u5458\u5DE5\uFF1A${unresolved.join("\u3001")} \u2014\u2014 \u8868\u5355\u91CC\u7684\u300C\u53C2\u4F1A\u4EBA\u5458/\u53EC\u96C6\u4EBA/\u8054\u7CFB\u4EBA\u300D\u53EF\u80FD\u663E\u793A\u4E0D\u51FA\u6765\u3002\u8BF7\u6539\u4F20\u5458\u5DE5 id\uFF0C\u6216\u786E\u8BA4\u59D3\u540D\u4E0E\u82B1\u540D\u518C\u5B8C\u5168\u4E00\u81F4\u3002`
|
|
6340
|
+
);
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
if (shaped.crm_members !== void 0 && shaped.crm_members !== "") {
|
|
6344
|
+
const rows = [];
|
|
6345
|
+
const push = (idRaw, nameRaw) => {
|
|
6346
|
+
const id = String(idRaw ?? "").trim();
|
|
6347
|
+
const name = String(nameRaw ?? "").trim();
|
|
6348
|
+
if (id === "" && name === "") return;
|
|
6349
|
+
rows.push({ id, name });
|
|
6350
|
+
};
|
|
6351
|
+
const pushToken = (tokenRaw) => {
|
|
6352
|
+
const token = String(tokenRaw ?? "").trim();
|
|
6353
|
+
if (token === "") return;
|
|
6354
|
+
const matched = token.match(/^(.*?)[((]\s*([0-9A-Za-z_-]+)\s*[))]$/);
|
|
6355
|
+
if (matched) {
|
|
6356
|
+
push(matched[2], matched[1]);
|
|
6357
|
+
return;
|
|
6358
|
+
}
|
|
6359
|
+
if (/^\d{8,}$/.test(token)) {
|
|
6360
|
+
push(token, "");
|
|
6361
|
+
return;
|
|
6362
|
+
}
|
|
6363
|
+
push("", token);
|
|
6364
|
+
};
|
|
6365
|
+
const raw = shaped.crm_members;
|
|
6366
|
+
if (Array.isArray(raw)) {
|
|
6367
|
+
for (const item of raw) {
|
|
6368
|
+
if (item && typeof item === "object") {
|
|
6369
|
+
const obj = item;
|
|
6370
|
+
push(obj.id ?? obj.sjID ?? obj.customerId, obj.name ?? obj.mc);
|
|
6371
|
+
} else {
|
|
6372
|
+
for (const token of String(item).split(/[,;,;]+/).map((one) => one.trim()).filter((one) => one !== "")) {
|
|
6373
|
+
pushToken(token);
|
|
6374
|
+
}
|
|
6375
|
+
}
|
|
6376
|
+
}
|
|
6377
|
+
} else if (typeof raw === "object") {
|
|
6378
|
+
const obj = raw;
|
|
6379
|
+
push(obj.id ?? obj.sjID ?? obj.customerId, obj.name ?? obj.mc);
|
|
6380
|
+
} else {
|
|
6381
|
+
for (const token of String(raw).split(/[,;,;]+/).map((item) => item.trim()).filter((item) => item !== "")) {
|
|
6382
|
+
pushToken(token);
|
|
6383
|
+
}
|
|
6384
|
+
}
|
|
6385
|
+
if (rows.length > 0) {
|
|
6386
|
+
const nameOnly = rows.filter((row) => row.id === "" && row.name !== "");
|
|
6387
|
+
if (nameOnly.length > 0) {
|
|
6388
|
+
try {
|
|
6389
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6390
|
+
const search = getMeetingOperation2("meeting.eb.crm.search");
|
|
6391
|
+
for (const row of nameOnly) {
|
|
6392
|
+
const found = await search.handler({ keyword: row.name, limit: 5 }, env).catch(() => null);
|
|
6393
|
+
const items = found?.data?.items ?? [];
|
|
6394
|
+
const hit = items.find((item) => String(item?.name ?? "").trim() === row.name) ?? items[0];
|
|
6395
|
+
const id = String(hit?.customerId ?? "").trim();
|
|
6396
|
+
if (id === "") continue;
|
|
6397
|
+
row.id = id;
|
|
6398
|
+
const fullName = String(hit?.name ?? "").trim();
|
|
6399
|
+
if (fullName !== "") row.name = fullName;
|
|
6400
|
+
}
|
|
6401
|
+
} catch {
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6404
|
+
const unresolved = rows.filter((row) => row.id === "");
|
|
6405
|
+
if (unresolved.length > 0) {
|
|
6406
|
+
throw meetingValidationError(
|
|
6407
|
+
"crm_not_found",
|
|
6408
|
+
`\u53C2\u4F1A\u5BA2\u6237\u6709 ${unresolved.length} \u4E2A\u5728 CRM \u91CC\u67E5\u4E0D\u5230\uFF1A${unresolved.map((row) => row.name).join("\u3001")}\u3002\u8BF7\u786E\u8BA4\u5BA2\u6237\u540D\u79F0\uFF0C\u6216\u5148\u5230\u5BA2\u6237\u8868\u5EFA\u6863\uFF1B\u4E5F\u53EF\u4EE5\u6539\u7528\u300C\u5BA2\u6237\u540D(\u5BA2\u6237id)\u300D\u6216 \`[{id,name}]\` \u4F20 crm_members\u3002`
|
|
6409
|
+
);
|
|
6410
|
+
}
|
|
6411
|
+
shaped.crm_members = rows;
|
|
6412
|
+
readable.crm_members = rows.map((row) => row.name || row.id).join("\u3001");
|
|
6413
|
+
notes.push(`\u53C2\u4F1A\u5BA2\u6237\u6309\u5BA2\u6237\u6D4F\u89C8\u6309\u94AE\u683C\u5F0F\u63D0\u4EA4\uFF1A${rows.length} \u4E2A\u5BA2\u6237`);
|
|
6414
|
+
const missingNames = rows.filter((row) => row.name === "");
|
|
6415
|
+
if (missingNames.length > 0) {
|
|
6416
|
+
throw meetingValidationError(
|
|
6417
|
+
"crm_name_required",
|
|
6418
|
+
`\u53C2\u4F1A\u5BA2\u6237\u6709 ${missingNames.length} \u4E2A\u53EA\u7ED9\u4E86 id\u3001\u6CA1\u6709\u5BA2\u6237\u540D\u79F0\uFF1A${missingNames.map((row) => row.id).join("\u3001")}\u3002\u5BA2\u6237\u6D4F\u89C8\u6309\u94AE\u5FC5\u987B\u5E26\u540D\u79F0\u624D\u80FD\u5199\u5165\uFF08\u53EA\u7ED9 id \u4F1A\u88AB\u670D\u52A1\u7AEF\u9759\u9ED8\u5B58\u6210\u7A7A\u503C\uFF09\u3002\u8BF7\u5148\u7528 \`meeting.eb.crm.search\` \u6309\u5BA2\u6237\u540D\u67E5\u5230 \`{ customerId, name }\`\uFF0C\u518D\u4EE5 \`[{id,name}]\` \u6216\u300C\u5BA2\u6237\u540D(\u5BA2\u6237id)\u300D\u7684\u5F62\u5F0F\u4F20 \`crm_members\`\u3002`
|
|
6419
|
+
);
|
|
6420
|
+
}
|
|
6421
|
+
} else {
|
|
6422
|
+
delete shaped.crm_members;
|
|
6423
|
+
}
|
|
5740
6424
|
}
|
|
5741
6425
|
for (const [key, raw] of Object.entries(values)) {
|
|
5742
6426
|
if (readable[key] !== void 0) continue;
|
|
@@ -5749,6 +6433,195 @@ async function shapeBrowserValues(env, values) {
|
|
|
5749
6433
|
function normalizeFieldName(name) {
|
|
5750
6434
|
return String(name ?? "").replace(/[((][^(())]*[))]/g, "").replace(/[\s\u3000]+/g, "").trim();
|
|
5751
6435
|
}
|
|
6436
|
+
var CRM_DETAIL_COLUMNS = {
|
|
6437
|
+
xm: ["\u59D3\u540D", "\u5BA2\u6237\u59D3\u540D", "\u53C2\u4F1A\u4EBA", "\u53C2\u4F1A\u4EBA\u59D3\u540D"],
|
|
6438
|
+
xb: ["\u6027\u522B"],
|
|
6439
|
+
zw: ["\u804C\u4F4D", "\u804C\u52A1"],
|
|
6440
|
+
sjhm: ["\u624B\u673A\u53F7\u7801", "\u624B\u673A\u53F7", "\u624B\u673A", "\u7535\u8BDD", "\u8054\u7CFB\u7535\u8BDD"],
|
|
6441
|
+
bz: ["\u5907\u6CE8", "\u8BF4\u660E"]
|
|
6442
|
+
};
|
|
6443
|
+
function resolveCrmDetailTarget(fields) {
|
|
6444
|
+
const groups = /* @__PURE__ */ new Map();
|
|
6445
|
+
for (const field of fields) {
|
|
6446
|
+
const sid = String(field.subFormId ?? "").trim();
|
|
6447
|
+
if (!sid) continue;
|
|
6448
|
+
const list = groups.get(sid);
|
|
6449
|
+
if (list) list.push(field);
|
|
6450
|
+
else groups.set(sid, [field]);
|
|
6451
|
+
}
|
|
6452
|
+
let best = null;
|
|
6453
|
+
for (const [subFormId, list] of groups) {
|
|
6454
|
+
const columns = {};
|
|
6455
|
+
const labels = {};
|
|
6456
|
+
for (const [semantic, aliases] of Object.entries(CRM_DETAIL_COLUMNS)) {
|
|
6457
|
+
const hit = list.find((field) => aliases.includes(normalizeFieldName(field.name)));
|
|
6458
|
+
if (!hit) continue;
|
|
6459
|
+
columns[semantic] = hit.id;
|
|
6460
|
+
labels[semantic] = hit.name;
|
|
6461
|
+
}
|
|
6462
|
+
if (!columns.xm) continue;
|
|
6463
|
+
const score = Object.keys(columns).length + (columns.sjhm ? 1 : 0) + (columns.zw ? 1 : 0);
|
|
6464
|
+
if (!best || score > best.score) best = { subFormId, columns, labels, score };
|
|
6465
|
+
}
|
|
6466
|
+
return best ? { subFormId: best.subFormId, columns: best.columns, labels: best.labels } : null;
|
|
6467
|
+
}
|
|
6468
|
+
function detectCrmMentionInText(...texts) {
|
|
6469
|
+
for (const text of texts) {
|
|
6470
|
+
if (typeof text !== "string") continue;
|
|
6471
|
+
const value = text.trim();
|
|
6472
|
+
if (value === "") continue;
|
|
6473
|
+
const hit = /(?:参会|拜访|来访)?客户\s*(?:名称)?\s*(?:是|为|[::])\s*([^\s,,。;;、))]{2,40})/.exec(value);
|
|
6474
|
+
if (hit?.[1]) return hit[1].trim();
|
|
6475
|
+
}
|
|
6476
|
+
return null;
|
|
6477
|
+
}
|
|
6478
|
+
function normalizeCrmDetailRows(raw) {
|
|
6479
|
+
if (raw === void 0 || raw === null || raw === "") return [];
|
|
6480
|
+
const list = Array.isArray(raw) ? raw : [raw];
|
|
6481
|
+
const keyAlias = {
|
|
6482
|
+
xm: "xm",
|
|
6483
|
+
name: "xm",
|
|
6484
|
+
customername: "xm",
|
|
6485
|
+
\u59D3\u540D: "xm",
|
|
6486
|
+
\u5BA2\u6237\u59D3\u540D: "xm",
|
|
6487
|
+
xb: "xb",
|
|
6488
|
+
gender: "xb",
|
|
6489
|
+
sex: "xb",
|
|
6490
|
+
\u6027\u522B: "xb",
|
|
6491
|
+
zw: "zw",
|
|
6492
|
+
title: "zw",
|
|
6493
|
+
position: "zw",
|
|
6494
|
+
job: "zw",
|
|
6495
|
+
\u804C\u4F4D: "zw",
|
|
6496
|
+
\u804C\u52A1: "zw",
|
|
6497
|
+
sjhm: "sjhm",
|
|
6498
|
+
mobile: "sjhm",
|
|
6499
|
+
phone: "sjhm",
|
|
6500
|
+
tel: "sjhm",
|
|
6501
|
+
\u624B\u673A\u53F7\u7801: "sjhm",
|
|
6502
|
+
\u624B\u673A\u53F7: "sjhm",
|
|
6503
|
+
\u7535\u8BDD: "sjhm",
|
|
6504
|
+
\u8054\u7CFB\u7535\u8BDD: "sjhm",
|
|
6505
|
+
bz: "bz",
|
|
6506
|
+
remark: "bz",
|
|
6507
|
+
note: "bz",
|
|
6508
|
+
\u5907\u6CE8: "bz",
|
|
6509
|
+
\u8BF4\u660E: "bz"
|
|
6510
|
+
};
|
|
6511
|
+
const rows = [];
|
|
6512
|
+
for (const item of list) {
|
|
6513
|
+
if (item === void 0 || item === null || typeof item !== "object") continue;
|
|
6514
|
+
const row = {};
|
|
6515
|
+
for (const [key, value] of Object.entries(item)) {
|
|
6516
|
+
const semantic = keyAlias[String(key).trim().toLowerCase()] ?? keyAlias[String(key).trim()];
|
|
6517
|
+
if (!semantic) continue;
|
|
6518
|
+
if (value === void 0 || value === null) continue;
|
|
6519
|
+
const text = String(value).trim();
|
|
6520
|
+
if (text === "") continue;
|
|
6521
|
+
row[semantic] = text;
|
|
6522
|
+
}
|
|
6523
|
+
if (!row.xm && !row.sjhm) continue;
|
|
6524
|
+
rows.push(row);
|
|
6525
|
+
}
|
|
6526
|
+
return rows;
|
|
6527
|
+
}
|
|
6528
|
+
function crmMemberEntriesFromArgs(raw) {
|
|
6529
|
+
const list = Array.isArray(raw) ? raw : raw === void 0 || raw === null || raw === "" ? [] : [raw];
|
|
6530
|
+
const out = [];
|
|
6531
|
+
const push = (idRaw, nameRaw, contactsRaw) => {
|
|
6532
|
+
const id = String(idRaw ?? "").trim();
|
|
6533
|
+
const name = String(nameRaw ?? "").trim();
|
|
6534
|
+
if (id === "" && name === "") return;
|
|
6535
|
+
const contacts = (Array.isArray(contactsRaw) ? contactsRaw : []).map((item) => {
|
|
6536
|
+
const row = item ?? {};
|
|
6537
|
+
return {
|
|
6538
|
+
name: String(row.name ?? row.xm ?? "").trim(),
|
|
6539
|
+
mobile: String(row.mobile ?? row.sjhm ?? row.phone ?? "").trim(),
|
|
6540
|
+
...String(row.dept ?? row.bm ?? "").trim() === "" ? {} : { dept: String(row.dept ?? row.bm).trim() }
|
|
6541
|
+
};
|
|
6542
|
+
}).filter((one) => one.name !== "" || one.mobile !== "");
|
|
6543
|
+
out.push({ id: id === "" ? name : id, name, contacts });
|
|
6544
|
+
};
|
|
6545
|
+
for (const item of list) {
|
|
6546
|
+
if (item && typeof item === "object") {
|
|
6547
|
+
const obj = item;
|
|
6548
|
+
push(obj.customerId ?? obj.sjID ?? obj.id, obj.name ?? obj.mc, obj.contacts ?? obj.lxr);
|
|
6549
|
+
} else {
|
|
6550
|
+
const token = String(item).trim();
|
|
6551
|
+
if (token === "") continue;
|
|
6552
|
+
const matched = token.match(/^(.*?)[((]\s*([0-9A-Za-z_-]+)\s*[))]$/);
|
|
6553
|
+
if (matched) push(matched[2], matched[1], void 0);
|
|
6554
|
+
else push(token, "", void 0);
|
|
6555
|
+
}
|
|
6556
|
+
}
|
|
6557
|
+
return out;
|
|
6558
|
+
}
|
|
6559
|
+
function crmContactsToDetailRows(entries) {
|
|
6560
|
+
const rows = [];
|
|
6561
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6562
|
+
for (const entry of entries) {
|
|
6563
|
+
for (const contact of entry.contacts) {
|
|
6564
|
+
const xm = contact.name.trim();
|
|
6565
|
+
const sjhm = contact.mobile.trim();
|
|
6566
|
+
if (xm === "" && sjhm === "") continue;
|
|
6567
|
+
const key = `${xm}|${sjhm}`;
|
|
6568
|
+
if (seen.has(key)) continue;
|
|
6569
|
+
seen.add(key);
|
|
6570
|
+
const row = { xm: xm === "" ? sjhm : xm };
|
|
6571
|
+
if (sjhm !== "") row.sjhm = sjhm;
|
|
6572
|
+
if (contact.dept && contact.dept.trim() !== "") row.bz = `\u90E8\u95E8\uFF1A${contact.dept.trim()}`;
|
|
6573
|
+
rows.push(row);
|
|
6574
|
+
}
|
|
6575
|
+
}
|
|
6576
|
+
return rows;
|
|
6577
|
+
}
|
|
6578
|
+
async function resolveAutoCrmDetailRows(env, raw) {
|
|
6579
|
+
const entries = crmMemberEntriesFromArgs(raw);
|
|
6580
|
+
const missing = [];
|
|
6581
|
+
if (entries.length > 0) {
|
|
6582
|
+
try {
|
|
6583
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6584
|
+
const search = getMeetingOperation2("meeting.eb.crm.search");
|
|
6585
|
+
for (const entry of entries) {
|
|
6586
|
+
const keyword = (entry.name || entry.id).trim();
|
|
6587
|
+
if (keyword === "") {
|
|
6588
|
+
missing.push(entry.id);
|
|
6589
|
+
continue;
|
|
6590
|
+
}
|
|
6591
|
+
const searchOnce = async (kw) => {
|
|
6592
|
+
const found = await search.handler({ keyword: kw, limit: 5 }, env).catch(() => null);
|
|
6593
|
+
const items = found?.data?.items ?? [];
|
|
6594
|
+
const hit = items.find((item) => String(item?.customerId ?? "") === entry.id) ?? items[0];
|
|
6595
|
+
return hit?.contacts ?? [];
|
|
6596
|
+
};
|
|
6597
|
+
let live = await searchOnce(keyword);
|
|
6598
|
+
if (live.length === 0 && keyword.includes("--")) {
|
|
6599
|
+
const short = keyword.split("--")[0].trim();
|
|
6600
|
+
if (short !== "") live = await searchOnce(short);
|
|
6601
|
+
}
|
|
6602
|
+
if (live.length === 0) {
|
|
6603
|
+
if (entry.contacts.length === 0) missing.push(entry.name || entry.id);
|
|
6604
|
+
continue;
|
|
6605
|
+
}
|
|
6606
|
+
const keyOf = (one) => `${String(one.name ?? "").trim()}|${String(one.mobile ?? "").trim()}`;
|
|
6607
|
+
const merged = /* @__PURE__ */ new Map();
|
|
6608
|
+
for (const one of live) merged.set(keyOf(one), one);
|
|
6609
|
+
for (const one of entry.contacts) {
|
|
6610
|
+
const key = keyOf(one);
|
|
6611
|
+
const base = merged.get(key);
|
|
6612
|
+
merged.set(key, base ? { ...base, ...one } : one);
|
|
6613
|
+
}
|
|
6614
|
+
entry.contacts = [...merged.values()];
|
|
6615
|
+
}
|
|
6616
|
+
} catch {
|
|
6617
|
+
}
|
|
6618
|
+
}
|
|
6619
|
+
return {
|
|
6620
|
+
rows: crmContactsToDetailRows(entries),
|
|
6621
|
+
customers: entries.map((entry) => entry.name || entry.id).filter((one) => one !== ""),
|
|
6622
|
+
missing
|
|
6623
|
+
};
|
|
6624
|
+
}
|
|
5752
6625
|
function mapFields(fields, values, preferred = {}) {
|
|
5753
6626
|
const byName = new Map(fields.map((field) => [field.name.trim(), field]));
|
|
5754
6627
|
const byId = new Map(fields.map((field) => [field.id, field]));
|
|
@@ -5794,6 +6667,90 @@ function mapFields(fields, values, preferred = {}) {
|
|
|
5794
6667
|
}
|
|
5795
6668
|
return { main, mapped, unmapped, resolved };
|
|
5796
6669
|
}
|
|
6670
|
+
var PREVIEW_PERSON_FIELD_RE = /^(召集人|联系人|参会人员|会议创建人|主讲人|负责人|费用承担人)$/;
|
|
6671
|
+
async function decoratePreviewPersonNames(env, main, fields, known = /* @__PURE__ */ new Map()) {
|
|
6672
|
+
const targets = fields.filter((field) => PREVIEW_PERSON_FIELD_RE.test(String(field?.name ?? "").trim()));
|
|
6673
|
+
if (targets.length === 0) return main;
|
|
6674
|
+
const ID_ONLY_RE = /^\d{8,}$/;
|
|
6675
|
+
const missingNameId = (value) => {
|
|
6676
|
+
if (typeof value === "string") return ID_ONLY_RE.test(value.trim()) ? value.trim() : null;
|
|
6677
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
6678
|
+
const obj = value;
|
|
6679
|
+
const id = String(obj.id ?? "").trim();
|
|
6680
|
+
const name = String(obj.name ?? "").trim();
|
|
6681
|
+
if (id !== "" && (name === "" || name === id)) return id;
|
|
6682
|
+
}
|
|
6683
|
+
return null;
|
|
6684
|
+
};
|
|
6685
|
+
const ids = /* @__PURE__ */ new Set();
|
|
6686
|
+
for (const field of targets) {
|
|
6687
|
+
const value = main[field.id];
|
|
6688
|
+
const one = missingNameId(value);
|
|
6689
|
+
if (one) ids.add(one);
|
|
6690
|
+
else if (Array.isArray(value)) for (const item of value) {
|
|
6691
|
+
const hit = missingNameId(item);
|
|
6692
|
+
if (hit) ids.add(hit);
|
|
6693
|
+
}
|
|
6694
|
+
}
|
|
6695
|
+
if (ids.size === 0) return main;
|
|
6696
|
+
let names = new Map(known);
|
|
6697
|
+
const unknown = [...ids].filter((id) => !names.has(id));
|
|
6698
|
+
if (unknown.length > 0) {
|
|
6699
|
+
try {
|
|
6700
|
+
const resolved = await resolveEmployeeNames(env, unknown);
|
|
6701
|
+
for (const [id, name] of resolved) names.set(id, name);
|
|
6702
|
+
} catch {
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
if (names.size === 0) return main;
|
|
6706
|
+
const rename = (value) => {
|
|
6707
|
+
const one = missingNameId(value);
|
|
6708
|
+
if (one) return names.get(one) ?? value;
|
|
6709
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
6710
|
+
const obj = value;
|
|
6711
|
+
const id = String(obj.id ?? "").trim();
|
|
6712
|
+
const name = names.get(id);
|
|
6713
|
+
if (name) return { ...obj, name };
|
|
6714
|
+
}
|
|
6715
|
+
return value;
|
|
6716
|
+
};
|
|
6717
|
+
const decorated = { ...main };
|
|
6718
|
+
for (const field of targets) {
|
|
6719
|
+
const value = decorated[field.id];
|
|
6720
|
+
decorated[field.id] = Array.isArray(value) ? value.map(rename) : rename(value);
|
|
6721
|
+
}
|
|
6722
|
+
return decorated;
|
|
6723
|
+
}
|
|
6724
|
+
function renderFormPreview(fields, main) {
|
|
6725
|
+
const fmt = (value) => {
|
|
6726
|
+
if (value === void 0 || value === null) return "\u2014";
|
|
6727
|
+
if (Array.isArray(value)) {
|
|
6728
|
+
const parts = value.map((one) => fmt(one)).filter((one) => one !== "\u2014");
|
|
6729
|
+
return parts.length > 0 ? parts.join("\u3001") : "\u2014";
|
|
6730
|
+
}
|
|
6731
|
+
if (typeof value === "object") {
|
|
6732
|
+
const obj = value;
|
|
6733
|
+
const name = String(obj.name ?? obj.mc ?? "").trim();
|
|
6734
|
+
if (name !== "") return name.replace(/\|/gu, "/");
|
|
6735
|
+
const id = String(obj.id ?? obj.customerId ?? obj.sjID ?? "").trim();
|
|
6736
|
+
return id === "" ? "\u2014" : id;
|
|
6737
|
+
}
|
|
6738
|
+
const text = String(value).trim();
|
|
6739
|
+
return text === "" ? "\u2014" : text.replace(/\|/gu, "/").replace(/\r?\n/gu, " ");
|
|
6740
|
+
};
|
|
6741
|
+
const lines = ["| \u5B57\u6BB5 | \u503C |", "| --- | --- |"];
|
|
6742
|
+
const known = /* @__PURE__ */ new Set();
|
|
6743
|
+
for (const field of fields) {
|
|
6744
|
+
known.add(field.id);
|
|
6745
|
+
if (!(field.id in main)) continue;
|
|
6746
|
+
lines.push(`| ${String(field.name).replace(/\|/gu, "/")} | ${fmt(main[field.id])} |`);
|
|
6747
|
+
}
|
|
6748
|
+
for (const [id, value] of Object.entries(main)) {
|
|
6749
|
+
if (known.has(id)) continue;
|
|
6750
|
+
lines.push(`| ${id} | ${fmt(value)} |`);
|
|
6751
|
+
}
|
|
6752
|
+
return lines.join("\n");
|
|
6753
|
+
}
|
|
5797
6754
|
function flowFieldCacheDir(env) {
|
|
5798
6755
|
const configured = env?.ctx?.config?.path?.();
|
|
5799
6756
|
const root = configured ? resolve5(String(configured), "..") : process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve5(homedir(), ".weaver-work-cli");
|
|
@@ -5957,7 +6914,7 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
5957
6914
|
resource: "eb",
|
|
5958
6915
|
method: "meeting.eb.meeting.create.flow.prepare",
|
|
5959
6916
|
action: "meeting.eb.meeting.create.flow.prepare",
|
|
5960
|
-
summary:
|
|
6917
|
+
summary: '\u6D41\u7A0B\u5EFA\u4F1A\uFF08\u51C6\u5907\uFF09\uFF1A\u7528\u56FA\u5316\u6D41\u7A0B\u5019\u9009\u9010\u4E2A\u63A2\u6D4B\u53D1\u8D77\u6743\u9650 \u2014\u2014 \u4EC5 1 \u4E2A\u53EF\u53D1\u8D77\u5C31\u81EA\u52A8\u7528\u5B83\u3001\u591A\u4E2A\u90FD\u53EF\u53D1\u8D77\u5219\u8FD4\u56DE\u9009\u9879\u8BA9\u7528\u6237\u9009\u3001\u90FD\u4E0D\u53EF\u53D1\u8D77\u62A5\u300C\u6CA1\u6709\u53D1\u8D77\u6743\u9650\u300D\uFF1B\u4E0D\u4F20 begin_datetime \u65F6\u81EA\u52A8\u63A8\u8350\u300C\u4EBA+\u4F1A\u8BAE\u5BA4\u90FD\u7A7A\u95F2\u300D\u7684\u65F6\u6BB5\u3002\u53EA\u51FA\u9884\u89C8\u4E0E\u786E\u8BA4\u7968\u636E\uFF0C\u4E0D\u63D0\u4EA4\u3002\u26A0\uFE0F \u7528\u6237\u63D0\u5230\u5BA2\u6237\u540D\uFF08\u300C\u5BA2\u6237\u662F X\u300D\uFF09\u65F6**\u5FC5\u987B\u5148** meeting.eb.crm.search {"keyword":"X"} \u62FF customerId\uFF0C\u518D\u4F20 crm_members:[{id,name}]\uFF1B\u53EA\u628A\u5BA2\u6237\u540D\u5199\u8FDB\u4F1A\u8BAE\u540D\u79F0/\u5185\u5BB9\uFF0C\u8868\u5355\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u5C31\u662F\u7A7A\u7684',
|
|
5961
6918
|
capability: "eb.meeting",
|
|
5962
6919
|
risk: "read-before-write",
|
|
5963
6920
|
requiresConfirmation: true,
|
|
@@ -5977,8 +6934,22 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
5977
6934
|
customize_address: { type: "string", description: "\u81EA\u5B9A\u4E49\u4F1A\u8BAE\u5730\u70B9" },
|
|
5978
6935
|
hrm_members: { type: "string", description: "\u53C2\u4F1A\u4EBA\u5458\uFF08\u9017\u53F7\u5206\u9694\u5458\u5DE5 id \u6216\u59D3\u540D\uFF0C\u6309\u6D41\u7A0B\u8868\u5355\u8981\u6C42\uFF09" },
|
|
5979
6936
|
total_member: { type: "number", description: "\u53C2\u4F1A\u4EBA\u6570" },
|
|
5980
|
-
|
|
5981
|
-
|
|
6937
|
+
crm_members: {
|
|
6938
|
+
oneOf: [{ type: "string" }, { type: "array", items: { oneOf: [{ type: "string" }, { type: "object" }] } }],
|
|
6939
|
+
description: "\u53C2\u4F1A\u5BA2\u6237\uFF1A**\u5FC5\u987B\u5E26\u5BA2\u6237\u540D\u79F0**\uFF0C\u5199\u6CD5 `[{id,name}]` \u6216\u300C\u5BA2\u6237\u540D(\u5BA2\u6237id)\u300D\u6216\u9017\u53F7\u5206\u9694\u7684\u8FD9\u4E24\u79CD\u3002\u5BA2\u6237\u5148\u4ECE `meeting.eb.crm.search` \u6309\u5BA2\u6237\u540D\u67E5\u51FA\uFF08\u5165\u53C2 custom_name\uFF0C\u51FA\u53C2 items[].customerId / name\uFF09\uFF0C\u8BE5\u67E5\u8BE2**\u4E00\u6B21\u53EA\u56DE\u9996\u4E2A\u5339\u914D** \u21D2 exact=false \u65F6\u5FC5\u987B\u5148\u8BA9\u7528\u6237\u786E\u8BA4\u5BA2\u6237\u540D\u518D\u5199\u8FD9\u4E2A\u5B57\u6BB5\u3002\u26D4 \u53EA\u7ED9 id \u4E0D\u7ED9\u540D\u79F0\u4F1A\u88AB\u62D2\u7EDD\uFF08\u5BA2\u6237\u6D4F\u89C8\u6309\u94AE\u6309\u540D\u79F0\u843D\u503C\uFF0C\u53EA\u7ED9 id \u4F1A\u9759\u9ED8\u5B58\u6210\u7A7A\uFF09"
|
|
6940
|
+
},
|
|
6941
|
+
crm_member_count: { type: "number", description: "\u5E94\u5230\u5BA2\u6237\u6570\uFF1B\u4E0D\u4F20\u5219\u6309 crm_members \u6761\u6570\u81EA\u52A8\u7B97" },
|
|
6942
|
+
crm_member_details: {
|
|
6943
|
+
type: "array",
|
|
6944
|
+
description: '\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6\uFF08\u5BBF\u4E3B\u8868\u5355\u91CC\u7684\u660E\u7EC6\u8868\uFF0C\u5217 \u59D3\u540D/\u6027\u522B/\u804C\u4F4D/\u624B\u673A\u53F7\u7801/\u5907\u6CE8\uFF09\uFF1A\u6BCF\u884C `{"xm":"\u5F20\u4E09","xb":"\u7537","zw":"\u7ECF\u7406","sjhm":"138...","bz":""}`\uFF0C\u4E5F\u63A5\u53D7\u4E2D\u6587\u952E\uFF08\u59D3\u540D/\u6027\u522B/\u804C\u4F4D/\u624B\u673A\u53F7\u7801/\u5907\u6CE8\uFF09\u3002\u5217\u5B57\u6BB5 id \u7531 CLI \u4ECE\u8868\u5355\u91CC\u6309\u5217\u540D\u53CD\u67E5\uFF0C\u4E0D\u7528\u4F20\u3002\u26A0\uFE0F \u8BE5\u660E\u7EC6\u8868\u5FC5\u987B\u5728\u53D1\u8D77\u8282\u70B9\u5E03\u5C40\u91CC\uFF08\u5426\u5219 CLI \u4F1A\u63D0\u793A"\u8868\u5355\u91CC\u6CA1\u6709\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6"\u5E76\u5FFD\u7565\u8FD9\u4E9B\u884C\uFF09\u26D4 \u9ED8\u8BA4\u4E0D\u751F\u6548\uFF1A\u5BA2\u6237\u8054\u7CFB\u4EBA\u7531 CLI \u6309 CRM \u5168\u91CF\u81EA\u52A8\u5E26\u5165\uFF0C\u8FD9\u91CC\u53EA\u5728 crm_detail_mode:"only" \u65F6\u624D\u7528\u6765"\u53EA\u5199\u8FD9\u51E0\u4F4D"',
|
|
6945
|
+
items: { type: "object" }
|
|
6946
|
+
},
|
|
6947
|
+
crm_detail_mode: {
|
|
6948
|
+
type: "string",
|
|
6949
|
+
description: '\u660E\u7EC6\u884C\u53E3\u5F84\uFF1A\u4E0D\u4F20\uFF08\u9ED8\u8BA4\uFF09= \u6309 CRM \u628A\u8BE5\u5BA2\u6237**\u5168\u90E8**\u8054\u7CFB\u4EBA\u81EA\u52A8\u5199\u5165\u300C\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6\u300D\uFF08\u4E00\u4EBA\u4E00\u884C\uFF0C\u4E0D\u7528\u95EE\u7528\u6237\u9009\u54EA\u4F4D\uFF09\uFF1B\u4F20 "only" = \u53EA\u5199 crm_member_details \u91CC\u70B9\u540D\u7684\u8FD9\u51E0\u4F4D'
|
|
6950
|
+
},
|
|
6951
|
+
caller: { type: "string", description: "\u53EC\u96C6\u4EBA\uFF08\u5458\u5DE5 id \u6216\u59D3\u540D\uFF09\u3002\u7F3A\u7701 = \u5F53\u524D\u767B\u5F55\u4EBA\uFF0C\u4E0D\u7528\u4F20\uFF1B\u53EA\u6709\u6307\u5B9A\u522B\u4EBA\u5F53\u53EC\u96C6\u4EBA\u624D\u4F20" },
|
|
6952
|
+
contacter: { type: "string", description: "\u8054\u7CFB\u4EBA\uFF08\u5458\u5DE5 id \u6216\u59D3\u540D\uFF09\u3002\u7F3A\u7701 = \u5F53\u524D\u767B\u5F55\u4EBA\uFF0C\u4E0D\u7528\u4F20\uFF1B\u53EA\u6709\u6307\u5B9A\u522B\u4EBA\u5F53\u8054\u7CFB\u4EBA\u624D\u4F20" },
|
|
5982
6953
|
mt_type: {
|
|
5983
6954
|
type: "string",
|
|
5984
6955
|
description: "\u4F1A\u8BAE\u7C7B\u578B\uFF1A\u53EF\u4F20\u7C7B\u578B\u540D\u79F0\u6216 id\uFF08\u5148\u7528 `meeting.eb.type.list` \u67E5\u6709\u54EA\u4E9B\uFF09\u3002**\u5F88\u591A\u79DF\u6237\u7684\u6D41\u7A0B\u8868\u5355\u628A\u300C\u4F1A\u8BAE\u7C7B\u578B\u300D\u8BBE\u4E3A\u5FC5\u586B**\uFF0C\u4E0D\u4F20\u4F1A\u88AB `workflow.createRequest` \u6253\u56DE\u7F3A\u5B57\u6BB5"
|
|
@@ -6034,7 +7005,7 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6034
7005
|
let endText = String(args.end_datetime ?? "").trim();
|
|
6035
7006
|
const rawMembers = String(args.hrm_members ?? "").split(/[,;,;\s]+/).map((item) => item.trim()).filter((item) => item !== "");
|
|
6036
7007
|
const nameLike = rawMembers.filter((item) => !/^\d+$/.test(item));
|
|
6037
|
-
const nameToId = nameLike.length > 0 ? await import("./schedule-
|
|
7008
|
+
const nameToId = nameLike.length > 0 ? await import("./schedule-UASAVDVD.js").then((m) => m.resolveMemberIdsByName(env, nameLike)).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
|
|
6038
7009
|
const memberIds = rawMembers.map((item) => nameToId.get(item) ?? item);
|
|
6039
7010
|
const timeConfirmed = args.timeConfirmed === true;
|
|
6040
7011
|
const callerWorkflowId = String(args.workflowId ?? "").trim();
|
|
@@ -6049,7 +7020,7 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6049
7020
|
if (!beginHasTime || !timeConfirmed) {
|
|
6050
7021
|
const day2 = /^\d{4}-\d{2}-\d{2}/.test(beginText) ? beginText.slice(0, 10) : String(args.dateFrom ?? "").trim().slice(0, 10) || tomorrowIso();
|
|
6051
7022
|
const duration = Number(args.durationMinutes) > 0 ? Math.round(Number(args.durationMinutes)) : 60;
|
|
6052
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
7023
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6053
7024
|
const suggested = await getMeetingOperation2("meeting.eb.meeting.create.suggest").handler(
|
|
6054
7025
|
{
|
|
6055
7026
|
dateFrom: day2,
|
|
@@ -6116,6 +7087,13 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6116
7087
|
enrichFailures.push(`${label}\u672A\u5B8C\u6210\uFF1A${String(error?.message ?? error).slice(0, 120)}`);
|
|
6117
7088
|
return null;
|
|
6118
7089
|
};
|
|
7090
|
+
const needSelfPerson = String(args.caller ?? "").trim() === "" || String(args.contacter ?? "").trim() === "";
|
|
7091
|
+
const autoPerson = applySelfPersonDefaults(
|
|
7092
|
+
args,
|
|
7093
|
+
needSelfPerson ? await resolveSelfPerson(env) : null
|
|
7094
|
+
);
|
|
7095
|
+
const autoFilledPerson = autoPerson.filled;
|
|
7096
|
+
const selfPersonWarning = autoPerson.warning;
|
|
6119
7097
|
const declaredTotal = Number(args.total_member) > 0 ? Number(args.total_member) : null;
|
|
6120
7098
|
const callerToken = String(args.caller ?? "").trim();
|
|
6121
7099
|
const callerInMembers = callerToken !== "" && (rawMembers.includes(callerToken) || memberIds.includes(callerToken));
|
|
@@ -6129,17 +7107,20 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6129
7107
|
topN: 3
|
|
6130
7108
|
}).catch(noteFailure("\u4F1A\u8BAE\u5BA4\u63A8\u8350")) : Promise.resolve(null);
|
|
6131
7109
|
const addressId = String(addressInput ?? "").trim();
|
|
6132
|
-
const addressIsRoomId = /^\d+$/.test(addressId);
|
|
6133
7110
|
const roomConfirmed = args.roomConfirmed === true;
|
|
6134
|
-
const roomConflictTask = enrich && beginText && endText &&
|
|
6135
|
-
const
|
|
6136
|
-
|
|
6137
|
-
|
|
7111
|
+
const roomConflictTask = enrich && beginText && endText && addressId !== "" ? (async () => {
|
|
7112
|
+
const room = await resolveAddressRoom(env, addressId);
|
|
7113
|
+
if (!room) return { unresolved: true, input: addressId };
|
|
7114
|
+
if (!room.id || room.lookupFailed || room.status !== "0") return { room };
|
|
7115
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
7116
|
+
const result = await getMeetingOperation2("meeting.eb.conflict.room").handler(
|
|
7117
|
+
{ beginDatetime: beginText, endDatetime: endText, address: room.id },
|
|
6138
7118
|
env
|
|
6139
7119
|
);
|
|
7120
|
+
return { room, ...result?.data ?? {} };
|
|
6140
7121
|
})().catch(noteFailure("\u4F1A\u8BAE\u5BA4**\u5360\u7528**\u68C0\u6D4B")) : Promise.resolve(null);
|
|
6141
7122
|
const conflictTask = enrich && beginText && endText && memberIds.length > 0 ? (async () => {
|
|
6142
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
7123
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6143
7124
|
return getMeetingOperation2("meeting.eb.conflict.member").handler(
|
|
6144
7125
|
{ beginDatetime: beginText, endDatetime: endText, hrmMembers: memberIds.join(",") },
|
|
6145
7126
|
env
|
|
@@ -6194,11 +7175,51 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6194
7175
|
value: { id: candidate.id, name: candidate.name, roomConfirmed: true },
|
|
6195
7176
|
reason: candidate.reasons.join("\uFF1B")
|
|
6196
7177
|
}));
|
|
6197
|
-
const roomConflictData = roomConflict
|
|
7178
|
+
const roomConflictData = roomConflict;
|
|
7179
|
+
const resolvedAddress = roomConflictData?.room ?? null;
|
|
7180
|
+
const resolvedAddressId = resolvedAddress?.id || addressId;
|
|
7181
|
+
const addressDisplay = resolvedAddress?.name || addressId;
|
|
7182
|
+
if (roomConflictData?.unresolved === true) {
|
|
7183
|
+
decisions.roomNotFound = { input: addressId, candidates: roomOptions.length };
|
|
7184
|
+
if (roomOptions.length > 0) decisions.roomOptions = roomOptions;
|
|
7185
|
+
return meetingSuccess("meeting.eb.meeting.create.flow.prepare", {
|
|
7186
|
+
status: "NEEDS_SELECTION",
|
|
7187
|
+
selectionType: "room",
|
|
7188
|
+
ui: { component: "choice", multiple: false, recommendedKey: "R1" },
|
|
7189
|
+
message: `\u6CA1\u627E\u5230\u540D\u4E3A\u300C${addressId}\u300D\u7684\u4F1A\u8BAE\u5BA4\uFF08\u4F1A\u8BAE\u5BA4\u53F0\u8D26\u91CC\u6CA1\u6709\u8FD9\u4E2A\u540D\u5B57\uFF09\uFF0C\u672C\u6B21**\u6CA1\u6709\u63D0\u4EA4**\u3002` + (roomOptions.length > 0 ? `\u8BF7\u4ECE\u4E0B\u9762 ${roomOptions.length} \u4E2A\u5728\u8BE5\u65F6\u6BB5\u7A7A\u95F2\u7684\u4F1A\u8BAE\u5BA4\u91CC\u9009\u4E00\u95F4\uFF0C\u6216\u6838\u5BF9\u4E00\u4E0B\u4F1A\u8BAE\u5BA4\u540D\u79F0` : "\u8BE5\u65F6\u6BB5\u4E5F\u6CA1\u6709\u53EF\u7528\u7684\u7A7A\u95F2\u4F1A\u8BAE\u5BA4\uFF0C\u8BF7\u6539\u4F1A\u8BAE\u65F6\u95F4\u6216\u6539\u7EBF\u4E0A\u4F1A\u8BAE\uFF08allowNoRoom: true\uFF09"),
|
|
7190
|
+
workflowPending: true,
|
|
7191
|
+
options: roomOptions,
|
|
7192
|
+
recommended: roomOptions[0]?.value ?? null,
|
|
7193
|
+
roomNotFound: decisions.roomNotFound,
|
|
7194
|
+
hint: "\u9009\u5B9A\u540E\u628A value **\u6574\u4F53**\u539F\u6837\u5E26\u56DE\uFF08\u542B roomConfirmed: true\uFF09\uFF1B\u6838\u5BF9\u540D\u79F0\u53EF\u7528 `meeting.eb.room.list` \u770B\u5168\u91CF\u6E05\u5355"
|
|
7195
|
+
}, {
|
|
7196
|
+
warnings: [
|
|
7197
|
+
`\u4F1A\u8BAE\u5BA4\u300C${addressId}\u300D\u5728\u53F0\u8D26\u91CC\u4E0D\u5B58\u5728\uFF0C\u5DF2\u62E6\u4E0B\u672A\u63D0\u4EA4\u3002`,
|
|
7198
|
+
'\u26D4 \u4E0D\u8981\u628A\u5B83\u5F53\u6210"\u7528\u6237\u6307\u5B9A\u7684\u623F\u95F4"\u5199\u8FDB\u786E\u8BA4\u6458\u8981 \u2014\u2014 \u8FD9\u95F4\u623F\u6839\u672C\u6CA1\u6709\u88AB\u89E3\u6790\u51FA\u6765\u3002'
|
|
7199
|
+
]
|
|
7200
|
+
});
|
|
7201
|
+
}
|
|
7202
|
+
if (resolvedAddress && resolvedAddress.status === "1") {
|
|
7203
|
+
decisions.roomSealed = { id: resolvedAddress.id, name: resolvedAddress.name };
|
|
7204
|
+
if (roomOptions.length > 0) decisions.roomOptions = roomOptions;
|
|
7205
|
+
return meetingSuccess("meeting.eb.meeting.create.flow.prepare", {
|
|
7206
|
+
status: "NEEDS_SELECTION",
|
|
7207
|
+
selectionType: "room",
|
|
7208
|
+
ui: { component: "choice", multiple: false, recommendedKey: "R1" },
|
|
7209
|
+
message: `\u4F1A\u8BAE\u5BA4\u300C${resolvedAddress.name}\u300D\u5F53\u524D\u662F**\u5C01\u5B58**\u72B6\u6001\uFF08\u4E0D\u53EF\u9884\u7EA6\uFF09\uFF0C\u672C\u6B21**\u6CA1\u6709\u63D0\u4EA4**\u3002` + (roomOptions.length > 0 ? "\u8BF7\u6539\u7528\u4E0B\u9762\u7A7A\u95F2\u7684\u4F1A\u8BAE\u5BA4" : "\u8BE5\u65F6\u6BB5\u6CA1\u6709\u5176\u5B83\u53EF\u7528\u4F1A\u8BAE\u5BA4\uFF0C\u8BF7\u6539\u4F1A\u8BAE\u65F6\u95F4"),
|
|
7210
|
+
workflowPending: true,
|
|
7211
|
+
options: roomOptions,
|
|
7212
|
+
recommended: roomOptions[0]?.value ?? null,
|
|
7213
|
+
roomSealed: decisions.roomSealed
|
|
7214
|
+
}, {
|
|
7215
|
+
warnings: [`\u4F1A\u8BAE\u5BA4\u300C${resolvedAddress.name}\u300D\uFF08${resolvedAddress.id}\uFF09\u5DF2\u5C01\u5B58\uFF0C\u4E0D\u53EF\u9884\u7EA6\uFF0C\u5DF2\u62E6\u4E0B\u672A\u63D0\u4EA4\u3002`]
|
|
7216
|
+
});
|
|
7217
|
+
}
|
|
6198
7218
|
if (addressInput && roomConfirmed && roomConflictData?.hasConflict === true) {
|
|
6199
7219
|
const busy = Array.isArray(roomConflictData.conflicts) ? roomConflictData.conflicts : [];
|
|
6200
7220
|
decisions.roomConflict = {
|
|
6201
|
-
address:
|
|
7221
|
+
address: resolvedAddressId,
|
|
7222
|
+
addressName: addressDisplay,
|
|
6202
7223
|
hasConflict: true,
|
|
6203
7224
|
conflicts: busy,
|
|
6204
7225
|
verdict: roomConflictData.verdict ?? "conflict"
|
|
@@ -6208,15 +7229,16 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6208
7229
|
status: "NEEDS_SELECTION",
|
|
6209
7230
|
selectionType: "room_conflict",
|
|
6210
7231
|
ui: { component: "choice", multiple: false, recommendedKey: "R1" },
|
|
6211
|
-
message: `\u4F60\u6307\u5B9A\u7684\u4F1A\u8BAE\u5BA4\u5728 ${beginText}~${endText} \u5DF2\u88AB\u5360\u7528\uFF08${busy.length} \u6761\u5360\u7528\u8BB0\u5F55\uFF09\uFF0C\u672C\u6B21**\u6CA1\u6709\u63D0\u4EA4**\u3002\u8BF7\u6539\u7528\u4E0B\u9762\u7A7A\u95F2\u7684\u4F1A\u8BAE\u5BA4\uFF0C\u6216\u8C03\u6574\u4F1A\u8BAE\u65F6\u95F4`,
|
|
7232
|
+
message: `\u4F60\u6307\u5B9A\u7684\u4F1A\u8BAE\u5BA4\u300C${addressDisplay}\u300D\u5728 ${beginText}~${endText} \u5DF2\u88AB\u5360\u7528\uFF08${busy.length} \u6761\u5360\u7528\u8BB0\u5F55\uFF09\uFF0C\u672C\u6B21**\u6CA1\u6709\u63D0\u4EA4**\u3002\u8BF7\u6539\u7528\u4E0B\u9762\u7A7A\u95F2\u7684\u4F1A\u8BAE\u5BA4\uFF0C\u6216\u8C03\u6574\u4F1A\u8BAE\u65F6\u95F4`,
|
|
6212
7233
|
workflowPending: true,
|
|
6213
7234
|
options: roomOptions,
|
|
6214
7235
|
recommended: roomOptions[0]?.value ?? null,
|
|
6215
7236
|
conflicts: busy,
|
|
7237
|
+
roomConflict: decisions.roomConflict,
|
|
6216
7238
|
hint: "\u9009\u5B9A\u540E\u628A value.id \u4F5C\u4E3A address \u91CD\u65B0\u8C03\u7528\uFF1B\u8981\u6539\u65F6\u95F4\u5C31\u540C\u65F6\u4F20\u65B0\u7684 begin_datetime/end_datetime"
|
|
6217
7239
|
}, {
|
|
6218
7240
|
warnings: [
|
|
6219
|
-
`\u4F1A\u8BAE\u5BA4
|
|
7241
|
+
`\u4F1A\u8BAE\u5BA4\u300C${addressDisplay}\u300D\uFF08${resolvedAddressId}\uFF09\u5728\u8BE5\u65F6\u6BB5\u5DF2\u6709 ${busy.length} \u6761\u5360\u7528\uFF0C\u5DF2\u62E6\u4E0B\u672A\u63D0\u4EA4\u3002`,
|
|
6220
7242
|
roomOptions.length > 0 ? `\u5DF2\u6309\u4EBA\u6570/\u5E38\u7528/\u7A7A\u95F2\u7ED9\u51FA ${roomOptions.length} \u4E2A\u66FF\u4EE3\u4F1A\u8BAE\u5BA4\uFF08R1 \u4E3A\u9996\u9009\uFF09\u3002` : "\u8BE5\u65F6\u6BB5\u6CA1\u6709\u53EF\u66FF\u4EE3\u7684\u7A7A\u95F2\u4F1A\u8BAE\u5BA4\uFF0C\u5EFA\u8BAE\u8C03\u6574\u4F1A\u8BAE\u65F6\u95F4\u6216\u6539\u7EBF\u4E0A\u4F1A\u8BAE\uFF08allowNoRoom: true\uFF09\u3002"
|
|
6221
7243
|
]
|
|
6222
7244
|
});
|
|
@@ -6232,21 +7254,21 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6232
7254
|
const needRoomPick = !addressInput || !roomConfirmed;
|
|
6233
7255
|
let pickOptions = roomOptions;
|
|
6234
7256
|
if (addressInput && !roomConfirmed) {
|
|
6235
|
-
const hit = roomOptions.find((item) => String(item.value?.id) ===
|
|
7257
|
+
const hit = roomOptions.find((item) => String(item.value?.id) === resolvedAddressId);
|
|
6236
7258
|
const specified = hit ? { ...hit, label: `${hit.label}\uFF08\u4F60\u6307\u5B9A\u7684\uFF0C\u5F85\u786E\u8BA4\uFF09`, value: { ...hit.value, roomConfirmed: true } } : {
|
|
6237
7259
|
key: "R0",
|
|
6238
|
-
label: `${
|
|
6239
|
-
value: { ...
|
|
7260
|
+
label: `${addressDisplay}\uFF08\u4F60\u6307\u5B9A\u7684\uFF0C\u5F85\u786E\u8BA4\uFF09`,
|
|
7261
|
+
value: { ...resolvedAddressId ? { id: resolvedAddressId } : {}, name: addressDisplay, roomConfirmed: true },
|
|
6240
7262
|
reason: "\u4F60\u4F20\u5165\u7684\u4F1A\u8BAE\u5BA4\uFF0C\u672A\u63D0\u4EA4\u3001\u672A\u786E\u8BA4"
|
|
6241
7263
|
};
|
|
6242
|
-
pickOptions = [specified, ...roomOptions.filter((item) => String(item.value?.id) !==
|
|
7264
|
+
pickOptions = [specified, ...roomOptions.filter((item) => String(item.value?.id) !== resolvedAddressId)].map((item, index) => ({ ...item, key: `R${index + 1}` }));
|
|
6243
7265
|
}
|
|
6244
7266
|
if (needRoomPick && !autoRoom && pickOptions.length > 0 && args.allowNoRoom !== true) {
|
|
6245
7267
|
return meetingSuccess("meeting.eb.meeting.create.flow.prepare", {
|
|
6246
7268
|
status: "NEEDS_SELECTION",
|
|
6247
7269
|
selectionType: "room",
|
|
6248
7270
|
ui: { component: "choice", multiple: false, recommendedKey: "R1" },
|
|
6249
|
-
message: addressInput ? `\u4F60\u4F20\u5165\u7684\u4F1A\u8BAE\u5BA4\u300C${
|
|
7271
|
+
message: addressInput ? `\u4F60\u4F20\u5165\u7684\u4F1A\u8BAE\u5BA4\u300C${addressDisplay}\u300D**\u672A\u7ECF\u7528\u6237\u786E\u8BA4**\uFF08\u6CA1\u5E26 roomConfirmed\uFF09\uFF0C\u5DF2\u628A\u5B83\u548C\u5176\u5B83\u5019\u9009\u4E00\u8D77\u5217\u51FA\u6765 \u2014\u2014 \u26D4 \u5FC5\u987B\u8BA9\u7528\u6237\u5728\u9009\u9879\u91CC\u70B9\u9009\uFF0C\u4E0D\u8981\u76F4\u63A5\u63D0\u4EA4` : `\u672A\u6307\u5B9A\u4F1A\u8BAE\u5BA4\uFF0C\u8BF7\u4ECE ${pickOptions.length} \u4E2A\u5019\u9009\u91CC\u9009\u62E9\uFF08\u5DF2\u6309\u4EBA\u6570/\u5E38\u7528/\u65F6\u6BB5\u5360\u7528\u6392\u5E8F\uFF09`,
|
|
6250
7272
|
// 固化自动选的流程要带出来:调用方下一轮带 address 重调时不用再猜用的是哪条流程。
|
|
6251
7273
|
workflowPending: true,
|
|
6252
7274
|
options: pickOptions,
|
|
@@ -6255,7 +7277,7 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6255
7277
|
...conflictBrief
|
|
6256
7278
|
}, {
|
|
6257
7279
|
warnings: [
|
|
6258
|
-
addressInput ? `\u4F1A\u8BAE\u5BA4\u300C${
|
|
7280
|
+
addressInput ? `\u4F1A\u8BAE\u5BA4\u300C${addressDisplay}\u300D\u672A\u7ECF\u7528\u6237\u786E\u8BA4\uFF1A\u672C\u6B21**\u6CA1\u6709**\u63D0\u4EA4\u3002` : "\u672A\u6307\u5B9A\u4F1A\u8BAE\u5BA4\uFF1A\u672C\u6B21**\u6CA1\u6709**\u63D0\u4EA4\uFF0C\u4E5F\u6CA1\u6709\u66FF\u7528\u6237\u6311\u623F\u95F4\u3002",
|
|
6259
7281
|
"\u5982\u9700\u76F4\u63A5\u5EFA\u4F1A\u5E76\u6CBF\u7528\u63A8\u8350\uFF0C\u53EF\u4F20 autoRoom: true\uFF1B\u4E0D\u9700\u8981\u4F1A\u8BAE\u5BA4\u5219\u4F20 allowNoRoom: true\u3002",
|
|
6260
7282
|
...earlyWorkflowNote ? [earlyWorkflowNote] : [],
|
|
6261
7283
|
...memberConflicts.length > 0 ? [`\u26A0\uFE0F \u6CE8\u610F\uFF1A\u53C2\u4F1A\u4EBA\u5728\u8BE5\u65F6\u6BB5\u5DF2\u6709 ${memberConflicts.length} \u573A\u4F1A\u8BAE\u51B2\u7A81 \u2014\u2014 \u9009\u623F\u524D\u5148\u628A\u8FD9\u6761\u544A\u8BC9\u7528\u6237\uFF0C\u522B\u8BA9\u4ED6\u9009\u5B8C\u624D\u53D1\u73B0\u3002`] : [],
|
|
@@ -6300,8 +7322,8 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6300
7322
|
if (enrich && addressInput && !roomConfirmed && roomOptions.length === 0 && args.allowNoRoom !== true) {
|
|
6301
7323
|
const specified = {
|
|
6302
7324
|
key: "R1",
|
|
6303
|
-
label: `${
|
|
6304
|
-
value: { ...
|
|
7325
|
+
label: `${addressDisplay}\uFF08\u4F60\u6307\u5B9A\u7684\uFF0C\u5F85\u786E\u8BA4\uFF09`,
|
|
7326
|
+
value: { ...resolvedAddressId ? { id: resolvedAddressId } : {}, name: addressDisplay, roomConfirmed: true },
|
|
6305
7327
|
reason: "\u4F60\u4F20\u5165\u7684\u4F1A\u8BAE\u5BA4\uFF0C\u672A\u63D0\u4EA4\u3001\u672A\u786E\u8BA4"
|
|
6306
7328
|
};
|
|
6307
7329
|
return meetingSuccess("meeting.eb.meeting.create.flow.prepare", {
|
|
@@ -6318,8 +7340,8 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6318
7340
|
});
|
|
6319
7341
|
}
|
|
6320
7342
|
const resolved = await resolveWorkflowId(env, args);
|
|
6321
|
-
const confirmedAddressId =
|
|
6322
|
-
const confirmedAddressLabel =
|
|
7343
|
+
const confirmedAddressId = resolvedAddressId;
|
|
7344
|
+
const confirmedAddressLabel = addressId === "" ? "" : resolvedAddress?.name || String(roomOptions.find((item) => String(item.value?.id ?? "") === confirmedAddressId)?.value?.name ?? "") || addressId;
|
|
6323
7345
|
const confirmedWhen = `${beginText}~${String(endText).slice(11) || endText}`;
|
|
6324
7346
|
let candidates = resolved.candidates;
|
|
6325
7347
|
workflowId = resolved.workflowId;
|
|
@@ -6421,6 +7443,16 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6421
7443
|
throw meetingValidationError("flow_context_missing", "\u5EFA\u4F1A\u6D41\u7A0B\u8868\u5355\u6CA1\u6709\u8FD4\u56DE continuation\uFF0C\u65E0\u6CD5\u7EE7\u7EED\u63D0\u4EA4");
|
|
6422
7444
|
}
|
|
6423
7445
|
decisions.timings = timings;
|
|
7446
|
+
const crmMemberCount = (() => {
|
|
7447
|
+
if (args.crm_member_count !== void 0 && args.crm_member_count !== "") return args.crm_member_count;
|
|
7448
|
+
const raw = args.crm_members;
|
|
7449
|
+
if (raw === void 0 || raw === null || raw === "") return void 0;
|
|
7450
|
+
if (Array.isArray(raw)) return raw.length > 0 ? raw.length : void 0;
|
|
7451
|
+
const text = String(raw).trim();
|
|
7452
|
+
if (!text) return void 0;
|
|
7453
|
+
const count = text.split(/[,;,;]+/).map((item) => item.trim()).filter((item) => item !== "").length;
|
|
7454
|
+
return count > 0 ? count : void 0;
|
|
7455
|
+
})();
|
|
6424
7456
|
const shaped = await shapeBrowserValues(env, {
|
|
6425
7457
|
mt_name: args.mt_name,
|
|
6426
7458
|
begin_datetime: args.begin_datetime,
|
|
@@ -6430,6 +7462,8 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6430
7462
|
customize_address: args.customize_address,
|
|
6431
7463
|
hrm_members: args.hrm_members,
|
|
6432
7464
|
total_member: args.total_member,
|
|
7465
|
+
crm_members: args.crm_members,
|
|
7466
|
+
...crmMemberCount === void 0 ? {} : { crm_member_count: crmMemberCount },
|
|
6433
7467
|
caller: args.caller,
|
|
6434
7468
|
contacter: args.contacter,
|
|
6435
7469
|
other_remark: args.other_remark,
|
|
@@ -6440,8 +7474,88 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6440
7474
|
const { main, mapped, unmapped, resolved: resolvedFields } = mapFields(form.fields, shaped.values, preferredFields);
|
|
6441
7475
|
await writeFlowFieldMap(env, workflowId, form.workflowName, resolvedFields);
|
|
6442
7476
|
const warnings = [];
|
|
7477
|
+
if (autoFilledPerson.length > 0) {
|
|
7478
|
+
const labels = autoFilledPerson.map((one) => `\u300C${PERSON_FIELD_LABELS[one.field]}\u300D`).join("");
|
|
7479
|
+
warnings.push(
|
|
7480
|
+
`${labels}\u6CA1\u6709\u4F20\u503C\uFF0C\u5DF2\u6309**\u5F53\u524D\u767B\u5F55\u4EBA**\u8865\u9F50\uFF1A${autoFilledPerson[0].name}\uFF08${autoFilledPerson[0].id}\uFF09\u3002\u8981\u6362\u6210\u522B\u4EBA\uFF08\u4F8B\u5982\u66FF\u4ED6\u4EBA\u5EFA\u4F1A\u3001\u6307\u5B9A\u522B\u7684\u8054\u7CFB\u4EBA\uFF09\u8BF7\u663E\u5F0F\u4F20 caller / contacter\u3002`
|
|
7481
|
+
);
|
|
7482
|
+
} else if (selfPersonWarning) {
|
|
7483
|
+
warnings.push(selfPersonWarning);
|
|
7484
|
+
}
|
|
6443
7485
|
if (flowPickNote) warnings.push(flowPickNote);
|
|
6444
7486
|
for (const note of shaped.notes) warnings.push(note);
|
|
7487
|
+
const crmMentioned = detectCrmMentionInText(args.mt_name, args.mt_desc, args.other_remark);
|
|
7488
|
+
if (crmMentioned && !args.crm_members) {
|
|
7489
|
+
const hasCrmField = form.fields.some((field) => /参会客户/.test(String(field?.label ?? field?.name ?? field?.fieldName ?? "")));
|
|
7490
|
+
warnings.push(
|
|
7491
|
+
`\u4F1A\u8BAE\u540D\u79F0/\u5185\u5BB9\u91CC\u63D0\u5230\u5BA2\u6237\u300C${crmMentioned}\u300D\uFF0C\u4F46\u672C\u6B21\u6CA1\u4F20 crm_members` + (hasCrmField ? `\uFF0C\u8BE5\u6D41\u7A0B\u8868\u5355**\u6709\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u5B57\u6BB5\uFF0C\u73B0\u5728\u4F1A\u662F\u7A7A\u7684**\u3002\u8BF7\u5148 meeting.eb.crm.search {"keyword":"${crmMentioned}"} \u62FF items[].customerId\uFF0C\u518D\u7528 crm_members:[{id,name}] \u91CD\u65B0\u63D0\u4EA4\uFF08\u5FC5\u987B\u5E26\u5BA2\u6237\u540D\u79F0\uFF09\u3002` : "\uFF08\u8BE5\u6D41\u7A0B\u8868\u5355\u91CC\u6CA1\u6709\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u5B57\u6BB5\uFF0C\u672C\u6761\u53EF\u5FFD\u7565\uFF09\u3002")
|
|
7492
|
+
);
|
|
7493
|
+
}
|
|
7494
|
+
const crmMembersGiven = Array.isArray(args.crm_members) ? args.crm_members.length > 0 : String(args.crm_members ?? "").trim() !== "";
|
|
7495
|
+
if (crmMembersGiven) {
|
|
7496
|
+
const crmFieldId = String(resolvedFields.crm_members ?? "").trim();
|
|
7497
|
+
const crmField = form.fields.find((field) => String(field?.id ?? "") === crmFieldId);
|
|
7498
|
+
const componentKey = String(crmField?.componentKey ?? "").toLowerCase();
|
|
7499
|
+
if (crmField && componentKey !== "" && componentKey !== "customer" && componentKey !== "customercomponent") {
|
|
7500
|
+
warnings.push(
|
|
7501
|
+
`\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u5B57\u6BB5\uFF08${crmFieldId}\uFF09\u662F ${crmField.componentKey} \u7EC4\u4EF6\uFF1A\u5BA2\u6237 id \u4E0E\u540D\u79F0\u7167\u5E38\u5199\u8FDB\u6D41\u7A0B\u5355\u636E\uFF0C\u518D\u7531 ESB \u7684\u5B57\u6BB5\u6620\u5C04\u540C\u6B65\u5230\u4F1A\u8BAE\u8868 \u2014\u2014 \u6B63\u5E38\u914D\u7F6E\uFF0C\u4E0D\u9700\u8981\u6539\u8868\u5355\u3002`
|
|
7502
|
+
);
|
|
7503
|
+
}
|
|
7504
|
+
}
|
|
7505
|
+
const providedCrmDetailRows = normalizeCrmDetailRows(args.crm_member_details);
|
|
7506
|
+
const onlyDetailMode = String(args.crm_detail_mode ?? "").trim().toLowerCase() === "only";
|
|
7507
|
+
let crmDetailRows = onlyDetailMode ? providedCrmDetailRows : [];
|
|
7508
|
+
if (crmMembersGiven && !onlyDetailMode) {
|
|
7509
|
+
const detailTarget = resolveCrmDetailTarget(form.fields);
|
|
7510
|
+
if (detailTarget) {
|
|
7511
|
+
const auto = await resolveAutoCrmDetailRows(env, args.crm_members);
|
|
7512
|
+
if (auto.rows.length > 0) {
|
|
7513
|
+
crmDetailRows = auto.rows;
|
|
7514
|
+
if (providedCrmDetailRows.length > 0) {
|
|
7515
|
+
const byName = new Map(providedCrmDetailRows.map((row) => [String(row.xm ?? "").trim(), row]));
|
|
7516
|
+
crmDetailRows = crmDetailRows.map((row) => {
|
|
7517
|
+
const given = byName.get(String(row.xm ?? "").trim());
|
|
7518
|
+
if (!given) return row;
|
|
7519
|
+
const merged = { ...row };
|
|
7520
|
+
for (const [key, value] of Object.entries(given)) {
|
|
7521
|
+
if (String(value ?? "").trim() !== "") merged[key] = String(value);
|
|
7522
|
+
}
|
|
7523
|
+
return merged;
|
|
7524
|
+
});
|
|
7525
|
+
}
|
|
7526
|
+
warnings.push(
|
|
7527
|
+
`\u5DF2\u81EA\u52A8\u628A\u300C${auto.customers.join("\u3001")}\u300D\u7684 ${auto.rows.length} \u4F4D\u8054\u7CFB\u4EBA\u5199\u8FDB\u300C\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6\u300D\uFF1A${auto.rows.map((row) => `${row.xm}${row.sjhm ? ` ${row.sjhm}` : ""}`).join("\u3001")}\uFF08\u660E\u7EC6\u8868\u672C\u6765\u5C31\u4E00\u4EBA\u4E00\u884C\uFF0C\u4E0D\u9700\u8981\u8BA9\u7528\u6237\u6311\uFF09\u3002\u786E\u5B9E\u53EA\u60F3\u8981\u5176\u4E2D\u51E0\u4F4D\u65F6\uFF0C\u4F20 crm_detail_mode:"only" \u518D\u914D crm_member_details \u624D\u8986\u76D6\u672C\u6B21\u81EA\u52A8\u5E26\u5165\u3002`
|
|
7528
|
+
);
|
|
7529
|
+
} else if (auto.missing.length > 0) {
|
|
7530
|
+
warnings.push(
|
|
7531
|
+
`\u5DF2\u5199\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\uFF0C\u4F46\u6CA1\u80FD\u81EA\u52A8\u5E26\u51FA\u300C${auto.missing.join("\u3001")}\u300D\u7684\u8054\u7CFB\u4EBA\uFF08CRM \u91CC\u67E5\u4E0D\u5230\uFF09\u3002\u8BF7\u628A\u5DF2\u67E5\u5230\u7684\u8054\u7CFB\u4EBA\u76F4\u63A5\u544A\u7ED9\u7528\u6237\u6838\u5BF9\uFF1B\u786E\u5B9E\u6CA1\u6709\u8054\u7CFB\u4EBA\u65F6\u95EE\u4E00\u6B21\u59D3\u540D+\u624B\u673A\u53F7\uFF0C\u518D\u4EE5 crm_member_details:[{"xm":"\u5F20\u4E09","sjhm":"13800000000"}] \u91CD\u65B0 prepare\u3002`
|
|
7532
|
+
);
|
|
7533
|
+
}
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
let detailPayload;
|
|
7537
|
+
if (crmDetailRows.length > 0) {
|
|
7538
|
+
const target = resolveCrmDetailTarget(form.fields);
|
|
7539
|
+
if (!target) {
|
|
7540
|
+
warnings.push(
|
|
7541
|
+
`\u4F20\u4E86 crm_member_details\uFF08${crmDetailRows.length} \u884C\uFF09\uFF0C\u4F46\u8BE5\u5EFA\u4F1A\u6D41\u7A0B\u7684**\u53D1\u8D77\u8282\u70B9\u8868\u5355\u91CC\u6CA1\u6709\u300C\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6\u300D\u660E\u7EC6\u8868**\uFF08\u6216\u5B83\u88AB\u6446\u5728\u9690\u85CF\u884C\u4E0A\uFF09\uFF0C\u660E\u7EC6\u65E0\u6CD5\u5199\u5165\uFF0C\u5DF2\u5FFD\u7565\u8FD9\u4E9B\u884C\uFF1B\u4E3B\u8868\u7684\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u7167\u5E38\u5199\u5165\u3002`
|
|
7542
|
+
);
|
|
7543
|
+
} else {
|
|
7544
|
+
detailPayload = {
|
|
7545
|
+
[target.subFormId]: crmDetailRows.map((row) => {
|
|
7546
|
+
const line = {};
|
|
7547
|
+
for (const [semantic, fieldId] of Object.entries(target.columns)) {
|
|
7548
|
+
const value = row[semantic];
|
|
7549
|
+
if (value !== void 0 && value !== "") line[fieldId] = value;
|
|
7550
|
+
}
|
|
7551
|
+
return line;
|
|
7552
|
+
})
|
|
7553
|
+
};
|
|
7554
|
+
warnings.push(
|
|
7555
|
+
`\u53C2\u4F1A\u5BA2\u6237\u660E\u7EC6\uFF1A${crmDetailRows.length} \u884C\u5199\u5165\u660E\u7EC6\u8868 ${target.subFormId}\uFF08\u5217\uFF1A${Object.values(target.labels).join("/")}\uFF09`
|
|
7556
|
+
);
|
|
7557
|
+
}
|
|
7558
|
+
}
|
|
6445
7559
|
if (args.fieldValues && typeof args.fieldValues === "object" && !Array.isArray(args.fieldValues)) {
|
|
6446
7560
|
const knownIds = new Set(form.fields.map((field) => field.id));
|
|
6447
7561
|
for (const [fieldId, raw] of Object.entries(args.fieldValues)) {
|
|
@@ -6479,7 +7593,7 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6479
7593
|
} else if (decisions.dayBlocked?.summary) {
|
|
6480
7594
|
warnings.push(String(decisions.dayBlocked.summary));
|
|
6481
7595
|
}
|
|
6482
|
-
const unmappedReal = unmapped.filter((name) => name !== "mt_name");
|
|
7596
|
+
const unmappedReal = unmapped.filter((name) => name !== "mt_name" && name !== "crm_member_count");
|
|
6483
7597
|
if (unmappedReal.length > 0) {
|
|
6484
7598
|
warnings.push(
|
|
6485
7599
|
`\u4EE5\u4E0B\u5B57\u6BB5\u6CA1\u6709\u5728\u5EFA\u4F1A\u6D41\u7A0B\u8868\u5355\u91CC\u627E\u5230\u540C\u540D\u5B57\u6BB5\uFF0C\u672A\u81EA\u52A8\u586B\u5199\uFF1A${unmappedReal.join("\u3001")}\uFF08\u8868\u5355\u73B0\u6709\u5B57\u6BB5\uFF1A${form.fields.map((field) => field.name).join("\u3001")}\uFF09`
|
|
@@ -6490,6 +7604,7 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6490
7604
|
"\u8BE5\u5EFA\u4F1A\u6D41\u7A0B\u7684\u8868\u5355\u6CA1\u6709\u300C\u4F1A\u8BAE\u540D\u79F0\u300D\u5B57\u6BB5\uFF08\u90E8\u5206\u6D41\u7A0B\u7528\u6D41\u7A0B\u6807\u9898\u4EE3\u66FF\u4F1A\u8BAE\u540D\u79F0\uFF0C\u5C5E\u6B63\u5E38\u914D\u7F6E\uFF0C\u4E0D\u662F\u6D41\u7A0B\u914D\u9519\uFF09\u3002\u5982\u9700\u4F1A\u8BAE\u540D\u79F0\u72EC\u7ACB\u6210\u5B57\u6BB5\uFF0C\u8BF7\u6539\u9009\u5E26\u8BE5\u5B57\u6BB5\u7684\u6D41\u7A0B\uFF08\u5982\u300C\u4F1A\u8BAE\u7533\u8BF7\u6D41\u7A0B\uFF08NEW\uFF09\u300D\uFF09\u3002"
|
|
6491
7605
|
);
|
|
6492
7606
|
}
|
|
7607
|
+
const crmPatchIds = (Array.isArray(shaped.values.crm_members) ? shaped.values.crm_members : []).map((row) => String(row?.id ?? "").trim()).filter((id) => id !== "");
|
|
6493
7608
|
const session = await env.host.getSession();
|
|
6494
7609
|
const continuation = await env.continuation.issue(
|
|
6495
7610
|
{
|
|
@@ -6501,12 +7616,18 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6501
7616
|
workflowId,
|
|
6502
7617
|
requestName: String(args.mt_name),
|
|
6503
7618
|
mtName: String(args.mt_name),
|
|
6504
|
-
data: { main },
|
|
7619
|
+
data: { main, ...detailPayload ? { details: detailPayload } : {} },
|
|
6505
7620
|
surfaceContinuation: form.continuation,
|
|
6506
7621
|
// 供 apply 在「会议还没生成」时按申请单信息预生成邀请函(预置函)
|
|
6507
|
-
invitationFields: shaped.readable
|
|
7622
|
+
invitationFields: shaped.readable,
|
|
7623
|
+
// 提交后回显要用「字段名 → 值」,字段清单先存下来(apply 阶段拿不到 createForm 结果)
|
|
7624
|
+
fieldLabels: form.fields.map((field) => ({ id: String(field.id), name: String(field.name) })),
|
|
7625
|
+
// 已确认的「人员 id → 姓名」,供 apply 回显时把裸 id 换成姓名
|
|
7626
|
+
...autoFilledPerson.length > 0 ? { personLabels: Object.fromEntries(autoFilledPerson.map((one) => [one.id, one.name])) } : {},
|
|
7627
|
+
// 会议记录的客户要靠 apply 补写(表单「参会客户」是 Ebuilder,单据↔会议表不同步)
|
|
7628
|
+
...crmPatchIds.length > 0 ? { crmPatch: { ids: crmPatchIds, count: crmMemberCount === void 0 ? crmPatchIds.length : crmMemberCount } } : {}
|
|
6508
7629
|
},
|
|
6509
|
-
fingerprint: JSON.stringify({ workflowId, main })
|
|
7630
|
+
fingerprint: JSON.stringify({ workflowId, main, ...detailPayload ? { details: detailPayload } : {} })
|
|
6510
7631
|
},
|
|
6511
7632
|
10 * 60 * 1e3
|
|
6512
7633
|
);
|
|
@@ -6522,6 +7643,23 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6522
7643
|
requestName: String(args.mt_name),
|
|
6523
7644
|
fieldMapping: mapped,
|
|
6524
7645
|
formData: { main },
|
|
7646
|
+
// 人话版「即将提交的内容」—— 提交前必须先贴给用户核对(见 SKILL 建会章节)。
|
|
7647
|
+
formPreview: renderFormPreview(
|
|
7648
|
+
form.fields,
|
|
7649
|
+
await decoratePreviewPersonNames(
|
|
7650
|
+
env,
|
|
7651
|
+
main,
|
|
7652
|
+
form.fields,
|
|
7653
|
+
new Map(autoFilledPerson.map((one) => [one.id, one.name]))
|
|
7654
|
+
)
|
|
7655
|
+
),
|
|
7656
|
+
// 召集人/联系人是不是"替用户默认填的"要说清楚,用户才知道能不能改。
|
|
7657
|
+
...autoFilledPerson.length > 0 ? {
|
|
7658
|
+
autoFilled: Object.fromEntries(
|
|
7659
|
+
autoFilledPerson.map((one) => [PERSON_FIELD_LABELS[one.field], `${one.name}(${one.id})`])
|
|
7660
|
+
)
|
|
7661
|
+
} : {},
|
|
7662
|
+
...detailPayload ? { detailRows: { subFormId: Object.keys(detailPayload)[0], count: crmDetailRows.length, rows: crmDetailRows } } : {},
|
|
6525
7663
|
formFieldCount: form.fields.length,
|
|
6526
7664
|
...Object.keys(decisions).length > 0 ? { decisions } : {}
|
|
6527
7665
|
},
|
|
@@ -6532,11 +7670,59 @@ var ebMeetingCreateFlowPrepare = {
|
|
|
6532
7670
|
);
|
|
6533
7671
|
}
|
|
6534
7672
|
};
|
|
7673
|
+
var CRM_PATCH_SETTLE_MS = [4e3, 6e3];
|
|
7674
|
+
async function patchMeetingCrmMembers(env, meetingId, ids, count, settleMsList = CRM_PATCH_SETTLE_MS) {
|
|
7675
|
+
const list = ids.map((id) => String(id ?? "").trim()).filter((id) => id !== "");
|
|
7676
|
+
if (String(meetingId).trim() === "" || list.length === 0) {
|
|
7677
|
+
return { ok: false, error: "\u6CA1\u6709\u4F1A\u8BAE id \u6216\u5BA2\u6237 id" };
|
|
7678
|
+
}
|
|
7679
|
+
const mainTable = {
|
|
7680
|
+
id: String(meetingId).trim(),
|
|
7681
|
+
operate_type: "UPDATE",
|
|
7682
|
+
crm_members: list.join(",")
|
|
7683
|
+
};
|
|
7684
|
+
const total = Number(count);
|
|
7685
|
+
if (Number.isFinite(total) && total > 0) mainTable.crm_total_member = String(total);
|
|
7686
|
+
const write = async () => {
|
|
7687
|
+
const session = await env.host.getSession();
|
|
7688
|
+
await env.host.request({
|
|
7689
|
+
method: "POST",
|
|
7690
|
+
path: `${EB_BASE}/updateFormData/change_meeting`,
|
|
7691
|
+
query: { id: String(meetingId).trim() },
|
|
7692
|
+
operation: "meeting.eb.meeting.create.flow.apply",
|
|
7693
|
+
body: writeBody(String(session.userId), { mainTable, details: {}, operateType: {} }),
|
|
7694
|
+
acceptBusiness: ebBusinessSuccess
|
|
7695
|
+
});
|
|
7696
|
+
};
|
|
7697
|
+
const readBack = async () => {
|
|
7698
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
7699
|
+
const detail = getMeetingOperation2("meeting.eb.meeting.detail");
|
|
7700
|
+
const read = await detail.handler({ id: String(meetingId).trim() }, env);
|
|
7701
|
+
return String(read?.data?.data?.crm_members ?? "").trim();
|
|
7702
|
+
};
|
|
7703
|
+
let lastError = "";
|
|
7704
|
+
for (const settleMs of settleMsList) {
|
|
7705
|
+
try {
|
|
7706
|
+
await write();
|
|
7707
|
+
} catch (error) {
|
|
7708
|
+
return { ok: false, error: String(error?.message ?? error).slice(0, 160) };
|
|
7709
|
+
}
|
|
7710
|
+
await new Promise((resolve6) => setTimeout(resolve6, settleMs));
|
|
7711
|
+
try {
|
|
7712
|
+
const value = await readBack();
|
|
7713
|
+
if (value !== "") return { ok: true, value };
|
|
7714
|
+
lastError = "\u8865\u5199\u540E\u56DE\u8BFB crm_members \u4ECD\u4E3A\u7A7A\uFF08\u591A\u534A\u88AB\u4F1A\u8BAE\u521D\u59CB\u5316\u7684\u540E\u7EED\u5199\u5165\u8986\u76D6\u4E86\uFF09";
|
|
7715
|
+
} catch (error) {
|
|
7716
|
+
lastError = `\u8865\u5199\u6210\u529F\u4F46\u56DE\u8BFB\u5931\u8D25\uFF1A${String(error?.message ?? error).slice(0, 120)}`;
|
|
7717
|
+
}
|
|
7718
|
+
}
|
|
7719
|
+
return { ok: false, error: lastError };
|
|
7720
|
+
}
|
|
6535
7721
|
async function renderPreInvitation(payload, env) {
|
|
6536
7722
|
const fields = payload?.invitationFields ?? {};
|
|
6537
7723
|
const started = Date.now();
|
|
6538
7724
|
try {
|
|
6539
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
7725
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6540
7726
|
const render = getMeetingOperation2("meeting.invitation.render");
|
|
6541
7727
|
const rendered = await render.handler(
|
|
6542
7728
|
{
|
|
@@ -6549,7 +7735,10 @@ async function renderPreInvitation(payload, env) {
|
|
|
6549
7735
|
org_members: String(fields.org_members ?? "").trim(),
|
|
6550
7736
|
caller: String(fields.caller ?? "").trim(),
|
|
6551
7737
|
contacter: String(fields.contacter ?? "").trim(),
|
|
6552
|
-
total_member: String(fields.total_member ?? "").trim()
|
|
7738
|
+
total_member: String(fields.total_member ?? "").trim(),
|
|
7739
|
+
// 客户单位(邀请函开头「尊敬的 XXX」):建会时填了参会客户就直接带过去,
|
|
7740
|
+
// 否则整句永远是【待补充】—— 用户看到的就是"客户明明填了,邀请函里却没有"。
|
|
7741
|
+
extra: { guest_org: String(fields.crm_members ?? "").trim() }
|
|
6553
7742
|
},
|
|
6554
7743
|
env
|
|
6555
7744
|
);
|
|
@@ -6582,6 +7771,11 @@ var ebMeetingCreateFlowApply = {
|
|
|
6582
7771
|
{
|
|
6583
7772
|
continuation: { type: "string", description: "prepare \u8FD4\u56DE\u7684\u786E\u8BA4\u7968\u636E\uFF08\u5FC5\u586B\uFF09" },
|
|
6584
7773
|
confirm: { type: "boolean", description: "\u5FC5\u987B\u663E\u5F0F\u4F20 true" },
|
|
7774
|
+
submit_mode: {
|
|
7775
|
+
type: "string",
|
|
7776
|
+
enum: ["direct", "browser"],
|
|
7777
|
+
description: '\u63D0\u4EA4\u65B9\u5F0F\uFF0C\u9ED8\u8BA4 browser\uFF1A\u5728\u5C0Fe \u91CC**\u5F39\u51FA\u6D41\u7A0B\u8868\u5355**\uFF0C\u5B57\u6BB5\u5DF2\u9884\u586B\uFF0C\u7528\u6237\u6838\u5BF9/\u4FEE\u6539\u540E\u81EA\u5DF1\u70B9\u63D0\u4EA4\u3002direct = \u76F4\u63A5\u5199\u670D\u52A1\u7AEF\uFF08\u4F1A\u8BAE\u5F53\u573A\u751F\u6210\u3001\u9080\u8BF7\u51FD\u7528\u771F\u5B9E\u6570\u636E\uFF0C\u4F46\u6CA1\u6709\u4EBA\u5DE5\u6838\u5BF9\u8868\u5355\u8FD9\u4E00\u6B65\uFF09\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8BF4"\u4E0D\u7528\u6211\u786E\u8BA4\uFF0C\u76F4\u63A5\u5EFA"\u65F6\u624D\u4F20 direct'
|
|
7778
|
+
},
|
|
6585
7779
|
waitSeconds: { type: "number", description: "\u63D0\u4EA4\u540E\u7B49\u5F85\u4F1A\u8BAE\u751F\u6210\u7684\u6700\u957F\u79D2\u6570\uFF08\u9ED8\u8BA4 60\uFF0C0 = \u4E0D\u7B49\u5F85\uFF09" }
|
|
6586
7780
|
},
|
|
6587
7781
|
{ required: ["continuation", "confirm"] }
|
|
@@ -6599,9 +7793,9 @@ var ebMeetingCreateFlowApply = {
|
|
|
6599
7793
|
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");
|
|
6600
7794
|
}
|
|
6601
7795
|
const payload = lease?.payload ?? {};
|
|
6602
|
-
const { createWorkflowHost } = await import("./host-
|
|
7796
|
+
const { createWorkflowHost } = await import("./host-YAQAPYNP.js");
|
|
6603
7797
|
const { createWorkflowContinuationSigner } = await import("./continuation-HZIZRZBX.js");
|
|
6604
|
-
const { getWorkflowOperation } = await import("./registry-
|
|
7798
|
+
const { getWorkflowOperation } = await import("./registry-YX4CSEMD.js");
|
|
6605
7799
|
const wfEnv = {
|
|
6606
7800
|
...workflowEnv(env),
|
|
6607
7801
|
host: createWorkflowHost(env.ctx),
|
|
@@ -6609,6 +7803,7 @@ var ebMeetingCreateFlowApply = {
|
|
|
6609
7803
|
};
|
|
6610
7804
|
const submitStartedAt = Date.now();
|
|
6611
7805
|
const submit = getWorkflowOperation("workflow.createRequest");
|
|
7806
|
+
const submitMode = String(args.submit_mode ?? "browser").trim();
|
|
6612
7807
|
const submitted = await submit.handler(
|
|
6613
7808
|
{
|
|
6614
7809
|
// 工作流的入参名是 context(createForm 返回的 continuation 就是它的 context 句柄)
|
|
@@ -6616,7 +7811,8 @@ var ebMeetingCreateFlowApply = {
|
|
|
6616
7811
|
data: payload.data,
|
|
6617
7812
|
action: "submit",
|
|
6618
7813
|
requestName: payload.requestName,
|
|
6619
|
-
confirm: true
|
|
7814
|
+
confirm: true,
|
|
7815
|
+
...submitMode === "browser" ? {} : { forceServerSubmit: true }
|
|
6620
7816
|
},
|
|
6621
7817
|
wfEnv
|
|
6622
7818
|
);
|
|
@@ -6681,7 +7877,7 @@ var ebMeetingCreateFlowApply = {
|
|
|
6681
7877
|
let meetingId = "";
|
|
6682
7878
|
const timings = { submitMs: Date.now() - submitStartedAt };
|
|
6683
7879
|
if (waitSeconds > 0) {
|
|
6684
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
7880
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6685
7881
|
const list = getMeetingOperation2("meeting.eb.meeting.list");
|
|
6686
7882
|
const deadline = Date.now() + Math.min(waitSeconds, 30) * 1e3;
|
|
6687
7883
|
const pollStart = Date.now();
|
|
@@ -6703,13 +7899,39 @@ var ebMeetingCreateFlowApply = {
|
|
|
6703
7899
|
}
|
|
6704
7900
|
timings.pollMs = Date.now() - pollStart;
|
|
6705
7901
|
}
|
|
7902
|
+
let crmLinked;
|
|
7903
|
+
const crmPatch = payload?.crmPatch;
|
|
7904
|
+
const crmPatchEnabled = process.env.WEAVER_MEETING_CRM_PATCH === "1";
|
|
7905
|
+
if (meetingId && crmPatchEnabled && Array.isArray(crmPatch?.ids) && crmPatch.ids.length > 0) {
|
|
7906
|
+
const patched = await patchMeetingCrmMembers(env, meetingId, crmPatch.ids, crmPatch.count);
|
|
7907
|
+
crmLinked = {
|
|
7908
|
+
ok: patched.ok,
|
|
7909
|
+
requested: crmPatch.ids.length,
|
|
7910
|
+
...patched.value ? { readBack: patched.value } : {},
|
|
7911
|
+
...patched.error ? { error: patched.error } : {}
|
|
7912
|
+
};
|
|
7913
|
+
if (patched.ok) {
|
|
7914
|
+
warnings.push(`\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u5DF2\u8865\u5199\u5230\u4F1A\u8BAE\u8BB0\u5F55\uFF08crm_members=${patched.value}\uFF09\u3002`);
|
|
7915
|
+
} else {
|
|
7916
|
+
warnings.push(
|
|
7917
|
+
`\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u6CA1\u6709\u56DE\u8BFB\u5230\uFF08${patched.error ?? "\u672A\u77E5\u539F\u56E0"}\uFF09\uFF1A\u5F53\u524D\u8D70\u7684\u662F CLI \u624B\u5DE5\u8865\u5199\uFF08WEAVER_MEETING_CRM_PATCH=1\uFF09\uFF0C\u4E0D\u4F9D\u8D56 ESB \u5B57\u6BB5\u6620\u5C04\u65F6\u624D\u9700\u8981\u5B83\u3002`
|
|
7918
|
+
);
|
|
7919
|
+
}
|
|
7920
|
+
}
|
|
6706
7921
|
let invitation = { pending: true };
|
|
6707
7922
|
if (meetingId) {
|
|
6708
7923
|
const invitationStart = Date.now();
|
|
6709
7924
|
try {
|
|
6710
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
7925
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6711
7926
|
const render = getMeetingOperation2("meeting.invitation.render");
|
|
6712
|
-
const rendered = await render.handler(
|
|
7927
|
+
const rendered = await render.handler(
|
|
7928
|
+
{
|
|
7929
|
+
mtId: meetingId,
|
|
7930
|
+
// 同理:会议主表不存客户名,用建会时填的参会客户补「客户单位」
|
|
7931
|
+
extra: { guest_org: String(payload?.invitationFields?.crm_members ?? "").trim() }
|
|
7932
|
+
},
|
|
7933
|
+
env
|
|
7934
|
+
);
|
|
6713
7935
|
invitation = { pending: false, ...rendered?.data ?? {} };
|
|
6714
7936
|
timings.invitationMs = Date.now() - invitationStart;
|
|
6715
7937
|
} catch (error) {
|
|
@@ -6736,6 +7958,19 @@ var ebMeetingCreateFlowApply = {
|
|
|
6736
7958
|
requestId,
|
|
6737
7959
|
requestName: payload.requestName,
|
|
6738
7960
|
meetingId: meetingId || null,
|
|
7961
|
+
// 参会客户有没有真的写进会议记录(表单侧是 Ebuilder,需 apply 补写;回读确认才算 ok)
|
|
7962
|
+
...crmLinked ? { crmLinked } : {},
|
|
7963
|
+
// 提交后回显「实际提交了什么」:字段名 → 值(人员/客户显示姓名,不显示 id)。
|
|
7964
|
+
// 用户要的就是"能看见内容",替代走不通的浏览器填单核对。
|
|
7965
|
+
submittedPreview: renderFormPreview(
|
|
7966
|
+
payload?.fieldLabels ?? [],
|
|
7967
|
+
await decoratePreviewPersonNames(
|
|
7968
|
+
env,
|
|
7969
|
+
payload?.data?.main ?? {},
|
|
7970
|
+
payload?.fieldLabels ?? [],
|
|
7971
|
+
new Map(Object.entries(payload?.personLabels ?? {}))
|
|
7972
|
+
)
|
|
7973
|
+
),
|
|
6739
7974
|
invitation,
|
|
6740
7975
|
result: submitted?.data ?? null
|
|
6741
7976
|
},
|
|
@@ -6748,7 +7983,7 @@ var ebMeetingCreateFlowQuick = {
|
|
|
6748
7983
|
resource: "eb",
|
|
6749
7984
|
method: "meeting.eb.meeting.create.flow.quick",
|
|
6750
7985
|
action: "meeting.eb.meeting.create.flow.quick",
|
|
6751
|
-
summary:
|
|
7986
|
+
summary: '\u4E00\u6B65\u6D41\u7A0B\u5EFA\u4F1A\uFF08prepare+apply \u5408\u5E76\uFF09\uFF1A\u5185\u90E8\u5E76\u884C\u505A\u4F1A\u8BAE\u5BA4\u63A8\u8350/\u51B2\u7A81\u68C0\u6D4B/\u7A7A\u95F2\u65F6\u6BB5\uFF0C\u9ED8\u8BA4**\u5F39\u6D4F\u89C8\u5668\u8868\u5355**\u7ED9\u7528\u6237\u6838\u5BF9\u63D0\u4EA4\uFF08submit_mode=browser\uFF0C\u5C0Fe \u91CC\u9884\u586B\u4EBA\u5458/\u5BA2\u6237\u540E\u7531\u7528\u6237\u70B9\u63D0\u4EA4\uFF1B\u975E\u5C0Fe \u73AF\u5883\u4F1A\u81EA\u52A8\u5199\u670D\u52A1\u7AEF\uFF09\uFF1B\u4F20 submit_mode=direct \u624D\u662F\u670D\u52A1\u7AEF\u76F4\u63D0\uFF08\u62FF requestId + meetingId\uFF0C\u4F1A\u8BAE\u5F53\u573A\u751F\u6210\u3001\u9080\u8BF7\u51FD\u7528\u771F\u5B9E\u6570\u636E\uFF09\u3002\u591A\u6D41\u7A0B\u6216\u9700\u9009\u62E9\u65F6\u4E0D\u63D0\u4EA4\uFF0C\u8FD4\u56DE\u9009\u9879\u3002\u26A0\uFE0F \u7528\u6237\u63D0\u5230\u5BA2\u6237\u540D\u65F6**\u5FC5\u987B\u5148** meeting.eb.crm.search {"keyword":"X"} \u62FF customerId \u518D\u4F20 crm_members:[{id,name}]\uFF1B\u53EA\u628A\u5BA2\u6237\u540D\u5199\u8FDB\u4F1A\u8BAE\u540D\u79F0/\u5185\u5BB9\u800C\u4E0D\u4F20 crm_members \u4F1A\u88AB\u76F4\u63A5\u62D2\u7EDD\uFF08crm_member_required\uFF09\u3002\u26D4 \u4E0D\u8981\u7528 submit_mode=browser \u2014\u2014 \u5C0Fe \u586B\u5355\u9875\u4E0D\u7ED9\u6D4F\u89C8\u6309\u94AE\u8D4B\u503C\uFF0C\u53C2\u4F1A\u4EBA\u5458/\u53C2\u4F1A\u5BA2\u6237\u4F1A\u6574\u6BB5\u4E22\u5931',
|
|
6752
7987
|
capability: "eb.meeting",
|
|
6753
7988
|
risk: "high-risk-write",
|
|
6754
7989
|
requiresConfirmation: true,
|
|
@@ -6768,8 +8003,8 @@ var ebMeetingCreateFlowQuick = {
|
|
|
6768
8003
|
customize_address: { type: "string", description: "\u81EA\u5B9A\u4E49\u4F1A\u8BAE\u5730\u70B9" },
|
|
6769
8004
|
hrm_members: { type: "string", description: "\u53C2\u4F1A\u4EBA\u5458 id\uFF0C\u9017\u53F7\u5206\u9694" },
|
|
6770
8005
|
total_member: { type: "number", description: "\u53C2\u4F1A\u4EBA\u6570" },
|
|
6771
|
-
caller: { type: "string", description: "\u53EC\u96C6\u4EBA" },
|
|
6772
|
-
contacter: { type: "string", description: "\u8054\u7CFB\u4EBA" },
|
|
8006
|
+
caller: { type: "string", description: "\u53EC\u96C6\u4EBA\uFF08\u5458\u5DE5 id \u6216\u59D3\u540D\uFF09\u3002\u7F3A\u7701 = \u5F53\u524D\u767B\u5F55\u4EBA\uFF0C\u4E0D\u7528\u4F20\uFF1B\u53EA\u6709\u6307\u5B9A\u522B\u4EBA\u5F53\u53EC\u96C6\u4EBA\u624D\u4F20" },
|
|
8007
|
+
contacter: { type: "string", description: "\u8054\u7CFB\u4EBA\uFF08\u5458\u5DE5 id \u6216\u59D3\u540D\uFF09\u3002\u7F3A\u7701 = \u5F53\u524D\u767B\u5F55\u4EBA\uFF0C\u4E0D\u7528\u4F20\uFF1B\u53EA\u6709\u6307\u5B9A\u522B\u4EBA\u5F53\u8054\u7CFB\u4EBA\u624D\u4F20" },
|
|
6773
8008
|
mt_type: {
|
|
6774
8009
|
type: "string",
|
|
6775
8010
|
description: "\u4F1A\u8BAE\u7C7B\u578B\uFF1A\u53EF\u4F20\u7C7B\u578B\u540D\u79F0\u6216 id\uFF08\u5148\u7528 `meeting.eb.type.list` \u67E5\u6709\u54EA\u4E9B\uFF09\u3002**\u5F88\u591A\u79DF\u6237\u7684\u6D41\u7A0B\u8868\u5355\u628A\u300C\u4F1A\u8BAE\u7C7B\u578B\u300D\u8BBE\u4E3A\u5FC5\u586B**\uFF0C\u4E0D\u4F20\u4F1A\u88AB `workflow.createRequest` \u6253\u56DE\u7F3A\u5B57\u6BB5"
|
|
@@ -6815,6 +8050,15 @@ var ebMeetingCreateFlowQuick = {
|
|
|
6815
8050
|
type: "string",
|
|
6816
8051
|
enum: ["auto", "ask"],
|
|
6817
8052
|
description: "\u591A\u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\u65F6\uFF1A\u9ED8\u8BA4\uFF08\u4E0D\u4F20 / ask\uFF09= \u8FD4\u56DE\u9009\u9879\u8BA9\u7528\u6237\u6311\uFF1Bauto = \u81EA\u52A8\u53D6\u4F18\u5148\u7EA7\u6700\u9AD8\u7684\u3002\u53EA\u6709 1 \u4E2A\u6709\u6743\u9650\u65F6\u76F4\u63A5\u53D1\u8D77"
|
|
8053
|
+
},
|
|
8054
|
+
crm_skip: {
|
|
8055
|
+
type: "boolean",
|
|
8056
|
+
description: "\u663E\u5F0F\u58F0\u660E\u300C\u8FD9\u6B21\u4E0D\u586B\u53C2\u4F1A\u5BA2\u6237\u300D\u3002\u4F1A\u8BAE\u540D\u79F0/\u5185\u5BB9\u91CC\u51FA\u73B0 `\u5BA2\u6237\uFF1AX`\u3001`\u5BA2\u6237\u662FX` \u8FD9\u7C7B\u5B57\u6837\u5374**\u6CA1\u4F20 `crm_members`**\u65F6\uFF0C\u4E00\u6B65\u5EFA\u4F1A\u4F1A\u76F4\u63A5\u62D2\u7EDD\uFF08crm_member_required\uFF09\u2014\u2014\u786E\u8BA4\u8FD9\u4E9B\u5B57\u6837\u4E0D\u662F\u8981\u4E0A\u4F1A\u8868\u7684\u5BA2\u6237\uFF0C\u624D\u4F20 true"
|
|
8057
|
+
},
|
|
8058
|
+
submit_mode: {
|
|
8059
|
+
type: "string",
|
|
8060
|
+
enum: ["direct", "browser"],
|
|
8061
|
+
description: '\u63D0\u4EA4\u65B9\u5F0F\uFF0C\u9ED8\u8BA4 browser\uFF1A\u5728\u5C0Fe \u91CC**\u5F39\u51FA\u6D41\u7A0B\u8868\u5355**\uFF08\u5B57\u6BB5\u5DF2\u9884\u586B\u542B\u4EBA\u5458/\u5BA2\u6237\uFF09\uFF0C\u7528\u6237\u6838\u5BF9\u4FEE\u6539\u540E\u81EA\u5DF1\u70B9\u63D0\u4EA4\u3002direct = \u76F4\u63A5\u5199\u670D\u52A1\u7AEF\uFF08\u4F1A\u8BAE\u5F53\u573A\u751F\u6210\u3001\u9080\u8BF7\u51FD\u7528\u771F\u5B9E\u6570\u636E\uFF0C\u4F46\u6CA1\u6709\u4EBA\u5DE5\u6838\u5BF9\u8868\u5355\u8FD9\u4E00\u6B65\uFF09\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8BF4"\u4E0D\u7528\u6211\u786E\u8BA4\uFF0C\u76F4\u63A5\u5EFA"\u65F6\u624D\u4F20 direct'
|
|
6818
8062
|
}
|
|
6819
8063
|
},
|
|
6820
8064
|
{ required: ["mt_name", "confirm"] }
|
|
@@ -6826,10 +8070,20 @@ var ebMeetingCreateFlowQuick = {
|
|
|
6826
8070
|
"\u4E00\u6B65\u5EFA\u4F1A\u4F1A\u76F4\u63A5\u63D0\u4EA4\u6D41\u7A0B\uFF0C\u5FC5\u987B\u663E\u5F0F\u4F20 confirm=true\uFF1B\u5982\u53EA\u60F3\u770B\u65B9\u6848\uFF0C\u8BF7\u7528 meeting.eb.meeting.create.flow.prepare"
|
|
6827
8071
|
);
|
|
6828
8072
|
}
|
|
6829
|
-
const
|
|
8073
|
+
const crmMentioned = detectCrmMentionInText(args.mt_name, args.mt_desc, args.other_remark);
|
|
8074
|
+
const crmSkipped = args.crm_skip === true;
|
|
8075
|
+
if (crmMentioned && !args.crm_members && !crmSkipped) {
|
|
8076
|
+
throw meetingValidationError(
|
|
8077
|
+
"crm_member_required",
|
|
8078
|
+
`\u4F1A\u8BAE\u540D\u79F0/\u5185\u5BB9\u91CC\u63D0\u5230\u5BA2\u6237\u300C${crmMentioned}\u300D\uFF0C\u4F46\u6CA1\u4F20 crm_members \u2014\u2014 \u63D0\u4EA4\u540E\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u4F1A\u662F\u7A7A\u7684\u3002\u5148 meeting.eb.crm.search {"keyword":"${crmMentioned}"} \u62FF items[].customerId\uFF0C\u518D\u628A crm_members:[{"id":"<customerId>","name":"<\u5B8C\u6574\u5BA2\u6237\u540D>"}] \u4E00\u8D77\u4F20\uFF08\u5FC5\u987B\u5E26\u540D\u79F0\uFF0C\u53EA\u7ED9 id \u4F1A\u88AB\u9759\u9ED8\u5B58\u7A7A\uFF09\uFF1B\u786E\u5B9E\u4E0D\u9700\u8981\u586B\u53C2\u4F1A\u5BA2\u6237\u5C31\u4F20 crm_skip:true\u3002`
|
|
8079
|
+
);
|
|
8080
|
+
}
|
|
8081
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
6830
8082
|
const prepareStartedAt = Date.now();
|
|
8083
|
+
const { submit_mode: _submitMode, confirm: _confirm, ...prepareArgs } = args;
|
|
6831
8084
|
const prepared = await getMeetingOperation2("meeting.eb.meeting.create.flow.prepare").handler(
|
|
6832
|
-
|
|
8085
|
+
// submit_mode 只属于提交阶段,prepare 的 schema 不接受它(additionalProperties:false)
|
|
8086
|
+
prepareArgs,
|
|
6833
8087
|
env
|
|
6834
8088
|
);
|
|
6835
8089
|
if (prepared?.data?.status === "NEEDS_SELECTION") {
|
|
@@ -6845,6 +8099,7 @@ var ebMeetingCreateFlowQuick = {
|
|
|
6845
8099
|
{
|
|
6846
8100
|
continuation,
|
|
6847
8101
|
confirm: true,
|
|
8102
|
+
...args.submit_mode ? { submit_mode: args.submit_mode } : {},
|
|
6848
8103
|
...args.waitSeconds !== void 0 ? { waitSeconds: args.waitSeconds } : {}
|
|
6849
8104
|
},
|
|
6850
8105
|
env
|
|
@@ -6861,6 +8116,8 @@ var ebMeetingCreateFlowQuick = {
|
|
|
6861
8116
|
requestId: applied?.data?.requestId,
|
|
6862
8117
|
meetingId: applied?.data?.meetingId ?? null,
|
|
6863
8118
|
invitation: applied?.data?.invitation ?? null,
|
|
8119
|
+
// 已提交内容回显(字段名 → 值),提交后可直接贴给用户看"到底填进去了什么"
|
|
8120
|
+
submittedPreview: applied?.data?.submittedPreview ?? null,
|
|
6864
8121
|
// 小e 环境(BROWSER_FILL)不写服务端,表单靠这段 <browsertool> 在浏览器里填 —— 必须一起透出,
|
|
6865
8122
|
// 否则宿主拿不到表单,用户看到的就是"提交了但没反应"。
|
|
6866
8123
|
...applied?.data?.contextId ? { contextId: (applied?.data).contextId } : {},
|
|
@@ -6916,7 +8173,7 @@ var ebMeetingCreateSuggest = {
|
|
|
6916
8173
|
const topN = Math.max(1, Math.min(5, Number(args.topN) || 3));
|
|
6917
8174
|
const rawMembers = String(args.hrm_members ?? "").split(/[,;,;\s]+/).map((item) => item.trim()).filter((item) => item !== "");
|
|
6918
8175
|
const nameLike = rawMembers.filter((item) => !/^\d+$/.test(item));
|
|
6919
|
-
const nameToId = nameLike.length > 0 ? await import("./schedule-
|
|
8176
|
+
const nameToId = nameLike.length > 0 ? await import("./schedule-UASAVDVD.js").then((m) => m.resolveMemberIdsByName(env, nameLike)).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
|
|
6920
8177
|
const memberIds = rawMembers.map((item) => nameToId.get(item) ?? item);
|
|
6921
8178
|
const unresolved = rawMembers.filter((item) => nameToId.get(item) === void 0 && !/^\d+$/.test(item));
|
|
6922
8179
|
const selfId = await env.host.getSession().then((s) => String(s?.userId ?? "")).catch(() => "");
|
|
@@ -7088,7 +8345,7 @@ var ebAutoInvitationAfterWrite = async (context) => {
|
|
|
7088
8345
|
const mtId = String(context.dataIds?.[0] ?? "").trim();
|
|
7089
8346
|
if (!isCreate || !enabled || !mtId) return association;
|
|
7090
8347
|
try {
|
|
7091
|
-
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-
|
|
8348
|
+
const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
|
|
7092
8349
|
const render = getMeetingOperation2("meeting.invitation.render");
|
|
7093
8350
|
const result = await render.handler({ mtId }, context.env);
|
|
7094
8351
|
return { ...association ?? {}, invitation: result?.data ?? null };
|
|
@@ -7111,6 +8368,7 @@ var meetingEbOperations = [
|
|
|
7111
8368
|
...meetingEbConflictOperations,
|
|
7112
8369
|
...meetingEbDecisionOperations,
|
|
7113
8370
|
...meetingEbScheduleOperations,
|
|
8371
|
+
...meetingEbCrmOperations,
|
|
7114
8372
|
...meetingEbCreateFlowOperations,
|
|
7115
8373
|
ebRoomRecommendOperation
|
|
7116
8374
|
];
|