Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
2
web/.gitignore
vendored
2
web/.gitignore
vendored
@@ -21,3 +21,5 @@ pnpm-debug.log*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
# 构建版本文件,无需上传git
|
||||
public/version-build
|
||||
|
||||
@@ -9,7 +9,7 @@ export default {
|
||||
two4: '友情链接',
|
||||
},
|
||||
account: {
|
||||
accountPlaceholder1: '请输入登录账号',
|
||||
accountPlaceholder1: '请输入登录账号/邮箱/手机号',
|
||||
accountPlaceholder2: '请输入登录密码',
|
||||
accountPlaceholder3: '请输入验证码',
|
||||
accountBtnText: '登 录',
|
||||
|
||||
@@ -13,6 +13,7 @@ import {initBackEndControlRoutes, setRouters} from '/@/router/backEnd';
|
||||
import {useFrontendMenuStore} from "/@/stores/frontendMenu";
|
||||
import {useTagsViewRoutes} from "/@/stores/tagsViewRoutes";
|
||||
import {toRaw} from "vue";
|
||||
import {checkVersion} from "/@/utils/upgrade";
|
||||
|
||||
/**
|
||||
* 1、前端控制路由时:isRequestRoutes 为 false,需要写 roles,需要走 setFilterRoute 方法。
|
||||
@@ -95,6 +96,8 @@ export function formatTwoStageRoutes(arr: any) {
|
||||
|
||||
// 路由加载前
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// 检查浏览器本地版本与线上版本是否一致,判断是否需要刷新页面进行更新
|
||||
await checkVersion()
|
||||
NProgress.configure({showSpinner: false});
|
||||
if (to.meta.title) NProgress.start();
|
||||
const token = Session.get('token');
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { nextTick } from 'vue';
|
||||
import '/@/theme/loading.scss';
|
||||
import { showUpgrade } from "/@/utils/upgrade";
|
||||
|
||||
|
||||
/**
|
||||
* 页面全局 Loading
|
||||
@@ -9,6 +11,8 @@ import '/@/theme/loading.scss';
|
||||
export const NextLoading = {
|
||||
// 创建 loading
|
||||
start: () => {
|
||||
// 显示升级提示
|
||||
showUpgrade()
|
||||
const bodys: Element = document.body;
|
||||
const div = <HTMLElement>document.createElement('div');
|
||||
div.setAttribute('class', 'loading-next');
|
||||
|
||||
55
web/src/utils/upgrade.ts
Normal file
55
web/src/utils/upgrade.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import axios from "axios";
|
||||
import * as process from "process";
|
||||
import {Local, Session} from '/@/utils/storage';
|
||||
import {ElNotification} from "element-plus";
|
||||
import fs from "fs";
|
||||
|
||||
// 是否显示升级提示信息框
|
||||
const IS_SHOW_UPGRADE_SESSION_KEY = 'isShowUpgrade';
|
||||
const VERSION_KEY = 'DVADMIN3_VERSION'
|
||||
const VERSION_FILE_NAME = 'version-build'
|
||||
|
||||
export function showUpgrade () {
|
||||
const isShowUpgrade = Session.get(IS_SHOW_UPGRADE_SESSION_KEY) ?? false
|
||||
if (isShowUpgrade) {
|
||||
Session.remove(IS_SHOW_UPGRADE_SESSION_KEY)
|
||||
ElNotification({
|
||||
title: '新版本升级',
|
||||
message: "检测到系统新版本,正在更新中!不用担心,更新很快的哦!",
|
||||
type: 'success',
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 生产环境前端版本校验,
|
||||
export async function checkVersion(){
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// 开发环境无需校验前端版本
|
||||
return
|
||||
}
|
||||
// 获取线上版本号 t为时间戳,防止缓存
|
||||
await axios.get(`/${VERSION_FILE_NAME}?t=${new Date().getTime()}`).then(res => {
|
||||
const {status, data} = res || {}
|
||||
if (status === 200) {
|
||||
// 获取当前版本号
|
||||
const localVersion = Local.get(VERSION_KEY)
|
||||
// 将当前版本号持久缓存至本地
|
||||
Local.set(VERSION_KEY, data)
|
||||
// 当用户本地存在版本号并且和线上版本号不一致时,进行页面刷新操作
|
||||
if (localVersion && localVersion !== data) {
|
||||
// 本地缓存版本号和线上版本号不一致,弹出升级提示框
|
||||
// 此处无法直接使用消息框进行提醒,因为 window.location.reload()会导致消息框消失,将在loading页面判断是否需要显示升级提示框
|
||||
Session.set(IS_SHOW_UPGRADE_SESSION_KEY, true)
|
||||
window.location.reload()
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function generateVersionFile (){
|
||||
// 生成版本文件到public目录下version文件中
|
||||
const version = `${process.env.npm_package_version}.${new Date().getTime()}`;
|
||||
fs.writeFileSync(`public/${VERSION_FILE_NAME}`, version);
|
||||
}
|
||||
@@ -80,8 +80,8 @@ export default defineComponent({
|
||||
const state = reactive({
|
||||
isShowPassword: false,
|
||||
ruleForm: {
|
||||
username: '',
|
||||
password: '',
|
||||
username: 'superadmin',
|
||||
password: 'admin123456',
|
||||
captcha: '',
|
||||
captchaKey: '',
|
||||
captchaImgBase: '',
|
||||
|
||||
@@ -42,10 +42,11 @@ export function getDataPermissionRangeAll() {
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
export function getDataPermissionDept() {
|
||||
export function getDataPermissionDept(query:object) {
|
||||
return request({
|
||||
url: '/api/system/role_menu_button_permission/role_to_dept_all/',
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params:query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
:label="btn.value">
|
||||
<div class="btn-item">
|
||||
{{ btn.data_range !== null ? `${btn.name}(${formatDataRange(btn.data_range)})` : btn.name }}
|
||||
<span v-show="btn.isCheck" @click.stop.prevent="handleSettingClick(menu, btn.id)">
|
||||
<span v-show="btn.isCheck" @click.stop.prevent="handleSettingClick(menu, btn)">
|
||||
<el-icon>
|
||||
<Setting />
|
||||
</el-icon>
|
||||
@@ -124,6 +124,7 @@ watch(
|
||||
(val) => {
|
||||
drawerVisible.value = val;
|
||||
getMenuBtnPermission()
|
||||
getDataPermissionRangeLable()
|
||||
|
||||
}
|
||||
);
|
||||
@@ -144,9 +145,10 @@ let menuCurrent = ref<Partial<MenuDataType>>({});
|
||||
let menuBtnCurrent = ref<number>(-1);
|
||||
let dialogVisible = ref(false);
|
||||
let dataPermissionRange = ref<DataPermissionRangeType[]>([]);
|
||||
let dataPermissionRangeLabel = ref<DataPermissionRangeType[]>([]);
|
||||
const formatDataRange = computed(() => {
|
||||
return function (datarange: number) {
|
||||
const findItem = dataPermissionRange.value.find((i) => i.value === datarange);
|
||||
const findItem = dataPermissionRangeLabel.value.find((i) => i.value === datarange);
|
||||
return findItem?.label || ''
|
||||
}
|
||||
})
|
||||
@@ -158,8 +160,13 @@ const getMenuBtnPermission = async () => {
|
||||
const resMenu = await getRolePermission({ role: props.roleId })
|
||||
menuData.value = resMenu
|
||||
}
|
||||
// 获取按钮的数据权限下拉选项
|
||||
const getDataPermissionRangeLable = async () => {
|
||||
const resRange = await getDataPermissionRange({ role: props.roleId })
|
||||
dataPermissionRangeLabel.value = resRange.data;
|
||||
}
|
||||
|
||||
const fetchData = async (btnId) => {
|
||||
const fetchData = async (btnId:number) => {
|
||||
try {
|
||||
const resRange = await getDataPermissionRange({menu_button:btnId});
|
||||
if (resRange?.code === 2000) {
|
||||
@@ -170,20 +177,22 @@ const fetchData = async (btnId) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleCollapseChange = (val: number) => {
|
||||
collapseCurrent.value = [val];
|
||||
};
|
||||
// const handleCollapseChange = (val: number) => {
|
||||
// collapseCurrent.value = [val];
|
||||
// };
|
||||
|
||||
/**
|
||||
* 设置按钮数据权限
|
||||
* @param record 当前菜单
|
||||
* @param btnType 按钮类型
|
||||
*/
|
||||
const handleSettingClick = (record: MenusType, btnId: number) => {
|
||||
const handleSettingClick = (record: MenusType, btn: MenusType['btns'][number]) => {
|
||||
menuCurrent.value = record;
|
||||
menuBtnCurrent.value = btnId;
|
||||
menuBtnCurrent.value = btn.id;
|
||||
dialogVisible.value = true;
|
||||
fetchData(btnId)
|
||||
dataPermission.value =btn.data_range;
|
||||
handlePermissionRangeChange(btn.data_range)
|
||||
fetchData( btn.id)
|
||||
};
|
||||
|
||||
const handleColumnChange = (val: boolean, record: MenusType, btnType: string) => {
|
||||
@@ -194,9 +203,10 @@ const handleColumnChange = (val: boolean, record: MenusType, btnType: string) =>
|
||||
|
||||
const handlePermissionRangeChange = async (val: number) => {
|
||||
if (val === 4) {
|
||||
const res = await getDataPermissionDept();
|
||||
const data = XEUtils.toArrayTree(res.data, { parentKey: 'parent', strict: false });
|
||||
deptData.value = data;
|
||||
const res = await getDataPermissionDept({ role: props.roleId,menu_button:menuBtnCurrent.value });
|
||||
const depts = XEUtils.toArrayTree(res.data.depts, { parentKey: 'parent', strict: false });
|
||||
deptData.value = depts;
|
||||
customDataPermission.value = res.data.dept_checked;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { resolve } from 'path';
|
||||
import { defineConfig, loadEnv, ConfigEnv } from 'vite';
|
||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import { generateVersionFile } from "/@/utils/upgrade";
|
||||
|
||||
const pathResolve = (dir: string) => {
|
||||
return resolve(__dirname, '.', dir);
|
||||
@@ -17,6 +18,8 @@ const alias: Record<string, string> = {
|
||||
|
||||
const viteConfig = defineConfig((mode: ConfigEnv) => {
|
||||
const env = loadEnv(mode.mode, process.cwd());
|
||||
// 当Vite构建时,生成版本文件
|
||||
generateVersionFile()
|
||||
return {
|
||||
plugins: [vue(), vueJsx(), vueSetupExtend()],
|
||||
root: process.cwd(),
|
||||
|
||||
Reference in New Issue
Block a user