初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="title clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/order_list' }">我的订单</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/member/order_detail?order_id=' + order_id }">订单详情</el-breadcrumb-item>
<el-breadcrumb-item>批量退款</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div slot="header" class="shopings clearfix">
<span>选择退款商品</span>
</div>
<el-table ref="multipleTable" :data="orderData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="商品图片" width="100" prop="goods_image">
<template slot-scope="scope">
<img class="box-img" :src="$img(scope.row.sku_image, { size: 'mid' })" alt="" @error="scope.row.sku_image = defaultGoodsImage" />
</template>
</el-table-column>
<el-table-column label="商品名称" prop="goods_name"></el-table-column>
<el-table-column label="价格" width="180" prop="price"></el-table-column>
</el-table>
<div class="flooter">
<div class="flooter-left">
<!-- <el-checkbox v-model="checked">全选</el-checkbox> -->
</div>
<div class="flooter-right">
共计选中{{order_goods_ids.length}}件商品
<el-button v-if="order_goods_ids.length" class="but" type="primary" @click="next">下一步</el-button>
<el-button v-else class="but" type="info">请选择退款商品</el-button>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {
apiOrderDetail
} from "@/api/order/order"
import {
mapGetters
} from 'vuex';
export default {
name: "account_edit",
components: {},
data() {
return {
yes: true,
order_id: 0,
orderData: [],
checked: false,
order_goods_ids: []
}
},
created() {
this.order_id = this.$route.query.order_id
this.getOrderInfo()
},
mounted() {
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
methods: {
/**
* 获取商品数据
*/
getOrderInfo() {
apiOrderDetail({
order_id: this.order_id
}).then((res) => {
if (res.code >= 0) {
this.orderData = [];
res.data.order_goods.forEach((item) => {
if (item.refund_status == 0) {
this.orderData.push(item);
}
})
}
})
},
handleSelectionChange(e) {
this.order_goods_ids = e.map((item, index) => {
return item.order_goods_id;
});
},
next() {
this.$router.push({
path: '/order/orderbatch_refund',
query: {
order_goods_id: this.order_goods_ids.join(','),
order_id: this.order_id
}
});
},
}
}
</script>
<style lang="scss" scoped>
.box-img {
width: 70px;
height: auto;
}
.flooter {
padding: 18px 20px;
box-sizing: border-box;
display: flex;
align-content: center;
justify-content: space-between;
.but {
padding: 10px 20px;
margin-left: 10px;
}
}
.title {
padding: 0 0 18px;
border-bottom: 1px solid #EBEEF5;
}
.shopings {
padding: 18px 0 0;
}
</style>

View File

@@ -0,0 +1,524 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div v-loading="loading">
<!--申请退款 start-->
<div v-if="!complainData.complain_info || action == 'apply'">
<el-card class="box-card order-list">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/activist' }">退款/售后</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/order/refund_detail?order_goods_id=' + orderGoodsId }">退款详情
</el-breadcrumb-item>
<el-breadcrumb-item>平台维权</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!--商品信息-->
<div>
<div class="goods-list">
<table>
<tr>
<td width="62.5%">商品</td>
<td width="12.5%">数量</td>
<td width="12.5%">金额</td>
</tr>
</table>
</div>
</div>
<div>
<div class="goods-list">
<table>
<tr>
<td width="62.5%">
<div class="goods-info">
<div class="goods-info-left">
<router-link :to="{ path: '/sku/' + complainData.order_goods_info.sku_id }" target="_blank">
<img class="goods-img" :src="$img(complainData.order_goods_info.sku_image, { size: 'mid' })" @error="complainData.order_goods_info.sku_image = defaultGoodsImage" />
</router-link>
</div>
<div class="goods-info-right">
<router-link :to="{ path: '/sku/' + complainData.order_goods_info.sku_id }" target="_blank">
<div class="goods-name">{{ complainData.order_goods_info.sku_name }}</div>
</router-link>
</div>
</div>
</td>
<td width="12.5%" class="goods-num">{{ complainData.order_goods_info.num }}</td>
<td width="12.5%" class="goods-money">{{ complainData.order_goods_info.goods_money }}</td>
</tr>
</table>
</div>
</div>
</el-card>
<!--退款填写-->
<div class="item-block">
<div class="block-text"></div>
<el-form ref="form" label-width="80px" class="refund-form">
<el-form-item label="退款金额">
<el-input disabled="" :value="complainData.refund_money"></el-input>
</el-form-item>
<el-form-item label="退款原因">
<el-select placeholder="请选择" v-model="complainReason">
<el-option v-for="(item, itemIndex) in complainData.refund_reason_type" :key="itemIndex" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="退款说明">
<el-input maxlength="140" show-word-limit resize="none" rows="5" placeholder="请输入退款说明(选填)" type="textarea" v-model="complainRemark"/>
</el-form-item>
</el-form>
</div>
<div class="item-block">
<div class="order-submit">
<el-button type="primary" class="el-button--primary" @click="submit">提交</el-button>
</div>
<div class="clear"></div>
</div>
</div>
<!--申请退款 end-->
<div v-else>
<div class="item-block">
<div class="block-text">{{ detail.complain_status_name }}</div>
</div>
<!--协商记录-->
<div class="item-block">
<div class="action-box">
<span class="media-left">协商记录</span>
<div class="media-right">
<div class="el-button--text" @click="actionOpen ? (actionOpen = false) : (actionOpen = true)">
协商记录
<i :class="actionOpen ? 'rotate' : ''" class="el-icon-arrow-down"></i>
</div>
</div>
<div class="clear"></div>
</div>
<div v-if="actionOpen">
<el-timeline>
<el-timeline-item :class="{ buyer: logItem.action_way == 1, seller: logItem.action_way == 2, platform: logItem.action_way == 3 }" v-for="(logItem, logIndex) in detail.refund_log_list" :key="logIndex" :timestamp="$util.timeStampTurnTime(logItem.action_time)" placement="top">
<div>
<h4 v-if="logItem.action_way == 1">买家</h4>
<h4 v-else-if="logItem.action_way == 2">卖家</h4>
<h4 v-else-if="logItem.action_way == 3">平台</h4>
<p>{{ logItem.action }}</p>
</div>
</el-timeline-item>
</el-timeline>
</div>
</div>
<!--退款详情-->
<div class="item-block">
<div class="goods-list">
<table>
<tr>
<td width="62.5%">商品</td>
<td width="12.5%">数量</td>
<td width="12.5%">退款金额</td>
</tr>
</table>
</div>
</div>
<div class="item-block">
<div class="goods-list">
<table>
<tr>
<td width="62.5%">
<div class="goods-info">
<div class="goods-info-left">
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
<img class="goods-img" :src="$img(detail.sku_image, { size: 'mid' })" @error="detail.sku_image = defaultGoodsImage" />
</router-link>
</div>
<div class="goods-info-right">
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
<div class="goods-name">{{ detail.sku_name }}</div>
</router-link>
</div>
</div>
</td>
<td width="12.5%" class="goods-num">{{ detail.num }}</td>
<td width="12.5%" class="goods-money">{{ detail.complain_apply_money }}</td>
</tr>
</table>
</div>
</div>
<div class="item-block">
<div class="order-statistics">
<table>
<tr>
<td align="right">退款原因</td>
<td align="left">{{ detail.complainReason }}</td>
</tr>
<tr>
<td align="right">退款金额</td>
<td align="left">{{ detail.complain_apply_money }}</td>
</tr>
<tr>
<td align="right">退款编号</td>
<td align="left">{{ detail.complain_no }}</td>
</tr>
<tr>
<td align="right">申请时间</td>
<td align="left">{{ $util.timeStampTurnTime(detail.complain_apply_time) }}</td>
</tr>
<tr v-if="detail.complain_time">
<td align="right">退款时间</td>
<td align="left">{{ $util.timeStampTurnTime(detail.complain_time) }}</td>
</tr>
</table>
</div>
<div class="clear"></div>
</div>
<div class="item-block" v-if="detail.complain_action.length">
<div class="order-submit" v-for="(actionItem, actionIndex) in detail.complain_action" :key="actionIndex">
<el-button type="primary" class="el-button--primary" @click="refundAction(actionItem.event)">{{ actionItem.title }}</el-button>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapGetters} from 'vuex';
import {complainData, complain, complainCancel} from '@/api/order/refund';
export default {
name: 'refund',
components: {},
data: () => {
return {
orderGoodsId: 0,
complainData: {
order_goods_info: {
sku_image: '',
sku_name: ''
}
},
detail: {
sku_image: ''
},
complainReason: '',
complainRemark: '',
action: '',
actionOpen: false,
loading: false,
yes: true
};
},
created() {
this.loading = true;
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
this.getComplainData();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
methods: {
/**
* 选择退款方式
* @param {Object} type
*/
selectRefundType(type) {
this.refund_type = type;
},
getComplainData() {
this.loading = true;
complainData({order_goods_id: this.orderGoodsId}).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.complainData = res.data;
this.detail = this.complainData.complain_info;
this.loading = false;
} else {
this.$message({
message: '未获取到该订单项退款信息',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/order_list'});
}
});
}
}).catch(err => {
this.loading = false;
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/order_list'});
}
});
});
},
submit() {
if (this.verify()) {
if (this.isSub) return;
this.isSub = true;
let submit_data = {
order_goods_id: this.orderGoodsId,
complain_reason: this.complainReason,
complain_remark: this.complainRemark
};
complain(submit_data).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.$message({
message: message,
type: 'success'
});
this.getComplainData();
this.$forceUpdate();
this.action = '';
} else {
this.isSub = false;
this.$message({message: message, type: 'warning'});
}
}).catch(err => {
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/order_list'});
}
});
});
}
},
verify() {
if (this.complainReason == '') {
this.$message({message: '请选择退款原因', type: 'warning'});
return false;
}
return true;
},
refundAction(event) {
switch (event) {
case 'complainCancel':
this.cancelRefund(this.detail.order_goods_id);
break;
case 'complainApply':
this.action = 'apply';
break;
}
},
cancelRefund(order_goods_id) {
this.$confirm('撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请', '提示', {
confirmButtonText: '确认撤销',
cancelButtonText: '暂不撤销',
type: 'warning'
}).then(() => {
if (this.isSub) return;
this.isSub = true;
complainCancel({order_goods_id: order_goods_id}).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.$message({
message: '撤销成功',
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/order_list'});
}
});
} else {
this.$message({message: message, type: 'warning'});
}
}).catch(err => {
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/order_list'});
}
});
});
})
}
}
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.clear {
clear: both;
}
.item-block {
padding: 0 15px 1px;
margin: 10px 0;
border-radius: 0;
border: none;
background: #ffffff;
.block-text {
border-color: #eeeeee;
color: $ns-text-color-black;
padding: 7px 0;
border-bottom: 1px;
}
}
.refund-form {
width: 350px;
.el-select {
width: 100%;
}
}
.order-submit {
text-align: center;
padding: 10px;
}
.goods-list {
padding: 15px 0;
table {
width: 100%;
}
.goods-info-left {
width: 60px;
height: 60px;
float: left;
.goods-img {
width: 60px;
height: 60px;
}
}
.goods-info-right {
float: left;
height: 60px;
margin-left: 10px;
color: $base-color;
width: 80%;
.goods-name {
line-height: 20px;
padding-top: 10px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-spec {
color: #999;
}
}
}
.pay-type-list {
padding: 20px 0;
}
.pay-type-item {
display: inline-block;
border: 2px solid #eeeeee;
padding: 5px 20px;
margin-right: 20px;
cursor: pointer;
}
.pay-type-item.active {
border-color: $base-color;
}
.status-wrap {
color: #999;
}
.media-left {
float: left;
}
.media-right {
float: right;
i.rotate {
transform: rotate(180deg);
transition: 0.3s;
}
}
.action-box {
padding: 10px 0;
}
.action-way {
float: left;
color: #999;
}
.head .time {
float: right;
color: #999;
}
.record-item {
margin-bottom: 10px;
}
.order-statistics {
float: left;
padding: 10px;
// color: #999;
}
.el-textarea .el-input__count {
line-height: 20px;
}
</style>

View File

@@ -0,0 +1,434 @@
<template>
<el-form class="ns-evalute" v-loading="loading">
<div class="ns-eva-li" v-for="(item, index) in goodsList" :key="index">
<!-- 商品信息 -->
<div class="ns-eva-good">
<el-image fit="scale-down" :src="$img(item.sku_image, { size: 'mid' })" @error="imageError(index)" @click="toGoodsDetail(item.sku_id)"/>
<p class="ns-eva-good-name" :title="item.sku_name" @click="toGoodsDetail(item.sku_id)">{{ item.sku_name }}</p>
<p>{{ item.price }}</p>
</div>
<!-- 评价表单 -->
<div class="ns-eva-form">
<div class="block" v-if="!isEvaluate">
<span class="demonstration">描述相符</span>
<el-rate v-model="goodsEvalList[index].scores" @change="setStar(index)"></el-rate>
<div class="level">
<i class="iconfont" :class="
goodsEvalList[index].explain_type == '1'
? 'iconhaoping1 ns-text-color'
: goodsEvalList[index].explain_type == '2'
? 'iconzhongchaping ns-text-color'
: goodsEvalList[index].explain_type == '3'
? 'iconzhongchaping'
: ''
"></i>
<span>
{{ goodsEvalList[index].explain_type == '1' ? '好评' : goodsEvalList[index].explain_type == '2' ? '中评' : goodsEvalList[index].explain_type == '3' ? '差评' : ''}}
</span>
</div>
</div>
<div class="ns-textarea">
<el-input v-if="!isEvaluate" type="textarea" :rows="5" placeholder="请在此处输入您的评价" v-model="goodsEvalList[index].content" maxlength="200" show-word-limit/>
<el-input v-else type="textarea" :rows="5" placeholder="请在此处输入您的追评" v-model="goodsEvalList[index].again_content" maxlength="200" show-word-limit/>
</div>
<div class="upload-wrap">
<el-upload ref="upload" :class="{ ishide: hide[index] }" :action="uploadActionUrl" :data="uploadData"
list-type="picture-card" :on-success="
(file, fileList) => {
return handleSuccess(file, fileList, index);
}
" :on-preview="handlePictureCardPreview" :on-remove="
(file, fileList) => {
return handleRemove(file, fileList, index);
}
" :on-exceed="handleExceed" multiple drag :limit="6">
<i class="el-icon-plus"></i>
<!-- <i class="el-icon-upload"></i> -->
<!-- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件且不超过500kb</div> -->
</el-upload>
<el-dialog :visible.sync="dialogVisible"><img width="100%" :src="dialogImageUrl" alt="" /></el-dialog>
<div class="tips">共6张还能上传{{ imgList[index].length ? 6 - imgList[index].length : 6 }}张</div>
</div>
</div>
</div>
<div class="save-btn-wrap">
<el-button @click="save" type="primary">提交</el-button>
</div>
</el-form>
</template>
<script>
import {
mapGetters
} from 'vuex';
import {
orderInfo,
save,
uploadImg
} from '@/api/order/order';
import Config from '@/plugins/config';
export default {
name: 'evaluate',
components: {},
data: () => {
return {
loading: true,
value1: 5,
memberName: '',
memberHeadimg: '',
orderId: null,
orderNo: '',
isAnonymous: 0, //是否匿名发布 1.匿名0.公开
goodsList: [], //订单列表
goodsEvalList: [], //评价列表
imgList: [],
isEvaluate: 0, //判断是否为追评
flag: false, //防止重复点击
siteName: '', // 店铺名称
shop_deliverycredit: 5, // 配送服务分值
shop_desccredit: 5, // 描述相符分值
shop_servicecredit: 5, // 服务态度分值
uploadActionUrl: Config.baseUrl + '/api/upload/evaluateimg',
uploadData: {
app_type: "pc",
app_type_name: "PC"
},
dialogImageUrl: '',
dialogVisible: false,
hide: []
};
},
created() {
this.orderId = this.$route.query.order_id;
this.getUserInfo();
if (this.orderId) {
this.getOrderInfo();
}
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
methods: {
handleSuccess(file, fileList, index) {
let arr = this.imgList[index];
arr = arr.concat(file.data.pic_path);
this.imgList[index] = [];
this.$set(this.imgList, index, arr);
if (this.isEvaluate) {
this.goodsEvalList[index].again_images = this.imgList[index].toString();
} else {
this.goodsEvalList[index].images = this.imgList[index].toString();
}
if (this.imgList[index].length >= 6) {
this.hide[index] = true;
}
},
handleRemove(file, fileList, index) {
let i = this.$util.inArray(file.response.data.pic_path, this.imgList[index]);
this.imgList[index].splice(i, 1);
if (this.isEvaluate) {
this.goodsEvalList[index].again_images = this.imgList[index].toString();
} else {
this.goodsEvalList[index].images = this.imgList[index].toString();
}
if (this.imgList[index].length < 6) {
this.hide[index] = false;
}
},
handleExceed(file, fileList) {
// 图片数量大于6
this.$message.warning('上传图片最大数量为6张');
},
handlePictureCardPreview(file) {
// 点开大图
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
//获取用户信息
getUserInfo() {
this.$store
.dispatch('member/member_detail', {
refresh: 1
}).then(res => {
this.memberName = res.data.nickname;
this.memberHeadimg = res.data.headimg;
}).catch(err => {
this.$message.error(err.message);
});
},
//获取订单信息
getOrderInfo() {
//获取订单信息
orderInfo({
order_id: this.orderId
}).then(res => {
if (res.code == 0) {
this.isEvaluate = res.data.evaluate_status;
this.orderNo = res.data.list[0].order_no;
this.goodsList = res.data.list;
this.siteName = res.data.list[0].site_name;
if (this.isEvaluate) {
for (let i = 0; i < res.data.list.length; i++) {
let array = [];
this.imgList.push(array);
this.hide.push(false);
this.goodsEvalList.push({
order_goods_id: res.data.list[i].order_goods_id,
goods_id: res.data.list[i].goods_id,
sku_id: res.data.list[i].sku_id,
again_content: '',
again_images: '',
site_id: res.data.list[i].site_id
});
}
} else {
for (let i = 0; i < res.data.list.length; i++) {
let array = [];
this.imgList.push(array);
this.goodsEvalList.push({
content: '', // 评价内容
images: '', //图片数组
scores: 5, // 评分
explain_type: 1, // 评价类型
order_goods_id: res.data.list[i].order_goods_id,
goods_id: res.data.list[i].goods_id,
sku_id: res.data.list[i].sku_id,
sku_name: res.data.list[i].sku_name,
sku_price: res.data.list[i].price,
sku_image: res.data.list[i].sku_image,
site_id: res.data.list[i].site_id
});
}
}
}
this.loading = false;
}).catch(err => {
this.$message.error(err.message);
this.$router.push('/member/order_list');
this.loading = false;
});
},
//监听评分变化
setStar(index) {
if (this.goodsEvalList[index].scores >= 4) {
this.goodsEvalList[index].explain_type = 1;
} else if (1 < this.goodsEvalList[index].scores && this.goodsEvalList[index].scores < 4) {
this.goodsEvalList[index].explain_type = 2;
} else {
this.goodsEvalList[index].explain_type = 3;
}
},
imageError(index) {
this.goodsList[index].sku_image = this.defaultGoodsImage;
},
/**
* 提交
*/
save() {
for (let i = 0; i < this.goodsEvalList.length; i++) {
if (this.isEvaluate) {
if (!this.goodsEvalList[i].again_content.trim().length) {
this.$message({
message: '商品的评价不能为空哦',
type: 'warning'
});
return;
}
} else {
if (!this.goodsEvalList[i].content.trim().length) {
this.$message({
message: '商品的评价不能为空哦',
type: 'warning'
});
return;
}
}
}
let goodsEvaluate = JSON.stringify(this.goodsEvalList);
let data = {
order_id: this.orderId,
goods_evaluate: goodsEvaluate,
isEvaluate: this.isEvaluate
};
if (!this.isEvaluate) {
data.order_no = this.orderNo;
data.member_name = this.memberName;
data.member_headimg = this.memberHeadimg;
data.is_anonymous = this.isAnonymous;
}
if (this.flag) return;
this.flag = true;
save(data).then(res => {
if (res.code == 0) {
this.$message({
message: '评价成功',
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/order_list'
});
}
});
} else {
this.$message({
message: res.message,
type: 'warning'
});
this.flag = false;
}
}).catch(err => {
this.$message.error(err.message);
this.flag = false;
});
},
/**
* 跳转到商品详情
*/
toGoodsDetail(id) {
this.$util.pushToTab('sku-' + id);
}
}
};
</script>
<style lang="scss" scoped>
.ns-evalute {
margin: 20px 0;
background: #ffffff;
padding: 30px;
border-radius: 5px;
.ns-eva-li {
display: flex;
padding: 20px 0;
border-bottom: 1px solid #eeeeee;
.ns-eva-good {
width: 30%;
text-align: center;
.el-image {
width: 125px;
height: 125px;
cursor: pointer;
}
.ns-eva-good-name {
width: 250px;
margin: 0 auto;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
cursor: pointer;
}
}
}
.ns-eva-form {
width: 70%;
.ns-textarea {
position: relative;
}
.upload-wrap {
.tips {
margin-top: 10px;
}
}
.level {
display: inline-block;
margin-left: 50px;
i {
margin-right: 5px;
vertical-align: top;
}
}
.el-textarea {
margin: 10px 0;
}
}
.el-rate {
display: inline-block;
vertical-align: middle;
}
.save-btn-wrap {
text-align: center;
margin-top: 20px;
}
.el-dialog {
img {
width: auto;
margin: 0 auto;
}
}
}
</style>
<style lang="scss">
.ns-evalute {
.el-upload--picture-card {
border: none;
}
.el-upload--picture-card,
.el-upload-list--picture-card .el-upload-list__item {
width: 70px;
height: 70px;
line-height: 80px;
position: relative;
}
.el-upload-list--picture-card .el-upload-list__item-thumbnail {
width: 100%;
height: auto;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.el-upload-list__item.is-success .el-upload-list__item-status-label {
display: none;
}
.ishide .el-upload--picture-card {
display: none;
}
.upload-wrap .el-upload-dragger {
width: 70px;
height: 70px;
}
.el-dialog {
.el-dialog__body {
text-align: center;
}
}
}
</style>

View File

@@ -0,0 +1,184 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card logistics">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/order_list' }">订单列表</el-breadcrumb-item>
<el-breadcrumb-item>物流详情</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div v-loading="loading">
<el-tabs v-model="activeParcel">
<el-tab-pane v-for="(packageItem, packageIndex) in packageList" :key="packageIndex" :label="packageItem.package_name" :name="'parcel_' + packageIndex">
<div class="trace" v-if="packageItem.trace.success && packageItem.trace.list.length > 0">
<el-timeline>
<el-timeline-item v-for="(traceItem, traceIndex) in packageItem.trace.list" :timestamp="traceItem.datetime" placement="top" :type="traceIndex == 0 ? 'primary' : ''" :key="traceIndex">
<p>{{ traceItem.remark }}</p>
</el-timeline-item>
</el-timeline>
</div>
<div class="trace" v-else>
<p class="empty-wrap">{{ packageItem.trace.reason }}</p>
</div>
<ul class="info-wrap">
<li>
<label>运单号码</label>
<span>{{ packageItem.delivery_no }}</span>
</li>
<li>
<label>物流公司</label>
<span>{{ packageItem.express_company_name }}</span>
</li>
</ul>
<ul class="goods-wrap">
<li v-for="(goodsItem, goodsIndex) in packageItem.goods_list" :key="goodsIndex" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
<div class="img-wrap">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(packageIndex, goodsIndex)" />
</div>
<p class="sku-name">{{ goodsItem.sku_name }} x {{ goodsItem.num }}</p>
</li>
</ul>
</el-tab-pane>
</el-tabs>
</div>
</el-card>
</div>
</template>
<script>
import {apiOrderPackageInfo} from '@/api/order/order';
import {mapGetters} from 'vuex';
export default {
name: 'logistics',
components: {},
data: () => {
return {
orderId: 0,
loading: true,
activeParcel: 'parcel_0',
packageList: [],
yes: true
};
},
created() {
this.orderId = this.$route.query.order_id;
if (!this.orderId) this.$router.push({path: '/member/order_list'});
this.getOrderPackageInfo();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
getOrderPackageInfo() {
apiOrderPackageInfo({
order_id: this.orderId
}).then(res => {
if (res.code >= 0) {
this.packageList = res.data;
this.packageList.forEach(item => {
if (item.trace.list) {
item.trace.list = item.trace.list.reverse();
}
});
this.loading = false;
} else {
this.$message({
message: '未获取到订单包裹信息!',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/order_list'});
}
});
}
}).catch(res => {
this.loading = false;
});
},
imageError(packageIndex, goodsIndex) {
this.packageList[packageIndex].goods_list[goodsIndex].sku_image = this.defaultGoodsImage;
}
}
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.logistics {
.trace {
.empty-wrap {
padding: 10px 0;
}
}
.info-wrap {
overflow: hidden;
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
span {
font-weight: bold;
}
}
}
.goods-wrap {
overflow: hidden;
margin: 10px 0;
li {
float: left;
width: 130px;
margin-right: 7px;
cursor: pointer;
&:nth-child(n + 7) {
margin-right: 0;
}
.img-wrap {
width: 120px;
}
.sku-name {
margin-top: 5px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: $ns-font-size-sm;
}
}
}
}
</style>

