问题修改

This commit is contained in:
jiang 2025-11-28 17:38:52 +08:00
parent a2615d9e69
commit 5cdcfd2460
16 changed files with 664 additions and 285 deletions

View File

@ -5,20 +5,25 @@ 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.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.log.annotation.SysLog;
import com.bonus.common.log.enums.OperaType;
import com.bonus.common.security.utils.SecurityUtils;
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 com.bonus.system.api.domain.SysUser;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
@ -171,207 +176,11 @@ public class MaDevInfoController extends BaseController {
@PostMapping("/export")
public void export(MaDevInfo o, HttpServletResponse response) throws IOException {
// 1. 查询所有符合条件的数据忽略分页
List<MaDevInfo> dataList = service.export(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();
}
List<MaDevInfoXlsx> dataList = service.export(o);
com.bonus.common.core.utils.poi.ExcelUtil<MaDevInfoXlsx> util = new ExcelUtil<MaDevInfoXlsx>(MaDevInfoXlsx.class);
util.exportExcel(response, dataList, "装备台账");
}
/**
* 转换设备信息为导出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

@ -7,210 +7,497 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 装备实体类
* 存储装备的详细信息包括基本属性状态使用情况文档资料等
* 装备Excel导出实体类
* 存储装备导出所需的详细信息含固定9组特征项
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MaDevInfoXlsx {
/**
* 设备id不导出无注解
* 设备id不导出
*/
@ApiModelProperty(value = "设备ID")
private Integer maId;
/**
* 所属省份
*/
@Excel(name = "所属省份") // 对应headerMap的key=province
@Excel(name = "所属省份")
@ApiModelProperty(value = "所属省份")
private String province;
/**
* 专业
*/
@Excel(name = "专业") // 对应headerMap的key=major
@Excel(name = "专业")
@ApiModelProperty(value = "专业")
private String major;
/**
* 工序子工序映射可根据实际调整
* 工序子工序
*/
@Excel(name = "工序") // 对应headerMap的key=process
@Excel(name = "工序")
@ApiModelProperty(value = "工序")
private String subProcess;
/**
* 装备类目小类目映射
* 装备类目小类目
*/
@Excel(name = "装备类目") // 对应headerMap的key=devType
@Excel(name = "装备类目")
@ApiModelProperty(value = "装备类目")
private String subCategory;
/**
* 类型分支装备分支映射
* 类型分支装备分支
*/
@Excel(name = "类型分支") // 对应headerMap的key=name
@Excel(name = "类型分支")
@ApiModelProperty(value = "类型分支")
private String branch;
/**
* 规格型号
*/
@Excel(name = "规格型号") // 对应headerMap的key=specificationModel
@Excel(name = "规格型号")
@ApiModelProperty(value = "规格型号")
private String specificationModel;
/**
* 装备编码
*/
@Excel(name = "装备编码") // 对应headerMap的key=code
@Excel(name = "装备编码")
@ApiModelProperty(value = "装备编码")
private String code;
/**
* 装备状态
*/
@Excel(name = "装备状态") // 对应headerMap的key=status
@Excel(name = "装备状态", readConverterExp = "1=在库,2=自用,3=共享,4=退役,5=维修", // 核心配置转换规则
defaultValue = "在库") // 空值默认显示下架)
@ApiModelProperty(value = "装备状态")
private String status;
/**
* 上下架状态
* 上下架状态通过 readConverterExp 配置映射规则1=上架0=下架
*/
@Excel(name = "上下架状态") // 对应headerMap的key=upDownStatus
private String upDownStatus;
@Excel(
name = "上下架状态",
readConverterExp = "1=上架,0=下架", // 核心配置转换规则
defaultValue = "下架" // 空值默认显示下架
)
@ApiModelProperty(value = "上下架状态")
private String upDownStatus; // 字段类型String/Integer均可
/**
* 使用年限
*/
@Excel(name = "使用年限") // 对应headerMap的key=serviceLife
@Excel(name = "使用年限")
@ApiModelProperty(value = "使用年限")
private String serviceLife;
/**
* 使用项目ID不导出
*/
@ApiModelProperty(value = "使用项目ID")
private String usingProjectId;
/**
* 使用项目
*/
@Excel(name = "使用项目") // 对应headerMap的key=usingProject
@Excel(name = "使用项目")
@ApiModelProperty(value = "使用项目")
private String usingProject;
/**
* 使用到期时间Hutool会自动格式化日期
* 使用到期时间
*/
@Excel(name = "使用到期时间") // 对应headerMap的key=expirationTime
@Excel(name = "使用到期时间", dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(value = "使用到期时间yyyy-MM-dd")
private Date expirationTime;
/**
* 使用次数
*/
@Excel(name = "使用次数") // 对应headerMap的key=usageCount
@Excel(name = "使用次数")
@ApiModelProperty(value = "使用次数")
private Integer usageCount;
/**
* 维修次数
*/
@Excel(name = "维修次数") // 对应headerMap的key=repairCount
@Excel(name = "维修次数")
@ApiModelProperty(value = "维修次数")
private Integer repairCount;
/**
* 装备原始编码
*/
@Excel(name = "装备原始编码") // 对应headerMap的key=originalCode
@Excel(name = "装备原始编码")
@ApiModelProperty(value = "装备原始编码")
private String originalCode;
/**
* 计量单位
*/
@Excel(name = "计量单位") // 对应headerMap的key=unit
@Excel(name = "计量单位")
@ApiModelProperty(value = "计量单位")
private String unit;
/**
* 生产厂家ID不导出
*/
@ApiModelProperty(value = "生产厂家ID")
private Integer manufacturerId;
/**
* 生产厂家
*/
@Excel(name = "生产厂家") // 对应headerMap的key=manufacturer
@Excel(name = "生产厂家")
@ApiModelProperty(value = "生产厂家")
private String manufacturer;
/**
* 出厂日期
*/
@Excel(name = "出厂日期") // 对应headerMap的key=productionDate
@Excel(name = "出厂日期", dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(value = "出厂日期yyyy-MM-dd")
private Date productionDate;
/**
* 采购日期
*/
@Excel(name = "采购日期") // 对应headerMap的key=purchaseDate
@Excel(name = "采购日期", dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(value = "采购日期yyyy-MM-dd")
private Date purchaseDate;
/**
* 资产原值
*/
@Excel(name = "资产原值(元)") // 对应headerMap的key=originalValue
@Excel(name = "资产原值(元)")
@ApiModelProperty(value = "资产原值(元)")
private BigDecimal originalValue;
/**
* 最大使用年限
*/
@Excel(name = "最大使用年限(年)") // 对应headerMap的key=maxServiceLifeYears
@Excel(name = "最大使用年限(年)")
@ApiModelProperty(value = "最大使用年限(年)")
private Integer maxServiceLifeYears;
/**
* 下次维保日期
*/
@Excel(name = "下次维保日期") // 对应headerMap的key=nextMaintenanceDate
@Excel(name = "下次维保日期", dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(value = "下次维保日期yyyy-MM-dd")
private Date nextMaintenanceDate;
/**
* 产权单位
*/
@Excel(name = "产权单位") // 对应headerMap的key=propertyUnit
@Excel(name = "产权单位")
@ApiModelProperty(value = "产权单位")
private String propertyUnit;
// 固定9组特征项+特征值
@Excel(name = "特征项1")
@ApiModelProperty(value = "特征项1")
private String propertyName1;
/**
* 属性值
*/
@Excel(name = "特征值1")
@ApiModelProperty(value = "特征值1")
private String propertyValue1;
@Excel(name = "特征项2")
@ApiModelProperty(value = "特征项2")
private String propertyName2;
/**
* 属性值
*/
@Excel(name = "特征值2")
@ApiModelProperty(value = "特征值2")
private String propertyValue2;
@Excel(name = "特征项3")
@ApiModelProperty(value = "特征项3")
private String propertyName3;
/**
* 属性值
*/
@Excel(name = "特征值3")
@ApiModelProperty(value = "特征值3")
private String propertyValue3;
@Excel(name = "特征项4")
@ApiModelProperty(value = "特征项4")
private String propertyName4;
/**
* 属性值
*/
@Excel(name = "特征值4")
@ApiModelProperty(value = "特征值4")
private String propertyValue4;
@Excel(name = "特征项5")
@ApiModelProperty(value = "特征项5")
private String propertyName5;
/**
* 属性值
*/
@Excel(name = "特征值5")
@ApiModelProperty(value = "特征值5")
private String propertyValue5;
@Excel(name = "特征项6")
@ApiModelProperty(value = "特征项6")
private String propertyName6;
/**
* 属性值
*/
@Excel(name = "特征值6")
@ApiModelProperty(value = "特征值6")
private String propertyValue6;
@Excel(name = "特征项7")
@ApiModelProperty(value = "特征项7")
private String propertyName7;
/**
* 属性值
*/
@Excel(name = "特征值7")
@ApiModelProperty(value = "特征值7")
private String propertyValue7;
@Excel(name = "特征项8")
@ApiModelProperty(value = "特征项8")
private String propertyName8;
/**
* 属性值
*/
@Excel(name = "特征值8")
@ApiModelProperty(value = "特征值8")
private String propertyValue8;
@Excel(name = "特征项9")
@ApiModelProperty(value = "特征项9")
private String propertyName9;
/**
* 属性值
*/
@Excel(name = "特征值9")
@ApiModelProperty(value = "特征值9")
private String propertyValue9;
}
private Integer devId;
/**
* 类型id
*/
private Integer typeId;
/**
* 订单id
*/
private Integer orderId;
/**
* 专业Id
* 说明装备所属的专业领域如机械电子建筑等
*/
private Integer majorId;
/**
* 管理模式
*/
private String manageType;
/**
* 数量
*/
private Integer count;
/**
* 主工序id
*/
private Integer mainProcessId;
/**
* 主工序
* 说明装备主要参与的工序环节
*/
private String mainProcess;
/**
* 子工序id
* 说明装备参与的具体子工序
*/
private Integer subProcessId;
/**
* 装备大类目id
* 说明装备所属的一级分类如工程机械仪器仪表等
*/
private Integer mainCategoryId;
/**
* 装备大类目
* 说明装备所属的一级分类如工程机械仪器仪表等
*/
private String mainCategory;
/**
* 装备小类目id
* 说明装备所属的二级分类主类目下的细分分类
*/
private Integer subCategoryId;
/**
* 装备分支id
* 说明小类目下的更细分类代表具体的装备类型分支
*/
private Integer branchId;
/**
* 装备名称
* 说明装备的具体名称用于标识和展示
*/
private String name;
// 新增开始出厂时间查询条件用于筛选 >= 该日期的记录
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date startProductionDate;
// 新增结束出厂时间查询条件用于筛选 <= 该日期的记录
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date endProductionDate;
/**
* 开始采购日期
* 说明装备被采购入库的日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date startPurchaseDate;
/**
* 结束采购日期
* 说明装备被采购入库的日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date endPurchaseDate;
/**
* 最小资产原值
* 说明装备的原始采购价值以元为单位
*/
private BigDecimal minOriginalValue;
/**
* 最大资产原值
* 说明装备的原始采购价值以元为单位
*/
private BigDecimal maxOriginalValue;
/**
* 产权单位id
* 说明装备的所有权所属单位
*/
private Integer propertyUnitId;
/**
* 装备外观
* 说明装备外观图片的URL列表存储装备的外观照片
*/
private List<MaDevFile> appearanceImages;
/**
* 合格证
* 说明装备合格证的URL列表存储合格证扫描件或照片
*/
private List<MaDevFile> certificates;
/**
* 定期检验报告
* 说明装备定期检验报告的URL列表
*/
private List<MaDevFile> inspectionReports;
/**
* 采购发票
* 说明装备采购发票的URL列表存储发票扫描件或照片
*/
private List<MaDevFile> purchaseInvoices;
/**
* 订单编号
*/
private String orderNumber;
/**
* 订单创建人
*/
private String orderCreateUser;
/**
* 订单时间
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date orderCreateTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date startOrderCreateTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date endOrderCreateTime;
/**
* 订单时间
*/
private String orderStatus;
private String daysDiff;
private String remainingDays;
private String remainingYears;
private String yearsDiff;
private String expirationYears;
private String actualStartYear;
private String remainingStartYear;
private String isWarn;
private String entryStatus;
private String remainingStopYear;
private String actualStopYear;
/**
* 特征项列表不导出用于映射到上述9组字段
*/
@ApiModelProperty(value = "特征项列表")
private List<DevInfoPropertyVo> propertyVoList;
/**
* 自动填充特征项到9组固定字段核心优化避免手动赋值
* 调用时机propertyVoList设置后执行
*/
public void fillPropertyFields() {
if (CollectionUtils.isEmpty(propertyVoList)) {
return; // 无特征项直接返回
}
// 循环处理前9个特征项超过9个则忽略符合Excel固定列设计
for (int i = 0; i < Math.min(propertyVoList.size(), 9); i++) {
DevInfoPropertyVo property = propertyVoList.get(i);
int index = i + 1; // 特征项序号1~9
// 根据序号设置对应的特征项名称和值通过反射简化重复代码
try {
// 设置特征项名称propertyName1~9
this.getClass().getDeclaredField("propertyName" + index)
.set(this, property.getPropertyName()); // 假设DevInfoPropertyVo的特征项名称字段是propertyKey
// 设置特征值propertyValue1~9
this.getClass().getDeclaredField("propertyValue" + index)
.set(this, property.getPropertyValue()); // 假设特征值字段是propertyValue
} catch (Exception e) {
// 反射异常时跳过该特征项不影响整体导出
e.printStackTrace();
}
}
}
}

View File

@ -50,5 +50,7 @@ public interface MaDevInfoMapper {
Integer selectTotalDeviceCount();
List<DevInfoPropertyVo> batchGetProperties( @Param("mainIds") List<Integer> mainIds);
List<MaDevInfoXlsx> listXlsx(MaDevInfo o);
}

View File

@ -1,10 +1,7 @@
package com.bonus.material.devchange.service;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.devchange.domain.DeviceCountBean;
import com.bonus.material.devchange.domain.DeviceTreeBean;
import com.bonus.material.devchange.domain.MaDevInfo;
import com.bonus.material.devchange.domain.MapBean;
import com.bonus.material.devchange.domain.*;
import com.bonus.material.device.domain.vo.DevMergeVo;
import java.util.List;
@ -31,5 +28,5 @@ public interface MaDevInfoService {
AjaxResult getDeviceByMaIds(String maIds);
List<MaDevInfo> export(MaDevInfo o);
List<MaDevInfoXlsx> export(MaDevInfo o);
}

View File

@ -3,10 +3,7 @@ package com.bonus.material.devchange.service;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.devchange.domain.DeviceCountBean;
import com.bonus.material.devchange.domain.DeviceTreeBean;
import com.bonus.material.devchange.domain.MaDevInfo;
import com.bonus.material.devchange.domain.MapBean;
import com.bonus.material.devchange.domain.*;
import com.bonus.material.devchange.mapper.MaDevInfoMapper;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.device.domain.vo.DevMergeVo;
@ -125,18 +122,16 @@ public class MaDevInfoServiceImpl implements MaDevInfoService {
* @return
*/
@Override
public List<MaDevInfo> export(MaDevInfo o) {
/* Long thisLoginUserDeptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
o.setPropertyUnitId(Math.toIntExact(thisLoginUserDeptId));*/
public List<MaDevInfoXlsx> export(MaDevInfo o) {
// 1. 一次性查询所有主表数据1次查询
List<MaDevInfo> mainList = mapper.list(o);
List<MaDevInfoXlsx> mainList = mapper.listXlsx(o);
if (mainList.isEmpty()) {
return Collections.emptyList(); // 空数据直接返回避免后续无效操作
}
// 2. 收集所有主表ID用于批量查关联属性
List<Integer> mainIds = mainList.stream()
.map(MaDevInfo::getMaId) // 假设主表主键是idLong类型根据实际字段调整
.map(MaDevInfoXlsx::getMaId) // 假设主表主键是idLong类型根据实际字段调整
.filter(Objects::nonNull) // 过滤空ID防止查询异常
.collect(Collectors.toList());
@ -152,6 +147,8 @@ public class MaDevInfoServiceImpl implements MaDevInfoService {
// 若主表ID无对应属性返回空集合避免null
List<DevInfoPropertyVo> properties = propertyMap.getOrDefault(main.getMaId(), Collections.emptyList());
main.setPropertyVoList(properties);
// 自动填充 propertyName1~9 propertyValue1~9适配Excel导出
main.fillPropertyFields();
});
return mainList;

View File

@ -7,7 +7,11 @@ import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.log.annotation.SysLog;
import com.bonus.common.log.enums.OperaType;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.devchange.domain.MaDevInfo;
import com.bonus.material.devchange.domain.MaDevInfoXlsx;
import com.bonus.material.device.domain.DevInfo;
import com.bonus.material.device.domain.dto.InfoMotionDto;
import com.bonus.material.device.domain.vo.DevInfoVo;
@ -16,6 +20,7 @@ import com.bonus.material.device.service.DevInfoService;
import com.bonus.material.device.service.DevMergeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@ -266,4 +271,19 @@ public class DevMergeController extends BaseController {
}
@PostMapping("/importData")
@SysLog(title = "用户管理", businessType = OperaType.IMPORT, logType = 0, module = "系统管理->用户管理", details = "导入用户信息")
public AjaxResult importData(MultipartFile file, String orderId) throws Exception {
try {
ExcelUtil<MaDevInfoXlsx> util = new ExcelUtil<MaDevInfoXlsx>(MaDevInfoXlsx.class);
List<MaDevInfoXlsx> list = util.importExcel(file.getInputStream());
return service.importData(list, orderId);
} catch (Exception e) {
logger.error(e.toString(), e);
return error(e.getMessage());
}
}
}

View File

@ -41,6 +41,7 @@ public interface DevInfoMapper {
/**
* 判断设备名称是否重复
*
* @param deviceName 物资名称
* @return 条数
*/
@ -60,6 +61,7 @@ public interface DevInfoMapper {
/**
* 获取企业设备浏览量
*
* @param companyId
* @return
*/
@ -87,6 +89,7 @@ public interface DevInfoMapper {
/**
* 保存草稿
*
* @param devInfo 设备信息
*/
int insertDraft(DevInfo devInfo);
@ -102,7 +105,7 @@ public interface DevInfoMapper {
/**
* 删除设备信息 -- 逻辑删除 -- 限制状态删除
*
* @param maId 设备信息主键
* @param maId 设备信息主键
* @param statusCode 状态码
* @return 结果
*/
@ -133,16 +136,17 @@ public interface DevInfoMapper {
List<DevInfoVo> selectDevInfoLists(DevInfoVo devInfo);
List<DevInfoPropertyVo> selectDevInfoProperties(@Param("maId")Long maId);
List<DevInfoPropertyVo> selectDevInfoProperties(@Param("maId") Long maId);
int deleteDevInfoProperties(@Param("maId")Long maId);
int deleteDevInfoProperties(@Param("maId") Long maId);
int batchDeleteDevInfoProperties(@Param("maIds")Long[] maIds);
int batchDeleteDevInfoProperties(@Param("maIds") Long[] maIds);
int insertDevInfoProperties(@Param("maId")Long maId, @Param("list") List<DevInfoPropertyVo> list);
int insertDevInfoProperties(@Param("maId") Long maId, @Param("list") List<DevInfoPropertyVo> list);
/**
* 查询企业信息
*
* @param obj
* @return
*/
@ -154,6 +158,7 @@ public interface DevInfoMapper {
/**
* 查询预约车详情
*
* @param maId
* @param userId
* @return
@ -162,6 +167,7 @@ public interface DevInfoMapper {
/**
* 查询企业上架装备数
*
* @param companyId
* @return
*/
@ -169,6 +175,7 @@ public interface DevInfoMapper {
/**
* 查询该设备的出租记录
*
* @param maId
* @return
*/
@ -180,6 +187,7 @@ public interface DevInfoMapper {
/**
* 查询企业信息
*
* @param companyId
* @return
*/
@ -188,6 +196,7 @@ public interface DevInfoMapper {
String getCodeByMaId(Long maId);
Integer updateDevInfoIsQc(MaDevQc maDevQc);
Integer updateDevInfoIsSafeBook(SafeBookInfo safeBookInfo);
List<DevInfoVo> selectAssociationList(DevInfoVo devInfo);
@ -230,6 +239,7 @@ public interface DevInfoMapper {
/**
* 在租装备信息查询
*
* @param devInfo
* @return
*/
@ -238,6 +248,7 @@ public interface DevInfoMapper {
/**
* 查询装备对应所属公司
*
* @return
*/
List<DevInfoVo> getCompanyNum();
@ -252,6 +263,7 @@ public interface DevInfoMapper {
/**
* 根据装备类型名称查询
*
* @param typeName
* @return
*/
@ -295,7 +307,7 @@ public interface DevInfoMapper {
int getEquipmentStatus(String changeStatus);
int getChangeNum();
Integer getChangeNum();
int getTurnoverRate();

View File

@ -6,6 +6,7 @@ import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.book.domain.BookCarInfoDto;
import com.bonus.material.devchange.domain.MaDevFile;
import com.bonus.material.devchange.domain.MaDevInfo;
import com.bonus.material.devchange.domain.MaDevInfoXlsx;
import com.bonus.material.devchange.domain.MapBean;
import com.bonus.material.device.domain.DevInfo;
import com.bonus.material.device.domain.MaDevQc;
@ -73,6 +74,7 @@ public interface DevMergeMapper {
Integer interDevice(MaDevInfo maDevInfo);
Integer interDeviceXlsx(MaDevInfoXlsx maDevInfo);
List<MaDevInfo> getDevice(MaDevInfo o);

View File

@ -4,6 +4,7 @@ package com.bonus.material.device.service;
import com.bonus.common.biz.domain.BmCompanyInfo;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.devchange.domain.MaDevInfo;
import com.bonus.material.devchange.domain.MaDevInfoXlsx;
import com.bonus.material.device.domain.DevInfo;
import com.bonus.material.device.domain.dto.DevInfoImpDto;
import com.bonus.material.device.domain.dto.InfoMotionDto;
@ -69,4 +70,6 @@ public interface DevMergeService {
List<MaDevInfo> getDeviceByOrderId(MaDevInfo o);
AjaxResult updateDevice(MaDevInfo maDevInfo);
AjaxResult importData(List<MaDevInfoXlsx> list, String orderId);
}

View File

@ -18,6 +18,7 @@ import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.book.domain.BookCarInfoDto;
import com.bonus.material.devchange.domain.MaDevFile;
import com.bonus.material.devchange.domain.MaDevInfo;
import com.bonus.material.devchange.domain.MaDevInfoXlsx;
import com.bonus.material.devchange.domain.MapBean;
import com.bonus.material.devchange.mapper.MaDevInfoMapper;
import com.bonus.material.device.domain.DevInfo;
@ -415,6 +416,90 @@ public class DevMergeServiceImpl implements DevMergeService {
}
}
/**
* @param list
* @param orderId
* @return
*/
@Override
public AjaxResult importData(List<MaDevInfoXlsx> list, String orderId) {
if (Objects.isNull(list) || list.isEmpty()) {
return AjaxResult.error("表格内没有数据");
}
if (Objects.isNull(orderId)) {
DevMergeVo o = new DevMergeVo();
o.setCreateUser(SecurityUtils.getLoginUser().getSysUser().getNickName());
o.setOrderNumber(generate());
devMergeMapper.addOrder(o);
orderId = o.getId();
}
for (MaDevInfoXlsx maDevInfo : list) {
}
for (MaDevInfoXlsx maDevInfo : list) {
maDevInfo.setOrderId(Integer.valueOf(orderId));
try {
Long thisLoginUserDeptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
maDevInfo.setPropertyUnitId(Math.toIntExact(thisLoginUserDeptId));
maDevInfo.setCode(getString());
Integer i = devMergeMapper.interDeviceXlsx(maDevInfo);
if (i > 0) {
devInfoMapper.deleteDevInfoProperties(Long.valueOf(maDevInfo.getMaId()));
MaDevQc maDevQc = new MaDevQc();
maDevQc.setMaId(maDevInfo.getMaId());
maDevQc.setQcCode(maDevInfo.getCode());
maDevQc.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
maDevQc.setCreateTime(DateUtils.getNowDate());
maDevQc.setQcCom(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()).toString());
maDevQc.setNextCheckTime(maDevInfo.getNextMaintenanceDate());
qcMapper.insertDevQc(maDevQc);
if (!CollectionUtils.isEmpty(maDevInfo.getPropertyVoList())) {
devInfoMapper.insertDevInfoProperties(Long.valueOf(maDevInfo.getMaId()), maDevInfo.getPropertyVoList());
}
devMergeMapper.insertOrderDevReal(String.valueOf(maDevInfo.getOrderId()), Long.valueOf(maDevInfo.getMaId()));
maDevInfo.getAppearanceImages().forEach(item -> {
// 这里编写对每个 image 的处理逻辑比如打印处理等
item.setFileType(1);
item.setMaId(maDevInfo.getMaId());
item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
devMergeMapper.interFile(item);
});
maDevInfo.getCertificates().forEach(item -> {
// 这里编写对每个 image 的处理逻辑比如打印处理等
item.setFileType(2);
item.setMaId(maDevInfo.getMaId());
item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
devMergeMapper.interFile(item);
});
maDevInfo.getInspectionReports().forEach(item -> {
// 这里编写对每个 image 的处理逻辑比如打印处理等
item.setFileType(3);
item.setMaId(maDevInfo.getMaId());
item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
devMergeMapper.interFile(item);
});
maDevInfo.getPurchaseInvoices().forEach(item -> {
// 这里编写对每个 image 的处理逻辑比如打印处理等
item.setFileType(4);
item.setMaId(maDevInfo.getMaId());
item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
devMergeMapper.interFile(item);
});
}
return i > 0 ? AjaxResult.success() : AjaxResult.error();
} catch (Exception e) {
log.error(e.getMessage());
return AjaxResult.error();
}
}
return null;
}
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyMMdd");
private static final String SEPARATOR = "-";

View File

@ -223,7 +223,7 @@ public class ProvinceScreenServiceImpl implements ProvinceScreenService {
Integer totalEquipmentQuantity = devInfoMapper.getTotalEquipment(devInfoReq);
res.put("proportion", totalEquipmentQuantity > 0 ? ((inUse + share) * 100) / totalEquipmentQuantity : 0 + "%");
//周转率
int devNum = devInfoMapper.getChangeNum();
Integer devNum = devInfoMapper.getChangeNum();
res.put("turnoverRate", totalEquipmentQuantity > 0 ? (devNum * 100) / totalEquipmentQuantity : 0 + "%");
return res;
}

View File

@ -10,6 +10,7 @@ import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@ -190,7 +191,7 @@ public class ToolLedgerEntity implements Serializable {
*/
private String fileList;
private List<DevInfoPropertyVo> propertyVoList;
private List<DevInfoPropertyVo> propertyVoList = new ArrayList<>();
private String proName;
}

View File

@ -1,5 +1,6 @@
package com.bonus.material.toolLedger.service.Impl;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.toolLedger.domain.ToolLedgerEntity;
@ -57,8 +58,11 @@ public class ToolLedgerServiceImpl implements ToolLedgerService {
public AjaxResult updateById(ToolLedgerEntity entity) {
try {
Integer num = mapper.updateById(entity);
mapper.delProperties(entity.getId());
mapper.insertDevInfoProperties(entity.getPropertyVoList(), entity.getId());
if(!entity.getPropertyVoList().isEmpty()){
mapper.delProperties(entity.getId());
mapper.insertDevInfoProperties(entity.getPropertyVoList(), entity.getId());
}
return num > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
} catch (Exception e) {
log.error(e.getMessage());

View File

@ -495,5 +495,113 @@
#{id}
</foreach>
</select>
<select id="listXlsx" resultType="com.bonus.material.devchange.domain.MaDevInfoXlsx">
select mdi.ma_id AS maId,
mdi.type_id AS typeId,
mdi.manage_type AS manageType,
mdi.device_count AS count,
mtv.maxTypeId AS majorId,
mtv.proType AS major,
mtv.mainGxId AS mainProcessId,
mtv.mainGx AS mainProcess,
mtv.childGxId AS subProcessId,
mtv.childGx AS subProcess,
mtv.devCategoryId AS mainCategoryId,
mtv.devCategory AS mainCategory,
mtv.devSubcategory AS subCategory,
mtv.devSubcategoryId AS subCategoryId,
mtv.devNameId AS branchId,
mtv.devName AS branch,
mdi.device_name AS name,
mdi.item_type_model As specificationModel,
mdi.code AS code,
mdi.up_down_status AS upDownStatus,
mdi.change_status AS status,
TIMESTAMPDIFF(YEAR, mdi.production_date, CURDATE()) AS serviceLife,
jsp.pro_code AS usingProjectId,
jsp.pro_name AS usingProject,
mdi.identify_code AS originalCode,
mdi.supplier_id AS manufacturerId,
ms.supplier_name AS manufacturer,
mdi.purchase_date AS purchaseDate,
mdi.production_date AS productionDate,
sd.dept_id AS propertyUnitId,
sd.dept_name AS propertyUnit,
mdi.buy_price AS originalValue,
mdi.unit AS unit,
mdq.next_check_time AS nextMaintenanceDate,
mdi.max_working_hours AS maxServiceLifeYears,
0 AS repairCount,
0 AS usageCount,
sc.name AS province
from ma_dev_info mdi
INNER JOIN ma_type_view mtv ON mtv.typeId = mdi.type_id
LEFT JOIN jj_sing_project jsp ON mdi.on_project = jsp.pro_code
LEFT JOIN sys_dept sd ON sd.dept_id = mdi.on_company
LEFT JOIN (SELECT max( next_check_time) next_check_time,ma_id from ma_dev_qc GROUP BY ma_id ) mdq on
mdi.ma_id=mdq.ma_id
LEFT JOIN ma_supplier ms ON ms.supplier_id = mdi.supplier_id
LEFT JOIN sys_cnarea sc ON sc.area_code = mdi.province_id
<where>
mdi.is_active = '1' and mdi.entry_status = '1'
<if test="typeId != null and typeId != 0 ">
and (
mtv.mainGxId = #{typeId}
or mtv.childGxId = #{typeId}
or mtv.devCategoryId = #{typeId}
or mtv.devSubcategoryId = #{typeId}
or mtv.maxTypeId = #{typeId}
)
</if>
<if test="name != null and name != ''">
and mdi.device_name like concat('%', #{name}, '%')
</if>
<if test="specificationModel != null and specificationModel != ''">
and mdi.item_type_model like concat('%', #{specificationModel}, '%')
</if>
<if test="province != null and province != ''">
and sc.area_code = #{province}
</if>
<if test="usingProjectId != null and usingProjectId != ''">
and jsp.pro_code = #{usingProjectId}
</if>
<if test="majorId != null and majorId != ''">
and mtv.maxTypeId = #{majorId}
</if>
<if test="subProcessId != null and subProcessId != ''">
and mtv.childGxId = #{subProcessId}
</if>
<if test="code != null and code != ''">
and mdi.code like concat('%', #{code}, '%')
</if>
<if test="originalCode != null and originalCode != ''">
and mdi.identify_code like concat('%', #{originalCode}, '%')
</if>
<if test="propertyUnitId != null and propertyUnitId != ''">
and sd.dept_id = #{propertyUnitId}
</if>
<if test="manufacturerId != null and manufacturerId != ''">
and mdi.brand = #{manufacturerId}
</if>
<if test="minOriginalValue != null and minOriginalValue != '' and maxOriginalValue != null and maxOriginalValue != ''">
and mdi.buy_price &gt;= #{minOriginalValue} and mdi.buy_price &lt;= #{maxOriginalValue}
</if>
<if test="startProductionDate != null and startProductionDate != '' and endProductionDate != null and endProductionDate != ''">
and DATE_FORMAT(mdi.production_date,'%Y-%m-%d') between #{startProductionDate} and #{endProductionDate}
</if>
<if test="startPurchaseDate != null and startPurchaseDate != '' and endPurchaseDate != null and endPurchaseDate != ''">
and DATE_FORMAT(mdi.purchase_date,'%Y-%m-%d') between #{startPurchaseDate} and #{endPurchaseDate}
</if>
<if test="status != null and status != ''">
AND mdi.change_status=#{status}
</if>
</where>
</select>
</mapper>

View File

@ -1459,7 +1459,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select count(1) from ma_dev_info where is_active ='1' and change_status = #{changeStatus}
</select>
<select id="getChangeNum" resultType="java.lang.Integer">
select SUM(num)
select IFNULL(SUM(num), 0)
from cs_device_change_details
where del_flag = '0'
and use_time is not null

View File

@ -154,6 +154,58 @@
now(),
'1')
</insert>
<insert parameterType="com.bonus.material.devchange.domain.MaDevInfoXlsx" id="interDeviceXlsx" useGeneratedKeys="true"
keyProperty="maId">
INSERT INTO ma_dev_info (
<!-- 必选字段若业务要求必须传值可去掉if判断 -->
device_name,
device_count,
item_type_model,
manage_type,
code,
ma_status,
province_id,
on_company,
<!-- 非必填字段:有值才插入 -->
<if test="originalCode != null and originalCode != ''">identify_code,</if>
<if test="typeId != null">type_id,</if>
<if test="manufacturerId != null and manufacturerId != ''">supplier_id,</if>
<if test="productionDate != null">production_date,</if>
<if test="maxServiceLifeYears != null">max_working_hours,</if>
<if test="expirationTime != null">expiration_time,</if>
<if test="originalValue != null">buy_price,</if>
<if test="purchaseDate != null">purchase_date,</if>
<if test="unit != null">unit,</if>
<!-- 默认值字段:无值时插入默认值'1'(未删除) -->
is_active,
change_status,
up_down_status
)
VALUES (
#{name},
#{count},
#{specificationModel},
#{manageType},
#{code},
'0',
'340000000000',
#{propertyUnitId},
<!-- 非必填字段对应值 -->
<if test="originalCode != null and originalCode != ''">#{originalCode},</if>
<if test="typeId != null">#{typeId},</if>
<if test="manufacturerId != null and manufacturerId != ''">#{manufacturerId},</if>
<if test="productionDate != null">#{productionDate},</if>
<if test="maxServiceLifeYears != null">#{maxServiceLifeYears},</if>
<if test="expirationTime != null">#{expirationTime},</if>
<if test="originalValue != null">#{originalValue},</if>
<if test="purchaseDate != null">#{purchaseDate},</if>
<if test="unit != null">#{unit},</if>
<!-- 默认值:即使实体类无该属性,也插入'1' -->
'1',
'0',
'0'
)
</insert>
<update id="submitOrder">
UPDATE ma_apply