| | |
| | | package com.ruoyi.cwgl.service.impl; |
| | | |
| | | import java.io.FileNotFoundException; |
| | | import java.io.FileOutputStream; |
| | | import java.lang.reflect.Method; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Paths; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.util.PageUtil; |
| | | import com.github.pagehelper.Page; |
| | | import com.itextpdf.text.Document; |
| | | import com.itextpdf.text.Font; |
| | | import com.itextpdf.text.PageSize; |
| | | import com.itextpdf.text.pdf.BaseFont; |
| | | import com.itextpdf.text.pdf.PdfWriter; |
| | | import com.ruoyi.common.annotation.Excel; |
| | | import com.ruoyi.common.config.RuoYiConfig; |
| | | import com.ruoyi.common.core.redis.RedisCache; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import javax.annotation.Resource; |
| | | |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.utils.file.DownloadExportUtil; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.cwgl.domain.vo.DispatchOrderVo; |
| | | import com.ruoyi.cwgl.enums.FeeTypeEnums; |
| | | import com.ruoyi.cwgl.utils.MultiPagePdfWithImageUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | |
| | | import com.ruoyi.cwgl.domain.DispatchOrderItem; |
| | | import com.ruoyi.cwgl.domain.vo.DispatchOrderAttachmentVo; |
| | |
| | | protected final Logger logger = LoggerFactory.getLogger(getClass()); |
| | | @Resource |
| | | private DispatchOrderMapper dispatchOrderMapper; |
| | | |
| | | @Autowired |
| | | private RedisCache redisCache; |
| | | |
| | | /** |
| | | * 查询调度单 |
| | |
| | | * @param exportKey 导出功能的唯一标识 |
| | | * @return 调度单集合 |
| | | */ |
| | | @DataSource(DataSourceType.SLAVE) |
| | | @DataSource(DataSourceType.CWSJ) |
| | | @Async |
| | | @Override |
| | | public void export(DispatchOrder dispatchOrder,String exportKey) { |
| | | |
| | | super.export(DispatchOrder.class,exportKey,"dispatchOrderData",(pageNum)->{ |
| | | PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE); |
| | | return selectDispatchOrderList(dispatchOrder); |
| | | return selectDispatchOrderList2(dispatchOrder); |
| | | }); |
| | | } |
| | | |
| | | @DataSource(DataSourceType.CWSJ) |
| | | @Async |
| | | @Override |
| | | public void export2(DispatchOrder dispatchOrder,String exportKey) { |
| | | |
| | | //查询并导出数据文件 |
| | | String fileName =selectListExport(dispatchOrder, "台账信息"); |
| | | //设置文件缓存 |
| | | DownloadExportUtil.setDownloadFile(redisCache, exportKey, fileName); |
| | | } |
| | | |
| | | @DataSource(DataSourceType.CWSJ) |
| | | public String selectListExport(DispatchOrder dispatchOrder, String fileName) |
| | | { |
| | | fileName =ExcelUtil.encodeFileName(fileName); |
| | | //数据集合 |
| | | List<DispatchOrder> dataList = new ArrayList<>(); |
| | | //导出表格对象 |
| | | ExcelUtil<DispatchOrderVo> excelUtil = new ExcelUtil<>(DispatchOrderVo.class); |
| | | excelUtil.initialize("台账信息", null, Excel.Type.EXPORT); |
| | | |
| | | List<DispatchOrderVo> exportList;//导出的数组 |
| | | int pageNum =1,i = 1; |
| | | boolean have=true; |
| | | //region循环分页获取数据 |
| | | while (have) { |
| | | Page<Object> page = PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE); |
| | | List<DispatchOrder> dispatchOrders = selectDispatchOrderList2(dispatchOrder); |
| | | if (dispatchOrders != null && !dispatchOrders.isEmpty()) { |
| | | // 导出当前页的数据 |
| | | exportList=structureData(dispatchOrders,i); |
| | | excelUtil.exportExcel(exportList); |
| | | pageNum++; |
| | | } else { |
| | | // 没有数据时退出 |
| | | have = false; |
| | | } |
| | | } |
| | | excelUtil.finishExport(fileName); |
| | | return fileName; |
| | | } |
| | | /** |
| | | * 封装数据 |
| | | * @param list |
| | | * @return |
| | | */ |
| | | @DataSource(DataSourceType.CWSJ) |
| | | private List<DispatchOrderVo> structureData(List<DispatchOrder> list,int i) { |
| | | List<DispatchOrderVo> exportList = new ArrayList<>(); |
| | | Set<String> dispatchNos = list.stream().map(DispatchOrder::getDispatchNo).collect(Collectors.toSet()); |
| | | Map<String, List<DispatchOrderItemVo>> itemMap = selectDispatchOrderItems(dispatchNos) |
| | | .stream().collect(Collectors.groupingBy(DispatchOrderItemVo::getDispatchNo)); |
| | | |
| | | for (DispatchOrder order : list) { |
| | | try { |
| | | DispatchOrderVo vo = BeanUtil.copyProperties(order, DispatchOrderVo.class); |
| | | vo.setId(i++); |
| | | |
| | | // 初始化费用结构:Map<角色_币种, Map<费用类型, 金额>> |
| | | Map<String, Map<FeeTypeEnums, BigDecimal>> feeMap = initFeeMap(); |
| | | Map<String, BigDecimal> totalMap = initTotalMap(); |
| | | List<DispatchOrderItemVo> items = itemMap.get(order.getDispatchNo()); |
| | | if (items != null) { |
| | | for (DispatchOrderItemVo item : items) { |
| | | if (!StringUtils.isNotEmpty(item.getFeeItem()) || item.getIsSettlement() == 0) continue; |
| | | |
| | | FeeTypeEnums feeType = FeeTypeEnums.from(item.getFeeItem()); |
| | | String actualCurrency = Optional.ofNullable(item.getActualFeeCurrency()).orElse("CNY"); |
| | | String receivableCurrency = Optional.ofNullable(item.getReceivableFeeCurrency()).orElse("CNY"); |
| | | |
| | | |
| | | addFee(feeMap, "customer_" + actualCurrency, feeType, item.getActualFee()); |
| | | addTotal(totalMap, "customer_" + actualCurrency, item.getActualFee()); |
| | | |
| | | addFee(feeMap, "supplier_" + receivableCurrency, feeType, item.getReceivableFee()); |
| | | addTotal(totalMap, "supplier_" + receivableCurrency, item.getReceivableFee()); |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | // 设置 VO 字段 |
| | | setFeeToVo(vo, feeMap, totalMap); |
| | | |
| | | exportList.add(vo); |
| | | } catch (Exception e) { |
| | | logger.error("数据处理失败 id:{}", order, e); |
| | | } |
| | | } |
| | | |
| | | return exportList; |
| | | } |
| | | private Map<String, Map<FeeTypeEnums, BigDecimal>> initFeeMap() { |
| | | Map<String, Map<FeeTypeEnums, BigDecimal>> map = new HashMap<>(); |
| | | for (String key : Arrays.asList("customer_CNY", "customer_HKD", "supplier_CNY", "supplier_HKD")) { |
| | | Map<FeeTypeEnums, BigDecimal> subMap = new EnumMap<>(FeeTypeEnums.class); |
| | | for (FeeTypeEnums feeType : FeeTypeEnums.values()) { |
| | | subMap.put(feeType, BigDecimal.ZERO); |
| | | } |
| | | map.put(key, subMap); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | private Map<String, BigDecimal> initTotalMap() { |
| | | Map<String, BigDecimal> totalMap = new HashMap<>(); |
| | | for (String key : Arrays.asList("customer_CNY", "customer_HKD", "supplier_CNY", "supplier_HKD")) { |
| | | totalMap.put(key, BigDecimal.ZERO); |
| | | } |
| | | return totalMap; |
| | | } |
| | | |
| | | private void addFee(Map<String, Map<FeeTypeEnums, BigDecimal>> map, String key, FeeTypeEnums feeType, BigDecimal amount) { |
| | | if (amount == null) return; |
| | | Map<FeeTypeEnums, BigDecimal> subMap = map.get(key); |
| | | subMap.put(feeType, subMap.get(feeType).add(amount)); |
| | | } |
| | | private void addTotal(Map<String, BigDecimal> totalMap, String key, BigDecimal amount) { |
| | | if (amount == null) return; |
| | | totalMap.put(key, totalMap.get(key).add(amount)); |
| | | } |
| | | |
| | | private void setFeeToVo(DispatchOrderVo vo, |
| | | Map<String, Map<FeeTypeEnums, BigDecimal>> map, |
| | | Map<String, BigDecimal> totalMap) { |
| | | |
| | | for (String role : Arrays.asList("Customer", "Supplier")) { |
| | | for (String currency : Arrays.asList("Rmb", "Hkd")) { |
| | | String mapKey = role.toLowerCase() + "_" + ("Rmb".equals(currency) ? "CNY" : "HKD"); |
| | | Map<FeeTypeEnums, BigDecimal> feeTypeMap = map.get(mapKey); |
| | | |
| | | for (FeeTypeEnums feeType : FeeTypeEnums.values()) { |
| | | String methodName = "set" + role + feeType.getFieldSuffix() + currency; |
| | | invokeSetter(vo, methodName, feeTypeMap.get(feeType)); |
| | | } |
| | | |
| | | // 设置 total 字段 |
| | | String totalMethod = "set" + role + "Total" + currency; |
| | | invokeSetter(vo, totalMethod, totalMap.get(mapKey)); |
| | | } |
| | | } |
| | | } |
| | | private void invokeSetter(Object obj, String methodName, BigDecimal value) { |
| | | try { |
| | | Method method = obj.getClass().getMethod(methodName, BigDecimal.class); |
| | | method.invoke(obj, value); |
| | | } catch (Exception e) { |
| | | logger.warn("调用方法失败: {}", methodName, e); |
| | | } |
| | | } |
| | | |
| | | |
| | | @DataSource(DataSourceType.CWSJ) |
| | | public List<DispatchOrderItemVo> selectDispatchOrderItems( Set<String> nos) { |
| | | // 使用Map来临时存储分组结果 |
| | | List<DispatchOrderItemVo> vos = new ArrayList<>(); |
| | | List<DispatchOrderItem> dispatchOrderItems=dispatchOrderMapper.selectDispatchOrderItemByNos(nos); |
| | | for (DispatchOrderItem dispatchOrderItem : dispatchOrderItems) { |
| | | HashSet<String> settableFeeItemSet = new HashSet<>( |
| | | Arrays.asList(Optional.ofNullable(dispatchOrderItem.getSettableFeeItems()).orElse("").split(","))); |
| | | |
| | | // 判断是否可结算 |
| | | String feeItem = Optional.ofNullable(dispatchOrderItem.getFeeItem()).orElse(""); |
| | | int isSettable = settableFeeItemSet.contains(feeItem)?1:0; |
| | | // 如果Map中不存在该费用类型,则创建新条目 |
| | | |
| | | DispatchOrderItemVo summary = new DispatchOrderItemVo(); |
| | | summary.setDispatchNo(dispatchOrderItem.getDispatchNo()); |
| | | summary.setFeeItem(feeItem); |
| | | summary.setReceivableFee(BigDecimal.ZERO); |
| | | summary.setActualFee(BigDecimal.ZERO); |
| | | summary.setIsSettlement(isSettable); |
| | | |
| | | if ("R".equals(dispatchOrderItem.getBillType())) { // 应收 |
| | | summary.setReceivableFee(dispatchOrderItem.getSettleFee()); |
| | | summary.setReceivableFeeCurrency(dispatchOrderItem.getCurrencyType()); |
| | | } else if ("P".equals(dispatchOrderItem.getBillType())) { // 应付 |
| | | summary.setActualFee(dispatchOrderItem.getSettleFee()); |
| | | summary.setActualFeeCurrency(dispatchOrderItem.getCurrencyType()); |
| | | |
| | | } |
| | | vos.add( summary); |
| | | } |
| | | return vos; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | public List<DispatchOrderAttachmentVo> selectDispatchOrderAttachment(String no) { |
| | | return dispatchOrderMapper.selectDispatchOrderAttachment(no); |
| | | } |
| | | |
| | | @DataSource(DataSourceType.CWSJ) |
| | | @Override |
| | | public String downAttachment(String no) throws Exception { |
| | | List<DispatchOrderAttachmentVo> dispatchOrderAttachmentVos = selectDispatchOrderAttachment(no); |
| | | return MultiPagePdfWithImageUtils.createPdf(dispatchOrderAttachmentVos, no); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |