weaver-work-cli 0.1.32 → 0.1.36
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 +2 -2
- package/dist/chunks/{archive-UMGX72K6.js → archive-XBVH7JU7.js} +2 -2
- package/dist/chunks/{archive-oa-N2IYBLF3.js → archive-oa-MZM3EKFQ.js} +2 -2
- package/dist/chunks/{asset-GLEGKFG5.js → asset-4XO7UOUW.js} +2 -2
- package/dist/chunks/{attachment-content-AQNX5N3S.js → attachment-content-VXSWANAC.js} +3 -2
- package/dist/chunks/{blog-E44OTVDA.js → blog-PGZKOPSC.js} +2 -2
- package/dist/chunks/{caizhilian-DQUFZXZL.js → caizhilian-BH4ZVGUN.js} +2 -2
- package/dist/chunks/{calendar-JKPIRKFD.js → calendar-MXEMTIO4.js} +2 -2
- package/dist/chunks/{chunk-QWY6PGL6.js → chunk-2LV74IWP.js} +361 -56
- package/dist/chunks/chunk-3SO6QL6U.js +73 -0
- package/dist/chunks/chunk-5DQEEGCC.js +229 -0
- package/dist/chunks/{chunk-G3QJULO2.js → chunk-6LLJFKJE.js} +1 -1
- package/dist/chunks/{chunk-C6R3B2ML.js → chunk-BPE37FPB.js} +35 -7
- package/dist/chunks/chunk-BYATLLEF.js +68 -0
- package/dist/chunks/chunk-BYBSCN4X.js +932 -0
- package/dist/chunks/{chunk-CVZ2JOSW.js → chunk-F746NKNF.js} +1 -1
- package/dist/chunks/{chunk-GCG2NMWR.js → chunk-HXJQI5NM.js} +4 -2
- package/dist/chunks/{chunk-YRVDW4WN.js → chunk-I6QGIBDM.js} +2 -2
- package/dist/chunks/{chunk-H7J4DC5R.js → chunk-JCSN3JGM.js} +2 -2
- package/dist/chunks/{chunk-2GA5ZIQL.js → chunk-JNG42JKG.js} +30 -1
- package/dist/chunks/{chunk-DW6AUUKS.js → chunk-JUXVYKII.js} +9 -4
- package/dist/chunks/{chunk-6RKD4DRZ.js → chunk-JYKABYCV.js} +2 -2
- package/dist/chunks/{chunk-6EFWDL7Y.js → chunk-NCOVUAZK.js} +2 -2
- package/dist/chunks/{chunk-E4Z23GHM.js → chunk-QHFANTX7.js} +1114 -904
- package/dist/chunks/{ebuilder-form-V5FG2EHC.js → chunk-QYGO5EE2.js} +22 -1148
- package/dist/chunks/{chunk-IURUFGZK.js → chunk-T72N74ZT.js} +50 -33
- package/dist/chunks/{chunk-H6XSTSLM.js → chunk-TC6MZAO3.js} +137 -204
- package/dist/chunks/{chunk-WKI2FBIQ.js → chunk-VPUTVEMC.js} +737 -341
- package/dist/chunks/{chunk-WSKBSQ2U.js → chunk-VPXOPQJI.js} +2 -2
- package/dist/chunks/chunk-WXFPWCXG.js +774 -0
- package/dist/chunks/{chunk-4YC43QQ4.js → chunk-XMGSYD6S.js} +4 -4
- package/dist/chunks/conflict-JAB2LJEZ.js +21 -0
- package/dist/chunks/continuation-RN6PZN2M.js +11 -0
- package/dist/chunks/contract-XI2EEIZU.js +9110 -0
- package/dist/chunks/cowork-SCPGLBA4.js +2527 -0
- package/dist/chunks/ebuilder-form-EYLHNOTA.js +121 -0
- package/dist/chunks/{ehr-HMFY6VIL.js → ehr-EAP77IMT.js} +1344 -27
- package/dist/chunks/{esb-ZYSVB7SG.js → esb-2TGGXEE7.js} +4 -4
- package/dist/chunks/{fna-B7RKPAZD.js → fna-2X7ZE7BU.js} +13 -8
- package/dist/chunks/{host-OCH2BCCV.js → host-C6EL2RKL.js} +3 -3
- package/dist/chunks/{host-45WED2KK.js → host-I4NRK4MX.js} +3 -3
- package/dist/chunks/{host-I4Z6BFYX.js → host-Q4LZGCRU.js} +3 -3
- package/dist/chunks/host-UEI5FGDM.js +23 -0
- package/dist/chunks/{host-KNZ52LJZ.js → host-XCLDDXKQ.js} +3 -3
- package/dist/chunks/{hrm-2KAZGUHI.js → hrm-YXERJM76.js} +3 -3
- package/dist/chunks/{im-ACJJWH4U.js → im-A4VZN2TQ.js} +88 -12
- package/dist/chunks/{invoice-ZK3WCX2U.js → invoice-2Z6YPMIS.js} +3 -3
- package/dist/chunks/{jiuchuanhui-5PQD3IL2.js → jiuchuanhui-AR5GMKZB.js} +2 -2
- package/dist/chunks/{lazy-dispatch-JQXBW3GM.js → lazy-dispatch-QXW7P4X3.js} +4 -4
- package/dist/chunks/{mail-S2HDDXO2.js → mail-7GZ6CPBJ.js} +45 -24
- package/dist/chunks/{meeting-QVN3I37L.js → meeting-3NMGA3MB.js} +278 -43
- package/dist/chunks/{okr-QNG4VC2Q.js → okr-BZ6XUOAG.js} +2 -2
- package/dist/chunks/operations-5QL3AECO.js +11 -0
- package/dist/chunks/{plan-A25EMW6U.js → plan-DR5CMUYP.js} +2 -2
- package/dist/chunks/{project-G6XV66DZ.js → project-6J63MK33.js} +2 -2
- package/dist/chunks/{registry-DC6KR3NH.js → registry-KDD7DHNK.js} +4 -4
- package/dist/chunks/{registry-2VLUAESA.js → registry-OZSMDVPP.js} +2 -2
- package/dist/chunks/{registry-7C5UMIPL.js → registry-TKX2E7C7.js} +2 -2
- package/dist/chunks/{registry-TI3CIUXF.js → registry-VRTNC6UR.js} +8 -6
- package/dist/chunks/{room-recommend-WRTHO6Y2.js → room-recommend-XCWRMB5P.js} +4 -3
- package/dist/chunks/{schedule-KFIITGSK.js → schedule-IVBICP32.js} +4 -3
- package/dist/chunks/{workflow-DJ7SYWAF.js → workflow-D74NFK3C.js} +179 -6
- package/dist/index.js +35 -25
- package/dist/internal/e10/auth-recovery.js +14 -4
- package/dist/internal/e10/fetch-timing.js +31 -0
- package/dist/internal/e10/request-runtime.js +5 -0
- package/dist/shortcuts/contract/host.js +34 -59
- package/dist/shortcuts/cowork/continuation.js +70 -0
- package/dist/shortcuts/cowork/errors.js +59 -0
- package/dist/shortcuts/cowork/host.js +180 -0
- package/dist/shortcuts/cowork/index.js +166 -0
- package/dist/shortcuts/cowork/manifest.js +65 -0
- package/dist/shortcuts/cowork/operations/discuss-write.js +277 -0
- package/dist/shortcuts/cowork/operations/item-write.js +380 -0
- package/dist/shortcuts/cowork/operations/member-write.js +283 -0
- package/dist/shortcuts/cowork/operations/permission-write.js +286 -0
- package/dist/shortcuts/cowork/operations/read.js +423 -0
- package/dist/shortcuts/cowork/operations/registry.js +39 -0
- package/dist/shortcuts/cowork/operations/review-write.js +157 -0
- package/dist/shortcuts/cowork/operations/shared.js +215 -0
- package/dist/shortcuts/cowork/operations/types.js +39 -0
- package/dist/shortcuts/cowork/operations.js +19 -0
- package/dist/shortcuts/ehr/host.js +4 -1
- package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +757 -0
- package/dist/shortcuts/ehr/operations/recruit-position.js +367 -0
- package/dist/shortcuts/ehr/operations/recruit-stats.js +133 -0
- package/dist/shortcuts/ehr/operations/recruit-write.js +43 -16
- package/dist/shortcuts/ehr/operations/recruit.js +182 -10
- package/dist/shortcuts/ehr/operations/registry.js +6 -0
- package/dist/shortcuts/fna/operations/expense-chart.js +19 -7
- package/dist/shortcuts/im/diagnostics.js +97 -0
- package/dist/shortcuts/im/host.js +58 -31
- package/dist/shortcuts/im/index.js +7 -2
- package/dist/shortcuts/im/operations/at-mention.js +127 -0
- package/dist/shortcuts/im/operations/file-user.js +10 -2
- package/dist/shortcuts/im/operations/group-read.js +26 -5
- package/dist/shortcuts/im/operations/group-write.js +35 -28
- package/dist/shortcuts/im/operations/msg-sync.js +7 -2
- package/dist/shortcuts/im/operations/msg-write.js +76 -10
- package/dist/shortcuts/im/operations/quote-mention.js +119 -0
- package/dist/shortcuts/im/operations/session.js +1 -1
- package/dist/shortcuts/im/operations/shared.js +10 -0
- package/dist/shortcuts/im/operations/types.js +13 -0
- package/dist/shortcuts/index.js +10 -0
- package/dist/shortcuts/mail/host.js +12 -1
- package/dist/shortcuts/mail/operations/types.js +17 -2
- package/dist/shortcuts/meeting/host.js +27 -34
- package/dist/shortcuts/meeting/index.js +79 -1
- package/dist/shortcuts/meeting/manifest.js +10 -0
- package/dist/shortcuts/meeting/operations/create.js +4 -1
- package/dist/shortcuts/meeting/operations/eb/catalog.js +10 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +84 -8
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1195 -140
- package/dist/shortcuts/meeting/operations/eb/factory.js +170 -8
- package/dist/shortcuts/meeting/operations/eb/index.js +16 -3
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +50 -5
- package/dist/shortcuts/meeting/operations/eb-fallback.js +163 -0
- package/dist/shortcuts/meeting/operations/env.js +99 -46
- package/dist/shortcuts/meeting/operations/form-fields.js +110 -0
- package/dist/shortcuts/meeting/operations/invitation.js +79 -20
- package/dist/shortcuts/meeting/operations/registry.js +2 -0
- package/dist/shortcuts/meeting/operations/standard-guard.js +71 -0
- package/dist/shortcuts/meeting/operations.js +16 -0
- package/dist/shortcuts/workflow/endpoints.js +8 -3
- package/dist/shortcuts/workflow/index.js +110 -1
- package/dist/shortcuts/workflow/operations/form.js +204 -36
- package/dist/shortcuts/workflow/operations/read.js +104 -23
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +448 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +106 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +47 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +30 -23
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +2 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +2 -4
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +138 -181
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +12 -7
- package/dist/shortcuts/workflow/operations.js +23 -1
- package/docs/e10-auth.md +1 -1
- package/docs/ehr.md +1 -1
- package/docs/fna.md +2 -1
- package/docs/im.md +8 -1
- package/docs/todo-smart-convert/README.md +1 -1
- package/docs/todo-smart-convert/data-contract.md +2 -2
- package/docs/todo-smart-convert/subgroup-rules.md +6 -0
- package/package.json +1 -1
- package/skill-template/business-info.json +18 -0
- package/skill-template/domains/cowork.md +14 -0
- package/skill-template/domains/yimiaoban.md +3 -3
- package/skill-template/skill-template.md +1 -1
- package/skills/weaver-e10-blog/SKILL.md +5 -5
- package/skills/weaver-e10-caizhilian/SKILL.md +5 -5
- package/skills/weaver-e10-calendar/SKILL.md +5 -5
- package/skills/weaver-e10-cowork/SKILL.md +101 -0
- package/skills/weaver-e10-cowork/references/cowork-read.md +90 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +131 -0
- package/skills/weaver-e10-cowork/references/safety-boundaries.md +45 -0
- package/skills/weaver-e10-esb/SKILL.md +5 -5
- package/skills/weaver-e10-hrm/SKILL.md +5 -5
- package/skills/weaver-e10-jinchengda/SKILL.md +2 -2
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +5 -5
- package/skills/weaver-e10-jucailin/SKILL.md +38 -14
- package/skills/weaver-e10-jucailin/references/recruit-create.md +104 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +25 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +13 -0
- package/skills/weaver-e10-jucailin/references/salary.md +15 -11
- package/skills/weaver-e10-mail/SKILL.md +17 -14
- package/skills/weaver-e10-meeting/SKILL.md +442 -46
- package/skills/weaver-e10-meeting/references/meeting-eb.md +135 -3
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +28 -2
- package/skills/weaver-e10-meeting/references/meeting-queries.md +9 -6
- package/skills/weaver-e10-meeting/references/meeting-verification.md +8 -6
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/SKILL.md +5 -5
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-plan/SKILL.md +5 -5
- package/skills/weaver-e10-qiyecheng/SKILL.md +5 -2
- package/skills/weaver-e10-qiyecheng/references/catalog.md +2 -2
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +15 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +22 -21
- package/skills/weaver-e10-shared/SKILL.md +12 -12
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -4
- package/skills/weaver-e10-wenshuding/SKILL.md +5 -5
- package/skills/weaver-e10-workflow/SKILL.md +29 -5
- package/skills/weaver-e10-workflow/aigroup/default.json +88 -0
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +66 -14
- package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +1 -1
- package/skills/weaver-e10-workflow/references/workflow-memory.md +1 -1
- package/skills/weaver-e10-workflow/references/workflow-query.md +12 -10
- package/skills/weaver-e10-workflow/references/workflow-view.md +2 -2
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +239 -0
- package/skills/weaver-e10-workflow/{scripts → tools}/todo-summary.cjs +218 -28
- package/skills/weaver-e10-yepiaotong/SKILL.md +10 -8
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +10 -10
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +40 -37
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -4
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +27 -38
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +4 -4
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +37 -29
- package/skills/weaver-e10-yimiaoban/SKILL.md +156 -33
- package/skills/weaver-e10-yimiaoban/references/ding-write.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/error-codes.md +5 -1
- package/skills/weaver-e10-yimiaoban/references/group-read.md +5 -1
- package/skills/weaver-e10-yimiaoban/references/group-write.md +6 -4
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -0
- package/skills/weaver-e10-yimiaoban/references/msg-write.md +34 -2
- package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +5 -2
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +79 -58
- package/skills/weaver-e10-yimiaoban/references/user-remind.md +2 -2
- package/skills/weaver-e10-ziguanjia/SKILL.md +5 -5
|
@@ -21,8 +21,10 @@ import {
|
|
|
21
21
|
} from "./chunk-AJ62BGAW.js";
|
|
22
22
|
import {
|
|
23
23
|
E10_REAUTH_GUIDANCE,
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
createFetchTimingSink,
|
|
25
|
+
hasXiaoEEnv,
|
|
26
|
+
runWithFetchTiming
|
|
27
|
+
} from "./chunk-JNG42JKG.js";
|
|
26
28
|
|
|
27
29
|
// src/shortcuts/workflow/operations/form.ts
|
|
28
30
|
import { randomUUID } from "node:crypto";
|
|
@@ -341,9 +343,9 @@ var FORM_ENDPOINTS = {
|
|
|
341
343
|
tenantSetting: "/api/file/tenant/setting"
|
|
342
344
|
};
|
|
343
345
|
var AJAX_QUERY = { sf_request_type: "ajax" };
|
|
344
|
-
function formApiUrl(path, relateType) {
|
|
346
|
+
function formApiUrl(path, relateType, ebPrefix = "/api/ebuilder/flow/") {
|
|
345
347
|
if (String(relateType || "").trim() === "WEA_EBUILDER") {
|
|
346
|
-
return path.replace("/api/workflow/core/",
|
|
348
|
+
return path.replace("/api/workflow/core/", ebPrefix);
|
|
347
349
|
}
|
|
348
350
|
return path;
|
|
349
351
|
}
|
|
@@ -2030,7 +2032,7 @@ var workflowSearch = {
|
|
|
2030
2032
|
}, env, { json: "last_search.json", md: "last_search.md" })), startedAt);
|
|
2031
2033
|
}
|
|
2032
2034
|
};
|
|
2033
|
-
var SMART_GROUPING_MIN_OA_VERSION = [10, 0,
|
|
2035
|
+
var SMART_GROUPING_MIN_OA_VERSION = [10, 0, 9807, 1];
|
|
2034
2036
|
function formatOaVersion(tuple) {
|
|
2035
2037
|
const [a, b, c, d] = tuple;
|
|
2036
2038
|
return `${a}.${b}.${c}.${String(d).padStart(2, "0")}`;
|
|
@@ -4839,11 +4841,25 @@ function formatHistoryFieldValue(raw, field) {
|
|
|
4839
4841
|
}
|
|
4840
4842
|
return stringifyDetailValue(raw);
|
|
4841
4843
|
}
|
|
4844
|
+
var SAAS_COLOGY_BASE_URL = "https://www.e-cology.com.cn";
|
|
4845
|
+
function isSaasCologyBaseUrl(baseUrl) {
|
|
4846
|
+
const normalize = (value) => String(value ?? "").trim().replace(/\/+$/u, "").toLowerCase();
|
|
4847
|
+
return normalize(baseUrl) === SAAS_COLOGY_BASE_URL;
|
|
4848
|
+
}
|
|
4849
|
+
async function isSaasCologyEnv(env) {
|
|
4850
|
+
try {
|
|
4851
|
+
const session = await env.host.getSession();
|
|
4852
|
+
return isSaasCologyBaseUrl(session?.baseUrl);
|
|
4853
|
+
} catch {
|
|
4854
|
+
return false;
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4842
4857
|
async function fetchHistoryListSnapshot(env, options = {}) {
|
|
4843
4858
|
try {
|
|
4844
4859
|
const now = /* @__PURE__ */ new Date();
|
|
4845
4860
|
const start = new Date(now.getTime() - HISTORY_LOOKBACK_DAYS * 24 * 60 * 60 * 1e3);
|
|
4846
4861
|
const historyWorkflowId = String(options.workflowId ?? "").trim();
|
|
4862
|
+
const addDisableCheckUserPermission = await isSaasCologyEnv(env);
|
|
4847
4863
|
const listResponse = await env.host.workflowRequest({
|
|
4848
4864
|
method: "POST",
|
|
4849
4865
|
path: WORKFLOW_ENDPOINTS.MINE_LIST,
|
|
@@ -4855,7 +4871,9 @@ async function fetchHistoryListSnapshot(env, options = {}) {
|
|
|
4855
4871
|
dimension: "mine",
|
|
4856
4872
|
flowSpareType: 1,
|
|
4857
4873
|
outType: 0,
|
|
4858
|
-
needIutData: false
|
|
4874
|
+
needIutData: false,
|
|
4875
|
+
// SaaS 公有云环境写死带上(见 `SAAS_COLOGY_BASE_URL`);其余环境不带此键。
|
|
4876
|
+
...addDisableCheckUserPermission ? { disableCheckUserPermission: "1" } : {}
|
|
4859
4877
|
},
|
|
4860
4878
|
// `needParseData: true`:让服务端把日期等字段直接解析成可读文本(`displayData`),
|
|
4861
4879
|
// 客户端不再自己转。
|
|
@@ -4944,7 +4962,31 @@ async function pickUniqueMineWorkflow(candidates, env) {
|
|
|
4944
4962
|
return null;
|
|
4945
4963
|
}
|
|
4946
4964
|
}
|
|
4947
|
-
|
|
4965
|
+
function prefetchHistoryDetails(env, listed) {
|
|
4966
|
+
const requestIds = listed?.requestIds ?? [];
|
|
4967
|
+
if (!requestIds.length) return Promise.resolve([]);
|
|
4968
|
+
return (async () => {
|
|
4969
|
+
const session = await env.host.getSession();
|
|
4970
|
+
return Promise.all(requestIds.map(async (requestId) => {
|
|
4971
|
+
const payload = {
|
|
4972
|
+
requestId,
|
|
4973
|
+
isGetRequestBaseInfo: false,
|
|
4974
|
+
isGetRequestLog: false,
|
|
4975
|
+
isGetFormData: true,
|
|
4976
|
+
isReadRequest: false
|
|
4977
|
+
};
|
|
4978
|
+
if (session.userId) payload.userId = session.userId;
|
|
4979
|
+
const response = await env.host.workflowRequest({
|
|
4980
|
+
method: "POST",
|
|
4981
|
+
path: WORKFLOW_ENDPOINTS.REQUEST_DETAIL,
|
|
4982
|
+
operation: "workflow.createRequest.history.detail",
|
|
4983
|
+
body: payload
|
|
4984
|
+
});
|
|
4985
|
+
return detailDataOf(response);
|
|
4986
|
+
}));
|
|
4987
|
+
})();
|
|
4988
|
+
}
|
|
4989
|
+
async function buildHistoryRequestData(env, fields, targets, options = {}, prefetchedList, prefetchedDetails) {
|
|
4948
4990
|
const targetList = toArray(targets).filter((item) => !item?.systemField && String(item?.id ?? "").trim()).map((item) => ({ id: String(item.id).trim(), name: String(item.name ?? item.id) }));
|
|
4949
4991
|
if (!targetList.length && !options.allFormFields) return null;
|
|
4950
4992
|
const fieldMeta = /* @__PURE__ */ new Map();
|
|
@@ -4956,7 +4998,7 @@ async function buildHistoryRequestData(env, fields, targets, options = {}, prefe
|
|
|
4956
4998
|
const items = listed.items;
|
|
4957
4999
|
const requestIds = listed.requestIds;
|
|
4958
5000
|
const session = await env.host.getSession();
|
|
4959
|
-
const details = await Promise.all(requestIds.map(async (requestId) => {
|
|
5001
|
+
const details = prefetchedDetails ? await prefetchedDetails : await Promise.all(requestIds.map(async (requestId) => {
|
|
4960
5002
|
const payload = {
|
|
4961
5003
|
requestId,
|
|
4962
5004
|
isGetRequestBaseInfo: false,
|
|
@@ -4973,6 +5015,7 @@ async function buildHistoryRequestData(env, fields, targets, options = {}, prefe
|
|
|
4973
5015
|
});
|
|
4974
5016
|
return detailDataOf(response);
|
|
4975
5017
|
}));
|
|
5018
|
+
if (!details) return null;
|
|
4976
5019
|
const result = [];
|
|
4977
5020
|
for (let index = 0; index < details.length; index += 1) {
|
|
4978
5021
|
const data = details[index] || {};
|
|
@@ -5307,6 +5350,7 @@ function parseTenantSetting(data) {
|
|
|
5307
5350
|
return { max_size_mb: maxSizeMb, format_mode: whitesEnable ? "white" : "black", formats };
|
|
5308
5351
|
}
|
|
5309
5352
|
function buildLayoutRequest(workflowId, runtime, frame) {
|
|
5353
|
+
const isEbForm = String(frame.relate_type ?? "").trim() === "WEA_EBUILDER";
|
|
5310
5354
|
const custom = {
|
|
5311
5355
|
permissionType: frame.permission_type,
|
|
5312
5356
|
requestId: runtime.request_id,
|
|
@@ -5322,6 +5366,7 @@ function buildLayoutRequest(workflowId, runtime, frame) {
|
|
|
5322
5366
|
mobile: false,
|
|
5323
5367
|
formId: frame.form_id,
|
|
5324
5368
|
source: "view",
|
|
5369
|
+
...isEbForm ? { bridgeService: "ebuilder" } : {},
|
|
5325
5370
|
isAgent: false,
|
|
5326
5371
|
beAgentId: "0",
|
|
5327
5372
|
hideSysFieldArea: true,
|
|
@@ -5336,7 +5381,7 @@ function buildLayoutRequest(workflowId, runtime, frame) {
|
|
|
5336
5381
|
terminalType: "PC",
|
|
5337
5382
|
formId: frame.form_id,
|
|
5338
5383
|
...nodePermissionEnabled && permissionId ? { permissionId } : {},
|
|
5339
|
-
module: "workflow",
|
|
5384
|
+
module: isEbForm ? "ebuildercard" : "workflow",
|
|
5340
5385
|
customParam: custom,
|
|
5341
5386
|
cacheUid: randomUUID(),
|
|
5342
5387
|
newLayout: frame.new_layout,
|
|
@@ -5994,7 +6039,20 @@ async function resolveCreateWorkflow(rawWorkflow, env) {
|
|
|
5994
6039
|
throw workflowClarificationError(
|
|
5995
6040
|
"workflow",
|
|
5996
6041
|
"",
|
|
5997
|
-
"\u8981\u53D1\u8D77\u54EA\u4E2A\u6D41\u7A0B\uFF1F\u8BF7\u63D0\u4F9B\u8BE5\u6D41\u7A0B\u7684\u5B8C\u6574\u540D\u79F0\uFF08\u6216\u5176\u5B83\u53EF\u7528\u4E8E\u68C0\u7D22\u7684\u5173\u952E\u8BCD\uFF09\u540E\u518D\u7EE7\u7EED\u3002"
|
|
6042
|
+
"\u8981\u53D1\u8D77\u54EA\u4E2A\u6D41\u7A0B\uFF1F\u8BF7\u63D0\u4F9B\u8BE5\u6D41\u7A0B\u7684\u5B8C\u6574\u540D\u79F0\uFF08\u6216\u5176\u5B83\u53EF\u7528\u4E8E\u68C0\u7D22\u7684\u5173\u952E\u8BCD\uFF09\u540E\u518D\u7EE7\u7EED\u3002",
|
|
6043
|
+
[],
|
|
6044
|
+
{
|
|
6045
|
+
clarificationReason: "workflow_required",
|
|
6046
|
+
missingInput: ["workflow"],
|
|
6047
|
+
requiredInput: {
|
|
6048
|
+
workflow: {
|
|
6049
|
+
required: true,
|
|
6050
|
+
type: "string | string[]",
|
|
6051
|
+
description: "\u8981\u53D1\u8D77\u7684\u5DE5\u4F5C\u6D41\uFF1A\u5B8C\u6574\u540D\u79F0\u3001\u540D\u79F0\u5173\u952E\u8BCD\uFF0C\u6216\u300C\u540D\u79F0(ID)\u300D\uFF1B\u7EAF\u6570\u5B57\u6309\u5DE5\u4F5C\u6D41 ID \u5904\u7406\u3002",
|
|
6052
|
+
example: ["\u8D39\u7528\u62A5\u9500"]
|
|
6053
|
+
}
|
|
6054
|
+
}
|
|
6055
|
+
}
|
|
5998
6056
|
);
|
|
5999
6057
|
}
|
|
6000
6058
|
const explicitIds = /* @__PURE__ */ new Set();
|
|
@@ -6164,15 +6222,15 @@ function singleExplicitWorkflowId(rawWorkflow) {
|
|
|
6164
6222
|
const parsed = parseNameWithId(terms[0]);
|
|
6165
6223
|
return parsed.id ?? (/^[0-9]+$/.test(terms[0]) ? terms[0] : "");
|
|
6166
6224
|
}
|
|
6167
|
-
async function loadCreateFormPack(workflowId, env) {
|
|
6225
|
+
async function loadCreateFormPack(workflowId, env, options = {}) {
|
|
6168
6226
|
const [{ data }, workflowMemory] = await Promise.all([
|
|
6169
|
-
buildCreateFormData(workflowId, env),
|
|
6227
|
+
buildCreateFormData(workflowId, env, options),
|
|
6170
6228
|
// 记忆读取是 best-effort(内部全 catch),不会把表单载入的错误顶掉。
|
|
6171
6229
|
fetchWorkflowMemory(workflowId, env)
|
|
6172
6230
|
]);
|
|
6173
6231
|
return { data, workflowMemory };
|
|
6174
6232
|
}
|
|
6175
|
-
async function prepareCreateFormPayload(args, env) {
|
|
6233
|
+
async function prepareCreateFormPayload(args, env, options = {}) {
|
|
6176
6234
|
const authStartedAt = Date.now();
|
|
6177
6235
|
await env.host.getSession();
|
|
6178
6236
|
const authMs = Date.now() - authStartedAt;
|
|
@@ -6181,10 +6239,10 @@ async function prepareCreateFormPayload(args, env) {
|
|
|
6181
6239
|
const explicitId = singleExplicitWorkflowId(args.workflow);
|
|
6182
6240
|
if (explicitId) {
|
|
6183
6241
|
target = { id: explicitId, name: "", source: "workflowId" };
|
|
6184
|
-
pack = await loadCreateFormPack(explicitId, env);
|
|
6242
|
+
pack = await loadCreateFormPack(explicitId, env, options);
|
|
6185
6243
|
} else {
|
|
6186
6244
|
target = await resolveCreateWorkflow(args.workflow, env);
|
|
6187
|
-
pack = await loadCreateFormPack(target.id, env);
|
|
6245
|
+
pack = await loadCreateFormPack(target.id, env, options);
|
|
6188
6246
|
}
|
|
6189
6247
|
const fullPayload = {
|
|
6190
6248
|
...pack.data,
|
|
@@ -6234,10 +6292,15 @@ async function commandCreateForm(args, env) {
|
|
|
6234
6292
|
};
|
|
6235
6293
|
return workflowSuccess("workflow.createForm", result);
|
|
6236
6294
|
}
|
|
6237
|
-
async function buildCreateFormData(workflowId, env) {
|
|
6295
|
+
async function buildCreateFormData(workflowId, env, options = {}) {
|
|
6296
|
+
const detailMark = options.detailMark === "isDetail" ? "isDetail" : "subFormId";
|
|
6297
|
+
const getHistory = options.getHistory !== false;
|
|
6238
6298
|
const query = { workflowId, isCreate: 1, ...AJAX_QUERY };
|
|
6239
6299
|
const body = { workflowId, isCreate: 1, isMobile: 0 };
|
|
6240
|
-
const historyListSnapshot = fetchHistoryListSnapshot(env, { workflowId }).catch(() => null);
|
|
6300
|
+
const historyListSnapshot = getHistory ? fetchHistoryListSnapshot(env, { workflowId }).catch(() => null) : Promise.resolve(null);
|
|
6301
|
+
const historyDetails = getHistory ? historyListSnapshot.then(async (snapshot) => snapshot && snapshot.requestIds.length ? prefetchHistoryDetails(env, snapshot) : null) : Promise.resolve(null);
|
|
6302
|
+
historyDetails.catch(() => {
|
|
6303
|
+
});
|
|
6241
6304
|
const isXiaoE = hasXiaoEEnv(env.ctx.env, env.ctx.getGlobalOptions?.());
|
|
6242
6305
|
const basePromise = requestJson(env, "POST", FORM_ENDPOINTS.loadBase, query, body, { tolerateBusinessError: true }).then((value) => ({ ok: true, value })).catch((error) => ({ ok: false, error }));
|
|
6243
6306
|
const framePromise = requestJson(env, "POST", FORM_ENDPOINTS.loadFrame, query, body).then((value) => ({ ok: true, value })).catch((error) => ({ ok: false, error }));
|
|
@@ -6411,7 +6474,11 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
6411
6474
|
if (!modelFieldIds.has(String(field.id ?? ""))) continue;
|
|
6412
6475
|
const slimSubFormId = String(field.subFormId ?? "");
|
|
6413
6476
|
const item = { id: field.id, name: field.name };
|
|
6414
|
-
if (
|
|
6477
|
+
if (detailMark === "isDetail") {
|
|
6478
|
+
if (slimSubFormId) item.isDetail = true;
|
|
6479
|
+
} else if (slimSubFormId) {
|
|
6480
|
+
item.subFormId = slimSubFormId;
|
|
6481
|
+
}
|
|
6415
6482
|
item.componentKey = field.componentKey;
|
|
6416
6483
|
const initialValue = initialValueByFieldId.get(String(field.id ?? ""));
|
|
6417
6484
|
if (initialValue !== void 0) item.initialValue = initialValue;
|
|
@@ -6446,8 +6513,8 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
6446
6513
|
}
|
|
6447
6514
|
if (String(field.componentKey ?? "").toLowerCase() === "textarea" && field.richEditor) item.componentKey = "RichText";
|
|
6448
6515
|
if (String(field.format ?? "").trim()) item.format = String(field.format).trim();
|
|
6449
|
-
const
|
|
6450
|
-
if (
|
|
6516
|
+
const options2 = field.options || [];
|
|
6517
|
+
if (options2.length) item.options = options2;
|
|
6451
6518
|
slimFields.push(item);
|
|
6452
6519
|
}
|
|
6453
6520
|
const fieldsById = /* @__PURE__ */ new Map();
|
|
@@ -6456,13 +6523,15 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
6456
6523
|
...requiredFieldsList.map((f) => String(f?.id ?? "")),
|
|
6457
6524
|
...Object.values(subFormRequired).flatMap((list) => list.map((f) => String(f?.id ?? "")))
|
|
6458
6525
|
].filter(Boolean))];
|
|
6459
|
-
const historyCache = fields.length ? await buildHistoryRequestData(
|
|
6526
|
+
const historyCache = getHistory && fields.length ? await buildHistoryRequestData(
|
|
6460
6527
|
env,
|
|
6461
6528
|
fields,
|
|
6462
6529
|
historyRequiredFieldIds.map((id) => ({ id, name: String((fieldsById.get(id) || {}).name ?? id) })),
|
|
6463
6530
|
{ allFormFields: true, workflowId },
|
|
6464
6531
|
// 本命令开头就已并发发起的列表请求:这里只补「详情」那几步(P2)。
|
|
6465
|
-
historyListSnapshot
|
|
6532
|
+
historyListSnapshot,
|
|
6533
|
+
// 明细也已在列表返回时就发出去(与 layout 并行),这里只等它回来、按本表单字段组装。
|
|
6534
|
+
historyDetails
|
|
6466
6535
|
) : null;
|
|
6467
6536
|
const session = await getSessionContext(env);
|
|
6468
6537
|
const context = {
|
|
@@ -6532,7 +6601,9 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
6532
6601
|
// 历史参考值(近一年、非草稿、最近 5 条「我发起的」)——填值前先看它,能直接照用的字段就别去
|
|
6533
6602
|
// 问用户。字段范围与 `fields` **同一口径**(见 modelFieldIds 注释);完整结果(本表单全部字段)
|
|
6534
6603
|
// 仍随句柄留给 `createRequest` 用(条件必填要到那边才现身)。
|
|
6535
|
-
|
|
6604
|
+
// `getHistory:false`(隐藏入参)时整段历史取数没做 ⇒ 这里给 `null`(不是空数组:空数组表示
|
|
6605
|
+
// "查了但没数据",两者含义不同)。
|
|
6606
|
+
historyRequestData: getHistory ? filterHistoryRequestData(historyCache, modelFieldIds) : null,
|
|
6536
6607
|
systemFields: {
|
|
6537
6608
|
permissions: minorInfo.permissions || {},
|
|
6538
6609
|
defaults: context.systemFields.defaults,
|
|
@@ -7582,9 +7653,10 @@ async function runFieldLinkage(env, ctx, entries, actionTypes, allDetails, isEdi
|
|
|
7582
7653
|
}
|
|
7583
7654
|
}
|
|
7584
7655
|
if (!dataList.length && !runDataList.length) return [];
|
|
7656
|
+
const linkageModule = formModuleName(ctx.frame && ctx.frame.relate_type, "ebuilderform");
|
|
7585
7657
|
const executeParam = {
|
|
7586
7658
|
formId: ctx.layout.form_id,
|
|
7587
|
-
module:
|
|
7659
|
+
module: linkageModule,
|
|
7588
7660
|
dataList,
|
|
7589
7661
|
runDataList,
|
|
7590
7662
|
moduleDataList: []
|
|
@@ -7625,9 +7697,9 @@ async function runFieldLinkage(env, ctx, entries, actionTypes, allDetails, isEdi
|
|
|
7625
7697
|
const frame = ctx.frame || {};
|
|
7626
7698
|
if (frame.layout_multi_id) executeParam.layoutId = frame.layout_multi_id;
|
|
7627
7699
|
}
|
|
7628
|
-
const payload = { formId: ctx.layout.form_id, module:
|
|
7700
|
+
const payload = { formId: ctx.layout.form_id, module: linkageModule, executeParam };
|
|
7629
7701
|
const relateType = ctx.frame && ctx.frame.relate_type || "";
|
|
7630
|
-
const endpoint = formApiUrl(FORM_ENDPOINTS.fdLinkage, relateType);
|
|
7702
|
+
const endpoint = formApiUrl(FORM_ENDPOINTS.fdLinkage, relateType, "/api/ebuilder/form/");
|
|
7631
7703
|
const response = await requestJson(env, "POST", endpoint, AJAX_QUERY, payload);
|
|
7632
7704
|
const data = response && typeof response === "object" ? response : null;
|
|
7633
7705
|
const linkageList = data && typeof data === "object" ? data.linkageDataList : null;
|
|
@@ -8234,6 +8306,15 @@ function xiaoECustomParams(preview) {
|
|
|
8234
8306
|
}
|
|
8235
8307
|
return { values, keys: ordered };
|
|
8236
8308
|
}
|
|
8309
|
+
function xiaoESrcFieldQuery(params) {
|
|
8310
|
+
let query = "";
|
|
8311
|
+
for (const fieldId of params.keys) {
|
|
8312
|
+
const text = params.values[fieldId];
|
|
8313
|
+
if (!text) continue;
|
|
8314
|
+
query += `&${fieldId}=${text}`;
|
|
8315
|
+
}
|
|
8316
|
+
return query;
|
|
8317
|
+
}
|
|
8237
8318
|
function renderXiaoEFillFormMarkdown(params) {
|
|
8238
8319
|
const base = String(params.baseUrl ?? "").replace(/\/+$/u, "");
|
|
8239
8320
|
const workflowId = String(params.workflowId ?? "").trim();
|
|
@@ -8245,7 +8326,7 @@ function renderXiaoEFillFormMarkdown(params) {
|
|
|
8245
8326
|
arguments: {
|
|
8246
8327
|
type: "e10",
|
|
8247
8328
|
title: String(params.title ?? ""),
|
|
8248
|
-
src: `${base}/sp/workflow${createPath}?workflowId=${workflowId}&isCreate=1`,
|
|
8329
|
+
src: `${base}/sp/workflow${createPath}?workflowId=${workflowId}&isCreate=1${xiaoESrcFieldQuery(params.customParams)}`,
|
|
8249
8330
|
sdkOptions: {
|
|
8250
8331
|
compName: XIAOE_FILL_FORM_SDK_OPTIONS.compName,
|
|
8251
8332
|
routerType: XIAOE_FILL_FORM_SDK_OPTIONS.routerType,
|
|
@@ -8728,10 +8809,18 @@ function apiShortName(path) {
|
|
|
8728
8809
|
function withApiTiming(host, spans) {
|
|
8729
8810
|
const record = async (path, run) => {
|
|
8730
8811
|
const start = Date.now();
|
|
8812
|
+
const fetchTiming = createFetchTimingSink();
|
|
8731
8813
|
try {
|
|
8732
|
-
return await run
|
|
8814
|
+
return await runWithFetchTiming(fetchTiming, run);
|
|
8733
8815
|
} finally {
|
|
8734
|
-
spans.push({
|
|
8816
|
+
spans.push({
|
|
8817
|
+
name: apiShortName(path),
|
|
8818
|
+
start,
|
|
8819
|
+
end: Date.now(),
|
|
8820
|
+
fetchStart: fetchTiming.fetchStart,
|
|
8821
|
+
fetchEnd: fetchTiming.fetchEnd,
|
|
8822
|
+
fetchMs: fetchTiming.fetchMs
|
|
8823
|
+
});
|
|
8735
8824
|
}
|
|
8736
8825
|
};
|
|
8737
8826
|
return {
|
|
@@ -8770,18 +8859,33 @@ function summarizeApiSpans(spans) {
|
|
|
8770
8859
|
const items = group.map((item) => ({
|
|
8771
8860
|
name: item.name,
|
|
8772
8861
|
at: Math.max(0, Math.round(item.start - origin)),
|
|
8773
|
-
ms: Math.max(0, Math.round(item.end - item.start))
|
|
8862
|
+
ms: Math.max(0, Math.round(item.end - item.start)),
|
|
8863
|
+
fetchAt: item.fetchStart === null ? null : Math.max(0, Math.round(item.fetchStart - origin)),
|
|
8864
|
+
fetchEnd: item.fetchEnd === null ? null : Math.max(0, Math.round(item.fetchEnd - origin)),
|
|
8865
|
+
fetchCost: Math.max(0, Math.round(item.fetchMs))
|
|
8774
8866
|
})).sort((a, b) => b.ms - a.ms || a.at - b.at);
|
|
8775
8867
|
slowest.push({ batch: key, name: items[0].name, ms: items[0].ms, items });
|
|
8776
8868
|
}
|
|
8777
8869
|
}
|
|
8778
8870
|
return { durations, slowest };
|
|
8779
8871
|
}
|
|
8872
|
+
function readHiddenGetHistory(value) {
|
|
8873
|
+
if (value === false || value === 0) return false;
|
|
8874
|
+
if (typeof value === "string") {
|
|
8875
|
+
const text = value.trim().toLowerCase();
|
|
8876
|
+
if (text === "false" || text === "0") return false;
|
|
8877
|
+
}
|
|
8878
|
+
return true;
|
|
8879
|
+
}
|
|
8780
8880
|
async function commandCreateRequestDirect(args, env) {
|
|
8781
8881
|
const startedAt = Date.now();
|
|
8782
8882
|
const spans = [];
|
|
8783
8883
|
const timedEnv = { ...env, host: withApiTiming(env.host, spans) };
|
|
8784
|
-
const
|
|
8884
|
+
const getHistory = readHiddenGetHistory(args.getHistory);
|
|
8885
|
+
const { payload, authMs } = await prepareCreateFormPayload(args, timedEnv, {
|
|
8886
|
+
getHistory,
|
|
8887
|
+
detailMark: "isDetail"
|
|
8888
|
+
});
|
|
8785
8889
|
const contextId = String(payload.contextId ?? "");
|
|
8786
8890
|
if (!contextId) {
|
|
8787
8891
|
throw workflowValidationError("context_missing", "\u8868\u5355\u8F7D\u5165\u672A\u4EA7\u51FA\u53EF\u7528\u53E5\u67C4\uFF0C\u8BF7\u91CD\u8BD5");
|
|
@@ -8808,7 +8912,7 @@ async function commandCreateRequestDirect(args, env) {
|
|
|
8808
8912
|
"workflow.createRequestDirect"
|
|
8809
8913
|
) > CREATE_FORM_STDOUT_SAFE_CHARS;
|
|
8810
8914
|
if (overLine()) {
|
|
8811
|
-
data.historyRequestData = [];
|
|
8915
|
+
if (getHistory) data.historyRequestData = [];
|
|
8812
8916
|
if ("userMemory" in data && overLine()) data.userMemory = "";
|
|
8813
8917
|
}
|
|
8814
8918
|
return workflowSuccess("workflow.createRequestDirect", {
|
|
@@ -8828,10 +8932,14 @@ function formatRemark(value) {
|
|
|
8828
8932
|
if (text.startsWith("_weaverMte_")) return text;
|
|
8829
8933
|
return `_weaverMte_<p>${text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</p>`;
|
|
8830
8934
|
}
|
|
8935
|
+
function formModuleName(relateType, ebModule = "ebuildercard") {
|
|
8936
|
+
return String(relateType ?? "").trim() === "WEA_EBUILDER" ? ebModule : "workflow";
|
|
8937
|
+
}
|
|
8831
8938
|
function buildSaveBody(context, prepared) {
|
|
8832
8939
|
const runtime = context.runtime;
|
|
8940
|
+
const moduleName = formModuleName(context.frame?.relate_type);
|
|
8833
8941
|
return {
|
|
8834
|
-
module:
|
|
8942
|
+
module: moduleName,
|
|
8835
8943
|
customParam: {
|
|
8836
8944
|
isCreate: true,
|
|
8837
8945
|
requestId: runtime.request_id,
|
|
@@ -8849,7 +8957,7 @@ function buildSaveBody(context, prepared) {
|
|
|
8849
8957
|
},
|
|
8850
8958
|
employeeId: runtime.employee_id,
|
|
8851
8959
|
formData: {
|
|
8852
|
-
module:
|
|
8960
|
+
module: moduleName,
|
|
8853
8961
|
presetDataId: runtime.request_id,
|
|
8854
8962
|
dataDetails: prepared.dataDetails,
|
|
8855
8963
|
client: "pc",
|
|
@@ -9226,12 +9334,15 @@ async function runCreateNodeFieldVerification(env, context, switches) {
|
|
|
9226
9334
|
result.passed = !result.blocked;
|
|
9227
9335
|
return result;
|
|
9228
9336
|
}
|
|
9229
|
-
function buildEditDataLayoutRequest(requestId, workflowId, nodeId, formId, dataId, layoutMultiId, viewFormNodeId, permissionType, runtime) {
|
|
9337
|
+
function buildEditDataLayoutRequest(requestId, workflowId, nodeId, formId, dataId, layoutMultiId, viewFormNodeId, permissionType, runtime, relateType) {
|
|
9230
9338
|
return {
|
|
9231
9339
|
terminalType: "PC",
|
|
9232
9340
|
dataId,
|
|
9233
9341
|
formId,
|
|
9234
|
-
|
|
9342
|
+
// 建模表单取 `ebuilderform`(2026-10-30 真机请求体实证),**不是** `ebuildercard`:
|
|
9343
|
+
// 同为 `form/core` 下的接口,`getFormLayout` / `saveFormData` 是 `ebuildercard`,
|
|
9344
|
+
// 本接口与 `executeFdLinkage` 是 `ebuilderform` —— 建模表单内部不能按"同族"推定。
|
|
9345
|
+
module: formModuleName(relateType, "ebuilderform"),
|
|
9235
9346
|
newLayout: true,
|
|
9236
9347
|
cacheUid: null,
|
|
9237
9348
|
layoutMultiId,
|
|
@@ -9301,7 +9412,7 @@ async function commandEditLoad(args, env) {
|
|
|
9301
9412
|
tenantSetting = {};
|
|
9302
9413
|
}
|
|
9303
9414
|
const dataId = requestId;
|
|
9304
|
-
const dlResp = await requestJson(env, "POST", formApiUrl(FORM_ENDPOINTS.formDataAndLayout, frame.relate_type), { formId: frame.form_id, dataId, ...AJAX_QUERY }, buildEditDataLayoutRequest(requestId, workflowId, runtime.node_id, frame.form_id, dataId, frame.layout_multi_id, frame.view_form_node_id, frame.permission_type, runtime));
|
|
9415
|
+
const dlResp = await requestJson(env, "POST", formApiUrl(FORM_ENDPOINTS.formDataAndLayout, frame.relate_type), { formId: frame.form_id, dataId, ...AJAX_QUERY }, buildEditDataLayoutRequest(requestId, workflowId, runtime.node_id, frame.form_id, dataId, frame.layout_multi_id, frame.view_form_node_id, frame.permission_type, runtime, frame.relate_type));
|
|
9305
9416
|
const dlData = dlResp;
|
|
9306
9417
|
if (!dlData || typeof dlData !== "object") throw workflowApiError("format_error", "getFormDataAndLayout \u672A\u8FD4\u56DE\u6709\u6548 data");
|
|
9307
9418
|
const vrc = Array.isArray(dlData.viewRelateConfig) ? dlData.viewRelateConfig : [];
|
|
@@ -9547,8 +9658,9 @@ async function commandEditPrepare(args, env) {
|
|
|
9547
9658
|
}
|
|
9548
9659
|
function buildEditSaveBody(context, prepared) {
|
|
9549
9660
|
const runtime = context.runtime || {};
|
|
9661
|
+
const moduleName = formModuleName(context.frame?.relate_type);
|
|
9550
9662
|
return {
|
|
9551
|
-
module:
|
|
9663
|
+
module: moduleName,
|
|
9552
9664
|
customParam: {
|
|
9553
9665
|
isCreate: false,
|
|
9554
9666
|
requestId: context.requestId ?? context.request_id,
|
|
@@ -9568,7 +9680,7 @@ function buildEditSaveBody(context, prepared) {
|
|
|
9568
9680
|
formData: {
|
|
9569
9681
|
id: context.data_id,
|
|
9570
9682
|
updateTimeStamp: context.update_time_stamp || "",
|
|
9571
|
-
module:
|
|
9683
|
+
module: moduleName,
|
|
9572
9684
|
dataDelRows: [],
|
|
9573
9685
|
dataDetails: prepared.dataDetails || [],
|
|
9574
9686
|
client: "pc",
|
|
@@ -10104,6 +10216,7 @@ function rowFromAny(raw) {
|
|
|
10104
10216
|
"lastfeedbacktime",
|
|
10105
10217
|
"lastFeedbackTime"
|
|
10106
10218
|
]) ?? "",
|
|
10219
|
+
...pick(["planFinishDatetime", "planfinishdatetime"]) ? { planFinishDatetime: pick(["planFinishDatetime", "planfinishdatetime"]) } : {},
|
|
10107
10220
|
summary: pick(["summary"]),
|
|
10108
10221
|
workflowName: pick(["workflowName", "workflowname", "workflowTypeName"], true),
|
|
10109
10222
|
receivedTime: pick(["receivedTime", "receivedtime", "receivedatetime", "operatedatetime", "stayStartAt"]),
|
|
@@ -10179,64 +10292,9 @@ function readBoundedInt(value, name, fallback, min, max) {
|
|
|
10179
10292
|
return parsed;
|
|
10180
10293
|
}
|
|
10181
10294
|
|
|
10182
|
-
// src/shortcuts/workflow/operations/todoSmartConvert/
|
|
10183
|
-
|
|
10184
|
-
|
|
10185
|
-
"requestId",
|
|
10186
|
-
"requestid",
|
|
10187
|
-
"workflowid",
|
|
10188
|
-
"workflowId",
|
|
10189
|
-
"userMasterId",
|
|
10190
|
-
"userid",
|
|
10191
|
-
"isremark",
|
|
10192
|
-
"isremarktype",
|
|
10193
|
-
"nodeid",
|
|
10194
|
-
"currentNodeId",
|
|
10195
|
-
// 状态位
|
|
10196
|
-
"overdue",
|
|
10197
|
-
"userOverTime",
|
|
10198
|
-
"requestlevel",
|
|
10199
|
-
"requestLevelShow",
|
|
10200
|
-
"requestlevelShow",
|
|
10201
|
-
"requestlevelTitle",
|
|
10202
|
-
// 展示字段
|
|
10203
|
-
"requestnamehtml",
|
|
10204
|
-
"requestnameTitle",
|
|
10205
|
-
"requestnametitle",
|
|
10206
|
-
"requestname",
|
|
10207
|
-
"creater",
|
|
10208
|
-
"creatername",
|
|
10209
|
-
"creatorName",
|
|
10210
|
-
"workflowname",
|
|
10211
|
-
"workflowName",
|
|
10212
|
-
"workflowTypeName",
|
|
10213
|
-
"requestmark",
|
|
10214
|
-
"flowstatusShow",
|
|
10215
|
-
"receivedatetime",
|
|
10216
|
-
"operatedatetime",
|
|
10217
|
-
// 最后反馈时间:`getTodoListData.displayData` 里的原始键是全小写,大小写变体一并保留。
|
|
10218
|
-
"lastfeedbackdatetime",
|
|
10219
|
-
"lastFeedbackDateTime"
|
|
10220
|
-
];
|
|
10221
|
-
function projectDisplayRows(response) {
|
|
10222
|
-
const record = responseData(response);
|
|
10223
|
-
const raw = record?.data?.displayData ?? record?.displayData ?? [];
|
|
10224
|
-
const rows = Array.isArray(raw) ? raw : [];
|
|
10225
|
-
const projected = [];
|
|
10226
|
-
for (const row of rows) {
|
|
10227
|
-
if (!row || typeof row !== "object" || Array.isArray(row)) continue;
|
|
10228
|
-
const source = row;
|
|
10229
|
-
const picked = {};
|
|
10230
|
-
for (const key of DISPLAY_ROW_FIELDS) {
|
|
10231
|
-
const value = source[key];
|
|
10232
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
10233
|
-
picked[key] = value;
|
|
10234
|
-
}
|
|
10235
|
-
}
|
|
10236
|
-
if (Object.keys(picked).length > 0) projected.push(picked);
|
|
10237
|
-
}
|
|
10238
|
-
return projected;
|
|
10239
|
-
}
|
|
10295
|
+
// src/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.ts
|
|
10296
|
+
import { existsSync as existsSync3, readFileSync } from "node:fs";
|
|
10297
|
+
import { join as join2 } from "node:path";
|
|
10240
10298
|
|
|
10241
10299
|
// src/shortcuts/workflow/operations/todoSmartConvert/summaryCache.ts
|
|
10242
10300
|
import { existsSync as existsSync2, readdirSync, statSync } from "node:fs";
|
|
@@ -10449,6 +10507,417 @@ async function openSummaryCache(ctx) {
|
|
|
10449
10507
|
return cache;
|
|
10450
10508
|
}
|
|
10451
10509
|
|
|
10510
|
+
// src/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.ts
|
|
10511
|
+
var AIGROUP_DIR_NAME = "aigroup";
|
|
10512
|
+
var DEFAULT_RULE_FILE = "default.json";
|
|
10513
|
+
var USER_INTENT_RULE_FILE = "user-intents.json";
|
|
10514
|
+
var FOCUS_OPERATORS = [
|
|
10515
|
+
"\u7B49\u4E8E",
|
|
10516
|
+
"\u4E0D\u7B49\u4E8E",
|
|
10517
|
+
"\u662F",
|
|
10518
|
+
"\u4E0D\u662F",
|
|
10519
|
+
"\u5927\u4E8E",
|
|
10520
|
+
"\u5C0F\u4E8E",
|
|
10521
|
+
"\u5C0F\u4E8E\u7B49\u4E8E",
|
|
10522
|
+
"\u5927\u4E8E\u7B49\u4E8E",
|
|
10523
|
+
"\u4ECB\u4E8E",
|
|
10524
|
+
"\u5305\u542B"
|
|
10525
|
+
];
|
|
10526
|
+
var MAX_GROUPING_PROMPT_CHARS = 500;
|
|
10527
|
+
var EMPTY_GROUP_RULE = { focus: false };
|
|
10528
|
+
var FALLBACK_DEFAULTS = {
|
|
10529
|
+
weight: 999,
|
|
10530
|
+
needSummary: true,
|
|
10531
|
+
requestSummaryPrompt: "",
|
|
10532
|
+
summaryMaxChars: 150,
|
|
10533
|
+
groupSummaryMaxChars: 100,
|
|
10534
|
+
groupSummaryTail: "\u53EF\u5C55\u5F00\u9010\u6761\u67E5\u770B\u6216\u76F4\u63A5\u6C47\u603B\u5904\u7406"
|
|
10535
|
+
};
|
|
10536
|
+
function emptyRuleFile(error = null) {
|
|
10537
|
+
return {
|
|
10538
|
+
file: { schemaVersion: 2, defaults: FALLBACK_DEFAULTS, rules: [] },
|
|
10539
|
+
error
|
|
10540
|
+
};
|
|
10541
|
+
}
|
|
10542
|
+
function asStringArray3(value) {
|
|
10543
|
+
if (typeof value === "string") return [value];
|
|
10544
|
+
if (!Array.isArray(value)) return null;
|
|
10545
|
+
const items = value.map((item) => String(item ?? "").trim()).filter((item) => item !== "");
|
|
10546
|
+
return items.length > 0 ? items : null;
|
|
10547
|
+
}
|
|
10548
|
+
function isOperator(value) {
|
|
10549
|
+
return typeof value === "string" && FOCUS_OPERATORS.includes(value);
|
|
10550
|
+
}
|
|
10551
|
+
function validateFocusKeyword(raw, index) {
|
|
10552
|
+
if (!Array.isArray(raw)) return `focusKeyword[${index}] \u5FC5\u987B\u662F\u6570\u7EC4`;
|
|
10553
|
+
const [metric, op] = raw;
|
|
10554
|
+
if (typeof metric !== "string" || !metric.trim()) return `focusKeyword[${index}] \u7684\u6307\u6807\u540D\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`;
|
|
10555
|
+
if (!isOperator(op)) return `focusKeyword[${index}] \u7684\u7B97\u5B50\u300C${String(op)}\u300D\u4E0D\u652F\u6301\uFF08\u53EF\u7528\uFF1A${FOCUS_OPERATORS.join("/")}\uFF09`;
|
|
10556
|
+
if (op === "\u4ECB\u4E8E") {
|
|
10557
|
+
if (raw.length !== 4) return `focusKeyword[${index}] \u7528\u300C\u4ECB\u4E8E\u300D\u65F6\u5FC5\u987B\u7ED9 [\u6307\u6807, \u4ECB\u4E8E, \u4E0B\u754C, \u4E0A\u754C]`;
|
|
10558
|
+
return null;
|
|
10559
|
+
}
|
|
10560
|
+
if (raw.length !== 3) return `focusKeyword[${index}] \u5FC5\u987B\u662F [\u6307\u6807, \u7B97\u5B50, \u503C] \u4E09\u5143\u7EC4`;
|
|
10561
|
+
return null;
|
|
10562
|
+
}
|
|
10563
|
+
function validateRuleFile(raw) {
|
|
10564
|
+
const errors = [];
|
|
10565
|
+
const file = raw;
|
|
10566
|
+
if (!file || typeof file !== "object") return ["\u89C4\u5219\u6587\u4EF6\u5FC5\u987B\u662F JSON \u5BF9\u8C61"];
|
|
10567
|
+
if (!Array.isArray(file.rules)) {
|
|
10568
|
+
errors.push("rules \u5FC5\u987B\u662F\u6570\u7EC4");
|
|
10569
|
+
return errors;
|
|
10570
|
+
}
|
|
10571
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10572
|
+
file.rules.forEach((rule, index) => {
|
|
10573
|
+
if (!rule || typeof rule !== "object") {
|
|
10574
|
+
errors.push(`rules[${index}] \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
10575
|
+
return;
|
|
10576
|
+
}
|
|
10577
|
+
const names = asStringArray3(rule.workflowName);
|
|
10578
|
+
if (!names) {
|
|
10579
|
+
errors.push(`rules[${index}].workflowName \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\u6216\u975E\u7A7A\u6570\u7EC4`);
|
|
10580
|
+
return;
|
|
10581
|
+
}
|
|
10582
|
+
for (const name of names) {
|
|
10583
|
+
if (seen.has(name)) errors.push(`workflowName\u300C${name}\u300D\u5728 rules[${index}] \u91CD\u590D\u51FA\u73B0`);
|
|
10584
|
+
seen.add(name);
|
|
10585
|
+
}
|
|
10586
|
+
if (rule.weight !== void 0 && (typeof rule.weight !== "number" || !Number.isFinite(rule.weight))) {
|
|
10587
|
+
errors.push(`rules[${index}].weight \u5FC5\u987B\u662F\u6570\u5B57`);
|
|
10588
|
+
}
|
|
10589
|
+
if (rule.summaryMaxChars !== void 0 && (typeof rule.summaryMaxChars !== "number" || rule.summaryMaxChars <= 0)) {
|
|
10590
|
+
errors.push(`rules[${index}].summaryMaxChars \u5FC5\u987B\u662F\u6B63\u6570`);
|
|
10591
|
+
}
|
|
10592
|
+
const groupRule = rule.aiGroup?.groupRule;
|
|
10593
|
+
if (groupRule) {
|
|
10594
|
+
if (typeof groupRule.focus !== "boolean") errors.push(`rules[${index}].aiGroup.groupRule.focus \u5FC5\u987B\u662F\u5E03\u5C14`);
|
|
10595
|
+
if (groupRule.focus) {
|
|
10596
|
+
const keywords = groupRule.focusKeyword;
|
|
10597
|
+
if (!Array.isArray(keywords) || keywords.length === 0) {
|
|
10598
|
+
errors.push(`rules[${index}] focus=true \u65F6\u5FC5\u987B\u7ED9 focusKeyword`);
|
|
10599
|
+
} else {
|
|
10600
|
+
keywords.forEach((keyword, k) => {
|
|
10601
|
+
const reason = validateFocusKeyword(keyword, k);
|
|
10602
|
+
if (reason) errors.push(`rules[${index}].${reason}`);
|
|
10603
|
+
});
|
|
10604
|
+
}
|
|
10605
|
+
} else if (groupRule.focusKeyword !== void 0 && groupRule.focusKeyword.length > 0) {
|
|
10606
|
+
errors.push(`rules[${index}] focus=false \u65F6\u4E0D\u5E94\u7ED9 focusKeyword`);
|
|
10607
|
+
}
|
|
10608
|
+
if (groupRule.focus === false && !groupRule.aiContext) {
|
|
10609
|
+
errors.push(`rules[${index}] focus=false \u65F6\u5FC5\u987B\u7ED9 aiContext\uFF08\u6D41\u7A0B\u6807\u9898 / \u6D41\u7A0B\u8BE6\u60C5\uFF09`);
|
|
10610
|
+
}
|
|
10611
|
+
if (groupRule.groupingPrompt !== void 0) {
|
|
10612
|
+
if (groupRule.focus === true) {
|
|
10613
|
+
errors.push(`rules[${index}] focus=true \u65F6\u4E0D\u5E94\u7ED9 groupingPrompt\uFF08\u5B83\u53EA\u4F5C\u7528\u4E8E focus=false \u7684\u8BED\u4E49\u5206\u7EC4\uFF09`);
|
|
10614
|
+
} else if (typeof groupRule.groupingPrompt !== "string" || groupRule.groupingPrompt.trim() === "") {
|
|
10615
|
+
errors.push(`rules[${index}].aiGroup.groupRule.groupingPrompt \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
10616
|
+
} else if (groupRule.groupingPrompt.length > MAX_GROUPING_PROMPT_CHARS) {
|
|
10617
|
+
errors.push(
|
|
10618
|
+
`rules[${index}].aiGroup.groupRule.groupingPrompt \u8D85\u8FC7 ${MAX_GROUPING_PROMPT_CHARS} \u5B57\uFF08\u5B83\u4F1A\u539F\u6837\u8FDB\u6A21\u578B\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u7CBE\u7B80\uFF09`
|
|
10619
|
+
);
|
|
10620
|
+
}
|
|
10621
|
+
}
|
|
10622
|
+
}
|
|
10623
|
+
const groupSummary = rule.aiGroup?.groupSummary;
|
|
10624
|
+
if (groupSummary) {
|
|
10625
|
+
if (typeof groupSummary.needAI !== "boolean") errors.push(`rules[${index}].aiGroup.groupSummary.needAI \u5FC5\u987B\u662F\u5E03\u5C14`);
|
|
10626
|
+
if (groupSummary.needAI && !groupSummary.prompt) errors.push(`rules[${index}] groupSummary.needAI=true \u65F6\u5FC5\u987B\u7ED9 prompt`);
|
|
10627
|
+
if (!groupSummary.needAI && !groupSummary.template) errors.push(`rules[${index}] groupSummary.needAI=false \u65F6\u5FC5\u987B\u7ED9 template`);
|
|
10628
|
+
}
|
|
10629
|
+
});
|
|
10630
|
+
return errors;
|
|
10631
|
+
}
|
|
10632
|
+
function loadRuleFile(file) {
|
|
10633
|
+
if (!existsSync3(file)) return emptyRuleFile(`\u89C4\u5219\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${file}`);
|
|
10634
|
+
let parsed;
|
|
10635
|
+
try {
|
|
10636
|
+
parsed = JSON.parse(readFileSync(file, "utf8"));
|
|
10637
|
+
} catch (error) {
|
|
10638
|
+
return emptyRuleFile(`\u89C4\u5219\u6587\u4EF6\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${file}\uFF08${error.message}\uFF09`);
|
|
10639
|
+
}
|
|
10640
|
+
const errors = validateRuleFile(parsed);
|
|
10641
|
+
if (errors.length > 0) return emptyRuleFile(`\u89C4\u5219\u6587\u4EF6\u6821\u9A8C\u5931\u8D25\uFF1A${errors.join("\uFF1B")}`);
|
|
10642
|
+
return { file: parsed, error: null };
|
|
10643
|
+
}
|
|
10644
|
+
function aigroupDir(ctx) {
|
|
10645
|
+
const explicit = process.env.WEAVER_WORK_CLI_AIGROUP_DIR?.trim();
|
|
10646
|
+
if (explicit) return join2(explicit);
|
|
10647
|
+
const roots = cacheRoots(ctx);
|
|
10648
|
+
return roots.skillDir ? join2(roots.skillDir, AIGROUP_DIR_NAME) : join2(stateRoot(ctx), AIGROUP_DIR_NAME);
|
|
10649
|
+
}
|
|
10650
|
+
function aigroupUserDir(ctx) {
|
|
10651
|
+
const explicit = process.env.WEAVER_WORK_CLI_AIGROUP_DIR?.trim();
|
|
10652
|
+
if (explicit) return join2(explicit);
|
|
10653
|
+
return join2(stateRoot(ctx), AIGROUP_DIR_NAME);
|
|
10654
|
+
}
|
|
10655
|
+
function loadRules(options = {}) {
|
|
10656
|
+
const dir = options.dir ?? aigroupDir(options.ctx);
|
|
10657
|
+
const userDir = options.dir ?? aigroupUserDir(options.ctx);
|
|
10658
|
+
const warnings = [];
|
|
10659
|
+
const base = loadRuleFile(join2(dir, DEFAULT_RULE_FILE));
|
|
10660
|
+
if (base.error) warnings.push(base.error);
|
|
10661
|
+
const rules = [...base.file.rules];
|
|
10662
|
+
const userIntentFile = join2(userDir, USER_INTENT_RULE_FILE);
|
|
10663
|
+
const legacyIntentFile = join2(dir, USER_INTENT_RULE_FILE);
|
|
10664
|
+
let intentFile = userIntentFile;
|
|
10665
|
+
if (!options.dir && !existsSync3(userIntentFile) && existsSync3(legacyIntentFile)) {
|
|
10666
|
+
intentFile = legacyIntentFile;
|
|
10667
|
+
warnings.push(`\u7528\u6237\u610F\u56FE\u4ECD\u8BFB\u81EA skill \u76EE\u5F55\uFF08${legacyIntentFile}\uFF09\uFF1A\u65B0\u4F4D\u7F6E\u662F ${userIntentFile}\uFF0C\u91CD\u65B0\u6267\u884C aigroup set \u5373\u53EF\u8FC1\u79FB`);
|
|
10668
|
+
}
|
|
10669
|
+
const intent = loadRuleFile(intentFile);
|
|
10670
|
+
if (intent.error) {
|
|
10671
|
+
if (existsSync3(intentFile)) warnings.push(intent.error);
|
|
10672
|
+
} else {
|
|
10673
|
+
for (const rule of intent.file.rules) {
|
|
10674
|
+
const names = new Set(asStringArray3(rule.workflowName) ?? []);
|
|
10675
|
+
const at = rules.findIndex((item) => (asStringArray3(item.workflowName) ?? []).some((name) => names.has(name)));
|
|
10676
|
+
if (at >= 0 && (asStringArray3(rules[at].workflowName) ?? []).includes("*")) {
|
|
10677
|
+
warnings.push(`\u7528\u6237\u610F\u56FE\u4E0D\u80FD\u8986\u76D6\u901A\u914D\u6761\u76EE\u300C*\u300D\uFF0C\u5DF2\u5FFD\u7565\uFF1A${[...names].join(",")}`);
|
|
10678
|
+
continue;
|
|
10679
|
+
}
|
|
10680
|
+
if (at >= 0) rules[at] = rule;
|
|
10681
|
+
else rules.push(rule);
|
|
10682
|
+
}
|
|
10683
|
+
}
|
|
10684
|
+
return {
|
|
10685
|
+
file: { schemaVersion: base.file.schemaVersion, defaults: { ...FALLBACK_DEFAULTS, ...base.file.defaults }, rules },
|
|
10686
|
+
warnings,
|
|
10687
|
+
dir
|
|
10688
|
+
};
|
|
10689
|
+
}
|
|
10690
|
+
function matchRule(rules, workflowName) {
|
|
10691
|
+
const name = String(workflowName ?? "").trim();
|
|
10692
|
+
const aliasesOf = (rule) => asStringArray3(rule.workflowName) ?? [];
|
|
10693
|
+
const indexOf = /* @__PURE__ */ new Map();
|
|
10694
|
+
rules.forEach((rule, index) => indexOf.set(rule, index));
|
|
10695
|
+
if (name) {
|
|
10696
|
+
const exact = rules.filter((rule) => aliasesOf(rule).includes(name));
|
|
10697
|
+
if (exact.length > 0) {
|
|
10698
|
+
const [rule] = exact;
|
|
10699
|
+
return { rule, matchedBy: "exact", index: indexOf.get(rule) ?? 0 };
|
|
10700
|
+
}
|
|
10701
|
+
const fuzzy = rules.filter((rule) => aliasesOf(rule).some((alias) => alias !== "*" && name.includes(alias)));
|
|
10702
|
+
if (fuzzy.length > 0) {
|
|
10703
|
+
const sorted = [...fuzzy].sort((a, b) => (a.weight ?? FALLBACK_DEFAULTS.weight) - (b.weight ?? FALLBACK_DEFAULTS.weight) || (indexOf.get(a) ?? 0) - (indexOf.get(b) ?? 0));
|
|
10704
|
+
const rule = sorted[0];
|
|
10705
|
+
return { rule, matchedBy: "fuzzy", index: indexOf.get(rule) ?? 0 };
|
|
10706
|
+
}
|
|
10707
|
+
}
|
|
10708
|
+
const fallback = rules.find((rule) => aliasesOf(rule).includes("*"));
|
|
10709
|
+
if (fallback) return { rule: fallback, matchedBy: "default", index: indexOf.get(fallback) ?? 0 };
|
|
10710
|
+
return null;
|
|
10711
|
+
}
|
|
10712
|
+
function resolveRule(file, workflowName) {
|
|
10713
|
+
const matched = matchRule(file.rules, workflowName);
|
|
10714
|
+
if (!matched) return null;
|
|
10715
|
+
const defaults = { ...FALLBACK_DEFAULTS, ...file.defaults };
|
|
10716
|
+
const raw = matched.rule;
|
|
10717
|
+
const groupSummary = raw.aiGroup?.groupSummary;
|
|
10718
|
+
const groupRule = raw.aiGroup?.groupRule;
|
|
10719
|
+
return {
|
|
10720
|
+
matchedBy: matched.matchedBy,
|
|
10721
|
+
rule: {
|
|
10722
|
+
workflowName: asStringArray3(raw.workflowName) ?? [],
|
|
10723
|
+
weight: raw.weight ?? defaults.weight,
|
|
10724
|
+
needSummary: raw.needSummary ?? defaults.needSummary,
|
|
10725
|
+
requestSummaryPrompt: raw.requestSummaryPrompt ?? defaults.requestSummaryPrompt,
|
|
10726
|
+
summaryMaxChars: raw.summaryMaxChars ?? defaults.summaryMaxChars,
|
|
10727
|
+
groupSummaryMaxChars: defaults.groupSummaryMaxChars,
|
|
10728
|
+
groupSummaryTail: defaults.groupSummaryTail,
|
|
10729
|
+
aiGroup: raw.aiGroup ? {
|
|
10730
|
+
groupSummary: {
|
|
10731
|
+
needAI: groupSummary?.needAI ?? false,
|
|
10732
|
+
...groupSummary?.prompt === void 0 ? {} : { prompt: groupSummary.prompt },
|
|
10733
|
+
...groupSummary?.template === void 0 ? {} : { template: groupSummary.template },
|
|
10734
|
+
maxChars: defaults.groupSummaryMaxChars,
|
|
10735
|
+
tail: defaults.groupSummaryTail
|
|
10736
|
+
},
|
|
10737
|
+
groupRule: groupRule ?? EMPTY_GROUP_RULE
|
|
10738
|
+
} : null,
|
|
10739
|
+
ruleIndex: matched.index
|
|
10740
|
+
}
|
|
10741
|
+
};
|
|
10742
|
+
}
|
|
10743
|
+
function dateOnly(value) {
|
|
10744
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
10745
|
+
return `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}`;
|
|
10746
|
+
}
|
|
10747
|
+
var RELATIVE_DAYS = { \u4ECA\u5929: 0, \u6628\u5929: -1, \u660E\u5929: 1 };
|
|
10748
|
+
function normalizeDateLike(value, now = /* @__PURE__ */ new Date()) {
|
|
10749
|
+
const text = value.trim();
|
|
10750
|
+
if (text in RELATIVE_DAYS) {
|
|
10751
|
+
const date = new Date(now.getTime());
|
|
10752
|
+
date.setDate(date.getDate() + RELATIVE_DAYS[text]);
|
|
10753
|
+
return dateOnly(date);
|
|
10754
|
+
}
|
|
10755
|
+
const matched = /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})/u.exec(text);
|
|
10756
|
+
if (!matched) return null;
|
|
10757
|
+
const [, y, m, d] = matched;
|
|
10758
|
+
return `${y}-${String(m).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
|
|
10759
|
+
}
|
|
10760
|
+
function toNumber(value) {
|
|
10761
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
10762
|
+
const text = String(value ?? "").replace(/[,¥¥\s]/gu, "");
|
|
10763
|
+
if (!text) return null;
|
|
10764
|
+
const parsed = Number(text);
|
|
10765
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
10766
|
+
}
|
|
10767
|
+
function comparableOf(value, now) {
|
|
10768
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
10769
|
+
if (typeof value === "number") return Number.isFinite(value) ? { kind: "number", value } : null;
|
|
10770
|
+
const text = String(value).trim();
|
|
10771
|
+
if (!text) return null;
|
|
10772
|
+
const date = normalizeDateLike(text, now);
|
|
10773
|
+
if (date) return { kind: "date", value: date };
|
|
10774
|
+
const num = toNumber(text);
|
|
10775
|
+
if (num !== null && /^[¥¥]?\s*-?\d[\d,]*(?:\.\d+)?$/.test(text.replace(/\s/gu, ""))) {
|
|
10776
|
+
return { kind: "number", value: num };
|
|
10777
|
+
}
|
|
10778
|
+
return { kind: "text", value: text };
|
|
10779
|
+
}
|
|
10780
|
+
function compare(a, b) {
|
|
10781
|
+
if (a.kind === "number" && b.kind === "number") return a.value - b.value;
|
|
10782
|
+
if (a.kind === "date" && b.kind === "date") return a.value < b.value ? -1 : a.value > b.value ? 1 : 0;
|
|
10783
|
+
if (a.kind === "text" || b.kind === "text") {
|
|
10784
|
+
const left = String(a.value);
|
|
10785
|
+
const right = String(b.value);
|
|
10786
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
10787
|
+
}
|
|
10788
|
+
return null;
|
|
10789
|
+
}
|
|
10790
|
+
function evaluateCondition(condition, actual, now = /* @__PURE__ */ new Date()) {
|
|
10791
|
+
const [metric, op, expected, upper] = condition;
|
|
10792
|
+
const left = comparableOf(actual, now);
|
|
10793
|
+
if (!left) return false;
|
|
10794
|
+
const right = comparableOf(expected, now);
|
|
10795
|
+
if (!right) return false;
|
|
10796
|
+
switch (op) {
|
|
10797
|
+
case "\u7B49\u4E8E":
|
|
10798
|
+
case "\u662F":
|
|
10799
|
+
return compare(left, right) === 0;
|
|
10800
|
+
case "\u4E0D\u7B49\u4E8E":
|
|
10801
|
+
case "\u4E0D\u662F":
|
|
10802
|
+
return compare(left, right) !== 0;
|
|
10803
|
+
case "\u5927\u4E8E": {
|
|
10804
|
+
const diff = compare(left, right);
|
|
10805
|
+
return diff !== null && diff > 0;
|
|
10806
|
+
}
|
|
10807
|
+
case "\u5C0F\u4E8E": {
|
|
10808
|
+
const diff = compare(left, right);
|
|
10809
|
+
return diff !== null && diff < 0;
|
|
10810
|
+
}
|
|
10811
|
+
case "\u5927\u4E8E\u7B49\u4E8E": {
|
|
10812
|
+
const diff = compare(left, right);
|
|
10813
|
+
return diff !== null && diff >= 0;
|
|
10814
|
+
}
|
|
10815
|
+
case "\u5C0F\u4E8E\u7B49\u4E8E": {
|
|
10816
|
+
const diff = compare(left, right);
|
|
10817
|
+
return diff !== null && diff <= 0;
|
|
10818
|
+
}
|
|
10819
|
+
case "\u4ECB\u4E8E": {
|
|
10820
|
+
const top = comparableOf(upper, now);
|
|
10821
|
+
if (!top) return false;
|
|
10822
|
+
const low = compare(left, right);
|
|
10823
|
+
const high = compare(left, top);
|
|
10824
|
+
return low !== null && high !== null && low >= 0 && high <= 0;
|
|
10825
|
+
}
|
|
10826
|
+
case "\u5305\u542B":
|
|
10827
|
+
return String(left.value).includes(String(right.value));
|
|
10828
|
+
default:
|
|
10829
|
+
return false;
|
|
10830
|
+
}
|
|
10831
|
+
}
|
|
10832
|
+
function evaluateFocusKeywords(conditions, resolve3, now = /* @__PURE__ */ new Date()) {
|
|
10833
|
+
if (conditions.length === 0) return false;
|
|
10834
|
+
return conditions.every((condition) => evaluateCondition(condition, resolve3(condition[0]), now));
|
|
10835
|
+
}
|
|
10836
|
+
var activeFile = null;
|
|
10837
|
+
var activeDir = null;
|
|
10838
|
+
function primeRules(ctx) {
|
|
10839
|
+
const loaded = loadRules({ ctx });
|
|
10840
|
+
activeFile = loaded.file;
|
|
10841
|
+
activeDir = loaded.dir;
|
|
10842
|
+
return loaded;
|
|
10843
|
+
}
|
|
10844
|
+
function activeRules() {
|
|
10845
|
+
if (!activeFile) {
|
|
10846
|
+
const loaded = loadRules();
|
|
10847
|
+
activeFile = loaded.file;
|
|
10848
|
+
activeDir = loaded.dir;
|
|
10849
|
+
}
|
|
10850
|
+
return activeFile;
|
|
10851
|
+
}
|
|
10852
|
+
function activeRuleFor(workflowName) {
|
|
10853
|
+
const name = String(workflowName ?? "").trim();
|
|
10854
|
+
if (!name) return null;
|
|
10855
|
+
return resolveRule(activeRules(), name)?.rule ?? null;
|
|
10856
|
+
}
|
|
10857
|
+
function resetActiveRules() {
|
|
10858
|
+
activeFile = null;
|
|
10859
|
+
activeDir = null;
|
|
10860
|
+
}
|
|
10861
|
+
|
|
10862
|
+
// src/shortcuts/workflow/operations/todoSmartConvert/todoListRows.ts
|
|
10863
|
+
var DISPLAY_ROW_FIELDS = [
|
|
10864
|
+
// 定位键
|
|
10865
|
+
"requestId",
|
|
10866
|
+
"requestid",
|
|
10867
|
+
"workflowid",
|
|
10868
|
+
"workflowId",
|
|
10869
|
+
"userMasterId",
|
|
10870
|
+
"userid",
|
|
10871
|
+
"isremark",
|
|
10872
|
+
"isremarktype",
|
|
10873
|
+
"nodeid",
|
|
10874
|
+
"currentNodeId",
|
|
10875
|
+
// 状态位
|
|
10876
|
+
"overdue",
|
|
10877
|
+
"userOverTime",
|
|
10878
|
+
"requestlevel",
|
|
10879
|
+
"requestLevelShow",
|
|
10880
|
+
"requestlevelShow",
|
|
10881
|
+
"requestlevelTitle",
|
|
10882
|
+
// 展示字段
|
|
10883
|
+
"requestnamehtml",
|
|
10884
|
+
"requestnameTitle",
|
|
10885
|
+
"requestnametitle",
|
|
10886
|
+
"requestname",
|
|
10887
|
+
"creater",
|
|
10888
|
+
"creatername",
|
|
10889
|
+
"creatorName",
|
|
10890
|
+
"workflowname",
|
|
10891
|
+
"workflowName",
|
|
10892
|
+
"workflowTypeName",
|
|
10893
|
+
"requestmark",
|
|
10894
|
+
"flowstatusShow",
|
|
10895
|
+
"receivedatetime",
|
|
10896
|
+
"operatedatetime",
|
|
10897
|
+
// 最后反馈时间:`getTodoListData.displayData` 里的原始键是全小写,大小写变体一并保留。
|
|
10898
|
+
"lastfeedbackdatetime",
|
|
10899
|
+
"lastFeedbackDateTime"
|
|
10900
|
+
];
|
|
10901
|
+
function projectDisplayRows(response) {
|
|
10902
|
+
const record = responseData(response);
|
|
10903
|
+
const raw = record?.data?.displayData ?? record?.displayData ?? [];
|
|
10904
|
+
const rows = Array.isArray(raw) ? raw : [];
|
|
10905
|
+
const projected = [];
|
|
10906
|
+
for (const row of rows) {
|
|
10907
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) continue;
|
|
10908
|
+
const source = row;
|
|
10909
|
+
const picked = {};
|
|
10910
|
+
for (const key of DISPLAY_ROW_FIELDS) {
|
|
10911
|
+
const value = source[key];
|
|
10912
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
10913
|
+
picked[key] = value;
|
|
10914
|
+
}
|
|
10915
|
+
}
|
|
10916
|
+
if (Object.keys(picked).length > 0) projected.push(picked);
|
|
10917
|
+
}
|
|
10918
|
+
return projected;
|
|
10919
|
+
}
|
|
10920
|
+
|
|
10452
10921
|
// src/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.ts
|
|
10453
10922
|
function normalizeDetailFieldName(raw) {
|
|
10454
10923
|
return String(raw ?? "").replace(/<[^>]*>/g, " ").replace(/[【】[\]()()]/g, "").replace(/\s+/g, "").trim();
|
|
@@ -10491,19 +10960,10 @@ function pickInternalMessageFieldPairs(fields, basicInfo = {}) {
|
|
|
10491
10960
|
}
|
|
10492
10961
|
|
|
10493
10962
|
// src/shortcuts/workflow/operations/todoSmartConvert/businessRules.ts
|
|
10494
|
-
var BUSINESS_KIND_LABEL = {
|
|
10495
|
-
leave: "\u8BF7\u5047\u7C7B",
|
|
10496
|
-
finance: "\u8D22\u52A1\u7C7B",
|
|
10497
|
-
"internal-message": "\u5185\u90E8\u7559\u8A00\u7C7B",
|
|
10498
|
-
satisfaction: "\u6EE1\u610F\u5EA6\u7C7B",
|
|
10499
|
-
"issue-support": "\u5BA2\u6237\u95EE\u9898\u652F\u6301\u7C7B",
|
|
10500
|
-
other: "\u5176\u4ED6\u7C7B"
|
|
10501
|
-
};
|
|
10502
10963
|
var ISSUE_SUPPORT_WORKFLOW_NAMES = [
|
|
10503
10964
|
"Ecology\u5BA2\u6237\u95EE\u9898\u652F\u6301\u89E3\u51B3\u6D41\u7A0B",
|
|
10504
10965
|
"E10\u5BA2\u6237\u95EE\u9898\u652F\u6301\u89E3\u51B3\u6D41\u7A0B"
|
|
10505
10966
|
];
|
|
10506
|
-
var ISSUE_SUPPORT_GROUP_TITLE = "\u5DF2\u8FC7\u671F\u53CA\u4ECA\u5929\u5373\u5C06\u8FC7\u671F\u7684\u6D41\u7A0B";
|
|
10507
10967
|
var LEAVE_DAY_THRESHOLD = 1;
|
|
10508
10968
|
var FINANCE_AMOUNT_THRESHOLD = 100;
|
|
10509
10969
|
var LEAVE_GROUP_TITLE = `${LEAVE_DAY_THRESHOLD}\u5929\u4EE5\u5185`;
|
|
@@ -10524,49 +10984,12 @@ function detectBusinessKind(workflowName) {
|
|
|
10524
10984
|
function isDeterministicGroupKind(kind) {
|
|
10525
10985
|
return kind === "leave" || kind === "finance" || kind === "issue-support";
|
|
10526
10986
|
}
|
|
10527
|
-
var INTENT_RULES = [
|
|
10528
|
-
{
|
|
10529
|
-
id: "leave",
|
|
10530
|
-
label: "\u8BF7\u5047\u7EF4\u5EA6",
|
|
10531
|
-
match: /请假|休假|年假|调休|病假|事假|婚假|产假|陪产|丧假|探亲|工伤|哺乳|假别|假期|假种|天数/u,
|
|
10532
|
-
kinds: ["leave"]
|
|
10533
|
-
},
|
|
10534
|
-
{
|
|
10535
|
-
id: "finance",
|
|
10536
|
-
label: "\u8D22\u52A1\u7EF4\u5EA6",
|
|
10537
|
-
match: /报销|费用|金额|发票|差旅|借款|付款|请款|科目|票据|对公|核销/u,
|
|
10538
|
-
kinds: ["finance"]
|
|
10539
|
-
},
|
|
10540
|
-
{
|
|
10541
|
-
id: "issue-support",
|
|
10542
|
-
label: "\u95EE\u9898\u652F\u6301\u7EF4\u5EA6",
|
|
10543
|
-
match: /问题|模块|处理阶段|客户问题|工单|支持/u,
|
|
10544
|
-
kinds: ["issue-support"]
|
|
10545
|
-
},
|
|
10546
|
-
{
|
|
10547
|
-
id: "generic",
|
|
10548
|
-
label: "\u901A\u7528\u7EF4\u5EA6",
|
|
10549
|
-
match: /客户|发起人|创建人|提交人|时间|日期|紧急|等级|优先级|主题|标题|类型|类别|状态|节点|内容/u,
|
|
10550
|
-
kinds: ["internal-message", "other"]
|
|
10551
|
-
}
|
|
10552
|
-
];
|
|
10553
|
-
function intentAppliesToKind(focus, kind) {
|
|
10554
|
-
const text = String(focus ?? "").trim();
|
|
10555
|
-
if (!text || kind === "satisfaction") return false;
|
|
10556
|
-
const specific = INTENT_RULES.filter((rule) => rule.id !== "generic" && rule.match.test(text));
|
|
10557
|
-
if (specific.length > 0) return specific.some((rule) => rule.kinds.includes(kind));
|
|
10558
|
-
const generic = INTENT_RULES.find((rule) => rule.id === "generic");
|
|
10559
|
-
return generic ? generic.kinds.includes(kind) : false;
|
|
10560
|
-
}
|
|
10561
10987
|
function requestSummaryStrategy(kind) {
|
|
10562
10988
|
return kind === "satisfaction" ? "title" : "ai";
|
|
10563
10989
|
}
|
|
10564
10990
|
function needsRequestSummary(kind) {
|
|
10565
10991
|
return requestSummaryStrategy(kind) === "ai";
|
|
10566
10992
|
}
|
|
10567
|
-
function usesTitleSummary(kind) {
|
|
10568
|
-
return requestSummaryStrategy(kind) === "title";
|
|
10569
|
-
}
|
|
10570
10993
|
var LEAVE_TYPE_FIELD_PATTERN = /^(?:假别|假类|请假类型|请假类别|假期类型|假期类别|休假类型|休假类别)$/u;
|
|
10571
10994
|
var LEAVE_DAYS_FIELD_PATTERN = /^(?:(?:请假|休假|假期|调休)(?:天数|时长|合计)|(?:请假|休假|假期|调休)?天数|天数合计|合计天数|总天数|时长)$/u;
|
|
10572
10995
|
var AMOUNT_FIELD_PATTERN = /^(?:人民币金额|报销金额|报销总金额|实报金额|实际支付金额|申请金额|付款金额|借款金额|请款金额|总金额|金额合计|合计金额|费用合计|小写金额|总价|价税合计|金额|合计|总计)(?:[((]元[))])?$/u;
|
|
@@ -10687,32 +11110,25 @@ function uniqueTexts(values) {
|
|
|
10687
11110
|
return result;
|
|
10688
11111
|
}
|
|
10689
11112
|
var GROUP_SUMMARY_TAIL_TEXT = "\u53EF\u5C55\u5F00\u9010\u6761\u67E5\u770B\u6216\u76F4\u63A5\u6C47\u603B\u5904\u7406";
|
|
10690
|
-
function
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10694
|
-
|
|
10695
|
-
|
|
10696
|
-
|
|
10697
|
-
const
|
|
10698
|
-
const
|
|
10699
|
-
const
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
}
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
const
|
|
10707
|
-
const
|
|
10708
|
-
return
|
|
10709
|
-
}
|
|
10710
|
-
function formatIssueSupportGroupSummary(input) {
|
|
10711
|
-
const allCreators = normalizeCreators(input.creators);
|
|
10712
|
-
const shown = allCreators.slice(0, 3);
|
|
10713
|
-
const creatorText = shown.length > 0 ? `\u7531 ${shown.join("\u3001")}${allCreators.length > shown.length ? " \u7B49" : ""} ${allCreators.length} \u4EBA\u53D1\u8D77\uFF0C` : "";
|
|
10714
|
-
const restText = input.restCount > 0 ? `\u5176\u4F59 ${input.restCount} \u6761\u6309\u5355\u6761\u5C55\u793A\uFF0C` : "";
|
|
10715
|
-
return `\u542B ${input.count} \u6761\u5DF2\u8FC7\u671F\u6216\u4ECA\u65E5\u5230\u671F\u7684\u95EE\u9898\u6D41\u7A0B\uFF0C${creatorText}${restText}${GROUP_SUMMARY_TAIL_TEXT}`;
|
|
11113
|
+
function renderGroupSummaryTemplate(input) {
|
|
11114
|
+
let text = String(input.template ?? "");
|
|
11115
|
+
if (!text.trim()) return "";
|
|
11116
|
+
const allCategories = uniqueTexts(input.categories ?? []);
|
|
11117
|
+
const shownCategories = allCategories.slice(0, 3);
|
|
11118
|
+
const categoryCount = allCategories.length > 0 ? allCategories.length : 1;
|
|
11119
|
+
const categories = shownCategories.length > 0 ? `${shownCategories.join("\u3001")}${allCategories.length > shownCategories.length ? "\u7B49" : ""}` : "";
|
|
11120
|
+
const allCreators = normalizeCreators(input.creators ?? []);
|
|
11121
|
+
const shownCreators = allCreators.slice(0, 3);
|
|
11122
|
+
const creators = shownCreators.length > 0 ? `\u7531${shownCreators.join("\u3001")}${allCreators.length > 2 ? "\u7B49" : ""}` : "";
|
|
11123
|
+
if (!creators) {
|
|
11124
|
+
text = text.replace(/\{\{creators\}\}发起[。,]/gu, "");
|
|
11125
|
+
}
|
|
11126
|
+
if (!categories) {
|
|
11127
|
+
text = text.replace(/(\{\{categories\}\})/gu, "");
|
|
11128
|
+
}
|
|
11129
|
+
const amounts = (input.amounts ?? []).filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
11130
|
+
const replaced = text.replace(/\{\{count\}\}/gu, String(input.count)).replace(/\{\{restCount\}\}/gu, String(input.restCount ?? 0)).replace(/\{\{categoryCount\}\}/gu, String(categoryCount)).replace(/\{\{categories\}\}/gu, categories).replace(/\{\{min\}\}/gu, amounts.length > 0 ? formatNumber(Math.min(...amounts)) : "").replace(/\{\{max\}\}/gu, amounts.length > 0 ? formatNumber(Math.max(...amounts)) : "").replace(/\{\{sum\}\}/gu, amounts.length > 0 ? formatNumber(Number(amounts.reduce((total, value) => total + value, 0).toFixed(2))) : "").replace(/\{\{creators\}\}/gu, creators).replace(/\{\{tail\}\}/gu, input.tail);
|
|
11131
|
+
return replaced.replace(/¥(\s*)/gu, "").replace(/\s*,\s*,/gu, "\uFF0C").trim();
|
|
10716
11132
|
}
|
|
10717
11133
|
|
|
10718
11134
|
// src/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.ts
|
|
@@ -11126,9 +11542,6 @@ var URGENT_PATTERN = /紧急/u;
|
|
|
11126
11542
|
var PRIORITY_GROUP_ID = "priority";
|
|
11127
11543
|
var PRIORITY_GROUP_TITLE = "\u5EFA\u8BAE\u4F18\u5148\u5904\u7406\u7684\u6D41\u7A0B";
|
|
11128
11544
|
var GROUP_MIN_ITEMS_FOR_SUBGROUP = 3;
|
|
11129
|
-
function focusAppliesToKind(focus, kind) {
|
|
11130
|
-
return intentAppliesToKind(focus, kind);
|
|
11131
|
-
}
|
|
11132
11545
|
function timeOf(value) {
|
|
11133
11546
|
if (!value) return void 0;
|
|
11134
11547
|
const text = value.trim();
|
|
@@ -11235,6 +11648,7 @@ function toRequestData(row) {
|
|
|
11235
11648
|
creater: row.creater,
|
|
11236
11649
|
createrName: row.createrName,
|
|
11237
11650
|
lastFeedBackDateTime: row.lastFeedBackDateTime,
|
|
11651
|
+
...row.planFinishDatetime ? { planFinishDatetime: row.planFinishDatetime } : {},
|
|
11238
11652
|
summary: row.summary ?? ""
|
|
11239
11653
|
};
|
|
11240
11654
|
}
|
|
@@ -11586,7 +12000,7 @@ async function collectRawTodos(args, env) {
|
|
|
11586
12000
|
const focusText = typeof args.groupFocus === "string" ? args.groupFocus.trim() : "";
|
|
11587
12001
|
const fieldsById = /* @__PURE__ */ new Map();
|
|
11588
12002
|
if (focusText) {
|
|
11589
|
-
const targetRows = wfIdGroup.filter((group) => !group.topPriority &&
|
|
12003
|
+
const targetRows = wfIdGroup.filter((group) => !group.topPriority && activeRuleFor(group.title)?.aiGroup?.groupRule.aiContext === "\u6D41\u7A0B\u8BE6\u60C5").flatMap((group) => group.requestDatas ?? []);
|
|
11590
12004
|
const targetIds = [...new Set(targetRows.map((row) => row.requestId).filter(Boolean))];
|
|
11591
12005
|
if (targetIds.length > 0) {
|
|
11592
12006
|
const { facts, stats } = await fetchDetailFacts(env, targetIds, args, stampsOfRows(targetRows));
|
|
@@ -11602,26 +12016,31 @@ async function collectRawTodos(args, env) {
|
|
|
11602
12016
|
};
|
|
11603
12017
|
}
|
|
11604
12018
|
}
|
|
11605
|
-
groupingBrief = wfIdGroup.map((group) =>
|
|
11606
|
-
|
|
11607
|
-
|
|
11608
|
-
|
|
11609
|
-
|
|
11610
|
-
|
|
11611
|
-
|
|
11612
|
-
|
|
11613
|
-
|
|
11614
|
-
|
|
11615
|
-
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
12019
|
+
groupingBrief = wfIdGroup.map((group) => {
|
|
12020
|
+
const groupRule = activeRuleFor(group.title)?.aiGroup?.groupRule;
|
|
12021
|
+
const groupingPrompt = groupRule && groupRule.focus === false && typeof groupRule.groupingPrompt === "string" ? groupRule.groupingPrompt.trim() : "";
|
|
12022
|
+
return {
|
|
12023
|
+
groupId: group.id,
|
|
12024
|
+
title: group.title,
|
|
12025
|
+
count: group.count,
|
|
12026
|
+
topPriority: group.topPriority,
|
|
12027
|
+
...groupingPrompt ? { groupingPrompt } : {},
|
|
12028
|
+
items: (group.requestDatas ?? []).map((row, index) => ({
|
|
12029
|
+
idx: index + 1,
|
|
12030
|
+
requestId: row.requestId,
|
|
12031
|
+
title: row.requestNameTitle ?? "",
|
|
12032
|
+
// 客户问题支持类无侧重点时按这两个布尔分组(模型不用自己解析日期文案)
|
|
12033
|
+
overdue: isOverdueRow(row),
|
|
12034
|
+
expiringToday: isExpiringTodayRow(row),
|
|
12035
|
+
...row.userOverTime ? { userOverTime: row.userOverTime } : {},
|
|
12036
|
+
...row.summary ? { summary: row.summary } : {},
|
|
12037
|
+
// `summaryCached:true` = 这条已有本地摘要(按 requestId__lastFeedBackDateTime 命中),
|
|
12038
|
+
// 分组仍要做(聚类看标题),但**不要再给它写摘要**。
|
|
12039
|
+
...cachedSummaryIds.has(row.requestId) ? { summaryCached: true } : {},
|
|
12040
|
+
...fieldsById.has(row.requestId) ? { fields: fieldsById.get(row.requestId) } : {}
|
|
12041
|
+
}))
|
|
12042
|
+
};
|
|
12043
|
+
});
|
|
11625
12044
|
const groupingFocus = typeof args.groupFocus === "string" ? args.groupFocus.trim() : "";
|
|
11626
12045
|
groupInfo = {
|
|
11627
12046
|
smartSummaryTitle: grouped.smartSummaryTitle,
|
|
@@ -11814,11 +12233,11 @@ function readAiGroups(value) {
|
|
|
11814
12233
|
if (!record) {
|
|
11815
12234
|
throw workflowValidationError("ai_groups_invalid", `${label} \u5FC5\u987B\u662F\u5BF9\u8C61 { groupId, title, requestIds }`, { retryAllowed: false });
|
|
11816
12235
|
}
|
|
11817
|
-
const unknownKeys = Object.keys(record).filter((key) => !["groupId", "title", "requestIds"
|
|
12236
|
+
const unknownKeys = Object.keys(record).filter((key) => !["groupId", "title", "requestIds"].includes(key));
|
|
11818
12237
|
if (unknownKeys.length > 0) {
|
|
11819
12238
|
throw workflowValidationError(
|
|
11820
12239
|
"ai_groups_invalid",
|
|
11821
|
-
`${label} \u4E0D\u63A5\u53D7\u5B57\u6BB5\uFF1A${unknownKeys.join(", ")}\uFF1B\u53EA\u652F\u6301 groupId / title / requestIds
|
|
12240
|
+
`${label} \u4E0D\u63A5\u53D7\u5B57\u6BB5\uFF1A${unknownKeys.join(", ")}\uFF1B\u53EA\u652F\u6301 groupId / title / requestIds`,
|
|
11822
12241
|
{ retryAllowed: false, details: { unknownKeys } }
|
|
11823
12242
|
);
|
|
11824
12243
|
}
|
|
@@ -11839,37 +12258,15 @@ function readAiGroups(value) {
|
|
|
11839
12258
|
);
|
|
11840
12259
|
}
|
|
11841
12260
|
const hasIds = Array.isArray(record.requestIds) && record.requestIds.length > 0;
|
|
11842
|
-
|
|
11843
|
-
if (hasIds && hasSeq) {
|
|
12261
|
+
if (!hasIds) {
|
|
11844
12262
|
throw workflowValidationError(
|
|
11845
12263
|
"ai_groups_invalid",
|
|
11846
|
-
`${label} \
|
|
12264
|
+
`${label} \u5FC5\u987B\u7ED9 requestIds\uFF08\u975E\u7A7A\u7684 requestId \u5B57\u7B26\u4E32\u6570\u7EC4\uFF09`,
|
|
11847
12265
|
{ retryAllowed: false }
|
|
11848
12266
|
);
|
|
11849
12267
|
}
|
|
11850
|
-
if (!hasIds && !hasSeq) {
|
|
11851
|
-
throw workflowValidationError(
|
|
11852
|
-
"ai_groups_invalid",
|
|
11853
|
-
`${label} \u9700\u8981 requestIds \u6216 seq\uFF08\u7EC4\u5185 1-based \u5E8F\u53F7\uFF0C\u89C1 collect \u7684 groupingBrief\uFF09`,
|
|
11854
|
-
{ retryAllowed: false }
|
|
11855
|
-
);
|
|
11856
|
-
}
|
|
11857
|
-
const seqNumbers = [];
|
|
11858
|
-
if (hasSeq) {
|
|
11859
|
-
for (const item of record.seq) {
|
|
11860
|
-
const n = typeof item === "number" ? item : Number(item);
|
|
11861
|
-
if (!Number.isInteger(n) || n < 1) {
|
|
11862
|
-
throw workflowValidationError(
|
|
11863
|
-
"ai_groups_invalid",
|
|
11864
|
-
`${label}.seq \u53EA\u63A5\u53D7 \u22651 \u7684\u6574\u6570\u5E8F\u53F7\uFF0C\u6536\u5230 ${String(item)}`,
|
|
11865
|
-
{ retryAllowed: false }
|
|
11866
|
-
);
|
|
11867
|
-
}
|
|
11868
|
-
seqNumbers.push(n);
|
|
11869
|
-
}
|
|
11870
|
-
}
|
|
11871
12268
|
const ids = [];
|
|
11872
|
-
for (const item of
|
|
12269
|
+
for (const item of record.requestIds) {
|
|
11873
12270
|
const id = typeof item === "string" ? item.trim() : typeof item === "number" ? String(item) : "";
|
|
11874
12271
|
if (!id) {
|
|
11875
12272
|
throw workflowValidationError(
|
|
@@ -11881,7 +12278,7 @@ function readAiGroups(value) {
|
|
|
11881
12278
|
ids.push(id);
|
|
11882
12279
|
}
|
|
11883
12280
|
const bucket = map.get(groupId) ?? [];
|
|
11884
|
-
bucket.push({ groupId, title, requestIds: [...new Set(ids)]
|
|
12281
|
+
bucket.push({ groupId, title, requestIds: [...new Set(ids)] });
|
|
11885
12282
|
map.set(groupId, bucket);
|
|
11886
12283
|
});
|
|
11887
12284
|
return map;
|
|
@@ -11900,34 +12297,21 @@ function ctxEmptyOf(facts) {
|
|
|
11900
12297
|
function rowMetricsOf(row, metrics) {
|
|
11901
12298
|
return metrics?.get(row.requestId) ?? {};
|
|
11902
12299
|
}
|
|
11903
|
-
function
|
|
11904
|
-
if (
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
return formatIssueSupportGroupSummary({ count: rows.length, restCount, creators });
|
|
11908
|
-
}
|
|
11909
|
-
if (kind === "leave") {
|
|
11910
|
-
const items = rows.map((row) => rowMetricsOf(row, metrics));
|
|
11911
|
-
return formatLeaveGroupSummary({
|
|
11912
|
-
count: rows.length,
|
|
11913
|
-
leaveTypes: items.map((item) => item.leaveType),
|
|
11914
|
-
creators
|
|
11915
|
-
});
|
|
12300
|
+
function metricValueOf(row, metric, sysArg, facts, metrics) {
|
|
12301
|
+
if (sysArg) {
|
|
12302
|
+
const key = Object.keys(row).find((item) => item.toLowerCase() === metric.toLowerCase());
|
|
12303
|
+
return key ? row[key] : void 0;
|
|
11916
12304
|
}
|
|
11917
|
-
|
|
11918
|
-
|
|
11919
|
-
|
|
11920
|
-
if (
|
|
11921
|
-
|
|
11922
|
-
return formatFinanceGroupSummary({
|
|
11923
|
-
min: Math.min(...amounts),
|
|
11924
|
-
max: Math.max(...amounts),
|
|
11925
|
-
sum,
|
|
11926
|
-
categories: items.map((item) => item.feeCategory),
|
|
11927
|
-
creators
|
|
11928
|
-
});
|
|
12305
|
+
const rowMetrics = metrics?.get(row.requestId);
|
|
12306
|
+
if (rowMetrics) {
|
|
12307
|
+
if (/金额|费用|价|合计/u.test(metric) && typeof rowMetrics.amount === "number") return rowMetrics.amount;
|
|
12308
|
+
if (/天数|时长/u.test(metric) && typeof rowMetrics.leaveDays === "number") return rowMetrics.leaveDays;
|
|
12309
|
+
if (/假别|假种|假期/u.test(metric) && typeof rowMetrics.leaveType === "string") return rowMetrics.leaveType;
|
|
11929
12310
|
}
|
|
11930
|
-
|
|
12311
|
+
const fact = facts?.get(row.requestId);
|
|
12312
|
+
const field = (fact?.fields ?? []).find((item) => String(item.fieldName ?? "").includes(metric));
|
|
12313
|
+
const value = field?.value;
|
|
12314
|
+
return value === void 0 || String(value).trim() === "" ? void 0 : value;
|
|
11931
12315
|
}
|
|
11932
12316
|
function totalTodoCount(groups) {
|
|
11933
12317
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -11995,6 +12379,7 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
11995
12379
|
}
|
|
11996
12380
|
}
|
|
11997
12381
|
const warnings = (base.warnings ?? []).filter((text) => !text.startsWith("markdown \u53EA\u5C55\u793A\u524D"));
|
|
12382
|
+
warnings.push(...primeRules(env.ctx).warnings);
|
|
11998
12383
|
if (skipDetail) {
|
|
11999
12384
|
warnings.push("withDetailContext=false\uFF1A\u672C\u6B21\u672A\u62C9\u53D6\u4EFB\u4F55\u8BE6\u60C5\u2014\u2014\u8BF7\u5047/\u8D22\u52A1\u9608\u503C\u6539\u4E3A\u6309\u6807\u9898\u8BC6\u522B\u3001\u8DF3\u8FC7\u6574\u7EC4\u7A7A\u5224\u5B9A\uFF0C\u4E5F\u4E0D\u4EA7 summaryBatches");
|
|
12000
12385
|
} else if (cachedIds.size > 0) {
|
|
@@ -12009,7 +12394,7 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12009
12394
|
topPriority: true,
|
|
12010
12395
|
title: group.title,
|
|
12011
12396
|
count: group.count,
|
|
12012
|
-
//
|
|
12397
|
+
// 大分组(含优先组)默认展开;只有汇总项(ai二次分组)收缩。
|
|
12013
12398
|
defaultExpanded: true,
|
|
12014
12399
|
displayItems: requestItemsOf(group.requestDatas)
|
|
12015
12400
|
};
|
|
@@ -12018,106 +12403,78 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12018
12403
|
const used = /* @__PURE__ */ new Set();
|
|
12019
12404
|
const subGroups = [];
|
|
12020
12405
|
const singles = [];
|
|
12021
|
-
const kind = detectBusinessKind(group.title);
|
|
12022
|
-
const rawPlans = plans?.get(group.id) ?? [];
|
|
12023
|
-
const groupHasFocus = hasFocus && focusAppliesToKind(groupFocus, kind);
|
|
12024
|
-
const plansAllowed = groupHasFocus || kind === "internal-message";
|
|
12025
|
-
const groupPlans = plansAllowed ? rawPlans : [];
|
|
12026
|
-
if (rawPlans.length > 0 && !plansAllowed) {
|
|
12027
|
-
warnings.push(hasFocus ? `\u300C${group.title}\u300D\u610F\u56FE\u300C${groupFocus}\u300D\u4E0D\u9002\u7528\u4E8E\u672C\u7C7B\u578B\uFF0C\u5DF2\u5FFD\u7565 aiGroups\uFF0C\u6309\u65E0\u610F\u56FE\u89C4\u5219\u5904\u7406` : `\u300C${group.title}\u300D${BUSINESS_KIND_LABEL[kind]}\u9ED8\u8BA4\u4E0D\u6309\u6807\u9898\u4E8C\u6B21\u5206\u7EC4\uFF0C\u5DF2\u5FFD\u7565 aiGroups\uFF08\u8981\u6309\u4FA7\u91CD\u70B9\u5206\u7EC4\u8BF7\u5728 groupFocus \u91CC\u8BF4\u660E\uFF09`);
|
|
12028
|
-
}
|
|
12029
12406
|
const flatReturn = () => ({
|
|
12030
12407
|
id: group.id,
|
|
12031
12408
|
topPriority: false,
|
|
12032
12409
|
title: group.title,
|
|
12033
12410
|
count: group.count,
|
|
12034
|
-
defaultExpanded:
|
|
12411
|
+
defaultExpanded: true,
|
|
12035
12412
|
displayItems: requestItemsOf(group.requestDatas)
|
|
12036
12413
|
});
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12414
|
+
const rawPlans = plans?.get(group.id) ?? [];
|
|
12415
|
+
const rule = activeRuleFor(group.title);
|
|
12416
|
+
if (!rule?.aiGroup) {
|
|
12417
|
+
if (rawPlans.length > 0) warnings.push(`\u300C${group.title}\u300D\u672A\u914D\u7F6E aiGroup\uFF0C\u5DF2\u5FFD\u7565 aiGroups`);
|
|
12418
|
+
if (!rule?.needSummary) warnings.push(`\u300C${group.title}\u300D\u4E0D\u9700\u8981 AI \u6458\u8981\uFF0Csummary \u7528\u6807\u9898\u515C\u5E95`);
|
|
12419
|
+
warnings.push(`\u300C${group.title}\u300D\u672A\u914D\u7F6E ai\u4E8C\u6B21\u5206\u7EC4\uFF0C${group.requestDatas.length} \u6761\u5E73\u94FA`);
|
|
12040
12420
|
return flatReturn();
|
|
12041
12421
|
}
|
|
12422
|
+
const groupRule = rule.aiGroup.groupRule;
|
|
12423
|
+
const focusMode = groupRule.focus === true;
|
|
12424
|
+
const groupPlans = rawPlans;
|
|
12042
12425
|
if (group.requestDatas.length < GROUP_MIN_ITEMS_FOR_SUBGROUP) {
|
|
12043
|
-
if (rawPlans.length > 0) warnings.push(`\u300C${group.title}\u300D\u4E0D\u8DB3
|
|
12426
|
+
if (rawPlans.length > 0) warnings.push(`\u300C${group.title}\u300D\u4E0D\u8DB3 ${GROUP_MIN_ITEMS_FOR_SUBGROUP} \u6761\uFF08\u786C\u95E8\u69DB\uFF09\uFF0C\u5FFD\u7565 aiGroups \u5E76\u5E73\u94FA`);
|
|
12044
12427
|
return flatReturn();
|
|
12045
12428
|
}
|
|
12046
|
-
if (
|
|
12047
|
-
|
|
12048
|
-
}
|
|
12049
|
-
if (kind === "internal-message" && groupPlans.length === 0) {
|
|
12429
|
+
if (!focusMode && groupPlans.length === 0) {
|
|
12430
|
+
const groupingPrompt = typeof groupRule.groupingPrompt === "string" ? groupRule.groupingPrompt.trim() : "";
|
|
12050
12431
|
throw workflowValidationError(
|
|
12051
12432
|
"ai_groups_required",
|
|
12052
|
-
`\u300C${group.title}\u300D\
|
|
12433
|
+
`\u300C${group.title}\u300D\u6309\u89C4\u5219\u8981\u6C42\u505A AI \u4E8C\u6B21\u5206\u7EC4\uFF08focus=false\uFF0C\u4E0A\u4E0B\u6587\uFF1A${groupRule.aiContext ?? "\u6D41\u7A0B\u6807\u9898"}\uFF09\uFF0C\u5FC5\u987B\u7ED9\u672C\u7EC4 aiGroups\uFF1B\u53EF\u7528 groupId\uFF1A${group.id}\uFF0CrequestIds \u53D6\u672C\u7EC4 ${group.requestDatas.length} \u6761` + (groupingPrompt ? `\u3002\u5206\u7EC4\u53E3\u5F84\uFF08groupingPrompt\uFF09\uFF1A${groupingPrompt}` : ""),
|
|
12053
12434
|
{
|
|
12054
12435
|
retryAllowed: true,
|
|
12055
|
-
details: {
|
|
12436
|
+
details: {
|
|
12437
|
+
groupId: group.id,
|
|
12438
|
+
count: group.requestDatas.length,
|
|
12439
|
+
aiContext: groupRule.aiContext ?? "",
|
|
12440
|
+
...groupingPrompt ? { groupingPrompt } : {}
|
|
12441
|
+
}
|
|
12056
12442
|
}
|
|
12057
12443
|
);
|
|
12058
12444
|
}
|
|
12059
12445
|
if (groupPlans.length === 0) {
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
const
|
|
12067
|
-
if (
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
if (unknown > 0) {
|
|
12081
|
-
warnings.push(
|
|
12082
|
-
`\u300C${group.title}\u300D\u6709 ${unknown} \u6761\u6D41\u7A0B\u8BE6\u60C5\u6570\u636E\u53D6\u4E0D\u5230${kind === "leave" ? "\u8BF7\u5047\u5929\u6570" : "\u62A5\u9500\u91D1\u989D"}\uFF0C\u4E0D\u505A ai\u4E8C\u6B21\u5206\u7EC4\u3001\u6309\u5355\u6761\u5E73\u94FA`
|
|
12083
|
-
);
|
|
12084
|
-
}
|
|
12085
|
-
} else if (kind === "issue-support") {
|
|
12086
|
-
const urgentRows = [];
|
|
12087
|
-
const rest = [];
|
|
12088
|
-
for (const row of group.requestDatas) {
|
|
12089
|
-
if (isExpiredUserOverTime(row.userOverTime) || isExpiringTodayRow(row)) urgentRows.push(row);
|
|
12090
|
-
else rest.push(row);
|
|
12091
|
-
}
|
|
12092
|
-
singles.push(...rest);
|
|
12093
|
-
if (urgentRows.length > 0) {
|
|
12094
|
-
subGroups.push({ title: ISSUE_SUPPORT_GROUP_TITLE, requestDatas: urgentRows });
|
|
12095
|
-
warnings.push(
|
|
12096
|
-
`\u300C${group.title}\u300D\u6309\u5BA2\u6237\u95EE\u9898\u652F\u6301\u7C7B\u53E3\u5F84\uFF1A${urgentRows.length} \u6761\u5DF2\u8FC7\u671F\u6216\u4ECA\u65E5\u5230\u671F\uFF0C\u5176\u4F59 ${rest.length} \u6761\u5E73\u94FA`
|
|
12097
|
-
);
|
|
12098
|
-
} else {
|
|
12099
|
-
warnings.push(`\u300C${group.title}\u300D\u6CA1\u6709\u5DF2\u8FC7\u671F\u6216\u4ECA\u65E5\u5230\u671F\u7684\u6761\u76EE\uFF08userOverTime \u672A\u547D\u4E2D\uFF09\uFF0C\u5168\u90E8\u5E73\u94FA`);
|
|
12100
|
-
}
|
|
12446
|
+
const conditions = groupRule.focusKeyword ?? [];
|
|
12447
|
+
const sysArg = groupRule.sysArg === true;
|
|
12448
|
+
const hit = [];
|
|
12449
|
+
const missing = /* @__PURE__ */ new Set();
|
|
12450
|
+
for (const row of group.requestDatas) {
|
|
12451
|
+
const resolve3 = (metric) => {
|
|
12452
|
+
const value = metricValueOf(row, metric, sysArg, facts, metrics);
|
|
12453
|
+
if (value === void 0) missing.add(metric);
|
|
12454
|
+
return value;
|
|
12455
|
+
};
|
|
12456
|
+
if (conditions.length > 0 && evaluateFocusKeywords(conditions, resolve3)) hit.push(row);
|
|
12457
|
+
else singles.push(row);
|
|
12458
|
+
}
|
|
12459
|
+
const conditionText = conditions.map((condition) => condition.join(" ")).join(" \u4E14 ");
|
|
12460
|
+
const title = groupRule.groupTitle?.trim() || conditionText || "\u6C47\u603B";
|
|
12461
|
+
if (hit.length > 0) {
|
|
12462
|
+
subGroups.push({ title, requestDatas: hit });
|
|
12463
|
+
warnings.push(
|
|
12464
|
+
`\u300C${group.title}\u300D\u6309\u89C4\u5219\u300C${title}\u300D\u547D\u4E2D ${hit.length} \u6761\uFF08${conditionText}\uFF09\uFF0C\u5176\u4F59 ${group.requestDatas.length - hit.length} \u6761\u5E73\u94FA`
|
|
12465
|
+
);
|
|
12101
12466
|
} else {
|
|
12102
|
-
|
|
12103
|
-
|
|
12467
|
+
warnings.push(`\u300C${group.title}\u300D\u89C4\u5219\u300C${title}\u300D\u547D\u4E2D 0 \u6761${conditionText ? `\uFF08${conditionText}\uFF09` : ""}\uFF0C\u5168\u90E8\u5E73\u94FA`);
|
|
12468
|
+
}
|
|
12469
|
+
if (missing.size > 0) {
|
|
12470
|
+
warnings.push(`\u300C${group.title}\u300D\u6307\u6807\u53D6\u4E0D\u5230\uFF1A${[...missing].join("\u3001")}\uFF0C\u76F8\u5173\u6761\u76EE\u6309\u5355\u6761\u5E73\u94FA\uFF1B\u8BF7\u68C0\u67E5\u89C4\u5219\u91CC\u7684\u6307\u6807\u540D`);
|
|
12104
12471
|
}
|
|
12105
12472
|
} else {
|
|
12106
|
-
const reservedTitle =
|
|
12473
|
+
const reservedTitle = groupRule.groupTitle ?? "";
|
|
12107
12474
|
const droppedByThreshold = [];
|
|
12108
12475
|
for (const plan of groupPlans) {
|
|
12109
12476
|
const datas = [];
|
|
12110
|
-
const planRequestIds = plan.requestIds
|
|
12111
|
-
const row = group.requestDatas[n - 1];
|
|
12112
|
-
if (!row) {
|
|
12113
|
-
throw workflowValidationError(
|
|
12114
|
-
"ai_group_seq_out_of_range",
|
|
12115
|
-
`aiGroups \u7ED9\u300C${group.title}\u300D\u7684 seq \u91CC\u6709 ${n}\uFF0C\u4F46\u8BE5\u7EC4\u53EA\u6709 ${group.requestDatas.length} \u6761\uFF08\u5E8F\u53F7\u4ECE 1 \u5F00\u59CB\uFF09`,
|
|
12116
|
-
{ retryAllowed: true, details: { groupId: group.id, seq: n, count: group.requestDatas.length } }
|
|
12117
|
-
);
|
|
12118
|
-
}
|
|
12119
|
-
return row.requestId;
|
|
12120
|
-
});
|
|
12477
|
+
const planRequestIds = plan.requestIds;
|
|
12121
12478
|
for (const requestId of planRequestIds) {
|
|
12122
12479
|
const data = byRequestId.get(requestId);
|
|
12123
12480
|
if (!data) {
|
|
@@ -12141,11 +12498,11 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12141
12498
|
if (reservedTitle && plan.title === reservedTitle) {
|
|
12142
12499
|
const kept2 = [];
|
|
12143
12500
|
const dropped = [];
|
|
12501
|
+
const conditions = groupRule.focusKeyword ?? [];
|
|
12502
|
+
const sysArg = groupRule.sysArg === true;
|
|
12144
12503
|
for (const row of datas) {
|
|
12145
|
-
const
|
|
12146
|
-
|
|
12147
|
-
const hit = kind === "leave" ? typeof value === "number" && value <= LEAVE_DAY_THRESHOLD : typeof value === "number" && value > 0 && value <= FINANCE_AMOUNT_THRESHOLD;
|
|
12148
|
-
(hit ? kept2 : dropped).push(row);
|
|
12504
|
+
const resolve3 = (metric) => metricValueOf(row, metric, sysArg, facts, metrics);
|
|
12505
|
+
(conditions.length > 0 && evaluateFocusKeywords(conditions, resolve3) ? kept2 : dropped).push(row);
|
|
12149
12506
|
}
|
|
12150
12507
|
if (dropped.length > 0) {
|
|
12151
12508
|
droppedByThreshold.push(...dropped);
|
|
@@ -12173,8 +12530,38 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12173
12530
|
singles.push(...uncovered);
|
|
12174
12531
|
warnings.push(`\u300C${group.title}\u300D\u6709 ${uncovered.length} \u6761\u672A\u88AB AI \u5206\u7EC4\uFF0C\u6309\u5355\u6761\u5E73\u94FA\uFF08\u4E0D\u9020 other \u5B50\u7EC4\uFF09`);
|
|
12175
12532
|
}
|
|
12533
|
+
if (focusMode && subGroups.length > 1) {
|
|
12534
|
+
const sorted = [...subGroups].sort((a, b) => b.requestDatas.length - a.requestDatas.length);
|
|
12535
|
+
const [keep] = sorted;
|
|
12536
|
+
const dropped = sorted.slice(1);
|
|
12537
|
+
const droppedCount = dropped.reduce((sum, sub) => sum + sub.requestDatas.length, 0);
|
|
12538
|
+
for (const sub of dropped) singles.push(...sub.requestDatas);
|
|
12539
|
+
subGroups.length = 0;
|
|
12540
|
+
subGroups.push(keep);
|
|
12541
|
+
warnings.push(
|
|
12542
|
+
`\u300C${group.title}\u300D\u4FA7\u91CD\u70B9\u4EA7\u51FA ${sorted.length} \u4E2A\u5B50\u7EC4\uFF0C\u6309\u89C4\u5219\u53EA\u4FDD\u7559\u6761\u6570\u6700\u591A\u7684\u300C${keep.title}\u300D\uFF08${keep.requestDatas.length} \u6761\uFF09\uFF0C\u5176\u4F59 ${droppedCount} \u6761\u6539\u5355\u6761\u5E73\u94FA`
|
|
12543
|
+
);
|
|
12544
|
+
}
|
|
12176
12545
|
}
|
|
12177
|
-
|
|
12546
|
+
const renderSubGroupSummary = (sub) => {
|
|
12547
|
+
const groupSummary = rule.aiGroup?.groupSummary;
|
|
12548
|
+
if (!groupSummary || groupSummary.needAI || !groupSummary.template) return "";
|
|
12549
|
+
if (groupRule.groupTitle && sub.title !== groupRule.groupTitle) return "";
|
|
12550
|
+
const rows = sub.requestDatas;
|
|
12551
|
+
const items = rows.map((row) => rowMetricsOf(row, metrics));
|
|
12552
|
+
const amounts = items.map((item) => item.amount).filter((value) => typeof value === "number" && value > 0);
|
|
12553
|
+
if (groupSummary.template.includes("{{min}}") && amounts.length === 0) return "";
|
|
12554
|
+
return renderGroupSummaryTemplate({
|
|
12555
|
+
template: groupSummary.template,
|
|
12556
|
+
tail: groupSummary.tail,
|
|
12557
|
+
count: rows.length,
|
|
12558
|
+
restCount: singles.length,
|
|
12559
|
+
categories: items.map((item) => item.leaveType ?? item.feeCategory),
|
|
12560
|
+
amounts,
|
|
12561
|
+
creators: rows.map((row) => row.createrName)
|
|
12562
|
+
});
|
|
12563
|
+
};
|
|
12564
|
+
if (!focusMode) subGroups.sort((a, b) => b.requestDatas.length - a.requestDatas.length);
|
|
12178
12565
|
const groupItems = subGroups.map((sub, index) => ({
|
|
12179
12566
|
// 键顺序照新目标结构:type → id → title → count → summary → defaultExpanded → requestDatas
|
|
12180
12567
|
type: "group",
|
|
@@ -12182,7 +12569,7 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12182
12569
|
title: sub.title,
|
|
12183
12570
|
count: sub.requestDatas.length,
|
|
12184
12571
|
// 组摘要口径不变(Q4):只有 CLI 自己造的三类固定组用固定文案;AI 子组一律留空交 groupSummary。
|
|
12185
|
-
summary:
|
|
12572
|
+
summary: renderSubGroupSummary(sub),
|
|
12186
12573
|
// 汇总项自身默认收缩(与大分组的展开状态互相独立)
|
|
12187
12574
|
defaultExpanded: false,
|
|
12188
12575
|
requestDatas: sub.requestDatas
|
|
@@ -12192,7 +12579,8 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12192
12579
|
topPriority: false,
|
|
12193
12580
|
title: group.title,
|
|
12194
12581
|
count: group.count,
|
|
12195
|
-
|
|
12582
|
+
// 大分组默认展开(与汇总项自身的收缩状态互相独立)
|
|
12583
|
+
defaultExpanded: true,
|
|
12196
12584
|
// 汇总项在前、单独条目在后。
|
|
12197
12585
|
displayItems: [...groupItems, ...requestItemsOf(singles)]
|
|
12198
12586
|
};
|
|
@@ -12213,6 +12601,9 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12213
12601
|
}
|
|
12214
12602
|
|
|
12215
12603
|
// src/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.ts
|
|
12604
|
+
function needAiSummary(workflowName) {
|
|
12605
|
+
return activeRuleFor(workflowName)?.needSummary ?? true;
|
|
12606
|
+
}
|
|
12216
12607
|
var DEFAULT_MAX_CHARS_PER_BATCH = 24e3;
|
|
12217
12608
|
var DEFAULT_MAX_ITEMS_PER_BATCH = 100;
|
|
12218
12609
|
var DEFAULT_REQUEST_SUMMARY_MAX3 = 50;
|
|
@@ -12319,7 +12710,7 @@ function validateFinalGroups(value) {
|
|
|
12319
12710
|
(sum, item) => sum + (item.type === "group" ? item.requestDatas.length : 1),
|
|
12320
12711
|
0
|
|
12321
12712
|
);
|
|
12322
|
-
return topPriority ? { id, topPriority: true, title, count, defaultExpanded: true, displayItems } : { id, topPriority: false, title, count, defaultExpanded:
|
|
12713
|
+
return topPriority ? { id, topPriority: true, title, count, defaultExpanded: true, displayItems } : { id, topPriority: false, title, count, defaultExpanded: true, displayItems };
|
|
12323
12714
|
});
|
|
12324
12715
|
}
|
|
12325
12716
|
async function readFinalGroups(args, env) {
|
|
@@ -12340,7 +12731,7 @@ function collectSummaryUnits(groups) {
|
|
|
12340
12731
|
const units = [];
|
|
12341
12732
|
for (const group of groups) {
|
|
12342
12733
|
if (group.topPriority) {
|
|
12343
|
-
if (!
|
|
12734
|
+
if (!needAiSummary(group.title)) continue;
|
|
12344
12735
|
units.push({
|
|
12345
12736
|
groupId: group.id,
|
|
12346
12737
|
groupTitle: group.title,
|
|
@@ -12381,7 +12772,7 @@ function collectSummaryUnits(groups) {
|
|
|
12381
12772
|
async function runSummaryContext(args, env, prefetched) {
|
|
12382
12773
|
const groups = await readFinalGroups(args, env);
|
|
12383
12774
|
const units = collectSummaryUnits(groups);
|
|
12384
|
-
const skippedSatisfaction = groups.filter((group) =>
|
|
12775
|
+
const skippedSatisfaction = groups.filter((group) => !needAiSummary(group.title)).reduce((sum, group) => sum + rowsOfGroup(group).length, 0);
|
|
12385
12776
|
const requestIds = [...new Set(units.flatMap((unit) => unit.rows.map((row) => row.requestId)))].filter(Boolean);
|
|
12386
12777
|
const summaryMaxChars = readBoundedInt(
|
|
12387
12778
|
args.summaryMaxChars,
|
|
@@ -12579,7 +12970,7 @@ async function runSummary(args, env) {
|
|
|
12579
12970
|
let cacheWritten = 0;
|
|
12580
12971
|
let titleSummary = 0;
|
|
12581
12972
|
for (const group of groups) {
|
|
12582
|
-
if (
|
|
12973
|
+
if (!needAiSummary(group.title)) {
|
|
12583
12974
|
for (const row of rowsOfGroup(group)) {
|
|
12584
12975
|
if ((row.summary ?? "").trim()) continue;
|
|
12585
12976
|
row.summary = row.requestNameTitle ?? "";
|
|
@@ -12642,7 +13033,7 @@ async function runSummary(args, env) {
|
|
|
12642
13033
|
}
|
|
12643
13034
|
};
|
|
12644
13035
|
for (const group of groups) {
|
|
12645
|
-
if (!
|
|
13036
|
+
if (!needAiSummary(group.title)) continue;
|
|
12646
13037
|
if (group.topPriority) {
|
|
12647
13038
|
applyAll(rowsOfGroup(group));
|
|
12648
13039
|
continue;
|
|
@@ -12669,7 +13060,7 @@ async function runSummary(args, env) {
|
|
|
12669
13060
|
if (prefilledKept > 0) {
|
|
12670
13061
|
warnings.push(`\u6709 ${prefilledKept} \u6761\u6CBF\u7528\u672C\u5730\u6458\u8981\u7F13\u5B58\uFF08\u672A\u91CD\u65B0\u751F\u6210\uFF09`);
|
|
12671
13062
|
}
|
|
12672
|
-
const titleSummaryCount = groups.filter((group) =>
|
|
13063
|
+
const titleSummaryCount = groups.filter((group) => !needAiSummary(group.title)).reduce((sum, group) => sum + rowsOfGroup(group).length, 0);
|
|
12673
13064
|
if (titleSummaryCount > 0) {
|
|
12674
13065
|
warnings.push(`\u6709 ${titleSummaryCount} \u6761\u6EE1\u610F\u5EA6\u7C7B\u5F85\u529E\u4E0D\u8C03\u7528 AI\uFF0Csummary \u76F4\u63A5\u4F7F\u7528\u6761\u76EE\u6807\u9898\uFF08\u4FDD\u8BC1\u975E\u7A7A\uFF09`);
|
|
12675
13066
|
}
|
|
@@ -12837,7 +13228,7 @@ async function runGroupSummaryContext(args, env) {
|
|
|
12837
13228
|
"\u672C\u6B21\u6CA1\u6709\u9700\u8981 AI \u5199\u7EC4\u6458\u8981\u7684\u6C47\u603B\u9879\uFF1A\u6240\u6709\u4E8C\u6B21\u5206\u7EC4\u6C47\u603B\u9879\u7684\u7EC4\u6458\u8981\u5747\u7531 CLI \u56FA\u5B9A\u751F\u6210"
|
|
12838
13229
|
);
|
|
12839
13230
|
}
|
|
12840
|
-
const deterministicGroups = groups.filter((group) => !group.topPriority &&
|
|
13231
|
+
const deterministicGroups = groups.filter((group) => !group.topPriority && activeRuleFor(group.title)?.aiGroup?.groupSummary.needAI === false).reduce((sum, group) => sum + groupItemsOf(group).length, 0);
|
|
12841
13232
|
return {
|
|
12842
13233
|
data: {
|
|
12843
13234
|
smartSummaryTitle: readSmartSummaryTitle(args, `\u60A8\u5F53\u524D\u6709 ${totalCount} \u6761\u5F85\u529E\uFF0C\u6E05\u5355\u5982\u4E0B\uFF1A`),
|
|
@@ -13011,18 +13402,16 @@ var inputSchema = schemaOf({
|
|
|
13011
13402
|
},
|
|
13012
13403
|
aiGroups: {
|
|
13013
13404
|
type: "array",
|
|
13014
|
-
description: "smartGroup \u7684\u4E8C\u6B21\u5206\u7EC4\u8BA1\u5212\u3002\u6BCF\u9879\u5FC5\u987B\u63D0\u4F9B groupId\u3001title\
|
|
13405
|
+
description: "smartGroup \u7684\u4E8C\u6B21\u5206\u7EC4\u8BA1\u5212\u3002\u6BCF\u9879\u5FC5\u987B\u63D0\u4F9B groupId\u3001title\u3001requestIds\u3002",
|
|
13015
13406
|
items: {
|
|
13016
13407
|
type: "object",
|
|
13017
13408
|
additionalProperties: false,
|
|
13018
13409
|
properties: {
|
|
13019
13410
|
groupId: { type: "string" },
|
|
13020
13411
|
title: { type: "string" },
|
|
13021
|
-
requestIds: { type: "array", minItems: 1, items: { type: "string" } }
|
|
13022
|
-
seq: { type: "array", minItems: 1, items: { type: "integer", minimum: 1 } }
|
|
13412
|
+
requestIds: { type: "array", minItems: 1, items: { type: "string" } }
|
|
13023
13413
|
},
|
|
13024
|
-
required: ["groupId", "title"]
|
|
13025
|
-
oneOf: [{ required: ["requestIds"] }, { required: ["seq"] }]
|
|
13414
|
+
required: ["groupId", "title", "requestIds"]
|
|
13026
13415
|
}
|
|
13027
13416
|
},
|
|
13028
13417
|
aiSummaries: {
|
|
@@ -15600,6 +15989,13 @@ export {
|
|
|
15600
15989
|
asObject,
|
|
15601
15990
|
assertNoForbiddenKeys,
|
|
15602
15991
|
compactStdoutPaths,
|
|
15992
|
+
USER_INTENT_RULE_FILE,
|
|
15993
|
+
emptyRuleFile,
|
|
15994
|
+
validateRuleFile,
|
|
15995
|
+
loadRuleFile,
|
|
15996
|
+
aigroupUserDir,
|
|
15997
|
+
loadRules,
|
|
15998
|
+
resetActiveRules,
|
|
15603
15999
|
workflowOperationDefinitions,
|
|
15604
16000
|
getWorkflowOperation,
|
|
15605
16001
|
hasWorkflowOperation
|