shinnosuke
2026-09-18 c2f0ec3b3891bc177bdc58c2a111ab9c4fea911d
talent-card-server/src/main/java/com/talentcard/server/business/merchant/MerchantManagementService.java
@@ -21,7 +21,11 @@
@Service
public class MerchantManagementService {
    private static final List<String> NOTICE_FIELDS = List.of("validity", "availableTime", "usage", "otherRules");
    /**
     * 购买须知里要落库的字段。{@code validPeriod} 是体检医院在后台团单里叫「可预约时间」的那一项,
     * 后台保存时写在同一个 purchase_notice 里,商家端要能读写同一个键,两端才不会各存一份。
     */
    private static final List<String> NOTICE_FIELDS = List.of("validity", "availableTime", "validPeriod", "usage", "otherRules");
    private final JdbcTemplate jdbc;
@@ -41,6 +45,9 @@
        result.put("address", value(store.get("address"), value(merchant.get("address"), "")));
        result.put("coverUrl", value(merchant.get("coverUrl"), ""));
        result.put("businessStatus", isBusinessOpen(merchant, principal.storeId()) ? "open" : "closed");
        // 商家端要按商家类型决定商品表单显示哪些字段(体检医院只配可预约时间 + 检查项目),
        // 类型跟着资料一起返回,页面不用再打一次接口。
        result.put("merchantTypeCode", value(merchant.get("merchantTypeCode"), ""));
        result.put("updatedAt", merchant.get("updatedAt"));
        Long productCount = jdbc.queryForObject("select count(*) from merchant_product where merchant_id = ? and deleted = 0 and status = 1 and audit_status = 2", Long.class, principal.merchantId());
        result.put("onlineProductCount", productCount == null ? 0 : productCount);
@@ -116,7 +123,9 @@
                from merchant_product where id = ? and merchant_id = ? and deleted = 0
                """, productId, principal.merchantId());
        if (records.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "商品不存在");
        return toProductDetail(records.get(0));
        Map<String, Object> detail = toProductDetail(records.get(0));
        detail.put("merchantTypeCode", value(merchant(principal.merchantId()).get("merchantTypeCode"), ""));
        return detail;
    }
    @Transactional
@@ -125,6 +134,15 @@
        product(principal, productId);
        String coverUrl = request.coverUrl() == null ? "" : request.coverUrl().trim();
        if (coverUrl.isEmpty()) throw new BusinessException(ErrorCode.BAD_REQUEST, "请上传商品封面图");
        // 体检医院在后台团单里没有「商品金额」这一项(后台保存时落 0,人才端据此显示「免费」),
        // 所以这里按商家类型区分:非体检医院仍然必须有大于 0 的金额。
        BigDecimal salePrice = request.salePrice();
        if (salePrice == null || salePrice.signum() <= 0) {
            if (!"medical".equals(value(merchant(principal.merchantId()).get("merchantTypeCode"), ""))) {
                throw new BusinessException(ErrorCode.BAD_REQUEST, "商品金额必须大于0");
            }
            salePrice = BigDecimal.ZERO;
        }
        String images = jsonArray(request.productImages() == null ? List.of() : request.productImages());
        Map<String, String> notice = new LinkedHashMap<>();
        for (String field : NOTICE_FIELDS) notice.put(field, request.purchaseNotice() == null ? "" : value(request.purchaseNotice().get(field), ""));
@@ -133,7 +151,7 @@
                set product_name = ?, sale_price = ?, cover_url = ?, product_images = ?, detail_text = ?, purchase_notice = ?,
                    audit_status = 1, status = 0, submit_time = now(), audit_remark = null
                where id = ? and merchant_id = ? and deleted = 0
                """, request.productName().trim(), request.salePrice(), coverUrl, images,
                """, request.productName().trim(), salePrice, coverUrl, images,
                value(request.detailText(), ""), jsonObject(notice), productId, principal.merchantId());
        appendProductAuditRecord(productId);
        return product(principal, productId);
@@ -283,7 +301,7 @@
    private Map<String, Object> merchant(Long merchantId) {
        List<Map<String, Object>> merchants = rows("""
                select id, merchant_name, address, cover_url, business_status, status, updated_at
                select id, merchant_name, merchant_type_code, address, cover_url, business_status, status, updated_at
                from merchant where id = ? and deleted = 0
                """, merchantId);
        if (merchants.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "商户不存在");