浏览代码

利润单-头条

yangzian 3 年之前
父节点
当前提交
0492be9a2e

+ 4 - 1
jeecg-boot-finance/src/main/java/org/jeecg/ctop/finance/settlement/mapper/ReportSettlementMapper.java

@@ -52,7 +52,8 @@ public interface ReportSettlementMapper {
      * 查询 头条利润表 总花费
      * @return
      */
-    List<Map<String,Object>> getProfitBytedanceCost(@Param("startTime") String startTime,@Param("endTime") String endTime);
+    List<Map<String,Object>> getProfitBytedanceAccountCost(@Param("accountId") String accountId,@Param("startTime") String startTime,@Param("endTime") String endTime);
+    List<Map<String,Object>> getProfitBytedanceCost(@Param("accountId") String accountId,@Param("startTime") String startTime,@Param("endTime") String endTime);
 
     /**
      * 查询 快手 利润表 总花费
@@ -68,6 +69,8 @@ public interface ReportSettlementMapper {
      */
     List<Map<String,Object>> getProfitBytedance(@Param("productName") String productName,@Param("mediaType") String mediaType,@Param("startTime")String startTime,@Param("endTime")String endTime);
 
+    Map<String,Object> getProfitRebate(@Param("productName") String productName,@Param("startTime")String startTime,@Param("endTime")String endTime);
+
     Map<String,Object> getProfitBytedanceSale(String accountId);
 
     Map<String,Object> getProfitBytedanceOperate(String accountId);

+ 64 - 2
jeecg-boot-finance/src/main/java/org/jeecg/ctop/finance/settlement/mapper/xml/ReportSettlementMapper.xml

@@ -75,8 +75,8 @@
 
 
 
-    <!-- 查询 头条利润表 总花费-->
-    <select id="getProfitBytedanceCost" resultType="java.util.LinkedHashMap">
+    <!-- 查询 头条利润表 所用账户-->
+    <select id="getProfitBytedanceAccountCost" resultType="java.util.LinkedHashMap">
         SELECT
         d.advertiser_id AS accountId,
         SUM( d.cost ) AS cost,
@@ -89,13 +89,18 @@
         LEFT JOIN ctop_user_allocation u ON d.advertiser_id = u.account_id
         LEFT JOIN ctop_project p ON u.project_id = p.id
         LEFT JOIN ctop_product pd on pd.id = p.product_id
+
         <where>
+            <if test="accountId !=null and accountId != ''">
+                AND d.advertiser_id = #{accountId}
+            </if>
             <if test="startTime !=null and startTime != ''">
                 AND d.date &gt;= #{startTime}
             </if>
             <if test="endTime !=null and endTime != ''">
                 AND d.date &lt;= #{endTime}
             </if>
+            AND u.media_id = 1 or u.media_id = 3
         </where>
         GROUP BY
             d.advertiser_id;
@@ -103,6 +108,36 @@
     </select>
 
 
+    <!-- 查询 头条利润表 总花费-->
+    <select id="getProfitBytedanceCost" resultType="java.util.LinkedHashMap">
+        SELECT
+        d.advertiser_id AS accountId,
+        SUM( d.cost ) AS cost,
+        SUM( d.cash_cost ) AS cashCost,
+        SUM( d.reward_cost ) rewardCost,
+        pd.id as productId,
+        pd.product_name AS productName
+        FROM
+        ctop_account_transaction_day d
+        LEFT JOIN ctop_user_allocation u ON d.advertiser_id = u.account_id
+        LEFT JOIN ctop_project p ON u.project_id = p.id
+        LEFT JOIN ctop_product pd on pd.id = p.product_id
+        where (u.media_id = 1 or u.media_id = 3)
+            <if test="accountId !=null and accountId != ''">
+                AND d.advertiser_id = #{accountId}
+            </if>
+            <if test="startTime !=null and startTime != ''">
+                AND d.date &gt;= #{startTime}
+            </if>
+            <if test="endTime !=null and endTime != ''">
+                AND d.date &lt;= #{endTime}
+            </if>
+
+
+
+    </select>
+
+
 
     <!-- 查询 头条利润表  返点类型和比列-->
     <select id="getProfitBytedance" resultType="java.util.LinkedHashMap">
@@ -135,6 +170,33 @@
             AND cp.policy_end_date &lt;= #{endTime}
         </if>
 
+    </select>
+
+
+    <!-- 查询 利润表  返点类型和比列-->
+    <select id="getProfitRebate" resultType="java.util.LinkedHashMap">
+        SELECT
+        p.id,
+        p.rebate_type AS rebateType,
+        p.rebate_rate AS rebateRate
+        FROM
+        ctop_cwjs_slettement_report r
+        LEFT JOIN ctop_cwjs_policy_info p ON r.policy_id = p.id
+        WHERE
+        p.del_flag = 0
+        <if test="productName !=null and productName != ''">
+            AND r.product_name = #{productName}
+        </if>
+        <if test="startTime !=null and startTime != ''">
+            AND  r.policy_date &gt;= #{startTime}
+        </if>
+        <if test="endTime !=null and endTime != ''">
+            AND r.policy_date &lt;= #{endTime}
+        </if>
+        GROUP BY
+        p.id
+        limit 1
+
 
 
 

+ 109 - 40
jeecg-boot-finance/src/main/java/org/jeecg/ctop/finance/settlement/service/serviceImpl/ReportSettlementServiceImpl.java

@@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
 import cn.com.ctop.common.module.mapper.MailLogMapper;
 import cn.com.ctop.common.module.utils.CorpWexinUtils;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.gson.JsonObject;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -18,27 +19,28 @@ import org.jeecg.ctop.finance.policy.entity.CwjsPolicyInfo;
 import org.jeecg.ctop.finance.policy.entity.CwjsPolicyProduct;
 import org.jeecg.ctop.finance.policy.mapper.CwjsPolicyProductMapper;
 import org.jeecg.ctop.finance.policy.utils.Check;
+import org.jeecg.ctop.finance.settlement.entity.pojo.CtopCwjsSettlementInfo;
 import org.jeecg.ctop.finance.settlement.entity.pojo.CtopCwjsSlettementReport;
 import org.jeecg.ctop.finance.settlement.entity.vo.*;
 import org.jeecg.ctop.finance.settlement.mapper.CwjsProfitMapper;
 import org.jeecg.ctop.finance.settlement.mapper.ReportSettlementMapper;
+import org.jeecg.ctop.finance.settlement.mapper.SettlementInfoMapper;
 import org.jeecg.ctop.finance.settlement.service.IReportSettlementService;
 import org.jeecg.ctop.finance.utils.SettlementUtil;
 import org.jeecg.ctop.finance.utils.createExcelByTemplate;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletResponse;
+import javax.swing.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.net.URLEncoder;
 import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -436,7 +438,8 @@ public class ReportSettlementServiceImpl implements IReportSettlementService {
 
 
 
-
+    @Resource
+    private SettlementInfoMapper settlementInfoMapper;
     /**
      *
      * @description: 财务结算 利润表导出 头条
@@ -449,55 +452,104 @@ public class ReportSettlementServiceImpl implements IReportSettlementService {
     public Result porfitReportBytedance(SettlementFileParamsVo paramsVo, HttpServletResponse response) {
 
         try {
-            //查询 头条利润表 总花费
-            List<Map<String,Object>> list = reportSettlementMapper.getProfitBytedanceCost(paramsVo.getStartTime(),paramsVo.getEndTime());
+            //查询 头条利润表 时间段内 所有 账户
+            List<Map<String,Object>> list = reportSettlementMapper.getProfitBytedanceAccountCost(null,paramsVo.getStartTime(),paramsVo.getEndTime());
             if (Check.isNull(list)){
                 return Result.errorMsg("暂无数据。");
             }
             List<ProfitReportBytedanceVo> resultList = new ArrayList<>(list.size());
             for (Map<String, Object> map : list) {
-                ProfitReportBytedanceVo vo = new ProfitReportBytedanceVo();
-                vo.setCost(map.getOrDefault("cost","")+"");//总消耗
-                vo.setCashCost(map.getOrDefault("cashCost","")+"");//现金消耗
-                vo.setRewardCost(map.getOrDefault("rewardCost","")+"");//赠款消耗
-                vo.setProductName(map.getOrDefault("productName","")+"");//产品名称
+                //查看该账户 状态信息
+                QueryWrapper<CtopCwjsSettlementInfo> settlementAccountQw = new QueryWrapper<>();
+                settlementAccountQw.eq("account_id",map.get("accountId"));
+                //账户状态 0-开 1-关
+                settlementAccountQw.eq("status",0);
+                //(0,正常,1已删除)
+                settlementAccountQw.eq("del_flag",0);
+                List<CtopCwjsSettlementInfo> settlementAccountList =  settlementInfoMapper.selectList(settlementAccountQw);
+                if (Check.isNull(settlementAccountList)){
+                    continue;
+                }
 
+                ProfitReportBytedanceVo voSource = new ProfitReportBytedanceVo();
                 //查询销售
                 Map<String,Object> slaeMap = reportSettlementMapper.getProfitBytedanceSale(map.get("accountId")+"");
-                vo.setSaleName(Check.isNull(slaeMap) ? "" : slaeMap.getOrDefault("saleName","")+"");//销售
-                //查询 头条利润表  返点类型和比列
-                List<Map<String,Object>> rateMap = reportSettlementMapper.getProfitBytedance(map.get("productName")+"","1",paramsVo.getStartTime(),paramsVo.getEndTime());
-
-
-
-
+                voSource.setSaleName(Check.isNull(slaeMap) ? "" : slaeMap.getOrDefault("saleName","")+"");//销售
 
+                //产品名称
+                voSource.setProductName(map.getOrDefault("productName","")+"");
 
+                Map<String,Object> operateMap = reportSettlementMapper.getProfitBytedanceOperate(map.get("accountId")+"");
+                if (!Check.isNull(operateMap)){
+                    voSource.setAdvertiserName(operateMap.getOrDefault("advertiserName","")+"");//广告主名称
+                    voSource.setOperateName(operateMap.getOrDefault("operateName","")+"");//运营
+                    voSource.setOperateArea(operateMap.getOrDefault("operateArea","")+"");//运营所属区域
+                }
 
+                //查询 头条利润表  返点类型和比列
+                List<Map<String,Object>> rateMap = reportSettlementMapper.getProfitBytedance(map.get("productName")+"","1",paramsVo.getStartTime(),paramsVo.getEndTime());
+                List listPolicyTIme = new ArrayList();
+                for (Map<String, Object> rate : rateMap) {
+                    listPolicyTIme.add(rate.get("policyStartDate"));
+                    listPolicyTIme.add(rate.get("policyEndDate"));
+                }
+                //政策时间 去重 排序
+                List<Object> times = SettlementUtil.sortlistTest(listPolicyTIme);
+                // 使用政策的时间段 拼接 开始 和 截至 时间
+                List<Map<String, String>> arrayList = new ArrayList<>();
+                for ( int i = 0; i < times.size(); i++) {
+                    HashMap<String, String> mapTime = new HashMap<>();
+                    mapTime.put("startDate", times.get(i).toString());
+                    mapTime.put("endDate",  times.get(i+1).toString());
+                    i += 1;
+                    arrayList.add(mapTime);
+                }
 
-                /*
-                if (!Check.isNull(rateMap)){
-                    // 当前查询时间 与 销售政策 开始 截至时间 是否匹配
-                    if (SettlementUtil.isEffectiveDate(paramsVo.getUploadYears(),rateMap.get("policyStart")+"",rateMap.get("policyEnd")+"")){
-                        //销售政策状态 为 通过 显示 返点类型 和 返点比列
-                        if (StringUtils.equals(rateMap.getOrDefault("approvedStatus","")+"","3")){
-                            vo.setRebateType(rateMap.getOrDefault("rebateType","")+"");//返点类型
-                            vo.setRebateRate(rateMap.getOrDefault("rebateRate","")+"");//返点比列
-                        }
-                    }
-                }*/
+                //政策所有时间点
+                List<String> policyDaysList = new ArrayList<>();
+                for (Map<String, String> stringMap : arrayList) {
+                    ProfitReportBytedanceVo vo = new ProfitReportBytedanceVo();
+                    //使用政策 返点类型和比例
+                    Map<String,Object>  policyRateMap = reportSettlementMapper.getProfitRebate(map.get("productName")+"",stringMap.get("startDate"),stringMap.get("endDate"));
+                    vo.setRebateType(policyRateMap.getOrDefault("rebateType","")+"");//返点类型
+                    vo.setRebateRate(policyRateMap.getOrDefault("rebateRate","")+"");//返点比列
+                    // 时间段内 账户流水 信息
+                    List<Map<String,Object>> listAccount = reportSettlementMapper.getProfitBytedanceCost(map.get("accountId")+"",stringMap.get("startDate"),stringMap.get("endDate"));
+                    listAccount.removeAll(Collections.singleton(null));
+                    vo.setCost(Check.isNull(listAccount) ? "0" : listAccount.get(0).getOrDefault("cost","")+"");//总消耗
+                    vo.setCashCost(Check.isNull(listAccount) ? "0" : listAccount.get(0).getOrDefault("cashCost","")+"");//现金消耗
+                    vo.setRewardCost(Check.isNull(listAccount) ? "0" : listAccount.get(0).getOrDefault("rewardCost","")+"");//赠款消耗
+                    BeanUtils.copyProperties(voSource,vo,SettlementUtil.getNullPropertyNames(voSource));
+                    resultList.add(vo);
+                    policyDaysList.addAll(SettlementUtil.getAllDatesOfTwoTimes(stringMap.get("startDate"),stringMap.get("endDate")));
+                }
 
-                Map<String,Object> operateMap = reportSettlementMapper.getProfitBytedanceOperate(map.get("accountId")+"");
-                if (!Check.isNull(operateMap)){
-                    vo.setAdvertiserName(operateMap.getOrDefault("advertiserName","")+"");//广告主名称
-                    vo.setOperateName(operateMap.getOrDefault("operateName","")+"");//运营
-                    vo.setOperateArea(operateMap.getOrDefault("operateArea","")+"");//运营所属区域
+                //不使用政策 的时间段
+                // 获取两个日期之间 所有的 时间 年-月-日
+                List<String> betweenDaysList = SettlementUtil.getAllDatesOfTwoTimes(paramsVo.getStartTime(),paramsVo.getEndTime());
+                // 时间差集(所有时间段 - 使用政策的时间段)
+                List<String>  reduceList = betweenDaysList.stream().filter(item -> !policyDaysList.contains(item)).collect(Collectors.toList());
+                //差集拼接  开始 和 结束时间
+                List<Map<String, String>> stringList = SettlementUtil.getTime(reduceList);
+                for (Map<String, String> stringMap : stringList) {
+                    ProfitReportBytedanceVo vo = new ProfitReportBytedanceVo();
+                    // 不使用 政策 则 返点为空
+                    //政策 返点类型和比例
+                   /* Map<String,Object>  policyRateMap = reportSettlementMapper.getProfitRebate(map.get("productName")+"",stringMap.get("startDate"),stringMap.get("endDate"));
+                  */
+                    vo.setRebateType("");//返点类型
+                    vo.setRebateRate("");//返点比列
+                    //账户流水 信息
+                    List<Map<String,Object>> listAccount = reportSettlementMapper.getProfitBytedanceCost(map.get("accountId")+"",stringMap.get("startDate"),stringMap.get("endDate"));
+                    listAccount.removeAll(Collections.singleton(null));
+                    vo.setCost(Check.isNull(listAccount) ? "0" : listAccount.get(0).getOrDefault("cost","")+"");//总消耗
+                    vo.setCashCost(Check.isNull(listAccount) ? "0" : listAccount.get(0).getOrDefault("cashCost","")+"");//现金消耗
+                    vo.setRewardCost(Check.isNull(listAccount) ? "0" : listAccount.get(0).getOrDefault("rewardCost","")+"");//赠款消耗
+                    BeanUtils.copyProperties(voSource,vo,SettlementUtil.getNullPropertyNames(voSource));
+                    resultList.add(vo);
                 }
-                resultList.add(vo);
             }
-
             Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("头条利润单", "头条利润单"), ProfitReportBytedanceVo.class, resultList);
-
             try {
                 response.setCharacterEncoding("UTF-8");
                 response.setHeader("content-Type", "application/vnd.ms-excel");
@@ -688,17 +740,34 @@ public class ReportSettlementServiceImpl implements IReportSettlementService {
         List list = new ArrayList();
 
         list.add("2021-07-01");
-        list.add("2021-07-05");
+       // list.add("2021-07-02");
         list.add("2021-07-10");
+        list.add("2021-07-05");
         list.add("2021-07-15");
 
 
-        List<Object> times = SettlementUtil.sortlistTest(list);
 
 
+        // 获取两个日期之间 所有的 时间 年-月-日
+        List<String> betweenDaysList = SettlementUtil.getAllDatesOfTwoTimes("2021-07-01","2021-07-20");
+
+        List<Object> times = SettlementUtil.sortlistTest(list);
+
+        //差集
+        List<String>  reduceList = betweenDaysList.stream().filter(item -> !times.contains(item)).collect(Collectors.toList());
 
 
+        System.out.println(betweenDaysList);
         System.out.println(times);
+        System.out.println(reduceList);
+
+       List<Map<String,String>> stringList = SettlementUtil.getTime(reduceList);
+
+        System.out.println(stringList);
+
+
+
+
 
 
     }

+ 150 - 34
jeecg-boot-finance/src/main/java/org/jeecg/ctop/finance/utils/SettlementUtil.java

@@ -8,10 +8,14 @@ import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
+import java.time.Period;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * zian Y
@@ -23,7 +27,7 @@ public class SettlementUtil {
     public static String getFileNameNoEx(String filename) {
         if ((filename != null) && (filename.length() > 0)) {
             int dot = filename.lastIndexOf('.');
-            if ((dot >-1) && (dot < (filename.length()))) {
+            if ((dot > -1) && (dot < (filename.length()))) {
                 return filename.substring(0, dot);
             }
         }
@@ -33,12 +37,13 @@ public class SettlementUtil {
     /**
      * 格式:123456-1
      * 截取 账户 id
+     *
      * @param str
      * @return
      */
-    public static String subAccountName(String str){
-        if (!Check.isNull(str)){
-            if (str.contains("-")){
+    public static String subAccountName(String str) {
+        if (!Check.isNull(str)) {
+            if (str.contains("-")) {
                 return str.substring(0, str.indexOf("-"));
             }
         }
@@ -50,11 +55,11 @@ public class SettlementUtil {
     /**
      * @Description: 忽略null值/只拷贝非null属性
      */
-    public static String[] getNullPropertyNames (Object source) {
+    public static String[] getNullPropertyNames(Object source) {
         final BeanWrapper src = new BeanWrapperImpl(source);
         java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
         Set<String> emptyNames = new HashSet<String>();
-        for(java.beans.PropertyDescriptor pd : pds) {
+        for (java.beans.PropertyDescriptor pd : pds) {
             Object srcValue = src.getPropertyValue(pd.getName());
             if (srcValue == null) emptyNames.add(pd.getName());
         }
@@ -63,9 +68,9 @@ public class SettlementUtil {
     }
 
 
-
     /**
      * 获取网络图片转成字节流
+     *
      * @param strUrl 完整图片地址
      * @return 图片资源数组
      */
@@ -89,13 +94,14 @@ public class SettlementUtil {
 
     /**
      * 从输入流中获取字节流数据
+     *
      * @param inStream 输入流
-     * @return  图片流
+     * @return 图片流
      */
     private static byte[] readInputStream(InputStream inStream) throws Exception {
         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
         // 设置每次读取缓存区大小
-        byte[] buffer = new byte[1024*10];
+        byte[] buffer = new byte[1024 * 10];
         int len = 0;
         while ((len = inStream.read(buffer)) != -1) {
             outStream.write(buffer, 0, len);
@@ -106,10 +112,11 @@ public class SettlementUtil {
 
     /**
      * 获取日期的年月
+     *
      * @param strDate
      * @return
      */
-    public static int getYearMonth(String strDate)throws Exception{
+    public static int getYearMonth(String strDate) throws Exception {
 
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
         Date date = simpleDateFormat.parse(strDate);
@@ -117,23 +124,23 @@ public class SettlementUtil {
         Calendar cal = Calendar.getInstance();
         cal.setTime(date);//设置时间
         int year = cal.get(Calendar.YEAR);//获取年份
-        int month=cal.get(Calendar.MONTH);//获取月份
-        return year*100+month;//返回年份乘以100加上月份的值,因为月份最多2位数,所以年份乘以100可以获取一个唯一的年月数值
+        int month = cal.get(Calendar.MONTH);//获取月份
+        return year * 100 + month;//返回年份乘以100加上月份的值,因为月份最多2位数,所以年份乘以100可以获取一个唯一的年月数值
     }
 
 
-
     /**
      * 判断当前时间是否在[startTime, endTime]区间
      * 年-月   2021-08
-     * @param nowStrTime 当前时间
+     *
+     * @param nowStrTime   当前时间
      * @param startStrTime 开始时间
-     * @param endStrTime 结束时间
+     * @param endStrTime   结束时间
      * @return
      * @author zian Y
      */
     public static boolean isEffectiveDate(String nowStrTime, String startStrTime, String endStrTime) throws Exception {
-       // SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        // SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
         Date nowTime = simpleDateFormat.parse(nowStrTime);
         Date startTime = simpleDateFormat.parse(startStrTime);
@@ -157,18 +164,13 @@ public class SettlementUtil {
     }
 
 
-
-
-
-
-
     public static long DateCompare(String s1, String s2) {
         try {
 
             SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
             Date d1 = simpleDateFormat.parse(s1);
             Date d2 = simpleDateFormat.parse(s2);
-           // LocalDateTime d1 = LocalDateTime.parse(s1, DateTimeFormatter.ISO_LOCAL_DATE);
+            // LocalDateTime d1 = LocalDateTime.parse(s1, DateTimeFormatter.ISO_LOCAL_DATE);
             //LocalDateTime d2 = LocalDateTime.parse(s2, DateTimeFormatter.ISO_LOCAL_DATE);
             //排序规则
             return ((d1.getTime()) - (d2.getTime()));
@@ -178,30 +180,30 @@ public class SettlementUtil {
         return 0;
     }
 
-    public static List<String> sortlistTest(List<String> list){
+    public static List<String> sortlistTest(List<String> list) {
         //去重
         List<String> newlist = new ArrayList<String>();
-        for(int i=0; i<list.size(); i++){
-            if(!newlist.contains(list.get(i))){
+        for (int i = 0; i < list.size(); i++) {
+            if (!newlist.contains(list.get(i))) {
                 newlist.add(list.get(i));
             }
         }
         String tmp;
-        for(int i=1; i<newlist.size(); i++){
+        for (int i = 1; i < newlist.size(); i++) {
             tmp = newlist.get(i);
-            int j=i-1;
-            for(; j>=0&&(DateCompare(tmp, newlist.get(j))<0); j--){
-                newlist.set(j+1, newlist.get(j));
+            int j = i - 1;
+            for (; j >= 0 && (DateCompare(tmp, newlist.get(j)) < 0); j--) {
+                newlist.set(j + 1, newlist.get(j));
             }
-            newlist.set(j+1, tmp);
+            newlist.set(j + 1, tmp);
         }
         return newlist;
     }
 
 
-
     /**
      * 获取 两个日期之间的所有 日期
+     *
      * @param startDate
      * @param endDate
      * @return
@@ -209,7 +211,7 @@ public class SettlementUtil {
     public static List<String> getAllDatesOfTwoTimes(String startDate, String endDate) {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
         List<String> dateList = new ArrayList<String>();
-        try{
+        try {
             Date dateOne = sdf.parse(startDate);
             Date dateTwo = sdf.parse(endDate);
 
@@ -217,17 +219,131 @@ public class SettlementUtil {
             calendar.setTime(dateOne);
 
             dateList.add(startDate);
-            while(calendar.getTime().before(dateTwo)){ //倒序时间,顺序after改before其他相应的改动。
+            while (calendar.getTime().before(dateTwo)) { //倒序时间,顺序after改before其他相应的改动。
                 calendar.add(Calendar.DAY_OF_MONTH, 1);
                 dateList.add(sdf.format(calendar.getTime()));
             }
-        } catch(Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return dateList;
     }
 
 
+    public static List<Map<String, String>> getTime( List<String> list) {
+        //初始化list,且该list中的日期是升序的。
+        //List<String> list = Arrays.asList("2020-11-19","2020-11-20","2020-11-21","2021-07-20");
+       /* List<String> list = Arrays.asList("2021-07-02", "2021-07-03", "2021-07-04", "2021-07-06",
+                "2021-07-07", "2021-07-08", "2021-07-09", "2021-07-11", "2021-07-12",
+                "2021-07-13", "2021-07-14", "2021-07-16", "2021-07-17", "2021-07-18",
+                "2021-07-19", "2021-07-20", "2021-07-21", "2021-07-22", "2021-07-23",
+                "2021-07-24", "2021-07-25", "2021-07-26", "2021-07-27", "2021-07-28",
+                "2021-07-29", "2021-07-30");
+        */
+        List<Map<String, String>> arrayList = new ArrayList<>();
+        int num = 0;
+        for (int i = 0; i < list.size(); i = num) {
+            String start = list.get(i);
+            String end = "";
+            if (i == list.size() - 1) {
+                end = start;
+            }
+            int n = 0;
+            for (int j = i + 1; j < list.size(); j++) {
+                //判断当前日期的后一天与list中该元素的下一个元素是否相等
+                if (getSpecifiedDayAfter(list.get(j - 1)).equals(list.get(j))) {
+                    end = list.get(j);
+                    n++;
+                    num++;
+                    continue;
+                } else {
+                    //list中该元素不是连续的
+                    if (n == 0) {
+                        end = list.get(j - 1);
+                    }
+                    break;
+                }
+            }
+            num = num + 1;
+            HashMap<String, String> map = new HashMap<>();
+            map.put("startDate", start);
+            map.put("endDate", end);
+            arrayList.add(map);
+        }
+
+       // System.out.println(arrayList);
+        return arrayList;
+
+
+}
+
+    /**
+     * 获取当前日期的后一天
+     * @param specifiedDay
+     * @return
+     */
+    public static String getSpecifiedDayAfter(String specifiedDay) {
+        Calendar c = Calendar.getInstance();
+        Date date = null;
+        try {
+            date = new SimpleDateFormat("yyyy-MM-dd").parse(specifiedDay);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        c.setTime(date);
+        int day = c.get(Calendar.DATE);
+        c.set(Calendar.DATE, day + 1);
+        String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
+        return dayAfter;
+    }
+
+    public static void main(String[] args) {
+
+
+
+            List list = new ArrayList();
+
+
+            Map map1 = new HashMap();
+            map1.put("startTime","2021-07-01");
+            map1.put("endTime","2021-07-05");
+
+            Map map2 = new HashMap();
+            map2.put("startTime","2021-07-10");
+            map2.put("endTime","2021-07-15");
+
+
+            list.add("2021-07-01");
+            list.add("2021-07-02");
+            //list.add("2021-07-03");
+            list.add("2021-07-04");
+            list.add("2021-07-05");
+
+
+
+
+            // 获取两个日期之间 所有的 时间 年-月-日
+            List<String> betweenDaysList = SettlementUtil.getAllDatesOfTwoTimes("2021-07-01","2021-07-10");
+
+            List<Object> times = SettlementUtil.sortlistTest(list);
+
+            //差集
+            List<String>  reduceList = betweenDaysList.stream().filter(item -> !times.contains(item)).collect(Collectors.toList());
+
+
+            System.out.println(betweenDaysList);
+            System.out.println(times);
+            System.out.println(reduceList);
+
+            List<Map<String, String>> stringList = SettlementUtil.getTime(reduceList);
+
+            System.out.println(stringList);
+
+
+
+
+
+    }