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