zhangwei
2025-08-20 115769e9ad3ddc64e21ad7285450c4c563c745ed
用户管理页面
13个文件已修改
1个文件已删除
686 ■■■■■ 已修改文件
src/api/system.ts 101 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/types.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.html 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/utils.ts 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.ts 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/types.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/auth.ts 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/form/index.vue 129 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/index.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/utils/hook.tsx 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/utils/rule.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/utils/types.ts 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system.ts
@@ -1,92 +1,41 @@
import { http } from "@/utils/http";
import { baseUrlApi } from "./util";
type Result = {
  success: boolean;
  data?: Array<any>;
};
type ResultTable = {
  success: boolean;
  data?: {
    /** 列表数据 */
    list: Array<any>;
    /** 总条目数 */
    total?: number;
    /** 每页显示条目个数 */
    pageSize?: number;
    /** 当前页数 */
    currentPage?: number;
  };
};
import type { Result } from "@/api/types";
/** 获取账户列表 */
export const getUserList = () => {
  return http.request<ResultTable>(
    "get",
    baseUrlApi("/api/customer/custormerUsersList")
  );
};
/** 系统管理-用户管理-获取所有角色列表 */
export const getAllRoleList = () => {
  return http.request<Result>(
    "get",
    baseUrlApi("/api/customer/custormerUsersList")
  );
};
/** 系统管理-用户管理-根据userId,获取对应角色id列表(userId:用户id) */
export const getRoleIds = (data?: object) => {
  return http.request<Result>("post", "/list-role-ids", { data });
/**新建员工数据 */
export const creatCustormerUsers = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/customer/creatCustormerUsers"),
    {
      data
    }
  );
};
/** 获取系统管理-角色管理列表 */
export const getRoleList = (data?: object) => {
  return http.request<ResultTable>("post", "/role", { data });
/** 修改管理员*/
export const changeManager = data => {
  return http.request<Result>(
    "get",
    baseUrlApi(`/api/customer/changeManager/${data.custormerUserId}`)
  );
};
/** 获取系统管理-菜单管理列表 */
export const getMenuList = (data?: object) => {
  return http.request<Result>("post", "/menu", { data });
};
/** 获取系统管理-部门管理列表 */
export const getDeptList = (data?: object) => {
  return http.request<Result>("post", "/dept", { data });
};
/** 获取系统监控-在线用户列表 */
export const getOnlineLogsList = (data?: object) => {
  return http.request<ResultTable>("post", "/online-logs", { data });
};
/** 获取系统监控-登录日志列表 */
export const getLoginLogsList = (data?: object) => {
  return http.request<ResultTable>("post", "/login-logs", { data });
};
/** 获取系统监控-操作日志列表 */
export const getOperationLogsList = (data?: object) => {
  return http.request<ResultTable>("post", "/operation-logs", { data });
};
/** 获取系统监控-系统日志列表 */
export const getSystemLogsList = (data?: object) => {
  return http.request<ResultTable>("post", "/system-logs", { data });
};
/** 获取系统监控-系统日志-根据 id 查日志详情 */
export const getSystemLogsDetail = (data?: object) => {
  return http.request<Result>("post", "/system-logs-detail", { data });
};
/** 获取角色管理-权限-菜单权限 */
export const getRoleMenu = (data?: object) => {
  return http.request<Result>("post", "/role-menu", { data });
};
/** 获取角色管理-权限-菜单权限-根据角色 id 查对应菜单 */
export const getRoleMenuIds = (data?: object) => {
  return http.request<Result>("post", "/role-menu-ids", { data });
/**更改员工信息 */
export const updataCustormerUsers = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/customer/updataCustormerUsers"),
    {
      data
    }
  );
};
src/api/types.ts
@@ -85,6 +85,7 @@
  refreshToken: string | null;
  exRoles: any | null; // exRoles为null,具体类型可根据实际业务场景细化
  code: string;
  isManager: boolean;
  customerExs: CustomerEx[];
  expires: string;
  roles: [];
