shinnosuke
2026-08-31 cb5a42c97fe9ae23b891bdc3231dc8eb100de218
talent-card-server/src/main/java/com/talentcard/server/business/portal/PortalService.java
@@ -49,7 +49,7 @@
            select id, title, summary, cover_url, source, view_count, is_top, publish_time
            from news_article
            where deleted = 0 and status = 1
            order by is_top desc, case when is_top = 1 then top_time end desc, publish_time desc, id desc
            order by is_top desc, case when is_top = 1 then updated_at end desc, publish_time desc, id desc
            limit 4
            """));
      result.put("policies", query("""
@@ -99,7 +99,7 @@
            select id, title, summary, cover_url, source, content, view_count, is_top, publish_time
            from news_article
            where deleted = 0 and status = 1
            order by is_top desc, case when is_top = 1 then top_time end desc, publish_time desc, id desc
            order by is_top desc, case when is_top = 1 then updated_at end desc, publish_time desc, id desc
            """, "select count(*) from news_article where deleted = 0 and status = 1", page, size);
      List<Map<String, Object>> records = result.records().stream().map(row -> {
         Map<String, Object> item = new LinkedHashMap<>(row);
@@ -525,7 +525,7 @@
   }
   @Transactional(readOnly = true)
   public PageResult<Map<String, Object>> transportMerchants(String type, int page, int size) {
   public PageResult<Map<String, Object>> transportMerchants(String type, int page, int size, Long talentId) {
      String requestedType = MerchantTypeCatalog.canonicalCode(type);
      if (!List.of("fuel", "parking", "carWash").contains(requestedType)) {
         throw new BusinessException(ErrorCode.BAD_REQUEST, "不支持的行服务类型");
@@ -539,12 +539,21 @@
            from merchant
            """ + merchantWhere + " order by sort_no asc, id asc",
            "select count(*) from merchant" + merchantWhere, page, size);
      String cardLevel = "carWash".equals(requestedType) ? activeProductCardLevel(talentId) : null;
      String sourceAreaType = "carWash".equals(requestedType) ? activeTalentSourceAreaType(talentId) : "";
      List<Map<String, Object>> records = result.records().stream().map(row -> {
         Map<String, Object> item = enrichMerchantSearchRow(row);
         item.put("merchantType", requestedType);
         item.put("discountText", textOrDefault(item.get("serviceLabel"), textOrDefault(item.get("discountText"), "人才专享")));
         if ("carWash".equals(requestedType)) {
            item.put("externalLinkType", carWashExternalLinkType(item.get("merchantRightsConfig")));
            List<Map<String, Object>> rights = merchantRightsConfigs(item.get("merchantRightsConfig"));
            String externalLinkType = carWashExternalLinkType(rights);
            Map<String, Object> right = matchingMerchantRight(rights, cardLevel, sourceAreaType, true);
            String discountText = carWashListDiscountText(externalLinkType, right);
            item.put("externalLinkType", externalLinkType);
            item.put("discountText", discountText);
            item.put("benefitTagVisible", !discountText.isBlank());
         } else {
            item.put("discountText", textOrDefault(item.get("serviceLabel"), textOrDefault(item.get("discountText"), "人才专享")));
         }
         item.remove("merchantRightsConfig");
         return item;
@@ -920,8 +929,8 @@
      }
   }
   private String carWashExternalLinkType(Object rightsConfig) {
      for (Map<String, Object> right : merchantRightsConfigs(rightsConfig)) {
   private String carWashExternalLinkType(List<Map<String, Object>> rights) {
      for (Map<String, Object> right : rights) {
         if (right.containsKey("externalLinkType")
               || right.containsKey("externalMiniProgramShortLink")
               || right.containsKey("externalMiniProgramPath")
@@ -932,6 +941,11 @@
      return "";
   }
   private String carWashListDiscountText(String externalLinkType, Map<String, Object> right) {
      if ("miniProgram".equals(externalLinkType) || right == null) return "";
      return merchantRightDiscountText(right);
   }
   private boolean booleanValue(Object value) {
      if (value instanceof Boolean bool) return bool;
      if (value instanceof Number number) return number.intValue() != 0;