Explorar o código

Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue into dev

 Conflicts:
	pom.xml
	ruoyi-admin/pom.xml
	ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
	ruoyi-admin/src/main/resources/application.yml
	ruoyi-common/pom.xml
	ruoyi-framework/pom.xml
	ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
	ruoyi-generator/pom.xml
	ruoyi-job/pom.xml
	ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java
	ruoyi-system/pom.xml
	ruoyi-ui/package.json
	ruoyi-ui/src/api/system/user.js
	ruoyi-ui/src/utils/request.js
	ruoyi-ui/src/views/index.vue
	ruoyi-ui/src/views/monitor/job/index.vue
	ruoyi-ui/src/views/system/user/index.vue
疯狂的狮子li %!s(int64=3) %!d(string=hai) anos
pai
achega
1c7d840ff6

+ 3 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java

@@ -113,9 +113,10 @@ public class SysUserController extends BaseController {
         ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
         ajax.put("posts", postService.selectPostAll());
         if (StringUtils.isNotNull(userId)) {
-            ajax.put("user", userService.selectUserById(userId));
+            SysUser sysUser = userService.selectUserById(userId);
+            ajax.put("user", sysUser);
             ajax.put("postIds", postService.selectPostListByUserId(userId));
-            ajax.put("roleIds", roleService.selectRoleListByUserId(userId));
+            ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
         }
         return AjaxResult.success(ajax);
     }

+ 2 - 2
ruoyi-ui/src/api/system/user.js

@@ -1,5 +1,5 @@
 import request from '@/utils/request'
-import { praseStrEmpty } from "@/utils/ruoyi";
+import { parseStrEmpty } from "@/utils/ruoyi";
 
 // 查询用户列表
 export function listUser(query) {
@@ -13,7 +13,7 @@ export function listUser(query) {
 // 查询用户详细
 export function getUser(userId) {
   return request({
-    url: '/system/user/' + praseStrEmpty(userId),
+    url: '/system/user/' + parseStrEmpty(userId),
     method: 'get'
   })
 }

+ 114 - 114
ruoyi-ui/src/components/Crontab/hour.vue

@@ -1,114 +1,114 @@
-<template>
-	<el-form size="small">
-		<el-form-item>
-			<el-radio v-model='radioValue' :label="1">
-				小时,允许的通配符[, - * /]
-			</el-radio>
-		</el-form-item>
-
-		<el-form-item>
-			<el-radio v-model='radioValue' :label="2">
-				周期从
-				<el-input-number v-model='cycle01' :min="0" :max="22" /> -
-				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
-			</el-radio>
-		</el-form-item>
-
-		<el-form-item>
-			<el-radio v-model='radioValue' :label="3">
-				从
-				<el-input-number v-model='average01' :min="0" :max="22" /> 小时开始,每
-				<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次
-			</el-radio>
-		</el-form-item>
-
-		<el-form-item>
-			<el-radio v-model='radioValue' :label="4">
-				指定
-				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
-					<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
-				</el-select>
-			</el-radio>
-		</el-form-item>
-	</el-form>
-</template>
-
-<script>
-export default {
-	data() {
-		return {
-			radioValue: 1,
-			cycle01: 0,
-			cycle02: 1,
-			average01: 0,
-			average02: 1,
-			checkboxList: [],
-			checkNum: this.$options.propsData.check
-		}
-	},
-	name: 'crontab-hour',
-	props: ['check', 'cron'],
-	methods: {
-		// 单选按钮值变化时
-		radioChange() {
-			switch (this.radioValue) {
-				case 1:
-        	this.$emit('update', 'hour', '*')
-        	break;
-				case 2:
-					this.$emit('update', 'hour', this.cycleTotal);
-					break;
-				case 3:
-					this.$emit('update', 'hour', this.averageTotal);
-					break;
-				case 4:
-					this.$emit('update', 'hour', this.checkboxString);
-					break;
-			}
-		},
-		// 周期两个值变化时
-		cycleChange() {
-			if (this.radioValue == '2') {
-				this.$emit('update', 'hour', this.cycleTotal);
-			}
-		},
-		// 平均两个值变化时
-		averageChange() {
-			if (this.radioValue == '3') {
-				this.$emit('update', 'hour', this.averageTotal);
-			}
-		},
-		// checkbox值变化时
-		checkboxChange() {
-			if (this.radioValue == '4') {
-				this.$emit('update', 'hour', this.checkboxString);
-			}
-		}
-	},
-	watch: {
-		'radioValue': 'radioChange',
-		'cycleTotal': 'cycleChange',
-		'averageTotal': 'averageChange',
-		'checkboxString': 'checkboxChange'
-	},
-	computed: {
-		// 计算两个周期值
-		cycleTotal: function () {
-			const cycle01 = this.checkNum(this.cycle01, 0, 22)
-			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
-			return cycle01 + '-' + cycle02;
-		},
-		// 计算平均用到的值
-		averageTotal: function () {
-			const average01 = this.checkNum(this.average01, 0, 22)
-			const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
-			return average01 + '/' + average02;
-		},
-		// 计算勾选的checkbox值合集
-		checkboxString: function () {
-			let str = this.checkboxList.join();
-			return str == '' ? '*' : str;
-		}
-	}
-}
-</script>
+<template>
+	<el-form size="small">
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				小时,允许的通配符[, - * /]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				周期从
+				<el-input-number v-model='cycle01' :min="0" :max="22" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				从
+				<el-input-number v-model='average01' :min="0" :max="22" /> 小时开始,每
+				<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 1,
+			cycle01: 0,
+			cycle02: 1,
+			average01: 0,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-hour',
+	props: ['check', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			switch (this.radioValue) {
+				case 1:
+        	this.$emit('update', 'hour', '*')
+        	break;
+				case 2:
+					this.$emit('update', 'hour', this.cycleTotal);
+					break;
+				case 3:
+					this.$emit('update', 'hour', this.averageTotal);
+					break;
+				case 4:
+					this.$emit('update', 'hour', this.checkboxString);
+					break;
+			}
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '2') {
+				this.$emit('update', 'hour', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'hour', this.averageTotal);
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'hour', this.checkboxString);
+			}
+		}
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'checkboxString': 'checkboxChange'
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, 0, 22)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, 0, 22)
+			const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
+			return average01 + '/' + average02;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 68 - 51
ruoyi-ui/src/components/ImagePreview/index.vue

