'admin-22.12.10:同步vue-next-admin-template分支v2.4.2版本内容'
This commit is contained in:
parent
e0f40f6f5e
commit
cef2754806
|
|
@ -1,6 +1,12 @@
|
|||
# <a href="https://gitee.com/lyt-top/vue-next-admin" target="_blank">vue-next-admin-template-js(不带国际化) 更新日志</a>
|
||||
|
||||
🎉🎉🔥 `vue-next-admin-template-js` 基于 (vue-next-admin-template v2.4.1 版本) vue3.x 、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||
🎉🎉🔥 `vue-next-admin-template-js` 基于 (vue-next-admin-template v2.4.2 版本) vue3.x 、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||
|
||||
## 2.4.2
|
||||
|
||||
`2022.12.10`
|
||||
|
||||
- 🎉 同步 vue-next-admin-template 基础版本(不带国际化) 分支 v2.4.2 版本内容,具体查看 master 分支 CHANGELOG.md
|
||||
|
||||
## 2.4.1
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<p> </p>
|
||||
</div>
|
||||
|
||||
#### 🌈 介绍 基础版 js(不带国际化,基于 vue-next-admin-template V2.4.1 版,setup 语法糖)
|
||||
#### 🌈 介绍 基础版 js(不带国际化,基于 vue-next-admin-template V2.4.2 版,setup 语法糖)
|
||||
|
||||
基于 vue3.x + CompositionAPI setup 语法糖 + typescript + vite + element plus + vue-router-next + pinia 技术,适配手机、平板、pc 的后台开源免费模板,希望减少工作量,帮助大家实现快速开发。
|
||||
|
||||
|
|
@ -43,13 +43,15 @@
|
|||
|
||||
| Edge | Firefox | Chrome | Safari |
|
||||
| --------- | ------------ | ----------- | ----------- |
|
||||
| Edge ≥ 79 | Firefox ≥ 78 | Chrome ≥ 76 | Safari ≥ 12 |
|
||||
| Edge ≥ 88 | Firefox ≥ 78 | Chrome ≥ 87 | Safari ≥ 13 |
|
||||
|
||||
> 由于 Vue3 不再支持 IE11,故而 ElementPlus 也不支持 IE11 及之前版本。
|
||||
|
||||
#### ⚡ 使用说明
|
||||
|
||||
建议使用 cnpm,因为 yarn 有时会报错。<a href="http://nodejs.cn/" target="_blank">node 版本 > 14xx.xx.x</a>
|
||||
建议使用 cnpm,因为 yarn 有时会报错。<a href="http://nodejs.cn/" target="_blank">node 版本 > 14.18+/16+</a>
|
||||
|
||||
> Vite 不再支持 Node 12 / 13 / 15,因为上述版本已经进入了 EOL 阶段。现在你必须使用 Node 14.18+ / 16+ 版本。
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vue-next-admin-template-js",
|
||||
"version": "2.4.1",
|
||||
"version": "2.4.2",
|
||||
"description": "vue3 vite next admin template js setup",
|
||||
"author": "lyt_20201208",
|
||||
"license": "MIT",
|
||||
|
|
@ -11,29 +11,30 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.0.10",
|
||||
"axios": "^1.2.0",
|
||||
"echarts": "^5.4.0",
|
||||
"element-plus": "^2.2.25",
|
||||
"axios": "^1.2.1",
|
||||
"echarts": "^5.4.1",
|
||||
"element-plus": "^2.2.26",
|
||||
"js-cookie": "^3.0.1",
|
||||
"mitt": "^3.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.27",
|
||||
"pinia": "^2.0.28",
|
||||
"qrcodejs2-fixes": "^0.0.2",
|
||||
"screenfull": "^6.0.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"vue": "^3.2.45",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"qs": "^6.11.0",
|
||||
"vue-router": "^4.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vue/compiler-sfc": "^3.2.45",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint": "^8.29.0",
|
||||
"eslint-plugin-vue": "^9.8.0",
|
||||
"prettier": "^2.8.0",
|
||||
"sass": "^1.56.1",
|
||||
"prettier": "^2.8.1",
|
||||
"sass": "^1.56.2",
|
||||
"unplugin-auto-import": "^0.12.0",
|
||||
"vite": "^3.2.4",
|
||||
"vite": "^4.0.0",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vue-eslint-parser": "^9.1.0"
|
||||
},
|
||||
|
|
@ -46,7 +47,7 @@
|
|||
"url": "https://gitee.com/lyt-top/vue-next-admin/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0",
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">= 7.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
|
|
|
|||
|
|
@ -1,17 +1,27 @@
|
|||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* (不建议写成 request.post(xxx),因为这样 post 时,无法 params 与 data 同时传参)
|
||||
*
|
||||
* 登录api接口集合
|
||||
* @method signIn 用户登录
|
||||
* @method signOut 用户退出登录
|
||||
*/
|
||||
export function useLoginApi() {
|
||||
return {
|
||||
signIn: (params) => {
|
||||
return request.post('/user/signIn', params);
|
||||
signIn: (data) => {
|
||||
return request({
|
||||
url: '/user/signIn',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
},
|
||||
signOut: (params) => {
|
||||
return request.post('/user/signOut', params);
|
||||
signOut: (data) => {
|
||||
return request({
|
||||
url: '/user/signOut',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import request from '/@/utils/request';
|
|||
/**
|
||||
* 以下为模拟接口地址,gitee 的不通,就换自己的真实接口地址
|
||||
*
|
||||
* (不建议写成 request.post(xxx),因为这样 post 时,无法 params 与 data 同时传参)
|
||||
*
|
||||
* 后端控制菜单模拟json,路径在 https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu
|
||||
* 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
||||
* @method getAdminMenu 获取后端动态路由菜单(admin)
|
||||
|
|
@ -11,10 +13,18 @@ import request from '/@/utils/request';
|
|||
export function useMenuApi() {
|
||||
return {
|
||||
getAdminMenu: (params) => {
|
||||
return request.get('/gitee/lyt-top/vue-next-admin-images/raw/master/menu/adminMenu.json', params);
|
||||
return request({
|
||||
url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/adminMenu.json',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
},
|
||||
getTestMenu: (params) => {
|
||||
return request.get('/gitee/lyt-top/vue-next-admin-images/raw/master/menu/testMenu.json', params);
|
||||
return request({
|
||||
url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/testMenu.json',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +1,48 @@
|
|||
<template>
|
||||
<div class="icon-selector w100 h100">
|
||||
<el-input
|
||||
v-model="state.fontIconSearch"
|
||||
:placeholder="state.fontIconPlaceholder"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
ref="inputWidthRef"
|
||||
@clear="onClearFontIcon"
|
||||
@focus="onIconFocus"
|
||||
@blur="onIconBlur"
|
||||
>
|
||||
<template #prepend>
|
||||
<SvgIcon
|
||||
:name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix"
|
||||
class="font14"
|
||||
v-if="state.fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : state.fontIconPrefix?.indexOf('ele-') > -1"
|
||||
/>
|
||||
<i v-else :class="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
:width="state.fontIconWidth"
|
||||
trigger="click"
|
||||
transition="el-zoom-in-top"
|
||||
popper-class="icon-selector-popper"
|
||||
@show="onPopoverShow"
|
||||
trigger="click"
|
||||
:virtual-ref="inputWidthRef"
|
||||
virtual-triggering
|
||||
>
|
||||
<template #reference>
|
||||
<el-input
|
||||
v-model="state.fontIconSearch"
|
||||
:placeholder="state.fontIconPlaceholder"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
ref="inputWidthRef"
|
||||
@clear="onClearFontIcon"
|
||||
@focus="onIconFocus"
|
||||
@blur="onIconBlur"
|
||||
>
|
||||
<template #prepend>
|
||||
<SvgIcon
|
||||
:name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix"
|
||||
class="font14"
|
||||
v-if="state.fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : state.fontIconPrefix?.indexOf('ele-') > -1"
|
||||
/>
|
||||
<i v-else :class="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
<template #default>
|
||||
<div class="icon-selector-warp">
|
||||
<div class="icon-selector-warp-title flex">
|
||||
<div class="flex-auto">{{ title }}</div>
|
||||
<div class="icon-selector-warp-title-tab" v-if="type === 'all'">
|
||||
<span :class="{ 'span-active': state.fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">
|
||||
ali
|
||||
</span>
|
||||
<span :class="{ 'span-active': state.fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">
|
||||
ele
|
||||
</span>
|
||||
<span :class="{ 'span-active': state.fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">
|
||||
awe
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="icon-selector-warp-row">
|
||||
<el-scrollbar ref="selectorScrollbarRef">
|
||||
<el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">
|
||||
<el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">
|
||||
<div class="icon-selector-warp-item" :class="{ 'icon-selector-active': state.fontIconPrefix === v }">
|
||||
<div class="flex-margin">
|
||||
<div class="icon-selector-warp-item-value">
|
||||
<SvgIcon :name="v" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<div class="icon-selector-warp-title">{{ title }}</div>
|
||||
<el-tabs v-model="state.fontIconTabActive" @tab-click="onIconClick">
|
||||
<el-tab-pane lazy label="ali" name="ali">
|
||||
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="ele" name="ele">
|
||||
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="awe" name="awe">
|
||||
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
|
|
@ -76,29 +57,24 @@ import '/@/theme/iconSelector.scss';
|
|||
const props = defineProps({
|
||||
// 输入框前置内容
|
||||
prepend: {
|
||||
type,
|
||||
type: String,
|
||||
default: () => 'ele-Pointer',
|
||||
},
|
||||
// 输入框占位文本
|
||||
placeholder: {
|
||||
type,
|
||||
type: String,
|
||||
default: () => '请输入内容搜索图标或者选择图标',
|
||||
},
|
||||
// 输入框占位文本
|
||||
size: {
|
||||
type,
|
||||
type: String,
|
||||
default: () => 'default',
|
||||
},
|
||||
// 弹窗标题
|
||||
title: {
|
||||
type,
|
||||
type: String,
|
||||
default: () => '请选择图标',
|
||||
},
|
||||
// icon 图标类型
|
||||
type: {
|
||||
type,
|
||||
default: () => 'ele',
|
||||
},
|
||||
// 禁用
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
|
|
@ -111,30 +87,34 @@ const props = defineProps({
|
|||
},
|
||||
// 自定义空状态描述文字
|
||||
emptyDescription: {
|
||||
type,
|
||||
type: String,
|
||||
default: () => '无相关图标',
|
||||
},
|
||||
// 双向绑定值,默认为 modelValue,
|
||||
// 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
|
||||
// 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A
|
||||
modelValue,
|
||||
modelValue: String,
|
||||
});
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['update:modelValue', 'get', 'clear']);
|
||||
|
||||
// 引入组件
|
||||
const IconList = defineAsyncComponent(() => import('/@/components/iconSelector/list.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const inputWidthRef = ref();
|
||||
const selectorScrollbarRef = ref();
|
||||
const state = reactive({
|
||||
fontIconPrefix: '',
|
||||
fontIconWidth: 0,
|
||||
fontIconSearch: '',
|
||||
fontIconTabsIndex: 0,
|
||||
fontIconSheetsList: [],
|
||||
fontIconPlaceholder: '',
|
||||
fontIconType: 'ali',
|
||||
fontIconShow: true,
|
||||
fontIconTabActive: 'ali',
|
||||
fontIconList: {
|
||||
ali: [],
|
||||
ele: [],
|
||||
awe: [],
|
||||
},
|
||||
});
|
||||
|
||||
// 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值
|
||||
|
|
@ -145,32 +125,91 @@ const onIconFocus = () => {
|
|||
};
|
||||
// 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值
|
||||
const onIconBlur = () => {
|
||||
const list = fontIconTabNameList();
|
||||
setTimeout(() => {
|
||||
const icon = state.fontIconSheetsList.filter((icon) => icon === state.fontIconSearch);
|
||||
const icon = list.filter((icon) => icon === state.fontIconSearch);
|
||||
if (icon.length <= 0) state.fontIconSearch = '';
|
||||
}, 300);
|
||||
};
|
||||
// 图标搜索及图标数据显示
|
||||
const fontIconSheetsFilterList = computed(() => {
|
||||
const list = fontIconTabNameList();
|
||||
if (!state.fontIconSearch) return list;
|
||||
let search = state.fontIconSearch.trim().toLowerCase();
|
||||
return list.filter((item) => {
|
||||
if (item.toLowerCase().indexOf(search) !== -1) return item;
|
||||
});
|
||||
});
|
||||
// 根据 tab name 类型设置图标
|
||||
const fontIconTabNameList = () => {
|
||||
let iconList = [];
|
||||
if (state.fontIconTabActive === 'ali') iconList = state.fontIconList.ali;
|
||||
else if (state.fontIconTabActive === 'ele') iconList = state.fontIconList.ele;
|
||||
else if (state.fontIconTabActive === 'awe') iconList = state.fontIconList.awe;
|
||||
return iconList;
|
||||
};
|
||||
// 处理 icon 双向绑定数值回显
|
||||
const initModeValueEcho = () => {
|
||||
if (props.modelValue === '') return (state.fontIconPlaceholder = props.placeholder);
|
||||
state.fontIconPlaceholder = props.modelValue;
|
||||
state.fontIconPrefix = props.modelValue;
|
||||
};
|
||||
// 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
|
||||
const initFontIconTypeEcho = () => {
|
||||
if (props.modelValue.indexOf('iconfont') > -1) onIconChange('ali');
|
||||
else if (props.modelValue.indexOf('ele-') > -1) onIconChange('ele');
|
||||
else if (props.modelValue.indexOf('fa') > -1) onIconChange('awe');
|
||||
else onIconChange('ali');
|
||||
// 处理 icon 类型,用于回显时,tab 高亮与初始化数据
|
||||
const initFontIconName = () => {
|
||||
let name = 'ali';
|
||||
if (props.modelValue.indexOf('iconfont') > -1) name = 'ali';
|
||||
else if (props.modelValue.indexOf('ele-') > -1) name = 'ele';
|
||||
else if (props.modelValue.indexOf('fa') > -1) name = 'awe';
|
||||
// 初始化 tab 高亮回显
|
||||
state.fontIconTabActive = name;
|
||||
return name;
|
||||
};
|
||||
// 初始化数据
|
||||
const initFontIconData = async (name) => {
|
||||
if (name === 'ali') {
|
||||
// 阿里字体图标使用 `iconfont xxx`
|
||||
if (state.fontIconList.ali.length > 0) return;
|
||||
await initIconfont.ali().then((res) => {
|
||||
state.fontIconList.ali = res.map((i) => `iconfont ${i}`);
|
||||
});
|
||||
} else if (name === 'ele') {
|
||||
// element plus 图标
|
||||
if (state.fontIconList.ele.length > 0) return;
|
||||
await initIconfont.ele().then((res) => {
|
||||
state.fontIconList.ele = res;
|
||||
});
|
||||
} else if (name === 'awe') {
|
||||
// fontawesome字体图标使用 `fa xxx`
|
||||
if (state.fontIconList.awe.length > 0) return;
|
||||
await initIconfont.awe().then((res) => {
|
||||
state.fontIconList.awe = res.map((i) => `fa ${i}`);
|
||||
});
|
||||
}
|
||||
// 初始化 input 的 placeholder
|
||||
// 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
|
||||
state.fontIconPlaceholder = props.placeholder;
|
||||
// 初始化双向绑定回显
|
||||
initModeValueEcho();
|
||||
};
|
||||
// 图标点击切换
|
||||
const onIconClick = (pane) => {
|
||||
initFontIconData(pane.paneName);
|
||||
inputWidthRef.value.focus();
|
||||
};
|
||||
// 获取当前点击的 icon 图标
|
||||
const onColClick = (v) => {
|
||||
state.fontIconPlaceholder = v;
|
||||
state.fontIconPrefix = v;
|
||||
emit('get', state.fontIconPrefix);
|
||||
emit('update:modelValue', state.fontIconPrefix);
|
||||
inputWidthRef.value.focus();
|
||||
};
|
||||
// 清空当前点击的 icon 图标
|
||||
const onClearFontIcon = () => {
|
||||
state.fontIconPrefix = '';
|
||||
emit('clear', state.fontIconPrefix);
|
||||
emit('update:modelValue', state.fontIconPrefix);
|
||||
};
|
||||
// 图标搜索及图标数据显示
|
||||
const fontIconSheetsFilterList = computed(() => {
|
||||
if (!state.fontIconSearch) return state.fontIconSheetsList;
|
||||
let search = state.fontIconSearch.trim().toLowerCase();
|
||||
return state.fontIconSheetsList.filter((item) => {
|
||||
if (item.toLowerCase().indexOf(search) !== -1) return item;
|
||||
});
|
||||
});
|
||||
// 获取 input 的宽度
|
||||
const getInputWidth = () => {
|
||||
nextTick(() => {
|
||||
|
|
@ -183,56 +222,9 @@ const initResize = () => {
|
|||
getInputWidth();
|
||||
});
|
||||
};
|
||||
// 初始化数据
|
||||
const initFontIconData = async (type) => {
|
||||
state.fontIconSheetsList = [];
|
||||
if (type === 'ali') {
|
||||
await initIconfont.ali().then((res) => {
|
||||
// 阿里字体图标使用 `iconfont xxx`
|
||||
state.fontIconSheetsList = res.map((i) => `iconfont ${i}`);
|
||||
});
|
||||
} else if (type === 'ele') {
|
||||
await initIconfont.ele().then((res) => {
|
||||
state.fontIconSheetsList = res;
|
||||
});
|
||||
} else if (type === 'awe') {
|
||||
await initIconfont.awe().then((res) => {
|
||||
// fontawesome字体图标使用 `fa xxx`
|
||||
state.fontIconSheetsList = res.map((i) => `fa ${i}`);
|
||||
});
|
||||
}
|
||||
// 初始化 input 的 placeholder
|
||||
// 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
|
||||
state.fontIconPlaceholder = props.placeholder;
|
||||
// 初始化双向绑定回显
|
||||
initModeValueEcho();
|
||||
};
|
||||
// 图标点击切换
|
||||
const onIconChange = (type) => {
|
||||
state.fontIconType = type;
|
||||
initFontIconData(type);
|
||||
};
|
||||
// 获取当前点击的 icon 图标
|
||||
const onColClick = (v) => {
|
||||
state.fontIconPlaceholder = v;
|
||||
state.fontIconPrefix = v;
|
||||
emit('get', state.fontIconPrefix);
|
||||
emit('update:modelValue', state.fontIconPrefix);
|
||||
};
|
||||
// 清空当前点击的 icon 图标
|
||||
const onClearFontIcon = () => {
|
||||
state.fontIconPrefix = '';
|
||||
emit('clear', state.fontIconPrefix);
|
||||
emit('update:modelValue', state.fontIconPrefix);
|
||||
};
|
||||
// 监听 Popover 打开,用于双向绑定值回显
|
||||
const onPopoverShow = () => {
|
||||
initModeValueEcho();
|
||||
initFontIconTypeEcho();
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initModeValueEcho();
|
||||
initFontIconData(initFontIconName());
|
||||
initResize();
|
||||
getInputWidth();
|
||||
});
|
||||
|
|
@ -241,6 +233,7 @@ watch(
|
|||
() => props.modelValue,
|
||||
() => {
|
||||
initModeValueEcho();
|
||||
initFontIconName();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<div class="icon-selector-warp-row">
|
||||
<el-scrollbar ref="selectorScrollbarRef">
|
||||
<el-row :gutter="10" v-if="props.list.length > 0">
|
||||
<el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" v-for="(v, k) in list" :key="k" @click="onColClick(v)">
|
||||
<div class="icon-selector-warp-item" :class="{ 'icon-selector-active': prefix === v }">
|
||||
<SvgIcon :name="v" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-empty :image-size="100" v-if="list.length <= 0" :description="empty"></el-empty>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="iconSelectorList">
|
||||
// 定义父组件传过来的值
|
||||
const props = defineProps({
|
||||
// 图标列表数据
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 自定义空状态描述文字
|
||||
empty: {
|
||||
type: String,
|
||||
default: () => '无相关图标',
|
||||
},
|
||||
// 高亮当前选中图标
|
||||
prefix: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
});
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['get-icon']);
|
||||
|
||||
// 当前 icon 图标点击时
|
||||
const onColClick = (v) => {
|
||||
emit('get-icon', v);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.icon-selector-warp-row {
|
||||
height: 230px;
|
||||
overflow: hidden;
|
||||
.el-row {
|
||||
padding: 15px;
|
||||
}
|
||||
.el-scrollbar__bar.is-horizontal {
|
||||
display: none;
|
||||
}
|
||||
.icon-selector-warp-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
height: 30px;
|
||||
i {
|
||||
font-size: 20px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 1px solid var(--el-color-primary-light-5);
|
||||
i {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon-selector-active {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 1px solid var(--el-color-primary-light-5);
|
||||
i {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -241,7 +241,7 @@ const refreshCurrentTagsView = async (fullPath) => {
|
|||
};
|
||||
// 3、关闭当前 tagsView:如果是设置了固定的(isAffix),不可以关闭
|
||||
const closeCurrentTagsView = (path) => {
|
||||
state.tagsViewList.map((v, k, arrs) => {
|
||||
state.tagsViewList.map((v, k, arr) => {
|
||||
if (!v.meta?.isAffix) {
|
||||
if (getThemeConfig.value.isShareTagsView ? v.path === path : v.url === path) {
|
||||
storesKeepALiveNames.delCachedView(v);
|
||||
|
|
|
|||
|
|
@ -78,9 +78,13 @@ onMounted(() => {
|
|||
getIframeListRoutes();
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I58U75
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I59RXK
|
||||
// https://gitee.com/lyt-top/vue-next-admin/pulls/40
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (themeConfig.value.isCacheTagsView) cachedViews.value = Session.get('tagsViewList')?.map((item) => item.name);
|
||||
if (themeConfig.value.isCacheTagsView) {
|
||||
let tagsViewArr = Session.get('tagsViewList') || [];
|
||||
cachedViews.value = tagsViewArr.filter((item) => item.meta?.isKeepAlive).map((item) => item.name);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@
|
|||
</div>
|
||||
<div class="upgrade-content">
|
||||
{{ getThemeConfig.globalTitle }} 新版本来啦,马上更新尝鲜吧!不用担心,更新很快的哦!
|
||||
<div class="mt5">
|
||||
<el-link type="primary" class="font12" href="https://gitee.com/lyt-top/vue-next-admin/blob/master/CHANGELOG.md" target="_black">
|
||||
CHANGELOG.md
|
||||
</el-link>
|
||||
</div>
|
||||
<div class="upgrade-content-desc mt5">提示:更新会还原默认配置</div>
|
||||
</div>
|
||||
<div class="upgrade-btn">
|
||||
|
|
@ -35,7 +40,7 @@ import { Local } from '/@/utils/storage';
|
|||
const storesThemeConfig = useThemeConfig();
|
||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||
const state = reactive({
|
||||
isUpgrade: true,
|
||||
isUpgrade: false,
|
||||
version: __VERSION__,
|
||||
isLoading: false,
|
||||
btnTxt: '',
|
||||
|
|
@ -59,8 +64,15 @@ const onUpgrade = () => {
|
|||
Local.set('version', state.version);
|
||||
}, 2000);
|
||||
};
|
||||
// 延迟显示,防止刷新时界面显示太快
|
||||
const delayShow = () => {
|
||||
setTimeout(() => {
|
||||
state.isUpgrade = true;
|
||||
}, 2000);
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
delayShow();
|
||||
setTimeout(() => {
|
||||
state.btnTxt = '马上更新';
|
||||
}, 200);
|
||||
|
|
@ -86,7 +98,7 @@ onMounted(() => {
|
|||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: var(--el-color-primary);
|
||||
background-color: var(--el-color-primary-light-1);
|
||||
width: 130%;
|
||||
height: 130px;
|
||||
border-bottom-left-radius: 100%;
|
||||
|
|
@ -101,7 +113,8 @@ onMounted(() => {
|
|||
letter-spacing: 3px;
|
||||
}
|
||||
.upgrade-title-warp-version {
|
||||
background-color: var(--next-color-white);
|
||||
color: var(--next-color-white);
|
||||
background-color: var(--el-color-primary-light-4);
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ export async function initBackEndControlRoutes() {
|
|||
await useUserInfo().setUserInfos();
|
||||
// 获取路由菜单数据
|
||||
const res = await getBackEndControlRoutes();
|
||||
// 无登录权限时,添加判断
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO
|
||||
if (res.data.length <= 0) return Promise.resolve(true);
|
||||
// 存储接口原始路由(未处理component),根据需求选择使用
|
||||
useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data)));
|
||||
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||
|
|
@ -57,7 +60,7 @@ export async function initBackEndControlRoutes() {
|
|||
* @description 用于左侧菜单、横向菜单的显示
|
||||
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
||||
*/
|
||||
export function setFilterMenuAndCacheTagsViewRoutes() {
|
||||
export async function setFilterMenuAndCacheTagsViewRoutes() {
|
||||
const storesRoutesList = useRoutesList(pinia);
|
||||
storesRoutesList.setRoutesList(dynamicRoutes[0].children);
|
||||
setCacheTagsViewRoutes();
|
||||
|
|
@ -118,8 +121,8 @@ export function getBackEndControlRoutes() {
|
|||
* @description 用于菜单管理界面刷新菜单(未进行测试)
|
||||
* @description 路径:/src/views/system/menu/component/addMenu.vue
|
||||
*/
|
||||
export function setBackEndControlRefreshRoutes() {
|
||||
getBackEndControlRoutes();
|
||||
export async function setBackEndControlRefreshRoutes() {
|
||||
await getBackEndControlRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ export async function initFrontEndControlRoutes() {
|
|||
// 触发初始化用户信息 pinia
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
||||
await useUserInfo(pinia).setUserInfos();
|
||||
// 无登录权限时,添加判断
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO
|
||||
if (useUserInfo().userInfos.roles.length <= 0) return Promise.resolve(true);
|
||||
// 添加动态路由
|
||||
await setAddRoute();
|
||||
// 设置递归过滤有权限的路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
|
|
|
|||
|
|
@ -89,13 +89,13 @@ export const useThemeConfig = defineStore('themeConfig', {
|
|||
// 是否开启 TagsView 共用
|
||||
isShareTagsView: false,
|
||||
// 是否开启 Footer 底部版权信息
|
||||
isFooter: true,
|
||||
isFooter: false,
|
||||
// 是否开启灰色模式
|
||||
isGrayscale: true,
|
||||
isGrayscale: false,
|
||||
// 是否开启色弱模式
|
||||
isInvert: false,
|
||||
// 是否开启水印
|
||||
isWartermark: false,
|
||||
isWartermark: true,
|
||||
// 水印文案
|
||||
wartermarkText: 'vue-next-admin',
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@
|
|||
|
||||
/* Input 输入框、InputNumber 计数器
|
||||
------------------------------- */
|
||||
.el-input {
|
||||
height: 100%;
|
||||
}
|
||||
// 菜单搜索
|
||||
.el-autocomplete-suggestion__wrap {
|
||||
max-height: 280px !important;
|
||||
|
|
|
|||
|
|
@ -5,64 +5,25 @@
|
|||
.icon-selector-warp {
|
||||
height: 260px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.icon-selector-warp-title {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0 15px;
|
||||
.icon-selector-warp-title-tab {
|
||||
span {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
.span-active {
|
||||
color: var(--el-color-primary);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
left: 15px;
|
||||
}
|
||||
.icon-selector-warp-row {
|
||||
height: 230px;
|
||||
overflow: hidden;
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
.el-row {
|
||||
padding: 15px;
|
||||
}
|
||||
.el-scrollbar__bar.is-horizontal {
|
||||
display: none;
|
||||
}
|
||||
.icon-selector-warp-item {
|
||||
display: flex;
|
||||
border: 1px solid var(--el-border-color);
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
.icon-selector-warp-item-value {
|
||||
i {
|
||||
font-size: 20px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
.el-tabs__header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 15px;
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
margin: 0 !important;
|
||||
.el-tabs__nav-wrap {
|
||||
&::after {
|
||||
height: 0 !important;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 1px solid var(--el-color-primary-light-5);
|
||||
.icon-selector-warp-item-value {
|
||||
i {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon-selector-active {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 1px solid var(--el-color-primary-light-5);
|
||||
.icon-selector-warp-item-value {
|
||||
i {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-tabs__item {
|
||||
padding: 0 5px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,16 @@
|
|||
// 响应式表单时,登录页需要重新处理
|
||||
display: unset !important;
|
||||
}
|
||||
// 表格演示中的表单筛选
|
||||
.table-form-btn {
|
||||
display: flex !important;
|
||||
.el-form-item__label {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
// 表格演示中的表单筛选最大高度,适配移动端
|
||||
.table-search-container {
|
||||
max-height: 160px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import axios from 'axios';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import qs from 'qs';
|
||||
import { Session } from '/@/utils/storage';
|
||||
|
||||
// 配置新建一个 axios 实例
|
||||
|
|
@ -7,6 +8,11 @@ const service = axios.create({
|
|||
baseURL: import.meta.env.VITE_API_URL,
|
||||
timeout: 50000,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
paramsSerializer: {
|
||||
serialize(params) {
|
||||
return qs.stringify(params, { allowDots: true });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 添加请求拦截器
|
||||
|
|
|
|||
|
|
@ -84,37 +84,41 @@ const onSignIn = async () => {
|
|||
Cookies.set('userName', state.ruleForm.userName);
|
||||
if (!themeConfig.value.isRequestRoutes) {
|
||||
// 前端控制路由,2、请注意执行顺序
|
||||
await initFrontEndControlRoutes();
|
||||
signInSuccess();
|
||||
const isNoPower = await initFrontEndControlRoutes();
|
||||
signInSuccess(isNoPower);
|
||||
} else {
|
||||
// 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
||||
// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
||||
await initBackEndControlRoutes();
|
||||
const isNoPower = await initBackEndControlRoutes();
|
||||
// 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
||||
signInSuccess();
|
||||
signInSuccess(isNoPower);
|
||||
}
|
||||
};
|
||||
// 登录成功后的跳转
|
||||
const signInSuccess = () => {
|
||||
// 初始化登录成功时间问候语
|
||||
let currentTimeInfo = currentTime.value;
|
||||
// 登录成功,跳到转首页
|
||||
// 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
|
||||
if (route.query?.redirect) {
|
||||
router.push({
|
||||
path: route.query?.redirect,
|
||||
query: Object.keys(route.query?.params).length > 0 ? JSON.parse(route.query?.params) : '',
|
||||
});
|
||||
const signInSuccess = (isNoPower) => {
|
||||
if (isNoPower) {
|
||||
ElMessage.warning('抱歉,您没有登录权限');
|
||||
Session.clear();
|
||||
} else {
|
||||
router.push('/');
|
||||
// 初始化登录成功时间问候语
|
||||
let currentTimeInfo = currentTime.value;
|
||||
// 登录成功,跳到转首页
|
||||
// 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
|
||||
if (route.query?.redirect) {
|
||||
router.push({
|
||||
path: route.query?.redirect,
|
||||
query: Object.keys(route.query?.params).length > 0 ? JSON.parse(route.query?.params) : '',
|
||||
});
|
||||
} else {
|
||||
router.push('/');
|
||||
}
|
||||
// 登录成功提示
|
||||
const signInText = '欢迎回来!';
|
||||
ElMessage.success(`${currentTimeInfo},${signInText}`);
|
||||
// 添加 loading,防止第一次进入界面时出现短暂空白
|
||||
NextLoading.start();
|
||||
}
|
||||
// 登录成功提示
|
||||
// 关闭 loading
|
||||
state.loading.signIn = true;
|
||||
const signInText = '欢迎回来!';
|
||||
ElMessage.success(`${currentTimeInfo},${signInText}`);
|
||||
// 添加 loading,防止第一次进入界面时出现短暂空白
|
||||
NextLoading.start();
|
||||
state.loading.signIn = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,146 +0,0 @@
|
|||
<template>
|
||||
<div class="system-edit-dept-container">
|
||||
<el-dialog title="修改部门" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="上级部门">
|
||||
<el-cascader
|
||||
:options="state.deptData"
|
||||
:props="{ checkStrictly: true, value: 'deptName', label: 'deptName' }"
|
||||
placeholder="请选择部门"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="state.ruleForm.deptLevel"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.deptName }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="部门名称">
|
||||
<el-input v-model="state.ruleForm.deptName" placeholder="请输入部门名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="负责人">
|
||||
<el-input v-model="state.ruleForm.person" placeholder="请输入负责人" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="state.ruleForm.phone" placeholder="请输入手机号" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="state.ruleForm.email" placeholder="请输入" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="state.ruleForm.sort" :min="0" :max="999" controls-position="right" placeholder="请输入排序" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="部门状态">
|
||||
<el-switch v-model="state.ruleForm.status" inline-prompt active-text="启" inactive-text="禁"></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="部门描述">
|
||||
<el-input v-model="state.ruleForm.describe" type="textarea" placeholder="请输入部门描述" maxlength="150"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">修 改</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemEditDept">
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
deptLevel: [], // 上级部门
|
||||
deptName: '', // 部门名称
|
||||
person: '', // 负责人
|
||||
phone: '', // 手机号
|
||||
email: '', // 邮箱
|
||||
sort: 0, // 排序
|
||||
status: true, // 部门状态
|
||||
describe: '', // 部门描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row) => {
|
||||
row.deptLevel = ['vueNextAdmin'];
|
||||
row.person = 'lyt';
|
||||
row.phone = '12345678910';
|
||||
row.email = 'vueNextAdmin@123.com';
|
||||
state.ruleForm = row;
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 初始化部门数据
|
||||
const initTableData = () => {
|
||||
state.deptData.push({
|
||||
deptName: 'vueNextAdmin',
|
||||
createTime: new Date().toLocaleString(),
|
||||
status: true,
|
||||
sort: Math.random(),
|
||||
describe: '顶级部门',
|
||||
id: Math.random(),
|
||||
children: [
|
||||
{
|
||||
deptName: 'IT外包服务',
|
||||
createTime: new Date().toLocaleString(),
|
||||
status: true,
|
||||
sort: Math.random(),
|
||||
describe: '总部',
|
||||
id: Math.random(),
|
||||
},
|
||||
{
|
||||
deptName: '资本控股',
|
||||
createTime: new Date().toLocaleString(),
|
||||
status: true,
|
||||
sort: Math.random(),
|
||||
describe: '分部',
|
||||
id: Math.random(),
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="system-add-dept-container">
|
||||
<el-dialog title="新增部门" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<div class="system-dept-dialog-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="769px">
|
||||
<el-form ref="deptDialogFormRef" :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="上级部门">
|
||||
|
|
@ -60,17 +60,20 @@
|
|||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">新 增</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemAddDept">
|
||||
<script setup name="systemDeptDialog">
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const deptDialogFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
deptLevel: [], // 上级部门
|
||||
deptName: '', // 部门名称
|
||||
|
|
@ -82,26 +85,51 @@ const state = reactive({
|
|||
describe: '', // 部门描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
dialog: {
|
||||
isShowDialog: false,
|
||||
type: '',
|
||||
title: '',
|
||||
submitTxt: '',
|
||||
},
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
state.isShowDialog = true;
|
||||
const openDialog = (type, row) => {
|
||||
if (type === 'edit') {
|
||||
row.deptLevel = ['vueNextAdmin'];
|
||||
row.person = 'lyt';
|
||||
row.phone = '12345678910';
|
||||
row.email = 'vueNextAdmin@123.com';
|
||||
state.ruleForm = row;
|
||||
state.dialog.title = '修改部门';
|
||||
state.dialog.submitTxt = '修 改';
|
||||
} else {
|
||||
state.dialog.title = '新增部门';
|
||||
state.dialog.submitTxt = '新 增';
|
||||
// 清空表单,此项需加表单验证才能使用
|
||||
// nextTick(() => {
|
||||
// deptDialogFormRef.value.resetFields();
|
||||
// });
|
||||
}
|
||||
state.dialog.isShowDialog = true;
|
||||
getMenuData();
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
state.dialog.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
emit('refresh');
|
||||
// if (state.dialog.type === 'add') { }
|
||||
};
|
||||
// 初始化部门数据
|
||||
const initTableData = () => {
|
||||
const getMenuData = () => {
|
||||
state.deptData.push({
|
||||
deptName: 'vueNextAdmin',
|
||||
createTime: new Date().toLocaleString(),
|
||||
|
|
@ -129,10 +157,6 @@ const initTableData = () => {
|
|||
],
|
||||
});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddDept">
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddDept('add')">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
</div>
|
||||
<el-table
|
||||
:data="state.tableData.data"
|
||||
v-loading="state.tableData.loading"
|
||||
style="width: 100%"
|
||||
row-key="id"
|
||||
default-expand-all
|
||||
|
|
@ -39,15 +40,14 @@
|
|||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="操作" show-overflow-tooltip width="140">
|
||||
<template #default="scope">
|
||||
<el-button size="small" text type="primary" @click="onOpenAddDept">新增</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenEditDept(scope.row)">修改</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenAddDept('add')">新增</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenEditDept('edit', scope.row)">修改</el-button>
|
||||
<el-button size="small" text type="primary" @click="onTabelRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<AddDept ref="addDeptRef" />
|
||||
<EditDept ref="editDeptRef" />
|
||||
<DeptDialog ref="deptDialogRef" @refresh="getTableData()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -55,12 +55,10 @@
|
|||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
|
||||
// 引入组件
|
||||
const AddDept = defineAsyncComponent(() => import('/@/views/system/dept/component/addDept.vue'));
|
||||
const EditDept = defineAsyncComponent(() => import('/@/views/system/dept/component/editDept.vue'));
|
||||
const DeptDialog = defineAsyncComponent(() => import('/@/views/system/dept/dialog.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const addDeptRef = ref();
|
||||
const editDeptRef = ref();
|
||||
const deptDialogRef = ref();
|
||||
const state = reactive({
|
||||
tableData: {
|
||||
data: [],
|
||||
|
|
@ -74,7 +72,9 @@ const state = reactive({
|
|||
});
|
||||
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const getTableData = () => {
|
||||
state.tableData.loading = true;
|
||||
state.tableData.data = [];
|
||||
state.tableData.data.push({
|
||||
deptName: 'vueNextAdmin',
|
||||
createTime: new Date().toLocaleString(),
|
||||
|
|
@ -102,14 +102,17 @@ const initTableData = () => {
|
|||
],
|
||||
});
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
setTimeout(() => {
|
||||
state.tableData.loading = false;
|
||||
}, 500);
|
||||
};
|
||||
// 打开新增菜单弹窗
|
||||
const onOpenAddDept = () => {
|
||||
addDeptRef.value.openDialog();
|
||||
const onOpenAddDept = (type) => {
|
||||
deptDialogRef.value.openDialog(type);
|
||||
};
|
||||
// 打开编辑菜单弹窗
|
||||
const onOpenEditDept = (row) => {
|
||||
editDeptRef.value.openDialog(row);
|
||||
const onOpenEditDept = (type, row) => {
|
||||
deptDialogRef.value.openDialog(type, row);
|
||||
};
|
||||
// 删除当前行
|
||||
const onTabelRowDel = (row) => {
|
||||
|
|
@ -119,12 +122,13 @@ const onTabelRowDel = (row) => {
|
|||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
getTableData();
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
getTableData();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
<template>
|
||||
<div class="system-add-dic-container">
|
||||
<el-dialog title="新增字典" v-model="state.isShowDialog" width="769px">
|
||||
<el-alert title="半成品,交互过于复杂,请自行扩展!" type="warning" :closable="false" class="mb20"> </el-alert>
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="字典名称">
|
||||
<el-input v-model="state.ruleForm.dicName" placeholder="请输入字典名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="字段名">
|
||||
<el-input v-model="state.ruleForm.fieldName" placeholder="请输入字段名,拼接 ruleForm.list" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="字典状态">
|
||||
<el-switch v-model="state.ruleForm.status" inline-prompt active-text="启" inactive-text="禁"></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-row :gutter="35" v-for="(v, k) in state.ruleForm.list" :key="k">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item :prop="`list[${k}].label`">
|
||||
<template #label>
|
||||
<el-button type="primary" circle size="small" @click="onAddRow" v-if="k === 0">
|
||||
<el-icon>
|
||||
<ele-Plus />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button type="danger" circle size="small" @click="onDelRow(k)" v-else>
|
||||
<el-icon>
|
||||
<ele-Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<span class="ml10">字段</span>
|
||||
</template>
|
||||
<el-input v-model="v.label" style="width: 100%" placeholder="请输入字段名"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="属性" :prop="`list[${k}].value`">
|
||||
<el-input v-model="v.value" style="width: 100%" placeholder="请输入属性值"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="字典描述">
|
||||
<el-input v-model="state.ruleForm.describe" type="textarea" placeholder="请输入字典描述" maxlength="150"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">新 增</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemAddDic">
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
dicName: '', // 字典名称
|
||||
fieldName: '', // 字段名
|
||||
status: true, // 字典状态
|
||||
list: [], // 子集字段 + 属性值
|
||||
describe: '', // 字典描述
|
||||
},
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增行
|
||||
const onAddRow = () => {
|
||||
state.ruleForm.list.push({
|
||||
id: Math.random(),
|
||||
label: '',
|
||||
value: '',
|
||||
});
|
||||
};
|
||||
// 删除行
|
||||
const onDelRow = (k) => {
|
||||
state.ruleForm.list.splice(k, 1);
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="system-edit-dic-container">
|
||||
<el-dialog title="修改字典" v-model="state.isShowDialog" width="769px">
|
||||
<div class="system-dic-dialog-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="769px">
|
||||
<el-alert title="半成品,交互过于复杂,请自行扩展!" type="warning" :closable="false" class="mb20"> </el-alert>
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-form ref="dicDialogFormRef" :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="字典名称">
|
||||
|
|
@ -56,17 +56,20 @@
|
|||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">修 改</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemEditDic">
|
||||
<script setup name="systemDicDialog">
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const dicDialogFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
dicName: '', // 字典名称
|
||||
fieldName: '', // 字段名
|
||||
|
|
@ -74,37 +77,56 @@ const state = reactive({
|
|||
list: [], // 子集字段 + 属性值
|
||||
describe: '', // 字典描述
|
||||
},
|
||||
dialog: {
|
||||
isShowDialog: false,
|
||||
type: '',
|
||||
title: '',
|
||||
submitTxt: '',
|
||||
},
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row) => {
|
||||
if (row.fieldName === 'SYS_UERINFO') {
|
||||
row.list = [
|
||||
{ id: Math.random(), label: 'sex', value: '1' },
|
||||
{ id: Math.random(), label: 'sex', value: '0' },
|
||||
];
|
||||
const openDialog = (type, row) => {
|
||||
if (type === 'edit') {
|
||||
if (row.fieldName === 'SYS_UERINFO') {
|
||||
row.list = [
|
||||
{ id: Math.random(), label: 'sex', value: '1' },
|
||||
{ id: Math.random(), label: 'sex', value: '0' },
|
||||
];
|
||||
} else {
|
||||
row.list = [
|
||||
{ id: Math.random(), label: 'role', value: 'admin' },
|
||||
{ id: Math.random(), label: 'role', value: 'common' },
|
||||
{ id: Math.random(), label: 'roleName', value: '超级管理员' },
|
||||
{ id: Math.random(), label: 'roleName', value: '普通用户' },
|
||||
];
|
||||
}
|
||||
state.ruleForm = row;
|
||||
state.dialog.title = '修改字典';
|
||||
state.dialog.submitTxt = '修 改';
|
||||
} else {
|
||||
row.list = [
|
||||
{ id: Math.random(), label: 'role', value: 'admin' },
|
||||
{ id: Math.random(), label: 'role', value: 'common' },
|
||||
{ id: Math.random(), label: 'roleName', value: '超级管理员' },
|
||||
{ id: Math.random(), label: 'roleName', value: '普通用户' },
|
||||
];
|
||||
state.dialog.title = '新增字典';
|
||||
state.dialog.submitTxt = '新 增';
|
||||
// 清空表单,此项需加表单验证才能使用
|
||||
// nextTick(() => {
|
||||
// dicDialogFormRef.value.resetFields();
|
||||
// });
|
||||
}
|
||||
state.ruleForm = row;
|
||||
state.isShowDialog = true;
|
||||
state.dialog.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
state.dialog.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
emit('refresh');
|
||||
// if (state.dialog.type === 'add') { }
|
||||
};
|
||||
// 新增行
|
||||
const onAddRow = () => {
|
||||
|
|
@ -9,14 +9,14 @@
|
|||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddDic">
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddDic('add')">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增字典
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="state.tableData.data" style="width: 100%">
|
||||
<el-table :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="50" />
|
||||
<el-table-column prop="dicName" label="字典名称" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="fieldName" label="字段名" show-overflow-tooltip></el-table-column>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button size="small" text type="primary" @click="onOpenEditDic(scope.row)">修改</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenEditDic('edit', scope.row)">修改</el-button>
|
||||
<el-button size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -49,8 +49,7 @@
|
|||
>
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
<AddDic ref="addDicRef" />
|
||||
<EditDic ref="editDicRef" />
|
||||
<DicDialog ref="dicDialogRef" @refresh="getTableData()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -58,12 +57,10 @@
|
|||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
|
||||
// 引入组件
|
||||
const AddDic = defineAsyncComponent(() => import('/@/views/system/dic/component/addDic.vue'));
|
||||
const EditDic = defineAsyncComponent(() => import('/@/views/system/dic/component/editDic.vue'));
|
||||
const DicDialog = defineAsyncComponent(() => import('/@/views/system/dic/dialog.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const addDicRef = ref();
|
||||
const editDicRef = ref();
|
||||
const dicDialogRef = ref();
|
||||
const state = reactive({
|
||||
tableData: {
|
||||
data: [],
|
||||
|
|
@ -77,7 +74,8 @@ const state = reactive({
|
|||
});
|
||||
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const getTableData = () => {
|
||||
state.tableData.loading = true;
|
||||
const data = [];
|
||||
for (let i = 0; i < 2; i++) {
|
||||
data.push({
|
||||
|
|
@ -91,14 +89,17 @@ const initTableData = () => {
|
|||
}
|
||||
state.tableData.data = data;
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
setTimeout(() => {
|
||||
state.tableData.loading = false;
|
||||
}, 500);
|
||||
};
|
||||
// 打开新增字典弹窗
|
||||
const onOpenAddDic = () => {
|
||||
addDicRef.value.openDialog();
|
||||
const onOpenAddDic = (type) => {
|
||||
dicDialogRef.value.openDialog(type);
|
||||
};
|
||||
// 打开修改字典弹窗
|
||||
const onOpenEditDic = (row) => {
|
||||
editDicRef.value.openDialog(row);
|
||||
const onOpenEditDic = (type, row) => {
|
||||
dicDialogRef.value.openDialog(type, row);
|
||||
};
|
||||
// 删除字典
|
||||
const onRowDel = (row) => {
|
||||
|
|
@ -108,6 +109,7 @@ const onRowDel = (row) => {
|
|||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
getTableData();
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
|
|
@ -115,13 +117,15 @@ const onRowDel = (row) => {
|
|||
// 分页改变
|
||||
const onHandleSizeChange = (val) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
getTableData();
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val) => {
|
||||
state.tableData.param.pageNum = val;
|
||||
getTableData();
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
getTableData();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,235 +0,0 @@
|
|||
<template>
|
||||
<div class="system-edit-menu-container">
|
||||
<el-dialog title="修改菜单" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="80px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="上级菜单">
|
||||
<el-cascader
|
||||
:options="state.menuData"
|
||||
:props="{ checkStrictly: true, value: 'path', label: 'title' }"
|
||||
placeholder="请选择上级菜单"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="state.ruleForm.menuSuperior"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.title }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="菜单类型">
|
||||
<el-radio-group v-model="state.ruleForm.menuType">
|
||||
<el-radio label="menu">菜单</el-radio>
|
||||
<el-radio label="btn">按钮</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="菜单名称">
|
||||
<el-input v-model="state.ruleForm.meta.title" placeholder="格式:message.router.xxx" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="state.ruleForm.menuType === 'menu'">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="路由名称">
|
||||
<el-input v-model="state.ruleForm.name" placeholder="路由中的 name 值" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="路由路径">
|
||||
<el-input v-model="state.ruleForm.path" placeholder="路由中的 path 值" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="重定向">
|
||||
<el-input v-model="state.ruleForm.redirect" placeholder="请输入路由重定向" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="菜单图标">
|
||||
<IconSelector placeholder="请输入菜单图标" v-model="state.ruleForm.meta.icon" type="all" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="组件路径">
|
||||
<el-input v-model="state.ruleForm.component" placeholder="组件路径" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="链接地址">
|
||||
<el-input
|
||||
v-model="state.ruleForm.meta.isLink"
|
||||
placeholder="外链/内嵌时链接地址(http:xxx.com)"
|
||||
clearable
|
||||
:disabled="!state.ruleForm.isLink"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="权限标识">
|
||||
<el-select v-model="state.ruleForm.meta.roles" multiple placeholder="取角色管理" clearable class="w100">
|
||||
<el-option label="admin" value="admin"></el-option>
|
||||
<el-option label="common" value="common"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<template v-if="state.ruleForm.menuType === 'btn'">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="权限标识">
|
||||
<el-input v-model="state.ruleForm.btnPower" placeholder="请输入权限标识" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="菜单排序">
|
||||
<el-input-number v-model="state.ruleForm.menuSort" controls-position="right" placeholder="请输入排序" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="state.ruleForm.menuType === 'menu'">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="是否隐藏">
|
||||
<el-radio-group v-model="state.ruleForm.meta.isHide">
|
||||
<el-radio :label="true">隐藏</el-radio>
|
||||
<el-radio :label="false">不隐藏</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="页面缓存">
|
||||
<el-radio-group v-model="state.ruleForm.meta.isKeepAlive">
|
||||
<el-radio :label="true">缓存</el-radio>
|
||||
<el-radio :label="false">不缓存</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="是否固定">
|
||||
<el-radio-group v-model="state.ruleForm.meta.isAffix">
|
||||
<el-radio :label="true">固定</el-radio>
|
||||
<el-radio :label="false">不固定</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="是否外链">
|
||||
<el-radio-group v-model="state.ruleForm.isLink" :disabled="state.ruleForm.meta.isIframe">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="是否内嵌">
|
||||
<el-radio-group v-model="state.ruleForm.meta.isIframe" @change="onSelectIframeChange">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">修 改</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemEditMenu">
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
|
||||
// 引入组件
|
||||
const IconSelector = defineAsyncComponent(() => import('/@/components/iconSelector/index.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const stores = useRoutesList();
|
||||
const { routesList } = storeToRefs(stores);
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
// 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式
|
||||
ruleForm: {
|
||||
menuSuperior: [], // 上级菜单
|
||||
menuType: 'menu', // 菜单类型
|
||||
name: '', // 路由名称
|
||||
component: '', // 组件路径
|
||||
isLink: false, // 是否外链
|
||||
menuSort: 0, // 菜单排序
|
||||
path: '', // 路由路径
|
||||
redirect: '', // 路由重定向,有子集 children 时
|
||||
meta: {
|
||||
title: '', // 菜单名称
|
||||
icon: '', // 菜单图标
|
||||
isHide: false, // 是否隐藏
|
||||
isKeepAlive: true, // 是否缓存
|
||||
isAffix: false, // 是否固定
|
||||
isLink: '', // 外链/内嵌时链接地址(http:xxx.com),开启外链条件,`1、isLink: 链接地址不为空`
|
||||
isIframe: false, // 是否内嵌,开启条件,`1、isIframe:true 2、isLink:链接地址不为空`
|
||||
roles: '', // 权限标识,取角色管理
|
||||
},
|
||||
btnPower: '', // 菜单类型为按钮时,权限标识
|
||||
},
|
||||
menuData: [], // 上级菜单数据
|
||||
});
|
||||
|
||||
// 获取 pinia 中的路由
|
||||
const getMenuData = (routes) => {
|
||||
const arr = [];
|
||||
routes.map((val) => {
|
||||
val['title'] = val.meta?.title;
|
||||
arr.push({ ...val });
|
||||
if (val.children) getMenuData(val.children);
|
||||
});
|
||||
return arr;
|
||||
};
|
||||
// 打开弹窗
|
||||
const openDialog = (row) => {
|
||||
// 模拟数据,实际请走接口
|
||||
row.menuType = 'menu';
|
||||
row.menuSort = Math.random();
|
||||
row.component = `${row.component} `
|
||||
.match(/\'(.+)\'/g)
|
||||
?.join('')
|
||||
.replace(/\'/g, '');
|
||||
state.ruleForm = row;
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 是否内嵌下拉改变
|
||||
const onSelectIframeChange = () => {
|
||||
if (state.ruleForm.meta.isIframe) state.ruleForm.isLink = true;
|
||||
else state.ruleForm.isLink = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
const onSubmit = () => {
|
||||
closeDialog(); // 关闭弹窗
|
||||
// setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
state.menuData = getMenuData(routesList.value);
|
||||
});
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="system-add-menu-container">
|
||||
<el-dialog title="新增菜单" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="80px">
|
||||
<div class="system-menu-dialog-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="769px">
|
||||
<el-form ref="menuDialogFormRef" :model="state.ruleForm" size="default" label-width="80px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="上级菜单">
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="菜单图标">
|
||||
<IconSelector placeholder="请输入菜单图标" v-model="state.ruleForm.meta.icon" type="all" />
|
||||
<IconSelector placeholder="请输入菜单图标" v-model="state.ruleForm.meta.icon" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
|
|
@ -138,26 +138,29 @@
|
|||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">新 增</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemAddMenu">
|
||||
<script setup name="systemMenuDialog">
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 引入组件
|
||||
const IconSelector = defineAsyncComponent(() => import('/@/components/iconSelector/index.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const menuDialogFormRef = ref();
|
||||
const stores = useRoutesList();
|
||||
const { routesList } = storeToRefs(stores);
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
// 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式
|
||||
ruleForm: {
|
||||
menuSuperior: [], // 上级菜单
|
||||
|
|
@ -181,6 +184,12 @@ const state = reactive({
|
|||
btnPower: '', // 菜单类型为按钮时,权限标识
|
||||
},
|
||||
menuData: [], // 上级菜单数据
|
||||
dialog: {
|
||||
isShowDialog: false,
|
||||
type: '',
|
||||
title: '',
|
||||
submitTxt: '',
|
||||
},
|
||||
});
|
||||
|
||||
// 获取 pinia 中的路由
|
||||
|
|
@ -194,12 +203,32 @@ const getMenuData = (routes) => {
|
|||
return arr;
|
||||
};
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
state.isShowDialog = true;
|
||||
const openDialog = (type, row) => {
|
||||
if (type === 'edit') {
|
||||
// 模拟数据,实际请走接口
|
||||
row.menuType = 'menu';
|
||||
row.menuSort = Math.random();
|
||||
row.component = `${row.component} `
|
||||
.match(/\'(.+)\'/g)
|
||||
?.join('')
|
||||
.replace(/\'/g, '');
|
||||
state.ruleForm = row;
|
||||
state.dialog.title = '修改菜单';
|
||||
state.dialog.submitTxt = '修 改';
|
||||
} else {
|
||||
state.dialog.title = '新增菜单';
|
||||
state.dialog.submitTxt = '新 增';
|
||||
// 清空表单,此项需加表单验证才能使用
|
||||
// nextTick(() => {
|
||||
// menuDialogFormRef.value.resetFields();
|
||||
// });
|
||||
}
|
||||
state.dialog.type = type;
|
||||
state.dialog.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
state.dialog.isShowDialog = false;
|
||||
};
|
||||
// 是否内嵌下拉改变
|
||||
const onSelectIframeChange = () => {
|
||||
|
|
@ -210,9 +239,11 @@ const onSelectIframeChange = () => {
|
|||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
closeDialog(); // 关闭弹窗
|
||||
emit('refresh');
|
||||
// if (state.dialog.type === 'add') { }
|
||||
// setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
|
||||
};
|
||||
// 页面加载时
|
||||
|
|
@ -16,7 +16,13 @@
|
|||
新增菜单
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="menuTableData" style="width: 100%" row-key="path" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
|
||||
<el-table
|
||||
:data="state.tableData.data"
|
||||
v-loading="state.tableData.loading"
|
||||
style="width: 100%"
|
||||
row-key="path"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column label="菜单名称" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<SvgIcon :name="scope.row.meta.icon" />
|
||||
|
|
@ -46,15 +52,14 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="操作" show-overflow-tooltip width="140">
|
||||
<template #default="scope">
|
||||
<el-button size="small" text type="primary" @click="onOpenAddMenu">新增</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenEditMenu(scope.row)">修改</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenAddMenu('add')">新增</el-button>
|
||||
<el-button size="small" text type="primary" @click="onOpenEditMenu('edit', scope.row)">修改</el-button>
|
||||
<el-button size="small" text type="primary" @click="onTabelRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<AddMenu ref="addMenuRef" />
|
||||
<EditMenu ref="editMenuRef" />
|
||||
<MenuDialog ref="menuDialogRef" @refresh="getTableData()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -62,28 +67,37 @@
|
|||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
|
||||
// 引入组件
|
||||
const AddMenu = defineAsyncComponent(() => import('/@/views/system/menu/component/addMenu.vue'));
|
||||
const EditMenu = defineAsyncComponent(() => import('/@/views/system/menu/component/editMenu.vue'));
|
||||
const MenuDialog = defineAsyncComponent(() => import('/@/views/system/menu/dialog.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const stores = useRoutesList();
|
||||
const { routesList } = storeToRefs(stores);
|
||||
const addMenuRef = ref();
|
||||
const editMenuRef = ref();
|
||||
|
||||
// 获取 pinia 中的路由
|
||||
const menuTableData = computed(() => {
|
||||
return routesList.value;
|
||||
const menuDialogRef = ref();
|
||||
const state = reactive({
|
||||
tableData: {
|
||||
data: [],
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
|
||||
// 获取路由数据,真实请从接口获取
|
||||
const getTableData = () => {
|
||||
state.tableData.loading = true;
|
||||
state.tableData.data = routesList.value;
|
||||
setTimeout(() => {
|
||||
state.tableData.loading = false;
|
||||
}, 500);
|
||||
};
|
||||
// 打开新增菜单弹窗
|
||||
const onOpenAddMenu = () => {
|
||||
addMenuRef.value.openDialog();
|
||||
const onOpenAddMenu = (type) => {
|
||||
menuDialogRef.value.openDialog(type);
|
||||
};
|
||||
// 打开编辑菜单弹窗
|
||||
const onOpenEditMenu = (row) => {
|
||||
editMenuRef.value.openDialog(row);
|
||||
const onOpenEditMenu = (type, row) => {
|
||||
menuDialogRef.value.openDialog(type, row);
|
||||
};
|
||||
// 删除当前行
|
||||
const onTabelRowDel = (row) => {
|
||||
|
|
@ -94,7 +108,13 @@ const onTabelRowDel = (row) => {
|
|||
})
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
getTableData();
|
||||
//await setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
getTableData();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,219 +0,0 @@
|
|||
<template>
|
||||
<div class="system-edit-role-container">
|
||||
<el-dialog title="修改角色" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="角色名称">
|
||||
<el-input v-model="state.ruleForm.roleName" placeholder="请输入角色名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="角色标识">
|
||||
<template #label>
|
||||
<el-tooltip effect="dark" content="用于 `router/route.ts` meta.roles" placement="top-start">
|
||||
<span>角色标识</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="state.ruleForm.roleSign" placeholder="请输入角色标识" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="state.ruleForm.sort" :min="0" :max="999" controls-position="right" placeholder="请输入排序" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="角色状态">
|
||||
<el-switch v-model="state.ruleForm.status" inline-prompt active-text="启" inactive-text="禁"></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="角色描述">
|
||||
<el-input v-model="state.ruleForm.describe" type="textarea" placeholder="请输入角色描述" maxlength="150"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="菜单权限">
|
||||
<el-tree
|
||||
:data="state.menuData"
|
||||
:props="state.menuProps"
|
||||
:default-checked-keys="[112, 113]"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
class="menu-data-tree"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">修 改</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemEditRole">
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
roleName: '', // 角色名称
|
||||
roleSign: '', // 角色标识
|
||||
sort: 0, // 排序
|
||||
status: true, // 角色状态
|
||||
describe: '', // 角色描述
|
||||
},
|
||||
menuData: [],
|
||||
menuProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row) => {
|
||||
state.ruleForm = row;
|
||||
state.isShowDialog = true;
|
||||
getMenuData();
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 获取菜单结构数据
|
||||
const getMenuData = () => {
|
||||
state.menuData = [
|
||||
{
|
||||
id: 1,
|
||||
label: '系统管理',
|
||||
children: [
|
||||
{
|
||||
id: 11,
|
||||
label: '菜单管理',
|
||||
children: [
|
||||
{
|
||||
id: 111,
|
||||
label: '菜单新增',
|
||||
},
|
||||
{
|
||||
id: 112,
|
||||
label: '菜单修改',
|
||||
},
|
||||
{
|
||||
id: 113,
|
||||
label: '菜单删除',
|
||||
},
|
||||
{
|
||||
id: 114,
|
||||
label: '菜单查询',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
label: '角色管理',
|
||||
children: [
|
||||
{
|
||||
id: 121,
|
||||
label: '角色新增',
|
||||
},
|
||||
{
|
||||
id: 122,
|
||||
label: '角色修改',
|
||||
},
|
||||
{
|
||||
id: 123,
|
||||
label: '角色删除',
|
||||
},
|
||||
{
|
||||
id: 124,
|
||||
label: '角色查询',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
label: '用户管理',
|
||||
children: [
|
||||
{
|
||||
id: 131,
|
||||
label: '用户新增',
|
||||
},
|
||||
{
|
||||
id: 132,
|
||||
label: '用户修改',
|
||||
},
|
||||
{
|
||||
id: 133,
|
||||
label: '用户删除',
|
||||
},
|
||||
{
|
||||
id: 134,
|
||||
label: '用户查询',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: '权限管理',
|
||||
children: [
|
||||
{
|
||||
id: 21,
|
||||
label: '前端控制',
|
||||
children: [
|
||||
{
|
||||
id: 211,
|
||||
label: '页面权限',
|
||||
},
|
||||
{
|
||||
id: 212,
|
||||
label: '页面权限',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
label: '后端控制',
|
||||
children: [
|
||||
{
|
||||
id: 221,
|
||||
label: '页面权限',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.system-edit-role-container {
|
||||
.menu-data-tree {
|
||||
width: 100%;
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="system-add-role-container">
|
||||
<el-dialog title="新增角色" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<div class="system-role-dialog-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="769px">
|
||||
<el-form ref="roleDialogFormRef" :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="角色名称">
|
||||
|
|
@ -43,17 +43,20 @@
|
|||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">新 增</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemAddRole">
|
||||
<script setup name="systemRoleDialog">
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const roleDialogFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
roleName: '', // 角色名称
|
||||
roleSign: '', // 角色标识
|
||||
|
|
@ -66,24 +69,44 @@ const state = reactive({
|
|||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
dialog: {
|
||||
isShowDialog: false,
|
||||
type: '',
|
||||
title: '',
|
||||
submitTxt: '',
|
||||
},
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
state.isShowDialog = true;
|
||||
const openDialog = (type, row) => {
|
||||
if (type === 'edit') {
|
||||
state.ruleForm = row;
|
||||
state.dialog.title = '修改角色';
|
||||
state.dialog.submitTxt = '修 改';
|
||||
} else {
|
||||
state.dialog.title = '新增角色';
|
||||
state.dialog.submitTxt = '新 增';
|
||||
// 清空表单,此项需加表单验证才能使用
|
||||
// nextTick(() => {
|
||||
// roleDialogFormRef.value.resetFields();
|
||||
// });
|
||||
}
|
||||
state.dialog.isShowDialog = true;
|
||||
getMenuData();
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
state.dialog.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
emit('refresh');
|
||||
// if (state.dialog.type === 'add') { }
|
||||
};
|
||||
// 获取菜单结构数据
|
||||
const getMenuData = () => {
|
||||
|
|
@ -200,7 +223,7 @@ defineExpose({
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.system-add-role-container {
|
||||
.system-role-dialog-container {
|
||||
.menu-data-tree {
|
||||
width: 100%;
|
||||
border: 1px solid var(--el-border-color);
|
||||
|
|
@ -9,14 +9,14 @@
|
|||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddRole">
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddRole('add')">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增角色
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="state.tableData.data" style="width: 100%">
|
||||
<el-table :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="roleName" label="角色名称" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="roleSign" label="角色标识" show-overflow-tooltip></el-table-column>
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button :disabled="scope.row.roleName === '超级管理员'" size="small" text type="primary" @click="onOpenEditRole(scope.row)"
|
||||
<el-button :disabled="scope.row.roleName === '超级管理员'" size="small" text type="primary" @click="onOpenEditRole('edit', scope.row)"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button :disabled="scope.row.roleName === '超级管理员'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
|
||||
|
|
@ -52,8 +52,7 @@
|
|||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
<AddRole ref="addRoleRef" />
|
||||
<EditRole ref="editRoleRef" />
|
||||
<RoleDialog ref="roleDialogRef" @refresh="getTableData()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -61,12 +60,10 @@
|
|||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
|
||||
// 引入组件
|
||||
const AddRole = defineAsyncComponent(() => import('/@/views/system/role/component/addRole.vue'));
|
||||
const EditRole = defineAsyncComponent(() => import('/@/views/system/role/component/editRole.vue'));
|
||||
const RoleDialog = defineAsyncComponent(() => import('/@/views/system/role/dialog.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const addRoleRef = ref();
|
||||
const editRoleRef = ref();
|
||||
const roleDialogRef = ref();
|
||||
const state = reactive({
|
||||
tableData: {
|
||||
data: [],
|
||||
|
|
@ -79,9 +76,9 @@ const state = reactive({
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const getTableData = () => {
|
||||
state.tableData.loading = true;
|
||||
const data = [];
|
||||
for (let i = 0; i < 20; i++) {
|
||||
data.push({
|
||||
|
|
@ -95,14 +92,17 @@ const initTableData = () => {
|
|||
}
|
||||
state.tableData.data = data;
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
setTimeout(() => {
|
||||
state.tableData.loading = false;
|
||||
}, 500);
|
||||
};
|
||||
// 打开新增角色弹窗
|
||||
const onOpenAddRole = () => {
|
||||
addRoleRef.value.openDialog();
|
||||
const onOpenAddRole = (type) => {
|
||||
roleDialogRef.value.openDialog(type);
|
||||
};
|
||||
// 打开修改角色弹窗
|
||||
const onOpenEditRole = (row) => {
|
||||
editRoleRef.value.openDialog(row);
|
||||
const onOpenEditRole = (type, row) => {
|
||||
roleDialogRef.value.openDialog(type, row);
|
||||
};
|
||||
// 删除角色
|
||||
const onRowDel = (row) => {
|
||||
|
|
@ -112,6 +112,7 @@ const onRowDel = (row) => {
|
|||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
getTableData();
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
|
|
@ -119,14 +120,16 @@ const onRowDel = (row) => {
|
|||
// 分页改变
|
||||
const onHandleSizeChange = (val) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
getTableData();
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val) => {
|
||||
state.tableData.param.pageNum = val;
|
||||
getTableData();
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
getTableData();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,166 +0,0 @@
|
|||
<template>
|
||||
<div class="system-edit-user-container">
|
||||
<el-dialog title="修改用户" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="账户名称">
|
||||
<el-input v-model="state.ruleForm.userName" placeholder="请输入账户名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="用户昵称">
|
||||
<el-input v-model="state.ruleForm.userNickname" placeholder="请输入用户昵称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="关联角色">
|
||||
<el-select v-model="state.ruleForm.roleSign" placeholder="请选择" clearable class="w100">
|
||||
<el-option label="超级管理员" value="admin"></el-option>
|
||||
<el-option label="普通用户" value="common"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="部门">
|
||||
<el-cascader
|
||||
:options="state.deptData"
|
||||
:props="{ checkStrictly: true, value: 'deptName', label: 'deptName' }"
|
||||
placeholder="请选择部门"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="state.ruleForm.department"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.deptName }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="state.ruleForm.phone" placeholder="请输入手机号" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="state.ruleForm.email" placeholder="请输入" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="性别">
|
||||
<el-select v-model="state.ruleForm.sex" placeholder="请选择" clearable class="w100">
|
||||
<el-option label="男" value="男"></el-option>
|
||||
<el-option label="女" value="女"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="账户密码">
|
||||
<el-input v-model="state.ruleForm.password" placeholder="请输入" type="password" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="账户过期">
|
||||
<el-date-picker v-model="state.ruleForm.overdueTime" type="date" placeholder="请选择" class="w100"> </el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="用户状态">
|
||||
<el-switch v-model="state.ruleForm.status" inline-prompt active-text="启" inactive-text="禁"></el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="用户描述">
|
||||
<el-input v-model="state.ruleForm.describe" type="textarea" placeholder="请输入用户描述" maxlength="150"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">修 改</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemEditUser">
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
userName: '', // 账户名称
|
||||
userNickname: '', // 用户昵称
|
||||
roleSign: '', // 关联角色
|
||||
department: [], // 部门
|
||||
phone: '', // 手机号
|
||||
email: '', // 邮箱
|
||||
sex: '', // 性别
|
||||
password: '', // 账户密码
|
||||
overdueTime: '', // 账户过期
|
||||
status: true, // 用户状态
|
||||
describe: '', // 用户描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row) => {
|
||||
state.ruleForm = row;
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 初始化部门数据
|
||||
const initTableData = () => {
|
||||
state.deptData.push({
|
||||
deptName: 'vueNextAdmin',
|
||||
createTime: new Date().toLocaleString(),
|
||||
status: true,
|
||||
sort: Math.random(),
|
||||
describe: '顶级部门',
|
||||
id: Math.random(),
|
||||
children: [
|
||||
{
|
||||
deptName: 'IT外包服务',
|
||||
createTime: new Date().toLocaleString(),
|
||||
status: true,
|
||||
sort: Math.random(),
|
||||
describe: '总部',
|
||||
id: Math.random(),
|
||||
},
|
||||
{
|
||||
deptName: '资本控股',
|
||||
createTime: new Date().toLocaleString(),
|
||||
status: true,
|
||||
sort: Math.random(),
|
||||
describe: '分部',
|
||||
id: Math.random(),
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="system-add-user-container">
|
||||
<el-dialog title="新增用户" v-model="state.isShowDialog" width="769px">
|
||||
<el-form :model="state.ruleForm" size="default" label-width="90px">
|
||||
<div class="system-user-dialog-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="769px">
|
||||
<el-form ref="userDialogFormRef" :model="state.ruleForm" size="default" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="账户名称">
|
||||
|
|
@ -81,17 +81,20 @@
|
|||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">新 增</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="systemAddUser">
|
||||
<script setup name="systemUserDialog">
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const userDialogFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
userName: '', // 账户名称
|
||||
userNickname: '', // 用户昵称
|
||||
|
|
@ -106,26 +109,47 @@ const state = reactive({
|
|||
describe: '', // 用户描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
dialog: {
|
||||
isShowDialog: false,
|
||||
type: '',
|
||||
title: '',
|
||||
submitTxt: '',
|
||||
},
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
state.isShowDialog = true;
|
||||
const openDialog = (type, row) => {
|
||||
if (type === 'edit') {
|
||||
state.ruleForm = row;
|
||||
state.dialog.title = '修改用户';
|
||||
state.dialog.submitTxt = '修 改';
|
||||
} else {
|
||||
state.dialog.title = '新增用户';
|
||||
state.dialog.submitTxt = '新 增';
|
||||
// 清空表单,此项需加表单验证才能使用
|
||||
// nextTick(() => {
|
||||
// userDialogFormRef.value.resetFields();
|
||||
// });
|
||||
}
|
||||
state.dialog.isShowDialog = true;
|
||||
getMenuData();
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
state.dialog.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 新增
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
closeDialog();
|
||||
emit('refresh');
|
||||
// if (state.dialog.type === 'add') { }
|
||||
};
|
||||
// 初始化部门数据
|
||||
const initTableData = () => {
|
||||
const getMenuData = () => {
|
||||
state.deptData.push({
|
||||
deptName: 'vueNextAdmin',
|
||||
createTime: new Date().toLocaleString(),
|
||||
|
|
@ -153,10 +177,6 @@ const initTableData = () => {
|
|||
],
|
||||
});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
|
|
@ -9,14 +9,14 @@
|
|||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddUser">
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddUser('add')">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增用户
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="state.tableData.data" style="width: 100%">
|
||||
<el-table :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="userName" label="账户名称" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="userNickname" label="用户昵称" show-overflow-tooltip></el-table-column>
|
||||
|
|
@ -34,7 +34,9 @@
|
|||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenEditUser(scope.row)">修改</el-button>
|
||||
<el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenEditUser('edit', scope.row)"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -53,8 +55,7 @@
|
|||
>
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
<AddUer ref="addUserRef" />
|
||||
<EditUser ref="editUserRef" />
|
||||
<UserDialog ref="userDialogRef" @refresh="getTableData()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -62,12 +63,10 @@
|
|||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
|
||||
// 引入组件
|
||||
const AddUer = defineAsyncComponent(() => import('/@/views/system/user/component/addUser.vue'));
|
||||
const EditUser = defineAsyncComponent(() => import('/@/views/system/user/component/editUser.vue'));
|
||||
const UserDialog = defineAsyncComponent(() => import('/@/views/system/user/dialog.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const addUserRef = ref();
|
||||
const editUserRef = ref();
|
||||
const userDialogRef = ref();
|
||||
const state = reactive({
|
||||
tableData: {
|
||||
data: [],
|
||||
|
|
@ -81,7 +80,8 @@ const state = reactive({
|
|||
});
|
||||
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const getTableData = () => {
|
||||
state.tableData.loading = true;
|
||||
const data = [];
|
||||
for (let i = 0; i < 2; i++) {
|
||||
data.push({
|
||||
|
|
@ -101,14 +101,17 @@ const initTableData = () => {
|
|||
}
|
||||
state.tableData.data = data;
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
setTimeout(() => {
|
||||
state.tableData.loading = false;
|
||||
}, 500);
|
||||
};
|
||||
// 打开新增用户弹窗
|
||||
const onOpenAddUser = () => {
|
||||
addUserRef.value.openDialog();
|
||||
const onOpenAddUser = (type) => {
|
||||
userDialogRef.value.openDialog(type);
|
||||
};
|
||||
// 打开修改用户弹窗
|
||||
const onOpenEditUser = (row) => {
|
||||
editUserRef.value.openDialog(row);
|
||||
const onOpenEditUser = (type, row) => {
|
||||
userDialogRef.value.openDialog(type, row);
|
||||
};
|
||||
// 删除用户
|
||||
const onRowDel = (row) => {
|
||||
|
|
@ -118,6 +121,7 @@ const onRowDel = (row) => {
|
|||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
getTableData();
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
|
|
@ -125,14 +129,16 @@ const onRowDel = (row) => {
|
|||
// 分页改变
|
||||
const onHandleSizeChange = (val) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
getTableData();
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val) => {
|
||||
state.tableData.param.pageNum = val;
|
||||
getTableData();
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
getTableData();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const viteConfig = defineConfig((mode) => {
|
|||
host: '0.0.0.0',
|
||||
port: env.VITE_PORT,
|
||||
open: env.VITE_OPEN,
|
||||
hmr: true,
|
||||
proxy: {
|
||||
'/gitee': {
|
||||
target: 'https://gitee.com',
|
||||
|
|
@ -40,7 +41,6 @@ const viteConfig = defineConfig((mode) => {
|
|||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
sourcemap: false,
|
||||
chunkSizeWarningLimit: 1500,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue