Browse Source
feat(pms): 新增MES TID EPC日志管理功能
feat(pms): 新增MES TID EPC日志管理功能
- 创建MesTidEpcLogEntity实体类映射数据库表 - 实现MesTidEpcLogController提供REST API接口 - 开发MesTidEpcLogService服务层处理业务逻辑 - 添加MyBatis Mapper接口及XML配置文件 - 实现Excel导入导出功能支持批量数据处理 - 提供分页查询、删除、下载模板等完整CRUD操作master
7 changed files with 991 additions and 0 deletions
-
97src/main/java/com/xujie/sys/modules/pms/controller/MesTidEpcLogController.java
-
81src/main/java/com/xujie/sys/modules/pms/data/MesTidEpcLogData.java
-
159src/main/java/com/xujie/sys/modules/pms/entity/MesTidEpcLogEntity.java
-
57src/main/java/com/xujie/sys/modules/pms/mapper/MesTidEpcLogMapper.java
-
364src/main/java/com/xujie/sys/modules/pms/service/Impl/MesTidEpcLogServiceImpl.java
-
63src/main/java/com/xujie/sys/modules/pms/service/MesTidEpcLogService.java
-
170src/main/resources/mapper/pms/MesTidEpcLogMapper.xml
@ -0,0 +1,97 @@ |
|||
package com.xujie.sys.modules.pms.controller; |
|||
|
|||
import com.xujie.sys.common.utils.PageUtils; |
|||
import com.xujie.sys.common.utils.R; |
|||
import com.xujie.sys.modules.pms.data.MesTidEpcLogData; |
|||
import com.xujie.sys.modules.pms.service.MesTidEpcLogService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import jakarta.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* MES TID EPC日志Controller - rqrq |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@RestController |
|||
@RequestMapping("/pms/mesTidEpcLog") |
|||
public class MesTidEpcLogController { |
|||
|
|||
@Autowired |
|||
private MesTidEpcLogService mesTidEpcLogService; |
|||
|
|||
/** |
|||
* @Description 分页查询日志列表 - rqrq |
|||
* @param data 查询条件 |
|||
* @return R |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@PostMapping("/searchList") |
|||
public R searchList(@RequestBody MesTidEpcLogData data) { |
|||
PageUtils page = mesTidEpcLogService.searchList(data); |
|||
return R.ok().put("page", page); |
|||
} |
|||
|
|||
/** |
|||
* @Description 导入Excel数据 - rqrq |
|||
* @param file Excel文件 |
|||
* @param site 站点 |
|||
* @param buNo BU编码 |
|||
* @param remark 备注 |
|||
* @param username 上传人 |
|||
* @return R |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@PostMapping("/importExcel") |
|||
public R importExcel(@RequestParam("file") MultipartFile file, |
|||
@RequestParam("site") String site, |
|||
@RequestParam("buNo") String buNo, |
|||
@RequestParam(value = "remark", required = false) String remark, |
|||
@RequestParam("username") String username) { |
|||
mesTidEpcLogService.importExcel(file, site, buNo, remark, username); |
|||
return R.ok().put("msg", "导入成功"); |
|||
} |
|||
|
|||
/** |
|||
* @Description 导出数据列表 - rqrq |
|||
* @param data 查询条件 |
|||
* @return R |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@PostMapping("/getExportList") |
|||
public R getExportList(@RequestBody MesTidEpcLogData data) { |
|||
List<MesTidEpcLogData> rows = mesTidEpcLogService.getExportList(data); |
|||
return R.ok().put("rows", rows); |
|||
} |
|||
|
|||
/** |
|||
* @Description 下载导入模板 - rqrq |
|||
* @param response HttpServletResponse |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@GetMapping("/downloadTemplate") |
|||
public void downloadTemplate(HttpServletResponse response) { |
|||
mesTidEpcLogService.downloadTemplate(response); |
|||
} |
|||
|
|||
/** |
|||
* @Description 删除日志数据 - rqrq |
|||
* @param ids ID数组 |
|||
* @return R |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@PostMapping("/delete") |
|||
public R delete(@RequestBody Long[] ids) { |
|||
mesTidEpcLogService.deleteByIds(ids); |
|||
return R.ok(); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
package com.xujie.sys.modules.pms.data; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import com.xujie.sys.modules.pms.entity.MesTidEpcLogEntity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.apache.ibatis.type.Alias; |
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
|
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* MES TID EPC日志业务实体类 - 用于业务查询和操作 - rqrq |
|||
* |
|||
* <p><b>功能说明:</b></p> |
|||
* <ul> |
|||
* <li>继承基础实体类 MesTidEpcLogEntity</li> |
|||
* <li>添加分页参数和查询条件字段</li> |
|||
* </ul> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Alias("MesTidEpcLogData") |
|||
public class MesTidEpcLogData extends MesTidEpcLogEntity { |
|||
|
|||
// ==================== 分页参数 ==================== |
|||
|
|||
/** |
|||
* 分页参数 - 当前页码 |
|||
*/ |
|||
private Integer page = 1; |
|||
|
|||
/** |
|||
* 分页参数 - 每页数量 |
|||
*/ |
|||
private Integer limit = 20; |
|||
|
|||
// ==================== 查询条件字段 ==================== |
|||
|
|||
/** |
|||
* 查询条件 - 序号 |
|||
*/ |
|||
private String searchSeqNo; |
|||
|
|||
/** |
|||
* 查询条件 - EPC编码 |
|||
*/ |
|||
private String searchEpc; |
|||
|
|||
/** |
|||
* 查询条件 - TID编码 |
|||
*/ |
|||
private String searchTid; |
|||
|
|||
/** |
|||
* 查询条件 - 用户区 |
|||
*/ |
|||
private String searchUserArea; |
|||
|
|||
/** |
|||
* 查询条件 - 扫描时间开始 |
|||
*/ |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
private Date scanTimeStart; |
|||
|
|||
/** |
|||
* 查询条件 - 扫描时间结束 |
|||
*/ |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
private Date scanTimeEnd; |
|||
|
|||
/** |
|||
* 查询条件 - 批次号 |
|||
*/ |
|||
private String searchBatchNo; |
|||
} |
|||
@ -0,0 +1,159 @@ |
|||
package com.xujie.sys.modules.pms.entity; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.*; |
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import lombok.Data; |
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
|
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* MES TID EPC日志实体类 - 直接映射数据库表 - rqrq |
|||
* |
|||
* <p><b>数据库表名:</b>mes_tid_epc_log</p> |
|||
* |
|||
* <p><b>功能说明:</b></p> |
|||
* <ul> |
|||
* <li>存储RFID设备扫描日志数据</li> |
|||
* <li>支持批量导入Excel数据</li> |
|||
* </ul> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@Data |
|||
@TableName("mes_tid_epc_log") |
|||
public class MesTidEpcLogEntity { |
|||
|
|||
// ==================== 主键 ==================== |
|||
|
|||
/** |
|||
* 主键,自增ID |
|||
*/ |
|||
@TableId(type = IdType.AUTO) |
|||
private Long id; |
|||
|
|||
// ==================== 业务基础字段 ==================== |
|||
|
|||
/** |
|||
* 工厂/站点编码 |
|||
*/ |
|||
@TableField("site") |
|||
private String site; |
|||
|
|||
/** |
|||
* BU编码 |
|||
*/ |
|||
@TableField("bu_no") |
|||
private String buNo; |
|||
|
|||
// ==================== 原始数据字段 ==================== |
|||
|
|||
/** |
|||
* 序号 |
|||
*/ |
|||
@TableField("seq_no") |
|||
private String seqNo; |
|||
|
|||
/** |
|||
* EPC编码 |
|||
*/ |
|||
@TableField("epc") |
|||
private String epc; |
|||
|
|||
/** |
|||
* TID编码 |
|||
*/ |
|||
@TableField("tid") |
|||
private String tid; |
|||
|
|||
/** |
|||
* 用户区 |
|||
*/ |
|||
@TableField("user_area") |
|||
private String userArea; |
|||
|
|||
/** |
|||
* LockiBtis |
|||
*/ |
|||
@TableField("lock_bits") |
|||
private String lockBits; |
|||
|
|||
/** |
|||
* 密匙 |
|||
*/ |
|||
@TableField("secret_key") |
|||
private String secretKey; |
|||
|
|||
/** |
|||
* 写码成功(True/False) |
|||
*/ |
|||
@TableField("write_success") |
|||
private String writeSuccess; |
|||
|
|||
/** |
|||
* 读码成功(True/False) |
|||
*/ |
|||
@TableField("read_success") |
|||
private String readSuccess; |
|||
|
|||
/** |
|||
* EPC锁定(True/False) |
|||
*/ |
|||
@TableField("epc_locked") |
|||
private String epcLocked; |
|||
|
|||
/** |
|||
* 强度/读距 |
|||
*/ |
|||
@TableField("signal_strength") |
|||
private String signalStrength; |
|||
|
|||
/** |
|||
* 扫描时间(原始时间字段) |
|||
*/ |
|||
@TableField("scan_time") |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
private Date scanTime; |
|||
|
|||
/** |
|||
* 计数信息 |
|||
*/ |
|||
@TableField("count_info") |
|||
private String countInfo; |
|||
|
|||
// ==================== 上传相关字段 ==================== |
|||
|
|||
/** |
|||
* 批次号(后台生成,格式:YYYYMMDD + 6位序列号) |
|||
*/ |
|||
@TableField("batch_no") |
|||
private String batchNo; |
|||
|
|||
/** |
|||
* 上传的文件名 |
|||
*/ |
|||
@TableField("file_name") |
|||
private String fileName; |
|||
|
|||
/** |
|||
* 上传人 |
|||
*/ |
|||
@TableField("upload_by") |
|||
private String uploadBy; |
|||
|
|||
/** |
|||
* 上传时间 |
|||
*/ |
|||
@TableField("upload_time") |
|||
private Date uploadTime; |
|||
|
|||
// ==================== 备注 ==================== |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
@TableField("remark") |
|||
private String remark; |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
package com.xujie.sys.modules.pms.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.xujie.sys.modules.pms.data.MesTidEpcLogData; |
|||
import com.xujie.sys.modules.pms.entity.MesTidEpcLogEntity; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.annotations.Param; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* MES TID EPC日志Mapper接口 - rqrq |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@Mapper |
|||
public interface MesTidEpcLogMapper extends BaseMapper<MesTidEpcLogEntity> { |
|||
|
|||
/** |
|||
* @Description 分页查询日志列表 - rqrq |
|||
* @param page 分页对象 |
|||
* @param query 查询条件 |
|||
* @return IPage<MesTidEpcLogData> |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
IPage<MesTidEpcLogData> searchList(Page<MesTidEpcLogData> page, @Param("query") MesTidEpcLogData query); |
|||
|
|||
/** |
|||
* @Description 查询日志列表(不分页,用于导出)- rqrq |
|||
* @param query 查询条件 |
|||
* @return List<MesTidEpcLogData> |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
List<MesTidEpcLogData> getExportList(@Param("query") MesTidEpcLogData query); |
|||
|
|||
/** |
|||
* @Description 批量插入日志数据 - rqrq |
|||
* @param list 日志数据列表 |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
void batchInsert(@Param("list") List<MesTidEpcLogEntity> list); |
|||
|
|||
/** |
|||
* @Description 获取当天最大批次号 - rqrq |
|||
* @param dateStr 日期字符串(格式:YYYYMMDD) |
|||
* @return String 最大批次号 |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
String getMaxBatchNoByDate(@Param("dateStr") String dateStr); |
|||
} |
|||
@ -0,0 +1,364 @@ |
|||
package com.xujie.sys.modules.pms.service.Impl; |
|||
|
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.xujie.sys.common.utils.PageUtils; |
|||
import com.xujie.sys.modules.pms.data.MesTidEpcLogData; |
|||
import com.xujie.sys.modules.pms.entity.MesTidEpcLogEntity; |
|||
import com.xujie.sys.modules.pms.mapper.MesTidEpcLogMapper; |
|||
import com.xujie.sys.modules.pms.service.MesTidEpcLogService; |
|||
import jakarta.servlet.http.HttpServletResponse; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.poi.ss.usermodel.*; |
|||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
|
|||
import java.io.IOException; |
|||
import java.io.OutputStream; |
|||
import java.net.URLEncoder; |
|||
import java.text.ParseException; |
|||
import java.text.SimpleDateFormat; |
|||
import java.time.LocalDate; |
|||
import java.time.format.DateTimeFormatter; |
|||
import java.util.*; |
|||
|
|||
/** |
|||
* MES TID EPC日志Service实现类 - rqrq |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class MesTidEpcLogServiceImpl extends ServiceImpl<MesTidEpcLogMapper, MesTidEpcLogEntity> implements MesTidEpcLogService { |
|||
|
|||
@Autowired |
|||
private MesTidEpcLogMapper mesTidEpcLogMapper; |
|||
|
|||
/** |
|||
* SQL Server批量插入的最大参数限制 - rqrq |
|||
* 每条记录19个字段,2100/19 ≈ 110,为安全起见设为100 |
|||
*/ |
|||
private static final int BATCH_SIZE = 100; |
|||
|
|||
/** |
|||
* @Description 分页查询日志列表 - rqrq |
|||
* @param data 查询条件 |
|||
* @return PageUtils |
|||
* @author rqrq |
|||
*/ |
|||
@Override |
|||
public PageUtils searchList(MesTidEpcLogData data) { |
|||
log.info("开始查询MES TID EPC日志列表 - rqrq"); |
|||
|
|||
IPage<MesTidEpcLogData> resultList = mesTidEpcLogMapper.searchList( |
|||
new Page<>(data.getPage(), data.getLimit()), data); |
|||
PageUtils pageResult = new PageUtils(resultList); |
|||
|
|||
log.info("查询MES TID EPC日志列表完成,共{}条记录 - rqrq", resultList.getTotal()); |
|||
return pageResult; |
|||
} |
|||
|
|||
/** |
|||
* @Description 导入Excel数据 - rqrq |
|||
* @param file Excel文件 |
|||
* @param site 站点 |
|||
* @param buNo BU编码 |
|||
* @param remark 备注 |
|||
* @param username 上传人 |
|||
* @author rqrq |
|||
*/ |
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void importExcel(MultipartFile file, String site, String buNo, String remark, String username) { |
|||
log.info("开始导入MES TID EPC日志数据 - rqrq"); |
|||
log.info("站点: {}, BU: {}, 上传人: {} - rqrq", site, buNo, username); |
|||
|
|||
// 参数校验 - rqrq |
|||
if (!StringUtils.hasText(site)) { |
|||
throw new RuntimeException("站点不能为空"); |
|||
} |
|||
if (!StringUtils.hasText(buNo)) { |
|||
throw new RuntimeException("BU不能为空"); |
|||
} |
|||
if (file == null || file.isEmpty()) { |
|||
throw new RuntimeException("上传文件不能为空"); |
|||
} |
|||
|
|||
String fileName = file.getOriginalFilename(); |
|||
if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) { |
|||
throw new RuntimeException("文件格式错误,请上传Excel文件(.xlsx或.xls)"); |
|||
} |
|||
|
|||
try { |
|||
// 生成批次号 - rqrq |
|||
String batchNo = generateBatchNo(); |
|||
log.info("生成批次号: {} - rqrq", batchNo); |
|||
|
|||
// 统一的上传时间 - rqrq |
|||
Date uploadTime = new Date(); |
|||
|
|||
// 解析Excel文件 - rqrq |
|||
List<MesTidEpcLogEntity> dataList = parseExcel(file, site, buNo, remark, username, batchNo, fileName, uploadTime); |
|||
|
|||
if (dataList.isEmpty()) { |
|||
throw new RuntimeException("Excel文件中没有有效数据"); |
|||
} |
|||
|
|||
log.info("解析到 {} 条数据 - rqrq", dataList.size()); |
|||
|
|||
// 分批插入数据 - rqrq |
|||
for (int i = 0; i < dataList.size(); i += BATCH_SIZE) { |
|||
int endIndex = Math.min(i + BATCH_SIZE, dataList.size()); |
|||
List<MesTidEpcLogEntity> batch = dataList.subList(i, endIndex); |
|||
mesTidEpcLogMapper.batchInsert(batch); |
|||
log.info("已插入第 {}-{} 条数据 - rqrq", i + 1, endIndex); |
|||
} |
|||
|
|||
log.info("MES TID EPC日志数据导入完成,共 {} 条 - rqrq", dataList.size()); |
|||
|
|||
} catch (IOException e) { |
|||
log.error("解析Excel文件失败 - rqrq: {}", e.getMessage(), e); |
|||
throw new RuntimeException("解析Excel文件失败: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @Description 解析Excel文件 - rqrq |
|||
* @param file Excel文件 |
|||
* @param site 站点 |
|||
* @param buNo BU编码 |
|||
* @param remark 备注 |
|||
* @param username 上传人 |
|||
* @param batchNo 批次号 |
|||
* @param fileName 文件名 |
|||
* @param uploadTime 上传时间 |
|||
* @return List<MesTidEpcLogEntity> |
|||
* @author rqrq |
|||
*/ |
|||
private List<MesTidEpcLogEntity> parseExcel(MultipartFile file, String site, String buNo, |
|||
String remark, String username, String batchNo, |
|||
String fileName, Date uploadTime) throws IOException { |
|||
List<MesTidEpcLogEntity> dataList = new ArrayList<>(); |
|||
DataFormatter dataFormatter = new DataFormatter(); |
|||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
|||
|
|||
Workbook workbook = new XSSFWorkbook(file.getInputStream()); |
|||
Sheet sheet = workbook.getSheetAt(0); |
|||
|
|||
// 从第二行开始(跳过表头)- rqrq |
|||
int lastRowNum = sheet.getLastRowNum(); |
|||
for (int rowNum = 1; rowNum <= lastRowNum; rowNum++) { |
|||
Row row = sheet.getRow(rowNum); |
|||
if (row == null) { |
|||
continue; |
|||
} |
|||
|
|||
// 检查是否为空行 - rqrq |
|||
boolean isEmptyRow = true; |
|||
for (int cellNum = 0; cellNum < 12; cellNum++) { |
|||
Cell cell = row.getCell(cellNum); |
|||
if (cell != null && StringUtils.hasText(getCellValue(cell, dataFormatter))) { |
|||
isEmptyRow = false; |
|||
break; |
|||
} |
|||
} |
|||
if (isEmptyRow) { |
|||
continue; |
|||
} |
|||
|
|||
MesTidEpcLogEntity entity = new MesTidEpcLogEntity(); |
|||
|
|||
// 设置基础字段 - rqrq |
|||
entity.setSite(site); |
|||
entity.setBuNo(buNo); |
|||
entity.setBatchNo(batchNo); |
|||
entity.setFileName(fileName); |
|||
entity.setUploadBy(username); |
|||
entity.setUploadTime(uploadTime); |
|||
entity.setRemark(remark); |
|||
|
|||
// 解析Excel列 - rqrq |
|||
// 列0: 序号 |
|||
entity.setSeqNo(getCellValue(row.getCell(0), dataFormatter)); |
|||
// 列1: EPC |
|||
entity.setEpc(getCellValue(row.getCell(1), dataFormatter)); |
|||
// 列2: TID |
|||
entity.setTid(getCellValue(row.getCell(2), dataFormatter)); |
|||
// 列3: 用户区 |
|||
entity.setUserArea(getCellValue(row.getCell(3), dataFormatter)); |
|||
// 列4: LockiBtis |
|||
entity.setLockBits(getCellValue(row.getCell(4), dataFormatter)); |
|||
// 列5: 密匙 |
|||
entity.setSecretKey(getCellValue(row.getCell(5), dataFormatter)); |
|||
// 列6: 写码成功 |
|||
entity.setWriteSuccess(getCellValue(row.getCell(6), dataFormatter)); |
|||
// 列7: 读码成功 |
|||
entity.setReadSuccess(getCellValue(row.getCell(7), dataFormatter)); |
|||
// 列8: EPC锁定 |
|||
entity.setEpcLocked(getCellValue(row.getCell(8), dataFormatter)); |
|||
// 列9: 强度/读距 |
|||
entity.setSignalStrength(getCellValue(row.getCell(9), dataFormatter)); |
|||
// 列10: 时间 |
|||
Cell timeCell = row.getCell(10); |
|||
if (timeCell != null) { |
|||
if (timeCell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(timeCell)) { |
|||
entity.setScanTime(timeCell.getDateCellValue()); |
|||
} else { |
|||
String timeStr = getCellValue(timeCell, dataFormatter); |
|||
if (StringUtils.hasText(timeStr)) { |
|||
try { |
|||
entity.setScanTime(sdf.parse(timeStr)); |
|||
} catch (ParseException e) { |
|||
log.warn("第{}行时间格式解析失败: {} - rqrq", rowNum + 1, timeStr); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
// 列11: 计数 |
|||
entity.setCountInfo(getCellValue(row.getCell(11), dataFormatter)); |
|||
|
|||
dataList.add(entity); |
|||
} |
|||
|
|||
workbook.close(); |
|||
return dataList; |
|||
} |
|||
|
|||
/** |
|||
* @Description 获取单元格值 - rqrq |
|||
* @param cell 单元格 |
|||
* @param dataFormatter 数据格式化器 |
|||
* @return String |
|||
* @author rqrq |
|||
*/ |
|||
private String getCellValue(Cell cell, DataFormatter dataFormatter) { |
|||
if (cell == null) { |
|||
return ""; |
|||
} |
|||
return dataFormatter.formatCellValue(cell).trim(); |
|||
} |
|||
|
|||
/** |
|||
* @Description 生成批次号 - rqrq |
|||
* 格式:YYYYMMDD + 6位序列号,如 20250130000001 |
|||
* @return String 批次号 |
|||
* @author rqrq |
|||
*/ |
|||
private String generateBatchNo() { |
|||
String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); |
|||
String maxBatchNo = mesTidEpcLogMapper.getMaxBatchNoByDate(dateStr); |
|||
|
|||
int seq = 1; |
|||
if (StringUtils.hasText(maxBatchNo) && maxBatchNo.length() > 8) { |
|||
seq = Integer.parseInt(maxBatchNo.substring(8)) + 1; |
|||
} |
|||
|
|||
return dateStr + String.format("%06d", seq); |
|||
} |
|||
|
|||
/** |
|||
* @Description 导出数据列表 - rqrq |
|||
* @param data 查询条件 |
|||
* @return List<MesTidEpcLogData> |
|||
* @author rqrq |
|||
*/ |
|||
@Override |
|||
public List<MesTidEpcLogData> getExportList(MesTidEpcLogData data) { |
|||
log.info("开始获取MES TID EPC日志导出数据 - rqrq"); |
|||
return mesTidEpcLogMapper.getExportList(data); |
|||
} |
|||
|
|||
/** |
|||
* @Description 下载导入模板 - rqrq |
|||
* @param response HttpServletResponse |
|||
* @author rqrq |
|||
*/ |
|||
@Override |
|||
public void downloadTemplate(HttpServletResponse response) { |
|||
log.info("开始生成MES TID EPC日志导入模板 - rqrq"); |
|||
|
|||
try { |
|||
Workbook workbook = new XSSFWorkbook(); |
|||
Sheet sheet = workbook.createSheet("日志数据"); |
|||
|
|||
// 创建表头样式 - rqrq |
|||
CellStyle headerStyle = workbook.createCellStyle(); |
|||
Font headerFont = workbook.createFont(); |
|||
headerFont.setBold(true); |
|||
headerStyle.setFont(headerFont); |
|||
headerStyle.setAlignment(HorizontalAlignment.CENTER); |
|||
headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); |
|||
headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); |
|||
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); |
|||
headerStyle.setBorderBottom(BorderStyle.THIN); |
|||
headerStyle.setBorderTop(BorderStyle.THIN); |
|||
headerStyle.setBorderLeft(BorderStyle.THIN); |
|||
headerStyle.setBorderRight(BorderStyle.THIN); |
|||
|
|||
// 创建表头 - rqrq |
|||
Row headerRow = sheet.createRow(0); |
|||
String[] headers = {"序号", "EPC", "TID", "用户区", "LockiBtis", "密匙", |
|||
"写码成功", "读码成功", "EPC锁定", "强度/读距", "时间", "计数"}; |
|||
|
|||
for (int i = 0; i < headers.length; i++) { |
|||
Cell cell = headerRow.createCell(i); |
|||
cell.setCellValue(headers[i]); |
|||
cell.setCellStyle(headerStyle); |
|||
// 设置列宽 - rqrq |
|||
if (i == 1 || i == 2 || i == 3) { |
|||
sheet.setColumnWidth(i, 30 * 256); |
|||
} else if (i == 10) { |
|||
sheet.setColumnWidth(i, 20 * 256); |
|||
} else if (i == 11) { |
|||
sheet.setColumnWidth(i, 25 * 256); |
|||
} else { |
|||
sheet.setColumnWidth(i, 15 * 256); |
|||
} |
|||
} |
|||
|
|||
// 设置响应头 - rqrq |
|||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); |
|||
response.setCharacterEncoding("UTF-8"); |
|||
String templateName = URLEncoder.encode("TID_EPC日志导入模板.xlsx", "UTF-8"); |
|||
response.setHeader("Content-Disposition", "attachment;filename=" + templateName); |
|||
|
|||
// 输出文件 - rqrq |
|||
OutputStream outputStream = response.getOutputStream(); |
|||
workbook.write(outputStream); |
|||
outputStream.flush(); |
|||
workbook.close(); |
|||
|
|||
log.info("MES TID EPC日志导入模板生成完成 - rqrq"); |
|||
|
|||
} catch (IOException e) { |
|||
log.error("生成导入模板失败 - rqrq: {}", e.getMessage(), e); |
|||
throw new RuntimeException("生成导入模板失败: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @Description 删除日志数据 - rqrq |
|||
* @param ids ID数组 |
|||
* @author rqrq |
|||
*/ |
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void deleteByIds(Long[] ids) { |
|||
log.info("开始删除MES TID EPC日志数据,共{}条 - rqrq", ids.length); |
|||
|
|||
if (ids == null || ids.length == 0) { |
|||
throw new RuntimeException("请选择要删除的数据"); |
|||
} |
|||
|
|||
this.removeByIds(Arrays.asList(ids)); |
|||
|
|||
log.info("删除MES TID EPC日志数据完成 - rqrq"); |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
package com.xujie.sys.modules.pms.service; |
|||
|
|||
import com.xujie.sys.common.utils.PageUtils; |
|||
import com.xujie.sys.modules.pms.data.MesTidEpcLogData; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import jakarta.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* MES TID EPC日志Service接口 - rqrq |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
public interface MesTidEpcLogService { |
|||
|
|||
/** |
|||
* @Description 分页查询日志列表 - rqrq |
|||
* @param data 查询条件 |
|||
* @return PageUtils |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
PageUtils searchList(MesTidEpcLogData data); |
|||
|
|||
/** |
|||
* @Description 导入Excel数据 - rqrq |
|||
* @param file Excel文件 |
|||
* @param site 站点 |
|||
* @param buNo BU编码 |
|||
* @param remark 备注 |
|||
* @param username 上传人 |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
void importExcel(MultipartFile file, String site, String buNo, String remark, String username); |
|||
|
|||
/** |
|||
* @Description 导出数据列表 - rqrq |
|||
* @param data 查询条件 |
|||
* @return List<MesTidEpcLogData> |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
List<MesTidEpcLogData> getExportList(MesTidEpcLogData data); |
|||
|
|||
/** |
|||
* @Description 下载导入模板 - rqrq |
|||
* @param response HttpServletResponse |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
void downloadTemplate(HttpServletResponse response); |
|||
|
|||
/** |
|||
* @Description 删除日志数据 - rqrq |
|||
* @param ids ID数组 |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
void deleteByIds(Long[] ids); |
|||
} |
|||
@ -0,0 +1,170 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.xujie.sys.modules.pms.mapper.MesTidEpcLogMapper"> |
|||
|
|||
<!-- rqrq - 分页查询日志列表 --> |
|||
<select id="searchList" parameterType="MesTidEpcLogData" resultType="MesTidEpcLogData"> |
|||
SELECT |
|||
id, |
|||
site, |
|||
bu_no AS buNo, |
|||
seq_no AS seqNo, |
|||
epc, |
|||
tid, |
|||
user_area AS userArea, |
|||
lock_bits AS lockBits, |
|||
secret_key AS secretKey, |
|||
write_success AS writeSuccess, |
|||
read_success AS readSuccess, |
|||
epc_locked AS epcLocked, |
|||
signal_strength AS signalStrength, |
|||
scan_time AS scanTime, |
|||
count_info AS countInfo, |
|||
batch_no AS batchNo, |
|||
file_name AS fileName, |
|||
upload_by AS uploadBy, |
|||
upload_time AS uploadTime, |
|||
remark |
|||
FROM mes_tid_epc_log |
|||
WHERE 1 = 1 |
|||
<if test="query.site != null and query.site != ''"> |
|||
AND site = #{query.site} |
|||
</if> |
|||
<if test="query.buNo != null and query.buNo != ''"> |
|||
AND bu_no = #{query.buNo} |
|||
</if> |
|||
<if test="query.searchSeqNo != null and query.searchSeqNo != ''"> |
|||
AND seq_no LIKE '%' + #{query.searchSeqNo} + '%' |
|||
</if> |
|||
<if test="query.searchEpc != null and query.searchEpc != ''"> |
|||
AND epc LIKE '%' + #{query.searchEpc} + '%' |
|||
</if> |
|||
<if test="query.searchTid != null and query.searchTid != ''"> |
|||
AND tid LIKE '%' + #{query.searchTid} + '%' |
|||
</if> |
|||
<if test="query.searchUserArea != null and query.searchUserArea != ''"> |
|||
AND user_area LIKE '%' + #{query.searchUserArea} + '%' |
|||
</if> |
|||
<if test="query.scanTimeStart != null "> |
|||
AND scan_time >= #{query.scanTimeStart} |
|||
</if> |
|||
<if test="query.scanTimeEnd != null "> |
|||
AND scan_time <= #{query.scanTimeEnd} |
|||
</if> |
|||
<if test="query.searchBatchNo != null and query.searchBatchNo != ''"> |
|||
AND batch_no LIKE '%' + #{query.searchBatchNo} + '%' |
|||
</if> |
|||
ORDER BY upload_time DESC, id DESC |
|||
</select> |
|||
|
|||
<!-- rqrq - 查询日志列表(不分页,用于导出)--> |
|||
<select id="getExportList" parameterType="MesTidEpcLogData" resultType="MesTidEpcLogData"> |
|||
SELECT |
|||
id, |
|||
site, |
|||
bu_no AS buNo, |
|||
seq_no AS seqNo, |
|||
epc, |
|||
tid, |
|||
user_area AS userArea, |
|||
lock_bits AS lockBits, |
|||
secret_key AS secretKey, |
|||
write_success AS writeSuccess, |
|||
read_success AS readSuccess, |
|||
epc_locked AS epcLocked, |
|||
signal_strength AS signalStrength, |
|||
scan_time AS scanTime, |
|||
count_info AS countInfo, |
|||
batch_no AS batchNo, |
|||
file_name AS fileName, |
|||
upload_by AS uploadBy, |
|||
upload_time AS uploadTime, |
|||
remark |
|||
FROM mes_tid_epc_log |
|||
WHERE 1 = 1 |
|||
<if test="query.site != null and query.site != ''"> |
|||
AND site = #{query.site} |
|||
</if> |
|||
<if test="query.buNo != null and query.buNo != ''"> |
|||
AND bu_no = #{query.buNo} |
|||
</if> |
|||
<if test="query.searchSeqNo != null and query.searchSeqNo != ''"> |
|||
AND seq_no LIKE '%' + #{query.searchSeqNo} + '%' |
|||
</if> |
|||
<if test="query.searchEpc != null and query.searchEpc != ''"> |
|||
AND epc LIKE '%' + #{query.searchEpc} + '%' |
|||
</if> |
|||
<if test="query.searchTid != null and query.searchTid != ''"> |
|||
AND tid LIKE '%' + #{query.searchTid} + '%' |
|||
</if> |
|||
<if test="query.searchUserArea != null and query.searchUserArea != ''"> |
|||
AND user_area LIKE '%' + #{query.searchUserArea} + '%' |
|||
</if> |
|||
<if test="query.scanTimeStart != null and query.scanTimeStart != ''"> |
|||
AND scan_time >= #{query.scanTimeStart} |
|||
</if> |
|||
<if test="query.scanTimeEnd != null and query.scanTimeEnd != ''"> |
|||
AND scan_time <= #{query.scanTimeEnd} |
|||
</if> |
|||
<if test="query.searchBatchNo != null and query.searchBatchNo != ''"> |
|||
AND batch_no LIKE '%' + #{query.searchBatchNo} + '%' |
|||
</if> |
|||
ORDER BY upload_time DESC, id DESC |
|||
</select> |
|||
|
|||
<!-- rqrq - 批量插入日志数据 --> |
|||
<insert id="batchInsert" parameterType="java.util.List"> |
|||
INSERT INTO mes_tid_epc_log ( |
|||
site, |
|||
bu_no, |
|||
seq_no, |
|||
epc, |
|||
tid, |
|||
user_area, |
|||
lock_bits, |
|||
secret_key, |
|||
write_success, |
|||
read_success, |
|||
epc_locked, |
|||
signal_strength, |
|||
scan_time, |
|||
count_info, |
|||
batch_no, |
|||
file_name, |
|||
upload_by, |
|||
upload_time, |
|||
remark |
|||
) VALUES |
|||
<foreach collection="list" item="item" separator=","> |
|||
( |
|||
#{item.site}, |
|||
#{item.buNo}, |
|||
#{item.seqNo}, |
|||
#{item.epc}, |
|||
#{item.tid}, |
|||
#{item.userArea}, |
|||
#{item.lockBits}, |
|||
#{item.secretKey}, |
|||
#{item.writeSuccess}, |
|||
#{item.readSuccess}, |
|||
#{item.epcLocked}, |
|||
#{item.signalStrength}, |
|||
#{item.scanTime}, |
|||
#{item.countInfo}, |
|||
#{item.batchNo}, |
|||
#{item.fileName}, |
|||
#{item.uploadBy}, |
|||
#{item.uploadTime}, |
|||
#{item.remark} |
|||
) |
|||
</foreach> |
|||
</insert> |
|||
|
|||
<!-- rqrq - 获取当天最大批次号 --> |
|||
<select id="getMaxBatchNoByDate" resultType="java.lang.String"> |
|||
SELECT MAX(batch_no) |
|||
FROM mes_tid_epc_log |
|||
WHERE batch_no LIKE #{dateStr} + '%' |
|||
</select> |
|||
|
|||
</mapper> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue