hr 4 vuotta sitten
vanhempi
commit
ceb3c0a3c2

+ 1 - 1
pom.xml

@@ -103,7 +103,7 @@
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <!--最好指定版本,不同环境版本可能不同-->
-            <version>8.0.25</version>
+            <version>8.0.16</version>
         </dependency>
 
         <dependency>

+ 2 - 0
src/main/java/com/imed/costaccount/common/token/RedisUtil.java

@@ -267,4 +267,6 @@ public class RedisUtil {
         return hashOperations.get(key, hKey);
     }
 
+
+
 }

+ 62 - 0
src/main/java/com/imed/costaccount/common/util/RedisLock.java

@@ -0,0 +1,62 @@
+package com.imed.costaccount.common.util;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RedisLock {
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+    /**
+     * 加锁
+     * @param lockKey 加锁的Key
+     * @param timeStamp 时间戳:当前时间+超时时间
+     * @return
+     */
+    public boolean lock(String lockKey,String timeStamp){
+        if(stringRedisTemplate.opsForValue().setIfAbsent(lockKey, timeStamp)){
+            // 对应setnx命令,可以成功设置,也就是key不存在,获得锁成功
+            return true;
+        }
+
+        //设置失败,获得锁失败
+        // 判断锁超时 - 防止原来的操作异常,没有运行解锁操作 ,防止死锁
+        String currentLock = stringRedisTemplate.opsForValue().get(lockKey);
+        // 如果锁过期 currentLock不为空且小于当前时间
+        if(StrUtil.isNotEmpty(currentLock) && Long.parseLong(currentLock) < System.currentTimeMillis()){
+            //如果lockKey对应的锁已经存在,获取上一次设置的时间戳之后并重置lockKey对应的锁的时间戳
+            String preLock = stringRedisTemplate.opsForValue().getAndSet(lockKey, timeStamp);
+
+            //假设两个线程同时进来这里,因为key被占用了,而且锁过期了。
+            //获取的值currentLock=A(get取的旧的值肯定是一样的),两个线程的timeStamp都是B,key都是K.锁时间已经过期了。
+            //而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的timeStamp已经变成了B。
+            //只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。
+            if(StrUtil.isNotEmpty(preLock) && preLock.equals(currentLock)){
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * 释放锁
+     * @param lockKey
+     * @param timeStamp
+     */
+    public void release(String lockKey,String timeStamp){
+        try {
+            String currentValue = stringRedisTemplate.opsForValue().get(lockKey);
+            if(!StrUtil.isEmpty(currentValue) && currentValue.equals(timeStamp) ){
+                // 删除锁状态
+                stringRedisTemplate.opsForValue().getOperations().delete(lockKey);
+            }
+        } catch (Exception e) {
+            System.out.println("警报!警报!警报!解锁异常");
+        }
+    }
+}

+ 20 - 0
src/main/java/com/imed/costaccount/mapper/IncomeCollectionMapper.java

@@ -3,6 +3,7 @@ package com.imed.costaccount.mapper;
 import com.imed.costaccount.model.IncomeCollection;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.imed.costaccount.model.dto.CollectDTO;
+import com.imed.costaccount.model.vo.CodeAndNameVO;
 import com.imed.costaccount.model.vo.CollectedVO;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -41,4 +42,23 @@ public interface IncomeCollectionMapper extends BaseMapper<IncomeCollection> {
      */
     BigDecimal getTotalAmount(@Param("collectDTO") CollectDTO collectDTO);
 
+    /**
+     * 纵向计算所有的amount
+     * @param responsibilityCode
+     * @param accountingCodes
+     * @param hospId
+     * @param date
+     * @return
+     */
+    BigDecimal getCountByResponseAndAccounts(@Param("responsibilityCode") String responsibilityCode, @Param("accountingCodes") List<String> accountingCodes, @Param("hospId") Long hospId, @Param("date") String date);
+
+
+    List<CodeAndNameVO> getResponsibility(@Param("hospId") Long hospId, @Param("responsibilityCode") String responsibilityCode, @Param("date") String date);
+
+    List<CodeAndNameVO> getAccount(@Param("hospId") Long hospId, @Param("accountingCode") String accountingCode, @Param("date") String date);
+
+    BigDecimal getCountAccountAndResponsibilities(@Param("hospId") Long hospId, @Param("date") String date, @Param("code") String code, @Param("responsibilityCodes") List<String> responsibilityCodes);
+
+    BigDecimal getCountByResponsibilitiesAndAccounts(@Param("responsibilityCodes") List<String> responsibilityCodes, @Param("accountingCodes") List<String> accountingCodes, @Param("hospId") Long hospId, @Param("date") String date);
+
 }

+ 15 - 0
src/main/java/com/imed/costaccount/model/vo/CodeAndNameVO.java

@@ -0,0 +1,15 @@
+package com.imed.costaccount.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CodeAndNameVO {
+
+    private String code;
+
+    private String name;
+}

+ 24 - 0
src/main/java/com/imed/costaccount/model/vo/CollectDataFormVO.java

@@ -0,0 +1,24 @@
+package com.imed.costaccount.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CollectDataFormVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    private Map<Integer, String> titleMap;
+
+    private List<Map<Integer, Object>> realData;
+
+    private Map<Integer, Object> map ;
+
+}

+ 10 - 0
src/main/java/com/imed/costaccount/service/IncomeCollectionService.java

@@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.imed.costaccount.common.util.PageUtils;
 import com.imed.costaccount.model.IncomeCollection;
 import com.imed.costaccount.model.dto.CollectDTO;
+import com.imed.costaccount.model.vo.CollectDataFormVO;
+
+import java.util.List;
 
 /**
  * 归集后列表
@@ -51,5 +54,12 @@ public interface IncomeCollectionService extends IService<IncomeCollection> {
      */
     PageUtils collectList(CollectDTO collectDTO);
 
+    /**
+     *
+     * @param collectDTO
+     * @return
+     */
+    CollectDataFormVO collectDataForm(CollectDTO collectDTO);
+
 }
 

+ 177 - 61
src/main/java/com/imed/costaccount/service/impl/IncomeCollectionServiceImpl.java

@@ -1,20 +1,24 @@
 package com.imed.costaccount.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.imed.costaccount.common.exception.CostException;
 import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.common.util.RedisLock;
 import com.imed.costaccount.mapper.CostIncomeGroupMapper;
 import com.imed.costaccount.mapper.IncomeCollectionMapper;
-import com.imed.costaccount.model.AfterIncomegroup;
-import com.imed.costaccount.model.CostIncomeGroup;
-import com.imed.costaccount.model.IncomeCollection;
+import com.imed.costaccount.model.*;
 import com.imed.costaccount.model.dto.CollectDTO;
+import com.imed.costaccount.model.vo.CodeAndNameVO;
+import com.imed.costaccount.model.vo.CollectDataFormVO;
 import com.imed.costaccount.model.vo.CollectedVO;
 import com.imed.costaccount.model.vo.CollectionVO;
+import com.imed.costaccount.service.AccountingService;
 import com.imed.costaccount.service.IncomeCollectionService;
+import com.imed.costaccount.service.ResponsibilityService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -33,10 +37,19 @@ public class IncomeCollectionServiceImpl
         extends ServiceImpl<IncomeCollectionMapper, IncomeCollection>
         implements IncomeCollectionService {
 
+    private final RedisLock redisLock;
+
     private final CostIncomeGroupMapper incomeGroupMapper;
 
-    public IncomeCollectionServiceImpl(CostIncomeGroupMapper incomeGroupMapper) {
+    private final ResponsibilityService responsibilityService;
+
+    private final AccountingService accountingService;
+
+    public IncomeCollectionServiceImpl(RedisLock redisLock, CostIncomeGroupMapper incomeGroupMapper, ResponsibilityService responsibilityService, AccountingService accountingService) {
+        this.redisLock = redisLock;
         this.incomeGroupMapper = incomeGroupMapper;
+        this.responsibilityService = responsibilityService;
+        this.accountingService = accountingService;
     }
 
     /**
@@ -83,65 +96,84 @@ public class IncomeCollectionServiceImpl
     @Override
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public void collect(Integer year, Integer month, Long hospId) {
-        //  可能几十万次数据 需要分段异步多线程处理,分布式锁处理,
-        List<CostIncomeGroup> costIncomeGroups = incomeGroupMapper.selectList(
-                new LambdaQueryWrapper<CostIncomeGroup>()
-                        .eq(CostIncomeGroup::getDateYear, year)
-                        .eq(CostIncomeGroup::getDateMonth, month)
-                        .eq(CostIncomeGroup::getHospId, hospId)
-        );
-        if (costIncomeGroups.isEmpty()) {
-            String format = StrUtil.format("{}年{}月数据不存在,请先导入数据", year, month);
-            throw new CostException(format);
-        }
-        // 根据会计科目和成本项目归纳所有数据
-        Map<String, List<CostIncomeGroup>> collectMap = costIncomeGroups.stream()
-                .collect(Collectors.groupingBy(i -> i.getAccountCode() + "cost" + i.getProductCode()));
-
-        // 遍历map 组装成List保存
-        List<IncomeCollection> list = new LinkedList<>();
-        Set<Map.Entry<String, List<CostIncomeGroup>>> entries = collectMap.entrySet();
-        entries.stream().map(Map.Entry::getValue).flatMap(Collection::stream).forEach(costIncomeGroup -> {
-            IncomeCollection incomeCollection = new IncomeCollection();
-            incomeCollection.setYear(year);
-            incomeCollection.setMonth(month);
-            incomeCollection.setAccountingCode(costIncomeGroup.getAccountCode());
-            incomeCollection.setAccountingName(costIncomeGroup.getAccountName());
-            incomeCollection.setProductName(costIncomeGroup.getProductName());
-            incomeCollection.setProductCode(costIncomeGroup.getProductCode());
-            incomeCollection.setAmount(costIncomeGroup.getAmount());
-            incomeCollection.setHospId(hospId);
-            // todo 来源id暂时不确定
-            incomeCollection.setFileId(costIncomeGroup.getFileId());
-            incomeCollection.setCreateTime(System.currentTimeMillis());
-            String afterIncomeGroupStr = costIncomeGroup.getAfterIncomeGroup();
-            AfterIncomegroup afterIncomegroup = JSONUtil.toBean(afterIncomeGroupStr, AfterIncomegroup.class);
-            if (Objects.isNull(afterIncomegroup)) {
-                throw new CostException("未能正确归集对应的....");
-            }
-            // 转换一下其他的
-            if (afterIncomegroup.getDirectStatus() == 2) {
-                afterIncomegroup.setDirectStatus(0);
-            }
-            incomeCollection.setIsDirectIncome(afterIncomegroup.getDirectStatus());
-            // 开单中心的数据
-            incomeCollection.setDepartmentCode(afterIncomegroup.getOpenDepartmentCode());
-            incomeCollection.setDepartmentName(afterIncomegroup.getOpenDepartmentName());
-            incomeCollection.setResponsibilityCode(afterIncomegroup.getResponsibilityCode());
-            incomeCollection.setResponsibilityName(afterIncomegroup.getResponsibilityName());
-
-            list.add(incomeCollection);
-            // 执行科室数据
-            incomeCollection.setDepartmentCode(afterIncomegroup.getStartDepartmentCode());
-            incomeCollection.setDepartmentName(afterIncomegroup.getStartDepartmentName());
-            incomeCollection.setResponsibilityCode(afterIncomegroup.getResponsibilityCode());
-            incomeCollection.setResponsibilityName(afterIncomegroup.getResponsibilityName());
-            list.add(incomeCollection);
-        });
 
+        // todo  可能几十万次数据 需要分段异步多线程处理,
+        // 1个小时
+        String key = "collect" + hospId;
+        String timestamp = DateUtil.offsetMillisecond(DateUtil.date(), 60 * 60).getTime() + "";
+        boolean lock = redisLock.lock(key, timestamp);
+        try {
+            if (lock) {
+                List<CostIncomeGroup> costIncomeGroups = incomeGroupMapper.selectList(
+                        new LambdaQueryWrapper<CostIncomeGroup>()
+                                .eq(CostIncomeGroup::getDateYear, year)
+                                .eq(CostIncomeGroup::getDateMonth, month)
+                                .eq(CostIncomeGroup::getHospId, hospId)
+                );
+                if (costIncomeGroups.isEmpty()) {
+                    String format = StrUtil.format("{}年{}月数据不存在,请先导入数据", year, month);
+                    throw new CostException(format);
+                }
+
+                // 删掉已归集的数据
+                this.remove(
+                        new LambdaQueryWrapper<IncomeCollection>().eq(IncomeCollection::getYear, year).eq(IncomeCollection::getMonth, month).eq(IncomeCollection::getHospId, hospId)
+                );
+                // 根据会计科目和成本项目归纳所有数据
+                Map<String, List<CostIncomeGroup>> collectMap = costIncomeGroups.stream()
+                        .collect(Collectors.groupingBy(i -> i.getAccountCode() + "cost" + i.getProductCode()));
+
+                // 遍历map 组装成List保存
+                List<IncomeCollection> list = new LinkedList<>();
+                Set<Map.Entry<String, List<CostIncomeGroup>>> entries = collectMap.entrySet();
+                entries.stream().map(Map.Entry::getValue).flatMap(Collection::stream).forEach(costIncomeGroup -> {
+                    IncomeCollection incomeCollection = new IncomeCollection();
+                    incomeCollection.setYear(year);
+                    incomeCollection.setMonth(month);
+                    incomeCollection.setAccountingCode(costIncomeGroup.getAccountCode());
+                    incomeCollection.setAccountingName(costIncomeGroup.getAccountName());
+                    incomeCollection.setProductName(costIncomeGroup.getProductName());
+                    incomeCollection.setProductCode(costIncomeGroup.getProductCode());
+                    incomeCollection.setAmount(costIncomeGroup.getAmount());
+                    incomeCollection.setHospId(hospId);
+                    // todo 来源id暂时不确定
+                    incomeCollection.setFileId(costIncomeGroup.getFileId());
+                    incomeCollection.setCreateTime(System.currentTimeMillis());
+                    String afterIncomeGroupStr = costIncomeGroup.getAfterIncomeGroup();
+                    AfterIncomegroup afterIncomegroup = JSONUtil.toBean(afterIncomeGroupStr, AfterIncomegroup.class);
+                    if (Objects.isNull(afterIncomegroup)) {
+                        throw new CostException("未能正确归集对应的....");
+                    }
+                    // 转换一下其他的
+                    if (afterIncomegroup.getDirectStatus() == 2) {
+                        afterIncomegroup.setDirectStatus(0);
+                    }
+                    incomeCollection.setIsDirectIncome(afterIncomegroup.getDirectStatus());
+                    // 开单中心的数据
+                    incomeCollection.setDepartmentCode(afterIncomegroup.getOpenDepartmentCode());
+                    incomeCollection.setDepartmentName(afterIncomegroup.getOpenDepartmentName());
+                    incomeCollection.setResponsibilityCode(afterIncomegroup.getResponsibilityCode());
+                    incomeCollection.setResponsibilityName(afterIncomegroup.getResponsibilityName());
+
+                    list.add(incomeCollection);
+                    // 执行科室数据
+                    incomeCollection.setDepartmentCode(afterIncomegroup.getStartDepartmentCode());
+                    incomeCollection.setDepartmentName(afterIncomegroup.getStartDepartmentName());
+                    incomeCollection.setResponsibilityCode(afterIncomegroup.getResponsibilityCode());
+                    incomeCollection.setResponsibilityName(afterIncomegroup.getResponsibilityName());
+                    list.add(incomeCollection);
+                });
+
+
+                // TODO: 2021/8/10 几十万条数据如何处理 待测试处理
+                this.saveBatch(list);
+            } else {
+                throw new CostException("已有人在操作,请稍后重试");
+            }
+        } finally {
+            redisLock.release(key, timestamp);
+        }
 
-        // TODO: 2021/8/10 几十万条数据如何处理 待测试处理
-        this.saveBatch(list);
     }
 
     /**
@@ -184,4 +216,88 @@ public class IncomeCollectionServiceImpl
 
         return new PageUtils(list, count, pageSize, current, totalAmount);
     }
+
+    /**
+     * 数据报表
+     *
+     * @param collectDTO
+     * @return
+     */
+    @Override
+    public CollectDataFormVO collectDataForm(CollectDTO collectDTO) {
+        Long hospId = collectDTO.getHospId();
+        String date = collectDTO.getDate();
+        // 1. 得到所有的标题栏 责任中心代码
+        List<CodeAndNameVO> responsibilities = this.baseMapper.getResponsibility(hospId, collectDTO.getResponsibilityCode(), date).stream().distinct().collect(Collectors.toList());
+        if (responsibilities.isEmpty()) {
+            return new CollectDataFormVO();
+        }
+        List<String> responsibilityCodes = responsibilities.stream().map(CodeAndNameVO::getCode).collect(Collectors.toList());
+        responsibilities.add(0, new CodeAndNameVO("#", "#"));
+        responsibilities.add(responsibilities.size(), new CodeAndNameVO("合计", "合计"));
+        List<String> titleData = responsibilities.stream().map(CodeAndNameVO::getName).collect(Collectors.toList());
+        Map<Integer, String> titleMap = new HashMap<>();
+        for (int i = 0; i < titleData.size(); i++) {
+            titleMap.put(i + 1, titleData.get(i));
+        }
+
+        // 所有的数据格式
+        List<CodeAndNameVO> realData = this.baseMapper.getAccount(hospId, collectDTO.getAccountingCode(), date);
+        if (realData.isEmpty()) {
+            return new CollectDataFormVO();
+        }
+        // realData [#,123,123,"合计"]
+        List<Map<Integer, Object>> realDatas = new ArrayList<>();
+        List<CodeAndNameVO> accounts = realData.stream().distinct().collect(Collectors.toList());
+
+        for (CodeAndNameVO account : accounts) {
+            Map<Integer, Object> map = new HashMap<>();
+            for (int i = 0; i < responsibilities.size(); i++) {
+                if (i == 0) {
+                    map.put(i + 1, accounts.get(i).getName());
+                    continue;
+                } else if (i == responsibilities.size() - 1) {
+                    // TODO: 2021/8/12 合计
+                    BigDecimal amount = this.baseMapper.getCountAccountAndResponsibilities(hospId, date, account.getCode(), responsibilityCodes);
+                    map.put(i + 1, amount);
+                    continue;
+                }
+                List<IncomeCollection> list = this.list(
+                        new LambdaQueryWrapper<IncomeCollection>().select(IncomeCollection::getAmount)
+                                .eq(IncomeCollection::getHospId, hospId)
+                                .eq(IncomeCollection::getYear, date.substring(0, 4))
+                                .eq(IncomeCollection::getMonth, date.substring(4))
+                                .eq(IncomeCollection::getAccountingCode, account.getCode())
+                                .eq(IncomeCollection::getResponsibilityCode, responsibilities.get(i).getCode())
+                );
+                if (list.isEmpty()) {
+                    map.put(i + 1, new BigDecimal("0.0000"));
+                } else {
+                    BigDecimal reduce = list.stream().map(IncomeCollection::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+                    map.put(i + 1, reduce);
+                }
+            }
+            realDatas.add(map);
+        }
+//
+        // 合计栏计算
+        // 长度一致的
+        List<String> accountingCodes = realData.stream().map(CodeAndNameVO::getCode).collect(Collectors.toList());
+        Map<Integer, Object> map = new HashMap<>();
+        for (int i = 0; i < responsibilities.size(); i++) {
+            if (i == 0) {
+                map.put(i + 1, "合计");
+                continue;
+            } else if (i == responsibilities.size() - 1) {
+                // 统计问题
+                BigDecimal bigDecimal = this.baseMapper.getCountByResponsibilitiesAndAccounts(responsibilityCodes, accountingCodes, hospId, date);
+                map.put(i + 1, bigDecimal);
+                continue;
+            }
+            BigDecimal bigDecimal = this.baseMapper.getCountByResponseAndAccounts(responsibilities.get(i).getCode(), accountingCodes, hospId, date);
+            map.put(i + 1, bigDecimal);
+        }
+
+        return new CollectDataFormVO(titleMap, realDatas, map);
+    }
 }

+ 10 - 0
src/main/java/com/imed/costaccount/web/IncomeCollectionController.java

@@ -3,12 +3,14 @@ package com.imed.costaccount.web;
 import com.imed.costaccount.common.util.PageUtils;
 import com.imed.costaccount.common.util.Result;
 import com.imed.costaccount.model.dto.CollectDTO;
+import com.imed.costaccount.model.vo.CollectDataFormVO;
 import com.imed.costaccount.service.IncomeCollectionService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.List;
 
 
 /**
@@ -62,4 +64,12 @@ public class IncomeCollectionController extends AbstractController {
         PageUtils pageUtils = incomeCollectionService.collectList(collectDTO);
         return Result.ok(pageUtils);
     }
+
+    @ApiOperation("归集后数据报表")
+    @GetMapping("/collectDataForm")
+    public Result collectDataForm(@ModelAttribute @Valid CollectDTO collectDTO) {
+        collectDTO.setHospId(getHospId());
+        CollectDataFormVO form = incomeCollectionService.collectDataForm(collectDTO);
+        return Result.ok(form);
+    }
 }

+ 1 - 0
src/main/resources/application-dev.yml

@@ -35,6 +35,7 @@ spring:
         max-idle: 10
         max-wait: -1
         min-idle: 0
+  profiles: dev
 
 mybatis-plus:
   mapper-locations: classpath*:/mapper/*.xml

+ 61 - 0
src/main/resources/mapper/IncomeCollectionMapper.xml

@@ -68,4 +68,65 @@
     </select>
 
 
+    <select id="getCountByResponseAndAccounts" resultType="java.math.BigDecimal">
+        select IFNULL(sum(amount), 0) as totalAmount
+        from cost_income_collection
+        where delete_time = 0 and hosp_id = #{hospId} and responsibility_code = #{responsibilityCode}
+        <if test="date != null and date != ''">
+            and `year` = YEAR(concat(#{date},'01')) and `month` = MONTH(concat(#{date},'01'))
+        </if>
+        and accounting_code in
+        <foreach collection="accountingCodes" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
+    <select id="getResponsibility" resultType="com.imed.costaccount.model.vo.CodeAndNameVO">
+        select responsibility_code as code ,responsibility_name as name from cost_income_collection
+        where delete_time = 0 and hosp_id = #{hospId}
+        <if test="responsibilityCode != null and responsibilityCode != ''">
+            and responsibility_code = #{responsibilityCode}
+        </if>
+        <if test="date != null and date != ''">
+            and `year` = YEAR(concat(#{date},'01')) and `month` = MONTH(concat(#{date},'01'))
+        </if>
+    </select>
+    <select id="getAccount" resultType="com.imed.costaccount.model.vo.CodeAndNameVO">
+        select accounting_code as code ,accounting_name as name from cost_income_collection
+        where delete_time = 0 and hosp_id = #{hospId}
+        <if test="accountingCode != null and accountingCode != ''">
+            and accounting_code = #{accountingCode}
+        </if>
+        <if test="date != null and date != ''">
+            and `year` = YEAR(concat(#{date},'01')) and `month` = MONTH(concat(#{date},'01'))
+        </if>
+    </select>
+    <select id="getCountAccountAndResponsibilities" resultType="java.math.BigDecimal">
+        select IFNULL(sum(amount), 0) as totalAmount
+        from cost_income_collection
+        where delete_time = 0 and hosp_id = #{hospId} and accounting_code = #{code}
+        <if test="date != null and date != ''">
+            and `year` = YEAR(concat(#{date},'01')) and `month` = MONTH(concat(#{date},'01'))
+        </if>
+        and responsibility_code in
+        <foreach collection="responsibilityCodes" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
+    <select id="getCountByResponsibilitiesAndAccounts" resultType="java.math.BigDecimal">
+        select IFNULL(sum(amount), 0) as totalAmount
+        from cost_income_collection
+        where delete_time = 0 and hosp_id = #{hospId} and responsibility_code in
+        <foreach  collection="responsibilityCodes" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        <if test="date != null and date != ''">
+            and `year` = YEAR(concat(#{date},'01')) and `month` = MONTH(concat(#{date},'01'))
+        </if>
+        and accounting_code in
+        <foreach collection="accountingCodes" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
+
+
 </mapper>