vome-core 0.0.66 → 0.0.68
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.
- package/dist/admin/config/plugin-dev.js +1 -1
- package/dist/admin/crud/components/vm-json-editor.vue +32 -3
- package/dist/admin/crud/components/vm-richtext.vue +5 -4
- package/dist/admin/crud/config.js +1 -1
- package/dist/admin/crud/confirm.js +1 -1
- package/dist/admin/crud/dict.js +1 -1
- package/dist/admin/crud/index.d.ts +1 -1
- package/dist/admin/crud/index.js +1 -1
- package/dist/admin/crud/key.js +1 -1
- package/dist/admin/crud/mitt.js +1 -1
- package/dist/admin/crud/plugins.js +1 -1
- package/dist/admin/crud/span.js +1 -1
- package/dist/admin/crud/style.d.ts +37 -0
- package/dist/admin/crud/style.js +1 -1
- package/dist/admin/crud/validate.js +1 -1
- package/dist/admin/crud/vm-add-btn.vue +2 -1
- package/dist/admin/crud/vm-adv-search.vue +5 -4
- package/dist/admin/crud/vm-crud.vue +14 -9
- package/dist/admin/crud/vm-export-btn.vue +2 -1
- package/dist/admin/crud/vm-import-btn.vue +2 -1
- package/dist/admin/crud/vm-multi-delete-btn.vue +2 -1
- package/dist/admin/crud/vm-pagination.vue +16 -7
- package/dist/admin/crud/vm-refresh-btn.vue +2 -1
- package/dist/admin/crud/vm-search-key.vue +3 -2
- package/dist/admin/crud/vm-search.vue +29 -20
- package/dist/admin/crud/vm-table.vue +65 -22
- package/dist/admin/crud/vm-toolbar.vue +12 -13
- package/dist/admin/crud/vm-upsert.vue +12 -6
- package/dist/admin/directives/perm.js +1 -1
- package/dist/admin/hooks/useUpload.js +1 -1
- package/dist/admin/index.d.ts +1 -1
- package/dist/admin/index.js +6 -1
- package/dist/admin/lib/browser.js +1 -1
- package/dist/admin/lib/cn.js +1 -1
- package/dist/admin/lib/dialog-float.js +1 -1
- package/dist/admin/lib/export-excel.js +1 -1
- package/dist/admin/lib/file-preview.js +1 -1
- package/dist/admin/lib/import-excel.js +1 -1
- package/dist/admin/lib/json.js +1 -1
- package/dist/admin/lib/menu.js +1 -1
- package/dist/admin/lib/tree.js +1 -1
- package/dist/admin/lib/upload.js +1 -1
- package/dist/admin/lib/video-frame.js +1 -1
- package/dist/admin/styles/base.css +33 -0
- package/dist/ai/index.js +28761 -0
- package/dist/ai.d.ts +1 -0
- package/dist/client/base.js +5 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/locale-store.d.ts +59 -0
- package/dist/client/locale-store.js +159 -0
- package/dist/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/excel.js +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/locale-json.js +1 -0
- package/dist/shared/tree.js +1 -1
- package/dist/src/ai/adapters/anthropic-gemini.d.ts +5 -0
- package/dist/src/ai/adapters/auth-headers.d.ts +4 -0
- package/dist/src/ai/adapters/index.d.ts +3 -0
- package/dist/src/ai/adapters/openai-compatible.d.ts +4 -0
- package/dist/src/ai/call-log-helpers.d.ts +13 -0
- package/dist/src/ai/index.d.ts +10 -0
- package/dist/src/ai/normalize.d.ts +18 -0
- package/dist/src/ai/sse.d.ts +13 -0
- package/dist/src/ai/transport.d.ts +16 -0
- package/dist/src/ai/types.d.ts +194 -0
- package/dist/src/core/index.d.ts +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/orm/index.d.ts +1 -1
- package/dist/src/server/index.d.ts +3 -1
- package/dist/src/shared/index.d.ts +1 -0
- package/dist/src/shared/locale-json.d.ts +7 -0
- package/dist/typings/routing/eps.d.ts +2 -0
- package/package.json +7 -2
- package/src/shared/index.ts +6 -0
- package/src/shared/locale-json.ts +79 -0
- package/typings/admin/comm/crud.d.ts +13 -0
- package/typings/admin/comm/crud.ts +13 -0
- package/typings/admin/comm/eps.d.ts +3 -0
- package/typings/admin/comm/eps.ts +3 -0
- package/typings/admin/comm/request.d.ts +1 -1
- package/typings/admin/comm/request.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(_0x115a82,_0x2dd0d0){const _0x275540=_0x2df2,_0x5b478b=_0x115a82();while(!![]){try{const _0x16cfa4=-parseInt(_0x275540(0x169))/0x1+parseInt(_0x275540(0x165))/0x2*(parseInt(_0x275540(0x16f))/0x3)+-parseInt(_0x275540(0x167))/0x4*(-parseInt(_0x275540(0x157))/0x5)+parseInt(_0x275540(0x155))/0x6+-parseInt(_0x275540(0x170))/0x7*(parseInt(_0x275540(0x174))/0x8)+parseInt(_0x275540(0x156))/0x9+-parseInt(_0x275540(0x15c))/0xa;if(_0x16cfa4===_0x2dd0d0)break;else _0x5b478b['push'](_0x5b478b['shift']());}catch(_0x2d1df2){_0x5b478b['push'](_0x5b478b['shift']());}}}(_0x104d,0x3f447));function _0x104d(){const _0x1f914f=['odi0ntq4yM5Xze1i','BgfIzwW','nta5nJuYAfLhDer4','BgvUz3rO','DhjPBq','C3rYAw5N','zNvUy3rPB24','B2jQzwn0','mtm0otqWmeHmCu1OBG','n2zhs1zXzG','5PYa5AsAia','AgLKzgvU','DMfSAwrHDg9Y','mtC4nda4B0LyD0LQ','AxnbCNjHEq','5lIn6io95lI656M6','mtmYnJqYnK1Ns1D0BW','ndeWntuYmuPgCKjyrW','mtbMte1yr3y','Cgf0DgvYBG','ChvZAa','CMvXDwLYzwq','DgvZDa','nZq4mJe4mgn2zeHdwa','ios4QUwTL+ESPG','Bwf4','BwvZC2fNzq','6iEZ5Bcria','ChjVCa','CNvSzxm','5Qc85BYp5lIn5Q2J56gU','BwLU','mKfqzezNsq','5QcH6AQm5AsX6lsL'];_0x104d=function(){return _0x1f914f;};return _0x104d();}function _0x2df2(_0x3c0ad0,_0x3b7094){_0x3c0ad0=_0x3c0ad0-0x153;const _0x104d1e=_0x104d();let _0x2df22a=_0x104d1e[_0x3c0ad0];if(_0x2df2['QItQmv']===undefined){var _0x5b9646=function(_0x3e2f30){const _0x43ec02='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x20c5f3='',_0x29dc0b='';for(let _0xffb7a0=0x0,_0x43f6e8,_0x12aa85,_0x378634=0x0;_0x12aa85=_0x3e2f30['charAt'](_0x378634++);~_0x12aa85&&(_0x43f6e8=_0xffb7a0%0x4?_0x43f6e8*0x40+_0x12aa85:_0x12aa85,_0xffb7a0++%0x4)?_0x20c5f3+=String['fromCharCode'](0xff&_0x43f6e8>>(-0x2*_0xffb7a0&0x6)):0x0){_0x12aa85=_0x43ec02['indexOf'](_0x12aa85);}for(let _0x3182d7=0x0,_0x5e6c2c=_0x20c5f3['length'];_0x3182d7<_0x5e6c2c;_0x3182d7++){_0x29dc0b+='%'+('00'+_0x20c5f3['charCodeAt'](_0x3182d7)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x29dc0b);};_0x2df2['ZMAnXy']=_0x5b9646,_0x2df2['CBedgx']={},_0x2df2['QItQmv']=!![];}const _0x76144f=_0x104d1e[0x0],_0x55e8e8=_0x3c0ad0+_0x76144f,_0x312dc2=_0x2df2['CBedgx'][_0x55e8e8];return!_0x312dc2?(_0x2df22a=_0x2df2['ZMAnXy'](_0x2df22a),_0x2df2['CBedgx'][_0x55e8e8]=_0x2df22a):_0x2df22a=_0x312dc2,_0x2df22a;}function isEmpty(_0x20c5f3){const _0x5081e3=_0x2df2;if(_0x20c5f3==null||_0x20c5f3==='')return!![];if(typeof _0x20c5f3===_0x5081e3(0x16c)&&_0x20c5f3[_0x5081e3(0x16b)]()==='')return!![];if(Array[_0x5081e3(0x153)](_0x20c5f3)&&_0x20c5f3[_0x5081e3(0x16a)]===0x0)return!![];return![];}function normalizeRules(_0x29dc0b){const _0x2a1e6f=_0x2df2,_0xffb7a0=[];_0x29dc0b[_0x2a1e6f(0x15a)]&&_0xffb7a0[_0x2a1e6f(0x159)]({'required':!![],'message':_0x29dc0b[_0x2a1e6f(0x168)]+_0x2a1e6f(0x154)});const _0x43f6e8=_0x29dc0b[_0x2a1e6f(0x162)];if(!_0x43f6e8)return _0xffb7a0;if(Array[_0x2a1e6f(0x153)](_0x43f6e8))for(const _0x12aa85 of _0x43f6e8){if(_0x12aa85&&typeof _0x12aa85===_0x2a1e6f(0x16e))_0xffb7a0[_0x2a1e6f(0x159)](_0x12aa85);}else typeof _0x43f6e8==='object'&&_0xffb7a0[_0x2a1e6f(0x159)](_0x43f6e8);return _0xffb7a0;}function isItemHidden(_0x378634,_0x3182d7){const _0x4ba97c=_0x2df2;if(typeof _0x378634[_0x4ba97c(0x172)]===_0x4ba97c(0x16d))return _0x378634[_0x4ba97c(0x172)](_0x3182d7);return Boolean(_0x378634[_0x4ba97c(0x172)]);}async function validateItem(_0x5e6c2c,_0x4f5653){const _0x249a3c=_0x2df2,_0x194024=_0x4f5653[_0x5e6c2c[_0x249a3c(0x161)]];for(const _0x5e5aa8 of normalizeRules(_0x5e6c2c)){if(_0x5e5aa8[_0x249a3c(0x15a)]&&isEmpty(_0x194024))return _0x5e5aa8['message']||_0x5e6c2c[_0x249a3c(0x168)]+_0x249a3c(0x154);if(isEmpty(_0x194024))continue;const _0x1c14ce=String(_0x194024);if(_0x5e5aa8[_0x249a3c(0x164)]!=null&&_0x1c14ce[_0x249a3c(0x16a)]<_0x5e5aa8[_0x249a3c(0x164)])return _0x5e5aa8['message']||_0x5e6c2c[_0x249a3c(0x168)]+_0x249a3c(0x160)+_0x5e5aa8[_0x249a3c(0x164)]+_0x249a3c(0x15d);if(_0x5e5aa8[_0x249a3c(0x15e)]!=null&&_0x1c14ce[_0x249a3c(0x16a)]>_0x5e5aa8['max'])return _0x5e5aa8[_0x249a3c(0x15f)]||_0x5e6c2c[_0x249a3c(0x168)]+_0x249a3c(0x171)+_0x5e5aa8[_0x249a3c(0x15e)]+_0x249a3c(0x15d);if(_0x5e5aa8[_0x249a3c(0x158)]&&!_0x5e5aa8['pattern'][_0x249a3c(0x15b)](_0x1c14ce))return _0x5e5aa8[_0x249a3c(0x15f)]||_0x5e6c2c[_0x249a3c(0x168)]+_0x249a3c(0x163);if(_0x5e5aa8[_0x249a3c(0x173)]){const _0x5e7224=await _0x5e5aa8['validator'](_0x194024,_0x4f5653);if(_0x5e7224!==!![])return _0x5e7224||_0x5e6c2c[_0x249a3c(0x168)]+_0x249a3c(0x166);}}return null;}export async function validateFormItems(_0x5181c6,_0xbc4f9c){for(const _0x2ea4a7 of _0x5181c6){if(isItemHidden(_0x2ea4a7,_0xbc4f9c))continue;const _0x2eba56=await validateItem(_0x2ea4a7,_0xbc4f9c);if(_0x2eba56)return _0x2eba56;}return null;}export async function validateFormFields(_0x2b9e7e,_0x410e39){const _0x551a5a=_0x2df2,_0x658855={};for(const _0x2dc57a of _0x2b9e7e){if(isItemHidden(_0x2dc57a,_0x410e39))continue;const _0x16e557=await validateItem(_0x2dc57a,_0x410e39);if(_0x16e557)_0x658855[_0x2dc57a[_0x551a5a(0x161)]]=_0x16e557;}return _0x658855;}export function applySetRules(_0x40f479){return _0x40f479['map'](_0x16ea7a=>{const _0x4c2753=_0x2df2;if(!_0x16ea7a[_0x4c2753(0x15a)]||_0x16ea7a['rules'])return _0x16ea7a;return{..._0x16ea7a,'rules':[{'required':!![],'message':_0x16ea7a[_0x4c2753(0x168)]+_0x4c2753(0x154)}]};});}
|
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
@click="onClick"
|
|
7
7
|
>
|
|
8
8
|
<i class="ri-add-line" />
|
|
9
|
-
{{ crud.dict.label
|
|
9
|
+
{{ crudLabel('add', crud.dict.label) }}
|
|
10
10
|
</button>
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script setup lang="ts">
|
|
14
14
|
import { computed } from 'vue'
|
|
15
15
|
import { useCrud } from './useCrud'
|
|
16
|
+
import { crudLabel } from './style'
|
|
16
17
|
|
|
17
18
|
defineOptions({ name: 'vm-add-btn' })
|
|
18
19
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="vm-adv-search">
|
|
3
3
|
<Button size="sm" variant="outline" class="h-8" @click="open = true">
|
|
4
4
|
<i class="ri-filter-3-line" />
|
|
5
|
-
{{ crud.dict.label
|
|
5
|
+
{{ crudLabel('advSearch', crud.dict.label) }}
|
|
6
6
|
</Button>
|
|
7
7
|
<Dialog :open="open" @update:open="onOpenChange">
|
|
8
8
|
<DialogContent
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
>
|
|
15
15
|
<DialogHeader class="vm-crud-shell__head">
|
|
16
16
|
<DialogTitle class="vm-crud-shell__title">
|
|
17
|
-
{{ crud.dict.label
|
|
17
|
+
{{ crudLabel('advSearch', crud.dict.label) }}
|
|
18
18
|
</DialogTitle>
|
|
19
19
|
</DialogHeader>
|
|
20
20
|
<div class="vm-crud-shell__body">
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
class="vm-crud-shell__btn is-ghost"
|
|
27
27
|
@click="reset"
|
|
28
28
|
>
|
|
29
|
-
{{ crud.dict.label
|
|
29
|
+
{{ crudLabel('reset', crud.dict.label) }}
|
|
30
30
|
</button>
|
|
31
31
|
<button
|
|
32
32
|
type="button"
|
|
33
33
|
class="vm-crud-shell__btn is-primary"
|
|
34
34
|
@click="search"
|
|
35
35
|
>
|
|
36
|
-
{{ crud.dict.label
|
|
36
|
+
{{ crudLabel('search', crud.dict.label) }}
|
|
37
37
|
</button>
|
|
38
38
|
</DialogFooter>
|
|
39
39
|
</DialogContent>
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
import { ref } from 'vue'
|
|
46
46
|
import { preventDialogOutsideClose } from '../lib/dialog-float'
|
|
47
47
|
import { useCrud } from './useCrud'
|
|
48
|
+
import { crudLabel } from './style'
|
|
48
49
|
defineOptions({ name: 'vm-adv-search' })
|
|
49
50
|
|
|
50
51
|
const props = withDefaults(
|
|
@@ -12,6 +12,7 @@ import { mergeDict, mergePermission } from './config'
|
|
|
12
12
|
import { vmConfirm } from './confirm'
|
|
13
13
|
import { CRUD_KEY, CRUD_MITT_KEY, injectCrudOptions, injectTableOptions, injectUpsertOptions } from './key'
|
|
14
14
|
import { createMitt } from './mitt'
|
|
15
|
+
import { crudLabel } from './style'
|
|
15
16
|
defineOptions({ name: 'vm-crud' })
|
|
16
17
|
|
|
17
18
|
const props = withDefaults(
|
|
@@ -283,7 +284,9 @@ async function doDelete(targets: Record<string, unknown>[], force = false) {
|
|
|
283
284
|
.map((r) => r[dict.primaryId] as string | number)
|
|
284
285
|
.filter((id) => id != null)
|
|
285
286
|
await svc.delete({ ids, force })
|
|
286
|
-
toast.success(
|
|
287
|
+
toast.success(
|
|
288
|
+
force ? crudLabel('forceDeleted', dict.label) : crudLabel('deleteSuccess', dict.label),
|
|
289
|
+
)
|
|
287
290
|
await refresh()
|
|
288
291
|
}
|
|
289
292
|
|
|
@@ -305,7 +308,9 @@ async function rowDelete(rows?: Record<string, unknown>[], force = false) {
|
|
|
305
308
|
...(payload as { ids: Array<string | number> }),
|
|
306
309
|
force: hard,
|
|
307
310
|
})
|
|
308
|
-
toast.success(
|
|
311
|
+
toast.success(
|
|
312
|
+
hard ? crudLabel('forceDeleted', dict.label) : crudLabel('deleteSuccess', dict.label),
|
|
313
|
+
)
|
|
309
314
|
await refresh()
|
|
310
315
|
return
|
|
311
316
|
}
|
|
@@ -318,13 +323,13 @@ async function rowDelete(rows?: Record<string, unknown>[], force = false) {
|
|
|
318
323
|
}
|
|
319
324
|
|
|
320
325
|
const tip = hard
|
|
321
|
-
? dict.label
|
|
322
|
-
: dict.label
|
|
326
|
+
? crudLabel('forceDeleteConfirm', dict.label)
|
|
327
|
+
: crudLabel('deleteConfirm', dict.label)
|
|
323
328
|
const ok = await vmConfirm({
|
|
324
|
-
title: hard ? '
|
|
329
|
+
title: hard ? crudLabel('forceDelete', dict.label) : crudLabel('tips', dict.label),
|
|
325
330
|
message: tip,
|
|
326
|
-
confirmText: '
|
|
327
|
-
cancelText: '
|
|
331
|
+
confirmText: crudLabel('confirm', dict.label),
|
|
332
|
+
cancelText: crudLabel('close', dict.label),
|
|
328
333
|
})
|
|
329
334
|
if (!ok) return
|
|
330
335
|
await next()
|
|
@@ -362,11 +367,11 @@ async function upsertSubmit() {
|
|
|
362
367
|
if (upsertMode.value === 'add') {
|
|
363
368
|
if (!svc.add) throw new Error('未配置 add')
|
|
364
369
|
await svc.add(data)
|
|
365
|
-
toast.success(dict.label
|
|
370
|
+
toast.success(crudLabel('saveSuccess', dict.label))
|
|
366
371
|
} else {
|
|
367
372
|
if (!svc.update) throw new Error('未配置 update')
|
|
368
373
|
await svc.update(data)
|
|
369
|
-
toast.success(dict.label
|
|
374
|
+
toast.success(crudLabel('saveSuccess', dict.label))
|
|
370
375
|
}
|
|
371
376
|
const after = async () => {
|
|
372
377
|
upsertVisible.value = false
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
type TableApi,
|
|
26
26
|
} from './key'
|
|
27
27
|
import { useCrud } from './useCrud'
|
|
28
|
+
import { crudLabel } from './style'
|
|
28
29
|
|
|
29
30
|
defineOptions({ name: 'vm-export-btn' })
|
|
30
31
|
|
|
@@ -59,7 +60,7 @@ const submitting = ref(false)
|
|
|
59
60
|
const visible = computed(() => Boolean(crud.getPermission(props.permission)))
|
|
60
61
|
|
|
61
62
|
const buttonText = computed(
|
|
62
|
-
() => props.text || crud.dict.label
|
|
63
|
+
() => props.text || crudLabel('export', crud.dict.label),
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
const exportColumns = computed(() => {
|
|
@@ -167,6 +167,7 @@ import {
|
|
|
167
167
|
uploadImportExcel,
|
|
168
168
|
} from '../lib/import-excel'
|
|
169
169
|
import { useCrud } from './useCrud'
|
|
170
|
+
import { crudLabel } from './style'
|
|
170
171
|
|
|
171
172
|
defineOptions({ name: 'vm-import-btn' })
|
|
172
173
|
|
|
@@ -215,7 +216,7 @@ const dragDepth = ref(0)
|
|
|
215
216
|
const visible = computed(() => Boolean(crud.getPermission(props.permission)))
|
|
216
217
|
|
|
217
218
|
const buttonText = computed(
|
|
218
|
-
() => props.text || crud.dict.label
|
|
219
|
+
() => props.text || crudLabel('import', crud.dict.label),
|
|
219
220
|
)
|
|
220
221
|
|
|
221
222
|
const totalPages = computed(() =>
|
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
@click="crud.rowDelete()"
|
|
8
8
|
>
|
|
9
9
|
<i class="ri-delete-bin-line" />
|
|
10
|
-
{{ crud.dict.label
|
|
10
|
+
{{ crudLabel('multiDelete', crud.dict.label) }}
|
|
11
11
|
</button>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
import { useCrud } from './useCrud'
|
|
16
|
+
import { crudLabel } from './style'
|
|
16
17
|
|
|
17
18
|
defineOptions({ name: 'vm-multi-delete-btn' })
|
|
18
19
|
const crud = useCrud()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="vm-crud-pagination">
|
|
3
|
-
<span class="vm-crud-pagination__total"
|
|
3
|
+
<span class="vm-crud-pagination__total">{{ totalText }}</span>
|
|
4
4
|
<div class="vm-crud-pagination__actions">
|
|
5
5
|
<Select
|
|
6
6
|
:model-value="String(crud.pagination.value.size)"
|
|
@@ -10,10 +10,9 @@
|
|
|
10
10
|
<SelectValue />
|
|
11
11
|
</SelectTrigger>
|
|
12
12
|
<SelectContent>
|
|
13
|
-
<SelectItem
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<SelectItem value="100">100 / 页</SelectItem>
|
|
13
|
+
<SelectItem v-for="n in pageSizes" :key="n" :value="String(n)">
|
|
14
|
+
{{ pageSizeText(n) }}
|
|
15
|
+
</SelectItem>
|
|
17
16
|
</SelectContent>
|
|
18
17
|
</Select>
|
|
19
18
|
<button
|
|
@@ -22,7 +21,7 @@
|
|
|
22
21
|
:disabled="crud.pagination.value.page <= 1"
|
|
23
22
|
@click="go(crud.pagination.value.page - 1)"
|
|
24
23
|
>
|
|
25
|
-
|
|
24
|
+
{{ crudLabel('prevPage', crud.dict.label) }}
|
|
26
25
|
</button>
|
|
27
26
|
<span class="vm-crud-pagination__page">
|
|
28
27
|
{{ crud.pagination.value.page }} / {{ totalPages }}
|
|
@@ -33,7 +32,7 @@
|
|
|
33
32
|
:disabled="crud.pagination.value.page >= totalPages"
|
|
34
33
|
@click="go(crud.pagination.value.page + 1)"
|
|
35
34
|
>
|
|
36
|
-
|
|
35
|
+
{{ crudLabel('nextPage', crud.dict.label) }}
|
|
37
36
|
</button>
|
|
38
37
|
</div>
|
|
39
38
|
</div>
|
|
@@ -42,15 +41,25 @@
|
|
|
42
41
|
<script setup lang="ts">
|
|
43
42
|
import { computed } from 'vue'
|
|
44
43
|
import { useCrud } from './useCrud'
|
|
44
|
+
import { crudFormat, crudLabel } from './style'
|
|
45
45
|
|
|
46
46
|
defineOptions({ name: 'vm-pagination' })
|
|
47
47
|
|
|
48
48
|
const crud = useCrud()
|
|
49
|
+
const pageSizes = [10, 20, 50, 100]
|
|
49
50
|
|
|
50
51
|
const totalPages = computed(() =>
|
|
51
52
|
Math.max(1, Math.ceil(crud.pagination.value.total / crud.pagination.value.size) || 1),
|
|
52
53
|
)
|
|
53
54
|
|
|
55
|
+
const totalText = computed(() =>
|
|
56
|
+
crudFormat(crudLabel('total', crud.dict.label), crud.pagination.value.total),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
function pageSizeText(n: number) {
|
|
60
|
+
return crudFormat(crudLabel('pageSize', crud.dict.label), n)
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
function go(page: number) {
|
|
55
64
|
const next = Math.min(Math.max(1, page), totalPages.value)
|
|
56
65
|
crud.pagination.value = { ...crud.pagination.value, page: next }
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button type="button" class="vm-crud-toolbar__btn is-ghost" @click="crud.refresh()">
|
|
3
3
|
<i class="ri-refresh-line" />
|
|
4
|
-
{{ crud.dict.label
|
|
4
|
+
{{ crudLabel('refresh', crud.dict.label) }}
|
|
5
5
|
</button>
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script setup lang="ts">
|
|
9
9
|
import { useCrud } from './useCrud'
|
|
10
|
+
import { crudLabel } from './style'
|
|
10
11
|
|
|
11
12
|
defineOptions({ name: 'vm-refresh-btn' })
|
|
12
13
|
const crud = useCrud()
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
<Input
|
|
4
4
|
class="vm-crud-search-key__input"
|
|
5
5
|
:model-value="keyword"
|
|
6
|
-
:placeholder="placeholder || crud.dict.label
|
|
6
|
+
:placeholder="placeholder || crudLabel('searchKey', crud.dict.label)"
|
|
7
7
|
@update:model-value="onInput"
|
|
8
8
|
@keydown.enter.prevent="search"
|
|
9
9
|
/>
|
|
10
10
|
<button type="button" class="vm-crud-search-key__btn" @click="search">
|
|
11
|
-
{{ crud.dict.label
|
|
11
|
+
{{ crudLabel('search', crud.dict.label) }}
|
|
12
12
|
</button>
|
|
13
13
|
</div>
|
|
14
14
|
</template>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
<script setup lang="ts">
|
|
17
17
|
import { ref } from 'vue'
|
|
18
18
|
import { useCrud } from './useCrud'
|
|
19
|
+
import { crudLabel } from './style'
|
|
19
20
|
|
|
20
21
|
defineOptions({ name: 'vm-search-key' })
|
|
21
22
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
@update:model-value="(v) => (form[item.prop] = coerceSelect(item, v))"
|
|
18
18
|
>
|
|
19
19
|
<SelectTrigger class="vm-crud-search__control">
|
|
20
|
-
<SelectValue :placeholder="item
|
|
20
|
+
<SelectValue :placeholder="itemPlaceholder(item)" />
|
|
21
21
|
</SelectTrigger>
|
|
22
22
|
<SelectContent>
|
|
23
23
|
<SelectItem
|
|
@@ -33,15 +33,19 @@
|
|
|
33
33
|
v-else
|
|
34
34
|
class="vm-crud-search__control"
|
|
35
35
|
:model-value="String(form[item.prop] ?? '')"
|
|
36
|
-
:placeholder="item
|
|
36
|
+
:placeholder="itemPlaceholder(item)"
|
|
37
37
|
@update:model-value="(v) => (form[item.prop] = v)"
|
|
38
38
|
@keydown.enter.prevent="search"
|
|
39
39
|
/>
|
|
40
40
|
</template>
|
|
41
41
|
</div>
|
|
42
42
|
<div v-if="inlineActions" class="vm-crud-search__actions">
|
|
43
|
-
<button type="button" class="vm-crud-search__btn is-primary" @click="search"
|
|
44
|
-
|
|
43
|
+
<button type="button" class="vm-crud-search__btn is-primary" @click="search">
|
|
44
|
+
{{ crudLabel('search', crud.dict.label) }}
|
|
45
|
+
</button>
|
|
46
|
+
<button type="button" class="vm-crud-search__btn is-ghost" @click="reset">
|
|
47
|
+
{{ crudLabel('reset', crud.dict.label) }}
|
|
48
|
+
</button>
|
|
45
49
|
<slot />
|
|
46
50
|
</div>
|
|
47
51
|
</div>
|
|
@@ -53,7 +57,13 @@ import { onBeforeUnmount } from 'vue'
|
|
|
53
57
|
import { useCrud } from './useCrud'
|
|
54
58
|
import { injectSearchOptions } from './key'
|
|
55
59
|
import { buildAutoSearchItems } from './plugins'
|
|
56
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
getCrudStyle,
|
|
62
|
+
crudLocaleRev,
|
|
63
|
+
crudLabel,
|
|
64
|
+
resolveSearchPlaceholder,
|
|
65
|
+
resolveRangePlaceholders,
|
|
66
|
+
} from './style'
|
|
57
67
|
import { resolveCrudComponent } from './registry'
|
|
58
68
|
import { service } from '../service'
|
|
59
69
|
defineOptions({ name: 'vm-search' })
|
|
@@ -85,7 +95,14 @@ function mergeSearchItems(auto: CrudSearchItem[], manual: CrudSearchItem[]) {
|
|
|
85
95
|
return merged
|
|
86
96
|
}
|
|
87
97
|
|
|
88
|
-
const items = computed(() =>
|
|
98
|
+
const items = computed(() => {
|
|
99
|
+
void crudLocaleRev.value
|
|
100
|
+
return mergeSearchItems(autoItems.value, manualItems.value)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
function itemPlaceholder(item: CrudSearchItem) {
|
|
104
|
+
return resolveSearchPlaceholder(item)
|
|
105
|
+
}
|
|
89
106
|
|
|
90
107
|
const form = reactive<Record<string, unknown>>({})
|
|
91
108
|
|
|
@@ -194,30 +211,22 @@ function resolveField(item: CrudSearchItem) {
|
|
|
194
211
|
}
|
|
195
212
|
|
|
196
213
|
function fieldProps(item: CrudSearchItem) {
|
|
197
|
-
const
|
|
214
|
+
const ph = itemPlaceholder(item)
|
|
198
215
|
const rangePlaceholders =
|
|
199
|
-
item.type === 'number-range'
|
|
200
|
-
?
|
|
201
|
-
|
|
202
|
-
endPlaceholder: `${name}最大值`,
|
|
203
|
-
}
|
|
204
|
-
: item.type === 'daterange' && name
|
|
205
|
-
? {
|
|
206
|
-
startPlaceholder: `${name}开始`,
|
|
207
|
-
endPlaceholder: `${name}结束`,
|
|
208
|
-
}
|
|
209
|
-
: {}
|
|
216
|
+
item.type === 'number-range' || item.type === 'daterange' || item.phMode === 'range'
|
|
217
|
+
? resolveRangePlaceholders(item)
|
|
218
|
+
: {}
|
|
210
219
|
return {
|
|
211
220
|
options: resolveOptions(item.options),
|
|
212
|
-
placeholder: item.placeholder || item.label,
|
|
213
221
|
refreshOnChange: false,
|
|
214
222
|
precision: item.range?.rangeType,
|
|
215
223
|
mode:
|
|
216
224
|
item.range?.rangeType === 'float' || item.range?.rangeType === 'int'
|
|
217
225
|
? item.range.rangeType
|
|
218
226
|
: undefined,
|
|
219
|
-
...rangePlaceholders,
|
|
220
227
|
...(item.component?.props || {}),
|
|
228
|
+
placeholder: ph,
|
|
229
|
+
...rangePlaceholders,
|
|
221
230
|
}
|
|
222
231
|
}
|
|
223
232
|
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
'is-auto-height': autoHeight,
|
|
7
7
|
}"
|
|
8
8
|
>
|
|
9
|
-
<div v-if="crud.loading.value" class="vm-crud-table__loading"
|
|
9
|
+
<div v-if="crud.loading.value" class="vm-crud-table__loading">
|
|
10
|
+
{{ crudLabel('loading', crud.dict.label) }}
|
|
11
|
+
</div>
|
|
10
12
|
<div ref="scrollRef" class="vm-crud-table__scroll vm-scroll">
|
|
11
13
|
<Table>
|
|
12
14
|
<TableHeader>
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
@click="onSortClick(col)"
|
|
27
29
|
>
|
|
28
30
|
<span class="vm-crud-table__th-inner">
|
|
29
|
-
{{ col
|
|
31
|
+
{{ columnLabel(col) }}
|
|
30
32
|
<i
|
|
31
33
|
v-if="isSortable(col) && col.prop"
|
|
32
34
|
class="vm-crud-table__sort"
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
class="vm-crud-table__th vm-crud-table__op"
|
|
40
42
|
:style="{ width: `${opWidth}px`, minWidth: `${opWidth}px` }"
|
|
41
43
|
>
|
|
42
|
-
{{ crud.dict.label
|
|
44
|
+
{{ crudLabel('op', crud.dict.label) }}
|
|
43
45
|
</TableHead>
|
|
44
46
|
</TableRow>
|
|
45
47
|
</TableHeader>
|
|
@@ -85,47 +87,52 @@
|
|
|
85
87
|
class="vm-crud-table__ops"
|
|
86
88
|
>
|
|
87
89
|
<Button size="xs" variant="softPrimary" @click="crud.rowRestore([row])">
|
|
88
|
-
|
|
90
|
+
{{ crudLabel('restore', crud.dict.label) }}
|
|
89
91
|
</Button>
|
|
90
92
|
<Button
|
|
91
93
|
size="xs"
|
|
92
94
|
variant="softDestructive"
|
|
93
95
|
@click="crud.rowDelete([row], true)"
|
|
94
96
|
>
|
|
95
|
-
|
|
97
|
+
{{ crudLabel('forceDelete', crud.dict.label) }}
|
|
96
98
|
</Button>
|
|
97
99
|
</div>
|
|
98
100
|
<div v-else class="vm-crud-table__ops">
|
|
99
101
|
<template v-for="(btn, bi) in resolveButtons(col, row)" :key="bi">
|
|
100
102
|
<Button
|
|
101
103
|
v-if="btn === 'edit' && crud.getPermission('update')"
|
|
104
|
+
type="button"
|
|
102
105
|
size="xs"
|
|
103
106
|
variant="softPrimary"
|
|
104
|
-
@click="crud.rowEdit(row)"
|
|
107
|
+
@click.stop="crud.rowEdit(row)"
|
|
105
108
|
>
|
|
106
|
-
{{ crud.dict.label
|
|
109
|
+
{{ crudLabel('update', crud.dict.label) }}
|
|
107
110
|
</Button>
|
|
108
111
|
<Button
|
|
109
112
|
v-else-if="btn === 'delete' && crud.getPermission('delete')"
|
|
113
|
+
type="button"
|
|
110
114
|
size="xs"
|
|
111
115
|
variant="softDestructive"
|
|
112
|
-
@click="crud.rowDelete([row])"
|
|
116
|
+
@click.stop="crud.rowDelete([row])"
|
|
113
117
|
>
|
|
114
|
-
{{ crud.dict.label
|
|
118
|
+
{{ crudLabel('delete', crud.dict.label) }}
|
|
115
119
|
</Button>
|
|
116
120
|
<Button
|
|
117
121
|
v-else-if="btn === 'info' && crud.getPermission('info')"
|
|
122
|
+
type="button"
|
|
118
123
|
size="xs"
|
|
119
124
|
variant="ghost"
|
|
120
|
-
@click="crud.rowInfo(row)"
|
|
125
|
+
@click.stop="crud.rowInfo(row)"
|
|
121
126
|
>
|
|
122
|
-
{{ crud.dict.label
|
|
127
|
+
{{ crudLabel('info', crud.dict.label) }}
|
|
123
128
|
</Button>
|
|
124
129
|
<Button
|
|
125
130
|
v-else-if="typeof btn === 'object' && !btn.hidden"
|
|
131
|
+
type="button"
|
|
126
132
|
size="xs"
|
|
133
|
+
:disabled="btn.disabled"
|
|
127
134
|
:variant="btn.variant || 'softSuccess'"
|
|
128
|
-
@click="btn.onClick(row)"
|
|
135
|
+
@click.stop="btn.onClick(row)"
|
|
129
136
|
>
|
|
130
137
|
{{ btn.label }}
|
|
131
138
|
</Button>
|
|
@@ -203,14 +210,14 @@
|
|
|
203
210
|
class="vm-crud-table__ops"
|
|
204
211
|
>
|
|
205
212
|
<Button size="xs" variant="softPrimary" @click="crud.rowRestore([row])">
|
|
206
|
-
|
|
213
|
+
{{ crudLabel('restore', crud.dict.label) }}
|
|
207
214
|
</Button>
|
|
208
215
|
<Button
|
|
209
216
|
size="xs"
|
|
210
217
|
variant="softDestructive"
|
|
211
218
|
@click="crud.rowDelete([row], true)"
|
|
212
219
|
>
|
|
213
|
-
|
|
220
|
+
{{ crudLabel('forceDelete', crud.dict.label) }}
|
|
214
221
|
</Button>
|
|
215
222
|
</div>
|
|
216
223
|
<slot v-else name="op" :row="row" />
|
|
@@ -229,7 +236,8 @@ import { useCrud } from './useCrud'
|
|
|
229
236
|
import { injectTableOptions, TABLE_API_KEY } from './key'
|
|
230
237
|
import { flattenTree } from '../lib/tree'
|
|
231
238
|
import { resolveCrudComponent } from './registry'
|
|
232
|
-
import { getCrudStyle } from './style'
|
|
239
|
+
import { getCrudStyle, crudLabel, crudT, crudLocaleRev } from './style'
|
|
240
|
+
import { findEpsEntity } from '../lib/eps'
|
|
233
241
|
defineOptions({ name: 'vm-table' })
|
|
234
242
|
|
|
235
243
|
const props = withDefaults(
|
|
@@ -284,6 +292,41 @@ const dataColumns = computed(() =>
|
|
|
284
292
|
)
|
|
285
293
|
const showSlotOp = computed(() => Boolean(slots.op) && !hasOpCol.value)
|
|
286
294
|
|
|
295
|
+
/** EPS 列 → field.{table}.{prop} */
|
|
296
|
+
function epsFieldKey(prop: string): string | undefined {
|
|
297
|
+
const ns = (crud.service as { namespace?: string } | undefined)?.namespace
|
|
298
|
+
if (!ns || !prop) return undefined
|
|
299
|
+
const entity = findEpsEntity(`/${ns}`)
|
|
300
|
+
if (!entity) return undefined
|
|
301
|
+
const cols = [
|
|
302
|
+
...((entity as { columns?: Array<{ propertyName?: string; table?: string; source?: string }> }).columns || []),
|
|
303
|
+
...((entity as { pageColumns?: Array<{ propertyName?: string; table?: string; source?: string }> }).pageColumns || []),
|
|
304
|
+
]
|
|
305
|
+
const meta =
|
|
306
|
+
cols.find((c) => c.propertyName === prop) ||
|
|
307
|
+
cols.find((c) => c.source === `a.${prop}`) ||
|
|
308
|
+
cols.find((c) => c.source?.endsWith(`.${prop}`))
|
|
309
|
+
const table = meta?.table?.trim()
|
|
310
|
+
const name = (meta?.propertyName || prop).trim()
|
|
311
|
+
if (!table || !name) return undefined
|
|
312
|
+
return `${table}.${name}`
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** 表头文案:labelKey → field.* → label / op */
|
|
316
|
+
function columnLabel(col: CrudColumn): string {
|
|
317
|
+
void crudLocaleRev.value
|
|
318
|
+
if (col.type === 'op') {
|
|
319
|
+
return col.labelKey
|
|
320
|
+
? crudT(col.labelKey, col.label || crudLabel('op', crud.dict.label))
|
|
321
|
+
: col.label || crudLabel('op', crud.dict.label)
|
|
322
|
+
}
|
|
323
|
+
const fb = col.label || col.prop || ''
|
|
324
|
+
if (col.labelKey) return crudT(col.labelKey, fb)
|
|
325
|
+
const fk = col.fieldKey || (col.prop ? epsFieldKey(col.prop) : undefined)
|
|
326
|
+
if (fk) return crudT(`field.${fk}`, fb)
|
|
327
|
+
return fb
|
|
328
|
+
}
|
|
329
|
+
|
|
287
330
|
const colSpan = computed(
|
|
288
331
|
() =>
|
|
289
332
|
dataColumns.value.length +
|
|
@@ -352,7 +395,7 @@ function onSortClick(col: CrudColumn) {
|
|
|
352
395
|
const prop = col.prop
|
|
353
396
|
let next: 'asc' | 'desc' = 'asc'
|
|
354
397
|
const current = sortState.value
|
|
355
|
-
if (current
|
|
398
|
+
if (current && current.prop === prop) {
|
|
356
399
|
next = current.order === 'asc' ? 'desc' : 'asc'
|
|
357
400
|
} else {
|
|
358
401
|
const hint = normalizeSortDir(
|
|
@@ -403,12 +446,12 @@ const ctxItems = computed<CtxMenuItem[]>(() => {
|
|
|
403
446
|
? conf
|
|
404
447
|
: ['refresh', 'check', 'edit', 'delete', 'order-asc', 'order-desc']
|
|
405
448
|
const map: Record<string, string> = {
|
|
406
|
-
refresh: crud.dict.label
|
|
407
|
-
check: crud.dict.label
|
|
408
|
-
edit: crud.dict.label
|
|
409
|
-
delete: crud.dict.label
|
|
410
|
-
'order-asc': crud.dict.label
|
|
411
|
-
'order-desc': crud.dict.label
|
|
449
|
+
refresh: crudLabel('refresh', crud.dict.label),
|
|
450
|
+
check: crudLabel('select', crud.dict.label),
|
|
451
|
+
edit: crudLabel('update', crud.dict.label),
|
|
452
|
+
delete: crudLabel('delete', crud.dict.label),
|
|
453
|
+
'order-asc': crudLabel('asc', crud.dict.label),
|
|
454
|
+
'order-desc': crudLabel('desc', crud.dict.label),
|
|
412
455
|
}
|
|
413
456
|
return keys.map((k) => ({
|
|
414
457
|
key: k,
|