From c8f7e94c8effd7980b1e0c9048811d2b9d64ede2 Mon Sep 17 00:00:00 2001
From: syruan <321359594@qq.com>
Date: Wed, 3 Dec 2025 19:53:45 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96Excel=E5=AF=BC=E5=87=BA?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=B4=B9=E7=94=A8?=
=?UTF-8?q?=E6=B1=87=E6=80=BB=E5=8C=BA=E5=9F=9F=E5=8F=8A=E9=87=91=E9=A2=9D?=
=?UTF-8?q?=E8=BD=AC=E6=8D=A2=E4=B8=BA=E4=B8=AD=E6=96=87=E5=A4=A7=E5=86=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../views/projectCost/calculation_detail.jsp | 18 +-
.../views/projectCost/calculation_form.jsp | 4 +-
.../static/js/projectCost/projectCost.js | Bin 141764 -> 141788 bytes
resources/mybatis/cost/ProjectCostMapper.xml | 14 +-
.../cost/service/ProjectCostServiceImpl.java | 363 +++++++++++++++++-
5 files changed, 377 insertions(+), 22 deletions(-)
diff --git a/WebContent/WEB-INF/views/projectCost/calculation_detail.jsp b/WebContent/WEB-INF/views/projectCost/calculation_detail.jsp
index 55e133e..f4a6399 100644
--- a/WebContent/WEB-INF/views/projectCost/calculation_detail.jsp
+++ b/WebContent/WEB-INF/views/projectCost/calculation_detail.jsp
@@ -246,23 +246,23 @@
elem: '#calculation-table',
data: details,
cols: [[
- {field: 'machineTypeName', title: '物资名称', width: 180},
- {field: 'machineModel', title: '规格型号', width: 150},
- {field: 'machineUnit', title: '单位', width: 100},
- {field: 'currentCount', title: '未退还数量', width: 120},
- {field: 'price', title: '单价(元/天)', width: 120, templet: function(d){
+ {field: 'machineTypeName', title: '物资名称', minWidth: 150},
+ {field: 'machineModel', title: '规格型号', minWidth: 120},
+ {field: 'machineUnit', title: '单位', width: 80},
+ {field: 'currentCount', title: '未退还数量', width: 110},
+ {field: 'price', title: '单价(元/天)', width: 110, templet: function(d){
return d.price ? d.price.toFixed(2) : '0.00';
}},
- {field: 'firstLeaseTime', title: '首次领料时间', width: 180, templet: function(d){
+ {field: 'firstLeaseTime', title: '首次领料时间', minWidth: 150, templet: function(d){
return d.firstLeaseTime || '--';
}},
- {field: 'lastReturnTime', title: '最后退料时间', width: 180, templet: function(d){
+ {field: 'lastReturnTime', title: '最后退料时间', minWidth: 150, templet: function(d){
return d.lastReturnTime || '--';
}},
- {field: 'amount', title: '金额(元)', width: 120, style: 'color: #FF5722; font-weight: bold;', templet: function(d){
+ {field: 'amount', title: '金额(元)', width: 110, style: 'color: #FF5722; font-weight: bold;', templet: function(d){
return d.amount ? d.amount.toFixed(2) : '0.00';
}},
- {title: '操作', width: 100, templet: function(d){
+ {title: '操作', width: 100, fixed: 'right', templet: function(d){
return '查看明细';
}}
]],
diff --git a/WebContent/WEB-INF/views/projectCost/calculation_form.jsp b/WebContent/WEB-INF/views/projectCost/calculation_form.jsp
index 79e3993..a5192bb 100644
--- a/WebContent/WEB-INF/views/projectCost/calculation_form.jsp
+++ b/WebContent/WEB-INF/views/projectCost/calculation_form.jsp
@@ -89,8 +89,8 @@
-
-
+
+
diff --git a/WebContent/static/js/projectCost/projectCost.js b/WebContent/static/js/projectCost/projectCost.js
index e8c15203251484c4a51385146f71b73134e8b5ce..f022e6ef768fcad0f87916440917d5adaa74ce8a 100644
GIT binary patch
delta 110
zcmX?dnd8o7j)pCaLadX28H+F)O`p%fls^3e3nSn3f?h^F@mz*XhCGIFAeq8Y!jQpW
z#h}1o$Y3#jAqP_`L|H&TqXuK{WO-}x>HpZ7lBPdlW3*$3YMcJ?9OLr#Q|ye}Pq8!o
GQUm~5
and wir.MODEL_ID = #{param.machineTypeId}
-
- and left(wtr.OPERATION_TIME,10) between #{param.startTime} and #{param.endTime}
+
+
+ and left(wtr.OPERATION_TIME,10) <= #{param.endTime}
AND(
@@ -88,7 +89,10 @@
and wir.MODEL_ID = #{param.machineTypeId}
- and left(wir.TIME,10) BETWEEN #{param.startTime} and #{param.endTime}
+
+
+ and left(wir.TIME,10) <= #{param.endTime}
+
and (
bu.`NAME` like concat('%',#{param.keyWord},'%') OR
diff --git a/src/com/bonus/cost/service/ProjectCostServiceImpl.java b/src/com/bonus/cost/service/ProjectCostServiceImpl.java
index ea1d8e8..cb1c6c0 100644
--- a/src/com/bonus/cost/service/ProjectCostServiceImpl.java
+++ b/src/com/bonus/cost/service/ProjectCostServiceImpl.java
@@ -165,6 +165,92 @@ public class ProjectCostServiceImpl implements ProjectCostService {
}
}
+ /**
+ * 将数字金额转换为中文大写金额
+ *
+ * @param amount 金额数字
+ * @return 中文大写金额字符串
+ */
+ private String convertToChineseAmount(double amount) {
+ if (amount == 0) {
+ return "零元整";
+ }
+
+ // 中文数字
+ String[] chineseNumbers = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
+ // 中文单位
+ String[] units = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"};
+
+ // 处理负数
+ boolean isNegative = amount < 0;
+ amount = Math.abs(amount);
+
+ // 分离整数和小数部分
+ long integerPart = (long) amount;
+ int decimalPart = (int) Math.round((amount - integerPart) * 100);
+
+ StringBuilder result = new StringBuilder();
+
+ if (isNegative) {
+ result.append("负");
+ }
+
+ // 处理整数部分
+ if (integerPart == 0) {
+ result.append("零");
+ } else {
+ String integerStr = String.valueOf(integerPart);
+ int length = integerStr.length();
+ boolean hasZero = false; // 标记是否有零
+
+ for (int i = 0; i < length; i++) {
+ int digit = integerStr.charAt(i) - '0';
+ int unitIndex = length - i - 1;
+
+ if (digit == 0) {
+ // 遇到0的处理
+ if (unitIndex == 4 || unitIndex == 8) {
+ // 万位或亿位,即使是0也要加单位
+ if (!hasZero) {
+ result.append(units[unitIndex]);
+ }
+ }
+ hasZero = true;
+ } else {
+ // 非0的处理
+ if (hasZero) {
+ result.append(chineseNumbers[0]); // 补零
+ }
+ result.append(chineseNumbers[digit]);
+ result.append(units[unitIndex]);
+ hasZero = false;
+ }
+ }
+ }
+
+ result.append("元");
+
+ // 处理小数部分
+ if (decimalPart == 0) {
+ result.append("整");
+ } else {
+ int jiao = decimalPart / 10;
+ int fen = decimalPart % 10;
+
+ if (jiao > 0) {
+ result.append(chineseNumbers[jiao]).append("角");
+ } else if (fen > 0) {
+ result.append("零");
+ }
+
+ if (fen > 0) {
+ result.append(chineseNumbers[fen]).append("分");
+ }
+ }
+
+ return result.toString();
+ }
+
@Override
public List queryProjectLeaseDetails(ProjectLeaseCostDetail o) {
return projectCostDao.queryProjectLeaseDetails(o);
@@ -356,16 +442,87 @@ public class ProjectCostServiceImpl implements ProjectCostService {
LocalDateTime firstLeaseTime = null;
LocalDateTime lastReturnTime = null;
+ // 第一步:处理统计期间开始之前的所有操作,计算期初在用数量
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (ProjectLeaseCostDetail item : items) {
if (item == null || item.getOperateTime() == null) {
continue;
}
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ LocalDateTime operateTime = LocalDateTime.parse(item.getOperateTime(), formatter);
+
+ // 只处理统计期间开始之前的操作
+ if (operateTime.isBefore(startDate)) {
+ boolean isLease = (item.getOperateType() == null || item.getOperateType() != 2);
+ if (isLease) {
+ int quantity = item.getLeaseNum() != null ? item.getLeaseNum() : 0;
+ currentCount += quantity;
+ System.out.println("期初领料: 物资ID=" + machineTypeId + ", 时间=" + item.getOperateTime() + ", 数量=" + quantity + ", 累计=" + currentCount);
+ } else {
+ int quantity = item.getReturnNum() != null ? item.getReturnNum() : 0;
+ currentCount -= quantity;
+ System.out.println("期初退料: 物资ID=" + machineTypeId + ", 时间=" + item.getOperateTime() + ", 数量=" + quantity + ", 累计=" + currentCount);
+ }
+ }
+ }
+
+ System.out.println("物资ID=" + machineTypeId + " 期初在用数量: " + currentCount);
+
+ // 如果期初在用数量大于0,需要计算从统计开始时间到第一个操作时间(或统计结束时间)的费用
+ if (currentCount > 0) {
+ // 找到统计期间内的第一个操作时间
+ LocalDateTime firstOperateTimeInPeriod = null;
+ for (ProjectLeaseCostDetail item : items) {
+ if (item == null || item.getOperateTime() == null) {
+ continue;
+ }
+ LocalDateTime operateTime = LocalDateTime.parse(item.getOperateTime(), formatter);
+ if (!operateTime.isBefore(startDate) && !operateTime.isAfter(endDate)) {
+ if (firstOperateTimeInPeriod == null || operateTime.isBefore(firstOperateTimeInPeriod)) {
+ firstOperateTimeInPeriod = operateTime;
+ }
+ }
+ }
+
+ // 如果统计期间内有操作,计算从开始时间到第一个操作时间的费用
+ // 如果统计期间内没有操作,计算从开始时间到结束时间的费用
+ LocalDateTime endTimeForInitialSegment = firstOperateTimeInPeriod != null ? firstOperateTimeInPeriod : endDate;
+ long daysBetween = java.time.Duration.between(startDate, endTimeForInitialSegment).toDays();
+
+ if (daysBetween > 0) {
+ double segmentAmount = currentCount * unitPrice * daysBetween;
+ totalItemAmount += segmentAmount;
+
+ Map segment = new HashMap<>();
+ segment.put("startTime", startDate.toString());
+ segment.put("endTime", endTimeForInitialSegment.toString());
+ segment.put("days", daysBetween);
+ segment.put("count", currentCount);
+ segment.put("amount", segmentAmount);
+ segments.add(segment);
+
+ System.out.println("期初在用费用: 物资ID=" + machineTypeId + ", 时段=" + startDate + " 至 " + endTimeForInitialSegment
+ + ", 天数=" + daysBetween + ", 数量=" + currentCount + ", 单价=" + unitPrice + ", 段金额=" + segmentAmount);
+ }
+
+ // 如果统计期间内有操作,更新previousTime为第一个操作时间
+ if (firstOperateTimeInPeriod != null) {
+ previousTime = firstOperateTimeInPeriod;
+ } else {
+ // 如果统计期间内没有操作,直接返回结果
+ previousTime = endDate;
+ }
+ }
+
+ // 第二步:处理统计期间内的所有操作
+ for (ProjectLeaseCostDetail item : items) {
+ if (item == null || item.getOperateTime() == null) {
+ continue;
+ }
LocalDateTime operateTime = LocalDateTime.parse(item.getOperateTime(), formatter);
- // 如果操作时间超出统计范围,跳过
+ // 只处理统计期间内的操作(包括开始和结束时间)
if (operateTime.isBefore(startDate) || operateTime.isAfter(endDate)) {
continue;
}
@@ -999,9 +1156,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
}
}
- // 调用带签名区域的导出方法,传递工程名称和制单时间
+ // 计算总金额
+ double totalAmount = calculation.getTotalAmount() != null ? calculation.getTotalAmount() : 0.0;
+
+ // 调用带签名区域的导出方法,传递工程名称、制单时间和总金额
exportSegmentExcelWithSignature(fileName, sheetName, headers, widths, formats, dataList,
- calculation.getProjectName(), calculation.getCreateTime(), response);
+ calculation.getProjectName(), calculation.getCreateTime(), totalAmount, response);
}
/**
@@ -1015,11 +1175,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
* @param dataList 数据列表
* @param projectName 工程名称
* @param createTime 制单时间
+ * @param totalAmount 总金额
* @param response HttpServletResponse对象
* @throws Exception 导出异常
*/
private void exportSegmentExcelWithSignature(String fileName, String sheetName, String[] headers, int[] widths, int[] formats,
- List