@a2simcode/ui 0.0.237 → 0.0.239

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 (361) hide show
  1. package/.cursor/skills/ui-component-helper/README.md +86 -86
  2. package/.cursor/skills/ui-component-helper/SKILL.md +115 -115
  3. package/LICENSE +53 -53
  4. package/README.md +156 -156
  5. package/dist/components/comp/src/interface.d.ts +1 -0
  6. package/dist/components/input-button/src/input-button.vue.d.ts +2 -0
  7. package/dist/components/input-code/src/input-code.vue.d.ts +2 -0
  8. package/dist/components/switch/index.d.ts +3 -3
  9. package/dist/components/switch/src/switch.vue.d.ts +1 -1
  10. package/dist/simcode-ui.es.js +961 -937
  11. package/dist/simcode-ui.umd.js +2 -2
  12. package/dist/stats.html +1 -1
  13. package/dist/ui.css +1 -1
  14. package/docs/components/autocomplete.md +89 -89
  15. package/docs/components/barcode.md +101 -101
  16. package/docs/components/button-select.md +24 -24
  17. package/docs/components/button.md +117 -117
  18. package/docs/components/buttons.md +119 -119
  19. package/docs/components/cascader-select.md +114 -114
  20. package/docs/components/checkbox.md +114 -114
  21. package/docs/components/code-mirror.md +85 -85
  22. package/docs/components/collapse.md +26 -26
  23. package/docs/components/comp.md +71 -71
  24. package/docs/components/count-up.md +24 -24
  25. package/docs/components/count.md +24 -24
  26. package/docs/components/data-panel.md +24 -24
  27. package/docs/components/date.md +76 -76
  28. package/docs/components/dialog-full.md +112 -112
  29. package/docs/components/dialog.md +127 -127
  30. package/docs/components/divider.md +24 -24
  31. package/docs/components/drawer.md +127 -127
  32. package/docs/components/dynamic-layer.md +118 -118
  33. package/docs/components/echarts.md +72 -72
  34. package/docs/components/editor.md +24 -24
  35. package/docs/components/form.md +87 -87
  36. package/docs/components/guid.md +39 -39
  37. package/docs/components/hpanel.md +24 -24
  38. package/docs/components/icon.md +56 -56
  39. package/docs/components/input-button.md +24 -24
  40. package/docs/components/input-code.md +24 -24
  41. package/docs/components/input-color.md +114 -114
  42. package/docs/components/input-layer.md +56 -56
  43. package/docs/components/input-rows.md +370 -370
  44. package/docs/components/input-tag.md +50 -50
  45. package/docs/components/input.md +129 -129
  46. package/docs/components/layer-form.md +61 -61
  47. package/docs/components/layer.md +127 -127
  48. package/docs/components/layout.md +132 -132
  49. package/docs/components/map.md +24 -24
  50. package/docs/components/menu.md +121 -121
  51. package/docs/components/meta/button.ts +212 -212
  52. package/docs/components/meta/buttons.ts +76 -76
  53. package/docs/components/meta/code-mirror.ts +108 -108
  54. package/docs/components/meta/comp.ts +236 -236
  55. package/docs/components/meta/date.ts +267 -267
  56. package/docs/components/meta/echarts.ts +64 -64
  57. package/docs/components/meta/form-item.ts +50 -50
  58. package/docs/components/meta/form.ts +181 -181
  59. package/docs/components/meta/input-button.ts +165 -165
  60. package/docs/components/meta/input-cards.ts +112 -112
  61. package/docs/components/meta/input-code.ts +151 -151
  62. package/docs/components/meta/input-color.ts +243 -243
  63. package/docs/components/meta/input-layer.ts +382 -382
  64. package/docs/components/meta/input-rows.ts +119 -119
  65. package/docs/components/meta/layer-form.ts +74 -74
  66. package/docs/components/meta/map.ts +68 -68
  67. package/docs/components/meta/panel.ts +152 -152
  68. package/docs/components/meta/radio.ts +55 -55
  69. package/docs/components/meta/select.ts +279 -279
  70. package/docs/components/meta/slider.ts +270 -270
  71. package/docs/components/meta/table-panel.ts +260 -260
  72. package/docs/components/meta/table.ts +403 -403
  73. package/docs/components/meta/tabs.ts +146 -146
  74. package/docs/components/meta/title.ts +91 -91
  75. package/docs/components/meta/tree-select.ts +199 -199
  76. package/docs/components/meta/tree.ts +219 -219
  77. package/docs/components/meta/vpanel.ts +19 -19
  78. package/docs/components/meta/workflow-viewer.ts +55 -55
  79. package/docs/components/number.md +124 -124
  80. package/docs/components/page.md +102 -102
  81. package/docs/components/panel.md +37 -37
  82. package/docs/components/radio.md +87 -87
  83. package/docs/components/rate.md +71 -71
  84. package/docs/components/select.md +133 -133
  85. package/docs/components/slider-captcha.md +41 -41
  86. package/docs/components/slider.md +101 -101
  87. package/docs/components/switch.md +90 -90
  88. package/docs/components/table-panel.md +282 -282
  89. package/docs/components/table.md +435 -435
  90. package/docs/components/tabs.md +26 -26
  91. package/docs/components/title.md +24 -24
  92. package/docs/components/tree.md +207 -207
  93. package/docs/components/upload.md +117 -117
  94. package/docs/components/workflow-viewer.md +21 -21
  95. package/docs/components/workflow.md +21 -21
  96. package/docs/examples/autocomplete/advanced.vue +35 -35
  97. package/docs/examples/autocomplete/basic.vue +32 -32
  98. package/docs/examples/autocomplete/clearable.vue +33 -33
  99. package/docs/examples/autocomplete/custom-template.vue +49 -49
  100. package/docs/examples/autocomplete/disabled.vue +33 -33
  101. package/docs/examples/autocomplete/icon.vue +37 -37
  102. package/docs/examples/barcode/all-types.vue +380 -380
  103. package/docs/examples/barcode/basic.vue +14 -14
  104. package/docs/examples/barcode/props-appearance.vue +243 -243
  105. package/docs/examples/barcode/props-geometry.vue +143 -143
  106. package/docs/examples/barcode/props-logic.vue +216 -216
  107. package/docs/examples/barcode/props-symbology.vue +199 -199
  108. package/docs/examples/barcode/props-text.vue +268 -268
  109. package/docs/examples/button/basic.vue +7 -7
  110. package/docs/examples/button/disabled.vue +42 -42
  111. package/docs/examples/button/loading.vue +6 -6
  112. package/docs/examples/button/shape.vue +7 -7
  113. package/docs/examples/button/size.vue +14 -14
  114. package/docs/examples/button/status.vue +34 -34
  115. package/docs/examples/button/type.vue +10 -10
  116. package/docs/examples/button-select/basic.vue +19 -19
  117. package/docs/examples/buttons/basic.vue +62 -62
  118. package/docs/examples/buttons/disabled.vue +36 -36
  119. package/docs/examples/buttons/dropdown.vue +63 -63
  120. package/docs/examples/buttons/group.vue +52 -52
  121. package/docs/examples/buttons/link.vue +47 -47
  122. package/docs/examples/buttons/popup.vue +39 -39
  123. package/docs/examples/buttons/size.vue +45 -45
  124. package/docs/examples/cascader-select/basic.vue +28 -28
  125. package/docs/examples/cascader-select/clearable.vue +34 -34
  126. package/docs/examples/cascader-select/disabled.vue +43 -43
  127. package/docs/examples/cascader-select/filterable.vue +37 -37
  128. package/docs/examples/cascader-select/methods.vue +84 -84
  129. package/docs/examples/cascader-select/multiple.vue +38 -38
  130. package/docs/examples/cascader-select/slot.vue +45 -45
  131. package/docs/examples/checkbox/basic.vue +18 -18
  132. package/docs/examples/checkbox/button.vue +19 -19
  133. package/docs/examples/checkbox/color.vue +25 -25
  134. package/docs/examples/checkbox/disabled.vue +17 -17
  135. package/docs/examples/checkbox/min-max.vue +20 -20
  136. package/docs/examples/checkbox/mixed.vue +56 -56
  137. package/docs/examples/checkbox/size.vue +28 -28
  138. package/docs/examples/code-mirror/basic.vue +11 -11
  139. package/docs/examples/code-mirror/events.vue +42 -42
  140. package/docs/examples/code-mirror/height.vue +25 -25
  141. package/docs/examples/code-mirror/mode.vue +33 -33
  142. package/docs/examples/code-mirror/readonly.vue +14 -14
  143. package/docs/examples/collapse/basic.vue +82 -82
  144. package/docs/examples/comp/basic.vue +7 -7
  145. package/docs/examples/comp/collapse.vue +38 -38
  146. package/docs/examples/comp/tabs.vue +38 -38
  147. package/docs/examples/count/basic.vue +101 -101
  148. package/docs/examples/count-up/basic.vue +89 -89
  149. package/docs/examples/data-panel/basic.vue +110 -110
  150. package/docs/examples/date/basic.vue +73 -73
  151. package/docs/examples/date/default-value.vue +59 -59
  152. package/docs/examples/date/format.vue +75 -75
  153. package/docs/examples/date/range.vue +66 -66
  154. package/docs/examples/date/types.vue +79 -79
  155. package/docs/examples/decorated-title/basic.vue +31 -31
  156. package/docs/examples/dialog/basic.vue +36 -36
  157. package/docs/examples/dialog/custom-buttons.vue +44 -44
  158. package/docs/examples/dialog/fullscreen.vue +23 -23
  159. package/docs/examples/dialog/no-mask.vue +17 -17
  160. package/docs/examples/dialog/size.vue +44 -44
  161. package/docs/examples/dialog/steps.vue +57 -57
  162. package/docs/examples/dialog-full/basic.vue +29 -29
  163. package/docs/examples/dialog-full/custom-buttons.vue +45 -45
  164. package/docs/examples/dialog-full/no-buttons.vue +18 -18
  165. package/docs/examples/dialog-full/no-header.vue +27 -27
  166. package/docs/examples/dialog-full/steps.vue +71 -71
  167. package/docs/examples/divider/basic.vue +52 -52
  168. package/docs/examples/drawer/basic.vue +35 -35
  169. package/docs/examples/drawer/custom-buttons.vue +34 -34
  170. package/docs/examples/drawer/direction.vue +47 -47
  171. package/docs/examples/drawer/mask.vue +36 -36
  172. package/docs/examples/drawer/no-buttons.vue +20 -20
  173. package/docs/examples/drawer/size.vue +28 -28
  174. package/docs/examples/dynamic-layer/basic.vue +33 -33
  175. package/docs/examples/dynamic-layer/custom-buttons.vue +43 -43
  176. package/docs/examples/dynamic-layer/form.vue +73 -73
  177. package/docs/examples/dynamic-layer/steps.vue +52 -52
  178. package/docs/examples/dynamic-layer/types.vue +40 -40
  179. package/docs/examples/echarts/basic.vue +31 -31
  180. package/docs/examples/echarts/dynamic.vue +43 -43
  181. package/docs/examples/echarts/line.vue +46 -46
  182. package/docs/examples/echarts/pie.vue +44 -44
  183. package/docs/examples/editor/basic.vue +15 -15
  184. package/docs/examples/form/basic.vue +663 -663
  185. package/docs/examples/form/init.vue +76 -76
  186. package/docs/examples/form/master-detail.vue +203 -203
  187. package/docs/examples/form/rule-format.vue +179 -179
  188. package/docs/examples/form/view-table.vue +378 -378
  189. package/docs/examples/guid/basic.vue +10 -10
  190. package/docs/examples/guid/size.vue +13 -13
  191. package/docs/examples/hpanel/basic.vue +79 -79
  192. package/docs/examples/icon/basic.vue +9 -9
  193. package/docs/examples/icon/rotate-flip.vue +9 -9
  194. package/docs/examples/icon/size.vue +7 -7
  195. package/docs/examples/input/basic.vue +10 -10
  196. package/docs/examples/input/clearable.vue +12 -12
  197. package/docs/examples/input/disabled.vue +6 -6
  198. package/docs/examples/input/icon.vue +23 -23
  199. package/docs/examples/input/password.vue +18 -18
  200. package/docs/examples/input/size.vue +13 -13
  201. package/docs/examples/input/textarea.vue +25 -25
  202. package/docs/examples/input/word-limit.vue +28 -28
  203. package/docs/examples/input-button/basic.vue +33 -33
  204. package/docs/examples/input-cards/basic.vue +79 -79
  205. package/docs/examples/input-code/basic.vue +29 -29
  206. package/docs/examples/input-color/basic.vue +10 -10
  207. package/docs/examples/input-color/disabled.vue +13 -13
  208. package/docs/examples/input-color/format.vue +17 -17
  209. package/docs/examples/input-color/no-alpha.vue +13 -13
  210. package/docs/examples/input-color/only-button.vue +15 -15
  211. package/docs/examples/input-color/predefine.vue +31 -31
  212. package/docs/examples/input-color/size.vue +15 -15
  213. package/docs/examples/input-layer/basic.vue +85 -85
  214. package/docs/examples/input-layer/render-vnode-page.vue +160 -160
  215. package/docs/examples/input-layer/render-vnode.vue +127 -127
  216. package/docs/examples/input-rows/basic.vue +73 -73
  217. package/docs/examples/input-rows/drag.vue +48 -48
  218. package/docs/examples/input-rows/layer-form.vue +85 -85
  219. package/docs/examples/input-rows/nested.vue +91 -91
  220. package/docs/examples/input-tag/basic.vue +27 -27
  221. package/docs/examples/input-tag/colors.vue +23 -23
  222. package/docs/examples/input-tag/readonly.vue +17 -17
  223. package/docs/examples/layer/basic.vue +43 -43
  224. package/docs/examples/layer/custom-buttons.vue +61 -61
  225. package/docs/examples/layer/drawer.vue +37 -37
  226. package/docs/examples/layer/full.vue +38 -38
  227. package/docs/examples/layer/modal.vue +34 -34
  228. package/docs/examples/layer/steps.vue +46 -46
  229. package/docs/examples/layer-form/basic.vue +76 -76
  230. package/docs/examples/layer-form/config.vue +82 -82
  231. package/docs/examples/layer-form/size.vue +72 -72
  232. package/docs/examples/layout/basic.vue +36 -36
  233. package/docs/examples/layout/custom-size.vue +50 -50
  234. package/docs/examples/layout/disable-move.vue +37 -37
  235. package/docs/examples/layout/hide-mid-when-narrow.vue +96 -96
  236. package/docs/examples/layout/min-size.vue +73 -73
  237. package/docs/examples/layout/percent-size.vue +80 -80
  238. package/docs/examples/layout/simple.vue +22 -22
  239. package/docs/examples/layout/top-side.vue +34 -34
  240. package/docs/examples/map/basic.vue +22 -22
  241. package/docs/examples/menu/basic.vue +58 -58
  242. package/docs/examples/menu/collapsed.vue +49 -49
  243. package/docs/examples/menu/horizontal.vue +44 -44
  244. package/docs/examples/menu/selection-test.vue +104 -104
  245. package/docs/examples/menu/theme.vue +46 -46
  246. package/docs/examples/menu/vertical.vue +46 -46
  247. package/docs/examples/number/advanced.vue +143 -143
  248. package/docs/examples/number/basic.vue +63 -63
  249. package/docs/examples/number/disabled.vue +49 -49
  250. package/docs/examples/number/size.vue +42 -42
  251. package/docs/examples/number/slots.vue +123 -123
  252. package/docs/examples/number/step-strictly.vue +41 -41
  253. package/docs/examples/number/step.vue +47 -47
  254. package/docs/examples/page/basic.vue +41 -41
  255. package/docs/examples/page/code-table-model.vue +428 -428
  256. package/docs/examples/page/dept-user-management.vue +211 -211
  257. package/docs/examples/page/init.vue +87 -87
  258. package/docs/examples/page/log.vue +453 -453
  259. package/docs/examples/page/user-management.vue +313 -313
  260. package/docs/examples/panel/tool-buttons.vue +18 -18
  261. package/docs/examples/radio/basic.vue +17 -17
  262. package/docs/examples/radio/button.vue +17 -17
  263. package/docs/examples/radio/color.vue +18 -18
  264. package/docs/examples/radio/disabled.vue +17 -17
  265. package/docs/examples/radio/size.vue +29 -29
  266. package/docs/examples/rate/basic.vue +24 -24
  267. package/docs/examples/rate/half.vue +24 -24
  268. package/docs/examples/rate/readonly.vue +11 -11
  269. package/docs/examples/rate/text.vue +37 -37
  270. package/docs/examples/select/basic.vue +16 -16
  271. package/docs/examples/select/clearable.vue +22 -22
  272. package/docs/examples/select/disabled.vue +31 -31
  273. package/docs/examples/select/filterable.vue +24 -24
  274. package/docs/examples/select/group.vue +23 -23
  275. package/docs/examples/select/icon.vue +16 -16
  276. package/docs/examples/select/multiple.vue +18 -18
  277. package/docs/examples/select/size.vue +39 -39
  278. package/docs/examples/slider/basic.vue +42 -42
  279. package/docs/examples/slider/disabled.vue +17 -17
  280. package/docs/examples/slider/marks.vue +30 -30
  281. package/docs/examples/slider/size.vue +37 -37
  282. package/docs/examples/slider/tooltip.vue +36 -36
  283. package/docs/examples/slider/vertical.vue +26 -26
  284. package/docs/examples/slider-captcha/basic.vue +44 -44
  285. package/docs/examples/slider-captcha/custom.vue +48 -48
  286. package/docs/examples/switch/basic.vue +16 -16
  287. package/docs/examples/switch/disabled.vue +13 -13
  288. package/docs/examples/switch/loading.vue +13 -13
  289. package/docs/examples/switch/size.vue +15 -15
  290. package/docs/examples/switch/text.vue +13 -13
  291. package/docs/examples/table/action-filter.vue +126 -126
  292. package/docs/examples/table/actions.vue +116 -116
  293. package/docs/examples/table/add-row.vue +103 -103
  294. package/docs/examples/table/basic.vue +168 -168
  295. package/docs/examples/table/checkbox-layout.vue +68 -68
  296. package/docs/examples/table/custom-layout.vue +115 -115
  297. package/docs/examples/table/dynamic-type.vue +73 -73
  298. package/docs/examples/table/editable.vue +262 -262
  299. package/docs/examples/table/field-selection.vue +87 -87
  300. package/docs/examples/table/frozen-column.vue +140 -140
  301. package/docs/examples/table/height-mode.vue +99 -99
  302. package/docs/examples/table/icon.vue +85 -85
  303. package/docs/examples/table/layer-form.vue +133 -133
  304. package/docs/examples/table/link.vue +66 -66
  305. package/docs/examples/table/multiple-disabled.vue +112 -112
  306. package/docs/examples/table/multiple.vue +188 -188
  307. package/docs/examples/table/pagination.vue +151 -151
  308. package/docs/examples/table/row-drag.vue +67 -67
  309. package/docs/examples/table/single-selection.vue +64 -64
  310. package/docs/examples/table/sub-table-lazy.vue +97 -97
  311. package/docs/examples/table/sub-table.vue +103 -103
  312. package/docs/examples/table/tag.vue +43 -43
  313. package/docs/examples/table/tree-column.vue +119 -119
  314. package/docs/examples/table/tree-data.vue +141 -141
  315. package/docs/examples/table/tree-default-expand-all.vue +60 -60
  316. package/docs/examples/table/tree-lazy.vue +80 -80
  317. package/docs/examples/table/tree-set-selection.vue +75 -75
  318. package/docs/examples/table-panel/basic.vue +229 -229
  319. package/docs/examples/table-panel/batch-operations.vue +286 -286
  320. package/docs/examples/table-panel/button-visibility.vue +88 -88
  321. package/docs/examples/table-panel/filter.vue +219 -219
  322. package/docs/examples/table-panel/get-selection.vue +111 -111
  323. package/docs/examples/table-panel/mask.vue +151 -151
  324. package/docs/examples/table-panel/model-value.vue +87 -87
  325. package/docs/examples/table-panel/multiple-selection.vue +243 -243
  326. package/docs/examples/table-panel/pagination.vue +133 -133
  327. package/docs/examples/table-panel/search-list.vue +207 -207
  328. package/docs/examples/table-panel/sub-table-lazy.vue +118 -118
  329. package/docs/examples/table-panel/tree-parent-key.vue +67 -67
  330. package/docs/examples/tabs/basic.vue +98 -98
  331. package/docs/examples/time/base.vue +67 -67
  332. package/docs/examples/title/basic.vue +87 -87
  333. package/docs/examples/tree/accordion.vue +46 -46
  334. package/docs/examples/tree/basic.vue +50 -50
  335. package/docs/examples/tree/buttons.vue +53 -53
  336. package/docs/examples/tree/checkable.vue +52 -52
  337. package/docs/examples/tree/custom-keys.vue +39 -39
  338. package/docs/examples/tree/default-expanded.vue +52 -52
  339. package/docs/examples/tree/draggable.vue +29 -29
  340. package/docs/examples/tree/expand-on-click.vue +39 -39
  341. package/docs/examples/tree/flat-data.vue +20 -20
  342. package/docs/examples/tree/icon.vue +40 -40
  343. package/docs/examples/tree/load-data.vue +37 -37
  344. package/docs/examples/tree/methods.vue +74 -74
  345. package/docs/examples/tree/theme.vue +33 -33
  346. package/docs/examples/tree-select/basic.vue +47 -47
  347. package/docs/examples/upload/accept.vue +31 -31
  348. package/docs/examples/upload/basic.vue +12 -12
  349. package/docs/examples/upload/drag.vue +11 -11
  350. package/docs/examples/upload/image.vue +17 -17
  351. package/docs/examples/upload/limit.vue +20 -20
  352. package/docs/examples/upload/multiple.vue +17 -17
  353. package/docs/examples/upload/readonly.vue +17 -17
  354. package/docs/examples/utils/cipher.vue +160 -160
  355. package/docs/examples/utils/common.vue +153 -153
  356. package/docs/examples/utils/date.vue +56 -56
  357. package/docs/examples/utils/dom.vue +52 -52
  358. package/docs/examples/utils/is.vue +70 -70
  359. package/docs/examples/workflow/basic.vue +265 -265
  360. package/docs/examples/workflow-viewer/basic.vue +248 -248
  361. package/package.json +23 -23
