Jelajahi Sumber

1.利润分析详情新需求

wuhp 1 tahun lalu
induk
melakukan
a0ccd82477

+ 7 - 0
src/main/java/com/ydtech/modules/admin/model/report/profitAnalysis/ProfitAnalysisDto.java

@@ -84,6 +84,13 @@ public class ProfitAnalysisDto {
     @ApiModelProperty("类目")
     private String category;
 
+    @ApiModelProperty("子类目类目")
+    private String subcategory;
+
+
+    @ApiModelProperty("占比")
+    private String radio;
+
     @ApiModelProperty("子级")
     private List<ProfitAnalysisDto> children;
 

+ 4 - 0
src/main/java/com/ydtech/modules/admin/model/report/profitAnalysis/ProfitAnalysisQueryDto.java

@@ -50,4 +50,8 @@ public class ProfitAnalysisQueryDto {
     @ApiModelProperty("支出ids")
     private List<String> expensesIds;
 
+
+    @ApiModelProperty("类目ids")
+    private List<String> ids;
+
 }

+ 160 - 7
src/main/java/com/ydtech/modules/admin/service/impl/ProfitAnalysisServiceImpl.java

@@ -1,23 +1,28 @@
 package com.ydtech.modules.admin.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto;
 import com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisQueryDto;
 import com.ydtech.modules.admin.service.ProfitAnalysisService;
 import com.ydtech.modules.admin.utils.SliceUpDateUtil;
 import com.ydtech.modules.console.dao.ProfitAnalysisMapper;
 import com.ydtech.modules.fnc.dao.InsPlyIncomeMapper;
+import com.ydtech.modules.inv.dao.InvAccountExpensesMapper;
 import com.ydtech.modules.inv.dao.InvAccountMapper;
 import com.ydtech.modules.inv.model.InvAccount;
 import com.ydtech.modules.inv.model.InvAccountCardVo;
 import com.ydtech.modules.inv.model.InvAccountExpenses;
 import com.ydtech.utils.BigDecimalUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  *  @version
@@ -35,6 +40,10 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
     @Autowired
     private ProfitAnalysisMapper profitAnalysisMapper;
 
+
+    @Autowired
+    private InvAccountExpensesMapper invAccountExpensesMapper;
+
     /**
      *  @version
      *  @author: hxl
@@ -87,11 +96,32 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
     @Override
     public List<ProfitAnalysisDto> getProfitAnalysisQueryDetailsList(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
         List<ProfitAnalysisDto> resultList =new ArrayList<>();
-
+//          总支出=人员成本+固定成本+变动成本+税费
+        BigDecimal allExpenditure =this.getAllExpenditure(profitAnalysisQueryDto);
         if (StringUtils.isNotEmpty(profitAnalysisQueryDto.getExpensesType()) && "3".equals(profitAnalysisQueryDto.getExpensesType())) {
             List<ProfitAnalysisDto> profitAnalysisDtos =  profitAnalysisMapper.selectAccountExpenses(profitAnalysisQueryDto);
-            resultList.addAll(profitAnalysisDtos) ;
-            List<ProfitAnalysisDto> addVariableCost = new ArrayList<>();
+
+            Map<String, ProfitAnalysisDto> map = new HashMap<>();
+            for (ProfitAnalysisDto dto : profitAnalysisDtos) {
+                map.put(dto.getExpensesId(), dto);
+            }
+            ArrayList<ProfitAnalysisDto> parentExpenIdList = new ArrayList<>();
+            // 如果没有parentId为0 的子级 则构建
+            for (ProfitAnalysisDto profitAnalysisDto : profitAnalysisDtos) {
+                if(ObjectUtils.isEmpty(map.get(profitAnalysisDto.getParentId())) && !profitAnalysisDto.getParentId() .equals("0")){
+                    QueryWrapper<InvAccountExpenses> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("expenses_id", profitAnalysisDto.getParentId());
+                    InvAccountExpenses invAccountExpenses = invAccountExpensesMapper.selectOne(queryWrapper);
+                    ProfitAnalysisDto profitAnalysisDto1 = new ProfitAnalysisDto();
+                    profitAnalysisDto1.setExpensesId(invAccountExpenses.getExpensesId());
+                    profitAnalysisDto1.setParentId(invAccountExpenses.getParentId());
+                    profitAnalysisDto1.setCategory(invAccountExpenses.getCategory());
+                    parentExpenIdList.add(profitAnalysisDto1);
+                    map.put(profitAnalysisDto1.getExpensesId(),profitAnalysisDto1);
+                }
+            }
+            profitAnalysisDtos.addAll(parentExpenIdList);
+            List<ProfitAnalysisDto> addVariableCost = new ArrayList<>();  //变动成本金额
             List<ProfitAnalysisDto> profitAnalysisDto1 = insPlyIncomeMapper.changeAmount(profitAnalysisQueryDto);
             for (ProfitAnalysisDto analysisDto : profitAnalysisDto1) {
                 String outCardNum = analysisDto.getOutCardNum();
@@ -105,7 +135,6 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
                     }
                 }
             }
-
             Map<String, BigDecimal> profitAnalysisDtoMap = addVariableCost.stream()
                     .collect(Collectors.toMap(
                             ProfitAnalysisDto::getExpensesId,  // keyMapper,用于提取键(expensesId)
@@ -113,19 +142,143 @@ public class ProfitAnalysisServiceImpl implements ProfitAnalysisService {
                             BigDecimal::add                    // mergeFunction,用于处理键冲突(相加 applyAmount)
                     ));
 
-            for (ProfitAnalysisDto profitAnalysisDto : resultList) {
+            for (ProfitAnalysisDto profitAnalysisDto : profitAnalysisDtos) {
                 String expensesId = profitAnalysisDto.getExpensesId();
                 if (profitAnalysisDtoMap.containsKey(expensesId)) {
                     BigDecimal bigDecimal = profitAnalysisDtoMap.get(expensesId);
                     profitAnalysisDto.setApplyAmount(bigDecimal);
                 }
             }
-        }else {
-            resultList.addAll(profitAnalysisMapper.getAllAccountExpenses(profitAnalysisQueryDto));
+
+            for (ProfitAnalysisDto dto : profitAnalysisDtos) {
+                if (dto.getParentId().equals("0")) {
+                    BigDecimal totalAmount = aggregateChildAmounts(dto.getExpensesId(), map);
+                    dto.setApplyAmount(totalAmount);
+                }
+            }
+
+            for (ProfitAnalysisDto allAccountExpens : profitAnalysisDtos) {
+                BigDecimal applyAmount = allAccountExpens.getApplyAmount() != null ? allAccountExpens.getApplyAmount() : BigDecimal.ZERO;
+                if(applyAmount.compareTo(BigDecimal.ZERO)>0){
+                    allAccountExpens.setRadio(applyAmount.divide(allExpenditure,4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).toString());
+                }
+            }
+            resultList.addAll(profitAnalysisDtos) ;
+
+
+        } else {
+
+
+            /**
+             *  子类目金额
+             */
+            List<ProfitAnalysisDto> allAccountExpenses = profitAnalysisMapper.getAllAccountExpenses(profitAnalysisQueryDto);
+            //二级类目
+            List<String> collect = allAccountExpenses.stream().filter(item -> !item.getParentId().equals("0")).map(ProfitAnalysisDto::getExpensesId).collect(Collectors.toList());
+            profitAnalysisQueryDto.setIds(collect);
+
+            List<ProfitAnalysisDto> pidAmountList = profitAnalysisMapper.getSumCategory(profitAnalysisQueryDto);
+
+            Map<String, BigDecimal> amountMap = pidAmountList.stream().collect(Collectors.toMap(ProfitAnalysisDto::getParentId, ProfitAnalysisDto::getApplyAmount));
+            Map<String, List<String>> stringListMap = buildTreeMap(allAccountExpenses);
+            stringListMap.forEach((id ,children) ->{
+                profitAnalysisQueryDto.setExpensesIds(children);
+                ProfitAnalysisDto sumCategory = profitAnalysisMapper.getSumByparentAmount(profitAnalysisQueryDto);
+                if(!amountMap.containsKey(id) && ObjectUtils.isNotEmpty(sumCategory)){
+                    amountMap.put(id,sumCategory.getApplyAmount());
+
+                }
+            });
+            for (ProfitAnalysisDto allAccountExpens : allAccountExpenses) {
+                if (amountMap.containsKey(allAccountExpens.getExpensesId())) {
+                    allAccountExpens.setApplyAmount(amountMap.get(allAccountExpens.getExpensesId()));
+                }
+            }
+            for (ProfitAnalysisDto allAccountExpens : allAccountExpenses) {
+                BigDecimal applyAmount = allAccountExpens.getApplyAmount() != null ? allAccountExpens.getApplyAmount() : BigDecimal.ZERO;
+                if(applyAmount.compareTo(BigDecimal.ZERO)>0){
+                    allAccountExpens.setRadio(applyAmount.divide(allExpenditure,4,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).toString());
+                }
+            }
+
+            resultList.addAll(allAccountExpenses);
         }
         return getTree(resultList);
     }
 
