| @@ -46,20 +46,9 @@ import java.util.stream.Collectors; | |||||
| public class WxMsgController extends BaseController { | public class WxMsgController extends BaseController { | ||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||||
| @Autowired | |||||
| private WxMsgService wxMsgService; | |||||
| @Autowired | |||||
| WxMsgConfigMapper wxMsgConfigMapper; | |||||
| @Autowired | |||||
| WxCUserTagsService wxCUserTagsService; | |||||
| @Autowired | @Autowired | ||||
| WxCUserBasicInfoService wxCUserBasicInfoService; | |||||
| @Autowired | |||||
| PushLimitService pushLimitService; | |||||
| private WxMsgService wxMsgService; | |||||
| @ApiOperation("分页列表接口") | @ApiOperation("分页列表接口") | ||||
| @GetMapping("list") | @GetMapping("list") | ||||
| @@ -82,79 +71,8 @@ public class WxMsgController extends BaseController { | |||||
| @SystemControllerLog(description = "标签短信-新增") | @SystemControllerLog(description = "标签短信-新增") | ||||
| public ResultData add(@RequestBody WxMsg wxMsg) { | public ResultData add(@RequestBody WxMsg wxMsg) { | ||||
| logger.debug("[" + getIpAddr() + "] WxMsgController::add"); | logger.debug("[" + getIpAddr() + "] WxMsgController::add"); | ||||
| //不是草稿检验疲劳度 | |||||
| if (!wxMsg.getStatus().equals(EnumMsgStatus.MSG_STATUS_DRAFT.getCode())) { | |||||
| if (wxMsg.getIsright().equals(EnumMsgSend.MSG_SEND_IMMEDIATELY.getCode())) { | |||||
| try { | |||||
| pushLimitService.checkSendTime(getTenantId()); | |||||
| } catch (MallinkException e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } | |||||
| } else { | |||||
| PushLimit pushLimit = pushLimitService.getPushLimit(getTenantId()); | |||||
| String sendtime = wxMsg.getSendtime(); | |||||
| Date date = DateUtils.stringToDate(sendtime, "yyyy-MM-dd HH:mm:ss"); | |||||
| boolean isInDate = DateUtils.isInDate(date, pushLimit.getTimeStart(), pushLimit.getTimeEnd()); | |||||
| if (!isInDate) { | |||||
| return new ResultData(ErrorCode.PUSH_LIMIT_NOT_INRANG); | |||||
| } | |||||
| } | |||||
| if(wxMsg.getId()!=null){ | |||||
| //如果不是草稿必然之前状态是草稿,删除 | |||||
| wxMsgService.deleteById(wxMsg.getId()); | |||||
| wxMsg.setId(null); | |||||
| } | |||||
| } | |||||
| wxMsg.setTenantId(getTenantId()); | wxMsg.setTenantId(getTenantId()); | ||||
| //1、手机多条以逗号分隔,直接通过实体得到wxmsg.getphones | |||||
| //2、通过标签 | |||||
| String phones = wxMsg.getPhones(); | |||||
| List<WxCUserBasicInfoFilterListDto> filter = wxMsg.getFilterList(); | |||||
| if (!phones.isEmpty() && !filter.isEmpty()) {//两种方式只能选其一 | |||||
| return new ResultData(ErrorCode.MSG_SEND_WAY_CHOOSE_ERROR); | |||||
| } | |||||
| if (phones.isEmpty() && filter.isEmpty()) {//两种方式必须选其一 | |||||
| return new ResultData(ErrorCode.MSG_SEND_WAY_CHOOSE_ERROR); | |||||
| } | |||||
| if (phones.isEmpty()) {//没有手工输入手机号时解析标签,有,继续流转 | |||||
| List<WxCUserBasicInfo> list = | |||||
| wxCUserBasicInfoService.listByFilterList(wxMsg.getTenantId(),wxMsg.getFilterList()); | |||||
| wxMsg.setExpectSendNumber(list.size());//预计发送数量 | |||||
| phones = list.stream().map(u -> u.getPhone()).collect(Collectors.joining(",")); | |||||
| if (phones==null || phones.isEmpty()) {//解析之后手机号依然不存在时返回 | |||||
| return new ResultData(ErrorCode.MSG_NO_VALID_PHONE); | |||||
| } | |||||
| wxMsg.setPhones(StringUtils.join(phones)); | |||||
| wxMsg.setTags(JSON.toJSONString(wxMsg.getFilterList())); | |||||
| } else { | |||||
| String[] phoneSplit = phones.split(","); | |||||
| Set<String> phoneSet = new HashSet<>(Arrays.asList(phoneSplit)); | |||||
| wxMsg.setExpectSendNumber(phoneSet.size());//预计发送数量 | |||||
| wxMsg.setPhones(StringUtils.join(phoneSet,",")); | |||||
| } | |||||
| //从短信配置中查询密钥 bid 等信息 | |||||
| WxMsgConfig wxMsgConfig = new WxMsgConfig(); | |||||
| wxMsgConfig.setTenantId(wxMsg.getTenantId()); | |||||
| List<WxMsgConfig> wxMsgConfigs = wxMsgConfigMapper.findList(wxMsgConfig); | |||||
| if (wxMsgConfigs.size() == 0) return new ResultData(ErrorCode.MSG_SERVER_NOT_FIND, "您还未接入短信运营商,请联系平台管理员"); | |||||
| wxMsgConfig = wxMsgConfigs.get(0); | |||||
| if (wxMsgConfig.getRemains() == 0) { | |||||
| logger.info("短信数量为0"); | |||||
| return new ResultData(ErrorCode.MSG_SUM_ZERO); | |||||
| } | |||||
| if (wxMsgConfig.getRemains() < wxMsg.getExpectSendNumber()) { | |||||
| logger.info("短信数量不足"); | |||||
| return new ResultData(ErrorCode.MSG_SUM_INSUFFICENT); | |||||
| } | |||||
| wxMsgService.saveOrUpdate(wxMsg, wxMsgConfig); | |||||
| return new ResultData(); | |||||
| return wxMsgService.add(wxMsg); | |||||
| } | } | ||||
| @@ -56,6 +56,11 @@ public class WxCUserBasicInfoDto implements Serializable{ | |||||
| @Transient | @Transient | ||||
| List<Long> tagIds; | List<Long> tagIds; | ||||
| @Transient | |||||
| private String phones; | |||||
| @Transient | @Transient | ||||
| protected String sortColumns; | protected String sortColumns; | ||||
| @@ -160,6 +165,14 @@ public class WxCUserBasicInfoDto implements Serializable{ | |||||
| this.tagIds = tagIds; | this.tagIds = tagIds; | ||||
| } | } | ||||
| public String getPhones() { | |||||
| return phones; | |||||
| } | |||||
| public void setPhones(String phones) { | |||||
| this.phones = phones; | |||||
| } | |||||
| public String getSortColumns() { | public String getSortColumns() { | ||||
| return sortColumns; | return sortColumns; | ||||
| } | } | ||||
| @@ -20,6 +20,7 @@ public class WxCUserBasicInfoFilterDto implements Serializable{ | |||||
| Long typeId; | Long typeId; | ||||
| Long id; | Long id; | ||||
| String param; | |||||
| public Long getTypeId() { | public Long getTypeId() { | ||||
| return typeId; | return typeId; | ||||
| @@ -36,4 +37,12 @@ public class WxCUserBasicInfoFilterDto implements Serializable{ | |||||
| public void setId(Long id) { | public void setId(Long id) { | ||||
| this.id = id; | this.id = id; | ||||
| } | } | ||||
| public String getParam() { | |||||
| return param; | |||||
| } | |||||
| public void setParam(String param) { | |||||
| this.param = param; | |||||
| } | |||||
| } | } | ||||
| @@ -39,6 +39,7 @@ public class WxCouponInject implements Serializable { | |||||
| @Transient | @Transient | ||||
| protected Date sendTimeEnd; | protected Date sendTimeEnd; | ||||
| public Long getId() { | public Long getId() { | ||||
| return id; | return id; | ||||
| } | } | ||||
| @@ -228,15 +229,23 @@ public class WxCouponInject implements Serializable { | |||||
| @Transient | @Transient | ||||
| List<WxCUserBasicInfoFilterListDto> filterList; | List<WxCUserBasicInfoFilterListDto> filterList; | ||||
| public List<WxCUserBasicInfoFilterListDto> getFilterList() { | public List<WxCUserBasicInfoFilterListDto> getFilterList() { | ||||
| return filterList; | return filterList; | ||||
| } | } | ||||
| public void setFilterList(List<WxCUserBasicInfoFilterListDto> filterList) { | public void setFilterList(List<WxCUserBasicInfoFilterListDto> filterList) { | ||||
| this.filterList = filterList; | this.filterList = filterList; | ||||
| } | } | ||||
| @Transient | |||||
| protected String phones; | |||||
| public String getPhones() { | |||||
| return phones; | |||||
| } | |||||
| public void setPhones(String phones) { | |||||
| this.phones = phones; | |||||
| } | |||||
| public static enum Field | public static enum Field | ||||
| { | { | ||||
| Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | ||||
| @@ -32,7 +32,7 @@ public enum EnumTagType { | |||||
| ID_25(25L, EnumTagTypeFlag.FLAG_NORMAL, EnumTagGroup.ID_4, "爱好"), | ID_25(25L, EnumTagTypeFlag.FLAG_NORMAL, EnumTagGroup.ID_4, "爱好"), | ||||
| ID_26(26L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_4, "生活半径"), | ID_26(26L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_4, "生活半径"), | ||||
| ID_0(0L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员手机"), | |||||
| ID_50(50L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员会龄"), | ID_50(50L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员会龄"), | ||||
| ID_51(51L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员等级"), | ID_51(51L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员等级"), | ||||
| ID_52(52L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员生日"), | ID_52(52L, EnumTagTypeFlag.FLAG_SINGLE, EnumTagGroup.ID_10, "会员生日"), | ||||
| @@ -26,19 +26,14 @@ public interface WxMsgService { | |||||
| */ | */ | ||||
| WxMsg getById(Long id); | WxMsg getById(Long id); | ||||
| /** | |||||
| * 保存或更新实体 | |||||
| * | |||||
| * @param record | |||||
| * @param wxMsgConfig | |||||
| */ | |||||
| ResultData saveOrUpdate(WxMsg record, WxMsgConfig wxMsgConfig); | |||||
| /** | |||||
| * 根据Id删除实体 | |||||
| * | |||||
| * @param id | |||||
| */ | |||||
| ResultData add(WxMsg wxmsg); | |||||
| /** | |||||
| * 根据Id删除实体 | |||||
| * | |||||
| * @param id | |||||
| */ | |||||
| void deleteById(Long id); | void deleteById(Long id); | ||||
| void sendMsgFromCouponInject(WxMsg wxmsg, WxMsgConfig wxMsgConfig, WxCouponInject record); | void sendMsgFromCouponInject(WxMsg wxmsg, WxMsgConfig wxMsgConfig, WxCouponInject record); | ||||
| @@ -221,78 +221,93 @@ public class WxCUserBasicInfoServiceImpl implements WxCUserBasicInfoService { | |||||
| ) | ) | ||||
| ); | ); | ||||
| private void filtersToDtoID0(WxCUserBasicInfoDto dto, WxCUserBasicInfoFilterDto f) { | |||||
| dto.setPhones(f.getParam()); | |||||
| } | |||||
| private void filtersToDtoID50(WxCUserBasicInfoDto dto, WxCUserBasicInfoFilterDto f) { | |||||
| ZoneId zone = ZoneId.systemDefault(); | |||||
| Map<String,Long> rangeMap = memberTimeMap.get(f.getId()); | |||||
| if (rangeMap != null) { | |||||
| Long rangeEnd = rangeMap.get(RANGE_END); | |||||
| if (rangeEnd != null) { | |||||
| LocalDateTime localDateTimeStart = LocalDateTime.now().minusDays(rangeEnd); | |||||
| dto.setStartTime(Date.from(localDateTimeStart.atZone(zone).toInstant())); | |||||
| } | |||||
| Long rangeStart = rangeMap.get(RANGE_START); | |||||
| if (rangeStart != null) { | |||||
| LocalDateTime localDateTimeEnd = LocalDateTime.now().minusDays(rangeStart); | |||||
| dto.setEndTime(Date.from(localDateTimeEnd.atZone(zone).toInstant())); | |||||
| } | |||||
| } | |||||
| } | |||||
| private void filtersToDtoID51(WxCUserBasicInfoDto dto, WxCUserBasicInfoFilterDto f) { | |||||
| List<WxLevelConfig> levels = wxLevelConfigService.getByTenantId(dto.getTenantId()); | |||||
| if (f.getId().equals(0L)) { | |||||
| dto.setLevelStartScore(0); | |||||
| if (levels.isEmpty()) | |||||
| dto.setLevelEndScore(null); | |||||
| else | |||||
| dto.setLevelEndScore(levels.get(0).getPoints()); | |||||
| } else { | |||||
| for (int i = 0; i < levels.size(); i++) { | |||||
| WxLevelConfig l = levels.get(i); | |||||
| if (l.getId().equals(f.getId())) { | |||||
| dto.setLevelStartScore(l.getPoints()); | |||||
| if (i + 1 < levels.size()) | |||||
| dto.setLevelEndScore(levels.get(i + 1).getPoints()); | |||||
| else | |||||
| dto.setLevelEndScore(null); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| private void filtersToDtoID52(WxCUserBasicInfoDto dto, WxCUserBasicInfoFilterDto f) { | |||||
| LocalDate localDate = LocalDate.now(); | |||||
| ZoneId zone = ZoneId.systemDefault(); | |||||
| if (f.getId().equals(EnumTag.ID_1100.getCode())) { | |||||
| dto.setBirthStartTime( | |||||
| Date.from( | |||||
| localDate.atStartOfDay().atZone(zone).toInstant())); | |||||
| dto.setBirthEndTime( | |||||
| Date.from( | |||||
| localDate.plusDays(1).atStartOfDay().atZone(zone).toInstant())); | |||||
| } else if (f.getId().equals(EnumTag.ID_1101.getCode())){ | |||||
| dto.setBirthStartTime( | |||||
| Date.from( | |||||
| localDate.with(DayOfWeek.MONDAY).atStartOfDay().atZone(zone).toInstant())); | |||||
| dto.setBirthEndTime( | |||||
| Date.from( | |||||
| localDate.plusWeeks(1).with(DayOfWeek.MONDAY).atStartOfDay().atZone(zone).toInstant())); | |||||
| } else if (f.getId().equals(EnumTag.ID_1102.getCode())){ | |||||
| dto.setBirthStartTime( | |||||
| Date.from( | |||||
| localDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay().atZone(zone).toInstant())); | |||||
| dto.setBirthEndTime( | |||||
| Date.from( | |||||
| localDate.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay().atZone(zone).toInstant())); | |||||
| } | |||||
| } | |||||
| private WxCUserBasicInfoDto filtersToDto(String tenantId, List<WxCUserBasicInfoFilterDto> filterList){ | private WxCUserBasicInfoDto filtersToDto(String tenantId, List<WxCUserBasicInfoFilterDto> filterList){ | ||||
| WxCUserBasicInfoDto dto = new WxCUserBasicInfoDto(); | WxCUserBasicInfoDto dto = new WxCUserBasicInfoDto(); | ||||
| List<Long> tagIdList = new ArrayList<>(); | List<Long> tagIdList = new ArrayList<>(); | ||||
| List<WxLevelConfig> levels = wxLevelConfigService.getByTenantId(tenantId); | |||||
| filterList.stream().forEach(f->{ | filterList.stream().forEach(f->{ | ||||
| if (f.getTypeId()==null) { | if (f.getTypeId()==null) { | ||||
| tagIdList.add(f.getId()); | tagIdList.add(f.getId()); | ||||
| return; | return; | ||||
| } | } | ||||
| if(f.getTypeId().equals(EnumTagType.ID_50.getCode())) { | |||||
| ZoneId zone = ZoneId.systemDefault(); | |||||
| Map<String,Long> rangeMap = memberTimeMap.get(f.getId()); | |||||
| if (rangeMap != null) { | |||||
| Long rangeEnd = rangeMap.get(RANGE_END); | |||||
| if (rangeEnd != null) { | |||||
| LocalDateTime localDateTimeStart = LocalDateTime.now().minusDays(rangeEnd); | |||||
| dto.setStartTime(Date.from(localDateTimeStart.atZone(zone).toInstant())); | |||||
| } | |||||
| Long rangeStart = rangeMap.get(RANGE_START); | |||||
| if (rangeStart != null) { | |||||
| LocalDateTime localDateTimeEnd = LocalDateTime.now().minusDays(rangeStart); | |||||
| dto.setEndTime(Date.from(localDateTimeEnd.atZone(zone).toInstant())); | |||||
| } | |||||
| } | |||||
| if(f.getTypeId().equals(EnumTagType.ID_0.getCode())) { | |||||
| filtersToDtoID0(dto,f); | |||||
| } else if(f.getTypeId().equals(EnumTagType.ID_50.getCode())) { | |||||
| filtersToDtoID50(dto,f); | |||||
| } else if (f.getTypeId().equals(EnumTagType.ID_51.getCode())) { | } else if (f.getTypeId().equals(EnumTagType.ID_51.getCode())) { | ||||
| if (f.getId().equals(0L)) { | |||||
| dto.setLevelStartScore(0); | |||||
| if (levels.isEmpty()) | |||||
| dto.setLevelEndScore(null); | |||||
| else | |||||
| dto.setLevelEndScore(levels.get(0).getPoints()); | |||||
| } else { | |||||
| for (int i = 0; i < levels.size(); i++) { | |||||
| WxLevelConfig l = levels.get(i); | |||||
| if (l.getId().equals(f.getId())) { | |||||
| dto.setLevelStartScore(l.getPoints()); | |||||
| if (i + 1 < levels.size()) | |||||
| dto.setLevelEndScore(levels.get(i + 1).getPoints()); | |||||
| else | |||||
| dto.setLevelEndScore(null); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| filtersToDtoID51(dto,f); | |||||
| } else if (f.getTypeId().equals(EnumTagType.ID_52.getCode())) { | } else if (f.getTypeId().equals(EnumTagType.ID_52.getCode())) { | ||||
| LocalDate localDate = LocalDate.now(); | |||||
| ZoneId zone = ZoneId.systemDefault(); | |||||
| if (f.getId().equals(EnumTag.ID_1100.getCode())) { | |||||
| dto.setBirthStartTime( | |||||
| Date.from( | |||||
| localDate.atStartOfDay().atZone(zone).toInstant())); | |||||
| dto.setBirthEndTime( | |||||
| Date.from( | |||||
| localDate.plusDays(1).atStartOfDay().atZone(zone).toInstant())); | |||||
| } else if (f.getId().equals(EnumTag.ID_1101.getCode())){ | |||||
| dto.setBirthStartTime( | |||||
| Date.from( | |||||
| localDate.with(DayOfWeek.MONDAY).atStartOfDay().atZone(zone).toInstant())); | |||||
| dto.setBirthEndTime( | |||||
| Date.from( | |||||
| localDate.plusWeeks(1).with(DayOfWeek.MONDAY).atStartOfDay().atZone(zone).toInstant())); | |||||
| } else if (f.getId().equals(EnumTag.ID_1102.getCode())){ | |||||
| dto.setBirthStartTime( | |||||
| Date.from( | |||||
| localDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay().atZone(zone).toInstant())); | |||||
| dto.setBirthEndTime( | |||||
| Date.from( | |||||
| localDate.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay().atZone(zone).toInstant())); | |||||
| } | |||||
| filtersToDtoID52(dto,f); | |||||
| } else { | } else { | ||||
| tagIdList.add(f.getId()); | tagIdList.add(f.getId()); | ||||
| } | } | ||||
| @@ -6,12 +6,15 @@ import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.common.ErrorCode; | import com.iformall.common.ErrorCode; | ||||
| import com.iformall.common.IdWorker; | import com.iformall.common.IdWorker; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.dto.WxCUserBasicInfoFilterDto; | |||||
| import com.iformall.domain.dto.WxCUserBasicInfoFilterListDto; | |||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.domain.po.msg.WxMsg; | import com.iformall.domain.po.msg.WxMsg; | ||||
| import com.iformall.enums.*; | import com.iformall.enums.*; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.WxCouponInjectMapper; | import com.iformall.mapper.WxCouponInjectMapper; | ||||
| import com.iformall.service.*; | import com.iformall.service.*; | ||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| @@ -108,18 +111,41 @@ public class WxCouponInjectServiceImpl implements WxCouponInjectService { | |||||
| return new ResultData(ErrorCode.COUPON_TYPE_IS_NOT_PASSIVE); | return new ResultData(ErrorCode.COUPON_TYPE_IS_NOT_PASSIVE); | ||||
| } | } | ||||
| //1、手机多条以逗号分隔,直接通过实体得到wxmsg.getphones | |||||
| //2、通过标签 | |||||
| String phones = record.getPhones(); | |||||
| List<WxCUserBasicInfoFilterListDto> filter = record.getFilterList(); | |||||
| if (!phones.isEmpty() && !filter.isEmpty()) {//两种方式只能选其一 | |||||
| return new ResultData(ErrorCode.MSG_SEND_WAY_CHOOSE_ERROR); | |||||
| } | |||||
| if (phones.isEmpty() && filter.isEmpty()) {//两种方式必须选其一 | |||||
| return new ResultData(ErrorCode.MSG_SEND_WAY_CHOOSE_ERROR); | |||||
| } | |||||
| if (!phones.isEmpty()) {//有手工输入手机号时解析 | |||||
| String[] phoneSplit = phones.split(","); | |||||
| Set<String> phoneSet = new HashSet<>(Arrays.asList(phoneSplit)); | |||||
| WxCUserBasicInfoFilterDto tag = new WxCUserBasicInfoFilterDto(); | |||||
| tag.setTypeId(EnumTagType.ID_0.getCode()); | |||||
| tag.setParam(StringUtils.join(phoneSet,",")); | |||||
| WxCUserBasicInfoFilterListDto filterListDto = new WxCUserBasicInfoFilterListDto(); | |||||
| filterListDto.setName(tag.getParam()); | |||||
| filterListDto.setTagList(new ArrayList<WxCUserBasicInfoFilterDto>(){{add(tag);}}); | |||||
| record.setFilterList(new ArrayList<WxCUserBasicInfoFilterListDto>(){{add(filterListDto);}}); | |||||
| } | |||||
| record.setTags(JSON.toJSONString(record.getFilterList())); | |||||
| List<WxCUserBasicInfo> userList = | List<WxCUserBasicInfo> userList = | ||||
| wxCUserBasicInfoService.listByFilterList(record.getTenantId(),record.getFilterList()); | wxCUserBasicInfoService.listByFilterList(record.getTenantId(),record.getFilterList()); | ||||
| if(userList.isEmpty()){ | if(userList.isEmpty()){ | ||||
| return new ResultData(ErrorCode.TAGS_MATCHED_NULL); | return new ResultData(ErrorCode.TAGS_MATCHED_NULL); | ||||
| } | } | ||||
| int inventory = wxCoupon.getRemainInventory();//库存数量 | int inventory = wxCoupon.getRemainInventory();//库存数量 | ||||
| if(userList.size()>inventory){ | if(userList.size()>inventory){ | ||||
| return new ResultData(ErrorCode.COUPON_IS_SELL_OUT); | return new ResultData(ErrorCode.COUPON_IS_SELL_OUT); | ||||
| } | } | ||||
| record.setTags(JSON.toJSONString(record.getFilterList())); | |||||
| //生成雪花id | //生成雪花id | ||||
| final IdWorker idWorker = IdWorker.get(); | final IdWorker idWorker = IdWorker.get(); | ||||
| @@ -1,17 +1,24 @@ | |||||
| package com.iformall.service.impl; | package com.iformall.service.impl; | ||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.github.pagehelper.PageHelper; | import com.github.pagehelper.PageHelper; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.IdWorker; | import com.iformall.common.IdWorker; | ||||
| import com.iformall.common.Result; | import com.iformall.common.Result; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.dto.WxCUserBasicInfoFilterListDto; | |||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.domain.po.msg.WxMsg; | import com.iformall.domain.po.msg.WxMsg; | ||||
| import com.iformall.enums.*; | import com.iformall.enums.*; | ||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mapper.*; | import com.iformall.mapper.*; | ||||
| import com.iformall.mq.MqBaseProducer; | import com.iformall.mq.MqBaseProducer; | ||||
| import com.iformall.service.PushLimitService; | |||||
| import com.iformall.service.WxCUserBasicInfoService; | |||||
| import com.iformall.service.WxCUserTagsService; | import com.iformall.service.WxCUserTagsService; | ||||
| import com.iformall.service.WxMsgService; | import com.iformall.service.WxMsgService; | ||||
| import com.iformall.utils.DateUtils; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| @@ -19,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.scheduling.annotation.Async; | import org.springframework.scheduling.annotation.Async; | ||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import java.util.*; | import java.util.*; | ||||
| import java.util.stream.Collectors; | |||||
| /** | /** | ||||
| @@ -49,6 +57,12 @@ public class WxMsgServiceImpl implements WxMsgService { | |||||
| @Autowired | @Autowired | ||||
| MqBaseProducer mqBaseProducer; | MqBaseProducer mqBaseProducer; | ||||
| @Autowired | |||||
| WxCUserBasicInfoService wxCUserBasicInfoService; | |||||
| @Autowired | |||||
| PushLimitService pushLimitService; | |||||
| @Override | @Override | ||||
| public PageInfo<WxMsg> listAsPage(WxMsg record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxMsg> listAsPage(WxMsg record, Integer pageIndex, Integer pageSize) { | ||||
| PageHelper.startPage(pageIndex, pageSize); | PageHelper.startPage(pageIndex, pageSize); | ||||
| @@ -86,8 +100,7 @@ public class WxMsgServiceImpl implements WxMsgService { | |||||
| } | } | ||||
| @Async | @Async | ||||
| @Override | |||||
| public ResultData saveOrUpdate(WxMsg wxMsg, WxMsgConfig wxMsgConfig) { | |||||
| private ResultData saveOrUpdate(WxMsg wxMsg, WxMsgConfig wxMsgConfig) { | |||||
| //新增记录 | //新增记录 | ||||
| if (wxMsg.getId() == null) { | if (wxMsg.getId() == null) { | ||||
| @@ -160,6 +173,84 @@ public class WxMsgServiceImpl implements WxMsgService { | |||||
| wxMsgMapper.deleteByPrimaryKey(id); | wxMsgMapper.deleteByPrimaryKey(id); | ||||
| } | } | ||||
| @Override | |||||
| public ResultData add(WxMsg wxMsg){ | |||||
| //不是草稿检验疲劳度 | |||||
| if (!wxMsg.getStatus().equals(EnumMsgStatus.MSG_STATUS_DRAFT.getCode())) { | |||||
| if (wxMsg.getIsright().equals(EnumMsgSend.MSG_SEND_IMMEDIATELY.getCode())) { | |||||
| try { | |||||
| pushLimitService.checkSendTime(wxMsg.getTenantId()); | |||||
| } catch (MallinkException e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } | |||||
| } else { | |||||
| PushLimit pushLimit = pushLimitService.getPushLimit(wxMsg.getTenantId()); | |||||
| String sendtime = wxMsg.getSendtime(); | |||||
| Date date = DateUtils.stringToDate(sendtime, "yyyy-MM-dd HH:mm:ss"); | |||||
| boolean isInDate = DateUtils.isInDate(date, pushLimit.getTimeStart(), pushLimit.getTimeEnd()); | |||||
| if (!isInDate) { | |||||
| return new ResultData(ErrorCode.PUSH_LIMIT_NOT_INRANG); | |||||
| } | |||||
| } | |||||
| if(wxMsg.getId()!=null){ | |||||
| //如果不是草稿必然之前状态是草稿,删除 | |||||
| deleteById(wxMsg.getId()); | |||||
| wxMsg.setId(null); | |||||
| } | |||||
| } | |||||
| //1、手机多条以逗号分隔,直接通过实体得到wxmsg.getphones | |||||
| //2、通过标签 | |||||
| String phones = wxMsg.getPhones(); | |||||
| List<WxCUserBasicInfoFilterListDto> filter = wxMsg.getFilterList(); | |||||
| if (!phones.isEmpty() && !filter.isEmpty()) {//两种方式只能选其一 | |||||
| return new ResultData(ErrorCode.MSG_SEND_WAY_CHOOSE_ERROR); | |||||
| } | |||||
| if (phones.isEmpty() && filter.isEmpty()) {//两种方式必须选其一 | |||||
| return new ResultData(ErrorCode.MSG_SEND_WAY_CHOOSE_ERROR); | |||||
| } | |||||
| if (phones.isEmpty()) {//没有手工输入手机号时解析标签,有,继续流转 | |||||
| List<WxCUserBasicInfo> list = | |||||
| wxCUserBasicInfoService.listByFilterList(wxMsg.getTenantId(),wxMsg.getFilterList()); | |||||
| wxMsg.setExpectSendNumber(list.size());//预计发送数量 | |||||
| phones = list.stream().map(u -> u.getPhone()).collect(Collectors.joining(",")); | |||||
| if (phones==null || phones.isEmpty()) {//解析之后手机号依然不存在时返回 | |||||
| return new ResultData(ErrorCode.MSG_NO_VALID_PHONE); | |||||
| } | |||||
| wxMsg.setPhones(StringUtils.join(phones)); | |||||
| wxMsg.setTags(JSON.toJSONString(wxMsg.getFilterList())); | |||||
| } else { | |||||
| String[] phoneSplit = phones.split(","); | |||||
| Set<String> phoneSet = new HashSet<>(Arrays.asList(phoneSplit)); | |||||
| wxMsg.setExpectSendNumber(phoneSet.size());//预计发送数量 | |||||
| wxMsg.setPhones(StringUtils.join(phoneSet,",")); | |||||
| } | |||||
| //从短信配置中查询密钥 bid 等信息 | |||||
| WxMsgConfig wxMsgConfig = new WxMsgConfig(); | |||||
| wxMsgConfig.setTenantId(wxMsg.getTenantId()); | |||||
| List<WxMsgConfig> wxMsgConfigs = wxMsgConfigMapper.findList(wxMsgConfig); | |||||
| if (wxMsgConfigs.size() == 0) return new ResultData(ErrorCode.MSG_SERVER_NOT_FIND, "您还未接入短信运营商,请联系平台管理员"); | |||||
| wxMsgConfig = wxMsgConfigs.get(0); | |||||
| if (wxMsgConfig.getRemains() == 0) { | |||||
| logger.info("短信数量为0"); | |||||
| return new ResultData(ErrorCode.MSG_SUM_ZERO); | |||||
| } | |||||
| if (wxMsgConfig.getRemains() < wxMsg.getExpectSendNumber()) { | |||||
| logger.info("短信数量不足"); | |||||
| return new ResultData(ErrorCode.MSG_SUM_INSUFFICENT); | |||||
| } | |||||
| saveOrUpdate(wxMsg, wxMsgConfig); | |||||
| return new ResultData(); | |||||
| } | |||||
| @Async | @Async | ||||
| @Override | @Override | ||||
| public void sendMsgFromCouponInject(WxMsg wxmsg, WxMsgConfig wxMsgConfig, WxCouponInject couponInject) { | public void sendMsgFromCouponInject(WxMsg wxmsg, WxMsgConfig wxMsgConfig, WxCouponInject couponInject) { | ||||
| @@ -180,7 +271,6 @@ public class WxMsgServiceImpl implements WxMsgService { | |||||
| String phones = StringUtils.join(phoneList, ","); | String phones = StringUtils.join(phoneList, ","); | ||||
| wxMsg.setPhones(phones); | wxMsg.setPhones(phones); | ||||
| wxMsg.setExpectSendNumber(extra); | wxMsg.setExpectSendNumber(extra); | ||||
| //sendmsg(wxMsg, wxMsgConfig, couponInject); | |||||
| wxMsg.setWxMsgConfig(wxMsgConfig); | wxMsg.setWxMsgConfig(wxMsgConfig); | ||||
| wxMsg.setCouponInject(couponInject); | wxMsg.setCouponInject(couponInject); | ||||
| wxMsg.setMsgType(EnumMsgRecordType.SMS_CALLBACK.getCode()); | wxMsg.setMsgType(EnumMsgRecordType.SMS_CALLBACK.getCode()); | ||||
| @@ -191,7 +281,6 @@ public class WxMsgServiceImpl implements WxMsgService { | |||||
| String phones = StringUtils.join(phoneList, ","); | String phones = StringUtils.join(phoneList, ","); | ||||
| wxMsg.setExpectSendNumber(1000); | wxMsg.setExpectSendNumber(1000); | ||||
| wxMsg.setPhones(phones); | wxMsg.setPhones(phones); | ||||
| //sendmsg(wxMsg, wxMsgConfig, couponInject); | |||||
| wxMsg.setWxMsgConfig(wxMsgConfig); | wxMsg.setWxMsgConfig(wxMsgConfig); | ||||
| wxMsg.setCouponInject(couponInject); | wxMsg.setCouponInject(couponInject); | ||||
| wxMsg.setMsgType(EnumMsgRecordType.SMS_CALLBACK.getCode()); | wxMsg.setMsgType(EnumMsgRecordType.SMS_CALLBACK.getCode()); | ||||
| @@ -201,74 +290,6 @@ public class WxMsgServiceImpl implements WxMsgService { | |||||
| } | } | ||||
| } | } | ||||
| // @Deprecated | |||||
| // public ResultData sendmsg(WxMsg record, WxMsgConfig wxMsgConfig, WxCouponInject couponInject) { | |||||
| // logger.info("发送短信开始..."); | |||||
| // logger.info("couponInject:" + couponInject); | |||||
| // String secret = wxMsgConfig.getSecret(); | |||||
| // String bid = wxMsgConfig.getBid(); | |||||
| // String publickey = wxMsgConfig.getPublickey(); | |||||
| // | |||||
| // String phone = record.getPhones(); | |||||
| // String signature = record.getSignature(); | |||||
| // String msg = record.getMsg(); | |||||
| // String notifyUrl = wxMsgConfig.getNotifyurl(); | |||||
| // WxMsgModel wxMsgModel = wxMsgModelMapper.selectByPrimaryKey(record.getModelId()); | |||||
| // Integer modelId = null; | |||||
| // if (wxMsgModel != null) { | |||||
| // modelId = wxMsgModel.getModelId(); | |||||
| // } | |||||
| // logger.info("=============迈外迪API开始调用"); | |||||
| // String result = WiwideUtil.sendMsg(secret, bid, publickey, phone, signature, msg, notifyUrl, EnumVerifyCode.NO.getCode().toString(), modelId); | |||||
| // logger.info("=============迈外迪API返回结果:" + result); | |||||
| // JSONObject jsonObjectResult = JSONObject.parseObject(result); | |||||
| // String ret = jsonObjectResult.get("ret").toString(); | |||||
| // String batchNo = jsonObjectResult.get("data").toString(); | |||||
| // String resultMsg = jsonObjectResult.get("msg").toString(); | |||||
| // record.setReturnResult(jsonObjectResult.toJSONString()); | |||||
| // | |||||
| // | |||||
| // if (ret.equals(EnumMsgSendStatus.MSG_SEND_SUCCESS.getCode().toString())) { | |||||
| // record.setSendstatus(EnumMsgSendStatus.MSG_SEND_SUCCESS.getCode()); | |||||
| // } else { | |||||
| // record.setSendstatus(EnumMsgSendStatus.MSG_SEND_FAIL.getCode()); | |||||
| // } | |||||
| // | |||||
| // final IdWorker idWorker = IdWorker.get(); | |||||
| // long id = idWorker.nextId(); | |||||
| // WxMsg wxMsg = new WxMsg(); | |||||
| // wxMsg.setTenantId(record.getTenantId()); | |||||
| // wxMsg.setModelId(record.getModelId()); | |||||
| // wxMsg.setMsg(record.getMsg()); | |||||
| // wxMsg.setExpectSendNumber(record.getExpectSendNumber()); | |||||
| // wxMsg.setPhones(record.getPhones()); | |||||
| // wxMsg.setSignature(record.getSignature()); | |||||
| // wxMsg.setIsright(record.getIsright()); | |||||
| // wxMsg.setName(record.getName()); | |||||
| // wxMsg.setSendstatus(record.getSendstatus()); | |||||
| // wxMsg.setLabel(record.getLabel()); | |||||
| // wxMsg.setStatus(record.getStatus()); | |||||
| // wxMsg.setWay(record.getWay()); | |||||
| // wxMsg.setId(id); | |||||
| // String systemTime = DateUtils.getSystemTime("yyyy-MM-dd HH:mm:ss"); | |||||
| // wxMsg.setSendtime(systemTime); | |||||
| // wxMsg.setCreatetime(DateUtils.stringToDate(systemTime, "yyyy-MM-dd HH:mm:ss")); | |||||
| // //精准投放 | |||||
| // if (couponInject != null) { | |||||
| // wxMsg.setCouponInjectId(couponInject.getId()); | |||||
| // } | |||||
| // wxMsgMapper.insertSelective(wxMsg); | |||||
| // | |||||
| // logger.info("发送短信结束..."); | |||||
| // if (ret.equals(EnumMsgSendStatus.MSG_SEND_SUCCESS.getCode().toString())) { | |||||
| // addMsgCallback(wxMsg, batchNo); | |||||
| // return new ResultData(Result.SUCCESS, "短信发送中,您可在短信明细中查看发送状态", id); | |||||
| // } else { | |||||
| // return new ResultData(ErrorCode.MSG_SEND_INTERFACE_ERROR.getCode(), | |||||
| // ErrorCode.MSG_SEND_INTERFACE_ERROR.getMessage() + ":" + resultMsg); | |||||
| // } | |||||
| // | |||||
| // } | |||||
| @Override | @Override | ||||
| public void addMsgCallback(WxMsg wxmsg, String batchNo) { | public void addMsgCallback(WxMsg wxmsg, String batchNo) { | ||||
| @@ -364,6 +364,10 @@ | |||||
| and cu.birthdate < #{birthEndTime} | and cu.birthdate < #{birthEndTime} | ||||
| </if> | </if> | ||||
| <if test=" null != phones"> | |||||
| and cu.phone in (${phones}) | |||||
| </if> | |||||
| <if test=" null != levelStartScore and (0 != levelStartScore and '' != levelStartScore)"> | <if test=" null != levelStartScore and (0 != levelStartScore and '' != levelStartScore)"> | ||||
| and cu.poins >= #{levelStartScore} | and cu.poins >= #{levelStartScore} | ||||
| <if test=" null != levelEndScore"> | <if test=" null != levelEndScore"> | ||||