feat: 商品详情评论+订单详情物流开发

This commit is contained in:
zc 2025-12-04 18:12:00 +08:00
parent 8d5168365d
commit 003f27fb15
6 changed files with 69 additions and 145 deletions

View File

@ -100,4 +100,20 @@ export const apiGetOrderDetail = (data) => {
); );
} }
// 获取订单物流信息
export const apiGetOrderLogistics = (data) => {
return httpRequest.post(
`${baseUrl}/logistics/query`,
data
);
}
// 我的个人中心获取订单数量
export const apiGetOrderCount = (data) => {
return httpRequest.post(
`${baseUrl}/order/count`,
data
);
}

View File

@ -10,31 +10,31 @@
<!-- 用户信息 --> <!-- 用户信息 -->
<view class="user-info"> <view class="user-info">
<view class="user-avatar"> <view class="user-avatar">
<avatar-image :url="item.user.avatar_url" :width="50" /> <avatar-image :url="item.avatar" :width="50" />
</view> </view>
<text class="user-name f-26">{{ item.user.nick_name }}</text> <text class="user-name f-26">{{ item.buyerName }}</text>
</view> </view>
<!-- 评星 --> <!-- 评星 -->
<u-rate active-color="#f4a213" :current="rates[item.score]" :disabled="true" /> <!-- <u-rate active-color="#f4a213" :current="rates[item.score]" :disabled="true" /> -->
<!-- 评价日期--> <!-- 评价日期-->
<view class="flex-box f-22 col-9 t-r">{{ item.create_time }}</view> <view class="flex-box f-22 col-9 t-r">{{ new Date(item.createTime).toLocaleString() }}</view>
</view> </view>
<!-- 评价内容 --> <!-- 评价内容 -->
<view class="item-content m-top20"> <view class="item-content m-top20">
<text class="f-26">{{ item.content }}</text> <text class="f-26">{{ item.productComment }}</text>
</view> </view>
<!-- 评价图片 --> <!-- 评价图片 -->
<view class="images-list clearfix" v-if="item.images.length"> <!-- <view class="images-list clearfix" v-if="item.images.length">
<view class="image-preview" v-for="(image, imgIdx) in item.images" :key="imgIdx"> <view class="image-preview" v-for="(image, imgIdx) in item.images" :key="imgIdx">
<image class="image" mode="aspectFill" :src="image.image_url" @click="onPreviewImages(index, imgIdx)"> <image class="image" mode="aspectFill" :src="image.image_url" @click="onPreviewImages(index, imgIdx)">
</image> </image>
</view> </view>
</view> </view> -->
<!-- 商品规格 --> <!-- 商品规格 -->
<view class="goods-props clearfix"> <view class="goods-props clearfix">
<view class="goods-props-item" v-for="(props, idx) in item.orderGoods.goods_props" :key="idx"> <view class="goods-props-item" v-for="(props, idx) in item.skuInfo" :key="idx">
<text class="group-name">{{ props.group.name }}: </text> <text class="group-name">{{ props.propertyName }}: </text>
<text>{{ props.value.name }}</text> <text>{{ props.propertyValue }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -48,21 +48,10 @@
import AvatarImage from '@/components/avatar-image' import AvatarImage from '@/components/avatar-image'
import { getEmptyPaginateObj, getMoreListData } from '@/core/app' import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
import * as CommentApi from '@/api/comment' import * as CommentApi from '@/api/comment'
import { apiGetCommentList } from '@/api/goods'
const pageSize = 15 const pageSize = 15
const tabs = [{ const tabs = [{ name: `全部`, scoreType: -1 }, { name: `好评`, scoreType: 10 }, { name: `中评`, scoreType: 20 }, { name: `差评`, scoreType: 30 }]
name: `全部`,
scoreType: -1
}, {
name: `好评`,
scoreType: 10
}, {
name: `中评`,
scoreType: 20
}, {
name: `差评`,
scoreType: 30
}]
export default { export default {
components: { components: {
@ -71,119 +60,70 @@
mixins: [MescrollMixin], mixins: [MescrollMixin],
data() { data() {
return { return {
// ID
goodsId: null, goodsId: null,
//
curTab: 0, curTab: 0,
//
list: getEmptyPaginateObj(), list: getEmptyPaginateObj(),
//
total: { all: 0, negative: 0, praise: 0, review: 0 }, total: { all: 0, negative: 0, praise: 0, review: 0 },
//
rates: { 10: 5, 20: 3, 30: 1 }, rates: { 10: 5, 20: 3, 30: 1 },
//
tabs, tabs,
// //
upOption: { upOption: {
// //
auto: true, auto: true,
// ; 10
page: { size: pageSize }, page: { size: pageSize },
// 4 // 4
noMoreSize: 4, noMoreSize: 4,
//
empty: { empty: {
tip: '亲,暂无相关商品评价' tip: '亲,暂无相关商品评价'
} }
}, },
} }
}, },
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) { onLoad(options) {
//
this.goodsId = options.goodsId this.goodsId = options.goodsId
// //
this.getTotal() this.getTotal()
}, },
methods: { methods: {
/** /**
* 上拉加载的回调 (页面初始化时也会执行一次) * 上拉加载的回调 (页面初始化时也会执行一次)
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
* @param {Object} page * @param {Object} page
*/ */
upCallback(page) { upCallback(page) {
const app = this const app = this
// apiGetCommentList({ productId: app.goodsId, scoreType: app.tabs[app.curTab].scoreType, page: page.num }).then(res => {
app.getCommentList(page.num) const data = res.data.map(item => ({
.then(list => { ...item,
const curPageLen = list.data.length skuInfo: JSON.parse(item.skuInfo)
const totalSize = list.total }))
app.mescroll.endBySize(curPageLen, totalSize) app.list.data = getMoreListData({ data }, app.list, page.num)
}) app.mescroll.endBySize(data.length, data.length)
.catch(() => app.mescroll.endErr()) }).catch(() => app.mescroll.endErr())
CommentApi.list({})
}, },
//
getCommentList(pageNo = 1) {
const app = this
return new Promise((resolve, reject) => {
CommentApi.list(app.goodsId, { scoreType: app.getScoreType(), page: pageNo }, { load: false })
.then(result => {
//
const newList = result.data.list
app.list.data = getMoreListData(newList, app.list, pageNo)
resolve(newList)
})
})
},
//
getScoreType() {
return this.tabs[this.curTab].scoreType
},
// //
getTotal() { getTotal() {
const app = this const app = this
CommentApi.total(app.goodsId) CommentApi.total(app.goodsId)
.then(result => { .then(result => {
// tab
const total = result.data.total const total = result.data.total
app.getTabs(total) const tabs = app.tabs
tabs[0].name = `全部(${total.all})`
tabs[1].name = `好评(${total.praise})`
tabs[2].name = `中评(${total.review})`
tabs[3].name = `差评(${total.negative})`
}) })
}, },
// tab
getTabs(total) {
const tabs = this.tabs
tabs[0].name = `全部(${total.all})`
tabs[1].name = `好评(${total.praise})`
tabs[2].name = `中评(${total.review})`
tabs[3].name = `差评(${total.negative})`
},
// //
onChangeTab(index) { onChangeTab(index) {
const app = this const app = this
//
app.curTab = index app.curTab = index
// app.list = getEmptyPaginateObj()
app.onRefreshList()
},
//
onRefreshList() {
this.list = getEmptyPaginateObj()
setTimeout(() => { setTimeout(() => {
this.mescroll.resetUpScroll() app.mescroll.resetUpScroll()
}, 120) }, 120)
}, },
// //
onPreviewImages(dataIdx, imgIndex) { onPreviewImages(dataIdx, imgIndex) {
const app = this const app = this

View File

@ -37,7 +37,6 @@
<script> <script>
import AvatarImage from '@/components/avatar-image' import AvatarImage from '@/components/avatar-image'
import * as CommentApi from '@/api/comment'
import * as GoodsApi from '@/api/goods' import * as GoodsApi from '@/api/goods'
export default { export default {
@ -45,12 +44,10 @@
AvatarImage AvatarImage
}, },
props: { props: {
// ID
goodsId: { goodsId: {
type: Number, type: Number,
default: null default: null
}, },
// 2
limit: { limit: {
type: Number, type: Number,
default: 2 default: 2
@ -58,24 +55,17 @@
}, },
data() { data() {
return { return {
//
isLoading: true, isLoading: true,
//
rates: { 10: 5, 20: 3, 30: 1 }, rates: { 10: 5, 20: 3, 30: 1 },
//
list: [], list: [],
//
total: 0 total: 0
} }
}, },
created() { created() {
//
this.getCommentList() this.getCommentList()
}, },
methods: { methods: {
//
getCommentList() { getCommentList() {
const app = this const app = this
app.isLoading = true app.isLoading = true
@ -88,8 +78,6 @@
app.total = result.data.length app.total = result.data.length
}).finally(() => app.isLoading = false) }).finally(() => app.isLoading = false)
}, },
//
onTargetToComment() { onTargetToComment() {
const app = this const app = this
app.$navTo('pages/comment/index', { goodsId: app.goodsId }) app.$navTo('pages/comment/index', { goodsId: app.goodsId })

View File

@ -34,7 +34,7 @@
</view> </view>
<!-- 物流信息 --> <!-- 物流信息 -->
<view v-if="orderDetail.vvPackageEntity.trackNumber" class="express i-card" @click="handleTargetExpress()"> <view v-if="orderDetail.vvPackageEntity.trackNumber" class="express i-card" @click="handleTargetExpress(orderDetail.vvPackageEntity.trackNumber)">
<!-- <view v-if="order.delivery.length > 1" class="main"> <!-- <view v-if="order.delivery.length > 1" class="main">
<view class="info-item"> <view class="info-item">
<view class="item-content"> <view class="item-content">
@ -295,8 +295,8 @@
}, },
// //
handleTargetExpress() { handleTargetExpress(trackNumber) {
this.$navTo('pages/order/express/index', { orderId: this.orderId }) this.$navTo('pages/order/express/index', { trackNumber })
}, },
// //

View File

@ -2,31 +2,31 @@
<view v-if="!isLoading && express.length" class="container"> <view v-if="!isLoading && express.length" class="container">
<!-- 标签栏 --> <!-- 标签栏 -->
<u-tabs v-if="tabs.length > 1" :list="tabs" :isScroll="true" v-model="curTab" :active-color="appTheme.mainBg" :duration="0.2" bar-width="60" <!-- <u-tabs v-if="tabs.length > 1" :list="tabs" :isScroll="true" v-model="curTab" :active-color="appTheme.mainBg" :duration="0.2" bar-width="60"
@change="onChangeTab"></u-tabs> @change="onChangeTab"></u-tabs> -->
<!-- 商品列表 --> <!-- 商品列表 -->
<view v-show="tabs.length > 1" class="deliver-goods-list i-card clearfix"> <!-- <view v-show="tabs.length > 1" class="deliver-goods-list i-card clearfix">
<view class="goods-item" v-for="(goods, idx) in express[curTab].goods" :key="idx"> <view class="goods-item" v-for="(goods, idx) in express[curTab].goods" :key="idx">
<image class="goods-img" :src="goods.goods.goods_image" alt="商品图片" /> <image class="goods-img" :src="goods.goods.goods_image" alt="商品图片" />
<view class="title">{{ goods.delivery_num }}</view> <view class="title">{{ goods.delivery_num }}</view>
</view> </view>
</view> </view> -->
<!-- 物流信息 --> <!-- 物流信息 -->
<view class="express i-card"> <view class="express i-card">
<view class="info-item"> <view class="info-item">
<view class="item-lable">物流公司</view> <view class="item-lable">物流公司</view>
<view class="item-content"> <view class="item-content">
<text v-if="express[curTab].delivery_method == 20">无需物流</text> <!-- <text v-if="express[curTab].delivery_method == 20">无需物流</text> -->
<text v-else>{{ express[curTab].express ? express[curTab].express.express_name : '--' }}</text> <text>{{ express[curTab].com || '--' }}</text>
</view> </view>
</view> </view>
<view class="info-item"> <view class="info-item">
<view class="item-lable">物流单号</view> <view class="item-lable">物流单号</view>
<view class="item-content"> <view class="item-content">
<text>{{ express[curTab].express_no ? express[curTab].express_no : '--' }}</text> <text>{{ express[curTab].nu || '--' }}</text>
<view v-show="express[curTab].express_no" class="act-copy" @click.stop="handleCopy(express[curTab].express_no)"> <view v-show="express[curTab].nu" class="act-copy" @click.stop="handleCopy(express[curTab].nu)">
<text>复制</text> <text>复制</text>
</view> </view>
</view> </view>
@ -34,8 +34,8 @@
</view> </view>
<!-- 物流轨迹 --> <!-- 物流轨迹 -->
<view class="logis-detail" v-if="express[curTab].traces && express[curTab].traces.length"> <view class="logis-detail" v-if="express[curTab].data && express[curTab].data.length">
<view class="logis-item" :class="{ first: index === 0 }" v-for="(item, index) in express[curTab].traces" :key="index"> <view class="logis-item" :class="{ first: index === 0 }" v-for="(item, index) in express[curTab].data" :key="index">
<view class="logis-item-content"> <view class="logis-item-content">
<view class="logis-item-content__describe"> <view class="logis-item-content__describe">
<text class="f-26">{{ item.context }}</text> <text class="f-26">{{ item.context }}</text>
@ -55,26 +55,15 @@
export default { export default {
data() { data() {
return { return {
//
isLoading: true, isLoading: true,
//
curTab: 0, curTab: 0,
// ID trackNumber: null,
orderId: null, express: [{}]
//
express: {}
} }
}, },
computed: { computed: {
tabs() { tabs() {
if (this.express && this.express.length) { if (this.express && this.express.length > 1) {
const test = this.express.map((item, index) => {
return { name: `包裹${index + 1}` }
})
console.log('test', test)
return this.express.map((item, index) => { return this.express.map((item, index) => {
return { name: `包裹${index + 1}` } return { name: `包裹${index + 1}` }
}) })
@ -82,29 +71,19 @@
return [] return []
} }
}, },
onLoad({ trackNumber }) {
/** this.trackNumber = trackNumber
* 生命周期函数--监听页面加载
*/
onLoad({ orderId }) {
this.orderId = orderId
//
this.getExpress() this.getExpress()
}, },
methods: { methods: {
//
getExpress() { getExpress() {
const app = this const app = this
app.isLoading = true app.isLoading = true
OrderApi.express(app.orderId) OrderApi.apiGetOrderLogistics({ trackNumber: app.trackNumber }).then(res => {
.then(result => { app.express = [res.data]
app.express = result.data.express
app.isLoading = false app.isLoading = false
}) })
}, },
// //
handleCopy(value) { handleCopy(value) {
const app = this const app = this
@ -114,7 +93,6 @@
fail: ({ errMsg }) => app.$toast('复制失败 ' + errMsg) fail: ({ errMsg }) => app.$toast('复制失败 ' + errMsg)
}) })
}, },
// //
onChangeTab(index) { onChangeTab(index) {
this.curTab = index this.curTab = index

View File

@ -145,6 +145,7 @@
import SettingKeyEnum from '@/common/enum/setting/Key' import SettingKeyEnum from '@/common/enum/setting/Key'
import SettingModel from '@/common/model/Setting' import SettingModel from '@/common/model/Setting'
import { checkLogin } from '@/core/app' import { checkLogin } from '@/core/app'
import { apiGetOrderCount } from '@/api/order'
// //
const orderNavbar = [ const orderNavbar = [
@ -196,11 +197,12 @@
this.getPageData() this.getPageData()
}, },
// //
getPageData(callback) { async getPageData(callback) {
const app = this const app = this
app.isLoading = true app.isLoading = true
app.assets = { balance: "500.00", points: 1000, coupon: 5 } app.assets = { balance: "500.00", points: 1000, coupon: 5 }
const counts = { payment: 2, delivery: 1, received: 3, refund: 0 } const res = await apiGetOrderCount({})
const counts = { wait_pay: res.data.waitPayCount, wait_shipping: res.data.waitShippingCount, shipping: res.data.shippingCount, refund: 0 }
app.orderNavbar = app.orderNavbar.map(item => { app.orderNavbar = app.orderNavbar.map(item => {
if (item.count != undefined) { if (item.count != undefined) {
item.count = counts[item.id] item.count = counts[item.id]