问题修改

This commit is contained in:
jiang 2025-10-27 15:14:42 +08:00
parent 010b0950ac
commit 199b2ef82d
9 changed files with 249 additions and 14 deletions

View File

@ -1,11 +1,19 @@
package com.bonus.material.devchange.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.contract.domain.BmContract;
import com.bonus.material.devchange.domain.*;
import com.bonus.material.devchange.service.MaDevInfoService;
import com.bonus.material.devchange.service.MaDevInfoServiceImpl;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.device.domain.vo.DevMergeVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
@ -13,8 +21,17 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 设备台账-总览表
@ -44,6 +61,7 @@ public class MaDevInfoController extends BaseController {
}
}
@ApiOperation(value = "设备台账-上下架")
@PostMapping("/updateDeviceStatus")
public AjaxResult updateDeviceStatus(@RequestBody DevMergeVo o) {
@ -143,4 +161,218 @@ public class MaDevInfoController extends BaseController {
}
/**
* 导出设备信息为Excel
*
* @param o 查询条件同列表接口
* @param response 响应对象
*/
@ApiOperation("导出设备信息Excel")
@PostMapping("/export")
public void export(MaDevInfo o, HttpServletResponse response) throws IOException {
// 1. 查询所有符合条件的数据忽略分页
List<MaDevInfo> dataList = service.list(o);
// 2. 转换数据为导出格式处理特殊字段
List<Map<String, Object>> exportData = dataList.stream()
.map(this::convertToExportMap)
.collect(Collectors.toList());
// 生成Excel时 headerMap 的顺序添加表头
ExcelWriter writer = ExcelUtil.getWriter();
Map<String, String> headerMap = getExportHeaderMap();
// headerMap 的顺序添加别名LinkedHashMap保证顺序
headerMap.forEach((prop, label) -> writer.addHeaderAlias(prop, label));
// 显式设置导出的字段顺序与表头一致
writer.setOnlyAlias(true); // 只导出有别名的字段
writer.write(exportData, true);
// 5. 设置响应头触发下载
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
String fileName = URLEncoder.encode("设备信息表_" + System.currentTimeMillis(), "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
// 6. 输出流写入
try (ServletOutputStream out = response.getOutputStream()) {
writer.flush(out, true);
} finally {
writer.close();
}
}
/**
* 转换设备信息为导出Map处理特殊字段
*/
private Map<String, Object> convertToExportMap(MaDevInfo item) {
Set<String> headerProps = getExportHeaderMap().keySet();
// 使用 LinkedHashMap 保持顺序
Map<String, Object> map = new LinkedHashMap<>();
// 1. 先添加表头中定义的字段确保顺序与表头一致
for (String prop : headerProps) {
// 从对象中获取字段值忽略不存在的字段
Object value = BeanUtil.getProperty(item, prop);
map.put(prop, value);
}
map.put("process", item.getMainProcess() + ">" + item.getSubProcess());
map.put("devType", item.getMainCategory() + ">" + item.getSubCategory() + ">" + item.getBranch());
Object productionDate = item.getProductionDate();
if (productionDate != null) {
map.put("productionDate", formatDateToYmd(productionDate));
}
// 格式化采购日期purchaseDate只保留年月日
Object purchaseDate = item.getPurchaseDate();
if (purchaseDate != null) {
map.put("purchaseDate", formatDateToYmd(purchaseDate));
}
// 格式化采购日期purchaseDate只保留年月日
Object nextMaintenanceDate = item.getNextMaintenanceDate();
if (purchaseDate != null) {
map.put("nextMaintenanceDate", formatDateToYmd(nextMaintenanceDate));
}
// 格式化采购日期purchaseDate只保留年月日
Object expirationTime = item.getExpirationTime();
if (purchaseDate != null) {
map.put("expirationTime", formatDateToYmd(expirationTime));
}
map.put("status", convertStatusToText(Integer.valueOf(item.getStatus())));
map.put("upDownStatus", convertUpDownStatusToText(Integer.valueOf(item.getUpDownStatus())));
List<DevInfoPropertyVo> propertyVoList = item.getPropertyVoList();
if (CollUtil.isNotEmpty(propertyVoList)) {
for (int i = 0; i < propertyVoList.size() && i < 9; i++) {
DevInfoPropertyVo property = propertyVoList.get(i);
int index = i + 1;
map.put("featureItem" + index, property.getPropertyName());
map.put("featureValue" + index, property.getPropertyValue());
}
}
for (int i = 1; i <= 9; i++) {
map.putIfAbsent("featureItem" + i, "");
map.putIfAbsent("featureValue" + i, "");
}
// 4. 最终过滤确保只保留表头中的字段防止处理过程中新增多余字段
map.keySet().retainAll(headerProps);
return map;
}
/**
* 工具方法将时间对象格式化为 "yyyy-MM-dd"兼容Date和LocalDate
*/
private String formatDateToYmd(Object dateObj) {
if (dateObj == null) {
return "";
}
// 处理java.util.Date类型
if (dateObj instanceof Date) {
return DateUtil.format((Date) dateObj, "yyyy-MM-dd");
}
// 处理java.time.LocalDate类型
if (dateObj instanceof LocalDate) {
return ((LocalDate) dateObj).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
// 处理java.time.LocalDateTime类型截取日期部分
if (dateObj instanceof LocalDateTime) {
return ((LocalDateTime) dateObj).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
// 其他类型直接返回字符串避免转换失败
return dateObj.toString();
}
/**
* 导出表头映射prop -> label- 兼容 Java 8
*/
private Map<String, String> getExportHeaderMap() {
Map<String, String> headerMap = new LinkedHashMap<>();
// 1. 基础字段映射已有部分保持不变
headerMap.put("province", "所属省份");
headerMap.put("propertyUnit", "产权单位");
headerMap.put("major", "专业");
headerMap.put("process", "工序");
headerMap.put("devType", "装备类目");
headerMap.put("name", "类型分支");
headerMap.put("specificationModel", "规格型号");
headerMap.put("code", "装备编码");
headerMap.put("status", "装备状态");
headerMap.put("upDownStatus", "上下架状态");
headerMap.put("serviceLife", "使用年限");
headerMap.put("usingProject", "使用项目");
headerMap.put("expirationTime", "使用到期时间");
headerMap.put("usageCount", "使用次数");
headerMap.put("repairCount", "维修次数");
headerMap.put("originalCode", "装备原始编码");
headerMap.put("unit", "计量单位");
headerMap.put("manufacturer", "生产厂家");
headerMap.put("productionDate", "出厂日期");
headerMap.put("purchaseDate", "采购日期");
headerMap.put("originalValue", "资产原值(元)");
headerMap.put("maxServiceLifeYears", "最大使用年限(年)");
headerMap.put("nextMaintenanceDate", "下次维保日期");
// 2. 补全特征项和特征值的中文映射关键补充
for (int i = 1; i <= 9; i++) {
headerMap.put("featureItem" + i, "特征项" + i); // 如featureItem1"特征项1"
headerMap.put("featureValue" + i, "特征值" + i); // 如featureValue1"特征值1"
}
return headerMap;
}
/**
* 装备状态枚举转文本根据实际枚举实现
*/
/**
* 装备状态枚举转文本兼容 Java 8
*/
private String convertStatusToText(Integer status) {
if (status == null) {
return "";
}
// 传统 switch 语句Java 8 支持
String statusText;
switch (status) {
case 1:
statusText = "在库";
break;
case 2:
statusText = "自用";
break;
case 3:
statusText = "共享";
break;
case 4:
statusText = "退役";
break;
case 5:
statusText = "维修";
break;
default:
statusText = "未知";
break;
}
return statusText;
}
/**
* 上下架状态枚举转文本根据实际枚举实现
*/
private String convertUpDownStatusToText(Integer upDownStatus) {
if (upDownStatus == null) return "";
// 示例实际项目中替换为枚举映射
return upDownStatus == 1 ? "上架" : "下架";
}
}

View File

@ -338,4 +338,6 @@ public class MaDevInfo {
private String upDownStatus;
private String remainingStopYear;
}

View File

@ -11,9 +11,7 @@ public interface MaSupplierMapper {
MaSupplier selectById(@Param("supplierId") Long supplierId);
List<MaSupplier> list(@Param("supplierCode") String supplierCode,
@Param("supplierName") String supplierName,
@Param("status") Integer status);
List<MaSupplier> list(MaSupplier query);
int insert(MaSupplier supplier);

View File

@ -21,7 +21,7 @@ public class MaSupplierServiceImpl implements MaSupplierService {
@Override
public List<MaSupplier> list(MaSupplier query) {
return maSupplierMapper.list(query.getSupplierCode(), query.getSupplierName(), query.getStatus());
return maSupplierMapper.list(query);
}
@Override

View File

@ -30,7 +30,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="list" resultType="com.bonus.material.contract.domain.BmContract">
select id, content, contract_code as contractCode, contract_name as contractName, status, create_time as createTime, update_time as updateTime, owner_id as ownerId, owner_com as ownerCom from bm_contract
<where>
owner_com = #{ownerCom}
<if test="contractCode != null and contractCode != ''">
and contract_code like concat('%', #{contractCode}, '%')
</if>

View File

@ -262,8 +262,6 @@
or mtv.childGxId = #{typeId}
or mtv.devCategoryId = #{typeId}
or mtv.devSubcategoryId = #{typeId}
or mtv.devNameId = #{typeId}
or mtv.devModelId = #{typeId}
or mtv.maxTypeId = #{typeId}
)
</if>
@ -362,8 +360,6 @@
or mtv.childGxId = #{typeId}
or mtv.devCategoryId = #{typeId}
or mtv.devSubcategoryId = #{typeId}
or mtv.devNameId = #{typeId}
or mtv.devModelId = #{typeId}
or mtv.maxTypeId = #{typeId}
)
</if>

View File

@ -56,10 +56,10 @@
) a
<where>
<if test="actualStartYear != null and actualStartYear != ''">
and years_diff between #{actualStartYear} and #{actualStopYear}
and yearsDiff between #{actualStartYear} and #{actualStopYear}
</if>
<if test="remainingStartYear != null and remainingStartYear != ''">
and remaining_years between #{remainingStartYear} and #{remainingStopYear}
and remainingYears between #{remainingStartYear} and #{remainingStopYear}
</if>
<if test="isWarn != null and isWarn != ''">
<if test="isWarn == 1">

View File

@ -148,10 +148,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
mdi.on_company as sellerCompany,
up.dept_name AS czcompanyName,
mdi.person AS person,
mdi.person_phone AS personPhone,
sd.phone AS personPhone,
su.phonenumber AS phoneNumber,
su.nick_name as buyerName,
su2.nick_name as sellerName,
sd.dept_name as sellerName,
moi.address,
moi.order_id,
dept.dept_name as companyName
@ -159,6 +159,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ma_order_details hh
LEFT JOIN ma_order_info moi ON moi.order_id = hh.order_id
LEFT JOIN ma_dev_info mdi ON hh.ma_id = mdi.ma_id
LEFT JOIN sys_dept sd ON sd.dept_id = mdi.on_company
LEFT JOIN ma_type mt ON mdi.type_id = mt.type_id
LEFT JOIN sys_user su ON su.user_id = moi.buyer_id
LEFT JOIN sys_user su2 ON su2.user_id = mdi.creator

View File

@ -49,6 +49,13 @@
<if test="status != null">
and status = #{status}
</if>
<if test="contactPerson != null and contactPerson != ''">
and contact_person like concat('%', #{contactPerson}, '%')
</if>
<if test="contactPhone != null and contactPhone != ''">
and contact_phone like concat('%', #{contactPhone}, '%')
</if>
</where>
order by update_time desc
</select>