Commit 41caa58c authored by honghy's avatar honghy

短信节点添加目的仓

parent de603ae7
...@@ -36,6 +36,7 @@ create table system_sms_node ...@@ -36,6 +36,7 @@ create table system_sms_node
template_id_two bigint comment '模板2', template_id_two bigint comment '模板2',
template_id_three bigint comment '模板3', template_id_three bigint comment '模板3',
template_id_four bigint comment '模板4', template_id_four bigint comment '模板4',
`extra` json NULL COMMENT '扩展字段',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
......
...@@ -21,4 +21,14 @@ public class Constants { ...@@ -21,4 +21,14 @@ public class Constants {
* 不接收货物code编码常量配置 * 不接收货物code编码常量配置
*/ */
public static final String NOT_ACCEPTED_PROD_CODE = "F"; public static final String NOT_ACCEPTED_PROD_CODE = "F";
/**
* 目的仓不选择key
*/
public static final String RECEIVE_ADDR_KEY = "1:1:1";
/**
* 目的仓全选key
*/
public static final String RECEIVE_ADDR_ALL_KEY = "0:0:0";
} }
...@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.order.service.orderCargoControlPick; ...@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.order.service.orderCargoControlPick;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.apollo.core.constants.Constants;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum;
...@@ -1297,7 +1298,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo ...@@ -1297,7 +1298,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
reqDTO.setTemplateParams(templateParams); reqDTO.setTemplateParams(templateParams);
smsMap.put(consigneeCountryCode + consigneePhone, reqDTO); smsMap.put(consigneeCountryCode + consigneePhone, reqDTO);
for (Map.Entry<String, SmsSendSingleToUserReqDTOV2> entry : smsMap.entrySet()) { for (Map.Entry<String, SmsSendSingleToUserReqDTOV2> entry : smsMap.entrySet()) {
smsSendApi.sendSingleSmsToAdminV2(entry.getValue()); smsSendApi.sendSingleSmsToAdminV2(entry.getValue(), Constants.RECEIVE_ADDR_KEY);
} }
} }
......
...@@ -119,6 +119,7 @@ import com.alibaba.fastjson.JSON; ...@@ -119,6 +119,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
...@@ -2367,8 +2368,10 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI ...@@ -2367,8 +2368,10 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
reqDTO.setTransportId(orderDO.getTransportId()); reqDTO.setTransportId(orderDO.getTransportId());
reqDTO.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue()); reqDTO.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue());
reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue()); reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue());
// 发送追加通知短信 // 发送追加通知短信
smsSendApi.sendSingleSmsToAdminV2(reqDTO); smsSendApi.sendSingleSmsToAdminV2(reqDTO,logisticsInfoDto.getDestCountryId()+ Constants.COLON+logisticsInfoDto.getDestCityId()+Constants.COLON
+logisticsInfoDto.getChannelId());
} else { } else {
// 入仓短信 发送给发货人与收货人 // 入仓短信 发送给发货人与收货人
String nodeValue = SmsNodeEnum.WAREHOUSE_IN.getNodeValue(); String nodeValue = SmsNodeEnum.WAREHOUSE_IN.getNodeValue();
...@@ -2424,7 +2427,8 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI ...@@ -2424,7 +2427,8 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
reqDTO.setTransportId(orderDO.getTransportId()); reqDTO.setTransportId(orderDO.getTransportId());
reqDTO.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue()); reqDTO.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue());
reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue()); reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue());
smsSendApi.sendSingleSmsToAdminV2(reqDTO); smsSendApi.sendSingleSmsToAdminV2(reqDTO,logisticsInfoDto.getDestCountryId()+ Constants.COLON+logisticsInfoDto.getDestCityId()+Constants.COLON
+logisticsInfoDto.getChannelId());
} }
} else { } else {
Map<String, Object> consignorParamMap = new HashMap<>(); Map<String, Object> consignorParamMap = new HashMap<>();
...@@ -2471,7 +2475,8 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI ...@@ -2471,7 +2475,8 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
reqDTO.setTransportId(orderDO.getTransportId()); reqDTO.setTransportId(orderDO.getTransportId());
reqDTO.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue()); reqDTO.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue());
reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue()); reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue());
smsSendApi.sendSingleSmsToAdminV2(reqDTO); smsSendApi.sendSingleSmsToAdminV2(reqDTO,logisticsInfoDto.getDestCountryId()+ Constants.COLON+logisticsInfoDto.getDestCityId()+Constants.COLON
+logisticsInfoDto.getChannelId());
// 收货人 短信发送信息 // 收货人 短信发送信息
OrderConsigneeDO orderConsigneeDO = orderConsigneeService.getOne(new LambdaQueryWrapper<OrderConsigneeDO>().eq(OrderConsigneeDO::getOrderId, orderDO.getOrderId()) OrderConsigneeDO orderConsigneeDO = orderConsigneeService.getOne(new LambdaQueryWrapper<OrderConsigneeDO>().eq(OrderConsigneeDO::getOrderId, orderDO.getOrderId())
...@@ -2513,7 +2518,8 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI ...@@ -2513,7 +2518,8 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
reqDTO2.setTransportId(orderDO.getTransportId()); reqDTO2.setTransportId(orderDO.getTransportId());
reqDTO2.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue()); reqDTO2.setIsOrders(SmsIsOrdersEnum.SMS_ORDERS_0.getValue());
reqDTO2.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue()); reqDTO2.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue());
smsSendApi.sendSingleSmsToAdminV2(reqDTO2); smsSendApi.sendSingleSmsToAdminV2(reqDTO2,logisticsInfoDto.getDestCountryId()+ Constants.COLON+logisticsInfoDto.getDestCityId()+Constants.COLON
+logisticsInfoDto.getChannelId());
} }
} }
} }
......
...@@ -289,7 +289,7 @@ public class ShipmentAirLoadExcelExportListener { ...@@ -289,7 +289,7 @@ public class ShipmentAirLoadExcelExportListener {
}else if (CustomsTypeEnum.CUSTOMS_TYPE_2.getValue().equals(orderInfo.getCustomsType())){ }else if (CustomsTypeEnum.CUSTOMS_TYPE_2.getValue().equals(orderInfo.getCustomsType())){
Integer color = Integer.valueOf(IndexedColors.ORANGE.index); Integer color = Integer.valueOf(IndexedColors.ORANGE.index);
if (prodAttrTag){ if (prodAttrTag){
color=Integer.valueOf(IndexedColors.GREEN.index); color=Integer.valueOf(IndexedColors.BRIGHT_GREEN.index);
} }
int andIncrement2 = colorRowNum.get(); int andIncrement2 = colorRowNum.get();
colorMap2.put(String.valueOf(andIncrement2),Integer.valueOf(color)); colorMap2.put(String.valueOf(andIncrement2),Integer.valueOf(color));
......
...@@ -262,7 +262,7 @@ public class ShipmentLoadExcelExportListener2 { ...@@ -262,7 +262,7 @@ public class ShipmentLoadExcelExportListener2 {
}else if (CustomsTypeEnum.CUSTOMS_TYPE_2.getValue().equals(orderInfo.getCustomsType())){ }else if (CustomsTypeEnum.CUSTOMS_TYPE_2.getValue().equals(orderInfo.getCustomsType())){
Integer color = Integer.valueOf(IndexedColors.ORANGE.index); Integer color = Integer.valueOf(IndexedColors.ORANGE.index);
if (prodAttrTag){ if (prodAttrTag){
color=Integer.valueOf(IndexedColors.GREEN.index); color=Integer.valueOf(IndexedColors.BRIGHT_GREEN.index);
} }
int andIncrement2 = colorRowNum.get(); int andIncrement2 = colorRowNum.get();
colorMap2.put(String.valueOf(andIncrement2),Integer.valueOf(color)); colorMap2.put(String.valueOf(andIncrement2),Integer.valueOf(color));
......
...@@ -26,6 +26,7 @@ import cn.iocoder.yudao.module.customer.service.customerContacts.CustomerContact ...@@ -26,6 +26,7 @@ import cn.iocoder.yudao.module.customer.service.customerContacts.CustomerContact
import cn.iocoder.yudao.module.depository.convert.warehouse.WarehouseConvert; import cn.iocoder.yudao.module.depository.convert.warehouse.WarehouseConvert;
import cn.iocoder.yudao.module.depository.dal.dataobject.warehouse.*; import cn.iocoder.yudao.module.depository.dal.dataobject.warehouse.*;
import cn.iocoder.yudao.module.depository.dal.mysql.warehouse.WarehouseLineMapper; import cn.iocoder.yudao.module.depository.dal.mysql.warehouse.WarehouseLineMapper;
import cn.iocoder.yudao.module.depository.dto.LogisticsInfoDto;
import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseAreaPositionService; import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseAreaPositionService;
import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseAreaService; import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseAreaService;
import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseService; import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseService;
...@@ -206,6 +207,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; ...@@ -206,6 +207,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -1622,10 +1624,13 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements ...@@ -1622,10 +1624,13 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
@Override @Override
public void sendSms(Long shipmentId, Collection<Long> orderIdList, SmsNodeEnum smsNodeEnum) { public void sendSms(Long shipmentId, Collection<Long> orderIdList, SmsNodeEnum smsNodeEnum) {
// 对订单列表进行分组, 统计通知发送人的订单数量,当通知人的订单数量大于1,切换模板,合并订单号逗号连接发送一次 // 对订单列表进行分组, 统计通知发送人的订单数量,当通知人的订单数量大于1,切换模板,合并订单号逗号连接发送一次
Map<String, List<Map<String, String>>> sendPhoneMap = new HashMap<>(); Map<String, List<Map<String, String>>> sendPhoneMap = new HashMap<>();
Map<String, Object> templateParams = new HashMap<>(); Map<String, Object> templateParams = new HashMap<>();
List<BoxOrderSmsLogDO> boxOrderSmsLogDOList = new ArrayList<>(); List<BoxOrderSmsLogDO> boxOrderSmsLogDOList = new ArrayList<>();
// 目的仓
LogisticsInfoDto logisticsInfoDto =null;
// 封装需要发送短信的手机号与订单信息 // 封装需要发送短信的手机号与订单信息
for (Long orderId : orderIdList) { for (Long orderId : orderIdList) {
// 判断当前货柜的当前订单是否发送过当前的场景短信 // 判断当前货柜的当前订单是否发送过当前的场景短信
...@@ -1639,6 +1644,9 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements ...@@ -1639,6 +1644,9 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
continue; continue;
} }
OrderBackVO orderBackVO = orderQueryService.getOrder(orderId); OrderBackVO orderBackVO = orderQueryService.getOrder(orderId);
if (logisticsInfoDto == null) {
logisticsInfoDto = warehouseLineMapper.getStartInfoAndDestInfoByLineId(orderBackVO.getLineId());
}
String orderNo = orderBackVO.getOrderNo(); String orderNo = orderBackVO.getOrderNo();
String marks = orderBackVO.getMarks(); String marks = orderBackVO.getMarks();
// 封装货柜订单短信发送记录 // 封装货柜订单短信发送记录
...@@ -1775,8 +1783,10 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements ...@@ -1775,8 +1783,10 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
reqDTO.setTransportId(Integer.valueOf(boxDO.getTransportType())); reqDTO.setTransportId(Integer.valueOf(boxDO.getTransportType()));
reqDTO.setIsOrders(isOrders); reqDTO.setIsOrders(isOrders);
reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue()); reqDTO.setMessageType(SmsMessageTypeEnum.SMS_MESSAGE_TYPE_1.getValue());
//给收发货人发送短信 //给收发货人发送短信
smsSendApi.sendSingleSmsToAdminV2(reqDTO); smsSendApi.sendSingleSmsToAdminV2(reqDTO,logisticsInfoDto.getDestCountryId()+ Constants.COLON+logisticsInfoDto.getDestCityId()+Constants.COLON
+logisticsInfoDto.getChannelId());
// 发送短信后初始化参数值 // 发送短信后初始化参数值
orders = null; orders = null;
marks = null; marks = null;
......
...@@ -30,7 +30,7 @@ public interface SmsSendApi { ...@@ -30,7 +30,7 @@ public interface SmsSendApi {
* @param reqDTO 发送请求 * @param reqDTO 发送请求
* @return 发送日志编号 * @return 发送日志编号
*/ */
Long sendSingleSmsToAdminV2(@Valid SmsSendSingleToUserReqDTOV2 reqDTO); Long sendSingleSmsToAdminV2(@Valid SmsSendSingleToUserReqDTOV2 reqDTO, String receive);
/** /**
* 发送单条短信给 Member 用户 * 发送单条短信给 Member 用户
......
...@@ -27,10 +27,10 @@ public class SmsSendApiImpl implements SmsSendApi { ...@@ -27,10 +27,10 @@ public class SmsSendApiImpl implements SmsSendApi {
} }
@Override @Override
public Long sendSingleSmsToAdminV2(SmsSendSingleToUserReqDTOV2 reqDTO) { public Long sendSingleSmsToAdminV2(SmsSendSingleToUserReqDTOV2 reqDTO, String receive) {
return smsSendService.sendSingleSmsToAdminV2(reqDTO.getMobile(), reqDTO.getUserId(), return smsSendService.sendSingleSmsToAdminV2(reqDTO.getMobile(), reqDTO.getUserId(),
reqDTO.getNodeValue(), reqDTO.getAreaCode(), reqDTO.getIsOrders(), reqDTO.getIsTransport(), reqDTO.getNodeValue(), reqDTO.getAreaCode(), reqDTO.getIsOrders(), reqDTO.getIsTransport(),
reqDTO.getTransportId(), reqDTO.getMessageType(), reqDTO.getTemplateParams()); reqDTO.getTransportId(), reqDTO.getMessageType(), reqDTO.getTemplateParams(),receive);
} }
@Override @Override
......
...@@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.system.convert.sms.SmsNodeConvert; ...@@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.system.convert.sms.SmsNodeConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO; import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO;
import cn.iocoder.yudao.module.system.service.sms.SmsNodeService; import cn.iocoder.yudao.module.system.service.sms.SmsNodeService;
import cn.iocoder.yudao.module.system.service.sms.SmsSendService; import cn.iocoder.yudao.module.system.service.sms.SmsSendService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -86,6 +88,11 @@ public class SmsNodeController { ...@@ -86,6 +88,11 @@ public class SmsNodeController {
} }
convert.setCountryIds(countryIdsInt); convert.setCountryIds(countryIdsInt);
} }
String extra = convert.getExtra();
if (extra != null) {
SmsNodeExtraVO smsNodeExtraVO = JSON.parseObject(extra, SmsNodeExtraVO.class);
convert.setReceiveAddrList(smsNodeExtraVO.getReceiveAddrList());
}
return success(convert); return success(convert);
} }
...@@ -121,9 +128,10 @@ public class SmsNodeController { ...@@ -121,9 +128,10 @@ public class SmsNodeController {
@PostMapping("/test") @PostMapping("/test")
@ApiOperation("测试短信节点") @ApiOperation("测试短信节点")
public CommonResult<Boolean> test(@Valid @RequestBody SmsNodeTestVO smsNodeTestVO) { public CommonResult<Boolean> test(@Valid @RequestBody SmsNodeTestVO smsNodeTestVO) {
List<Long> longs = smsNodeTestVO.getReceiveAddrList().get(0);
smsSendService.sendSingleSmsV2(smsNodeTestVO.getMobile(), SecurityFrameworkUtils.getLoginUserId(), UserTypeEnum.ADMIN.getValue(), smsNodeTestVO.getNodeValue(), smsSendService.sendSingleSmsV2(smsNodeTestVO.getMobile(), SecurityFrameworkUtils.getLoginUserId(), UserTypeEnum.ADMIN.getValue(), smsNodeTestVO.getNodeValue(),
smsNodeTestVO.getCountryCode(), smsNodeTestVO.getIsOrders(), smsNodeTestVO.getIsTransport(), smsNodeTestVO.getTransportId(), smsNodeTestVO.getCountryCode(), smsNodeTestVO.getIsOrders(), smsNodeTestVO.getIsTransport(), smsNodeTestVO.getTransportId(),
smsNodeTestVO.getMessageType(), smsNodeTestVO.getTemplateParams(), null, smsNodeTestVO.getNodeTemplateSn(),null); smsNodeTestVO.getMessageType(), smsNodeTestVO.getTemplateParams(), null, smsNodeTestVO.getNodeTemplateSn(), null, longs.get(0) + Constants.COLON + longs.get(1) + Constants.COLON + longs.get(2));
return success(true); return success(true);
} }
} }
...@@ -9,6 +9,7 @@ import lombok.Data; ...@@ -9,6 +9,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
...@@ -78,4 +79,10 @@ public class SmsNodeBackVO { ...@@ -78,4 +79,10 @@ public class SmsNodeBackVO {
@ExcelProperty("多订单") @ExcelProperty("多订单")
@ApiModelProperty(value = "多订单", required = true) @ApiModelProperty(value = "多订单", required = true)
private Integer isOrders; private Integer isOrders;
@ApiModelProperty(value = "扩展字段")
private String extra;
@ApiModelProperty(value = "目的仓(国家,城市,仓库id)")
private List<List<Long>> receiveAddrList;
} }
...@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List;
/** /**
* 短信节点 Base VO,提供给添加、修改、详细的子 VO 使用 * 短信节点 Base VO,提供给添加、修改、详细的子 VO 使用
...@@ -51,4 +52,6 @@ public class SmsNodeBaseVO { ...@@ -51,4 +52,6 @@ public class SmsNodeBaseVO {
@ApiModelProperty(value = "多订单", required = true) @ApiModelProperty(value = "多订单", required = true)
private Integer isOrders; private Integer isOrders;
@ApiModelProperty(value = "目的仓(国家,城市,仓库id)")
private List<List<Long>> receiveAddrList;
} }
package cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode; package cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode;
import lombok.*; import io.swagger.annotations.ApiModel;
import java.util.*; import lombok.Data;
import io.swagger.annotations.*; import lombok.EqualsAndHashCode;
import javax.validation.constraints.*; import lombok.ToString;
@Data @Data
@ToString(callSuper = true) @ToString(callSuper = true)
......
package cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 管理后台 - 短信节点 VO
*
* @author Jayden
* @date 2024/12/11
*/
@Data
@ApiModel("管理后台 - 短信节点 VO")
public class SmsNodeExtraVO {
@ApiModelProperty(value = "目的仓(国家,城市,仓库id)")
private List<List<Long>> receiveAddrList;
}
...@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
...@@ -50,6 +51,9 @@ public class SmsNodeTestVO { ...@@ -50,6 +51,9 @@ public class SmsNodeTestVO {
@NotNull(message = "发送类型不能为空") @NotNull(message = "发送类型不能为空")
private Integer messageType; private Integer messageType;
@ApiModelProperty(value = "目的仓(国家,城市,仓库id)")
private List<List<Long>> receiveAddrList;
@ApiModelProperty(value = "参数") @ApiModelProperty(value = "参数")
private Map<String, Object> templateParams; private Map<String, Object> templateParams;
} }
...@@ -74,5 +74,8 @@ public class SmsNodeDO extends BaseDO { ...@@ -74,5 +74,8 @@ public class SmsNodeDO extends BaseDO {
* 多订单(0:否,1:是) * 多订单(0:否,1:是)
*/ */
private Integer isOrders; private Integer isOrders;
/**
* 扩展字段
*/
private String extra;
} }
package cn.iocoder.yudao.module.system.service.sms; package cn.iocoder.yudao.module.system.service.sms;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.apollo.core.constants.Constants;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
...@@ -41,7 +42,7 @@ public class SmsCodeServiceImpl implements SmsCodeService { ...@@ -41,7 +42,7 @@ public class SmsCodeServiceImpl implements SmsCodeService {
String code = createSmsCode(reqDTO.getMobile(), reqDTO.getNodeValue(), reqDTO.getCreateIp()); String code = createSmsCode(reqDTO.getMobile(), reqDTO.getNodeValue(), reqDTO.getCreateIp());
// 发送验证码 // 发送验证码
smsSendService.sendSingleSmsV2(reqDTO.getAreaCode() + reqDTO.getMobile(), null, null, reqDTO.getNodeValue(), reqDTO.getAreaCode(), reqDTO.getIsOrders(), reqDTO.getIsTransport(), smsSendService.sendSingleSmsV2(reqDTO.getAreaCode() + reqDTO.getMobile(), null, null, reqDTO.getNodeValue(), reqDTO.getAreaCode(), reqDTO.getIsOrders(), reqDTO.getIsTransport(),
reqDTO.getTransportId(), reqDTO.getMessageType(), MapUtil.of("code", code), null, 1,null); reqDTO.getTransportId(), reqDTO.getMessageType(), MapUtil.of("code", code), null, 1,null, Constants.RECEIVE_ADDR_KEY);
} }
private String createSmsCode(String mobile, String nodeValue, String ip) { private String createSmsCode(String mobile, String nodeValue, String ip) {
......
...@@ -78,9 +78,10 @@ public interface SmsNodeService extends IService<SmsNodeDO> { ...@@ -78,9 +78,10 @@ public interface SmsNodeService extends IService<SmsNodeDO> {
* 这是为了确保每个配置项在缓存中都有一个唯一的标识 * 这是为了确保每个配置项在缓存中都有一个唯一的标识
* *
* @param smsNodeDO SmsNodeDO 对象 * @param smsNodeDO SmsNodeDO 对象
* @param receive 目的仓
* @return 缓存键 * @return 缓存键
*/ */
String buildCacheKey(SmsNodeDO smsNodeDO); String buildCacheKey(SmsNodeDO smsNodeDO, String receive);
/** /**
* 短信重发定时任务 * 短信重发定时任务
......
package cn.iocoder.yudao.module.system.service.sms; package cn.iocoder.yudao.module.system.service.sms;
import cn.iocoder.yudao.framework.apollo.core.constants.CacheConstants;
import cn.iocoder.yudao.framework.apollo.core.constants.Constants;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService; import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
...@@ -9,6 +11,7 @@ import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory; ...@@ -9,6 +11,7 @@ import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsLogDTO; import cn.iocoder.yudao.framework.sms.core.client.dto.SmsLogDTO;
import cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum; import cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum;
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeExtraVO;
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeQueryVO; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeQueryVO;
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeUpdateReqVO; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeUpdateReqVO;
import cn.iocoder.yudao.module.system.convert.sms.SmsLogConvert; import cn.iocoder.yudao.module.system.convert.sms.SmsLogConvert;
...@@ -86,19 +89,21 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -86,19 +89,21 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
* 这是为了确保每个配置项在缓存中都有一个唯一的标识 * 这是为了确保每个配置项在缓存中都有一个唯一的标识
* *
* @param smsNodeDO SmsNodeDO 对象 * @param smsNodeDO SmsNodeDO 对象
* @param receive 目的仓
* @return 缓存键 * @return 缓存键
*/ */
@Override @Override
public String buildCacheKey(SmsNodeDO smsNodeDO) { public String buildCacheKey(SmsNodeDO smsNodeDO, String receive) {
// 使用格式化字符串构建缓存键,SYSTEM_SMS_NODE_KEY:短信节点:是否匹配运输方式:运输方式:是否多订单:国家代码:启用状态 // 使用格式化字符串构建缓存键,SYSTEM_SMS_NODE_KEY:短信节点:是否匹配运输方式:运输方式:是否多订单:国家代码:启用状态:目的仓
return String.format("%s%s:%s:%s:%s:%s:%s", return String.format("%s%s:%s:%s:%s:%s:%s:%s",
SYSTEM_SMS_NODE_KEY, SYSTEM_SMS_NODE_KEY,
smsNodeDO.getNodeValue(), smsNodeDO.getNodeValue(),
smsNodeDO.getIsTransport(), smsNodeDO.getIsTransport(),
smsNodeDO.getTransportId(), smsNodeDO.getTransportId(),
smsNodeDO.getIsOrders(), smsNodeDO.getIsOrders(),
smsNodeDO.getCountryCode(), smsNodeDO.getCountryCode(),
smsNodeDO.getStatus()); smsNodeDO.getStatus(),
receive);
} }
/** /**
...@@ -154,10 +159,49 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -154,10 +159,49 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
// 调用短信发送服务重新发送短信 // 调用短信发送服务重新发送短信
smsSendService.sendSingleSmsV2(smsLog.getMobile(), smsLog.getUserId(), smsLog.getUserType(), smsNodeDO.getNodeValue(), smsSendService.sendSingleSmsV2(smsLog.getMobile(), smsLog.getUserId(), smsLog.getUserType(), smsNodeDO.getNodeValue(),
smsNodeDO.getCountryCode(), smsNodeDO.getIsOrders(), smsNodeDO.getIsTransport(), smsNodeDO.getTransportId(), smsNodeDO.getCountryCode(), smsNodeDO.getIsOrders(), smsNodeDO.getIsTransport(), smsNodeDO.getTransportId(),
smsLog.getMessageType(), smsLog.getTemplateParams(), smsLog.getId(), smsLog.getNodeTemplateSn() + 1, smsNodeDO); smsLog.getMessageType(), smsLog.getTemplateParams(), smsLog.getId(), smsLog.getNodeTemplateSn() + 1, smsNodeDO, Constants.RECEIVE_ADDR_KEY);
} }
} }
// 辅助方法:获取目的仓,若为空则初始化目的仓默认值1:1:1
private List<List<Long>> getReceiveAddrList(SmsNodeExtraVO smsNodeExtraVO) {
if (smsNodeExtraVO == null || smsNodeExtraVO.getReceiveAddrList() == null || smsNodeExtraVO.getReceiveAddrList().isEmpty()) {
List<List<Long>> receiveAddrList = new ArrayList<>();
List<Long> longs = new ArrayList<>();
longs.add(1L);
longs.add(1L);
longs.add(1L);
receiveAddrList.add(longs);
return receiveAddrList;
}
return smsNodeExtraVO.getReceiveAddrList();
}
// 辅助方法:获取目的仓,若为空则初始化目的仓默认值1:1:1
private List<List<Long>> getReceiveAddrList(List<List<Long>> receiveAddrList) {
if (receiveAddrList == null || receiveAddrList.isEmpty()) {
List<List<Long>> list = new ArrayList<>();
List<Long> longs = new ArrayList<>();
longs.add(1L);
longs.add(1L);
longs.add(1L);
list.add(longs);
return list;
}
return receiveAddrList;
}
// 辅助方法:生成键 节点国家:目的仓国家:目的仓城市:目的仓仓库
private String generateKey(String countryId, List<Long> integers) {
if (integers.size() < 3) {
throw new IllegalArgumentException("Receive address list must have at least 3 elements");
}
String targetCountry = String.valueOf(integers.get(0));
String targetCity = String.valueOf(integers.get(1));
String receiveAddr = String.valueOf(integers.get(2));
return countryId + CacheConstants.COLON + targetCountry + CacheConstants.COLON + targetCity + CacheConstants.COLON + receiveAddr;
}
/** /**
* 创建短信节点 * 创建短信节点
* <p> * <p>
...@@ -178,20 +222,51 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -178,20 +222,51 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
smsNodeDO.setTransportId(createReqVO.getTransportId()); smsNodeDO.setTransportId(createReqVO.getTransportId());
smsNodeDO.setIsOrders(createReqVO.getIsOrders()); smsNodeDO.setIsOrders(createReqVO.getIsOrders());
List<SmsNodeDO> smsNodeDOList = smsNodeMapper.selectList(smsNodeDO); List<SmsNodeDO> smsNodeDOList = smsNodeMapper.selectList(smsNodeDO);
String country = createReqVO.getCountryId();
if (smsNodeDOList != null && !smsNodeDOList.isEmpty()) { if (smsNodeDOList != null && !smsNodeDOList.isEmpty()) {
Set<String> reqCountryIds = new HashSet<>(Arrays.asList(createReqVO.getCountryId().split(","))); Map<String, Integer> map = new HashMap<>();
for (SmsNodeDO nodeDO : smsNodeDOList) { for (SmsNodeDO nodeDO : smsNodeDOList) {
String countryIds = nodeDO.getCountryId(); String countryIds = nodeDO.getCountryId();
if ("0".equals(countryIds) || reqCountryIds.contains("0")) {
// 如果节点已存在,抛出异常
throw new ServiceException(500, "不能重复添加");
}
Set<String> existingCountryIds = new HashSet<>(Arrays.asList(countryIds.split(","))); Set<String> existingCountryIds = new HashSet<>(Arrays.asList(countryIds.split(",")));
if (!Collections.disjoint(reqCountryIds, existingCountryIds)) { SmsNodeExtraVO smsNodeExtraVO = JSON.parseObject(nodeDO.getExtra(), SmsNodeExtraVO.class);
// 如果节点已存在,抛出异常 // 获取目的仓
throw new ServiceException(500, "不能重复添加"); List<List<Long>> receiveAddrList = getReceiveAddrList(smsNodeExtraVO);
for (List<Long> integers : receiveAddrList) {
for (String existingCountryId : existingCountryIds) {
String countryId = existingCountryId;
String targetCountry = String.valueOf(integers.get(0));
String targetCity = String.valueOf(integers.get(1));
String receiveAddr = String.valueOf(integers.get(2));
String key = countryId + CacheConstants.COLON + targetCountry + CacheConstants.COLON + targetCity + CacheConstants.COLON + receiveAddr;
map.put(key, 0);
if ("0".equals(countryId)) {
// 如果存在全部国家,则判断节点是否为单个国家
if (!"0".equals(country)) {
// 如果节点已存在,抛出异常
throw new ServiceException(500, "不能对单个国家设置");
}
}
}
}
}
Set<String> existingCountryIds = new HashSet<>(Arrays.asList(country.split(",")));
// 获取目的仓
List<List<Long>> receiveAddrList = getReceiveAddrList(createReqVO.getReceiveAddrList());
for (List<Long> integers : receiveAddrList) {
for (String existingCountryId : existingCountryIds) {
String key = generateKey(existingCountryId, integers);
if (map.containsKey(key)) {
// 如果节点已存在,抛出异常
throw new ServiceException(500, "不能重复设置");
}
} }
} }
SmsNodeExtraVO smsNodeExtraVO = new SmsNodeExtraVO();
smsNodeExtraVO.setReceiveAddrList(receiveAddrList);
smsNode.setExtra(JSON.toJSONString(smsNodeExtraVO));
} }
// 插入新的短信节点到数据库 // 插入新的短信节点到数据库
smsNodeMapper.insert(smsNode); smsNodeMapper.insert(smsNode);
...@@ -207,14 +282,24 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -207,14 +282,24 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
public void createCache(SmsNodeDO smsNode) { public void createCache(SmsNodeDO smsNode) {
String[] countryCodesStr = smsNode.getCountryCode().split(","); String[] countryCodesStr = smsNode.getCountryCode().split(",");
Map<String, String> maps = new HashMap<>(); Map<String, String> maps = new HashMap<>();
for (String s : countryCodesStr) { SmsNodeExtraVO smsNodeExtraVO = JSON.parseObject(smsNode.getExtra(), SmsNodeExtraVO.class);
smsNode.setCountryCode(s); // 获取目的仓
// 构建缓存键 List<List<Long>> receiveAddrList = getReceiveAddrList(smsNodeExtraVO);
String key = buildCacheKey(smsNode);
// 将对象转换为JSON字符串作为缓存值 for (List<Long> integers : receiveAddrList) {
String value = JSON.toJSONString(smsNode); for (String s : countryCodesStr) {
maps.put(key, value); smsNode.setCountryCode(s);
// 构建缓存键
String targetCountry = String.valueOf(integers.get(0));
String targetCity = String.valueOf(integers.get(1));
String receiveAddr = String.valueOf(integers.get(2));
String key = buildCacheKey(smsNode, targetCountry + CacheConstants.COLON + targetCity + CacheConstants.COLON + receiveAddr);
// 将对象转换为JSON字符串作为缓存值
String value = JSON.toJSONString(smsNode);
maps.put(key, value);
}
} }
// 将键值对存入Redis缓存 // 将键值对存入Redis缓存
redisHelper.multiSet(maps); redisHelper.multiSet(maps);
redisHelper.set(SYSTEM_SMS_NODE_KEY + smsNode.getId(), JSON.toJSONString(smsNode)); redisHelper.set(SYSTEM_SMS_NODE_KEY + smsNode.getId(), JSON.toJSONString(smsNode));
...@@ -225,12 +310,22 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -225,12 +310,22 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
*/ */
public void deleteCache(SmsNodeDO smsNode) { public void deleteCache(SmsNodeDO smsNode) {
String[] countryCodesStr = smsNode.getCountryCode().split(","); String[] countryCodesStr = smsNode.getCountryCode().split(",");
SmsNodeExtraVO smsNodeExtraVO = JSON.parseObject(smsNode.getExtra(), SmsNodeExtraVO.class);
// 获取目的仓
List<List<Long>> receiveAddrList = getReceiveAddrList(smsNodeExtraVO);
Collection<String> keys = new ArrayList<>(); Collection<String> keys = new ArrayList<>();
for (String s : countryCodesStr) { for (List<Long> integers : receiveAddrList) {
smsNode.setCountryCode(s); for (String s : countryCodesStr) {
// 构建缓存键 smsNode.setCountryCode(s);
String key = buildCacheKey(smsNode); // 构建缓存键
keys.add(key); String targetCountry = String.valueOf(integers.get(0));
String targetCity = String.valueOf(integers.get(1));
String receiveAddr = String.valueOf(integers.get(2));
String key = buildCacheKey(smsNode, targetCountry + CacheConstants.COLON + targetCity + CacheConstants.COLON + receiveAddr);
// 将对象转换为JSON字符串作为缓存值
keys.add(key);
}
} }
// 将键值对存入Redis缓存 // 将键值对存入Redis缓存
redisHelper.delete(keys); redisHelper.delete(keys);
...@@ -260,13 +355,47 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -260,13 +355,47 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
// 检查节点是否重复,如果重复且ID不匹配,则抛出异常 // 检查节点是否重复,如果重复且ID不匹配,则抛出异常
if (smsNodeDOList != null && !smsNodeDOList.isEmpty()) { if (smsNodeDOList != null && !smsNodeDOList.isEmpty()) {
String[] targetCountries = updateObj.getCountryId().split(","); Map<String, SmsNodeDO> map = new HashMap<>();
String country = updateReqVO.getCountryId();
for (SmsNodeDO nodeDO : smsNodeDOList) { for (SmsNodeDO nodeDO : smsNodeDOList) {
String[] existingCountries = nodeDO.getCountryId().split(","); String countryIds = nodeDO.getCountryId();
if (isDuplicateCountry(targetCountries, existingCountries, nodeDO.getId(), updateObj.getId())) { Set<String> existingCountryIds = new HashSet<>(Arrays.asList(countryIds.split(",")));
throw new ServiceException(500, "不能重复添加"); SmsNodeExtraVO smsNodeExtraVO = JSON.parseObject(nodeDO.getExtra(), SmsNodeExtraVO.class);
// 获取目的仓
List<List<Long>> receiveAddrList = getReceiveAddrList(smsNodeExtraVO);
for (List<Long> integers : receiveAddrList) {
for (String existingCountryId : existingCountryIds) {
String key = generateKey(existingCountryId, integers);
map.put(key, nodeDO);
if ("0".equals(existingCountryId)) {
if (!"0".equals(country) && nodeDO.getId() != updateObj.getId()) {
throw new ServiceException(500, "不能对单个国家设置");
}
}
}
}
}
Set<String> existingCountryIds = new HashSet<>(Arrays.asList(country.split(",")));
List<List<Long>> receiveAddrList = updateReqVO.getReceiveAddrList();
for (List<Long> integers : receiveAddrList) {
for (String existingCountryId : existingCountryIds) {
String key = generateKey(existingCountryId, integers);
if (map.containsKey(key)) {
SmsNodeDO nodeDO = map.get(key);
if (nodeDO.getId() != updateObj.getId()) {
// 如果节点已存在,抛出异常
throw new ServiceException(500, "不能重复设置");
}
}
} }
} }
SmsNodeExtraVO smsNodeExtraVO = new SmsNodeExtraVO();
smsNodeExtraVO.setReceiveAddrList(receiveAddrList);
updateObj.setExtra(JSON.toJSONString(smsNodeExtraVO));
} }
// 更新数据库中的短信节点信息 // 更新数据库中的短信节点信息
smsNodeMapper.updateById(updateObj); smsNodeMapper.updateById(updateObj);
...@@ -276,31 +405,6 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO ...@@ -276,31 +405,6 @@ public class SmsNodeServiceImpl extends AbstractService<SmsNodeMapper, SmsNodeDO
createCache(updateObj); createCache(updateObj);
} }
/**
* 检查目标国家和现有国家是否有重复
*
* @param targetCountries 目标国家数组
* @param existingCountries 现有国家数组
* @param existingNodeId 现有节点ID
* @param updateNodeId 更新节点ID
* @return 如果有重复且节点ID不匹配,则返回true,否则返回false
*/
private boolean isDuplicateCountry(String[] targetCountries, String[] existingCountries, Long existingNodeId, Long updateNodeId) {
for (String targetCountry : targetCountries) {
for (String existingCountry : existingCountries) {
// 检查是否有国家代码为"0"的情况,且节点ID不匹配
if (("0".equals(targetCountry) || "0".equals(existingCountry)) && existingNodeId != updateNodeId) {
return true;
}
// 检查国家代码是否匹配,且节点ID不匹配
if (targetCountry.equals(existingCountry) && existingNodeId != updateNodeId) {
return true;
}
}
}
return false;
}
@Override @Override
public void deleteSmsNode(Long id) { public void deleteSmsNode(Long id) {
// 校验存在 // 校验存在
......
...@@ -49,7 +49,7 @@ public interface SmsSendService { ...@@ -49,7 +49,7 @@ public interface SmsSendService {
Long sendSingleSmsToAdminV2(@Mobile @NotEmpty(message = "手机号不能为空") String mobile, Long userId, Long sendSingleSmsToAdminV2(@Mobile @NotEmpty(message = "手机号不能为空") String mobile, Long userId,
@NotNull(message = "业务节点不能为空") String nodeValue, @NotNull(message = "国家区号不能为空") String areaCode, @NotNull(message = "业务节点不能为空") String nodeValue, @NotNull(message = "国家区号不能为空") String areaCode,
@NotNull(message = "是否多订单不能为空") Integer isOrders, @NotNull(message = "是否匹配运输方式不能为空") Integer isTransport, @NotNull(message = "是否多订单不能为空") Integer isOrders, @NotNull(message = "是否匹配运输方式不能为空") Integer isTransport,
@NotNull(message = "运输方式不能空") Integer transportId, @NotNull(message = "发送类型不能为空") Integer messageType, Map<String, Object> templateParams); @NotNull(message = "运输方式不能空") Integer transportId, @NotNull(message = "发送类型不能为空") Integer messageType, Map<String, Object> templateParams, String receive);
/** /**
* 发送单条短信给用户 APP 的用户 * 发送单条短信给用户 APP 的用户
...@@ -82,7 +82,7 @@ public interface SmsSendService { ...@@ -82,7 +82,7 @@ public interface SmsSendService {
Long sendSingleSmsToMemberV2(@Mobile @NotEmpty(message = "手机号不能为空") String mobile, Long userId, Long sendSingleSmsToMemberV2(@Mobile @NotEmpty(message = "手机号不能为空") String mobile, Long userId,
@NotNull(message = "业务节点不能为空") String nodeValue, @NotNull(message = "国家区号不能为空") String areaCode, @NotNull(message = "业务节点不能为空") String nodeValue, @NotNull(message = "国家区号不能为空") String areaCode,
@NotNull(message = "是否多订单不能为空") Integer isOrders, @NotNull(message = "是否匹配运输方式不能为空") Integer isTransport, @NotNull(message = "是否多订单不能为空") Integer isOrders, @NotNull(message = "是否匹配运输方式不能为空") Integer isTransport,
@NotNull(message = "运输方式不能空") Integer transportId, @NotNull(message = "发送类型不能为空") Integer messageType, Map<String, Object> templateParams); @NotNull(message = "运输方式不能空") Integer transportId, @NotNull(message = "发送类型不能为空") Integer messageType, Map<String, Object> templateParams, String receive);
/** /**
* 发送单条短信给用户 * 发送单条短信给用户
...@@ -115,10 +115,12 @@ public interface SmsSendService { ...@@ -115,10 +115,12 @@ public interface SmsSendService {
* @param smsLogId 重发短信时的原短信日志id * @param smsLogId 重发短信时的原短信日志id
* @param nodeTemplateSn 模板序号 * @param nodeTemplateSn 模板序号
* @param smsNode 节点对象 * @param smsNode 节点对象
* @param receive 目的仓
*/ */
Long sendSingleSmsV2(@Mobile @NotEmpty(message = "手机号不能为空") String mobile, Long userId, Integer userType, @NotNull(message = "业务节点不能为空") String nodeValue, Long sendSingleSmsV2(@Mobile @NotEmpty(message = "手机号不能为空") String mobile, Long userId, Integer userType, @NotNull(message = "业务节点不能为空") String nodeValue,
@NotNull(message = "国家区号不能为空") String areaCode, @NotNull(message = "是否多订单不能为空") Integer isOrders, @NotNull(message = "是否匹配运输方式不能为空") Integer isTransport, @NotNull(message = "国家区号不能为空") String areaCode, @NotNull(message = "是否多订单不能为空") Integer isOrders, @NotNull(message = "是否匹配运输方式不能为空") Integer isTransport,
@NotNull(message = "运输方式不能空") Integer transportId, @NotNull(message = "发送类型不能为空") Integer messageType, Map<String, Object> templateParams, Long smsLogId, Integer nodeTemplateSn, SmsNodeDO smsNode); @NotNull(message = "运输方式不能空") Integer transportId, @NotNull(message = "发送类型不能为空") Integer messageType, Map<String, Object> templateParams, Long smsLogId, Integer nodeTemplateSn, SmsNodeDO smsNode,
@NotNull(message = "目的仓不能空") String receive);
void resendSingleSmsBySmsLogIds(Collection<Long> smsLogIds); void resendSingleSmsBySmsLogIds(Collection<Long> smsLogIds);
......
...@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.sms; ...@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.sms;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.apollo.core.constants.Constants;
import cn.iocoder.yudao.framework.common.util.json.core.KeyValue; import cn.iocoder.yudao.framework.common.util.json.core.KeyValue;
import cn.iocoder.yudao.framework.common.util.spring.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.spring.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum;
...@@ -30,6 +31,7 @@ import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer; ...@@ -30,6 +31,7 @@ import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
import cn.iocoder.yudao.module.system.service.user.AdminUserService; import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert; import org.springframework.util.Assert;
...@@ -45,6 +47,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; ...@@ -45,6 +47,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
* *
* @author 捷道源码 * @author 捷道源码
*/ */
@Slf4j
@Service @Service
public class SmsSendServiceImpl implements SmsSendService { public class SmsSendServiceImpl implements SmsSendService {
...@@ -92,7 +95,7 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -92,7 +95,7 @@ public class SmsSendServiceImpl implements SmsSendService {
@Override @Override
public Long sendSingleSmsToAdminV2(String mobile, Long userId, String nodeValue, String areaCode, public Long sendSingleSmsToAdminV2(String mobile, Long userId, String nodeValue, String areaCode,
Integer isOrders, Integer isTransport, Integer transportId, Integer messageType, Map<String, Object> templateParams) { Integer isOrders, Integer isTransport, Integer transportId, Integer messageType, Map<String, Object> templateParams, String receive) {
// 如果 mobile 为空,则加载用户编号对应的手机号 // 如果 mobile 为空,则加载用户编号对应的手机号
if (StrUtil.isEmpty(mobile)) { if (StrUtil.isEmpty(mobile)) {
AdminUserDO user = adminUserService.getUser(userId); AdminUserDO user = adminUserService.getUser(userId);
...@@ -102,7 +105,7 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -102,7 +105,7 @@ public class SmsSendServiceImpl implements SmsSendService {
} }
} }
// 执行发送 // 执行发送
return this.sendSingleSmsV2(areaCode + mobile, userId, UserTypeEnum.ADMIN.getValue(), nodeValue, areaCode, isOrders, isTransport, transportId, messageType, templateParams, null, 1, null); return this.sendSingleSmsV2(areaCode + mobile, userId, UserTypeEnum.ADMIN.getValue(), nodeValue, areaCode, isOrders, isTransport, transportId, messageType, templateParams, null, 1, null, receive);
} }
@Override @Override
...@@ -121,7 +124,7 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -121,7 +124,7 @@ public class SmsSendServiceImpl implements SmsSendService {
@Override @Override
public Long sendSingleSmsToMemberV2(String mobile, Long userId, String nodeValue, String areaCode, public Long sendSingleSmsToMemberV2(String mobile, Long userId, String nodeValue, String areaCode,
Integer isOrders, Integer isTransport, Integer transportId, Integer messageType, Map<String, Object> templateParams) { Integer isOrders, Integer isTransport, Integer transportId, Integer messageType, Map<String, Object> templateParams, String receive) {
// 如果 mobile 为空,则加载用户编号对应的手机号 // 如果 mobile 为空,则加载用户编号对应的手机号
if (StrUtil.isEmpty(mobile)) { if (StrUtil.isEmpty(mobile)) {
UserRespDTO user = memberUserApi.getUser(userId); UserRespDTO user = memberUserApi.getUser(userId);
...@@ -131,7 +134,7 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -131,7 +134,7 @@ public class SmsSendServiceImpl implements SmsSendService {
} }
} }
// 执行发送 // 执行发送
return this.sendSingleSmsV2(areaCode + mobile, userId, UserTypeEnum.MEMBER.getValue(), nodeValue, areaCode, isOrders, isTransport, transportId, messageType, templateParams, null, 1, null); return this.sendSingleSmsV2(areaCode + mobile, userId, UserTypeEnum.MEMBER.getValue(), nodeValue, areaCode, isOrders, isTransport, transportId, messageType, templateParams, null, 1, null, receive);
} }
@Override @Override
...@@ -315,10 +318,11 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -315,10 +318,11 @@ public class SmsSendServiceImpl implements SmsSendService {
* @param smsLogId 重发短信时的原短信日志id * @param smsLogId 重发短信时的原短信日志id
* @param nodeTemplateSn 模板序号 * @param nodeTemplateSn 模板序号
* @param smsNode 节点对象 * @param smsNode 节点对象
* @param receive 目的仓
*/ */
@Override @Override
public Long sendSingleSmsV2(String mobile, Long userId, Integer userType, String nodeValue, String areaCode, public Long sendSingleSmsV2(String mobile, Long userId, Integer userType, String nodeValue, String areaCode,
Integer isOrders, Integer isTransport, Integer transportId, Integer messageType, Map<String, Object> templateParams, Long smsLogId, Integer nodeTemplateSn, SmsNodeDO smsNode) { Integer isOrders, Integer isTransport, Integer transportId, Integer messageType, Map<String, Object> templateParams, Long smsLogId, Integer nodeTemplateSn, SmsNodeDO smsNode, String receive) {
//首次发送 //首次发送
if (smsNode == null) { if (smsNode == null) {
// 创建SmsNodeDO对象并设置相关属性 // 创建SmsNodeDO对象并设置相关属性
...@@ -329,30 +333,12 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -329,30 +333,12 @@ public class SmsSendServiceImpl implements SmsSendService {
.setIsOrders(isOrders) .setIsOrders(isOrders)
.setCountryCode(areaCode) .setCountryCode(areaCode)
.setStatus(SystemStatusEnum.SYSTEM_STATUS_0.getValue()); .setStatus(SystemStatusEnum.SYSTEM_STATUS_0.getValue());
// 构建缓存键,用于查询短信节点缓存
String cacheKey = smsNodeService.buildCacheKey(smsNodeDO);
String smsNodeCache = redisHelper.get(cacheKey);
// 第一次找不到,则在全部国家里面找
if (smsNodeCache == null) {
smsNodeDO.setCountryCode(SmsCountryCodeEnum.SMS_COUNTRY_CODE_0.getValue());
cacheKey = smsNodeService.buildCacheKey(smsNodeDO);
smsNodeCache = redisHelper.get(cacheKey);
// 第二次找不到,则在其他国家里面找
if (smsNodeCache == null) {
smsNodeDO.setCountryCode(SmsCountryCodeEnum.SMS_COUNTRY_CODE_1.getValue());
cacheKey = smsNodeService.buildCacheKey(smsNodeDO);
smsNodeCache = redisHelper.get(cacheKey);
}
}
// 如果 still null, throw exception // 尝试从缓存中获取短信节点信息
if (smsNodeCache == null) { smsNode = getSmsNodeFromCache(smsNodeDO, receive);
throw exception(SMS_SEND_TEMPLATE_NOT_EXISTS); if (smsNode == null) {
throw exception(SMS_NODE_NOT_EXISTS);
} }
// 解析缓存获取短信节点信息
smsNode = JSON.parseObject(smsNodeCache, SmsNodeDO.class);
} }
String smsTemplateDO = null; String smsTemplateDO = null;
...@@ -371,7 +357,7 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -371,7 +357,7 @@ public class SmsSendServiceImpl implements SmsSendService {
} }
if (smsTemplateDO == null) { if (smsTemplateDO == null) {
// throw exception(SMS_SEND_TEMPLATE_NOT_EXISTS); log.error(SMS_SEND_TEMPLATE_NOT_EXISTS.getMsg());
return null; return null;
} }
...@@ -407,6 +393,49 @@ public class SmsSendServiceImpl implements SmsSendService { ...@@ -407,6 +393,49 @@ public class SmsSendServiceImpl implements SmsSendService {
return sendLogId; return sendLogId;
} }
/**
* 获取缓存节点
*/
private SmsNodeDO getSmsNodeFromCache(SmsNodeDO smsNodeDO, String receive) {
// 构建缓存键,用于查询短信节点缓存
String cacheKey = smsNodeService.buildCacheKey(smsNodeDO, receive);
String smsNodeCache = redisHelper.get(cacheKey);
// 第一次找不到,则在全部目的仓里面找
if (smsNodeCache == null) {
cacheKey = smsNodeService.buildCacheKey(smsNodeDO, Constants.RECEIVE_ADDR_ALL_KEY);
smsNodeCache = redisHelper.get(cacheKey);
}
// 第二次找不到,则在全部国家里面找
if (smsNodeCache == null) {
smsNodeDO.setCountryCode(SmsCountryCodeEnum.SMS_COUNTRY_CODE_0.getValue());
cacheKey = smsNodeService.buildCacheKey(smsNodeDO, receive);
smsNodeCache = redisHelper.get(cacheKey);
}
// 第三次找不到,则在全部国家、全部目的仓里面找
if (smsNodeCache == null) {
cacheKey = smsNodeService.buildCacheKey(smsNodeDO, Constants.RECEIVE_ADDR_ALL_KEY);
smsNodeCache = redisHelper.get(cacheKey);
}
// 第四次找不到,则在其他国家里面找
if (smsNodeCache == null) {
smsNodeDO.setCountryCode(SmsCountryCodeEnum.SMS_COUNTRY_CODE_1.getValue());
cacheKey = smsNodeService.buildCacheKey(smsNodeDO, receive);
smsNodeCache = redisHelper.get(cacheKey);
}
// 第五次次找不到,则在其他国家、全部目的仓里面找
if (smsNodeCache == null) {
cacheKey = smsNodeService.buildCacheKey(smsNodeDO, Constants.RECEIVE_ADDR_ALL_KEY);
smsNodeCache = redisHelper.get(cacheKey);
}
return smsNodeCache != null ? JSON.parseObject(smsNodeCache, SmsNodeDO.class) : null;
}
/** /**
* 根据节点模板序号获取模板ID * 根据节点模板序号获取模板ID
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment