Explorar o código

Merge branch 'dev' of http://192.168.1.245:11111/jinjilong/onlineEducation-fwd into dev

honorfire hai 6 meses
pai
achega
71c24038ff

+ 66 - 4
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceStatisticController.java

@@ -2,15 +2,20 @@ package vip.xiaonuo.disk.controller;
 
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.qiwenshare.common.result.RestResult;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.web.bind.annotation.*;
+import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
 import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.disk.domain.StorageBean;
+import vip.xiaonuo.disk.service.ResourceFileService;
 import vip.xiaonuo.disk.service.ResourceStatisticService;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -25,7 +30,8 @@ public class ResourceStatisticController {
 
     @Resource
     private ResourceStatisticService resourceStatisticService;
-
+    @Resource
+    private ResourceFileService resourceFileService;
     /**
      * 资源统计分析总统计
      *
@@ -39,4 +45,60 @@ public class ResourceStatisticController {
         return CommonResult.data(resourceStatisticService.getResourceStatisticData());
     }
 
+
+    /**
+     * 资源类型分布(按资源类型统计)
+     *
+     * @author pans
+     * @date  2025/08/27 14:10
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("资源类型分布")
+    @GetMapping("/resourceTypeStatistic")
+    public CommonResult<List<Map<String, Object>>> resourceTypeStatistic(String collegeId,String type) {
+        return CommonResult.data(resourceStatisticService.resourceTypeStatistic(collegeId,type));
+    }
+
+
+    /**
+     * 资源类型分布(按院系统计)
+     *
+     * @author pans
+     * @date  2025/08/27 14:10
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("资源类型分布")
+    @GetMapping("/collegeStatistic")
+    public CommonResult<List<Map<String, Object>>> collegeStatistic(String collegeId,String type) {
+        return CommonResult.data(resourceStatisticService.collegeStatistic(collegeId,type));
+    }
+
+
+
+    /**
+     * 资源公开情况
+     *
+     * @author pans
+     * @date  2025/08/27 14:10
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("资源公开分布")
+    @GetMapping("/resourcePublicStatistic")
+    public CommonResult<List<Map<String, Object>>> resourcePublicStatistic(String collegeId,String type) {
+        return CommonResult.data(resourceStatisticService.resourcePublicStatistic(collegeId,type));
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 }

+ 7 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/ResourceStatisticMapper.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 import vip.xiaonuo.disk.domain.ResourceFile;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -18,4 +19,10 @@ public interface ResourceStatisticMapper extends BaseMapper<Map<String, Object>>
      * @return
      */
     Map<String, Object> getResourceStatisticData(@Param("userId")String userId);
+
+    List<Map<String, Object>> resourceTypeStatistic(@Param("collegeId") String collegeId,@Param("map") Map<String,Object> map);
+
+    List<Map<String, Object>> collegeStatistic(@Param("collegeId") String collegeId,@Param("map") Map<String,Object> map);
+
+    List<Map<String, Object>> resourcePublicStatistic(@Param("collegeId") String collegeId, @Param("map") Map<String, Object> map);
 }

+ 65 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/ResourceStatisticMapper.xml

@@ -45,4 +45,69 @@
             ) r4
 
     </select>
+
+
+    <select id="resourceTypeStatistic" resultType="map">
+        SELECT
+            rr.RESOURCE_TYPE resourceType,
+            rt.name resourceTypeName,
+            count(DISTINCT rr.id) num
+        FROM
+            RESOURCE_RECORD rr LEFT JOIN resource_type rt ON rr.RESOURCE_TYPE =rt.id
+        <where>
+            <if test="collegeId != null">
+                rr.COLLEGE_ID = #{collegeId}
+            </if>
+            <if test="map.startTime != null">
+                AND rr.create_time &gt;= #{map.startTime}
+            </if>
+            <if test="map.endTime != null">
+                AND rr.create_time &lt;= #{map.endTime}
+            </if>
+        </where>
+        GROUP BY
+            rr.RESOURCE_TYPE,rt.name
+    </select>
+
+    <select id="collegeStatistic" resultType="map">
+        SELECT
+            rr.COLLEGE_ID collegeId,
+            so.name collegeName,
+            count(DISTINCT rr.id) num
+        FROM
+            RESOURCE_RECORD rr LEFT JOIN SYS_ORG so  ON rr.COLLEGE_ID =so.id
+        <where>
+            <if test="collegeId != null">
+                 rr.COLLEGE_ID = #{collegeId}
+            </if>
+            <if test="map.startTime != null">
+                AND rr.create_time &gt;= #{map.startTime}
+            </if>
+            <if test="map.endTime != null">
+                AND rr.create_time &lt;= #{map.endTime}
+            </if>
+        </where>
+        GROUP BY
+            rr.COLLEGE_ID,so.name
+    </select>
+
+    <select id="resourcePublicStatistic" resultType="map">
+        SELECT
+            rr.VERIFY_STATUS verifyStatus,
+            count(DISTINCT rr.id) num
+        FROM RESOURCE_RECORD rr
+        <where>
+            VERIFY_STATUS IN (0, 2)
+            <if test="collegeId != null">
+                AND rr.COLLEGE_ID = #{collegeId}
+            </if>
+            <if test="map.startTime != null">
+                AND rr.create_time &gt;= #{map.startTime}
+            </if>
+            <if test="map.endTime != null">
+                AND rr.create_time &lt;= #{map.endTime}
+            </if>
+        </where>
+        GROUP BY rr.VERIFY_STATUS
+    </select>
 </mapper>