@@ -1,453 +1,453 @@
1
- <template>
2
- <div class="j-block j-user-center-log" style="height: 600px">
3
- <j-page :noPadding="true" :schema="schema" />
4
- </div>
5
- </template>
6
- <script lang="ts" setup>
7
- import type { TableColumnCompConfig, ColumnSchemaConfig, LayerParamType } from '@a2simcode/ui'
8
-
9
- import { ref, h, defineComponent, resolveComponent } from 'vue'
10
- import { iconLoaded, loadIcon } from '@iconify/vue'
11
-
12
- const ExecuteResultLayer = defineComponent({
13
- name: 'ExecuteResultLayer',
14
- props: {
15
- text: {
16
- type: String,
17
- default: '',
18
- },
19
- },
20
- setup(props) {
21
- const JCodeMirror = resolveComponent('j-code-mirror')
22
- return () =>
23
- h(JCodeMirror, {
24
- readOnly: true,
25
- value: props.text || '',
26
- })
27
- },
28
- })
29
-
30
- const browsers = [
31
- { name: 'Chrome', icon: 'logos:chrome' },
32
- { name: 'Firefox', icon: 'logos:firefox' },
33
- { name: 'Safari', icon: 'logos:safari' },
34
- { name: 'Edge', icon: 'logos:microsoft-edge' },
35
- ]
36
-
37
- interface ColumnType {
38
- label: string
39
- id: string
40
- }
41
-
42
- const columns: ColumnType[] = [
43
- { label: '浏览器', id: 'j_BrowserTag' },
44
- {
45
- label: '类型',
46
- id: 'j_CategoryId',
47
- },
48
- { label: '时间', id: 'j_CreateDate' },
49
- { label: '时长(ms)', id: 'j_Times' },
50
- { label: '请求接口', id: 'j_Url' },
51
- { label: '请求类型', id: 'j_OperateType' },
52
- { label: 'IP', id: 'j_IPAddress' },
53
- { label: '结果', id: 'j_Result' },
54
- { label: '描述', id: 'j_ExecuteResult' },
55
- ]
56
-
57
- const columnsConfig: Record<string, TableColumnCompConfig> = {
58
- j_BrowserTag: {
59
- width: 72,
60
- type: 'j-icon',
61
- align: 'center',
62
- dataType: 'options',
63
- fieldFormat: (row: Record<string, any>) =>
64
- browsers.find((b) => b.name === row.j_BrowserTag)?.icon || '',
65
- options: browsers.map((b) => ({ label: b.name, value: b.name })),
66
- },
67
- j_CategoryId: {
68
- type: 'j-tag',
69
- width: 100,
70
- align: 'center',
71
- dataType: 'options',
72
- options: [
73
- { label: '登录', value: 1, color: '#e8ffea' },
74
- { label: '访问', value: 2, color: '#e8f3ff' },
75
- { label: '操作', value: 3, color: '#e5f9f8' },
76
- { label: '文件下载', value: 5, color: '#fff7e8' },
77
- { label: '文件预览', value: 6, color: '#f5f2ff' },
78
- { label: '接口请求', value: 7, color: '#f0f5ff' },
79
- { label: '接口限流', value: 8, color: '#fffce8' },
80
- { label: '接口熔断', value: 9, color: '#fff2e8' },
81
- { label: '异常', value: 4, color: '#ffece8' },
82
- ],
83
- },
84
- j_CreateDate: {
85
- width: 168,
86
- type: 'dateTime',
87
- },
88
- j_Times: {
89
- width: 80,
90
- align: 'center',
91
- type: 'number',
92
- },
93
- j_Url: {
94
- width: 200,
95
- isSearchKeyword: true,
96
- },
97
- j_OperateType: {
98
- width: 96,
99
- align: 'center',
100
- type: 'j-tag',
101
- dataType: 'options',
102
- options: [
103
- { label: 'GET', value: 'GET', color: '#e8f3ff' },
104
- { label: 'POST', value: 'POST', color: '#e8ffea' },
105
- { label: 'PUT', value: 'PUT', color: '#fff7e8' },
106
- { label: 'DELETE', value: 'DELETE', color: '#ffece8' },
107
- ],
108
- },
109
-
110
- j_IPAddress: {
111
- width: 120,
112
- isSearchKeyword: true,
113
- },
114
- j_Result: {
115
- type: 'j-tag',
116
- width: 72,
117
- align: 'center',
118
- dataType: 'options',
119
- fieldFormat: (row: Record<string, any>) => (row.j_Result === 1 ? 1 : 2),
120
- options: [
121
- { label: '成功', value: 1, color: '#e8ffea' },
122
- { label: '失败', value: 2, color: '#ffece8' },
123
- ],
124
- },
125
- j_ExecuteResult: {
126
- type: 'link',
127
- width: 60,
128
- align: 'center',
129
- frozen: 'right',
130
- fieldFormat: () => '查看',
131
- click: ({ row, openLayer }: { row: any; openLayer: (params: LayerParamType) => void }) => {
132
- openLayer({
133
- title: '描述',
134
- name: ExecuteResultLayer,
135
- config: { text: row?.j_ExecuteResult || '' },
136
- width: 1000,
137
- height: 600,
138
- hasBtns: false,
139
- })
140
- },
141
- },
142
- }
143
-
144
- const myColumns: ColumnSchemaConfig[] = []
145
- columns.forEach((item) => {
146
- const config = columnsConfig[item.id || ''] || {}
147
- const schemaItem: ColumnSchemaConfig = {
148
- id: item.id || '',
149
- type: config.type || '',
150
- config: { ...config, label: item.label || '' },
151
- }
152
- myColumns.push(schemaItem)
153
- })
154
-
155
- // Mock API
156
- const mockData = Array.from({ length: 100 }).map((_, i) => ({
157
- j_Id: i + 1,
158
- j_BrowserTag: browsers[i % browsers.length].name,
159
- j_CategoryId: (i % 9) + 1,
160
- j_CreateDate: new Date(Date.now() - Math.floor(Math.random() * 1000000000)).toISOString(),
161
- j_Times: Math.floor(Math.random() * 1000),
162
- j_Url: `/api/v1/resource/${i}`,
163
- j_OperateType: ['GET', 'POST', 'PUT', 'DELETE'][i % 4],
164
- j_IPAddress: `192.168.1.${i}`,
165
- j_Result: i % 5 === 0 ? 2 : 1,
166
- j_ExecuteResult: JSON.stringify({ status: 200, message: 'Success' }),
167
- }))
168
-
169
- const api = {
170
- getMyPage: async (params: any) => {
171
- console.log(JSON.stringify(params), 'params')
172
- // Simulate API call
173
- await new Promise((resolve) => setTimeout(resolve, 300))
174
-
175
- let result = [...mockData]
176
-
177
- // Filter
178
- if (params.filter && params.filter.cond && params.filter.cond.length > 0) {
179
- const { rel, cond } = params.filter
180
- const parseDateVal = (s: string) => {
181
- if (!s) return NaN
182
- const str = s.includes('T') ? s : s.replace(' ', 'T')
183
- const d = new Date(str)
184
- return d.getTime()
185
- }
186
- const dayStart = (d: Date) =>
187
- new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0).getTime()
188
- const dayEnd = (d: Date) =>
189
- new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999).getTime()
190
- const monthStart = (y: number, m: number) => new Date(y, m, 1, 0, 0, 0, 0).getTime()
191
- const monthEnd = (y: number, m: number) => new Date(y, m + 1, 0, 23, 59, 59, 999).getTime()
192
- const quarterRange = (y: number, q: number) => {
193
- const startMonth = (q - 1) * 3
194
- const start = monthStart(y, startMonth)
195
- const end = monthEnd(y, startMonth + 2)
196
- return [start, end] as const
197
- }
198
- const weekStartEnd = (d: Date) => {
199
- const dow = (d.getDay() + 6) % 7
200
- const startD = new Date(d)
201
- startD.setDate(d.getDate() - dow)
202
- const endD = new Date(startD)
203
- endD.setDate(startD.getDate() + 6)
204
- return [dayStart(startD), dayEnd(endD)] as const
205
- }
206
- const rangeFromFormula = (f: string) => {
207
- const now = new Date()
208
- if (f === 'today') return [dayStart(now), dayEnd(now)] as const
209
- if (f === 'yesterday') {
210
- const d = new Date(now)
211
- d.setDate(now.getDate() - 1)
212
- return [dayStart(d), dayEnd(d)] as const
213
- }
214
- if (f === 'tomorrow') {
215
- const d = new Date(now)
216
- d.setDate(now.getDate() + 1)
217
- return [dayStart(d), dayEnd(d)] as const
218
- }
219
- if (f === 'last7days') {
220
- const end = dayEnd(now)
221
- const d = new Date(now)
222
- d.setDate(now.getDate() - 6)
223
- const start = dayStart(d)
224
- return [start, end] as const
225
- }
226
- if (f === 'last30days') {
227
- const end = dayEnd(now)
228
- const d = new Date(now)
229
- d.setDate(now.getDate() - 29)
230
- const start = dayStart(d)
231
- return [start, end] as const
232
- }
233
- if (f === 'thisWeek') return weekStartEnd(now)
234
- if (f === 'lastWeek') {
235
- const d = new Date(now)
236
- d.setDate(now.getDate() - 7)
237
- return weekStartEnd(d)
238
- }
239
- if (f === 'nextWeek') {
240
- const d = new Date(now)
241
- d.setDate(now.getDate() + 7)
242
- return weekStartEnd(d)
243
- }
244
- if (f === 'thisMonth') {
245
- const y = now.getFullYear()
246
- const m = now.getMonth()
247
- return [monthStart(y, m), monthEnd(y, m)] as const
248
- }
249
- if (f === 'lastMonth') {
250
- const d = new Date(now)
251
- d.setMonth(now.getMonth() - 1)
252
- const y = d.getFullYear()
253
- const m = d.getMonth()
254
- return [monthStart(y, m), monthEnd(y, m)] as const
255
- }
256
- if (f === 'nextMonth') {
257
- const d = new Date(now)
258
- d.setMonth(now.getMonth() + 1)
259
- const y = d.getFullYear()
260
- const m = d.getMonth()
261
- return [monthStart(y, m), monthEnd(y, m)] as const
262
- }
263
- if (f === 'thisQuarter') {
264
- const y = now.getFullYear()
265
- const q = Math.floor(now.getMonth() / 3) + 1
266
- return quarterRange(y, q)
267
- }
268
- if (f === 'lastQuarter') {
269
- let y = now.getFullYear()
270
- let q = Math.floor(now.getMonth() / 3)
271
- if (q === 0) {
272
- q = 4
273
- y = y - 1
274
- }
275
- return quarterRange(y, q)
276
- }
277
- if (f === 'nextQuarter') {
278
- let y = now.getFullYear()
279
- let q = Math.floor(now.getMonth() / 3) + 2
280
- if (q === 5) {
281
- q = 1
282
- y = y + 1
283
- }
284
- return quarterRange(y, q)
285
- }
286
- if (f === 'thisYear') {
287
- const y = now.getFullYear()
288
- return [
289
- new Date(y, 0, 1).getTime(),
290
- new Date(y, 11, 31, 23, 59, 59, 999).getTime(),
291
- ] as const
292
- }
293
- if (f === 'lastYear') {
294
- const y = now.getFullYear() - 1
295
- return [
296
- new Date(y, 0, 1).getTime(),
297
- new Date(y, 11, 31, 23, 59, 59, 999).getTime(),
298
- ] as const
299
- }
300
- if (f === 'nextYear') {
301
- const y = now.getFullYear() + 1
302
- return [
303
- new Date(y, 0, 1).getTime(),
304
- new Date(y, 11, 31, 23, 59, 59, 999).getTime(),
305
- ] as const
306
- }
307
- return [NaN, NaN] as const
308
- }
309
- result = result.filter((item) => {
310
- const matches = cond.map((c: any) => {
311
- const rawVal = item[c.field as keyof typeof item]
312
- const val = rawVal == null ? '' : String(rawVal)
313
- const target = c.value == null ? '' : String(c.value)
314
-
315
- if (c.type === 'dateTime') {
316
- const ts = parseDateVal(val)
317
- if (c.method === 'eq') {
318
- const t = parseDateVal(target)
319
- return ts === t
320
- } else if (c.method === 'ne') {
321
- const t = parseDateVal(target)
322
- return ts !== t
323
- } else if (c.method === 'gte') {
324
- const t = parseDateVal(target)
325
- return ts >= t
326
- } else if (c.method === 'lte') {
327
- const t = parseDateVal(target)
328
- return ts <= t
329
- } else if (c.method === 'range') {
330
- if (!target) return true
331
- const [s, e] = target.split(',')
332
- const st = parseDateVal(s)
333
- const et = parseDateVal(e)
334
- if (isNaN(st) && isNaN(et)) return true
335
- if (!isNaN(st) && !isNaN(et)) return ts >= st && ts <= et
336
- if (!isNaN(st) && isNaN(et)) return ts >= st
337
- if (isNaN(st) && !isNaN(et)) return ts <= et
338
- return true
339
- } else if (c.method === 'formula') {
340
- const [st, et] = rangeFromFormula(target)
341
- if (isNaN(st) || isNaN(et)) return true
342
- return ts >= st && ts <= et
343
- } else if (c.method === 'not_empty') {
344
- return val !== '' && val !== 'null' && val !== 'undefined'
345
- } else if (c.method === 'empty') {
346
- return val === '' || val === 'null' || val === 'undefined'
347
- }
348
- return false
349
- } else {
350
- if (
351
- c.method === 'gt' ||
352
- c.method === 'gte' ||
353
- c.method === 'lt' ||
354
- c.method === 'lte'
355
- ) {
356
- const nVal = Number(val)
357
- const nTarget = Number(target)
358
- if (isNaN(nVal) || isNaN(nTarget)) return false
359
- if (c.method === 'gt') return nVal > nTarget
360
- if (c.method === 'gte') return nVal >= nTarget
361
- if (c.method === 'lt') return nVal < nTarget
362
- if (c.method === 'lte') return nVal <= nTarget
363
- }
364
- if (c.method === 'eq') {
365
- return val === target
366
- } else if (c.method === 'ne') {
367
- return val !== target
368
- } else if (c.method === 'like') {
369
- return val.includes(target)
370
- } else if (c.method === 'unlike') {
371
- return !val.includes(target)
372
- } else if (c.method === 'in') {
373
- const targetList = target.split(',')
374
- return targetList.includes(val)
375
- } else if (c.method === 'nin') {
376
- const targetList = target.split(',')
377
- return !targetList.includes(val)
378
- } else if (c.method === 'not_empty') {
379
- return val !== '' && val !== 'null' && val !== 'undefined'
380
- } else if (c.method === 'empty') {
381
- return val === '' || val === 'null' || val === 'undefined'
382
- }
383
- }
384
- return false
385
- })
386
-
387
- if (rel === 'and') return matches.every((x: boolean) => x)
388
- if (rel === 'or') return matches.some((x: boolean) => x)
389
- return true
390
- })
391
- }
392
-
393
- // Sort
394
- if (params.pagination && params.pagination.sort) {
395
- const [field, order] = params.pagination.sort.split(' ')
396
- result.sort((a, b) => {
397
- const valA = a[field as keyof typeof a]
398
- const valB = b[field as keyof typeof b]
399
- if (valA < valB) return order === 'ASC' ? -1 : 1
400
- if (valA > valB) return order === 'ASC' ? 1 : -1
401
- return 0
402
- })
403
- }
404
-
405
- // Pagination
406
- const page = params.pagination?.page || 1
407
- const rows = params.pagination?.rows || 20
408
- const start = (page - 1) * rows
409
- const end = start + rows
410
-
411
- return {
412
- total: result.length,
413
- rows: result.slice(start, end),
414
- }
415
- },
416
- }
417
-
418
- const schema = [
419
- {
420
- id: 'mainTable',
421
- type: 'j-table-panel',
422
- config: {
423
- columns: myColumns,
424
- rowKey: 'j_Id',
425
- sort: 'j_CreateDate DESC',
426
- isPage: true,
427
- loadData: async (params: Record<string, any>) => {
428
- let res = await api.getMyPage(params)
429
- if (res && res.rows) {
430
- const iconsToLoad = new Set()
431
- res.rows.forEach((item: any) => {
432
- const browser = browsers.find((b) => item.j_BrowserTag && item.j_BrowserTag === b.name)
433
- if (browser) {
434
- iconsToLoad.add(browser.icon)
435
- }
436
- })
437
-
438
- await Promise.all(
439
- [...iconsToLoad].map(async (icon) => {
440
- if (!iconLoaded(icon as string)) {
441
- await loadIcon(icon as string)
442
- }
443
- })
444
- )
445
- }
446
-
447
- console.log(res, 'res')
448
- return res
449
- },
450
- },
451
- },
452
- ]
453
- </script>
1
+ <template>
2
+ <div class="j-block j-user-center-log" style="height: 600px">
3
+ <j-page :noPadding="true" :schema="schema" />
4
+ </div>
5
+ </template>
6
+ <script lang="ts" setup>
7
+ import type { TableColumnCompConfig, ColumnSchemaConfig, LayerParamType } from '@a2simcode/ui'
8
+
9
+ import { ref, h, defineComponent, resolveComponent } from 'vue'
10
+ import { iconLoaded, loadIcon } from '@iconify/vue'
11
+
12
+ const ExecuteResultLayer = defineComponent({
13
+ name: 'ExecuteResultLayer',
14
+ props: {
15
+ text: {
16
+ type: String,
17
+ default: '',
18
+ },
19
+ },
20
+ setup(props) {
21
+ const JCodeMirror = resolveComponent('j-code-mirror')
22
+ return () =>
23
+ h(JCodeMirror, {
24
+ readOnly: true,
25
+ value: props.text || '',
26
+ })
27
+ },
28
+ })
29
+
30
+ const browsers = [
31
+ { name: 'Chrome', icon: 'logos:chrome' },
32
+ { name: 'Firefox', icon: 'logos:firefox' },
33
+ { name: 'Safari', icon: 'logos:safari' },
34
+ { name: 'Edge', icon: 'logos:microsoft-edge' },
35
+ ]
36
+
37
+ interface ColumnType {
38
+ label: string
39
+ id: string
40
+ }
41
+
42
+ const columns: ColumnType[] = [
43
+ { label: '浏览器', id: 'j_BrowserTag' },
44
+ {
45
+ label: '类型',
46
+ id: 'j_CategoryId',
47
+ },
48
+ { label: '时间', id: 'j_CreateDate' },
49
+ { label: '时长(ms)', id: 'j_Times' },
50
+ { label: '请求接口', id: 'j_Url' },
51
+ { label: '请求类型', id: 'j_OperateType' },
52
+ { label: 'IP', id: 'j_IPAddress' },
53
+ { label: '结果', id: 'j_Result' },
54
+ { label: '描述', id: 'j_ExecuteResult' },
55
+ ]
56
+
57
+ const columnsConfig: Record<string, TableColumnCompConfig> = {
58
+ j_BrowserTag: {
59
+ width: 72,
60
+ type: 'j-icon',
61
+ align: 'center',
62
+ dataType: 'options',
63
+ fieldFormat: (row: Record<string, any>) =>
64
+ browsers.find((b) => b.name === row.j_BrowserTag)?.icon || '',
65
+ options: browsers.map((b) => ({ label: b.name, value: b.name })),
66
+ },
67
+ j_CategoryId: {
68
+ type: 'j-tag',
69
+ width: 100,
70
+ align: 'center',
71
+ dataType: 'options',
72
+ options: [
73
+ { label: '登录', value: 1, color: '#e8ffea' },
74
+ { label: '访问', value: 2, color: '#e8f3ff' },
75
+ { label: '操作', value: 3, color: '#e5f9f8' },
76
+ { label: '文件下载', value: 5, color: '#fff7e8' },
77
+ { label: '文件预览', value: 6, color: '#f5f2ff' },
78
+ { label: '接口请求', value: 7, color: '#f0f5ff' },
79
+ { label: '接口限流', value: 8, color: '#fffce8' },
80
+ { label: '接口熔断', value: 9, color: '#fff2e8' },
81
+ { label: '异常', value: 4, color: '#ffece8' },
82
+ ],
83
+ },
84
+ j_CreateDate: {
85
+ width: 168,
86
+ type: 'dateTime',
87
+ },
88
+ j_Times: {
89
+ width: 80,
90
+ align: 'center',
91
+ type: 'number',
92
+ },
93
+ j_Url: {
94
+ width: 200,
95
+ isSearchKeyword: true,
96
+ },
97
+ j_OperateType: {
98
+ width: 96,
99
+ align: 'center',
100
+ type: 'j-tag',
101
+ dataType: 'options',
102
+ options: [
103
+ { label: 'GET', value: 'GET', color: '#e8f3ff' },
104
+ { label: 'POST', value: 'POST', color: '#e8ffea' },
105
+ { label: 'PUT', value: 'PUT', color: '#fff7e8' },
106
+ { label: 'DELETE', value: 'DELETE', color: '#ffece8' },
107
+ ],
108
+ },
109
+
110
+ j_IPAddress: {
111
+ width: 120,
112
+ isSearchKeyword: true,
113
+ },
114
+ j_Result: {
115
+ type: 'j-tag',
116
+ width: 72,
117
+ align: 'center',
118
+ dataType: 'options',
119
+ fieldFormat: (row: Record<string, any>) => (row.j_Result === 1 ? 1 : 2),
120
+ options: [
121
+ { label: '成功', value: 1, color: '#e8ffea' },
122
+ { label: '失败', value: 2, color: '#ffece8' },
123
+ ],
124
+ },
125
+ j_ExecuteResult: {
126
+ type: 'link',
127
+ width: 60,
128
+ align: 'center',
129
+ frozen: 'right',
130
+ fieldFormat: () => '查看',
131
+ click: ({ row, openLayer }: { row: any; openLayer: (params: LayerParamType) => void }) => {
132
+ openLayer({
133
+ title: '描述',
134
+ name: ExecuteResultLayer,
135
+ config: { text: row?.j_ExecuteResult || '' },
136
+ width: 1000,
137
+ height: 600,
138
+ hasBtns: false,
139
+ })
140
+ },
141
+ },
142
+ }
143
+
144
+ const myColumns: ColumnSchemaConfig[] = []
145
+ columns.forEach((item) => {
146
+ const config = columnsConfig[item.id || ''] || {}
147
+ const schemaItem: ColumnSchemaConfig = {
148
+ id: item.id || '',
149
+ type: config.type || '',
150
+ config: { ...config, label: item.label || '' },
151
+ }
152
+ myColumns.push(schemaItem)
153
+ })
154
+
155
+ // Mock API
156
+ const mockData = Array.from({ length: 100 }).map((_, i) => ({
157
+ j_Id: i + 1,
158
+ j_BrowserTag: browsers[i % browsers.length].name,
159
+ j_CategoryId: (i % 9) + 1,
160
+ j_CreateDate: new Date(Date.now() - Math.floor(Math.random() * 1000000000)).toISOString(),
161
+ j_Times: Math.floor(Math.random() * 1000),
162
+ j_Url: `/api/v1/resource/${i}`,
163
+ j_OperateType: ['GET', 'POST', 'PUT', 'DELETE'][i % 4],
164
+ j_IPAddress: `192.168.1.${i}`,
165
+ j_Result: i % 5 === 0 ? 2 : 1,
166
+ j_ExecuteResult: JSON.stringify({ status: 200, message: 'Success' }),
167
+ }))
168
+
169
+ const api = {
170
+ getMyPage: async (params: any) => {
171
+ console.log(JSON.stringify(params), 'params')
172
+ // Simulate API call
173
+ await new Promise((resolve) => setTimeout(resolve, 300))
174
+
175
+ let result = [...mockData]
176
+
177
+ // Filter
178
+ if (params.filter && params.filter.cond && params.filter.cond.length > 0) {
179
+ const { rel, cond } = params.filter
180
+ const parseDateVal = (s: string) => {
181
+ if (!s) return NaN
182
+ const str = s.includes('T') ? s : s.replace(' ', 'T')
183
+ const d = new Date(str)
184
+ return d.getTime()
185
+ }
186
+ const dayStart = (d: Date) =>
187
+ new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0).getTime()
188
+ const dayEnd = (d: Date) =>
189
+ new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999).getTime()
190
+ const monthStart = (y: number, m: number) => new Date(y, m, 1, 0, 0, 0, 0).getTime()
191
+ const monthEnd = (y: number, m: number) => new Date(y, m + 1, 0, 23, 59, 59, 999).getTime()
192
+ const quarterRange = (y: number, q: number) => {
193
+ const startMonth = (q - 1) * 3
194
+ const start = monthStart(y, startMonth)
195
+ const end = monthEnd(y, startMonth + 2)
196
+ return [start, end] as const
197
+ }
198
+ const weekStartEnd = (d: Date) => {
199
+ const dow = (d.getDay() + 6) % 7
200
+ const startD = new Date(d)
201
+ startD.setDate(d.getDate() - dow)
202
+ const endD = new Date(startD)
203
+ endD.setDate(startD.getDate() + 6)
204
+ return [dayStart(startD), dayEnd(endD)] as const
205
+ }
206
+ const rangeFromFormula = (f: string) => {
207
+ const now = new Date()
208
+ if (f === 'today') return [dayStart(now), dayEnd(now)] as const
209
+ if (f === 'yesterday') {
210
+ const d = new Date(now)
211
+ d.setDate(now.getDate() - 1)
212
+ return [dayStart(d), dayEnd(d)] as const
213
+ }
214
+ if (f === 'tomorrow') {
215
+ const d = new Date(now)
216
+ d.setDate(now.getDate() + 1)
217
+ return [dayStart(d), dayEnd(d)] as const
218
+ }
219
+ if (f === 'last7days') {
220
+ const end = dayEnd(now)
221
+ const d = new Date(now)
222
+ d.setDate(now.getDate() - 6)
223
+ const start = dayStart(d)
224
+ return [start, end] as const
225
+ }
226
+ if (f === 'last30days') {
227
+ const end = dayEnd(now)
228
+ const d = new Date(now)
229
+ d.setDate(now.getDate() - 29)
230
+ const start = dayStart(d)
231
+ return [start, end] as const
232
+ }
233
+ if (f === 'thisWeek') return weekStartEnd(now)
234
+ if (f === 'lastWeek') {
235
+ const d = new Date(now)
236
+ d.setDate(now.getDate() - 7)
237
+ return weekStartEnd(d)
238
+ }
239
+ if (f === 'nextWeek') {
240
+ const d = new Date(now)
241
+ d.setDate(now.getDate() + 7)
242
+ return weekStartEnd(d)
243
+ }
244
+ if (f === 'thisMonth') {
245
+ const y = now.getFullYear()
246
+ const m = now.getMonth()
247
+ return [monthStart(y, m), monthEnd(y, m)] as const
248
+ }
249
+ if (f === 'lastMonth') {
250
+ const d = new Date(now)
251
+ d.setMonth(now.getMonth() - 1)
252
+ const y = d.getFullYear()
253
+ const m = d.getMonth()
254
+ return [monthStart(y, m), monthEnd(y, m)] as const
255
+ }
256
+ if (f === 'nextMonth') {
257
+ const d = new Date(now)
258
+ d.setMonth(now.getMonth() + 1)
259
+ const y = d.getFullYear()
260
+ const m = d.getMonth()
261
+ return [monthStart(y, m), monthEnd(y, m)] as const
262
+ }
263
+ if (f === 'thisQuarter') {
264
+ const y = now.getFullYear()
265
+ const q = Math.floor(now.getMonth() / 3) + 1
266
+ return quarterRange(y, q)
267
+ }
268
+ if (f === 'lastQuarter') {
269
+ let y = now.getFullYear()
270
+ let q = Math.floor(now.getMonth() / 3)
271
+ if (q === 0) {
272
+ q = 4
273
+ y = y - 1
274
+ }
275
+ return quarterRange(y, q)
276
+ }
277
+ if (f === 'nextQuarter') {
278
+ let y = now.getFullYear()
279
+ let q = Math.floor(now.getMonth() / 3) + 2
280
+ if (q === 5) {
281
+ q = 1
282
+ y = y + 1
283
+ }
284
+ return quarterRange(y, q)
285
+ }
286
+ if (f === 'thisYear') {
287
+ const y = now.getFullYear()
288
+ return [
289
+ new Date(y, 0, 1).getTime(),
290
+ new Date(y, 11, 31, 23, 59, 59, 999).getTime(),
291
+ ] as const
292
+ }
293
+ if (f === 'lastYear') {
294
+ const y = now.getFullYear() - 1
295
+ return [
296
+ new Date(y, 0, 1).getTime(),
297
+ new Date(y, 11, 31, 23, 59, 59, 999).getTime(),
298
+ ] as const
299
+ }
300
+ if (f === 'nextYear') {
301
+ const y = now.getFullYear() + 1
302
+ return [
303
+ new Date(y, 0, 1).getTime(),
304
+ new Date(y, 11, 31, 23, 59, 59, 999).getTime(),
305
+ ] as const
306
+ }
307
+ return [NaN, NaN] as const
308
+ }
309
+ result = result.filter((item) => {
310
+ const matches = cond.map((c: any) => {
311
+ const rawVal = item[c.field as keyof typeof item]
312
+ const val = rawVal == null ? '' : String(rawVal)
313
+ const target = c.value == null ? '' : String(c.value)
314
+
315
+ if (c.type === 'dateTime') {
316
+ const ts = parseDateVal(val)
317
+ if (c.method === 'eq') {
318
+ const t = parseDateVal(target)
319
+ return ts === t
320
+ } else if (c.method === 'ne') {
321
+ const t = parseDateVal(target)
322
+ return ts !== t
323
+ } else if (c.method === 'gte') {
324
+ const t = parseDateVal(target)
325
+ return ts >= t
326
+ } else if (c.method === 'lte') {
327
+ const t = parseDateVal(target)
328
+ return ts <= t
329
+ } else if (c.method === 'range') {
330
+ if (!target) return true
331
+ const [s, e] = target.split(',')
332
+ const st = parseDateVal(s)
333
+ const et = parseDateVal(e)
334
+ if (isNaN(st) && isNaN(et)) return true
335
+ if (!isNaN(st) && !isNaN(et)) return ts >= st && ts <= et
336
+ if (!isNaN(st) && isNaN(et)) return ts >= st
337
+ if (isNaN(st) && !isNaN(et)) return ts <= et
338
+ return true
339
+ } else if (c.method === 'formula') {
340
+ const [st, et] = rangeFromFormula(target)
341
+ if (isNaN(st) || isNaN(et)) return true
342
+ return ts >= st && ts <= et
343
+ } else if (c.method === 'not_empty') {
344
+ return val !== '' && val !== 'null' && val !== 'undefined'
345
+ } else if (c.method === 'empty') {
346
+ return val === '' || val === 'null' || val === 'undefined'
347
+ }
348
+ return false
349
+ } else {
350
+ if (
351
+ c.method === 'gt' ||
352
+ c.method === 'gte' ||
353
+ c.method === 'lt' ||
354
+ c.method === 'lte'
355
+ ) {
356
+ const nVal = Number(val)
357
+ const nTarget = Number(target)
358
+ if (isNaN(nVal) || isNaN(nTarget)) return false
359
+ if (c.method === 'gt') return nVal > nTarget
360
+ if (c.method === 'gte') return nVal >= nTarget
361
+ if (c.method === 'lt') return nVal < nTarget
362
+ if (c.method === 'lte') return nVal <= nTarget
363
+ }
364
+ if (c.method === 'eq') {
365
+ return val === target
366
+ } else if (c.method === 'ne') {
367
+ return val !== target
368
+ } else if (c.method === 'like') {
369
+ return val.includes(target)
370
+ } else if (c.method === 'unlike') {
371
+ return !val.includes(target)
372
+ } else if (c.method === 'in') {
373
+ const targetList = target.split(',')
374
+ return targetList.includes(val)
375
+ } else if (c.method === 'nin') {
376
+ const targetList = target.split(',')
377
+ return !targetList.includes(val)
378
+ } else if (c.method === 'not_empty') {
379
+ return val !== '' && val !== 'null' && val !== 'undefined'
380
+ } else if (c.method === 'empty') {
381
+ return val === '' || val === 'null' || val === 'undefined'
382
+ }
383
+ }
384
+ return false
385
+ })
386
+
387
+ if (rel === 'and') return matches.every((x: boolean) => x)
388
+ if (rel === 'or') return matches.some((x: boolean) => x)
389
+ return true
390
+ })
391
+ }
392
+
393
+ // Sort
394
+ if (params.pagination && params.pagination.sort) {
395
+ const [field, order] = params.pagination.sort.split(' ')
396
+ result.sort((a, b) => {
397
+ const valA = a[field as keyof typeof a]
398
+ const valB = b[field as keyof typeof b]
399
+ if (valA < valB) return order === 'ASC' ? -1 : 1
400
+ if (valA > valB) return order === 'ASC' ? 1 : -1
401
+ return 0
402
+ })
403
+ }
404
+
405
+ // Pagination
406
+ const page = params.pagination?.page || 1
407
+ const rows = params.pagination?.rows || 20
408
+ const start = (page - 1) * rows
409
+ const end = start + rows
410
+
411
+ return {
412
+ total: result.length,
413
+ rows: result.slice(start, end),
414
+ }
415
+ },
416
+ }
417
+
418
+ const schema = [
419
+ {
420
+ id: 'mainTable',
421
+ type: 'j-table-panel',
422
+ config: {
423
+ columns: myColumns,
424
+ rowKey: 'j_Id',
425
+ sort: 'j_CreateDate DESC',
426
+ isPage: true,
427
+ loadData: async (params: Record<string, any>) => {
428
+ let res = await api.getMyPage(params)
429
+ if (res && res.rows) {
430
+ const iconsToLoad = new Set()
431
+ res.rows.forEach((item: any) => {
432
+ const browser = browsers.find((b) => item.j_BrowserTag && item.j_BrowserTag === b.name)
433
+ if (browser) {
434
+ iconsToLoad.add(browser.icon)
435
+ }
436
+ })
437
+
438
+ await Promise.all(
439
+ [...iconsToLoad].map(async (icon) => {
440
+ if (!iconLoaded(icon as string)) {
441
+ await loadIcon(icon as string)
442
+ }
443
+ })
444
+ )
445
+ }
446
+
447
+ console.log(res, 'res')
448
+ return res
449
+ },
450
+ },
451
+ },
452
+ ]
453
+ </script>