weaver-e10-builder 1.5.7 → 1.5.9

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 (142) hide show
  1. package/dist/commands/app.d.ts.map +1 -1
  2. package/dist/commands/app.js +259 -0
  3. package/dist/commands/app.js.map +1 -1
  4. package/dist/commands/form-add-detail-table.d.ts.map +1 -1
  5. package/dist/commands/form-add-detail-table.js +13 -2
  6. package/dist/commands/form-add-detail-table.js.map +1 -1
  7. package/dist/commands/form-button.d.ts.map +1 -1
  8. package/dist/commands/form-button.js +6 -4
  9. package/dist/commands/form-button.js.map +1 -1
  10. package/dist/commands/form-formula-linkage.d.ts.map +1 -1
  11. package/dist/commands/form-formula-linkage.js +4 -4
  12. package/dist/commands/form-formula-linkage.js.map +1 -1
  13. package/dist/commands/form-list-filter.d.ts +3 -0
  14. package/dist/commands/form-list-filter.d.ts.map +1 -1
  15. package/dist/commands/form-list-filter.js +88 -24
  16. package/dist/commands/form-list-filter.js.map +1 -1
  17. package/dist/commands/form-list-search-group.d.ts.map +1 -1
  18. package/dist/commands/form-list-search-group.js +54 -64
  19. package/dist/commands/form-list-search-group.js.map +1 -1
  20. package/dist/commands/form-list-stats.d.ts.map +1 -1
  21. package/dist/commands/form-list-stats.js +29 -4
  22. package/dist/commands/form-list-stats.js.map +1 -1
  23. package/dist/commands/form-list-utils.d.ts +46 -1
  24. package/dist/commands/form-list-utils.d.ts.map +1 -1
  25. package/dist/commands/form-list-utils.js +140 -47
  26. package/dist/commands/form-list-utils.js.map +1 -1
  27. package/dist/commands/form-list.d.ts.map +1 -1
  28. package/dist/commands/form-list.js +141 -71
  29. package/dist/commands/form-list.js.map +1 -1
  30. package/dist/commands/form-message.d.ts +3 -0
  31. package/dist/commands/form-message.d.ts.map +1 -0
  32. package/dist/commands/form-message.js +341 -0
  33. package/dist/commands/form-message.js.map +1 -0
  34. package/dist/commands/form-view.d.ts.map +1 -1
  35. package/dist/commands/form-view.js +31 -4
  36. package/dist/commands/form-view.js.map +1 -1
  37. package/dist/commands/matrix.d.ts.map +1 -1
  38. package/dist/commands/matrix.js +80 -42
  39. package/dist/commands/matrix.js.map +1 -1
  40. package/dist/commands/org.d.ts.map +1 -1
  41. package/dist/commands/org.js +61 -0
  42. package/dist/commands/org.js.map +1 -1
  43. package/dist/commands/role.d.ts.map +1 -1
  44. package/dist/commands/role.js +69 -9
  45. package/dist/commands/role.js.map +1 -1
  46. package/dist/commands/wf-form.d.ts.map +1 -1
  47. package/dist/commands/wf-form.js +5 -5
  48. package/dist/commands/wf-form.js.map +1 -1
  49. package/dist/index.js +2 -0
  50. package/dist/index.js.map +1 -1
  51. package/dist/services/actionflow/context_preflight.d.ts +3 -3
  52. package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
  53. package/dist/services/actionflow/context_preflight.js +45 -24
  54. package/dist/services/actionflow/context_preflight.js.map +1 -1
  55. package/dist/services/actionflow/context_provider.d.ts +7 -0
  56. package/dist/services/actionflow/context_provider.d.ts.map +1 -1
  57. package/dist/services/actionflow/context_provider.js +13 -1
  58. package/dist/services/actionflow/context_provider.js.map +1 -1
  59. package/dist/services/actionflow/formula_service.d.ts +15 -0
  60. package/dist/services/actionflow/formula_service.d.ts.map +1 -1
  61. package/dist/services/actionflow/formula_service.js +401 -57
  62. package/dist/services/actionflow/formula_service.js.map +1 -1
  63. package/dist/services/actionflow/param_group_dto.d.ts.map +1 -1
  64. package/dist/services/actionflow/param_group_dto.js +17 -3
  65. package/dist/services/actionflow/param_group_dto.js.map +1 -1
  66. package/dist/services/actionflow/param_type.d.ts +14 -0
  67. package/dist/services/actionflow/param_type.d.ts.map +1 -0
  68. package/dist/services/actionflow/param_type.js +69 -0
  69. package/dist/services/actionflow/param_type.js.map +1 -0
  70. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  71. package/dist/services/actionflow/preflight_service.js +59 -41
  72. package/dist/services/actionflow/preflight_service.js.map +1 -1
  73. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  74. package/dist/services/actionflow/workflow_compiler.js +65 -29
  75. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  76. package/dist/services/app-publish.d.ts +227 -0
  77. package/dist/services/app-publish.d.ts.map +1 -0
  78. package/dist/services/app-publish.js +403 -0
  79. package/dist/services/app-publish.js.map +1 -0
  80. package/dist/services/form-button-position.d.ts.map +1 -1
  81. package/dist/services/form-button-position.js +7 -1
  82. package/dist/services/form-button-position.js.map +1 -1
  83. package/dist/services/form-field-drop.d.ts.map +1 -1
  84. package/dist/services/form-field-drop.js +7 -0
  85. package/dist/services/form-field-drop.js.map +1 -1
  86. package/dist/services/form-formula-linkage.d.ts +24 -3
  87. package/dist/services/form-formula-linkage.d.ts.map +1 -1
  88. package/dist/services/form-formula-linkage.js +24 -5
  89. package/dist/services/form-formula-linkage.js.map +1 -1
  90. package/dist/services/form-list-search-group.d.ts +89 -0
  91. package/dist/services/form-list-search-group.d.ts.map +1 -0
  92. package/dist/services/form-list-search-group.js +260 -0
  93. package/dist/services/form-list-search-group.js.map +1 -0
  94. package/dist/services/form-list-search.d.ts +110 -0
  95. package/dist/services/form-list-search.d.ts.map +1 -0
  96. package/dist/services/form-list-search.js +231 -0
  97. package/dist/services/form-list-search.js.map +1 -0
  98. package/dist/services/form-list-stats.d.ts +21 -1
  99. package/dist/services/form-list-stats.d.ts.map +1 -1
  100. package/dist/services/form-list-stats.js +86 -12
  101. package/dist/services/form-list-stats.js.map +1 -1
  102. package/dist/services/form-message.d.ts +273 -0
  103. package/dist/services/form-message.d.ts.map +1 -0
  104. package/dist/services/form-message.js +575 -0
  105. package/dist/services/form-message.js.map +1 -0
  106. package/dist/services/form-sub-detail.d.ts.map +1 -1
  107. package/dist/services/form-sub-detail.js +5 -1
  108. package/dist/services/form-sub-detail.js.map +1 -1
  109. package/dist/services/form-view.d.ts +34 -2
  110. package/dist/services/form-view.d.ts.map +1 -1
  111. package/dist/services/form-view.js +74 -8
  112. package/dist/services/form-view.js.map +1 -1
  113. package/dist/services/matrix-fields.d.ts +42 -0
  114. package/dist/services/matrix-fields.d.ts.map +1 -0
  115. package/dist/services/matrix-fields.js +102 -0
  116. package/dist/services/matrix-fields.js.map +1 -0
  117. package/dist/services/org-browser.d.ts +60 -0
  118. package/dist/services/org-browser.d.ts.map +1 -0
  119. package/dist/services/org-browser.js +62 -0
  120. package/dist/services/org-browser.js.map +1 -0
  121. package/dist/services/quick-date-range.d.ts +22 -0
  122. package/dist/services/quick-date-range.d.ts.map +1 -0
  123. package/dist/services/quick-date-range.js +134 -0
  124. package/dist/services/quick-date-range.js.map +1 -0
  125. package/dist/services/role-member.d.ts +73 -2
  126. package/dist/services/role-member.d.ts.map +1 -1
  127. package/dist/services/role-member.js +141 -9
  128. package/dist/services/role-member.js.map +1 -1
  129. package/package.json +1 -1
  130. package/skill-docs/SKILL.md +281 -278
  131. package/skill-docs/_catalog.md +3 -0
  132. package/skill-docs/actionflows/SKILL.md +2 -1
  133. package/skill-docs/actionflows/references/components/message/InnerMQSend.md +6 -0
  134. package/skill-docs/references/app/guide-app-publish.md +92 -0
  135. package/skill-docs/references/common/guide-plan-template.md +148 -252
  136. package/skill-docs/references/common/map.md +2 -1
  137. package/skill-docs/references/common/ref-cli-commands.md +27 -8
  138. package/skill-docs/references/form/guide-form-message.md +57 -0
  139. package/skill-docs/references/form/guide-form-view.md +7 -2
  140. package/skill-docs/references/form/guide-formula-linkage.md +1 -1
  141. package/skill-docs/references/form/guide-list-stats.md +55 -2
  142. package/skill-docs/references/hrm/guide-matrix.md +30 -2
@@ -0,0 +1,227 @@
1
+ /**
2
+ * 应用(app)的「启用 / 发布到前台 / 取消发布 / 改发布信息」与「应用名称多语言」。
3
+ *
4
+ * ⚠️ 这族接口**不在** `bs/ebuilder` 命名空间下,分散在三处,别按老习惯拼路径:
5
+ *
6
+ * | 动作 | 命名空间 |
7
+ * |---|---|
8
+ * | 启用 / 停用 | `/api/ebd/component/ableSwitch/*` |
9
+ * | 发布 / 改发布信息 / 取消发布 | `/api/basicserver/*` |
10
+ * | 应用名多语言 | `/api/bs/ebuilder/app/multilangset/*`(这条才回 bs 老窝) |
11
+ *
12
+ * 三者的**请求形状也各不相同**:启用是 GET 带 URL 中文参数、发布是 JSON、
13
+ * 取消发布是 **multipart**、改发布信息又是另一个 JSON 形状。同域不同形,最容易踩。
14
+ */
15
+ import type { ApiClient } from '../core/client.js';
16
+ /** 启用/停用。GET,参数 appId / appName(必带,中文要 URL 编码)。 */
17
+ export declare const ABLE_SWITCH_PATH = "/api/ebd/component/ableSwitch";
18
+ /** 发布到前台:新建一个前台自定义应用。JSON。 */
19
+ export declare const CREATE_CUSTOM_APP_PATH = "/api/basicserver/createCustomApplication";
20
+ /** 改发布信息。JSON,但要的是**回读形状的子集**,和发布那份不是一套。 */
21
+ export declare const SAVE_CUSTOM_APP_PATH = "/api/basicserver/saveCustomApplication";
22
+ /** 取消发布。**multipart**,只吃 sysMenuId + displayClient。 */
23
+ export declare const DELETE_CUSTOM_APP_PATH = "/api/basicserver/deleteCustomApplication";
24
+ /**
25
+ * 读一条已发布的前台自定义应用。**multipart**,只吃 sysMenuId。
26
+ * 命中回 `data.{sysMenuId, sysMenus}`,未命中只回 `{sysMenuId: "<传入值>"}`(**没有 sysMenus**)——
27
+ * 所以「未发布」的判据是**有没有 `sysMenus`**,不是看 code。
28
+ */
29
+ export declare const QUERY_FREE_APP_PATH = "/api/basicserver/free/queryFreeApplication";
30
+ /** 根机构号。发布/取消发布 body 里的 deptId 就是它。 */
31
+ export declare const QUERY_ROOT_DEPT_PATH = "/api/basicserver/app/manage/queryRootDept";
32
+ /** 应用分类表(汇报/协作/…/自定义)。⚠️ 响应**没有 code/status 包装**,是裸对象。 */
33
+ export declare const QUERY_APP_TYPES_PATH = "/api/basicserver/queryAppTypes";
34
+ /** 应用名多语文:读。 */
35
+ export declare const APP_ML_GETDATA_PATH = "/api/bs/ebuilder/app/multilangset/getdata";
36
+ /** 应用名多语文:写。 */
37
+ export declare const APP_ML_SAVEDATA_PATH = "/api/bs/ebuilder/app/multilangset/savedata";
38
+ /** 应用名多语文的「哪张表的哪个字段」——认记录靠这两把钥匙,不靠 targetId。 */
39
+ export declare const APP_ML_MODULE = "ebuilder_app";
40
+ export declare const APP_ML_TABLEFIELD = "ebda_app.name";
41
+ /** 停用时要带的档位参数(启用不带)。实测原值 8,含义未解,**照传**。 */
42
+ export declare const DISABLE_SWITCH_NUM = "8";
43
+ /**
44
+ * 前台自定义应用的应用类型。发布、取消发布都要带,固定 `'eBuilder'`。
45
+ * 注意 body 里它出现两种形状:发布是顶层 `module:{moduleStr}`,取消发布没有。
46
+ */
47
+ export declare const CUSTOM_APP_MODULE = "eBuilder";
48
+ /** 发布/取消发布都带的前端标识。 */
49
+ export declare const DISPLAY_CLIENT = "pc";
50
+ /**
51
+ * 拼启用/停用的 URL。
52
+ *
53
+ * `appName` 是**必带的**,平台拿它对不上会拒。老坑:`appName` 是中文时,
54
+ * 走 shell 内联会变 GBK —— 所以这里**一律由本函数做 URL 编码**,调用方只管传原文。
55
+ */
56
+ export declare function buildAbleSwitchUrl(baseUrl: string, appId: string, appName: string, on: boolean): string;
57
+ /**
58
+ * 启用/停用应用。
59
+ *
60
+ * 语义(实测):这一条**同时翻 `publishEnabled` 和 `publishEteams`** ——
61
+ * 停用会把「已发布到 eteams」一并收掉,这正是界面那句
62
+ * 「应用暂未启用,启用后才可以发布给成员使用」的由来。
63
+ *
64
+ * 取值:`1` 启用、`2` 停用、`0` 从未启用。
65
+ */
66
+ export declare function setAppEnabled(client: ApiClient, baseUrl: string, appId: string, appName: string, on: boolean): Promise<{
67
+ app: boolean;
68
+ esb: boolean;
69
+ appManager: boolean;
70
+ ecode: boolean;
71
+ }>;
72
+ export interface AppLangRow {
73
+ id: string;
74
+ langid?: number;
75
+ langtype: string;
76
+ langName?: string;
77
+ value?: string;
78
+ [k: string]: unknown;
79
+ }
80
+ /**
81
+ * 读应用名的各语言译文。
82
+ *
83
+ * ⚠️ **`targetId` 必须传应用的 `nameLabelId`,传空串只会读回一张空白模板**
84
+ * (2026-10-13 实测:传空串时两行 `value` 都是 `''`,而且行 `id` 每次重生成)。
85
+ * 前端那条读之所以传空串,是因为它走的是「新建标签」路径,不是「读已有」。
86
+ */
87
+ export declare function readAppLangRows(client: ApiClient, baseUrl: string, nameLabelId: string): Promise<AppLangRow[]>;
88
+ /**
89
+ * 保存应用名的多语言,返回要挂回应用记录的 `nameLabelId`。
90
+ *
91
+ * 两态响应键名不同,**两个都要兜**(实测):
92
+ * - `targetId` 传空 → 平台新造一个,回 `data.new_targetId`
93
+ * - `targetId` 传已有 → 原地更新,回 `data.targetId`(同一个号)
94
+ *
95
+ * ⚠️ 行里的 `id` 是**前端行标识,每次读都重生成**,照抄即可,
96
+ * 但**绝不能用它定位记录** —— 定位靠 `targetId + module + tablefield + langtype`。
97
+ */
98
+ export declare function saveAppLangRows(client: ApiClient, baseUrl: string, rows: AppLangRow[], values: Record<string, string>, targetId: string): Promise<string>;
99
+ /** 保存响应里取 `nameLabelId`。新建回 `new_targetId`、更新回 `targetId`,两态都要兜。 */
100
+ export declare function resolveSavedLabelId(res: any): string;
101
+ /** 从语言行里取某语言的译文。 */
102
+ export declare function langValueOf(rows: AppLangRow[], langtype: string): string;
103
+ /** 前台应用的入口地址。发布时要显式登记,少一条前台点进去是白页。 */
104
+ export declare function innerUrlOf(appId: string): string;
105
+ export declare function innerUrlMobileOf(appId: string): string;
106
+ /** 平台自带的手机端默认图,前端发的是这个固定路径。 */
107
+ export declare const DEFAULT_MOBILE_IMG_ICON = "/build/manager/static/media/defaultMobileAppImg.png";
108
+ /** 由应用图标(PC)派生手机端图标 —— 前端就是这么拼的(白字 + 底色)。 */
109
+ export declare function mobileIconFrom(iconJson: string): string;
110
+ /**
111
+ * 「所有人」共享条目。发布时默认按所有人可见 —— 前端发的就是这两条
112
+ * (`permissionType` 0 和 2 各一条,其余键逐字相同)。要收窄可见范围,
113
+ * 发布之后走菜单/共享权限那套命令,不在这里改。
114
+ */
115
+ export declare function everyoneShareMap(permissionType: number): Record<string, unknown>;
116
+ export interface PublishAppInput {
117
+ appId: string;
118
+ /** 前台显示名;不给就用应用名 */
119
+ menuName?: string;
120
+ /** 应用描述 → 前台的 `characterization`(不是 `description`,别填错格) */
121
+ characterization?: string;
122
+ scope?: string;
123
+ deptId: string;
124
+ /** 应用分类 id,默认「自定义」那一档 */
125
+ acId: string;
126
+ /** PC 图标 JSON 字符串,默认取应用自己的 iconPath */
127
+ icon?: string;
128
+ }
129
+ /**
130
+ * 发布到前台的报文。
131
+ *
132
+ * ⚠️ 与「改发布信息」(`buildSaveCustomApplicationBody`)**不是一套形状**:
133
+ * 这里要 `targetName/scope/innerUrl/innerUrlMobile/module/permissionShareMaps`,
134
+ * 那里一个都不要、反而要 `sysMenus.id`。别图省事复用一个构造器。
135
+ */
136
+ export declare function buildCreateCustomApplicationBody(input: PublishAppInput): Record<string, unknown>;
137
+ /** 发布到前台。返回的平台响应里不含自定义应用 id,需要另外读回。 */
138
+ export declare function publishAppToFront(client: ApiClient, baseUrl: string, body: Record<string, unknown>): Promise<any>;
139
+ /**
140
+ * 取消发布。**multipart**,只吃 `sysMenuId` + `displayClient`。
141
+ * ⚠️ 与同页面的「改发布信息」同域不同 content-type,最容易踩。
142
+ */
143
+ export declare function unpublishAppFromFront(client: ApiClient, baseUrl: string, sysMenuId: string): Promise<any>;
144
+ /**
145
+ * 已发布的前台应用列表。
146
+ *
147
+ * ⚠️ 这个路径是 **`baseserver`(ba-se)**,不是上面那些 `basicserver`(ba-si-cs)——
148
+ * 两个命名空间只差一个字母族,打错了就是 404,很容易找半天。
149
+ */
150
+ export declare const TENANT_APP_LIST_PATH = "/api/baseserver/queryTenantApplicationList";
151
+ export interface TenantApplication {
152
+ /** 就是 sysMenuId */
153
+ id: string;
154
+ /** 就是 Ebuilder 应用 id */
155
+ targetId: string;
156
+ menuname?: string;
157
+ status?: boolean;
158
+ [k: string]: unknown;
159
+ }
160
+ /**
161
+ * 拼列表 URL。
162
+ *
163
+ * ⚠️ `domainName` 要**再编码一次**:前端发出去的值本身就是 `encodeURIComponent(baseUrl)`,
164
+ * 交给 URLSearchParams 序列化后再叠一层,最终形如
165
+ * `domainName=https%253A%252F%252F...`。少编一层平台就认不出来。
166
+ */
167
+ export declare function buildTenantAppListUrl(baseUrl: string, deptId: string, displayClient?: string): string;
168
+ /**
169
+ * 把列表响应摊平。
170
+ *
171
+ * ⚠️ `data` **不是扁平的应用数组,是分组**:`[{groupName:'基本应用', menus:[...]}, …]`。
172
+ * 菜单项在 `menus` 里,系统菜单(门户/团队分享,id 是 `-6`/`-4` 这种负数)也混在一起;
173
+ * 我们要的那条靠 `targetId`(= Ebuilder 应用 id)过滤,别按位置取。
174
+ */
175
+ export declare function flattenTenantApps(data: unknown): TenantApplication[];
176
+ /** 拉已发布的前台应用列表(无 body,POST)。 */
177
+ export declare function queryTenantApplications(client: ApiClient, baseUrl: string, deptId: string): Promise<TenantApplication[]>;
178
+ /** 从列表里按 Ebuilder 应用 id 找它的前台 sysMenuId。**列表条目的 `id` 就是 sysMenuId。** */
179
+ export declare function findSysMenuId(list: TenantApplication[], appId: string): string;
180
+ /** 读一条前台自定义应用的完整配置。找不到(未发布)返回 `null`。 */
181
+ export declare function readCustomApplication(client: ApiClient, baseUrl: string, sysMenuId: string): Promise<Record<string, unknown> | null>;
182
+ /** 已发布的前台应用列表 + 回读:拿到某应用的 `sysMenus`(③ 改发布信息要用它 prefill)。 */
183
+ export declare function readAppPublishInfo(client: ApiClient, baseUrl: string, appId: string, deptId: string): Promise<{
184
+ sysMenuId: string;
185
+ sysMenus: Record<string, unknown> | null;
186
+ }>;
187
+ /**
188
+ * 「改发布信息」的 `sysMenus` **白名单**。
189
+ *
190
+ * ⚠️ 回读形状 ≠ 保存形状。回读多出来的 `pcUrlType/appUrlType/buildTerminal/navMode/`
191
+ * `menuSort/createTime/creator/appModule/applicationCustoms/appModuleLink/status` 前端**一个都不发**。
192
+ * 照抄回读整对象回写会把平台不认的键塞进去。
193
+ */
194
+ export declare const SAVE_SYSMENU_KEYS: readonly ["id", "menuname", "shortname", "description", "applicationType", "applicationRange", "icon", "mobileIcon", "appIconType", "appIconValue", "applyClient", "characterization", "curInstitution", "defaultSubSharing", "subDeptType", "subContain", "subPermission", "sysMenuShares", "menuTop", "syncStatus", "defaultMenu", "menuDisplay", "allowDomains", "mobileIconType", "mobileImgIcon", "cornerMark", "cornerMarkData", "pcCornerMark"];
195
+ /** 从回读对象里挑出保存形状的 `sysMenus`。 */
196
+ export declare function pickSaveSysMenus(readBack: Record<string, unknown>): Record<string, unknown>;
197
+ /**
198
+ * 「改发布信息」的报文。
199
+ *
200
+ * ⚠️ 与「发布到前台」(`buildCreateCustomApplicationBody`)**不是一套形状**:
201
+ * 这里要 `sysMenus.id`、`shareEdit`,**不要** `targetName/scope/innerUrl/module/permissionShareMaps`。
202
+ */
203
+ export declare function buildSaveCustomApplicationBody(input: {
204
+ appId: string;
205
+ /** 回读的 sysMenus(已按 pickSaveSysMenus 过滤) */
206
+ sysMenus: Record<string, unknown>;
207
+ deptId: string;
208
+ acId: string;
209
+ }): Record<string, unknown>;
210
+ /** 改发布信息。 */
211
+ export declare function saveCustomApplication(client: ApiClient, baseUrl: string, body: Record<string, unknown>): Promise<any>;
212
+ /** 取根机构号(发布/取消发布 body 里的 deptId)。响应是**裸字符串**。 */
213
+ export declare function queryRootDept(client: ApiClient, baseUrl: string): Promise<string>;
214
+ export interface AppCategory {
215
+ id: string;
216
+ name: string;
217
+ categoryType: string;
218
+ [k: string]: unknown;
219
+ }
220
+ /** 取应用分类表。⚠️ 响应**没有 code/status 包装**,是裸的 `{appTypes:[...]}`。 */
221
+ export declare function queryAppCategories(client: ApiClient, baseUrl: string, appId: string): Promise<AppCategory[]>;
222
+ /**
223
+ * 解析要用的应用分类 id:给了就用给的(先按 id 精确匹配,再按中文名匹配),
224
+ * 没给就落「自定义」(`categoryType === 'custom'`)—— 设计器默认也是这档。
225
+ */
226
+ export declare function resolveCategoryId(list: AppCategory[], input?: string): string;
227
+ //# sourceMappingURL=app-publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-publish.d.ts","sourceRoot":"","sources":["../../src/services/app-publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,403 @@
1
+ // ── 端点 ────────────────────────────────────────────────────────────────
2
+ /** 启用/停用。GET,参数 appId / appName(必带,中文要 URL 编码)。 */
3
+ export const ABLE_SWITCH_PATH = '/api/ebd/component/ableSwitch';
4
+ /** 发布到前台:新建一个前台自定义应用。JSON。 */
5
+ export const CREATE_CUSTOM_APP_PATH = '/api/basicserver/createCustomApplication';
6
+ /** 改发布信息。JSON,但要的是**回读形状的子集**,和发布那份不是一套。 */
7
+ export const SAVE_CUSTOM_APP_PATH = '/api/basicserver/saveCustomApplication';
8
+ /** 取消发布。**multipart**,只吃 sysMenuId + displayClient。 */
9
+ export const DELETE_CUSTOM_APP_PATH = '/api/basicserver/deleteCustomApplication';
10
+ /**
11
+ * 读一条已发布的前台自定义应用。**multipart**,只吃 sysMenuId。
12
+ * 命中回 `data.{sysMenuId, sysMenus}`,未命中只回 `{sysMenuId: "<传入值>"}`(**没有 sysMenus**)——
13
+ * 所以「未发布」的判据是**有没有 `sysMenus`**,不是看 code。
14
+ */
15
+ export const QUERY_FREE_APP_PATH = '/api/basicserver/free/queryFreeApplication';
16
+ /** 根机构号。发布/取消发布 body 里的 deptId 就是它。 */
17
+ export const QUERY_ROOT_DEPT_PATH = '/api/basicserver/app/manage/queryRootDept';
18
+ /** 应用分类表(汇报/协作/…/自定义)。⚠️ 响应**没有 code/status 包装**,是裸对象。 */
19
+ export const QUERY_APP_TYPES_PATH = '/api/basicserver/queryAppTypes';
20
+ /** 应用名多语文:读。 */
21
+ export const APP_ML_GETDATA_PATH = '/api/bs/ebuilder/app/multilangset/getdata';
22
+ /** 应用名多语文:写。 */
23
+ export const APP_ML_SAVEDATA_PATH = '/api/bs/ebuilder/app/multilangset/savedata';
24
+ /** 应用名多语文的「哪张表的哪个字段」——认记录靠这两把钥匙,不靠 targetId。 */
25
+ export const APP_ML_MODULE = 'ebuilder_app';
26
+ export const APP_ML_TABLEFIELD = 'ebda_app.name';
27
+ /** 停用时要带的档位参数(启用不带)。实测原值 8,含义未解,**照传**。 */
28
+ export const DISABLE_SWITCH_NUM = '8';
29
+ /**
30
+ * 前台自定义应用的应用类型。发布、取消发布都要带,固定 `'eBuilder'`。
31
+ * 注意 body 里它出现两种形状:发布是顶层 `module:{moduleStr}`,取消发布没有。
32
+ */
33
+ export const CUSTOM_APP_MODULE = 'eBuilder';
34
+ /** 发布/取消发布都带的前端标识。 */
35
+ export const DISPLAY_CLIENT = 'pc';
36
+ // ── 启用 / 停用 ─────────────────────────────────────────────────────────
37
+ /**
38
+ * 拼启用/停用的 URL。
39
+ *
40
+ * `appName` 是**必带的**,平台拿它对不上会拒。老坑:`appName` 是中文时,
41
+ * 走 shell 内联会变 GBK —— 所以这里**一律由本函数做 URL 编码**,调用方只管传原文。
42
+ */
43
+ export function buildAbleSwitchUrl(baseUrl, appId, appName, on) {
44
+ const verb = on ? 'enableEbApp' : 'disableEbApp';
45
+ const params = new URLSearchParams();
46
+ params.set('appId', appId);
47
+ params.set('appName', appName);
48
+ if (!on)
49
+ params.set('switchNum', DISABLE_SWITCH_NUM);
50
+ return `${baseUrl}${ABLE_SWITCH_PATH}/${verb}?${params.toString()}`;
51
+ }
52
+ /**
53
+ * 启用/停用应用。
54
+ *
55
+ * 语义(实测):这一条**同时翻 `publishEnabled` 和 `publishEteams`** ——
56
+ * 停用会把「已发布到 eteams」一并收掉,这正是界面那句
57
+ * 「应用暂未启用,启用后才可以发布给成员使用」的由来。
58
+ *
59
+ * 取值:`1` 启用、`2` 停用、`0` 从未启用。
60
+ */
61
+ export async function setAppEnabled(client, baseUrl, appId, appName, on) {
62
+ const res = await client.get(buildAbleSwitchUrl(baseUrl, appId, appName, on));
63
+ if (res?.code !== 200 || res?.status === false) {
64
+ throw new Error(`${on ? '启用' : '停用'}应用失败: ${res?.msg || '未知错误'}`);
65
+ }
66
+ return res?.data || {};
67
+ }
68
+ /**
69
+ * 读应用名的各语言译文。
70
+ *
71
+ * ⚠️ **`targetId` 必须传应用的 `nameLabelId`,传空串只会读回一张空白模板**
72
+ * (2026-10-13 实测:传空串时两行 `value` 都是 `''`,而且行 `id` 每次重生成)。
73
+ * 前端那条读之所以传空串,是因为它走的是「新建标签」路径,不是「读已有」。
74
+ */
75
+ export async function readAppLangRows(client, baseUrl, nameLabelId) {
76
+ const res = await client.post(`${baseUrl}${APP_ML_GETDATA_PATH}`, {
77
+ module: APP_ML_MODULE,
78
+ tablefield: APP_ML_TABLEFIELD,
79
+ targetId: nameLabelId || '',
80
+ versionEnable: false,
81
+ });
82
+ if (res?.code !== 200 || res?.status === false) {
83
+ throw new Error(`读取应用名称多语言失败: ${res?.msg || '未知错误'}`);
84
+ }
85
+ return res?.data?.usernamePerLangs || [];
86
+ }
87
+ /**
88
+ * 保存应用名的多语言,返回要挂回应用记录的 `nameLabelId`。
89
+ *
90
+ * 两态响应键名不同,**两个都要兜**(实测):
91
+ * - `targetId` 传空 → 平台新造一个,回 `data.new_targetId`
92
+ * - `targetId` 传已有 → 原地更新,回 `data.targetId`(同一个号)
93
+ *
94
+ * ⚠️ 行里的 `id` 是**前端行标识,每次读都重生成**,照抄即可,
95
+ * 但**绝不能用它定位记录** —— 定位靠 `targetId + module + tablefield + langtype`。
96
+ */
97
+ export async function saveAppLangRows(client, baseUrl, rows, values, targetId) {
98
+ const tableData = rows
99
+ .filter((r) => values[r.langtype] !== undefined)
100
+ .map((r) => ({ ...r, value: values[r.langtype] }));
101
+ if (!tableData.length)
102
+ throw new Error('没有要写入的语言(至少给 --zh 或 --en 之一)');
103
+ const res = await client.post(`${baseUrl}${APP_ML_SAVEDATA_PATH}`, {
104
+ module: APP_ML_MODULE,
105
+ tablefield: APP_ML_TABLEFIELD,
106
+ targetId: targetId || '',
107
+ versionEnable: false,
108
+ tableData,
109
+ usernamePerLangs: rows.map((r) => ({ ...r, value: '' })),
110
+ });
111
+ if (res?.code !== 200 || res?.status === false) {
112
+ throw new Error(`保存应用名称多语言失败: ${res?.msg || '未知错误'}`);
113
+ }
114
+ return resolveSavedLabelId(res);
115
+ }
116
+ /** 保存响应里取 `nameLabelId`。新建回 `new_targetId`、更新回 `targetId`,两态都要兜。 */
117
+ export function resolveSavedLabelId(res) {
118
+ const id = String(res?.data?.targetId || res?.data?.new_targetId || '');
119
+ if (!id)
120
+ throw new Error('保存应用名称多语言后未返回 targetId/new_targetId');
121
+ return id;
122
+ }
123
+ /** 从语言行里取某语言的译文。 */
124
+ export function langValueOf(rows, langtype) {
125
+ return String(rows.find((r) => r.langtype === langtype)?.value ?? '');
126
+ }
127
+ // ── 发布到前台 / 取消发布 ────────────────────────────────────────────────
128
+ /** 前台应用的入口地址。发布时要显式登记,少一条前台点进去是白页。 */
129
+ export function innerUrlOf(appId) {
130
+ return `/ebdapp/view/${appId}`;
131
+ }
132
+ export function innerUrlMobileOf(appId) {
133
+ return `/mobile/ebdapp/view/${appId}`;
134
+ }
135
+ /** 平台自带的手机端默认图,前端发的是这个固定路径。 */
136
+ export const DEFAULT_MOBILE_IMG_ICON = '/build/manager/static/media/defaultMobileAppImg.png';
137
+ /** 由应用图标(PC)派生手机端图标 —— 前端就是这么拼的(白字 + 底色)。 */
138
+ export function mobileIconFrom(iconJson) {
139
+ try {
140
+ const o = JSON.parse(iconJson);
141
+ const style = { ...(o?.style || {}) };
142
+ style.color = '#ffffff';
143
+ style.fillType = 'backgroundColor';
144
+ if (!style.bgColor)
145
+ style.bgColor = style.borderColor || '#FF8503';
146
+ return JSON.stringify({ path: o?.path || '#icon-custom01-o', style, iconDisplayType: 'line' });
147
+ }
148
+ catch {
149
+ return iconJson;
150
+ }
151
+ }
152
+ /**
153
+ * 「所有人」共享条目。发布时默认按所有人可见 —— 前端发的就是这两条
154
+ * (`permissionType` 0 和 2 各一条,其余键逐字相同)。要收窄可见范围,
155
+ * 发布之后走菜单/共享权限那套命令,不在这里改。
156
+ */
157
+ export function everyoneShareMap(permissionType) {
158
+ return {
159
+ permissionId: 'share', icon: 'Icon-all02', hq: false, type: false,
160
+ content: '所有人', browserType: 'all', download: true,
161
+ obj_id_span: '所有人', targetSubBordinateInclude: false, extra: false,
162
+ objIdList: ['所有人'], objType: 'all', objTypeSpan: '所有人',
163
+ permissionType, obj_id: '所有人', targetId: '0', level: '',
164
+ _entityType: 'all', targetType: 11, sourceType: 1,
165
+ browserTypeStr: 'all', name: '所有人', targetSupBordinateInclude: false,
166
+ };
167
+ }
168
+ /**
169
+ * 发布到前台的报文。
170
+ *
171
+ * ⚠️ 与「改发布信息」(`buildSaveCustomApplicationBody`)**不是一套形状**:
172
+ * 这里要 `targetName/scope/innerUrl/innerUrlMobile/module/permissionShareMaps`,
173
+ * 那里一个都不要、反而要 `sysMenus.id`。别图省事复用一个构造器。
174
+ */
175
+ export function buildCreateCustomApplicationBody(input) {
176
+ const name = input.menuName || '';
177
+ const icon = input.icon || JSON.stringify({
178
+ path: '#icon-eBuilder-o',
179
+ style: { color: '#5d9cec', fillType: 'borderColor', borderColor: '#5d9cec' },
180
+ });
181
+ return {
182
+ targetId: input.appId,
183
+ targetName: name,
184
+ scope: input.scope || 'PC_MOBILE',
185
+ innerUrl: innerUrlOf(input.appId),
186
+ innerUrlMobile: innerUrlMobileOf(input.appId),
187
+ sysMenus: {
188
+ menuname: name,
189
+ shortname: name,
190
+ characterization: input.characterization || '',
191
+ description: '',
192
+ applicationType: CUSTOM_APP_MODULE,
193
+ applicationRange: 'company',
194
+ icon,
195
+ mobileIcon: mobileIconFrom(icon),
196
+ appIconType: '',
197
+ appIconValue: '',
198
+ mobileIconSvg: '',
199
+ cornerMark: '0',
200
+ pcCornerMark: '0',
201
+ cornerMarkData: '',
202
+ applyClient: '1',
203
+ cornerMarkIcon: '',
204
+ pcCornerMarkIcon: '',
205
+ curInstitution: '0',
206
+ defaultSubSharing: '0',
207
+ subDeptType: '0',
208
+ subContain: '0',
209
+ subPermission: '0',
210
+ sysMenuShares: [],
211
+ menuTop: '0',
212
+ syncStatus: '0',
213
+ defaultMenu: '0',
214
+ menuDisplay: '1',
215
+ allowDomains: '',
216
+ mobileIconType: 'ebcoms',
217
+ mobileImgIcon: DEFAULT_MOBILE_IMG_ICON,
218
+ specificAppDispaly: '1',
219
+ },
220
+ module: { moduleStr: CUSTOM_APP_MODULE },
221
+ acId: input.acId,
222
+ status: true,
223
+ // ⚠️ 前端这里发了**两条一模一样**的;原样保留(平台可能按「条数>0」判可见范围)
224
+ shares: [
225
+ { module: CUSTOM_APP_MODULE, sid: '0', entryType: 'all' },
226
+ { module: CUSTOM_APP_MODULE, sid: '0', entryType: 'all' },
227
+ ],
228
+ permissionShareMaps: [everyoneShareMap(0), everyoneShareMap(2)],
229
+ deptId: input.deptId,
230
+ displayClient: DISPLAY_CLIENT,
231
+ };
232
+ }
233
+ /** 发布到前台。返回的平台响应里不含自定义应用 id,需要另外读回。 */
234
+ export async function publishAppToFront(client, baseUrl, body) {
235
+ const res = await client.post(`${baseUrl}${CREATE_CUSTOM_APP_PATH}`, body);
236
+ if (res?.code !== 200 || res?.status === false) {
237
+ throw new Error(`发布到前台失败: ${res?.msg || '未知错误'}`);
238
+ }
239
+ return res;
240
+ }
241
+ /**
242
+ * 取消发布。**multipart**,只吃 `sysMenuId` + `displayClient`。
243
+ * ⚠️ 与同页面的「改发布信息」同域不同 content-type,最容易踩。
244
+ */
245
+ export async function unpublishAppFromFront(client, baseUrl, sysMenuId) {
246
+ const form = new FormData();
247
+ form.append('sysMenuId', sysMenuId);
248
+ form.append('displayClient', DISPLAY_CLIENT);
249
+ const res = await client.postMultipart(`${baseUrl}${DELETE_CUSTOM_APP_PATH}`, form);
250
+ if (res?.code !== 200 || res?.status === false) {
251
+ throw new Error(`取消发布失败: ${res?.msg || '未知错误'}`);
252
+ }
253
+ return res;
254
+ }
255
+ /**
256
+ * 已发布的前台应用列表。
257
+ *
258
+ * ⚠️ 这个路径是 **`baseserver`(ba-se)**,不是上面那些 `basicserver`(ba-si-cs)——
259
+ * 两个命名空间只差一个字母族,打错了就是 404,很容易找半天。
260
+ */
261
+ export const TENANT_APP_LIST_PATH = '/api/baseserver/queryTenantApplicationList';
262
+ /**
263
+ * 拼列表 URL。
264
+ *
265
+ * ⚠️ `domainName` 要**再编码一次**:前端发出去的值本身就是 `encodeURIComponent(baseUrl)`,
266
+ * 交给 URLSearchParams 序列化后再叠一层,最终形如
267
+ * `domainName=https%253A%252F%252F...`。少编一层平台就认不出来。
268
+ */
269
+ export function buildTenantAppListUrl(baseUrl, deptId, displayClient = DISPLAY_CLIENT) {
270
+ const params = new URLSearchParams();
271
+ params.set('teamOnly', 'true');
272
+ params.set('loadAll', 'true');
273
+ params.set('deptId', deptId);
274
+ params.set('keywords', '');
275
+ params.set('displayClient', displayClient);
276
+ params.set('domainName', encodeURIComponent(baseUrl));
277
+ return `${baseUrl}${TENANT_APP_LIST_PATH}?${params.toString()}`;
278
+ }
279
+ /**
280
+ * 把列表响应摊平。
281
+ *
282
+ * ⚠️ `data` **不是扁平的应用数组,是分组**:`[{groupName:'基本应用', menus:[...]}, …]`。
283
+ * 菜单项在 `menus` 里,系统菜单(门户/团队分享,id 是 `-6`/`-4` 这种负数)也混在一起;
284
+ * 我们要的那条靠 `targetId`(= Ebuilder 应用 id)过滤,别按位置取。
285
+ */
286
+ export function flattenTenantApps(data) {
287
+ if (!Array.isArray(data))
288
+ return [];
289
+ const out = [];
290
+ for (const item of data) {
291
+ if (Array.isArray(item?.menus))
292
+ out.push(...item.menus);
293
+ else if (item?.targetId)
294
+ out.push(item);
295
+ }
296
+ return out;
297
+ }
298
+ /** 拉已发布的前台应用列表(无 body,POST)。 */
299
+ export async function queryTenantApplications(client, baseUrl, deptId) {
300
+ const res = await client.post(buildTenantAppListUrl(baseUrl, deptId), undefined);
301
+ if (res?.code !== 200 || res?.status === false) {
302
+ throw new Error(`查询前台应用列表失败: ${res?.msg || '未知错误'}`);
303
+ }
304
+ return flattenTenantApps(res?.data);
305
+ }
306
+ /** 从列表里按 Ebuilder 应用 id 找它的前台 sysMenuId。**列表条目的 `id` 就是 sysMenuId。** */
307
+ export function findSysMenuId(list, appId) {
308
+ const hit = list.find((a) => String(a.targetId) === String(appId));
309
+ return String(hit?.id || '');
310
+ }
311
+ /** 读一条前台自定义应用的完整配置。找不到(未发布)返回 `null`。 */
312
+ export async function readCustomApplication(client, baseUrl, sysMenuId) {
313
+ const form = new FormData();
314
+ form.append('sysMenuId', sysMenuId);
315
+ const res = await client.postMultipart(`${baseUrl}${QUERY_FREE_APP_PATH}`, form);
316
+ const data = res?.data ?? res;
317
+ return data?.sysMenus ? data.sysMenus : null;
318
+ }
319
+ /** 已发布的前台应用列表 + 回读:拿到某应用的 `sysMenus`(③ 改发布信息要用它 prefill)。 */
320
+ export async function readAppPublishInfo(client, baseUrl, appId, deptId) {
321
+ const list = await queryTenantApplications(client, baseUrl, deptId);
322
+ const sysMenuId = findSysMenuId(list, appId);
323
+ if (!sysMenuId)
324
+ return { sysMenuId: '', sysMenus: null };
325
+ return { sysMenuId, sysMenus: await readCustomApplication(client, baseUrl, sysMenuId) };
326
+ }
327
+ /**
328
+ * 「改发布信息」的 `sysMenus` **白名单**。
329
+ *
330
+ * ⚠️ 回读形状 ≠ 保存形状。回读多出来的 `pcUrlType/appUrlType/buildTerminal/navMode/`
331
+ * `menuSort/createTime/creator/appModule/applicationCustoms/appModuleLink/status` 前端**一个都不发**。
332
+ * 照抄回读整对象回写会把平台不认的键塞进去。
333
+ */
334
+ export const SAVE_SYSMENU_KEYS = [
335
+ 'id', 'menuname', 'shortname', 'description', 'applicationType', 'applicationRange',
336
+ 'icon', 'mobileIcon', 'appIconType', 'appIconValue', 'applyClient', 'characterization',
337
+ 'curInstitution', 'defaultSubSharing', 'subDeptType', 'subContain', 'subPermission',
338
+ 'sysMenuShares', 'menuTop', 'syncStatus', 'defaultMenu', 'menuDisplay', 'allowDomains',
339
+ 'mobileIconType', 'mobileImgIcon', 'cornerMark', 'cornerMarkData', 'pcCornerMark',
340
+ ];
341
+ /** 从回读对象里挑出保存形状的 `sysMenus`。 */
342
+ export function pickSaveSysMenus(readBack) {
343
+ const out = {};
344
+ for (const k of SAVE_SYSMENU_KEYS)
345
+ if (readBack[k] !== undefined)
346
+ out[k] = readBack[k];
347
+ return out;
348
+ }
349
+ /**
350
+ * 「改发布信息」的报文。
351
+ *
352
+ * ⚠️ 与「发布到前台」(`buildCreateCustomApplicationBody`)**不是一套形状**:
353
+ * 这里要 `sysMenus.id`、`shareEdit`,**不要** `targetName/scope/innerUrl/module/permissionShareMaps`。
354
+ */
355
+ export function buildSaveCustomApplicationBody(input) {
356
+ return {
357
+ targetId: input.appId,
358
+ sysMenus: input.sysMenus,
359
+ status: true,
360
+ shares: [],
361
+ shareEdit: false,
362
+ deptId: input.deptId,
363
+ acId: input.acId,
364
+ displayClient: DISPLAY_CLIENT,
365
+ };
366
+ }
367
+ /** 改发布信息。 */
368
+ export async function saveCustomApplication(client, baseUrl, body) {
369
+ const res = await client.post(`${baseUrl}${SAVE_CUSTOM_APP_PATH}`, body);
370
+ if (res?.code !== 200 || res?.status === false) {
371
+ throw new Error(`保存发布信息失败: ${res?.msg || '未知错误'}`);
372
+ }
373
+ return res;
374
+ }
375
+ /** 取根机构号(发布/取消发布 body 里的 deptId)。响应是**裸字符串**。 */
376
+ export async function queryRootDept(client, baseUrl) {
377
+ const res = await client.get(`${baseUrl}${QUERY_ROOT_DEPT_PATH}`);
378
+ const dept = typeof res === 'string' ? res : (res?.data ?? '');
379
+ return String(dept || '');
380
+ }
381
+ /** 取应用分类表。⚠️ 响应**没有 code/status 包装**,是裸的 `{appTypes:[...]}`。 */
382
+ export async function queryAppCategories(client, baseUrl, appId) {
383
+ const res = await client.get(`${baseUrl}${QUERY_APP_TYPES_PATH}?targetId=${encodeURIComponent(appId)}&deptId=`);
384
+ return (res?.appTypes || res?.data?.appTypes || []);
385
+ }
386
+ /**
387
+ * 解析要用的应用分类 id:给了就用给的(先按 id 精确匹配,再按中文名匹配),
388
+ * 没给就落「自定义」(`categoryType === 'custom'`)—— 设计器默认也是这档。
389
+ */
390
+ export function resolveCategoryId(list, input) {
391
+ if (input) {
392
+ const byId = list.find((t) => String(t.id) === String(input));
393
+ if (byId)
394
+ return String(byId.id);
395
+ const byName = list.find((t) => String(t.name) === String(input));
396
+ if (byName)
397
+ return String(byName.id);
398
+ throw new Error(`找不到应用分类「${input}」;可选:${list.map((t) => t.name).join(' / ')}`);
399
+ }
400
+ const custom = list.find((t) => t.categoryType === 'custom') || list[0];
401
+ return String(custom?.id || '');
402
+ }
403
+ //# sourceMappingURL=app-publish.js.map