zhouli 10 months ago
parent
commit
b69c9e31e1

+ 1 - 1
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/entity/AttendanceEntity.java

@@ -21,7 +21,7 @@ import java.io.Serial;
  * @since 2025-06-29
  */
 @Data
-@TableName("kd_attendance")
+@TableName("kd_attendance_records")
 @Schema(description = "研发人员考勤表")
 @EqualsAndHashCode(callSuper = true)
 public class AttendanceEntity extends TenantEntity {

+ 3 - 9
kd-service/kd-scientific/src/main/java/org/sky/scientific/excel/AttendanceMonthlyDataListener.java

@@ -75,9 +75,9 @@ public class AttendanceMonthlyDataListener implements ReadListener<Map<Integer,
 		// 解析固定列
 		record.setSerialNumber(safeParseInt(data.get(0)));
 		record.setName(data.get(1));
-		record.setEmployeeId(data.get(2));
-		record.setIdCard(data.get(3));
-		record.setEmployeeType(data.get(4));
+		record.setNumber(data.get(2));
+		record.setIdentityCard(data.get(3));
+		record.setPersonnelType(data.get(4));
 
 		// 解析每日考勤数据
 		int maxDays = Math.min(dateHeaders.size(), dayOfWeekHeaders.size());
@@ -128,10 +128,4 @@ public class AttendanceMonthlyDataListener implements ReadListener<Map<Integer,
 			return null;
 		}
 	}
-
-//	public static void main(String[] args) {
-//		Date yyyYmmdd = DateUtil.parse("2025056", "yyyyMMdd");
-//		String str = DateUtil.format(yyyYmmdd, "yyyyMMdd");
-//		System.out.println(str);
-//	}
 }

+ 3 - 3
kd-service/kd-scientific/src/main/java/org/sky/scientific/excel/AttendanceMonthlyExcel.java

