diff --git a/pom.xml b/pom.xml index 9dce46546..43eb242ba 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,13 @@ + + com.tencentcloudapi + tencentcloud-sdk-java + + + 3.1.1000 + javax.json.bind javax.json.bind-api diff --git a/src/main/java/com/zhgd/xmgl/async/AsyncAiAnalyse.java b/src/main/java/com/zhgd/xmgl/async/AsyncAiAnalyse.java index 34e1a950c..72e9e3faf 100644 --- a/src/main/java/com/zhgd/xmgl/async/AsyncAiAnalyse.java +++ b/src/main/java/com/zhgd/xmgl/async/AsyncAiAnalyse.java @@ -1,7 +1,15 @@ package com.zhgd.xmgl.async; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zhgd.mqtt.bean.PushPayload; import com.zhgd.mqtt.server.IMqttSender; +import com.zhgd.xmgl.call.TencentCloudMessageCall; +import com.zhgd.xmgl.call.YunPianMessageCall; +import com.zhgd.xmgl.call.api.MessageManufacturer; +import com.zhgd.xmgl.call.factory.MessageManufacturerFactory; import com.zhgd.xmgl.constant.Cts; import com.zhgd.xmgl.modules.basicdata.constant.DictionaryConstant; import com.zhgd.xmgl.modules.basicdata.entity.CompanyConfig; @@ -13,19 +21,27 @@ import com.zhgd.xmgl.modules.basicdata.service.ICompanyConfigService; import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService; import com.zhgd.xmgl.modules.basicdata.service.impl.DictionaryItemServiceImpl; import com.zhgd.xmgl.modules.basicdata.service.impl.NoticeServiceImpl; +import com.zhgd.xmgl.modules.project.service.IMessageConfigV2Service; import com.zhgd.xmgl.modules.video.entity.AiAnalyseHardWareAlarmRecord; +import com.zhgd.xmgl.modules.worker.entity.WorkerInfo; +import com.zhgd.xmgl.modules.worker.service.impl.WorkerInfoServiceImpl; import com.zhgd.xmgl.push.service.UniPushService; import com.zhgd.xmgl.util.MapBuilder; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; /** * @program: wisdomSite @@ -36,6 +52,9 @@ import java.util.Objects; @Slf4j @Component public class AsyncAiAnalyse { + @Lazy + @Autowired + WorkerInfoServiceImpl workerInfoService; @Autowired private IMqttSender mqttPushClient; @Autowired @@ -54,6 +73,12 @@ public class AsyncAiAnalyse { @Value("${mqtt-scope}") private String scope; + @Autowired + @Qualifier("doubleCarbonExecutor") + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + @Lazy + @Autowired + private MessageManufacturerFactory messageManufacturerFactory; /** * @param record @@ -63,6 +88,7 @@ public class AsyncAiAnalyse { try { String title = getTitleByAlarmType(record.getAlarmType(), record.getProjectSn()); title = title == null ? "其他类型" : title; + String typeName = title; String msg = title + ",位置" + record.getLocation(); List systemUserList; if (type.equals(Cts.PROJECT_LEVEL)) { @@ -78,11 +104,36 @@ public class AsyncAiAnalyse { } // sendAppNotice(record.getProjectSn(), title, msg, systemUserList, "/pages/potentialRisk/potentialRisk?id=" + record.getId()); } + sendMsg(systemUserList, typeName, record.getLocation(), record.getProjectSn()); } catch (Exception e) { log.error("error:", e); } } + /** + * 发送短信 + * + * @param systemUserList + * @param typeName + * @param location + * @param projectSn + */ + private void sendMsg(List systemUserList, String typeName, String location, String projectSn) { + CompletableFuture.runAsync(() -> { + MessageManufacturer messageManufacturer = messageManufacturerFactory.getMessageManufacturer(projectSn); + if (messageManufacturer != null) { + List phoneNums = systemUserList.stream().map(SystemUser::getUserTel).collect(Collectors.toList()); + List templateParams = new ArrayList<>(); + //报警类型,报警名称,设备名称,报警值,阈值,超标时间,超标量 + templateParams.add(typeName); + templateParams.add(location); + String text = StrUtil.format("【{}】AI警报!{},位置{}", + messageManufacturer.getConfig().getSignature(), typeName, location); + messageManufacturer.sendMsgByConfig(phoneNums, 2, templateParams, text); + } + }, threadPoolTaskExecutor); + } + public String getTitleByAlarmType(Integer alarmType, String projectSn) { DictionaryItem dict = dictionaryItemService.getDict(DictionaryConstant.AI_ANALYSE_HARD_WARE_ALARM_RECORD_TYPE, alarmType + "", projectSn); return dict != null ? dict.getName() : null; diff --git a/src/main/java/com/zhgd/xmgl/call/TencentCloudMessageCall.java b/src/main/java/com/zhgd/xmgl/call/TencentCloudMessageCall.java new file mode 100644 index 000000000..362503605 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/call/TencentCloudMessageCall.java @@ -0,0 +1,75 @@ +package com.zhgd.xmgl.call; + +import com.gexin.fastjson.JSON; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.exception.TencentCloudSDKException; +import com.tencentcloudapi.sms.v20210111.SmsClient; +import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest; +import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse; +import com.zhgd.xmgl.call.api.MessageManufacturer; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 腾讯云短信 + */ +@Slf4j +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class TencentCloudMessageCall implements MessageManufacturer { + private MessageConfigV2 config; + + @Override + public MessageConfigV2 getConfig() { + return config; + } + + @Override + public void setConfig(MessageConfigV2 config) { + this.config = config; + } + + + @Override + public void sendMsgByConfig(List phoneNums, int pushFunctionType, List templateParams, String text) { + try { + if (pushFunctionType == 1 && config.getEnableDustSend() == 1) { + //报警类型,报警名称,设备名称,报警值,阈值,超标时间,超标量 + doSendMsg(phoneNums, config.getDustTemplateId(), templateParams.toArray(new String[]{})); + } else if (pushFunctionType == 2 && config.getEnableAiSend() == 1) { + doSendMsg(phoneNums, config.getAiTemplateId(), templateParams.toArray(new String[]{})); + } else if (pushFunctionType == 3 && config.getEnableLoginSend() == 1) { + doSendMsg(phoneNums, config.getLoginTemplateId(), templateParams.toArray(new String[]{})); + } + } catch (Exception e) { + log.error("按短信配置发送短信异常", e); + } + } + + /** + * 发送短信 + * + * @param phoneNums 手机号码 + * @param templateId 短信模板id + * @param templateParamSet 短信模板参数 + * @throws TencentCloudSDKException + */ + private void doSendMsg(List phoneNums, String templateId, String[] templateParamSet) throws TencentCloudSDKException { + Credential credential = new Credential(config.getSecretId(), config.getSecretKey()); + SmsClient smsClient = new SmsClient(credential, "ap-singapore"); + SendSmsRequest req = new SendSmsRequest(); + req.setPhoneNumberSet(phoneNums.stream().map(s -> "+86" + s).collect(Collectors.toList()).toArray(new String[]{})); + req.setSmsSdkAppId(config.getSmsSdkAppId()); + req.setTemplateId(templateId); + req.setTemplateParamSet(templateParamSet); + SendSmsResponse response = smsClient.SendSms(req); + log.info("腾讯云发送短信结果:{}", JSON.toJSONString(response)); + } + +} diff --git a/src/main/java/com/zhgd/xmgl/call/YunPianMessageCall.java b/src/main/java/com/zhgd/xmgl/call/YunPianMessageCall.java new file mode 100644 index 000000000..0e9bc1f4d --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/call/YunPianMessageCall.java @@ -0,0 +1,53 @@ +package com.zhgd.xmgl.call; + +import cn.hutool.http.HttpRequest; +import com.gexin.fastjson.JSON; +import com.zhgd.xmgl.call.api.MessageManufacturer; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; + +/** + * 云片短信 + */ +@Slf4j +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class YunPianMessageCall implements MessageManufacturer { + private MessageConfigV2 config; + + @Override + public MessageConfigV2 getConfig() { + return config; + } + + @Override + public void setConfig(MessageConfigV2 config) { + this.config = config; + } + + @Override + public void sendMsgByConfig(List phoneNums, int pushFunctionType, List templateParams, String text) { + try { + for (String phoneNum : phoneNums) { + HashMap formMap = new HashMap<>(); + formMap.put("apikey", config.getApiKey()); + formMap.put("mobile", phoneNum); + formMap.put("text", text); + String url = "https://sms.yunpian.com/v2/sms/single_send.json"; + log.info("云片短信按短信配置发送短信,url:{},body:{}", url, JSON.toJSONString(formMap)); + String body = HttpRequest.post(url).form(formMap).execute().body(); + log.info("云片短信按短信配置发送短信,结果:{}", body); + } + } catch (Exception e) { + log.error("云片短信按短信配置发送短信异常", e); + } + } + + +} diff --git a/src/main/java/com/zhgd/xmgl/call/api/MessageManufacturer.java b/src/main/java/com/zhgd/xmgl/call/api/MessageManufacturer.java new file mode 100644 index 000000000..ae0cabf47 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/call/api/MessageManufacturer.java @@ -0,0 +1,26 @@ +package com.zhgd.xmgl.call.api; + +import com.zhgd.xmgl.modules.car.entity.CarInfo; +import com.zhgd.xmgl.modules.car.entity.ProjectCarCameraConfig; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; + +import java.util.Date; +import java.util.List; + +/** + * 短信接口 + */ +public interface MessageManufacturer { + + MessageConfigV2 getConfig(); + + void setConfig(MessageConfigV2 config); + /** + * 按配置发送短信 + * @param phoneNums + * @param pushFunctionType 1:扬尘;2:AI报警;3:登录; + * @param templateParams + * @param text 消息(云片选择) + */ + void sendMsgByConfig(List phoneNums, int pushFunctionType, List templateParams, String text); +} diff --git a/src/main/java/com/zhgd/xmgl/call/factory/MessageManufacturerFactory.java b/src/main/java/com/zhgd/xmgl/call/factory/MessageManufacturerFactory.java new file mode 100644 index 000000000..9b9a74cee --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/call/factory/MessageManufacturerFactory.java @@ -0,0 +1,47 @@ +package com.zhgd.xmgl.call.factory; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zhgd.jeecg.common.util.SpringContextUtils; +import com.zhgd.xmgl.call.TencentCloudMessageCall; +import com.zhgd.xmgl.call.YunPianMessageCall; +import com.zhgd.xmgl.call.api.MessageManufacturer; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import com.zhgd.xmgl.modules.project.service.IMessageConfigV2Service; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +@Slf4j +@Component +public class MessageManufacturerFactory { + @Lazy + @Autowired + private IMessageConfigV2Service messageConfigV2Service; + + /** + * 获取CarManufacturer + * + * @param projectSn + * @return + */ + public MessageManufacturer getMessageManufacturer(String projectSn) { + MessageConfigV2 config = messageConfigV2Service.getOne(new LambdaQueryWrapper() + .eq(MessageConfigV2::getProjectSn, projectSn) + ); + if (config == null) { + return null; + } + MessageManufacturer manufacturer = null; + if (Objects.equals(config.getMessageManufacturerType(), 1)) { + manufacturer = SpringContextUtils.getBean(TencentCloudMessageCall.class); + manufacturer.setConfig(config); + } else if (Objects.equals(config.getMessageManufacturerType(), 2)) { + manufacturer = SpringContextUtils.getBean(YunPianMessageCall.class); + manufacturer.setConfig(config); + } + return manufacturer; + } +} diff --git a/src/main/java/com/zhgd/xmgl/constant/Cts.java b/src/main/java/com/zhgd/xmgl/constant/Cts.java index 99852b848..09498e45e 100644 --- a/src/main/java/com/zhgd/xmgl/constant/Cts.java +++ b/src/main/java/com/zhgd/xmgl/constant/Cts.java @@ -112,4 +112,8 @@ public interface Cts { String STR1112 = "."; String S32434 = "."; String LIMIT_1 = "limit 1"; + /** + * 手机号登录的验证码前缀 + */ + String LOGIN_VERIFICATION_CODE = "LOGIN_VERIFICATION_CODE_"; } diff --git a/src/main/java/com/zhgd/xmgl/modules/basicdata/controller/LoginController.java b/src/main/java/com/zhgd/xmgl/modules/basicdata/controller/LoginController.java index 0e8c1ea7e..a91fd39de 100644 --- a/src/main/java/com/zhgd/xmgl/modules/basicdata/controller/LoginController.java +++ b/src/main/java/com/zhgd/xmgl/modules/basicdata/controller/LoginController.java @@ -1,14 +1,23 @@ package com.zhgd.xmgl.modules.basicdata.controller; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.zhgd.annotation.OperLog; import com.zhgd.jeecg.common.api.vo.Result; +import com.zhgd.jeecg.common.execption.OpenAlertException; +import com.zhgd.redis.lock.RedisRepository; +import com.zhgd.xmgl.call.api.MessageManufacturer; +import com.zhgd.xmgl.call.factory.MessageManufacturerFactory; +import com.zhgd.xmgl.constant.Cts; import com.zhgd.xmgl.modules.basicdata.entity.SystemUser; import com.zhgd.xmgl.modules.basicdata.entity.dto.LoginInfoByTokenDto; import com.zhgd.xmgl.modules.basicdata.service.ILoginService; import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService; -import com.zhgd.xmgl.modules.worker.entity.WorkerInfo; +import com.zhgd.xmgl.util.MapBuilder; +import com.zhgd.xmgl.util.NumberUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -16,12 +25,13 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.MapUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.Map; +import java.util.*; /** * @program: devManage @@ -38,6 +48,12 @@ public class LoginController { private ISystemUserService systemUserService; @Autowired private ILoginService iLoginService; + @Lazy + @Autowired + private MessageManufacturerFactory messageManufacturerFactory; + @Lazy + @Autowired + private RedisRepository redisRepository; @OperLog(operModul = "用户登录", operType = "账号密码登录", operDesc = "账号密码登录") @ApiOperation(value = "账号密码登录", notes = "账号密码登录", httpMethod = "POST") @@ -170,7 +186,6 @@ public class LoginController { return Result.ok(); } - @ApiOperation(value = "获取注册短信验证码", notes = "获取注册短信验证码", httpMethod = "POST") @ApiImplicitParam(name = "phone", required = true, value = "手机号", paramType = "body") @PostMapping(value = "/getRegisterVerificationCode") @@ -179,7 +194,6 @@ public class LoginController { return Result.success(resultMap); } - @ApiOperation(value = "通过第三方标识获取用户登录信息", notes = "通过第三方标识获取用户登录信息", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "uid", required = true, value = "第三方标识", paramType = "body"), @@ -212,4 +226,76 @@ public class LoginController { } return Result.success(true); } + + @ApiOperation(value = "获取登录短信验证码", notes = "获取登录短信验证码", httpMethod = "POST") + @ApiImplicitParam(name = "phone", required = true, value = "手机号", paramType = "body") + @PostMapping(value = "/getLoginVerificationCode") + public Result getLoginVerificationCode(@RequestBody Map map) { + try { + SystemUser user = systemUserService.getOne(new LambdaQueryWrapper() + .eq(SystemUser::getUserTel, MapUtils.getString(map, "phone"))); + if (user == null) { + throw new OpenAlertException("手机号不存在"); + } + MessageManufacturer messageManufacturer = messageManufacturerFactory.getMessageManufacturer(user.getSn()); + if (messageManufacturer != null && messageManufacturer.getConfig().getEnableLoginSend() == 1) { + List templateParams = new ArrayList<>(); + String key = Cts.LOGIN_VERIFICATION_CODE + user.getUserTel(); + Map hashValue = redisRepository.getHashValue(key); + if (hashValue == null) { + hashValue = new HashMap<>(); + } else { + if (DateUtil.compare(DateUtil.parseDateTime(hashValue.get("t").toString()), DateUtil.offsetMinute(new Date(), -1)) > 0) { + throw new OpenAlertException("获取登录短信验证码太频繁,请稍后重试"); + } + } + //报警类型,报警名称,设备名称,报警值,阈值,超标时间,超标量 + String randomNum = NumberUtils.randomNum(6); + hashValue.put("num", randomNum); + hashValue.put("t", DateUtil.now()); + redisRepository.set(key, hashValue, 60L); + templateParams.add(randomNum); + String text = StrUtil.format("【{}】您的登录验证码是:{},有效期5分钟。请勿泄露给他人。", + messageManufacturer.getConfig().getSignature(), randomNum); + List phoneNums = new ArrayList<>(); + phoneNums.add(user.getUserTel()); + messageManufacturer.sendMsgByConfig(phoneNums, 3, templateParams, text); + return Result.ok(); + } else { + throw new OpenAlertException("短信没配置或没启动短信登录"); + } + } catch (OpenAlertException e) { + throw e; + } catch (Exception e) { + throw new OpenAlertException("获取登录短信验证码异常"); + } + } + + @ApiOperation(value = "短信验证码手机号登录", notes = "短信验证码手机号登录", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name = "phone", required = true, value = "手机号", paramType = "body"), + @ApiImplicitParam(name = "verificationCode", required = true, value = "短信验证码", paramType = "body"), + }) + @PostMapping(value = "/loginPhoneByVerificationCode") + public Result> loginPhoneByVerificationCode(@RequestBody Map map) { + SystemUser user = systemUserService.getOne(new LambdaQueryWrapper() + .eq(SystemUser::getUserTel, MapUtils.getString(map, "phone"))); + if (user == null) { + throw new OpenAlertException("手机号不存在"); + } + String key = Cts.LOGIN_VERIFICATION_CODE + user.getUserTel(); + Map hashValue = redisRepository.getHashValue(key); + if (hashValue == null) { + throw new OpenAlertException("短信验证码已过期"); + } else { + if (!hashValue.get("num").toString().equals(MapUtils.getString(map,"verificationCode"))) { + throw new OpenAlertException("短信验证码不正确"); + } + } + Map resultMap = systemUserService.login(new MapBuilder() + .put("account", user.getAccount()) + .put("password", user.getShowPassword()) + .build()); + return Result.success(resultMap); + } } diff --git a/src/main/java/com/zhgd/xmgl/modules/environment/service/impl/EnvironmentAlarmServiceImpl.java b/src/main/java/com/zhgd/xmgl/modules/environment/service/impl/EnvironmentAlarmServiceImpl.java index 3b77a9084..704d2cc54 100644 --- a/src/main/java/com/zhgd/xmgl/modules/environment/service/impl/EnvironmentAlarmServiceImpl.java +++ b/src/main/java/com/zhgd/xmgl/modules/environment/service/impl/EnvironmentAlarmServiceImpl.java @@ -1,5 +1,8 @@ package com.zhgd.xmgl.modules.environment.service.impl; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; import cn.xuyanwu.spring.file.storage.FileInfo; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -7,13 +10,15 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zhgd.jeecg.common.mybatis.EntityMap; -import com.zhgd.redis.lock.RedisRepository; import com.zhgd.xmgl.async.AsyncEnvironment; +import com.zhgd.xmgl.call.api.MessageManufacturer; +import com.zhgd.xmgl.call.factory.MessageManufacturerFactory; import com.zhgd.xmgl.modules.basicdata.entity.Notice; import com.zhgd.xmgl.modules.basicdata.entity.SystemUser; import com.zhgd.xmgl.modules.basicdata.mapper.SystemUserMapper; import com.zhgd.xmgl.modules.basicdata.service.ICompanyService; import com.zhgd.xmgl.modules.basicdata.service.INoticeService; +import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService; import com.zhgd.xmgl.modules.basicdata.service.UploadFileService; import com.zhgd.xmgl.modules.bigdevice.mapper.BigDeviceVideoMapper; import com.zhgd.xmgl.modules.environment.entity.*; @@ -23,12 +28,17 @@ import com.zhgd.xmgl.modules.environment.mapper.EnvironmentAlarmMapper; import com.zhgd.xmgl.modules.environment.mapper.EnvironmentWarningMapper; import com.zhgd.xmgl.modules.environment.service.IEnvironmentAlarmService; import com.zhgd.xmgl.modules.project.entity.qo.QueryProjectTodayAlarmInfoQO; +import com.zhgd.xmgl.modules.project.service.IMessageConfigV2Service; import com.zhgd.xmgl.modules.sprayrt.service.ISprayRtDevService; +import com.zhgd.xmgl.modules.worker.service.impl.WorkerInfoServiceImpl; import com.zhgd.xmgl.util.DateUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -36,6 +46,7 @@ import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.sql.Timestamp; import java.util.*; +import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; /** @@ -47,6 +58,12 @@ import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) public class EnvironmentAlarmServiceImpl extends ServiceImpl implements IEnvironmentAlarmService { + @Lazy + @Autowired + WorkerInfoServiceImpl workerInfoService; + @Lazy + @Autowired + ISystemUserService systemUserService; @Autowired private SystemUserMapper systemUserMapper; @Autowired @@ -69,6 +86,15 @@ public class EnvironmentAlarmServiceImpl extends ServiceImpl queryEnvironmentAlarmPageList(Map map) { @@ -127,6 +153,7 @@ public class EnvironmentAlarmServiceImpl extends ServiceImpl { + MessageManufacturer messageManufacturer = messageManufacturerFactory.getMessageManufacturer(environmentAlarm.getProjectSn()); + if (messageManufacturer != null) { + String alarmType = environmentAlarm.getType() == 1 ? "预警" : "报警"; + String threshold = NumberUtil.sub(environmentAlarm.getAlarmValue(), environmentAlarm.getExceed()) + ""; + String time = DateUtil.formatDateTime(environmentAlarm.getAlarmTime()); + List phoneNums = systemUserService.list(new LambdaQueryWrapper() + .in(SystemUser::getId, StrUtil.split(pushPerson, ","))).stream().map(SystemUser::getUserTel).collect(Collectors.toList()); + List templateParams = new ArrayList<>(); + //报警类型,报警名称,设备名称,报警值,阈值,超标时间,超标量 + templateParams.add(alarmType); + templateParams.add(alarmName); + templateParams.add(devname); + templateParams.add(environmentAlarm.getAlarmValue() + ""); + templateParams.add(threshold); + templateParams.add(time); + templateParams.add(environmentAlarm.getExceed() + ""); + String text = StrUtil.format("【{}】扬尘超标警报!报警类型:{},报警名称:{},设备名称:{},报警值:{},阈值:{},超标时间:{},超标量:{}", + messageManufacturer.getConfig().getSignature(), alarmType, alarmName, devname, environmentAlarm.getAlarmValue() + "", threshold, time, environmentAlarm.getExceed() + ""); + messageManufacturer.sendMsgByConfig(phoneNums, 1, templateParams, text); + } + }, threadPoolTaskExecutor); + } + @Override public List selectNewEnvironmentAlarmList(Map map) { return environmentAlarmMapper.selectNewEnvironmentAlarmList(map); diff --git a/src/main/java/com/zhgd/xmgl/modules/project/controller/MessageConfigV2Controller.java b/src/main/java/com/zhgd/xmgl/modules/project/controller/MessageConfigV2Controller.java new file mode 100644 index 000000000..7b0cf2cf8 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/controller/MessageConfigV2Controller.java @@ -0,0 +1,141 @@ +package com.zhgd.xmgl.modules.project.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.zhgd.annotation.OperLog; +import com.zhgd.jeecg.common.api.vo.Result; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import com.zhgd.xmgl.modules.project.entity.dto.MessageConfigV2Dto; +import com.zhgd.xmgl.modules.project.entity.vo.MessageConfigV2Vo; +import com.zhgd.xmgl.modules.project.service.IMessageConfigV2Service; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.MapUtils; +import org.simpleframework.xml.core.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.HashMap; +import java.util.List; + + +/** + * @Title: Controller + * @Description: 短信配置v2 + * @author: pds + * @date: 2025-07-29 + * @version: V1.0 + */ +@RestController +@RequestMapping("/xmgl/messageConfigV2") +@Slf4j +@Api(tags = "短信配置v2相关Api") +public class MessageConfigV2Controller { + @Lazy + @Autowired + private IMessageConfigV2Service messageConfigV2Service; + + /** + * 分页列表查询 + * + * @return + */ + @OperLog(operModul = "短信配置v2管理", operType = "分页查询", operDesc = "分页列表查询短信配置v2信息") + @ApiOperation(value = "分页列表查询短信配置v2信息", notes = "分页列表查询短信配置v2信息", httpMethod = "GET") + @ApiImplicitParams({ + @ApiImplicitParam(name = "pageNo", value = "第几页", paramType = "query", required = true, dataType = "Integer"), + @ApiImplicitParam(name = "pageSize", value = "每页显示条数", paramType = "query", required = true, dataType = "Integer"), + }) + @GetMapping(value = "/page") + public Result> queryPageList(@ApiIgnore @RequestParam HashMap param) { + return Result.success(messageConfigV2Service.queryPageList(param)); + } + + /** + * 列表查询 + * + * @return + */ + @OperLog(operModul = "短信配置v2管理", operType = "列表查询", operDesc = "列表查询短信配置v2信息") + @ApiOperation(value = "列表查询短信配置v2信息", notes = "列表查询短信配置v2信息", httpMethod = "GET") + @GetMapping(value = "/list") + public Result> queryList(@ApiIgnore @RequestParam HashMap param) { + return Result.success(messageConfigV2Service.queryList(param)); + } + + /** + * 添加 + * + * @param messageConfigV2Dto + * @return + */ + @OperLog(operModul = "短信配置v2管理", operType = "添加", operDesc = "添加短信配置v2信息") + @ApiOperation(value = "添加短信配置v2信息", notes = "添加短信配置v2信息", httpMethod = "POST") + @PostMapping(value = "/add") + public Result add(@RequestBody @Validate MessageConfigV2Dto messageConfigV2Dto) { + messageConfigV2Service.add(messageConfigV2Dto); + return Result.ok(); + } + + /** + * 编辑 + * + * @param messageConfigV2Dto + * @return + */ + @OperLog(operModul = "短信配置v2管理", operType = "编辑", operDesc = "编辑短信配置v2信息") + @ApiOperation(value = "编辑短信配置v2信息", notes = "编辑短信配置v2信息", httpMethod = "POST") + @PostMapping(value = "/edit") + public Result edit(@RequestBody MessageConfigV2Dto messageConfigV2Dto) { + messageConfigV2Service.edit(messageConfigV2Dto); + return Result.ok(); + } + + /** + * 通过id删除 + * + * @return + */ + @OperLog(operModul = "短信配置v2管理", operType = "删除", operDesc = "删除短信配置v2信息") + @ApiOperation(value = "删除短信配置v2信息", notes = "删除短信配置v2信息", httpMethod = "POST") + @ApiImplicitParam(name = "id", value = "短信配置v2ID", paramType = "body", required = true, dataType = "String", example = "{\"id\":\"1\"}") + @PostMapping(value = "/delete") + public Result delete(@ApiIgnore @RequestBody HashMap map) { + messageConfigV2Service.delete(MapUtils.getString(map, "id")); + return Result.ok(); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @OperLog(operModul = "短信配置v2管理", operType = "通过id查询", operDesc = "通过id查询短信配置v2信息") + @ApiOperation(value = "通过id查询短信配置v2信息", notes = "通过id查询短信配置v2信息", httpMethod = "GET") + @ApiImplicitParam(name = "id", value = "短信配置v2ID", paramType = "query", required = true, dataType = "Integer") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + return Result.success(messageConfigV2Service.queryById(id)); + } + + @OperLog(operModul = "短信配置v2管理", operType = "", operDesc = "保存短信配置v2信息") + @ApiOperation(value = "保存短信配置v2信息", notes = "保存短信配置v2信息", httpMethod = "POST") + @PostMapping(value = "/saveConfig") + public Result saveConfig(@RequestBody MessageConfigV2Dto messageConfigV2Dto) { + MessageConfigV2 configV2 = messageConfigV2Service.getOne(new LambdaQueryWrapper() + .eq(MessageConfigV2::getProjectSn, messageConfigV2Dto.getProjectSn())); + if (configV2 == null) { + messageConfigV2Service.add(messageConfigV2Dto); + } else { + messageConfigV2Dto.setId(configV2.getId()); + messageConfigV2Service.edit(messageConfigV2Dto); + } + return Result.success(messageConfigV2Dto); + } +} diff --git a/src/main/java/com/zhgd/xmgl/modules/project/entity/MessageConfigV2.java b/src/main/java/com/zhgd/xmgl/modules/project/entity/MessageConfigV2.java new file mode 100644 index 000000000..92907a28b --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/entity/MessageConfigV2.java @@ -0,0 +1,117 @@ +package com.zhgd.xmgl.modules.project.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; + +/** + * @Description: 短信配置v2 + * @author: pds + * @date: 2025-07-29 + * @version: V1.0 + */ +@Data +@TableName("message_config_v2") +@ApiModel(value = "MessageConfigV2实体类", description = "MessageConfigV2") +public class MessageConfigV2 implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键id") + private java.lang.Long id; + /** + * 所属项目SN + */ + @ApiModelProperty(value = "所属项目SN") + private java.lang.String projectSn; + /** + * 短信厂商:1:腾讯云;2:云片; + */ + @ApiModelProperty(value = "短信厂商:1:腾讯云;2:云片;") + private java.lang.Integer messageManufacturerType; + /** + * 签名 + */ + @ApiModelProperty(value = "签名") + private java.lang.String signature; + /** + * 腾讯云的secret_id + */ + @ApiModelProperty(value = "腾讯云的secret_id") + private java.lang.String secretId; + /** + * 腾讯云的secret_key + */ + @ApiModelProperty(value = "腾讯云的secret_key") + private java.lang.String secretKey; + /** + * 腾讯云在短信控制台中添加应用后生成的短信 SdkAppId,例如 2400006666 + */ + @ApiModelProperty(value = "腾讯云在短信控制台中添加应用后生成的短信 SdkAppId,例如 2400006666") + private java.lang.String smsSdkAppId; + /** + * 云片apikey + */ + @ApiModelProperty(value = "云片apikey") + private java.lang.String apiKey; + /** + * 验证码短信模板 + */ + @ApiModelProperty(value = "验证码短信模板") + private java.lang.String validCodeMessage; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private java.util.Date createTime; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private java.util.Date updateTime; + /** + * 1扬尘推送配置发送短信0不发送 + */ + @ApiModelProperty(value = "1扬尘推送配置发送短信0不发送") + private java.lang.Integer enableDustSend; + /** + * 1AI报警人员推送配置发送短信0不发送 + */ + @ApiModelProperty(value = "1AI报警人员推送配置发送短信0不发送") + private java.lang.Integer enableAiSend; + /** + * 1短信登录推送配置发送短信0不发送 + */ + @ApiModelProperty(value = "1短信登录推送配置发送短信0不发送") + private java.lang.Integer enableLoginSend; + /** + * 腾讯云扬尘短信模板id + */ + @ApiModelProperty(value = "腾讯云扬尘短信模板id") + private java.lang.String dustTemplateId; + /** + * 腾讯云AI报警短信模板id + */ + @ApiModelProperty(value = "腾讯云AI报警短信模板id") + private java.lang.String aiTemplateId; + /** + * 腾讯云登录短信模板id + */ + @ApiModelProperty(value = "腾讯云登录短信模板id") + private java.lang.String loginTemplateId; + +} diff --git a/src/main/java/com/zhgd/xmgl/modules/project/entity/dto/MessageConfigV2Dto.java b/src/main/java/com/zhgd/xmgl/modules/project/entity/dto/MessageConfigV2Dto.java new file mode 100644 index 000000000..8f32f0ef9 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/entity/dto/MessageConfigV2Dto.java @@ -0,0 +1,11 @@ +package com.zhgd.xmgl.modules.project.entity.dto; + +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +@Data +@ApiModel(value="MessageConfigV2Dto实体类",description="MessageConfigV2Dto实体类") +public class MessageConfigV2Dto extends MessageConfigV2 { + +} diff --git a/src/main/java/com/zhgd/xmgl/modules/project/entity/vo/MessageConfigV2Vo.java b/src/main/java/com/zhgd/xmgl/modules/project/entity/vo/MessageConfigV2Vo.java new file mode 100644 index 000000000..7a13223aa --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/entity/vo/MessageConfigV2Vo.java @@ -0,0 +1,11 @@ +package com.zhgd.xmgl.modules.project.entity.vo; + +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +@Data +@ApiModel(value="MessageConfigV2Vo实体类",description="MessageConfigV2Vo实体类") +public class MessageConfigV2Vo extends MessageConfigV2 { + +} diff --git a/src/main/java/com/zhgd/xmgl/modules/project/mapper/MessageConfigV2Mapper.java b/src/main/java/com/zhgd/xmgl/modules/project/mapper/MessageConfigV2Mapper.java new file mode 100644 index 000000000..f1f500daa --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/mapper/MessageConfigV2Mapper.java @@ -0,0 +1,52 @@ +package com.zhgd.xmgl.modules.project.mapper; + +import java.util.List; +import java.util.HashMap; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import com.zhgd.xmgl.modules.project.entity.vo.MessageConfigV2Vo; +import com.zhgd.xmgl.modules.project.entity.dto.MessageConfigV2Dto; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 短信配置v2 + * @author: pds + * @date: 2025-07-29 + * @version: V1.0 + */ +@Mapper +public interface MessageConfigV2Mapper extends BaseMapper { + + /** + * 分页列表查询短信配置v2信息 + * + * @param page + * @param queryWrapper + * @param param + * @return + */ + IPage queryList(Page page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper, @Param("param") HashMap param); + + /** + * 列表查询短信配置v2信息 + * + * @param queryWrapper + * @param param + * @return + */ + List queryList(@Param(Constants.WRAPPER) QueryWrapper queryWrapper, @Param("param") HashMap param); + + + /** + * 通过id查询短信配置v2信息 + * + * @param id + * @return + */ + MessageConfigV2Vo queryById(String id); +} diff --git a/src/main/java/com/zhgd/xmgl/modules/project/mapper/xml/MessageConfigV2Mapper.xml b/src/main/java/com/zhgd/xmgl/modules/project/mapper/xml/MessageConfigV2Mapper.xml new file mode 100644 index 000000000..e7b824079 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/mapper/xml/MessageConfigV2Mapper.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/src/main/java/com/zhgd/xmgl/modules/project/service/IMessageConfigV2Service.java b/src/main/java/com/zhgd/xmgl/modules/project/service/IMessageConfigV2Service.java new file mode 100644 index 000000000..be1e3d1bf --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/service/IMessageConfigV2Service.java @@ -0,0 +1,56 @@ +package com.zhgd.xmgl.modules.project.service; + +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import com.zhgd.xmgl.modules.project.entity.vo.MessageConfigV2Vo; +import com.zhgd.xmgl.modules.project.entity.dto.MessageConfigV2Dto; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.core.metadata.IPage; +import java.util.HashMap; +import java.util.List; + +/** + * @Description: 短信配置v2 + * @author: pds + * @date: 2025-07-29 + * @version: V1.0 + */ +public interface IMessageConfigV2Service extends IService { + /** + * 分页列表查询短信配置v2信息 + * @param param 参数map + * @return + */ + IPage queryPageList(HashMap param); + /** + * 列表查询短信配置v2信息 + * @param param 参数map + * @return + */ + List queryList(HashMap param); + /** + * 添加短信配置v2信息 + * @param messageConfigV2Dto 短信配置v2 + * @return + */ + void add(MessageConfigV2Dto messageConfigV2Dto); + /** + * 编辑短信配置v2信息 + * @param messageConfigV2Dto 短信配置v2 + * @return + */ + void edit(MessageConfigV2Dto messageConfigV2Dto); + /** + * 根据id删除短信配置v2信息 + * @param id 短信配置v2的id + * @return + */ + void delete(String id); + /** + * 根据id查询短信配置v2信息 + * @param id 短信配置v2的id + * @return + */ + MessageConfigV2Vo queryById(String id); + + +} diff --git a/src/main/java/com/zhgd/xmgl/modules/project/service/impl/MessageConfigV2ServiceImpl.java b/src/main/java/com/zhgd/xmgl/modules/project/service/impl/MessageConfigV2ServiceImpl.java new file mode 100644 index 000000000..1a81c2bf5 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/modules/project/service/impl/MessageConfigV2ServiceImpl.java @@ -0,0 +1,90 @@ +package com.zhgd.xmgl.modules.project.service.impl; + +import com.zhgd.jeecg.common.execption.OpenAlertException; +import com.zhgd.xmgl.modules.project.entity.MessageConfigV2; +import com.zhgd.xmgl.modules.project.entity.vo.MessageConfigV2Vo; +import com.zhgd.xmgl.modules.project.entity.dto.MessageConfigV2Dto; +import com.zhgd.xmgl.modules.project.mapper.MessageConfigV2Mapper; +import com.zhgd.xmgl.modules.project.service.IMessageConfigV2Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zhgd.jeecg.common.system.query.QueryGenerator; +import com.zhgd.xmgl.util.PageUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import java.util.HashMap; +import java.util.List; +import com.zhgd.xmgl.util.RefUtil; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: 短信配置v2 + * @author: pds + * @date: 2025-07-29 + * @version: V1.0 + */ +@Service +public class MessageConfigV2ServiceImpl extends ServiceImpl implements IMessageConfigV2Service { + @Autowired + private MessageConfigV2Mapper messageConfigV2Mapper; + @Override + public IPage queryPageList(HashMap param) { + QueryWrapper queryWrapper = this.getQueryWrapper(param); + Page page = PageUtil.getPage(param); + IPage pageList = baseMapper.queryList(page, queryWrapper,param); + pageList.setRecords(this.dealList(pageList.getRecords())); + return pageList; + } + + @Override + public List queryList(HashMap param) { + QueryWrapper queryWrapper = getQueryWrapper(param); + return dealList(baseMapper.queryList(queryWrapper,param)); + } + + private QueryWrapper getQueryWrapper(HashMap param) { + QueryWrapper queryWrapper = QueryGenerator.initPageQueryWrapper(MessageConfigV2Vo.class, param, true); + queryWrapper.orderByDesc(RefUtil.fieldNameUlc(MessageConfigV2Vo::getId)); + return queryWrapper; + } + + private List dealList(List list) { + return list; + } + + @Override + public void add(MessageConfigV2Dto messageConfigV2Dto) { + messageConfigV2Dto.setId(null); + baseMapper.insert(messageConfigV2Dto); + } + + @Override + public void edit(MessageConfigV2Dto messageConfigV2Dto) { + MessageConfigV2 oldMessageConfigV2 = baseMapper.selectById(messageConfigV2Dto.getId()); + if(oldMessageConfigV2==null) { + throw new OpenAlertException("未找到对应实体"); + } + baseMapper.updateById(messageConfigV2Dto); + } + + @Override + public void delete(String id) { + MessageConfigV2 messageConfigV2 = baseMapper.selectById(id); + if(messageConfigV2==null) { + throw new OpenAlertException("未找到对应实体"); + } + baseMapper.deleteById(id); + } + + @Override + public MessageConfigV2Vo queryById(String id) { + MessageConfigV2Vo entity = baseMapper.queryById(id); + if (entity == null) { + throw new OpenAlertException("未找到对应实体"); + } + return entity; + } + +}