+    private BigDecimal aggregateChildAmounts(String expensesId, Map<String, ProfitAnalysisDto> map) {
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        for (ProfitAnalysisDto dto : map.values()) {
+            if (dto.getParentId() .equals(expensesId) ) {
+                totalAmount = totalAmount.add(dto.getApplyAmount() != null ? dto.getApplyAmount() : BigDecimal.ZERO);
+                totalAmount = totalAmount.add(aggregateChildAmounts(dto.getExpensesId(), map)); // 递归查找子对象
+            }
+        }
+        return totalAmount;
+    }
+
+    private BigDecimal getAllExpenditure(ProfitAnalysisQueryDto profitAnalysisQueryDto) {
+        HashMap<String, BigDecimal> sumExpenditure = profitAnalysisMapper.getTotalExpenditure(profitAnalysisQueryDto);
+//          查询变动成本
+        BigDecimal variableCost = BigDecimal.ZERO;
+        BigDecimal allExpenditure = BigDecimal.ZERO;
+
+
+        String yearAndMonth = profitAnalysisQueryDto.getYearAndMonth();
+        profitAnalysisQueryDto.setYearAndMonth(yearAndMonth);
+        List<ProfitAnalysisDto> profitAnalysisDto1 = insPlyIncomeMapper.changeAmount(profitAnalysisQueryDto);
+        for (ProfitAnalysisDto analysisDto : profitAnalysisDto1) {
+            String outCardNum = analysisDto.getOutCardNum();
+            String enterCardNum = analysisDto.getEnterCardNum();
+            InvAccountCardVo outAccount = invAccountMapper.getByCarNumber(outCardNum);
+            InvAccountCardVo enterAccount  = invAccountMapper.getByCarNumber(enterCardNum);
+            if(StringUtils.isNotEmpty(outAccount.getOuterFlag()) && StringUtils.isNotEmpty(enterAccount.getOuterFlag())){
+                if(!enterAccount.getOuterFlag().equals(outAccount.getOuterFlag())){
+                    variableCost=variableCost.add(analysisDto.getApplyAmount());
+                }
+            }
+        }
+        if(!sumExpenditure.isEmpty()){
+            BigDecimal fixedCost = sumExpenditure.get("fixedCost") != null ? sumExpenditure.get("fixedCost") : BigDecimal.ZERO;
+            BigDecimal laborCost = sumExpenditure.get("laborCost") != null ? sumExpenditure.get("laborCost") : BigDecimal.ZERO;
+            BigDecimal taxation = sumExpenditure.get("taxation") != null ? sumExpenditure.get("taxation") : BigDecimal.ZERO;
+            allExpenditure =allExpenditure.add(fixedCost).add(laborCost).add(taxation).add(variableCost);
+        }
+        return allExpenditure;
+    }
+
+
+    public static Map<String, List<String>> buildTreeMap(List<ProfitAnalysisDto> nodes) {
+        Map<String, ProfitAnalysisDto> nodeMap = new HashMap<>();
+        for (ProfitAnalysisDto node : nodes) {
+            nodeMap.put(node.getExpensesId(), node);
+        }
+
+        Map<String, List<String>> parentChildrenMap = new HashMap<>();
+
+        for (ProfitAnalysisDto node : nodes) {
+            if (node.getParentId().equals("0")) {
+                // Root node, start recursion here
+                List<String> allIds = getAllIds(node, nodeMap, new ArrayList<>());
+                parentChildrenMap.put(String.valueOf(node.getExpensesId()), allIds);
+            }
+        }
+
+        return parentChildrenMap;
+    }
+
+
+    private static List<String> getAllIds(ProfitAnalysisDto node, Map<String, ProfitAnalysisDto> nodeMap, List<String> ids) {
+        ids.add(String.valueOf(node.getExpensesId()));
+
+        for (ProfitAnalysisDto potentialChild : nodeMap.values()) {
+            if (potentialChild.getParentId() .equals(node.getExpensesId())) {
+                getAllIds(potentialChild, nodeMap, ids);
+            }
+        }
+        return ids;
+    }
+
     /**
      * 组装树形结构结果集方法
      */

