Browse Source

add mall logic for tid1878

tid1878
刘嘉炜 5 months ago
parent
commit
bcea875894
  1. 48
      src/pages.json
  2. 74
      src/subpackage/mall/components/submit_bar.vue
  3. 29
      src/subpackage/mall/js/api.js
  4. 1623
      src/subpackage/mall/js/wxqrcode.js
  5. 1
      src/subpackage/mall/pages/goods_info.vue
  6. 182
      src/subpackage/mall/pages/modules/order/details_goods.vue
  7. 369
      src/subpackage/mall/pages/modules/order/order_list_item.vue
  8. 158
      src/subpackage/mall/pages/modules/order/product_info.vue
  9. 159
      src/subpackage/mall/pages/modules/order/upload_image.vue
  10. 101
      src/subpackage/mall/pages/modules/pay/product_item.vue
  11. 180
      src/subpackage/mall/pages/modules/pay/self_pickup_addr.vue
  12. 214
      src/subpackage/mall/pages/order/comment_edit.vue
  13. 128
      src/subpackage/mall/pages/order/comment_list.vue
  14. 938
      src/subpackage/mall/pages/order/order_details.vue
  15. 352
      src/subpackage/mall/pages/order/order_list.vue
  16. 423
      src/subpackage/mall/pages/order/request_write.vue
  17. 423
      src/subpackage/mall/pages/pay/order_pay.vue
  18. 841
      src/subpackage/mall/pages/pay/pay_confirm.vue
  19. 57
      src/subpackage/mall/pages/pay/pay_product.vue
  20. BIN
      src/subpackage/mall/static/images/close_333.png
  21. BIN
      src/subpackage/mall/static/images/line.png
  22. BIN
      src/subpackage/mall/static/images/no_venue_order.png
  23. BIN
      src/subpackage/mall/static/images/order/invalid.png
  24. BIN
      src/subpackage/mall/static/images/order/status_0.png
  25. BIN
      src/subpackage/mall/static/images/order/status_1.png
  26. BIN
      src/subpackage/mall/static/images/order/status_2.png
  27. BIN
      src/subpackage/mall/static/images/order/status_3.png
  28. BIN
      src/subpackage/mall/static/images/order/status_4.png
  29. BIN
      src/subpackage/mall/static/images/order/status_5.png
  30. BIN
      src/subpackage/mall/static/images/position.png
  31. BIN
      src/subpackage/mall/static/images/road_sign.png
  32. BIN
      src/subpackage/mall/static/images/star_empty.png
  33. BIN
      src/subpackage/mall/static/images/star_fill.png
  34. BIN
      src/subpackage/mall/static/images/vip_pay.png
  35. BIN
      src/subpackage/mall/static/images/wx_pay.png

48
src/pages.json

@ -1024,6 +1024,54 @@
"navigationBarTitleText": "购物车",
"enablePullDownRefresh": true
}
},
{
"path": "pages/pay/pay_confirm",
"style" : {
"navigationBarTitleText": "确认订单"
}
},
{
"path": "pages/pay/order_pay",
"style" : {
"navigationBarTitleText": "支付订单"
}
},
{
"path": "pages/pay/pay_product",
"style" : {
"navigationBarTitleText": "商品信息"
}
},
{
"path": "pages/order/order_list",
"style" : {
"navigationBarTitleText": "我的订单"
}
},
{
"path": "pages/order/order_details",
"style" : {
"navigationBarTitleText": "订单详情"
}
},
{
"path": "pages/order/request_write",
"style" : {
"navigationBarTitleText": "申请退款"
}
},
{
"path": "pages/order/comment_list",
"style" : {
"navigationBarTitleText": "评价"
}
},
{
"path": "pages/order/comment_edit",
"style" : {
"navigationBarTitleText": "评价"
}
}
]
}

74
src/subpackage/mall/components/submit_bar.vue

@ -0,0 +1,74 @@
<template>
<view class="submit-bar">
<view class="sb-bar">
<view class="sb-view"><text class="sv-text">¥</text>{{price || 0}}</view>
<view class="sb-view" hover-class="hover-active" @click="btnClick">{{btn_txt}}</view>
</view>
</view>
</template>
<script>
export default {
props: {
price: {
default: 0,
},
btn_txt: {
default: '立即支付',
type: String
}
},
data(){
return {
}
},
methods: {
btnClick(){
this.$emit('btn_evemt');
}
}
}
</script>
<style lang="scss">
/*总高度为208upx*/
.submit-bar{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
z-index: 2;
.sb-bar{
@include isPd(10upx);
padding-top: 10upx;
padding-left: 32upx;
padding-right: 24upx;
background-color: #fff;
@include ctf(space-between);
.sb-view{
&:first-child{
flex-grow: 1;
font-size: 48upx;
line-height: 52upx;
color: #ff873d;
@include tHide(1);
.sv-text{
font-size: 38upx;
}
}
&+.sb-view{
flex-shrink: 0;
margin-left: 20upx;
width: 290upx;
height: 88upx;
line-height: 88upx;
text-align: center;
border-radius: 44upx;
font-size: 32upx;
color: #fff;
background-color: #FF873D;
}
}
}
}
</style>

29
src/subpackage/mall/js/api.js

@ -10,9 +10,38 @@ export const MALL_API = {
goodsComment:`${ORIGIN}/shop2/goodsComment`, //商品评价列表
goodsList:`${ORIGIN}/shop2/goodsList`, //商品列表
goodsCateList:`${ORIGIN}/shop2/goodsCateList`, // 商品分类列表
goodsCartNumsEdit:`${ORIGIN}/shop2/goodsCartNumsEdit`, //购物车 - 修改数量
goodsCartDel:`${ORIGIN}/shop2/goodsCartDel`, //购物车 - 删除商品
goodsCartSettlement:`${ORIGIN}/shop2/goodsCartSettlement`, //购物车 - 去结算
goodsOrderUsingStores:`${ORIGIN}/shop2/goodsOrderUsingStores`, //确认订单 - 获取自提门店信息
getLogisticsTime:`${ORIGIN}/shop2/getLogisticsTime`, //确认订单 - 获取自提时间段
getLogisticsAmount:`${ORIGIN}/shop2/getLogisticsAmount`, //确认订单 - 获取运费
goodsOrderConfirm:`${ORIGIN}/shop2/goodsOrderConfirm`, //确认订单 - 提交订单
payInfo:`${ORIGIN}/stadium/order/pay/info`, //订单支付接口-积分优惠券计算
addrList:`${ORIGIN}/user/addr/list`, // 收货地址列表
canPayCard:`${ORIGIN}/userValueCard/current`, //支付时可选储值卡
orderPay:`${ORIGIN}/stadium/order/pay/mini`, // A预约场馆-预约场馆-微信支付[小程序]
orderPayVip:`${ORIGIN}/stadium/order/pay/card`, // A预约场馆-预约场馆-会员卡支付
goodsOrderList:`${ORIGIN}/shop2/goodsOrderList`, //订单 - 列表
goodsOrderInfo:`${ORIGIN}/shop2/goodsOrderInfo`, //订单 - 详情
goodsOrdeChangeAddr:`${ORIGIN}/shop2/goodsOrdeChangeAddr`, //订单 - 修改地址[未支付订单]
goodsOrderDel:`${ORIGIN}/shop2/goodsOrderDel`, //订单 - 删除
goodsOrderCancel:`${ORIGIN}/shop2/goodsOrderCancel`, //订单 - 取消
goodsOrderAgain:`${ORIGIN}/shop2/goodsOrderAgain`, //订单 - 再来一单
goodsOrderUserTake:`${ORIGIN}/shop2/goodsOrderUserTake`, //订单 - 确认收货
feedbackInfo:`${ORIGIN}/stadium/order/feedback/info`, //售后反馈-页面信息
feedbackSubmit:`${ORIGIN}/stadium/order/feedback/submit`, //售后反馈-提交信息
uploadFeedbackImg:`${ORIGIN}/upload/file/mall_feedback`, // 上传反馈图片
goodsOrdeRefund:`${ORIGIN}/shop2/goodsOrdeRefund`, //订单 - 售后 - 申请退款
goodsOrdeRefundCancel:`${ORIGIN}/shop2/goodsOrdeRefundCancel`, //订单 - 售后 - 撤销退款申请
goodsComment:`${ORIGIN}/shop2/goodsComment`, //商品评价列表
goodsCommentPublish:`${ORIGIN}/shop2/goodsCommentPublish`, //商品评价
}
export default { ORIGIN, MALL_API };

1623
src/subpackage/mall/js/wxqrcode.js
File diff suppressed because it is too large
View File

1
src/subpackage/mall/pages/goods_info.vue

@ -316,6 +316,7 @@ export default {
go_buy: 1,
price_amount: _amount
}
routeTo(`/subpackage/mall/pages/pay/pay_confirm?query=${jsonStr(_query)}&brand_id=${brand_id}`, 'nT');
console.log(_query);
}else{
showModal({content: '购买操作失败,请稍后重试!'});

182
src/subpackage/mall/pages/modules/order/details_goods.vue

@ -0,0 +1,182 @@
<template>
<!-- 订单详情的商品部分 -->
<view class="details-goods">
<image mode="aspectFill" :src="goodsInfo.product_imgs || ''"></image>
<view class="dg-section">
<view class="ds-name">
<view>{{goodsInfo.product_name || '-'}}</view>
<view>
<text>¥</text>
<!--20220225 因为拼团的单价和对应的物品价格对不上所以现在直接用总价除以数量 -->
<text>{{ (goodsInfo.product_price/goodsInfo.product_nums).toFixed(2) || 0}}</text>
</view>
</view>
<view class="ds-line">
<view>{{specText}}</view>
<view>×{{goodsInfo.product_nums || 0}}</view>
</view>
<view class="ds-price">
<text>实付¥</text>
<!--20220225 实付金额=总价-优惠券金额-积分抵扣金额-会员卡抵扣金额(拼团时包含团长折扣金额) -->
<text>{{(goodsInfo.product_price-goodsInfo.product_price_pay-goodsInfo.product_integral_price_pay-goodsInfo.product_discount_price_pay).toFixed(2) || 0}}</text>
</view>
<view class="ds-btn" v-if="isRefund">
<view hover-class="hover-active" @click="refundChange">申请退款</view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
goodsInfo: {
type: Object,
default: ()=>({})
},
orderData: {
type: Object,
default: ()=>({})
}
},
computed: {
specText(){
let { goodsInfo } = this
if(goodsInfo.product_spec_multi == 1){
let specStr = (goodsInfo.product_spec_multi_info.spec_info).join(";")
return specStr;
}
return '';
},
isRefund(){
let status = this.orderData.order_info.status
if(status == 2 || status == 3 || status == 4) return true;
else return false;
},
},
methods: {
refundChange(){
let { orderData, goodsInfo } = this
if(orderData.order_info.status == 4 && orderData.refund_btn_show == 0){
this.$emit('refundChange',{refund_btn_show: false,refund_day: orderData.refund_day });
return;
}
if(orderData.order_info.status == 2 || orderData.order_info.status == 3 || (orderData.order_info.status == 4 && orderData.refund_btn_show == 1)){
let _arr = []
_arr.push({
product_cart_id: goodsInfo.product_cart_id,
product_id: goodsInfo.product_id,
number: goodsInfo.product_nums,
})
let _list = []
_list.push(this.goodsInfo)
let _query = {
feedbackDetail: _arr,
order_no: orderData.order_info.order_no,
goods_list: _list,
isBatch: false,
}
this.$emit('refundChange',{refund_btn_show: true, query: _query});
}
},
},
}
</script>
<style lang="scss">
.details-goods{
width: 100%;
margin-top: 30rpx;
padding-bottom: 30rpx;
border-bottom: 2rpx solid #F2F2F7;
display: flex;
flex-direction: row;
justify-content: flex-start;
>image{
flex-shrink: 0;
margin-right: 20rpx;
width: 180rpx;
height: 180rpx;
border-radius: 10rpx;
}
.dg-section{
flex-grow: 1;
.ds-name{
display: flex;
flex-direction: row;
justify-content: space-between;
>view{
color: #FF873D;
&:first-child{
flex-grow: 1;
color: #333;
font-size: 28rpx;
line-height: 40rpx;
@include tHide(2);
}
&:nth-child(2){
flex-shrink: 0;
margin-left: 62rpx;
line-height: 34rpx;
>text{
color: #FF873D;
&:first-child{
font-size: 24rpx;
}
&:nth-child(2){
font-size: 28rpx;
}
}
}
}
}
.ds-line{
margin: 12rpx 0 14rpx;
@include ctf(space-between);
>view{
color: #9A9A9D;
&:first-child{
flex-grow: 1;
font-size: 24rpx;
}
&:nth-child(2){
flex-shrink: 0;
font-size: 28rpx;
margin-left: 20rpx;
}
}
}
.ds-price{
>text{
color: #F6843E;
&:first-child{
font-size: 28rpx;
}
&:nth-child(2){
font-size: 36rpx;
font-weight: 700;
}
}
}
.ds-btn{
margin-top: 14rpx;
@include ctf(flex-end);
>view{
padding: 16rpx 0;
width: 192rpx;
color: #9A9A9D;
font-size: 28rpx;
border: 2rpx solid #D8D8D8;
border-radius: 36rpx;
text-align: center;
}
}
}
}
</style>

369
src/subpackage/mall/pages/modules/order/order_list_item.vue

