Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

wanghao 2 месяцев назад
Родитель
Сommit
2ad3ed2b2a

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/account/po/SysUserAccountChangeLog.java

@@ -49,6 +49,7 @@ public class SysUserAccountChangeLog extends BaseModel {
 
     @ExcelProperty("车牌号")
     @Schema(description = "车牌号")
+    @TableField(exist = false)
     private String licenseNo;
 
     @ExcelProperty("操作前金额")
@@ -129,10 +130,12 @@ public class SysUserAccountChangeLog extends BaseModel {
 
     @ExcelProperty("签单时间")
     @Schema(description = "签单时间")
+    @TableField(exist = false)
     private String signTime;
 
     @ExcelProperty("提现时间")
     @Schema(description = "提现时间")
+    @TableField(exist = false)
     private String payTime;
 
     public SysUserAccountChangeLog(){

+ 40 - 0
commons/src/main/java/com/jzg/commons/entity/vo/ChangeLogDetail.java

@@ -0,0 +1,40 @@
+package com.jzg.commons.entity.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+public class ChangeLogDetail implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -4016580596162118096L;
+
+    @Schema(name = "标题")
+    private String title;
+
+    @Schema(name = "时间")
+    private LocalDateTime time;
+
+    // 状态:true-成功, false-失败, null-未完成
+    @Schema(name = "是否勾选")
+    private Boolean show;
+
+    @Schema(name = "审核说明")
+    private String content;
+
+    public ChangeLogDetail(){
+
+    }
+
+    public ChangeLogDetail(String title,LocalDateTime time, Boolean show, String content) {
+        this.title = title;
+        this.time = time;
+        this.show = show;
+        this.content = content;
+    }
+
+}

+ 19 - 0
commons/src/main/java/com/jzg/commons/entity/vo/IncomeAndExpenseList.java

@@ -5,6 +5,7 @@ import lombok.Data;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Data
 public class IncomeAndExpenseList {
@@ -38,4 +39,22 @@ public class IncomeAndExpenseList {
 
     @Schema(description = "驳回原因")
     private String rejectReason;
+
+    @Schema(description = "数据来源")
+    private String source;
+
+    @Schema(description = "付款时间")
+    private LocalDateTime paymentTime;
+
+    @Schema(description = "拒绝付款时间")
+    private LocalDateTime rejectTime;
+
+    @Schema(description = "费用审核状态")
+    private String auditingStatus;
+
+    @Schema(description = "处理进度")
+    private List<ChangeLogDetail> stepList;
+
+
+
 }

+ 6 - 0
commons/src/main/java/com/jzg/commons/entity/vo/IncomeAndExpenseVo.java

@@ -62,5 +62,11 @@ public class IncomeAndExpenseVo {
 
         @Schema(description = "驳回原因")
         private String rejectReason;
+
+        @Schema(description = "数据来源")
+        private String source;
+
+        @Schema(description = "处理进度")
+        private List<ChangeLogDetail> stepList;
     }
 }

+ 12 - 0
commons/src/main/java/com/jzg/commons/util/BigDecimalUtil.java

@@ -23,6 +23,18 @@ public class BigDecimalUtil {
     private BigDecimalUtil() {}
 
 
+    /**
+     *
+     * @author lipf
+     * @date 2026/7/21 9:31
+     */
+    public static boolean biggerZero(BigDecimal amount){
+        if(amount == null){
+            return false;
+        }
+        return amount.compareTo(BigDecimal.ZERO) > 0;
+    }
+
     public static BigDecimal abs(BigDecimal val) {
         if (val == null) {
             return BigDecimal.ZERO;

+ 47 - 50
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerRequestImpl.java

@@ -3,9 +3,9 @@ package com.jzg.quotation.ansheng.crawler.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
+import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.quote.vo.AccidentalDrivingVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.aggregated.*;
@@ -237,31 +237,17 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
         List<AnShengCrawlerNonInsuranceResponse.DutyPremiumDTO> dtoList = new ArrayList<>();
         BigDecimal nonPrice = BigDecimal.ZERO;
         List<QuotationListDTO> quotationList = new ArrayList<>();
-        final int SUCCESS_CODE = 200;
-
         if (CollectionUtil.isNotEmpty(quoteVo.getAccidentalDrivings())) {
             for (AccidentalDrivingVo accidentalDriving : quoteVo.getAccidentalDrivings()) {
                 // 1.组装请求获取附加险
-                AnShengCrawlerGetNonConfigCoveragesRequest coveragesRequest = new AnShengCrawlerGetNonConfigCoveragesRequest(
-                        userDetailResponse.getDepartmentCode(),
-                        accidentalDriving.getParentProductCode(),
-                        accidentalDriving.getProductCode()
-                );
-                AnShengCrawlerNonConfigCoveragesResponse crawlerNonConfigCoveragesResponse =
-                        anShengCrawlerRequestComponent.getNonConfigCoverages(coveragesRequest, httpHeaders);
+                AnShengCrawlerGetNonConfigCoveragesRequest coveragesRequest = new AnShengCrawlerGetNonConfigCoveragesRequest(userDetailResponse.getDepartmentCode(), accidentalDriving.getParentProductCode(), accidentalDriving.getProductCode());
+                AnShengCrawlerNonConfigCoveragesResponse crawlerNonConfigCoveragesResponse = anShengCrawlerRequestComponent.getNonConfigCoverages(coveragesRequest, httpHeaders);
 
                 // 2.保费计算请求
-                AnShengCrawlerCalculatePremiumNonApplyRequest applyRequest = new AnShengCrawlerCalculatePremiumNonApplyRequest(
-                        crawlerNonConfigCoveragesResponse,
-                        userDetailResponse,
-                        accidentalDriving,
-                        quoteVo,
-                        insureAdd,
-                        crawlerCalculatePremiumApply
-                );
+                AnShengCrawlerCalculatePremiumNonApplyRequest applyRequest = new AnShengCrawlerCalculatePremiumNonApplyRequest(crawlerNonConfigCoveragesResponse, userDetailResponse, accidentalDriving, quoteVo, insureAdd, crawlerCalculatePremiumApply);
                 AnShengCrawlerCalculatePremiumNonApplyResponse nonApplyResponse = anShengCrawlerRequestComponent.calculatePremiumNonApply(applyRequest, httpHeaders);
                 // 响应校验
-                if (SUCCESS_CODE != nonApplyResponse.getCode()) {
+                if (HttpResult.ok().getCode() != nonApplyResponse.getCode()) {
                     throw new SystemException(nonApplyResponse.getMessage());
                 }
                 List<AnShengCrawlerCalculatePremiumNonApplyResponse.ContractDTO> contracts = nonApplyResponse.getData().getContracts();
@@ -272,14 +258,13 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
                 AnShengCrawlerCalculatePremiumNonApplyResponse.PolicyBaseDTO policyBase = contract.getPolicyBase();
                 BigDecimal totalAgreePremium = policyBase.getTotalAgreePremium();
 
-                // 对象转换,避免两次JSON来回序列化
-                QuotationListDTO item = JSONObject.parseObject(JSONObject.toJSONString(policyBase),QuotationListDTO.class);
-                quotationList.add(item);
+                QuotationListDTO quotationItem = BeanUtil.copyProperties(policyBase, QuotationListDTO.class);
+                quotationList.add(quotationItem);
 
                 accidentalDriving.setPremium(totalAgreePremium.toPlainString());
                 nonPrice = nonPrice.add(totalAgreePremium);
                 // 责任保费集合赋值
-                dtoList.addAll(JSONArray.parseArray(JSONArray.toJSONString(contract.getPolicyCoverages()), AnShengCrawlerNonInsuranceResponse.DutyPremiumDTO.class));
+                dtoList.addAll(BeanUtil.copyToList(contract.getPolicyCoverages(), AnShengCrawlerNonInsuranceResponse.DutyPremiumDTO.class));
             }
         }
         anShengCrawlerNonInsuranceResponse.setFcxPrice(nonPrice);
@@ -332,9 +317,9 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
             contract.setPolicyAttachments(imagesInfo);
         });
         Map<String, Object> stringObjectMap = BeanUtil.beanToMap(applicationRequest);
-        //   存在非车险
-        if (!applicationRequest.getContracts().get(0).getQuotationList().isEmpty()){
-            stringObjectMap = AnShengCrawlerNonContractsBuild.build(applicationRequest,stringObjectMap);
+        //   存在非车险
+        if (hasNonAutoContracts(applicationRequest)) {
+            stringObjectMap = AnShengCrawlerNonContractsBuild.build(applicationRequest, stringObjectMap);
         }
         log.info("安盛核保参数:{}", JSONObject.toJSONString(applicationRequest));
         // 核保
@@ -371,6 +356,17 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
 
     }
 
+
+    private boolean hasNonAutoContracts(AnShengCrawlerApplyApplicationRequest request) {
+        return Optional.ofNullable(request)
+                .map(AnShengCrawlerApplyApplicationRequest::getContracts)
+                .filter(contracts -> !contracts.isEmpty())
+                .map(contracts -> contracts.get(0))
+                .map(AnShengCrawlerApplyApplicationRequest.ContractsDTO::getQuotationList)
+                .map(quotations -> !quotations.isEmpty())
+                .orElse(false);
+    }
+
     /**
      * 循环重试获取支付链接
      * @param paymentLinkVo 请求参数
@@ -673,32 +669,33 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
         if (CollectionUtils.isEmpty(targetPolicyNos)) {
             return "";
         }
-        StringBuilder reasonBuilder = new StringBuilder();
         Set<String> addedReasons = new HashSet<>();
-        for (String policyNo : targetPolicyNos) {
-            AnShengCrawlerSaleSlipRequest request = new AnShengCrawlerSaleSlipRequest(policyNo);
-            AnShengCrawlerPolicyResponse response = anShengCrawlerRequestComponent.getSaleSlip(request, httpHeaders);
-            if (response == null || response.getData() == null || response.getData().getContract() == null || CollectionUtils.isEmpty(response.getData().getContract().getUnderwriteInfos())) {
-                continue;
-            }
-            List<AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo> underwriteInfos = response.getData().getContract().getUnderwriteInfos();
-            for (AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo underwriteInfo : underwriteInfos) {
-                if (!StringUtils.equals("0", underwriteInfo.getUnderwriteMark())) {
-                    continue;
-                }
-                List<AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo.UnderwriteOpinion> opinions = underwriteInfo.getUnderwriteOpinions();
-                if (CollectionUtils.isEmpty(opinions)) {
-                    continue;
-                }
-                for (AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo.UnderwriteOpinion opinion : opinions) {
-                    String desc = opinion.getUnderwriteOpinionDesc();
-                    if (StringUtils.isNotBlank(desc) && addedReasons.add(desc)) {
-                        reasonBuilder.append(desc);
-                    }
-                }
-            }
-        }
+        StringBuilder reasonBuilder = new StringBuilder();
+        targetPolicyNos.forEach(policyNo ->
+                Optional.ofNullable(anShengCrawlerRequestComponent.getSaleSlip(
+                                new AnShengCrawlerSaleSlipRequest(policyNo), httpHeaders))
+                        .map(AnShengCrawlerPolicyResponse::getData)
+                        .map(AnShengCrawlerPolicyResponse.DataVo::getContract)
+                        .map(AnShengCrawlerPolicyResponse.DataVo.Contract::getUnderwriteInfos)
+                        .orElse(Collections.emptyList())
+                        .stream()
+                        .filter(this::isFailureUnderwrite)
+                        .map(AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo::getUnderwriteOpinions)
+                        .filter(CollectionUtils::isNotEmpty)
+                        .flatMap(List::stream)
+                        .map(AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo.UnderwriteOpinion::getUnderwriteOpinionDesc)
+                        .filter(StringUtils::isNotBlank)
+                        .forEach(desc -> {
+                            if (addedReasons.add(desc)) {
+                                reasonBuilder.append(desc).append("\n");
+                            }
+                        })
+        );
         return reasonBuilder.toString();
     }
 
+    private boolean isFailureUnderwrite(AnShengCrawlerPolicyResponse.DataVo.Contract.UnderwriteInfo underwriteInfo) {
+        return underwriteInfo != null && StringUtils.equals("0", underwriteInfo.getUnderwriteMark());
+    }
+
 }

+ 2 - 2
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/request/GuoRenCrawlerCreateOrderRequest.java

@@ -126,7 +126,7 @@ public class GuoRenCrawlerCreateOrderRequest implements Serializable {
         insuredListDTO.setInsuredType("1");
         insuredListDTO.setCertiStartDate(insuredPersonInfo.getIdentifyValidDate());
         insuredListDTO.setCertiEndDate("");
-        insuredListDTO.setCertiValidity("2");
+        insuredListDTO.setCertiValidity("4");
         insuredListDTO.setCountryCode("156");
         insuredListDTO.setCountryName("中国");
         insuredListDTO.setCustomerRelations("01");
@@ -200,7 +200,7 @@ public class GuoRenCrawlerCreateOrderRequest implements Serializable {
         orderAppl.setContactMobile(null);
         orderAppl.setCertiStartDate(policyHolderInfo.getIdentifyValidDate());
         orderAppl.setCertiEndDate("");
-        orderAppl.setCertiValidity("2");
+        orderAppl.setCertiValidity("4");
         orderAppl.setCountryCode("156");
         orderAppl.setCountryName("中国");
         orderAppl.setAddrProvince(policyHolderInfo.getProvince());

+ 53 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/service/impl/GuoRenCrawlerRequestImpl.java

@@ -193,6 +193,8 @@ public class GuoRenCrawlerRequestImpl implements GuoRenCrawlerRequest {
         } else if (calculationPremium.getResultCode() == 1) {
             return GuoRenCrawlerQuoteResultsVoBuild.buildFailQuoteResultsVo(quoteVo, calculationPremium);
         }
+        // 报价成功后,根据保司返回信息更新交强险和商业险的起保日期和终保日期
+        updateInsuranceDates(quoteVo, calculationPremium.getData());
         // 驾意险(非车险)处理:查询 → 校验 → 投保
         String niPolicyNumber = null;
         GuoRenCrawlerCreateOrderRequest createOrderRequest = null;
@@ -221,7 +223,6 @@ public class GuoRenCrawlerRequestImpl implements GuoRenCrawlerRequest {
             }
         }
 
-
         // 投保验证码处理
         GuoRenCrawlerCalculationPremiumData calculationPremiumData = guoRenCrawlerQuoteProcessService.insuranceVerificationCodeProcessing(crawlerCalculationPremiumRequest, calculationPremium.getData(), headers);
         // 保存投保单号
@@ -239,6 +240,57 @@ public class GuoRenCrawlerRequestImpl implements GuoRenCrawlerRequest {
         return guoRenCrawlerRequestComponent.writeBackAddress(addressNew, headers);
     }
 
+    /**
+     * 报价成功后,根据保司返回的报价信息更新交强险和商业险的起保日期和终保日期
+     * 从 prptitemkindList 中取第一个险种的日期作为保险起止日期
+     *
+     * @param quoteVo 报价单
+     * @param data    保费计算结果数据
+     */
+    private void updateInsuranceDates(QuoteVo quoteVo, GuoRenCrawlerCalculationPremiumData data) {
+        if (data == null) {
+            return;
+        }
+        // 更新交强险起保/终保日期
+        if (data.getCi() != null && CollUtil.isNotEmpty(data.getCi().getPrptitemkindList())) {
+            GuoRenCrawlerCalculationPremiumData.CiDTO.PrptitemkindListDTO firstKind = data.getCi().getPrptitemkindList().get(0);
+            if (firstKind.getStartDate() != null && quoteVo.getCiRiskInfoVo() != null) {
+                String ciStartDateTime = buildDateTimeString(firstKind.getStartDate(),
+                        firstKind.getStartHour(), 0);
+                String ciEndDateTime = buildDateTimeString(firstKind.getEndDate(),
+                        firstKind.getEndHour(), 0);
+                quoteVo.getCiRiskInfoVo().setStartDate(ciStartDateTime);
+                quoteVo.getCiRiskInfoVo().setEndDate(ciEndDateTime);
+            }
+        }
+        // 更新商业险起保/终保日期
+        if (data.getBi() != null && CollUtil.isNotEmpty(data.getBi().getPrptitemkindList())) {
+            GuoRenCrawlerCalculationPremiumData.BiDTO.PrptitemkindListDTO firstKind = data.getBi().getPrptitemkindList().get(0);
+            if (firstKind.getStartDate() != null && quoteVo.getBiRiskInfoVo() != null) {
+                String biStartDateTime = buildDateTimeString(firstKind.getStartDate(),
+                        firstKind.getStartHour(), 0);
+                String biEndDateTime = buildDateTimeString(firstKind.getEndDate(),
+                        firstKind.getEndHour(), 0);
+                quoteVo.getBiRiskInfoVo().setStartDate(biStartDateTime);
+                quoteVo.getBiRiskInfoVo().setEndDate(biEndDateTime);
+            }
+        }
+    }
+
+    /**
+     * 拼接日期、时、分为完整时间字符串
+     *
+     * @param date   日期,格式 yyyy-MM-dd
+     * @param hour   小时
+     * @param minute 分钟
+     * @return 完整时间字符串,格式 yyyy-MM-dd HH:mm:ss
+     */
+    private static String buildDateTimeString(String date, Integer hour, Integer minute) {
+        int h = hour != null ? hour : 0;
+        int m = minute != null ? minute : 0;
+        return date + " " + String.format("%02d", h) + ":" + String.format("%02d", m) + ":00";
+    }
+
     // 截取重复投保终保日期
     private static final Pattern DUPLICATE_END_TIME_PATTERN = Pattern.compile("终保日期 (\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2})");
 

+ 15 - 2
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysAmountAuditingServiceImpl.java

@@ -350,7 +350,7 @@ public class SysAmountAuditingServiceImpl extends ServiceImpl<SysAmountAuditingM
         audit.setRejectPerson(userName);
         audit.setRejectTime(LocalDateTime.now());
         this.updateById(audit);
-        this.saveChangeLog(audit,param);
+        this.saveChangeLog(audit,param,baseController.getSystemCode());
     }
 
     /**
@@ -359,15 +359,28 @@ public class SysAmountAuditingServiceImpl extends ServiceImpl<SysAmountAuditingM
      * @author lipf
      * @date 2026/7/15 16:48
      */
-    private void saveChangeLog(SysAmountAuditing audit, AmountAuditRejectParam param) {
+    private void saveChangeLog(SysAmountAuditing audit, AmountAuditRejectParam param, String systemCode) {
         log.info("提现申请不通过的时候,向changeLog表中插入一条状态为90的数据。audit=[{}],param=[{}]", JSONUtil.toJsonStr(audit), JSONUtil.toJsonStr(param));
         SysUserAccountChangeLog log = new SysUserAccountChangeLog();
         log.setRelatedAmountAuditingId(audit.getId());
         log.setStatus("90");
+        log.setAmount(BigDecimalUtil.negate(BigDecimalUtil.abs(audit.getAmount())));
         log.setRemark("提现驳回");
         log.setSystemCode(audit.getSystemCode());
         log.setUserId(audit.getUserId());
         log.setOperType(4);
+        log.setIsDelete(1);
+        SysAmountAuditing sysAmountAuditing = baseMapper.selectById(param.getId());
+        if(sysAmountAuditing != null){
+            log.setRelatedAmountAuditingId(sysAmountAuditing.getId());
+            String bankCardNum = sysAmountAuditing.getBankCardNum();
+            List<SysUserJzgInfoBankCard> sysUserJzgInfoBankCards =  sysUserJzgInfoBankCardService.queryBankCardBybankCardNum(bankCardNum,systemCode);
+            if(CollUtil.isNotEmpty(sysUserJzgInfoBankCards)){
+                SysUserJzgInfoBankCard sysUserJzgInfoBankCard = sysUserJzgInfoBankCards.get(0);
+                log.setBankCardIdTo(sysUserJzgInfoBankCard.getId());
+                log.setBankCardNoTo(sysUserJzgInfoBankCard.getBankCardNumber());
+            }
+        }
         sysUserAccountIncomeLogService.save(log);
     }
 

+ 114 - 50
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserAccountServiceImpl.java

@@ -8,12 +8,14 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jzg.commons.core.base.BaseController;
+import com.jzg.commons.entity.account.po.SysUserAccountChangeLog;
 import com.jzg.commons.entity.dto.*;
 import com.jzg.commons.entity.po.*;
 import com.jzg.commons.entity.vo.*;
 import com.jzg.commons.util.BigDecimalUtil;
 import com.jzg.organization.client.QuoteClient;
 import com.jzg.organization.mapper.SysAmountAuditingMapper;
+import com.jzg.organization.mapper.SysUserAccountIncomeLogMapper;
 import com.jzg.organization.mapper.SysUserAccountMapper;
 import com.jzg.organization.service.*;
 import org.slf4j.Logger;
@@ -56,6 +58,9 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
     @Autowired
     private SysAmountAuditingService sysAmountAuditingService;
 
+    @Autowired
+    private SysUserAccountIncomeLogMapper sysUserAccountIncomeLogMapper;
+
     @Autowired
     private SysDeptService sysDeptService;
     @Autowired
@@ -123,6 +128,7 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
         if (systemCode == null) {
             systemCode = baseController.getAppSystemCode();
         }
+        log.info("获取用户钱包信息:mobile=[{}],systemCode=[{}]", mobile, systemCode);
         String userId  = baseController.getUserId();
         log.info("查询用户的钱包信息:mobile=[{}], systemCode=[{}],userId=[{}]", mobile, systemCode, userId);
         SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getMobile, mobile));
@@ -195,57 +201,70 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
         sysUserWalletVo.setTotalInviteCount(String.valueOf(sysUserJzgInfoList.size()));
         // 获取累计收入
 
+        LocalDate now = LocalDate.now();
+        // LocalDate todayDay = now.minusDays(1);
+        LocalDate todayDay = now;
         // 获取今天的开始时间和结束时间
-        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
-        LocalDateTime todayEnd = LocalDate.now().atTime(23, 59, 59, 999);
-        List<SysAmountAuditing> sysAmountAuditingListToday = sysAmountAuditingService
-                .list(new LambdaQueryWrapper<SysAmountAuditing>()
-                        .eq(SysAmountAuditing::getUserId, sysUser.getId())
-                        .ge(SysAmountAuditing::getCreateTime, todayStart)
-                        .le(SysAmountAuditing::getCreateTime, todayEnd)
-                        .in(SysAmountAuditing::getAuditingStatus, 0, 1));
-        sysUserWalletVo.setTodayExpense(sysAmountAuditingListToday.stream()
-                .map(SysAmountAuditing::getAmount)
-                .map(amount -> amount != null ? amount : BigDecimal.ZERO)
-                .reduce(BigDecimal.ZERO, BigDecimal::add));
-        // 今日订单收入
-        // 初始化今日收入为0
-        BigDecimal todayIncome = BigDecimal.ZERO;
-        InsFeeOrdersParam feeOrdersParamTodayIncome = new InsFeeOrdersParam();
-        feeOrdersParamTodayIncome.setCreateTimeStart(todayStart);
-        feeOrdersParamTodayIncome.setCreateTimeEnd(todayEnd);
-        feeOrdersParamTodayIncome.setUserId(sysUserJzgInfo.getUserId());
-
-        List<InsFeeOrders> insFeeOrdersListTodayIncome = quoteClient.getInsFeeOrderByUserId(feeOrdersParamTodayIncome);
-        BigDecimal orderIncome = insFeeOrdersListTodayIncome.stream()
-                .map(InsFeeOrders::getTotalReceivablePremium)
-                .map(amount -> amount != null ? amount : BigDecimal.ZERO)
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-        todayIncome = todayIncome.add(orderIncome);
-        // 今日分销收入
-        InsFeeOrdersParam feeOrdersParam1 = new InsFeeOrdersParam();
-        feeOrdersParam1.setCreateTimeStart(todayStart);
-        feeOrdersParam1.setCreateTimeEnd(todayEnd);
-        feeOrdersParam1.setDistributorId(sysUserJzgInfo.getId());
-        List<InsFeeOrders> distributionList = quoteClient.getInsFeeOrdersList(feeOrdersParam1);
-
-        BigDecimal distributionIncome = distributionList.stream()
-                .map(order -> {
-                    BigDecimal fee = BigDecimal.ZERO;
-                    if (sysUserJzgInfo.getId().equals(order.getFirstDistributorId())) {
-                        fee = fee.add(order.getFirstDistributionFee() != null ? order.getFirstDistributionFee() : BigDecimal.ZERO);
-                    }
-                    if (sysUserJzgInfo.getId().equals(order.getSecondDistributorId())) {
-                        fee = fee.add(order.getSecondDistributionFee() != null ? order.getSecondDistributionFee() : BigDecimal.ZERO);
-                    }
-                    if (sysUserJzgInfo.getId().equals(order.getThirdDistributorId())) {
-                        fee = fee.add(order.getThirdDistributionFee() != null ? order.getThirdDistributionFee() : BigDecimal.ZERO);
-                    }
-                    return fee;
-                })
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-        todayIncome = todayIncome.add(distributionIncome);
+        LocalDateTime todayStart = todayDay.atStartOfDay();
+        LocalDateTime todayEnd = todayDay.atTime(23, 59, 59, 999);
+        LambdaQueryWrapper<SysUserAccountChangeLog> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(SysUserAccountChangeLog::getUserId, sysUser.getId());
+        wrapper.ge(SysUserAccountChangeLog::getCreateTime, todayStart);
+        wrapper.le(SysUserAccountChangeLog::getCreateTime, todayEnd);
+
+        List<SysUserAccountChangeLog> changeLogs = sysUserAccountIncomeLogMapper.selectList(wrapper);
+        BigDecimal todayIncome = changeLogs.stream().map(SysUserAccountChangeLog::getAmount).filter(BigDecimalUtil::biggerZero).reduce(BigDecimal.ZERO, BigDecimalUtil::add);
+        BigDecimal todayExpense = changeLogs.stream().map(SysUserAccountChangeLog::getAmount).map(BigDecimalUtil::negate).filter(BigDecimalUtil::biggerZero).reduce(BigDecimal.ZERO, BigDecimalUtil::add);
         sysUserWalletVo.setTodayIncome(todayIncome);
+        sysUserWalletVo.setTodayExpense(todayExpense);
+//        List<SysAmountAuditing> sysAmountAuditingListToday = sysAmountAuditingService
+//                .list(new LambdaQueryWrapper<SysAmountAuditing>()
+//                        .eq(SysAmountAuditing::getUserId, sysUser.getId())
+//                        .ge(SysAmountAuditing::getCreateTime, todayStart)
+//                        .le(SysAmountAuditing::getCreateTime, todayEnd)
+//                        .in(SysAmountAuditing::getAuditingStatus, 0, 1));
+//        sysUserWalletVo.setTodayExpense(sysAmountAuditingListToday.stream()
+//                .map(SysAmountAuditing::getAmount)
+//                .map(amount -> amount != null ? amount : BigDecimal.ZERO)
+//                .reduce(BigDecimal.ZERO, BigDecimal::add));
+//        // 今日订单收入
+//        // 初始化今日收入为0
+//        BigDecimal todayIncome = BigDecimal.ZERO;
+//        InsFeeOrdersParam feeOrdersParamTodayIncome = new InsFeeOrdersParam();
+//        feeOrdersParamTodayIncome.setCreateTimeStart(todayStart);
+//        feeOrdersParamTodayIncome.setCreateTimeEnd(todayEnd);
+//        feeOrdersParamTodayIncome.setUserId(sysUserJzgInfo.getUserId());
+//
+//        List<InsFeeOrders> insFeeOrdersListTodayIncome = quoteClient.getInsFeeOrderByUserId(feeOrdersParamTodayIncome);
+//        BigDecimal orderIncome = insFeeOrdersListTodayIncome.stream()
+//                .map(InsFeeOrders::getTotalReceivablePremium)
+//                .map(amount -> amount != null ? amount : BigDecimal.ZERO)
+//                .reduce(BigDecimal.ZERO, BigDecimal::add);
+//        todayIncome = todayIncome.add(orderIncome);
+//        // 今日分销收入
+//        InsFeeOrdersParam feeOrdersParam1 = new InsFeeOrdersParam();
+//        feeOrdersParam1.setCreateTimeStart(todayStart);
+//        feeOrdersParam1.setCreateTimeEnd(todayEnd);
+//        feeOrdersParam1.setDistributorId(sysUserJzgInfo.getId());
+//        List<InsFeeOrders> distributionList = quoteClient.getInsFeeOrdersList(feeOrdersParam1);
+//
+//        BigDecimal distributionIncome = distributionList.stream()
+//                .map(order -> {
+//                    BigDecimal fee = BigDecimal.ZERO;
+//                    if (sysUserJzgInfo.getId().equals(order.getFirstDistributorId())) {
+//                        fee = fee.add(order.getFirstDistributionFee() != null ? order.getFirstDistributionFee() : BigDecimal.ZERO);
+//                    }
+//                    if (sysUserJzgInfo.getId().equals(order.getSecondDistributorId())) {
+//                        fee = fee.add(order.getSecondDistributionFee() != null ? order.getSecondDistributionFee() : BigDecimal.ZERO);
+//                    }
+//                    if (sysUserJzgInfo.getId().equals(order.getThirdDistributorId())) {
+//                        fee = fee.add(order.getThirdDistributionFee() != null ? order.getThirdDistributionFee() : BigDecimal.ZERO);
+//                    }
+//                    return fee;
+//                })
+//                .reduce(BigDecimal.ZERO, BigDecimal::add);
+//        todayIncome = todayIncome.add(distributionIncome);
+//        sysUserWalletVo.setTodayIncome(todayIncome);
         return sysUserWalletVo;
     }
 
@@ -279,8 +298,53 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
             param.setCreateTimeStart(createTimeStart);
             param.setCreateTimeEnd(createTimeEnd);
         }
