vome-core 0.0.26 → 0.0.31
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/components/vm-action-btn.vue +35 -8
- package/dist/admin/components/vm-aside-list-item.vue +18 -6
- package/dist/admin/components/vm-card-grid.vue +3 -2
- package/dist/admin/components/vm-card-head.vue +45 -0
- package/dist/admin/components/vm-card-meta.vue +22 -0
- package/dist/admin/components/vm-card-title.vue +56 -0
- package/dist/admin/components/vm-card.vue +72 -2
- package/dist/admin/components/vm-clamp-text.vue +39 -0
- package/dist/admin/components/vm-icon-btn.vue +88 -0
- package/dist/admin/components/vm-inline-search.vue +60 -0
- package/dist/admin/components/vm-page-tabs.vue +93 -0
- package/dist/admin/components/vm-split-layout.vue +36 -15
- package/dist/admin/components/vm-thumb.vue +49 -0
- package/dist/admin/config/plugin-dev.js +1 -1
- package/dist/admin/crud/components/vm-form-hint.vue +40 -22
- package/dist/admin/crud/components/vm-kv-row.vue +51 -0
- package/dist/admin/crud/components/vm-tag-list.vue +43 -17
- package/dist/admin/crud/components/vm-toggle-switch.vue +84 -0
- 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 +3 -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.js +1 -1
- package/dist/admin/crud/validate.js +1 -1
- package/dist/admin/crud/vm-import-btn.vue +686 -0
- package/dist/admin/crud/vm-toolbar.vue +16 -0
- package/dist/admin/directives/perm.js +1 -1
- package/dist/admin/hooks/useUpload.js +1 -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.d.ts +18 -0
- package/dist/admin/lib/import-excel.js +1 -0
- 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/router/index.js +13 -3
- package/dist/client/vite-plugin-eps.d.ts +3 -3
- package/dist/client/vite-plugin-eps.js +6 -2
- package/dist/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/excel.d.ts +10 -0
- package/dist/shared/excel.js +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/tree.js +1 -1
- package/dist/src/core/index.d.ts +1 -1
- package/dist/src/orm/import-excel.d.ts +31 -0
- package/dist/src/routing/index.d.ts +1 -0
- package/dist/src/routing/public-routes.d.ts +6 -0
- package/dist/src/server/index.d.ts +2 -2
- package/dist/src/shared/excel.d.ts +10 -0
- package/dist/src/shared/index.d.ts +1 -1
- package/dist/typings/routing/crud.d.ts +5 -0
- package/package.json +8 -3
- package/src/shared/excel.d.ts +10 -0
- package/src/shared/excel.ts +77 -0
- package/src/shared/index.ts +4 -0
- package/dist/admin/crud/components/vm-json-viewer.vue +0 -147
package/dist/shared/excel.d.ts
CHANGED
|
@@ -3,8 +3,18 @@ export type ExcelColumn = {
|
|
|
3
3
|
label: string;
|
|
4
4
|
};
|
|
5
5
|
export type ExcelFormatCell = (prop: string, row: Record<string, unknown>) => string;
|
|
6
|
+
/** 导入模板排除的自动字段(实体公共列) */
|
|
7
|
+
export declare const IMPORT_SKIP_FIELDS: readonly ["id", "createTime", "updateTime", "deletedAt", "tenantId"];
|
|
8
|
+
export declare function isImportSkipField(name: string): boolean;
|
|
6
9
|
/** 二维表 → xlsx 二进制 */
|
|
7
10
|
export declare function buildExcelBuffer(columns: ExcelColumn[], rows: Record<string, unknown>[], formatCell?: ExcelFormatCell): Uint8Array;
|
|
11
|
+
/** 仅表头的导入模板 */
|
|
12
|
+
export declare function buildImportTemplateBuffer(columns: ExcelColumn[]): Uint8Array;
|
|
13
|
+
/**
|
|
14
|
+
* 解析 xlsx:首行表头 → 行对象。
|
|
15
|
+
* 表头可为字段名或中文 label(通过 columns 反查 prop)。
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseExcelBuffer(data: ArrayBuffer | Uint8Array, columns?: ExcelColumn[]): Record<string, unknown>[];
|
|
8
18
|
export declare function excelFilename(name: string): string;
|
|
9
19
|
/** Service 下载响应头 */
|
|
10
20
|
export declare function excelResponseHeaders(filename: string): {
|
package/dist/shared/excel.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
const _0x10ef60=_0x161f;(function(_0x3f81f3,_0x220aa3){const _0x468791=_0x161f,_0x1b959a=_0x3f81f3();while(!![]){try{const _0x1a1eca=parseInt(_0x468791(0xd5))/0x1*(-parseInt(_0x468791(0xca))/0x2)+-parseInt(_0x468791(0xbf))/0x3*(-parseInt(_0x468791(0xc8))/0x4)+-parseInt(_0x468791(0xc9))/0x5*(-parseInt(_0x468791(0xc3))/0x6)+-parseInt(_0x468791(0xc5))/0x7*(-parseInt(_0x468791(0xdd))/0x8)+-parseInt(_0x468791(0xe0))/0x9*(-parseInt(_0x468791(0xe2))/0xa)+-parseInt(_0x468791(0xcf))/0xb*(parseInt(_0x468791(0xda))/0xc)+parseInt(_0x468791(0xcd))/0xd;if(_0x1a1eca===_0x220aa3)break;else _0x1b959a['push'](_0x1b959a['shift']());}catch(_0x5af43c){_0x1b959a['push'](_0x1b959a['shift']());}}}(_0x85e2,0x2711b));import*as _0x4d8189 from'xlsx';export const IMPORT_SKIP_FIELDS=['id','createTime',_0x10ef60(0xcc),_0x10ef60(0xc7),_0x10ef60(0xce)];function _0x161f(_0xedca10,_0xd03ba4){_0xedca10=_0xedca10-0xbf;const _0x85e208=_0x85e2();let _0x161f6c=_0x85e208[_0xedca10];if(_0x161f['TpFUuL']===undefined){var _0x1a7a40=function(_0x4abdfc){const _0x2cf070='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4d8189='',_0x247c84='';for(let _0x4f482e=0x0,_0x5b264f,_0xd4d7cd,_0x159033=0x0;_0xd4d7cd=_0x4abdfc['charAt'](_0x159033++);~_0xd4d7cd&&(_0x5b264f=_0x4f482e%0x4?_0x5b264f*0x40+_0xd4d7cd:_0xd4d7cd,_0x4f482e++%0x4)?_0x4d8189+=String['fromCharCode'](0xff&_0x5b264f>>(-0x2*_0x4f482e&0x6)):0x0){_0xd4d7cd=_0x2cf070['indexOf'](_0xd4d7cd);}for(let _0x293f0c=0x0,_0x5f15e5=_0x4d8189['length'];_0x293f0c<_0x5f15e5;_0x293f0c++){_0x247c84+='%'+('00'+_0x4d8189['charCodeAt'](_0x293f0c)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x247c84);};_0x161f['IKdCGO']=_0x1a7a40,_0x161f['QGcCCN']={},_0x161f['TpFUuL']=!![];}const _0x4b0a27=_0x85e208[0x0],_0x519a9e=_0xedca10+_0x4b0a27,_0x2e432d=_0x161f['QGcCCN'][_0x519a9e];return!_0x2e432d?(_0x161f6c=_0x161f['IKdCGO'](_0x161f6c),_0x161f['QGcCCN'][_0x519a9e]=_0x161f6c):_0x161f6c=_0x2e432d,_0x161f6c;}export function isImportSkipField(_0x247c84){const _0xa4d9ec=_0x10ef60;return IMPORT_SKIP_FIELDS[_0xa4d9ec(0xcb)](_0x247c84);}export function buildExcelBuffer(_0x4f482e,_0x5b264f,_0xd4d7cd){const _0x39c625=_0x10ef60,_0x159033=_0x4f482e[_0x39c625(0xd9)](_0x368b73=>_0x368b73[_0x39c625(0xd4)]||_0x368b73[_0x39c625(0xdb)]),_0x293f0c=_0x5b264f[_0x39c625(0xd9)](_0x45a2d8=>_0x4f482e[_0x39c625(0xd9)](_0x332434=>{const _0x3d2d72=_0x39c625;if(_0xd4d7cd)return _0xd4d7cd(_0x332434[_0x3d2d72(0xdb)],_0x45a2d8);const _0x105a37=_0x45a2d8[_0x332434[_0x3d2d72(0xdb)]];if(_0x105a37==null)return'';return String(_0x105a37);})),_0x5f15e5=_0x4d8189[_0x39c625(0xc1)]['aoa_to_sheet']([_0x159033,..._0x293f0c]),_0x28949c=_0x4d8189[_0x39c625(0xc1)][_0x39c625(0xde)]();return _0x4d8189[_0x39c625(0xc1)][_0x39c625(0xd0)](_0x28949c,_0x5f15e5,_0x39c625(0xc6)),_0x4d8189[_0x39c625(0xd1)](_0x28949c,{'bookType':_0x39c625(0xd3),'type':'array'});}export function buildImportTemplateBuffer(_0x5649cc){return buildExcelBuffer(_0x5649cc,[]);}function _0x85e2(){const _0x450ac8=['BwfW','mtu2D3PbrvjP','ChjVCa','C2v0','mZq0oeTyDuLbyq','yM9VA19UzxC','yxjYyxK','mJK3BLrAqwHq','C3rYAw5N','nJa2nZbtAuHptNG','m2POq1riuq','BgvUz3rO','DxrPBhm','zw5KC1DPDgG','mte0DMD1uevL','lNHSC3G','mtmXnMnqCKH0vG','u2HLzxqX','zgvSzxrLzef0','mtu5ndy4A1zHsMPH','mJq1nJv5z0L6ueO','mMD3zxDRzq','Aw5JBhvKzxm','DxbKyxrLvgLTzq','mZeYmJe5n1vhzhLXrq','DgvUyw50swq','mtuZnti3zMrPqMHb','yM9VA19HChbLBMrFC2HLzxq','D3jPDgu','C2HLzxrFDg9FANnVBG','EgXZEa','BgfIzwW','mZeZmtu0z0jLq0vx','DhjPBq','u2HLzxroyw1LCW','ChvZAa'];_0x85e2=function(){return _0x450ac8;};return _0x85e2();}export function parseExcelBuffer(_0xeb7d10,_0x5cf00c){const _0x2e8bac=_0x10ef60,_0x30b1c4=_0x4d8189['read'](_0xeb7d10,{'type':_0x2e8bac(0xdf),'cellDates':!![]}),_0x1b26f6=_0x30b1c4[_0x2e8bac(0xd7)][0x0];if(!_0x1b26f6)return[];const _0x4af2bc=_0x30b1c4['Sheets'][_0x1b26f6];if(!_0x4af2bc)return[];const _0x247736=_0x4d8189['utils'][_0x2e8bac(0xd2)](_0x4af2bc,{'header':0x1,'defval':'','raw':![]});if(!_0x247736[_0x2e8bac(0xc0)])return[];const _0x47d9a4=(_0x247736[0x0]||[])[_0x2e8bac(0xd9)](_0x35482f=>String(_0x35482f??'')[_0x2e8bac(0xd6)]()),_0x145d43=new Map();if(_0x5cf00c?.[_0x2e8bac(0xc0)])for(const _0x59a24d of _0x5cf00c){_0x145d43[_0x2e8bac(0xdc)](_0x59a24d['label']['trim'](),_0x59a24d[_0x2e8bac(0xdb)]),_0x145d43[_0x2e8bac(0xdc)](_0x59a24d[_0x2e8bac(0xdb)],_0x59a24d['prop']);}const _0x215b75=_0x47d9a4[_0x2e8bac(0xd9)](_0x3e7052=>{if(!_0x3e7052)return'';return _0x145d43['get'](_0x3e7052)||_0x3e7052;}),_0xe58b99=[];for(let _0x14e2b9=0x1;_0x14e2b9<_0x247736[_0x2e8bac(0xc0)];_0x14e2b9++){const _0x1ccced=_0x247736[_0x14e2b9]||[],_0x40835e={};let _0x4379bc=!![];for(let _0x388c29=0x0;_0x388c29<_0x215b75[_0x2e8bac(0xc0)];_0x388c29++){const _0x311713=_0x215b75[_0x388c29];if(!_0x311713)continue;let _0x3c36c4=_0x1ccced[_0x388c29];if(_0x3c36c4==null||_0x3c36c4===''){_0x40835e[_0x311713]=_0x3c36c4==null?null:'';continue;}_0x4379bc=![],typeof _0x3c36c4===_0x2e8bac(0xe1)?_0x40835e[_0x311713]=_0x3c36c4[_0x2e8bac(0xd6)]():_0x40835e[_0x311713]=_0x3c36c4;}if(!_0x4379bc)_0xe58b99[_0x2e8bac(0xd8)](_0x40835e);}return _0xe58b99;}export function excelFilename(_0xc820ca){const _0x1f8ee6=_0x10ef60;return _0xc820ca[_0x1f8ee6(0xc2)](_0x1f8ee6(0xc4))?_0xc820ca:_0xc820ca+_0x1f8ee6(0xc4);}export function excelResponseHeaders(_0x4c6e3e){const _0x8de03f=excelFilename(_0x4c6e3e);return{'Content-Type':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','Content-Disposition':'attachment;\x20filename*=UTF-8\x27\x27'+encodeURIComponent(_0x8de03f)};}
|
package/dist/shared/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
(function(_0x57e8a1,_0x1e9c3f){var _0x4527b4=_0x4176,_0x102d91=_0x57e8a1();while(!![]){try{var _0x416010=parseInt(_0x4527b4(0xe2))/0x1+-parseInt(_0x4527b4(0xe5))/0x2+-parseInt(_0x4527b4(0xe3))/0x3*(-parseInt(_0x4527b4(0xe1))/0x4)+parseInt(_0x4527b4(0xe4))/0x5*(parseInt(_0x4527b4(0xe9))/0x6)+-parseInt(_0x4527b4(0xe7))/0x7*(-parseInt(_0x4527b4(0xea))/0x8)+parseInt(_0x4527b4(0xe8))/0x9+-parseInt(_0x4527b4(0xe6))/0xa;if(_0x416010===_0x1e9c3f)break;else _0x102d91['push'](_0x102d91['shift']());}catch(_0x43f42b){_0x102d91['push'](_0x102d91['shift']());}}}(_0xf032,0xb8062));export{merge}from'../comm/merge';export{deepTree,flattenTree}from'./tree';function _0x4176(_0x55c5ea,_0x2fd416){_0x55c5ea=_0x55c5ea-0xe1;var _0xf032a4=_0xf032();var _0x4176c7=_0xf032a4[_0x55c5ea];if(_0x4176['XOTugH']===undefined){var _0x4762a0=function(_0x2eaa76){var _0x2e86d2='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x454716='',_0x3f054a='';for(var _0x7a4840=0x0,_0x4d5b13,_0x421d45,_0x44adba=0x0;_0x421d45=_0x2eaa76['charAt'](_0x44adba++);~_0x421d45&&(_0x4d5b13=_0x7a4840%0x4?_0x4d5b13*0x40+_0x421d45:_0x421d45,_0x7a4840++%0x4)?_0x454716+=String['fromCharCode'](0xff&_0x4d5b13>>(-0x2*_0x7a4840&0x6)):0x0){_0x421d45=_0x2e86d2['indexOf'](_0x421d45);}for(var _0x4d980b=0x0,_0x297c34=_0x454716['length'];_0x4d980b<_0x297c34;_0x4d980b++){_0x3f054a+='%'+('00'+_0x454716['charCodeAt'](_0x4d980b)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3f054a);};_0x4176['TZCbuB']=_0x4762a0,_0x4176['bNnUdr']={},_0x4176['XOTugH']=!![];}var _0x4b3f54=_0xf032a4[0x0],_0x5511ae=_0x55c5ea+_0x4b3f54,_0x1bc64e=_0x4176['bNnUdr'][_0x5511ae];return!_0x1bc64e?(_0x4176c7=_0x4176['TZCbuB'](_0x4176c7),_0x4176['bNnUdr'][_0x5511ae]=_0x4176c7):_0x4176c7=_0x1bc64e,_0x4176c7;}export{RES_CODE}from'../routing/base';function _0xf032(){var _0x2c4d30=['nJzhD2ThBhK','ntmWotm2ohzgD3fxAq','mZC1mJeWogDxu3fkDa','ndG0nZC3swPJCNjg','m3LIuwT5uW','mJy0ode1wfLqyKvX','mJuZmJm1off5we9ptW','mtu5ndy4ntbvrfbszMS','n1bqv2TMvq','oduXmdaYmLLyCfz3DG'];_0xf032=function(){return _0x2c4d30;};return _0xf032();}export{buildExcelBuffer,buildImportTemplateBuffer,parseExcelBuffer,excelFilename,excelResponseHeaders,IMPORT_SKIP_FIELDS,isImportSkipField}from'./excel';
|
package/dist/shared/tree.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _0x355ad9=_0x4768;function _0x9c22(){const _0x496796=['odeWnwXYs2ngBW','n21cwK54qG','z2v0','nZeWmdqWtgvHBLfS','ndG4zNfyBenM','y2HPBgrYzw4','yxnJ','AgfZ','mta5ntCYm1zXB0juqG','mtq0mZa0oeDWqNrNwG','C29YDa','otrnywDuvhK','mtiXmdm1z2riq3rA','ChvZAa','B3jKzxjoDw0','BgvUz3rO','ntq2owzKtMP2Ba','mJaZntyZmgnvveTTzG'];_0x9c22=function(){return _0x496796;};return _0x9c22();}function _0x4768(_0x4aa468,_0x38c7c5){_0x4aa468=_0x4aa468-0x15a;const _0x9c22da=_0x9c22();let _0x4768cf=_0x9c22da[_0x4aa468];if(_0x4768['zVkJvB']===undefined){var _0x23febf=function(_0xa93285){const _0x2d40a1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x41981b='',_0x506415='';for(let _0x1aca74=0x0,_0x58a30f,_0x103432,_0x3445e9=0x0;_0x103432=_0xa93285['charAt'](_0x3445e9++);~_0x103432&&(_0x58a30f=_0x1aca74%0x4?_0x58a30f*0x40+_0x103432:_0x103432,_0x1aca74++%0x4)?_0x41981b+=String['fromCharCode'](0xff&_0x58a30f>>(-0x2*_0x1aca74&0x6)):0x0){_0x103432=_0x2d40a1['indexOf'](_0x103432);}for(let _0xadf200=0x0,_0x4b1ba0=_0x41981b['length'];_0xadf200<_0x4b1ba0;_0xadf200++){_0x506415+='%'+('00'+_0x41981b['charCodeAt'](_0xadf200)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x506415);};_0x4768['LhMqvC']=_0x23febf,_0x4768['pBVtMn']={},_0x4768['zVkJvB']=!![];}const _0x555a75=_0x9c22da[0x0],_0x1ee987=_0x4aa468+_0x555a75,_0x20b64f=_0x4768['pBVtMn'][_0x1ee987];return!_0x20b64f?(_0x4768cf=_0x4768['LhMqvC'](_0x4768cf),_0x4768['pBVtMn'][_0x1ee987]=_0x4768cf):_0x4768cf=_0x20b64f,_0x4768cf;}(function(_0x47966b,_0x12fa0c){const _0x4a1fa6=_0x4768,_0x3a1ba3=_0x47966b();while(!![]){try{const _0x2ad09e=parseInt(_0x4a1fa6(0x16a))/0x1*(parseInt(_0x4a1fa6(0x165))/0x2)+parseInt(_0x4a1fa6(0x166))/0x3+-parseInt(_0x4a1fa6(0x15e))/0x4*(parseInt(_0x4a1fa6(0x15a))/0x5)+parseInt(_0x4a1fa6(0x163))/0x6*(parseInt(_0x4a1fa6(0x15b))/0x7)+-parseInt(_0x4a1fa6(0x15d))/0x8+parseInt(_0x4a1fa6(0x162))/0x9+-parseInt(_0x4a1fa6(0x16b))/0xa;if(_0x2ad09e===_0x12fa0c)break;else _0x3a1ba3['push'](_0x3a1ba3['shift']());}catch(_0x367b41){_0x3a1ba3['push'](_0x3a1ba3['shift']());}}}(_0x9c22,0x2965b));export function deepTree(_0x41981b,_0x506415=_0x355ad9(0x160)){const _0x96b666=_0x355ad9,_0x1aca74=new Map();for(const _0x3445e9 of _0x41981b){if(_0x3445e9['id']==null)continue;_0x1aca74['set'](_0x3445e9['id'],{..._0x3445e9,'children':[]});}const _0x58a30f=[];for(const _0xadf200 of _0x1aca74['values']()){const _0x4b1ba0=_0xadf200['parentId'];_0x4b1ba0!=null&&_0x4b1ba0!==''&&_0x1aca74[_0x96b666(0x161)](_0x4b1ba0)?_0x1aca74[_0x96b666(0x15c)](_0x4b1ba0)['children'][_0x96b666(0x167)](_0xadf200):_0x58a30f[_0x96b666(0x167)](_0xadf200);}const _0x103432=_0x104c60=>{const _0x371fc3=_0x96b666;_0x104c60[_0x371fc3(0x164)]((_0x42c2b4,_0x17f2c6)=>{const _0x2e6650=_0x371fc3,_0x4609eb=_0x42c2b4[_0x2e6650(0x168)]??0x0,_0x2c3375=_0x17f2c6[_0x2e6650(0x168)]??0x0,_0x5f5ca3=_0x506415==='desc'?_0x2c3375-_0x4609eb:_0x4609eb-_0x2c3375;return _0x5f5ca3||Number(_0x42c2b4['id'])-Number(_0x17f2c6['id']);});for(const _0x911da3 of _0x104c60)if(_0x911da3[_0x371fc3(0x15f)]?.['length'])_0x103432(_0x911da3[_0x371fc3(0x15f)]);};return _0x103432(_0x58a30f),_0x58a30f;}export function flattenTree(_0x2b8760,_0x2e3575,_0x25a1ab=0x0,_0x2186b7=[]){const _0x12935f=_0x355ad9;for(const _0x4c8f4a of _0x2b8760){const _0x3b67f0=_0x4c8f4a[_0x12935f(0x15f)]||[];_0x2186b7[_0x12935f(0x167)]({..._0x4c8f4a,'depth':_0x25a1ab,'hasChildren':_0x3b67f0[_0x12935f(0x169)]>0x0});if(_0x3b67f0[_0x12935f(0x169)]&&_0x2e3575[_0x12935f(0x161)](_0x4c8f4a['id']))flattenTree(_0x3b67f0,_0x2e3575,_0x25a1ab+0x1,_0x2186b7);}return _0x2186b7;}
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { scanFiles } from '../comm/scan';
|
|
|
11
11
|
export type { ScanOptions } from '../comm/scan';
|
|
12
12
|
export { getEnv } from '../comm/env';
|
|
13
13
|
export { Logger, CommException, isCommException } from '../logger';
|
|
14
|
-
export { Eps, isEpsEnabled, BaseController, RES_CODE, Controller, Get, Post, Put, Delete, Patch, Body, Query, Param, Public, Perms, IgnorePerms, Use, listControllers, } from '../routing';
|
|
14
|
+
export { Eps, isEpsEnabled, BaseController, RES_CODE, Controller, Get, Post, Put, Delete, Patch, Body, Query, Param, Public, Perms, IgnorePerms, Use, listControllers, isPublicHttpRoute, clearPublicRouteCache, collectPublicRouteKeys, } from '../routing';
|
|
15
15
|
export type { ApiFail, ApiResult, ApiSuccess, ControllerCrudOptions, ControllerMeta, ControllerRouteMeta, ControllerSide, CrudApi, CrudBeforeFn, CrudRegistrar, EpsApiItem, EpsColumn, EpsEntity, EpsModuleMap, HttpMethod, InsertParamFn, QueryExtendFn, QueryExtendQb, QueryFieldRef, QueryJoin, QueryJoinType, QueryOp, QueryOpCtx, QueryWhereFn, QueryWhereResult, ResCode, RouteMiddleware, RouteParamMeta, RouteParamSource, } from '../routing';
|
|
16
16
|
export { DbStore, baseColumns, BASE_COLUMN_COMMENTS, entitySchemas, columnComments, getColumnComments, syncColumnCommentsToPg, readCrudConfig, resolveSoftDelete, resolveUpsert, Repository, getRepository, InjectRepository, BaseService, q, compactWhere, needsAdvancedQuery, buildQueryOp, queryWithOp, attachCrudRoutes, isTenantEnabled, noTenant, normalizeHost, resolveTenantScope, tableHasDepartmentId, resolveDataScope, applyDataScopeWhere, applyRowScopes, noDataScope, } from '../orm';
|
|
17
17
|
export type { CrudUpsertMode, CrudModifyType, CrudWriteOptions, CrudTrashQueryOptions, CrudDeleteOptions, PageQuery, PagePagination, PageResult, } from '../orm';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type PgTable } from 'drizzle-orm/pg-core';
|
|
2
|
+
import { type ExcelColumn } from '../shared/excel';
|
|
3
|
+
import type { BaseService } from './service';
|
|
4
|
+
/** 从表唯一索引 / unique 约束提取键集合(用于导入 upsert) */
|
|
5
|
+
export declare function listUniqueKeySets(table: PgTable): string[][];
|
|
6
|
+
/** 导入模板列:实体业务字段,排除自动生成列 */
|
|
7
|
+
export declare function buildImportExcelColumns(table: PgTable, ignoreProperty?: string[]): ExcelColumn[];
|
|
8
|
+
export declare function buildEntityImportTemplate(table: PgTable, ignoreProperty?: string[]): Uint8Array;
|
|
9
|
+
export type ImportRowResult = {
|
|
10
|
+
inserted: number;
|
|
11
|
+
updated: number;
|
|
12
|
+
failed: Array<{
|
|
13
|
+
row: number;
|
|
14
|
+
message: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* 按唯一键 upsert 导入行:
|
|
19
|
+
* 1. 有 id 且存在 → 更新
|
|
20
|
+
* 2. 否则按 unique 索引匹配 → 更新
|
|
21
|
+
* 3. 否则新增
|
|
22
|
+
*/
|
|
23
|
+
export declare function importEntityRows(svc: BaseService, table: PgTable, rows: Record<string, unknown>[], options?: {
|
|
24
|
+
uniqueKeys?: string[];
|
|
25
|
+
ignoreProperty?: string[];
|
|
26
|
+
}): Promise<ImportRowResult>;
|
|
27
|
+
/** 从上传文件解析并导入 */
|
|
28
|
+
export declare function importEntityExcel(svc: BaseService, table: PgTable, fileData: ArrayBuffer | Uint8Array, options?: {
|
|
29
|
+
uniqueKeys?: string[];
|
|
30
|
+
ignoreProperty?: string[];
|
|
31
|
+
}): Promise<ImportRowResult>;
|
|
@@ -4,5 +4,6 @@ export { BaseController, RES_CODE } from './base';
|
|
|
4
4
|
export type { ApiFail, ApiResult, ApiSuccess, ResCode } from './base';
|
|
5
5
|
export { Controller, Get, Post, Put, Delete, Patch, Body, Query, Param, Public, Perms, IgnorePerms, Use, } from './decorators';
|
|
6
6
|
export { listControllers, type ControllerMeta, type ControllerRouteMeta, type ControllerSide, type HttpMethod, type RouteParamMeta, type RouteParamSource, } from './metadata';
|
|
7
|
+
export { clearPublicRouteCache, collectPublicRouteKeys, isPublicHttpRoute, } from './public-routes';
|
|
7
8
|
export type { ControllerCrudOptions, CrudApi, CrudBeforeFn, InsertParamFn, QueryExtendFn, QueryExtendQb, QueryFieldRef, QueryJoin, QueryJoinType, QueryOp, QueryOpCtx, QueryWhereFn, QueryWhereResult, RouteMiddleware, } from '../../typings/routing/crud';
|
|
8
9
|
export type { CrudRegistrar } from './register';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** 收集所有 @Public() 路由(METHOD + 全路径) */
|
|
2
|
+
export declare function collectPublicRouteKeys(): Set<string>;
|
|
3
|
+
/** 是否为 @Public() 开放接口(懒加载缓存;路由注册完成后调用) */
|
|
4
|
+
export declare function isPublicHttpRoute(method: string, path: string): boolean;
|
|
5
|
+
/** 测试或热重载后清空缓存 */
|
|
6
|
+
export declare function clearPublicRouteCache(): void;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* 导入时加载宿主 `src/config`;扫描 / IoC / 路由注册在 `App.start()` 中执行。
|
|
5
5
|
* 宿主须:`import 'reflect-metadata'`,并开启 `experimentalDecorators` + `emitDecoratorMetadata`。
|
|
6
6
|
*/
|
|
7
|
-
export { App, appendInjectMeta, BaseController, Body, CommException, Context, Controller, Delete, Eps, isEpsEnabled, Get, getEnv, Inject, Ioc, isCommException, listControllers, listProviders, Logger, Param, Patch, Post, Provide, Public, Perms, IgnorePerms, Put, Query, RES_CODE, scanFiles, ScopeEnum, Use, vome, VomeConfig, DbStore, baseColumns, BASE_COLUMN_COMMENTS, entitySchemas, columnComments, getColumnComments, syncColumnCommentsToPg, Repository, getRepository, InjectRepository, BaseService, q, attachCrudRoutes, isTenantEnabled, noTenant, normalizeHost, resolveTenantScope, tableHasDepartmentId, resolveDataScope, applyDataScopeWhere, applyRowScopes, noDataScope, BasePlugin, loadPluginClass, readPluginScript, pDataPath, pPluginPath, pModulesPath, pModulePath, ModuleRegistry, loadModuleHandlers, microApps, createModuleGateway, defineAuthMacro, } from '../core';
|
|
8
|
-
export { buildExcelBuffer, excelFilename, excelResponseHeaders, } from '../shared/excel';
|
|
7
|
+
export { App, appendInjectMeta, BaseController, Body, CommException, Context, Controller, Delete, Eps, isEpsEnabled, Get, getEnv, Inject, Ioc, isCommException, listControllers, isPublicHttpRoute, listProviders, Logger, Param, Patch, Post, Provide, Public, Perms, IgnorePerms, Put, Query, RES_CODE, scanFiles, ScopeEnum, Use, vome, VomeConfig, DbStore, baseColumns, BASE_COLUMN_COMMENTS, entitySchemas, columnComments, getColumnComments, syncColumnCommentsToPg, Repository, getRepository, InjectRepository, BaseService, q, attachCrudRoutes, isTenantEnabled, noTenant, normalizeHost, resolveTenantScope, tableHasDepartmentId, resolveDataScope, applyDataScopeWhere, applyRowScopes, noDataScope, BasePlugin, loadPluginClass, readPluginScript, pDataPath, pPluginPath, pModulesPath, pModulePath, ModuleRegistry, loadModuleHandlers, microApps, createModuleGateway, defineAuthMacro, } from '../core';
|
|
8
|
+
export { buildExcelBuffer, buildImportTemplateBuffer, parseExcelBuffer, excelFilename, excelResponseHeaders, IMPORT_SKIP_FIELDS, isImportSkipField, } from '../shared/excel';
|
|
9
9
|
export type { ExcelColumn, ExcelFormatCell } from '../shared/excel';
|
|
10
10
|
export type { ApiFail, ApiResult, ApiSuccess, ClassToken, ContextData, ControllerCrudOptions, ControllerMeta, ControllerRouteMeta, ControllerSide, CrudApi, CrudBeforeFn, CrudRegistrar, CrudUpsertMode, CrudModifyType, CrudWriteOptions, CrudTrashQueryOptions, CrudDeleteOptions, PageQuery, PagePagination, PageResult, PluginManifest, PluginInfo, PluginPayload, PluginCheckResult, ModuleRouteDef, ModuleMenuDef, ModuleManifest, ModuleHandlerCtx, ModuleHandler, ModuleInstalled, EpsApiItem, EpsColumn, EpsEntity, EpsModuleMap, HttpMethod, InjectionToken, InjectMeta, InsertParamFn, ProvideOptions, ProviderToken, QueryExtendFn, QueryExtendQb, QueryFieldRef, QueryJoin, QueryJoinType, QueryOp, QueryOpCtx, QueryWhereFn, QueryWhereResult, ResCode, RouteMiddleware, RouteParamMeta, RouteParamSource, ScanOptions, } from '../core';
|
|
11
11
|
/** 与 package.json version 同步 */
|
|
@@ -3,8 +3,18 @@ export type ExcelColumn = {
|
|
|
3
3
|
label: string;
|
|
4
4
|
};
|
|
5
5
|
export type ExcelFormatCell = (prop: string, row: Record<string, unknown>) => string;
|
|
6
|
+
/** 导入模板排除的自动字段(实体公共列) */
|
|
7
|
+
export declare const IMPORT_SKIP_FIELDS: readonly ["id", "createTime", "updateTime", "deletedAt", "tenantId"];
|
|
8
|
+
export declare function isImportSkipField(name: string): boolean;
|
|
6
9
|
/** 二维表 → xlsx 二进制 */
|
|
7
10
|
export declare function buildExcelBuffer(columns: ExcelColumn[], rows: Record<string, unknown>[], formatCell?: ExcelFormatCell): Uint8Array;
|
|
11
|
+
/** 仅表头的导入模板 */
|
|
12
|
+
export declare function buildImportTemplateBuffer(columns: ExcelColumn[]): Uint8Array;
|
|
13
|
+
/**
|
|
14
|
+
* 解析 xlsx:首行表头 → 行对象。
|
|
15
|
+
* 表头可为字段名或中文 label(通过 columns 反查 prop)。
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseExcelBuffer(data: ArrayBuffer | Uint8Array, columns?: ExcelColumn[]): Record<string, unknown>[];
|
|
8
18
|
export declare function excelFilename(name: string): string;
|
|
9
19
|
/** Service 下载响应头 */
|
|
10
20
|
export declare function excelResponseHeaders(filename: string): {
|
|
@@ -6,5 +6,5 @@ export { deepTree, flattenTree } from './tree';
|
|
|
6
6
|
export type { Loose } from '../../typings/common';
|
|
7
7
|
export type { PageQuery, PagePagination, PageResult } from '../../typings/comm/page';
|
|
8
8
|
export { RES_CODE, type ResCode, type ApiSuccess, type ApiFail, type ApiResult, } from '../routing/base';
|
|
9
|
-
export { buildExcelBuffer, excelFilename, excelResponseHeaders, } from './excel';
|
|
9
|
+
export { buildExcelBuffer, buildImportTemplateBuffer, parseExcelBuffer, excelFilename, excelResponseHeaders, IMPORT_SKIP_FIELDS, isImportSkipField, } from './excel';
|
|
10
10
|
export type { ExcelColumn, ExcelFormatCell } from './excel';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vome-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"description": "Vome framework — shared + Bun/Elysia server + Vue admin",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -94,7 +94,8 @@
|
|
|
94
94
|
"clsx": ">=2.0.0",
|
|
95
95
|
"tailwind-merge": ">=2.0.0",
|
|
96
96
|
"dompurify": ">=3.0.0",
|
|
97
|
-
"marked": ">=9.0.0"
|
|
97
|
+
"marked": ">=9.0.0",
|
|
98
|
+
"vite": ">=5.0.0"
|
|
98
99
|
},
|
|
99
100
|
"peerDependenciesMeta": {
|
|
100
101
|
"drizzle-orm": {
|
|
@@ -129,6 +130,9 @@
|
|
|
129
130
|
},
|
|
130
131
|
"marked": {
|
|
131
132
|
"optional": true
|
|
133
|
+
},
|
|
134
|
+
"vite": {
|
|
135
|
+
"optional": true
|
|
132
136
|
}
|
|
133
137
|
},
|
|
134
138
|
"devDependencies": {
|
|
@@ -138,7 +142,8 @@
|
|
|
138
142
|
"elysia": "latest",
|
|
139
143
|
"javascript-obfuscator": "^5.4.7",
|
|
140
144
|
"reflect-metadata": "^0.2.2",
|
|
141
|
-
"typescript": "latest"
|
|
145
|
+
"typescript": "latest",
|
|
146
|
+
"vite": "^6.0.7"
|
|
142
147
|
},
|
|
143
148
|
"dependencies": {
|
|
144
149
|
"@bogeychan/elysia-logger": "^0.1.10",
|
package/src/shared/excel.d.ts
CHANGED
|
@@ -3,8 +3,18 @@ export type ExcelColumn = {
|
|
|
3
3
|
label: string;
|
|
4
4
|
};
|
|
5
5
|
export type ExcelFormatCell = (prop: string, row: Record<string, unknown>) => string;
|
|
6
|
+
/** 导入模板排除的自动字段(实体公共列) */
|
|
7
|
+
export declare const IMPORT_SKIP_FIELDS: readonly ["id", "createTime", "updateTime", "deletedAt", "tenantId"];
|
|
8
|
+
export declare function isImportSkipField(name: string): boolean;
|
|
6
9
|
/** 二维表 → xlsx 二进制 */
|
|
7
10
|
export declare function buildExcelBuffer(columns: ExcelColumn[], rows: Record<string, unknown>[], formatCell?: ExcelFormatCell): Uint8Array;
|
|
11
|
+
/** 仅表头的导入模板 */
|
|
12
|
+
export declare function buildImportTemplateBuffer(columns: ExcelColumn[]): Uint8Array;
|
|
13
|
+
/**
|
|
14
|
+
* 解析 xlsx:首行表头 → 行对象。
|
|
15
|
+
* 表头可为字段名或中文 label(通过 columns 反查 prop)。
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseExcelBuffer(data: ArrayBuffer | Uint8Array, columns?: ExcelColumn[]): Record<string, unknown>[];
|
|
8
18
|
export declare function excelFilename(name: string): string;
|
|
9
19
|
/** Service 下载响应头 */
|
|
10
20
|
export declare function excelResponseHeaders(filename: string): {
|
package/src/shared/excel.ts
CHANGED
|
@@ -10,6 +10,19 @@ export type ExcelFormatCell = (
|
|
|
10
10
|
row: Record<string, unknown>,
|
|
11
11
|
) => string
|
|
12
12
|
|
|
13
|
+
/** 导入模板排除的自动字段(实体公共列) */
|
|
14
|
+
export const IMPORT_SKIP_FIELDS = [
|
|
15
|
+
'id',
|
|
16
|
+
'createTime',
|
|
17
|
+
'updateTime',
|
|
18
|
+
'deletedAt',
|
|
19
|
+
'tenantId',
|
|
20
|
+
] as const
|
|
21
|
+
|
|
22
|
+
export function isImportSkipField(name: string) {
|
|
23
|
+
return (IMPORT_SKIP_FIELDS as readonly string[]).includes(name)
|
|
24
|
+
}
|
|
25
|
+
|
|
13
26
|
/** 二维表 → xlsx 二进制 */
|
|
14
27
|
export function buildExcelBuffer(
|
|
15
28
|
columns: ExcelColumn[],
|
|
@@ -31,6 +44,70 @@ export function buildExcelBuffer(
|
|
|
31
44
|
return XLSX.write(book, { bookType: 'xlsx', type: 'array' }) as Uint8Array
|
|
32
45
|
}
|
|
33
46
|
|
|
47
|
+
/** 仅表头的导入模板 */
|
|
48
|
+
export function buildImportTemplateBuffer(columns: ExcelColumn[]): Uint8Array {
|
|
49
|
+
return buildExcelBuffer(columns, [])
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 解析 xlsx:首行表头 → 行对象。
|
|
54
|
+
* 表头可为字段名或中文 label(通过 columns 反查 prop)。
|
|
55
|
+
*/
|
|
56
|
+
export function parseExcelBuffer(
|
|
57
|
+
data: ArrayBuffer | Uint8Array,
|
|
58
|
+
columns?: ExcelColumn[],
|
|
59
|
+
): Record<string, unknown>[] {
|
|
60
|
+
const book = XLSX.read(data, { type: 'array', cellDates: true })
|
|
61
|
+
const name = book.SheetNames[0]
|
|
62
|
+
if (!name) return []
|
|
63
|
+
const sheet = book.Sheets[name]
|
|
64
|
+
if (!sheet) return []
|
|
65
|
+
const aoa = XLSX.utils.sheet_to_json(sheet, {
|
|
66
|
+
header: 1,
|
|
67
|
+
defval: '',
|
|
68
|
+
raw: false,
|
|
69
|
+
}) as unknown[][]
|
|
70
|
+
if (!aoa.length) return []
|
|
71
|
+
|
|
72
|
+
const headerRow = (aoa[0] || []).map((h) => String(h ?? '').trim())
|
|
73
|
+
const labelToProp = new Map<string, string>()
|
|
74
|
+
if (columns?.length) {
|
|
75
|
+
for (const c of columns) {
|
|
76
|
+
labelToProp.set(c.label.trim(), c.prop)
|
|
77
|
+
labelToProp.set(c.prop, c.prop)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const props = headerRow.map((h) => {
|
|
82
|
+
if (!h) return ''
|
|
83
|
+
return labelToProp.get(h) || h
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const rows: Record<string, unknown>[] = []
|
|
87
|
+
for (let i = 1; i < aoa.length; i++) {
|
|
88
|
+
const line = aoa[i] || []
|
|
89
|
+
const row: Record<string, unknown> = {}
|
|
90
|
+
let empty = true
|
|
91
|
+
for (let c = 0; c < props.length; c++) {
|
|
92
|
+
const prop = props[c]
|
|
93
|
+
if (!prop) continue
|
|
94
|
+
let val: unknown = line[c]
|
|
95
|
+
if (val == null || val === '') {
|
|
96
|
+
row[prop] = val == null ? null : ''
|
|
97
|
+
continue
|
|
98
|
+
}
|
|
99
|
+
empty = false
|
|
100
|
+
if (typeof val === 'string') {
|
|
101
|
+
row[prop] = val.trim()
|
|
102
|
+
} else {
|
|
103
|
+
row[prop] = val
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!empty) rows.push(row)
|
|
107
|
+
}
|
|
108
|
+
return rows
|
|
109
|
+
}
|
|
110
|
+
|
|
34
111
|
export function excelFilename(name: string) {
|
|
35
112
|
return name.endsWith('.xlsx') ? name : `${name}.xlsx`
|
|
36
113
|
}
|
package/src/shared/index.ts
CHANGED
|
@@ -14,7 +14,11 @@ export {
|
|
|
14
14
|
} from '../routing/base'
|
|
15
15
|
export {
|
|
16
16
|
buildExcelBuffer,
|
|
17
|
+
buildImportTemplateBuffer,
|
|
18
|
+
parseExcelBuffer,
|
|
17
19
|
excelFilename,
|
|
18
20
|
excelResponseHeaders,
|
|
21
|
+
IMPORT_SKIP_FIELDS,
|
|
22
|
+
isImportSkipField,
|
|
19
23
|
} from './excel'
|
|
20
24
|
export type { ExcelColumn, ExcelFormatCell } from './excel'
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<template v-if="mode === 'code'">
|
|
3
|
-
<vm-json-code :model-value="modelValue" :empty="empty" />
|
|
4
|
-
</template>
|
|
5
|
-
<template v-else>
|
|
6
|
-
<vm-text-link
|
|
7
|
-
v-if="hasContent"
|
|
8
|
-
:label="label"
|
|
9
|
-
@click="open = true"
|
|
10
|
-
/>
|
|
11
|
-
<span v-else class="vm-json-viewer is-empty">—</span>
|
|
12
|
-
</template>
|
|
13
|
-
|
|
14
|
-
<Teleport to="body">
|
|
15
|
-
<div
|
|
16
|
-
v-if="open"
|
|
17
|
-
class="vm-json-viewer__dialog"
|
|
18
|
-
role="dialog"
|
|
19
|
-
aria-modal="true"
|
|
20
|
-
@click.self="open = false"
|
|
21
|
-
>
|
|
22
|
-
<header class="vm-json-viewer__head">
|
|
23
|
-
<span class="vm-json-viewer__title">{{ title }}</span>
|
|
24
|
-
<div class="vm-json-viewer__actions">
|
|
25
|
-
<vm-copy-btn :text="body" size="sm" label="复制" />
|
|
26
|
-
<button type="button" class="vm-json-viewer__close" title="关闭" @click="open = false">
|
|
27
|
-
<i class="ri-close-line" />
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
</header>
|
|
31
|
-
<div class="vm-json-viewer__body vm-scroll">
|
|
32
|
-
<vm-json-code :model-value="modelValue" :empty="empty" />
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</Teleport>
|
|
36
|
-
</template>
|
|
37
|
-
|
|
38
|
-
<script setup lang="ts">
|
|
39
|
-
import { computed, ref } from 'vue'
|
|
40
|
-
import { hasJsonContent, prettyJson } from '../../lib/json'
|
|
41
|
-
import VmJsonCode from './vm-json-code.vue'
|
|
42
|
-
import VmTextLink from './vm-text-link.vue'
|
|
43
|
-
import VmCopyBtn from './vm-copy-btn.vue'
|
|
44
|
-
|
|
45
|
-
defineOptions({ name: 'vm-json-viewer' })
|
|
46
|
-
|
|
47
|
-
const props = withDefaults(
|
|
48
|
-
defineProps<{
|
|
49
|
-
modelValue?: unknown
|
|
50
|
-
title?: string
|
|
51
|
-
label?: string
|
|
52
|
-
/** button 打开浮层;code 仅渲染代码块(upsert fill) */
|
|
53
|
-
mode?: 'button' | 'code'
|
|
54
|
-
empty?: string
|
|
55
|
-
}>(),
|
|
56
|
-
{
|
|
57
|
-
title: 'JSON',
|
|
58
|
-
label: '查看',
|
|
59
|
-
mode: 'button',
|
|
60
|
-
empty: '(空)',
|
|
61
|
-
},
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
const open = ref(false)
|
|
65
|
-
const hasContent = computed(() => hasJsonContent(props.modelValue))
|
|
66
|
-
const body = computed(() => prettyJson(props.modelValue, props.empty))
|
|
67
|
-
</script>
|
|
68
|
-
|
|
69
|
-
<style lang="scss" scoped>
|
|
70
|
-
.vm-json-viewer.is-empty {
|
|
71
|
-
color: var(--muted-foreground);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.vm-json-viewer__dialog {
|
|
75
|
-
position: fixed;
|
|
76
|
-
inset: 0;
|
|
77
|
-
z-index: 5200;
|
|
78
|
-
display: flex;
|
|
79
|
-
flex-direction: column;
|
|
80
|
-
padding: 24px;
|
|
81
|
-
background: color-mix(in srgb, var(--foreground) 42%, transparent);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.vm-json-viewer__head {
|
|
85
|
-
display: flex;
|
|
86
|
-
flex-shrink: 0;
|
|
87
|
-
align-items: center;
|
|
88
|
-
justify-content: space-between;
|
|
89
|
-
gap: 12px;
|
|
90
|
-
margin: 0 auto;
|
|
91
|
-
width: min(960px, 100%);
|
|
92
|
-
padding: 12px 16px;
|
|
93
|
-
border-radius: 14px 14px 0 0;
|
|
94
|
-
background: var(--card);
|
|
95
|
-
border: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
|
|
96
|
-
border-bottom: none;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.vm-json-viewer__title {
|
|
100
|
-
font-size: 14px;
|
|
101
|
-
font-weight: 700;
|
|
102
|
-
color: var(--foreground);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.vm-json-viewer__actions {
|
|
106
|
-
display: inline-flex;
|
|
107
|
-
align-items: center;
|
|
108
|
-
gap: 8px;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.vm-json-viewer__close {
|
|
112
|
-
display: inline-flex;
|
|
113
|
-
width: 32px;
|
|
114
|
-
height: 32px;
|
|
115
|
-
align-items: center;
|
|
116
|
-
justify-content: center;
|
|
117
|
-
border: none;
|
|
118
|
-
border-radius: 8px;
|
|
119
|
-
background: transparent;
|
|
120
|
-
color: var(--muted-foreground);
|
|
121
|
-
cursor: pointer;
|
|
122
|
-
|
|
123
|
-
&:hover {
|
|
124
|
-
background: var(--muted);
|
|
125
|
-
color: var(--foreground);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.vm-json-viewer__body {
|
|
130
|
-
flex: 1;
|
|
131
|
-
min-height: 0;
|
|
132
|
-
margin: 0 auto;
|
|
133
|
-
width: min(960px, 100%);
|
|
134
|
-
display: flex;
|
|
135
|
-
flex-direction: column;
|
|
136
|
-
border-radius: 0 0 14px 14px;
|
|
137
|
-
background: var(--card);
|
|
138
|
-
border: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
|
|
139
|
-
border-top: none;
|
|
140
|
-
overflow: hidden;
|
|
141
|
-
|
|
142
|
-
:deep(.vm-json-code) {
|
|
143
|
-
border-radius: 0;
|
|
144
|
-
background: var(--muted);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
</style>
|