@ -0,0 +1,369 @@
<template>
<view class="ol-list" @click="toDetailChange">
<view class="ol-line">
<view class="ol-address">
<image mode="aspectFit" :src="orderInfo.image || ''"></image>
<view class="oa-view">
<view>{{orderInfo.name || '-'}}</view>
<view>
<text>{{orderInfo.create_at || '-'}}</text>
<text>下单</text>
</view>
</view>
</view>
<view class="ol-status">{{orderInfo.status_text || '-'}}</view>
</view>
<product-info :goodsInfo="orderInfo.goods" :goodsNums="orderInfo.goods_nums"></product-info>
<view class="ol-price">
<text>合计支付</text>
<text>¥</text>
<text>{{orderInfo.pay_amount || 0}}</text>
</view>
<view class="ol-tips" v-if="orderInfo.status == 0">
<text>订单将于</text>
<text>{{orderInfo.close_time ||'分钟'}}</text>
<text>后自动关闭</text>
</view>
<view class="ol-btn">
<view
class="ob1"
hover-class="hover-active"
@click.stop="btnChange(1, orderInfo.status)"
>{{setbtnText(1,orderInfo.status)}}</view>
<view
class="ob2"
hover-class="hover-active"
@click.stop="btnChange(2, orderInfo.status)"
v-if="isBtnStyle2"
>再来一单</view>
<view
class="ob3"
hover-class="hover-active"
@click.stop="btnChange(3, orderInfo.status)"
v-if="isBtnStyle3"
>{{setbtnText(3,orderInfo.status)}}</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import productInfo from './product_info.vue';
import { MALL_API } from "../../../js/api";
import server from "../../../js/server";
export default {
props:{
orderInfo: {
type: Object,
default: ()=>({})
},
brandId: {
type: Number,
default: 0
}
},
components: {
'product-info': productInfo,
},
computed: {
// status 0 1 2 3 4 5 6退 7退 8退
isBtnStyle2(){
let { orderInfo } = this
if(orderInfo.status != 0 )return true;
else return false;
},
isBtnStyle3(){
let { orderInfo } = this
if(orderInfo.status == 0 || orderInfo.status == 2 ||orderInfo.status == 3)return true;
else return false;
},
// id
setProIds(){
let data = this.orderInfo.goods
let arr = []
for(var i in data){
arr.push(data[i].product_id)
}
return arr;
},
},
methods: {
setbtnText(type, status){
// status 0 1 2 3 4 5 6退 7退 8退
if(type == 1){
let arr = ['取消订单','晒单分享','晒单分享','晒单分享','删除订单','删除订单','退款详情','删除订单','删除订单']
return arr[status] || '-';
}
if(type == 3){
let arr = ['继续支付','','确认收货','评价','','','','','']
return arr[status] || '-';
}
},
btnChange(type, status){
let { orderInfo, brandId } = this;
if(type == 1){
// 0 1,2,3 4,5,7,8 6退
if(status == 0) return this.determineOperate(0);
if(status == 1 || status == 2 || status == 3){
let _query = {}
_query['goodsList'] = this.orderInfo.goods || []
return util.routeTo(`/subpackage/mall/pages/order/order_share/order_share?query=${util.jsonStr(_query)}`,'nT');
}
if(status == 4 || status == 5 || status == 7 || status == 8) return this.determineOperate(1);
if(status == 6 ) return console.log("退款详情");
}
//
if(type == 2) return this.getOrderAgain({
brand_id: brandId ?? '',
order_no: orderInfo?.order_no ?? ''
});
if(type == 3){
// 0 2 3
if(status == 0) return this.continuePay();
if(status == 2) return this.determineOperate(2);
if(status == 3){
let _query = {}
_query['goodsList'] = this.orderInfo.goods || []
_query['order_no'] = this.orderInfo.order_no
return util.routeTo(`/subpackage/mall/pages/order/comment_list/comment_list?query=${util.jsonStr(_query)}`,'nT');
}
}
},
toDetailChange(){
let { orderInfo, brandId } = this;
let _qryStr = `order_no=${ orderInfo.order_no }&brand_id=${ brandId }`
util.routeTo(`/subpackage/mall/pages/order/order_details?${_qryStr}`,'nT')
},
determineOperate: util.debounce(function(type){
let { orderInfo, brandId } = this;
// type 0 1 2
util.showModal({
title: '提示',
content: type == 0?'确定取消该订单吗?':type == 1?'确定删除该订单吗?':'确认收货吗',
showCancel: true,
success: modalRes=>{
if(modalRes.confirm){
if(type == 0) this.getOrderCancel({
brand_id: brandId ?? '',
order_no: orderInfo?.order_no ?? ''
});
if(type == 1) this.getOrderDel({
brand_id: brandId ?? '',
order_no: orderInfo?.order_no ?? ''
});
if(type == 2) this.getOrderUserTake({
brand_id: brandId ?? '',
order_no: orderInfo?.order_no ?? ''
});
this.$nextTick(_ => {
this.$emit('defineChange', true)
});
}
}
})
}, 300, 300),
//
continuePay(){
let { orderInfo } = this
// let _query = {}
// _query['goodsList'] = this.orderInfo.goods
// _query['pay_amount'] = this.orderInfo.pay_amount
// _query['order_no'] = this.orderInfo.order_no
// util.routeTo(`../../pay/pay_order/pay_order?query=${util.jsonStr(_query)}`,'nT')
let _query = {}
_query['price'] = orderInfo.pay_amount
_query['order_no'] = orderInfo.order_no
_query['pay_type'] = 4 //
util.routeTo(`/subpackage/mall/pages/pay/order_pay?query=${util.jsonStr(_query)}`,'rT')
},
// -
getOrderDel({ brand_id, order_no }){
// util.showLoad();
server.get({
url: MALL_API.goodsOrderDel,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
// util.hideLoad();
console.log('订单删除: ', res);
util.showNone("操作成功")
});
},
// -
getOrderCancel({ brand_id, order_no }){
// util.showLoad();
server.get({
url: MALL_API.goodsOrderCancel,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
// util.hideLoad();
console.log('订单取消: ', res);
util.showNone("操作成功")
});
},
//
getOrderAgain({ brand_id, order_no }){
server.get({
url: MALL_API.goodsOrderAgain,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
console.log('再来一单: ', res);
let { orderInfo } = this;
let _goods = orderInfo?.goods ?? [];
let _query = {}
_query['goodsList'] = _goods;
_query['price_amount'] = orderInfo.amount
_query['product_ids'] = _goods.map(item=>item.id);
_query['go_buy'] = 1
util.routeTo(`/subpackage/mall/pages/pay/pay_confirm?query=${util.jsonStr(_query)}&brand_id=${brand_id}`,'nT')
});
},
//
getOrderUserTake({ brand_id, order_no }){
// util.showLoad();
server.get({
url: MALL_API.goodsOrderUserTake,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
// util.hideLoad();
console.log('确认收货: ', res);
util.showNone("操作成功")
});
},
},
}
</script>
<style lang="scss">
.ol-list{
margin: 0 24rpx 24rpx;
padding: 22rpx 20rpx 30rpx;
background-color: #fff;
border-radius: 10rpx;
.ol-line{
display: flex;
flex-direction: row;
justify-content: space-between;
padding-bottom: 24rpx;
margin-bottom: 32rpx;
border-bottom: 2rpx solid #D8D8D8;
.ol-address{
flex-grow: 1;
display: flex;
flex-direction: row;
justify-content: flex-start;
>image{
flex-shrink: 0;
margin-right: 14rpx;
width: 40rpx;
height: 40rpx;
border-radius: 10rpx;
}
.oa-view{
flex-grow: 1;
>view{
&:first-child{
color: #333;
font-size: 28rpx;
@include tHide(1);
}
&:nth-child(2){
color: #9A9A9D;
font-size: 24rpx;
margin-top: 12rpx;
>text{
&:first-child{
}
&:nth-child(2){
margin-left: 30rpx;
}
}
}
}
}
}
.ol-status{
flex-shrink: 0;
color: #009874;
font-size: 28rpx;
}
}
.ol-price{
margin: 36rpx 0 10rpx;
flex-grow: 1;
text-align: right;
>text{
line-height: 40rpx;
color: #333;
&:first-child{
font-size: 28rpx;
}
&:nth-child(2){
font-size: 24rpx;
}
&:nth-child(3){
font-size: 32rpx;
}
}
}
.ol-tips{
flex-grow: 1;
padding-bottom: 4rpx;
@include ctf(flex-end);
>text{
font-size: 24rpx;
&:first-child{
color: #9A9A9D;
}
&:nth-child(2){
color: #E60213;
}
&:nth-child(3){
color: #9A9A9D;
}
}
}
.ol-btn{
flex-grow: 1;
margin-top: 26rpx;
@include ctf(flex-end);
>view{
width: 192rpx;
padding: 16rpx 0;
font-size: 28rpx;
text-align: center;
border-radius: 36rpx;
margin-left: 20rpx;
}
.ob1{
color: #9A9A9D;
border: 2rpx solid #D8D8D8;
}
.ob2{
color: #009874;
border: 2rpx solid #009874;
}
.ob3{
color: #fff;
padding: 18rpx 0;
background: linear-gradient(90deg, #44D7B6 0%, #009874 100%);
}
}
}
</style>

158
src/subpackage/mall/pages/modules/order/product_info.vue

@ -0,0 +1,158 @@
<template>
<!-- 订单列表和售后列表的商品部分 -->
<view class="product-info">
<view >
<!-- 2件商品以上 -->
<block v-if="goodsInfo.length > 1">
<view class="pi-list" v-for="(e, i) in goodsInfo" :key="i" v-if="i < 3">
<view class="pl-box">
<image mode="aspectFill" :src="e.product_imgs || '-'"></image>
<view v-if="e.product_refund != 0 && !isRefund">{{setStatus(e.product_refund)}}</view>
</view>
<view class="pl-txt">{{e.product_name || '-'}}</view>
</view>
</block>
<!-- 1件商品 -->
<view class="pi-item" v-for="(e, i) in goodsInfo" :key="i" v-if="goodsInfo.length == 1">
<view class="pi-box">
<image mode="aspectFill" :src="e.product_imgs || '-'"></image>
<view v-if="e.product_refund != 0 && !isRefund">{{setStatus(e.product_refund)}}</view>
</view>
<view class="pi-txt">{{e.product_name || '-'}}</view>
</view>
</view>
<view>
<text>{{goodsNums || 0}}</text>
<image src="/subpackage/mall/static/images/arrow_9ad.png"></image>
</view>
</view>
</template>
<script>
export default {
props:{
goodsInfo: { //
type: Array,
default() {
return [];
}
},
goodsNums: { //
type: Number,
default: 0,
},
isRefund: {
type: Boolean,
default: false,
}
},
methods: {
setStatus(status){
// status 0退 1退 2退 3退
let arr = ['','退款中','已退款','退款关闭']
return arr[status] || '-';
},
},
}
</script>
<style lang="scss">
.product-info{
@include ctf(space-between);
>view{
&:first-child{
flex-grow: 1;
@include ctf(flex-start);
.pi-list{
margin-right: 20rpx;
.pl-box{
position: relative;
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
>image{
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
}
>view{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40rpx;
background: rgba(0, 0, 0, 0.5);
border-radius: 0rpx 0rpx 10rpx 10rpx;
color: #FFF;
font-size: 20rpx;
text-align: center;
line-height: 40rpx;
}
}
.pl-txt{
margin-top: 6rpx;
color: #333;
font-size: 24rpx;
max-width: 152rpx;
@include tHide(1);
}
}
.pi-item{
display: flex;
flex-direction: row;
justify-content: flex-start;
.pi-box{
flex-shrink: 0;
position: relative;
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
>image{
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
}
>view{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40rpx;
background: rgba(0, 0, 0, 0.5);
border-radius: 0rpx 0rpx 10rpx 10rpx;
color: #FFF;
font-size: 20rpx;
text-align: center;
line-height: 40rpx;
}
}
.pi-txt{
flex-grow: 1;
margin: 0 34rpx 0 22rpx;
color: #333;
font-size: 24rpx;
@include tHide(2);
}
}
}
&:nth-child(2){
flex-shrink: 0;
margin-top: -40rpx;
@include ctf(flex-start);
>text{
color: #9A9A9D;
font-size: 24rpx;
}
>image{
width: 30rpx;
height: 30rpx;
margin-left: 8rpx;
}
}
}
}
</style>

159
src/subpackage/mall/pages/modules/order/upload_image.vue

@ -0,0 +1,159 @@
<template>
<!-- 上传图片 -->
<view class="upload-image">
<view class="ui-tit">
<text>上传图片(选填)</text>
<text>最多3张</text>
</view>
<view class="ui-list">
<view class="ul-box" v-for="(img,i) in imageList" :key="i">
<image class="ub-img" mode="aspectFill" :src="img" :data-src="img" @tap="previewImage"></image>
<image class="ub-icon" src="/subpackage/mall/static/images/close_333.png" @tap="clearImage(i)"></image>
</view>
<view class="ul-add" v-if="imageList.length < 3" @tap="chooseImage">
<view></view>
<view>上传照片</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import { MALL_API } from "../../../js/api";
import server from "../../../js/server";
export default {
data() {
return {
imageList: [],
};
},
methods: {
//
previewImage: function(e) {
var current = e.target.dataset.src
uni.previewImage({
current: current,
urls: this.imageList
})
},
//
clearImage: function(e){
this.imageList.splice(e,1)
this.$nextTick(this.$forceUpdate());
this.$emit('uploadImageChange', this.imageList)
},
//
chooseImage: async function() {
uni.chooseImage({
count: 1,
sizeType: [ 'compressed ' ],
success: (res) => {
util.showLoad();
server.uploadFile({
url: MALL_API.uploadFeedbackImg, //
filePath: res.tempFilePaths[0],
})
.then(e=>{
util.hideLoad();
let _res = util.jsonPar(e.data);
if(_res.code == 0){
this.imageList.push(_res.data.url);
this.$nextTick(this.$forceUpdate());
this.$emit('uploadImageChange', this.imageList)
}else{
console.error('上传图片失败--->',_res);
util.showNone(_res.message || '上传图片失败,请重试!')
}
})
.catch(err=>{
console.error('上传图片失败--->',err);
util.showNone('上传图片失败,稍后重试!')
})
},
})
},
},
}
</script>
<style lang="scss">
.upload-image{
width: 100%;
.ui-tit{
margin-bottom: 30rpx;
>text{
&:first-child{
color: #9A9A9D;
font-size: 28rpx;
}
&:nth-child(2){
color: #333;
font-size: 24rpx;
margin-left: 10rpx;
}
}
}
.ui-list{
@include ctf(flex-start);
.ul-box{
position: relative;
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
margin-right: 20rpx;
.ub-img{
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
}
.ub-icon{
position: absolute;
top: 6rpx;
right: 6rpx;
width: 40rpx;
height: 40rpx;
}
}
.ul-add{
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2rpx solid #D8D8D8;
>view{
&:first-child{
position: relative;
width: 60rpx;
height: 60rpx;
&::before,&::after{
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
width: 60rpx;
height: 6rpx;
background-color: #D8D8D8;
border-radius: 2rpx;
}
&::after{
transform: translate(-50%,-50%) rotateZ(90deg);
}
}
&:nth-child(2){
color: #9A9A9D;
font-size: 28rpx;
margin-top: 25rpx;
}
}
}
}
}
</style>

101
src/subpackage/mall/pages/modules/pay/product_item.vue

@ -0,0 +1,101 @@
<template>
<view class="product-item">
<image mode="aspectFill" :src="goodsInfo.product_imgs || ''"></image>
<view class="pi-section">
<view>{{goodsInfo.product_name || '-'}}</view>
<view>
<view>{{ specText }}</view>
<view>×{{goodsInfo.product_nums || 0}}</view>
</view>
<view>
<text>¥</text>
<text>{{ priceText }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
goodsInfo: {
type: Object,
default: ()=>({})
}
},
computed: {
specText(){
let { goodsInfo } = this
if(goodsInfo.product_spec_multi == 0) return '';
if(goodsInfo.product_spec_multi == 1) return this.setSpec() || '-';
},
priceText(){
let { goodsInfo } = this
if(goodsInfo.product_spec_multi == 0) return goodsInfo.product_spec_single_info.price || 0;
if(goodsInfo.product_spec_multi == 1) return goodsInfo.product_spec_multi_info.price || 0;
return 0;
},
},
methods:{
setSpec(){
let { goodsInfo } = this
if(goodsInfo.product_spec_multi_info.spec_info == null) return '';
return goodsInfo.product_spec_multi_info.spec_info.join(';');
},
}
}
</script>
<style lang="scss">
.product-item{
@include ctf(flex-start);
>image{
flex-shrink: 0;
flex-grow: 0;
width: 180rpx;
height: 180rpx;
border-radius: 10rpx;
}
.pi-section{
flex-grow: 1;
margin-left: 20rpx;
>view{
&:first-child{
color: #333;
font-size: 28rpx;
@include tHide(2);
}
&:nth-child(2){
margin-top: 12rpx;
width: 100%;
@include ctf(space-between);
>view{
color: #9A9A9D;
&:first-child{
font-size: 24rpx;
}
&:nth-child(2){
font-size: 28rpx;
}
}
}
&:nth-child(3){
margin-top: 14rpx;
>text{
color: #FF873D;
&:first-child{
font-size: 28rpx;
}
&:nth-child(2){
font-size: 36rpx;
font-weight: 700;
}
}
}
}
}
}
</style>

