合同协议功能开发

This commit is contained in:
liang.chao 2025-02-21 18:43:12 +08:00
parent f6bbc9d2f5
commit 15515e28ee
4 changed files with 266 additions and 12 deletions

View File

@ -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<String, String> 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<OrderDetailDto> 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<OrderDetailDto> 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<String, String> replacements) throws ParseException {

View File

@ -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;
}

View File

@ -136,4 +136,6 @@ public class OrderInfoDto {
private BigDecimal totalRealPrice;
private Integer orderCount;
private String deviceNames;
}

View File

@ -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