View File

@@ -0,0 +1,377 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div v-loading="loading">
<el-card class="box-card order-list">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/order_list' }">我的订单</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/member/order_detail?order_id=' + orderId }">订单详情</el-breadcrumb-item>
<el-breadcrumb-item>退款</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!--商品信息-->
<div class="goods-list">
<table>
<tr>
<td width="62.5%">商品</td>
<td width="12.5%">数量</td>
<td width="12.5%">金额</td>
</tr>
</table>
</div>
<div class="goods-list">
<table>
<tr v-for="(item,index) in refundData.order_goods_info" :key="index">
<td width="62.5%">
<div class="goods-info">
<div class="goods-info-left" v-if="item.sku_image">
<router-link :to="{ path: '/sku/' + item.sku_id }" target="_blank">
<img class="goods-img" :src="$img(item.sku_image, { size: 'mid' })" @error="item.sku_image = defaultGoodsImage" />
</router-link>
</div>
<div class="goods-info-right">
<router-link :to="{ path: '/sku/' + item.sku_id }" target="_blank">
<div class="goods-name">{{ item.sku_name }}</div>
</router-link>
</div>
</div>
</td>
<td width="12.5%" class="goods-num">{{ item.num }}</td>
<td width="12.5%" class="goods-money">{{ item.goods_money }}</td>
</tr>
</table>
</div>
</el-card>
<!--退款类型 -->
<div class="item-block">
<div class="block-text">退款类型</div>
<div class="pay-type-list">
<div class="pay-type-item" :class="refundType == 1 ? 'active' : ''" @click="selectRefundType(1)">退款无需退货</div>
<div v-if="refundData.refund_type.length == 2" class="pay-type-item" :class="refundType == 2 ? 'active' : ''" @click="selectRefundType(2)">退货退款</div>
<div class="clear"></div>
</div>
</div>
<!--退款填写-->
<div class="item-block">
<div class="block-text"></div>
<el-form ref="form" label-width="80px" class="refund-form">
<el-form-item label="退款金额">
<el-input disabled="" :value="refundData.refund_money"></el-input>
</el-form-item>
<el-form-item label="退款原因">
<el-select placeholder="请选择" v-model="refundReason">
<el-option v-for="(item, itemIndex) in refundData.refund_reason_type" :key="itemIndex" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="退款说明">
<el-input maxlength="140" show-word-limit resize="none" rows="5" placeholder="请输入退款说明(选填)" type="textarea" v-model="refundRemark"/>
</el-form-item>
</el-form>
</div>
<div class="item-block">
<div class="order-submit">
<el-button type="primary" class="el-button--primary" @click="submit">提交</el-button>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</template>
<script>
import {refundDataBatch, refund} from '@/api/order/refund';
import {mapGetters} from 'vuex';
export default {
name: 'refund',
components: {},
data: () => {
return {
orderGoodsId: '',
orderId: '',
refundType: 1,
refundReason: '',
refundRemark: '',
isIphoneX: false,
refundData: {
refund_type: [],
order_goods_info: {
sku_image: ''
}
},
isSub: false,
show_type: 0, //退款状态 1-待退款 2-已退款
detail: {
refund_action: []
},
loading: true,
yes: true
};
},
created() {
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
if (this.$route.query.order_id) this.orderId = this.$route.query.order_id;
this.getRefundData();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
/**
* 选择退款方式
* @param {Object} type
*/
selectRefundType(type) {
this.refundType = type;
},
getRefundData() {
refundDataBatch({order_goods_ids: this.orderGoodsId}).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.refundData = data;
} else {
this.$message({
message: '未获取到该订单项退款信息!',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
}
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
});
},
submit() {
if (this.verify()) {
if (this.isSub) return;
this.isSub = true;
let submit_data = {
order_goods_ids: this.orderGoodsId,
refund_type: this.refundType,
refund_reason: this.refundReason,
refund_remark: this.refundRemark
};
refund(submit_data).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.$message({
message: '申请成功!',
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
} else {
this.isSub = false;
this.$message({message: message, type: 'warning'});
}
}).catch(err => {
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
});
}
},
verify() {
if (this.refundReason == '') {
this.$message({message: '请选择退款原因', type: 'warning'});
return false;
}
return true;
}
}
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.clear {
clear: both;
}
.item-block {
padding: 0 15px 1px;
margin: 10px 0;
border-radius: 0;
border: none;
background: #ffffff;
.block-text {
border-color: #eeeeee;
color: $ns-text-color-black;
padding: 7px 0;
border-bottom: 1px;
}
}
.refund-form {
width: 350px;
.el-select {
width: 100%;
}
}
.order-submit {
text-align: center;
padding: 10px;
}
.goods-list {
padding: 15px 0;
table {
width: 100%;
}
.goods-info-left {
width: 60px;
height: 60px;
float: left;
.goods-img {
width: 60px;
height: 60px;
}
}
.goods-info-right {
float: left;
height: 60px;
margin-left: 10px;
color: $base-color;
width: 80%;
.goods-name {
line-height: 20px;
padding-top: 10px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-spec {
color: #999;
}
}
}
.pay-type-list {
padding: 20px 0;
}
.pay-type-item {
display: inline-block;
border: 2px solid #eeeeee;
padding: 5px 20px;
margin-right: 20px;
cursor: pointer;
}
.pay-type-item.active {
border-color: $base-color;
}
.status-wrap {
color: #999;
}
.media-left {
float: left;
}
.media-right {
float: right;
i.rotate {
transform: rotate(180deg);
transition: 0.3s;
}
}
.action-box {
padding: 10px 0;
}
.action-way {
float: left;
color: #999;
}
.head .time {
float: right;
color: #999;
}
.record-item {
margin-bottom: 10px;
}
.order-statistics {
float: left;
padding: 10px;
// color: #999;
}
.el-textarea .el-input__count {
line-height: 20px;
}
</style>

View File

@@ -0,0 +1,417 @@
<template>
<div class="payment-wrap" v-loading="fullscreenLoading">
<!--购买虚拟类商品需填写您的手机号-->
<div class="item-block" v-if="orderPaymentData.is_virtual == 1">
<div class="block-text">购买虚拟类商品需填写您的手机号以方便商家与您联系</div>
<el-form ref="form" size="mini" class="mobile-wrap" label-width="80px">
<el-form-item label="手机号码">
<el-input placeholder="请输入您的手机号码" maxlength="11" v-model="orderCreateData.member_address.mobile" @input="virtualMobileChange" />
</el-form-item>
</el-form>
</div>
<!--收货地址-->
<div class="item-block" v-if="orderPaymentData.is_virtual == 0">
<div class="block-text">收货地址</div>
<div class="address-list">
<div class="address-item" @click="addAddressShow">
<div class="add-address">
<i class="el-icon-circle-plus-outline"></i>
添加收货地址
</div>
</div>
<div class="address-item" v-for="(item, key) in memberAddress" :key="item.id" :class="addressId == item.id ? 'active' : ''" v-if="key < 3 || (addressShow && key >= 3)">
<div class="address-info">
<div class="options">
<div @click="editAddress(item.id)">编辑</div>
<template v-if="item.is_default == 0">
<el-popconfirm title="确定要删除该地址吗?" @onConfirm="deleteMemberAddress(item.id)">
<div slot="reference">删除</div>
</el-popconfirm>
</template>
</div>
<div class="address-name">{{ item.name }}</div>
<div class="address-mobile" @click="setMemberAddress(item.id)">{{ item.mobile }}</div>
<div class="address-desc" @click="setMemberAddress(item.id)">{{ item.full_address }} {{ item.address }}
</div>
</div>
</div>
<div v-if="memberAddress.length > 3 && !addressShow" @click="addressShow = true" class="el-button--text address-open">
<i class="el-icon-arrow-down"></i>
更多收货地址
</div>
<div class="clear"></div>
</div>
</div>
<!--收货地址添加-->
<el-dialog :title="addressForm.id == 0 ? '添加收货地址' : '编辑收货地址'" :visible.sync="dialogVisible" width="32%">
<el-form ref="form" :rules="addressRules" :model="addressForm" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="addressForm.name" placeholder="收货人姓名" />
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="addressForm.mobile" maxlength="11" placeholder="收货人手机号" />
</el-form-item>
<el-form-item label="电话">
<el-input v-model="addressForm.telephone" placeholder="收货人固定电话(选填)" />
</el-form-item>
<el-form-item class="area" label="地区" prop="area">
<el-row :gutter="10">
<el-col :span="7">
<el-select prop="province" ref="province" v-model="addressForm.province_id" @change="getAddress(1)" placeholder="请选择省">
<el-option label="请选择省" value="0"></el-option>
<el-option v-for="item in pickerValueArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="7">
<el-select ref="city" prop="city" v-model="addressForm.city_id" @change="getAddress(2)" placeholder="请选择市">
<el-option label="请选择市" value="0"></el-option>
<el-option v-for="item in cityArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="7">
<el-select ref="district" prop="district" v-model="addressForm.district_id" placeholder="请选择区/县">
<el-option label="请选择区/县" value="0"></el-option>
<el-option v-for="item in districtArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="详细地址" prop="address">
<el-input v-model="addressForm.address" placeholder="定位小区、街道、写字楼" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="addmemberAddress('form')"> </el-button>
</span>
</el-dialog>
<!--使用余额-->
<div class="item-block" v-if="orderPaymentData.member_account.balance_total > 0 && balance_show == 1">
<div class="block-text">是否使用余额</div>
<div class="pay-type-list">
<div class="pay-type-item" :class="orderCreateData.is_balance ? '' : 'active'" @click="useBalance(0)">不使用余额
</div>
<div class="pay-type-item" :class="orderCreateData.is_balance ? 'active' : ''" @click="useBalance(1)">使用余额</div>
<div class="clear"></div>
</div>
</div>
<!-- 支付密码 -->
<el-dialog title="使用余额" :visible.sync="dialogpay" width="350px">
<template v-if="orderPaymentData.member_account.is_pay_password == 0">
<p>为了您的账户安全,请您先设置的支付密码</p>
<p>可到"会员中心","账号安全","支付密码"中设置</p>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogpay = false">暂不设置</el-button>
<el-button size="small" type="primary" @click="setPayPassword">立即设置</el-button>
</span>
</template>
<el-form v-else status-icon ref="ruleForm" label-width="100px">
<el-form-item label="支付密码" class="pay-password-item">
<!--添加一个不可见的input,欺骗浏览器自动填充-->
<el-input type="password" class="pay-password hide-password" :maxlength="6"></el-input>
<el-input type="password" class="pay-password" :maxlength="6" v-model="password" @input="input"></el-input>
</el-form-item>
<p class="ns-text-color forget-password" @click="setPayPassword">忘记密码</p>
</el-form>
</el-dialog>
<!--使用积分抵扣-->
<div class="item-block" v-if="calculateData && calculateData.max_usable_point > 0">
<div class="block-text">是否使用积分</div>
<div class="pay-type-list">
<div class="pay-type-item" :class="orderCreateData.is_point ? '' : 'active'" @click="usePoint(0)">不使用积分</div>
<div class="pay-type-item" :class="orderCreateData.is_point ? 'active' : ''" @click="usePoint(1)">使用积分</div>
<div class="clear"></div>
</div>
</div>
<!-- 配送方式 -->
<div class="item-block padd-bom-20" v-if="orderPaymentData.delivery.express_type.length > 0">
<div class="block-text">
<span>配送方式</span>
<span class="distribution" v-if="orderCreateData.delivery.delivery_type == 'store'">{{ orderCreateData.delivery.store_name }}</span>
</div>
<div class="pay-type-item" v-for="(item, index) in orderPaymentData.delivery.express_type" :key="index" @click="selectDeliveryType(item)" :class="item.name == orderCreateData.delivery.delivery_type ? 'active' : ''">
{{ item.title }}
</div>
</div>
<!--配送方式 门店 -->
<el-dialog title="选择门店" :visible.sync="dialogStore" width="50%">
<el-table ref="singleTable" :data="storeList" highlight-current-row @row-click="selectStore" class="cursor-pointer">
<el-table-column label="" width="55">
<template slot-scope="scope">
<el-radio v-model="storeRadio" :label="scope.row"><i></i></el-radio>
</template>
</el-table-column>
<el-table-column prop="store_name" label="名称" width="160"></el-table-column>
<el-table-column prop="store_address" label="地址"></el-table-column>
<el-table-column prop="open_date" label="营业时间"></el-table-column>
</el-table>
</el-dialog>
<div class="item-block" v-if="orderPaymentData.invoice && orderPaymentData.invoice.invoice_status == 1">
<div class="block-text">发票信息</div>
<div class="pay-type-list">
<div class="pay-type-item" :class="orderCreateData.is_invoice == 0 ? 'active' : ''" @click="changeIsInvoice">
无需发票
</div>
<div class="pay-type-item" :class="orderCreateData.is_invoice == 1 ? 'active' : ''" @click="changeIsInvoice">
需要发票
</div>
<div class="clear"></div>
</div>
<div class="invoice-information" v-if="orderCreateData.is_invoice == 1">
<div class="invoice-title">
<div class="invoice-type-box invoice-title-box">
<span class="invoice-name">发票类型</span>
<label class="invoice-to-type">
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 1 ? 'active' : ''" @click="clickType(1)"></i>
<span>纸质</span>
</label>
<label class="invoice-to-type">
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 2 ? 'active' : ''" @click="clickType(2)"></i>
<span>电子</span>
</label>
</div>
<div class="invoice-type-box invoice-title-box">
<span class="invoice-name">抬头类型</span>
<label class="invoice-to-type">
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 1 ? 'active' : ''" @click="clickTitleType(1)"></i>
<span>个人</span>
</label>
<label class="invoice-to-type">
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 2 ? 'active' : ''" @click="clickTitleType(2)"></i>
<span>企业</span>
</label>
</div>
</div>
<div class="invoice-type-box">
<span class="invoice-name">发票信息</span>
<div class="invoice-box-form">
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
<input type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" v-if="orderCreateData.invoice_title_type == 2" />
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-show="orderCreateData.invoice_type == 1" />
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-show="orderCreateData.invoice_type == 2" />
</div>
</div>
<div class="invoice-condition">
<span class="invoice-name">发票内容</span>
<div class="invoice-box-form">
<span class="option-item" :key="index" v-for="(item, index) in orderPaymentData.invoice.invoice_content_array" @click="changeInvoiceContent(item)" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }">{{ item }}</span>
</div>
</div>
<div class="invoice-tops">发票内容将以根据税法调整具体请以展示为准发票内容显示详细商品名 称及价格信息</div>
</div>
</div>
<!--商品信息-->
<div class="item-block">
<div class="goods-list">
<table>
<tr>
<td width="50%">商品</td>
<td width="12.5%">价格</td>
<td width="12.5%">数量</td>
<td width="12.5%">小计</td>
</tr>
</table>
</div>
</div>
<div>
<div class="item-block" v-if="calculateData">
<div class="goods-list">
<table>
<tr v-for="(goodsItem, goodsIndex) in calculateData.goods_list" :key="goodsIndex">
<td width="50%">
<div class="goods-info">
<div class="goods-info-left">
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
<img class="goods-img" :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
</router-link>
</div>
<div class="goods-info-right">
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
<div class="goods-name">{{ goodsItem.goods_name }}</div>
</router-link>
<!-- 规格 -->
<div class="goods-spec" v-if="goodsItem.sku_spec_format">
<span v-for="(x, i) in goodsItem.sku_spec_format" :key="i">{{ x.spec_value_name }}</span>
</div>
</div>
</div>
</td>
<td width="12.5%" class="goods-price">{{ goodsItem.price }}</td>
<td width="12.5%" class="goods-num">{{ goodsItem.num }}</td>
<td width="12.5%" class="goods-money">{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</td>
</tr>
</table>
</div>
</div>
</div>
<!--优惠券-->
<div class="item-block" v-if="calculateData && couponList.length">
<div class="block-text">优惠券</div>
<div class="order-cell platform-coupon">
<div v-if="calculateData.coupon_money != 0">
<span class="ns-text-color" @click="openPlatformCoupon">已选择优惠券已优惠</span>
<span class="ns-text-color" @click="openPlatformCoupon">
<span class="inline"></span>
{{ calculateData.coupon_money }}
</span>
</div>
<div v-else>
<div class="box ns-text-color" @click="openPlatformCoupon">不使用优惠券</div>
</div>
</div>
</div>
<!-- 活动优惠 -->
<div class="item-block" v-if="promotionInfo">
<div class="block-text">{{ promotionInfo.title }}</div>
<div class="order-cell platform-coupon">
<div class="box ns-text-color" v-html="promotionInfo.content"></div>
</div>
</div>
<!--优惠券弹框-->
<el-dialog title="选择优惠券" :visible.sync="dialogPlatcoupon" width="50%" @close="savePlatformCoupon()">
<el-table ref="platformCouponTable" :data="couponList" highlight-current-row @row-click="selectPlatformCoupon" class="cursor-pointer">
<el-table-column label="" width="55">
<template slot-scope="scope">
<div class="disabled-selected-wrap">
<el-radio v-model="platformCouponRadio" :label="scope.row"><i></i></el-radio>
</div>
</template>
</el-table-column>
<el-table-column prop="platformcoupon_name" label="名称" width="200">
<template slot-scope="scope">
<span>{{ scope.row.coupon_name }}</span>
</template>
</el-table-column>
<el-table-column prop="money" label="优惠">
<template slot-scope="scope">
<template v-if="scope.row.type == 'divideticket'">
<span class="money">{{ parseFloat(scope.row.money) }}</span>
</template>
<template v-else-if="scope.row.type == 'reward'">
<span class="money">{{ parseFloat(scope.row.money) }}</span>
</template>
<template v-else-if="scope.row.type == 'discount'">
<span class="money">{{ parseFloat(scope.row.discount) }}</span>
</template>
</template>
</el-table-column>
<el-table-column label="使用">
<template slot-scope="scope">
<span class="ns-text-color-gray ns-font-size-sm" v-if="scope.row.at_least > 0">{{ scope.row.at_least }}可用</span>
<span class="ns-text-color-gray ns-font-size-sm" v-else>无门槛</span>
</template>
</el-table-column>
<el-table-column label="有效期">
<template slot-scope="scope">
<span>{{ scope.row.end_time ? $util.timeStampTurnTime(scope.row.end_time) : '长期有效' }}</span>
</template>
</el-table-column>
</el-table>
<br />
<div class="align-right">
<el-button @click="dialogPlatcoupon = false">取消</el-button>
<el-button @click="dialogPlatcoupon = false" type="primary">确认选择</el-button>
</div>
</el-dialog>
<!-- 买家留言 -->
<div class="item-block padd-bom-10">
<div class="block-text">买家留言</div>
<el-input rows="3" type="textarea" placeholder="留言前建议先与商家协调一致" v-model="orderCreateData.buyer_message" class="buyer-message" @input="textarea" maxlength="140" show-word-limit resize="none" />
</div>
<!-- 总计 -->
<div class="item-block" v-if="calculateData">
<div class="order-statistics">
<table>
<tr>
<td align="right">商品金额</td>
<td align="left">{{ calculateData.goods_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
<td align="right">运费</td>
<td align="left">{{ calculateData.delivery_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.invoice_money > 0">
<td align="right">发票税费<span class="ns-text-color">({{ calculateData.invoice.invoice_rate }}%)</span></td>
<td align="left">{{ calculateData.invoice_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.invoice_delivery_money > 0">
<td align="right">发票邮寄费</td>
<td align="left">{{ calculateData.invoice_delivery_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.promotion_money > 0">
<td align="right">优惠</td>
<td align="left">{{ calculateData.promotion_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.coupon_money > 0">
<td align="right">优惠券</td>
<td align="left">{{ calculateData.coupon_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.point_money > 0">
<td align="right">积分抵扣</td>
<td align="left">{{ calculateData.point_money | moneyFormat }}</td>
</tr>
<tr v-if="calculateData.balance_money > 0">
<td align="right">使用余额</td>
<td align="left">{{ calculateData.balance_money | moneyFormat }}</td>
</tr>
</table>
</div>
<div class="clear"></div>
</div>
<!--结算-->
<div class="item-block" v-if="calculateData">
<div class="order-submit">
<div class="order-money">
{{ calculateData.goods_num }}应付金额
<div class="ns-text-color">{{ calculateData.pay_money | moneyFormat }}</div>
</div>
<el-button type="primary" class="el-button--primary" @click="orderCreate">订单结算</el-button>
</div>
<div class="clear"></div>
</div>
</div>
</template>
<script>
import detail from '@/assets/js/order/payment.js';
export default {
name: 'payment',
mixins: [detail]
};
</script>
<style lang="scss" scoped>
@import '@/assets/css/order/payment.scss';
</style>

View File

@@ -0,0 +1,482 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div v-loading="loading">
<el-card class="box-card order-list">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/order_list' }">我的订单</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/member/order_detail?order_id=' + orderId }">订单详情</el-breadcrumb-item>
<el-breadcrumb-item>退款</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!--商品信息-->
<div class="goods-list">
<table>
<tr>
<td width="62.5%">商品</td>
<td width="12.5%">数量</td>
<td width="12.5%">金额</td>
</tr>
</table>
</div>
<div class="goods-list">
<table>
<tr>
<td width="62.5%">
<div class="goods-info">
<div class="goods-info-left">
<router-link :to="{ path: '/sku/' + refundData.order_goods_info.sku_id }" target="_blank">
<img class="goods-img" :src="$img(refundData.order_goods_info.sku_image, { size: 'mid' })" @error="refundData.order_goods_info.sku_image = defaultGoodsImage" />
</router-link>
</div>
<div class="goods-info-right">
<router-link :to="{ path: '/sku/' + refundData.order_goods_info.sku_id }" target="_blank">
<div class="goods-name">{{ refundData.order_goods_info.sku_name }}</div>
</router-link>
</div>
</div>
</td>
<td width="12.5%" class="goods-num">{{ refundData.order_goods_info.num }}</td>
<td width="12.5%" class="goods-money">{{ refundData.order_goods_info.goods_money }}</td>
</tr>
</table>
</div>
</el-card>
<!--退款类型 -->
<div class="item-block">
<div class="block-text">退款类型</div>
<div class="pay-type-list">
<div class="pay-type-item" :class="refundType == 1 ? 'active' : ''" @click="selectRefundType(1)">退款无需退货</div>
<div v-if="refundData.refund_type.length == 2" class="pay-type-item" :class="refundType == 2 ? 'active' : ''" @click="selectRefundType(2)">退货退款</div>
<div class="clear"></div>
</div>
</div>
<!--退款填写-->
<div class="item-block">
<div class="block-text"></div>
<el-form ref="form" label-width="80px" class="refund-form">
<el-form-item label="退款金额">
<el-input disabled="" :value="refundData.refund_money"></el-input>
</el-form-item>
<el-form-item label="退款原因">
<el-select placeholder="请选择" v-model="refundReason">
<el-option v-for="(item, itemIndex) in refundData.refund_reason_type" :key="itemIndex" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="退款说明">
<el-input maxlength="140" show-word-limit resize="none" rows="5" placeholder="请输入退款说明(选填)" type="textarea" v-model="refundRemark"/>
</el-form-item>
<el-form-item label="退款图片">
<div class="upload-wrap">
<el-upload ref="upload" :class="{ ishide: hide }" :action="uploadActionUrl" :data="uploadData"
list-type="picture-card" :on-success="
(file, fileList) => {
return handleSuccess(file, fileList);
}
" :on-preview="handlePictureCardPreview" :on-remove="
(file, fileList) => {
return handleRemove(file, fileList);
}
" :on-exceed="handleExceed" multiple drag :limit="5">
<i class="el-icon-plus"></i>
<!-- <i class="el-icon-upload"></i> -->
<!-- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件且不超过500kb</div> -->
</el-upload>
<el-dialog :visible.sync="dialogVisible"><img width="100%" :src="dialogImageUrl" alt="" /></el-dialog>
<div class="tips">共5张还能上传{{ imgList.length ? 5 - imgList.length : 5 }}张</div>
</div>
</el-form-item>
</el-form>
</div>
<div class="item-block">
<div class="order-submit">
<el-button type="primary" class="el-button--primary" @click="submit">提交</el-button>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</template>
<script>
import {refundData, refund, detail, delivery} from '@/api/order/refund';
import {mapGetters} from 'vuex';
import Config from '@/plugins/config';
export default {
name: 'refund',
components: {},
data: () => {
return {
orderGoodsId: '',
orderId: '',
refundType: 1,
refundReason: '',
refundRemark: '',
isIphoneX: false,
refundData: {
refund_type: [],
order_goods_info: {
sku_image: ''
}
},
isSub: false,
show_type: 0, //退款状态 1-待退款 2-已退款
detail: {
refund_action: []
},
loading: true,
yes: true,
dialogVisible: false,
hide: false,
uploadActionUrl: Config.baseUrl + '/api/upload/refundimg',
uploadData: {
app_type: "pc",
app_type_name: "PC"
},
imgList: [],
dialogImageUrl: '',
};
},
created() {
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
if (this.$route.query.order_id) this.orderId = this.$route.query.order_id;
this.getRefundData();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
handleRemove(file, fileList) {
let i = this.$util.inArray(file.response.data.pic_path, this.imgList);
this.imgList.splice(i, 1);
if (this.imgList.length < 5) {
this.hide = false;
}
},
handleSuccess(file, fileList) {
let arr = this.imgList;
arr = arr.concat(file.data.pic_path);
this.imgList = arr;
if (this.imgList.length >= 5) {
this.hide = true;
}
},
handleExceed(file, fileList) {
// 图片数量大于5
this.$message.warning('上传图片最大数量为5张');
},
handlePictureCardPreview(file) {
// 点开大图
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
/**
* 选择退款方式
* @param {Object} type
*/
selectRefundType(type) {
this.refundType = type;
},
getRefundData() {
refundData({order_goods_id: this.orderGoodsId}).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.refundData = data;
} else {
this.$message({
message: '未获取到该订单项退款信息!',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
}
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
});
},
submit() {
if (this.verify()) {
if (this.isSub) return;
this.isSub = true;
let submit_data = {
order_goods_ids: this.orderGoodsId,
refund_type: this.refundType,
refund_reason: this.refundReason,
refund_remark: this.refundRemark,
refund_images: this.imgList.toString()
};
refund(submit_data).then(res => {
const {code, message, data} = res;
if (code >= 0) {
this.$message({
message: '申请成功!',
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
} else {
this.isSub = false;
this.$message({message: message, type: 'warning'});
}
}).catch(err => {
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({path: '/member/activist'});
}
});
});
}
},
verify() {
if (this.refundReason == '') {
this.$message({message: '请选择退款原因', type: 'warning'});
return false;
}
return true;
}
}
};
</script>
<style lang="scss">
.upload-wrap .el-upload--picture-card {
border: none;
}
.upload-wrap .el-upload--picture-card,
.upload-wrap .el-upload-list--picture-card .el-upload-list__item {
width: 70px;
height: 70px;
line-height: 80px;
position: relative;
}
.upload-wrap .el-upload-list--picture-card .el-upload-list__item-thumbnail {
width: 100%;
height: auto;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.upload-wrap .el-upload-list__item.is-success .el-upload-list__item-status-label {
display: none;
}
.upload-wrap .ishide .el-upload--picture-card {
display: none;
}
.upload-wrap .el-upload-dragger {
width: 70px;
height: 70px;
}
.upload-wrap .el-upload--picture-card {
border: none;
}
.upload-wrap .el-upload-dragger {
width: 70px;
height: 70px;
}
</style>
<style lang="scss" scoped>
.upload-wrap {
.tips {
margin-top: 10px;
}
}
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.clear {
clear: both;
}
.item-block {
padding: 0 15px 1px;
margin: 10px 0;
border-radius: 0;
border: none;
background: #ffffff;
.block-text {
border-color: #eeeeee;
color: $ns-text-color-black;
padding: 7px 0;
border-bottom: 1px;
}
}
.refund-form {
width: 350px;
.el-select {
width: 100%;
}
}
.order-submit {
text-align: center;
padding: 10px;
}
.goods-list {
padding: 15px 0;
table {
width: 100%;
}
.goods-info-left {
width: 60px;
height: 60px;
float: left;
.goods-img {
width: 60px;
height: 60px;
}
}
.goods-info-right {
float: left;
height: 60px;
margin-left: 10px;
color: $base-color;
width: 80%;
.goods-name {
line-height: 20px;
padding-top: 10px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-spec {
color: #999;
}
}
}
.pay-type-list {
padding: 20px 0;
}
.pay-type-item {
display: inline-block;
border: 2px solid #eeeeee;
padding: 5px 20px;
margin-right: 20px;
cursor: pointer;
}
.pay-type-item.active {
border-color: $base-color;
}
.status-wrap {
color: #999;
}
.media-left {
float: left;
}
.media-right {
float: right;
i.rotate {
transform: rotate(180deg);
transition: 0.3s;
}
}
.action-box {
padding: 10px 0;
}
.action-way {
float: left;
color: #999;
}
.head .time {
float: right;
color: #999;
}
.record-item {
margin-bottom: 10px;
}
.order-statistics {
float: left;
padding: 10px;
// color: #999;
}
.el-textarea .el-input__count {
line-height: 20px;
}
</style>

View File

@@ -0,0 +1,630 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div v-loading="loading">
<!-- 退款详情start -->
<div>
<el-card class="box-card order-list">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/activist' }">退款/售后</el-breadcrumb-item>
<el-breadcrumb-item>退款详情</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div>
<div class="block-text color-red" v-if="detail.refund_status==-1">{{ detail.refund_status_name }}</div>
<div class="block-text color-green" v-if="detail.refund_status==3">{{ detail.refund_status_name }}</div>
<div class="fail-text" v-if="detail.refund_status==-1">
<div class="fail-title">拒绝原因:</div>
<div class="fail-detail">{{ detail.refund_refuse_reason }}</div>
</div>
<div class="block-text" v-if="detail.refund_status!=-1 && detail.refund_status!=3">
{{ detail.refund_status_name }}
</div>
<div class="status-wrap">
<div class="refund-explain" v-if="detail.refund_status == 1">
<div>如果商家拒绝你可重新发起申请</div>
<div>如果商家同意将通过申请并退款给你</div>
<div>如果商家逾期未处理平台将自动通过申请并退款给你</div>
</div>
<div class="refund-explain" v-if="detail.refund_status == 5">
<div>如果商家确认收货将会退款给你</div>
<div>如果商家拒绝收货该次退款将会关闭你可以重新发起退款</div>
</div>
</div>
</div>
</el-card>
<!--协商记录-->
<div class="item-block">
<div class="action-box">
<span class="media-left">协商记录</span>
<div class="media-right">
<div class="el-button--text" @click="actionOpen ? (actionOpen = false) : (actionOpen = true)">
协商记录
<i :class="actionOpen ? 'rotate' : ''" class="el-icon-arrow-down"></i>
</div>
</div>
<div class="clear"></div>
</div>
<div v-if="actionOpen">
<el-timeline>
<el-timeline-item :class="logItem.action_way == 1 ? 'buyer' : 'seller'" v-for="(logItem, logIndex) in detail.refund_log_list" :key="logIndex" :timestamp="$util.timeStampTurnTime(logItem.action_time)" placement="top">
<div>
<h4>{{ logItem.action_way == 1 ? '买家' : '卖家' }}</h4>
<p>{{ logItem.action }}</p>
</div>
</el-timeline-item>
</el-timeline>
</div>
</div>
<!-- 退货地址 -->
<div class="item-block" v-if="detail.refund_status == 4">
<div class="block-text">
<span>收货人{{ detail.shop_contacts }}</span>
<span>联系电话{{ detail.shop_mobile }}</span>
</div>
<div class="block-text">
<span>退货地址{{ detail.shop_address }}</span>
</div>
</div>
<!--退款详情-->
<div class="item-block">
<div class="goods-list">
<table>
<tr>
<td width="62.5%">商品</td>
<td width="12.5%">数量</td>
<td width="12.5%">退款金额</td>
</tr>
</table>
</div>
</div>
<div class="item-block">
<div class="goods-list">
<table>
<tr>
<td width="62.5%">
<div class="goods-info">
<div class="goods-info-left">
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
<img class="goods-img" :src="$img(detail.sku_image)" @error="detail.sku_image = defaultGoodsImage" />
</router-link>
</div>
<div class="goods-info-right">
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
<div class="goods-name">{{ detail.sku_name }}</div>
</router-link>
</div>
</div>
</td>
<td width="12.5%" class="goods-num">{{ detail.num }}</td>
<td width="12.5%" class="goods-money">{{ detail.refund_apply_money }}</td>
</tr>
</table>
</div>
</div>
<div class="item-block">
<div class="order-statistics">
<table v-if="detail.refund_apply_money > 0">
<!-- 申请信息 -->
<tr>
<td align="right">退款方式</td>
<td align="left">{{ detail.refund_type == 1 ? '仅退款' : '退款退货' }}</td>
</tr>
<tr>
<td align="right">申请原因</td>
<td align="left">{{ detail.refund_reason }}</td>
</tr>
<tr>
<td align="right">申请金额</td>
<td align="left">{{ detail.refund_apply_money }}</td>
</tr>
<tr>
<td align="right">申请时间</td>
<td align="left">{{ $util.timeStampTurnTime(detail.refund_action_time) }}</td>
</tr>
<tr class="refund-images" v-if="detail.refund_images">
<td align="right refund-title">退款图片</td>
<td align="left">
<img class="image" v-for="(item,index) in detail.refund_images.split(',')" :key="index" :src="$img(item)" alt="" />
</td>
</tr>
</table>
<table v-if="detail.refund_apply_money > 0 && detail.refund_status == 3">
<!-- 退款信息 -->
<tr>
<td align="right">退款金额</td>
<td align="left">{{ detail.refund_apply_money }} ({{ detail.refund_money_type_name }})</td>
</tr>
<tr>
<td align="right">退款编号</td>
<td align="left">{{ detail.refund_no }}</td>
</tr>
<tr v-if="detail.refund_time">
<td align="right">退款时间</td>
<td align="left">{{ $util.timeStampTurnTime(detail.refund_time) }}</td>
</tr>
</table>
<table v-if="detail.shop_active_refund == 1">
<!-- 主动退款信息 -->
<tr>
<td align="right">主动退款金额</td>
<td align="left">{{ detail.shop_active_refund_money }} ({{ detail.shop_active_refund_money_type_name }})</td>
</tr>
<tr>
<td align="right">主动退款编号</td>
<td align="left">{{ detail.shop_active_refund_no }}</td>
</tr>
<tr>
<td align="right">主动退款说明</td>
<td align="left">{{ detail.shop_active_refund_remark }}</td>
</tr>
</table>
</div>
<div class="clear"></div>
</div>
<div class="item-block" v-if="detail.refund_action.length">
<div class="order-submit" v-for="(actionItem, actionIndex) in detail.refund_action" :key="actionIndex">
<el-button type="primary" class="el-button--primary" @click="refundAction(actionItem.event)">{{ actionItem.title }}</el-button>
</div>
<div class="order-submit" v-if="detail.complain_action">
<el-button type="primary" class="el-button--primary" @click="refundAction('complain')">平台维权</el-button>
</div>
<div class="clear"></div>
</div>
</div>
<!-- 退款详情end -->
<!-- 输入物流信息弹出 -->
<el-dialog title="输入发货物流" :visible.sync="refundDeliveryDialog" width="50%">
<el-form ref="form" :model="formData" label-width="80px">
<el-form-item label="物流公司">
<el-input v-model="formData.refund_delivery_name" placeholder="请输入物流公司"></el-input>
</el-form-item>
<el-form-item label="物流单号">
<el-input v-model="formData.refund_delivery_no" placeholder="请输入物流单号"></el-input>
</el-form-item>
<el-form-item label="物流说明">
<el-input v-model="formData.refund_delivery_remark" placeholder="选填"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="refundDeliveryDialog = false"> </el-button>
<el-button type="primary" @click="refundGoods('form')"> </el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import {
refundData,
refund,
detail,
delivery,
cancleRefund
} from '@/api/order/refund';
import {
mapGetters
} from 'vuex';
export default {
name: 'refund_detail',
components: {},
data: () => {
return {
orderGoodsId: '',
isSub: false,
detail: {
refund_action: []
},
formData: {
refund_delivery_name: '',
refund_delivery_no: '',
refund_delivery_remark: ''
},
actionOpen: false, //协商记录
refundDeliveryDialog: false, //发货地址弹出
loading: true,
yes: true
};
},
created() {
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
this.getRefundDetail();
// if (this.$route.query.action && this.$route.query.action == 'returngoods') {
// this.refundDeliveryDialog = true;
// }
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
//退款详情相关
getRefundDetail() {
this.loading = true;
detail({
order_goods_id: this.orderGoodsId
}).then(res => {
const {
code,
message,
data
} = res;
if (code >= 0) {
this.detail = data;
} else {
this.$message({
message: '未获取到该订单项退款信息!',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/activist'
});
}
});
}
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/activist'
});
}
});
});
},
refundAction(event) {
switch (event) {
case 'orderRefundCancel':
this.cancleRefund(this.detail.order_goods_id);
break;
case 'orderRefundDelivery':
this.refundDeliveryDialog = true;
break;
case 'orderRefundAsk':
this.$router.push({
path: '/order/refund?order_goods_id=' + this.detail.order_goods_id
});
break;
case 'complain':
this.$router.push({
path: '/order/complain?order_goods_id=' + this.detail.order_goods_id
});
break;
case 'orderRefundApply':
this.$router.push({
path: '/order/refund',
query: { order_goods_id: this.detail.order_goods_id, order_id: this.detail.order_id },
});
break;
}
},
refundGoods() {
if (this.formData.refund_delivery_name == '') {
this.$message({
message: '请输入物流公司',
type: 'warning'
});
return false;
}
if (this.formData.refund_delivery_no == '') {
this.$message({
message: '请输入物流单号',
type: 'warning'
});
return false;
}
this.formData.order_goods_id = this.orderGoodsId;
if (this.isSub) return;
this.isSub = true;
delivery(this.formData).then(res => {
const {
code,
message,
data
} = res;
if (code >= 0) {
this.getRefundDetail();
this.refundDeliveryDialog = false;
} else {
this.$message({
message: '未获取到该订单项退款信息!',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/activist'
});
}
});
}
}).catch(err => {
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/activist'
});
}
});
});
},
cancleRefund(order_goods_id) {
this.$confirm('撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请', '提示', {
confirmButtonText: '确认撤销',
cancelButtonText: '暂不撤销',
type: 'warning'
})
.then(() => {
if (this.isSub) return;
this.isSub = true;
cancleRefund({
order_goods_id: order_goods_id
}).then(res => {
const {
code,
message,
data
} = res;
if (code >= 0) {
this.$message({
message: '撤销成功!',
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/activist'
});
}
});
} else {
this.$message({
message: message,
type: 'warning'
});
}
}).catch(err => {
this.$message.error({
message: err.message,
duration: 2000,
onClose: () => {
this.$router.push({
path: '/member/activist'
});
}
});
});
})
}
}
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.clear {
clear: both;
}
.item-block {
padding: 0 20px 1px;
margin: 10px 0;
border-radius: 0;
border: none;
background: #ffffff;
.block-text {
border-color: #eeeeee;
color: $ns-text-color-black;
padding: 7px 0;
border-bottom: 1px;
span {
margin-right: 60px;
}
}
}
.fail-text {
display: flex;
align-items: flex-start;
color: #F94460;
padding: 7px 0;
border-bottom: 1px;
.fail-title {
width: 7%;
}
.fail-detail {
width: 93%;
}
}
.color-green {
color: #34C25D;
}
.color-red {
color: #F94460;
}
.order-submit {
float: right;
padding: 10px;
}
.goods-list {
padding: 15px 0;
table {
width: 100%;
}
.goods-info-left {
width: 60px;
height: 60px;
float: left;
.goods-img {
width: 60px;
height: 60px;
}
}
.goods-info-right {
float: left;
height: 60px;
margin-left: 10px;
color: $base-color;
width: 80%;
.goods-name {
line-height: 20px;
padding-top: 10px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-spec {
color: #999;
}
}
}
.pay-type-list {
padding: 20px 0;
}
.pay-type-item {
display: inline-block;
border: 2px solid #eeeeee;
padding: 5px 20px;
margin-right: 20px;
cursor: pointer;
}
.pay-type-item.active {
border-color: $base-color;
}
.status-wrap {
color: #999;
}
.media-left {
float: left;
}
.media-right {
float: right;
cursor: pointer;
i.rotate {
transform: rotate(180deg);
transition: 0.3s;
}
}
.action-box {
padding: 10px 0;
}
.action-way {
float: left;
color: #999;
}
.head .time {
float: right;
color: #999;
}
.record-item {
margin-bottom: 10px;
}
.order-statistics {
float: left;
padding: 10px;
// color: #999;
table{
margin-bottom:10px;
}
table:last-child{
margin-bottom: 0;
}
}
</style>
<style lang="scss">
.refund-images{
td{
&:first-child{
vertical-align: baseline;
}
}
.image{
width: 60px;
height: 60px;
margin-right: 10px;
}
}
</style>

View File

@@ -0,0 +1,147 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card order-list">
<div slot="header" class="clearfix"><span>核销台</span></div>
<div class="ns-verification">
<div class="ns-verification-flow">
<div class="ns-verification-icon">
<div><i class="iconfont icon-shurutianxiebi"></i></div>
<p>输入核销码</p>
</div>
<div><i class="iconfont icon-jiang-copy"></i></div>
<div class="ns-verification-icon">
<div><i class="iconfont icon-hexiao"></i></div>
<p>核销</p>
</div>
</div>
<div class="ns-verification-wrap">
<el-input v-model="verify_code" placeholder="请输入核销码"></el-input>
<el-button @click="confirm">确认</el-button>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {
verifyInfo
} from "@/api/order/verification"
export default {
name: "verification",
components: {},
data: () => {
return {
verify_code: "",
yes: true
}
},
created() {
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
confirm() {
var reg = /[\S]+/
if (!reg.test(this.verify_code)) {
this.$message({
message: "请输入核销码",
type: "warning"
})
return false
}
verifyInfo({
verify_code: this.verify_code
}).then(res => {
if (res.code >= 0) {
this.$router.push({
path: "/order/verification_detail",
query: {
code: this.verify_code
}
})
} else {
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.$message.error(err.message)
})
}
}
}
</script>
<style lang="scss" scoped>
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.ns-verification {
margin: 20px 0;
background: #ffffff;
padding: 80px;
text-align: center;
.ns-verification-flow {
display: flex;
justify-content: center;
.ns-verification-icon {
width: 150px;
margin: 0 20px;
div {
display: inline-block;
background: #eee;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
border-radius: 50%;
}
p {
color: #999999;
margin-top: 5px;
}
}
i {
font-size: 30px;
color: #999999;
}
}
.ns-verification-wrap {
display: inline-block;
width: 500px;
margin-top: 50px;
.el-button {
margin-top: 50px;
background: $base-color;
color: #ffffff;
}
}
}
</style>

View File

@@ -0,0 +1,155 @@
<template>
<el-card class="box-card order-list">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/order/verification_list' }">核销记录</el-breadcrumb-item>
<el-breadcrumb-item>核销验证</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="ns-verification" v-loading="loading">
<div class="ns-verification-order">
<p class="ns-site-name">{{ verifyInfo.site_name }}</p>
<div class="ns-goods-list" v-for="(item, index) in verifyInfo.item_array" :key="index">
<div class="ns-goods-img">
<el-image fit="cover" :src="$img(item.img)" @error="imageError(index)"></el-image>
</div>
<div class="ns-goods-info">
<p>{{ item.name }}</p>
<p class="ns-goods-price ns-text-color">{{ item.price }}</p>
<p>数量{{ item.num }}</p>
</div>
</div>
<div class="ns-order-info">
<p v-for="(item, index) in verifyInfo.remark_array" :key="index">{{ item.title }}{{ item.value }}</p>
<p>核销类型{{ verifyInfo.verify_type_name }}</p>
<template v-if="verifyInfo.is_verify">
<p>核销状态已核销</p>
<p v-if="verifyInfo.verify_time">核销人员{{ verifyInfo.verifier_name }}</p>
<p v-if="verifyInfo.verify_time">核销时间{{ $timeStampTurnTime(verifyInfo.verify_time) }}</p>
</template>
</div>
<div class="ns-btn">
<el-button @click="verify" v-if="verifyInfo.is_verify == 0">确认使用</el-button>
</div>
</div>
</div>
</el-card>
</template>
<script>
import {verifyInfo, verify} from '@/api/order/verification';
import {mapGetters} from 'vuex';
export default {
name: 'verification_detail',
components: {},
data: () => {
return {
verify_code: '',
verifyInfo: {},
isSub: false,
loading: true
};
},
created() {
this.verify_code = this.$route.query.code;
this.getVerifyInfo();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
methods: {
getVerifyInfo() {
verifyInfo({
verify_code: this.verify_code
}).then(res => {
if (res.code >= 0) {
this.verifyInfo = res.data;
} else {
this.$message({message: res.message, type: 'warning'});
this.$router.push('/member');
}
this.loading = false;
}).catch(err => {
this.$message.error(err.message);
this.$router.push('/member');
this.loading = false;
});
},
verify() {
if (this.isSub) return;
this.isSub = true;
verify({
verify_code: this.verify_code
}).then(res => {
if (res.code >= 0) {
this.$message({
message: res.message,
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push('/order/verification_list');
}
});
} else {
this.$message({message: res.message, type: 'warning'});
this.isSub = false;
}
}).catch(err => {
this.$message.error(err.message);
this.isSub = false;
});
},
/**
* 图片加载失败
*/
imageError(index) {
this.verifyInfo.item_array[index].img = this.defaultGoodsImage;
}
}
};
</script>
<style lang="scss" scoped>
.ns-verification {
.ns-verification-order {
.ns-goods-list {
display: flex;
margin: 10px 0;
.el-image {
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
margin-right: 10px;
border-radius: 5px;
}
.ns-goods-price span:first-child {
font-weight: 600;
font-size: 16px;
}
}
.ns-order-info {
border-top: 1px solid #eeeeee;
padding-top: 20px;
color: $base-color-info;
line-height: 30px;
}
.ns-btn {
text-align: right;
.el-button {
background: $base-color;
color: #ffffff;
}
}
}
}
</style>

View File

@@ -0,0 +1,301 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card order-list">
<div slot="header" class="clearfix"><span>核销记录</span></div>
<div v-loading="loading">
<el-tabs v-model="orderType" @tab-click="handleClick">
<el-tab-pane v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.type"></el-tab-pane>
</el-tabs>
<div>
<nav>
<li>商品信息</li>
<li>单价</li>
<li>数量</li>
</nav>
<div class="list" v-if="verifyList.length > 0">
<div class="item" v-for="(item, index) in verifyList" :key="index">
<div class="head">
<span class="create-time">{{ $util.timeStampTurnTime(item.create_time) }}</span>
<router-link :to="'/shop-' + item.site_id" target="_blank">{{ item.site_name }}</router-link>
<span class="order-type">{{ item.order_type_name }}</span>
<span class="order-type">核销员{{ item.verifier_name }}</span>
</div>
<ul v-for="(goodsItem, goodsIndex) in item.item_array" :key="goodsIndex">
<li>
<div class="img-wrap" @click="toVerifyDetail(item.verify_code)">
<img :src="$img(goodsItem.img)" @error="imageError(index, goodsIndex)" />
</div>
<div class="info-wrap">
<h5 @click="toVerifyDetail(item.verify_code)">{{ goodsItem.name }}</h5>
</div>
</li>
<li>
<span>{{ goodsItem.price }}</span>
</li>
<li>
<span>{{ goodsItem.num }}</span>
</li>
</ul>
</div>
</div>
<div v-else-if="!loading && verifyList.length == 0" class="empty-wrap">暂无相关订单</div>
</div>
</div>
<div class="pager">
<el-pagination
background
:pager-count="5"
:total="total"
prev-text="上一页"
next-text="下一页"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
@size-change="handlePageSizeChange"
@current-change="handleCurrentPageChange"
hide-on-single-page
></el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import {mapGetters} from 'vuex';
import {getVerifyType, verifyList} from '@/api/order/verification';
export default {
name: 'verification_list',
components: {},
data: () => {
return {
orderType: '',
loading: true,
typeList: [],
verifyList: [],
currentPage: 1,
pageSize: 10,
total: 0,
yes: true
};
},
created() {
this.getVerifyType();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
handlePageSizeChange(size) {
this.pageSize = size;
this.refresh();
},
handleCurrentPageChange(page) {
this.currentPage = page;
this.refresh();
},
refresh() {
this.loading = true;
this.getVerifyType();
},
/**
* 订单类型(自提/虚拟)
*/
handleClick(tab, event) {
this.refresh();
},
getVerifyType() {
getVerifyType().then(res => {
if (res.code >= 0) {
this.typeList = [];
this.verifyList = [];
Object.keys(res.data).forEach(key => {
this.typeList.push({
type: key,
name: res.data[key].name
});
});
if (this.orderType == 0) {
for (let i = 0; i < this.typeList.length; i++) {
if (i == 0) {
this.orderType = this.typeList[i].type;
}
}
}
this.getVerifyList(this.orderType);
}
})
},
/**
* 获取核销记录
*/
getVerifyList(type) {
verifyList({
verify_type: type,
page: this.currentPage,
page_size: this.pageSize
}).then(res => {
this.verifyList = res.data.list;
this.total = res.data.count;
this.loading = false;
}).catch(err => {
this.$message.error(err.message);
this.loading = false;
});
},
imageError(orderIndex, goodsIndex) {
this.verifyList[orderIndex].item_array[goodsIndex].img = this.defaultGoodsImage;
},
toVerifyDetail(code) {
this.$router.push({path: '/order/verification_detail', query: {code: code}});
}
}
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.order-list {
nav {
overflow: hidden;
padding: 10px 0;
background: #fff;
margin-bottom: 10px;
border-bottom: 1px solid #eeeeee;
li {
float: left;
&:nth-child(1) {
width: 70%;
}
&:nth-child(2) {
width: 20%;
}
&:nth-child(3) {
width: 10%;
}
}
}
.list {
.item {
margin-bottom: 20px;
border: 1px solid #eeeeee;
border-top: 0;
.head {
padding: 8px 10px;
background: #f7f7f7;
font-size: 12px;
.create-time {
margin-right: 10px;
}
border-bottom: 1px solid #eeeeee;
a {
margin: 0 10px 0 20px;
}
.order-type {
margin-left: 30px;
}
}
}
ul {
background-color: #fff;
padding: 10px;
overflow: hidden;
li {
float: left;
line-height: 60px;
&:nth-child(1) {
width: 70%;
line-height: inherit;
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
h5 {
cursor: pointer;
font-weight: normal;
font-size: $ns-font-size-base;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
margin-right: 10px;
display: inline-block;
&:hover {
color: $base-color;
}
}
span {
font-size: $ns-font-size-sm;
color: #9a9a9a;
}
}
}
&:nth-child(2) {
width: 20%;
}
&:nth-child(3) {
width: 10%;
}
}
}
}
.empty-wrap {
text-align: center;
padding: 10px;
}
}
</style>