| @@ -0,0 +1,10 @@ | |||||
| drop table if exists `wx_msg_limit`; | |||||
| CREATE TABLE `wx_msg_limit` ( | |||||
| `id` bigint(20) NOT NULL COMMENT '主键ID', | |||||
| `tenant_id` varchar(10) NOT NULL COMMENT '租户id', | |||||
| `type` tinyint(1) DEFAULT '0' COMMENT '1: 短信-验证码(24小时10条)2:短信-营销(24小时3条) 10:prepay_id(7天内3次), 12:form_id(7天内1次), 13.open_id for 小程序统一消息限制(2天内1次),14.open_id for 公众号模板消息限制(2天内1次)', | |||||
| `limit_id` varchar(64) DEFAULT NULL COMMENT '限制ID', | |||||
| `limit_num` smallint(2) DEFAULT '0' COMMENT '限制次数', | |||||
| `limit_date` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '限制时间' | |||||
| PRIMARY KEY (`id`) | |||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |||||
| @@ -0,0 +1,107 @@ | |||||
| package com.iformall.domain.po; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import lombok.ToString; | |||||
| import javax.persistence.Id; | |||||
| import javax.persistence.Table; | |||||
| import javax.persistence.Transient; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| @Table(name = "wx_msg_limit") | |||||
| @Data | |||||
| @ToString(callSuper = true) | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| public class WxMsgLimit extends BaseEntity { | |||||
| @Id | |||||
| protected Long id; | |||||
| @Transient | |||||
| protected List<Long> ids; | |||||
| @Transient | |||||
| protected String sortColumns; | |||||
| @Override | |||||
| public String getSortColumns() { | |||||
| super.setSortColumns(this.sortColumns); | |||||
| return super.getSortColumns(); | |||||
| } | |||||
| @io.swagger.annotations.ApiModelProperty(value="租户ID",name="tenantId") | |||||
| private String tenantId; | |||||
| @io.swagger.annotations.ApiModelProperty(value="1: 短信-验证码(24小时10条)2:短信-营销(24小时3条) 11:prepay_id(7天内3次), 12:form_id(7天内1次), 13.open_id for 小程序统一消息限制(2天内1次),14.open_id for 公众号模板消息限制(2天内1次)",name="type") | |||||
| private Integer type; | |||||
| @io.swagger.annotations.ApiModelProperty(value="限制ID",name="limitId") | |||||
| private String limitId; | |||||
| @io.swagger.annotations.ApiModelProperty(value="限制次数",name="limitNum") | |||||
| private Integer limitNum; | |||||
| @io.swagger.annotations.ApiModelProperty(value="限制时间(type=1,2时,24小时; tyep=11,12,13时,为自然日结束时间)",name="limitDate") | |||||
| private Date limitDate; | |||||
| @Transient | |||||
| @io.swagger.annotations.ApiModelProperty(value="过期时间(一般为当前时间)",name="expireDate") | |||||
| private Date expireDate; | |||||
| public static enum Field | |||||
| { | |||||
| Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | |||||
| ,TenantId_ASC("`tenant_id` ASC"),TenantId_DESC("`tenant_id` DESC") | |||||
| ,Type_ASC("`type` ASC"),Name_DESC("`type` DESC") | |||||
| ,LimitId_ASC("`limit_id` ASC"),LimitId_DESC("`limit_id` DESC") | |||||
| ,LimitDate_ASC("`limit_date` ASC"),LimitDate_DESC("`limit_date` DESC") | |||||
| ; | |||||
| private String value; | |||||
| Field(String value){ | |||||
| this.value = value; | |||||
| } | |||||
| public String getValue() { | |||||
| return value; | |||||
| } | |||||
| public void setCol(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return this.getValue(); | |||||
| } | |||||
| } | |||||
| public void setSortColumns(WxMsgLimit.Field... fields) | |||||
| { | |||||
| if (fields == null || fields.length == 0) { | |||||
| return; | |||||
| } | |||||
| for (int k = 0; k < fields.length; k++) { | |||||
| if (fields[k] == null) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| StringBuilder sb = new StringBuilder(fields[0].toString()); | |||||
| for (int k = 1; k < fields.length; k++) { | |||||
| sb.append(","); | |||||
| sb.append(fields[k].toString()); | |||||
| } | |||||
| this.sortColumns = sb.toString(); | |||||
| } | |||||
| public void setSortColumns(String sortColumns) | |||||
| { | |||||
| if (sortColumns == null || "".equals(sortColumns.trim())) { | |||||
| return; | |||||
| } | |||||
| if (sortColumns.contains(",")) { | |||||
| String[] cols = sortColumns.split(","); | |||||
| List<Field> fList = new java.util.ArrayList(); | |||||
| for (int k = 0; k < cols.length; k++) { | |||||
| fList.add(Field.valueOf(cols[k])); | |||||
| } | |||||
| this.setSortColumns(fList.toArray(new Field[fList.size()])); | |||||
| } else { | |||||
| this.setSortColumns(Field.valueOf(sortColumns)); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package com.iformall.enums; | |||||
| /** | |||||
| * Created by Stormeye | |||||
| * 消息限制类型 | |||||
| */ | |||||
| public enum EnumMsgLimitType { | |||||
| // type,name | |||||
| SMS_VALID(1, "短信-验证码"), | |||||
| SMS_SALE(2, "短信-营销"), | |||||
| WEAPP_PREPAYID(11, "小程序prepayId"), | |||||
| WEAPP_FORMID(12, "小程序formId"), | |||||
| WEAPP_OPENID(13, "小程序openId"), | |||||
| WXCHAT_OPENID(14, "公众号openId") | |||||
| ; | |||||
| public static EnumMsgLimitType getEnum(Integer code) { | |||||
| for (EnumMsgLimitType value : values()) { | |||||
| if (value.getCode().equals(code)) { | |||||
| return value; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private Integer code; | |||||
| private String message; | |||||
| EnumMsgLimitType(Integer code, String message) { | |||||
| this.code = code; | |||||
| this.message = message; | |||||
| } | |||||
| public Integer getCode() { | |||||
| return code; | |||||
| } | |||||
| public String getMessage() { | |||||
| return message; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| package com.iformall.mapper; | |||||
| import com.iformall.common.CommonMapper; | |||||
| import com.iformall.domain.po.WxMsgLimit; | |||||
| import java.util.List; | |||||
| public interface WxMsgLimitMapper extends CommonMapper<WxMsgLimit, String> { | |||||
| List<WxMsgLimit> findList(WxMsgLimit wxMsgWxLimit); | |||||
| int updateLimitNum(WxMsgLimit wxMsgWxLimit); | |||||
| int delLimitNum(WxMsgLimit wxMsgWxLimit); | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package com.iformall.service; | |||||
| import com.iformall.domain.po.WxMsgLimit; | |||||
| import java.util.List; | |||||
| public interface WxMsgLimitService { | |||||
| List<WxMsgLimit> findList(WxMsgLimit record); | |||||
| void add(WxMsgLimit record); | |||||
| int updateLimit(WxMsgLimit record); | |||||
| boolean checkIsLimit(WxMsgLimit record); | |||||
| } | |||||
| @@ -113,6 +113,9 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||||
| @Autowired | @Autowired | ||||
| WxScoreRulesService wxScoreRulesService; | WxScoreRulesService wxScoreRulesService; | ||||
| @Autowired | |||||
| WxMsgLimitService wxMsgLimitService; | |||||
| @Override | @Override | ||||
| public PageInfo<WxCouponOrder> listAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxCouponOrder> listAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize) { | ||||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponOrderMapper.findList(record)); | return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponOrderMapper.findList(record)); | ||||
| @@ -624,7 +627,8 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||||
| } | } | ||||
| // 6. get payOrder info | // 6. get payOrder info | ||||
| if(StringUtils.isBlank(order.getFormId())) { | |||||
| int formType = EnumMsgLimitType.WEAPP_FORMID.getCode(); | |||||
| if(StringUtils.isBlank(order.getFormId()) || order.getFormId().equalsIgnoreCase("undefined")) { | |||||
| // formId为空,获取prepayId | // formId为空,获取prepayId | ||||
| WxPayOrder payOrder = null; | WxPayOrder payOrder = null; | ||||
| WxPayOrder payOrderQ = new WxPayOrder(); | WxPayOrder payOrderQ = new WxPayOrder(); | ||||
| @@ -644,14 +648,27 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||||
| throw new MallinkException(ErrorCode.PREPAY_ID_IS_EMPTY); | throw new MallinkException(ErrorCode.PREPAY_ID_IS_EMPTY); | ||||
| } | } | ||||
| formId = payOrder.getPrepayId(); | formId = payOrder.getPrepayId(); | ||||
| formType = EnumMsgLimitType.WEAPP_PREPAYID.getCode(); | |||||
| } | } | ||||
| if(StringUtils.isBlank(formId)) { | if(StringUtils.isBlank(formId)) { | ||||
| logger.error("formId为空"); | logger.error("formId为空"); | ||||
| throw new MallinkException(ErrorCode.TEMPLATE_FORMID_NOT_FOUND); | |||||
| return; | |||||
| } | } | ||||
| // 9. 微信小程序-模板消息 | // 9. 微信小程序-模板消息 | ||||
| /** | |||||
| * 检查 小程序模板消息是否超限 | |||||
| */ | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(user.getTenantId()); | |||||
| msgLimit.setType(formType); | |||||
| msgLimit.setLimitId(formId); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| // 已达到限制条件,不发消息了 | |||||
| logger.error("已达到限制条件,不发小程序模板消息了: " + user.getId()); | |||||
| return; | |||||
| } | |||||
| SmartAppMsg smartAppMsg; | SmartAppMsg smartAppMsg; | ||||
| if (bUsed) { | if (bUsed) { | ||||
| //mq发送小程序消息 - 核销成功消息 | //mq发送小程序消息 - 核销成功消息 | ||||
| @@ -665,6 +682,19 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||||
| } | } | ||||
| private void doVerifyMpMsg(WxCouponOrder couponOrder, WxCoupon coupon, WxMerchant merchant, WxCUser user, SimpleDateFormat dateFormat, String gotopage) { | private void doVerifyMpMsg(WxCouponOrder couponOrder, WxCoupon coupon, WxMerchant merchant, WxCUser user, SimpleDateFormat dateFormat, String gotopage) { | ||||
| /** | |||||
| * 检查 公众号消息是否超限 | |||||
| */ | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(user.getTenantId()); | |||||
| msgLimit.setType(EnumMsgLimitType.WXCHAT_OPENID.getCode()); | |||||
| msgLimit.setLimitId(user.getMpOpenId()); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| // 已达到限制条件,不发消息了 | |||||
| logger.info("已达到限制条件,不发公众号模板消息了: " + user.getId()); | |||||
| return; | |||||
| } | |||||
| /** | /** | ||||
| * 卡券核销通知 | * 卡券核销通知 | ||||
| * {{first.DATA}} | * {{first.DATA}} | ||||
| @@ -698,6 +728,19 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||||
| } | } | ||||
| private void doVerifyAppUniformMsg(WxCouponOrder couponOrder, WxCoupon coupon, WxMerchant merchant, WxCUser user, SimpleDateFormat dateFormat, String gotopage) { | private void doVerifyAppUniformMsg(WxCouponOrder couponOrder, WxCoupon coupon, WxMerchant merchant, WxCUser user, SimpleDateFormat dateFormat, String gotopage) { | ||||
| /** | |||||
| * 检查 小程序统一消息是否超限 | |||||
| */ | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(user.getTenantId()); | |||||
| msgLimit.setType(EnumMsgLimitType.WEAPP_OPENID.getCode()); | |||||
| msgLimit.setLimitId(user.getOpenId()); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| // 已达到限制条件,不发消息了 | |||||
| logger.info("已达到限制条件,不发小程序统一消息了: " + user.getId()); | |||||
| return; | |||||
| } | |||||
| WxAuthorizerInfo authQ = new WxAuthorizerInfo(); | WxAuthorizerInfo authQ = new WxAuthorizerInfo(); | ||||
| authQ.setAuthorizerAppid(user.getAppId()); | authQ.setAuthorizerAppid(user.getAppId()); | ||||
| authQ.setTenantId(user.getTenantId()); | authQ.setTenantId(user.getTenantId()); | ||||
| @@ -765,6 +808,7 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||||
| } | } | ||||
| private void doVerifyFailMsg(WxCouponOrder couponOrder, String formId, WxCoupon coupon, WxCUser user, SimpleDateFormat dateFormat, String couponDetail, String gotopage) { | private void doVerifyFailMsg(WxCouponOrder couponOrder, String formId, WxCoupon coupon, WxCUser user, SimpleDateFormat dateFormat, String couponDetail, String gotopage) { | ||||
| SmartAppMsg smartAppMsg; /** | SmartAppMsg smartAppMsg; /** | ||||
| * 核销失败消息 | * 核销失败消息 | ||||
| * 商品名称 {{keyword1.DATA}} | * 商品名称 {{keyword1.DATA}} | ||||
| @@ -63,6 +63,8 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| WxAppinfoService wxAppinfoService; | WxAppinfoService wxAppinfoService; | ||||
| @Autowired | @Autowired | ||||
| WxAuthorizerInfoMapper authorizerInfoMapper; | WxAuthorizerInfoMapper authorizerInfoMapper; | ||||
| @Autowired | |||||
| WxMsgLimitService wxMsgLimitService; | |||||
| @Override | @Override | ||||
| public PageInfo<WxCouponSendVo> listAsPage(WxCouponSend record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxCouponSendVo> listAsPage(WxCouponSend record, Integer pageIndex, Integer pageSize) { | ||||
| @@ -269,6 +271,16 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| if(StringUtils.isNotBlank(user.getMpAppId()) && | if(StringUtils.isNotBlank(user.getMpAppId()) && | ||||
| StringUtils.isNotBlank(user.getMpOpenId()) && | StringUtils.isNotBlank(user.getMpOpenId()) && | ||||
| user.getMpSubscribe().equals(EnumUserIsSubscribe.YES.getCode())) { | user.getMpSubscribe().equals(EnumUserIsSubscribe.YES.getCode())) { | ||||
| // 检查是否超限 | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(user.getTenantId()); | |||||
| msgLimit.setType(EnumMsgLimitType.WXCHAT_OPENID.getCode()); | |||||
| msgLimit.setLimitId(user.getMpOpenId()); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| logger.error("用户公众号模板消息超限" + user.getId()); | |||||
| return; | |||||
| } | |||||
| // 已关注公众号 | // 已关注公众号 | ||||
| /** | /** | ||||
| * 购票成功通知 | * 购票成功通知 | ||||
| @@ -308,6 +320,15 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| } else { | } else { | ||||
| // 可能未关注公众号, 用户可能收不到 | // 可能未关注公众号, 用户可能收不到 | ||||
| // 8. 微信小程序-统一消息 | // 8. 微信小程序-统一消息 | ||||
| // 检查是否超限 | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(user.getTenantId()); | |||||
| msgLimit.setType(EnumMsgLimitType.WEAPP_OPENID.getCode()); | |||||
| msgLimit.setLimitId(user.getOpenId()); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| logger.error("用户小程序统一模板消息超限:" + user.getId()); | |||||
| return; | |||||
| } | |||||
| // 获取小程序关联的服务号 | // 获取小程序关联的服务号 | ||||
| WxAuthorizerInfo authQ = new WxAuthorizerInfo(); | WxAuthorizerInfo authQ = new WxAuthorizerInfo(); | ||||
| authQ.setAuthorizerAppid(user.getAppId()); | authQ.setAuthorizerAppid(user.getAppId()); | ||||
| @@ -347,6 +368,7 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| String title = send.getTitle(); | String title = send.getTitle(); | ||||
| //找出用户手机号 | //找出用户手机号 | ||||
| String phone = user.getPhone(); | String phone = user.getPhone(); | ||||
| //小程序名称 | //小程序名称 | ||||
| WxAppinfo appInfo = wxAppinfoService.getCAppInfo(tenantId); | WxAppinfo appInfo = wxAppinfoService.getCAppInfo(tenantId); | ||||
| String appName = appInfo.getName(); | String appName = appInfo.getName(); | ||||
| @@ -85,8 +85,6 @@ public class WxFlowServiceImpl implements WxFlowService { | |||||
| private WxCouponMapper wxCouponMapper; | private WxCouponMapper wxCouponMapper; | ||||
| @Autowired | @Autowired | ||||
| private WxCouponService wxCouponService; | private WxCouponService wxCouponService; | ||||
| @Autowired | |||||
| private WxCouponChannelService wxCouponChannelService; | |||||
| /** | /** | ||||
| * 获取流程key | * 获取流程key | ||||
| @@ -1036,25 +1034,25 @@ public class WxFlowServiceImpl implements WxFlowService { | |||||
| wxFlowRecordMapper.updateCurrStatus(new WxFlowRecord(processInstanceId,EnumRentContractAppStatus.REJECT.getCode())); | wxFlowRecordMapper.updateCurrStatus(new WxFlowRecord(processInstanceId,EnumRentContractAppStatus.REJECT.getCode())); | ||||
| //给发起人发送驳回消息 | //给发起人发送驳回消息 | ||||
| Map<String,String> msgReplaceMap = new HashedMap(); | |||||
| msgReplaceMap.put("contract",(String)getVariableByKey(variables,"contractNumber")); | |||||
| msgReplaceMap.put("page",Constant.adminPage); | |||||
| WxMsgRecord wxMsgRecord = new WxMsgRecord(); | |||||
| wxMsgRecord.setMsgType(EnumMsgRecordType.SMS.getCode()); | |||||
| wxMsgRecord.setModelType(EnumMsgModel.FLOW_REJECT_NODIFY.getCode()); | |||||
| wxMsgRecord.setReceiver(userMap!=null?(String)userMap.get("phone"):""); | |||||
| wxMsgRecord.setTenantId(tenantId); | |||||
| if(isContract(flowType)){ | |||||
| msgReplaceMap.put("bustype","合同"); | |||||
| }else if(isBill(flowType)){ | |||||
| msgReplaceMap.put("bustype","账单"); | |||||
| msgReplaceMap.put("contract", businessId.toString()); | |||||
| }else if(isCoupon(flowType)){ | |||||
| msgReplaceMap.put("bustype","有价卷"); | |||||
| msgReplaceMap.put("contract",businessId.toString()); | |||||
| Map<String, String> msgReplaceMap = new HashedMap(); | |||||
| String phone = userMap!=null?(String)userMap.get("phone"):""; | |||||
| if(phone.length() > 0) { | |||||
| msgReplaceMap.put("contract", (String) getVariableByKey(variables, "contractNumber")); | |||||
| msgReplaceMap.put("page", Constant.adminPage); | |||||
| WxMsgRecord wxMsgRecord = new WxMsgRecord(); | |||||
| wxMsgRecord.setMsgType(EnumMsgRecordType.SMS.getCode()); | |||||
| wxMsgRecord.setModelType(EnumMsgModel.FLOW_REJECT_NODIFY.getCode()); | |||||
| wxMsgRecord.setReceiver(userMap != null ? (String) userMap.get("phone") : ""); | |||||
| wxMsgRecord.setTenantId(tenantId); | |||||
| if (isContract(flowType)) { | |||||
| msgReplaceMap.put("bustype", "合同"); | |||||
| } else if (isBill(flowType)) { | |||||
| msgReplaceMap.put("bustype", "账单"); | |||||
| msgReplaceMap.put("contract", businessId.toString()); | |||||
| } | |||||
| wxMsgRecord.setDynamicContentMap(msgReplaceMap); | |||||
| mqBaseProducer.sendMessage(wxMsgRecord, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); | |||||
| } | } | ||||
| wxMsgRecord.setDynamicContentMap(msgReplaceMap); | |||||
| mqBaseProducer.sendMessage(wxMsgRecord, EnumMsgMqTopic.DEFAULT.getCode(),EnumMsgMqTag.DEFAULT.getCode(),EnumMsgMqKey.DEFAULT.getCode()); | |||||
| //发送邮件 | //发送邮件 | ||||
| if(StringUtils.isNotBlank(email)) { | if(StringUtils.isNotBlank(email)) { | ||||
| @@ -0,0 +1,122 @@ | |||||
| package com.iformall.service.impl; | |||||
| import com.iformall.common.IdWorker; | |||||
| import com.iformall.domain.po.WxMsgLimit; | |||||
| import com.iformall.enums.EnumMsgLimitType; | |||||
| import com.iformall.mapper.WxMsgLimitMapper; | |||||
| import com.iformall.service.WxMsgLimitService; | |||||
| import com.iformall.utils.DateUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author luozukai | |||||
| * 消息发送限制检查 | |||||
| */ | |||||
| @Service | |||||
| public class WxMsgLimitServiceImpl implements WxMsgLimitService { | |||||
| @Autowired | |||||
| private WxMsgLimitMapper wxMsgLimitMapper; | |||||
| @Override | |||||
| public List<WxMsgLimit> findList(WxMsgLimit record) { | |||||
| return wxMsgLimitMapper.findList(record); | |||||
| } | |||||
| @Override | |||||
| public void add(WxMsgLimit record){ | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| // 删除老的, 手机, openId会出现旧数据,删掉 | |||||
| if(record.getType().equals(EnumMsgLimitType.SMS_VALID.getCode()) || | |||||
| record.getType().equals(EnumMsgLimitType.SMS_SALE.getCode()) || | |||||
| record.getType().equals(EnumMsgLimitType.WXCHAT_OPENID.getCode()) | |||||
| ){ | |||||
| wxMsgLimitMapper.delLimitNum(record); | |||||
| } | |||||
| // 新增,根据类型获取限制条数 | |||||
| setLimitNum(record); | |||||
| // 保存 | |||||
| wxMsgLimitMapper.insertSelective(record); | |||||
| } | |||||
| private WxMsgLimit setLimitNum(WxMsgLimit record) { | |||||
| Date curDate = new Date(); | |||||
| if(record.getType().equals(EnumMsgLimitType.SMS_VALID.getCode())) { | |||||
| // 短信 - 验证码, 24小时内10条 | |||||
| record.setLimitNum(10); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(1, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } else if(record.getType().equals(EnumMsgLimitType.SMS_SALE.getCode())) { | |||||
| // 短信 - 营销, 24小时内3条 | |||||
| record.setLimitNum(3); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(1, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } else if(record.getType().equals(EnumMsgLimitType.WEAPP_PREPAYID.getCode())) { | |||||
| // 小程序prepayId, 7天内3条 | |||||
| record.setLimitNum(3); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(7, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } else if(record.getType().equals(EnumMsgLimitType.WEAPP_FORMID.getCode())) { | |||||
| // 小程序formId, 7天内1条 | |||||
| record.setLimitNum(1); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(7, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } else if(record.getType().equals(EnumMsgLimitType.WEAPP_OPENID.getCode())) { | |||||
| // 小程序openId, 2天内1条 | |||||
| record.setLimitNum(1); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(2, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } else if(record.getType().equals(EnumMsgLimitType.WXCHAT_OPENID.getCode())) { | |||||
| // 公众号openId, 2天内1条 | |||||
| record.setLimitNum(1); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(2, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } else { | |||||
| // 未知的,暂定1天内1条 | |||||
| record.setLimitNum(1); | |||||
| Date limitDate = DateUtils.getTimeAfterDays(1, curDate); | |||||
| record.setLimitDate(limitDate); | |||||
| } | |||||
| return record; | |||||
| } | |||||
| @Override | |||||
| public int updateLimit(WxMsgLimit record) { | |||||
| int ret = wxMsgLimitMapper.updateLimitNum(record); | |||||
| return ret; | |||||
| } | |||||
| @Override | |||||
| public boolean checkIsLimit(WxMsgLimit record) { | |||||
| if(record.getExpireDate() == null) { | |||||
| record.setExpireDate(new Date()); | |||||
| } | |||||
| record.setSortColumns(WxMsgLimit.Field.LimitDate_DESC, WxMsgLimit.Field.Id_DESC); | |||||
| List<WxMsgLimit> list = wxMsgLimitMapper.findList(record); | |||||
| if(list.size() > 0) { | |||||
| // 已有限制条件 | |||||
| WxMsgLimit msgLimit = list.get(0); | |||||
| if(msgLimit.getLimitNum() > 0) { | |||||
| int ret = updateLimit(msgLimit); | |||||
| if(ret > 0) { | |||||
| // 更新失败,未达到限制条件 | |||||
| return false; | |||||
| } else { | |||||
| // 更新失败,已达到限制条件 | |||||
| return true; | |||||
| } | |||||
| } else { | |||||
| // 已达到限制条件,不发 | |||||
| return true; | |||||
| } | |||||
| } else { | |||||
| // 没有限制条件 | |||||
| add(record); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -118,6 +118,9 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| @Autowired | @Autowired | ||||
| private WxCUserBasicInfoMapper wxCUserBasicInfoMapper; | private WxCUserBasicInfoMapper wxCUserBasicInfoMapper; | ||||
| @Autowired | |||||
| private WxMsgLimitService wxMsgLimitService; | |||||
| @Override | @Override | ||||
| public PageInfo<WxOrder> listAsPage(WxOrder record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxOrder> listAsPage(WxOrder record, Integer pageIndex, Integer pageSize) { | ||||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxOrderMapper.findList(record)); | return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxOrderMapper.findList(record)); | ||||
| @@ -11,6 +11,7 @@ import com.iformall.enums.EnumMsgStatus; | |||||
| import com.iformall.enums.EnumVerifyCode; | import com.iformall.enums.EnumVerifyCode; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.*; | import com.iformall.mapper.*; | ||||
| import com.iformall.service.WxMsgLimitService; | |||||
| import com.iformall.service.msg.MsgSendService; | import com.iformall.service.msg.MsgSendService; | ||||
| import com.iformall.service.WxMsgService; | import com.iformall.service.WxMsgService; | ||||
| import com.iformall.service.WxMsgValidationcodeService; | import com.iformall.service.WxMsgValidationcodeService; | ||||
| @@ -44,6 +45,10 @@ public class SendCallBackSmsServiceImpl implements MsgSendService { | |||||
| @Autowired | @Autowired | ||||
| private WxMsgService wxMsgService; | private WxMsgService wxMsgService; | ||||
| @Autowired | |||||
| private WxMsgLimitService wxMsgLimitService; | |||||
| @Override | @Override | ||||
| public void send(BaseMsg baseMsg) throws Exception{ | public void send(BaseMsg baseMsg) throws Exception{ | ||||
| WxMsg record = (WxMsg)baseMsg; | WxMsg record = (WxMsg)baseMsg; | ||||
| @@ -82,6 +87,18 @@ public class SendCallBackSmsServiceImpl implements MsgSendService { | |||||
| if (wxMsgModel != null) { | if (wxMsgModel != null) { | ||||
| modelId = wxMsgModel.getModelId(); | modelId = wxMsgModel.getModelId(); | ||||
| } | } | ||||
| /* | |||||
| // 检查是否超限 | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(record.getTenantId()); | |||||
| msgLimit.setType(EnumMsgLimitType.SMS_SALE.getCode()); | |||||
| msgLimit.setLimitId(phone); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| logger.error("用户短信超限:" + phone); | |||||
| return; | |||||
| } | |||||
| */ | |||||
| String result = WiwideUtil.sendMsg(secret, bid, publickey, phone, signature, msg, notifyUrl, EnumVerifyCode.NO.getCode().toString(), modelId); | String result = WiwideUtil.sendMsg(secret, bid, publickey, phone, signature, msg, notifyUrl, EnumVerifyCode.NO.getCode().toString(), modelId); | ||||
| JSONObject jsonObjectResult = JSONObject.parseObject(result); | JSONObject jsonObjectResult = JSONObject.parseObject(result); | ||||
| String ret = jsonObjectResult.get("ret").toString(); | String ret = jsonObjectResult.get("ret").toString(); | ||||
| @@ -6,11 +6,13 @@ import com.iformall.common.IdWorker; | |||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.domain.po.msg.BaseMsg; | import com.iformall.domain.po.msg.BaseMsg; | ||||
| import com.iformall.domain.po.msg.WxMsgRecord; | import com.iformall.domain.po.msg.WxMsgRecord; | ||||
| import com.iformall.enums.EnumMsgLimitType; | |||||
| import com.iformall.enums.EnumVerifyCode; | import com.iformall.enums.EnumVerifyCode; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.WxMsgConfigMapper; | import com.iformall.mapper.WxMsgConfigMapper; | ||||
| import com.iformall.mapper.WxMsgValidationcodeMapper; | import com.iformall.mapper.WxMsgValidationcodeMapper; | ||||
| import com.iformall.mapper.WxMsgValidationcodeModelMapper; | import com.iformall.mapper.WxMsgValidationcodeModelMapper; | ||||
| import com.iformall.service.WxMsgLimitService; | |||||
| import com.iformall.service.msg.MsgSendService; | import com.iformall.service.msg.MsgSendService; | ||||
| import com.iformall.service.WxMsgValidationcodeService; | import com.iformall.service.WxMsgValidationcodeService; | ||||
| import com.iformall.utils.WiwideUtil; | import com.iformall.utils.WiwideUtil; | ||||
| @@ -39,6 +41,9 @@ public class SendSmsServiceImpl implements MsgSendService { | |||||
| @Autowired | @Autowired | ||||
| private WxMsgValidationcodeService wxMsgValidationcodeService; | private WxMsgValidationcodeService wxMsgValidationcodeService; | ||||
| @Autowired | |||||
| private WxMsgLimitService wxMsgLimitService; | |||||
| @Override | @Override | ||||
| public void send(BaseMsg baseMsg) throws Exception{ | public void send(BaseMsg baseMsg) throws Exception{ | ||||
| WxMsgRecord record = (WxMsgRecord)baseMsg; | WxMsgRecord record = (WxMsgRecord)baseMsg; | ||||
| @@ -85,6 +90,16 @@ public class SendSmsServiceImpl implements MsgSendService { | |||||
| wxMsgValidationcode.setCode(record.getDynamicContentMap().get("s6")); | wxMsgValidationcode.setCode(record.getDynamicContentMap().get("s6")); | ||||
| } | } | ||||
| // 检查是否超限 | |||||
| WxMsgLimit msgLimit = new WxMsgLimit(); | |||||
| msgLimit.setTenantId(record.getTenantId()); | |||||
| msgLimit.setType(EnumMsgLimitType.SMS_VALID.getCode()); | |||||
| msgLimit.setLimitId(phone); | |||||
| if(wxMsgLimitService.checkIsLimit(msgLimit)) { | |||||
| logger.error("用户短信超限:" + phone); | |||||
| return; | |||||
| } | |||||
| String notifyUrl = wxMsgConfig.getNotifyurl(); | String notifyUrl = wxMsgConfig.getNotifyurl(); | ||||
| Integer modelId = wxMsgValidationcodeModel.getModelId(); | Integer modelId = wxMsgValidationcodeModel.getModelId(); | ||||
| String result = WiwideUtil.sendMsg(secret, bid, publickey, phone, signature, msg, notifyUrl, EnumVerifyCode.YES.getCode().toString(), modelId); | String result = WiwideUtil.sendMsg(secret, bid, publickey, phone, signature, msg, notifyUrl, EnumVerifyCode.YES.getCode().toString(), modelId); | ||||
| @@ -388,6 +388,20 @@ public class DateUtils { | |||||
| return testDate; | return testDate; | ||||
| } | } | ||||
| /** | |||||
| * 获得当前时间后几天的时间 | |||||
| * | |||||
| * @param days 后几天 | |||||
| * | |||||
| * @return | |||||
| */ | |||||
| public static Date getTimeAfterDays(int days, Date myDate) { | |||||
| Calendar now = Calendar.getInstance(); | |||||
| now.setTime(myDate); | |||||
| now.set(Calendar.DATE, now.get(Calendar.DATE) + days); | |||||
| return now.getTime(); | |||||
| } | |||||
| /** | /** | ||||
| * 获得指定时间前几天,格式yyyy-MM-dd | * 获得指定时间前几天,格式yyyy-MM-dd | ||||
| * | * | ||||
| @@ -0,0 +1,73 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.iformall.mapper.WxMsgLimitMapper"> | |||||
| <resultMap id="BaseResultMap" type="com.iformall.domain.po.WxMsgLimit"> | |||||
| <id column="id" jdbcType="BIGINT" property="id"/> | |||||
| <result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/> | |||||
| <result column="type" jdbcType="TINYINT" property="type"/> | |||||
| <result column="limit_id" jdbcType="VARCHAR" property="limitId"/> | |||||
| <result column="limit_num" jdbcType="INTEGER" property="limitNum"/> | |||||
| <result column="limit_date" jdbcType="TIMESTAMP" property="limitDate"/> | |||||
| </resultMap> | |||||
| <sql id="allColumns"> | |||||
| `id`,`tenant_id`,`type`,`limit_id`,`limit_num`,`limit_date` | |||||
| </sql> | |||||
| <sql id="dynamicWhereConditions"> | |||||
| where 1 = 1 | |||||
| <if test=" null != id "> | |||||
| and `id` = #{id} | |||||
| </if> | |||||
| <if test=" null != tenantId "> | |||||
| and `tenant_id`=#{tenantId} | |||||
| </if> | |||||
| <if test=" null != type "> | |||||
| and `type` = #{type} | |||||
| </if> | |||||
| <if test=" null != limitId "> | |||||
| and `limit_id` = #{limitId} | |||||
| </if> | |||||
| <if test=" null != limitNum "> | |||||
| and `limitNum` = #{limitNum} | |||||
| </if> | |||||
| <if test=" null != limitDate "> | |||||
| and `limit_date` = #{limitDate} | |||||
| </if> | |||||
| <if test=" null != expireDate "> | |||||
| and `limit_date` > #{expireDate} | |||||
| </if> | |||||
| <if test=" null != ids "> | |||||
| and id in | |||||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||||
| #{idItem} | |||||
| </foreach> | |||||
| </if> | |||||
| <if test=" null != sortColumns">order by ${sortColumns}</if> | |||||
| </sql> | |||||
| <select id="findList" parameterType="com.iformall.domain.po.WxMsgLimit" resultMap="BaseResultMap"> | |||||
| select | |||||
| <include refid="allColumns"/> | |||||
| from wx_msg_limit | |||||
| <include refid="dynamicWhereConditions"/> | |||||
| </select> | |||||
| <update id="updateLimitNum" parameterType="com.iformall.domain.po.WxMsgLimit"> | |||||
| update wx_msg_limit set limit_num = limit_num - 1 where `id` = #{id} and `tenant_id` = #{tenandId} and limit_num > 1 | |||||
| </update> | |||||
| <delete id="delLimitNum" parameterType="com.iformall.domain.po.WxMsgLimit"> | |||||
| delete from wx_msg_limit | |||||
| where `tenant_id` = #{tenandId} and `type`= #{type} and `limit_id` = #{limitId} | |||||
| </delete> | |||||
| </mapper> | |||||