shinnosuke
2026-08-28 e3f6118d03793e8ad58e10797718e93e5b1f011f
fix: allow expired scanned talent codes for consumption
1个文件已添加
1个文件已修改
63 ■■■■■ 已修改文件
talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java
@@ -72,10 +72,7 @@
        Map<String, Object> coupon = usableCoupon(principal.merchantId(), number(source.get("talentId")), string(source.get("cardLevel")), request.couponId(), discountedAmount(rule, request.amount()));
        Map<String, Object> amounts = quote(rule, coupon, request.amount());
        Long dynamicCodeId = number(source.get("dynamicCodeId"));
        int codeUpdated = jdbc.update("""
                update talent_dynamic_code set status = 1, merchant_id = ?, used_at = now()
                where id = ? and status = 0
                """, principal.merchantId(), dynamicCodeId);
        int codeUpdated = consumeScannedTalentCode(principal, dynamicCodeId);
        if (codeUpdated == 0) {
            throw new BusinessException(ErrorCode.CONFLICT, "人才码已被使用或已失效");
        }
@@ -121,6 +118,13 @@
        return sources.get(0);
    }
    int consumeScannedTalentCode(MerchantPrincipal principal, Long dynamicCodeId) {
        return jdbc.update("""
                update talent_dynamic_code set status = 1, merchant_id = ?, used_at = now()
                where id = ? and status in (0, 2)
                """, principal.merchantId(), dynamicCodeId);
    }
    private void ensurePending(Map<String, Object> source) {
        if (number(source.get("attemptStatus")) != ATTEMPT_PENDING) {
            throw new BusinessException(ErrorCode.CONFLICT, "该人才码已处理,请重新扫码");
talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java
New file
@@ -0,0 +1,51 @@
package com.talentcard.server.business.merchant;
import static org.assertj.core.api.Assertions.assertThat;
import com.talentcard.server.business.merchant.auth.MerchantPrincipal;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
class ManualConsumptionServiceTests {
    private JdbcTemplate jdbc;
    private ManualConsumptionService service;
    private MerchantPrincipal principal;
    @BeforeEach
    void setUp() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(
                "jdbc:h2:mem:manual-consumption-" + System.nanoTime() + ";MODE=MySQL;DB_CLOSE_DELAY=-1", "sa", "");
        jdbc = new JdbcTemplate(dataSource);
        jdbc.execute("""
                create table talent_dynamic_code (
                    id bigint primary key,
                    status tinyint not null,
                    merchant_id bigint,
                    used_at timestamp
                )
                """);
        service = new ManualConsumptionService(jdbc);
        principal = new MerchantPrincipal(9L, 88L, 7L, "operator");
    }
    @Test
    void consumesActiveOrExpiredCodeAfterSuccessfulScan() {
        jdbc.update("insert into talent_dynamic_code(id, status) values (1, 0), (2, 2)");
        assertThat(service.consumeScannedTalentCode(principal, 1L)).isEqualTo(1);
        assertThat(service.consumeScannedTalentCode(principal, 2L)).isEqualTo(1);
        assertThat(jdbc.queryForObject("select status from talent_dynamic_code where id = 1", Integer.class)).isEqualTo(1);
        assertThat(jdbc.queryForObject("select status from talent_dynamic_code where id = 2", Integer.class)).isEqualTo(1);
    }
    @Test
    void rejectsAlreadyUsedCode() {
        jdbc.update("insert into talent_dynamic_code(id, status, merchant_id) values (3, 1, 66)");
        assertThat(service.consumeScannedTalentCode(principal, 3L)).isZero();
        assertThat(jdbc.queryForObject("select merchant_id from talent_dynamic_code where id = 3", Long.class)).isEqualTo(66L);
    }
}