detail.vue 12.6 KB
<!--
 * @Date: 2024-09-29 14:26:41
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2024-10-23 18:29:36
 * @FilePath: /hager/src/views/product/detail.vue
 * @Description: 文件描述
-->
<template>
  <div class="product-detail">
    <hager-box>
      <div style="margin-top: 1.5rem;">
        <el-breadcrumb separator="/">
          <el-breadcrumb-item v-if="!is_xs">所有产品</el-breadcrumb-item>
          <el-breadcrumb-item>{{ info.parent_name }}</el-breadcrumb-item>
          <el-breadcrumb-item>{{ info.category_name }}</el-breadcrumb-item>
          <el-breadcrumb-item>{{ info.product_name }}</el-breadcrumb-item>
        </el-breadcrumb>
      </div>
    </hager-box>
    <hager-box class="box-n">
      <el-row v-if="!is_xs" :gutter="10" style="margin-bottom: 3rem;">
        <el-col :span="8">
          <hager-carousel :images="info_images"></hager-carousel>
        </el-col>
        <el-col :span="16">
          <div class="product-detail-info">
            <div class="product-title" style="">{{ info.product_name }}</div>
            <div class="product-sub" style="margin: 1rem 0 2rem;" v-html="info.post_excerpt"></div>
          </div>
        </el-col>
      </el-row>
      <div v-else>
        <div class="product-detail-info">
          <div class="product-title" style="">{{ info.product_name }}</div>
          <div class="product-sub" style="margin: 1rem 0 2rem;" v-html="info.post_excerpt"></div>
        </div>
        <div v-for="(item, index) in info_images" :key="index" class="product-item-img">
          <el-image style="height: 14rem;" :src="item" fit="cover"></el-image>
        </div>
      </div>
    </hager-box>
    <hager-box class="box-2n">
      <hager-h1 title="产品优势" sub="Product advantages"></hager-h1>
      <div :class="['product-advantage', is_xs ? 'xs' : '']">
        <div :class="['item', is_xs ? 'xs' : '']" v-for="(item, index) in product_advantages" :key="index">
          <el-row :gutter="0" v-for="(x, idx) in item" :key="idx">
            <el-col :span="24">{{ x }}</el-col>
          </el-row>
        </div>
      </div>
    </hager-box>
    <hager-box class="box-n">
      <hager-h1 title="产品资料" sub="Product Information"></hager-h1>
      <div class="product-info">
        <div class="info-control">
          <el-row :gutter="0">
            <el-col :span="is_xs ? 24 : 19">
              <div :class="['control-left', is_xs ? 'xs' : '']">
                <div v-if="product_sample" :class="['button', is_xs ? 'xs' : '', is_active === 0 ? 'active' : '']" @click="onClick(0, product_sample)">产品样本</div>
                <div v-if="technical_parameter" :class="['button', is_xs ? 'xs' : '', is_active === 1 ? 'active' : '']" @click="onClick(1, technical_parameter)">技术参数</div>
                <div v-if="product_manual" :class="['button', is_xs ? 'xs' : '', is_active === 2 ? 'active' : '']" @click="onClick(2, product_manual)">产品说明书</div>
                <div v-if="installation_tutorial" :class="['button', is_xs ? 'xs' : '', is_active === 3 ? 'active' : '']" @click="onClick(3, installation_tutorial)">安装教程</div>
              </div>
            </el-col>
            <el-col v-if="!is_xs" :span="5">
              <div>
                <div @click="goToDownload" :class="['button', is_download_checked ? 'active' : '']">发送到邮箱</div>
              </div>
            </el-col>
          </el-row>
        </div>
        <div>
          <div class="mini-download-wrapper" v-if="is_xs">
            <div>
              <span @click="checkAll">全选</span>&nbsp;
              <span v-if="checked_sum">已选 {{ checked_sum }}</span>
            </div>
            <div @click="goToDownload" :class="['button', is_download_checked ? 'active' : '']">发送到邮箱</div>
          </div>
          <div class="info-list" v-for="(item, index) in download_list" :key="index">
            <el-row :gutter="0">
              <el-col :span="18">
                <div class="info-list-title">
                  <el-row :gutter="0">
                    <el-col :span="is_xs ? 4 : 2">
                      <i v-if="item.checked" @click="checkItem(item)" class="el-icon-folder-checked download-checked"></i>
                      <i v-else @click="checkItem(item)" class="el-icon-folder  download-unchecked"></i>&nbsp;
                    </el-col>
                    <el-col :span="is_xs ? 20 : 22">
                      <i class="el-icon-document" style="font-size: 1.5rem;"></i>
                      {{ item.name }}{{ item.size }}
                    </el-col>
                  </el-row>
                  <!-- <i v-if="item.checked" @click="checkItem(item)" class="el-icon-folder-checked download-checked"></i>
                  <i v-else @click="checkItem(item)" class="el-icon-folder  download-unchecked"></i>
                  <i class="el-icon-document" style="font-size: 1.25rem; margin-left: 1rem;"></i>
                  <p><span>{{ item.name }}</span><span>{{ item.size }}</span></p> -->
                </div>
              </el-col>
              <el-col :span="6">
                <div class="info-list-control">
                  <div @click="preview(item)">预览</div>
                  <div @click="sendEmail" class="icon-wrapper">
                    <img style="height: 1rem; width: auto;" src="https://cdn.ipadbiz.cn/hager/icon/%E9%82%AE%E4%BB%B6@2x.png">
                  </div>
                </div>
              </el-col>
            </el-row>
          </div>
        </div>
      </div>
    </hager-box>
  </div>
