package com.talentcard.server.business.portal; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.talentcard.server.business.DatabaseRows; import com.talentcard.server.common.BusinessException; import com.talentcard.server.common.ErrorCode; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class ShoppingMerchantPortalService { private final JdbcTemplate jdbc; private final PortalService portalService; private final TalentCardPortalService talentCardPortalService; public ShoppingMerchantPortalService( JdbcTemplate jdbc, PortalService portalService, TalentCardPortalService talentCardPortalService ) { this.jdbc = jdbc; this.portalService = portalService; this.talentCardPortalService = talentCardPortalService; } @Transactional(readOnly = true) public Map detail(Long merchantId) { return detail(merchantId, null); } @Transactional(readOnly = true) public Map detail(Long merchantId, Long talentId) { Map row = one(""" select m.id, m.merchant_name, m.cover_url, m.service_label, m.address, m.contact_mobile, m.contact_name, m.rights_text, m.longitude, m.latitude, m.status as merchant_status, case m.merchant_type_code when 'housing' then 'housing' when 'car' then 'car' when 'appliance' then 'appliance' when 'digital' then 'digital' when 'culture' then 'book' when 'telecom' then 'telecom' end as category_key, detail_config.benefit_detail, detail_config.advisor_id, detail_config.advisor_name, detail_config.advisor_department, detail_config.advisor_mobile, detail_config.advisor_service_time, detail_config.advisor_available, detail_config.unavailable_reason, detail_config.status as detail_status from merchant m left join shopping_service_detail detail_config on detail_config.merchant_id = m.id and detail_config.deleted = 0 where m.id = ? and m.merchant_type_code in ('shopping', 'housing', 'car', 'appliance', 'digital', 'culture', 'telecom') and m.deleted = 0 order by detail_config.id asc limit 1 """, merchantId); Map configuredMerchant = portalService.merchantDetail(merchantId, talentId); String rightsStatus = text(configuredMerchant.get("rightsStatus"), "UNCONFIGURED"); boolean rightsAvailable = !"DISABLED".equals(rightsStatus) && !"MISSING".equals(rightsStatus); boolean available = number(row.get("merchantStatus")) == 1 && (row.get("detailStatus") == null || number(row.get("detailStatus")) == 1) && rightsAvailable; Map result = new LinkedHashMap<>(); result.put("merchantId", row.get("id")); result.put("categoryId", row.get("categoryKey")); result.put("merchantName", row.get("merchantName")); result.put("coverUrl", row.get("coverUrl")); result.put("discountText", text(row.get("serviceLabel"), "")); result.put("applicableCards", text(configuredMerchant.get("applicableCards"), text(configuredMerchant.get("rightsTag"), ""))); result.put("address", text(row.get("address"), "")); result.put("contactMobile", text(row.get("contactMobile"), "")); result.put("longitude", row.get("longitude")); result.put("latitude", row.get("latitude")); result.put("benefitDetail", text(configuredMerchant.get("rightsText"), text(row.get("benefitDetail"), text(row.get("rightsText"), "")))); result.put("rightsStatus", rightsStatus); result.put("available", available); String unavailableReason = switch (rightsStatus) { case "DISABLED" -> "当前人才卡暂未开通该权益"; case "MISSING" -> "当前人才卡暂未配置该权益"; default -> text(row.get("unavailableReason"), "该购物服务当前不可用"); }; result.put("unavailableReason", available ? "" : unavailableReason); Map advisor = accountAdvisor(talentId); result.put("advisor", advisor); return result; } private Map accountAdvisor(Long talentId) { if (talentId == null) return Map.of("available", false); Object source = talentCardPortalService.profile(talentId).get("advisor"); if (!(source instanceof Map sourceAdvisor)) return Map.of("available", false); Map advisor = new LinkedHashMap<>(); sourceAdvisor.forEach((key, value) -> advisor.put(String.valueOf(key), value)); advisor.put("available", !text(advisor.get("mobile"), "").isEmpty()); return advisor; } private Map one(String sql, Object... args) { List> rows = jdbc.queryForList(sql, args).stream().map(DatabaseRows::normalize).toList(); if (rows.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "购物服务详情不存在"); return rows.get(0); } private int number(Object value) { return value instanceof Number number ? number.intValue() : 0; } private String text(Object value, String fallback) { if (value == null) return fallback; String text = String.valueOf(value).trim(); return text.isEmpty() ? fallback : text; } }