Merge branch 'master' of http://47.99.164.66:3000/hzdyjs-xg/all-project
This commit is contained in:
commit
c00199b2cf
29 files changed
+3848
-366
No files matched your search
+18
@@ -99,4 +99,22 @@ public class ZsjyInternshipDailyController extends BaseController {
|
||||
return dailyService.getStatistics(queryBo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取学生个人月度考勤统计(移动端专用)
|
||||
*/
|
||||
@Operation(summary = "获取学生月度统计", description = "获取指定学生的月度考勤统计数据")
|
||||
@SaCheckPermission("zsjy:internshipdaily:statistics")
|
||||
@GetMapping("/monthly-statistics")
|
||||
public R<Map<String, Object>> getStudentMonthlyStatistics(
|
||||
@Parameter(description = "学生ID", required = true) @RequestParam Long studentId,
|
||||
@Parameter(description = "年份", required = true) @RequestParam Integer year,
|
||||
@Parameter(description = "月份", required = true) @RequestParam Integer month) {
|
||||
|
||||
log.info("=== Controller层调试 ===");
|
||||
log.info("接口被调用: /zsjy/internship/daily/monthly-statistics");
|
||||
log.info("学生ID: {}, 年月: {}-{}", studentId, year, month);
|
||||
|
||||
return dailyService.getStudentMonthlyStatistics(studentId, year, month);
|
||||
}
|
||||
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package org.dromara.zsjy.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
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.ZsjyInternshipVisitBo;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipVisitQueryBo;
|
||||
import org.dromara.zsjy.domain.vo.ZsjyInternshipVisitVo;
|
||||
import org.dromara.zsjy.service.IZsjyInternshipVisitService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班主任走访Controller
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/zsjy/internshipVisit")
|
||||
@Tag(name = "班主任走访管理", description = "班主任走访管理")
|
||||
public class ZsjyInternshipVisitController extends BaseController {
|
||||
|
||||
private final IZsjyInternshipVisitService zsjyInternshipVisitService;
|
||||
|
||||
/**
|
||||
* 查询班主任走访列表
|
||||
*/
|
||||
@Operation(summary = "查询班主任走访列表")
|
||||
@SaCheckPermission("zsjy:internshipVisit:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<ZsjyInternshipVisitVo> list(ZsjyInternshipVisitQueryBo bo, PageQuery pageQuery) {
|
||||
return zsjyInternshipVisitService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出班主任走访列表
|
||||
*/
|
||||
@Operation(summary = "导出班主任走访列表")
|
||||
@SaCheckPermission("zsjy:internshipVisit:export")
|
||||
@Log(title = "班主任走访", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(ZsjyInternshipVisitQueryBo bo, HttpServletResponse response) {
|
||||
List<ZsjyInternshipVisitVo> list = zsjyInternshipVisitService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "班主任走访", ZsjyInternshipVisitVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取班主任走访详细信息
|
||||
*/
|
||||
@Operation(summary = "获取班主任走访详细信息")
|
||||
@SaCheckPermission("zsjy:internshipVisit:query")
|
||||
@GetMapping("/{visitId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "visitId", description = "走访记录ID", required = true)
|
||||
})
|
||||
public R<ZsjyInternshipVisitVo> getInfo(@NotNull(message = "走访记录ID不能为空")
|
||||
@PathVariable Long visitId) {
|
||||
return R.ok(zsjyInternshipVisitService.queryById(visitId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增班主任走访
|
||||
*/
|
||||
@Operation(summary = "新增班主任走访")
|
||||
@SaCheckPermission("zsjy:internshipVisit:add")
|
||||
@Log(title = "班主任走访", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody ZsjyInternshipVisitBo bo) {
|
||||
return toAjax(zsjyInternshipVisitService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改班主任走访
|
||||
*/
|
||||
@Operation(summary = "修改班主任走访")
|
||||
@SaCheckPermission("zsjy:internshipVisit:edit")
|
||||
@Log(title = "班主任走访", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ZsjyInternshipVisitBo bo) {
|
||||
return toAjax(zsjyInternshipVisitService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除班主任走访
|
||||
*/
|
||||
@Operation(summary = "删除班主任走访")
|
||||
@SaCheckPermission("zsjy:internshipVisit:remove")
|
||||
@Log(title = "班主任走访", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{visitIds}")
|
||||
@Parameters({
|
||||
@Parameter(name = "visitIds", description = "走访记录ID串", required = true)
|
||||
})
|
||||
public R<Void> remove(@NotEmpty(message = "走访记录ID不能为空")
|
||||
@PathVariable Long[] visitIds) {
|
||||
return toAjax(zsjyInternshipVisitService.deleteWithValidByIds(List.of(visitIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可选项列表(学生选择)
|
||||
*/
|
||||
@Operation(summary = "获取可选项列表")
|
||||
@SaCheckPermission("zsjy:internshipVisit:list")
|
||||
@GetMapping("/options")
|
||||
public R<List<ZsjyInternshipVisitVo>> getOptions() {
|
||||
List<ZsjyInternshipVisitVo> list = zsjyInternshipVisitService.getStudentOptions();
|
||||
return R.ok(list);
|
||||
}
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
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;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 班主任走访实体对象 zsjy_internship_visit
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("zsjy_internship_visit")
|
||||
public class ZsjyInternshipVisit extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 走访记录ID
|
||||
*/
|
||||
@TableId(value = "visit_id", type = IdType.ASSIGN_ID)
|
||||
private Long visitId;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@TableField("tenant_id")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 实习ID
|
||||
*/
|
||||
@TableField("internship_id")
|
||||
private Long internshipId;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
@TableField("student_id")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
@TableField("company_name")
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 企业地址
|
||||
*/
|
||||
@TableField("company_address")
|
||||
private String companyAddress;
|
||||
|
||||
/**
|
||||
* 走访时间
|
||||
*/
|
||||
@TableField("visit_date")
|
||||
private Date visitDate;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
@TableField("visitor_name")
|
||||
private String visitorName;
|
||||
|
||||
/**
|
||||
* 走访人员职务
|
||||
*/
|
||||
@TableField("visitor_position")
|
||||
private String visitorPosition;
|
||||
|
||||
/**
|
||||
* 走访目的
|
||||
*/
|
||||
@TableField("visit_purpose")
|
||||
private String visitPurpose;
|
||||
|
||||
/**
|
||||
* 企业情况
|
||||
*/
|
||||
@TableField("company_situation")
|
||||
private String companySituation;
|
||||
|
||||
/**
|
||||
* 学生表现
|
||||
*/
|
||||
@TableField("student_performance")
|
||||
private String studentPerformance;
|
||||
|
||||
/**
|
||||
* 发现问题
|
||||
*/
|
||||
@TableField("problems_found")
|
||||
private String problemsFound;
|
||||
|
||||
/**
|
||||
* 改进建议
|
||||
*/
|
||||
@TableField("suggestions")
|
||||
private String suggestions;
|
||||
|
||||
/**
|
||||
* 走访总结
|
||||
*/
|
||||
@TableField("visit_summary")
|
||||
private String visitSummary;
|
||||
|
||||
/**
|
||||
* 现场照片(JSON格式)
|
||||
*/
|
||||
@TableField("visit_images")
|
||||
private String visitImages;
|
||||
|
||||
/**
|
||||
* 走访文件附件(JSON格式)
|
||||
*/
|
||||
@TableField("visit_files")
|
||||
private String visitFiles;
|
||||
|
||||
/**
|
||||
* 走访状态:数据库存储数字编码(0-草稿 1-已提交 2-已审核)
|
||||
*/
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 专业名称 (通过student_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String majorName;
|
||||
|
||||
/**
|
||||
* 学院名称 (通过student_id关联查询获取)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String collegeName;
|
||||
}
|
||||
+6
@@ -82,4 +82,10 @@ public class ZsjyInternshipDailyQueryBo extends BaseEntity {
|
||||
@Schema(description = "公司名称")
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 班主任ID(用于权限控制)
|
||||
*/
|
||||
@Schema(description = "班主任ID")
|
||||
private Long headTeacherId;
|
||||
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package org.dromara.zsjy.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.zsjy.domain.ZsjyInternshipVisit;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 班主任走访业务对象 ZsjyInternshipVisitBo
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = ZsjyInternshipVisit.class, reverseConvertGenerate = false)
|
||||
public class ZsjyInternshipVisitBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 走访记录ID
|
||||
*/
|
||||
@NotNull(message = "走访记录ID不能为空", groups = { EditGroup.class })
|
||||
private Long visitId;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 实习ID
|
||||
*/
|
||||
@NotNull(message = "实习ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long internshipId;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
@NotNull(message = "学生ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
@NotBlank(message = "企业名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 企业地址
|
||||
*/
|
||||
private String companyAddress;
|
||||
|
||||
/**
|
||||
* 走访时间
|
||||
*/
|
||||
@NotNull(message = "走访时间不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Date visitDate;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
@NotBlank(message = "走访人员不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String visitorName;
|
||||
|
||||
/**
|
||||
* 走访人员职务
|
||||
*/
|
||||
private String visitorPosition;
|
||||
|
||||
/**
|
||||
* 走访目的
|
||||
*/
|
||||
@NotBlank(message = "走访目的不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String visitPurpose;
|
||||
|
||||
/**
|
||||
* 企业情况
|
||||
*/
|
||||
private String companySituation;
|
||||
|
||||
/**
|
||||
* 学生表现
|
||||
*/
|
||||
private String studentPerformance;
|
||||
|
||||
/**
|
||||
* 发现问题
|
||||
*/
|
||||
private String problemsFound;
|
||||
|
||||
/**
|
||||
* 改进建议
|
||||
*/
|
||||
private String suggestions;
|
||||
|
||||
/**
|
||||
* 走访总结
|
||||
*/
|
||||
private String visitSummary;
|
||||
|
||||
/**
|
||||
* 现场照片(JSON格式)
|
||||
*/
|
||||
private String visitImages;
|
||||
|
||||
/**
|
||||
* 走访文件附件(JSON格式)
|
||||
*/
|
||||
private String visitFiles;
|
||||
|
||||
/**
|
||||
* 走访状态:数据库存储数字编码(0-草稿 1-已提交 2-已审核)
|
||||
*/
|
||||
@Pattern(regexp = "^[0-2]$",
|
||||
message = "走访状态只能是:0(草稿)、1(已提交)、2(已审核)",
|
||||
groups = { AddGroup.class, EditGroup.class })
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package org.dromara.zsjy.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 班主任走访查询业务对象 ZsjyInternshipVisitQueryBo
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "班主任走访查询业务对象")
|
||||
public class ZsjyInternshipVisitQueryBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 走访记录ID
|
||||
*/
|
||||
@Schema(description = "走访记录ID")
|
||||
private Long visitId;
|
||||
|
||||
/**
|
||||
* 实习ID
|
||||
*/
|
||||
@Schema(description = "实习ID")
|
||||
private Long internshipId;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
@Schema(description = "学生ID")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
@Schema(description = "学生姓名")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
@Schema(description = "学号")
|
||||
private String studentNumber;
|
||||
|
||||
/**
|
||||
* 班级名称
|
||||
*/
|
||||
@Schema(description = "班级名称")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
@Schema(description = "企业名称")
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
@Schema(description = "走访人员")
|
||||
private String visitorName;
|
||||
|
||||
/**
|
||||
* 走访状态:数据库存储数字编码(0-草稿 1-已提交 2-已审核),前端通过字典显示为中文
|
||||
*/
|
||||
@Schema(description = "走访状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 走访开始时间
|
||||
*/
|
||||
@Schema(description = "走访开始时间")
|
||||
private Date visitStartDate;
|
||||
|
||||
/**
|
||||
* 走访结束时间
|
||||
*/
|
||||
@Schema(description = "走访结束时间")
|
||||
private Date visitEndDate;
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
package org.dromara.zsjy.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.dromara.zsjy.domain.ZsjyInternshipVisit;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 班主任走访视图对象 ZsjyInternshipVisitVo
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
@Data
|
||||
@AutoMapper(target = ZsjyInternshipVisit.class)
|
||||
@Schema(description = "班主任走访视图对象")
|
||||
public class ZsjyInternshipVisitVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 走访记录ID
|
||||
*/
|
||||
@Schema(description = "走访记录ID")
|
||||
private Long visitId;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@Schema(description = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 实习ID
|
||||
*/
|
||||
@Schema(description = "实习ID")
|
||||
private Long internshipId;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
@Schema(description = "学生ID")
|
||||
private Long studentId;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
@Schema(description = "企业名称")
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 企业地址
|
||||
*/
|
||||
@Schema(description = "企业地址")
|
||||
private String companyAddress;
|
||||
|
||||
/**
|
||||
* 走访时间
|
||||
*/
|
||||
@Schema(description = "走访时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date visitDate;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
@Schema(description = "走访人员")
|
||||
private String visitorName;
|
||||
|
||||
/**
|
||||
* 走访人员职务
|
||||
*/
|
||||
@Schema(description = "走访人员职务")
|
||||
private String visitorPosition;
|
||||
|
||||
/**
|
||||
* 走访目的
|
||||
*/
|
||||
@Schema(description = "走访目的")
|
||||
private String visitPurpose;
|
||||
|
||||
/**
|
||||
* 企业情况
|
||||
*/
|
||||
@Schema(description = "企业情况")
|
||||
private String companySituation;
|
||||
|
||||
/**
|
||||
* 学生表现
|
||||
*/
|
||||
@Schema(description = "学生表现")
|
||||
private String studentPerformance;
|
||||
|
||||
/**
|
||||
* 发现问题
|
||||
*/
|
||||
@Schema(description = "发现问题")
|
||||
private String problemsFound;
|
||||
|
||||
/**
|
||||
* 改进建议
|
||||
*/
|
||||
@Schema(description = "改进建议")
|
||||
private String suggestions;
|
||||
|
||||
/**
|
||||
* 走访总结
|
||||
*/
|
||||
@Schema(description = "走访总结")
|
||||
private String visitSummary;
|
||||
|
||||
/**
|
||||
* 现场照片(JSON格式)
|
||||
*/
|
||||
@Schema(description = "现场照片")
|
||||
private String visitImages;
|
||||
|
||||
/**
|
||||
* 走访文件附件(JSON格式)
|
||||
*/
|
||||
@Schema(description = "走访文件附件")
|
||||
private String visitFiles;
|
||||
|
||||
/**
|
||||
* 走访状态:数据库存储数字编码(0-草稿 1-已提交 2-已审核),前端通过字典显示为中文
|
||||
*/
|
||||
@Schema(description = "走访状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
// ==================== 关联查询字段 ====================
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
@Schema(description = "学生姓名")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
@Schema(description = "学号")
|
||||
private String studentNumber;
|
||||
|
||||
/**
|
||||
* 班级名称
|
||||
*/
|
||||
@Schema(description = "班级名称")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 专业名称
|
||||
*/
|
||||
@Schema(description = "专业名称")
|
||||
private String majorName;
|
||||
|
||||
/**
|
||||
* 学院名称
|
||||
*/
|
||||
@Schema(description = "学院名称")
|
||||
private String collegeName;
|
||||
|
||||
// ==================== 统一基础字段(强制性,避免MyBatis映射错误) ====================
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@Schema(description = "创建者")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@Schema(description = "更新者")
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
}
|
||||
+20
@@ -61,4 +61,24 @@ public interface ZsjyInternshipDailyMapper extends BaseMapper<ZsjyInternshipDail
|
||||
boolean existsByStudentAndDate(@Param("studentId") Long studentId,
|
||||
@Param("checkDate") Date checkDate);
|
||||
|
||||
/**
|
||||
* 获取学生个人月度考勤统计
|
||||
*
|
||||
* @param studentId 学生ID
|
||||
* @param year 年份
|
||||
* @param month 月份
|
||||
* @return 学生月度统计数据
|
||||
*/
|
||||
Map<String, Object> selectStudentMonthlyStatistics(@Param("studentId") Long studentId,
|
||||
@Param("year") Integer year,
|
||||
@Param("month") Integer month);
|
||||
|
||||
/**
|
||||
* 统计班主任管理的班级数量
|
||||
*
|
||||
* @param teacherId 班主任ID
|
||||
* @return 班级数量
|
||||
*/
|
||||
Long countClassesByTeacherId(@Param("teacherId") Long teacherId);
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package org.dromara.zsjy.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.zsjy.domain.ZsjyInternshipVisit;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipVisitQueryBo;
|
||||
import org.dromara.zsjy.domain.vo.ZsjyInternshipVisitVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班主任走访Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
public interface ZsjyInternshipVisitMapper extends BaseMapperPlus<ZsjyInternshipVisit, ZsjyInternshipVisitVo> {
|
||||
|
||||
/**
|
||||
* 根据ID查询班主任走访详情(包含关联学生信息)
|
||||
* @param visitId 走访记录ID
|
||||
* @return 走访详情VO
|
||||
*/
|
||||
ZsjyInternshipVisitVo selectById(Long visitId);
|
||||
|
||||
/**
|
||||
* 查询班主任走访列表(包含关联学生信息)
|
||||
* @param bo 查询条件
|
||||
* @return 走访记录列表
|
||||
*/
|
||||
List<ZsjyInternshipVisitVo> queryList(ZsjyInternshipVisitQueryBo bo);
|
||||
|
||||
/**
|
||||
* 分页查询班主任走访列表(包含关联学生信息)
|
||||
* @param page 分页参数
|
||||
* @param bo 查询条件
|
||||
* @return 走访记录分页结果
|
||||
*/
|
||||
Page<ZsjyInternshipVisitVo> queryPageList(Page<?> page, ZsjyInternshipVisitQueryBo bo);
|
||||
}
|
||||
+10
@@ -61,4 +61,14 @@ public interface IZsjyInternshipDailyService {
|
||||
*/
|
||||
R<Map<String, Object>> getStatistics(ZsjyInternshipDailyQueryBo queryBo);
|
||||
|
||||
/**
|
||||
* 获取学生个人月度考勤统计
|
||||
*
|
||||
* @param studentId 学生ID
|
||||
* @param year 年份
|
||||
* @param month 月份
|
||||
* @return 学生月度统计数据
|
||||
*/
|
||||
R<Map<String, Object>> getStudentMonthlyStatistics(Long studentId, Integer year, Integer month);
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package org.dromara.zsjy.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipVisitBo;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipVisitQueryBo;
|
||||
import org.dromara.zsjy.domain.vo.ZsjyInternshipVisitVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班主任走访Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
public interface IZsjyInternshipVisitService {
|
||||
|
||||
/**
|
||||
* 查询班主任走访
|
||||
*/
|
||||
ZsjyInternshipVisitVo queryById(Long visitId);
|
||||
|
||||
/**
|
||||
* 查询班主任走访列表
|
||||
*/
|
||||
TableDataInfo<ZsjyInternshipVisitVo> queryPageList(ZsjyInternshipVisitQueryBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询班主任走访列表
|
||||
*/
|
||||
List<ZsjyInternshipVisitVo> queryList(ZsjyInternshipVisitQueryBo bo);
|
||||
|
||||
/**
|
||||
* 新增班主任走访
|
||||
*/
|
||||
Boolean insertByBo(ZsjyInternshipVisitBo bo);
|
||||
|
||||
/**
|
||||
* 修改班主任走访
|
||||
*/
|
||||
Boolean updateByBo(ZsjyInternshipVisitBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除班主任走访信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 获取学生选项列表(用于下拉选择)
|
||||
*/
|
||||
List<ZsjyInternshipVisitVo> getStudentOptions();
|
||||
}
|
||||
+104
@@ -48,8 +48,19 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<ZsjyInternshipDailyVo> queryPageList(ZsjyInternshipDailyQueryBo queryBo, PageQuery pageQuery) {
|
||||
log.info("=== 实习日常查询后端调试日志 ===");
|
||||
log.info("1. 查询参数: {}", queryBo);
|
||||
log.info("2. 分页参数: pageNum={}, pageSize={}", pageQuery.getPageNum(), pageQuery.getPageSize());
|
||||
|
||||
// 设置数据权限
|
||||
setDataPermission(queryBo);
|
||||
log.info("3. 设置数据权限后的查询参数: {}", queryBo);
|
||||
log.info("3.1. 权限控制参数: headTeacherId={}", queryBo.getHeadTeacherId());
|
||||
|
||||
Page<ZsjyInternshipDailyVo> page = pageQuery.build();
|
||||
List<ZsjyInternshipDailyVo> list = baseMapper.selectDailyList(page, queryBo);
|
||||
log.info("4. 查询到的数据条数: {}", list != null ? list.size() : "null");
|
||||
|
||||
return TableDataInfo.build(list);
|
||||
}
|
||||
|
||||
@@ -58,6 +69,9 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
*/
|
||||
@Override
|
||||
public List<ZsjyInternshipDailyVo> queryList(ZsjyInternshipDailyQueryBo queryBo) {
|
||||
// 设置数据权限
|
||||
setDataPermission(queryBo);
|
||||
|
||||
return baseMapper.selectDailyList(null, queryBo);
|
||||
}
|
||||
|
||||
@@ -202,4 +216,94 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取学生个人月度考勤统计
|
||||
*/
|
||||
@Override
|
||||
public R<Map<String, Object>> getStudentMonthlyStatistics(Long studentId, Integer year, Integer month) {
|
||||
try {
|
||||
// 1. 参数校验
|
||||
if (ObjectUtil.isNull(studentId)) {
|
||||
return R.fail("学生ID不能为空");
|
||||
}
|
||||
if (ObjectUtil.isNull(year) || ObjectUtil.isNull(month)) {
|
||||
return R.fail("年月参数不能为空");
|
||||
}
|
||||
if (year < 2020 || year > 2030) {
|
||||
return R.fail("年份参数不合法");
|
||||
}
|
||||
if (month < 1 || month > 12) {
|
||||
return R.fail("月份参数不合法");
|
||||
}
|
||||
|
||||
// 2. 查询学生月度统计数据
|
||||
Map<String, Object> statistics = baseMapper.selectStudentMonthlyStatistics(studentId, year, month);
|
||||
|
||||
// 3. 补充默认值
|
||||
if (ObjectUtil.isNull(statistics)) {
|
||||
statistics = new HashMap<>();
|
||||
statistics.put("totalDays", 0);
|
||||
statistics.put("checkedDays", 0);
|
||||
statistics.put("missedDays", 0);
|
||||
statistics.put("exceptionDays", 0);
|
||||
}
|
||||
|
||||
// 4. 确保数据类型正确
|
||||
statistics.put("totalDays", ObjectUtil.defaultIfNull(statistics.get("totalDays"), 0));
|
||||
statistics.put("checkedDays", ObjectUtil.defaultIfNull(statistics.get("checkedDays"), 0));
|
||||
statistics.put("missedDays", ObjectUtil.defaultIfNull(statistics.get("missedDays"), 0));
|
||||
statistics.put("exceptionDays", ObjectUtil.defaultIfNull(statistics.get("exceptionDays"), 0));
|
||||
|
||||
log.info("学生{}的{}-{}月度统计: {}", studentId, year, month, statistics);
|
||||
return R.ok(statistics);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("获取学生月度统计数据失败: studentId={}, year={}, month={}, error={}",
|
||||
studentId, year, month, e.getMessage(), e);
|
||||
return R.fail("获取学生月度统计数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据权限(班主任只能查看自己班级的学生数据)
|
||||
*/
|
||||
private void setDataPermission(ZsjyInternshipDailyQueryBo queryBo) {
|
||||
try {
|
||||
// 获取当前登录用户ID
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
log.info("=== 权限控制调试 ===");
|
||||
log.info("当前登录用户ID: {}", currentUserId);
|
||||
|
||||
if (ObjectUtil.isNotNull(currentUserId)) {
|
||||
// 检查该用户是否是班主任
|
||||
Long classTeacherCount = baseMapper.countClassesByTeacherId(currentUserId);
|
||||
log.info("用户ID {}作为班主任管理的班级数量: {}", currentUserId, classTeacherCount);
|
||||
|
||||
if (classTeacherCount > 0) {
|
||||
// 是班主任,设置权限限制
|
||||
queryBo.setHeadTeacherId(currentUserId);
|
||||
log.info("✅ 权限判断:用户是班主任,设置headTeacherId={}", currentUserId);
|
||||
} else {
|
||||
// 不是班主任,设置不存在的班主任ID,使其无法查看任何数据
|
||||
log.info("❌ 权限判断:用户不是班主任,设置权限限制");
|
||||
|
||||
// 设置一个不存在的班主任ID(-1),这样SQL查询结果为空
|
||||
queryBo.setHeadTeacherId(-1L);
|
||||
log.info("🔒 设置数据权限:非班主任用户无法查看数据,headTeacherId=-1");
|
||||
}
|
||||
|
||||
// 输出最终的权限设置
|
||||
log.info("🎯 最终权限设置:queryBo.headTeacherId = {}", queryBo.getHeadTeacherId());
|
||||
} else {
|
||||
log.warn("⚠️ 未获取到当前用户ID,设置权限限制");
|
||||
queryBo.setHeadTeacherId(-1L);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("❌ 设置数据权限失败:{}", e.getMessage(), e);
|
||||
// 异常情况下,设置权限限制以确保数据安全
|
||||
queryBo.setHeadTeacherId(-1L);
|
||||
log.warn("🔒 异常情况下设置权限限制,headTeacherId=-1");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package org.dromara.zsjy.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.zsjy.domain.ZsjyInternshipVisit;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipVisitBo;
|
||||
import org.dromara.zsjy.domain.bo.ZsjyInternshipVisitQueryBo;
|
||||
import org.dromara.zsjy.domain.vo.ZsjyInternshipVisitVo;
|
||||
import org.dromara.zsjy.mapper.ZsjyInternshipVisitMapper;
|
||||
import org.dromara.zsjy.service.IZsjyInternshipVisitService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班主任走访Service业务层处理
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-01-03
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class ZsjyInternshipVisitServiceImpl implements IZsjyInternshipVisitService {
|
||||
|
||||
private final ZsjyInternshipVisitMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询班主任走访
|
||||
*/
|
||||
@Override
|
||||
public ZsjyInternshipVisitVo queryById(Long visitId){
|
||||
return baseMapper.selectById(visitId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询班主任走访列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<ZsjyInternshipVisitVo> queryPageList(ZsjyInternshipVisitQueryBo bo, PageQuery pageQuery) {
|
||||
// 使用自定义分页查询方法获取包含学生信息的完整数据
|
||||
Page<ZsjyInternshipVisitVo> result = baseMapper.queryPageList(pageQuery.build(), bo);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询班主任走访列表
|
||||
*/
|
||||
@Override
|
||||
public List<ZsjyInternshipVisitVo> queryList(ZsjyInternshipVisitQueryBo bo) {
|
||||
// 使用自定义查询方法获取包含学生信息的完整数据
|
||||
return baseMapper.queryList(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增班主任走访
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(ZsjyInternshipVisitBo bo) {
|
||||
ZsjyInternshipVisit add = MapstructUtils.convert(bo, ZsjyInternshipVisit.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setVisitId(add.getVisitId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改班主任走访
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(ZsjyInternshipVisitBo bo) {
|
||||
ZsjyInternshipVisit update = MapstructUtils.convert(bo, ZsjyInternshipVisit.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(ZsjyInternshipVisit entity){
|
||||
// TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除班主任走访
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
// TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取学生选项列表(用于下拉选择)
|
||||
*/
|
||||
@Override
|
||||
public List<ZsjyInternshipVisitVo> getStudentOptions() {
|
||||
// TODO 实现获取有实习信息的学生列表
|
||||
LambdaQueryWrapper<ZsjyInternshipVisit> lqw = Wrappers.lambdaQuery();
|
||||
lqw.select(ZsjyInternshipVisit::getStudentId, ZsjyInternshipVisit::getInternshipId);
|
||||
lqw.groupBy(ZsjyInternshipVisit::getStudentId);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
}
|
||||
+56
@@ -104,6 +104,15 @@
|
||||
<if test="queryBo.companyName != null and queryBo.companyName != ''">
|
||||
AND i.company_name LIKE CONCAT('%', #{queryBo.companyName}, '%')
|
||||
</if>
|
||||
<!-- 权限控制:班主任只能查看自己班级的学生数据 -->
|
||||
<if test="queryBo.headTeacherId != null">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM xg_student_msg s
|
||||
WHERE s.id = d.student_id
|
||||
AND s.class_teacher_id = #{queryBo.headTeacherId}
|
||||
AND s.deleted = 0
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY d.check_date DESC, d.create_time DESC
|
||||
</select>
|
||||
@@ -175,6 +184,44 @@
|
||||
) as attendanceRate
|
||||
</select>
|
||||
|
||||
<!-- 获取学生个人月度考勤统计 -->
|
||||
<select id="selectStudentMonthlyStatistics" resultType="java.util.Map">
|
||||
<![CDATA[
|
||||
SELECT
|
||||
-- 本月工作日总天数(简化计算,按22天计算)
|
||||
22 as totalDays,
|
||||
|
||||
-- 已签到天数
|
||||
(SELECT COUNT(*)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE student_id = #{studentId}
|
||||
AND deleted = 0
|
||||
AND YEAR(check_date) = #{year}
|
||||
AND MONTH(check_date) = #{month}
|
||||
AND check_in_time IS NOT NULL) as checkedDays,
|
||||
|
||||
-- 异常天数
|
||||
(SELECT COUNT(*)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE student_id = #{studentId}
|
||||
AND deleted = 0
|
||||
AND YEAR(check_date) = #{year}
|
||||
AND MONTH(check_date) = #{month}
|
||||
AND is_exception = '1') as exceptionDays,
|
||||
|
||||
-- 未签到天数(22 - 已签到 - 异常)
|
||||
(22 -
|
||||
(SELECT COUNT(*)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE student_id = #{studentId}
|
||||
AND deleted = 0
|
||||
AND YEAR(check_date) = #{year}
|
||||
AND MONTH(check_date) = #{month}
|
||||
AND (check_in_time IS NOT NULL OR is_exception = '1'))
|
||||
) as missedDays
|
||||
]]>
|
||||
</select>
|
||||
|
||||
<!-- 检查学生当日是否已签到 -->
|
||||
<select id="existsByStudentAndDate" resultType="boolean">
|
||||
SELECT COUNT(*) > 0
|
||||
@@ -184,4 +231,13 @@
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<!-- 统计班主任管理的班级数量 -->
|
||||
<select id="countClassesByTeacherId" resultType="java.lang.Long">
|
||||
SELECT COUNT(DISTINCT s.class_id)
|
||||
FROM xg_student_msg s
|
||||
WHERE s.class_teacher_id = #{teacherId}
|
||||
AND s.deleted = 0
|
||||
AND s.class_id IS NOT NULL
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.zsjy.mapper.ZsjyInternshipVisitMapper">
|
||||
|
||||
<resultMap type="org.dromara.zsjy.domain.vo.ZsjyInternshipVisitVo" id="ZsjyInternshipVisitResult">
|
||||
<result property="visitId" column="visit_id" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="internshipId" column="internship_id" />
|
||||
<result property="studentId" column="student_id" />
|
||||
<result property="companyName" column="company_name" />
|
||||
<result property="companyAddress" column="company_address" />
|
||||
<result property="visitDate" column="visit_date" />
|
||||
<result property="visitorName" column="visitor_name" />
|
||||
<result property="visitorPosition" column="visitor_position" />
|
||||
<result property="visitPurpose" column="visit_purpose" />
|
||||
<result property="companySituation" column="company_situation" />
|
||||
<result property="studentPerformance" column="student_performance" />
|
||||
<result property="problemsFound" column="problems_found" />
|
||||
<result property="suggestions" column="suggestions" />
|
||||
<result property="visitSummary" column="visit_summary" />
|
||||
<result property="visitImages" column="visit_images" />
|
||||
<result property="visitFiles" column="visit_files" />
|
||||
<result property="status" column="status" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<!-- 关联查询字段 -->
|
||||
<result property="studentName" column="student_name" />
|
||||
<result property="studentNumber" column="student_number" />
|
||||
<result property="className" column="class_name" />
|
||||
<result property="majorName" column="major_name" />
|
||||
<result property="collegeName" column="college_name" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectZsjyInternshipVisitVo">
|
||||
select
|
||||
v.visit_id,
|
||||
v.tenant_id,
|
||||
v.internship_id,
|
||||
v.student_id,
|
||||
v.company_name,
|
||||
v.company_address,
|
||||
v.visit_date,
|
||||
v.visitor_name,
|
||||
v.visitor_position,
|
||||
v.visit_purpose,
|
||||
v.company_situation,
|
||||
v.student_performance,
|
||||
v.problems_found,
|
||||
v.suggestions,
|
||||
v.visit_summary,
|
||||
v.visit_images,
|
||||
v.visit_files,
|
||||
v.status,
|
||||
v.remark,
|
||||
v.create_by,
|
||||
v.create_time,
|
||||
v.update_by,
|
||||
v.update_time,
|
||||
-- 关联查询学生信息
|
||||
s.name as student_name,
|
||||
s.student_no as student_number,
|
||||
s.class_name as class_name,
|
||||
s.major_name as major_name,
|
||||
s.college_name as college_name
|
||||
from zsjy_internship_visit v
|
||||
left join zsjy_internship_info ii on v.internship_id = ii.internship_id and ii.tenant_id = '000000'
|
||||
left join xg_student_msg s on v.student_id = s.id and s.tenant_id = '000000' and s.deleted = 0
|
||||
</sql>
|
||||
|
||||
<select id="queryList" parameterType="org.dromara.zsjy.domain.bo.ZsjyInternshipVisitQueryBo" resultMap="ZsjyInternshipVisitResult">
|
||||
<include refid="selectZsjyInternshipVisitVo"/>
|
||||
<where>
|
||||
v.deleted = 0 and v.tenant_id = '000000'
|
||||
<if test="visitId != null">
|
||||
and v.visit_id = #{visitId}
|
||||
</if>
|
||||
<if test="internshipId != null">
|
||||
and v.internship_id = #{internshipId}
|
||||
</if>
|
||||
<if test="studentId != null">
|
||||
and v.student_id = #{studentId}
|
||||
</if>
|
||||
<if test="studentName != null and studentName != ''">
|
||||
and s.name like concat('%', #{studentName}, '%')
|
||||
</if>
|
||||
<if test="studentNumber != null and studentNumber != ''">
|
||||
and s.student_no like concat('%', #{studentNumber}, '%')
|
||||
</if>
|
||||
<if test="className != null and className != ''">
|
||||
and s.class_name like concat('%', #{className}, '%')
|
||||
</if>
|
||||
<if test="companyName != null and companyName != ''">
|
||||
and v.company_name like concat('%', #{companyName}, '%')
|
||||
</if>
|
||||
<if test="visitorName != null and visitorName != ''">
|
||||
and v.visitor_name like concat('%', #{visitorName}, '%')
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
and v.status = #{status}
|
||||
</if>
|
||||
<if test="visitStartDate != null">
|
||||
and v.visit_date >= #{visitStartDate}
|
||||
</if>
|
||||
<if test="visitEndDate != null">
|
||||
and v.visit_date <= #{visitEndDate}
|
||||
</if>
|
||||
</where>
|
||||
order by v.visit_date desc, v.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="queryPageList" parameterType="org.dromara.zsjy.domain.bo.ZsjyInternshipVisitQueryBo" resultMap="ZsjyInternshipVisitResult">
|
||||
<include refid="selectZsjyInternshipVisitVo"/>
|
||||
<where>
|
||||
v.deleted = 0 and v.tenant_id = '000000'
|
||||
<if test="bo.visitId != null">
|
||||
and v.visit_id = #{bo.visitId}
|
||||
</if>
|
||||
<if test="bo.internshipId != null">
|
||||
and v.internship_id = #{bo.internshipId}
|
||||
</if>
|
||||
<if test="bo.studentId != null">
|
||||
and v.student_id = #{bo.studentId}
|
||||
</if>
|
||||
<if test="bo.studentName != null and bo.studentName != ''">
|
||||
and s.name like concat('%', #{bo.studentName}, '%')
|
||||
</if>
|
||||
<if test="bo.studentNumber != null and bo.studentNumber != ''">
|
||||
and s.student_no like concat('%', #{bo.studentNumber}, '%')
|
||||
</if>
|
||||
<if test="bo.className != null and bo.className != ''">
|
||||
and s.class_name like concat('%', #{bo.className}, '%')
|
||||
</if>
|
||||
<if test="bo.companyName != null and bo.companyName != ''">
|
||||
and v.company_name like concat('%', #{bo.companyName}, '%')
|
||||
</if>
|
||||
<if test="bo.visitorName != null and bo.visitorName != ''">
|
||||
and v.visitor_name like concat('%', #{bo.visitorName}, '%')
|
||||
</if>
|
||||
<if test="bo.status != null and bo.status != ''">
|
||||
and v.status = #{bo.status}
|
||||
</if>
|
||||
<if test="bo.visitStartDate != null">
|
||||
and v.visit_date >= #{bo.visitStartDate}
|
||||
</if>
|
||||
<if test="bo.visitEndDate != null">
|
||||
and v.visit_date <= #{bo.visitEndDate}
|
||||
</if>
|
||||
</where>
|
||||
order by v.visit_date desc, v.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectById" parameterType="Long" resultMap="ZsjyInternshipVisitResult">
|
||||
<include refid="selectZsjyInternshipVisitVo"/>
|
||||
where v.visit_id = #{visitId} and v.deleted = 0 and v.tenant_id = '000000'
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -63,7 +63,7 @@ export const getCalendarData = (studentId, year, month) => {
|
||||
*/
|
||||
export const getStatistics = (params) => {
|
||||
return request({
|
||||
url: '/zsjy/internship/daily/statistics',
|
||||
url: '/zsjy/internship/daily/monthly-statistics',
|
||||
method: 'GET',
|
||||
params
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,4 @@
|
||||
import request from '@/utils/request'
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 查询实习日常记录列表
|
||||
export function listInternshipDaily(query) {
|
||||
@@ -6,7 +6,7 @@ export function listInternshipDaily(query) {
|
||||
url: '/zsjy/internship/daily/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 学生签到打卡
|
||||
@@ -15,7 +15,7 @@ export function checkIn(data) {
|
||||
url: '/zsjy/internship/daily/checkin',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 新增实习日常记录
|
||||
@@ -24,7 +24,7 @@ export function addInternshipDaily(data) {
|
||||
url: '/zsjy/internship/daily',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取学生考勤日历
|
||||
@@ -33,7 +33,7 @@ export function getCalendar(studentId, params) {
|
||||
url: `/zsjy/internship/daily/calendar/${studentId}`,
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取考勤统计数据
|
||||
@@ -42,5 +42,5 @@ export function getStatistics(query) {
|
||||
url: '/zsjy/internship/daily/statistics',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { InternshipVisitVO, InternshipVisitQuery, InternshipVisitAddBO, InternshipVisitEditBO } from '@/api/zsjy/types';
|
||||
import { TableDataInfo, R } from '@/api/types';
|
||||
|
||||
/**
|
||||
* 查询班主任走访记录列表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
export const listInternshipVisit = (query?: InternshipVisitQuery): AxiosPromise<TableDataInfo<InternshipVisitVO>> => {
|
||||
return request({
|
||||
url: '/zsjy/internshipVisit/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询班主任走访记录详细信息
|
||||
* @param visitId 走访记录ID
|
||||
*/
|
||||
export const getInternshipVisit = (visitId: string | number): AxiosPromise<R<InternshipVisitVO>> => {
|
||||
return request({
|
||||
url: `/zsjy/internshipVisit/${visitId}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增班主任走访记录
|
||||
* @param data 走访记录信息
|
||||
*/
|
||||
export const addInternshipVisit = (data: InternshipVisitAddBO): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: '/zsjy/internshipVisit',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改班主任走访记录
|
||||
* @param data 走访记录信息
|
||||
*/
|
||||
export const updateInternshipVisit = (data: InternshipVisitEditBO): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: '/zsjy/internshipVisit',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除班主任走访记录
|
||||
* @param visitIds 走访记录ID
|
||||
*/
|
||||
export const delInternshipVisit = (visitIds: string | number | Array<string | number>): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: `/zsjy/internshipVisit/${visitIds}`,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出班主任走访记录列表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
export const exportInternshipVisit = (query: InternshipVisitQuery) => {
|
||||
return request({
|
||||
url: '/zsjy/internshipVisit/export',
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取可选项列表(学生选择)
|
||||
*/
|
||||
export const getInternshipVisitOptions = (): AxiosPromise<R<InternshipVisitVO[]>> => {
|
||||
return request({
|
||||
url: '/zsjy/internshipVisit/options',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@@ -1195,6 +1195,16 @@ export interface InternshipInfoQuery {
|
||||
* 实习开始日期-结束
|
||||
*/
|
||||
internshipStartDateEnd?: string;
|
||||
|
||||
/**
|
||||
* 班主任ID(用于数据权限控制)
|
||||
*/
|
||||
classTeacherId?: string | number;
|
||||
|
||||
/**
|
||||
* 辅导员ID(用于数据权限控制)
|
||||
*/
|
||||
counselorId?: string | number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1261,3 +1271,283 @@ export interface InternshipStatisticsVO {
|
||||
*/
|
||||
internshipRate?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 班主任走访记录 VO
|
||||
*/
|
||||
export interface InternshipVisitVO {
|
||||
/**
|
||||
* 走访记录ID
|
||||
*/
|
||||
visitId?: string | number;
|
||||
|
||||
/**
|
||||
* 实习记录ID
|
||||
*/
|
||||
internshipId?: string | number;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
studentId?: string | number;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName?: string;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
studentNumber?: string;
|
||||
|
||||
/**
|
||||
* 班级名称
|
||||
*/
|
||||
className?: string;
|
||||
|
||||
/**
|
||||
* 专业名称
|
||||
*/
|
||||
majorName?: string;
|
||||
|
||||
/**
|
||||
* 学院名称
|
||||
*/
|
||||
collegeName?: string;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
companyName?: string;
|
||||
|
||||
/**
|
||||
* 企业地址
|
||||
*/
|
||||
companyAddress?: string;
|
||||
|
||||
/**
|
||||
* 走访日期
|
||||
*/
|
||||
visitDate?: string;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
visitorName?: string;
|
||||
|
||||
/**
|
||||
* 走访人员职务
|
||||
*/
|
||||
visitorPosition?: string;
|
||||
|
||||
/**
|
||||
* 走访目的
|
||||
*/
|
||||
visitPurpose?: string;
|
||||
|
||||
/**
|
||||
* 企业情况
|
||||
*/
|
||||
companySituation?: string;
|
||||
|
||||
/**
|
||||
* 学生表现
|
||||
*/
|
||||
studentPerformance?: string;
|
||||
|
||||
/**
|
||||
* 发现问题
|
||||
*/
|
||||
problemsFound?: string;
|
||||
|
||||
/**
|
||||
* 改进建议
|
||||
*/
|
||||
suggestions?: string;
|
||||
|
||||
/**
|
||||
* 走访总结
|
||||
*/
|
||||
visitSummary?: string;
|
||||
|
||||
/**
|
||||
* 现场照片(JSON格式)
|
||||
*/
|
||||
visitImages?: string;
|
||||
|
||||
/**
|
||||
* 走访文件附件(JSON格式)
|
||||
*/
|
||||
visitFiles?: string;
|
||||
|
||||
/**
|
||||
* 状态(0-草稿 1-已提交 2-已审核)
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime?: string;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
createBy?: number;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
updateTime?: string;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
updateBy?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 班主任走访记录查询参数
|
||||
*/
|
||||
export interface InternshipVisitQuery extends PageQuery {
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName?: string;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
studentNumber?: string;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
companyName?: string;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
visitorName?: string;
|
||||
|
||||
/**
|
||||
* 走访日期-开始
|
||||
*/
|
||||
visitDateBegin?: string;
|
||||
|
||||
/**
|
||||
* 走访日期-结束
|
||||
*/
|
||||
visitDateEnd?: string;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 班主任走访记录新增参数
|
||||
*/
|
||||
export interface InternshipVisitAddBO {
|
||||
/**
|
||||
* 实习记录ID
|
||||
*/
|
||||
internshipId?: string | number;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
studentId?: string | number;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
companyName?: string;
|
||||
|
||||
/**
|
||||
* 企业地址
|
||||
*/
|
||||
companyAddress?: string;
|
||||
|
||||
/**
|
||||
* 走访日期
|
||||
*/
|
||||
visitDate?: string;
|
||||
|
||||
/**
|
||||
* 走访人员
|
||||
*/
|
||||
visitorName?: string;
|
||||
|
||||
/**
|
||||
* 走访人员职务
|
||||
*/
|
||||
visitorPosition?: string;
|
||||
|
||||
/**
|
||||
* 走访目的
|
||||
*/
|
||||
visitPurpose?: string;
|
||||
|
||||
/**
|
||||
* 企业情况
|
||||
*/
|
||||
companySituation?: string;
|
||||
|
||||
/**
|
||||
* 学生表现
|
||||
*/
|
||||
studentPerformance?: string;
|
||||
|
||||
/**
|
||||
* 发现问题
|
||||
*/
|
||||
problemsFound?: string;
|
||||
|
||||
/**
|
||||
* 改进建议
|
||||
*/
|
||||
suggestions?: string;
|
||||
|
||||
/**
|
||||
* 走访总结
|
||||
*/
|
||||
visitSummary?: string;
|
||||
|
||||
/**
|
||||
* 现场照片(JSON格式)
|
||||
*/
|
||||
visitImages?: string;
|
||||
|
||||
/**
|
||||
* 走访文件附件(JSON格式)
|
||||
*/
|
||||
visitFiles?: string;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 班主任走访记录编辑参数
|
||||
*/
|
||||
export interface InternshipVisitEditBO extends InternshipVisitAddBO {
|
||||
/**
|
||||
* 走访记录ID
|
||||
*/
|
||||
visitId?: string | number;
|
||||
}
|
||||
@@ -455,14 +455,38 @@ const handleBeforeUpload = (file: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 设置超时处理 - 如果60秒后仍在loading状态,自动关闭并提示
|
||||
const timeoutId = setTimeout(() => {
|
||||
if (number.value > 0) {
|
||||
console.warn('上传超时,自动关闭loading');
|
||||
(proxy as any)?.$modal.closeLoading();
|
||||
(proxy as any)?.$modal.msgError('上传超时,请检查网络连接或重试');
|
||||
number.value = 0; // 重置计数器
|
||||
}
|
||||
}, 60000); // 60秒超时
|
||||
|
||||
//压缩图片,开启压缩并且大于指定的压缩大小时才压缩
|
||||
if (props.compressSupport && file.size / 1024 > props.compressTargetSize) {
|
||||
(proxy as any)?.$modal.loading('正在上传图片,请稍候...');
|
||||
number.value++;
|
||||
return compressAccurately(file, props.compressTargetSize);
|
||||
|
||||
// 压缩图片时的错误处理
|
||||
try {
|
||||
return compressAccurately(file, props.compressTargetSize);
|
||||
} catch (compressionError) {
|
||||
console.error('图片压缩失败:', compressionError);
|
||||
clearTimeout(timeoutId);
|
||||
(proxy as any)?.$modal.closeLoading();
|
||||
(proxy as any)?.$modal.msgError('图片压缩失败,请重试');
|
||||
number.value--;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
(proxy as any)?.$modal.loading('正在上传图片,请稍候...');
|
||||
number.value++;
|
||||
|
||||
// 保存timeout ID以便在上传完成时清除
|
||||
(file as any).uploadTimeoutId = timeoutId;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -476,6 +500,11 @@ const handleUploadSuccess = (res: any, file: any) => {
|
||||
console.log('handleUploadSuccess:res', res);
|
||||
console.log('handleUploadSuccess:file', file);
|
||||
|
||||
// 清除上传超时处理
|
||||
if ((file as any).uploadTimeoutId) {
|
||||
clearTimeout((file as any).uploadTimeoutId);
|
||||
}
|
||||
|
||||
if (res.code === 200) {
|
||||
const uploadItem = {
|
||||
name: res.data.fileName,
|
||||
@@ -488,7 +517,9 @@ const handleUploadSuccess = (res: any, file: any) => {
|
||||
} else {
|
||||
number.value--;
|
||||
(proxy as any)?.$modal.closeLoading();
|
||||
(proxy as any)?.$modal.msgError(res.msg);
|
||||
// 提供更详细的错误信息
|
||||
const errorMsg = res.msg || '上传失败,请重试';
|
||||
(proxy as any)?.$modal.msgError(errorMsg);
|
||||
imageUploadRef.value?.handleRemove(file);
|
||||
uploadedSuccessfully();
|
||||
}
|
||||
@@ -657,9 +688,62 @@ const uploadedSuccessfully = async () => {
|
||||
};
|
||||
|
||||
// 上传失败
|
||||
const handleUploadError = () => {
|
||||
(proxy as any)?.$modal.msgError('上传图片失败');
|
||||
const handleUploadError = (error: any, file: any) => {
|
||||
console.error('上传失败详细信息:', error);
|
||||
|
||||
// 清除上传超时处理
|
||||
if (file && (file as any).uploadTimeoutId) {
|
||||
clearTimeout((file as any).uploadTimeoutId);
|
||||
}
|
||||
|
||||
// 确保关闭loading
|
||||
(proxy as any)?.$modal.closeLoading();
|
||||
|
||||
// 减少计数器
|
||||
number.value--;
|
||||
|
||||
// 根据错误类型提供不同的错误信息
|
||||
let errorMessage = '上传图片失败';
|
||||
|
||||
if (error.response) {
|
||||
const status = error.response.status;
|
||||
const responseData = error.response.data;
|
||||
|
||||
switch (status) {
|
||||
case 403:
|
||||
errorMessage = '没有文件上传权限,请联系管理员';
|
||||
break;
|
||||
case 413:
|
||||
errorMessage = '文件太大,超过服务器限制';
|
||||
break;
|
||||
case 500:
|
||||
errorMessage = '服务器内部错误,请稍后重试';
|
||||
break;
|
||||
case 504:
|
||||
errorMessage = '上传超时,请检查网络连接';
|
||||
break;
|
||||
default:
|
||||
if (responseData && responseData.msg) {
|
||||
errorMessage = responseData.msg;
|
||||
} else if (responseData && typeof responseData === 'string') {
|
||||
errorMessage = `上传失败: ${responseData}`;
|
||||
} else {
|
||||
errorMessage = `上传失败,错误代码: ${status}`;
|
||||
}
|
||||
}
|
||||
} else if (error.request) {
|
||||
// 网络错误
|
||||
if (error.code === 'ECONNABORTED' || error.message.includes('timeout')) {
|
||||
errorMessage = '上传超时,请检查网络连接或文件大小';
|
||||
} else {
|
||||
errorMessage = '网络连接错误,请检查网络设置';
|
||||
}
|
||||
} else if (error.message) {
|
||||
errorMessage = `上传失败: ${error.message}`;
|
||||
}
|
||||
|
||||
console.error('上传错误信息:', errorMessage);
|
||||
(proxy as any)?.$modal.msgError(errorMessage);
|
||||
};
|
||||
|
||||
// 预览
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
## 功能特性
|
||||
|
||||
### 1. 统计概览
|
||||
|
||||
- 待审核申请数量
|
||||
- 已通过申请数量
|
||||
- 已通过申请数量
|
||||
- 已拒绝申请数量
|
||||
- 总处理数量
|
||||
|
||||
### 2. 待审核申请管理
|
||||
|
||||
- 查看待审核申请列表
|
||||
- 支持多条件搜索(岗位名称、学生姓名、学号、学院名称、申请日期)
|
||||
- 单个申请审核(通过/拒绝)
|
||||
@@ -20,6 +22,7 @@
|
||||
- 查看申请详情
|
||||
|
||||
### 3. 所有申请查看
|
||||
|
||||
- 查看所有申请记录
|
||||
- 支持按状态筛选
|
||||
- 导出申请数据
|
||||
@@ -40,16 +43,19 @@ xgreview/
|
||||
## 技术特点
|
||||
|
||||
### 1. 响应式设计
|
||||
|
||||
- 使用Vue 3 Composition API
|
||||
- TypeScript类型支持
|
||||
- Element Plus UI组件库
|
||||
|
||||
### 2. 数据管理
|
||||
|
||||
- 基于学工处审核API
|
||||
- 支持分页查询
|
||||
- 实时数据更新
|
||||
|
||||
### 3. 用户体验
|
||||
|
||||
- 加载状态提示
|
||||
- 操作反馈消息
|
||||
- 响应式布局
|
||||
@@ -57,6 +63,7 @@ xgreview/
|
||||
## API接口
|
||||
|
||||
### 主要接口
|
||||
|
||||
- `listPendingApplications` - 获取待审核申请列表
|
||||
- `listStudentAffairsApplications` - 获取所有申请列表
|
||||
- `getStudentAffairsApplication` - 获取申请详情
|
||||
@@ -68,15 +75,18 @@ xgreview/
|
||||
## 使用说明
|
||||
|
||||
### 1. 访问路径
|
||||
|
||||
```
|
||||
/jcbt/workstudy/xgreview
|
||||
```
|
||||
|
||||
### 2. 权限要求
|
||||
|
||||
- 需要学工处审核权限
|
||||
- 支持批量操作权限
|
||||
|
||||
### 3. 操作流程
|
||||
|
||||
1. 查看统计概览,了解待处理申请数量
|
||||
2. 在"待审核申请"标签页中查看待处理申请
|
||||
3. 使用搜索功能筛选特定申请
|
||||
@@ -100,16 +110,19 @@ xgreview/
|
||||
## 开发说明
|
||||
|
||||
### 1. 组件复用
|
||||
|
||||
本模块复用了学院审核模块的组件结构,但使用不同的API接口和字段。
|
||||
|
||||
### 2. 样式规范
|
||||
|
||||
遵循项目的前端开发规范,使用统一的颜色主题和组件样式。
|
||||
|
||||
### 3. 错误处理
|
||||
|
||||
包含完整的错误处理机制,提供用户友好的错误提示。
|
||||
|
||||
## 更新日志
|
||||
|
||||
- **2025-01-03**:创建学工处审核模块
|
||||
- **2025-01-03**:实现基础审核功能
|
||||
- **2025-01-03**:添加统计概览和批量操作
|
||||
- **2025-01-03**:添加统计概览和批量操作
|
||||
@@ -7,12 +7,14 @@
|
||||
## ✅ 已完成功能
|
||||
|
||||
### 1. 主页面 (index.vue)
|
||||
|
||||
- ✅ 统计卡片展示(待审核、已通过、已拒绝、总计)
|
||||
- ✅ 标签页切换(待审核申请、所有申请)
|
||||
- ✅ 响应式布局和美观的UI设计
|
||||
- ✅ 与后勤管理模块保持一致的样式风格
|
||||
|
||||
### 2. 待审核申请组件 (PendingApplications.vue)
|
||||
|
||||
- ✅ 多条件搜索表单(岗位名称、学生姓名、学号、学院名称、申请日期)
|
||||
- ✅ 批量操作按钮(批量通过、批量拒绝)
|
||||
- ✅ 数据表格展示(包含学院审核状态)
|
||||
@@ -22,6 +24,7 @@
|
||||
- ✅ 分页功能
|
||||
|
||||
### 3. 所有申请组件 (AllApplications.vue)
|
||||
|
||||
- ✅ 扩展搜索条件(包含学工处审核状态)
|
||||
- ✅ 完整申请列表展示
|
||||
- ✅ 学院审核和学工处审核状态对比
|
||||
@@ -29,6 +32,7 @@
|
||||
- ✅ 审核操作(针对待审核状态)
|
||||
|
||||
### 4. 申请详情组件 (ApplicationDetail.vue)
|
||||
|
||||
- ✅ 完整的申请信息展示
|
||||
- ✅ 学院审核信息展示
|
||||
- ✅ 学工处审核信息展示
|
||||
@@ -36,23 +40,27 @@
|
||||
- ✅ 立即审核功能
|
||||
|
||||
### 5. 路由配置 (jcbt.ts)
|
||||
|
||||
- ✅ 创建jcbt模块路由配置
|
||||
- ✅ 包含学工处审核模块路由
|
||||
- ✅ 支持懒加载
|
||||
|
||||
### 6. 文档说明
|
||||
|
||||
- ✅ README.md - 详细的功能说明和使用指南
|
||||
- ✅ 开发总结.md - 开发过程和成果总结
|
||||
|
||||
## 🏗️ 技术架构
|
||||
|
||||
### 前端技术栈
|
||||
|
||||
- **Vue 3.5.13** + **TypeScript 5.8.3**
|
||||
- **Element Plus** UI组件库
|
||||
- **Composition API** 响应式编程
|
||||
- **SCSS** 样式预处理器
|
||||
|
||||
### 组件结构
|
||||
|
||||
```
|
||||
xgreview/
|
||||
├── index.vue # 主页面
|
||||
@@ -66,6 +74,7 @@ xgreview/
|
||||
```
|
||||
|
||||
### API接口
|
||||
|
||||
- 基于 `@/api/jcbt/workStudyApplicationStudentAffairsReview.ts`
|
||||
- 支持加密请求(AES+RSA)
|
||||
- 完整的CRUD操作接口
|
||||
@@ -73,16 +82,19 @@ xgreview/
|
||||
## 🎨 设计特点
|
||||
|
||||
### 1. 视觉一致性
|
||||
|
||||
- 与学院审核模块保持完全一致的视觉风格
|
||||
- 使用相同的颜色主题和组件样式
|
||||
- 统一的布局结构和交互模式
|
||||
|
||||
### 2. 用户体验
|
||||
|
||||
- 响应式设计,支持不同屏幕尺寸
|
||||
- 加载状态提示和操作反馈
|
||||
- 直观的操作流程和清晰的界面布局
|
||||
|
||||
### 3. 功能完整性
|
||||
|
||||
- 覆盖完整的审核业务流程
|
||||
- 支持单个和批量操作
|
||||
- 提供详细的数据展示和操作记录
|
||||
@@ -90,53 +102,61 @@ xgreview/
|
||||
## 🔧 开发规范遵循
|
||||
|
||||
### 1. 前端开发规范
|
||||
|
||||
- ✅ 遵循 `.cursor/cursorrules-frontend.md` 规范
|
||||
- ✅ 使用Vue 3 Composition API
|
||||
- ✅ TypeScript类型定义完整
|
||||
- ✅ 组件化开发,代码复用
|
||||
|
||||
### 2. 项目结构规范
|
||||
|
||||
- ✅ 页面代码存放在 `web/src/views/jcbt/workstudy/xgreview/`
|
||||
- ✅ API代码存放在 `web/src/api/jcbt/`
|
||||
- ✅ 路由配置存放在 `web/src/router/`
|
||||
|
||||
### 3. 代码质量
|
||||
|
||||
- ✅ 完整的错误处理机制
|
||||
- ✅ 清晰的代码注释和文档
|
||||
- ✅ 遵循Vue 3最佳实践
|
||||
|
||||
## 📊 功能对比
|
||||
|
||||
| 功能模块 | 学院审核 | 学工处审核 | 状态 |
|
||||
|---------|---------|-----------|------|
|
||||
| 统计概览 | ✅ | ✅ | 完全一致 |
|
||||
| 待审核列表 | ✅ | ✅ | 完全一致 |
|
||||
| 所有申请 | ✅ | ✅ | 完全一致 |
|
||||
| 申请详情 | ✅ | ✅ | 完全一致 |
|
||||
| 审核操作 | ✅ | ✅ | 完全一致 |
|
||||
| 批量操作 | ✅ | ✅ | 完全一致 |
|
||||
| 导出功能 | ✅ | ✅ | 完全一致 |
|
||||
| 功能模块 | 学院审核 | 学工处审核 | 状态 |
|
||||
| ---------- | -------- | ---------- | -------- |
|
||||
| 统计概览 | ✅ | ✅ | 完全一致 |
|
||||
| 待审核列表 | ✅ | ✅ | 完全一致 |
|
||||
| 所有申请 | ✅ | ✅ | 完全一致 |
|
||||
| 申请详情 | ✅ | ✅ | 完全一致 |
|
||||
| 审核操作 | ✅ | ✅ | 完全一致 |
|
||||
| 批量操作 | ✅ | ✅ | 完全一致 |
|
||||
| 导出功能 | ✅ | ✅ | 完全一致 |
|
||||
|
||||
## 🚀 部署说明
|
||||
|
||||
### 1. 文件位置
|
||||
|
||||
所有文件已正确放置在指定目录:
|
||||
|
||||
- 主页面:`web/src/views/jcbt/workstudy/xgreview/index.vue`
|
||||
- 组件:`web/src/views/jcbt/workstudy/xgreview/components/`
|
||||
- 路由:`web/src/router/jcbt.ts`
|
||||
|
||||
### 2. 访问路径
|
||||
|
||||
```
|
||||
/jcbt/workstudy/xgreview
|
||||
```
|
||||
|
||||
### 3. 权限要求
|
||||
|
||||
- 需要学工处审核权限
|
||||
- 支持批量操作权限
|
||||
|
||||
## 🔍 测试建议
|
||||
|
||||
### 1. 功能测试
|
||||
|
||||
- 统计数据展示
|
||||
- 搜索和筛选功能
|
||||
- 审核操作流程
|
||||
@@ -144,11 +164,13 @@ xgreview/
|
||||
- 导出功能
|
||||
|
||||
### 2. 兼容性测试
|
||||
|
||||
- 不同浏览器兼容性
|
||||
- 不同屏幕尺寸响应式
|
||||
- 权限控制验证
|
||||
|
||||
### 3. 性能测试
|
||||
|
||||
- 大数据量加载性能
|
||||
- 操作响应速度
|
||||
- 内存使用情况
|
||||
@@ -156,16 +178,19 @@ xgreview/
|
||||
## 📝 后续优化建议
|
||||
|
||||
### 1. 功能增强
|
||||
|
||||
- 添加审核历史记录
|
||||
- 支持审核意见模板
|
||||
- 增加数据统计图表
|
||||
|
||||
### 2. 性能优化
|
||||
|
||||
- 实现虚拟滚动
|
||||
- 添加数据缓存
|
||||
- 优化API请求
|
||||
|
||||
### 3. 用户体验
|
||||
|
||||
- 添加操作引导
|
||||
- 支持快捷键操作
|
||||
- 增加个性化设置
|
||||
@@ -186,4 +211,4 @@ xgreview/
|
||||
**开发完成时间**:2025-01-03
|
||||
**开发状态**:✅ 完成
|
||||
**代码质量**:⭐⭐⭐⭐⭐
|
||||
**文档完整性**:⭐⭐⭐⭐⭐
|
||||
**文档完整性**:⭐⭐⭐⭐⭐
|
||||
@@ -216,8 +216,8 @@
|
||||
</template>
|
||||
|
||||
<script setup name="InternshipCheckin">
|
||||
import { checkIn } from "@/api/zsjy/internshipDaily";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
import { checkIn } from '@/api/zsjy/internshipDaily';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -273,7 +273,7 @@ const getRecentRecords = () => {
|
||||
workDuration: 8,
|
||||
status: '1',
|
||||
workContent: '参与项目开发,完成用户模块设计'
|
||||
},
|
||||
}
|
||||
// 更多记录...
|
||||
];
|
||||
};
|
||||
|
||||
@@ -212,13 +212,7 @@
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div class="pagination-container">
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page="queryParams.pageNum"
|
||||
:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
@@ -244,10 +238,10 @@
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="签到地点" :span="2">{{ currentRecord.checkInLocation || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="工作内容" :span="2">
|
||||
<div style="white-space: pre-wrap;">{{ currentRecord.workContent || '-' }}</div>
|
||||
<div style="white-space: pre-wrap">{{ currentRecord.workContent || '-' }}</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">
|
||||
<div style="white-space: pre-wrap;">{{ currentRecord.remark || '-' }}</div>
|
||||
<div style="white-space: pre-wrap">{{ currentRecord.remark || '-' }}</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
@@ -277,10 +271,7 @@
|
||||
<div class="calendar-day">
|
||||
<div class="day-number">{{ data.day.split('-').slice(2).join('') }}</div>
|
||||
<div v-if="getAttendanceStatus(data.day)" class="attendance-status">
|
||||
<el-tag
|
||||
:type="getStatusTagType(getAttendanceStatus(data.day))"
|
||||
size="small"
|
||||
>
|
||||
<el-tag :type="getStatusTagType(getAttendanceStatus(data.day))" size="small">
|
||||
{{ getStatusText(getAttendanceStatus(data.day)) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
@@ -350,25 +341,13 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="签到状态" prop="status">
|
||||
<el-select v-model="addForm.status" placeholder="请选择签到状态" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in attendanceStatusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<el-option v-for="item in attendanceStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作时长" prop="workDuration">
|
||||
<el-input-number
|
||||
v-model="addForm.workDuration"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:precision="1"
|
||||
placeholder="工作时长(小时)"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<el-input-number v-model="addForm.workDuration" :min="0" :max="24" :precision="1" placeholder="工作时长(小时)" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -376,24 +355,10 @@
|
||||
<el-input v-model="addForm.checkInLocation" placeholder="请输入签到地点" />
|
||||
</el-form-item>
|
||||
<el-form-item label="工作内容" prop="workContent">
|
||||
<el-input
|
||||
v-model="addForm.workContent"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入工作内容"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-input v-model="addForm.workContent" type="textarea" :rows="3" placeholder="请输入工作内容" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="addForm.remark"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入备注"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-input v-model="addForm.remark" type="textarea" :rows="2" placeholder="请输入备注" maxlength="200" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -447,24 +412,12 @@ const addForm = ref({
|
||||
|
||||
// 新增表单验证规则
|
||||
const addFormRules = ref({
|
||||
studentName: [
|
||||
{ required: true, message: '请输入学生姓名', trigger: 'blur' }
|
||||
],
|
||||
studentNumber: [
|
||||
{ required: true, message: '请输入学号', trigger: 'blur' }
|
||||
],
|
||||
className: [
|
||||
{ required: true, message: '请输入班级', trigger: 'blur' }
|
||||
],
|
||||
companyName: [
|
||||
{ required: true, message: '请输入实习单位', trigger: 'blur' }
|
||||
],
|
||||
checkInTime: [
|
||||
{ required: true, message: '请选择签到时间', trigger: 'change' }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '请选择签到状态', trigger: 'change' }
|
||||
]
|
||||
studentName: [{ required: true, message: '请输入学生姓名', trigger: 'blur' }],
|
||||
studentNumber: [{ required: true, message: '请输入学号', trigger: 'blur' }],
|
||||
className: [{ required: true, message: '请输入班级', trigger: 'blur' }],
|
||||
companyName: [{ required: true, message: '请输入实习单位', trigger: 'blur' }],
|
||||
checkInTime: [{ required: true, message: '请选择签到时间', trigger: 'change' }],
|
||||
status: [{ required: true, message: '请选择签到状态', trigger: 'change' }]
|
||||
});
|
||||
|
||||
// 查询参数
|
||||
@@ -500,7 +453,7 @@ const getList = () => {
|
||||
queryParams.value.checkTimeEnd = '';
|
||||
}
|
||||
|
||||
listInternshipDaily(queryParams.value).then(response => {
|
||||
listInternshipDaily(queryParams.value).then((response) => {
|
||||
internshipDailyList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
@@ -510,13 +463,15 @@ const getList = () => {
|
||||
// 获取统计数据
|
||||
const getStatisticsData = () => {
|
||||
console.log('正在获取统计数据...');
|
||||
getStatistics().then(response => {
|
||||
console.log('统计数据响应:', response);
|
||||
statistics.value = response.data || {};
|
||||
console.log('设置的统计数据:', statistics.value);
|
||||
}).catch(error => {
|
||||
console.error('获取统计数据失败:', error);
|
||||
});
|
||||
getStatistics()
|
||||
.then((response) => {
|
||||
console.log('统计数据响应:', response);
|
||||
statistics.value = response.data || {};
|
||||
console.log('设置的统计数据:', statistics.value);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取统计数据失败:', error);
|
||||
});
|
||||
};
|
||||
|
||||
// 搜索按钮操作
|
||||
@@ -528,7 +483,7 @@ const handleQuery = () => {
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
daterangeCheckTime.value = [];
|
||||
proxy.resetForm("queryFormRef");
|
||||
proxy.resetForm('queryFormRef');
|
||||
queryParams.value = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
@@ -581,17 +536,19 @@ const cancelAdd = () => {
|
||||
|
||||
// 提交新增
|
||||
const submitAdd = () => {
|
||||
proxy.$refs.addFormRef.validate(valid => {
|
||||
proxy.$refs.addFormRef.validate((valid) => {
|
||||
if (valid) {
|
||||
addLoading.value = true;
|
||||
|
||||
addInternshipDaily(addForm.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增签到记录成功");
|
||||
addDialogVisible.value = false;
|
||||
getList();
|
||||
}).finally(() => {
|
||||
addLoading.value = false;
|
||||
});
|
||||
addInternshipDaily(addForm.value)
|
||||
.then((response) => {
|
||||
proxy.$modal.msgSuccess('新增签到记录成功');
|
||||
addDialogVisible.value = false;
|
||||
getList();
|
||||
})
|
||||
.finally(() => {
|
||||
addLoading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -625,16 +582,14 @@ const loadCalendarData = () => {
|
||||
month: calendarMonth.value
|
||||
};
|
||||
|
||||
getCalendar(currentStudent.value.studentId, params).then(response => {
|
||||
getCalendar(currentStudent.value.studentId, params).then((response) => {
|
||||
calendarData.value = response.data || [];
|
||||
});
|
||||
};
|
||||
|
||||
// 获取考勤状态
|
||||
const getAttendanceStatus = (date) => {
|
||||
const record = calendarData.value.find(item =>
|
||||
item.checkDate === date
|
||||
);
|
||||
const record = calendarData.value.find((item) => item.checkDate === date);
|
||||
return record ? record.status : null;
|
||||
};
|
||||
|
||||
@@ -662,9 +617,13 @@ const getStatusText = (status) => {
|
||||
|
||||
// 导出按钮操作
|
||||
const handleExport = () => {
|
||||
proxy.download('zsjy/internship/daily/export', {
|
||||
...queryParams.value
|
||||
}, `实习日常记录_${new Date().getTime()}.xlsx`);
|
||||
proxy.download(
|
||||
'zsjy/internship/daily/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`实习日常记录_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
// 初始化
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="新增实习信息"
|
||||
width="80%"
|
||||
:before-close="handleClose"
|
||||
draggable
|
||||
destroy-on-close
|
||||
>
|
||||
<el-dialog v-model="visible" title="新增实习信息" width="80%" :before-close="handleClose" draggable destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="form-container">
|
||||
<el-row :gutter="24">
|
||||
<!-- 基本信息 -->
|
||||
@@ -32,7 +25,14 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实习津贴" prop="internshipAllowance">
|
||||
<el-input-number v-model="form.internshipAllowance" :min="0" :precision="2" controls-position="right" placeholder="实习津贴" style="width: 100%" />
|
||||
<el-input-number
|
||||
v-model="form.internshipAllowance"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
placeholder="实习津贴"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
@@ -363,4 +363,3 @@ const handleSubmit = async () => {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="编辑实习信息"
|
||||
width="80%"
|
||||
:before-close="handleClose"
|
||||
draggable
|
||||
destroy-on-close
|
||||
>
|
||||
<el-dialog v-model="visible" title="编辑实习信息" width="80%" :before-close="handleClose" draggable destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="form-container" v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<!-- 基本信息 -->
|
||||
@@ -32,7 +25,14 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实习津贴" prop="internshipAllowance">
|
||||
<el-input-number v-model="form.internshipAllowance" :min="0" :precision="2" controls-position="right" placeholder="实习津贴" style="width: 100%" />
|
||||
<el-input-number
|
||||
v-model="form.internshipAllowance"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
placeholder="实习津贴"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
@@ -277,12 +277,15 @@ const rules = reactive({
|
||||
});
|
||||
|
||||
// 监听弹窗显示状态
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
visible.value = newVal;
|
||||
if (newVal && props.studentId) {
|
||||
getInternshipDetail();
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
visible.value = newVal;
|
||||
if (newVal && props.studentId) {
|
||||
getInternshipDetail();
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
watch(visible, (newVal) => {
|
||||
emit('update:modelValue', newVal);
|
||||
@@ -434,4 +437,3 @@ const handleDelete = async () => {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -191,8 +191,6 @@
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
|
||||
|
||||
<!-- 学生实习详情对话框 -->
|
||||
<el-dialog title="学生实习详情" v-model="dialog.visible" width="900px" append-to-body>
|
||||
<div v-if="studentDetail" class="student-detail">
|
||||
@@ -226,7 +224,9 @@
|
||||
<el-descriptions-item label="单位联系人">{{ studentDetail.contactPersonName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人电话">{{ studentDetail.contactPersonPhone || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实习津贴">
|
||||
<span v-if="studentDetail.internshipAllowance && studentDetail.internshipAllowance > 0">{{ studentDetail.internshipAllowance }}元/月</span>
|
||||
<span v-if="studentDetail.internshipAllowance && studentDetail.internshipAllowance > 0"
|
||||
>{{ studentDetail.internshipAllowance }}元/月</span
|
||||
>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="协议状态">
|
||||
@@ -245,18 +245,10 @@
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新增弹窗 -->
|
||||
<AddDialog
|
||||
v-model="showAddDialog"
|
||||
:student-info="selectedStudentInfo"
|
||||
@success="handleDialogSuccess"
|
||||
/>
|
||||
<AddDialog v-model="showAddDialog" :student-info="selectedStudentInfo" @success="handleDialogSuccess" />
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<EditDialog
|
||||
v-model="showEditDialog"
|
||||
:student-id="selectedStudentId"
|
||||
@success="handleDialogSuccess"
|
||||
/>
|
||||
<EditDialog v-model="showEditDialog" :student-id="selectedStudentId" @success="handleDialogSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user