180
src/subpackage/mall/pages/modules/pay/self_pickup_addr.vue

@ -0,0 +1,180 @@
<template>
<view class="fixed-mask m-zidx" @touchmove.stop.prevent="moveHandle">
<view class="pc-address-modal">
<view class="pam-close">
<image src="/subpackage/mall/static/images/close_c97.png" @click="selfAddrCloseChange"></image>
</view>
<view class="pam-title">选择自提地点</view>
<scroll-view class="pam-list" scroll-y="true">
<block v-for="(e, i) in selfAddressList" :key="i">
<view class="pl-item" @click="itemChange(e)">
<image src="/subpackage/mall/static/images/position.png"></image>
<view class="pi-section">
<view class="ps-store">
<view class="ps-name">
<view>{{e.venue_name || '-'}}</view>
<!-- <view>3.0k</view> -->
</view>
<view class="ps-address">{{e.venue_addr || '-'}}</view>
</view>
<image
class="ps-icon"
:class="{iconChange: getId(e.id)}"
:src="getId(e.id)?'/subpackage/mall/static/images/selected2.png':''"
></image>
</view>
</view>
<view class="pl-line" >
<view v-for="j in 99" :key="j">
<view class="pl-sign" ></view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
props:{
selfAddressList: {
type: Array,
default() {
return [];
}
},
selfSelectAddr: {
type: Object,
default: ()=>({})
}
},
computed:{
},
data() {
return{
}
},
methods:{
moveHandle(){},
selfAddrCloseChange(){
this.$emit('selfAddrCloseChange')
},
itemChange(e){
let selfPickup = {}
selfPickup["lat"] = e.lat
selfPickup["lng"] = e.lng
selfPickup["store_id"] = e.id
selfPickup["store_name"] = e.venue_name
selfPickup["store_addr"] = e.venue_addr
this.$emit('selfSelectAddrChange', selfPickup);
},
getId(id){
let { selfSelectAddr } = this
if(selfSelectAddr.store_id == id) return true;
else return false;
},
}
}
</script>
<style lang="scss">
.m-zidx{
z-index: 9;
}
.pc-address-modal{
position: absolute;
left: 0;
bottom: 0;
background-color: #fff;
width: 750rpx;
padding: 28rpx 24rpx;
.pam-close{
width: 100%;
@include ctf(flex-end);
>image{
width: 40rpx;
height: 40rpx;
}
}
.pam-title{
width: 100%;
color: #333;
font-size: 32rpx;
font-weight: 700;
text-align: center;
}
.pam-list{
margin: 56rpx 46rpx 0 4rpx;
height: 750rpx;
.pl-item{
display: flex;
flex-direction: row;
justify-content: flex-start;
>image{
flex-shrink: 0;
// flex-grow: 0;
width: 28rpx;
height: 28rpx;
margin-top: 8rpx;
}
.pi-section{
margin-left: 12rpx;
width: 612rpx;
// margin-top: -18rpx;
@include ctf(space-between);
.ps-store{
max-width: 486rpx;
.ps-name{
>view{
font-size: 28rpx;
&:first-child{
color: #333;
}
&:nth-child(2){
color: #9A9A9D;
margin-left: 20rpx;
}
}
}
.ps-address{
color: #9A9A9D;
font-size: 28rpx;
margin-top: 10rpx;
}
}
.ps-icon{
width: 38rpx;
height: 38rpx;
border-radius: 50%;
border: 2rpx solid #D8D8D8;
}
.iconChange{
width: 40rpx;
height: 40rpx;
border: 0rpx solid #fff;
}
}
}
.pl-line{
margin: 30rpx 0 30rpx 34rpx;
width: 618rpx;
flex-wrap: nowrap;
overflow:hidden;
@include ctf(flex-start);
.pl-sign{
// display: inline-block;
width: 8rpx;
height: 2rpx;
margin-left: 6rpx;
background-color: #D8D8D8;
}
}
}
}
</style>

214
src/subpackage/mall/pages/order/comment_edit.vue