+ 7 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceStatisticService.java

@@ -2,6 +2,7 @@ package vip.xiaonuo.disk.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -15,4 +16,10 @@ public interface ResourceStatisticService extends IService<Map<String, Object>>
      * @return Map<String, Object>
      */
     Map<String, Object> getResourceStatisticData();
+
+    List<Map<String, Object>> resourceTypeStatistic(String collegeId,String type);
+
+    List<Map<String, Object>> collegeStatistic(String collegeId,String type);
+
+    List<Map<String, Object>> resourcePublicStatistic(String collegeId, String type);
 }

+ 52 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceStatisticServiceImpl.java

@@ -1,5 +1,6 @@
 package vip.xiaonuo.disk.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -10,10 +11,10 @@ import vip.xiaonuo.disk.mapper.ResourceStatisticMapper;
 import vip.xiaonuo.disk.mapper.ResourceUserFileMapper;
 import vip.xiaonuo.disk.service.ResourceFootprintService;
 import vip.xiaonuo.disk.service.ResourceStatisticService;
+import vip.xiaonuo.disk.util.AppUseAggregationUtil;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 资源统计分析Service接口实现类
@@ -48,4 +49,53 @@ public class ResourceStatisticServiceImpl extends ServiceImpl<ResourceStatisticM
         }
         return result;
     }
+
+    public Map<String, Object> getTime(String type) {
+        Map<String,Object> map = new HashMap<>(2);
+        if(Objects.isNull(type)){
+            map.put("startTime", null);
+            map.put("endTime", null);
+            return map;
+        }
+        String startTime="";
+        String endTime=DateUtil.format(new Date(), "yyyy-MM-dd");
+        switch(type){
+            case "1":
+                startTime = AppUseAggregationUtil.offsetDay(endTime, -30, "yyyy-MM-dd");
+                break;
+            case "2":
+                startTime = AppUseAggregationUtil.offsetDay(endTime, -90, "yyyy-MM-dd");
+                break;
+            case "3":
+                startTime = AppUseAggregationUtil.offsetDay(endTime, -180, "yyyy-MM-dd");
+                break;
+            case "4":
+                startTime = AppUseAggregationUtil.offsetDay(endTime, -365, "yyyy-MM-dd");
+                break;
+            default:
+
+                break;
+        }
+        map.put("startTime", startTime);
+        map.put("endTime", endTime);
+        return map;
+    }
+
+    @Override
+    public List<Map<String, Object>> resourceTypeStatistic(String collegeId,String type) {
+        Map<String,Object> map=getTime(type);
+        return resourceStatisticMapper.resourceTypeStatistic(collegeId,map);
+    }
+
+    @Override
+    public List<Map<String, Object>> collegeStatistic(String collegeId,String type) {
+        Map<String,Object> map=getTime(type);
+        return resourceStatisticMapper.collegeStatistic(collegeId,map);
+    }
+
+    @Override
+    public List<Map<String, Object>> resourcePublicStatistic(String collegeId, String type) {
+        Map<String,Object> map=getTime(type);
+        return resourceStatisticMapper.resourcePublicStatistic(collegeId,map);
+    }
 }

+ 691 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/util/AppUseAggregationUtil.java

