@robot-admin/naive-ui-components 0.4.3 → 0.4.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 (285) hide show
  1. package/dist/C_ActionBar.cjs +1 -5
  2. package/dist/C_ActionBar.js +1 -4
  3. package/dist/C_ActionBar.js.map +1 -0
  4. package/dist/C_ActionBar2.js +1 -195
  5. package/dist/C_ActionBar2.js.map +1 -1
  6. package/dist/C_AntV.cjs +1 -8
  7. package/dist/C_AntV.js +1 -4
  8. package/dist/C_AntV.js.map +1 -0
  9. package/dist/C_AntV2.js +4 -3149
  10. package/dist/C_AntV2.js.map +1 -1
  11. package/dist/C_Barcode.cjs +1 -4
  12. package/dist/C_Barcode.js +1 -3
  13. package/dist/C_Barcode.js.map +1 -0
  14. package/dist/C_Barcode2.js +1 -67
  15. package/dist/C_Barcode2.js.map +1 -1
  16. package/dist/C_Captcha.cjs +1 -4
  17. package/dist/C_Captcha.js +1 -3
  18. package/dist/C_Captcha.js.map +1 -0
  19. package/dist/C_Captcha2.js +1 -154
  20. package/dist/C_Captcha2.js.map +1 -1
  21. package/dist/C_Cascade.cjs +1 -4
  22. package/dist/C_Cascade.js +1 -3
  23. package/dist/C_Cascade.js.map +1 -0
  24. package/dist/C_Cascade2.js +1 -102
  25. package/dist/C_Cascade2.js.map +1 -1
  26. package/dist/C_City.cjs +1 -4
  27. package/dist/C_City.js +1 -3
  28. package/dist/C_City.js.map +1 -0
  29. package/dist/C_City2.js +1 -840
  30. package/dist/C_City2.js.map +1 -1
  31. package/dist/C_Code.cjs +1 -5
  32. package/dist/C_Code.js +1 -4
  33. package/dist/C_Code.js.map +1 -0
  34. package/dist/C_Code2.js +1 -346
  35. package/dist/C_Code2.js.map +1 -1
  36. package/dist/C_CollapsePanel.cjs +1 -6
  37. package/dist/C_CollapsePanel.js +1 -4
  38. package/dist/C_CollapsePanel.js.map +1 -0
  39. package/dist/C_CollapsePanel2.js +1 -318
  40. package/dist/C_CollapsePanel2.js.map +1 -1
  41. package/dist/C_Cron.cjs +1 -15
  42. package/dist/C_Cron.js +1 -4
  43. package/dist/C_Cron.js.map +1 -0
  44. package/dist/C_Cron2.js +1 -1209
  45. package/dist/C_Cron2.js.map +1 -1
  46. package/dist/C_Date.cjs +1 -4
  47. package/dist/C_Date.js +1 -3
  48. package/dist/C_Date.js.map +1 -0
  49. package/dist/C_Date2.js +1 -218
  50. package/dist/C_Date2.js.map +1 -1
  51. package/dist/C_Draggable.cjs +1 -5
  52. package/dist/C_Draggable.js +1 -3
  53. package/dist/C_Draggable.js.map +1 -0
  54. package/dist/C_Draggable2.js +1 -294
  55. package/dist/C_Draggable2.js.map +1 -1
  56. package/dist/C_Editor.cjs +1 -4
  57. package/dist/C_Editor.js +1 -3
  58. package/dist/C_Editor.js.map +1 -0
  59. package/dist/C_Editor2.js +1 -159
  60. package/dist/C_Editor2.js.map +1 -1
  61. package/dist/C_FilePreview.cjs +1 -7
  62. package/dist/C_FilePreview.js +1 -4
  63. package/dist/C_FilePreview.js.map +1 -0
  64. package/dist/C_FilePreview2.js +1 -1031
  65. package/dist/C_FilePreview2.js.map +1 -1
  66. package/dist/C_Form.cjs +1 -16
  67. package/dist/C_Form.js +1 -5
  68. package/dist/C_Form.js.map +1 -0
  69. package/dist/C_Form2.js +1 -2569
  70. package/dist/C_Form2.js.map +1 -1
  71. package/dist/C_FormSearch.cjs +1 -6
  72. package/dist/C_FormSearch.js +1 -3
  73. package/dist/C_FormSearch.js.map +1 -0
  74. package/dist/C_FormSearch2.js +1 -355
  75. package/dist/C_FormSearch2.js.map +1 -1
  76. package/dist/C_FormulaEditor.cjs +1 -13
  77. package/dist/C_FormulaEditor.js +1 -4
  78. package/dist/C_FormulaEditor.js.map +1 -0
  79. package/dist/C_FormulaEditor2.js +1 -1432
  80. package/dist/C_FormulaEditor2.js.map +1 -1
  81. package/dist/C_FullCalendar.cjs +1 -9
  82. package/dist/C_FullCalendar.js +1 -3
  83. package/dist/C_FullCalendar.js.map +1 -0
  84. package/dist/C_FullCalendar2.js +1 -376
  85. package/dist/C_FullCalendar2.js.map +1 -1
  86. package/dist/C_GlobalSearch.cjs +1 -5
  87. package/dist/C_GlobalSearch.js +1 -3
  88. package/dist/C_GlobalSearch.js.map +1 -0
  89. package/dist/C_GlobalSearch2.js +1 -335
  90. package/dist/C_GlobalSearch2.js.map +1 -1
  91. package/dist/C_Guide.cjs +1 -5
  92. package/dist/C_Guide.js +1 -4
  93. package/dist/C_Guide.js.map +1 -0
  94. package/dist/C_Guide2.js +1 -60
  95. package/dist/C_Guide2.js.map +1 -1
  96. package/dist/C_Icon.cjs +1 -4
  97. package/dist/C_Icon.js +1 -3
  98. package/dist/C_Icon.js.map +1 -0
  99. package/dist/C_Icon2.js +1 -285
  100. package/dist/C_Icon2.js.map +1 -1
  101. package/dist/C_ImageCropper.cjs +1 -6
  102. package/dist/C_ImageCropper.js +1 -4
  103. package/dist/C_ImageCropper.js.map +1 -0
  104. package/dist/C_ImageCropper2.js +1 -722
  105. package/dist/C_ImageCropper2.js.map +1 -1
  106. package/dist/C_Language.cjs +1 -5
  107. package/dist/C_Language.js +1 -4
  108. package/dist/C_Language.js.map +1 -0
  109. package/dist/C_Language2.js +1 -78
  110. package/dist/C_Language2.js.map +1 -1
  111. package/dist/C_Map.cjs +1 -7
  112. package/dist/C_Map.js +1 -3
  113. package/dist/C_Map.js.map +1 -0
  114. package/dist/C_Map2.js +1 -198
  115. package/dist/C_Map2.js.map +1 -1
  116. package/dist/C_Markdown.cjs +1 -4
  117. package/dist/C_Markdown.js +1 -3
  118. package/dist/C_Markdown.js.map +1 -0
  119. package/dist/C_Markdown2.js +1 -185
  120. package/dist/C_Markdown2.js.map +1 -1
  121. package/dist/C_NotificationCenter.cjs +1 -20
  122. package/dist/C_NotificationCenter.js +1 -4
  123. package/dist/C_NotificationCenter.js.map +1 -0
  124. package/dist/C_NotificationCenter2.js +1 -1383
  125. package/dist/C_NotificationCenter2.js.map +1 -1
  126. package/dist/C_Progress.cjs +1 -4
  127. package/dist/C_Progress.js +1 -3
  128. package/dist/C_Progress.js.map +1 -0
  129. package/dist/C_Progress2.js +1 -102
  130. package/dist/C_Progress2.js.map +1 -1
  131. package/dist/C_QRCode.cjs +1 -5
  132. package/dist/C_QRCode.js +1 -3
  133. package/dist/C_QRCode.js.map +1 -0
  134. package/dist/C_QRCode2.js +1 -217
  135. package/dist/C_QRCode2.js.map +1 -1
  136. package/dist/C_Signature.cjs +1 -8
  137. package/dist/C_Signature.js +1 -4
  138. package/dist/C_Signature.js.map +1 -0
  139. package/dist/C_Signature2.js +1 -617
  140. package/dist/C_Signature2.js.map +1 -1
  141. package/dist/C_SplitPane.cjs +1 -6
  142. package/dist/C_SplitPane.js +1 -4
  143. package/dist/C_SplitPane.js.map +1 -0
  144. package/dist/C_SplitPane2.js +1 -355
  145. package/dist/C_SplitPane2.js.map +1 -1
  146. package/dist/C_Steps.cjs +1 -4
  147. package/dist/C_Steps.js +1 -3
  148. package/dist/C_Steps.js.map +1 -0
  149. package/dist/C_Steps2.js +1 -81
  150. package/dist/C_Steps2.js.map +1 -1
  151. package/dist/C_Table.cjs +1 -20
  152. package/dist/C_Table.js +1 -6
  153. package/dist/C_Table.js.map +1 -0
  154. package/dist/C_Table2.js +1 -3023
  155. package/dist/C_Table2.js.map +1 -1
  156. package/dist/C_Theme.cjs +1 -5
  157. package/dist/C_Theme.js +1 -4
  158. package/dist/C_Theme.js.map +1 -0
  159. package/dist/C_Theme2.js +1 -63
  160. package/dist/C_Theme2.js.map +1 -1
  161. package/dist/C_Time.cjs +1 -5
  162. package/dist/C_Time.js +1 -3
  163. package/dist/C_Time.js.map +1 -0
  164. package/dist/C_Time2.js +1 -198
  165. package/dist/C_Time2.js.map +1 -1
  166. package/dist/C_Tree.cjs +1 -7
  167. package/dist/C_Tree.js +1 -4
  168. package/dist/C_Tree.js.map +1 -0
  169. package/dist/C_Tree2.js +1 -440
  170. package/dist/C_Tree2.js.map +1 -1
  171. package/dist/C_Upload.cjs +1 -12
  172. package/dist/C_Upload.js +1 -4
  173. package/dist/C_Upload.js.map +1 -0
  174. package/dist/C_Upload2.js +2 -1365
  175. package/dist/C_Upload2.js.map +1 -1
  176. package/dist/C_VideoPlayer.cjs +1 -23
  177. package/dist/C_VideoPlayer.js +1 -3
  178. package/dist/C_VideoPlayer.js.map +1 -0
  179. package/dist/C_VideoPlayer2.js +3 -1932
  180. package/dist/C_VideoPlayer2.js.map +1 -1
  181. package/dist/C_VtableGantt.cjs +1 -6
  182. package/dist/C_VtableGantt.js +1 -4
  183. package/dist/C_VtableGantt.js.map +1 -0
  184. package/dist/C_VtableGantt2.js +1 -872
  185. package/dist/C_VtableGantt2.js.map +1 -1
  186. package/dist/C_WaterFall.cjs +1 -13
  187. package/dist/C_WaterFall.js +1 -3
  188. package/dist/C_WaterFall.js.map +1 -0
  189. package/dist/C_WaterFall2.js +1 -364
  190. package/dist/C_WaterFall2.js.map +1 -1
  191. package/dist/C_WorkFlow.cjs +1 -8
  192. package/dist/C_WorkFlow.js +1 -4
  193. package/dist/C_WorkFlow.js.map +1 -0
  194. package/dist/C_WorkFlow2.js +1 -1983
  195. package/dist/C_WorkFlow2.js.map +1 -1
  196. package/dist/chunk.js +1 -18
  197. package/dist/city.js +1 -4816
  198. package/dist/constants.d.ts +2 -2
  199. package/dist/constants2.d.ts +3 -3
  200. package/dist/constants3.d.ts +3 -3
  201. package/dist/constants4.d.ts +5 -5
  202. package/dist/constants5.d.ts +2 -2
  203. package/dist/data.d.ts +1 -1
  204. package/dist/export-helper.js +1 -9
  205. package/dist/index.cjs +2 -413
  206. package/dist/index.cjs.map +1 -0
  207. package/dist/index.d.cts +1 -2
  208. package/dist/index.d.ts +1 -2
  209. package/dist/index.js +1 -231
  210. package/dist/index.js.map +1 -1
  211. package/dist/index.vue.d.ts +2 -2
  212. package/dist/index10.vue.d.ts +5 -5
  213. package/dist/index12.vue.d.ts +3 -3
  214. package/dist/index13.vue.d.ts +3 -3
  215. package/dist/index14.vue.d.ts +3 -3
  216. package/dist/index16.vue.d.ts +3 -3
  217. package/dist/index3.vue.d.ts +3 -3
  218. package/dist/index5.vue.d.ts +1 -1
  219. package/dist/index7.vue.d.ts +4 -4
  220. package/dist/index8.vue.d.ts +2 -2
  221. package/dist/resolver.cjs +2 -89
  222. package/dist/resolver.cjs.map +1 -0
  223. package/dist/resolver.js +1 -86
  224. package/dist/resolver.js.map +1 -1
  225. package/dist/storage.js +1 -30
  226. package/dist/storage.js.map +1 -1
  227. package/dist/useCollapsePanel.d.ts +2 -2
  228. package/dist/useCropperCore.d.ts +8 -8
  229. package/dist/useDraggableLayout.d.ts +4 -4
  230. package/dist/useDynamicFormState.d.ts +7 -7
  231. package/dist/useEdgeInteraction.d.ts +1 -1
  232. package/dist/useFullscreen.d.ts +2 -2
  233. package/dist/useInfiniteScroll.d.ts +1 -1
  234. package/dist/useModalEdit.d.ts +1 -1
  235. package/dist/useQRCode.d.ts +3 -3
  236. package/dist/useSearchState.d.ts +2 -2
  237. package/dist/useSignatureHistory.d.ts +1 -1
  238. package/dist/useSplitResize.d.ts +6 -6
  239. package/dist/useTimeSelection.d.ts +2 -2
  240. package/dist/useTreeOperations.d.ts +6 -6
  241. package/dist/useWorkflowValidation.d.ts +4 -4
  242. package/package.json +1 -2
  243. package/dist/constants.d.ts.map +0 -1
  244. package/dist/constants2.d.ts.map +0 -1
  245. package/dist/constants3.d.ts.map +0 -1
  246. package/dist/constants4.d.ts.map +0 -1
  247. package/dist/constants5.d.ts.map +0 -1
  248. package/dist/data.d.ts.map +0 -1
  249. package/dist/index.d.cts.map +0 -1
  250. package/dist/index.d.ts.map +0 -1
  251. package/dist/index.vue.d.ts.map +0 -1
  252. package/dist/index10.vue.d.ts.map +0 -1
  253. package/dist/index11.vue.d.ts.map +0 -1
  254. package/dist/index12.vue.d.ts.map +0 -1
  255. package/dist/index13.vue.d.ts.map +0 -1
  256. package/dist/index14.vue.d.ts.map +0 -1
  257. package/dist/index15.vue.d.ts.map +0 -1
  258. package/dist/index16.vue.d.ts.map +0 -1
  259. package/dist/index2.vue.d.ts.map +0 -1
  260. package/dist/index3.vue.d.ts.map +0 -1
  261. package/dist/index4.vue.d.ts.map +0 -1
  262. package/dist/index5.vue.d.ts.map +0 -1
  263. package/dist/index6.vue.d.ts.map +0 -1
  264. package/dist/index7.vue.d.ts.map +0 -1
  265. package/dist/index8.vue.d.ts.map +0 -1
  266. package/dist/index9.vue.d.ts.map +0 -1
  267. package/dist/resolver.d.cts.map +0 -1
  268. package/dist/resolver.d.ts.map +0 -1
  269. package/dist/useCalendarEvents.d.ts.map +0 -1
  270. package/dist/useCollapsePanel.d.ts.map +0 -1
  271. package/dist/useCropperCore.d.ts.map +0 -1
  272. package/dist/useDraggableLayout.d.ts.map +0 -1
  273. package/dist/useDynamicFormState.d.ts.map +0 -1
  274. package/dist/useEdgeInteraction.d.ts.map +0 -1
  275. package/dist/useFullscreen.d.ts.map +0 -1
  276. package/dist/useGlobalSearch.d.ts.map +0 -1
  277. package/dist/useInfiniteScroll.d.ts.map +0 -1
  278. package/dist/useModalEdit.d.ts.map +0 -1
  279. package/dist/useQRCode.d.ts.map +0 -1
  280. package/dist/useSearchState.d.ts.map +0 -1
  281. package/dist/useSignatureHistory.d.ts.map +0 -1
  282. package/dist/useSplitResize.d.ts.map +0 -1
  283. package/dist/useTimeSelection.d.ts.map +0 -1
  284. package/dist/useTreeOperations.d.ts.map +0 -1
  285. package/dist/useWorkflowValidation.d.ts.map +0 -1
