19 Commits

Author SHA1 Message Date
RuoYi
a5f02187f9 若依 3.8.4 2022-09-26 08:07:15 +08:00
RuoYi
7148a8e428 优化日志操作中重置按钮时重复查询的问题 2022-09-19 14:47:49 +08:00
RuoYi
aad94b236e 通用下载方法新增config配置选项 2022-09-19 13:22:52 +08:00
RuoYi
9290e3c318 添加新群号:160110482 2022-08-28 20:11:00 +08:00
RuoYi
fabc195e90 修复多文件上传报错出现的异常问题 2022-08-24 13:40:52 +08:00
RuoYi
439b134c9b 优化页面内嵌iframe切换tab不刷新数据 2022-08-23 20:47:41 +08:00
RuoYi
2952cb2c4f 优化多角色数据权限匹配规则 2022-08-21 22:54:25 +08:00
RuoYi
1d2f37bfe1 修复图片预览组件src属性为null值控制台报错问题(I5KBAS) 2022-08-15 12:07:45 +08:00
RuoYi
0c66bc0624 个人中心修改密码去除多余的user传递 2022-08-12 12:18:15 +08:00
RuoYi
6b236930fd 登录日志新增解锁账户功能 2022-08-08 09:24:33 +08:00
RuoYi
f8e6431684 支持全局主题颜色设置 2022-07-31 17:51:45 +08:00
RuoYi
de7e21457d 升级vue到最新版本3.2.37 2022-07-31 17:51:04 +08:00
RuoYi
d6129f8471 升级vite到最新版本2.9.14 2022-07-31 17:50:44 +08:00
RuoYi
3d29929b57 优化表格上右侧工具条(搜索按钮显隐&右侧样式凸出) 2022-07-29 20:38:55 +08:00
RuoYi
8b49d6572a 修复菜单图标文本框搜索消失问题(I5IHZV) 2022-07-27 14:56:51 +08:00
RuoYi
56680d26e1 添加新群号:104748341 2022-07-25 17:47:08 +08:00
RuoYi
cafff38a6e 优化字典数据使用store存取 2022-07-20 19:38:44 +08:00
RuoYi
6c19bfbd90 修改验证码开关变量名 2022-07-14 19:49:20 +08:00
RuoYi
331dbc44b2 修改验证码开关变量名 2022-07-12 18:13:54 +08:00
35 changed files with 454 additions and 144 deletions

View File

@@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.3</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.4</h1>
<h4 align="center">基于SpringBoot+Vue3前后端分离的Java快速开发框架</h4> <h4 align="center">基于SpringBoot+Vue3前后端分离的Java快速开发框架</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.3-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.4-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@@ -106,4 +106,4 @@ yarn dev
## 若依前后端分离交流群 ## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/139821253-blue.svg)](https://jq.qq.com/?_wv=1027&k=njiWDmkj) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) 点击按钮入群。

View File

@@ -1,6 +1,6 @@
{ {
"name": "ruoyi", "name": "ruoyi",
"version": "3.8.3", "version": "3.8.4",
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
@@ -26,7 +26,7 @@
"jsencrypt": "3.2.1", "jsencrypt": "3.2.1",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"pinia": "2.0.14", "pinia": "2.0.14",
"vue": "3.2.31", "vue": "3.2.37",
"vue-cropper": "1.0.3", "vue-cropper": "1.0.3",
"vue-router": "4.0.14" "vue-router": "4.0.14"
}, },
@@ -35,7 +35,7 @@
"@vue/compiler-sfc": "3.2.36", "@vue/compiler-sfc": "3.2.36",
"sass": "1.52.1", "sass": "1.52.1",
"unplugin-auto-import": "0.8.5", "unplugin-auto-import": "0.8.5",
"vite": "2.9.9", "vite": "2.9.14",
"vite-plugin-compression": "0.5.1", "vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons": "2.0.1", "vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-setup-extend": "0.4.0" "vite-plugin-vue-setup-extend": "0.4.0"

View File

@@ -1,3 +1,15 @@
<template> <template>
<router-view /> <router-view />
</template> </template>
<script setup>
import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme'
onMounted(() => {
nextTick(() => {
// 初始化主题样式
handleThemeStyle(useSettingsStore().theme)
})
})
</script>

View File

@@ -17,6 +17,14 @@ export function delLogininfor(infoId) {
}) })
} }
// 解锁用户登录状态
export function unlockLogininfor(userName) {
return request({
url: '/monitor/logininfor/unlock/' + userName,
method: 'get'
})
}
// 清空登录日志 // 清空登录日志
export function cleanLogininfor() { export function cleanLogininfor() {
return request({ return request({

View File

@@ -25,22 +25,6 @@ export function getDept(deptId) {
}) })
} }
// 查询部门下拉树结构
export function treeselect() {
return request({
url: '/system/dept/treeselect',
method: 'get'
})
}
// 根据角色ID查询部门树结构
export function roleDeptTreeselect(roleId) {
return request({
url: '/system/dept/roleDeptTreeselect/' + roleId,
method: 'get'
})
}
// 新增部门 // 新增部门
export function addDept(data) { export function addDept(data) {
return request({ return request({

View File

@@ -109,3 +109,11 @@ export function authUserSelectAll(data) {
params: data params: data
}) })
} }
// 根据角色ID查询部门树结构
export function deptTreeSelect(roleId) {
return request({
url: '/system/role/deptTree/' + roleId,
method: 'get'
})
}

View File

@@ -125,3 +125,11 @@ export function updateAuthRole(data) {
params: data params: data
}) })
} }
// 查询部门下拉树结构
export function deptTreeSelect() {
return request({
url: '/system/user/deptTree',
method: 'get'
})
}

