|
|
@@ -10,7 +10,8 @@ import jakarta.validation.constraints.NotNull;
|
|
|
import jakarta.validation.constraints.Size;
|
|
|
import java.io.Serial;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.sql.Time;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalTime;
|
|
|
import java.util.Date;
|
|
|
|
|
|
/**
|
|
|
@@ -31,53 +32,87 @@ public class ZsjyInternshipDailyAddBo extends BaseEntity {
|
|
|
* 实习ID
|
|
|
*/
|
|
|
@Schema(description = "实习ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
- @NotNull(message = "实习ID不能为空", groups = {AddGroup.class})
|
|
|
+ @NotNull(message = "实习ID不能为空", groups = {AddGroup.class, CheckInGroup.class})
|
|
|
private Long internshipId;
|
|
|
|
|
|
/**
|
|
|
* 学生ID
|
|
|
*/
|
|
|
@Schema(description = "学生ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
- @NotNull(message = "学生ID不能为空", groups = {AddGroup.class})
|
|
|
+ @NotNull(message = "学生ID不能为空", groups = {AddGroup.class, CheckInGroup.class})
|
|
|
private Long studentId;
|
|
|
|
|
|
/**
|
|
|
- * 打卡日期
|
|
|
+ * 签到日期
|
|
|
*/
|
|
|
- @Schema(description = "打卡日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
- @NotNull(message = "打卡日期不能为空", groups = {AddGroup.class})
|
|
|
- private Date checkDate;
|
|
|
+ @Schema(description = "签到日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签到日期不能为空", groups = {AddGroup.class, CheckInGroup.class})
|
|
|
+ private LocalDate checkDate;
|
|
|
|
|
|
/**
|
|
|
* 签到时间
|
|
|
*/
|
|
|
- @Schema(description = "签到时间")
|
|
|
- private Time checkInTime;
|
|
|
+ @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签到时间不能为空", groups = {AddGroup.class, CheckInGroup.class})
|
|
|
+ private LocalTime checkInTime;
|
|
|
|
|
|
/**
|
|
|
- * 签到位置
|
|
|
+ * 签退时间
|
|
|
*/
|
|
|
- @Schema(description = "签到位置")
|
|
|
- @Size(max = 200, message = "签到位置长度不能超过200个字符")
|
|
|
+ @Schema(description = "签退时间")
|
|
|
+ private LocalTime checkOutTime;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 签到地点 (前端传递字段,映射到数据库check_in_location字段)
|
|
|
+ */
|
|
|
+ @Schema(description = "签到地点", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签到地点不能为空", groups = {CheckInGroup.class})
|
|
|
+ @Size(max = 500, message = "签到地点长度不能超过500个字符")
|
|
|
private String checkInLocation;
|
|
|
|
|
|
/**
|
|
|
- * 纬度
|
|
|
+ * 签到纬度 (前端传递字段,映射到数据库latitude字段)
|
|
|
*/
|
|
|
- @Schema(description = "纬度")
|
|
|
+ @Schema(description = "签到纬度", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签到纬度不能为空", groups = {CheckInGroup.class})
|
|
|
private BigDecimal latitude;
|
|
|
|
|
|
/**
|
|
|
- * 经度
|
|
|
+ * 签到经度 (前端传递字段,映射到数据库longitude字段)
|
|
|
*/
|
|
|
- @Schema(description = "经度")
|
|
|
+ @Schema(description = "签到经度", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签到经度不能为空", groups = {CheckInGroup.class})
|
|
|
private BigDecimal longitude;
|
|
|
|
|
|
/**
|
|
|
- * 日总结
|
|
|
+ * 签退地点 (对应数据库check_in_location字段,实际存储签退地点)
|
|
|
*/
|
|
|
- @Schema(description = "日总结")
|
|
|
- private String dailySummary;
|
|
|
+ @Schema(description = "签退地点", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签退地点不能为空", groups = {AddGroup.class})
|
|
|
+ @Size(max = 500, message = "签退地点长度不能超过500个字符")
|
|
|
+ private String checkOutLocation;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 签退纬度 (对应数据库latitude字段)
|
|
|
+ */
|
|
|
+ @Schema(description = "签退纬度", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签退纬度不能为空", groups = {AddGroup.class})
|
|
|
+ private BigDecimal checkOutLatitude;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 签退经度 (对应数据库longitude字段)
|
|
|
+ */
|
|
|
+ @Schema(description = "签退经度", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "签退经度不能为空", groups = {AddGroup.class})
|
|
|
+ private BigDecimal checkOutLongitude;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 工作内容 (对应数据库daily_summary字段)
|
|
|
+ */
|
|
|
+ @Schema(description = "工作内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
|
+ @NotNull(message = "工作内容不能为空", groups = {AddGroup.class})
|
|
|
+ @Size(max = 1000, message = "工作内容长度不能超过1000个字符")
|
|
|
+ private String workContent;
|
|
|
|
|
|
/**
|
|
|
* 图片附件(JSON格式)
|
|
|
@@ -95,25 +130,112 @@ public class ZsjyInternshipDailyAddBo extends BaseEntity {
|
|
|
* 异常原因
|
|
|
*/
|
|
|
@Schema(description = "异常原因")
|
|
|
- @Size(max = 500, message = "异常原因长度不能超过500个字符")
|
|
|
private String exceptionReason;
|
|
|
|
|
|
/**
|
|
|
- * 异常处理状态(0待处理 1已处理)
|
|
|
+ * 考勤状态(0=未签到 1=正常 2=迟到 3=早退 4=旷工)
|
|
|
*/
|
|
|
- @Schema(description = "异常处理状态")
|
|
|
- private String exceptionStatus;
|
|
|
-
|
|
|
- /**
|
|
|
- * 状态(0正常 1停用)
|
|
|
- */
|
|
|
- @Schema(description = "状态")
|
|
|
+ @Schema(description = "考勤状态")
|
|
|
private String status;
|
|
|
|
|
|
/**
|
|
|
* 备注
|
|
|
*/
|
|
|
@Schema(description = "备注")
|
|
|
+ @Size(max = 500, message = "备注长度不能超过500个字符")
|
|
|
private String remark;
|
|
|
|
|
|
+ // ==================== 扩展字段(用于显示,不存储到数据库) ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 学生姓名(扩展字段,用于显示)
|
|
|
+ */
|
|
|
+ @Schema(description = "学生姓名", hidden = true)
|
|
|
+ private String studentName;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 学生学号(扩展字段,用于显示)
|
|
|
+ */
|
|
|
+ @Schema(description = "学生学号", hidden = true)
|
|
|
+ private String studentNumber;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 班级名称(扩展字段,用于显示)
|
|
|
+ */
|
|
|
+ @Schema(description = "班级名称", hidden = true)
|
|
|
+ private String className;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 企业名称(扩展字段,用于显示)
|
|
|
+ */
|
|
|
+ @Schema(description = "企业名称", hidden = true)
|
|
|
+ private String companyName;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 实习岗位(扩展字段,用于显示)
|
|
|
+ */
|
|
|
+ @Schema(description = "实习岗位", hidden = true)
|
|
|
+ private String position;
|
|
|
+
|
|
|
+ // ==================== 兼容移动端字段(前端可能使用的别名) ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 日总结(兼容移动端,实际映射为workContent)
|
|
|
+ */
|
|
|
+ @Schema(description = "日总结", hidden = true)
|
|
|
+ private String dailySummary;
|
|
|
+
|
|
|
+ // ==================== 数据转换方法(处理前端字段映射) ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理移动端兼容字段映射
|
|
|
+ * 将移动端使用的字段名映射到实际的字段
|
|
|
+ */
|
|
|
+ public void processCompatibleFields() {
|
|
|
+ // 处理经纬度映射(签到时映射到签退字段存储)
|
|
|
+ if (this.latitude != null && this.checkOutLatitude == null) {
|
|
|
+ this.checkOutLatitude = this.latitude;
|
|
|
+ }
|
|
|
+ if (this.longitude != null && this.checkOutLongitude == null) {
|
|
|
+ this.checkOutLongitude = this.longitude;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理工作内容映射
|
|
|
+ if (this.dailySummary != null && this.workContent == null) {
|
|
|
+ this.workContent = this.dailySummary;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理签到位置映射(签到时映射到签退字段存储)
|
|
|
+ if (this.checkInLocation != null && this.checkOutLocation == null) {
|
|
|
+ this.checkOutLocation = this.checkInLocation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取实际的签退地点(优先使用checkOutLocation,否则使用checkInLocation)
|
|
|
+ */
|
|
|
+ public String getActualCheckOutLocation() {
|
|
|
+ return this.checkOutLocation != null ? this.checkOutLocation : this.checkInLocation;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取实际的签退经度(优先使用checkOutLongitude,否则使用longitude)
|
|
|
+ */
|
|
|
+ public BigDecimal getActualCheckOutLongitude() {
|
|
|
+ return this.checkOutLongitude != null ? this.checkOutLongitude : this.longitude;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取实际的签退纬度(优先使用checkOutLatitude,否则使用latitude)
|
|
|
+ */
|
|
|
+ public BigDecimal getActualCheckOutLatitude() {
|
|
|
+ return this.checkOutLatitude != null ? this.checkOutLatitude : this.latitude;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取实际的工作内容(优先使用workContent,否则使用dailySummary)
|
|
|
+ */
|
|
|
+ public String getActualWorkContent() {
|
|
|
+ return this.workContent != null ? this.workContent : this.dailySummary;
|
|
|
+ }
|
|
|
}
|