| | |
| | | |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.ArrayList; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.TypeReference; |
| | | import com.talentcard.server.business.BusinessIdGenerator; |
| | | import com.talentcard.server.business.DatabaseRows; |
| | | import com.talentcard.server.common.BusinessException; |
| | |
| | | } |
| | | |
| | | @Transactional(readOnly = true) |
| | | public Map<String, Object> detail(Long merchantId) { |
| | | public Map<String, Object> detail(Long merchantId, Long talentCardId) { |
| | | Map<String, Object> merchant = fuelMerchant(merchantId); |
| | | Map<String, Object> benefit = one(""" |
| | | select id, talent_levels, discount_text, oil_types, single_limit_text, annual_limit_text, |
| | |
| | | where merchant_id = ? and deleted = 0 |
| | | order by id asc limit 1 |
| | | """, merchantId); |
| | | String cardLevel = talentCardId == null ? "" : talentCardLevel(talentCardId); |
| | | String sourceAreaType = talentCardId == null ? "" : talentSourceAreaType(talentCardId); |
| | | Map<String, Object> right = matchingRight(parseRights(merchant.get("merchantRightsConfig")), cardLevel, sourceAreaType); |
| | | boolean available = number(merchant.get("status")) == 1 && number(benefit.get("status")) == 1; |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | result.put("merchantId", merchant.get("id")); |
| | |
| | | result.put("available", available); |
| | | result.put("serviceLabel", text(merchant.get("serviceLabel"), "请咨询商户")); |
| | | result.put("discountText", text(benefit.get("discountText"), "请咨询商户")); |
| | | result.put("applicableCards", text(benefit.get("talentLevels"), "请咨询商户")); |
| | | result.put("rightsTag", text(right == null ? null : right.get("tag"), "")); |
| | | result.put("applicableCards", text(right == null ? null : right.get("tag"), text(benefit.get("talentLevels"), "请咨询商户"))); |
| | | result.put("groupBuyingEnabled", false); |
| | | result.put("usageInstructions", text(benefit.get("usageInstructions"), "请咨询商户")); |
| | | result.put("rightsText", text(benefit.get("ruleText"), "请咨询商户")); |
| | | String configuredDetail = text(right == null ? null : right.get("detail"), ""); |
| | | result.put("usageInstructions", text(configuredDetail, text(benefit.get("usageInstructions"), "请咨询商户"))); |
| | | result.put("rightsText", text(configuredDetail, text(benefit.get("ruleText"), "请咨询商户"))); |
| | | result.put("benefit", benefitView(benefit)); |
| | | result.put("heroImages", query(""" |
| | | select id, image_url, sort_no |
| | |
| | | |
| | | private Map<String, Object> fuelMerchant(Long merchantId) { |
| | | return one(""" |
| | | select id, merchant_name, merchant_type_code as merchant_type, contact_mobile, address, cover_url, service_label, status, latitude, longitude |
| | | select id, merchant_name, merchant_type_code as merchant_type, contact_mobile, address, cover_url, service_label, |
| | | merchant_rights_config, status, latitude, longitude |
| | | from merchant |
| | | where id = ? and merchant_type_code = 'fuel' and deleted = 0 |
| | | """, merchantId); |
| | | } |
| | | |
| | | private Map<String, Object> matchingRight(List<Map<String, Object>> rights, String cardLevel, String sourceAreaType) { |
| | | if (rights.isEmpty() || cardLevel.isBlank()) return null; |
| | | for (String candidate : rightCandidates(cardLevel, sourceAreaType)) { |
| | | for (Map<String, Object> right : rights) { |
| | | if (booleanValue(right.get("enabled")) && candidate.equals(text(right.get("level"), ""))) return right; |
| | | } |
| | | } |
| | | String level = normalizedCardLevel(cardLevel); |
| | | for (Map<String, Object> right : rights) { |
| | | if (!booleanValue(right.get("enabled"))) continue; |
| | | if (!level.equals(normalizedCardLevel(text(right.get("level"), "")))) continue; |
| | | if (!"EXCELLENT".equals(level) || !areaSpecificExcellentLevel(text(right.get("level"), ""))) return right; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private List<String> rightCandidates(String cardLevel, String sourceAreaType) { |
| | | String level = normalizedCardLevel(cardLevel); |
| | | if (!"EXCELLENT".equals(level)) return List.of(cardLevel); |
| | | String area = text(sourceAreaType, "").toUpperCase(Locale.ROOT); |
| | | if (area.contains("LOCAL") || area.contains("本地")) return List.of("卓越人才卡(本地)", "卓越人才卡"); |
| | | if (area.contains("OUTSIDE") || area.contains("外地")) return List.of("卓越人才卡(外地)", "卓越人才卡"); |
| | | return List.of("卓越人才卡"); |
| | | } |
| | | |
| | | private boolean areaSpecificExcellentLevel(String level) { |
| | | String value = text(level, "").toUpperCase(Locale.ROOT); |
| | | return value.contains("LOCAL") || value.contains("OUTSIDE") || value.contains("本地") || value.contains("外地"); |
| | | } |
| | | |
| | | private List<Map<String, Object>> parseRights(Object value) { |
| | | if (value instanceof List<?> list) { |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (Object item : list) if (item instanceof Map<?, ?> map) result.add(copyMap(map)); |
| | | return result; |
| | | } |
| | | String raw = text(value, ""); |
| | | if (raw.isBlank()) return List.of(); |
| | | try { |
| | | List<Map<String, Object>> parsed = JSON.parseObject(raw, new TypeReference<List<Map<String, Object>>>() {}); |
| | | return parsed == null ? List.of() : parsed.stream().map(this::copyMap).toList(); |
| | | } catch (Exception ignored) { |
| | | return List.of(); |
| | | } |
| | | } |
| | | |
| | | private Map<String, Object> copyMap(Map<?, ?> source) { |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | for (Map.Entry<?, ?> entry : source.entrySet()) result.put(String.valueOf(entry.getKey()), entry.getValue()); |
| | | return result; |
| | | } |
| | | |
| | | private String talentCardLevel(Long talentCardId) { |
| | | List<Map<String, Object>> cards = query("select card_level from talent_card where id = ? and deleted = 0 limit 1", talentCardId); |
| | | return cards.isEmpty() ? "" : text(cards.get(0).get("cardLevel"), ""); |
| | | } |
| | | |
| | | private String talentSourceAreaType(Long talentCardId) { |
| | | List<Map<String, Object>> cards = query(""" |
| | | select u.source_area_type |
| | | from talent_card c join talent_user u on u.id = c.talent_id and u.deleted = 0 |
| | | where c.id = ? and c.deleted = 0 |
| | | limit 1 |
| | | """, talentCardId); |
| | | return cards.isEmpty() ? "" : text(cards.get(0).get("sourceAreaType"), ""); |
| | | } |
| | | |
| | | private String normalizedCardLevel(String value) { |
| | | String raw = text(value, ""); |
| | | String upper = raw.toUpperCase(Locale.ROOT); |
| | | if (upper.contains("EXCELLENT") || raw.contains("卓越")) return "EXCELLENT"; |
| | | if (upper.contains("OUTSTANDING") || raw.contains("杰出")) return "OUTSTANDING"; |
| | | if (upper.contains("ELITE") || raw.contains("菁英") || raw.contains("精英")) return "ELITE"; |
| | | return upper; |
| | | } |
| | | |
| | | private boolean booleanValue(Object value) { |
| | | if (value instanceof Boolean bool) return bool; |
| | | if (value instanceof Number number) return number.intValue() != 0; |
| | | String text = text(value, "").toLowerCase(Locale.ROOT); |
| | | return "true".equals(text) || "1".equals(text) || "yes".equals(text); |
| | | } |
| | | |
| | | private Map<String, Object> benefitView(Map<String, Object> benefit) { |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | result.put("benefitId", benefit.get("id")); |