Explorar o código

feat(activity): 报名驳回原因落库

Xiaogang Liao hai 5 días
pai
achega
73b0ff8d34

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminActivityRegistrationController.java

@@ -44,7 +44,8 @@ public class AdminActivityRegistrationController {
         }
         Long registrationId = readRegistrationId(params);
         if (registrationId == null) return Result.error("报名ID不能为空");
-        return registrationService.reject(registrationId, userId);
+        String reason = params.get("reason") != null ? params.get("reason").toString() : null;
+        return registrationService.reject(registrationId, userId, reason);
     }
 
     /** 兼容 registrationId 与 id 两种入参 */

+ 1 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/ActivityRegistration.java

@@ -20,6 +20,7 @@ public class ActivityRegistration implements Serializable {
     /** 报名人联系方式 */
     private String registrantPhone;
     private String status;
+    private String rejectReason;
     private LocalDateTime registeredAt;
     private LocalDateTime approvedAt;
     private Long approvedBy;

+ 8 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/ActivityRegistrationService.java

@@ -111,11 +111,19 @@ public class ActivityRegistrationService {
 
     @Transactional
     public Result<Void> reject(Long registrationId, Long adminUserId) {
+        return reject(registrationId, adminUserId, null);
+    }
+
+    @Transactional
+    public Result<Void> reject(Long registrationId, Long adminUserId, String reason) {
         ActivityRegistration reg = registrationMapper.selectById(registrationId);
         if (reg == null) return Result.error("报名记录不存在");
         if (!"pending".equals(reg.getStatus())) return Result.error("当前状态不允许审核");
         reg.setStatus("rejected"); reg.setApprovedAt(LocalDateTime.now());
         reg.setApprovedBy(adminUserId); reg.setUpdatedAt(LocalDateTime.now());
+        if (reason != null && !reason.trim().isEmpty()) {
+            reg.setRejectReason(reason.trim());
+        }
         registrationMapper.updateById(reg);
         return Result.success(null);
     }

+ 1 - 0
cfc-backend/src/main/resources/schema.sql

@@ -2070,6 +2070,7 @@ CREATE TABLE IF NOT EXISTS activity_registrations (
     registrant_name VARCHAR(100) COMMENT '报名人姓名',
     registrant_phone VARCHAR(20) COMMENT '报名人联系方式',
     status VARCHAR(20) DEFAULT 'pending' COMMENT '状态: pending/approved/rejected/cancelled',
+    reject_reason VARCHAR(500) COMMENT '驳回原因',
     registered_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '报名时间',
     approved_at DATETIME COMMENT '审核通过时间',
     approved_by BIGINT COMMENT '审核人用户ID',

+ 68 - 0
cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityRegistrationRejectTest.java

@@ -0,0 +1,68 @@
+package com.etotem.cfc.unit;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.ActivityRegistration;
+import com.etotem.cfc.mapper.ActivityRegistrationMapper;
+import com.etotem.cfc.service.ActivityRegistrationService;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Field;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+class ActivityRegistrationRejectTest {
+
+    private ActivityRegistrationService serviceWith(ActivityRegistrationMapper mapper) throws Exception {
+        ActivityRegistrationService svc = new ActivityRegistrationService();
+        Field f = ActivityRegistrationService.class.getDeclaredField("registrationMapper");
+        f.setAccessible(true);
+        f.set(svc, mapper);
+        return svc;
+    }
+
+    @Test
+    void 驳回写入状态与原因() throws Exception {
+        ActivityRegistrationMapper mapper = mock(ActivityRegistrationMapper.class);
+        ActivityRegistrationService svc = serviceWith(mapper);
+        ActivityRegistration reg = new ActivityRegistration();
+        reg.setId(1L);
+        reg.setStatus("pending");
+        when(mapper.selectById(1L)).thenReturn(reg);
+        when(mapper.updateById(any())).thenReturn(1);
+
+        svc.reject(1L, 9L, "信息不完整");
+
+        assertEquals("rejected", reg.getStatus());
+        assertEquals("信息不完整", reg.getRejectReason());
+        verify(mapper).updateById(reg);
+    }
+
+    @Test
+    void 非待审状态不允许驳回() throws Exception {
+        ActivityRegistrationMapper mapper = mock(ActivityRegistrationMapper.class);
+        ActivityRegistrationService svc = serviceWith(mapper);
+        ActivityRegistration reg = new ActivityRegistration();
+        reg.setId(2L);
+        reg.setStatus("approved");
+        when(mapper.selectById(2L)).thenReturn(reg);
+
+        Result<Void> result = svc.reject(2L, 9L, "x");
+
+        assertEquals(500, result.getCode());
+        verify(mapper, never()).updateById(any());
+    }
+
+    @Test
+    void 记录不存在返回错误() throws Exception {
+        ActivityRegistrationMapper mapper = mock(ActivityRegistrationMapper.class);
+        ActivityRegistrationService svc = serviceWith(mapper);
+        when(mapper.selectById(3L)).thenReturn(null);
+
+        Result<Void> result = svc.reject(3L, 9L, "x");
+
+        assertEquals(500, result.getCode());
+        verify(mapper, never()).updateById(any());
+    }
+}