weaver-work-cli 0.1.8 → 0.1.20
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 +11 -11
- package/dist/cmd/action.js +76 -0
- package/dist/cmd/index.js +2 -0
- package/dist/cmd/refs/index.js +103 -0
- package/dist/cmd/register.js +31 -0
- package/dist/cmd/root.js +1 -0
- package/dist/cmd/setup/index.js +25 -5
- package/dist/cmd/skills/index.js +37 -5
- package/dist/core/connector.js +54 -0
- package/dist/core/context.js +2 -1
- package/dist/core/input.js +48 -0
- package/dist/core/output.js +298 -3
- package/dist/core/refs.js +432 -0
- package/dist/core/state.js +26 -0
- package/dist/internal/e10/auth/commands.js +2 -2
- package/dist/internal/e10/auth/session.js +14 -0
- package/dist/internal/e10/auth/xiaoe.js +116 -51
- package/dist/internal/e10/request-runtime.js +5 -0
- package/dist/internal/skills/install.js +148 -28
- package/dist/internal/skills/reader.js +12 -9
- package/dist/shortcuts/blog/continuation.js +74 -0
- package/dist/shortcuts/blog/errors.js +60 -0
- package/dist/shortcuts/blog/host.js +175 -0
- package/dist/shortcuts/blog/index.js +324 -0
- package/dist/shortcuts/blog/manifest.js +415 -0
- package/dist/shortcuts/blog/operations/comment.js +125 -0
- package/dist/shortcuts/blog/operations/comments.js +31 -0
- package/dist/shortcuts/blog/operations/edit.js +131 -0
- package/dist/shortcuts/blog/operations/export.js +46 -0
- package/dist/shortcuts/blog/operations/like.js +80 -0
- package/dist/shortcuts/blog/operations/publish.js +157 -0
- package/dist/shortcuts/blog/operations/query-user.js +58 -0
- package/dist/shortcuts/blog/operations/query.js +96 -0
- package/dist/shortcuts/blog/operations/registry.js +54 -0
- package/dist/shortcuts/blog/operations/remind.js +176 -0
- package/dist/shortcuts/blog/operations/shared.js +330 -0
- package/dist/shortcuts/blog/operations/types.js +16 -0
- package/dist/shortcuts/blog/operations.js +9 -0
- package/dist/shortcuts/caizhilian/continuation.js +70 -0
- package/dist/shortcuts/caizhilian/errors.js +53 -0
- package/dist/shortcuts/caizhilian/host.js +190 -0
- package/dist/shortcuts/caizhilian/index.js +186 -0
- package/dist/shortcuts/caizhilian/manifest.js +42 -0
- package/dist/shortcuts/caizhilian/operations/api.js +801 -0
- package/dist/shortcuts/caizhilian/operations/confirm.js +75 -0
- package/dist/shortcuts/caizhilian/operations/files.js +306 -0
- package/dist/shortcuts/caizhilian/operations/form.js +170 -0
- package/dist/shortcuts/caizhilian/operations/handlers/collab.js +611 -0
- package/dist/shortcuts/caizhilian/operations/handlers/document.js +890 -0
- package/dist/shortcuts/caizhilian/operations/handlers/file-collection.js +346 -0
- package/dist/shortcuts/caizhilian/operations/handlers/file-upload.js +192 -0
- package/dist/shortcuts/caizhilian/operations/handlers/fileops.js +570 -0
- package/dist/shortcuts/caizhilian/operations/handlers/folder.js +969 -0
- package/dist/shortcuts/caizhilian/operations/handlers/search.js +318 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-attach.js +294 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-backup.js +423 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-encrypt.js +238 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-storage.js +364 -0
- package/dist/shortcuts/caizhilian/operations/handlers/system.js +106 -0
- package/dist/shortcuts/caizhilian/operations/registry.js +151 -0
- package/dist/shortcuts/caizhilian/operations/shared.js +408 -0
- package/dist/shortcuts/caizhilian/operations/specs.js +623 -0
- package/dist/shortcuts/caizhilian/operations/types.js +57 -0
- package/dist/shortcuts/caizhilian/operations.js +21 -0
- package/dist/shortcuts/contract/continuation.js +70 -0
- package/dist/shortcuts/contract/errors.js +62 -0
- package/dist/shortcuts/contract/host.js +205 -0
- package/dist/shortcuts/contract/index.js +318 -0
- package/dist/shortcuts/contract/manifest.js +596 -0
- package/dist/shortcuts/contract/operations/clause-reference.js +78 -0
- package/dist/shortcuts/contract/operations/form-info.js +371 -0
- package/dist/shortcuts/contract/operations/read.js +118 -0
- package/dist/shortcuts/contract/operations/registry.js +43 -0
- package/dist/shortcuts/contract/operations/request.js +300 -0
- package/dist/shortcuts/contract/operations/shared.js +133 -0
- package/dist/shortcuts/contract/operations/subject.js +157 -0
- package/dist/shortcuts/contract/operations/template.js +81 -0
- package/dist/shortcuts/contract/operations/types.js +7 -0
- package/dist/shortcuts/contract/operations/workflow.js +52 -0
- package/dist/shortcuts/contract/operations/write.js +131 -0
- package/dist/shortcuts/contract/operations.js +8 -0
- package/dist/shortcuts/hrm/index.js +83 -2
- package/dist/shortcuts/hrm/operations/employee.js +160 -30
- package/dist/shortcuts/hrm/operations/org.js +17 -3
- package/dist/shortcuts/hrm/operations/position.js +18 -2
- package/dist/shortcuts/index.js +5 -1
- package/dist/shortcuts/invoice/index.js +74 -36
- package/dist/shortcuts/invoice/manifest.js +674 -4
- package/dist/shortcuts/invoice/markdown.js +172 -0
- package/dist/shortcuts/invoice/operations/add.js +3 -3
- package/dist/shortcuts/invoice/operations/delete.js +2 -2
- package/dist/shortcuts/invoice/operations/get.js +10 -2
- package/dist/shortcuts/invoice/operations/import.js +2 -2
- package/dist/shortcuts/invoice/operations/registry.js +8 -1
- package/dist/shortcuts/invoice/operations/reim-auto.js +719 -0
- package/dist/shortcuts/invoice/operations/reim.js +85 -2
- package/dist/shortcuts/invoice/operations/shared.js +75 -8
- package/dist/shortcuts/invoice/operations/update.js +2 -2
- package/dist/shortcuts/invoice/operations/upload-and-validate.js +93 -0
- package/dist/shortcuts/invoice/operations/validate-preview.js +2 -1
- package/dist/shortcuts/invoice/projection.js +328 -0
- package/dist/shortcuts/meeting/host.js +18 -1
- package/dist/shortcuts/meeting/manifest.js +30 -18
- package/dist/shortcuts/meeting/operations/eb/catalog.js +390 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +389 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +389 -0
- package/dist/shortcuts/meeting/operations/eb/index.js +22 -0
- package/dist/shortcuts/meeting/operations/env.js +8 -1
- package/dist/shortcuts/meeting/operations/registry.js +2 -0
- package/dist/shortcuts/meeting/operations/signs.js +216 -2
- package/dist/shortcuts/workflow/endpoints.js +2 -1
- package/dist/shortcuts/workflow/errors.js +8 -2
- package/dist/shortcuts/workflow/host.js +6 -3
- package/dist/shortcuts/workflow/operations/form.js +931 -589
- package/dist/shortcuts/workflow/operations/read.js +128 -205
- package/dist/shortcuts/workflow/operations/shared.js +21 -0
- package/dist/shortcuts/workflow/operations/write.js +750 -52
- package/dist/shortcuts/workflow/operations.js +36 -10
- package/docs/_catalog.md +6 -0
- package/docs/agent-invoice.md +5 -1
- package/docs/agent-io-channel-design.md +468 -0
- package/docs/agent-skill-install.md +9 -4
- package/docs/blog.md +123 -0
- package/docs/caizhilian.md +304 -0
- package/docs/contract.md +91 -0
- package/docs/e10-auth.md +2 -2
- package/docs/hrm.md +19 -9
- package/docs/invoice.md +5 -1
- package/docs/meeting.md +1 -1
- package/docs/operation-manual.md +15 -3
- package/docs/skill-review-2026-09-19.md +2 -2
- package/package.json +2 -2
- package/scripts/package-skill.mjs +32 -20
- package/skill-template/business-info.json +113 -14
- package/skill-template/domains/blog.md +24 -0
- package/skill-template/domains/caizhilian.md +22 -0
- package/skill-template/domains/jinchengda.md +23 -0
- package/skill-template/domains/meeting.md +1 -1
- package/skill-template/domains/workflow.md +1 -1
- package/skill-template/skill-template.md +1 -1
- package/skills/weaver-e10-blog/SKILL.md +111 -0
- package/skills/weaver-e10-blog/references/blog-comment.md +51 -0
- package/skills/weaver-e10-blog/references/blog-comments.md +39 -0
- package/skills/weaver-e10-blog/references/blog-default-permission.md +38 -0
- package/skills/weaver-e10-blog/references/blog-disabled-capabilities.md +11 -0
- package/skills/weaver-e10-blog/references/blog-edit.md +51 -0
- package/skills/weaver-e10-blog/references/blog-export.md +42 -0
- package/skills/weaver-e10-blog/references/blog-like.md +50 -0
- package/skills/weaver-e10-blog/references/blog-publish.md +52 -0
- package/skills/weaver-e10-blog/references/blog-query-user.md +45 -0
- package/skills/weaver-e10-blog/references/blog-query.md +49 -0
- package/skills/weaver-e10-blog/references/blog-remind.md +51 -0
- package/skills/weaver-e10-blog/references/blog-resolve-users.md +38 -0
- package/skills/weaver-e10-blog/references/source-manifest.json +1540 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +216 -0
- package/skills/weaver-e10-caizhilian/references/agent-entry.md +106 -0
- package/skills/weaver-e10-caizhilian/references/collaboration.md +112 -0
- package/skills/weaver-e10-caizhilian/references/document.md +111 -0
- package/skills/weaver-e10-caizhilian/references/file-collection.md +136 -0
- package/skills/weaver-e10-caizhilian/references/file-upload.md +309 -0
- package/skills/weaver-e10-caizhilian/references/files.md +120 -0
- package/skills/weaver-e10-caizhilian/references/folder.md +118 -0
- package/skills/weaver-e10-caizhilian/references/org-browser.md +104 -0
- package/skills/weaver-e10-caizhilian/references/setting-attach.md +410 -0
- package/skills/weaver-e10-caizhilian/references/setting-backup.md +372 -0
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +399 -0
- package/skills/weaver-e10-caizhilian/references/setting-storage.md +603 -0
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +5079 -0
- package/skills/weaver-e10-caizhilian/references/withheld.md +93 -0
- package/skills/weaver-e10-caizhilian/references/write-protocol.md +120 -0
- package/skills/weaver-e10-calendar/SKILL.md +4 -3
- package/skills/weaver-e10-ebuilder-form/SKILL.md +4 -9
- package/skills/weaver-e10-ebuilder-form/references/context-routing.md +0 -9
- package/skills/weaver-e10-ebuilder-form/references/custom-api.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/fields-browser.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/list-nlist.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/openapi-read.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +1 -5
- package/skills/weaver-e10-esb/SKILL.md +2 -2
- package/skills/weaver-e10-esb/references/source-manifest.json +9 -9
- package/skills/weaver-e10-hrm/SKILL.md +54 -6
- package/skills/weaver-e10-hrm/references/employee.md +89 -15
- package/skills/weaver-e10-hrm/references/org.md +7 -4
- package/skills/weaver-e10-hrm/references/position.md +14 -7
- package/skills/weaver-e10-hrm/references/source-manifest.json +1 -1
- package/skills/weaver-e10-jinchengda/SKILL.md +166 -0
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +82 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +69 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +78 -0
- package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +27 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-status.md +71 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +94 -0
- package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +89 -0
- package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +77 -0
- package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +66 -0
- package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +94 -0
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +259 -0
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +5 -11
- package/skills/weaver-e10-jucailin/SKILL.md +4 -3
- package/skills/weaver-e10-mail/SKILL.md +4 -11
- package/skills/weaver-e10-meeting/SKILL.md +66 -32
- package/skills/weaver-e10-meeting/references/meeting-change.md +5 -2
- package/skills/weaver-e10-meeting/references/meeting-create.md +2 -1
- package/skills/weaver-e10-meeting/references/meeting-eb.md +114 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +9 -8
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +35 -7
- package/skills/weaver-e10-meeting/references/meeting-update.md +1 -1
- package/skills/weaver-e10-okr/SKILL.md +6 -11
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-plan/SKILL.md +3 -3
- package/skills/weaver-e10-plan/references/plan-collect-and-compose.md +1 -1
- package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +1 -1
- package/skills/weaver-e10-plan/references/source-manifest.json +13 -13
- package/skills/weaver-e10-qiyecheng/SKILL.md +4 -10
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +9 -9
- package/skills/weaver-e10-shared/SKILL.md +36 -25
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +10 -31
- package/skills/weaver-e10-shared/references/json-output-contract.md +20 -11
- package/skills/weaver-e10-shijingran/SKILL.md +2 -1
- package/skills/weaver-e10-shijingran/references/source-manifest.json +9 -9
- package/skills/weaver-e10-skill-maker/SKILL.md +4 -10
- package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +5 -3
- package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +12 -27
- package/skills/weaver-e10-skill-maker/references/module-gap-audit-and-repair.md +17 -5
- package/skills/weaver-e10-skill-maker/references/source-update-detection.md +4 -27
- package/skills/weaver-e10-wenshuding/SKILL.md +5 -16
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +7 -7
- package/skills/weaver-e10-workflow/SKILL.md +32 -37
- package/skills/weaver-e10-workflow/references/source-manifest.json +39 -75
- package/skills/weaver-e10-workflow/references/workflow-batch.md +90 -29
- package/skills/weaver-e10-workflow/references/workflow-create.md +79 -109
- package/skills/weaver-e10-workflow/references/workflow-memory.md +19 -9
- package/skills/weaver-e10-workflow/references/workflow-operate.md +2 -2
- package/skills/weaver-e10-workflow/references/workflow-query.md +38 -20
- package/skills/weaver-e10-workflow/references/workflow-share.md +18 -2
- package/skills/weaver-e10-workflow/references/workflow-view.md +3 -4
- package/skills/weaver-e10-yepiaotong/SKILL.md +75 -39
- package/skills/weaver-e10-yepiaotong/references/invoice-detail.md +22 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +3 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-output-view.md +135 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +15 -3
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-summarize.py +217 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-upload-and-validate.md +88 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-validation-preview.md +7 -2
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +89 -9
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +1 -0
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +70 -49
- package/skills/weaver-e10-yepiaotong/references/reim-fast-path.md +119 -0
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +55 -36
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +4 -0
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +149 -0
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +125 -5
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +430 -63
- package/skills/weaver-e10-yimiaoban/SKILL.md +4 -12
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
- package/skills/weaver-e10-ziguanjia/SKILL.md +2 -1
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-agent-entry.md +3 -3
- package/tools/weaver-skill-detector-1.0.13/SKILL.md +9 -9
- package/tools/weaver-skill-detector-1.0.13/references/checklist.md +3 -3
- package/tools/weaver-skill-detector-1.0.13/scripts/__pycache__/validate_skill.cpython-313.pyc +0 -0
- package/tools/weaver-skill-detector-1.0.13/scripts/validate_skill.py +98 -91
- package/scripts/sync-connector-skills.mjs +0 -172
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
const DATE = '^\\d{4}-\\d{2}-\\d{2}$';
|
|
2
|
+
const POSITIVE_ID = { type: 'string', pattern: '^[1-9]\\d*$' };
|
|
3
|
+
const CONFIRM_SCHEMA = {
|
|
4
|
+
type: 'object',
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
properties: {
|
|
7
|
+
continuation: { type: 'string', minLength: 1, description: 'prepare 返回的确认令牌(HMAC 签发,10 分钟有效)' },
|
|
8
|
+
confirm: { const: true, description: '必须显式为 true,否则 CLI 拒绝写入' },
|
|
9
|
+
},
|
|
10
|
+
required: ['continuation', 'confirm'],
|
|
11
|
+
};
|
|
12
|
+
/** 本模块全部 operation 合约(WHAT):名称、风险等级、固定参数与输入 JSON Schema。 */
|
|
13
|
+
export const blogOperations = [
|
|
14
|
+
{
|
|
15
|
+
name: 'blog.query',
|
|
16
|
+
risk: 'read',
|
|
17
|
+
summary: '群体日报查询(直接/间接/全部下属、我关注的人),窗口裁剪在客户端完成',
|
|
18
|
+
fixed: { blogType: 'order', timezoneOffset: -8 },
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: 'object',
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
properties: {
|
|
23
|
+
user_type: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
enum: ['directSubordinate', 'indirectSubordinate', 'allSubordinate', 'myFollow'],
|
|
26
|
+
description: '人员范围:directSubordinate=直接下属,indirectSubordinate=间接下属,allSubordinate=全部下属,myFollow=我关注的人。查指定个人请改用 blog.query_user。',
|
|
27
|
+
},
|
|
28
|
+
start_date: { type: 'string', pattern: DATE, description: '窗口起始日期(客户端裁剪用)' },
|
|
29
|
+
end_date: { type: 'string', pattern: DATE, description: '窗口结束日期(含);区间按天计数,上限 62 天' },
|
|
30
|
+
keywords: { type: 'string', description: '按内容关键字服务端模糊过滤,可传空串' },
|
|
31
|
+
page_size: { type: 'integer', minimum: 1, maximum: 300, default: 300, description: '服务端单页返回行数(上限 300)。行数 ≈ 人数 × 天数,窗口大时保持默认 300 以尽量覆盖' },
|
|
32
|
+
page_no: { type: 'integer', minimum: 1, default: 1, description: '透传页码;服务端实测忽略 pageNo(返回同一批数据),调大不会拿到更多数据' },
|
|
33
|
+
},
|
|
34
|
+
required: ['user_type', 'start_date', 'end_date'],
|
|
35
|
+
},
|
|
36
|
+
inputExamples: [
|
|
37
|
+
{
|
|
38
|
+
name: '查我关注的人本周日报',
|
|
39
|
+
input: { user_type: 'myFollow', start_date: '2026-09-14', end_date: '2026-09-18' },
|
|
40
|
+
source: 'scripts/query-weaver-e10-blog.mjs(--userType myfollow 用法)',
|
|
41
|
+
sourceType: 'source-provided',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: '查直接下属日报',
|
|
45
|
+
input: { user_type: 'directSubordinate', start_date: '2026-09-01', end_date: '2026-09-30' },
|
|
46
|
+
source: 'SKILL.md 能力表(下属日报查询场景)',
|
|
47
|
+
sourceType: 'source-provided',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'blog.query_user',
|
|
53
|
+
risk: 'read',
|
|
54
|
+
summary: '单人日报逐日扫描(detailsByDate),区间上限 62 天;查指定个人的唯一可靠路径',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
additionalProperties: false,
|
|
58
|
+
properties: {
|
|
59
|
+
user_id: { ...POSITIVE_ID, description: '目标人员 userId;与 name 二选一,都缺省时查当前登录人的日报' },
|
|
60
|
+
name: { type: 'string', minLength: 1, description: '目标人员姓名,经 HRM 精确解析;与 user_id 二选一,同名多命中时报错并列出候选' },
|
|
61
|
+
date: { type: 'string', pattern: DATE, description: '起始日期 YYYY-MM-DD' },
|
|
62
|
+
end_date: { type: 'string', pattern: DATE, description: '结束日期(含),缺省时只查 date 当天;区间按天扫描,上限 62 天' },
|
|
63
|
+
},
|
|
64
|
+
required: ['date'],
|
|
65
|
+
},
|
|
66
|
+
inputExamples: [
|
|
67
|
+
{
|
|
68
|
+
name: '按姓名查某天日报',
|
|
69
|
+
input: { name: '章智涵', date: '2026-08-18' },
|
|
70
|
+
source: 'scripts/query-day.mjs 用法示例(node query-day.mjs 2026-08-18 --name 章智涵)',
|
|
71
|
+
sourceType: 'source-provided',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: '按 userId 查一段日报',
|
|
75
|
+
input: { user_id: '1077039731822690306', date: '2026-08-17', end_date: '2026-08-20' },
|
|
76
|
+
source: 'scripts/query-day.mjs 用法示例(--userId 1077039731822690306)',
|
|
77
|
+
sourceType: 'source-provided',
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'blog.resolve_users',
|
|
83
|
+
risk: 'read',
|
|
84
|
+
summary: 'HRM 按姓名精确解析 userId(取 id 字段,不是 userid)',
|
|
85
|
+
inputSchema: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
additionalProperties: false,
|
|
88
|
+
properties: {
|
|
89
|
+
name: { type: 'string', minLength: 1, description: '员工姓名(精确匹配)' },
|
|
90
|
+
},
|
|
91
|
+
required: ['name'],
|
|
92
|
+
},
|
|
93
|
+
inputExamples: [
|
|
94
|
+
{
|
|
95
|
+
name: '按姓名解析',
|
|
96
|
+
input: { name: '章智涵' },
|
|
97
|
+
source: 'scripts/query-weaver-e10-blog.mjs(HRM 解析姓名段)',
|
|
98
|
+
sourceType: 'source-provided',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'blog.comments',
|
|
104
|
+
risk: 'read',
|
|
105
|
+
summary: '查某条日报的评论列表(commentPage)',
|
|
106
|
+
fixed: { module: 'blog', foldCommentList: false },
|
|
107
|
+
inputSchema: {
|
|
108
|
+
type: 'object',
|
|
109
|
+
additionalProperties: false,
|
|
110
|
+
properties: {
|
|
111
|
+
blog_id: { ...POSITIVE_ID, description: '日报记录 id(detailsByDate 的 blog.id)' },
|
|
112
|
+
page_no: { type: 'integer', minimum: 1, maximum: 10_000, default: 1 },
|
|
113
|
+
page_size: { type: 'integer', minimum: 1, maximum: 100, default: 20 },
|
|
114
|
+
},
|
|
115
|
+
required: ['blog_id'],
|
|
116
|
+
},
|
|
117
|
+
inputExamples: [
|
|
118
|
+
{
|
|
119
|
+
name: '查某日报评论',
|
|
120
|
+
input: { blog_id: '1310837921662951425' },
|
|
121
|
+
source: 'scripts/query-comments.mjs(--blogId 入参)',
|
|
122
|
+
sourceType: 'source-provided',
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'blog.default_permission',
|
|
128
|
+
risk: 'read',
|
|
129
|
+
summary: '查某日期的默认共享对象,供发布时回填 permissionList',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
additionalProperties: false,
|
|
133
|
+
properties: {
|
|
134
|
+
date: { type: 'string', pattern: DATE, description: '日报归属日期,返回的 data.list 可直接作为发布时的共享对象' },
|
|
135
|
+
},
|
|
136
|
+
required: ['date'],
|
|
137
|
+
},
|
|
138
|
+
inputExamples: [
|
|
139
|
+
{
|
|
140
|
+
name: '查默认共享(按日期)',
|
|
141
|
+
input: { date: '2026-08-19' },
|
|
142
|
+
source: 'references/daily-report-blog-get-default-permission.md(blogTime 入参)',
|
|
143
|
+
sourceType: 'source-provided',
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'blog.export',
|
|
149
|
+
risk: 'local-file-write',
|
|
150
|
+
summary: '导出日报报表为 xlsx(拒绝覆盖已有文件)',
|
|
151
|
+
fixed: { blogType: 'all', searchType: 'all', disableType: 'all', isNeedConvert: false },
|
|
152
|
+
inputSchema: {
|
|
153
|
+
type: 'object',
|
|
154
|
+
additionalProperties: false,
|
|
155
|
+
properties: {
|
|
156
|
+
start_date: { type: 'string', pattern: DATE },
|
|
157
|
+
end_date: { type: 'string', pattern: DATE },
|
|
158
|
+
output: { type: 'string', minLength: 1, description: '本地输出 .xlsx 路径;文件已存在时拒绝覆盖' },
|
|
159
|
+
page_size: { type: 'integer', minimum: 1, maximum: 500, default: 200 },
|
|
160
|
+
},
|
|
161
|
+
required: ['start_date', 'end_date', 'output'],
|
|
162
|
+
},
|
|
163
|
+
inputExamples: [
|
|
164
|
+
{
|
|
165
|
+
name: '导出某月日报',
|
|
166
|
+
input: { start_date: '2026-08-01', end_date: '2026-08-31', output: 'C:/path/to/aug.xlsx' },
|
|
167
|
+
source: 'scripts/export-blog.mjs 用法示例(node export-blog.mjs 2026-08-01 2026-08-31 --out ...)',
|
|
168
|
+
sourceType: 'source-provided',
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'blog.publish.prepare',
|
|
174
|
+
risk: 'read-before-write',
|
|
175
|
+
summary: '发布准备:查当日是否已有日报 + 回填默认共享 + 签发 continuation(不写数据)',
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: 'object',
|
|
178
|
+
additionalProperties: false,
|
|
179
|
+
properties: {
|
|
180
|
+
date: { type: 'string', pattern: DATE, description: '日报归属日期(只能发布当前登录人自己的日报)' },
|
|
181
|
+
content: { type: 'string', minLength: 1, description: '日报正文;纯文本自动包裹 <p>,HTML 原样保留' },
|
|
182
|
+
share_default: { type: 'boolean', default: true, description: '是否回填该日期的默认共享对象;false 表示仅自己可见' },
|
|
183
|
+
},
|
|
184
|
+
required: ['date', 'content'],
|
|
185
|
+
},
|
|
186
|
+
inputExamples: [
|
|
187
|
+
{
|
|
188
|
+
name: '准备发布某日日报',
|
|
189
|
+
input: { date: '2026-08-19', content: '<p>今日工作总结</p>', share_default: true },
|
|
190
|
+
source: 'scripts/publish-blog.mjs 用法示例(node publish-blog.mjs 2026-08-14 "<p>补交内容</p>" --share)',
|
|
191
|
+
sourceType: 'source-provided',
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'blog.publish.apply',
|
|
197
|
+
risk: 'high-risk-write',
|
|
198
|
+
summary: '发布落库:校验 continuation 与写前状态后调用 addBlog,并回查验证',
|
|
199
|
+
inputSchema: CONFIRM_SCHEMA,
|
|
200
|
+
missingExamples: [
|
|
201
|
+
{
|
|
202
|
+
reason: 'apply 的唯一入参是 prepare 当场签发的 continuation,源资料不提供固定样例',
|
|
203
|
+
missingFacts: ['continuation'],
|
|
204
|
+
source: 'scripts/publish-blog.mjs(无 continuation 概念)',
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: 'blog.edit.prepare',
|
|
210
|
+
risk: 'read-before-write',
|
|
211
|
+
summary: '编辑准备:回查原内容与差异 + 目标指纹 + 签发 continuation(不写数据)',
|
|
212
|
+
inputSchema: {
|
|
213
|
+
type: 'object',
|
|
214
|
+
additionalProperties: false,
|
|
215
|
+
properties: {
|
|
216
|
+
user_id: { ...POSITIVE_ID, description: '目标人员 userId;与 name 二选一;都不传时编辑当前登录人的日报' },
|
|
217
|
+
name: { type: 'string', minLength: 1, description: '目标人员姓名;与 user_id 二选一' },
|
|
218
|
+
date: { type: 'string', pattern: DATE },
|
|
219
|
+
content: { type: 'string', minLength: 1, description: '新日报正文;纯文本自动包裹 <p>' },
|
|
220
|
+
},
|
|
221
|
+
required: ['date', 'content'],
|
|
222
|
+
},
|
|
223
|
+
inputExamples: [
|
|
224
|
+
{
|
|
225
|
+
name: '准备编辑自己的日报',
|
|
226
|
+
input: { date: '2026-08-19', content: '<p>修正后的内容</p>' },
|
|
227
|
+
source: 'scripts/edit-blog.mjs(blogTime + content 入参)',
|
|
228
|
+
sourceType: 'source-provided',
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: 'blog.edit.apply',
|
|
234
|
+
risk: 'high-risk-write',
|
|
235
|
+
summary: '编辑落库:目标指纹校验后调用 updateBlog,并回查内容一致性',
|
|
236
|
+
inputSchema: CONFIRM_SCHEMA,
|
|
237
|
+
missingExamples: [
|
|
238
|
+
{
|
|
239
|
+
reason: 'apply 的唯一入参是 prepare 当场签发的 continuation,源资料不提供固定样例',
|
|
240
|
+
missingFacts: ['continuation'],
|
|
241
|
+
source: 'scripts/edit-blog.mjs(无 continuation 概念)',
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'blog.comment.prepare',
|
|
247
|
+
risk: 'read-before-write',
|
|
248
|
+
summary: '评论准备:定位目标日报(blog_id 或 date+user)后签发 continuation',
|
|
249
|
+
inputSchema: {
|
|
250
|
+
type: 'object',
|
|
251
|
+
additionalProperties: false,
|
|
252
|
+
properties: {
|
|
253
|
+
blog_id: { ...POSITIVE_ID, description: '日报记录 id;与 date(+ user_id/name)二选一' },
|
|
254
|
+
user_id: POSITIVE_ID,
|
|
255
|
+
name: { type: 'string', minLength: 1 },
|
|
256
|
+
date: { type: 'string', pattern: DATE },
|
|
257
|
+
content: { type: 'string', minLength: 1, description: '评论内容' },
|
|
258
|
+
},
|
|
259
|
+
required: ['content'],
|
|
260
|
+
anyOf: [{ required: ['blog_id'] }, { required: ['date'] }],
|
|
261
|
+
},
|
|
262
|
+
inputExamples: [
|
|
263
|
+
{
|
|
264
|
+
name: '按日期定位并评论',
|
|
265
|
+
input: { date: '2026-08-19', content: '收到,请补齐明细' },
|
|
266
|
+
source: 'scripts/comment-blog.mjs(blogId 或 date+name 定位)',
|
|
267
|
+
sourceType: 'source-provided',
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: 'blog.comment.apply',
|
|
273
|
+
risk: 'high-risk-write',
|
|
274
|
+
summary: '评论落库:createComment 后从评论列表回查该评论',
|
|
275
|
+
inputSchema: CONFIRM_SCHEMA,
|
|
276
|
+
missingExamples: [
|
|
277
|
+
{
|
|
278
|
+
reason: 'apply 的唯一入参是 prepare 当场签发的 continuation,源资料不提供固定样例',
|
|
279
|
+
missingFacts: ['continuation'],
|
|
280
|
+
source: 'scripts/comment-blog.mjs(无 continuation 概念)',
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'blog.like.prepare',
|
|
286
|
+
risk: 'read-before-write',
|
|
287
|
+
summary: '点赞/取消点赞准备:定位目标日报后签发 continuation',
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
additionalProperties: false,
|
|
291
|
+
properties: {
|
|
292
|
+
blog_id: { ...POSITIVE_ID, description: '日报记录 id;与 date(+ user_id/name)二选一' },
|
|
293
|
+
user_id: POSITIVE_ID,
|
|
294
|
+
name: { type: 'string', minLength: 1 },
|
|
295
|
+
date: { type: 'string', pattern: DATE },
|
|
296
|
+
cancel: { type: 'boolean', default: false, description: 'false=点赞(vote),true=取消点赞(cancelVote)' },
|
|
297
|
+
},
|
|
298
|
+
anyOf: [{ required: ['blog_id'] }, { required: ['date'] }],
|
|
299
|
+
},
|
|
300
|
+
inputExamples: [
|
|
301
|
+
{
|
|
302
|
+
name: '按日期点赞',
|
|
303
|
+
input: { date: '2026-08-19' },
|
|
304
|
+
source: 'scripts/like-blog.mjs(vote / cancelVote 两种路径)',
|
|
305
|
+
sourceType: 'source-provided',
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: 'blog.like.apply',
|
|
311
|
+
risk: 'high-risk-write',
|
|
312
|
+
summary: '点赞落库:vote / cancelVote,以业务码为生效依据(无只读回查接口)',
|
|
313
|
+
inputSchema: CONFIRM_SCHEMA,
|
|
314
|
+
missingExamples: [
|
|
315
|
+
{
|
|
316
|
+
reason: 'apply 的唯一入参是 prepare 当场签发的 continuation,源资料不提供固定样例',
|
|
317
|
+
missingFacts: ['continuation'],
|
|
318
|
+
source: 'scripts/like-blog.mjs(无 continuation 概念)',
|
|
319
|
+
},
|
|
320
|
+
],
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: 'blog.remind.prepare',
|
|
324
|
+
risk: 'read-before-write',
|
|
325
|
+
summary: '提醒准备:解析被提醒人 + 生成默认文案 + 签发 continuation(不发送)',
|
|
326
|
+
inputSchema: {
|
|
327
|
+
type: 'object',
|
|
328
|
+
additionalProperties: false,
|
|
329
|
+
properties: {
|
|
330
|
+
user_ids: {
|
|
331
|
+
type: 'array',
|
|
332
|
+
minItems: 1,
|
|
333
|
+
maxItems: 50,
|
|
334
|
+
items: POSITIVE_ID,
|
|
335
|
+
description: '被提醒人 userId 列表(或逗号分隔字符串);与 names 二选一',
|
|
336
|
+
},
|
|
337
|
+
names: {
|
|
338
|
+
type: 'array',
|
|
339
|
+
minItems: 1,
|
|
340
|
+
maxItems: 50,
|
|
341
|
+
items: { type: 'string', minLength: 1 },
|
|
342
|
+
description: '被提醒人姓名列表,经 HRM 解析;与 user_ids 二选一',
|
|
343
|
+
},
|
|
344
|
+
date: { type: 'string', pattern: DATE, description: '日报归属日期,用于默认文案与年份' },
|
|
345
|
+
content: { type: 'string', minLength: 1, description: '提醒文案;缺省时生成「请填写 YYYY年 M月 D日 的日报!」,自定义文案必须包含日期' },
|
|
346
|
+
year: { type: 'integer', minimum: 2000, maximum: 2100, description: '日报所属年份;缺省时从 date 推断' },
|
|
347
|
+
},
|
|
348
|
+
required: ['date'],
|
|
349
|
+
oneOf: [{ required: ['user_ids'] }, { required: ['names'] }],
|
|
350
|
+
},
|
|
351
|
+
inputExamples: [
|
|
352
|
+
{
|
|
353
|
+
name: '按 userId 提醒(默认文案)',
|
|
354
|
+
input: { user_ids: ['1077039731822690306'], date: '2026-08-19' },
|
|
355
|
+
source: 'scripts/remind-blog.mjs 用法示例(--userId 1077039731822690306 --date 2026-08-19)',
|
|
356
|
+
sourceType: 'source-provided',
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
name: '按姓名提醒(自定义文案)',
|
|
360
|
+
input: { names: ['章智涵'], content: '请尽快提交 8 月 19 日日报', year: 2026 },
|
|
361
|
+
source: 'scripts/remind-blog.mjs 用法示例(--name 章智涵 --content ... --year 2026)',
|
|
362
|
+
sourceType: 'source-provided',
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
name: 'blog.remind.apply',
|
|
368
|
+
risk: 'high-risk-write',
|
|
369
|
+
summary: '提醒落库:逐人 POST sendUrge;部分失败返回 PARTIAL,中断返回 write_uncertain',
|
|
370
|
+
inputSchema: CONFIRM_SCHEMA,
|
|
371
|
+
missingExamples: [
|
|
372
|
+
{
|
|
373
|
+
reason: 'apply 的唯一入参是 prepare 当场签发的 continuation,源资料不提供固定样例',
|
|
374
|
+
missingFacts: ['continuation'],
|
|
375
|
+
source: 'scripts/remind-blog.mjs(无 continuation 概念)',
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
},
|
|
379
|
+
];
|
|
380
|
+
export const blogManifest = {
|
|
381
|
+
schemaVersion: 1,
|
|
382
|
+
name: 'blog',
|
|
383
|
+
title: '泛微E10工作日报',
|
|
384
|
+
version: '0.1.0',
|
|
385
|
+
host: 'e10-blog',
|
|
386
|
+
status: 'builtin',
|
|
387
|
+
sourceSkill: 'weaver-e10-blog',
|
|
388
|
+
capabilities: ['query', 'query-user', 'comments', 'export', 'publish', 'edit', 'comment', 'like', 'remind'],
|
|
389
|
+
operations: blogOperations,
|
|
390
|
+
withheldOperations: [
|
|
391
|
+
{
|
|
392
|
+
name: 'blog.query_by_ids',
|
|
393
|
+
reason: 'blogs 接口的 filter.userIds/empIds/userId/creator 被服务端忽略(内网租户实测,恒定返回当前登录人且 HTTP 200),按 userId 列表查个人会静默变成查自己;查指定个人统一走 blog.query_user(detailsByDate)。',
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: 'blog.unread',
|
|
397
|
+
reason: 'POST /api/blog/query/unRead 在当前租户多种 body 形态实测恒返回空 blogList,不可作为数据源。',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: 'blog.eb.*',
|
|
401
|
+
reason: 'EB 日报应用接口族(ebuilder getFormDataList + secondev addBlog/editBlog)依赖租户是否启用 EB 日报应用,当前租户未启用;启用后需另行转换并按租户探测。',
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: 'blog.delete',
|
|
405
|
+
reason: '服务端未提供日报删除接口,源资料亦无删除脚本;不做推测实现。',
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
name: 'blog.remind.cancel',
|
|
409
|
+
reason: '已发送提醒无法撤回(源资料无对应接口)。',
|
|
410
|
+
},
|
|
411
|
+
],
|
|
412
|
+
};
|
|
413
|
+
export function hasBlogOperation(operation) {
|
|
414
|
+
return blogOperations.some((item) => item.name === operation);
|
|
415
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { blogConfirmationError, blogPartialError, blogValidationError, isBlogNetworkError, } from '../errors.js';
|
|
2
|
+
import { objectFingerprint, resolveTargetBlog, sessionMatches } from './shared.js';
|
|
3
|
+
import { workflow } from './types.js';
|
|
4
|
+
/** 评论 prepare:定位目标日报(无日报直接报错,不追问),签发 continuation */
|
|
5
|
+
export class BlogCommentPrepareOperation {
|
|
6
|
+
name = 'blog.comment.prepare';
|
|
7
|
+
async execute(input, { host, continuation }) {
|
|
8
|
+
const content = typeof input.content === 'string' ? input.content.trim() : '';
|
|
9
|
+
if (!content)
|
|
10
|
+
throw blogValidationError('input_invalid', 'content 必须是非空字符串');
|
|
11
|
+
const target = await resolveTargetBlog(input, host, '评论');
|
|
12
|
+
const session = await host.getSession();
|
|
13
|
+
const continuationToken = await continuation.issue({
|
|
14
|
+
operation: 'blog.comment.apply',
|
|
15
|
+
workflow: workflow('blog.comment', 'AWAITING_CONFIRMATION'),
|
|
16
|
+
baseUrl: session.baseUrl,
|
|
17
|
+
profile: session.profile,
|
|
18
|
+
userId: session.userId,
|
|
19
|
+
blogId: target.blogId,
|
|
20
|
+
content,
|
|
21
|
+
fingerprint: objectFingerprint(target.blog ? { id: target.blog.id, content: target.blog.content } : { id: target.blogId }),
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
status: 'AWAITING_CONFIRMATION',
|
|
25
|
+
data: {
|
|
26
|
+
blog_id: target.blogId,
|
|
27
|
+
target: target.date ? { date: target.date, user_id: target.userId } : undefined,
|
|
28
|
+
target_content_text: target.blog?.content_text,
|
|
29
|
+
comment: content,
|
|
30
|
+
continuation: continuationToken,
|
|
31
|
+
expires_in_seconds: 600,
|
|
32
|
+
workflow: workflow('blog.comment', 'AWAITING_CONFIRMATION'),
|
|
33
|
+
next: '向用户复述目标日报与评论内容,用户确认后调用 blog.comment.apply 并传 confirm=true',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** 评论 apply:确认 + continuation + 写后从评论列表回查该评论 */
|
|
39
|
+
export class BlogCommentApplyOperation {
|
|
40
|
+
name = 'blog.comment.apply';
|
|
41
|
+
async execute(input, { host, continuation }) {
|
|
42
|
+
if (input.confirm !== true) {
|
|
43
|
+
throw blogConfirmationError('blog.comment.apply', { hint: '重新调用时传入 confirm=true' });
|
|
44
|
+
}
|
|
45
|
+
const lease = await continuation.verify(input.continuation, 'blog.comment.apply');
|
|
46
|
+
if (typeof lease.blogId !== 'string' || typeof lease.content !== 'string') {
|
|
47
|
+
throw blogValidationError('continuation_invalid', '评论 continuation 缺少有效目标或内容');
|
|
48
|
+
}
|
|
49
|
+
const session = await host.getSession();
|
|
50
|
+
if (!sessionMatches(lease, session)) {
|
|
51
|
+
throw blogValidationError('context_mismatch', '确认上下文已变化,请重新准备评论');
|
|
52
|
+
}
|
|
53
|
+
let result;
|
|
54
|
+
try {
|
|
55
|
+
result = await host.blogRequest({
|
|
56
|
+
path: '/api/blog/common/comment/createComment',
|
|
57
|
+
body: {
|
|
58
|
+
comment: {
|
|
59
|
+
targetId: lease.blogId,
|
|
60
|
+
disableMessage: false,
|
|
61
|
+
relevanceList: [],
|
|
62
|
+
imAtContent: lease.content,
|
|
63
|
+
atLinkList: [],
|
|
64
|
+
content: lease.content,
|
|
65
|
+
originContent: lease.content,
|
|
66
|
+
module: 'blog',
|
|
67
|
+
},
|
|
68
|
+
attachments: '',
|
|
69
|
+
attachmentsList: [],
|
|
70
|
+
client: 'pc',
|
|
71
|
+
},
|
|
72
|
+
operation: 'blog.comment.apply',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (isBlogNetworkError(error)) {
|
|
77
|
+
throw blogPartialError('评论请求发送后连接中断,结果不确定,禁止自动重试', {
|
|
78
|
+
blog_id: lease.blogId,
|
|
79
|
+
workflow: workflow('blog.comment', 'EXECUTING'),
|
|
80
|
+
}, { stage: 'comment' });
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
// 写后回查:评论列表中应能找到该评论
|
|
85
|
+
let verified = false;
|
|
86
|
+
let commentId = null;
|
|
87
|
+
try {
|
|
88
|
+
const page = await host.blogRequest({
|
|
89
|
+
path: '/api/blog/common/comment/commentPage',
|
|
90
|
+
body: { pageNo: 1, pageSize: 50, targetId: lease.blogId, module: 'blog', foldCommentList: false },
|
|
91
|
+
operation: 'blog.comment.apply',
|
|
92
|
+
});
|
|
93
|
+
const comments = Array.isArray(page?.data?.page?.result) ? page.data.page.result : [];
|
|
94
|
+
const matched = comments.find((item) => item?.content === lease.content);
|
|
95
|
+
if (matched?.id) {
|
|
96
|
+
verified = true;
|
|
97
|
+
commentId = String(matched.id);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
throw blogPartialError('评论接口已返回成功,但评论列表回查失败,结果不确定', {
|
|
102
|
+
blog_id: lease.blogId,
|
|
103
|
+
result,
|
|
104
|
+
workflow: workflow('blog.comment', 'VERIFYING'),
|
|
105
|
+
}, { stage: 'readback' });
|
|
106
|
+
}
|
|
107
|
+
if (!verified) {
|
|
108
|
+
throw blogPartialError('评论接口已返回成功,但评论列表中未找到该评论', {
|
|
109
|
+
blog_id: lease.blogId,
|
|
110
|
+
result,
|
|
111
|
+
workflow: workflow('blog.comment', 'VERIFYING'),
|
|
112
|
+
}, { stage: 'readback' });
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
status: 'COMPLETE',
|
|
116
|
+
data: {
|
|
117
|
+
blog_id: lease.blogId,
|
|
118
|
+
comment_id: commentId,
|
|
119
|
+
verified: true,
|
|
120
|
+
result,
|
|
121
|
+
workflow: workflow('blog.comment', 'COMPLETE'),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { asInteger, asPositiveString } from './shared.js';
|
|
2
|
+
export class BlogCommentsOperation {
|
|
3
|
+
name = 'blog.comments';
|
|
4
|
+
async execute(input, { host }) {
|
|
5
|
+
const blogId = asPositiveString(input.blog_id, 'blog_id');
|
|
6
|
+
const pageNo = asInteger(input.page_no, 'page_no', { min: 1, max: 10_000, dflt: 1 });
|
|
7
|
+
const pageSize = asInteger(input.page_size, 'page_size', { min: 1, max: 100, dflt: 20 });
|
|
8
|
+
const value = await host.blogRequest({
|
|
9
|
+
path: '/api/blog/common/comment/commentPage',
|
|
10
|
+
body: {
|
|
11
|
+
pageNo,
|
|
12
|
+
pageSize,
|
|
13
|
+
targetId: blogId,
|
|
14
|
+
module: 'blog',
|
|
15
|
+
foldCommentList: false,
|
|
16
|
+
},
|
|
17
|
+
operation: 'blog.comments',
|
|
18
|
+
});
|
|
19
|
+
const page = value?.data?.page ?? {};
|
|
20
|
+
return {
|
|
21
|
+
status: 'COMPLETE',
|
|
22
|
+
data: {
|
|
23
|
+
blog_id: blogId,
|
|
24
|
+
total_count: page.totalCount ?? null,
|
|
25
|
+
page_no: page.pageNo ?? pageNo,
|
|
26
|
+
page_size: page.pageSize ?? pageSize,
|
|
27
|
+
comments: Array.isArray(page.result) ? page.result : [],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|