vome-core 0.3.10 → 0.3.11

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 (120) hide show
  1. package/dist/admin/api/client.js +9 -8
  2. package/dist/admin/components/ui/avatar/index.js +1 -1
  3. package/dist/admin/components/ui/badge/index.d.ts +1 -1
  4. package/dist/admin/components/ui/button/index.d.ts +1 -1
  5. package/dist/admin/components/ui/checkbox/index.js +1 -1
  6. package/dist/admin/components/ui/dialog/index.js +1 -1
  7. package/dist/admin/components/ui/dropdown-menu/index.js +1 -1
  8. package/dist/admin/components/ui/input/Input.vue +2 -1
  9. package/dist/admin/components/ui/input/index.js +1 -1
  10. package/dist/admin/components/ui/label/index.js +1 -1
  11. package/dist/admin/components/ui/scroll-area/index.js +1 -1
  12. package/dist/admin/components/ui/select/index.js +1 -1
  13. package/dist/admin/components/ui/separator/index.js +1 -1
  14. package/dist/admin/components/ui/sheet/index.js +1 -1
  15. package/dist/admin/components/ui/sonner/index.js +1 -1
  16. package/dist/admin/components/ui/table/index.js +1 -1
  17. package/dist/admin/components/ui/tabs/index.js +1 -1
  18. package/dist/admin/components/ui/tooltip/index.js +1 -1
  19. package/dist/admin/components/vm-aside.vue +8 -6
  20. package/dist/admin/components/vm-auto-perm-dialog.vue +12 -11
  21. package/dist/admin/components/vm-check-tree.vue +3 -2
  22. package/dist/admin/components/vm-dept-tree.vue +29 -28
  23. package/dist/admin/components/vm-empty.vue +16 -2
  24. package/dist/admin/components/vm-eps-perm-picker.vue +3 -2
  25. package/dist/admin/components/vm-form-dialog.vue +4 -3
  26. package/dist/admin/components/vm-group-cascader.vue +5 -4
  27. package/dist/admin/components/vm-icon-picker.vue +24 -15
  28. package/dist/admin/components/vm-inline-search.vue +3 -2
  29. package/dist/admin/components/vm-loading.vue +4 -3
  30. package/dist/admin/components/vm-markdown.vue +6 -5
  31. package/dist/admin/components/vm-role-picker.vue +6 -5
  32. package/dist/admin/components/vm-view-path-picker.vue +3 -2
  33. package/dist/admin/crud/auto-fields.js +1 -1
  34. package/dist/admin/crud/components/vm-avatar.vue +2 -1
  35. package/dist/admin/crud/components/vm-color-picker.vue +8 -8
  36. package/dist/admin/crud/components/vm-column-custom.vue +6 -5
  37. package/dist/admin/crud/components/vm-copy-btn.vue +4 -3
  38. package/dist/admin/crud/components/vm-date-calendar-panel.vue +30 -27
  39. package/dist/admin/crud/components/vm-date-picker.vue +6 -5
  40. package/dist/admin/crud/components/vm-date-range.vue +5 -4
  41. package/dist/admin/crud/components/vm-datetime-field.vue +4 -3
  42. package/dist/admin/crud/components/vm-json-code.vue +3 -2
  43. package/dist/admin/crud/components/vm-json-editor.vue +3 -2
  44. package/dist/admin/crud/components/vm-json-kv-editor.vue +13 -12
  45. package/dist/admin/crud/components/vm-multi-select.vue +5 -4
  46. package/dist/admin/crud/components/vm-number-range.vue +5 -4
  47. package/dist/admin/crud/components/vm-preview-viewer.vue +33 -29
  48. package/dist/admin/crud/components/vm-richtext-extensions.js +1 -1
  49. package/dist/admin/crud/components/vm-richtext.vue +33 -30
  50. package/dist/admin/crud/components/vm-select.vue +4 -3
  51. package/dist/admin/crud/components/vm-status-tag.vue +2 -1
  52. package/dist/admin/crud/components/vm-switch.vue +5 -4
  53. package/dist/admin/crud/components/vm-text-link.vue +3 -2
  54. package/dist/admin/crud/components/vm-tree-select.vue +3 -2
  55. package/dist/admin/crud/components/vm-upload-item.vue +6 -4
  56. package/dist/admin/crud/components/vm-upload.vue +6 -5
  57. package/dist/admin/crud/config.js +1 -1
  58. package/dist/admin/crud/confirm.js +1 -1
  59. package/dist/admin/crud/crud-page-request.js +1 -1
  60. package/dist/admin/crud/data-i18n.js +1 -1
  61. package/dist/admin/crud/dict.d.ts +1 -1
  62. package/dist/admin/crud/dict.js +1 -1
  63. package/dist/admin/crud/export-fetch.js +1 -1
  64. package/dist/admin/crud/key.js +1 -1
  65. package/dist/admin/crud/plugins.js +1 -1
  66. package/dist/admin/crud/span.js +1 -1
  67. package/dist/admin/crud/style.js +1 -1
  68. package/dist/admin/crud/validate.js +1 -1
  69. package/dist/admin/crud/vm-crud.vue +15 -15
  70. package/dist/admin/crud/vm-data-i18n-btn.vue +1 -1
  71. package/dist/admin/crud/vm-export-btn.vue +7 -7
  72. package/dist/admin/crud/vm-import-btn.vue +33 -27
  73. package/dist/admin/crud/vm-table.vue +7 -2
  74. package/dist/admin/crud/vm-upsert.vue +1 -0
  75. package/dist/admin/directives/perm.js +1 -1
  76. package/dist/admin/hooks/useUpload.js +1 -1
  77. package/dist/admin/lib/browser.js +1 -1
  78. package/dist/admin/lib/cn.js +1 -1
  79. package/dist/admin/lib/dialog-float.js +1 -1
  80. package/dist/admin/lib/export-excel.js +1 -1
  81. package/dist/admin/lib/file-preview.js +8 -6
  82. package/dist/admin/lib/import-excel.js +1 -1
  83. package/dist/admin/lib/json.d.ts +0 -1
  84. package/dist/admin/lib/json.js +1 -1
  85. package/dist/admin/lib/menu.js +1 -1
  86. package/dist/admin/lib/micro-locale.js +1 -1
  87. package/dist/admin/lib/micro-theme.js +1 -1
  88. package/dist/admin/lib/shell.js +1 -1
  89. package/dist/admin/lib/theme-color-options.d.ts +1 -2
  90. package/dist/admin/lib/theme-color-options.js +1 -1
  91. package/dist/admin/lib/tree.js +1 -1
  92. package/dist/admin/lib/upload.d.ts +5 -0
  93. package/dist/admin/lib/upload.js +1 -1
  94. package/dist/admin/lib/video-frame.js +1 -1
  95. package/dist/admin/router/create.js +1 -1
  96. package/dist/admin/router/guards.js +1 -1
  97. package/dist/ai/index.js +1 -1
  98. package/dist/client/ai-model-registry.js +1 -1
  99. package/dist/client/base.js +1 -1
  100. package/dist/client/configure.js +1 -1
  101. package/dist/client/dict.js +1 -1
  102. package/dist/client/eps-payload.js +1 -1
  103. package/dist/client/eps.js +1 -1
  104. package/dist/client/index.js +1 -1
  105. package/dist/client/locale-store.js +1 -1
  106. package/dist/client/service.js +1 -1
  107. package/dist/client/vite-admin.js +1 -1
  108. package/dist/client/vite-auto-import.js +1 -1
  109. package/dist/client/vite-micro-proxy.js +1 -1
  110. package/dist/client/vite-plugin-eps.js +1 -1
  111. package/dist/client/vite-resolve.js +1 -1
  112. package/dist/config/index.js +1 -1
  113. package/dist/index.js +1 -1
  114. package/dist/server/index.js +1 -1
  115. package/dist/shared/datetime-picker.js +1 -1
  116. package/dist/shared/excel.js +1 -1
  117. package/dist/shared/index.js +1 -1
  118. package/dist/shared/locale-json.js +1 -1
  119. package/dist/shared/tree.js +1 -1
  120. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <vm-aside
3
- :title="onlyTrashed ? '部门回收站' : '组织架构'"
3
+ :title="onlyTrashed ? crudLabel('deptTrash') : crudLabel('deptOrg')"
4
4
  :empty="emptyText"
5
5
  :loading="loading"
6
6
  :add="canAdd && !onlyTrashed"
7
- add-title="新增顶级部门"
7
+ :add-title="crudLabel('deptAddRoot')"
8
8
  @refresh="emit('refresh')"
9
9
  @add="openAdd(null)"
10
10
  >
@@ -15,7 +15,7 @@
15
15
  @click="select(null)"
16
16
  >
17
17
  <i class="ri-building-2-line" />
