Merge remote-tracking branch 'origin/main'

This commit is contained in:
jiang 2025-07-15 17:54:02 +08:00
commit 3e8403de35
9 changed files with 359 additions and 29 deletions

View File

@ -1,7 +1,11 @@
package com.bonus.gzcar.business.backstage.controller;
import cn.afterturn.easypoi.cache.manager.IFileLoader;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.bonus.gzcar.business.backstage.entity.*;
import com.bonus.gzcar.business.backstage.mapper.SupDispatchCarMapper;
import com.bonus.gzcar.business.backstage.service.DispatchCarService;
import com.bonus.gzcar.business.backstage.service.SupDispatchCarService;
import com.bonus.gzcar.business.utils.ExportExcelUtil;
@ -15,16 +19,20 @@ import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
/**
* @author 黑子
@ -40,6 +48,9 @@ public class SupDispatchCarController {
@Autowired
private SupDispatchCarService service;
@Autowired
private SupDispatchCarMapper mapper;
/**
* 查询 已分配的供应商 数据信息
* @param dto
@ -184,29 +195,274 @@ public class SupDispatchCarController {
* @param response
* @param dto
*/
// @PostMapping("expOutPageList")
// public void expOutPageList(HttpServletResponse response, @RequestBody CarNeedPlanVo dto) {
// try {
// List<CarNeedPlanVo> list = service.getOutPageList(dto);
// List<CarNeedPlanExport1Vo> exportList=new ArrayList<>();
// final int[] num = {1};
// list.forEach(vo->{
// CarNeedPlanExport1Vo exp=new CarNeedPlanExport1Vo();
// BeanUtils.copyProperties(vo,exp);
//
// if(ListHelpUtil.isNotEmpty(exp.getFileList())){
// exp.setFileNum("已上传");
// }else{
// exp.setFileNum("待上传");
// }
// exp.setStatusName("已派车");
// exp.setXh(num[0]);
// num[0]++;
// exportList.add(exp);
// });
// ExportExcelUtil.export(response,"到货期确认单", CarNeedPlanExport1Vo.class,exportList);
// } catch (Exception e) {
// log.error(e.toString(), e);
// }
// }
@PostMapping("expOutPageList")
public void expOutPageList(HttpServletResponse response, @RequestBody CarNeedPlanVo dto) {
try {
List<CarNeedPlanVo> list = service.getOutPageList(dto);
List<CarNeedPlanExport1Vo> exportList=new ArrayList<>();
final int[] num = {1};
list.forEach(vo->{
CarNeedPlanExport1Vo exp=new CarNeedPlanExport1Vo();
BeanUtils.copyProperties(vo,exp);
List<CarNeedPlanExport1Vo> exportList = new ArrayList<>();
if(ListHelpUtil.isNotEmpty(exp.getFileList())){
exp.setFileNum("已上传");
}else{
exp.setFileNum("待上传");
}
// 用于存储合并单元格的区域
List<CellRangeAddress> mergeRegions = new ArrayList<>();
int currentRow = 1; // 从第1行开始第0行是标题行
for (int i = 0; i < list.size(); i++) {
CarNeedPlanVo vo = list.get(i);
CarNeedPlanExport1Vo exp = new CarNeedPlanExport1Vo();
BeanUtils.copyProperties(vo, exp);
// 设置文件状态和派车状态
exp.setFileNum(ListHelpUtil.isNotEmpty(exp.getFileList()) ? "已上传" : "待上传");
exp.setStatusName("已派车");
exp.setXh(num[0]);
num[0]++;
exp.setXh(i + 1);
// 获取详情数据
CarPlanOutVo bean1 = new CarPlanOutVo();
bean1.setId(exp.getId());
List<CarPlanOutVoDetailsVo> details = mapper.getListDetails(bean1);
int detailCount = details != null ? Math.max(details.size(), 1) : 1;
// 处理详情数据无论数量多少都处理
if (details != null && !details.isEmpty()) {
// 第一条详情数据设置到主数据对象中
CarPlanOutVoDetailsVo firstDetail = details.get(0);
exp.setCarType(firstDetail.getType());
exp.setStartAddress(firstDetail.getStartAddress());
exp.setEndAddress(firstDetail.getEndAddress());
exp.setUseAddress(firstDetail.getUseAddress());
exp.setName(firstDetail.getName());
exp.setModel(firstDetail.getModel());
exp.setCarNumStr(firstDetail.getCarNum());
}
// 添加主数据行总是包含第一条详情数据
exportList.add(exp);
});
ExportExcelUtil.export(response,"到货期确认单", CarNeedPlanExport1Vo.class,exportList);
// 添加剩余详情数据行如果有
for (int j = 1; j < detailCount; j++) {
CarNeedPlanExport1Vo detailRow = new CarNeedPlanExport1Vo();
if (j < details.size()) {
CarPlanOutVoDetailsVo detail = details.get(j);
detailRow.setCarType(detail.getType());
detailRow.setStartAddress(detail.getStartAddress());
detailRow.setEndAddress(detail.getEndAddress());
detailRow.setUseAddress(detail.getUseAddress());
detailRow.setName(detail.getName());
detailRow.setModel(detail.getModel());
detailRow.setCarNumStr(detail.getCarNum());
}
exportList.add(detailRow);
}
// 只有当detailCount > 1时才需要合并
if (detailCount > 1) {
// 合并主数据列前10列
for (int col = 0; col < 10; col++) {
mergeRegions.add(new CellRangeAddress(
currentRow,
currentRow + detailCount - 1,
col,
col
));
}
}
currentRow += detailCount;
}
// 自定义导出
customExportWithDetails(response, "到货期确认单", exportList, mergeRegions);
} catch (Exception e) {
log.error(e.toString(), e);
log.error("导出Excel失败", e);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
try {
response.getWriter().write("导出Excel失败: " + e.getMessage());
} catch (IOException ex) {
log.error("写入错误响应失败", ex);
}
}
}
private void customExportWithDetails(HttpServletResponse response, String sheetName,
List<CarNeedPlanExport1Vo> dataList,
List<CellRangeAddress> mergeRegions) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet(sheetName);
// 创建样式
CellStyle headerStyle = createHeaderStyle(workbook); // 标题样式
CellStyle dataStyle = createDataStyle(workbook); // 数据样式
CellStyle wrapTextStyle = createWrapTextStyle(workbook); // 自动换行样式
// 设置列宽可根据实际情况调整
int[] columnWidths = {8, 15, 15, 10, 15, 20, 10, 10, 15, 15, 15, 15, 15, 10, 10, 10, 10};
for (int i = 0; i < columnWidths.length; i++) {
sheet.setColumnWidth(i, columnWidths[i] * 256); // 256是一个字符的宽度单位
}
// 创建标题行
Row titleRow = sheet.createRow(0);
String[] titles = {"序号", "工程", "计划编号", "申请人", "申请时间", "备注", "派车状态", "派车数量", "派车日期", "到货确认单",
"类型","起运地", "目的地", "使用地", "车型", "型号", "车牌"};
for (int i = 0; i < titles.length; i++) {
Cell cell = titleRow.createCell(i);
cell.setCellValue(titles[i]);
cell.setCellStyle(headerStyle);
}
// 填充数据
int rowNum = 1;
for (CarNeedPlanExport1Vo data : dataList) {
Row row = sheet.createRow(rowNum++);
// 主数据前10列
setCellValueWithStyle(row, 0, data.getXh(),dataStyle);
setCellValueWithStyle(row, 1, data.getProName(), wrapTextStyle);
setCellValueWithStyle(row, 2, data.getCode(), dataStyle);
setCellValueWithStyle(row, 3, data.getUserName(), dataStyle);
setCellValueWithStyle(row, 4, data.getAppLyTime(), dataStyle);
setCellValueWithStyle(row, 5, data.getRemark(), wrapTextStyle);
setCellValueWithStyle(row, 6, data.getStatusName(), dataStyle);
setCellValueWithStyle(row, 7, data.getDispatchNum(), dataStyle);
setCellValueWithStyle(row, 8, data.getOutTime(), dataStyle);
setCellValueWithStyle(row, 9, data.getFileNum(), dataStyle);
// 详情数据后6列
setCellValueWithStyle(row, 10, data.getCarType(), dataStyle);
setCellValueWithStyle(row, 11, data.getStartAddress(), dataStyle);
setCellValueWithStyle(row, 12, data.getEndAddress(), dataStyle);
setCellValueWithStyle(row, 13, data.getUseAddress(), dataStyle);
setCellValueWithStyle(row, 14, data.getName(), dataStyle);
setCellValueWithStyle(row, 15, data.getModel(), dataStyle);
setCellValueWithStyle(row, 16, data.getCarNumStr(), dataStyle);
}
// 添加合并区域
for (CellRangeAddress region : mergeRegions) {
if (region.getFirstRow() != region.getLastRow() ||
region.getFirstColumn() != region.getLastColumn()) {
sheet.addMergedRegion(region);
// 为合并区域设置样式
setMergedRegionStyle(sheet, region, dataStyle);
}
}
// 输出Excel
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(sheetName + ".xlsx", "UTF-8"));
try (ServletOutputStream out = response.getOutputStream()) {
workbook.write(out);
} finally {
workbook.close();
}
}
// 创建标题样式加粗居中带边框
private CellStyle createHeaderStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true); // 加粗
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER); // 水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
// 设置边框
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
return style;
}
// 创建数据样式带边框
private CellStyle createDataStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
return style;
}
// 创建自动换行样式
private CellStyle createWrapTextStyle(Workbook workbook) {
CellStyle style = createDataStyle(workbook);
style.setWrapText(true); // 自动换行
return style;
}
// 设置单元格值并应用样式
private void setCellValueWithStyle(Row row, int column, Object value, CellStyle style) {
if (row == null) return;
Cell cell = row.createCell(column);
cell.setCellStyle(style);
if (value == null) {
cell.setCellValue("");
return;
}
if (value instanceof Number) {
cell.setCellValue(((Number) value).doubleValue());
} else if (value instanceof Date) {
cell.setCellValue((Date) value);
// 设置日期格式
CellStyle dateStyle = row.getSheet().getWorkbook().createCellStyle();
dateStyle.cloneStyleFrom(style);
dateStyle.setDataFormat(row.getSheet().getWorkbook().createDataFormat().getFormat("yyyy-MM-dd"));
cell.setCellStyle(dateStyle);
} else if (value instanceof Boolean) {
cell.setCellValue((Boolean) value);
} else {
cell.setCellValue(value.toString());
// 如果文本长度超过50个字符使用自动换行样式
if (value.toString().length() > 50) {
CellStyle wrapStyle = row.getSheet().getWorkbook().createCellStyle();
wrapStyle.cloneStyleFrom(style);
wrapStyle.setWrapText(true);
cell.setCellStyle(wrapStyle);
}
}
}
// 为合并区域设置样式
private void setMergedRegionStyle(Sheet sheet, CellRangeAddress region, CellStyle style) {
for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
Row row = sheet.getRow(i) == null ? sheet.createRow(i) : sheet.getRow(i);
for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
Cell cell = row.getCell(j) == null ? row.createCell(j) : row.getCell(j);
cell.setCellStyle(style);
}
}
}

