chengf
2025-08-28 ebeb1441ce5bd4c93cfd733b1b2825ca5b6d5c03
service-fee/src/main/java/com/java110/fee/cmd/fee/ReportFeePropertyCmd.java
@@ -7,24 +7,34 @@
import com.java110.core.event.cmd.CmdEvent;
import com.java110.dto.community.CommunityDto;
import com.java110.dto.dict.DictDto;
import com.java110.dto.fee.FeeConfigDto;
import com.java110.dto.fee.FeeDetailDto;
import com.java110.dto.fee.FeeDto;
import com.java110.dto.owner.OwnerDto;
import com.java110.dto.report.ReportExcelDto;
import com.java110.dto.report.ReportQueryRecord;
import com.java110.dto.room.RoomDto;
import com.java110.intf.community.ICommunityInnerServiceSMO;
import com.java110.intf.community.IRoomInnerServiceSMO;
import com.java110.intf.dev.IDictV1InnerServiceSMO;
import com.java110.intf.fee.IFeeConfigInnerServiceSMO;
import com.java110.intf.fee.IFeeDetailInnerServiceSMO;
import com.java110.intf.fee.IReportFeeInnerServiceSMO;
import com.java110.intf.user.IOwnerInnerServiceSMO;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.BeanConvertUtil;
import com.java110.utils.util.DateUtil;
import com.java110.vo.FeeQueryParams;
import com.java110.vo.ResultVo;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -43,6 +53,15 @@
    @Autowired
    private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
    @Autowired
    private IFeeConfigInnerServiceSMO  feeConfigInnerServiceSMOImpl;
    @Autowired
    private IOwnerInnerServiceSMO ownerInnerServiceSMOImpl;
    @Autowired
    private IFeeDetailInnerServiceSMO feeDetailInnerServiceSMOImpl;
    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
