初始化提交
This commit is contained in:
173
web/src/views/system/dept/component/addDept.vue
Normal file
173
web/src/views/system/dept/component/addDept.vue
Normal file
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div class="system-add-dept-container">
|
||||
<el-dialog title="新增部门" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="deptData"
|
||||
:props="{ checkStrictly: true, value: 'deptName', label: 'deptName' }"
|
||||
placeholder="请选择部门"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="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="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="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="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="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="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="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="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 lang="ts">
|
||||
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface TableDataRow {
|
||||
deptName: string;
|
||||
createTime: string;
|
||||
status: boolean;
|
||||
sort: number;
|
||||
describe: string;
|
||||
id: number;
|
||||
children?: TableDataRow[];
|
||||
}
|
||||
interface DeptSate {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: {
|
||||
deptLevel: Array<string>;
|
||||
deptName: string;
|
||||
person: string;
|
||||
phone: string | number;
|
||||
email: string;
|
||||
sort: number;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
};
|
||||
deptData: Array<TableDataRow>;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemAddDept',
|
||||
setup() {
|
||||
const state = reactive<DeptSate>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
deptLevel: [], // 上级部门
|
||||
deptName: '', // 部门名称
|
||||
person: '', // 负责人
|
||||
phone: '', // 手机号
|
||||
email: '', // 邮箱
|
||||
sort: 0, // 排序
|
||||
status: true, // 部门状态
|
||||
describe: '', // 部门描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
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();
|
||||
});
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
179
web/src/views/system/dept/component/editDept.vue
Normal file
179
web/src/views/system/dept/component/editDept.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div class="system-edit-dept-container">
|
||||
<el-dialog title="修改部门" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="deptData"
|
||||
:props="{ checkStrictly: true, value: 'deptName', label: 'deptName' }"
|
||||
placeholder="请选择部门"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="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="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="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="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="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="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="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="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 lang="ts">
|
||||
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface TableDataRow {
|
||||
deptName: string;
|
||||
createTime: string;
|
||||
status: boolean;
|
||||
sort: number;
|
||||
describe: string;
|
||||
id: number;
|
||||
children?: TableDataRow[];
|
||||
}
|
||||
interface RuleFormState {
|
||||
deptLevel: Array<string>;
|
||||
deptName: string;
|
||||
person: string;
|
||||
phone: string | number;
|
||||
email: string;
|
||||
sort: number;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
}
|
||||
interface DeptSate {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: RuleFormState;
|
||||
deptData: Array<TableDataRow>;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemEditDept',
|
||||
setup() {
|
||||
const state = reactive<DeptSate>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
deptLevel: [], // 上级部门
|
||||
deptName: '', // 部门名称
|
||||
person: '', // 负责人
|
||||
phone: '', // 手机号
|
||||
email: '', // 邮箱
|
||||
sort: 0, // 排序
|
||||
status: true, // 部门状态
|
||||
describe: '', // 部门描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row: RuleFormState) => {
|
||||
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();
|
||||
});
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
163
web/src/views/system/dept/index.vue
Normal file
163
web/src/views/system/dept/index.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div class="system-dept-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="system-dept-search mb15">
|
||||
<el-input size="default" placeholder="请输入部门名称" style="max-width: 180px"> </el-input>
|
||||
<el-button size="default" type="primary" class="ml10">
|
||||
<el-icon>
|
||||
<ele-Search />
|
||||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddDept">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增部门
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="tableData.data"
|
||||
style="width: 100%"
|
||||
row-key="id"
|
||||
default-expand-all
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column prop="deptName" label="部门名称" show-overflow-tooltip> </el-table-column>
|
||||
<el-table-column label="排序" show-overflow-tooltip width="80">
|
||||
<template #default="scope">
|
||||
{{ scope.$index }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="部门状态" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="scope.row.status">启用</el-tag>
|
||||
<el-tag type="info" v-else>禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="describe" label="部门描述" show-overflow-tooltip></el-table-column>
|
||||
<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="onTabelRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<AddDept ref="addDeptRef" />
|
||||
<EditDept ref="editDeptRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, toRefs, reactive, onMounted, defineComponent } from 'vue';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import AddDept from '/@/views/system/dept/component/addDept.vue';
|
||||
import EditDept from '/@/views/system/dept/component/editDept.vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface TableDataRow {
|
||||
deptName: string;
|
||||
createTime: string;
|
||||
status: boolean;
|
||||
sort: number;
|
||||
describe: string;
|
||||
id: number;
|
||||
children?: TableDataRow[];
|
||||
}
|
||||
interface TableDataState {
|
||||
tableData: {
|
||||
data: Array<TableDataRow>;
|
||||
total: number;
|
||||
loading: boolean;
|
||||
param: {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemDept',
|
||||
components: { AddDept, EditDept },
|
||||
setup() {
|
||||
const addDeptRef = ref();
|
||||
const editDeptRef = ref();
|
||||
const state = reactive<TableDataState>({
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
state.tableData.data.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(),
|
||||
},
|
||||
],
|
||||
});
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
};
|
||||
// 打开新增菜单弹窗
|
||||
const onOpenAddDept = () => {
|
||||
addDeptRef.value.openDialog();
|
||||
};
|
||||
// 打开编辑菜单弹窗
|
||||
const onOpenEditDept = (row: TableDataRow) => {
|
||||
editDeptRef.value.openDialog(row);
|
||||
};
|
||||
// 删除当前行
|
||||
const onTabelRowDel = (row: TableDataRow) => {
|
||||
ElMessageBox.confirm(`此操作将永久删除部门:${row.deptName}, 是否继续?`, '提示', {
|
||||
confirmButtonText: '删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
return {
|
||||
addDeptRef,
|
||||
editDeptRef,
|
||||
onOpenAddDept,
|
||||
onOpenEditDept,
|
||||
onTabelRowDel,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
129
web/src/views/system/dic/component/addDic.vue
Normal file
129
web/src/views/system/dic/component/addDic.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="system-add-dic-container">
|
||||
<el-dialog title="新增字典" v-model="isShowDialog" width="769px">
|
||||
<el-alert title="半成品,交互过于复杂,请自行扩展!" type="warning" :closable="false" class="mb20"> </el-alert>
|
||||
<el-form :model="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="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="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="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 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="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 lang="ts">
|
||||
import { reactive, toRefs, defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemAddDic',
|
||||
setup() {
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
dicName: '', // 字典名称
|
||||
fieldName: '', // 字段名
|
||||
status: true, // 字典状态
|
||||
list: [
|
||||
// 子集字段 + 属性值
|
||||
{
|
||||
id: Math.random(),
|
||||
label: '',
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
describe: '', // 字典描述
|
||||
fieldNameList: [], // 字段名: [{子集字段 + 属性值}]
|
||||
},
|
||||
});
|
||||
// 打开弹窗
|
||||
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: number) => {
|
||||
state.ruleForm.list.splice(k, 1);
|
||||
};
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
onAddRow,
|
||||
onDelRow,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
162
web/src/views/system/dic/component/editDic.vue
Normal file
162
web/src/views/system/dic/component/editDic.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div class="system-edit-dic-container">
|
||||
<el-dialog title="修改字典" v-model="isShowDialog" width="769px">
|
||||
<el-alert title="半成品,交互过于复杂,请自行扩展!" type="warning" :closable="false" class="mb20"> </el-alert>
|
||||
<el-form :model="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="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="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="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 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="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 lang="ts">
|
||||
import { reactive, toRefs, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface RuleFormList {
|
||||
id: number;
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
interface RuleFormState {
|
||||
dicName: string;
|
||||
fieldName: string;
|
||||
status: boolean;
|
||||
list: RuleFormList[];
|
||||
describe: string;
|
||||
fieldNameList: Array<any>;
|
||||
}
|
||||
interface DicState {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: RuleFormState;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemEditDic',
|
||||
setup() {
|
||||
const state = reactive<DicState>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
dicName: '', // 字典名称
|
||||
fieldName: '', // 字段名
|
||||
status: true, // 字典状态
|
||||
list: [
|
||||
// 子集字段 + 属性值
|
||||
{
|
||||
id: Math.random(),
|
||||
label: '',
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
describe: '', // 字典描述
|
||||
fieldNameList: [], // 字段名: [{子集字段 + 属性值}]
|
||||
},
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row: RuleFormState) => {
|
||||
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.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: number) => {
|
||||
state.ruleForm.list.splice(k, 1);
|
||||
};
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
onAddRow,
|
||||
onDelRow,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
159
web/src/views/system/dic/index.vue
Normal file
159
web/src/views/system/dic/index.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="system-dic-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="system-user-search mb15">
|
||||
<el-input size="default" placeholder="请输入字典名称" style="max-width: 180px"> </el-input>
|
||||
<el-button size="default" type="primary" class="ml10">
|
||||
<el-icon>
|
||||
<ele-Search />
|
||||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddDic">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增字典
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData.data" 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>
|
||||
<el-table-column prop="status" label="字典状态" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="scope.row.status">启用</el-tag>
|
||||
<el-tag type="info" v-else>禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="describe" label="字典描述" show-overflow-tooltip></el-table-column>
|
||||
<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="onRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="onHandleSizeChange"
|
||||
@current-change="onHandleCurrentChange"
|
||||
class="mt15"
|
||||
:pager-count="5"
|
||||
:page-sizes="[10, 20, 30]"
|
||||
v-model:current-page="tableData.param.pageNum"
|
||||
background
|
||||
v-model:page-size="tableData.param.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total"
|
||||
>
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
<AddDic ref="addDicRef" />
|
||||
<EditDic ref="editDicRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import AddDic from '/@/views/system/dic/component/addDic.vue';
|
||||
import EditDic from '/@/views/system/dic/component/editDic.vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface TableDataRow {
|
||||
dicName: string;
|
||||
fieldName: string;
|
||||
describe: string;
|
||||
status: boolean;
|
||||
createTime: string;
|
||||
}
|
||||
interface TableDataState {
|
||||
tableData: {
|
||||
data: Array<TableDataRow>;
|
||||
total: number;
|
||||
loading: boolean;
|
||||
param: {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemDic',
|
||||
components: { AddDic, EditDic },
|
||||
setup() {
|
||||
const addDicRef = ref();
|
||||
const editDicRef = ref();
|
||||
const state = reactive<TableDataState>({
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const data: Array<TableDataRow> = [];
|
||||
for (let i = 0; i < 2; i++) {
|
||||
data.push({
|
||||
dicName: i === 0 ? '角色标识' : '用户性别',
|
||||
fieldName: i === 0 ? 'SYS_ROLE' : 'SYS_UERINFO',
|
||||
describe: i === 0 ? '这是角色字典' : '这是用户性别字典',
|
||||
status: true,
|
||||
createTime: new Date().toLocaleString(),
|
||||
});
|
||||
}
|
||||
state.tableData.data = data;
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
};
|
||||
// 打开新增字典弹窗
|
||||
const onOpenAddDic = () => {
|
||||
addDicRef.value.openDialog();
|
||||
};
|
||||
// 打开修改字典弹窗
|
||||
const onOpenEditDic = (row: TableDataRow) => {
|
||||
editDicRef.value.openDialog(row);
|
||||
};
|
||||
// 删除字典
|
||||
const onRowDel = (row: TableDataRow) => {
|
||||
ElMessageBox.confirm(`此操作将永久删除字典名称:“${row.dicName}”,是否继续?`, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleSizeChange = (val: number) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val: number) => {
|
||||
state.tableData.param.pageNum = val;
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
return {
|
||||
addDicRef,
|
||||
editDicRef,
|
||||
onOpenAddDic,
|
||||
onOpenEditDic,
|
||||
onRowDel,
|
||||
onHandleSizeChange,
|
||||
onHandleCurrentChange,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
230
web/src/views/system/menu/component/addMenu.vue
Normal file
230
web/src/views/system/menu/component/addMenu.vue
Normal file
@@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<div class="system-add-menu-container">
|
||||
<el-dialog title="新增菜单" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="menuData"
|
||||
:props="{ checkStrictly: true, value: 'path', label: 'title' }"
|
||||
placeholder="请选择上级菜单"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="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="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="ruleForm.meta.title" placeholder="格式:message.router.xxx" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="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="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="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="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="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="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="ruleForm.meta.isLink" placeholder="外链/内嵌时链接地址(http:xxx.com)" clearable :disabled="!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="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="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="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="ruleForm.menuSort" controls-position="right" placeholder="请输入排序" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="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="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="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="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="ruleForm.isLink" :disabled="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="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 lang="ts">
|
||||
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
import { i18n } from '/@/i18n/index';
|
||||
import IconSelector from '/@/components/iconSelector/index.vue';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemAddMenu',
|
||||
components: { IconSelector },
|
||||
setup() {
|
||||
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: [], // 上级菜单数据
|
||||
});
|
||||
// 获取 vuex 中的路由
|
||||
const getMenuData = (routes: any) => {
|
||||
const arr: any = [];
|
||||
routes.map((val: any) => {
|
||||
val['title'] = i18n.global.t(val.meta.title);
|
||||
val['id'] = Math.random();
|
||||
arr.push({ ...val });
|
||||
if (val.children) getMenuData(val.children);
|
||||
});
|
||||
return arr;
|
||||
};
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
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);
|
||||
});
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onSelectIframeChange,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
238
web/src/views/system/menu/component/editMenu.vue
Normal file
238
web/src/views/system/menu/component/editMenu.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div class="system-edit-menu-container">
|
||||
<el-dialog title="修改菜单" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="menuData"
|
||||
:props="{ checkStrictly: true, value: 'path', label: 'title' }"
|
||||
placeholder="请选择上级菜单"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="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="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="ruleForm.meta.title" placeholder="格式:message.router.xxx" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="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="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="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="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="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="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="ruleForm.meta.isLink" placeholder="外链/内嵌时链接地址(http:xxx.com)" clearable :disabled="!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="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="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="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="ruleForm.menuSort" controls-position="right" placeholder="请输入排序" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="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="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="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="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="ruleForm.isLink" :disabled="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="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 lang="ts">
|
||||
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
import { i18n } from '/@/i18n/index';
|
||||
import IconSelector from '/@/components/iconSelector/index.vue';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemEditMenu',
|
||||
components: { IconSelector },
|
||||
setup() {
|
||||
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: [], // 上级菜单数据
|
||||
});
|
||||
// 获取 vuex 中的路由
|
||||
const getMenuData = (routes: any) => {
|
||||
const arr: any = [];
|
||||
routes.map((val: any) => {
|
||||
val['title'] = i18n.global.t(val.meta.title);
|
||||
val['id'] = Math.random();
|
||||
arr.push({ ...val });
|
||||
if (val.children) getMenuData(val.children);
|
||||
});
|
||||
return arr;
|
||||
};
|
||||
// 打开弹窗
|
||||
const openDialog = (row: any) => {
|
||||
// 模拟数据,实际请走接口
|
||||
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);
|
||||
});
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onSelectIframeChange,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
114
web/src/views/system/menu/index.vue
Normal file
114
web/src/views/system/menu/index.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div class="system-menu-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="system-menu-search mb15">
|
||||
<el-input size="default" placeholder="请输入菜单名称" style="max-width: 180px"> </el-input>
|
||||
<el-button size="default" type="primary" class="ml10">
|
||||
<el-icon>
|
||||
<ele-Search />
|
||||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddMenu">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增菜单
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="menuTableData" 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" />
|
||||
<span class="ml10">{{ $t(scope.row.meta.title) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="path" label="路由路径" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="组件路径" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.component }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="权限标识" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.meta.roles }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" show-overflow-tooltip width="80">
|
||||
<template #default="scope">
|
||||
{{ scope.$index }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" show-overflow-tooltip width="80">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" size="small">{{ scope.row.xx }}菜单</el-tag>
|
||||
</template>
|
||||
</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="onTabelRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<AddMenu ref="addMenuRef" />
|
||||
<EditMenu ref="editMenuRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, toRefs, reactive, computed, defineComponent } from 'vue';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
import AddMenu from '/@/views/system/menu/component/addMenu.vue';
|
||||
import EditMenu from '/@/views/system/menu/component/editMenu.vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemMenu',
|
||||
components: { AddMenu, EditMenu },
|
||||
setup() {
|
||||
const stores = useRoutesList();
|
||||
const { routesList } = storeToRefs(stores);
|
||||
const addMenuRef = ref();
|
||||
const editMenuRef = ref();
|
||||
const state = reactive({});
|
||||
// 获取 vuex 中的路由
|
||||
const menuTableData = computed(() => {
|
||||
return routesList.value;
|
||||
});
|
||||
// 打开新增菜单弹窗
|
||||
const onOpenAddMenu = () => {
|
||||
addMenuRef.value.openDialog();
|
||||
};
|
||||
// 打开编辑菜单弹窗
|
||||
const onOpenEditMenu = (row: RouteRecordRaw) => {
|
||||
editMenuRef.value.openDialog(row);
|
||||
};
|
||||
// 删除当前行
|
||||
const onTabelRowDel = (row: RouteRecordRaw) => {
|
||||
ElMessageBox.confirm(`此操作将永久删除路由:${row.path}, 是否继续?`, '提示', {
|
||||
confirmButtonText: '删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
return {
|
||||
addMenuRef,
|
||||
editMenuRef,
|
||||
onOpenAddMenu,
|
||||
onOpenEditMenu,
|
||||
menuTableData,
|
||||
onTabelRowDel,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
240
web/src/views/system/role/component/addRole.vue
Normal file
240
web/src/views/system/role/component/addRole.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div class="system-add-role-container">
|
||||
<el-dialog title="新增角色" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="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="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="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="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="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="menuData" :props="menuProps" 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 lang="ts">
|
||||
import { reactive, toRefs, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface MenuDataTree {
|
||||
id: number;
|
||||
label: string;
|
||||
children?: MenuDataTree[];
|
||||
}
|
||||
interface RoleState {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: {
|
||||
roleName: string;
|
||||
roleSign: string;
|
||||
sort: number;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
};
|
||||
menuData: Array<MenuDataTree>;
|
||||
menuProps: {
|
||||
children: string;
|
||||
label: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemAddRole',
|
||||
setup() {
|
||||
const state = reactive<RoleState>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
roleName: '', // 角色名称
|
||||
roleSign: '', // 角色标识
|
||||
sort: 0, // 排序
|
||||
status: true, // 角色状态
|
||||
describe: '', // 角色描述
|
||||
},
|
||||
menuData: [],
|
||||
menuProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
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: '页面权限',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.system-add-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>
|
||||
242
web/src/views/system/role/component/editRole.vue
Normal file
242
web/src/views/system/role/component/editRole.vue
Normal file
@@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<div class="system-edit-role-container">
|
||||
<el-dialog title="修改角色" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="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="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="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="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="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="menuData" :props="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 lang="ts">
|
||||
import { reactive, toRefs, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface MenuDataTree {
|
||||
id: number;
|
||||
label: string;
|
||||
children?: MenuDataTree[];
|
||||
}
|
||||
interface DialogRow {
|
||||
roleName: string;
|
||||
roleSign: string;
|
||||
sort: number;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
}
|
||||
interface RoleState {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: DialogRow;
|
||||
menuData: Array<MenuDataTree>;
|
||||
menuProps: {
|
||||
children: string;
|
||||
label: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemEditRole',
|
||||
setup() {
|
||||
const state = reactive<RoleState>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
roleName: '', // 角色名称
|
||||
roleSign: '', // 角色标识
|
||||
sort: 0, // 排序
|
||||
status: true, // 角色状态
|
||||
describe: '', // 角色描述
|
||||
},
|
||||
menuData: [],
|
||||
menuProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row: DialogRow) => {
|
||||
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: '页面权限',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</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>
|
||||
164
web/src/views/system/role/index.vue
Normal file
164
web/src/views/system/role/index.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div class="system-role-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="system-user-search mb15">
|
||||
<el-input size="default" placeholder="请输入角色名称" style="max-width: 180px"> </el-input>
|
||||
<el-button size="default" type="primary" class="ml10">
|
||||
<el-icon>
|
||||
<ele-Search />
|
||||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddRole">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增角色
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData.data" 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>
|
||||
<el-table-column prop="sort" label="排序" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="status" label="角色状态" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="scope.row.status">启用</el-tag>
|
||||
<el-tag type="info" v-else>禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="describe" label="角色描述" show-overflow-tooltip></el-table-column>
|
||||
<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
|
||||
>
|
||||
<el-button :disabled="scope.row.roleName === '超级管理员'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="onHandleSizeChange"
|
||||
@current-change="onHandleCurrentChange"
|
||||
class="mt15"
|
||||
:pager-count="5"
|
||||
:page-sizes="[10, 20, 30]"
|
||||
v-model:current-page="tableData.param.pageNum"
|
||||
background
|
||||
v-model:page-size="tableData.param.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total"
|
||||
>
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
<AddRole ref="addRoleRef" />
|
||||
<EditRole ref="editRoleRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import AddRole from '/@/views/system/role/component/addRole.vue';
|
||||
import EditRole from '/@/views/system/role/component/editRole.vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface TableData {
|
||||
roleName: string;
|
||||
roleSign: string;
|
||||
describe: string;
|
||||
sort: number;
|
||||
status: boolean;
|
||||
createTime: string;
|
||||
}
|
||||
interface TableDataState {
|
||||
tableData: {
|
||||
data: Array<TableData>;
|
||||
total: number;
|
||||
loading: boolean;
|
||||
param: {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemRole',
|
||||
components: { AddRole, EditRole },
|
||||
setup() {
|
||||
const addRoleRef = ref();
|
||||
const editRoleRef = ref();
|
||||
const state = reactive<TableDataState>({
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const data: Array<TableData> = [];
|
||||
for (let i = 0; i < 2; i++) {
|
||||
data.push({
|
||||
roleName: i === 0 ? '超级管理员' : '普通用户',
|
||||
roleSign: i === 0 ? 'admin' : 'common',
|
||||
describe: `测试角色${i + 1}`,
|
||||
sort: i,
|
||||
status: true,
|
||||
createTime: new Date().toLocaleString(),
|
||||
});
|
||||
}
|
||||
state.tableData.data = data;
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
};
|
||||
// 打开新增角色弹窗
|
||||
const onOpenAddRole = () => {
|
||||
addRoleRef.value.openDialog();
|
||||
};
|
||||
// 打开修改角色弹窗
|
||||
const onOpenEditRole = (row: Object) => {
|
||||
editRoleRef.value.openDialog(row);
|
||||
};
|
||||
// 删除角色
|
||||
const onRowDel = (row: any) => {
|
||||
ElMessageBox.confirm(`此操作将永久删除角色名称:“${row.roleName}”,是否继续?`, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleSizeChange = (val: number) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val: number) => {
|
||||
state.tableData.param.pageNum = val;
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
return {
|
||||
addRoleRef,
|
||||
editRoleRef,
|
||||
onOpenAddRole,
|
||||
onOpenEditRole,
|
||||
onRowDel,
|
||||
onHandleSizeChange,
|
||||
onHandleCurrentChange,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
200
web/src/views/system/user/component/addUser.vue
Normal file
200
web/src/views/system/user/component/addUser.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div class="system-add-user-container">
|
||||
<el-dialog title="新增用户" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="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="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="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="deptData"
|
||||
:props="{ checkStrictly: true, value: 'deptName', label: 'deptName' }"
|
||||
placeholder="请选择部门"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="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="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="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="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="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="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="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="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 lang="ts">
|
||||
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface DeptData {
|
||||
deptName: string;
|
||||
createTime: string;
|
||||
status: boolean;
|
||||
sort: number | string;
|
||||
describe: string;
|
||||
id: number;
|
||||
children?: DeptData[];
|
||||
}
|
||||
interface UserState {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: {
|
||||
userName: string;
|
||||
userNickname: string;
|
||||
roleSign: string;
|
||||
department: any;
|
||||
phone: string;
|
||||
email: string;
|
||||
sex: string;
|
||||
password: string;
|
||||
overdueTime: string;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
};
|
||||
deptData: Array<DeptData>;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemAddUser',
|
||||
setup() {
|
||||
const state = reactive<UserState>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
userName: '', // 账户名称
|
||||
userNickname: '', // 用户昵称
|
||||
roleSign: '', // 关联角色
|
||||
department: [], // 部门
|
||||
phone: '', // 手机号
|
||||
email: '', // 邮箱
|
||||
sex: '', // 性别
|
||||
password: '', // 账户密码
|
||||
overdueTime: '', // 账户过期
|
||||
status: true, // 用户状态
|
||||
describe: '', // 用户描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
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();
|
||||
});
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
202
web/src/views/system/user/component/editUser.vue
Normal file
202
web/src/views/system/user/component/editUser.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="system-edit-user-container">
|
||||
<el-dialog title="修改用户" v-model="isShowDialog" width="769px">
|
||||
<el-form :model="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="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="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="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="deptData"
|
||||
:props="{ checkStrictly: true, value: 'deptName', label: 'deptName' }"
|
||||
placeholder="请选择部门"
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="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="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="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="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="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="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="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="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 lang="ts">
|
||||
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface DeptData {
|
||||
deptName: string;
|
||||
createTime: string;
|
||||
status: boolean;
|
||||
sort: number | string;
|
||||
describe: string;
|
||||
id: number;
|
||||
children?: DeptData[];
|
||||
}
|
||||
interface RuleFormRow {
|
||||
userName: string;
|
||||
userNickname: string;
|
||||
roleSign: string;
|
||||
department: any;
|
||||
phone: string;
|
||||
email: string;
|
||||
sex: string;
|
||||
password: string;
|
||||
overdueTime: string;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
}
|
||||
interface UserState {
|
||||
isShowDialog: boolean;
|
||||
ruleForm: RuleFormRow;
|
||||
deptData: Array<DeptData>;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemEditUser',
|
||||
setup() {
|
||||
const state = reactive<UserState>({
|
||||
isShowDialog: false,
|
||||
ruleForm: {
|
||||
userName: '', // 账户名称
|
||||
userNickname: '', // 用户昵称
|
||||
roleSign: '', // 关联角色
|
||||
department: [], // 部门
|
||||
phone: '', // 手机号
|
||||
email: '', // 邮箱
|
||||
sex: '', // 性别
|
||||
password: '', // 账户密码
|
||||
overdueTime: '', // 账户过期
|
||||
status: true, // 用户状态
|
||||
describe: '', // 用户描述
|
||||
},
|
||||
deptData: [], // 部门数据
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row: RuleFormRow) => {
|
||||
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();
|
||||
});
|
||||
return {
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
177
web/src/views/system/user/index.vue
Normal file
177
web/src/views/system/user/index.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div class="system-user-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="system-user-search mb15">
|
||||
<el-input size="default" placeholder="请输入用户名称" style="max-width: 180px"> </el-input>
|
||||
<el-button size="default" type="primary" class="ml10">
|
||||
<el-icon>
|
||||
<ele-Search />
|
||||
</el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="default" type="success" class="ml10" @click="onOpenAddUser">
|
||||
<el-icon>
|
||||
<ele-FolderAdd />
|
||||
</el-icon>
|
||||
新增用户
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData.data" 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>
|
||||
<el-table-column prop="roleSign" label="关联角色" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="department" label="部门" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="phone" label="手机号" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="email" label="邮箱" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="status" label="用户状态" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="scope.row.status">启用</el-tag>
|
||||
<el-tag type="info" v-else>禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="describe" label="用户描述" show-overflow-tooltip></el-table-column>
|
||||
<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="onRowDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="onHandleSizeChange"
|
||||
@current-change="onHandleCurrentChange"
|
||||
class="mt15"
|
||||
:pager-count="5"
|
||||
:page-sizes="[10, 20, 30]"
|
||||
v-model:current-page="tableData.param.pageNum"
|
||||
background
|
||||
v-model:page-size="tableData.param.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total"
|
||||
>
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
<AddUer ref="addUserRef" />
|
||||
<EditUser ref="editUserRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import AddUer from '/@/views/system/user/component/addUser.vue';
|
||||
import EditUser from '/@/views/system/user/component/editUser.vue';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface TableDataRow {
|
||||
userName: string;
|
||||
userNickname: string;
|
||||
roleSign: string;
|
||||
department: string[];
|
||||
phone: string;
|
||||
email: string;
|
||||
sex: string;
|
||||
password: string;
|
||||
overdueTime: Date;
|
||||
status: boolean;
|
||||
describe: string;
|
||||
createTime: string;
|
||||
}
|
||||
interface TableDataState {
|
||||
tableData: {
|
||||
data: Array<TableDataRow>;
|
||||
total: number;
|
||||
loading: boolean;
|
||||
param: {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'systemUser',
|
||||
components: { AddUer, EditUser },
|
||||
setup() {
|
||||
const addUserRef = ref();
|
||||
const editUserRef = ref();
|
||||
const state = reactive<TableDataState>({
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
const data: Array<TableDataRow> = [];
|
||||
for (let i = 0; i < 2; i++) {
|
||||
data.push({
|
||||
userName: i === 0 ? 'admin' : 'test',
|
||||
userNickname: i === 0 ? '我是管理员' : '我是普通用户',
|
||||
roleSign: i === 0 ? 'admin' : 'common',
|
||||
department: i === 0 ? ['vueNextAdmin', 'IT外包服务'] : ['vueNextAdmin', '资本控股'],
|
||||
phone: '12345678910',
|
||||
email: 'vueNextAdmin@123.com',
|
||||
sex: '女',
|
||||
password: '123456',
|
||||
overdueTime: new Date(),
|
||||
status: true,
|
||||
describe: i === 0 ? '不可删除' : '测试用户',
|
||||
createTime: new Date().toLocaleString(),
|
||||
});
|
||||
}
|
||||
state.tableData.data = data;
|
||||
state.tableData.total = state.tableData.data.length;
|
||||
};
|
||||
// 打开新增用户弹窗
|
||||
const onOpenAddUser = () => {
|
||||
addUserRef.value.openDialog();
|
||||
};
|
||||
// 打开修改用户弹窗
|
||||
const onOpenEditUser = (row: TableDataRow) => {
|
||||
editUserRef.value.openDialog(row);
|
||||
};
|
||||
// 删除用户
|
||||
const onRowDel = (row: TableDataRow) => {
|
||||
ElMessageBox.confirm(`此操作将永久删除账户名称:“${row.userName}”,是否继续?`, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleSizeChange = (val: number) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val: number) => {
|
||||
state.tableData.param.pageNum = val;
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
return {
|
||||
addUserRef,
|
||||
editUserRef,
|
||||
onOpenAddUser,
|
||||
onOpenEditUser,
|
||||
onRowDel,
|
||||
onHandleSizeChange,
|
||||
onHandleCurrentChange,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user