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.
Files changed (108) hide show
  1. package/README.md +3 -0
  2. package/bin/yida.js +42 -0
  3. package/lib/app/app-list.js +133 -0
  4. package/lib/app/create-app.js +1 -1
  5. package/lib/app/create-form.js +56 -9
  6. package/lib/app/create-page.js +2 -2
  7. package/lib/app/get-schema.js +1 -1
  8. package/lib/app/publish.js +105 -0
  9. package/lib/app/update-app.js +202 -0
  10. package/lib/auth/login.js +10 -14
  11. package/lib/auth/qr-login.js +4 -2
  12. package/lib/connector/action-generator.js +23 -9
  13. package/lib/connector/connector-smart-create.js +3 -1
  14. package/lib/core/check-data.js +514 -0
  15. package/lib/core/doctor.js +4 -4
  16. package/lib/core/env-cmd.js +384 -0
  17. package/lib/core/env-manager.js +218 -0
  18. package/lib/core/i18n.js +1 -1
  19. package/lib/core/locales/ar.js +24 -0
  20. package/lib/core/locales/de.js +24 -0
  21. package/lib/core/locales/en.js +256 -21
  22. package/lib/core/locales/es.js +24 -0
  23. package/lib/core/locales/fr.js +24 -0
  24. package/lib/core/locales/hi.js +24 -0
  25. package/lib/core/locales/ja.js +107 -21
  26. package/lib/core/locales/ko.js +24 -0
  27. package/lib/core/locales/pt.js +24 -0
  28. package/lib/core/locales/vi.js +24 -0
  29. package/lib/core/locales/zh-TW.js +122 -21
  30. package/lib/core/locales/zh.js +257 -21
  31. package/lib/core/query-data.js +36 -2
  32. package/lib/core/sample.js +145 -0
  33. package/lib/core/update.js +51 -0
  34. package/lib/core/utils.js +91 -9
  35. package/lib/db/db-seq-fix.js +436 -0
  36. package/lib/dws/dws-wrapper.js +21 -3
  37. package/lib/page-config/get-page-config.js +1 -1
  38. package/lib/page-config/save-share-config.js +1 -1
  39. package/lib/page-config/verify-short-url.js +2 -2
  40. package/lib/process/configure-process.js +8 -2
  41. package/lib/process/create-process.js +13 -0
  42. package/lib/process/preview-process.js +878 -0
  43. package/{yida-skills/skills/yida-custom-page/templates → lib/samples/yida-custom-page}/custom-page-template.js +48 -18
  44. package/package.json +1 -1
  45. package/project/pages/src/demo-chip-insight.js +3 -1
  46. package/project/pages/src/demo-ppt.js +1192 -0
  47. package/yida-skills/SKILL.md +32 -2
  48. package/yida-skills/references/yida-api.md +24 -1
  49. package/yida-skills/skills/large-file-write/SKILL.md +32 -43
  50. package/yida-skills/skills/large-file-write/references/write-patterns.md +124 -0
  51. package/yida-skills/skills/yida-app/SKILL.md +47 -14
  52. package/yida-skills/skills/yida-chart/SKILL.md +5 -5
  53. package/yida-skills/skills/yida-chart/{reference → references}/echarts-code-template.md +3 -3
  54. package/yida-skills/skills/yida-chart/references/examples.md +164 -0
  55. package/yida-skills/skills/yida-connector/SKILL.md +41 -1
  56. package/yida-skills/skills/yida-create-app/SKILL.md +19 -3
  57. package/yida-skills/skills/yida-create-form-page/SKILL.md +25 -1
  58. package/yida-skills/skills/yida-create-page/SKILL.md +23 -2
  59. package/yida-skills/skills/yida-create-process/SKILL.md +42 -2
  60. package/yida-skills/skills/yida-custom-page/SKILL.md +101 -239
  61. package/yida-skills/skills/yida-custom-page/examples/attachment-upload.js +223 -0
  62. package/yida-skills/skills/yida-custom-page/references/assets-guide.md +3 -3
  63. package/yida-skills/skills/yida-custom-page/references/attachment-upload-guide.md +459 -0
  64. package/yida-skills/skills/yida-custom-page/references/coding-guide.md +116 -86
  65. package/yida-skills/skills/yida-custom-page/references/design-system.md +4 -0
  66. package/yida-skills/skills/yida-data-management/SKILL.md +51 -0
  67. package/yida-skills/skills/yida-db-seq-fix/SKILL.md +110 -0
  68. package/yida-skills/skills/yida-density/SKILL.md +65 -246
  69. package/yida-skills/skills/yida-export-conversation/SKILL.md +39 -2
  70. package/yida-skills/skills/yida-flash-note-to-prd/SKILL.md +42 -250
  71. package/yida-skills/skills/yida-flash-note-to-prd/references/examples.md +124 -0
  72. package/yida-skills/skills/yida-flash-note-to-prd/references/flash-note-prd-template.md +42 -0
  73. package/yida-skills/skills/yida-flash-note-to-prd/references/flash-note-prompt.md +197 -0
  74. package/yida-skills/skills/yida-flash-note-to-prd/references/yida-field-types.md +20 -0
  75. package/yida-skills/skills/yida-form-permission/SKILL.md +36 -2
  76. package/yida-skills/skills/yida-formula/SKILL.md +37 -21
  77. package/yida-skills/skills/yida-formula/references/examples.md +149 -0
  78. package/yida-skills/skills/yida-get-schema/SKILL.md +35 -1
  79. package/yida-skills/skills/yida-integration/SKILL.md +71 -127
  80. package/yida-skills/skills/yida-integration/references/examples.md +119 -0
  81. package/yida-skills/skills/yida-integration/references/integration-node-schemas.md +377 -0
  82. package/yida-skills/skills/yida-login/SKILL.md +24 -2
  83. package/yida-skills/skills/yida-logout/SKILL.md +33 -1
  84. package/yida-skills/skills/yida-page-config/SKILL.md +36 -1
  85. package/yida-skills/skills/yida-ppt-slider/SKILL.md +750 -1
  86. package/yida-skills/skills/yida-ppt-slider/references/examples.md +381 -0
  87. package/yida-skills/skills/yida-process-rule/SKILL.md +30 -320
  88. package/yida-skills/skills/yida-process-rule/references/examples.md +344 -0
  89. package/yida-skills/skills/yida-publish-page/SKILL.md +56 -1
  90. package/yida-skills/skills/yida-report/SKILL.md +25 -341
  91. package/yida-skills/skills/yida-report/references/examples.md +145 -0
  92. package/yida-skills/skills/yida-report/references/report-api-guide.md +287 -0
  93. package/yida-skills/skills/yida-table-form/SKILL.md +65 -437
  94. package/yida-skills/skills/yida-table-form/references/examples.md +113 -0
  95. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/china-map.js +0 -0
  96. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/dashboard-bindform.js +0 -0
  97. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/line-trend.js +0 -0
  98. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/multi-bar-compare.js +0 -0
  99. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/radar-chart.js +0 -0
  100. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/scatter-bindform.js +0 -0
  101. /package/{yida-skills/skills/yida-chart/examples → lib/samples/yida-chart}/stacked-area.js +0 -0
  102. /package/{yida-skills/skills/yida-create-app/templates → lib/samples/yida-create-app}/ipd-app-template.js +0 -0
  103. /package/{yida-skills/skills/yida-custom-page/examples → lib/samples/yida-custom-page}/design-tokens.js +0 -0
  104. /package/{yida-skills/skills/yida-data-management/templates → lib/samples/yida-data-management}/form-field-template.js +0 -0
  105. /package/{yida-skills/skills/yida-density/examples → lib/samples/yida-density}/density-switch-page.js +0 -0
  106. /package/{yida-skills/skills/yida-table-form/examples → lib/samples/yida-table-form}/table-form-batch-submit.js +0 -0
  107. /package/yida-skills/skills/yida-chart/{reference → references}/echarts-bindding-guide.md +0 -0
  108. /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 };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * create-app.js - 宜搭应用创建命令
3
3
  *
4
- * 用法:yidacli create-app "<appName>" [description] [icon] [iconColor] [colour] [navTheme] [layoutDirection]
4
+ * 用法:openyida create-app "<appName>" [description] [icon] [iconColor] [colour] [navTheme] [layoutDirection]
5
5
  */
6
6
 
7
7
  'use strict';
@@ -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: 'didMount',
1467
- title: 'didMount',
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.step_read_changes', 3));
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 4: 应用修改
2422
- console.error(t('create_form.step_apply_changes', 4));
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 5 & 6: 保存 Schema 并更新表单配置
2437
- const { configResult } = await saveSchemaAndUpdateConfig(authRef, appType, formUuid, schema, version, 5);
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);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * create-page.js - 宜搭自定义页面创建命令
3
3
  *
4
- * 用法:yidacli create-page <appType> "<pageName>"
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 }));
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * get-schema.js - 宜搭表单 Schema 获取命令
3
3
  *
4
- * 用法:yidacli get-schema <appType> <formUuid>
4
+ * 用法:openyida get-schema <appType> <formUuid>
5
5
  */
6
6
 
7
7
  'use strict';
@@ -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 };