|
@@ -1,11 +1,427 @@
|
|
|
-<script setup lang="ts">
|
|
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <PlusPage
|
|
|
|
|
+ ref="plusPageInstance"
|
|
|
|
|
+ :columns="tableConfig"
|
|
|
|
|
+ :request="getList"
|
|
|
|
|
+ :is-card="true"
|
|
|
|
|
+ :search="{
|
|
|
|
|
+ labelWidth: 100,
|
|
|
|
|
+ showNumber: 3
|
|
|
|
|
+ }"
|
|
|
|
|
+ :table="{
|
|
|
|
|
+ actionBar: { buttons, type: 'link', width: 140 },
|
|
|
|
|
+ adaptive: { offsetBottom: 50 }
|
|
|
|
|
+ }"
|
|
|
|
|
+ :pagination="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #table-title>
|
|
|
|
|
+ <el-row class="button-row">
|
|
|
|
|
+ <el-button size="default" type="success" @click="handleCreate">
|
|
|
|
|
+ 新增
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </PlusPage>
|
|
|
|
|
+ <!-- 弹窗编辑 -->
|
|
|
|
|
+ <PlusDialogForm
|
|
|
|
|
+ ref="dialogForm"
|
|
|
|
|
+ v-model="form"
|
|
|
|
|
+ v-model:visible="dialogVisible"
|
|
|
|
|
+ :form="{
|
|
|
|
|
+ columns,
|
|
|
|
|
+ labelPosition: 'right',
|
|
|
|
|
+ labelWidth: 100,
|
|
|
|
|
+ rules,
|
|
|
|
|
+ rowProps: { gutter: 20 },
|
|
|
|
|
+ colProps: { span: 12 }
|
|
|
|
|
+ }"
|
|
|
|
|
+ :dialog="{ title: dialogTitle + '菜单', width: 800, confirmLoading }"
|
|
|
|
|
+ @confirm="handleSubmit"
|
|
|
|
|
+ @close="handleClose"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+import {
|
|
|
|
|
+ computed,
|
|
|
|
|
+ defineOptions,
|
|
|
|
|
+ onMounted,
|
|
|
|
|
+ reactive,
|
|
|
|
|
+ ref,
|
|
|
|
|
+ toRefs,
|
|
|
|
|
+ type Ref
|
|
|
|
|
+} from "vue";
|
|
|
|
|
+import type { FormRules } from "element-plus";
|
|
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
|
|
+import {
|
|
|
|
|
+ type FieldValues,
|
|
|
|
|
+ type PlusColumn,
|
|
|
|
|
+ type OptionsRow,
|
|
|
|
|
+ PlusDialogForm,
|
|
|
|
|
+ PlusPage,
|
|
|
|
|
+ PlusPageInstance,
|
|
|
|
|
+ useTable
|
|
|
|
|
+} from "plus-pro-components";
|
|
|
|
|
+import {
|
|
|
|
|
+ addUser,
|
|
|
|
|
+ deleteUser,
|
|
|
|
|
+ editUser,
|
|
|
|
|
+ getSystemUserList,
|
|
|
|
|
+ getUserInfoById
|
|
|
|
|
+} from "@/api/system/user";
|
|
|
|
|
+import {
|
|
|
|
|
+ getSystemRoleDeptTree,
|
|
|
|
|
+ getSystemRoleOptionselect
|
|
|
|
|
+} from "@/api/system/role";
|
|
|
|
|
+
|
|
|
defineOptions({
|
|
defineOptions({
|
|
|
name: "User"
|
|
name: "User"
|
|
|
});
|
|
});
|
|
|
-</script>
|
|
|
|
|
|
|
|
|
|
-<template>
|
|
|
|
|
- <div />
|
|
|
|
|
-</template>
|
|
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ await getDeptList();
|
|
|
|
|
+ await getRoleOptions();
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 菜单列表
|
|
|
|
|
+const menuList = ref([]);
|
|
|
|
|
+const plusPageInstance = ref<PlusPageInstance | null>(null);
|
|
|
|
|
+
|
|
|
|
|
+const getList = async (query: Record<string, any>) => {
|
|
|
|
|
+ let res = await getSystemUserList(query);
|
|
|
|
|
+ return {
|
|
|
|
|
+ data: res.rows,
|
|
|
|
|
+ total: res.total
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 重新请求列表接口
|
|
|
|
|
+const refresh = () => {
|
|
|
|
|
+ plusPageInstance.value?.getList();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const dialogTitle = computed(() => (state.isCreate ? "新增" : "编辑"));
|
|
|
|
|
+
|
|
|
|
|
+const { buttons } = useTable();
|
|
|
|
|
+
|
|
|
|
|
+// 表格数据
|
|
|
|
|
+const tableConfig: PlusColumn[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "用户姓名",
|
|
|
|
|
+ prop: "nickName",
|
|
|
|
|
+ width: 180,
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "登录账号",
|
|
|
|
|
+ prop: "userName",
|
|
|
|
|
+ width: 180,
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "角色",
|
|
|
|
|
+ prop: "roleName",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "所属部门",
|
|
|
|
|
+ prop: "deptName",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "岗位",
|
|
|
|
|
+ prop: "postName",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ /*{
|
|
|
|
|
+ label: "用户类型",
|
|
|
|
|
+ prop: "menuName",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },*/
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "状态",
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ hideInSearch: true,
|
|
|
|
|
+ valueType: "select",
|
|
|
|
|
+ options: [
|
|
|
|
|
+ { label: "启用", value: "0" },
|
|
|
|
|
+ { label: "停用", value: "1" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "最近IP",
|
|
|
|
|
+ prop: "loginIp",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "最近登录时间",
|
|
|
|
|
+ prop: "loginDate",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ }
|
|
|
|
|
+];
|
|
|
|
|
|
|
|
-<style scoped lang="scss"></style>
|
|
|
|
|
|
|
+/*--------------------表单--------------------*/
|
|
|
|
|
+
|
|
|
|
|
+// 表单实例
|
|
|
|
|
+const dialogForm = ref(null);
|
|
|
|
|
+
|
|
|
|
|
+interface State {
|
|
|
|
|
+ dialogVisible: boolean;
|
|
|
|
|
+ detailsVisible: boolean;
|
|
|
|
|
+ confirmLoading: boolean;
|
|
|
|
|
+ selectedIds: number[];
|
|
|
|
|
+ isCreate: boolean;
|
|
|
|
|
+ form: {};
|
|
|
|
|
+ rules: FormRules;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const state = reactive<State>({
|
|
|
|
|
+ dialogVisible: false,
|
|
|
|
|
+ detailsVisible: false,
|
|
|
|
|
+ confirmLoading: false,
|
|
|
|
|
+ selectedIds: [],
|
|
|
|
|
+ isCreate: false,
|
|
|
|
|
+ form: {},
|
|
|
|
|
+ rules: {
|
|
|
|
|
+ password2: [
|
|
|
|
|
+ { required: true, message: "二次密码不能为空", trigger: "blur" },
|
|
|
|
|
+ {
|
|
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
|
|
+ if (value !== state.form["password"]) {
|
|
|
|
|
+ callback(new Error("两次输入的密码不一致"));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ callback();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ trigger: "blur"
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ phonenumber: [
|
|
|
|
|
+ {
|
|
|
|
|
+ pattern: /^1[3-9]\d{9}$/,
|
|
|
|
|
+ message: "请输入正确的手机号",
|
|
|
|
|
+ trigger: "blur"
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const deptList = ref([]);
|
|
|
|
|
+const roleList: Ref<OptionsRow[]> = ref([]);
|
|
|
|
|
+
|
|
|
|
|
+const getDeptList = async () => {
|
|
|
|
|
+ let res = await getSystemRoleDeptTree("2");
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ deptList.value = res.depts;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const getRoleOptions = async () => {
|
|
|
|
|
+ let res = await getSystemRoleOptionselect();
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ roleList.value = res.data;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const columns: PlusColumn[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "所属部门",
|
|
|
|
|
+ prop: "deptId",
|
|
|
|
|
+ valueType: "tree-select",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ placeholder: "请选择所属部门",
|
|
|
|
|
+ clearable: true,
|
|
|
|
|
+ props: {
|
|
|
|
|
+ label: "label",
|
|
|
|
|
+ value: "id",
|
|
|
|
|
+ children: "children"
|
|
|
|
|
+ },
|
|
|
|
|
+ data: deptList
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "登录账号",
|
|
|
|
|
+ prop: "userName",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "登录密码",
|
|
|
|
|
+ prop: "password",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true,
|
|
|
|
|
+ type: "password",
|
|
|
|
|
+ showPassword: false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "二次密码",
|
|
|
|
|
+ prop: "password2",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true,
|
|
|
|
|
+ type: "password",
|
|
|
|
|
+ showPassword: false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "用户姓名",
|
|
|
|
|
+ prop: "nickName",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "手机号",
|
|
|
|
|
+ prop: "phonenumber",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "角色",
|
|
|
|
|
+ prop: "roleId",
|
|
|
|
|
+ valueType: "select",
|
|
|
|
|
+ options: computed(() => roleList.value),
|
|
|
|
|
+ optionsMap: {
|
|
|
|
|
+ value: "roleId",
|
|
|
|
|
+ label: "roleName"
|
|
|
|
|
+ },
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ placeholder: "请选择角色",
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "岗位",
|
|
|
|
|
+ prop: "postName",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "状态",
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ valueType: "select",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ placeholder: "请选择状态",
|
|
|
|
|
+ clearable: true,
|
|
|
|
|
+ options: [
|
|
|
|
|
+ { label: "启用", value: "0" },
|
|
|
|
|
+ { label: "停用", value: "1" }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+];
|
|
|
|
|
+
|
|
|
|
|
+// 创建
|
|
|
|
|
+const handleCreate = (): void => {
|
|
|
|
|
+ form.value = {};
|
|
|
|
|
+ state.isCreate = true;
|
|
|
|
|
+ state.dialogVisible = true;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const handleSubmit = async (values: FieldValues) => {
|
|
|
|
|
+ console.log(values, "Submit");
|
|
|
|
|
+ confirmLoading.value = true;
|
|
|
|
|
+ if (state.isCreate) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let params = form.value;
|
|
|
|
|
+ let res = await addUser(params);
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success("新增成功");
|
|
|
|
|
+ confirmLoading.value = false;
|
|
|
|
|
+ dialogVisible.value = false;
|
|
|
|
|
+ refresh();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ confirmLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 编辑
|
|
|
|
|
+ try {
|
|
|
|
|
+ let params = form.value;
|
|
|
|
|
+ let res = await editUser(params);
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success("修改成功");
|
|
|
|
|
+ confirmLoading.value = false;
|
|
|
|
|
+ dialogVisible.value = false;
|
|
|
|
|
+ refresh();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ confirmLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const handleClose = () => {
|
|
|
|
|
+ console.log(dialogForm.value.formInstance);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+buttons.value = [
|
|
|
|
|
+ {
|
|
|
|
|
+ // 修改
|
|
|
|
|
+ text: "修改",
|
|
|
|
|
+ code: "edit",
|
|
|
|
|
+ // props v0.1.16 版本新增函数类型
|
|
|
|
|
+ props: {
|
|
|
|
|
+ type: "primary"
|
|
|
|
|
+ },
|
|
|
|
|
+ onClick(params) {
|
|
|
|
|
+ getUserInfoById(params.row.userId).then(res => {
|
|
|
|
|
+ form.value = res.data;
|
|
|
|
|
+ form.value.password2 = res.data.password;
|
|
|
|
|
+ state.isCreate = false;
|
|
|
|
|
+ state.dialogVisible = true;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ // 删除
|
|
|
|
|
+ text: "删除",
|
|
|
|
|
+ code: "delete",
|
|
|
|
|
+ // props v0.1.16 版本新增计算属性支持
|
|
|
|
|
+ props: computed(() => ({ type: "danger" })),
|
|
|
|
|
+ confirm: {
|
|
|
|
|
+ options: {
|
|
|
|
|
+ draggable: true,
|
|
|
|
|
+ message: "确定删除此数据吗?"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ onConfirm: async params => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await deleteUser(params.row.userId);
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success("删除成功");
|
|
|
|
|
+ refresh();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ ElMessage.error("删除失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+];
|
|
|
|
|
+
|
|
|
|
|
+const { form, confirmLoading, rules, dialogVisible } = toRefs(state);
|
|
|
|
|
+</script>
|