瀏覽代碼

add:广告分佣统计

ct 4 天之前
父節點
當前提交
09868b6b69

+ 27 - 0
fs-admin/src/main/java/com/fs/his/controller/AdProfitDetailController.java

@@ -9,7 +9,9 @@ import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.his.domain.AdProfitDetail;
 import com.fs.his.dto.AdProfitDetailDto;
+import com.fs.his.param.AdProfitDetailStatisticsParam;
 import com.fs.his.service.IAdProfitDetailService;
+import com.fs.his.vo.AdProfitDetailStatisticsVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -107,4 +109,29 @@ public class AdProfitDetailController extends BaseController
     {
         return adProfitDetailService.getWithFinishAndMayWithdraw();
     }
+
+    /**
+     * 统计
+     */
+    @PreAuthorize("@ss.hasPermi('his:statistics:commission')")
+    @GetMapping("/statistics")
+    public R statistics(AdProfitDetailStatisticsParam param)
+    {
+        List<AdProfitDetailStatisticsVo> list = adProfitDetailService.statisticsList(param);
+        return R.ok().put("list",list);
+    }
+
+    /**
+     * 导出统计
+     */
+    @PreAuthorize("@ss.hasPermi('his:statistics:commissionExport')")
+    @GetMapping("/exportCommission")
+    @Log(title = "广告分佣统计导出", businessType = BusinessType.EXPORT)
+    public AjaxResult exportCommission(AdProfitDetailStatisticsParam param)
+    {
+        List<AdProfitDetailStatisticsVo> list = adProfitDetailService.statisticsList(param);
+
+        ExcelUtil<AdProfitDetailStatisticsVo> util = new ExcelUtil<AdProfitDetailStatisticsVo>(AdProfitDetailStatisticsVo.class);
+        return util.exportExcel(list, "广告分佣统计数据");
+    }
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/mapper/AdProfitDetailMapper.java

@@ -4,6 +4,9 @@ package com.fs.his.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.his.domain.AdProfitDetail;
 import com.fs.his.dto.AdProfitDetailDto;
+import com.fs.his.param.AdProfitDetailStatisticsParam;
+import com.fs.his.vo.AdProfitDetailStatisticsVo;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -65,4 +68,6 @@ public interface AdProfitDetailMapper extends BaseMapper<AdProfitDetail>  {
     String getCompanyByUserId(String userId);
 
     Map<String, Object> getWithFinishAndMayWithdraw();
+
+    List<AdProfitDetailStatisticsVo> statisticsList(@Param("param")AdProfitDetailStatisticsParam param);
 }

+ 12 - 0
fs-service/src/main/java/com/fs/his/param/AdProfitDetailStatisticsParam.java

@@ -0,0 +1,12 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+@Data
+public class AdProfitDetailStatisticsParam {
+    Integer type;//"类型 1今天 2昨天 3 本周 4 上周 5本月 6上月 7本季度 8上季度 9本年 10去年
+    String companyIds;//员工IDS 多个用,分割
+    Long[] companies;
+    String startTime;
+    String endTime;
+}

+ 4 - 0
fs-service/src/main/java/com/fs/his/service/IAdProfitDetailService.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.AdProfitDetail;
 import com.fs.his.dto.AdProfitDetailDto;
+import com.fs.his.param.AdProfitDetailStatisticsParam;
+import com.fs.his.vo.AdProfitDetailStatisticsVo;
 
 import java.util.List;
 
@@ -63,4 +65,6 @@ public interface IAdProfitDetailService extends IService<AdProfitDetail>{
     int deleteAdProfitDetailById(Long id);
 
     R getWithFinishAndMayWithdraw();
+
+    List<AdProfitDetailStatisticsVo> statisticsList(AdProfitDetailStatisticsParam param);
 }

+ 70 - 0
fs-service/src/main/java/com/fs/his/service/impl/AdProfitDetailServiceImpl.java

@@ -4,16 +4,29 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.AdProfitDetail;
 import com.fs.his.dto.AdProfitDetailDto;
+import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.mapper.AdProfitDetailMapper;
+import com.fs.his.mapper.FsIntegralRedPacketLogMapper;
+import com.fs.his.param.AdProfitDetailStatisticsParam;
 import com.fs.his.service.IAdProfitDetailService;
+import com.fs.his.service.IFsUserIntegralLogsService;
+import com.fs.his.vo.AdProfitDetailStatisticsVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * 广告分佣Service业务层处理
@@ -22,7 +35,15 @@ import java.util.Map;
  * @date 2025-11-27
  */
 @Service
