| | |
| | | |
| | | import { http } from "@/utils/http"; |
| | | import { baseUrlApi } from "../util"; |
| | | import type { Result, CaptchaResult } from "../types"; |
| | | import type { Result, CaptchaResult, RoleData } from "../types"; |
| | | |
| | | export const register = (data?: object) => { |
| | | return http.request<Result>( |
| | |
| | | |
| | | //获取角色 |
| | | export const exRole = () => { |
| | | return http.request<Result>("get", baseUrlApi("/api/customer/exRole")); |
| | | return http.request<RoleData>("get", baseUrlApi("/api/customer/exRole")); |
| | | }; |
| | | |
| | | // 获取手机验证码 |
| | |
| | | ); |
| | | }; |
| | | |
| | | // 申请角色 |
| | | export const applyRole = params => { |
| | | return http.request<Result>( |
| | | "get", |
| | | baseUrlApi(`/api/customer/createrExRolsInformation/${params.ruleCode}`) |
| | | ); |
| | | }; |
New file |
| | |
| | | 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; |
| | | }; |
| | | }; |
| | | |
| | | /** 获取账户列表 */ |
| | | 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 getRoleList = (data?: object) => { |
| | | return http.request<ResultTable>("post", "/role", { data }); |
| | | }; |
| | | |
| | | /** 获取系统管理-菜单管理列表 */ |
| | | 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 }); |
| | | }; |
| | |
| | | result: captchaImg; |
| | | code: string | number; |
| | | }; |
| | | |
| | | export type UserResult = { |
| | | success: boolean; |
| | | data: { |
| | | /** 头像 */ |
| | | avatar: string; |
| | | /** 用户名 */ |
| | | username: string; |
| | | /** 昵称 */ |
| | | nickname: string; |
| | | /** 当前登录用户的角色 */ |
| | | roles: Array<string>; |
| | | /** 按钮级别权限 */ |
| | | permissions: Array<string>; |
| | | /** `token` */ |
| | | accessToken: string; |
| | | /** 用于调用刷新`accessToken`的接口时所需的`token` */ |
| | | refreshToken: string; |
| | | /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ |
| | | expires: Date; |
| | | }; |
| | | }; |
| | | // 企业信息项类型 |
| | | interface CustomerEx { |
| | | customerUserID: number; |
| | | enterpriseName: string; |
| | | isManger: boolean; // 注意:原数据中可能存在拼写错误(应为isManager),此处保持与原数据一致 |
| | | unifiedSocialCreditCode: string; |
| | | } |
| | | |
| | | // 整体结果类型 |
| | | export interface LoginResult { |
| | | theLastLogo: boolean; |
| | | accessToken: string | null; |
| | | refreshToken: string | null; |
| | | exRoles: any | null; // exRoles为null,具体类型可根据实际业务场景细化 |
| | | code: string; |
| | | customerExs: CustomerEx[]; |
| | | expires: string; |
| | | roles: []; |
| | | username: string; |
| | | avatar: string; |
| | | nickname: string; |
| | | permissions: []; |
| | | } |
| | | |
| | | export type LoginData = { |
| | | message: string; |
| | | success: boolean; |
| | | code: string | number; |
| | | result: LoginResult; |
| | | }; |
| | | export interface RoleItem { |
| | | id: number; |
| | | name: string; |
| | | code: string; |
| | | orderNo: number; |
| | | dataScope: number; |
| | | remark: string | null; // 可能为null或字符串 |
| | | status: number; |
| | | } |
| | | // 角色列表 |
| | | export type RoleData = { |
| | | message: string; |
| | | success: boolean; |
| | | code: string | number; |
| | | result: RoleItem[]; |
| | | }; |
| | |
| | | import { http } from "@/utils/http"; |
| | | import { baseUrlApi } from "./util"; |
| | | |
| | | export type UserResult = { |
| | | success: boolean; |
| | | data: { |
| | | /** 头像 */ |
| | | avatar: string; |
| | | /** 用户名 */ |
| | | username: string; |
| | | /** 昵称 */ |
| | | nickname: string; |
| | | /** 当前登录用户的角色 */ |
| | | roles: Array<string>; |
| | | /** 按钮级别权限 */ |
| | | permissions: Array<string>; |
| | | /** `token` */ |
| | | accessToken: string; |
| | | /** 用于调用刷新`accessToken`的接口时所需的`token` */ |
| | | refreshToken: string; |
| | | /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ |
| | | expires: Date; |
| | | }; |
| | | }; |
| | | |
| | | export type LoginResult = { |
| | | success: boolean; |
| | | code: string | number; |
| | | result: { |
| | | /** 头像 */ |
| | | avatar: string; |
| | | /** 用户名 */ |
| | | username: string; |
| | | /** 昵称 */ |
| | | nickname: string; |
| | | /** 当前登录用户的角色 */ |
| | | exRoles: Array<string>; |
| | | /** 按钮级别权限 */ |
| | | permissions: Array<string>; |
| | | /** `token` */ |
| | | accessToken: string; |
| | | /** 用于调用刷新`accessToken`的接口时所需的`token` */ |
| | | refreshToken: string; |
| | | /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ |
| | | expires: Date; |
| | | }; |
| | | }; |
| | | |
| | | export type RefreshTokenResult = { |
| | | success: boolean; |
| | | data: { |
| | | /** `token` */ |
| | | accessToken: string; |
| | | /** 用于调用刷新`accessToken`的接口时所需的`token` */ |
| | | refreshToken: string; |
| | | /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ |
| | | expires: Date; |
| | | }; |
| | | }; |
| | | import type { LoginData } from "./types"; |
| | | |
| | | /** 登录 */ |
| | | export const getLogin = (data?: object) => { |
| | | return http.request<LoginResult>("post", baseUrlApi("/api/auth/loginPhone"), { |
| | | return http.request<LoginData>("post", baseUrlApi("/api/auth/loginPhone"), { |
| | | data |
| | | }); |
| | | // return http.request<UserResult>("post", "/login", { data }); |
| | | }; |
| | | |
| | | /** 刷新`token` */ |
| | | export const refreshTokenApi = (data?: object) => { |
| | | return http.request<RefreshTokenResult>("post", "/refresh-token1", { data }); |
| | | }; |
| | | // /** 刷新`token` */ |
| | | // export const refreshTokenApi = (data?: object) => { |
| | | // return http.request<RefreshTokenResult>("post", "/refresh-token1", { data }); |
| | | // }; |
| | | |
| | | // 切换角色 |
| | | export const getChangeLogoInExRule = params => { |
| | | return http.request<LoginResult>( |
| | | return http.request<LoginData>( |
| | | "post", |
| | | baseUrlApi(`/api/auth/changeLogoInExRule/${params.ruleCode}`) |
| | | ); |
| | |
| | | import ExitFullscreen from "~icons/ri/fullscreen-exit-fill"; |
| | | import Fullscreen from "~icons/ri/fullscreen-fill"; |
| | | import { unref } from "vue"; |
| | | import { message } from "@/utils/message"; |
| | | |
| | | const errorInfo = |
| | | "The current routing configuration is incorrect, please check the configuration"; |
| | |
| | | // 获取后端路由 |
| | | initRouter(); |
| | | onFresh(); |
| | | } else { |
| | | message(res?.message, { type: "warning" }); |
| | | } |
| | | }); |
| | | }; |
| | |
| | | ] |
| | | }, |
| | | { |
| | | path: "/user", |
| | | meta: { |
| | | title: "用户管理", |
| | | icon: "mdi:chart-timeline" |
| | | }, |
| | | children: [ |
| | | { |
| | | // path随便写,但前面必须有个 `/` |
| | | path: "/user", |
| | | // component对应的值前不需要加 / 值对应的是实际业务 `.vue` 或 `.tsx` 代码路径 |
| | | component: () => import("@/views/system/user/index.vue"), |
| | | name: "user", |
| | | meta: { |
| | | title: "用户管理" |
| | | // showLink:false |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: "/aboutItem", |
| | | meta: { |
| | | title: "关注项目", |
| | |
| | | storageLocal |
| | | } from "../utils"; |
| | | import { |
| | | type LoginResult, |
| | | type RefreshTokenResult, |
| | | getLogin, |
| | | refreshTokenApi, |
| | | // refreshTokenApi, |
| | | getChangeLogoInExRule |
| | | } from "@/api/user"; |
| | | import type { LoginData, RoleData, RoleItem } from "@/api/types"; |
| | | import { useMultiTagsStoreHook } from "./multiTags"; |
| | | import { |
| | | type DataInfo, |
| | |
| | | import { exRole } from "@/api/register/index"; |
| | | import { cusExtendInfo } from "@/api/mine"; |
| | | import type { nowRoleType } from "@/store/types"; |
| | | import { cloneDeep } from "@pureadmin/utils"; |
| | | import { message } from "@/utils/message"; |
| | | |
| | | export const useUserStore = defineStore("pure-user", { |
| | | state: (): userType => ({ |
| | |
| | | enterpriseInfo: |
| | | storageLocal().getItem<CusExtendDto>("enterpriseInfo") ?? {}, |
| | | nowRole: storageLocal().getItem<nowRoleType>("nowRole") ?? {}, |
| | | rolesList: storageLocal().getItem<DataInfo<number>>("rolesList") ?? [], |
| | | rolesList: storageLocal().getItem<RoleItem[]>("rolesList") ?? [], |
| | | // 页面级别权限 |
| | | roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [] |
| | | }), |
| | |
| | | this.nowRole = nowRole; |
| | | }, |
| | | /** 存储角色列表 */ |
| | | SET_EXROLES_LIST(rolesList: Array<string>) { |
| | | SET_EXROLES_LIST(rolesList: RoleItem[]) { |
| | | this.rolesList = rolesList; |
| | | }, |
| | | /** 存储按钮级别权限 */ |
| | |
| | | }, |
| | | /** 登入 */ |
| | | async loginByUsername(obj) { |
| | | return new Promise<LoginResult>((resolve, reject) => { |
| | | return new Promise<LoginData>((resolve, reject) => { |
| | | getLogin(obj) |
| | | .then(data => { |
| | | if (data?.code == 200) { |
| | | data.result.roles = [obj.exRuleCode]; |
| | | setToken(data.result); |
| | | this.getNowRole(obj.exRuleCode); |
| | | if (data.result.theLastLogo) { |
| | | const resObj = cloneDeep(data.result); |
| | | resObj.roles = [obj.exRuleCode]; |
| | | setToken(resObj); |
| | | this.getNowRole(obj.exRuleCode); |
| | | } |
| | | } |
| | | resolve(data); |
| | | }) |
| | |
| | | }, |
| | | /** 获取角色列表 */ |
| | | async getRoleList() { |
| | | return new Promise<LoginResult>((resolve, reject) => { |
| | | return new Promise<RoleData>((resolve, reject) => { |
| | | exRole() |
| | | .then(data => { |
| | | if (data?.code == 200) { |
| | |
| | | }, |
| | | /** 获取当前角色 */ |
| | | async getNowRole(code) { |
| | | return new Promise<LoginResult>((resolve, reject) => { |
| | | return new Promise(resolve => { |
| | | const data = this.rolesList.find(item => { |
| | | return item.code == code; |
| | | }); |
| | |
| | | }, |
| | | /** 切换角色 */ |
| | | async changeLogoInExRule(obj) { |
| | | return new Promise<LoginResult>((resolve, reject) => { |
| | | return new Promise<LoginData>((resolve, reject) => { |
| | | getChangeLogoInExRule(obj) |
| | | .then(async data => { |
| | | if (data?.code == 200) { |
| | | data.result.roles = [obj.ruleCode]; |
| | | setToken(data.result); |
| | | const resObj = cloneDeep(data.result); |
| | | resObj.roles = [obj.ruleCode]; |
| | | setToken(resObj); |
| | | this.getNowRole(obj.ruleCode); |
| | | await this.getCusExtendInfo(); |
| | | resolve(data); |
| | | } else { |
| | | message(data?.message, { type: "warning" }); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | |
| | | .then(data => { |
| | | setEnterpriseInfo(data.result); |
| | | if (data?.code == 200) { |
| | | data.result.username = data.result?.enterpriseName; |
| | | resolve(data); |
| | | const resData = cloneDeep(data); |
| | | resData.result.username = data.result?.enterpriseName; |
| | | resolve(resData); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | |
| | | router.push("/index"); |
| | | }, |
| | | /** 刷新`token` */ |
| | | async handRefreshToken(data) { |
| | | return new Promise<RefreshTokenResult>((resolve, reject) => { |
| | | refreshTokenApi(data) |
| | | .then(data => { |
| | | if (data) { |
| | | setToken(data.data); |
| | | resolve(data); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | reject(error); |
| | | }); |
| | | }); |
| | | async handRefreshToken() { |
| | | // return new Promise<RefreshTokenResult>((resolve, reject) => { |
| | | // refreshTokenApi(data) |
| | | // .then(data => { |
| | | // if (data) { |
| | | // setToken(data.data); |
| | | // resolve(data); |
| | | // } |
| | | // }) |
| | | // .catch(error => { |
| | | // reject(error); |
| | | // }); |
| | | // }); |
| | | } |
| | | } |
| | | }); |
| | |
| | | import type { RouteRecordName } from "vue-router"; |
| | | |
| | | import type { RoleItem } from "@/api/types"; |
| | | export type cacheType = { |
| | | mode: string; |
| | | name?: RouteRecordName; |
| | |
| | | }; |
| | | |
| | | export type nowRoleType = { |
| | | code: string; |
| | | name: string; |
| | | hasFlsh: boolean; |
| | | code?: string; |
| | | name?: string; |
| | | hasFlsh?: boolean; |
| | | }; |
| | | |
| | | export type userType = { |
| | | avatar?: string; |
| | | username?: string; |
| | | nickname?: string; |
| | | exRoles?: Array<string>; |
| | | exRoles?: RoleItem[]; |
| | | roles?: Array<string>; |
| | | permissions?: Array<string>; |
| | | isRemembered?: boolean; |
| | | loginDay?: number; |
| | | enterpriseInfo: object; |
| | | nowRole: nowRoleType; |
| | | rolesList: object; |
| | | rolesList: RoleItem[]; |
| | | }; |
| | |
| | | import { useUserStoreHook } from "@/store/modules/user"; |
| | | import { storageLocal, isString, isIncludeAllChildren } from "@pureadmin/utils"; |
| | | import type { nowRoleType } from "@/store/types"; |
| | | import type { LoginResult, RoleItem } from "@/api/types"; |
| | | |
| | | export interface DataInfo<T> { |
| | | /** token */ |
| | |
| | | * 将`accessToken`、`expires`、`refreshToken`这三条信息放在key值为authorized-token的cookie里(过期自动销毁) |
| | | * 将`avatar`、`username`、`nickname`、`exRoles`、`permissions`、`refreshToken`、`expires`这七条信息放在key值为`user-info`的localStorage里(利用`multipleTabsKey`当浏览器完全关闭后自动销毁) |
| | | */ |
| | | export function setToken(data: DataInfo<Date>) { |
| | | export function setToken(data: LoginResult) { |
| | | let expires = 0; |
| | | const { accessToken, refreshToken } = data; |
| | | const { isRemembered, loginDay } = useUserStoreHook(); |
| | |
| | | storageLocal().setItem(userKey, obj); |
| | | } |
| | | |
| | | export function setRoleListInfo(data: DataInfo<string>) { |
| | | export function setRoleListInfo(data: RoleItem[]) { |
| | | useUserStoreHook().SET_EXROLES_LIST(data); |
| | | storageLocal().setItem("rolesList", data); |
| | | } |
| | |
| | | const obj = list.find(item => { |
| | | return item.code == data.code; |
| | | }); |
| | | data = { ...obj, ...data }; |
| | | data = Object.assign(obj, data); |
| | | } |
| | | useUserStoreHook().SET_ROLES([data.name]); |
| | | useUserStoreHook().SET_NOW_ROLE(data); |
| | |
| | | <my-footer /> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | <script lang="tsx" setup> |
| | | import { onMounted, ref, computed, reactive } from "vue"; |
| | | import MyFooter from "./component/myFooter.vue"; |
| | | import MyHeader from "./component/myHeader.vue"; |
| | | import { useUserStoreHook } from "@/store/modules/user"; |
| | | import { exRole } from "@/api/register/index"; |
| | | import { storageLocal, isString, isIncludeAllChildren } from "@pureadmin/utils"; |
| | | import { initRouter, getTopMenu } from "@/router/utils"; |
| | | |
| | | import { getToken } from "@/utils/auth"; |
| | | import { useRoute, useRouter } from "vue-router"; |
| | | const router = useRouter(); |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import { addDialog } from "@/components/ReDialog"; |
| | | import { applyRole } from "@/api/register/index"; |
| | | import { message } from "@/utils/message"; |
| | | import type { userType } from "@/store/types"; |
| | | import type { RoleItem } from "@/api/types"; |
| | | |
| | | const userStore = useUserStore(); |
| | | |
| | |
| | | /** 角色(如果昵称为空则显示用户名) */ |
| | | const getUseRoles = () => { |
| | | state.userInfo = storageLocal().getItem("user-info"); |
| | | state.userInfo?.exRoles.forEach(element => { |
| | | state.userInfo?.exRoles.forEach((element: RoleItem) => { |
| | | state.rolesCode.push(element.code); |
| | | }); |
| | | }; |
| | | const state = reactive({ |
| | | roleList: [], |
| | | rolesCode: [], |
| | | userInfo: {}, |
| | | userInfo: {} as userType, |
| | | accessToken: "" |
| | | }); |
| | | onMounted(() => { |
| | |
| | | }; |
| | | // 申请 |
| | | const toApply = item => { |
| | | router.push({ name: "RegisterNav", query: { code: item.code } }); |
| | | addDialog({ |
| | | width: "20%", |
| | | title: "确认信息", |
| | | contentRenderer: () => <p>是否申请为{item.name}!</p>, // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx") |
| | | closeCallBack: ({ options, args }) => { |
| | | if (args?.command === "cancel") { |
| | | // 您点击了取消按钮 |
| | | } else if (args?.command === "sure") { |
| | | applyRole({ ruleCode: item.code }).then(res => { |
| | | if (res.code == 200) { |
| | | message("申请成功!", { type: "success" }); |
| | | } else { |
| | | message(res?.message || "申请失败!", { type: "error" }); |
| | | } |
| | | }); |
| | | } else { |
| | | } |
| | | } |
| | | }); |
| | | // router.push({ name: "RegisterNav", query: { code: item.code } }); |
| | | }; |
| | | // 去首页 |
| | | const toWelcome = async item => { |
| | | if (useUserStoreHook().nowRole.code !== item.code) { |
| | | await useUserStoreHook().changeLogoInExRule({ |
| | | ruleCode: item.code |
| | | // 获取后端路由 |
| | | initRouter().then(() => { |
| | | useUserStoreHook().changeLogoInExRule({ |
| | | ruleCode: item.code |
| | | }); |
| | | }); |
| | | } |
| | | router.push({ name: "Mine" }); |
| | | router.push({ name: "Welcome" }); |
| | | }; |
| | | // 去登录 |
| | | const toLogin = item => { |
| | | router.push({ name: "Login", query: item }); |
| | | router.push({ name: "Login" }); |
| | | }; |
| | | </script> |
| | | |
| | |
| | | reactive, |
| | | computed, |
| | | ref, |
| | | Ref, |
| | | h, |
| | | onMounted, |
| | | defineAsyncComponent, |
| | | onUnmounted, |
| | | watch |
| | | } from "vue"; |
| | | import { debounce } from "@pureadmin/utils"; |
| | | import { debounce, storageLocal } from "@pureadmin/utils"; |
| | | import { useNav } from "@/layout/hooks/useNav"; |
| | | import { useEventListener } from "@vueuse/core"; |
| | | import type { FormInstance } from "element-plus"; |
| | |
| | | myEnterpriseList: [], |
| | | nowRole: {} |
| | | }); |
| | | let secondCode = ""; |
| | | let secondId: Ref<string | number | boolean> = ref(""); |
| | | // 验证码过期计时器 |
| | | let timer: any = null; |
| | | let phonetimer: any = null; |
| | |
| | | // 页面初始化 |
| | | onMounted(async () => { |
| | | getCaptcha(); |
| | | exRole().then(res => { |
| | | state.roleList = res.result; |
| | | const role = route.query; |
| | | if (role.code) { |
| | | state.nowRole = state.roleList.find(item => { |
| | | return item.code == role.code; |
| | | }); |
| | | } else { |
| | | state.nowRole = state.roleList[0]; |
| | | } |
| | | state.ruleForm.exRoleCode = state.nowRole.code; |
| | | }); |
| | | // 注册验证码过期计时器 |
| | | timer = setInterval(() => { |
| | | if (state.expirySeconds > 0) state.expirySeconds -= 1; |
| | |
| | | width: "30%", |
| | | title: "选择登录公司", |
| | | contentRenderer: () => |
| | | h(ElForm, { |
| | | ref: ruleFormRef, |
| | | model: state.ruleForm, |
| | | rules: loginRules, |
| | | size: 'large' |
| | | }, [ |
| | | h(Motion, { delay: 150 }, [ |
| | | h(ElFormItem, { |
| | | prop: 'exRoleCode', |
| | | label: '主体角色' // 可添加表单项标签 |
| | | }, [ |
| | | // 单选框组 - 父容器添加样式控制 |
| | | h(ElRadioGroup, { |
| | | modelValue: state.ruleForm.exRoleCode, |
| | | 'onUpdate:modelValue': (val) => { |
| | | state.ruleForm.exRoleCode = val |
| | | }, |
| | | style: { |
| | | display: 'flex', |
| | | flexDirection: 'column', |
| | | gap: '8px' // 单选框之间的间距 |
| | | } |
| | | }, [ |
| | | // 循环渲染单选框 - 每个单选框单独占一行 |
| | | state.myEnterpriseList.map(item => h(ElRadio, { |
| | | key: item.id, |
| | | value: item.code, |
| | | style: { |
| | | display: 'block', // 让每个单选框分行显示 |
| | | padding: '4px 0' |
| | | } |
| | | }, item.name),) |
| | | ]), |
| | | |
| | | // 管理员标签 - 显示在单选框后面 |
| | | |
| | | ]) |
| | | ]) |
| | | ]) |
| | | // <> |
| | | // <el-form |
| | | // ref="ruleFormRef" |
| | | // model={state.ruleForm} |
| | | // rules={loginRules} |
| | | // size="large" |
| | | // > |
| | | // <Motion delay={150}> |
| | | // <el-form-item prop="exRoleCode"> |
| | | // <el-radio-group v-model={state.ruleForm.exRoleCode}> |
| | | // <el-radio |
| | | // v-for={item in state.myEnterpriseList} |
| | | // key={item.id} |
| | | // value={item.code} |
| | | // > |
| | | // {item.name} |
| | | // </el-radio> |
| | | // </el-radio-group> |
| | | // </el-form-item> |
| | | // </Motion> |
| | | // </el-form> |
| | | // </> |
| | | // h( |
| | | // ElForm, |
| | | // { |
| | | // ref: ruleFormRef, |
| | | // model: state.ruleForm, |
| | | // rules: loginRules, |
| | | // size: "large" |
| | | // }, |
| | | // [ |
| | | // h(Motion, { delay: 150 }, [ |
| | | // h(ElFormItem, { prop: "exRoleCode" }, [ |
| | | // h( |
| | | // ElRadioGroup, |
| | | // { |
| | | // modelValue: state.ruleForm.exRoleCode, |
| | | // "onUpdate:modelValue": val => { |
| | | // state.ruleForm.exRoleCode = val; |
| | | // } |
| | | // }, |
| | | // [ |
| | | // // 用map实现v-for循环 |
| | | // state.myEnterpriseList.map(item => |
| | | // h(ElRow, {}, [ |
| | | // h( |
| | | // ElRadio, |
| | | // { |
| | | // key: item.customerUserID, |
| | | // value: item.customerUserID |
| | | // }, |
| | | // item.enterpriseName |
| | | // ), |
| | | // item.isManager ? 444 : "" // 标签内容 |
| | | // ]) |
| | | // ) |
| | | // ] |
| | | // ) |
| | | // ]) |
| | | // ]) |
| | | // ] |
| | | // ), |
| | | // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx") |
| | | h( |
| | | ElForm, |
| | | { |
| | | ref: ruleFormRef, |
| | | model: state.ruleForm, |
| | | rules: loginRules, |
| | | size: "large" |
| | | }, |
| | | [ |
| | | h(Motion, { delay: 150 }, [ |
| | | h( |
| | | ElFormItem, |
| | | { |
| | | prop: "exRoleCode", |
| | | label: "" |
| | | }, |
| | | [ |
| | | // 单选框组 - 纵向排列 |
| | | h( |
| | | ElRadioGroup, |
| | | { |
| | | modelValue: secondId.value, |
| | | "onUpdate:modelValue": val => { |
| | | secondId.value = val; |
| | | } |
| | | }, |
| | | [ |
| | | // 循环渲染单选框 - 根据每项的isManager显示标签 |
| | | state.myEnterpriseList.map(item => |
| | | h( |
| | | "el-row", |
| | | { |
| | | style: { |
| | | width: "100%" |
| | | } |
| | | }, |
| | | [ |
| | | h( |
| | | "el-col", |
| | | { |
| | | span: 24 |
| | | }, |
| | | [ |
| | | h( |
| | | ElRadio, |
| | | { |
| | | key: item.customerUserID, |
| | | value: item.customerUserID, |
| | | label: item.enterpriseName |
| | | }, |
| | | [ |
| | | // 单选框文本 |
| | | // 根据当前项的isManager显示标签(放在文本后面) |
| | | item.isManger |
| | | ? h( |
| | | ElTag, |
| | | { |
| | | type: "primary", |
| | | size: "small", |
| | | style: { |
| | | marginLeft: "8px", |
| | | alignSelf: "center" |
| | | } |
| | | }, |
| | | "管理员" |
| | | ) |
| | | : null |
| | | ] |
| | | ) |
| | | ] |
| | | ) |
| | | ] |
| | | ) |
| | | ) |
| | | ] |
| | | ) |
| | | ] |
| | | ) |
| | | ]) |
| | | ] |
| | | ), |
| | | // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx") |
| | | closeCallBack: ({ options, args }) => { |
| | | // options.props 是响应式的 |
| | | // const { formInline } = options.props as FormProps; |
| | | // const text = `姓名:${formInline.user} 城市:${formInline.region}`; |
| | | if (args?.command === "cancel") { |
| | | // 您点击了取消按钮 |
| | | // active.value -= 1; |
| | | } else if (args?.command === "sure") { |
| | | let obj = { |
| | | phone: state.ruleForm.phone, |
| | | code: state.ruleForm.phoneVCode, |
| | | exRuleCode: state.ruleForm.exRoleCode |
| | | code: secondCode, |
| | | id: secondId.value |
| | | }; |
| | | useUserStoreHook() |
| | | .loginByUsername(obj) |
| | | .then(res => { |
| | | if (res?.code == 200) { |
| | | message("注册成功!", { type: "success" }); |
| | | message("登录成功!", { type: "success" }); |
| | | router.replace({ |
| | | path: "/RegisterSucess", |
| | | query: { |
| | | code: obj.exRoleCode |
| | | } |
| | | path: "/Index" |
| | | }); |
| | | } else { |
| | | message(res?.message, { type: "warning" }); |
| | |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 点击登录 |
| | | const onLogin = async (formEl: FormInstance | undefined) => { |
| | | if (!formEl) return; |
| | | await formEl.validate(valid => { |
| | |
| | | .finally(() => (disabled.value = false)); |
| | | } else { |
| | | state.myEnterpriseList = obj.customerExs; |
| | | secondCode = obj.code; |
| | | openDialog(); |
| | | } |
| | | if (res.result.exRoles.length == 0) { |
| | | disabled.value = true; |
| | | router |
| | | .replace({ |
| | | name: "RegisterNav", |
| | | query: { code: state.ruleForm.exRoleCode } |
| | | }) |
| | | .then(() => { |
| | | message("登录成功", { type: "success" }); |
| | | }) |
| | | .finally(() => (disabled.value = false)); |
| | | } else if (res.result.exRoles.length > 0) { |
| | | let data = res.result.exRoles.find(item => { |
| | | return item.code == state.ruleForm.exRoleCode; |
| | | }); |
| | | |
| | | if (!data) { |
| | | router.replace({ |
| | | name: "RegisterNav", |
| | | query: { code: state.ruleForm.exRoleCode } |
| | | }); |
| | | } else if (data?.hasFlsh) { |
| | | router.replace("index"); |
| | | } else { |
| | | router.replace("mine"); |
| | | } |
| | | } |
| | | useUserStoreHook().getCusExtendInfo(); |
| | | }); |
| | | } else { |
| | | message(res?.message || "登录失败", { type: "error" }); |
| | | } |
| | | }) |
| | | .finally(() => (loading.value = false)); |
| | | .finally(() => { |
| | | loading.value = false; |
| | | disabled.value = false; |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 发送手机验证码 |
| | | const sendValidationCode = async () => { |
| | | if (!state.ruleForm.phone) { |
| | | return message("请先输入手机号", { type: "warning" }); |
| | |
| | | <div class="wave"> |
| | | <img width="400px" :src="logo1" class="logo1" /> |
| | | </div> |
| | | <!-- <img :src="bg" class="wave" /> --> |
| | | <!-- <div class="flex-c absolute right-5 top-3"> --> |
| | | <!-- 主题 --> |
| | | <!-- <el-switch |
| | | v-model="dataTheme" |
| | | inline-prompt |
| | | :active-icon="dayIcon" |
| | | :inactive-icon="darkIcon" |
| | | @change="dataThemeChange" |
| | | /> |
| | | </div> --> |
| | | <div class="login-container"> |
| | | <div class="img"> |
| | | <!-- <component :is="toRaw(illustration)" /> --> |
| | | </div> |
| | | <div class="img" /> |
| | | <div class="login-box"> |
| | | <div class="login-form"> |
| | | <!-- <avatar class="avatar" /> --> |
| | | <Motion> |
| | | <h2 class="logintitle">{{ state.nowRole.name }}登录</h2> |
| | | <h2 class="logintitle">登录</h2> |
| | | </Motion> |
| | | |
| | | <el-form |
| | |
| | | :rules="loginRules" |
| | | size="large" |
| | | > |
| | | <!-- <Motion :delay="150"> |
| | | <el-form-item prop="exRoleCode"> |
| | | <el-radio-group v-model="state.ruleForm.exRoleCode"> |
| | | <el-radio |
| | | v-for="item in state.roleList" |
| | | :key="item.id" |
| | | :value="item.code" |
| | | >{{ item.name }}</el-radio |
| | | > |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </Motion> --> |
| | | <Motion :delay="100"> |
| | | <el-form-item |
| | | :rules="[ |
| | |
| | | </div> |
| | | </el-col> |
| | | </el-form-item> |
| | | |
| | | <!-- <el-form-item prop="password"> |
| | | <el-input |
| | | v-model="ruleForm.password" |
| | | clearable |
| | | show-password |
| | | placeholder="密码" |
| | | :prefix-icon="useRenderIcon(Lock)" |
| | | /> |
| | | </el-form-item> --> |
| | | </Motion> |
| | | <Motion :delay="150"> |
| | | <el-form-item prop="phoneVCode"> |
| | |
| | | <span |
| | | id="suffix-span-2" |
| | | ref="spanRef" |
| | | @click="sendValidationCode(state.ruleForm.phone)" |
| | | @click="sendValidationCode" |
| | | > |
| | | 获取验证码 |
| | | </span> |
| | |
| | | // 企业开户行 |
| | | bankName: null, // string,可空 |
| | | // 企业银行账号 |
| | | bankAccount: null // string,可空 |
| | | bankAccount: null, // string,可空 |
| | | bankAccountIMG: null |
| | | }, |
| | | enterpriseList: [], |
| | | type: "", |
| | |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const handlebankAccountIMG: UploadProps["onSuccess"] = ( |
| | | response, |
| | | uploadFile |
| | | ) => { |
| | | if (response.code == "200") { |
| | | // state.ruleForm.businessLicense = URL.createObjectURL(uploadFile.raw!); |
| | | state.ruleForm.bankAccountIMG = response.result; |
| | | } else { |
| | | message(response.message, { |
| | | type: "error" |
| | | }); |
| | | } |
| | | isLoading.value = false; |
| | | }; |
| | | |
| | | defineOptions({ |
| | | name: "mine" |
| | | }); |
| | |
| | | <el-descriptions |
| | | v-if="state.userInfo.enterpriseName" |
| | | class="margin-top" |
| | | title="" |
| | | title="企业资料" |
| | | :column="3" |
| | | border |
| | | > |
| | |
| | | <template #label> |
| | | <div class="cell-item">联系电话</div> |
| | | </template> |
| | | {{ userInfo.legalRepresentativePhone }} |
| | | {{ userInfo.enterprisePhone }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item> |
| | | <template #label> |
| | |
| | | <div class="cell-item">银行账号</div> |
| | | </template> |
| | | {{ userInfo.bankAccount }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item> |
| | | <template #label> |
| | | <div class="cell-item">银行收款二维码</div> |
| | | </template> |
| | | <span style="margin-right: auto" @click="showImg('bankAccountIMG')"> |
| | | <el-link type="primary" underline>查看二维码</el-link> |
| | | </span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div class="m-5"> |
| | |
| | | <img |
| | | v-if="state.ruleForm.businessLicense" |
| | | :src="state.ruleForm.businessLicense" |
| | | width="200px" |
| | | height="150px" |
| | | width="80px" |
| | | height="50px" |
| | | /> |
| | | <el-button v-else type="primary">上传</el-button> |
| | | </el-upload> |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"> |
| | | <el-form-item label="开户行" prop="bankName"> |
| | | <el-input |
| | | v-model="state.ruleForm.bankName" |
| | | placeholder="请输入" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16"> |
| | | <el-form-item label="银行账号" prop="bankAccount"> |
| | | <el-input |
| | | v-model="state.ruleForm.bankAccount" |
| | | placeholder="请输入" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24"> |
| | | <el-form-item label="开户行收款二维码" prop="bankAccountIMG"> |
| | | <el-upload |
| | | :action="`${baseUrlApi('/api/upFile/file')}`" |
| | | :show-file-list="false" |
| | | :on-success="handlebankAccountIMG" |
| | | :before-upload="beforeAvatarUpload" |
| | | :headers="state.headers" |
| | | > |
| | | <img |
| | | v-if="state.ruleForm.bankAccountIMG" |
| | | :src="state.ruleForm.bankAccountIMG" |
| | | width="85.6px" |
| | | height="5.4px" |
| | | /> |
| | | <el-button v-else type="primary">上传</el-button> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24"> |
| | | <el-form-item label="法定代表人" prop="legalRepresentativeIdCard"> |
| | |
| | | <el-form-item label="联系电话" prop="operatorPhone"> |
| | | <el-input |
| | | v-model="state.ruleForm.operatorPhone" |
| | | placeholder="请输入" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"> |
| | | <el-form-item label="开户行" prop="bankName"> |
| | | <el-input |
| | | v-model="state.ruleForm.bankName" |
| | | placeholder="请输入" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16"> |
| | | <el-form-item label="银行账号" prop="bankAccount"> |
| | | <el-input |
| | | v-model="state.ruleForm.bankAccount" |
| | | placeholder="请输入" |
| | | /> |
| | | </el-form-item> |
| | |
| | | > |
| | | </div> |
| | | <el-divider /> |
| | | <div class="formContent"> |
| | | <div v-loading="isLoading" class="formContent"> |
| | | <el-form |
| | | ref="ruleFormRef" |
| | | style="width: 95%" |
| | |
| | | <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24"> |
| | | <el-form-item label="身份证" prop="legalRepresentativeIdCard"> |
| | | <el-upload |
| | | :ref="uploadSFZ" |
| | | :action="`${baseUrlApi('/api/upFile/uploadIdCord?PageName=FRONT')}`" |
| | | :show-file-list="false" |
| | | :on-success="handleAvatarSuccessLegalRepresentative" |
| | |
| | | v-model="state.checkedAgree" |
| | | name="type" |
| | | />我已阅读并同意 |
| | | <el-link type="primary" :underline="false" |
| | | <el-link type="primary" :underline="false" @click="openAgreement" |
| | | >《非政采招标采购交易平台用户协议》</el-link |
| | | > |
| | | </el-form-item> |
| | |
| | | sumbitData, |
| | | handleAvatarSuccess, |
| | | loadNode, |
| | | handlebankAccountIMG |
| | | handlebankAccountIMG, |
| | | isLoading, |
| | | uploadSFZ, |
| | | openAgreement |
| | | } = useRegister(); |
| | | |
| | | defineOptions({ |
| | |
| | | reactive, |
| | | computed, |
| | | ref, |
| | | h, |
| | | onMounted, |
| | | defineAsyncComponent, |
| | | onUnmounted, |
| | |
| | | } from "@/api/register/index"; |
| | | import { cloneDeep } from "@pureadmin/utils"; |
| | | import { changeCusExtend } from "@/api/mine"; |
| | | |
| | | import agreement from "../component/agreement.vue"; |
| | | const route = useRoute(); |
| | | export function useRegister() { |
| | | const isLoading = ref(false); |
| | |
| | | isShowPassword: false, |
| | | ruleForm: { |
| | | id: null, // 主键Id,可为空 |
| | | enterpriseType: "", // 企业类型,不可空,最小长度1 |
| | | enterpriseType: [], // 企业类型,不可空,最小长度1 |
| | | exRoleCode: "", // 主体角色代码,不可空,最小长度1 |
| | | transactionCode: "", // 交易主体代码(同角色代码exRoleCode,不可空,最小长度1) |
| | | businessLicense: "", // 营业执照文件路径,不可空,最小长度1 |
| | |
| | | |
| | | // 验证码区域文字说明 |
| | | const spanRef = ref(); |
| | | |
| | | const uploadSFZ = ref(); |
| | | async function sendValidationCode() { |
| | | if (!state.ruleForm.operatorPhone) { |
| | | return message("请先输入业务经办人联系电话", { type: "warning" }); |
| | |
| | | async function sumbitData(formEl: FormInstance | undefined) { |
| | | if (!formEl) return; |
| | | await formEl.validate((valid, fields) => { |
| | | router.replace({ |
| | | path: "/RegisterSucess", |
| | | query: { |
| | | code: state.ruleForm.exRoleCode |
| | | } |
| | | }); |
| | | if (valid && state.checkedAgree) { |
| | | addDialog({ |
| | | width: "20%", |
| | | title: "确认信息", |
| | | contentRenderer: () => ( |
| | | <p> |
| | | 请您认真核对填报的资料是否正确,如因填报错误影响后续投标等操作,平台不承担任何责任,所有后果需要自行承担,请您谨慎填写! |
| | | </p> |
| | | ), // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx") |
| | | closeCallBack: ({ options, args }) => { |
| | | // options.props 是响应式的 |
| | | // const { formInline } = options.props as FormProps; |
| | | // const text = `姓名:${formInline.user} 城市:${formInline.region}`; |
| | | if (args?.command === "cancel") { |
| | | // 您点击了取消按钮 |
| | | // active.value -= 1; |
| | | } else if (args?.command === "sure") { |
| | | state.ruleForm.account = state.ruleForm.operatorPhone; |
| | | const obj = cloneDeep(state.ruleForm); |
| | | obj.enterpriseType = state.ruleForm.enterpriseType.join(","); |
| | | register(obj).then(res => { |
| | | if (res?.code == 200) { |
| | | message("注册成功!", { type: "success" }); |
| | | router.replace({ |
| | | path: "/RegisterSucess", |
| | | query: { |
| | | code: obj.exRoleCode |
| | | } |
| | | }); |
| | | } else { |
| | | message(res?.message, { type: "warning" }); |
| | | } |
| | | }); |
| | | } else { |
| | | if (valid) { |
| | | if (state.checkedAgree) { |
| | | addDialog({ |
| | | width: "20%", |
| | | title: "确认信息", |
| | | contentRenderer: () => ( |
| | | <p> |
| | | 请您认真核对填报的资料是否正确,如因填报错误影响后续投标等操作,平台不承担任何责任,所有后果需要自行承担,请您谨慎填写! |
| | | </p> |
| | | ), // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx") |
| | | closeCallBack: ({ options, args }) => { |
| | | if (args?.command === "cancel") { |
| | | // 您点击了取消按钮 |
| | | } else if (args?.command === "sure") { |
| | | state.ruleForm.account = state.ruleForm.operatorPhone; |
| | | const obj = cloneDeep(state.ruleForm); |
| | | obj.enterpriseType = state.ruleForm.enterpriseType.join(","); |
| | | register(obj).then(res => { |
| | | if (res?.code == 200) { |
| | | message("注册成功!", { type: "success" }); |
| | | router.replace({ |
| | | path: "/RegisterSucess", |
| | | query: { |
| | | code: obj.exRoleCode |
| | | } |
| | | }); |
| | | } else { |
| | | message(res?.message, { type: "warning" }); |
| | | } |
| | | }); |
| | | } else { |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } else { |
| | | message("请勾选用户协议", { type: "warning" }); |
| | | } |
| | | } else { |
| | | const fail = []; |
| | | for (const key in fields) { |
| | | fail.push(fields[key][0].message); |
| | | } |
| | | message(fail[0], { |
| | | type: "warning" |
| | | }); |
| | | return; |
| | | } else message("请勾选用户协议", { type: "warning" }); |
| | | } |
| | | }); |
| | | } |
| | | function handleAvatarSuccess( |
| | |
| | | if (response.code == "200") { |
| | | // state.ruleForm.businessLicense = URL.createObjectURL(uploadFile.raw!); |
| | | const res = response.result; |
| | | // if (res.info.Name !== state.ruleForm.enterpriseName) { |
| | | // message("请上传法定代表人身份证!", { type: "error" }); |
| | | // } else { |
| | | state.ruleForm.legalRepresentativeIdCard = res.url; // 法定代表人身份证文件路径 |
| | | state.ruleForm.legalRepresentativeIdNumber = res.info.IdNum; // 法定代表人身份证号码 |
| | | // } |
| | | } else { |
| | | message(response.message, { |
| | | type: "error" |
| | |
| | | return resolve([]); |
| | | } |
| | | } |
| | | function openAgreement() { |
| | | addDialog({ |
| | | width: "40%", |
| | | title: "确认信息", |
| | | contentRenderer: () => h(agreement), // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx") |
| | | closeCallBack: ({ options, args }) => { |
| | | if (args?.command === "cancel") { |
| | | // 您点击了取消按钮 |
| | | } else if (args?.command === "sure") { |
| | | } else { |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | return { |
| | | state, |
| | | resetForm, |
| | |
| | | getCaptcha, |
| | | ruleFormRef, |
| | | spanRef, |
| | | uploadSFZ, |
| | | isLoading, |
| | | beforeAvatarUpload, |
| | | handleAvatarSuccessOperator, |
| | | handleAvatarSuccessLegalRepresentative, |
| | | sumbitData, |
| | | handleAvatarSuccess, |
| | | loadNode, |
| | | handlebankAccountIMG |
| | | handlebankAccountIMG, |
| | | openAgreement |
| | | }; |
| | | } |
| | |
| | | /** 主键Id */ |
| | | id?: number | null; |
| | | /** 企业类型(不可空) */ |
| | | enterpriseType: string; |
| | | enterpriseType: []; |
| | | /** 主体角色代码(不可空,原字段TransactionCode) */ |
| | | exRoleCode: string; |
| | | /** 交易主体代码(同角色代码,不可空) */ |
| | |
| | | /** 电话号码校验码(不可空) */ |
| | | phoneVCode: string; |
| | | bankAccountIMG: string; |
| | | account?: string; |
| | | } |
| | | interface RoleInfo { |
| | | /** 角色编码 */ |
| | |
| | | onTreeSelect, |
| | | handleUpdate, |
| | | handleDelete, |
| | | handleUpload, |
| | | handleReset, |
| | | handleRole, |
| | | handleSizeChange, |
| | |
| | | |
| | | <template> |
| | | <div :class="['flex', 'justify-between', deviceDetection() && 'flex-wrap']"> |
| | | <tree |
| | | <!-- <tree |
| | | ref="treeRef" |
| | | :class="['mr-2', deviceDetection() ? 'w-full' : 'min-w-[200px]']" |
| | | :treeData="treeData" |
| | | :treeLoading="treeLoading" |
| | | @tree-select="onTreeSelect" |
| | | /> |
| | | <div |
| | | :class="[deviceDetection() ? ['w-full', 'mt-2'] : 'w-[calc(100%-200px)]']" |
| | | > |
| | | /> --> |
| | | <div class="w-full mt-2"> |
| | | <el-form |
| | | ref="formRef" |
| | | :inline="true" |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <PureTableBar |
| | | title="用户管理(仅演示,操作后不生效)" |
| | | :columns="columns" |
| | | @refresh="onSearch" |
| | | > |
| | | <PureTableBar title="" :columns="columns" @refresh="onSearch"> |
| | | <template #buttons> |
| | | <el-button |
| | | type="primary" |
| | |
| | | :size="size" |
| | | :data="dataList" |
| | | :columns="dynamicColumns" |
| | | :pagination="{ ...pagination, size }" |
| | | :header-cell-style="{ |
| | | background: 'var(--el-fill-color-light)', |
| | | color: 'var(--el-text-color-primary)' |
| | |
| | | import dayjs from "dayjs"; |
| | | import roleForm from "../form/role.vue"; |
| | | import editForm from "../form/index.vue"; |
| | | import { zxcvbn } from "@zxcvbn-ts/core"; |
| | | // import { zxcvbn } from "@zxcvbn-ts/core"; |
| | | import { handleTree } from "@/utils/tree"; |
| | | import { message } from "@/utils/message"; |
| | | import userAvatar from "@/assets/user.jpg"; |
| | | import { usePublicHooks } from "../../hooks"; |
| | | import { addDialog } from "@/components/ReDialog"; |
| | | import type { PaginationProps } from "@pureadmin/table"; |
| | | import ReCropperPreview from "@/components/ReCropperPreview"; |
| | | // import ReCropperPreview from "@/components/ReCropperPreview"; |
| | | import type { FormItemProps, RoleFormItemProps } from "../utils/types"; |
| | | import { |
| | | getKeyList, |
| | |
| | | }, |
| | | { |
| | | label: "用户名称", |
| | | prop: "username", |
| | | prop: "name", |
| | | minWidth: 130 |
| | | }, |
| | | { |
| | |
| | | minWidth: 130 |
| | | }, |
| | | { |
| | | label: "性别", |
| | | prop: "sex", |
| | | label: "角色", |
| | | prop: "isManager", |
| | | minWidth: 90, |
| | | cellRenderer: ({ row, props }) => ( |
| | | <el-tag |
| | | size={props.size} |
| | | type={row.sex === 1 ? "danger" : null} |
| | | type={row.isManager ? "danger" : null} |
| | | effect="plain" |
| | | > |
| | | {row.sex === 1 ? "女" : "男"} |
| | | {row.isManager ? "管理员" : "员工"} |
| | | </el-tag> |
| | | ) |
| | | }, |
| | |
| | | }, |
| | | { |
| | | label: "手机号码", |
| | | prop: "phone", |
| | | prop: "phoneNumber", |
| | | minWidth: 90, |
| | | formatter: ({ phone }) => hideTextAtIndex(phone, { start: 3, end: 6 }) |
| | | formatter: ({ phoneNumber }) => |
| | | hideTextAtIndex(phoneNumber, { start: 3, end: 6 }) |
| | | }, |
| | | { |
| | | label: "状态", |
| | |
| | | |
| | | async function onSearch() { |
| | | loading.value = true; |
| | | const { data } = await getUserList(toRaw(form)); |
| | | dataList.value = data.list; |
| | | pagination.total = data.total; |
| | | pagination.pageSize = data.pageSize; |
| | | pagination.currentPage = data.currentPage; |
| | | const { result } = await getUserList(toRaw(form)); |
| | | dataList.value = result; |
| | | // pagination.total = data.total; |
| | | // pagination.pageSize = data.pageSize; |
| | | // pagination.currentPage = data.currentPage; |
| | | |
| | | setTimeout(() => { |
| | | loading.value = false; |
| | | }, 500); |
| | | // setTimeout(() => { |
| | | loading.value = false; |
| | | // }, 500); |
| | | } |
| | | |
| | | const resetForm = formEl => { |
| | |
| | | |
| | | const cropRef = ref(); |
| | | /** 上传头像 */ |
| | | function handleUpload(row) { |
| | | addDialog({ |
| | | title: "裁剪、上传头像", |
| | | width: "40%", |
| | | closeOnClickModal: false, |
| | | fullscreen: deviceDetection(), |
| | | contentRenderer: () => |
| | | h(ReCropperPreview, { |
| | | ref: cropRef, |
| | | imgSrc: row.avatar || userAvatar, |
| | | onCropper: info => (avatarInfo.value = info) |
| | | }), |
| | | beforeSure: done => { |
| | | console.log("裁剪后的图片信息:", avatarInfo.value); |
| | | // 根据实际业务使用avatarInfo.value和row里的某些字段去调用上传头像接口即可 |
| | | done(); // 关闭弹框 |
| | | onSearch(); // 刷新表格数据 |
| | | }, |
| | | closeCallBack: () => cropRef.value.hidePopover() |
| | | }); |
| | | } |
| | | // function handleUpload(row) { |
| | | // addDialog({ |
| | | // title: "裁剪、上传头像", |
| | | // width: "40%", |
| | | // closeOnClickModal: false, |
| | | // fullscreen: deviceDetection(), |
| | | // contentRenderer: () => |
| | | // h(ReCropperPreview, { |
| | | // ref: cropRef, |
| | | // imgSrc: row.avatar || userAvatar, |
| | | // onCropper: info => (avatarInfo.value = info) |
| | | // }), |
| | | // beforeSure: done => { |
| | | // console.log("裁剪后的图片信息:", avatarInfo.value); |
| | | // // 根据实际业务使用avatarInfo.value和row里的某些字段去调用上传头像接口即可 |
| | | // done(); // 关闭弹框 |
| | | // onSearch(); // 刷新表格数据 |
| | | // }, |
| | | // closeCallBack: () => cropRef.value.hidePopover() |
| | | // }); |
| | | // } |
| | | |
| | | watch( |
| | | pwdForm, |
| | | ({ newPwd }) => |
| | | (curScore.value = isAllEmpty(newPwd) ? -1 : zxcvbn(newPwd).score) |
| | | ); |
| | | watch(); |
| | | // pwdForm |
| | | // ({ newPwd }) => |
| | | // (curScore.value = isAllEmpty(newPwd) ? -1 : zxcvbn(newPwd).score) |
| | | |
| | | /** 重置密码 */ |
| | | function handleReset(row) { |
| | |
| | | onTreeSelect, |
| | | handleUpdate, |
| | | handleDelete, |
| | | handleUpload, |
| | | // handleUpload, |
| | | handleReset, |
| | | handleRole, |
| | | handleSizeChange, |