shinnosuke
2026-08-24 cb14410caa219227eaf574040a0145bda4ec253c
fix: align hotel detail benefit display
2个文件已修改
55 ■■■■■ 已修改文件
rencaika/pages/merchant/merchant.uvue 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/java/com/talentcard/server/business/portal/PortalService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rencaika/pages/merchant/merchant.uvue
@@ -33,7 +33,7 @@
                    </view>
                    <view v-else class="merchant-title-row">
                        <text class="merchant-title">{{merchantName}}</text>
                        <view class="merchant-tags"><text v-if="merchantHasCoupon" class="coupon-tag">券</text><text v-if="merchantDiscount != ''" class="discount-tag">{{merchantDiscount}}</text></view>
                        <view class="merchant-tags"><text v-if="!isHotelMerchant && merchantHasCoupon" class="coupon-tag">券</text><text v-if="merchantDiscount != ''" class="discount-tag">{{merchantDiscount}}</text><text v-if="isHotelMerchant && merchantConsumeDiscount != ''" class="discount-tag">{{merchantConsumeDiscount}}</text></view>
                    </view>
                    <view class="service-tags"><text v-if="!isParkingMerchant && !isMedicalMerchant">{{merchantServiceLabel}}</text><text>{{applicableCards}}</text></view>
                    <view v-if="!isParkingMerchant && merchantType != 'apartment'" class="merchant-address-row">
@@ -73,7 +73,7 @@
                            <image class="package-image" :src="item.image" mode="aspectFill" @error="replaceImage(item)"></image>
                            <view class="package-info">
                                <text class="package-name">{{item.name}}</text>
                                <view class="package-tags"><text v-if="merchantHasCoupon" class="coupon-tag">券</text><text v-if="merchantDiscount != ''" class="discount-tag">{{merchantDiscount}}</text></view>
                                <view class="package-tags"><text v-if="!isHotelMerchant && merchantHasCoupon" class="coupon-tag">券</text><text v-if="merchantDiscount != ''" class="discount-tag">{{merchantDiscount}}</text><text v-if="isHotelMerchant && merchantConsumeDiscount != ''" class="discount-tag">{{merchantConsumeDiscount}}</text></view>
                                <view class="package-bottom"><view class="price-row"><text class="price-symbol">¥</text><text class="price">{{item.price}}</text><text v-if="!isHotelMerchant" class="old-price">¥{{item.originalPrice}}</text></view><view class="buy-button"><text>{{item.available === false ? '已售罄' : (isHotelMerchant ? '预约' : '购买')}}</text></view></view>
                            </view>
                        </view>
@@ -173,6 +173,15 @@
    const merchantPrimaryTag = ref('')
    const merchantHasCoupon = ref(false)
    const merchantDiscount = ref('')
    const merchantConsumeDiscount = ref('')
    const normalizeHotelCardLabel = (value: string): string => {
        let label = value.trim()
        const separator = label.indexOf('|')
        if (separator >= 0) label = label.substring(0, separator).trim()
        label = label.replace('(外地)', '').replace('(本地)', '').trim()
        if (label == '') return ''
        return label.endsWith('可用') ? label : label + '可用'
    }
    const merchantAddress = ref('四川省攀枝花市东区炳三区新福路20号中环天地负一层')
    const merchantServiceLabel = ref('到店消费')
    const applicableCards = ref('卓越卡可用')
@@ -374,6 +383,7 @@
                merchantName.value = name
                merchantHero.value = routedImage
                merchantDiscount.value = routedDiscount
                merchantConsumeDiscount.value = ''
                hasFreeVoucher.value = false
                merchantPrimaryTag.value = '惠'
                merchantAddress.value = routedAddress == '' ? '西区清香坪北街51号' : routedAddress
