shinnosuke
2026-08-05 971e637c2eebe93011a485ddfa99d4f19289811d
talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
@@ -10,6 +10,7 @@
import java.util.Map;
import com.talentcard.server.business.BusinessIdGenerator;
import com.alibaba.fastjson.JSON;
import com.talentcard.server.business.DatabaseRows;
import com.talentcard.server.business.PageResult;
import com.talentcard.server.business.merchant.auth.MerchantPasswordHasher;
@@ -714,7 +715,7 @@
   ) {
      StringBuilder sql = new StringBuilder("""
            select c.id, c.merchant_id, m.merchant_name, c.coupon_name, c.condition_type,
                   c.condition_amount, c.coupon_amount, c.talent_levels, c.valid_start, c.valid_end,
                   c.condition_amount, c.coupon_amount, c.talent_levels, c.talent_level_quantities, c.valid_start, c.valid_end,
                   c.product_scope, c.store_consume, c.government_subsidy, c.use_count, c.status,
                   c.created_at, c.updated_at,
                   (select count(*) from merchant_coupon_product cp where cp.coupon_id = c.id) as product_count,
@@ -766,7 +767,7 @@
   public Map<String, Object> coupon(Long id) {
      Map<String, Object> result = one("""
            select c.id, c.merchant_id, m.merchant_name, c.coupon_name, c.condition_type,
                   c.condition_amount, c.coupon_amount, c.talent_levels, c.valid_start, c.valid_end,
                   c.condition_amount, c.coupon_amount, c.talent_levels, c.talent_level_quantities, c.valid_start, c.valid_end,
                   c.product_scope, c.store_consume, c.government_subsidy, c.use_count, c.status,
                   c.created_at, c.updated_at
            from merchant_coupon c
@@ -782,11 +783,13 @@
   public Map<String, Object> createCoupon(CouponCreateRequest request) {
      ensureMerchantExists(request.merchantId());
      validateCouponConfiguration(request.validStart(), request.validEnd(), request.productScope(), request.productIds());
      validateCouponAmount(request.couponAmount());
      validateTalentLevelQuantities(request.talentLevelQuantities());
      jdbcTemplate.update("""
            insert into merchant_coupon(merchant_id, coupon_name, condition_type, condition_amount,
                                        coupon_amount, talent_levels, valid_start, valid_end,
                                        coupon_amount, talent_levels, talent_level_quantities, valid_start, valid_end,
                                        product_scope, store_consume, government_subsidy, status)
            values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
            values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
            """,
            request.merchantId(),
            request.couponName(),
@@ -794,6 +797,7 @@
            request.conditionAmount(),
            valueOrZero(request.couponAmount()),
            joinTalentLevels(request.talentLevels()),
            levelQuantitiesJson(request.talentLevelQuantities()),
            blankToNull(request.validStart()),
            blankToNull(request.validEnd()),
            normalizeProductScope(request.productScope()),
@@ -808,10 +812,12 @@
   public Map<String, Object> updateCoupon(Long id, CouponUpdateRequest request) {
      ensureMerchantExists(request.merchantId());
      validateCouponConfiguration(request.validStart(), request.validEnd(), request.productScope(), request.productIds());
      validateCouponAmount(request.couponAmount());
      validateTalentLevelQuantities(request.talentLevelQuantities());
      int updated = jdbcTemplate.update("""
            update merchant_coupon
            set merchant_id = ?, coupon_name = ?, condition_type = ?, condition_amount = ?,
                coupon_amount = ?, talent_levels = ?, valid_start = ?, valid_end = ?,
                coupon_amount = ?, talent_levels = ?, talent_level_quantities = ?, valid_start = ?, valid_end = ?,
                product_scope = ?, store_consume = ?, government_subsidy = ?, status = ?
            where deleted = 0 and id = ?
            """,
@@ -821,6 +827,7 @@
            request.conditionAmount(),
            valueOrZero(request.couponAmount()),
            joinTalentLevels(request.talentLevels()),
            levelQuantitiesJson(request.talentLevelQuantities()),
            blankToNull(request.validStart()),
            blankToNull(request.validEnd()),
            normalizeProductScope(request.productScope()),
@@ -893,6 +900,17 @@
      return value == null ? BigDecimal.ZERO : value;
   }
   private void validateCouponAmount(BigDecimal value) {
      if (value == null || value.compareTo(new BigDecimal("0.1")) < 0 || value.compareTo(new BigDecimal("9999.9")) > 0) {
         throw new BusinessException(ErrorCode.BAD_REQUEST, "优惠券金额必须在0.1-9999.9元之间");
      }
   }
   private void validateTalentLevelQuantities(Map<String, Integer> values) {
      if (values == null) return;
      values.values().forEach(value -> { if (value == null || value < 1 || value > 99) throw new BusinessException(ErrorCode.BAD_REQUEST, "人才卡发放数量必须为1-99"); });
   }
   private String levelQuantitiesJson(Map<String, Integer> values) { return values == null || values.isEmpty() ? null : JSON.toJSONString(values); }
   private String toJson(Object value) {
      if (value == null) {
         return null;