mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-11 18:47:20 +00:00
@@ -56,6 +56,19 @@
|
||||
<artifactId>ruoyi-system-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons IO -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 测试依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package org.ruoyi.system.listener;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.common.core.utils.SpringUtils;
|
||||
import org.ruoyi.common.excel.core.ExcelListener;
|
||||
import org.ruoyi.common.excel.core.ExcelResult;
|
||||
import org.ruoyi.system.domain.MinUsagePeriod;
|
||||
import org.ruoyi.system.domain.bo.MinUsagePeriodBo;
|
||||
import org.ruoyi.system.domain.vo.MinUsagePeriodImportVo;
|
||||
import org.ruoyi.system.service.IMinUsagePeriodService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 最低使用年限表自定义导入监听器
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class MinUsagePeriodImportListener extends AnalysisEventListener<MinUsagePeriodImportVo> implements ExcelListener<MinUsagePeriodImportVo> {
|
||||
|
||||
private final IMinUsagePeriodService minUsagePeriodService;
|
||||
|
||||
private final Boolean isUpdateSupport;
|
||||
|
||||
private final String operName;
|
||||
|
||||
private final List<MinUsagePeriodImportVo> list = new ArrayList<>();
|
||||
|
||||
private int successNum = 0;
|
||||
private int failureNum = 0;
|
||||
private final StringBuilder successMsg = new StringBuilder();
|
||||
private final StringBuilder failureMsg = new StringBuilder();
|
||||
|
||||
public MinUsagePeriodImportListener(Boolean isUpdateSupport) {
|
||||
this.minUsagePeriodService = SpringUtils.getBean(IMinUsagePeriodService.class);
|
||||
this.isUpdateSupport = isUpdateSupport;
|
||||
this.operName = "系统";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(MinUsagePeriodImportVo data, AnalysisContext context) {
|
||||
list.add(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext context) {
|
||||
log.info("所有数据解析完成!");
|
||||
// 这里可以添加批量处理逻辑
|
||||
for (MinUsagePeriodImportVo data : list) {
|
||||
try {
|
||||
// 验证是否存在这个数据
|
||||
MinUsagePeriod existData = minUsagePeriodService.queryByGbCode(data.getGbCode());
|
||||
if (ObjectUtil.isNull(existData)) {
|
||||
minUsagePeriodService.insertByBo(BeanUtil.toBean(data, MinUsagePeriodBo.class));
|
||||
successNum++;
|
||||
successMsg.append("<br/>" + successNum + "、国标代码 " + data.getGbCode() + " 导入成功");
|
||||
} else if (isUpdateSupport) {
|
||||
BeanUtil.copyProperties(data, existData);
|
||||
minUsagePeriodService.updateByBo(BeanUtil.toBean(existData, MinUsagePeriodBo.class));
|
||||
successNum++;
|
||||
successMsg.append("<br/>" + successNum + "、国标代码 " + data.getGbCode() + " 更新成功");
|
||||
} else {
|
||||
failureNum++;
|
||||
failureMsg.append("<br/>" + failureNum + "、国标代码 " + data.getGbCode() + " 已存在");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failureNum++;
|
||||
String msg = "<br/>" + failureNum + "、国标代码 " + data.getGbCode() + " 导入失败:";
|
||||
failureMsg.append(msg + e.getMessage());
|
||||
log.error(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExcelResult<MinUsagePeriodImportVo> getExcelResult() {
|
||||
return new ExcelResult<MinUsagePeriodImportVo>() {
|
||||
@Override
|
||||
public List<MinUsagePeriodImportVo> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getErrorList() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnalysis() {
|
||||
if (failureNum > 0) {
|
||||
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
|
||||
return failureMsg.toString();
|
||||
} else {
|
||||
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
|
||||
return successMsg.toString();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package org.ruoyi.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.common.core.utils.MapstructUtils;
|
||||
import org.ruoyi.common.core.utils.StringUtils;
|
||||
import org.ruoyi.core.page.PageQuery;
|
||||
import org.ruoyi.core.page.TableDataInfo;
|
||||
import org.ruoyi.system.domain.MinUsagePeriod;
|
||||
import org.ruoyi.system.domain.bo.MinUsagePeriodBo;
|
||||
import org.ruoyi.system.domain.vo.MinUsagePeriodVo;
|
||||
import org.ruoyi.system.mapper.MinUsagePeriodMapper;
|
||||
import org.ruoyi.system.service.IMinUsagePeriodService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 最低使用年限表Service业务层处理
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class MinUsagePeriodServiceImpl implements IMinUsagePeriodService {
|
||||
|
||||
private final MinUsagePeriodMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询最低使用年限表
|
||||
*/
|
||||
@Override
|
||||
public MinUsagePeriodVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据国标代码查询最低使用年限表
|
||||
*/
|
||||
@Override
|
||||
public MinUsagePeriod queryByGbCode(String gbCode) {
|
||||
LambdaQueryWrapper<MinUsagePeriod> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MinUsagePeriod::getGbCode, gbCode);
|
||||
return baseMapper.selectOne(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最低使用年限表列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MinUsagePeriodVo> queryPageList(MinUsagePeriodBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MinUsagePeriod> lqw = buildQueryWrapper(bo);
|
||||
Page<MinUsagePeriodVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最低使用年限表列表
|
||||
*/
|
||||
@Override
|
||||
public List<MinUsagePeriodVo> queryList(MinUsagePeriodBo bo) {
|
||||
LambdaQueryWrapper<MinUsagePeriod> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MinUsagePeriod> buildQueryWrapper(MinUsagePeriodBo bo) {
|
||||
LambdaQueryWrapper<MinUsagePeriod> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getCategory()), MinUsagePeriod::getCategory, bo.getCategory());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getContent()), MinUsagePeriod::getContent, bo.getContent());
|
||||
lqw.eq(ObjectUtil.isNotNull(bo.getMinYears()), MinUsagePeriod::getMinYears, bo.getMinYears());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getGbCode()), MinUsagePeriod::getGbCode, bo.getGbCode());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增最低使用年限表
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(MinUsagePeriodBo bo) {
|
||||
MinUsagePeriod add = MapstructUtils.convert(bo, MinUsagePeriod.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改最低使用年限表
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(MinUsagePeriodBo bo) {
|
||||
MinUsagePeriod update = MapstructUtils.convert(bo, MinUsagePeriod.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MinUsagePeriod entity) {
|
||||
// 校验国标代码唯一性
|
||||
LambdaQueryWrapper<MinUsagePeriod> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MinUsagePeriod::getGbCode, entity.getGbCode());
|
||||
if (ObjectUtil.isNotNull(entity.getId())) {
|
||||
lqw.ne(MinUsagePeriod::getId, entity.getId());
|
||||
}
|
||||
boolean exists = baseMapper.exists(lqw);
|
||||
if (exists) {
|
||||
throw new RuntimeException("国标代码已存在");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除最低使用年限表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量导入最低使用年限表数据
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importData(List<MinUsagePeriodVo> dataList, Boolean isUpdateSupport, String operName) {
|
||||
if (ObjectUtil.isNull(dataList) || dataList.size() == 0) {
|
||||
throw new RuntimeException("导入数据不能为空!");
|
||||
}
|
||||
int successNum = 0;
|
||||
int failureNum = 0;
|
||||
StringBuilder successMsg = new StringBuilder();
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
for (MinUsagePeriodVo data : dataList) {
|
||||
try {
|
||||
// 验证是否存在这个数据
|
||||
LambdaQueryWrapper<MinUsagePeriod> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MinUsagePeriod::getGbCode, data.getGbCode());
|
||||
MinUsagePeriod existData = baseMapper.selectOne(lqw);
|
||||
if (ObjectUtil.isNull(existData)) {
|
||||
MinUsagePeriod addData = MapstructUtils.convert(data, MinUsagePeriod.class);
|
||||
baseMapper.insert(addData);
|
||||
successNum++;
|
||||
successMsg.append("<br/>" + successNum + "、国标代码 " + data.getGbCode() + " 导入成功");
|
||||
} else if (isUpdateSupport) {
|
||||
MapstructUtils.convert(data, existData);
|
||||
baseMapper.updateById(existData);
|
||||
successNum++;
|
||||
successMsg.append("<br/>" + successNum + "、国标代码 " + data.getGbCode() + " 更新成功");
|
||||
} else {
|
||||
failureNum++;
|
||||
failureMsg.append("<br/>" + failureNum + "、国标代码 " + data.getGbCode() + " 已存在");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failureNum++;
|
||||
String msg = "<br/>" + failureNum + "、国标代码 " + data.getGbCode() + " 导入失败:";
|
||||
failureMsg.append(msg + e.getMessage());
|
||||
log.error(msg, e);
|
||||
}
|
||||
}
|
||||
if (failureNum > 0) {
|
||||
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
} else {
|
||||
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
|
||||
}
|
||||
return successMsg.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.ruoyi.system.domain.MinUsagePeriod;
|
||||
import org.ruoyi.system.domain.vo.MinUsagePeriodImportVo;
|
||||
import org.ruoyi.system.listener.MinUsagePeriodImportListener;
|
||||
import org.ruoyi.system.mapper.MinUsagePeriodMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据库导入测试
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootTest(classes = {org.ruoyi.RuoYiAIApplication.class})
|
||||
@ActiveProfiles("test")
|
||||
public class DatabaseImportTest {
|
||||
|
||||
@Autowired
|
||||
private MinUsagePeriodMapper minUsagePeriodMapper;
|
||||
|
||||
@Autowired
|
||||
private IMinUsagePeriodService minUsagePeriodService;
|
||||
|
||||
/**
|
||||
* Excel文件路径
|
||||
*/
|
||||
private static final String EXCEL_FILE_PATH = "E:/z. WorkSpace/ruoyi-ai/workspace/教育部直属高校固定资产最低使用年限表.xlsx";
|
||||
|
||||
/**
|
||||
* 测试Excel数据导入到数据库
|
||||
*/
|
||||
@Test
|
||||
@Transactional
|
||||
public void testExcelImportToDatabase() {
|
||||
try {
|
||||
log.info("=== 开始Excel数据导入到数据库测试 ===");
|
||||
|
||||
// 1. 清空测试数据
|
||||
log.info("1. 清空测试数据...");
|
||||
minUsagePeriodMapper.delete(null);
|
||||
log.info(" 清空完成");
|
||||
|
||||
// 2. 读取Excel文件
|
||||
log.info("2. 读取Excel文件...");
|
||||
File excelFile = new File(EXCEL_FILE_PATH);
|
||||
if (!excelFile.exists()) {
|
||||
log.error("Excel文件不存在: {}", EXCEL_FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
List<MinUsagePeriodImportVo> dataList;
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
dataList = EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
}
|
||||
log.info(" 读取到 {} 条数据", dataList.size());
|
||||
|
||||
// 3. 处理数据(填充固定资产类别)
|
||||
log.info("3. 处理数据...");
|
||||
processData(dataList);
|
||||
log.info(" 数据处理完成");
|
||||
|
||||
// 4. 批量插入数据库
|
||||
log.info("4. 批量插入数据库...");
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
|
||||
for (MinUsagePeriodImportVo importVo : dataList) {
|
||||
try {
|
||||
// 转换为实体对象
|
||||
MinUsagePeriod entity = convertToEntity(importVo);
|
||||
|
||||
// 插入数据库
|
||||
minUsagePeriodMapper.insert(entity);
|
||||
successCount++;
|
||||
|
||||
if (successCount <= 5) {
|
||||
log.info(" 插入成功: {} - {}", entity.getContent(), entity.getGbCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failCount++;
|
||||
log.error(" 插入失败: {} - {}", importVo.getContent(), importVo.getGbCode(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info(" 插入完成: 成功 {} 条, 失败 {} 条", successCount, failCount);
|
||||
|
||||
// 5. 验证数据库中的数据
|
||||
log.info("5. 验证数据库中的数据...");
|
||||
List<MinUsagePeriod> dbData = minUsagePeriodMapper.selectList(null);
|
||||
log.info(" 数据库中共有 {} 条记录", dbData.size());
|
||||
|
||||
// 显示前10条数据
|
||||
for (int i = 0; i < Math.min(10, dbData.size()); i++) {
|
||||
MinUsagePeriod data = dbData.get(i);
|
||||
log.info(" 第{}条: 类别={}, 内容={}, 年限={}, 国标代码={}",
|
||||
i + 1, data.getCategory(), data.getContent(), data.getMinYears(), data.getGbCode());
|
||||
}
|
||||
|
||||
// 6. 验证数据完整性
|
||||
log.info("6. 验证数据完整性...");
|
||||
validateDatabaseData(dbData);
|
||||
|
||||
log.info("=== Excel数据导入到数据库测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Excel数据导入到数据库测试失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试使用Service层导入数据
|
||||
*/
|
||||
@Test
|
||||
@Transactional
|
||||
public void testServiceImportData() {
|
||||
try {
|
||||
log.info("=== 开始Service层导入数据测试 ===");
|
||||
|
||||
// 1. 清空测试数据
|
||||
log.info("1. 清空测试数据...");
|
||||
minUsagePeriodMapper.delete(null);
|
||||
log.info(" 清空完成");
|
||||
|
||||
// 2. 使用Service层导入数据
|
||||
log.info("2. 使用Service层导入数据...");
|
||||
File excelFile = new File(EXCEL_FILE_PATH);
|
||||
if (!excelFile.exists()) {
|
||||
log.error("Excel文件不存在: {}", EXCEL_FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
// 使用自定义监听器导入数据
|
||||
MinUsagePeriodImportListener listener = new MinUsagePeriodImportListener(true);
|
||||
|
||||
EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.registerReadListener(listener)
|
||||
.sheet()
|
||||
.doRead();
|
||||
|
||||
log.info(" Service层导入完成");
|
||||
}
|
||||
|
||||
// 3. 验证数据库中的数据
|
||||
log.info("3. 验证数据库中的数据...");
|
||||
List<MinUsagePeriod> dbData = minUsagePeriodMapper.selectList(null);
|
||||
log.info(" 数据库中共有 {} 条记录", dbData.size());
|
||||
|
||||
// 显示前10条数据
|
||||
for (int i = 0; i < Math.min(10, dbData.size()); i++) {
|
||||
MinUsagePeriod data = dbData.get(i);
|
||||
log.info(" 第{}条: 类别={}, 内容={}, 年限={}, 国标代码={}",
|
||||
i + 1, data.getCategory(), data.getContent(), data.getMinYears(), data.getGbCode());
|
||||
}
|
||||
|
||||
log.info("=== Service层导入数据测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Service层导入数据测试失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据,填充固定资产类别
|
||||
*/
|
||||
private void processData(List<MinUsagePeriodImportVo> dataList) {
|
||||
String currentCategory = null;
|
||||
|
||||
for (MinUsagePeriodImportVo data : dataList) {
|
||||
// 如果当前行有固定资产类别,更新当前类别
|
||||
if (data.getCategory() != null && !data.getCategory().trim().isEmpty()) {
|
||||
currentCategory = data.getCategory().trim();
|
||||
}
|
||||
|
||||
// 如果当前行没有固定资产类别,使用当前类别
|
||||
if (data.getCategory() == null || data.getCategory().trim().isEmpty()) {
|
||||
data.setCategory(currentCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为实体对象
|
||||
*/
|
||||
private MinUsagePeriod convertToEntity(MinUsagePeriodImportVo importVo) {
|
||||
MinUsagePeriod entity = new MinUsagePeriod();
|
||||
entity.setCategory(importVo.getCategory());
|
||||
entity.setContent(importVo.getContent());
|
||||
entity.setMinYears(importVo.getMinYears());
|
||||
entity.setGbCode(importVo.getGbCode());
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数据库中的数据
|
||||
*/
|
||||
private void validateDatabaseData(List<MinUsagePeriod> dbData) {
|
||||
log.info(" 数据验证结果:");
|
||||
log.info(" - 总记录数: {}", dbData.size());
|
||||
|
||||
// 统计各类别的数量
|
||||
long categoryCount = dbData.stream()
|
||||
.filter(data -> data.getCategory() != null && !data.getCategory().trim().isEmpty())
|
||||
.count();
|
||||
log.info(" - 有固定资产类别的记录: {}/{}", categoryCount, dbData.size());
|
||||
|
||||
// 统计各年限的数量
|
||||
long yearsCount = dbData.stream()
|
||||
.filter(data -> data.getMinYears() != null)
|
||||
.count();
|
||||
log.info(" - 有最低使用年限的记录: {}/{}", yearsCount, dbData.size());
|
||||
|
||||
// 统计各国标代码的数量
|
||||
long gbCodeCount = dbData.stream()
|
||||
.filter(data -> data.getGbCode() != null && !data.getGbCode().trim().isEmpty())
|
||||
.count();
|
||||
log.info(" - 有国标代码的记录: {}/{}", gbCodeCount, dbData.size());
|
||||
|
||||
// 检查重复的国标代码
|
||||
long uniqueGbCodeCount = dbData.stream()
|
||||
.filter(data -> data.getGbCode() != null && !data.getGbCode().trim().isEmpty())
|
||||
.map(MinUsagePeriod::getGbCode)
|
||||
.distinct()
|
||||
.count();
|
||||
log.info(" - 唯一国标代码数量: {}", uniqueGbCodeCount);
|
||||
|
||||
if (uniqueGbCodeCount != gbCodeCount) {
|
||||
log.warn(" - 发现重复的国标代码!");
|
||||
} else {
|
||||
log.info(" - 国标代码唯一性检查通过");
|
||||
}
|
||||
|
||||
// 数据质量评估
|
||||
if (categoryCount == dbData.size() &&
|
||||
yearsCount == dbData.size() &&
|
||||
gbCodeCount == dbData.size()) {
|
||||
log.info(" - 数据质量: 优秀 (所有字段都完整)");
|
||||
} else if (yearsCount == dbData.size() && gbCodeCount == dbData.size()) {
|
||||
log.info(" - 数据质量: 良好 (核心字段完整)");
|
||||
} else {
|
||||
log.warn(" - 数据质量: 需要改进 (存在缺失字段)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.ruoyi.system.mapper.MinUsagePeriodMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Statement;
|
||||
|
||||
/**
|
||||
* 数据库初始化测试
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootTest(classes = {org.ruoyi.RuoYiAIApplication.class})
|
||||
@ActiveProfiles("test")
|
||||
public class DatabaseInitTest {
|
||||
|
||||
@Autowired
|
||||
private MinUsagePeriodMapper minUsagePeriodMapper;
|
||||
|
||||
/**
|
||||
* 测试数据库连接和表创建
|
||||
*/
|
||||
@Test
|
||||
public void testDatabaseConnectionAndTableCreation() {
|
||||
try {
|
||||
log.info("=== 开始数据库连接和表创建测试 ===");
|
||||
|
||||
// 1. 测试数据库连接
|
||||
log.info("1. 测试数据库连接...");
|
||||
String url = "jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
|
||||
String username = "root";
|
||||
String password = "666666";
|
||||
|
||||
try (Connection connection = DriverManager.getConnection(url, username, password)) {
|
||||
log.info(" 数据库连接成功");
|
||||
|
||||
// 2. 检查表是否存在
|
||||
log.info("2. 检查min_usage_period表是否存在...");
|
||||
boolean tableExists = checkTableExists(connection);
|
||||
|
||||
if (!tableExists) {
|
||||
log.info(" 表不存在,开始创建表...");
|
||||
createTable(connection);
|
||||
log.info(" 表创建完成");
|
||||
} else {
|
||||
log.info(" 表已存在");
|
||||
}
|
||||
|
||||
// 3. 测试Mapper
|
||||
log.info("3. 测试Mapper...");
|
||||
try {
|
||||
Long count = minUsagePeriodMapper.selectCount(null);
|
||||
log.info(" 当前表中有 {} 条记录", count);
|
||||
} catch (Exception e) {
|
||||
log.error(" Mapper测试失败", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
log.info("=== 数据库连接和表创建测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("数据库连接和表创建测试失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查表是否存在
|
||||
*/
|
||||
private boolean checkTableExists(Connection connection) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.executeQuery("SELECT 1 FROM min_usage_period LIMIT 1");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建表
|
||||
*/
|
||||
private void createTable(Connection connection) {
|
||||
String createTableSql = """
|
||||
CREATE TABLE `min_usage_period` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`category` varchar(100) NOT NULL COMMENT '固定资产类别',
|
||||
`content` varchar(200) NOT NULL COMMENT '内容',
|
||||
`min_years` int(11) NOT NULL COMMENT '最低使用年限(年)',
|
||||
`gb_code` varchar(20) NOT NULL COMMENT '国标代码',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_gb_code` (`gb_code`),
|
||||
KEY `idx_category` (`category`),
|
||||
KEY `idx_content` (`content`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='最低使用年限表'
|
||||
""";
|
||||
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(createTableSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.ruoyi.system.domain.vo.MinUsagePeriodImportVo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 简单的Excel导入测试(不依赖Spring Boot)
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExcelImportSimpleTest {
|
||||
|
||||
/**
|
||||
* Excel文件路径
|
||||
*/
|
||||
private static final String EXCEL_FILE_PATH = "E:/z. WorkSpace/ruoyi-ai/workspace/教育部直属高校固定资产最低使用年限表.xlsx";
|
||||
|
||||
public static void main(String[] args) {
|
||||
ExcelImportSimpleTest test = new ExcelImportSimpleTest();
|
||||
test.testExcelFileRead();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试Excel文件读取和解析
|
||||
*/
|
||||
@Test
|
||||
public void testExcelFileRead() {
|
||||
try {
|
||||
File excelFile = new File(EXCEL_FILE_PATH);
|
||||
|
||||
if (!excelFile.exists()) {
|
||||
log.error("Excel文件不存在: {}", EXCEL_FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("=== Excel文件信息 ===");
|
||||
log.info("文件路径: {}", excelFile.getAbsolutePath());
|
||||
log.info("文件大小: {} bytes", excelFile.length());
|
||||
log.info("文件是否存在: {}", excelFile.exists());
|
||||
log.info("文件是否可读: {}", excelFile.canRead());
|
||||
|
||||
// 使用EasyExcel直接读取
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
List<MinUsagePeriodImportVo> dataList = EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
log.info("=== 读取结果 ===");
|
||||
log.info("EasyExcel直接读取到 {} 条数据", dataList.size());
|
||||
|
||||
// 打印前10条数据
|
||||
for (int i = 0; i < Math.min(10, dataList.size()); i++) {
|
||||
MinUsagePeriodImportVo data = dataList.get(i);
|
||||
log.info("第{}条: 类别={}, 内容={}, 年限={}, 国标代码={}",
|
||||
i + 1, data.getCategory(), data.getContent(), data.getMinYears(), data.getGbCode());
|
||||
}
|
||||
|
||||
// 验证数据完整性
|
||||
validateData(dataList);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Excel文件读取测试失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数据完整性
|
||||
*/
|
||||
private void validateData(List<MinUsagePeriodImportVo> dataList) {
|
||||
log.info("=== 数据验证结果 ===");
|
||||
|
||||
int validCategoryCount = 0;
|
||||
int validContentCount = 0;
|
||||
int validMinYearsCount = 0;
|
||||
int validGbCodeCount = 0;
|
||||
|
||||
for (MinUsagePeriodImportVo data : dataList) {
|
||||
if (data.getCategory() != null && !data.getCategory().trim().isEmpty()) {
|
||||
validCategoryCount++;
|
||||
}
|
||||
if (data.getContent() != null && !data.getContent().trim().isEmpty()) {
|
||||
validContentCount++;
|
||||
}
|
||||
if (data.getMinYears() != null) {
|
||||
validMinYearsCount++;
|
||||
}
|
||||
if (data.getGbCode() != null && !data.getGbCode().trim().isEmpty()) {
|
||||
validGbCodeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("总行数: {}", dataList.size());
|
||||
log.info("有效固定资产类别: {}/{}", validCategoryCount, dataList.size());
|
||||
log.info("有效内容: {}/{}", validContentCount, dataList.size());
|
||||
log.info("有效最低使用年限: {}/{}", validMinYearsCount, dataList.size());
|
||||
log.info("有效国标代码: {}/{}", validGbCodeCount, dataList.size());
|
||||
|
||||
// 检查重复的国标代码
|
||||
long uniqueGbCodeCount = dataList.stream()
|
||||
.filter(data -> data.getGbCode() != null && !data.getGbCode().trim().isEmpty())
|
||||
.map(MinUsagePeriodImportVo::getGbCode)
|
||||
.distinct()
|
||||
.count();
|
||||
|
||||
log.info("唯一国标代码数量: {}", uniqueGbCodeCount);
|
||||
|
||||
if (uniqueGbCodeCount != validGbCodeCount) {
|
||||
log.warn("发现重复的国标代码!");
|
||||
}
|
||||
|
||||
// 检查数据质量
|
||||
if (validCategoryCount == dataList.size() &&
|
||||
validContentCount == dataList.size() &&
|
||||
validMinYearsCount == dataList.size() &&
|
||||
validGbCodeCount == dataList.size()) {
|
||||
log.info("✓ 数据质量检查通过,所有字段都完整");
|
||||
} else {
|
||||
log.warn("✗ 数据质量检查未通过,存在缺失字段");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试Excel文件格式
|
||||
*/
|
||||
@Test
|
||||
public void testExcelFormat() {
|
||||
try {
|
||||
File excelFile = new File(EXCEL_FILE_PATH);
|
||||
|
||||
if (!excelFile.exists()) {
|
||||
log.error("Excel文件不存在: {}", EXCEL_FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("=== 开始Excel格式测试 ===");
|
||||
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
// 测试读取第一行(标题行)
|
||||
List<MinUsagePeriodImportVo> dataList = EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
if (!dataList.isEmpty()) {
|
||||
MinUsagePeriodImportVo firstData = dataList.get(0);
|
||||
log.info("第一行数据示例:");
|
||||
log.info("- 固定资产类别: {}", firstData.getCategory());
|
||||
log.info("- 内容: {}", firstData.getContent());
|
||||
log.info("- 最低使用年限: {}", firstData.getMinYears());
|
||||
log.info("- 国标代码: {}", firstData.getGbCode());
|
||||
}
|
||||
|
||||
log.info("Excel格式测试完成,共读取 {} 行数据", dataList.size());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Excel格式测试失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.ruoyi.system.domain.MinUsagePeriod;
|
||||
import org.ruoyi.system.domain.vo.MinUsagePeriodImportVo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 简单数据库测试(不依赖Spring Boot)
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class SimpleDatabaseTest {
|
||||
|
||||
/**
|
||||
* Excel文件路径
|
||||
*/
|
||||
private static final String EXCEL_FILE_PATH = "E:/z. WorkSpace/ruoyi-ai/workspace/教育部直属高校固定资产最低使用年限表.xlsx";
|
||||
|
||||
/**
|
||||
* 数据库连接信息
|
||||
*/
|
||||
private static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
|
||||
private static final String DB_USERNAME = "root";
|
||||
private static final String DB_PASSWORD = "666666";
|
||||
|
||||
/**
|
||||
* 测试Excel数据导入到数据库
|
||||
*/
|
||||
@Test
|
||||
public void testExcelImportToDatabase() {
|
||||
try {
|
||||
log.info("=== 开始Excel数据导入到数据库测试 ===");
|
||||
|
||||
// 1. 连接数据库
|
||||
log.info("1. 连接数据库...");
|
||||
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD)) {
|
||||
log.info(" 数据库连接成功");
|
||||
|
||||
// 2. 创建表(如果不存在)
|
||||
log.info("2. 创建表(如果不存在)...");
|
||||
createTableIfNotExists(connection);
|
||||
log.info(" 表创建完成");
|
||||
|
||||
// 3. 清空测试数据
|
||||
log.info("3. 清空测试数据...");
|
||||
clearTestData(connection);
|
||||
log.info(" 清空完成");
|
||||
|
||||
// 4. 读取Excel文件
|
||||
log.info("4. 读取Excel文件...");
|
||||
List<MinUsagePeriodImportVo> dataList = readExcelFile();
|
||||
log.info(" 读取到 {} 条数据", dataList.size());
|
||||
|
||||
// 5. 处理数据(填充固定资产类别)
|
||||
log.info("5. 处理数据...");
|
||||
processData(dataList);
|
||||
log.info(" 数据处理完成");
|
||||
|
||||
// 6. 批量插入数据库
|
||||
log.info("6. 批量插入数据库...");
|
||||
int successCount = insertDataToDatabase(connection, dataList);
|
||||
log.info(" 插入完成: 成功 {} 条", successCount);
|
||||
|
||||
// 7. 验证数据库中的数据
|
||||
log.info("7. 验证数据库中的数据...");
|
||||
int dbCount = getDatabaseRecordCount(connection);
|
||||
log.info(" 数据库中共有 {} 条记录", dbCount);
|
||||
|
||||
// 8. 显示部分数据
|
||||
log.info("8. 显示部分数据...");
|
||||
showSampleData(connection);
|
||||
|
||||
}
|
||||
|
||||
log.info("=== Excel数据导入到数据库测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Excel数据导入到数据库测试失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建表(如果不存在)
|
||||
*/
|
||||
private void createTableIfNotExists(Connection connection) throws Exception {
|
||||
String createTableSql = """
|
||||
CREATE TABLE IF NOT EXISTS `min_usage_period` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`category` varchar(100) NOT NULL COMMENT '固定资产类别',
|
||||
`content` varchar(200) NOT NULL COMMENT '内容',
|
||||
`min_years` int(11) NOT NULL COMMENT '最低使用年限(年)',
|
||||
`gb_code` varchar(20) NOT NULL COMMENT '国标代码',
|
||||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_gb_code` (`gb_code`),
|
||||
KEY `idx_category` (`category`),
|
||||
KEY `idx_content` (`content`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='最低使用年限表'
|
||||
""";
|
||||
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(createTableSql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空测试数据
|
||||
*/
|
||||
private void clearTestData(Connection connection) throws Exception {
|
||||
String deleteSql = "DELETE FROM min_usage_period";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.executeUpdate(deleteSql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Excel文件
|
||||
*/
|
||||
private List<MinUsagePeriodImportVo> readExcelFile() throws Exception {
|
||||
File excelFile = new File(EXCEL_FILE_PATH);
|
||||
if (!excelFile.exists()) {
|
||||
throw new RuntimeException("Excel文件不存在: " + EXCEL_FILE_PATH);
|
||||
}
|
||||
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
return EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据,填充固定资产类别
|
||||
*/
|
||||
private void processData(List<MinUsagePeriodImportVo> dataList) {
|
||||
String currentCategory = null;
|
||||
|
||||
for (MinUsagePeriodImportVo data : dataList) {
|
||||
// 如果当前行有固定资产类别,更新当前类别
|
||||
if (data.getCategory() != null && !data.getCategory().trim().isEmpty()) {
|
||||
currentCategory = data.getCategory().trim();
|
||||
}
|
||||
|
||||
// 如果当前行没有固定资产类别,使用当前类别
|
||||
if (data.getCategory() == null || data.getCategory().trim().isEmpty()) {
|
||||
data.setCategory(currentCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入数据到数据库
|
||||
*/
|
||||
private int insertDataToDatabase(Connection connection, List<MinUsagePeriodImportVo> dataList) throws Exception {
|
||||
String insertSql = "INSERT INTO min_usage_period (category, content, min_years, gb_code) VALUES (?, ?, ?, ?)";
|
||||
|
||||
int successCount = 0;
|
||||
try (PreparedStatement statement = connection.prepareStatement(insertSql)) {
|
||||
for (MinUsagePeriodImportVo data : dataList) {
|
||||
try {
|
||||
statement.setString(1, data.getCategory());
|
||||
statement.setString(2, data.getContent());
|
||||
statement.setInt(3, data.getMinYears());
|
||||
statement.setString(4, data.getGbCode());
|
||||
|
||||
statement.executeUpdate();
|
||||
successCount++;
|
||||
|
||||
if (successCount <= 5) {
|
||||
log.info(" 插入成功: {} - {}", data.getContent(), data.getGbCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(" 插入失败: {} - {}", data.getContent(), data.getGbCode(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return successCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库记录数
|
||||
*/
|
||||
private int getDatabaseRecordCount(Connection connection) throws Exception {
|
||||
String countSql = "SELECT COUNT(*) FROM min_usage_period";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
var resultSet = statement.executeQuery(countSql);
|
||||
if (resultSet.next()) {
|
||||
return resultSet.getInt(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示部分数据
|
||||
*/
|
||||
private void showSampleData(Connection connection) throws Exception {
|
||||
String selectSql = "SELECT * FROM min_usage_period LIMIT 10";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
var resultSet = statement.executeQuery(selectSql);
|
||||
int count = 0;
|
||||
while (resultSet.next() && count < 10) {
|
||||
count++;
|
||||
String category = resultSet.getString("category");
|
||||
String content = resultSet.getString("content");
|
||||
int minYears = resultSet.getInt("min_years");
|
||||
String gbCode = resultSet.getString("gb_code");
|
||||
|
||||
log.info(" 第{}条: 类别={}, 内容={}, 年限={}, 国标代码={}",
|
||||
count, category, content, minYears, gbCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.system.domain.vo.MinUsagePeriodImportVo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 简单的Excel导入测试(不依赖Spring Boot)
|
||||
*
|
||||
* @author cass
|
||||
* @date 2025-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class SimpleExcelImportTest {
|
||||
|
||||
/**
|
||||
* 测试Excel文件读取
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SimpleExcelImportTest test = new SimpleExcelImportTest();
|
||||
test.testExcelFileRead();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试Excel文件读取和解析
|
||||
*/
|
||||
public void testExcelFileRead() {
|
||||
try {
|
||||
String excelPath = "workspace/教育部直属高校固定资产最低使用年限表.xlsx";
|
||||
File excelFile = new File(excelPath);
|
||||
|
||||
if (!excelFile.exists()) {
|
||||
log.error("Excel文件不存在: {}", excelPath);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Excel文件信息:");
|
||||
log.info("文件路径: {}", excelFile.getAbsolutePath());
|
||||
log.info("文件大小: {} bytes", excelFile.length());
|
||||
log.info("文件是否存在: {}", excelFile.exists());
|
||||
log.info("文件是否可读: {}", excelFile.canRead());
|
||||
|
||||
// 使用EasyExcel直接读取
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
List<MinUsagePeriodImportVo> dataList = EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
log.info("EasyExcel直接读取到 {} 条数据", dataList.size());
|
||||
|
||||
// 打印所有数据
|
||||
for (int i = 0; i < dataList.size(); i++) {
|
||||
MinUsagePeriodImportVo data = dataList.get(i);
|
||||
log.info("第{}条: 类别={}, 内容={}, 年限={}, 国标代码={}",
|
||||
i + 1, data.getCategory(), data.getContent(), data.getMinYears(), data.getGbCode());
|
||||
}
|
||||
|
||||
// 验证数据完整性
|
||||
validateData(dataList);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Excel文件读取测试失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数据完整性
|
||||
*/
|
||||
private void validateData(List<MinUsagePeriodImportVo> dataList) {
|
||||
log.info("开始数据验证...");
|
||||
|
||||
int validCategoryCount = 0;
|
||||
int validContentCount = 0;
|
||||
int validMinYearsCount = 0;
|
||||
int validGbCodeCount = 0;
|
||||
|
||||
for (MinUsagePeriodImportVo data : dataList) {
|
||||
if (data.getCategory() != null && !data.getCategory().trim().isEmpty()) {
|
||||
validCategoryCount++;
|
||||
}
|
||||
if (data.getContent() != null && !data.getContent().trim().isEmpty()) {
|
||||
validContentCount++;
|
||||
}
|
||||
if (data.getMinYears() != null) {
|
||||
validMinYearsCount++;
|
||||
}
|
||||
if (data.getGbCode() != null && !data.getGbCode().trim().isEmpty()) {
|
||||
validGbCodeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("数据验证结果:");
|
||||
log.info("- 总行数: {}", dataList.size());
|
||||
log.info("- 有效固定资产类别: {}/{}", validCategoryCount, dataList.size());
|
||||
log.info("- 有效内容: {}/{}", validContentCount, dataList.size());
|
||||
log.info("- 有效最低使用年限: {}/{}", validMinYearsCount, dataList.size());
|
||||
log.info("- 有效国标代码: {}/{}", validGbCodeCount, dataList.size());
|
||||
|
||||
// 检查重复的国标代码
|
||||
long uniqueGbCodeCount = dataList.stream()
|
||||
.filter(data -> data.getGbCode() != null && !data.getGbCode().trim().isEmpty())
|
||||
.map(MinUsagePeriodImportVo::getGbCode)
|
||||
.distinct()
|
||||
.count();
|
||||
|
||||
log.info("- 唯一国标代码数量: {}", uniqueGbCodeCount);
|
||||
|
||||
if (uniqueGbCodeCount != validGbCodeCount) {
|
||||
log.warn("发现重复的国标代码!");
|
||||
}
|
||||
|
||||
// 检查数据质量
|
||||
if (validCategoryCount == dataList.size() &&
|
||||
validContentCount == dataList.size() &&
|
||||
validMinYearsCount == dataList.size() &&
|
||||
validGbCodeCount == dataList.size()) {
|
||||
log.info("✓ 数据质量检查通过,所有字段都完整");
|
||||
} else {
|
||||
log.warn("✗ 数据质量检查未通过,存在缺失字段");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试Excel文件格式
|
||||
*/
|
||||
public void testExcelFormat() {
|
||||
try {
|
||||
String excelPath = "workspace/教育部直属高校固定资产最低使用年限表.xlsx";
|
||||
File excelFile = new File(excelPath);
|
||||
|
||||
if (!excelFile.exists()) {
|
||||
log.error("Excel文件不存在: {}", excelPath);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("开始Excel格式测试...");
|
||||
|
||||
try (InputStream inputStream = new FileInputStream(excelFile)) {
|
||||
// 测试读取第一行(标题行)
|
||||
List<MinUsagePeriodImportVo> dataList = EasyExcel.read(inputStream)
|
||||
.head(MinUsagePeriodImportVo.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
if (!dataList.isEmpty()) {
|
||||
MinUsagePeriodImportVo firstData = dataList.get(0);
|
||||
log.info("第一行数据示例:");
|
||||
log.info("- 固定资产类别: {}", firstData.getCategory());
|
||||
log.info("- 内容: {}", firstData.getContent());
|
||||
log.info("- 最低使用年限: {}", firstData.getMinYears());
|
||||
log.info("- 国标代码: {}", firstData.getGbCode());
|
||||
}
|
||||
|
||||
log.info("Excel格式测试完成,共读取 {} 行数据", dataList.size());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Excel格式测试失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user