@@ -74,7 +93,32 @@
        reportQueryRecord.setOperator("白单流水物业表");
        List<ReportQueryRecord> reportQueryRecords = reportFeeInnerServiceSMOImpl.queryReport(BeanConvertUtil.beanCovertMap(reportQueryRecord));
        if(reportQueryRecords.size()>0 && !reqJson.containsKey("reload")){
        if (reqJson.containsKey("roomNum")){
            RoomDto roomDto = new RoomDto();
            roomDto.setRoomNum(reqJson.getString("roomNum"));
            roomDto.setCommunityId(reqJson.getString("communityId"));
            List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);//获取房屋
            OwnerDto ownerDto = new OwnerDto();
            ownerDto.setCommunityId(reqJson.getString("communityId"));
            ownerDto.setRoomId(reqJson.getString("roomNum"));
            List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(ownerDto);//获取业主
            ReportExcelDto reportExcelDto = new ReportExcelDto();
            reportExcelDto.setOwner(ownerDtos.get(0));
            FeeDetailDto feeDetailDto = new FeeDetailDto();
            List<Map> rooms = roomInnerServiceSMOImpl.queryRoomsAsReport(roomDto);
            String[][] strings = new String[rooms.size() + 1][];
            setHeader(strings[0]);
            List<Map> onceOwner = roomInnerServiceSMOImpl.queryRoomsAsReport(roomDto);
            ResultVo resultVo = new ResultVo(strings);
            ResponseEntity<String> responseEntity = new ResponseEntity<String>(resultVo.toString(), HttpStatus.OK);
            context.setResponseEntity(responseEntity);
        }
        else if(reportQueryRecords.size()>0 && !reqJson.containsKey("reload")){
            ResultVo resultVo = new ResultVo(JSONObject.parse(reportQueryRecords.get(reportQueryRecords.size()-1).getReportContent()));
            ResponseEntity<String> responseEntity = new ResponseEntity<String>(resultVo.toString(), HttpStatus.OK);
@@ -83,26 +127,238 @@
        }
        else{
            int row = Integer.parseInt(reqJson.containsKey("row")?reqJson.getString("row"):"10");
            int page = Integer.parseInt(reqJson.containsKey("page")?reqJson.getString("page"):"1");
            startYear = 2016;
            endYear = 2025;
            Object[][] test = new Object[row][];
            RoomDto roomDto = new RoomDto();
            roomDto.setRoomId(reqJson.getString("communityId"));
            roomDto.setCommunityId(reqJson.getString("communityId"));
            roomDto.setRow(row);
            roomDto.setPage(page);
            int count = roomInnerServiceSMOImpl.queryRoomsCount(roomDto);
            List<Map> rooms = roomInnerServiceSMOImpl.queryRoomsAsReport(roomDto);
            FeeConfigDto feeConfigDto = new FeeConfigDto();
            feeConfigDto.setCommunityId(reqJson.getString("communityId"));
            feeConfigDto.setFeeTypeCds(new String[]{"630000001","630000002"});
            feeConfigDto.setRow(2);
            feeConfigDto.setPage(1);
            List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
            int arrLength = 11 + (2 * feeConfigDtos.size()) + 8 + ((endYear - startYear + 1) * 3 + 10) - 9;
            ReportExcelDto[] header = new ReportExcelDto[arrLength];
            List<List<ReportExcelDto>> lists = headerDoing(feeConfigDtos, startYear, endYear, arrLength);
            test[0] = header;
            for (int i = 1; i <= rooms.size(); i++) {
                Map map = rooms.get(i - 1);
                String[] strings = new String[arrLength];
                strings[0] = String.valueOf(row * (page - 1) + i);
                strings[1] = String.valueOf(rooms.get(i - 1).get("property_type"));
                strings[2] = rooms.get(i - 1).get("floor_num").toString();
                strings[3] = rooms.get(i - 1).get("unit_num").toString();
                strings[4] = rooms.get(i - 1).get("room_num").toString();
                strings[5] = strings[3] + "-" +  strings[4];
                strings[6] = rooms.get(i - 1).get("property_address").toString();
                strings[7] = rooms.get(i - 1).get("room_area").toString();
                strings[8] = rooms.get(i - 1).get("name").toString();
                for (int j = 1; j <= feeConfigDtos.size(); j++) {
                    strings[8 + j] = feeConfigDtos.get(j - 1).getSquarePrice();
                }
                strings[8 + feeConfigDtos.size() + 1] = "";
                for (int j = 1; j <= feeConfigDtos.size(); j++) {
                    strings[8 + feeConfigDtos.size() + 1 + j] = (doublequ2(Double.parseDouble(feeConfigDtos.get(j - 1).getSquarePrice()) * Double.parseDouble(String.valueOf((BigDecimal) rooms.get(i - 1).get("room_area")))))+"";
                }
                strings[8 + (2 * feeConfigDtos.size()) + 2] = (doublequ2(Double.parseDouble(feeConfigDtos.get(feeConfigDtos.size() - 1).getSquarePrice()) * Double.parseDouble(String.valueOf((BigDecimal) rooms.get(i - 1).get("room_area")))))+"";
                HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
                objectObjectHashMap.put("payObjId", map.get("room_id"));
                List<Map> fee = reportFeeInnerServiceSMOImpl.onceRoomFee(objectObjectHashMap);
                double allMoney = 0;
                double allPayMoney = 0;
                int monthCount = 0;
                int noPayMoney = 0;
                int year1 = 0;
                int year2 = 0;
                double discountMoney = 0;
                String noPayDate = "";
                currentYear = DateUtil.getYear();
                for (Map map1 : fee){
                    if(map1.containsKey("统计维度") && !(map1.get("统计维度").toString().contains("总计"))){
                        allMoney += ((BigDecimal) map1.get("应收金额")).doubleValue();
                        allPayMoney += ((BigDecimal) map1.get("实收金额")).doubleValue();
                        monthCount += ((BigDecimal)map1.get("未收月数")).intValue();
                        noPayMoney += ((BigDecimal)map1.get("未收金额")).intValue();
                        noPayDate = noPayDate + map1.get("未收区间");
                        discountMoney += ((BigDecimal)map1.get("折扣金额")).doubleValue();
                        if(map1.get("统计维度").equals("2026")){
                            year1 += ((BigDecimal) map1.get("应收金额")).doubleValue();
                        }
                        if(map1.get("统计维度").equals("2027")){
                            year2 += ((BigDecimal) map1.get("应收金额")).doubleValue();
                        }
                    }
                }
                for (int x = endYear ; x >= startYear ; x --){
                    strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 1] = "0";
                    strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 2] = "";
                    strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 3] = "";
                    for (Map map1 : fee){
                        if(map1.get("统计维度").equals((endYear - x + startYear)+"年")) {
                            strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 1] = Integer.parseInt(strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 1]) + ((BigDecimal) map1.get("已收月数")).intValue() + "";
                            if(map1.containsKey("已收区间")){
                                strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 2] = strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 2] + "  " + map1.get("已收区间");
                            }
                            if(map1.containsKey("未收区间")){
                                strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 3] = strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - x)) + 3] + "  " + map1.get("未收区间");
                            }
                        }
                    }
                }
                strings[8 + (2 * feeConfigDtos.size()) + 3] = allMoney+"";
                strings[8 + (2 * feeConfigDtos.size()) + 4] = allPayMoney+"";
                strings[8 + (2 * feeConfigDtos.size()) + 5] = "";
                strings[8 + (2 * feeConfigDtos.size()) + 6] = year1+"";//2026
                strings[8 + (2 * feeConfigDtos.size()) + 7] = year2+"";//2027
                strings[8 + (2 * feeConfigDtos.size()) + 8] = monthCount+"";
                strings[8 + (2 * feeConfigDtos.size()) + 9] = noPayMoney+"";
                strings[8 + (2 * feeConfigDtos.size()) + 10] = "";//22
                strings[8 + (2 * feeConfigDtos.size()) + 11] = "";//23历年待收
                strings[8 + (2 * feeConfigDtos.size()) + 10 + (3 * (endYear - startYear)) + 3 + 1] = discountMoney+"";
                test[i - 1] = strings;
            }
            reportQueryRecord.setCommunityId(reqJson.getString("communityId"));
            reportQueryRecord.setQueryStatus("0");
            reportQueryRecord.setEndYear(currentYear+"");