View File

@ -72,4 +72,9 @@ public class CarDriverVo extends ParentVo {
*/
private int num;
/**
* 是否派车
*/
private String isDispatch;
}

View File

@ -78,7 +78,7 @@ public class CarNeedPlanExport1Vo extends ParentVo {
/**
* 备注
*/
@Excel(name = "申请时间", width = 10.0, orderNum = "4")
@Excel(name = "备注", width = 10.0, orderNum = "4")
private String remark;
/**
* 计划类型 0 正常 1紧急
@ -158,6 +158,28 @@ public class CarNeedPlanExport1Vo extends ParentVo {
@Excel(name = "到货确认单", width = 10.0, orderNum = "7")
private String fileNum;
/**
* 起运地:
* */
private String startAddress;
/**
* 目的地
*/
private String endAddress;
/**
* 使用地
*/
private String useAddress;
/**
* 车辆类型
*/
private String carType;
/**
* 车辆类型
*/
private String carNumStr;
}

View File

@ -186,5 +186,9 @@ public class CarNeedPlanVo extends ParentVo {
private String outId;
/**
* 车牌
*/
private String licensePlate;
}

View File

@ -191,4 +191,11 @@ public interface SupDispatchCarMapper {
* @return
*/
int delAuditRecord(CarPlanOutVo outVo);
/**
* 查询car_plan_out_details数据
* @param bean1
* @return
*/
List<CarPlanOutVoDetailsVo> getListDetails(CarPlanOutVo bean1);
}

