Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	miniapp/src/main/java/com/kym/miniapp/jobs/StartChargeDelayJob.java
#	miniapp/src/main/java/com/kym/miniapp/jobs/StopChargeDelayJob.java
zuypeng 2 gadi atpakaļ
vecāks
revīzija
dea18e4c1a
22 mainītis faili ar 433 papildinājumiem un 69 dzēšanām
  1. 1 1
      admin-web/src/views/admin/index.vue
  2. 10 0
      admin/src/main/java/com/kym/admin/controller/ConnectorInfoController.java
  3. 0 20
      admin/src/main/java/com/kym/admin/controller/EquipmentInfoController.java
  4. 24 3
      admin/src/main/java/com/kym/admin/controller/FinanceController.java
  5. 112 0
      entity/src/main/java/com/kym/entity/admin/InvoiceDetail.java
  6. 18 0
      entity/src/main/java/com/kym/entity/admin/queryParams/InvoiceDetailQueryParam.java
  7. 28 0
      entity/src/main/java/com/kym/entity/typehandle/InvoiceDetailBuyerInformationTypeHandle.java
  8. 28 0
      entity/src/main/java/com/kym/entity/typehandle/InvoiceDetailSellerInformationTypeHandle.java
  9. 2 2
      entity/src/main/java/com/kym/entity/wechat/FaPiao.java
  10. 4 4
      entity/src/main/java/com/kym/entity/wechat/FapiaoApplications.java
  11. 2 2
      entity/src/main/java/com/kym/entity/wechat/InvoiceBaseInfo.java
  12. 16 0
      mapper/src/main/java/com/kym/mapper/admin/InvoiceDetailMapper.java
  13. 31 0
      mapper/src/main/resources/mappers/admin/InvoiceDetailMapper.xml
  14. 2 3
      miniapp/src/main/java/com/kym/miniapp/jobs/StartChargeDelayJob.java
  15. 8 7
      miniapp/src/main/java/com/kym/miniapp/jobs/StopChargeDelayJob.java
  16. 3 0
      service/src/main/java/com/kym/service/admin/ConnectorInfoService.java
  17. 0 1
      service/src/main/java/com/kym/service/admin/EquipmentInfoService.java
  18. 19 0
      service/src/main/java/com/kym/service/admin/InvoiceDetailService.java
  19. 41 0
      service/src/main/java/com/kym/service/admin/impl/ConnectorInfoServiceImpl.java
  20. 0 24
      service/src/main/java/com/kym/service/admin/impl/EquipmentInfoServiceImpl.java
  21. 33 0
      service/src/main/java/com/kym/service/admin/impl/InvoiceDetailServiceImpl.java
  22. 51 2
      service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

+ 1 - 1
admin-web/src/views/admin/index.vue

