diff --git a/fw-hestia-common/pom.xml b/fw-hestia-common/pom.xml index af0c587..a00262b 100644 --- a/fw-hestia-common/pom.xml +++ b/fw-hestia-common/pom.xml @@ -19,6 +19,10 @@ com.alibaba fastjson + + cn.fw + fw-common-data + diff --git a/fw-hestia-rpc/pom.xml b/fw-hestia-rpc/pom.xml index 7c871d4..66adbd4 100644 --- a/fw-hestia-rpc/pom.xml +++ b/fw-hestia-rpc/pom.xml @@ -23,6 +23,10 @@ cn.fw fw-hestia-common + + cn.fw + fw-passport-sdk + cn.fw diff --git a/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/PassportService.java b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/PassportService.java new file mode 100644 index 0000000..099bb6f --- /dev/null +++ b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/PassportService.java @@ -0,0 +1,43 @@ +package cn.fw.hestia.rpc.passport; + +import cn.fw.common.exception.BusinessException; +import cn.fw.data.base.domain.common.Message; +import cn.fw.passport.sdk.api.MiniQrCodeApi; +import cn.fw.passport.sdk.api.param.WxBCodeParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 会员外部服务 + * @author kurisu + */ +@Slf4j +@Service +public class PassportService { + + @Autowired + private MiniQrCodeApi miniQrCodeApi; + + /** + * 获取小程序二维码 + * + * @param param + * @return + */ + public byte[] getWxBCode(WxBCodeParam param){ + try { + Message message = miniQrCodeApi.getWxBCode(param); + if (!message.isSuccess()) { + log.error("调用passport api 生成小程序码业务异常:{}", message.getResult()); + throw new BusinessException(message.getCode(), message.getResult()); + } + return message.getData(); + }catch (Exception e){ + log.error("会员系统调用失败",e); + throw new BusinessException("调用会员系统异常"); + } + } + + +} diff --git a/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/TemplateMessageService.java b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/TemplateMessageService.java new file mode 100644 index 0000000..f0ecf88 --- /dev/null +++ b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/TemplateMessageService.java @@ -0,0 +1,166 @@ +package cn.fw.hestia.rpc.passport; + +import cn.fw.data.base.domain.common.Message; +import cn.fw.hestia.rpc.passport.dto.TemplateMessageParam; +import cn.fw.passport.sdk.api.WxMpTemplateMessageApi; +import cn.fw.passport.sdk.api.param.WxMpTempMessageData; +import cn.fw.passport.sdk.api.param.WxMpTempMessageParam; +import cn.fw.hestia.rpc.passport.dto.RenewInsurNoticeMessageParam; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * passport系统-模板消息服务 + *