@@ -1,67 +1,84 @@
 <template>
-    <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[`${realSrc}`]">
-        <div slot="error" class="image-slot">
-          <i class="el-icon-picture-outline"></i>
-        </div>
-    </el-image>
+  <el-image
+    :src="`${realSrc}`"
+    fit="cover"
+    :style="`width:${realWidth};height:${realHeight};`"
+    :preview-src-list="realSrcList"
+  >
+    <div slot="error" class="image-slot">
+      <i class="el-icon-picture-outline"></i>
+    </div>
+  </el-image>
 </template>
 
 <script>
-import { isExternal } from '@/utils/validate'
+import { isExternal } from "@/utils/validate";
 
 export default {
-    name: 'ImagePreview',
-    props: {
-        src: {
-            type: String,
-            required: true
-        },
-        width: {
-            type: [Number, String],
-            default: ''
-        },
-        height: {
-            type: [Number, String],
-            default: ''
-        }
+  name: "ImagePreview",
+  props: {
+    src: {
+      type: String,
+      required: true
+    },
+    width: {
+      type: [Number, String],
+      default: ""
     },
-    computed: {
-        realSrc() {
-            if (isExternal(this.src)) {
-                return this.src
-            }
-            return process.env.VUE_APP_BASE_API + this.src
-        },
-        realWidth() {
-            return typeof this.width == 'string' ? this.width : `${this.width}px`
-        },
-        realHeight() {
-            return typeof this.height == 'string' ? this.height : `${this.height}px`
+    height: {
+      type: [Number, String],
+      default: ""
+    }
+  },
+  computed: {
+    realSrc() {
+      let real_src = this.src.split(",")[0];
+      if (isExternal(real_src)) {
+        return real_src;
+      }
+      return process.env.VUE_APP_BASE_API + real_src;
+    },
+    realSrcList() {
+      let real_src_list = this.src.split(",");
+      let srcList = [];
+      real_src_list.forEach(item => {
+        if (isExternal(item)) {
+          return srcList.push(item);
         }
+        return srcList.push(process.env.VUE_APP_BASE_API + item);
+      });
+      return srcList;
+    },
+    realWidth() {
+      return typeof this.width == "string" ? this.width : `${this.width}px`;
+    },
+    realHeight() {
+      return typeof this.height == "string" ? this.height : `${this.height}px`;
     }
-}
+  },
+};
 </script>
 
 <style lang="scss" scoped>
 .el-image {
-    border-radius: 5px;
-    background-color: #ebeef5;
-    box-shadow: 0 0 5px 1px #ccc;
-    ::v-deep .el-image__inner {
-        transition: all 0.3s;
-        cursor: pointer;
-        &:hover {
-            transform: scale(1.2);
-        }
-    }
-    ::v-deep .image-slot {
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        width: 100%;
-        height: 100%;
-        color: #909399;
-        font-size: 30px;
+  border-radius: 5px;
+  background-color: #ebeef5;
+  box-shadow: 0 0 5px 1px #ccc;
+  ::v-deep .el-image__inner {
+    transition: all 0.3s;
+    cursor: pointer;
+    &:hover {
+      transform: scale(1.2);
     }
+  }
+  ::v-deep .image-slot {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 100%;
+    color: #909399;
+    font-size: 30px;
+  }
 }
 </style>

+ 40 - 3
ruoyi-ui/src/utils/request.js

@@ -4,9 +4,12 @@ import store from '@/store'
 import { getToken } from '@/utils/auth'
 import errorCode from '@/utils/errorCode'
 import { tansParams, blobValidate } from "@/utils/ruoyi";
+import cache from '@/plugins/cache'
 import { saveAs } from 'file-saver'
 
 let downloadLoadingInstance;
+// 是否显示重新登录
+let isReloginShow;
 
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 // 对应国际化资源文件后缀
@@ -23,6 +26,8 @@ const service = axios.create({
 service.interceptors.request.use(config => {
   // 是否需要设置 token
   const isToken = (config.headers || {}).isToken === false
+  // 是否需要防止数据重复提交
+  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
   if (getToken() && !isToken) {
     config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
   }
@@ -33,6 +38,29 @@ service.interceptors.request.use(config => {
     config.params = {};
     config.url = url;
   }
+  if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+    const requestObj = {
+      url: config.url,
+      data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
+      time: new Date().getTime()
+    }
+    const sessionObj = cache.session.getJSON('sessionObj')
+    if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+      cache.session.setJSON('sessionObj', requestObj)
+    } else {
+      const s_url = sessionObj.url;                  // 请求地址
+      const s_data = sessionObj.data;                // 请求数据
+      const s_time = sessionObj.time;                // 请求时间
+      const interval = 1000;                         // 间隔时间(ms),小于此时间视为重复提交
+      if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+        const message = '数据正在处理,请勿重复提交';
+        console.warn(`[${s_url}]: ` + message)
+        return Promise.reject(new Error(message))
+      } else {
+        cache.session.setJSON('sessionObj', requestObj)
+      }
+    }
+  }
   return config
 }, error => {
     console.log(error)
@@ -50,16 +78,25 @@ service.interceptors.response.use(res => {
       return res.data
     }
     if (code === 401) {
-      MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
+      if (!isReloginShow) {
+        isReloginShow = true;
+        MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
           confirmButtonText: '重新登录',
           cancelButtonText: '取消',
           type: 'warning'
         }
       ).then(() => {
+        isReloginShow = false;
         store.dispatch('LogOut').then(() => {
-          location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
+          // 如果是登录页面不需要重新加载
+          if (window.location.hash.indexOf("#/login") != 0) {
+            location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
+          }
         })
-      }).catch(() => {});
+      }).catch(() => {
+        isReloginShow = false;
+      });
+    }
       return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
     } else if (code === 500) {
       Message({

+ 170 - 165
ruoyi-ui/src/utils/ruoyi.js

@@ -1,3 +1,5 @@
+
+
 /**
  * 通用js方法封装处理
  * Copyright (c) 2019 ruoyi
@@ -5,130 +7,133 @@
 
 // 日期格式化
 export function parseTime(time, pattern) {
-	if (arguments.length === 0 || !time) {
-		return null
-	}
-	const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
-	let date
-	if (typeof time === 'object') {
-		date = time
-	} else {
-		if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
-			time = parseInt(time)
-		} else if (typeof time === 'string') {
-			time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm),'');
-		}
-		if ((typeof time === 'number') && (time.toString().length === 10)) {
-			time = time * 1000
-		}
-		date = new Date(time)
-	}
-	const formatObj = {
-		y: date.getFullYear(),
-		m: date.getMonth() + 1,
-		d: date.getDate(),
-		h: date.getHours(),
-		i: date.getMinutes(),
-		s: date.getSeconds(),
-		a: date.getDay()
-	}
-	const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
-		let value = formatObj[key]
-		// Note: getDay() returns 0 on Sunday
-		if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
-		if (result.length > 0 && value < 10) {
-			value = '0' + value
-		}
-		return value || 0
-	})
-	return time_str
+  if (arguments.length === 0 || !time) {
+    return null
+  }
+  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+  let date
+  if (typeof time === 'object') {
+    date = time
+  } else {
+    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+      time = parseInt(time)
+    } else if (typeof time === 'string') {
+      time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
+    }
+    if ((typeof time === 'number') && (time.toString().length === 10)) {
+      time = time * 1000
+    }
+    date = new Date(time)
+  }
+  const formatObj = {
+    y: date.getFullYear(),
+    m: date.getMonth() + 1,
+    d: date.getDate(),
+    h: date.getHours(),
+    i: date.getMinutes(),
+    s: date.getSeconds(),
+    a: date.getDay()
+  }
+  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+    let value = formatObj[key]
+    // Note: getDay() returns 0 on Sunday
+    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+    if (result.length > 0 && value < 10) {
+      value = '0' + value
+    }
+    return value || 0
+  })
+  return time_str
 }
 
 // 表单重置
 export function resetForm(refName) {
-	if (this.$refs[refName]) {
-		this.$refs[refName].resetFields();
-	}
+  if (this.$refs[refName]) {
+    this.$refs[refName].resetFields();
+  }
 }
 
 // 添加日期范围
 export function addDateRange(params, dateRange, propName) {
-	let search = params;
-	search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
-	dateRange = Array.isArray(dateRange) ? dateRange : [];
-	if (typeof (propName) === 'undefined') {
-		search.params['beginTime'] = dateRange[0];
-		search.params['endTime'] = dateRange[1];
-	} else {
-		search.params['begin' + propName] = dateRange[0];
-		search.params['end' + propName] = dateRange[1];
-	}
-	return search;
+  let search = params;
+  search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+  dateRange = Array.isArray(dateRange) ? dateRange : [];
+  if (typeof (propName) === 'undefined') {
+    search.params['beginTime'] = dateRange[0];
+    search.params['endTime'] = dateRange[1];
+  } else {
+    search.params['begin' + propName] = dateRange[0];
+    search.params['end' + propName] = dateRange[1];
+  }
+  return search;
 }
 
-// 回显数据字典
+// 回显数据字典 
 export function selectDictLabel(datas, value) {
-	var actions = [];
-	Object.keys(datas).some((key) => {
-		if (datas[key].value == ('' + value)) {
-			actions.push(datas[key].label);
-			return true;
-		}
-	})
-	return actions.join('');
+  var actions = [];
+  Object.keys(datas).some((key) => {
+    if (datas[key].value == ('' + value)) {
+      actions.push(datas[key].label);
+      return true;
+    }
+  })
+  return actions.join('');
 }
 
 // 回显数据字典(字符串数组)
 export function selectDictLabels(datas, value, separator) {
-	var actions = [];
-	var currentSeparator = undefined === separator ? "," : separator;
-	var temp = value.split(currentSeparator);
-	Object.keys(value.split(currentSeparator)).some((val) => {
-		Object.keys(datas).some((key) => {
-			if (datas[key].value == ('' + temp[val])) {
-				actions.push(datas[key].label + currentSeparator);
-			}
-		})
-	})
-	return actions.join('').substring(0, actions.join('').length - 1);
+  if(value === undefined) {
+    return "";
+  }
+  var actions = [];
+  var currentSeparator = undefined === separator ? "," : separator;
+  var temp = value.split(currentSeparator);
+  Object.keys(value.split(currentSeparator)).some((val) => {
+    Object.keys(datas).some((key) => {
+      if (datas[key].value == ('' + temp[val])) {
+        actions.push(datas[key].label + currentSeparator);
+      }
+    })
+  })
+  return actions.join('').substring(0, actions.join('').length - 1);
 }
 
 // 字符串格式化(%s )
 export function sprintf(str) {
-	var args = arguments, flag = true, i = 1;
-	str = str.replace(/%s/g, function () {
-		var arg = args[i++];
-		if (typeof arg === 'undefined') {
-			flag = false;
-			return '';
-		}
-		return arg;
-	});
-	return flag ? str : '';
+  var args = arguments, flag = true, i = 1;
+  str = str.replace(/%s/g, function () {
+    var arg = args[i++];
+    if (typeof arg === 'undefined') {
+      flag = false;
+      return '';
+    }
+    return arg;
+  });
+  return flag ? str : '';
 }
 
 // 转换字符串,undefined,null等转化为""
-export function praseStrEmpty(str) {
-	if (!str || str == "undefined" || str == "null") {
-		return "";
-	}
-	return str;
+export function parseStrEmpty(str) {
+  if (!str || str == "undefined" || str == "null") {
+    return "";
+  }
+  return str;
 }
 
 // 数据合并
 export function mergeRecursive(source, target) {
-    for (var p in target) {
-        try {
-            if (target[p].constructor == Object) {
-                source[p] = mergeRecursive(source[p], target[p]);
-            } else {
-                source[p] = target[p];
-            }
-        } catch(e) {
-            source[p] = target[p];
-        }
+  for (var p in target) {
+    try {
+      if (target[p].constructor == Object) {
+        source[p] = mergeRecursive(source[p], target[p]);
+      } else {
+        source[p] = target[p];
+      }
+    } catch (e) {
+      source[p] = target[p];
     }
-    return source;
+  }
+  return source;
 };
 
 /**
@@ -139,47 +144,47 @@ export function mergeRecursive(source, target) {
  * @param {*} children 孩子节点字段 默认 'children'
  */
 export function handleTree(data, id, parentId, children) {
-	let config = {
-		id: id || 'id',
-		parentId: parentId || 'parentId',
-		childrenList: children || 'children'
-	};
-
-	var childrenListMap = {};
-	var nodeIds = {};
-	var tree = [];
-
-	for (let d of data) {
-		let parentId = d[config.parentId];
-		if (childrenListMap[parentId] == null) {
-			childrenListMap[parentId] = [];
-		}
-		nodeIds[d[config.id]] = d;
-		childrenListMap[parentId].push(d);
-	}
-
-	for (let d of data) {
-		let parentId = d[config.parentId];
-		if (nodeIds[parentId] == null) {
-			tree.push(d);
-		}
-	}
-
-	for (let t of tree) {
-		adaptToChildrenList(t);
-	}
-
-	function adaptToChildrenList(o) {
-		if (childrenListMap[o[config.id]] !== null) {
-			o[config.childrenList] = childrenListMap[o[config.id]];
-		}
-		if (o[config.childrenList]) {
-			for (let c of o[config.childrenList]) {
-				adaptToChildrenList(c);
-			}
-		}
-	}
-	return tree;
+  let config = {
+    id: id || 'id',
+    parentId: parentId || 'parentId',
+    childrenList: children || 'children'
+  };
+
+  var childrenListMap = {};
+  var nodeIds = {};
+  var tree = [];
+
+  for (let d of data) {
+    let parentId = d[config.parentId];
+    if (childrenListMap[parentId] == null) {
+      childrenListMap[parentId] = [];
+    }
+    nodeIds[d[config.id]] = d;
+    childrenListMap[parentId].push(d);
+  }
+
+  for (let d of data) {
+    let parentId = d[config.parentId];
+    if (nodeIds[parentId] == null) {
+      tree.push(d);
+    }
+  }
+
+  for (let t of tree) {
+    adaptToChildrenList(t);
+  }
+
+  function adaptToChildrenList(o) {
+    if (childrenListMap[o[config.id]] !== null) {
+      o[config.childrenList] = childrenListMap[o[config.id]];
+    }
+    if (o[config.childrenList]) {
+      for (let c of o[config.childrenList]) {
+        adaptToChildrenList(c);
+      }
+    }
+  }
+  return tree;
 }
 
 /**
@@ -187,34 +192,34 @@ export function handleTree(data, id, parentId, children) {
 * @param {*} params  参数
 */
 export function tansParams(params) {
-	let result = ''
-	for (const propName of Object.keys(params)) {
-		const value = params[propName];
-		var part = encodeURIComponent(propName) + "=";
-		if (value !== null && typeof (value) !== "undefined") {
-			if (typeof value === 'object') {
-				for (const key of Object.keys(value)) {
-					if (value[key] !== null && typeof (value[key]) !== 'undefined') {
-						let params = propName + '[' + key + ']';
-						var subPart = encodeURIComponent(params) + "=";
-						result += subPart + encodeURIComponent(value[key]) + "&";
-					}
-				}
-			} else {
-				result += part + encodeURIComponent(value) + "&";
-			}
-		}
-	}
-	return result
+  let result = ''
+  for (const propName of Object.keys(params)) {
+    const value = params[propName];
+    var part = encodeURIComponent(propName) + "=";
+    if (value !== null && typeof (value) !== "undefined") {
+      if (typeof value === 'object') {
+        for (const key of Object.keys(value)) {
+          if (value[key] !== null && typeof (value[key]) !== 'undefined') {
+            let params = propName + '[' + key + ']';
+            var subPart = encodeURIComponent(params) + "=";
+            result += subPart + encodeURIComponent(value[key]) + "&";
+          }
+        }
+      } else {
+        result += part + encodeURIComponent(value) + "&";
+      }
+    }
+  }
+  return result
 }
 
 // 验证是否为blob格式
 export async function blobValidate(data) {
-    try {
-      const text = await data.text();
-      JSON.parse(text);
-      return false;
-    } catch (error) {
-      return true;
-    }
-}
+  try {
+    const text = await data.text();
+    JSON.parse(text);
+    return false;
+  } catch (error) {
+    return true;
+  }
+}

+ 1 - 1
ruoyi-ui/src/views/system/user/index.vue

@@ -495,7 +495,7 @@ export default {
     // 节点单击事件
     handleNodeClick(data) {
       this.queryParams.deptId = data.id;
-      this.getList();
+      this.handleQuery();
     },
     // 用户状态修改
     handleStatusChange(row) {

+ 1 - 0
ruoyi-ui/src/views/tool/gen/editTable.vue

@@ -33,6 +33,7 @@
                 <el-option label="Double" value="Double" />
                 <el-option label="BigDecimal" value="BigDecimal" />
                 <el-option label="Date" value="Date" />
+                <el-option label="Boolean" value="Boolean" />
               </el-select>
             </template>
           </el-table-column>