src/router/index.html
File was deleted
src/router/utils.ts
@@ -27,7 +27,9 @@
// https://cn.vitejs.dev/guide/features.html#glob-import
const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}");
const quanxianList = ["/item"];
const managerList = ["/user"];
const userInfo = storageLocal().getItem<DataInfo<number>>(userKey);
// 动态路由
import { getAsyncRoutes } from "@/api/routes";
@@ -57,9 +59,11 @@
/** 过滤meta中showLink为false的菜单 */
function filterTree(data: RouteComponent[]) {
  const hasFlsh = useUserStoreHook().nowRole.hasFlsh;
  const isManager = useUserStoreHook().isManager;
  const newTree = cloneDeep(data).filter(
    (v: { meta: { showLink: boolean } }) => {
    (v: { path: string; meta: { showLink: boolean } }) => {
      quanxianList.includes(v.path) ? (v.meta.showLink = hasFlsh) : null;
      managerList.includes(v.path) ? (v.meta.showLink = isManager) : null;
      return v.meta?.showLink !== false;
    }
  );
src/store/modules/user.ts
@@ -54,7 +54,9 @@
    nowRole: storageLocal().getItem<nowRoleType>("nowRole") ?? {},
    rolesList: storageLocal().getItem<RoleItem[]>("rolesList") ?? [],
    // 页面级别权限
    roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? []
    roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [],
    isManager:
      storageLocal().getItem<DataInfo<number>>(userKey)?.isManager ?? false
  }),
  actions: {
    /** 存储头像 */
@@ -70,7 +72,7 @@
      this.nickname = nickname;
    },
    /** 存储用户角色 */
    SET_EXROLES(exRoles: Array<string>) {
    SET_EXROLES(exRoles: RoleItem[]) {
      this.exRoles = exRoles;
    },
    /** 存储角色 */
@@ -100,6 +102,9 @@
    // 设置企业资料
    SET_ENTERPRISEINFO(enterpriseInfo: CusExtendDto) {
      this.enterpriseInfo = enterpriseInfo;
    },
    SET_ISMANAGER(isManager: boolean) {
      this.isManager = isManager;
    },
    /** 登入 */
    async loginByUsername(obj) {
@@ -145,8 +150,10 @@
        const data = this.rolesList.find(item => {
          return item.code == code;
        });
        setNowRole(data);
        resolve(data);
        if (data?.code) {
          setNowRole(data);
          resolve(data);
        }
      });
    },
    /** 切换角色 */