+ 31 - 0
src/main/java/com/ydtech/modules/console/dao/ProfitAnalysisMapper.java

@@ -5,6 +5,7 @@ import com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisQueryD
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.List;
 
@@ -16,4 +17,34 @@ public interface ProfitAnalysisMapper {
 
     List<ProfitAnalysisDto> selectAccountExpenses(@Param("vo") ProfitAnalysisQueryDto profitAnalysisQueryDto);
 
+    /**
+     *
+     *
+     * @param profitAnalysisQueryDto
+     * @return  类目总金额
+     */
+    List<ProfitAnalysisDto> getSumCategory(@Param("vo") ProfitAnalysisQueryDto profitAnalysisQueryDto);
+
+    /**
+     *
+     *
+     * @param parentId
+     * @return  通过父id获取子集合
+     */
+    List<ProfitAnalysisDto> getByparentId(String parentId);
+
+    /**
+     *
+     * @param profitAnalysisQueryDto
+     * @return  通过父id获取金额
+     */
+    ProfitAnalysisDto getSumByparentAmount(@Param("vo") ProfitAnalysisQueryDto profitAnalysisQueryDto);
+
+    /**
+     *
+     * @param profitAnalysisQueryDto
+     * @return  获取公司总支出
+     */
+    HashMap<String, BigDecimal> getTotalExpenditure( @Param("vo") ProfitAnalysisQueryDto profitAnalysisQueryDto);
+
 }