-
+        if (createTimeStart != null && !createTimeStart.isEmpty()) {
+            log.info("createTimeStart=[{}]", createTimeStart);
+            if(StrUtil.length(createTimeStart) < "2026-07-15 23:59:59".length()){
+                createTimeStart += " 00:00:00";
+            }
+        }
+        if (createTimeEnd != null && !createTimeEnd.isEmpty()) {
+            log.info("createTimeEnd=[{}]",createTimeEnd);
+            if(StrUtil.length(createTimeEnd) < "2026-07-15 23:59:59".length()){
+                createTimeEnd += " 23:59:59";
+            }
+        }
+        param.setCreateTimeStart(createTimeStart);
+        param.setCreateTimeEnd(createTimeEnd);
         List<IncomeAndExpenseList> allRecords = sysAmountAuditingService.getIncomeAndExpense(param);
+        allRecords = allRecords.stream().peek(action->{
+            if("0".equals(action.getStatus())){
+                action.setRemark("提现审核中");
+            }
+            List<ChangeLogDetail> stepList = new ArrayList<>();
+            if("0".equals(action.getAuditingStatus())){
+                stepList.add(new ChangeLogDetail("提交提现申请",action.getCreateTime(),true, null));
+                stepList.add(new ChangeLogDetail("财务人员审核",null, null,null));
+                stepList.add(new ChangeLogDetail("财务人员打款", null, null, null));
+            }else if(StrUtil.isEmpty(action.getAuditingStatus())){
+                if("1".equals(action.getStatus())){
+                    if("1".equals(action.getIncomeAndExpense())){
+                        stepList.add(new ChangeLogDetail("提交提现申请",action.getCreateTime(),true, null));
+                        stepList.add(new ChangeLogDetail("财务人员审核",action.getPaymentTime(), true,null));
+                        stepList.add(new ChangeLogDetail("财务人员打款", action.getPaymentTime(), true, null));
+                    }
+                    if("0".equals(action.getIncomeAndExpense())){
+                        // 保费收入
+                        stepList.add(new ChangeLogDetail("费用审核通过",action.getCreateTime(),true, null));
+                        stepList.add(new ChangeLogDetail());
+                        stepList.add(new ChangeLogDetail());
+                    }
+                }else if("2".equals(action.getStatus())){
+                    stepList.add(new ChangeLogDetail("提交提现申请",action.getCreateTime(),true, null));
+                    stepList.add(new ChangeLogDetail("财务人员审核",action.getPaymentTime(), true,null));
+                    stepList.add(new ChangeLogDetail("财务审核不通过", action.getRejectTime(), false, null));
+                }
+            }
+            action.setStepList(stepList);
+
+        }).toList();
+        allRecords= new ArrayList<>(allRecords);
         // 排序
         allRecords.sort((a, b) -> {
             if (a.getCreateTime() == null) return 1;

+ 15 - 9
tenant/organization/src/main/resources/mapper/SysAmountAuditingMapper.xml

@@ -270,15 +270,19 @@
         a.*
         from
         (
-        select
-        suacl.amount,
+        select 'changelog' as source,
+        abs(suacl.amount) as amount,
         CASE
         WHEN suacl.amount >= 0 THEN 0
         -- 正数或0为收入
         ELSE 1
         -- 负数为支出
         END AS incomeAndExpense,
-        '1' as status,
+        case
+            when suacl.is_delete = 0 then 1
+            when suacl.is_delete = 1 then 2
+        else -1
+        end AS status,
         suacl.oper_type,
         CASE
         suacl.oper_type
@@ -297,7 +301,8 @@
         suacl.create_time,
         suacl.update_by,
         suacl.update_time,
-        ioci.license_no
+        ioci.license_no,
+        null as payment_time , null as reject_time ,  null as auditing_status
         from
         sys_user_account_change_log suacl
         left join sys_amount_auditing saa on
@@ -307,8 +312,8 @@
         where
         suacl.system_code = #{systemCode}
         union ALL
-        select
-        saa.amount,
+        select 'amount_auditing' as source,
+        abs(saa.amount) as amount,
         1 as incomeAndExpense,
         saa.auditing_status as status,
         null as oper_type,
@@ -316,18 +321,19 @@
         saa.reject_reason,
         saa.bank_name,
         saa.bank_num as userName,
-        null as bankCardNum,
+        saa.bank_card_num,
         saa.user_id,
         saa.create_by,
         saa.create_time,
         saa.update_by,
         saa.update_time,
-        null as license_no
+        null as license_no,
+        saa.payment_time , saa.reject_time ,  saa.auditing_status
         from
         sys_amount_auditing saa
         where
         saa.system_code = #{systemCode}
-        and saa.auditing_status in (0, 2)  ) as a
+        and saa.auditing_status = 0  ) as a
         <where>
             a.user_id = #{userId}
             <if test="status != null and status != ''">