shinnosuke
2026-08-24 389777ce425036ffe0e342272d1d566b82f7fb13
又又更新
3个文件已修改
64 ■■■■■ 已修改文件
rencaika/pages/merchant/merchant.uvue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rencaika_merchant/pages/withdrawal-detail/withdrawal-detail.uvue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-admin/src/views/ProductAuditDetailView.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rencaika/pages/merchant/merchant.uvue
@@ -93,10 +93,7 @@
                </view>
                <view v-else-if="!merchantError && isMedicalMerchant" class="medical-usage-panel"><text>{{merchantRightsText}}</text></view>
                <view v-else-if="!merchantError" class="rights-panel">
                    <text class="rights-title">人才卡专属权益</text>
                    <text class="rights-text">{{merchantRightsText}}</text>
                    <view class="rule-row"><text>适用卡种</text><text>{{applicableCards}}</text></view>
                    <view class="rule-row"><text>使用方式</text><text>到店出示人才码</text></view>
                </view>
            </view>
            <view class="content-bottom"></view>
@@ -262,26 +259,41 @@
    const parseRightsConfig = (value: any): any[] => {
        if (value == null || value == '') return []
        if (value instanceof Array) return value as any[]
        if (value.rights instanceof Array) return value.rights as any[]
        if (value.items instanceof Array) return value.items as any[]
        const text = '' + value
        if (text.trim() == '') return []
        try {
            const parsed = JSON.parse(text)
            return parsed instanceof Array ? parsed as any[] : []
            if (parsed instanceof Array) return parsed as any[]
            if (parsed != null && parsed.rights instanceof Array) return parsed.rights as any[]
            if (parsed != null && parsed.items instanceof Array) return parsed.items as any[]
            return []
        } catch (error) {
            return []
        }
    }
    const rightLevel = (right: any): any => right != null && right.level != null ? right.level : (right != null && right.cardLevel != null ? right.cardLevel : (right != null ? right.card_level : null))
    const rightDetail = (right: any): any => {
        if (right == null) return ''
        if (right.detail != null && right.detail != '') return right.detail
        if (right.benefitDetail != null && right.benefitDetail != '') return right.benefitDetail
        if (right.rightsText != null && right.rightsText != '') return right.rightsText
        if (right.benefit_text != null && right.benefit_text != '') return right.benefit_text
        return ''
    }
    const applyMedicalRightsConfig = (data: any) => {
        if (!isMedicalMerchant.value) return
        if (data != null && data.cardLevel != null && data.cardLevel != '') currentCardLevel.value = data.cardLevel as string
        const cardLevel = currentCardLevel.value
        if (cardLevel == '') return
        const rights = parseRightsConfig(data != null ? data.merchantRightsConfig : null)
        // Use the configured detail for every merchant type; keep the API fallback when absent.
        if (!isMedicalMerchant.value && rights.length == 0) return
        if (cardLevel == '') return
        let matched: any = null
        let disabledMatched: any = null
        for (let index = 0; index < rights.length; index++) {
            const item: any = rights[index]
            if (!sameCardLevel(item != null ? item.level : '', cardLevel)) continue
            if (!sameCardLevel(rightLevel(item), cardLevel)) continue
            if (isRightEnabled(item != null ? item.enabled : null)) {
                matched = item
                break
@@ -291,7 +303,10 @@
        if (matched != null) {
            const tag = matched.tag != null && matched.tag != '' ? matched.tag as string : cardLevel
            if (tag != '') applicableCards.value = tag
            merchantRightsText.value = matched.detail != null && matched.detail != '' ? matched.detail as string : (data != null && data.rightsText != null && data.rightsText != '' ? data.rightsText as string : '请咨询商户')
            const configuredDetail = rightDetail(matched)
            merchantRightsText.value = configuredDetail != null && configuredDetail != ''
                ? configuredDetail as string
                : (data != null && data.rightsText != null && data.rightsText != '' ? data.rightsText as string : '请咨询商户')
            return
        }
        if (rights.length > 0) {
@@ -940,10 +955,7 @@
    .buy-button { display: flex; width: 132rpx; height: 57rpx; border-radius: 29rpx; background-image: linear-gradient(90deg, #FF5733 0%, #FF8A20 100%); justify-content: center; align-items: center; }
    .buy-button text { color: #FFFFFF; font-size: 27rpx; }
    .rights-panel { margin: 16rpx 25rpx 0; padding: 28rpx 26rpx; border-radius: 15rpx; background-color: #FFFFFF; }
    .rights-title { display: block; color: #303030; font-size: 32rpx; font-weight: 700; }
    .rights-text { display: block; margin-top: 18rpx; color: #777F8B; font-size: 27rpx; line-height: 43rpx; }
    .rule-row { display: flex; min-height: 70rpx; margin-top: 9rpx; border-top-width: 1rpx; border-top-style: solid; border-top-color: #F0F0F0; flex-direction: row; align-items: center; justify-content: space-between; color: #7D838C; font-size: 26rpx; }
    .rule-row text:last-child { color: #3C424A; }
    .rights-text { display: block; margin-top: 0; color: #777F8B; font-size: 27rpx; line-height: 43rpx; }
    .store-panel { margin: 16rpx 25rpx 0; overflow: hidden; border-width: 2rpx; border-style: solid; border-color: #DCE7FA; border-radius: 16rpx; background-color: #FFFFFF; }
    .store-table-header { display: flex; min-height: 67rpx; background-color: #EEF4FF; flex-direction: row; align-items: center; }
    .store-head-name, .store-head-address { display: flex; height: 67rpx; box-sizing: border-box; padding: 0 13rpx; justify-content: flex-start; align-items: center; }
rencaika_merchant/pages/withdrawal-detail/withdrawal-detail.uvue
@@ -86,11 +86,11 @@
    .available-value { margin: 2rpx 0 0; color: #E87535; font-size: 30rpx; line-height: 42rpx; }
    .form-card { padding: 54rpx 28rpx 34rpx; border-radius: 28rpx; }
    .amount-field-row { min-height: 0; flex-direction: column; align-items: stretch; }
    .amount-field-row .field-label { width: auto; margin-bottom: 10rpx; text-align: center; color: #273345; font-size: 30rpx; line-height: 42rpx; font-weight: 700; }
    .amount-input-shell { width: 100%; height: 160rpx; padding: 10rpx 18rpx 0; flex: none; flex-direction: column; align-items: center; box-sizing: border-box; }
    .amount-prefix { line-height: 34rpx; }
    .amount-input { width: 100%; height: 100rpx; margin: 0; flex: none; text-align: center; }
    .input-placeholder { text-align: center; }
    .amount-field-row .field-label { width: auto; margin-bottom: 10rpx; text-align: left; color: #273345; font-size: 30rpx; line-height: 42rpx; font-weight: 700; }
    .amount-input-shell { width: 100%; height: 160rpx; padding: 0 28rpx; flex: none; flex-direction: row; align-items: center; justify-content: flex-start; box-sizing: border-box; }
    .amount-prefix { line-height: 68rpx; }
    .amount-input { width: 100%; height: 68rpx; margin: 0 0 0 8rpx; flex: 1; text-align: left; }
    .input-placeholder { text-align: left; }
    .field-divider { display: none; }
    .bank-field-block { margin-top: 56rpx; }
    .bank-field-row { min-height: 0; flex-direction: column; align-items: flex-start; }
talent-card-admin/src/views/ProductAuditDetailView.vue
@@ -54,8 +54,22 @@
  return merchantType === '酒店服务' || merchantType === '酒店'
})
const hideTalentBenefitPanel = computed(() => {
  const merchantType = String(product.value?.merchantType || '').trim().toLowerCase()
  return ['酒店服务', '酒店', '医院服务', '医院', '医疗服务', '医疗', 'hotel', 'hospital', 'medical', 'health_check'].includes(merchantType)
  const productData = product.value as (Product & Record<string, unknown>) | undefined
  const merchantTypes = [
    productData?.merchantType,
    productData?.merchantTypeCode,
    productData?.merchant_type,
    productData?.merchant_type_code,
  ]
    .map(value => String(value || '').trim().toLowerCase().replace(/[\s_-]+/g, ''))
    .filter(Boolean)
  const productType = String(productData?.productType || '').trim().toLowerCase().replace(/[\s_-]+/g, '')
  const hiddenTypes = [
    '酒店服务', '酒店', 'hotel',
    '医院服务', '医院', '医疗服务', '医疗', '免费体检', '体检服务', '医疗体检',
    'hospital', 'medical', 'healthcheck', 'medicalservice',
  ]
  return merchantTypes.some(type => hiddenTypes.includes(type)) || ['hotel', 'hospital', 'medical', 'healthcheck'].includes(productType)
})
const productAmountText = computed(() => {
  const salePrice = product.value?.salePrice