zhoulisky 10 months ago
parent
commit
b4197019a8

+ 27 - 0
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/dto/AttendanceDto.java

@@ -0,0 +1,27 @@
+package org.sky.scientific.pojo.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+public class AttendanceDto {
+
+	@Schema(description = "研发人员id")
+	private Long technicianId;
+
+	@Schema(description = "姓名")
+	private String name;
+
+	@Schema(description = "工号")
+	private String number;
+
+	@Schema(description = "身份证号码")
+	private String identityCard;
+
+	@Schema(description = "人员类型")
+	private String personnelType;
+
+	@Schema(description = "年月")
+	private String yearAndMonth;
+
+}

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

@@ -1,7 +1,6 @@
 
 package org.sky.scientific.pojo.entity;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.Max;
@@ -33,22 +32,6 @@ public class AttendanceEntity extends TenantEntity {
 	@NotBlank(message = "请选择研发人员")
 	private Long technicianId;
 
-	@Schema(description = "姓名")
-	@TableField(exist = false)
-	private String name;
-
-	@Schema(description = "工号")
-	@TableField(exist = false)
-	private String number;
-
-	@Schema(description = "身份证号码")
-	@TableField(exist = false)
-	private String identityCard;
-
-	@Schema(description = "人员类型")
-	@TableField(exist = false)
-	private String personnelType;
-
 	@Schema(description="考勤时间,yyyyMMdd")
 	@NotNull(message = "请选择考勤时间")
 	private String workDate;
@@ -57,6 +40,7 @@ public class AttendanceEntity extends TenantEntity {
 	@NotNull(message = "请填写出勤时长(小时)")
 	@Min(value = 0, message = "请填写正确的出勤时长(小时)")
 	@Max(value = 24, message = "请填写正确的出勤时长(小时)")
-	private Double workDuration;
+	private Double workHours;
+
 
 }

+ 35 - 0
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/vo/AttendanceVO.java

@@ -0,0 +1,35 @@
+package org.sky.scientific.pojo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AttendanceVO {
+
+	@Schema(description = "研发人员id")
+	private Long technicianId;
+
+	@Schema(description = "姓名")
+	private String name;
+
+	@Schema(description = "工号")
+	private String number;
+
+	@Schema(description = "身份证号码")
+	private String identityCard;
+
+	@Schema(description = "人员类型")
+	private String personnelType;
+
+	@Schema(description = "考勤明细")
+	private List<DailyAttendance> dailyAttendances;
+
+	@Schema(description="本月出勤/小时")
+ 	private Double monthlyHours;
+
+	@Schema(description="本月出勤/天")
+ 	private Double monthlyDays;
+
+}

+ 18 - 0
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/vo/DailyAttendance.java

@@ -0,0 +1,18 @@
+package org.sky.scientific.pojo.vo;
+
+import lombok.Data;
+
+@Data
+public class DailyAttendance {
+
+	private String workDate;        // 日期(如"20250506")
+	private Double workHours;
+
+	@Override
+	public String toString() {
+		return "DailyAttendance{" +
+			"workDate='" + workDate + '\'' +
+			", workHours=" + workHours +
+			'}';
+	}
+}

+ 17 - 8
kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/AttendanceController.java

@@ -1,5 +1,6 @@
 package org.sky.scientific.controller;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -7,13 +8,14 @@ import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
 import lombok.AllArgsConstructor;
 import org.sky.core.boot.ctrl.KdController;
+import org.sky.core.mp.support.Condition;
+import org.sky.core.mp.support.Query;
 import org.sky.core.tool.api.R;
+import org.sky.scientific.pojo.dto.AttendanceDto;
 import org.sky.scientific.pojo.entity.AttendanceEntity;
+import org.sky.scientific.pojo.vo.AttendanceVO;
 import org.sky.scientific.service.IAttendanceService;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 @RestController
@@ -25,16 +27,23 @@ public class AttendanceController extends KdController {
 	@Resource
 	private IAttendanceService service;
 
-	@PostMapping("/submit")
+	@GetMapping("page")
 	@ApiOperationSupport(order = 1)
-	@Operation(summary = "研发人员考勤表-新增或修改")
+	@Operation(summary = "每月考勤信息-分页查询")
+	public R<IPage<AttendanceVO>> page(AttendanceDto attendance, Query query) {
+		return R.data(service.selectAttendancePage(attendance, Condition.getPage(query)));
+	}
+
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 2)
+	@Operation(summary = "每月考勤信息-新增或修改")
 	public R submit(@Valid @RequestBody AttendanceEntity attendance) {
 		return R.status(service.submit(attendance));
 	}
 
 	@PostMapping("/import")
-	@ApiOperationSupport(order = 6)
-	@Operation(summary = "研发人员考勤表-导入", description = "传入excel")
+	@ApiOperationSupport(order = 3)
+	@Operation(summary = "每月考勤信息-导入", description = "传入excel")
 	public R importAttendance(MultipartFile file,String yearAndMonth) {
 		service.importAttendance(file, yearAndMonth);
 		return R.success("操作成功");

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

@@ -5,6 +5,7 @@ import com.alibaba.excel.metadata.data.ReadCellData;
 import com.alibaba.excel.read.listener.ReadListener;
 import lombok.Data;
 import org.sky.core.tool.utils.StringUtil;
+import org.sky.scientific.pojo.vo.DailyAttendance;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -87,8 +88,8 @@ public class AttendanceMonthlyDataListener implements ReadListener<Map<Integer,
 			if (hoursStr != null && !hoursStr.trim().isEmpty()) {
 				try {
 					DailyAttendance daily = new DailyAttendance();
-					daily.setDate(yearAndMonth + dateHeaders.get(i));
-					daily.setHours(safeParseDouble(hoursStr));
+					daily.setWorkDate(yearAndMonth + dateHeaders.get(i));
+					daily.setWorkHours(safeParseDouble(hoursStr));
 					record.getDailyAttendances().add(daily);
 				} catch (NumberFormatException e) {
 					System.err.printf("解析错误: 员工[%s] 日期[%s] 值[%s]%n",

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

@@ -6,6 +6,7 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
 import com.alibaba.excel.annotation.write.style.ContentRowHeight;
 import com.alibaba.excel.annotation.write.style.HeadRowHeight;
 import lombok.Data;
+import org.sky.scientific.pojo.vo.DailyAttendance;
 
 import java.io.Serial;
 import java.io.Serializable;

+ 0 - 18
kd-service/kd-scientific/src/main/java/org/sky/scientific/excel/DailyAttendance.java

@@ -1,18 +0,0 @@
-package org.sky.scientific.excel;
-
-import lombok.Data;
-
-@Data
-public class DailyAttendance {
-
-	private String date;        // 日期(如"20250506")
-	private Double hours;
-
-	@Override
-	public String toString() {
-		return "DailyAttendance{" +
-			"date='" + date + '\'' +
-			", hours=" + hours +
-			'}';
-	}
-}

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

@@ -2,8 +2,12 @@
 package org.sky.scientific.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Param;
+import org.sky.scientific.pojo.dto.AttendanceDto;
 import org.sky.scientific.pojo.entity.AttendanceEntity;
+import org.sky.scientific.pojo.vo.AttendanceVO;
+import org.sky.scientific.pojo.vo.DailyAttendance;
 
 import java.util.List;
 
@@ -22,4 +26,8 @@ public interface AttendanceMapper extends BaseMapper<AttendanceEntity> {
 	Long selectPrimaryKeyByTechnicianIdAndWorkDate(@Param("technicianId") Long technicianId, @Param("workDate") String workDate);
 
 	int batchSave(List<AttendanceEntity> list);
+
+	List<DailyAttendance> selectDailyAttendanceByTechnicianAndMonth(@Param("technicianId") Long technicianId, @Param("yearAndMonth") String yearAndMonth);
+
+	List<AttendanceVO> selectAttendancePage(IPage<AttendanceVO> page, @Param("ew") AttendanceDto attendance);
 }

+ 65 - 4
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AttendanceMapper.xml

@@ -2,10 +2,69 @@
 <!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">
 
+    <resultMap id="ResultMap" type="org.sky.scientific.pojo.entity.AttendanceEntity">
+        <result column="id" property="id"/>
+        <result column="tenant_id" property="tenantId"/>
+        <result column="technician_id" property="technicianId"/>
+        <result column="work_date" property="workDate"/>
+        <result column="work_hours" property="workHours"/>
+
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+    </resultMap>
+
+    <resultMap id="ResultVoMap" type="org.sky.scientific.pojo.vo.AttendanceVO">
+        <result column="technician_id" property="technicianId"/>
+        <result column="name" property="name"/>
+        <result column="number" property="number"/>
+        <result column="identity_card" property="identityCard"/>
+        <result column="personnel_type" property="personnelType"/>
+<!--        <collection property="dailyAttendances" ofType="org.sky.scientific.pojo.vo.DailyAttendance">-->
+<!--            <result column="work_date" property="workDate"/>-->
+<!--            <result column="work_hours" property="workHours"/>-->
+<!--        </collection>-->
+    </resultMap>
+
+    <select id="selectDailyAttendanceByTechnicianAndMonth" resultType="org.sky.scientific.pojo.vo.DailyAttendance">
+        select work_date,work_hours
+        from kd_attendance_records
+        where technician_id = #{technicianId} and left(work_date,6) = #{yearAndMonth}
+        order by work_date asc
+    </select>
+
+    <select id="selectAttendancePage" resultMap="ResultVoMap">
+        SELECT DISTINCT(r.technician_id), rs.name, rs.number, rs.identity_card, rs.personnel_type
+        FROM kd_attendance_records r
+        LEFT JOIN
+        (
+            SELECT t.id, t.NAME, t.number, t.identity_card, s.personnel_type
+            FROM kd_technician t
+            left JOIN kd_technician_snapshot s ON s.technician_id = t.id  AND year_and_month = #{ew.yearAndMonth}
+        )rs on rs.id = r.technician_id
+        WHERE LEFT(r.work_date,6) = #{ew.yearAndMonth}
+        <if test="ew.name != null">
+            and rs.name like concat('%',#{ew.name},'%')
+        </if>
+        <if test="ew.number != null">
+            and rs.number like concat('%',#{ew.number},'%')
+        </if>
+        <if test="ew.identityCard != null">
+            and rs.identity_card like concat('%',#{ew.identityCard},'%')
+        </if>
+        <if test="ew.personnelType != null">
+            and rs.personnel_type = #{ew.personnelType}
+        </if>
+    </select>
+
     <update id="batchUpdate" parameterType="java.util.List">
         <foreach collection="list" item="record" open="" separator=";" close="">
             update kd_attendance_records
-            set work_duration = #{record.workDuration}
+            set work_hours = #{record.workHours}
             where id = #{record.id}
         </foreach>
     </update>
@@ -15,15 +74,17 @@
     </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)
+        insert into kd_attendance_records(tenant_id,technician_id,work_date,work_hours,create_user,create_dept)
         VALUES
         <foreach collection="list" item="a" separator=",">
-            (#{a.tenantId},#{a.technicianId},#{a.workDate},#{a.workDuration},#{a.createUser},#{a.createDept})
+            (#{a.tenantId},#{a.technicianId},#{a.workDate},#{a.workHours},#{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
+        select id,technician_id as technicianId, work_date as workDate, work_hours as workHours from kd_attendance_records
         where left(work_date,6) = #{yearAndMonth}
     </select>
+
+
 </mapper>

+ 11 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IAttendanceService.java

@@ -1,8 +1,11 @@
 
 package org.sky.scientific.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.sky.core.mp.base.BaseService;
+import org.sky.scientific.pojo.dto.AttendanceDto;
 import org.sky.scientific.pojo.entity.AttendanceEntity;
+import org.sky.scientific.pojo.vo.AttendanceVO;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
@@ -14,6 +17,14 @@ import org.springframework.web.multipart.MultipartFile;
 public interface IAttendanceService extends BaseService<AttendanceEntity> {
 
 	/**
+	 * 研发人员考勤表-分页查询
+	 * @param attendance
+	 * @param page
+	 * @return
+	 */
+	IPage<AttendanceVO> selectAttendancePage(AttendanceDto attendance, IPage<AttendanceVO> page);
+
+	/**
 	 * 研发人员考勤表-新增或修改
 	 * @param attendance
 	 * @return

+ 27 - 6
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/AttendanceServiceImpl.java

@@ -3,20 +3,24 @@ package org.sky.scientific.service.impl;
 
 import com.alibaba.excel.EasyExcel;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.google.protobuf.ServiceException;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
+import org.sky.core.log.exception.ServiceException;
 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.core.tool.utils.StringUtil;
 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.dto.AttendanceDto;
 import org.sky.scientific.pojo.entity.AttendanceEntity;
+import org.sky.scientific.pojo.vo.AttendanceVO;
+import org.sky.scientific.pojo.vo.DailyAttendance;
 import org.sky.scientific.service.IAttendanceService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -40,6 +44,23 @@ public class AttendanceServiceImpl extends BaseServiceImpl<AttendanceMapper, Att
 	private final TechnicianMapper technicianMapper;
 
 	@Override
+	public IPage<AttendanceVO> selectAttendancePage(AttendanceDto attendance, IPage<AttendanceVO> page) {
+		if(StringUtil.isBlank(attendance.getYearAndMonth())) {
+			throw new ServiceException("参数yearAndMonth不能为空");
+		}
+		List<AttendanceVO> list = baseMapper.selectAttendancePage(page, attendance);
+		for (AttendanceVO vo : list) {
+			List<DailyAttendance> dailyAttendanceList = baseMapper.selectDailyAttendanceByTechnicianAndMonth(vo.getTechnicianId(), attendance.getYearAndMonth());
+			vo.setMonthlyHours(dailyAttendanceList.stream().mapToDouble(DailyAttendance::getWorkHours).sum());
+//			TODO 获取企业填报的考勤时长
+			Double workHours = 8.0;
+			vo.setMonthlyDays(vo.getMonthlyHours() / workHours);
+			vo.setDailyAttendances(dailyAttendanceList);
+		}
+		return page.setRecords(list);
+	}
+
+	@Override
 	public boolean submit(AttendanceEntity attendance) {
 		int affectNum = 0;
 		AttendanceEntity one = baseMapper.selectOne(Wrappers.<AttendanceEntity>lambdaQuery().
@@ -91,14 +112,14 @@ public class AttendanceServiceImpl extends BaseServiceImpl<AttendanceMapper, Att
 			List<AttendanceEntity> dataByTechnicianMonthly = dbList.stream().filter(e -> e.getTechnicianId().equals(technicianId)).toList();
 			for (DailyAttendance dailyAttendance : record.getDailyAttendances()) {
 
-				List<Long> primaryKeyList = dataByTechnicianMonthly.stream().filter(e -> Objects.equals(e.getWorkDate(), dailyAttendance.getDate())).map(AttendanceEntity::getId).toList();
+				List<Long> primaryKeyList = dataByTechnicianMonthly.stream().filter(e -> Objects.equals(e.getWorkDate(), dailyAttendance.getWorkDate())).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.setWorkDate(dailyAttendance.getWorkDate());
+					entity.setWorkHours(dailyAttendance.getWorkHours());
 					entity.setTenantId(SecureUtil.getTenantId());
 					entity.setCreateUser(SecureUtil.getUserId());
 					entity.setCreateDept(Func.toLong(SecureUtil.getDeptId()));
@@ -106,7 +127,7 @@ public class AttendanceServiceImpl extends BaseServiceImpl<AttendanceMapper, Att
 				} else {
 					AttendanceEntity entity = new AttendanceEntity();
 					entity.setId(primaryKey);
-					entity.setWorkDuration(dailyAttendance.getHours());
+					entity.setWorkHours(dailyAttendance.getWorkHours());
 					updateList.add(entity);
 				}
 				if (insertList.size() % batchCount == 0) {