18
- <span>{{ rootLabel }}</span>
18
+ <span>{{ rootLabel ?? crudLabel('all') }}</span>
19
19
  </button>
20
20
 
21
21
  <div
@@ -40,7 +40,7 @@
40
40
  <div v-if="onlyTrashed && canTrashOps" class="vm-dept-tree__ops" @click.stop>
41
41
  <button
42
42
  type="button"
43
- title="恢复"
43
+ :title="crudLabel('restore')"
44
44
  :disabled="trashBusyId === row.id"
45
45
  @click="restoreDept(row)"
46
46
  >
@@ -48,7 +48,7 @@
48
48
  </button>
49
49
  <button
50
50
  type="button"
51
- title="彻底删除"
51
+ :title="crudLabel('forceDelete')"
52
52
  :disabled="trashBusyId === row.id"
53
53
  @click="forceDeleteDept(row)"
54
54
  >
@@ -56,13 +56,13 @@
56
56
  </button>
57
57
  </div>
58
58
  <div v-else-if="!onlyTrashed && canManage" class="vm-dept-tree__ops" @click.stop>
59
- <button v-if="canAdd" type="button" title="新增子部门" @click="openAdd(row.id)">
59
+ <button v-if="canAdd" type="button" :title="crudLabel('deptAddChild')" @click="openAdd(row.id)">
60
60
  <i class="ri-add-line" />
61
61
  </button>
62
- <button v-if="canUpdate" type="button" title="编辑" @click="openEdit(row)">
62
+ <button v-if="canUpdate" type="button" :title="crudLabel('update')" @click="openEdit(row)">
63
63
  <i class="ri-edit-line" />
64
64
  </button>
65
- <button v-if="canDelete" type="button" title="删除" @click="remove(row)">
65
+ <button v-if="canDelete" type="button" :title="crudLabel('delete')" @click="remove(row)">
66
66
  <i class="ri-delete-bin-line" />
67
67
  </button>
68
68
  </div>
@@ -72,7 +72,7 @@
72
72
  <vm-form-dialog
73
73
  v-model:open="formOpen"
74
74
  v-model="formData"
75
- :title="formMode === 'add' ? '新增部门' : '编辑部门'"
75
+ :title="formMode === 'add' ? crudLabel('deptAddTitle') : crudLabel('deptEditTitle')"
76
76
  :items="dialogItems"
77
77
  @submit="onFormSubmit"
78
78
  />
@@ -82,6 +82,7 @@
82
82
  import { ref, computed, watch } from 'vue'
83
83
  import { flattenTree } from '../lib/tree'
84
84
  import { vmConfirm } from '../crud/confirm'
85
+ import { crudFormat, crudLabel } from '../crud/style'
85
86
  import { mergeByProp } from '../crud/auto-fields'
86
87
  import type { CrudFormItem } from '../../../typings/admin/comm/crud'
87
88
  import type { VmFormDialogSubmitHelpers } from './vm-form-dialog.vue'
