Merge remote-tracking branch 'upstream/master'

This commit is contained in:
zyj 2025-01-02 11:20:32 +08:00
commit e32dd01d3b
25 changed files with 317 additions and 212 deletions

View File

@ -22,11 +22,11 @@
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.8</h1>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.9</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<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"><img src="https://img.shields.io/badge/RuoYi-v3.8.8-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.9-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>
</p>
@ -38,11 +38,10 @@
* 权限认证使用Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast)Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast)Oracle版本[RuoYi-Vue-Oracle](https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
## 内置功能

View File

@ -6,14 +6,14 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.8.8</version>
<version>3.8.9</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>3.8.8</ruoyi.version>
<ruoyi.version>3.8.9</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.8</version>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

View File

@ -1,5 +1,6 @@
package com.ruoyi.web.controller.system;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -87,8 +88,10 @@ public class SysProfileController extends BaseController
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public AjaxResult updatePwd(String oldPassword, String newPassword)
public AjaxResult updatePwd(@RequestBody Map<String, String> params)
{
String oldPassword = params.get("oldPassword");
String newPassword = params.get("newPassword");
LoginUser loginUser = getLoginUser();
String userName = loginUser.getUsername();
String password = loginUser.getPassword();

View File

@ -3,7 +3,7 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 3.8.8
version: 3.8.9
# 版权年份
copyrightYear: 2024
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.8</version>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,8 +4,10 @@ import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.utils.StringUtils;
/**
* Treeselect树结构实体类
@ -22,6 +24,9 @@ public class TreeSelect implements Serializable
/** 节点名称 */
private String label;
/** 节点禁用 */
private boolean disabled = false;
/** 子节点 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<TreeSelect> children;
@ -35,6 +40,7 @@ public class TreeSelect implements Serializable
{
this.id = dept.getDeptId();
this.label = dept.getDeptName();
this.disabled = StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus());
this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
}
@ -65,6 +71,16 @@ public class TreeSelect implements Serializable
this.label = label;
}
public boolean isDisabled()
{
return disabled;
}
public void setDisabled(boolean disabled)
{
this.disabled = disabled;
}
public List<TreeSelect> getChildren()
{
return children;

View File

@ -310,11 +310,23 @@ public class ExcelUtil<T>
* @return 转换后集合
*/
public List<T> importExcel(InputStream is)
{
return importExcel(is, 0);
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param is 输入流
* @param titleNum 标题占用行数
* @return 转换后集合
*/
public List<T> importExcel(InputStream is, int titleNum)
{
List<T> list = null;
try
{
list = importExcel(is, 0);
list = importExcel(StringUtils.EMPTY, is, titleNum);
}
catch (Exception e)
{
@ -328,18 +340,6 @@ public class ExcelUtil<T>
return list;
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param is 输入流
* @param titleNum 标题占用行数
* @return 转换后集合
*/
public List<T> importExcel(InputStream is, int titleNum) throws Exception
{
return importExcel(StringUtils.EMPTY, is, titleNum);
}
/**
* 对excel表单指定表格索引名转换成list
*

View File

@ -13,7 +13,7 @@ public class SqlUtil
/**
* 定义常用的 sql关键字
*/
public static String SQL_REGEX = "and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
/**
* 仅支持字母数字下划线空格逗号小数点支持多个字段排序

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.8</version>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.8</version>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -21,12 +21,15 @@ public class GenConfig
/** 生成包路径 */
public static String packageName;
/** 自动去除表前缀默认是false */
/** 自动去除表前缀 */
public static boolean autoRemovePre;
/** 表前缀(类名不会包含表前缀) */
/** 表前缀 */
public static String tablePrefix;
/** 是否允许生成文件覆盖到本地(自定义路径) */
public static boolean allowOverwrite;
public static String getAuthor()
{
return author;
@ -70,4 +73,15 @@ public class GenConfig
{
GenConfig.tablePrefix = tablePrefix;
}
public static boolean isAllowOverwrite()
{
return allowOverwrite;
}
@Value("${allowOverwrite}")
public void setAllowOverwrite(boolean allowOverwrite)
{
GenConfig.allowOverwrite = allowOverwrite;
}
}

View File

@ -30,6 +30,7 @@ import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import com.ruoyi.generator.config.GenConfig;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.service.IGenTableColumnService;
@ -213,6 +214,10 @@ public class GenController extends BaseController
@GetMapping("/genCode/{tableName}")
public AjaxResult genCode(@PathVariable("tableName") String tableName)
{
if (!GenConfig.isAllowOverwrite())
{
return AjaxResult.error("【系统预设】不允许生成文件覆盖到本地");
}
genTableService.generatorCode(tableName);
return success();
}

View File

@ -7,4 +7,6 @@ gen:
# 自动去除表前缀默认是false
autoRemovePre: false
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
tablePrefix: sys_
tablePrefix: sys_
# 是否允许生成文件覆盖到本地(自定义路径),默认不允许
allowOverwrite: false

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.8</version>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.8</version>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -1,6 +1,6 @@
{
"name": "ruoyi",
"version": "3.8.8",
"version": "3.8.9",
"description": "若依管理系统",
"author": "若依",
"license": "MIT",

File diff suppressed because one or more lines are too long

View File

@ -96,7 +96,7 @@ export function updateUserPwd(oldPassword, newPassword) {
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
data: data
})
}

View File

@ -1,173 +1,170 @@
<template>
<el-color-picker
v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
</template>
<script>
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
},
computed: {
defaultTheme() {
return this.$store.state.settings.theme
}
},
watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
},
immediate: true
},
async theme(val) {
await this.setTheme(val)
}
},
created() {
if(this.defaultTheme !== ORIGINAL_THEME) {
this.setTheme(this.defaultTheme)
}
},
methods: {
async setTheme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$emit('change', val)
},
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</script>
<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>
<template>
<el-color-picker
v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
</template>
<script>
const ORIGINAL_THEME = '#409EFF' // default color
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
},
computed: {
defaultTheme() {
return this.$store.state.settings.theme
}
},
watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
},
immediate: true
},
async theme(val) {
await this.setTheme(val)
}
},
created() {
if(this.defaultTheme !== ORIGINAL_THEME) {
this.setTheme(this.defaultTheme)
}
},
methods: {
async setTheme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!this.chalk) {
const url = `/styles/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$emit('change', val)
},
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</script>
<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>

View File

@ -96,8 +96,8 @@ export default {
let activePath = path;
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
const tmpPath = path.substring(1, path.length);
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
if (!this.$route.meta.link) {
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
this.$store.dispatch('app/toggleSideBarHide', false);
}
} else if(!this.$route.children) {

View File

@ -9,7 +9,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register', '/register*', '/register/*']
const whiteList = ['/login', '/register']
const isWhiteList = (path) => {
return whiteList.some(pattern => isPathMatch(pattern, path))

View File

@ -147,6 +147,45 @@
<span>更新日志</span>
</div>
<el-collapse accordion>
<el-collapse-item title="v3.8.9 - 2024-12-30">
<ol>
<li>用户管理支持分栏拖动</li>
<li>修改主题样式本地读取</li>
<li>用户头像http(s)链接支持</li>
<li>用户管理过滤掉已禁用部门</li>
<li>支持自定义显示Excel属性列</li>
<li>操作日志记录DELETE请求参数</li>
<li>白名单支持对通配符路径匹配</li>
<li>校检文件名是否包含特殊字符</li>
<li>代码生成创建表屏蔽违规的字符</li>
<li>菜单面包屑导航支持多层级显示</li>
<li>Excel注解支持wrapText是否允许内容换行</li>
<li>代码生成新增配置是否允许文件覆盖到本地</li>
<li>修复角色禁用权限不失效问题</li>
<li>修复代码生成上级菜单显示问题</li>
<li>修复导出子列表对象只能在最后的问题</li>
<li>修复TopNav无法正确获取active的问题</li>
<li>修复默认关闭Tags-Views内链页面打不开</li>
<li>升级oshi到最新版本6.6.5</li>
<li>升级tomcat到最新版本9.0.96</li>
<li>升级fastjson到最新版2.0.53</li>
<li>升级logback到最新版本1.2.13</li>
<li>升级spring-framework到最新版本5.3.39</li>
<li>升级quill到最新版本2.0.2</li>
<li>升级axios到最新版本0.28.1</li>
<li>优化身份证脱敏正则</li>
<li>优化权限更新后同步缓存</li>
<li>优化查询时间范围日期格式</li>
<li>优化参数键值更换为多行文本</li>
<li>优化导入带标题文件关闭清理</li>
<li>优化上传图片带域名不增加前缀</li>
<li>优化特殊字符密码修改失败问题</li>
<li>优化无用户编号不校验数据权限</li>
<li>优化TopNav内链菜单点击没有高亮</li>
<li>优化菜单管理切换Mini布局错乱问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.8 - 2024-06-30">
<ol>
<li>菜单管理新增路由名称</li>
@ -1020,7 +1059,7 @@ export default {
data() {
return {
//
version: "3.8.8"
version: "3.8.9"
};
},
methods: {

View File

@ -117,6 +117,8 @@
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="菜单类型" prop="menuType">
<el-radio-group v-model="form.menuType">
@ -126,6 +128,8 @@
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24" v-if="form.menuType != 'F'">
<el-form-item label="菜单图标" prop="icon">
<el-popover
@ -147,6 +151,8 @@
</el-popover>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="form.menuName" placeholder="请输入菜单名称" />
@ -157,6 +163,8 @@
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item prop="isFrame">
<span slot="label">
@ -182,6 +190,8 @@
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item prop="component">
<span slot="label">
@ -204,6 +214,8 @@
</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item prop="query">
<el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
@ -229,6 +241,8 @@
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item prop="visible">
<span slot="label">

View File

@ -105,7 +105,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="归属部门" prop="deptId">
<treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
<treeselect v-model="form.deptId" :options="enabledDeptOptions" :show-count="true" placeholder="请选择归属部门" />
</el-form-item>
</el-col>
</el-row>
@ -230,8 +230,10 @@ export default {
userList: null,
//
title: "",
//
//
deptOptions: undefined,
//
enabledDeptOptions: undefined,
//
open: false,
//
@ -343,6 +345,19 @@ export default {
getDeptTree() {
deptTreeSelect().then(response => {
this.deptOptions = response.data;
this.enabledDeptOptions = this.filterDisabledDept(JSON.parse(JSON.stringify(response.data)));
});
},
//
filterDisabledDept(deptList) {
return deptList.filter(dept => {
if (dept.disabled) {
return false;
}
if (dept.children && dept.children.length) {
dept.children = this.filterDisabledDept(dept.children);
}
return true;
});
},
//