</template>

<script>
import mixin from 'common/mixin';
import hagerBox from '@/components/common/hagerBox';
import hagerCarousel from '@/components/hagerCarousel';
import hagerH1 from '@/components/common/hagerH1.vue';
import { MessageBox, Message } from 'element-ui';
import { getProductInfoAPI } from "@/api/hager.js";

export default {
  components: { hagerBox, hagerCarousel, hagerH1 },
  mixins: [mixin.init],
  data () {
    return {
      is_active: 0,
      download_list: [],
      images: [],
      info: {},
      info_images: [],
      product_advantages: [],
      product_sample: '',
      technical_parameter: '',
      product_manual: '',
      installation_tutorial: '',
    }
  },
  computed: {
    is_download_checked () {
      return this.download_list.filter(item => item.checked).length > 0;
    },
    checked_sum () {
      return this.download_list.filter(item => item.checked).length;
    },
  },
  async mounted () {
    this.getInfo();
  },
  watch: {
    // 监听路由参数变化时,更新输入框的值
    async '$route.query.id' (val, old) {
      if (old !== val) {
        this.getInfo();
      }
    }
  },
  methods: {
    async getInfo () {
      const { code, data } = await getProductInfoAPI( { id: this.$route.query.id });
      if (code) {
        this.info = data;
        if (this.info.file?.img) {
          this.info_images = this.info.file.img.map(item => item.value);
        }
        //
        this.product_advantages = this.splitArrayIntoChunks(this.info.product_advantages);
        //
        this.product_sample = this.info.file?.yangben?.map(item => ({ ...item, checked: false }));// 产品样本
        this.technical_parameter = this.info.file?.canshu?.map(item => ({ ...item, checked: false })); // 技术参数
        this.product_manual = this.info.file?.shuomingshu?.map(item => ({ ...item, checked: false })); // 产品说明书
        this.installation_tutorial = this.info.file?.jiaocheng?.map(item => ({ ...item, checked: false })); // 安装教程
        let arr = [this.product_sample, this.technical_parameter, this.product_manual, this.installation_tutorial]
        for (let index = 0; index < arr.length; index++) {
          const element = arr[index];
          if (element) {
            this.download_list = element;
            return;
          }
        }
      }
    },
    onClick (n , item) {
      this.is_active = n;
      this.download_list = item;
      this.download_list.forEach(item => item.checked = false);
    },
    goToDownload () {
      if (this.is_download_checked) {
        // 发送邮箱接口
        Message({
          type: 'success',
          message: '发送成功'
        });
      }
    },
    checkAll () {
      this.download_list.forEach(item => item.checked = true);
    },
    sendEmail () {
      // 发送邮箱接口
      Message({
        type: 'success',
        message: '发送成功'
      });
    },
    preview (item) {
      window.open(item.value, '_blank');
    },
    splitArrayIntoChunks(list) {
      const productAdvantages = list;
      const chunkSize = 5;
      const result = [];

      for (let i = 0; i < productAdvantages.length; i += chunkSize) {
        // 使用 slice 方法按每组 5 个元素分割
        const chunk = productAdvantages.slice(i, i + chunkSize);
        result.push(chunk);
      }

      return result;
    },
    checkItem (item) {
      item.checked = !item.checked;
      // this.$forceUpdate();
    },
  }
}
</script>

