| | |
| | | if (!item.meta.title) return ""; |
| | | const Title = getConfig().Title; |
| | | if (Title) document.title = `${item.meta.title} | ${Title}`; |
| | | else document.title = item.meta.title as string; |
| | | else document.title = item.meta.title; |
| | | }); |
| | | } |
| | | /** 如果已经登录并存在登录信息后不能跳转到路由白名单,而是继续保持在当前页面 */ |
| | |
| | | } |
| | | if (Cookies.get(multipleTabsKey) && userInfo) { |
| | | // 无权限跳转403页面 |
| | | if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.exRoles)) { |
| | | if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) { |
| | | next({ path: "/error/403" }); |
| | | } |
| | | // 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面 |
| | |
| | | if (whiteList.indexOf(to.path) !== -1) { |
| | | next(); |
| | | } else { |
| | | // if (noLoginList.indexOf(to.path) == -1) { |
| | | next(); |
| | | // } else { |
| | | // removeToken(); |
| | | // next({ path: "/login" }); |
| | | // } |
| | | removeToken(); |
| | | next({ path: "/login" }); |
| | | } |
| | | } else { |
| | | next(); |
| | |
| | | export default { |
| | | path: "/item", |
| | | component: () => import("@/views/system/dept/index.vue"), |
| | | name: "item", |
| | | // redirect: "/error/403", |
| | | meta: { |
| | | icon: "ri/information-line", |
| | | // showLink: hasFlash, |
| | | title: "项目管理", |
| | | rank: 9 |
| | | } |
| | | icon: "mdi:chart-timeline" |
| | | }, |
| | | children: [ |
| | | { |
| | | // path随便写,但前面必须有个 `/` |
| | | path: "/item", |
| | | // component对应的值前不需要加 / 值对应的是实际业务 `.vue` 或 `.tsx` 代码路径 |
| | | component: () => import("@/views/system/dept/index.vue"), |
| | | name: "item", |
| | | meta: { |
| | | title: "项目管理", |
| | | roles: ["GYS"] |
| | | // showLink:false |
| | | } |
| | | } |
| | | ] |
| | | } satisfies RouteConfigsTable; |
| | |
| | | name: "Mine", |
| | | // redirect: "/error/403", |
| | | meta: { |
| | | icon: "ep/home-filled", |
| | | icon: "mdi:account-outline", |
| | | // showLink: false, |
| | | title: "个人中心", |
| | | rank: 9 |
| | |
| | | const IFrame = () => import("@/layout/frame.vue"); |
| | | // https://cn.vitejs.dev/guide/features.html#glob-import |
| | | const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}"); |
| | | const quanxianList = ["/item"]; |
| | | |
| | | // 动态路由 |
| | | import { getAsyncRoutes } from "@/api/routes"; |
| | |
| | | |
| | | /** 过滤meta中showLink为false的菜单 */ |
| | | function filterTree(data: RouteComponent[]) { |
| | | const hasFlsh = useUserStoreHook().nowRole.hasFlsh; |
| | | const newTree = cloneDeep(data).filter( |
| | | (v: { meta: { showLink: boolean } }) => v.meta?.showLink !== false |
| | | (v: { meta: { showLink: boolean } }) => { |
| | | quanxianList.includes(v.path) ? (v.meta.showLink = hasFlsh) : null; |
| | | return v.meta?.showLink !== false; |
| | | } |
| | | ); |
| | | console.log(newTree); |
| | | |
| | | newTree.forEach( |
| | | (v: { children }) => v.children && (v.children = filterTree(v.children)) |
| | | ); |
| | |
| | | /** 从localStorage里取出当前登录用户的角色roles,过滤无权限的菜单 */ |
| | | function filterNoPermissionTree(data: RouteComponent[]) { |
| | | const currentRoles = |
| | | storageLocal().getItem<DataInfo<number>>(userKey)?.exRoles ?? []; |
| | | storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? []; |
| | | const newTree = cloneDeep(data).filter((v: any) => |
| | | isOneOfArray(v.meta?.roles, currentRoles) |
| | | ); |
| | |
| | | value?: T | multiType, |
| | | position?: positionType |
| | | ): T { |
| | | console.log(mode, "--------------",value); |
| | | |
| | | switch (mode) { |
| | | case "equal": |
| | | this.multiTags = value; |
| | |
| | | username: storageLocal().getItem<DataInfo<number>>(userKey)?.username ?? "", |
| | | // 昵称 |
| | | nickname: storageLocal().getItem<DataInfo<number>>(userKey)?.nickname ?? "", |
| | | // 页面级别权限 |
| | | // 当前角色列表 |
| | | exRoles: storageLocal().getItem<DataInfo<number>>(userKey)?.exRoles ?? [], |
| | | // 按钮级别权限 |
| | | permissions: |
| | |
| | | enterpriseInfo: |
| | | storageLocal().getItem<CusExtendDto>("enterpriseInfo") ?? {}, |
| | | nowRole: storageLocal().getItem<nowRoleType>("nowRole") ?? {}, |
| | | rolesList: storageLocal().getItem<DataInfo<number>>("rolesList") ?? [] |
| | | rolesList: storageLocal().getItem<DataInfo<number>>("rolesList") ?? [], |
| | | // 页面级别权限 |
| | | roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [] |
| | | }), |
| | | actions: { |
| | | /** 存储头像 */ |
| | |
| | | this.nickname = nickname; |
| | | }, |
| | | /** 存储用户角色 */ |
| | | SET_ROLES(exRoles: Array<string>) { |
| | | SET_EXROLES(exRoles: Array<string>) { |
| | | this.exRoles = exRoles; |
| | | }, |
| | | /** 存储角色 */ |
| | | SET_ROLES(roles: Array<string>) { |
| | | this.roles = roles; |
| | | }, |
| | | /** 存储角色当前角色 */ |
| | | SET_NOW_ROLE(nowRole: nowRoleType) { |
| | | this.nowRole = nowRole; |
| | | }, |
| | | /** 存储角色列表 */ |
| | | SET_ROLES_LIST(rolesList: Array<string>) { |
| | | SET_EXROLES_LIST(rolesList: Array<string>) { |
| | | this.rolesList = rolesList; |
| | | }, |
| | | /** 存储按钮级别权限 */ |
| | |
| | | getLogin(obj) |
| | | .then(data => { |
| | | if (data?.code == 200) { |
| | | data.result.roles = [obj.exRuleCode]; |
| | | setToken(data.result); |
| | | this.getNowRole(obj.exRuleCode); |
| | | } |
| | |
| | | getChangeLogoInExRule(obj) |
| | | .then(async data => { |
| | | if (data?.code == 200) { |
| | | data.result.roles = [obj.ruleCode]; |
| | | setToken(data.result); |
| | | this.getNowRole(obj.ruleCode); |
| | | await this.getCusExtendInfo(); |
| | |
| | | logOut() { |
| | | this.username = ""; |
| | | this.exRoles = []; |
| | | this.roles = []; |
| | | this.permissions = []; |
| | | removeToken(); |
| | | useMultiTagsStoreHook().handleTags("equal", [...routerArrays]); |
| | |
| | | username?: string; |
| | | nickname?: string; |
| | | exRoles?: Array<string>; |
| | | roles?: Array<string>; |
| | | permissions?: Array<string>; |
| | | isRemembered?: boolean; |
| | | loginDay?: number; |
| | |
| | | username?: string; |
| | | /** 昵称 */ |
| | | nickname?: string; |
| | | /** 当前登录用户的角色 */ |
| | | /** 当前登录用户的角色列表 */ |
| | | exRoles?: Array<string>; |
| | | /** 当前登录用户的角色 */ |
| | | roles?: Array<string>; |
| | | /** 当前登录用户的按钮级别权限 */ |
| | | permissions?: Array<string>; |
| | | } |
| | |
| | | : {} |
| | | ); |
| | | |
| | | function setUserKey({ avatar, username, nickname, exRoles, permissions }) { |
| | | function setUserKey({ |
| | | avatar, |
| | | username, |
| | | nickname, |
| | | exRoles, |
| | | permissions, |
| | | roles |
| | | }) { |
| | | useUserStoreHook().SET_AVATAR(avatar); |
| | | useUserStoreHook().SET_USERNAME(username); |
| | | useUserStoreHook().SET_NICKNAME(nickname); |
| | | useUserStoreHook().SET_ROLES(exRoles); |
| | | useUserStoreHook().SET_EXROLES(exRoles); |
| | | useUserStoreHook().SET_ROLES(roles); |
| | | useUserStoreHook().SET_PERMS(permissions); |
| | | storageLocal().setItem(userKey, { |
| | | refreshToken, |
| | |
| | | username, |
| | | nickname, |
| | | exRoles, |
| | | roles, |
| | | permissions |
| | | }); |
| | | } |
| | | |
| | | if (data.exRoles) { |
| | | const { username, exRoles } = data; |
| | | if (data.exRoles && data.roles) { |
| | | const { username, exRoles, roles } = data; |
| | | setUserKey({ |
| | | avatar: data?.avatar ?? "", |
| | | username, |
| | | nickname: data?.nickname ?? "", |
| | | exRoles, |
| | | roles, |
| | | permissions: data?.permissions ?? [] |
| | | }); |
| | | } else { |
| | |
| | | storageLocal().getItem<DataInfo<number>>(userKey)?.nickname ?? ""; |
| | | const exRoles = |
| | | storageLocal().getItem<DataInfo<number>>(userKey)?.exRoles ?? []; |
| | | const roles = |
| | | storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? []; |
| | | const permissions = |
| | | storageLocal().getItem<DataInfo<number>>(userKey)?.permissions ?? []; |
| | | setUserKey({ |
| | |
| | | username, |
| | | nickname, |
| | | exRoles, |
| | | roles, |
| | | permissions |
| | | }); |
| | | } |
| | |
| | | } |
| | | |
| | | export function setRoleListInfo(data: DataInfo<string>) { |
| | | useUserStoreHook().SET_ROLES_LIST(data); |
| | | useUserStoreHook().SET_EXROLES_LIST(data); |
| | | storageLocal().setItem("rolesList", data); |
| | | } |
| | | |
| | |
| | | }); |
| | | data = { ...obj, ...data }; |
| | | } |
| | | useUserStoreHook().SET_ROLES([data.name]); |
| | | useUserStoreHook().SET_NOW_ROLE(data); |
| | | storageLocal().setItem("nowRole", data); |
| | | } |
| | |
| | | import { cusExtendInfo, changeCusExtend } from "@/api/mine"; |
| | | import { Edit } from "@element-plus/icons-vue"; |
| | | import { enterpriseTypes } from "@/api/register/index"; |
| | | import { initRouter, getTopMenu, handleAliveRoute } from "@/router/utils"; |
| | | |
| | | const ruleFormRef = ref<FormInstance>(); |
| | | const isLoading = ref(false); |
| | | const showDialog = ref(false); |
| | |
| | | await useUserStoreHook().changeLogoInExRule({ |
| | | ruleCode: useUserStoreHook().nowRole.code |
| | | }); |
| | | initRouter(); |
| | | message("修改成功!", { |
| | | type: "success" |
| | | }); |
| | |
| | | class="w-full" |
| | | :options="state.regionList" |
| | | :props="{ |
| | | value: 'id', |
| | | value: 'code', |
| | | label: 'name', |
| | | emitPath: false, |
| | | children: 'regions' |
| | | }" |
| | | clearable |
| | |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4"> |
| | | <el-form-item label-width="40"> |
| | | <el-button |
| | | type="primary" |
| | | :icon="useRenderIcon('ri/search-line')" |
| | | :loading="loading" |
| | | @click="onSearch" |
| | | > |
| | | <el-button type="primary" :loading="loading" @click="onSearch"> |
| | | 搜索 |
| | | </el-button> |
| | | <!-- <el-button |
| | |
| | | > |
| | | 重置 |
| | | </el-button> --> |
| | | <el-button |
| | | type="primary" |
| | | :icon="useRenderIcon(AddFill)" |
| | | @click="openDialog()" |
| | | > |
| | | 新增 |
| | | </el-button> |
| | | <el-button type="primary" @click="openDialog()"> 新增 </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | :size="size" |
| | | :icon="useRenderIcon(EditPen)" |
| | | @click="openDialog('修改', row)" |
| | | > |
| | | 修改 |
| | | </el-button> |
| | | /> |
| | | <!-- <el-button |
| | | class="reset-margin" |
| | | link |
| | |
| | | type="primary" |
| | | :size="size" |
| | | :icon="useRenderIcon(Delete)" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | /> |
| | | </template> |
| | | </el-popconfirm> |
| | | </template> |
| | |
| | | } |
| | | }; |
| | | async function onSearch() { |
| | | loading.value = true; |
| | | const obj = cloneDeep(form); |
| | | obj.tousu = obj.tousu.join(""); |
| | | obj.zhiyi = obj.zhiyi.join(""); |
| | | obj.xingzhengquyu = obj.xingzhengquyu.join(""); |
| | | obj.xingzhengquyu = obj.xingzhengquyu ? obj.xingzhengquyu.join("") : ""; |
| | | loading.value = true; |
| | | const { result } = await zhaobiaoPageOrder(obj); // 这里是返回一维数组结构,前端自行处理成树结构,返回格式要求:唯一id加父节点parentId,parentId取父节点id |
| | | const newData = result.items; |
| | | loading.value = false; |
| | |
| | | } |
| | | |
| | | function openDialog(title = "新增", row?: FormItemProps) { |
| | | console.log(row,'-'); |
| | | |
| | | addDialog({ |
| | | title: `${title}项目`, |
| | | props: { |
| | |
| | | } else { |
| | | closeLoading(); |
| | | const fail = []; |
| | | console.log(obj); |
| | | |
| | | for (const key in obj) { |
| | | fail.push(obj[key][0].message); |
| | | } |
| | |
| | | ], |
| | | // 采购预算(可选,需为数字) |
| | | caigouyusuan: [ |
| | | { required: true, message: "请输入采购预算", trigger: "blur" }, |
| | | { type: "number", message: "采购预算必须为数字", trigger: "blur" }, |
| | | { min: 0, message: "采购预算不能为负数", trigger: "blur" } |
| | | { required: true, message: "请输入采购预算", trigger: "blur" } |
| | | // { type: "number", message: "采购预算必须为数字", trigger: "blur" }, |
| | | // { min: 0, message: "采购预算不能为负数", trigger: "blur" } |
| | | ], |
| | | // 定标规则(可选) |
| | | dingbiaoguize: [ |
| | |
| | | ], |
| | | // 报名费(可选,需为数字) |
| | | baomingfei: [ |
| | | { required: true, message: "请输入报名费", trigger: "blur" }, |
| | | { type: "number", message: "报名费必须为数字", trigger: "blur" }, |
| | | { min: 0, message: "报名费不能为负数", trigger: "blur" } |
| | | { required: true, message: "请输入报名费", trigger: "blur" } |
| | | // { type: "number", message: "报名费必须为数字", trigger: "blur" }, |
| | | // { min: 0, message: "报名费不能为负数", trigger: "blur" } |
| | | ], |
| | | // 投标保证金(可选,需为数字) |
| | | toubiaobaozhengjin: [ |
| | | { required: true, message: "请输入投标保证金费", trigger: "blur" }, |
| | | { type: "number", message: "投标保证金必须为数字", trigger: "blur" }, |
| | | { min: 0, message: "投标保证金不能为负数", trigger: "blur" } |
| | | { required: true, message: "请输入投标保证金费", trigger: "blur" } |
| | | // { type: "number", message: "投标保证金必须为数字", trigger: "blur" }, |
| | | // { min: 0, message: "投标保证金不能为负数", trigger: "blur" } |
| | | ], |
| | | // 联合体投标(可选,需为布尔值) |
| | | lianhetitoubiao: [ |
| | |
| | | { type: "array", message: "行政区域必须为数组格式", trigger: "change" } |
| | | ], |
| | | // 行政区域名称(可选) |
| | | xingzhengquyuName: [ |
| | | { required: false }, |
| | | { max: 100, message: "行政区域名称长度不能超过100个字符", trigger: "blur" } |
| | | ], |
| | | // xingzhengquyuName: [ |
| | | // { required: false }, |
| | | // { max: 100, message: "行政区域名称长度不能超过100个字符", trigger: "blur" } |
| | | // ], |
| | | // 机构代码(可选,验证格式) |
| | | jigoudaima: [ |
| | | { required: true, message: "请输入机构代码", trigger: "blur" }, |
| | | { |
| | | pattern: /^[A-Z0-9]{8}-[A-Z0-9]{1}$/, |
| | | message: "机构代码格式不正确", |
| | | trigger: "blur" |
| | | } |
| | | { required: true, message: "请输入机构代码", trigger: "blur" } |
| | | // { |
| | | // pattern: /^[A-Z0-9]{8}-[A-Z0-9]{1}$/, |
| | | // message: "机构代码格式不正确", |
| | | // trigger: "blur" |
| | | // } |
| | | ], |
| | | // 代码类型(可选) |
| | | daimaleixing: [ |
| | |
| | | showParent?: boolean; |
| | | /** 页面级别权限设置 `可选` */ |
| | | exRoles?: Array<string>; |
| | | // 页面级别权限设置 |
| | | roles?: Array<string>; |
| | | /** 按钮级别权限设置 `可选` */ |
| | | auths?: Array<string>; |
| | | /** 路由组件缓存(开启 `true`、关闭 `false`)`可选` */ |