feat: 下单完成(下一步:订单列表)
This commit is contained in:
parent
5f446bc97a
commit
25f9813687
10
.vscode/extensions.json
vendored
10
.vscode/extensions.json
vendored
@ -3,6 +3,14 @@
|
||||
"Vue.volar",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"EditorConfig.EditorConfig",
|
||||
"esbenp.prettier-vscode"
|
||||
"esbenp.prettier-vscode",
|
||||
"zhuangtongfa.Material-theme",
|
||||
"PKief.material-icon-theme",
|
||||
"ms-vscode.vscode-typescript-next",
|
||||
"pranaygp.vscode-css-peek",
|
||||
"ecmel.vscode-html-css",
|
||||
"formulahendry.auto-rename-tag",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"unocss.unocss"
|
||||
]
|
||||
}
|
||||
|
||||
11
components.d.ts
vendored
11
components.d.ts
vendored
@ -10,15 +10,22 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
VanArea: typeof import('vant/es')['Area']
|
||||
VanButton: typeof import('vant/es')['Button']
|
||||
VanCell: typeof import('vant/es')['Cell']
|
||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanForm: typeof import('vant/es')['Form']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
VanRate: typeof import('vant/es')['Rate']
|
||||
VanNoticeBar: typeof import('vant/es')['NoticeBar']
|
||||
VanPopover: typeof import('vant/es')['Popover']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanSearch: typeof import('vant/es')['Search']
|
||||
VanStepper: typeof import('vant/es')['Stepper']
|
||||
VanSwipe: typeof import('vant/es')['Swipe']
|
||||
VanSwipeItem: typeof import('vant/es')['SwipeItem']
|
||||
VanSwitch: typeof import('vant/es')['Switch']
|
||||
VanTab: typeof import('vant/es')['Tab']
|
||||
VanTabs: typeof import('vant/es')['Tabs']
|
||||
VanUploader: typeof import('vant/es')['Uploader']
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import axios from '@/utils/axios'
|
||||
import user from './user'
|
||||
import shop from './commodity'
|
||||
import shop from './shop'
|
||||
import common from './common'
|
||||
|
||||
const totalApiConfig = { user, shop, common }
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
// 商品维度接口
|
||||
const shop = {
|
||||
// 商品
|
||||
searchCommodityList: ['/index/page/list'], // 获取商品列表接口
|
||||
getCommodityDetail: ['/index/product/detail'], // 获取商品详情
|
||||
getReviewList: ['/comment/list'], // 获取评价接口
|
||||
addCart: ['/shipping/cart/addOrUpdate'], // 添加购物车接口
|
||||
order: ['/order/add'], // 下单
|
||||
// 订单
|
||||
orderList: ['/order/list'], // 订单列表
|
||||
}
|
||||
|
||||
export default shop
|
||||
@ -1,4 +1,5 @@
|
||||
$theme-color: #01cf24;
|
||||
$theme-light-color: #e4fdea;
|
||||
$theme-disabled-color: #cefad5;
|
||||
|
||||
.theme-bg-color {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import api from '@/api'
|
||||
import { closeToast, showLoadingToast, type ToastWrapperInstance } from 'vant'
|
||||
|
||||
interface ApiType {
|
||||
@ -61,3 +62,8 @@ window.useTipDialog = (
|
||||
tipDialogData.show = true
|
||||
tipDialogData.callback = callback
|
||||
}
|
||||
|
||||
// 添加购物车
|
||||
export const handleAddCart = async (skuId: number, num: number = 1) => {
|
||||
await api.shop.addCart.post({ num, skuId })
|
||||
}
|
||||
|
||||
@ -11,24 +11,24 @@
|
||||
</h4>
|
||||
<div class="flex-1 overflow-y-scroll">
|
||||
<van-cell-group class="address-list__container">
|
||||
<van-cell :class="['address-list__item']" v-for="item in addressList" :key="item.id">
|
||||
<van-cell :class="['address-list__item', { 'theme-color': chooseAddressData.id === item.id }]" v-for="item in addressList" :key="item.id" @click="chooseAddressData = item">
|
||||
<template #title>
|
||||
<div class="item__info">
|
||||
<h6 class="text-[.1rem]">{{ item.area }}</h6>
|
||||
<h6 class="text-[.1rem]">{{ item.contry + item.province + item.city + item.district }}</h6>
|
||||
<p class="item__info__detail">{{ item.detail }}</p>
|
||||
<p class="item__info__subtitle text-[.13rem]">{{ item.name }} {{ item.tel }}</p>
|
||||
<p class="item__info__subtitle text-[.13rem]">{{ item.buyerName }} {{ item.buyerPhone }}</p>
|
||||
</div>
|
||||
</template>
|
||||
<template #value>
|
||||
<div class="item__editor text-base">
|
||||
<van-icon v-if="!isManage" name="edit" color="#999" @click="onAddOrEditAddress('edit', item.originData)" />
|
||||
<van-icon v-else name="delete-o" />
|
||||
<van-icon v-if="!isManage" name="edit" color="#999" @click.stop="onAddOrEditAddress('edit', item.originData)" />
|
||||
<van-icon v-else name="delete-o" @click.stop="onDeleteAddress(item.id)" />
|
||||
</div>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<div class="bg-white w-full h-12 p-2 box-border">
|
||||
<button class="block w-full h-full border-none bg-red color-white rounded-[.04rem]">确定</button>
|
||||
<button class="block w-full h-full border-none bg-red color-white rounded-[.04rem]" @click="onSubmit">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
@ -42,12 +42,15 @@ const model = defineModel<boolean>()
|
||||
const addressFormType = defineModel<'add' | 'edit'>('addressFormType')
|
||||
const showAddAddressFormDialog = defineModel<boolean>('showAddAddressFormDialog')
|
||||
const isUpDateAddressList = defineModel<boolean>('isUpDateAddressList')
|
||||
const props = defineProps<{ curAddressData: Recordable<any> }>()
|
||||
const addressList = ref([])
|
||||
const chooseAddressData = ref({})
|
||||
|
||||
const emits = defineEmits(['edit', 'confirm'])
|
||||
|
||||
watch(model, (val) => {
|
||||
val && handleGetAddressData()
|
||||
val && (chooseAddressData.value = { ...props.curAddressData })
|
||||
})
|
||||
|
||||
// 是否需要更新地址列表
|
||||
@ -68,20 +71,26 @@ const onAddOrEditAddress = (type: 'edit' | 'add', data?: any) => {
|
||||
|
||||
const handleGetAddressData = () => {
|
||||
api.user.getAddressList.post<any>().then((res) => {
|
||||
addressList.value = res.data.rows.map((item) => {
|
||||
addressList.value = res.data.rows
|
||||
.filter((item) => item.status !== 'delete')
|
||||
.map((item) => {
|
||||
const originData = { ...item }
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.buyerName,
|
||||
tel: item.buyerPhone,
|
||||
area: item.contry + item.province + item.city + item.district,
|
||||
detail: item.detail,
|
||||
isDefault: item.status === 'default',
|
||||
originData,
|
||||
...originData,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onDeleteAddress = async (id: number) => {
|
||||
await api.user.updateAddress.post({ id, status: 'delete' })
|
||||
handleGetAddressData()
|
||||
}
|
||||
const onSubmit = () => {
|
||||
model.value = false
|
||||
emits('confirm', chooseAddressData.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -94,6 +103,9 @@ const handleGetAddressData = () => {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.theme-color {
|
||||
background: $theme-light-color;
|
||||
}
|
||||
:deep(.van-cell) {
|
||||
.van-cell__title {
|
||||
width: 0;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
<li :class="['all-review__tab-li', { active: item.active }]" v-for="item in tabs" :key="item.value">{{ item.name }}</li>
|
||||
</ul>
|
||||
<ul class="all-review__contain flex-1 overflow-y-scroll">
|
||||
<li class="p-3" v-for="item in reviews" :key="item.id">
|
||||
<review-single />
|
||||
<li class="p-3" v-for="item in list" :key="item.id">
|
||||
<review-single :data="item" />
|
||||
</li>
|
||||
</ul>
|
||||
</van-popup>
|
||||
@ -16,13 +16,13 @@
|
||||
import reviewSingle from './review-single.vue'
|
||||
|
||||
const model = defineModel<boolean>()
|
||||
defineProps<{ list: Recordable<any>[] }>()
|
||||
const tabs = [
|
||||
{ name: '全部', value: 0, active: true },
|
||||
{ name: '最新评价', value: 3, active: false },
|
||||
{ name: '5/4星好评', value: 1, active: false },
|
||||
{ name: '图/视频', value: 2, active: false },
|
||||
]
|
||||
const reviews = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 5 }]
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -3,21 +3,22 @@
|
||||
<h3 class="flex items-center text-sm">
|
||||
<img class="w-8 h-8 rounded-full" src="" alt="" />
|
||||
<div class="ml-1">
|
||||
<p class="">饭**子</p>
|
||||
<p class="mt-0.5 text-xs color-[#666]">2025.08.23</p>
|
||||
<p class="">{{ data.buyerName }}</p>
|
||||
<p class="mt-0.5 text-xs color-[#666]">{{ handleData.formatTime(data.createTime, 'YYYY.MM.DD') }}</p>
|
||||
</div>
|
||||
</h3>
|
||||
<div class="review-content mt-3">
|
||||
<p>公司大丰收东方闪电防守打法四大分三大胜多负少的</p>
|
||||
<p>{{ data.productComment }}</p>
|
||||
<p class="flex items-center mt-2">
|
||||
<img class="w-16 h-16 mr-1 rounded-[4px]" src="" alt="" v-for="(item, index) in list" :key="index" />
|
||||
<img class="w-16 h-16 mr-1 rounded-[4px]" :src="item.commentUrl" alt="" v-for="(item, index) in data.vvCommentDetailEntities" :key="index" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const list = ref(['', ''])
|
||||
import { handleData } from 'lz-utils-lib'
|
||||
withDefaults(defineProps<{ data: any }>(), { data: {} })
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
||||
@ -5,44 +5,113 @@
|
||||
<div class="mb-8">
|
||||
<div class="cart-wrap">
|
||||
<p class="flex justify-between" @click="showAddressList = true">
|
||||
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">张四</span> <b class="font- flex-1">我的详细地址是什么东西的地方的好的么</b><van-icon name="arrow" />
|
||||
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">{{ curAddressData.buyerName }}</span>
|
||||
<b class="font- flex-1">{{ curAddressData.province + curAddressData.city + curAddressData.district + curAddressData.detail }}</b
|
||||
><van-icon name="arrow" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="cart-wrap mt-2">
|
||||
<div class="flex">
|
||||
<img class="w-16 h-16 mr-4" style="border-radius: 0.04rem" src="" alt="" />
|
||||
<p>¥<span>29.9</span></p>
|
||||
<img class="w-16 h-16 mr-4" style="border-radius: 0.04rem" :src="curPageData.imageUrl" alt="" />
|
||||
<div>
|
||||
<p>
|
||||
¥<span>{{ curPageData.price }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<van-stepper v-model="formData.num" input-width=".4rem" button-size=".2rem" min="1" :max="curPageData.num" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cart-cagetory-wrap">
|
||||
<h4>更多系列</h4>
|
||||
<template v-for="(arr, key) in skuData" :key="key">
|
||||
<h4>{{ key }}</h4>
|
||||
<div class="cagetory">
|
||||
<p>手表系列</p>
|
||||
<p>手表系列水</p>
|
||||
<p>手表</p>
|
||||
<p>手表123</p>
|
||||
<p>手表12</p>
|
||||
</div>
|
||||
<h4>颜色</h4>
|
||||
<div class="cagetory">
|
||||
<p>手表系列</p>
|
||||
<p>手表系列水</p>
|
||||
<p>手表</p>
|
||||
<p>手表123</p>
|
||||
<p>手表12</p>
|
||||
<p
|
||||
v-for="item in arr"
|
||||
:key="item.propertyId"
|
||||
:class="{ 'theme-border-color theme-color': item.propertyId === curPropertyIds.find((it) => it.productPropertyName === key).id }"
|
||||
@click="onChooseProperty(item, key)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed bg-white w-full h-12 left-0 bottom-0 p-2 box-border">
|
||||
<button class="block w-full h-full border-none theme-bg-color color-white rounded-[.04rem]">确定</button>
|
||||
<button class="block w-full h-full border-none theme-bg-color color-white rounded-[.04rem]" @click="onSubmit">{{ scene === 'cart' ? '加入购物车' : '立即下单' }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import api from '@/api'
|
||||
|
||||
const model = defineModel<boolean>()
|
||||
const showAddressList = defineModel<boolean>('showAddressList')
|
||||
const props = defineProps<{ list: any[]; curAddressData: Recordable<any>; scene: 'order' | 'cart' }>()
|
||||
const skuData = ref({}) // sku分类,key为属性的类目,value为属性的分类{ 颜色: [{ '黄色'}]}
|
||||
const commodityData = ref({}) // 商品对象, value为每种商品的skuId,图片,销售价,成交价,库存(key为属性id的集合)
|
||||
const curPropertyIds = ref([]) // 当前选中的属性id的集合[{ id: 1, name: '颜色'},{id: 2, name: '重量'}] name是用来赋值的
|
||||
const curPageData = ref({ price: '', imageUrl: '', num: 0 }) // 当前商品页面数据
|
||||
const formData = ref({ skuId: NaN, num: 1 })
|
||||
|
||||
watch(model, (val) => {
|
||||
if (val) {
|
||||
const { result, commodityMap, firstShopIds } = handleGetSkuList(props.list)
|
||||
skuData.value = result
|
||||
commodityData.value = commodityMap
|
||||
curPropertyIds.value = firstShopIds
|
||||
const { pageData, skuId } = handleGetPageData(commodityData.value, curPropertyIds.value)
|
||||
curPageData.value = pageData
|
||||
formData.value = { skuId, num: 1 }
|
||||
}
|
||||
})
|
||||
|
||||
const handleGetSkuList = (list: any[]) => {
|
||||
const result = {} as any // sku分类
|
||||
const commodityMap = {} //
|
||||
let firstShopIds = []
|
||||
list.forEach((item, i) => {
|
||||
const commodityValue = { id: item.id, imageUrl: item.imageUrl, salePrice: item.salePrice, price: item.promotionPrice, num: item.stock }
|
||||
let commodityPropertyId = ''
|
||||
if (i === 0) {
|
||||
firstShopIds = item.vvSkuPropertyValueList.map((child) => ({ id: child.productPropertyValueId, productPropertyName: child.productPropertyName }))
|
||||
}
|
||||
item.vvSkuPropertyValueList.forEach((item2, index) => {
|
||||
commodityPropertyId += item2.productPropertyValueId + (index < item.vvSkuPropertyValueList.length - 1 ? '_' : '')
|
||||
if (!result[item2.productPropertyName]) result[item2.productPropertyName] = []
|
||||
if (result[item2.productPropertyName].some((child) => child.propertyId === item2.productPropertyValueId)) return
|
||||
result[item2.productPropertyName].push({ propertyId: item2.productPropertyValueId, label: item2.productPropertyValue })
|
||||
})
|
||||
commodityMap[commodityPropertyId] = commodityValue
|
||||
})
|
||||
|
||||
return { result, commodityMap, firstShopIds }
|
||||
}
|
||||
|
||||
const onChooseProperty = (item, categoryName) => {
|
||||
curPropertyIds.value.find((it) => it.productPropertyName === categoryName).id = item.propertyId
|
||||
const { pageData, skuId } = handleGetPageData(commodityData.value, curPropertyIds.value)
|
||||
curPageData.value = pageData
|
||||
formData.value = { skuId, num: 1 }
|
||||
}
|
||||
const handleGetPageData = (commodityData, curPropertyIds) => {
|
||||
const data = commodityData[curPropertyIds.map((item) => item.id).join('_')]
|
||||
return { pageData: { price: data.price, imageUrl: data.imageUrl, num: data.num }, skuId: data.id }
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (props.scene === 'cart') {
|
||||
await api.shop.addCart.post(formData.value)
|
||||
showToast('加入购物车成功')
|
||||
} else {
|
||||
await api.shop.order.post({ buyerAddressId: 2, vvTradeOrderLineDTOList: [formData.value] })
|
||||
showToast('下单成功')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -63,6 +132,8 @@ const showAddressList = defineModel<boolean>('showAddressList')
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
& > p {
|
||||
border: 1px solid #f2f2f2;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
height: 0.28rem;
|
||||
line-height: 0.28rem;
|
||||
@ -72,6 +143,9 @@ const showAddressList = defineModel<boolean>('showAddressList')
|
||||
border-radius: 0.04rem;
|
||||
margin-right: 0.08rem;
|
||||
margin-bottom: 0.08rem;
|
||||
&.theme-border-color {
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,27 +1,37 @@
|
||||
<template>
|
||||
<div id="commodity-detail">
|
||||
<header class="h-70 bg-[#aaa]"></header>
|
||||
<header class="h-70 bg-[#aaa]">
|
||||
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
|
||||
<van-swipe-item><img class="h-full w-full" :src="detail.mainImg" alt="" /></van-swipe-item>
|
||||
<van-swipe-item v-if="detail.video">{{ detail.video }}</van-swipe-item>
|
||||
<van-swipe-item v-for="img in detail.subImgs" :key="img">{{ img }}</van-swipe-item>
|
||||
</van-swipe>
|
||||
</header>
|
||||
<main>
|
||||
<div class="detail-info wrap">
|
||||
<h2 class="text-2xl color-[#000]">陕西珍珠首饰项链</h2>
|
||||
<h4 class="mt-2 text-sm">副标题</h4>
|
||||
<h2 class="text-2xl color-[#000]">{{ detail.title }}</h2>
|
||||
<!-- <h4 class="mt-2 text-sm">副标题</h4>
|
||||
<ul class="detail-wrap">
|
||||
<li><span>配送</span> <em>立即下单,预计最快今天23:00发货</em></li>
|
||||
<li><span>服务</span> <button>7天无理由退款</button></li>
|
||||
</ul>
|
||||
</ul> -->
|
||||
</div>
|
||||
<div class="review-info wrap">
|
||||
<h3 class="wrap-title"><b>用户评价(45.6万+)</b><span @click="onShowAllReview">全部评价 ></span></h3>
|
||||
<h3 class="wrap-title">
|
||||
<b>用户评价({{ reviews.length }}+)</b><span @click="onShowAllReview">全部评价 ></span>
|
||||
</h3>
|
||||
<div class="mt-5">
|
||||
<review-single />
|
||||
<review-single :data="reviews[0]" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<h3 class="wrap-title"><b>商品详情</b><span>查看全部信息</span></h3>
|
||||
<info-table class="mt-3" />
|
||||
<h3 class="wrap-title">
|
||||
<b>商品详情</b>
|
||||
<!-- <span>查看全部信息</span> -->
|
||||
</h3>
|
||||
<!-- <info-table class="mt-3" /> -->
|
||||
<div class="imgs">
|
||||
<img class="w-full h-40" src="" alt="" />
|
||||
<img class="w-full h-40" src="" alt="" />
|
||||
<img v-for="img in detail.detailImgs" :src="img" alt="" class="w-full h-40" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
@ -46,17 +56,18 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex-1 button-wrap">
|
||||
<button class="bg-orange text-white w-30!">加入购物车</button>
|
||||
<button class="theme-bg-color color-white" @click="onPayNowBtn">立即购买</button>
|
||||
<button class="bg-orange text-white w-30!" @click="onSubmit('cart')">加入购物车</button>
|
||||
<button class="theme-bg-color color-white" @click="onSubmit('order')">立即购买</button>
|
||||
</div>
|
||||
</footer>
|
||||
<shopping-cart v-model="showShopCart" v-model:showAddressList="showAddressList" v-model:curAddressData="curAddressData"></shopping-cart>
|
||||
<all-review v-model="showAllReview"></all-review>
|
||||
<shopping-cart v-model="showShopCart" v-model:showAddressList="showAddressList" v-model:curAddressData="curAddressData" :list="skuList" :scene="cartType"></shopping-cart>
|
||||
<all-review v-model="showAllReview" :list="reviews"></all-review>
|
||||
<address-list
|
||||
v-model="showAddressList"
|
||||
v-model:isUpDateAddressList="isUpDateAddressList"
|
||||
v-model:showAddAddressFormDialog="showAddAddressFormDialog"
|
||||
v-model:addressFormType="addressFormType"
|
||||
:curAddressData="curAddressData"
|
||||
@edit="(val) => (editAddressData = val)"
|
||||
@confirm="(val) => (curAddressData = val)"
|
||||
></address-list>
|
||||
@ -74,7 +85,16 @@ import shoppingCart from './components/shopping-cart.vue'
|
||||
import addressList from './components/address-list.vue'
|
||||
import addressForm from './components/address-form.vue'
|
||||
|
||||
const detail = reactive({
|
||||
mainImg: '',
|
||||
video: '',
|
||||
subImgs: [],
|
||||
detailImgs: [],
|
||||
title: '',
|
||||
})
|
||||
|
||||
const showShopCart = ref(false) // 展示购物车
|
||||
const cartType = ref<'order' | 'cart'>('order')
|
||||
const showAllReview = ref(false) // 展示全部评价
|
||||
const showAddressList = ref(false) // 展示收货地址列表
|
||||
const showAddAddressFormDialog = ref(false) // 展示收货地址form
|
||||
@ -85,7 +105,9 @@ const curAddressData = ref({}) // 当前选中的收货地址
|
||||
|
||||
const route = useRoute()
|
||||
const init = () => {
|
||||
handleGetCommodityDetail(+route.query.id)
|
||||
handleGetReviews(+route.query.id)
|
||||
handleGetAddressList()
|
||||
}
|
||||
|
||||
// 查看全部评价
|
||||
@ -93,13 +115,35 @@ const onShowAllReview = () => {
|
||||
showAllReview.value = true
|
||||
}
|
||||
// 点击立即购买按钮
|
||||
const onPayNowBtn = () => {
|
||||
const onSubmit = (type: 'order' | 'cart') => {
|
||||
cartType.value = type
|
||||
showShopCart.value = true
|
||||
}
|
||||
|
||||
// 获取评价
|
||||
const reviews = ref([])
|
||||
const handleGetReviews = (productId: number) => {
|
||||
api.shop.getReviewList.post({ productId }).then((res) => {
|
||||
console.log(res)
|
||||
api.shop.getReviewList.post<any>({ productId }).then((res) => {
|
||||
reviews.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const skuList = ref([])
|
||||
// 获取商品详情
|
||||
const handleGetCommodityDetail = (productId: number) => {
|
||||
api.shop.getCommodityDetail.post<any>({ productId }).then((res) => {
|
||||
detail.mainImg = res.data.mainImageUrl
|
||||
detail.video = res.data.videoUrl
|
||||
detail.subImgs = res.data.vvProductDetailList.filter((item) => item.type === 1)?.map((item) => item.testzc)
|
||||
detail.detailImgs = res.data.vvProductDetailList.find((item) => item.type === 2)?.testzc
|
||||
detail.title = res.data.title
|
||||
skuList.value = res.data.vvSkuList
|
||||
})
|
||||
}
|
||||
|
||||
const handleGetAddressList = () => {
|
||||
api.user.getAddressList.post<any>({}).then((res) => {
|
||||
curAddressData.value = res.data.rows.find((item) => item.status === 'default')
|
||||
})
|
||||
}
|
||||
init()
|
||||
@ -108,6 +152,9 @@ init()
|
||||
<style scope lang="scss">
|
||||
#commodity-detail {
|
||||
background: #f2f2f2;
|
||||
.my-swipe {
|
||||
height: 100%;
|
||||
}
|
||||
.wrap {
|
||||
margin: 0.08rem 0.12rem;
|
||||
border-radius: 0.12rem;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<script setup lang="ts">
|
||||
const list = [
|
||||
{ title: '搜索结果', path: 'search-container' },
|
||||
{ title: '商品详情', path: 'commodity-detail' },
|
||||
{ title: '商品详情', path: 'commodity-detail', query: { id: 4 } },
|
||||
{ title: '我的订单', path: 'order' },
|
||||
{ title: '订单详情', path: 'order/detail' },
|
||||
{ title: '评价中心', path: 'review/center' },
|
||||
@ -18,7 +18,7 @@ const list = [
|
||||
|
||||
const router = useRouter()
|
||||
const onClick = (item: any) => {
|
||||
router.push({ name: item.path })
|
||||
router.push({ name: item.path, query: item.query })
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -58,6 +58,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import { showToast } from 'vant'
|
||||
|
||||
const searchValue = ref('')
|
||||
@ -122,6 +123,22 @@ const router = useRouter()
|
||||
const goDetail = (id: number) => {
|
||||
router.push({ path: '/order/detail', query: { id } })
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
handleGetList()
|
||||
}
|
||||
|
||||
const handleGetList = () => {
|
||||
api.shop.orderList.post().then((res) => {
|
||||
orders.value = res.data.map((item) => ({
|
||||
id: item.id,
|
||||
storeName: item.title,
|
||||
}))
|
||||
console.warn('----- my data is res: ', res)
|
||||
})
|
||||
}
|
||||
|
||||
init()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
<van-search class="flex-1 p-0!" background="#f2f2f2" v-model="searchValue" placeholder="请输入搜索关键词" @search="onSearch(searchValue)" />
|
||||
<van-icon name="shopping-cart-o" size=".2rem" class="ml-2" />
|
||||
</header>
|
||||
<van-tabs v-model:active="searchSort" sticky :color="appStore.themeColor" @change="onChangeSort">
|
||||
<van-tabs v-model:active="searchSort" sticky :color="appStore.themeColor" @click="onChangeSort(searchSort)">
|
||||
<van-tab title="综合" name="0"></van-tab>
|
||||
<van-tab title="销量" name="1"></van-tab>
|
||||
<van-tab title="价格" name="2"></van-tab>
|
||||
</van-tabs>
|
||||
<ul class="search-condition bg-white pt-2 flex-1 overflow-y-scroll">
|
||||
<li v-for="item in searchList" :key="item.id" class="flex item-center p-2 relative" @click="onGoDetail(item.id)">
|
||||
<li v-for="item in searchList" :key="item.productId" class="flex item-center p-2 relative" @click="onGoDetail(item.productId)">
|
||||
<img :src="item.mainImageUrl" alt="" class="w-24 h-24" />
|
||||
<div class="ml-2">
|
||||
<h4 class="text-[.13rem]">{{ item.title }}</h4>
|
||||
@ -27,7 +27,18 @@
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<van-icon name="add" :color="appStore.themeColor" size=".2rem" class="absolute! right-3 bottom-6 h-5" />
|
||||
<van-icon
|
||||
name="add"
|
||||
:color="appStore.themeColor"
|
||||
size=".2rem"
|
||||
class="absolute! right-3 bottom-6 h-5"
|
||||
@click="
|
||||
(e) => {
|
||||
e.stopPropagation()
|
||||
handleAddCart(item.skuId)
|
||||
}
|
||||
"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -35,10 +46,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import { handleAddCart } from '@/utils/page'
|
||||
import useAppStore from '@/stores/modules/app'
|
||||
const route = useRoute()
|
||||
const searchValue = ref(route.query.initValue as string)
|
||||
const searchSort = ref('0')
|
||||
const priceSort = ref('DESC')
|
||||
|
||||
const searchList = ref([])
|
||||
|
||||
@ -51,9 +64,25 @@ const onGoDetail = (id: number) => {
|
||||
|
||||
const onSearch = async (searchValue: string, sort = '0') => {
|
||||
searchSort.value = sort
|
||||
const result = await api.shop.searchCommodityList.post<any>({ productName: searchValue, frontPage: 0, isTest: 0, sort: searchSort.value }) // testzc排序
|
||||
let sortParams = {}
|
||||
// ASC: 升序, DESC: 降序
|
||||
if (sort === '0') {
|
||||
// 综合
|
||||
priceSort.value = 'DESC'
|
||||
sortParams = { createTimestampSort: 'DESC' }
|
||||
} else if (sort === '1') {
|
||||
// 销量
|
||||
priceSort.value = 'DESC'
|
||||
sortParams = { salePriceSort: 'DESC' }
|
||||
} else if (sort === '2') {
|
||||
// 价格
|
||||
priceSort.value = priceSort.value === 'ASC' ? 'DESC' : 'ASC'
|
||||
sortParams = { priceSort: priceSort.value }
|
||||
}
|
||||
const result = await api.shop.searchCommodityList.post<any>({ productName: searchValue, frontPage: 0, isTest: 0, ...sortParams }) // testzc排序
|
||||
searchList.value = result.data.rows.map((item) => ({
|
||||
id: item.id,
|
||||
skuId: item.skuId,
|
||||
productId: item.productId,
|
||||
title: item.title,
|
||||
mainImageUrl: item.mainImageUrl,
|
||||
originPrice: String(item.showSalePrice),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user