|
|
@@ -31,12 +31,16 @@ public class WorkerRegistrationService {
|
|
31
|
31
|
|
|
32
|
32
|
private static final String BATCH_ACTIVE = "active";
|
|
33
|
33
|
private static final String REG_UNDER_REVIEW = "under_review";
|
|
|
34
|
+ /** 审核通过后进入个人签合同阶段 */
|
|
|
35
|
+ private static final String REG_CONTRACT_SIGNING = "contract_signing";
|
|
34
|
36
|
private static final String REG_COMPLETED = "completed";
|
|
35
|
37
|
/** 企业审核驳回(与实名核验失败 verify_failed 区分) */
|
|
36
|
38
|
private static final String REG_REJECTED = "rejected";
|
|
37
|
39
|
private static final String STEP_REGISTRATION = "registration";
|
|
38
|
40
|
private static final String STEP_ENTERPRISE_AUDIT = "enterprise_audit";
|
|
39
|
41
|
private static final String STEP_CONTRACT_SIGNING = "contract_signing";
|
|
|
42
|
+ private static final String STEP_PLAN_CONFIRMED = "plan_confirmed";
|
|
|
43
|
+ private static final String STEP_DRAFT_CREATED = "draft_created";
|
|
40
|
44
|
private static final String APPLY_SUCCESS = "success";
|
|
41
|
45
|
private static final String APPLY_ALREADY = "already_applied";
|
|
42
|
46
|
private static final String REVIEW_APPROVED = "approved";
|
|
|
@@ -119,16 +123,15 @@ public class WorkerRegistrationService {
|
|
119
|
123
|
feWorkerRegistrationMapper.insert(reg);
|
|
120
|
124
|
|
|
121
|
125
|
bumpBatchCounters(batch, now);
|
|
122
|
|
- bumpOrderCounters(order, now);
|
|
123
|
|
- maybeAdvanceOrderToEnterpriseAudit(order, now);
|
|
|
126
|
+ bumpOrderCountersAndAdvanceToEnterpriseAudit(order, now);
|
|
124
|
127
|
|
|
125
|
128
|
return toResponse(reg, batch, order, APPLY_SUCCESS, "申请已提交,请等待企业确认");
|
|
126
|
129
|
}
|
|
127
|
130
|
|
|
128
|
131
|
/**
|
|
129
|
132
|
* 企业审核通过用工登记。
|
|
130
|
|
- * <p>仅 {@code under_review} 可审核;写 reviewed_*,登记置 completed,批次 completed_count+1;
|
|
131
|
|
- * 当本批次登记审核全部结束且通过人数达标时,订单推进到 {@code contract_signing}。</p>
|
|
|
133
|
+ * <p>仅 {@code under_review} 可审;该人 {@code reg_status→contract_signing}(进入个人签合同);
|
|
|
134
|
+ * 订单若尚未进入签约阶段则推进到 {@code contract_signing}(不要求整批审完)。</p>
|
|
132
|
135
|
*/
|
|
133
|
136
|
@Transactional(rollbackFor = Exception.class)
|
|
134
|
137
|
public WorkerRegistrationReviewResponse approve(Long userId, Long registrationId) {
|
|
|
@@ -138,7 +141,7 @@ public class WorkerRegistrationService {
|
|
138
|
141
|
FeRegistrationBatch batch = requireBatch(reg.getBatchId());
|
|
139
|
142
|
FeEmploymentOrder order = requireOrder(reg.getOrderId());
|
|
140
|
143
|
|
|
141
|
|
- if (REG_COMPLETED.equals(reg.getRegStatus())) {
|
|
|
144
|
+ if (REG_CONTRACT_SIGNING.equals(reg.getRegStatus()) || REG_COMPLETED.equals(reg.getRegStatus())) {
|
|
142
|
145
|
return toReviewResponse(reg, batch, order, REVIEW_ALREADY, "该登记已审核通过");
|
|
143
|
146
|
}
|
|
144
|
147
|
if (REG_REJECTED.equals(reg.getRegStatus())) {
|
|
|
@@ -151,33 +154,29 @@ public class WorkerRegistrationService {
|
|
151
|
154
|
LocalDateTime now = LocalDateTime.now();
|
|
152
|
155
|
FeWorkerRegistration update = new FeWorkerRegistration();
|
|
153
|
156
|
update.setId(reg.getId());
|
|
154
|
|
- update.setRegStatus(REG_COMPLETED);
|
|
|
157
|
+ update.setRegStatus(REG_CONTRACT_SIGNING);
|
|
155
|
158
|
update.setFailReason(null);
|
|
156
|
159
|
update.setReviewedAt(now);
|
|
157
|
160
|
update.setReviewedBy(userId);
|
|
158
|
161
|
update.setUpdateTime(now);
|
|
159
|
162
|
feWorkerRegistrationMapper.updateById(update);
|
|
160
|
163
|
|
|
161
|
|
- reg.setRegStatus(REG_COMPLETED);
|
|
|
164
|
+ reg.setRegStatus(REG_CONTRACT_SIGNING);
|
|
162
|
165
|
reg.setFailReason(null);
|
|
163
|
166
|
reg.setReviewedAt(now);
|
|
164
|
167
|
reg.setReviewedBy(userId);
|
|
165
|
168
|
|
|
166
|
169
|
bumpCompletedCounters(batch, now);
|
|
167
|
|
- batch = feRegistrationBatchMapper.selectById(batch.getId());
|
|
168
|
|
- maybeAdvanceOrderAfterRegistrationAudit(batch, order, now);
|
|
|
170
|
+ maybeAdvanceOrderToContractSigning(order, now);
|
|
169
|
171
|
|
|
170
|
172
|
order = feEmploymentOrderMapper.selectById(order.getId());
|
|
171
|
|
- String message = STEP_CONTRACT_SIGNING.equals(order.getCurrentStepCode())
|
|
172
|
|
- ? "审核通过,登记审核已全部完成,已进入合同签署"
|
|
173
|
|
- : "审核通过";
|
|
174
|
|
- return toReviewResponse(reg, batch, order, REVIEW_APPROVED, message);
|
|
|
173
|
+ return toReviewResponse(reg, batch, order, REVIEW_APPROVED, "审核通过,已进入合同签署");
|
|
175
|
174
|
}
|
|
176
|
175
|
|
|
177
|
176
|
/**
|
|
178
|
177
|
* 企业驳回用工登记。
|
|
179
|
|
- * <p>仅 {@code under_review} 可驳回;写 fail_reason / reviewed_*,登记置 rejected,并释放名额(registered-1、pending+1)。
|
|
180
|
|
- * 若驳回后本批次已无待审且通过人数仍达标,同样可推进到下一节点。</p>
|
|
|
178
|
+ * <p>仅 {@code under_review} 可驳回;写 fail_reason / reviewed_*,登记置 rejected,并释放名额。
|
|
|
179
|
+ * 驳回不影响其他人的签约进度,不推进订单到签约。</p>
|
|
181
|
180
|
*/
|
|
182
|
181
|
@Transactional(rollbackFor = Exception.class)
|
|
183
|
182
|
public WorkerRegistrationReviewResponse reject(Long userId, Long registrationId,
|
|
|
@@ -199,7 +198,7 @@ public class WorkerRegistrationService {
|
|
199
|
198
|
if (REG_REJECTED.equals(reg.getRegStatus())) {
|
|
200
|
199
|
return toReviewResponse(reg, batch, order, REVIEW_ALREADY, "该登记已驳回");
|
|
201
|
200
|
}
|
|
202
|
|
- if (REG_COMPLETED.equals(reg.getRegStatus())) {
|
|
|
201
|
+ if (REG_CONTRACT_SIGNING.equals(reg.getRegStatus()) || REG_COMPLETED.equals(reg.getRegStatus())) {
|
|
203
|
202
|
throw new BizException(ErrorCode.BAD_REQUEST, "该登记已审核通过,无法驳回");
|
|
204
|
203
|
}
|
|
205
|
204
|
if (!REG_UNDER_REVIEW.equals(reg.getRegStatus())) {
|
|
|
@@ -222,8 +221,6 @@ public class WorkerRegistrationService {
|
|
222
|
221
|
reg.setReviewedBy(userId);
|
|
223
|
222
|
|
|
224
|
223
|
releaseSlotCounters(batch, order, now);
|
|
225
|
|
- batch = feRegistrationBatchMapper.selectById(batch.getId());
|
|
226
|
|
- maybeAdvanceOrderAfterRegistrationAudit(batch, order, now);
|
|
227
|
224
|
|
|
228
|
225
|
order = feEmploymentOrderMapper.selectById(order.getId());
|
|
229
|
226
|
return toReviewResponse(reg, batch, order, REVIEW_REJECTED, "已驳回");
|
|
|
@@ -301,43 +298,47 @@ public class WorkerRegistrationService {
|
|
301
|
298
|
}
|
|
302
|
299
|
|
|
303
|
300
|
/**
|
|
304
|
|
- * 有人提交登记申请后,订单从 registration 进入 enterprise_audit(企业审核阶段)。
|
|
|
301
|
+ * 申请成功后:名额计数 + 如需则推进到 enterprise_audit。
|
|
305
|
302
|
*/
|
|
306
|
|
- private void maybeAdvanceOrderToEnterpriseAudit(FeEmploymentOrder order, LocalDateTime now) {
|
|
307
|
|
- String step = order.getCurrentStepCode();
|
|
308
|
|
- if (STEP_REGISTRATION.equals(step) || !StringUtils.hasText(step)) {
|
|
309
|
|
- FeEmploymentOrder update = new FeEmploymentOrder();
|
|
310
|
|
- update.setId(order.getId());
|
|
|
303
|
+ private void bumpOrderCountersAndAdvanceToEnterpriseAudit(FeEmploymentOrder order, LocalDateTime now) {
|
|
|
304
|
+ int registered = order.getRegisteredCount() != null ? order.getRegisteredCount() : 0;
|
|
|
305
|
+ int pending = order.getPendingCount() != null ? order.getPendingCount() : 0;
|
|
|
306
|
+ FeEmploymentOrder update = new FeEmploymentOrder();
|
|
|
307
|
+ update.setId(order.getId());
|
|
|
308
|
+ update.setRegisteredCount(registered + 1);
|
|
|
309
|
+ update.setPendingCount(Math.max(0, pending - 1));
|
|
|
310
|
+ update.setUpdateTime(now);
|
|
|
311
|
+ if (shouldEnterEnterpriseAudit(order.getCurrentStepCode())) {
|
|
311
|
312
|
update.setCurrentStepCode(STEP_ENTERPRISE_AUDIT);
|
|
312
|
|
- update.setUpdateTime(now);
|
|
313
|
|
- feEmploymentOrderMapper.updateById(update);
|
|
314
|
313
|
order.setCurrentStepCode(STEP_ENTERPRISE_AUDIT);
|
|
315
|
314
|
}
|
|
|
315
|
+ feEmploymentOrderMapper.updateById(update);
|
|
|
316
|
+ order.setRegisteredCount(registered + 1);
|
|
|
317
|
+ order.setPendingCount(Math.max(0, pending - 1));
|
|
|
318
|
+ }
|
|
|
319
|
+
|
|
|
320
|
+ private static boolean shouldEnterEnterpriseAudit(String step) {
|
|
|
321
|
+ if (!StringUtils.hasText(step)) {
|
|
|
322
|
+ return true;
|
|
|
323
|
+ }
|
|
|
324
|
+ String code = step.trim();
|
|
|
325
|
+ return STEP_REGISTRATION.equals(code)
|
|
|
326
|
+ || STEP_PLAN_CONFIRMED.equals(code)
|
|
|
327
|
+ || STEP_DRAFT_CREATED.equals(code);
|
|
316
|
328
|
}
|
|
317
|
329
|
|
|
318
|
330
|
/**
|
|
319
|
|
- * 登记审核全部结束且通过人数达标时,订单进入 contract_signing。
|
|
320
|
|
- * <p>
|
|
321
|
|
- * 完成条件(同时满足):
|
|
322
|
|
- * <ol>
|
|
323
|
|
- * <li>批次内无 {@code under_review}</li>
|
|
324
|
|
- * <li>{@code completed_count >= expected_count}(expected>0);expected=0 时至少 1 人通过</li>
|
|
325
|
|
- * </ol>
|
|
326
|
|
- * </p>
|
|
|
331
|
+ * 有人审核通过后,订单进入 contract_signing(整单进入签约阶段;个人已是 contract_signing)。
|
|
|
332
|
+ * <p>不要求整批审完;已处于签约及之后步骤则不回退。</p>
|
|
327
|
333
|
*/
|
|
328
|
|
- private void maybeAdvanceOrderAfterRegistrationAudit(FeRegistrationBatch batch,
|
|
329
|
|
- FeEmploymentOrder order,
|
|
330
|
|
- LocalDateTime now) {
|
|
331
|
|
- if (batch == null || order == null || !isBatchRegistrationAuditComplete(batch.getId(), batch)) {
|
|
|
334
|
+ private void maybeAdvanceOrderToContractSigning(FeEmploymentOrder order, LocalDateTime now) {
|
|
|
335
|
+ if (order == null) {
|
|
332
|
336
|
return;
|
|
333
|
337
|
}
|
|
334
|
338
|
String step = order.getCurrentStepCode();
|
|
335
|
339
|
if (STEP_CONTRACT_SIGNING.equals(step) || isStepAfter(step, STEP_CONTRACT_SIGNING)) {
|
|
336
|
340
|
return;
|
|
337
|
341
|
}
|
|
338
|
|
- if (!STEP_ENTERPRISE_AUDIT.equals(step) && !STEP_REGISTRATION.equals(step)) {
|
|
339
|
|
- return;
|
|
340
|
|
- }
|
|
341
|
342
|
FeEmploymentOrder update = new FeEmploymentOrder();
|
|
342
|
343
|
update.setId(order.getId());
|
|
343
|
344
|
update.setCurrentStepCode(STEP_CONTRACT_SIGNING);
|
|
|
@@ -346,32 +347,10 @@ public class WorkerRegistrationService {
|
|
346
|
347
|
order.setCurrentStepCode(STEP_CONTRACT_SIGNING);
|
|
347
|
348
|
}
|
|
348
|
349
|
|
|
349
|
|
- /**
|
|
350
|
|
- * 批次登记审核是否已全部结束:无待审,且通过人数达到计划用工人数。
|
|
351
|
|
- */
|
|
352
|
|
- private boolean isBatchRegistrationAuditComplete(Long batchId, FeRegistrationBatch batch) {
|
|
353
|
|
- Long underReview = feWorkerRegistrationMapper.selectCount(new LambdaQueryWrapper<FeWorkerRegistration>()
|
|
354
|
|
- .eq(FeWorkerRegistration::getBatchId, batchId)
|
|
355
|
|
- .eq(FeWorkerRegistration::getRegStatus, REG_UNDER_REVIEW));
|
|
356
|
|
- if (underReview != null && underReview > 0) {
|
|
357
|
|
- return false;
|
|
358
|
|
- }
|
|
359
|
|
- Long approved = feWorkerRegistrationMapper.selectCount(new LambdaQueryWrapper<FeWorkerRegistration>()
|
|
360
|
|
- .eq(FeWorkerRegistration::getBatchId, batchId)
|
|
361
|
|
- .eq(FeWorkerRegistration::getRegStatus, REG_COMPLETED));
|
|
362
|
|
- int approvedCount = approved != null ? approved.intValue() : 0;
|
|
363
|
|
- int expected = batch.getExpectedCount() != null ? batch.getExpectedCount() : 0;
|
|
364
|
|
- if (expected > 0) {
|
|
365
|
|
- return approvedCount >= expected;
|
|
366
|
|
- }
|
|
367
|
|
- return approvedCount > 0;
|
|
368
|
|
- }
|
|
369
|
|
-
|
|
370
|
350
|
private static boolean isStepAfter(String current, String target) {
|
|
371
|
351
|
if (!StringUtils.hasText(current) || !StringUtils.hasText(target)) {
|
|
372
|
352
|
return false;
|
|
373
|
353
|
}
|
|
374
|
|
- // 九步顺序中的粗略比较,避免重复推进
|
|
375
|
354
|
String[] order = {
|
|
376
|
355
|
"draft_created", "plan_confirmed", "registration", "enterprise_audit",
|
|
377
|
356
|
"contract_signing", "work_started", "settlement_pending", "settlement_paid", "completed"
|
|
|
@@ -441,17 +420,6 @@ public class WorkerRegistrationService {
|
|
441
|
420
|
feRegistrationBatchMapper.updateById(update);
|
|
442
|
421
|
}
|
|
443
|
422
|
|
|
444
|
|
- private void bumpOrderCounters(FeEmploymentOrder order, LocalDateTime now) {
|
|
445
|
|
- int registered = order.getRegisteredCount() != null ? order.getRegisteredCount() : 0;
|
|
446
|
|
- int pending = order.getPendingCount() != null ? order.getPendingCount() : 0;
|
|
447
|
|
- FeEmploymentOrder update = new FeEmploymentOrder();
|
|
448
|
|
- update.setId(order.getId());
|
|
449
|
|
- update.setRegisteredCount(registered + 1);
|
|
450
|
|
- update.setPendingCount(Math.max(0, pending - 1));
|
|
451
|
|
- update.setUpdateTime(now);
|
|
452
|
|
- feEmploymentOrderMapper.updateById(update);
|
|
453
|
|
- }
|
|
454
|
|
-
|
|
455
|
423
|
private static WorkerRegistrationApplyResponse toResponse(FeWorkerRegistration reg,
|
|
456
|
424
|
FeRegistrationBatch batch,
|
|
457
|
425
|
FeEmploymentOrder order,
|