From e2b3605106c81ec21a45dfcd6f163ed174d295c0 Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期一, 03 八月 2026 18:03:31 +0800
Subject: [PATCH] fix: resolve admin merchant management defects

---
 talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java |   38 +++++++++++++++++++++++++++++++++-----
 1 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java b/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
index 374f605..287127a 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/admin/AdminBusinessService.java
@@ -1,6 +1,8 @@
 package com.talentcard.server.business.admin;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
@@ -312,7 +314,7 @@
 				insert into merchant(merchant_name, merchant_type, contact_name, contact_mobile, address,
 					                     logo_url, cover_url, business_status, longitude, latitude, can_login_merchant_app, group_buying_enabled,
 					                     usage_instructions, rights_text, merchant_rights_config, service_label, is_recommend, status, sort_no)
-				values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0)
+				values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)
 				""",
 				request.merchantName(),
 				request.merchantType(),
@@ -330,9 +332,10 @@
 				request.rightsText(),
 				toJson(request.merchantRightsConfig()),
 				request.serviceLabel(),
-				request.recommend() == null ? 0 : request.recommend());
+				request.recommend() == null ? defaultRecommend(request.merchantType()) : request.recommend(),
+				request.sortNo() == null ? 0 : request.sortNo());
 		Long id = jdbcTemplate.queryForObject("select last_insert_id()", Long.class);
-		if (isFoodMerchantWithAppAccess(request)) {
+		if (hasMerchantAppAccess(request)) {
 			String account = request.loginAccount().trim();
 			if (!account.matches("^[A-Za-z0-9]{1,32}$")) {
 				throw new BusinessException(ErrorCode.BAD_REQUEST, "商户登录账号只能包含英文字母和数字");
@@ -352,8 +355,13 @@
 		return one("select * from merchant where id = ?", id);
 	}
 
-	private boolean isFoodMerchantWithAppAccess(MerchantCreateRequest request) {
-		return "餐饮服务".equals(request.merchantType()) && (request.canLoginMerchantApp() == null || request.canLoginMerchantApp() == 1);
+	private boolean hasMerchantAppAccess(MerchantCreateRequest request) {
+		return ("餐饮服务".equals(request.merchantType()) || "景区服务".equals(request.merchantType()))
+				&& (request.canLoginMerchantApp() == null || request.canLoginMerchantApp() == 1);
+	}
+
+	private byte defaultRecommend(String merchantType) {
+		return (byte) (("餐饮服务".equals(merchantType) || "景区服务".equals(merchantType)) ? 1 : 0);
 	}
 
 	@Transactional
@@ -696,6 +704,7 @@
 	@Transactional
 	public Map<String, Object> createCoupon(CouponCreateRequest request) {
 		ensureMerchantExists(request.merchantId());
+		validateCouponConfiguration(request.validStart(), request.validEnd(), request.productScope(), request.productIds());
 		jdbcTemplate.update("""
 				insert into merchant_coupon(merchant_id, coupon_name, condition_type, condition_amount,
 				                            coupon_amount, talent_levels, valid_start, valid_end,
@@ -721,6 +730,7 @@
 	@Transactional
 	public Map<String, Object> updateCoupon(Long id, CouponUpdateRequest request) {
 		ensureMerchantExists(request.merchantId());
+		validateCouponConfiguration(request.validStart(), request.validEnd(), request.productScope(), request.productIds());
 		int updated = jdbcTemplate.update("""
 				update merchant_coupon
 				set merchant_id = ?, coupon_name = ?, condition_type = ?, condition_amount = ?,
@@ -859,6 +869,24 @@
 		return "ALL".equalsIgnoreCase(value) ? "ALL" : "SELECTED";
 	}
 
+	private void validateCouponConfiguration(String validStart, String validEnd, String productScope, List<Long> productIds) {
+		if (validStart == null || validStart.isBlank() || validEnd == null || validEnd.isBlank()) {
+			throw new BusinessException(ErrorCode.BAD_REQUEST, "优惠券有效期不能为空");
+		}
+		try {
+			LocalDate start = LocalDate.parse(validStart);
+			LocalDate end = LocalDate.parse(validEnd);
+			if (start.isAfter(end)) {
+				throw new BusinessException(ErrorCode.BAD_REQUEST, "优惠券结束日期不能早于开始日期");
+			}
+		} catch (DateTimeParseException exception) {
+			throw new BusinessException(ErrorCode.BAD_REQUEST, "优惠券有效期格式错误");
+		}
+		if (!"ALL".equalsIgnoreCase(productScope) && (productIds == null || productIds.isEmpty())) {
+			throw new BusinessException(ErrorCode.BAD_REQUEST, "请至少选择一个可用商品");
+		}
+	}
+
 	private int defaultNewsStatus(Integer status) {
 		return status == null ? 1 : status;
 	}

--
Gitblit v1.7.1