+ * create at 2019-05-15 + * + * @author kurisu + */ +@Slf4j +@Service +public class TemplateMessageService { + + private final WxMpTemplateMessageApi wxMpTemplateMessageApi; + + public TemplateMessageService(final WxMpTemplateMessageApi wxMpTemplateMessageApi) { + this.wxMpTemplateMessageApi = wxMpTemplateMessageApi; + } + + /** + * 消息模板Code + */ + @Value("${templateCode}") + @Getter + private String templateCode = ""; + + + /** + * 小程序页面--续保提醒/保险估算 + */ + private static final String PAGE_PATH_INSU = "/pgCas/Insurance/Append/index?bizType={0}"; + /** + * 保养预约页面 + */ + private static final String RESE_URL = "/pgCas/Appoint/Index/index"; + + /** + * 发送续保提醒通知 + * + * @param messageParam + */ + public String sendTemplateMessage(TemplateMessageParam messageParam) { + log.info("开始发送续保提醒通知,senderId:{}", messageParam); + try { + WxMpTempMessageParam param = new WxMpTempMessageParam(); + param.setCusId(messageParam.getMemberId()); + param.setTempCode(getTemplateCode()); + WxMpTempMessageData remark = new WxMpTempMessageData(); + remark.setValue("点击“详情”进行保险估价⬇"); + remark.setColor("#a61b29"); + param.setRemark(remark); + WxMpTempMessageData title = new WxMpTempMessageData(); + title.setValue("您好!您购买的车险即将到期,现在预约续保可享养车大礼包!"); + param.setTitle(title); + List keywords = new ArrayList<>(); + //车牌号 + WxMpTempMessageData keyword1 = new WxMpTempMessageData(); + keyword1.setValue(""); + keywords.add(keyword1); + + param.setKeyWordList(keywords); + param.setPagePath(MessageFormat.format(PAGE_PATH_INSU, 2)); + Message msg = wxMpTemplateMessageApi.send(param); + if (!msg.isSuccess()) { + log.error("【passport系统】发送续保提醒模板消息失败:{}", msg.getResult()); + return msg.getResult(); + } + return ""; + } catch (Exception e) { + log.error("发送续保提醒模板消息失败", e); + return "系统异常"; + } + } + + /** + * 发送首保消息提醒 + * + * @param messageParam + * @return + */ + public String sendFMNotice(RenewInsurNoticeMessageParam messageParam) { + log.info("开始发送首保消息提醒,senderId:{}", messageParam); + try { + WxMpTempMessageParam param = new WxMpTempMessageParam(); + param.setCusId(messageParam.getMemberId()); + param.setTempCode(getTemplateCode()); + + param.setRemark(new WxMpTempMessageData("点击“详情”可在线预约保养", "a61b29")); + param.setTitle(new WxMpTempMessageData("您好!您的爱车的首次保养即将到期,请尽快进店进行保养!")); + + List keywords = Arrays.asList( + new WxMpTempMessageData("首保提醒"), + //门店 + new WxMpTempMessageData(messageParam.getShopName()), + //到期时间 + new WxMpTempMessageData(messageParam.getExpireDate()) + ); + + param.setKeyWordList(keywords); + param.setPagePath(RESE_URL); + Message msg = wxMpTemplateMessageApi.send(param); + if (!msg.isSuccess()) { + log.error("【passport系统】发送首保提醒模板消息失败:{}", msg.getResult()); + return msg.getResult(); + } + return ""; + } catch (Exception e) { + log.error("发送首保提醒模板消息失败", e); + return "系统异常"; + } + } + + /** + * 发送例保消息提醒 + * + * @param messageParam + * @return + */ + public String sendRMNotice(RenewInsurNoticeMessageParam messageParam) { + log.info("开始发送例保消息提醒,senderId:{}", messageParam); + try { + WxMpTempMessageParam param = new WxMpTempMessageParam(); + param.setCusId(messageParam.getMemberId()); + param.setTempCode(getTemplateCode()); + + param.setRemark(new WxMpTempMessageData("点击“详情”可在线预约保养", "a61b29")); + param.setTitle(new WxMpTempMessageData("您好!您的爱车的下次保养即将到期,请尽快进店进行保养!")); + + List keywords = Arrays.asList( + new WxMpTempMessageData("保养提醒"), + //门店 + new WxMpTempMessageData(messageParam.getShopName()), + //到期时间 + new WxMpTempMessageData(messageParam.getExpireDate()) + ); + + param.setKeyWordList(keywords); + param.setPagePath(RESE_URL); + Message msg = wxMpTemplateMessageApi.send(param); + if (!msg.isSuccess()) { + log.error("【passport系统】发送例保提醒模板消息失败:{}", msg.getResult()); + return msg.getResult(); + } + return ""; + } catch (Exception e) { + log.error("发送例保提醒模板消息失败", e); + return "系统异常"; + } + } +} diff --git a/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/OrderConfirmMessageParam.java b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/OrderConfirmMessageParam.java new file mode 100644 index 0000000..ed5bac3 --- /dev/null +++ b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/OrderConfirmMessageParam.java @@ -0,0 +1,34 @@ +package cn.fw.hestia.rpc.passport.dto; + +import lombok.Data; + +/** + * 订单确认模板消息param + *

+ * create at 2019-05-15 + * + * @author kurisu + */ +@Data +public class OrderConfirmMessageParam { + /** + * 客户ID + */ + private Long cusId; + /** + * 工单号 + */ + private String orderNo; + /** + * 车牌号 + */ + private String carPlateNo; + /** + * 商家名称 + */ + private String dealerName; + /** + * 工单总金额 + */ + private Double totalValue; +} diff --git a/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/RenewInsurNoticeMessageParam.java b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/RenewInsurNoticeMessageParam.java new file mode 100644 index 0000000..466eb0e --- /dev/null +++ b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/RenewInsurNoticeMessageParam.java @@ -0,0 +1,32 @@ +package cn.fw.hestia.rpc.passport.dto; + +import lombok.Data; +import lombok.ToString; + +/** + * 续保提醒模板消息param + *

+ * create at 2019-05-15 + * + * @author kurisu + */ +@Data +@ToString +public class RenewInsurNoticeMessageParam { + /** + * 客户ID + */ + private Long memberId; + /** + * 保险公司名称 + */ + private String insurCompanyName; + /** + * 服务站 + */ + private String shopName; + /** + * 保险到期时间 + */ + private String expireDate; +} diff --git a/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/TemplateMessageParam.java b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/TemplateMessageParam.java new file mode 100644 index 0000000..0dcc8da --- /dev/null +++ b/fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/TemplateMessageParam.java @@ -0,0 +1,21 @@ +package cn.fw.hestia.rpc.passport.dto; + +import lombok.Data; +import lombok.ToString; + +import java.util.Map; + +/** + * 续保提醒模板消息param + *

+ * create at 2019-05-15 + * + * @author kurisu + */ +@Data +@ToString +public class TemplateMessageParam { + private Long memberId; + private String path; + private Map paramMap; +} diff --git a/fw-hestia-server/src/main/java/cn/fw/hestia/server/Application.java b/fw-hestia-server/src/main/java/cn/fw/hestia/server/Application.java index 375315d..860b27f 100644 --- a/fw-hestia-server/src/main/java/cn/fw/hestia/server/Application.java +++ b/fw-hestia-server/src/main/java/cn/fw/hestia/server/Application.java @@ -11,6 +11,7 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.annotation.EnableTransactionManagement; /** * 启动类 @@ -21,6 +22,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableAuthClient @EnableScheduling @EnableDiscoveryClient +@EnableTransactionManagement @EnableAutoConfiguration @Configuration @EnableRedisRepositories diff --git a/fw-hestia-server/src/main/java/cn/fw/hestia/server/config/LocalDateTimeSerializerConfig.java b/fw-hestia-server/src/main/java/cn/fw/hestia/server/config/LocalDateTimeSerializerConfig.java new file mode 100644 index 0000000..47e59ab --- /dev/null +++ b/fw-hestia-server/src/main/java/cn/fw/hestia/server/config/LocalDateTimeSerializerConfig.java @@ -0,0 +1,98 @@ +package cn.fw.hestia.server.config; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * @author : kurisu + * @className : LocalDateTimeSerializerConfig + * @description : LocalDateTime序列化和反序列化配置 + * @date: 2021-01-19 10:04 + */ +@Configuration +public class LocalDateTimeSerializerConfig { + + + @Bean + public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { + return builder -> { + builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer()); + builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer()); + builder.serializerByType(LocalDate.class, new LocalDateSerializer()); + builder.deserializerByType(LocalDate.class, new LocalDateDeserializer()); + }; + } + + /** + * 序列化 + */ + public static class LocalDateTimeSerializer extends JsonSerializer { + @Override + public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + if (value != null) { + long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + gen.writeNumber(timestamp); + } + } + } + + /** + * 反序列化 + */ + public static class LocalDateTimeDeserializer extends JsonDeserializer { + @Override + public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) + throws IOException { + long timestamp = p.getValueAsLong(); + if (timestamp > 0) { + return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()); + } else { + return null; + } + } + } + + /** + * 序列化 + */ + public static class LocalDateSerializer extends JsonSerializer { + @Override + public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + if (value != null) { + long timestamp = value.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli(); + gen.writeNumber(timestamp); + } + } + } + + /** + * 反序列化 + */ + public static class LocalDateDeserializer extends JsonDeserializer { + @Override + public LocalDate deserialize(JsonParser p, DeserializationContext deserializationContext) + throws IOException { + long timestamp = p.getValueAsLong(); + if (timestamp > 0) { + return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()).toLocalDate(); + } else { + return null; + } + } + } +} \ No newline at end of file diff --git a/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2DateConverter.java b/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2DateConverter.java new file mode 100644 index 0000000..f1f1533 --- /dev/null +++ b/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2DateConverter.java @@ -0,0 +1,29 @@ +package cn.fw.hestia.server.converter; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * @author : kurisu + * @className : Timestamp2DateConverter + * @description : {@link String} to {@link Date} + * @date: 2021-01-19 10:04 + */ +@Component +@ConfigurationPropertiesBinding +public class Timestamp2DateConverter implements Converter { + @Override + @Nullable + public Date convert(@Nullable final String value) { + if (StringUtils.isNotBlank(value) && NumberUtils.isDigits(value)) { + return new Date(new Long(value)); + } + return null; + } +} diff --git a/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2LocalDateConverter.java b/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2LocalDateConverter.java new file mode 100644 index 0000000..1c650e9 --- /dev/null +++ b/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2LocalDateConverter.java @@ -0,0 +1,31 @@ +package cn.fw.hestia.server.converter; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; + +/** + * @author : kurisu + * @className : Timestamp2LocalDateConverter + * @description : {@link String} to {@link LocalDate} + * @date: 2021-01-19 10:04 + */ +@Component +@ConfigurationPropertiesBinding +public class Timestamp2LocalDateConverter implements Converter { + @Override + @Nullable + public LocalDate convert(@Nullable final String value) { + if (StringUtils.isNotBlank(value) && NumberUtils.isDigits(value)) { + return Instant.ofEpochMilli(NumberUtils.toLong(value)).atZone(ZoneId.systemDefault()).toLocalDate(); + } + return null; + } +} diff --git a/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2LocalDateTimeConverter.java b/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2LocalDateTimeConverter.java new file mode 100644 index 0000000..e33efa9 --- /dev/null +++ b/fw-hestia-server/src/main/java/cn/fw/hestia/server/converter/Timestamp2LocalDateTimeConverter.java @@ -0,0 +1,31 @@ +package cn.fw.hestia.server.converter; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * @author : kurisu + * @className : Timestamp2LocalDateTimeConverter + * @description : {@link String} to {@link LocalDateTime} + * @date: 2021-01-19 10:04 + */ +@Component +@ConfigurationPropertiesBinding +public class Timestamp2LocalDateTimeConverter implements Converter { + @Override + @Nullable + public LocalDateTime convert(@Nullable final String value) { + if (StringUtils.isNotBlank(value) && NumberUtils.isDigits(value)) { + return Instant.ofEpochMilli(NumberUtils.toLong(value)).atZone(ZoneId.systemDefault()).toLocalDateTime(); + } + return null; + } +} diff --git a/fw-hestia-server/src/main/resources/application.yml b/fw-hestia-server/src/main/resources/application.yml index 7b2426f..f40862c 100644 --- a/fw-hestia-server/src/main/resources/application.yml +++ b/fw-hestia-server/src/main/resources/application.yml @@ -119,4 +119,6 @@ server: worker-threads: 50 task: - switch: 'on' \ No newline at end of file + switch: 'on' + +templateCode: 'OPENTM408237350' \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2f6663f..d65e840 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,6 @@ fw-hestia-domain fw-hestia-sdk fw-hestia-rpc - fw-hestia-rpc @@ -37,6 +36,7 @@ 2.1.0 1.0 1.2.51 + 2.2.0 @@ -87,6 +87,11 @@ cn.fw + fw-passport-sdk + ${fw-passport-sdk.version} + + + cn.fw fw-hestia-sdk ${fw.hestia.sdk.version}