提交代码
This commit is contained in:
1 parent
4e34c7eb36
commit
375a2c8df7
54 files changed
+4631
-4352
No files matched your search
@@ -1,2 +0,0 @@
|
||||
# 人事管理模块 - 控制器层
|
||||
# 此目录用于存放REST API控制器类
|
||||
+41
-27
@@ -24,6 +24,7 @@ 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.core.utils.StringUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
@@ -97,6 +98,8 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
|
||||
/**
|
||||
* 查询当前用户的待审批申请列表(五级审批模式)
|
||||
*
|
||||
* @deprecated 已废弃,请使用 pendingPageList 方法(支持分页和搜索)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseasapproval:list")
|
||||
@GetMapping("/pending/list")
|
||||
@@ -105,6 +108,30 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户的待审批申请分页列表(根据角色过滤,支持分页和搜索)
|
||||
*
|
||||
* 🔴 核心逻辑:
|
||||
* 1. 根据用户角色确定审批级别列表
|
||||
* 2. 部门负责人(rs_bmfzr)只能看到本部门的申请
|
||||
* 3. 其他角色可以看到全校的申请
|
||||
* 4. 支持分页和搜索(前往国家、出境事由)
|
||||
* 5. 只返回status='0'(待审核)的申请
|
||||
* 6. 按创建时间倒序排列
|
||||
*
|
||||
* 角色映射:
|
||||
* - rs_bmfzr → approval_level='1' + 部门过滤
|
||||
* - hr_dept_role → approval_level='2'
|
||||
* - discipline_committee_role → approval_level='3'
|
||||
* - college_leader_role → approval_level='4'
|
||||
* - party_secretary_role → approval_level='5'
|
||||
*/
|
||||
@SaCheckPermission("rs:overseasapproval:list")
|
||||
@GetMapping("/pending/page")
|
||||
public TableDataInfo<RsOverseasApplicationVo> pendingPageList(RsOverseasApplicationQuery query) {
|
||||
return applicationService.queryPendingPageListByRole(query);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// 五级审批模式说明
|
||||
//
|
||||
@@ -321,7 +348,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
@PostMapping("/approve")
|
||||
public R<Void> approve(@RequestBody ApprovalRequest request) {
|
||||
Long approverId = LoginHelper.getUserId();
|
||||
String approverName = LoginHelper.getUsername();
|
||||
String approverName = StringUtils.defaultIfBlank(LoginHelper.getNickname(), LoginHelper.getUsername());
|
||||
|
||||
// 🔴 标准工作流模式:支持任务ID参数
|
||||
// 如果传入了taskId,将通过工作流引擎进行审批
|
||||
@@ -488,12 +515,6 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
public R<Map<String, Object>> uploadStampedFile(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam("applicationId") Long applicationId) {
|
||||
try {
|
||||
// 验证文件格式
|
||||
String contentType = file.getContentType();
|
||||
if (!isValidFileType(contentType)) {
|
||||
return R.fail("不支持的文件格式,请上传PDF、JPG或PNG文件");
|
||||
}
|
||||
|
||||
// 验证文件大小(10MB)
|
||||
long maxSize = 10 * 1024 * 1024; // 10MB
|
||||
if (file.getSize() > maxSize) {
|
||||
@@ -561,12 +582,6 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
public R<Map<String, Object>> uploadPartyRetentionFile(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam("applicationId") Long applicationId) {
|
||||
try {
|
||||
// 验证文件格式
|
||||
String contentType = file.getContentType();
|
||||
if (!isValidFileType(contentType)) {
|
||||
return R.fail("不支持的文件格式,请上传PDF、JPG或PNG文件");
|
||||
}
|
||||
|
||||
// 验证文件大小(10MB)
|
||||
long maxSize = 10 * 1024 * 1024; // 10MB
|
||||
if (file.getSize() > maxSize) {
|
||||
@@ -583,7 +598,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
ossResult.getOriginalName(), // 原始文件名
|
||||
new Date(), // 上传时间
|
||||
"1", // 上传状态:已上传
|
||||
ossResult.getOssId() // OSS文件ID
|
||||
String.valueOf(ossResult.getOssId()) // OSS文件ID - 转换为字符串
|
||||
);
|
||||
|
||||
// 返回结果
|
||||
@@ -616,25 +631,24 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理多个OSS ID的情况(逗号分隔),取第一个ID进行下载
|
||||
String ossIdStr = application.getPartyRetentionFileOssId();
|
||||
Long ossId;
|
||||
if (ossIdStr.contains(",")) {
|
||||
// 如果包含逗号,取第一个ID
|
||||
ossId = Long.parseLong(ossIdStr.split(",")[0].trim());
|
||||
} else {
|
||||
// 单个ID直接解析
|
||||
ossId = Long.parseLong(ossIdStr);
|
||||
}
|
||||
|
||||
// 使用系统OSS服务进行安全下载
|
||||
ossService.secureDownload(application.getPartyRetentionFileOssId(), response);
|
||||
ossService.secureDownload(ossId, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证文件类型
|
||||
*/
|
||||
private boolean isValidFileType(String contentType) {
|
||||
if (contentType == null)
|
||||
return false;
|
||||
return contentType.equals("application/pdf") ||
|
||||
contentType.equals("image/jpeg") ||
|
||||
contentType.equals("image/jpg") ||
|
||||
contentType.equals("image/png");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
*/
|
||||
|
||||
+6
-10
@@ -62,17 +62,13 @@ public class RsOverseasItineraryChangeController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔴 标准化改造:删除自定义待审批查询接口
|
||||
*
|
||||
* 原因:出国行程变更工作流应使用标准工作流模式
|
||||
* 用户应通过工作流API pageByTaskWait() 获取待办任务
|
||||
* 而不是调用自定义的业务API
|
||||
* 查询待审批的行程变更申请列表(status=0)
|
||||
*/
|
||||
@SaCheckPermission("rs:itineraryChange:approve")
|
||||
@GetMapping("/pending/list")
|
||||
public R<String> pendingList(RsOverseasItineraryChangeQuery query) {
|
||||
// 提示用户使用标准工作流API
|
||||
return R.fail("请使用标准工作流待办页面查看审批任务。访问:工作流 > 我的任务 > 待办任务");
|
||||
public TableDataInfo<RsOverseasItineraryChangeVo> pendingList(RsOverseasItineraryChangeQuery query) {
|
||||
query.setTenantId(LoginHelper.getTenantId());
|
||||
return changeService.queryPendingList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +163,7 @@ public class RsOverseasItineraryChangeController extends BaseController {
|
||||
/**
|
||||
* 导出行程变更申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:itineraryChange:export")
|
||||
// @SaCheckPermission("rs:itineraryChange:export")
|
||||
@Log(title = "行程变更申请", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(RsOverseasItineraryChangeQuery query, HttpServletResponse response) {
|
||||
@@ -179,7 +175,7 @@ public class RsOverseasItineraryChangeController extends BaseController {
|
||||
/**
|
||||
* 查询某个出国记录的所有变更历史
|
||||
*/
|
||||
@SaCheckPermission("rs:itineraryChange:query")
|
||||
// @SaCheckPermission("rs:itineraryChange:query")
|
||||
@GetMapping("/record/{recordId}/history")
|
||||
public R<List<RsOverseasItineraryChangeVo>> getChangeHistory(@PathVariable Long recordId) {
|
||||
return R.ok(changeService.queryByRecordId(recordId));
|
||||
|
||||
+29
-37
@@ -32,7 +32,7 @@ import org.dromara.rs.service.IRsOverseasRegistrationService;
|
||||
|
||||
/**
|
||||
* 出国登记Controller
|
||||
*
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@@ -47,7 +47,7 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 查询出国登记列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:list")
|
||||
// @SaCheckPermission("rs:overseasregistration:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsOverseasRegistrationVo> list(RsOverseasRegistrationQuery query) {
|
||||
return registrationService.queryPageList(query);
|
||||
@@ -56,7 +56,7 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 查询我的出国登记列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:list")
|
||||
// @SaCheckPermission("rs:overseasregistration:list")
|
||||
@GetMapping("/my/list")
|
||||
public TableDataInfo<RsOverseasRegistrationVo> myList(RsOverseasRegistrationQuery query) {
|
||||
return registrationService.queryMyRegistrationList(query);
|
||||
@@ -65,7 +65,7 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 导出出国登记列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:export")
|
||||
// @SaCheckPermission("rs:overseasregistration:export")
|
||||
@Log(title = "出国登记", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(RsOverseasRegistrationQuery query, HttpServletResponse response) {
|
||||
@@ -76,27 +76,26 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 获取出国登记详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:query")
|
||||
// @SaCheckPermission("rs:overseasregistration:query")
|
||||
@GetMapping("/{registrationId}")
|
||||
public R<RsOverseasRegistrationVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long registrationId) {
|
||||
public R<RsOverseasRegistrationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long registrationId) {
|
||||
return R.ok(registrationService.queryById(registrationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据申请ID获取出国登记信息
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:query")
|
||||
// @SaCheckPermission("rs:overseasregistration:query")
|
||||
@GetMapping("/application/{applicationId}")
|
||||
public R<RsOverseasRegistrationVo> getByApplicationId(@NotNull(message = "申请ID不能为空")
|
||||
@PathVariable Long applicationId) {
|
||||
public R<RsOverseasRegistrationVo> getByApplicationId(
|
||||
@NotNull(message = "申请ID不能为空") @PathVariable Long applicationId) {
|
||||
return R.ok(registrationService.queryByApplicationId(applicationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:add")
|
||||
// @SaCheckPermission("rs:overseasregistration:add")
|
||||
@Log(title = "出国登记", businessType = BusinessType.INSERT)
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody RsOverseasRegistrationBo bo) {
|
||||
@@ -106,7 +105,7 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 新增并提交出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:add")
|
||||
// @SaCheckPermission("rs:overseasregistration:add")
|
||||
@Log(title = "出国登记", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/addAndSubmit")
|
||||
public R<Void> addAndSubmit(@Validated(AddGroup.class) @RequestBody RsOverseasRegistrationBo bo) {
|
||||
@@ -116,7 +115,7 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 修改出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:edit")
|
||||
// @SaCheckPermission("rs:overseasregistration:edit")
|
||||
@Log(title = "出国登记", businessType = BusinessType.UPDATE)
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody RsOverseasRegistrationBo bo) {
|
||||
@@ -126,67 +125,61 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 删除出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:remove")
|
||||
// @SaCheckPermission("rs:overseasregistration:remove")
|
||||
@Log(title = "出国登记", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{registrationIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] registrationIds) {
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] registrationIds) {
|
||||
return toAjax(registrationService.deleteWithValidByIds(List.of(registrationIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:submit")
|
||||
// @SaCheckPermission("rs:overseasregistration:submit")
|
||||
@Log(title = "出国登记", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/submit/{registrationId}")
|
||||
public R<Void> submit(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long registrationId) {
|
||||
public R<Void> submit(@NotNull(message = "主键不能为空") @PathVariable Long registrationId) {
|
||||
return toAjax(registrationService.submitRegistration(registrationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:confirm")
|
||||
// @SaCheckPermission("rs:overseasregistration:confirm")
|
||||
@Log(title = "出国登记", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/confirm/{registrationId}")
|
||||
public R<Void> confirm(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long registrationId) {
|
||||
public R<Void> confirm(@NotNull(message = "主键不能为空") @PathVariable Long registrationId) {
|
||||
return toAjax(registrationService.confirmRegistration(registrationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:withdraw")
|
||||
// @SaCheckPermission("rs:overseasregistration:withdraw")
|
||||
@Log(title = "出国登记", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/withdraw/{registrationId}")
|
||||
public R<Void> withdraw(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long registrationId) {
|
||||
public R<Void> withdraw(@NotNull(message = "主键不能为空") @PathVariable Long registrationId) {
|
||||
return toAjax(registrationService.withdrawRegistration(registrationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于出国申请创建登记记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:registration:create")
|
||||
// @SaCheckPermission("rs:overseasregistration:create")
|
||||
@Log(title = "出国登记", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/create/{applicationId}")
|
||||
public R<Void> createFromApplication(@NotNull(message = "申请ID不能为空")
|
||||
@PathVariable Long applicationId) {
|
||||
public R<Void> createFromApplication(@NotNull(message = "申请ID不能为空") @PathVariable Long applicationId) {
|
||||
return toAjax(registrationService.createFromApplication(applicationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批准出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:registration:approve")
|
||||
// @SaCheckPermission("rs:registration:approve")
|
||||
@Log(title = "出国登记", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/approve/{registrationId}")
|
||||
public R<Void> approve(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long registrationId,
|
||||
@RequestBody(required = false) RsOverseasRegistrationBo bo) {
|
||||
public R<Void> approve(@NotNull(message = "主键不能为空") @PathVariable Long registrationId,
|
||||
@RequestBody(required = false) RsOverseasRegistrationBo bo) {
|
||||
String approveNotes = (bo != null && bo.getRemarks() != null) ? bo.getRemarks() : "同意";
|
||||
return toAjax(registrationService.approveRegistration(registrationId, approveNotes));
|
||||
}
|
||||
@@ -194,13 +187,12 @@ public class RsOverseasRegistrationController extends BaseController {
|
||||
/**
|
||||
* 拒绝出国登记
|
||||
*/
|
||||
@SaCheckPermission("rs:registration:reject")
|
||||
// @SaCheckPermission("rs:registration:reject")
|
||||
@Log(title = "出国登记", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/reject/{registrationId}")
|
||||
public R<Void> reject(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long registrationId,
|
||||
@RequestBody(required = false) RsOverseasRegistrationBo bo) {
|
||||
public R<Void> reject(@NotNull(message = "主键不能为空") @PathVariable Long registrationId,
|
||||
@RequestBody(required = false) RsOverseasRegistrationBo bo) {
|
||||
String rejectReason = (bo != null && bo.getRemarks() != null) ? bo.getRemarks() : "不同意";
|
||||
return toAjax(registrationService.rejectRegistration(registrationId, rejectReason));
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -384,10 +384,10 @@ public class RsOverseasApplication extends BaseEntity {
|
||||
private String partyRetentionUploadStatus;
|
||||
|
||||
/**
|
||||
* 党籍保留附件OSS ID(用于安全下载)
|
||||
* 党籍保留附件OSS ID(用于安全下载,支持多个ID用逗号分隔)
|
||||
*/
|
||||
@ExcelIgnore
|
||||
private Long partyRetentionFileOssId;
|
||||
private String partyRetentionFileOssId;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class RsOverseasRegistration extends BaseEntity {
|
||||
/**
|
||||
* 登记ID
|
||||
*/
|
||||
@TableId(value = "registration_id", type = IdType.AUTO)
|
||||
@TableId(value = "registration_id", type = IdType.ASSIGN_ID)
|
||||
@ExcelProperty(value = "登记ID")
|
||||
private Long registrationId;
|
||||
|
||||
|
||||
+26
@@ -317,6 +317,32 @@ public class RsOverseasApplicationBo extends BaseEntity {
|
||||
*/
|
||||
private String stampedFileUploadStatus;
|
||||
|
||||
/**
|
||||
* 党籍保留附件文件路径
|
||||
*/
|
||||
private String partyRetentionFilePath;
|
||||
|
||||
/**
|
||||
* 党籍保留附件文件名
|
||||
*/
|
||||
private String partyRetentionFileName;
|
||||
|
||||
/**
|
||||
* 党籍保留附件上传时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date partyRetentionUploadTime;
|
||||
|
||||
/**
|
||||
* 党籍保留附件上传状态:0-未上传,1-已上传
|
||||
*/
|
||||
private String partyRetentionUploadStatus;
|
||||
|
||||
/**
|
||||
* 党籍保留附件OSS ID(支持多个ID用逗号分隔)
|
||||
*/
|
||||
private String partyRetentionFileOssId;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
|
||||
+2
-2
@@ -365,9 +365,9 @@ public class RsOverseasApplicationVo implements Serializable {
|
||||
private String partyRetentionUploadStatus;
|
||||
|
||||
/**
|
||||
* 党籍保留附件OSS ID(用于安全下载)
|
||||
* 党籍保留附件OSS ID(用于安全下载,支持多个ID用逗号分隔)
|
||||
*/
|
||||
private Long partyRetentionFileOssId;
|
||||
private String partyRetentionFileOssId;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
|
||||
+5
@@ -196,6 +196,11 @@ public class RsOverseasApprovalMonitorVo implements Serializable {
|
||||
@ExcelProperty(value = "应急联系人及电话")
|
||||
private String emergencyContact;
|
||||
|
||||
/**
|
||||
* 申请人手写签名(base64)
|
||||
*/
|
||||
private String signature;
|
||||
|
||||
// ==================== 审批状态信息 ====================
|
||||
|
||||
/**
|
||||
|
||||
+19
@@ -144,4 +144,23 @@ public interface RsOverseasApplicationMapper extends BaseMapperPlus<RsOverseasAp
|
||||
* @return 待审批申请列表
|
||||
*/
|
||||
List<RsOverseasApplication> selectPendingApplications(List<String> approvalLevels, Long deptId);
|
||||
|
||||
/**
|
||||
* 🔴 新增:根据角色查询待审批申请列表(支持分页和搜索)
|
||||
*
|
||||
* 查询逻辑:
|
||||
* 1. 根据用户角色确定审批级别列表
|
||||
* 2. 关联 sys_user 表获取申请人的部门信息
|
||||
* 3. 按审批级别过滤(approvalLevel IN (...))
|
||||
* 4. 按状态过滤(status = '0' 待审核)
|
||||
* 5. 按部门过滤(部门负责人:u.dept_id = 当前用户部门ID)
|
||||
* 6. 按搜索条件过滤(前往国家、出境事由)
|
||||
* 7. 按创建时间倒序排列
|
||||
*
|
||||
* @param query 查询条件(包含分页、搜索条件)
|
||||
* @param approvalLevels 审批级别列表,例如:["1", "2"]
|
||||
* @param deptId 部门ID(部门负责人需要),为null则不过滤部门
|
||||
* @return 待审批申请分页列表
|
||||
*/
|
||||
List<RsOverseasApplicationVo> selectPendingApplicationsByRole(RsOverseasApplicationQuery query, List<String> approvalLevels, Long deptId);
|
||||
}
|
||||
+9
-1
@@ -48,6 +48,14 @@ public interface IRsOverseasApplicationService {
|
||||
*/
|
||||
List<RsOverseasApplicationVo> queryPendingByCurrentUser();
|
||||
|
||||
/**
|
||||
* 查询当前用户的待审批申请分页列表(根据角色过滤)
|
||||
*
|
||||
* @param query 查询条件(包含分页、搜索条件)
|
||||
* @return 待审批申请分页集合
|
||||
*/
|
||||
TableDataInfo<RsOverseasApplicationVo> queryPendingPageListByRole(RsOverseasApplicationQuery query);
|
||||
|
||||
/**
|
||||
* 查询出国申请详细信息
|
||||
*
|
||||
@@ -207,7 +215,7 @@ public interface IRsOverseasApplicationService {
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean updatePartyRetentionFileInfo(Long applicationId, String filePath, String fileName,
|
||||
java.util.Date uploadTime, String uploadStatus, Long ossId);
|
||||
java.util.Date uploadTime, String uploadStatus, String ossId);
|
||||
|
||||
/**
|
||||
* 校验出国登记前置条件
|
||||
|
||||
+195
-19
@@ -51,7 +51,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
/**
|
||||
* 出国申请Service业务层处理
|
||||
*
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-07-28
|
||||
*/
|
||||
@@ -232,14 +232,14 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 查询当前用户的待审批申请列表(动态权限方案 + 部门过滤)
|
||||
*
|
||||
*
|
||||
* 🆕 核心改进:
|
||||
* 1. 不再依赖 current_approver_id 字段(该字段仅作为冗余展示用)
|
||||
* 2. 动态查询用户的审批权限,转换为审批级别
|
||||
* 3. 根据审批级别和状态查询待审批申请
|
||||
* 4. 🔴 部门负责人只能看到本部门的申请
|
||||
* 5. 支持人员岗位变动:权限调整后立即生效
|
||||
*
|
||||
*
|
||||
* 查询逻辑:
|
||||
* - 用户有 rs:overseas:approve1 权限(部门负责人)→ 查询本部门员工的、approval_level='1' 且
|
||||
* status='0' 的申请
|
||||
@@ -307,6 +307,156 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户的待审批申请分页列表(根据角色过滤)
|
||||
*
|
||||
* 🔴 核心逻辑:
|
||||
* 1. 根据用户角色确定审批级别列表
|
||||
* 2. 部门负责人(rs_bmfzr)只能看到本部门的申请
|
||||
* 3. 其他角色可以看到全校的申请
|
||||
* 4. 支持分页和搜索(前往国家、出境事由)
|
||||
* 5. 按创建时间倒序排列
|
||||
* 6. 🔴 修复:当用户同时拥有多个角色时,分别查询后合并去重
|
||||
*
|
||||
* 角色映射:
|
||||
* - rs_bmfzr → approval_level='1' + 部门过滤
|
||||
* - hr_dept_role → approval_level='2'
|
||||
* - discipline_committee_role → approval_level='3'
|
||||
* - college_leader_role → approval_level='4'
|
||||
* - party_secretary_role → approval_level='5'
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<RsOverseasApplicationVo> queryPendingPageListByRole(RsOverseasApplicationQuery query) {
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
String currentUserName = LoginHelper.getUsername();
|
||||
String tenantId = LoginHelper.getTenantId();
|
||||
|
||||
log.info("🔍 查询用户待审批申请分页列表 - 用户ID: {}, 用户名: {}", currentUserId, currentUserName);
|
||||
|
||||
// 1. 获取当前用户的角色列表
|
||||
List<SysRoleVo> userRoles = roleService.selectRolesByUserId(currentUserId);
|
||||
if (userRoles == null || userRoles.isEmpty()) {
|
||||
log.warn("❌ 用户 {} 没有任何角色,返回空列表", currentUserName);
|
||||
return TableDataInfo.build();
|
||||
}
|
||||
|
||||
// 2. 根据角色编码确定审批级别列表
|
||||
List<String> deptHeadLevels = new ArrayList<>(); // 部门负责人审批级别
|
||||
List<String> otherLevels = new ArrayList<>(); // 其他审批级别
|
||||
Long deptIdForFilter = null;
|
||||
boolean hasDeptHeadRole = false;
|
||||
boolean hasOtherRole = false;
|
||||
|
||||
for (SysRoleVo role : userRoles) {
|
||||
String roleKey = role.getRoleKey();
|
||||
if (roleKey == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 角色编码映射到审批级别
|
||||
if ("rs_bmfzr".equals(roleKey)) {
|
||||
deptHeadLevels.add("1");
|
||||
hasDeptHeadRole = true;
|
||||
} else if ("hr_dept_role".equals(roleKey)) {
|
||||
otherLevels.add("2");
|
||||
hasOtherRole = true;
|
||||
} else if ("discipline_committee_role".equals(roleKey)) {
|
||||
otherLevels.add("3");
|
||||
hasOtherRole = true;
|
||||
} else if ("college_leader_role".equals(roleKey)) {
|
||||
otherLevels.add("4");
|
||||
hasOtherRole = true;
|
||||
} else if ("party_secretary_role".equals(roleKey)) {
|
||||
otherLevels.add("5");
|
||||
hasOtherRole = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDeptHeadRole && !hasOtherRole) {
|
||||
log.warn("❌ 用户 {} 没有任何出国审批角色,返回空列表", currentUserName);
|
||||
return TableDataInfo.build();
|
||||
}
|
||||
|
||||
log.info("✅ 用户 {} 拥有审批级别 - 部门负责人: {}, 其他角色: {}",
|
||||
currentUserName, deptHeadLevels, otherLevels);
|
||||
|
||||
// 3. 如果是部门负责人,获取部门ID进行过滤
|
||||
if (hasDeptHeadRole) {
|
||||
SysUserVo currentUser = userService.selectUserById(currentUserId);
|
||||
if (currentUser != null && currentUser.getDeptId() != null) {
|
||||
deptIdForFilter = currentUser.getDeptId();
|
||||
log.info("🔒 [部门权限过滤] 部门负责人,用户: {}, 部门ID: {}, 只查看本部门待审批",
|
||||
currentUserName, deptIdForFilter);
|
||||
} else {
|
||||
log.warn("⚠️ 用户 {} 是部门负责人但没有部门信息,无法过滤", currentUserName);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 设置租户ID
|
||||
if (StringUtils.isNotBlank(tenantId)) {
|
||||
query.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
// 5. 🔴 修复:分别查询不同角色的数据,然后合并去重
|
||||
List<RsOverseasApplicationVo> allList = new ArrayList<>();
|
||||
Map<Long, RsOverseasApplicationVo> applicationMap = new HashMap<>(); // 用于去重,key=applicationId
|
||||
|
||||
// 5.1 查询部门负责人的数据(本部门,审批级别='1')
|
||||
if (hasDeptHeadRole && !deptHeadLevels.isEmpty() && deptIdForFilter != null) {
|
||||
List<RsOverseasApplicationVo> deptList = baseMapper.selectPendingApplicationsByRole(
|
||||
query, deptHeadLevels, deptIdForFilter);
|
||||
log.info("📋 [部门负责人] 查询到 {} 条本部门待审批申请", deptList.size());
|
||||
for (RsOverseasApplicationVo vo : deptList) {
|
||||
applicationMap.put(vo.getApplicationId(), vo);
|
||||
}
|
||||
}
|
||||
|
||||
// 5.2 查询其他角色的数据(全校,审批级别为其他级别)
|
||||
if (hasOtherRole && !otherLevels.isEmpty()) {
|
||||
List<RsOverseasApplicationVo> otherList = baseMapper.selectPendingApplicationsByRole(
|
||||
query, otherLevels, null); // deptIdForFilter=null,不限制部门
|
||||
log.info("📋 [其他角色] 查询到 {} 条全校待审批申请", otherList.size());
|
||||
for (RsOverseasApplicationVo vo : otherList) {
|
||||
applicationMap.put(vo.getApplicationId(), vo);
|
||||
}
|
||||
}
|
||||
|
||||
// 5.3 合并去重后的结果,按创建时间倒序排列
|
||||
allList = new ArrayList<>(applicationMap.values());
|
||||
allList.sort((a, b) -> {
|
||||
if (a.getCreateTime() != null && b.getCreateTime() != null) {
|
||||
return b.getCreateTime().compareTo(a.getCreateTime());
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
log.info("✅ [合并结果] 去重后共 {} 条待审批申请", allList.size());
|
||||
|
||||
// 6. 手动分页处理
|
||||
int pageNum = query.getPageNum();
|
||||
int pageSize = query.getPageSize();
|
||||
int total = allList.size();
|
||||
int start = (pageNum - 1) * pageSize;
|
||||
int end = Math.min(start + pageSize, total);
|
||||
|
||||
List<RsOverseasApplicationVo> pageList;
|
||||
if (start >= total) {
|
||||
pageList = new ArrayList<>();
|
||||
} else {
|
||||
pageList = allList.subList(start, end);
|
||||
}
|
||||
|
||||
// 7. 构建分页对象
|
||||
Page<RsOverseasApplicationVo> page = new Page<>(pageNum, pageSize);
|
||||
page.setRecords(pageList);
|
||||
page.setTotal(total);
|
||||
|
||||
log.info("📋 用户 {} 查询到 {} 条待审批申请,分页显示第 {} 页,共 {} 条",
|
||||
currentUserName, total, pageNum, pageList.size());
|
||||
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换实体为VO对象
|
||||
* 🔴 修复:使用Mapper查询完整的VO对象,包含字典翻译等扩展信息
|
||||
@@ -514,7 +664,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 提交出国申请(动态审批人方案)
|
||||
*
|
||||
*
|
||||
* 🆕 核心改进:
|
||||
* 1. 不再设置固定的 current_approver_id(该字段改为冗余展示字段)
|
||||
* 2. 仅设置 approval_level='1',审批人根据权限动态查询
|
||||
@@ -599,7 +749,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
RsOverseasApproval approval = new RsOverseasApproval();
|
||||
approval.setApplicationId(applicationId);
|
||||
approval.setApproverId(approverId);
|
||||
approval.setApproverName(approverName);
|
||||
approval.setApproverName(resolveApproverDisplayName(approverId, approverName));
|
||||
approval.setApprovalLevel(application.getApprovalLevel());
|
||||
approval.setApprovalStatus(approvalStatus);
|
||||
approval.setApprovalOpinion(approvalOpinion);
|
||||
@@ -721,7 +871,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 修复已审批通过但未创建记录的申请
|
||||
*
|
||||
*
|
||||
* @return 修复的记录数量
|
||||
*/
|
||||
@Override
|
||||
@@ -950,6 +1100,16 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
entity.setStampedFileUploadTime(bo.getStampedFileUploadTime());
|
||||
entity.setStampedFileUploadStatus(bo.getStampedFileUploadStatus());
|
||||
|
||||
// ==================== 党籍保留附件相关字段 ====================
|
||||
entity.setPartyRetentionFilePath(bo.getPartyRetentionFilePath());
|
||||
entity.setPartyRetentionFileName(bo.getPartyRetentionFileName());
|
||||
entity.setPartyRetentionUploadTime(bo.getPartyRetentionUploadTime());
|
||||
entity.setPartyRetentionUploadStatus(bo.getPartyRetentionUploadStatus());
|
||||
entity.setPartyRetentionFileOssId(bo.getPartyRetentionFileOssId());
|
||||
|
||||
// ==================== 附件ID列表 ====================
|
||||
entity.setAttachmentIds(bo.getAttachmentIds());
|
||||
|
||||
// ==================== 租户信息 ====================
|
||||
// 🔴 关键修复:设置租户ID(如果Bo中有值则使用Bo的值,否则依赖MyBatis-Plus自动填充)
|
||||
if (bo.getTenantId() != null) {
|
||||
@@ -975,6 +1135,22 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析审批人的展示名称:优先使用用户昵称,缺省时回退账号
|
||||
*/
|
||||
private String resolveApproverDisplayName(Long approverId, String fallbackName) {
|
||||
String displayName = fallbackName;
|
||||
try {
|
||||
SysUserVo approver = userService.selectUserById(approverId);
|
||||
if (approver != null && StringUtils.isNotBlank(approver.getNickName())) {
|
||||
displayName = approver.getNickName();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("⚠️ 获取审批人昵称失败, 使用账号作为展示名称. approverId={}, error={}", approverId, e.getMessage());
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除出国申请
|
||||
*/
|
||||
@@ -1008,7 +1184,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
@Override
|
||||
@Transactional
|
||||
public Boolean updatePartyRetentionFileInfo(Long applicationId, String filePath, String fileName,
|
||||
java.util.Date uploadTime, String uploadStatus, Long ossId) {
|
||||
java.util.Date uploadTime, String uploadStatus, String ossId) {
|
||||
return baseMapper.update(null,
|
||||
new LambdaUpdateWrapper<RsOverseasApplication>()
|
||||
.eq(RsOverseasApplication::getApplicationId, applicationId)
|
||||
@@ -1087,7 +1263,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 根据申请人ID获取部门审批人ID
|
||||
*
|
||||
*
|
||||
* @param applicantId 申请人ID
|
||||
* @return 部门审批人ID
|
||||
*/
|
||||
@@ -1134,7 +1310,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 根据申请人ID获取人事处审批人列表
|
||||
*
|
||||
*
|
||||
* @param applicantId 申请人ID
|
||||
* @return 人事处审批人ID列表
|
||||
*/
|
||||
@@ -1176,7 +1352,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 根据申请人查找对应的部门负责人审批人ID
|
||||
*
|
||||
*
|
||||
* @param applicantId 申请人ID
|
||||
* @return 部门负责人审批人ID
|
||||
*/
|
||||
@@ -1203,7 +1379,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 根据部门ID查找对应的部门负责人审批人
|
||||
*
|
||||
*
|
||||
* @param deptId 部门ID
|
||||
* @return 部门负责人审批人ID
|
||||
*/
|
||||
@@ -1251,7 +1427,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 查找父部门的负责人审批人
|
||||
*
|
||||
*
|
||||
* @param deptId 当前部门ID
|
||||
* @param approvers 所有部门负责人审批人列表
|
||||
* @return 父部门负责人审批人ID
|
||||
@@ -1288,7 +1464,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 根据审批级别获取下一级审批人ID
|
||||
*
|
||||
*
|
||||
* @param approvalLevel 审批级别
|
||||
* @return 下一级审批人ID
|
||||
*/
|
||||
@@ -1298,7 +1474,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 根据审批级别获取审批环节描述
|
||||
*
|
||||
*
|
||||
* @param approvalLevel 审批级别
|
||||
* @return 审批环节描述
|
||||
*/
|
||||
@@ -1321,14 +1497,14 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 🆕 根据当前登录用户的审批权限,获取其可审批的级别列表
|
||||
*
|
||||
*
|
||||
* 权限到级别的映射:
|
||||
* - rs:overseas:approve1 → 审批级别 "1" (部门负责人)
|
||||
* - rs:overseas:approve2 → 审批级别 "2" (人事处)
|
||||
* - rs:overseas:approve3 → 审批级别 "3" (纪委)
|
||||
* - rs:overseas:approve4 → 审批级别 "4" (学院分管领导)
|
||||
* - rs:overseas:approve5 → 审批级别 "5" (学院党委书记)
|
||||
*
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 可审批的级别列表,例如:["2", "3"]
|
||||
*/
|
||||
@@ -1371,7 +1547,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 🆕 根据审批级别获取对应的权限标识
|
||||
*
|
||||
*
|
||||
* @param approvalLevel 审批级别(2-5)
|
||||
* @return 权限标识,例如:"rs:overseas:approve2"
|
||||
*/
|
||||
@@ -1396,7 +1572,7 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
|
||||
/**
|
||||
* 🔴 新增方法:验证审批人是否有指定级别的审批权限
|
||||
*
|
||||
*
|
||||
* @param approverId 审批人ID
|
||||
* @param approvalLevel 需要的审批级别(1-5)
|
||||
* @return true-有权限,false-无权限
|
||||
@@ -1423,4 +1599,4 @@ public class RsOverseasApplicationServiceImpl extends ServiceImpl<RsOverseasAppl
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -311,6 +311,7 @@ public class RsOverseasApprovalMonitorServiceImpl implements IRsOverseasApproval
|
||||
vo.setMobilePhone(application.getMobilePhone());
|
||||
vo.setContactPhone(application.getContactPhone());
|
||||
vo.setEmergencyContact(application.getEmergencyContact());
|
||||
vo.setSignature(application.getSignature());
|
||||
|
||||
// 审批状态信息
|
||||
vo.setStatus(application.getStatus());
|
||||
|
||||
+190
-18
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.rs.domain.RsOverseasItineraryChange;
|
||||
@@ -13,14 +14,23 @@ import org.dromara.rs.domain.bo.RsOverseasItineraryChangeBo;
|
||||
import org.dromara.rs.domain.query.RsOverseasItineraryChangeQuery;
|
||||
import org.dromara.rs.domain.vo.RsOverseasItineraryChangeVo;
|
||||
import org.dromara.rs.mapper.RsOverseasItineraryChangeMapper;
|
||||
import org.dromara.rs.mapper.RsOverseasApplicationMapper;
|
||||
import org.dromara.rs.mapper.RsOverseasRecordMapper;
|
||||
import org.dromara.rs.domain.RsOverseasApplication;
|
||||
import org.dromara.rs.domain.RsOverseasRecord;
|
||||
import org.dromara.rs.domain.vo.RsOverseasRecordVo;
|
||||
import org.dromara.rs.service.IRsOverseasItineraryChangeService;
|
||||
import org.dromara.rs.service.IRsOverseasApplicationService;
|
||||
import org.dromara.rs.service.IRsOverseasRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* 出国行程变更申请Service业务层处理
|
||||
@@ -35,14 +45,38 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
|
||||
private final RsOverseasItineraryChangeMapper changeMapper;
|
||||
private final IRsOverseasApplicationService applicationService;
|
||||
private final RsOverseasApplicationMapper applicationMapper;
|
||||
private final IRsOverseasRecordService recordService;
|
||||
private final RsOverseasRecordMapper recordMapper;
|
||||
|
||||
/**
|
||||
* 查询出国行程变更申请分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<RsOverseasItineraryChangeVo> queryPageList(RsOverseasItineraryChangeQuery query) {
|
||||
// 查询所有符合条件的数据(不分页)
|
||||
List<RsOverseasItineraryChangeVo> list = changeMapper.selectChangeList(query);
|
||||
return TableDataInfo.build(list);
|
||||
|
||||
// 手动分页处理
|
||||
int pageNum = query.getPageNum();
|
||||
int pageSize = query.getPageSize();
|
||||
int total = list.size();
|
||||
int start = (pageNum - 1) * pageSize;
|
||||
int end = Math.min(start + pageSize, total);
|
||||
|
||||
List<RsOverseasItineraryChangeVo> pageList;
|
||||
if (start >= total) {
|
||||
pageList = new ArrayList<>();
|
||||
} else {
|
||||
pageList = list.subList(start, end);
|
||||
}
|
||||
|
||||
// 构建分页对象
|
||||
Page<RsOverseasItineraryChangeVo> page = new Page<>(pageNum, pageSize);
|
||||
page.setRecords(pageList);
|
||||
page.setTotal(total);
|
||||
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,11 +123,12 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(RsOverseasItineraryChangeBo bo) {
|
||||
// 查询出国申请信息
|
||||
org.dromara.rs.domain.vo.RsOverseasApplicationVo application = applicationService.queryById(bo.getApplicationId());
|
||||
org.dromara.rs.domain.vo.RsOverseasApplicationVo application = applicationService
|
||||
.queryById(bo.getApplicationId());
|
||||
if (application == null) {
|
||||
throw new ServiceException("出国申请不存在");
|
||||
}
|
||||
|
||||
|
||||
// 检查申请状态是否为已通过
|
||||
if (!"1".equals(application.getStatus())) {
|
||||
throw new ServiceException("只能为已通过审批的出国申请提交变更申请");
|
||||
@@ -102,8 +137,8 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
// 检查是否有未完成的变更申请
|
||||
LambdaQueryWrapper<RsOverseasItineraryChange> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(RsOverseasItineraryChange::getApplicationId, bo.getApplicationId())
|
||||
.in(RsOverseasItineraryChange::getStatus, Arrays.asList("0")) // 待审核
|
||||
.eq(RsOverseasItineraryChange::getDeleted, 0);
|
||||
.in(RsOverseasItineraryChange::getStatus, Arrays.asList("0")) // 待审核
|
||||
.eq(RsOverseasItineraryChange::getDeleted, 0);
|
||||
Long count = changeMapper.selectCount(wrapper);
|
||||
if (count > 0) {
|
||||
throw new ServiceException("该出国申请已有待审核的变更申请,请先处理");
|
||||
@@ -117,11 +152,12 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
entity.setApplicantId(userId);
|
||||
entity.setApplicantName(LoginHelper.getUsername());
|
||||
entity.setApplicationId(bo.getApplicationId());
|
||||
|
||||
|
||||
// 从出国申请中复制原始信息
|
||||
entity.setOriginalDestination(application.getDestination());
|
||||
entity.setOriginalDestinationCity(application.getDestinationCity());
|
||||
entity.setOriginalExitReason(application.getExitReason() != null ? application.getExitReason() : application.getPurposeDetail());
|
||||
entity.setOriginalExitReason(
|
||||
application.getExitReason() != null ? application.getExitReason() : application.getPurposeDetail());
|
||||
entity.setOriginalStartDate(application.getStartDate());
|
||||
entity.setOriginalEndDate(application.getEndDate());
|
||||
entity.setOriginalDuration(application.getDuration());
|
||||
@@ -148,9 +184,10 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
throw new ServiceException("变更申请不存在");
|
||||
}
|
||||
|
||||
// 只有待审核或已拒绝的申请可以修改
|
||||
if (!"0".equals(original.getStatus()) && !"2".equals(original.getStatus())) {
|
||||
throw new ServiceException("只有待审核或已拒绝的变更申请可以修改");
|
||||
// 只有待审核、已拒绝或已撤回的申请可以修改
|
||||
if (!"0".equals(original.getStatus()) && !"2".equals(original.getStatus())
|
||||
&& !"3".equals(original.getStatus())) {
|
||||
throw new ServiceException("只有待审核、已拒绝或已撤回的变更申请可以修改");
|
||||
}
|
||||
|
||||
// 检查权限:只能修改自己的申请
|
||||
@@ -161,7 +198,7 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
|
||||
// 转换BO到Entity
|
||||
RsOverseasItineraryChange entity = BeanUtil.toBean(bo, RsOverseasItineraryChange.class);
|
||||
|
||||
|
||||
// 重新提交时,状态改为待审核
|
||||
entity.setStatus("0");
|
||||
entity.setApprovalOpinion(null);
|
||||
@@ -179,24 +216,24 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteByIds(List<Long> changeIds) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
|
||||
|
||||
for (Long changeId : changeIds) {
|
||||
RsOverseasItineraryChange change = changeMapper.selectById(changeId);
|
||||
if (change == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// 检查权限:只能删除自己的申请
|
||||
if (!userId.equals(change.getApplicantId())) {
|
||||
throw new ServiceException("只能删除自己的变更申请");
|
||||
}
|
||||
|
||||
|
||||
// 只有待审核或已拒绝的申请可以删除
|
||||
if (!"0".equals(change.getStatus()) && !"2".equals(change.getStatus())) {
|
||||
throw new ServiceException("只有待审核或已拒绝的变更申请可以删除");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return changeMapper.deleteBatchIds(changeIds) > 0;
|
||||
}
|
||||
|
||||
@@ -229,6 +266,12 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
|
||||
/**
|
||||
* 审批变更申请
|
||||
*
|
||||
* 🔴 审批通过后,需要更新原申请单和记录的数据:
|
||||
* 1. 前往国家 → 更新到 rs_overseas_application 和 rs_overseas_record
|
||||
* 2. 实际出行开始时间、结束时间 → 更新到 rs_overseas_application 和 rs_overseas_record
|
||||
* 3. 行程安排 → 更新到 rs_overseas_application 和 rs_overseas_record
|
||||
* 4. 出境事由 → 追加到 rs_overseas_application 的备注字段
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -249,9 +292,139 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
change.setApprovalOpinion(opinion);
|
||||
change.setApprovalTime(new Date());
|
||||
change.setApproverId(userId);
|
||||
change.setApproverName(LoginHelper.getUsername());
|
||||
String displayName = StringUtils.defaultIfBlank(LoginHelper.getNickname(), LoginHelper.getUsername());
|
||||
change.setApproverName(displayName);
|
||||
|
||||
return changeMapper.updateById(change) > 0;
|
||||
// 更新变更申请状态
|
||||
boolean updateChangeResult = changeMapper.updateById(change) > 0;
|
||||
if (!updateChangeResult) {
|
||||
throw new ServiceException("更新变更申请状态失败");
|
||||
}
|
||||
|
||||
// 🔴 如果审批通过,需要更新原申请单和记录的数据
|
||||
if (approved && change.getApplicationId() != null) {
|
||||
log.info("🔧 [审批通过] 开始更新原申请单和记录数据,变更ID: {}, 申请ID: {}", changeId, change.getApplicationId());
|
||||
|
||||
try {
|
||||
// 1. 更新 rs_overseas_application 表
|
||||
RsOverseasApplication application = applicationMapper.selectById(change.getApplicationId());
|
||||
if (application != null) {
|
||||
LambdaUpdateWrapper<RsOverseasApplication> appUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||
appUpdateWrapper.eq(RsOverseasApplication::getApplicationId, change.getApplicationId());
|
||||
|
||||
// 更新前往国家(destination 和 destinationCountry 同步更新)
|
||||
if (change.getNewDestination() != null && !change.getNewDestination().trim().isEmpty()) {
|
||||
appUpdateWrapper.set(RsOverseasApplication::getDestination, change.getNewDestination());
|
||||
appUpdateWrapper.set(RsOverseasApplication::getDestinationCountry, change.getNewDestination());
|
||||
log.info("✅ [更新申请单] 前往国家: {} (同步更新 destination 和 destinationCountry)",
|
||||
change.getNewDestination());
|
||||
}
|
||||
|
||||
// 更新出发日期和返回日期
|
||||
if (change.getNewStartDate() != null) {
|
||||
appUpdateWrapper.set(RsOverseasApplication::getStartDate, change.getNewStartDate());
|
||||
log.info("✅ [更新申请单] 出发日期: {}", change.getNewStartDate());
|
||||
}
|
||||
if (change.getNewEndDate() != null) {
|
||||
appUpdateWrapper.set(RsOverseasApplication::getEndDate, change.getNewEndDate());
|
||||
log.info("✅ [更新申请单] 返回日期: {}", change.getNewEndDate());
|
||||
|
||||
// 重新计算出国天数
|
||||
if (change.getNewStartDate() != null && change.getNewEndDate() != null) {
|
||||
long diffInMillies = change.getNewEndDate().getTime() - change.getNewStartDate().getTime();
|
||||
int days = (int) (diffInMillies / (1000 * 60 * 60 * 24)) + 1;
|
||||
appUpdateWrapper.set(RsOverseasApplication::getDuration, days);
|
||||
log.info("✅ [更新申请单] 出国天数: {} 天", days);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新行程安排
|
||||
if (change.getNewItinerary() != null && !change.getNewItinerary().trim().isEmpty()) {
|
||||
appUpdateWrapper.set(RsOverseasApplication::getItinerary, change.getNewItinerary());
|
||||
log.info("✅ [更新申请单] 行程安排已更新");
|
||||
}
|
||||
|
||||
// 追加出境事由到备注字段
|
||||
if (change.getNewExitReason() != null && !change.getNewExitReason().trim().isEmpty()) {
|
||||
String currentRemarks = application.getRemarks() != null ? application.getRemarks() : "";
|
||||
String newRemarks = currentRemarks.isEmpty()
|
||||
? "行程变更-出境事由: " + change.getNewExitReason()
|
||||
: currentRemarks + "\n行程变更-出境事由: " + change.getNewExitReason();
|
||||
appUpdateWrapper.set(RsOverseasApplication::getRemarks, newRemarks);
|
||||
log.info("✅ [更新申请单] 备注已追加出境事由: {}", change.getNewExitReason());
|
||||
}
|
||||
|
||||
boolean appUpdateResult = applicationMapper.update(null, appUpdateWrapper) > 0;
|
||||
if (!appUpdateResult) {
|
||||
log.warn("⚠️ [更新申请单] 更新失败,申请ID: {}", change.getApplicationId());
|
||||
} else {
|
||||
log.info("✅ [更新申请单] 更新成功,申请ID: {}", change.getApplicationId());
|
||||
}
|
||||
} else {
|
||||
log.warn("⚠️ [更新申请单] 申请单不存在,申请ID: {}", change.getApplicationId());
|
||||
}
|
||||
|
||||
// 2. 更新 rs_overseas_record 表
|
||||
RsOverseasRecordVo recordVo = recordMapper
|
||||
.selectOverseasRecordByApplicationId(change.getApplicationId());
|
||||
if (recordVo != null) {
|
||||
RsOverseasRecord record = recordMapper.selectById(recordVo.getRecordId());
|
||||
if (record != null) {
|
||||
LambdaUpdateWrapper<RsOverseasRecord> recordUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||
recordUpdateWrapper.eq(RsOverseasRecord::getRecordId, record.getRecordId());
|
||||
|
||||
// 更新前往国家
|
||||
if (change.getNewDestination() != null && !change.getNewDestination().trim().isEmpty()) {
|
||||
recordUpdateWrapper.set(RsOverseasRecord::getDestination, change.getNewDestination());
|
||||
log.info("✅ [更新记录] 前往国家: {}", change.getNewDestination());
|
||||
}
|
||||
|
||||
// 更新实际开始日期和结束日期
|
||||
if (change.getNewStartDate() != null) {
|
||||
recordUpdateWrapper.set(RsOverseasRecord::getActualStartDate, change.getNewStartDate());
|
||||
log.info("✅ [更新记录] 实际开始日期: {}", change.getNewStartDate());
|
||||
}
|
||||
if (change.getNewEndDate() != null) {
|
||||
recordUpdateWrapper.set(RsOverseasRecord::getActualEndDate, change.getNewEndDate());
|
||||
log.info("✅ [更新记录] 实际结束日期: {}", change.getNewEndDate());
|
||||
|
||||
// 重新计算实际出国天数
|
||||
if (change.getNewStartDate() != null && change.getNewEndDate() != null) {
|
||||
long diffInMillies = change.getNewEndDate().getTime()
|
||||
- change.getNewStartDate().getTime();
|
||||
int days = (int) (diffInMillies / (1000 * 60 * 60 * 24)) + 1;
|
||||
recordUpdateWrapper.set(RsOverseasRecord::getActualDuration, days);
|
||||
log.info("✅ [更新记录] 实际出国天数: {} 天", days);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新行程安排
|
||||
if (change.getNewItinerary() != null && !change.getNewItinerary().trim().isEmpty()) {
|
||||
recordUpdateWrapper.set(RsOverseasRecord::getItinerary, change.getNewItinerary());
|
||||
log.info("✅ [更新记录] 行程安排已更新");
|
||||
}
|
||||
|
||||
boolean recordUpdateResult = recordMapper.update(null, recordUpdateWrapper) > 0;
|
||||
if (!recordUpdateResult) {
|
||||
log.warn("⚠️ [更新记录] 更新失败,记录ID: {}", record.getRecordId());
|
||||
} else {
|
||||
log.info("✅ [更新记录] 更新成功,记录ID: {}", record.getRecordId());
|
||||
}
|
||||
} else {
|
||||
log.warn("⚠️ [更新记录] 记录不存在,记录ID: {}", recordVo.getRecordId());
|
||||
}
|
||||
} else {
|
||||
log.warn("⚠️ [更新记录] 未找到关联记录,申请ID: {}", change.getApplicationId());
|
||||
}
|
||||
|
||||
log.info("✅ [审批通过] 数据更新完成,变更ID: {}", changeId);
|
||||
} catch (Exception e) {
|
||||
log.error("❌ [审批通过] 更新原申请单和记录数据失败,变更ID: {}, 错误: {}", changeId, e.getMessage(), e);
|
||||
throw new ServiceException("审批通过后更新原申请单和记录数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,4 +435,3 @@ public class RsOverseasItineraryChangeServiceImpl implements IRsOverseasItinerar
|
||||
return changeMapper.selectChangeListByRecordId(recordId);
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -617,5 +617,42 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</if>
|
||||
ORDER BY a.apply_time DESC, a.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 🔴 新增:根据角色查询待审批申请列表(支持分页和搜索) -->
|
||||
<select id="selectPendingApplicationsByRole" resultMap="RsOverseasApplicationVoResult">
|
||||
<include refid="selectOverseasApplicationVo"/>
|
||||
<where>
|
||||
oa.deleted = '0'
|
||||
AND oa.status = '0'
|
||||
<!-- 审批级别过滤 -->
|
||||
<if test="approvalLevels != null and approvalLevels.size() > 0">
|
||||
AND oa.approval_level IN
|
||||
<foreach collection="approvalLevels" item="level" open="(" separator="," close=")">
|
||||
#{level}
|
||||
</foreach>
|
||||
</if>
|
||||
<!-- 部门过滤(仅对部门负责人生效) -->
|
||||
<if test="deptId != null">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM sys_user u
|
||||
WHERE u.user_id = oa.applicant_id
|
||||
AND u.dept_id = #{deptId}
|
||||
)
|
||||
</if>
|
||||
<!-- 搜索条件:前往国家 -->
|
||||
<if test="query != null and query.destination != null and query.destination != ''">
|
||||
AND oa.destination LIKE CONCAT('%', #{query.destination}, '%')
|
||||
</if>
|
||||
<!-- 搜索条件:出境事由 -->
|
||||
<if test="query != null and query.exitReason != null and query.exitReason != ''">
|
||||
AND oa.exit_reason = #{query.exitReason}
|
||||
</if>
|
||||
<!-- 租户过滤 -->
|
||||
<if test="query != null and query.tenantId != null and query.tenantId != ''">
|
||||
AND oa.tenant_id = #{query.tenantId}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY oa.create_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+5
-8
@@ -74,8 +74,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<sql id="selectOverseasRecordDetailVo">
|
||||
select
|
||||
ors.record_id, ors.application_id, ors.applicant_id, ors.applicant_name, ors.department,
|
||||
ors.position,
|
||||
COALESCE(sp.post_name, ors.position) as position_text,
|
||||
oa.position,
|
||||
oa.position as position_text,
|
||||
ors.contact_phone, ors.contact_email, ors.purpose, ors.purpose_detail, ors.destination, ors.destination_city,
|
||||
ors.actual_start_date, ors.actual_end_date, ors.actual_duration, ors.actual_budget,
|
||||
ors.invitation, ors.itinerary, ors.accommodation_plan, ors.transportation_plan,
|
||||
@@ -134,7 +134,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
'record' as data_source
|
||||
from rs_overseas_record ors
|
||||
left join rs_overseas_application oa on ors.application_id = oa.application_id and oa.deleted = '0'
|
||||
left join sys_post sp on (ors.position = CAST(sp.post_id AS CHAR) or ors.position = sp.post_code) and sp.status = '0'
|
||||
</sql>
|
||||
|
||||
<!-- 联合查询:出国记录 + 已完成审批的申请 -->
|
||||
@@ -142,8 +141,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
-- 查询已创建的出国记录(关联申请表获取扩展字段)
|
||||
select
|
||||
ors.record_id, ors.application_id, ors.applicant_id, ors.applicant_name, ors.department,
|
||||
ors.position,
|
||||
COALESCE(sp1.post_name, ors.position) as position_text,
|
||||
oa.position,
|
||||
oa.position as position_text,
|
||||
ors.contact_phone, ors.contact_email, ors.purpose, ors.purpose_detail, ors.destination, ors.destination_city,
|
||||
ors.actual_start_date as actual_start_date, ors.actual_end_date as actual_end_date, ors.actual_duration as actual_duration,
|
||||
ors.actual_budget as actual_budget,
|
||||
@@ -212,7 +211,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
'record' as data_source
|
||||
from rs_overseas_record ors
|
||||
left join rs_overseas_application oa on ors.application_id = oa.application_id and oa.deleted = '0'
|
||||
left join sys_post sp1 on (ors.position = CAST(sp1.post_id AS CHAR) or ors.position = sp1.post_code) and sp1.status = '0'
|
||||
where ors.deleted = '0'
|
||||
|
||||
UNION ALL
|
||||
@@ -222,7 +220,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
NULL as record_id,
|
||||
oa.application_id, oa.applicant_id, oa.applicant_name, oa.department,
|
||||
oa.position,
|
||||
COALESCE(sp2.post_name, oa.position) as position_text,
|
||||
oa.position as position_text,
|
||||
oa.contact_phone, oa.contact_email, oa.purpose, oa.purpose_detail, oa.destination, oa.destination_city,
|
||||
oa.start_date as actual_start_date, oa.end_date as actual_end_date, oa.duration as actual_duration,
|
||||
NULL as actual_budget,
|
||||
@@ -284,7 +282,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
'进行中' as completion_status_text,
|
||||
'approved_application' as data_source
|
||||
from rs_overseas_application oa
|
||||
left join sys_post sp2 on (oa.position = CAST(sp2.post_id AS CHAR) or oa.position = sp2.post_code) and sp2.status = '0'
|
||||
where oa.deleted = '0'
|
||||
and oa.status = '1'
|
||||
and not exists (
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
-- 招聘模块表结构
|
||||
-- 创建于 2025-07-02
|
||||
|
||||
-- 职位表
|
||||
DROP TABLE IF EXISTS `rs_job`;
|
||||
CREATE TABLE `rs_job` (
|
||||
`job_id` bigint(20) NOT NULL COMMENT '职位ID',
|
||||
`title` varchar(100) NOT NULL COMMENT '职位名称',
|
||||
`department` varchar(50) NOT NULL COMMENT '部门',
|
||||
`salary_range` varchar(50) DEFAULT NULL COMMENT '薪资范围',
|
||||
`location` varchar(100) DEFAULT NULL COMMENT '工作地点',
|
||||
`description` text COMMENT '职位描述',
|
||||
`requirements` text COMMENT '任职要求',
|
||||
`is_active` char(1) DEFAULT '0' COMMENT '是否在招(0是 1否)',
|
||||
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
|
||||
`view_count` int(11) DEFAULT '0' COMMENT '浏览次数',
|
||||
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
`deleted` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`job_id`),
|
||||
KEY `idx_department` (`department`),
|
||||
KEY `idx_is_active` (`is_active`)
|
||||
) ENGINE=InnoDB COMMENT='招聘职位表';
|
||||
|
||||
-- 应聘者表
|
||||
DROP TABLE IF EXISTS `rs_applicant`;
|
||||
CREATE TABLE `rs_applicant` (
|
||||
`applicant_id` bigint(20) NOT NULL COMMENT '应聘者ID',
|
||||
`user_id` bigint(20) DEFAULT NULL COMMENT '关联用户ID',
|
||||
`name` varchar(50) NOT NULL COMMENT '姓名',
|
||||
`phone` varchar(20) NOT NULL COMMENT '手机号码',
|
||||
`email` varchar(100) NOT NULL COMMENT '电子邮箱',
|
||||
`resume_file_path` varchar(255) DEFAULT NULL COMMENT '简历文件路径',
|
||||
`self_intro` text COMMENT '自我介绍',
|
||||
`current_status` varchar(20) DEFAULT 'active' COMMENT '当前状态(active-可申请 hired-已录用 rejected-已拒绝)',
|
||||
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
|
||||
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
`deleted` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`applicant_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_phone` (`phone`)
|
||||
) ENGINE=InnoDB COMMENT='应聘者信息表';
|
||||
|
||||
-- 教育经历表
|
||||
DROP TABLE IF EXISTS `rs_education`;
|
||||
CREATE TABLE `rs_education` (
|
||||
`edu_id` bigint(20) NOT NULL COMMENT '教育经历ID',
|
||||
`applicant_id` bigint(20) NOT NULL COMMENT '应聘者ID',
|
||||
`school_name` varchar(100) NOT NULL COMMENT '学校名称',
|
||||
`major` varchar(100) DEFAULT NULL COMMENT '专业',
|
||||
`degree` varchar(50) DEFAULT NULL COMMENT '学位',
|
||||
`start_date` date DEFAULT NULL COMMENT '开始日期',
|
||||
`end_date` date DEFAULT NULL COMMENT '结束日期',
|
||||
`gpa` varchar(20) DEFAULT NULL COMMENT '绩点',
|
||||
`description` text COMMENT '描述',
|
||||
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
|
||||
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`deleted` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`edu_id`),
|
||||
KEY `idx_applicant_id` (`applicant_id`)
|
||||
) ENGINE=InnoDB COMMENT='教育经历表';
|
||||
|
||||
-- 工作经历表
|
||||
DROP TABLE IF EXISTS `rs_work_experience`;
|
||||
CREATE TABLE `rs_work_experience` (
|
||||
`exp_id` bigint(20) NOT NULL COMMENT '工作经历ID',
|
||||
`applicant_id` bigint(20) NOT NULL COMMENT '应聘者ID',
|
||||
`company_name` varchar(100) NOT NULL COMMENT '公司名称',
|
||||
`position` varchar(100) NOT NULL COMMENT '职位',
|
||||
`start_date` date DEFAULT NULL COMMENT '开始日期',
|
||||
`end_date` date DEFAULT NULL COMMENT '结束日期',
|
||||
`is_current` char(1) DEFAULT '0' COMMENT '是否当前工作(0是 1否)',
|
||||
`description` text COMMENT '工作描述',
|
||||
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
|
||||
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`deleted` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`exp_id`),
|
||||
KEY `idx_applicant_id` (`applicant_id`)
|
||||
) ENGINE=InnoDB COMMENT='工作经历表';
|
||||
|
||||
-- 申请记录表
|
||||
DROP TABLE IF EXISTS `rs_application`;
|
||||
CREATE TABLE `rs_application` (
|
||||
`application_id` bigint(20) NOT NULL COMMENT '申请ID',
|
||||
`job_id` bigint(20) NOT NULL COMMENT '职位ID',
|
||||
`applicant_id` bigint(20) NOT NULL COMMENT '应聘者ID',
|
||||
`apply_time` datetime NOT NULL COMMENT '申请时间',
|
||||
`status` varchar(20) DEFAULT 'pending' COMMENT '状态(pending-待处理 interviewed-已面试 offered-已录用 rejected-已拒绝)',
|
||||
`hr_notes` text COMMENT 'HR备注',
|
||||
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
|
||||
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
`deleted` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`application_id`),
|
||||
KEY `idx_job_id` (`job_id`),
|
||||
KEY `idx_applicant_id` (`applicant_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB COMMENT='申请记录表';
|
||||
|
||||
-- 附件表
|
||||
DROP TABLE IF EXISTS `rs_attachment`;
|
||||
CREATE TABLE `rs_attachment` (
|
||||
`attachment_id` bigint(20) NOT NULL COMMENT '附件ID',
|
||||
`application_id` bigint(20) NOT NULL COMMENT '申请ID',
|
||||
`file_name` varchar(100) NOT NULL COMMENT '文件名',
|
||||
`file_path` varchar(255) NOT NULL COMMENT '文件路径',
|
||||
`file_type` varchar(50) DEFAULT NULL COMMENT '文件类型',
|
||||
`file_size` bigint(20) DEFAULT NULL COMMENT '文件大小(字节)',
|
||||
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
|
||||
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`deleted` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`attachment_id`),
|
||||
KEY `idx_application_id` (`application_id`)
|
||||
) ENGINE=InnoDB COMMENT='申请附件表';
|
||||
|
||||
-- 插入初始测试数据
|
||||
INSERT INTO `rs_job` (`job_id`, `title`, `department`, `salary_range`, `location`, `description`, `requirements`, `is_active`, `create_time`, `create_by`, `update_time`, `update_by`, `remark`, `deleted`, `tenant_id`)
|
||||
VALUES
|
||||
(1, '高级Java开发工程师', '教学', '15k-25k', '杭州', '负责校园教学管理系统的开发和维护,参与核心模块设计与实现,优化系统性能,解决技术难题。\n作为团队核心成员,参与技术方案评审,指导初级开发人员,确保项目按时高质量交付。', '计算机相关专业本科及以上学历,3年以上Java开发经验\n精通Java核心技术,熟悉Spring Boot、MyBatis等主流框架\n熟练掌握MySQL数据库设计与优化\n有教育行业相关系统开发经验者优先\n良好的沟通能力和团队协作精神', '0', NOW(), 1, NOW(), 1, '示例职位', '0', '000000'),
|
||||
(2, '前端工程师', '教学', '12k-18k', '杭州', '负责校园教学管理系统前端开发,使用Vue3+TypeScript技术栈,参与UI设计与实现', '计算机相关专业本科及以上学历,2年以上前端开发经验\n精通HTML5/CSS3/JavaScript,熟悉Vue3/React等主流框架\n熟练使用TypeScript进行开发\n有教育行业相关系统开发经验者优先', '0', NOW(), 1, NOW(), 1, '示例职位', '0', '000000'),
|
||||
(3, '行政助理', '行政', '5k-8k', '杭州', '协助部门主管处理日常行政事务,包括文件整理、会议安排、接待来访等工作', '大专及以上学历,行政管理相关专业优先\n熟悉办公软件,有较强的文字处理能力\n工作认真负责,有较强的组织协调能力\n有相关工作经验者优先', '0', NOW(), 1, NOW(), 1, '示例职位', '0', '000000');
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
-- -----------------------------
|
||||
-- 删除培训申请表中的提交次数字段
|
||||
-- -----------------------------
|
||||
|
||||
-- 删除 rs_training_application 表中的 submit_count 字段
|
||||
-- 注意:MySQL 5.7及以下版本不支持 DROP COLUMN IF EXISTS 语法
|
||||
-- 需要先检查字段是否存在,然后删除
|
||||
ALTER TABLE rs_training_application DROP COLUMN submit_count;
|
||||
|
||||
-- 验证字段已删除
|
||||
DESCRIBE rs_training_application;
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
-- -----------------------------
|
||||
-- 培训审批数据一致性检查和修复
|
||||
-- -----------------------------
|
||||
|
||||
-- 检查审批记录表是否为空
|
||||
SELECT COUNT(*) AS approval_count FROM rs_training_approval WHERE deleted = '0';
|
||||
|
||||
-- 检查审批记录与申请记录是否一致
|
||||
SELECT
|
||||
COUNT(*) AS inconsistent_count
|
||||
FROM
|
||||
rs_training_approval a
|
||||
LEFT JOIN
|
||||
rs_training_application app ON a.application_id = app.application_id
|
||||
WHERE
|
||||
a.deleted = '0'
|
||||
AND (app.application_id IS NULL OR app.deleted = '1');
|
||||
|
||||
-- 插入测试数据(如果没有审批记录)
|
||||
INSERT INTO rs_training_approval (
|
||||
approval_id, application_id, approver_id, approver_name,
|
||||
approval_level, status, opinion, approval_time, tenant_id,
|
||||
create_by, create_time, deleted
|
||||
)
|
||||
SELECT
|
||||
FLOOR(RAND() * 1000000) + 100000, -- 随机审批ID
|
||||
app.application_id, -- 使用真实申请ID
|
||||
app.create_by, -- 使用申请的创建者ID作为审批人ID
|
||||
(SELECT user_name FROM sys_user WHERE user_id = app.create_by LIMIT 1), -- 获取用户名
|
||||
1, -- 审批级别
|
||||
app.status, -- 使用申请状态
|
||||
'系统自动生成的测试审批记录', -- 审批意见
|
||||
app.update_time, -- 使用申请更新时间作为审批时间
|
||||
app.tenant_id, -- 租户ID
|
||||
app.create_by, -- 创建者
|
||||
NOW(), -- 创建时间
|
||||
'0' -- 未删除
|
||||
FROM
|
||||
rs_training_application app
|
||||
WHERE
|
||||
app.deleted = '0'
|
||||
AND app.status IN ('1', '2') -- 已通过或已拒绝
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM rs_training_approval a
|
||||
WHERE a.application_id = app.application_id AND a.deleted = '0'
|
||||
)
|
||||
LIMIT 5; -- 限制生成5条测试数据
|
||||
|
||||
-- 查询生成的测试数据
|
||||
SELECT
|
||||
a.approval_id, a.application_id, a.approver_name, a.status, a.opinion, a.approval_time,
|
||||
app.user_name AS applicant_name, app.reason
|
||||
FROM
|
||||
rs_training_approval a
|
||||
JOIN
|
||||
rs_training_application app ON a.application_id = app.application_id
|
||||
WHERE
|
||||
a.deleted = '0'
|
||||
AND a.create_time > DATE_SUB(NOW(), INTERVAL 1 HOUR) -- 最近一小时创建的记录
|
||||
ORDER BY
|
||||
a.create_time DESC;
|
||||
@@ -1,38 +0,0 @@
|
||||
-- ----------------------------
|
||||
-- 培训管理模块测试数据
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训课程表测试数据
|
||||
-- ----------------------------
|
||||
INSERT INTO `rs_training_course` (`course_id`, `title`, `description`, `instructor`, `duration`, `location`, `capacity`, `status`, `start_time`, `end_time`, `tenant_id`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `deleted`)
|
||||
VALUES
|
||||
(10001, '新入职教师培训', '针对新入职教师的岗前培训,包括教学理念、师德师风、教学方法等内容', '张教授', 16, '学术会议厅', 50, '1', '2025-08-01 09:00:00', '2025-08-03 17:00:00', '000000', 1, NOW(), 1, NOW(), '重要培训', '0'),
|
||||
(10002, '教育技术与信息化', '介绍现代教育技术在教学中的应用,包括多媒体教学、在线教育平台等', '李博士', 12, '多媒体教室', 30, '1', '2025-08-10 09:00:00', '2025-08-12 17:00:00', '000000', 1, NOW(), 1, NOW(), '技术培训', '0'),
|
||||
(10003, '教学方法与技能培训', '提升教师教学技能,包括课堂管理、学生互动、教学评估等', '王老师', 8, '实训楼', 40, '1', '2025-08-05 14:00:00', '2025-08-05 18:00:00', '000000', 1, NOW(), 1, NOW(), '实用培训', '0'),
|
||||
(10004, '学生管理与心理健康', '帮助教师了解学生心理,掌握学生管理技巧和心理疏导方法', '陈心理师', 6, '学术报告厅', 60, '1', '2025-08-15 14:00:00', '2025-08-15 18:00:00', '000000', 1, NOW(), 1, NOW(), '心理培训', '0'),
|
||||
(10005, '科研方法与学术写作', '指导教师进行科学研究,提升学术写作和论文发表能力', '赵教授', 20, '图书馆报告厅', 25, '1', '2025-08-25 09:00:00', '2025-08-30 17:00:00', '000000', 1, NOW(), 1, NOW(), '科研培训', '0');
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训申请表测试数据
|
||||
-- ----------------------------
|
||||
INSERT INTO `rs_training_application` (`application_id`, `course_id`, `user_id`, `user_name`, `department`, `position`, `reason`, `status`, `apply_time`, `current_approver`, `process_instance_id`, `tenant_id`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `deleted`)
|
||||
VALUES
|
||||
(20001, 10001, 2, '张老师', '教务处', '教师', '新入职需要培训', '1', '2025-07-25 12:03:49', 'admin', NULL, '000000', 1, NOW(), 1, NOW(), NULL, '0'),
|
||||
(20002, 10002, 3, '王老师', '信息技术中心', '工程师', '学习新技术', '1', '2025-08-01 12:37:17', 'admin', NULL, '000000', 1, NOW(), 1, NOW(), '未完成', '0'),
|
||||
(20003, 10003, 4, '刘老师', '计算机学院', '讲师', '提升教学技能', '1', '2025-07-25 12:04:06', 'admin', NULL, '000000', 1, NOW(), 1, NOW(), '培训尚未结束', '0'),
|
||||
(20004, 10004, 5, '李老师', '学生处', '辅导员', '提升学生管理能力', '1', '2025-08-06 14:24:37', 'admin', NULL, '000000', 1, NOW(), 1, NOW(), '未完成', '0'),
|
||||
(20005, 10005, 6, '陈老师', '科研处', '副教授', '提升科研能力', '1', '2025-08-22 15:25:51', 'admin', NULL, '000000', 1, NOW(), 1, NOW(), '未完成', '0');
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训审批表测试数据
|
||||
-- ----------------------------
|
||||
INSERT INTO `rs_training_approval` (`approval_id`, `application_id`, `approver_id`, `approver_name`, `approval_level`, `status`, `opinion`, `approval_time`, `tenant_id`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `deleted`)
|
||||
VALUES
|
||||
(30001, 20001, 101, '王主任', 1, '1', '同意参加,安排好工作交接', '2025-07-21 09:30:00', '000000', 101, NOW(), 101, NOW(), NULL, '0'),
|
||||
(30002, 20003, 102, '孙院长', 1, '1', '批准参加,对提升教学质量有帮助', '2025-07-23 10:15:00', '000000', 102, NOW(), 102, NOW(), NULL, '0'),
|
||||
(30003, 20004, 103, '周主任', 1, '2', '近期有重要工作交接,建议下次再参加', '2025-07-24 14:20:00', '000000', 103, NOW(), 103, NOW(), NULL, '0');
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训记录表测试数据已删除,请通过申请界面新增
|
||||
-- ----------------------------
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
-- -----------------------------
|
||||
-- 培训审批数据修复脚本
|
||||
-- -----------------------------
|
||||
|
||||
-- 检查comment列是否存在,如果存在则迁移数据到opinion列
|
||||
SET @columnExists = 0;
|
||||
SELECT COUNT(*) INTO @columnExists
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'rs_training_approval'
|
||||
AND COLUMN_NAME = 'comment';
|
||||
|
||||
-- 如果comment列存在,将数据从comment迁移到opinion
|
||||
SET @sqlStmt = IF(@columnExists > 0,
|
||||
'UPDATE rs_training_approval SET opinion = comment WHERE opinion IS NULL AND comment IS NOT NULL',
|
||||
'SELECT "comment列不存在,无需迁移" AS message');
|
||||
|
||||
PREPARE stmt FROM @sqlStmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 添加测试数据(如果表为空)
|
||||
INSERT INTO rs_training_approval (
|
||||
approval_id, application_id, approver_id, approver_name,
|
||||
approval_level, status, opinion, approval_time, tenant_id,
|
||||
create_by, create_time, deleted
|
||||
)
|
||||
SELECT
|
||||
FLOOR(RAND() * 1000000) + 100000, -- 随机ID
|
||||
app.application_id, -- 关联到真实的申请ID
|
||||
1, -- 管理员ID
|
||||
'系统管理员', -- 管理员名称
|
||||
1, -- 第一级审批
|
||||
'1', -- 已通过状态
|
||||
'系统自动生成的测试审批记录', -- 审批意见
|
||||
NOW(), -- 当前时间
|
||||
app.tenant_id, -- 使用申请的租户ID
|
||||
app.create_by, -- 使用申请的创建者
|
||||
NOW(), -- 当前时间
|
||||
'0' -- 未删除
|
||||
FROM rs_training_application app
|
||||
WHERE NOT EXISTS (SELECT 1 FROM rs_training_approval)
|
||||
LIMIT 1;
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
-- -----------------------------
|
||||
-- 培训审批历史记录完整性更新脚本
|
||||
-- -----------------------------
|
||||
|
||||
-- 1. 在培训申请表中添加提交次数字段
|
||||
ALTER TABLE rs_training_application ADD COLUMN IF NOT EXISTS submit_count int DEFAULT 1 COMMENT '提交次数';
|
||||
|
||||
-- 2. 检查并移除审批表可能存在的唯一约束(允许一个申请有多条审批记录)
|
||||
ALTER TABLE rs_training_approval DROP INDEX IF EXISTS uk_application_approver;
|
||||
ALTER TABLE rs_training_approval DROP INDEX IF EXISTS uk_application_level;
|
||||
|
||||
-- 3. 确保审批表中有足够的索引来高效查询
|
||||
CREATE INDEX IF NOT EXISTS idx_training_approval_application ON rs_training_approval(application_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_training_approval_status ON rs_training_approval(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_training_approval_time ON rs_training_approval(approval_time);
|
||||
|
||||
-- 4. 添加审批记录表注释说明
|
||||
ALTER TABLE rs_training_approval COMMENT = '培训审批表(记录所有审批动作,包括通过和拒绝记录)';
|
||||
|
||||
-- 5. 更新已有数据的提交次数为1(如果有)
|
||||
UPDATE rs_training_application SET submit_count = 1 WHERE submit_count IS NULL;
|
||||
|
||||
-- 6. 检查并修复可能的数据不一致问题
|
||||
-- 查找有申请状态为已拒绝但没有对应拒绝记录的数据
|
||||
SELECT
|
||||
app.application_id,
|
||||
app.course_id,
|
||||
app.user_name,
|
||||
app.status,
|
||||
COUNT(appr.approval_id) as approval_count
|
||||
FROM
|
||||
rs_training_application app
|
||||
LEFT JOIN
|
||||
rs_training_approval appr ON app.application_id = appr.application_id
|
||||
WHERE
|
||||
app.status = '2' AND app.deleted = '0'
|
||||
GROUP BY
|
||||
app.application_id
|
||||
HAVING
|
||||
approval_count = 0;
|
||||
|
||||
-- 查找有申请状态为已通过但没有对应通过记录的数据
|
||||
SELECT
|
||||
app.application_id,
|
||||
app.course_id,
|
||||
app.user_name,
|
||||
app.status,
|
||||
COUNT(appr.approval_id) as approval_count
|
||||
FROM
|
||||
rs_training_application app
|
||||
LEFT JOIN
|
||||
rs_training_approval appr ON app.application_id = appr.application_id
|
||||
WHERE
|
||||
app.status = '1' AND app.deleted = '0'
|
||||
GROUP BY
|
||||
app.application_id
|
||||
HAVING
|
||||
approval_count = 0;
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
-- -----------------------------
|
||||
-- 培训审批历史记录更新
|
||||
-- -----------------------------
|
||||
|
||||
-- 确保审批表中没有唯一约束,允许一个申请有多条审批记录
|
||||
ALTER TABLE rs_training_approval DROP INDEX IF EXISTS uk_application_approver;
|
||||
|
||||
-- 添加审批意见列(如果不存在)
|
||||
ALTER TABLE rs_training_approval ADD COLUMN IF NOT EXISTS opinion varchar(500) COMMENT '审批意见' AFTER status;
|
||||
|
||||
-- 添加comment列的别名以保持向后兼容(如果存在)
|
||||
ALTER TABLE rs_training_approval CHANGE COLUMN comment opinion varchar(500) COMMENT '审批意见';
|
||||
|
||||
-- 更新审批记录表注释
|
||||
ALTER TABLE rs_training_approval COMMENT = '培训审批表(记录所有审批动作,包括拒绝记录)';
|
||||
|
||||
-- 添加相关索引以提高查询效率
|
||||
CREATE INDEX IF NOT EXISTS idx_training_approval_application ON rs_training_approval(application_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_training_approval_status ON rs_training_approval(status);
|
||||
@@ -1,17 +0,0 @@
|
||||
-- 更新培训课程表,添加create_dept字段
|
||||
ALTER TABLE rs_training_course ADD COLUMN create_dept bigint(20) COMMENT '创建部门' AFTER tenant_id;
|
||||
|
||||
-- 更新培训申请表,添加create_dept字段
|
||||
ALTER TABLE rs_training_application ADD COLUMN create_dept bigint(20) COMMENT '创建部门' AFTER tenant_id;
|
||||
|
||||
-- 更新培训申请表,添加location、duration、startTime和endTime字段
|
||||
ALTER TABLE rs_training_application ADD COLUMN location varchar(200) COMMENT '培训地点' AFTER current_approver;
|
||||
ALTER TABLE rs_training_application ADD COLUMN duration int(11) COMMENT '学时' AFTER location;
|
||||
ALTER TABLE rs_training_application ADD COLUMN start_time datetime COMMENT '开始时间' AFTER duration;
|
||||
ALTER TABLE rs_training_application ADD COLUMN end_time datetime COMMENT '结束时间' AFTER start_time;
|
||||
|
||||
-- 更新培训审批表,添加create_dept字段
|
||||
ALTER TABLE rs_training_approval ADD COLUMN create_dept bigint(20) COMMENT '创建部门' AFTER tenant_id;
|
||||
|
||||
-- 更新培训记录表,添加create_dept字段
|
||||
ALTER TABLE rs_training_record ADD COLUMN create_dept bigint(20) COMMENT '创建部门' AFTER tenant_id;
|
||||
@@ -1,122 +0,0 @@
|
||||
-- ----------------------------
|
||||
-- 培训管理模块数据库表
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训课程表
|
||||
-- ----------------------------
|
||||
drop table if exists rs_training_course;
|
||||
create table rs_training_course (
|
||||
course_id bigint(20) not null comment '课程ID',
|
||||
title varchar(100) not null comment '课程名称',
|
||||
category varchar(50) not null comment '课程类别',
|
||||
description text comment '课程描述',
|
||||
start_time datetime not null comment '开始时间',
|
||||
end_time datetime not null comment '结束时间',
|
||||
duration int(11) not null comment '学时数',
|
||||
location varchar(200) comment '培训地点',
|
||||
max_participants int(11) default 0 comment '最大参与人数',
|
||||
current_participants int(11) default 0 comment '当前报名人数',
|
||||
status char(1) default '0' comment '状态(0正常 1停用)',
|
||||
tenant_id varchar(20) default '000000' comment '租户编号',
|
||||
create_by bigint(20) comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by bigint(20) comment '更新者',
|
||||
update_time datetime comment '更新时间',
|
||||
remark varchar(500) comment '备注',
|
||||
deleted char(1) default '0' comment '删除标志',
|
||||
primary key (course_id)
|
||||
) engine=innodb comment = '培训课程表';
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训申请表
|
||||
-- ----------------------------
|
||||
drop table if exists rs_training_application;
|
||||
create table rs_training_application (
|
||||
application_id bigint(20) not null comment '申请ID',
|
||||
course_name varchar(100) not null comment '培训名称',
|
||||
user_id bigint(20) not null comment '申请人ID',
|
||||
user_name varchar(50) not null comment '申请人姓名',
|
||||
department varchar(50) not null comment '所属部门',
|
||||
position varchar(50) comment '职位',
|
||||
reason text comment '申请理由',
|
||||
status char(1) default '0' comment '状态(0待审核 1已通过 2已拒绝 3进行中 4已完成)',
|
||||
apply_time datetime comment '申请时间',
|
||||
current_approver varchar(50) comment '当前审批人',
|
||||
location varchar(200) comment '培训地点',
|
||||
duration int(11) comment '学时',
|
||||
start_time datetime comment '开始时间',
|
||||
end_time datetime comment '结束时间',
|
||||
tenant_id varchar(20) default '000000' comment '租户编号',
|
||||
create_dept bigint(20) comment '创建部门',
|
||||
reject_time datetime comment '拒绝时间',
|
||||
create_by bigint(20) comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by bigint(20) comment '更新者',
|
||||
update_time datetime comment '更新时间',
|
||||
remark varchar(500) comment '备注',
|
||||
deleted char(1) default '0' comment '删除标志',
|
||||
primary key (application_id)
|
||||
) engine=innodb comment = '培训申请表';
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训审批表
|
||||
-- ----------------------------
|
||||
drop table if exists rs_training_approval;
|
||||
create table rs_training_approval (
|
||||
approval_id bigint(20) not null comment '审批ID',
|
||||
application_id bigint(20) not null comment '申请ID',
|
||||
approver_id bigint(20) not null comment '审批人ID',
|
||||
approver_name varchar(50) not null comment '审批人姓名',
|
||||
approval_level int(11) not null comment '审批级别(1部门主管 2分管领导 3校领导)',
|
||||
status char(1) default '0' comment '状态(0待审核 1已通过 2已拒绝)',
|
||||
opinion varchar(500) comment '审批意见',
|
||||
approval_time datetime comment '审批时间',
|
||||
tenant_id varchar(20) default '000000' comment '租户编号',
|
||||
create_by bigint(20) comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by bigint(20) comment '更新者',
|
||||
update_time datetime comment '更新时间',
|
||||
remark varchar(500) comment '备注',
|
||||
deleted char(1) default '0' comment '删除标志',
|
||||
primary key (approval_id)
|
||||
) engine=innodb comment = '培训审批表';
|
||||
|
||||
-- ----------------------------
|
||||
-- 培训记录表
|
||||
-- ----------------------------
|
||||
drop table if exists rs_training_record;
|
||||
create table rs_training_record (
|
||||
record_id bigint(20) not null comment '记录ID',
|
||||
application_id bigint(20) not null comment '申请ID',
|
||||
course_id bigint(20) not null comment '课程ID',
|
||||
user_id bigint(20) not null comment '用户ID',
|
||||
user_name varchar(50) not null comment '用户姓名',
|
||||
completion_status char(1) default '0' comment '完成状态(0进行中 1已完成 2未完成)',
|
||||
completion_time datetime comment '完成时间',
|
||||
score decimal(5,2) comment '成绩',
|
||||
certificate_path varchar(255) comment '证书路径',
|
||||
certificate_number varchar(50) comment '证书编号',
|
||||
attachment_ids varchar(255) comment '证书附件ID(多个用逗号分隔)',
|
||||
feedback text comment '培训反馈',
|
||||
location varchar(255) comment '培训地点',
|
||||
duration int(11) comment '学时',
|
||||
apply_time datetime comment '申请时间',
|
||||
status varchar(10) comment '申请状态',
|
||||
course_name varchar(255) comment '课程名称',
|
||||
department varchar(255) comment '所属部门',
|
||||
position varchar(255) comment '职位',
|
||||
reason varchar(255) comment '申请理由',
|
||||
current_approver varchar(255) comment '当前审批人',
|
||||
start_time datetime comment '开始时间',
|
||||
end_time datetime comment '结束时间',
|
||||
tenant_id varchar(20) default '000000' comment '租户编号',
|
||||
create_dept bigint(20) comment '创建部门',
|
||||
create_by bigint(20) comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by bigint(20) comment '更新者',
|
||||
update_time datetime comment '更新时间',
|
||||
remark varchar(500) comment '备注',
|
||||
deleted char(1) default '0' comment '删除标志',
|
||||
primary key (record_id)
|
||||
) engine=innodb comment = '培训记录表';
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
-- 添加自定义课程名称字段
|
||||
-- 创建于 2025-07-24
|
||||
|
||||
-- 在rs_training_application表中添加course_name列,用于存储自定义培训名称
|
||||
ALTER TABLE `rs_training_application` ADD COLUMN `course_name` varchar(100) DEFAULT NULL COMMENT '自定义课程名称' AFTER `course_id`;
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
-- 为rs_application表添加附件相关字段
|
||||
ALTER TABLE `rs_application`
|
||||
ADD COLUMN `attachment_path` varchar(255) DEFAULT NULL COMMENT '附件路径' AFTER `self_description`,
|
||||
ADD COLUMN `attachment_name` varchar(255) DEFAULT NULL COMMENT '附件名称' AFTER `attachment_path`;
|
||||
|
||||
-- 更新表注释
|
||||
ALTER TABLE `rs_application` COMMENT '应聘申请记录表';
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
-- =============================================
|
||||
-- 修改 rs_overseas_application 表结构
|
||||
-- 将 party_retention_file_oss_id 字段从 bigint 改为 varchar(500)
|
||||
-- 以支持存储多个附件OSS ID(逗号分隔)
|
||||
-- 创建时间: 2025-11-27
|
||||
-- =============================================
|
||||
|
||||
-- 修改字段类型(MySQL/MariaDB)
|
||||
ALTER TABLE rs_overseas_application
|
||||
MODIFY COLUMN party_retention_file_oss_id VARCHAR(500) COMMENT '党籍保留附件OSS ID(多个ID用逗号分隔)';
|
||||
|
||||
-- 注意:
|
||||
-- 1. 此脚本会保留现有数据,bigint值会自动转换为字符串
|
||||
-- 2. 建议在执行前备份数据库
|
||||
-- 3. 如果字段当前有NOT NULL约束,会被保留
|
||||
Reference in new issue
Block a user