@@ -593,10 +603,23 @@
                ? true
                : (data == null || data.groupBuyingEnabled == null ? groupBuyingEnabled.value : data.groupBuyingEnabled === true || Number(data.groupBuyingEnabled) == 1)
            isHotelMerchant.value = merchantType.value == 'hotel'
            merchantConsumeDiscount.value = ''
            if (isHotelMerchant.value) {
                const configuredServiceLabel = data != null && data.serviceLabel != null ? String(data.serviceLabel) : ''
                const configuredCardTag = data != null && data.applicableCards != null ? String(data.applicableCards) : ''
                const hasStoreConsumeTag = configuredCardTag.indexOf('到店消费') >= 0
                const hotelStoreConsume = (data != null && (data.storeConsume === true || Number(data.storeConsume) == 1) && (data.consumeEnabled === true || Number(data.consumeEnabled) == 1)) || configuredServiceLabel.indexOf('到店') >= 0 || hasStoreConsumeTag
                merchantServiceLabel.value = hotelStoreConsume ? '到店消费' : '住宿服务'
                const normalizedCardLabel = normalizeHotelCardLabel(configuredCardTag)
                if (normalizedCardLabel != '') applicableCards.value = normalizedCardLabel
                const consumeType = data != null && data.consumeType != null ? String(data.consumeType) : ''
                const consumeDiscount = data != null && data.consumeDiscount != null ? String(data.consumeDiscount).trim() : ''
                merchantConsumeDiscount.value = consumeType == '折扣' && consumeDiscount != '' ? consumeDiscount + '折' : ''
            }
            hasFreeVoucher.value = isHotelMerchant.value && data != null && data.rightsStatus != null && String(data.rightsStatus) == 'AVAILABLE' && (data.freeVoucherEnabled === true || Number(data.freeVoucherEnabled) == 1)
            if (hasFreeVoucher.value) {
                const freeVoucherTimes = data != null && data.freeVoucherTimes != null ? String(data.freeVoucherTimes).trim() : ''
                merchantDiscount.value = freeVoucherTimes != '' ? freeVoucherTimes + '次' : '免费'
                merchantDiscount.value = freeVoucherTimes != '' ? '免费' + freeVoucherTimes + '次' : '免费'
                merchantPrimaryTag.value = '券'
            }
            if (isHotelMerchant.value && talentId.value != '' && talentCardId.value == '') {
@@ -652,8 +675,16 @@
                    const item: any = records[index]
                    const sale = item.salePrice != null ? Number(item.salePrice) : 0
                    const original = item.originalPrice != null ? Number(item.originalPrice) : 0
                    const configuredSale = item.configuredSalePrice != null ? Number(item.configuredSalePrice) : sale
                    const configuredOriginal = item.configuredOriginalPrice != null ? Number(item.configuredOriginalPrice) : original
                    const stock = item.stock != null ? Number(item.stock) : -1
                    remotePackages.push({ id: '' + item.id, name: item.productName != null ? item.productName as string : '人才专享套餐', discount: sale > 0 && original > sale ? '' + Math.round(sale / original * 100) / 10 + '折' : '人才专享', price: '' + sale, originalPrice: original > 0 ? '' + original : '', image: item.coverUrl != null && item.coverUrl != '' ? resolveApiUrl(item.coverUrl as string) : fallbackImage, available: stock != 0 })
                    let displayPrice = '' + sale
                    if (isHotelMerchant.value) {
                        const rangeMin = configuredSale > 0 ? configuredSale : configuredOriginal
                        const rangeMax = configuredOriginal > 0 ? configuredOriginal : rangeMin
                        displayPrice = rangeMin > 0 && rangeMax > 0 && rangeMin != rangeMax ? '' + rangeMin + '-' + rangeMax : '' + rangeMin
                    }
                    remotePackages.push({ id: '' + item.id, name: item.productName != null ? item.productName as string : '人才专享套餐', discount: sale > 0 && original > sale ? '' + Math.round(sale / original * 100) / 10 + '折' : '人才专享', price: displayPrice, originalPrice: original > 0 ? '' + original : '', image: item.coverUrl != null && item.coverUrl != '' ? resolveApiUrl(item.coverUrl as string) : fallbackImage, available: stock != 0 })
                }
                visiblePackages.value = remotePackages
                visibleMedicalPackages.value = []
talent-card-server/src/main/java/com/talentcard/server/business/portal/PortalService.java
@@ -663,6 +663,10 @@
        boolean freeVoucherEnabled = false;
        String freeVoucherTimes = "";
        String freeVoucherCycle = "";
        String consumeType = "";
        String consumeDiscount = "";
        boolean storeConsume = false;
        boolean consumeEnabled = false;
        merchant.put("rightsAvailable", configuredRight != null);
        if (configuredRight != null) {
            merchant.put("rightsTag", textOrDefault(configuredRight.get("tag"), ""));
@@ -672,6 +676,10 @@
            freeVoucherEnabled = booleanValue(configuredRight.get("freeVoucherEnabled"));
            freeVoucherTimes = textOrDefault(configuredRight.get("freeVoucherTimes"), "");
            freeVoucherCycle = textOrDefault(configuredRight.get("freeVoucherCycle"), "");
            consumeType = textOrDefault(configuredRight.get("consumeType"), "");
            consumeDiscount = textOrDefault(configuredRight.get("consumeDiscount"), "");
            storeConsume = booleanValue(configuredRight.get("storeConsume"));
            consumeEnabled = booleanValue(configuredRight.get("consumeEnabled"));
        } else if (levelRight != null) {
            merchant.put("rightsTag", textOrDefault(levelRight.get("tag"), ""));
            merchant.put("rightsText", "当前人才卡暂未开通该权益");
@@ -688,6 +696,10 @@
        merchant.put("freeVoucherEnabled", freeVoucherEnabled);
        merchant.put("freeVoucherTimes", freeVoucherTimes);
        merchant.put("freeVoucherCycle", freeVoucherCycle);
        merchant.put("consumeType", consumeType);
        merchant.put("consumeDiscount", consumeDiscount);
        merchant.put("storeConsume", storeConsume);
        merchant.put("consumeEnabled", consumeEnabled);
        merchant.put("usageInstructions", merchantUsageInstructions(
                id, merchant.get("merchantRightsConfig"), cardLevel, merchant.get("usageInstructions")));
        List<String> heroImages = new ArrayList<>();
@@ -1011,9 +1023,13 @@
        PageResult<Map<String, Object>> result = page(sql.toString(), countSql.toString(), page, size, args.toArray());
        List<Map<String, Object>> records = result.records().stream().map(product -> {
            Map<String, Object> item = new LinkedHashMap<>(product);
            BigDecimal configuredSalePrice = decimal(product.get("salePrice"));
            BigDecimal configuredOriginalPrice = decimal(product.get("originalPrice"));
            BigDecimal originalPrice = decimal(item.get("originalPrice"));
            if (originalPrice.signum() <= 0) originalPrice = decimal(item.get("salePrice"));
            BigDecimal personalizedPrice = personalizedProductPrice(item, talentId);
            item.put("configuredSalePrice", configuredSalePrice);
            item.put("configuredOriginalPrice", configuredOriginalPrice.signum() > 0 ? configuredOriginalPrice : originalPrice);
            item.put("originalPrice", originalPrice);
            item.put("salePrice", personalizedPrice);
            item.put("personalized", talentId != null && personalizedPrice.compareTo(decimal(product.get("salePrice"))) != 0);