weaver-e10-builder 1.5.16 → 1.6.4

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 (232) hide show
  1. package/dist/commands/auth.d.ts.map +1 -1
  2. package/dist/commands/auth.js +4 -2
  3. package/dist/commands/auth.js.map +1 -1
  4. package/dist/commands/check.d.ts.map +1 -1
  5. package/dist/commands/check.js +109 -51
  6. package/dist/commands/check.js.map +1 -1
  7. package/dist/commands/form-attachment-setting.d.ts +3 -0
  8. package/dist/commands/form-attachment-setting.d.ts.map +1 -0
  9. package/dist/commands/form-attachment-setting.js +422 -0
  10. package/dist/commands/form-attachment-setting.js.map +1 -0
  11. package/dist/commands/form-data.d.ts.map +1 -1
  12. package/dist/commands/form-data.js +49 -1
  13. package/dist/commands/form-data.js.map +1 -1
  14. package/dist/commands/form-ebuilder-scope.d.ts +21 -0
  15. package/dist/commands/form-ebuilder-scope.d.ts.map +1 -1
  16. package/dist/commands/form-ebuilder-scope.js +41 -8
  17. package/dist/commands/form-ebuilder-scope.js.map +1 -1
  18. package/dist/commands/form-field-linkage.d.ts +6 -1
  19. package/dist/commands/form-field-linkage.d.ts.map +1 -1
  20. package/dist/commands/form-field-linkage.js +138 -31
  21. package/dist/commands/form-field-linkage.js.map +1 -1
  22. package/dist/commands/form-layout-code-reviewed.d.ts +3 -0
  23. package/dist/commands/form-layout-code-reviewed.d.ts.map +1 -0
  24. package/dist/commands/form-layout-code-reviewed.js +61 -0
  25. package/dist/commands/form-layout-code-reviewed.js.map +1 -0
  26. package/dist/commands/form-layout-describe.d.ts +3 -0
  27. package/dist/commands/form-layout-describe.d.ts.map +1 -0
  28. package/dist/commands/form-layout-describe.js +58 -0
  29. package/dist/commands/form-layout-describe.js.map +1 -0
  30. package/dist/commands/form-layout-diff.d.ts +3 -0
  31. package/dist/commands/form-layout-diff.d.ts.map +1 -0
  32. package/dist/commands/form-layout-diff.js +48 -0
  33. package/dist/commands/form-layout-diff.js.map +1 -0
  34. package/dist/commands/form-layout-document.d.ts +3 -0
  35. package/dist/commands/form-layout-document.d.ts.map +1 -0
  36. package/dist/commands/form-layout-document.js +81 -0
  37. package/dist/commands/form-layout-document.js.map +1 -0
  38. package/dist/commands/form-layout-edit.d.ts +3 -0
  39. package/dist/commands/form-layout-edit.d.ts.map +1 -0
  40. package/dist/commands/form-layout-edit.js +51 -0
  41. package/dist/commands/form-layout-edit.js.map +1 -0
  42. package/dist/commands/form-layout-init-reviewed.d.ts +3 -0
  43. package/dist/commands/form-layout-init-reviewed.d.ts.map +1 -0
  44. package/dist/commands/form-layout-init-reviewed.js +78 -0
  45. package/dist/commands/form-layout-init-reviewed.js.map +1 -0
  46. package/dist/commands/form-layout-restore.d.ts.map +1 -1
  47. package/dist/commands/form-layout-restore.js +23 -0
  48. package/dist/commands/form-layout-restore.js.map +1 -1
  49. package/dist/commands/form-layout-template-catalog.d.ts +3 -0
  50. package/dist/commands/form-layout-template-catalog.d.ts.map +1 -0
  51. package/dist/commands/form-layout-template-catalog.js +45 -0
  52. package/dist/commands/form-layout-template-catalog.js.map +1 -0
  53. package/dist/commands/form.d.ts.map +1 -1
  54. package/dist/commands/form.js +80 -5
  55. package/dist/commands/form.js.map +1 -1
  56. package/dist/commands/project.d.ts.map +1 -1
  57. package/dist/commands/project.js +39 -6
  58. package/dist/commands/project.js.map +1 -1
  59. package/dist/index.js +15 -0
  60. package/dist/index.js.map +1 -1
  61. package/dist/services/actionflow/components/action_eb_add.d.ts.map +1 -1
  62. package/dist/services/actionflow/components/action_eb_add.js +12 -5
  63. package/dist/services/actionflow/components/action_eb_add.js.map +1 -1
  64. package/dist/services/actionflow/components/action_eb_add_compiler.d.ts.map +1 -1
  65. package/dist/services/actionflow/components/action_eb_add_compiler.js +5 -0
  66. package/dist/services/actionflow/components/action_eb_add_compiler.js.map +1 -1
  67. package/dist/services/actionflow/components/action_eb_delete.d.ts +6 -1
  68. package/dist/services/actionflow/components/action_eb_delete.d.ts.map +1 -1
  69. package/dist/services/actionflow/components/action_eb_delete.js +23 -5
  70. package/dist/services/actionflow/components/action_eb_delete.js.map +1 -1
  71. package/dist/services/actionflow/components/action_eb_delete_compiler.d.ts.map +1 -1
  72. package/dist/services/actionflow/components/action_eb_delete_compiler.js +22 -0
  73. package/dist/services/actionflow/components/action_eb_delete_compiler.js.map +1 -1
  74. package/dist/services/actionflow/components/action_eb_update.d.ts.map +1 -1
  75. package/dist/services/actionflow/components/action_eb_update.js +13 -4
  76. package/dist/services/actionflow/components/action_eb_update.js.map +1 -1
  77. package/dist/services/actionflow/components/action_eb_update_compiler.d.ts.map +1 -1
  78. package/dist/services/actionflow/components/action_eb_update_compiler.js +9 -2
  79. package/dist/services/actionflow/components/action_eb_update_compiler.js.map +1 -1
  80. package/dist/services/actionflow/components/date_trigger.js +2 -2
  81. package/dist/services/actionflow/components/date_trigger.js.map +1 -1
  82. package/dist/services/actionflow/components/enquiry_form.d.ts.map +1 -1
  83. package/dist/services/actionflow/components/enquiry_form.js +11 -10
  84. package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
  85. package/dist/services/actionflow/components/event_button.js +1 -1
  86. package/dist/services/actionflow/components/event_button.js.map +1 -1
  87. package/dist/services/actionflow/components/form_data_builder.d.ts +29 -1
  88. package/dist/services/actionflow/components/form_data_builder.d.ts.map +1 -1
  89. package/dist/services/actionflow/components/form_data_builder.js +67 -3
  90. package/dist/services/actionflow/components/form_data_builder.js.map +1 -1
  91. package/dist/services/actionflow/components/time_batch_trigger.js +2 -2
  92. package/dist/services/actionflow/components/time_batch_trigger.js.map +1 -1
  93. package/dist/services/actionflow/form_source.d.ts +44 -1
  94. package/dist/services/actionflow/form_source.d.ts.map +1 -1
  95. package/dist/services/actionflow/form_source.js +231 -5
  96. package/dist/services/actionflow/form_source.js.map +1 -1
  97. package/dist/services/actionflow/preflight_service.d.ts +8 -0
  98. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  99. package/dist/services/actionflow/preflight_service.js +120 -14
  100. package/dist/services/actionflow/preflight_service.js.map +1 -1
  101. package/dist/services/actionflow/system_params.d.ts.map +1 -1
  102. package/dist/services/actionflow/system_params.js +4 -1
  103. package/dist/services/actionflow/system_params.js.map +1 -1
  104. package/dist/services/actionflow/trigger_common.d.ts.map +1 -1
  105. package/dist/services/actionflow/trigger_common.js +12 -3
  106. package/dist/services/actionflow/trigger_common.js.map +1 -1
  107. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  108. package/dist/services/actionflow/workflow_compiler.js +117 -40
  109. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  110. package/dist/services/form-attachment-settings.d.ts +110 -0
  111. package/dist/services/form-attachment-settings.d.ts.map +1 -0
  112. package/dist/services/form-attachment-settings.js +332 -0
  113. package/dist/services/form-attachment-settings.js.map +1 -0
  114. package/dist/services/form-attachment-upload.d.ts +30 -0
  115. package/dist/services/form-attachment-upload.d.ts.map +1 -0
  116. package/dist/services/form-attachment-upload.js +76 -0
  117. package/dist/services/form-attachment-upload.js.map +1 -0
  118. package/dist/services/form-data-openapi.d.ts +2 -0
  119. package/dist/services/form-data-openapi.d.ts.map +1 -1
  120. package/dist/services/form-data-openapi.js +1 -0
  121. package/dist/services/form-data-openapi.js.map +1 -1
  122. package/dist/services/form-layout-code-reviewed.d.ts +32 -0
  123. package/dist/services/form-layout-code-reviewed.d.ts.map +1 -0
  124. package/dist/services/form-layout-code-reviewed.js +101 -0
  125. package/dist/services/form-layout-code-reviewed.js.map +1 -0
  126. package/dist/services/form-layout-describe.d.ts +4 -0
  127. package/dist/services/form-layout-describe.d.ts.map +1 -0
  128. package/dist/services/form-layout-describe.js +107 -0
  129. package/dist/services/form-layout-describe.js.map +1 -0
  130. package/dist/services/form-layout-diff.d.ts +37 -0
  131. package/dist/services/form-layout-diff.d.ts.map +1 -0
  132. package/dist/services/form-layout-diff.js +232 -0
  133. package/dist/services/form-layout-diff.js.map +1 -0
  134. package/dist/services/form-layout-document-apply.d.ts +23 -0
  135. package/dist/services/form-layout-document-apply.d.ts.map +1 -0
  136. package/dist/services/form-layout-document-apply.js +82 -0
  137. package/dist/services/form-layout-document-apply.js.map +1 -0
  138. package/dist/services/form-layout-document.d.ts +13 -0
  139. package/dist/services/form-layout-document.d.ts.map +1 -0
  140. package/dist/services/form-layout-document.js +228 -0
  141. package/dist/services/form-layout-document.js.map +1 -0
  142. package/dist/services/form-layout-edit.d.ts +21 -0
  143. package/dist/services/form-layout-edit.d.ts.map +1 -0
  144. package/dist/services/form-layout-edit.js +103 -0
  145. package/dist/services/form-layout-edit.js.map +1 -0
  146. package/dist/services/form-layout-init-plan.d.ts +54 -0
  147. package/dist/services/form-layout-init-plan.d.ts.map +1 -0
  148. package/dist/services/form-layout-init-plan.js +211 -0
  149. package/dist/services/form-layout-init-plan.js.map +1 -0
  150. package/dist/services/form-layout-source/review.d.ts +4 -0
  151. package/dist/services/form-layout-source/review.d.ts.map +1 -0
  152. package/dist/services/form-layout-source/review.js +54 -0
  153. package/dist/services/form-layout-source/review.js.map +1 -0
  154. package/dist/services/form-layout-template-advanced.d.ts +5 -0
  155. package/dist/services/form-layout-template-advanced.d.ts.map +1 -1
  156. package/dist/services/form-layout-template-advanced.js +17 -1
  157. package/dist/services/form-layout-template-advanced.js.map +1 -1
  158. package/dist/services/form-layout-template-catalog.d.ts +13 -0
  159. package/dist/services/form-layout-template-catalog.d.ts.map +1 -0
  160. package/dist/services/form-layout-template-catalog.js +27 -0
  161. package/dist/services/form-layout-template-catalog.js.map +1 -0
  162. package/dist/services/form-layout-template-flow.d.ts +1 -1
  163. package/dist/services/form-layout-template-flow.d.ts.map +1 -1
  164. package/dist/services/form-layout-template-flow.js.map +1 -1
  165. package/dist/services/form-layout-template-verification.d.ts +34 -0
  166. package/dist/services/form-layout-template-verification.d.ts.map +1 -0
  167. package/dist/services/form-layout-template-verification.js +124 -0
  168. package/dist/services/form-layout-template-verification.js.map +1 -0
  169. package/dist/services/form-style-template.d.ts +3 -3
  170. package/dist/services/form-style-template.d.ts.map +1 -1
  171. package/dist/services/form-style-template.js +18 -13
  172. package/dist/services/form-style-template.js.map +1 -1
  173. package/package.json +1 -1
  174. package/skill-docs/SKILL.md +163 -155
  175. package/skill-docs/_catalog.md +110 -106
  176. package/skill-docs/actionflows/references/components/ebuilder/ActionEbDelete.md +60 -3
  177. package/skill-docs/actionflows/references/components/ebuilder/EventButton.md +35 -33
  178. package/skill-docs/assets/sample/api/formApi.js +689 -510
  179. package/skill-docs/assets/sample/app/config.js +4 -0
  180. package/skill-docs/assets/sample/app/fields.js +25 -0
  181. package/skill-docs/assets/sample/entry.js +24 -22
  182. package/skill-docs/assets/sample/eslint.config.cjs +1 -0
  183. package/skill-docs/assets/sample/pages/Items.js +247 -0
  184. package/skill-docs/assets/sample/styles/prototypeStyles.js +137 -0
  185. package/skill-docs/references/coding/guide-edit-backfill.md +102 -150
  186. package/skill-docs/references/coding/guide-form-crud.md +195 -172
  187. package/skill-docs/references/coding/guide-html-to-react.md +250 -0
  188. package/skill-docs/references/coding/guide-page-code.md +194 -167
  189. package/skill-docs/references/coding/guide-page-export.md +27 -18
  190. package/skill-docs/references/coding/ref-compile-rules.md +7 -7
  191. package/skill-docs/references/common/capability-boundaries.md +20 -1
  192. package/skill-docs/references/common/guide-plan-template.md +29 -3
  193. package/skill-docs/references/common/map.md +13 -8
  194. package/skill-docs/references/common/ref-cli-commands.md +31 -10
  195. package/skill-docs/references/components/display-FilePreview.md +5 -4
  196. package/skill-docs/references/form/guide-browser-definition.md +57 -13
  197. package/skill-docs/references/form/guide-create-form.md +258 -258
  198. package/skill-docs/references/form/guide-field-linkage.md +4 -1
  199. package/skill-docs/references/form/guide-form-attachment-setting.md +95 -0
  200. package/skill-docs/references/form/guide-form-data.md +22 -1
  201. package/skill-docs/references/form/layout/code-block/code-block-guide.md +153 -0
  202. package/skill-docs/references/form/layout/code-block/controls.md +60 -0
  203. package/skill-docs/references/form/layout/code-block/coverage.md +32 -0
  204. package/skill-docs/references/form/layout/code-block/details.md +57 -0
  205. package/skill-docs/references/form/layout/code-block/events-validation.md +42 -0
  206. package/skill-docs/references/form/layout/code-block/foundations-fields.md +56 -0
  207. package/skill-docs/references/form/layout/code-block/layout-css.md +116 -0
  208. package/skill-docs/references/form/layout/code-block/recipes.md +164 -0
  209. package/skill-docs/references/form/layout/code-block/troubleshooting.md +49 -0
  210. package/skill-docs/references/form/layout/code-block/ui-global.md +47 -0
  211. package/skill-docs/references/form/layout/document.md +39 -0
  212. package/skill-docs/references/form/layout/incremental.md +133 -0
  213. package/skill-docs/references/form/layout/initialization.md +39 -0
  214. package/skill-docs/references/form/layout/inspect-edit.md +76 -0
  215. package/skill-docs/references/form/layout/layout-overview.md +67 -0
  216. package/skill-docs/references/form/layout/management.md +64 -0
  217. package/skill-docs/references/form/layout/planning.md +76 -0
  218. package/skill-docs/references/form/layout/source-restoration.md +388 -0
  219. package/skill-docs/references/form/layout/template/advanced-css.md +167 -0
  220. package/skill-docs/references/form/layout/template/advanced.md +318 -0
  221. package/skill-docs/references/form/layout/template/easy.md +64 -0
  222. package/skill-docs/references/form/layout/template/flow.md +30 -0
  223. package/skill-docs/references/form/layout/template/template-guide.md +56 -0
  224. package/skill-docs/references/form/layout/workflow-layout.md +44 -0
  225. package/skill-docs/references/form/ref-form-fields.md +303 -301
  226. package/skill-docs/references/workflow/guide-workflow-node-layout.md +189 -187
  227. package/skill-docs/assets/sample/config/config.js +0 -0
  228. package/skill-docs/assets/sample/config/configLoad.js +0 -0
  229. package/skill-docs/assets/sample/config/configLoad_default.js +0 -0
  230. package/skill-docs/assets/sample/config/config_default.js +0 -0
  231. package/skill-docs/assets/sample/memo.md +0 -0
  232. package/skill-docs/assets/sample/readme.js +0 -8
