feat: 完成用户管理功能。
This commit is contained in:
@@ -15,5 +15,8 @@ export const GATEWAY_TIMEOUT_URL = "/500";
|
|||||||
export const TEST_URL = "/test";
|
export const TEST_URL = "/test";
|
||||||
export const TEST_NAME = "test";
|
export const TEST_NAME = "test";
|
||||||
|
|
||||||
|
export const PERMISSION_URL = "/systemset/permission";
|
||||||
|
export const PERMISSION_NAME = "permission";
|
||||||
|
|
||||||
// 移动端最大宽度
|
// 移动端最大宽度
|
||||||
export const mobileMaxWidthMedia = "(max-width: 960px)";
|
export const mobileMaxWidthMedia = "(max-width: 960px)";
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export default {
|
|||||||
|
|
||||||
SYS: "系统管理",
|
SYS: "系统管理",
|
||||||
SYSUSER: "用户管理",
|
SYSUSER: "用户管理",
|
||||||
|
PERMISSION: "权限管理",
|
||||||
|
|
||||||
warehouse: "仓库管理",
|
warehouse: "仓库管理",
|
||||||
warehouse_item: "物料总表",
|
warehouse_item: "物料总表",
|
||||||
@@ -51,18 +52,33 @@ export default {
|
|||||||
repair_record: "维修记录",
|
repair_record: "维修记录",
|
||||||
|
|
||||||
systemset: "系统管理",
|
systemset: "系统管理",
|
||||||
syschannel: "栏目管理",
|
syschannel: "权限管理",
|
||||||
key_account: "客户管理",
|
key_account: "客户管理",
|
||||||
vendor: "供应商管理",
|
vendor: "供应商管理",
|
||||||
store: "仓库管理",
|
store: "仓库管理",
|
||||||
sysrecord: "日志列表",
|
sysrecord: "日志列表",
|
||||||
sysrole: "角色管理",
|
sysrole: "角色管理",
|
||||||
|
sysuser: "用户管理",
|
||||||
},
|
},
|
||||||
_enum: {
|
_enum: {
|
||||||
outStockType: {
|
outStockType: {
|
||||||
material: "物料",
|
material: "物料",
|
||||||
finishedProduct: "成品",
|
finishedProduct: "成品",
|
||||||
},
|
},
|
||||||
|
permissionType: {
|
||||||
|
menu: "菜单",
|
||||||
|
tableTopButton: "表格顶部按钮",
|
||||||
|
tableOperateButton: "表格操作按钮",
|
||||||
|
statusButton: "状态栏按钮",
|
||||||
|
},
|
||||||
|
userType: {
|
||||||
|
normal: "普通用户",
|
||||||
|
admin: "系统管理员",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_common: {
|
||||||
|
yes: "是",
|
||||||
|
no: "否",
|
||||||
},
|
},
|
||||||
_prop: {
|
_prop: {
|
||||||
common: {
|
common: {
|
||||||
@@ -402,10 +418,36 @@ export default {
|
|||||||
roleName: "角色名称",
|
roleName: "角色名称",
|
||||||
roleType: "角色类型",
|
roleType: "角色类型",
|
||||||
},
|
},
|
||||||
|
sysuser: {
|
||||||
|
loginName: "登录账号",
|
||||||
|
userName: "姓名",
|
||||||
|
password: "密码",
|
||||||
|
confirmPassword: "确认密码",
|
||||||
|
userType: "用户类型",
|
||||||
|
role: "角色",
|
||||||
|
roleNames: "角色",
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
permissionName: "权限名称",
|
||||||
|
permissionI18n: "国际化键",
|
||||||
|
permissionType: "权限类型",
|
||||||
|
permissionCode: "权限编码",
|
||||||
|
pageLink: "页面路由",
|
||||||
|
viewLink: "组件路径",
|
||||||
|
eventName: "事件名称",
|
||||||
|
className: "样式类名",
|
||||||
|
iconName: "图标名称",
|
||||||
|
sort: "排序",
|
||||||
|
hidden: "是否隐藏",
|
||||||
|
parentId: "父级权限",
|
||||||
|
rootNode: "根节点",
|
||||||
|
selectParent: "选择父级",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_button: {
|
_button: {
|
||||||
add: "新增",
|
add: "新增",
|
||||||
|
addChild: "新增子级",
|
||||||
edit: "编辑",
|
edit: "编辑",
|
||||||
remove: "删除",
|
remove: "删除",
|
||||||
batchRemove: "批量删除",
|
batchRemove: "批量删除",
|
||||||
@@ -832,6 +874,32 @@ export default {
|
|||||||
select_roleType: "请选择角色类型",
|
select_roleType: "请选择角色类型",
|
||||||
delete_message: "删除角色",
|
delete_message: "删除角色",
|
||||||
},
|
},
|
||||||
|
sysuser: {
|
||||||
|
input_loginName: "请输入登录账号",
|
||||||
|
input_userName: "请输入姓名",
|
||||||
|
input_password: "请输入密码",
|
||||||
|
input_password_edit: "不修改请留空",
|
||||||
|
input_confirmPassword: "请确认密码",
|
||||||
|
password_min_length: "密码长度不能少于6位",
|
||||||
|
password_not_match: "两次输入的密码不一致",
|
||||||
|
select_userType: "请选择用户类型",
|
||||||
|
select_role: "请选择角色",
|
||||||
|
delete_message: "删除用户",
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
input_permissionName: "请输入权限名称",
|
||||||
|
input_permissionI18n: "请输入国际化键",
|
||||||
|
select_permissionType: "请选择权限类型",
|
||||||
|
input_permissionCode: "请输入权限编码",
|
||||||
|
input_pageLink: "请输入页面路由",
|
||||||
|
input_viewLink: "请输入组件路径",
|
||||||
|
input_eventName: "请输入事件名称",
|
||||||
|
input_className: "请输入样式类名",
|
||||||
|
input_iconName: "请输入图标名称",
|
||||||
|
input_sort: "请输入排序值",
|
||||||
|
input_parentId: "请输入父级权限ID,0表示根节点",
|
||||||
|
delete_message: "删除权限",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_title: {
|
_title: {
|
||||||
@@ -961,6 +1029,15 @@ export default {
|
|||||||
add: "添加角色",
|
add: "添加角色",
|
||||||
edit: "编辑角色",
|
edit: "编辑角色",
|
||||||
},
|
},
|
||||||
|
sysuser: {
|
||||||
|
add: "添加用户",
|
||||||
|
edit: "编辑用户",
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
add: "添加权限",
|
||||||
|
addChild: "添加子权限",
|
||||||
|
edit: "编辑权限",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_tabNav: {
|
_tabNav: {
|
||||||
|
|||||||
94
src/components/base/base-multi-select/BaseMultiSelect.vue
Normal file
94
src/components/base/base-multi-select/BaseMultiSelect.vue
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { get } from "@/common/http/request";
|
||||||
|
|
||||||
|
interface OptionData {
|
||||||
|
value: string | number;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: "value",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: "label",
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array as PropType<Array<Record<string, string | number>>>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "请选择",
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
clearable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
collapseTags: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
collapseTagsTooltip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const optionData = ref<OptionData[]>([]);
|
||||||
|
const model = defineModel<(string | number)[]>({ required: true });
|
||||||
|
|
||||||
|
function pushOptionData(data: any[]) {
|
||||||
|
optionData.value = [];
|
||||||
|
for (const item of data) {
|
||||||
|
optionData.value.push({
|
||||||
|
value: props.name !== undefined ? item[props.name] : item["value"],
|
||||||
|
label: props.label !== undefined ? item[props.label] : item["label"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
if (props.url !== undefined) {
|
||||||
|
const res = await get(props.url);
|
||||||
|
pushOptionData(res.data || []);
|
||||||
|
} else if (props.data !== undefined) {
|
||||||
|
pushOptionData(props.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(getData);
|
||||||
|
|
||||||
|
const getSelectedLabels = () => {
|
||||||
|
return optionData.value.filter(item => model.value?.includes(item.value)).map(item => item.label);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getSelectedLabels,
|
||||||
|
refresh: getData,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<el-select
|
||||||
|
v-model="model"
|
||||||
|
multiple
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="disabled"
|
||||||
|
:clearable="clearable"
|
||||||
|
:collapse-tags="collapseTags"
|
||||||
|
:collapse-tags-tooltip="collapseTagsTooltip"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option v-for="o in optionData" :key="o.value" :value="o.value" :label="o.label" />
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Compass } from "@element-plus/icons-vue";
|
import { Compass } from "@element-plus/icons-vue";
|
||||||
import { HOME_URL, HOME_NAME, TEST_URL, TEST_NAME } from "@/common/config";
|
import { HOME_URL, HOME_NAME } from "@/common/config";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫描路由文件,获取默认暴露得路由信息
|
* 扫描路由文件,获取默认暴露得路由信息
|
||||||
@@ -77,13 +77,4 @@ export const dynamicRoutes: RouterConfigRaw[] = [
|
|||||||
tagProps: { type: "success" },
|
tagProps: { type: "success" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: TEST_URL,
|
|
||||||
name: TEST_NAME,
|
|
||||||
component: "/systemset/vendor/form",
|
|
||||||
meta: {
|
|
||||||
title: "总表",
|
|
||||||
icon: "ep:Compass",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import { Compass, Odometer } from "@element-plus/icons-vue";
|
// import { Compass, Odometer } from "@element-plus/icons-vue";
|
||||||
import { $t } from "@/common/languages";
|
// import { $t } from "@/common/languages";
|
||||||
|
|
||||||
export const sysRoutes: RouterConfigRaw = {
|
// export const sysRoutes: RouterConfigRaw = {
|
||||||
path: "/sys",
|
// path: "/sys",
|
||||||
name: "sys",
|
// name: "sys",
|
||||||
meta: {
|
// meta: {
|
||||||
title: $t("{{ _route.SYS }}"),
|
// title: $t("{{ _route.SYS }}"),
|
||||||
icon: Odometer,
|
// icon: Odometer,
|
||||||
},
|
// },
|
||||||
children: [
|
// children: [
|
||||||
{
|
// {
|
||||||
path: "/sys/sysuser",
|
// path: "/sys/sysuser",
|
||||||
name: "sysuser",
|
// name: "sysuser",
|
||||||
component: "/sys/sysuser/index",
|
// component: "/sys/sysuser/index",
|
||||||
meta: {
|
// meta: {
|
||||||
title: $t("{{ _route.SYSUSER }}"),
|
// title: $t("{{ _route.SYSUSER }}"),
|
||||||
icon: Compass,
|
// icon: Compass,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
};
|
// };
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import BaseSelect from "@/components/base/base-select/BaseSelect.vue";
|
|
||||||
const form = defineModel<Record<string, any>>();
|
|
||||||
const roleUrl = "/sys/role/getSysRoleSelectList";
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<!-- <el-dialog> -->
|
|
||||||
<el-form label-position="left" label-width="auto" :model="form">
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="登录名称"><el-input class="two-col-input" /></el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="用户名"><el-input class="two-col-input" /></el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="20" class="password-box">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="密码"><el-input class="two-col-input" type="password" /></el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="确认密码"><el-input class="two-col-input" type="password" /></el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="20" class="password-box">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="密码"><el-input class="two-col-input" type="password" /></el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="角色"><BaseSelect :url="roleUrl" name="roleId" label="roleName" /></el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<!-- </el-dialog> -->
|
|
||||||
</template>
|
|
||||||
<style>
|
|
||||||
.two-col-input {
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
121
src/views/sys/sysuser/SysUserView.vue
Normal file
121
src/views/sys/sysuser/SysUserView.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { get, post } from "@/common/http/request";
|
||||||
|
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
|
||||||
|
import StatusSwitch from "@/components/base/base-switch/StatusSwitch.vue";
|
||||||
|
import UserFormDialog from "./UserFormDialog.vue";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
|
||||||
|
import DefaultOperateButtonColumn from "@/components/base/default-column/DefaultOperateButtonColumn.vue";
|
||||||
|
|
||||||
|
const url = "/api/sys/sysuser/getSysUserPage";
|
||||||
|
const menu = "sysuser";
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const formDialogVisible = ref(false);
|
||||||
|
const isEdit = ref(false);
|
||||||
|
const currentRow = ref<Record<string, any>>({});
|
||||||
|
|
||||||
|
const searchers = [
|
||||||
|
{ name: "loginName", type: "text" as const, placeholder: "请输入账号" },
|
||||||
|
{ name: "userName", type: "text" as const, placeholder: "请输入姓名" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const userTypeMap: Record<number, string> = {
|
||||||
|
0: "普通用户",
|
||||||
|
5: "系统管理员",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUserTypeLabel = (type: number) => userTypeMap[type] || "未知";
|
||||||
|
|
||||||
|
const addClick = () => {
|
||||||
|
isEdit.value = false;
|
||||||
|
currentRow.value = {
|
||||||
|
loginName: "",
|
||||||
|
userName: "",
|
||||||
|
passWord: "",
|
||||||
|
confirmPassword: "",
|
||||||
|
userType: 0,
|
||||||
|
roleIds: [],
|
||||||
|
status: 1,
|
||||||
|
};
|
||||||
|
formDialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const editClick = (row: Record<string, any>) => {
|
||||||
|
isEdit.value = true;
|
||||||
|
currentRow.value = {
|
||||||
|
...row,
|
||||||
|
passWord: "",
|
||||||
|
confirmPassword: "",
|
||||||
|
roleIds: row.roleIds || [],
|
||||||
|
};
|
||||||
|
formDialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteClick = async (row: Record<string, any>) => {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm("确定要删除该用户吗?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
await post("/api/sys/sysuser/deleteSysUser", { id: row.id });
|
||||||
|
ElMessage.success("删除成功");
|
||||||
|
tableRef.value?.refresh();
|
||||||
|
} catch (error) {
|
||||||
|
// 用户取消删除
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStatusChange = async (row: Record<string, any>) => {
|
||||||
|
try {
|
||||||
|
await post("/api/sys/sysuser/setStatus", {
|
||||||
|
id: row.id,
|
||||||
|
status: row.status,
|
||||||
|
});
|
||||||
|
ElMessage.success("状态修改成功");
|
||||||
|
} catch (error) {
|
||||||
|
// 恢复原状态
|
||||||
|
row.status = row.status === 1 ? 0 : 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSuccess = () => {
|
||||||
|
tableRef.value?.refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDialogTitle = computed(() => (isEdit.value ? "编辑用户" : "新建用户"));
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<BasePageableTable ref="tableRef" :url="url" :searchers="searchers">
|
||||||
|
<template #tool-button>
|
||||||
|
<DefaultToolButton :add-click="addClick" :menu="menu" />
|
||||||
|
</template>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column type="selection" width="40" />
|
||||||
|
<el-table-column label="账号" prop="loginName" min-width="120" />
|
||||||
|
<el-table-column label="姓名" prop="userName" min-width="120" />
|
||||||
|
<el-table-column label="角色" min-width="200" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.roleNames || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="用户类型" prop="userType" min-width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getUserTypeLabel(row.userType) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" prop="createDate" min-width="160" />
|
||||||
|
<DefaultStatusSwitchColumn />
|
||||||
|
<DefaultOperateButtonColumn />
|
||||||
|
</template>
|
||||||
|
</BasePageableTable>
|
||||||
|
|
||||||
|
<UserFormDialog
|
||||||
|
v-model:visible="formDialogVisible"
|
||||||
|
v-model:is-edit="isEdit"
|
||||||
|
v-model:form-data="currentRow"
|
||||||
|
:title="getDialogTitle"
|
||||||
|
@success="handleSuccess"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
172
src/views/sys/sysuser/UserFormDialog.vue
Normal file
172
src/views/sys/sysuser/UserFormDialog.vue
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { post, put, get } from "@/common/http/request";
|
||||||
|
import BaseMultiSelect from "@/components/base/base-multi-select/BaseMultiSelect.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const visible = defineModel<boolean>("visible", { required: true });
|
||||||
|
const isEdit = defineModel<boolean>("isEdit", { required: true });
|
||||||
|
const formData = defineModel<Record<string, any>>("formData", { required: true });
|
||||||
|
const emit = defineEmits(["success"]);
|
||||||
|
|
||||||
|
const roleUrl = "/api/sys/sysrole/getSysRoleSelectList";
|
||||||
|
const userTypeOptions = [
|
||||||
|
{ value: 0, label: "普通用户" },
|
||||||
|
{ value: 5, label: "系统管理员" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const loading = ref(false);
|
||||||
|
const passwordModified = ref(false);
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
loginName: [{ required: true, message: "请输入登录账号", trigger: "blur" }],
|
||||||
|
userName: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||||
|
passWord: [
|
||||||
|
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||||
|
{ min: 6, message: "密码长度不能少于6位", trigger: "blur" },
|
||||||
|
],
|
||||||
|
confirmPassword: [
|
||||||
|
{ required: true, message: "请确认密码", trigger: "blur" },
|
||||||
|
{
|
||||||
|
validator: (rule: any, value: string, callback: Function) => {
|
||||||
|
if (value !== formData.value.passWord) {
|
||||||
|
callback(new Error("两次输入的密码不一致"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
userType: [{ required: true, message: "请选择用户类型", trigger: "change" }],
|
||||||
|
roleIds: [{ required: true, message: "请选择角色", trigger: "change", type: "array" }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePasswordChange = () => {
|
||||||
|
if (isEdit.value) {
|
||||||
|
passwordModified.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
const valid = await formRef.value?.validate().catch(() => false);
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const submitData = { ...formData.value };
|
||||||
|
|
||||||
|
// 编辑模式下,如果密码未修改,则不提交密码字段
|
||||||
|
if (isEdit.value && !passwordModified.value) {
|
||||||
|
delete submitData.passWord;
|
||||||
|
delete submitData.confirmPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEdit.value) {
|
||||||
|
await put(`/api/sys/sysuser/${submitData.id}`, submitData);
|
||||||
|
} else {
|
||||||
|
await post("/api/sys/sysuser", submitData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessage.success(isEdit.value ? "编辑成功" : "新建成功");
|
||||||
|
visible.value = false;
|
||||||
|
emit("success");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
passwordModified.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpen = () => {
|
||||||
|
if (!isEdit.value) {
|
||||||
|
// 新建时重置密码相关状态
|
||||||
|
passwordModified.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
:title="title"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@close="handleClose"
|
||||||
|
@open="handleOpen"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules" label-position="right" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="登录账号" prop="loginName">
|
||||||
|
<el-input v-model="formData.loginName" placeholder="请输入登录账号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="姓名" prop="userName">
|
||||||
|
<el-input v-model="formData.userName" placeholder="请输入姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="密码" prop="passWord">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.passWord"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
show-password
|
||||||
|
@input="handlePasswordChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="确认密码" prop="confirmPassword">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.confirmPassword"
|
||||||
|
type="password"
|
||||||
|
placeholder="请确认密码"
|
||||||
|
show-password
|
||||||
|
@input="handlePasswordChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="用户类型" prop="userType">
|
||||||
|
<el-select v-model="formData.userType" placeholder="请选择用户类型" style="width: 100%">
|
||||||
|
<el-option v-for="item in userTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="角色" prop="roleIds">
|
||||||
|
<BaseMultiSelect
|
||||||
|
v-model="formData.roleIds"
|
||||||
|
:url="roleUrl"
|
||||||
|
name="roleId"
|
||||||
|
label="roleName"
|
||||||
|
placeholder="请选择角色"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import BasePageableTable from "@/components/base/base-pageable-table/BasePageableTable.vue";
|
|
||||||
import DefaultOperateButton from "@/components/base/default-operate-button/DefaultOperateButton.vue";
|
|
||||||
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
|
|
||||||
import FormView from "./FormView.vue";
|
|
||||||
|
|
||||||
const url = "/api/user/getUserPage";
|
|
||||||
const menu = "sysuser";
|
|
||||||
const searchers = [{ name: "loginName", type: "text" as const, placeholder: "请输入登录名" }];
|
|
||||||
const addClick = () => {};
|
|
||||||
const editClick = () => {};
|
|
||||||
const delteClick = () => {};
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<BasePageableTable :url="url" :searchers="searchers">
|
|
||||||
<template #tool-button>
|
|
||||||
<DefaultToolButton :add-click="addClick" :menu="menu" />
|
|
||||||
</template>
|
|
||||||
<template #columns>
|
|
||||||
<el-table-column prop="id" type="selection" width="40" />
|
|
||||||
<el-table-column label="登录账户" prop="loginName" />
|
|
||||||
<el-table-column label="用户名" prop="userName" />
|
|
||||||
<el-table-column label="集团" prop="contactPerson" />
|
|
||||||
<el-table-column label="登录次数" prop="loginCount" />
|
|
||||||
<el-table-column label="登陆时间" prop="loginDate" />
|
|
||||||
<el-table-column label="登录 IP" prop="loginIp" />
|
|
||||||
<el-table-column label="创建时间" prop="createDate" />
|
|
||||||
<el-table-column>
|
|
||||||
<DefaultOperateButton :edit-click="editClick" :delete-click="delteClick" :menu="menu" />
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
</BasePageableTable>
|
|
||||||
<FormView />
|
|
||||||
</template>
|
|
||||||
286
src/views/systemset/permission/PermissionView.vue
Normal file
286
src/views/systemset/permission/PermissionView.vue
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
|
||||||
|
import DefaultOperateButtonColumn from "@/components/base/default-column/DefaultOperateButtonColumn.vue";
|
||||||
|
import { usePage } from "@/composables/use-page";
|
||||||
|
import BaseForm from "@/components/base/base-form/BaseForm.vue";
|
||||||
|
import { $t } from "@/common/languages";
|
||||||
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
|
import { formatDate } from "@/common/utils/format-utils";
|
||||||
|
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
||||||
|
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
|
||||||
|
import StatusSwitch from "@/components/base/base-switch/StatusSwitch.vue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必须要的变量
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getPageUrl = "/sys/syspermission/getSysPermissionPage";
|
||||||
|
const treeSideUrl = "/sys/syspermission/getPermissionTree";
|
||||||
|
const addUrl = "/sys/syspermission/addSysPermission";
|
||||||
|
const editUrl = "/sys/syspermission/updateSysPermission";
|
||||||
|
const removeUrl = "/sys/syspermission/deleteSysPermission";
|
||||||
|
const statusUrl = "/sys/syspermission/setStatus";
|
||||||
|
const searchers = [
|
||||||
|
{
|
||||||
|
name: "permissionName",
|
||||||
|
type: "text" as const,
|
||||||
|
placeholder: $t("_prop.systemset.permission.permissionName"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const rules = reactive<FormRules>({
|
||||||
|
permissionName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t("_message.systemset.permission.input_permissionName"),
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
permissionType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t("_message.systemset.permission.select_permissionType"),
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sort: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t("_message.systemset.permission.input_sort"),
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限类型枚举
|
||||||
|
*/
|
||||||
|
const permissionTypeOptions = [
|
||||||
|
{ code: 0, description: $t("_enum.permissionType.menu") },
|
||||||
|
{ code: 1, description: $t("_enum.permissionType.tableTopButton") },
|
||||||
|
{ code: 2, description: $t("_enum.permissionType.tableOperateButton") },
|
||||||
|
{ code: 3, description: $t("_enum.permissionType.statusButton") },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本不变通用变量
|
||||||
|
*/
|
||||||
|
const tableRef = ref<InstanceType<typeof TreeSidePageableTable> | null>(null);
|
||||||
|
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
||||||
|
const { title, visible, formType, form } = useGeneralPageRef();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可以自定义的变量
|
||||||
|
*/
|
||||||
|
|
||||||
|
const add = () => {
|
||||||
|
form.value = {};
|
||||||
|
title.value = "_title.systemset.permission.add";
|
||||||
|
visible.value = true;
|
||||||
|
formType.value = false;
|
||||||
|
};
|
||||||
|
const edit = (row: any) => {
|
||||||
|
title.value = "_title.systemset.permission.edit";
|
||||||
|
form.value = { ...row };
|
||||||
|
visible.value = true;
|
||||||
|
formType.value = true;
|
||||||
|
};
|
||||||
|
const remove = (row: any) => {
|
||||||
|
useRemove(removeUrl, row.id, "_message.systemset.permission.delete_message");
|
||||||
|
};
|
||||||
|
const submit = (formData: any, formRef: FormInstance | undefined) => {
|
||||||
|
if (formRef !== undefined) {
|
||||||
|
formRef.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (formType.value) useEdit(editUrl, formData, visible);
|
||||||
|
else useAdd(addUrl, formData, visible);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const topButtonClick = (eventName: string) => {
|
||||||
|
switch (eventName) {
|
||||||
|
case "add":
|
||||||
|
add();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
|
switch (eventName) {
|
||||||
|
case "edit":
|
||||||
|
edit(row);
|
||||||
|
break;
|
||||||
|
case "remove":
|
||||||
|
remove(row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限类型格式化
|
||||||
|
*/
|
||||||
|
const formatPermissionType = (row: any) => {
|
||||||
|
const type = permissionTypeOptions.find(item => item.code === row.permissionType);
|
||||||
|
return type?.description || "";
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TreeSidePageableTable
|
||||||
|
:url="getPageUrl"
|
||||||
|
:searchers="searchers"
|
||||||
|
ref="tableRef"
|
||||||
|
:tree-side-url="treeSideUrl"
|
||||||
|
tree-side-param-name="parentId"
|
||||||
|
tree-side-node-name="id"
|
||||||
|
>
|
||||||
|
<template #tool-button>
|
||||||
|
<DefaultToolButton @top-button-click="topButtonClick" />
|
||||||
|
</template>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.permissionName')" prop="permissionName" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.permissionCode')" prop="permissionCode" />
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('_prop.systemset.permission.permissionType')"
|
||||||
|
prop="permissionType"
|
||||||
|
:formatter="formatPermissionType"
|
||||||
|
/>
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.pageLink')" prop="pageLink" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.eventName')" prop="eventName" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.iconName')" prop="iconName" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.sort')" prop="sort" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.permission.hidden')" prop="hidden">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag v-if="row.hidden" type="info" size="small">
|
||||||
|
{{ $t("_common.yes") }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else type="success" size="small">
|
||||||
|
{{ $t("_common.no") }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<DefaultStatusSwitchColumn :url="statusUrl" />
|
||||||
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
|
</template>
|
||||||
|
</TreeSidePageableTable>
|
||||||
|
|
||||||
|
<BaseForm v-model:visible="visible" @submit="submit" v-model:form="form" :title="$t(title)" :rules="rules">
|
||||||
|
<template #form-items>
|
||||||
|
<el-form-item prop="id" v-if="false">
|
||||||
|
<el-input v-model="form.id" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.permissionName')" prop="permissionName">
|
||||||
|
<el-input
|
||||||
|
v-model="form.permissionName"
|
||||||
|
:placeholder="$t('_message.systemset.permission.input_permissionName')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.permissionI18n')" prop="permissionI18n">
|
||||||
|
<el-input
|
||||||
|
v-model="form.permissionI18n"
|
||||||
|
:placeholder="$t('_message.systemset.permission.input_permissionI18n')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.permissionType')" prop="permissionType">
|
||||||
|
<el-select
|
||||||
|
v-model="form.permissionType"
|
||||||
|
:placeholder="$t('_message.systemset.permission.select_permissionType')"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in permissionTypeOptions"
|
||||||
|
:key="item.code"
|
||||||
|
:label="item.description"
|
||||||
|
:value="item.code"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.permissionCode')" prop="permissionCode">
|
||||||
|
<el-input
|
||||||
|
v-model="form.permissionCode"
|
||||||
|
:placeholder="$t('_message.systemset.permission.input_permissionCode')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.pageLink')" prop="pageLink">
|
||||||
|
<el-input v-model="form.pageLink" :placeholder="$t('_message.systemset.permission.input_pageLink')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.viewLink')" prop="viewLink">
|
||||||
|
<el-input v-model="form.viewLink" :placeholder="$t('_message.systemset.permission.input_viewLink')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.eventName')" prop="eventName">
|
||||||
|
<el-input v-model="form.eventName" :placeholder="$t('_message.systemset.permission.input_eventName')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.className')" prop="className">
|
||||||
|
<el-input v-model="form.className" :placeholder="$t('_message.systemset.permission.input_className')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.iconName')" prop="iconName">
|
||||||
|
<el-input v-model="form.iconName" :placeholder="$t('_message.systemset.permission.input_iconName')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.sort')" prop="sort">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.sort"
|
||||||
|
:min="0"
|
||||||
|
:placeholder="$t('_message.systemset.permission.input_sort')"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.common.status')" prop="status">
|
||||||
|
<StatusSwitch v-model="form.status" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.hidden')" prop="hidden">
|
||||||
|
<el-switch v-model="form.hidden" :active-text="$t('_common.yes')" :inactive-text="$t('_common.no')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item :label="$t('_prop.systemset.permission.parentId')" prop="parentId">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.parentId"
|
||||||
|
:min="0"
|
||||||
|
:placeholder="$t('_message.systemset.permission.input_parentId')"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</BaseForm>
|
||||||
|
</template>
|
||||||
@@ -21,7 +21,7 @@ const addUrl = "/sys/sysrole/addSysRole";
|
|||||||
const editUrl = "/sys/sysrole/updateSysRole";
|
const editUrl = "/sys/sysrole/updateSysRole";
|
||||||
const removeUrl = "/sys/sysrole/deleteSysRole";
|
const removeUrl = "/sys/sysrole/deleteSysRole";
|
||||||
const statusUrl = "/sys/sysrole/setStatus";
|
const statusUrl = "/sys/sysrole/setStatus";
|
||||||
const treeUrl = "/sys/syschannel/getSysChannelTree";
|
const treeUrl = "/sys/syspermission/getPermissionTree";
|
||||||
const searchers = [{ name: "roleName", type: "text" as const, placeholder: $t("_prop.systemset.sysrole.roleName") }];
|
const searchers = [{ name: "roleName", type: "text" as const, placeholder: $t("_prop.systemset.sysrole.roleName") }];
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
roleName: [{ required: true, message: $t("_message.systemset.sysrole.input_roleName"), trigger: "blur" }],
|
roleName: [{ required: true, message: $t("_message.systemset.sysrole.input_roleName"), trigger: "blur" }],
|
||||||
@@ -128,7 +128,7 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
</el-row>
|
</el-row>
|
||||||
<br />
|
<br />
|
||||||
<el-form-item style="max-height: 400px; overflow: auto">
|
<el-form-item style="max-height: 400px; overflow: auto">
|
||||||
<BaseTree ref="treeRef" :url="treeUrl" :show-checkbox="true" v-model="form.channelIds" />
|
<BaseTree ref="treeRef" :url="treeUrl" :show-checkbox="true" v-model="form.permissionIds" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</BaseForm>
|
</BaseForm>
|
||||||
|
|||||||
288
src/views/systemset/sysuser/SysUserView.vue
Normal file
288
src/views/systemset/sysuser/SysUserView.vue
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import BasePageableTable from "@/components/base/base-pageable-table/BasePageableTable.vue";
|
||||||
|
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
|
||||||
|
import DefaultOperateButtonColumn from "@/components/base/default-column/DefaultOperateButtonColumn.vue";
|
||||||
|
import { usePage } from "@/composables/use-page";
|
||||||
|
import BaseForm from "@/components/base/base-form/BaseForm.vue";
|
||||||
|
import { $t } from "@/common/languages";
|
||||||
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
|
import { formatDate } from "@/common/utils/format-utils";
|
||||||
|
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
|
||||||
|
import StatusSwitch from "@/components/base/base-switch/StatusSwitch.vue";
|
||||||
|
import BaseMultiSelect from "@/components/base/base-multi-select/BaseMultiSelect.vue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 必须要的变量
|
||||||
|
*/
|
||||||
|
const getPageUrl = "/sys/sysuser/getSysUserPage";
|
||||||
|
const addUrl = "/sys/sysuser/addSysUser";
|
||||||
|
const editUrl = "/sys/sysuser/updateSysUser";
|
||||||
|
const removeUrl = "/sys/sysuser/deleteSysUser";
|
||||||
|
const statusUrl = "/sys/sysuser/setStatus";
|
||||||
|
const roleSelectUrl = "/sys/sysrole/getSysRoleSelectList";
|
||||||
|
|
||||||
|
const searchers = [
|
||||||
|
{ name: "loginName", type: "text" as const, placeholder: $t("_prop.systemset.sysuser.loginName") },
|
||||||
|
{ name: "userName", type: "text" as const, placeholder: $t("_prop.systemset.sysuser.userName") },
|
||||||
|
];
|
||||||
|
|
||||||
|
const rules = reactive<FormRules>({
|
||||||
|
loginName: [{ required: true, message: $t("_message.systemset.sysuser.input_loginName"), trigger: "blur" }],
|
||||||
|
userName: [{ required: true, message: $t("_message.systemset.sysuser.input_userName"), trigger: "blur" }],
|
||||||
|
passWord: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
// 编辑模式下密码为空表示不修改,允许通过
|
||||||
|
if (formType.value && !value) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 新建模式下密码必填
|
||||||
|
if (!formType.value && !value) {
|
||||||
|
callback(new Error($t("_message.systemset.sysuser.input_password")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 密码长度校验
|
||||||
|
if (value && value.length < 6) {
|
||||||
|
callback(new Error($t("_message.systemset.sysuser.password_min_length")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
confirmPassword: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
// 编辑模式下如果密码为空,确认密码也为空时允许通过
|
||||||
|
if (formType.value && !form.value.passWord && !value) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 新建模式下确认密码必填
|
||||||
|
if (!formType.value && !value) {
|
||||||
|
callback(new Error($t("_message.systemset.sysuser.input_confirmPassword")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 密码一致性校验
|
||||||
|
if (value !== form.value.passWord) {
|
||||||
|
callback(new Error($t("_message.systemset.sysuser.password_not_match")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
userType: [{ required: true, message: $t("_message.systemset.sysuser.select_userType"), trigger: "change" }],
|
||||||
|
roleIds: [
|
||||||
|
{ required: true, message: $t("_message.systemset.sysuser.select_role"), trigger: "change", type: "array" },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const userTypeOptions = [
|
||||||
|
{ code: 0, description: $t("_enum.userType.normal") },
|
||||||
|
{ code: 5, description: $t("_enum.userType.admin") },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本不变通用变量
|
||||||
|
*/
|
||||||
|
const tableRef = ref<InstanceType<typeof BasePageableTable> | null>(null);
|
||||||
|
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
||||||
|
const { title, visible, formType, form } = useGeneralPageRef();
|
||||||
|
const baseFormRef = ref<InstanceType<typeof BaseForm>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可以自定义的变量
|
||||||
|
*/
|
||||||
|
const add = () => {
|
||||||
|
form.value = {
|
||||||
|
userType: 0,
|
||||||
|
roleIds: [],
|
||||||
|
status: 1,
|
||||||
|
};
|
||||||
|
title.value = "_title.systemset.sysuser.add";
|
||||||
|
visible.value = true;
|
||||||
|
formType.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const edit = (row: any) => {
|
||||||
|
title.value = "_title.systemset.sysuser.edit";
|
||||||
|
form.value = {
|
||||||
|
...row,
|
||||||
|
passWord: "",
|
||||||
|
confirmPassword: "",
|
||||||
|
roleIds: row.roleIds || [],
|
||||||
|
};
|
||||||
|
visible.value = true;
|
||||||
|
formType.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const remove = (row: any) => {
|
||||||
|
useRemove(removeUrl, row.id, "_message.systemset.sysuser.delete_message");
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = (formData: any, formRef: FormInstance | undefined) => {
|
||||||
|
if (formRef !== undefined) {
|
||||||
|
formRef.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
const submitData = { ...formData };
|
||||||
|
// 编辑模式下,如果密码为空,则不提交密码字段
|
||||||
|
if (formType.value && !submitData.passWord) {
|
||||||
|
delete submitData.passWord;
|
||||||
|
delete submitData.confirmPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formType.value) {
|
||||||
|
// 编辑模式:使用新的 DTO 格式 { id, dto }
|
||||||
|
const updateData = {
|
||||||
|
id: submitData.id,
|
||||||
|
dto: submitData,
|
||||||
|
};
|
||||||
|
useEdit(editUrl, updateData, visible);
|
||||||
|
} else {
|
||||||
|
useAdd(addUrl, submitData, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const topButtonClick = (eventName: string) => {
|
||||||
|
switch (eventName) {
|
||||||
|
case "add":
|
||||||
|
add();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
|
switch (eventName) {
|
||||||
|
case "edit":
|
||||||
|
edit(row);
|
||||||
|
break;
|
||||||
|
case "remove":
|
||||||
|
remove(row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUserTypeLabel = (type: number) => {
|
||||||
|
const option = userTypeOptions.find(item => item.code === type);
|
||||||
|
return option?.description || "-";
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
||||||
|
<template #tool-button>
|
||||||
|
<DefaultToolButton @top-button-click="topButtonClick" />
|
||||||
|
</template>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column :label="$t('_prop.systemset.sysuser.loginName')" prop="loginName" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.sysuser.userName')" prop="userName" />
|
||||||
|
<el-table-column :label="$t('_prop.systemset.sysuser.roleNames')" prop="roleNames" show-overflow-tooltip />
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('_prop.systemset.sysuser.userType')"
|
||||||
|
prop="userType"
|
||||||
|
:formatter="(row: any) => getUserTypeLabel(row.userType)"
|
||||||
|
/>
|
||||||
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
|
<DefaultStatusSwitchColumn :url="statusUrl" />
|
||||||
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
|
</template>
|
||||||
|
</BasePageableTable>
|
||||||
|
|
||||||
|
<BaseForm
|
||||||
|
ref="baseFormRef"
|
||||||
|
v-model:visible="visible"
|
||||||
|
@submit="submit"
|
||||||
|
v-model:form="form"
|
||||||
|
:title="$t(title)"
|
||||||
|
:rules="rules"
|
||||||
|
>
|
||||||
|
<template #form-items>
|
||||||
|
<el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.sysuser.loginName')" prop="loginName">
|
||||||
|
<el-input v-model="form.loginName" :placeholder="$t('_message.systemset.sysuser.input_loginName')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.sysuser.userName')" prop="userName">
|
||||||
|
<el-input v-model="form.userName" :placeholder="$t('_message.systemset.sysuser.input_userName')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.sysuser.password')" prop="passWord">
|
||||||
|
<el-input
|
||||||
|
v-model="form.passWord"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
:placeholder="
|
||||||
|
formType
|
||||||
|
? $t('_message.systemset.sysuser.input_password_edit')
|
||||||
|
: $t('_message.systemset.sysuser.input_password')
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.sysuser.confirmPassword')" prop="confirmPassword">
|
||||||
|
<el-input
|
||||||
|
v-model="form.confirmPassword"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
:placeholder="$t('_message.systemset.sysuser.input_confirmPassword')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.sysuser.userType')" prop="userType">
|
||||||
|
<el-select
|
||||||
|
v-model="form.userType"
|
||||||
|
:placeholder="$t('_message.systemset.sysuser.select_userType')"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in userTypeOptions"
|
||||||
|
:key="item.code"
|
||||||
|
:label="item.description"
|
||||||
|
:value="item.code"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.systemset.sysuser.role')" prop="roleIds">
|
||||||
|
<BaseMultiSelect
|
||||||
|
v-model="form.roleIds"
|
||||||
|
:url="roleSelectUrl"
|
||||||
|
name="roleId"
|
||||||
|
label="roleName"
|
||||||
|
:placeholder="$t('_message.systemset.sysuser.select_role')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.common.status')" prop="status">
|
||||||
|
<StatusSwitch v-model="form.status" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
</BaseForm>
|
||||||
|
</template>
|
||||||
Reference in New Issue
Block a user