weaver-work-cli 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/internal/e10/auth/commands.js +4 -1
  2. package/dist/internal/e10/request-runtime.js +3 -2
  3. package/dist/shortcuts/index.js +4 -0
  4. package/dist/shortcuts/meeting/continuation.js +70 -0
  5. package/dist/shortcuts/meeting/errors.js +63 -0
  6. package/dist/shortcuts/meeting/host.js +167 -0
  7. package/dist/shortcuts/meeting/index.js +123 -0
  8. package/dist/shortcuts/meeting/manifest.js +64 -0
  9. package/dist/shortcuts/meeting/operations/catalogs.js +58 -0
  10. package/dist/shortcuts/meeting/operations/change.js +242 -0
  11. package/dist/shortcuts/meeting/operations/conflicts.js +142 -0
  12. package/dist/shortcuts/meeting/operations/create.js +349 -0
  13. package/dist/shortcuts/meeting/operations/env.js +191 -0
  14. package/dist/shortcuts/meeting/operations/lifecycle.js +139 -0
  15. package/dist/shortcuts/meeting/operations/meetings.js +73 -0
  16. package/dist/shortcuts/meeting/operations/receipts.js +195 -0
  17. package/dist/shortcuts/meeting/operations/registry.js +47 -0
  18. package/dist/shortcuts/meeting/operations/rooms.js +132 -0
  19. package/dist/shortcuts/meeting/operations/shared.js +112 -0
  20. package/dist/shortcuts/meeting/operations/signs.js +41 -0
  21. package/dist/shortcuts/meeting/operations/types.js +25 -0
  22. package/dist/shortcuts/meeting/operations.js +19 -0
  23. package/dist/shortcuts/yimiaoban/continuation.js +70 -0
  24. package/dist/shortcuts/yimiaoban/errors.js +61 -0
  25. package/dist/shortcuts/yimiaoban/host.js +469 -0
  26. package/dist/shortcuts/yimiaoban/index.js +271 -0
  27. package/dist/shortcuts/yimiaoban/manifest.js +28 -0
  28. package/dist/shortcuts/yimiaoban/operations/file-user.js +288 -0
  29. package/dist/shortcuts/yimiaoban/operations/group-read.js +477 -0
  30. package/dist/shortcuts/yimiaoban/operations/group-write.js +591 -0
  31. package/dist/shortcuts/yimiaoban/operations/msg-parse.js +429 -0
  32. package/dist/shortcuts/yimiaoban/operations/msg-sync.js +519 -0
  33. package/dist/shortcuts/yimiaoban/operations/msg-write.js +593 -0
  34. package/dist/shortcuts/yimiaoban/operations/person.js +102 -0
  35. package/dist/shortcuts/yimiaoban/operations/registry.js +38 -0
  36. package/dist/shortcuts/yimiaoban/operations/session.js +437 -0
  37. package/dist/shortcuts/yimiaoban/operations/shared.js +236 -0
  38. package/dist/shortcuts/yimiaoban/operations/types.js +27 -0
  39. package/dist/shortcuts/yimiaoban/operations/write-util.js +78 -0
  40. package/dist/shortcuts/yimiaoban/operations.js +8 -0
  41. package/docs/_catalog.md +6 -0
  42. package/docs/meeting.md +48 -0
  43. package/docs/yimiaoban.md +86 -0
  44. package/package.json +1 -1
  45. package/skill-template/business-info.json +4 -1
  46. package/skill-template/domains/meeting.md +3 -0
  47. package/skill-template/domains/yimiaoban.md +21 -0
  48. package/skills/weaver-e10-calendar/SKILL.md +1 -0
  49. package/skills/weaver-e10-esb/SKILL.md +1 -0
  50. package/skills/weaver-e10-esb/references/source-manifest.json +3 -3
  51. package/skills/weaver-e10-hrm/SKILL.md +1 -0
  52. package/skills/weaver-e10-jiuchuanhui/SKILL.md +1 -0
  53. package/skills/weaver-e10-jucailin/SKILL.md +1 -0
  54. package/skills/weaver-e10-mail/SKILL.md +1 -0
  55. package/skills/weaver-e10-meeting/SKILL.md +106 -0
  56. package/skills/weaver-e10-meeting/product.json +8 -0
  57. package/skills/weaver-e10-meeting/references/meeting-change.md +67 -0
  58. package/skills/weaver-e10-meeting/references/meeting-create.md +52 -0
  59. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +57 -0
  60. package/skills/weaver-e10-meeting/references/meeting-queries.md +61 -0
  61. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +48 -0
  62. package/skills/weaver-e10-meeting/references/meeting-update.md +7 -0
  63. package/skills/weaver-e10-meeting/references/source-manifest.json +50 -0
  64. package/skills/weaver-e10-plan/SKILL.md +1 -0
  65. package/skills/weaver-e10-plan/references/source-manifest.json +3 -3
  66. package/skills/weaver-e10-qiyecheng/SKILL.md +1 -0
  67. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +3 -3
  68. package/skills/weaver-e10-shared/SKILL.md +4 -0
  69. package/skills/weaver-e10-skill-maker/SKILL.md +1 -0
  70. package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +1 -1
  71. package/skills/weaver-e10-wenshuding/SKILL.md +1 -0
  72. package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
  73. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +5 -5
  74. package/skills/weaver-e10-yimiaoban/SKILL.md +104 -0
  75. package/skills/weaver-e10-yimiaoban/product.json +8 -0
  76. package/skills/weaver-e10-yimiaoban/references/ding-write.md +68 -0
  77. package/skills/weaver-e10-yimiaoban/references/error-codes.md +85 -0
  78. package/skills/weaver-e10-yimiaoban/references/field-resolution.md +46 -0
  79. package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +54 -0
  80. package/skills/weaver-e10-yimiaoban/references/group-read.md +55 -0
  81. package/skills/weaver-e10-yimiaoban/references/group-write.md +72 -0
  82. package/skills/weaver-e10-yimiaoban/references/msg-read.md +59 -0
  83. package/skills/weaver-e10-yimiaoban/references/msg-write.md +64 -0
  84. package/skills/weaver-e10-yimiaoban/references/person.md +44 -0
  85. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +61 -0
  86. package/skills/weaver-e10-yimiaoban/references/session-sysmsg.md +47 -0
  87. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +485 -0
  88. package/skills/weaver-e10-ziguanjia/SKILL.md +1 -0
