1464 lines
46 KiB
Vue
1464 lines
46 KiB
Vue
<template>
|
||
<div v-if="loading" class="ui-shopDetail">
|
||
<van-swipe :autoplay="3000" lazy-render>
|
||
<van-swipe-item v-for="image in banner" :key="image" class="ui-relative">
|
||
<img class="ui-mall-pic" :src="image" alt="" />
|
||
</van-swipe-item>
|
||
<template #indicator="{ active, total }">
|
||
<div class="custom-indicator font_26 colorF">{{ active + 1 }}/{{ total }}</div>
|
||
</template>
|
||
</van-swipe>
|
||
<div class="ui-shop-detail-container">
|
||
<div class="ui-shop-data-box">
|
||
<div class="f-fcl">
|
||
<span class="font_28 ui-price-symbol bold">¥</span>
|
||
<div class="font_44 ui-show-price bold"><span v-html="htmlPrice"></span></div>
|
||
<!-- <div class="font_28 ui-original-price color6">¥{{ originPrice }}</div>-->
|
||
</div>
|
||
<div class="font_32 color3 bold ui-pt-10">{{ title }}</div>
|
||
<!-- <div class="font_24 color9 ui-pt-20">通过无抗生素产品认证,个个可...</div>-->
|
||
</div>
|
||
<div class="ui-ExpressDelivery-data-box">
|
||
<div>
|
||
<div class="f-fcl font_28">
|
||
<span class="color9 ui-pr-24">配送</span>
|
||
<span class="ui-pr-24">广东深圳</span>
|
||
<!-- <span v-if="freightPrice != '0.00' || freightPrice != 0" class="ui-pl-24 ui-relative ui-distribution-address">运费:{{ freightPrice }}</span>-->
|
||
</div>
|
||
<!-- <div class="font_28 ui-pt-24">-->
|
||
<!-- <span class="color9 ui-pr-24">服务</span>-->
|
||
<!-- <span class="color3">支持7天无理由退货</span>-->
|
||
<!-- </div>-->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-if="describe" class="ui-relative ui-pt-40">
|
||
<img class="ui-line-icon" src="https://image.fulllinkai.com/202405/15/266a22038e0122c70fc282f00c78dbc7.png" alt="" />
|
||
<div class="font_26 color3 ui-line-text">商品详情</div>
|
||
</div>
|
||
<div v-if="describe" class="font_28 color3 ui-detail-introduce">
|
||
<richTextParsing :rich-text="describe"></richTextParsing>
|
||
</div>
|
||
<div class="ui-bottom-operation f-fbc">
|
||
<div class="ui-operation-icon-box" @click="showShare = true">
|
||
<img class="ui-operation-icon" src="https://image.fulllinkai.com/202405/15/b18fc23a9956849ddbead6882fa60bb9.png" alt="" />
|
||
<div class="font_20 color6 text-center">分享</div>
|
||
</div>
|
||
<div class="ui-buy-btn f-fcc font_30 colorF" @click="showBug = true">立即购买</div>
|
||
</div>
|
||
<sharePosterV2 ref="openSharePoster">
|
||
<template #sharePoster>
|
||
<!--生成海报html容器-->
|
||
<div id="capture" class="ui-poster-container">
|
||
<div class="ui-user-avatar-box f-fcc">
|
||
<div class="ui-user-avatar backCover" :style="{ background: 'url(' + canvasData.avatar + ')' }"></div>
|
||
<div class="color3 font_22 ui-ml-8 ui-user-name-box f-fcc">
|
||
<div v-if="shareName">{{ shareName }}</div>
|
||
<div>推荐一个好物给你</div>
|
||
</div>
|
||
</div>
|
||
<div class="ui-poster-pic-box">
|
||
<img class="ui-poster-pic" :src="canvasData.pic" alt="" />
|
||
</div>
|
||
<div class="ui-poster-data-box">
|
||
<div class="ui-mt-20 ui-ml-20">
|
||
<div class="f-fcl">
|
||
<span class="font_24 ui-poster-price-symbol">¥</span>
|
||
<div class="font_40 ui-poster-price"><span v-html="htmlSharePrice"></span></div>
|
||
</div>
|
||
<div class="font_24 ellipsis_2 ui-poster-title color3">{{ title }}</div>
|
||
</div>
|
||
<div class="ui-poster-qrcode-box">
|
||
<img class="ui-poster-qrcode" :src="canvasData.qrcode" alt="" />
|
||
<div class="font_20 color6 text-center">长按保存图片至相册</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</sharePosterV2>
|
||
<van-popup v-model:show="showBug" round position="bottom" :duration="0.5">
|
||
<div class="ui-bug-box">
|
||
<img class="ui-close-icon" src="https://image.fulllinkai.com/202405/16/20161b3e74af1eacd328181ff40b0358.png" alt="" @click="showBug = false" />
|
||
<div class="ui-buy-detail-box">
|
||
<img class="ui-buy-pic" :src="icon" alt="" />
|
||
<div>
|
||
<div class="ellipsis_1 font_32 color333 bold ui-buy-title">{{ title }}</div>
|
||
<div>
|
||
<div class="f-fbc ui-total-price-box">
|
||
<div class="f-fcl">
|
||
<div v-if="calculating" class="font_24 color6 bold">计算中...</div>
|
||
<!-- <div v-else-if="stock == 0 || stock < minNum" class="font_24 color6">{{ stock == 0 ? '库存不足' : stock < minNum ? '库存不足,小于最低购买量' : '' }}</div>-->
|
||
<div v-else class="f-fcl bold ui-total-price">
|
||
<span class="font_28 ui-buy-price-symbol">¥</span>
|
||
<div class="font_44"><span v-html="htmlTotalPrice"></span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="f-fcl ui-buy-price color3 font_24 ui-mt-6"> 已选:{{ getSelectedSpecNames() }} </div>
|
||
</div>
|
||
<!-- <div class="f-fcl ui-buy-price color3 font_24"> 已选:{{ spuData.spec[spuIndex].name }} {{ spuSubIndex !== null ? spuSubData.spec[spuSubIndex].name : '' }} </div>-->
|
||
</div>
|
||
</div>
|
||
<div v-if="spuData.name" class="ui-sku-box">
|
||
<div class="ui-sku-list">
|
||
<!-- <div class="font_28 color3 bold">{{ spuData.name }}</div>-->
|
||
<!-- <div class="f-fcl f-wrap">-->
|
||
<!-- <div v-for="(item, index) in spuData.spec" :key="index" class="font_26 f-fbc color3 ui-pt-16" @click="selectSku(index)">-->
|
||
<!-- <div class="ui-sku-item" :class="spuIndex == index ? 'ui-sku-item-active colorF' : 'color3'">{{ item.name }}</div>-->
|
||
<!-- </div>-->
|
||
<!-- </div>-->
|
||
<!-- <div v-if="spuSubData.name" class="ui-pt-36">-->
|
||
<!-- <div class="font_28 color3 bold">{{ spuSubData.name }}</div>-->
|
||
<!-- <div class="f-fcl f-wrap">-->
|
||
<!-- <div v-for="(item, index) in spuSubData.spec" :key="index" class="font_26 f-fbc color3 ui-pt-16" @click="selectSubSku(index)">-->
|
||
<!-- <div class="ui-sku-item" :class="spuSubIndex == index ? 'ui-sku-item-active colorF' : 'color3'">{{ item.name }}</div>-->
|
||
<!-- </div>-->
|
||
<!-- </div>-->
|
||
<!-- </div>-->
|
||
<div class="ui-sku-list ui-sku-list-v2">
|
||
<!-- 使用动态递归规格选择器 -->
|
||
<dynamic-sku-selector :specs="[spuData]" :selected-path="selectedSpecPath" :disabled="isRouteSelected" :show-only-selected="showOnlySelected" @select="handleSpecSelect" />
|
||
</div>
|
||
|
||
<div class="ui-num-box f-fbc ui-pt-28">
|
||
<div class="font_24 color6"><span class="font_28 color3 ui-mr-16">数量</span></div>
|
||
<div class="f-fcr ui-num-input-box">
|
||
<div class="ui-relative f-fcl">
|
||
<div class="font_40 color6 ui-num-input-minus" @click="numMinus()">
|
||
<div class="ui-num-minus">-</div>
|
||
</div>
|
||
<van-field v-model="num" type="digit" class="ui-input f-fcc font_28 color3" input-align="center" placeholder="购买数量" @input="numChange" />
|
||
<!-- <div class="ui-select-input font_28">{{ num }}</div>-->
|
||
<div class="font_40 color6 ui-num-input-add" @click="numAdd()">
|
||
<div class="ui-num-minus-v2">+</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- <div class="f-fbc ui-total-price-box">-->
|
||
<!-- <div class="f-fcl">-->
|
||
<!-- <div class="font_24 color6">合计金额:</div>-->
|
||
<!-- <div v-if="calculating" class="font_26 color6 bold">计算中...</div>-->
|
||
<!-- <div v-else-if="num == 0" class="font_26 color6 bold">库存不足</div>-->
|
||
<!-- <div v-else class="f-fcl bold ui-total-price">-->
|
||
<!-- <span class="font_28 ui-buy-price-symbol">¥</span>-->
|
||
<!-- <div class="font_44"><span v-html="htmlTotalPrice"></span></div>-->
|
||
<!-- </div>-->
|
||
<!-- </div>-->
|
||
<!-- </div>-->
|
||
</div>
|
||
<div v-if="policyTitle" class="ui-confirm-bottom-box">
|
||
<div class="f-fcc">
|
||
<img v-show="!isAgreement" class="ui-agreement-icon" src="https://image.fulllinkai.com/202405/16/fae039c670338fe6743b7f6a8803ec43.png" alt="" @click="isAgreement = !isAgreement" />
|
||
<img v-show="isAgreement" class="ui-agreement-icon" src="https://image.fulllinkai.com/202405/16/c27533426d24451aceba94e4fe316e88.png" alt="" @click="isAgreement = !isAgreement" />
|
||
<div class="font_24 color6" @click="isAgreement = !isAgreement">
|
||
已阅读并同意<span class="ui-agreement-text" @click.stop="jumpAgreement">{{ policyTitle }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="ui-confirm-btn font_32 f-fcc colorF bold" @click="payment">立即支付</div>
|
||
</div>
|
||
</van-popup>
|
||
<van-share-sheet v-model:show="showShare" title="立即分享给好友" :options="options" @select="onSelect" />
|
||
</div>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { onMounted, ref, onDeactivated, onActivated, computed } from 'vue';
|
||
import qrcode from 'qrcode';
|
||
import { showToast } from 'vant';
|
||
import clipboard3 from 'vue-clipboard3';
|
||
import router from '@/router';
|
||
import requestGo from '@/utils/requestGo';
|
||
import { weXinShare } from '@/plugins/wxShare';
|
||
import { examineRegister, imageConversion } from '@/plugins/public';
|
||
import { useUserStore } from '@/store/modules/user';
|
||
import dynamicSkuSelector from '@/components/dynamicSkuSelector.vue';
|
||
|
||
defineOptions({ name: 'ShopDetail' });
|
||
|
||
const { toClipboard } = clipboard3();
|
||
const userStore = useUserStore() as any;
|
||
const loading = ref(false);
|
||
const showBug = ref(false);
|
||
const timer = ref<any>(null);
|
||
const isAgreement = ref(false); // 是否同意协议
|
||
const isRouteSelected = ref(false); // 标记是否通过路由参数选择
|
||
const currentSkuId = ref(0); // 当前选中的SKU ID
|
||
|
||
const id = ref<any>('');
|
||
const title = ref<any>('');
|
||
const icon = ref<any>('');
|
||
const shareIcon = ref<any>('');
|
||
const sharePosterDesc = ref<any>('');
|
||
const policyId = ref<any>('');
|
||
const policyTitle = ref<any>('');
|
||
const banner = ref<any[]>([]); // 轮播图
|
||
const describe = ref<any>(); // 详情富文本
|
||
const num = ref<any>(0); // 购买数量
|
||
const minNum = ref<any>(0); // 购买最小数量
|
||
const skuIds = ref<any>([]);
|
||
const skuIdDataList = ref<any[]>([]);
|
||
const stock = ref<any>(0); // 选中的sku剩余库存
|
||
const calculating = ref<any>(false); // 是否显示价格计算中
|
||
|
||
const shareUrl = ref('');
|
||
|
||
const spuData = ref<any>({}); // spu一级数据
|
||
const spuSubData = ref<any>({}); // spu二级数据
|
||
|
||
const spuIndex = ref(0); // spu一级选中下标
|
||
const spuSubIndex = ref<any>(null); // spu二级选中下标
|
||
const defaultSkuId = ref<any>(0); // 默认sku_id
|
||
const querySkuId = ref<any>(0); // 路径sku_id
|
||
const skuShip = ref(3); // sku对应的物流设置
|
||
|
||
const htmlPrice = ref<any>(''); // 详情展示价格
|
||
const htmlSharePrice = ref<any>(''); // 分享展示价格
|
||
const shareName = ref<any>('');
|
||
const htmlTotalPrice = ref<any>('0'); // 总价展示价格
|
||
const originPrice = ref<any>(0); // 原价
|
||
const freightPrice = ref<any>(0); // 邮费
|
||
|
||
const canvasData = ref<any>({ background: '', avatar: '', pic: '', qrcode: '' }); // 分享所需要的图片数据
|
||
const openSharePoster = ref<any>(); // 分享按钮组件事件
|
||
const spuBanner = ref<any>([]);
|
||
const spuDesc = ref<any>('');
|
||
|
||
const showShare = ref(false);
|
||
const options = [
|
||
{ name: '复制链接', icon: 'link' },
|
||
{ name: '分享海报', icon: 'poster' },
|
||
];
|
||
|
||
const onSelect = (option) => {
|
||
if (option.name == '复制链接') {
|
||
onCopy(shareUrl.value);
|
||
} else {
|
||
isShowPoster();
|
||
}
|
||
showShare.value = false;
|
||
};
|
||
|
||
const onCopy = (e) => {
|
||
try {
|
||
toClipboard(e);
|
||
showToast('复制成功');
|
||
} catch (err) {
|
||
console.error(err);
|
||
showToast('复制失败,请手动复制');
|
||
}
|
||
};
|
||
|
||
// 获取商品详情
|
||
const getDetail = () => {
|
||
spuBanner.value = [];
|
||
spuDesc.value = '';
|
||
requestGo({ url: `/h5/v2/shop/common/spu/detail/${id.value}`, hideLoading: true, method: 'get' })
|
||
.then((res) => {
|
||
const result = res.data;
|
||
banner.value = [];
|
||
banner.value = [result.sku_default.icon];
|
||
result.spu.banner = JSON.parse(result.spu.banner);
|
||
console.log(spuBanner.value, banner.value, 'spuBanner.value');
|
||
if (banner.value.length == 0) {
|
||
banner.value = spuBanner.value;
|
||
}
|
||
describe.value = result.spu.description;
|
||
spuDesc.value = result.spu.description;
|
||
title.value = result.spu.title;
|
||
icon.value = result.sku_default.icon;
|
||
policyId.value = result.spu.policy_id;
|
||
policyTitle.value = result.spu.policy_title;
|
||
result.spu.spec = JSON.parse(result.spu.spec);
|
||
spuData.value = result.spu.spec;
|
||
// spuSubData.value = {};
|
||
// // 默认选中第一个sku
|
||
// if (spuData.value.name && spuData.value.spec[spuIndex.value].sub_spec) {
|
||
// spuSubData.value = spuData.value.spec[spuIndex.value].sub_spec;
|
||
// spuSubIndex.value = 0;
|
||
// }
|
||
selectedSpecPath.value = findFirstSkuPath([spuData.value]);
|
||
// 收集所有skuid
|
||
// const allSkuIds = collectAllSkuIds(spuData.value.spec);
|
||
// console.log(allSkuIds, 'allSkuIds');
|
||
// skuIds.value = allSkuIds.join(',');
|
||
// 默认的sku_id
|
||
defaultSkuId.value = result.sku_default?.id || 0;
|
||
minNum.value = result.sku_default?.maxNum || 10;
|
||
|
||
// 循环出所有的skuid
|
||
spuData.value.spec.forEach((item) => {
|
||
if (item.skuid) {
|
||
skuIds.value.push(item.skuid);
|
||
}
|
||
if (item.sub_spec && item.sub_spec.spec) {
|
||
recursion(item.sub_spec.spec, skuIds.value);
|
||
}
|
||
});
|
||
console.log(spuData.value.spec, '=====');
|
||
if (`${result.sku_default.price}`.includes('.')) {
|
||
let splitPrice = result.sku_default.price.split('.');
|
||
htmlSharePrice.value = `${splitPrice[0]}.<span class="font_32">${splitPrice[1]}</span>`;
|
||
} else {
|
||
htmlSharePrice.value = result.sku_default.price;
|
||
}
|
||
console.log(htmlSharePrice.value, 'htmlSharePrice.value');
|
||
|
||
shareName.value = userStore.agentName ? (userStore.agentName.length > 4 ? `${userStore.agentName.slice(0, 4)}...` : userStore.agentName) : '';
|
||
|
||
// 根据循环出所有的skuid获取每一个skuid的库存
|
||
// 获取库存数据后设置默认选中
|
||
getSkuIdStock();
|
||
let shareTitle = ''
|
||
shareIcon.value = ''
|
||
let shareDesc = '';
|
||
if (id.value == 118 || id.value == 332) {
|
||
shareDesc = '核心方案+专业服务团队与 AI 技术全程支持';
|
||
} else if (id.value == 178) {
|
||
shareDesc = '双证报考,自我提升 + 就业双赢';
|
||
} else if (id.value == 489) {
|
||
shareTitle = '友福同享•体重管理'
|
||
shareIcon.value = 'https://images.health.ufutx.com/202608/11/e2cd3393a41a54fe00d6f446fc7e1826.jpg'
|
||
shareDesc = '轻松减 不反弹';
|
||
sharePosterDesc.value = '轻松减 不反弹'
|
||
} else {
|
||
shareDesc = '🌟 友福同享严选好物 →';
|
||
}
|
||
weXinShare(`${shareIcon.value || result.spu.icon}`, `https://health.ufutx.cn/go_html/store_common#/shopDetail/${id.value}?from_user_id=${userStore.userID}&from_type=rt_${id.value}`, `${shareTitle || result.spu.title}`, `${shareDesc}`);
|
||
|
||
let text = `https://health.ufutx.cn/go_html/store_common#/shopDetail/${id.value}?from_user_id=${userStore.userID}&from_type=rt_${id.value}`;
|
||
shareUrl.value = text;
|
||
qrcode.toDataURL(text, (err, url) => {
|
||
if (err) {
|
||
console.log(err);
|
||
} else {
|
||
// 分享二维码图片转base64
|
||
canvasData.value.qrcode = url;
|
||
}
|
||
});
|
||
|
||
// 分享背景图片转base64
|
||
imageConversion('https://image.fulllinkai.com/202111/02/f23994d8fd3088c833a8bbf2bfdf6de5.png').then((res) => {
|
||
canvasData.value.background = res;
|
||
});
|
||
// 分享用户头像图片转base64
|
||
imageConversion(`${userStore.agentAvatar}`).then((res) => {
|
||
canvasData.value.avatar = res;
|
||
});
|
||
// 分享活动图片转base64
|
||
imageConversion(`${shareIcon.value || result.spu.icon}`).then((res) => {
|
||
canvasData.value.pic = res;
|
||
});
|
||
console.log(result);
|
||
})
|
||
.catch((err) => {
|
||
console.log(err);
|
||
});
|
||
};
|
||
|
||
// 获取所有skuid库存
|
||
const getSkuIdStock = () => {
|
||
console.log(skuIds.value, 'skuIds.value');
|
||
requestGo({ url: `/h5/v2/shop/common/sku/${skuIds.value}`, hideLoading: true, method: 'get' })
|
||
.then((res) => {
|
||
const result = res.data;
|
||
console.log(result, '77777');
|
||
skuIdDataList.value = result;
|
||
//
|
||
// if (skuIdDataList.value && skuIdDataList.value.length > 0) {
|
||
// // 判断路径 sku_id是否存在sku列表中
|
||
// skuIdDataList.value.map((item) => {
|
||
// if (item.id == querySkuId.value) {
|
||
// defaultSkuId.value = querySkuId.value;
|
||
// }
|
||
// });
|
||
//
|
||
// spuData.value.spec.map((item, index) => {
|
||
// if (item.sub_spec) {
|
||
// item.sub_spec.spec.map((itemV2, indexV2) => {
|
||
// if (defaultSkuId.value == itemV2.skuid) {
|
||
// spuIndex.value = index;
|
||
// spuSubIndex.value = indexV2;
|
||
// spuSubData.value = item.sub_spec;
|
||
// }
|
||
// });
|
||
// } else {
|
||
// if (defaultSkuId.value == item.skuid) {
|
||
// spuIndex.value = index;
|
||
// }
|
||
// }
|
||
// });
|
||
// gainSelectStock();
|
||
// console.log('3444');
|
||
// num.value = stock.value > minNum.value ? minNum.value : 0;
|
||
// } else {
|
||
// console.log('999');
|
||
// num.value = 0;
|
||
// }
|
||
// console.log(skuIdDataList.value, 'vvv-');
|
||
const firstPath = findFirstSkuPath([spuData.value]);
|
||
console.log(firstPath, '===');
|
||
if (firstPath.length > 0) {
|
||
selectedSpecPath.value = firstPath;
|
||
gainSelectStock();
|
||
}
|
||
console.log(router.currentRoute.value.query.selectPath, 'router.currentRoute.value.query.selectPath');
|
||
if (router.currentRoute.value.query.selectPath) {
|
||
console.log('111');
|
||
handleRouteSelectPath();
|
||
} else {
|
||
console.log('222');
|
||
prepay('init');
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
console.log(err);
|
||
});
|
||
};
|
||
|
||
// 替换原有的固定两级规格变量
|
||
const selectedSpecPath = ref([]); // 存储选中的规格路径 [0, 0, 1, 2]
|
||
const specHierarchy = ref([]); // 存储规格层级结构
|
||
const showOnlySelected = ref(false);
|
||
// // 新增:递归获取所有skuid的通用方法
|
||
// // 修正后的collectAllSkuIds函数
|
||
// const collectAllSkuIds = (specData) => {
|
||
// const ids = [];
|
||
//
|
||
// const traverse = (specs) => {
|
||
// if (!specs || !Array.isArray(specs)) return;
|
||
//
|
||
// specs.forEach((item) => {
|
||
// if (item.skuid) {
|
||
// ids.push(item.skuid);
|
||
// }
|
||
// if (item.sub_spec && item.sub_spec.spec) {
|
||
// traverse(item.sub_spec.spec);
|
||
// }
|
||
// });
|
||
// };
|
||
//
|
||
// traverse(specData);
|
||
// return ids;
|
||
// };
|
||
|
||
// 修正findFirstSkuPath支持多级递归
|
||
const findFirstSkuPath = (specData) => {
|
||
const traverse = (specs, basePath = []) => {
|
||
if (!specs || !Array.isArray(specs)) return [];
|
||
|
||
for (let specIndex = 0; specIndex < specs.length; specIndex++) {
|
||
const specGroup = specs[specIndex];
|
||
if (!specGroup || !specGroup.spec) continue;
|
||
|
||
for (let itemIndex = 0; itemIndex < specGroup.spec.length; itemIndex++) {
|
||
const item = specGroup.spec[itemIndex];
|
||
const currentPath = [...basePath, itemIndex];
|
||
|
||
if (item.skuid) {
|
||
return currentPath;
|
||
}
|
||
|
||
if (item.sub_spec && item.sub_spec.spec && item.sub_spec.spec.length > 0) {
|
||
const subPath = traverse([item.sub_spec], currentPath);
|
||
if (subPath.length > 0) {
|
||
return subPath;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return [];
|
||
};
|
||
|
||
return traverse(specData);
|
||
};
|
||
|
||
// 修正后的getSkuByPath函数
|
||
const getSkuByPath = (path, specData) => {
|
||
if (!path || !path.length || !specData || !Array.isArray(specData)) return null;
|
||
// 移除偶数长度检查
|
||
|
||
let currentSpecs = specData;
|
||
let result = null;
|
||
|
||
for (let i = 0; i < path.length; i++) {
|
||
const index = path[i];
|
||
|
||
// 边界检查
|
||
if (!currentSpecs[0] || !currentSpecs[0].spec || index < 0 || index >= currentSpecs[0].spec.length) {
|
||
return null;
|
||
}
|
||
|
||
const item = currentSpecs[0].spec[index];
|
||
if (!item) {
|
||
return null;
|
||
}
|
||
|
||
result = item;
|
||
|
||
// 如果还有下一级,继续深入
|
||
if (i + 1 < path.length && result.sub_spec) {
|
||
currentSpecs = [result.sub_spec];
|
||
} else if (i + 1 < path.length && !result.sub_spec) {
|
||
return null; // 路径超出层级
|
||
}
|
||
}
|
||
|
||
return result;
|
||
};
|
||
|
||
const getSelectedSpecNames = () => {
|
||
if (!selectedSpecPath.value.length) return '';
|
||
|
||
const names = [];
|
||
let current = spuData.value;
|
||
|
||
for (let i = 0; i < selectedSpecPath.value.length; i++) {
|
||
const index = selectedSpecPath.value[i];
|
||
|
||
// 边界检查
|
||
if (!current || !current.spec || !Array.isArray(current.spec) || index < 0 || index >= current.spec.length) {
|
||
break;
|
||
}
|
||
|
||
const item = current.spec[index];
|
||
if (!item) {
|
||
break;
|
||
}
|
||
|
||
names.push(item.name);
|
||
|
||
// 继续深入下一层
|
||
if (i < selectedSpecPath.value.length - 1) {
|
||
if (!item.sub_spec) {
|
||
break;
|
||
}
|
||
current = item.sub_spec;
|
||
}
|
||
}
|
||
|
||
return names.join(' ');
|
||
};
|
||
|
||
// // 修正后的collectAllSkuIds函数
|
||
// const collectAllSkuIds = (specs) => {
|
||
// const ids = [];
|
||
// console.log(specs, 'specs=');
|
||
// const traverse = (items) => {
|
||
// console.log(items, 'i==sdf');
|
||
// if (!Array.isArray(items)) return;
|
||
//
|
||
// items.forEach((specGroup) => {
|
||
// if (specGroup && specGroup.spec && Array.isArray(specGroup.spec)) {
|
||
// specGroup.spec.forEach((item) => {
|
||
// if (item.skuid) {
|
||
// ids.push(item.skuid);
|
||
// }
|
||
// if (item.sub_spec && item.sub_spec.spec && Array.isArray(item.sub_spec.spec)) {
|
||
// traverse([item.sub_spec]); // 保持数组格式
|
||
// }
|
||
// });
|
||
// }
|
||
// });
|
||
// };
|
||
//
|
||
// traverse(specs || []);
|
||
// return ids;
|
||
// };
|
||
|
||
// 处理规格选择事件
|
||
const handleSpecSelect = (fullPath: number[]) => {
|
||
console.log('handleSpecSelect收到路径:', fullPath);
|
||
|
||
if (!fullPath || !Array.isArray(fullPath) || fullPath.length === 0) {
|
||
console.warn('无效的路径:', fullPath);
|
||
return;
|
||
}
|
||
|
||
selectedSpecPath.value = [...fullPath];
|
||
|
||
const currentItem = getItemByPath(fullPath);
|
||
if (!currentItem) {
|
||
console.warn('路径对应的规格项不存在:', fullPath);
|
||
return;
|
||
}
|
||
|
||
// 自动选择下一层级规格(使用新的路径格式)
|
||
const autoSelectNextLevel = (currentPath: number[]) => {
|
||
const item = getItemByPath(currentPath);
|
||
|
||
if (!item) {
|
||
console.warn('autoSelectNextLevel - 规格项不存在:', currentPath);
|
||
return;
|
||
}
|
||
|
||
if (item.sub_spec && item.sub_spec.spec && Array.isArray(item.sub_spec.spec) && item.sub_spec.spec.length > 0) {
|
||
// 使用新的路径格式:[...currentPath, 0]
|
||
const nextPath = [...currentPath, 0];
|
||
|
||
const nextItem = getItemByPath(nextPath);
|
||
if (nextItem) {
|
||
selectedSpecPath.value = nextPath;
|
||
autoSelectNextLevel(nextPath);
|
||
} else {
|
||
console.warn('下一层级路径无效:', nextPath);
|
||
}
|
||
}
|
||
};
|
||
|
||
autoSelectNextLevel([...fullPath]);
|
||
gainSelectStock();
|
||
};
|
||
// 通过路径获取规格项
|
||
const getItemByPath = (path: number[]) => {
|
||
if (!path || path.length === 0 || !spuData.value) return null;
|
||
// 移除偶数长度检查
|
||
|
||
let current = spuData.value;
|
||
|
||
for (let i = 0; i < path.length; i++) {
|
||
const index = path[i];
|
||
|
||
// 边界检查
|
||
if (!current || !current.spec || !Array.isArray(current.spec) || index < 0 || index >= current.spec.length) {
|
||
return null;
|
||
}
|
||
|
||
const item = current.spec[index];
|
||
if (!item) {
|
||
return null;
|
||
}
|
||
|
||
if (i === path.length - 1) {
|
||
return item;
|
||
}
|
||
|
||
// 继续深入下一层
|
||
if (!item.sub_spec) {
|
||
return null;
|
||
}
|
||
|
||
current = item.sub_spec;
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
// // 修正后的findItemByPath函数 - 与getItemByPath保持一致
|
||
// const findItemByPath = (path: number[]) => {
|
||
// if (!path || path.length === 0 || !spuData.value) return null;
|
||
// // 移除偶数长度检查
|
||
//
|
||
// let current = spuData.value;
|
||
//
|
||
// for (let i = 0; i < path.length; i++) {
|
||
// const index = path[i];
|
||
//
|
||
// if (!current || !current.spec || !Array.isArray(current.spec) || index < 0 || index >= current.spec.length) {
|
||
// return null;
|
||
// }
|
||
//
|
||
// const item = current.spec[index];
|
||
// if (!item) {
|
||
// return null;
|
||
// }
|
||
//
|
||
// if (i === path.length - 1) {
|
||
// return item;
|
||
// }
|
||
//
|
||
// if (!item.sub_spec) {
|
||
// return null;
|
||
// }
|
||
//
|
||
// current = item.sub_spec;
|
||
// }
|
||
//
|
||
// return null;
|
||
// };
|
||
//
|
||
// const getNextLevelPath = (currentPath) => {
|
||
// console.log(currentPath, 'currentPath');
|
||
// let current = spuData.value;
|
||
//
|
||
// // 遍历到当前路径
|
||
// for (let i = 0; i < currentPath.length; i += 2) {
|
||
// const specIndex = currentPath[i];
|
||
// const itemIndex = currentPath[i + 1];
|
||
// if (!current || !current.spec || !current.spec[specIndex] || !current.spec[specIndex].spec[itemIndex]) {
|
||
// return null;
|
||
// }
|
||
//
|
||
// const item = current.spec[specIndex].spec[itemIndex];
|
||
// console.log(item, 'item====');
|
||
//
|
||
// // 检查是否有子规格
|
||
// if (item.sub_spec && item.sub_spec.spec && item.sub_spec.spec.length > 0) {
|
||
// // 返回下一层级的第一项
|
||
// return [0, 0];
|
||
// }
|
||
//
|
||
// current = item.sub_spec;
|
||
// console.log(current, 'current');
|
||
// }
|
||
//
|
||
// return null;
|
||
// };
|
||
|
||
// 获取选中sku的库存信息
|
||
const gainSelectStock = () => {
|
||
console.log('当前选中路径:', selectedSpecPath.value);
|
||
console.log('当前选中路径2:', [spuData.value]);
|
||
const selectedSku = getSkuByPath(selectedSpecPath.value, [spuData.value]);
|
||
console.log('选中的sku:', selectedSku);
|
||
|
||
if (selectedSku && selectedSku.skuid) {
|
||
const skuInfo = skuIdDataList.value.find((item) => item.id === selectedSku.skuid);
|
||
console.log(skuInfo, 'skuInfo');
|
||
if (skuInfo) {
|
||
stock.value = skuInfo.stock;
|
||
minNum.value = skuInfo.min_num;
|
||
num.value = minNum.value;
|
||
originPrice.value = skuInfo.price;
|
||
banner.value = [skuInfo.icon];
|
||
icon.value = skuInfo.icon;
|
||
describe.value = skuInfo.description || spuDesc.value;
|
||
}
|
||
} else {
|
||
// 如果没有找到sku,重置状态
|
||
// stock.value = 0;
|
||
num.value = 0;
|
||
}
|
||
prepay('init');
|
||
console.log();
|
||
};
|
||
|
||
// 重构:递归收集所有skuid
|
||
const recursion = (items, ids = []) => {
|
||
items.forEach((item) => {
|
||
if (item.skuid) {
|
||
ids.push(item.skuid);
|
||
}
|
||
if (item.sub_spec && item.sub_spec.spec) {
|
||
recursion(item.sub_spec.spec, ids);
|
||
}
|
||
});
|
||
return ids;
|
||
};
|
||
|
||
// 获取预计算价格
|
||
const prepay = (e) => {
|
||
// let id = '';
|
||
// if (spuSubIndex.value !== null) {
|
||
// id = spuSubData.value.spec[spuSubIndex.value].skuid;
|
||
// } else {
|
||
// id = spuData.value.spec[spuIndex.value].skuid;
|
||
// }
|
||
const selectedSku = getSkuByPath(selectedSpecPath.value, [spuData.value]);
|
||
if (!selectedSku || !selectedSku.skuid) return;
|
||
|
||
const id = selectedSku.skuid;
|
||
console.log(id, 'id===');
|
||
clearTimeout(timer.value);
|
||
timer.value = setTimeout(() => {
|
||
let data = {
|
||
sku_unit_list: [{ sku_id: id, num: num.value - 0 }],
|
||
};
|
||
requestGo({ url: `/h5/v2/shop/common/sku/prepay_amount/1`, data, method: 'post' })
|
||
.then((res) => {
|
||
const result = res.data.prepay_amount_list[0];
|
||
// originPrice.value = result.price_origin;
|
||
freightPrice.value = result.freight;
|
||
loading.value = true;
|
||
if (e == 'init') {
|
||
if (`${result.price}`.includes('.')) {
|
||
let splitPrice = result.price.split('.');
|
||
htmlPrice.value = `${splitPrice[0]}.<span class="font_32">${splitPrice[1]}</span>`;
|
||
} else {
|
||
htmlPrice.value = result.price;
|
||
}
|
||
// if (!stock.value) {
|
||
// num.value = 0;
|
||
// }
|
||
}
|
||
minNum.value = result.min_num;
|
||
skuShip.value = result.ship;
|
||
title.value = result.title;
|
||
console.log(skuShip.value, 'sss');
|
||
if (`${result.price}`.includes('.')) {
|
||
let splitPrice = result.price.split('.');
|
||
htmlTotalPrice.value = `${splitPrice[0]}.<span class="font_32">${splitPrice[1]}</span>`;
|
||
htmlPrice.value = `${splitPrice[0]}.<span class="font_32">${splitPrice[1]}</span>`;
|
||
} else {
|
||
htmlTotalPrice.value = result.price;
|
||
htmlPrice.value = result.price;
|
||
}
|
||
calculating.value = false;
|
||
})
|
||
.catch((err) => {
|
||
console.log(err);
|
||
});
|
||
}, 300);
|
||
};
|
||
|
||
// Sku 数量减少
|
||
const numMinus = () => {
|
||
if (num.value <= 1) {
|
||
return;
|
||
}
|
||
if (num.value <= minNum.value) {
|
||
showToast('不能小于基础购买量');
|
||
return;
|
||
}
|
||
num.value--;
|
||
calculating.value = true;
|
||
prepay('calculate');
|
||
};
|
||
|
||
// Sku 数量增加
|
||
const numAdd = () => {
|
||
// if (num.value >= stock.value) {
|
||
// showToast('超出限购或商品库存上限');
|
||
// return;
|
||
// }
|
||
// if (stock.value < minNum.value) {
|
||
// showToast('库存不足,小于最低购买量');
|
||
// return;
|
||
// }
|
||
num.value++;
|
||
calculating.value = true;
|
||
prepay('calculate');
|
||
};
|
||
// 过滤输入的数字
|
||
const numChange = () => {
|
||
if (num.value < minNum.value) {
|
||
num.value;
|
||
}
|
||
// if (num.value >= stock.value) {
|
||
// num.value = stock.value;
|
||
// }
|
||
if (num.value < minNum.value) {
|
||
num.value = minNum.value;
|
||
}
|
||
// if (stock.value < minNum.value) {
|
||
// num.value = 0;
|
||
// }
|
||
if (num.value) {
|
||
prepay('calculate');
|
||
} else {
|
||
calculating.value = true;
|
||
}
|
||
};
|
||
|
||
// 支付
|
||
const payment = () => {
|
||
const selectedSku = getSkuByPath(selectedSpecPath.value, [spuData.value]);
|
||
|
||
if (!selectedSku || !selectedSku.skuid) {
|
||
showToast('请先选择规格');
|
||
return;
|
||
}
|
||
|
||
const data = {
|
||
id: id.value,
|
||
skuId: selectedSku.skuid,
|
||
spuNum: num.value,
|
||
spuName: getSelectedSpecNames(),
|
||
skuShip: skuShip.value,
|
||
};
|
||
if (num.value <= 0) {
|
||
showToast('请先选择购买数量');
|
||
return;
|
||
}
|
||
|
||
if (policyTitle.value && !isAgreement.value) {
|
||
showToast('请先阅读并同意协议');
|
||
return;
|
||
}
|
||
// if (import.meta.env.MODE === 'development') {
|
||
// router.push({
|
||
// name: 'shopOrderConfirmV2',
|
||
// query: { orderData: JSON.stringify(data) },
|
||
// });
|
||
// return;
|
||
// }
|
||
|
||
// 没有资料先去注册,注册后回到分享的指定页面
|
||
console.log(userStore, 'userStore.agentMobile');
|
||
if (!userStore.agentMobile && id.value != '118' && id.value != '332' && id.value != '489') {
|
||
examineRegister(router.currentRoute.value);
|
||
return;
|
||
}
|
||
|
||
router.push({
|
||
name: 'shopOrderConfirm',
|
||
query: { orderData: JSON.stringify(data) },
|
||
});
|
||
};
|
||
|
||
const selectSku = (index) => {
|
||
if (spuIndex.value == index) {
|
||
return;
|
||
}
|
||
htmlTotalPrice.value = '0';
|
||
spuIndex.value = index;
|
||
if (spuData.value.spec[index].sub_spec) {
|
||
spuSubData.value = spuData.value.spec[index].sub_spec;
|
||
spuSubIndex.value = 0;
|
||
} else {
|
||
spuSubData.value = {};
|
||
spuSubIndex.value = null;
|
||
}
|
||
|
||
num.value = 0;
|
||
if (skuIdDataList.value && skuIdDataList.value.length > 0) {
|
||
gainSelectStock();
|
||
}
|
||
|
||
// if (stock.value) {
|
||
num.value = minNum.value;
|
||
calculating.value = true;
|
||
prepay('calculate');
|
||
// }
|
||
};
|
||
|
||
const selectSubSku = (index) => {
|
||
if (spuSubIndex.value == index) {
|
||
return;
|
||
}
|
||
htmlTotalPrice.value = '0';
|
||
spuSubData.value = spuData.value.spec[spuIndex.value].sub_spec;
|
||
spuSubIndex.value = index;
|
||
num.value = 0;
|
||
|
||
if (skuIdDataList.value && skuIdDataList.value.length > 0) {
|
||
gainSelectStock();
|
||
}
|
||
|
||
if (stock.value && stock.value >= minNum.value) {
|
||
num.value = stock.value > minNum.value ? minNum.value : 0;
|
||
calculating.value = true;
|
||
prepay('calculate');
|
||
}
|
||
};
|
||
|
||
const isShowPoster = () => {
|
||
if (canvasData.value.background && canvasData.value.avatar && canvasData.value.pic && canvasData.value.qrcode) {
|
||
openSharePoster.value.isShow();
|
||
}
|
||
};
|
||
|
||
const jumpAgreement = () => {
|
||
router.push({
|
||
name: 'shopAgreement',
|
||
params: { id: policyId.value },
|
||
query: { title: policyTitle.value },
|
||
});
|
||
};
|
||
|
||
// 添加处理路由参数的函数
|
||
const handleRouteSelectPath = () => {
|
||
const selectPathParam = router.currentRoute.value.query.selectPath;
|
||
if (selectPathParam) {
|
||
try {
|
||
// 解析路径参数
|
||
const pathStr = String(selectPathParam);
|
||
const pathArray = pathStr
|
||
.split(',')
|
||
.map(Number)
|
||
.filter((n) => !isNaN(n) && n >= 0);
|
||
|
||
if (pathArray.length > 0) {
|
||
console.log('从路由参数获取选择路径:', pathArray);
|
||
|
||
// 验证路径有效性
|
||
const isValid = validatePath(pathArray);
|
||
if (isValid) {
|
||
selectedSpecPath.value = [...pathArray];
|
||
isRouteSelected.value = true;
|
||
|
||
// 获取选中SKU信息
|
||
const selectedItem = getItemByPath(pathArray);
|
||
console.log(selectedItem, 'selectedItem=');
|
||
if (selectedItem && selectedItem.skuid) {
|
||
currentSkuId.value = selectedItem.skuid;
|
||
console.log(currentSkuId.value, 'currentSkuId.value');
|
||
|
||
// // 查找对应的SKU数据
|
||
// const skuData = skuIdDataList.value.find((item) => item.id === selectedItem.skuid);
|
||
// if (skuData) {
|
||
// updateSkuInfo(skuData);
|
||
// }
|
||
|
||
// 自动展开下一层级
|
||
const autoSelectNextLevel = (currentPath: number[]) => {
|
||
const item = getItemByPath(currentPath);
|
||
if (item && item.sub_spec && item.sub_spec.spec && item.sub_spec.spec.length > 0) {
|
||
const nextPath = [...currentPath, 0];
|
||
const nextItem = getItemByPath(nextPath);
|
||
if (nextItem) {
|
||
selectedSpecPath.value = nextPath;
|
||
autoSelectNextLevel(nextPath);
|
||
}
|
||
}
|
||
};
|
||
|
||
autoSelectNextLevel([...pathArray]);
|
||
console.log('gainSelectStock');
|
||
gainSelectStock();
|
||
}
|
||
} else {
|
||
console.warn('无效的路由路径:', pathArray);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('解析路由参数失败:', error);
|
||
}
|
||
}
|
||
};
|
||
|
||
// 添加路径验证函数
|
||
const validatePath = (path: number[]): boolean => {
|
||
if (!path || path.length === 0) return false;
|
||
|
||
let current = spuData.value;
|
||
|
||
for (let i = 0; i < path.length; i++) {
|
||
const index = path[i];
|
||
|
||
if (!current || !current.spec || !Array.isArray(current.spec) || index < 0 || index >= current.spec.length) {
|
||
return false;
|
||
}
|
||
|
||
const item = current.spec[index];
|
||
if (!item) return false;
|
||
|
||
if (i < path.length - 1) {
|
||
if (!item.sub_spec) return false;
|
||
current = item.sub_spec;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
// 离开时清除生成的海报
|
||
onDeactivated(() => {
|
||
openSharePoster.value.remove();
|
||
});
|
||
|
||
onActivated(() => {});
|
||
|
||
onMounted(() => {
|
||
let route = router.currentRoute.value.params;
|
||
let query = router.currentRoute.value.query;
|
||
// if (id.value != route.id) {
|
||
id.value = route.id;
|
||
loading.value = false;
|
||
showBug.value = false;
|
||
spuIndex.value = 0;
|
||
spuSubIndex.value = null;
|
||
querySkuId.value = query?.sku_id || 0;
|
||
skuIds.value = [];
|
||
getDetail();
|
||
// } else {
|
||
// // 分享用户头像图片转base64
|
||
// imageConversion(`${userStore.agentAvatar}`).then((res) => {
|
||
// canvasData.value.avatar = res;
|
||
// });
|
||
// }
|
||
});
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.ui-shopDetail {
|
||
background: #f4f4f4;
|
||
overflow-y: auto;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.ui-mall-pic {
|
||
width: 100vw;
|
||
height: px2rem(750);
|
||
display: block;
|
||
object-fit: cover;
|
||
object-position: center;
|
||
}
|
||
|
||
:deep(.van-cell) {
|
||
padding: 0 px2rem(2);
|
||
}
|
||
.ui-input {
|
||
width: px2rem(88);
|
||
}
|
||
|
||
.custom-indicator {
|
||
position: absolute;
|
||
right: px2rem(20);
|
||
top: px2rem(20);
|
||
border-radius: px2rem(8);
|
||
padding: px2rem(8) px2rem(14);
|
||
letter-spacing: px2rem(4);
|
||
background: #aaaaaa;
|
||
}
|
||
|
||
.ui-shop-detail-container {
|
||
padding: px2rem(24);
|
||
|
||
.ui-shop-data-box,
|
||
.ui-ExpressDelivery-data-box {
|
||
padding: px2rem(30) px2rem(24);
|
||
background: #ffffff;
|
||
border-radius: px2rem(16);
|
||
margin-bottom: px2rem(24);
|
||
|
||
.ui-price-symbol {
|
||
margin-right: px2rem(2);
|
||
margin-top: px2rem(2);
|
||
}
|
||
|
||
.ui-show-price,
|
||
.ui-price-symbol {
|
||
color: #cc352f;
|
||
}
|
||
|
||
.ui-original-price {
|
||
text-decoration: line-through;
|
||
margin-left: px2rem(16);
|
||
}
|
||
}
|
||
|
||
.ui-ExpressDelivery-data-box {
|
||
.ui-distribution-address:after {
|
||
content: '';
|
||
width: px2rem(2);
|
||
height: px2rem(22);
|
||
background: #d8d8d8;
|
||
position: absolute;
|
||
left: 0;
|
||
top: px2rem(10);
|
||
}
|
||
}
|
||
}
|
||
|
||
.ui-line-icon {
|
||
width: px2rem(310);
|
||
height: px2rem(12);
|
||
display: block;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.ui-line-text {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: px2rem(28);
|
||
transform: translateX(-50%);
|
||
}
|
||
|
||
.ui-detail-introduce {
|
||
padding: px2rem(20) 0 px2rem(120) 0;
|
||
background: #ffffff;
|
||
margin-top: px2rem(30);
|
||
}
|
||
|
||
.ui-bottom-operation {
|
||
width: 100%;
|
||
background: #ffffff;
|
||
padding: px2rem(18) px2rem(24) px2rem(42) 0;
|
||
box-sizing: border-box;
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
border-top: px2rem(2) solid #f5f5f5;
|
||
|
||
.ui-operation-icon-box {
|
||
flex: 1;
|
||
|
||
.ui-operation-icon {
|
||
width: px2rem(44);
|
||
height: px2rem(44);
|
||
display: block;
|
||
margin: 0 auto px2rem(2) auto;
|
||
}
|
||
}
|
||
|
||
.ui-buy-btn {
|
||
width: px2rem(480);
|
||
height: px2rem(88);
|
||
background: #2a63b2;
|
||
border-radius: px2rem(24);
|
||
}
|
||
}
|
||
|
||
.ui-poster-container {
|
||
position: relative;
|
||
position: fixed;
|
||
top: -100000;
|
||
left: 0;
|
||
z-index: -99999;
|
||
border-radius: px2rem(16);
|
||
width: px2rem(482);
|
||
height: px2rem(806);
|
||
padding: 0 px2rem(30) px2rem(30) px2rem(30);
|
||
background: #f7f7f7;
|
||
box-sizing: border-box;
|
||
background-size: cover !important;
|
||
background-position: center !important;
|
||
background-repeat: no-repeat !important;
|
||
|
||
.ui-user-avatar-box {
|
||
width: px2rem(440);
|
||
height: px2rem(48);
|
||
background: #ffffff;
|
||
border-radius: px2rem(40);
|
||
margin-top: px2rem(8);
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
top: px2rem(10);
|
||
z-index: 10;
|
||
|
||
.ui-user-avatar {
|
||
width: px2rem(28);
|
||
height: px2rem(28);
|
||
border-radius: 50%;
|
||
margin-left: px2rem(18);
|
||
}
|
||
|
||
.ui-user-name-box {
|
||
margin-top: px2rem(-6);
|
||
}
|
||
}
|
||
|
||
.ui-poster-pic-box,
|
||
.ui-poster-data-box {
|
||
width: px2rem(450);
|
||
height: px2rem(450);
|
||
border-radius: px2rem(16);
|
||
background: #ffffff;
|
||
position: absolute;
|
||
top: px2rem(80);
|
||
left: px2rem(16);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.ui-poster-pic {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: px2rem(16);
|
||
object-fit: cover;
|
||
object-position: center;
|
||
display: block;
|
||
vertical-align: top;
|
||
}
|
||
}
|
||
|
||
.ui-poster-data-box {
|
||
top: px2rem(546);
|
||
height: px2rem(244);
|
||
|
||
.ui-poster-title {
|
||
width: px2rem(226);
|
||
line-height: px2rem(36);
|
||
max-width: px2rem(226);
|
||
margin-top: px2rem(4);
|
||
}
|
||
|
||
.ui-poster-price,
|
||
.ui-poster-price-symbol {
|
||
color: #cc352f;
|
||
}
|
||
|
||
.ui-poster-price-symbol {
|
||
margin-right: px2rem(2);
|
||
margin-top: px2rem(6);
|
||
}
|
||
|
||
.ui-poster-qrcode-box {
|
||
.ui-poster-qrcode {
|
||
width: px2rem(200);
|
||
height: px2rem(200);
|
||
border-radius: px2rem(16);
|
||
display: block;
|
||
object-fit: cover;
|
||
object-position: center;
|
||
margin-bottom: px2rem(-8);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.ui-bug-box {
|
||
position: relative;
|
||
background: #ffffff;
|
||
padding-bottom: px2rem(60);
|
||
border-radius: px2rem(24);
|
||
|
||
.ui-close-icon {
|
||
position: absolute;
|
||
right: px2rem(24);
|
||
top: px2rem(24);
|
||
z-index: 22;
|
||
width: px2rem(48);
|
||
height: px2rem(48);
|
||
}
|
||
|
||
.ui-buy-detail-box {
|
||
display: flex;
|
||
justify-content: left;
|
||
//height: px2rem(160);
|
||
position: relative;
|
||
padding: px2rem(30) px2rem(30) 0 px2rem(30);
|
||
|
||
.ui-buy-pic {
|
||
width: px2rem(160);
|
||
min-width: px2rem(160);
|
||
height: px2rem(160);
|
||
display: block;
|
||
object-fit: cover;
|
||
object-position: center;
|
||
vertical-align: top;
|
||
margin-right: px2rem(16);
|
||
border-radius: px2rem(8);
|
||
border: px2rem(2) solid #f8f8f8;
|
||
}
|
||
|
||
.ui-buy-title {
|
||
max-width: px2rem(440);
|
||
line-height: px2rem(48);
|
||
}
|
||
|
||
.ui-buy-price {
|
||
//position: absolute;
|
||
//bottom: px2rem(-12);
|
||
}
|
||
}
|
||
|
||
.ui-buy-price-symbol {
|
||
margin-right: px2rem(2);
|
||
margin-top: px2rem(2);
|
||
}
|
||
|
||
.ui-total-price-box {
|
||
padding-top: px2rem(40);
|
||
|
||
.ui-total-price {
|
||
color: #cc352f;
|
||
}
|
||
}
|
||
|
||
.ui-user-input {
|
||
width: px2rem(532);
|
||
box-sizing: border-box;
|
||
border: px2rem(2) solid #f5f5f5;
|
||
border-radius: px2rem(16);
|
||
padding: px2rem(16) px2rem(30);
|
||
}
|
||
|
||
::v-deep(input::-webkit-input-placeholder) {
|
||
font-weight: initial;
|
||
color: #999999;
|
||
}
|
||
|
||
// 去除默认下划线
|
||
::v-deep(.van-cell:after) {
|
||
position: relative;
|
||
}
|
||
|
||
.ui-sku-box {
|
||
padding: px2rem(40) px2rem(30) px2rem(24) px2rem(30);
|
||
.ui-sku-list-v2 {
|
||
height: px2rem(500);
|
||
overflow-y: auto;
|
||
}
|
||
.ui-sku-list {
|
||
.ui-sku-item,
|
||
.ui-sku-item-active {
|
||
padding: px2rem(12) px2rem(24);
|
||
background: #f4f4f4;
|
||
border-radius: px2rem(8);
|
||
margin-right: px2rem(20);
|
||
}
|
||
|
||
.ui-sku-item-active {
|
||
background: #2a63b2;
|
||
}
|
||
|
||
.ui-active-sku {
|
||
background: #e8fff7;
|
||
}
|
||
}
|
||
}
|
||
|
||
.ui-num-box {
|
||
.ui-num-input-box {
|
||
border-radius: px2rem(8);
|
||
border: px2rem(2) solid #ececec;
|
||
|
||
.ui-num-input-minus,
|
||
.ui-num-input-add {
|
||
width: px2rem(56);
|
||
height: px2rem(56);
|
||
text-align: center;
|
||
position: relative;
|
||
|
||
.ui-num-minus,
|
||
.ui-num-minus-v2 {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
}
|
||
|
||
.ui-num-minus {
|
||
top: 43%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.ui-num-input-minus {
|
||
border-right: px2rem(2) solid #ececec;
|
||
}
|
||
|
||
.ui-num-input-add {
|
||
border-left: px2rem(2) solid #ececec;
|
||
}
|
||
|
||
.ui-select-input {
|
||
width: px2rem(44);
|
||
border: none;
|
||
text-align: center;
|
||
padding: px2rem(4) px2rem(20);
|
||
background: initial;
|
||
line-height: px2rem(40);
|
||
}
|
||
}
|
||
|
||
.ui-confirm-btn {
|
||
width: px2rem(638);
|
||
height: px2rem(88);
|
||
background: #2a63b2;
|
||
border-radius: px2rem(24);
|
||
margin: px2rem(28) auto 0 auto;
|
||
}
|
||
|
||
.ui-confirm-bottom-box {
|
||
padding-top: px2rem(28);
|
||
border-top: px2rem(2) solid #eaeaea;
|
||
|
||
.ui-agreement-icon {
|
||
width: px2rem(32);
|
||
height: px2rem(32);
|
||
display: block;
|
||
vertical-align: top;
|
||
margin-right: px2rem(8);
|
||
}
|
||
|
||
.ui-agreement-text {
|
||
color: #2a63b2;
|
||
}
|
||
}
|
||
}
|
||
</style>
|