+@Slf4j
 public class AdProfitDetailServiceImpl extends ServiceImpl<AdProfitDetailMapper, AdProfitDetail> implements IAdProfitDetailService {
+    @Autowired
+    private FsIntegralRedPacketLogMapper fsIntegralRedPacketLogMapper;
+    @Autowired
+    private IFsUserIntegralLogsService fsUserIntegralLogsService;
+    @Autowired
+    @Qualifier("threadPoolTaskExecutor")
+    private ThreadPoolTaskExecutor executor;
 
     /**
      * 查询广告分佣
@@ -112,9 +133,58 @@ public class AdProfitDetailServiceImpl extends ServiceImpl<AdProfitDetailMapper,
         BigDecimal totalMayWithdraw = new BigDecimal(map.get("totalMayWithdraw").toString()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
         // 已提现总金额
         BigDecimal totalWithdrawFinish = new BigDecimal(map.get("totalWithdrawFinish").toString()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
+        // 提现中金额
+        BigDecimal withdrawMoney = fsIntegralRedPacketLogMapper.sumMoneyByStatus(0);
+        if (withdrawMoney != null) {
+            totalMayWithdraw = totalMayWithdraw.subtract(withdrawMoney);
+            totalWithdrawFinish = totalWithdrawFinish.subtract(withdrawMoney);
+            withdrawMoney = withdrawMoney.setScale(2, RoundingMode.UP);
+        }
         Map<String,Object> widthdrawMap = new HashMap<>();
         widthdrawMap.put("totalMayWithdraw",totalMayWithdraw);
         widthdrawMap.put("totalWithdrawFinish",totalWithdrawFinish);
+        widthdrawMap.put("withdrawMoney",withdrawMoney);
         return R.ok(widthdrawMap);
     }
+
+    @Override
+    public List<AdProfitDetailStatisticsVo> statisticsList(AdProfitDetailStatisticsParam param) {
+        // 并行执行两个查询
+        CompletableFuture<List<AdProfitDetailStatisticsVo>> vosFuture = CompletableFuture
+                .supplyAsync(() -> baseMapper.statisticsList(param), executor);
+
+        CompletableFuture<BigDecimal> integralFuture = CompletableFuture
+                .supplyAsync(() -> {
+                    Long integral = fsUserIntegralLogsService.sumIntegralByLogTypeAndCreateTime(
+                            FsUserIntegralLogTypeEnum.TYPE_31.getValue(), param
+                    );
+                    return integral != null && integral > 0
+                            ? new BigDecimal(integral).divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP)
+                            : BigDecimal.ZERO;
+                }, executor);
+
+        try {
+            // 等待两个都完成
+            CompletableFuture.allOf(vosFuture, integralFuture)
+                    .get(60, TimeUnit.SECONDS);
+
+            List<AdProfitDetailStatisticsVo> vos = vosFuture.getNow(null);
+            BigDecimal totalIntegral = integralFuture.getNow(BigDecimal.ZERO);
+
+            if (vos != null && !vos.isEmpty()) {
+                vos.get(0).setAmountYuan(totalIntegral);
+            }
+
+            return vos != null ? vos : Collections.emptyList();
+
+        } catch (TimeoutException e) {
+            log.error("查询超时", e);
+            vosFuture.cancel(true);
+            integralFuture.cancel(true);
+            throw new RuntimeException("查询超时,请稍后重试");
+        } catch (Exception e) {
+            log.error("查询异常", e);
+            throw new RuntimeException("查询执行异常", e);
+        }
+    }
 }

+ 14 - 0
fs-service/src/main/java/com/fs/his/vo/AdProfitDetailStatisticsVo.java

@@ -0,0 +1,14 @@
+package com.fs.his.vo;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class AdProfitDetailStatisticsVo {
+    @Excel(name = "公司名称")
+    String name;
+    @Excel(name = "分佣金额")
+    BigDecimal amountYuan;
+}

+ 118 - 0
fs-service/src/main/resources/mapper/his/AdProfitDetailMapper.xml

@@ -130,6 +130,124 @@
             may_withdraw > 0.00
            OR withdraw_finish > 0.00
     </select>
+    <select id="statisticsList" resultType="com.fs.his.vo.AdProfitDetailStatisticsVo">
+        <!-- 1. 用户分润 -->
+        SELECT
+        '用户分润' AS `name`,
+        IFNULL(ROUND(SUM(a.user_money) / 100, 2), 0) AS amountYuan,
+        'summary' AS type,
+        1 AS sortOrder
+        FROM ad_profit_detail a
+        WHERE <include refid="timeCondition"/>
+
+        UNION ALL
+
+        <!-- 2. 互医分润 -->
+        SELECT
+        '互医分润' AS `name`,
+        IFNULL(ROUND(SUM(a.huyi_money) / 100, 2), 0) AS amountYuan,
+        'summary' AS type,
+        2 AS sortOrder
+        FROM ad_profit_detail a
+        WHERE <include refid="timeCondition"/>
+
+        UNION ALL
+
+        <!-- 3. 云联分润 -->
+        SELECT
+        '云联分润' AS `name`,
+        IFNULL(ROUND(SUM(a.yunlian_money) / 100, 2), 0) AS amountYuan,
+        'summary' AS type,
+        3 AS sortOrder
+        FROM ad_profit_detail a
+        WHERE <include refid="timeCondition"/>
+
+        UNION ALL
+
+        <!-- 4. 各公司分润 -->
+        SELECT
+        c.company_name AS `name`,
+        IFNULL(ROUND(SUM(a.company_money) / 100, 2), 0) AS amountYuan,
+        'company' AS type,
+        a.company_id + 100 AS sortOrder
+        FROM ad_profit_detail a
+        LEFT JOIN company c ON a.company_id = c.company_id
+        WHERE a.company_id IS NOT NULL
+        AND <include refid="timeCondition"/>
+        GROUP BY a.company_id, c.company_name
+
+        ORDER BY sortOrder, `name`
+    </select>
+
+    <sql id="timeCondition">
+        <choose>
+            <!-- type为null时,使用startTime和endTime -->
+            <when test="param.type == null">
+                a.create_time >= #{param.startTime}
+                AND a.create_time &lt; DATE_ADD(#{param.endTime}, INTERVAL 1 DAY)
+            </when>
+
+            <!-- 1. 今天 -->
+            <when test="param.type == 1">
+                a.create_time >= CURDATE()
+                AND a.create_time &lt; DATE_ADD(CURDATE(), INTERVAL 1 DAY)
+            </when>
+
+            <!-- 2. 昨天 -->
+            <when test="param.type == 2">
+                a.create_time >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
+                AND a.create_time &lt; CURDATE()
+            </when>
+
+            <!-- 3. 本周 -->
+            <when test="param.type == 3">
+                a.create_time >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+                AND a.create_time &lt; DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+            </when>
+
+            <!-- 4. 上周 -->
+            <when test="param.type == 4">
+                a.create_time >= DATE_SUB(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+                AND a.create_time &lt; DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+            </when>
+
+            <!-- 5. 本月 -->
+            <when test="param.type == 5">
+                a.create_time >= DATE_FORMAT(CURDATE(), '%Y-%m-01')
+                AND a.create_time &lt; DATE_ADD(DATE_FORMAT(CURDATE(), '%Y-%m-01'), INTERVAL 1 MONTH)
+            </when>
+
+            <!-- 6. 上月 -->
+            <when test="param.type == 6">
+                a.create_time >= DATE_SUB(DATE_FORMAT(CURDATE(), '%Y-%m-01'), INTERVAL 1 MONTH)
+                AND a.create_time &lt; DATE_FORMAT(CURDATE(), '%Y-%m-01')
+            </when>
+
+            <!-- 7. 本季度 -->
+            <when test="param.type == 7">
+                a.create_time >= STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-', QUARTER(CURDATE())*3-2, '-01'), '%Y-%m-%d')
+                AND a.create_time &lt; DATE_ADD(STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-', QUARTER(CURDATE())*3-2, '-01'), '%Y-%m-%d'), INTERVAL 3 MONTH)
+            </when>
+
+            <!-- 8. 上季度 -->
+            <when test="param.type == 8">
+                a.create_time >= DATE_SUB(STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-', QUARTER(CURDATE())*3-2, '-01'), '%Y-%m-%d'), INTERVAL 3 MONTH)
+                AND a.create_time &lt; STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-', QUARTER(CURDATE())*3-2, '-01'), '%Y-%m-%d')
+            </when>
+
+            <!-- 9. 本年 -->
+            <when test="param.type == 9">
+                a.create_time >= STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-01-01'), '%Y-%m-%d')
+                AND a.create_time &lt; DATE_ADD(STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-01-01'), '%Y-%m-%d'), INTERVAL 1 YEAR)
+            </when>
+
+            <!-- 10. 去年 -->
+            <when test="param.type == 10">
+                a.create_time >= DATE_SUB(STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-01-01'), '%Y-%m-%d'), INTERVAL 1 YEAR)
+                AND a.create_time &lt; STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-01-01'), '%Y-%m-%d')
+            </when>
+        </choose>
+    </sql>
 
 
 </mapper>