(Arrays.asList(info.getAlarmEmail().split(",")));
- for (String email: emailSet) {
+ for (String email : emailSet) {
// make mail
try {
@@ -88,28 +89,28 @@ public class EmailJobAlarm implements JobAlarm {
*
* @return
*/
- private static final String loadEmailJobAlarmTemplate(){
+ private static final String loadEmailJobAlarmTemplate() {
String mailBodyTemplate = "" + I18nUtil.getString("jobconf_monitor_detail") + ":" +
- " \n" +
- " " +
- " \n" +
- " "+ I18nUtil.getString("jobinfo_field_jobgroup") +" \n" +
- " "+ I18nUtil.getString("jobinfo_field_id") +" \n" +
- " "+ I18nUtil.getString("jobinfo_field_jobdesc") +" \n" +
- " "+ I18nUtil.getString("jobconf_monitor_alarm_title") +" \n" +
- " "+ I18nUtil.getString("jobconf_monitor_alarm_content") +" \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " {0} \n" +
- " {1} \n" +
- " {2} \n" +
- " "+ I18nUtil.getString("jobconf_monitor_alarm_type") +" \n" +
- " {3} \n" +
- " \n" +
- " \n" +
- "
";
+ "\n" +
+ " " +
+ " \n" +
+ " " + I18nUtil.getString("jobinfo_field_jobgroup") + " \n" +
+ " " + I18nUtil.getString("jobinfo_field_id") + " \n" +
+ " " + I18nUtil.getString("jobinfo_field_jobdesc") + " \n" +
+ " " + I18nUtil.getString("jobconf_monitor_alarm_title") + " \n" +
+ " " + I18nUtil.getString("jobconf_monitor_alarm_content") + " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " {0} \n" +
+ " {1} \n" +
+ " {2} \n" +
+ " " + I18nUtil.getString("jobconf_monitor_alarm_type") + " \n" +
+ " {3} \n" +
+ " \n" +
+ " \n" +
+ "
";
return mailBodyTemplate;
}
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java
index b9ac59a38..83399336b 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java
@@ -32,7 +32,7 @@ public class XxlJobCompleter {
// text最大64kb 避免长度过长
if (xxlJobLog.getHandleMsg().length() > 15000) {
- xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg().substring(0, 15000) );
+ xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg().substring(0, 15000));
}
// fresh handle
@@ -43,18 +43,18 @@ public class XxlJobCompleter {
/**
* do somethind to finish job
*/
- private static void finishJob(XxlJobLog xxlJobLog){
+ private static void finishJob(XxlJobLog xxlJobLog) {
// 1、handle success, to trigger child job
String triggerChildMsg = null;
- if (XxlJobContext.HANDLE_COCE_SUCCESS == xxlJobLog.getHandleCode()) {
+ if (XxlJobContext.HANDLE_CODE_SUCCESS == xxlJobLog.getHandleCode()) {
XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
- if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) {
- triggerChildMsg = " >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<< ";
+ if (xxlJobInfo != null && xxlJobInfo.getChildJobId() != null && xxlJobInfo.getChildJobId().trim().length() > 0) {
+ triggerChildMsg = " >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_child_run") + "<<<<<<<<<<< ";
String[] childJobIds = xxlJobInfo.getChildJobId().split(",");
for (int i = 0; i < childJobIds.length; i++) {
- int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
+ int childJobId = (childJobIds[i] != null && childJobIds[i].trim().length() > 0 && isNumeric(childJobIds[i])) ? Integer.valueOf(childJobIds[i]) : -1;
if (childJobId > 0) {
JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null);
@@ -62,16 +62,16 @@ public class XxlJobCompleter {
// add msg
triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"),
- (i+1),
- childJobIds.length,
- childJobIds[i],
- (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?I18nUtil.getString("system_success"):I18nUtil.getString("system_fail")),
- triggerChildResult.getMsg());
+ (i + 1),
+ childJobIds.length,
+ childJobIds[i],
+ (triggerChildResult.getCode() == ReturnT.SUCCESS_CODE ? I18nUtil.getString("system_success") : I18nUtil.getString("system_fail")),
+ triggerChildResult.getMsg());
} else {
triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"),
- (i+1),
- childJobIds.length,
- childJobIds[i]);
+ (i + 1),
+ childJobIds.length,
+ childJobIds[i]);
}
}
@@ -79,7 +79,7 @@ public class XxlJobCompleter {
}
if (triggerChildMsg != null) {
- xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg() + triggerChildMsg );
+ xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg() + triggerChildMsg);
}
// 2、fix_delay trigger next
@@ -87,7 +87,7 @@ public class XxlJobCompleter {
}
- private static boolean isNumeric(String str){
+ private static boolean isNumeric(String str) {
try {
int result = Integer.valueOf(str);
return true;
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
index 380b8a596..6e40cb760 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java
@@ -23,6 +23,7 @@ import java.util.Arrays;
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
private static XxlJobAdminConfig adminConfig = null;
+
public static XxlJobAdminConfig getAdminConfig() {
return adminConfig;
}
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java
index fce23524d..2ce373eeb 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java
@@ -1,18 +1,18 @@
/*
* All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
* under the License.
- *
+ *
*/
package com.xxl.job.admin.core.cron;
@@ -31,14 +31,14 @@ import java.util.TimeZone;
import java.util.TreeSet;
/**
- * Provides a parser and evaluator for unix-like cron expressions. Cron
+ * Provides a parser and evaluator for unix-like cron expressions. Cron
* expressions provide the ability to specify complex time combinations such as
- * "At 8:00am every Monday through Friday" or "At 1:30am every
- * last Friday of the month".
+ * "At 8:00am every Monday through Friday" or "At 1:30am every
+ * last Friday of the month".
*
* Cron expressions are comprised of 6 required fields and one optional field
* separated by white space. The fields respectively are described as follows:
- *
+ *
*
*
* Field Name
@@ -98,7 +98,7 @@ import java.util.TreeSet;
*
*
*
- * The '*' character is used to specify all values. For example, "*"
+ * The '*' character is used to specify all values. For example, "*"
* in the minute field means "every minute".
*
* The '?' character is allowed for the day-of-month and day-of-week fields. It
@@ -113,55 +113,55 @@ import java.util.TreeSet;
* Wednesday, and Friday".
*
* The '/' character is used to specify increments. For example "0/15"
- * in the seconds field means "the seconds 0, 15, 30, and 45". And
+ * in the seconds field means "the seconds 0, 15, 30, and 45". And
* "5/15" in the seconds field means "the seconds 5, 20, 35, and
* 50". Specifying '*' before the '/' is equivalent to specifying 0 is
* the value to start with. Essentially, for each field in the expression, there
- * is a set of numbers that can be turned on or off. For seconds and minutes,
+ * is a set of numbers that can be turned on or off. For seconds and minutes,
* the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to
* 31, and for months 0 to 11 (JAN to DEC). The "/" character simply helps you turn
* on every "nth" value in the given set. Thus "7/6" in the
- * month field only turns on month "7", it does NOT mean every 6th
- * month, please note that subtlety.
+ * month field only turns on month "7", it does NOT mean every 6th
+ * month, please note that subtlety.
*
* The 'L' character is allowed for the day-of-month and day-of-week fields.
- * This character is short-hand for "last", but it has different
- * meaning in each of the two fields. For example, the value "L" in
- * the day-of-month field means "the last day of the month" - day 31
- * for January, day 28 for February on non-leap years. If used in the
- * day-of-week field by itself, it simply means "7" or
+ * This character is short-hand for "last", but it has different
+ * meaning in each of the two fields. For example, the value "L" in
+ * the day-of-month field means "the last day of the month" - day 31
+ * for January, day 28 for February on non-leap years. If used in the
+ * day-of-week field by itself, it simply means "7" or
* "SAT". But if used in the day-of-week field after another value, it
* means "the last xxx day of the month" - for example "6L"
- * means "the last friday of the month". You can also specify an offset
- * from the last day of the month, such as "L-3" which would mean the third-to-last
- * day of the calendar month. When using the 'L' option, it is important not to
+ * means "the last friday of the month". You can also specify an offset
+ * from the last day of the month, such as "L-3" which would mean the third-to-last
+ * day of the calendar month. When using the 'L' option, it is important not to
* specify lists, or ranges of values, as you'll get confusing/unexpected results.
*
- * The 'W' character is allowed for the day-of-month field. This character
- * is used to specify the weekday (Monday-Friday) nearest the given day. As an
- * example, if you were to specify "15W" as the value for the
+ * The 'W' character is allowed for the day-of-month field. This character
+ * is used to specify the weekday (Monday-Friday) nearest the given day. As an
+ * example, if you were to specify "15W" as the value for the
* day-of-month field, the meaning is: "the nearest weekday to the 15th of
- * the month". So if the 15th is a Saturday, the trigger will fire on
+ * the month". So if the 15th is a Saturday, the trigger will fire on
* Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the
- * 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th.
+ * 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th.
* However if you specify "1W" as the value for day-of-month, and the
- * 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not
- * 'jump' over the boundary of a month's days. The 'W' character can only be
+ * 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not
+ * 'jump' over the boundary of a month's days. The 'W' character can only be
* specified when the day-of-month is a single day, not a range or list of days.
*
- * The 'L' and 'W' characters can also be combined for the day-of-month
- * expression to yield 'LW', which translates to "last weekday of the
+ * The 'L' and 'W' characters can also be combined for the day-of-month
+ * expression to yield 'LW', which translates to "last weekday of the
* month".
*
* The '#' character is allowed for the day-of-week field. This character is
- * used to specify "the nth" XXX day of the month. For example, the
- * value of "6#3" in the day-of-week field means the third Friday of
- * the month (day 6 = Friday and "#3" = the 3rd one in the month).
- * Other examples: "2#1" = the first Monday of the month and
+ * used to specify "the nth" XXX day of the month. For example, the
+ * value of "6#3" in the day-of-week field means the third Friday of
+ * the month (day 6 = Friday and "#3" = the 3rd one in the month).
+ * Other examples: "2#1" = the first Monday of the month and
* "4#5" = the fifth Wednesday of the month. Note that if you specify
* "#5" and there is not 5 of the given day-of-week in the month, then
* no firing will occur that month. If the '#' character is used, there can
- * only be one expression in the day-of-week field ("3#1,6#3" is
+ * only be one expression in the day-of-week field ("3#1,6#3" is
* not valid, since there are two expressions).
*
*
-
- org.apache.poi
- poi-ooxml
-
-
com.alibaba
easyexcel
-
+
- com.sun.xml.bind
- jaxb-impl
+ org.yaml
+ snakeyaml
@@ -179,6 +173,11 @@
hutool-extra
+
+ com.sun.mail
+ jakarta.mail
+
+
org.projectlombok
lombok
@@ -225,36 +224,27 @@
tlog-xxljob-spring-boot-starter
-
- com.qiniu
- qiniu-java-sdk
- ${qiniu.version}
-
- com.aliyun.oss
- aliyun-sdk-oss
- ${aliyun.oss.version}
+ com.amazonaws
+ aws-java-sdk-s3
+
+
- com.qcloud
- cos_api
- ${qcloud.cos.version}
+ com.aliyun
+ dysmsapi20170525
+
+
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java
- org.slf4j
- slf4j-log4j12
-
-
- org.bouncycastle
- bcprov-jdk15on
+ com.squareup.okio
+ okio
-
- io.minio
- minio
- ${minio.version}
-
diff --git a/ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java b/ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java
new file mode 100644
index 000000000..fe2810083
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/annotation/Anonymous.java
@@ -0,0 +1,18 @@
+package com.ruoyi.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 匿名访问不鉴权注解
+ *
+ * @author ruoyi
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Anonymous {
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java b/ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java
new file mode 100644
index 000000000..4af822eda
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/annotation/CellMerge.java
@@ -0,0 +1,24 @@
+package com.ruoyi.common.annotation;
+
+import com.ruoyi.common.excel.CellMergeStrategy;
+
+import java.lang.annotation.*;
+
+/**
+ * excel 列单元格合并(合并列相同项)
+ *
+ * 需搭配 {@link CellMergeStrategy} 策略使用
+ *
+ * @author Lion Li
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface CellMerge {
+
+ /**
+ * col index
+ */
+ int index() default -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 6885e95cf..9aa75f7a4 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
@@ -108,12 +108,6 @@ public class SysUser extends BaseEntity {
)
private String password;
- @JsonIgnore
- @JsonProperty
- public String getPassword() {
- return password;
- }
-
/**
* 帐号状态(0正常 1停用)
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java b/ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java
new file mode 100644
index 000000000..04a1bbb8a
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java
@@ -0,0 +1,114 @@
+package com.ruoyi.common.excel;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import com.ruoyi.common.annotation.CellMerge;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 列值重复合并策略
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@Slf4j
+public class CellMergeStrategy extends AbstractMergeStrategy {
+
+ private List> list;
+ private boolean hasTitle;
+
+ @Override
+ protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+ List cellList = handle(list, hasTitle);
+ // judge the list is not null
+ if (CollectionUtils.isNotEmpty(cellList)) {
+ // the judge is necessary
+ if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {
+ for (CellRangeAddress item : cellList) {
+ sheet.addMergedRegion(item);
+ }
+ }
+ }
+ }
+
+ @SneakyThrows
+ private static List handle(List> list, boolean hasTitle) {
+ List cellList = new ArrayList<>();
+ if (CollectionUtils.isEmpty(list)) {
+ return cellList;
+ }
+ Class> clazz = list.get(0).getClass();
+ Field[] fields = clazz.getDeclaredFields();
+ // 有注解的字段
+ List mergeFields = new ArrayList<>();
+ List mergeFieldsIndex = new ArrayList<>();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (field.isAnnotationPresent(CellMerge.class)) {
+ CellMerge cm = field.getAnnotation(CellMerge.class);
+ mergeFields.add(field);
+ mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index());
+ }
+ }
+ // 行合并开始下标
+ int rowIndex = hasTitle ? 1 : 0;
+ Map map = new HashMap<>();
+ // 生成两两合并单元格
+ for (int i = 0; i < list.size(); i++) {
+ for (int j = 0; j < mergeFields.size(); j++) {
+ Field field = mergeFields.get(j);
+ String name = field.getName();
+ String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+ Method readMethod = clazz.getMethod(methodName);
+ Object val = readMethod.invoke(list.get(i));
+
+ int colNum = mergeFieldsIndex.get(j);
+ if (!map.containsKey(field)) {
+ map.put(field, new RepeatCell(val, i));
+ } else {
+ RepeatCell repeatCell = map.get(field);
+ Object cellValue = repeatCell.getValue();
+ if (cellValue == null || "".equals(cellValue)) {
+ // 空值跳过不合并
+ continue;
+ }
+ if (cellValue != val) {
+ if (i - repeatCell.getCurrent() > 1) {
+ cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
+ }
+ map.put(field, new RepeatCell(val, i));
+ } else if (i == list.size() - 1) {
+ if (i > repeatCell.getCurrent()) {
+ cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+ }
+ }
+ }
+ }
+ }
+ return cellList;
+ }
+
+ @Data
+ @AllArgsConstructor
+ static class RepeatCell {
+
+ private Object value;
+
+ private int current;
+
+ }
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java b/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java
index ec4d56767..0e60485ad 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/helper/DataPermissionHelper.java
@@ -1,11 +1,11 @@
package com.ruoyi.common.helper;
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaStorage;
import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.utils.ServletUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
-import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@@ -33,11 +33,11 @@ public class DataPermissionHelper {
}
public static Map getContext() {
- HttpServletRequest request = ServletUtils.getRequest();
- Object attribute = request.getAttribute(DATA_PERMISSION_KEY);
+ SaStorage saStorage = SaHolder.getStorage();
+ Object attribute = saStorage.get(DATA_PERMISSION_KEY);
if (ObjectUtil.isNull(attribute)) {
- request.setAttribute(DATA_PERMISSION_KEY, new HashMap<>());
- attribute = request.getAttribute(DATA_PERMISSION_KEY);
+ saStorage.set(DATA_PERMISSION_KEY, new HashMap<>());
+ attribute = saStorage.get(DATA_PERMISSION_KEY);
}
if (attribute instanceof Map) {
return (Map) attribute;
diff --git a/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java b/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java
index 7875c5630..09e1dc757 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/helper/LoginHelper.java
@@ -1,5 +1,6 @@
package com.ruoyi.common.helper;
+import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.constant.UserConstants;
@@ -13,7 +14,7 @@ import lombok.NoArgsConstructor;
/**
* 登录鉴权助手
- *
+ *
* user_type 为 用户类型 同一个用户表 可以有多种用户类型 例如 pc,app
* deivce 为 设备类型 同一个用户类型 可以有 多种设备类型 例如 web,ios
* 可以组成 用户类型与设备类型多对多的 权限灵活控制
@@ -29,15 +30,13 @@ public class LoginHelper {
public static final String JOIN_CODE = ":";
public static final String LOGIN_USER_KEY = "loginUser";
- private static final ThreadLocal LOGIN_CACHE = new ThreadLocal<>();
-
/**
* 登录系统
*
* @param loginUser 登录用户信息
*/
public static void login(LoginUser loginUser) {
- LOGIN_CACHE.set(loginUser);
+ SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
StpUtil.login(loginUser.getLoginId());
setLoginUser(loginUser);
}
@@ -49,7 +48,7 @@ public class LoginHelper {
* @param loginUser 登录用户信息
*/
public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) {
- LOGIN_CACHE.set(loginUser);
+ SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
StpUtil.login(loginUser.getLoginId(), deviceType.getDevice());
setLoginUser(loginUser);
}
@@ -65,18 +64,13 @@ public class LoginHelper {
* 获取用户(多级缓存)
*/
public static LoginUser getLoginUser() {
- LoginUser loginUser = LOGIN_CACHE.get();
+ LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
if (loginUser != null) {
return loginUser;
}
- return (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);
- }
-
- /**
- * 清除一级缓存 防止内存问题
- */
- public static void clearCache() {
- LOGIN_CACHE.remove();
+ loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);
+ SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
+ return loginUser;
}
/**
diff --git a/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java b/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java
index 55c4e6a7d..404f393fe 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/jackson/SensitiveJsonSerializer.java
@@ -27,9 +27,9 @@ public class SensitiveJsonSerializer extends JsonSerializer implements C
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
if (sensitiveService.isSensitive()) {
- gen.writeString(value);
- } else {
gen.writeString(strategy.desensitizer().apply(value));
+ } else {
+ gen.writeString(value);
}
}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java
new file mode 100644
index 000000000..32a3f8252
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/email/MailUtils.java
@@ -0,0 +1,468 @@
+package com.ruoyi.common.utils.email;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.CharUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.mail.*;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import javax.mail.Authenticator;
+import javax.mail.Session;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 邮件工具类
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MailUtils {
+
+ private static final MailAccount ACCOUNT = SpringUtils.getBean(MailAccount.class);
+
+ /**
+ * 获取邮件发送实例
+ */
+ public static MailAccount getMailAccount() {
+ return ACCOUNT;
+ }
+
+ /**
+ * 获取邮件发送实例 (自定义发送人以及授权码)
+ *
+ * @param user 发送人
+ * @param pass 授权码
+ */
+ public static MailAccount getMailAccount(String from, String user, String pass) {
+ ACCOUNT.setFrom(StringUtils.blankToDefault(from, ACCOUNT.getFrom()));
+ ACCOUNT.setUser(StringUtils.blankToDefault(user, ACCOUNT.getUser()));
+ ACCOUNT.setPass(StringUtils.blankToDefault(pass, ACCOUNT.getPass()));
+ return ACCOUNT;
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String sendText(String to, String subject, String content, File... files) {
+ return send(to, subject, content, false, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String sendHtml(String to, String subject, String content, File... files) {
+ return send(to, subject, content, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ */
+ public static String send(String to, String subject, String content, boolean isHtml, File... files) {
+ return send(splitAddress(to), subject, content, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.0.3
+ */
+ public static String send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) {
+ return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送文本邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @return message-id
+ */
+ public static String sendText(Collection tos, String subject, String content, File... files) {
+ return send(tos, subject, content, false, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String sendHtml(Collection tos, String subject, String content, File... files) {
+ return send(tos, subject, content, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ */
+ public static String send(Collection tos, String subject, String content, boolean isHtml, File... files) {
+ return send(tos, null, null, subject, content, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.0.3
+ */
+ public static String send(Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
+ return send(getMailAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files);
+ }
+
+ // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件认证对象
+ * @param to 收件人,多个收件人逗号或者分号隔开
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) {
+ return send(mailAccount, splitAddress(to), subject, content, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ */
+ public static String send(MailAccount mailAccount, Collection tos, String subject, String content, boolean isHtml, File... files) {
+ return send(mailAccount, tos, null, null, subject, content, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.0.3
+ */
+ public static String send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, boolean isHtml, File... files) {
+ return send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String sendHtml(String to, String subject, String content, Map imageMap, File... files) {
+ return send(to, subject, content, imageMap, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ */
+ public static String send(String to, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ return send(splitAddress(to), subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ *
+ * @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param cc 抄送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param bcc 密送人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.0.3
+ */
+ public static String send(String to, String cc, String bcc, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送HTML邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String sendHtml(Collection tos, String subject, String content, Map imageMap, File... files) {
+ return send(tos, subject, content, imageMap, true, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ */
+ public static String send(Collection tos, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ return send(tos, null, null, subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 使用配置文件中设置的账户发送邮件,发送给多人
+ *
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.0.3
+ */
+ public static String send(Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ return send(getMailAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
+ }
+
+ // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件认证对象
+ * @param to 收件人,多个收件人逗号或者分号隔开
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ * @since 3.2.0
+ */
+ public static String send(MailAccount mailAccount, String to, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ return send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.6.3
+ */
+ public static String send(MailAccount mailAccount, Collection tos, String subject, String content, Map imageMap, boolean isHtml, File... files) {
+ return send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:$IMAGE_PLACEHOLDER
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.6.3
+ */
+ public static String send(MailAccount mailAccount, Collection tos, Collection ccs, Collection bccs, String subject, String content, Map imageMap,
+ boolean isHtml, File... files) {
+ return send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
+ }
+
+ /**
+ * 根据配置文件,获取邮件客户端会话
+ *
+ * @param mailAccount 邮件账户配置
+ * @param isSingleton 是否单例(全局共享会话)
+ * @return {@link Session}
+ * @since 5.5.7
+ */
+ public static Session getSession(MailAccount mailAccount, boolean isSingleton) {
+ Authenticator authenticator = null;
+ if (mailAccount.isAuth()) {
+ authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass());
+ }
+
+ return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
+ : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
+ }
+
+ // ------------------------------------------------------------------------------------------------------------------------ Private method start
+
+ /**
+ * 发送邮件给多人
+ *
+ * @param mailAccount 邮件帐户信息
+ * @param useGlobalSession 是否全局共享Session
+ * @param tos 收件人列表
+ * @param ccs 抄送人列表,可以为null或空
+ * @param bccs 密送人列表,可以为null或空
+ * @param subject 标题
+ * @param content 正文
+ * @param imageMap 图片与占位符,占位符格式为cid:${cid}
+ * @param isHtml 是否为HTML格式
+ * @param files 附件列表
+ * @return message-id
+ * @since 4.6.3
+ */
+ private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection tos, Collection ccs, Collection bccs, String subject, String content,
+ Map imageMap, boolean isHtml, File... files) {
+ final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession);
+
+ // 可选抄送人
+ if (CollUtil.isNotEmpty(ccs)) {
+ mail.setCcs(ccs.toArray(new String[0]));
+ }
+ // 可选密送人
+ if (CollUtil.isNotEmpty(bccs)) {
+ mail.setBccs(bccs.toArray(new String[0]));
+ }
+
+ mail.setTos(tos.toArray(new String[0]));
+ mail.setTitle(subject);
+ mail.setContent(content);
+ mail.setHtml(isHtml);
+ mail.setFiles(files);
+
+ // 图片
+ if (MapUtil.isNotEmpty(imageMap)) {
+ for (Map.Entry entry : imageMap.entrySet()) {
+ mail.addImage(entry.getKey(), entry.getValue());
+ // 关闭流
+ IoUtil.close(entry.getValue());
+ }
+ }
+
+ return mail.send();
+ }
+
+ /**
+ * 将多个联系人转为列表,分隔符为逗号或者分号
+ *
+ * @param addresses 多个联系人,如果为空返回null
+ * @return 联系人列表
+ */
+ private static List splitAddress(String addresses) {
+ if (StrUtil.isBlank(addresses)) {
+ return null;
+ }
+
+ List result;
+ if (StrUtil.contains(addresses, CharUtil.COMMA)) {
+ result = StrUtil.splitTrim(addresses, CharUtil.COMMA);
+ } else if (StrUtil.contains(addresses, ';')) {
+ result = StrUtil.splitTrim(addresses, ';');
+ } else {
+ result = CollUtil.newArrayList(addresses);
+ }
+ return result;
+ }
+ // ------------------------------------------------------------------------------------------------------------------------ Private method end
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java
new file mode 100644
index 000000000..6ca97fe60
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java
@@ -0,0 +1,40 @@
+package com.ruoyi.common.utils.file;
+
+/**
+ * 媒体类型工具类
+ *
+ * @author ruoyi
+ */
+public class MimeTypeUtils {
+ public static final String IMAGE_PNG = "image/png";
+
+ public static final String IMAGE_JPG = "image/jpg";
+
+ public static final String IMAGE_JPEG = "image/jpeg";
+
+ public static final String IMAGE_BMP = "image/bmp";
+
+ public static final String IMAGE_GIF = "image/gif";
+
+ public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
+
+ public static final String[] FLASH_EXTENSION = {"swf", "flv"};
+
+ public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
+ "asf", "rm", "rmvb"};
+
+ public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
+
+ public static final String[] DEFAULT_ALLOWED_EXTENSION = {
+ // 图片
+ "bmp", "gif", "jpg", "jpeg", "png",
+ // word excel powerpoint
+ "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+ // 压缩文件
+ "rar", "zip", "gz", "bz2",
+ // 视频格式
+ "mp4", "avi", "rmvb",
+ // pdf
+ "pdf"};
+
+}
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 36dc67fa1..e6a67b26b 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
@@ -1,9 +1,17 @@
package com.ruoyi.common.utils.poi;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.fill.FillConfig;
+import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.ruoyi.common.convert.ExcelBigNumberConvert;
+import com.ruoyi.common.excel.CellMergeStrategy;
import com.ruoyi.common.excel.DefaultExcelListener;
import com.ruoyi.common.excel.ExcelListener;
import com.ruoyi.common.excel.ExcelResult;
@@ -16,7 +24,10 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
/**
* Excel相关处理
@@ -69,27 +80,125 @@ public class ExcelUtil {
*
* @param list 导出数据集合
* @param sheetName 工作表的名称
- * @return 结果
+ * @param clazz 实体类
+ * @param response 响应体
*/
public static void exportExcel(List list, String sheetName, Class clazz, HttpServletResponse response) {
+ exportExcel(list, sheetName, clazz, false, response);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param list 导出数据集合
+ * @param sheetName 工作表的名称
+ * @param clazz 实体类
+ * @param merge 是否合并单元格
+ * @param response 响应体
+ */
+ public static void exportExcel(List list, String sheetName, Class clazz, boolean merge, HttpServletResponse response) {
try {
- String filename = encodingFilename(sheetName);
- response.reset();
- FileUtils.setAttachmentResponseHeader(response, filename);
- response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
+ resetResponse(sheetName, response);
ServletOutputStream os = response.getOutputStream();
- EasyExcel.write(os, clazz)
+ ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
.autoCloseStream(false)
// 自动适配
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
- .sheet(sheetName).doWrite(list);
+ .sheet(sheetName);
+ if (merge) {
+ // 合并处理器
+ builder.registerWriteHandler(new CellMergeStrategy(list, true));
+ }
+ builder.doWrite(list);
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
+ /**
+ * 单表多数据模板导出 模板格式为 {.属性}
+ *
+ * @param filename 文件名
+ * @param templatePath 模板路径 resource 目录下的路径包括模板文件名
+ * 例如: excel/temp.xlsx
+ * 重点: 模板文件必须放置到启动类对应的 resource 目录下
+ * @param data 模板需要的数据
+ */
+ public static void exportTemplate(List data, String filename, String templatePath, HttpServletResponse response) {
+ try {
+ resetResponse(filename, response);
+ ClassPathResource templateResource = new ClassPathResource(templatePath);
+ ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
+ .withTemplate(templateResource.getStream())
+ .autoCloseStream(false)
+ // 大数值自动转换 防止失真
+ .registerConverter(new ExcelBigNumberConvert())
+ .build();
+ WriteSheet writeSheet = EasyExcel.writerSheet().build();
+ if (CollUtil.isEmpty(data)) {
+ throw new IllegalArgumentException("数据为空");
+ }
+ // 单表多数据导出 模板格式为 {.属性}
+ for (Object d : data) {
+ excelWriter.fill(d, writeSheet);
+ }
+ excelWriter.finish();
+ } catch (IOException e) {
+ throw new RuntimeException("导出Excel异常");
+ }
+ }
+
+ /**
+ * 多表多数据模板导出 模板格式为 {key.属性}
+ *
+ * @param filename 文件名
+ * @param templatePath 模板路径 resource 目录下的路径包括模板文件名
+ * 例如: excel/temp.xlsx
+ * 重点: 模板文件必须放置到启动类对应的 resource 目录下
+ * @param data 模板需要的数据
+ */
+ public static void exportTemplateMultiList(Map data, String filename, String templatePath, HttpServletResponse response) {
+ try {
+ resetResponse(filename, response);
+ ClassPathResource templateResource = new ClassPathResource(templatePath);
+ ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
+ .withTemplate(templateResource.getStream())
+ .autoCloseStream(false)
+ // 大数值自动转换 防止失真
+ .registerConverter(new ExcelBigNumberConvert())
+ .build();
+ WriteSheet writeSheet = EasyExcel.writerSheet().build();
+ if (CollUtil.isEmpty(data)) {
+ throw new IllegalArgumentException("数据为空");
+ }
+ for (Map.Entry map : data.entrySet()) {
+ // 设置列表后续还有数据
+ FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
+ if (map.getValue() instanceof Collection) {
+ // 多表导出必须使用 FillWrapper
+ excelWriter.fill(new FillWrapper(map.getKey(), (Collection>) map.getValue()), fillConfig, writeSheet);
+ } else {
+ excelWriter.fill(map.getValue(), writeSheet);
+ }
+ }
+ excelWriter.finish();
+ } catch (IOException e) {
+ throw new RuntimeException("导出Excel异常");
+ }
+ }
+
+ /**
+ * 重置响应体
+ */
+ private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException {
+ String filename = encodingFilename(sheetName);
+ response.reset();
+ FileUtils.setAttachmentResponseHeader(response, filename);
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
+ }
+
/**
* 解析导出值 0=男,1=女,2=未知
*
@@ -103,7 +212,7 @@ public class ExcelUtil {
String[] convertSource = converterExp.split(",");
for (String item : convertSource) {
String[] itemArray = item.split("=");
- if (StringUtils.containsAny(separator, propertyValue)) {
+ if (StringUtils.containsAny(propertyValue, separator)) {
for (String value : propertyValue.split(separator)) {
if (itemArray[0].equals(value)) {
propertyString.append(itemArray[1] + separator);
@@ -132,7 +241,7 @@ public class ExcelUtil {
String[] convertSource = converterExp.split(",");
for (String item : convertSource) {
String[] itemArray = item.split("=");
- if (StringUtils.containsAny(separator, propertyValue)) {
+ if (StringUtils.containsAny(propertyValue, separator)) {
for (String value : propertyValue.split(separator)) {
if (itemArray[1].equals(value)) {
propertyString.append(itemArray[0] + separator);
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java
index 5a15d46b7..7ed3b2827 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/utils/redis/RedisUtils.java
@@ -6,11 +6,11 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.redisson.api.*;
+import java.time.Duration;
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;
/**
@@ -107,7 +107,7 @@ public class RedisUtils {
} catch (Exception e) {
long timeToLive = bucket.remainTimeToLive();
bucket.set(value);
- bucket.expire(timeToLive, TimeUnit.MILLISECONDS);
+ bucket.expire(Duration.ofMillis(timeToLive));
}
} else {
bucket.set(value);
@@ -119,13 +119,12 @@ public class RedisUtils {
*
* @param key 缓存的键值
* @param value 缓存的值
- * @param timeout 时间
- * @param timeUnit 时间颗粒度
+ * @param duration 时间
*/
- public static void setCacheObject(final String key, final T value, final long timeout, final TimeUnit timeUnit) {
+ public static void setCacheObject(final String key, final T value, final Duration duration) {
RBucket result = CLIENT.getBucket(key);
result.set(value);
- result.expire(timeout, timeUnit);
+ result.expire(duration);
}
/**
@@ -149,20 +148,19 @@ public class RedisUtils {
* @return true=设置成功;false=设置失败
*/
public static boolean expire(final String key, final long timeout) {
- return expire(key, timeout, TimeUnit.SECONDS);
+ return expire(key, Duration.ofSeconds(timeout));
}
/**
* 设置有效时间
*
- * @param key Redis键
- * @param timeout 超时时间
- * @param unit 时间单位
+ * @param key Redis键
+ * @param duration 超时时间
* @return true=设置成功;false=设置失败
*/
- public static boolean expire(final String key, final long timeout, final TimeUnit unit) {
+ public static boolean expire(final String key, final Duration duration) {
RBucket rBucket = CLIENT.getBucket(key);
- return rBucket.expire(timeout, unit);
+ return rBucket.expire(duration);
}
/**
@@ -366,6 +364,50 @@ public class RedisUtils {
return rMap.getAll(hKeys);
}
+ /**
+ * 设置原子值
+ *
+ * @param key Redis键
+ * @param value 值
+ */
+ public static void setAtomicValue(String key, long value) {
+ RAtomicLong atomic = CLIENT.getAtomicLong(key);
+ atomic.set(value);
+ }
+
+ /**
+ * 获取原子值
+ *
+ * @param key Redis键
+ * @return 当前值
+ */
+ public static long getAtomicValue(String key) {
+ RAtomicLong atomic = CLIENT.getAtomicLong(key);
+ return atomic.get();
+ }
+
+ /**
+ * 递增原子值
+ *
+ * @param key Redis键
+ * @return 当前值
+ */
+ public static long incrAtomicValue(String key) {
+ RAtomicLong atomic = CLIENT.getAtomicLong(key);
+ return atomic.incrementAndGet();
+ }
+
+ /**
+ * 递减原子值
+ *
+ * @param key Redis键
+ * @return 当前值
+ */
+ public static long decrAtomicValue(String key) {
+ RAtomicLong atomic = CLIENT.getAtomicLong(key);
+ return atomic.decrementAndGet();
+ }
+
/**
* 获得缓存的基本对象列表
*
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java
new file mode 100644
index 000000000..6dabe5132
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/MailController.java
@@ -0,0 +1,48 @@
+package com.ruoyi.demo.controller;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.utils.email.MailUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+
+
+/**
+ * 邮件发送案例
+ *
+ * @author Michelle.Chung
+ */
+@Validated
+@Api(value = "邮件发送案例", tags = {"邮件发送案例"})
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/mail")
+public class MailController {
+
+ @ApiOperation("发送邮件")
+ @GetMapping("/sendSimpleMessage")
+ public R sendSimpleMessage(@ApiParam("接收人") String to,
+ @ApiParam("标题") String subject,
+ @ApiParam("内容") String text) {
+ MailUtils.sendText(to, subject, text);
+ return R.ok();
+ }
+
+ @ApiOperation("发送邮件(带附件)")
+ @GetMapping("/sendMessageWithAttachment")
+ public R sendMessageWithAttachment(@ApiParam("接收人") String to,
+ @ApiParam("标题") String subject,
+ @ApiParam("内容") String text,
+ @ApiParam("附件路径") String filePath) {
+ MailUtils.sendText(to, subject, text, new File(filePath));
+ return R.ok();
+ }
+
+}
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 98cca18c0..9fc93074f 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import java.util.concurrent.TimeUnit;
+import java.time.Duration;
/**
* spring-cache 演示案例
@@ -87,7 +87,7 @@ public class RedisCacheController {
@GetMapping("/test6")
public R test6(String key, String value) {
RedisUtils.setCacheObject(key, value);
- boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS);
+ boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10));
System.out.println("***********" + flag);
try {
Thread.sleep(11 * 1000);
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java
new file mode 100644
index 000000000..b92078624
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/SmsController.java
@@ -0,0 +1,72 @@
+package com.ruoyi.demo.controller;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.sms.config.properties.SmsProperties;
+import com.ruoyi.sms.core.SmsTemplate;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 短信演示案例
+ * 请先阅读文档 否则无法使用
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@Validated
+@Api(value = "短信演示案例", tags = {"短信演示案例"})
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/sms")
+public class SmsController {
+
+ private final SmsProperties smsProperties;
+// private final SmsTemplate smsTemplate; // 可以使用spring注入
+// private final AliyunSmsTemplate smsTemplate; // 也可以注入某个厂家的模板工具
+
+ @ApiOperation("发送短信Aliyun")
+ @GetMapping("/sendAliyun")
+ public R sendAliyun(@ApiParam("电话号") String phones,
+ @ApiParam("模板ID") String templateId) {
+ if (!smsProperties.getEnabled()) {
+ return R.fail("当前系统没有开启短信功能!");
+ }
+ if (!SpringUtils.containsBean("aliyunSmsTemplate")) {
+ return R.fail("阿里云依赖未引入!");
+ }
+ SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
+ Map map = new HashMap<>(1);
+ map.put("code", "1234");
+ Object send = smsTemplate.send(phones, templateId, map);
+ return R.ok(send);
+ }
+
+ @ApiOperation("发送短信Tencent")
+ @GetMapping("/sendTencent")
+ public R sendTencent(@ApiParam("电话号") String phones,
+ @ApiParam("模板ID") String templateId) {
+ if (!smsProperties.getEnabled()) {
+ return R.fail("当前系统没有开启短信功能!");
+ }
+ if (!SpringUtils.containsBean("tencentSmsTemplate")) {
+ return R.fail("腾讯云依赖未引入!");
+ }
+ SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
+ Map map = new HashMap<>(1);
+// map.put("2", "测试测试");
+ map.put("1", "1234");
+ Object send = smsTemplate.send(phones, templateId, map);
+ return R.ok(send);
+ }
+
+}
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 d1f994e5d..9f00c0770 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
@@ -29,6 +29,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
+import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -70,7 +71,7 @@ public class TestDemoController extends BaseController {
@ApiOperation("导入测试-校验")
@ApiImplicitParams({
- @ApiImplicitParam(name = "file", value = "导入文件", dataType = "java.io.File", required = true),
+ @ApiImplicitParam(name = "file", value = "导入文件", paramType = "query", dataTypeClass = File.class, required = true),
})
@Log(title = "测试单表", businessType = BusinessType.IMPORT)
@SaCheckPermission("demo:demo:import")
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java
new file mode 100644
index 000000000..a318b4658
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/demo/controller/TestExcelController.java
@@ -0,0 +1,102 @@
+package com.ruoyi.demo.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 测试Excel功能
+ *
+ * @author Lion Li
+ */
+@Api(value = "测试Excel功能", tags = {"测试Excel功能"})
+@RestController
+@RequestMapping("/demo/excel")
+public class TestExcelController {
+
+ /**
+ * 单列表多数据
+ */
+ @ApiOperation(value = "单列表多数据")
+ @GetMapping("/exportTemplateOne")
+ public void exportTemplateOne(HttpServletResponse response) {
+ Map map = new HashMap<>();
+ map.put("title","单列表多数据");
+ map.put("test1","数据测试1");
+ map.put("test2","数据测试2");
+ map.put("test3","数据测试3");
+ map.put("test4","数据测试4");
+ map.put("testTest","666");
+ List list = new ArrayList<>();
+ list.add(new TestObj("单列表测试1", "列表测试1", "列表测试2", "列表测试3", "列表测试4"));
+ list.add(new TestObj("单列表测试2", "列表测试5", "列表测试6", "列表测试7", "列表测试8"));
+ list.add(new TestObj("单列表测试3", "列表测试9", "列表测试10", "列表测试11", "列表测试12"));
+ ExcelUtil.exportTemplate(CollUtil.newArrayList(map,list),"单列表.xlsx", "excel/单列表.xlsx", response);
+ }
+
+ /**
+ * 多列表多数据
+ */
+ @ApiOperation(value = "多列表多数据")
+ @GetMapping("/exportTemplateMuliti")
+ public void exportTemplateMuliti(HttpServletResponse response) {
+ Map map = new HashMap<>();
+ map.put("title1","标题1");
+ map.put("title2","标题2");
+ map.put("title3","标题3");
+ map.put("title4","标题4");
+ map.put("author","Lion Li");
+ List list1 = new ArrayList<>();
+ list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3"));
+ list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6"));
+ list1.add(new TestObj1("list1测试7", "list1测试8", "list1测试9"));
+ List list2 = new ArrayList<>();
+ list2.add(new TestObj1("list2测试1", "list2测试2", "list2测试3"));
+ list2.add(new TestObj1("list2测试4", "list2测试5", "list2测试6"));
+ List list3 = new ArrayList<>();
+ list3.add(new TestObj1("list3测试1", "list3测试2", "list3测试3"));
+ List list4 = new ArrayList<>();
+ list4.add(new TestObj1("list4测试1", "list4测试2", "list4测试3"));
+ list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6"));
+ list4.add(new TestObj1("list4测试7", "list4测试8", "list4测试9"));
+ list4.add(new TestObj1("list4测试10", "list4测试11", "list4测试12"));
+ Map multiListMap = new HashMap<>();
+ multiListMap.put("map",map);
+ multiListMap.put("data1",list1);
+ multiListMap.put("data2",list2);
+ multiListMap.put("data3",list3);
+ multiListMap.put("data4",list4);
+ ExcelUtil.exportTemplateMultiList(multiListMap, "多列表.xlsx", "excel/多列表.xlsx", response);
+ }
+
+ @Data
+ @AllArgsConstructor
+ static class TestObj1 {
+ private String test1;
+ private String test2;
+ private String test3;
+ }
+
+ @Data
+ @AllArgsConstructor
+ static class TestObj {
+ private String name;
+ private String list1;
+ private String list2;
+ private String list3;
+ private String list4;
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java b/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java
index 5c41204d7..61c10ab16 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java
@@ -49,7 +49,7 @@ public class TestDemoBo extends BaseEntity {
*/
@ApiModelProperty("排序号")
@NotNull(message = "排序号不能为空", groups = {AddGroup.class, EditGroup.class})
- private Long orderNum;
+ private Integer orderNum;
/**
* key键
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java b/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java
index ef26ff325..1e896500d 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java
@@ -48,7 +48,7 @@ public class TestDemoVo {
*/
@ExcelProperty(value = "排序号")
@ApiModelProperty("排序号")
- private Long orderNum;
+ private Integer orderNum;
/**
* key键
diff --git a/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java b/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
index b1b80d26e..11a3d50e2 100644
--- a/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
+++ b/ruoyi/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
@@ -54,5 +54,5 @@ public interface TestDemoMapper extends BaseMapperPlus idList);
+ int deleteBatchIds(@Param(Constants.COLL) Collection> idList);
}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
index aedc4431c..b77acb40e 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
@@ -25,9 +25,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.time.Duration;
import java.util.Collection;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
/**
* 防止重复提交(参考美团GTIS防重系统)
@@ -66,7 +66,7 @@ public class RepeatSubmitAspect {
String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + url + submitKey;
String key = RedisUtils.getCacheObject(cacheRepeatKey);
if (key == null) {
- RedisUtils.setCacheObject(cacheRepeatKey, "", interval, TimeUnit.MILLISECONDS);
+ RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval));
KEY_CACHE.set(cacheRepeatKey);
} else {
String message = repeatSubmit.message();
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java
index a5d637165..eace537a5 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/JacksonConfig.java
@@ -1,17 +1,14 @@
package com.ruoyi.framework.config;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.ruoyi.framework.jackson.BigNumberSerializer;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -28,23 +25,22 @@ import java.util.TimeZone;
@Configuration
public class JacksonConfig {
- @Primary
@Bean
- public ObjectMapper getObjectMapper(Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) {
- ObjectMapper objectMapper = builder.createXmlMapper(false).build();
- // 全局配置序列化返回 JSON 处理
- SimpleModule simpleModule = new SimpleModule();
- simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
- simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
- simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
- simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat());
- simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
- simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
- objectMapper.registerModule(simpleModule);
- objectMapper.setTimeZone(TimeZone.getDefault());
- log.info("初始化 jackson 配置");
- return objectMapper;
+ public Jackson2ObjectMapperBuilderCustomizer customizer() {
+ return builder -> {
+ // 全局配置序列化返回 JSON 处理
+ JavaTimeModule javaTimeModule = new JavaTimeModule();
+ javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
+ javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
+ javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
+ javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
+ javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
+ builder.modules(javaTimeModule);
+ builder.timeZone(TimeZone.getDefault());
+ log.info("初始化 jackson 配置");
+ };
}
}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java
new file mode 100644
index 000000000..20769aa19
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/MailConfig.java
@@ -0,0 +1,35 @@
+package com.ruoyi.framework.config;
+
+import cn.hutool.extra.mail.MailAccount;
+import com.ruoyi.framework.config.properties.MailProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * JavaMail 配置
+ *
+ * @author Michelle.Chung
+ */
+@Configuration
+public class MailConfig {
+
+ @Bean
+ @ConditionalOnProperty(value = "mail.enabled", havingValue = "true")
+ public MailAccount mailAccount(MailProperties mailProperties) {
+ MailAccount account = new MailAccount();
+ account.setHost(mailProperties.getHost());
+ account.setPort(mailProperties.getPort());
+ account.setAuth(mailProperties.getAuth());
+ account.setFrom(mailProperties.getFrom());
+ account.setUser(mailProperties.getUser());
+ account.setPass(mailProperties.getPass());
+ account.setSocketFactoryPort(mailProperties.getPort());
+ account.setStarttlsEnable(mailProperties.getStarttlsEnable());
+ account.setSslEnable(mailProperties.getSslEnable());
+ account.setTimeout(mailProperties.getTimeout());
+ account.setConnectionTimeout(mailProperties.getConnectionTimeout());
+ return account;
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java
index da18cfd17..38a871895 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java
@@ -1,28 +1,25 @@
package com.ruoyi.framework.config;
import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.utils.StringUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.framework.config.properties.RedissonProperties;
import lombok.extern.slf4j.Slf4j;
-import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
-import org.redisson.config.Config;
import org.redisson.spring.cache.CacheConfig;
import org.redisson.spring.cache.RedissonSpringCacheManager;
+import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
/**
* redis配置
@@ -32,72 +29,49 @@ import java.util.stream.Collectors;
@Slf4j
@Configuration
@EnableCaching
+@EnableConfigurationProperties(RedissonProperties.class)
public class RedisConfig extends CachingConfigurerSupport {
- private static final String REDIS_PROTOCOL_PREFIX = "redis://";
- private static final String REDISS_PROTOCOL_PREFIX = "rediss://";
-
- @Autowired
- private RedisProperties redisProperties;
-
@Autowired
private RedissonProperties redissonProperties;
- @Primary
- @Bean(destroyMethod = "shutdown")
- public RedissonClient redisson() {
- String prefix = REDIS_PROTOCOL_PREFIX;
- if (redisProperties.isSsl()) {
- prefix = REDISS_PROTOCOL_PREFIX;
- }
- Config config = new Config();
- config.setThreads(redissonProperties.getThreads())
- .setNettyThreads(redissonProperties.getNettyThreads())
- .setCodec(JsonJacksonCodec.INSTANCE);
+ @Autowired
+ private ObjectMapper objectMapper;
- RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
- if (ObjectUtil.isNotNull(singleServerConfig)) {
- // 使用单机模式
- config.useSingleServer()
- .setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort())
- .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue())
- .setDatabase(redisProperties.getDatabase())
- .setPassword(StringUtils.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null)
- .setTimeout(singleServerConfig.getTimeout())
- .setClientName(singleServerConfig.getClientName())
- .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
- .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
- .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
- .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
- }
- // 集群配置方式 参考下方注释
- RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
- if (ObjectUtil.isNotNull(clusterServersConfig)) {
- // 使用集群模式
- String finalPrefix = prefix;
- List nodes = redisProperties.getCluster().getNodes()
- .stream()
- .map(node -> finalPrefix + node)
- .collect(Collectors.toList());
-
- config.useClusterServers()
- .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue())
- .setPassword(StringUtils.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null)
- .setTimeout(clusterServersConfig.getTimeout())
- .setClientName(clusterServersConfig.getClientName())
- .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
- .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
- .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
- .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
- .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
- .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
- .setReadMode(clusterServersConfig.getReadMode())
- .setSubscriptionMode(clusterServersConfig.getSubscriptionMode())
- .setNodeAddresses(nodes);
- }
- RedissonClient redissonClient = Redisson.create(config);
- log.info("初始化 redis 配置");
- return redissonClient;
+ @Bean
+ public RedissonAutoConfigurationCustomizer redissonCustomizer() {
+ return config -> {
+ config.setThreads(redissonProperties.getThreads())
+ .setNettyThreads(redissonProperties.getNettyThreads())
+ .setCodec(new JsonJacksonCodec(objectMapper));
+ RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
+ if (ObjectUtil.isNotNull(singleServerConfig)) {
+ // 使用单机模式
+ config.useSingleServer()
+ .setTimeout(singleServerConfig.getTimeout())
+ .setClientName(singleServerConfig.getClientName())
+ .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
+ .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
+ .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
+ .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
+ }
+ // 集群配置方式 参考下方注释
+ RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
+ if (ObjectUtil.isNotNull(clusterServersConfig)) {
+ config.useClusterServers()
+ .setTimeout(clusterServersConfig.getTimeout())
+ .setClientName(clusterServersConfig.getClientName())
+ .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
+ .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
+ .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
+ .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
+ .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
+ .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
+ .setReadMode(clusterServersConfig.getReadMode())
+ .setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
+ }
+ log.info("初始化 redis 配置");
+ };
}
/**
@@ -112,7 +86,7 @@ public class RedisConfig extends CachingConfigurerSupport {
cacheConfig.setMaxSize(group.getMaxSize());
config.put(group.getGroupId(), cacheConfig);
}
- return new RedissonSpringCacheManager(redissonClient, config, JsonJacksonCodec.INSTANCE);
+ return new RedissonSpringCacheManager(redissonClient, config, new JsonJacksonCodec(objectMapper));
}
/**
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java
index 671400f6f..a5be2678e 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/SaTokenConfig.java
@@ -2,11 +2,12 @@ package com.ruoyi.framework.config;
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
-import cn.dev33.satoken.jwt.StpLogicJwtForStyle;
+import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
-import com.ruoyi.common.helper.LoginHelper;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.framework.config.properties.ExcludeUrlProperties;
import com.ruoyi.framework.config.properties.SecurityProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -15,9 +16,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
/**
* sa-token 配置
*
@@ -37,12 +35,14 @@ public class SaTokenConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
// 注册路由拦截器,自定义验证规则
registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> {
+ ExcludeUrlProperties excludeUrlProperties = SpringUtils.getBean(ExcludeUrlProperties.class);
// 登录验证 -- 排除多个路径
SaRouter
// 获取所有的
.match("/**")
// 排除下不需要拦截的
.notMatch(securityProperties.getExcludes())
+ .notMatch(excludeUrlProperties.getExcludes())
// 对未排除的路径进行检查
.check(() -> {
// 检查是否登录 是否有token
@@ -55,20 +55,14 @@ public class SaTokenConfig implements WebMvcConfigurer {
// }
});
- }) {
- @SuppressWarnings("all")
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- LoginHelper.clearCache();
- }
- }).addPathPatterns("/**");
+ })).addPathPatterns("/**");
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
}
@Bean
public StpLogic getStpLogicJwt() {
- // Sa-Token 整合 jwt (Style模式)
- return new StpLogicJwtForStyle();
+ // Sa-Token 整合 jwt (简单模式)
+ return new StpLogicJwtForSimple();
}
}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
index 22ef7c1b5..2424981c1 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
@@ -109,7 +109,7 @@ public class SwaggerConfig {
* 安全模式,这里指定token通过Authorization头请求头传递
*/
private List securitySchemes() {
- List apiKeyList = new ArrayList();
+ List apiKeyList = new ArrayList<>();
String header = saTokenConfig.getTokenName();
apiKeyList.add(new ApiKey(header, header, In.HEADER.toValue()));
return apiKeyList;
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
index ebf236c87..a85ad1e57 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
@@ -33,8 +33,8 @@ public class ThreadPoolConfig {
@ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
- executor.setMaxPoolSize(core);
- executor.setCorePoolSize(core * 2);
+ executor.setCorePoolSize(core);
+ executor.setMaxPoolSize(core * 2);
executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java
new file mode 100644
index 000000000..64e745a86
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/UndertowConfig.java
@@ -0,0 +1,30 @@
+package com.ruoyi.framework.config;
+
+import io.undertow.server.DefaultByteBufferPool;
+import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
+import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Undertow 自定义配置
+ *
+ * @author Lion Li
+ */
+@Configuration
+public class UndertowConfig implements WebServerFactoryCustomizer {
+
+ /**
+ * 设置 Undertow 的 websocket 缓冲池
+ */
+ @Override
+ public void customize(UndertowServletWebServerFactory factory) {
+ // 默认不直接分配内存 如果项目中使用了 websocket 建议直接分配
+ factory.addDeploymentInfoCustomizers(deploymentInfo -> {
+ WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
+ webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 512));
+ deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
+ });
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java
new file mode 100644
index 000000000..b4e3eae6d
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/ExcludeUrlProperties.java
@@ -0,0 +1,61 @@
+package com.ruoyi.framework.config.properties;
+
+import cn.hutool.core.util.ReUtil;
+import com.ruoyi.common.annotation.Anonymous;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import lombok.Getter;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * 设置注解允许匿名访问的url
+ *
+ * @author Lion Li
+ */
+@Lazy
+@Component
+public class ExcludeUrlProperties implements InitializingBean {
+
+ private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
+
+ @Getter
+ private final List excludes = new ArrayList<>();
+
+ @Override
+ public void afterPropertiesSet() {
+ String asterisk = "*";
+ RequestMappingHandlerMapping mapping = SpringUtils.getBean(RequestMappingHandlerMapping.class);
+ Map map = mapping.getHandlerMethods();
+
+ map.keySet().forEach(info -> {
+ HandlerMethod handlerMethod = map.get(info);
+
+ // 获取方法上边的注解 替代path variable 为 *
+ Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
+ Optional.ofNullable(method).ifPresent(anonymous -> {
+ Set patterns = info.getPatternsCondition().getPatterns();
+ patterns.forEach(url -> {
+ excludes.add(ReUtil.replaceAll(url, PATTERN, asterisk));
+ });
+ });
+
+ // 获取类上边的注解, 替代path variable 为 *
+ Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
+ Optional.ofNullable(controller).ifPresent(anonymous -> {
+ Set patterns = info.getPatternsCondition().getPatterns();
+ patterns.forEach(url -> {
+ excludes.add(ReUtil.replaceAll(url, PATTERN, asterisk));
+ });
+ });
+ });
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java
new file mode 100644
index 000000000..95e6cb8ba
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/MailProperties.java
@@ -0,0 +1,71 @@
+package com.ruoyi.framework.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * JavaMail 配置属性
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "mail")
+public class MailProperties {
+
+ /**
+ * 过滤开关
+ */
+ private Boolean enabled;
+
+ /**
+ * SMTP服务器域名
+ */
+ private String host;
+
+ /**
+ * SMTP服务端口
+ */
+ private Integer port;
+
+ /**
+ * 是否需要用户名密码验证
+ */
+ private Boolean auth;
+
+ /**
+ * 用户名
+ */
+ private String user;
+
+ /**
+ * 密码
+ */
+ private String pass;
+
+ /**
+ * 发送方,遵循RFC-822标准
+ */
+ private String from;
+
+ /**
+ * 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。它将纯文本连接升级为加密连接(TLS或SSL), 而不是使用一个单独的加密通信端口。
+ */
+ private Boolean starttlsEnable;
+
+ /**
+ * 使用 SSL安全连接
+ */
+ private Boolean sslEnable;
+
+ /**
+ * SMTP超时时长,单位毫秒,缺省值不超时
+ */
+ private Long timeout;
+
+ /**
+ * Socket连接超时值,单位毫秒,缺省值不超时
+ */
+ private Long connectionTimeout;
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java b/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java
index 75277c257..dcb9b1996 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/listener/UserActionListener.java
@@ -3,7 +3,6 @@ package com.ruoyi.framework.listener;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
-import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.ruoyi.common.constant.Constants;
@@ -18,7 +17,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
-import java.util.concurrent.TimeUnit;
+import java.time.Duration;
/**
* 用户行为 侦听器的实现
@@ -36,13 +35,12 @@ public class UserActionListener implements SaTokenListener {
* 每次登录时触发
*/
@Override
- public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {
+ public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
UserType userType = UserType.getUserType(loginId.toString());
if (userType == UserType.SYS_USER) {
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = ServletUtils.getClientIP();
LoginUser user = LoginHelper.getLoginUser();
- String tokenValue = StpUtil.getTokenValueByLoginId(loginId);
UserOnlineDTO dto = new UserOnlineDTO();
dto.setIpaddr(ip);
dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
@@ -52,7 +50,7 @@ public class UserActionListener implements SaTokenListener {
dto.setTokenId(tokenValue);
dto.setUserName(user.getUsername());
dto.setDeptName(user.getDeptName());
- RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, dto, tokenConfig.getTimeout(), TimeUnit.SECONDS);
+ RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
} else if (userType == UserType.APP_USER) {
// app端 自行根据业务编写
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java b/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java
index f78e81415..68df5a646 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/satoken/dao/PlusSaTokenDao.java
@@ -5,10 +5,10 @@ import cn.dev33.satoken.util.SaFoxUtil;
import com.ruoyi.common.utils.redis.RedisUtils;
import org.springframework.stereotype.Component;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.TimeUnit;
/**
* Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一)
@@ -38,7 +38,7 @@ public class PlusSaTokenDao implements SaTokenDao {
if (timeout == SaTokenDao.NEVER_EXPIRE) {
RedisUtils.setCacheObject(key, value);
} else {
- RedisUtils.setCacheObject(key, value, timeout, TimeUnit.SECONDS);
+ RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout));
}
}
@@ -68,7 +68,8 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public long getTimeout(String key) {
- return RedisUtils.getTimeToLive(key) / 1000;
+ long timeout = RedisUtils.getTimeToLive(key);
+ return timeout < 0 ? timeout : timeout / 1000;
}
/**
@@ -87,7 +88,7 @@ public class PlusSaTokenDao implements SaTokenDao {
}
return;
}
- RedisUtils.expire(key, timeout, TimeUnit.SECONDS);
+ RedisUtils.expire(key, Duration.ofSeconds(timeout));
}
@@ -111,7 +112,7 @@ public class PlusSaTokenDao implements SaTokenDao {
if (timeout == SaTokenDao.NEVER_EXPIRE) {
RedisUtils.setCacheObject(key, object);
} else {
- RedisUtils.setCacheObject(key, object, timeout, TimeUnit.SECONDS);
+ RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout));
}
}
@@ -141,7 +142,8 @@ public class PlusSaTokenDao implements SaTokenDao {
*/
@Override
public long getObjectTimeout(String key) {
- return RedisUtils.getTimeToLive(key) / 1000;
+ long timeout = RedisUtils.getTimeToLive(key);
+ return timeout < 0 ? timeout : timeout / 1000;
}
/**
@@ -160,7 +162,7 @@ public class PlusSaTokenDao implements SaTokenDao {
}
return;
}
- RedisUtils.expire(key, timeout, TimeUnit.SECONDS);
+ RedisUtils.expire(key, Duration.ofSeconds(timeout));
}
diff --git a/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
index 9dccab2d1..2a99a2e65 100644
--- a/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
@@ -33,6 +33,7 @@ import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -135,6 +136,7 @@ public class GenTableServiceImpl implements IGenTableService {
* @param genTable 业务信息
* @return 结果
*/
+ @Transactional(rollbackFor = Exception.class)
@Override
public void updateGenTable(GenTable genTable) {
String options = JsonUtils.toJsonString(genTable.getParams());
@@ -153,6 +155,7 @@ public class GenTableServiceImpl implements IGenTableService {
* @param tableIds 需要删除的数据ID
* @return 结果
*/
+ @Transactional(rollbackFor = Exception.class)
@Override
public void deleteGenTableByIds(Long[] tableIds) {
List ids = Arrays.asList(tableIds);
@@ -165,6 +168,7 @@ public class GenTableServiceImpl implements IGenTableService {
*
* @param tableList 导入表列表
*/
+ @Transactional(rollbackFor = Exception.class)
@Override
public void importGenTable(List tableList) {
String operName = LoginHelper.getUsername();
@@ -284,6 +288,7 @@ public class GenTableServiceImpl implements IGenTableService {
*
* @param tableName 表名称
*/
+ @Transactional(rollbackFor = Exception.class)
@Override
public void synchDb(String tableName) {
GenTable table = baseMapper.selectGenTableByName(tableName);
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java b/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java
index 6c00cd8db..1d1a77708 100644
--- a/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java
+++ b/ruoyi/src/main/java/com/ruoyi/oss/constant/OssConstant.java
@@ -35,6 +35,11 @@ public interface OssConstant {
*/
List SYSTEM_DATA_IDS = Arrays.asList(1, 2, 3, 4);
+ /**
+ * 云服务商
+ */
+ String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu"};
+
/**
* https 状态
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java b/ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java
new file mode 100644
index 000000000..6f6be8f8c
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/oss/core/OssClient.java
@@ -0,0 +1,188 @@
+package com.ruoyi.oss.core;
+
+import cn.hutool.core.util.IdUtil;
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.Protocol;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.model.CannedAccessControlList;
+import com.amazonaws.services.s3.model.CreateBucketRequest;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.oss.constant.OssConstant;
+import com.ruoyi.oss.entity.UploadResult;
+import com.ruoyi.oss.enumd.PolicyType;
+import com.ruoyi.oss.exception.OssException;
+import com.ruoyi.oss.properties.OssProperties;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * S3 存储协议 所有兼容S3协议的云厂商均支持
+ * 阿里云 腾讯云 七牛云 minio
+ *
+ * @author Lion Li
+ */
+public class OssClient {
+
+ private final String configKey;
+
+ private final OssProperties properties;
+
+ private final AmazonS3 client;
+
+ public OssClient(String configKey, OssProperties ossProperties) {
+ this.configKey = configKey;
+ this.properties = ossProperties;
+ try {
+ AwsClientBuilder.EndpointConfiguration endpointConfig =
+ new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
+
+ AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
+ AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
+ ClientConfiguration clientConfig = new ClientConfiguration();
+ if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
+ clientConfig.setProtocol(Protocol.HTTPS);
+ } else {
+ clientConfig.setProtocol(Protocol.HTTP);
+ }
+ this.client = AmazonS3Client.builder()
+ .withEndpointConfiguration(endpointConfig)
+ .withClientConfiguration(clientConfig)
+ .withCredentials(credentialsProvider)
+ .disableChunkedEncoding()
+ .build();
+
+ createBucket();
+ } catch (Exception e) {
+ if (e instanceof OssException) {
+ throw e;
+ }
+ throw new OssException("配置错误! 请检查系统配置:[" + e.getMessage() + "]");
+ }
+ }
+
+ public void createBucket() {
+ try {
+ String bucketName = properties.getBucketName();
+ if (client.doesBucketExistV2(bucketName)) {
+ return;
+ }
+ CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+ createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead);
+ client.createBucket(createBucketRequest);
+ client.setBucketPolicy(bucketName, getPolicy(bucketName, PolicyType.READ));
+ } catch (Exception e) {
+ throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]");
+ }
+ }
+
+ public UploadResult upload(byte[] data, String path, String contentType) {
+ return upload(new ByteArrayInputStream(data), path, contentType);
+ }
+
+ public UploadResult upload(InputStream inputStream, String path, String contentType) {
+ try {
+ ObjectMetadata metadata = new ObjectMetadata();
+ metadata.setContentType(contentType);
+ metadata.setContentLength(inputStream.available());
+ client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata));
+ } catch (Exception e) {
+ throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
+ }
+ return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
+ }
+
+ public void delete(String path) {
+ path = path.replace(getUrl() + "/", "");
+ try {
+ client.deleteObject(properties.getBucketName(), path);
+ } catch (Exception e) {
+ throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
+ }
+ }
+
+ public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
+ return upload(data, getPath(properties.getPrefix(), suffix), contentType);
+ }
+
+ public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
+ return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
+ }
+
+ public String getUrl() {
+ String domain = properties.getDomain();
+ if (StringUtils.isNotBlank(domain)) {
+ return domain;
+ }
+ String endpoint = properties.getEndpoint();
+ String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
+ // 云服务商直接返回
+ if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)){
+ return header + properties.getBucketName() + "." + endpoint;
+ }
+ // minio 单独处理
+ return header + endpoint + "/" + properties.getBucketName();
+ }
+
+ public String getPath(String prefix, String suffix) {
+ // 生成uuid
+ String uuid = IdUtil.fastSimpleUUID();
+ // 文件路径
+ String path = DateUtils.datePath() + "/" + uuid;
+ if (StringUtils.isNotBlank(prefix)) {
+ path = prefix + "/" + path;
+ }
+ return path + suffix;
+ }
+
+
+ public String getConfigKey() {
+ return configKey;
+ }
+
+ private static String getPolicy(String bucketName, PolicyType policyType) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
+ if (policyType == PolicyType.WRITE) {
+ builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n");
+ } else if (policyType == PolicyType.READ_WRITE) {
+ builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n");
+ } else {
+ builder.append("\"s3:GetBucketLocation\"\n");
+ }
+ builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+ builder.append(bucketName);
+ builder.append("\"\n},\n");
+ if (policyType == PolicyType.READ) {
+ builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+ builder.append(bucketName);
+ builder.append("\"\n},\n");
+ }
+ builder.append("{\n\"Action\": ");
+ switch (policyType) {
+ case WRITE:
+ builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n");
+ break;
+ case READ_WRITE:
+ builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n");
+ break;
+ default:
+ builder.append("\"s3:GetObject\",\n");
+ break;
+ }
+ builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+ builder.append(bucketName);
+ builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
+ return builder.toString();
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java b/ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java
deleted file mode 100644
index e16a67338..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.oss.enumd;
-
-import com.ruoyi.oss.service.impl.AliyunOssStrategy;
-import com.ruoyi.oss.service.impl.MinioOssStrategy;
-import com.ruoyi.oss.service.impl.QcloudOssStrategy;
-import com.ruoyi.oss.service.impl.QiniuOssStrategy;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 对象存储服务商枚举
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum OssEnumd {
-
- /**
- * 七牛云
- */
- QINIU("qiniu", QiniuOssStrategy.class),
-
- /**
- * 阿里云
- */
- ALIYUN("aliyun", AliyunOssStrategy.class),
-
- /**
- * 腾讯云
- */
- QCLOUD("qcloud", QcloudOssStrategy.class),
-
- /**
- * minio
- */
- MINIO("minio", MinioOssStrategy.class);
-
- private final String value;
-
- private final Class> beanClass;
-
- public static OssEnumd find(String value) {
- for (OssEnumd enumd : values()) {
- if (enumd.getValue().equals(value)) {
- return enumd;
- }
- }
- return null;
- }
-
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java b/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java
index e1925dcfb..606f0f484 100644
--- a/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java
+++ b/ruoyi/src/main/java/com/ruoyi/oss/enumd/PolicyType.java
@@ -1,19 +1,3 @@
-/*
- * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the dreamlu.net developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: Chill 庄骞 (smallchill@163.com)
- */
package com.ruoyi.oss.enumd;
import lombok.AllArgsConstructor;
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java b/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java
index 9ac887e65..7065c4a4a 100644
--- a/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java
+++ b/ruoyi/src/main/java/com/ruoyi/oss/factory/OssFactory.java
@@ -3,15 +3,15 @@ package com.ruoyi.oss.factory;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.oss.constant.OssConstant;
-import com.ruoyi.oss.enumd.OssEnumd;
+import com.ruoyi.oss.core.OssClient;
import com.ruoyi.oss.exception.OssException;
import com.ruoyi.oss.properties.OssProperties;
-import com.ruoyi.oss.service.IOssStrategy;
-import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
import lombok.extern.slf4j.Slf4j;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* 文件上传Factory
*
@@ -20,17 +20,19 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class OssFactory {
+ private static final Map CLIENT_CACHE = new ConcurrentHashMap<>();
+
/**
* 初始化工厂
*/
public static void init() {
log.info("初始化OSS工厂");
- RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, type -> {
- AbstractOssStrategy strategy = getStrategy(type);
+ RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, configKey -> {
+ OssClient client = getClient(configKey);
// 未初始化不处理
- if (strategy.isInit) {
- refresh(type);
- log.info("订阅刷新OSS配置 => " + type);
+ if (client != null) {
+ refresh(configKey);
+ log.info("订阅刷新OSS配置 => " + configKey);
}
});
}
@@ -38,42 +40,38 @@ public class OssFactory {
/**
* 获取默认实例
*/
- public static IOssStrategy instance() {
+ public static OssClient instance() {
// 获取redis 默认类型
- String type = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY);
- if (StringUtils.isEmpty(type)) {
+ String configKey = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY);
+ if (StringUtils.isEmpty(configKey)) {
throw new OssException("文件存储服务类型无法找到!");
}
- return instance(type);
+ return instance(configKey);
}
/**
* 根据类型获取实例
*/
- public static IOssStrategy instance(String type) {
- OssEnumd enumd = OssEnumd.find(type);
- if (enumd == null) {
- throw new OssException("文件存储服务类型无法找到!");
+ public static OssClient instance(String configKey) {
+ OssClient client = getClient(configKey);
+ if (client == null) {
+ refresh(configKey);
+ return getClient(configKey);
}
- AbstractOssStrategy strategy = getStrategy(type);
- if (!strategy.isInit) {
- refresh(type);
- }
- return strategy;
+ return client;
}
- private static void refresh(String type) {
- Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + type);
+ private static void refresh(String configKey) {
+ Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + configKey);
OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class);
if (properties == null) {
- throw new OssException("系统异常, '" + type + "'配置信息不存在!");
+ throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");
}
- getStrategy(type).init(properties);
+ CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
}
- private static AbstractOssStrategy getStrategy(String type) {
- OssEnumd enumd = OssEnumd.find(type);
- return (AbstractOssStrategy) SpringUtils.getBean(enumd.getBeanClass());
+ private static OssClient getClient(String configKey) {
+ return CLIENT_CACHE.get(configKey);
}
}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java b/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java
index d09bfdb69..a01777901 100644
--- a/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java
+++ b/ruoyi/src/main/java/com/ruoyi/oss/properties/OssProperties.java
@@ -11,10 +11,15 @@ import lombok.Data;
public class OssProperties {
/**
- * 域名
+ * 访问站点
*/
private String endpoint;
+ /**
+ * 自定义域名
+ */
+ private String domain;
+
/**
* 前缀
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java
deleted file mode 100644
index 981c23e9e..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/service/IOssStrategy.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.oss.service;
-
-import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.OssEnumd;
-
-import java.io.InputStream;
-
-/**
- * 对象存储策略
- *
- * @author Lion Li
- */
-public interface IOssStrategy {
-
- /**
- * 创建存储桶
- */
- void createBucket();
-
- /**
- * 获取服务商类型
- * @return 对象存储服务商枚举
- */
- OssEnumd getServiceType();
-
- /**
- * 文件上传
- *
- * @param data 文件字节数组
- * @param path 文件路径,包含文件名
- * @param contentType 文件类型
- * @return 返回http地址
- */
- UploadResult upload(byte[] data, String path, String contentType);
-
- /**
- * 文件删除
- *
- * @param path 文件路径,包含文件名
- */
- void delete(String path);
-
- /**
- * 文件上传
- *
- * @param data 文件字节数组
- * @param suffix 后缀
- * @param contentType 文件类型
- * @return 返回http地址
- */
- UploadResult uploadSuffix(byte[] data, String suffix, String contentType);
-
- /**
- * 文件上传
- *
- * @param inputStream 字节流
- * @param path 文件路径,包含文件名
- * @param contentType 文件类型
- * @return 返回http地址
- */
- UploadResult upload(InputStream inputStream, String path, String contentType);
-
- /**
- * 文件上传
- *
- * @param inputStream 字节流
- * @param suffix 后缀
- * @param contentType 文件类型
- * @return 返回http地址
- */
- UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
-
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java
deleted file mode 100644
index ae17c19de..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.ruoyi.oss.service.abstractd;
-
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.IdUtil;
-import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.OssEnumd;
-import com.ruoyi.oss.properties.OssProperties;
-import com.ruoyi.oss.service.IOssStrategy;
-
-import java.io.InputStream;
-
-/**
- * 对象存储策略(支持七牛、阿里云、腾讯云、minio)
- *
- * @author Lion Li
- */
-public abstract class AbstractOssStrategy implements IOssStrategy {
-
- protected OssProperties properties;
- public boolean isInit = false;
-
- public void init(OssProperties properties) {
- this.properties = properties;
- }
-
- @Override
- public abstract void createBucket();
-
- @Override
- public abstract OssEnumd getServiceType();
-
- public String getPath(String prefix, String suffix) {
- // 生成uuid
- String uuid = IdUtil.fastSimpleUUID();
- // 文件路径
- String path = DateUtils.datePath() + "/" + uuid;
- if (StringUtils.isNotBlank(prefix)) {
- path = prefix + "/" + path;
- }
- return path + suffix;
- }
-
- @Override
- public abstract UploadResult upload(byte[] data, String path, String contentType);
-
- @Override
- public abstract void delete(String path);
-
- @Override
- public UploadResult upload(InputStream inputStream, String path, String contentType) {
- byte[] data = IoUtil.readBytes(inputStream);
- return this.upload(data, path, contentType);
- }
-
- @Override
- public abstract UploadResult uploadSuffix(byte[] data, String suffix, String contentType);
-
- @Override
- public abstract UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
-
- /**
- * 获取域名访问链接
- *
- * @return 域名访问链接
- */
- public abstract String getEndpointLink();
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java
deleted file mode 100644
index 62c29228f..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.ruoyi.oss.service.impl;
-
-import com.aliyun.oss.ClientConfiguration;
-import com.aliyun.oss.OSSClient;
-import com.aliyun.oss.common.auth.DefaultCredentialProvider;
-import com.aliyun.oss.common.comm.Protocol;
-import com.aliyun.oss.model.CannedAccessControlList;
-import com.aliyun.oss.model.CreateBucketRequest;
-import com.aliyun.oss.model.ObjectMetadata;
-import com.aliyun.oss.model.PutObjectRequest;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.oss.constant.OssConstant;
-import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.OssEnumd;
-import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.OssProperties;
-import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
-import org.springframework.stereotype.Component;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-/**
- * 阿里云存储策略
- *
- * @author Lion Li
- */
-@Component
-public class AliyunOssStrategy extends AbstractOssStrategy {
-
- private OSSClient client;
-
- @Override
- public void init(OssProperties ossProperties) {
- super.init(ossProperties);
- try {
- ClientConfiguration configuration = new ClientConfiguration();
- if (OssConstant.IS_HTTPS.equals(ossProperties.getIsHttps())) {
- configuration.setProtocol(Protocol.HTTPS);
- }
- DefaultCredentialProvider credentialProvider = new DefaultCredentialProvider(
- properties.getAccessKey(), properties.getSecretKey());
- client = new OSSClient(properties.getEndpoint(), credentialProvider, configuration);
- createBucket();
- } catch (Exception e) {
- throw new OssException("阿里云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
- }
- isInit = true;
- }
-
- @Override
- public void createBucket() {
- try {
- String bucketName = properties.getBucketName();
- if (client.doesBucketExist(bucketName)) {
- return;
- }
- CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
- createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
- client.createBucket(createBucketRequest);
- } catch (Exception e) {
- throw new OssException("创建Bucket失败, 请核对阿里云配置信息:[" + e.getMessage() + "]");
- }
- }
-
- @Override
- public OssEnumd getServiceType() {
- return OssEnumd.ALIYUN;
- }
-
- @Override
- public UploadResult upload(byte[] data, String path, String contentType) {
- return upload(new ByteArrayInputStream(data), path, contentType);
- }
-
- @Override
- public UploadResult upload(InputStream inputStream, String path, String contentType) {
- try {
- ObjectMetadata metadata = new ObjectMetadata();
- metadata.setContentType(contentType);
- client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata));
- } catch (Exception e) {
- throw new OssException("上传文件失败,请检查阿里云配置信息:[" + e.getMessage() + "]");
- }
- return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build(); }
-
- @Override
- public void delete(String path) {
- path = path.replace(getEndpointLink() + "/", "");
- try {
- client.deleteObject(properties.getBucketName(), path);
- } catch (Exception e) {
- throw new OssException("上传文件失败,请检查阿里云配置信息:[" + e.getMessage() + "]");
- }
- }
-
- @Override
- public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
- return upload(data, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
- return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public String getEndpointLink() {
- String endpoint = properties.getEndpoint();
- StringBuilder sb = new StringBuilder(endpoint);
- if (StringUtils.containsAnyIgnoreCase(endpoint, "http://")) {
- sb.insert(7, properties.getBucketName() + ".");
- } else if (StringUtils.containsAnyIgnoreCase(endpoint, "https://")) {
- sb.insert(8, properties.getBucketName() + ".");
- } else {
- throw new OssException("Endpoint配置错误");
- }
- return sb.toString();
- }
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java
deleted file mode 100644
index f5be957fa..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java
+++ /dev/null
@@ -1,194 +0,0 @@
-package com.ruoyi.oss.service.impl;
-
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.oss.constant.OssConstant;
-import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.OssEnumd;
-import com.ruoyi.oss.enumd.PolicyType;
-import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.OssProperties;
-import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
-import io.minio.*;
-import io.minio.http.HttpUtils;
-import okhttp3.HttpUrl;
-import org.springframework.http.MediaType;
-import org.springframework.stereotype.Component;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-/**
- * minio存储策略
- *
- * @author Lion Li
- */
-@Component
-public class MinioOssStrategy extends AbstractOssStrategy {
-
- private MinioClient minioClient;
-
- @Override
- public void init(OssProperties ossProperties) {
- super.init(ossProperties);
- try {
- MinioClient.Builder builder = MinioClient.builder();
- if (OssConstant.IS_HTTPS.equals(ossProperties.getIsHttps())) {
- HttpUrl url = HttpUtils.getBaseUrl(properties.getEndpoint())
- .newBuilder().scheme("https").build();
- builder.endpoint(url);
- } else {
- builder.endpoint(properties.getEndpoint());
- }
- minioClient = builder.credentials(properties.getAccessKey(), properties.getSecretKey()).build();
- createBucket();
- } catch (Exception e) {
- throw new OssException("Minio存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
- }
- isInit = true;
- }
-
- @Override
- public void createBucket() {
- try {
- String bucketName = properties.getBucketName();
- boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
- if (exists) {
- return;
- }
- // 不存在就创建桶
- minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
- minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
- .bucket(bucketName)
- .config(getPolicy(bucketName, PolicyType.READ))
- .build());
- } catch (Exception e) {
- throw new OssException("创建Bucket失败, 请核对Minio配置信息:[" + e.getMessage() + "]");
- }
- }
-
- @Override
- public OssEnumd getServiceType() {
- return OssEnumd.MINIO;
- }
-
- @Override
- public UploadResult upload(byte[] data, String path, String contentType) {
- return upload(new ByteArrayInputStream(data), path, contentType);
- }
-
- @Override
- public UploadResult upload(InputStream inputStream, String path, String contentType) {
- try {
- // 解决 inputStream.available() 再 socket 下传输延迟问题 导致获取数值不精确
- Thread.sleep(1000);
- minioClient.putObject(PutObjectArgs.builder()
- .bucket(properties.getBucketName())
- .object(path)
- .contentType(StringUtils.blankToDefault(contentType, MediaType.APPLICATION_OCTET_STREAM_VALUE))
- .stream(inputStream, inputStream.available(), -1)
- .build());
- } catch (Exception e) {
- throw new OssException("上传文件失败,请核对Minio配置信息:[" + e.getMessage() + "]");
- }
- return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build();
- }
-
- @Override
- public void delete(String path) {
- path = path.replace(getEndpointLink() + "/", "");
- try {
- minioClient.removeObject(RemoveObjectArgs.builder()
- .bucket(properties.getBucketName())
- .object(path)
- .build());
- } catch (Exception e) {
- throw new OssException(e.getMessage());
- }
- }
-
- @Override
- public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
- return upload(data, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
- return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public String getEndpointLink() {
- return properties.getEndpoint() + "/" + properties.getBucketName();
- }
-
- private String getPolicy(String bucketName, PolicyType policyType) {
- StringBuilder builder = new StringBuilder();
- builder.append("{\n");
- builder.append(" \"Statement\": [\n");
- builder.append(" {\n");
- builder.append(" \"Action\": [\n");
- if (policyType == PolicyType.WRITE) {
- builder.append(" \"s3:GetBucketLocation\",\n");
- builder.append(" \"s3:ListBucketMultipartUploads\"\n");
- } else if (policyType == PolicyType.READ_WRITE) {
- builder.append(" \"s3:GetBucketLocation\",\n");
- builder.append(" \"s3:ListBucket\",\n");
- builder.append(" \"s3:ListBucketMultipartUploads\"\n");
- } else {
- builder.append(" \"s3:GetBucketLocation\"\n");
- }
- builder.append(" ],\n");
- builder.append(" \"Effect\": \"Allow\",\n");
- builder.append(" \"Principal\": \"*\",\n");
- builder.append(" \"Resource\": \"arn:aws:s3:::");
- builder.append(bucketName);
- builder.append("\"\n");
- builder.append(" },\n");
- if (PolicyType.READ.equals(policyType)) {
- builder.append(" {\n");
- builder.append(" \"Action\": [\n");
- builder.append(" \"s3:ListBucket\"\n");
- builder.append(" ],\n");
- builder.append(" \"Effect\": \"Deny\",\n");
- builder.append(" \"Principal\": \"*\",\n");
- builder.append(" \"Resource\": \"arn:aws:s3:::");
- builder.append(bucketName);
- builder.append("\"\n");
- builder.append(" },\n");
- }
- builder.append(" {\n");
- builder.append(" \"Action\": ");
- switch (policyType) {
- case WRITE:
- builder.append("[\n");
- builder.append(" \"s3:AbortMultipartUpload\",\n");
- builder.append(" \"s3:DeleteObject\",\n");
- builder.append(" \"s3:ListMultipartUploadParts\",\n");
- builder.append(" \"s3:PutObject\"\n");
- builder.append(" ],\n");
- break;
- case READ_WRITE:
- builder.append("[\n");
- builder.append(" \"s3:AbortMultipartUpload\",\n");
- builder.append(" \"s3:DeleteObject\",\n");
- builder.append(" \"s3:GetObject\",\n");
- builder.append(" \"s3:ListMultipartUploadParts\",\n");
- builder.append(" \"s3:PutObject\"\n");
- builder.append(" ],\n");
- break;
- default:
- builder.append("\"s3:GetObject\",\n");
- break;
- }
- builder.append(" \"Effect\": \"Allow\",\n");
- builder.append(" \"Principal\": \"*\",\n");
- builder.append(" \"Resource\": \"arn:aws:s3:::");
- builder.append(bucketName);
- builder.append("/*\"\n");
- builder.append(" }\n");
- builder.append(" ],\n");
- builder.append(" \"Version\": \"2012-10-17\"\n");
- builder.append("}\n");
- return builder.toString();
- }
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java
deleted file mode 100644
index 756462e4d..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.ruoyi.oss.service.impl;
-
-import com.qcloud.cos.COSClient;
-import com.qcloud.cos.ClientConfig;
-import com.qcloud.cos.auth.BasicCOSCredentials;
-import com.qcloud.cos.auth.COSCredentials;
-import com.qcloud.cos.http.HttpProtocol;
-import com.qcloud.cos.model.*;
-import com.qcloud.cos.region.Region;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.oss.constant.OssConstant;
-import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.OssEnumd;
-import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.OssProperties;
-import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
-import org.springframework.stereotype.Component;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-/**
- * 腾讯云存储策略
- *
- * @author Lion Li
- */
-@Component
-public class QcloudOssStrategy extends AbstractOssStrategy {
-
- private COSClient client;
-
- @Override
- public void init(OssProperties ossProperties) {
- super.init(ossProperties);
- try {
- COSCredentials credentials = new BasicCOSCredentials(
- properties.getAccessKey(), properties.getSecretKey());
- // 初始化客户端配置
- ClientConfig clientConfig = new ClientConfig();
- // 设置bucket所在的区域,华南:gz 华北:tj 华东:sh
- clientConfig.setRegion(new Region(properties.getRegion()));
- if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
- clientConfig.setHttpProtocol(HttpProtocol.https);
- } else {
- clientConfig.setHttpProtocol(HttpProtocol.http);
- }
- client = new COSClient(credentials, clientConfig);
- createBucket();
- } catch (Exception e) {
- throw new OssException("腾讯云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
- }
- isInit = true;
- }
-
- @Override
- public void createBucket() {
- try {
- String bucketName = properties.getBucketName();
- if (client.doesBucketExist(bucketName)) {
- return;
- }
- CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
- createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead);
- client.createBucket(createBucketRequest);
- } catch (Exception e) {
- throw new OssException("创建Bucket失败, 请核对腾讯云配置信息:[" + e.getMessage() + "]");
- }
- }
-
- @Override
- public OssEnumd getServiceType() {
- return OssEnumd.QCLOUD;
- }
-
- @Override
- public UploadResult upload(byte[] data, String path, String contentType) {
- return upload(new ByteArrayInputStream(data), path, contentType);
- }
-
- @Override
- public UploadResult upload(InputStream inputStream, String path, String contentType) {
- try {
- ObjectMetadata metadata = new ObjectMetadata();
- metadata.setContentType(contentType);
- client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata));
- } catch (Exception e) {
- throw new OssException("上传文件失败,请检查腾讯云配置信息:[" + e.getMessage() + "]");
- }
- return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build();
- }
-
- @Override
- public void delete(String path) {
- path = path.replace(getEndpointLink() + "/", "");
- try {
- client.deleteObject(new DeleteObjectRequest(properties.getBucketName(), path));
- } catch (Exception e) {
- throw new OssException("上传文件失败,请检腾讯云查配置信息:[" + e.getMessage() + "]");
- }
- }
-
- @Override
- public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
- return upload(data, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
- return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public String getEndpointLink() {
- String endpoint = properties.getEndpoint();
- StringBuilder sb = new StringBuilder(endpoint);
- if (StringUtils.containsAnyIgnoreCase(endpoint, "http://")) {
- sb.insert(7, properties.getBucketName() + ".");
- } else if (StringUtils.containsAnyIgnoreCase(endpoint, "https://")) {
- sb.insert(8, properties.getBucketName() + ".");
- } else {
- throw new OssException("Endpoint配置错误");
- }
- return sb.toString();
- }
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java b/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java
deleted file mode 100644
index 20f13eca1..000000000
--- a/ruoyi/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package com.ruoyi.oss.service.impl;
-
-import cn.hutool.core.util.ArrayUtil;
-import com.qiniu.http.Response;
-import com.qiniu.storage.BucketManager;
-import com.qiniu.storage.Configuration;
-import com.qiniu.storage.Region;
-import com.qiniu.storage.UploadManager;
-import com.qiniu.util.Auth;
-import com.ruoyi.oss.constant.OssConstant;
-import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.OssEnumd;
-import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.OssProperties;
-import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
-import org.springframework.stereotype.Component;
-
-import java.io.InputStream;
-
-/**
- * 七牛云存储策略
- *
- * @author Lion Li
- */
-@Component
-public class QiniuOssStrategy extends AbstractOssStrategy {
-
- private UploadManager uploadManager;
- private BucketManager bucketManager;
- private Auth auth;
-
-
- @Override
- public void init(OssProperties ossProperties) {
- super.init(ossProperties);
- try {
- Configuration config = new Configuration(getRegion(properties.getRegion()));
- // https设置
- config.useHttpsDomains = OssConstant.IS_HTTPS.equals(properties.getIsHttps());
- uploadManager = new UploadManager(config);
- auth = Auth.create(properties.getAccessKey(), properties.getSecretKey());
- bucketManager = new BucketManager(auth, config);
- createBucket();
- } catch (Exception e) {
- throw new OssException("七牛云存储配置错误! 请检查系统配置:[" + e.getMessage() + "]");
- }
- isInit = true;
- }
-
- @Override
- public void createBucket() {
- try {
- String bucketName = properties.getBucketName();
- if (ArrayUtil.contains(bucketManager.buckets(), bucketName)) {
- return;
- }
- bucketManager.createBucket(bucketName, properties.getRegion());
- } catch (Exception e) {
- throw new OssException("创建Bucket失败, 请核对七牛云配置信息:[" + e.getMessage() + "]");
- }
- }
-
- @Override
- public OssEnumd getServiceType() {
- return OssEnumd.QINIU;
- }
-
- @Override
- public UploadResult upload(byte[] data, String path, String contentType) {
- try {
- String token = auth.uploadToken(properties.getBucketName());
- Response res = uploadManager.put(data, path, token, null, contentType, false);
- if (!res.isOK()) {
- throw new RuntimeException("上传七牛出错:" + res.error);
- }
- } catch (Exception e) {
- throw new OssException("上传文件失败,请核对七牛配置信息:[" + e.getMessage() + "]");
- }
- return UploadResult.builder().url(getEndpointLink() + "/" + path).filename(path).build();
- }
-
- @Override
- public void delete(String path) {
- try {
- path = path.replace(getEndpointLink() + "/", "");
- Response res = bucketManager.delete(properties.getBucketName(), path);
- if (!res.isOK()) {
- throw new RuntimeException("删除七牛文件出错:" + res.error);
- }
- } catch (Exception e) {
- throw new OssException(e.getMessage());
- }
- }
-
- @Override
- public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
- return upload(data, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
- return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
- }
-
- @Override
- public String getEndpointLink() {
- return properties.getEndpoint();
- }
-
- private Region getRegion(String region) {
- switch (region) {
- case "z0":
- return Region.region0();
- case "z1":
- return Region.region1();
- case "z2":
- return Region.region2();
- case "na0":
- return Region.regionNa0();
- case "as0":
- return Region.regionAs0();
- default:
- return Region.autoRegion();
- }
- }
-
-}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java b/ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java
new file mode 100644
index 000000000..e9ce2b4de
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/config/SmsConfig.java
@@ -0,0 +1,46 @@
+package com.ruoyi.sms.config;
+
+import com.ruoyi.sms.config.properties.SmsProperties;
+import com.ruoyi.sms.core.AliyunSmsTemplate;
+import com.ruoyi.sms.core.SmsTemplate;
+import com.ruoyi.sms.core.TencentSmsTemplate;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 短信配置类
+ * 需要哪个 打开哪个的注释即可
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@Configuration
+public class SmsConfig {
+
+// @Configuration
+// @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
+// @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class)
+// static class AliyunSmsConfig {
+//
+// @Bean
+// public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) {
+// return new AliyunSmsTemplate(smsProperties);
+// }
+//
+// }
+
+ @Configuration
+ @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
+ @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class)
+ static class TencentSmsConfig {
+
+ @Bean
+ public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) {
+ return new TencentSmsTemplate(smsProperties);
+ }
+
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java b/ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java
new file mode 100644
index 000000000..39359cdfd
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java
@@ -0,0 +1,47 @@
+package com.ruoyi.sms.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * SMS短信 配置属性
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "sms")
+public class SmsProperties {
+
+ private Boolean enabled;
+
+ /**
+ * 配置节点
+ * 阿里云 dysmsapi.aliyuncs.com
+ * 腾讯云 sms.tencentcloudapi.com
+ */
+ private String endpoint;
+
+ /**
+ * key
+ */
+ private String accessKeyId;
+
+ /**
+ * 密匙
+ */
+ private String accessKeySecret;
+
+ /*
+ * 短信签名
+ */
+ private String signName;
+
+ /**
+ * 短信应用ID (腾讯专属)
+ */
+ private String sdkAppId;
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java b/ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java
new file mode 100644
index 000000000..eede376e5
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java
@@ -0,0 +1,66 @@
+package com.ruoyi.sms.core;
+
+import com.aliyun.dysmsapi20170525.Client;
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.teaopenapi.models.Config;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.sms.config.properties.SmsProperties;
+import com.ruoyi.sms.entity.SmsResult;
+import com.ruoyi.sms.exception.SmsException;
+import lombok.SneakyThrows;
+
+import java.util.Map;
+
+/**
+ * Aliyun 短信模板
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public class AliyunSmsTemplate implements SmsTemplate {
+
+ private SmsProperties properties;
+
+ private Client client;
+
+ @SneakyThrows(Exception.class)
+ public AliyunSmsTemplate(SmsProperties smsProperties) {
+ this.properties = smsProperties;
+ Config config = new Config()
+ // 您的AccessKey ID
+ .setAccessKeyId(smsProperties.getAccessKeyId())
+ // 您的AccessKey Secret
+ .setAccessKeySecret(smsProperties.getAccessKeySecret())
+ // 访问的域名
+ .setEndpoint(smsProperties.getEndpoint());
+ this.client = new Client(config);
+ }
+
+ @Override
+ public SmsResult send(String phones, String templateId, Map param) {
+ if (StringUtils.isBlank(phones)) {
+ throw new SmsException("手机号不能为空");
+ }
+ if (StringUtils.isBlank(templateId)) {
+ throw new SmsException("模板ID不能为空");
+ }
+ SendSmsRequest req = new SendSmsRequest()
+ .setPhoneNumbers(phones)
+ .setSignName(properties.getSignName())
+ .setTemplateCode(templateId)
+ .setTemplateParam(JsonUtils.toJsonString(param));
+ try {
+ SendSmsResponse resp = client.sendSms(req);
+ return SmsResult.builder()
+ .isSuccess("OK".equals(resp.getBody().getCode()))
+ .message(resp.getBody().getMessage())
+ .response(resp)
+ .build();
+ } catch (Exception e) {
+ throw new SmsException(e.getMessage());
+ }
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java b/ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java
new file mode 100644
index 000000000..0aec3ddbe
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/core/SmsTemplate.java
@@ -0,0 +1,26 @@
+package com.ruoyi.sms.core;
+
+import com.ruoyi.sms.entity.SmsResult;
+
+import java.util.Map;
+
+/**
+ * 短信模板
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public interface SmsTemplate {
+
+ /**
+ * 发送短信
+ *
+ * @param phones 电话号(多个逗号分割)
+ * @param templateId 模板id
+ * @param param 模板对应参数
+ * 阿里 需使用 模板变量名称对应内容 例如: code=1234
+ * 腾讯 需使用 模板变量顺序对应内容 例如: 1=1234, 1为模板内第一个参数
+ */
+ SmsResult send(String phones, String templateId, Map param);
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java b/ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java
new file mode 100644
index 000000000..1de8eae14
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java
@@ -0,0 +1,81 @@
+package com.ruoyi.sms.core;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.sms.config.properties.SmsProperties;
+import com.ruoyi.sms.entity.SmsResult;
+import com.ruoyi.sms.exception.SmsException;
+import com.tencentcloudapi.common.Credential;
+import com.tencentcloudapi.common.profile.ClientProfile;
+import com.tencentcloudapi.common.profile.HttpProfile;
+import com.tencentcloudapi.sms.v20190711.SmsClient;
+import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
+import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
+import com.tencentcloudapi.sms.v20190711.models.SendStatus;
+import lombok.SneakyThrows;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Tencent 短信模板
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public class TencentSmsTemplate implements SmsTemplate {
+
+ private SmsProperties properties;
+
+ private SmsClient client;
+
+ @SneakyThrows(Exception.class)
+ public TencentSmsTemplate(SmsProperties smsProperties) {
+ this.properties = smsProperties;
+ Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret());
+ HttpProfile httpProfile = new HttpProfile();
+ httpProfile.setEndpoint(smsProperties.getEndpoint());
+ ClientProfile clientProfile = new ClientProfile();
+ clientProfile.setHttpProfile(httpProfile);
+ this.client = new SmsClient(credential, "", clientProfile);
+ }
+
+ @Override
+ public SmsResult send(String phones, String templateId, Map param) {
+ if (StringUtils.isBlank(phones)) {
+ throw new SmsException("手机号不能为空");
+ }
+ if (StringUtils.isBlank(templateId)) {
+ throw new SmsException("模板ID不能为空");
+ }
+ SendSmsRequest req = new SendSmsRequest();
+ Set set = Arrays.stream(phones.split(",")).map(p -> "+86" + p).collect(Collectors.toSet());
+ req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class));
+ if (CollUtil.isNotEmpty(param)) {
+ req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class));
+ }
+ req.setTemplateID(templateId);
+ req.setSign(properties.getSignName());
+ req.setSmsSdkAppid(properties.getSdkAppId());
+ try {
+ SendSmsResponse resp = client.SendSms(req);
+ SmsResult.SmsResultBuilder builder = SmsResult.builder()
+ .isSuccess(true)
+ .message("send success")
+ .response(resp);
+ for (SendStatus sendStatus : resp.getSendStatusSet()) {
+ if (!"Ok".equals(sendStatus.getCode())) {
+ builder.isSuccess(false).message(sendStatus.getMessage());
+ break;
+ }
+ }
+ return builder.build();
+ } catch (Exception e) {
+ throw new SmsException(e.getMessage());
+ }
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java b/ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java
new file mode 100644
index 000000000..3f13b2774
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/entity/SmsResult.java
@@ -0,0 +1,29 @@
+package com.ruoyi.sms.entity;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 上传返回体
+ *
+ * @author Lion Li
+ */
+@Data
+@Builder
+public class SmsResult {
+
+ /**
+ * 是否成功
+ */
+ private boolean isSuccess;
+
+ /**
+ * 响应消息
+ */
+ private String message;
+
+ /**
+ * 实际响应体
+ */
+ private Object response;
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java b/ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java
new file mode 100644
index 000000000..28632a375
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/sms/exception/SmsException.java
@@ -0,0 +1,16 @@
+package com.ruoyi.sms.exception;
+
+/**
+ * Sms异常类
+ *
+ * @author Lion Li
+ */
+public class SmsException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SmsException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java b/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
index a8340df77..577f17fb8 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
/**
* 对象存储配置对象 sys_oss_config
@@ -53,6 +52,11 @@ public class SysOssConfig extends BaseEntity {
*/
private String endpoint;
+ /**
+ * 自定义域名
+ */
+ private String domain;
+
/**
* 是否https(0否 1是)
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java b/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
index 9a66e384b..5ac4e96e4 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
@@ -35,8 +35,8 @@ public class SysOssConfigBo extends BaseEntity {
/**
* 配置key
*/
- @ApiModelProperty(value = "configKey", required = true)
- @NotBlank(message = "configKey不能为空", groups = {AddGroup.class, EditGroup.class})
+ @ApiModelProperty(value = "配置key", required = true)
+ @NotBlank(message = "配置key不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "configKey长度必须介于2和20 之间")
private String configKey;
@@ -59,8 +59,8 @@ public class SysOssConfigBo extends BaseEntity {
/**
* 桶名称
*/
- @ApiModelProperty(value = "bucketName", required = true)
- @NotBlank(message = "bucketName不能为空", groups = {AddGroup.class, EditGroup.class})
+ @ApiModelProperty(value = "桶名称", required = true)
+ @NotBlank(message = "桶名称不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "bucketName长度必须介于2和100之间")
private String bucketName;
@@ -73,11 +73,17 @@ public class SysOssConfigBo extends BaseEntity {
/**
* 访问站点
*/
- @ApiModelProperty(value = "endpoint", required = true)
- @NotBlank(message = "endpoint不能为空", groups = {AddGroup.class, EditGroup.class})
+ @ApiModelProperty(value = "访问站点", required = true)
+ @NotBlank(message = "访问站点不能为空", groups = {AddGroup.class, EditGroup.class})
@Size(min = 2, max = 100, message = "endpoint长度必须介于2和100之间")
private String endpoint;
+ /**
+ * 自定义域名
+ */
+ @ApiModelProperty("自定义域名")
+ private String domain;
+
/**
* 是否https(Y=是,N=否)
*/
@@ -93,7 +99,7 @@ public class SysOssConfigBo extends BaseEntity {
/**
* 域
*/
- @ApiModelProperty(value = "region")
+ @ApiModelProperty(value = "域")
private String region;
/**
@@ -102,4 +108,10 @@ public class SysOssConfigBo extends BaseEntity {
@ApiModelProperty(value = "扩展字段")
private String ext1;
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
}
diff --git a/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java b/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
index 0fb08dd00..20edacaa6 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
@@ -62,6 +62,12 @@ public class SysOssConfigVo {
@ApiModelProperty("访问站点")
private String endpoint;
+ /**
+ * 自定义域名
+ */
+ @ApiModelProperty("自定义域名")
+ private String domain;
+
/**
* 是否https(Y=是,N=否)
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java b/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java
index b444e6d06..c55e5bc12 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/ISysOssService.java
@@ -8,6 +8,7 @@ import com.ruoyi.system.domain.vo.SysOssVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
+import java.util.List;
/**
* 文件上传 服务层
@@ -18,6 +19,8 @@ public interface ISysOssService {
TableDataInfo queryPageList(SysOssBo sysOss, PageQuery pageQuery);
+ List listByIds(Collection ossIds);
+
SysOss getById(Long ossId);
SysOss upload(MultipartFile file);
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java
index e0b53c1fb..1a672e59c 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/SysLoginService.java
@@ -27,8 +27,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
+import java.time.Duration;
import java.util.List;
-import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
@@ -79,7 +79,7 @@ public class SysLoginService {
SysUser user = loadUserByPhonenumber(phonenumber);
HttpServletRequest request = ServletUtils.getRequest();
- checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode));
+ checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode, request));
// 此处可根据登录用户的数据不同 自行创建 loginUser
LoginUser loginUser = buildLoginUser(user);
// 生成token
@@ -121,9 +121,13 @@ public class SysLoginService {
/**
* 校验短信验证码
*/
- private boolean validateSmsCode(String phonenumber, String smsCode) {
- // todo 此处使用手机号查询redis验证码与参数验证码是否一致 用户自行实现
- return true;
+ private boolean validateSmsCode(String phonenumber, String smsCode, HttpServletRequest request) {
+ String code = RedisUtils.getCacheObject(Constants.CAPTCHA_CODE_KEY + phonenumber);
+ if (StringUtils.isBlank(code)) {
+ asyncService.recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request);
+ throw new CaptchaExpireException();
+ }
+ return code.equals(smsCode);
}
/**
@@ -205,7 +209,7 @@ public class SysLoginService {
loginUser.setUserType(user.getUserType());
loginUser.setMenuPermission(permissionService.getMenuPermission(user));
loginUser.setRolePermission(permissionService.getRolePermission(user));
- loginUser.setDeptName(user.getDept().getDeptName());
+ loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
List roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
loginUser.setRoles(roles);
return loginUser;
@@ -248,7 +252,7 @@ public class SysLoginService {
errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
// 达到规定错误次数 则锁定登录
if (errorNumber.equals(setErrorNumber)) {
- RedisUtils.setCacheObject(errorKey, errorNumber, errorLimitTime, TimeUnit.MINUTES);
+ RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(errorLimitTime));
asyncService.recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), errorLimitTime), request);
throw new UserException(loginType.getRetryLimitExceed(), errorLimitTime);
} else {
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
index 2f9d0020a..6525d31e9 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
@@ -68,7 +68,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
.orderByAsc(SysMenu::getOrderNum));
} else {
QueryWrapper wrapper = Wrappers.query();
- wrapper.eq("ur.user_id", userId)
+ wrapper.eq("sur.user_id", userId)
.like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
index f78be1e83..015c156ab 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
@@ -95,9 +95,10 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService {
SysOssConfig config = BeanUtil.toBean(bo, SysOssConfig.class);
validEntityBeforeSave(config);
LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>();
- luw.set(StringUtils.isBlank(config.getPrefix()), SysOssConfig::getPrefix, "");
- luw.set(StringUtils.isBlank(config.getRegion()), SysOssConfig::getRegion, "");
- luw.set(StringUtils.isBlank(config.getExt1()), SysOssConfig::getExt1, "");
+ luw.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, "");
+ luw.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, "");
+ luw.set(ObjectUtil.isNull(config.getExt1()), SysOssConfig::getExt1, "");
+ luw.set(ObjectUtil.isNull(config.getRemark()), SysOssConfig::getRemark, "");
luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId());
return setConfigCache(baseMapper.update(config, luw) > 0, config);
}
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
index 19423f404..03a6cfca8 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.system.service.impl;
+import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -7,9 +8,11 @@ import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.redis.RedisUtils;
+import com.ruoyi.oss.constant.OssConstant;
+import com.ruoyi.oss.core.OssClient;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.factory.OssFactory;
-import com.ruoyi.oss.service.IOssStrategy;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
@@ -20,6 +23,8 @@ import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
+import java.time.Duration;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -42,6 +47,21 @@ public class SysOssServiceImpl implements ISysOssService {
return TableDataInfo.build(result);
}
+ @Override
+ public List listByIds(Collection ossIds) {
+ List list = new ArrayList<>();
+ for (Long id : ossIds) {
+ String key = OssConstant.SYS_OSS_KEY + id;
+ SysOssVo vo = RedisUtils.getCacheObject(key);
+ if (ObjectUtil.isNull(vo)) {
+ vo = baseMapper.selectVoById(id);
+ RedisUtils.setCacheObject(key, vo, Duration.ofDays(30));
+ }
+ list.add(vo);
+ }
+ return list;
+ }
+
private LambdaQueryWrapper buildQueryWrapper(SysOssBo bo) {
Map params = bo.getParams();
LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
@@ -65,7 +85,7 @@ public class SysOssServiceImpl implements ISysOssService {
public SysOss upload(MultipartFile file) {
String originalfileName = file.getOriginalFilename();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
- IOssStrategy storage = OssFactory.instance();
+ OssClient storage = OssFactory.instance();
UploadResult uploadResult;
try {
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
@@ -78,7 +98,7 @@ public class SysOssServiceImpl implements ISysOssService {
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalfileName);
- oss.setService(storage.getServiceType().getValue());
+ oss.setService(storage.getConfigKey());
baseMapper.insert(oss);
return oss;
}
@@ -90,7 +110,7 @@ public class SysOssServiceImpl implements ISysOssService {
}
List list = baseMapper.selectBatchIds(ids);
for (SysOss sysOss : list) {
- IOssStrategy storage = OssFactory.instance(sysOss.getService());
+ OssClient storage = OssFactory.instance(sysOss.getService());
storage.delete(sysOss.getUrl());
}
return baseMapper.deleteBatchIds(ids) > 0;
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
index 08d4cc4f9..fe142ca3c 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
@@ -20,7 +20,7 @@ public class SysSensitiveServiceImpl implements SensitiveService {
*/
@Override
public boolean isSensitive() {
- return LoginHelper.isAdmin();
+ return !LoginHelper.isAdmin();
}
}
diff --git a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index 2ef63881c..ed24ab4e9 100644
--- a/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -115,11 +116,11 @@ public class SysUserServiceImpl implements ISysUserService {
*/
@Override
public TableDataInfo selectUnallocatedList(SysUser user, PageQuery pageQuery) {
- List userId = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
+ List userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
QueryWrapper wrapper = Wrappers.query();
wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
.and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id"))
- .notIn("u.user_id", userId)
+ .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds)
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
Page page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper);
@@ -402,20 +403,7 @@ public class SysUserServiceImpl implements ISysUserService {
* @param user 用户对象
*/
public void insertUserRole(SysUser user) {
- Long[] roles = user.getRoleIds();
- if (ObjectUtil.isNotNull(roles)) {
- // 新增用户与角色管理
- List list = new ArrayList();
- for (Long roleId : roles) {
- SysUserRole ur = new SysUserRole();
- ur.setUserId(user.getUserId());
- ur.setRoleId(roleId);
- list.add(ur);
- }
- if (list.size() > 0) {
- userRoleMapper.insertBatch(list);
- }
- }
+ this.insertUserRole(user.getUserId(), user.getRoleIds());
}
/**
@@ -425,18 +413,16 @@ public class SysUserServiceImpl implements ISysUserService {
*/
public void insertUserPost(SysUser user) {
Long[] posts = user.getPostIds();
- if (ObjectUtil.isNotNull(posts)) {
+ if (ArrayUtil.isNotEmpty(posts)) {
// 新增用户与岗位管理
- List list = new ArrayList();
+ List list = new ArrayList<>(posts.length);
for (Long postId : posts) {
SysUserPost up = new SysUserPost();
up.setUserId(user.getUserId());
up.setPostId(postId);
list.add(up);
}
- if (list.size() > 0) {
- userPostMapper.insertBatch(list);
- }
+ userPostMapper.insertBatch(list);
}
}
@@ -447,18 +433,16 @@ public class SysUserServiceImpl implements ISysUserService {
* @param roleIds 角色组
*/
public void insertUserRole(Long userId, Long[] roleIds) {
- if (ObjectUtil.isNotNull(roleIds)) {
+ if (ArrayUtil.isNotEmpty(roleIds)) {
// 新增用户与角色管理
- List list = new ArrayList();
+ List list = new ArrayList<>(roleIds.length);
for (Long roleId : roleIds) {
SysUserRole ur = new SysUserRole();
ur.setUserId(userId);
ur.setRoleId(roleId);
list.add(ur);
}
- if (list.size() > 0) {
- userRoleMapper.insertBatch(list);
- }
+ userRoleMapper.insertBatch(list);
}
}
diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
index a19be65ea..0889aabc7 100644
--- a/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
+++ b/ruoyi/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
@@ -4,6 +4,8 @@ import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.CaptchaType;
@@ -12,30 +14,68 @@ import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.config.properties.CaptchaProperties;
+import com.ruoyi.sms.config.properties.SmsProperties;
+import com.ruoyi.sms.core.SmsTemplate;
+import com.ruoyi.sms.entity.SmsResult;
import com.ruoyi.system.service.ISysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
+import javax.validation.constraints.NotBlank;
+import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
/**
* 验证码操作处理
*
* @author Lion Li
*/
+@Anonymous
+@Slf4j
+@Validated
@Api(value = "验证码操作处理", tags = {"验证码管理"})
@RequiredArgsConstructor
@RestController
public class CaptchaController {
private final CaptchaProperties captchaProperties;
+ private final SmsProperties smsProperties;
private final ISysConfigService configService;
+ /**
+ * 短信验证码
+ */
+ @ApiOperation("短信验证码")
+ @GetMapping("/captchaSms")
+ public R smsCaptcha(@ApiParam("用户手机号")
+ @NotBlank(message = "{user.phonenumber.not.blank}")
+ String phonenumber) {
+ if (smsProperties.getEnabled()) {
+ R.fail("当前系统没有开启短信功能!");
+ }
+ String key = Constants.CAPTCHA_CODE_KEY + phonenumber;
+ String code = RandomUtil.randomNumbers(4);
+ RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+ // 验证码模板id 自行处理 (查数据库或写死均可)
+ String templateId = "";
+ Map map = new HashMap<>(1);
+ map.put("code", code);
+ SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
+ SmsResult result = smsTemplate.send(phonenumber, templateId, map);
+ if (!result.isSuccess()) {
+ log.error("验证码短信发送异常 => {}", result);
+ return R.fail(result.getMessage());
+ }
+ return R.ok();
+ }
+
/**
* 生成验证码
*/
@@ -60,7 +100,7 @@ public class CaptchaController {
captcha.setGenerator(codeGenerator);
captcha.createCode();
String code = isMath ? getCodeResult(captcha.getCode()) : captcha.getCode();
- RedisUtils.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+ RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
ajax.put("uuid", uuid);
ajax.put("img", captcha.getImageBase64());
return R.ok(ajax);
diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index facf6ce99..cdb1d6cd6 100644
--- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -2,6 +2,7 @@ package com.ruoyi.web.controller.system;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
+import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysMenu;
@@ -51,6 +52,7 @@ public class SysLoginController {
* @param loginBody 登录信息
* @return 结果
*/
+ @Anonymous
@ApiOperation("登录方法")
@PostMapping("/login")
public R> login(@Validated @RequestBody LoginBody loginBody) {
@@ -68,6 +70,7 @@ public class SysLoginController {
* @param smsLoginBody 登录信息
* @return 结果
*/
+ @Anonymous
@ApiOperation("短信登录(示例)")
@PostMapping("/smsLogin")
public R> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) {
@@ -84,6 +87,7 @@ public class SysLoginController {
* @param xcxCode 小程序code
* @return 结果
*/
+ @Anonymous
@ApiOperation("小程序登录(示例)")
@PostMapping("/xcxLogin")
public R> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
@@ -94,12 +98,14 @@ public class SysLoginController {
return R.ok(ajax);
}
+ @Anonymous
@ApiOperation("登出方法")
@PostMapping("/logout")
public R logout() {
try {
+ String username = LoginHelper.getUsername();
StpUtil.logout();
- loginService.logout(LoginHelper.getUsername());
+ loginService.logout(username);
} catch (NotLoginException e) {
}
return R.ok("退出成功");
diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java
index a128a15ff..d4e52acc6 100644
--- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java
+++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysOssController.java
@@ -32,6 +32,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -58,6 +59,19 @@ public class SysOssController extends BaseController {
return iSysOssService.queryPageList(bo, pageQuery);
}
+ /**
+ * 查询OSS对象基于id串
+ */
+ @ApiOperation("查询OSS对象基于ID")
+ @SaCheckPermission("system:oss:list")
+ @GetMapping("/listByIds/{ossIds}")
+ public R> listByIds(@ApiParam("OSS对象ID串")
+ @NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] ossIds) {
+ List list = iSysOssService.listByIds(Arrays.asList(ossIds));
+ return R.ok(list);
+ }
+
/**
* 上传OSS对象存储
*/
diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
index 84d4c0b3d..22b506f36 100644
--- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
+++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
@@ -1,6 +1,7 @@
package com.ruoyi.web.controller.system;
import cn.dev33.satoken.secure.BCrypt;
+import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
@@ -9,6 +10,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.service.ISysOssService;
import com.ruoyi.system.service.ISysUserService;
@@ -22,6 +24,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -117,6 +120,10 @@ public class SysProfileController extends BaseController {
public R> avatar(@RequestPart("avatarfile") MultipartFile file) {
Map ajax = new HashMap<>();
if (!file.isEmpty()) {
+ String extension = FileUtil.extName(file.getOriginalFilename());
+ if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
+ return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
+ }
SysOss oss = iSysOssService.upload(file);
String avatar = oss.getUrl();
if (userService.updateUserAvatar(getUsername(), avatar)) {
diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java
index 6595f06df..b8cedd67a 100644
--- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java
+++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java
@@ -1,5 +1,6 @@
package com.ruoyi.web.controller.system;
+import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.RegisterBody;
@@ -27,6 +28,7 @@ public class SysRegisterController extends BaseController {
private final SysRegisterService registerService;
private final ISysConfigService configService;
+ @Anonymous
@ApiOperation("用户注册")
@PostMapping("/register")
public R register(@Validated @RequestBody RegisterBody user) {
diff --git a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
index 5d9a20615..9b7cb268b 100644
--- a/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
+++ b/ruoyi/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
@@ -148,7 +148,7 @@ public class SysRoleController extends BaseController {
@SaCheckPermission("system:role:remove")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
- public R remove(@ApiParam("岗位ID串") @PathVariable Long[] roleIds) {
+ public R remove(@ApiParam("角色ID串") @PathVariable Long[] roleIds) {
return toAjax(roleService.deleteRoleByIds(roleIds));
}
diff --git a/ruoyi/src/main/resources/application-dev.yml b/ruoyi/src/main/resources/application-dev.yml
index 45eb5be97..f9327f779 100644
--- a/ruoyi/src/main/resources/application-dev.yml
+++ b/ruoyi/src/main/resources/application-dev.yml
@@ -130,8 +130,8 @@ spring:
port: 6379
# 数据库索引
database: 0
- # 密码
- password:
+ # 密码(如没有密码请注释掉)
+ # password:
# 连接超时时间
timeout: 10s
# 是否开启ssl
@@ -156,3 +156,37 @@ redisson:
timeout: 3000
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
+
+--- # mail 邮件发送
+mail:
+ enabled: false
+ host: smtp.163.com
+ port: 465
+ # 是否需要用户名密码验证
+ auth: true
+ # 发送方,遵循RFC-822标准
+ from: xxx@163.com
+ # 用户名(注意:如果使用foxmail邮箱,此处user为qq号)
+ user: xxx@163.com
+ # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助)
+ pass: xxxxxxxxxx
+ # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
+ starttlsEnable: true
+ # 使用SSL安全连接
+ sslEnable: true
+ # SMTP超时时长,单位毫秒,缺省值不超时
+ timeout: 0
+ # Socket连接超时值,单位毫秒,缺省值不超时
+ connectionTimeout: 0
+
+--- # sms 短信
+sms:
+ enabled: false
+ # 阿里云 dysmsapi.aliyuncs.com
+ # 腾讯云 sms.tencentcloudapi.com
+ endpoint: "dysmsapi.aliyuncs.com"
+ accessKeyId: xxxxxxx
+ accessKeySecret: xxxxxx
+ signName: 测试
+ # 腾讯专用
+ sdkAppId:
diff --git a/ruoyi/src/main/resources/application-prod.yml b/ruoyi/src/main/resources/application-prod.yml
index 6a28bccfb..def5f1666 100644
--- a/ruoyi/src/main/resources/application-prod.yml
+++ b/ruoyi/src/main/resources/application-prod.yml
@@ -133,8 +133,8 @@ spring:
port: 6379
# 数据库索引
database: 0
- # 密码
- password:
+ # 密码(如没有密码请注释掉)
+ # password:
# 连接超时时间
timeout: 10s
# 是否开启ssl
@@ -159,3 +159,37 @@ redisson:
timeout: 3000
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
+
+--- # mail 邮件发送
+mail:
+ enabled: false
+ host: smtp.163.com
+ port: 465
+ # 是否需要用户名密码验证
+ auth: true
+ # 发送方,遵循RFC-822标准
+ from: xxx@163.com
+ # 用户名(注意:如果使用foxmail邮箱,此处user为qq号)
+ user: xxx@163.com
+ # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助)
+ pass: xxxxxxxxxx
+ # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
+ starttlsEnable: true
+ # 使用SSL安全连接
+ sslEnable: true
+ # SMTP超时时长,单位毫秒,缺省值不超时
+ timeout: 0
+ # Socket连接超时值,单位毫秒,缺省值不超时
+ connectionTimeout: 0
+
+--- # sms 短信
+sms:
+ enabled: false
+ # 阿里云 dysmsapi.aliyuncs.com
+ # 腾讯云 sms.tencentcloudapi.com
+ endpoint: "dysmsapi.aliyuncs.com"
+ accessKeyId: xxxxxxx
+ accessKeySecret: xxxxxx
+ signName: 测试
+ # 腾讯专用
+ sdkAppId:
diff --git a/ruoyi/src/main/resources/application.yml b/ruoyi/src/main/resources/application.yml
index c692fc267..ceaaf9561 100644
--- a/ruoyi/src/main/resources/application.yml
+++ b/ruoyi/src/main/resources/application.yml
@@ -118,12 +118,6 @@ sa-token:
security:
# 排除路径
excludes:
- - /login
- - /smsLogin
- - /xcxLogin
- - /logout
- - /register
- - /captchaImage
# 静态资源
- /*.html
- /**/*.html
diff --git a/ruoyi/src/main/resources/excel/单列表.xlsx b/ruoyi/src/main/resources/excel/单列表.xlsx
new file mode 100644
index 000000000..0f7347d65
Binary files /dev/null and b/ruoyi/src/main/resources/excel/单列表.xlsx differ
diff --git a/ruoyi/src/main/resources/excel/多列表.xlsx b/ruoyi/src/main/resources/excel/多列表.xlsx
new file mode 100644
index 000000000..c7d11dcce
Binary files /dev/null and b/ruoyi/src/main/resources/excel/多列表.xlsx differ
diff --git a/ruoyi/src/main/resources/logback.xml b/ruoyi/src/main/resources/logback.xml
index 4d6b910d3..b78044b35 100644
--- a/ruoyi/src/main/resources/logback.xml
+++ b/ruoyi/src/main/resources/logback.xml
@@ -97,17 +97,9 @@
-
-
-
-
-
-
-
-
-
+
diff --git a/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml
index 08838c599..2f69197b3 100644
--- a/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml
+++ b/ruoyi/src/main/resources/mapper/system/SysMenuMapper.xml
@@ -32,8 +32,8 @@
m.perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
- left join sys_user_role ur on rm.role_id = ur.role_id
- left join sys_role ro on ur.role_id = ro.role_id
+ left join sys_user_role sur on rm.role_id = sur.role_id
+ left join sys_role ro on sur.role_id = ro.role_id
${ew.getCustomSqlSegment}
@@ -55,9 +55,9 @@
m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
- left join sys_user_role ur on rm.role_id = ur.role_id
- left join sys_role ro on ur.role_id = ro.role_id
- left join sys_user u on ur.user_id = u.user_id
+ left join sys_user_role sur on rm.role_id = sur.role_id
+ left join sys_role ro on sur.role_id = ro.role_id
+ left join sys_user u on sur.user_id = u.user_id
where u.user_id = #{userId}
and m.menu_type in ('M', 'C')
and m.status = '0'
@@ -81,18 +81,18 @@
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
- left join sys_user_role ur on rm.role_id = ur.role_id
+ left join sys_user_role sur on rm.role_id = sur.role_id
diff --git a/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml
index dc54c7e9f..90dff5051 100644
--- a/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml
+++ b/ruoyi/src/main/resources/mapper/system/SysRoleMapper.xml
@@ -34,8 +34,8 @@
r.create_time,
r.remark
from sys_role r
- left join sys_user_role ur on ur.role_id = r.role_id
- left join sys_user u on u.user_id = ur.user_id
+ left join sys_user_role sur on sur.role_id = r.role_id
+ left join sys_user u on u.user_id = sur.user_id
left join sys_dept d on u.dept_id = d.dept_id
@@ -51,14 +51,14 @@
- WHERE r.del_flag = '0' and ur.user_id = #{userId}
+ WHERE r.del_flag = '0' and sur.user_id = #{userId}
select r.role_id
from sys_role r
- left join sys_user_role ur on ur.role_id = r.role_id
- left join sys_user u on u.user_id = ur.user_id
+ left join sys_user_role sur on sur.role_id = r.role_id
+ left join sys_user u on u.user_id = sur.user_id
where u.user_id = #{userId}
diff --git a/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml
index 0b388d136..dacdcd8a6 100644
--- a/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi/src/main/resources/mapper/system/SysUserMapper.xml
@@ -80,12 +80,12 @@
r.status as role_status
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
- left join sys_user_role ur on u.user_id = ur.user_id
- left join sys_role r on r.role_id = ur.role_id
+ left join sys_user_role sur on u.user_id = sur.user_id
+ left join sys_role r on r.role_id = sur.role_id
- select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex,
+ select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from
sys_user u
left join sys_dept d on u.dept_id = d.dept_id
@@ -93,7 +93,7 @@
- select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex,
+ select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from
sys_user u
left join sys_dept d on u.dept_id = d.dept_id
@@ -104,8 +104,8 @@
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
- left join sys_user_role ur on u.user_id = ur.user_id
- left join sys_role r on r.role_id = ur.role_id
+ left join sys_user_role sur on u.user_id = sur.user_id
+ left join sys_role r on r.role_id = sur.role_id
${ew.getCustomSqlSegment}
@@ -113,8 +113,8 @@
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
- left join sys_user_role ur on u.user_id = ur.user_id
- left join sys_role r on r.role_id = ur.role_id
+ left join sys_user_role sur on u.user_id = sur.user_id
+ left join sys_role r on r.role_id = sur.role_id
${ew.getCustomSqlSegment}
diff --git a/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml
index 63a846d30..5a55fcb1e 100644
--- a/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml
+++ b/ruoyi/src/main/resources/mapper/system/SysUserRoleMapper.xml
@@ -10,8 +10,8 @@
select u.user_id from sys_user u
- inner join sys_user_role ur
- on u.user_id = ur.user_id and ur.role_id = #{roleId}
+ inner join sys_user_role sur
+ on u.user_id = sur.user_id and sur.role_id = #{roleId}
diff --git a/ruoyi/src/main/resources/vm/java/controller.java.vm b/ruoyi/src/main/resources/vm/java/controller.java.vm
index 20580d860..6b2fc6582 100644
--- a/ruoyi/src/main/resources/vm/java/controller.java.vm
+++ b/ruoyi/src/main/resources/vm/java/controller.java.vm
@@ -53,11 +53,11 @@ public class ${ClassName}Controller extends BaseController {
@SaCheckPermission("${permissionPrefix}:list")
@GetMapping("/list")
#if($table.crud || $table.sub)
- public TableDataInfo<${ClassName}Vo> list(@Validated(QueryGroup.class) ${ClassName}Bo bo, PageQuery pageQuery) {
+ public TableDataInfo<${ClassName}Vo> list(${ClassName}Bo bo, PageQuery pageQuery) {
return i${ClassName}Service.queryPageList(bo, pageQuery);
}
#elseif($table.tree)
- public R> list(@Validated(QueryGroup.class) ${ClassName}Bo bo) {
+ public R> list(${ClassName}Bo bo) {
List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo);
return R.ok(list);
}
@@ -70,7 +70,7 @@ public class ${ClassName}Controller extends BaseController {
@SaCheckPermission("${permissionPrefix}:export")
@Log(title = "${functionName}", businessType = BusinessType.EXPORT)
@PostMapping("/export")
- public void export(@Validated ${ClassName}Bo bo, HttpServletResponse response) {
+ public void export(${ClassName}Bo bo, HttpServletResponse response) {
List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo);
ExcelUtil.exportExcel(list, "${functionName}", ${ClassName}Vo.class, response);
}
@@ -82,8 +82,8 @@ public class ${ClassName}Controller extends BaseController {
@SaCheckPermission("${permissionPrefix}:query")
@GetMapping("/{${pkColumn.javaField}}")
public R<${ClassName}Vo> getInfo(@ApiParam("主键")
- @NotNull(message = "主键不能为空")
- @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) {
+ @NotNull(message = "主键不能为空")
+ @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) {
return R.ok(i${ClassName}Service.queryById(${pkColumn.javaField}));
}
diff --git a/ruoyi/src/main/resources/vm/java/domain.java.vm b/ruoyi/src/main/resources/vm/java/domain.java.vm
index 8fde4adea..28ca34c0f 100644
--- a/ruoyi/src/main/resources/vm/java/domain.java.vm
+++ b/ruoyi/src/main/resources/vm/java/domain.java.vm
@@ -2,7 +2,7 @@ package ${packageName}.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
@@ -28,6 +28,7 @@ import com.ruoyi.common.core.domain.TreeEntity;
#set($Entity="TreeEntity<${ClassName}>")
#end
@Data
+@EqualsAndHashCode(callSuper = true)
@TableName("${tableName}")
public class ${ClassName} extends ${Entity} {
diff --git a/ruoyi/src/main/resources/vm/java/service.java.vm b/ruoyi/src/main/resources/vm/java/service.java.vm
index 309328ca3..0f9137a5d 100644
--- a/ruoyi/src/main/resources/vm/java/service.java.vm
+++ b/ruoyi/src/main/resources/vm/java/service.java.vm
@@ -21,52 +21,33 @@ public interface I${ClassName}Service {
/**
* 查询${functionName}
- *
- * @param ${pkColumn.javaField} ${functionName}主键
- * @return ${functionName}
*/
${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField});
#if($table.crud || $table.sub)
/**
* 查询${functionName}列表
- *
- * @param ${className} ${functionName}
- * @return ${functionName}集合
*/
TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery);
#end
/**
* 查询${functionName}列表
- *
- * @param ${className} ${functionName}
- * @return ${functionName}集合
*/
List<${ClassName}Vo> queryList(${ClassName}Bo bo);
/**
* 修改${functionName}
- *
- * @param ${className} ${functionName}
- * @return 结果
*/
Boolean insertByBo(${ClassName}Bo bo);
/**
* 修改${functionName}
- *
- * @param ${className} ${functionName}
- * @return 结果
*/
Boolean updateByBo(${ClassName}Bo bo);
/**
* 校验并批量删除${functionName}信息
- *
- * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合
- * @param isValid 是否校验,true-删除前校验,false-不校验
- * @return 结果
*/
Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid);
}
diff --git a/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm
index 005c84a9f..776738219 100644
--- a/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm
+++ b/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm
@@ -35,9 +35,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
/**
* 查询${functionName}
- *
- * @param ${pkColumn.javaField} ${functionName}主键
- * @return ${functionName}
*/
@Override
public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){
@@ -47,9 +44,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
#if($table.crud || $table.sub)
/**
* 查询${functionName}列表
- *
- * @param bo ${functionName}
- * @return ${functionName}
*/
@Override
public TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery) {
@@ -61,9 +55,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
/**
* 查询${functionName}列表
- *
- * @param bo ${functionName}
- * @return ${functionName}
*/
@Override
public List<${ClassName}Vo> queryList(${ClassName}Bo bo) {
@@ -100,9 +91,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
/**
* 新增${functionName}
- *
- * @param bo ${functionName}
- * @return 结果
*/
@Override
public Boolean insertByBo(${ClassName}Bo bo) {
@@ -118,9 +106,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
/**
* 修改${functionName}
- *
- * @param bo ${functionName}
- * @return 结果
*/
@Override
public Boolean updateByBo(${ClassName}Bo bo) {
@@ -131,8 +116,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
/**
* 保存前的数据校验
- *
- * @param entity 实体类数据
*/
private void validEntityBeforeSave(${ClassName} entity){
//TODO 做一些数据校验,如唯一约束
@@ -140,9 +123,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
/**
* 批量删除${functionName}
- *
- * @param ${pkColumn.javaField}s 需要删除的${functionName}主键
- * @return 结果
*/
@Override
public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) {
diff --git a/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm
index 6776687d9..5db196710 100644
--- a/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm
+++ b/ruoyi/src/main/resources/vm/vue/v3/index-tree.vue.vm
@@ -173,11 +173,13 @@
#set($dictType=$column.dictType)
#if("" != $treeParentCode && $column.javaField == $treeParentCode)
-
#elseif($column.htmlType == "input")
@@ -353,8 +355,8 @@ function getList() {
}
/** 查询${functionName}下拉树结构 */
-async function getTreeselect() {
- await list${BusinessName}().then(response => {
+function getTreeselect() {
+ list${BusinessName}().then(response => {
${businessName}Options.value = [];
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] };
data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}");
@@ -403,9 +405,9 @@ function resetQuery() {
}
/** 新增按钮操作 */
-async function handleAdd(row) {
+function handleAdd(row) {
reset();
- await getTreeselect();
+ getTreeselect();
if (row != null && row.${treeCode}) {
form.value.${treeParentCode} = row.${treeCode};
} else {
diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml
index e80f75b0a..3dcdf32c6 100644
--- a/script/docker/docker-compose.yml
+++ b/script/docker/docker-compose.yml
@@ -2,7 +2,7 @@ version: '3'
services:
mysql:
- image: mysql:8.0.27
+ image: mysql:8.0.29
container_name: mysql
environment:
# 时区上海
@@ -32,7 +32,7 @@ services:
ipv4_address: 172.30.0.36
nginx-web:
- image: nginx:1.21.3
+ image: nginx:1.21.6
container_name: nginx-web
environment:
# 时区上海
@@ -55,7 +55,7 @@ services:
- ruoyi_net
redis:
- image: redis:6.2.6
+ image: redis:6.2.7
container_name: redis
ports:
- "6379:6379"
@@ -75,7 +75,7 @@ services:
ipv4_address: 172.30.0.48
minio:
- image: minio/minio:RELEASE.2021-10-27T16-29-42Z
+ image: minio/minio:RELEASE.2022-05-26T05-48-41Z
container_name: minio
ports:
# api 端口
@@ -110,7 +110,7 @@ services:
ipv4_address: 172.30.0.54
ruoyi-server1:
- image: ruoyi/ruoyi-server:4.1.0
+ image: ruoyi/ruoyi-server:4.2.0
container_name: ruoyi-server1
environment:
# 时区上海
@@ -125,7 +125,7 @@ services:
ipv4_address: 172.30.0.60
ruoyi-server2:
- image: "ruoyi/ruoyi-server:4.1.0"
+ image: "ruoyi/ruoyi-server:4.2.0"
container_name: ruoyi-server2
environment:
# 时区上海
@@ -140,7 +140,7 @@ services:
ipv4_address: 172.30.0.61
ruoyi-monitor-admin:
- image: ruoyi/ruoyi-monitor-admin:4.1.0
+ image: ruoyi/ruoyi-monitor-admin:4.2.0
container_name: ruoyi-monitor-admin
environment:
# 时区上海
@@ -155,7 +155,7 @@ services:
ipv4_address: 172.30.0.90
ruoyi-xxl-job-admin:
- image: ruoyi/ruoyi-xxl-job-admin:4.1.0
+ image: ruoyi/ruoyi-xxl-job-admin:4.2.0
container_name: ruoyi-xxl-job-admin
environment:
# 时区上海
diff --git a/script/docker/nginx/nginx.conf b/script/docker/nginx/nginx.conf
index 07df78391..daa2acf49 100644
--- a/script/docker/nginx/nginx.conf
+++ b/script/docker/nginx/nginx.conf
@@ -23,16 +23,16 @@ http {
upstream server {
ip_hash;
- server 172.30.0.60:8080;
- server 172.30.0.61:8080;
+ server 127.0.0.1:8080;
+ server 127.0.0.1:8080;
}
upstream monitor-admin {
- server 172.30.0.90:9090;
+ server 127.0.0.1:9090;
}
upstream xxljob-admin {
- server 172.30.0.92:9100;
+ server 127.0.0.1:9100;
}
server {
@@ -62,6 +62,11 @@ http {
# return 200 '{"msg":"演示模式,不允许操作","code":500}';
# }
+ # 限制外网访问内网 actuator 相关路径
+ location ~ ^(/[^/]*)?/actuator(/.*)?$ {
+ return 403;
+ }
+
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
diff --git a/script/sql/oracle/oracle_ry_vue_4.X.sql b/script/sql/oracle/oracle_ry_vue_4.X.sql
index 68b29e998..eabf91910 100644
--- a/script/sql/oracle/oracle_ry_vue_4.X.sql
+++ b/script/sql/oracle/oracle_ry_vue_4.X.sql
@@ -812,7 +812,7 @@ comment on column gen_table.remark is '备注';
-- ----------------------------
create table gen_table_column (
column_id number(20) not null,
- table_id varchar2(64),
+ table_id number(20),
column_name varchar2(200),
column_comment varchar2(500),
column_type varchar2(100),
@@ -904,6 +904,7 @@ create table sys_oss_config (
bucket_name varchar(255) default '',
prefix varchar(255) default '',
endpoint varchar(255) default '',
+ domain varchar(255) default '',
is_https char(1) default 'N',
region varchar(255) default '',
status char(1) default '1',
@@ -925,6 +926,7 @@ comment on column sys_oss_config.secret_key is '秘钥';
comment on column sys_oss_config.bucket_name is '桶名称';
comment on column sys_oss_config.prefix is '前缀';
comment on column sys_oss_config.endpoint is '访问站点';
+comment on column sys_oss_config.domain is '自定义域名';
comment on column sys_oss_config.is_https is '是否https(Y=是,N=否)';
comment on column sys_oss_config.region is '域';
comment on column sys_oss_config.status is '状态(0=正常,1=停用)';
@@ -935,10 +937,12 @@ comment on column sys_oss_config.create_time is '创建时间';
comment on column sys_oss_config.update_by is '更新者';
comment on column sys_oss_config.update_time is '更新时间';
-insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', NULL, 'admin', sysdate, 'admin', sysdate);
-insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
-insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
-insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
+insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '','N', '', '0', '', NULL, 'admin', sysdate, 'admin', sysdate);
+insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
+insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
+insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
+insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate);
+
-- ----------------------------
-- 钩子 ,用于session连接之后 自动设置默认的date类型格式化 简化时间查询
diff --git a/script/sql/postgres/postgres_ry_vue_4.X.sql b/script/sql/postgres/postgres_ry_vue_4.X.sql
index 850491fc6..316d3bbd5 100644
--- a/script/sql/postgres/postgres_ry_vue_4.X.sql
+++ b/script/sql/postgres/postgres_ry_vue_4.X.sql
@@ -205,8 +205,8 @@ create table if not exists sys_menu
path varchar(200) default ''::varchar,
component varchar(255) default null::varchar,
query_param varchar(255) default null::varchar,
- is_frame int4 default 1,
- is_cache int4 default 0,
+ is_frame char default '1'::bpchar,
+ is_cache char default '0'::bpchar,
menu_type char default ''::bpchar,
visible char default '0'::bpchar,
status char default '0'::bpchar,
@@ -245,109 +245,109 @@ comment on column sys_menu.remark is '备注';
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
-insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', now(), '', null, '系统管理目录');
-insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', now(), '', null, '系统监控目录');
-insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', now(), '', null, '系统工具目录');
-insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', now(), '', null, 'RuoYi-Vue-Plus官网地址');
+insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', '1', '0', 'M', '0', '0', '', 'system', 'admin', now(), '', null, '系统管理目录');
+insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '1', '0', 'M', '0', '0', '', 'monitor', 'admin', now(), '', null, '系统监控目录');
+insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '1', '0', 'M', '0', '0', '', 'tool', 'admin', now(), '', null, '系统工具目录');
+insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null, '', '0', '0', 'M', '0', '0', '', 'guide', 'admin', now(), '', null, 'RuoYi-Vue-Plus官网地址');
-- 二级菜单
-insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', now(), '', null, '用户管理菜单');
-insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', now(), '', null, '角色管理菜单');
-insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', now(), '', null, '菜单管理菜单');
-insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', now(), '', null, '部门管理菜单');
-insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', now(), '', null, '岗位管理菜单');
-insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', now(), '', null, '字典管理菜单');
-insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', now(), '', null, '参数设置菜单');
-insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', now(), '', null, '通知公告菜单');
-insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', now(), '', null, '日志管理菜单');
-insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', now(), '', null, '在线用户菜单');
-insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', now(), '', null, '数据监控菜单');
-insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', now(), '', null, '缓存监控菜单');
-insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', now(), '', null, '表单构建菜单');
-insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', now(), '', null, '代码生成菜单');
-insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', now(), '', null, '系统接口菜单');
+insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '1', '0', 'C', '0', '0', 'system:user:list', 'user', 'admin', now(), '', null, '用户管理菜单');
+insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '1', '0', 'C', '0', '0', 'system:role:list', 'peoples', 'admin', now(), '', null, '角色管理菜单');
+insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '1', '0', 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', now(), '', null, '菜单管理菜单');
+insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '1', '0', 'C', '0', '0', 'system:dept:list', 'tree', 'admin', now(), '', null, '部门管理菜单');
+insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '1', '0', 'C', '0', '0', 'system:post:list', 'post', 'admin', now(), '', null, '岗位管理菜单');
+insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '1', '0', 'C', '0', '0', 'system:dict:list', 'dict', 'admin', now(), '', null, '字典管理菜单');
+insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '1', '0', 'C', '0', '0', 'system:config:list', 'edit', 'admin', now(), '', null, '参数设置菜单');
+insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '1', '0', 'C', '0', '0', 'system:notice:list', 'message', 'admin', now(), '', null, '通知公告菜单');
+insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '1', '0', 'M', '0', '0', '', 'log', 'admin', now(), '', null, '日志管理菜单');
+insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '1', '0', 'C', '0', '0', 'monitor:online:list', 'online', 'admin', now(), '', null, '在线用户菜单');
+insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '1', '0', 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', now(), '', null, '数据监控菜单');
+insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '1', '0', 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', now(), '', null, '缓存监控菜单');
+insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', '1', '0', 'C', '0', '0', 'tool:build:list', 'build', 'admin', now(), '', null, '表单构建菜单');
+insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '1', '0', 'C', '0', '0', 'tool:gen:list', 'code', 'admin', now(), '', null, '代码生成菜单');
+insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '1', '0', 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', now(), '', null, '系统接口菜单');
-- springboot-admin监控
-insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', 1, 0, 'C', '0', '0', 'monitor:admin:list', 'dashboard', 'admin', now(), '', null, 'Admin监控菜单');
+insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', '1', '0', 'C', '0', '0', 'monitor:admin:list', 'dashboard', 'admin', now(), '', null, 'Admin监控菜单');
-- oss菜单
-insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', 1, 0, 'C', '0', '0', 'system:oss:list', 'upload', 'admin', now(), '', null, '文件管理菜单');
+insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', '1', '0', 'C', '0', '0', 'system:oss:list', 'upload', 'admin', now(), '', null, '文件管理菜单');
-- xxl-job-admin控制台
-insert into sys_menu values('120', '任务调度中心', '2', '5', 'XxlJob', 'monitor/xxljob/index', '', 1, 0, 'C', '0', '0', 'monitor:xxljob:list', 'job', 'admin', now(), '', null, 'Xxl-Job控制台菜单');
+insert into sys_menu values('120', '任务调度中心', '2', '5', 'XxlJob', 'monitor/xxljob/index', '', '1', '0', 'C', '0', '0', 'monitor:xxljob:list', 'job', 'admin', now(), '', null, 'Xxl-Job控制台菜单');
-- 三级菜单
-insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', now(), '', null, '操作日志菜单');
-insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', now(), '', null, '登录日志菜单');
+insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '1', '0', 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', now(), '', null, '操作日志菜单');
+insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '1', '0', 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', now(), '', null, '登录日志菜单');
-- 用户管理按钮
-insert into sys_menu values('1001', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1002', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1003', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1004', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1005', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1006', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1007', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1001', '用户查询', '100', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:user:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1002', '用户新增', '100', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:user:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1003', '用户修改', '100', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:user:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1004', '用户删除', '100', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:user:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1005', '用户导出', '100', '5', '', '', '', '1', '0', 'F', '0', '0', 'system:user:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1006', '用户导入', '100', '6', '', '', '', '1', '0', 'F', '0', '0', 'system:user:import', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1007', '重置密码', '100', '7', '', '', '', '1', '0', 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', now(), '', null, '');
-- 角色管理按钮
-insert into sys_menu values('1008', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1009', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1010', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1011', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1012', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1008', '角色查询', '101', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:role:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1009', '角色新增', '101', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:role:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1010', '角色修改', '101', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:role:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1011', '角色删除', '101', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:role:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1012', '角色导出', '101', '5', '', '', '', '1', '0', 'F', '0', '0', 'system:role:export', '#', 'admin', now(), '', null, '');
-- 菜单管理按钮
-insert into sys_menu values('1013', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1014', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1015', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1016', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1013', '菜单查询', '102', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1014', '菜单新增', '102', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1015', '菜单修改', '102', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1016', '菜单删除', '102', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:menu:remove', '#', 'admin', now(), '', null, '');
-- 部门管理按钮
-insert into sys_menu values('1017', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1018', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1019', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1020', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1017', '部门查询', '103', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1018', '部门新增', '103', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1019', '部门修改', '103', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1020', '部门删除', '103', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:dept:remove', '#', 'admin', now(), '', null, '');
-- 岗位管理按钮
-insert into sys_menu values('1021', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1022', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1023', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1024', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1025', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1021', '岗位查询', '104', '1', '', '', '', '1', '0', 'F', '0', '0', 'system:post:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1022', '岗位新增', '104', '2', '', '', '', '1', '0', 'F', '0', '0', 'system:post:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1023', '岗位修改', '104', '3', '', '', '', '1', '0', 'F', '0', '0', 'system:post:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1024', '岗位删除', '104', '4', '', '', '', '1', '0', 'F', '0', '0', 'system:post:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1025', '岗位导出', '104', '5', '', '', '', '1', '0', 'F', '0', '0', 'system:post:export', '#', 'admin', now(), '', null, '');
-- 字典管理按钮
-insert into sys_menu values('1026', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1027', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1028', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1029', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1030', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1026', '字典查询', '105', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1027', '字典新增', '105', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1028', '字典修改', '105', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1029', '字典删除', '105', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1030', '字典导出', '105', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:dict:export', '#', 'admin', now(), '', null, '');
-- 参数设置按钮
-insert into sys_menu values('1031', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1032', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1033', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1034', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1035', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1031', '参数查询', '106', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1032', '参数新增', '106', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1033', '参数修改', '106', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1034', '参数删除', '106', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1035', '参数导出', '106', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:config:export', '#', 'admin', now(), '', null, '');
-- 通知公告按钮
-insert into sys_menu values('1036', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1037', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1038', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1039', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1036', '公告查询', '107', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1037', '公告新增', '107', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1038', '公告修改', '107', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1039', '公告删除', '107', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:notice:remove', '#', 'admin', now(), '', null, '');
-- 操作日志按钮
-insert into sys_menu values('1040', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1041', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1040', '操作查询', '500', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1041', '操作删除', '500', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', now(), '', null, '');
-- 登录日志按钮
-insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', now(), '', null, '');
-- 在线用户按钮
-insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', now(), '', null, '');
-- 代码生成按钮
-insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:import', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:preview', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', '1', '0', 'F', '0', '0', 'tool:gen:code', '#', 'admin', now(), '', null, '');
-- oss相关按钮
-insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:query', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add', '#', 'admin', now(), '', null, '');
-insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:query', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:upload', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:download', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:remove', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:add', '#', 'admin', now(), '', null, '');
+insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:edit', '#', 'admin', now(), '', null, '');
-- ----------------------------
@@ -917,6 +917,7 @@ create table if not exists sys_oss_config
bucket_name varchar(255) default ''::varchar,
prefix varchar(255) default ''::varchar,
endpoint varchar(255) default ''::varchar,
+ domain varchar(255) default ''::varchar,
is_https char default 'N'::bpchar,
region varchar(255) default ''::varchar,
status char default '1'::bpchar,
@@ -937,6 +938,7 @@ comment on column sys_oss_config.secret_key is '秘钥';
comment on column sys_oss_config.bucket_name is '桶名称';
comment on column sys_oss_config.prefix is '前缀';
comment on column sys_oss_config.endpoint is '访问站点';
+comment on column sys_oss_config.domain is '自定义域名';
comment on column sys_oss_config.is_https is '是否https(Y=是,N=否)';
comment on column sys_oss_config.region is '域';
comment on column sys_oss_config.status is '状态(0=正常,1=停用)';
@@ -947,7 +949,9 @@ comment on column sys_oss_config.update_by is '更新者';
comment on column sys_oss_config.update_time is '更新时间';
comment on column sys_oss_config.remark is '备注';
-insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', now(), 'admin', now(), null);
-insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', now(), 'admin', now(), null);
-insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', now(), 'admin', now(), null);
-insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', now(), 'admin', now(), null);
+insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '','N', '', '0', '', 'admin', now(), 'admin', now(), null);
+insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', 'admin', now(), 'admin', now(), null);
+insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', 'admin', now(), 'admin', now(), null);
+insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', now(), 'admin', now(), null);
+insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', 'admin', now(), 'admin', now(), NULL);
+
diff --git a/script/sql/ry_vue_4.0.sql b/script/sql/ry_vue_4.0.sql
deleted file mode 100644
index 9b57bd010..000000000
--- a/script/sql/ry_vue_4.0.sql
+++ /dev/null
@@ -1,686 +0,0 @@
--- ----------------------------
--- 1、部门表
--- ----------------------------
-drop table if exists sys_dept;
-create table sys_dept (
- dept_id bigint(20) not null auto_increment comment '部门id',
- parent_id bigint(20) default 0 comment '父部门id',
- ancestors varchar(50) default '' comment '祖级列表',
- dept_name varchar(30) default '' comment '部门名称',
- order_num int(4) default 0 comment '显示顺序',
- leader varchar(20) default null comment '负责人',
- phone varchar(11) default null comment '联系电话',
- email varchar(50) default null comment '邮箱',
- status char(1) default '0' comment '部门状态(0正常 1停用)',
- del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- primary key (dept_id)
-) engine=innodb auto_increment=200 comment = '部门表';
-
--- ----------------------------
--- 初始化-部门表数据
--- ----------------------------
-insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-
-
--- ----------------------------
--- 2、用户信息表
--- ----------------------------
-drop table if exists sys_user;
-create table sys_user (
- user_id bigint(20) not null auto_increment comment '用户ID',
- dept_id bigint(20) default null comment '部门ID',
- user_name varchar(30) not null comment '用户账号',
- nick_name varchar(30) not null comment '用户昵称',
- user_type varchar(10) default 'sys_user' comment '用户类型(sys_user系统用户)',
- email varchar(50) default '' comment '用户邮箱',
- phonenumber varchar(11) default '' comment '手机号码',
- sex char(1) default '0' comment '用户性别(0男 1女 2未知)',
- avatar varchar(100) default '' comment '头像地址',
- password varchar(100) default '' comment '密码',
- status char(1) default '0' comment '帐号状态(0正常 1停用)',
- del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)',
- login_ip varchar(128) default '' comment '最后登录IP',
- login_date datetime comment '最后登录时间',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (user_id)
-) engine=innodb auto_increment=100 comment = '用户信息表';
-
--- ----------------------------
--- 初始化-用户信息表数据
--- ----------------------------
-insert into sys_user values(1, 103, 'admin', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员');
-insert into sys_user values(2, 105, 'lionli', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员');
-
-
--- ----------------------------
--- 3、岗位信息表
--- ----------------------------
-drop table if exists sys_post;
-create table sys_post
-(
- post_id bigint(20) not null auto_increment comment '岗位ID',
- post_code varchar(64) not null comment '岗位编码',
- post_name varchar(50) not null comment '岗位名称',
- post_sort int(4) not null comment '显示顺序',
- status char(1) not null comment '状态(0正常 1停用)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (post_id)
-) engine=innodb comment = '岗位信息表';
-
--- ----------------------------
--- 初始化-岗位信息表数据
--- ----------------------------
-insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, '');
-insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, '');
-insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, '');
-insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, '');
-
-
--- ----------------------------
--- 4、角色信息表
--- ----------------------------
-drop table if exists sys_role;
-create table sys_role (
- role_id bigint(20) not null auto_increment comment '角色ID',
- role_name varchar(30) not null comment '角色名称',
- role_key varchar(100) not null comment '角色权限字符串',
- role_sort int(4) not null comment '显示顺序',
- data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)',
- menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示',
- dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示',
- status char(1) not null comment '角色状态(0正常 1停用)',
- del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (role_id)
-) engine=innodb auto_increment=100 comment = '角色信息表';
-
--- ----------------------------
--- 初始化-角色信息表数据
--- ----------------------------
-insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员');
-insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色');
-
-
--- ----------------------------
--- 5、菜单权限表
--- ----------------------------
-drop table if exists sys_menu;
-create table sys_menu (
- menu_id bigint(20) not null auto_increment comment '菜单ID',
- menu_name varchar(50) not null comment '菜单名称',
- parent_id bigint(20) default 0 comment '父菜单ID',
- order_num int(4) default 0 comment '显示顺序',
- path varchar(200) default '' comment '路由地址',
- component varchar(255) default null comment '组件路径',
- query varchar(255) default null comment '路由参数',
- is_frame int(1) default 1 comment '是否为外链(0是 1否)',
- is_cache int(1) default 0 comment '是否缓存(0缓存 1不缓存)',
- menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)',
- visible char(1) default 0 comment '菜单状态(0显示 1隐藏)',
- status char(1) default 0 comment '菜单状态(0正常 1停用)',
- perms varchar(100) default null comment '权限标识',
- icon varchar(100) default '#' comment '菜单图标',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default '' comment '备注',
- primary key (menu_id)
-) engine=innodb auto_increment=2000 comment = '菜单权限表';
-
--- ----------------------------
--- 初始化-菜单信息表数据
--- ----------------------------
--- 一级菜单
-insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
-insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
-insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
-insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, 'RuoYi-Vue-Plus官网地址');
--- 二级菜单
-insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
-insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
-insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单');
-insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单');
-insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单');
-insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
-insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
-insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
-insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
-insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
-insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
-insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单');
-insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
-insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');
-insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单');
--- springboot-admin监控
-insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', 1, 0, 'C', '0', '0', 'monitor:admin:list', 'dashboard', 'admin', sysdate(), '', null, 'Admin监控菜单');
--- oss菜单
-insert into sys_menu values('118', '文件管理', '1', '10', 'oss', 'system/oss/index', '', 1, 0, 'C', '0', '0', 'system:oss:list', 'upload', 'admin', sysdate(), '', null, '文件管理菜单');
--- xxl-job-admin控制台
-insert into sys_menu values('120', '任务调度中心', '2', '5', 'XxlJob', 'monitor/xxljob/index', '', 1, 0, 'C', '0', '0', 'monitor:xxljob:list', 'job', 'admin', sysdate(), '', null, 'Xxl-Job控制台菜单');
-
--- 三级菜单
-insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单');
-insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单');
--- 用户管理按钮
-insert into sys_menu values('1001', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1002', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1003', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1004', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1005', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1006', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1007', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, '');
--- 角色管理按钮
-insert into sys_menu values('1008', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1009', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1010', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1011', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1012', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, '');
--- 菜单管理按钮
-insert into sys_menu values('1013', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1014', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1015', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1016', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, '');
--- 部门管理按钮
-insert into sys_menu values('1017', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1018', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1019', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1020', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, '');
--- 岗位管理按钮
-insert into sys_menu values('1021', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1022', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1023', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1024', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1025', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, '');
--- 字典管理按钮
-insert into sys_menu values('1026', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1027', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1028', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1029', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1030', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, '');
--- 参数设置按钮
-insert into sys_menu values('1031', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1032', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1033', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1034', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1035', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, '');
--- 通知公告按钮
-insert into sys_menu values('1036', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1037', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1038', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1039', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, '');
--- 操作日志按钮
-insert into sys_menu values('1040', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1041', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, '');
--- 登录日志按钮
-insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, '');
--- 在线用户按钮
-insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, '');
--- 代码生成按钮
-insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, '');
--- oss相关按钮
-insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:query', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1604', '配置添加', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add', '#', 'admin', sysdate(), '', null, '');
-insert into sys_menu values('1605', '配置编辑', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit', '#', 'admin', sysdate(), '', null, '');
-
-
--- ----------------------------
--- 6、用户和角色关联表 用户N-1角色
--- ----------------------------
-drop table if exists sys_user_role;
-create table sys_user_role (
- user_id bigint(20) not null comment '用户ID',
- role_id bigint(20) not null comment '角色ID',
- primary key(user_id, role_id)
-) engine=innodb comment = '用户和角色关联表';
-
--- ----------------------------
--- 初始化-用户和角色关联表数据
--- ----------------------------
-insert into sys_user_role values ('1', '1');
-insert into sys_user_role values ('2', '2');
-
-
--- ----------------------------
--- 7、角色和菜单关联表 角色1-N菜单
--- ----------------------------
-drop table if exists sys_role_menu;
-create table sys_role_menu (
- role_id bigint(20) not null comment '角色ID',
- menu_id bigint(20) not null comment '菜单ID',
- primary key(role_id, menu_id)
-) engine=innodb comment = '角色和菜单关联表';
-
--- ----------------------------
--- 初始化-角色和菜单关联表数据
--- ----------------------------
-insert into sys_role_menu values ('2', '1');
-insert into sys_role_menu values ('2', '2');
-insert into sys_role_menu values ('2', '3');
-insert into sys_role_menu values ('2', '4');
-insert into sys_role_menu values ('2', '100');
-insert into sys_role_menu values ('2', '101');
-insert into sys_role_menu values ('2', '102');
-insert into sys_role_menu values ('2', '103');
-insert into sys_role_menu values ('2', '104');
-insert into sys_role_menu values ('2', '105');
-insert into sys_role_menu values ('2', '106');
-insert into sys_role_menu values ('2', '107');
-insert into sys_role_menu values ('2', '108');
-insert into sys_role_menu values ('2', '109');
-insert into sys_role_menu values ('2', '110');
-insert into sys_role_menu values ('2', '111');
-insert into sys_role_menu values ('2', '112');
-insert into sys_role_menu values ('2', '113');
-insert into sys_role_menu values ('2', '114');
-insert into sys_role_menu values ('2', '115');
-insert into sys_role_menu values ('2', '116');
-insert into sys_role_menu values ('2', '500');
-insert into sys_role_menu values ('2', '501');
-insert into sys_role_menu values ('2', '1000');
-insert into sys_role_menu values ('2', '1001');
-insert into sys_role_menu values ('2', '1002');
-insert into sys_role_menu values ('2', '1003');
-insert into sys_role_menu values ('2', '1004');
-insert into sys_role_menu values ('2', '1005');
-insert into sys_role_menu values ('2', '1006');
-insert into sys_role_menu values ('2', '1007');
-insert into sys_role_menu values ('2', '1008');
-insert into sys_role_menu values ('2', '1009');
-insert into sys_role_menu values ('2', '1010');
-insert into sys_role_menu values ('2', '1011');
-insert into sys_role_menu values ('2', '1012');
-insert into sys_role_menu values ('2', '1013');
-insert into sys_role_menu values ('2', '1014');
-insert into sys_role_menu values ('2', '1015');
-insert into sys_role_menu values ('2', '1016');
-insert into sys_role_menu values ('2', '1017');
-insert into sys_role_menu values ('2', '1018');
-insert into sys_role_menu values ('2', '1019');
-insert into sys_role_menu values ('2', '1020');
-insert into sys_role_menu values ('2', '1021');
-insert into sys_role_menu values ('2', '1022');
-insert into sys_role_menu values ('2', '1023');
-insert into sys_role_menu values ('2', '1024');
-insert into sys_role_menu values ('2', '1025');
-insert into sys_role_menu values ('2', '1026');
-insert into sys_role_menu values ('2', '1027');
-insert into sys_role_menu values ('2', '1028');
-insert into sys_role_menu values ('2', '1029');
-insert into sys_role_menu values ('2', '1030');
-insert into sys_role_menu values ('2', '1031');
-insert into sys_role_menu values ('2', '1032');
-insert into sys_role_menu values ('2', '1033');
-insert into sys_role_menu values ('2', '1034');
-insert into sys_role_menu values ('2', '1035');
-insert into sys_role_menu values ('2', '1036');
-insert into sys_role_menu values ('2', '1037');
-insert into sys_role_menu values ('2', '1038');
-insert into sys_role_menu values ('2', '1039');
-insert into sys_role_menu values ('2', '1040');
-insert into sys_role_menu values ('2', '1041');
-insert into sys_role_menu values ('2', '1042');
-insert into sys_role_menu values ('2', '1043');
-insert into sys_role_menu values ('2', '1044');
-insert into sys_role_menu values ('2', '1045');
-insert into sys_role_menu values ('2', '1046');
-insert into sys_role_menu values ('2', '1047');
-insert into sys_role_menu values ('2', '1048');
-insert into sys_role_menu values ('2', '1055');
-insert into sys_role_menu values ('2', '1056');
-insert into sys_role_menu values ('2', '1057');
-insert into sys_role_menu values ('2', '1058');
-insert into sys_role_menu values ('2', '1059');
-insert into sys_role_menu values ('2', '1060');
-
--- ----------------------------
--- 8、角色和部门关联表 角色1-N部门
--- ----------------------------
-drop table if exists sys_role_dept;
-create table sys_role_dept (
- role_id bigint(20) not null comment '角色ID',
- dept_id bigint(20) not null comment '部门ID',
- primary key(role_id, dept_id)
-) engine=innodb comment = '角色和部门关联表';
-
--- ----------------------------
--- 初始化-角色和部门关联表数据
--- ----------------------------
-insert into sys_role_dept values ('2', '100');
-insert into sys_role_dept values ('2', '101');
-insert into sys_role_dept values ('2', '105');
-
-
--- ----------------------------
--- 9、用户与岗位关联表 用户1-N岗位
--- ----------------------------
-drop table if exists sys_user_post;
-create table sys_user_post
-(
- user_id bigint(20) not null comment '用户ID',
- post_id bigint(20) not null comment '岗位ID',
- primary key (user_id, post_id)
-) engine=innodb comment = '用户与岗位关联表';
-
--- ----------------------------
--- 初始化-用户与岗位关联表数据
--- ----------------------------
-insert into sys_user_post values ('1', '1');
-insert into sys_user_post values ('2', '2');
-
-
--- ----------------------------
--- 10、操作日志记录
--- ----------------------------
-drop table if exists sys_oper_log;
-create table sys_oper_log (
- oper_id bigint(20) not null auto_increment comment '日志主键',
- title varchar(50) default '' comment '模块标题',
- business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)',
- method varchar(100) default '' comment '方法名称',
- request_method varchar(10) default '' comment '请求方式',
- operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)',
- oper_name varchar(50) default '' comment '操作人员',
- dept_name varchar(50) default '' comment '部门名称',
- oper_url varchar(255) default '' comment '请求URL',
- oper_ip varchar(128) default '' comment '主机地址',
- oper_location varchar(255) default '' comment '操作地点',
- oper_param varchar(2000) default '' comment '请求参数',
- json_result varchar(2000) default '' comment '返回参数',
- status int(1) default 0 comment '操作状态(0正常 1异常)',
- error_msg varchar(2000) default '' comment '错误消息',
- oper_time datetime comment '操作时间',
- primary key (oper_id)
-) engine=innodb auto_increment=100 comment = '操作日志记录';
-
-
--- ----------------------------
--- 11、字典类型表
--- ----------------------------
-drop table if exists sys_dict_type;
-create table sys_dict_type
-(
- dict_id bigint(20) not null auto_increment comment '字典主键',
- dict_name varchar(100) default '' comment '字典名称',
- dict_type varchar(100) default '' comment '字典类型',
- status char(1) default '0' comment '状态(0正常 1停用)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (dict_id),
- unique (dict_type)
-) engine=innodb auto_increment=100 comment = '字典类型表';
-
-insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表');
-insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表');
-insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表');
-insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表');
-insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表');
-insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表');
-insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表');
-insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表');
-
-
--- ----------------------------
--- 12、字典数据表
--- ----------------------------
-drop table if exists sys_dict_data;
-create table sys_dict_data
-(
- dict_code bigint(20) not null auto_increment comment '字典编码',
- dict_sort int(4) default 0 comment '字典排序',
- dict_label varchar(100) default '' comment '字典标签',
- dict_value varchar(100) default '' comment '字典键值',
- dict_type varchar(100) default '' comment '字典类型',
- css_class varchar(100) default null comment '样式属性(其他样式扩展)',
- list_class varchar(100) default null comment '表格回显样式',
- is_default char(1) default 'N' comment '是否默认(Y是 N否)',
- status char(1) default '0' comment '状态(0正常 1停用)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (dict_code)
-) engine=innodb auto_increment=100 comment = '字典数据表';
-
-insert into sys_dict_data values(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男');
-insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女');
-insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知');
-insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单');
-insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单');
-insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态');
-insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态');
-insert into sys_dict_data values(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是');
-insert into sys_dict_data values(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否');
-insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知');
-insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告');
-insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态');
-insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态');
-insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作');
-insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作');
-insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作');
-insert into sys_dict_data values(21, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作');
-insert into sys_dict_data values(22, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作');
-insert into sys_dict_data values(23, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作');
-insert into sys_dict_data values(24, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作');
-insert into sys_dict_data values(25, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作');
-insert into sys_dict_data values(26, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作');
-insert into sys_dict_data values(27, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态');
-insert into sys_dict_data values(28, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态');
-
-
--- ----------------------------
--- 13、参数配置表
--- ----------------------------
-drop table if exists sys_config;
-create table sys_config (
- config_id int(5) not null auto_increment comment '参数主键',
- config_name varchar(100) default '' comment '参数名称',
- config_key varchar(100) default '' comment '参数键名',
- config_value varchar(500) default '' comment '参数键值',
- config_type char(1) default 'N' comment '系统内置(Y是 N否)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (config_id)
-) engine=innodb auto_increment=100 comment = '参数配置表';
-
-insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
-insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' );
-insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' );
-insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaOnOff', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能(true开启,false关闭)');
-insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)');
-insert into sys_config values(11, 'OSS预览列表资源开关', 'sys.oss.previewListResource', 'true', 'Y', 'admin', sysdate(), '', null, 'true:开启, false:关闭');
-
-
--- ----------------------------
--- 14、系统访问记录
--- ----------------------------
-drop table if exists sys_logininfor;
-create table sys_logininfor (
- info_id bigint(20) not null auto_increment comment '访问ID',
- user_name varchar(50) default '' comment '用户账号',
- ipaddr varchar(128) default '' comment '登录IP地址',
- login_location varchar(255) default '' comment '登录地点',
- browser varchar(50) default '' comment '浏览器类型',
- os varchar(50) default '' comment '操作系统',
- status char(1) default '0' comment '登录状态(0成功 1失败)',
- msg varchar(255) default '' comment '提示消息',
- login_time datetime comment '访问时间',
- primary key (info_id)
-) engine=innodb auto_increment=100 comment = '系统访问记录';
-
-
--- ----------------------------
--- 17、通知公告表
--- ----------------------------
-drop table if exists sys_notice;
-create table sys_notice (
- notice_id int(4) not null auto_increment comment '公告ID',
- notice_title varchar(50) not null comment '公告标题',
- notice_type char(1) not null comment '公告类型(1通知 2公告)',
- notice_content longblob default null comment '公告内容',
- status char(1) default '0' comment '公告状态(0正常 1关闭)',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(255) default null comment '备注',
- primary key (notice_id)
-) engine=innodb auto_increment=10 comment = '通知公告表';
-
--- ----------------------------
--- 初始化-公告信息表数据
--- ----------------------------
-insert into sys_notice values('1', '温馨提醒:2018-07-01 新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员');
-insert into sys_notice values('2', '维护通知:2018-07-01 系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员');
-
-
--- ----------------------------
--- 18、代码生成业务表
--- ----------------------------
-drop table if exists gen_table;
-create table gen_table (
- table_id bigint(20) not null auto_increment comment '编号',
- table_name varchar(200) default '' comment '表名称',
- table_comment varchar(500) default '' comment '表描述',
- sub_table_name varchar(64) default null comment '关联子表的表名',
- sub_table_fk_name varchar(64) default null comment '子表关联的外键名',
- class_name varchar(100) default '' comment '实体类名称',
- tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)',
- package_name varchar(100) comment '生成包路径',
- module_name varchar(30) comment '生成模块名',
- business_name varchar(30) comment '生成业务名',
- function_name varchar(50) comment '生成功能名',
- function_author varchar(50) comment '生成功能作者',
- gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)',
- gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)',
- options varchar(1000) comment '其它生成选项',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (table_id)
-) engine=innodb auto_increment=1 comment = '代码生成业务表';
-
-
--- ----------------------------
--- 19、代码生成业务表字段
--- ----------------------------
-drop table if exists gen_table_column;
-create table gen_table_column (
- column_id bigint(20) not null auto_increment comment '编号',
- table_id varchar(64) comment '归属表编号',
- column_name varchar(200) comment '列名称',
- column_comment varchar(500) comment '列描述',
- column_type varchar(100) comment '列类型',
- java_type varchar(500) comment 'JAVA类型',
- java_field varchar(200) comment 'JAVA字段名',
- is_pk char(1) comment '是否主键(1是)',
- is_increment char(1) comment '是否自增(1是)',
- is_required char(1) comment '是否必填(1是)',
- is_insert char(1) comment '是否为插入字段(1是)',
- is_edit char(1) comment '是否编辑字段(1是)',
- is_list char(1) comment '是否列表字段(1是)',
- is_query char(1) comment '是否查询字段(1是)',
- query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)',
- html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)',
- dict_type varchar(200) default '' comment '字典类型',
- sort int comment '排序',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime comment '更新时间',
- primary key (column_id)
-) engine=innodb auto_increment=1 comment = '代码生成业务表字段';
-
--- ----------------------------
--- OSS对象存储表
--- ----------------------------
-drop table if exists sys_oss;
-create table sys_oss (
- oss_id bigint(20) not null auto_increment comment '对象存储主键',
- file_name varchar(255) not null default '' comment '文件名',
- original_name varchar(255) not null default '' comment '原名',
- file_suffix varchar(10) not null default '' comment '文件后缀名',
- url varchar(500) not null comment 'URL地址',
- create_time datetime default null comment '创建时间',
- create_by varchar(64) default '' comment '上传人',
- update_time datetime default null comment '更新时间',
- update_by varchar(64) default '' comment '更新人',
- service varchar(10) not null default 'minio' comment '服务商',
- primary key (oss_id)
-) engine=innodb comment ='OSS对象存储表';
-
--- ----------------------------
--- OSS对象存储动态配置表
--- ----------------------------
-drop table if exists sys_oss_config;
-create table sys_oss_config (
- oss_config_id bigint(20) not null auto_increment comment '主建',
- config_key varchar(255) not null default '' comment '配置key',
- access_key varchar(255) default '' comment 'accessKey',
- secret_key varchar(255) default '' comment '秘钥',
- bucket_name varchar(255) default '' comment '桶名称',
- prefix varchar(255) default '' comment '前缀',
- endpoint varchar(255) default '' comment '访问站点',
- is_https char(1) default 'N' comment '是否https(Y=是,N=否)',
- region varchar(255) default '' comment '域',
- status char(1) default '1' comment '状态(0=正常,1=停用)',
- ext1 varchar(255) default '' comment '扩展字段',
- create_by varchar(64) default '' comment '创建者',
- create_time datetime default null comment '创建时间',
- update_by varchar(64) default '' comment '更新者',
- update_time datetime default null comment '更新时间',
- remark varchar(500) default null comment '备注',
- primary key (oss_config_id)
-) engine=innodb comment='对象存储配置表';
-
-insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
diff --git a/script/sql/ry_vue_4.X.sql b/script/sql/ry_vue_4.X.sql
index e190186ba..560f3fc53 100644
--- a/script/sql/ry_vue_4.X.sql
+++ b/script/sql/ry_vue_4.X.sql
@@ -515,7 +515,7 @@ insert into sys_dict_data values(28, 2, '失败', '1', 'sys_common_st
-- ----------------------------
drop table if exists sys_config;
create table sys_config (
- config_id int(5) not null comment '参数主键',
+ config_id bigint(20) not null comment '参数主键',
config_name varchar(100) default '' comment '参数名称',
config_key varchar(100) default '' comment '参数键名',
config_value varchar(500) default '' comment '参数键值',
@@ -559,7 +559,7 @@ create table sys_logininfor (
-- ----------------------------
drop table if exists sys_notice;
create table sys_notice (
- notice_id int(4) not null comment '公告ID',
+ notice_id bigint(20) not null comment '公告ID',
notice_title varchar(50) not null comment '公告标题',
notice_type char(1) not null comment '公告类型(1通知 2公告)',
notice_content longblob default null comment '公告内容',
@@ -614,7 +614,7 @@ create table gen_table (
drop table if exists gen_table_column;
create table gen_table_column (
column_id bigint(20) not null comment '编号',
- table_id varchar(64) comment '归属表编号',
+ table_id bigint(20) comment '归属表编号',
column_name varchar(200) comment '列名称',
column_comment varchar(500) comment '列描述',
column_type varchar(100) comment '列类型',
@@ -668,6 +668,7 @@ create table sys_oss_config (
bucket_name varchar(255) default '' comment '桶名称',
prefix varchar(255) default '' comment '前缀',
endpoint varchar(255) default '' comment '访问站点',
+ domain varchar(255) default '' comment '自定义域名',
is_https char(1) default 'N' comment '是否https(Y=是,N=否)',
region varchar(255) default '' comment '域',
status char(1) default '1' comment '状态(0=正常,1=停用)',
@@ -680,7 +681,9 @@ create table sys_oss_config (
primary key (oss_config_id)
) engine=innodb comment='对象存储配置表';
-insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', 'http://localhost:9000', 'N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://XXX.XXXX.com', 'N', 'z0', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'http://oss-cn-beijing.aliyuncs.com', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
-insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'http://cos.ap-beijing.myqcloud.com', 'N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
+insert into sys_oss_config values (1, 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '','N', '', '0', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
+insert into sys_oss_config values (2, 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
+insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
+insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
+insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL);
+
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql
index d37f1b40e..97b8be1cd 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql
@@ -157,7 +157,7 @@ GO
CREATE TABLE [gen_table_column]
(
[column_id] bigint NOT NULL,
- [table_id] nvarchar(64) NULL,
+ [table_id] bigint NULL,
[column_name] nvarchar(200) NULL,
[column_comment] nvarchar(500) NULL,
[column_type] nvarchar(100) NULL,
@@ -2193,6 +2193,7 @@ CREATE TABLE [sys_oss_config]
[bucket_name] nvarchar(255) DEFAULT '' NULL,
[prefix] nvarchar(255) DEFAULT '' NULL,
[endpoint] nvarchar(255) DEFAULT '' NULL,
+ [domain] nvarchar(255) DEFAULT '' NULL,
[is_https] nchar(1) DEFAULT ('N') NULL,
[region] nvarchar(255) DEFAULT '' NULL,
[status] nchar(1) DEFAULT ('1') NULL,
@@ -2251,6 +2252,12 @@ EXEC sp_addextendedproperty
'TABLE', N'sys_oss_config',
'COLUMN', N'endpoint'
GO
+EXEC sp_addextendedproperty
+ 'MS_Description', N'自定义域名',
+ 'SCHEMA', N'dbo',
+ 'TABLE', N'sys_oss_config',
+ 'COLUMN', N'domain'
+GO
EXEC sp_addextendedproperty
'MS_Description', N'是否https(Y=是,N=否)',
'SCHEMA', N'dbo',
@@ -2311,11 +2318,13 @@ EXEC sp_addextendedproperty
'TABLE', N'sys_oss_config'
GO
-INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'1', N'minio', N'lihongbo', N'lihongbo.123', N'ruoyi', N'', N'http://81.70.150.73:9000', N'N', N'', N'0', N'', N'admin', getdate(), N'admin', getdate(), NULL)
+INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'1', N'minio', N'ruoyi', N'ruoyi123', N'ruoyi', N'', N'127.0.0.1:9000', N'',N'N', N'', N'0', N'', N'admin', getdate(), N'admin', getdate(), NULL)
GO
-INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'2', N'qiniu', N'XXXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N'http://XXX.XXXX.com', N'N', N'z0', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
+INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'2', N'qiniu', N'XXXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N's3-cn-north-1.qiniucs.com', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
GO
-INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'3', N'aliyun', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N'http://oss-cn-beijing.aliyuncs.com', N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
+INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'3', N'aliyun', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi', N'', N'oss-cn-beijing.aliyuncs.com', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
GO
-INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'4', N'qcloud', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi-1250000000', N'', N'http://cos.ap-beijing.myqcloud.com', N'N', N'ap-beijing', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
+INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'4', N'qcloud', N'XXXXXXXXXXXXXXX', N'XXXXXXXXXXXXXXX', N'ruoyi-1250000000', N'', N'cos.ap-beijing.myqcloud.com', N'',N'N', N'ap-beijing', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
+GO
+INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'5', N'image', N'ruoyi', N'ruoyi123', N'ruoyi', N'image', N'127.0.0.1:9000', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
GO
diff --git a/script/sql/update/oracle/update-4.1-4.2.sql b/script/sql/update/oracle/update-4.1-4.2.sql
new file mode 100644
index 000000000..a4cbf248c
--- /dev/null
+++ b/script/sql/update/oracle/update-4.1-4.2.sql
@@ -0,0 +1,12 @@
+ALTER TABLE "SYS_OSS_CONFIG" ADD ("DOMAIN" VARCHAR2(255));
+
+COMMENT ON COLUMN "SYS_OSS_CONFIG"."DOMAIN" IS '自定义域名';
+
+update sys_oss_config set endpoint = '127.0.0.1:9000' where oss_config_id = 1;
+update sys_oss_config set endpoint = 's3-cn-north-1.qiniucs.com', region = '' where oss_config_id = 2;
+update sys_oss_config set endpoint = 'oss-cn-beijing.aliyuncs.com' where oss_config_id = 3;
+update sys_oss_config set endpoint = 'cos.ap-beijing.myqcloud.com' where oss_config_id = 4;
+
+insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', 'N', '', '1', '', NULL, 'admin', sysdate, 'admin', sysdate, '');
+
+ALTER TABLE "GEN_TABLE_COLUMN" MODIFY ("TABLE_ID" NUMBER(20,0));
diff --git a/script/sql/update/postgres/update-4.1-4.2.sql b/script/sql/update/postgres/update-4.1-4.2.sql
new file mode 100644
index 000000000..5ea2cf531
--- /dev/null
+++ b/script/sql/update/postgres/update-4.1-4.2.sql
@@ -0,0 +1,11 @@
+ALTER TABLE "sys_oss_config" ADD COLUMN "domain" varchar(255);
+
+COMMENT ON COLUMN "sys_oss_config"."domain" IS '自定义域名';
+
+update sys_oss_config set endpoint = '127.0.0.1:9000' where oss_config_id = 1;
+update sys_oss_config set endpoint = 's3-cn-north-1.qiniucs.com', region = '' where oss_config_id = 2;
+update sys_oss_config set endpoint = 'oss-cn-beijing.aliyuncs.com' where oss_config_id = 3;
+update sys_oss_config set endpoint = 'cos.ap-beijing.myqcloud.com' where oss_config_id = 4;
+
+insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', 'N', '', '1', '', 'admin', now(), 'admin', now(), NULL, '');
+
diff --git a/script/sql/update/sqlserver/update-4.1-4.2.sql b/script/sql/update/sqlserver/update-4.1-4.2.sql
new file mode 100644
index 000000000..9e217ec7b
--- /dev/null
+++ b/script/sql/update/sqlserver/update-4.1-4.2.sql
@@ -0,0 +1,27 @@
+ALTER TABLE [sys_oss_config] ADD [domain] nvarchar(255) DEFAULT '' NULL
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'自定义域名',
+'SCHEMA', N'dbo',
+'TABLE', N'sys_oss_config',
+'COLUMN', N'domain'
+GO
+
+UPDATE [sys_oss_config] SET [access_key] = N'ruoyi', [secret_key] = N'ruoyi123', [endpoint] = N'127.0.0.1:9000' WHERE [oss_config_id] = 1
+GO
+
+UPDATE [sys_oss_config] SET [endpoint] = N's3-cn-north-1.qiniucs.com' WHERE [oss_config_id] = 2
+GO
+
+UPDATE [sys_oss_config] SET [endpoint] = N'oss-cn-beijing.aliyuncs.com' WHERE [oss_config_id] = 3
+GO
+
+UPDATE [sys_oss_config] SET [endpoint] = N'cos.ap-beijing.myqcloud.com' WHERE [oss_config_id] = 4
+GO
+
+INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'5', N'image', N'ruoyi', N'ruoyi123', N'ruoyi', N'image', N'127.0.0.1:9000', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
+GO
+
+ALTER TABLE [gen_table_column] ALTER COLUMN [table_id] bigint NULL
+GO
diff --git a/script/sql/update/update-4.1-4.2.sql b/script/sql/update/update-4.1-4.2.sql
new file mode 100644
index 000000000..1d9cf508f
--- /dev/null
+++ b/script/sql/update/update-4.1-4.2.sql
@@ -0,0 +1,14 @@
+alter table sys_oss_config add column domain varchar(255) null default '' COMMENT '自定义域名';
+
+update sys_oss_config set endpoint = '127.0.0.1:9000' where oss_config_id = 1;
+update sys_oss_config set endpoint = 's3-cn-north-1.qiniucs.com', region = '' where oss_config_id = 2;
+update sys_oss_config set endpoint = 'oss-cn-beijing.aliyuncs.com' where oss_config_id = 3;
+update sys_oss_config set endpoint = 'cos.ap-beijing.myqcloud.com' where oss_config_id = 4;
+
+insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', 'N', '', '1', '', 'admin', sysdate(), 'admin', sysdate(), NULL, '');
+
+alter table gen_table_column modify column table_id bigint(0) null default null COMMENT '归属表编号';
+
+alter table sys_notice modify column notice_id bigint(0) not null COMMENT '公告ID';
+
+alter table sys_config modify column config_id bigint(0) not null COMMENT '参数主键';