From 71a0235a576f96adc37d62c1056fd74a593dc4fa Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期一, 24 八月 2026 14:12:27 +0800
Subject: [PATCH] feat: adapt fuel stores and medical product audit details

---
 talent-card-admin/src/views/ProductAuditDetailView.vue |   64 ++++++++++++++++++++++++++++++--
 1 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/talent-card-admin/src/views/ProductAuditDetailView.vue b/talent-card-admin/src/views/ProductAuditDetailView.vue
index 33c2b00..2439cfc 100644
--- a/talent-card-admin/src/views/ProductAuditDetailView.vue
+++ b/talent-card-admin/src/views/ProductAuditDetailView.vue
@@ -20,6 +20,12 @@
   subsidy: boolean
 }
 
+interface HealthCheckItem {
+  name: string
+  meaning: string
+  gender: string[]
+}
+
 type LegacyBenefitConfig =
   | { rows?: Array<Partial<BenefitRow> & { levelName?: string; governmentSubsidy?: boolean }> }
   | Array<Partial<BenefitRow>>
@@ -39,6 +45,7 @@
   availableTime: '',
   otherRules: '',
 })
+const healthCheckItems = ref<HealthCheckItem[]>([])
 
 const benefitRows = reactive<BenefitRow[]>([
   { level: '卓越人才卡', enabled: true, free: true, limitCount: '', discount: '', exceedDiscount: '', resetCycle: '每天', subsidy: true },
@@ -52,6 +59,20 @@
 const isHotelProduct = computed(() => {
   const merchantType = product.value?.merchantType || ''
   return merchantType === '酒店服务' || merchantType === '酒店'
+})
+const isHealthCheckProduct = computed(() => {
+  const productData = product.value as (Product & Record<string, unknown>) | undefined
+  const values = [
+    productData?.merchantType,
+    productData?.merchantTypeCode,
+    productData?.merchant_type,
+    productData?.merchant_type_code,
+    productData?.productType,
+  ].map(value => String(value || '').trim().toLowerCase().replace(/[\s_-]+/g, '')).filter(Boolean)
+  return values.some(value => [
+    '医院服务', '医院', '医疗服务', '医疗', '免费体检', '体检服务', '医疗体检',
+    'hospital', 'medical', 'healthcheck', 'medicalservice',
+  ].includes(value))
 })
 const hideTalentBenefitPanel = computed(() => {
   const productData = product.value as (Product & Record<string, unknown>) | undefined
@@ -72,12 +93,19 @@
   return merchantTypes.some(type => hiddenTypes.includes(type)) || ['hotel', 'hospital', 'medical', 'healthcheck'].includes(productType)
 })
 const productAmountText = computed(() => {
+  if (isHealthCheckProduct.value) return ''
   const salePrice = product.value?.salePrice
   const originalPrice = product.value?.originalPrice
   if (isHotelProduct.value && salePrice !== undefined && originalPrice !== undefined) {
     return `${amountText(salePrice)} - ${amountText(originalPrice)}`
   }
   return amountText(salePrice ?? originalPrice) || '158'
+})
+const healthCheckPeriodText = computed(() => {
+  const directValue = [product.value?.validStartTime, product.value?.validEndTime].filter(Boolean).join(' 至 ')
+  if (directValue) return directValue
+  const savedNotice = parseJsonValue<Record<string, unknown>>(product.value?.purchaseNotice, {})
+  return String(savedNotice.validPeriod || savedNotice.valid_period || savedNotice.validity || '')
 })
 const formatDateTime = (value?: string) => value ? value.replace('T', ' ') : ''
 const createdAtText = computed(() => formatDateTime(product.value?.createdAt) || '2026-06-18 11:34:25')
@@ -139,6 +167,17 @@
   return coverUrl ? [coverUrl] : [fallbackImage]
 }
 
+function parseHealthCheckItems(value?: Product['detailText']) {
+  healthCheckItems.value = []
+  const parsed = parseJsonValue<unknown>(value, [])
+  if (!Array.isArray(parsed)) return
+  healthCheckItems.value = parsed.map((item: any) => ({
+    name: String(item?.name || ''),
+    meaning: String(item?.meaning || ''),
+    gender: Array.isArray(item?.gender) ? item.gender.map((entry: unknown) => String(entry)) : [],
+  }))
+}
+
 function parseBenefits(value?: Product['rightsConfig'], legacyValue?: string) {
   benefitRows.forEach((row) => {
     row.enabled = true
@@ -182,6 +221,7 @@
     return
   } finally {
     galleryImages.value = parseProductImages(product.value?.productImages, product.value?.coverUrl)
+    parseHealthCheckItems(product.value?.detailText)
     parseNotice(product.value?.purchaseNotice, product.value)
     parseBenefits(product.value?.rightsConfig, product.value?.benefitDesc)
     loading.value = false
@@ -238,10 +278,14 @@
           <label>商品名称</label>
           <el-input :model-value="productNameText" readonly />
         </div>
-        <div class="detail-field detail-money-field">
+        <div v-if="!isHealthCheckProduct" class="detail-field detail-money-field">
           <label>商品金额</label>
           <el-input :model-value="productAmountText" readonly />
           <span>元</span>
+        </div>
+        <div v-else class="detail-field detail-period-field">
+          <label>可预约时间</label>
+          <el-input :model-value="healthCheckPeriodText" placeholder="未配置" readonly />
         </div>
         <div class="detail-time-pair">
           <label>创建时间</label>
@@ -258,7 +302,7 @@
         </div>
       </div>
 
-      <div class="audit-gallery-row">
+      <div v-if="!isHealthCheckProduct" class="audit-gallery-row">
         <label>商品图片</label>
         <div class="audit-thumb-list">
           <div v-for="image in imageList" :key="image" class="audit-thumb-box">
@@ -270,12 +314,24 @@
         </div>
       </div>
 
-      <div class="audit-textarea-row">
+      <div v-if="!isHealthCheckProduct" class="audit-textarea-row">
         <label>商品详情</label>
         <div class="audit-rich-text-preview" v-html="product?.detailText || ''"></div>
       </div>
 
-      <div class="purchase-notice-block">
+      <div v-else class="audit-textarea-row health-check-audit-row">
+        <label>商品详情</label>
+        <el-table :data="healthCheckItems" border class="health-check-audit-table">
+          <el-table-column prop="name" label="检查项目" min-width="220" />
+          <el-table-column prop="meaning" label="项目意义" min-width="320" />
+          <el-table-column label="男/女" width="180">
+            <template #default="{ row }">{{ row.gender.join('、') }}</template>
+          </el-table-column>
+          <template #empty>暂无体检项目</template>
+        </el-table>
+      </div>
+
+      <div v-if="!isHealthCheckProduct" class="purchase-notice-block">
         <p>购买须知设置(非必填)</p>
         <div class="purchase-notice-grid">
           <div>

--
Gitblit v1.7.1