256 lines
7.0 KiB
Vue
Raw Normal View History

<template>
2025-05-27 11:58:55 +08:00
<div class="c-goods-item-warp" @click="toDetail(data.id, data.parentId)">
<div class="goods-img">
2025-06-11 17:37:35 +08:00
<img :src="processedGoodUrl" alt="" style="width: 100%" />
2025-05-22 16:11:32 +08:00
<!-- <el-image :src="encodeURIComponent(data.goodUrl) ? encodeURIComponent(data.goodUrl) : ''" fit="cover" @error="handleImageError" />-->
</div>
<div class="goods-name txt-ellipsis clamp2">{{ data.goodName }}</div>
<div class="goods-do">
2025-06-09 10:59:28 +08:00
<div class="price txt-ellipsis clamp">{{ data.goodPrice }}</div>
2025-06-10 18:19:58 +08:00
<div class="do" @click.stop="openDialog(data)">
<div class="iconfont icon-cart"></div>
</div>
</div>
</div>
2025-06-10 18:19:58 +08:00
<el-dialog v-model="centerDialogVisible" title="Warning" width="80%" align-center :show-close="false" style="border-radius: 16px">
<template #header>
2025-06-11 14:38:40 +08:00
<div style="display: flex; justify-content: space-between; padding: 0 20px" @click="centerDialogVisible = false">
<div style="font-size: 20px">商品购买</div>
2025-06-10 18:19:58 +08:00
<el-icon size="25" style="cursor: pointer"><Close /></el-icon>
</div>
</template>
<template #default>
2025-06-11 14:38:40 +08:00
<div style="padding: 0 20px 20px 20px; text-align: left">
2025-06-10 18:19:58 +08:00
<div style="text-align: left; display: flex">
<img :src="currentGood.goodUrl" style="width: 120px" alt="" />
<div style="margin-left: 15px; display: flex; flex-direction: column; justify-content: space-around">
<div style="font-size: 20px; color: #25bf82">{{ currentGood.netWeight ? currentGood.netWeight[0].goodPrice : 0 }}</div>
<div style="font-size: 18px; color: black">{{ currentGood.goodName }}</div>
</div>
</div>
<div class="dialogSubTitle">选择规格</div>
<div class="weight">
<div
v-for="(item, index) in currentGood.netWeight"
:key="item.id"
:class="{ weightActive: currentWeight === index }"
@click="currentWeight = index"
>
{{ item.goodSpecs }}{{ item.unit }}
</div>
</div>
<div class="dialogSubTitle">购买数量</div>
<el-input-number v-model="buyCount" :min="1" :max="10" style="margin-top: 20px" />
</div>
</template>
<template #footer>
<div class="dialog-footer" style="text-align: center">
<el-button class="btnBottom" style="background-color: #25bf82" @click="buyGood">立即购买</el-button>
<el-button class="btnBottom" style="background-color: #ffbe4d" @click="addGoodToCart">加入购物车</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
2025-05-22 16:11:32 +08:00
import { ref, onMounted, computed } from 'vue';
import { isEmpty, getAssetsFile } from '@/utils';
2025-04-09 17:25:08 +08:00
import { useRoute, useRouter } from 'vue-router';
2025-05-22 16:11:32 +08:00
import { encodeURL } from 'js-base64';
2025-06-10 18:19:58 +08:00
import { getGoodDetail } from '@/apis/agricultural.js';
import { addToCart, quicklyBuy } from '@/apis/agricultural.js';
import { useMethodsStore } from '@/store/modules/methods';
import { ElMessage, ElMessageBox } from 'element-plus';
2025-04-09 17:25:08 +08:00
const route = useRoute();
const router = useRouter();
2025-05-22 16:11:32 +08:00
const props = defineProps({
data: {
type: Object,
default: () => {},
},
type: {
type: Number,
default: () => 1,
},
2025-05-22 16:11:32 +08:00
});
2025-06-11 17:37:35 +08:00
const processedGoodUrl = computed(() => {
if (!props.data?.goodUrl) return '';
// 如果包含逗号取第一个URL
if (props.data.goodUrl.includes(',')) {
return props.data.goodUrl.split(',')[0].trim();
}
return props.data.goodUrl;
});
2025-06-10 18:19:58 +08:00
const centerDialogVisible = ref(false);
const currentWeight = ref(0);
2025-05-22 16:11:32 +08:00
const handleImageError = (e) => {
console.error('图片加载失败:', e);
};
2025-06-10 18:19:58 +08:00
const currentGood = ref({});
const buyCount = ref(1);
const methodsStore = useMethodsStore();
2025-06-11 17:37:35 +08:00
onMounted(() => {});
2025-06-10 18:19:58 +08:00
const buyGood = () => {
ElMessageBox.confirm('是否确认直接购买该商品?', '请确认', {
distinguishCancelAndClose: true,
confirmButtonText: '确认',
cancelButtonText: '取消',
}).then(() => {
const obj = {
goodsId: currentGood.value.id,
weightId: currentGood.value.netWeight[currentWeight.value].id, // 规格ID
quantity: buyCount.value,
};
quicklyBuy(obj).then((res) => {
if (res.code === 200) {
router.push({
path: '/sub-operation-service/sureOrder',
query: { id: res.data.id },
});
}
});
});
};
const addGoodToCart = () => {
const obj = {
goodsId: currentGood.value.id,
weightId: currentGood.value.netWeight[currentWeight.value].id, // 规格ID
quantity: buyCount.value,
};
addToCart(obj).then((res) => {
if (res.code === 200) {
centerDialogVisible.value = false;
methodsStore.callOuterMethod();
ElMessage.success('添加成功');
}
});
};
const openDialog = (data) => {
centerDialogVisible.value = true;
getGoodDetail(data.id).then(async (res) => {
if (res.code === 200) {
currentGood.value = res.data;
currentGood.value.id = data.id;
console.log(currentGood.value);
}
});
};
2025-05-27 11:58:55 +08:00
const toDetail = (id, pid) => {
if (props.type === 2) {
router.push('/sub-operation-service/ecommerce-supplier/detail?id=' + id + '&pid=' + pid);
} else {
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail?id=' + id + '&pid=' + pid);
}
2025-04-09 17:25:08 +08:00
};
</script>
<style lang="scss" scoped>
2025-06-10 18:19:58 +08:00
.dialog-footer {
.btnBottom {
height: 60px;
width: 200px;
border-radius: 16px;
font-size: 20px;
font-weight: bold;
color: #ffffff;
}
}
.weight {
display: flex;
justify-content: flex-start;
margin-top: 20px;
text-align: center;
div {
width: 22%;
margin: 0 1%;
font-size: 18px;
padding: 10px 0;
color: #dadada;
border-radius: 8px;
border: 1px solid #dadada;
cursor: pointer;
}
}
.weightActive {
border: 1px solid #25bf82 !important;
color: #25bf82 !important;
}
.dialogSubTitle {
font-size: 20px;
font-weight: bold;
text-align: left;
color: black;
margin-top: 20px;
}
.c-goods-item-warp {
padding: 8px;
2025-05-20 13:05:37 +08:00
width: 100%;
2025-04-12 14:32:47 +08:00
cursor: pointer;
.goods-img {
2025-05-20 13:05:37 +08:00
overflow: hidden;
width: 100%;
height: 168px;
border-radius: 16px;
:deep(.el-image) {
width: 100%;
height: 168px;
}
}
.goods-name {
2025-06-09 10:59:28 +08:00
width: 100%;
margin-top: 8px;
2025-06-09 10:59:28 +08:00
font-size: 1.4em;
height: 2.8em;
color: $color-666;
text-align: left;
}
.goods-do {
display: inline-flex;
justify-content: space-between;
2025-05-20 13:05:37 +08:00
width: 100%;
.price {
2025-05-20 13:05:37 +08:00
padding-right: 8px;
width: calc(100% - 32px);
font-size: 22px;
font-weight: 700;
2025-05-20 13:05:37 +08:00
text-align: left;
color: $color-main;
}
.price::before {
content: ' ¥';
font-size: 16px !important;
font-weight: normal !important;
}
.do {
2025-05-20 13:05:37 +08:00
position: relative;
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
text-align: center;
background: $color-main;
cursor: pointer;
.iconfont {
position: absolute;
top: 50%;
2025-05-20 13:05:37 +08:00
left: 50%;
font-size: 20px;
2025-05-20 13:05:37 +08:00
color: $color-fff;
transform: translate(-50%, -50%);
}
}
}
}
</style>