@@ -0,0 +1,242 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { meetingConfirmationError, meetingPartialError, meetingValidationError } from '../errors.js';
3
+ import { meetingSuccess, SCHEMA_DATETIME_MINUTE, SCHEMA_ID } from './types.js';
4
+ import { assertDateTimeMinute, extractRows, toIdCsv, toIdString } from './shared.js';
5
+ const CONTINUATION_TTL_SECONDS = 600;
6
+ const LIST_PATH = '/api/meeting/search/getMeetingList';
7
+ function fingerprint(value) {
8
+ return createHash('sha256').update(JSON.stringify(value ?? null)).digest('hex').slice(0, 32);
9
+ }
10
+ function requireConfirm(args, action) {
11
+ if (args.confirm !== true) {
12
+ throw meetingConfirmationError(action, { hint: '重新调用时传入 confirm=true 与 prepare 返回的 continuation' });
13
+ }
14
+ }
15
+ async function verifyLease(args, action, env) {
16
+ const lease = await env.continuation.verify(args.continuation, action);
17
+ const session = await env.host.getSession();
18
+ if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
19
+ throw meetingValidationError('context_mismatch', '确认上下文已变化(租户或登录账号不同),请重新执行 prepare');
20
+ }
21
+ return lease;
22
+ }
23
+ function isNetworkError(error) {
24
+ return error instanceof Error && error.type === 'network';
25
+ }
26
+ /** 可变更的主表字段(与 MeetingDetailBean 对齐)。 */
27
+ const CHANGABLE_FIELDS = [
28
+ 'name',
29
+ 'beginDatetime',
30
+ 'endDatetime',
31
+ 'address',
32
+ 'customizeAddress',
33
+ 'mtType',
34
+ 'hrmMembers',
35
+ 'orgMembers',
36
+ 'otherMembers',
37
+ 'crmMembers',
38
+ 'totalMember',
39
+ 'caller',
40
+ 'contacter',
41
+ ];
42
+ const DATE_FIELDS = new Set(['beginDatetime', 'endDatetime']);
43
+ const ID_FIELDS = new Set(['address', 'mtType', 'caller', 'contacter']);
44
+ const CSV_FIELDS = new Set(['hrmMembers', 'orgMembers', 'crmMembers']);
45
+ /** 归一化变更输入:只提交调用方显式给出的字段。 */
46
+ export function normalizeChangeInput(args) {
47
+ const id = toIdString(args.id, 'id');
48
+ const body = { id };
49
+ for (const field of CHANGABLE_FIELDS) {
50
+ const value = args[field];
51
+ if (value === undefined)
52
+ continue;
53
+ if (DATE_FIELDS.has(field)) {
54
+ body[field] = assertDateTimeMinute(value, field);
55
+ }
56
+ else if (ID_FIELDS.has(field)) {
57
+ body[field] = toIdString(value, field);
58
+ }
59
+ else if (CSV_FIELDS.has(field)) {
60
+ const csv = toIdCsv(value, field);
61
+ if (csv !== undefined)
62
+ body[field] = csv;
63
+ }
64
+ else if (field === 'name') {
65
+ const name = typeof value === 'string' ? value.trim() : '';
66
+ if (!name)
67
+ throw meetingValidationError('name_invalid', 'name 不能为空字符串');
68
+ body[field] = name;
69
+ }
70
+ else {
71
+ body[field] = value;
72
+ }
73
+ }
74
+ if (Object.keys(body).length <= 1) {
75
+ throw meetingValidationError('no_changes', '未提供任何要修改的字段:请至少提供 name / beginDatetime / endDatetime / address 等其中之一');
76
+ }
77
+ return body;
78
+ }
79
+ /**
80
+ * 按会议当前状态确定 operateType。源码依据(MeetingBaseServiceUtils.getShowButtons):
81
+ * - mtStatus==0(草稿)→ 按钮 do_edit(编辑)→ operateMeetingByType(operateType=UPDATE)
82
+ * - mtStatus 正常(2/8/9,未结束)→ 按钮 do_change → operateMeetingByType(operateType=CHANGE)
83
+ * 实测列表字段:草稿会议 mtStatus="草稿"/status="0",正常会议 mtStatus="未开始"/status="notStart"。
84
+ */
85
+ function isDraftRow(row) {
86
+ const text = `${row?.mtStatus ?? ''}`;
87
+ if (text.includes('草稿'))
88
+ return true;
89
+ return row?.status !== undefined && String(row?.status) === '0';
90
+ }
91
+ async function resolveOperateType(id, env, operation) {
92
+ const pageSize = 50;
93
+ for (let current = 1; current <= 10; current++) {
94
+ const response = await env.host.request({
95
+ method: 'POST',
96
+ path: LIST_PATH,
97
+ operation,
98
+ body: { current, pageSize },
99
+ });
100
+ const { rows, total } = extractRows(response);
101
+ const row = rows.find((item) => String(item?.id ?? '') === id);
102
+ if (row) {
103
+ return {
104
+ operateType: isDraftRow(row) ? 'UPDATE' : 'CHANGE',
105
+ mtStatus: `${row?.mtStatus ?? ''}`,
106
+ name: `${row?.name ?? ''}`,
107
+ };
108
+ }
109
+ if (rows.length === 0 || (total !== undefined && current * pageSize >= total))
110
+ break;
111
+ }
112
+ throw meetingValidationError('meeting_not_found', `未在会议列表中定位到会议 ${id}:请确认 id 正确且当前账号可见(草稿走 UPDATE、正常会议走 CHANGE,二者都要求会议在列表中可见)`);
113
+ }
114
+ const meetingChangePrepare = {
115
+ name: 'meeting.change.prepare',
116
+ resource: 'meeting',
117
+ method: 'change.prepare',
118
+ action: 'meeting.change.prepare',
119
+ summary: '准备会议变更(改期/改地点/改参会人):按会议状态自动选择 operateType(草稿=UPDATE、正常=CHANGE),生成确认预览,不写入',
120
+ capability: 'lifecycle',
121
+ risk: 'read-before-write',
122
+ requiresConfirmation: true,
123
+ inputSchema: {
124
+ type: 'object',
125
+ additionalProperties: false,
126
+ properties: {
127
+ id: { ...SCHEMA_ID, description: '会议 id(必填)' },
128
+ name: { type: 'string', minLength: 1, description: '会议名称' },
129
+ beginDatetime: { ...SCHEMA_DATETIME_MINUTE, description: '开始时间' },
130
+ endDatetime: { ...SCHEMA_DATETIME_MINUTE, description: '结束时间' },
131
+ address: { ...SCHEMA_ID, description: '会议室 id' },
132
+ customizeAddress: { type: 'string', description: '自定义地点' },
133
+ mtType: { ...SCHEMA_ID, description: '会议类型 id' },
134
+ hrmMembers: { type: 'string', description: '参会人员 id,逗号分隔字符串' },
135
+ orgMembers: { type: 'string', description: '参会部门 id,逗号分隔字符串' },
136
+ otherMembers: { type: 'string', description: '其他参会人员(文本)' },
137
+ crmMembers: { type: 'string', description: '参会客户 id,逗号分隔字符串' },
138
+ totalMember: { type: 'integer', description: '参会人数' },
139
+ caller: { ...SCHEMA_ID, description: '召集人 id' },
140
+ contacter: { ...SCHEMA_ID, description: '联系人 id' },
141
+ },
142
+ required: ['id'],
143
+ },
144
+ handler: async (args, env) => {
145
+ const body = normalizeChangeInput(args);
146
+ const id = String(body.id);
147
+ const { operateType, mtStatus, name } = await resolveOperateType(id, env, 'meeting.change.prepare');
148
+ const payload = { ...body, operateType };
149
+ const session = await env.host.getSession();
150
+ const token = await env.continuation.issue({
151
+ operation: 'meeting.change.apply',
152
+ baseUrl: session.baseUrl,
153
+ profile: session.profile,
154
+ userId: session.userId,
155
+ payload,
156
+ fingerprint: fingerprint(payload),
157
+ }, CONTINUATION_TTL_SECONDS * 1000);
158
+ return meetingSuccess('meeting.change.prepare', {
159
+ status: 'AWAITING_CONFIRMATION',
160
+ preview: {
161
+ id,
162
+ name,
163
+ currentStatus: mtStatus,
164
+ operateType,
165
+ operateTypeReason: operateType === 'UPDATE' ? '草稿会议走更新(UPDATE)' : '正常会议走变更(CHANGE)',
166
+ changedFields: Object.keys(body).filter((key) => key !== 'id'),
167
+ body: payload,
168
+ note: '本 operation 只提交上面列出的字段;权限由服务端按会议状态判定,若无权限会返回“您没有变更权限!”等原文提示,请原样转达用户。',
169
+ },
170
+ continuation: token,
171
+ expiresInSeconds: CONTINUATION_TTL_SECONDS,
172
+ });
173
+ },
174
+ };
175
+ const meetingChangeApply = {
176
+ name: 'meeting.change.apply',
177
+ resource: 'meeting',
178
+ method: 'change.apply',
179
+ action: 'meeting.change.apply',
180
+ summary: '提交会议变更(operateMeetingByType,草稿 UPDATE / 正常 CHANGE,body 传参);必须在用户明确确认后调用',
181
+ capability: 'lifecycle',
182
+ risk: 'high-risk-write',
183
+ requiresConfirmation: true,
184
+ inputSchema: {
185
+ type: 'object',
186
+ additionalProperties: false,
187
+ properties: {
188
+ confirm: { const: true },
189
+ continuation: { type: 'string', minLength: 1 },
190
+ id: SCHEMA_ID,
191
+ name: { type: 'string' },
192
+ beginDatetime: SCHEMA_DATETIME_MINUTE,
193
+ endDatetime: SCHEMA_DATETIME_MINUTE,
194
+ address: SCHEMA_ID,
195
+ customizeAddress: { type: 'string' },
196
+ mtType: SCHEMA_ID,
197
+ hrmMembers: { type: 'string' },
198
+ orgMembers: { type: 'string' },
199
+ otherMembers: { type: 'string' },
200
+ crmMembers: { type: 'string' },
201
+ totalMember: { type: 'integer' },
202
+ caller: SCHEMA_ID,
203
+ contacter: SCHEMA_ID,
204
+ },
205
+ required: ['confirm', 'continuation', 'id'],
206
+ },
207
+ handler: async (args, env) => {
208
+ requireConfirm(args, 'meeting.change.apply');
209
+ const lease = await verifyLease(args, 'meeting.change.apply', env);
210
+ const body = normalizeChangeInput(args);
211
+ const id = String(body.id);
212
+ const { operateType, mtStatus } = await resolveOperateType(id, env, 'meeting.change.apply');
213
+ const leaseOperateType = lease.payload?.operateType;
214
+ if (leaseOperateType && leaseOperateType !== operateType) {
215
+ throw meetingValidationError('target_changed', `会议状态已变化(prepare 时按 ${leaseOperateType}、当前按 ${operateType},当前状态:${mtStatus}),请重新执行 prepare 并向用户确认`);
216
+ }
217
+ const payload = { ...body, operateType };
218
+ if (lease.fingerprint !== fingerprint(payload)) {
219
+ throw meetingValidationError('target_changed', '变更内容与 prepare 时的快照不一致,请重新执行 prepare');
220
+ }
221
+ let response;
222
+ try {
223
+ response = await env.host.request({
224
+ method: 'POST',
225
+ path: '/api/meeting/detail/operateMeetingByType',
226
+ operation: 'meeting.change.apply',
227
+ body: payload,
228
+ });
229
+ }
230
+ catch (error) {
231
+ if (isNetworkError(error)) {
232
+ throw meetingPartialError('变更请求发送后连接中断,是否已生效不确定,禁止自动重试,请通过 meeting.list 或会议详情回查确认', { attempted: { id, operateType } }, { stage: 'change' });
233
+ }
234
+ throw error;
235
+ }
236
+ return meetingSuccess('meeting.change.apply', { status: 'COMPLETE', id, operateType, result: response });
237
+ },
238
+ };
239
+ export const meetingChangeOperations = [
240
+ meetingChangePrepare,
241
+ meetingChangeApply,
242
+ ];
@@ -0,0 +1,142 @@
1
+ import { meetingSuccess, SCHEMA_DATETIME_MINUTE, SCHEMA_ID } from './types.js';
2
+ import { assertDateTimeMinute, extractConflict, toIdCsv, toIdString } from './shared.js';
3
+ /**
4
+ * MeetingCheckBean 公共输入(标准版三个冲突接口共用)。
5
+ * 返回 verdict 归一化:ok(cansub=true 且无冲突描述)/ warn(cansub=true 但有冲突描述)
6
+ * / rejected(cansub=false)/ unknown(接口未返回 cansub,需人工复核)。
7
+ */
8
+ function conflictProperties() {
9
+ return {
10
+ beginDatetime: { ...SCHEMA_DATETIME_MINUTE, description: '开始时间(必填)' },
11
+ endDatetime: { ...SCHEMA_DATETIME_MINUTE, description: '结束时间(必填)' },
12
+ address: { ...SCHEMA_ID, description: '会议室 id(会议室冲突目标)' },
13
+ hrmids: { type: 'string', description: '参会人员 id,逗号分隔字符串' },
14
+ crmids: { type: 'string', description: '参会客户 id,逗号分隔字符串' },
15
+ mtId: { ...SCHEMA_ID, description: '会议 id(变更检测时排除自身)' },
16
+ caller: SCHEMA_ID,
17
+ contacter: SCHEMA_ID,
18
+ requestid: { type: 'string', description: '流程 id' },
19
+ totalmember: { type: 'integer', description: '应到人数' },
20
+ frequent: { type: 'integer', enum: [1, 2, 3, 4], description: '周期频率:1=天 2=周 3=月 4=年' },
21
+ repeatRuleEx: { type: 'string', description: '周期规则(RRULE)' },
22
+ serviceItems: { type: 'string', description: '会议服务' },
23
+ creator: SCHEMA_ID,
24
+ };
25
+ }
26
+ function verdictOf(cansub, message) {
27
+ if (cansub === false)
28
+ return 'rejected';
29
+ if (cansub === true)
30
+ return message ? 'warn' : 'ok';
31
+ return message ? 'warn' : 'unknown';
32
+ }
33
+ async function runConflictCheck(operation, path, args, host) {
34
+ const body = {
35
+ beginDatetime: assertDateTimeMinute(args.beginDatetime, 'beginDatetime'),
36
+ endDatetime: assertDateTimeMinute(args.endDatetime, 'endDatetime'),
37
+ };
38
+ if (args.address !== undefined)
39
+ body.address = toIdString(args.address, 'address');
40
+ if (args.hrmids !== undefined)
41
+ body.hrmids = toIdCsv(args.hrmids, 'hrmids');
42
+ if (args.crmids !== undefined)
43
+ body.crmids = toIdCsv(args.crmids, 'crmids');
44
+ if (args.mtId !== undefined)
45
+ body.mtId = toIdString(args.mtId, 'mtId');
46
+ if (args.caller !== undefined)
47
+ body.caller = toIdString(args.caller, 'caller');
48
+ if (args.contacter !== undefined)
49
+ body.contacter = toIdString(args.contacter, 'contacter');
50
+ if (args.requestid !== undefined)
51
+ body.requestid = args.requestid;
52
+ if (args.totalmember !== undefined)
53
+ body.totalmember = args.totalmember;
54
+ if (args.frequent !== undefined)
55
+ body.frequent = args.frequent;
56
+ if (args.repeatRuleEx !== undefined)
57
+ body.repeatRuleEx = args.repeatRuleEx;
58
+ if (args.serviceItems !== undefined)
59
+ body.serviceItems = args.serviceItems;
60
+ if (args.creator !== undefined)
61
+ body.creator = toIdString(args.creator, 'creator');
62
+ const response = await host.request({ method: 'POST', path, operation, body });
63
+ const conflict = extractConflict(response);
64
+ return { ...conflict, verdict: verdictOf(conflict.cansub, conflict.message), raw: response };
65
+ }
66
+ const meetingConflictRoom = {
67
+ name: 'meeting.conflict.room',
68
+ resource: 'conflict',
69
+ method: 'conflict.room',
70
+ action: 'meeting.conflict.room',
71
+ summary: '会议室冲突检测(meetingChkRoom):verdict=rejected 禁止提交 / warn 仅提醒 / ok 无冲突',
72
+ capability: 'conflict',
73
+ risk: 'read',
74
+ inputSchema: {
75
+ type: 'object',
76
+ additionalProperties: false,
77
+ properties: conflictProperties(),
78
+ required: ['beginDatetime', 'endDatetime', 'address'],
79
+ },
80
+ handler: async (args, { host }) => {
81
+ const result = await runConflictCheck('meeting.conflict.room', '/api/meeting/detail/meetingChkRoom', args, host);
82
+ return meetingSuccess('meeting.conflict.room', {
83
+ verdict: result.verdict,
84
+ cansub: result.cansub,
85
+ message: result.message,
86
+ raw: result.raw,
87
+ });
88
+ },
89
+ };
90
+ const meetingConflictMember = {
91
+ name: 'meeting.conflict.member',
92
+ resource: 'conflict',
93
+ method: 'conflict.member',
94
+ action: 'meeting.conflict.member',
95
+ summary: '参会人员冲突检测(meetingChkMember):verdict=rejected 禁止提交 / warn 仅提醒 / ok 无冲突',
96
+ capability: 'conflict',
97
+ risk: 'read',
98
+ inputSchema: {
99
+ type: 'object',
100
+ additionalProperties: false,
101
+ properties: conflictProperties(),
102
+ required: ['beginDatetime', 'endDatetime', 'hrmids'],
103
+ },
104
+ handler: async (args, { host }) => {
105
+ const result = await runConflictCheck('meeting.conflict.member', '/api/meeting/detail/meetingChkMember', args, host);
106
+ return meetingSuccess('meeting.conflict.member', {
107
+ verdict: result.verdict,
108
+ cansub: result.cansub,
109
+ message: result.message,
110
+ raw: result.raw,
111
+ });
112
+ },
113
+ };
114
+ const meetingConflictRoomAttribute = {
115
+ name: 'meeting.conflict.roomAttribute',
116
+ resource: 'conflict',
117
+ method: 'conflict.roomAttribute',
118
+ action: 'meeting.conflict.roomAttribute',
119
+ summary: '会议室属性冲突检测(meetingChkRoomAttribute):比对需求属性与会议室实际属性',
120
+ capability: 'conflict',
121
+ risk: 'read',
122
+ inputSchema: {
123
+ type: 'object',
124
+ additionalProperties: false,
125
+ properties: conflictProperties(),
126
+ required: ['beginDatetime', 'endDatetime', 'address'],
127
+ },
128
+ handler: async (args, { host }) => {
129
+ const result = await runConflictCheck('meeting.conflict.roomAttribute', '/api/meeting/detail/meetingChkRoomAttribute', args, host);
130
+ return meetingSuccess('meeting.conflict.roomAttribute', {
131
+ verdict: result.verdict,
132
+ cansub: result.cansub,
133
+ message: result.message,
134
+ raw: result.raw,
135
+ });
136
+ },
137
+ };
138
+ export const meetingConflictOperations = [
139
+ meetingConflictRoom,
140
+ meetingConflictMember,
141
+ meetingConflictRoomAttribute,
142
+ ];