openxiangda 2.5.0 → 2.7.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 (80) hide show
  1. package/dist/browser/application.d.ts +3 -1
  2. package/dist/browser/application.d.ts.map +1 -1
  3. package/dist/browser/application.js +4 -3
  4. package/dist/browser/application.js.map +1 -1
  5. package/dist/browser/components/platform-fields/DateTimeField.d.ts +5 -3
  6. package/dist/browser/components/platform-fields/DateTimeField.d.ts.map +1 -1
  7. package/dist/browser/components/platform-fields/DateTimeField.js +24 -7
  8. package/dist/browser/components/platform-fields/DateTimeField.js.map +1 -1
  9. package/dist/browser/components/platform-fields/MobileDateTimeField.d.ts +2 -1
  10. package/dist/browser/components/platform-fields/MobileDateTimeField.d.ts.map +1 -1
  11. package/dist/browser/components/platform-fields/MobileDateTimeField.js +10 -1
  12. package/dist/browser/components/platform-fields/MobileDateTimeField.js.map +1 -1
  13. package/dist/browser/components/platform-fields/MobileZonedDateTimeField.d.ts +6 -0
  14. package/dist/browser/components/platform-fields/MobileZonedDateTimeField.d.ts.map +1 -0
  15. package/dist/browser/components/platform-fields/MobileZonedDateTimeField.js +68 -0
  16. package/dist/browser/components/platform-fields/MobileZonedDateTimeField.js.map +1 -0
  17. package/dist/browser/components/platform-fields/SignatureField.d.ts.map +1 -1
  18. package/dist/browser/components/platform-fields/SignatureField.js +2 -1
  19. package/dist/browser/components/platform-fields/SignatureField.js.map +1 -1
  20. package/dist/browser/components/platform-fields/ZonedDateTimeField.d.ts +12 -0
  21. package/dist/browser/components/platform-fields/ZonedDateTimeField.d.ts.map +1 -0
  22. package/dist/browser/components/platform-fields/ZonedDateTimeField.js +81 -0
  23. package/dist/browser/components/platform-fields/ZonedDateTimeField.js.map +1 -0
  24. package/dist/browser/components/platform-fields/zoned-date-time.d.ts +25 -0
  25. package/dist/browser/components/platform-fields/zoned-date-time.d.ts.map +1 -0
  26. package/dist/browser/components/platform-fields/zoned-date-time.js +91 -0
  27. package/dist/browser/components/platform-fields/zoned-date-time.js.map +1 -0
  28. package/dist/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -1
  29. package/dist/browser/components/resource/GeneratedResourceCrud.js +5 -3
  30. package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -1
  31. package/dist/browser/components/resource/RecordChangeHistory.d.ts.map +1 -1
  32. package/dist/browser/components/resource/RecordChangeHistory.js +2 -1
  33. package/dist/browser/components/resource/RecordChangeHistory.js.map +1 -1
  34. package/dist/browser/components/resource/RecordDetailFrame.d.ts +1 -1
  35. package/dist/browser/components/resource/RecordDetailFrame.d.ts.map +1 -1
  36. package/dist/browser/components/resource/RecordDetailFrame.js +5 -3
  37. package/dist/browser/components/resource/RecordDetailFrame.js.map +1 -1
  38. package/dist/browser/components/resource/ResourceFormDrafts.d.ts.map +1 -1
  39. package/dist/browser/components/resource/ResourceFormDrafts.js +2 -1
  40. package/dist/browser/components/resource/ResourceFormDrafts.js.map +1 -1
  41. package/dist/browser/components/resource/useResourceFormDrafts.d.ts.map +1 -1
  42. package/dist/browser/components/resource/useResourceFormDrafts.js +3 -1
  43. package/dist/browser/components/resource/useResourceFormDrafts.js.map +1 -1
  44. package/dist/browser/components/todo/ApplicationTodoCenterPage.d.ts.map +1 -1
  45. package/dist/browser/components/todo/ApplicationTodoCenterPage.js +8 -7
  46. package/dist/browser/components/todo/ApplicationTodoCenterPage.js.map +1 -1
  47. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts.map +1 -1
  48. package/dist/browser/components/workflow/StandardWorkflowPages.js +4 -9
  49. package/dist/browser/components/workflow/StandardWorkflowPages.js.map +1 -1
  50. package/dist/browser/navigation-guard.d.ts +13 -0
  51. package/dist/browser/navigation-guard.d.ts.map +1 -0
  52. package/dist/browser/navigation-guard.js +93 -0
  53. package/dist/browser/navigation-guard.js.map +1 -0
  54. package/dist/browser/presentation-time.d.ts +10 -0
  55. package/dist/browser/presentation-time.d.ts.map +1 -0
  56. package/dist/browser/presentation-time.js +33 -0
  57. package/dist/browser/presentation-time.js.map +1 -0
  58. package/dist/browser/ui-provider.d.ts +2 -1
  59. package/dist/browser/ui-provider.d.ts.map +1 -1
  60. package/dist/browser/ui-provider.js +4 -2
  61. package/dist/browser/ui-provider.js.map +1 -1
  62. package/dist/field-kit.d.ts +1 -0
  63. package/dist/field-kit.d.ts.map +1 -1
  64. package/dist/field-kit.js.map +1 -1
  65. package/dist/react.d.ts +1 -0
  66. package/dist/react.d.ts.map +1 -1
  67. package/dist/react.js +1 -0
  68. package/dist/react.js.map +1 -1
  69. package/documentation/field-components.md +25 -0
  70. package/documentation/frontend.md +26 -0
  71. package/documentation/getting-started.md +7 -7
  72. package/documentation/manifest.json +4 -4
  73. package/package.json +19 -17
  74. package/releases/2.6.0.json +37 -0
  75. package/releases/2.7.0.json +37 -0
  76. package/skills/manifest.json +1 -1
  77. package/skills/openxiangda-v2/SKILL.md +4 -4
  78. package/skills/openxiangda-v2/references/field-components.md +25 -0
  79. package/skills/openxiangda-v2/references/frontend.md +26 -0
  80. package/skills/openxiangda-v2/references/getting-started.md +7 -7