src/store/types.ts
@@ -54,4 +54,5 @@
  enterpriseInfo: object;
  nowRole: nowRoleType;
  rolesList: RoleItem[];
  isManager: boolean;
};
src/utils/auth.ts
@@ -18,11 +18,12 @@
  /** 昵称 */
  nickname?: string;
  /** 当前登录用户的角色列表 */
  exRoles?: Array<string>;
  exRoles?: RoleItem[];
  /** 当前登录用户的角色 */
  roles?: Array<string>;
  /** 当前登录用户的按钮级别权限 */
  permissions?: Array<string>;
  isManager: boolean;
}
/**
 * AdminResult_CusExtendDto,全局返回结果
@@ -202,7 +203,8 @@
    nickname,
    exRoles,
    permissions,
    roles
    roles,
    isManager
  }) {
    useUserStoreHook().SET_AVATAR(avatar);
    useUserStoreHook().SET_USERNAME(username);
@@ -210,6 +212,7 @@
    useUserStoreHook().SET_EXROLES(exRoles);
    useUserStoreHook().SET_ROLES(roles);
    useUserStoreHook().SET_PERMS(permissions);
    useUserStoreHook().SET_ISMANAGER(isManager);
    storageLocal().setItem(userKey, {
      refreshToken,
      expires,
@@ -218,19 +221,21 @@
      nickname,
      exRoles,
      roles,
      permissions
      permissions,
      isManager
    });
  }
  if (data.exRoles && data.roles) {
    const { username, exRoles, roles } = data;
    const { username, exRoles, roles, isManager } = data;
    setUserKey({
      avatar: data?.avatar ?? "",
      username,
      nickname: data?.nickname ?? "",
      exRoles,
      roles,
      permissions: data?.permissions ?? []
      permissions: data?.permissions ?? [],
      isManager
    });
  } else {
    const avatar =
@@ -245,13 +250,16 @@
      storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [];
    const permissions =
      storageLocal().getItem<DataInfo<number>>(userKey)?.permissions ?? [];
    const isManager =
      storageLocal().getItem<DataInfo<number>>(userKey)?.isManager ?? false;
    setUserKey({
      avatar,
      username,
      nickname,
      exRoles,
      roles,
      permissions
      permissions,
      isManager
    });
  }
}
src/views/login/index.vue
@@ -195,11 +195,11 @@
                                ElRadio,
                                {
                                  key: item.customerUserID,
                                  value: item.customerUserID,
                                  label: item.enterpriseName
                                  value: item.customerUserID
                                },
                                [
                                  // 单选框文本
                                  item.enterpriseName,
                                  // 根据当前项的isManager显示标签(放在文本后面)
                                  item.isManger
                                    ? h(
@@ -278,7 +278,7 @@
              if (obj.theLastLogo) {
                router
                  .replace({
                    name: "Index"
                    path: "/Index"
                  })
                  .then(() => {
                    message("登录成功", { type: "success" });
src/views/system/role/index.vue
@@ -114,7 +114,7 @@
          class="w-[180px]!"
        />
      </el-form-item>
      <el-form-item label="状态:" prop="status">
      <el-form-item label="是否启用:" prop="status">
        <el-select
          v-model="form.status"
          placeholder="请选择状态"
src/views/system/user/form/index.vue
@@ -9,15 +9,18 @@
  formInline: () => ({
    title: "新增",
    higherDeptOptions: [],
    parentId: 0,
    nickname: "",
    username: "",
    password: "",
    phone: "",
    email: "",
    sex: "",
    status: 1,
    remark: ""
    id: null, // ID (integer($int64), 可空)
    cusExtendId: null, // 组织机构ID (integer($int64), 可空)
    name: null, // 姓名 (string, 可空)
    nickname: null, // 昵称 (string, 可空)
    phoneNumber: null, // 电话号码 (string, 可空)
    remarks: null, // 备注 (string, 可空)
    jobTitle: null, // 职务 (string, 可空)
    avatar: null, // 头像 (string, 可空)
    isEn: true, // 是否启用 (boolean, 不可空)
    passWord: null, // 密码 (string, 可空)
    isManager: false, // 是否是管理员 全权限 (boolean, 不可空)
    signature: null // isEn:false,//是否启用 (string, 可空)
  })
});
@@ -51,110 +54,48 @@
  >
    <el-row :gutter="30">
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="用户昵称" prop="nickname">
        <el-form-item label="姓名" prop="name">
          <el-input
            v-model="newFormInline.nickname"
            v-model="newFormInline.name"
            clearable
            placeholder="请输入用户昵称"
            placeholder="请输入姓名"
          />
        </el-form-item>
      </re-col>
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="用户名称" prop="username">
        <el-form-item label="手机号" prop="phoneNumber">
          <el-input
            v-model="newFormInline.username"
            clearable
            placeholder="请输入用户名称"
          />
        </el-form-item>
      </re-col>
      <re-col
        v-if="newFormInline.title === '新增'"
        :value="12"
        :xs="24"
        :sm="24"
      >
        <el-form-item label="用户密码" prop="password">
          <el-input
            v-model="newFormInline.password"
            clearable
            placeholder="请输入用户密码"
          />
        </el-form-item>
      </re-col>
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="手机号" prop="phone">
          <el-input
            v-model="newFormInline.phone"
            v-model="newFormInline.phoneNumber"
            clearable
            placeholder="请输入手机号"
          />
        </el-form-item>
      </re-col>
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="邮箱" prop="email">
          <el-input
            v-model="newFormInline.email"
            clearable
            placeholder="请输入邮箱"
          />
        </el-form-item>
      </re-col>
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="用户性别">
          <el-select
            v-model="newFormInline.sex"
            placeholder="请选择用户性别"
            class="w-full"
            clearable
          >
            <el-option
              v-for="(item, index) in sexOptions"
              :key="index"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </re-col>
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="归属部门">
          <el-cascader
            v-model="newFormInline.parentId"
            class="w-full"
            :options="newFormInline.higherDeptOptions"
            :props="{
              value: 'id',
              label: 'name',
              emitPath: false,
              checkStrictly: true
            }"
            clearable
            filterable
            placeholder="请选择归属部门"
          >
            <template #default="{ node, data }">
              <span>{{ data.name }}</span>
              <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
            </template>
          </el-cascader>
        </el-form-item>
      </re-col>
      <re-col
        v-if="newFormInline.title === '新增'"
        :value="12"
        :xs="24"
        :sm="24"
      >
        <el-form-item label="用户状态">
        <el-form-item label="是否管理员">
          <el-switch
            v-model="newFormInline.status"
            v-model="newFormInline.isManager"
            inline-prompt
            :active-value="1"
            :inactive-value="0"
            :active-value="true"
            :inactive-value="false"
            active-text="是"
            inactive-text="否"
            :style="switchStyle"
          />
        </el-form-item>
      </re-col>
      <re-col :value="12" :xs="24" :sm="24">
        <el-form-item label="是否启用">
          <el-switch
            v-model="newFormInline.isEn"
            inline-prompt
            :active-value="true"
            :inactive-value="false"
            active-text="启用"
            inactive-text="停用"
            :style="switchStyle"
@@ -165,7 +106,7 @@
      <re-col>
        <el-form-item label="备注">
          <el-input
            v-model="newFormInline.remark"
            v-model="newFormInline.remarks"
            placeholder="请输入备注信息"
            type="textarea"
          />
src/views/system/user/index.vue
@@ -59,37 +59,37 @@
      @tree-select="onTreeSelect"
    /> -->
    <div class="w-full mt-2">
      <el-form
      <!-- <el-form
        ref="formRef"
        :inline="true"
        :model="form"
        class="search-form bg-bg_color w-full pl-8 pt-[12px] overflow-auto"
      >
        <el-form-item label="用户名称:" prop="username">
        <el-form-item label="姓名:" prop="name">
          <el-input
            v-model="form.username"
            placeholder="请输入用户名称"
            v-model="form.name"
            placeholder="请输入姓名"
            clearable
            class="w-[180px]!"
          />
        </el-form-item>
        <el-form-item label="手机号码:" prop="phone">
        <el-form-item label="手机号码:" prop="phoneNumber">
          <el-input
            v-model="form.phone"
            v-model="form.phoneNumber"
            placeholder="请输入手机号码"
            clearable
            class="w-[180px]!"
          />
        </el-form-item>
        <el-form-item label="状态:" prop="status">
        <el-form-item label="是否启用" prop="isEN">
          <el-select
            v-model="form.status"
            placeholder="请选择"
            v-model="form.isEN"
            placeholder="请选择状态"
            clearable
            class="w-[180px]!"
          >
            <el-option label="已开启" value="1" />
            <el-option label="已关闭" value="0" />
            <el-option label="已开启" :value="true" />
            <el-option label="已关闭" :value="false" />
          </el-select>
        </el-form-item>
        <el-form-item>
@@ -105,17 +105,11 @@
            重置
          </el-button>
        </el-form-item>
      </el-form>
      </el-form> -->
      <PureTableBar title="" :columns="columns" @refresh="onSearch">
        <template #buttons>
          <el-button
            type="primary"
            :icon="useRenderIcon(AddFill)"
            @click="openDialog()"
          >
            新增用户
          </el-button>
          <el-button type="primary" @click="openDialog()"> 新增用户 </el-button>
        </template>
        <template v-slot="{ size, dynamicColumns }">
          <div
@@ -148,7 +142,6 @@
            adaptive
            :adaptiveConfig="{ offsetBottom: 108 }"
            align-whole="center"
            table-layout="auto"
            :loading="loading"
            :size="size"
            :data="dataList"
@@ -169,10 +162,8 @@
                :size="size"
                :icon="useRenderIcon(EditPen)"
                @click="openDialog('修改', row)"
              >
                修改
              </el-button>
              <el-popconfirm
              />
              <!-- <el-popconfirm
                :title="`是否确认删除用户编号为${row.id}的这条数据`"
                @confirm="handleDelete(row)"
              >
@@ -183,12 +174,10 @@
                    type="primary"
                    :size="size"
                    :icon="useRenderIcon(Delete)"
                  >
                    删除
                  </el-button>
                  />
                </template>
              </el-popconfirm>
              <el-dropdown>
              </el-popconfirm> -->
              <!-- <el-dropdown>
                <el-button
                  class="ml-3! mt-[2px]!"
                  link
@@ -237,7 +226,7 @@
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
              </el-dropdown> -->
            </template>
          </pure-table>
        </template>
src/views/system/user/utils/hook.tsx
@@ -21,6 +21,9 @@
  getRoleIds,
  getDeptList,
  getUserList,
  creatCustormerUsers,
  changeManager,
  updataCustormerUsers,
  getAllRoleList
} from "@/api/system";
import {
@@ -28,7 +31,9 @@
  ElInput,
  ElFormItem,
  ElProgress,
  ElMessageBox
  ElMessageBox,
  Elpopover,
  ElText
} from "element-plus";
import {
  type Ref,
@@ -44,10 +49,9 @@
export function useUser(tableRef: Ref, treeRef: Ref) {
  const form = reactive({
    // 左侧部门树的id
    deptId: "",
    username: "",
    phone: "",
    status: ""
    name: "",
    phoneNumber: "",
    isEn: true
  });
  const formRef = ref();
  const ruleFormRef = ref();
@@ -68,59 +72,64 @@
    background: true
  });
  const columns: TableColumnList = [
    // {
    //   label: "勾选列", // 如果需要表格多选,此处label必须设置
    //   type: "selection",
    //   fixed: "left",
    //   reserveSelection: true // 数据刷新后保留选项
    // },
    {
      label: "勾选列", // 如果需要表格多选,此处label必须设置
      type: "selection",
      fixed: "left",
      reserveSelection: true // 数据刷新后保留选项
    },
    {
      label: "用户编号",
      prop: "id",
      width: 90
    },
    {
      label: "用户头像",
      prop: "avatar",
      cellRenderer: ({ row }) => (
        <el-image
          fit="cover"
          preview-teleported={true}
          src={row.avatar || userAvatar}
          preview-src-list={Array.of(row.avatar || userAvatar)}
          class="w-[24px] h-[24px] rounded-full align-middle"
        />
      ),
      width: 90
    },
    {
      label: "用户名称",
      label: "姓名",
      prop: "name",
      minWidth: 130
    },
    {
      label: "用户昵称",
      prop: "nickname",
      minWidth: 130
    },
    // {
    //   label: "用户头像",
    //   prop: "avatar",
    //   cellRenderer: ({ row }) => (
    //     <el-image
    //       fit="cover"
    //       preview-teleported={true}
    //       src={row.avatar || userAvatar}
    //       preview-src-list={Array.of(row.avatar || userAvatar)}
    //       class="w-[24px] h-[24px] rounded-full align-middle"
    //     />
    //   ),
    //   width: 90
    // },
    // {
    //   label: "用户昵称",
    //   prop: "nickname",
    //   minWidth: 130
    // },
    {
      label: "角色",
      prop: "isManager",
      minWidth: 90,
      cellRenderer: ({ row, props }) => (
        <el-tag
          size={props.size}
          type={row.isManager ? "danger" : null}
          effect="plain"
        >
          {row.isManager ? "管理员" : "员工"}
        </el-tag>
      cellRenderer: scope => (
        <div>
          {/* <el-tag
            size={scope.props.size}
            type={scope.row.isManager ? "danger" : null}
            effect="plain"
          >
            {scope.row.isManager ? "管理员" : "员工"}
          </el-tag> */}
          <el-switch
            size={scope.props.size === "small" ? "small" : "default"}
            loading={switchLoadMap.value[scope.index]?.loading}
            v-model={scope.row.isManager}
            active-value={true}
            inactive-value={false}
            active-text="管理员"
            inactive-text="员工"
            inline-prompt
            style={switchStyle.value}
            onChange={() => onManagerChange(scope as any)}
          />
        </div>
      )
    },
    {
      label: "部门",
      prop: "dept.name",
      minWidth: 90
    },
    {
      label: "手机号码",
@@ -130,35 +139,47 @@
        hideTextAtIndex(phoneNumber, { start: 3, end: 6 })
    },
    {
      label: "状态",
      prop: "status",
      label: "是否启用",
      prop: "isEn",
      minWidth: 90,
      cellRenderer: scope => (
        <el-switch
          size={scope.props.size === "small" ? "small" : "default"}
          loading={switchLoadMap.value[scope.index]?.loading}
          v-model={scope.row.status}
          active-value={1}
          inactive-value={0}
          active-text="已启用"
          inactive-text="已停用"
          inline-prompt
          style={switchStyle.value}
          onChange={() => onChange(scope as any)}
        />
        <el-tag
          size={scope.props.size}
          type={scope.row.isEn ? null : "danger"}
          effect="plain"
        >
          {scope.row.isEn ? "是" : "否"}
        </el-tag>
        // <el-switch
        //   size={scope.props.size === "small" ? "small" : "default"}
        //   loading={switchLoadMap.value[scope.index]?.loading}
        //   v-model={scope.row.isEn}
        //   active-value={true}
        //   inactive-value={false}
        //   active-text="已启用"
        //   inactive-text="已停用"
        //   inline-prompt
        //   style={switchStyle.value}
        //   onChange={() => onChange(scope as any)}
        // />
      )
    },
    {
      label: "创建时间",
      minWidth: 90,
      width: 160,
      prop: "createTime",
      formatter: ({ createTime }) =>
        dayjs(createTime).format("YYYY-MM-DD HH:mm:ss")
      formatter: ({ createTime }) => dayjs(createTime).format("YYYY-MM-DD")
    },
    {
      label: "备注",
      prop: "remarks",
      width: 180,
      cellRenderer: scope => <el-text truncated>{scope.row.remarks}</el-text>
    },
    {
      label: "操作",
      fixed: "right",
      width: 180,
      width: 80,
      slot: "operation"
    }
  ];