@@ -137,7 +138,7 @@ const props = withDefaults(
137
138
  data: () => [],
138
139
  loading: false,
139
140
  modelValue: null,
140
- rootLabel: '全部',
141
+ rootLabel: undefined,
141
142
  onlyTrashed: false,
142
143
  canAdd: false,
143
144
  canUpdate: false,
@@ -172,20 +173,20 @@ const canTrashOps = computed(() => props.canRestore || props.canDelete)
172
173
  const builtinFormItems = computed((): CrudFormItem[] => [
173
174
  {
174
175
  prop: 'parentLabel',
175
- label: '上级部门',
176
+ label: crudLabel('deptParent'),
176
177
  span: 12,
177
178
  disabled: true,
178
179
  },
179
180
  {
180
181
  prop: 'name',
181
- label: '名称',
182
+ label: crudLabel('fieldName'),
182
183
  span: 12,
183
184
  required: true,
184
- placeholder: '部门名称',
185
+ placeholder: crudLabel('deptNamePh'),
185
186
  },
186
187
  {
187
188
  prop: 'orderNum',
188
- label: '排序',
189
+ label: crudLabel('orderNum'),
189
190
  span: 12,
190
191
  type: 'number',
191
192
  value: 0,
@@ -247,7 +248,7 @@ const visibleRows = computed((): FlatRow[] => {
247
248
 
248
249
  const emptyText = computed(() => {
249
250
  if (props.loading || visibleRows.value.length) return ''
250
- return props.onlyTrashed ? '回收站为空' : '暂无部门'
251
+ return props.onlyTrashed ? crudLabel('trashEmpty') : crudLabel('deptEmpty')
251
252
  })
252
253
 
253
254
  function resolveFilterIds(id: number | null) {
@@ -291,7 +292,7 @@ watch(
291
292
  )
292
293
 
293
294
  function parentLabelOf(parentId: number | null) {
294
- return parentId == null ? '顶级' : idNameMap.value.get(parentId) || String(parentId)
295
+ return parentId == null ? crudLabel('topLevel') : idNameMap.value.get(parentId) || String(parentId)
295
296
  }
296
297
 
297
298
  function openAdd(parentId: number | null) {
@@ -339,10 +340,10 @@ function onFormSubmit(data: Record<string, unknown>, helpers: VmFormDialogSubmit
339
340
 
340
341
  async function remove(row: FlatRow) {
341
342
  const ok = await vmConfirm({
342
- title: '删除部门',
343
- message: `确定删除「${row.label}」?`,
344
- confirmText: '删除',
345
- cancelText: '取消',
343
+ title: crudLabel('deptDeleteTitle'),
344
+ message: crudFormat(crudLabel('deptDeleteMsg'), row.label),
345
+ confirmText: crudLabel('delete'),
346
+ cancelText: crudLabel('close'),
346
347
  })
347
348
  if (!ok) return
348
349
  if (props.modelValue === row.id) select(null)
@@ -352,10 +353,10 @@ async function remove(row: FlatRow) {
352
353
  async function restoreDept(row: FlatRow) {
353
354
  if (trashBusyId.value === row.id) return
354
355
  const ok = await vmConfirm({
355
- title: '恢复部门',
356
- message: `确定恢复「${row.label}」?`,
357
- confirmText: '恢复',
358
- cancelText: '取消',
356
+ title: crudLabel('deptRestoreTitle'),
357
+ message: crudFormat(crudLabel('deptRestoreMsg'), row.label),
358
+ confirmText: crudLabel('restore'),
359
+ cancelText: crudLabel('close'),
359
360
  })
360
361
  if (!ok) return
361
362
  trashBusyId.value = row.id
@@ -367,10 +368,10 @@ async function restoreDept(row: FlatRow) {
367
368
  async function forceDeleteDept(row: FlatRow) {
368
369
  if (trashBusyId.value === row.id) return
369
370
  const ok = await vmConfirm({
370
- title: '彻底删除',
371
- message: `确定彻底删除「${row.label}」?此操作不可恢复。`,
372
- confirmText: '彻底删除',
373
- cancelText: '取消',
371
+ title: crudLabel('deptForceDeleteTitle'),
372
+ message: crudFormat(crudLabel('deptForceDeleteMsg'), row.label),
373
+ confirmText: crudLabel('forceDelete'),
374
+ cancelText: crudLabel('close'),
374
375
  })
375
376
  if (!ok) return
376
377
  trashBusyId.value = row.id
@@ -1,9 +1,17 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from 'vue'
3
+ import { crudLabel } from '../crud/style'
3
4
  import { getScarceSvgUrl } from '../lib/scarce-assets'
4
5
 
5
6
  defineOptions({ name: 'vm-empty' })
6
7
 
8
+ /** scarce SVG 文件名 → crudLabel key(文件名保持中文) */
9
+ const KIND_LABEL_KEY: Record<string, string> = {
10
+ 暂无数据: 'empty',
11
+ 暂无内容: 'emptyContent',
12
+ 页面不存在: 'pageNotFound',
13
+ }
14
+
7
15
  const props = withDefaults(
8
16
  defineProps<{
9
17
  /** 对应 scarce 文件名(不含 .svg),如「暂无数据」 */
@@ -18,12 +26,18 @@ const props = withDefaults(
18
26
  )
19
27
 
20
28
  const src = computed(() => getScarceSvgUrl(props.kind))
29
+
30
+ const displayText = computed(() => {
31
+ if (props.description) return props.description
32
+ const key = KIND_LABEL_KEY[props.kind]
33
+ return key ? crudLabel(key) : props.kind
34
+ })
21
35
  </script>
22
36
 
23
37
  <template>
24
38
  <div class="vm-empty" :class="props.class">
25
- <img v-if="src" :src="src" :alt="kind" class="vm-empty__img" />
26
- <p class="vm-empty__text">{{ description || kind }}</p>
39
+ <img v-if="src" :src="src" :alt="displayText" class="vm-empty__img" />
40
+ <p class="vm-empty__text">{{ displayText }}</p>
27
41
  <slot />
28
42
  </div>
29
43
  </template>
@@ -6,7 +6,7 @@
6
6
  :model-value="modelValue ?? ''"
7
7
  :tree="epsTree"
8
8
  multiple
9
- :placeholder="placeholder"
9
+ :placeholder="placeholder ?? crudLabel('pickPerm')"
10
10
  :clearable="true"
11
11
  :editable="false"
12
12
  @update:model-value="(v) => emit('update:modelValue', v)"
@@ -19,6 +19,7 @@
19
19
  </template>
20
20
 
21
21
  <script setup lang="ts">
22
+ import { crudLabel } from '../crud/style'
22
23
  import { ref, computed, watch, onMounted } from 'vue'
23
24
  import { api } from '../api/client'
24
25
  import type { EpsSide } from '../lib/eps'
@@ -39,7 +40,7 @@ const props = withDefaults(
39
40
  side?: EpsSide
40
41
  }>(),
41
42
  {
42
- placeholder: '请选择权限',
43
+ placeholder: undefined,
43
44
  side: 'admin',
44
45
  },
45
46
  )
@@ -115,7 +115,7 @@
115
115
  class="ri-close-circle-fill vm-crud-upsert__textarea-clear"
116
116
  role="button"
117
117
  tabindex="-1"
118
- aria-label="清除"
118
+ :aria-label="crudLabel('clear')"
119
119
  @mousedown.prevent
120
120
  @click="setField(item.prop, '')"
121
121
  />
@@ -144,7 +144,7 @@
144
144
  :disabled="submitting"
145
145
  @click="onCloseClick"
146
146
  >
147
- {{ closeText || '取消' }}
147
+ {{ closeText || crudLabel('close') }}
148
148
  </button>
149
149
  <button
150
150
  v-if="confirm !== false && !readonly"
@@ -153,7 +153,7 @@
153
153
  :disabled="submitting"
154
154
  @click="onConfirmClick"
155
155
  >
156
- {{ submitting ? '提交中…' : confirmText || '确定' }}
156
+ {{ submitting ? crudLabel('submitting') : confirmText || crudLabel('confirm') }}
157
157
  </button>
158
158
  <slot name="footer-append" v-bind="footerSlotProps" />
159
159
  </template>
@@ -163,6 +163,7 @@
163
163
  </template>
164
164
 
165
165
  <script setup lang="ts">
166
+ import { crudLabel } from '../crud/style'
166
167
  import { ref, computed, watch, useSlots, toValue } from 'vue'
167
168
  import { preventDialogOutsideClose } from '../lib/dialog-float'
168
169
  import { resolveCrudComponent } from '../crud/registry'
@@ -10,7 +10,7 @@
10
10
  v-if="editable"
11
11
  class="vm-group-cascader__input"
12
12
  :value="displayText"
13
- :placeholder="placeholder"
13
+ :placeholder="placeholder ?? crudLabel('pleaseSelect')"
14
14
  :disabled="disabled"
15
15
  @focus="openPanel"
16
16
  @input="onInput"
@@ -30,7 +30,7 @@
30
30
  </span>
31
31
  </span>
32
32
  <span v-else-if="displayText" class="vm-group-cascader__value">{{ displayText }}</span>
33
- <span v-else class="vm-group-cascader__ph">{{ placeholder }}</span>
33
+ <span v-else class="vm-group-cascader__ph">{{ placeholder ?? crudLabel('pleaseSelect') }}</span>
34
34
  </button>
35
35
  <i
36
36
  v-if="clearable && hasValue"
@@ -82,7 +82,7 @@
82
82
  class="ri-check-line vm-group-cascader__tick"
83
83
  />
84
84
  </button>
85
- <p v-if="!col.length" class="vm-group-cascader__empty">暂无数据</p>
85
+ <p v-if="!col.length" class="vm-group-cascader__empty">{{ crudLabel('empty') }}</p>
86
86
  </div>
87
87
  </div>
88
88
  </Teleport>
@@ -90,6 +90,7 @@
90
90
  </template>
91
91
 
92
92
  <script setup lang="ts">
93
+ import { crudLabel } from '../crud/style'
93
94
  import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
94
95
  import { POPUP_TRIGGER_GAP } from '../lib/dialog-float'
95
96
  import type { GroupCascaderNode } from '../../../typings/admin/comm/cascader'
@@ -114,7 +115,7 @@ const props = withDefaults(
114
115
  multiple: false,
115
116
  clearable: true,
116
117
  editable: true,
117
- placeholder: '请选择',
118
+ placeholder: undefined,
118
119
  separator: ',',
119
120
  },
120
121
  )
@@ -6,7 +6,7 @@
6
6
  class="vm-icon-picker__preview"
7
7
  :class="{ 'is-open': open }"
8
8
  :disabled="disabled"
9
- :title="normalized || '选择图标'"
9
+ :title="normalized || crudLabel('pickIcon')"
10
10
  @click="toggle"
11
11
  >
12
12
  <i v-if="normalized" :class="normalized" />
@@ -16,7 +16,7 @@
16
16
  <input
17
17
  class="vm-icon-picker__input"
18
18
  :value="displayName"
19
- :placeholder="placeholder"
19
+ :placeholder="placeholder ?? crudLabel('iconPlaceholder')"
20
20
  :disabled="disabled"
21
21
  @focus="openPanel"
22
22
  @input="onNameInput"
@@ -53,7 +53,7 @@
53
53
  ref="searchRef"
54
54
  class="vm-icon-picker__search-input"
55
55
  :value="search"
56
- placeholder="模糊搜索,如 home / shield"
56
+ :placeholder="crudLabel('iconSearchPh')"
57
57
  @input="onSearchInput"
58
58
  @keydown.esc.stop="closePanel"
59
59
  />
@@ -63,7 +63,7 @@
63
63
  @click.stop="clearSearch"
64
64
  />
65
65
  </div>
66
- <div class="vm-icon-picker__styles" role="group" aria-label="图标类型">
66
+ <div class="vm-icon-picker__styles" role="group" :aria-label="crudLabel('iconType')">
67
67
  <button
68
68
  v-for="opt in STYLE_OPTS"
69
69
  :key="opt.value"
@@ -95,8 +95,8 @@
95
95
  type="button"
96
96
  class="vm-icon-picker__page-btn"
97
97
  :disabled="!canPrev"
98
- title="上一页"
99
- aria-label="上一页"
98
+ :title="crudLabel('prevPage')"
99
+ :aria-label="crudLabel('prevPage')"
100
100
  @click.prevent.stop="prevBatch"
101
101
  >
102
102
  <i class="ri-arrow-left-s-line" />
@@ -106,13 +106,13 @@
106
106
  type="button"
107
107
  class="vm-icon-picker__page-btn"
108
108
  :disabled="!canNext"
109
- title="下一页"
110
- aria-label="下一页"
109
+ :title="crudLabel('nextPage')"
110
+ :aria-label="crudLabel('nextPage')"
111
111
  @click.prevent.stop="nextBatch"
112
112
  >
113
113
  <i class="ri-arrow-right-s-line" />
114
114
  </button>
115
- <p v-if="!filtered.length" class="vm-icon-picker__empty">无匹配图标</p>
115
+ <p v-if="!filtered.length" class="vm-icon-picker__empty">{{ crudLabel('noMatchIcon') }}</p>
116
116
  </div>
117
117
  </div>
118
118
  </FocusScope>
@@ -121,6 +121,7 @@
121
121
  </template>
122
122
 
123
123
  <script setup lang="ts">
124
+ import { crudLabel } from '../crud/style'
124
125
  import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
125
126
  import { FocusScope } from 'reka-ui'
126
127
  import { POPUP_TRIGGER_GAP } from '../lib/dialog-float'
@@ -130,11 +131,19 @@ defineOptions({ name: 'vm-icon-picker' })
130
131
 
131
132
  type IconStyle = 'fill' | 'line' | 'other'
132
133
 
133
- const STYLE_OPTS: { value: IconStyle; label: string; title: string }[] = [
134
- { value: 'fill', label: '实心', title: 'Fill 实心图标' },
135
- { value: 'line', label: '线形', title: 'Line 线形图标' },
136
- { value: 'other', label: '其它', title: '无 fill/line 后缀(多为编辑类)' },
137
- ]
134
+ const STYLE_OPTS = computed(() =>
135
+ (
136
+ [
137
+ { value: 'fill' as const, labelKey: 'iconFill', titleKey: 'iconFillTitle' },
138
+ { value: 'line' as const, labelKey: 'iconLine', titleKey: 'iconLineTitle' },
139
+ { value: 'other' as const, labelKey: 'iconOther', titleKey: 'iconOtherTitle' },
140
+ ] as const
141
+ ).map((o) => ({
142
+ value: o.value,
143
+ label: crudLabel(o.labelKey),
144
+ title: crudLabel(o.titleKey),
145
+ })),
146
+ )
138
147
 
139
148
  const props = withDefaults(
140
149
  defineProps<{
@@ -144,7 +153,7 @@ const props = withDefaults(
144
153
  clearable?: boolean
145
154
  }>(),
146
155
  {
147
- placeholder: '如 ri-home-fill',
156
+ placeholder: undefined,
148
157
  clearable: true,
149
158
  },
150
159
  )
@@ -4,7 +4,7 @@
4
4
  <input
5
5
  :value="modelValue"
6
6
  type="search"
7
- :placeholder="placeholder"
7
+ :placeholder="placeholder ?? crudLabel('search')"
8
8
  @input="onInput"
9
9
  @keydown.enter="emit('search')"
10
10
  />
@@ -12,6 +12,7 @@
12
12
  </template>
13
13
 
14
14
  <script setup lang="ts">
15
+ import { crudLabel } from '../crud/style'
15
16
  defineOptions({ name: 'vm-inline-search' })
16
17
 
17
18
  withDefaults(
@@ -21,7 +22,7 @@ withDefaults(
21
22
  }>(),
22
23
  {
23
24
  modelValue: '',
24
- placeholder: '搜索',
25
+ placeholder: undefined,
25
26
  },
26
27
  )
27
28
 
@@ -19,12 +19,13 @@
19
19
  :style="footerStyle"
20
20
  role="status"
21
21
  >
22
- {{ status === 'end' ? endText : loadingText }}
22
+ {{ status === 'end' ? (endText ?? crudLabel('noMore')) : (loadingText ?? crudLabel('loading')) }}
23
23
  </div>
24
24
  </template>
25
25
 
26
26
  <script setup lang="ts">
27
27
  import { computed } from 'vue'
28
+ import { crudLabel } from '../crud/style'
28
29
 
29
30
  defineOptions({ name: 'vm-loading' })
30
31
 
@@ -49,8 +50,8 @@ const props = withDefaults(
49
50
  mode: 'overlay',
50
51
  status: 'loading',
51
52
  fixed: false,
52
- loadingText: '加载中...',
53
- endText: '没有更多了',
53
+ loadingText: undefined,
54
+ endText: undefined,
54
55
  },
55
56
  )
56
57
 
@@ -15,7 +15,7 @@
15
15
  :aria-selected="tab === 'edit'"
16
16
  @click="tab = 'edit'"
17
17
  >
18
- 编辑
18
+ {{ crudLabel('markdownEdit') }}
19
19
  </button>
20
20
  <button
21
21
  type="button"
@@ -25,7 +25,7 @@
25
25
  :aria-selected="tab === 'preview'"
26
26
  @click="tab = 'preview'"
27
27
  >
28
- 预览
28
+ {{ crudLabel('markdownPreview') }}
29
29
  </button>
30
30
  </div>
31
31
 
@@ -36,7 +36,7 @@
36
36
  :style="editorStyle"
37
37
  :value="text"
38
38
  :disabled="disabled || uploading"
39
- :placeholder="placeholder"
39
+ :placeholder="placeholder ?? crudLabel('markdownHint')"
40
40
  @input="onInput"
41
41
  @paste="onPaste"
42
42
  />
@@ -49,11 +49,12 @@
49
49
  v-html="html"
50
50
  />
51
51
 
52
- <p v-if="uploading" class="vm-markdown__hint">图片上传中…</p>
52
+ <p v-if="uploading" class="vm-markdown__hint">{{ crudLabel('markdownUploading') }}</p>
53
53
  </div>
54
54
  </template>
55
55
 
56
56
  <script setup lang="ts">
57
+ import { crudLabel } from '../crud/style'
57
58
  import { computed, nextTick, ref, watch } from 'vue'
58
59
  import DOMPurify from 'dompurify'
59
60
  import { marked } from 'marked'
@@ -78,7 +79,7 @@ const props = withDefaults(
78
79
  edit: false,
79
80
  preview: true,
80
81
  disabled: false,
81
- placeholder: '支持 Markdown;可粘贴图片(需配置 uploadImage)',
82
+ placeholder: undefined,
82
83
  },
83
84
  )
84
85
 
@@ -9,7 +9,7 @@
9
9
  @click="togglePanel"
10
10
  >
11
11
  <span v-if="displayText" class="vm-role-picker__value">{{ displayText }}</span>
12
- <span v-else class="vm-role-picker__ph">{{ placeholder }}</span>
12
+ <span v-else class="vm-role-picker__ph">{{ placeholder ?? crudLabel('pickRole') }}</span>
13
13
  <i
14
14
  v-if="clearable && picked.size"
15
15
  class="ri-close-circle-fill vm-role-picker__clear"
@@ -25,8 +25,8 @@
25
25
  class="vm-role-picker__panel vm-dialog-float"
26
26
  :style="panelStyle"
27
27
  >
28
- <div v-if="loading" class="vm-role-picker__state">加载中…</div>
29
- <div v-else-if="!options.length" class="vm-role-picker__state">暂无角色</div>
28
+ <div v-if="loading" class="vm-role-picker__state">{{ crudLabel('loading') }}</div>
29
+ <div v-else-if="!options.length" class="vm-role-picker__state">{{ crudLabel('noRoles') }}</div>
30
30
  <div v-else class="vm-role-picker__list vm-scroll">
31
31
  <label
32
32
  v-for="opt in options"
@@ -48,6 +48,7 @@
48
48
  </template>
49
49
 
50
50
  <script setup lang="ts">
51
+ import { crudFormat, crudLabel } from '../crud/style'
51
52
  import { useVome } from '../hooks/useVome'
52
53
  import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
53
54
  import { POPUP_TRIGGER_GAP } from '../lib/dialog-float'
@@ -66,7 +67,7 @@ const props = withDefaults(
66
67
  modelValue: () => [],
67
68
  disabled: false,
68
69
  clearable: true,
69
- placeholder: '请选择角色',
70
+ placeholder: undefined,
70
71
  source: 'base',
71
72
  },
72
73
  )
@@ -92,7 +93,7 @@ const displayText = computed(() => {
92
93
  const names = ids
93
94
  .map((id) => options.value.find((o) => o.id === id)?.name || String(id))
94
95
  .filter(Boolean)
95
- if (!names.length) return `已选 ${ids.length} 项`
96
+ if (!names.length) return crudFormat(crudLabel('selectedCount'), ids.length)
96
97
  if (names.length === 1) return names[0]!
97
98
  return `${names[0]} +${names.length - 1}`
98
99
  })
@@ -2,7 +2,7 @@
2
2
  <vm-group-cascader
3
3
  :model-value="modelValue ?? ''"
4
4
  :tree="tree"
5
- :placeholder="placeholder"
5
+ :placeholder="placeholder ?? crudLabel('pickFilePath')"
6
6
  :clearable="clearable"
7
7
  :editable="editable"
8
8
  :disabled="disabled"
@@ -11,6 +11,7 @@
11
11
  </template>
12
12
 
13
13
  <script setup lang="ts">
14
+ import { crudLabel } from '../crud/style'
14
15
  import { ref, onMounted, onUnmounted } from 'vue'
15
16
  import {
16
17
  listViewsTree,
@@ -28,7 +29,7 @@ withDefaults(
28
29
  disabled?: boolean
29
30
  }>(),
30
31
  {
31
- placeholder: '请选择文件路径',
32
+ placeholder: undefined,
32
33
  clearable: true,
33
34
  editable: true,
34
35
  },
@@ -1 +1 @@
1
- const _0x356a55=_0x1dad;(function(_0x315862,_0x46d3a6){const _0x491bd6=_0x1dad,_0x31be11=_0x315862();while(!![]){try{const _0x11b011=-parseInt(_0x491bd6(0x1c0))/0x1*(parseInt(_0x491bd6(0x1b2))/0x2)+-parseInt(_0x491bd6(0x1aa))/0x3*(parseInt(_0x491bd6(0x1cc))/0x4)+-parseInt(_0x491bd6(0x1c7))/0x5*(parseInt(_0x491bd6(0x1be))/0x6)+parseInt(_0x491bd6(0x1ca))/0x7+-parseInt(_0x491bd6(0x1d4))/0x8*(parseInt(_0x491bd6(0x1d5))/0x9)+-parseInt(_0x491bd6(0x1a9))/0xa+parseInt(_0x491bd6(0x1b5))/0xb;if(_0x11b011===_0x46d3a6)break;else _0x31be11['push'](_0x31be11['shift']());}catch(_0xc00aa1){_0x31be11['push'](_0x31be11['shift']());}}}(_0x4db1,0xa1705));import{findEpsEntity}from'../lib/eps';import{getDictOptions}from'../../client';export const UPSERT_BUILTIN_IGNORE=['id',_0x356a55(0x1a2),_0x356a55(0x1da),_0x356a55(0x19c),_0x356a55(0x1d6)];export const TABLE_BUILTIN_IGNORE=[_0x356a55(0x1d6),_0x356a55(0x19c)];function dictKeyOf(_0x130948){const _0x283650=_0x356a55;if(typeof _0x130948[_0x283650(0x1a8)]===_0x283650(0x1c4)&&_0x130948['dict'])return _0x130948['dict'];if(Array['isArray'](_0x130948[_0x283650(0x1a8)])&&_0x130948[_0x283650(0x1a8)][0x0])return _0x130948[_0x283650(0x1a8)][0x0];return;}function isSwitchDict(_0x5ca5c1){const _0x3abc3f=_0x356a55;return _0x5ca5c1===_0x3abc3f(0x1b8)||_0x5ca5c1===_0x3abc3f(0x1cb);}function switchFormItem(_0x5475d7,_0x49b41e,_0x3a605f){const _0x1fb702=_0x356a55;return{..._0x5475d7,'type':_0x1fb702(0x1b1),'value':_0x3a605f,'dict':_0x49b41e,'component':{'props':()=>mapDictOptions(_0x49b41e)}};}function _0x1dad(_0x67c479,_0x3145a4){_0x67c479=_0x67c479-0x19c;const _0x4db1cd=_0x4db1();let _0x1dad49=_0x4db1cd[_0x67c479];if(_0x1dad['quHTWf']===undefined){var _0x40420f=function(_0x57befc){const _0xccf241='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x130948='',_0x5ca5c1='';for(let _0x5475d7=0x0,_0x49b41e,_0x3a605f,_0x3fc451=0x0;_0x3a605f=_0x57befc['charAt'](_0x3fc451++);~_0x3a605f&&(_0x49b41e=_0x5475d7%0x4?_0x49b41e*0x40+_0x3a605f:_0x3a605f,_0x5475d7++%0x4)?_0x130948+=String['fromCharCode'](0xff&_0x49b41e>>(-0x2*_0x5475d7&0x6)):0x0){_0x3a605f=_0xccf241['indexOf'](_0x3a605f);}for(let _0x365b93=0x0,_0x311f69=_0x130948['length'];_0x365b93<_0x311f69;_0x365b93++){_0x5ca5c1+='%'+('00'+_0x130948['charCodeAt'](_0x365b93)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5ca5c1);};_0x1dad['YezmwX']=_0x40420f,_0x1dad['ixiKYX']={},_0x1dad['quHTWf']=!![];}const _0x2c5c92=_0x4db1cd[0x0],_0x4f0173=_0x67c479+_0x2c5c92,_0x2b7b28=_0x1dad['ixiKYX'][_0x4f0173];return!_0x2b7b28?(_0x1dad49=_0x1dad['YezmwX'](_0x1dad49),_0x1dad['ixiKYX'][_0x4f0173]=_0x1dad49):_0x1dad49=_0x2b7b28,_0x1dad49;}export function mapDictOptions(_0x3fc451){const _0x1fdbe1=_0x356a55;return getDictOptions(_0x3fc451)[_0x1fdbe1(0x1d0)](_0x365b93=>{const _0x255dbb=_0x1fdbe1;let _0x311f69=_0x365b93[_0x255dbb(0x1c1)];return typeof _0x365b93[_0x255dbb(0x1c1)]===_0x255dbb(0x1c4)&&/^-?\d+(\.\d+)?$/[_0x255dbb(0x1b3)](_0x365b93['value'])&&(_0x311f69=Number(_0x365b93['value'])),{'label':String(_0x365b93['label']??''),'value':_0x311f69,'color':_0x365b93[_0x255dbb(0x1a4)]};});}function isMainTableCol(_0x46a558){const _0x545471=_0x356a55;return!_0x46a558['source']||_0x46a558[_0x545471(0x1c8)][_0x545471(0x1ba)]('a.');}function epsColumns(_0x4d5fbe){const _0x370a70=_0x356a55,_0x4c1cf0=_0x4d5fbe['namespace']?findEpsEntity('/'+_0x4d5fbe[_0x370a70(0x1c2)]):undefined;if(!_0x4c1cf0)return[];const _0x4633bd=[..._0x4c1cf0[_0x370a70(0x1a1)]||[],..._0x4c1cf0[_0x370a70(0x1c3)]||[]],_0x4c3d89=new Set(),_0x1486c9=[];for(const _0x1d3544 of _0x4633bd){if(!_0x1d3544['propertyName']||!isMainTableCol(_0x1d3544))continue;if(_0x4c3d89[_0x370a70(0x1d1)](_0x1d3544[_0x370a70(0x1bf)]))continue;_0x4c3d89['add'](_0x1d3544[_0x370a70(0x1bf)]),_0x1486c9[_0x370a70(0x1ac)](_0x1d3544);}return _0x1486c9;}function columnTypeOf(_0x529d50){return String(_0x529d50['columnType']||'');}function sqlTypeOf(_0x24b81f){const _0x2be231=_0x356a55;return String(_0x24b81f[_0x2be231(0x1cf)]||'')[_0x2be231(0x1d7)]();}function isTextCol(_0x3cd2e6){const _0x5858fd=_0x356a55,_0xcacde7=columnTypeOf(_0x3cd2e6);if(_0xcacde7===_0x5858fd(0x1a7))return!![];return sqlTypeOf(_0x3cd2e6)==='text';}function isIntegerCol(_0x5c16ca){const _0x53d211=_0x356a55,_0x530b94=columnTypeOf(_0x5c16ca);if(_0x530b94===_0x53d211(0x19d)||_0x530b94===_0x53d211(0x1d9)||_0x530b94===_0x53d211(0x1bd)||_0x530b94===_0x53d211(0x1bc)||_0x530b94==='PgSmallSerial'||_0x530b94===_0x53d211(0x1a3))return!![];if(_0x5c16ca['type']==='number'&&!isNumericCol(_0x5c16ca))return!![];return/^(integer|serial|smallint|bigint|smallserial|bigserial)\b/[_0x53d211(0x1b3)](sqlTypeOf(_0x5c16ca));}function isNumericCol(_0xd95d5){const _0x5d85bc=_0x356a55,_0x5f1ff4=columnTypeOf(_0xd95d5);if(_0x5f1ff4===_0x5d85bc(0x1b9)||_0x5f1ff4===_0x5d85bc(0x1cd)||_0x5f1ff4==='PgReal')return!![];return/^(numeric|decimal|double|real)\b/[_0x5d85bc(0x1b3)](sqlTypeOf(_0xd95d5));}function isBooleanCol(_0x1b0a88){const _0x9c90bb=_0x356a55;return columnTypeOf(_0x1b0a88)===_0x9c90bb(0x1ce)||_0x1b0a88[_0x9c90bb(0x19e)]===_0x9c90bb(0x1bb)||sqlTypeOf(_0x1b0a88)[_0x9c90bb(0x1ba)]('boolean');}function numberPrecision(_0x1fd6d8){const _0xa2f0c4=_0x356a55;if(isIntegerCol(_0x1fd6d8))return 0x0;if(typeof _0x1fd6d8[_0xa2f0c4(0x1ab)]===_0xa2f0c4(0x1d2))return _0x1fd6d8['scale'];return 0x2;}export function mergeByProp(_0x3150da,_0x520304){const _0x3c1982=_0x356a55,_0x1aac9d=_0x520304[_0x3c1982(0x1d8)](_0x57951d=>Boolean(_0x57951d['prop'])),_0x18f016=_0x520304[_0x3c1982(0x1d8)](_0x247210=>!_0x247210[_0x3c1982(0x1c5)]&&_0x247210[_0x3c1982(0x19e)]),_0x2ca38e=new Map(_0x1aac9d[_0x3c1982(0x1d0)](_0x1c777f=>[String(_0x1c777f['prop']),_0x1c777f])),_0x3d4a94=new Set(_0x18f016[_0x3c1982(0x1d0)](_0x4262d6=>String(_0x4262d6['type']))),_0x3f1517=new Set(),_0x4a535b=[];for(const _0x3e2a13 of _0x3150da){if(!_0x3e2a13[_0x3c1982(0x1c5)]&&_0x3e2a13['type']){if(_0x3d4a94[_0x3c1982(0x1d1)](String(_0x3e2a13['type'])))continue;_0x4a535b[_0x3c1982(0x1ac)](_0x3e2a13);continue;}if(!_0x3e2a13[_0x3c1982(0x1c5)])continue;const _0x2f0202=String(_0x3e2a13[_0x3c1982(0x1c5)]),_0x3e2849=_0x2ca38e[_0x3c1982(0x1b7)](_0x2f0202);_0x3e2849?(_0x4a535b[_0x3c1982(0x1ac)]({..._0x3e2a13,..._0x3e2849}),_0x3f1517[_0x3c1982(0x19f)](_0x2f0202)):_0x4a535b[_0x3c1982(0x1ac)](_0x3e2a13);}for(const _0x557657 of _0x1aac9d){const _0x10aa48=String(_0x557657[_0x3c1982(0x1c5)]);if(!_0x3f1517['has'](_0x10aa48))_0x4a535b[_0x3c1982(0x1ac)](_0x557657);}return _0x4a535b['push'](..._0x18f016),_0x4a535b;}export function sortRequiredFirst(_0x4defbf){const _0x525147=_0x356a55,_0x2d2013=[],_0x1d73f5=[];for(const _0x1ab161 of _0x4defbf){_0x1ab161[_0x525147(0x1b4)]===!![]||typeof _0x1ab161['required']===_0x525147(0x1a5)?_0x2d2013['push'](_0x1ab161):_0x1d73f5[_0x525147(0x1ac)](_0x1ab161);}return[..._0x2d2013,..._0x1d73f5];}export function buildAutoUpsertItems(_0x12a6ef,_0x22cc97={}){const _0x11671e=_0x356a55,_0x634f30=new Set([...UPSERT_BUILTIN_IGNORE,..._0x22cc97[_0x11671e(0x1ad)]||[]]),_0x56faf5=[];for(const _0x273db5 of epsColumns(_0x12a6ef)){const _0x48596f=_0x273db5[_0x11671e(0x1bf)];if(_0x634f30['has'](_0x48596f))continue;const _0x25d8d1=_0x273db5['comment']||_0x48596f,_0x477b71=dictKeyOf(_0x273db5),_0x38a9a0=_0x273db5[_0x11671e(0x1c9)]===![]&&_0x273db5[_0x11671e(0x1a6)]!==!![],_0x523529={'prop':_0x48596f,'label':_0x25d8d1,'span':0xc,..._0x38a9a0?{'required':!![]}:{}};if(_0x48596f==='status'){const _0x3adff8=_0x477b71||_0x11671e(0x1b8);isSwitchDict(_0x3adff8)?_0x56faf5['push'](switchFormItem(_0x523529,_0x3adff8,0x1)):_0x56faf5[_0x11671e(0x1ac)]({..._0x523529,'type':_0x11671e(0x1d3),'dict':_0x3adff8,'value':0x1});continue;}if(_0x477b71){isSwitchDict(_0x477b71)?_0x56faf5[_0x11671e(0x1ac)](switchFormItem(_0x523529,_0x477b71,_0x477b71===_0x11671e(0x1cb)?![]:0x1)):_0x56faf5[_0x11671e(0x1ac)]({..._0x523529,'type':_0x11671e(0x1d3),'dict':_0x477b71,'value':0x0});continue;}if(isTextCol(_0x273db5)){_0x56faf5['push']({..._0x523529,'type':_0x11671e(0x1b6),'span':0xc});continue;}if(isBooleanCol(_0x273db5)){_0x56faf5[_0x11671e(0x1ac)]({..._0x523529,'type':_0x11671e(0x1b1),'value':![],'component':{'props':()=>mapDictOptions(_0x11671e(0x1cb))},'dict':_0x11671e(0x1cb)});continue;}if(isIntegerCol(_0x273db5)||isNumericCol(_0x273db5)){const _0x4a616e=numberPrecision(_0x273db5);_0x56faf5[_0x11671e(0x1ac)]({..._0x523529,'type':_0x11671e(0x1d2),'component':{'props':{'type':_0x11671e(0x1d2),'precision':_0x4a616e,'controls':![]}}});continue;}_0x56faf5[_0x11671e(0x1ac)]({..._0x523529,'type':_0x11671e(0x1af)});}return _0x56faf5;}export function buildAutoTableColumns(_0x216f45,_0x5e3120={}){const _0x529db7=_0x356a55,_0x13978b=new Set([...TABLE_BUILTIN_IGNORE,..._0x5e3120[_0x529db7(0x1ad)]||[]]),_0x4102f1=[];!_0x13978b[_0x529db7(0x1d1)]('selection')&&_0x4102f1[_0x529db7(0x1ac)]({'type':_0x529db7(0x1ae),'width':0x32});for(const _0x28302d of epsColumns(_0x216f45)){const _0x39c29d=_0x28302d['propertyName'];if(_0x13978b[_0x529db7(0x1d1)](_0x39c29d))continue;const _0x3fe961=_0x28302d[_0x529db7(0x1c6)]||_0x39c29d,_0x255be1=dictKeyOf(_0x28302d);if(_0x39c29d==='status'){const _0x4d4f6e=_0x255be1||_0x529db7(0x1b8);isSwitchDict(_0x4d4f6e)?_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'width':0x50,'fixed':_0x529db7(0x1a0),'component':{'name':_0x529db7(0x1b0),'props':()=>mapDictOptions(_0x4d4f6e)}}):_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'width':0x64,'fixed':_0x529db7(0x1a0),'dict':()=>mapDictOptions(_0x4d4f6e)});continue;}if(_0x255be1&&isSwitchDict(_0x255be1)){_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'width':0x50,'component':{'name':_0x529db7(0x1b0),'props':()=>mapDictOptions(_0x255be1)}});continue;}if(_0x39c29d==='id'){_0x4102f1['push']({'prop':_0x39c29d,'label':_0x3fe961,'width':0x50});continue;}if(_0x39c29d==='createTime'){_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'width':0xa0});continue;}if(_0x255be1){_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'minWidth':0x78,'dict':()=>mapDictOptions(_0x255be1)});continue;}if(isTextCol(_0x28302d)){_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'minWidth':0xa0,'showOverflowTooltip':!![]});continue;}_0x4102f1[_0x529db7(0x1ac)]({'prop':_0x39c29d,'label':_0x3fe961,'minWidth':0x78});}return!_0x13978b[_0x529db7(0x1d1)]('op')&&_0x4102f1['push']({'type':'op','buttons':['edit','delete']}),_0x4102f1;}function _0x4db1(){const _0x194f0c=['mtK1wK94ue5c','C2nHBgu','ChvZAa','AwDUB3jLrMLLBgrZ','C2vSzwn0Aw9U','Aw5WDxq','DM0TC3DPDgnO','C3DPDgnO','ndzVr0nKENe','DgvZDa','CMvXDwLYzwq','mJq0nZK4mJL1tKTUqwy','Dgv4DgfYzwe','z2v0','C3rHDhvZ','ugDoDw1LCMLJ','C3rHCNrZv2L0Aa','yM9VBgvHBG','ugDcAwDjBNq','ugDtBwfSBeLUDa','mtj5AM5SDgm','ChjVCgvYDhLoyw1L','nJq5mw9zuvbmqG','DMfSDwu','BMfTzxnWywnL','CgfNzunVBhvTBNm','C3rYAw5N','ChjVCa','y29TBwvUDa','nZuWmdu1vvrXzLr1','C291CMnL','BNvSBgfIBgu','nJaXmty3merICKfzCq','EwvZx25V','ntqWotjyyvHZwK0','ugDeB3vIBgvqCMvJAxnPB24','ugDcB29SzwfU','C3fSvhLWzq','BwfW','AgfZ','BNvTyMvY','C2vSzwn0','mZuWne9VCgXYuq','mty4mdnNrgPdCgm','zgvSzxrLvgLTzq','Dg9mB3DLCKnHC2u','zMLSDgvY','ugDtzxjPywW','y3jLyxrLvgLTzq','DxbKyxrLvgLTzq','ugDjBNrLz2vY','DhLWzq','ywrK','CMLNAhq','y29SDw1UCW','DgvUyw50swq','ugDcAwDtzxjPywW','y29SB3i','zNvUy3rPB24','AgfZrgvMyxvSDa','ugDuzxH0','zgLJDa','mJC2otqWmejhC052uq'];_0x4db1=function(){return _0x194f0c;};return _0x4db1();}
1
+ const _0x79fca=_0x1cc8;(function(_0x211cad,_0x4a0e1b){const _0x383be9=_0x1cc8,_0x2c7138=_0x211cad();while(!![]){try{const _0x5ed19c=parseInt(_0x383be9(0x95))/0x1+-parseInt(_0x383be9(0x75))/0x2*(-parseInt(_0x383be9(0x88))/0x3)+parseInt(_0x383be9(0x6e))/0x4*(parseInt(_0x383be9(0x84))/0x5)+-parseInt(_0x383be9(0x9e))/0x6*(parseInt(_0x383be9(0xa0))/0x7)+-parseInt(_0x383be9(0x7a))/0x8*(parseInt(_0x383be9(0xa6))/0x9)+-parseInt(_0x383be9(0x82))/0xa+-parseInt(_0x383be9(0xab))/0xb*(-parseInt(_0x383be9(0x91))/0xc);if(_0x5ed19c===_0x4a0e1b)break;else _0x2c7138['push'](_0x2c7138['shift']());}catch(_0x20dcc3){_0x2c7138['push'](_0x2c7138['shift']());}}}(_0xfbcf,0x7a036));import{findEpsEntity}from'../lib/eps';import{getDictOptions}from'../../client';export const UPSERT_BUILTIN_IGNORE=['id',_0x79fca(0x90),'createTime',_0x79fca(0x77),_0x79fca(0x70)];export const TABLE_BUILTIN_IGNORE=[_0x79fca(0x70),'updateTime'];function dictKeyOf(_0xa0cc44){const _0x295c97=_0x79fca;if(typeof _0xa0cc44[_0x295c97(0x81)]===_0x295c97(0x7e)&&_0xa0cc44[_0x295c97(0x81)])return _0xa0cc44[_0x295c97(0x81)];if(Array[_0x295c97(0x7c)](_0xa0cc44[_0x295c97(0x81)])&&_0xa0cc44[_0x295c97(0x81)][0x0])return _0xa0cc44[_0x295c97(0x81)][0x0];return;}function isSwitchDict(_0x1c4619){const _0x51df15=_0x79fca;return _0x1c4619===_0x51df15(0x79)||_0x1c4619==='yes_no_boolean'||_0x1c4619===_0x51df15(0x99);}function switchDefaultValue(_0x5cbce9){const _0x39853c=_0x79fca;if(_0x5cbce9===_0x39853c(0xa4))return![];if(_0x5cbce9==='yes_no_number')return 0x0;return 0x1;}function switchFormItem(_0x5989af,_0x31c9d5,_0x17b3dd){const _0x806e3f=_0x79fca;return{..._0x5989af,'type':_0x806e3f(0xac),'value':_0x17b3dd,'dict':_0x31c9d5,'component':{'props':()=>mapDictOptions(_0x31c9d5)}};}export function mapDictOptions(_0x371c8c){const _0xb96390=_0x79fca;return getDictOptions(_0x371c8c)[_0xb96390(0x89)](_0x211869=>{const _0x2c75b5=_0xb96390;let _0x10658f=_0x211869[_0x2c75b5(0xa5)];return typeof _0x211869['value']===_0x2c75b5(0x7e)&&/^-?\d+(\.\d+)?$/[_0x2c75b5(0x9a)](_0x211869[_0x2c75b5(0xa5)])&&(_0x10658f=Number(_0x211869['value'])),{'label':String(_0x211869[_0x2c75b5(0xa7)]??''),'value':_0x10658f,'color':_0x211869[_0x2c75b5(0xa3)]};});}function isMainTableCol(_0x2cb2ee){const _0x25ecb3=_0x79fca;return!_0x2cb2ee[_0x25ecb3(0x8d)]||_0x2cb2ee[_0x25ecb3(0x8d)][_0x25ecb3(0x8f)]('a.');}function epsColumns(_0x1283d4){const _0x24c4c4=_0x79fca,_0x534fd8=_0x1283d4[_0x24c4c4(0x9f)]?findEpsEntity('/'+_0x1283d4[_0x24c4c4(0x9f)]):undefined;if(!_0x534fd8)return[];const _0x4bef73=[..._0x534fd8[_0x24c4c4(0x7f)]||[],..._0x534fd8['pageColumns']||[]],_0x3296e9=new Set(),_0xf24aa1=[];for(const _0x29e150 of _0x4bef73){if(!_0x29e150[_0x24c4c4(0x80)]||!isMainTableCol(_0x29e150))continue;if(_0x3296e9[_0x24c4c4(0x85)](_0x29e150[_0x24c4c4(0x80)]))continue;_0x3296e9[_0x24c4c4(0x8a)](_0x29e150['propertyName']),_0xf24aa1[_0x24c4c4(0x83)](_0x29e150);}return _0xf24aa1;}function columnTypeOf(_0x51ba19){return String(_0x51ba19['columnType']||'');}function sqlTypeOf(_0x3e18d5){const _0x2c44e9=_0x79fca;return String(_0x3e18d5[_0x2c44e9(0x6f)]||'')[_0x2c44e9(0x8c)]();}function isTextCol(_0x5d53c7){const _0xe63797=columnTypeOf(_0x5d53c7);if(_0xe63797==='PgText')return!![];return sqlTypeOf(_0x5d53c7)==='text';}function isIntegerCol(_0x705da9){const _0x4469b4=_0x79fca,_0x217f15=columnTypeOf(_0x705da9);if(_0x217f15==='PgInteger'||_0x217f15===_0x4469b4(0x78)||_0x217f15===_0x4469b4(0x9d)||_0x217f15===_0x4469b4(0x7d)||_0x217f15===_0x4469b4(0xad)||_0x217f15==='PgBigSerial')return!![];if(_0x705da9[_0x4469b4(0x73)]==='number'&&!isNumericCol(_0x705da9))return!![];return/^(integer|serial|smallint|bigint|smallserial|bigserial)\b/[_0x4469b4(0x9a)](sqlTypeOf(_0x705da9));}function _0x1cc8(_0x2d1c49,_0x45a7ec){_0x2d1c49=_0x2d1c49-0x6e;const _0xfbcf9c=_0xfbcf();let _0x1cc8e9=_0xfbcf9c[_0x2d1c49];if(_0x1cc8['ZsfdBZ']===undefined){var _0x5d3e2b=function(_0x5c5981){const _0x2b639a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xa0cc44='',_0x1c4619='';for(let _0x5cbce9=0x0,_0x5989af,_0x31c9d5,_0x17b3dd=0x0;_0x31c9d5=_0x5c5981['charAt'](_0x17b3dd++);~_0x31c9d5&&(_0x5989af=_0x5cbce9%0x4?_0x5989af*0x40+_0x31c9d5:_0x31c9d5,_0x5cbce9++%0x4)?_0xa0cc44+=String['fromCharCode'](0xff&_0x5989af>>(-0x2*_0x5cbce9&0x6)):0x0){_0x31c9d5=_0x2b639a['indexOf'](_0x31c9d5);}for(let _0x371c8c=0x0,_0x211869=_0xa0cc44['length'];_0x371c8c<_0x211869;_0x371c8c++){_0x1c4619+='%'+('00'+_0xa0cc44['charCodeAt'](_0x371c8c)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1c4619);};_0x1cc8['AfYcfO']=_0x5d3e2b,_0x1cc8['HcZwyr']={},_0x1cc8['ZsfdBZ']=!![];}const _0x32066e=_0xfbcf9c[0x0],_0x3ac34f=_0x2d1c49+_0x32066e,_0x3b2262=_0x1cc8['HcZwyr'][_0x3ac34f];return!_0x3b2262?(_0x1cc8e9=_0x1cc8['AfYcfO'](_0x1cc8e9),_0x1cc8['HcZwyr'][_0x3ac34f]=_0x1cc8e9):_0x1cc8e9=_0x3b2262,_0x1cc8e9;}function isNumericCol(_0x59e03a){const _0x585142=_0x79fca,_0x6cae02=columnTypeOf(_0x59e03a);if(_0x6cae02===_0x585142(0x7b)||_0x6cae02===_0x585142(0xaa)||_0x6cae02==='PgReal')return!![];return/^(numeric|decimal|double|real)\b/['test'](sqlTypeOf(_0x59e03a));}function isBooleanCol(_0x43d140){const _0x2d22a7=_0x79fca;return columnTypeOf(_0x43d140)===_0x2d22a7(0x97)||_0x43d140['type']===_0x2d22a7(0x8e)||sqlTypeOf(_0x43d140)[_0x2d22a7(0x8f)](_0x2d22a7(0x8e));}function numberPrecision(_0x58c973){const _0x3751d2=_0x79fca;if(isIntegerCol(_0x58c973))return 0x0;if(typeof _0x58c973[_0x3751d2(0xa1)]===_0x3751d2(0x94))return _0x58c973[_0x3751d2(0xa1)];return 0x2;}export function mergeByProp(_0x4b8d48,_0x2cfb90){const _0x45287f=_0x79fca,_0x4753f8=_0x2cfb90[_0x45287f(0x86)](_0x8e8b37=>Boolean(_0x8e8b37[_0x45287f(0x87)])),_0x31edba=_0x2cfb90['filter'](_0x138bc6=>!_0x138bc6[_0x45287f(0x87)]&&_0x138bc6[_0x45287f(0x73)]),_0x288c11=new Map(_0x4753f8[_0x45287f(0x89)](_0x3c7e2c=>[String(_0x3c7e2c[_0x45287f(0x87)]),_0x3c7e2c])),_0x2866d8=new Set(_0x31edba[_0x45287f(0x89)](_0x17019d=>String(_0x17019d[_0x45287f(0x73)]))),_0x3ad967=new Set(),_0x3baea7=[];for(const _0xbc346e of _0x4b8d48){if(!_0xbc346e[_0x45287f(0x87)]&&_0xbc346e[_0x45287f(0x73)]){if(_0x2866d8[_0x45287f(0x85)](String(_0xbc346e[_0x45287f(0x73)])))continue;_0x3baea7[_0x45287f(0x83)](_0xbc346e);continue;}if(!_0xbc346e['prop'])continue;const _0x11dc32=String(_0xbc346e[_0x45287f(0x87)]),_0x48e2bb=_0x288c11[_0x45287f(0xa9)](_0x11dc32);_0x48e2bb?(_0x3baea7['push']({..._0xbc346e,..._0x48e2bb}),_0x3ad967['add'](_0x11dc32)):_0x3baea7[_0x45287f(0x83)](_0xbc346e);}for(const _0x593b86 of _0x4753f8){const _0x2bdbc6=String(_0x593b86[_0x45287f(0x87)]);if(!_0x3ad967['has'](_0x2bdbc6))_0x3baea7[_0x45287f(0x83)](_0x593b86);}return _0x3baea7[_0x45287f(0x83)](..._0x31edba),_0x3baea7;}function _0xfbcf(){const _0x49dcff=['mti4ngrZtMHOzW','AgfZrgvMyxvSDa','BNvSBgfIBgu','BNvTyMvY','nZq1ndi0CvDZzhrz','C2vSzwn0','ugDcB29SzwfU','y3jLyxrLvgLTzq','EwvZx25Vx251BwjLCG','DgvZDa','zNvUy3rPB24','y29TBwvUDa','ugDtBwfSBeLUDa','otC4DvL5reri','BMfTzxnWywnL','nJi1mxHjruDiCW','C2nHBgu','zwrPDa','y29SB3i','EwvZx25Vx2jVB2XLyw4','DMfSDwu','mZuYnJu4n0DdBuf2uW','BgfIzwW','C2vSzwn0Aw9U','z2v0','ugDeB3vIBgvqCMvJAxnPB24','nta2ntv6tuLeCum','C3DPDgnO','ugDtBwfSBfnLCMLHBa','Aw5WDxq','mJKWoffAD09sza','C3fSvhLWzq','zgvSzxrLvgLTzq','Dgv4DgfYzwe','DM0TC3DPDgnO','DhLWzq','AwDUB3jLrMLLBgrZ','neTyzenrAq','CMLNAhq','DxbKyxrLvgLTzq','ugDtzxjPywW','C3rHDhvZ','mtzps25iqui','ugDoDw1LCMLJ','AxnbCNjHEq','ugDcAwDjBNq','C3rYAw5N','y29SDw1UCW','ChjVCgvYDhLoyw1L','zgLJDa','mJGZnZKZmgLSu0rfEa','ChvZAa','ntm1DeDRyw9A','AgfZ','zMLSDgvY','ChjVCa','ntK1mJG0z3rVA3Pc','BwfW','ywrK','CMvXDwLYzwq','Dg9mB3DLCKnHC2u','C291CMnL','yM9VBgvHBG','C3rHCNrZv2L0Aa','DgvUyw50swq'];_0xfbcf=function(){return _0x49dcff;};return _0xfbcf();}export function sortRequiredFirst(_0x29d78e){const _0x2abd68=_0x79fca,_0x4889ec=[],_0x15cef0=[];for(const _0x2a387f of _0x29d78e){_0x2a387f[_0x2abd68(0x8b)]===!![]||typeof _0x2a387f[_0x2abd68(0x8b)]===_0x2abd68(0x9b)?_0x4889ec[_0x2abd68(0x83)](_0x2a387f):_0x15cef0[_0x2abd68(0x83)](_0x2a387f);}return[..._0x4889ec,..._0x15cef0];}export function buildAutoUpsertItems(_0x5993e2,_0x598a99={}){const _0x5f4815=_0x79fca,_0x1da60c=new Set([...UPSERT_BUILTIN_IGNORE,..._0x598a99[_0x5f4815(0x74)]||[]]),_0x373dc5=[];for(const _0x48af96 of epsColumns(_0x5993e2)){const _0x487b7f=_0x48af96[_0x5f4815(0x80)];if(_0x1da60c['has'](_0x487b7f))continue;const _0x4dc13f=_0x48af96[_0x5f4815(0x9c)]||_0x487b7f,_0x5cf8ec=dictKeyOf(_0x48af96),_0x1ad0e5=_0x48af96[_0x5f4815(0x93)]===![]&&_0x48af96[_0x5f4815(0x92)]!==!![],_0x29c6c4={'prop':_0x487b7f,'label':_0x4dc13f,'span':0xc,..._0x1ad0e5?{'required':!![]}:{}};if(_0x487b7f==='status'){const _0x1c35ea=_0x5cf8ec||_0x5f4815(0x79);isSwitchDict(_0x1c35ea)?_0x373dc5[_0x5f4815(0x83)](switchFormItem(_0x29c6c4,_0x1c35ea,switchDefaultValue(_0x1c35ea))):_0x373dc5[_0x5f4815(0x83)]({..._0x29c6c4,'type':_0x5f4815(0x96),'dict':_0x1c35ea,'value':0x1});continue;}if(_0x5cf8ec){isSwitchDict(_0x5cf8ec)?_0x373dc5[_0x5f4815(0x83)](switchFormItem(_0x29c6c4,_0x5cf8ec,switchDefaultValue(_0x5cf8ec))):_0x373dc5[_0x5f4815(0x83)]({..._0x29c6c4,'type':_0x5f4815(0x96),'dict':_0x5cf8ec,'value':0x0});continue;}if(isTextCol(_0x48af96)){_0x373dc5['push']({..._0x29c6c4,'type':_0x5f4815(0x71),'span':0xc});continue;}if(isBooleanCol(_0x48af96)){_0x373dc5[_0x5f4815(0x83)]({..._0x29c6c4,'type':'switch','value':![],'component':{'props':()=>mapDictOptions(_0x5f4815(0xa4))},'dict':'yes_no_boolean'});continue;}if(isIntegerCol(_0x48af96)||isNumericCol(_0x48af96)){const _0xfb0be6=numberPrecision(_0x48af96);_0x373dc5['push']({..._0x29c6c4,'type':_0x5f4815(0x94),'component':{'props':{'type':_0x5f4815(0x94),'precision':_0xfb0be6,'controls':![]}}});continue;}_0x373dc5[_0x5f4815(0x83)]({..._0x29c6c4,'type':_0x5f4815(0xae)});}return _0x373dc5;}export function buildAutoTableColumns(_0x4ea308,_0x258bef={}){const _0x343f45=_0x79fca,_0x14a743=new Set([...TABLE_BUILTIN_IGNORE,..._0x258bef['ignoreFields']||[]]),_0x4eaed8=[];!_0x14a743[_0x343f45(0x85)](_0x343f45(0xa8))&&_0x4eaed8[_0x343f45(0x83)]({'type':_0x343f45(0xa8),'width':0x32});for(const _0xd9a5fe of epsColumns(_0x4ea308)){const _0x40acc7=_0xd9a5fe[_0x343f45(0x80)];if(_0x14a743[_0x343f45(0x85)](_0x40acc7))continue;const _0x329b5b=_0xd9a5fe[_0x343f45(0x9c)]||_0x40acc7,_0x572987=dictKeyOf(_0xd9a5fe);if(_0x40acc7===_0x343f45(0x79)){const _0x32a7a4=_0x572987||_0x343f45(0x79);isSwitchDict(_0x32a7a4)?_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'width':0x50,'fixed':_0x343f45(0x76),'component':{'name':_0x343f45(0x72),'props':()=>mapDictOptions(_0x32a7a4)}}):_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'width':0x64,'fixed':_0x343f45(0x76),'dict':()=>mapDictOptions(_0x32a7a4)});continue;}if(_0x572987&&isSwitchDict(_0x572987)){_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'width':0x50,'component':{'name':_0x343f45(0x72),'props':()=>mapDictOptions(_0x572987)}});continue;}if(_0x40acc7==='id'){_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'width':0x50});continue;}if(_0x40acc7===_0x343f45(0x98)){_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'width':0xa0});continue;}if(_0x572987){_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'minWidth':0x78,'dict':()=>mapDictOptions(_0x572987)});continue;}if(isTextCol(_0xd9a5fe)){_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'minWidth':0xa0,'showOverflowTooltip':!![]});continue;}_0x4eaed8[_0x343f45(0x83)]({'prop':_0x40acc7,'label':_0x329b5b,'minWidth':0x78});}return!_0x14a743[_0x343f45(0x85)]('op')&&_0x4eaed8[_0x343f45(0x83)]({'type':'op','buttons':[_0x343f45(0xa2),'delete']}),_0x4eaed8;}