package/dist/C_Cron2.js CHANGED
@@ -1,1210 +1,2 @@
1
- import { t as C_Icon_default } from "./C_Icon2.js";
2
- import { t as export_helper_default } from "./export-helper.js";
3
- import { NButton, NEmpty, NInput, NInputNumber, NRadioButton, NRadioGroup, NScrollbar, NSpin, NTag } from "naive-ui";
4
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, toDisplayString, unref, vShow, watch, withCtx, withDirectives, withKeys } from "vue";
5
-
6
- //#region src/components/C_Cron/constants.ts
7
- const CRON_FIELD_META = [
8
- {
9
- type: "second",
10
- label: "秒",
11
- min: 0,
12
- max: 59
13
- },
14
- {
15
- type: "minute",
16
- label: "分",
17
- min: 0,
18
- max: 59
19
- },
20
- {
21
- type: "hour",
22
- label: "时",
23
- min: 0,
24
- max: 23
25
- },
26
- {
27
- type: "day",
28
- label: "日",
29
- min: 1,
30
- max: 31
31
- },
32
- {
33
- type: "month",
34
- label: "月",
35
- min: 1,
36
- max: 12
37
- },
38
- {
39
- type: "week",
40
- label: "周",
41
- min: 1,
42
- max: 7,
43
- valueLabels: {
44
- 1: "周日",
45
- 2: "周一",
46
- 3: "周二",
47
- 4: "周三",
48
- 5: "周四",
49
- 6: "周五",
50
- 7: "周六"
51
- }
52
- }
53
- ];
54
- const DEFAULT_FIELD_VALUE = {
55
- mode: "every",
56
- rangeStart: 0,
57
- rangeEnd: 0,
58
- stepStart: 0,
59
- stepInterval: 1,
60
- specificValues: []
61
- };
62
- const DEFAULT_CRON_VALUE = {
63
- second: {
64
- ...DEFAULT_FIELD_VALUE,
65
- rangeEnd: 59
66
- },
67
- minute: {
68
- ...DEFAULT_FIELD_VALUE,
69
- rangeEnd: 59
70
- },
71
- hour: {
72
- ...DEFAULT_FIELD_VALUE,
73
- rangeEnd: 23
74
- },
75
- day: {
76
- ...DEFAULT_FIELD_VALUE,
77
- rangeStart: 1,
78
- rangeEnd: 31
79
- },
80
- month: {
81
- ...DEFAULT_FIELD_VALUE,
82
- rangeStart: 1,
83
- rangeEnd: 12
84
- },
85
- week: {
86
- ...DEFAULT_FIELD_VALUE,
87
- mode: "none",
88
- rangeStart: 1,
89
- rangeEnd: 7
90
- }
91
- };
92
- const DEFAULT_CRON_EXPRESSION = "0 0 0 * * ?";
93
- const CRON_TEMPLATES = [
94
- {
95
- label: "每秒执行",
96
- value: "* * * * * ?",
97
- description: "每秒执行一次",
98
- icon: "mdi:timer-sand"
99
- },
100
- {
101
- label: "每分钟执行",
102
- value: "0 * * * * ?",
103
- description: "每分钟第 0 秒执行",
104
- icon: "mdi:clock-outline"
105
- },
106
- {
107
- label: "每小时执行",
108
- value: "0 0 * * * ?",
109
- description: "每小时整点执行",
110
- icon: "mdi:clock-time-twelve-outline"
111
- },
112
- {
113
- label: "每天 0 点",
114
- value: "0 0 0 * * ?",
115
- description: "每天凌晨 00:00 执行",
116
- icon: "mdi:weather-night"
117
- },
118
- {
119
- label: "每天 8:30",
120
- value: "0 30 8 * * ?",
121
- description: "每天早上 08:30 执行",
122
- icon: "mdi:weather-sunny"
123
- },
124
- {
125
- label: "每天 12:00",
126
- value: "0 0 12 * * ?",
127
- description: "每天中午 12:00 执行",
128
- icon: "mdi:food"
129
- },
130
- {
131
- label: "工作日 9:00",
132
- value: "0 0 9 ? * 2-6",
133
- description: "周一至周五 09:00 执行",
134
- icon: "mdi:briefcase-outline"
135
- },
136
- {
137
- label: "每周一 0 点",
138
- value: "0 0 0 ? * 2",
139
- description: "每周一凌晨 00:00 执行",
140
- icon: "mdi:calendar-week"
141
- },
142
- {
143
- label: "每月 1 号 0 点",
144
- value: "0 0 0 1 * ?",
145
- description: "每月 1 号凌晨 00:00 执行",
146
- icon: "mdi:calendar-month"
147
- },
148
- {
149
- label: "每 5 分钟",
150
- value: "0 0/5 * * * ?",
151
- description: "每隔 5 分钟执行一次",
152
- icon: "mdi:timer-5"
153
- },
154
- {
155
- label: "每 30 分钟",
156
- value: "0 0/30 * * * ?",
157
- description: "每隔 30 分钟执行一次",
158
- icon: "mdi:timer-30"
159
- },
160
- {
161
- label: "每 2 小时",
162
- value: "0 0 0/2 * * ?",
163
- description: "每隔 2 小时执行一次",
164
- icon: "mdi:timer-2"
165
- }
166
- ];
167
- const MONTH_LABELS = {
168
- 1: "一月",
169
- 2: "二月",
170
- 3: "三月",
171
- 4: "四月",
172
- 5: "五月",
173
- 6: "六月",
174
- 7: "七月",
175
- 8: "八月",
176
- 9: "九月",
177
- 10: "十月",
178
- 11: "十一月",
179
- 12: "十二月"
180
- };
181
- const WEEK_LABELS = {
182
- 1: "周日",
183
- 2: "周一",
184
- 3: "周二",
185
- 4: "周三",
186
- 5: "周四",
187
- 6: "周五",
188
- 7: "周六"
189
- };
190
-
191
- //#endregion
192
- //#region src/components/C_Cron/composables/useCronParser.ts
193
- const FIELD_ORDER = [
194
- "second",
195
- "minute",
196
- "hour",
197
- "day",
198
- "month",
199
- "week"
200
- ];
201
- /**
202
- * Cron 解析 & 生成引擎
203
- */
204
- function useCronParser() {
205
- /** 当前 Cron 对象 */
206
- const cronValue = ref(structuredClone(DEFAULT_CRON_VALUE));
207
- /** 将单个字段值转为 Cron 表达式片段 */
208
- function fieldToExpression(field) {
209
- switch (field.mode) {
210
- case "every": return "*";
211
- case "range": return `${field.rangeStart}-${field.rangeEnd}`;
212
- case "step": return `${field.stepStart}/${field.stepInterval}`;
213
- case "specific": return field.specificValues.length > 0 ? field.specificValues.sort((a, b) => a - b).join(",") : "*";
214
- case "none": return "?";
215
- default: return "*";
216
- }
217
- }
218
- /** 创建默认字段值 */
219
- function createFieldValue(meta, mode, overrides = {}) {
220
- return {
221
- mode,
222
- rangeStart: meta.min,
223
- rangeEnd: meta.max,
224
- stepStart: meta.min,
225
- stepInterval: 1,
226
- specificValues: [],
227
- ...overrides
228
- };
229
- }
230
- /** 解析步进表达式为字段值 */
231
- function parseStepExpr(expr, meta) {
232
- const [start, interval] = expr.split("/").map(Number);
233
- return createFieldValue(meta, "step", {
234
- stepStart: isNaN(start) ? meta.min : start,
235
- stepInterval: isNaN(interval) ? 1 : interval
236
- });
237
- }
238
- /** 解析范围表达式为字段值 */
239
- function parseRangeExpr(expr, meta) {
240
- const [start, end] = expr.split("-").map(Number);
241
- return createFieldValue(meta, "range", {
242
- rangeStart: isNaN(start) ? meta.min : start,
243
- rangeEnd: isNaN(end) ? meta.max : end
244
- });
245
- }
246
- /** 将 Cron 表达式片段解析为字段值对象 */
247
- function expressionToField(expr, type) {
248
- const meta = CRON_FIELD_META.find((m) => m.type === type);
249
- if (expr === "?") return createFieldValue(meta, "none");
250
- if (expr === "*") return createFieldValue(meta, "every");
251
- if (expr.includes("/")) return parseStepExpr(expr, meta);
252
- if (expr.includes("-") && !expr.includes(",")) return parseRangeExpr(expr, meta);
253
- const values = expr.split(",").map(Number).filter((n) => !isNaN(n));
254
- if (values.length > 0) return createFieldValue(meta, "specific", { specificValues: values });
255
- return createFieldValue(meta, "every");
256
- }
257
- /** 由 CronValue 生成完整 Cron 表达式 */
258
- function generate() {
259
- return FIELD_ORDER.map((type) => fieldToExpression(cronValue.value[type])).join(" ");
260
- }
261
- /** 解析 Cron 表达式字符串为 CronValue */
262
- function parse(expression) {
263
- const parts = expression.trim().split(/\s+/);
264
- if (parts.length < 6) return;
265
- FIELD_ORDER.forEach((type, index) => {
266
- cronValue.value[type] = expressionToField(parts[index], type);
267
- });
268
- }
269
- /** 日/周互斥:修改一方时另一方自动设为 ? */
270
- function handleDayWeekExclusion(changedField) {
271
- if (changedField === "day") {
272
- if (cronValue.value.day.mode !== "none") cronValue.value.week = {
273
- ...cronValue.value.week,
274
- mode: "none"
275
- };
276
- } else if (cronValue.value.week.mode !== "none") cronValue.value.day = {
277
- ...cronValue.value.day,
278
- mode: "none"
279
- };
280
- }
281
- /** 校验 Cron 表达式合法性 */
282
- function validate(expression) {
283
- const parts = (expression ?? generate()).trim().split(/\s+/);
284
- if (parts.length !== 6) return {
285
- valid: false,
286
- message: `表达式应包含 6 个字段,当前为 ${parts.length} 个`
287
- };
288
- const dayPart = parts[3];
289
- const weekPart = parts[5];
290
- if (dayPart !== "?" && weekPart !== "?") return {
291
- valid: false,
292
- message: "日和周不能同时指定,其中一个必须为 ?",
293
- field: "day"
294
- };
295
- if (dayPart === "?" && weekPart === "?") return {
296
- valid: false,
297
- message: "日和周不能同时为 ?,至少指定一个",
298
- field: "day"
299
- };
300
- for (let i = 0; i < FIELD_ORDER.length; i++) {
301
- const type = FIELD_ORDER[i];
302
- const part = parts[i];
303
- const result = validateField(part, CRON_FIELD_META.find((m) => m.type === type));
304
- if (!result.valid) return {
305
- ...result,
306
- field: type
307
- };
308
- }
309
- return {
310
- valid: true,
311
- message: "表达式合法"
312
- };
313
- }
314
- /** 校验步进表达式 */
315
- function validateStep(part, meta) {
316
- const [s, i] = part.split("/");
317
- const start = s === "*" ? meta.min : Number(s);
318
- const interval = Number(i);
319
- if (isNaN(start) || isNaN(interval)) return {
320
- valid: false,
321
- message: `${meta.label}字段步进格式错误`
322
- };
323
- if (start < meta.min || start > meta.max) return {
324
- valid: false,
325
- message: `${meta.label}字段步进起始值超出范围 (${meta.min}-${meta.max})`
326
- };
327
- if (interval < 1) return {
328
- valid: false,
329
- message: `${meta.label}字段步进间隔必须大于 0`
330
- };
331
- return {
332
- valid: true,
333
- message: ""
334
- };
335
- }
336
- /** 校验范围表达式 */
337
- function validateRange(part, meta) {
338
- const [s, e] = part.split("-").map(Number);
339
- if (isNaN(s) || isNaN(e)) return {
340
- valid: false,
341
- message: `${meta.label}字段范围格式错误`
342
- };
343
- if (s < meta.min || e > meta.max) return {
344
- valid: false,
345
- message: `${meta.label}字段范围超出 (${meta.min}-${meta.max})`
346
- };
347
- if (s > e) return {
348
- valid: false,
349
- message: `${meta.label}字段范围起始不能大于结束`
350
- };
351
- return {
352
- valid: true,
353
- message: ""
354
- };
355
- }
356
- /** 校验指定值表达式 */
357
- function validateSpecific(part, meta) {
358
- const values = part.split(",").map(Number);
359
- if (values.some(isNaN)) return {
360
- valid: false,
361
- message: `${meta.label}字段包含非数字字符`
362
- };
363
- if (values.some((v) => v < meta.min || v > meta.max)) return {
364
- valid: false,
365
- message: `${meta.label}字段值超出范围 (${meta.min}-${meta.max})`
366
- };
367
- return {
368
- valid: true,
369
- message: ""
370
- };
371
- }
372
- /** 校验单个字段表达式 */
373
- function validateField(part, meta) {
374
- if (part === "*" || part === "?") return {
375
- valid: true,
376
- message: ""
377
- };
378
- if (part.includes("/")) return validateStep(part, meta);
379
- if (part.includes("-") && !part.includes(",")) return validateRange(part, meta);
380
- return validateSpecific(part, meta);
381
- }
382
- return {
383
- cronValue,
384
- expression: computed(() => generate()),
385
- validation: computed(() => validate()),
386
- parse,
387
- generate,
388
- validate,
389
- handleDayWeekExclusion
390
- };
391
- }
392
-
393
- //#endregion
394
- //#region src/components/C_Cron/composables/useCronPreview.ts
395
- /**
396
- * 解析 Cron 表达式,预测未来 N 次执行时间
397
- * 纯逻辑实现,不依赖外部库
398
- */
399
- function useCronPreview(expression, validation, count) {
400
- /** 预测的执行时间列表 */
401
- const nextExecutions = ref([]);
402
- /** 是否正在计算 */
403
- const computing = ref(false);
404
- /** 检查单个值是否匹配 Cron 字段片段 */
405
- function matchesPart(value, part) {
406
- if (part === "*" || part === "?") return true;
407
- if (part.includes("/")) {
408
- const [s, i] = part.split("/");
409
- const start = s === "*" ? 0 : Number(s);
410
- const interval = Number(i);
411
- return value - start >= 0 && (value - start) % interval === 0;
412
- }
413
- if (part.includes("-") && !part.includes(",")) {
414
- const [start, end] = part.split("-").map(Number);
415
- return value >= start && value <= end;
416
- }
417
- return part.split(",").map(Number).includes(value);
418
- }
419
- /** 检查日期是否匹配 Cron 表达式 */
420
- function matchesCron(date, parts) {
421
- if (parts.length !== 6) return false;
422
- const [secPart, minPart, hourPart, dayPart, monthPart, weekPart] = parts;
423
- if (!matchesPart(date.getMonth() + 1, monthPart)) return false;
424
- if (dayPart !== "?") {
425
- if (!matchesPart(date.getDate(), dayPart)) return false;
426
- }
427
- if (weekPart !== "?") {
428
- if (!matchesPart(date.getDay() + 1, weekPart)) return false;
429
- }
430
- if (!matchesPart(date.getHours(), hourPart)) return false;
431
- if (!matchesPart(date.getMinutes(), minPart)) return false;
432
- if (!matchesPart(date.getSeconds(), secPart)) return false;
433
- return true;
434
- }
435
- /** 计算未来 N 次执行时间 */
436
- function computeNextExecutions() {
437
- const expr = expression.value;
438
- if (!expr || !validation.value.valid) return [];
439
- const parts = expr.trim().split(/\s+/);
440
- if (parts.length !== 6) return [];
441
- const results = [];
442
- const now = /* @__PURE__ */ new Date();
443
- const cursor = new Date(now.getTime() + 1e3);
444
- cursor.setMilliseconds(0);
445
- const hasSecond = parts[0] !== "0";
446
- const stepMs = hasSecond ? 1e3 : 6e4;
447
- if (!hasSecond) {
448
- cursor.setSeconds(0);
449
- if (cursor.getTime() <= now.getTime()) cursor.setTime(cursor.getTime() + 6e4);
450
- }
451
- const maxIterations = 525600;
452
- const target = count.value;
453
- for (let i = 0; i < maxIterations && results.length < target; i++) {
454
- if (matchesCron(cursor, parts)) results.push(new Date(cursor));
455
- cursor.setTime(cursor.getTime() + stepMs);
456
- }
457
- return results;
458
- }
459
- watch([expression, count], () => {
460
- if (!validation.value.valid) {
461
- nextExecutions.value = [];
462
- return;
463
- }
464
- computing.value = true;
465
- setTimeout(() => {
466
- nextExecutions.value = computeNextExecutions();
467
- computing.value = false;
468
- }, 0);
469
- }, { immediate: true });
470
- /** 格式化日期为字符串 */
471
- function formatDate(date) {
472
- const pad = (n) => String(n).padStart(2, "0");
473
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
474
- }
475
- /** 获取日期的中文星期名称 */
476
- function formatWeekDay(date) {
477
- return [
478
- "周日",
479
- "周一",
480
- "周二",
481
- "周三",
482
- "周四",
483
- "周五",
484
- "周六"
485
- ][date.getDay()];
486
- }
487
- return {
488
- nextExecutions,
489
- computing,
490
- formatDate,
491
- formatWeekDay
492
- };
493
- }
494
-
495
- //#endregion
496
- //#region src/components/C_Cron/composables/useCronDescription.ts
497
- /** 获取周名称 */
498
- function weekLabel(n) {
499
- return WEEK_LABELS[Number(n)] || `周${n}`;
500
- }
501
- /**
502
- * 将 Cron 表达式自动转换为中文可读描述
503
- */
504
- function useCronDescription(expression, validation) {
505
- /** 中文描述 */
506
- const description = computed(() => {
507
- if (!validation.value.valid) return "表达式不合法";
508
- return generateDescription(expression.value);
509
- });
510
- /** 将完整 Cron 表达式转为中文描述 */
511
- function generateDescription(expr) {
512
- const parts = expr.trim().split(/\s+/);
513
- if (parts.length !== 6) return "表达式格式错误";
514
- const [sec, min, hour, day, month, week] = parts;
515
- const fragments = [];
516
- fragments.push(describeMonth(month));
517
- if (week !== "?") fragments.push(describeWeek(week));
518
- else fragments.push(describeDay(day));
519
- fragments.push(describeHour(hour));
520
- fragments.push(describeMinute(min));
521
- fragments.push(describeSecond(sec));
522
- return fragments.filter(Boolean).join(" ") + " 执行";
523
- }
524
- /** 描述秒字段 */
525
- function describeSecond(part) {
526
- if (part === "0") return "";
527
- if (part === "*") return "每秒";
528
- return describeFieldGeneric(part, "秒");
529
- }
530
- /** 描述分字段 */
531
- function describeMinute(part) {
532
- if (part === "*") return "每分钟";
533
- if (part === "0") return "";
534
- return describeFieldGeneric(part, "分");
535
- }
536
- /** 描述时字段 */
537
- function describeHour(part) {
538
- if (part === "*") return "每小时";
539
- if (/^\d+$/.test(part)) return `${part.padStart(2, "0")}:`;
540
- return describeFieldGeneric(part, "时");
541
- }
542
- /** 描述日字段 */
543
- function describeDay(part) {
544
- if (part === "*" || part === "?") return "每天";
545
- if (/^\d+$/.test(part)) return `每月 ${part} 号`;
546
- if (part.includes("/")) {
547
- const [s, i] = part.split("/");
548
- return `从 ${s} 号开始每 ${i} 天`;
549
- }
550
- if (part.includes("-")) {
551
- const [s, e] = part.split("-");
552
- return `${s} 号到 ${e} 号`;
553
- }
554
- if (part.includes(",")) return `每月 ${part} 号`;
555
- return "";
556
- }
557
- /** 描述月字段 */
558
- function describeMonth(part) {
559
- if (part === "*") return "";
560
- if (/^\d+$/.test(part)) {
561
- const n = Number(part);
562
- return MONTH_LABELS[n] ? `${MONTH_LABELS[n]}` : `${n} 月`;
563
- }
564
- if (part.includes("/")) {
565
- const [s, i] = part.split("/");
566
- return `从 ${s} 月开始每 ${i} 个月`;
567
- }
568
- if (part.includes("-")) {
569
- const [s, e] = part.split("-");
570
- return `${s} 月到 ${e} 月`;
571
- }
572
- if (part.includes(",")) return part.split(",").map((n) => MONTH_LABELS[Number(n)] || `${n}月`).join("、");
573
- return "";
574
- }
575
- /** 描述周字段 */
576
- function describeWeek(part) {
577
- if (part === "*" || part === "?") return "";
578
- if (/^\d+$/.test(part)) return `每${weekLabel(part)}`;
579
- if (part.includes("/")) return `从${weekLabel(part.split("/")[0])}开始每 ${part.split("/")[1]} 天`;
580
- if (part.includes("-")) return `${weekLabel(part.split("-")[0])}到${weekLabel(part.split("-")[1])}`;
581
- if (part.includes(",")) return `每${part.split(",").map(weekLabel).join("、")}`;
582
- return "";
583
- }
584
- /** 通用字段描述 */
585
- function describeFieldGeneric(part, unit) {
586
- if (part.includes("/")) {
587
- const [s, i] = part.split("/");
588
- return `${s === "*" || s === "0" ? "" : `从第 ${s} ${unit}开始`}每 ${i} ${unit}`;
589
- }
590
- if (part.includes("-")) {
591
- const [s, e] = part.split("-");
592
- return `${s} ${unit}到 ${e} ${unit}`;
593
- }
594
- if (part.includes(",")) return `第 ${part} ${unit}`;
595
- if (/^\d+$/.test(part)) return `${part.padStart(2, "0")}`;
596
- return "";
597
- }
598
- return { description };
599
- }
600
-
601
- //#endregion
602
- //#region src/components/C_Cron/components/CronFieldEditor.vue?vue&type=script&setup=true&lang.ts
603
- const _hoisted_1$3 = { class: "cron-field-editor" };
604
- const _hoisted_2$3 = ["onClick"];
605
- var CronFieldEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
606
- __name: "CronFieldEditor",
607
- props: {
608
- modelValue: {},
609
- meta: {}
610
- },
611
- emits: ["update:modelValue"],
612
- setup(__props, { emit: __emit }) {
613
- const props = __props;
614
- const emit = __emit;
615
- /** 网格列数 */
616
- const gridColumns = computed(() => {
617
- switch (props.meta.type) {
618
- case "second":
619
- case "minute": return 10;
620
- case "hour": return 12;
621
- case "day": return 7;
622
- case "month": return 6;
623
- case "week": return 7;
624
- default: return 10;
625
- }
626
- });
627
- /** 可选值列表 */
628
- const valueOptions = computed(() => {
629
- const items = [];
630
- for (let i = props.meta.min; i <= props.meta.max; i++) items.push({
631
- value: i,
632
- label: props.meta.valueLabels?.[i] ?? String(i)
633
- });
634
- return items;
635
- });
636
- /** 根据当前模式计算高亮值集合 */
637
- const highlightedValues = computed(() => {
638
- const { modelValue: f, meta } = props;
639
- const set = /* @__PURE__ */ new Set();
640
- switch (f.mode) {
641
- case "every":
642
- for (let i = meta.min; i <= meta.max; i++) set.add(i);
643
- break;
644
- case "none": break;
645
- case "range":
646
- for (let i = f.rangeStart; i <= f.rangeEnd; i++) set.add(i);
647
- break;
648
- case "step":
649
- for (let i = f.stepStart; i <= meta.max; i += f.stepInterval) set.add(i);
650
- break;
651
- case "specific":
652
- f.specificValues.forEach((v) => set.add(v));
653
- break;
654
- }
655
- return set;
656
- });
657
- /** 点击单元格(仅 specific 模式生效) */
658
- function handleCellClick(value) {
659
- if (props.modelValue.mode !== "specific") return;
660
- const current = [...props.modelValue.specificValues];
661
- const idx = current.indexOf(value);
662
- if (idx >= 0) current.splice(idx, 1);
663
- else current.push(value);
664
- emit("update:modelValue", {
665
- ...props.modelValue,
666
- specificValues: current
667
- });
668
- }
669
- return (_ctx, _cache) => {
670
- return openBlock(), createElementBlock("div", _hoisted_1$3, [createElementVNode("div", {
671
- class: "cron-field-editor__grid",
672
- style: normalizeStyle({ "--cols": gridColumns.value })
673
- }, [(openBlock(true), createElementBlock(Fragment, null, renderList(valueOptions.value, (item) => {
674
- return openBlock(), createElementBlock("div", {
675
- key: item.value,
676
- class: normalizeClass(["cron-field-editor__cell", {
677
- "cron-field-editor__cell--on": highlightedValues.value.has(item.value),
678
- "cron-field-editor__cell--pick": _ctx.modelValue.mode === "specific"
679
- }]),
680
- onClick: ($event) => handleCellClick(item.value)
681
- }, toDisplayString(item.label), 11, _hoisted_2$3);
682
- }), 128))], 4)]);
683
- };
684
- }
685
- });
686
-
687
- //#endregion
688
- //#region src/components/C_Cron/components/CronFieldEditor.vue
689
- var CronFieldEditor_default = /* @__PURE__ */ export_helper_default(CronFieldEditor_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-769c51fe"]]);
690
-
691
- //#endregion
692
- //#region src/components/C_Cron/components/CronPreview.vue?vue&type=script&setup=true&lang.ts
693
- const _hoisted_1$2 = { class: "cron-preview" };
694
- const _hoisted_2$2 = { class: "cron-preview__header" };
695
- const _hoisted_3$2 = {
696
- key: 0,
697
- class: "cron-preview__list"
698
- };
699
- const _hoisted_4$2 = { class: "cron-preview__idx" };
700
- const _hoisted_5$2 = { class: "cron-preview__date" };
701
- const _hoisted_6$2 = { class: "cron-preview__week" };
702
- var CronPreview_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
703
- __name: "CronPreview",
704
- props: {
705
- nextExecutions: {},
706
- computing: { type: Boolean },
707
- count: {},
708
- formatDate: { type: Function },
709
- formatWeekDay: { type: Function }
710
- },
711
- setup(__props) {
712
- return (_ctx, _cache) => {
713
- const _component_NSpin = NSpin;
714
- const _component_NEmpty = NEmpty;
715
- const _component_NScrollbar = NScrollbar;
716
- return openBlock(), createElementBlock("div", _hoisted_1$2, [createElementVNode("div", _hoisted_2$2, [
717
- createVNode(C_Icon_default, {
718
- name: "mdi:calendar-clock",
719
- size: 15
720
- }),
721
- _cache[0] || (_cache[0] = createElementVNode("span", null, "未来执行", -1)),
722
- _ctx.computing ? (openBlock(), createBlock(_component_NSpin, {
723
- key: 0,
724
- size: 14
725
- })) : createCommentVNode("v-if", true)
726
- ]), createVNode(_component_NScrollbar, { style: { "max-height": "220px" } }, {
727
- default: withCtx(() => [_ctx.nextExecutions.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_3$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.nextExecutions, (date, index) => {
728
- return openBlock(), createElementBlock("div", {
729
- key: index,
730
- class: "cron-preview__item"
731
- }, [
732
- createElementVNode("span", _hoisted_4$2, toDisplayString(index + 1), 1),
733
- createElementVNode("span", _hoisted_5$2, toDisplayString(_ctx.formatDate(date)), 1),
734
- createElementVNode("span", _hoisted_6$2, toDisplayString(_ctx.formatWeekDay(date)), 1)
735
- ]);
736
- }), 128))])) : (openBlock(), createBlock(_component_NEmpty, {
737
- key: 1,
738
- size: "small",
739
- description: "暂无匹配"
740
- }))]),
741
- _: 1
742
- })]);
743
- };
744
- }
745
- });
746
-
747
- //#endregion
748
- //#region src/components/C_Cron/components/CronPreview.vue
749
- var CronPreview_default = /* @__PURE__ */ export_helper_default(CronPreview_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-570ad3fb"]]);
750
-
751
- //#endregion
752
- //#region src/components/C_Cron/components/CronTemplates.vue?vue&type=script&setup=true&lang.ts
753
- const _hoisted_1$1 = { class: "cron-templates" };
754
- const _hoisted_2$1 = { class: "cron-templates__header" };
755
- const _hoisted_3$1 = { class: "cron-templates__cards" };
756
- const _hoisted_4$1 = ["onClick"];
757
- const _hoisted_5$1 = { class: "cron-templates__card-name" };
758
- const _hoisted_6$1 = { class: "cron-templates__card-expr" };
759
- var CronTemplates_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
760
- __name: "CronTemplates",
761
- props: {
762
- templates: {},
763
- currentValue: {}
764
- },
765
- emits: ["select"],
766
- setup(__props) {
767
- return (_ctx, _cache) => {
768
- return openBlock(), createElementBlock("div", _hoisted_1$1, [createElementVNode("div", _hoisted_2$1, [createVNode(C_Icon_default, {
769
- name: "mdi:lightning-bolt",
770
- size: 15
771
- }), _cache[0] || (_cache[0] = createElementVNode("span", null, "常用模板", -1))]), createElementVNode("div", _hoisted_3$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.templates, (template) => {
772
- return openBlock(), createElementBlock("div", {
773
- key: template.value,
774
- class: normalizeClass(["cron-templates__card", { "cron-templates__card--active": template.value === _ctx.currentValue }]),
775
- onClick: ($event) => _ctx.$emit("select", template.value)
776
- }, [createElementVNode("div", _hoisted_5$1, toDisplayString(template.label), 1), createElementVNode("div", _hoisted_6$1, toDisplayString(template.value), 1)], 10, _hoisted_4$1);
777
- }), 128))])]);
778
- };
779
- }
780
- });
781
-
782
- //#endregion
783
- //#region src/components/C_Cron/components/CronTemplates.vue
784
- var CronTemplates_default = /* @__PURE__ */ export_helper_default(CronTemplates_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-5190cefc"]]);
785
-
786
- //#endregion
787
- //#region src/components/C_Cron/index.vue?vue&type=script&setup=true&lang.ts
788
- const _hoisted_1 = { class: "c-cron__header" };
789
- const _hoisted_2 = { class: "c-cron__title-row" };
790
- const _hoisted_3 = { class: "c-cron__title" };
791
- const _hoisted_4 = { class: "c-cron__segments" };
792
- const _hoisted_5 = ["onClick"];
793
- const _hoisted_6 = { class: "c-cron__segment-value" };
794
- const _hoisted_7 = { class: "c-cron__segment-label" };
795
- const _hoisted_8 = { class: "c-cron__expr-row" };
796
- const _hoisted_9 = { class: "c-cron__expr-desc" };
797
- const _hoisted_10 = {
798
- key: 0,
799
- class: "c-cron__description"
800
- };
801
- const _hoisted_11 = {
802
- key: 1,
803
- class: "c-cron__error"
804
- };
805
- const _hoisted_12 = { class: "c-cron__body" };
806
- const _hoisted_13 = { class: "c-cron__main" };
807
- const _hoisted_14 = { class: "c-cron__panel" };
808
- const _hoisted_15 = {
809
- key: 0,
810
- class: "c-cron__config"
811
- };
812
- const _hoisted_16 = { class: "c-cron__config-row" };
813
- const _hoisted_17 = {
814
- key: 1,
815
- class: "c-cron__config"
816
- };
817
- const _hoisted_18 = { class: "c-cron__config-row" };
818
- const _hoisted_19 = {
819
- key: 2,
820
- class: "c-cron__quick"
821
- };
822
- const _hoisted_20 = {
823
- key: 0,
824
- class: "c-cron__quick-count"
825
- };
826
- const _hoisted_21 = {
827
- key: 0,
828
- class: "c-cron__footer"
829
- };
830
- var index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
831
- name: "C_Cron",
832
- __name: "index",
833
- props: {
834
- modelValue: { default: DEFAULT_CRON_EXPRESSION },
835
- disabled: {
836
- type: Boolean,
837
- default: false
838
- },
839
- previewCount: { default: 10 },
840
- showTemplates: {
841
- type: Boolean,
842
- default: true
843
- },
844
- showPreview: {
845
- type: Boolean,
846
- default: true
847
- },
848
- showSecond: {
849
- type: Boolean,
850
- default: true
851
- },
852
- height: { default: "auto" }
853
- },
854
- emits: [
855
- "update:modelValue",
856
- "change",
857
- "validation-change"
858
- ],
859
- setup(__props, { expose: __expose, emit: __emit }) {
860
- const props = __props;
861
- const emit = __emit;
862
- const { cronValue, expression, validation, parse, validate, handleDayWeekExclusion } = useCronParser();
863
- const { nextExecutions, computing, formatDate, formatWeekDay } = useCronPreview(expression, validation, computed(() => props.previewCount ?? 10));
864
- const { description } = useCronDescription(expression, validation);
865
- /** 手动输入框值(与 expression 解耦,输入完成后同步) */
866
- const manualInput = ref(props.modelValue || DEFAULT_CRON_EXPRESSION);
867
- /** 当前激活的字段 Tab */
868
- const activeField = ref(props.showSecond ? "second" : "minute");
869
- const containerHeight = computed(() => {
870
- if (typeof props.height === "number") return `${props.height}px`;
871
- return props.height;
872
- });
873
- const visibleFields = computed(() => {
874
- return props.showSecond ? CRON_FIELD_META : CRON_FIELD_META.filter((m) => m.type !== "second");
875
- });
876
- /** 当前激活字段元数据 */
877
- const activeFieldMeta = computed(() => CRON_FIELD_META.find((m) => m.type === activeField.value));
878
- /** 当前激活字段值 */
879
- const activeFieldValue = computed(() => cronValue.value[activeField.value]);
880
- /** 计算单字段表达式文本 */
881
- function computeFieldExpr(f) {
882
- switch (f.mode) {
883
- case "every": return "*";
884
- case "none": return "?";
885
- case "range": return `${f.rangeStart}-${f.rangeEnd}`;
886
- case "step": return `${f.stepStart}/${f.stepInterval}`;
887
- case "specific": return f.specificValues.length > 0 ? [...f.specificValues].sort((a, b) => a - b).join(",") : "*";
888
- default: return "*";
889
- }
890
- }
891
- /** 各字段表达式映射 */
892
- const fieldExpressions = computed(() => {
893
- const map = {};
894
- for (const meta of CRON_FIELD_META) map[meta.type] = computeFieldExpr(cronValue.value[meta.type]);
895
- return map;
896
- });
897
- onMounted(() => {
898
- const initial = props.modelValue || DEFAULT_CRON_EXPRESSION;
899
- parse(initial);
900
- manualInput.value = initial;
901
- });
902
- watch(() => props.modelValue, (newVal) => {
903
- if (newVal && newVal !== expression.value) {
904
- parse(newVal);
905
- manualInput.value = newVal;
906
- }
907
- });
908
- watch(() => props.showSecond, (show) => {
909
- if (!show && activeField.value === "second") activeField.value = "minute";
910
- });
911
- watch(expression, (newExpr) => {
912
- manualInput.value = newExpr;
913
- emit("update:modelValue", newExpr);
914
- emit("change", newExpr);
915
- });
916
- watch(validation, (v) => {
917
- emit("validation-change", v);
918
- });
919
- /** 字段编辑变更处理 */
920
- function handleFieldChange(type, value) {
921
- cronValue.value[type] = value;
922
- if (type === "day" || type === "week") handleDayWeekExclusion(type);
923
- }
924
- /** 切换当前字段模式 */
925
- function handleActiveFieldModeChange(mode) {
926
- handleFieldChange(activeField.value, {
927
- ...activeFieldValue.value,
928
- mode
929
- });
930
- }
931
- /** 更新当前字段属性 */
932
- function handleActiveFieldUpdate(partial) {
933
- handleFieldChange(activeField.value, {
934
- ...activeFieldValue.value,
935
- ...partial
936
- });
937
- }
938
- /** 全选当前字段所有值 */
939
- function handleSelectAll() {
940
- const { min, max } = activeFieldMeta.value;
941
- const allValues = Array.from({ length: max - min + 1 }, (_, i) => min + i);
942
- handleFieldChange(activeField.value, {
943
- ...activeFieldValue.value,
944
- specificValues: allValues
945
- });
946
- }
947
- /** 清空当前字段所有选中值 */
948
- function handleClearAll() {
949
- handleFieldChange(activeField.value, {
950
- ...activeFieldValue.value,
951
- specificValues: []
952
- });
953
- }
954
- /** 手动输入更新 */
955
- function handleManualInput(value) {
956
- manualInput.value = value;
957
- }
958
- /** 输入框失焦时同步 */
959
- function handleManualBlur() {
960
- const trimmed = manualInput.value.trim();
961
- if (trimmed && trimmed !== expression.value) parse(trimmed);
962
- }
963
- /** 选择常用模板 */
964
- function handleTemplateSelect(expr) {
965
- parse(expr);
966
- manualInput.value = expr;
967
- }
968
- /** 重置为初始值 */
969
- function handleReset() {
970
- const initial = props.modelValue || DEFAULT_CRON_EXPRESSION;
971
- parse(initial);
972
- manualInput.value = initial;
973
- }
974
- __expose({
975
- getValue: () => expression.value,
976
- setValue: (expr) => {
977
- parse(expr);
978
- manualInput.value = expr;
979
- },
980
- reset: handleReset,
981
- validate: () => validate()
982
- });
983
- return (_ctx, _cache) => {
984
- const _component_NTag = NTag;
985
- const _component_NInput = NInput;
986
- const _component_NButton = NButton;
987
- const _component_NRadioButton = NRadioButton;
988
- const _component_NRadioGroup = NRadioGroup;
989
- const _component_NInputNumber = NInputNumber;
990
- return openBlock(), createElementBlock("div", {
991
- class: "c-cron",
992
- style: normalizeStyle({ height: containerHeight.value })
993
- }, [
994
- createCommentVNode(" ═══════ 顶部 ═══════ "),
995
- createElementVNode("div", _hoisted_1, [
996
- createCommentVNode(" 标题行 "),
997
- createElementVNode("div", _hoisted_2, [createElementVNode("div", _hoisted_3, [createVNode(C_Icon_default, {
998
- name: "mdi:clock-edit-outline",
999
- size: 18
1000
- }), _cache[4] || (_cache[4] = createElementVNode("span", null, "Cron 表达式", -1))]), createVNode(_component_NTag, {
1001
- type: unref(validation).valid ? "success" : "error",
1002
- size: "small",
1003
- round: ""
1004
- }, {
1005
- icon: withCtx(() => [createVNode(C_Icon_default, { name: unref(validation).valid ? "mdi:check-circle" : "mdi:alert-circle" }, null, 8, ["name"])]),
1006
- default: withCtx(() => [createTextVNode(" " + toDisplayString(unref(validation).valid ? "合法" : "错误"), 1)]),
1007
- _: 1
1008
- }, 8, ["type"])]),
1009
- createCommentVNode(" 分段式字段选择器 "),
1010
- createElementVNode("div", _hoisted_4, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (meta) => {
1011
- return openBlock(), createElementBlock("div", {
1012
- key: meta.type,
1013
- class: normalizeClass(["c-cron__segment", {
1014
- "c-cron__segment--active": activeField.value === meta.type,
1015
- "c-cron__segment--wildcard": fieldExpressions.value[meta.type] === "*" || fieldExpressions.value[meta.type] === "?"
1016
- }]),
1017
- onClick: ($event) => activeField.value = meta.type
1018
- }, [createElementVNode("div", _hoisted_6, toDisplayString(fieldExpressions.value[meta.type]), 1), createElementVNode("div", _hoisted_7, toDisplayString(meta.label), 1)], 10, _hoisted_5);
1019
- }), 128))]),
1020
- createCommentVNode(" 表达式行:输入 + 重置 + 描述 "),
1021
- createElementVNode("div", _hoisted_8, [
1022
- createVNode(_component_NInput, {
1023
- value: manualInput.value,
1024
- status: unref(validation).valid ? void 0 : "error",
1025
- placeholder: "秒 分 时 日 月 周",
1026
- disabled: props.disabled,
1027
- font: "mono",
1028
- size: "small",
1029
- clearable: "",
1030
- class: "c-cron__expr-input",
1031
- "onUpdate:value": handleManualInput,
1032
- onBlur: handleManualBlur,
1033
- onKeydown: withKeys(handleManualBlur, ["enter"])
1034
- }, {
1035
- prefix: withCtx(() => [createVNode(C_Icon_default, {
1036
- name: "mdi:console",
1037
- size: 14,
1038
- style: { "opacity": "0.4" }
1039
- })]),
1040
- _: 1
1041
- }, 8, [
1042
- "value",
1043
- "status",
1044
- "disabled"
1045
- ]),
1046
- createVNode(_component_NButton, {
1047
- size: "small",
1048
- quaternary: "",
1049
- disabled: props.disabled,
1050
- onClick: handleReset
1051
- }, {
1052
- icon: withCtx(() => [createVNode(C_Icon_default, { name: "mdi:refresh" })]),
1053
- _: 1
1054
- }, 8, ["disabled"]),
1055
- createElementVNode("div", _hoisted_9, [unref(validation).valid ? (openBlock(), createElementBlock("span", _hoisted_10, toDisplayString(unref(description)), 1)) : (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(unref(validation).message), 1))])
1056
- ])
1057
- ]),
1058
- createCommentVNode(" ═══════ 主内容 ═══════ "),
1059
- createElementVNode("div", _hoisted_12, [
1060
- createCommentVNode(" 左侧:值网格 "),
1061
- createElementVNode("div", _hoisted_13, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (meta) => {
1062
- return withDirectives((openBlock(), createBlock(CronFieldEditor_default, {
1063
- key: meta.type,
1064
- "model-value": unref(cronValue)[meta.type],
1065
- meta,
1066
- "onUpdate:modelValue": (v) => handleFieldChange(meta.type, v)
1067
- }, null, 8, [
1068
- "model-value",
1069
- "meta",
1070
- "onUpdate:modelValue"
1071
- ])), [[vShow, activeField.value === meta.type]]);
1072
- }), 128))]),
1073
- createCommentVNode(" 右侧:控制面板 "),
1074
- createElementVNode("div", _hoisted_14, [
1075
- createVNode(_component_NRadioGroup, {
1076
- value: activeFieldValue.value.mode,
1077
- size: "small",
1078
- "onUpdate:value": handleActiveFieldModeChange
1079
- }, {
1080
- default: withCtx(() => [
1081
- createVNode(_component_NRadioButton, { value: "every" }, {
1082
- default: withCtx(() => [createTextVNode(" 每" + toDisplayString(activeFieldMeta.value.label), 1)]),
1083
- _: 1
1084
- }),
1085
- activeField.value === "day" || activeField.value === "week" ? (openBlock(), createBlock(_component_NRadioButton, {
1086
- key: 0,
1087
- value: "none"
1088
- }, {
1089
- default: withCtx(() => _cache[5] || (_cache[5] = [createTextVNode(" 不指定 ", -1)])),
1090
- _: 1,
1091
- __: [5]
1092
- })) : createCommentVNode("v-if", true),
1093
- createVNode(_component_NRadioButton, { value: "range" }, {
1094
- default: withCtx(() => _cache[6] || (_cache[6] = [createTextVNode("范围", -1)])),
1095
- _: 1,
1096
- __: [6]
1097
- }),
1098
- createVNode(_component_NRadioButton, { value: "step" }, {
1099
- default: withCtx(() => _cache[7] || (_cache[7] = [createTextVNode("步进", -1)])),
1100
- _: 1,
1101
- __: [7]
1102
- }),
1103
- createVNode(_component_NRadioButton, { value: "specific" }, {
1104
- default: withCtx(() => _cache[8] || (_cache[8] = [createTextVNode("指定", -1)])),
1105
- _: 1,
1106
- __: [8]
1107
- })
1108
- ]),
1109
- _: 1
1110
- }, 8, ["value"]),
1111
- createCommentVNode(" 范围配置 "),
1112
- activeFieldValue.value.mode === "range" ? (openBlock(), createElementBlock("div", _hoisted_15, [createElementVNode("div", _hoisted_16, [
1113
- _cache[9] || (_cache[9] = createElementVNode("span", null, "从", -1)),
1114
- createVNode(_component_NInputNumber, {
1115
- value: activeFieldValue.value.rangeStart,
1116
- min: activeFieldMeta.value.min,
1117
- max: activeFieldMeta.value.max,
1118
- size: "small",
1119
- "show-button": false,
1120
- class: "c-cron__config-num",
1121
- "onUpdate:value": _cache[0] || (_cache[0] = (v) => handleActiveFieldUpdate({ rangeStart: v ?? activeFieldMeta.value.min }))
1122
- }, null, 8, [
1123
- "value",
1124
- "min",
1125
- "max"
1126
- ]),
1127
- _cache[10] || (_cache[10] = createElementVNode("span", null, "到", -1)),
1128
- createVNode(_component_NInputNumber, {
1129
- value: activeFieldValue.value.rangeEnd,
1130
- min: activeFieldMeta.value.min,
1131
- max: activeFieldMeta.value.max,
1132
- size: "small",
1133
- "show-button": false,
1134
- class: "c-cron__config-num",
1135
- "onUpdate:value": _cache[1] || (_cache[1] = (v) => handleActiveFieldUpdate({ rangeEnd: v ?? activeFieldMeta.value.max }))
1136
- }, null, 8, [
1137
- "value",
1138
- "min",
1139
- "max"
1140
- ])
1141
- ])])) : createCommentVNode("v-if", true),
1142
- createCommentVNode(" 步进配置 "),
1143
- activeFieldValue.value.mode === "step" ? (openBlock(), createElementBlock("div", _hoisted_17, [createElementVNode("div", _hoisted_18, [
1144
- _cache[11] || (_cache[11] = createElementVNode("span", null, "从第", -1)),
1145
- createVNode(_component_NInputNumber, {
1146
- value: activeFieldValue.value.stepStart,
1147
- min: activeFieldMeta.value.min,
1148
- max: activeFieldMeta.value.max,
1149
- size: "small",
1150
- "show-button": false,
1151
- class: "c-cron__config-num",
1152
- "onUpdate:value": _cache[2] || (_cache[2] = (v) => handleActiveFieldUpdate({ stepStart: v ?? activeFieldMeta.value.min }))
1153
- }, null, 8, [
1154
- "value",
1155
- "min",
1156
- "max"
1157
- ]),
1158
- createElementVNode("span", null, toDisplayString(activeFieldMeta.value.label) + "起,每", 1),
1159
- createVNode(_component_NInputNumber, {
1160
- value: activeFieldValue.value.stepInterval,
1161
- min: 1,
1162
- max: activeFieldMeta.value.max - activeFieldMeta.value.min + 1,
1163
- size: "small",
1164
- "show-button": false,
1165
- class: "c-cron__config-num",
1166
- "onUpdate:value": _cache[3] || (_cache[3] = (v) => handleActiveFieldUpdate({ stepInterval: v ?? 1 }))
1167
- }, null, 8, ["value", "max"]),
1168
- createElementVNode("span", null, toDisplayString(activeFieldMeta.value.label) + "执行", 1)
1169
- ])])) : createCommentVNode("v-if", true),
1170
- createCommentVNode(" 指定快捷操作 "),
1171
- activeFieldValue.value.mode === "specific" ? (openBlock(), createElementBlock("div", _hoisted_19, [
1172
- createElementVNode("a", { onClick: handleSelectAll }, "全选"),
1173
- _cache[12] || (_cache[12] = createElementVNode("span", { class: "c-cron__quick-sep" }, "·", -1)),
1174
- createElementVNode("a", { onClick: handleClearAll }, "清空"),
1175
- activeFieldValue.value.specificValues.length > 0 ? (openBlock(), createElementBlock("span", _hoisted_20, " 已选 " + toDisplayString(activeFieldValue.value.specificValues.length), 1)) : createCommentVNode("v-if", true)
1176
- ])) : createCommentVNode("v-if", true),
1177
- createCommentVNode(" 执行预览 "),
1178
- props.showPreview ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [_cache[13] || (_cache[13] = createElementVNode("div", { class: "c-cron__panel-line" }, null, -1)), createVNode(CronPreview_default, {
1179
- "next-executions": unref(nextExecutions),
1180
- computing: unref(computing),
1181
- count: props.previewCount ?? 5,
1182
- "format-date": unref(formatDate),
1183
- "format-week-day": unref(formatWeekDay)
1184
- }, null, 8, [
1185
- "next-executions",
1186
- "computing",
1187
- "count",
1188
- "format-date",
1189
- "format-week-day"
1190
- ])], 64)) : createCommentVNode("v-if", true)
1191
- ])
1192
- ]),
1193
- createCommentVNode(" ═══════ 底部模板 ═══════ "),
1194
- props.showTemplates ? (openBlock(), createElementBlock("div", _hoisted_21, [createVNode(CronTemplates_default, {
1195
- templates: unref(CRON_TEMPLATES),
1196
- "current-value": unref(expression),
1197
- onSelect: handleTemplateSelect
1198
- }, null, 8, ["templates", "current-value"])])) : createCommentVNode("v-if", true)
1199
- ], 4);
1200
- };
1201
- }
1202
- });
1203
-
1204
- //#endregion
1205
- //#region src/components/C_Cron/index.vue
1206
- var C_Cron_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-b3efef0a"]]);
1207
-
1208
- //#endregion
1209
- export { CRON_FIELD_META as a, DEFAULT_CRON_VALUE as c, WEEK_LABELS as d, useCronParser as i, DEFAULT_FIELD_VALUE as l, useCronDescription as n, CRON_TEMPLATES as o, useCronPreview as r, DEFAULT_CRON_EXPRESSION as s, C_Cron_default as t, MONTH_LABELS as u };
1
+ import{t as e}from"./C_Icon2.js";import{t}from"./export-helper.js";import{NButton as n,NEmpty as r,NInput as i,NInputNumber as a,NRadioButton as o,NRadioGroup as s,NScrollbar as c,NSpin as l,NTag as u}from"naive-ui";import{Fragment as d,computed as f,createBlock as p,createCommentVNode as m,createElementBlock as h,createElementVNode as g,createTextVNode as _,createVNode as v,defineComponent as y,normalizeClass as b,normalizeStyle as x,onMounted as S,openBlock as C,ref as w,renderList as T,toDisplayString as E,unref as D,vShow as ee,watch as O,withCtx as k,withDirectives as te,withKeys as ne}from"vue";const A=[{type:`second`,label:`秒`,min:0,max:59},{type:`minute`,label:`分`,min:0,max:59},{type:`hour`,label:`时`,min:0,max:23},{type:`day`,label:`日`,min:1,max:31},{type:`month`,label:`月`,min:1,max:12},{type:`week`,label:`周`,min:1,max:7,valueLabels:{1:`周日`,2:`周一`,3:`周二`,4:`周三`,5:`周四`,6:`周五`,7:`周六`}}],j={mode:`every`,rangeStart:0,rangeEnd:0,stepStart:0,stepInterval:1,specificValues:[]},M={second:{...j,rangeEnd:59},minute:{...j,rangeEnd:59},hour:{...j,rangeEnd:23},day:{...j,rangeStart:1,rangeEnd:31},month:{...j,rangeStart:1,rangeEnd:12},week:{...j,mode:`none`,rangeStart:1,rangeEnd:7}},N=`0 0 0 * * ?`,P=[{label:`每秒执行`,value:`* * * * * ?`,description:`每秒执行一次`,icon:`mdi:timer-sand`},{label:`每分钟执行`,value:`0 * * * * ?`,description:`每分钟第 0 秒执行`,icon:`mdi:clock-outline`},{label:`每小时执行`,value:`0 0 * * * ?`,description:`每小时整点执行`,icon:`mdi:clock-time-twelve-outline`},{label:`每天 0 点`,value:`0 0 0 * * ?`,description:`每天凌晨 00:00 执行`,icon:`mdi:weather-night`},{label:`每天 8:30`,value:`0 30 8 * * ?`,description:`每天早上 08:30 执行`,icon:`mdi:weather-sunny`},{label:`每天 12:00`,value:`0 0 12 * * ?`,description:`每天中午 12:00 执行`,icon:`mdi:food`},{label:`工作日 9:00`,value:`0 0 9 ? * 2-6`,description:`周一至周五 09:00 执行`,icon:`mdi:briefcase-outline`},{label:`每周一 0 点`,value:`0 0 0 ? * 2`,description:`每周一凌晨 00:00 执行`,icon:`mdi:calendar-week`},{label:`每月 1 号 0 点`,value:`0 0 0 1 * ?`,description:`每月 1 号凌晨 00:00 执行`,icon:`mdi:calendar-month`},{label:`每 5 分钟`,value:`0 0/5 * * * ?`,description:`每隔 5 分钟执行一次`,icon:`mdi:timer-5`},{label:`每 30 分钟`,value:`0 0/30 * * * ?`,description:`每隔 30 分钟执行一次`,icon:`mdi:timer-30`},{label:`每 2 小时`,value:`0 0 0/2 * * ?`,description:`每隔 2 小时执行一次`,icon:`mdi:timer-2`}],F={1:`一月`,2:`二月`,3:`三月`,4:`四月`,5:`五月`,6:`六月`,7:`七月`,8:`八月`,9:`九月`,10:`十月`,11:`十一月`,12:`十二月`},I={1:`周日`,2:`周一`,3:`周二`,4:`周三`,5:`周四`,6:`周五`,7:`周六`},L=[`second`,`minute`,`hour`,`day`,`month`,`week`];function R(){let e=w(structuredClone(M));function t(e){switch(e.mode){case`every`:return`*`;case`range`:return`${e.rangeStart}-${e.rangeEnd}`;case`step`:return`${e.stepStart}/${e.stepInterval}`;case`specific`:return e.specificValues.length>0?e.specificValues.sort((e,t)=>e-t).join(`,`):`*`;case`none`:return`?`;default:return`*`}}function n(e,t,n={}){return{mode:t,rangeStart:e.min,rangeEnd:e.max,stepStart:e.min,stepInterval:1,specificValues:[],...n}}function r(e,t){let[r,i]=e.split(`/`).map(Number);return n(t,`step`,{stepStart:isNaN(r)?t.min:r,stepInterval:isNaN(i)?1:i})}function i(e,t){let[r,i]=e.split(`-`).map(Number);return n(t,`range`,{rangeStart:isNaN(r)?t.min:r,rangeEnd:isNaN(i)?t.max:i})}function a(e,t){let a=A.find(e=>e.type===t);if(e===`?`)return n(a,`none`);if(e===`*`)return n(a,`every`);if(e.includes(`/`))return r(e,a);if(e.includes(`-`)&&!e.includes(`,`))return i(e,a);let o=e.split(`,`).map(Number).filter(e=>!isNaN(e));return o.length>0?n(a,`specific`,{specificValues:o}):n(a,`every`)}function o(){return L.map(n=>t(e.value[n])).join(` `)}function s(t){let n=t.trim().split(/\s+/);n.length<6||L.forEach((t,r)=>{e.value[t]=a(n[r],t)})}function c(t){t===`day`?e.value.day.mode!==`none`&&(e.value.week={...e.value.week,mode:`none`}):e.value.week.mode!==`none`&&(e.value.day={...e.value.day,mode:`none`})}function l(e){let t=(e??o()).trim().split(/\s+/);if(t.length!==6)return{valid:!1,message:`表达式应包含 6 个字段,当前为 ${t.length} 个`};let n=t[3],r=t[5];if(n!==`?`&&r!==`?`)return{valid:!1,message:`日和周不能同时指定,其中一个必须为 ?`,field:`day`};if(n===`?`&&r===`?`)return{valid:!1,message:`日和周不能同时为 ?,至少指定一个`,field:`day`};for(let e=0;e<L.length;e++){let n=L[e],r=t[e],i=m(r,A.find(e=>e.type===n));if(!i.valid)return{...i,field:n}}return{valid:!0,message:`表达式合法`}}function u(e,t){let[n,r]=e.split(`/`),i=n===`*`?t.min:Number(n),a=Number(r);return isNaN(i)||isNaN(a)?{valid:!1,message:`${t.label}字段步进格式错误`}:i<t.min||i>t.max?{valid:!1,message:`${t.label}字段步进起始值超出范围 (${t.min}-${t.max})`}:a<1?{valid:!1,message:`${t.label}字段步进间隔必须大于 0`}:{valid:!0,message:``}}function d(e,t){let[n,r]=e.split(`-`).map(Number);return isNaN(n)||isNaN(r)?{valid:!1,message:`${t.label}字段范围格式错误`}:n<t.min||r>t.max?{valid:!1,message:`${t.label}字段范围超出 (${t.min}-${t.max})`}:n>r?{valid:!1,message:`${t.label}字段范围起始不能大于结束`}:{valid:!0,message:``}}function p(e,t){let n=e.split(`,`).map(Number);return n.some(isNaN)?{valid:!1,message:`${t.label}字段包含非数字字符`}:n.some(e=>e<t.min||e>t.max)?{valid:!1,message:`${t.label}字段值超出范围 (${t.min}-${t.max})`}:{valid:!0,message:``}}function m(e,t){return e===`*`||e===`?`?{valid:!0,message:``}:e.includes(`/`)?u(e,t):e.includes(`-`)&&!e.includes(`,`)?d(e,t):p(e,t)}return{cronValue:e,expression:f(()=>o()),validation:f(()=>l()),parse:s,generate:o,validate:l,handleDayWeekExclusion:c}}function z(e,t,n){let r=w([]),i=w(!1);function a(e,t){if(t===`*`||t===`?`)return!0;if(t.includes(`/`)){let[n,r]=t.split(`/`),i=n===`*`?0:Number(n),a=Number(r);return e-i>=0&&(e-i)%a===0}if(t.includes(`-`)&&!t.includes(`,`)){let[n,r]=t.split(`-`).map(Number);return e>=n&&e<=r}return t.split(`,`).map(Number).includes(e)}function o(e,t){if(t.length!==6)return!1;let[n,r,i,o,s,c]=t;return!(!a(e.getMonth()+1,s)||o!==`?`&&!a(e.getDate(),o)||c!==`?`&&!a(e.getDay()+1,c)||!a(e.getHours(),i)||!a(e.getMinutes(),r)||!a(e.getSeconds(),n))}function s(){let r=e.value;if(!r||!t.value.valid)return[];let i=r.trim().split(/\s+/);if(i.length!==6)return[];let a=[],s=new Date,c=new Date(s.getTime()+1e3);c.setMilliseconds(0);let l=i[0]!==`0`,u=l?1e3:6e4;l||(c.setSeconds(0),c.getTime()<=s.getTime()&&c.setTime(c.getTime()+6e4));let d=n.value;for(let e=0;e<525600&&a.length<d;e++)o(c,i)&&a.push(new Date(c)),c.setTime(c.getTime()+u);return a}O([e,n],()=>{if(!t.value.valid){r.value=[];return}i.value=!0,setTimeout(()=>{r.value=s(),i.value=!1},0)},{immediate:!0});function c(e){let t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function l(e){return[`周日`,`周一`,`周二`,`周三`,`周四`,`周五`,`周六`][e.getDay()]}return{nextExecutions:r,computing:i,formatDate:c,formatWeekDay:l}}function B(e){return I[Number(e)]||`周${e}`}function re(e,t){let n=f(()=>t.value.valid?r(e.value):`表达式不合法`);function r(e){let t=e.trim().split(/\s+/);if(t.length!==6)return`表达式格式错误`;let[n,r,u,d,f,p]=t,m=[];return m.push(c(f)),p===`?`?m.push(s(d)):m.push(l(p)),m.push(o(u)),m.push(a(r)),m.push(i(n)),m.filter(Boolean).join(` `)+` 执行`}function i(e){return e===`0`?``:e===`*`?`每秒`:u(e,`秒`)}function a(e){return e===`*`?`每分钟`:e===`0`?``:u(e,`分`)}function o(e){return e===`*`?`每小时`:/^\d+$/.test(e)?`${e.padStart(2,`0`)}:`:u(e,`时`)}function s(e){if(e===`*`||e===`?`)return`每天`;if(/^\d+$/.test(e))return`每月 ${e} 号`;if(e.includes(`/`)){let[t,n]=e.split(`/`);return`从 ${t} 号开始每 ${n} 天`}if(e.includes(`-`)){let[t,n]=e.split(`-`);return`${t} 号到 ${n} 号`}return e.includes(`,`)?`每月 ${e} 号`:``}function c(e){if(e===`*`)return``;if(/^\d+$/.test(e)){let t=Number(e);return F[t]?`${F[t]}`:`${t} 月`}if(e.includes(`/`)){let[t,n]=e.split(`/`);return`从 ${t} 月开始每 ${n} 个月`}if(e.includes(`-`)){let[t,n]=e.split(`-`);return`${t} 月到 ${n} 月`}return e.includes(`,`)?e.split(`,`).map(e=>F[Number(e)]||`${e}月`).join(`、`):``}function l(e){return e===`*`||e===`?`?``:/^\d+$/.test(e)?`每${B(e)}`:e.includes(`/`)?`从${B(e.split(`/`)[0])}开始每 ${e.split(`/`)[1]} 天`:e.includes(`-`)?`${B(e.split(`-`)[0])}到${B(e.split(`-`)[1])}`:e.includes(`,`)?`每${e.split(`,`).map(B).join(`、`)}`:``}function u(e,t){if(e.includes(`/`)){let[n,r]=e.split(`/`);return`${n===`*`||n===`0`?``:`从第 ${n} ${t}开始`}每 ${r} ${t}`}if(e.includes(`-`)){let[n,r]=e.split(`-`);return`${n} ${t}到 ${r} ${t}`}return e.includes(`,`)?`第 ${e} ${t}`:/^\d+$/.test(e)?`${e.padStart(2,`0`)}`:``}return{description:n}}const ie={class:`cron-field-editor`},ae=[`onClick`];var oe=t(y({__name:`CronFieldEditor`,props:{modelValue:{},meta:{}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,r=t,i=f(()=>{switch(n.meta.type){case`second`:case`minute`:return 10;case`hour`:return 12;case`day`:return 7;case`month`:return 6;case`week`:return 7;default:return 10}}),a=f(()=>{let e=[];for(let t=n.meta.min;t<=n.meta.max;t++)e.push({value:t,label:n.meta.valueLabels?.[t]??String(t)});return e}),o=f(()=>{let{modelValue:e,meta:t}=n,r=new Set;switch(e.mode){case`every`:for(let e=t.min;e<=t.max;e++)r.add(e);break;case`none`:break;case`range`:for(let t=e.rangeStart;t<=e.rangeEnd;t++)r.add(t);break;case`step`:for(let n=e.stepStart;n<=t.max;n+=e.stepInterval)r.add(n);break;case`specific`:e.specificValues.forEach(e=>r.add(e));break}return r});function s(e){if(n.modelValue.mode!==`specific`)return;let t=[...n.modelValue.specificValues],i=t.indexOf(e);i>=0?t.splice(i,1):t.push(e),r(`update:modelValue`,{...n.modelValue,specificValues:t})}return(e,t)=>(C(),h(`div`,ie,[g(`div`,{class:`cron-field-editor__grid`,style:x({"--cols":i.value})},[(C(!0),h(d,null,T(a.value,t=>(C(),h(`div`,{key:t.value,class:b([`cron-field-editor__cell`,{"cron-field-editor__cell--on":o.value.has(t.value),"cron-field-editor__cell--pick":e.modelValue.mode===`specific`}]),onClick:e=>s(t.value)},E(t.label),11,ae))),128))],4)]))}}),[[`__scopeId`,`data-v-769c51fe`]]);const V={class:`cron-preview`},H={class:`cron-preview__header`},U={key:0,class:`cron-preview__list`},W={class:`cron-preview__idx`},G={class:`cron-preview__date`},K={class:`cron-preview__week`};var se=t(y({__name:`CronPreview`,props:{nextExecutions:{},computing:{type:Boolean},count:{},formatDate:{type:Function},formatWeekDay:{type:Function}},setup(t){return(t,n)=>{let i=l,a=r,o=c;return C(),h(`div`,V,[g(`div`,H,[v(e,{name:`mdi:calendar-clock`,size:15}),n[0]||=g(`span`,null,`未来执行`,-1),t.computing?(C(),p(i,{key:0,size:14})):m(`v-if`,!0)]),v(o,{style:{"max-height":`220px`}},{default:k(()=>[t.nextExecutions.length>0?(C(),h(`div`,U,[(C(!0),h(d,null,T(t.nextExecutions,(e,n)=>(C(),h(`div`,{key:n,class:`cron-preview__item`},[g(`span`,W,E(n+1),1),g(`span`,G,E(t.formatDate(e)),1),g(`span`,K,E(t.formatWeekDay(e)),1)]))),128))])):(C(),p(a,{key:1,size:`small`,description:`暂无匹配`}))]),_:1})])}}}),[[`__scopeId`,`data-v-570ad3fb`]]);const q={class:`cron-templates`},J={class:`cron-templates__header`},Y={class:`cron-templates__cards`},ce=[`onClick`],X={class:`cron-templates__card-name`},Z={class:`cron-templates__card-expr`};var le=t(y({__name:`CronTemplates`,props:{templates:{},currentValue:{}},emits:[`select`],setup(t){return(t,n)=>(C(),h(`div`,q,[g(`div`,J,[v(e,{name:`mdi:lightning-bolt`,size:15}),n[0]||=g(`span`,null,`常用模板`,-1)]),g(`div`,Y,[(C(!0),h(d,null,T(t.templates,e=>(C(),h(`div`,{key:e.value,class:b([`cron-templates__card`,{"cron-templates__card--active":e.value===t.currentValue}]),onClick:n=>t.$emit(`select`,e.value)},[g(`div`,X,E(e.label),1),g(`div`,Z,E(e.value),1)],10,ce))),128))])]))}}),[[`__scopeId`,`data-v-5190cefc`]]);const ue={class:`c-cron__header`},de={class:`c-cron__title-row`},fe={class:`c-cron__title`},pe={class:`c-cron__segments`},me=[`onClick`],he={class:`c-cron__segment-value`},ge={class:`c-cron__segment-label`},_e={class:`c-cron__expr-row`},ve={class:`c-cron__expr-desc`},ye={key:0,class:`c-cron__description`},be={key:1,class:`c-cron__error`},xe={class:`c-cron__body`},Se={class:`c-cron__main`},Ce={class:`c-cron__panel`},we={key:0,class:`c-cron__config`},Te={class:`c-cron__config-row`},Ee={key:1,class:`c-cron__config`},De={class:`c-cron__config-row`},Oe={key:2,class:`c-cron__quick`},ke={key:0,class:`c-cron__quick-count`},Ae={key:0,class:`c-cron__footer`};var je=t(y({name:`C_Cron`,__name:`index`,props:{modelValue:{default:N},disabled:{type:Boolean,default:!1},previewCount:{default:10},showTemplates:{type:Boolean,default:!0},showPreview:{type:Boolean,default:!0},showSecond:{type:Boolean,default:!0},height:{default:`auto`}},emits:[`update:modelValue`,`change`,`validation-change`],setup(t,{expose:r,emit:c}){let l=t,y=c,{cronValue:j,expression:M,validation:F,parse:I,validate:L,handleDayWeekExclusion:B}=R(),{nextExecutions:ie,computing:ae,formatDate:V,formatWeekDay:H}=z(M,F,f(()=>l.previewCount??10)),{description:U}=re(M,F),W=w(l.modelValue||N),G=w(l.showSecond?`second`:`minute`),K=f(()=>typeof l.height==`number`?`${l.height}px`:l.height),q=f(()=>l.showSecond?A:A.filter(e=>e.type!==`second`)),J=f(()=>A.find(e=>e.type===G.value)),Y=f(()=>j.value[G.value]);function ce(e){switch(e.mode){case`every`:return`*`;case`none`:return`?`;case`range`:return`${e.rangeStart}-${e.rangeEnd}`;case`step`:return`${e.stepStart}/${e.stepInterval}`;case`specific`:return e.specificValues.length>0?[...e.specificValues].sort((e,t)=>e-t).join(`,`):`*`;default:return`*`}}let X=f(()=>{let e={};for(let t of A)e[t.type]=ce(j.value[t.type]);return e});S(()=>{let e=l.modelValue||N;I(e),W.value=e}),O(()=>l.modelValue,e=>{e&&e!==M.value&&(I(e),W.value=e)}),O(()=>l.showSecond,e=>{!e&&G.value===`second`&&(G.value=`minute`)}),O(M,e=>{W.value=e,y(`update:modelValue`,e),y(`change`,e)}),O(F,e=>{y(`validation-change`,e)});function Z(e,t){j.value[e]=t,(e===`day`||e===`week`)&&B(e)}function je(e){Z(G.value,{...Y.value,mode:e})}function Q(e){Z(G.value,{...Y.value,...e})}function Me(){let{min:e,max:t}=J.value,n=Array.from({length:t-e+1},(t,n)=>e+n);Z(G.value,{...Y.value,specificValues:n})}function Ne(){Z(G.value,{...Y.value,specificValues:[]})}function Pe(e){W.value=e}function Fe(){let e=W.value.trim();e&&e!==M.value&&I(e)}function Ie(e){I(e),W.value=e}function $(){let e=l.modelValue||N;I(e),W.value=e}return r({getValue:()=>M.value,setValue:e=>{I(e),W.value=e},reset:$,validate:()=>L()}),(t,r)=>{let c=u,f=i,y=n,S=o,w=s,O=a;return C(),h(`div`,{class:`c-cron`,style:x({height:K.value})},[m(` ═══════ 顶部 ═══════ `),g(`div`,ue,[m(` 标题行 `),g(`div`,de,[g(`div`,fe,[v(e,{name:`mdi:clock-edit-outline`,size:18}),r[4]||=g(`span`,null,`Cron 表达式`,-1)]),v(c,{type:D(F).valid?`success`:`error`,size:`small`,round:``},{icon:k(()=>[v(e,{name:D(F).valid?`mdi:check-circle`:`mdi:alert-circle`},null,8,[`name`])]),default:k(()=>[_(` `+E(D(F).valid?`合法`:`错误`),1)]),_:1},8,[`type`])]),m(` 分段式字段选择器 `),g(`div`,pe,[(C(!0),h(d,null,T(q.value,e=>(C(),h(`div`,{key:e.type,class:b([`c-cron__segment`,{"c-cron__segment--active":G.value===e.type,"c-cron__segment--wildcard":X.value[e.type]===`*`||X.value[e.type]===`?`}]),onClick:t=>G.value=e.type},[g(`div`,he,E(X.value[e.type]),1),g(`div`,ge,E(e.label),1)],10,me))),128))]),m(` 表达式行:输入 + 重置 + 描述 `),g(`div`,_e,[v(f,{value:W.value,status:D(F).valid?void 0:`error`,placeholder:`秒 分 时 日 月 周`,disabled:l.disabled,font:`mono`,size:`small`,clearable:``,class:`c-cron__expr-input`,"onUpdate:value":Pe,onBlur:Fe,onKeydown:ne(Fe,[`enter`])},{prefix:k(()=>[v(e,{name:`mdi:console`,size:14,style:{opacity:`0.4`}})]),_:1},8,[`value`,`status`,`disabled`]),v(y,{size:`small`,quaternary:``,disabled:l.disabled,onClick:$},{icon:k(()=>[v(e,{name:`mdi:refresh`})]),_:1},8,[`disabled`]),g(`div`,ve,[D(F).valid?(C(),h(`span`,ye,E(D(U)),1)):(C(),h(`span`,be,E(D(F).message),1))])])]),m(` ═══════ 主内容 ═══════ `),g(`div`,xe,[m(` 左侧:值网格 `),g(`div`,Se,[(C(!0),h(d,null,T(q.value,e=>te((C(),p(oe,{key:e.type,"model-value":D(j)[e.type],meta:e,"onUpdate:modelValue":t=>Z(e.type,t)},null,8,[`model-value`,`meta`,`onUpdate:modelValue`])),[[ee,G.value===e.type]])),128))]),m(` 右侧:控制面板 `),g(`div`,Ce,[v(w,{value:Y.value.mode,size:`small`,"onUpdate:value":je},{default:k(()=>[v(S,{value:`every`},{default:k(()=>[_(` 每`+E(J.value.label),1)]),_:1}),G.value===`day`||G.value===`week`?(C(),p(S,{key:0,value:`none`},{default:k(()=>r[5]||=[_(` 不指定 `,-1)]),_:1,__:[5]})):m(`v-if`,!0),v(S,{value:`range`},{default:k(()=>r[6]||=[_(`范围`,-1)]),_:1,__:[6]}),v(S,{value:`step`},{default:k(()=>r[7]||=[_(`步进`,-1)]),_:1,__:[7]}),v(S,{value:`specific`},{default:k(()=>r[8]||=[_(`指定`,-1)]),_:1,__:[8]})]),_:1},8,[`value`]),m(` 范围配置 `),Y.value.mode===`range`?(C(),h(`div`,we,[g(`div`,Te,[r[9]||=g(`span`,null,`从`,-1),v(O,{value:Y.value.rangeStart,min:J.value.min,max:J.value.max,size:`small`,"show-button":!1,class:`c-cron__config-num`,"onUpdate:value":r[0]||=e=>Q({rangeStart:e??J.value.min})},null,8,[`value`,`min`,`max`]),r[10]||=g(`span`,null,`到`,-1),v(O,{value:Y.value.rangeEnd,min:J.value.min,max:J.value.max,size:`small`,"show-button":!1,class:`c-cron__config-num`,"onUpdate:value":r[1]||=e=>Q({rangeEnd:e??J.value.max})},null,8,[`value`,`min`,`max`])])])):m(`v-if`,!0),m(` 步进配置 `),Y.value.mode===`step`?(C(),h(`div`,Ee,[g(`div`,De,[r[11]||=g(`span`,null,`从第`,-1),v(O,{value:Y.value.stepStart,min:J.value.min,max:J.value.max,size:`small`,"show-button":!1,class:`c-cron__config-num`,"onUpdate:value":r[2]||=e=>Q({stepStart:e??J.value.min})},null,8,[`value`,`min`,`max`]),g(`span`,null,E(J.value.label)+`起,每`,1),v(O,{value:Y.value.stepInterval,min:1,max:J.value.max-J.value.min+1,size:`small`,"show-button":!1,class:`c-cron__config-num`,"onUpdate:value":r[3]||=e=>Q({stepInterval:e??1})},null,8,[`value`,`max`]),g(`span`,null,E(J.value.label)+`执行`,1)])])):m(`v-if`,!0),m(` 指定快捷操作 `),Y.value.mode===`specific`?(C(),h(`div`,Oe,[g(`a`,{onClick:Me},`全选`),r[12]||=g(`span`,{class:`c-cron__quick-sep`},`·`,-1),g(`a`,{onClick:Ne},`清空`),Y.value.specificValues.length>0?(C(),h(`span`,ke,` 已选 `+E(Y.value.specificValues.length),1)):m(`v-if`,!0)])):m(`v-if`,!0),m(` 执行预览 `),l.showPreview?(C(),h(d,{key:3},[r[13]||=g(`div`,{class:`c-cron__panel-line`},null,-1),v(se,{"next-executions":D(ie),computing:D(ae),count:l.previewCount??5,"format-date":D(V),"format-week-day":D(H)},null,8,[`next-executions`,`computing`,`count`,`format-date`,`format-week-day`])],64)):m(`v-if`,!0)])]),m(` ═══════ 底部模板 ═══════ `),l.showTemplates?(C(),h(`div`,Ae,[v(le,{templates:D(P),"current-value":D(M),onSelect:Ie},null,8,[`templates`,`current-value`])])):m(`v-if`,!0)],4)}}}),[[`__scopeId`,`data-v-b3efef0a`]]);export{A as a,M as c,I as d,R as i,j as l,re as n,P as o,z as r,N as s,je as t,F as u};
1210
2
  //# sourceMappingURL=C_Cron2.js.map