@@ -227,6 +248,42 @@
        row.status === 0 ? (row.status = 1) : (row.status = 0);
      });
  }
  function onManagerChange({ row, index }) {
    ElMessageBox.confirm(
      `确认要设置<strong style='color:var(--el-color-primary)'>${
        row.name
      }</strong>用户为<strong>${
        row.isManager === true ? "管理员" : "员工"
      }</strong>吗?`,
      "更改权限",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        dangerouslyUseHTMLString: true,
        draggable: true
      }
    )
      .then(() => {
        changeManager({ custormerUserId: row.id }).then(res => {
          if (res.code == 200) {
            message("设置成功!", {
              type: "success"
            });
          } else {
            message(res.message || "设置失败!", {
              type: "error"
            });
          }
          onSearch();
        });
      })
      .catch(() => {
        row.isManager === true
          ? (row.isManager = false)
          : (row.isManager = true);
      });
  }
  function handleUpdate(row) {
    console.log(row);
@@ -273,7 +330,7 @@
  async function onSearch() {
    loading.value = true;
    const { result } = await getUserList(toRaw(form));
    const { result } = await getUserList();
    dataList.value = result;
    // pagination.total = data.total;
    // pagination.pageSize = data.pageSize;
@@ -287,13 +344,11 @@
  const resetForm = formEl => {
    if (!formEl) return;
    formEl.resetFields();
    form.deptId = "";
    treeRef.value.onTreeReset();
    onSearch();
  };
  function onTreeSelect({ id, selected }) {
    form.deptId = selected ? id : "";
    onSearch();
  }
@@ -316,15 +371,18 @@
        formInline: {
          title,
          higherDeptOptions: formatHigherDeptOptions(higherDeptOptions.value),
          parentId: row?.dept.id ?? 0,
          id: row?.id ?? null,
          cusExtendId: row?.cusExtendId ?? dataList.value[0].cusExtendId,
          name: row?.name ?? "",
          nickname: row?.nickname ?? "",
          username: row?.username ?? "",
          password: row?.password ?? "",
          phone: row?.phone ?? "",
          email: row?.email ?? "",
          sex: row?.sex ?? "",
          status: row?.status ?? 1,
          remark: row?.remark ?? ""
          phoneNumber: row?.phoneNumber ?? "",
          remarks: row?.remarks ?? "",
          jobTitle: row?.jobTitle ?? "",
          avatar: row?.avatar ?? "",
          isEn: row?.isEn ?? true,
          passWord: row?.passWord ?? "",
          isManager: row?.isManager ?? false,
          signature: row?.signature ?? ""
        }
      },
      width: "46%",
@@ -336,10 +394,22 @@
      beforeSure: (done, { options }) => {
        const FormRef = formRef.value.getRef();
        const curData = options.props.formInline as FormItemProps;
        function chores() {
          message(`您${title}了用户名称为${curData.username}的这条数据`, {
            type: "success"
          });
        async function chores() {
          let res;
          if (title == "新增") {
            res = await creatCustormerUsers(curData);
          } else {
            res = await updataCustormerUsers(curData);
          }
          if (res.code != "200") {
            message(res.message, {
              type: "error"
            });
          } else {
            message(`${title}成功!`, {
              type: "success"
            });
          }
          done(); // 关闭弹框
          onSearch(); // 刷新表格数据
        }
@@ -384,7 +454,7 @@
  //   });
  // }
  watch();
  // watch();
  // pwdForm
  // ({ newPwd }) =>
  //   (curScore.value = isAllEmpty(newPwd) ? -1 : zxcvbn(newPwd).score)
@@ -466,7 +536,6 @@
  /** 分配角色 */
  async function handleRole(row) {
    // 选中的角色列表
    const ids = (await getRoleIds({ userId: row.id })).data ?? [];
    addDialog({
      title: `分配 ${row.username} 用户的角色`,
      props: {
@@ -497,13 +566,13 @@
    onSearch();
    // 归属部门
    const { data } = await getDeptList();
    higherDeptOptions.value = handleTree(data);
    treeData.value = handleTree(data);
    treeLoading.value = false;
    // const { data } = await getDeptList();
    // higherDeptOptions.value = handleTree(data);
    // treeData.value = handleTree(data);
    // treeLoading.value = false;
    // 角色列表
    roleOptions.value = (await getAllRoleList()).data;
    // roleOptions.value = (await getAllRoleList()).data;
  });
  return {
src/views/system/user/utils/rule.ts
@@ -4,10 +4,9 @@
/** 自定义表单规则校验 */
export const formRules = reactive(<FormRules>{
  nickname: [{ required: true, message: "用户昵称为必填项", trigger: "blur" }],
  username: [{ required: true, message: "用户名称为必填项", trigger: "blur" }],
  password: [{ required: true, message: "用户密码为必填项", trigger: "blur" }],
  phone: [
  name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
  phoneNumber: [
    { required: true, message: "请输入手机号", trigger: "blur" },
    {
      validator: (rule, value, callback) => {
        if (value === "") {
src/views/system/user/utils/types.ts
@@ -3,19 +3,17 @@
  /** 用于判断是`新增`还是`修改` */
  title: string;
  higherDeptOptions: Record<string, unknown>[];
  parentId: number;
  nickname: string;
  username: string;
  password: string;
  phone: string | number;
  email: string;
  sex: string | number;
  status: number;
  dept?: {
    id?: number;
    name?: string;
  };
  remark: string;
  cusExtendId?: number; // 组织机构ID
  name?: string; // 姓名
  nickname?: string; // 昵称
  phoneNumber?: string; // 电话号码
  remarks?: string; // 备注
  jobTitle?: string; // 职务
  avatar?: string; // 头像
  isEn: boolean; // 是否启用
  passWord?: string; // 密码
  isManager: boolean; // 是否是管理员 全权限
  signature?: string; // 可空
}
interface FormProps {
  formInline: FormItemProps;