first commit

This commit is contained in:
不做码农
2022-04-16 12:48:42 +08:00
commit abaf1671ff
273 changed files with 14907 additions and 0 deletions
+274
View File
@@ -0,0 +1,274 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="参数名称" prop="configName">
<el-input v-model="queryParams.configName" placeholder="请输入参数名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="参数键名" prop="configKey">
<el-input v-model="queryParams.configKey" placeholder="请输入参数键名" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="系统内置" prop="configType">
<el-select v-model="queryParams.configType" placeholder="系统内置" clearable>
<el-option v-for="dict in sysYesNoOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker v-model="dateRange" type="daterange" range-separator="-"
start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" size="small" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" size="small" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="plus" size="small" @click="handleAdd" v-hasPermi="['system:config:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="edit" size="small" :disabled="single" @click="handleUpdate" v-hasPermi="['system:config:edit']">
修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="delete" size="small" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:config:remove']">删除
</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button type="danger" plain icon="refresh" size="small" @click="handleRefreshCache" v-hasPermi="['system:config:remove']">刷新缓存</el-button>
</el-col> -->
<right-toolbar :showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="参数主键" align="center" prop="configId" />
<el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
<el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
<el-table-column label="参数键值" align="center" prop="configValue" />
<el-table-column label="系统内置" align="center" prop="configType">
<template #default="scope">
<dict-tag :options="sysYesNoOptions" :value="scope.row.configType" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{scope.row.createTime}}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button size="small" type="text" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:config:edit']">修改</el-button>
<el-button size="small" type="text" icon="delete" @click="handleDelete(scope.row)" v-hasPermi="['system:config:remove']">删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="参数名称" prop="configName">
<el-input v-model="form.configName" placeholder="请输入参数名称" />
</el-form-item>
<el-form-item label="参数键名" prop="configKey">
<el-input v-model="form.configKey" placeholder="请输入参数键名" />
</el-form-item>
<el-form-item label="参数键值" prop="configValue">
<el-input v-model="form.configValue" placeholder="请输入参数键值" />
</el-form-item>
<el-form-item label="系统内置" prop="configType">
<el-radio-group v-model="form.configType">
<el-radio v-for="dict in sysYesNoOptions" :key="dict.dictValue" :label="dict.dictValue">{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import {
listConfig,
getConfig,
delConfig,
addConfig,
updateConfig,
// exportConfig,
refreshCache,
} from "@/api/system/config";
export default {
name: "config",
data() {
return {
// 遮罩层
loading: true,
// 导出遮罩层
exportLoading: false,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 参数表格数据
configList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 日期范围
dateRange: [],
// 系统是否
sysYesNoOptions: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
configName: undefined,
configKey: undefined,
configType: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
configName: [
{ required: true, message: "参数名称不能为空", trigger: "blur" },
],
configKey: [
{ required: true, message: "参数键名不能为空", trigger: "blur" },
],
configValue: [
{ required: true, message: "参数键值不能为空", trigger: "blur" },
],
},
};
},
created() {
this.getDicts("sys_yes_no").then((response) => {
this.sysYesNoOptions = response.data;
});
this.getList();
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true;
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(
(response) => {
this.configList = response.data.result;
this.total = response.data.totalNum;
this.loading = false;
}
);
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
configId: undefined,
configName: undefined,
configKey: undefined,
configValue: undefined,
configType: "Y",
remark: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加参数";
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.configId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const configId = row.configId || this.ids;
getConfig(configId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改参数";
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.configId != undefined) {
updateConfig(this.form).then((response) => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addConfig(this.form).then((response) => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.configId || this.ids;
this.$confirm('是否确认删除参数编号为"' + configIds + '"的数据项?')
.then(function () {
return delConfig(configIds);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
/** 刷新缓存按钮操作 */
handleRefreshCache() {
refreshCache().then(() => {
this.$modal.msgSuccess("刷新成功");
});
},
},
};
</script>
+292
View File
@@ -0,0 +1,292 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
<el-form-item label="部门名称" prop="deptName">
<el-input v-model="queryParams.deptName" placeholder="请输入部门名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable>
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button plain type="primary" icon="plus" @click="handleAdd" v-hasPermi="['system:dept:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="sort" @click="toggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar :showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-if="refreshTable" v-loading="loading" :data="deptList" row-key="deptId" :default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
<el-table-column prop="leader" label="负责人" width="100"></el-table-column>
<el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :options="statusOptions" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="200">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button type="text" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:update']">修改</el-button>
<el-button type="text" icon="plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']">新增</el-button>
<el-button v-if="scope.row.parentId != 0" type="text" icon="delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']">删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改部门对话框 -->
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row :gutter="20">
<el-col :lg="24" v-if="form.parentId !== 0">
<el-form-item label="上级部门" prop="parentId">
<TreeSelect v-model:value="form.parentId" :options="deptOptions" :objMap="{ value: 'deptId', label: 'deptName', children: 'children' }" placeholder="选择上级部门" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="部门名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="负责人" prop="leader">
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="部门状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="text" @click="cancel">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import {
listDept,
getDept,
delDept,
addDept,
updateDept,
listDeptExcludeChild,
} from "@/api/system/dept";
export default {
name: "dept",
// components: { Treeselect },
data() {
return {
// 遮罩层
loading: true,
// 显示搜索条件
showSearch: true,
// 表格树数据
deptList: [],
// 是否展开,默认全部折叠
isExpandAll: false,
// 重新渲染表格状态
refreshTable: true,
// 部门树选项
deptOptions: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 状态数据字典
statusOptions: [],
// 查询参数
queryParams: {
deptName: undefined,
status: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
parentId: [
{ required: true, message: "上级部门不能为空", trigger: "blur" },
],
deptName: [
{ required: true, message: "部门名称不能为空", trigger: "blur" },
],
orderNum: [
{ required: true, message: "显示排序不能为空", trigger: "blur" },
],
email: [
{
type: "email",
message: "请输入正确的邮箱地址",
trigger: ["blur", "change"],
},
],
phone: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur",
},
],
},
};
},
created() {
this.getList();
this.getDicts("sys_normal_disable").then((response) => {
this.statusOptions = response.data;
});
},
methods: {
/** 查询部门列表 */
getList() {
this.loading = true;
listDept(this.queryParams).then((response) => {
this.deptList = this.handleTree(response.data, "deptId");
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
deptId: undefined,
parentId: undefined,
deptName: undefined,
orderNum: undefined,
leader: undefined,
phone: undefined,
email: undefined,
status: "0",
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset();
if (row != undefined) {
this.form.parentId = row.deptId;
}
this.open = true;
this.title = "添加部门";
listDept().then((response) => {
this.deptOptions = this.handleTree(response.data, "deptId");
});
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
getDept(row.deptId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改部门";
});
listDeptExcludeChild(row.deptId).then((response) => {
this.deptOptions = this.handleTree(response.data, "deptId");
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.deptId != undefined) {
updateDept(this.form).then((response) => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addDept(this.form).then((response) => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm(
'是否确认删除名称为"' + row.deptName + '"的数据项?',
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(function () {
return delDept(row.deptId);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
});
},
//展开/折叠操作
toggleExpandAll() {
this.refreshTable = false;
this.isExpandAll = !this.isExpandAll;
this.$nextTick(() => {
this.refreshTable = true;
});
},
},
};
</script>
+316
View File
@@ -0,0 +1,316 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="字典名称" prop="dictName">
<el-input v-model="queryParams.dictName" placeholder="请输入字典名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input v-model="queryParams.dictType" placeholder="请输入字典类型" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="字典状态" clearable>
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item label="是否内置" prop="type">
<el-select v-model="queryParams.type" placeholder="是否内置" clearable>
<el-option v-for="dict in typeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker v-model="dateRange" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="plus" @click="handleAdd" v-hasPermi="['system:dict:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:dict:edit']">修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:dict:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['system:dict:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table :data="typeList" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典编号" align="center" prop="dictId" width="80" />
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
<template #default="scope">
<el-button type="text" @click="showDictData(scope.row)">{{ scope.row.dictType }}</el-button>
</template>
</el-table-column>
<el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" />
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :options="statusOptions" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{ scope.row.createTime }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button type="text" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']">修改</el-button>
<el-button type="text" icon="delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典名称" prop="dictName">
<el-input v-model="form.dictName" placeholder="请输入字典名称" />
</el-form-item>
<el-form-item label="字典类型" prop="dictType">
<el-input v-model="form.dictType" placeholder="请输入字典类型" />
</el-form-item>
<el-form-item label="字典状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="系统内置" prop="type">
<el-radio-group v-model="form.type">
<el-radio v-for="dict in typeOptions" :key="dict.dictValue" :label="dict.dictValue">{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dictDataVisible" width="60%" :lock-scroll="false">
<dict-data v-model:dictId="dictId"></dict-data>
</el-dialog>
</div>
</template>
<script>
import dictData from "@/views/components/dictData";
import {
listType,
getType,
delType,
addType,
updateType,
exportType,
} from "@/api/system/dict/type";
export default {
name: "dict",
components: { dictData },
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 字典表格数据
typeList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 字典弹出层
dictDataVisible: false,
// 状态数据字典
statusOptions: [],
// 是否内置
typeOptions: [],
// 日期范围
dateRange: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
dictName: undefined,
dictType: undefined,
status: undefined,
},
// 字典Id传值给子组件
dictId: 0,
// 表单参数
form: {},
// 表单校验
rules: {
dictName: [
{ required: true, message: "字典名称不能为空", trigger: "blur" },
],
dictType: [
{ required: true, message: "字典类型不能为空", trigger: "blur" },
],
},
};
},
created() {
this.getList();
this.getDicts("sys_normal_disable").then((response) => {
this.statusOptions = response.data;
});
this.getDicts("sys_yes_no").then((response) => {
this.typeOptions = response.data;
});
},
methods: {
/** 查询字典类型列表 */
getList() {
this.loading = true;
listType(this.addDateRange(this.queryParams, this.dateRange)).then(
(response) => {
this.typeList = response.data.result;
this.total = response.data.totalNum;
this.loading = false;
}
);
},
// 字典状态字典翻译
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
dictId: undefined,
dictName: undefined,
dictType: undefined,
status: "0",
type: "N",
remark: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加字典类型";
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.dictId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const dictId = row.dictId || this.ids;
getType(dictId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改字典类型";
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.dictId != undefined) {
updateType(this.form).then((response) => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addType(this.form).then((response) => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const dictIds = row.dictId || this.ids;
this.$confirm(
'是否确认删除字典编号为"' + dictIds + '"的数据项?',
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(function () {
return delType(dictIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有类型数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return exportType(queryParams);
})
.then((response) => {
this.download(response.data.path);
});
},
showDictData(row) {
this.dictId = row.dictId;
this.dictDataVisible = true;
},
},
};
</script>
+436
View File
@@ -0,0 +1,436 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="queryParams.menuName" placeholder="请输入菜单名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable>
<el-option v-for="dict in sys_normal_disable" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:menu:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="toggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-if="refreshTable" v-loading="loading" :data="menuList" row-key="menuId" :default-expand-all="isExpandAll" border
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column>
<el-table-column prop="icon" label="图标" align="center" width="100">
<template #default="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column prop="menuType" label="类型" align="center" width="80">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.menuType == 'M' && scope.row.isFrame == 1">链接</el-tag>
<el-tag v-else-if="scope.row.menuType == 'C'">菜单</el-tag>
<el-tag type="success" v-else-if="scope.row.menuType == 'M'">目录</el-tag>
<el-tag type="warning" v-else-if="scope.row.menuType == 'F'">按钮</el-tag>
</template>
</el-table-column>
<el-table-column prop="orderNum" label="排序" width="60"></el-table-column>
<el-table-column prop="perms" label="权限标识" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="visible" label="显示" width="70">
<template #default="scope">
<dict-tag :options="sys_show_hide" :value="scope.row.visible" />
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="80">
<template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-button type="text" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:menu:edit']">修改</el-button>
<el-button type="text" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:menu:add']">新增</el-button>
<el-button type="text" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:menu:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改菜单对话框 -->
<el-dialog :title="title" v-model="open" width="680px" append-to-body>
<el-form ref="menuRef" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :lg="24">
<el-form-item label="上级菜单">
<tree-select v-model:value="form.parentId" :options="menuOptions" :objMap="{ value: 'menuId', label: 'menuName', children: 'children' }"
placeholder="选择上级菜单" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="菜单类型" prop="menuType">
<el-radio-group v-model="form.menuType">
<el-radio label="M">目录</el-radio>
<el-radio label="C">菜单</el-radio>
<el-radio label="F">按钮</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="form.menuName" placeholder="请输入菜单名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :lg="24" v-if="form.menuType != 'F'">
<el-form-item label="菜单图标" prop="icon">
<el-popover placement="bottom-start" :width="540" v-model:visible="showChooseIcon" trigger="click" @show="showSelectIcon">
<template #reference>
<el-input v-model="form.icon" placeholder="点击选择图标" @click="showSelectIcon" readonly>
<template #prefix>
<svg-icon v-if="form.icon" :icon-class="form.icon" class="el-input__icon" style="height: 32px;width: 16px;" />
<el-icon v-else style="height: 32px;width: 16px;">
<search />
</el-icon>
</template>
</el-input>
</template>
<icon-select ref="iconSelectRef" @selected="selected" />
</el-popover>
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
<i class="question"></i>
</el-tooltip>是否外链
</span>
</template>
<el-radio-group v-model="form.isFrame">
<el-radio label="1">是</el-radio>
<el-radio label="0">否</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType != 'F'">
<el-form-item prop="path">
<template #label>
<span>
<el-tooltip content="访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
路由地址
</span>
</template>
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType == 'C'">
<el-form-item prop="component">
<template #label>
<span>
<el-tooltip content="访问的组件路径,如:`system/user/index`,默认在`views`目录下" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
组件路径
</span>
</template>
<el-input v-model="form.component" placeholder="请输入组件路径" />
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType != 'M'">
<el-form-item>
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
<template #label>
<span>
<el-tooltip content="控制器中定义的权限字符,如:[ActionPermissionFilter(Permission = 'system:user:delete')])" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
权限字符
</span>
</template>
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType == 'C'">
<el-form-item>
<el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
<template #label>
<span>
<el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top">
<!-- <el-icon :size="15"><questionFilled/></el-icon> -->
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
路由参数
</span>
</template>
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType == 'C'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
是否缓存
</span>
</template>
<el-radio-group v-model="form.isCache">
<el-radio label="0">缓存</el-radio>
<el-radio label="1">不缓存</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
显示状态
</span>
</template>
<el-radio-group v-model="form.visible">
<el-radio v-for="dict in sys_show_hide" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
菜单状态
</span>
</template>
<el-radio-group v-model="form.status">
<el-radio v-for="dict in sys_normal_disable" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="menu">
import {
addMenu,
delMenu,
getMenu,
listMenu,
updateMenu,
} from '@/api/system/menu'
import SvgIcon from '@/components/SvgIcon'
import IconSelect from '@/components/IconSelect'
const { proxy } = getCurrentInstance()
var dictParams = [
{ dictType: 'sys_show_hide', columnName: 'sys_show_hide' },
{ dictType: 'sys_normal_disable', columnName: 'sys_normal_disable' },
]
const sys_show_hide = ref([])
const sys_normal_disable = ref([])
proxy.getDicts(dictParams).then((response) => {
response.data.forEach((element) => {
proxy[element.columnName] = element.list
})
})
const menuList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const title = ref('')
const menuOptions = ref([])
const isExpandAll = ref(false)
const refreshTable = ref(true)
const showChooseIcon = ref(false)
const iconSelectRef = ref(null)
const menuRef = ref(null)
const data = reactive({
form: {},
queryParams: {
menuName: undefined,
visible: undefined,
},
rules: {
menuName: [
{ required: true, message: '菜单名称不能为空', trigger: 'blur' },
],
orderNum: [
{ required: true, message: '菜单顺序不能为空', trigger: 'blur' },
],
path: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],
},
})
const { queryParams, form, rules } = toRefs(data)
/** 查询菜单列表 */
function getList() {
loading.value = true
listMenu(queryParams.value).then((response) => {
menuList.value = response.data // proxy.handleTree(response.data, "menuId");
loading.value = false
})
}
/** 查询菜单下拉树结构 */
async function getTreeselect() {
menuOptions.value = []
await listMenu().then((response) => {
const menu = { menuId: 0, menuName: '主类目', children: [] }
//menu.children = proxy.handleTree(response.data, "menuId");
menu.children = response.data
menuOptions.value.push(menu)
})
}
/** 取消按钮 */
function cancel() {
open.value = false
reset()
}
/** 表单重置 */
function reset() {
form.value = {
menuId: undefined,
parentId: 0,
menuName: undefined,
icon: undefined,
menuType: 'M',
orderNum: 999,
isFrame: '0',
isCache: '0',
visible: '0',
status: '0',
}
proxy.resetForm('menuRef')
}
/** 展示下拉图标 */
function showSelectIcon() {
iconSelectRef.value.reset()
showChooseIcon.value = true
}
/** 选择图标 */
function selected(name) {
form.value.icon = name
showChooseIcon.value = false
}
/** 搜索按钮操作 */
function handleQuery() {
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
/** 新增按钮操作 */
async function handleAdd(row) {
reset()
await getTreeselect()
if (row != null && row.menuId) {
form.value.parentId = row.menuId
} else {
form.value.parentId = 0
}
open.value = true
title.value = '添加菜单'
}
/** 展开/折叠操作 */
function toggleExpandAll() {
refreshTable.value = false
isExpandAll.value = !isExpandAll.value
nextTick(() => {
refreshTable.value = true
})
}
/** 修改按钮操作 */
async function handleUpdate(row) {
reset()
await getTreeselect()
getMenu(row.menuId).then((response) => {
form.value = response.data
open.value = true
title.value = '修改菜单'
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs['menuRef'].validate((valid) => {
if (valid) {
if (form.value.menuId != undefined) {
updateMenu(form.value).then((response) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addMenu(form.value).then((response) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
proxy.$modal
.confirm('是否确认删除名称为"' + row.menuName + '"的数据项?')
.then(function () {
return delMenu(row.menuId)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
}
getList()
</script>
+250
View File
@@ -0,0 +1,250 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="公告标题" prop="noticeTitle">
<el-input v-model="queryParams.noticeTitle" placeholder="请输入公告标题" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="操作人员" prop="createBy">
<el-input v-model="queryParams.createBy" placeholder="请输入操作人员" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="类型" prop="noticeType">
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable>
<el-option v-for="dict in typeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:notice:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:notice:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:notice:remove']">删除</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" prop="noticeId" width="100" />
<el-table-column label="公告标题" align="center" prop="noticeTitle" :show-overflow-tooltip="true" />
<el-table-column label="内容" align="center" prop="noticeContent" :show-overflow-tooltip="true" />
<el-table-column label="公告类型" align="center" prop="noticeType" width="100">
<template #default="scope">
<dict-tag :options="typeOptions" :value="scope.row.noticeType" />
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" width="100">
<template #default="scope">
<dict-tag :options="statusOptions" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="创建者" align="center" prop="createBy" width="100" />
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button type="text" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:notice:edit']">修改</el-button>
<el-button type="text" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:notice:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改公告对话框 -->
<el-dialog :title="title" v-model="open" width="780px" append-to-body>
<el-form ref="noticeRef" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="公告标题" prop="noticeTitle">
<el-input v-model="form.noticeTitle" placeholder="请输入公告标题" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="公告类型" prop="noticeType">
<el-select v-model="form.noticeType" placeholder="请选择公告类型">
<el-option v-for="dict in typeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="内容">
<editor v-model="form.noticeContent" :min-height="196" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="notice">
// 富文本组件
import Editor from "@/components/Editor";
import {
listNotice,
getNotice,
delNotice,
addNotice,
updateNotice,
} from '@/api/system/notice'
const { proxy } = getCurrentInstance()
const noticeList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref('')
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
noticeTitle: undefined,
createBy: undefined,
status: undefined,
},
rules: {
noticeTitle: [
{ required: true, message: '公告标题不能为空', trigger: 'blur' },
],
noticeType: [
{ required: true, message: '公告类型不能为空', trigger: 'change' },
],
},
})
const statusOptions = ref([])
const typeOptions = ref([])
proxy.getDicts('sys_notice_status').then((response) => {
statusOptions.value = response.data
})
proxy.getDicts('sys_notice_type').then((response) => {
typeOptions.value = response.data
})
const { queryParams, form, rules } = toRefs(data)
/** 查询公告列表 */
function getList() {
loading.value = true
listNotice(queryParams.value).then((response) => {
noticeList.value = response.data.result
total.value = response.data.totalNum
loading.value = false
})
}
/** 取消按钮 */
function cancel() {
open.value = false
reset()
}
/** 表单重置 */
function reset() {
form.value = {
noticeId: undefined,
noticeTitle: undefined,
noticeType: undefined,
noticeContent: undefined,
status: '0',
}
proxy.resetForm('noticeRef')
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
/** 多选框选中数据 */
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.noticeId)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = '添加公告'
}
/**修改按钮操作 */
function handleUpdate(row) {
reset()
const noticeId = row.noticeId || ids.value
getNotice(noticeId).then((response) => {
form.value = response.data
open.value = true
title.value = '修改公告'
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs['noticeRef'].validate((valid) => {
console.log(valid)
if (valid) {
if (form.value.noticeId != undefined) {
updateNotice(form.value).then((response) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addNotice(form.value).then((response) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const noticeIds = row.noticeId || ids.value
proxy.$modal
.confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?')
.then(function () {
return delNotice(noticeIds)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
}
getList()
</script>
+279
View File
@@ -0,0 +1,279 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="岗位编码" prop="postCode">
<el-input v-model="queryParams.postCode" placeholder="请输入岗位编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="岗位名称" prop="postName">
<el-input v-model="queryParams.postName" placeholder="请输入岗位名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="plus" @click="handleAdd" v-hasPermi="['system:post:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:post:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:post:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['system:post:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="岗位编号" align="center" prop="postId" />
<el-table-column label="岗位编码" align="center" prop="postCode" />
<el-table-column label="岗位名称" align="center" prop="postName" />
<el-table-column label="岗位排序" align="center" prop="postSort" />
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :options="statusOptions" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button type="text" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:post:edit']">修改</el-button>
<el-button type="text" icon="delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改岗位对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="岗位名称" prop="postName">
<el-input v-model="form.postName" placeholder="请输入岗位名称" />
</el-form-item>
<el-form-item label="岗位编码" prop="postCode">
<el-input v-model="form.postCode" placeholder="请输入编码名称" />
</el-form-item>
<el-form-item label="岗位顺序" prop="postSort">
<el-input-number v-model="form.postSort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="岗位状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import {
listPost,
getPost,
delPost,
addPost,
updatePost,
exportPost,
} from "@/api/system/post";
export default {
name: "post",
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 岗位表格数据
postList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 状态数据字典
statusOptions: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
postCode: undefined,
postName: undefined,
status: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
postName: [
{ required: true, message: "岗位名称不能为空", trigger: "blur" },
],
postCode: [
{ required: true, message: "岗位编码不能为空", trigger: "blur" },
],
postSort: [
{ required: true, message: "岗位顺序不能为空", trigger: "blur" },
],
},
};
},
created() {
this.getList();
this.getDicts("sys_normal_disable").then((response) => {
this.statusOptions = response.data;
});
},
methods: {
/** 查询岗位列表 */
getList() {
this.loading = true;
listPost(this.queryParams).then((response) => {
this.postList = response.data.result;
this.total = response.data.totalNum;
this.loading = false;
});
},
// 岗位状态字典翻译
// statusFormat(row, column) {
// return this.selectDictLabel(this.statusOptions, row.status);
// },
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
postId: undefined,
postCode: undefined,
postName: undefined,
postSort: 0,
status: "0",
remark: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.postId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加岗位";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const postId = row.postId || this.ids;
getPost(postId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改岗位";
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.postId != undefined) {
updatePost(this.form).then((response) => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addPost(this.form).then((response) => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const postIds = row.postId || this.ids;
this.$confirm(
'是否确认删除岗位编号为"' + postIds + '"的数据项?',
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(function () {
return delPost(postIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有岗位数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return exportPost(queryParams);
})
.then((response) => {
this.download(response.data.path);
});
},
},
};
</script>
+619
View File
@@ -0,0 +1,619 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
<el-form-item label="角色名称" prop="roleName">
<el-input v-model="queryParams.roleName" placeholder="请输入角色名称" clearable size="small" @keyup.enter="handleQuery" />
</el-form-item>
<!-- <el-form-item label="权限字符" prop="roleKey">
<el-input v-model="queryParams.roleKey" placeholder="请输入权限字符" clearable size="small" style="width: 240px" @keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="角色状态" clearable size="small">
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" size="small" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" size="small" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="plus" size="small" @click="handleAdd" v-hasPermi="['system:role:add']">新增</el-button>
</el-col>
<right-toolbar :showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="roleList" highlight-current-row @selection-change="handleSelectionChange">
<el-table-column label="编号" prop="roleId" width="80" />
<el-table-column label="名称" prop="roleName" />
<el-table-column label="显示顺序" prop="roleSort"></el-table-column>
<el-table-column label="权限字符" prop="roleKey" />
<el-table-column label="权限范围" prop="dataScope" :formatter="dataScopeFormat"></el-table-column>
<el-table-column label="状态" align="center" width="90">
<template #default="scope">
<el-switch v-model="scope.row.status" :disabled="scope.row.roleKey == 'admin'" active-value="0" inactive-value="1"
@change="handleStatusChange(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="用户个数" align="center" prop="userNum" width="90" />
<el-table-column label="创建时间" align="center" prop="createTime" width="150" />
<el-table-column label="备注" align="center" prop="remark" width="150" :show-overflow-tooltip="true" />
<el-table-column label="操作" align="center" width="200">
<template #default="scope">
<div v-if="scope.row.roleKey != 'admin'">
<el-button size="small" type="text" icon="edit" @click.stop="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']">修改
</el-button>
<el-button size="small" type="text" icon="delete" @click.stop="handleDelete(scope.row)" v-hasPermi="['system:role:remove']">删除
</el-button>
<el-dropdown size="small" @command="(command) => handleCommand(command, scope.row)"
v-hasPermi="['system:role:edit', 'system:role:authorize', 'system:roleusers:list']">
<span class="el-dropdown-link">
更多
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="handleDataScope" icon="circle-check">菜单权限</el-dropdown-item>
<el-dropdown-item command="handleAuthUser" icon="user">分配用户</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 角色菜单弹框 -->
<el-dialog title="角色权限分配" v-model="showRoleScope" width="500px">
<el-form :model="form" label-width="80px">
<el-form-item label="菜单搜索">
<el-input placeholder="请输入关键字进行过滤" v-model="searchText"></el-input>
</el-form-item>
<el-form-item label="权限字符">
{{form.roleKey}}
</el-form-item>
<el-form-item label="数据权限">
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
<el-tree class="tree-border" :data="menuOptions" show-checkbox ref="menu" node-key="id" :check-strictly="!form.menuCheckStrictly"
empty-text="加载中,请稍后" :filter-node-method="menuFilterNode" :props="defaultProps"></el-tree>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitDataScope" v-hasPermi="['system:role:authorize']">保存</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 添加或修改角色配置对话框 -->
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :lg="12">
<el-form-item label="角色名称" prop="roleName">
<el-input v-model="form.roleName" placeholder="请输入角色名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="权限字符" prop="roleKey">
<el-input v-model="form.roleKey" placeholder="请输入权限字符" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="角色顺序" prop="roleSort">
<el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="数据范围">
<el-select v-model="form.dataScope" @change="dataScopeSelectChange">
<el-option v-for="item in dataScopeOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="数据权限" v-show="form.dataScope == 2">
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
<el-tree class="tree-border" :data="deptOptions" show-checkbox default-expand-all ref="dept" node-key="id"
:check-strictly="!form.deptCheckStrictly" empty-text="加载中,请稍候" :props="defaultProps"></el-tree>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import {
listRole,
getRole,
delRole,
addRole,
updateRole,
exportRole,
dataScope,
changeRoleStatus,
} from '@/api/system/role'
import {
treeselect as menuTreeselect,
roleMenuTreeselect,
} from '@/api/system/menu'
import {
treeselect as deptTreeselect,
roleDeptTreeselect,
} from '@/api/system/dept'
export default {
name: 'role',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 表格高度
tableHeight: window.innerHeight,
// 总条数
total: 0,
// 角色表格数据
roleList: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
menuExpand: true,
menuNodeAll: false,
deptExpand: true,
deptNodeAll: false,
// 日期范围
dateRange: [],
// 状态数据字典
statusOptions: [],
// 是否显示下拉菜单分配
showRoleScope: false,
// 数据范围选项
dataScopeOptions: [
{
dictValue: '1',
dictLabel: '全部',
},
{
dictValue: '2',
dictLabel: '自定义',
},
{
dictValue: '3',
dictLabel: '本部门',
},
{
dictValue: "4",
dictLabel: "本部门及以下数据权限",
},
{
dictValue: '5',
dictLabel: '仅本人',
},
],
// 菜单列表
menuOptions: [],
// 部门列表
deptOptions: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
roleName: undefined,
roleKey: undefined,
status: undefined,
},
searchText: '',
// 表单参数
form: {},
defaultProps: {
children: 'children',
label: 'label',
},
// 表单校验
rules: {
roleName: [
{ required: true, message: '角色名称不能为空', trigger: 'blur' },
],
roleKey: [
{ required: true, message: '权限字符不能为空', trigger: 'blur' },
],
roleSort: [
{ required: true, message: '角色顺序不能为空', trigger: 'blur' },
],
},
}
},
watch: {
searchText(val) {
this.$refs.menu.filter(val)
},
},
created() {
this.getList()
this.getDicts('sys_normal_disable').then((response) => {
this.statusOptions = response.data
})
},
methods: {
/** 查询角色列表 */
getList() {
this.loading = true
listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
(response) => {
this.roleList = response.data.result
this.total = response.data.totalNum
this.loading = false
}
)
},
/** 查询菜单树结构 */
getMenuTreeselect() {
menuTreeselect().then((response) => {
this.menuOptions = response.data
})
},
/** 查询部门树结构 */
getDeptTreeselect() {
deptTreeselect().then((response) => {
this.deptOptions = response.data
})
},
// 所有菜单节点数据
getMenuAllCheckedKeys() {
// 目前被选中的菜单节点
const checkedKeys = this.$refs.menu.getCheckedKeys()
// 半选中的菜单节点
const halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys()
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
return checkedKeys
},
// 所有部门节点数据
getDeptAllCheckedKeys() {
// 目前被选中的部门节点
const checkedKeys = this.$refs.dept.getCheckedKeys()
// 半选中的部门节点
const halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys()
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
return checkedKeys
},
/** 根据角色ID查询菜单树结构 */
getRoleMenuTreeselect(roleId) {
return roleMenuTreeselect(roleId).then((response) => {
this.menuOptions = response.data.menus
return response
})
},
/** 根据角色ID查询部门树结构 */
getRoleDeptTreeselect(roleId) {
return roleDeptTreeselect(roleId).then((response) => {
console.log('角色', response)
this.deptOptions = response.data.depts
return response
})
},
// 角色状态修改
handleStatusChange(row) {
const text = row.status === '0' ? '启用' : '停用'
this.$confirm(
'确认要"' + text + '""' + row.roleName + '"角色吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(function () {
return changeRoleStatus(row.roleId, row.status)
})
.then(() => {
this.$modal.msgSuccess(text + '成功')
})
.catch(function () {
row.status = row.status === '0' ? '1' : '0'
})
},
// 取消按钮
cancel() {
this.open = false
this.showRoleScope = false
this.reset()
},
// 表单重置
reset() {
if (this.$refs.menu != undefined) {
this.$refs.menu.setCheckedKeys([])
}
;(this.menuExpand = false),
(this.menuNodeAll = false),
(this.deptExpand = true),
(this.deptNodeAll = false),
(this.form = {
roleId: undefined,
roleName: undefined,
roleKey: undefined,
roleSort: 99,
status: '0',
menuIds: [],
deptIds: [],
dataScope: '1',
menuCheckStrictly: true,
deptCheckStrictly: true,
remark: undefined,
})
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.roleId)
this.single = selection.length != 1
this.multiple = !selection.length
},
// 更多操作触发
handleCommand(command, row) {
switch (command) {
case 'handleDataScope':
this.handleDataScope(row)
break
case 'handleAuthUser':
this.handleAuthUser(row)
break
default:
break
}
},
// 树权限(展开/折叠)
handleCheckedTreeExpand(value, type) {
if (type == 'menu') {
const treeList = this.menuOptions
for (let i = 0; i < treeList.length; i++) {
this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value
}
} else if (type == 'dept') {
const treeList = this.deptOptions
for (let i = 0; i < treeList.length; i++) {
this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value
}
}
},
// 树权限(全选/全不选)
handleCheckedTreeNodeAll(value, type) {
if (type == 'menu') {
this.$refs.menu.setCheckedNodes(value ? this.menuOptions : [])
} else if (type == 'dept') {
this.$refs.dept.setCheckedNodes(value ? this.deptOptions : [])
}
},
// 树权限(父子联动)
handleCheckedTreeConnect(value, type) {
if (type == 'menu') {
this.form.menuCheckStrictly = !!value
} else if (type == 'dept') {
this.form.deptCheckStrictly = !!value
}
},
// 菜单筛选
menuFilterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.getDeptTreeselect()
this.open = true
this.title = '添加角色'
this.showRoleScope = false
},
/** 修改按钮操作 ok */
handleUpdate(row) {
this.reset()
this.showRoleScope = false
const roleId = row.roleId || this.ids
const roleDeptTreeselect = this.getRoleDeptTreeselect(row.roleId)
getRole(roleId).then((response) => {
this.form = response.data
this.open = true
this.title = '修改角色'
this.$nextTick(() => {
roleDeptTreeselect.then((res) => {
this.$refs.dept.setCheckedKeys(res.data.checkedKeys)
})
})
})
},
/** 选择角色权限范围触发 */
dataScopeSelectChange(value) {
if (value !== '2') {
this.$refs.dept.setCheckedKeys([])
}
},
// 数据权限
dataScopeFormat(row, column) {
return this.selectDictLabel(this.dataScopeOptions, row.dataScope)
},
/** 分配角色权限按钮操作 */
// 新增 和上面代码基本相同
handleDataScope(row) {
if (row.roleId == 1) {
this.showRoleScope = false
return
}
this.reset()
this.showRoleScope = true
const roleId = row.roleId || this.ids
const roleMenu = this.getRoleMenuTreeselect(roleId)
roleMenu.then((res) => {
const checkedKeys = res.data.checkedKeys
checkedKeys.forEach((v) => {
this.$nextTick(() => {
this.$refs.menu.setChecked(v, true, false)
})
})
})
this.form = {
roleId: row.roleId,
roleName: row.roleName,
roleKey: row.roleKey,
menuCheckStrictly: row.menuCheckStrictly,
}
},
/** 分配用户操作 */
handleAuthUser: function (row) {
const roleId = row.roleId
this.$router.push({ path: '/system/roleusers', query: { roleId } })
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.roleId != undefined && this.form.roleId > 0) {
this.form.type = 'edit'
this.form.deptIds = this.getDeptAllCheckedKeys()
updateRole(this.form).then((response) => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
} else {
this.form.type = 'add'
this.form.deptIds = this.getDeptAllCheckedKeys()
addRole(this.form).then((response) => {
this.open = false
if (response.code == 200) {
this.$modal.msgSuccess('新增成功')
this.getList()
} else {
this.msgInfo(response.msg)
}
})
}
}
})
},
/** 提交按钮(菜单数据权限) */
submitDataScope: function () {
if (this.form.roleId != undefined) {
this.form.menuIds = this.getMenuAllCheckedKeys()
dataScope(this.form).then((response) => {
this.$modal.msgSuccess('修改成功')
this.getList()
this.cancel()
})
} else {
this.$modal.msgError('请选择角色')
}
},
/** 删除按钮操作 */
handleDelete(row) {
const roleIds = row.roleId || this.ids
this.$confirm(
'是否确认删除角色编号为"' + roleIds + '"的数据项?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(function () {
return delRole(roleIds)
})
.then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams
this.$confirm('是否确认导出所有角色数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(function () {
return exportRole(queryParams)
})
.then((response) => {
this.download(response.data.path)
})
},
},
}
</script>
<style scoped>
/* tree border */
.tree-border {
margin-top: 5px;
border: 1px solid #e5e6e7;
background: #ffffff none;
border-radius: 4px;
width: 100%;
}
.el-dropdown-link {
cursor: pointer;
color: var(--el-color-primary);
display: flex;
align-items: center;
}
.el-dropdown {
vertical-align: middle;
}
</style>
+295
View File
@@ -0,0 +1,295 @@
<template>
<div class="app-container">
<!-- <el-col :span="4" :xs="24">
<el-table ref="roleTable" v-loading="loadingRole" highlight-current-row :data="dataRoleTable" border :height="tableHeight-135"
@row-click="handleRoleTableSelection">
<el-table-column prop="roleName" label="请选择角色名称" />
</el-table>
</el-col> -->
<el-form :inline="true" @submit.prevent>
<el-form-item label="角色名">
<el-input v-model="roleUserQueryParams.roleName" disabled />
</el-form-item>
<el-form-item label="角色字符串">
<el-input v-model="roleUserQueryParams.roleKey" disabled />
</el-form-item>
<el-form-item label="用户名">
<el-input v-model="roleUserQueryParams.userName" placeholder="请输入用户名称" clearable prefix-icon="el-icon-search" @keyup.enter="searchRoleUser" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="searchRoleUser">搜索</el-button>
<!-- <el-button icon="refresh" @click="resetQuery">重置</el-button> -->
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="plus" @click="handleGetUserTable" v-hasPermi="['system:roleusers:add']">添加用户
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="circle-close" @click="cancelAuthUserAll" v-hasPermi="['system:roleusers:remove']">
批量取消授权</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="close" @click="handleClose">关闭</el-button>
</el-col>
</el-row>
<el-table ref="roleUserTable" v-loading="loadingRoleUser" :data="dataRoleUserTable" row-key="userId" stripe border>
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="userId" align="center" label="用户Id" width="150" />
<el-table-column prop="userName" align="center" label="用户名" width="150" />
<el-table-column prop="nickName" align="center" label="用户昵称" width="150" />
<el-table-column prop="email" align="center" label="邮箱" />
<el-table-column prop="status" align="center" label="账号状态" width="80">
<template #default="scope">
<dict-tag :options="statusOptions" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column prop="remark" :show-overflow-tooltip="true" align="center" label="备注" />
<el-table-column align="center" label="操作">
<template #default="scope">
<el-button type="text" icon="el-icon-circle-close" @click="handleCancelPerm(scope.row)" v-if="scope.row.userId != 1"
v-hasPermi="['system:roleusers:del']">取消授权</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-model:total="dataRoleUserCount" v-model:page="roleUserQueryParams.pageNum" v-model:limit="roleUserQueryParams.pageSize" @pagination="getRoleUser" />
<!-- 添加或修改菜单对话框 -->
<el-dialog title="添加用户" v-model="open" append-to-body @close="cancel">
<el-form :inline="true" @submit.prevent>
<el-form-item>
<el-input v-model="userQueryParams.userName" placeholder="请输入用户名称" clearable prefix-icon="search"
@keyup.enter="handleSearchRoleUser" />
</el-form-item>
</el-form>
<el-row>
<el-col>
<el-table ref="userTable" v-loading="loadingUser" :data="dataUserTable" @selection-change="handleSelectionChange" row-key="userId" stripe
border :height="tableHeight*0.5">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="userId" align="center" label="用户编号" width="150" />
<el-table-column prop="userName" align="center" label="用户名称" width="150" />
<el-table-column prop="nickName" align="center" label="用户昵称" width="150" />
<el-table-column prop="status" align="center" label="用户状态">
<template #default="scope">
<dict-tag :options="statusOptions" :value="scope.row.status" />
</template>
</el-table-column>
</el-table>
<pagination :total="dataUserCount" v-model:page="userQueryParams.pageNum" v-model:limit="userQueryParams.pageSize" @pagination="handleGetUserTable" />
</el-col>
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="handleSubmit">确 定</el-button>
<el-button @click="open = false">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
// import { listRole } from "@/api/system/role";
import { getRole } from "@/api/system/role";
import {
getRoleUsers,
createRoleUsers,
deleteRoleUsers,
getExcludeUsers,
} from "@/api/system/userRoles";
export default {
name: "roleusers",
data() {
return {
// 遮罩层
loadingRole: false,
loadingUser: false,
loadingRoleUser: false,
// 表格高度
tableHeight: window.innerHeight,
// 角色列表
dataRoleTable: [],
// 已添加用户列表
dataRoleUserTable: [],
dataRoleUserCount: 0,
// 未添加用户列表
dataUserTable: [],
dataUserCount: 0,
// 勾选添加用户列表
addSelections: [],
// 勾选删除用户列表
delSelections: [],
// 过滤查询
search: "",
// 角色id
roleId: "",
// 是否显示弹出层
open: false,
// 角色用户查询参数
roleUserQueryParams: {
pageNum: 1,
pageSize: 10,
roleId: undefined,
userName: undefined,
roleName: undefined,
roleKey: undefined,
},
userQueryParams: {
pageNum: 1,
pageSize: 10,
roleId: undefined,
userName: undefined,
},
// 状态字典
statusOptions: [],
};
},
created() {
// 获取角色列表
// this.loadingRole = true;
// listRole({ pageSize: 50 }).then((response) => {
// this.dataRoleTable = response.data.result;
// // this.handleRoleTableSelection(this.dataRoleTable[0]);
// // this.$refs.roleTable.setCurrentRow(this.dataRoleTable[0]);
// this.loadingRole = false;
// });
this.getDicts("sys_normal_disable").then((response) => {
this.statusOptions = response.data;
});
var roleId = this.$route.query.roleId;
console.log(roleId);
if (roleId) {
this.roleId = roleId;
this.searchRoleUser();
getRole(roleId).then((response) => {
const { code, data } = response;
if (code == 200) {
this.roleUserQueryParams.roleName = data.roleName;
this.roleUserQueryParams.roleKey = data.roleKey;
}
});
} else {
this.msgError("请升级数据库");
}
},
methods: {
searchRoleUser() {
this.roleUserQueryParams.pageNum = 1;
this.getRoleUser();
},
// 获取角色用户
getRoleUser() {
this.loadingRoleUser = true;
this.roleUserQueryParams.roleId = this.roleId;
getRoleUsers(this.roleUserQueryParams).then((response) => {
this.dataRoleUserTable = response.data.result;
this.dataRoleUserCount = response.data.totalNum;
this.loadingRoleUser = false;
});
},
// 返回按钮
handleClose() {
const obj = { path: "/system/role" };
this.$tab.closeOpenPage(obj);
},
// 批量删除角色用户
cancelAuthUserAll() {
this.delSelections = [];
this.$refs.roleUserTable.selection.forEach((element) => {
this.delSelections.push(element.userId);
});
if (this.delSelections.length === 0) {
this.$modal.msgError("请选择要删除的用户");
return;
}
this.$confirm(
"是否确认删除选中的 " + this.delSelections.length + " 条数据?",
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
deleteRoleUsers({
roleId: this.roleId,
userIds: this.delSelections,
}).then((response) => {
if (response.code === 200) {
this.$message({
message: "成功删除" + response.data + "条数据",
type: "success",
});
this.getRoleUser();
}
});
})
.catch(() => {});
},
// 取消授权
handleCancelPerm(row) {
this.delSelections = [];
this.delSelections.push(row.userId);
deleteRoleUsers({
roleId: this.roleId,
userIds: this.delSelections,
}).then((response) => {
if (response.code === 200) {
this.$message({
message: "成功删除" + response.data + "条数据",
type: "success",
});
this.getRoleUser();
}
});
},
// 选中角色
// 多选框选中数据
handleSelectionChange(selection) {
this.addSelections = selection.map((item) => item.userId);
},
handleSearchRoleUser() {
this.userQueryParams.pageNum = 1;
this.handleGetUserTable();
},
// 获取未添加角色列表
handleGetUserTable() {
this.open = true;
this.loadingUser = true;
this.userQueryParams.roleId = this.roleId;
getExcludeUsers(this.userQueryParams).then((response) => {
this.dataUserTable = response.data.result;
this.dataUserCount = response.data.totalNum;
this.loadingUser = false;
});
},
// 新增用户角色
handleSubmit() {
createRoleUsers({
roleId: this.roleId,
userIds: this.addSelections,
}).then((response) => {
if (response.code === 200) {
this.$message({
message: "成功添加" + response.data + "条数据",
type: "success",
});
this.getRoleUser();
this.open = false;
}
});
},
cancel() {
this.open = false;
},
},
};
</script>
+621
View File
@@ -0,0 +1,621 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--部门数据-->
<el-col :span="4" :xs="24">
<div class="head-container">
<el-input v-model="deptName" placeholder="请输入部门名称" clearable prefix-icon="el-icon-search" style="margin-bottom: 20px" />
</div>
<div class="head-container">
<el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }" :expand-on-click-node="false"
:filter-node-method="filterNode" ref="deptTreeRef" default-expand-all @node-click="handleNodeClick" />
</div>
</el-col>
<!--用户数据-->
<el-col :lg="20" :xm="24">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户名称" prop="userName">
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px">
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker v-model="dateRange" style="width: 240px" type="daterange" range-separator="-" start-placeholder="开始日期"
end-placeholder="结束日期"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">删除</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
<el-table-column label="登录名" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" key="deptName" prop="deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
<el-table-column label="状态" align="center" key="status">
<template #default="scope">
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="160"></el-table-column>
<el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
<template #default="scope">
<el-button v-if="scope.row.userId !== 1" type="text" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">
</el-button>
<el-button v-if="scope.row.userId !== 1" type="text" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']">
</el-button>
<el-button v-if="scope.row.userId !== 1" type="text" icon="Key" @click="handleResetPwd(scope.row)"
v-hasPermi="['system:user:resetPwd']"></el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-col>
</el-row>
<!-- 添加或修改用户配置对话框 -->
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
<el-form :model="form" :rules="rules" ref="userRef" label-width="80px">
<el-row v-if="form.userId == undefined">
<el-col :lg="12">
<el-form-item label="用户名" prop="userName">
<el-input :disabled="form.userId != undefined" v-model="form.userName" placeholder="请输入用户名(用于登陆)" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="用户密码" prop="password">
<el-input :disabled="form.userId != undefined" v-model="form.password" placeholder="请输入用户密码" type="password" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户昵称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="归属部门" prop="deptId">
<tree-select v-model:value="form.deptId" :show-count="true" :options="deptOptions" placeholder="请选择归属部门"
:objMap="{ value: 'id', label: 'label', children: 'children' }" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :lg="12">
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :lg="12">
<el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择用户性别">
<el-option v-for="dict in sexOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="用户状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :lg="12">
<el-form-item label="岗位">
<el-select v-model="form.postIds" multiple placeholder="请选择">
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择" style="width:100%" @change="selectRole($event)">
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :lg="24">
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 用户导入对话框 -->
<!-- <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
<el-upload name="file" ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<div class="el-upload__tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</template>
</el-dialog> -->
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
<el-upload name="file" ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :auto-upload="false" drag>
<!-- <i class="el-icon-upload"></i> -->
<el-icon class="el-icon--upload">
<upload-filled />
</el-icon>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<!-- <div class="el-upload__tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div> -->
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="user">
import { getToken } from '@/utils/auth'
import { treeselect } from '@/api/system/dept'
import {
changeUserStatus,
listUser,
resetUserPwd,
delUser,
getUser,
updateUser,
addUser,
exportUser,
} from '@/api/system/user'
const router = useRouter()
const { proxy } = getCurrentInstance()
const statusOptions = ref([])
const sexOptions = ref([])
proxy.getDicts('sys_normal_disable').then((response) => {
statusOptions.value = response.data
})
proxy.getDicts('sys_user_sex').then((response) => {
sexOptions.value = response.data
})
// proxy.getConfigKey("sys.user.initPassword").then((response) => {
// initPassword.value = response.data;
// });
const userList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref('')
const dateRange = ref([])
const deptName = ref('')
const deptOptions = ref(undefined)
const initPassword = ref(undefined)
const postOptions = ref([])
const roleOptions = ref([])
/*** 用户导入参数 */
const upload = reactive({
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: 'Bearer ' + getToken() },
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + 'system/user/importData',
})
// 列显隐信息
const columns = ref([
{ key: 0, label: `用户编号`, visible: true },
{ key: 1, label: `用户名称`, visible: true },
{ key: 2, label: `用户昵称`, visible: true },
{ key: 3, label: `部门`, visible: true },
{ key: 4, label: `手机号码`, visible: true },
{ key: 5, label: `状态`, visible: true },
{ key: 6, label: `创建时间`, visible: true },
])
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
userName: undefined,
phonenumber: undefined,
status: undefined,
deptId: undefined,
},
rules: {
userName: [
{ required: true, message: '用户名称不能为空', trigger: 'blur' },
{
min: 2,
max: 20,
message: '用户名称长度必须介于 2 和 20 之间',
trigger: 'blur',
},
],
nickName: [
{ required: true, message: '用户昵称不能为空', trigger: 'blur' },
],
password: [
{ required: true, message: '用户密码不能为空', trigger: 'blur' },
{
min: 5,
max: 20,
message: '用户密码长度必须介于 5 和 20 之间',
trigger: 'blur',
},
],
email: [
{
type: 'email',
message: "'请输入正确的邮箱地址",
trigger: ['blur', 'change'],
},
],
phonenumber: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur',
},
],
},
})
const { queryParams, form, rules } = toRefs(data)
/** 通过条件过滤节点 */
const filterNode = (value, data) => {
if (!value) return true
return data.label.indexOf(value) !== -1
}
/** 根据名称筛选部门树 */
watch(deptName, (val) => {
proxy.$refs['deptTreeRef'].filter(val)
})
/** 查询部门下拉树结构 */
function getTreeselect() {
treeselect().then((response) => {
deptOptions.value = response.data
})
}
/** 查询用户列表 */
function getList() {
loading.value = true
listUser(proxy.addDateRange(queryParams.value, dateRange.value)).then(
(res) => {
loading.value = false
userList.value = res.data.result
total.value = res.data.totalNum
}
)
}
/** 节点单击事件 */
function handleNodeClick(data) {
queryParams.value.deptId = data.id
handleQuery()
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
dateRange.value = []
proxy.resetForm('queryRef')
handleQuery()
}
/** 删除按钮操作 */
function handleDelete(row) {
const userIds = row.userId || ids.value
proxy.$modal
.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
.then(function () {
return delUser(userIds)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
}
/** 导出按钮操作 */
function handleExport() {
proxy.$modal
.confirm('是否确认导出所有用户数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
exportUser(queryParams.value).then((response) => {
const { code, data } = response
if (code == 200) {
proxy.$modal.msgSuccess('导出成功')
proxy.download(data.path)
} else {
proxy.$modal.msgError('导出失败')
}
})
})
}
/** 用户状态修改 */
function handleStatusChange(row) {
let text = row.status === '0' ? '启用' : '停用'
proxy.$modal
.confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
.then(function () {
return changeUserStatus(row.userId, row.status)
})
.then(() => {
proxy.$modal.msgSuccess(text + '成功')
})
.catch(function () {
row.status = row.status === '0' ? '1' : '0'
})
}
/** 更多操作 */
function handleCommand(command, row) {
switch (command) {
case 'handleResetPwd':
handleResetPwd(row)
break
case 'handleAuthRole':
handleAuthRole(row)
break
default:
break
}
}
/** 跳转角色分配 */
function handleAuthRole(row) {
const userId = row.userId
router.push('/system/user-auth/role/' + userId)
}
/** 重置密码按钮操作 */
function handleResetPwd(row) {
proxy
.$prompt('请输入"' + row.userName + '"的新密码', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
inputPattern: /^.{5,20}$/,
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
})
.then(({ value }) => {
resetUserPwd(row.userId, value).then((response) => {
proxy.$modal.msgSuccess('修改成功,新密码是:' + value)
})
})
.catch(() => {})
}
/** 选择条数 */
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.userId)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 导入按钮操作 */
function handleImport() {
upload.title = '用户导入'
upload.open = true
}
/** 下载模板操作 */
function importTemplate() {
// proxy.download(
// "system/user/importTemplate",
// {},
// `user_template_${new Date().getTime()}.xlsx`
// );
proxy.download('/system/user/importTemplate', '用户数据导入模板')
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true
}
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
upload.open = false
upload.isUploading = false
proxy.$refs['uploadRef'].clearFiles()
proxy.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true }
)
getList()
}
/** 提交上传文件 */
function submitFileForm() {
proxy.$refs['uploadRef'].submit()
}
/** 初始化部门数据 */
function initTreeData() {
// 判断部门的数据是否存在,存在不获取,不存在则获取
if (deptOptions.value === undefined) {
treeselect().then((response) => {
deptOptions.value = response.data
})
}
}
/** 重置操作表单 */
function reset() {
form.value = {
userId: undefined,
deptId: undefined,
userName: undefined,
nickName: undefined,
password: undefined,
phonenumber: undefined,
email: undefined,
sex: undefined,
status: '0',
remark: undefined,
postIds: [],
roleIds: [],
}
proxy.resetForm('userRef')
}
/** 取消按钮 */
function cancel() {
open.value = false
reset()
}
/** 新增按钮操作 */
function handleAdd() {
reset()
initTreeData()
getUser().then((response) => {
postOptions.value = response.data.posts
roleOptions.value = response.data.roles
open.value = true
title.value = '添加用户'
// form.password.value = initPassword.value;
})
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
initTreeData()
const userId = row.userId || ids.value
getUser(userId).then((response) => {
var data = response.data
form.value = {
userId: data.user.userId,
deptId: data.user.deptId,
userName: data.user.userName,
nickName: data.user.nickName,
password: '',
phonenumber: data.user.phonenumber,
email: data.user.email,
sex: data.user.sex,
status: data.user.status,
remark: data.user.remark,
postIds: data.postIds,
roleIds: data.roleIds,
}
roleOptions.value = response.data.roles
postOptions.value = response.data.posts
open.value = true
title.value = '修改用户'
form.password = ''
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs['userRef'].validate((valid) => {
if (valid) {
if (form.value.userId != undefined) {
updateUser(form.value).then((response) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addUser(form.value).then((response) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
}
}
})
}
/**
* 解决编辑时角色选中不了问题
*/
function selectRole(e) {
console.log(e, JSON.stringify(this.form))
proxy.$forceUpdate()
}
getTreeselect()
getList()
</script>
+118
View File
@@ -0,0 +1,118 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<el-card class="box-card">
<template v-slot:header>
<div class="clearfix">
<span>个人信息</span>
</div>
</template>
<div>
<div class="text-center">
<userAvatar :user="state.user" />
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
<svg-icon icon-class="user" />用户名称
<div class="pull-right">{{ state.user.userName }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ state.user.phonenumber }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ state.user.email }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right">{{ state.user.deptName }} / {{ state.postGroup }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色
<div class="pull-right">
<span v-for="item in state.roles" :key="item">{{item}}</span>
</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ state.user.createTime }}</div>
</li>
</ul>
</div>
</el-card>
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<template v-slot:header>
<div class="clearfix">
<span>基本资料</span>
</div>
</template>
<el-tabs v-model="activeTab">
<el-tab-pane label="基本资料" name="userinfo">
<userInfo :user="state.user" />
</el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd">
<resetPwd :user="state.user" />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup name="Profile">
import userAvatar from "./userAvatar";
import userInfo from "./userInfo";
import resetPwd from "./resetPwd";
import { getUserProfile } from "@/api/system/user";
const activeTab = ref("userinfo");
const state = reactive({
user: {},
roles: [],
roleGroup: {},
postGroup: {},
});
function getUser() {
getUserProfile().then((response) => {
state.user = response.data.user;
state.roles = response.data.roles;
state.roleGroup = response.data.roleGroup;
state.postGroup = response.data.postGroup;
});
}
getUser();
</script>
<style scoped>
.list-group-striped > .list-group-item {
border-left: 0;
border-right: 0;
border-radius: 0;
padding-left: 0;
padding-right: 0;
}
.list-group {
padding-left: 0px;
list-style: none;
}
.list-group-item {
border-bottom: 1px solid #e7eaec;
border-top: 1px solid #e7eaec;
margin-bottom: -1px;
padding: 11px 0px;
font-size: 13px;
}
.pull-right {
float: right !important;
}
</style>
@@ -0,0 +1,63 @@
<template>
<el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="user.confirmPassword" placeholder="请确认密码" type="password" show-password />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">保存</el-button>
<el-button type="danger" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { updateUserPwd } from "@/api/system/user";
const { proxy } = getCurrentInstance();
const user = reactive({
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined,
});
const equalToPassword = (rule, value, callback) => {
if (user.newPassword !== value) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
};
const rules = ref({
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "blur" }],
newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
],
confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" },
{ required: true, validator: equalToPassword, trigger: "blur" },
],
});
/** 提交按钮 */
function submit() {
proxy.$refs.pwdRef.validate((valid) => {
if (valid) {
updateUserPwd(user.oldPassword, user.newPassword).then((response) => {
proxy.$modal.msgSuccess("修改成功");
});
}
});
}
/** 关闭按钮 */
function close() {
proxy.$tab.closePage();
}
</script>
@@ -0,0 +1,186 @@
<template>
<div class="user-info-head" @click="editCropper()"><img :src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
<el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
<el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<vue-cropper ref="cropper" :img="options.img" :info="true" :autoCrop="options.autoCrop" :autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight" :fixedBox="options.fixedBox" @realTime="realTime" v-if="visible" />
</el-col>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<div class="avatar-upload-preview">
<img :src="options.previews.url" :style="options.previews.img" />
</div>
</el-col>
</el-row>
<br />
<el-row>
<el-col :lg="2" :md="2">
<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
<el-button>
选择
<el-icon class="el-icon--right">
<Upload />
</el-icon>
</el-button>
</el-upload>
</el-col>
<el-col :lg="{span: 1, offset: 2}" :md="2">
<el-button icon="Plus" @click="changeScale(1)"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :md="2">
<el-button icon="Minus" @click="changeScale(-1)"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :md="2">
<el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :md="2">
<el-button icon="RefreshRight" @click="rotateRight()"></el-button>
</el-col>
<el-col :lg="{span: 2, offset: 6}" :md="2">
<el-button type="primary" @click="uploadImg()">提 交</el-button>
</el-col>
</el-row>
</el-dialog>
</template>
<script>
import "vue-cropper/dist/index.css";
import { VueCropper } from "vue-cropper";
import { uploadAvatar } from "@/api/system/user";
import { reactive, ref, getCurrentInstance } from "vue";
export default {
components: {
VueCropper,
uploadAvatar,
},
props: {
user: {
type: Object,
},
},
setup() {
const store = useStore();
const { proxy } = getCurrentInstance();
const open = ref(false);
const visible = ref(false);
const title = ref("修改头像");
//图片裁剪数据
const options = reactive({
img: store.getters.avatar, // 裁剪图片的地址
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 200, // 默认生成截图框宽度
autoCropHeight: 200, // 默认生成截图框高度
fixedBox: true, // 固定截图框大小 不允许改变
previews: {}, //预览数据
});
/** 编辑头像 */
function editCropper() {
open.value = true;
}
/** 打开弹出层结束时的回调 */
function modalOpened() {
visible.value = true;
}
/** 覆盖默认上传行为 */
function requestUpload() {}
/** 向左旋转 */
function rotateLeft() {
proxy.$refs.cropper.rotateLeft();
}
/** 向右旋转 */
function rotateRight() {
proxy.$refs.cropper.rotateRight();
}
/** 图片缩放 */
function changeScale(num) {
num = num || 1;
proxy.$refs.cropper.changeScale(num);
}
/** 上传预处理 */
function beforeUpload(file) {
if (file.type.indexOf("image/") == -1) {
proxy.$modal.msgError(
"文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。"
);
} else {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
options.img = reader.result;
};
}
}
/** 上传图片 */
function uploadImg() {
proxy.$refs.cropper.getCropBlob((data) => {
let formData = new FormData();
formData.append("picture", data);
uploadAvatar(formData).then((response) => {
open.value = false;
options.img = response.data.imgUrl;;
store.commit("SET_AVATAR", options.img);
proxy.$modal.msgSuccess("修改成功");
visible.value = false;
});
});
}
/** 实时预览 */
function realTime(data) {
options.previews = data;
}
/** 关闭窗口 */
function closeDialog() {
options.img = store.getters.avatar;
options.visible = false;
}
return {
open,
visible,
title,
options,
requestUpload,
modalOpened,
rotateRight,
rotateLeft,
editCropper,
changeScale,
beforeUpload,
uploadImg,
realTime,
closeDialog,
};
},
};
</script>
<style lang='scss' scoped>
.user-info-head {
position: relative;
display: inline-block;
height: 120px;
}
.user-info-head:hover:after {
content: "+";
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #eee;
background: rgba(0, 0, 0, 0.5);
font-size: 24px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
cursor: pointer;
line-height: 110px;
border-radius: 50%;
}
</style>
@@ -0,0 +1,70 @@
<template>
<el-form ref="userRef" :model="user" :rules="rules" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="user.nickName" maxlength="30" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="user.phonenumber" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="user.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="user.sex">
<el-radio label="0">男</el-radio>
<el-radio label="1">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">保存</el-button>
<el-button type="danger" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { updateUserProfile } from "@/api/system/user";
const props = defineProps({
user: {
type: Object,
},
});
const { proxy } = getCurrentInstance();
const rules = ref({
nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
email: [
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
{
type: "email",
message: "'请输入正确的邮箱地址",
trigger: ["blur", "change"],
},
],
phonenumber: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur",
},
],
});
/** 提交按钮 */
function submit() {
proxy.$refs.userRef.validate((valid) => {
if (valid) {
updateUserProfile(props.user).then((response) => {
proxy.$modal.msgSuccess("修改成功");
});
}
});
}
/** 关闭按钮 */
function close() {
proxy.$tab.closePage();
}
</script>