From b12738ed513c2ecafc6b48255d8e890cb4ffb15d Mon Sep 17 00:00:00 2001 From: 张涛 <“2538313560@qq.com”> Date: 星期三, 30 十月 2024 17:38:14 +0800 Subject: [PATCH] feat:用户组静态页面 --- src/locale/en-US.ts | 2 .gitignore | 1 src/views/authority/group/index.vue | 731 ++++++++++++++++++++++++++++++++++++++++++++++++++++ .vscode/settings.json | 1 config/vite.config.dev.ts | 6 src/locale/zh-CN.ts | 6 src/views/authority/group/locale/zh-CN.ts | 3 src/components/menu/index.vue | 26 + src/views/authority/group/locale/en-US.ts | 4 src/router/routes/modules/authority.ts | 11 10 files changed, 774 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 5e14ce6..6327c5a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store dist dist-ssr +.vscode *.local node_modules .DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json index 65a3ad7..0d85a20 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "src/views/authority/resource/locale", "src/views/authority/role/locale", "src/views/authority/users/locale", + "src/views/authority/group/locale", "src/views/dashboard/monitor/locale", "src/views/dashboard/workplace/locale", "src/views/dmx/agent/locale", diff --git a/config/vite.config.dev.ts b/config/vite.config.dev.ts index 8238ae6..b5914c6 100644 --- a/config/vite.config.dev.ts +++ b/config/vite.config.dev.ts @@ -15,7 +15,7 @@ '/base': { // target: 'http://aiotlink.com:8189', //target: 'http://192.168.20.116:8089', - target: 'http://192.168.20.158:8089', + target: 'http://smartai.com:8190', changeOrigin: true, ws: true, // rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), @@ -25,7 +25,7 @@ '/api': { // target: 'http://aiotlink.com:8189', //target: 'http://192.168.20.116:8089', - target: 'http://192.168.20.158:8089', + target: 'http://smartai.com:8190', changeOrigin: true, ws: true, // rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), @@ -33,7 +33,7 @@ '/api/v1': { // target: 'http://aiotlink.com:8189', //target: 'http://192.168.20.116:8089', - target: 'http://192.168.20.158:8089', + target: 'http://smartai.com:8190', changeOrigin: true, ws: true, // rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), diff --git a/src/components/menu/index.vue b/src/components/menu/index.vue index 1987bb5..d565cc7 100644 --- a/src/components/menu/index.vue +++ b/src/components/menu/index.vue @@ -176,18 +176,20 @@ </script> <style lang="less" scoped> - :deep(.arco-menu-inner) { - .arco-menu-inline-header { - display: flex; - align-items: center; - } - .arco-icon { - &:not(.arco-icon-down) { - font-size: 18px; - } +:deep(.arco-menu-inner) { + .arco-menu-inline-header { + display: flex; + align-items: center; + } + + .arco-icon { + &:not(.arco-icon-down) { + font-size: 18px; } } - .session-manager { - display: none; - } +} + +.session-manager { + display: none; +} </style> diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index 6b294fe..a83a633 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -7,6 +7,7 @@ import localeOrganization from '@/views/authority/organization/locale/en-US'; import localeResource from '@/views/authority/resource/locale/en-US'; import localeRole from '@/views/authority/role/locale/en-US'; +import localeGroup from '@/views/authority/group/locale/en-US'; import localeMonitor from '@/views/dashboard/monitor/locale/en-US'; @@ -61,6 +62,7 @@ ...localeOrganization, ...localeResource, ...localeRole, + ...localeGroup, ...localeMonitor, ...localeSearchTable, diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index 5f6edd3..e394d41 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -7,6 +7,7 @@ import localeOrganization from '@/views/authority/organization/locale/zh-CN'; import localeResource from '@/views/authority/resource/locale/zh-CN'; import localeRole from '@/views/authority/role/locale/zh-CN'; +import localeGroup from '@/views/authority/group/locale/zh-CN'; import localeMonitor from '@/views/dashboard/monitor/locale/zh-CN'; @@ -42,8 +43,8 @@ 'menu.server.dashboard': '浠〃鐩�-鏈嶅姟绔�', 'menu.server.workplace': '宸ヤ綔鍙�-鏈嶅姟绔�', 'menu.server.monitor': '瀹炴椂鐩戞帶-鏈嶅姟绔�', - 'menu.session':'浼氳瘽', - 'menu.sessionRecords':'浼氳瘽璁板綍', + 'menu.session': '浼氳瘽', + 'menu.sessionRecords': '浼氳瘽璁板綍', 'menu.list': '鍒楄〃椤�', 'menu.result': '缁撴灉椤�', 'menu.exception': '寮傚父椤�', @@ -66,6 +67,7 @@ ...localeOrganization, ...localeResource, ...localeRole, + ...localeGroup, ...localeMonitor, ...localeSearchTable, diff --git a/src/router/routes/modules/authority.ts b/src/router/routes/modules/authority.ts index a7c28e5..44904a5 100644 --- a/src/router/routes/modules/authority.ts +++ b/src/router/routes/modules/authority.ts @@ -53,6 +53,17 @@ roles: ['*'], }, }, + { + path: 'group', + name: 'group', + component: () => import('@/views/authority/group/index.vue'), + meta: { + locale: 'menu.group.title', + // locale: '鐢ㄦ埛缁�', + requiresAuth: true, + roles: ['*'], + }, + }, ], }; diff --git a/src/views/authority/group/index.vue b/src/views/authority/group/index.vue new file mode 100644 index 0000000..533239b --- /dev/null +++ b/src/views/authority/group/index.vue @@ -0,0 +1,731 @@ +<template> + <div class="container"> + <authheader :items="menuTips"></authheader> + <a-card ref="account" class="general-card"> + <div class="table-page-search-wrapper"> + <div class="search-wrapper"> + <div> + <a-input v-model="formModel.name" :style="{ width: '320px' }" :placeholder="$t('璇疯緭鍏�')" /> + </div> + <div> + <a-button type="primary" style="margin-right: 20px; margin-left: 10px" @click="search"> + <template #icon> + <icon-search /> + </template> + {{ $t('searchTable.form.search') }} + </a-button> + <a-button @click="reset"> + <template #icon> + <icon-refresh /> + </template> + {{ $t('searchTable.form.reset') }} + </a-button> + </div> + </div> + <div class="search-wrapper"> + <div> + <a-space> + <a-button type="primary" :align="'right'" @click="operation(0)">+ 鏂板缓鐢ㄦ埛缁�</a-button> + </a-space> + </div> + <div class="wrapper-icon"> + <a-tooltip :content="$t('searchTable.actions.refresh')"> + <div class="action-icon" @click="search"> + <icon-refresh size="18" /> + </div> + </a-tooltip> + <a-dropdown @select="handleSelectDensity"> + <a-tooltip :content="$t('searchTable.actions.density')"> + <div class="action-icon"> + <icon-line-height size="18" /> + </div> + </a-tooltip> + <template #content> + <a-doption v-for="item in densityList" :key="item.value" :value="item.value" + :class="{ active: item.value === size }"> + <span>{{ item.name }}</span> + </a-doption> + </template> + </a-dropdown> + </div> + </div> + </div> + <a-table row-key="id" :loading="loading" :pagination="pagination" :columns="columns" :data="renderData" + :bordered="false" :size="size" @page-change="onPageChange"> + <template #index="{ rowIndex }"> + {{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }} + </template> + <template #status="{ record }"> + <a-switch v-model="record.status" checked-value="1" unchecked-value="0" + @change="statusChange(record.status, record)" /> + </template> + <template #operations="{ record }"> + <a-space> + <a-button type="outline" @click="operation(2, record)">缂栬緫</a-button> + <a-button type="dashed" status="success" @click="operation(1, record)">鎴愬憳绠$悊</a-button> + <a-button type="dashed" status="warning" @click="operation(4, record)">鏉冮檺绠$悊</a-button> + <a-popconfirm content="璇风‘璁ゆ槸鍚﹀垹闄わ紵" type="success" @ok="operation(3, record)"> + <a-button type="outline" status="danger">鍒犻櫎</a-button> + </a-popconfirm> + </a-space> + </template> + </a-table> + </a-card> + <a-modal v-model:visible="visible" :title="editModalTitle" width="30%" @cancel="handleCancel(1)" @ok="editHandleOk"> + <a-form ref="formRef" :model="editform" auto-label-width> + <a-row> + <a-form-item field="loginName" label="鐢ㄦ埛缁勫悕绉板悕绉�:" :rules="[{ required: true, message: '鐢ㄦ埛鍚嶅繀濉�' }]"> + <a-input v-model="editform.loginName" /> + </a-form-item> + </a-row> + <a-row> + <a-form-item field="userName" label="鐢ㄦ埛缁勮鏄�:"> + <a-textarea v-model="editform.userName" allow-clear /> + </a-form-item> + </a-row> + </a-form> + </a-modal> + <a-modal v-model:visible="memberVisible" width="50%" title="鐢ㄦ埛缁勬垚鍛樼鐞�" @cancel="handleCancel(2)" + @ok="editDeptHandleOk"> + <div :style="{ display: 'flex', justifyContent: 'center' }"> + <!-- TODO榛樿鍊煎洖鏄� --> + <a-transfer show-search :data="memberList" :default-value="selectedMemberList" :source-input-search-props="{ + placeholder: '璇疯緭鍏ョ敤鎴峰悕鎼滅储' + }" :target-input-search-props="{ + placeholder: '璇疯緭鍏ョ敤鎴峰悕鎼滅储' + }"> + <template #source-title>鍙�夊垪琛�</template> + <template #target-title>宸查�夊垪琛�</template> + </a-transfer> + </div> + </a-modal> + <a-modal v-if="resourcevisible" v-model:visible="resourcevisible" width="50%" title="鏉冮檺绠$悊" ok-text="鍏抽棴" + hide-cancel="true" @ok="handleCancel(3)"> + <div :style="{ 'display': 'flex', 'flex-direction': 'column' }"> + <a-card :style="{ + 'width': '100%', + 'height': '40%', + 'overflow-y': 'auto', + 'margin': '1px', + }" class="card-demo" title="鐢ㄦ埛鎵�鏈夋潈闄�" hoverable> + + <a-space wrap> + 鑿滃崟鍔熻兘锛� + <!-- TODO榛樿鍊煎洖鏄� --> + <a-checkbox-group :default-value="['1']"> + <a-checkbox v-for="(item, index) of checkStrictlyMenu" :value="item.menuId" :key="item.menuId"> + {{ item.menuName }}</a-checkbox> + </a-checkbox-group> + </a-space> + <a-divider /> + <a-space wrap> + 鐭ヨ瘑搴�: + <!-- TODO榛樿鍊煎洖鏄� --> + <a-checkbox-group :default-value="['1']"> + <a-checkbox v-for="(item, index) of checkStrictlyKnowledge" :value="item.menuId" :key="item.knowledgeId"> + {{ item.knowledgeName }}</a-checkbox> + </a-checkbox-group> + </a-space> + <a-divider /> + <a-space wrap> + 鏅鸿兘浣�: + <!-- TODO榛樿鍊煎洖鏄� --> + <a-checkbox-group :default-value="['1']"> + <a-checkbox v-for="(item, index) of checkStrictlyDialog" :value="item.dialogId" :key="item.menuId"> + {{ item.dialogName }}</a-checkbox> + </a-checkbox-group> + <!-- TODO榛樿鍊煎洖鏄� --> + <a-checkbox-group :default-value="['1']"> + <a-checkbox v-for="(item, index) of checkStrictlyAgent" :value="item.agentId" :key="item.menuId"> + {{ item.agentName }}</a-checkbox> + </a-checkbox-group> + </a-space> + </a-card> + </div> + </a-modal> + </div> +</template> + +<script lang="ts" setup> +import { computed, reactive, ref, h, onMounted } from 'vue'; +import { useI18n } from 'vue-i18n'; +import useLoading from '@/hooks/loading'; +import { Pagination } from '@/types/global'; +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'; +import { + DialogList, + KnowledgeList, + OrganizationList, + ResourceList, + Role, + RoleList, + User, + UserAdd, + UserChangePwd, + UserDelete, + UserEdit, + UserList, + Userstatus, +} from '@/api/authority'; +import { Modal } from '@arco-design/web-vue'; +import Authheader from '@/views/authority/components/authheader.vue'; +import { create } from 'lodash'; +import { queryCanvasList } from '@/api/Agent'; + +const memberList = ref([ + { + label: '寮犱笁', + value: 'zhangsan', + }, + { + label: ' 鏉庡洓', + value: 'lisi', + }, + { + label: '寮犱笁', + value: 'zhangsan', + }, +]); +const selectedMemberList = ref(['zhangsan']) + +const roles = ref([]); + +const treeData = ref([]); +const checkedKeys = ref([]); +const expandKdys = ref([]); +const checkStrictly = ref([]); +const checkStrictlyMenu = ref([]); +const checkStrictlyKnowledge = ref([]); +const checkStrictlyDialog = ref([]); +const checkStrictlyAgent = ref([]); +const checkStrictlyDeptRole = ref([]); +const formRef = ref(); + +const menuTips = ref(['鏉冮檺绠$悊', '鐢ㄦ埛缁�']); +type SizeProps = 'mini' | 'small' | 'medium' | 'large'; +const account = ref(null); +const generateFormModel = () => { + return { + name: '', + }; +}; +const showLine = ref(true); +const { loading, setLoading } = useLoading(true); +const { t } = useI18n(); +const editModalTitle = ref('鏂板'); +const renderData = ref<User[]>([]); +const formModel = ref(generateFormModel()); +const editform = ref<User>({ + createTime: '', + dept: undefined, + deptName: '', + email: '', + nickName: '', + phoneNumber: '', + status: '', + userId: '', + loginName: '', + userName: '', + psw: '', + role: [], +}); + +const size = ref<SizeProps>('medium'); +const visible = ref(false); +const memberVisible = ref(false); +const resourcevisible = ref(false); +const selectUser = ref({}); + +const loadRole = async () => { + await RoleList(null).then((res) => { + roles.value = res.rows; + }); +}; + +const roleChange = (val) => { + editform.value.role = val; +}; + +const onCheck = (newCheckedKeys, event) => { + const o = { deptId: event.node.deptId, deptName: event.node.deptName }; + if (event.checked) { + event.node.roles.forEach((val) => { + checkStrictlyDeptRole.value.push(val); + }); + checkStrictly.value.push(o); + } else { + checkStrictly.value.forEach((val, idx, array) => { + // val: 褰撳墠鍊� + if (val.deptId == event.node.deptId) { + checkStrictly.value.splice(idx, 1); + checkStrictlyDeptRole.value.forEach((val2, idx2, array2) => { + if (val2.deptId == event.node.deptId) { + checkStrictlyDeptRole.value.splice(idx2, 1); + } + }); + return true; + } + }); + } +}; + +const basePagination: Pagination = { + current: 1, + pageSize: 15, +}; +const pagination = reactive({ + ...basePagination, +}); + +const densityList = computed(() => [ + { + name: t('searchTable.size.mini'), + value: 'mini', + }, + { + name: t('searchTable.size.small'), + value: 'small', + }, + { + name: t('searchTable.size.medium'), + value: 'medium', + }, + { + name: t('searchTable.size.large'), + value: 'large', + }, +]); +const columns = computed<TableColumnData[]>(() => [ + { + title: t('搴忓彿'), + dataIndex: 'index', + slotName: 'index', + }, + // TODO 浠ヤ笅闇�瑕佸瓧娈靛鎺� + { + title: t('鐢ㄦ埛缁勫悕绉�'), + dataIndex: 'loginName', + }, + { + title: t('鐢ㄦ埛缁勬垚鍛�'), + dataIndex: 'roleName', + }, + { + title: t('鐢ㄦ埛缁勮鏄�'), + dataIndex: 'deptName', + slotName: 'deptName', + }, + { + title: t('鍒涘缓鏃堕棿'), + dataIndex: 'deptName', + slotName: 'deptName', + }, + { + title: t('鐘舵��'), + dataIndex: 'status', + slotName: 'status', + }, + { + title: t('searchTable.columns.operations'), + dataIndex: 'operations', + slotName: 'operations', + }, +]); + +const statusChange = async (value, record) => { + if (record?.dept) { + await Userstatus(record.userId, value).then((res) => { }); + } else { + record.status = '0'; + Modal.warning({ + title: '鎻愮ず', + content: '濡傛兂鍚敤鐢ㄦ埛锛岄渶杩涜閮ㄩ棬閰嶇疆.', + }); + } +}; + +const handleCancel = (type) => { + if (type == 1) { + visible.value = false; + } + if (type == 2) { + memberVisible.value = false; + } +}; + +const editDeptHandleOk = async () => { + const depts: Array = []; + const user: User = { userId: selectUser.value.userId }; + checkStrictly.value.forEach((val) => { + depts.push(val.deptId); + }); + user.dept = depts; + await UserEdit(user).then((res) => { + fetchData(); + }); +}; + +const cb = async (err) => { + if (err) { + visible.value = true; + } else { + let uuu; + if (editform.value.userId.length > 0) { + await UserEdit({ + ...editform.value, + } as unknown as User).then((res) => { + fetchData(); + uuu = res.data; + }); + } else { + await UserAdd({ + ...editform.value, + } as unknown as User).then((res) => { + fetchData(); + uuu = res.data; + }); + } + if (!uuu.dept) { + memberVisible.value = true; + checkedKeys.value = []; + expandKdys.value = []; + checkStrictly.value = []; + selectUser.value = uuu; + } + } +}; +const editHandleOk = () => { + formRef.value.validate(cb); +}; +const operation = async (t, record) => { + if (t == 0) { + editModalTitle.value = '鏂板'; + visible.value = true; + editform.value.userId = ''; + editform.value.userName = ''; + editform.value.loginName = ''; + editform.value.nickName = ''; + editform.value.email = ''; + editform.value.phoneNumber = ''; + editform.value.role = ''; + } + // 鎴愬憳绠$悊 + if (t == 1) { + memberVisible.value = true; + } + // 缂栬緫 + if (t == 2) { + visible.value = true; + formRef.value?.resetFields(); + editform.value.role = []; + editModalTitle.value = '缂栬緫'; + editform.value.userId = record.userId; + editform.value.userName = record.userName; + editform.value.loginName = record.loginName; + editform.value.email = record.email; + editform.value.phoneNumber = record.phoneNumber; + if (record.roles?.length > 0) { + // 閬嶅巻record.roles + record.roles.forEach((val) => { + editform.value.role.push(val.roleId); + }); + } + } + // 鍒犻櫎 + if (t == 3) { + await UserDelete(record.userId).then((res) => { + if (res.code == 200) { + fetchData(); + } + }); + } + // 鏉冮檺 + if (t == 4) { + resourcevisible.value = true; + checkStrictlyMenu.value = []; + checkStrictlyKnowledge.value = []; + checkStrictlyDialog.value = []; + checkStrictlyAgent.value = []; + selectUser.value = record; + + let agents; + if (record.agents) { + agents = record.agents; + } else { + agents = record.roles ? record.roles[0].agents : null; + } + if (agents) { + agents.forEach((val) => { + checkStrictlyAgent.value.push({ + agentId: val.id, + agentName: val.title, + }); + }); + } + let resources; + if (record.resources) { + resources = record.resources; + } else { + resources = record.roles ? record.roles[0].resources : null; + } + if (resources) { + resources.forEach((val) => { + checkStrictlyMenu.value.push({ + menuId: val.menuId, + menuName: val.menuName, + }); + }); + } + let knowledges; + if (record.knowledges) { + knowledges = record.knowledges; + } else { + knowledges = record.roles ? record.roles[0].knowledges : null; + } + if (knowledges) { + knowledges.forEach((val) => { + checkStrictlyKnowledge.value.push({ + knowledgeId: val.id, + knowledgeName: val.name, + }); + }); + } + const dialogs = record.roles ? record.roles[0].dialogs : null; + if (dialogs) { + dialogs.forEach((val) => { + checkStrictlyDialog.value.push({ + dialogId: val.id, + dialogName: val.name, + }); + }); + } + } +}; + +const fetchData = async ( + params: Pagination = { current: 1, pageSize: 20 } +) => { + setLoading(true); + try { + await UserList(params).then((res) => { + for (const user of res.rows) { + if (user.dept) { + for (const d of user.dept) { + if (user.deptName) { + user.deptName += `${d.deptName},`; + } else { + user.deptName = `${d.deptName},`; + } + } + } + if (user.roles) { + for (const r of user.roles) { + if (user.roleName) { + user.roleName += `${r.roleName},`; + } else { + user.roleName = `${r.roleName},`; + } + } + } + } + renderData.value = res.rows; + console.log(renderData); + pagination.current = params.current; + pagination.total = res.total; + }); + } catch (err) { + // you can report use errorHandler or other + } finally { + setLoading(false); + } +}; + +const search = () => { + fetchData({ + ...basePagination, + ...formModel.value, + } as unknown as Pagination); +}; + +const onPageChange = (current: number) => { + fetchData({ ...basePagination, current }); +}; + +const OrganizationData = async (key) => { + await OrganizationList(key).then((res) => { + treeData.value = [...res.rows]; + }); +}; + +fetchData(); +OrganizationData(''); +loadRole(); + +const reset = () => { + formModel.value = generateFormModel(); +}; + +const handleSelectDensity = ( + val: string | number | Record<string, any> | undefined, + e: Event +) => { + size.value = val as SizeProps; +}; +</script> + +<style scoped lang="less"> +.card-demo { + width: 460px; + margin-left: 24px; + transition-property: all; +} + +.card-demo:hover { + transform: translateY(-4px); +} + +.table-page-search-wrapper { + padding-top: 10px; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 1px solid #e8e8e8; + + .search-wrapper { + display: flex; + + .wrapper-icon { + display: flex; + align-items: center; + margin-left: 40px; + // margin-right: 40px; + } + } +} + +.space_select_all { + display: flex; + justify-content: end; + margin-bottom: 15px; +} + +.table_box { + display: flex; + + border: 1px solid #e8e8e8; + border-bottom: none; + + .row1_clo { + min-width: 200px; + display: flex; + padding-left: 20px; + border-right: 1px solid #e8e8e8; + } + + .table_row1 { + width: 100%; + + .row1_list { + display: flex; + min-height: 40px; + border-bottom: 1px solid #e8e8e8; + // line-height: 40px; + } + } + + .row1_clo2 { + width: 100%; + border-top: none; + + .row2_clo2_1 { + display: flex; + width: 100%; + min-height: 40px; + line-height: 40px; + border-bottom: 1px solid #e8e8e8; + + .row1_clo2_1 { + border-right: 1px solid #e8e8e8; + min-width: 310px; + padding-left: 20px; + } + + .row1_clo2_2 { + border-top: none; + border-right: none; + width: 100%; + display: flex; + flex-wrap: wrap; + + div { + margin-left: 20px; + } + } + } + } + + .row2_clo2_1:last-child { + border-bottom: none; + } +} + +:deep(.arco-transfer-view) { + width: 250px; + height: 400px +} +</style> + +<style lang="less"> +.ant-table-wrapper { + .ant-table-tbody { + tr { + td { + .ant-table-row-cell-break-word { + .ant-table-column-sorter { + display: none; + } + } + } + } + } + + .search-wrapper { + display: flex; + + .wrapper-icon { + display: flex; + align-items: center; + margin-left: 40px; + // margin-right: 40px; + } + } +} +</style> + +<style lang="less"> +.ant-table-wrapper { + .ant-table-tbody { + tr { + td { + .ant-table-row-cell-break-word { + .ant-table-column-sorter { + display: none; + } + } + } + } + } +} +</style> + +<style lang="less" scoped> +.table-page-search-wrapper { + .ant-form-inline { + :deep(.ant-form-item) { + display: flex; + } + } +} +</style> diff --git a/src/views/authority/group/locale/en-US.ts b/src/views/authority/group/locale/en-US.ts new file mode 100644 index 0000000..6cc9079 --- /dev/null +++ b/src/views/authority/group/locale/en-US.ts @@ -0,0 +1,4 @@ +export default { + "menu.group.title": "Group", +}; +// export default { "menu.user.title": "Account" }; \ No newline at end of file diff --git a/src/views/authority/group/locale/zh-CN.ts b/src/views/authority/group/locale/zh-CN.ts new file mode 100644 index 0000000..63c88af --- /dev/null +++ b/src/views/authority/group/locale/zh-CN.ts @@ -0,0 +1,3 @@ +export default { + 'menu.group.title': '鐢ㄦ埛缁�', +}; \ No newline at end of file -- Gitblit v1.8.0