确定
@@ -112,7 +112,7 @@ import CrontabSecond from "./second.vue";
import CrontabMin from "./min.vue";
import CrontabHour from "./hour.vue";
import CrontabDay from "./day.vue";
-import CrontabMouth from "./mouth.vue";
+import CrontabMonth from "./month.vue";
import CrontabWeek from "./week.vue";
import CrontabYear from "./year.vue";
import CrontabResult from "./result.vue";
@@ -123,12 +123,12 @@ export default {
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
tabActive: 0,
myindex: 0,
- contabValueObj: {
+ crontabValueObj: {
second: "*",
min: "*",
hour: "*",
day: "*",
- mouth: "*",
+ month: "*",
week: "?",
year: "",
},
@@ -142,7 +142,7 @@ export default {
return true;
},
resolveExp() {
- //反解析 表达式
+ // 反解析 表达式
if (this.expression) {
let arr = this.expression.split(" ");
if (arr.length >= 6) {
@@ -152,11 +152,11 @@ export default {
min: arr[1],
hour: arr[2],
day: arr[3],
- mouth: arr[4],
+ month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : "",
};
- this.contabValueObj = {
+ this.crontabValueObj = {
...obj,
};
for (let i in obj) {
@@ -164,7 +164,7 @@ export default {
}
}
} else {
- //没有传入的表达式 则还原
+ // 没有传入的表达式 则还原
this.clearCron();
}
},
@@ -173,122 +173,122 @@ export default {
this.tabActive = index;
},
// 由子组件触发,更改表达式组成的字段值
- updateContabValue(name, value, from) {
- "updateContabValue", name, value, from;
- this.contabValueObj[name] = value;
+ updateCrontabValue(name, value, from) {
+ "updateCrontabValue", name, value, from;
+ this.crontabValueObj[name] = value;
if (from && from !== name) {
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
this.changeRadio(name, value);
}
},
- //赋值到组件
+ // 赋值到组件
changeRadio(name, value) {
- let arr = ["second", "min", "hour", "mouth"],
+ let arr = ["second", "min", "hour", "month"],
refName = "cron" + name,
- insVlaue;
+ insValue;
if (!this.$refs[refName]) return;
if (arr.includes(name)) {
if (value === "*") {
- insVlaue = 1;
+ insValue = 1;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1];
- insVlaue = 2;
+ insValue = 2;
} else if (value.indexOf("/") > -1) {
let indexArr = value.split("/");
isNaN(indexArr[0])
? (this.$refs[refName].average01 = 0)
: (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1];
- insVlaue = 3;
+ insValue = 3;
} else {
- insVlaue = 4;
+ insValue = 4;
this.$refs[refName].checkboxList = value.split(",");
}
} else if (name == "day") {
if (value === "*") {
- insVlaue = 1;
+ insValue = 1;
} else if (value == "?") {
- insVlaue = 2;
+ insValue = 2;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1];
- insVlaue = 3;
+ insValue = 3;
} else if (value.indexOf("/") > -1) {
let indexArr = value.split("/");
isNaN(indexArr[0])
? (this.$refs[refName].average01 = 0)
: (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1];
- insVlaue = 4;
+ insValue = 4;
} else if (value.indexOf("W") > -1) {
let indexArr = value.split("W");
isNaN(indexArr[0])
? (this.$refs[refName].workday = 0)
: (this.$refs[refName].workday = indexArr[0]);
- insVlaue = 5;
+ insValue = 5;
} else if (value === "L") {
- insVlaue = 6;
+ insValue = 6;
} else {
this.$refs[refName].checkboxList = value.split(",");
- insVlaue = 7;
+ insValue = 7;
}
} else if (name == "week") {
if (value === "*") {
- insVlaue = 1;
+ insValue = 1;
} else if (value == "?") {
- insVlaue = 2;
+ insValue = 2;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1];
- insVlaue = 3;
+ insValue = 3;
} else if (value.indexOf("#") > -1) {
let indexArr = value.split("#");
isNaN(indexArr[0])
? (this.$refs[refName].average01 = 1)
: (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1];
- insVlaue = 4;
+ insValue = 4;
} else if (value.indexOf("L") > -1) {
let indexArr = value.split("L");
isNaN(indexArr[0])
? (this.$refs[refName].weekday = 1)
: (this.$refs[refName].weekday = indexArr[0]);
- insVlaue = 5;
+ insValue = 5;
} else {
this.$refs[refName].checkboxList = value.split(",");
- insVlaue = 7;
+ insValue = 7;
}
} else if (name == "year") {
if (value == "") {
- insVlaue = 1;
+ insValue = 1;
} else if (value == "*") {
- insVlaue = 2;
+ insValue = 2;
} else if (value.indexOf("-") > -1) {
- insVlaue = 3;
+ insValue = 3;
} else if (value.indexOf("/") > -1) {
- insVlaue = 4;
+ insValue = 4;
} else {
this.$refs[refName].checkboxList = value.split(",");
- insVlaue = 5;
+ insValue = 5;
}
}
- this.$refs[refName].radioValue = insVlaue;
+ this.$refs[refName].radioValue = insValue;
},
// 表单选项的子组件校验数字格式(通过-props传递)
checkNumber(value, minLimit, maxLimit) {
- //检查必须为整数
+ // 检查必须为整数
value = Math.floor(value);
if (value < minLimit) {
value = minLimit;
@@ -303,29 +303,29 @@ export default {
},
// 填充表达式
submitFill() {
- this.$emit("fill", this.contabValueString);
+ this.$emit("fill", this.crontabValueString);
this.hidePopup();
},
clearCron() {
// 还原选择项
("准备还原");
- this.contabValueObj = {
+ this.crontabValueObj = {
second: "*",
min: "*",
hour: "*",
day: "*",
- mouth: "*",
+ month: "*",
week: "?",
year: "",
};
- for (let j in this.contabValueObj) {
- this.changeRadio(j, this.contabValueObj[j]);
+ for (let j in this.crontabValueObj) {
+ this.changeRadio(j, this.crontabValueObj[j]);
}
},
},
computed: {
- contabValueString: function() {
- let obj = this.contabValueObj;
+ crontabValueString: function() {
+ let obj = this.crontabValueObj;
let str =
obj.second +
" " +
@@ -335,7 +335,7 @@ export default {
" " +
obj.day +
" " +
- obj.mouth +
+ obj.month +
" " +
obj.week +
(obj.year == "" ? "" : " " + obj.year);
@@ -347,7 +347,7 @@ export default {
CrontabMin,
CrontabHour,
CrontabDay,
- CrontabMouth,
+ CrontabMonth,
CrontabWeek,
CrontabYear,
CrontabResult,
diff --git a/ruoyi-ui/src/components/Crontab/mouth.vue b/ruoyi-ui/src/components/Crontab/month.vue
similarity index 81%
rename from ruoyi-ui/src/components/Crontab/mouth.vue
rename to ruoyi-ui/src/components/Crontab/month.vue
index 7d0e0c84a..619d1e791 100644
--- a/ruoyi-ui/src/components/Crontab/mouth.vue
+++ b/ruoyi-ui/src/components/Crontab/month.vue
@@ -46,56 +46,56 @@ export default {
checkNum: this.check
}
},
- name: 'crontab-mouth',
+ name: 'crontab-month',
props: ['check', 'cron'],
methods: {
// 单选按钮值变化时
radioChange() {
if (this.radioValue === 1) {
- this.$emit('update', 'mouth', '*');
+ this.$emit('update', 'month', '*');
this.$emit('update', 'year', '*');
} else {
if (this.cron.day === '*') {
- this.$emit('update', 'day', '0', 'mouth');
+ this.$emit('update', 'day', '0', 'month');
}
if (this.cron.hour === '*') {
- this.$emit('update', 'hour', '0', 'mouth');
+ this.$emit('update', 'hour', '0', 'month');
}
if (this.cron.min === '*') {
- this.$emit('update', 'min', '0', 'mouth');
+ this.$emit('update', 'min', '0', 'month');
}
if (this.cron.second === '*') {
- this.$emit('update', 'second', '0', 'mouth');
+ this.$emit('update', 'second', '0', 'month');
}
}
switch (this.radioValue) {
case 2:
- this.$emit('update', 'mouth', this.cycle01 + '-' + this.cycle02);
+ this.$emit('update', 'month', this.cycle01 + '-' + this.cycle02);
break;
case 3:
- this.$emit('update', 'mouth', this.average01 + '/' + this.average02);
+ this.$emit('update', 'month', this.average01 + '/' + this.average02);
break;
case 4:
- this.$emit('update', 'mouth', this.checkboxString);
+ this.$emit('update', 'month', this.checkboxString);
break;
}
},
// 周期两个值变化时
cycleChange() {
if (this.radioValue == '2') {
- this.$emit('update', 'mouth', this.cycleTotal);
+ this.$emit('update', 'month', this.cycleTotal);
}
},
// 平均两个值变化时
averageChange() {
if (this.radioValue == '3') {
- this.$emit('update', 'mouth', this.averageTotal);
+ this.$emit('update', 'month', this.averageTotal);
}
},
// checkbox值变化时
checkboxChange() {
if (this.radioValue == '4') {
- this.$emit('update', 'mouth', this.checkboxString);
+ this.$emit('update', 'month', this.checkboxString);
}
}
},
@@ -125,4 +125,4 @@ export default {
}
}
}
-
\ No newline at end of file
+
diff --git a/ruoyi-ui/src/components/Crontab/result.vue b/ruoyi-ui/src/components/Crontab/result.vue
index 0e75b9ee2..07b963b79 100644
--- a/ruoyi-ui/src/components/Crontab/result.vue
+++ b/ruoyi-ui/src/components/Crontab/result.vue
@@ -37,7 +37,7 @@ export default {
// 获取当前时间精确至[年、月、日、时、分、秒]
let nTime = new Date();
let nYear = nTime.getFullYear();
- let nMouth = nTime.getMonth() + 1;
+ let nMonth = nTime.getMonth() + 1;
let nDay = nTime.getDate();
let nHour = nTime.getHours();
let nMin = nTime.getMinutes();
@@ -47,7 +47,7 @@ export default {
this.getMinArr(ruleArr[1]);
this.getHourArr(ruleArr[2]);
this.getDayArr(ruleArr[3]);
- this.getMouthArr(ruleArr[4]);
+ this.getMonthArr(ruleArr[4]);
this.getWeekArr(ruleArr[5]);
this.getYearArr(ruleArr[6], nYear);
// 将获取到的数组赋值-方便使用
@@ -62,7 +62,7 @@ export default {
let mIdx = this.getIndex(mDate, nMin);
let hIdx = this.getIndex(hDate, nHour);
let DIdx = this.getIndex(DDate, nDay);
- let MIdx = this.getIndex(MDate, nMouth);
+ let MIdx = this.getIndex(MDate, nMonth);
let YIdx = this.getIndex(YDate, nYear);
// 重置月日时分秒的函数(后面用的比较多)
const resetSecond = function () {
@@ -84,17 +84,17 @@ export default {
nDay = DDate[DIdx]
resetHour();
}
- const resetMouth = function () {
+ const resetMonth = function () {
MIdx = 0;
- nMouth = MDate[MIdx]
+ nMonth = MDate[MIdx]
resetDay();
}
// 如果当前年份不为数组中当前值
if (nYear !== YDate[YIdx]) {
- resetMouth();
+ resetMonth();
}
// 如果当前月份不为数组中当前值
- if (nMouth !== MDate[MIdx]) {
+ if (nMonth !== MDate[MIdx]) {
resetDay();
}
// 如果当前“日”不为数组中当前值
@@ -114,12 +114,12 @@ export default {
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
let YY = YDate[Yi];
// 如果到达最大值时
- if (nMouth > MDate[MDate.length - 1]) {
- resetMouth();
+ if (nMonth > MDate[MDate.length - 1]) {
+ resetMonth();
continue;
}
// 循环月份数组
- goMouth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
+ goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
// 赋值、方便后面运算
let MM = MDate[Mi];
MM = MM < 10 ? '0' + MM : MM;
@@ -127,7 +127,7 @@ export default {
if (nDay > DDate[DDate.length - 1]) {
resetDay();
if (Mi == MDate.length - 1) {
- resetMouth();
+ resetMonth();
continue goYear;
}
continue;
@@ -144,10 +144,10 @@ export default {
if (Di == DDate.length - 1) {
resetDay();
if (Mi == MDate.length - 1) {
- resetMouth();
+ resetMonth();
continue goYear;
}
- continue goMouth;
+ continue goMonth;
}
continue;
}
@@ -155,11 +155,11 @@ export default {
// 判断日期的合法性,不合法的话也是跳出当前循环
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
resetDay();
- continue goMouth;
+ continue goMonth;
}
// 如果日期规则中有值时
if (this.dayRule == 'lastDay') {
- //如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
+ // 如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
@@ -169,7 +169,7 @@ export default {
}
}
} else if (this.dayRule == 'workDay') {
- //校验并调整如果是2月30号这种日期传进来时需调整至正常月底
+ // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--;
@@ -180,15 +180,15 @@ export default {
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
// 当星期日时
if (thisWeek == 0) {
- //先找下一个日,并判断是否为月底
+ // 先找下一个日,并判断是否为月底
DD++;
thisDD = DD < 10 ? '0' + DD : DD;
- //判断下一日已经不是合法日期
+ // 判断下一日已经不是合法日期
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD -= 3;
}
} else if (thisWeek == 6) {
- //当星期6时只需判断不是1号就可进行操作
+ // 当星期6时只需判断不是1号就可进行操作
if (this.dayRuleSup !== 1) {
DD--;
} else {
@@ -196,25 +196,25 @@ export default {
}
}
} else if (this.dayRule == 'weekDay') {
- //如果指定了是星期几
- //获取当前日期是属于星期几
+ // 如果指定了是星期几
+ // 获取当前日期是属于星期几
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
- //校验当前星期是否在星期池(dayRuleSup)中
+ // 校验当前星期是否在星期池(dayRuleSup)中
if (Array.indexOf(this.dayRuleSup, thisWeek) < 0) {
// 如果到达最大值时
if (Di == DDate.length - 1) {
resetDay();
if (Mi == MDate.length - 1) {
- resetMouth();
+ resetMonth();
continue goYear;
}
- continue goMouth;
+ continue goMonth;
}
continue;
}
} else if (this.dayRule == 'assWeek') {
- //如果指定了是第几周的星期几
- //获取每月1号是属于星期几
+ // 如果指定了是第几周的星期几
+ // 获取每月1号是属于星期几
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
if (this.dayRuleSup[1] >= thisWeek) {
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
@@ -222,17 +222,17 @@ export default {
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
}
} else if (this.dayRule == 'lastWeek') {
- //如果指定了每月最后一个星期几
- //校验并调整如果是2月30号这种日期传进来时需调整至正常月底
+ // 如果指定了每月最后一个星期几
+ // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--;
thisDD = DD < 10 ? '0' + DD : DD;
}
}
- //获取月末最后一天是星期几
+ // 获取月末最后一天是星期几
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
- //找到要求中最近的那个星期几
+ // 找到要求中最近的那个星期几
if (this.dayRuleSup < thisWeek) {
DD -= thisWeek - this.dayRuleSup;
} else if (this.dayRuleSup > thisWeek) {
@@ -254,10 +254,10 @@ export default {
if (Di == DDate.length - 1) {
resetDay();
if (Mi == MDate.length - 1) {
- resetMouth();
+ resetMonth();
continue goYear;
}
- continue goMouth;
+ continue goMonth;
}
continue goDay;
}
@@ -277,10 +277,10 @@ export default {
if (Di == DDate.length - 1) {
resetDay();
if (Mi == MDate.length - 1) {
- resetMouth();
+ resetMonth();
continue goYear;
}
- continue goMouth;
+ continue goMonth;
}
continue goDay;
}
@@ -296,9 +296,9 @@ export default {
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
nums++;
}
- //如果条数满了就退出循环
+ // 如果条数满了就退出循环
if (nums == 5) break goYear;
- //如果到达最大值时
+ // 如果到达最大值时
if (si == sDate.length - 1) {
resetSecond();
if (mi == mDate.length - 1) {
@@ -308,10 +308,10 @@ export default {
if (Di == DDate.length - 1) {
resetDay();
if (Mi == MDate.length - 1) {
- resetMouth();
+ resetMonth();
continue goYear;
}
- continue goMouth;
+ continue goMonth;
}
continue goDay;
}
@@ -323,7 +323,7 @@ export default {
} //goMin
}//goHour
}//goDay
- }//goMouth
+ }//goMonth
}
// 判断100年内的结果条数
if (resultArr.length == 0) {
@@ -339,7 +339,7 @@ export default {
},
- //用于计算某位数字在数组中的索引
+ // 用于计算某位数字在数组中的索引
getIndex(arr, value) {
if (value <= arr[0] || value > arr[arr.length - 1]) {
return 0;
@@ -365,7 +365,7 @@ export default {
}
},
// 获取"月"数组
- getMouthArr(rule) {
+ getMonthArr(rule) {
this.dateArr[4] = this.getOrderArr(1, 12);
if (rule.indexOf('-') >= 0) {
this.dateArr[4] = this.getCycleArr(rule, 12, false)
@@ -377,7 +377,7 @@ export default {
},
// 获取"日"数组-主要为日期规则
getWeekArr(rule) {
- //只有当日期规则的两个值均为“”时则表达日期是有选项的
+ // 只有当日期规则的两个值均为“”时则表达日期是有选项的
if (this.dayRule == '' && this.dayRuleSup == '') {
if (rule.indexOf('-') >= 0) {
this.dayRule = 'weekDay';
@@ -401,7 +401,7 @@ export default {
this.dayRule = 'weekDay';
this.dayRuleSup = this.getAssignArr(rule)
}
- //如果weekDay时将7调整为0【week值0即是星期日】
+ // 如果weekDay时将7调整为0【week值0即是星期日】
if (this.dayRule == 'weekDay') {
for (let i = 0; i < this.dayRuleSup.length; i++) {
if (this.dayRuleSup[i] == 7) {
@@ -502,7 +502,7 @@ export default {
},
// 根据规则返回一个具有周期性的数组
getCycleArr(rule, limit, status) {
- //status--表示是否从0开始(则从1开始)
+ // status--表示是否从0开始(则从1开始)
let arr = [];
let cycleArr = rule.split('-');
let min = Number(cycleArr[0]);
@@ -520,7 +520,7 @@ export default {
arr.sort(this.compare)
return arr;
},
- //比较数字大小(用于Array.sort)
+ // 比较数字大小(用于Array.sort)
compare(value1, value2) {
if (value2 - value1 > 0) {
return -1;
@@ -563,4 +563,4 @@ export default {
}
}
-
\ No newline at end of file
+
diff --git a/ruoyi-ui/src/components/Crontab/second.vue b/ruoyi-ui/src/components/Crontab/second.vue
index 0776e7597..0fdf3386d 100644
--- a/ruoyi-ui/src/components/Crontab/second.vue
+++ b/ruoyi-ui/src/components/Crontab/second.vue
@@ -86,7 +86,7 @@ export default {
}
},
othChange() {
- //反解析
+ // 反解析
let ins = this.cron.second
('反解析 second', ins);
if (ins === '*') {
@@ -130,4 +130,4 @@ export default {
}
}
}
-
\ No newline at end of file
+
diff --git a/ruoyi-ui/src/components/Crontab/week.vue b/ruoyi-ui/src/components/Crontab/week.vue
index cb4c542ba..5ad949d6b 100644
--- a/ruoyi-ui/src/components/Crontab/week.vue
+++ b/ruoyi-ui/src/components/Crontab/week.vue
@@ -71,8 +71,8 @@ export default {
this.$emit('update', 'week', '*');
this.$emit('update', 'year', '*');
} else {
- if (this.cron.mouth === '*') {
- this.$emit('update', 'mouth', '0', 'week');
+ if (this.cron.month === '*') {
+ this.$emit('update', 'month', '0', 'week');
}
if (this.cron.day === '*') {
this.$emit('update', 'day', '0', 'week');
@@ -164,4 +164,4 @@ export default {
}
}
}
-
\ No newline at end of file
+
diff --git a/ruoyi-ui/src/components/Crontab/year.vue b/ruoyi-ui/src/components/Crontab/year.vue
index 8cb886f76..800dfa522 100644
--- a/ruoyi-ui/src/components/Crontab/year.vue
+++ b/ruoyi-ui/src/components/Crontab/year.vue
@@ -55,12 +55,12 @@ export default {
}
},
name: 'crontab-year',
- props: ['check', 'mouth', 'cron'],
+ props: ['check', 'month', 'cron'],
methods: {
// 单选按钮值变化时
radioChange() {
- if (this.cron.mouth === '*') {
- this.$emit('update', 'mouth', '0', 'year');
+ if (this.cron.month === '*') {
+ this.$emit('update', 'month', '0', 'year');
}
if (this.cron.day === '*') {
this.$emit('update', 'day', '0', 'year');
@@ -141,4 +141,4 @@ export default {
this.fullYear = Number(new Date().getFullYear());
}
}
-
\ No newline at end of file
+
diff --git a/ruoyi-ui/src/components/DictData/index.js b/ruoyi-ui/src/components/DictData/index.js
new file mode 100644
index 000000000..c2a0359cc
--- /dev/null
+++ b/ruoyi-ui/src/components/DictData/index.js
@@ -0,0 +1,21 @@
+import Vue from 'vue'
+import DataDict from '@/utils/dict'
+import { getDicts as getDicts } from '@/api/system/dict/data'
+
+function install() {
+ Vue.use(DataDict, {
+ metas: {
+ '*': {
+ labelField: 'dictLabel',
+ valueField: 'dictValue',
+ request(dictMeta) {
+ return getDicts(dictMeta.type).then(res => res.data)
+ },
+ },
+ },
+ })
+}
+
+export default {
+ install,
+}
\ No newline at end of file
diff --git a/ruoyi-ui/src/components/DictTag/index.vue b/ruoyi-ui/src/components/DictTag/index.vue
index 742f38c0c..4c196c489 100644
--- a/ruoyi-ui/src/components/DictTag/index.vue
+++ b/ruoyi-ui/src/components/DictTag/index.vue
@@ -1,22 +1,23 @@
-
+
{{ item.dictLabel }}{{ item.label }}
- {{ item.dictLabel }}
+ {{ item.label }}
diff --git a/ruoyi-ui/src/components/ImageUpload/index.vue b/ruoyi-ui/src/components/ImageUpload/index.vue
index ba088b93a..fcf010dfd 100644
--- a/ruoyi-ui/src/components/ImageUpload/index.vue
+++ b/ruoyi-ui/src/components/ImageUpload/index.vue
@@ -18,7 +18,7 @@
>
-
+
请上传
@@ -113,8 +113,10 @@ export default {
// 删除图片
handleRemove(file, fileList) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
- this.fileList.splice(findex, 1);
- this.$emit("input", this.listToString(this.fileList));
+ if(findex > -1) {
+ this.fileList.splice(findex, 1);
+ this.$emit("input", this.listToString(this.fileList));
+ }
},
// 上传成功回调
handleUploadSuccess(res) {
@@ -187,24 +189,23 @@ export default {
for (let i in list) {
strs += list[i].url + separator;
}
- return strs != "" ? strs.substr(0, strs.length - 1) : "";
- },
- },
+ return strs != '' ? strs.substr(0, strs.length - 1) : '';
+ }
+ }
};
+
\ No newline at end of file
diff --git a/ruoyi-ui/src/views/system/user/profile/userInfo.vue b/ruoyi-ui/src/views/system/user/profile/userInfo.vue
index bde242325..854b819e4 100644
--- a/ruoyi-ui/src/views/system/user/profile/userInfo.vue
+++ b/ruoyi-ui/src/views/system/user/profile/userInfo.vue
@@ -2,7 +2,7 @@
-
+
@@ -62,7 +62,7 @@ export default {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserProfile(this.user).then(response => {
- this.msgSuccess("修改成功");
+ this.$modal.msgSuccess("修改成功");
});
}
});
diff --git a/ruoyi-ui/src/views/tool/build/index.vue b/ruoyi-ui/src/views/tool/build/index.vue
index 1f8b3616b..0a1d94c69 100644
--- a/ruoyi-ui/src/views/tool/build/index.vue
+++ b/ruoyi-ui/src/views/tool/build/index.vue
@@ -137,23 +137,13 @@
\ No newline at end of file
+
diff --git a/ruoyi/pom.xml b/ruoyi/pom.xml
index cb30d2dbf..fc8b2c234 100644
--- a/ruoyi/pom.xml
+++ b/ruoyi/pom.xml
@@ -5,7 +5,7 @@
ruoyi-vue-plus
com.ruoyi
- 3.1.0
+ 3.2.0
4.0.0
jar
@@ -84,6 +84,11 @@
knife4j-spring-boot-starter
+
+ io.swagger
+ swagger-annotations
+
+
mysql
diff --git a/ruoyi/src/main/java/com/ruoyi/common/annotation/Log.java b/ruoyi/src/main/java/com/ruoyi/common/annotation/Log.java
index eb05dc7ce..ca02c6c4a 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/annotation/Log.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/annotation/Log.java
@@ -38,4 +38,9 @@ public @interface Log
* 是否保存请求的参数
*/
public boolean isSaveRequestData() default true;
+
+ /**
+ * 是否保存响应的参数
+ */
+ public boolean isSaveResponseData() default true;
}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java b/ruoyi/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
index c2bbee476..512f4bf52 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
@@ -20,10 +20,15 @@ import java.util.concurrent.TimeUnit;
public @interface RepeatSubmit {
/**
- * 默认使用全局配置
+ * 间隔时间(ms),小于此时间视为重复提交
*/
- int intervalTime() default 0;
+ int interval() default 5000;
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
+ /**
+ * 提示消息
+ */
+ String message() default "不允许重复提交,请稍后再试";
+
}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java b/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java
index 1fa328e45..072fb403c 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java
@@ -44,16 +44,21 @@ public class GenConstants
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "double", "decimal" };
+ /** 页面不需要添加字段 */
+ public static final String[] COLUMNNAME_NOT_ADD = { "create_by", "create_time", "del_flag", "update_by",
+ "update_time", "version" };
+
/** 页面不需要编辑字段 */
- public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
+ public static final String[] COLUMNNAME_NOT_EDIT = { "create_by", "create_time", "del_flag", "update_by",
+ "update_time", "version" };
/** 页面不需要显示的列表字段 */
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
- "update_time" };
+ "update_time", "version" };
/** 页面不需要查询字段 */
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
- "update_time", "remark" };
+ "update_time", "remark", "version" };
/** Entity基类字段 */
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
index 72d624a9c..a5a92f4d3 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
@@ -1,5 +1,6 @@
package com.ruoyi.common.core.domain;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -62,6 +63,7 @@ public class BaseEntity implements Serializable {
/**
* 请求参数
*/
+ @JsonIgnore
@ApiModelProperty(value = "请求参数")
private Map params = new HashMap<>();
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/dto/OperLogDTO.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/dto/OperLogDTO.java
new file mode 100644
index 000000000..f5132efe6
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/dto/OperLogDTO.java
@@ -0,0 +1,107 @@
+package com.ruoyi.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 操作日志记录表 oper_log
+ *
+ * @author ruoyi
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class OperLogDTO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 日志主键
+ */
+ private Long operId;
+
+ /**
+ * 操作模块
+ */
+ private String title;
+
+ /**
+ * 业务类型(0其它 1新增 2修改 3删除)
+ */
+ private Integer businessType;
+
+ /**
+ * 业务类型数组
+ */
+ private Integer[] businessTypes;
+
+ /**
+ * 请求方法
+ */
+ private String method;
+
+ /**
+ * 请求方式
+ */
+ private String requestMethod;
+
+ /**
+ * 操作类别(0其它 1后台用户 2手机端用户)
+ */
+ private Integer operatorType;
+
+ /**
+ * 操作人员
+ */
+ private String operName;
+
+ /**
+ * 部门名称
+ */
+ private String deptName;
+
+ /**
+ * 请求url
+ */
+ private String operUrl;
+
+ /**
+ * 操作地址
+ */
+ private String operIp;
+
+ /**
+ * 操作地点
+ */
+ private String operLocation;
+
+ /**
+ * 请求参数
+ */
+ private String operParam;
+
+ /**
+ * 返回参数
+ */
+ private String jsonResult;
+
+ /**
+ * 操作状态(0正常 1异常)
+ */
+ private Integer status;
+
+ /**
+ * 错误消息
+ */
+ private String errorMsg;
+
+ /**
+ * 操作时间
+ */
+ private Date operTime;
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
index e8bc0f156..89ee1c1bc 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictData.java
@@ -90,7 +90,7 @@ public class SysDictData implements Serializable {
* 状态(0正常 1停用)
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
- @ExcelDictFormat(dictType = "sys_common_status")
+ @ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
/**
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
index 1108671d8..35d9a60fe 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysDictType.java
@@ -57,7 +57,7 @@ public class SysDictType implements Serializable {
* 状态(0正常 1停用)
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
- @ExcelDictFormat(dictType = "sys_common_status")
+ @ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
/**
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
index 6fc86418e..d2c5bbf94 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
@@ -66,6 +66,11 @@ public class SysMenu implements Serializable {
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
private String component;
+ /**
+ * 路由参数
+ */
+ private String query;
+
/**
* 是否为外链(0是 1否)
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
index 6e44a3b95..770998126 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
@@ -91,11 +91,6 @@ public class SysUser implements Serializable {
return password;
}
- /**
- * 盐加密
- */
- private String salt;
-
/**
* 帐号状态(0正常 1停用)
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
deleted file mode 100644
index 23a25e045..000000000
--- a/ruoyi/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package com.ruoyi.common.core.redis;
-
-import com.google.common.collect.Lists;
-import org.redisson.api.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-/**
- * spring redis 工具类
- *
- * @author shenxinquan
- * @see com.ruoyi.common.utils.RedisUtils
- * @deprecated 3.2.0 删除此类
- **/
-@SuppressWarnings(value = {"unchecked", "rawtypes"})
-@Component
-@Deprecated
-public class RedisCache {
-
- @Autowired
- private RedissonClient redissonClient;
-
- /**
- * 发布通道消息
- *
- * @param channelKey 通道key
- * @param msg 发送数据
- * @param consumer 自定义处理
- */
- public void publish(String channelKey, T msg, Consumer consumer) {
- RTopic topic = redissonClient.getTopic(channelKey);
- topic.publish(msg);
- consumer.accept(msg);
- }
-
- public void publish(String channelKey, T msg) {
- RTopic topic = redissonClient.getTopic(channelKey);
- topic.publish(msg);
- }
-
- /**
- * 订阅通道接收消息
- *
- * @param channelKey 通道key
- * @param clazz 消息类型
- * @param consumer 自定义处理
- */
- public void subscribe(String channelKey, Class clazz, Consumer consumer) {
- RTopic topic = redissonClient.getTopic(channelKey);
- topic.addListener(clazz, (channel, msg) -> consumer.accept(msg));
- }
-
- /**
- * 缓存基本的对象,Integer、String、实体类等
- *
- * @param key 缓存的键值
- * @param value 缓存的值
- */
- public void setCacheObject(final String key, final T value) {
- redissonClient.getBucket(key).set(value);
- }
-
- /**
- * 缓存基本的对象,Integer、String、实体类等
- *
- * @param key 缓存的键值
- * @param value 缓存的值
- * @param timeout 时间
- * @param timeUnit 时间颗粒度
- */
- public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
- RBucket result = redissonClient.getBucket(key);
- result.set(value);
- result.expire(timeout, timeUnit);
- }
-
- /**
- * 设置有效时间
- *
- * @param key Redis键
- * @param timeout 超时时间
- * @return true=设置成功;false=设置失败
- */
- public boolean expire(final String key, final long timeout) {
- return expire(key, timeout, TimeUnit.SECONDS);
- }
-
- /**
- * 设置有效时间
- *
- * @param key Redis键
- * @param timeout 超时时间
- * @param unit 时间单位
- * @return true=设置成功;false=设置失败
- */
- public boolean expire(final String key, final long timeout, final TimeUnit unit) {
- RBucket rBucket = redissonClient.getBucket(key);
- return rBucket.expire(timeout, unit);
- }
-
- /**
- * 获得缓存的基本对象。
- *
- * @param key 缓存键值
- * @return 缓存键值对应的数据
- */
- public T getCacheObject(final String key) {
- RBucket rBucket = redissonClient.getBucket(key);
- return rBucket.get();
- }
-
- /**
- * 删除单个对象
- *
- * @param key
- */
- public boolean deleteObject(final String key) {
- return redissonClient.getBucket(key).delete();
- }
-
- /* */
-
- /**
- * 删除集合对象
- *
- * @param collection 多个对象
- * @return
- */
- public void deleteObject(final Collection collection) {
- RBatch batch = redissonClient.createBatch();
- collection.forEach(t->{
- batch.getBucket(t.toString()).deleteAsync();
- });
- batch.execute();
- }
-
- /**
- * 缓存List数据
- *
- * @param key 缓存的键值
- * @param dataList 待缓存的List数据
- * @return 缓存的对象
- */
- public boolean setCacheList(final String key, final List dataList) {
- RList rList = redissonClient.getList(key);
- return rList.addAll(dataList);
- }
-
- /**
- * 获得缓存的list对象
- *
- * @param key 缓存的键值
- * @return 缓存键值对应的数据
- */
- public List getCacheList(final String key) {
- RList rList = redissonClient.getList(key);
- return rList.readAll();
- }
-
- /**
- * 缓存Set
- *
- * @param key 缓存键值
- * @param dataSet 缓存的数据
- * @return 缓存数据的对象
- */
- public boolean setCacheSet(final String key, final Set dataSet) {
- RSet rSet = redissonClient.getSet(key);
- return rSet.addAll(dataSet);
- }
-
- /**
- * 获得缓存的set
- *
- * @param key
- * @return
- */
- public Set getCacheSet(final String key) {
- RSet rSet = redissonClient.getSet(key);
- return rSet.readAll();
- }
-
- /**
- * 缓存Map
- *
- * @param key
- * @param dataMap
- */
- public void setCacheMap(final String key, final Map dataMap) {
- if (dataMap != null) {
- RMap rMap = redissonClient.getMap(key);
- rMap.putAll(dataMap);
- }
- }
-
- /**
- * 获得缓存的Map
- *
- * @param key
- * @return
- */
- public Map getCacheMap(final String key) {
- RMap rMap = redissonClient.getMap(key);
- return rMap.getAll(rMap.keySet());
- }
-
- /**
- * 往Hash中存入数据
- *
- * @param key Redis键
- * @param hKey Hash键
- * @param value 值
- */
- public void setCacheMapValue(final String key, final String hKey, final T value) {
- RMap rMap = redissonClient.getMap(key);
- rMap.put(hKey, value);
- }
-
- /**
- * 获取Hash中的数据
- *
- * @param key Redis键
- * @param hKey Hash键
- * @return Hash中的对象
- */
- public T getCacheMapValue(final String key, final String hKey) {
- RMap rMap = redissonClient.getMap(key);
- return rMap.get(hKey);
- }
-
- /**
- * 获取多个Hash中的数据
- *
- * @param key Redis键
- * @param hKeys Hash键集合
- * @return Hash对象集合
- */
- public Map getMultiCacheMapValue(final String key, final Set hKeys) {
- RMap rMap = redissonClient.getMap(key);
- return rMap.getAll(hKeys);
- }
-
- /**
- * 获得缓存的基本对象列表
- *
- * @param pattern 字符串前缀
- * @return 对象列表
- */
- public Collection keys(final String pattern) {
- Iterable iterable = redissonClient.getKeys().getKeysByPattern(pattern);
- return Lists.newArrayList(iterable);
- }
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/service/LogininforService.java b/ruoyi/src/main/java/com/ruoyi/common/core/service/LogininforService.java
new file mode 100644
index 000000000..1bf34d526
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/service/LogininforService.java
@@ -0,0 +1,9 @@
+package com.ruoyi.common.core.service;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface LogininforService {
+
+ void recordLogininfor(String username, String status, String message,
+ HttpServletRequest request, Object... args);
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/service/OperLogService.java b/ruoyi/src/main/java/com/ruoyi/common/core/service/OperLogService.java
new file mode 100644
index 000000000..71e5647ee
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/service/OperLogService.java
@@ -0,0 +1,9 @@
+package com.ruoyi.common.core.service;
+
+import com.ruoyi.common.core.domain.dto.OperLogDTO;
+import org.springframework.scheduling.annotation.Async;
+
+public interface OperLogService {
+ @Async
+ void recordOper(OperLogDTO operLogDTO);
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/service/TokenService.java b/ruoyi/src/main/java/com/ruoyi/common/core/service/TokenService.java
new file mode 100644
index 000000000..d9a9f0acf
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/core/service/TokenService.java
@@ -0,0 +1,69 @@
+package com.ruoyi.common.core.service;
+
+import com.ruoyi.common.core.domain.model.LoginUser;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * token验证处理
+ *
+ * @author Lion Li
+ */
+public interface TokenService {
+
+ /**
+ * 获取用户身份信息
+ *
+ * @return 用户信息
+ */
+ LoginUser getLoginUser(HttpServletRequest request);
+
+ /**
+ * 设置用户身份信息
+ */
+ void setLoginUser(LoginUser loginUser);
+
+ /**
+ * 删除用户身份信息
+ */
+ void delLoginUser(String token);
+
+ /**
+ * 创建令牌
+ *
+ * @param loginUser 用户信息
+ * @return 令牌
+ */
+ String createToken(LoginUser loginUser);
+
+ /**
+ * 验证令牌有效期,相差不足20分钟,自动刷新缓存
+ *
+ * @param loginUser
+ * @return 令牌
+ */
+ void verifyToken(LoginUser loginUser);
+
+ /**
+ * 刷新令牌有效期
+ *
+ * @param loginUser 登录信息
+ */
+ void refreshToken(LoginUser loginUser);
+
+ /**
+ * 设置用户代理信息
+ *
+ * @param loginUser 登录信息
+ */
+ void setUserAgent(LoginUser loginUser);
+
+ /**
+ * 从令牌中获取用户名
+ *
+ * @param token 令牌
+ * @return 用户名
+ */
+ String getUsernameFromToken(String token);
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/enums/LimitType.java b/ruoyi/src/main/java/com/ruoyi/common/enums/LimitType.java
index c609fd8ac..9fb96ee48 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/enums/LimitType.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/enums/LimitType.java
@@ -16,5 +16,10 @@ public enum LimitType
/**
* 根据请求者IP进行限流
*/
- IP
+ IP,
+
+ /**
+ * 实例限流(集群多后端实例)
+ */
+ CLUSTER
}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java b/ruoyi/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java
index 0c40f341c..5529bb336 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/enums/ThreadPoolRejectedPolicy.java
@@ -15,7 +15,7 @@ import java.util.concurrent.ThreadPoolExecutor;
@AllArgsConstructor
public enum ThreadPoolRejectedPolicy {
- CALLER_RUNS_POLICY("等待", ThreadPoolExecutor.CallerRunsPolicy.class),
+ CALLER_RUNS_POLICY("调用方执行", ThreadPoolExecutor.CallerRunsPolicy.class),
DISCARD_OLDEST_POLICY("放弃最旧的", ThreadPoolExecutor.DiscardOldestPolicy.class),
DISCARD_POLICY("丢弃", ThreadPoolExecutor.DiscardPolicy.class),
ABORT_POLICY("中止", ThreadPoolExecutor.AbortPolicy.class);
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/TokenProperties.java b/ruoyi/src/main/java/com/ruoyi/common/properties/TokenProperties.java
similarity index 91%
rename from ruoyi/src/main/java/com/ruoyi/framework/config/properties/TokenProperties.java
rename to ruoyi/src/main/java/com/ruoyi/common/properties/TokenProperties.java
index f695c1c62..927a9413d 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/TokenProperties.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/properties/TokenProperties.java
@@ -1,4 +1,4 @@
-package com.ruoyi.framework.config.properties;
+package com.ruoyi.common.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/RedisUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/RedisUtils.java
index 5fcfb9dee..769ee7153 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/utils/RedisUtils.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/RedisUtils.java
@@ -25,6 +25,32 @@ public class RedisUtils {
private static RedissonClient client = SpringUtils.getBean(RedissonClient.class);
+ /**
+ * 限流
+ *
+ * @param key 限流key
+ * @param rateType 限流类型
+ * @param rate 速率
+ * @param rateInterval 速率间隔
+ * @return -1 表示失败
+ */
+ public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {
+ RRateLimiter rateLimiter = client.getRateLimiter(key);
+ rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
+ if (rateLimiter.tryAcquire()) {
+ return rateLimiter.availablePermits();
+ } else {
+ return -1L;
+ }
+ }
+
+ /**
+ * 获取实例id
+ */
+ public static String getClientId() {
+ return client.getId();
+ }
+
/**
* 发布通道消息
*
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
index dc3aea2c0..3ab304c0c 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -35,6 +35,7 @@ public class FileUtils extends FileUtil
.append(percentEncodedFileName);
response.setHeader("Content-disposition", contentDispositionValue.toString());
+ response.setHeader("download-filename", percentEncodedFileName);
}
/**
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
index 03c608af8..bd7522c51 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
@@ -27,6 +27,9 @@ public class AddressUtils {
public static String getRealAddressByIP(String ip) {
String address = UNKNOWN;
+ if (StringUtils.isBlank(ip)){
+ return address;
+ }
// 内网不查询
ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
if (NetUtil.isInnerIP(ip)) {
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
index 4060b1794..e3001c605 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -46,7 +46,7 @@ public class ExcelUtil {
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
- FileUtils.setAttachmentResponseHeader(response, URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()));
+ FileUtils.setAttachmentResponseHeader(response, filename);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
ServletOutputStream os = response.getOutputStream();
EasyExcel.write(os, clazz)
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
index 6877aed2d..5ef9d49cd 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
@@ -34,6 +34,9 @@ public class RedisCacheController {
* 如果没有,就调用方法,然后把结果缓存起来
* 这个注解「一般用在查询方法上」
*
+ * 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
+ * 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
+ *
* cacheNames 为配置文件内 groupId
*/
@ApiOperation("测试 @Cacheable")
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
new file mode 100644
index 000000000..33d75093b
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
@@ -0,0 +1,58 @@
+package com.ruoyi.demo.controller;
+
+import com.ruoyi.common.annotation.RateLimiter;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.LimitType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * 测试分布式限流样例
+ *
+ * @author Lion Li
+ */
+@Api(value = "测试分布式限流样例", tags = {"测试分布式限流样例"})
+@Slf4j
+@RestController
+@RequestMapping("/demo/rateLimiter")
+public class RedisRateLimiterController {
+
+ /**
+ * 测试全局限流
+ * 全局影响
+ */
+ @ApiOperation("测试全局限流")
+ @RateLimiter(count = 2, time = 10)
+ @GetMapping("/test")
+ public AjaxResult test(String value){
+ return AjaxResult.success("操作成功",value);
+ }
+
+ /**
+ * 测试请求IP限流
+ * 同一IP请求受影响
+ */
+ @ApiOperation("测试请求IP限流")
+ @RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
+ @GetMapping("/testip")
+ public AjaxResult testip(String value){
+ return AjaxResult.success("操作成功",value);
+ }
+
+ /**
+ * 测试集群实例限流
+ * 启动两个后端服务互不影响
+ */
+ @ApiOperation("测试集群实例限流")
+ @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
+ @GetMapping("/testcluster")
+ public AjaxResult testcluster(String value){
+ return AjaxResult.success("操作成功",value);
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
index 563704e05..a3a9d2224 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
@@ -96,7 +96,7 @@ public class TestDemoController extends BaseController {
@ApiOperation("新增测试单表")
@PreAuthorize("@ss.hasPermi('demo:demo:add')")
@Log(title = "测试单表", businessType = BusinessType.INSERT)
- @RepeatSubmit(intervalTime = 2, timeUnit = TimeUnit.SECONDS)
+ @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "不允许重复提交")
@PostMapping()
public AjaxResult add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) {
return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0);
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
index fe103ef88..4280d509d 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
@@ -75,7 +75,11 @@ public class TestDemoServiceImpl extends ServicePlusImpl paramsMap = (Map, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
}
}
- /**
- * 是否存在注解,如果存在就获取
- */
- private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
- {
- Signature signature = joinPoint.getSignature();
- MethodSignature methodSignature = (MethodSignature) signature;
- Method method = methodSignature.getMethod();
-
- if (method != null)
- {
- return method.getAnnotation(Log.class);
- }
- return null;
- }
-
/**
* 参数拼装
*/
- private String argsArrayToString(Object[] paramsArray)
- {
+ private String argsArrayToString(Object[] paramsArray) {
StringBuilder params = new StringBuilder();
- if (paramsArray != null && paramsArray.length > 0)
- {
- for (Object o : paramsArray) {
- if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
- params.append(JsonUtils.toJsonString(o)).append(" ");
- }
- }
+ if (paramsArray != null && paramsArray.length > 0) {
+ for (Object o : paramsArray) {
+ if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
+ try {
+ params.append(JsonUtils.toJsonString(o)).append(" ");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
}
return params.toString().trim();
}
@@ -209,27 +164,21 @@ public class LogAspect
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
@SuppressWarnings("rawtypes")
- public boolean isFilterObject(final Object o)
- {
+ public boolean isFilterObject(final Object o) {
Class> clazz = o.getClass();
- if (clazz.isArray())
- {
+ if (clazz.isArray()) {
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
- }
- else if (Collection.class.isAssignableFrom(clazz))
- {
+ } else if (Collection.class.isAssignableFrom(clazz)) {
Collection collection = (Collection) o;
- for (Object value : collection) {
- return value instanceof MultipartFile;
- }
- }
- else if (Map.class.isAssignableFrom(clazz))
- {
+ for (Object value : collection) {
+ return value instanceof MultipartFile;
+ }
+ } else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) o;
- for (Object value : map.entrySet()) {
- Map.Entry entry = (Map.Entry) value;
- return entry.getValue() instanceof MultipartFile;
- }
+ for (Object value : map.entrySet()) {
+ Map.Entry entry = (Map.Entry) value;
+ return entry.getValue() instanceof MultipartFile;
+ }
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
index 1e21e376d..dc140e22b 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
@@ -3,114 +3,63 @@ package com.ruoyi.framework.aspectj;
import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.enums.LimitType;
import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.RedisUtils;
import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.script.RedisScript;
+import org.redisson.api.RateType;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
/**
* 限流处理
*
- * @author ruoyi
+ * @author Lion Li
*/
+@Slf4j
@Aspect
@Component
-public class RateLimiterAspect
-{
- private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
+public class RateLimiterAspect {
- private RedisTemplate