|
@@ -5,14 +5,18 @@ import cn.kdan.cloud.pdf.office.api.account.feign.UserApi;
|
|
|
import cn.kdan.cloud.pdf.office.api.account.feign.UserSubscriptionInfoApi;
|
|
|
import cn.kdan.cloud.pdf.office.api.account.utils.SubscriptionUtil;
|
|
|
import cn.kdan.cloud.pdf.office.api.account.vo.UserSubscriptionInfo;
|
|
|
+import cn.kdan.cloud.pdf.office.api.email.bo.EmailSendBO;
|
|
|
+import cn.kdan.cloud.pdf.office.api.email.feign.EmailApi;
|
|
|
import cn.kdan.cloud.pdf.office.api.payment.constant.OrderConstant;
|
|
|
import cn.kdan.cloud.pdf.office.api.payment.constant.SubscriptionConstant;
|
|
|
import cn.kdan.cloud.pdf.office.api.payment.vo.OrdersVO;
|
|
|
import cn.kdan.cloud.pdf.office.api.product.feign.ProductApi;
|
|
|
import cn.kdan.cloud.pdf.office.api.product.vo.ProductVO;
|
|
|
+import cn.kdan.cloud.pdf.office.common.enums.EmailCodeTypeEnum;
|
|
|
import cn.kdan.cloud.pdf.office.common.enums.account.AccountTypeEnum;
|
|
|
import cn.kdan.cloud.pdf.office.common.enums.account.PDFOfficeUserSubscriptionStatusEnum;
|
|
|
import cn.kdan.cloud.pdf.office.common.utils.CommonUtils;
|
|
|
+import cn.kdan.cloud.pdf.office.common.utils.MyDateUtils;
|
|
|
import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
|
|
|
import cn.kdan.cloud.pdf.office.common.vo.UserSubscriptionInfoVO;
|
|
|
import cn.kdan.cloud.pdf.office.common.vo.UserVO;
|
|
@@ -23,6 +27,7 @@ import cn.kdan.cloud.pdf.office.payment.service.OrderGiftService;
|
|
|
import cn.kdan.cloud.pdf.office.payment.service.OrderService;
|
|
|
import cn.kdan.cloud.pdf.office.payment.service.PayCenterWebhookService;
|
|
|
import cn.kdan.cloud.pdf.office.payment.service.SubscriptionsService;
|
|
|
+import cn.kdan.cloud.pdf.office.payment.utils.TemplatesUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
@@ -32,9 +37,21 @@ import org.jetbrains.annotations.NotNull;
|
|
|
import org.redisson.api.RLock;
|
|
|
import org.redisson.api.RedissonClient;
|
|
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.http.HttpEntity;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.LinkedMultiValueMap;
|
|
|
+import org.springframework.util.MultiValueMap;
|
|
|
+import org.springframework.util.StreamUtils;
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
@@ -64,6 +81,14 @@ public class PayCenterWebhookServiceImpl implements PayCenterWebhookService {
|
|
|
private final RabbitTemplate rabbitTemplate;
|
|
|
|
|
|
private final OrderGiftService orderGiftService;
|
|
|
+
|
|
|
+ private final EmailApi emailApi;
|
|
|
+
|
|
|
+ private static final RestTemplate restTemplate = new RestTemplate();
|
|
|
+
|
|
|
+ @Value("${htmlToPdfUrl:http://139.196.160.101:3060/api/get-invoice}")
|
|
|
+ private String htmlToPdfUrl;
|
|
|
+
|
|
|
/**
|
|
|
* 支付中台统一回调
|
|
|
* @param body 请求参数
|
|
@@ -177,10 +202,13 @@ public class PayCenterWebhookServiceImpl implements PayCenterWebhookService {
|
|
|
order.setThirdTradeNo(payId);
|
|
|
order.setStatus(OrderConstant.COMPLETED);
|
|
|
order.setPayDate(new Date());
|
|
|
+ order.setInvoiceNo(MyDateUtils.getTimeStamp() + (int) ((Math.random() * 9 + 1) * 1000));
|
|
|
ordersService.updateById(order);
|
|
|
+ ordersVO.setInvoiceNo(order.getInvoiceNo());
|
|
|
// 更新user_subscription_info
|
|
|
UserSubscriptionInfo userSubscriptionInfo = new UserSubscriptionInfo();
|
|
|
|
|
|
+ boolean emailFlag = false;
|
|
|
// 如果是批量的购买,不需要判断用户有没有购买,直接存到订单赠送
|
|
|
if (productVO.getPlatform() == 1 && ordersVO.getPayNumber() > 1) {
|
|
|
log.info("批量购买{}个,新增订单赠送", ordersVO.getPayNumber());
|
|
@@ -241,6 +269,7 @@ public class PayCenterWebhookServiceImpl implements PayCenterWebhookService {
|
|
|
}
|
|
|
userApi.updateUser(userVO);
|
|
|
userSubscriptionInfoApi.update(userSubscriptionInfo);
|
|
|
+ emailFlag = true;
|
|
|
}
|
|
|
} else {
|
|
|
log.info("用户没有订阅信息,新增记录");
|
|
@@ -286,12 +315,88 @@ public class PayCenterWebhookServiceImpl implements PayCenterWebhookService {
|
|
|
}
|
|
|
userApi.updateUser(userVO);
|
|
|
userSubscriptionInfoApi.insert(userSubscriptionInfo);
|
|
|
+ emailFlag = true;
|
|
|
}
|
|
|
}
|
|
|
//删除缓存中的订单
|
|
|
ordersService.deleteTheCacheInTheCacheManager(ordersVO.getUserId() + "-" + ordersVO.getProductId() + "-" + ordersVO.getPayment());
|
|
|
// 关闭用户同类型订单
|
|
|
ordersService.closeOrderByUser(ordersVO.getUserId(), productVO.getPlatform());
|
|
|
+ if (emailFlag) {
|
|
|
+ log.info("用户订阅或支付成功,发送订阅邮件");
|
|
|
+ EmailSendBO bo = new EmailSendBO();
|
|
|
+ bo.setToEmail(userInfoVO.getEmail());
|
|
|
+ //设置事件
|
|
|
+ if (ordersVO.getDiscountType() == 2) {
|
|
|
+ bo.setUseEvent(EmailCodeTypeEnum.MEMBER_UPGRADE_SUCCESS.value());
|
|
|
+ } else {
|
|
|
+ bo.setUseEvent(EmailCodeTypeEnum.MEMBER_BUY_SUCCESS.value());
|
|
|
+ }
|
|
|
+ //设置title
|
|
|
+ Map<String,String> titleMap = new HashMap<>();
|
|
|
+ bo.setSendTitleContent(titleMap);
|
|
|
+ //设置内容
|
|
|
+ Map<String,String> contentMap = new HashMap<>();
|
|
|
+ contentMap.put("@plan@", productVO.getProductName());
|
|
|
+ Date date = new Date();
|
|
|
+ // 创建 SimpleDateFormat 对象,指定日期格式
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
|
|
|
+ // 格式化当前日期
|
|
|
+ String formattedDate = sdf.format(date);
|
|
|
+ contentMap.put("@date@",formattedDate);
|
|
|
+ String price = ObjectUtils.isNotEmpty(ordersVO.getReducedPrice())? ordersVO.getReducedPrice().toEngineeringString() : ordersVO.getPrice().toEngineeringString();
|
|
|
+ contentMap.put("@payPrice@", price);
|
|
|
+ contentMap.put("@renewPrice@", productVO.getPrice().toEngineeringString());
|
|
|
+ bo.setSendContent(contentMap);
|
|
|
+ log.info("获取发票");
|
|
|
+ String invoiceHtml = null;
|
|
|
+ try {
|
|
|
+ invoiceHtml = new String(StreamUtils.copyToByteArray(this.getClass().getClassLoader().getResourceAsStream("templates/invoice_member.html")), StandardCharsets.UTF_8);
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error(e.getMessage());
|
|
|
+ }
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("Name", userInfoVO.getEmail());
|
|
|
+ map.put("email", userInfoVO.getEmail());
|
|
|
+ map.put("purchasedDate", formattedDate);
|
|
|
+ map.put("orderNumber", ordersVO.getTradeNo());
|
|
|
+ map.put("invoiceDate", formattedDate);
|
|
|
+ map.put("invoiceNumber", ordersVO.getInvoiceNo());
|
|
|
+ map.put("quantity", ordersVO.getPayNumber());
|
|
|
+ map.put("unitPrice", productVO.getPrice().toEngineeringString());
|
|
|
+ String discount = "0";
|
|
|
+ String amount = ordersVO.getPrice().toEngineeringString();
|
|
|
+ if (ordersVO.getReducedPrice() != null) {
|
|
|
+ /*if (ordersVO.getPayNumber() > 0) {
|
|
|
+ BigDecimal totalPrice = productVO.getPrice().multiply(BigDecimal.valueOf(ordersVO.getPayNumber()));
|
|
|
+ discount = totalPrice.subtract(ordersVO.getReducedPrice()).toEngineeringString();
|
|
|
+ } else {
|
|
|
+ discount = productVO.getPrice().subtract(ordersVO.getReducedPrice()).toEngineeringString();
|
|
|
+ }*/
|
|
|
+ discount = productVO.getPrice().subtract(ordersVO.getReducedPrice()).toEngineeringString();
|
|
|
+ amount = ordersVO.getReducedPrice().toEngineeringString();
|
|
|
+ }
|
|
|
+ map.put("discount", discount);
|
|
|
+ map.put("amount", amount);
|
|
|
+ map.put("total", amount);
|
|
|
+ log.info("发票html内容填充map:{}", map);
|
|
|
+ // 生成替换内容后的发票
|
|
|
+ String htmlStr = TemplatesUtil.replaceStringUsingFreeMarker(invoiceHtml, map);
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
+ // 封装表单数据
|
|
|
+ MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
|
|
|
+ paramMap.add("html", htmlStr);
|
|
|
+ HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(paramMap, headers);
|
|
|
+ // 发送POST请求,html转pdf
|
|
|
+ Map postForObjectMap = restTemplate.postForObject(htmlToPdfUrl, request, Map.class);
|
|
|
+ String invoiceFileUrl = postForObjectMap.get("url").toString();
|
|
|
+ log.info("发票文件地址:{}", invoiceFileUrl);
|
|
|
+ bo.setFileUrl(invoiceFileUrl);
|
|
|
+ bo.setFileName("invoice.pdf");
|
|
|
+ log.info("发送订阅邮件");
|
|
|
+ emailApi.sendEmail(bo);
|
|
|
+ }
|
|
|
break;
|
|
|
case "2":
|
|
|
// 支付失败,有延时队列暂不处理
|