提交
This commit is contained in:
1 parent
86401c7753
commit
8783150883
13 files changed
+10336
-2
No files matched your search
+119
@@ -0,0 +1,119 @@
|
|||||||
|
package org.dromara.xg.controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.validation.constraints.*;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||||
|
import org.dromara.common.log.annotation.Log;
|
||||||
|
import org.dromara.common.web.core.BaseController;
|
||||||
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
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.log.enums.BusinessType;
|
||||||
|
import org.dromara.common.excel.utils.ExcelUtil;
|
||||||
|
import org.dromara.xg.domain.vo.XgStudentStatusChangeVo;
|
||||||
|
import org.dromara.xg.domain.bo.XgStudentStatusChangeBo;
|
||||||
|
import org.dromara.xg.service.IXgStudentStatusChangeService;
|
||||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/studentMsg/studentStatusChange")
|
||||||
|
public class XgStudentStatusChangeController extends BaseController {
|
||||||
|
|
||||||
|
private final IXgStudentStatusChangeService xgStudentStatusChangeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询学生学籍异动列表
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo<XgStudentStatusChangeVo> list(XgStudentStatusChangeBo bo, PageQuery pageQuery) {
|
||||||
|
return xgStudentStatusChangeService.queryPageList(bo, pageQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出学生学籍异动列表
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:export")
|
||||||
|
@Log(title = "学生学籍异动", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(XgStudentStatusChangeBo bo, HttpServletResponse response) {
|
||||||
|
List<XgStudentStatusChangeVo> list = xgStudentStatusChangeService.queryList(bo);
|
||||||
|
ExcelUtil.exportExcel(list, "学生学籍异动", XgStudentStatusChangeVo.class, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取学生学籍异动详细信息
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:query")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R<XgStudentStatusChangeVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||||
|
return R.ok(xgStudentStatusChangeService.queryById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增学生学籍异动
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:add")
|
||||||
|
@Log(title = "学生学籍异动", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping()
|
||||||
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody XgStudentStatusChangeBo bo) {
|
||||||
|
return toAjax(xgStudentStatusChangeService.insertByBo(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量新增学生学籍异动(用于前端提交多个学生的异动)
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:add")
|
||||||
|
@Log(title = "学生学籍异动", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping("/batch")
|
||||||
|
public R<Void> addBatch(@Validated(AddGroup.class) @RequestBody List<XgStudentStatusChangeBo> boList) {
|
||||||
|
boolean result = true;
|
||||||
|
for (XgStudentStatusChangeBo bo : boList) {
|
||||||
|
result &= xgStudentStatusChangeService.insertByBo(bo);
|
||||||
|
}
|
||||||
|
return toAjax(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改学生学籍异动
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:edit")
|
||||||
|
@Log(title = "学生学籍异动", businessType = BusinessType.UPDATE)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PutMapping()
|
||||||
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody XgStudentStatusChangeBo bo) {
|
||||||
|
return toAjax(xgStudentStatusChangeService.updateByBo(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生学籍异动
|
||||||
|
*
|
||||||
|
* @param ids 主键串
|
||||||
|
*/
|
||||||
|
// @SaCheckPermission("studentMsg:studentStatusChange:remove")
|
||||||
|
@Log(title = "学生学籍异动", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
|
||||||
|
return toAjax(xgStudentStatusChangeService.deleteWithValidByIds(List.of(ids), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
package org.dromara.xg.domain;
|
||||||
|
|
||||||
|
import org.dromara.common.tenant.core.TenantEntity;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动对象 xg_student_status_change
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("xg_student_status_change")
|
||||||
|
public class XgStudentStatusChange extends TenantEntity {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键,雪花ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标志(0代表存在 1代表删除)
|
||||||
|
*/
|
||||||
|
@TableLogic(value = "0", delval = "1")
|
||||||
|
private Long deleted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生ID,关联学生主表
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学号
|
||||||
|
*/
|
||||||
|
private String studentNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业)
|
||||||
|
*/
|
||||||
|
private String changeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请/登记日期
|
||||||
|
*/
|
||||||
|
private Date applyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效日期(业务生效时间)
|
||||||
|
*/
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异动原因
|
||||||
|
*/
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经办人ID(登记人)
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经办人姓名
|
||||||
|
*/
|
||||||
|
private String operatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源: manual/import/workflow
|
||||||
|
*/
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理状态:0=未处理,1=已处理
|
||||||
|
*/
|
||||||
|
private Integer processStatus;
|
||||||
|
|
||||||
|
}
|
||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
package org.dromara.xg.domain.bo;
|
||||||
|
|
||||||
|
import org.dromara.xg.domain.XgStudentStatusChange;
|
||||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
|
import org.dromara.common.core.validate.AddGroup;
|
||||||
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import jakarta.validation.constraints.*;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动业务对象 xg_student_status_change
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@AutoMapper(target = XgStudentStatusChange.class, reverseConvertGenerate = false)
|
||||||
|
public class XgStudentStatusChangeBo extends BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键,雪花ID
|
||||||
|
*/
|
||||||
|
@NotNull(message = "主键,雪花ID不能为空", groups = { EditGroup.class })
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生ID,关联学生主表
|
||||||
|
*/
|
||||||
|
@NotNull(message = "学生ID,关联学生主表不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Long studentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学号
|
||||||
|
*/
|
||||||
|
private String studentNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业)
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业)不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String changeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请/登记日期
|
||||||
|
*/
|
||||||
|
@NotNull(message = "申请/登记日期不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Date applyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效日期(业务生效时间)
|
||||||
|
*/
|
||||||
|
@NotNull(message = "生效日期(业务生效时间)不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异动原因
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "异动原因不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经办人ID(登记人)
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经办人姓名
|
||||||
|
*/
|
||||||
|
private String operatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源: manual/import/workflow
|
||||||
|
*/
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理状态:0=未处理,1=已处理
|
||||||
|
*/
|
||||||
|
private Integer processStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建部门
|
||||||
|
*/
|
||||||
|
private Long createDept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注信息
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
package org.dromara.xg.domain.vo;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.dromara.xg.domain.XgStudentStatusChange;
|
||||||
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
|
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动视图对象 xg_student_status_change
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
@AutoMapper(target = XgStudentStatusChange.class)
|
||||||
|
public class XgStudentStatusChangeVo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键,雪花ID
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "主键,雪花ID", converter = ExcelDictConvert.class)
|
||||||
|
@ExcelDictFormat(readConverterExp = "雪=花ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生ID,关联学生主表
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "学生ID,关联学生主表")
|
||||||
|
private Long studentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学号
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "学号")
|
||||||
|
private String studentNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生姓名
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "学生姓名")
|
||||||
|
private String studentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班级名称
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "班级名称")
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 专业名称
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "专业名称")
|
||||||
|
private String majorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学院名称
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "学院名称")
|
||||||
|
private String collegeName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "异动类型")
|
||||||
|
private String changeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请/登记日期
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "申请/登记日期")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date applyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效日期(业务生效时间)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "生效日期")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date effectiveDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异动原因
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "异动原因")
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经办人ID(登记人)
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "经办人ID")
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经办人姓名
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "经办人姓名")
|
||||||
|
private String operatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源: manual/import/workflow
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "来源")
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理状态:0=未处理,1=已处理
|
||||||
|
*/
|
||||||
|
@ExcelProperty(value = "处理状态")
|
||||||
|
private Integer processStatus;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建部门
|
||||||
|
*/
|
||||||
|
private Long createDept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建者
|
||||||
|
*/
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新者
|
||||||
|
*/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package org.dromara.xg.mapper;
|
||||||
|
|
||||||
|
import org.dromara.xg.domain.XgStudentStatusChange;
|
||||||
|
import org.dromara.xg.domain.vo.XgStudentStatusChangeVo;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动Mapper接口
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
public interface XgStudentStatusChangeMapper extends BaseMapperPlus<XgStudentStatusChange, XgStudentStatusChangeVo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询学生学籍异动列表(包含学生信息)
|
||||||
|
*/
|
||||||
|
Page<XgStudentStatusChangeVo> selectVoPageWithStudentInfo(IPage<XgStudentStatusChange> page, LambdaQueryWrapper<XgStudentStatusChange> lqw);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询学生学籍异动列表(包含学生信息)
|
||||||
|
*/
|
||||||
|
List<XgStudentStatusChangeVo> selectVoListWithStudentInfo(LambdaQueryWrapper<XgStudentStatusChange> lqw);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询学生学籍异动(包含学生信息)
|
||||||
|
*/
|
||||||
|
XgStudentStatusChangeVo selectVoByIdWithStudentInfo(Long id);
|
||||||
|
|
||||||
|
}
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
package org.dromara.xg.service;
|
||||||
|
|
||||||
|
import org.dromara.xg.domain.vo.XgStudentStatusChangeVo;
|
||||||
|
import org.dromara.xg.domain.bo.XgStudentStatusChangeBo;
|
||||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动Service接口
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
public interface IXgStudentStatusChangeService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询学生学籍异动
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
* @return 学生学籍异动
|
||||||
|
*/
|
||||||
|
XgStudentStatusChangeVo queryById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询学生学籍异动列表
|
||||||
|
*
|
||||||
|
* @param bo 查询条件
|
||||||
|
* @param pageQuery 分页参数
|
||||||
|
* @return 学生学籍异动分页列表
|
||||||
|
*/
|
||||||
|
TableDataInfo<XgStudentStatusChangeVo> queryPageList(XgStudentStatusChangeBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询符合条件的学生学籍异动列表
|
||||||
|
*
|
||||||
|
* @param bo 查询条件
|
||||||
|
* @return 学生学籍异动列表
|
||||||
|
*/
|
||||||
|
List<XgStudentStatusChangeVo> queryList(XgStudentStatusChangeBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增学生学籍异动
|
||||||
|
*
|
||||||
|
* @param bo 学生学籍异动
|
||||||
|
* @return 是否新增成功
|
||||||
|
*/
|
||||||
|
Boolean insertByBo(XgStudentStatusChangeBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改学生学籍异动
|
||||||
|
*
|
||||||
|
* @param bo 学生学籍异动
|
||||||
|
* @return 是否修改成功
|
||||||
|
*/
|
||||||
|
Boolean updateByBo(XgStudentStatusChangeBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并批量删除学生学籍异动信息
|
||||||
|
*
|
||||||
|
* @param ids 待删除的主键集合
|
||||||
|
* @param isValid 是否进行有效性校验
|
||||||
|
* @return 是否删除成功
|
||||||
|
*/
|
||||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
|
}
|
||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
package org.dromara.xg.service.impl;
|
||||||
|
|
||||||
|
import org.dromara.common.core.utils.MapstructUtils;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.dromara.xg.domain.bo.XgStudentStatusChangeBo;
|
||||||
|
import org.dromara.xg.domain.vo.XgStudentStatusChangeVo;
|
||||||
|
import org.dromara.xg.domain.XgStudentStatusChange;
|
||||||
|
import org.dromara.xg.mapper.XgStudentStatusChangeMapper;
|
||||||
|
import org.dromara.xg.service.IXgStudentStatusChangeService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生学籍异动Service业务层处理
|
||||||
|
*
|
||||||
|
* @author zlwu
|
||||||
|
* @date 2025-07-23
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class XgStudentStatusChangeServiceImpl implements IXgStudentStatusChangeService {
|
||||||
|
|
||||||
|
private final XgStudentStatusChangeMapper baseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询学生学籍异动
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
* @return 学生学籍异动
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public XgStudentStatusChangeVo queryById(Long id) {
|
||||||
|
return baseMapper.selectVoByIdWithStudentInfo(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询学生学籍异动列表
|
||||||
|
*
|
||||||
|
* @param bo 查询条件
|
||||||
|
* @param pageQuery 分页参数
|
||||||
|
* @return 学生学籍异动分页列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TableDataInfo<XgStudentStatusChangeVo> queryPageList(XgStudentStatusChangeBo bo, PageQuery pageQuery) {
|
||||||
|
LambdaQueryWrapper<XgStudentStatusChange> lqw = buildQueryWrapper(bo);
|
||||||
|
Page<XgStudentStatusChange> page = pageQuery.build();
|
||||||
|
Page<XgStudentStatusChangeVo> result = baseMapper.selectVoPageWithStudentInfo(page, lqw);
|
||||||
|
return TableDataInfo.build(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询符合条件的学生学籍异动列表
|
||||||
|
*
|
||||||
|
* @param bo 查询条件
|
||||||
|
* @return 学生学籍异动列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<XgStudentStatusChangeVo> queryList(XgStudentStatusChangeBo bo) {
|
||||||
|
LambdaQueryWrapper<XgStudentStatusChange> lqw = buildQueryWrapper(bo);
|
||||||
|
return baseMapper.selectVoListWithStudentInfo(lqw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<XgStudentStatusChange> buildQueryWrapper(XgStudentStatusChangeBo bo) {
|
||||||
|
Map<String, Object> params = bo.getParams();
|
||||||
|
LambdaQueryWrapper<XgStudentStatusChange> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(bo.getId() != null, XgStudentStatusChange::getId, bo.getId());
|
||||||
|
lqw.eq(bo.getStudentId() != null, XgStudentStatusChange::getStudentId, bo.getStudentId());
|
||||||
|
lqw.like(StringUtils.isNotBlank(bo.getStudentNo()), XgStudentStatusChange::getStudentNo, bo.getStudentNo());
|
||||||
|
lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), XgStudentStatusChange::getChangeType, bo.getChangeType());
|
||||||
|
lqw.eq(bo.getEffectiveDate() != null, XgStudentStatusChange::getEffectiveDate, bo.getEffectiveDate());
|
||||||
|
lqw.like(StringUtils.isNotBlank(bo.getReason()), XgStudentStatusChange::getReason, bo.getReason());
|
||||||
|
lqw.eq(bo.getOperatorId() != null, XgStudentStatusChange::getOperatorId, bo.getOperatorId());
|
||||||
|
lqw.like(StringUtils.isNotBlank(bo.getOperatorName()), XgStudentStatusChange::getOperatorName, bo.getOperatorName());
|
||||||
|
lqw.eq(StringUtils.isNotBlank(bo.getSource()), XgStudentStatusChange::getSource, bo.getSource());
|
||||||
|
lqw.eq(bo.getProcessStatus() != null, XgStudentStatusChange::getProcessStatus, bo.getProcessStatus());
|
||||||
|
return lqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增学生学籍异动
|
||||||
|
*
|
||||||
|
* @param bo 学生学籍异动
|
||||||
|
* @return 是否新增成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean insertByBo(XgStudentStatusChangeBo bo) {
|
||||||
|
XgStudentStatusChange add = MapstructUtils.convert(bo, XgStudentStatusChange.class);
|
||||||
|
validEntityBeforeSave(add);
|
||||||
|
boolean flag = baseMapper.insert(add) > 0;
|
||||||
|
if (flag) {
|
||||||
|
bo.setId(add.getId());
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改学生学籍异动
|
||||||
|
*
|
||||||
|
* @param bo 学生学籍异动
|
||||||
|
* @return 是否修改成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean updateByBo(XgStudentStatusChangeBo bo) {
|
||||||
|
XgStudentStatusChange update = MapstructUtils.convert(bo, XgStudentStatusChange.class);
|
||||||
|
validEntityBeforeSave(update);
|
||||||
|
return baseMapper.updateById(update) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存前的数据校验
|
||||||
|
*/
|
||||||
|
private void validEntityBeforeSave(XgStudentStatusChange entity) {
|
||||||
|
// TODO 做一些数据校验,如唯一约束
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并批量删除学生学籍异动信息
|
||||||
|
*
|
||||||
|
* @param ids 待删除的主键集合
|
||||||
|
* @param isValid 是否进行有效性校验
|
||||||
|
* @return 是否删除成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||||
|
if (isValid) {
|
||||||
|
// TODO 做一些业务上的校验,判断是否需要校验
|
||||||
|
}
|
||||||
|
return baseMapper.deleteByIds(ids) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
<?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.xg.mapper.XgStudentStatusChangeMapper">
|
||||||
|
|
||||||
|
<resultMap id="XgStudentStatusChangeResult" type="org.dromara.xg.domain.vo.XgStudentStatusChangeVo">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="studentId" column="student_id"/>
|
||||||
|
<result property="studentNo" column="student_no"/>
|
||||||
|
<result property="studentName" column="student_name"/>
|
||||||
|
<result property="className" column="class_name"/>
|
||||||
|
<result property="majorName" column="major_name"/>
|
||||||
|
<result property="collegeName" column="college_name"/>
|
||||||
|
<result property="changeType" column="change_type"/>
|
||||||
|
<result property="applyDate" column="apply_date"/>
|
||||||
|
<result property="effectiveDate" column="effective_date"/>
|
||||||
|
<result property="reason" column="reason"/>
|
||||||
|
<result property="operatorId" column="operator_id"/>
|
||||||
|
<result property="operatorName" column="operator_name"/>
|
||||||
|
<result property="source" column="source"/>
|
||||||
|
<result property="processStatus" column="process_status"/>
|
||||||
|
<result property="createDept" column="create_dept"/>
|
||||||
|
<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="remark" column="remark"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectXgStudentStatusChangeVo">
|
||||||
|
select c.id, c.student_id, c.student_no,
|
||||||
|
s.name as student_name, s.class_name as class_name, s.major_name as major_name, s.college_name as college_name,
|
||||||
|
c.change_type, c.apply_date, c.effective_date,
|
||||||
|
c.reason, c.operator_id, c.operator_name, c.source, c.process_status,
|
||||||
|
c.create_dept, c.create_by, c.create_time, c.update_by, c.update_time
|
||||||
|
from xg_student_status_change c
|
||||||
|
left join xg_student_msg s on c.student_id = s.id and s.deleted = 0
|
||||||
|
where c.deleted = 0
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectVoList" resultMap="XgStudentStatusChangeResult">
|
||||||
|
<include refid="selectXgStudentStatusChangeVo"/>
|
||||||
|
${ew.getCustomSqlSegment}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectVoById" parameterType="Long" resultMap="XgStudentStatusChangeResult">
|
||||||
|
<include refid="selectXgStudentStatusChangeVo"/>
|
||||||
|
and c.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectVoPage" resultMap="XgStudentStatusChangeResult">
|
||||||
|
<include refid="selectXgStudentStatusChangeVo"/>
|
||||||
|
${ew.getCustomSqlSegment}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 自定义查询方法,包含学生信息 -->
|
||||||
|
<select id="selectVoPageWithStudentInfo" resultMap="XgStudentStatusChangeResult">
|
||||||
|
<include refid="selectXgStudentStatusChangeVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="lqw != null">
|
||||||
|
${lqw.getCustomSqlSegment}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by c.create_time desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectVoListWithStudentInfo" resultMap="XgStudentStatusChangeResult">
|
||||||
|
<include refid="selectXgStudentStatusChangeVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="lqw != null">
|
||||||
|
${lqw.getCustomSqlSegment}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by c.create_time desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectVoByIdWithStudentInfo" parameterType="Long" resultMap="XgStudentStatusChangeResult">
|
||||||
|
<include refid="selectXgStudentStatusChangeVo"/>
|
||||||
|
and c.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/** 学生学籍异动查询参数 */
|
||||||
|
export interface XgStudentStatusChangeQuery {
|
||||||
|
/** 学号 */
|
||||||
|
studentNo?: string;
|
||||||
|
/** 异动类型 */
|
||||||
|
changeType?: string;
|
||||||
|
/** 处理状态 */
|
||||||
|
processStatus?: number | null;
|
||||||
|
/** 经办人姓名 */
|
||||||
|
operatorName?: string;
|
||||||
|
/** 分页大小 */
|
||||||
|
pageSize: number;
|
||||||
|
/** 当前页码 */
|
||||||
|
pageNum: number;
|
||||||
|
/** 其他参数 */
|
||||||
|
params: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 学生学籍异动视图对象 */
|
||||||
|
export interface XgStudentStatusChangeVo {
|
||||||
|
/** 主键,雪花ID */
|
||||||
|
id: string | number;
|
||||||
|
/** 学生ID,关联学生主表 */
|
||||||
|
studentId?: string | number;
|
||||||
|
/** 学号 */
|
||||||
|
studentNo?: string;
|
||||||
|
/** 学生姓名 */
|
||||||
|
studentName?: string;
|
||||||
|
/** 班级名称 */
|
||||||
|
className?: string;
|
||||||
|
/** 专业名称 */
|
||||||
|
majorName?: string;
|
||||||
|
/** 学院名称 */
|
||||||
|
collegeName?: string;
|
||||||
|
/** 异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业) */
|
||||||
|
changeType?: string;
|
||||||
|
/** 申请/登记日期 */
|
||||||
|
applyDate?: string;
|
||||||
|
/** 生效日期(业务生效时间) */
|
||||||
|
effectiveDate?: string;
|
||||||
|
/** 异动原因 */
|
||||||
|
reason?: string;
|
||||||
|
/** 经办人ID(登记人) */
|
||||||
|
operatorId?: string | number;
|
||||||
|
/** 经办人姓名 */
|
||||||
|
operatorName?: string;
|
||||||
|
/** 来源: manual/import/workflow */
|
||||||
|
source?: string;
|
||||||
|
/** 处理状态:0=未处理,1=已处理 */
|
||||||
|
processStatus?: number;
|
||||||
|
/** 创建者 */
|
||||||
|
createBy?: string | number;
|
||||||
|
/** 创建时间 */
|
||||||
|
createTime?: string;
|
||||||
|
/** 更新者 */
|
||||||
|
updateBy?: string | number;
|
||||||
|
/** 更新时间 */
|
||||||
|
updateTime?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 学生学籍异动业务对象 */
|
||||||
|
export interface XgStudentStatusChangeBo {
|
||||||
|
/** 主键,雪花ID */
|
||||||
|
id?: string | number;
|
||||||
|
/** 学生ID,关联学生主表 */
|
||||||
|
studentId?: string | number;
|
||||||
|
/** 学号 */
|
||||||
|
studentNo?: string;
|
||||||
|
/** 异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业) */
|
||||||
|
changeType?: string;
|
||||||
|
/** 申请/登记日期 */
|
||||||
|
applyDate?: string;
|
||||||
|
/** 生效日期(业务生效时间) */
|
||||||
|
effectiveDate?: string;
|
||||||
|
/** 异动原因 */
|
||||||
|
reason?: string;
|
||||||
|
/** 经办人ID(登记人) */
|
||||||
|
operatorId?: string | number;
|
||||||
|
/** 经办人姓名 */
|
||||||
|
operatorName?: string;
|
||||||
|
/** 来源: manual/import/workflow */
|
||||||
|
source?: string;
|
||||||
|
/** 处理状态:0=未处理,1=已处理 */
|
||||||
|
processStatus?: number;
|
||||||
|
}
|
||||||
@@ -115,6 +115,18 @@
|
|||||||
<!-- <el-col :span="1.5">
|
<!-- <el-col :span="1.5">
|
||||||
<el-button :disabled="multiple" icon="Delete" @click="handleDelete()"> 删除 </el-button>
|
<el-button :disabled="multiple" icon="Delete" @click="handleDelete()"> 删除 </el-button>
|
||||||
</el-col> -->
|
</el-col> -->
|
||||||
|
<el-col :span="1.2">
|
||||||
|
<el-button type="danger" :disabled="multiple" @click="openStatusChangeModal('TUI_XUE')">退学</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.2">
|
||||||
|
<el-button type="warning" :disabled="multiple" @click="openStatusChangeModal('XIU_XUE')">休学</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.2">
|
||||||
|
<el-button type="success" :disabled="multiple" @click="openStatusChangeModal('FU_XUE')">复学</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.2">
|
||||||
|
<el-button type="primary" :disabled="multiple" @click="openStatusChangeModal('BI_YE')">毕业</el-button>
|
||||||
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-dropdown class="mt-[1px]">
|
<el-dropdown class="mt-[1px]">
|
||||||
<el-button>
|
<el-button>
|
||||||
@@ -1508,6 +1520,69 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 学籍异动弹窗 -->
|
||||||
|
<el-dialog v-model="statusChangeDialog.visible" :title="getStatusChangeDialogTitle()" width="900px" append-to-body>
|
||||||
|
<el-form ref="statusChangeFormRef" :model="statusChangeForm" :rules="statusChangeRules" label-width="120px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="异动类型" prop="changeType">
|
||||||
|
<el-select v-model="statusChangeForm.changeType" placeholder="请选择异动类型" style="width: 100%">
|
||||||
|
<el-option v-for="dict in xg_stu_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="生效日期" prop="effectiveDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="statusChangeForm.effectiveDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择生效日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
:disabled-date="disabledDate"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="异动原因" prop="reason">
|
||||||
|
<el-input v-model="statusChangeForm.reason" type="textarea" placeholder="请输入异动原因" :rows="3" maxlength="1000" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="经办人ID" prop="operatorId">
|
||||||
|
<el-input v-model="statusChangeForm.operatorId" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="经办人姓名" prop="operatorName">
|
||||||
|
<el-input v-model="statusChangeForm.operatorName" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item :label="`选中的学生 (${statusChangeForm.selectedStudents.length})`">
|
||||||
|
<div class="selected-students-container">
|
||||||
|
<div v-for="student in statusChangeForm.selectedStudents" :key="student.id" class="student-item">
|
||||||
|
<el-tag type="info">{{ student.studentNo }} - {{ student.name }}</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="statusChangeDialog.visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitStatusChange">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -1527,11 +1602,13 @@ import { globalHeaders } from '@/utils/request';
|
|||||||
// import type { FormInstance, TreeInstance } from 'element-plus';
|
// import type { FormInstance, TreeInstance } from 'element-plus';
|
||||||
import { Plus, ArrowDown, InfoFilled, Loading } from '@element-plus/icons-vue';
|
import { Plus, ArrowDown, InfoFilled, Loading } from '@element-plus/icons-vue';
|
||||||
import service from '@/utils/request';
|
import service from '@/utils/request';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
interface ComponentInternalInstance {
|
interface ComponentInternalInstance {
|
||||||
proxy?: any;
|
proxy?: any;
|
||||||
}
|
}
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
const userStore = useUserStore();
|
||||||
const {
|
const {
|
||||||
wenhuachengdu,
|
wenhuachengdu,
|
||||||
xg_political_status,
|
xg_political_status,
|
||||||
@@ -1551,7 +1628,8 @@ const {
|
|||||||
xg_training_mode,
|
xg_training_mode,
|
||||||
admission_category,
|
admission_category,
|
||||||
student_status,
|
student_status,
|
||||||
xg_class_status
|
xg_class_status,
|
||||||
|
xg_stu_status
|
||||||
} = toRefs<any>(
|
} = toRefs<any>(
|
||||||
proxy?.useDict(
|
proxy?.useDict(
|
||||||
'wenhuachengdu',
|
'wenhuachengdu',
|
||||||
@@ -1572,7 +1650,8 @@ const {
|
|||||||
'xg_training_mode',
|
'xg_training_mode',
|
||||||
'admission_category',
|
'admission_category',
|
||||||
'student_status',
|
'student_status',
|
||||||
'xg_class_status'
|
'xg_class_status',
|
||||||
|
'xg_stu_status'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1696,6 +1775,7 @@ const columns = ref([
|
|||||||
const deptTreeRef = ref<any>();
|
const deptTreeRef = ref<any>();
|
||||||
const queryFormRef = ref<any>();
|
const queryFormRef = ref<any>();
|
||||||
const studentFormRef = ref<any>();
|
const studentFormRef = ref<any>();
|
||||||
|
const statusChangeFormRef = ref<any>();
|
||||||
const uploadRef = ref<any>();
|
const uploadRef = ref<any>();
|
||||||
|
|
||||||
const initPassword = ref('Hzdyjs123456!@#');
|
const initPassword = ref('Hzdyjs123456!@#');
|
||||||
@@ -1704,6 +1784,21 @@ const dialog = reactive({
|
|||||||
title: ''
|
title: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 学籍异动弹窗
|
||||||
|
const statusChangeDialog = reactive({
|
||||||
|
visible: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// 学籍异动表单
|
||||||
|
const statusChangeForm = reactive({
|
||||||
|
changeType: '',
|
||||||
|
effectiveDate: '',
|
||||||
|
reason: '',
|
||||||
|
operatorId: '',
|
||||||
|
operatorName: '',
|
||||||
|
selectedStudents: [] as StudentVO[]
|
||||||
|
});
|
||||||
|
|
||||||
const detailDialog = reactive({
|
const detailDialog = reactive({
|
||||||
visible: false,
|
visible: false,
|
||||||
title: '学生详情'
|
title: '学生详情'
|
||||||
@@ -1854,6 +1949,15 @@ const rules = reactive({
|
|||||||
gender: [{ required: true, message: '性别不能为空', trigger: 'blur' }]
|
gender: [{ required: true, message: '性别不能为空', trigger: 'blur' }]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 学籍异动表单验证规则
|
||||||
|
const statusChangeRules = reactive({
|
||||||
|
changeType: [{ required: true, message: '异动类型不能为空', trigger: 'change' }],
|
||||||
|
effectiveDate: [{ required: true, message: '生效日期不能为空', trigger: 'blur' }],
|
||||||
|
reason: [{ required: true, message: '异动原因不能为空', trigger: 'blur' }]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 异动类型选项通过字典表获取:xg_stu_status
|
||||||
|
|
||||||
const queryParams = reactive<StudentQuery>({
|
const queryParams = reactive<StudentQuery>({
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -2811,6 +2915,81 @@ const handleSelectionChange = (selection: StudentVO[]) => {
|
|||||||
multiple.value = !selection.length;
|
multiple.value = !selection.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 打开学籍异动弹窗 */
|
||||||
|
const openStatusChangeModal = (changeType?: string) => {
|
||||||
|
if (ids.value.length === 0) {
|
||||||
|
ElMessage.warning('请先选择要进行学籍异动的学生');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取选中的学生信息
|
||||||
|
const selectedStudents = studentList.value.filter((student) => ids.value.includes(student.id));
|
||||||
|
|
||||||
|
// 设置表单数据
|
||||||
|
statusChangeForm.changeType = changeType || '';
|
||||||
|
statusChangeForm.effectiveDate = proxy?.parseTime(new Date(), '{y}-{m}-{d}');
|
||||||
|
statusChangeForm.reason = '';
|
||||||
|
statusChangeForm.operatorId = userStore.userId || '';
|
||||||
|
statusChangeForm.operatorName = userStore.nickname || '';
|
||||||
|
statusChangeForm.selectedStudents = selectedStudents;
|
||||||
|
|
||||||
|
statusChangeDialog.visible = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取学籍异动弹窗标题 */
|
||||||
|
const getStatusChangeDialogTitle = () => {
|
||||||
|
const typeMap = {
|
||||||
|
'TUI_XUE': '退学',
|
||||||
|
'XIU_XUE': '休学',
|
||||||
|
'FU_XUE': '复学',
|
||||||
|
'BI_YE': '毕业'
|
||||||
|
};
|
||||||
|
const typeLabel = typeMap[statusChangeForm.changeType as keyof typeof typeMap] || '学籍异动';
|
||||||
|
return `${typeLabel}申请`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 限制日期选择(不能选择过去的日期) */
|
||||||
|
const disabledDate = (time: Date) => {
|
||||||
|
return time.getTime() < Date.now() - 24 * 60 * 60 * 1000; // 不能选择昨天及以前的日期
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交学籍异动 */
|
||||||
|
const submitStatusChange = async () => {
|
||||||
|
const formRef = statusChangeFormRef.value;
|
||||||
|
if (!formRef) return;
|
||||||
|
|
||||||
|
await formRef.validate(async (valid: boolean) => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
const submitData = statusChangeForm.selectedStudents.map((student) => ({
|
||||||
|
studentId: student.id,
|
||||||
|
studentNo: student.studentNo,
|
||||||
|
changeType: statusChangeForm.changeType,
|
||||||
|
applyDate: proxy?.parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}'),
|
||||||
|
effectiveDate: statusChangeForm.effectiveDate,
|
||||||
|
reason: statusChangeForm.reason,
|
||||||
|
operatorId: statusChangeForm.operatorId,
|
||||||
|
operatorName: statusChangeForm.operatorName,
|
||||||
|
source: 'manual',
|
||||||
|
processStatus: 0
|
||||||
|
}));
|
||||||
|
|
||||||
|
const res = await service.post('/studentMsg/studentStatusChange/batch', submitData);
|
||||||
|
if (res && res.code === 200) {
|
||||||
|
ElMessage.success('学籍异动申请提交成功');
|
||||||
|
statusChangeDialog.visible = false;
|
||||||
|
await getList(); // 刷新列表
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res?.msg || '提交失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交学籍异动失败:', error);
|
||||||
|
ElMessage.error('提交失败,请重试');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/** 导入按钮操作 */
|
/** 导入按钮操作 */
|
||||||
const handleImport = () => {
|
const handleImport = () => {
|
||||||
if (!showAddButton.value) {
|
if (!showAddButton.value) {
|
||||||
@@ -3580,4 +3759,25 @@ onMounted(() => {
|
|||||||
:deep(.batch-cancel-bed-dialog .el-message-box__message strong) {
|
:deep(.batch-cancel-bed-dialog .el-message-box__message strong) {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 选中学生列表样式 */
|
||||||
|
.selected-students-container {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-item {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -0,0 +1,359 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-2 page-container">
|
||||||
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
|
<div v-show="showSearch" class="mb-[10px]">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="学号" prop="studentNo">
|
||||||
|
<el-input v-model="queryParams.studentNo" placeholder="请输入学号" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="异动类型" prop="changeType">
|
||||||
|
<el-select v-model="queryParams.changeType" placeholder="请选择异动类型" clearable>
|
||||||
|
<el-option v-for="dict in xg_stu_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="处理状态" prop="processStatus">
|
||||||
|
<el-select v-model="queryParams.processStatus" placeholder="请选择处理状态" clearable>
|
||||||
|
<el-option label="未处理" :value="0" />
|
||||||
|
<el-option label="已处理" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="经办人" prop="operatorName">
|
||||||
|
<el-input v-model="queryParams.operatorName" placeholder="请输入经办人姓名" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="申请日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" class="search-btn-container">
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="Delete"
|
||||||
|
:disabled="multiple || selectedRows.some(row => row.processStatus === 1)"
|
||||||
|
@click="handleDelete()"
|
||||||
|
v-hasPermi="['studentMsg:studentStatusChange:remove']"
|
||||||
|
>删除</el-button
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['studentMsg:studentStatusChange:export']"
|
||||||
|
>导出</el-button
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" border :data="statusChangeList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="主键ID" align="center" prop="id" v-if="false" />
|
||||||
|
<el-table-column label="学号" align="center" prop="studentNo" />
|
||||||
|
<el-table-column label="姓名" align="center" prop="studentName" />
|
||||||
|
<el-table-column label="班级" align="center" prop="className" />
|
||||||
|
<el-table-column label="专业" align="center" prop="majorName" />
|
||||||
|
<el-table-column label="学院" align="center" prop="collegeName" />
|
||||||
|
<el-table-column label="异动类型" align="center" prop="changeType">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :options="xg_stu_status" :value="scope.row.changeType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="申请日期" align="center" prop="applyDate" width="160">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ proxy?.parseTime(scope.row.applyDate, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="生效日期" align="center" prop="effectiveDate" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ proxy?.parseTime(scope.row.effectiveDate, '{y}-{m}-{d}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="异动原因" align="center" prop="reason" width="200" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column label="经办人" align="center" prop="operatorName" />
|
||||||
|
<el-table-column label="来源" align="center" prop="source">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.source === 'manual'" type="primary">手动</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.source === 'import'" type="success">导入</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.source === 'workflow'" type="warning">工作流</el-tag>
|
||||||
|
<el-tag v-else type="info">{{ scope.row.source }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="处理状态" align="center" prop="processStatus">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.processStatus === 0" type="warning">未处理</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.processStatus === 1" type="success">已处理</el-tag>
|
||||||
|
<el-tag v-else type="info">未知</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ proxy?.parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip content="删除" placement="top">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="Delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['studentMsg:studentStatusChange:remove']"
|
||||||
|
:disabled="scope.row.processStatus === 1"
|
||||||
|
></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="StudentStatusChange" lang="ts">
|
||||||
|
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue';
|
||||||
|
import type { FormInstance as ElFormInstance } from 'element-plus';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { to } from 'await-to-js';
|
||||||
|
import service from '@/utils/request';
|
||||||
|
import { XgStudentStatusChangeVo, XgStudentStatusChangeQuery } from '@/api/xg/xsjcxx/studentStatusChange/types';
|
||||||
|
|
||||||
|
interface PageData<T, Q> {
|
||||||
|
form: T;
|
||||||
|
queryParams: Q;
|
||||||
|
rules: Record<string, any[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ComponentInternalInstance {
|
||||||
|
proxy?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
// 字典数据
|
||||||
|
const { xg_stu_status } = toRefs<any>(proxy?.useDict('xg_stu_status'));
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const statusChangeList = ref<XgStudentStatusChangeVo[]>([]);
|
||||||
|
const loading = ref(true);
|
||||||
|
const ids = ref<Array<number | string>>([]);
|
||||||
|
const selectedRows = ref<XgStudentStatusChangeVo[]>([]);
|
||||||
|
const single = ref(true);
|
||||||
|
const multiple = ref(true);
|
||||||
|
const total = ref(0);
|
||||||
|
const dateRange = ref<[string, string]>(['', '']);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
|
||||||
|
// 分页参数
|
||||||
|
const queryParams = reactive<XgStudentStatusChangeQuery>({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
studentNo: '',
|
||||||
|
changeType: '',
|
||||||
|
processStatus: null,
|
||||||
|
operatorName: '',
|
||||||
|
params: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单引用
|
||||||
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构造请求参数
|
||||||
|
const requestBody: any = {
|
||||||
|
studentNo: queryParams.studentNo || '',
|
||||||
|
changeType: queryParams.changeType || '',
|
||||||
|
processStatus: queryParams.processStatus,
|
||||||
|
operatorName: queryParams.operatorName || ''
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理时间范围查询
|
||||||
|
if (dateRange.value && dateRange.value[0] && dateRange.value[1]) {
|
||||||
|
requestBody.beginTime = dateRange.value[0];
|
||||||
|
requestBody.endTime = dateRange.value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造分页参数
|
||||||
|
const pageQuery = {
|
||||||
|
pageNum: queryParams.pageNum,
|
||||||
|
pageSize: queryParams.pageSize
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调用后端接口
|
||||||
|
const res = await service.get('/studentMsg/studentStatusChange/list', {
|
||||||
|
params: { ...requestBody, ...pageQuery }
|
||||||
|
});
|
||||||
|
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (res && res.code === 200) {
|
||||||
|
statusChangeList.value = res.rows || [];
|
||||||
|
total.value = res.total || 0;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res?.msg || '查询失败');
|
||||||
|
statusChangeList.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
loading.value = false;
|
||||||
|
console.error('查询失败:', error);
|
||||||
|
ElMessage.error('查询失败,请重试');
|
||||||
|
statusChangeList.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 选择条数 */
|
||||||
|
const handleSelectionChange = (selection: XgStudentStatusChangeVo[]) => {
|
||||||
|
ids.value = selection.map((item) => item.id);
|
||||||
|
selectedRows.value = selection;
|
||||||
|
single.value = selection.length !== 1;
|
||||||
|
multiple.value = !selection.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
dateRange.value = ['', ''];
|
||||||
|
proxy?.resetForm(queryFormRef.value);
|
||||||
|
queryParams.pageNum = 1;
|
||||||
|
queryParams.studentNo = '';
|
||||||
|
queryParams.changeType = '';
|
||||||
|
queryParams.processStatus = null;
|
||||||
|
queryParams.operatorName = '';
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (row?: XgStudentStatusChangeVo) => {
|
||||||
|
if (row && row.processStatus === 1) {
|
||||||
|
ElMessage.warning('已处理的记录不能删除');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusChangeIds = row?.id || ids.value;
|
||||||
|
const [err] = await to(
|
||||||
|
ElMessageBox.confirm(`是否确认删除选中的${Array.isArray(statusChangeIds) ? statusChangeIds.length : 1}条数据项?`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
try {
|
||||||
|
const res = await service.delete(`/studentMsg/studentStatusChange/${statusChangeIds}`);
|
||||||
|
if (res && res.code === 200) {
|
||||||
|
await getList();
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res?.msg || '删除失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error);
|
||||||
|
ElMessage.error('删除失败,请重试');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = () => {
|
||||||
|
ElMessage({
|
||||||
|
message: '正在导出数据,请耐心等待...',
|
||||||
|
type: 'info',
|
||||||
|
duration: 0,
|
||||||
|
zIndex: 4000
|
||||||
|
});
|
||||||
|
|
||||||
|
proxy
|
||||||
|
?.download(
|
||||||
|
'studentMsg/studentStatusChange/export',
|
||||||
|
{
|
||||||
|
...queryParams,
|
||||||
|
...proxy?.addDateRange(queryParams, dateRange.value)
|
||||||
|
},
|
||||||
|
`student_status_change_${new Date().getTime()}.xlsx`
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.closeAll();
|
||||||
|
ElMessage.success('导出成功');
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
ElMessage.closeAll();
|
||||||
|
if (error.message && error.message.includes('timeout')) {
|
||||||
|
ElMessage.error('导出超时,请尝试减少导出数据量或联系管理员');
|
||||||
|
} else {
|
||||||
|
ElMessage.error('导出失败,请稍后重试');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-container {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-btn-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-btn-container .el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,31 @@
|
|||||||
|
-- xg_student_status_change.sql
|
||||||
|
-- 学生学籍异动表 DDL(退学/休学/复学/毕业)
|
||||||
|
-- 生成说明:根据用户提供的表模型,已修正小幅语法问题(尾逗号)。如需保持原样请告知。
|
||||||
|
|
||||||
|
CREATE TABLE `xg_student_status_change` (
|
||||||
|
`id` bigint(20) NOT NULL COMMENT '主键,雪花ID(建议使用雪花算法生成)',
|
||||||
|
`student_id` bigint(20) NOT NULL COMMENT '学生ID,关联学生主表',
|
||||||
|
`student_no` varchar(100) DEFAULT NULL COMMENT '学号',
|
||||||
|
`change_type` varchar(20) NOT NULL COMMENT '异动类型: TUI_XUE(退学), XIU_XUE(休学), FU_XUE(复学), BI_YE(毕业)',
|
||||||
|
`apply_date` datetime NOT NULL COMMENT '申请/登记日期',
|
||||||
|
`effective_date` datetime DEFAULT NULL COMMENT '生效日期(业务生效时间)',
|
||||||
|
`reason` varchar(1000) DEFAULT NULL COMMENT '异动原因',
|
||||||
|
`operator_id` bigint(20) DEFAULT NULL COMMENT '经办人ID(登记人)',
|
||||||
|
`operator_name` varchar(64) DEFAULT NULL COMMENT '经办人姓名',
|
||||||
|
`source` varchar(50) DEFAULT 'manual' COMMENT '来源: manual/import/workflow',
|
||||||
|
`process_status` tinyint(2) NOT NULL DEFAULT 0 COMMENT '处理状态:0=未处理,1=已处理',
|
||||||
|
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||||
|
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||||
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||||
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户ID(多租户)',
|
||||||
|
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0=正常,1=已删除',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_student_id` (`student_id`),
|
||||||
|
KEY `idx_change_type` (`change_type`),
|
||||||
|
KEY `idx_process_status` (`process_status`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
|
COMMENT='学生学籍异动表';
|
||||||
|
|
||||||
|
|
||||||
Reference in new issue
Block a user