(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).
*
*
+
+ com.ruoyi
+ ruoyi-common
+
+
+
+ com.aliyun
+ dysmsapi20170525
+ true
+
+
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java
+ true
+
+
+
+
+
diff --git a/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java
new file mode 100644
index 000000000..753773e87
--- /dev/null
+++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java
@@ -0,0 +1,45 @@
+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-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java
new file mode 100644
index 000000000..39359cdfd
--- /dev/null
+++ b/ruoyi-sms/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-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java
new file mode 100644
index 000000000..87c3f3bdb
--- /dev/null
+++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java
@@ -0,0 +1,65 @@
+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);
+ }
+
+ 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-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java
new file mode 100644
index 000000000..0aec3ddbe
--- /dev/null
+++ b/ruoyi-sms/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-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java
new file mode 100644
index 000000000..ce82c3c69
--- /dev/null
+++ b/ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java
@@ -0,0 +1,80 @@
+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);
+ }
+
+ 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-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java
new file mode 100644
index 000000000..3f13b2774
--- /dev/null
+++ b/ruoyi-sms/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-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java b/ruoyi-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java
new file mode 100644
index 000000000..28632a375
--- /dev/null
+++ b/ruoyi-sms/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-system/pom.xml b/ruoyi-system/pom.xml
index 57ec06c08..9e49b71ad 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -5,7 +5,7 @@
ruoyi-vue-plus
com.ruoyi
- 4.1.0
+ 4.2.0
4.0.0
@@ -29,6 +29,12 @@
ruoyi-oss
+
+
+ com.ruoyi
+ ruoyi-sms
+
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
index a8340df77..577f17fb8 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
index 9a66e384b..5ac4e96e4 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
index 0fb08dd00..20edacaa6 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/ISysOssService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java
index b444e6d06..c55e5bc12 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
index e0b53c1fb..1a672e59c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
index 2f9d0020a..6525d31e9 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
index f78be1e83..015c156ab 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
index 19423f404..03a6cfca8 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
index 08d4cc4f9..fe142ca3c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
+++ b/ruoyi-system/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-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index 2ef63881c..ed24ab4e9 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-system/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-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
index 08838c599..2f69197b3 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
+++ b/ruoyi-system/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-system/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
index dc54c7e9f..90dff5051 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
+++ b/ruoyi-system/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 @@
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index 0b388d136..dacdcd8a6 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/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
@@ -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-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
index 63a846d30..5a55fcb1e 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
@@ -10,8 +10,8 @@
diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json
index c7f0b7334..c9486724f 100644
--- a/ruoyi-ui/package.json
+++ b/ruoyi-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "ruoyi-vue-plus",
- "version": "4.1.0",
+ "version": "4.2.0",
"description": "RuoYi-Vue-Plus后台管理系统",
"author": "LionLi",
"license": "MIT",
diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js
index 0327e6f9a..3c5bcfe21 100644
--- a/ruoyi-ui/src/api/login.js
+++ b/ruoyi-ui/src/api/login.js
@@ -57,3 +57,15 @@ export function getCodeImg() {
timeout: 20000
})
}
+
+// 短信验证码
+export function getCodeSms() {
+ return request({
+ url: '/captchaSms',
+ headers: {
+ isToken: false
+ },
+ method: 'get',
+ timeout: 20000
+ })
+}
diff --git a/ruoyi-ui/src/api/system/oss.js b/ruoyi-ui/src/api/system/oss.js
index 83adca54e..7d8002600 100644
--- a/ruoyi-ui/src/api/system/oss.js
+++ b/ruoyi-ui/src/api/system/oss.js
@@ -9,6 +9,14 @@ export function listOss(query) {
})
}
+// 查询OSS对象基于id串
+export function listByIds(ossId) {
+ return request({
+ url: '/system/oss/listByIds/' + ossId,
+ method: 'get'
+ })
+}
+
// 删除OSS对象存储
export function delOss(ossId) {
return request({
diff --git a/ruoyi-ui/src/assets/styles/element-variables.scss b/ruoyi-ui/src/assets/styles/element-variables.scss
index 8b7a48e9e..1615ff289 100644
--- a/ruoyi-ui/src/assets/styles/element-variables.scss
+++ b/ruoyi-ui/src/assets/styles/element-variables.scss
@@ -17,7 +17,7 @@ $--button-font-weight: 400;
$--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5;
-$--table-border:1px solid#dfe6ec;
+$--table-border: 1px solid #dfe6ec;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
diff --git a/ruoyi-ui/src/components/FileUpload/index.vue b/ruoyi-ui/src/components/FileUpload/index.vue
index 78baf48dd..e999f14f8 100644
--- a/ruoyi-ui/src/components/FileUpload/index.vue
+++ b/ruoyi-ui/src/components/FileUpload/index.vue
@@ -41,7 +41,7 @@
diff --git a/ruoyi-ui/src/components/ImagePreview/index.vue b/ruoyi-ui/src/components/ImagePreview/index.vue
index 743d8d51d..671eda323 100644
--- a/ruoyi-ui/src/components/ImagePreview/index.vue
+++ b/ruoyi-ui/src/components/ImagePreview/index.vue
@@ -12,7 +12,6 @@
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index 1e0144f40..caf30d747 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -73,6 +73,9 @@ DictData.install()
* please remove it before going online! ! !
*/
+// 修改 el-dialog 默认点击遮照为不关闭
+Element.Dialog.props.closeOnClickModal.default = false
+
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
})
diff --git a/ruoyi-ui/src/utils/dict/DictMeta.js b/ruoyi-ui/src/utils/dict/DictMeta.js
index 8ae6133ec..2ae08273a 100644
--- a/ruoyi-ui/src/utils/dict/DictMeta.js
+++ b/ruoyi-ui/src/utils/dict/DictMeta.js
@@ -11,7 +11,7 @@ import DictOptions from './DictOptions'
export default class DictMeta {
constructor(options) {
this.type = options.type
- this.request = options.request,
+ this.request = options.request
this.responseConverter = options.responseConverter
this.labelField = options.labelField
this.valueField = options.valueField
diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js
index 7e6eccd11..d2cd2a060 100644
--- a/ruoyi-ui/src/utils/ruoyi.js
+++ b/ruoyi-ui/src/utils/ruoyi.js
@@ -68,7 +68,7 @@ export function addDateRange(params, dateRange, propName) {
return search;
}
-// 回显数据字典
+// 回显数据字典
export function selectDictLabel(datas, value) {
if (value === undefined) {
return "";
@@ -207,10 +207,10 @@ export function tansParams(params) {
for (const propName of Object.keys(params)) {
const value = params[propName];
var part = encodeURIComponent(propName) + "=";
- if (value !== null && typeof (value) !== "undefined") {
+ if (value !== null && value !== "" && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
- if (value[key] !== null && typeof (value[key]) !== 'undefined') {
+ if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
result += subPart + encodeURIComponent(value[key]) + "&";
@@ -233,4 +233,4 @@ export async function blobValidate(data) {
} catch (error) {
return true;
}
-}
\ No newline at end of file
+}
diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue
index 5a13cc4bd..1576cbd75 100644
--- a/ruoyi-ui/src/views/index.vue
+++ b/ruoyi-ui/src/views/index.vue
@@ -114,7 +114,7 @@ export default {
data() {
return {
// 版本号
- version: "4.1.0",
+ version: "4.2.0",
};
},
methods: {
diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue
index f22099dd3..bdd095234 100644
--- a/ruoyi-ui/src/views/system/dict/data.vue
+++ b/ruoyi-ui/src/views/system/dict/data.vue
@@ -191,7 +191,7 @@