shinnosuke
2026-08-27 b0edd6c4bd7912e706ef3af5a221caf0d6c78fac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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<String, Object> detail(Long merchantId) {
        return detail(merchantId, null);
    }
 
    @Transactional(readOnly = true)
    public Map<String, Object> detail(Long merchantId, Long talentId) {
        Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> advisor = accountAdvisor(talentId);
        result.put("advisor", advisor);
        return result;
    }
 
    private Map<String, Object> 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<String, Object> 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<String, Object> one(String sql, Object... args) {
        List<Map<String, Object>> 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;
    }
}