From 15515e28ee4030d81c0fdf4ba9cb7f86fbd5acf3 Mon Sep 17 00:00:00 2001 From: "liang.chao" <1360241448@qq.com> Date: Fri, 21 Feb 2025 18:43:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=90=8C=E5=8D=8F=E8=AE=AE=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/controller/OrderController.java | 265 +++++++++++++++++- .../material/order/domain/OrderDetailDto.java | 7 +- .../material/order/domain/OrderInfoDto.java | 2 + .../mapper/material/order/OrderInfoMapper.xml | 4 + 4 files changed, 266 insertions(+), 12 deletions(-) diff --git a/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/controller/OrderController.java b/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/controller/OrderController.java index d7dee42..24c92c0 100644 --- a/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/controller/OrderController.java +++ b/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/controller/OrderController.java @@ -1,5 +1,6 @@ package com.bonus.material.order.controller; +import cn.hutool.core.date.DateUtil; import com.bonus.common.core.utils.DateUtils; import com.bonus.common.core.web.controller.BaseController; import com.bonus.common.core.web.domain.AjaxResult; @@ -27,6 +28,8 @@ import javax.annotation.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -58,6 +61,13 @@ public class OrderController extends BaseController { @Resource private RemoteFileService sysFileService; + // 中文大写数字 + private static final String[] CHINESE_NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}; + // 位数单位 + private static final String[] UNITS = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万"}; + // 小数部分单位 + private static final String[] DECIMAL_UNITS = {"角", "分"}; + /** * 提交预约车到订单 */ @@ -161,30 +171,66 @@ public class OrderController extends BaseController { return AjaxResult.error("请先上传合同"); } String wordUrl = list.get(0).getBmFileInfoList().get(0).getFileUrl(); + String contractCode = list.get(0).getContractCode(); InputStream inputStream = new URL(wordUrl).openStream(); XWPFDocument document = new XWPFDocument(inputStream); String dateStr = orderInfoDto.getOrderTime().toString(); SimpleDateFormat inputFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH); - SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = inputFormat.parse(dateStr); String formattedDate = outputFormat.format(date); + Date date1 = inputFormat.parse(orderInfoDto.getStartTime().toString()); + String startTime = outputFormat.format(date1); + Date date2 = inputFormat.parse(orderInfoDto.getEndTime().toString()); + String endTime = outputFormat.format(date2); //订单日期 replacements.put("${createTime}", formattedDate); + + //合同编号 + replacements.put("${contractCode}", contractCode); + + //设备名 + replacements.put("${deviceNames}", orderInfoDto.getDeviceNames()); + + //开始时间 + replacements.put("${startTime}", startTime); + + //结束时间 + replacements.put("${{endTime}}", endTime); + //装备所属公司 replacements.put("${sellerCompanyName}", orderInfoDto.getCzcompanyName()); + //承租方所属公司 replacements.put("${buyerCompanyName}", orderInfoDto.getCompanyName()); + + //订单金额大写 + replacements.put("${costBig}", convert(Double.valueOf(orderInfoDto.getCost().toString()))); + //订单金额 replacements.put("${cost}", orderInfoDto.getCost().toString()); + + //不含税金额 + BigDecimal noTaxCost = orderInfoDto.getCost().multiply(BigDecimal.valueOf(0.87)).setScale(2, RoundingMode.HALF_UP); + replacements.put("${noTaxCost}", noTaxCost.toString()); + + //不含税金额大写 + replacements.put("${noTaxCostBig}", convert(Double.valueOf(noTaxCost.toString()))); + + //税额 + BigDecimal taxCost = orderInfoDto.getCost().subtract(noTaxCost); + replacements.put("${taxCost}", taxCost.toString()); + //出租方电话 replacements.put("${sellerCompanyPhone}", orderInfoDto.getPersonPhone()); + //承租方电话 replacements.put("${buyerCompanyPhone}", orderInfoDto.getPhoneNumber()); //订单详情 - StringBuilder orderDetail = new StringBuilder(); - for (OrderDetailDto orderDetailDto : orderDetailsByOrderId) { +// StringBuilder orderDetail = new StringBuilder(); + /* for (OrderDetailDto orderDetailDto : orderDetailsByOrderId) { Date rentBeginTime = inputFormat.parse(orderDetailDto.getRentBeginTime().toString()); String beginTime = outputFormat.format(rentBeginTime); Date rentEndTime = inputFormat.parse(orderDetailDto.getRentEndTime().toString()); @@ -196,10 +242,12 @@ public class OrderController extends BaseController { .append("天数:").append(orderDetailDto.getDays()).append("天").append("\n") .append("租金:").append(orderDetailDto.getDayLeasePrice()).append("元/天").append("\n") .append("数量:").append(orderDetailDto.getNum()).append("个").append("\n"); - } + }*/ + // 填充订单详情到表格 + fillOrderTable(document, orderDetailsByOrderId, orderInfoDto.getCost().toString()); // 将拼接的字符串放入替换的map中 - replacements.put("${orderTable}", orderDetail.toString()); +// replacements.put("${orderTable}", orderDetail.toString()); for (IBodyElement element : document.getBodyElements()) { if (element instanceof XWPFParagraph) { @@ -236,25 +284,60 @@ public class OrderController extends BaseController { return AjaxResult.error("请先上传合同"); } String wordUrl = list.get(0).getBmFileInfoList().get(0).getFileUrl(); + String contractCode = list.get(0).getContractCode(); InputStream inputStream = new URL(wordUrl).openStream(); XWPFDocument document = new XWPFDocument(inputStream); SimpleDateFormat inputFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH); - SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date date1 = inputFormat.parse(orderInfoDto.getStartTime().toString()); + String startTime = outputFormat.format(date1); + Date date2 = inputFormat.parse(orderInfoDto.getEndTime().toString()); + String endTime = outputFormat.format(date2); Map replacements = new HashMap<>(); //订单日期 replacements.put("${createTime}", DateUtils.getDate()); + + //合同编号 + replacements.put("${contractCode}", contractCode); + + //设备名 + replacements.put("${deviceNames}", orderInfoDto.getDeviceNames()); + + //开始时间 + replacements.put("${startTime}", startTime); + + //结束时间 + replacements.put("${{endTime}}", endTime); + //装备所属公司 replacements.put("${sellerCompanyName}", orderInfoDto.getCzcompanyName()); + //承租方所属公司 replacements.put("${buyerCompanyName}", orderInfoDto.getCompanyName()); + + //订单金额大写 + replacements.put("${costBig}", convert(Double.valueOf(orderInfoDto.getCost().toString()))); + //订单金额 replacements.put("${cost}", orderInfoDto.getCost().toString()); + + //不含税金额 + BigDecimal noTaxCost = orderInfoDto.getCost().multiply(BigDecimal.valueOf(0.87)).setScale(2, RoundingMode.HALF_UP); + replacements.put("${noTaxCost}", noTaxCost.toString()); + + //不含税金额大写 + replacements.put("${noTaxCostBig}", convert(Double.valueOf(noTaxCost.toString()))); + + //税额 + BigDecimal taxCost = orderInfoDto.getCost().subtract(noTaxCost); + replacements.put("${taxCost}", taxCost.toString()); + //出租方电话 replacements.put("${sellerCompanyPhone}", orderInfoDto.getPersonPhone()); + //承租方电话 - replacements.put("${buyerCompanyPhone}", SecurityUtils.getLoginUser().getSysUser().getPhonenumber()); - //订单详情 - StringBuilder orderDetail = new StringBuilder(); + replacements.put("${buyerCompanyPhone}", orderInfoDto.getPhoneNumber()); + /* StringBuilder orderDetail = new StringBuilder(); List detailsList = orderInfoDto.getDetailsList(); for (OrderDetailDto orderDetailDto : detailsList) { if (Objects.isNull(orderDetailDto.getRentBeginTime()) || Objects.isNull(orderDetailDto.getRentEndTime())) { @@ -272,8 +355,9 @@ public class OrderController extends BaseController { .append("租金:").append(orderDetailDto.getDayLeasePrice()).append("元/天").append("\n") .append("数量:").append(orderDetailDto.getNum()).append("个").append("\n"); } - replacements.put("${orderTable}", orderDetail.toString()); - + replacements.put("${orderTable}", orderDetail.toString());*/ + // 填充订单详情到表格 + fillOrderTable(document, orderInfoDto.getDetailsList(), orderInfoDto.getCost().toString()); for (IBodyElement element : document.getBodyElements()) { if (element instanceof XWPFParagraph) { XWPFParagraph paragraph = (XWPFParagraph) element; @@ -301,6 +385,165 @@ public class OrderController extends BaseController { } + /** + * 将数字转换为中文大写金额 + * + * @param number 输入的数字(必须是正数且最多保留两位小数) + * @return 中文大写金额 + */ + public static String convert(double number) { + if (number < 0) { + throw new IllegalArgumentException("只支持正数转换!"); + } + + // 转换为 BigDecimal 并保留两位小数 + BigDecimal decimal = new BigDecimal(number).setScale(2, BigDecimal.ROUND_HALF_UP); + String numStr = decimal.toPlainString(); + + // 分离整数部分和小数部分 + String[] parts = numStr.split("\\."); + String integerPart = parts[0]; // 整数部分 + String decimalPart = parts.length > 1 ? parts[1] : "00"; // 小数部分,默认补足两位 + + // 处理整数部分 + StringBuilder chineseInteger = new StringBuilder(); + boolean hasNonZero = false; // 标记是否有非零数字 + for (int i = 0; i < integerPart.length(); i++) { + char digitChar = integerPart.charAt(i); + int digit = Character.getNumericValue(digitChar); + int unitIndex = integerPart.length() - i - 1; + + // 转换数字为中文大写 + if (digit != 0) { + hasNonZero = true; + chineseInteger.append(CHINESE_NUMBERS[digit]); + chineseInteger.append(UNITS[unitIndex]); + } else if (hasNonZero || (unitIndex > 0 && UNITS[unitIndex].equals("万") || UNITS[unitIndex].equals("亿"))) { + // 如果前面有非零数字或遇到“万”、“亿”,保留“零” + chineseInteger.append(CHINESE_NUMBERS[digit]); + hasNonZero = false; + } + } + + // 去掉多余的“零” + String processedInteger = removeExtraZeros(chineseInteger.toString()); + + // 添加“元”字 + if (processedInteger.isEmpty()) { + processedInteger = "零"; + } + processedInteger += "元"; + + // 处理小数部分 + StringBuilder chineseDecimal = new StringBuilder(); + for (int i = 0; i < decimalPart.length(); i++) { + if (i >= DECIMAL_UNITS.length) { + break; // 超过两位小数的部分忽略 + } + int digit = Character.getNumericValue(decimalPart.charAt(i)); + if (digit != 0) { + chineseDecimal.append(CHINESE_NUMBERS[digit]); + chineseDecimal.append(DECIMAL_UNITS[i]); + } else if (i == 0 && !chineseDecimal.toString().contains("角")) { + chineseDecimal.append(CHINESE_NUMBERS[digit]); // 补充“零”字 + } + } + + // 如果小数部分全为零,则补充“整”字 + if (decimalPart.equals("00")) { + return processedInteger + "整"; + } else { + return processedInteger + chineseDecimal.toString(); + } + } + + /** + * 去掉多余的“零” + * + * @param str 输入字符串 + * @return 去掉多余“零”的字符串 + */ + private static String removeExtraZeros(String str) { + String result = str.replaceAll("(?<=\\B)零(?=\\B)", ""); // 去掉连续的“零” + result = result.replaceAll("亿万", "亿"); // 去掉“亿万”中的“万” + result = result.replaceAll("零+$", ""); // 去掉末尾的“零” + return result; + } + + private static void fillOrderTable(XWPFDocument document, List orderDetails, String cost) { + // 获取第一个表格(假设模板中只有一个表格) + XWPFTable table = document.getTables().get(1); + + // 保留第一行(表头)和最后一行(合计行),仅在中间插入数据行 + int headerRowIndex = 0; // 表头行索引 + int footerRowIndex = table.getRows().size(); // 合计行索引 + + // 删除中间的所有行(如果有的话) + for (int i = table.getRows().size() - 2; i > headerRowIndex; i--) { + table.removeRow(i); + } + // 获取表头行的单元格数量 + int cellCount = table.getRow(headerRowIndex).getTableCells().size(); + + // 遍历订单详情并动态插入数据行 + SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + int num = 1; + for (OrderDetailDto detail : orderDetails) { + XWPFTableRow newRow = table.insertNewTableRow(headerRowIndex + 1); + + // 确保新行有足够数量的单元格 + while (newRow.getTableCells().size() < cellCount) { + newRow.createCell(); + } + int cellIndex = 0; + // 序号 + newRow.getCell(cellIndex++).setText(String.valueOf(num)); + num++; + + // 机具名称 + newRow.getCell(cellIndex++).setText(detail.getDeviceName()); + String typeName = detail.getTypeName(); + // 规格型号 + newRow.getCell(cellIndex++).setText(typeName); + // 单位 + newRow.getCell(cellIndex++).setText(detail.getUnitName()); + // 数量 + newRow.getCell(cellIndex++).setText(detail.getNum() + "个"); + + // 租金 + newRow.getCell(cellIndex++).setText(detail.getDayLeasePrice() + "元/天"); + // 税率 + newRow.getCell(cellIndex++).setText("%13"); + + // 天数 + newRow.getCell(cellIndex++).setText(detail.getDays() + "天"); + + // 预估租赁费用 + newRow.getCell(cellIndex++).setText(detail.getCosts() + "元"); + + // 备注 + newRow.getCell(cellIndex).setText("这是备注"); + // 填充最后一行(合计行) + XWPFTableRow footerRow = table.getRow(footerRowIndex); + int footerCellIndex = 0; + + // 跳过无关列 + footerCellIndex += 1; + + // 合计金额 + footerRow.getCell(footerCellIndex).setText(cost + "元"); + + +// // 租期开始时间 +// newRow.getCell(cellIndex++).setText(outputFormat.format(detail.getRentBeginTime())); +// +// // 租期结束时间 +// newRow.getCell(cellIndex).setText(outputFormat.format(detail.getRentEndTime())); + + } + } + + /* @ApiOperation(value = "租赁协议(查看)-富文本方式") @GetMapping("/leaseAgreement") public AjaxResult getleaseAgreement(String orderId, Map replacements) throws ParseException { diff --git a/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderDetailDto.java b/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderDetailDto.java index 74a9af4..6976b1b 100644 --- a/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderDetailDto.java +++ b/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderDetailDto.java @@ -51,9 +51,12 @@ public class OrderDetailDto { @ApiModelProperty(value = "设备类型id") private Integer typeId; - @ApiModelProperty(value = "类型名称") + @ApiModelProperty(value = "规格型号") private String typeName; + @ApiModelProperty(value = "类型名称") + private String modelName; + @ApiModelProperty(value = "租期开始时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @@ -161,5 +164,7 @@ public class OrderDetailDto { @ApiModelProperty(value = "卖方出租方公司名称") private String sellerCompanyName; + @ApiModelProperty(value = "单位") + private String unitName; } diff --git a/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderInfoDto.java b/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderInfoDto.java index b385c80..f0b9be1 100644 --- a/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderInfoDto.java +++ b/bonus-modules/bonus-material-mall/src/main/java/com/bonus/material/order/domain/OrderInfoDto.java @@ -136,4 +136,6 @@ public class OrderInfoDto { private BigDecimal totalRealPrice; private Integer orderCount; + + private String deviceNames; } diff --git a/bonus-modules/bonus-material-mall/src/main/resources/mapper/material/order/OrderInfoMapper.xml b/bonus-modules/bonus-material-mall/src/main/resources/mapper/material/order/OrderInfoMapper.xml index ec9043c..730a8a9 100644 --- a/bonus-modules/bonus-material-mall/src/main/resources/mapper/material/order/OrderInfoMapper.xml +++ b/bonus-modules/bonus-material-mall/src/main/resources/mapper/material/order/OrderInfoMapper.xml @@ -268,6 +268,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" mdi.type_id as typeId, mdi.device_name, mt.lease_price as dayLeasePrice, + mt.unit_name as unitName, mt.type_name as typeName, hh.order_status, hh.days, @@ -360,11 +361,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" moi.order_time, up.dept_name AS czcompanyName, up.dept_id as companyId, + hh.rent_begin_time as startTime, + hh.rent_end_time as endTime, mdi.person_phone AS personPhone, su.phonenumber AS phoneNumber, moi.address, moi.order_id, sum( hh.costs ) cost, + GROUP_CONCAT(mdi.device_name) deviceNames, dept.dept_name AS companyName FROM ma_order_details hh