@@ -30,9 +30,9 @@ public class AttendanceMonthlyExcel implements Serializable {
 
 	private Integer serialNumber;  // 序号
 	private String name;           // 姓名
-	private String employeeId;     // 工号
-	private String idCard;         // 身份证号码
-	private String employeeType;   // 科研人员类别
+	private String number;     // 工号
+	private String identityCard;         // 身份证号码
+	private String personnelType;   // 科研人员类别
 	private List<DailyAttendance> dailyAttendances = new ArrayList<>(); // 每日考勤数据
 	private Double monthlyHours;   // 本月出勤/小时
 	private Double monthlyDays;    // 本月出勤/天

+ 9 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AttendanceMapper.java

@@ -2,8 +2,11 @@
 package org.sky.scientific.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
 import org.sky.scientific.pojo.entity.AttendanceEntity;
 
+import java.util.List;
+
 /**
  * 考勤 Mapper 接口
  *
@@ -12,5 +15,11 @@ import org.sky.scientific.pojo.entity.AttendanceEntity;
  */
 public interface AttendanceMapper extends BaseMapper<AttendanceEntity> {
 
+	List<AttendanceEntity> selectByYearAndMonth(@Param("yearAndMonth") String yearAndMonth);
+
+	int batchUpdate(List<AttendanceEntity> list);
+
+	Long selectPrimaryKeyByTechnicianIdAndWorkDate(@Param("technicianId") Long technicianId, @Param("workDate") String workDate);
 
+	int batchSave(List<AttendanceEntity> list);
 }

+ 23 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AttendanceMapper.xml

@@ -2,5 +2,28 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.sky.scientific.mapper.AttendanceMapper">
 
+    <update id="batchUpdate" parameterType="java.util.List">
+        <foreach collection="list" item="record" open="" separator=";" close="">
+            update kd_attendance_records
+            set work_duration = #{record.workDuration}
+            where id = #{record.id}
+        </foreach>
+    </update>
 
+    <select id="selectPrimaryKeyByTechnicianIdAndWorkDate" resultType="java.lang.Long">
+        select id from kd_attendance_records where technician_id = #{technicianId} and work_date = #{workDate}
+    </select>
+
+    <insert id="batchSave" parameterType="java.util.List">
+        insert into kd_attendance_records(tenant_id,technician_id,work_date,work_duration,create_user,create_dept)
+        VALUES
+        <foreach collection="list" item="a" separator=",">
+            (#{a.tenantId},#{a.technicianId},#{a.workDate},#{a.workDuration},#{a.createUser},#{a.createDept})
+        </foreach>
+    </insert>
+
+    <select id="selectByYearAndMonth" resultType="org.sky.scientific.pojo.entity.AttendanceEntity" parameterType="java.lang.String">
+        select id,technician_id as technicianId, work_date as workDate, work_duration as workDuration  from kd_attendance_records
+        where left(work_date,6) = #{yearAndMonth}
+    </select>
 </mapper>

+ 58 - 20
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/AttendanceServiceImpl.java

@@ -5,22 +5,27 @@ import com.alibaba.excel.EasyExcel;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.google.protobuf.ServiceException;
+import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
 import org.sky.core.mp.base.BaseServiceImpl;
+import org.sky.core.secure.utils.SecureUtil;
 import org.sky.core.tool.utils.CollectionUtil;
+import org.sky.core.tool.utils.Func;
 import org.sky.scientific.excel.AttendanceMonthlyDataListener;
 import org.sky.scientific.excel.AttendanceMonthlyExcel;
 import org.sky.scientific.excel.DailyAttendance;
 import org.sky.scientific.mapper.AttendanceMapper;
+import org.sky.scientific.mapper.TechnicianMapper;
 import org.sky.scientific.pojo.entity.AttendanceEntity;
 import org.sky.scientific.service.IAttendanceService;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.BufferedInputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 考勤管理 服务实现类
@@ -29,8 +34,11 @@ import java.util.List;
  * @since 2025-06-29
  */
 @Service
+@AllArgsConstructor
 public class AttendanceServiceImpl extends BaseServiceImpl<AttendanceMapper, AttendanceEntity> implements IAttendanceService {
 
+	private final TechnicianMapper technicianMapper;
+
 	@Override
 	public boolean submit(AttendanceEntity attendance) {
 		int affectNum = 0;
@@ -50,6 +58,7 @@ public class AttendanceServiceImpl extends BaseServiceImpl<AttendanceMapper, Att
 	}
 
 	@SneakyThrows
+	@Transactional(rollbackFor = Exception.class)
 	@Override
 	public void importAttendance(MultipartFile file, String yearAndMonth) {
 		AttendanceMonthlyDataListener listener = new AttendanceMonthlyDataListener();
@@ -63,31 +72,60 @@ public class AttendanceServiceImpl extends BaseServiceImpl<AttendanceMapper, Att
 		if (CollectionUtil.isEmpty(records)) {
 			throw new ServiceException("未能从模板中读取数据,请检查模板格式是否正确");
 		}
-		List<Long> technicianIds = Arrays.asList(2L, 3L, 5L);
 
-		List<AttendanceEntity> attendanceEntities = new ArrayList<>();
-		int index = 0;
+		//需要新增的,以便后续批量新增
+		List<AttendanceEntity> insertList = new ArrayList<>();
+		//需要更新的,以便后续批量修改
+		List<AttendanceEntity> updateList = new ArrayList<>();
+
+		int batchCount = 20;
+
+		List<AttendanceEntity> dbList = baseMapper.selectByYearAndMonth(yearAndMonth);
 		for (AttendanceMonthlyExcel record : records) {
 			//保存
-//			technicianId 2,3,5,先写死吧
-
+			Long technicianId = technicianMapper.selectPrimaryKeyByNumberOrIdentityCard(record.getNumber(), record.getIdentityCard());
+			if (technicianId == null) {
+				throw new ServiceException("序号为[" + record.getSerialNumber() + "]的工号和者身份证都不存在");
+			}
+//			List<AttendanceEntity> dataByTechnicianMonthly = dbList.stream().filter(e -> e.getTechnicianId().equals(technicianId) && Objects.equals(e.getWorkDate().substring(0, 6), yearAndMonth)).toList();
+			List<AttendanceEntity> dataByTechnicianMonthly = dbList.stream().filter(e -> e.getTechnicianId().equals(technicianId)).toList();
 			for (DailyAttendance dailyAttendance : record.getDailyAttendances()) {
-				index++;
-				AttendanceEntity entity = new AttendanceEntity();
-				entity.setTechnicianId(technicianIds.get(records.indexOf(record)));
-				entity.setWorkDate(dailyAttendance.getDate());
-				entity.setWorkDuration(dailyAttendance.getHours());
-				attendanceEntities.add(entity);
-				if(index%20 == 0){
-					boolean saveBatchResult = this.saveBatch(attendanceEntities);
-					if(saveBatchResult){
-						attendanceEntities.clear();
-					}
+
+				List<Long> primaryKeyList = dataByTechnicianMonthly.stream().filter(e -> Objects.equals(e.getWorkDate(), dailyAttendance.getDate())).map(AttendanceEntity::getId).toList();
+				Long primaryKey = CollectionUtil.isEmpty(primaryKeyList) ? null : primaryKeyList.get(0);
+//					baseMapper.selectPrimaryKeyByTechnicianIdAndWorkDate(technicianId, dailyAttendance.getDate());
+				if (primaryKey == null) {
+					AttendanceEntity entity = new AttendanceEntity();
+					entity.setTechnicianId(technicianId);
+					entity.setWorkDate(dailyAttendance.getDate());
+					entity.setWorkDuration(dailyAttendance.getHours());
+					entity.setTenantId(SecureUtil.getTenantId());
+					entity.setCreateUser(SecureUtil.getUserId());
+					entity.setCreateDept(Func.toLong(SecureUtil.getDeptId()));
+					insertList.add(entity);
+				} else {
+					AttendanceEntity entity = new AttendanceEntity();
+					entity.setId(primaryKey);
+					entity.setWorkDuration(dailyAttendance.getHours());
+					updateList.add(entity);
 				}
+				if (insertList.size() % batchCount == 0) {
+					int insertCount = baseMapper.batchSave(insertList);
+					insertList.clear();
+				}
+//				if (updateList.size() % batchCount == 0) {
+//					int updateCount = baseMapper.batchUpdate(updateList);
+//					if (updateCount == batchCount) {
+//						updateList.clear();
+//					}
+//				}
 			}
-			if(index%20>0){
-				this.saveBatch(attendanceEntities);
-			}
 		}
+		if (!insertList.isEmpty()) {
+			baseMapper.batchSave(insertList);
+		}
+//		if (!updateList.isEmpty()) {
+//			baseMapper.batchUpdate(updateList);
+//		}
 	}
 }

+ 1 - 1
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/TechnicianServiceImpl.java

@@ -62,7 +62,7 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
 		//根据年月和工号或身份证,不存在则更新
 		Long technicianId = baseMapper.selectPrimaryKeyByNumberOrIdentityCard(technician.getNumber(), technician.getIdentityCard());
 		if (technicianId == null) {
-			technician.setCreateDept(Func.firstLong(AuthUtil.getDeptId()));
+			technician.setCreateDept(Func.toLong(AuthUtil.getDeptId()));
 			technician.setCreateUser(AuthUtil.getUserId());
 			technician.setUpdateUser(AuthUtil.getUserId());
 			baseMapper.saveTechnicianBasic(technician);