合同协议功能开发
This commit is contained in:
parent
f6bbc9d2f5
commit
15515e28ee
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,4 +136,6 @@ public class OrderInfoDto {
|
|||
private BigDecimal totalRealPrice;
|
||||
|
||||
private Integer orderCount;
|
||||
|
||||
private String deviceNames;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue