openyida 2026.4.2 → 2026.4.14-beta.0
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 +3 -0
- package/bin/yida.js +42 -0
- package/lib/app/app-list.js +133 -0
- package/lib/app/create-app.js +1 -1
- package/lib/app/create-form.js +56 -9
- package/lib/app/create-page.js +2 -2
- package/lib/app/get-schema.js +1 -1
- package/lib/app/publish.js +105 -0
- package/lib/app/update-app.js +202 -0
- package/lib/auth/login.js +10 -14
- package/lib/auth/qr-login.js +4 -2
- package/lib/connector/action-generator.js +23 -9
- package/lib/connector/connector-smart-create.js +3 -1
- package/lib/core/check-data.js +514 -0
- package/lib/core/doctor.js +4 -4
- package/lib/core/env-cmd.js +384 -0
- package/lib/core/env-manager.js +218 -0
- package/lib/core/i18n.js +1 -1
- package/lib/core/locales/ar.js +24 -0
- package/lib/core/locales/de.js +24 -0
- package/lib/core/locales/en.js +256 -21
- package/lib/core/locales/es.js +24 -0
- package/lib/core/locales/fr.js +24 -0
- package/lib/core/locales/hi.js +24 -0
- package/lib/core/locales/ja.js +107 -21
- package/lib/core/locales/ko.js +24 -0
- package/lib/core/locales/pt.js +24 -0
- package/lib/core/locales/vi.js +24 -0
- package/lib/core/locales/zh-TW.js +122 -21
- package/lib/core/locales/zh.js +257 -21
- package/lib/core/query-data.js +36 -2
- package/lib/core/sample.js +145 -0
- package/lib/core/update.js +51 -0
- package/lib/core/utils.js +91 -9
- package/lib/db/db-seq-fix.js +436 -0
- package/lib/dws/dws-wrapper.js +21 -3
- package/lib/page-config/get-page-config.js +1 -1
- package/lib/page-config/save-share-config.js +1 -1
- package/lib/page-config/verify-short-url.js +2 -2
- package/lib/process/configure-process.js +8 -2
- package/lib/process/create-process.js +13 -0
- package/lib/process/preview-process.js +878 -0
- package/{yida-skills/skills/yida-custom-page/templates → lib/samples/yida-custom-page}/custom-page-template.js +48 -18
- package/package.json +1 -1
- package/project/pages/src/demo-chip-insight.js +3 -1
- package/project/pages/src/demo-ppt.js +1192 -0
- package/yida-skills/SKILL.md +32 -2
- package/yida-skills/references/yida-api.md +24 -1
- package/yida-skills/skills/large-file-write/SKILL.md +32 -43
- package/yida-skills/skills/large-file-write/references/write-patterns.md +124 -0
- package/yida-skills/skills/yida-app/SKILL.md +47 -14
- package/yida-skills/skills/yida-chart/SKILL.md +5 -5
- package/yida-skills/skills/yida-chart/{reference → references}/echarts-code-template.md +3 -3
- package/yida-skills/skills/yida-chart/references/examples.md +164 -0
- package/yida-skills/skills/yida-connector/SKILL.md +41 -1
- package/yida-skills/skills/yida-create-app/SKILL.md +19 -3
- package/yida-skills/skills/yida-create-form-page/SKILL.md +25 -1
- package/yida-skills/skills/yida-create-page/SKILL.md +23 -2
- package/yida-skills/skills/yida-create-process/SKILL.md +42 -2
- package/yida-skills/skills/yida-custom-page/SKILL.md +101 -239
- package/yida-skills/skills/yida-custom-page/examples/attachment-upload.js +223 -0
- package/yida-skills/skills/yida-custom-page/references/assets-guide.md +3 -3
- package/yida-skills/skills/yida-custom-page/references/attachment-upload-guide.md +459 -0
- package/yida-skills/skills/yida-custom-page/references/coding-guide.md +116 -86
- package/yida-skills/skills/yida-custom-page/references/design-system.md +4 -0
- package/yida-skills/skills/yida-data-management/SKILL.md +51 -0
- package/yida-skills/skills/yida-db-seq-fix/SKILL.md +110 -0
- package/yida-skills/skills/yida-density/SKILL.md +65 -246
- package/yida-skills/skills/yida-export-conversation/SKILL.md +39 -2
- package/yida-skills/skills/yida-flash-note-to-prd/SKILL.md +42 -250
- package/yida-skills/skills/yida-flash-note-to-prd/references/examples.md +124 -0
- package/yida-skills/skills/yida-flash-note-to-prd/references/flash-note-prd-template.md +42 -0
- package/yida-skills/skills/yida-flash-note-to-prd/references/flash-note-prompt.md +197 -0
- package/yida-skills/skills/yida-flash-note-to-prd/references/yida-field-types.md +20 -0
- package/yida-skills/skills/yida-form-permission/SKILL.md +36 -2
- package/yida-skills/skills/yida-formula/SKILL.md +37 -21
- package/yida-skills/skills/yida-formula/references/examples.md +149 -0
- package/yida-skills/skills/yida-get-schema/SKILL.md +35 -1
- package/yida-skills/skills/yida-integration/SKILL.md +71 -127
- package/yida-skills/skills/yida-integration/references/examples.md +119 -0
- package/yida-skills/skills/yida-integration/references/integration-node-schemas.md +377 -0
- package/yida-skills/skills/yida-login/SKILL.md +24 -2
- package/yida-skills/skills/yida-logout/SKILL.md +33 -1
- package/yida-skills/skills/yida-page-config/SKILL.md +36 -1
- package/yida-skills/skills/yida-ppt-slider/SKILL.md +750 -1
- package/yida-skills/skills/yida-ppt-slider/references/examples.md +381 -0
- package/yida-skills/skills/yida-process-rule/SKILL.md +30 -320
- package/yida-skills/skills/yida-process-rule/references/examples.md +344 -0
- package/yida-skills/skills/yida-publish-page/SKILL.md +56 -1
- package/yida-skills/skills/yida-report/SKILL.md +25 -341
- package/yida-skills/skills/yida-report/references/examples.md +145 -0
- package/yida-skills/skills/yida-report/references/report-api-guide.md +287 -0
- package/yida-skills/skills/yida-table-form/SKILL.md +65 -437
- package/yida-skills/skills/yida-table-form/references/examples.md +113 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/china-map.js +0 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/dashboard-bindform.js +0 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/line-trend.js +0 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/multi-bar-compare.js +0 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/radar-chart.js +0 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/scatter-bindform.js +0 -0
- /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/stacked-area.js +0 -0
- /package/{yida-skills/skills/yida-create-app/templates → lib/samples/yida-create-app}/ipd-app-template.js +0 -0
- /package/{yida-skills/skills/yida-custom-page/examples → lib/samples/yida-custom-page}/design-tokens.js +0 -0
- /package/{yida-skills/skills/yida-data-management/templates → lib/samples/yida-data-management}/form-field-template.js +0 -0
- /package/{yida-skills/skills/yida-density/examples → lib/samples/yida-density}/density-switch-page.js +0 -0
- /package/{yida-skills/skills/yida-table-form/examples → lib/samples/yida-table-form}/table-form-batch-submit.js +0 -0
- /package/yida-skills/skills/yida-chart/{reference → references}/echarts-bindding-guide.md +0 -0
- /package/yida-skills/skills/yida-chart/{reference → references}/echarts-design-spec.md +0 -0
package/README.md
CHANGED
|
@@ -99,7 +99,9 @@ openyida create-form # Create / update a form page
|
|
|
99
99
|
openyida create-page # Create a custom display page
|
|
100
100
|
openyida create-process # Create a process form (integrated)
|
|
101
101
|
openyida create-report # Create a Yida report
|
|
102
|
+
openyida process preview # Preview process instance (generate visual flowchart)
|
|
102
103
|
openyida data # Unified data management (form/process/task/subform)
|
|
104
|
+
openyida data check <appType> <formUuid> <rules.json> [options] # Detect anomalous records in process forms based on custom rules
|
|
103
105
|
openyida doctor # Environment diagnostics and auto-repair
|
|
104
106
|
openyida dws <command> [args] # DingTalk CLI (Contacts/Calendar/Todo/Approval, etc.)
|
|
105
107
|
openyida env # Detect current AI tool environment and login status
|
|
@@ -205,6 +207,7 @@ Thanks to everyone who has contributed to OpenYida! Read the [Contributing Guide
|
|
|
205
207
|
<a href="https://github.com/liug0911"><img src="https://avatars.githubusercontent.com/u/1578814?v=4&s=48" width="48" height="48" alt="LIUG" title="LIUG"/></a>
|
|
206
208
|
<a href="https://github.com/sunliz-xiuli"><img src="https://avatars.githubusercontent.com/u/76982855?v=4&s=48" width="48" height="48" alt="sunliz-xiuli" title="sunliz-xiuli"/></a>
|
|
207
209
|
<a href="https://github.com/M12REDX"><img src="https://avatars.githubusercontent.com/u/22703542?v=4&s=48" width="48" height="48" alt="M12REDX" title="M12REDX"/></a>
|
|
210
|
+
<a href="https://github.com/key-668"><img src="https://avatars.githubusercontent.com/u/270536058?v=4&s=48" width="48" height="48" alt="再不喝汽水" title="再不喝汽水"/></a>
|
|
208
211
|
</p>
|
|
209
212
|
|
|
210
213
|
---
|
package/bin/yida.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* openyida save-share-config <appType> <formUuid> <url> <isOpen> [openAuth] 保存公开访问/分享配置
|
|
27
27
|
* openyida get-page-config <appType> <formUuid> 查询页面公开访问/分享配置
|
|
28
28
|
* openyida update-form-config <appType> <formUuid> <isRenderNav> <title> 更新表单配置
|
|
29
|
+
* openyida update-app <appType> --name "新名称" [--desc "描述"] [--icon "图标"] 更新应用信息
|
|
29
30
|
* openyida data <action> <resource> [args] 统一数据管理(表单/流程/任务/子表单)
|
|
30
31
|
* openyida task-center <type> [--page N] [--size N] [--keyword TEXT] 全局任务中心(待办/我创建的/我已处理/抄送/代提交)
|
|
31
32
|
* openyida doctor [选项] 检查环境依赖,诊断应用问题
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
* openyida import <file> [name] 导入迁移包,在目标环境重建应用
|
|
34
35
|
* openyida get-permission <appType> <formUuid> 查询表单权限配置
|
|
35
36
|
* openyida save-permission <appType> <formUuid> [--data-permission <json>] [--action-permission <json>] 保存表单权限配置
|
|
37
|
+
* openyida process preview <appType> <processInstanceId> [--output <path>] 预览流程实例(生成可视化流程图)
|
|
36
38
|
* openyida connector list [选项] 列出 HTTP 连接器
|
|
37
39
|
* openyida connector create "名称" "域名" --operations <file> [选项] 创建连接器
|
|
38
40
|
* openyida connector detail <connector-id> 查看连接器详情
|
|
@@ -50,6 +52,7 @@
|
|
|
50
52
|
* openyida create-report <appType> "<报表名称>" <图表定义JSON或文件路径> 创建宜搭报表
|
|
51
53
|
* openyida append-chart <appType> <reportId> <图表定义JSON或文件路径> 向已有报表追加图表
|
|
52
54
|
* openyida dws <command> [args] 钉钉 CLI(通讯录/日历/待办/审批等)
|
|
55
|
+
* openyida update 检查并更新 openyida 到最新版本
|
|
53
56
|
*/
|
|
54
57
|
|
|
55
58
|
'use strict';
|
|
@@ -86,6 +89,7 @@ openyida - 宜搭命令行工具
|
|
|
86
89
|
save-share-config <appType> <formUuid> <url> <isOpen> [auth] 保存公开访问/分享配置
|
|
87
90
|
get-page-config <appType> <formUuid> 查询页面公开访问/分享配置
|
|
88
91
|
update-form-config <appType> <formUuid> <isRenderNav> <title> 更新表单配置
|
|
92
|
+
update-app <appType> --name "新名称" [--desc "描述"] [--icon "图标"] 更新应用信息
|
|
89
93
|
data <action> <resource> [args] 统一数据管理(表单/流程/任务/子表单)
|
|
90
94
|
doctor [选项] 检查环境依赖,诊断应用问题
|
|
91
95
|
--fix / --repair 诊断并自动修复
|
|
@@ -106,6 +110,7 @@ openyida - 宜搭命令行工具
|
|
|
106
110
|
configure-process <appType> <formUuid> <processDefinitionFile> [processCode] 配置并发布流程
|
|
107
111
|
create-process <appType> <formTitle> <fieldsJsonFile> <processDefinitionFile> 创建流程表单(一体化)
|
|
108
112
|
create-process <appType> --formUuid <formUuid> <processDefinitionFile> 复用已有表单创建流程
|
|
113
|
+
process preview <appType> <processInstanceId> [--output <path>] 预览流程实例(生成可视化流程图)
|
|
109
114
|
connector list [选项] 列出 HTTP 连接器
|
|
110
115
|
connector create "名称" "域名" --operations <file> [选项] 创建连接器
|
|
111
116
|
connector detail <connector-id> 查看连接器详情
|
|
@@ -120,6 +125,7 @@ openyida - 宜搭命令行工具
|
|
|
120
125
|
connector parse-api [选项] 解析接口信息
|
|
121
126
|
connector gen-template [输出路径] 生成接口文档模板
|
|
122
127
|
dws <command> [args] 钉钉 CLI(通讯录/日历/待办/审批等)
|
|
128
|
+
update 检查并更新 openyida 到最新版本
|
|
123
129
|
create-report <appType> "<报表名称>" <图表定义 JSON 或文件路径> 创建宜搭报表
|
|
124
130
|
append-chart <appType> <reportId> <图表定义 JSON 或文件路径> 向已有报表追加图表
|
|
125
131
|
export-conversation [选项] 导出 AI 对话记录
|
|
@@ -432,6 +438,17 @@ async function main() {
|
|
|
432
438
|
break;
|
|
433
439
|
}
|
|
434
440
|
|
|
441
|
+
case 'update-app': {
|
|
442
|
+
if (args.length < 2) {
|
|
443
|
+
console.error(t('cli.update_app_usage'));
|
|
444
|
+
console.error(t('cli.update_app_example'));
|
|
445
|
+
process.exit(1);
|
|
446
|
+
}
|
|
447
|
+
const { run: runUpdateApp } = require('../lib/app/update-app');
|
|
448
|
+
await runUpdateApp(args);
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
|
|
435
452
|
case 'data': {
|
|
436
453
|
if (args.length < 2) {
|
|
437
454
|
console.error('用法: openyida data <action> <resource> [args] [options]');
|
|
@@ -517,6 +534,25 @@ async function main() {
|
|
|
517
534
|
break;
|
|
518
535
|
}
|
|
519
536
|
|
|
537
|
+
case 'process': {
|
|
538
|
+
const subCommand = args[0];
|
|
539
|
+
const subArgs = args.slice(1);
|
|
540
|
+
|
|
541
|
+
if (subCommand === 'preview') {
|
|
542
|
+
if (subArgs.length < 2) {
|
|
543
|
+
console.error(t('cli.process_preview_usage'));
|
|
544
|
+
console.error(t('cli.process_preview_example'));
|
|
545
|
+
process.exit(1);
|
|
546
|
+
}
|
|
547
|
+
const { run: runPreviewProcess } = require('../lib/process/preview-process');
|
|
548
|
+
await runPreviewProcess(subArgs);
|
|
549
|
+
} else {
|
|
550
|
+
console.error(t('cli.process_usage'));
|
|
551
|
+
process.exit(1);
|
|
552
|
+
}
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
|
|
520
556
|
case 'create-report': {
|
|
521
557
|
const { run } = require('../lib/report/create-report');
|
|
522
558
|
await run(args);
|
|
@@ -659,6 +695,12 @@ async function main() {
|
|
|
659
695
|
break;
|
|
660
696
|
}
|
|
661
697
|
|
|
698
|
+
case 'update': {
|
|
699
|
+
const { runUpdate } = require('../lib/core/update');
|
|
700
|
+
await runUpdate(currentVersion);
|
|
701
|
+
break;
|
|
702
|
+
}
|
|
703
|
+
|
|
662
704
|
default: {
|
|
663
705
|
console.error(t('cli.unknown_command', command));
|
|
664
706
|
console.error(t('cli.run_help'));
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* app-list.js - 查询我的应用列表
|
|
3
|
+
*
|
|
4
|
+
* 用法:openyida app-list [--page <页码>] [--size <每页数量>]
|
|
5
|
+
*
|
|
6
|
+
* 输出字段:
|
|
7
|
+
* appName - 应用名称(zh_CN)
|
|
8
|
+
* appType - 应用唯一标识
|
|
9
|
+
* systemLink - 应用访问地址
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
loadCookieData,
|
|
16
|
+
triggerLogin,
|
|
17
|
+
resolveBaseUrl,
|
|
18
|
+
extractInfoFromCookies,
|
|
19
|
+
httpGet,
|
|
20
|
+
requestWithAutoLogin,
|
|
21
|
+
} = require('../core/utils');
|
|
22
|
+
const { t } = require('../core/i18n');
|
|
23
|
+
|
|
24
|
+
const API_PATH = '/query/app/getAppList.json';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 拉取单页应用列表
|
|
28
|
+
*/
|
|
29
|
+
function fetchAppListPage(auth, pageIndex, pageSize) {
|
|
30
|
+
const queryParams = {
|
|
31
|
+
_api: 'nattyFetch',
|
|
32
|
+
_mock: 'false',
|
|
33
|
+
pageIndex,
|
|
34
|
+
pageSize,
|
|
35
|
+
creator: auth.userId,
|
|
36
|
+
_csrf_token: auth.csrfToken,
|
|
37
|
+
_stamp: Date.now(),
|
|
38
|
+
};
|
|
39
|
+
return httpGet(auth.baseUrl, API_PATH, queryParams, auth.cookies);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 拉取全量应用列表(自动翻页)
|
|
44
|
+
*/
|
|
45
|
+
async function fetchAllApps(auth, pageSize) {
|
|
46
|
+
const firstResult = await fetchAppListPage(auth, 1, pageSize);
|
|
47
|
+
|
|
48
|
+
if (!firstResult.success) {
|
|
49
|
+
throw new Error(firstResult.errorMsg || '查询应用列表失败');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const { data: firstPageData, totalCount } = firstResult.content;
|
|
53
|
+
const allApps = [...firstPageData];
|
|
54
|
+
|
|
55
|
+
const totalPages = Math.ceil(totalCount / pageSize);
|
|
56
|
+
const remainingFetches = [];
|
|
57
|
+
|
|
58
|
+
for (let pageIndex = 2; pageIndex <= totalPages; pageIndex++) {
|
|
59
|
+
remainingFetches.push(fetchAppListPage(auth, pageIndex, pageSize));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const remainingResults = await Promise.all(remainingFetches);
|
|
63
|
+
for (const result of remainingResults) {
|
|
64
|
+
if (result.success && result.content && result.content.data) {
|
|
65
|
+
allApps.push(...result.content.data);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return allApps;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 将应用原始数据提取为输出字段
|
|
74
|
+
*/
|
|
75
|
+
function formatApp(app) {
|
|
76
|
+
return {
|
|
77
|
+
appName: (app.appName && app.appName.zh_CN) || '',
|
|
78
|
+
appType: app.appType || '',
|
|
79
|
+
systemLink: app.systemLink || '',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* app-list 命令主入口
|
|
85
|
+
* @param {string[]} args
|
|
86
|
+
*/
|
|
87
|
+
async function run(args) {
|
|
88
|
+
const pageSizeIndex = args.indexOf('--size');
|
|
89
|
+
const pageSize = pageSizeIndex !== -1 && args[pageSizeIndex + 1]
|
|
90
|
+
? parseInt(args[pageSizeIndex + 1], 10)
|
|
91
|
+
: 20;
|
|
92
|
+
|
|
93
|
+
let cookieData = await loadCookieData();
|
|
94
|
+
if (!cookieData) {
|
|
95
|
+
cookieData = await triggerLogin();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const baseUrl = resolveBaseUrl(cookieData);
|
|
99
|
+
const { csrfToken, userId } = extractInfoFromCookies(cookieData.cookies);
|
|
100
|
+
const authRef = { baseUrl, cookies: cookieData.cookies, csrfToken, userId };
|
|
101
|
+
|
|
102
|
+
let apps;
|
|
103
|
+
try {
|
|
104
|
+
apps = await requestWithAutoLogin(
|
|
105
|
+
(auth) => fetchAllApps(
|
|
106
|
+
{ baseUrl: auth.baseUrl, cookies: auth.cookies, csrfToken: auth.csrfToken, userId: auth.userId },
|
|
107
|
+
pageSize
|
|
108
|
+
),
|
|
109
|
+
authRef
|
|
110
|
+
);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
console.error(`查询应用列表失败:${err.message}`);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!apps || apps.length === 0) {
|
|
117
|
+
console.log('暂无应用');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const formattedApps = apps.map(formatApp);
|
|
122
|
+
|
|
123
|
+
// stdout 输出 JSON,方便 AI 工具解析
|
|
124
|
+
console.log(JSON.stringify(formattedApps, null, 2));
|
|
125
|
+
|
|
126
|
+
// stderr 输出人类可读摘要
|
|
127
|
+
console.error(`\n共找到 ${formattedApps.length} 个应用:`);
|
|
128
|
+
for (const app of formattedApps) {
|
|
129
|
+
console.error(` • ${app.appName} [${app.appType}] ${app.systemLink}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = { run };
|
package/lib/app/create-app.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* create-app.js - 宜搭应用创建命令
|
|
3
3
|
*
|
|
4
|
-
* 用法:
|
|
4
|
+
* 用法:openyida create-app "<appName>" [description] [icon] [iconColor] [colour] [navTheme] [layoutDirection]
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
package/lib/app/create-form.js
CHANGED
|
@@ -101,7 +101,7 @@ function parseArgs() {
|
|
|
101
101
|
// 复制一份 args 用于解析(避免修改原始数组影响后续处理)
|
|
102
102
|
const args = [...rawArgs];
|
|
103
103
|
|
|
104
|
-
// 解析 --layout, --theme, --label-align 参数
|
|
104
|
+
// 解析 --layout, --theme, --label-align, --force 参数
|
|
105
105
|
for (let i = 0; i < args.length; i++) {
|
|
106
106
|
if (args[i] === '--layout' && i + 1 < args.length) {
|
|
107
107
|
options.layout = args[i + 1];
|
|
@@ -115,6 +115,10 @@ function parseArgs() {
|
|
|
115
115
|
options.labelAlign = args[i + 1];
|
|
116
116
|
args.splice(i, 2);
|
|
117
117
|
i--;
|
|
118
|
+
} else if (args[i] === '--force') {
|
|
119
|
+
options.force = true;
|
|
120
|
+
args.splice(i, 1);
|
|
121
|
+
i--;
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
124
|
|
|
@@ -1463,8 +1467,11 @@ function buildFormSchema(formTitle, fields, formUuid, corpId, appType, layout, t
|
|
|
1463
1467
|
type: 'FUNCTION',
|
|
1464
1468
|
list: [
|
|
1465
1469
|
{
|
|
1466
|
-
id:
|
|
1467
|
-
|
|
1470
|
+
id: nextNodeId(),
|
|
1471
|
+
type: 'lifeCycleEvent',
|
|
1472
|
+
name: 'didMount',
|
|
1473
|
+
relatedEventId: 'lifecycle:didMount',
|
|
1474
|
+
params: {},
|
|
1468
1475
|
},
|
|
1469
1476
|
],
|
|
1470
1477
|
},
|
|
@@ -2404,8 +2411,48 @@ async function mainUpdate(parsedArgs, csrfToken, cookies, baseUrl, cookieData) {
|
|
|
2404
2411
|
console.error(t('create_form.schema_got_empty'));
|
|
2405
2412
|
}
|
|
2406
2413
|
|
|
2407
|
-
// Step 3:
|
|
2408
|
-
console.error(t('create_form.
|
|
2414
|
+
// Step 3: 检查表单是否已有数据
|
|
2415
|
+
console.error(t('create_form.step_check_data', 3));
|
|
2416
|
+
const dataCheckResult = await requestWithAutoLogin(function (auth) {
|
|
2417
|
+
return sendGetRequest(
|
|
2418
|
+
auth.baseUrl, auth.cookies,
|
|
2419
|
+
'/dingtalk/web/' + appType + '/v1/form/searchFormDatas.json',
|
|
2420
|
+
{ formUuid: formUuid, appType: appType, currentPage: '1', pageSize: '1' }
|
|
2421
|
+
);
|
|
2422
|
+
}, authRef);
|
|
2423
|
+
|
|
2424
|
+
let existingDataCount = 0;
|
|
2425
|
+
if (dataCheckResult && dataCheckResult.content && typeof dataCheckResult.content.totalCount === 'number') {
|
|
2426
|
+
existingDataCount = dataCheckResult.content.totalCount;
|
|
2427
|
+
} else if (dataCheckResult && typeof dataCheckResult.totalCount === 'number') {
|
|
2428
|
+
existingDataCount = dataCheckResult.totalCount;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
if (existingDataCount > 0) {
|
|
2432
|
+
console.error(t('create_form.data_exists_warning', existingDataCount));
|
|
2433
|
+
console.error(t('create_form.data_exists_impact'));
|
|
2434
|
+
|
|
2435
|
+
if (!parsedArgs.force) {
|
|
2436
|
+
console.error(t('create_form.data_exists_abort'));
|
|
2437
|
+
console.log(JSON.stringify({
|
|
2438
|
+
success: false,
|
|
2439
|
+
requiresConfirmation: true,
|
|
2440
|
+
formUuid: formUuid,
|
|
2441
|
+
appType: appType,
|
|
2442
|
+
existingDataCount: existingDataCount,
|
|
2443
|
+
message: t('create_form.data_exists_confirm_message', existingDataCount),
|
|
2444
|
+
hint: t('create_form.data_exists_force_hint'),
|
|
2445
|
+
}));
|
|
2446
|
+
process.exit(0);
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
console.error(t('create_form.data_exists_force_proceed', existingDataCount));
|
|
2450
|
+
} else {
|
|
2451
|
+
console.error(t('create_form.data_check_empty'));
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
// Step 4: 读取修改定义
|
|
2455
|
+
console.error(t('create_form.step_read_changes', 4));
|
|
2409
2456
|
const changes = readChangesDefinition(changesJsonOrFile);
|
|
2410
2457
|
console.error(t('create_form.changes_loaded', changes.length));
|
|
2411
2458
|
changes.forEach(function (change, changeIndex) {
|
|
@@ -2418,8 +2465,8 @@ async function mainUpdate(parsedArgs, csrfToken, cookies, baseUrl, cookieData) {
|
|
|
2418
2465
|
}
|
|
2419
2466
|
});
|
|
2420
2467
|
|
|
2421
|
-
// Step
|
|
2422
|
-
console.error(t('create_form.step_apply_changes',
|
|
2468
|
+
// Step 5: 应用修改
|
|
2469
|
+
console.error(t('create_form.step_apply_changes', 5));
|
|
2423
2470
|
const appliedChanges = applyChangesToSchema(schema, changes);
|
|
2424
2471
|
|
|
2425
2472
|
// 为 SerialNumberField 补全 formula(若尚未设置)
|
|
@@ -2433,8 +2480,8 @@ async function mainUpdate(parsedArgs, csrfToken, cookies, baseUrl, cookieData) {
|
|
|
2433
2480
|
fillSerialNumberFormulas(formContainerUpdate.children, corpId, appType, formUuid);
|
|
2434
2481
|
}
|
|
2435
2482
|
|
|
2436
|
-
// Step
|
|
2437
|
-
const { configResult } = await saveSchemaAndUpdateConfig(authRef, appType, formUuid, schema, version,
|
|
2483
|
+
// Step 6 & 7: 保存 Schema 并更新表单配置
|
|
2484
|
+
const { configResult } = await saveSchemaAndUpdateConfig(authRef, appType, formUuid, schema, version, 6);
|
|
2438
2485
|
|
|
2439
2486
|
// 输出结果
|
|
2440
2487
|
const SEP2 = '='.repeat(50);
|
package/lib/app/create-page.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* create-page.js - 宜搭自定义页面创建命令
|
|
3
3
|
*
|
|
4
|
-
* 用法:
|
|
4
|
+
* 用法:openyida create-page <appType> "<pageName>"
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
@@ -81,7 +81,7 @@ async function run(args) {
|
|
|
81
81
|
|
|
82
82
|
console.log(JSON.stringify({ success: true, pageId, pageName, appType, url: pageUrl }));
|
|
83
83
|
} else {
|
|
84
|
-
const errorMsg = response ? response.errorMsg || t('common.unknown_error') : t('common.request_failed');
|
|
84
|
+
const errorMsg = response ? response.errorMsg || response.error || t('common.unknown_error') : t('common.request_failed');
|
|
85
85
|
console.error(t('create_page.failed', errorMsg));
|
|
86
86
|
console.error(SEP2);
|
|
87
87
|
console.log(JSON.stringify({ success: false, error: errorMsg }));
|
package/lib/app/get-schema.js
CHANGED
package/lib/app/publish.js
CHANGED
|
@@ -71,6 +71,12 @@ function lintYidaSource(sourceCode, _filePath) {
|
|
|
71
71
|
// 警告级别:使用 const 或 let 声明变量
|
|
72
72
|
const constLetRegex = /\b(const|let)\s+/;
|
|
73
73
|
|
|
74
|
+
// 警告级别:ES6 计算属性名 { [expr]: value } — 宜搭 JS 引擎会静默失败
|
|
75
|
+
const computedPropertyRegex = /\{\s*\[/;
|
|
76
|
+
|
|
77
|
+
// 警告级别:padStart / padEnd — 宜搭 JS 引擎不支持,会静默中断
|
|
78
|
+
const padMethodRegex = /\.(padStart|padEnd)\s*\(/;
|
|
79
|
+
|
|
74
80
|
// 用于排除注释和字符串内的简单检测
|
|
75
81
|
function isInCommentOrString(line, matchIndex) {
|
|
76
82
|
const beforeMatch = line.substring(0, matchIndex);
|
|
@@ -83,6 +89,69 @@ function lintYidaSource(sourceCode, _filePath) {
|
|
|
83
89
|
return quotes % 2 !== 0;
|
|
84
90
|
}
|
|
85
91
|
|
|
92
|
+
// 警告级别:Promise .then() 回调代码量过大(超过 50 行会被静默截断)
|
|
93
|
+
const THEN_CALLBACK_LINE_LIMIT = 50;
|
|
94
|
+
const thenStartRegex = /\.then\s*\(\s*(function\s*\(|(\([^)]*\)|[a-zA-Z_$]\w*)\s*=>)/;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 检测 .then() 回调是否超过行数限制。
|
|
98
|
+
* 通过简单的花括号计数来追踪回调体的起止。
|
|
99
|
+
*/
|
|
100
|
+
function detectLargeThenCallbacks(lines) {
|
|
101
|
+
const results = [];
|
|
102
|
+
let inThenCallback = false;
|
|
103
|
+
let braceDepth = 0;
|
|
104
|
+
let thenStartLine = 0;
|
|
105
|
+
let thenBodyStartLine = 0;
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < lines.length; i++) {
|
|
108
|
+
const line = lines[i];
|
|
109
|
+
const trimmed = line.trim();
|
|
110
|
+
|
|
111
|
+
// 跳过注释行
|
|
112
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!inThenCallback) {
|
|
117
|
+
const thenMatch = line.match(thenStartRegex);
|
|
118
|
+
if (thenMatch && !isInCommentOrString(line, thenMatch.index)) {
|
|
119
|
+
// 找到 .then( 的起始,开始追踪花括号
|
|
120
|
+
inThenCallback = true;
|
|
121
|
+
thenStartLine = i + 1;
|
|
122
|
+
braceDepth = 0;
|
|
123
|
+
|
|
124
|
+
// 统计当前行的花括号
|
|
125
|
+
const afterMatch = line.substring(thenMatch.index);
|
|
126
|
+
for (const char of afterMatch) {
|
|
127
|
+
if (char === '{') braceDepth++;
|
|
128
|
+
if (char === '}') braceDepth--;
|
|
129
|
+
}
|
|
130
|
+
thenBodyStartLine = i + 1;
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
for (const char of line) {
|
|
134
|
+
if (char === '{') braceDepth++;
|
|
135
|
+
if (char === '}') braceDepth--;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (braceDepth <= 0) {
|
|
139
|
+
// 回调结束
|
|
140
|
+
const callbackLineCount = (i + 1) - thenBodyStartLine;
|
|
141
|
+
if (callbackLineCount > THEN_CALLBACK_LINE_LIMIT) {
|
|
142
|
+
results.push({
|
|
143
|
+
line: thenStartLine,
|
|
144
|
+
lineCount: callbackLineCount,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
inThenCallback = false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return results;
|
|
153
|
+
}
|
|
154
|
+
|
|
86
155
|
lines.forEach((line, index) => {
|
|
87
156
|
const lineNumber = index + 1;
|
|
88
157
|
|
|
@@ -109,6 +178,42 @@ function lintYidaSource(sourceCode, _filePath) {
|
|
|
109
178
|
});
|
|
110
179
|
}
|
|
111
180
|
}
|
|
181
|
+
|
|
182
|
+
// 检查 ES6 计算属性名
|
|
183
|
+
const computedMatch = line.match(computedPropertyRegex);
|
|
184
|
+
if (computedMatch && !isInCommentOrString(line, computedMatch.index)) {
|
|
185
|
+
const trimmed = line.trim();
|
|
186
|
+
if (!trimmed.startsWith('*') && !trimmed.startsWith('/*')) {
|
|
187
|
+
warnings.push({
|
|
188
|
+
line: lineNumber,
|
|
189
|
+
type: 'warning',
|
|
190
|
+
message: t('publish.lint_computed_property'),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 检查 padStart / padEnd 调用
|
|
196
|
+
const padMatch = line.match(padMethodRegex);
|
|
197
|
+
if (padMatch && !isInCommentOrString(line, padMatch.index)) {
|
|
198
|
+
const trimmed = line.trim();
|
|
199
|
+
if (!trimmed.startsWith('*') && !trimmed.startsWith('/*')) {
|
|
200
|
+
warnings.push({
|
|
201
|
+
line: lineNumber,
|
|
202
|
+
type: 'warning',
|
|
203
|
+
message: t('publish.lint_pad_method', padMatch[1]),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// 检查 .then() 回调代码量过大
|
|
210
|
+
const largeThenCallbacks = detectLargeThenCallbacks(lines);
|
|
211
|
+
largeThenCallbacks.forEach(({ line, lineCount }) => {
|
|
212
|
+
warnings.push({
|
|
213
|
+
line,
|
|
214
|
+
type: 'warning',
|
|
215
|
+
message: t('publish.lint_large_then_callback', lineCount, THEN_CALLBACK_LINE_LIMIT),
|
|
216
|
+
});
|
|
112
217
|
});
|
|
113
218
|
|
|
114
219
|
return { errors, warnings };
|