+ 199 - 7
src/main/resources/mapper/modules/console/ProfitAnalysisMapper.xml

@@ -9,12 +9,15 @@
 
         select iae.expenses_id as "expensesId",
                iae.parent_id as "parentId",
-               iae.category as "category",
-               a.applyAmount as "applyAmount"
+                case when iae.parent_id ='0' then iae.category  end as "category",
+                case when iae.parent_id !='0' then iae.category   end as "subcategory",
+               a.applyAmount as "applyAmount",
+               a.parentId as "parentId"
         from inv_account_expenses iae
         left  join  (
             SELECT
                 b.expensesId,
+                b.parentId,
                 sum( CAST(a.apply_amount AS DECIMAL ( 10, 2 )) ) AS "applyAmount"
             FROM
                 inv_account_operate a
@@ -23,12 +26,16 @@
                         a.category AS "aCategory",
                         b.category AS "bCategory",
                         a.expenditure_details AS "expenditureDetails",
-                        a.expenses_id AS "expensesId"
+                        a.expenses_id AS "expensesId",
+                        a.parent_id as "parentId"
                     FROM
                         inv_account_expenses a
                             LEFT JOIN inv_account_expenses b ON a.parent_id = b.expenses_id
                     WHERE
                         b.category IS NOT NULL
+                    <if test="vo.expensesType !=null  and  vo.expensesType !='' ">
+                        AND a.expenditure_details  =#{vo.expensesType}
+                    </if>
                 ) b ON a.fund_use = b.bCategory
                     AND a.fund_fen = b.aCategory
             WHERE
@@ -44,9 +51,6 @@
                 )
               AND a.revenue_outlay = '1'
               AND a.del_flag = '0'