View File

@ -10,6 +10,7 @@ import com.bonus.gzcar.business.system.entity.FileUploadVo;
import com.bonus.gzcar.business.system.service.FileUploadService;
import com.bonus.gzcar.manager.advice.ValidatorsUtils;
import com.bonus.gzcar.manager.annotation.DecryptAndVerify;
import com.bonus.gzcar.manager.common.util.DateTimeHelper;
import com.bonus.gzcar.manager.common.util.StringHelper;
import com.bonus.gzcar.manager.common.util.UserUtil;
import com.bonus.gzcar.manager.core.entity.EncryptedReq;
@ -345,6 +346,7 @@ public class CarDriverServiceImpl implements CarDriverService{
public List<CarDriverVo> getDriverListBySup(CarDriverVo data) {
List<CarDriverVo> list=new ArrayList<>();
try {
data.setCreateTime(DateTimeHelper.getNowDay());
list=mapper.getDriverListBySup(data);
}catch (Exception e){
log.error(e.toString());

View File

@ -14,7 +14,7 @@ public class ParentVo {
* 序号
*/
@Excel(name = "序号", width = 10.0, orderNum = "0")
private int xh;
private Integer xh;
/**
* 创建人

View File

@ -18,6 +18,11 @@
</update>
<select id="getDriverPageList" resultType="com.bonus.gzcar.business.backstage.entity.CarDriverVo">
SELECT
a.*,
COUNT( DISTINCT cpod.apply_id ) AS num
FROM
(
select cdi.id, cdi.name, cdi.phone, cdi.sup_id supId,file1.num sfzNum,file2.num jszNum,file3.num
otherNum,cs.name supName,cdi.is_white as isWhiteList
from car_driver_info cdi
@ -45,6 +50,10 @@
and cs.name like concat('%',#{supName},'%')
</if>
ORDER BY cdi.create_time desc
) a
LEFT JOIN car_plan_out_details cpod ON cpod.driver_id = a.id
GROUP BY
a.id
</select>
<select id="getDriverPageWhiteList" resultType="com.bonus.gzcar.business.backstage.entity.CarDriverVo">
SELECT
@ -90,9 +99,11 @@
where cdi.id=#{id}
</select>
<select id="getDriverListBySup" resultType="com.bonus.gzcar.business.backstage.entity.CarDriverVo">
select cdi.id,cdi.name,cdi.phone,cdi.sup_id supId ,cs.name supName,cdi.is_white as isWhiteList
select cdi.id,cdi.name,cdi.phone,cdi.sup_id supId ,cs.name supName,cdi.is_white as isWhiteList,
cpod.id as isDispatch
FROM car_driver_info cdi
left join car_supplier cs on cs.id=cdi.sup_id
LEFT JOIN car_plan_out_details cpod on cpod.driver_id=cdi.id and LEFT(cpod.create_time,10)=#{createTime}
where cdi.is_active=1
<if test="supId!=null and supId!=''">
and cdi.sup_id=#{supId}
@ -109,9 +120,6 @@
<select id="getRePlan" resultType="com.bonus.gzcar.business.backstage.entity.CarNeedPlanVo">
SELECT cpa.id,
cpa.`code`,
bp.ID as proId,
bp.`NAME` as proName,
CASE
cpa.type
WHEN 1 THEN
@ -120,14 +128,24 @@
'吊车'
ELSE ''
END typeName,
cpa.`code`,
bp.ID AS proId,
bp.`NAME` AS proName,
cpa.user_name userName,
DATE_FORMAT(cpa.create_time, '%Y-%m-%d') appLyTime,
cpa.remark
FROM (SELECT cpod.apply_id AS applyId
a.createTime as outTime,
a.carNum AS licensePlate,
CONCAT(cmt2.`name`, '-', cmt.`name`) AS model
FROM (SELECT cpod.apply_id AS applyId,
cpod.create_time AS createTime,
car_num AS carNum,
model_id
FROM car_plan_out_details cpod
WHERE cpod.driver_id = #{id}
GROUP BY cpod.apply_id) a
LEFT JOIN car_plan_apply cpa ON cpa.id = a.applyId
LEFT JOIN bm_project bp on bp.ID = cpa.pro_id
LEFT JOIN bm_project bp ON bp.ID = cpa.pro_id
LEFT JOIN car_ma_type cmt ON cmt.id = a.model_id
LEFT JOIN car_ma_type cmt2 ON cmt2.id = cmt.parent_id
</select>
</mapper>

View File

@ -26,11 +26,11 @@
out_id,apply_id,model_id,plan_type,contract_id,sup_id,car_id,goods_name,
gls,start_address,end_address,price_id, gls_price,gls_money,use_address,
use_day,driver_id, czy_id,day_price,month_price,jc_gls,jc_price,dc_money,
dc_unit,es_cost,car_out_id,day_or_m,remark,car_num
dc_unit,es_cost,car_out_id,day_or_m,remark,car_num,create_time
)values (#{outId},#{planId},#{modelId},#{planType},#{contractId},#{supId},#{carId},#{goodsName},
#{gls},#{startAddress},#{endAddress},#{priceId},#{glsPrice},#{glsMoney},#{useAddress},
#{planDay},#{driverUserId},#{operaUserId},#{dayPrice},#{monthPrice},#{jcGls},#{jcMoney},#{dcMoney},#{dcUnit}
,#{cost},#{carOutId},#{isDayOrMonth},#{remark},#{carNum})
,#{cost},#{carOutId},#{isDayOrMonth},#{remark},#{carNum},NOW())
</insert>
<insert id="addDispatchCarDetailsDataRecord" keyProperty="detailsId" useGeneratedKeys="true">
insert into car_plan_out_details_record(
@ -322,5 +322,21 @@
and cpo.sup_id = #{supId}
and (cpo.status = 0 or cpo.status = 1)
</select>
<select id="getListDetails" resultType="com.bonus.gzcar.business.backstage.entity.CarPlanOutVoDetailsVo">
SELECT
cpod.id,
cmti.type,
cmti.NAME,
cmti.model,
cpod.car_num carNum,
cpod.start_address startAddress,
cpod.end_address endAddress,
cpod.use_address useAddress
FROM
car_plan_out_details cpod
LEFT JOIN car_ma_type_info cmti ON cmti.id = cpod.model_id
WHERE
cpod.out_id = #{id}
</select>
</mapper>