//            reportQueryRecord.setReportContent(JSONObject.toJSONString());
            ReportExcelDto reportExcelDto = new ReportExcelDto();
            reportExcelDto.setHeader(lists);
            reportExcelDto.setData(test);
            reportQueryRecord.setReportContent(JSONObject.toJSONString(reportExcelDto));
            reportQueryRecord.setOperator("白单流水物业表");
//            int i = reportFeeInnerServiceSMOImpl.saveReport(BeanConvertUtil.beanCovertMap(reportQueryRecord));
            String[][] strings = new String[10][57];
            ResultVo resultVo = new ResultVo(strings);
            ResultVo resultVo = new ResultVo(reportExcelDto);
            resultVo.setTotal(count);
            resultVo.setRecords(count / row);
            ResponseEntity<String> responseEntity = new ResponseEntity<String>(resultVo.toString(), HttpStatus.OK);
            context.setResponseEntity(responseEntity);
        }
    }
    private void setHeader(String[] header) {
        header[0] = "年份";
        header[1] = "应缴月数";
        header[2] = "应缴金额";
        header[3] = "折扣";
        header[4] = "打折金额";
        header[5] = "打折区间";
        header[6] = "打折单归档日期";
        header[7] = "申请人";
        header[8] = "审批人";
        header[9] = "发起日期";
        header[10] = "折后应缴";
        header[11] = "已收月数";
        header[12] = "已缴金额";
        header[13] = "已收区间";
        header[14] = "未缴月数";
        header[15] = "未缴金额";
        header[16] = "未收区间";
    }
    private List<List<ReportExcelDto>> headerDoing(List<FeeConfigDto> feeConfigDtos, int startYear, int endYear, int arrLength) {
        LinkedList<List<ReportExcelDto>> reportExcelDtos = new LinkedList<>();
        int feeRow = feeConfigDtos.size();
        LinkedList<ReportExcelDto> header = new LinkedList<>();
// 1. 固定表头项:严格按原代码col值设置
        header.add(createHeaderRow("序号", 1, 3));          // 原row.setCol(1)
        header.add(createHeaderRow("物业类型", 1, 3));      // 原未改col,沿用前一个1
        header.add(createHeaderRow("楼栋号/弄", 1, 3));    // 原未改col,沿用1
        header.add(createHeaderRow("门号", 1, 3));          // 原未改col,沿用1
        header.add(createHeaderRow("室号", 1, 3));          // 原未改col,沿用1
        header.add(createHeaderRow("门室号", 1, 3));        // 原未改col,沿用1
        header.add(createHeaderRow("产证地址", 1, 3));      // 原未改col,沿用1
        header.add(createHeaderRow("收费面积(m²)", 1, 3));// 原未改col,沿用1
        header.add(createHeaderRow("购房人姓名", 1, 3));    // 原未改col,沿用1
// 2. 第一个feeRow循环:原未显式改col,沿用前一个1(按原逻辑保持col=1)
        for (int i = 0; i < feeRow; i++) {
            header.add(createHeaderRow(feeConfigDtos.get(0).getFeeName(), 1, 3));
        }
// 3. 设备运作费:原未改col,沿用前一个1
        header.add(createHeaderRow("设备运作费", 1, 3));
// 4. 第二个feeRow循环:原未显式改col,沿用前一个1(按原逻辑保持col=1)
        for (int i = 0; i < feeRow; i++) {
            header.add(createHeaderRow(feeConfigDtos.get(0).getFeeName(), 1, 3));
        }
// 5. 年应收款:原显式setCol(1),保持col=1
        header.add(createHeaderRow("年应收款", 1, 3));
// 6. 合计(2020年1月-至今):原显式setCol(8),保持col=8;原setRow(1),保持row=1
        header.add(createHeaderRow("合计(2020年1月-至今)", 8, 1));
// 7. 历年实收:原显式setCol((endYear - startYear + 1) * 3),保持该计算逻辑
        int yearCol = (endYear - startYear + 1) * 3;
        header.add(createHeaderRow("历年实收", yearCol+1, 1));
        header.add(createHeaderRow("操作", 1, 3));    // 原未改col,沿用1
// 最终添加表头到报表列表
        reportExcelDtos.add(header);
        // 初始化 LinkedList(而非数组,支持顺序添加)
        LinkedList<ReportExcelDto> header2 = new LinkedList<>();
// 1. 应收、实收、代收等固定项:按顺序add,对应原数组0-7下标
        header2.add(createHeaderRow("应收", 1, 2));          // 对应原header[0]
        header2.add(createHeaderRow("实收", 1, 2));          // 对应原header[1]
        header2.add(createHeaderRow("代收", 1, 2));          // 对应原header[2]
        header2.add(createHeaderRow("2026年", 1, 2));        // 对应原header[3]
        header2.add(createHeaderRow("2027年", 1, 2));        // 对应原header[4]
        header2.add(createHeaderRow("待收月数", 1, 2));      // 对应原header[5]
        header2.add(createHeaderRow("待收金额", 1, 2));      // 对应原header[6]
        header2.add(createHeaderRow("代收区间", 1, 2));      // 对应原header[7]
// 2. 年份循环:按原下标逻辑计算顺序,继续add(原header[8]及以后)
        for (int i = startYear; i <= endYear; i++) {
            // 原逻辑:index = 7 + (i - startYear + 1) → 首次循环i=startYear时,index=8
            // LinkedList无需关心下标,直接add即可保持顺序(与原数组下标顺序一致)
            header2.add(createHeaderRow(String.valueOf(i), 3, 1));
        }
// 3. 打折金额汇总:原逻辑中"年份循环后"的下一个位置,继续add
        header2.add(createHeaderRow("打折金额汇总", 1, 2));
// 4. 最终添加到报表列表
        reportExcelDtos.add(header2);
        LinkedList<ReportExcelDto> header3 = new LinkedList<>();
        for (int i = startYear ; i <= endYear ; i++){
            header3.add(createHeaderRow("已收月数", 1, 1));
            header3.add(createHeaderRow("已收区间", 1, 1));
            header3.add(createHeaderRow("未收区间", 1, 1));
        }
        reportExcelDtos.add(header3);
        return reportExcelDtos;
    }
    private ReportExcelDto createHeaderRow(String text, int col, int row) {
        ReportExcelDto reportExcelDto = new ReportExcelDto();
        reportExcelDto.setTest(text); // 注意:可能是setText()的笔误
        reportExcelDto.setCol(col);
        reportExcelDto.setRow(row);
        return reportExcelDto;
    }
    public double doublequ2(double num){
        return (int)(num * 100) / 100.0;
    }
}