-              <if test="vo.expensesType !=null  and  vo.expensesType !='' ">
-                  AND b.expenditureDetails  =#{vo.expensesType}
-              </if>
 
               <if test="vo.yearAndMonth !=null and vo.yearAndMonth !=''">
                   AND DATE_FORMAT( a.create_time, '%Y-%m' )=#{vo.yearAndMonth}
@@ -60,9 +64,81 @@
             GROUP BY
                 b.expensesId
         ) a  on a.expensesId  =iae.expenses_id
+        <where>
+            <if test="vo.expensesType !=null  and  vo.expensesType !='' ">
+                AND iae.expenditure_details  =#{vo.expensesType}
+            </if>
+
+        </where>
     </select>
 
 
+    <select id="getSumCategory" resultType="com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto">
+
+        select   a.parentId as "parentId",
+                 sum(a.applyAmount) as "applyAmount"
+        from  (
+        SELECT
+        b.parentId,
+        sum( CAST(a.apply_amount AS DECIMAL ( 10, 2 )) ) AS "applyAmount"
+        FROM
+        inv_account_operate a
+        LEFT JOIN (
+        SELECT
+        a.category AS "aCategory",
+        b.category AS "bCategory",
+        a.expenditure_details AS "expenditureDetails",
+        a.expenses_id AS "expensesId",
+        a.parent_id as "parentId"
+        FROM
+        inv_account_expenses a
+        LEFT JOIN inv_account_expenses b ON a.parent_id = b.expenses_id
+        WHERE
+        b.category IS NOT NULL
+        <if test="vo.expensesType !=null  and  vo.expensesType !='' ">
+            AND a.expenditure_details  =#{vo.expensesType}
+        </if>
+        ) b ON a.fund_use = b.bCategory
+        AND a.fund_fen = b.aCategory
+        WHERE
+        a.out_card_num IN (
+        SELECT
+        bank_card_num
+        FROM
+        inv_account_card iac
+        LEFT JOIN inv_account ia ON iac.account_id = ia.account_id
+        WHERE
+        ia.del_flag = '0'
+        AND ia.outer_flag LIKE concat( '%', '0', '%' )
+        )
+        AND a.revenue_outlay = '1'
+        AND a.del_flag = '0'
+
+        <if test="vo.yearAndMonth !=null and vo.yearAndMonth !=''">
+            AND DATE_FORMAT( a.create_time, '%Y-%m' )=#{vo.yearAndMonth}
+        </if>
+        <if test="vo.expensesIds !=null  and  vo.expensesIds !='' and vo.expensesIds.size()>0 ">
+            and b.expensesId in
+            <foreach collection="vo.expensesIds" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        <if test="vo.ids !=null  and  vo.ids !='' and vo.ids.size()>0 ">
+            and b.parentId in
+            <foreach collection="vo.ids" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        GROUP BY
+        b.expensesId
+       ) a
+        group by   a.parentId
+    </select>
+
+
+
+
+
     <select id="getAllAccountExpensesId" resultType="com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto">
         SELECT
         b.expensesId,
@@ -122,9 +198,125 @@
     <select id="selectAccountExpenses" resultType="com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto">
         select iae.expenses_id as "expensesId",
         iae.parent_id as "parentId",
-        iae.category as "category"
+        case when iae.parent_id ='0' then iae.category  end as "category",
+        case when iae.parent_id !='0' then iae.category   end as "subcategory"
         from inv_account_expenses iae
+        <where>
+            1=1
+            <if test="vo.expensesType !=null  and  vo.expensesType !='' ">
+                AND iae.expenditure_details  =#{vo.expensesType}
+            </if>
+        </where>
+
     </select>
 
 
+    <select id="getByparentId" resultType="com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto">
+        select
+        a.expenses_id as "expensesId",
+        a.category as "category",
+        a.parent_id as "parentId"
+        from  inv_account_expenses  a
+        <where>
+            <if test="parentId !=null  and  parentId !=''">
+                a.parent_id =#{parentId}
+            </if>
+        </where>
+    </select>
+
+    <select id="getSumByparentAmount" resultType="com.ydtech.modules.admin.model.report.profitAnalysis.ProfitAnalysisDto">
+        select  IFNULL(sum(a.applyAmount),0) as "applyAmount" from  (
+        SELECT
+        sum( CAST(a.apply_amount AS DECIMAL ( 10, 2 )) ) AS "applyAmount"
+        FROM
+        inv_account_operate a
+        LEFT JOIN (
+        SELECT
+        a.category AS "aCategory",
+        b.category AS "bCategory",
+        a.expenditure_details AS "expenditureDetails",
+        a.expenses_id AS "expensesId"
+        FROM
+        inv_account_expenses a
+        LEFT JOIN inv_account_expenses b ON a.parent_id = b.expenses_id
+        WHERE
+        b.category IS NOT NULL
+        ) b ON a.fund_use = b.bCategory
+        AND a.fund_fen = b.aCategory
+        WHERE
+        a.out_card_num IN (
+        SELECT
+        bank_card_num
+        FROM
+        inv_account_card iac
+        LEFT JOIN inv_account ia ON iac.account_id = ia.account_id
+        WHERE
+        ia.del_flag = '0'
+        AND ia.outer_flag LIKE concat( '%', '0', '%' )
+        )
+        AND a.revenue_outlay = '1'
+        AND a.del_flag = '0'
+        <if test="vo.expensesType !=null  and  vo.expensesType !='' ">
+            <choose>
+                <when test="vo.expensesType !=3 ">
+                    AND b.expenditureDetails = #{vo.expensesType}
+                </when>
+                <when test="vo.expensesType = 3 ">
+                    AND b.expenditureDetails !=  #{vo.expensesType}
+                </when>
+            </choose>
+        </if>
+        <if test="vo.expensesIds !=null  and  vo.expensesIds !='' and vo.expensesIds.size()>0 ">
+            and b.expensesId in
+            <foreach collection="vo.expensesIds" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        <if test="vo.yearAndMonth !=null and vo.yearAndMonth !=''">
+            AND DATE_FORMAT( a.create_time, '%Y-%m' )=#{vo.yearAndMonth}
+        </if>
+        GROUP BY
+        b.expensesId) a
+    </select>
+
+
+    <select id="getTotalExpenditure" resultType="java.util.HashMap">
+     select sum(a.fixedCost)  as "fixedCost",
+            sum(a.laborCost)  as "laborCost",
+            sum(a.taxation)  as "taxation"
+     from  (
+            SELECT
+            CAST(sum(case when b.expenditureDetails = '1' then a.apply_amount else 0 end) as  DECIMAL(10, 2) ) as "laborCost",
+            CAST(sum(case when b.expenditureDetails = '2' then a.apply_amount else 0 end) as  DECIMAL(10, 2) ) as "fixedCost",
+            CAST(sum(case when b.expenditureDetails = '4' then a.apply_amount else 0 end) as  DECIMAL(10, 2) ) as "taxation",
+            b.expenditureDetails
+            FROM
+            inv_account_operate a
+            left  join  (
+            select a.category as "aCategory",b. category as "bCategory",a.expenditure_details as "expenditureDetails" from  inv_account_expenses a
+            left  join  inv_account_expenses  b  on a.parent_id =b.expenses_id
+            where   b.category  is  not  null
+            )  b on a.fund_use  = b.bCategory  and  a.fund_fen  = b.aCategory
+            <where>
+                a.out_card_num IN (
+                SELECT
+                bank_card_num
+                FROM
+                inv_account_card iac
+                LEFT JOIN inv_account ia ON iac.account_id = ia.account_id
+                WHERE
+                ia.del_flag = '0'
+                AND ia.outer_flag LIKE concat( '%', '0', '%' )
+                )
+                AND a.revenue_outlay = '1'
+                AND a.del_flag = '0'
+                <if test="vo.yearAndMonth  !=null  and vo.yearAndMonth !=''">
+                   and  DATE_FORMAT( a.create_time, '%Y-%m' ) =#{vo.yearAndMonth}
+                </if>
+            </where>
+            GROUP BY  DATE_FORMAT( a.create_time, '%Y-%m' )  , b.expenditureDetails
+             )  a
+
+    </select>
+
 </mapper>