zhwl-miniapp/pages/shop/refund.vue

348 lines
16 KiB
Vue
Raw Normal View History

2025-06-26 12:38:35 +08:00
<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>