zhwl-miniapp/pages/shop/refund.vue
2025-06-26 12:38:35 +08:00

348 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="waper">
<u-navbar :autoBack="true" :placeholder="true" bgColor="#FBFBFB">
<view slot='center' class="navbar_title">填写退款信息</view>
</u-navbar>
<view class="waper_content" :style="'padding-bottom: ' + waperBottom1 + 'px;'" v-if="detail">
<view class="info">
<view class="title">{{detail.storeName}}</view>
<view class="goods">
<view class="img">
<image :src="$utils.setImgUrl(detail.goodsImage)" mode=""></image>
</view>
<view class="text">
<view class="name">{{detail.goodsTitle}}</view>
<view class="tag">
<view>
<text v-if="detail.goodsSkuText">{{detail.goodsSkuText.split(',').join('-')}}</text>
</view>
<view>X{{detail.goodsNum}}</view>
</view>
<view class="num">总价{{(detail.goodsNum * detail.goodsPrice).toFixed(2)}}</view>
</view>
</view>
</view>
<view class="reason" @click="refund = true;">
<view class="left">退款原因<text>*</text></view>
<view class="right">
<view class="cont">
<input type="text" placeholder="请选择退款原因" v-model="refundReason.name" disabled placeholder-class="placeholder" />
</view>
<view class="icon">
<u-icon name="arrow-right" size="32rpx" color="#333"></u-icon>
</view>
</view>
</view>
<template v-if="detail.type == 1">
<view class="reason" @click="express = true;">
<view class="left">快递公司<text>*</text></view>
<view class="right">
<view class="cont">
<input type="text" placeholder="请选择快递公司" v-model="refundExpress.name" disabled placeholder-class="placeholder" />
</view>
<view class="icon">
<u-icon name="arrow-right" size="32rpx" color="#333"></u-icon>
</view>
</view>
</view>
<view class="reason">
<view class="left">快递单号<text>*</text></view>
<view class="right">
<view class="cont" style="padding-right: 0;">
<input type="text" placeholder="请输入快递单号" v-model="expressNo" placeholder-class="placeholder" />
</view>
</view>
</view>
</template>
<view class="money">
<view>
<text>退款商品金额</text>
<text>¥{{(detail.goodsNum * detail.goodsPrice).toFixed(2)}}</text>
</view>
<view>
<text>运费</text>
<text>用户自行承担</text>
</view>
</view>
<view class="describe">
<view class="list">
<view class="name">退款描述和凭证(选填)</view>
<view class="form">
<u--textarea v-model="content" border="none" placeholder="请详细填写内容,以便我们提供更好的帮助" count :maxlength="200" placeholderClass="placeholder"></u--textarea>
</view>
</view>
<view class="list">
<view class="name">上传凭证(选填)</view>
<view class="form">
<u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="file" multiple :maxCount="5" width="156rpx" height="156rpx">
<image src="https://common/shop_refund_bg.png" class="img_list"></image>
</u-upload>
</view>
</view>
</view>
<view class="button" :style="'bottom: ' + waperBottom + 'px;'">
<view @click="submitRefund">提交</view>
</view>
</view>
<u-popup :show="refund" mode="bottom" bgColor="transparent">
<view class="refund_waper">
<view class="title">请选择退款原因
<view class="icon" @click="closeRefund">
<u-icon name="close" size="32rpx" color="#333"></u-icon>
</view>
</view>
<view class="cont">
<u-radio-group v-model="refundReason.value" iconPlacement="right" placement="column">
<u-radio v-for="(i, index) in refundReasonList" :key="index" activeColor="#03AE80" :name="i.dictValue" :label="i.dictLabel"></u-radio>
</u-radio-group>
</view>
<view class="btn" @click="confirmRefund">确定</view>
</view>
</u-popup>
<u-popup :show="express" mode="bottom" bgColor="transparent">
<view class="refund_waper">
<view class="title">请选择快递公司
<view class="icon" @click="closeExpress">
<u-icon name="close" size="32rpx" color="#333"></u-icon>
</view>
</view>
<view class="cont">
<u-radio-group v-model="refundExpress.value" iconPlacement="right" placement="column">
<u-radio v-for="(i, index) in expressList" :key="index" activeColor="#03AE80" :name="i.code" :label="i.name"></u-radio>
</u-radio-group>
</view>
<view class="btn" @click="confirmExpress">确定</view>
</view>
</u-popup>
</view>
</template>
<script>
import _config from '../../common/http/config.js'
export default {
data () {
return {
waperBottom: 0,
waperBottom1: 0,
fileList: [],
refund: false,
detail: null,
refundReason: {
name: '',
value: ''
},
refundReasonList: [],
content: '',
express: false,
refundExpress: {
name: '',
value: ''
},
expressList: [],
expressNo: ''
}
},
async onLoad (options) {
this.waperBottom = this.$safeAreaBottom + uni.upx2px(6);
this.waperBottom1 = this.$safeAreaBottom + uni.upx2px(110);
this.detail = JSON.parse(decodeURIComponent(options.info));
let info = await this.$http.common({ dictType: 'wcsc_refund_reason' });
this.refundReasonList = info.data;
if (this.detail.type == 1) {
let express = await this.$shop.getExpressList();
this.expressList = express.data;
}
},
methods: {
async submitRefund () {
if (!this.refundReason.value) {
uni.showToast({ mask: true, title: '请选择退款原因', icon: 'none' })
return false;
}
let data = { orderId: this.detail.orderId, orderItemId: this.detail.id, goodsId: this.detail.goodsId, reason: this.refundReason.value, content: this.content, totalPrice: (this.detail.goodsNum * this.detail.goodsPrice).toFixed(2), totalNum: this.detail.goodsNum, saleType: (this.detail.type == 0 ? 'refund' : 'return'), goodsSkuPriceId: this.detail.goodsSkuPriceId };
let image = [];
this.fileList.forEach((item) => {
image.push(item.url)
})
data.images = image.join(',');
if (this.detail.type == 1) {
if (!this.refundExpress.value) {
uni.showToast({ mask: true, title: '请选择快递公司', icon: 'none' })
return false;
}
data.expressName = this.refundExpress.name;
data.expressCode = this.refundExpress.value;
data.expressNo = this.expressNo;
}
let info = await this.$shop.applyRefundOrder(data);
uni.showToast({ mask: true, title: '操作成功', icon: 'success' });
setTimeout(() => {
uni.redirectTo({ url: '/pages/shop/refundReason?id=' + info.data })
}, 1500)
},
confirmRefund () {
if (!this.refundReason.value) {
uni.showToast({ mask: true, title: '请选择退款原因', icon: 'none' })
return false;
}
this.refundReasonList.forEach((item) => {
if (item.dictValue == this.refundReason.value) this.refundReason.name = item.dictLabel;
})
this.refund = false;
},
confirmExpress () {
if (!this.refundExpress.value) {
uni.showToast({ mask: true, title: '请选择快递公司', icon: 'none' })
return false;
}
this.expressList.forEach((item) => {
if (item.code == this.refundExpress.value) this.refundExpress.name = item.name;
})
this.express = false;
},
// 新增图片
async afterRead(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this.fileList.length
lists.map((item) => {
this.fileList.push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url)
let item = this.fileList[fileListLen]
this.fileList.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: JSON.parse(result).fileName
}))
fileListLen++
}
},
// 删除图片
deletePic(event) {
this.fileList.splice(event.index, 1)
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: _config.url + '/app/common/upload',
filePath: url,
header: { token: uni.getStorageSync("ztc_token") },
name: 'file',
success: (res) => {
setTimeout(() => {
resolve(res.data)
}, 1000)
}
});
})
},
closeRefund () {
this.refund = false;
},
closeExpress () {
this.express = false;
}
}
}
</script>
<style lang="scss">
.placeholder{ color: #999; }
.waper_content{
width: 100%; box-sizing: border-box; padding: 32rpx 24rpx 24rpx;
.info{
width: 100%; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 28rpx 24rpx;
.title{ line-height: 38rpx; color: rgba(0,0,0,0.85); font-size: 32rpx; font-weight: 500; }
.goods{
width: 100%; margin-top: 25rpx; box-sizing: border-box; padding-left: 190rpx; position: relative; min-height: 170rpx;
.img{
width: 170rpx; height: 170rpx; position: absolute; left: 0; top: 0;
image{ border-radius: 10rpx; }
}
.text{
width: 100%;
.name{ line-height: 33rpx; color: rgba(0,0,0,0.85); font-size: 28rpx; font-weight: 500; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.tag{
width: 100%; margin-top: 20rpx; display: flex; justify-content: space-between; align-items: center; height: 48rpx;
view{
&:nth-child(1){
display: flex; align-items: center;
text{ height: 48rpx; line-height: 48rpx; padding: 0 24rpx; box-sizing: border-box; background: #F4F4F4; border-radius: 2rpx; color: rgba(0,0,0,0.65); font-size: 24rpx; }
}
&:nth-child(2){ color: rgba(0,0,0,0.65); font-size: 24rpx; }
}
}
.num{ margin-top: 30rpx; text-align: right; color: rgba(0,0,0,0.85); font-size: 28rpx; line-height: 33rpx; }
}
}
}
.reason{
width: 100%; height: 90rpx; margin-top: 20rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding-left: 198rpx; position: relative;
.left{
width: 198rpx; box-sizing: border-box; padding-left: 24rpx; position: absolute; left: 0; top: 0; height: 100%; display: flex; align-items: center; color: rgba(0,0,0,0.85); font-size: 28rpx;
text{ color: #FF5833; }
&::after{ content: ""; width: 2rpx; height: 24rpx; background: rgba(0,0,0,0.1); position: absolute; right: 20rpx; top: 50%; transform: translateY(-50%); }
}
.right{
width: 100%; height: 100%; box-sizing: border-box; padding-right: 80rpx; position: relative; display: flex; align-items: center;
.cont{
width: 100%; height: 100%; display: flex; align-items: center;
input{ width: 100%; height: 72rpx; font-size: 28rpx; color: #333; display: inline-block; vertical-align: top; }
}
.icon{ position: absolute; right: 24rpx; top: 50%; transform: translateY(-50%); }
}
}
.money{
width: 100%; margin-top: 20rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 24rpx;
view{
width: 100%; display: flex; justify-content: space-between; align-items: center; height: 40rpx; color: rgba(0,0,0,0.85); font-size: 28rpx; margin-bottom: 20rpx;
&:last-child{ margin-bottom: 0; }
}
}
.describe{
width: 100%; margin-top: 20rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 32rpx 24rpx;
.list{
width: 100%; margin-bottom: 32rpx;
&:last-child{ margin-bottom: 0; }
.name{ line-height: 33rpx; color: rgba(0,0,0,0.85); font-size: 28rpx; }
.form{
margin-top: 24rpx; width: 100%;
.u-textarea{ background: #FBFBFB; }
.u-textarea__field{ font-size: 28rpx; line-height: 40rpx; }
.u-textarea__count{ background: transparent !important; }
.img_list{ width: 156rpx; height: 156rpx; }
.u-upload__deletable{ width: 40rpx; height: 40rpx; border-radius: 0; margin: 0; justify-content: center; align-items: center; background: #FF5833; }
.u-upload__deletable__icon{ position: static; }
.u-icon__icon{ font-size: 32rpx !important; }
}
}
}
.button{
position: fixed; left: 0; width: 100%; padding: 10rpx 32rpx 0; background: #FBFBFB; box-sizing: border-box;
view { height: 80rpx; background: #03AE80; border-radius: 64rpx; color: #fff; text-align: center; line-height: 80rpx; font-size: 30rpx; }
}
}
.refund_waper{
width: 100%; background: #fff; box-sizing: border-box; padding: 32rpx 24rpx 20rpx; border-radius: 30rpx 30rpx 0 0;
.title{
line-height: 42rpx; color: rgba(0,0,0,0.65); font-size: 36rpx; font-weight: 500; text-align: center; position: relative;
.icon{ position: absolute; right: 0; top: 0; }
}
.cont{
width: 100%; margin-top: 48rpx;
.u-radio{
line-height: 33rpx; margin-bottom: 24rpx;
&:last-child{ margin-bottom: 0; }
}
.u-radio__text{ color: rgba(0,0,0,0.85) !important; font-size: 28rpx !important; }
}
.btn{ width: 686rpx; height: 80rpx; background: #03AE80; border-radius: 66rpx; text-align: center; line-height: 80rpx; color: #fff; font-size: 32rpx; font-weight: 500; margin: 90rpx auto 0; }
}
</style>