@@ -3,6 +3,7 @@ export * from './browser/components/platform-fields/AddressField';
3
3
  export * from './browser/components/platform-fields/AttachmentFileList';
4
4
  export * from './browser/components/platform-fields/CascadeField';
5
5
  export * from './browser/components/platform-fields/DateTimeField';
6
+ export type { DateTimeConstraints } from './browser/components/platform-fields/zoned-date-time';
6
7
  export * from './browser/components/platform-fields/JsonField';
7
8
  export * from './browser/components/platform-fields/LocationField';
8
9
  export * from './browser/components/platform-fields/PlatformDirectoryPicker';
@@ -1 +1 @@
1
- {"version":3,"file":"field-kit.d.ts","sourceRoot":"","sources":["../src/field-kit.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,oDAAoD,CAAC;AACnE,cAAc,8DAA8D,CAAC;AAC7E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,cAAc,0DAA0D,CAAC"}
1
+ {"version":3,"file":"field-kit.d.ts","sourceRoot":"","sources":["../src/field-kit.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,YAAY,EAAE,mBAAmB,EAAE,MAAM,sDAAsD,CAAC;AAChG,cAAc,gDAAgD,CAAC;AAC/D,cAAc,oDAAoD,CAAC;AACnE,cAAc,8DAA8D,CAAC;AAC7E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,cAAc,0DAA0D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"field-kit.js","sourceRoot":"","sources":["../src/field-kit.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,oDAAoD,CAAC;AACnE,cAAc,8DAA8D,CAAC;AAC7E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,cAAc,0DAA0D,CAAC"}
1
+ {"version":3,"file":"field-kit.js","sourceRoot":"","sources":["../src/field-kit.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AAEnE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,oDAAoD,CAAC;AACnE,cAAc,8DAA8D,CAAC;AAC7E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,cAAc,0DAA0D,CAAC"}
package/dist/react.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from './browser/FilePreviewPage';
9
9
  export * from './browser/OpenXiangdaAdminPage';
10
10
  export * from './browser/runtime';
11
11
  export * from './browser/route-manifest';
12
+ export { useUnsavedChangesGuard, type UnsavedChangesGuardOptions } from './browser/navigation-guard';
12
13
  export * from './browser/standard-user-surfaces';
13
14
  export * from './browser/Shell';
14
15
  export * from './browser/resource-definitions';
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0CAA0C,CAAC;AACzD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EACL,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qDAAqD,CAAC;AACpE,mBAAmB,6DAA6D,CAAC"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0CAA0C,CAAC;AACzD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,KAAK,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACrG,cAAc,kCAAkC,CAAC;AACjD,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EACL,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qDAAqD,CAAC;AACpE,mBAAmB,6DAA6D,CAAC"}
package/dist/react.js CHANGED
@@ -9,6 +9,7 @@ export * from './browser/FilePreviewPage';
9
9
  export * from './browser/OpenXiangdaAdminPage';
10
10
  export * from './browser/runtime';
11
11
  export * from './browser/route-manifest';
12
+ export { useUnsavedChangesGuard } from './browser/navigation-guard';
12
13
  export * from './browser/standard-user-surfaces';
13
14
  export * from './browser/Shell';
14
15
  export * from './browser/resource-definitions';
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0CAA0C,CAAC;AACzD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EACL,6BAA6B,EAE7B,2BAA2B,GAG5B,MAAM,2BAA2B,CAAC;AAEnC,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qDAAqD,CAAC"}
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0CAA0C,CAAC;AACzD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAmC,MAAM,4BAA4B,CAAC;AACrG,cAAc,kCAAkC,CAAC;AACjD,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EACL,6BAA6B,EAE7B,2BAA2B,GAG5B,MAAM,2BAA2B,CAAC;AAEnC,cAAc,qDAAqD,CAAC;AACpE,cAAc,oDAAoD,CAAC;AACnE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qDAAqD,CAAC;AACpE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qDAAqD,CAAC"}
@@ -214,6 +214,31 @@ pnpm openxiangda check
214
214
 
215
215
  ## 移动字段呈现与分组
216
216
 
217
+ ### 应用时区与时间限制
218
+
219
+ `OpenXiangdaApplication` 的可选 `timeZone="Asia/Shanghai"` 统一标准表单、详情、
220
+ 审批业务摘要、待办/通知、审计和草稿时间的展示。独立使用组件时可在
221
+ `OpenXiangdaUiProvider` 传同一参数;不指定时保留浏览器本地时区。
222
+ 这只影响输入与展示,`datetime` / `datetime-range` 仍读写 UTC ISO instant。
223
+ `date` / `date-range` 保留自然日期,`time` 保留无日期时间。
224
+
225
+ `DateTimeField`、`DateTimeFilter`、`DateTimeValueDisplay` 和 `MobileDateTimeField`
226
+ 可显式传 `timeZone` 覆盖应用默认。日期时间输入还可传 `min` / `max`(含端点的
227
+ ISO instant)与 `minuteStep`(1 到 60 且整除 60)。设置步长后只接受整分钟,秒和
228
+ 毫秒为零;例如 `minuteStep={15}`。服务端仍须验证最终业务窗口与授权。
229
+
230
+ ```tsx
231
+ <DateTimeField field={startsAtField} value={startsAt} onChange={setStartsAt}
232
+ timeZone="Asia/Shanghai" minuteStep={15}
233
+ min="2026-09-08T01:00:00Z" max="2026-10-08T01:00:00Z" />
234
+ ```
235
+
236
+ 输入到夏令时不存在或重复的墙上时间时显示错误,不自动选偏移。无效时区、步长或
237
+ 上下限配置会报错。手机指定时区的日期时间使用日期/时间滚轮,最多提供当前选择前后
238
+ 各 365 天并按限制收窄;范围仍分两步确认,取消不修改原值。
239
+
240
+ ### 字段布局
241
+
217
242
  移动字段自身提供无边框输入、上下标签、行分隔和错误提示;标准表单与自定义页面使用同一
218
243
  字段组件。页面负责把相关字段组织在浅色背景上的白色分组中,不另设移动主题配置。
219
244
 
@@ -41,6 +41,32 @@ DataQuery 使用有界 where 条件树,支持 and/or/not。标准列表的筛
41
41
 
42
42
  ## 标准后台扩展
43
43
 
44
+ ### 未保存内容的离开保护
45
+
46
+ 自定义表单可在 `OpenXiangdaApplication` 内调用
47
+ `useUnsavedChangesGuard({ when, message? })`。`when` 包含未保存表单、正在提交或
48
+ 结果尚不确定的状态;成功后清除,组件卸载时自动注销。多个表单由应用入口统一汇总,
49
+ 不需要应用创建路由或拦截 document 点击。
50
+
51
+ ```tsx
52
+ useUnsavedChangesGuard({
53
+ when: !result && (hasDraft || pending || hasUnresolvedIntent),
54
+ message: '会议尚未提交完成,离开将丢失当前填写内容。',
55
+ });
56
+ ```
57
+
58
+ 站内使用 React Router 的 `Link` 或 `navigate`,前进/后退与程序跳转使用同一确认框。
59
+ 确认框打开时保留第一次目标,取消后继续原地编辑。刷新、关闭和文档跳转使用浏览器
60
+ 原生提示,其文案和是否展示受浏览器限制。保存成功可在状态清除后的 effect 中跳转。
61
+ 该 hook 只保护导航,不持久化草稿或恢复提交回执;业务数据仍由各自既有能力负责。
62
+ 不要直接调用 `history.pushState` 或修改路由内部状态。
63
+
64
+ ### 应用时区
65
+
66
+ 如业务采用固定时区,在现有 `OpenXiangdaApplication` 传可选 `timeZone`,例如
67
+ `Asia/Shanghai`。标准表单、审批摘要和各中心时间随同一 UI Provider 展示,应用无需
68
+ 修改设备时区或保存第二份时间。具体控件参数见[字段组件](./field-components.md)。
69
+
44
70
  默认 CRUD、统一 Shell、current-user 权限和 Data Provider 都由 `openxiangda/react`
45
71
  维护;应用拥有后台信息架构声明。页面实现、路由可达、菜单可见是三个不同合同:
46
72
 
@@ -11,10 +11,10 @@ OpenXiangda 2.0 默认生成 React 应用和共享契约。普通 CRUD、标准
11
11
  以下命令的版本占位符由随包资料替换为该根包的精确版本。网站源码阅读者应先确认要使用的发行版本。
12
12
 
13
13
  ```bash
14
- pnpm dlx openxiangda@2.5.0 skill install --force
15
- pnpm dlx openxiangda@2.5.0 auth status --base-url <平台地址> --json
16
- pnpm dlx openxiangda@2.5.0 login --base-url https://platform.example.com
17
- pnpm dlx openxiangda@2.5.0 create my-app --base-url https://platform.example.com
14
+ pnpm dlx openxiangda@2.7.0 skill install --force
15
+ pnpm dlx openxiangda@2.7.0 auth status --base-url <平台地址> --json
16
+ pnpm dlx openxiangda@2.7.0 login --base-url https://platform.example.com
17
+ pnpm dlx openxiangda@2.7.0 create my-app --base-url https://platform.example.com
18
18
  cd my-app
19
19
  pnpm openxiangda context --json
20
20
  pnpm openxiangda dev
@@ -114,9 +114,9 @@ MCP 的 `docs_read` 可以读取本说明,当前没有独立的源码操作 MC
114
114
  无需本地工作区,使用本 Skill 随包精确版本或已安装的对应 CLI:
115
115
 
116
116
  ```bash
117
- pnpm dlx openxiangda@2.5.0 auth status --base-url <平台> --json
118
- pnpm dlx openxiangda@2.5.0 source resolve <仓库URL> --base-url <平台> --json
119
- pnpm dlx openxiangda@2.5.0 source clone <仓库URL> <新目录> --base-url <平台> --json
117
+ pnpm dlx openxiangda@2.7.0 auth status --base-url <平台> --json
118
+ pnpm dlx openxiangda@2.7.0 source resolve <仓库URL> --base-url <平台> --json
119
+ pnpm dlx openxiangda@2.7.0 source clone <仓库URL> <新目录> --base-url <平台> --json
120
120
  ```
121
121
 
122
122
  登录缺失或站点不匹配时,先按该平台执行 login。resolve 根据平台已经登记的绑定返回
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "schemaVersion": "openxiangda.documentation/v1",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "topics": [
5
5
  {
6
6
  "id": "getting-started",
7
7
  "title": "安装与开始开发",
8
8
  "file": "getting-started.md",
9
- "sha256": "d2327918d1e82d341d62bd17343b00fe61d24fd0540ea0fdd6d5bda746571b24"
9
+ "sha256": "86d4364e8778ae34285164c13ea19a9f290017398565aa186506283f026206cc"
10
10
  },
11
11
  {
12
12
  "id": "product-design",
@@ -48,13 +48,13 @@
48
48
  "id": "frontend",
49
49
  "title": "页面与标准组件扩展",
50
50
  "file": "frontend.md",
51
- "sha256": "8073d6f66b994ade2e5a4e806062dfe2182fefd3b2fe695d8ebb2a176d7ae68b"
51
+ "sha256": "35a7ce0f00dd92c4d3155e953a2f95082572994b92d706ba677844e709dcaba8"
52
52
  },
53
53
  {
54
54
  "id": "field-components",
55
55
  "title": "字段、表单与移动控件",
56
56
  "file": "field-components.md",
57
- "sha256": "b26da9fb33518203c59a154dd0117f714f3edab5a4d84936b71107c936516893"
57
+ "sha256": "4bb36d6b6162be84aaf95b86fabe2e44805d5f9441dc8cfa5f951c24ce6d6102"
58
58
  },
59
59
  {
60
60
  "id": "data-authz",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "OpenXiangda 2.0 的统一命令、应用 SDK、MCP 与中文 AI 技能资料。",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,16 +55,18 @@
55
55
  "README.md"
56
56
  ],
57
57
  "dependencies": {
58
+ "@js-temporal/polyfill": "0.5.1",
59
+ "@rc-component/picker": "1.10.0",
58
60
  "antd-mobile": "5.42.3",
59
61
  "dayjs": "1.11.18",
60
62
  "docx-preview": "0.3.7",
61
- "openxiangda-cli": "2.2.7",
63
+ "openxiangda-cli": "2.2.9",
62
64
  "openxiangda-contracts": "2.5.0",
63
65
  "openxiangda-devkit-core": "2.4.1",
64
66
  "openxiangda-legacy": "npm:openxiangda@1.0.268",
65
67
  "openxiangda-mcp": "2.0.7",
66
68
  "openxiangda-nest": "2.1.0",
67
- "openxiangda-skill-kit": "2.0.9",
69
+ "openxiangda-skill-kit": "2.0.11",
68
70
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
69
71
  },
70
72
  "peerDependencies": {
@@ -130,18 +132,18 @@
130
132
  },
131
133
  "openxiangdaRelease": {
132
134
  "schemaVersion": "openxiangda.release-notes/v1",
133
- "version": "2.5.0",
134
- "title": "按业务记录恢复原流程命令",
135
+ "version": "2.7.0",
136
+ "title": "应用统一保护未保存内容",
135
137
  "status": "reviewed",
136
- "summary": "浏览器和 Nest 可在重新进入详情时按业务记录查找原流程命令,继续原回执和进度查询。",
138
+ "summary": "自定义表单可注册未保存状态,应用统一处理站内跳转、浏览器历史和刷新关闭提示。",
137
139
  "newFeatures": [
138
- "增加当前用户范围的流程命令分页查询,支持精确记录、流程和操作筛选,每页最多 50 条。"
140
+ "增加 useUnsavedChangesGuard,聚合多个表单的未保存状态,取消导航保留输入和原位置,提交成功后解除保护。"
139
141
  ],
140
142
  "fixes": [
141
- "补齐业务记录已提交但流程事件尚未投影时,从列表重新进入详情无法定位原命令的恢复路径。"
143
+ "补齐原 BrowserRouter 无法使用标准 useBlocker 导致自定义表单浏览器前进后退未受保护的问题。"
142
144
  ],
143
145
  "affectedUsers": [
144
- "使用 Business Process 原子提交业务数据与流程的 V2 应用开发者。"
146
+ "有自定义录入页面、异步提交或未知结果恢复的 V2 应用开发者。"
145
147
  ],
146
148
  "compatibility": {
147
149
  "node": ">=24",
@@ -150,20 +152,20 @@
150
152
  "v2"
151
153
  ],
152
154
  "v1Policy": "V1 引擎和已有应用不变。",
153
- "platformPolicy": "使用 Business Process 的新编译包要求 durable-command 1.1.0 和匹配的共享校验器;旧客户端继续兼容。"
155
+ "platformPolicy": "公共 React 路由生命周期调整,无服务端契约或数据库变更;应用仍使用既有 Routes、Link navigate。"
154
156
  },
155
157
  "upgradeSteps": [
156
- "将应用精确依赖升级至 openxiangda 2.5.0,更新锁文件并刷新技能资料。",
157
- "平台部署匹配版本后执行检查和测试发布,验证重新进入详情时恢复原命令而不重复提交。"
158
+ "精确升级到 openxiangda 2.7.0 并刷新技能资料。",
159
+ "在应用入口内使用 useUnsavedChangesGuard,涵盖未保存内容和结果未知状态,验证成功后解除以及取消后的输入保留。"
158
160
  ],
159
161
  "knownLimitations": [
160
- "查询沿用原命令的发起人或既有超级管理员权限,记录读取权限不授予他人命令访问。",
161
- "同一记录可能有多次流程,应用须根据业务约束选择原命令,不能任意选择第一条。",
162
- "包发布、平台部署和实际业务验收分别验证。"
162
+ "原生刷新/关闭提示受浏览器限制,不能自定义提示文字。",
163
+ "该能力不持久化草稿或代替原提交回执恢复;应用不得直接操作 history.pushState。",
164
+ "包发布、应用部署与真实业务验收分别验证。"
163
165
  ],
164
166
  "issues": [],
165
- "sha256": "35a3bd6f8f97d3261243e1c65e2876a946448c5af455f43ababf18bd8f6f3653",
166
- "url": "https://github.com/1377385356/openxiangda/releases/tag/v2.5.0"
167
+ "sha256": "e8af0fc7c484cad1dc59ce982432e6a2fd4451d7f455141edc2d6128a057542e",
168
+ "url": "https://github.com/1377385356/openxiangda/releases/tag/v2.7.0"
167
169
  },
168
170
  "scripts": {
169
171
  "build": "node ../../scripts/prune-package-dist.mjs && tsc -p tsconfig.json && node scripts/copy-assets.mjs",
@@ -0,0 +1,37 @@
1
+ {
2
+ "schemaVersion": "openxiangda.release-notes/v1",
3
+ "version": "2.6.0",
4
+ "title": "统一应用时区与日期时间输入",
5
+ "status": "reviewed",
6
+ "summary": "应用可指定业务展示时区,标准字段、审批详情、待办、通知和审计时间统一显示,日期时间输入仍保存 UTC。",
7
+ "newFeatures": [
8
+ "OpenXiangdaApplication 和 OpenXiangdaUiProvider 接受可选 timeZone;日期时间字段可覆盖时区并声明 min、max 和 minuteStep。"
9
+ ],
10
+ "fixes": [
11
+ "修复设备时区不同导致日期时间编辑和公共详情、中心时间不一致的问题,拒绝夏令时不存在或重复的本地时间。"
12
+ ],
13
+ "affectedUsers": [
14
+ "需要固定业务时区或限制日期时间输入的 V2 应用开发者。"
15
+ ],
16
+ "compatibility": {
17
+ "node": ">=24",
18
+ "workspaceGenerations": [
19
+ "v1",
20
+ "v2"
21
+ ],
22
+ "v1Policy": "V1 引擎和已有应用不变。",
23
+ "platformPolicy": "展示与输入能力,无新增服务端契约或数据库迁移。未配置时区和限制的应用保留设备本地行为。"
24
+ },
25
+ "upgradeSteps": [
26
+ "将应用精确依赖升级至 openxiangda 2.6.0,更新锁文件并刷新技能资料。",
27
+ "在应用入口指定业务 timeZone,验证 PC 和移动端编辑、审批摘要与各中心显示。"
28
+ ],
29
+ "knownLimitations": [
30
+ "时区只影响呈现;服务端仍须独立验证业务时间窗口和授权。",
31
+ "手机指定时区的日期时间滚轮提供当前选择前后各 365 天并按限制收窄;夏令时重复时间需选择其他无歧义时间。",
32
+ "包发布、应用部署和实际业务验收分别验证。"
33
+ ],
34
+ "issues": [],
35
+ "sha256": "ba11ac3a69cbd9dd27e339c1d84642af99e107ca1170f0876b8be0583abda79f",
36
+ "url": "https://github.com/1377385356/openxiangda/releases/tag/v2.6.0"
37
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "schemaVersion": "openxiangda.release-notes/v1",
3
+ "version": "2.7.0",
4
+ "title": "应用统一保护未保存内容",
5
+ "status": "reviewed",
6
+ "summary": "自定义表单可注册未保存状态,应用统一处理站内跳转、浏览器历史和刷新关闭提示。",
7
+ "newFeatures": [
8
+ "增加 useUnsavedChangesGuard,聚合多个表单的未保存状态,取消导航保留输入和原位置,提交成功后解除保护。"
9
+ ],
10
+ "fixes": [
11
+ "补齐原 BrowserRouter 无法使用标准 useBlocker 导致自定义表单浏览器前进后退未受保护的问题。"
12
+ ],
13
+ "affectedUsers": [
14
+ "有自定义录入页面、异步提交或未知结果恢复的 V2 应用开发者。"
15
+ ],
16
+ "compatibility": {
17
+ "node": ">=24",
18
+ "workspaceGenerations": [
19
+ "v1",
20
+ "v2"
21
+ ],
22
+ "v1Policy": "V1 引擎和已有应用不变。",
23
+ "platformPolicy": "公共 React 路由生命周期调整,无服务端契约或数据库变更;应用仍使用既有 Routes、Link 和 navigate。"
24
+ },
25
+ "upgradeSteps": [
26
+ "精确升级到 openxiangda 2.7.0 并刷新技能资料。",
27
+ "在应用入口内使用 useUnsavedChangesGuard,涵盖未保存内容和结果未知状态,验证成功后解除以及取消后的输入保留。"
28
+ ],
29
+ "knownLimitations": [
30
+ "原生刷新/关闭提示受浏览器限制,不能自定义提示文字。",
31
+ "该能力不持久化草稿或代替原提交回执恢复;应用不得直接操作 history.pushState。",
32
+ "包发布、应用部署与真实业务验收分别验证。"
33
+ ],
34
+ "issues": [],
35
+ "sha256": "e8af0fc7c484cad1dc59ce982432e6a2fd4451d7f455141edc2d6128a057542e",
36
+ "url": "https://github.com/1377385356/openxiangda/releases/tag/v2.7.0"
37
+ }
@@ -4,7 +4,7 @@
4
4
  {
5
5
  "name": "openxiangda-v2",
6
6
  "description": "使用 OpenXiangda 2.0 从模糊业务想法、已有资料或具体变更出发,通过对话发现模块、完成详细产品设计,再开发、检查和交付应用。维护 1.x 应用时使用对应的 1.x 技能。",
7
- "sha256": "d001775cd43ef5b66b371f41ae64f982da68ce4f84f0a9943b2bac3f27fbea63"
7
+ "sha256": "76c31169ed695c8af811b9a7d42b10345cf3e4ea31c7cdce5986bbf20b1608df"
8
8
  }
9
9
  ]
10
10
  }
@@ -18,10 +18,10 @@ description: 使用 OpenXiangda 2.0 从模糊业务想法、已有资料或具
18
18
  未创建工作区时使用本 Skill 随根包发布的精确版本:
19
19
 
20
20
  ```bash
21
- pnpm dlx openxiangda@2.5.0 auth status --base-url <平台地址> --json
22
- pnpm dlx openxiangda@2.5.0 login --base-url <平台地址>
23
- pnpm dlx openxiangda@2.5.0 create <应用目录> --base-url <同一平台地址>
24
- pnpm dlx openxiangda@2.5.0 skill install --force
21
+ pnpm dlx openxiangda@2.7.0 auth status --base-url <平台地址> --json
22
+ pnpm dlx openxiangda@2.7.0 login --base-url <平台地址>
23
+ pnpm dlx openxiangda@2.7.0 create <应用目录> --base-url <同一平台地址>
24
+ pnpm dlx openxiangda@2.7.0 skill install --force
25
25
  ```
26
26
 
27
27
  创建前把产品要求的目标平台明确带入命令,不从旧登录态推断站点。已有工作区从原绑定恢复,平台不一致时先解决登录与目标,不改 link 文件跨站创建。
@@ -214,6 +214,31 @@ pnpm openxiangda check
214
214
 
215
215
  ## 移动字段呈现与分组
216
216
 
217
+ ### 应用时区与时间限制
218
+
219
+ `OpenXiangdaApplication` 的可选 `timeZone="Asia/Shanghai"` 统一标准表单、详情、
220
+ 审批业务摘要、待办/通知、审计和草稿时间的展示。独立使用组件时可在
221
+ `OpenXiangdaUiProvider` 传同一参数;不指定时保留浏览器本地时区。
222
+ 这只影响输入与展示,`datetime` / `datetime-range` 仍读写 UTC ISO instant。
223
+ `date` / `date-range` 保留自然日期,`time` 保留无日期时间。
224
+
225
+ `DateTimeField`、`DateTimeFilter`、`DateTimeValueDisplay` 和 `MobileDateTimeField`
226
+ 可显式传 `timeZone` 覆盖应用默认。日期时间输入还可传 `min` / `max`(含端点的
227
+ ISO instant)与 `minuteStep`(1 到 60 且整除 60)。设置步长后只接受整分钟,秒和
228
+ 毫秒为零;例如 `minuteStep={15}`。服务端仍须验证最终业务窗口与授权。
229
+
230
+ ```tsx
231
+ <DateTimeField field={startsAtField} value={startsAt} onChange={setStartsAt}
232
+ timeZone="Asia/Shanghai" minuteStep={15}
233
+ min="2026-09-08T01:00:00Z" max="2026-10-08T01:00:00Z" />
234
+ ```
235
+
236
+ 输入到夏令时不存在或重复的墙上时间时显示错误,不自动选偏移。无效时区、步长或
237
+ 上下限配置会报错。手机指定时区的日期时间使用日期/时间滚轮,最多提供当前选择前后
238
+ 各 365 天并按限制收窄;范围仍分两步确认,取消不修改原值。
239
+
240
+ ### 字段布局
241
+
217
242
  移动字段自身提供无边框输入、上下标签、行分隔和错误提示;标准表单与自定义页面使用同一
218
243
  字段组件。页面负责把相关字段组织在浅色背景上的白色分组中,不另设移动主题配置。
219
244
 
@@ -41,6 +41,32 @@ DataQuery 使用有界 where 条件树,支持 and/or/not。标准列表的筛
41
41
 
42
42
  ## 标准后台扩展
43
43
 
44
+ ### 未保存内容的离开保护
45
+
46
+ 自定义表单可在 `OpenXiangdaApplication` 内调用
47
+ `useUnsavedChangesGuard({ when, message? })`。`when` 包含未保存表单、正在提交或
48
+ 结果尚不确定的状态;成功后清除,组件卸载时自动注销。多个表单由应用入口统一汇总,
49
+ 不需要应用创建路由或拦截 document 点击。
50
+
51
+ ```tsx
52
+ useUnsavedChangesGuard({
53
+ when: !result && (hasDraft || pending || hasUnresolvedIntent),
54
+ message: '会议尚未提交完成,离开将丢失当前填写内容。',
55
+ });
56
+ ```
57
+
58
+ 站内使用 React Router 的 `Link` 或 `navigate`,前进/后退与程序跳转使用同一确认框。
59
+ 确认框打开时保留第一次目标,取消后继续原地编辑。刷新、关闭和文档跳转使用浏览器
60
+ 原生提示,其文案和是否展示受浏览器限制。保存成功可在状态清除后的 effect 中跳转。
61
+ 该 hook 只保护导航,不持久化草稿或恢复提交回执;业务数据仍由各自既有能力负责。
62
+ 不要直接调用 `history.pushState` 或修改路由内部状态。
63
+
64
+ ### 应用时区
65
+
66
+ 如业务采用固定时区,在现有 `OpenXiangdaApplication` 传可选 `timeZone`,例如
67
+ `Asia/Shanghai`。标准表单、审批摘要和各中心时间随同一 UI Provider 展示,应用无需
68
+ 修改设备时区或保存第二份时间。具体控件参数见[字段组件](field-components.md)。
69
+
44
70
  默认 CRUD、统一 Shell、current-user 权限和 Data Provider 都由 `openxiangda/react`
45
71
  维护;应用拥有后台信息架构声明。页面实现、路由可达、菜单可见是三个不同合同:
46
72
 
@@ -11,10 +11,10 @@ OpenXiangda 2.0 默认生成 React 应用和共享契约。普通 CRUD、标准
11
11
  以下命令的版本占位符由随包资料替换为该根包的精确版本。网站源码阅读者应先确认要使用的发行版本。
12
12
 
13
13
  ```bash
14
- pnpm dlx openxiangda@2.5.0 skill install --force
15
- pnpm dlx openxiangda@2.5.0 auth status --base-url <平台地址> --json
16
- pnpm dlx openxiangda@2.5.0 login --base-url https://platform.example.com
17
- pnpm dlx openxiangda@2.5.0 create my-app --base-url https://platform.example.com
14
+ pnpm dlx openxiangda@2.7.0 skill install --force
15
+ pnpm dlx openxiangda@2.7.0 auth status --base-url <平台地址> --json
16
+ pnpm dlx openxiangda@2.7.0 login --base-url https://platform.example.com
17
+ pnpm dlx openxiangda@2.7.0 create my-app --base-url https://platform.example.com
18
18
  cd my-app
19
19
  pnpm openxiangda context --json
20
20
  pnpm openxiangda dev
@@ -114,9 +114,9 @@ MCP 的 `docs_read` 可以读取本说明,当前没有独立的源码操作 MC
114
114
  无需本地工作区,使用本 Skill 随包精确版本或已安装的对应 CLI:
115
115
 
116
116
  ```bash
117
- pnpm dlx openxiangda@2.5.0 auth status --base-url <平台> --json
118
- pnpm dlx openxiangda@2.5.0 source resolve <仓库URL> --base-url <平台> --json
119
- pnpm dlx openxiangda@2.5.0 source clone <仓库URL> <新目录> --base-url <平台> --json
117
+ pnpm dlx openxiangda@2.7.0 auth status --base-url <平台> --json
118
+ pnpm dlx openxiangda@2.7.0 source resolve <仓库URL> --base-url <平台> --json
119
+ pnpm dlx openxiangda@2.7.0 source clone <仓库URL> <新目录> --base-url <平台> --json
120
120
  ```
121
121
 
122
122
  登录缺失或站点不匹配时,先按该平台执行 login。resolve 根据平台已经登记的绑定返回