Skip to content

Commit

Permalink
!72 发布 vue 版本 5.1.2 与 cloud 版本 2.1.2
Browse files Browse the repository at this point in the history
Merge pull request !72 from 疯狂的狮子Li/temp
  • Loading branch information
JavaLionLi authored and gitee-org committed Dec 22, 2023
2 parents 183e0e9 + 2c95f86 commit cc9b67d
Show file tree
Hide file tree
Showing 25 changed files with 99 additions and 38 deletions.
2 changes: 2 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ VITE_APP_PORT = 80

# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
VITE_APP_RSA_PRIVATE_KEY = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE='

# 客户端id
VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
Expand Down
2 changes: 2 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ VITE_APP_PORT = 80

# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
VITE_APP_RSA_PRIVATE_KEY = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE='

# 客户端id
VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ npm install --registry=https://registry.npmmirror.com
# 启动服务
npm run dev

# 构建生产环境 yarn build:prod
# 构建生产环境
npm run build:prod

# 前端访问地址 http://localhost:80
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ruoyi-vue-plus",
"version": "5.1.1",
"version": "5.1.2",
"description": "RuoYi-Vue-Plus多租户管理系统",
"author": "LionLi",
"license": "MIT",
Expand Down
4 changes: 2 additions & 2 deletions src/components/DictTag/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div>
<template v-for="(item, index) in options">
<template v-if="values.includes(item.value)">
<span v-if="(item.elTagType == 'default' || item.elTagType == '') && (item.elTagClass == '' || item.elTagClass == null)"
<span v-if="(item.elTagType === 'default' || item.elTagType === '') && (item.elTagClass === '' || item.elTagClass == null)"
:key="item.value" :index="index" :class="item.elTagClass">
{{ item.label + " " }}
</span>
Expand All @@ -11,7 +11,7 @@
:disable-transitions="true"
:key="item.value + ''"
:index="index"
:type="item.elTagType === 'primary' ? '' : item.elTagType"
:type="(item.elTagType === 'primary' || item.elTagType === 'default')? '' : item.elTagType"
:class="item.elTagClass"
>
{{ item.label + " " }}
Expand Down
2 changes: 1 addition & 1 deletion src/components/IconSelect/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="relative" :style="{ width: width }">
<el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="点击选择图标">
<template #prepend>
<svg-icon :icon-class="modelValue as string" />
<svg-icon :icon-class="modelValue" />
</template>
</el-input>

Expand Down
4 changes: 2 additions & 2 deletions src/layout/components/Sidebar/SidebarItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
</template>
<sidebar-item
v-for="(child) in item.children as RouteOption[]"
:key="child.path"
v-for="(child, index) in item.children"
:key="child.path + index"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
Expand Down
2 changes: 2 additions & 0 deletions src/permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ router.beforeEach(async (to, from, next) => {
if (to.path === '/login') {
next({ path: '/' });
NProgress.done();
} else if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
if (useUserStore().roles.length === 0) {
isRelogin.show = true;
Expand Down
2 changes: 1 addition & 1 deletion src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const dynamicRoutes: RouteOption[] = [
path: '/system/oss-config',
component: Layout,
hidden: true,
permissions: ['system:oss:list'],
permissions: ['system:ossConfig:list'],
children: [
{
path: 'index',
Expand Down
11 changes: 9 additions & 2 deletions src/store/modules/tagsView.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TagView } from 'vue-router';
import { TagView, RouteRecordNormalized } from 'vue-router';

export const useTagsViewStore = defineStore('tagsView', () => {
const visitedViews = ref<TagView[]>([]);
Expand Down Expand Up @@ -35,7 +35,9 @@ export const useTagsViewStore = defineStore('tagsView', () => {
const delView = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
return new Promise((resolve) => {
delVisitedView(view);
delCachedView(view);
if (!isDynamicRoute(view)) {
delCachedView(view);
}
resolve({
visitedViews: [...visitedViews.value],
cachedViews: [...cachedViews.value]
Expand Down Expand Up @@ -177,6 +179,11 @@ export const useTagsViewStore = defineStore('tagsView', () => {
}
};

const isDynamicRoute = (view: any): boolean => {
// 检查匹配的路由记录中是否有动态段
return view.matched.some((m: RouteRecordNormalized) => m.path.includes(':'));
};

return {
visitedViews,
cachedViews,
Expand Down
7 changes: 6 additions & 1 deletion src/store/modules/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export const useUserStore = defineStore('user', () => {
removeToken();
};

const setAvatar = (value: string) => {
avatar.value = value;
};

return {
userId,
token,
Expand All @@ -72,7 +76,8 @@ export const useUserStore = defineStore('user', () => {
permissions,
login,
getInfo,
logout
logout,
setAvatar
};
});

Expand Down
1 change: 1 addition & 0 deletions src/types/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ interface ImportMetaEnv {
VITE_APP_POWERJOB_ADMIN: string;
VITE_APP_ENV: string;
VITE_APP_RSA_PUBLIC_KEY: string;
VITE_APP_RSA_PRIVATE_KEY: string;
VITE_APP_CLIENT_ID: string;
VITE_APP_WEBSOCKET: string;
}
Expand Down
21 changes: 21 additions & 0 deletions src/utils/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export const encryptBase64 = (str: CryptoJS.lib.WordArray) => {
return CryptoJS.enc.Base64.stringify(str);
};

/**
* 解密base64
*/
export const decryptBase64 = (str: string) => {
return CryptoJS.enc.Base64.parse(str);
};

/**
* 使用密钥对数据进行加密
* @param message
Expand All @@ -43,3 +50,17 @@ export const encryptWithAes = (message: string, aesKey: CryptoJS.lib.WordArray)
});
return encrypted.toString();
};

/**
* 使用密钥对数据进行解密
* @param message
* @param aesKey
* @returns {string}
*/
export const decryptWithAes = (message: string, aesKey: CryptoJS.lib.WordArray) => {
const decrypted = CryptoJS.AES.decrypt(message, aesKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
};
2 changes: 1 addition & 1 deletion src/utils/jsencrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import JSEncrypt from 'jsencrypt';
const publicKey = import.meta.env.VITE_APP_RSA_PUBLIC_KEY;

// 前端不建议存放私钥 不建议解密数据 因为都是透明的意义不大
const privateKey = '**********';
const privateKey = import.meta.env.VITE_APP_RSA_PRIVATE_KEY;

// 加密
export const encrypt = (txt: string) => {
Expand Down
21 changes: 18 additions & 3 deletions src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { errorCode } from '@/utils/errorCode';
import { LoadingInstance } from 'element-plus/es/components/loading/src/loading';
import FileSaver from 'file-saver';
import { getLanguage } from '@/lang';
import { encryptBase64, encryptWithAes, generateAesKey } from '@/utils/crypto';
import { encrypt } from '@/utils/jsencrypt';
import { encryptBase64, encryptWithAes, generateAesKey, decryptWithAes, decryptBase64 } from '@/utils/crypto';
import { encrypt, decrypt } from '@/utils/jsencrypt';

const encryptHeader = 'encrypt-key';
let downloadLoadingInstance: LoadingInstance;
// 是否显示重新登录
export const isRelogin = { show: false };
Expand Down Expand Up @@ -78,7 +79,7 @@ service.interceptors.request.use(
if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
// 生成一个 AES 密钥
const aesKey = generateAesKey();
config.headers['encrypt-key'] = encrypt(encryptBase64(aesKey));
config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
}
// FormData数据去请求头Content-Type
Expand All @@ -96,6 +97,20 @@ service.interceptors.request.use(
// 响应拦截器
service.interceptors.response.use(
(res: AxiosResponse) => {
// 加密后的 AES 秘钥
const keyStr = res.headers[encryptHeader];
// 加密
if (keyStr != null && keyStr != '') {
const data = res.data;
// 请求体 AES 解密
const base64Str = decrypt(keyStr);
// base64 解码 得到请求头的 AES 秘钥
const aesKey = decryptBase64(base64Str.toString());
// aesKey 解码 data
const decryptData = decryptWithAes(data, aesKey);
// 将结果 (得到的是 JSON 字符串) 转为 JSON
res.data = JSON.parse(decryptData);
}
// 未设置状态码则默认成功状态
const code = res.data.code || HttpStatus.SUCCESS;
// 获取错误信息
Expand Down
4 changes: 2 additions & 2 deletions src/views/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* 部署方式 Docker 容器编排 一键部署业务集群<br />
* 国际化 SpringMessage Spring标准国际化方案<br />
</p>
<p><b>当前版本:</b> <span>v5.1.1</span></p>
<p><b>当前版本:</b> <span>v5.1.2</span></p>
<p>
<el-tag type="danger">&yen;免费开源</el-tag>
</p>
Expand Down Expand Up @@ -78,7 +78,7 @@
* 分布式监控 Prometheus、Grafana 全方位性能监控<br />
* 其余与 Vue 版本一致<br />
</p>
<p><b>当前版本:</b> <span>v2.1.1</span></p>
<p><b>当前版本:</b> <span>v2.1.2</span></p>
<p>
<el-tag type="danger">&yen;免费开源</el-tag>
</p>
Expand Down
12 changes: 8 additions & 4 deletions src/views/monitor/online/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
<script setup name="Online" lang="ts">
import { forceLogout, list as initData } from "@/api/monitor/online";
import { OnlineQuery, OnlineVO } from "@/api/monitor/online/types";
import api from "@/api/system/user";
import {to} from "await-to-js";
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_device_type } = toRefs<any>(proxy?.useDict("sys_device_type"));
Expand Down Expand Up @@ -100,10 +102,12 @@ const resetQuery = () => {
}
/** 强退按钮操作 */
const handleForceLogout = async (row: OnlineVO) => {
await proxy?.$modal.confirm('是否确认强退名称为"' + row.userName + '"的用户?');
await forceLogout(row.tokenId);
await getList();
proxy?.$modal.msgSuccess("删除成功");
const [err] = await to(proxy?.$modal.confirm('是否确认强退名称为"' + row.userName + '"的用户?') as any);
if (!err) {
await forceLogout(row.tokenId);
await getList();
proxy?.$modal.msgSuccess("删除成功");
}
}
onMounted(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/views/register.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ const registerRules: ElFormRules = {
const codeUrl = ref("");
const loading = ref(false);
const captchaEnabled = ref(true);
const registerRef = ref(ElForm);
const registerRef = ref<ElFormInstance>();
// 租户列表
const tenantList = ref<TenantVO[]>([]);
const handleRegister = () => {
registerRef.value.validate(async (valid: boolean) => {
registerRef.value?.validate(async (valid: boolean) => {
if (valid) {
loading.value = true;
const [err] = await to(register(registerForm.value));
Expand Down
2 changes: 1 addition & 1 deletion src/views/system/dept/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
</el-table>
</el-card>
<el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="600px">
<el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-body width="600px">
<el-form ref="deptFormRef" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24" v-if="form.parentId !== 0">
Expand Down
4 changes: 2 additions & 2 deletions src/views/system/dict/data.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
<el-table-column label="字典编码" align="center" prop="dictCode" v-if="false" />
<el-table-column label="字典标签" align="center" prop="dictLabel">
<template #default="scope">
<span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span>
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
<span v-if="(scope.row.listClass === '' || scope.row.listClass === 'default') && (scope.row.cssClass === '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span>
<el-tag v-else :type="(scope.row.listClass === 'primary' || scope.row.listClass === 'default') ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
</template>
</el-table-column>
<el-table-column label="字典键值" align="center" prop="dictValue" />
Expand Down
2 changes: 1 addition & 1 deletion src/views/system/menu/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
<template #label>
<span>
<el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
<el-tooltip content="控制器中定义的权限字符,如:@SaCheckPermission('system:user:list')" placement="top">
<el-icon>
<question-filled />
</el-icon>
Expand Down
10 changes: 5 additions & 5 deletions src/views/system/oss/config.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:oss:add']">新增</el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:ossConfig:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:oss:edit']">修改</el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:ossConfig:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:oss:remove']">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:ossConfig:remove']">
删除
</el-button>
</el-col>
Expand Down Expand Up @@ -67,10 +67,10 @@
<el-table-column label="操作" fixed="right" align="center" width="150" class-name="small-padding">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:oss:edit']"></el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:ossConfig:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:ossConfig:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
Expand Down
2 changes: 1 addition & 1 deletion src/views/system/role/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
<el-form-item prop="roleKey">
<template #label>
<span>
<el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
<el-tooltip content="控制器中定义的权限字符,如:@SaCheckRole('admin')" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
权限字符
Expand Down
6 changes: 3 additions & 3 deletions src/views/system/user/profile/userAvatar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="user-info-head" @click="editCropper()">
<img :src="options.img as string" title="点击上传头像" class="img-circle img-lg" />
<img :src="options.img" title="点击上传头像" class="img-circle img-lg" />
<el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
<el-row>
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
Expand Down Expand Up @@ -62,7 +62,7 @@ import { uploadAvatar } from "@/api/system/user";
import useUserStore from "@/store/modules/user";
interface Options {
img: string | ArrayBuffer | null; // 裁剪图片的地址
img: string | any; // 裁剪图片的地址
autoCrop: boolean; // 是否默认生成截图框
autoCropWidth: number; // 默认生成截图框宽度
autoCropHeight: number; // 默认生成截图框高度
Expand Down Expand Up @@ -140,7 +140,7 @@ const uploadImg = async () => {
const res = await uploadAvatar(formData);
open.value = false;
options.img = res.data.imgUrl;
userStore.avatar = options.img as string
userStore.setAvatar(options.img as string)
proxy?.$modal.msgSuccess("修改成功");
visible.value = false;
});
Expand Down
4 changes: 2 additions & 2 deletions src/views/tool/gen/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@
<el-tabs v-model="preview.activeName">
<el-tab-pane
v-for="(value, key) in preview.data"
:label="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))"
:name="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))"
:label="key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm'))"
:name="key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm'))"
:key="value"
>
<el-link :underline="false" icon="DocumentCopy" v-copyText="value" v-copyText:callback="copyTextSuccess" style="float:right">
Expand Down

0 comments on commit cc9b67d

Please sign in to comment.