@ -0,0 +1,214 @@
<template>
<view class="comment-edit">
<!-- 商品 -->
<view class="ce-goods">
<image mode="aspectFill" :src="optionsQuery.product_imgs"></image>
<view class="cg-name">{{optionsQuery.product_name}}</view>
<view class="cg-price">¥{{optionsQuery.unit_price}}</view>
</view>
<!-- 评分 -->
<view class="ce-score">
<view>
<text>评分</text>
<text>*</text>
<text>{{submit.level}}.0</text>
</view>
<view>
<image v-for="(e,i) in 5" :key="i" :src="i<submit.level?'/subpackage/mall/static/images/star_fill.png':'/subpackage/mall/static/images/star_empty.png'" @click="starChange(i)"></image>
</view>
</view>
<!-- 评价 -->
<view class="ce-appraise">
<textarea class="ca-textarea" @blur="bindTextAreaBlur" placeholder="在此输入您的评价" v-model="submit.description"></textarea>
</view>
<!-- 上传图片 -->
<view class="ce-pic">
<upload-image @uploadImageChange="uploadImageChange"></upload-image>
</view>
<view class="ce-btn">
<view hover-class="hover-active" @click="onSubmit">发布</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import { MALL_API } from "../../js/api";
import server from "../../js/server";
import uploadImage from '../modules/order/upload_image.vue';
export default {
components: {
'upload-image': uploadImage,
},
data() {
return {
isCheck: false,
optionsQuery: {},
submit: {
description: '', //
level: 0, //
images: [],
},
brand_id: '',
}
},
onLoad(options) {
let _bid = options?.brand_id ?? '';
this.brand_id = _bid;
let _query = util.jsonPar(options.query);
this.optionsQuery = _query
},
methods: {
starChange(index){
// this.isCheck = true
this.submit.level = (index + 1)
},
//
bindTextAreaBlur: function(e) {
this.submit.description = e.detail.value
},
//
uploadImageChange: function(e){
console.log("选择的图片: " + e)
let images = e.join(",");
console.log("需要上传的图片: ",images)
this.submit.images = e
},
onSubmit(){
let { optionsQuery, submit, brand_id } = this
if(submit.level < 1) return util.showNone("请选择评价星级");
if(submit.description == '') return util.showNone("请输入您的评价");
util.showLoad();
server.post({
url: MALL_API.goodsCommentPublish,
data: {
brand_id,
product_id: optionsQuery.product_id, //ID
product_order_no: optionsQuery.order_no, //ID
product_comment_level: submit.level, //
product_comment_text: submit.description, //
product_comment_imgs: submit.images, // []
},
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('评价: ', res);
util.showNone("评价成功")
setTimeout(_=>uni.navigateBack({delta: 2}),1200)
});
},
}
}
</script>
<style lang="scss">
.comment-edit{
position: relative;
width: 100%;
@include isPd(150upx);
.ce-goods{
margin: 24rpx;
padding: 40rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
display: flex;
flex-direction: row;
justify-content: flex-start;
>image{
flex-shrink: 0;
width: 180rpx;
height: 180rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.cg-name{
flex-grow: 1;
color: #333;
font-size: 28rpx;
margin-right: 28rpx;
}
.cg-price{
flex-shrink: 0;
color: #333;
font-size: 32rpx;
}
}
.ce-score{
margin: 0rpx 24rpx;
padding: 16rpx 20rpx 40rpx;
border-radius: 10rpx;
background-color: #fff;
>view{
&:first-child{
>text{
font-size: 28rpx;
&:first-child{
color: #9A9A9D;
}
&:nth-child(2){
color: #FF873D;
}
&:nth-child(3){
color: #FF873D;
// font-size: 36rpx;
font-weight: bold;
margin-left: 30rpx;
}
}
}
&:nth-child(2){
margin-top: 40rpx;
flex-grow: 1;
@include ctf(center);
>image{
display: inline-block;
flex-shrink: 0;
width: 84rpx;
height: 84rpx;
}
}
}
}
.ce-appraise{
flex-grow: 1;
margin: 24rpx;
padding: 30rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
.ca-textarea{
width: 100%;
height: 210rpx;
color: #333;
font-size: 28rpx;
}
}
.ce-pic{
margin: 0rpx 24rpx;
padding: 30rpx 20rpx 38rpx;
border-radius: 10rpx;
background-color: #fff;
}
.ce-btn{
position: fixed;
bottom: 0;
padding: 20rpx 0rpx;
@include isPd(20rpx);
width: 100%;
background-color: #fff;
>view{
flex-grow: 1;
margin: 0rpx 24rpx;
padding: 22rpx 0rpx;
color: #FFF;
font-size: 32rpx;
font-weight: 700;
text-align: center;
border-radius: 44rpx;
background: linear-gradient(90deg, #44D7B6 0%, $mColor 100%);
}
}
}
</style>

128
src/subpackage/mall/pages/order/comment_list.vue

@ -0,0 +1,128 @@
<template>
<view class="comment-list">
<view class="cl-item" v-for="(e,i) in goodsList" :key="i" @click="toCommentEdit(e)">
<view class="ci-line">
<image mode="aspectFill" :src="e.product_imgs || ''"></image>
<view class="cl-section">
<view>{{e.product_name || '-'}}</view>
<view>
<image src="/subpackage/mall/static/images/star_empty.png" v-for="i in 5" :key="i"></image>
<view>
<text>¥</text>
<text>{{setPrice(e)}}</text>
</view>
</view>
</view>
</view>
<view class="ci-btn">
<view hover-class="hover-active">评价</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
data() {
return {
goodsList: [],
optionsQuery: {},
brand_id: '',
}
},
onLoad(options) {
this.brand_id = options?.brand_id ?? '';
let _query = util.jsonPar(options.query);
this.goodsList = _query.goodsList
this.optionsQuery = _query
},
methods: {
toCommentEdit(item){
let { optionsQuery, brand_id } = this
let unitPrice = (item.product_price / item.product_nums).toFixed(2)
let _query = {}
_query['order_no'] = optionsQuery.order_no
_query['product_id'] = item.product_id
_query['product_name'] = item.product_name
_query['product_imgs'] = item.product_imgs
_query['unit_price'] = unitPrice
util.routeTo(`/subpackage/mall/pages/order/comment_edit?query=${util.jsonStr(_query)}&brand_id=${brand_id}`,'nT')
},
setPrice(item){
let unitPrice = 0.00
unitPrice = (item.product_price / item.product_nums).toFixed(2)
return unitPrice;
},
}
}
</script>
<style lang="scss">
.comment-list{
width: 100%;
padding-bottom: 24rpx;
.cl-item{
margin: 24rpx 24rpx 0rpx;
padding: 30rpx 20rpx;
border-radius: 10rpx;
background-color: #FFF;
.ci-line{
@include ctf(flex-start);
>image{
flex-shrink: 0;
width: 180rpx;
height: 180rpx;
margin-right: 20rpx;
border-radius: 10rpx;
}
.cl-section{
flex-grow: 1;
>view{
&:first-child{
color: #333;
font-size: 28rpx;
@include tHide(2);
}
&:nth-child(2){
margin-top: 58rpx;
@include ctf(space-between);
>image{
flex-shrink: 0;
display: inline-block;
width: 40rpx;
height: 40rpx;
}
>view{
flex-grow: 1;
text-align: right;
>text{
color: #333;
&:first-child{
font-size: 28rpx;
}
&:nth-child(2){
font-size: 36rpx;
}
}
}
}
}
}
}
.ci-btn{
flex-grow: 1;
margin-top: 30rpx;
@include ctf(flex-end);
>view{
padding: 16rpx 68rpx;
color: #FFF;
font-size: 28rpx;
border-radius: 36rpx;
background: linear-gradient(90deg, #44D7B6 0%, $mColor 100%);
}
}
}
}
</style>

938
src/subpackage/mall/pages/order/order_details.vue

@ -0,0 +1,938 @@
<template>
<view class="order-details">
<view class="od-head">
<view class="oh-view">
<view>{{ setStatus }}</view>
<view>{{ setStatusText }}</view>
</view>
<image :src="setStatusImg"></image>
</view>
<!-- 自提 订单关闭待付款待发货 -->
<view class="od-self" v-if="orderInfo.product_order_self_pickup == 1">
<view class="os-tit">到店自提</view>
<view class="os-line">
<view>
<text>{{ orderInfo.product_order_self_pickup_info.name || '-' }}</text>
<text>{{ orderInfo.product_order_self_pickup_info.phone || '-' }}</text>
</view>
<!-- 待付款 -->
<view v-if="orderInfo.status == 0" @click="isSelfAddressModel = !isSelfAddressModel">修改</view>
</view>
<view class="os-store">{{ orderInfo.product_order_self_pickup_info.store_name || '-' }}</view>
<view class="os-addr">{{ orderInfo.product_order_self_pickup_info.store_addr || '-' }}</view>
<!-- 待发货交易完成退款完成, 其中交易完成和退款完成需要置灰 -->
<view class="os-code" v-if="isCode">
<view class="oc-box">
<image class="oi-qrcode" :class="{ qrcodeChange: isGrayCode }" :src="codeImg || ''"></image>
<!-- 交易完成退款完成 -->
<image v-if="isGrayCode" class="oi-icon" src="/subpackage/mall/static/images/order/invalid.png"></image>
</view>
<view class="oc-tips">到店请出示此二维码给工作人员核销拿取商品</view>
<view class="oc-num" :class="{ numChange: isGrayCode }">
<view>取货码</view>
<view>{{ orderInfo.product_order_self_pickup_info.gcode }}</view>
</view>
</view>
</view>
<!-- 快递 订单关闭待付款 -->
<view class="od-sd" v-if="orderInfo.product_order_self_pickup == 0">
<!-- 待发货 -->
<view class="os-tit" v-if="orderInfo.status == 1">快递收货</view>
<!-- 待收货交易完成退款完成 -->
<view class="os-section" @click="toLogistics" v-if="orderInfo.status == 2 || orderInfo.status == 3">
<view class="os-info">
<view class="oi-line">
<text>快递公司</text>
<text>{{ orderInfo.product_order_goods[0].product_logistics.logistics_name || '-' }}</text>
</view>
<view class="oi-line">
<text>快递单号</text>
<text>{{ orderInfo.product_order_goods[0].product_logistics.logistics_no || '-' }}</text>
<text @click.stop="copyOrder(orderInfo.product_order_goods[0].product_logistics.logistics_no)">复制</text>
</view>
</view>
<image src="/subpackage/mall/static/images/arrow_9ad.png"></image>
</view>
<view class="os-line">
<view>
<text>{{ orderInfo.product_order_custom.name || '-' }}</text>
<text>{{ orderInfo.product_order_custom.phone || '-' }}</text>
</view>
<view v-if="orderInfo.status == 0" @click="toAddressList">修改</view>
</view>
<view class="os-addr">{{ orderInfo.product_order_custom.address || '-' }}</view>
</view>
<!-- 商品详情 -->
<view class="od-info">
<view class="oi-store">
<view>
<image mode="aspectFit" :src="orderInfo.brand_image || ''"></image>
<text>{{ orderInfo.brand_name || '-' }}</text>
</view>
<view @click="phoneCall">联系商家</view>
</view>
<view class="oi-goods" v-for="(e, i) in orderInfo.product_order_goods" :key="i">
<details-goods :goodsInfo="e" :orderData="orderData" @refundChange="refundChange"></details-goods>
</view>
<view class="oi-line">
<view>金额小计</view>
<view>¥{{ orderInfo.product_order_price || 0 }}</view>
</view>
<view class="oi-line" v-if="orderInfo.collage_product_order_leader==true">
<view>团长折扣</view>
<view>-¥{{ orderInfo.collage_leader_discount_amount || 0 }}</view>
</view>
<view class="oi-line">
<view>积分抵扣</view>
<view>-¥{{ orderInfo.deduction_amount || 0 }}</view>
</view>
<view class="oi-line">
<view>折扣金额</view>
<view>-¥{{ orderInfo.discount_amount || 0 }}</view>
</view>
<view class="oi-line">
<view>优惠券优惠</view>
<view>-¥{{ orderInfo.coupons_amount || 0 }}</view>
</view>
<view class="oi-line">
<view>运费</view>
<view>¥{{ orderInfo.product_logistics_price || 0 }}</view>
</view>
<view class="oi-price">
<text>合计支付</text>
<text></text>
<text>{{ orderInfo.pay_amount || 0 }}</text>
</view>
</view>
<!-- 支付信息 -->
<view class="od-pay">
<view class="op-line">
<view>下单时间</view>
<view>{{ orderInfo.created_at || '-' }}</view>
</view>
<view class="op-line">
<view>订单编号</view>
<view>{{ orderInfo.order_no || '-' }}</view>
<view @click="copyOrder(orderInfo.order_no)">复制</view>
</view>
<view class="op-line" v-if="orderInfo.status != 0 && orderInfo.status != 5">
<view>支付方式</view>
<view>{{ orderInfo.pay_type == 0 ? '微信支付' : orderInfo.pay_type == 1 ? '支付宝支付' : orderInfo.pay_type == 2 ? '储值卡支付' : '-' }}</view>
</view>
<view class="op-line" v-if="orderInfo.status != 0 && orderInfo.status != 5">
<view>交易流水号</view>
<view>{{ orderInfo.trade_no || '' }}</view>
</view>
</view>
<!-- 底部按钮 ob-btn1 -->
<view class="od-btn">
<view class="ob-btn1" hover-class="hover-active" @click="btnChange(1, orderInfo.status)" v-if="isBtnStyle1">{{ setbtnText(1, orderInfo.status) }}</view>
<view class="ob-btn2" hover-class="hover-active" @click="btnChange(2, orderInfo.status)" v-if="isBtnStyle2">再来一单</view>
<view class="ob-btn3" hover-class="hover-active" @click="btnChange(3, orderInfo.status)" v-if="isBtnStyle3">{{ setbtnText(3, orderInfo.status) }}</view>
</view>
<!-- 弹框 无法申请退款 -->
<view class="fixed-mask zindex" v-if="isShowRefund" @touchmove.stop.prevent="moveHandle">
<view class="od-refund-modal">
<view class="orm-tit">无法申请退款</view>
<view class="orm-tips">您已错过了申请退款的时间段交易成功后{{refundDay || 0}}天内如果您有退货需求建议您联系客服</view>
<view class="orm-btn" @click="isShowRefund = !isShowRefund">我知道了</view>
</view>
</view>
<!-- 弹框 选择自提地点 -->
<self-pickup-addr
v-if="isSelfAddressModel"
:selfAddressList="selfAddrList"
:selfSelectAddr="selfPickup"
@selfSelectAddrChange="selfSelectAddrChange"
@selfAddrCloseChange="isSelfAddressModel = !isSelfAddressModel"
></self-pickup-addr>
</view>
</template>
<script>
import util from '@/utils/util';
import qrcode from '../../js/wxqrcode';
import { MALL_API } from "../../js/api";
import server from "../../js/server";
import selfPickupAddr from '../modules/pay/self_pickup_addr.vue';
import detailsGoods from '../modules/order/details_goods.vue';
export default {
components: {
'details-goods': detailsGoods,
'self-pickup-addr': selfPickupAddr
},
computed: {
setStatus() {
// 0 1 2 3 4 5 6退 7退 8退
let statusArr = ['待付款', '待发货', '待收货', '交易完成', '交易完成', '订单关闭', '退款中', '退款完成', '退款关闭'];
return statusArr[this.orderInfo.status] || '-';
},
setStatusText() {
let statusArr = [
this.orderInfo.product_order_pay_end_time + '后订单关闭。请及时付款哦~',
'商家正在处理中,请耐心等待商家发货',
'商品已打包完成发货,请耐心等待收货,祝您生活愉快',
'收到货后,如有意见,请联系我们客服哦!',
'收到货后,如有意见,请联系我们客服哦!',
'订单未支付,超时自动关闭',
'请等待商家处理',
'订单已退款完成',
'退款失败,如问题仍未解决,您可重新发起申请'
];
return statusArr[this.orderInfo.status] || '-';
},
setStatusImg() {
let { orderInfo } = this;
let statusArr = [
'/subpackage/mall/static/images/order/status_1.png',
'/subpackage/mall/static/images/order/status_3.png',
'/subpackage/mall/static/images/order/status_3.png',
'/subpackage/mall/static/images/order/status_4.png',
'/subpackage/mall/static/images/order/status_4.png',
'/subpackage/mall/static/images/order/status_0.png',
'/subpackage/mall/static/images/order/status_5.png',
'/subpackage/mall/static/images/order/status_5.png',
'/subpackage/mall/static/images/order/status_5.png'
];
if (orderInfo.product_order_self_pickup == 1 && orderInfo.status == 1) return '/subpackage/mall/static/images/order/status_2.png';
else return statusArr[this.orderInfo.status] || '';
},
//
isBtnStyle1() {
let { orderInfo } = this;
if (orderInfo.status == 0 || orderInfo.status == 1 || orderInfo.status == 2 || orderInfo.status == 3 || orderInfo.status == 4 || orderInfo.status == 5 || orderInfo.status == 7 || orderInfo.status == 8) return true;
else return false;
},
// 0
isBtnStyle2() {
let { orderInfo } = this;
if (orderInfo.status != 0) return true;
else return false;
},
// 0 2 3
isBtnStyle3() {
let { orderInfo } = this;
if (orderInfo.status == 0 || orderInfo.status == 2 || orderInfo.status == 3) return true;
else return false;
},
//
isCode() {
let { orderInfo } = this;
if (orderInfo.status == 1 || orderInfo.status == 3 || orderInfo.status == 4 || orderInfo.status == 6 || orderInfo.status == 7 || orderInfo.status == 8) return true;
else return false;
},
//
isGrayCode() {
let { orderInfo } = this;
if (orderInfo.status == 3 || orderInfo.status == 4 || orderInfo.status == 6 || orderInfo.status == 7 || orderInfo.status == 8) return true;
else return false;
},
//
codeImg() {
let { orderInfo } = this;
if(orderInfo.product_order_self_pickup_code) return qrcode.createQrCodeImg(orderInfo.product_order_self_pickup_code);
},
// 退 feedbackDetail
getFeedbackDetail(){
let { orderInfo } = this
let _list = orderInfo.product_order_goods
let _arr = []
for(var i in _list){
_arr.push({
product_cart_id: _list[i].product_cart_id,
product_id: _list[i].product_id,
number: _list[i].product_nums,
})
}
return _arr;
},
//
getBatchList(){
let { orderInfo } = this
let _list = orderInfo.product_order_goods
let arr = []
for(var i in _list){
if(_list[i].product_nums - _list[i].refund_nums > 0){
_list[i].product_nums = _list[i].product_nums - _list[i].refund_nums
_list[i].goods_nums = _list[i].product_nums
arr.push(_list[i])
}
}
return arr;
},
},
data() {
return {
isShowRefund: false,
isSelfAddressModel: false,
orderInfo: {},
orderData: {},
selfAddrList: [{}, {}],
selfPickup: {} ,//
queryOrderNo: "",
refundDay: 0,
brand_id: '',
};
},
onLoad(options) {
let _bid = options?.brand_id ?? '';
this.queryOrderNo = options.order_no;
this.brand_id = _bid;
},
onShow() {
let { brand_id, queryOrderNo } = this;
this.getOrderDetail({ order_no: queryOrderNo, brand_id });
},
methods: {
moveHandle() {},
toLogistics() {
let { orderInfo } = this;
let logisticsList = [];
for (var i in orderInfo.product_order_goods) {
logisticsList.push(orderInfo.product_order_goods[i].product_logistics);
}
let _query = {};
_query['logistics_list'] = logisticsList;
util.routeTo(`../logistics_info/logistics_info?query=${util.jsonStr(logisticsList)}`, 'nT');
},
setbtnText(type, status) {
// status 0 1 2 3 4 5 6退 7退 8退
if (type == 1) {
let arr = ['取消订单', '申请退款', '批量退款', '批量退款', '删除订单', '删除订单', '删除订单', '删除订单', '删除订单'];
return arr[status] || '-';
}
if (type == 3) {
let arr = ['继续支付', '', '确认收货', '评价', '', '', '', '', ''];
return arr[status] || '-';
}
},
btnChange(type, status) {
let { orderInfo, brand_id } = this;
if (type == 1) {
// 0 1退 2,3退 else
if (status == 0) return this.determineOperate(0);
if (status == 1){
let _query = {
feedbackDetail: this.getFeedbackDetail,
order_no: orderInfo.order_no,
goods_list: orderInfo.product_order_goods,
feedback_type: 0,
}
return util.routeTo(`/subpackage/mall/pages/order/request_write?query=${util.jsonStr(_query)}&brand_id=${brand_id}`, 'nT');
}
if (status == 2 || status == 3) {
let _query = {
order_no: orderInfo.order_no,
goods_list: this.getBatchList,
isBatch: true,
}
return util.routeTo(`../request_service/request_service?query=${util.jsonStr(_query)}`, 'nT');
// util.routeTo(`../request_batch/request_batch?query=${util.jsonStr(_query)}`, 'nT');
} else return this.determineOperate(1);
}
//
if (type == 2) return this.getOrderAgain({ brand_id, order_no: orderInfo?.order_no ?? '' });
if (type == 3) {
// 0 2 3
if (status == 0) return this.continuePay();
if (status == 2) return this.determineOperate(2);
if (status == 3) {
let _query = {};
_query['goodsList'] = orderInfo.product_order_goods || [];
_query['order_no'] = orderInfo.order_no;
util.routeTo(`/subpackage/mall/pages/order/comment_list?query=${util.jsonStr(_query)}&brand_id=${brand_id}`, 'nT');
}
}
},
determineOperate: util.debounce(function(type) {
// type 0 1 2
let { brand_id, orderInfo } = this;
util.showModal({
title: '提示',
content: type == 0 ? '确定取消该订单吗?' : type == 1 ? '确定删除该订单吗?' : '确认收货吗',
showCancel: true,
success: modalRes => {
if (modalRes.confirm) {
let _commonQry = { order_no: orderInfo?.order_no ?? '', brand_id };
if (type == 0) this.getOrderCancel(_commonQry);
if (type == 1) return this.getOrderDel(_commonQry);
if (type == 2) this.getOrderUserTake(_commonQry);
this.$nextTick(_ => {
this.getOrderDetail(_commonQry);
});
}
}
});
},300,300),
//
continuePay() {
let { orderInfo } = this
let _query = {}
_query['price'] = orderInfo.pay_amount
_query['order_no'] = orderInfo.order_no
_query['pay_type'] = 4 //
util.routeTo(`/pages/order_pay/order_pay?query=${util.jsonStr(_query)}`,'rT')
},
// -
getOrderDetail({ order_no, brand_id }) {
util.showLoad();
server.get({
url: MALL_API.goodsOrderInfo,
data: { brand_id, order_no },
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('订单详情: ', res);
this.orderInfo = res.order_info;
this.orderData = res
this.getOrderUsingStores({ order_no, brand_id });
let _selfPickup = {};
_selfPickup['store_id'] = res.order_info.product_order_self_pickup_info.store_id;
_selfPickup['store_name'] = res.order_info.product_order_self_pickup_info.store_name;
_selfPickup['store_addr'] = res.order_info.product_order_self_pickup_info.store_addr;
this.selfPickup = _selfPickup;
});
},
// -
getOrderDel({ brand_id, order_no }) {
// util.showLoad();
server.get({
url: MALL_API.goodsOrderDel,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
// util.hideLoad();
console.log('订单删除: ', res);
util.showNone("操作成功")
setTimeout(_=>uni.navigateBack(), 1200);
});
},
// -
getOrderCancel({ brand_id, order_no }){
util.showLoad();
server.get({
url: MALL_API.goodsOrderCancel,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
util.hideLoad();
console.log('订单删除: ', res);
});
},
//
getOrderAgain({ brand_id, order_no }) {
server.get({
url: MALL_API.goodsOrderAgain,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
console.log('再来一单: ', res);
let { orderInfo } = this;
let _goods = orderInfo?.product_order_goods ?? [];
let _query = {};
_query['goodsList'] = _goods;
_query['price_amount'] = orderInfo.amount;
_query['product_ids'] = _goods.map(item=>item.id);
_query['go_buy'] = 1
util.routeTo(`/subpackage/mall/pages/pay/pay_confirm?query=${util.jsonStr(_query)}&brand_id=${brand_id}`,'nT')
});
},
//
getOrderUserTake({ brand_id, order_no }) {
util.showLoad();
server.get({
url: MALL_API.goodsOrderUserTake,
data: { brand_id, order_no },
failMsg: '请求失败!'
})
.then(res => {
util.hideLoad();
console.log('确认收货: ', res);
});
},
phoneCall() {
let { orderInfo } = this;
let _phoneStr = orderInfo.contact_mobile || '';
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res => {
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
});
}
});
},
copyOrder(data) {
uni.setClipboardData({ data });
},
toAddressList() {
util.routeTo(`/pages/mine/address_list/address_list?back_func=setAddrInfo`, 'nT');
},
setAddrInfo(info) {
this.addressInfo = info;
this.getOrdeChangeAddr(0, info);
},
//
selfSelectAddrChange(e) {
this.selfPickup = e;
this.isSelfAddressModel = false;
console.log('选中的自提门店:', this.selfPickup);
this.getOrdeChangeAddr(1, e);
},
//
getOrdeChangeAddr(type, info) {
// type 0 1
let { orderInfo, brand_id } = this;
let _query = {};
_query['brand_id'] = brand_id;
_query['order_no'] = orderInfo.order_no;
_query['self_pickup'] = orderInfo.product_order_self_pickup;
if (type == 0) {
_query['custom_name'] = info.username;
_query['custom_phone'] = info.mobile;
_query['custom_addr'] = info.province + info.city + info.area + info.addr;
}
if (type == 1) {
_query['store_id'] = info.store_id;
_query['store_name'] = info.store_name;
_query['store_addr'] = info.store_addr;
_query['user_name'] = orderInfo.product_order_self_pickup_info.name;
_query['user_phone'] = orderInfo.product_order_self_pickup_info.phone;
_query['user_gtime'] = orderInfo.product_order_self_pickup_info.gtime;
}
server.post({
url: MALL_API.goodsOrdeChangeAddr,
data: _query,
failMsg: '请求失败!'
})
.then(res => {
console.log('修改地址: ', res);
this.getOrderDetail({ order_no: orderInfo?.order_no ?? '', brand_id });
});
},
//-
getOrderUsingStores({ brand_id, order_no }) {
util.showLoad();
server.get({
url: MALL_API.goodsOrderUsingStores,
data: { brand_id, order_no, gobuy: 1 },
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('确认订单获取自提门店信息: ', res);
if (res != null) {
this.selfAddrList = res;
}
});
},
refundChange(e){
console.log("hi: ",e)
if(!e.refund_btn_show){
this.refundDay = e.refund_day
this.isShowRefund = true
return;
}
if(e.refund_btn_show){
return util.routeTo(`/subpackage/mall/pages/order/request_service/request_service?query=${util.jsonStr(e.query)}`, 'nT');
}
},
}
};
</script>
<style lang="scss">
.order-details {
position: relative;
width: 100%;
@include isPd(130upx);
.od-head {
position: relative;
width: 100%;
height: 160rpx;
background-color: $mColor;
@include ctf(flex-end);
> image {
width: 266rpx;
height: 160rpx;
}
.oh-view {
position: absolute;
left: 44rpx;
top: 22rpx;
margin-right: 44rpx;
> view {
&:first-child {
color: #fff;
font-size: 36rpx;
font-weight: 700;
}
&:nth-child(2) {
font-size: 24rpx;
color: rgba($color: #fff, $alpha: 0.6);
margin-top: 2rpx;
@include tHide(2);
}
}
}
}
.od-sd {
margin: 24rpx;
padding: 30rpx 20rpx;
flex-grow: 1;
border-radius: 10rpx;
background-color: #fff;
.os-tit {
color: #333;
font-size: 32rpx;
font-weight: 700;
margin-bottom: 30rpx;
}
.os-section {
margin-bottom: 30rpx;
padding-bottom: 28rpx;
border-bottom: 2rpx solid #f2f2f7;
display: flex;
flex-direction: row;
justify-content: space-between;
.os-info {
flex-grow: 1;
.oi-line {
> text {
font-size: 28rpx;
&:first-child {
color: #9a9a9d;
}
&:nth-child(2) {
color: #333;
}
&:nth-child(3) {
color: $mColor;
margin-left: 54rpx;
}
}
}
}
> image {
flex-shrink: 0;
width: 30rpx;
height: 30rpx;
}
}
.os-line {
@include ctf(space-between);
> view {
&:first-child {
> text {
color: #333;
font-size: 32rpx;
font-weight: 700;
&:first-child {
}
&:nth-child(2) {
margin-left: 52rpx;
}
}
}
&:nth-child(2) {
color: $mColor;
font-size: 28rpx;
}
}
}
.os-addr {
color: #9a9a9d;
font-size: 28rpx;
margin-top: 10rpx;
}
}
.od-self {
margin: 24rpx;
padding: 30rpx 20rpx;
flex-grow: 1;
border-radius: 10rpx;
background-color: #fff;
.os-tit {
color: #333;
font-size: 32rpx;
font-weight: 700;
}
.os-line {
padding: 16rpx 0 30rpx;
border-bottom: 2rpx solid #f2f2f7;
@include ctf(space-between);
> view {
&:first-child {
> text {
color: #333;
font-size: 32rpx;
&:first-child {
}
&:nth-child(2) {
margin-left: 50rpx;
}
}
}
&:nth-child(2) {
color: $mColor;
font-size: 32rpx;
}
}
}
.os-store {
color: #333;
font-size: 28rpx;
margin: 30rpx 0 10rpx;
}
.os-addr {
color: #9a9a9d;
font-size: 28rpx;
}
.os-code {
flex-grow: 1;
border-top: 2rpx solid #f2f2f7;
padding-top: 38rpx;
margin-top: 30rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.oc-box {
position: relative;
width: 300rpx;
height: 300rpx;
margin: 20rpx 0;
.oi-qrcode {
width: 300rpx;
height: 300rpx;
background-color: skyblue;
}
.oi-icon {
position: absolute;
top: -36rpx;
right: -82rpx;
width: 152rpx;
height: 152rpx;
}
.qrcodeChange {
opacity: 0.4;
}
}
.oc-tips {
color: #9c9c9f;
font-size: 24rpx;
}
.oc-num {
margin: 50rpx 0;
padding: 12rpx 14rpx;
border-radius: 10rpx;
background: rgba($color: $mColor, $alpha: 0.09);
@include ctf(flex-start);
> view {
color: $mColor;
font-size: 28rpx;
line-height: 40rpx;
&:first-child {
}
&:nth-child(2) {
font-weight: 700;
}
}
}
.numChange {
margin: 50rpx 0;
padding: 12rpx 14rpx;
border-radius: 10rpx;
background: #f8f8f8;
@include ctf(flex-start);
> view {
color: #9c9c9f;
font-size: 28rpx;
line-height: 40rpx;
&:first-child {
}
&:nth-child(2) {
font-weight: 700;
}
}
}
}
}
.od-info {
margin: 0 24rpx;
padding: 0 20rpx;
flex-grow: 1;
border-radius: 10rpx;
background-color: #fff;
.oi-store {
padding: 24rpx 0;
border-bottom: 2rpx solid #d8d8d8;
@include ctf(space-between);
> view {
&:first-child {
flex-grow: 1;
@include ctf(flex-start);
> image {
flex-shrink: 0;
width: 40rpx;
height: 40rpx;
margin-right: 14rpx;
border-radius: 10rpx;
}
> text {
flex-grow: 1;
color: #333;
font-size: 28rpx;
@include tHide(2);
}
}
&:nth-child(2) {
flex-shrink: 0;
color: #9a9a9d;
font-size: 28rpx;
margin-right: 8rpx;
}
}
}
.oi-goods {
// margin-top: 30rpx;
}
.oi-line {
margin-top: 30rpx;
@include ctf(space-between);
> view {
color: #333;
&:first-child {
flex-grow: 1;
font-size: 28rpx;
}
&:nth-child(2) {
flex-shrink: 0;
font-size: 24rpx;
}
}
}
.oi-price {
padding: 20rpx 0 30rpx;
flex-grow: 1;
text-align: right;
> text {
color: #ff873d;
&:first-child {
color: #333;
font-size: 28rpx;
}
&:nth-child(2) {
font-size: 28rpx;
font-weight: 700;
}
&:nth-child(3) {
font-size: 36rpx;
font-weight: 700;
}
}
}
}
.od-pay {
margin: 24rpx;
padding: 30rpx 28rpx;
flex-grow: 1;
border-radius: 10rpx;
background-color: #fff;
.op-line {
@include ctf(flex-start);
> view {
font-size: 28rpx;
line-height: 60rpx;
&:first-child {
color: #9a9a9d;
width: 140rpx;
}
&:nth-child(2) {
color: #333;
margin-left: 32rpx;
}
&:nth-child(3) {
color: $mColor;
margin-left: 30rpx;
}
}
}
}
.od-btn {
position: fixed;
bottom: 0;
width: 100%;
padding: 20rpx 18rpx 20rpx 0rpx;
padding-bottom: calc(20rpx );
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
@include isPd(20upx);
background-color: #fff;
border-top: 2rpx solid #f2f2f7;
@include ctf(flex-end);
> view {
width: 192rpx;
padding: 24rpx 0;
margin-right: 20rpx;
border-radius: 44rpx;
text-align: center;
font-size: 28rpx;
}
.ob-btn1 {
color: #9a9a9d;
border: 2rpx solid #d8d8d8;
}
.ob-btn2 {
color: $mColor;
border: 2rpx solid $mColor;
}
.ob-btn3 {
color: #fff;
background: linear-gradient(90deg, #44d7b6 0%, $mColor 100%);
}
}
.od-refund-modal {
position: absolute;
left: 56rpx;
top: 26%;
background-color: #fff;
width: 640rpx;
padding: 64rpx 48rpx;
border-radius: 10rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.orm-tit {
color: #333;
font-size: 34rpx;
font-weight: 700;
}
.orm-tips {
color: #9a9a9d;
font-size: 28rpx;
padding: 68rpx 0;
}
.orm-btn {
padding: 16rpx 52rpx;
border-radius: 10rpx;
background-color: $mColor;
color: #fff;
font-size: 34rpx;
font-weight: 700;
}
}
.zindex{
z-index: 9;
}
}
</style>

352
src/subpackage/mall/pages/order/order_list.vue

@ -0,0 +1,352 @@
<template>
<view class="order-list">
<view class="ol-head">
<view class="oh-line">
<view class="ol-ipt" @click="toOrderSearch">
<image mode="aspectFit" src="/subpackage/mall/static/images/search.png"></image>
<input placeholder="搜索我的订单" disabled/>
</view>
<view class="ol-refund" @click="toRefundList">退款/售后</view>
</view>
<view class="tab-list">
<block v-for="(e,i) in tabList" :key="i">
<view :class="['tab_no', curTabID == e.id ? 'tab_yes':'']" @click="tabChange(e)">
<view class="tab-txt">{{e.name}}</view>
</view>
</block>
</view>
</view>
<block v-for="(e, i) in orderList" :key="i" v-if="orderList.length > 0">
<order-list-item
:brand-id="brand_id"
:orderInfo="e"
@defineChange="defineChange"
></order-list-item>
</block>
<view class="ol-no-list" v-if="orderList.length == 0">
<image src="/subpackage/mall/static/images/no_venue_order.png"></image>
<view>还没订单~去下一单</view>
</view>
<view class="ol-like" v-if="curTabID != -1 && orderList.length == 0">
<view><view></view></view>
<view>猜你喜欢</view>
<view><view></view></view>
</view>
<view class="ol-goods-list" v-if="curTabID != -1 && orderList.length == 0">
<view class="ogl-item" v-for="(e, i) in likeGoodsList" :key="i">
<goods-item
:poster="(e.product_imgs&&e.product_imgs[0]) || ''"
:name="e.product_name"
:price="e.product_price"
:product-id="e.id"
:brand-id="brand_id"
:is-del-price="e.product_spec_multi === 0&&e.product_price_show != 0"
:del-price="e.product_price_show || 0"
@click:add="addCartChange(e)"
></goods-item>
</view>
</view>
<specification-modal ref="specificationModal" ></specification-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import orderListItem from '../modules/order/order_list_item.vue';
import goodsItem from "../../components/goods_item.vue";
import specificationModal from "../../components/specification_modal.vue";
import { MALL_API } from "../../js/api";
import server from "../../js/server";
const tabList=[
{name: '全部', id: -1}, {name: '待付款', id: 0}, {name: '待发货', id: 1}, {name: '待收货', id: 2}, {name: '待评价', id: 3}
];
export default {
components: {
orderListItem,
goodsItem,
specificationModal,
},
data() {
return {
tabList,
curTabID: -1,
page: 1,
orderList: [],
likeGoodsList: [],
brand_id: '',
}
},
onLoad(options) {
let _bid = options?.brand_id ?? '';
this.brand_id = _bid;
this.getLikeList({ brand_id: _bid });
},
onShow() {
let { brand_id } = this;
this.getOrderList({ brand_id });
},
onReachBottom(){
let { page, brand_id } = this;
this.getOrderList({ page: ++page, brand_id });
},
methods: {
toOrderSearch(){
util.routeTo(`../order_search/order_search`,'nT')
},
toRefundList(){
util.routeTo(`../refund_list/refund_list`,'nT')
},
defineChange(e){
let { brand_id } = this;
if(e == true) this.getOrderList({ brand_id });
},
// -
getOrderList({ brand_id, page = 1, page_size = 20,}){
let { curTabID } = this;
let _query = {
brand_id,
page,
page_size,
}
if(curTabID == -1)_query['status'] = '';
if(curTabID != -1)_query['status'] = curTabID;
util.showLoad();
server.get({
url: MALL_API.goodsOrderList,
data: _query,
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('订单列表: ', res);
let _list = res.list || [];
if(page == 1){
this.orderList = _list;
return
}
if(_list.length<=0)return util.showNone('没有更多!');
this.page = page;
this.orderList = [...this.orderList, ...res.list];
console.log("列表长度: ",this.orderList.length)
console.log(res);
});
},
tabChange: util.debounce(function(e){
this.curTabID = e.id;
this.refreshList();
}, 300, 300),
refreshList(){
let { brand_id } = this;
this.page = 1;
this.orderList = [];
this.getOrderList({ brand_id });
},
// pmrecommend1ID
getLikeList({ brand_id, page = 1, page_size = 20}){
util.showLoad();
server.get({
url: MALL_API.goodsList,
data: {
brand_id,
cateid: '',
show_sort: '',
recommend: 1,
page,
page_size,
},
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
this.likeGoodsList = res.list || []
});
},
//
addCartChange(e){
let { brand_id } = this;
//
// product_spec_multi 1
if(e.product_spec_multi == 1){
this.$refs.specificationModal.alert({
id: e?.id ?? '',
brand_id: brand_id,
poster: e?.product_imgs?.[0] ?? '',
name: e?.product_name ?? '',
price: e?.product_price ?? '',
specArr: e?.product_spec ?? [],
});
return
}
this.$refs?.specificationModal?.goodsCartAdd({ brand_id, id: e?.id, });
},
}
}
</script>
<style lang="scss">
.order-list{
position: relative;
padding-top: 216rpx;
@include isPd(20upx);
.ol-head{
position: fixed;
top: 0;
z-index: 6;
width: 100%;
padding-top: 4rpx;
background-color: #fff;
border-bottom: 4rpx solid #F2F2F7;
.oh-line{
padding: 28rpx 24rpx 0 24rpx;
@include ctf(space-between);
.ol-ipt{
flex-grow: 1;
padding: 0 28rpx;
height: 72rpx;
border-radius: 36rpx;
border: 2rpx solid #009874;
@include ctf(flex-start);
>image{
flex-shrink: 0;
margin-right: 24rpx;
width: 30rpx;
height: 30rpx;
}
& input{
flex-grow: 1;
height: 100%;
font-size: 28rpx;
color: #333;
}
}
.ol-refund{
flex-shrink: 0;
margin-left: 26rpx;
color: #333;
font-size: 28rpx;
}
}
.tab-list{
width: 750rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-around;
.tab_no{
position: relative;
flex-shrink: 0;
flex-grow: 1;
height: 100rpx;
line-height: 100rpx;
text-align: center;
.tab-txt{
position: relative;
display: inline-block;
font-size: 28rpx;
font-weight: 700;
color: #9A9A9D;
&::after{
content: '';
transition: all .2s;
position: absolute;
left: 50%;
bottom: 6rpx;
transform: translateX(-50%) translateY(50%);
display: block;
width: 70%;
height: 10rpx;
border-radius: 5rpx;
background-color: #009874;
opacity: 0;
}
}
&.tab_yes{
.tab-txt{
color: #009874;
&::after{
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
}
}
}
}
.ol-no-list{
padding: 78rpx 0 96rpx;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
>image{
width: 346rpx;
height: 346rpx;
}
>view{
color: #9A9A9D;
font-size: 28rpx;
}
}
.ol-like{
margin: 40rpx 0;
@include ctf(center);
>view{
&:first-child{
position: relative;
width: 60rpx;
height: 2rpx;
background-color: #D8D8D8;
>view{
position: absolute;
top: -3rpx;
right: 0;
width: 8rpx;
height: 8rpx;
border-radius: 8rpx;
background-color: #D8D8D8;
}
}
&:nth-child(2){
color: #333;
font-size: 28rpx;
margin: 0 26rpx;
font-weight: 700;
}
&:nth-child(3){
position: relative;
width: 60rpx;
height: 2rpx;
background-color: #D8D8D8;
>view{
position: absolute;
top: -3rpx;
left: 0;
width: 8rpx;
height: 8rpx;
border-radius: 8rpx;
background-color: #D8D8D8;
}
}
}
}
.ol-goods-list{
padding: 0 24rpx;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.ogl-item{
flex-shrink: 0;
margin-bottom: 24rpx;
}
}
}
</style>

423
src/subpackage/mall/pages/order/request_write.vue

@ -0,0 +1,423 @@
<template>
<!-- 退款申请 退款填写 -->
<view class="request-write">
<view class="rw-goods">
<!-- 2件商品以上 -->
<view class="rg-more" v-if="optionsQuery.goods_list.length > 1" @click="goBackChange">
<view >
<view v-for="(e, i) in optionsQuery.goods_list" :key="i">
<image class="rm-img" mode="aspectFill" :src="e.product_imgs || ''"></image>
<view class="rm-txt">{{e.product_name || '-'}}</view>
</view>
</view>
<view>
<text>{{optionsQuery.goods_list.length || 0}}</text>
<image src="/subpackage/mall/static/images/arrow_9ad.png"></image>
</view>
</view>
<!-- 1件商品 -->
<view class="rg-one" v-if="optionsQuery.goods_list.length == 1">
<block v-for="(e, i) in optionsQuery.goods_list" :key="i">
<image mode="aspectFill" :src="e.product_imgs || ''"></image>
<view>{{e.product_name || '-'}}</view>
</block>
</view>
</view>
<view class="rw-line">
<view>售后方式</view>
<view>{{ setFeedbackType }}</view>
</view>
<!-- 退款原因 -->
<picker class="rw-picker" :range="pageInfo.question_type" @change="questionPickerChange">
<view class="rp-cause">
<view>
<view>请选择退款原因</view>
<view>*</view>
<view>{{ submitInfo.questionType }}</view>
</view>
<image src="/subpackage/mall/static/images/arrow_9ad.png" style="transform: rotateZ(90deg)"></image>
</view>
</picker>
<!-- 退款金额 -->
<view class="rw-price">
<view>
<text>退款金额</text>
<text></text>
<text>{{pageInfo.refundable_amount || 0}}</text>
<text>(退还抵扣积分{{pageInfo.refundable_deduction_integral || 0}}积分)</text>
</view>
<view>最大可退 {{pageInfo.refundable_amount || 0}}含运费0退款将返回实际支付金额</view>
</view>
<!-- 退款描述 -->
<view class="rw-desc">
<view class="rd-tit">退款说明</view>
<textarea class="rd-textarea" @blur="bindTextAreaBlur" placeholder="请输入内容" v-model="submitInfo.questionDesc"></textarea>
</view>
<!-- 上传图片 -->
<view class="rw-pic">
<upload-image @uploadImageChange="uploadImageChange"></upload-image>
</view>
<view class="rw-btn">
<view hover-class="hover-active" :class="[isQuestionType?'':'opa-gray']" @click="isQuestionType?submitBtn():''">提交</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import server from "../../js/server";
import { MALL_API } from "../../js/api";
import uploadImage from '../modules/order/upload_image.vue'
export default {
components: {
'upload-image': uploadImage,
},
computed: {
setFeedbackType(){
let type = this.optionsQuery.feedback_type
if(type == 0) return "仅退款";
if(type == 1) return "退货退款";
else return "";
},
isQuestionType(){
if(this.submitInfo.questionType != '')return true;
else return false;
},
productCartIds(){
let _list = this.optionsQuery.goods_list
let _arr = []
for(var i in _list){
_arr.push(_list[i].product_cart_id)
}
return _arr;
},
},
data() {
return {
brand_id: '',
optionsQuery: {
order_no: '',
feedbackDetail: [],
goods_list: [],
feedback_type: -1,
},
submitInfo: {
questionType: '',
questionDesc: '',
questionImg: '',
},
pageInfo: {
question_type: [],
},
}
},
onLoad(options) {
let _bid = options?.brand_id ?? '';
this.brand_id = _bid;
let _query = util.jsonPar(options.query);
this.optionsQuery = _query
this.getFeedbackInfo({
brand_id: _bid,
order_no: _query.order_no,
feedback_detail: _query.feedbackDetail,
})
},
methods: {
goBackChange(){
uni.navigateBack({delta: 1})
},
//
bindTextAreaBlur: function(e) {
this.submitInfo.questionDesc = e.detail.value
},
//
uploadImageChange: function(e){
console.log("选择的图片: " + e)
let images = e.join(",");
console.log("需要上传的图片: ",images)
this.submitInfo.questionImg = e.join(",");
},
questionPickerChange(e){
console.log(e);
let _questionList = this.pageInfo.question_type || [];
this.submitInfo.questionType = _questionList[e.detail.value] || ''
},
getFeedbackInfo({ brand_id, order_no, feedback_detail }){
util.showLoad();
server.post({
url: MALL_API.feedbackInfo,
data: {
brand_id,
order_no,
feedback_detail,
},
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('feedbackInfo: ', res);
this.pageInfo = res
});
},
getOrdeRefund(brand_id){
server.post({
url: MALL_API.goodsOrdeRefund,
data: {
brand_id,
order_no: this.optionsQuery.order_no,
product_cart_ids: this.productCartIds,
},
failMsg: '加载数据失败!'
})
.then(res => {
console.log('getOrdeRefund: ', res);
});
},
getFeedbackSubmit({brand_id, order_no, question_type, question_desc, question_img, feedback_detail, feedback_type}){
util.showLoad();
server.post({
url: MALL_API.feedbackSubmit,
data: {
brand_id,
order_no,
question_type,
question_desc,
question_img,
feedback_detail,
feedback_type,
},
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('feedbackSubmit: ', res);
this.getOrdeRefund(brand_id)
util.showNone('操作成功!');
setTimeout(_=>uni.navigateBack({delta: 2}),1200)
});
},
submitBtn(){
let { optionsQuery, submitInfo, brand_id } = this
this.getFeedbackSubmit({
brand_id,
order_no: optionsQuery.order_no,
question_type: submitInfo.questionType,
question_desc: submitInfo.questionDesc,
question_img: submitInfo.questionImg,
feedback_detail: optionsQuery.feedbackDetail,
feedback_type: optionsQuery.feedback_type,
})
},
}
}
</script>
<style lang="scss">
.request-write{
position: relative;
width: 100%;
@include isPd(150upx);
.rw-goods{
margin: 24rpx;
padding: 30rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
.rg-more{
flex-grow: 1;
@include ctf(space-between);
>view{
&:first-child{
flex-grow: 1;
@include ctf(flex-start);
>view{
.rm-img{
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.rm-txt{
color: #333;
font-size: 24rpx;
margin-top: 6rpx;
max-width: 152rpx;
@include tHide(1);
}
}
}
&:nth-child(2){
flex-shrink: 0;
margin-top: -40rpx;
@include ctf(flex-start);
>text{
color: #9A9A9D;
font-size: 24rpx;
}
>image{
width: 30rpx;
height: 30rpx;
margin-left: 8rpx;
}
}
}
}
.rg-one{
flex-grow: 1;
display: flex;
flex-direction: row;
justify-content: flex-start;
>image{
flex-shrink: 0;
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
>view{
flex-grow: 1;
color: #333;
font-size: 28rpx;
@include tHide(2);
}
}
}
.rw-line{
margin: 0rpx 24rpx;
padding: 24rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
@include ctf(space-between);
>view{
font-size: 28rpx;
&:first-child{
color: #9A9A9D;
}
&:nth-child(2){
color: #333;
}
}
}
.rw-picker{
width: 100%;
.rp-cause{
margin:24rpx;
padding: 24rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
@include ctf(space-between);
>view{
flex-grow: 1;
@include ctf(flex-start);
>view{
font-size: 28rpx;
&:first-child{
flex-shrink: 0;
color: #9A9A9D;
}
&:nth-child(2){
flex-shrink: 0;
color: #FF873D;
}
&:nth-child(3){
flex-grow: 1;
color: #333;
margin-left: 30rpx;
@include tHide(1);
}
}
}
>image{
flex-shrink: 0;
width: 30rpx;
height: 30rpx;
margin-left: 10rpx;
}
}
}
.rw-price{
margin: 0rpx 24rpx;
padding: 26rpx 20rpx 30rpx;
border-radius: 10rpx;
background-color: #fff;
>view{
&:first-child{
>text{
color: #FF873D;
margin-bottom: 10rpx;
&:first-child{
font-size: 28rpx;
color: #9A9A9D;
}
&:nth-child(2){
font-size: 28rpx;
}
&:nth-child(3){
font-size: 32rpx;
}
&:nth-child(4){
font-size: 24rpx;
}
}
}
&:nth-child(2){
color: #333;
font-size: 28rpx;
}
}
}
.rw-desc{
flex-grow: 1;
margin: 24rpx;
padding: 30rpx 20rpx;
border-radius: 10rpx;
background-color: #fff;
.rd-tit{
color: #9A9A9D;
font-size: 28rpx;
margin-bottom: 10rpx;
}
.rd-textarea{
width: 100%;
height: 150rpx;
color: #333;
font-size: 28rpx;
}
}
.rw-pic{
margin: 0rpx 24rpx;
padding: 30rpx 20rpx 38rpx;
border-radius: 10rpx;
background-color: #fff;
}
.rw-btn{
position: fixed;
bottom: 0;
padding: 20rpx 0rpx;
padding-bottom: calc(20rpx );
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
width: 100%;
background-color: #fff;
>view{
flex-grow: 1;
margin: 0rpx 24rpx;
padding: 22rpx 0rpx;
color: #FFF;
font-size: 32rpx;
font-weight: 700;
text-align: center;
border-radius: 44rpx;
background: linear-gradient(90deg, #44D7B6 0%, $mColor 100%);
opacity: 1;
}
.opa-gray{
opacity: 0.5;
}
}
}
</style>

423
src/subpackage/mall/pages/pay/order_pay.vue

@ -0,0 +1,423 @@
<template>
<view class="order-pay">
<view class="op-header">
<view class="oh-stadium">
<image mode='aspectFit' :src="storeInfo.logo || ''"></image>
<text>{{ storeInfo.name || '-' }}</text>
</view>
<view class="oh-type-tip">{{ get_zh_tip(option_query.pay_type) || '-' }}</view>
<view class="oh-price"><text>¥</text>{{ payAmount || '0.00' }}</view>
<!-- <view class="oh-discount">原价¥{{option_query.price || '0.00'}}<text>折扣金额¥{{ discountAmount || '0.00' }}</text></view> -->
</view>
<view class="op-pay-method">
<!-- <view class="opm-value-card" v-if="vipCardList&&vipCardList.length">
<view class="ovc-tit">
<image mode="aspectFit" src="/static/image/icon/vip_pay.png"></image>
储值卡支付
</view>
<view class="ovc-list">
<view class="ol-item" v-for="(e, i) in vipCardList" :key="i" @click="cardSelect(e)">
<view class="oi-left">
<view class="ol-name">{{ e.card_name || '-' }}</view>
<view class="ol-balance">当前余额{{ e.card_balance || '0.00' }}</view>
</view>
<view class="oi-right">
<view class="or-tag">{{ e.discount != 10 ? '折扣:' : '' }}{{ e.discount == 10 ? '不打' : e.discount || '-' }}</view>
<view class="or-icon" :class="{ 's-active': payType == 1&&payCardInfo.card_no == e.card_no }">
<image mode="aspectFit" src="/static/image/icon/selected.png"></image>
</view>
</view>
</view>
</view>
</view> -->
<view class="opm-weixin" @click="wxPaySelect">
<view class="ow-left">
<image mode="aspectFit" src="/subpackage/mall/static/images/wx_pay.png"></image>
微信支付
</view>
<view class="ow-icon" :class="{ 's-active': payType == 0 }">
<image mode="aspectFit" src="/subpackage/mall/static/images/selected2.png"></image>
</view>
</view>
</view>
<view class="op-fixed">
<view hover-class="hover-active" @click="confirmPay">立即支付</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util'
import { mapState } from 'vuex'
import { MALL_API } from "../../js/api";
import server from "../../js/server";
/**
* option_query @Object
* pay_type 4->商城
* price 支付金额
* order_no 订单号
*
* 选传---------
* stadium_id 场馆id (调试)
*/
export default {
computed: {
...mapState([ 'APPID','storeInfo', 'brandInfo' ]),
//
payAmount(){
let { payCardInfo, option_query } = this;
if(payCardInfo){
return payCardInfo.pay_amount
}
return (option_query?.price || 0);
},
//
discountAmount(){
// pay_amount
let { payCardInfo, option_query } = this;
if(payCardInfo){
let discount_price = option_query.price-payCardInfo.pay_amount
return discount_price.toFixed(2)
}
return '0.00';
},
},
data(){
return {
option_query: { //
pay_type: -1,
//
// 0-> , 1 -> / 2 -> ,
// 3 -> , 4->, 5->, 6->, 7->, 8->,
price: 0, //
order_no: '', //
order_id: '', // id //
},
vipCardList: [],
get_zh_tip,
payType: 0, // 0-> 1->
payCardInfo: null, //
//
isWxPaying: false, //
isToDoing: false //
}
},
async onLoad(options){
// util.showLoad();
// if(options.stadium_id)await this.$store.dispatch('initStoreInfo', options.stadium_id || '');
// util.hideLoad();
this.option_query = util.jsonPar(options.query);
// this.getMyVipCard(this.option_query);
},
onHide(){
this.isWxPaying = false;
this.isToDoing = false;
},
methods: {
cardSelect(e){
this.payType = 1;
this.payCardInfo = e;
},
wxPaySelect(){
this.payType = 0;
this.payCardInfo = null;
},
confirmPay: util.debounce(function(){
let { payType } = this;
if(this.isWxPaying || this.isToDoing)return;
if(payType === 0)this.wxPay();
if(payType === 1)this.vipPay();
}, 500, true),
// vipPay(){
// let { storeInfo, APPID, option_query, payCardInfo, getPayApi } = this;
// // return console.log(option_query.order_no)
// if(!getPayApi().vip)return util.showNone('');
// util.showLoad();
// servers.get({
// url: getPayApi().vip,
// data: {
// card_no: payCardInfo.card_no,
// order_no: option_query.order_no,
// stadium_id: storeInfo.id,
// type: "v2.0", //
// },
// isDefaultGet: false,
// })
// .then(res=>{
// util.hideLoad();
// if(res.data.code == 0){
// let _data = res.data.data || {};
// util.showNone(res.data.message || '');
// //
// this.successToDo({ order_no: _data.order_no || option_query.order_no || '' });
// }else{
// util.showNone(res.data.message || '')
// }
// })
// .catch(err=>{
// util.hideLoad();
// console.error('--->', err);
// })
// },
getPayApi(){
let _type = this.option_query.pay_type;
if(_type == -1)return {};
return {
wx: MALL_API.orderPay,
vip: MALL_API.orderPayVip,
}
},
wxPay(){
let { storeInfo, APPID, option_query, getPayApi } = this;
util.showLoad();
server.get({
url: getPayApi().wx,
data: {
appid: APPID,
mch_id: storeInfo.pay_wechat_mch_id,
order_no: option_query.order_no,
stadium_id: storeInfo.id
},
failMsg: '生成支付信息失败!'
}).then(res=>{
util.hideLoad();
if(res.pay_amount == 0)return this.successToDo({ integral: res.integral || 0, order_no: res.order_no || option_query.order_no || '' });
this.isWxPaying = true;
uni.requestPayment({
...res,
success: sucRes => {
util.showNone('支付成功!');
this.successToDo({ integral: res.integral || 0, order_no: res.order_no || option_query.order_no || '' });
},
fail(errRes){
console.error('支付失败--->',errRes);
if(errRes.errMsg.indexOf('cancel') != -1){
setTimeout(_=>util.routeTo(),1200);
return util.showNone('取消支付')
};
util.showNone(errRes.errMsg || '支付失败稍后重试!');
},
complete: payRes=>{
this.isWxPaying = false;
console.log(payRes,'payRes');
}
})
})
.catch(err=>{
util.hideLoad();
console.error('生成支付信息失败--->',err);
})
},
successToDo({
//
integral = 0,
order_no = ''
}){
this.isToDoing = true;
let { option_query, storeInfo } = this;
let _type = this.option_query.pay_type;
setTimeout(()=>{
if(_type == 4){
return util.routeTo(`/subpackage/mall/pages/pay/pay_success/pay_success?order_no=${option_query.order_no}&integral=${integral}`,'rT');
}
},2000);
},
// type=1/2 type=0
getMyVipCard(query){
let { storeInfo, brandInfo } = this;
util.showLoad();
server.get({
url: MALL_API.canPayCard,
data: {
stadium_id: storeInfo.id,
brand_id: brandInfo.id,
price: query.price,
order_no: query.order_no,
},
failMsg: '加载会员卡失败!',
})
.then(res=>{
util.hideLoad();
this.vipCardList = res || [];
if(!Array.isArray(res) || res.length <= 0)return;
this.payType = 1;
this.payCardInfo = res[0];
})
.catch(err=>{
util.hideLoad();
console.error('获取会员卡失败--->',err);
})
}
}
}
function get_zh_tip(type) {
let _obj = {
'4': '商城支付金额',
}
return _obj[ type + '' ]
}
</script>
<style lang="scss">
page{
background: #EDEDF5;
}
.order-pay{
@include isPd(152upx);
}
.op-header{
.oh-stadium{
padding: 0 30upx;
@include flcw($height: 100upx, $weight: 500);
@include tHide;
>image{
margin-right: 10upx;
vertical-align: middle;
width: 30upx;
height: 30upx;
}
}
.oh-type-tip{
padding: 0 30upx;
margin-top: 8upx;
text-align: center;
@include flcw(24upx, 50upx, #9A9A9D);
@include tHide;
}
.oh-price{
padding: 0 30upx;
text-align: center;
letter-spacing: 2upx;
@include flcw(80upx, 112upx, #333, 500);
@include tHide;
>text{
font-size: 60upx;
}
}
.oh-discount{
padding: 0 30upx;
text-align: center;
@include flcw;
@include tHide;
>text{
color: #FF873D;
}
}
}
/* 支付方式选中 icon */
@mixin sIcon{
flex-shrink: 0;
width: 36upx;
height: 36upx;
font-size: 0;
border: 2upx solid #9F9FAA;
border-radius: 50%;
>image{
width: 100%;
height: 100%;
opacity: 0;
}
&.s-active{
border-color: transparent;
border-width: 0upx;
>image{
opacity: 1;
}
}
}
.op-pay-method{
margin-top: 60upx;
padding: 0 24upx;
.opm-value-card{
padding: 40upx 20upx 20upx;
border-radius: 10upx;
background: #F0FDFA;
.ovc-tit{
@include flcw(32upx, 44upx, #333, 500);
>image{
vertical-align: middle;
margin-right: 20upx;
width: 44upx;
height: 44upx;
}
}
.ovc-list{
margin-top: 20upx;
padding-left: 40upx;
background: #fff;
border-radius: 6upx;
.ol-item{
padding: 20upx 20upx 30upx 0upx;
@include ctf(space-between);
&:nth-child(n+2){
border-top: 1px solid #EDEDF5;
}
.oi-left{
.ol-name{
@include flcw($height: 44upx);
@include tHide;
}
.ol-balance{
@include flcw(20upx, 28upx, $mColor, 500);
@include tHide;
}
}
.oi-right{
flex-shrink: 0;
@include ctf(flex-end);
.or-tag{
padding: 0 4upx;
border: 1px solid #FF873D;
border-radius: 4upx;
@include flcw(18upx, 26upx, #FF873D);
}
}
.or-icon{
margin-left: 20upx;
@include sIcon;
}
}
}
}
.opm-weixin{
margin-top: 24upx;
padding-left: 20upx;
padding-right: 40upx;
height: 124upx;
border-radius: 10upx;
background: #fff;
@include ctf(space-between);
.ow-left{
@include flcw(32upx, 44upx, #333);
>image{
margin-right: 20upx;
vertical-align: middle;
width: 44upx;
height: 44upx;
}
}
.ow-icon{
@include sIcon;
}
}
}
.op-fixed{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 10upx 20upx;
@include isPd(10upx);
>view{
border-radius: 10upx;
text-align: center;
background: $mColor;
@include flcw(32upx, 92upx, #fff, 500);
}
}
</style>

841
src/subpackage/mall/pages/pay/pay_confirm.vue

@ -0,0 +1,841 @@
<template>
<view class="pay-confirm">
<view class="pc-head">
<view class="ph-tab">
<!--
<block v-for="(e,i) in ['快递配送','门店自提']" :key="i">
<view :class="['tab_no', tabIdx == i ? 'tab_yes':'']" @click="tabChange(i)">{{e}}</view>
</block>
-->
<!-- 20240119 隐藏快递 -->
<block v-for="(e,i) in ['门店自提']" :key="i">
<view :class="['tab_no', tabIdx == 1 ? 'tab_yes':'']" @click="tabChange(1)">{{e}}</view>
</block>
</view>
</view>
<!-- 选择快递 -->
<view class="pc-address" v-if="tabIdx == 0" @click="toAddressList">
<image class="pa-icon" src="/subpackage/mall/static/images/position.png"></image>
<!-- 未填写快递地址 -->
<view class="pa-line" v-if="!addressInfo">
<view>您暂没填写快递地址请选填写快递地址</view>
<image src="/subpackage/mall/static/images/arrow_9ad.png"></image>
</view>
<!-- 已填写快递地址 -->
<view class="pa-detail" v-else>
<view>
<text>{{addressInfo.username || '-'}}</text>
<text>{{addressInfo.mobile || '-'}}</text>
</view>
<view>
<text>{{addressInfo.province || ''}}{{addressInfo.city || ''}}{{addressInfo.area || ''}}{{addressInfo.addr || ''}}</text>
<image src="/subpackage/mall/static/images/arrow_9ad.png"></image>
</view>
</view>
<image class="pa-end" src="/subpackage/mall/static/images/line.png"></image>
</view>
<!-- 选择自提 -->
<view class="pc-self" v-if="tabIdx == 1">
<!-- 支持自提 -->
<block v-if="selfAddrList.length > 0">
<view class="ps-address" @click="isAddressModel = !isAddressModel">
<view class="pa-store">
<view>
<text>{{selfPickup.store_name || '-'}}</text>
<text>最近自提点</text>
</view>
<view>{{selfPickup.store_addr || '-'}}</view>
</view>
<view class="pa-route" @click.stop="toWxMap">
<image src="/subpackage/mall/static/images/road_sign.png"></image>
<view>路线</view>
</view>
</view>
<view class="ps-info" >
<block v-for="(e, i) in selfList" :key="i">
<view class="pi-box">
<view class="pb-tit">{{e.tit}}</view>
<picker
v-if="i == 0"
mode="multiSelector"
@change="bindDateChange"
:value="dateSelected"
:range="dateArray"
:range-key="'en'"
>
<input class="pb-txt" type="text" placeholder="选择时间" v-model="e.txt" disabled />
</picker>
<input
v-if="i != 0"
class="pb-txt"
type="text"
:placeholder="i == 1?'输入电话':'输入姓名'"
v-model="e.txt"
disabled
@click="onSelfChange(i)"
/>
</view>
<view class="pi-line" v-if="i != 2">
<view class="pl-sign" v-for="j in 10" :key="j"></view>
</view>
</block>
</view>
</block>
<!-- 不支持自提 -->
<!-- <view class="ps-desc" v-else>
<view>很抱歉暂不支持自提请选择快递配送</view>
<view>订单中有不可自提的商品或门店不支持商品自提</view>
</view> -->
<!-- 20240119 隐藏快递 -->
<view class="ps-desc" v-else>
<view>很抱歉暂不支持自提</view>
</view>
<image class="ps-end" src="/subpackage/mall/static/images/line.png"></image>
</view>
<!-- 商品信息 -->
<view class="pc-info">
<view class="pi-tit">商品信息</view>
<view class="pi-line" @click="toProductInfo">
<view >
<view v-for="(e, i) in optionsQuery.goodsList" :key="i" v-if="i < 3">
<image class="pi-img" mode="aspectFill" :src="e.product_imgs || ''"></image>
<view class="pi-txt">{{e.product_name || '-'}}</view>
</view>
</view>
<view>
<text>{{optionsQuery.goodsList.length || 0}}</text>
<image src="/subpackage/mall/static/images/arrow_9ad.png"></image>
</view>
</view>
<view class="pi-price">
<text>商品金额合计</text>
<text>¥{{optionsQuery.price_amount || 0}}</text>
</view>
</view>
<!-- 使用优惠 积分 优惠券 -->
<view class="pc-discount">
<view class="pd-line">
<view>运费</view>
<view>¥{{ shippingAmount || 0}}</view>
</view>
</view>
<!-- 订单备注 -->
<view class="pc-desc">
<view>订单备注</view>
<input :class="{changeSize: orderRemark!=''}" type="text" v-model="orderRemark" placeholder="选填" @change="descChange" />
</view>
<!-- 应付金额 -->
<!-- <view class="pc-end">
<view>
<text>应付金额</text>
<text>¥{{payInfo.pay_amount || 0}}</text>
</view>
<view @click="toPay" hover-class="hover-active">提交订单</view>
</view> -->
<submit-bar @btn_evemt="toPay" :price="payInfo.pay_amount || 0"></submit-bar>
<!-- 弹框 选择自提地点 -->
<self-pickup-addr
v-if="isAddressModel"
:selfAddressList="selfAddrList"
:selfSelectAddr="selfPickup"
@selfSelectAddrChange="selfSelectAddrChange"
@selfAddrCloseChange="isAddressModel = !isAddressModel"
></self-pickup-addr>
<!-- 弹框 输入电话号码 -->
<view class="fixed-mask m-zidx" v-if="isPhoneModel" @touchmove.stop.prevent="moveHandle" @click="isPhoneModel = !isPhoneModel">
<view class="pc-input-modal" @click.stop>
<view class="pim-close">
<image src="/subpackage/mall/static/images/close_c97.png" @click.stop="isPhoneModel = !isPhoneModel"></image>
</view>
<view class="pim-title">输入电话号码</view>
<input type="number" maxlength="11" v-model="selfList[1].txt" @change="phoneChange" placeholder="请输入电话号码"/>
</view>
</view>
<!-- 弹框 输入姓名 -->
<view class="fixed-mask m-zidx" v-if="isUsernameModel" @touchmove.stop.prevent="moveHandle" @click="isUsernameModel = !isUsernameModel">
<view class="pc-input-modal" @click.stop>
<view class="pim-close">
<image src="/subpackage/mall/static/images/close_c97.png" @click.stop="isUsernameModel = !isUsernameModel"></image>
</view>
<view class="pim-title">输入姓名</view>
<input type="text" v-model="selfList[2].txt" @change="usernameChange" placeholder="请输入姓名"/>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import selfPickupAddr from '../modules/pay/self_pickup_addr.vue';
import submitBar from '../../components/submit_bar.vue';
import { mapState } from 'vuex';
import { MALL_API } from "../../js/api";
import server from "../../js/server";
//()14:00
const selfList = [{tit: '自提时间', txt: '',}, {tit: '电话', txt: '',}, {tit: '姓名', txt: '',}];
export default {
components: {
'self-pickup-addr': selfPickupAddr,
'submit-bar': submitBar,
},
computed: {
...mapState(['storeInfo']),
dateArray(){
let dateArr = [{en:'今天'},{en:'明天'},{en:'后天'}];
let timeArr = []
if(this.selfDate.times) timeArr = this.selfDate.times.map(item => ({en:item}));
return [dateArr, timeArr];
},
},
data() {
return {
selfList,
// 20240119
tabIdx: 1,
addressInfo: null,
isAddressModel: false, //
isPhoneModel: false, //
isUsernameModel: false, //
dateSelected: [0, 0], //
orderRemark: "", //
optionsQuery: {},
payInfo: {},
selfPickup: {}, //
selfAddrList: [], //
selfDate: {}, //
selfgTiem: "", //
totalPrice: 0, // +
shippingAmount: 0, //
brand_id: '',
}
},
async onLoad(options) {
let _bid = options?.brand_id || '';
this.brand_id = _bid;
let _query = util.jsonPar(options.query);
this.optionsQuery = _query
// 20240119
// this.getLogisticsAmount()
this.getOrderUsingStores({
gobuy: _query.go_buy,
brand_id: _bid,
})
this.getLogisticsTime(_bid);
// 20240119
this.tabChange(1);
for(var i in this.selfList){
this.selfList[i].txt = ""
}
},
onShow() {
let { brand_id } = this;
this.getAddrList(brand_id);
},
methods: {
moveHandle(){},
get_zh_day(date){
// if(isSameDay(new Date().getTime(),new Date(date).getTime()))return ''
const Arr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return Arr[new Date(date).getDay()] || '';
},
//-
getOrderUsingStores({ gobuy, brand_id }) {
util.showLoad();
server
.get({
url: MALL_API.goodsOrderUsingStores,
data: {
brand_id,
order_no: '', //[]
gobuy,
},
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('确认订单获取自提门店信息: ', res);
if(res != null){
this.selfAddrList = res;
let _selfPickup = {}
_selfPickup["lat"] = res[0].lat
_selfPickup["lng"] = res[0].lng
_selfPickup["store_id"] = res[0].id
_selfPickup["store_name"] = res[0].venue_name
_selfPickup["store_addr"] = res[0].venue_addr
this.selfPickup = _selfPickup
}
});
},
//
getLogisticsTime(brand_id) {
server
.get({
url: MALL_API.getLogisticsTime,
data: { brand_id },
failMsg: '加载数据失败!'
})
.then(res => {
console.log('获取门店自提时间: ', res);
this.selfDate = res
});
},
//
getLogisticsAmount(brand_id) {
server
.get({
url: MALL_API.getLogisticsAmount,
data: {
brand_id,
amount: this.optionsQuery.price_amount,
},
failMsg: '加载数据失败!'
})
.then(res => {
console.log('获取运费: ', res);
this.shippingAmount = res.shipping_amount || 0
this.totalPrice = parseFloat(this.shippingAmount) + parseFloat(this.optionsQuery.price_amount);
this.getPayInfo({ brand_id });
});
},
// -
getOrderConfirm() {
let { addressInfo, selfPickup, selfList, optionsQuery, brand_id } = this
let _query = {}
_query["brand_id"] = brand_id;
_query["gobuy"] = optionsQuery.go_buy;
_query["self_pickup"] = this.tabIdx; // 0- 1-
_query["remark"] = this.orderRemark; //
_query["integral"] = this.payInfo.use_integral; //
if(this.tabIdx == 0){
_query["custom_name"] = addressInfo.username; //
_query["custom_phone"] = addressInfo.mobile; //
_query["custom_addr"] = addressInfo.province + addressInfo.city + addressInfo.area + addressInfo.addr; //
}
if(this.tabIdx == 1){
_query["store_id"] = selfPickup.store_id; //ID
_query["store_name"] = selfPickup.store_name; //
_query["store_addr"] = selfPickup.store_addr; //
_query["user_name"] = selfList[2].txt; //
_query["user_phone"] = selfList[1].txt; //
_query["user_gtime"] = this.selfgTiem; //
}
util.showLoad();
server
.post({
url: MALL_API.goodsOrderConfirm,
data: _query,
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('确认订单提交订单: ', res);
// let _query = this.optionsQuery
// _query['pay_amount'] = this.payInfo.pay_amount
// _query['order_no'] = res.order.order_no
// util.routeTo(`../pay_order/pay_order?query=${util.jsonStr(_query)}`,'rT')
this.$nextTick(_=>{
let _query = {}
_query['price'] = res?.pay_amount ?? 0;
_query['order_no'] = res?.order.order_no ?? '';
_query['pay_type'] = 4 //
util.routeTo(`/subpackage/mall/pages/pay/order_pay?query=${util.jsonStr(_query)}`,'rT')
})
});
},
toPay(){
let { tabIdx, selfAddrList, selfgTiem, selfList } = this
if(tabIdx==1 && selfAddrList.length == 0)return util.showNone("请选择快递方式");
if(tabIdx==1 && selfgTiem=='')return util.showNone("请选择自提时间");
if(tabIdx==1 && selfList[1].txt=='')return util.showNone("请填写预留电话");
if(tabIdx==1 && selfList[2].txt=='')return util.showNone("请填写预留姓名");
this.getOrderConfirm()
},
tabChange(index){
let { brand_id } = this;
this.tabIdx = index;
if(this.tabIdx == 0){
this.getLogisticsAmount(brand_id)
}
if(this.tabIdx == 1){
this.totalPrice = this.optionsQuery.price_amount;
this.shippingAmount = 0;
this.getPayInfo({ brand_id });
}
},
toAddressList(){
util.routeTo(`/pages/mine/address_list/address_list?back_func=setAddrInfo`,'nT');
},
getAddrList(brand_id){
server.get({
url: MALL_API.addrList,
data: { brand_id },
failMsg: '获取地址信息失败 '
})
.then(res=>{
if(Array.isArray(res)&&res.length>0){
this.addressInfo = res.filter(e=>e.is_default)[0] || res[0];
}
})
},
setAddrInfo(info){
this.addressInfo = info
},
selfSelectAddrChange(e){
this.selfPickup = e
this.isAddressModel = false
console.log("选中的自提门店:",this.selfPickup )
},
toWxMap(){
let { selfPickup } = this
wx.openLocation({
latitude: +selfPickup.lat,
longitude: +selfPickup.lng,
name: selfPickup.store_name,
address: selfPickup.store_addr
})
},
//
descChange: util.debounce(function(e) {
this.orderRemark = e.detail.value || '';
},300,300),
phoneChange: util.debounce(function(e) {
this.selfList[1].txt = e.detail.value || '';
},300,300),
usernameChange: util.debounce(function(e) {
this.selfList[2].txt = e.detail.value || '';
},300,300),
onSelfChange(index){
// if(index == 0) return;
if(index == 1) return this.isPhoneModel = true;
if(index == 2) return this.isUsernameModel = true;
},
toProductInfo(){
let _query = this.optionsQuery.goodsList
util.routeTo(`/subpackage/mall/pages/pay/pay_product?query=${util.jsonStr(_query)}`,'nT')
},
//
bindDateChange: function(e){
console.log("dateArray: ", this.dateArray)
let { value } = e.detail;
this.dateSelected = value;
let _day = this.get_zh_day(this.selfDate.days[this.dateSelected[0]])
console.log("dateSelected: ",this.dateSelected)
this.selfList[0].txt = this.dateArray[0][value[0]]['en'] + '('+ _day +')' + this.dateArray[1][value[1]]['en'].substring(0,5);
console.log("this.selfList[0].txt : ", this.selfList[0].txt)
this.selfgTiem = this.selfDate.days[this.dateSelected[0]] + " " + this.dateArray[1][value[1]]['en']
},
getPayInfo({ integral=0, coupon_ids='', brand_id}) {
util.showLoad();
server
.get({
url: MALL_API.payInfo,
data: {
brand_id: brand_id,
amount: this.totalPrice,
scenes: 'mall',
integral,
coupon_ids,
mks: this.optionsQuery.product_ids.join(','), //id
},
failMsg: '加载数据失败!'
})
.then(res => {
util.hideLoad();
console.log('积分优惠券计算: ', res);
this.payInfo = res
});
},
}
}
</script>
<style lang="scss">
.pay-confirm{
position: relative;
padding: 136rpx 0 208upx;
@include isPd(208upx);
.pc-head{
z-index: 6;
position: fixed;
top: 0;
padding: 30rpx 0;
width: 100%;
background-color: #fff;
border-bottom: 24rpx solid #F2F2F7;
@include ctf(center);
.ph-tab{
padding: 4rpx;
border-radius: 54rpx;
// border: 4rpx solid $mColor;
background-color: $mColor;
@include ctf(flex-start);
.tab_no{
width: 172rpx;
padding: 8rpx;
color: #fff;
font-size: 28rpx;
text-align: center;
}
.tab_yes{
border-radius: 54rpx;
background-color: #fff;
color: $mColor;
}
}
}
.pc-address{
position: relative;
padding: 0rpx 24rpx 8rpx;
height: 168rpx;
background-color: #fff;
@include ctf(flex-start);
.pa-icon{
flex-shrink: 0;
flex-grow: 0;
// flex-grow: 1;
width: 46rpx;
height: 46rpx;
}
.pa-line{
margin-left: 20rpx;
flex-grow: 1;
@include ctf(space-between);
>view{
color: #333;
font-size: 28rpx;
}
>image{
width: 30rpx;
height: 30rpx;
}
}
.pa-detail{
margin-left: 20rpx;
flex-grow: 1;
>view{
&:first-child{
>text{
color: #333;
font-size: 32rpx;
font-weight: 700;
&:first-child{
}
&:nth-child(2){
margin-left: 52rpx;
}
}
}
&:nth-child(2){
margin-top: 10rpx;
@include ctf(space-between);
>text{
color: #9A9A9D;
font-size: 28rpx;
}
>image{
width: 30rpx;
height: 30rpx;
}
}
}
}
.pa-end{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 8rpx;
}
}
.pc-self{
position: relative;
padding: 40rpx 30rpx 48rpx;
background-color: #fff;
.ps-address{
padding-bottom: 30rpx;
border-bottom: 2rpx solid #D8D8D8;
@include ctf(space-between);
.pa-store{
>view{
&:first-child{
>text{
&:first-child{
color: #333;
font-size: 28rpx;
max-width: 400rpx;
}
&:nth-child(2){
color: $mColor;
font-size: 20rpx;
margin-left: 30rpx;
}
}
}
&:nth-child(2){
color: #9A9A9D;
font-size: 28rpx;
margin-top: 10rpx;
max-width: 486rpx;
}
}
}
.pa-route{
margin-right: 22rpx;
>image{
width: 52rpx;
height: 52rpx;
}
>view{
color: #9A9A9D;
font-size: 28rpx;
margin-top: 10rpx;
}
}
}
.ps-info{
padding: 30rpx 2rpx 0;
@include ctf(space-around);
.pi-box{
min-width: 200rpx;
font-size: 28rpx;
.pb-tit{
color: #9A9A9D;
}
.pb-txt{
color: #333;
margin-top: 20rpx;
width: 100%;
}
}
.pi-line{
margin: 0 30rpx 0 10rpx;
display: flex;
align-items: center;
flex-direction: column;
justify-content: flex-start;
.pl-sign{
width: 2rpx;
height: 8rpx;
background-color: #D8D8D8;
margin-top: 6rpx;
}
}
}
.ps-desc{
>view{
flex-grow: 1;
text-align: center;
&:first-child{
color: #333;
font-size: 28rpx;
}
&:nth-child(2){
color: #9A9A9D;
font-size: 24rpx;
margin-top: 14rpx;
}
}
}
.ps-end{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 8rpx;
}
}
.pc-info{
padding: 30rpx 36rpx 30rpx 32rpx;
margin-top: 24rpx;
background-color: #fff;
.pi-tit{
color: #333;
font-size: 28rpx;
}
.pi-line{
margin: 20rpx 0 30rpx;
@include ctf(space-between);
>view{
&:first-child{
@include ctf(flex-start);
>view{
margin-right: 20rpx;
.pi-img{
width: 152rpx;
height: 152rpx;
border-radius: 10rpx;
}
.pi-txt{
margin-top: 6rpx;
color: #333;
font-size: 24rpx;
max-width: 152rpx;
@include tHide(1);
}
}
}
&:nth-child(2){
margin-top: -40rpx;
@include ctf(flex-start);
>text{
color: #9A9A9D;
font-size: 24rpx;
}
>image{
width: 30rpx;
height: 30rpx;
margin-left: 8rpx;
}
}
}
}
.pi-price{
flex-shrink: 1;
@include ctf(flex-end);
>text{
font-size: 24rpx;
&:first-child{
color: #333;
}
&:nth-child(2){
color: #FF873D;
}
}
}
}
.pc-discount{
margin-top: 24rpx;
padding: 0 20rpx;
background-color: #fff;
.pd-line{
padding: 30rpx 0;
border-top: 2rpx solid #EDEDF5;
@include ctf(space-between);
>view{
color: #333;
font-size: 28rpx;
margin: 0rpx 6rpx 0rpx 4rpx;
}
}
}
.pc-desc{
margin: 24rpx 0;
padding: 30rpx 32rpx;
background-color: #fff;
@include ctf(flex-start);
>view{
flex-shrink: 0;
color: #333;
font-size: 28rpx;
}
& input {
flex-grow: 1;
padding: 0 20rpx;
color: #333;
font-size: 24rpx;
}
.changeSize{
font-size: 26rpx;
}
}
.pc-end{
z-index: 2;
position: fixed;
bottom: 0;
padding: 20rpx 24rpx;
width: 100%;
background-color: #fff;
border-top: 2rpx solid #f2f2f7;
@include ctf(space-between);
>view{
margin-left: 4rpx;
&:first-child{
>text{
&:first-child{
color: #333;
font-size: 28rpx;
}
&:nth-child(2){
color: #FF873D;
font-size: 32rpx;
font-weight: 700;
}
}
}
&:nth-child(2){
padding: 22rpx 56rpx;
border-radius: 44rpx;
background: linear-gradient(90deg, #44D7B6 0%, $mColor 100%);
color: #fff;
font-size: 32rpx;
font-weight: 700;
text-align: center;
}
}
}
.fixed-mask{
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba($color: #000000, $alpha: .5);
}
.m-zidx{
z-index: 99;
}
.pc-input-modal{
position: absolute;
left: 0;
bottom: 0;
background-color: #fff;
width: 750rpx;
padding: 28rpx 24rpx;
.pim-close{
width: 100%;
@include ctf(flex-end);
>image{
width: 40rpx;
height: 40rpx;
}
}
.pim-title{
width: 100%;
color: #333;
font-size: 32rpx;
font-weight: 700;
text-align: center;
}
& input{
width: 670rpx;
height: 96rpx;
border-radius: 10rpx;
border: 2rpx solid #d8d8d8;
padding: 0 20rpx;
color: #333;
font-size: 32rpx;
margin-top: 56rpx;
margin: 56rpx 0 100rpx;
}
}
}
</style>

57
src/subpackage/mall/pages/pay/pay_product.vue

@ -0,0 +1,57 @@
<template>
<view class="product-info">
<view class="pi-title">商品({{productNum}})</view>
<view class="pi-list" v-for="(e,i) in goodsList" :key="i">
<product-item :goodsInfo="e"></product-item>
</view>
</view>
</template>
<script>
import { jsonPar } from '@/utils/util';
import productItem from '../modules/pay/product_item.vue';
export default {
components: {
'product-item': productItem,
},
computed: {
productNum(){
let { goodsList } = this;
let nums = 0
for(var i in goodsList){
nums = goodsList[i].product_nums + nums
}
return nums || 0;
},
},
data() {
return {
goodsList: [],
}
},
onLoad(options) {
let _query = jsonPar(options.query);
this.goodsList = _query
},
methods: {
}
}
</script>
<style lang="scss">
.product-info{
padding: 40rpx 24rpx;
.pi-title{
color: #333;
font-size: 28rpx;
margin-bottom: 20rpx;
}
.pi-list{
padding: 40rpx 20rpx;
margin-bottom: 24rpx;
border-radius: 10rpx;
background-color: #fff;
}
}
</style>

BIN
src/subpackage/mall/static/images/close_333.png

After

Width: 40  |  Height: 40  |  Size: 353 B

BIN
src/subpackage/mall/static/images/line.png

After

Width: 758  |  Height: 8  |  Size: 331 B

BIN
src/subpackage/mall/static/images/no_venue_order.png

After

Width: 346  |  Height: 346  |  Size: 1.9 KiB

BIN
src/subpackage/mall/static/images/order/invalid.png

After

Width: 152  |  Height: 152  |  Size: 3.2 KiB

BIN
src/subpackage/mall/static/images/order/status_0.png

After

Width: 268  |  Height: 160  |  Size: 4.0 KiB

BIN
src/subpackage/mall/static/images/order/status_1.png

After

Width: 266  |  Height: 160  |  Size: 3.5 KiB

BIN
src/subpackage/mall/static/images/order/status_2.png

After

Width: 266  |  Height: 160  |  Size: 3.6 KiB

BIN
src/subpackage/mall/static/images/order/status_3.png

After

Width: 268  |  Height: 160  |  Size: 3.2 KiB

BIN
src/subpackage/mall/static/images/order/status_4.png

After

Width: 266  |  Height: 160  |  Size: 3.2 KiB

BIN
src/subpackage/mall/static/images/order/status_5.png

After

Width: 266  |  Height: 160  |  Size: 3.6 KiB

BIN
src/subpackage/mall/static/images/position.png

After

Width: 46  |  Height: 46  |  Size: 1.9 KiB

BIN
src/subpackage/mall/static/images/road_sign.png

After

Width: 52  |  Height: 52  |  Size: 470 B

BIN
src/subpackage/mall/static/images/star_empty.png

After

Width: 84  |  Height: 84  |  Size: 979 B

BIN
src/subpackage/mall/static/images/star_fill.png

After

Width: 84  |  Height: 84  |  Size: 1.1 KiB

BIN
src/subpackage/mall/static/images/vip_pay.png

After

Width: 54  |  Height: 54  |  Size: 627 B

BIN
src/subpackage/mall/static/images/wx_pay.png

After

Width: 54  |  Height: 54  |  Size: 583 B

Loading…
Cancel
Save