|
|
@@ -16,15 +16,28 @@ import com.lc.ibps.hrm.service.PersonnelManagementService;
|
|
|
import com.lc.ibps.org.api.IPartyPositionService;
|
|
|
import com.lc.ibps.org.party.persistence.entity.PartyPositionPo;
|
|
|
import com.lc.ibps.sysdata.dao.UpdateDataTableDao;
|
|
|
+import com.lc.ibps.vo.ImportError;
|
|
|
+import com.lc.ibps.vo.ImportResult;
|
|
|
+import com.lc.ibps.vo.PerformanceQueryDTO;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections.MapUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFCell;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFRow;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFSheet;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
+import org.apache.poi.ss.usermodel.CellType;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* @title: xiexh
|
|
|
@@ -41,17 +54,29 @@ public class PersonnelManagementServiceImpl extends GenericProvider implements P
|
|
|
@Resource
|
|
|
private ICommonDao<?> commonDao;
|
|
|
|
|
|
+ // ================== 新增:Excel 列索引常量 ==================
|
|
|
+ // 根据实际导出的列顺序调整 (假设为:姓名, 部门, 年份, 月份, 条款名称, 绩效评分, 备注)
|
|
|
+ private static final int COL_INDEX_XM = 0;
|
|
|
+ private static final int COL_INDEX_BM = 1;
|
|
|
+ private static final int COL_INDEX_NF = 2;
|
|
|
+ private static final int COL_INDEX_YF = 3;
|
|
|
+ private static final int COL_INDEX_TK = 4;
|
|
|
+ private static final int COL_INDEX_PF = 5;
|
|
|
+ private static final int COL_INDEX_BZ = 6;
|
|
|
+
|
|
|
+ // ================== 原有业务方法 (保留不变) ==================
|
|
|
+
|
|
|
@Override
|
|
|
public APIResult<Object> queryDeptSnapshot(Map<String, Object> map) throws Exception {
|
|
|
APIResult<Object> result = new APIResult<>();
|
|
|
try {
|
|
|
int pageNo = Integer.parseInt(map.get("pageNo").toString());
|
|
|
int limit = Integer.parseInt(map.get("limit").toString());
|
|
|
- int startPage = limit*(pageNo-1);
|
|
|
- map.put("startPage",startPage);
|
|
|
+ int startPage = limit * (pageNo - 1);
|
|
|
+ map.put("startPage", startPage);
|
|
|
Map mapDeal = getMapV2(map);
|
|
|
- List<Map<String,Object>> list = personnelManagementDao.querySnapshoot(mapDeal);
|
|
|
- APIPageList<Map<String,Object>> pageList = getAPIPageList(list);
|
|
|
+ List<Map<String, Object>> list = personnelManagementDao.querySnapshoot(mapDeal);
|
|
|
+ APIPageList<Map<String, Object>> pageList = getAPIPageList(list);
|
|
|
APIPageResult pageResult = new APIPageResult();
|
|
|
pageResult.setTotalCount(1);
|
|
|
pageResult.setLimit(limit);
|
|
|
@@ -59,44 +84,412 @@ public class PersonnelManagementServiceImpl extends GenericProvider implements P
|
|
|
pageList.setPageResult(pageResult);
|
|
|
result.setData(pageList);
|
|
|
} catch (Exception e) {
|
|
|
- setExceptionResult(result, StateEnum.ERROR_FORM_BO.getCode(), I18nUtil.getMessage(StateEnum.ERROR_FORM_BO.getCode()+""), e);
|
|
|
+ setExceptionResult(result, StateEnum.ERROR_FORM_BO.getCode(), I18nUtil.getMessage(StateEnum.ERROR_FORM_BO.getCode() + ""), e);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private Map getMapV2(Map<String, Object> map) {
|
|
|
- HashMap<String, Object> stringObjectHashMap = new HashMap<>();
|
|
|
-
|
|
|
- if (BeanUtils.isNotEmpty(map)) {
|
|
|
- stringObjectHashMap.put("pageNo", map.get("pageNo"));
|
|
|
- stringObjectHashMap.put("limit", map.get("limit"));
|
|
|
- stringObjectHashMap.put("startPage", map.get("startPage"));
|
|
|
- stringObjectHashMap.put("locationId", getDiDian());
|
|
|
- if(BeanUtils.isNotEmpty(map.get("param"))){
|
|
|
- Map param = (Map) map.get("param");
|
|
|
- if(BeanUtils.isNotEmpty(param.get("gangWei"))){
|
|
|
- // 将逗号分隔的字符串拆分为List
|
|
|
- String gangweiStr= (String) param.get("gangWei");
|
|
|
- List<String> gangweiList = Arrays.asList(gangweiStr.trim().split("\\s*,\\s*"));
|
|
|
- stringObjectHashMap.put("gangWei",gangweiList);
|
|
|
- }
|
|
|
+ HashMap<String, Object> stringObjectHashMap = new HashMap<>();
|
|
|
+ if (BeanUtils.isNotEmpty(map)) {
|
|
|
+ stringObjectHashMap.put("pageNo", map.get("pageNo"));
|
|
|
+ stringObjectHashMap.put("limit", map.get("limit"));
|
|
|
+ stringObjectHashMap.put("startPage", map.get("startPage"));
|
|
|
+ stringObjectHashMap.put("locationId", getDiDian());
|
|
|
+ if (BeanUtils.isNotEmpty(map.get("param"))) {
|
|
|
+ Map param = (Map) map.get("param");
|
|
|
+ if (BeanUtils.isNotEmpty(param.get("gangWei"))) {
|
|
|
+ // 将逗号分隔的字符串拆分为List
|
|
|
+ String gangweiStr = (String) param.get("gangWei");
|
|
|
+ List<String> gangweiList = Arrays.asList(gangweiStr.trim().split("\\s*,\\s*"));
|
|
|
+ stringObjectHashMap.put("gangWei", gangweiList);
|
|
|
}
|
|
|
}
|
|
|
- return stringObjectHashMap;
|
|
|
-
|
|
|
+ }
|
|
|
+ return stringObjectHashMap;
|
|
|
}
|
|
|
|
|
|
- //获取当前用户地点,前端可以不用传
|
|
|
+ // 获取当前用户地点,前端可以不用传
|
|
|
private String getDiDian() {
|
|
|
IPartyPositionService partyPositionService = AppUtil.getBean(IPartyPositionService.class);
|
|
|
APIResult<List<PartyPositionPo>> result = partyPositionService.findByUserId(ContextUtil.getCurrentUserId());
|
|
|
- String diDian ="";
|
|
|
+ String diDian = "";
|
|
|
try {
|
|
|
diDian = result.getData().get(0).getPath().split(StringPool.BACK_SLASH + StringPool.DOT)[1];
|
|
|
- }catch (Exception ex){
|
|
|
- log.error("Can't get didian information",ex);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error("Can't get didian information", ex);
|
|
|
return null;
|
|
|
}
|
|
|
return diDian;
|
|
|
}
|
|
|
-}
|
|
|
+
|
|
|
+ // ================== 新增:1. 绩效数据导出 ==================
|
|
|
+ @Override
|
|
|
+ public void exportPerformanceData(HttpServletResponse response, PerformanceQueryDTO queryDTO) throws IOException {
|
|
|
+ // 1. 查询数据库数据
|
|
|
+ List<Map<String, Object>> rawData = personnelManagementDao.queryPerformanceForExport(convertToMap(queryDTO));
|
|
|
+ if (rawData == null || rawData.isEmpty()) {
|
|
|
+ throw new RuntimeException("未查询到相关绩效数据");
|
|
|
+ }
|
|
|
+ // 2. 构建xls输出文件流
|
|
|
+ constructExportSheet(rawData,response);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建并导出包含三个Sheet页的绩效Excel文件
|
|
|
+ * @param rawData 从数据库查询出的原始明细数据
|
|
|
+ * @param response HttpServletResponse响应对象
|
|
|
+ */
|
|
|
+ private void constructExportSheet(List<Map<String, Object>> rawData, HttpServletResponse response) throws IOException {
|
|
|
+ HSSFWorkbook workbook = new HSSFWorkbook();
|
|
|
+ Map Mapping = new HashMap();
|
|
|
+ //构建映射
|
|
|
+ List<Map<String, Object>> list = personnelManagementDao.queryPartyInfo(null);
|
|
|
+ for(Map map :list){
|
|
|
+ Mapping.putIfAbsent(map.get("ID_"),map.get("NAME_"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 创建第一个Sheet:个人评分明细
|
|
|
+ createDetailSheet(workbook, rawData, Mapping);
|
|
|
+
|
|
|
+ // 2. 创建第二个Sheet:按月份和年份汇总
|
|
|
+ createMonthSummarySheet(workbook, rawData, Mapping);
|
|
|
+
|
|
|
+ // 3. 创建第三个Sheet:按条款汇总
|
|
|
+ createClauseSummarySheet(workbook, rawData, Mapping);
|
|
|
+
|
|
|
+ // 4. 输出Excel文件到浏览器
|
|
|
+ response.setContentType("application/vnd.ms-excel");
|
|
|
+ String wjmc = "个人评分汇总_" + System.currentTimeMillis() + ".xls";
|
|
|
+ String encodedFileName = URLEncoder.encode(wjmc, "UTF-8").replaceAll("\\+", "%20");
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
|
|
|
+
|
|
|
+ workbook.write(response.getOutputStream());
|
|
|
+ workbook.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建第一个Sheet:个人评分明细
|
|
|
+ */
|
|
|
+ private void createDetailSheet(HSSFWorkbook workbook, List<Map<String, Object>> rawData, Map<String, String> mapping) {
|
|
|
+ HSSFSheet sheet = workbook.createSheet("个人评分明细");
|
|
|
+ // 创建表头
|
|
|
+ String[] headers = {"部门", "年份", "月份", "姓名", "条款名称", "绩效评分", "备注"};
|
|
|
+ HSSFRow headerRow = sheet.createRow(0);
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
+ headerRow.createCell(i).setCellValue(headers[i]);
|
|
|
+ }
|
|
|
+ // 填充数据
|
|
|
+ for (int i = 0; i < rawData.size(); i++) {
|
|
|
+ Map<String, Object> rowMap = rawData.get(i);
|
|
|
+ HSSFRow row = sheet.createRow(i + 1);
|
|
|
+ String buMeng = MapUtils.getString(mapping,MapUtils.getString(rowMap, "bu_men_2_", ""), "");
|
|
|
+ String name = MapUtils.getString(mapping,MapUtils.getString(rowMap, "xing_ming_2_", ""), "");
|
|
|
+ row.createCell(0).setCellValue(buMeng);
|
|
|
+ row.createCell(1).setCellValue(MapUtils.getString(rowMap, "nian_fen_2_", ""));
|
|
|
+ row.createCell(2).setCellValue(MapUtils.getString(rowMap, "yue_fen_2_", ""));
|
|
|
+ row.createCell(3).setCellValue(name);
|
|
|
+ row.createCell(4).setCellValue(MapUtils.getString(rowMap, "tiao_kuan_ming_ch", ""));
|
|
|
+ row.createCell(5).setCellValue(MapUtils.getString(rowMap, "ji_xiao_ping_fen_", ""));
|
|
|
+ row.createCell(6).setCellValue(MapUtils.getString(rowMap, "bei_zhu_", ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建第二个Sheet:按月份和年份汇总
|
|
|
+ */
|
|
|
+ private void createMonthSummarySheet(HSSFWorkbook workbook, List<Map<String, Object>> rawData, Map<String, String> mapping) {
|
|
|
+ HSSFSheet sheet = workbook.createSheet("按月份和年份汇总");
|
|
|
+ // 创建表头
|
|
|
+ String[] headers = {"序号", "部门", "年份", "姓名", "一月", "二月", "三月", "四月", "五月", "六月",
|
|
|
+ "七月", "八月", "九月", "十月", "十一月", "十二月", "年份汇总"};
|
|
|
+ HSSFRow headerRow = sheet.createRow(0);
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
+ headerRow.createCell(i).setCellValue(headers[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 汇总逻辑:按 部门、年份、姓名 分组
|
|
|
+ Map<String, Map<Integer, BigDecimal>> summaryMap = new LinkedHashMap<>();
|
|
|
+ Map<String, String> deptYearNameMap = new LinkedHashMap<>(); // 保存部门、年份、姓名的对应关系
|
|
|
+
|
|
|
+ for (Map<String, Object> row : rawData) {
|
|
|
+ String dept = MapUtils.getString(row, "bu_men_2_");
|
|
|
+ String year = MapUtils.getString(row, "nian_fen_2_");
|
|
|
+ String name = MapUtils.getString(row, "xing_ming_2_");
|
|
|
+ String monthStr = MapUtils.getString(row, "yue_fen_2_");
|
|
|
+ String scoreStr = MapUtils.getString(row, "ji_xiao_ping_fen_");
|
|
|
+
|
|
|
+ BigDecimal score = StringUtils.isNotBlank(scoreStr) ? new BigDecimal(scoreStr) : BigDecimal.ZERO;
|
|
|
+ int month = 0;
|
|
|
+ try { month = Integer.parseInt(monthStr); } catch (Exception e) { continue; }
|
|
|
+
|
|
|
+ // 构建分组Key
|
|
|
+ String groupKey = dept + "_" + year + "_" + name;
|
|
|
+ deptYearNameMap.putIfAbsent(groupKey, groupKey);
|
|
|
+
|
|
|
+ // 累加对应月份的分数
|
|
|
+ summaryMap.computeIfAbsent(groupKey, k -> new HashMap<>()).merge(month, score, BigDecimal::add);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 填充汇总数据到Sheet
|
|
|
+ int rowIndex = 1;
|
|
|
+ for (Map.Entry<String, Map<Integer, BigDecimal>> entry : summaryMap.entrySet()) {
|
|
|
+ String[] keys = entry.getKey().split("_");
|
|
|
+ String dept = keys[0];
|
|
|
+ String year = keys[1];
|
|
|
+ String name = keys[2];
|
|
|
+
|
|
|
+ String buMeng = MapUtils.getString(mapping,dept, dept);
|
|
|
+ String xingMing = MapUtils.getString(mapping,name, name);
|
|
|
+
|
|
|
+ Map<Integer, BigDecimal> monthScores = entry.getValue();
|
|
|
+
|
|
|
+ HSSFRow row = sheet.createRow(rowIndex++);
|
|
|
+ row.createCell(0).setCellValue(rowIndex - 1); // 序号
|
|
|
+ row.createCell(1).setCellValue(buMeng);
|
|
|
+ row.createCell(2).setCellValue(year);
|
|
|
+ row.createCell(3).setCellValue(xingMing);
|
|
|
+ BigDecimal yearTotal = BigDecimal.ZERO;
|
|
|
+ for (int m = 1; m <= 12; m++) {
|
|
|
+ BigDecimal monthScore = monthScores.getOrDefault(m, BigDecimal.ZERO);
|
|
|
+ row.createCell(3 + m).setCellValue(monthScore.toPlainString());
|
|
|
+ yearTotal = yearTotal.add(monthScore);
|
|
|
+ }
|
|
|
+ row.createCell(16).setCellValue(yearTotal.toPlainString()); // 年份汇总
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建第三个Sheet:按条款汇总
|
|
|
+ */
|
|
|
+ private void createClauseSummarySheet(HSSFWorkbook workbook, List<Map<String, Object>> rawData, Map<String, String> mapping) {
|
|
|
+ HSSFSheet sheet = workbook.createSheet("按条款汇总");
|
|
|
+ List<String> clauseConfig = new ArrayList<>();
|
|
|
+ // 查询条款配置项
|
|
|
+ List<String> dbRecords = personnelManagementDao.queryConfiguration(null);
|
|
|
+
|
|
|
+ clauseConfig.addAll(dbRecords);
|
|
|
+ // 创建表头
|
|
|
+ String[] headers = new String[3 + clauseConfig.size() + 1]; // 序号 + 部门 + 年份 + 姓名 + 16个条款 + 汇总
|
|
|
+ headers[0] = "序号"; headers[1] = "部门"; headers[2] = "年份"; headers[3] = "姓名";
|
|
|
+ for (int i = 0; i < clauseConfig.size(); i++) {
|
|
|
+ headers[4 + i] = clauseConfig.get(i);
|
|
|
+ }
|
|
|
+ headers[headers.length - 1] = "条款分值汇总";
|
|
|
+
|
|
|
+ HSSFRow headerRow = sheet.createRow(0);
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
+ headerRow.createCell(i).setCellValue(headers[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 汇总逻辑:按 部门、年份、姓名、条款名称 分组
|
|
|
+ Map<String, Map<String, BigDecimal>> summaryMap = new LinkedHashMap<>();
|
|
|
+ Map<String, String> deptYearNameMap = new LinkedHashMap<>();
|
|
|
+
|
|
|
+ for (Map<String, Object> row : rawData) {
|
|
|
+ String dept = MapUtils.getString(row, "bu_men_2_");
|
|
|
+ String year = MapUtils.getString(row, "nian_fen_2_");
|
|
|
+ String name = MapUtils.getString(row, "xing_ming_2_");
|
|
|
+ String clauseName = MapUtils.getString(row, "tiao_kuan_ming_ch", "");
|
|
|
+ String scoreStr = MapUtils.getString(row, "ji_xiao_ping_fen_");
|
|
|
+
|
|
|
+ BigDecimal score = StringUtils.isNotBlank(scoreStr) ? new BigDecimal(scoreStr) : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ // 如果条款不在配置的16个条款内,归为"其他条款"
|
|
|
+ String finalClause = clauseConfig.contains(clauseName) ? clauseName : "其他条款";
|
|
|
+
|
|
|
+ String groupKey = dept + "_" + year + "_" + name;
|
|
|
+ deptYearNameMap.putIfAbsent(groupKey, groupKey);
|
|
|
+
|
|
|
+ // 累加对应条款的分数
|
|
|
+ summaryMap.computeIfAbsent(groupKey, k -> new HashMap<>()).merge(finalClause, score, BigDecimal::add);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 填充汇总数据到Sheet
|
|
|
+ int rowIndex = 1;
|
|
|
+ for (Map.Entry<String, Map<String, BigDecimal>> entry : summaryMap.entrySet()) {
|
|
|
+ String[] keys = entry.getKey().split("_");
|
|
|
+ String dept = keys[0];
|
|
|
+ String year = keys[1];
|
|
|
+ String name = keys[2];
|
|
|
+ Map<String, BigDecimal> clauseScores = entry.getValue();
|
|
|
+
|
|
|
+ String buMeng = MapUtils.getString(mapping,dept, dept);
|
|
|
+ String xingMing = MapUtils.getString(mapping,name, name);
|
|
|
+
|
|
|
+ HSSFRow row = sheet.createRow(rowIndex++);
|
|
|
+ row.createCell(0).setCellValue(rowIndex - 1); // 序号
|
|
|
+ row.createCell(1).setCellValue(buMeng);
|
|
|
+ row.createCell(2).setCellValue(year);
|
|
|
+ row.createCell(3).setCellValue(xingMing);
|
|
|
+
|
|
|
+ BigDecimal clauseTotal = BigDecimal.ZERO;
|
|
|
+ for (int i = 0; i < clauseConfig.size(); i++) {
|
|
|
+ String clause = clauseConfig.get(i);
|
|
|
+ BigDecimal score = clauseScores.getOrDefault(clause, BigDecimal.ZERO);
|
|
|
+ row.createCell(4 + i).setCellValue(score.toPlainString());
|
|
|
+ clauseTotal = clauseTotal.add(score);
|
|
|
+ }
|
|
|
+ row.createCell(4 + clauseConfig.size()).setCellValue(clauseTotal.toPlainString()); // 条款分值汇总
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ================== 新增:2. 绩效数据导入 ==================
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public ImportResult importPerformanceData(MultipartFile file) throws IOException {
|
|
|
+ ImportResult result = new ImportResult();
|
|
|
+
|
|
|
+ // 1. 解析 Excel 数据
|
|
|
+ List<Map<String, Object>> excelDataList = readExcelRows(file);
|
|
|
+ if (excelDataList.isEmpty()) {
|
|
|
+ result.setFailCount(1);
|
|
|
+ result.getErrorList().add(new ImportError(0, "Excel文件为空或格式错误"));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 提取唯一键,准备去数据库匹配真实 ID
|
|
|
+ List<Map<String, Object>> queryKeys = new ArrayList<>();
|
|
|
+ Map<String, Map<String, Object>> excelDataMap = new LinkedHashMap<>(); // 保持顺序
|
|
|
+
|
|
|
+ for (Map<String, Object> excelRow : excelDataList) {
|
|
|
+ String uniqueKey = buildUniqueKey(excelRow);
|
|
|
+
|
|
|
+ // 构建查询参数 (对应 XML 中的批量 IN 查询)
|
|
|
+ Map<String, Object> keyParam = new HashMap<>();
|
|
|
+ keyParam.put("xing_ming_2_", excelRow.get("xing_ming_2_"));
|
|
|
+ keyParam.put("bu_men_2_", excelRow.get("bu_men_2_"));
|
|
|
+ keyParam.put("nian_fen_2_", excelRow.get("nian_fen_2_"));
|
|
|
+ keyParam.put("yue_fen_2_", excelRow.get("yue_fen_2_"));
|
|
|
+ keyParam.put("tiao_kuan_ming_ch", excelRow.get("tiao_kuan_ming_ch"));
|
|
|
+
|
|
|
+ queryKeys.add(keyParam);
|
|
|
+ excelDataMap.put(uniqueKey, excelRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 批量查询数据库中已存在的记录 ID
|
|
|
+ List<Map<String, Object>> dbRecords = personnelManagementDao.queryPerformanceIdsByKeys(queryKeys);
|
|
|
+ Map<String, String> dbIdMap = new HashMap<>();
|
|
|
+ for (Map<String, Object> dbRow : dbRecords) {
|
|
|
+ dbIdMap.put(buildUniqueKey(dbRow), MapUtils.getString(dbRow, "id_"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 比对数据,组装更新列表
|
|
|
+ List<Map<String, Object>> updateBatch = new ArrayList<>();
|
|
|
+ int rowNum = 1; // Excel 行号,从1开始(跳过表头)
|
|
|
+
|
|
|
+ for (Map.Entry<String, Map<String, Object>> entry : excelDataMap.entrySet()) {
|
|
|
+ rowNum++;
|
|
|
+ String key = entry.getKey();
|
|
|
+ Map<String, Object> excelData = entry.getValue();
|
|
|
+
|
|
|
+ if (dbIdMap.containsKey(key)) {
|
|
|
+ // 找到匹配项,只提取允许修改的字段 + 数据库真实ID
|
|
|
+ Map<String, Object> updateParam = new HashMap<>();
|
|
|
+ updateParam.put("id_", dbIdMap.get(key));
|
|
|
+ updateParam.put("ji_xiao_ping_fen_", excelData.get("ji_xiao_ping_fen_"));
|
|
|
+ updateParam.put("bei_zhu_", excelData.get("bei_zhu_"));
|
|
|
+ updateBatch.add(updateParam);
|
|
|
+ result.setSuccessCount(result.getSuccessCount() + 1);
|
|
|
+ } else {
|
|
|
+ // 未找到匹配项
|
|
|
+ result.setFailCount(result.getFailCount() + 1);
|
|
|
+ result.getErrorList().add(new ImportError(rowNum, "未找到匹配的原始数据: " + key));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 执行数据库批量更新
|
|
|
+ if (!updateBatch.isEmpty()) {
|
|
|
+ personnelManagementDao.batchUpdatePerformanceScores(updateBatch);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ================== 私有辅助方法 ==================
|
|
|
+
|
|
|
+ // DTO 转 Map
|
|
|
+ private Map<String, Object> convertToMap(PerformanceQueryDTO dto) {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("nianFen", dto.getNianFen());
|
|
|
+ map.put("yueFen", dto.getYueFen());
|
|
|
+ map.put("xingMing", dto.getXingMing());
|
|
|
+ map.put("buMen", dto.getBuMen());
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 Excel 行数据
|
|
|
+ private List<Map<String, Object>> readExcelRows(MultipartFile file) throws IOException {
|
|
|
+ List<Map<String, Object>> list = new ArrayList<>();
|
|
|
+ try (HSSFWorkbook workbook = new HSSFWorkbook(file.getInputStream())) {
|
|
|
+ HSSFSheet sheet = workbook.getSheetAt(0);
|
|
|
+ // 假设第一行是表头,从第二行开始读取
|
|
|
+ for (int i = 1; i <= sheet.getLastRowNum(); i++) {
|
|
|
+ HSSFRow row = sheet.getRow(i);
|
|
|
+ if (row == null) continue;
|
|
|
+
|
|
|
+ Map<String, Object> data = new HashMap<>();
|
|
|
+ data.put("xing_ming_2_", getCellValue(row.getCell(COL_INDEX_XM)));
|
|
|
+ data.put("bu_men_2_", getCellValue(row.getCell(COL_INDEX_BM)));
|
|
|
+ data.put("nian_fen_2_", getCellValue(row.getCell(COL_INDEX_NF)));
|
|
|
+ data.put("yue_fen_2_", getCellValue(row.getCell(COL_INDEX_YF)));
|
|
|
+ data.put("tiao_kuan_ming_ch", getCellValue(row.getCell(COL_INDEX_TK)));
|
|
|
+ data.put("ji_xiao_ping_fen_", getCellValue(row.getCell(COL_INDEX_PF)));
|
|
|
+ data.put("bei_zhu_", getCellValue(row.getCell(COL_INDEX_BZ)));
|
|
|
+ list.add(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取单元格字符串值
|
|
|
+ private String getCellValue(HSSFCell cell) {
|
|
|
+ if (cell == null) return "";
|
|
|
+ cell.setCellType(CellType.STRING);
|
|
|
+ return cell.getStringCellValue().trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建业务唯一键 (姓名|部门|年|月|条款)
|
|
|
+ private String buildUniqueKey(Map<String, Object> data) {
|
|
|
+ return MapUtils.getString(data, "xing_ming_2_") + "|" +
|
|
|
+ MapUtils.getString(data, "bu_men_2_") + "|" +
|
|
|
+ MapUtils.getString(data, "nian_fen_2_") + "|" +
|
|
|
+ MapUtils.getString(data, "yue_fen_2_") + "|" +
|
|
|
+ MapUtils.getString(data, "tiao_kuan_ming_ch");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 内部类:年度汇总数据容器
|
|
|
+ private static class YearSummary {
|
|
|
+ private final String year;
|
|
|
+ private BigDecimal totalScore = BigDecimal.ZERO;
|
|
|
+ private int itemCount = 0;
|
|
|
+ private final List<Map<String, Object>> dataList = new ArrayList<>();
|
|
|
+
|
|
|
+ public YearSummary(String year) {
|
|
|
+ this.year = year;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addData(Map<String, Object> data, BigDecimal score) {
|
|
|
+ this.totalScore = this.totalScore.add(score);
|
|
|
+ this.itemCount++;
|
|
|
+ this.dataList.add(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getYear() {
|
|
|
+ return year;
|
|
|
+ }
|
|
|
+
|
|
|
+ public BigDecimal getTotalScore() {
|
|
|
+ return totalScore;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getItemCount() {
|
|
|
+ return itemCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<Map<String, Object>> getDataList() {
|
|
|
+ return dataList;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|