View File

@@ -12,11 +12,16 @@
} }
/* fade-transform */ /* fade-transform */
.fade-transform--move,
.fade-transform-leave-active, .fade-transform-leave-active,
.fade-transform-enter-active { .fade-transform-enter-active {
transition: all .5s; transition: all .5s;
} }
.fade-transform-leave-active {
position: absolute;
}
.fade-transform-enter { .fade-transform-enter {
opacity: 0; opacity: 0;
transform: translateX(-30px); transform: translateX(-30px);

View File

@@ -12,7 +12,7 @@
:show-file-list="false" :show-file-list="false"
:headers="headers" :headers="headers"
class="upload-file-uploader" class="upload-file-uploader"
ref="upload" ref="fileUpload"
> >
<!-- 上传按钮 --> <!-- 上传按钮 -->
<el-button type="primary">选取文件</el-button> <el-button type="primary">选取文件</el-button>
@@ -70,7 +70,7 @@ const emit = defineEmits();
const number = ref(0); const number = ref(0);
const uploadList = ref([]); const uploadList = ref([]);
const baseUrl = import.meta.env.VITE_APP_BASE_API; const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址 const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
const headers = ref({ Authorization: "Bearer " + getToken() }); const headers = ref({ Authorization: "Bearer " + getToken() });
const fileList = ref([]); const fileList = ref([]);
const showTip = computed( const showTip = computed(
@@ -139,13 +139,15 @@ function handleUploadError(err) {
// 上传成功回调 // 上传成功回调
function handleUploadSuccess(res, file) { function handleUploadSuccess(res, file) {
if (res.code === 200) {
uploadList.value.push({ name: res.fileName, url: res.fileName }); uploadList.value.push({ name: res.fileName, url: res.fileName });
if (uploadList.value.length === number.value) { uploadedSuccessfully();
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value); } else {
uploadList.value = []; number.value--;
number.value = 0;
emit("update:modelValue", listToString(fileList.value));
proxy.$modal.closeLoading(); proxy.$modal.closeLoading();
proxy.$modal.msgError(res.msg);
proxy.$refs.fileUpload.handleRemove(file);
uploadedSuccessfully();
} }
} }
@@ -155,6 +157,17 @@ function handleDelete(index) {
emit("update:modelValue", listToString(fileList.value)); emit("update:modelValue", listToString(fileList.value));
} }
// 上传结束处理
function uploadedSuccessfully() {
if (number.value > 0 && uploadList.value.length === number.value) {
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
uploadList.value = [];
number.value = 0;
emit("update:modelValue", listToString(fileList.value));
proxy.$modal.closeLoading();
}
}
// 获取文件名称 // 获取文件名称
function getFileName(name) { function getFileName(name) {
if (name.lastIndexOf("/") > -1) { if (name.lastIndexOf("/") > -1) {
@@ -169,7 +182,7 @@ function listToString(list, separator) {
let strs = ""; let strs = "";
separator = separator || ","; separator = separator || ",";
for (let i in list) { for (let i in list) {
if(undefined !== list[i].url) { if (list[i].url) {
strs += list[i].url + separator; strs += list[i].url + separator;
} }
} }

View File

@@ -20,7 +20,7 @@ import { isExternal } from "@/utils/validate";
const props = defineProps({ const props = defineProps({
src: { src: {
type: String, type: String,
required: true default: ""
}, },
width: { width: {
type: [Number, String], type: [Number, String],
@@ -33,6 +33,9 @@ const props = defineProps({
}); });
const realSrc = computed(() => { const realSrc = computed(() => {
if (!props.src) {
return;
}
let real_src = props.src.split(",")[0]; let real_src = props.src.split(",")[0];
if (isExternal(real_src)) { if (isExternal(real_src)) {
return real_src; return real_src;
@@ -41,6 +44,9 @@ const realSrc = computed(() => {
}); });
const realSrcList = computed(() => { const realSrcList = computed(() => {
if (!props.src) {
return;
}
let real_src_list = props.src.split(","); let real_src_list = props.src.split(",");
let srcList = []; let srcList = [];
real_src_list.forEach(item => { real_src_list.forEach(item => {

View File

@@ -9,8 +9,8 @@
:limit="limit" :limit="limit"
:on-error="handleUploadError" :on-error="handleUploadError"
:on-exceed="handleExceed" :on-exceed="handleExceed"
name="file" ref="imageUpload"
:on-remove="handleRemove" :before-remove="handleDelete"
:show-file-list="true" :show-file-list="true"
:headers="headers" :headers="headers"
:file-list="fileList" :file-list="fileList"
@@ -107,23 +107,6 @@ watch(() => props.modelValue, val => {
} }
},{ deep: true, immediate: true }); },{ deep: true, immediate: true });
// 删除图片
function handleRemove(file, files) {
emit("update:modelValue", listToString(fileList.value));
}
// 上传成功回调
function handleUploadSuccess(res) {
uploadList.value.push({ name: res.fileName, url: res.fileName });
if (uploadList.value.length === number.value) {
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
uploadList.value = [];
number.value = 0;
emit("update:modelValue", listToString(fileList.value));
proxy.$modal.closeLoading();
}
}
// 上传前loading加载 // 上传前loading加载
function handleBeforeUpload(file) { function handleBeforeUpload(file) {
let isImg = false; let isImg = false;
@@ -162,6 +145,41 @@ function handleExceed() {
proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`); proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
} }
// 上传成功回调
function handleUploadSuccess(res, file) {
if (res.code === 200) {
uploadList.value.push({ name: res.fileName, url: res.fileName });
uploadedSuccessfully();
} else {
number.value--;
proxy.$modal.closeLoading();
proxy.$modal.msgError(res.msg);
proxy.$refs.imageUpload.handleRemove(file);
uploadedSuccessfully();
}
}
// 删除图片
function handleDelete(file) {
const findex = fileList.value.map(f => f.name).indexOf(file.name);
if (findex > -1 && uploadList.value.length === number.value) {
fileList.value.splice(findex, 1);
emit("update:modelValue", listToString(fileList.value));
return false;
}
}
// 上传结束处理
function uploadedSuccessfully() {
if (number.value > 0 && uploadList.value.length === number.value) {
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
uploadList.value = [];
number.value = 0;
emit("update:modelValue", listToString(fileList.value));
proxy.$modal.closeLoading();
}
}
// 上传失败 // 上传失败
function handleUploadError() { function handleUploadError() {
proxy.$modal.msgError("上传图片失败"); proxy.$modal.msgError("上传图片失败");

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="top-right-btn"> <div class="top-right-btn" :style="style">
<el-row> <el-row>
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top"> <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-button circle icon="Search" @click="toggleSearch()" /> <el-button circle icon="Search" @click="toggleSearch()" />
</el-tooltip> </el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top"> <el-tooltip class="item" effect="dark" content="刷新" placement="top">
@@ -31,6 +31,14 @@ const props = defineProps({
columns: { columns: {
type: Array, type: Array,
}, },
search: {
type: Boolean,
default: true,
},
gutter: {
type: Number,
default: 10,
},
}) })
const emits = defineEmits(['update:showSearch', 'queryTable']); const emits = defineEmits(['update:showSearch', 'queryTable']);
@@ -42,6 +50,14 @@ const title = ref("显示/隐藏");
// 是否显示弹出层 // 是否显示弹出层
const open = ref(false); const open = ref(false);
const style = computed(() => {
const ret = {};
if (props.gutter) {
ret.marginRight = `${props.gutter / 2}px`;
}
return ret;
});
// 搜索 // 搜索
function toggleSearch() { function toggleSearch() {
emits("update:showSearch", !props.showSearch); emits("update:showSearch", !props.showSearch);

View File

@@ -2,23 +2,20 @@
<section class="app-main"> <section class="app-main">
<router-view v-slot="{ Component, route }"> <router-view v-slot="{ Component, route }">
<transition name="fade-transform" mode="out-in"> <transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews"> <keep-alive :include="tagsViewStore.cachedViews">
<component :is="Component" :key="route.path"/> <component v-if="!route.meta.link" :is="Component" :key="route.path"/>
</keep-alive> </keep-alive>
</transition> </transition>
</router-view> </router-view>
<iframe-toggle />
</section> </section>
</template> </template>
<script setup> <script setup>
import iframeToggle from "./IframeToggle/index"
import useTagsViewStore from '@/store/modules/tagsView' import useTagsViewStore from '@/store/modules/tagsView'
const tagsViewStore = useTagsViewStore() const tagsViewStore = useTagsViewStore()
const route = useRoute()
tagsViewStore.addCachedView(route)
const cachedViews = computed(() => {
return tagsViewStore.cachedViews
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -0,0 +1,19 @@
<template>
<transition-group name="fade-transform" mode="out-in">
<inner-link
v-for="(item, index) in tagsViewStore.iframeViews"
:key="item.path"
:iframeId="'iframe' + index"
v-show="route.path === item.path"
:src="item.meta.link"
></inner-link>
</transition-group>
</template>
<script setup>
import InnerLink from "../InnerLink/index"
import useTagsViewStore from '@/store/modules/tagsView'
const route = useRoute();
const tagsViewStore = useTagsViewStore()
</script>

View File

@@ -1,30 +1,43 @@
<script> <template>
export default { <div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!">
setup() { <iframe
const route = useRoute(); :id="iframeId"
const link = route.meta.link; style="width: 100%; height: 100%"
if (link === "") { :src="src"
return "404"; frameborder="no"
} ></iframe>
let url = link; </div>
const height = document.documentElement.clientHeight - 94.5 + "px"; </template>
const style = { height: height };
// 返回渲染函数 <script setup>
return () => const props = defineProps({
h( src: {
"div", type: String,
{ default: "/"
style: style,
},
h("iframe", {
src: url,
frameborder: "no",
width: "100%",
height: "100%",
scrolling: "auto",
})
);
}, },
iframeId: {
type: String
}
});
const height = ref(document.documentElement.clientHeight - 94.5 + "px");
const loading = ref(false);
onMounted(() => {
const { proxy } = getCurrentInstance()
const iframeId = ("#" + props.iframeId).replace(/\//g, "\\/");
const iframe = document.querySelector(iframeId);
// iframe页面loading控制
if (iframe.attachEvent) {
loading.value = true;
iframe.attachEvent("onload", function () {
proxy.loading = false;
});
} else {
loading.value = true;
iframe.onload = function () {
proxy.loading = false;
}; };
}
})
</script> </script>

View File

@@ -87,6 +87,7 @@ import { useDynamicTitle } from '@/utils/dynamicTitle'
import useAppStore from '@/store/modules/app' import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings' import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission' import usePermissionStore from '@/store/modules/permission'
import { handleThemeStyle } from '@/utils/theme'
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const appStore = useAppStore() const appStore = useAppStore()
@@ -143,6 +144,7 @@ const dynamicTitle = computed({
function themeChange(val) { function themeChange(val) {
settingsStore.changeSetting({ key: 'theme', value: val }) settingsStore.changeSetting({ key: 'theme', value: val })
theme.value = val; theme.value = val;
handleThemeStyle(val);
} }
function handleTheme(val) { function handleTheme(val) {
settingsStore.changeSetting({ key: 'sideTheme', value: val }) settingsStore.changeSetting({ key: 'sideTheme', value: val })

View File

@@ -141,6 +141,9 @@ function addTags() {
const { name } = route const { name } = route
if (name) { if (name) {
useTagsViewStore().addView(route) useTagsViewStore().addView(route)
if (route.meta.link) {
useTagsViewStore().addIframeView(route);
}
} }
return false return false
} }
@@ -159,6 +162,9 @@ function moveToCurrentTag() {
} }
function refreshSelectedTag(view) { function refreshSelectedTag(view) {
proxy.$tab.refreshPage(view); proxy.$tab.refreshPage(view);
if (route.meta.link) {
useTagsViewStore().delIframeView(route);
}
} }
function closeSelectedTag(view) { function closeSelectedTag(view) {
proxy.$tab.closePage(view).then(({ visitedViews }) => { proxy.$tab.closePage(view).then(({ visitedViews }) => {

View File

@@ -1,6 +1,5 @@
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
const useAppStore = defineStore( const useAppStore = defineStore(
'app', 'app',
{ {

57
src/store/modules/dict.js Normal file
View File

@@ -0,0 +1,57 @@
const useDictStore = defineStore(
'dict',
{
state: () => ({
dict: new Array()
}),
actions: {
// 获取字典
getDict(_key) {
if (_key == null && _key == "") {
return null;
}
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
return this.dict[i].value;
}
}
} catch (e) {
return null;
}
},
// 设置字典
setDict(_key, value) {
if (_key !== null && _key !== "") {
this.dict.push({
key: _key,
value: value
});
}
},
// 删除字典
removeDict(_key) {
var bln = false;
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
this.dict.splice(i, 1);
return true;
}
}
} catch (e) {
bln = false;
}
return bln;
},
// 清空字典
cleanDict() {
this.dict = new Array();
},
// 初始字典
initDict() {
}
}
})
export default useDictStore

View File

@@ -3,13 +3,22 @@ const useTagsViewStore = defineStore(
{ {
state: () => ({ state: () => ({
visitedViews: [], visitedViews: [],
cachedViews: [] cachedViews: [],
iframeViews: []
}), }),
actions: { actions: {
addView(view) { addView(view) {
this.addVisitedView(view) this.addVisitedView(view)
this.addCachedView(view) this.addCachedView(view)
}, },
addIframeView(view) {
if (this.iframeViews.some(v => v.path === view.path)) return
this.iframeViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
addVisitedView(view) { addVisitedView(view) {
if (this.visitedViews.some(v => v.path === view.path)) return if (this.visitedViews.some(v => v.path === view.path)) return
this.visitedViews.push( this.visitedViews.push(
@@ -42,9 +51,16 @@ const useTagsViewStore = defineStore(
break break
} }
} }
this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
resolve([...this.visitedViews]) resolve([...this.visitedViews])
}) })
}, },
delIframeView(view) {
return new Promise(resolve => {
this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
resolve([...this.iframeViews])
})
},
delCachedView(view) { delCachedView(view) {
return new Promise(resolve => { return new Promise(resolve => {
const index = this.cachedViews.indexOf(view.name) const index = this.cachedViews.indexOf(view.name)
@@ -67,6 +83,7 @@ const useTagsViewStore = defineStore(
this.visitedViews = this.visitedViews.filter(v => { this.visitedViews = this.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path return v.meta.affix || v.path === view.path
}) })
this.iframeViews = this.iframeViews.filter(item => item.path === view.path)
resolve([...this.visitedViews]) resolve([...this.visitedViews])
}) })
}, },
@@ -95,6 +112,7 @@ const useTagsViewStore = defineStore(
return new Promise(resolve => { return new Promise(resolve => {
const affixTags = this.visitedViews.filter(tag => tag.meta.affix) const affixTags = this.visitedViews.filter(tag => tag.meta.affix)
this.visitedViews = affixTags this.visitedViews = affixTags
this.iframeViews = []
resolve([...this.visitedViews]) resolve([...this.visitedViews])
}) })
}, },
@@ -126,6 +144,10 @@ const useTagsViewStore = defineStore(
if (i > -1) { if (i > -1) {
this.cachedViews.splice(i, 1) this.cachedViews.splice(i, 1)
} }
if(item.meta.link) {
const fi = this.iframeViews.findIndex(v => v.path === item.path)
this.iframeViews.splice(fi, 1)
}
return false return false
}) })
resolve([...this.visitedViews]) resolve([...this.visitedViews])
@@ -145,6 +167,10 @@ const useTagsViewStore = defineStore(
if (i > -1) { if (i > -1) {
this.cachedViews.splice(i, 1) this.cachedViews.splice(i, 1)
} }
if(item.meta.link) {
const fi = this.iframeViews.findIndex(v => v.path === item.path)
this.iframeViews.splice(fi, 1)
}
return false return false
}) })
resolve([...this.visitedViews]) resolve([...this.visitedViews])

View File

@@ -1,3 +1,4 @@
import useDictStore from '@/store/modules/dict'
import { getDicts } from '@/api/system/dict/data' import { getDicts } from '@/api/system/dict/data'
/** /**
@@ -6,11 +7,17 @@ import { getDicts } from '@/api/system/dict/data'
export function useDict(...args) { export function useDict(...args) {
const res = ref({}); const res = ref({});
return (() => { return (() => {
args.forEach((d, index) => { args.forEach((dictType, index) => {
res.value[d] = []; res.value[dictType] = [];
getDicts(d).then(resp => { const dicts = useDictStore().getDict(dictType);
res.value[d] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })) if (dicts) {
res.value[dictType] = dicts;
} else {
getDicts(dictType).then(resp => {
res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }))
useDictStore().setDict(dictType, res.value[dictType]);
}) })
}
}) })
return toRefs(res.value); return toRefs(res.value);
})() })()

View File

@@ -130,12 +130,13 @@ service.interceptors.response.use(res => {
) )
// 通用下载方法 // 通用下载方法
export function download(url, params, filename) { export function download(url, params, filename, config) {
downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
return service.post(url, params, { return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }], transformRequest: [(params) => { return tansParams(params) }],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob' responseType: 'blob',
...config
}).then(async (data) => { }).then(async (data) => {
const isLogin = await blobValidate(data); const isLogin = await blobValidate(data);
if (isLogin) { if (isLogin) {

49
src/utils/theme.js Normal file
View File

@@ -0,0 +1,49 @@
// 处理主题样式
export function handleThemeStyle(theme) {
document.documentElement.style.setProperty('--el-color-primary', theme)
for (let i = 1; i <= 9; i++) {
document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`)
}
for (let i = 1; i <= 9; i++) {
document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`)
}
}
// hex颜色转rgb颜色
export function hexToRgb(str) {
str = str.replace('#', '')
let hexs = str.match(/../g)
for (let i = 0; i < 3; i++) {
hexs[i] = parseInt(hexs[i], 16)
}
return hexs
}
// rgb颜色转Hex颜色
export function rgbToHex(r, g, b) {
let hexs = [r.toString(16), g.toString(16), b.toString(16)]
for (let i = 0; i < 3; i++) {
if (hexs[i].length == 1) {
hexs[i] = `0${hexs[i]}`
}
}
return `#${hexs.join('')}`
}
// 变浅颜色值
export function getLightColor(color, level) {
let rgb = hexToRgb(color)
for (let i = 0; i < 3; i++) {
rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i])
}
return rgbToHex(rgb[0], rgb[1], rgb[2])
}
// 变深颜色值
export function getDarkColor(color, level) {
let rgb = hexToRgb(color)
for (let i = 0; i < 3; i++) {
rgb[i] = Math.floor(rgb[i] * (1 - level))
}
return rgbToHex(rgb[0], rgb[1], rgb[2])
}

View File

@@ -121,8 +121,8 @@
<i class="el-icon-user-solid"></i> QQ群<s>满937441</s> <s>满887144332</s> <i class="el-icon-user-solid"></i> QQ群<s>满937441</s> <s>满887144332</s>
<s>满180251782</s> <s>满104180207</s> <s>满186866453</s> <s>满201396349</s> <s>满180251782</s> <s>满104180207</s> <s>满186866453</s> <s>满201396349</s>
<s>满101456076</s> <s>满101539465</s> <s>满264312783</s> <s>满167385320</s> <s>满101456076</s> <s>满101539465</s> <s>满264312783</s> <s>满167385320</s>
<a href="https://jq.qq.com/?_wv=1027&k=DuWxuULe" target="_blank"> <s>满104748341</s> <a href="https://jq.qq.com/?_wv=1027&k=0fsNiYZt" target="_blank">
139821253</a 160110482</a
> >
</p> </p>
<p> <p>
@@ -149,6 +149,42 @@
</div> </div>
</template> </template>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v3.8.4 - 2022-09-26">
<ol>
<li>数据逻辑删除不进行唯一验证</li>
<li>Excel注解支持导出对象的子列表方法</li>
<li>Excel注解支持自定义隐藏属性列</li>
<li>Excel注解支持backgroundColor属性设置背景色</li>
<li>支持配置密码最大错误次数/锁定时间</li>
<li>登录日志新增解锁账户功能</li>
<li>通用下载方法新增config配置选项</li>
<li>支持多权限字符匹配角色数据权限</li>
<li>页面内嵌iframe切换tab不刷新数据</li>
<li>操作日志记录支持排除敏感属性字段</li>
<li>修复多文件上传报错出现的异常问题</li>
<li>修复图片预览组件src属性为null值控制台报错问题</li>
<li>升级oshi到最新版本6.2.2</li>
<li>升级fastjson到最新版2.0.14</li>
<li>升级pagehelper到最新版1.4.3</li>
<li>升级core-js到最新版本3.25.2</li>
<li>升级element-ui到最新版本2.15.10</li>
<li>优化任务过期不执行调度</li>
<li>优化字典数据使用store存取</li>
<li>优化修改资料头像被覆盖的问题</li>
<li>优化修改用户登录账号重复验证</li>
<li>优化代码生成同步后值NULL问题</li>
<li>优化定时任务支持执行父类方法</li>
<li>优化用户个人信息接口防止修改部门</li>
<li>优化布局设置使用el-drawer抽屉显示</li>
<li>优化没有权限的用户编辑部门缺少数据</li>
<li>优化日志注解记录限制请求地址的长度</li>
<li>优化excel/scale属性导出单元格数值类型</li>
<li>优化日志操作中重置按钮时重复查询的问题</li>
<li>优化多个相同角色数据导致权限SQL重复问题</li>
<li>优化表格上右侧工具条搜索按钮显隐&右侧样式凸出</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.3 - 2022-06-27"> <el-collapse-item title="v3.8.3 - 2022-06-27">
<ol> <ol>
<li>新增缓存列表菜单功能</li> <li>新增缓存列表菜单功能</li>

View File

@@ -25,7 +25,7 @@
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaOnOff"> <el-form-item prop="code" v-if="captchaEnabled">
<el-input <el-input
v-model="loginForm.code" v-model="loginForm.code"
size="large" size="large"
@@ -91,7 +91,7 @@ const loginRules = {
const codeUrl = ref(""); const codeUrl = ref("");
const loading = ref(false); const loading = ref(false);
// 验证码开关 // 验证码开关
const captchaOnOff = ref(true); const captchaEnabled = ref(true);
// 注册开关 // 注册开关
const register = ref(false); const register = ref(false);
const redirect = ref(undefined); const redirect = ref(undefined);
@@ -117,7 +117,7 @@ function handleLogin() {
}).catch(() => { }).catch(() => {
loading.value = false; loading.value = false;
// 重新获取验证码 // 重新获取验证码
if (captchaOnOff.value) { if (captchaEnabled.value) {
getCode(); getCode();
} }
}); });
@@ -127,8 +127,8 @@ function handleLogin() {
function getCode() { function getCode() {
getCodeImg().then(res => { getCodeImg().then(res => {
captchaOnOff.value = res.captchaOnOff === undefined ? true : res.captchaOnOff; captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (captchaOnOff.value) { if (captchaEnabled.value) {
codeUrl.value = "data:image/gif;base64," + res.img; codeUrl.value = "data:image/gif;base64," + res.img;
loginForm.value.uuid = res.uuid; loginForm.value.uuid = res.uuid;
} }

View File

@@ -58,7 +58,7 @@
icon="Delete" icon="Delete"
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete"
v-hasPermi="['system:logininfor:remove']" v-hasPermi="['monitor:logininfor:remove']"
>删除</el-button> >删除</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
@@ -67,16 +67,26 @@
plain plain
icon="Delete" icon="Delete"
@click="handleClean" @click="handleClean"
v-hasPermi="['system:logininfor:remove']" v-hasPermi="['monitor:logininfor:remove']"
>清空</el-button> >清空</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Unlock"
:disabled="single"
@click="handleUnlock"
v-hasPermi="['monitor:logininfor:unlock']"
>解锁</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="warning" type="warning"
plain plain
icon="Download" icon="Download"
@click="handleExport" @click="handleExport"
v-hasPermi="['system:logininfor:export']" v-hasPermi="['monitor:logininfor:export']"
>导出</el-button> >导出</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
@@ -114,7 +124,7 @@
</template> </template>
<script setup name="Logininfor"> <script setup name="Logininfor">
import { list, delLogininfor, cleanLogininfor } from "@/api/monitor/logininfor"; import { list, delLogininfor, cleanLogininfor, unlockLogininfor } from "@/api/monitor/logininfor";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { sys_common_status } = proxy.useDict("sys_common_status"); const { sys_common_status } = proxy.useDict("sys_common_status");
@@ -123,7 +133,9 @@ const logininforList = ref([]);
const loading = ref(true); const loading = ref(true);
const showSearch = ref(true); const showSearch = ref(true);
const ids = ref([]); const ids = ref([]);
const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const selectName = ref("");
const total = ref(0); const total = ref(0);
const dateRange = ref([]); const dateRange = ref([]);
const defaultSort = ref({ prop: "loginTime", order: "descending" }); const defaultSort = ref({ prop: "loginTime", order: "descending" });
@@ -157,13 +169,15 @@ function handleQuery() {
function resetQuery() { function resetQuery() {
dateRange.value = []; dateRange.value = [];
proxy.resetForm("queryRef"); proxy.resetForm("queryRef");
queryParams.value.pageNum = 1;
proxy.$refs["logininforRef"].sort(defaultSort.value.prop, defaultSort.value.order); proxy.$refs["logininforRef"].sort(defaultSort.value.prop, defaultSort.value.order);
handleQuery();
} }
/** 多选框选中数据 */ /** 多选框选中数据 */
function handleSelectionChange(selection) { function handleSelectionChange(selection) {
ids.value = selection.map(item => item.infoId); ids.value = selection.map(item => item.infoId);
multiple.value = !selection.length; multiple.value = !selection.length;
single.value = selection.length != 1;
selectName.value = selection.map(item => item.userName);
} }
/** 排序触发事件 */ /** 排序触发事件 */
function handleSortChange(column, prop, order) { function handleSortChange(column, prop, order) {
@@ -190,6 +204,15 @@ function handleClean() {
proxy.$modal.msgSuccess("清空成功"); proxy.$modal.msgSuccess("清空成功");
}).catch(() => {}); }).catch(() => {});
} }
/** 解锁按钮操作 */
function handleUnlock() {
const username = selectName.value;
proxy.$modal.confirm('是否确认解锁用户"' + username + '"数据项?').then(function () {
return unlockLogininfor(username);
}).then(() => {
proxy.$modal.msgSuccess("用户" + username + "解锁成功");
}).catch(() => {});
}
/** 导出按钮操作 */ /** 导出按钮操作 */
function handleExport() { function handleExport() {
proxy.download("monitor/logininfor/export", { proxy.download("monitor/logininfor/export", {

View File

@@ -73,7 +73,7 @@
icon="Delete" icon="Delete"
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete"
v-hasPermi="['system:operlog:remove']" v-hasPermi="['monitor:operlog:remove']"
>删除</el-button> >删除</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
@@ -82,7 +82,7 @@
plain plain
icon="Delete" icon="Delete"
@click="handleClean" @click="handleClean"
v-hasPermi="['system:operlog:remove']" v-hasPermi="['monitor:operlog:remove']"
>清空</el-button> >清空</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
@@ -91,7 +91,7 @@
plain plain
icon="Download" icon="Download"
@click="handleExport" @click="handleExport"
v-hasPermi="['system:operlog:export']" v-hasPermi="['monitor:operlog:export']"
>导出</el-button> >导出</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
@@ -125,7 +125,7 @@
type="text" type="text"
icon="View" icon="View"
@click="handleView(scope.row, scope.index)" @click="handleView(scope.row, scope.index)"
v-hasPermi="['system:operlog:query']" v-hasPermi="['monitor:operlog:query']"
>详细</el-button> >详细</el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -239,8 +239,8 @@ function handleQuery() {
function resetQuery() { function resetQuery() {
dateRange.value = []; dateRange.value = [];
proxy.resetForm("queryRef"); proxy.resetForm("queryRef");
queryParams.value.pageNum = 1;
proxy.$refs["operlogRef"].sort(defaultSort.value.prop, defaultSort.value.order); proxy.$refs["operlogRef"].sort(defaultSort.value.prop, defaultSort.value.order);
handleQuery();
} }
/** 多选框选中数据 */ /** 多选框选中数据 */
function handleSelectionChange(selection) { function handleSelectionChange(selection) {

View File

@@ -37,7 +37,7 @@
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaOnOff"> <el-form-item prop="code" v-if="captchaEnabled">
<el-input <el-input
size="large" size="large"
v-model="registerForm.code" v-model="registerForm.code"
@@ -116,7 +116,7 @@ const registerRules = {
const codeUrl = ref(""); const codeUrl = ref("");
const loading = ref(false); const loading = ref(false);
const captchaOnOff = ref(true); const captchaEnabled = ref(true);
function handleRegister() { function handleRegister() {
proxy.$refs.registerRef.validate(valid => { proxy.$refs.registerRef.validate(valid => {
@@ -132,7 +132,7 @@ function handleRegister() {
}).catch(() => {}); }).catch(() => {});
}).catch(() => { }).catch(() => {
loading.value = false; loading.value = false;
if (captchaOnOff) { if (captchaEnabled) {
getCode(); getCode();
} }
}); });
@@ -142,8 +142,8 @@ function handleRegister() {
function getCode() { function getCode() {
getCodeImg().then(res => { getCodeImg().then(res => {
captchaOnOff.value = res.captchaOnOff === undefined ? true : res.captchaOnOff; captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (captchaOnOff.value) { if (captchaEnabled.value) {
codeUrl.value = "data:image/gif;base64," + res.img; codeUrl.value = "data:image/gif;base64," + res.img;
registerForm.value.uuid = res.uuid; registerForm.value.uuid = res.uuid;
} }

View File

@@ -185,6 +185,7 @@
</template> </template>
<script setup name="Data"> <script setup name="Data">
import useDictStore from '@/store/modules/dict'
import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type"; import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type";
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data"; import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
@@ -319,12 +320,14 @@ function submitForm() {
if (valid) { if (valid) {
if (form.value.dictCode != undefined) { if (form.value.dictCode != undefined) {
updateData(form.value).then(response => { updateData(form.value).then(response => {
useDictStore().removeDict(queryParams.value.dictType);
proxy.$modal.msgSuccess("修改成功"); proxy.$modal.msgSuccess("修改成功");
open.value = false; open.value = false;
getList(); getList();
}); });
} else { } else {
addData(form.value).then(response => { addData(form.value).then(response => {
useDictStore().removeDict(queryParams.value.dictType);
proxy.$modal.msgSuccess("新增成功"); proxy.$modal.msgSuccess("新增成功");
open.value = false; open.value = false;
getList(); getList();
@@ -341,6 +344,7 @@ function handleDelete(row) {
}).then(() => { }).then(() => {
getList(); getList();
proxy.$modal.msgSuccess("删除成功"); proxy.$modal.msgSuccess("删除成功");
useDictStore().removeDict(queryParams.value.dictType);
}).catch(() => {}); }).catch(() => {});
} }
/** 导出按钮操作 */ /** 导出按钮操作 */

View File

@@ -182,6 +182,7 @@
</template> </template>
<script setup name="Dict"> <script setup name="Dict">
import useDictStore from '@/store/modules/dict'
import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type"; import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
@@ -313,6 +314,7 @@ function handleExport() {
function handleRefreshCache() { function handleRefreshCache() {
refreshCache().then(() => { refreshCache().then(() => {
proxy.$modal.msgSuccess("刷新成功"); proxy.$modal.msgSuccess("刷新成功");
useDictStore().cleanDict();
}); });
} }

View File

@@ -375,9 +375,13 @@ function selected(name) {
showChooseIcon.value = false; showChooseIcon.value = false;
} }
/** 图标外层点击隐藏下拉列表 */ /** 图标外层点击隐藏下拉列表 */
function hideSelectIcon() { function hideSelectIcon(event) {
var elem = event.relatedTarget || event.srcElement || event.target || event.currentTarget;
var className = elem.className;
if (className !== "el-input__inner") {
showChooseIcon.value = false; showChooseIcon.value = false;
} }
}
/** 搜索按钮操作 */ /** 搜索按钮操作 */
function handleQuery() { function handleQuery() {
getList(); getList();

View File

@@ -262,9 +262,8 @@
</template> </template>
<script setup name="Role"> <script setup name="Role">
import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole } from "@/api/system/role"; import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole, deptTreeSelect } from "@/api/system/role";
import { roleMenuTreeselect, treeselect as menuTreeselect } from "@/api/system/menu"; import { roleMenuTreeselect, treeselect as menuTreeselect } from "@/api/system/menu";
import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
const router = useRouter(); const router = useRouter();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
@@ -462,8 +461,8 @@ function getRoleMenuTreeselect(roleId) {
}); });
} }
/** 根据角色ID查询部门树结构 */ /** 根据角色ID查询部门树结构 */
function getRoleDeptTreeselect(roleId) { function getDeptTree(roleId) {
return roleDeptTreeselect(roleId).then(response => { return deptTreeSelect(roleId).then(response => {
deptOptions.value = response.depts; deptOptions.value = response.depts;
return response; return response;
}); });
@@ -543,12 +542,12 @@ function dataScopeSelectChange(value) {
/** 分配数据权限操作 */ /** 分配数据权限操作 */
function handleDataScope(row) { function handleDataScope(row) {
reset(); reset();
const roleDeptTreeselect = getRoleDeptTreeselect(row.roleId); const deptTreeSelect = getDeptTree(row.roleId);
getRole(row.roleId).then(response => { getRole(row.roleId).then(response => {
form.value = response.data; form.value = response.data;
openDataScope.value = true; openDataScope.value = true;
nextTick(() => { nextTick(() => {
roleDeptTreeselect.then(res => { deptTreeSelect.then(res => {
nextTick(() => { nextTick(() => {
if (deptRef.value) { if (deptRef.value) {
deptRef.value.setCheckedKeys(res.checkedKeys); deptRef.value.setCheckedKeys(res.checkedKeys);

View File

@@ -350,8 +350,7 @@
<script setup name="User"> <script setup name="User">
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
import { treeselect } from "@/api/system/dept"; import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user";
import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser } from "@/api/system/user";
const router = useRouter(); const router = useRouter();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
@@ -429,8 +428,8 @@ watch(deptName, val => {
proxy.$refs["deptTreeRef"].filter(val); proxy.$refs["deptTreeRef"].filter(val);
}); });
/** 查询部门下拉树结构 */ /** 查询部门下拉树结构 */
function getTreeselect() { function getDeptTree() {
treeselect().then(response => { deptTreeSelect().then(response => {
deptOptions.value = response.data; deptOptions.value = response.data;
}); });
}; };
@@ -550,15 +549,6 @@ const handleFileSuccess = (response, file, fileList) => {
function submitFileForm() { function submitFileForm() {
proxy.$refs["uploadRef"].submit(); proxy.$refs["uploadRef"].submit();
}; };
/** 初始化部门数据 */
function initTreeData() {
// 判断部门的数据是否存在,存在不获取,不存在则获取
if (deptOptions.value === undefined) {
treeselect().then(response => {
deptOptions.value = response.data;
});
}
};
/** 重置操作表单 */ /** 重置操作表单 */
function reset() { function reset() {
form.value = { form.value = {
@@ -585,7 +575,6 @@ function cancel() {
/** 新增按钮操作 */ /** 新增按钮操作 */
function handleAdd() { function handleAdd() {
reset(); reset();
initTreeData();
getUser().then(response => { getUser().then(response => {
postOptions.value = response.posts; postOptions.value = response.posts;
roleOptions.value = response.roles; roleOptions.value = response.roles;
@@ -597,7 +586,6 @@ function handleAdd() {
/** 修改按钮操作 */ /** 修改按钮操作 */
function handleUpdate(row) { function handleUpdate(row) {
reset(); reset();
initTreeData();
const userId = row.userId || ids.value; const userId = row.userId || ids.value;
getUser(userId).then(response => { getUser(userId).then(response => {
form.value = response.data; form.value = response.data;
@@ -631,6 +619,6 @@ function submitForm() {
}); });
}; };
getTreeselect(); getDeptTree();
getList(); getList();
</script> </script>

View File

@@ -53,7 +53,7 @@
<userInfo :user="state.user" /> <userInfo :user="state.user" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd"> <el-tab-pane label="修改密码" name="resetPwd">
<resetPwd :user="state.user" /> <resetPwd />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-card> </el-card>

View File

@@ -7,7 +7,7 @@
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password /> <el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password />
</el-form-item> </el-form-item>
<el-form-item label="确认密码" prop="confirmPassword"> <el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="user.confirmPassword" placeholder="请确认密码" type="password" show-password/> <el-input v-model="user.confirmPassword" placeholder="请确认密码" type="password" show-password/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submit">保存</el-button> <el-button type="primary" @click="submit">保存</el-button>