@@ -424,7 +424,7 @@ const initEchartsResize = () => {
 };
 
 const loadCurrentEquipmentStatus = () => {
-  $get(`equipment/statEquipmentStatus`, {stationId: state.currentStationId}).then((res: any) => {
+  $get(`connector/statConnectorStatus`, {stationId: state.currentStationId}).then((res: any) => {
     console.log(res)
     initPieChart(res || {});
   })

+ 10 - 0
admin/src/main/java/com/kym/admin/controller/ConnectorInfoController.java

@@ -41,5 +41,15 @@ public class ConnectorInfoController {
         return R.success(res);
     }
 
+    /**
+     * 统计充电桩状态
+     *
+     * @return
+     */
+    @GetMapping("/statConnectorStatus")
+    R<?> statEquipment(String stationId) {
+        return R.success(connectorInfoService.statConnectorStatus(stationId));
+    }
+
 
 }

+ 0 - 20
admin/src/main/java/com/kym/admin/controller/EquipmentInfoController.java

@@ -1,8 +1,5 @@
 package com.kym.admin.controller;
 
-import com.kym.common.R;
-import com.kym.service.admin.EquipmentInfoService;
-import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -18,21 +15,4 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/equipment")
 public class EquipmentInfoController {
 
-    private final EquipmentInfoService equipmentInfoService;
-
-    public EquipmentInfoController(EquipmentInfoService equipmentInfoService) {
-        this.equipmentInfoService = equipmentInfoService;
-    }
-
-
-    /**
-     * 统计充电桩状态
-     *
-     * @return
-     */
-    @GetMapping("/statEquipmentStatus")
-    R<?> statEquipment(String stationId) {
-        return R.success(equipmentInfoService.statEquipmentStatus(stationId));
-    }
-
 }

+ 24 - 3
admin/src/main/java/com/kym/admin/controller/FinanceController.java

@@ -3,7 +3,9 @@ package com.kym.admin.controller;
 import com.kym.common.R;
 import com.kym.common.annotation.SysLog;
 import com.kym.entity.admin.queryParams.CommonQueryParam;
+import com.kym.entity.admin.queryParams.InvoiceDetailQueryParam;
 import com.kym.entity.admin.queryParams.InvoiceQueryParam;
+import com.kym.service.admin.InvoiceDetailService;
 import com.kym.service.miniapp.InvoiceService;
 import com.kym.service.miniapp.RefundLogService;
 import com.kym.service.wechat.WxPayService;
@@ -23,11 +25,13 @@ public class FinanceController {
     private final RefundLogService refundLogService;
 
     private final InvoiceService invoiceService;
+    private final InvoiceDetailService invoiceDetailService;
 
-    public FinanceController(WxPayService wxPayService, RefundLogService refundLogService, InvoiceService invoiceService) {
+    public FinanceController(WxPayService wxPayService, RefundLogService refundLogService, InvoiceService invoiceService, InvoiceDetailService invoiceDetailService) {
         this.wxPayService = wxPayService;
         this.refundLogService = refundLogService;
         this.invoiceService = invoiceService;
+        this.invoiceDetailService = invoiceDetailService;
     }
 
     @SysLog("退款申请列表")
@@ -44,7 +48,7 @@ public class FinanceController {
     }
 
     @GetMapping("/getUserTitle/{applyId}")
-    Object getUserTitle(@PathVariable String applyId){
+    Object getUserTitle(@PathVariable String applyId) {
         return wxPayService.userTitle(applyId);
     }
 
@@ -74,12 +78,29 @@ public class FinanceController {
 
     /**
      * 取消申请发票,发票抬头填写页关闭事件调用
+     *
      * @return
      */
     @GetMapping("/cancelApplyInvoice/{invoiceId}")
-    R<?> cancelApplyInvoice(@PathVariable String invoiceId){
+    R<?> cancelApplyInvoice(@PathVariable String invoiceId) {
         invoiceService.cancelApplyInvoice(invoiceId);
         return R.success();
     }
 
+    /**
+     * 查询发票
+     */
+    @GetMapping("/getInvoice/{applyId}")
+    R<?> getInvoice(@PathVariable String applyId) {
+        return R.success(wxPayService.queryFapiao(applyId));
+    }
+
+
+    /**
+     * 发票详情
+     */
+    @GetMapping("/listInvoiceDetail")
+    R<?> listInvoiceDetail(@ModelAttribute InvoiceDetailQueryParam params) {
+        return R.success(invoiceDetailService.listInvoiceDetail(params));
+    }
 }

+ 112 - 0
entity/src/main/java/com/kym/entity/admin/InvoiceDetail.java

@@ -0,0 +1,112 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.kym.entity.BaseEntity;
+import com.kym.entity.typehandle.InvoiceDetailBuyerInformationTypeHandle;
+import com.kym.entity.typehandle.InvoiceDetailSellerInformationTypeHandle;
+import com.kym.entity.wechat.FaPiao;
+import com.kym.entity.wechat.FapiaoApplications;
+import com.kym.entity.wechat.InvoiceBaseInfo;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 发票详情表
+ * </p>
+ *
+ * @author skyline
+ * @since 2024-03-19
+ */
+@Getter
+@Setter
+@TableName(value = "t_invoice_detail",autoResultMap = true)
+@Accessors(chain = true)
+public class InvoiceDetail extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 微信发票申请id
+     */
+    private String applyId;
+
+    /**
+     * 开票时间
+     */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime fapiaoTime;
+
+    /**
+     * 发票状态:ISSUE_ACCEPTED-开票申请已受理,ISSUED-发票已开具,REVERSE_ACCEPTED-冲红申请已受理,REVERSED-发票已冲红
+     */
+    private String status;
+
+    /**
+     * 蓝票
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private FapiaoApplications.FapiaoInfo blueFapiao;
+
+    /**
+     * 红票
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Object redFapiao;
+
+    /**
+     * 卡包信息
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Object cardInformation;
+
+    /**
+     * 总开票金额(分)
+     */
+    private Integer totalAmount;
+
+    /**
+     * 税额(分)
+     */
+    private Integer taxAmount;
+
+    /**
+     * 不含税金额(分)
+     */
+    private Integer amount;
+
+    /**
+     * 售卖方信息
+     */
+    @TableField(typeHandler = InvoiceDetailSellerInformationTypeHandle.class)
+    private InvoiceBaseInfo.SellerInfo sellerInformation;
+
+    /**
+     * 购买方信息
+     */
+    @TableField(typeHandler = InvoiceDetailBuyerInformationTypeHandle.class)
+    private FaPiao.BuyerInformation buyerInformation;
+
+    /**
+     * 扩展信息
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Object extraInformation;
+
+    /**
+     * 发票明细
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Object items;
+
+    /**
+     * 备注
+     */
+    private String remark;
+}

+ 18 - 0
entity/src/main/java/com/kym/entity/admin/queryParams/InvoiceDetailQueryParam.java

@@ -0,0 +1,18 @@
+package com.kym.entity.admin.queryParams;
+
+import com.kym.entity.common.PageParams;
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description 发票详情查询参数
+ * @date 2023-08-22 18:56
+ */
+@Data
+public class InvoiceDetailQueryParam extends PageParams {
+    /**
+     * 发票申请id
+     */
+    private String applyId;
+
+}

+ 28 - 0
entity/src/main/java/com/kym/entity/typehandle/InvoiceDetailBuyerInformationTypeHandle.java

@@ -0,0 +1,28 @@
+package com.kym.entity.typehandle;
+
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.kym.entity.wechat.FaPiao;
+
+import java.io.IOException;
+
+/**
+ * @author skyline
+ * @description 发票中购买方信息序列化处理
+ * https://github.com/baomidou/mybatis-plus-samples/blob/master/mybatis-plus-sample-typehandler/src/main/java/com/baomidou/mybatisplus/samples/typehandler/WalletListTypeHandler.java
+ */
+public class InvoiceDetailBuyerInformationTypeHandle extends JacksonTypeHandler {
+    public InvoiceDetailBuyerInformationTypeHandle(Class<?> type) {
+        super(type);
+    }
+
+    @Override
+    protected Object parse(String json) {
+        try {
+            return getObjectMapper().readValue(json, new TypeReference<FaPiao.BuyerInformation>() {
+            });
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 28 - 0
entity/src/main/java/com/kym/entity/typehandle/InvoiceDetailSellerInformationTypeHandle.java

@@ -0,0 +1,28 @@
+package com.kym.entity.typehandle;
+
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.kym.entity.wechat.InvoiceBaseInfo;
+
+import java.io.IOException;
+
+/**
+ * @author skyline
+ * @description 发票中购买方信息序列化处理
+ * https://github.com/baomidou/mybatis-plus-samples/blob/master/mybatis-plus-sample-typehandler/src/main/java/com/baomidou/mybatisplus/samples/typehandler/WalletListTypeHandler.java
+ */
+public class InvoiceDetailSellerInformationTypeHandle extends JacksonTypeHandler {
+    public InvoiceDetailSellerInformationTypeHandle(Class<?> type) {
+        super(type);
+    }
+
+    @Override
+    protected Object parse(String json) {
+        try {
+            return getObjectMapper().readValue(json, new TypeReference<InvoiceBaseInfo.SellerInfo>() {
+            });
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 2 - 2
entity/src/main/java/com/kym/entity/wechat/FaPiao.java

@@ -52,7 +52,7 @@ public class FaPiao {
      */
     @Data
     @Accessors(chain = true)
-    public static class BuyerInformation{
+    public static class BuyerInformation {
         /**
          * INDIVIDUAL: 个人
          * ORGANIZATION: 单位
@@ -105,7 +105,7 @@ public class FaPiao {
 
     @Data
     @Accessors(chain = true)
-    public static class FaPiaoInfomation{
+    public static class FaPiaoInfomation {
 
         /**
          * 商户发票单号,唯一标识一张要开具的发票。只能是字母、数字、中划线-、下划线_、竖线|、星号*

+ 4 - 4
entity/src/main/java/com/kym/entity/wechat/FapiaoApplications.java

@@ -15,7 +15,7 @@ public class FapiaoApplications {
     private List<FapiaoEntity> fapiao_information;
 
     @Data
-    public class FapiaoEntity {
+    public static class FapiaoEntity {
         private String fapiao_id;
         /**
          * ISSUE_ACCEPTED: 开票申请已受理
@@ -75,7 +75,7 @@ public class FapiaoApplications {
     }
 
     @Data
-    public class FapiaoInfo {
+    public static class FapiaoInfo {
         /**
          * 发票代码
          */
@@ -100,7 +100,7 @@ public class FapiaoApplications {
     }
 
     @Data
-    public class CardInfo {
+    public static class CardInfo {
         private String card_appid;
         private String card_openid;
         private String card_id;
@@ -115,7 +115,7 @@ public class FapiaoApplications {
     }
 
     @Data
-    public class FapiaoItem {
+    public static class FapiaoItem {
         /**
          * 税局侧规定的货物或应税劳务、服务税收分类编码
          */

+ 2 - 2
entity/src/main/java/com/kym/entity/wechat/InvoiceBaseInfo.java

@@ -19,7 +19,7 @@ public class InvoiceBaseInfo {
 
     @Data
     @Accessors(chain = true)
-    class SellerInfo{
+    public static class SellerInfo{
 
         /**
          * 销售方名称
@@ -55,7 +55,7 @@ public class InvoiceBaseInfo {
 
     @Data
     @Accessors(chain = true)
-    class ExtraInfo{
+    public static class ExtraInfo{
 
         /**
          * 收款人

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/InvoiceDetailMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.InvoiceDetail;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 发票详情表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2024-03-19
+ */
+public interface InvoiceDetailMapper extends BaseMapper<InvoiceDetail> {
+
+}

+ 31 - 0
mapper/src/main/resources/mappers/admin/InvoiceDetailMapper.xml

@@ -0,0 +1,31 @@
+<?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.kym.mapper.admin.InvoiceDetailMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.InvoiceDetail">
+        <result column="id" property="id" />
+        <result column="apply_id" property="applyId" />
+        <result column="fapiao_time" property="fapiaoTime" />
+        <result column="status" property="status" />
+        <result column="blue_fapiao" property="blueFapiao" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
+        <result column="red_fapiao" property="redFapiao" />
+        <result column="card_information" property="cardInformation" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
+        <result column="total_amount" property="totalAmount" />
+        <result column="tax_amount" property="taxAmount" />
+        <result column="amount" property="amount" />
+        <result column="seller_information" property="sellerInformation" typeHandler="com.kym.entity.typehandle.InvoiceDetailSellerInformationTypeHandle" />
+        <result column="buyer_information" property="buyerInformation" typeHandler="com.kym.entity.typehandle.InvoiceDetailBuyerInformationTypeHandle" />
+        <result column="extra_information" property="extraInformation" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
+        <result column="items" property="items" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
+        <result column="remark" property="remark" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id,apply_id, fapiao_time, status, blue_fapiao, red_fapiao, card_information, total_amount, tax_amount, amount, seller_information, buyer_information, extra_information, items, remark,create_time,update_time
+    </sql>
+
+</mapper>

+ 2 - 3
miniapp/src/main/java/com/kym/miniapp/jobs/StartChargeDelayJob.java

@@ -14,7 +14,6 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.context.event.EventListener;
-import org.springframework.core.annotation.Order;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
@@ -53,7 +52,7 @@ public class StartChargeDelayJob implements DelayService<DelayChargeOrder> {
 
     @DS("db-miniapp")
     // 这里不能使用@PostConstruct,在初始化完成后, bean 进入增强阶段, 所以这个阶段的任何AOP都是无效的,https://www.cnblogs.com/eternityz/p/15330069.html
-    @EventListener(classes = {ContextRefreshedEvent.class},id="StartChargeDelayJob")
+    @EventListener(classes = {ContextRefreshedEvent.class}, id = "StartChargeDelayJob")
     @Async
     public void init() {
         // 队列加载所有充电状态为预约中的订单,按照开始时间排序
@@ -81,7 +80,7 @@ public class StartChargeDelayJob implements DelayService<DelayChargeOrder> {
         while (true) {
             executor.execute(() -> {
                 ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> null); // 初始化为空值,避免使用new ThreadLocal()
-                log.info("预约充电订单处理线程:{}", Thread.currentThread().getName());
+                log.info("预约启动充电处理线程:{}", Thread.currentThread().getName());
                 DelayedItem<DelayChargeOrder> delayedItem;
 
                 try {

+ 8 - 7
miniapp/src/main/java/com/kym/miniapp/jobs/StopChargeDelayJob.java

@@ -14,7 +14,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.context.event.EventListener;
-import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import java.util.concurrent.DelayQueue;
@@ -51,13 +51,14 @@ public class StopChargeDelayJob implements DelayService<DelayChargeOrder> {
 
     @DS("db-miniapp")
     // 这里不能使用@PostConstruct,在初始化完成后, bean 进入增强阶段, 所以这个阶段的任何AOP都是无效的,https://www.cnblogs.com/eternityz/p/15330069.html
-    @EventListener(classes = {ContextRefreshedEvent.class},id="StopChargeDelayJob")
+    @EventListener(classes = {ContextRefreshedEvent.class}, id = "StopChargeDelayJob")
+    @Async
     public void init() {
-        log.info("StopChargeDelayJob  init>>>>>>>");
-        // 队列加载所有充电状态为预约中且有结束时间的订单,按照开始时间排序
+
+        // 队列加载所有充电状态为预约中且有结束时间的订单,按照结束时间排序
         var orderList = chargeOrderService.lambdaQuery()
-                .eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中)
-                .eq(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_是)
+                .eq(ChargeOrder::getOrderStatus, ChargeOrder.ORDER_STATUS_未知)
+                .in(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中, ChargeOrder.CHARGE_STATUS_启动中, ChargeOrder.CHARGE_STATUS_充电中)
                 .isNotNull(ChargeOrder::getEndTime)
                 .orderByAsc(ChargeOrder::getEndTime)
                 .list();
@@ -80,7 +81,7 @@ public class StopChargeDelayJob implements DelayService<DelayChargeOrder> {
         while (true) {
             executor.execute(() -> {
                 ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> null); // 初始化为空值,避免使用new ThreadLocal()
-                log.info("预约停止充电订单处理线程:{}", Thread.currentThread().getName());
+                log.info("预约停止充电处理线程:{}", Thread.currentThread().getName());
                 DelayedItem<DelayChargeOrder> delayedItem;
 
                 try {

+ 3 - 0
service/src/main/java/com/kym/service/admin/ConnectorInfoService.java

@@ -6,6 +6,8 @@ import com.kym.entity.admin.queryParams.EquipmentQueryParam;
 import com.kym.entity.admin.vo.ConnectorInfoVo;
 import com.kym.entity.common.PageBean;
 
+import java.util.Map;
+
 /**
  * <p>
  * 充电桩接口(枪)信息 服务类
@@ -17,4 +19,5 @@ import com.kym.entity.common.PageBean;
 public interface ConnectorInfoService extends MPJBaseService<ConnectorInfo> {
     PageBean<ConnectorInfoVo> listConnectors(EquipmentQueryParam params);
 
+    Map<Integer, Long> statConnectorStatus(String stationId);
 }

+ 0 - 1
service/src/main/java/com/kym/service/admin/EquipmentInfoService.java

@@ -15,5 +15,4 @@ import java.util.Map;
  */
 public interface EquipmentInfoService extends MPJBaseService<EquipmentInfo> {
 
-    Map<Integer, Long> statEquipmentStatus(String stationId);
 }

+ 19 - 0
service/src/main/java/com/kym/service/admin/InvoiceDetailService.java

@@ -0,0 +1,19 @@
+package com.kym.service.admin;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.kym.entity.admin.InvoiceDetail;
+import com.kym.entity.admin.queryParams.InvoiceDetailQueryParam;
+import com.kym.entity.common.PageBean;
+
+/**
+ * <p>
+ * 发票详情表 服务类
+ * </p>
+ *
+ * @author skyline
+ * @since 2024-03-19
+ */
+public interface InvoiceDetailService extends IService<InvoiceDetail> {
+
+    PageBean<InvoiceDetail> listInvoiceDetail(InvoiceDetailQueryParam params);
+}

+ 41 - 0
service/src/main/java/com/kym/service/admin/impl/ConnectorInfoServiceImpl.java

@@ -2,20 +2,27 @@ package com.kym.service.admin.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.github.pagehelper.PageHelper;
 import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.kym.common.utils.CommUtil;
 import com.kym.entity.admin.ConnectorInfo;
+import com.kym.entity.admin.EquipmentInfo;
 import com.kym.entity.admin.queryParams.EquipmentQueryParam;
 import com.kym.entity.admin.vo.ConnectorInfoVo;
 import com.kym.entity.common.PageBean;
+import com.kym.entity.miniapp.ChargeOrder;
 import com.kym.mapper.admin.ConnectorInfoMapper;
 import com.kym.service.admin.ConnectorInfoService;
 import com.kym.service.cache.KymCache;
+import com.kym.service.miniapp.ChargeOrderService;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 import static com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotNull;
 
@@ -30,6 +37,13 @@ import static com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotNull;
 @Service
 @DS("db-admin")
 public class ConnectorInfoServiceImpl extends MPJBaseServiceImpl<ConnectorInfoMapper, ConnectorInfo> implements ConnectorInfoService {
+
+    private final ChargeOrderService chargeOrderService;
+
+    public ConnectorInfoServiceImpl(ChargeOrderService chargeOrderService) {
+        this.chargeOrderService = chargeOrderService;
+    }
+
     @Override
     public PageBean<ConnectorInfoVo> listConnectors(EquipmentQueryParam params) {
         // 判断数据权限
@@ -63,4 +77,31 @@ public class ConnectorInfoServiceImpl extends MPJBaseServiceImpl<ConnectorInfoMa
         page.setList(res);
         return page;
     }
+
+    @Override
+    public Map<Integer, Long> statConnectorStatus(String stationId) {
+        if (CommUtil.null2Long(stationId) <= 0) {
+            // 判断数据权限
+            stationId = KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()) == null ? null : KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()).get(0);
+        }
+        // 获取指定站点下的充电桩
+        var connectorInfos = lambdaQuery().eq(isNotNull(stationId), ConnectorInfo::getStationId, stationId).list();
+        // 根据状态进行分组
+
+        // 预约中的设备
+        // 手动切换数据源
+        DynamicDataSourceContextHolder.push("db-miniapp");
+        // 查询预约中的订单,按照站点id分组并对connectorId去重计数
+        var orderInfos = chargeOrderService.lambdaQuery()
+                .select(ChargeOrder::getConnectorId)
+                .eq(ChargeOrder::getStationId, stationId)
+                .eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中)
+                .list().stream().filter(CommUtil.distinctByKey(ChargeOrder::getConnectorId)).count();
+
+        DynamicDataSourceContextHolder.poll();
+        var res = connectorInfos.stream().collect(Collectors.groupingBy(ConnectorInfo::getStatus, Collectors.counting()));
+        res.put(EquipmentInfo.SERVICE_STATUS_已连接, res.getOrDefault(EquipmentInfo.SERVICE_STATUS_已连接, 0L) - orderInfos);
+        res.put(EquipmentInfo.SERVICE_STATUS_预约中, orderInfos);
+        return res;
+    }
 }

+ 0 - 24
service/src/main/java/com/kym/service/admin/impl/EquipmentInfoServiceImpl.java

@@ -1,23 +1,17 @@
 package com.kym.service.admin.impl;
 
-import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.github.yulichang.base.MPJBaseServiceImpl;
-import com.kym.common.utils.CommUtil;
 import com.kym.entity.admin.EquipmentInfo;
 import com.kym.mapper.admin.EquipmentInfoMapper;
-import com.kym.service.admin.ConnectorInfoService;
 import com.kym.service.admin.EquipmentInfoService;
 import com.kym.service.cache.KymCache;
 import jakarta.annotation.PostConstruct;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
 import java.util.stream.Collectors;
 
-import static com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotNull;
-
 /**
  * <p>
  * 充电桩桩体设备 服务实现类
@@ -30,13 +24,6 @@ import static com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotNull;
 @DS("db-admin")
 public class EquipmentInfoServiceImpl extends MPJBaseServiceImpl<EquipmentInfoMapper, EquipmentInfo> implements EquipmentInfoService {
 
-    private final ConnectorInfoService connectorInfoService;
-
-    public EquipmentInfoServiceImpl(ConnectorInfoService connectorInfoService) {
-        this.connectorInfoService = connectorInfoService;
-    }
-
-
     @PostConstruct
     private void init() {
         // 手动切换数据源
@@ -45,15 +32,4 @@ public class EquipmentInfoServiceImpl extends MPJBaseServiceImpl<EquipmentInfoMa
         DynamicDataSourceContextHolder.poll();
     }
 
-    @Override
-    public Map<Integer, Long> statEquipmentStatus(String stationId) {
-        if (CommUtil.null2Long(stationId) <= 0) {
-            // 判断数据权限
-            stationId = KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()) == null ? null : KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()).get(0);
-        }
-        // 获取指定站点下的充电桩
-        var equipmentInfos = lambdaQuery().eq(isNotNull(stationId), EquipmentInfo::getStationId, stationId).list();
-        // 根据状态进行分组
-        return equipmentInfos.stream().collect(Collectors.groupingBy(EquipmentInfo::getServiceStatus, Collectors.counting()));
-    }
 }

+ 33 - 0
service/src/main/java/com/kym/service/admin/impl/InvoiceDetailServiceImpl.java

@@ -0,0 +1,33 @@
+package com.kym.service.admin.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.PageHelper;
+import com.kym.common.utils.CommUtil;
+import com.kym.entity.admin.InvoiceDetail;
+import com.kym.entity.admin.queryParams.InvoiceDetailQueryParam;
+import com.kym.entity.common.PageBean;
+import com.kym.mapper.admin.InvoiceDetailMapper;
+import com.kym.service.admin.InvoiceDetailService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 发票详情表 服务实现类
+ * </p>
+ *
+ * @author skyline
+ * @since 2024-03-19
+ */
+@Service
+public class InvoiceDetailServiceImpl extends ServiceImpl<InvoiceDetailMapper, InvoiceDetail> implements InvoiceDetailService {
+
+    @Override
+    public PageBean<InvoiceDetail> listInvoiceDetail(InvoiceDetailQueryParam params) {
+        PageHelper.startPage(params.getPageNum(), params.getPageSize());
+        var res = lambdaQuery()
+                .eq(CommUtil.isNotEmptyAndNull(params.getApplyId()), InvoiceDetail::getApplyId, params.getApplyId())
+                .orderByDesc(InvoiceDetail::getFapiaoTime)
+                .list();
+        return new PageBean<>(res);
+    }
+}

+ 51 - 2
service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

@@ -16,10 +16,12 @@ import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.LambadaTools;
 import com.kym.common.utils.OrderUtils;
+import com.kym.entity.admin.InvoiceDetail;
 import com.kym.entity.miniapp.Account;
 import com.kym.entity.miniapp.*;
 import com.kym.entity.wechat.*;
 import com.kym.service.admin.ActivityService;
+import com.kym.service.admin.InvoiceDetailService;
 import com.kym.service.enplus.EnPlusService;
 import com.kym.service.miniapp.*;
 import com.kym.service.wechat.WxPayService;
@@ -107,6 +109,8 @@ public class WxPayServiceImpl implements WxPayService {
 
     private final UserRechargeRightsService userRechargeRightsService;
 
+    private final InvoiceDetailService invoiceDetailService;
+
 
     /**
      * 微信支付专用,支持自动签名验签解密等
@@ -117,7 +121,7 @@ public class WxPayServiceImpl implements WxPayService {
     public WxPayServiceImpl(WxPayConfig conf, WxFapiaoConfig fapiaoConfig, WalletDetailService walletDetailService,
                             PayLogService payLogService, AccountService accountService, ChargeOrderService chargeOrderService,
                             RefundLogService refundLogService, InvoiceService invoiceService, InvoiceTitleService invoiceTitleService,
-                            EnPlusService enPlusService, ActivityService activityService, UserRechargeRightsService userRechargeRightsService) {
+                            EnPlusService enPlusService, ActivityService activityService, UserRechargeRightsService userRechargeRightsService, InvoiceDetailService invoiceDetailService) {
         this.conf = conf;
         this.fapiaoConfig = fapiaoConfig;
         this.walletDetailService = walletDetailService;
@@ -130,6 +134,7 @@ public class WxPayServiceImpl implements WxPayService {
         this.enPlusService = enPlusService;
         this.activityService = activityService;
         this.userRechargeRightsService = userRechargeRightsService;
+        this.invoiceDetailService = invoiceDetailService;
     }
 
     /**
@@ -883,6 +888,31 @@ public class WxPayServiceImpl implements WxPayService {
                 if (!CommUtil.isEmptyOrNull(chargeOrderSeqs)) {
                     chargeOrderService.lambdaUpdate().set(ChargeOrder::getInvoiceStatus, ChargeOrder.INVOICE_STATUS_已开票).in(ChargeOrder::getStartChargeSeq, chargeOrderSeqs).update();
                 }
+                /*
+                 * 销项发票excel数据中需包含:
+                 * 1.开票日期
+                 * 2.购买方名称及税号
+                 * 3.开票明细、金额、税额
+                 * 4.开票优惠明细、金额、税额
+                 * 5.发票状态是否作废或者红冲
+                 */
+                var fapiaoApplications = queryFapiao(invoice.getApplyId());
+                var invoiceDetail = new InvoiceDetail()
+                        .setApplyId(invoice.getApplyId())
+                        .setStatus(InvoiceNotification.FapiaoStatus.ISSUED.name())
+                        .setFapiaoTime(DateUtil.parse(fapiaoApplications.getFapiao_information().get(0).getBlue_fapiao().getFapiao_time(), "yyyy-MM-dd'T'HH:mm:ssXXX").toLocalDateTime())
+                        .setBlueFapiao(fapiaoApplications.getFapiao_information().get(0).getBlue_fapiao())
+                        .setRedFapiao(fapiaoApplications.getFapiao_information().get(0).getRed_fapiao())
+                        .setCardInformation(fapiaoApplications.getFapiao_information().get(0).getCard_information())
+                        .setTotalAmount(fapiaoApplications.getFapiao_information().get(0).getTotal_amount())
+                        .setTaxAmount(fapiaoApplications.getFapiao_information().get(0).getTax_amount())
+                        .setAmount(fapiaoApplications.getFapiao_information().get(0).getAmount())
+                        .setSellerInformation(fapiaoApplications.getFapiao_information().get(0).getSeller_information())
+                        .setBuyerInformation(fapiaoApplications.getFapiao_information().get(0).getBuyer_information())
+                        .setExtraInformation(fapiaoApplications.getFapiao_information().get(0).getExtra_information())
+                        .setItems(fapiaoApplications.getFapiao_information().get(0).getItems());
+                invoiceDetailService.save(invoiceDetail);
+
             } else {
                 LOGGER.error("微信开具发票失败:{}", invoiceNotification);
             }
@@ -962,8 +992,27 @@ public class WxPayServiceImpl implements WxPayService {
         headers.addHeader("Accept", "application/json");
         headers.addHeader("Content-Type", "application/json");
         var res = wxHttpClient.get(headers, fapiaoConfig.getQueryFapiao().formatted(applyId), FapiaoApplications.class);
+
+
+        var fapiaoApplications = res.getServiceResponse();
+        var invoiceDetail = new InvoiceDetail()
+                .setApplyId(applyId)
+                .setStatus(InvoiceNotification.FapiaoStatus.ISSUED.name())
+                .setFapiaoTime(DateUtil.parse(fapiaoApplications.getFapiao_information().get(0).getBlue_fapiao().getFapiao_time(), "yyyy-MM-dd'T'HH:mm:ssXXX").toLocalDateTime())
+                .setBlueFapiao(fapiaoApplications.getFapiao_information().get(0).getBlue_fapiao())
+                .setRedFapiao(fapiaoApplications.getFapiao_information().get(0).getRed_fapiao())
+                .setCardInformation(fapiaoApplications.getFapiao_information().get(0).getCard_information())
+                .setTotalAmount(fapiaoApplications.getFapiao_information().get(0).getTotal_amount())
+                .setTaxAmount(fapiaoApplications.getFapiao_information().get(0).getTax_amount())
+                .setAmount(fapiaoApplications.getFapiao_information().get(0).getAmount())
+                .setSellerInformation(fapiaoApplications.getFapiao_information().get(0).getSeller_information())
+                .setBuyerInformation(fapiaoApplications.getFapiao_information().get(0).getBuyer_information())
+                .setExtraInformation(fapiaoApplications.getFapiao_information().get(0).getExtra_information())
+                .setItems(fapiaoApplications.getFapiao_information().get(0).getItems());
+        invoiceDetailService.save(invoiceDetail);
+
+
         return res.getServiceResponse();
     }
 
-
 }