@@ -0,0 +1,4 @@
1
+ // 填当前 Ebuilder 应用 ID 和表单 objId。
2
+ // 注意:entry.js 里 asyncImport 的 '${appId}' 是固定字符串,不是这里这个应用 ID。
3
+ export var APP_ID = 'YOUR_EBUILDER_APP_ID';
4
+ export var OBJ_ID = 'YOUR_FORM_OBJ_ID';
@@ -0,0 +1,25 @@
1
+ // 用下面的命令导出字段后,把真实 fieldId 填到这里:
2
+ // e10-cli form read <objId> --app-id <appId> --out fields.json
3
+ //
4
+ // F 的 key 是页面里使用的短名,value 是平台 fieldId。
5
+ // D 是明细表字段;DETAIL_SUB_FORM_ID 是明细表 subFormId(稳定,不随 detail1/detail2 节点名变化)。
6
+ // 表单没有明细表时,删掉 D / DETAIL_SUB_FORM_ID 和页面里的明细段。
7
+ export var F = {
8
+ name: 'FIELD_ID_NAME',
9
+ status: 'FIELD_ID_STATUS'
10
+ };
11
+
12
+ export var D = {
13
+ name: 'DETAIL_FIELD_ID_NAME',
14
+ quantity: 'DETAIL_FIELD_ID_QUANTITY'
15
+ };
16
+
17
+ export var DETAIL_SUB_FORM_ID = 'DETAIL_SUB_FORM_ID';
18
+
19
+ export var LABELS = {
20
+ name: '名称',
21
+ status: '状态',
22
+ detail: '明细',
23
+ detailName: '明细名称',
24
+ detailQuantity: '数量'
25
+ };
@@ -1,22 +1,24 @@
1
- import React, { useState, useEffect, Suspense } from 'react';
2
- import { Route } from 'react-router-dom';
3
- import { regOvProps, appInfo, regReactChildren } from '@weapp/utils';
4
- import { getSimpleData } from './api/formApi.js';
5
- import { asyncImport } from '@weapp/ecodesdk';
6
-
7
- // 初始的空白模板项目
8
- const { publicUrl } = appInfo('@weapp/ecodesdk');
9
- const extract = (
10
- <Route path={`${publicUrl}/sp/custom/123123`}>
11
- <React.Suspense fallback={<div>Loading...</div>}>
12
- <>
13
- HELLO WORLD
14
- </>
15
- </React.Suspense>
16
- </Route>
17
- );
18
-
19
- regOvProps('weappEcodesdk', 'Switch', (props) => {
20
- regReactChildren(props, extract);
21
- return props;
22
- }, 0);
1
+ import React from 'react';
2
+ import { Route } from 'react-router-dom';
3
+ import { regOvProps, appInfo, regReactChildren } from '@weapp/utils';
4
+ import { asyncImport } from '@weapp/ecodesdk';
5
+
6
+ var publicUrl = appInfo('@weapp/ecodesdk').publicUrl;
7
+
8
+ var ItemsPage = React.lazy(function () {
9
+ // 单引号里的 ${appId} 是固定字符串,不是应用 ID,不要替换成数字
10
+ return asyncImport('${appId}', 'pages/Items');
11
+ });
12
+
13
+ var extract = (
14
+ <Route path={publicUrl + '/sp/custom/ecode/items'}>
15
+ <React.Suspense fallback={<div>Loading...</div>}>
16
+ <ItemsPage />
17
+ </React.Suspense>
18
+ </Route>
19
+ );
20
+
21
+ regOvProps('weappEcodesdk', 'Switch', function (props) {
22
+ regReactChildren(props, extract);
23
+ return props;
24
+ }, 0);
@@ -25,6 +25,7 @@ module.exports = [
25
25
  Array: "readonly",
26
26
  Date: "readonly",
27
27
  String: "readonly",
28
+ Number: "readonly",
28
29
  parseInt: "readonly",
29
30
  encodeURIComponent: "readonly",
30
31
  Error: "readonly",
@@ -0,0 +1,247 @@
1
+ // 先填 app/config.js(APP_ID / OBJ_ID)和 app/fields.js(真实字段 ID),再运行。
2
+ import React, { useEffect, useState } from 'react';
3
+ import { formClient } from '../api/formApi.js';
4
+ import { APP_ID, OBJ_ID } from '../app/config.js';
5
+ import { F, D, DETAIL_SUB_FORM_ID, LABELS } from '../app/fields.js';
6
+ import { PROTOTYPE_CSS } from '../styles/prototypeStyles.js';
7
+
8
+ // 模块顶层创建一次,字段和选项缓存会复用;不要放进组件 render。
9
+ var items = formClient({ objId: OBJ_ID, appId: APP_ID });
10
+
11
+ var EMPTY = {};
12
+ Object.keys(F).forEach(function (key) {
13
+ EMPTY[F[key]] = '';
14
+ });
15
+
16
+ var EMPTY_DETAIL = {};
17
+ Object.keys(D).forEach(function (key) {
18
+ EMPTY_DETAIL[D[key]] = '';
19
+ });
20
+
21
+ export default function Items() {
22
+ var [rows, setRows] = useState([]);
23
+ var [total, setTotal] = useState(null);
24
+ var [loading, setLoading] = useState(true);
25
+ var [error, setError] = useState('');
26
+ var [statusOptions, setStatusOptions] = useState([]);
27
+ var [form, setForm] = useState(EMPTY);
28
+ var [detailRows, setDetailRows] = useState([]);
29
+ var [editingId, setEditingId] = useState('');
30
+ var [showForm, setShowForm] = useState(false);
31
+
32
+ function load() {
33
+ setLoading(true);
34
+ setError('');
35
+ items.list({ page: 1, size: 20, withDetail: true }).then(function (page) {
36
+ setRows(page.rows);
37
+ setTotal(page.total);
38
+ }).catch(function (err) {
39
+ setError(err.message);
40
+ }).then(function () {
41
+ setLoading(false);
42
+ });
43
+ }
44
+
45
+ useEffect(function () {
46
+ load();
47
+ items.options(F.status).then(setStatusOptions).catch(function () {});
48
+ }, []);
49
+
50
+ function openCreate() {
51
+ setEditingId('');
52
+ setForm(Object.assign({}, EMPTY));
53
+ setDetailRows([]);
54
+ setShowForm(true);
55
+ }
56
+
57
+ function openEdit(row) {
58
+ var detail = (row.detailRows && row.detailRows[DETAIL_SUB_FORM_ID]) || [];
59
+ setEditingId(row.id);
60
+ setForm(Object.assign({}, row.values));
61
+ setDetailRows(detail.map(function (line) {
62
+ return Object.assign({}, line.values);
63
+ }));
64
+ setShowForm(true);
65
+ }
66
+
67
+ function closeForm() {
68
+ setShowForm(false);
69
+ setEditingId('');
70
+ }
71
+
72
+ function change(fieldId, value) {
73
+ var next = Object.assign({}, form);
74
+ next[fieldId] = value;
75
+ setForm(next);
76
+ }
77
+
78
+ function changeDetail(index, fieldId, value) {
79
+ setDetailRows(detailRows.map(function (line, i) {
80
+ if (i !== index) return line;
81
+ var next = Object.assign({}, line);
82
+ next[fieldId] = value;
83
+ return next;
84
+ }));
85
+ }
86
+
87
+ function addDetailRow() {
88
+ setDetailRows(detailRows.concat([Object.assign({}, EMPTY_DETAIL)]));
89
+ }
90
+
91
+ function removeDetailRow(index) {
92
+ setDetailRows(detailRows.filter(function (line, i) { return i !== index; }));
93
+ }
94
+
95
+ function submit() {
96
+ var details = {};
97
+ details[DETAIL_SUB_FORM_ID] = detailRows;
98
+ var writeOptions = { details: details };
99
+ var action;
100
+ if (editingId) {
101
+ writeOptions.detailMode = 'cover';
102
+ action = items.update(editingId, form, writeOptions);
103
+ } else {
104
+ action = items.save(form, writeOptions);
105
+ }
106
+ action.then(function () {
107
+ closeForm();
108
+ load();
109
+ }).catch(function (err) {
110
+ setError(err.message);
111
+ });
112
+ }
113
+
114
+ function remove(row) {
115
+ if (!window.confirm('确认删除「' + (row.display[F.name] || row.id) + '」?')) return;
116
+ items.remove(row.id).then(load).catch(function (err) {
117
+ setError(err.message);
118
+ });
119
+ }
120
+
121
+ function detailCount(row) {
122
+ var detail = row.detailRows && row.detailRows[DETAIL_SUB_FORM_ID];
123
+ return detail ? detail.length : 0;
124
+ }
125
+
126
+ return (
127
+ <div className="items-page">
128
+ <style>{PROTOTYPE_CSS}</style>
129
+
130
+ <div className="items-head">
131
+ <h2>物品列表</h2>
132
+ <button className="items-btn" onClick={openCreate}>新增</button>
133
+ </div>
134
+
135
+ {error ? <div className="items-error">{error}</div> : null}
136
+ {loading ? <div className="items-empty">加载中...</div> : null}
137
+ {!loading && rows.length === 0 ? <div className="items-empty">暂无数据</div> : null}
138
+
139
+ {!loading && rows.length > 0 ? (
140
+ <table className="items-table">
141
+ <thead>
142
+ <tr>
143
+ <th>{LABELS.name}</th>
144
+ <th>{LABELS.status}</th>
145
+ <th>{LABELS.detail}</th>
146
+ <th>操作</th>
147
+ </tr>
148
+ </thead>
149
+ <tbody>
150
+ {rows.map(function (row) {
151
+ return (
152
+ <tr key={row.id}>
153
+ <td>{row.display[F.name]}</td>
154
+ <td>{row.display[F.status]}</td>
155
+ <td>{detailCount(row)} 行</td>
156
+ <td>
157
+ <button className="items-link" onClick={function () { openEdit(row); }}>编辑</button>
158
+ <button className="items-link items-link-danger" onClick={function () { remove(row); }}>删除</button>
159
+ </td>
160
+ </tr>
161
+ );
162
+ })}
163
+ </tbody>
164
+ </table>
165
+ ) : null}
166
+
167
+ {total !== null ? <div className="items-total">共 {total} 条</div> : null}
168
+
169
+ {showForm ? (
170
+ <div className="items-form">
171
+ <h3>{editingId ? '编辑物品' : '新增物品'}</h3>
172
+
173
+ <label>
174
+ 名称
175
+ <input
176
+ value={form[F.name] || ''}
177
+ onChange={function (e) { change(F.name, e.target.value); }}
178
+ />
179
+ </label>
180
+
181
+ <label>
182
+ 状态
183
+ <select
184
+ value={form[F.status] || ''}
185
+ onChange={function (e) { change(F.status, e.target.value); }}
186
+ >
187
+ <option value="">请选择</option>
188
+ {statusOptions.map(function (opt) {
189
+ return <option key={opt.valueKey} value={opt.valueKey}>{opt.name}</option>;
190
+ })}
191
+ </select>
192
+ </label>
193
+
194
+ <div className="items-detail">
195
+ <div className="items-detail-head">
196
+ <strong>{LABELS.detail}</strong>
197
+ <button className="items-btn items-btn-plain" onClick={addDetailRow}>加一行</button>
198
+ </div>
199
+
200
+ {detailRows.length === 0 ? (
201
+ <div className="items-empty">暂无明细</div>
202
+ ) : (
203
+ <table className="items-detail-table">
204
+ <thead>
205
+ <tr>
206
+ <th>{LABELS.detailName}</th>
207
+ <th>{LABELS.detailQuantity}</th>
208
+ <th>操作</th>
209
+ </tr>
210
+ </thead>
211
+ <tbody>
212
+ {detailRows.map(function (line, index) {
213
+ return (
214
+ <tr key={index}>
215
+ <td>
216
+ <input
217
+ value={line[D.name] || ''}
218
+ onChange={function (e) { changeDetail(index, D.name, e.target.value); }}
219
+ />
220
+ </td>
221
+ <td>
222
+ <input
223
+ type="number"
224
+ value={line[D.quantity] || ''}
225
+ onChange={function (e) { changeDetail(index, D.quantity, e.target.value); }}
226
+ />
227
+ </td>
228
+ <td>
229
+ <button className="items-link items-link-danger" onClick={function () { removeDetailRow(index); }}>删除</button>
230
+ </td>
231
+ </tr>
232
+ );
233
+ })}
234
+ </tbody>
235
+ </table>
236
+ )}
237
+ </div>
238
+
239
+ <div className="items-actions">
240
+ <button className="items-btn" onClick={submit}>保存</button>
241
+ <button className="items-btn items-btn-plain" onClick={closeForm}>取消</button>
242
+ </div>
243
+ </div>
244
+ ) : null}
245
+ </div>
246
+ );
247
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * 原型 HTML 的 <style> 内容原样放这里。
3
+ * 不要改写选择器、不要拆成独立 .css 文件、不要逐条转成内联 style。
4
+ * 页面用 <style>{PROTOTYPE_CSS}</style> 渲染一次。
5
+ */
6
+ export var PROTOTYPE_CSS = `
7
+ .items-page {
8
+ padding: 24px;
9
+ color: #1f2937;
10
+ background: #f7f8fa;
11
+ min-height: 100%;
12
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
13
+ }
14
+ .items-head {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ margin-bottom: 16px;
19
+ }
20
+ .items-head h2 {
21
+ margin: 0;
22
+ font-size: 20px;
23
+ }
24
+ .items-btn {
25
+ border: 0;
26
+ border-radius: 6px;
27
+ padding: 7px 16px;
28
+ color: #fff;
29
+ background: #2563eb;
30
+ cursor: pointer;
31
+ }
32
+ .items-btn-plain {
33
+ color: #374151;
34
+ background: #e5e7eb;
35
+ }
36
+ .items-table {
37
+ width: 100%;
38
+ border-collapse: collapse;
39
+ background: #fff;
40
+ border-radius: 8px;
41
+ overflow: hidden;
42
+ }
43
+ .items-table th,
44
+ .items-table td {
45
+ padding: 10px 12px;
46
+ border-bottom: 1px solid #eef0f3;
47
+ text-align: left;
48
+ font-size: 14px;
49
+ }
50
+ .items-table th {
51
+ color: #6b7280;
52
+ font-weight: 500;
53
+ background: #fafbfc;
54
+ }
55
+ .items-link {
56
+ border: 0;
57
+ padding: 0;
58
+ margin-right: 12px;
59
+ color: #2563eb;
60
+ background: none;
61
+ cursor: pointer;
62
+ }
63
+ .items-link-danger {
64
+ color: #dc2626;
65
+ }
66
+ .items-empty,
67
+ .items-error,
68
+ .items-total {
69
+ padding: 12px 0;
70
+ font-size: 14px;
71
+ }
72
+ .items-error {
73
+ color: #dc2626;
74
+ }
75
+ .items-form {
76
+ margin-top: 20px;
77
+ padding: 16px;
78
+ border: 1px solid #e5e7eb;
79
+ border-radius: 8px;
80
+ background: #fff;
81
+ }
82
+ .items-form h3 {
83
+ margin: 0 0 12px;
84
+ font-size: 16px;
85
+ }
86
+ .items-form label {
87
+ display: block;
88
+ margin-bottom: 12px;
89
+ font-size: 14px;
90
+ }
91
+ .items-form input,
92
+ .items-form select {
93
+ display: block;
94
+ width: 100%;
95
+ box-sizing: border-box;
96
+ margin-top: 6px;
97
+ padding: 8px 10px;
98
+ border: 1px solid #d1d5db;
99
+ border-radius: 6px;
100
+ font: inherit;
101
+ }
102
+ .items-actions {
103
+ display: flex;
104
+ gap: 8px;
105
+ }
106
+ .items-detail {
107
+ margin: 16px 0;
108
+ padding-top: 12px;
109
+ border-top: 1px solid #eef0f3;
110
+ }
111
+ .items-detail-head {
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: space-between;
115
+ margin-bottom: 8px;
116
+ font-size: 14px;
117
+ }
118
+ .items-detail-table {
119
+ width: 100%;
120
+ border-collapse: collapse;
121
+ }
122
+ .items-detail-table th,
123
+ .items-detail-table td {
124
+ padding: 6px 8px;
125
+ border-bottom: 1px solid #eef0f3;
126
+ text-align: left;
127
+ font-size: 13px;
128
+ }
129
+ .items-detail-table input {
130
+ width: 100%;
131
+ box-sizing: border-box;
132
+ padding: 6px 8px;
133
+ border: 1px solid #d1d5db;
134
+ border-radius: 6px;
135
+ font: inherit;
136
+ }
137
+ `;