Masters.vue 4.42 KB
<template>
  <div class="masters-container">
    <!-- 一行一个 Item(单列) -->
    <section class="single-list">
      <div
        class="item-card"
        v-for="(item, i) in singleItems"
        :key="`single-${i}`"
        @click="goDetail(item)"
      >
        <div class="item-image">
          <img :src="item.image" :alt="item.name" />
        </div>
        <div class="item-caption">
          <div class="item-role">{{ item.role }}</div>
          <div class="item-name" v-html="formatNameWithSuperscript(item.name)"></div>
        </div>
      </div>
    </section>

    <!-- 一行两个 Item(双列) -->
    <section class="grid-two">
      <div
        class="item-card small"
        v-for="(item, i) in gridItems"
        :key="`grid-${i}`"
        @click="goDetail(item)"
      >
        <div class="item-image">
          <img :src="item.image" :alt="item.name" />
        </div>
        <div class="item-caption">
          <div class="item-role">{{ item.role }}</div>
          <div class="item-name small" v-html="formatNameWithSuperscript(item.name)"></div>
        </div>
      </div>
    </section>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useTitle } from '@vueuse/core';

// 导入接口
import { getSSQZAPI } from '@/api/index.js'

const router = useRouter()

useTitle('三師七證')

// 三师
const singleItems = ref([])

// 七证
const gridItems = ref([])

const goDetail = (item) => {
  router.push(`/masters/${item.id}`)
}

/**
 * 为name字段的第一个文字添加上标效果
 * @param {string} name - 原始姓名
 * @returns {string} - 带上标的HTML字符串
 */
const formatNameWithSuperscript = (name) => {
  if (!name || name.length === 0) return name

  const firstChar = name.charAt(0)
  const restChars = name.slice(1)

  return `<sup style="font-size: 0.6rem;">上</sup>${firstChar}<sup style="font-size: 0.6rem;">下</sup>${restChars}`
}

const pid = ref(router.currentRoute.value.query.pid)

onMounted(async () => {
  // 调用接口获取三师七证数据
  const { code, list } = await getSSQZAPI({ pid: pid.value });
  if (code) {
    const singleItemsData = list[0].list;
    const gridItemsData = list[1].list;
    singleItems.value = singleItemsData.map(item => ({
      id: item.id,
      role: item.post_excerpt,
      name: item.post_title,
      image: item.photo + '?imageMogr2/thumbnail/400x/strip/quality/70'
    }))
    gridItems.value = gridItemsData.map(item => ({
      id: item.id,
      role: item.post_excerpt,
      name: item.post_title,
      image: item.photo + '?imageMogr2/thumbnail/400x/strip/quality/70'
    }))
  }
})
</script>

<style scoped>
/* 页面容器 */
.masters-container {
  padding: 1.5rem;
  background: #F2EBDB;
}

/* 单列列表区 */
.single-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-bottom: 1rem;
}

/* 双列网格区 */
.grid-two {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

/* 卡片 */
.item-card {
  position: relative;
  border: 2px solid #6B4102;
  overflow: hidden;
  transition: transform 0.2s ease;
  padding: 0.5rem;
}

.item-card:hover {
  transform: translateY(-0.125rem);
}

.item-card.small {
  /* 双列卡片视觉上更紧凑 */
  border: 1px solid rgba(107, 65, 2, 0.8);
}

/* 图片区域 - 采用固定纵向比例 */
.item-image {
  width: 100%;
  aspect-ratio: 3 / 4;
  background: #f5f5f5;
}

.item-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* 底部说明条 */
.item-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(107, 65, 2, 0.8);
  color: #fff;
  padding: 0.75rem;
  text-align: center;
}

.item-role {
  font-size: 0.75rem;
  opacity: 0.95;
}

.item-name {
  font-size: 1.5rem;
  font-weight: 600;
  margin-top: 0.25rem;
}

.item-name.small {
  font-size: 1.25rem;
}


/* 响应式调整 */
@media (max-width: 48rem) {
  .item-caption {
    padding: 0.625rem;
    margin: 0.5rem;
  }
}

@media (max-width: 30rem) {
  .masters-container {
    padding: 0.75rem;
  }
  .item-caption {
    padding: 0.5rem;
    margin: 0.5rem;
  }
  .item-name {
    font-size: 1.25rem;
  }
  .item-name.small {
    font-size: 1rem;
  }
}

@media (max-width: 20rem) {
  .grid-two {
    gap: 0.5rem;
  }
  .item-caption {
    padding: 0.375rem;
    margin: 0.5rem;
  }
  .item-name {
    font-size: 1rem;
  }
  .item-name.small {
    font-size: 0.875rem;
  }
}
</style>