@utogether/udp-core 1.0.1-beta.2 → 1.0.1-beta.20
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/build/plugins.ts +8 -1
- package/dist/{403-BBQoJwTM.js → 403-Bz5EJPLA.js} +1 -1
- package/dist/{404-BbJPSIWM.js → 404-ClOnaj9V.js} +1 -1
- package/dist/{500-BtFL9R4M.js → 500-DCUfhV7Y.js} +1 -1
- package/dist/{AuthorityInfo-DhiwCeLN.js → AuthorityInfo-q6E-js1r.js} +1 -1
- package/dist/AuthorityInfo.vue_vue_type_style_index_0_lang-BM52QDgn.js +100 -0
- package/dist/{Company-CGqmslx-.js → Company-BSShW3Q4.js} +3 -3
- package/dist/{CompanyPanel-hlDsxD-6.js → CompanyPanel-Dl8eOYLk.js} +26 -26
- package/dist/{Department-BZyJtacc.js → Department-CVIxAnUN.js} +3 -3
- package/dist/{DepartmentPanel-D-a_EBFt.js → DepartmentPanel-Sa3IDl4z.js} +25 -25
- package/dist/{DesignPanel-Bl4luWDV.js → DesignPanel-DnRipagE.js} +1 -1
- package/dist/{DesignPanel.vue_vue_type_style_index_0_lang-I8C3iGvz.js → DesignPanel.vue_vue_type_style_index_0_lang-DGNyp3Vl.js} +28 -30
- package/dist/DictView-uf2K9A1d.js +109 -0
- package/dist/InvOrganization-CG9VCpXl.js +74 -0
- package/dist/Org-W2CBN1B8.js +39 -0
- package/dist/{Preview-pHD84xqI.js → Preview-DPBxdDvW.js} +2 -2
- package/dist/{ReportDefine-DnnCNQWS.js → ReportDefine-Dsx9VM-I.js} +1 -1
- package/dist/{ReportDesign-BnI_Q4pg.js → ReportDesign-DiIGfte0.js} +43 -43
- package/dist/{ReportQuery-Dby2MmtM.js → ReportQuery-9A4Bfs1M.js} +1 -1
- package/dist/{ReportQueryFrom-Blm1N8P1.js → ReportQueryFrom-M5qLoGAa.js} +1 -1
- package/dist/{ReportQueryFrom.vue_vue_type_style_index_0_lang-CnG_Ybnt.js → ReportQueryFrom.vue_vue_type_style_index_0_lang-OQ9pUCKP.js} +1 -1
- package/dist/{ReportTemplate-D65RXRY_.js → ReportTemplate-C34FWAuK.js} +28 -28
- package/dist/{Role-eFZoTpXc.js → Role-jG3VTeOF.js} +6 -6
- package/dist/{RoleAssign-D9-Y3UNz.js → RoleAssign-BfHpCequ.js} +9 -9
- package/dist/{RolePanel-DlFw6HSf.js → RolePanel-DW9pNl0L.js} +1 -1
- package/dist/{RolePanel-CoUOc3sX.js → RolePanel-xRN2-rkk.js} +1 -1
- package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-Clwk-MHw.js → RolePanel.vue_vue_type_script_setup_true_lang-BVEHqEq9.js} +44 -38
- package/dist/RolePanel.vue_vue_type_script_setup_true_lang-C0rTy6vZ.js +132 -0
- package/dist/{ScrollPanel.vue_vue_type_style_index_0_lang-M2FQJwPU.js → ScrollPanel.vue_vue_type_style_index_0_lang-D65sJYWT.js} +23 -23
- package/dist/{Staff-DFBLCsAd.js → Staff-BqBVEjau.js} +3 -3
- package/dist/{StaffInfo-d2CK0oBA.js → StaffInfo-DXeyyEFL.js} +1 -1
- package/dist/{StaffInfo.vue_vue_type_script_setup_true_lang-4m8wK9tq.js → StaffInfo.vue_vue_type_script_setup_true_lang-Dg0iYgRf.js} +16 -16
- package/dist/{StaffPanel-D6aWLKN3.js → StaffPanel-iE-8VtUm.js} +1 -1
- package/dist/{StaffPanel.vue_vue_type_script_setup_true_lang-C7YT2CVb.js → StaffPanel.vue_vue_type_script_setup_true_lang-BrrvE1xm.js} +2 -2
- package/dist/{SysUser-BdZvYxQH.js → SysUser-DSZyW30i.js} +2 -2
- package/dist/{SysUserPanel-BIVa6LLr.js → SysUserPanel-CbiG6GQF.js} +1 -1
- package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-B1Y1fmBe.js +298 -0
- package/dist/{SystemMenu-C-5VKlHK.js → SystemMenu-DreuWY-a.js} +33 -33
- package/dist/{UserInfo-DqXCRZts.js → UserInfo-DXrzKAim.js} +1 -1
- package/dist/{UserInfo.vue_vue_type_style_index_0_lang-N3TwfpPx.js → UserInfo.vue_vue_type_style_index_0_lang-C44E20b4.js} +41 -39
- package/dist/{childView-B2lSsqS3.js → childView-VCidWgY6.js} +1 -1
- package/dist/{childView-DRUNqgjI.js → childView-k5IkJOBr.js} +1 -1
- package/dist/{childView.vue_vue_type_style_index_0_lang-B9XBDDU_.js → childView.vue_vue_type_style_index_0_lang-C6ftwwvZ.js} +1 -1
- package/dist/{childView.vue_vue_type_style_index_0_lang-oGriyFTv.js → childView.vue_vue_type_style_index_0_lang-DmG82dVB.js} +43 -43
- package/dist/{code-rule-DZC9T6cl.js → code-rule-7WQMabpW.js} +13 -15
- package/dist/core.es.js +18 -10
- package/dist/{cron-task-BJwPeA5F.js → cron-task-D1t56MSu.js} +11 -11
- package/dist/{frameView-C6wkvok-.js → frameView-CWsIFBgU.js} +1 -1
- package/dist/img/l_img.svg +1 -1
- package/dist/img/minicolors.png +0 -0
- package/dist/img/v_img.svg +1 -1
- package/dist/index-DxWAYxai.js +5495 -0
- package/dist/{layoutView-CeJBpZb_.js → layoutView-DLpHSner.js} +1564 -1559
- package/dist/{log-in-e7D5Ss1P.js → log-in-CpGqc33f.js} +5 -4
- package/dist/{log-out--RRncZhN.js → log-out-D1b4VRMZ.js} +30 -24
- package/dist/login-OjDiQmz8.js +249 -0
- package/dist/{login-log-CvVnyGi3.js → login-log-BNRXLeMi.js} +4 -3
- package/dist/{lov-view-DRF-99U4.js → lov-view-D28X6m3k.js} +5 -5
- package/dist/{menuInfo-3Sjvs9nM.js → menuInfo-DwPB6rHz.js} +1 -1
- package/dist/{menuInfo.vue_vue_type_style_index_0_lang-DrQ560nm.js → menuInfo.vue_vue_type_style_index_0_lang-l5DNRfb7.js} +34 -32
- package/dist/{pda-app-B9tn7jdv.js → pda-app-Bdms2PRY.js} +202 -188
- package/dist/{resource-BqnxbQNe.js → resource-y6SHrHoq.js} +18 -18
- package/dist/{su-welcome-VwifUK_O.js → su-welcome-D9G6EuK2.js} +118 -120
- package/dist/sys-config-DFnGHiFc.js +355 -0
- package/dist/udp-core.css +1 -9
- package/dist/utogether-MlnyYtNS.js +4 -0
- package/index.ts +17 -5
- package/package.json +1 -1
- package/src/App.vue +2 -7
- package/src/api/http.ts +1 -4
- package/src/api/index.ts +5 -3
- package/src/api/user.ts +2 -2
- package/src/components/SuCharts/src/UserInfo.vue +3 -3
- package/src/components/SuScrollTree/ScrollPanel.vue +170 -175
- package/src/components/udp/form/form.vue +109 -0
- package/src/components/udp/grid/index.vue +509 -0
- package/src/components/udp/index.ts +4 -4
- package/src/components/udp/utils.ts +405 -40
- package/src/directives/permission/index.ts +1 -1
- package/src/layout/components/lay-navbar/index.vue +9 -7
- package/src/layout/components/lay-panel/index.vue +3 -3
- package/src/layout/components/lay-search/index.vue +1 -1
- package/src/layout/components/lay-select-org/index.vue +4 -9
- package/src/layout/components/lay-sidebar/breadCrumb.vue +1 -1
- package/src/layout/components/lay-sidebar/horizontal.vue +4 -5
- package/src/layout/components/lay-sidebar/mixNav.vue +6 -4
- package/src/layout/components/lay-sidebar/sidebar-logo.vue +94 -98
- package/src/layout/components/lay-tag/index.vue +596 -625
- package/src/layout/hooks/useTag.ts +223 -233
- package/src/layout/layoutView.vue +215 -215
- package/src/layout/types.ts +3 -2
- package/src/main.ts +39 -31
- package/src/plugins/i18n/en.ts +26 -13
- package/src/plugins/i18n/zh.ts +35 -16
- package/src/plugins/vxe-table/index.ts +67 -4
- package/src/plugins/vxe-table/render.tsx +945 -817
- package/src/router/index.ts +186 -183
- package/src/router/modules/remaining.ts +1 -26
- package/src/router/utils.ts +393 -377
- package/src/store/modules/app.ts +1 -3
- package/src/store/modules/multiTags.ts +110 -109
- package/src/store/modules/permission.ts +113 -103
- package/src/store/modules/system.ts +1 -3
- package/src/style/button.scss +10 -3
- package/src/style/login.css +1 -1
- package/src/style/tailwind.css +1 -68
- package/src/style/vxetable.scss +348 -256
- package/src/utils/authority/index.ts +1 -1
- package/src/utils/index.ts +3 -1
- package/src/utils/propTypes.ts +1 -6
- package/src/views/login/login-view.vue +6 -20
- package/src/views/organization/company/CompanyPanel.vue +2 -2
- package/src/views/organization/department/DepartmentPanel.vue +269 -283
- package/src/views/organization/inv-org/InvOrganization.vue +23 -9
- package/src/views/organization/org/Org.vue +9 -5
- package/src/views/system/menu/SystemMenu.vue +183 -197
- package/src/views/system/menu/menuInfo.vue +8 -18
- package/src/views/system/role/AuthorityInfo.vue +19 -15
- package/src/views/system/role/Role.vue +1 -5
- package/src/views/system/role/RolePanel.vue +11 -2
- package/src/views/system/role/UserInfo.vue +11 -9
- package/src/views/system/role-assign/RoleAssign.vue +2 -2
- package/src/views/system/role-assign/RolePanel.vue +12 -9
- package/src/views/system/sys/sys-config.vue +66 -21
- package/src/views/system/sysUser/SysUserPanel.vue +44 -43
- package/src/views/uapp/pda/pda-app.vue +48 -16
- package/src/views/udev/coderule/code-rule.vue +120 -121
- package/src/views/udev/dict/DictView.vue +16 -4
- package/src/views/udev/dict/childView.vue +8 -8
- package/src/views/ufile/aggregation/File.vue +5 -5
- package/src/views/ufile/file/water-mark.vue +14 -14
- package/src/views/uhome/components/menu-favorite.vue +314 -331
- package/src/views/uhome/su-welcome.vue +3 -3
- package/src/views/ulogin/login.vue +19 -12
- package/src/views/upms/interface/log-in.vue +100 -106
- package/src/views/upms/interface/log-out.vue +2 -8
- package/src/views/upms/user/login-log.vue +54 -60
- package/src/views/urpt/design/DesignPanel.vue +16 -35
- package/src/views/urpt/design/Preview.vue +1 -0
- package/src/views/urpt/design/ReportDesign.vue +17 -23
- package/src/views/urpt/static-resource/resource.vue +3 -3
- package/src/views/urpt/template/ReportTemplate.vue +7 -7
- package/types/global.d.ts +4 -9
- package/vite.config.ts +6 -2
- package/dist/AuthorityInfo.vue_vue_type_style_index_0_lang-Duyweh89.js +0 -102
- package/dist/DictView-B4a7Hs1X.js +0 -95
- package/dist/InvOrganization-q4T3y8dQ.js +0 -260
- package/dist/Org-BTGTrAVz.js +0 -35
- package/dist/RolePanel.vue_vue_type_script_setup_true_lang-DKHgNWQP.js +0 -126
- package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-BsBKpYR7.js +0 -288
- package/dist/index-DZc3qRTx.js +0 -2650
- package/dist/login-BOxwzwdB.js +0 -252
- package/dist/sys-config-C0-gSBFO.js +0 -277
- package/dist/utogether-Di1byIum.js +0 -182
- package/src/components/udp/form-upload.vue +0 -183
- package/src/components/udp/modal-form.vue +0 -180
- package/src/utils/http/index.ts +0 -297
- package/src/utils/http/types.d.ts +0 -46
- package/src/utils/udp/useRender.ts +0 -420
|
@@ -1,40 +1,405 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
/*
|
|
2
|
+
* @Author: wei.li
|
|
3
|
+
* @Date: 2022-06-23 17:29:11
|
|
4
|
+
* @LastEditors: levi7754 levi7754@163.com
|
|
5
|
+
* @LastEditTime: 2025-10-29 18:04:53
|
|
6
|
+
* @Description: file content
|
|
7
|
+
*/
|
|
8
|
+
// @ts-nocheck
|
|
9
|
+
|
|
10
|
+
import { clone, isString, orderBy, isEmpty, toDateString, isObject, isFunction } from 'xe-utils';
|
|
11
|
+
import { cookies, storageLocal } from '@utogether/utils';
|
|
12
|
+
/** 系统配置的key */
|
|
13
|
+
const kSYSCONFIG = 'kSysConfig';
|
|
14
|
+
const kCOOKIES = 'kCookies_param';
|
|
15
|
+
|
|
16
|
+
const sysConfig = storageLocal.getItem(kSYSCONFIG);
|
|
17
|
+
|
|
18
|
+
/** 工具栏按钮标准化 */
|
|
19
|
+
export const formatButton = (buttons, auth?) => {
|
|
20
|
+
buttons.forEach(btn => {
|
|
21
|
+
btn.auth = auth ? auth[btn.code] || btn.auth : btn.auth;
|
|
22
|
+
if (!btn.name) {
|
|
23
|
+
btn.name = `message.btn.${btn.code}`;
|
|
24
|
+
} else if (sysConfig?.i18nEnabled === 'Y' && !btn.name.startsWith('message.')) {
|
|
25
|
+
btn.name = `message.btn.${btn.name}`;
|
|
26
|
+
}
|
|
27
|
+
if (btn.dropdowns?.length) {
|
|
28
|
+
formatButton(btn.dropdowns, auth);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return buttons;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @description 查询10W数据,常用于Excel导出
|
|
36
|
+
* @param props 查询接口的路径
|
|
37
|
+
* @param http http实例
|
|
38
|
+
* @param form 查询条件
|
|
39
|
+
* @returns 查询返回的数据
|
|
40
|
+
*/
|
|
41
|
+
export const queryAll = (props, http, form) => {
|
|
42
|
+
const params = { pageNum: 1, pageSize: 100000 };
|
|
43
|
+
const commonParam = getCookieParam();
|
|
44
|
+
Object.assign(params, form, commonParam, props.defaultParams || {});
|
|
45
|
+
let query = formatMultipleParams(params, props.items);
|
|
46
|
+
query = formatDateRange(query, props.items);
|
|
47
|
+
|
|
48
|
+
const { url } = props;
|
|
49
|
+
if (!url) return null;
|
|
50
|
+
const requestURL = isString(url) ? url : url.fetch || url.restful;
|
|
51
|
+
if (!requestURL) return null;
|
|
52
|
+
const method = url.fetch ? 'post' : 'get';
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
http[method](requestURL, query)
|
|
55
|
+
.then((response: IResponseData) => {
|
|
56
|
+
resolve(response.list);
|
|
57
|
+
})
|
|
58
|
+
.catch((e: any) => {
|
|
59
|
+
reject(e);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @description 查询服务
|
|
66
|
+
* @param props 查询接口的路径
|
|
67
|
+
* @param form 查询条件
|
|
68
|
+
* @param page 分页参数
|
|
69
|
+
* @param http http实例
|
|
70
|
+
* @param isDoc doc文档
|
|
71
|
+
* @returns Promise
|
|
72
|
+
*/
|
|
73
|
+
export const query = (props, form, page, http, code, isDoc) => {
|
|
74
|
+
if (isDoc) return getDocData();
|
|
75
|
+
for (const key in form) {
|
|
76
|
+
if (form[key] && isString(form[key])) {
|
|
77
|
+
form[key] = form[key].trim();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const params = { pageNum: page.currentPage, pageSize: page.pageSize };
|
|
81
|
+
const commonParam = getCookieParam();
|
|
82
|
+
Object.assign(params, commonParam, props.defaultParams || {}, form);
|
|
83
|
+
|
|
84
|
+
let query = formatMultipleParams(params, props.items, form);
|
|
85
|
+
query = formatDateRange(query, props.items);
|
|
86
|
+
const { url } = props;
|
|
87
|
+
if (!url) return null;
|
|
88
|
+
const requestURL = isString(url) ? url : url.fetch || url.restful;
|
|
89
|
+
const method = url.fetch ? 'post' : 'get';
|
|
90
|
+
if (!requestURL) return null;
|
|
91
|
+
return http[method](requestURL, query);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @description 表格删除方法
|
|
96
|
+
* @param http http实例
|
|
97
|
+
* @param records 记录行
|
|
98
|
+
* @param props 删除接口的路径
|
|
99
|
+
* @returns Promise
|
|
100
|
+
*/
|
|
101
|
+
export const del = (http, records, props) => {
|
|
102
|
+
const { url } = props;
|
|
103
|
+
if (!url) return null;
|
|
104
|
+
const requestURL = isString(url) ? url : url.del || url.restful;
|
|
105
|
+
if (!requestURL) return null;
|
|
106
|
+
const method = url.del ? 'post' : 'delete';
|
|
107
|
+
return http[method](requestURL, records);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/** 更新服务 */
|
|
111
|
+
export const save = (http, body, props) => {
|
|
112
|
+
const allService = [];
|
|
113
|
+
const { url } = props;
|
|
114
|
+
if (!url) return null;
|
|
115
|
+
|
|
116
|
+
const { insertRecords, updateRecords } = body;
|
|
117
|
+
if (!isEmpty(insertRecords)) {
|
|
118
|
+
const commonParam = getCookieParam();
|
|
119
|
+
insertRecords.forEach(m => {
|
|
120
|
+
!isEmpty(props?.defaultValue) && Object.assign(m, props.defaultValue);
|
|
121
|
+
Object.keys(commonParam)?.forEach(key => {
|
|
122
|
+
m[key] = m[key] || commonParam[key];
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
const requestURL = isString(url) ? url : url.add || url.restful;
|
|
126
|
+
requestURL && allService.push(http.post(requestURL, insertRecords));
|
|
127
|
+
}
|
|
128
|
+
if (!isEmpty(updateRecords)) {
|
|
129
|
+
const requestURL = isString(url) ? url : url.save || url.restful;
|
|
130
|
+
const method = url.save ? 'post' : 'put';
|
|
131
|
+
requestURL && allService.push(http[method](requestURL, updateRecords));
|
|
132
|
+
}
|
|
133
|
+
return allService;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* 多选数据优化
|
|
138
|
+
* @param listQuery
|
|
139
|
+
* @param items
|
|
140
|
+
* @returns
|
|
141
|
+
*/
|
|
142
|
+
const formatMultipleParams = (listQuery: any, items) => {
|
|
143
|
+
const multipleItems = items.filter(f => f.itemRender?.props?.multiple || f.multiple);
|
|
144
|
+
if (isEmpty(multipleItems)) return listQuery;
|
|
145
|
+
const query = clone(listQuery, true);
|
|
146
|
+
multipleItems.forEach((element: any) => {
|
|
147
|
+
if (element.itemRender.name === '#select') {
|
|
148
|
+
// const data = query[`_${element.field}`] || query[`${element.field}`];
|
|
149
|
+
// query[element.field] = !isString(data) ? data?.join(',') : data;
|
|
150
|
+
delete query[`_${element.field}`];
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
return query;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const startFormatter = 'yyyy-MM-dd 00:00:00';
|
|
157
|
+
const endFormatter = 'yyyy-MM-dd 23:59:59';
|
|
158
|
+
// 时间范围优化
|
|
159
|
+
const formatDateRange = (listQuery: any, items) => {
|
|
160
|
+
const dateRanges = items.filter(f => ['#SuDateRange', 'VxeDateRangePicker'].includes(f.itemRender?.name));
|
|
161
|
+
if (isEmpty(dateRanges)) return listQuery;
|
|
162
|
+
const query = clone(listQuery, true);
|
|
163
|
+
dateRanges.forEach((element: any) => {
|
|
164
|
+
const val = query[element.field];
|
|
165
|
+
if (val && element.itemRender.startField) {
|
|
166
|
+
query[element.itemRender.startField] = toDateString(query[element.itemRender.startField], startFormatter);
|
|
167
|
+
query[element.itemRender.endField] = toDateString(query[element.itemRender.endField], endFormatter);
|
|
168
|
+
} else if (val) {
|
|
169
|
+
query[`${element.field}From`] = toDateString(val[0], startFormatter);
|
|
170
|
+
query[`${element.field}To`] = toDateString(val[1], endFormatter);
|
|
171
|
+
}
|
|
172
|
+
delete query[element.field];
|
|
173
|
+
});
|
|
174
|
+
return query;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const getCookieParam = () => {
|
|
178
|
+
return cookies.get(kCOOKIES) ? JSON.parse(cookies.get(kCOOKIES)) : {};
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/** 工具栏默认按钮组 */
|
|
182
|
+
export const inlineButtons = [
|
|
183
|
+
{
|
|
184
|
+
code: 'insert_actived',
|
|
185
|
+
name: 'add',
|
|
186
|
+
status: 'u-cyan',
|
|
187
|
+
icon: 'vxe-icon-add',
|
|
188
|
+
auth: 'add',
|
|
189
|
+
sort: 1
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
code: 'delete',
|
|
193
|
+
status: 'danger',
|
|
194
|
+
icon: 'vxe-icon-delete',
|
|
195
|
+
auth: 'del',
|
|
196
|
+
sort: 2
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
code: 'save',
|
|
200
|
+
status: 'primary',
|
|
201
|
+
icon: 'vxe-icon-save',
|
|
202
|
+
auth: 'edit',
|
|
203
|
+
sort: 3
|
|
204
|
+
}
|
|
205
|
+
];
|
|
206
|
+
// form 模式按钮
|
|
207
|
+
export const dialogButtons = [
|
|
208
|
+
{
|
|
209
|
+
code: 'add',
|
|
210
|
+
status: 'u-cyan',
|
|
211
|
+
icon: 'vxe-icon-add',
|
|
212
|
+
auth: 'add',
|
|
213
|
+
sort: 1
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
code: 'del',
|
|
217
|
+
status: 'danger',
|
|
218
|
+
icon: 'vxe-icon-delete',
|
|
219
|
+
auth: 'del',
|
|
220
|
+
sort: 2
|
|
221
|
+
}
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
export const defaultColums = [
|
|
225
|
+
{ field: 'createdByName', width: 90, visible: false },
|
|
226
|
+
{ field: 'creationDate', width: 140, visible: false },
|
|
227
|
+
{ field: 'lastUpdatedByName', width: 90, visible: false },
|
|
228
|
+
{ field: 'lastUpdateDate', width: 140, visible: false }
|
|
229
|
+
];
|
|
230
|
+
|
|
231
|
+
/** 导出配置 */
|
|
232
|
+
export const getExportConfig = attrs => {
|
|
233
|
+
if (isObject(attrs.exportConfig)) return attrs.exportConfig;
|
|
234
|
+
return {
|
|
235
|
+
filename: attrs.fileName || '导出明细',
|
|
236
|
+
type: 'xlsx',
|
|
237
|
+
types: ['xlsx', 'csv'],
|
|
238
|
+
modes: ['current', 'selected', 'all'],
|
|
239
|
+
useStyle: true,
|
|
240
|
+
sheetMethod: ({ worksheet }) => (attrs.onSheetMethod ? attrs.onSheetMethod(worksheet) : onSheetMethod(worksheet)),
|
|
241
|
+
columnFilterMethod: ({ column }) =>
|
|
242
|
+
attrs.columnFilter
|
|
243
|
+
? !!attrs.columnFilter(column)
|
|
244
|
+
: !['operate'].includes(column.field) && column.type !== 'checkbox'
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export const getToolBarConfig = (data, props, attrs, hasAuthority) => {
|
|
249
|
+
const refreshOptions = {
|
|
250
|
+
icon: 'ri-refresh-line',
|
|
251
|
+
iconLoading: 'vxe-icon-spinner roll vxe-loading--default-icon'
|
|
252
|
+
};
|
|
253
|
+
// 不可编辑时
|
|
254
|
+
if (!props.editable) {
|
|
255
|
+
data.editConfig.editable = props.editable;
|
|
256
|
+
const hasExport = props.needExport && hasAuthority('export');
|
|
257
|
+
if (hasExport) {
|
|
258
|
+
data.exportConfig = getExportConfig(attrs);
|
|
259
|
+
}
|
|
260
|
+
data.toolbarConfig = {
|
|
261
|
+
buttons: [],
|
|
262
|
+
enabled: hasExport,
|
|
263
|
+
refreshOptions,
|
|
264
|
+
exportOptions: { icon: 'ri-download-2-line', code: 'export' },
|
|
265
|
+
export: hasExport,
|
|
266
|
+
custom: !!attrs.gridId,
|
|
267
|
+
refresh: true,
|
|
268
|
+
perfect: true
|
|
269
|
+
};
|
|
270
|
+
return data;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// 先设置传入的按钮
|
|
274
|
+
let buttons = clone(attrs.buttons || [], true);
|
|
275
|
+
|
|
276
|
+
buttons.forEach((button, idx) => {
|
|
277
|
+
button.sort = button.sort || idx + 10;
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// 获取默认的按钮
|
|
281
|
+
const toolButtons = attrs.mode !== 'form' ? clone(inlineButtons, true) : clone(dialogButtons, true);
|
|
282
|
+
// 判断传入的按钮是否有默认按钮的auth,有就不加入按钮组中,相当于重写了默认的按钮
|
|
283
|
+
// reverse的原因是: 保持现有按钮顺序, 新增,保存,删除
|
|
284
|
+
toolButtons.reverse().forEach(btn => {
|
|
285
|
+
!buttons.some(s => s.code === btn.code) && buttons.unshift(btn);
|
|
286
|
+
if (attrs.authPrefix && !['printer', 'export'].includes(btn.auth)) {
|
|
287
|
+
btn.auth = attrs.authPrefix + btn.auth.slice(0, 1).toLocaleUpperCase() + btn.auth.slice(1).toLocaleLowerCase();
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
buttons = formatButton(buttons, props.auth).filter(button => {
|
|
292
|
+
const flag = button.auth ? hasAuthority(button.auth) : true;
|
|
293
|
+
if (button.dropdowns?.length) {
|
|
294
|
+
button.dropdowns = button.dropdowns.filter(btn => !btn.auth || (btn.auth && hasAuthority(btn.auth)));
|
|
295
|
+
}
|
|
296
|
+
return flag;
|
|
297
|
+
});
|
|
298
|
+
// inline 行内模式,单击行模式
|
|
299
|
+
const editConfig = { trigger: 'dblclick', mode: 'row', showStatus: true };
|
|
300
|
+
data.editConfig = attrs.mode !== 'form' ? editConfig : { enabled: false };
|
|
301
|
+
// 导出权限
|
|
302
|
+
const hasExport = props.needExport && hasAuthority('export');
|
|
303
|
+
let exportBtn = null;
|
|
304
|
+
if (hasExport) {
|
|
305
|
+
data.exportConfig = getExportConfig(attrs);
|
|
306
|
+
exportBtn = { icon: 'ri-download-2-line', code: 'export' };
|
|
307
|
+
}
|
|
308
|
+
data.toolbarConfig = {
|
|
309
|
+
buttons: orderBy(buttons, 'sort'),
|
|
310
|
+
enabled: true,
|
|
311
|
+
refreshOptions,
|
|
312
|
+
customOptions: attrs.gridId ? {} : null,
|
|
313
|
+
exportOptions: exportBtn,
|
|
314
|
+
custom: !!attrs.gridId,
|
|
315
|
+
export: hasExport,
|
|
316
|
+
refresh: true,
|
|
317
|
+
perfect: true
|
|
318
|
+
};
|
|
319
|
+
return data;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @description: 表格脚合并方法
|
|
324
|
+
* @param {*} columns 列数据
|
|
325
|
+
* @param {*} data 数据源
|
|
326
|
+
* @param {*} sum 合并属性
|
|
327
|
+
* @return {*} 合并脚方法
|
|
328
|
+
*/
|
|
329
|
+
export const footerSumMethod = ({ columns, data }, sum) => {
|
|
330
|
+
return [
|
|
331
|
+
columns.map((column, columnIdx) => {
|
|
332
|
+
if (columnIdx === (sum.index || 0)) {
|
|
333
|
+
return sum.label || '合计';
|
|
334
|
+
}
|
|
335
|
+
if (sum.fields?.includes(column.property)) {
|
|
336
|
+
const total = data.reduce((prev, cur) => {
|
|
337
|
+
return prev + Number(cur[column.property] || 0);
|
|
338
|
+
}, 0);
|
|
339
|
+
return total ? Number(total.toFixed(sum.decimal || 2)) : total;
|
|
340
|
+
}
|
|
341
|
+
return '';
|
|
342
|
+
})
|
|
343
|
+
];
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* @description: checkbox是否可选
|
|
348
|
+
*/
|
|
349
|
+
export const onCheckMethod = (row, props) => {
|
|
350
|
+
if (isFunction(props.checkMethod)) {
|
|
351
|
+
return props.checkMethod(row);
|
|
352
|
+
}
|
|
353
|
+
return true;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
/*** excel样式重置 */
|
|
357
|
+
const onSheetMethod = ws => {
|
|
358
|
+
ws.eachRow((row, rowNumber) => {
|
|
359
|
+
row.font = { name: '微软雅黑', size: 9 };
|
|
360
|
+
row.border = {
|
|
361
|
+
top: { style: 'thin' },
|
|
362
|
+
left: { style: 'thin' },
|
|
363
|
+
bottom: { style: 'thin' },
|
|
364
|
+
right: { style: 'thin' }
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
if (rowNumber === 1) {
|
|
368
|
+
row.fill = {
|
|
369
|
+
type: 'pattern',
|
|
370
|
+
pattern: 'solid',
|
|
371
|
+
fgColor: { argb: '4F81BD' }
|
|
372
|
+
};
|
|
373
|
+
row.font = {
|
|
374
|
+
name: '微软雅黑',
|
|
375
|
+
size: 10,
|
|
376
|
+
bold: true,
|
|
377
|
+
color: { argb: 'FFFFFFFF' }
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const getDocData = () => {
|
|
384
|
+
return new Promise(resolve => {
|
|
385
|
+
setTimeout(() => {
|
|
386
|
+
const list = [
|
|
387
|
+
{ id: 1, name: 'Test1', sex: 'Man', age: 28, address: 'Shenzhen' },
|
|
388
|
+
{ id: 2, name: 'Test2', sex: 'Women', age: 22, address: 'Guangzhou' },
|
|
389
|
+
{ id: 3, name: 'Test3', sex: 'Man', age: 32, address: 'Shanghai' },
|
|
390
|
+
{ id: 4, name: 'Test4', sex: 'Women', age: 23, address: 'test abc' },
|
|
391
|
+
{ id: 5, name: 'Test5', sex: 'Women', age: 30, address: 'Shanghai' }
|
|
392
|
+
];
|
|
393
|
+
resolve({ list, total: 5 });
|
|
394
|
+
}, 100);
|
|
395
|
+
});
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
export const getAttrs = attrs => {
|
|
399
|
+
const data = {};
|
|
400
|
+
Object.keys(attrs).forEach(key => {
|
|
401
|
+
const nKey = key.replace(/-(\w)/g, str => str.slice(1).toUpperCase());
|
|
402
|
+
data[nKey] = attrs[key];
|
|
403
|
+
});
|
|
404
|
+
return data;
|
|
405
|
+
};
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { usePermissionStoreHook } from '../../store/modules/permission';
|
|
10
10
|
import type { Directive } from 'vue';
|
|
11
|
-
import router from '../../router';
|
|
11
|
+
import { router } from '../../router';
|
|
12
12
|
import type { DirectiveBinding } from 'vue';
|
|
13
13
|
|
|
14
14
|
export const auth: Directive = {
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* @Author: wei.li
|
|
3
3
|
* @Date: 2021-11-17 16:02:30
|
|
4
4
|
* @LastEditors: levi7754 levi7754@163.com
|
|
5
|
-
* @LastEditTime: 2025-
|
|
5
|
+
* @LastEditTime: 2025-08-29 08:57:37
|
|
6
6
|
* @Description: file content
|
|
7
7
|
-->
|
|
8
8
|
<template>
|
|
9
|
-
<div class="system-navbar bg-
|
|
9
|
+
<div class="system-navbar bg-white shadow-sm shadow-[rgba(0, 21, 41, 0.08)] dark:shadow-[#0d0d0d]">
|
|
10
10
|
<Hamburger
|
|
11
11
|
v-if="layout !== 'mix'"
|
|
12
12
|
:is-active="appHook.sidebar.opened"
|
|
@@ -20,16 +20,14 @@
|
|
|
20
20
|
|
|
21
21
|
<div v-if="layout === 'vertical'" class="vertical-header-right">
|
|
22
22
|
<!-- 业务单元选择 -->
|
|
23
|
-
<OrgSelect />
|
|
23
|
+
<OrgSelect v-if="sysConfig['orgTaggle'] === 'Y'" />
|
|
24
24
|
<!-- 菜单搜索 -->
|
|
25
25
|
<Search />
|
|
26
26
|
<!-- 通知 -->
|
|
27
27
|
<!-- <Notice id="header-notice" /> -->
|
|
28
28
|
<!-- 国际化 -->
|
|
29
29
|
<el-dropdown id="header-translation" trigge·r="click">
|
|
30
|
-
<globalization
|
|
31
|
-
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
|
|
32
|
-
/>
|
|
30
|
+
<globalization class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden" />
|
|
33
31
|
<template #dropdown>
|
|
34
32
|
<el-dropdown-menu class="translation">
|
|
35
33
|
<el-dropdown-item
|
|
@@ -98,7 +96,7 @@ export default { name: 'NavBar' };
|
|
|
98
96
|
</script>
|
|
99
97
|
<script setup lang="ts">
|
|
100
98
|
import { ref } from 'vue';
|
|
101
|
-
|
|
99
|
+
import { storageLocal } from '@utogether/utils';
|
|
102
100
|
import Hamburger from '../lay-sidebar/hamBurger.vue';
|
|
103
101
|
import Breadcrumb from '../lay-sidebar/breadCrumb.vue';
|
|
104
102
|
// import Notice from './lay-notice/index.vue';
|
|
@@ -109,6 +107,7 @@ import OrgSelect from '../lay-select-org/index.vue';
|
|
|
109
107
|
import { useTranslationLang } from '../../hooks/useTranslationLang';
|
|
110
108
|
import globalization from '../../../assets/svg/globalization.svg?component';
|
|
111
109
|
import avatars from '../../../assets/images/avatars.jpg';
|
|
110
|
+
import { kSYSCONFIG } from '../../../contant';
|
|
112
111
|
|
|
113
112
|
// const router = useRouter();
|
|
114
113
|
// const route = useRoute();
|
|
@@ -131,6 +130,9 @@ const {
|
|
|
131
130
|
const { locale, translationCh, translationEn } = useTranslationLang();
|
|
132
131
|
|
|
133
132
|
const record: IRecord = {};
|
|
133
|
+
|
|
134
|
+
const sysConfig = storageLocal.getItem(kSYSCONFIG) || {};
|
|
135
|
+
|
|
134
136
|
/**
|
|
135
137
|
* @description: 重置密码
|
|
136
138
|
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @Author: wei.li
|
|
3
3
|
* @Date: 2021-12-23 17:33:20
|
|
4
4
|
* @LastEditors: levi7754 levi7754@163.com
|
|
5
|
-
* @LastEditTime: 2025-
|
|
5
|
+
* @LastEditTime: 2025-07-31 10:15:40
|
|
6
6
|
* @Description: 个性化设置页面
|
|
7
7
|
-->
|
|
8
8
|
<script setup lang="ts">
|
|
@@ -52,7 +52,7 @@ onBeforeUnmount(() => {
|
|
|
52
52
|
<template>
|
|
53
53
|
<div :class="{ show }">
|
|
54
54
|
<div class="right-panel-background" />
|
|
55
|
-
<div ref="target" class="right-panel bg-bg_color">
|
|
55
|
+
<div ref="target" class="right-panel bg-bg_color bg-white">
|
|
56
56
|
<div
|
|
57
57
|
class="project-configuration border-0 border-b-[1px] border-solid border-[var(--pure-border-color)]"
|
|
58
58
|
>
|
|
@@ -118,7 +118,7 @@ onBeforeUnmount(() => {
|
|
|
118
118
|
position: fixed;
|
|
119
119
|
top: 0;
|
|
120
120
|
right: 0;
|
|
121
|
-
z-index:
|
|
121
|
+
z-index: 400000;
|
|
122
122
|
width: 100%;
|
|
123
123
|
max-width: 300px;
|
|
124
124
|
box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
|
|
@@ -16,7 +16,7 @@ function handleSearch() {
|
|
|
16
16
|
|
|
17
17
|
<template>
|
|
18
18
|
<div
|
|
19
|
-
class="search-container w-[40px] h-[48px] flex-
|
|
19
|
+
class="search-container w-[40px] h-[48px] px-2 flex justify-center items-center cursor-pointer navbar-bg-hover"
|
|
20
20
|
@click="handleSearch"
|
|
21
21
|
>
|
|
22
22
|
<IconifyIconOffline icon="ri:search-line" />
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @Author: wei.li
|
|
3
3
|
* @Date: 2021-11-27 16:16:11
|
|
4
4
|
* @LastEditors: levi7754 levi7754@163.com
|
|
5
|
-
* @LastEditTime: 2025-
|
|
5
|
+
* @LastEditTime: 2025-09-22 09:47:39
|
|
6
6
|
* @Description: file content
|
|
7
7
|
-->
|
|
8
8
|
|
|
@@ -10,12 +10,7 @@
|
|
|
10
10
|
<template>
|
|
11
11
|
<div style="width: 240px">
|
|
12
12
|
<el-select v-model="orgId" size="small" @change="onChange">
|
|
13
|
-
<el-option
|
|
14
|
-
v-for="element in orgList"
|
|
15
|
-
:key="element.id"
|
|
16
|
-
:label="element.orgName"
|
|
17
|
-
:value="element.id"
|
|
18
|
-
/>
|
|
13
|
+
<el-option v-for="element in orgList" :key="element.id" :label="element.orgName" :value="element.id" />
|
|
19
14
|
</el-select>
|
|
20
15
|
</div>
|
|
21
16
|
</template>
|
|
@@ -47,8 +42,8 @@ const onChange = async orgId => {
|
|
|
47
42
|
const [err, data]: [Error, any] = await to(getServiceApi().get('/uums/cusOrganization', query));
|
|
48
43
|
if (!err && data.list?.length) {
|
|
49
44
|
useSystemStoreHook().setInvOrgList(data.list || []);
|
|
50
|
-
const invOrg = data
|
|
51
|
-
organizationId = invOrg
|
|
45
|
+
const invOrg = data?.list?.find(f => f.orgId === orgId);
|
|
46
|
+
organizationId = invOrg?.id;
|
|
52
47
|
useSystemStoreHook().setOrganizationId(organizationId);
|
|
53
48
|
}
|
|
54
49
|
const param = { orgId, organizationId };
|
|
@@ -119,7 +119,7 @@ watch(
|
|
|
119
119
|
</script>
|
|
120
120
|
|
|
121
121
|
<template>
|
|
122
|
-
<el-breadcrumb class="!leading-[50px] select-none" separator="/">
|
|
122
|
+
<el-breadcrumb class="!leading-[50px] select-none" separator="/" style="line-height: 50px">
|
|
123
123
|
<transition-group name="breadcrumb">
|
|
124
124
|
<el-breadcrumb-item v-for="item in levelList" :key="item.path" class="inline! items-stretch!">
|
|
125
125
|
<a @click.prevent="handleLink(item)">
|
|
@@ -21,6 +21,7 @@ const routeStore = usePermissionStoreHook();
|
|
|
21
21
|
const sysConfig = storageLocal.getItem(kSYSCONFIG) || {};
|
|
22
22
|
|
|
23
23
|
const logo = ref(sysConfig['logo'] || utogether);
|
|
24
|
+
|
|
24
25
|
const {
|
|
25
26
|
title,
|
|
26
27
|
logout,
|
|
@@ -88,16 +89,14 @@ export default { name: 'LayoutHorizontal' };
|
|
|
88
89
|
</el-scrollbar>
|
|
89
90
|
<div class="horizontal-header-right flex-[2]">
|
|
90
91
|
<!-- 业务单元选择 -->
|
|
91
|
-
<OrgSelect class="udp-horizontal" />
|
|
92
|
+
<OrgSelect v-if="sysConfig['orgTaggle'] === 'Y'" class="udp-horizontal" />
|
|
92
93
|
<!-- 菜单搜索 -->
|
|
93
94
|
<Search />
|
|
94
95
|
<!-- 通知 -->
|
|
95
96
|
<!-- <Notice id="header-notice" /> -->
|
|
96
97
|
<!-- 国际化 -->
|
|
97
|
-
<el-dropdown id="header-translation" trigger="click">
|
|
98
|
-
<globalization
|
|
99
|
-
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
|
|
100
|
-
/>
|
|
98
|
+
<el-dropdown id="header-translation" class="px-2" trigger="click">
|
|
99
|
+
<globalization class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden" />
|
|
101
100
|
<template #dropdown>
|
|
102
101
|
<el-dropdown-menu class="translation">
|
|
103
102
|
<el-dropdown-item
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, watch, toRaw, onMounted, nextTick } from 'vue';
|
|
3
|
+
import { storageLocal } from '@utogether/utils';
|
|
3
4
|
import OrgSelect from '../lay-select-org/index.vue';
|
|
4
5
|
import Search from '../lay-search/index.vue';
|
|
5
6
|
// import Notice from '../lay-notice/index.vue';
|
|
@@ -13,6 +14,7 @@ import { useNav } from '../../hooks/useNav';
|
|
|
13
14
|
import { useTranslationLang } from '../../hooks/useTranslationLang';
|
|
14
15
|
import { usePermissionStoreHook } from '../../../store/modules/permission';
|
|
15
16
|
import globalization from '../../../assets/svg/globalization.svg?component';
|
|
17
|
+
import { kSYSCONFIG } from '../../../contant';
|
|
16
18
|
|
|
17
19
|
const menuRef = ref();
|
|
18
20
|
const { route, locale, translationCh, translationEn } = useTranslationLang(menuRef);
|
|
@@ -38,6 +40,8 @@ const record: IRecord = {};
|
|
|
38
40
|
|
|
39
41
|
const showModal = ref(false);
|
|
40
42
|
|
|
43
|
+
const sysConfig = storageLocal.getItem(kSYSCONFIG) || {};
|
|
44
|
+
|
|
41
45
|
function getDefaultActive(routePath) {
|
|
42
46
|
const wholeMenus = usePermissionStoreHook().wholeMenus;
|
|
43
47
|
// 当前路由的父级路径
|
|
@@ -135,16 +139,14 @@ const handleScroll = e => {
|
|
|
135
139
|
</el-scrollbar>
|
|
136
140
|
<div class="horizontal-header-right">
|
|
137
141
|
<!-- 业务单元选择 -->
|
|
138
|
-
<OrgSelect />
|
|
142
|
+
<OrgSelect v-if="sysConfig['orgTaggle'] === 'Y'" />
|
|
139
143
|
<!-- 菜单搜索 -->
|
|
140
144
|
<Search />
|
|
141
145
|
<!-- 通知 -->
|
|
142
146
|
<!-- <Notice id="header-notice" /> -->
|
|
143
147
|
<!-- 国际化 -->
|
|
144
148
|
<el-dropdown id="header-translation" trigger="click">
|
|
145
|
-
<globalization
|
|
146
|
-
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
|
|
147
|
-
/>
|
|
149
|
+
<globalization class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden" />
|
|
148
150
|
<template #dropdown>
|
|
149
151
|
<el-dropdown-menu class="translation">
|
|
150
152
|
<el-dropdown-item
|