<style lang="less" scoped>
.product-detail {
  .box-n {
    background-color: #fff;
    padding: 2rem 0;
  }
  .box-2n {
    background-color: #f1f1f1;
    padding: 2rem 0;
  }
  .product-detail-info {
    .product-title {
      font-size: 2rem;
      font-weight: bold;
      color: @secondary-color;
    }
    .product-sub {
      // margin: 1rem 0 2rem;
      // color: @text-color;
    }
    .product-info-list {
      padding: 0 1rem;
      li {
        line-height: 2;
        font-size: 0.9rem;
      }
    }
  }
  .product-advantage {
    margin-top: 1rem;
    display: flex;
    flex-wrap: wrap;
    // gap: 3rem;
    .item {
      width: calc(50% - 3rem);
      box-sizing: border-box;
      margin-right: 3rem;
      margin-bottom: 1rem;
      padding-top: 1rem;
      background-color: #f0f0f0;
      border-top: 4px solid @primary-color;
      line-height: 2;
      &.xs {
        padding-bottom: 1rem;
        width: 100%;
      }
    }
    &.xs {
      display: block;
    }
  }
  .product-info {
    .info-control {
      // display: flex;
      border-bottom: 4px solid @primary-color;
      padding-bottom: 1rem;
      margin-top: 2rem;
      .control-left {
        display: flex;
        // flex: 1 0 0;
        &.xs {
          display: flex;
          flex-wrap: nowrap; /* 禁止换行 */
          overflow-x: auto; /* 启用横向滚动 */
          -webkit-overflow-scrolling: touch; /* 使滚动更平滑,适用于移动端 */
        }
      }
      .button {
        background-color: #f3f3f3;
        padding: 1rem 2.2rem;
        border-radius: 5px;
        margin-right: 1rem;
        text-align: center;
        &:hover {
          cursor: pointer;
        }
        &.active {
          background-color: @primary-color;
          color: #fff;
        }
        &.xs {
          flex: 0 0 auto; /* 子元素保持固定大小 */
          width: 5rem; /* 可以根据需要设置宽度 */
          margin-right: 10px; /* 子元素之间的间距 */
        }
      }
    }
    .info-list {
      // display: flex;
      // justify-content: space-between;
      // align-items: center;
      padding-top: 2rem;
      color: #6b6b6b;
      .info-list-title {
        // display: flex;
        // align-items: center;
      }
      .info-list-control {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        color: @primary-color;
        div {
          margin-right: 1rem;
          &:hover {
            cursor: pointer;
            color: @primary-color;
            text-decoration: underline;
          }
        }
        .icon-wrapper {
          display: flex;
          justify-content: center; /* 水平居中 */
          align-items: center; /* 垂直居中 */
          img {
            max-width: 100%; /* 确保图片不会超出容器 */
            height: auto; /* 保持图片的宽高比 */
          }
        }
      }

      .download-checked {
          font-size: 1.5rem;
          color: @primary-color;
          &:hover {
            cursor: pointer;
          }
        }
        .download-unchecked {
          font-size: 1.5rem;
          &:hover {
            cursor: pointer;
          }
        }
    }

    .mini-download-wrapper {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-top: 1rem;
      .button {
        background-color: #f3f3f3;
        padding: 0.85rem 1rem;
        border-radius: 5px;
        text-align: center;
        &.active {
          background-color: @primary-color;
          color: #fff;
        }
      }
    }
  }

  .product-item-img {
    height: auto;
    padding: 1.5rem;
    text-align: center;
    color: #333;
    border-radius: 8px;
    background-color: #FFF;
    margin-bottom: 1rem;
    border: 1px solid #ebebeb;
  }
}
</style>