shinnosuke
2026-08-25 b5d2d9e2b08d45050c418f9713e709589c23491e
fix: align parking benefit actions by card level
2个文件已修改
33 ■■■■■ 已修改文件
rencaika/pages/merchant/merchant.uvue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/java/com/talentcard/server/business/portal/ParkingMerchantPortalService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rencaika/pages/merchant/merchant.uvue
@@ -140,7 +140,7 @@
    const isFuelMerchant = ref(false)
    const isParkingMerchant = ref(false)
    const isMedicalMerchant = ref(false)
    // 后台停车权益配置:plate=填写车牌,talentCode=出示人才码。
    // 当前人才等级的停车权益:免费填写车牌,付费出示人才码。
    const parkingActionMode = ref('plate')
    // 后台车牌表单配置:withParking=需搜索停车场,simple=仅填写车牌。
    const parkingPlateMode = ref('simple')
@@ -552,7 +552,7 @@
                ? parkingRightDetail
                : (data != null && data.rightsText != null && data.rightsText != '' ? data.rightsText as string : '请咨询商户')
            merchantRightsText.value = data != null && data.rightsText != null ? data.rightsText as string : '请咨询商户'
            parkingActionMode.value = data != null && (data.actionMode == 'talentCode' || data.parkingType == 'paid') ? 'talentCode' : 'plate'
            parkingActionMode.value = data != null && data.parkingType == 'paid' ? 'talentCode' : 'plate'
            parkingPlateMode.value = data != null && data.plateFormMode == 'withParking' ? 'withParking' : 'simple'
            parkingBenefitId.value = data != null && data.benefit != null && data.benefit.benefitId != null ? '' + data.benefit.benefitId : ''
            groupBuyingEnabled.value = false
talent-card-server/src/main/java/com/talentcard/server/business/portal/ParkingMerchantPortalService.java
@@ -55,8 +55,8 @@
        result.put("usageInstructions", usageInstructions(merchant, right));
        result.put("rightsText", rightsText(merchant, right));
        String parkingType = text(right == null ? null : right.get("parkingType"), "paid");
        // 付费停车权益按到店消费规则使用,前端展示使用说明并出示人才码。
        result.put("actionMode", "paid".equalsIgnoreCase(parkingType) || "free".equalsIgnoreCase(parkingType) ? "talentCode" : "plate");
        // 付费权益到店出示人才码,免费权益先登记车牌。
        result.put("actionMode", "paid".equalsIgnoreCase(parkingType) ? "talentCode" : "plate");
        result.put("plateFormMode", text(benefit.get("plateFormMode"), "simple"));
        result.put("benefit", benefitView(benefit));
        result.put("applicableStores", parkingStores(merchant.get("usageInstructions")));
@@ -107,15 +107,23 @@
                where id = ? and merchant_id = ? and deleted = 0
                """, request.benefitId(), merchantId);
        if (number(benefit.get("status")) != 1) throw new BusinessException(ErrorCode.CONFLICT, "停车权益当前不可用");
        if (!"plate".equals(benefit.get("actionMode"))) throw new BusinessException(ErrorCode.CONFLICT, "当前停车权益无需登记车牌");
        Map<String, Object> card = activeTalentCard(request.talentId());
        String cardLevel = text(card.get("cardLevel"), "");
        Map<String, Object> right = mergeRight(
                matchingRight(parseList(merchant.get("merchantRightsConfig")), cardLevel),
                parkingCardLevelRight(merchantId, cardLevel));
        if (right == null || !booleanValue(right.get("enabled")) || !rightStatusEnabled(right)) {
            throw new BusinessException(ErrorCode.CONFLICT, "当前人才卡暂无可用停车权益");
        }
        if (!"free".equalsIgnoreCase(text(right.get("parkingType"), "paid"))) {
            throw new BusinessException(ErrorCode.CONFLICT, "付费停车权益无需登记车牌");
        }
        if ("withParking".equals(benefit.get("plateFormMode"))) {
            if (request.parkingLotId() == null) throw new BusinessException(ErrorCode.BAD_REQUEST, "请选择停车场");
            boolean matchedLot = parkingStores(merchant.get("usageInstructions")).stream()
                    .anyMatch(item -> String.valueOf(request.parkingLotId()).equals(String.valueOf(item.get("id"))));
            if (!matchedLot) throw new BusinessException(ErrorCode.BAD_REQUEST, "停车场不可用");
        }
        Integer talentCount = jdbc.queryForObject("select count(*) from talent_user where id = ? and deleted = 0", Integer.class, request.talentId());
        if (talentCount == null || talentCount == 0) throw new BusinessException(ErrorCode.NOT_FOUND, "人才用户不存在");
        Integer duplicateCount = jdbc.queryForObject("""
                select count(*) from transport_parking_plate_registration
                where merchant_id = ? and talent_id = ? and plate_number = ? and deleted = 0
@@ -311,6 +319,17 @@
        return rows.isEmpty() ? "" : text(rows.get(0).get("cardLevel"), "");
    }
    private Map<String, Object> activeTalentCard(Long talentId) {
        List<Map<String, Object>> rows = query("""
                select id, card_level
                from talent_card
                where talent_id = ? and card_type = 'PERSONAL' and status = 1 and deleted = 0
                order by id desc limit 1
                """, talentId);
        if (rows.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "人才用户或有效人才卡不存在");
        return rows.get(0);
    }
    private String normalizedCardLevel(String value) {
        String raw = value == null ? "" : value.trim();
        String upper = raw.toUpperCase(Locale.ROOT);