@@ -0,0 +1,691 @@
+package vip.xiaonuo.disk.util;
+
+
+
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class AppUseAggregationUtil {
+
+    private static final BigDecimal hundred = new BigDecimal(100);
+
+    //判断是否是数字类型
+    private static final String regex = "-?\\d+(\\.\\d+)?";
+
+
+
+    //省分列表
+    public static List<String> getProvinceCodeList() {
+        return Arrays.asList("210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224",
+                "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240");
+    }
+
+    //仅地区列表,无本部
+    public static List<String> getCityCodeList() {
+        return Arrays.asList("21000", "21002", "21003", "21004",
+                "21006", "21007", "21008", "21009", "21010", "21011", "21012", "21013", "21014", "21015", "21016", "21017", "21301", "21302", "21303",
+                "21304", "21305", "21306", "21307", "21308", "21309", "21401", "21402", "21403", "21404", "21405", "21406", "21407", "21408", "21409",
+                "21410", "21411", "21412", "21501", "21502", "21503", "21504", "21505", "21506", "21507", "21508", "21509", "21510", "21511", "21512",
+                "21513", "21514", "21515", "21516", "21517", "21518", "21519", "21520", "21521", "21601", "21602", "21603", "21604", "21605", "21606", "21607",
+                "21608", "21609", "21610", "21611", "21612", "21613", "21614", "21701", "21702", "21703", "21704", "21705", "21708", "21709", "21801", "21802",
+                "21803", "21804", "21805", "21806", "21807", "21808", "21809", "21810", "21811", "21902", "21903", "21904", "21905", "21906", "21907", "21908",
+                "21909", "21910", "21911", "21912", "21913", "21914", "21915", "21916", "21917", "21918", "21919", "22007", "22008", "22009", "22101", "22102",
+                "22103", "22104", "22105", "22106", "22107", "22108", "22109", "22110", "22111", "22112", "22116", "22201", "22202", "22203", "22204", "22205",
+                "22206", "22207", "22208", "22209", "22210", "22211", "22212", "22301", "22302", "22303", "22304", "22305", "22306", "22307", "22308", "22309",
+                "22310", "22311", "22312", "22313", "22401", "22402", "22403", "22404", "22405", "22406", "22407", "22408", "22409", "22501", "22502", "22503",
+                "22504", "22505", "22506", "22507", "22508", "22509", "22510", "22511", "22512", "22513", "22601", "22602", "22603", "22604", "22605", "22606",
+                "22607", "22608", "22609", "22610", "22611", "22700", "22701", "22702", "22703", "22704", "22705", "22706", "22707", "22708", "22709", "22710",
+                "22711", "22712", "22713", "22800", "22801", "22802", "22803", "22804", "22805", "22807", "22808", "22809", "22810", "22811", "22812", "22901",
+                "22902", "22903", "22904", "22905", "23000", "23001", "23002", "23003", "23004", "23005", "23006", "23007", "23008", "23100", "23101", "23102",
+                "23103", "23104", "23105", "23107", "23108", "23109", "23110", "23112", "23113", "23114", "23115", "23116", "23117", "23201", "23202", "23203",
+                "23204", "23205", "23206", "23207", "23208", "23209", "23210", "23211", "23301", "23302", "23303", "23304", "23305", "23306", "23307", "23308",
+                "23309", "23310", "23501", "23502", "23503", "23504", "23505", "23506", "23507", "23508", "23509", "23510", "23511", "23512", "23513", "23514",
+                "23515", "23516", "23517", "23701", "23707", "23708", "23709", "23710", "23711", "23712", "23801", "23802", "23805", "23806", "23808", "23809",
+                "23810", "23811", "23812", "23813", "23814", "23815", "23816", "23901", "23902", "23903", "23906", "23910", "23911", "23913", "23914", "24001",
+                "24002", "24003", "24004", "24005", "24006", "24007", "24008", "24009", "24010", "24011", "22213", "22214", "22314", "23521", "23520", "23519",
+                "21812", "22019", "23912", "23916", "23915", "23909", "23908", "23904", "23905", "23907", "21414", "21413", "21707", "21706", "23803", "23804",
+                "23807","23518");
+    }
+
+    //自定义的本部+省分+地市
+    public static List<String> getAllRegionCodeList() {
+        return Arrays.asList("21099", "21199", "21299", "21399", "21499", "21599", "21699", "21799", "21899", "21999", "22099",
+                "22199", "22299", "22399", "22499", "22599", "22699", "22799", "22899", "22999", "23099", "23199", "23299", "23399", "23499", "23599", "23699", "23799", "23899", "23999", "24099",
+                "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225",
+                "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "21000", "21002", "21003", "21004",
+                "21006", "21007", "21008", "21009", "21010", "21011", "21012", "21013", "21014", "21015", "21016", "21017", "21301", "21302", "21303",
+                "21304", "21305", "21306", "21307", "21308", "21309", "21401", "21402", "21403", "21404", "21405", "21406", "21407", "21408", "21409",
+                "21410", "21411", "21412", "21501", "21502", "21503", "21504", "21505", "21506", "21507", "21508", "21509", "21510", "21511", "21512",
+                "21513", "21514", "21515", "21516", "21517", "21518", "21519", "21520", "21521", "21601", "21602", "21603", "21604", "21605", "21606", "21607",
+                "21608", "21609", "21610", "21611", "21612", "21613", "21614", "21701", "21702", "21703", "21704", "21705", "21708", "21709", "21801", "21802",
+                "21803", "21804", "21805", "21806", "21807", "21808", "21809", "21810", "21811", "21902", "21903", "21904", "21905", "21906", "21907", "21908",
+                "21909", "21910", "21911", "21912", "21913", "21914", "21915", "21916", "21917", "21918", "21919", "22007", "22008", "22009", "22101", "22102",
+                "22103", "22104", "22105", "22106", "22107", "22108", "22109", "22110", "22111", "22112", "22116", "22201", "22202", "22203", "22204", "22205",
+                "22206", "22207", "22208", "22209", "22210", "22211", "22212", "22301", "22302", "22303", "22304", "22305", "22306", "22307", "22308", "22309",
+                "22310", "22311", "22312", "22313", "22401", "22402", "22403", "22404", "22405", "22406", "22407", "22408", "22409", "22501", "22502", "22503",
+                "22504", "22505", "22506", "22507", "22508", "22509", "22510", "22511", "22512", "22513", "22601", "22602", "22603", "22604", "22605", "22606",
+                "22607", "22608", "22609", "22610", "22611", "22700", "22701", "22702", "22703", "22704", "22705", "22706", "22707", "22708", "22709", "22710",
+                "22711", "22712", "22713", "22800", "22801", "22802", "22803", "22804", "22805", "22807", "22808", "22809", "22810", "22811", "22812", "22901",
+                "22902", "22903", "22904", "22905", "23000", "23001", "23002", "23003", "23004", "23005", "23006", "23007", "23008", "23100", "23101", "23102",
+                "23103", "23104", "23105", "23107", "23108", "23109", "23110", "23112", "23113", "23114", "23115", "23116", "23117", "23201", "23202", "23203",
+                "23204", "23205", "23206", "23207", "23208", "23209", "23210", "23211", "23301", "23302", "23303", "23304", "23305", "23306", "23307", "23308",
+                "23309", "23310", "23501", "23502", "23503", "23504", "23505", "23506", "23507", "23508", "23509", "23510", "23511", "23512", "23513", "23514",
+                "23515", "23516", "23517", "23701", "23707", "23708", "23709", "23710", "23711", "23712", "23801", "23802", "23805", "23806", "23808", "23809",
+                "23810", "23811", "23812", "23813", "23814", "23815", "23816", "23901", "23902", "23903", "23906", "23910", "23911", "23913", "23914", "24001",
+                "24002", "24003", "24004", "24005", "24006", "24007", "24008", "24009", "24010", "24011", "22213", "22214", "22314", "23521", "23520", "23519",
+                "21812", "22019", "23912", "23916", "23915", "23909", "23908", "23904", "23905", "23907", "21414", "21413", "21707", "21706", "23803", "23804",
+                "23807","23518");
+    }
+
+    //全部+自定义的本部+省分+地市  去除了直辖市本部
+    public static List<String> getAllRegionAndTotalCodeList() {
+        return Arrays.asList("all",
+                "210", "21099","21000", "21002", "21003", "21004", "21006", "21007", "21008", "21009", "21010", "21011", "21012", "21013", "21014", "21015", "21016", "21017",
+                "211", "212",
+                "213", "21399", "21301", "21302", "21303", "21304", "21305", "21306", "21307", "21308", "21309",
+                "214", "21499", "21401", "21402", "21403", "21404", "21405", "21406", "21407", "21408", "21409", "21410", "21411", "21412", "21413", "21414",
+                "215", "21599", "21501", "21502", "21503", "21504", "21505", "21506", "21507", "21508", "21509", "21510", "21511", "21512", "21513", "21514", "21515", "21516", "21517", "21518", "21519", "21520", "21521",
+                "216", "21699", "21601", "21602", "21603", "21604", "21605", "21606", "21607", "21608", "21609", "21610", "21611", "21612", "21613", "21614",
+                "217", "21799", "21701", "21702", "21703", "21704", "21705", "21706", "21707", "21708", "21709",
+                "218", "21899", "21801", "21802", "21803", "21804", "21805", "21806", "21807", "21808", "21809", "21810", "21811", "21812",
+                "219", "21999", "21902", "21903", "21904", "21905", "21906", "21907", "21908", "21909", "21910", "21911", "21912", "21913", "21914", "21915", "21916", "21917", "21918", "21919",
+                "220", "22099", "22007", "22008", "22009", "22019",
+                "221", "22199", "22101", "22102", "22103", "22104", "22105", "22106", "22107", "22108", "22109", "22110", "22111", "22112", "22116",
+                "222", "22299", "22201", "22202", "22203", "22204", "22205", "22206", "22207", "22208", "22209", "22210", "22211", "22212", "22213", "22214",
+                "223", "22399", "22301", "22302", "22303", "22304", "22305", "22306", "22307", "22308", "22309", "22310", "22311", "22312", "22313", "22314",
+                "224", "22499", "22401", "22402", "22403", "22404", "22405", "22406", "22407", "22408", "22409",
+                "225", "22599", "22501", "22502", "22503", "22504", "22505", "22506", "22507", "22508", "22509", "22510", "22511", "22512", "22513",
+                "226", "22699", "22601", "22602", "22603", "22604", "22605", "22606", "22607", "22608", "22609", "22610", "22611",
+                "227", "22799", "22700", "22701", "22702", "22703", "22704", "22705", "22706", "22707", "22708", "22709", "22710", "22711", "22712", "22713",
+                "228", "22899", "22800", "22801", "22802", "22803", "22804", "22805", "22807", "22808", "22809", "22810", "22811", "22812",
+                "229", "22999", "22901", "22902", "22903", "22904", "22905",
+                "230", "23099", "23000", "23001", "23002", "23003", "23004", "23005", "23006", "23007", "23008",
+                "231", "23199", "23100", "23101", "23102", "23103", "23104", "23105", "23107", "23108", "23109", "23110", "23112", "23113", "23114", "23115", "23116", "23117",
+                "232", "23299", "23201", "23202", "23203", "23204", "23205", "23206", "23207", "23208", "23209", "23210", "23211",
+                "233", "23399", "23301", "23302", "23303", "23304", "23305", "23306", "23307", "23308", "23309", "23310",
+                "234",
+                "235", "23599", "23501", "23502", "23503", "23504", "23505", "23506", "23507", "23508", "23509", "23510", "23511", "23512", "23513", "23514", "23515", "23516", "23517", "23519", "23520", "23521",
+                "236",
+                "237", "23799", "23701", "23707", "23708", "23709", "23710", "23711", "23712",
+                "238", "23899", "23801", "23802", "23803", "23804", "23805", "23806", "23807", "23808", "23809", "23810", "23811", "23812", "23813", "23814", "23815", "23816",
+                "239", "23999", "23901", "23902", "23903", "23904", "23905", "23906", "23907", "23908", "23909", "23910", "23911", "23912", "23913", "23914", "23915", "23916",
+                "240", "24099", "24001", "24002", "24003", "24004", "24005", "24006", "24007", "24008", "24009", "24010", "24011"
+        );
+    }
+
+    public static List<String> transformCkList(List<String> ckList) {
+        List<String> list = new ArrayList<>();
+        if (ObjectUtil.isNotEmpty(ckList)) {
+            for (String str : ckList) {
+                if (!"[]".equals(str)) {
+                    String newStr = str.replace("[", "").replace("]", "").replace(" ","");
+                    List<String> stringList = StrUtil.split(newStr, ",");
+
+                    if (ObjectUtil.isNotEmpty(stringList)) {
+                        list.addAll(stringList);
+                    }
+                }
+            }
+        }
+        return list;
+    }
+
+
+
+
+
+
+
+
+    public static String computeSum(String num1, String num2) {
+        int sum = NumberUtil.parseInt(num1) + NumberUtil.parseInt(num2);
+        return String.valueOf(sum);
+    }
+
+    public static String computeAvg(String sum, String num) {
+        try {
+            BigDecimal sumValue = new BigDecimal(sum);
+            BigDecimal numValue = new BigDecimal(num);
+            double avg = sumValue.divide(numValue, 2, RoundingMode.HALF_UP).doubleValue();
+            return String.valueOf(avg);
+        } catch (Exception e) {
+            return "0";
+        }
+    }
+
+    public static String computeAvg(long sum, String num) {
+        try {
+            BigDecimal sumValue = new BigDecimal(sum);
+            BigDecimal numValue = new BigDecimal(num);
+            double avg = sumValue.divide(numValue, 2, RoundingMode.HALF_UP).doubleValue();
+            return String.valueOf(avg);
+        } catch (Exception e) {
+            return "0";
+        }
+    }
+
+    public static String computeAvg(String sum, int num) {
+        try {
+            BigDecimal sumValue = new BigDecimal(sum);
+            BigDecimal numValue = new BigDecimal(num);
+            double avg = sumValue.divide(numValue, 2, RoundingMode.HALF_UP).doubleValue();
+            return String.valueOf(avg);
+        } catch (Exception e) {
+            return "0";
+        }
+
+    }
+
+    //查找list1有,list2没有的数据
+    public static <T> List<T> getUnContainedListByGeneric(List<T> list1, List<T> list2) {
+        List<T> unContainedList = new ArrayList<>();
+        if (ObjectUtil.isEmpty(list1)) {
+            return unContainedList;
+        }
+        if (ObjectUtil.isEmpty(list2)) {
+            return list1;
+        }
+        for (T user : list1) {
+            for (T userRetained : list2) {
+                if (!list2.contains(userRetained)) {
+                    unContainedList.add(user);
+                }
+
+            }
+        }
+        return unContainedList;
+    }
+
+    //查找list1有,list2没有的数据
+    public static List<String> getUnContainedList(List<String> list1, List<String> list2) {
+        List<String> unContainedList = new ArrayList<>();
+        if (ObjectUtil.isEmpty(list1)) {
+            return unContainedList;
+        }
+        if (ObjectUtil.isEmpty(list2)) {
+            return list1;
+        }
+        Map<String, String> tempMap = list2.parallelStream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));
+        return list1.parallelStream().filter(str -> !tempMap.containsKey(str)).collect(Collectors.toList());
+    }
+    public static void main(String[] args) {
+        List<String> list1 = Arrays.asList("a", "b", "c","f");
+        List<String> list2 = Arrays.asList("b","a","e");
+        list1=intersectList(list1,list2);
+        System.out.println(list1);
+    }
+
+    public static String formatRegionName(String name) {
+        String province = null;
+        if (name == null) {
+            return null;
+        } else if (name.endsWith("壮族自治区分公司")) {
+            province = name.replace("壮族自治区分公司", "");
+        } else if (name.endsWith("回族自治区分公司")) {
+            province = name.replace("回族自治区分公司", "");
+        } else if (name.endsWith("维吾尔自治区分公司")) {
+            province = name.replace("维吾尔自治区分公司", "");
+        } else if (name.endsWith("自治区分公司")) {
+            province = name.replace("自治区分公司", "");
+        } else if (name.endsWith("省分公司")) {
+            province = name.replace("省分公司", "");
+        } else if (name.endsWith("市分公司")) {
+            province = name.replace("市分公司", "");
+        } else if (name.equals("全部地区")) {
+            province = "合计";
+        } else if (name.endsWith("分公司")) {
+            province = name.replace("分公司", "");
+        } else if (name.endsWith("地区")) {
+            province = name.replace("地区", "");
+        }else {
+            province = name;
+        }
+        return province;
+    }
+
+
+    //根据时间生成结束时间
+    public static String getEndTime(String time) {
+        Date date = DateUtil.parse(time, "yyyy-MM-dd");
+        Date endTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, 1);
+        return DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    //根据时间生成开始时间
+    public static String getStartTime(String time, String type) {
+        Date date = DateUtil.parse(time, "yyyy-MM-dd");
+        Date startTime = null;
+        if (type.equals("W")) {
+            startTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, -6);
+        } else if (type.equals("M")) {
+            startTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, -29);
+        } else if (type.equals("D")) {
+            startTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, 0);
+        }
+        return DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    //根据时间生成上一周期开始时间
+    public static String getBeforeTime(String time, String type) {
+        Date date = DateUtil.parse(time, "yyyy-MM-dd");
+        Date startTime = null;
+        if (type.equals("W")) {
+            startTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, -13);
+        } else if (type.equals("M")) {
+            startTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, -59);
+        } else if (type.equals("D")) {
+            startTime = DateUtil.offset(date, DateField.DAY_OF_YEAR, -1);
+        }
+        return DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss");
+    }
+
+
+    //合并列表
+    public static <T> List<T> mergeList(List<T> list1, List<T> list2) {
+        List<T> list = new ArrayList<>();
+        if (ObjectUtil.isNotEmpty(list1)) {
+            list.addAll(list1);
+        }
+        if (ObjectUtil.isNotEmpty(list2)) {
+            list.addAll(list2);
+        }
+        return list;
+    }
+
+    public static <T> List<T> mergeList(List<T> list1, List<T> list2, List<T> list3) {
+        List<T> list = new ArrayList<>();
+        if (ObjectUtil.isNotEmpty(list1)) {
+            list.addAll(list1);
+        }
+        if (ObjectUtil.isNotEmpty(list2)) {
+            list.addAll(list2);
+        }
+        if (ObjectUtil.isNotEmpty(list3)) {
+            list.addAll(list3);
+        }
+        return list;
+    }
+
+
+    //查找list1有,list2没有的数据
+    public static List<String> subList(List<String> list1, List<String> list2) {
+        Map<String, String> tempMap = list2.parallelStream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));
+        return list1.parallelStream().filter(str -> !tempMap.containsKey(str)).collect(Collectors.toList());
+    }
+
+    //查找list1、list2的交集
+    public static List<String> intersectList(List<String> list1, List<String> list2) {
+        if (ObjectUtil.isEmpty(list2)) {
+            return null;
+        }
+        Map<String, String> tempMap = list2.parallelStream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));
+        return list1.parallelStream().filter(tempMap::containsKey).collect(Collectors.toList());
+    }
+
+
+    //计算平均值
+    public static String computeAvg(double totalApplicationScore, int num) {
+
+        BigDecimal total = BigDecimal.valueOf(totalApplicationScore);
+        BigDecimal number = BigDecimal.valueOf(num);
+        if (number.compareTo(BigDecimal.valueOf(0)) != 0) {
+
+            double result = total.divide(number, 2, RoundingMode.HALF_UP).doubleValue();
+            return String.valueOf(result);
+        } else {
+            return "0.00";
+        }
+    }
+
+    //计算乘积
+    public static String multiplyNumbers(String num1, String num2) {
+        try {
+            BigDecimal number1 = new BigDecimal(num1);
+            BigDecimal number2 = new BigDecimal(num2);
+            BigDecimal result = number1.multiply(number2).setScale(0, RoundingMode.HALF_UP); // 四舍五入取整数
+            return result.toString();
+        } catch (Exception e) {
+            return "0.00"; // 出现异常时返回默认值
+        }
+    }
+
+    public static String subtractNumbers(String num1, String num2) {
+        try {
+            BigDecimal number1 = new BigDecimal(num1);
+            BigDecimal number2 = new BigDecimal(num2);
+            BigDecimal result = number1.subtract(number2).setScale(2, RoundingMode.HALF_UP); // 保留两位小数
+            return result.toString();
+        } catch (Exception e) {
+            return "0.00"; // 出现异常时返回默认值
+        }
+    }
+
+
+    //合并列表
+    public static <T> List<T> addList(List<T> list1, List<T> list2) {
+
+        if (ObjectUtil.isNotEmpty(list2)) {
+            list1.addAll(list2);
+        }
+        return list1;
+    }
+
+
+    //计算环比
+    public static String computeHb(String before, String now) {
+        try {
+            BigDecimal beforeValue = BigDecimal.valueOf(NumberUtil.parseFloat(before));
+            BigDecimal nowValue = BigDecimal.valueOf(NumberUtil.parseFloat(now));
+            if (beforeValue.compareTo(BigDecimal.valueOf(0)) != 0) {
+                //被除数
+                BigDecimal dividend = nowValue.subtract(beforeValue);
+                double result = dividend.multiply(hundred).divide(beforeValue, 2, RoundingMode.HALF_UP).doubleValue();
+                return String.valueOf(result) + "%";
+            } else {
+                return "0.00%";
+            }
+        } catch (Exception exception) {
+            return "0.00%";
+        }
+    }
+
+    //计算环比
+    public static String computeHb(Integer before, Integer now) {
+        try {
+            BigDecimal beforeValue = BigDecimal.valueOf(before);
+            BigDecimal nowValue = BigDecimal.valueOf(now);
+            if (beforeValue.compareTo(BigDecimal.valueOf(0)) != 0) {
+                //被除数
+                BigDecimal dividend = nowValue.subtract(beforeValue);
+                double result = dividend.multiply(hundred).divide(beforeValue, 2, RoundingMode.HALF_UP).doubleValue();
+                return String.valueOf(result) + "%";
+            } else {
+                return "0.00%";
+            }
+        } catch (Exception exception) {
+            return "0.00%";
+        }
+    }
+
+    //计算环比
+    public static String computeHb(double before, double now) {
+
+        try {
+            BigDecimal beforeValue = BigDecimal.valueOf(before);
+            BigDecimal nowValue = BigDecimal.valueOf(now);
+            if (beforeValue.compareTo(BigDecimal.valueOf(0)) != 0) {
+                //被除数
+                BigDecimal dividend = nowValue.subtract(beforeValue);
+                double result = dividend.multiply(hundred).divide(beforeValue, 2, RoundingMode.HALF_UP).doubleValue();
+                return String.valueOf(result) + "%";
+            } else {
+                return "0.00%";
+            }
+        } catch (Exception exception) {
+            return "0.00%";
+        }
+    }
+
+    //计算占比
+    public static String computeZb(String now, String total) {
+        try {
+            BigDecimal nowValue = BigDecimal.valueOf(NumberUtil.parseFloat(now));
+            BigDecimal totalValue = BigDecimal.valueOf(NumberUtil.parseFloat(total));
+            if (totalValue.compareTo(BigDecimal.valueOf(0)) != 0) {
+                double result = nowValue.multiply(hundred).divide(totalValue, 2, RoundingMode.HALF_UP).doubleValue();
+                return String.valueOf(result) + "%";
+            } else {
+                return "0.00%";
+            }
+        } catch (Exception exception) {
+            return "0.00%";
+        }
+    }
+
+
+    //计算占比
+    public static String computeZb(Integer now, Integer total) {
+        try {
+            BigDecimal nowValue = BigDecimal.valueOf(now);
+            BigDecimal totalValue = BigDecimal.valueOf(total);
+            if (totalValue.compareTo(BigDecimal.valueOf(0)) != 0) {
+                double result = nowValue.multiply(hundred).divide(totalValue, 2, RoundingMode.HALF_UP).doubleValue();
+                return String.valueOf(result) + "%";
+            } else {
+                return "0.00%";
+            }
+        } catch (Exception exception) {
+            return "0.00%";
+        }
+    }
+
+
+    //计算环比
+    public static BigDecimal computeHbValue(float beforeValue, float nowValue) {
+        BigDecimal before = BigDecimal.valueOf(beforeValue);
+        BigDecimal now = BigDecimal.valueOf(nowValue);
+        if (before.compareTo(BigDecimal.valueOf(0)) != 0) {
+            //被除数
+            BigDecimal dividend = now.subtract(before);
+            //环比或同比值
+            return dividend.multiply(hundred).divide(before, 2, RoundingMode.HALF_UP);
+        } else {
+            return new BigDecimal(0);
+        }
+
+    }
+
+
+    //计算占比
+    public static BigDecimal computeZbValue(String value, Float totalValue) {
+        if (totalValue == null) {
+            return null;
+        }
+        if (value == null) {
+            return null;
+        }
+
+        BigDecimal dividend = BigDecimal.valueOf(NumberUtil.parseFloat(value));
+        BigDecimal total = BigDecimal.valueOf(totalValue);
+        //环比或同比值
+        BigDecimal percent = dividend.multiply(hundred).divide(total, 2, RoundingMode.HALF_UP);
+
+        return percent;
+    }
+
+
+
+    public static String getBeforeAggregationTime(String time, String type, String timeFormat) {
+        if ("D".equals(type)) {
+            return DateUtil.format(DateUtil.offsetDay(DateUtil.parse(time, timeFormat), -1), timeFormat);
+        } else if ("W".equals(type)) {
+            return DateUtil.format(DateUtil.offsetWeek(DateUtil.parse(time, timeFormat), -1), timeFormat);
+        } else if ("M".equals(type)) {
+            return DateUtil.format(DateUtil.offsetMonth(DateUtil.parse(time, timeFormat), -1), timeFormat);
+        }
+        return null;
+    }
+
+    //获取上上周期的时间
+    public static String getTwoDurationBeforeAggregationTime(String time, String type, String timeFormat) {
+        if ("D".equals(type)) {
+            return DateUtil.format(DateUtil.offsetDay(DateUtil.parse(time, timeFormat), -2), timeFormat);
+        } else if ("W".equals(type)) {
+            return DateUtil.format(DateUtil.offsetWeek(DateUtil.parse(time, timeFormat), -2), timeFormat);
+        } else if ("M".equals(type)) {
+            return DateUtil.format(DateUtil.offsetMonth(DateUtil.parse(time, timeFormat), -2), timeFormat);
+        }
+        return null;
+    }
+
+    //获取下一天
+    public static String getNextDay(String time, String timeFormat) {
+        String nextDay = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(time, timeFormat), 1), timeFormat);
+        return nextDay;
+    }
+
+    //时间偏移
+    public static String offsetDay(String time, int offsetNum, String timeFormat) {
+        return DateUtil.format(DateUtil.offsetDay(DateUtil.parse(time, timeFormat), offsetNum), timeFormat);
+    }
+
+    //获取去年时间
+    public static String lastYear(String time) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate date = LocalDate.parse(time, formatter);
+        LocalDate lastYearStartDate = date.minusYears(1);
+        return lastYearStartDate.format(formatter);
+    }
+
+    //根据起止时间生成时间列表
+    public static List<String> getAggregationTimeList(String startTime, String endTime, String timeFormat) {
+        Date start = DateUtil.parse(startTime, timeFormat);
+        Date end = DateUtil.parse(endTime, timeFormat);
+        Date temp = start;
+
+        List<String> timeList = new ArrayList<>();
+        while (temp.before(end)) {
+            timeList.add(DateUtil.format(temp, timeFormat));
+            temp = DateUtil.offsetDay(temp, 1);
+        }
+        timeList.add(endTime);
+        return timeList;
+    }
+
+
+    //根据起止时间生成前一周期时间列表
+    public static List<String> getBeforeAggregationTimeList(String startTime, String endTime, String timeFormat) {
+        Date start = DateUtil.parse(startTime, timeFormat);
+        Date end = DateUtil.parse(endTime, timeFormat);
+        Date temp = start;
+
+        List<String> timeList = new ArrayList<>();
+        while (temp.before(end)) {
+            timeList.add(DateUtil.format(temp, timeFormat));
+            temp = DateUtil.offsetDay(temp, 1);
+        }
+        timeList.add(endTime);
+        return timeList;
+    }
+
+    public static List<String> checkListNull(List<String> list) {
+        if (ObjectUtil.isNotEmpty(list)) {
+            return list;
+        } else {
+            return new ArrayList<>();
+        }
+    }
+
+    public static double convertPercentageToDouble(String percentage) {
+        // 去除字符串末尾的百分号
+        String numberStr = percentage.replace("%", "");
+        try {
+            // 将去除百分号后的字符串转换为 double 类型
+            double number = Double.parseDouble(numberStr);
+            // 将得到的数值除以 100 以得到对应的小数形式
+            return number / 100;
+        } catch (NumberFormatException e) {
+            // 若转换过程中出现异常,打印错误信息并返回 0
+            System.err.println("输入的字符串无法转换为有效的数字: " + percentage);
+            return 0;
+        }
+    }
+
+    public static String formatRateValue(String value) {
+        try {
+            if (value == null) {
+                return "0.00%";
+            }
+            if (value.equals("Infinity")) {
+                return "0.00%";
+            }
+            if (value.equals("NaN")) {
+                return "0.00%";
+            }
+            float result = NumberUtil.parseFloat(value) * 100;
+            return String.format("%.2f", result)+"%";
+        } catch (Exception e) {
+            return "0.00%";
+        }
+    }
+
+    public static String getParentRegionCode(String parentRegionCode) {
+        if (parentRegionCode.equals("110")) {
+            return "all";
+        } else if (parentRegionCode.equals("")) {
+            return "all";
+        } else {
+            return parentRegionCode;
+        }
+
+    }
+
+
+    public static int getDayNumByType(String type) {
+        if (type.equals("M")) {
+            return 30;
+        } else if (type.equals("W")) {
+            return 7;
+        } else {
+            return 1;
+        }
+    }
+
+
+    //用户数/(正式员工基数+代维用户数+非网络线人数)
+    public static String computePenetrationRate(int userNoRepeatNum, int formalBaseNum, int userAgentNum, int notNetworkCableNum) {
+
+        BigDecimal sum = BigDecimal.valueOf(formalBaseNum).add(BigDecimal.valueOf(userAgentNum)).add(BigDecimal.valueOf(notNetworkCableNum));
+
+        BigDecimal num = BigDecimal.valueOf(userNoRepeatNum);
+
+        if (userNoRepeatNum == 0) {
+            return "0";
+        }
+
+        if (sum.compareTo(BigDecimal.valueOf(0)) != 0) {
+            float result = num.multiply(hundred).divide(sum, 2, RoundingMode.HALF_UP).floatValue();
+            return String.valueOf(result);
+        }
+
+        return "0";
+    }
+
+
+
+    //格式化数据
+    public static String numberFormatPercent(String number) {
+        try {
+            boolean isNumFlag = ReUtil.isMatch(regex, number);
+
+            if (isNumFlag) {
+                NumberFormat nf = NumberFormat.getPercentInstance();
+                nf.setMaximumFractionDigits(2);
+                return nf.format(Double.parseDouble(number));
+            }
+
+            if (number.endsWith("%")) {
+                return number;
+            }
+
+        } catch (Exception ignored) {
+            return "- -";
+        }
+        return "0.00%";
+    }
+
+}