weaver-work-cli 0.1.28 → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/archive-U766FTFH.js +2537 -0
- package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
- package/dist/chunks/asset-TCR7VDEV.js +2109 -0
- package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
- package/dist/chunks/blog-EVZWGDVM.js +2157 -0
- package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
- package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
- package/dist/chunks/chunk-2DUV44UX.js +15606 -0
- package/dist/chunks/chunk-324YPTC2.js +1607 -0
- package/dist/chunks/chunk-65QMVWHS.js +231 -0
- package/dist/chunks/chunk-6V7ZLF34.js +387 -0
- package/dist/chunks/chunk-AC7KJWC5.js +358 -0
- package/dist/chunks/chunk-AJ62BGAW.js +29 -0
- package/dist/chunks/chunk-BUSC6UAE.js +43 -0
- package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
- package/dist/chunks/chunk-D4LTJSJD.js +477 -0
- package/dist/chunks/chunk-EG6ZU444.js +654 -0
- package/dist/chunks/chunk-EZALDOQH.js +383 -0
- package/dist/chunks/chunk-FMPJJYYI.js +106 -0
- package/dist/chunks/chunk-G2JSIUWF.js +769 -0
- package/dist/chunks/chunk-GCG2NMWR.js +703 -0
- package/dist/chunks/chunk-GPMFD4RD.js +75 -0
- package/dist/chunks/chunk-H3WDBYJW.js +508 -0
- package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
- package/dist/chunks/chunk-J7RJTZSV.js +5556 -0
- package/dist/chunks/chunk-LUSPKZKY.js +53 -0
- package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
- package/dist/chunks/chunk-NOODWMCL.js +584 -0
- package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
- package/dist/chunks/chunk-P26ZWSKU.js +73 -0
- package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
- package/dist/chunks/chunk-R2IJAK7T.js +464 -0
- package/dist/chunks/chunk-R7O5PUWO.js +205 -0
- package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
- package/dist/chunks/chunk-VZTXRG6X.js +403 -0
- package/dist/chunks/chunk-WHD4XMRP.js +161 -0
- package/dist/chunks/chunk-YLCYX7LE.js +371 -0
- package/dist/chunks/chunk-ZEDWSH32.js +68 -0
- package/dist/chunks/continuation-2CKSBLA6.js +11 -0
- package/dist/chunks/continuation-HZIZRZBX.js +13 -0
- package/dist/chunks/continuation-NLECEJPX.js +11 -0
- package/dist/chunks/ebuilder-form-NJ4YK6CC.js +2276 -0
- package/dist/chunks/ehr-MMYN36VA.js +5241 -0
- package/dist/chunks/employee-SAK2QYXX.js +11 -0
- package/dist/chunks/esb-HIWHOU7Q.js +141 -0
- package/dist/chunks/fna-KBACQTA5.js +1444 -0
- package/dist/chunks/host-3OHS5QUX.js +21 -0
- package/dist/chunks/host-IG6KEH5Q.js +19 -0
- package/dist/chunks/host-KQL5N4HO.js +23 -0
- package/dist/chunks/host-LLSZQCWR.js +17 -0
- package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
- package/dist/chunks/im-RN2UKAEU.js +252 -0
- package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
- package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
- package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
- package/dist/chunks/mail-LNQLTF6L.js +2695 -0
- package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
- package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
- package/dist/chunks/okr-TMWTIU2K.js +2482 -0
- package/dist/chunks/plan-A2FSFA7T.js +2025 -0
- package/dist/chunks/project-T26QLBQF.js +1361 -0
- package/dist/chunks/registry-2VLUAESA.js +14 -0
- package/dist/chunks/registry-JCFEYXOE.js +18 -0
- package/dist/chunks/registry-NYPYMZXG.js +16 -0
- package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
- package/dist/chunks/registry-ZJMJVWFA.js +19 -0
- package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
- package/dist/chunks/schedule-5L2PM4M6.js +24 -0
- package/dist/chunks/state-Y2XBP6YE.js +15 -0
- package/dist/chunks/workflow-TR6PG2SL.js +245 -0
- package/dist/cmd/argv.js +45 -0
- package/dist/cmd/docs/index.js +3 -3
- package/dist/cmd/lazy-dispatch.js +20 -0
- package/dist/cmd/root.js +2 -4
- package/dist/cmd/setup/index.js +2 -2
- package/dist/cmd/skills/index.js +2 -2
- package/dist/core/package-paths.js +47 -0
- package/dist/index.js +163 -7
- package/dist/internal/e10/auth/xiaoe.js +3 -3
- package/dist/internal/e10/request-runtime.js +18 -62
- package/dist/internal/skills/detector.js +2 -2
- package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
- package/dist/shortcuts/contract/host.js +91 -35
- package/dist/shortcuts/contract/index.js +213 -0
- package/dist/shortcuts/contract/manifest.js +928 -0
- package/dist/shortcuts/contract/ooxml/docx.js +295 -0
- package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
- package/dist/shortcuts/contract/ooxml/zip.js +158 -0
- package/dist/shortcuts/contract/operations/assistant.js +1156 -0
- package/dist/shortcuts/contract/operations/clause-library.js +522 -0
- package/dist/shortcuts/contract/operations/compare.js +193 -0
- package/dist/shortcuts/contract/operations/credit-page.js +34 -0
- package/dist/shortcuts/contract/operations/flow.js +98 -0
- package/dist/shortcuts/contract/operations/page.js +66 -0
- package/dist/shortcuts/contract/operations/performance.js +733 -0
- package/dist/shortcuts/contract/operations/quote.js +557 -0
- package/dist/shortcuts/contract/operations/recommend.js +78 -0
- package/dist/shortcuts/contract/operations/registry.js +18 -0
- package/dist/shortcuts/contract/operations/review.js +83 -0
- package/dist/shortcuts/contract/operations/shared.js +37 -0
- package/dist/shortcuts/contract/operations/upload.js +108 -0
- package/dist/shortcuts/contract/operations/write.js +3 -2
- package/dist/shortcuts/index.js +140 -40
- package/dist/shortcuts/invoice/host.js +2 -1
- package/dist/shortcuts/invoice/manifest.js +36 -12
- package/dist/shortcuts/invoice/operations/issuing-qys.js +132 -36
- package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
- package/dist/shortcuts/invoice/operations/reim.js +81 -5
- package/dist/shortcuts/invoice/operations/shared.js +12 -5
- package/dist/shortcuts/meeting/host.js +45 -3
- package/dist/shortcuts/meeting/invitation/docx.js +442 -0
- package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
- package/dist/shortcuts/meeting/operations/attachment.js +442 -0
- package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
- package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
- package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
- package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
- package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
- package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
- package/dist/shortcuts/meeting/operations/invitation.js +458 -0
- package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
- package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
- package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
- package/dist/shortcuts/meeting/operations/receipts.js +1 -1
- package/dist/shortcuts/meeting/operations/registry.js +18 -0
- package/dist/shortcuts/meeting/operations/summary.js +276 -0
- package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
- package/dist/shortcuts/meeting/operations.js +42 -1
- package/dist/shortcuts/meeting/qr/encoder.js +427 -0
- package/dist/shortcuts/meeting/qr/render.js +103 -0
- package/dist/shortcuts/workflow/index.js +3 -0
- package/dist/shortcuts/workflow/operations/form.js +17 -5
- package/dist/shortcuts/workflow/operations/read.js +13 -6
- package/dist/shortcuts/workflow/operations/registry.js +2 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +331 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +133 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +326 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +113 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +259 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoListRows.js +64 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoOutputPlanner.js +28 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.aggregate.js +70 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +267 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +392 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +165 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +448 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +348 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +222 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +66 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +502 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +540 -0
- package/docs/_catalog.md +1 -0
- package/docs/contract.md +39 -4
- package/docs/invoice.md +7 -7
- package/docs/todo-smart-convert/README.md +171 -0
- package/docs/todo-smart-convert/data-contract.md +236 -0
- package/docs/todo-smart-convert/mock/ai-todo-query-target.json +209 -0
- package/docs/todo-smart-convert/subgroup-rules.md +245 -0
- package/package.json +3 -2
- package/scripts/bundle.mjs +63 -0
- package/scripts/package-skill.mjs +1 -1
- package/skill-template/business-info.json +25 -4
- package/skill-template/domains/jinchengda.md +16 -3
- package/skill-template/domains/yepiaotong.md +3 -3
- package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
- package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
- package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
- package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
- package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
- package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
- package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
- package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
- package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
- package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
- package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
- package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
- package/skills/weaver-e10-meeting/SKILL.md +493 -17
- package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
- package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
- package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-workflow/SKILL.md +23 -1
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +282 -0
- package/skills/weaver-e10-workflow/scripts/todo-summary.cjs +695 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +15 -11
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +10 -7
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +41 -14
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +54 -26
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +8 -2
- package/templates/meeting/invitation.docx +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { meetingConflictError } from '../../errors.js';
|
|
1
|
+
import { meetingConflictError, meetingValidationError } from '../../errors.js';
|
|
2
2
|
import { meetingSuccess, SCHEMA_DATETIME_MINUTE, SCHEMA_ID } from '../types.js';
|
|
3
3
|
import { assertDateTimeMinute, toIdCsv } from '../shared.js';
|
|
4
4
|
import { EB_BASE, ebBusinessSuccess, extractEbRows, queryBody } from './factory.js';
|
|
@@ -77,13 +77,20 @@ async function listAllEbRows(env, interfacePk, baseQuery, operation) {
|
|
|
77
77
|
return { rows, requests };
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
|
-
* 读取应用设置(query_meeting_baseset
|
|
80
|
+
* 读取应用设置(query_meeting_baseset):
|
|
81
81
|
* 同时取「冲突策略」与「建会路径开关」,一次请求供两处使用。
|
|
82
|
+
*
|
|
83
|
+
* 口径:正常情况下该表只有**一条有效记录**(`data_status=1`)。
|
|
84
|
+
* 但接口返回里可能混入历史/无效记录,且顺序不保证 —— 直接"取第一条"有机会读到失效配置,
|
|
85
|
+
* 表现为"同一个请求时而放行、时而被打回"。因此这里先按 `data_status` 过滤,再按 `update_time`
|
|
86
|
+
* 取最新一条,并把条数带回(多条时上层会提示以哪条为准)。
|
|
82
87
|
*/
|
|
83
88
|
export async function fetchEbAppSettings(env, operation) {
|
|
84
89
|
try {
|
|
85
|
-
const rows = await requestEbList(env, 'query_meeting_baseset', { pageNo: 1, pageSize:
|
|
86
|
-
const
|
|
90
|
+
const rows = await requestEbList(env, 'query_meeting_baseset', { pageNo: 1, pageSize: 20 }, operation);
|
|
91
|
+
const valid = rows.filter((row) => String(row.data_status ?? '1') === '1');
|
|
92
|
+
const ordered = [...valid].sort((left, right) => (String(right.update_time ?? '').localeCompare(String(left.update_time ?? ''))));
|
|
93
|
+
const base = ordered[0] ?? {};
|
|
87
94
|
return {
|
|
88
95
|
roomChk: String(base.room_conflict_chk ?? ''),
|
|
89
96
|
roomAction: String(base.room_conflict ?? ''),
|
|
@@ -93,6 +100,9 @@ export async function fetchEbAppSettings(env, operation) {
|
|
|
93
100
|
openMtApprove: String(base.open_mt_approve ?? ''),
|
|
94
101
|
mtNewWf: String(base.mt_new_wf ?? ''),
|
|
95
102
|
mtRepeatNewWf: String(base.mt_repeat_new_wf ?? ''),
|
|
103
|
+
settingsRows: valid.length,
|
|
104
|
+
settingsId: String(base.id ?? ''),
|
|
105
|
+
settingsUpdatedAt: String(base.update_time ?? ''),
|
|
96
106
|
};
|
|
97
107
|
}
|
|
98
108
|
catch (error) {
|
|
@@ -105,6 +115,7 @@ export async function fetchEbAppSettings(env, operation) {
|
|
|
105
115
|
openMtApprove: '',
|
|
106
116
|
mtNewWf: '',
|
|
107
117
|
mtRepeatNewWf: '',
|
|
118
|
+
settingsRows: 0,
|
|
108
119
|
error: errorText(error),
|
|
109
120
|
};
|
|
110
121
|
}
|
|
@@ -138,7 +149,9 @@ export function assertEbCreatePathAllowed(settings) {
|
|
|
138
149
|
throw meetingConflictError('conflict_rejected', `应用设置不允许直接建会:${blocked.join(';')}。该应用的会议必须经流程创建`
|
|
139
150
|
+ `(新建会议工作流 mt_new_wf=${settings.mtNewWf || '未配置'},周期会议工作流 mt_repeat_new_wf=${settings.mtRepeatNewWf || '未配置'})——`
|
|
140
151
|
+ 'CLI 不直接建会、也不代替流程建会(否则会产生流程之外、request_id 为空的会议,且与流程/ESB 自动建会重复)。'
|
|
141
|
-
+ '
|
|
152
|
+
+ '这属于应用管控,CLI 不会绕过 —— 但也不用停手:改走 **meeting.eb.meeting.create.flow**'
|
|
153
|
+
+ '(prepare→apply)即可,它会按 mt_new_wf 载入建会流程表单、提交审批,并在会议生成后自动出邀请函。'
|
|
154
|
+
+ '如需直连建会,请管理员先在会议应用设置中关闭该开关。', {
|
|
142
155
|
onlyFlowCreate: settings.onlyFlowCreate,
|
|
143
156
|
openMtApprove: settings.openMtApprove,
|
|
144
157
|
mtNewWf: settings.mtNewWf,
|
|
@@ -330,7 +343,7 @@ export async function runEbConflictCheck(input, env, operation, options = {}) {
|
|
|
330
343
|
* 连冲突检测都不必做(结论已定局);读应用设置失败同样拒绝。
|
|
331
344
|
* 2. 冲突检测仅在拿到起止时间、且传了 address / hrm_members 时才发请求(无目标即无冲突)。
|
|
332
345
|
*/
|
|
333
|
-
export const ebMeetingWritePreflight = async ({ endpoint, payload, args, env }) => {
|
|
346
|
+
export const ebMeetingWritePreflight = async ({ endpoint, payload, args, env, extras }) => {
|
|
334
347
|
const isCreate = endpoint.interfacePk === 'create_meeting';
|
|
335
348
|
const isChange = endpoint.interfacePk === 'change_meeting';
|
|
336
349
|
if (!isCreate && !isChange)
|
|
@@ -344,12 +357,20 @@ export const ebMeetingWritePreflight = async ({ endpoint, payload, args, env })
|
|
|
344
357
|
const hrmMembers = typeof main.hrm_members === 'string' && main.hrm_members ? main.hrm_members : undefined;
|
|
345
358
|
// 建会必读应用设置(闸门);变更只在确有冲突检测目标时才读(避免多一次请求)。
|
|
346
359
|
const settings = isCreate || address || hrmMembers ? await fetchEbAppSettings(env, operation) : undefined;
|
|
347
|
-
|
|
360
|
+
const preflightWarnings = [];
|
|
361
|
+
if (settings && isCreate) {
|
|
348
362
|
assertEbCreatePathAllowed(settings);
|
|
363
|
+
if ((settings.settingsRows ?? 0) > 1) {
|
|
364
|
+
// 多条设置时只按最新一条判断,但必须告诉用户:另一份设置里的开关不生效
|
|
365
|
+
preflightWarnings.push(`会议应用设置存在 ${settings.settingsRows} 条记录,本次按最新一条(id=${settings.settingsId ?? '未知'},`
|
|
366
|
+
+ `更新于 ${settings.settingsUpdatedAt || '未知'})判断建会路径与冲突策略;`
|
|
367
|
+
+ '如需以另一条为准,请先在系统页面清理重复的设置记录。');
|
|
368
|
+
}
|
|
369
|
+
}
|
|
349
370
|
if (!begin || !end)
|
|
350
|
-
return
|
|
371
|
+
return preflightWarnings;
|
|
351
372
|
if (!address && !hrmMembers)
|
|
352
|
-
return
|
|
373
|
+
return preflightWarnings;
|
|
353
374
|
const outcome = await runEbConflictCheck({
|
|
354
375
|
beginDatetime: begin,
|
|
355
376
|
endDatetime: end,
|
|
@@ -358,7 +379,53 @@ export const ebMeetingWritePreflight = async ({ endpoint, payload, args, env })
|
|
|
358
379
|
...(typeof main.org_members === 'string' && main.org_members ? { orgMembers: main.org_members } : {}),
|
|
359
380
|
...(typeof args.id === 'string' || typeof args.id === 'number' ? { excludeMtId: String(args.id) } : {}),
|
|
360
381
|
}, env, operation, settings ? { settings } : {});
|
|
361
|
-
|
|
382
|
+
const extraWarnings = [];
|
|
383
|
+
// 冲突了不能只说"撞了"——直接算出「所有人共同空闲」的候选时段,让用户能选
|
|
384
|
+
// (2026-10-28 用户反馈:冲突提示有了,但没有给出可选的日期/时段)。
|
|
385
|
+
if (outcome.member && outcome.member.conflicts.length > 0) {
|
|
386
|
+
extras.memberConflicts = outcome.member.conflicts;
|
|
387
|
+
if (begin && end && hrmMembers) {
|
|
388
|
+
try {
|
|
389
|
+
const durationMinutes = Math.max(15, Math.round((Date.parse(end.replace(' ', 'T')) - Date.parse(begin.replace(' ', 'T'))) / 60000) || 60);
|
|
390
|
+
// 用户口径(2026-10-28):**约的是哪天就只推荐哪天**,不跨天乱推;
|
|
391
|
+
// 并且同时核对「会议回执」与「日程(ESB)」,不能只看会议。
|
|
392
|
+
const day = begin.slice(0, 10);
|
|
393
|
+
const free = await findCommonFreeSlots(env, {
|
|
394
|
+
rangeStart: `${day} 00:00`,
|
|
395
|
+
rangeEnd: `${day} 23:59`,
|
|
396
|
+
durationMinutes,
|
|
397
|
+
members: hrmMembers.split(/[,;,;\s]+/).map((item) => item.trim()).filter((item) => item !== ''),
|
|
398
|
+
...(typeof args.id === 'string' || typeof args.id === 'number' ? { excludeMtId: String(args.id) } : {}),
|
|
399
|
+
maxSlots: 3,
|
|
400
|
+
maxDays: 1,
|
|
401
|
+
includeSchedule: true,
|
|
402
|
+
});
|
|
403
|
+
if (free.slots.length > 0) {
|
|
404
|
+
extras.suggestedSlots = free.slots;
|
|
405
|
+
extras.slotOptions = free.slots.map((slot, index) => ({
|
|
406
|
+
key: `T${index + 1}`,
|
|
407
|
+
// 选项里必须写清"为什么推荐这个时段",否则用户看到的只是两个时间点(2026-10-28 用户反馈)
|
|
408
|
+
label: `${slot.begin.slice(11)}~${slot.end.slice(11)}(${day}) · 全部参会人空闲`,
|
|
409
|
+
value: { begin: slot.begin, end: slot.end },
|
|
410
|
+
reason: '该时段所有参会人都没有会议与日程占用',
|
|
411
|
+
}));
|
|
412
|
+
extraWarnings.push(`当天(${day})推荐改期到:${free.slots.map((slot, index) => `[T${index + 1}] ${slot.begin.slice(11)}~${slot.end.slice(11)}`).join(';')}`
|
|
413
|
+
+ '(已同时核对会议回执与日程)——请用选项方式让用户挑一个。');
|
|
414
|
+
}
|
|
415
|
+
else if (free.blockingSummary) {
|
|
416
|
+
extraWarnings.push(free.blockingSummary);
|
|
417
|
+
extras.dayBlocked = { day, summary: free.blockingSummary };
|
|
418
|
+
}
|
|
419
|
+
extras.scheduleItems = free.scheduleItems;
|
|
420
|
+
extras.busyByMember = free.busyByMember;
|
|
421
|
+
extras.availabilityCost = free.cost;
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
extraWarnings.push(`共同空闲时段计算失败(${String(error?.message ?? error).slice(0, 80)}),请手动换时间`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return [...preflightWarnings, ...outcome.warnings, ...extraWarnings];
|
|
362
429
|
};
|
|
363
430
|
/** 只查不建:会议室冲突检测 operation。 */
|
|
364
431
|
const ebConflictRoom = {
|
|
@@ -458,4 +525,298 @@ const ebConflictMember = {
|
|
|
458
525
|
}, outcome.warnings.length > 0 ? { warnings: outcome.warnings } : {});
|
|
459
526
|
},
|
|
460
527
|
};
|
|
461
|
-
|
|
528
|
+
function formatNowForRange() {
|
|
529
|
+
const now = new Date();
|
|
530
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
531
|
+
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`;
|
|
532
|
+
}
|
|
533
|
+
function formatMinuteLocal(date) {
|
|
534
|
+
return formatMinute(date);
|
|
535
|
+
}
|
|
536
|
+
function parseMinute(text) {
|
|
537
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})/.exec(String(text ?? '').trim());
|
|
538
|
+
if (!match)
|
|
539
|
+
return null;
|
|
540
|
+
return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]), Number(match[4]), Number(match[5]), 0, 0);
|
|
541
|
+
}
|
|
542
|
+
function formatMinute(date) {
|
|
543
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
544
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
545
|
+
}
|
|
546
|
+
/** 员工 id → 姓名(批量;失败返回空表,summary 里退回 id)。 */
|
|
547
|
+
async function resolveMemberNames(env, ids) {
|
|
548
|
+
const map = new Map();
|
|
549
|
+
const unique = [...new Set(ids.filter((id) => id !== ''))];
|
|
550
|
+
if (unique.length === 0)
|
|
551
|
+
return map;
|
|
552
|
+
try {
|
|
553
|
+
const { hrmEmployeeOperations } = await import('../../../hrm/operations/employee.js');
|
|
554
|
+
const batch = hrmEmployeeOperations.find((operation) => operation.name === 'hrm.employee.batch');
|
|
555
|
+
if (!batch)
|
|
556
|
+
return map;
|
|
557
|
+
const result = await batch.handler({ ids: unique }, env);
|
|
558
|
+
const rows = (result?.data?.rows ?? result?.data?.userList ?? []);
|
|
559
|
+
for (const row of rows) {
|
|
560
|
+
const id = String(row.id ?? '').trim();
|
|
561
|
+
const name = String(row.name ?? '').trim();
|
|
562
|
+
if (id && name)
|
|
563
|
+
map.set(id, name);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
catch {
|
|
567
|
+
// 名字拿不到就用 id,不影响判定
|
|
568
|
+
}
|
|
569
|
+
return map;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* 扫「所有人共同空闲」的时段。
|
|
573
|
+
*
|
|
574
|
+
* 两个维度都要算(2026-10-28 用户要求):
|
|
575
|
+
* ① **会议回执**:一次拉候选 + 按 mt_id 批量回执;
|
|
576
|
+
* ② **日程(ESB)**:一次调用覆盖该范围全部符合条件日程(会议日程类型由服务端过滤),
|
|
577
|
+
* 只返回提示语时也能解析出「时间 + 日程名 + 人」,因为查询范围限定在同一天,HH:mm 可安全补上日期。
|
|
578
|
+
*
|
|
579
|
+
* 默认**只看 rangeStart 当天**(用户口径:约的是哪天就推荐哪天)。
|
|
580
|
+
*/
|
|
581
|
+
export async function findCommonFreeSlots(env, input) {
|
|
582
|
+
const members = input.members.map((item) => String(item).trim()).filter((item) => item !== '');
|
|
583
|
+
const wanted = new Set(members);
|
|
584
|
+
const duration = Math.max(15, Math.min(24 * 60, Math.round(input.durationMinutes || 60)));
|
|
585
|
+
const step = Math.max(15, Math.min(120, Math.round(input.stepMinutes ?? 30)));
|
|
586
|
+
const workStart = Math.max(0, Math.min(23, input.workStartHour ?? 9));
|
|
587
|
+
const workEnd = Math.max(workStart + 1, Math.min(24, input.workEndHour ?? 18));
|
|
588
|
+
const maxSlots = Math.max(1, Math.min(20, input.maxSlots ?? 3));
|
|
589
|
+
const maxDays = Math.max(1, Math.min(14, input.maxDays ?? 1));
|
|
590
|
+
const includeSchedule = input.includeSchedule !== false;
|
|
591
|
+
const rangeStart = parseMinute(input.rangeStart);
|
|
592
|
+
const rangeEnd = parseMinute(input.rangeEnd);
|
|
593
|
+
const cost = { candidateCalls: 0, receiptCalls: 0, candidates: 0, busyIntervals: 0, scheduleCalls: 0 };
|
|
594
|
+
const empty = { slots: [], idle: false, cost, scheduleItems: [], busyByMember: [] };
|
|
595
|
+
if (!rangeStart || !rangeEnd)
|
|
596
|
+
return empty;
|
|
597
|
+
const detail = new Map();
|
|
598
|
+
const pushBusy = (memberId, item) => {
|
|
599
|
+
const list = detail.get(memberId) ?? [];
|
|
600
|
+
list.push(item);
|
|
601
|
+
detail.set(memberId, list);
|
|
602
|
+
cost.busyIntervals += 1;
|
|
603
|
+
};
|
|
604
|
+
// ① 会议维度
|
|
605
|
+
const candidate = await listAllEbRows(env, 'query_mtDetail_list', { begindatetime: input.rangeStart, enddatetime: input.rangeEnd, mt_status: ACTIVE_MT_STATUS }, 'meeting.eb.conflict.availability');
|
|
606
|
+
cost.candidateCalls += candidate.requests;
|
|
607
|
+
const meetings = candidate.rows
|
|
608
|
+
.map((row) => ({
|
|
609
|
+
id: String(row.id ?? ''),
|
|
610
|
+
name: String(row.mt_name ?? row.name ?? row.mt_name ?? ''),
|
|
611
|
+
begin: parseMinute(String(row.begin_datetime ?? '')),
|
|
612
|
+
end: parseMinute(String(row.end_datetime ?? '')),
|
|
613
|
+
}))
|
|
614
|
+
.filter((item) => item.id && item.id !== (input.excludeMtId ?? '') && item.begin && item.end);
|
|
615
|
+
cost.candidates = meetings.length;
|
|
616
|
+
const byId = new Map(meetings.map((item) => [item.id, item]));
|
|
617
|
+
for (let index = 0; index < meetings.length; index += MT_ID_BATCH) {
|
|
618
|
+
const csv = meetings.slice(index, index + MT_ID_BATCH).map((item) => item.id).join(',');
|
|
619
|
+
const page = await listAllEbRows(env, 'query_meeting_receipt_list', { mt_id: csv }, 'meeting.eb.conflict.availability');
|
|
620
|
+
cost.receiptCalls += page.requests;
|
|
621
|
+
for (const row of page.rows) {
|
|
622
|
+
const meetingId = String(row.mt_id ?? '');
|
|
623
|
+
const memberId = String(row.member_id ?? '');
|
|
624
|
+
const memberType = String(row.member_type ?? '');
|
|
625
|
+
if (!meetingId || !memberId)
|
|
626
|
+
continue;
|
|
627
|
+
if (memberType && memberType !== '1')
|
|
628
|
+
continue;
|
|
629
|
+
if (!wanted.has(memberId))
|
|
630
|
+
continue;
|
|
631
|
+
const meeting = byId.get(meetingId);
|
|
632
|
+
if (!meeting?.begin || !meeting?.end)
|
|
633
|
+
continue;
|
|
634
|
+
pushBusy(memberId, {
|
|
635
|
+
source: 'meeting',
|
|
636
|
+
title: meeting.name || '会议',
|
|
637
|
+
begin: formatMinute(meeting.begin),
|
|
638
|
+
end: formatMinute(meeting.end),
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
// ② 日程维度(ESB 一次调完整段范围)
|
|
643
|
+
const scheduleItems = [];
|
|
644
|
+
if (includeSchedule) {
|
|
645
|
+
try {
|
|
646
|
+
const { runScheduleConflictFlow, parseScheduleConflictMessage, resolveMemberIdsByName } = await import('./schedule.js');
|
|
647
|
+
const dayBegin = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate(), 0, 0, 0, 0);
|
|
648
|
+
const dayEnd = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate(), 23, 59, 0, 0);
|
|
649
|
+
const flow = await runScheduleConflictFlow(env, {
|
|
650
|
+
startDate: formatMinute(dayBegin),
|
|
651
|
+
endDate: formatMinute(dayEnd),
|
|
652
|
+
memberIds: members,
|
|
653
|
+
});
|
|
654
|
+
cost.scheduleCalls += 1;
|
|
655
|
+
const rawItems = [];
|
|
656
|
+
for (const row of flow.rows) {
|
|
657
|
+
const main = row?.mainTable ?? row ?? {};
|
|
658
|
+
const type = main.agn_type;
|
|
659
|
+
const typeId = Array.isArray(type) ? String(type[0]?.id ?? '') : String(type?.id ?? type ?? '');
|
|
660
|
+
void typeId;
|
|
661
|
+
rawItems.push({
|
|
662
|
+
title: String(main.agn_name ?? main.name ?? '').trim() || '日程',
|
|
663
|
+
begin: String(main.start_time ?? '').trim(),
|
|
664
|
+
end: String(main.end_time ?? '').trim(),
|
|
665
|
+
names: String(main.participants ?? '')
|
|
666
|
+
.split(/[,;,;\s]+/)
|
|
667
|
+
.map((item) => item.trim())
|
|
668
|
+
.filter((item) => item !== ''),
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
if (rawItems.length === 0) {
|
|
672
|
+
for (const item of parseScheduleConflictMessage(flow.message)) {
|
|
673
|
+
rawItems.push({ title: item.title, begin: item.startTime, end: item.endTime, names: item.memberNames });
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
const idsByName = await resolveMemberIdsByName(env, rawItems.flatMap((item) => item.names));
|
|
677
|
+
const datePrefix = `${rangeStart.getFullYear()}-${String(rangeStart.getMonth() + 1).padStart(2, '0')}-${String(rangeStart.getDate()).padStart(2, '0')}`;
|
|
678
|
+
for (const item of rawItems) {
|
|
679
|
+
const beginText = item.begin.includes('-') ? item.begin : `${datePrefix} ${item.begin}`;
|
|
680
|
+
const endText = item.end.includes('-') ? item.end : `${datePrefix} ${item.end}`;
|
|
681
|
+
const beginDate = parseMinute(beginText);
|
|
682
|
+
const endDate = parseMinute(endText);
|
|
683
|
+
if (!beginDate || !endDate)
|
|
684
|
+
continue;
|
|
685
|
+
const memberIds = item.names.map((name) => idsByName.get(name) ?? '').filter((id) => id !== '');
|
|
686
|
+
scheduleItems.push({ title: item.title, begin: beginText, end: endText, members: memberIds.length > 0 ? memberIds : item.names });
|
|
687
|
+
for (const memberId of memberIds) {
|
|
688
|
+
if (!wanted.has(memberId))
|
|
689
|
+
continue;
|
|
690
|
+
pushBusy(memberId, { source: 'schedule', title: item.title, begin: beginText, end: endText });
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
catch {
|
|
695
|
+
// ESB 失败不阻断推荐:退化为只看会议回执,调用方从 scheduleItems 为空可看出未校验
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
const names = await resolveMemberNames(env, [...detail.keys()]);
|
|
699
|
+
const busyByMember = [...detail.entries()].map(([memberId, items]) => ({
|
|
700
|
+
memberId,
|
|
701
|
+
...(names.get(memberId) ? { memberName: names.get(memberId) } : {}),
|
|
702
|
+
items: items.sort((left, right) => left.begin.localeCompare(right.begin)),
|
|
703
|
+
}));
|
|
704
|
+
const overlaps = (slotStart, slotEnd) => {
|
|
705
|
+
for (const entry of busyByMember) {
|
|
706
|
+
for (const item of entry.items) {
|
|
707
|
+
const begin = parseMinute(item.begin);
|
|
708
|
+
const end = parseMinute(item.end);
|
|
709
|
+
if (!begin || !end)
|
|
710
|
+
continue;
|
|
711
|
+
if (slotStart < end && slotEnd > begin)
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return false;
|
|
716
|
+
};
|
|
717
|
+
const now = new Date();
|
|
718
|
+
const slots = [];
|
|
719
|
+
const dayCount = Math.min(maxDays, Math.ceil((rangeEnd.getTime() - rangeStart.getTime()) / 86_400_000) + 1);
|
|
720
|
+
for (let day = 0; day < dayCount && slots.length < maxSlots; day += 1) {
|
|
721
|
+
const dayStart = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + day, workStart, 0, 0, 0);
|
|
722
|
+
const dayLimit = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + day, workEnd, 0, 0, 0);
|
|
723
|
+
for (let cursor = new Date(dayStart); cursor.getTime() + duration * 60_000 <= dayLimit.getTime(); cursor = new Date(cursor.getTime() + step * 60_000)) {
|
|
724
|
+
const slotStart = new Date(cursor);
|
|
725
|
+
const slotEnd = new Date(cursor.getTime() + duration * 60_000);
|
|
726
|
+
if (slotStart.getTime() < now.getTime() + 5 * 60_000)
|
|
727
|
+
continue; // 过去的时间不算
|
|
728
|
+
if (slotStart < rangeStart || slotEnd > rangeEnd)
|
|
729
|
+
continue;
|
|
730
|
+
if (overlaps(slotStart, slotEnd))
|
|
731
|
+
continue;
|
|
732
|
+
slots.push({ begin: formatMinute(slotStart), end: formatMinute(slotEnd) });
|
|
733
|
+
if (slots.length >= maxSlots)
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
let blockingSummary;
|
|
738
|
+
if (slots.length === 0) {
|
|
739
|
+
const day = `${rangeStart.getFullYear()}-${String(rangeStart.getMonth() + 1).padStart(2, '0')}-${String(rangeStart.getDate()).padStart(2, '0')}`;
|
|
740
|
+
const perMember = busyByMember.map((entry) => {
|
|
741
|
+
const items = entry.items
|
|
742
|
+
.slice(0, 3)
|
|
743
|
+
.map((item) => `${item.source === 'meeting' ? '会议' : '日程'}《${item.title}》${item.begin.slice(11)}~${item.end.slice(11)}`)
|
|
744
|
+
.join('、');
|
|
745
|
+
const more = entry.items.length > 3 ? ` 等 ${entry.items.length} 项` : '';
|
|
746
|
+
return `${entry.memberName ?? entry.memberId}:${items}${more}`;
|
|
747
|
+
});
|
|
748
|
+
blockingSummary = perMember.length > 0
|
|
749
|
+
? `${day} 当天 ${workStart}:00-${workEnd}:00 内没有所有人都空闲的 ${duration} 分钟时段(已同时核对会议回执与日程)——${perMember.join(';')}`
|
|
750
|
+
: `${day} 当天 ${workStart}:00-${workEnd}:00 内没有找到符合条件的 ${duration} 分钟时段,建议换个日期或缩短时长`;
|
|
751
|
+
}
|
|
752
|
+
return {
|
|
753
|
+
slots,
|
|
754
|
+
idle: cost.busyIntervals === 0,
|
|
755
|
+
cost,
|
|
756
|
+
scheduleItems,
|
|
757
|
+
busyByMember,
|
|
758
|
+
...(blockingSummary ? { blockingSummary } : {}),
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
/** 只查不建:给「某几个人、要开多久」找共同空闲时段。 */
|
|
762
|
+
const ebConflictAvailability = {
|
|
763
|
+
name: 'meeting.eb.conflict.availability',
|
|
764
|
+
resource: 'eb',
|
|
765
|
+
method: 'meeting.eb.conflict.availability',
|
|
766
|
+
action: 'meeting.eb.conflict.availability',
|
|
767
|
+
summary: '参会人共同空闲时段推荐(会议维度):一次拉候选会议 + 批量回执,内存切 30 分钟 slot,给出所有人都空闲的时间段(默认最多 3 个,往后 7 天)',
|
|
768
|
+
capability: 'eb.conflict',
|
|
769
|
+
risk: 'read',
|
|
770
|
+
inputSchema: {
|
|
771
|
+
type: 'object',
|
|
772
|
+
additionalProperties: false,
|
|
773
|
+
properties: {
|
|
774
|
+
rangeStart: { ...SCHEMA_DATETIME_MINUTE, description: '搜索范围开始(必填,yyyy-MM-dd HH:mm)' },
|
|
775
|
+
rangeEnd: { ...SCHEMA_DATETIME_MINUTE, description: '搜索范围结束(必填,yyyy-MM-dd HH:mm)' },
|
|
776
|
+
durationMinutes: { type: 'number', description: '会议时长(分钟,默认 60)' },
|
|
777
|
+
hrmMembers: { type: 'string', description: '参会人 id,逗号分隔(必填)' },
|
|
778
|
+
mtId: { ...SCHEMA_ID, description: '变更会议时排除自身' },
|
|
779
|
+
workStartHour: { type: 'number', description: '工作时段起始小时(默认 9)' },
|
|
780
|
+
workEndHour: { type: 'number', description: '工作时段结束小时(默认 18)' },
|
|
781
|
+
stepMinutes: { type: 'number', description: '候选步长(分钟,默认 30)' },
|
|
782
|
+
maxSlots: { type: 'number', description: '返回几个时段(默认 3,最多 20)' },
|
|
783
|
+
maxDays: { type: 'number', description: '往后找几天(默认 1 = 只找当天,符合"约的是哪天就推荐哪天")' },
|
|
784
|
+
includeSchedule: { type: 'boolean', description: '是否同时核对日程(ESB),默认 true' },
|
|
785
|
+
},
|
|
786
|
+
required: ['rangeStart', 'rangeEnd', 'hrmMembers'],
|
|
787
|
+
},
|
|
788
|
+
handler: async (args, env) => {
|
|
789
|
+
const members = String(args.hrmMembers ?? '')
|
|
790
|
+
.split(/[,;,;\s]+/)
|
|
791
|
+
.map((item) => item.trim())
|
|
792
|
+
.filter((item) => item !== '');
|
|
793
|
+
if (members.length === 0) {
|
|
794
|
+
throw meetingValidationError('members_required', 'hrmMembers 不能为空');
|
|
795
|
+
}
|
|
796
|
+
const result = await findCommonFreeSlots(env, {
|
|
797
|
+
rangeStart: String(args.rangeStart),
|
|
798
|
+
rangeEnd: String(args.rangeEnd),
|
|
799
|
+
durationMinutes: Number(args.durationMinutes ?? 60),
|
|
800
|
+
members,
|
|
801
|
+
...(args.mtId ? { excludeMtId: String(args.mtId) } : {}),
|
|
802
|
+
...(args.workStartHour !== undefined ? { workStartHour: Number(args.workStartHour) } : {}),
|
|
803
|
+
...(args.workEndHour !== undefined ? { workEndHour: Number(args.workEndHour) } : {}),
|
|
804
|
+
...(args.stepMinutes !== undefined ? { stepMinutes: Number(args.stepMinutes) } : {}),
|
|
805
|
+
...(args.maxSlots !== undefined ? { maxSlots: Number(args.maxSlots) } : {}),
|
|
806
|
+
...(args.maxDays !== undefined ? { maxDays: Number(args.maxDays) } : {}),
|
|
807
|
+
...(args.includeSchedule !== undefined ? { includeSchedule: args.includeSchedule !== false } : {}),
|
|
808
|
+
});
|
|
809
|
+
return meetingSuccess('meeting.eb.conflict.availability', {
|
|
810
|
+
slots: result.slots,
|
|
811
|
+
idle: result.idle,
|
|
812
|
+
members,
|
|
813
|
+
scheduleItems: result.scheduleItems,
|
|
814
|
+
busyByMember: result.busyByMember,
|
|
815
|
+
...(result.blockingSummary ? { blockingSummary: result.blockingSummary } : {}),
|
|
816
|
+
cost: result.cost,
|
|
817
|
+
}, result.slots.length === 0
|
|
818
|
+
? { warnings: [result.blockingSummary ?? '范围内没有找到所有人都空闲的时段,建议换个日期或缩短时长'] }
|
|
819
|
+
: {});
|
|
820
|
+
},
|
|
821
|
+
};
|
|
822
|
+
export const meetingEbConflictOperations = [ebConflictRoom, ebConflictMember, ebConflictAvailability];
|