| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- <template>
- <div class="detail-box">
- <div class="main-info__box">
- <div class="main-info__content">
- <div class="goods-info">
- <div class="image-box">
- <img :src="mainForm.detail.imgUrl" />
- </div>
- <div class="info-content">
- <div class="title">{{ mainForm.detail.goodsName || '' }}</div>
- <div class="stock-info__box">
- <div class="stock-content">
- <a-flex v-if="!isLogin" align="center">
- <a-button type="link" @click="toLogin">登录</a-button>
- <span>查看商品实时库存</span>
- </a-flex>
- <div v-else>库存: {{ mainForm.detail.stock }}</div>
- </div>
- </div>
- </div>
- </div>
- <div class="goods-handle">
- <div>
- <a-flex v-if="!isLogin" align="center">
- <a-button type="link" @click="toLogin">登录</a-button>
- <span>查看商品实时价格</span>
- </a-flex>
- <div v-else>价格: ¥ {{ mainForm.detail.goodsPrice }}</div>
- </div>
- <div>
- <a-form
- :model="mainForm"
- name="mainForm"
- :label-col="{ span: 24 }"
- :wrapper-col="{ span: 24 }"
- autocomplete="off"
- @finish="onFinish"
- @finishFailed="onFailed"
- >
- <a-form-item
- label="数量"
- name="quantity"
- :rules="[{ required: true, message: '数量不能为空' }]"
- >
- <a-input-number v-model:value="mainForm.quantity" :min="1" style="width: 100%;">
- <template #upIcon>
- <ArrowUpOutlined />
- </template>
- <template #downIcon>
- <ArrowDownOutlined />
- </template>
- </a-input-number>
- </a-form-item>
- <a-form-item label="" name="addToCard">
- <a-button :disabled="!isLogin" type="primary" block @click="handleAddToCart">添加到购物车</a-button>
- </a-form-item>
- <a-form-item label="" name="saveToList">
- <a-button :disabled="!isLogin" type="primary" block>保存到列表</a-button>
- </a-form-item>
- </a-form>
- </div>
- </div>
- </div>
- </div>
- <div class="main-desc__box">
- <a-tabs v-model:activeKey="mainForm.tabIndex" type="card" :tabBarStyle="{background: '#f3f3f7', marginBottom: 0}">
- <a-tab-pane
- v-for="(tabName, index) in tabs"
- :key="index"
- :tab="tabName"
- />
- </a-tabs>
- <div class="desc-content">
- <div v-show="mainForm.tabIndex == 0">
- <div v-html="mainForm.detail.content"></div>
- </div>
- <div v-show="mainForm.tabIndex == 1">
- <div :style="{marginBottom: '20px'}">
- <a-input
- v-model:value="mainForm.searchFileName"
- placeholder="点击输入文档名称搜索"
- size="large"
- allowClear
- >
- <template #prefix>
- <SearchOutlined />
- </template>
- </a-input>
- </div>
- <a-collapse
- v-for="(item, index) in goodsDocumentsRelaList"
- :key="index"
- collapsible="header"
- :style="{marginBottom: '20px'}"
- >
- <a-collapse-panel key="1" :header="item.children && item.children.length > 0 ? `${item.folderName} (${item.children.length})` : item.parentCategoryName">
- <div v-if="item.children && item.children.length > 0">
- <ViewFile
- v-for="(child, cIndex) in item.children"
- :key="cIndex"
- :url="child.url"
- :name="child.fileName"
- :show-delete="false"
- :style="{
- marginBottom: cIndex === item.children.length - 1 ? 0 : '12px'
- }"
- />
- </div>
- </a-collapse-panel>
- </a-collapse>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="js">
- import ViewFile from '@/components/viewFile/index.vue';
- import { ArrowUpOutlined, ArrowDownOutlined, SearchOutlined } from '@ant-design/icons-vue';
- import { reactive, computed, onMounted, watch } from 'vue';
- import { useRoute, useRouter } from 'vue-router';
- import { getDetail, getFileList } from '@/api/goods';
- import { useUserStore } from '@/store/user';
- import { useHomeStore } from '@/store/home';
- import { useGoodsStore } from '@/store/goods';
- import { goodsDetailData, fileList } from '@/utils/mock';
- const route = useRoute();
- const router = useRouter();
- const userStore = useUserStore();
- const homeStore = useHomeStore();
- const goodsStore = useGoodsStore();
- const mainForm = reactive({
- quantity: 1,
- tabIndex: 0,
- detail: {},
- searchFileName: ''
- })
- const isLogin = computed(() => userStore.isLogin);
- const goodsDocumentsRelaList = computed(() => {
- if (!mainForm.detail.goodsDocumentsRelaList || mainForm.detail.goodsDocumentsRelaList.length === 0) return [];
- const validList = mainForm.detail.goodsDocumentsRelaList.filter(item => item.goodsDocumentsId.indexOf(mainForm.searchFileName) > -1 || item.fileName.indexOf(mainForm.searchFileName) > -1);
- return validList.reduce((prev, curItem) => {
- const target = prev.find(item => item.goodsDocumentsId === curItem.goodsDocumentsId);
- if (target) {
- target.children.push(curItem);
- } else {
- prev.push({
- ...curItem,
- children: [curItem]
- })
- };
- return prev;
- }, []);
- });
- const tabs = computed(() => {
- if (!mainForm.detail.goodsDocumentsRelaList || mainForm.detail.goodsDocumentsRelaList.length === 0) return ['商品详情'];
- return ['商品详情', '文档'];
- });
- const onFinish = () => {}
- const onFailed = () => {}
- const fetchDetail = async () => {
- // const res = await getDetail(route.query.id);
- // mainForm.detail = res.data || {};
- mainForm.detail = goodsDetailData;
- }
- const fetchFileData = async () => {
- // const res = await getFileList(route.query.id);
- // mainForm.detail.goodsDocumentsRelaList = res.data || [];
- mainForm.detail.goodsDocumentsRelaList = fileList;
- }
- const handleAddToCart = () => {
- if (!mainForm.detail.goodsId) return;
- const buyGoods = [
- {
- goodsId: route.query.id,
- goodsSpecId: mainForm.detail.goodsSpecs ? mainForm.detail.goodsSpecs[0]?.goodsSpecId : '',
- secKillId: mainForm.detail.secKillId || '',
- promotionGroupId: mainForm.detail.promotionGroupId || ''
- }
- ]
- const params = {
- storageId: homeStore.storageId,
- buyGoods: buyGoods
- }
- goodsStore.addToCard(params)
- }
- const toLogin = () => {
- router.push({
- path: '/login'
- })
- }
- onMounted(() => {
- fetchDetail();
- fetchFileData();
- })
- watch(() => route.query.id, newVal => {
- fetchDetail();
- fetchFileData();
- })
- </script>
- <style lang="less" scoped>
- .detail-box {
- .main-info__box {
- margin-bottom: 24px;
- border: 1px solid @border-color;
- border-radius: 2px;
- .main-info__content {
- width: 100%;
- display: flex;
- .goods-info {
- flex: 1;
- display: flex;
- min-width: 1px;
- background: #fff;
- .image-box {
- width: 360px;
- height: 360px;
- flex-shrink: 0;
- img {
- display: block;
- width: 100%;
- height: 100%;
- }
- }
- .info-content {
- flex: 1;
- min-width: 1px;
- padding: 20px;
- word-break: break-all;
- .title {
- color: #000;
- font-size: 24px;
- font-weight: 600;
- line-height: 1.5;
- text-align: center;
- margin-bottom: 24px;
- }
- .stock-info__box {
- padding: 0 40px;
- .stock-content {
- padding: 20px 24px;
- border: 1px solid @border-color;
- border-radius: 2px;
- }
- }
- }
- }
- .goods-handle {
- width: 240px;
- padding: 20px;
- flex-shrink: 0;
- background: #fff9db;
- }
- }
- }
- .main-desc__box {
- .desc-content {
- padding: 20px;
- background: #fff;
- }
- }
- }
- ::v-deep img {
- max-width: 100% !important;
- }
- </style>
|