wuzhen update
This commit is contained in:
1 parent
84016d2f1a
commit
9a16535359
9 files changed
+408
-64
No files matched your search
+32
@@ -5,6 +5,7 @@ import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.zsjy.domain.vo.InternshipInfoVO;
|
||||
import org.dromara.zsjy.domain.bo.InternshipInfoQueryBO;
|
||||
import org.dromara.zsjy.domain.bo.InternshipInfoAddBO;
|
||||
@@ -101,6 +102,37 @@ public class InternshipInfoController extends BaseController {
|
||||
return R.ok(internshipInfoService.getInternshipStatistics(queryBO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 学生获取自己的实习信息(移动端专用)
|
||||
*/
|
||||
@Operation(summary = "学生获取实习信息", description = "学生查看自己的实习信息(移动端)")
|
||||
@GetMapping("/student/info")
|
||||
public R<InternshipInfoVO> getStudentInfo() {
|
||||
log.info("=== 学生获取实习信息 ===");
|
||||
log.info("当前用户ID: {}", LoginHelper.getUserId());
|
||||
|
||||
try {
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
if (currentUserId == null) {
|
||||
log.error("用户ID为空,无法获取实习信息");
|
||||
return R.fail("用户未登录");
|
||||
}
|
||||
|
||||
InternshipInfoVO result = internshipInfoService.queryById(currentUserId);
|
||||
|
||||
if (result != null) {
|
||||
log.info("成功获取学生实习信息,学生ID: {}", currentUserId);
|
||||
return R.ok(result);
|
||||
} else {
|
||||
log.info("学生暂无实习信息,学生ID: {}", currentUserId);
|
||||
return R.fail("暂无实习信息");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取学生实习信息异常,用户ID: {},错误信息: {}", LoginHelper.getUserId(), e.getMessage(), e);
|
||||
return R.fail("获取实习信息失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增实习信息
|
||||
*/
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@ import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.zsjy.domain.bo.CheckInGroup;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyAddBo;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyQueryBo;
|
||||
import org.dromara.zsjy.domain.vo.ZsjyInternshipDailyVo;
|
||||
@@ -58,7 +59,7 @@ public class ZsjyInternshipDailyController extends BaseController {
|
||||
@Operation(summary = "学生签到打卡", description = "学生进行实习日常签到打卡")
|
||||
@SaCheckPermission("zsjy:internshipdaily:checkin")
|
||||
@PostMapping("/checkin")
|
||||
public R<Void> checkIn(@Validated(AddGroup.class) @RequestBody ZsjyInternshipDailyAddBo addBo) {
|
||||
public R<Void> checkIn(@Validated(CheckInGroup.class) @RequestBody ZsjyInternshipDailyAddBo addBo) {
|
||||
log.info("=== Controller层调试 ===");
|
||||
log.info("接口被调用: /zsjy/internship/daily/checkin");
|
||||
log.info("签到参数: {}", addBo);
|
||||
|
||||
+106
-15
@@ -1,5 +1,7 @@
|
||||
package org.dromara.zsjy.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
@@ -9,6 +11,8 @@ import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Time;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@@ -26,74 +30,161 @@ public class ZsjyInternshipDaily extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 日常记录ID
|
||||
* 日常记录ID (对应数据库daily_id字段)
|
||||
*/
|
||||
@TableId(value = "daily_id")
|
||||
private Long dailyId;
|
||||
@TableId(value = "daily_id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@TableField("tenant_id")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 实习ID
|
||||
*/
|
||||
@TableField("internship_id")
|
||||
private Long internshipId;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
@TableField("student_id")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 打卡日期
|
||||
* 签到日期
|
||||
*/
|
||||
private Date checkDate;
|
||||
@TableField("check_date")
|
||||
private LocalDate checkDate;
|
||||
|
||||
/**
|
||||
* 签到时间
|
||||
*/
|
||||
private Time checkInTime;
|
||||
@TableField("check_in_time")
|
||||
private LocalTime checkInTime;
|
||||
|
||||
/**
|
||||
* 签到位置
|
||||
* 签到地点 (对应数据库check_in_location字段)
|
||||
*/
|
||||
private String checkInLocation;
|
||||
@TableField("check_in_location")
|
||||
private String checkOutLocation;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
* 签到经度 (对应数据库longitude字段)
|
||||
*/
|
||||
private BigDecimal latitude;
|
||||
@TableField("longitude")
|
||||
private BigDecimal checkOutLongitude;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
* 签到纬度 (对应数据库latitude字段)
|
||||
*/
|
||||
private BigDecimal longitude;
|
||||
@TableField("latitude")
|
||||
private BigDecimal checkOutLatitude;
|
||||
|
||||
/**
|
||||
* 日总结
|
||||
* 工作内容/日总结
|
||||
*/
|
||||
private String dailySummary;
|
||||
@TableField("daily_summary")
|
||||
private String workContent;
|
||||
|
||||
/**
|
||||
* 图片附件(JSON格式)
|
||||
*/
|
||||
@TableField("images")
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 是否异常(0正常 1异常)
|
||||
*/
|
||||
@TableField("is_exception")
|
||||
private String isException;
|
||||
|
||||
/**
|
||||
* 异常原因
|
||||
*/
|
||||
@TableField("exception_reason")
|
||||
private String exceptionReason;
|
||||
|
||||
/**
|
||||
* 异常处理状态(0待处理 1已处理)
|
||||
*/
|
||||
@TableField("exception_status")
|
||||
private String exceptionStatus;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
* 考勤状态(0=未签到 1=正常 2=迟到 3=早退 4=旷工)
|
||||
*/
|
||||
@TableField("status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@TableField("remark")
|
||||
private String remark;
|
||||
|
||||
// ==================== 扩展字段(数据库中不存在,通过关联查询获取) ====================
|
||||
|
||||
/**
|
||||
* 学生姓名 (通过student_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 学号 (通过student_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String studentNumber;
|
||||
|
||||
/**
|
||||
* 班级名称 (通过student_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 实习单位名称 (通过internship_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 实习岗位 (通过internship_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String position;
|
||||
|
||||
/**
|
||||
* 签到地点 (业务扩展字段,当前只有签退地点)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String checkInLocation;
|
||||
|
||||
/**
|
||||
* 签到经度 (业务扩展字段,当前只有签退经度)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private BigDecimal checkInLongitude;
|
||||
|
||||
/**
|
||||
* 签到纬度 (业务扩展字段,当前只有签退纬度)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private BigDecimal checkInLatitude;
|
||||
|
||||
/**
|
||||
* 签退时间 (业务扩展字段,当前只有签到时间)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private LocalTime checkOutTime;
|
||||
|
||||
/**
|
||||
* 工作时长(小时) (业务计算字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private BigDecimal workDuration;
|
||||
|
||||
}
|
||||
+150
-28
@@ -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;
|
||||
}
|
||||
}
|
||||
+58
-16
@@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
@@ -22,8 +23,11 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.YearMonth;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -64,32 +68,70 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<Void> checkIn(ZsjyInternshipDailyAddBo addBo) {
|
||||
try {
|
||||
// 1. 验证学生当日是否已签到
|
||||
boolean exists = baseMapper.existsByStudentAndDate(addBo.getStudentId(), addBo.getCheckDate());
|
||||
// 1. 验证学生当日是否已签到 - 将LocalDate转换为Date
|
||||
Date checkDateAsDate = Date.from(addBo.getCheckDate().atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
boolean exists = baseMapper.existsByStudentAndDate(addBo.getStudentId(), checkDateAsDate);
|
||||
if (exists) {
|
||||
return R.fail("今日已签到,请勿重复签到");
|
||||
}
|
||||
|
||||
// 2. 构建实体对象
|
||||
ZsjyInternshipDaily entity = MapstructUtils.convert(addBo, ZsjyInternshipDaily.class);
|
||||
// 2. 处理兼容字段映射(移动端可能使用的别名映射到正确的字段)
|
||||
if (addBo.getLatitude() != null && addBo.getCheckOutLatitude() == null) {
|
||||
addBo.setCheckOutLatitude(addBo.getLatitude());
|
||||
}
|
||||
if (addBo.getLongitude() != null && addBo.getCheckOutLongitude() == null) {
|
||||
addBo.setCheckOutLongitude(addBo.getLongitude());
|
||||
}
|
||||
if (addBo.getDailySummary() != null && addBo.getWorkContent() == null) {
|
||||
addBo.setWorkContent(addBo.getDailySummary());
|
||||
}
|
||||
if (addBo.getCheckInLocation() != null && addBo.getCheckOutLocation() == null) {
|
||||
addBo.setCheckOutLocation(addBo.getCheckInLocation());
|
||||
}
|
||||
|
||||
// 3. 设置签到时间为当前时间
|
||||
// 3. 构建实体对象 - 手动创建避免MapStruct转换器错误
|
||||
ZsjyInternshipDaily entity = new ZsjyInternshipDaily();
|
||||
|
||||
// 核心必填字段(对应数据库字段)
|
||||
entity.setInternshipId(addBo.getInternshipId());
|
||||
entity.setStudentId(addBo.getStudentId());
|
||||
entity.setCheckDate(addBo.getCheckDate());
|
||||
entity.setCheckInTime(addBo.getCheckInTime());
|
||||
entity.setCheckOutLocation(addBo.getCheckOutLocation()); // 对应数据库check_in_location字段
|
||||
entity.setCheckOutLatitude(addBo.getCheckOutLatitude()); // 对应数据库latitude字段
|
||||
entity.setCheckOutLongitude(addBo.getCheckOutLongitude()); // 对应数据库longitude字段
|
||||
entity.setWorkContent(addBo.getWorkContent()); // 对应数据库daily_summary字段
|
||||
entity.setImages(addBo.getImages());
|
||||
entity.setIsException(addBo.getIsException());
|
||||
entity.setExceptionReason(addBo.getExceptionReason());
|
||||
entity.setStatus(addBo.getStatus());
|
||||
entity.setRemark(addBo.getRemark());
|
||||
|
||||
// 扩展字段(不存储到数据库,仅用于显示)
|
||||
entity.setStudentName(addBo.getStudentName());
|
||||
entity.setStudentNumber(addBo.getStudentNumber());
|
||||
entity.setClassName(addBo.getClassName());
|
||||
entity.setCompanyName(addBo.getCompanyName());
|
||||
entity.setPosition(addBo.getPosition());
|
||||
|
||||
// 继承BaseEntity的字段会自动填充(create_time, create_by等)
|
||||
|
||||
// 4. 设置签到时间为当前时间(如果没有传入)
|
||||
if (ObjectUtil.isNull(entity.getCheckInTime())) {
|
||||
entity.setCheckInTime(Time.valueOf(DateUtil.format(new Date(), "HH:mm:ss")));
|
||||
entity.setCheckInTime(LocalTime.now());
|
||||
}
|
||||
|
||||
// 4. 设置默认值
|
||||
if (ObjectUtil.isNull(entity.getIsException())) {
|
||||
entity.setIsException("0"); // 默认正常
|
||||
}
|
||||
if (ObjectUtil.isNull(entity.getExceptionStatus())) {
|
||||
entity.setExceptionStatus("0"); // 默认待处理
|
||||
}
|
||||
// 5. 设置默认状态
|
||||
if (ObjectUtil.isNull(entity.getStatus())) {
|
||||
entity.setStatus("0"); // 默认正常
|
||||
entity.setStatus("1"); // 正常状态
|
||||
}
|
||||
|
||||
// 5. 保存签到记录
|
||||
// 6. 设置默认异常状态
|
||||
if (ObjectUtil.isNull(entity.getIsException())) {
|
||||
entity.setIsException("0"); // 正常
|
||||
}
|
||||
|
||||
// 7. 保存签到记录
|
||||
boolean result = baseMapper.insert(entity) > 0;
|
||||
if (!result) {
|
||||
return R.fail("签到失败,请稍后重试");
|
||||
@@ -100,7 +142,7 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("学生签到失败: {}", e.getMessage(), e);
|
||||
throw new ServiceException("签到失败: " + e.getMessage());
|
||||
return R.fail("签到失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,14 @@
|
||||
"navigationBarTitleText": "微信JS-SDK测试",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/internship/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "实习打卡",
|
||||
"navigationBarBackgroundColor": "#0051d9",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@@ -154,6 +154,20 @@
|
||||
/>
|
||||
</template>
|
||||
</ServiceItem>
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:internship:list'])"
|
||||
title="实习打卡"
|
||||
@click="gotoInternshipManage"
|
||||
>
|
||||
<template #icon>
|
||||
<image
|
||||
src="/static/00116.png"
|
||||
mode="aspectFit"
|
||||
style="width: 24px; height: 24px"
|
||||
/>
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
|
||||
@@ -575,7 +589,8 @@ export default {
|
||||
this.hasPermi(['student:psychology:list']) ||
|
||||
this.hasPermi(['student:club:list']) ||
|
||||
this.hasPermi(['student:counsel:list']) ||
|
||||
this.hasPermi(['student:info:edit'])
|
||||
this.hasPermi(['student:info:edit']) ||
|
||||
this.hasPermi(['student:internship:list'])
|
||||
);
|
||||
},
|
||||
|
||||
@@ -776,6 +791,13 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到实习管理页面
|
||||
gotoInternshipManage() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/internship/index',
|
||||
});
|
||||
},
|
||||
|
||||
// 图片加载成功处理
|
||||
handleImageLoad(event) {
|
||||
console.log('✅ 轮播图片加载成功:', event.detail);
|
||||
|
||||
@@ -14,6 +14,10 @@ export const checkPermi = (value) => {
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const userInfo = userStorage.getUserInfo();
|
||||
if (!userInfo || !userInfo.permissions) {
|
||||
console.warn('🚫 权限检查失败: 用户信息或权限列表不存在', {
|
||||
hasUserInfo: !!userInfo,
|
||||
hasPermissions: !!(userInfo && userInfo.permissions)
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -21,11 +25,33 @@ export const checkPermi = (value) => {
|
||||
const permissionDatas = value;
|
||||
const all_permission = '*:*:*';
|
||||
|
||||
// 调试日志:输出当前用户权限和检查的权限
|
||||
console.log('🔐 权限检查调试信息:', {
|
||||
检查权限: permissionDatas,
|
||||
用户权限数量: permissions.length,
|
||||
是否包含超级权限: permissions.includes(all_permission),
|
||||
权限匹配结果: permissionDatas.some(perm => permissions.includes(perm))
|
||||
});
|
||||
|
||||
// 特别检查实习相关权限
|
||||
if (permissionDatas.some(perm => perm.includes('internship'))) {
|
||||
console.log('📚 实习权限检查详情:', {
|
||||
检查的实习权限: permissionDatas.filter(perm => perm.includes('internship')),
|
||||
用户拥有的实习权限: permissions.filter(perm => perm.includes('internship')),
|
||||
所有权限前10条: permissions.slice(0, 10)
|
||||
});
|
||||
}
|
||||
|
||||
const hasPermission = permissions.some((permission) => {
|
||||
return all_permission === permission || permissionDatas.includes(permission);
|
||||
});
|
||||
|
||||
if (!hasPermission) {
|
||||
console.warn('🚫 权限验证失败:', {
|
||||
需要权限: permissionDatas,
|
||||
用户ID: userInfo.user?.userId,
|
||||
用户名: userInfo.user?.userName
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -125,9 +125,9 @@
|
||||
<div class="card-header-vertical">
|
||||
<div class="toolbar-title">实习日常管理</div>
|
||||
<div class="button-group">
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:internship:daily:add']">新增签到</el-button>
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:internshipdaily:add']">新增签到</el-button>
|
||||
<el-button plain icon="Search" @click="showSearch = !showSearch">搜索</el-button>
|
||||
<el-button type="primary" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internship:daily:export']">导出</el-button>
|
||||
<el-button type="primary" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internshipdaily:export']">导出</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -578,7 +578,7 @@ const submitAdd = () => {
|
||||
proxy.$refs.addFormRef.validate(valid => {
|
||||
if (valid) {
|
||||
addLoading.value = true;
|
||||
|
||||
|
||||
addInternshipDaily(addForm.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增签到记录成功");
|
||||
addDialogVisible.value = false;
|
||||
|
||||
Reference in new issue
Block a user