结算修改
This commit is contained in:
parent
7621de57f3
commit
72944b90ce
|
|
@ -0,0 +1,3 @@
|
|||
/build/
|
||||
/classes/
|
||||
/logs/
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,32 +17,43 @@
|
|||
.layui-card-header {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
background: linear-gradient(to right, #1E9FFF, #5FB878);
|
||||
color: white;
|
||||
}
|
||||
.detail-header {
|
||||
margin-bottom: 20px;
|
||||
background-color: #f8f8f8;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid #1E9FFF;
|
||||
}
|
||||
.detail-info {
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.detail-info .layui-inline {
|
||||
margin-right: 20px;
|
||||
margin-right: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.detail-info .label {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
min-width: 90px;
|
||||
text-align: right;
|
||||
margin-right: 10px;
|
||||
color: #333;
|
||||
}
|
||||
.detail-info .value {
|
||||
display: inline-block;
|
||||
color: #666;
|
||||
}
|
||||
.total-amount {
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
color: #FF5722;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
padding: 10px 20px;
|
||||
padding: 15px 0;
|
||||
border-top: 2px dashed #e6e6e6;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.layui-tab-content {
|
||||
padding: 15px 0;
|
||||
|
|
@ -50,33 +61,57 @@
|
|||
.layui-table-view {
|
||||
margin: 0;
|
||||
}
|
||||
/* 操作按钮区域样式 */
|
||||
.action-buttons {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 30px;
|
||||
z-index: 999;
|
||||
background: white;
|
||||
padding: 15px 20px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
max-width: 600px;
|
||||
}
|
||||
.action-buttons .layui-btn {
|
||||
margin: 0;
|
||||
}
|
||||
/* 打印时隐藏操作按钮 */
|
||||
@media print {
|
||||
.action-buttons {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">计算结果详情</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="detail-header">
|
||||
<div class="detail-info" style="font-size: 13px;">
|
||||
<div class="detail-info">
|
||||
<div class="layui-inline">
|
||||
<span class="label" style="background-color: #1E9FFF !important;">工程名称:</span>
|
||||
<span class="label" style="background-color: transparent !important;">工程名称:</span>
|
||||
<span class="value" id="projectName"></span>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<span class="label" style="background-color: #1E9FFF !important;">统计区间:</span>
|
||||
<span class="label" style="background-color: transparent !important;">统计区间:</span>
|
||||
<span class="value" id="timeRange"></span>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<span class="label" style="background-color: #1E9FFF !important;">创建时间:</span>
|
||||
<span class="label" style="background-color: transparent !important;">创建时间:</span>
|
||||
<span class="value" id="createTime"></span>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<span class="label" style="background-color: #1E9FFF !important;">创建人:</span>
|
||||
<span class="label" style="background-color: transparent !important;">创建人:</span>
|
||||
<span class="value" id="createUser"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-amount">
|
||||
<i class="layui-icon layui-icon-rmb" style="font-size: 18px;"></i>
|
||||
总金额:<span id="totalAmount">0.00</span> 元
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -92,14 +127,20 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-primary" id="back-btn">返回</button>
|
||||
<button class="layui-btn" id="print-btn">打印</button>
|
||||
<button class="layui-btn layui-btn-normal" id="export-cost-btn"><i class="layui-icon layui-icon-export"></i> 导出费用计算表</button>
|
||||
<button class="layui-btn layui-btn-normal" id="export-segment-btn"><i class="layui-icon layui-icon-export"></i> 导出物资区间费用表</button>
|
||||
<button class="layui-btn layui-btn-normal" id="export-record-btn"><i class="layui-icon layui-icon-export"></i> 导出领退记录表</button>
|
||||
</div>
|
||||
<!-- 操作按钮区域 - 固定在右下角 -->
|
||||
<div class="action-buttons">
|
||||
<!-- <button class="layui-btn layui-btn-warm" id="print-btn">
|
||||
<i class="layui-icon layui-icon-print"></i> 打印
|
||||
</button> -->
|
||||
<button class="layui-btn layui-btn-normal" id="export-segment-btn">
|
||||
<i class="layui-icon layui-icon-export"></i> 导出物资区间费用表
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-primary" id="export-cost-btn">
|
||||
<i class="layui-icon layui-icon-export"></i> 导出费用计算表
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-primary" id="export-record-btn">
|
||||
<i class="layui-icon layui-icon-export"></i> 导出领退记录表
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -205,23 +246,23 @@
|
|||
elem: '#calculation-table',
|
||||
data: details,
|
||||
cols: [[
|
||||
{field: 'machineTypeName', title: '物资名称', minWidth: 160},
|
||||
{field: 'machineModel', title: '规格型号', minWidth: 120},
|
||||
{field: 'machineUnit', title: '单位', width: 80},
|
||||
{field: 'currentCount', title: '未退还数量', width: 100},
|
||||
{field: 'price', title: '单价(元/天)', width: 100, templet: function(d){
|
||||
{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){
|
||||
return d.price ? d.price.toFixed(2) : '0.00';
|
||||
}},
|
||||
{field: 'firstLeaseTime', title: '首次领料时间', minWidth: 160, templet: function(d){
|
||||
{field: 'firstLeaseTime', title: '首次领料时间', width: 180, templet: function(d){
|
||||
return d.firstLeaseTime || '--';
|
||||
}},
|
||||
{field: 'lastReturnTime', title: '最后退料时间', minWidth: 160, templet: function(d){
|
||||
{field: 'lastReturnTime', title: '最后退料时间', width: 180, templet: function(d){
|
||||
return d.lastReturnTime || '--';
|
||||
}},
|
||||
{field: 'amount', title: '金额(元)', width: 100, style: 'color: #FF5722; font-weight: bold;', templet: function(d){
|
||||
{field: 'amount', title: '金额(元)', width: 120, style: 'color: #FF5722; font-weight: bold;', templet: function(d){
|
||||
return d.amount ? d.amount.toFixed(2) : '0.00';
|
||||
}},
|
||||
{title: '操作', width: 90, templet: function(d){
|
||||
{title: '操作', width: 100, templet: function(d){
|
||||
return '<a class="layui-btn layui-btn-xs" lay-event="viewDetail">查看明细</a>';
|
||||
}}
|
||||
]],
|
||||
|
|
@ -262,7 +303,7 @@
|
|||
area: ['800px', '500px'],
|
||||
success: function(layero, index){
|
||||
let i;
|
||||
// 初始化Tab
|
||||
// 初始化Tab
|
||||
element.render('tab');
|
||||
|
||||
// 填充时段数据
|
||||
|
|
@ -383,11 +424,6 @@
|
|||
});
|
||||
}
|
||||
|
||||
// 返回按钮
|
||||
$('#back-btn').on('click', function(){
|
||||
location.href = '${bonuspath}/backstage/projectCost/list';
|
||||
});
|
||||
|
||||
// 打印按钮
|
||||
$('#print-btn').on('click', function(){
|
||||
window.print();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
.layui-form-item .layui-input-inline {
|
||||
width: 180px;
|
||||
}
|
||||
/* 工程名称下拉框加宽 */
|
||||
.project-select-width {
|
||||
width: 400px !important;
|
||||
}
|
||||
.filter-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -68,8 +72,8 @@
|
|||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<div class="filter-label">工程名称</div>
|
||||
<div class="layui-input-inline">
|
||||
<select name="projectId" lay-verify="required" lay-filter="projectSelect">
|
||||
<div class="layui-input-inline project-select-width">
|
||||
<select name="projectId" lay-verify="required" lay-filter="projectSelect" lay-search="">
|
||||
<option value="">请选择工程</option>
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,91 +15,200 @@
|
|||
<link rel="stylesheet" href="${bonuspath}/static/css/admin.css" media="all">
|
||||
<link rel="stylesheet" href="${bonuspath}/static/css/common.css" media="all">
|
||||
<style>
|
||||
/* 优化筛选区域和按钮布局 */
|
||||
/* 页面整体布局 */
|
||||
.layui-card {
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* 搜索栏区域样式 */
|
||||
.search-bar-wrapper {
|
||||
padding: 20px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.filter-area {
|
||||
padding: 10px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
margin-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
padding: 8px 15px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
width: auto;
|
||||
padding-right: 8px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-right: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
}
|
||||
.filter-buttons {
|
||||
margin-left: auto;
|
||||
white-space: nowrap;
|
||||
|
||||
.filter-item .layui-input {
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 3px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.filter-item .layui-input:focus {
|
||||
border-color: #1E9FFF;
|
||||
box-shadow: 0 0 5px rgba(30, 159, 255, 0.3);
|
||||
}
|
||||
|
||||
.layui-input-inline-auto {
|
||||
width: auto;
|
||||
min-width: 120px;
|
||||
min-width: 180px;
|
||||
}
|
||||
|
||||
.layui-input-inline-date {
|
||||
width: 120px;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.layui-form-mid {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
/* 按钮区域样式 */
|
||||
.filter-buttons {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.filter-buttons .layui-btn {
|
||||
border-radius: 4px;
|
||||
padding: 0 20px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.filter-buttons .layui-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.filter-buttons .layui-btn i {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* 表格区域样式 */
|
||||
.table-wrapper {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 0 0 6px 6px;
|
||||
border-top: 3px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.layui-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 表格操作按钮优化 */
|
||||
.layui-table-view .layui-btn-xs {
|
||||
padding: 0 10px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* 响应式布局 */
|
||||
@media screen and (max-width: 768px) {
|
||||
.search-bar-wrapper {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.filter-area {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.filter-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.filter-label {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.layui-input-inline-auto,
|
||||
.layui-input-inline-date {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.filter-buttons {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filter-buttons .layui-btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-form filter-area">
|
||||
<div class="filter-item">
|
||||
<div class="filter-label">工程名称</div>
|
||||
<div class="layui-input-inline layui-input-inline-auto">
|
||||
<input type="text" name="projectName" placeholder="请输入工程名称" autocomplete="off" class="layui-input">
|
||||
<!-- 搜索栏区域 -->
|
||||
<div class="search-bar-wrapper">
|
||||
<div class="layui-form filter-area">
|
||||
<div class="filter-item">
|
||||
<div class="filter-label">工程名称</div>
|
||||
<div class="layui-input-inline layui-input-inline-auto">
|
||||
<input type="text" name="projectName" placeholder="请输入工程名称" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<div class="filter-label">计算日期</div>
|
||||
<div class="layui-input-inline layui-input-inline-date">
|
||||
<input type="text" name="startDate" id="startDate" placeholder="开始日期" autocomplete="off" class="layui-input">
|
||||
<div class="filter-item">
|
||||
<div class="filter-label">计算日期</div>
|
||||
<div class="layui-input-inline layui-input-inline-date">
|
||||
<input type="text" name="startDate" id="startDate" placeholder="开始日期" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid">-</div>
|
||||
<div class="layui-input-inline layui-input-inline-date">
|
||||
<input type="text" name="endDate" id="endDate" placeholder="结束日期" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-mid">-</div>
|
||||
<div class="layui-input-inline layui-input-inline-date">
|
||||
<input type="text" name="endDate" id="endDate" placeholder="结束日期" autocomplete="off" class="layui-input">
|
||||
<div class="filter-buttons">
|
||||
<button class="layui-btn" lay-submit lay-filter="LAY-project-cost-search">
|
||||
<i class="layui-icon layui-icon-search"></i> 搜索
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-normal" data-type="add">
|
||||
<i class="layui-icon layui-icon-add-1"></i> 新增结算单
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-buttons">
|
||||
<button class="layui-btn layui-btn-sm" lay-submit lay-filter="LAY-project-cost-search">
|
||||
<i class="layui-icon layui-icon-search"></i> 搜索
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-normal" data-type="add">
|
||||
<i class="layui-icon layui-icon-add-1"></i> 新增结算单
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card-body">
|
||||
<table id="LAY-project-cost-list" lay-filter="LAY-project-cost-list"></table>
|
||||
<script type="text/html" id="table-project-cost-list">
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="detail"><i class="layui-icon layui-icon-search"></i>查看</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete"><i class="layui-icon layui-icon-delete"></i>删除</a>
|
||||
</script>
|
||||
<!-- 表格区域 -->
|
||||
<div class="table-wrapper">
|
||||
<div class="layui-card-body">
|
||||
<table id="LAY-project-cost-list" lay-filter="LAY-project-cost-list"></table>
|
||||
<script type="text/html" id="table-project-cost-list">
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="detail">
|
||||
<i class="layui-icon layui-icon-search"></i> 查看
|
||||
</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">
|
||||
<i class="layui-icon layui-icon-delete"></i> 删除
|
||||
</a>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -139,7 +248,7 @@
|
|||
$('.layui-btn[data-type="add"]').on('click', function(){
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '新增计算结果',
|
||||
title: '机具费用结算单',
|
||||
content: '${bonuspath}/backstage/projectCost/calculation_form',
|
||||
area: ['90%', '90%'],
|
||||
maxmin: false
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -19,6 +19,7 @@ import org.apache.poi.hssf.usermodel.HSSFFont;
|
|||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -115,7 +116,7 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
|
||||
/**
|
||||
* 安全转换为String类型
|
||||
*
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @param defaultValue 默认值
|
||||
* @return 转换后的String值
|
||||
|
|
@ -132,6 +133,38 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
return String.valueOf(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期时间字符串,只保留年月日部分
|
||||
*
|
||||
* @param dateTimeStr 日期时间字符串,格式如 "2025-04-02T09:41:13" 或 "2025-04-02 09:41:13"
|
||||
* @return 格式化后的日期字符串,格式为 "2025-04-02"
|
||||
*/
|
||||
private String formatDateOnly(String dateTimeStr) {
|
||||
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
try {
|
||||
// 如果包含 'T',说明是 ISO 格式(2025-04-02T09:41:13)
|
||||
if (dateTimeStr.contains("T")) {
|
||||
// 直接截取 'T' 之前的部分
|
||||
return dateTimeStr.substring(0, dateTimeStr.indexOf("T"));
|
||||
}
|
||||
// 如果包含空格,说明是标准格式(2025-04-02 09:41:13)
|
||||
else if (dateTimeStr.contains(" ")) {
|
||||
// 直接截取空格之前的部分
|
||||
return dateTimeStr.substring(0, dateTimeStr.indexOf(" "));
|
||||
}
|
||||
// 如果已经是日期格式(2025-04-02),直接返回
|
||||
else {
|
||||
return dateTimeStr;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 如果格式化失败,返回原字符串
|
||||
return dateTimeStr;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectLeaseCostDetail> queryProjectLeaseDetails(ProjectLeaseCostDetail o) {
|
||||
return projectCostDao.queryProjectLeaseDetails(o);
|
||||
|
|
@ -347,28 +380,34 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
if (currentCount > 0 && !previousTime.equals(operateTime)) {
|
||||
// 计算两个时间点之间的天数
|
||||
long daysBetween = java.time.Duration.between(previousTime, operateTime).toDays();
|
||||
// 不足一天按一天计算
|
||||
if (daysBetween < 1) {
|
||||
daysBetween = 1;
|
||||
|
||||
// 如果天数为0(开始时间等于结束时间),跳过这个时间段
|
||||
if (daysBetween == 0) {
|
||||
System.out.println("跳过无效时间段: " + previousTime + " 至 " + operateTime + " (开始时间等于结束时间)");
|
||||
} else {
|
||||
// 不足一天按一天计算
|
||||
if (daysBetween < 1) {
|
||||
daysBetween = 1;
|
||||
}
|
||||
|
||||
// 计算该时间段的租赁费用
|
||||
double segmentAmount = currentCount * unitPrice * daysBetween;
|
||||
totalItemAmount += segmentAmount;
|
||||
|
||||
// 记录该时间段
|
||||
Map<String, Object> segment = new HashMap<>();
|
||||
segment.put("startTime", previousTime.toString());
|
||||
segment.put("endTime", operateTime.toString());
|
||||
segment.put("days", daysBetween);
|
||||
segment.put("count", currentCount);
|
||||
segment.put("amount", segmentAmount);
|
||||
segments.add(segment);
|
||||
|
||||
// 添加调试信息
|
||||
System.out.println("物资ID: " + machineTypeId + ", 时段: " + previousTime + " 至 " + operateTime
|
||||
+ ", 天数: " + daysBetween + ", 数量: " + currentCount + ", 单价: " + unitPrice + ", 段金额: "
|
||||
+ segmentAmount);
|
||||
}
|
||||
|
||||
// 计算该时间段的租赁费用
|
||||
double segmentAmount = currentCount * unitPrice * daysBetween;
|
||||
totalItemAmount += segmentAmount;
|
||||
|
||||
// 记录该时间段
|
||||
Map<String, Object> segment = new HashMap<>();
|
||||
segment.put("startTime", previousTime.toString());
|
||||
segment.put("endTime", operateTime.toString());
|
||||
segment.put("days", daysBetween);
|
||||
segment.put("count", currentCount);
|
||||
segment.put("amount", segmentAmount);
|
||||
segments.add(segment);
|
||||
|
||||
// 添加调试信息
|
||||
System.out.println("物资ID: " + machineTypeId + ", 时段: " + previousTime + " 至 " + operateTime
|
||||
+ ", 天数: " + daysBetween + ", 数量: " + currentCount + ", 单价: " + unitPrice + ", 段金额: "
|
||||
+ segmentAmount);
|
||||
}
|
||||
|
||||
// 更新当前在用数量
|
||||
|
|
@ -399,27 +438,33 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
if (currentCount > 0 && !previousTime.equals(endDate)) {
|
||||
// 计算两个时间点之间的天数
|
||||
long daysBetween = java.time.Duration.between(previousTime, endDate).toDays();
|
||||
// 不足一天按一天计算
|
||||
if (daysBetween < 1) {
|
||||
daysBetween = 1;
|
||||
|
||||
// 如果天数为0(开始时间等于结束时间),跳过这个时间段
|
||||
if (daysBetween == 0) {
|
||||
System.out.println("跳过无效时间段: " + previousTime + " 至 " + endDate + " (开始时间等于结束时间)");
|
||||
} else {
|
||||
// 不足一天按一天计算
|
||||
if (daysBetween < 1) {
|
||||
daysBetween = 1;
|
||||
}
|
||||
|
||||
// 计算该时间段的租赁费用
|
||||
double segmentAmount = currentCount * unitPrice * daysBetween;
|
||||
totalItemAmount += segmentAmount;
|
||||
|
||||
// 记录该时间段
|
||||
Map<String, Object> segment = new HashMap<>();
|
||||
segment.put("startTime", previousTime.toString());
|
||||
segment.put("endTime", endDate.toString());
|
||||
segment.put("days", daysBetween);
|
||||
segment.put("count", currentCount);
|
||||
segment.put("amount", segmentAmount);
|
||||
segments.add(segment);
|
||||
|
||||
// 添加调试信息
|
||||
System.out.println("物资ID: " + machineTypeId + ", 时段: " + previousTime + " 至 " + endDate + ", 天数: "
|
||||
+ daysBetween + ", 数量: " + currentCount + ", 单价: " + unitPrice + ", 段金额: " + segmentAmount);
|
||||
}
|
||||
|
||||
// 计算该时间段的租赁费用
|
||||
double segmentAmount = currentCount * unitPrice * daysBetween;
|
||||
totalItemAmount += segmentAmount;
|
||||
|
||||
// 记录该时间段
|
||||
Map<String, Object> segment = new HashMap<>();
|
||||
segment.put("startTime", previousTime.toString());
|
||||
segment.put("endTime", endDate.toString());
|
||||
segment.put("days", daysBetween);
|
||||
segment.put("count", currentCount);
|
||||
segment.put("amount", segmentAmount);
|
||||
segments.add(segment);
|
||||
|
||||
// 添加调试信息
|
||||
System.out.println("物资ID: " + machineTypeId + ", 时段: " + previousTime + " 至 " + endDate + ", 天数: "
|
||||
+ daysBetween + ", 数量: " + currentCount + ", 单价: " + unitPrice + ", 段金额: " + segmentAmount);
|
||||
}
|
||||
|
||||
// 更新总金额
|
||||
|
|
@ -913,16 +958,16 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
String fileName = "物资区间费用表_" + calculation.getProjectName() + "_" + calculation.getId() + ".xls";
|
||||
String sheetName = "物资区间费用表";
|
||||
|
||||
// 表头 - 增加工程名称、规格型号、故障停用天数、扣减费用字段
|
||||
String[] headers = { "序号", "工程名称", "物资类型", "规格型号", "起始时间", "截止时间", "租赁天数(天)", "数量", "金额(元)", "因故障造成的停用天数",
|
||||
// 表头 - 增加工程名称、规格型号、每日单价、故障停用天数、扣减费用字段
|
||||
String[] headers = { "序号", "工程名称", "物资类型", "规格型号", "起始时间", "截止时间", "租赁天数(天)", "数量", "每日单价(元/天)", "金额(元)", "因故障造成的停用天数",
|
||||
"扣减费用(元)" };
|
||||
// 列宽 - 调整并新增字段宽度
|
||||
int[] widths = { 256 * 6, 256 * 60, 256 * 20, 256 * 16, 256 * 22, 256 * 22, 256 * 16, 256 * 10, 256 * 12,
|
||||
int[] widths = { 256 * 6, 256 * 60, 256 * 20, 256 * 16, 256 * 22, 256 * 22, 256 * 16, 256 * 10, 256 * 14, 256 * 12,
|
||||
256 * 22, 256 * 16 };
|
||||
|
||||
// 数据格式(1:String left; 2:String center; 3:String right; 4:int right; 5:float
|
||||
// right)
|
||||
int[] formats = { 4, 2, 2, 2, 2, 2, 4, 4, 5, 4, 5 };
|
||||
int[] formats = { 4, 2, 2, 2, 2, 2, 4, 4, 5, 5, 4, 5 };
|
||||
|
||||
// 准备数据
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
|
|
@ -939,10 +984,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
row.put("工程名称", calculation.getProjectName()); // 添加工程名称字段
|
||||
row.put("物资类型", detail.getMachineTypeName());
|
||||
row.put("规格型号", detail.getMachineModel()); // 添加规格型号字段
|
||||
row.put("起始时间", segment.getStartTime());
|
||||
row.put("截止时间", segment.getEndTime());
|
||||
// 格式化时间,只保留年月日
|
||||
row.put("起始时间", formatDateOnly(segment.getStartTime()));
|
||||
row.put("截止时间", formatDateOnly(segment.getEndTime()));
|
||||
row.put("租赁天数(天)", segment.getDays());
|
||||
row.put("数量", segment.getCount());
|
||||
row.put("每日单价(元/天)", detail.getPrice()); // 添加每日单价字段
|
||||
row.put("金额(元)", segment.getAmount());
|
||||
row.put("因故障造成的停用天数", 0); // 默认为0天
|
||||
row.put("扣减费用(元)", 0.00); // 默认为0.00元
|
||||
|
|
@ -952,24 +999,27 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
}
|
||||
}
|
||||
|
||||
// 调用带签名区域的导出方法
|
||||
exportSegmentExcelWithSignature(fileName, sheetName, headers, widths, formats, dataList, response);
|
||||
// 调用带签名区域的导出方法,传递工程名称和制单时间
|
||||
exportSegmentExcelWithSignature(fileName, sheetName, headers, widths, formats, dataList,
|
||||
calculation.getProjectName(), calculation.getCreateTime(), response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装导出带签名区域的Excel方法,专用于物资区间费用表
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @param sheetName sheet名称
|
||||
* @param headers 表头
|
||||
* @param widths 列宽
|
||||
* @param formats 数据格式
|
||||
* @param dataList 数据列表
|
||||
* @param response HttpServletResponse对象
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @param sheetName sheet名称
|
||||
* @param headers 表头
|
||||
* @param widths 列宽
|
||||
* @param formats 数据格式
|
||||
* @param dataList 数据列表
|
||||
* @param projectName 工程名称
|
||||
* @param createTime 制单时间
|
||||
* @param response HttpServletResponse对象
|
||||
* @throws Exception 导出异常
|
||||
*/
|
||||
private void exportSegmentExcelWithSignature(String fileName, String sheetName, String[] headers, int[] widths, int[] formats,
|
||||
List<Map<String, Object>> dataList, javax.servlet.http.HttpServletResponse response) throws Exception {
|
||||
List<Map<String, Object>> dataList, String projectName, String createTime, javax.servlet.http.HttpServletResponse response) throws Exception {
|
||||
try {
|
||||
// 设置文件名
|
||||
String filename = "";
|
||||
|
|
@ -989,8 +1039,90 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
// 创建一个sheet
|
||||
HSSFSheet sheet = wb.createSheet(sheetName);
|
||||
|
||||
// 创建表头
|
||||
int currentRowIndex = 0;
|
||||
|
||||
// 创建第一行标题:贵州送变电智联装备云控公司(设备及工器具)产值明细确认单
|
||||
HSSFRow titleRow = sheet.createRow(currentRowIndex);
|
||||
titleRow.setHeight((short) 600); // 设置标题行高度
|
||||
|
||||
// 标题样式
|
||||
HSSFCellStyle titleStyle = wb.createCellStyle();
|
||||
HSSFFont titleFont = wb.createFont();
|
||||
titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
|
||||
titleFont.setFontName("微软雅黑");
|
||||
titleFont.setFontHeightInPoints((short) 14); // 标题字体稍大
|
||||
titleStyle.setFont(titleFont);
|
||||
titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中
|
||||
titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
|
||||
|
||||
// 创建第一个单元格并设置标题内容
|
||||
HSSFCell titleCell = titleRow.createCell(0);
|
||||
titleCell.setCellValue("贵州送变电智联装备云控公司(设备及工器具)产值明细确认单");
|
||||
titleCell.setCellStyle(titleStyle);
|
||||
|
||||
// 合并单元格:从第0列到最后一列(headers.length - 1)
|
||||
if (headers != null && headers.length > 1) {
|
||||
org.apache.poi.ss.util.CellRangeAddress titleRegion = new org.apache.poi.ss.util.CellRangeAddress(
|
||||
currentRowIndex, // 起始行
|
||||
currentRowIndex, // 结束行
|
||||
0, // 起始列
|
||||
headers.length - 1 // 结束列
|
||||
);
|
||||
sheet.addMergedRegion(titleRegion);
|
||||
}
|
||||
currentRowIndex++;
|
||||
|
||||
// 创建第二行:工程名称和制单时间
|
||||
HSSFRow infoRow = sheet.createRow(currentRowIndex);
|
||||
infoRow.setHeight((short) 400); // 设置信息行高度
|
||||
|
||||
// 信息行样式
|
||||
HSSFCellStyle infoStyle = wb.createCellStyle();
|
||||
HSSFFont infoFont = wb.createFont();
|
||||
infoFont.setFontName("微软雅黑");
|
||||
infoFont.setFontHeightInPoints((short) 11);
|
||||
infoStyle.setFont(infoFont);
|
||||
infoStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
|
||||
|
||||
// 计算中间列位置(用于分隔左右两列)
|
||||
int midColumn = headers.length / 2;
|
||||
|
||||
// 左侧列:工程名称
|
||||
HSSFCell projectNameCell = infoRow.createCell(0);
|
||||
projectNameCell.setCellValue("工程名称:" + projectName);
|
||||
projectNameCell.setCellStyle(infoStyle);
|
||||
|
||||
// 合并左侧单元格(从第0列到中间列-1)
|
||||
if (midColumn > 1) {
|
||||
org.apache.poi.ss.util.CellRangeAddress leftRegion = new org.apache.poi.ss.util.CellRangeAddress(
|
||||
currentRowIndex, // 起始行
|
||||
currentRowIndex, // 结束行
|
||||
0, // 起始列
|
||||
midColumn - 1 // 结束列
|
||||
);
|
||||
sheet.addMergedRegion(leftRegion);
|
||||
}
|
||||
|
||||
// 右侧列:制单时间
|
||||
HSSFCell createTimeCell = infoRow.createCell(midColumn);
|
||||
// 格式化制单时间,只保留年月日
|
||||
String formattedCreateTime = formatDateOnly(createTime);
|
||||
createTimeCell.setCellValue("制单时间:" + formattedCreateTime);
|
||||
createTimeCell.setCellStyle(infoStyle);
|
||||
|
||||
// 合并右侧单元格(从中间列到最后一列)
|
||||
if (midColumn < headers.length - 1) {
|
||||
org.apache.poi.ss.util.CellRangeAddress rightRegion = new org.apache.poi.ss.util.CellRangeAddress(
|
||||
currentRowIndex, // 起始行
|
||||
currentRowIndex, // 结束行
|
||||
midColumn, // 起始列
|
||||
headers.length - 1 // 结束列
|
||||
);
|
||||
sheet.addMergedRegion(rightRegion);
|
||||
}
|
||||
currentRowIndex++;
|
||||
|
||||
// 创建表头
|
||||
if (headers != null) {
|
||||
HSSFRow row = sheet.createRow(currentRowIndex);
|
||||
// 设置表头行高 - 调高表头高度
|
||||
|
|
|
|||
Loading…
Reference in New Issue