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 @@