初始上传

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,235 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div class="my-account">
<div class="account-wrap">
<div class="account-left">
<div class="title">我的可用余额()</div>
<div class="money">
<div class="balance-money">
<b>{{ integer }}</b>
<span>.{{ decimal }}</span>
</div>
<div class="tx" @click="applyWithdrawal">提现</div>
<div class="cz" @click="rechargeList">充值</div>
</div>
</div>
<div class="account-right">
<div class="item-wrap">
<div class="item">
<div class="iconfont icon-ziyuan"></div>
<div class="title">储值余额:</div>
<b class="num">{{ balanceInfo.balance_money }}</b>
</div>
<div class="item">
<div class="iconfont icon-ziyuan"></div>
<div class="title">现金余额:</div>
<b class="num">{{ balanceInfo.balance }}</b>
</div>
</div>
</div>
</div>
<div class="detail" v-loading="loading">
<el-table :data="accountList" border>
<el-table-column prop="type_name" label="来源" width="150"></el-table-column>
<el-table-column prop="account_data" label="金额" width="150"></el-table-column>
<el-table-column prop="remark" class="detail-name" label="详细说明"></el-table-column>
<el-table-column prop="time" label="时间" width="180"></el-table-column>
</el-table>
</div>
<div class="pager">
<el-pagination
background
:pager-count="5"
:total="total"
prev-text="上一页"
next-text="下一页"
:current-page.sync="account.page"
:page-size.sync="account.page_size"
@size-change="handlePageSizeChange"
@current-change="handleCurrentPageChange"
hide-on-single-page
></el-pagination>
</div>
</div>
</div>
</template>
<script>
import {balance, balanceDetail} from "@/api/member/account"
export default {
name: "account",
layout: "member",
components: {},
data: () => {
return {
account: {
page: 1,
page_size: 10
},
balanceInfo: {
balance: 0,
balance_money: 0
},
accountList: [],
total: 0,
integer: 0,
decimal: 0,
loading: true,
yes: true
}
},
created() {
this.getAccount();
this.getAccountList()
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
//获取余额信息
getAccount() {
balance({account_type: "balance,balance_money"}).then(res => {
if (res.code == 0 && res.data) {
this.balanceInfo = res.data;
const price = (parseFloat(this.balanceInfo.balance) + parseFloat(this.balanceInfo.balance_money)).toFixed(2)
let priceSplit = price.split(".");
this.integer = priceSplit[0];
this.decimal = priceSplit[1];
}
this.loading = false
}).catch(err => {
this.loading = false;
this.$message.error(err.message)
})
},
//获取余额明细
getAccountList() {
balanceDetail({
page_size: this.account.page_size,
page: this.account.page,
account_type: "balance"
}).then(res => {
if (res.code == 0 && res.data) {
this.accountList = res.data.list;
this.total = res.data.count;
this.accountList.forEach(item => {
item.time = this.$util.timeStampTurnTime(item.create_time)
})
}
}).catch(err => {
this.$message.error(err.message)
})
},
handlePageSizeChange(num) {
this.account.page_size = num;
this.getAccountList()
},
handleCurrentPageChange(page) {
this.account.page = page
this.getAccountList()
},
applyWithdrawal() {
this.$router.push("/member/apply_withdrawal")
},
rechargeList() {
this.$router.push("/member/recharge_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;
}
.my-account {
background: #ffffff;
padding: 20px;
.account-wrap {
display: flex;
margin-bottom: 10px;
.account-left {
flex: 1;
.title {
font-size: $ns-font-size-base;
font-weight: 600;
}
.money {
display: flex;
.balance-money {
b {
font-size: 30px;
}
span {
font-weight: 600;
}
}
.tx {
color: $base-color;
margin-left: 5px;
margin-top: 20px;
cursor: pointer;
}
.cz {
color: $base-color;
margin-left: 5px;
margin-top: 20px;
cursor: pointer;
}
}
}
.account-right {
flex: 1;
font-size: $ns-font-size-base;
display: flex;
align-items: center;
.item {
display: flex;
align-items: center;
.title {
margin-left: 3px;
}
.num {
margin-left: 3px;
}
}
}
}
.page {
display: flex;
justify-content: center;
align-content: center;
padding-top: 20px;
}
}
</style>

View File

@@ -0,0 +1,208 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>编辑账户</span>
</div>
<div v-loading="loading">
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="80px">
<el-form-item label="姓名" prop="realname">
<el-input v-model="formData.realname" placeholder="请输入真实姓名" class="ns-len-input"/>
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="formData.mobile" autocomplete="off" placeholder="请输入手机号" maxlength="11" class="ns-len-input"/>
</el-form-item>
<el-form-item label="账号类型" prop="withdraw_type">
<el-select v-model="formData.withdraw_type" placeholder="请选择账号类型">
<el-option v-for="(value, key) in transferType" :key="key" :label="value" :value="key" :disabled="key == 'wechatpay'"></el-option>
</el-select>
</el-form-item>
<el-form-item label="银行名称" prop="branch_bank_name" v-if="formData.withdraw_type == 'bank'">
<el-input v-model="formData.branch_bank_name" autocomplete="off" placeholder="请输入银行名称" maxlength="50" class="ns-len-input"/>
</el-form-item>
<el-form-item label="提现账号" prop="bank_account" v-if="formData.withdraw_type != 'wechatpay' && formData.withdraw_type">
<el-input v-model="formData.bank_account" autocomplete="off" placeholder="请输入提现账号" maxlength="30" class="ns-len-input"/>
</el-form-item>
<el-form-item>
<el-button size="medium" type="primary" @click="saveAccount('ruleForm')">保存</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import {transferType, accountDetail, saveAccount} from "@/api/member/member"
export default {
name: "account_edit",
layout: "member",
data() {
var isMobile = (rule, value, callback) => {
if (!value) {
return callback(new Error("手机号不能为空"))
} else {
if (/^\d{11}$/.test(value)) {
callback()
} else {
callback(new Error("请输入正确的手机号"))
}
}
}
return {
formData: {
id: '',
realname: '',
mobile: '',
withdraw_type: '',
bank_account: '',
branch_bank_name: ''
},
flag: false, //防重复标识
payList: [],
loading: true,
index: 0,
transferType: [],
rules: {
realname: [{required: true, message: "请输入真实姓名", trigger: "blur"}],
mobile: [{required: true, validator: isMobile, trigger: "blur"}],
withdraw_type: [{required: true, message: '请选择账号类型', trigger: 'change'}],
branch_bank_name: [{required: true, message: "请输入银行名称", trigger: "blur"}],
bank_account: [{required: true, message: "请输入提现账号", trigger: "blur"}],
},
yes: true
}
},
created() {
this.formData.id = this.$route.query.id;
this.getTransferType();
if (this.formData.id) {
this.getAccountDetail(this.formData.id)
}
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
/**
* 获取转账方式
*/
getTransferType() {
transferType().then(res => {
this.transferType = res.data;
if (!this.formData.id) { // id为空即添加时在此结束加载
this.loading = false
}
}).catch(err => {
if (!this.formData.id) {
this.loading = false
}
})
},
/**
* 获取账户详情(编辑)
*/
getAccountDetail(id) {
accountDetail({id: this.formData.id}).then(res => {
if (res.code == 0 && res.data) {
this.formData.realname = res.data.realname;
this.formData.mobile = res.data.mobile;
this.formData.bank_account = res.data.bank_account;
this.formData.branch_bank_name = res.data.branch_bank_name;
this.formData.withdraw_type = res.data.withdraw_type;
}
this.loading = false
}).catch(err => {
this.loading = false
})
},
/**
* 保存
*/
saveAccount(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
var data = {
id: this.formData.id,
realname: this.formData.realname,
mobile: this.formData.mobile,
withdraw_type: this.formData.withdraw_type,
bank_account: this.formData.bank_account,
branch_bank_name: this.formData.branch_bank_name
}
data.url = "add"
if (this.formData.id) {
data.url = "edit"
}
if (this.flag) return
this.flag = true
saveAccount(data).then(res => {
if (res.code == 0) {
this.$router.push({path: "/member/account_list"})
} else {
this.flag = false
this.$message({message: res.message, type: "warning"})
}
}).catch(err => {
this.flag = false
this.$message.error(err.message)
})
} else {
return false
}
})
}
}
}
</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;
}
.ns-len-input {
width: 350px;
}
.el-select {
margin-right: 10px;
}
</style>

View File

@@ -0,0 +1,285 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>账户列表</span>
</div>
<div v-loading="loading">
<div class="ns-member-address-list">
<div class="text item ns-add-address" @click="addAccount('add')">
<span>+ 新增账户</span>
</div>
<div class="text item ns-account-list" v-for="(item, index) in dataList" :key="index" @click="setDefault(item.id)">
<div class="text-name">
<span>{{ item.realname }}</span>
<span v-if="item.is_default == 1" class="text-default">默认</span>
</div>
<div class="text-content">
<p>手机号码{{ item.mobile }}</p>
<p v-if="item.withdraw_type == 'alipay'">提现账号{{ item.bank_account }}</p>
<p>账号类型{{ item.withdraw_type_name }}</p>
<p v-if="item.withdraw_type == 'bank'">银行名称{{ item.branch_bank_name }}</p>
</div>
<div class="text-operation">
<span v-if="item.is_default != 1" @click="setDefault(item.id)">设为默认</span>
<span @click.stop="addAccount('edit', item.id)">编辑</span>
<span v-if="item.is_default != 1" @click.stop="delAccount(item.id, item.is_default)">删除</span>
</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>
</div>
</el-card>
</div>
</template>
<script>
import {accountList, accountDefault, delAccount} from "@/api/member/member"
export default {
name: "account_list",
layout: "member",
components: {},
data: () => {
return {
dataList: [],
total: 0,
currentPage: 1,
pageSize: 8,
loading: true,
isSub: false,
yes: true
}
},
created() {
this.back = this.$route.query.back
this.getAccountList()
},
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.getAccountList()
},
/**
* 获取账户列表
*/
getAccountList() {
accountList({
page_size: this.pageSize,
page: this.currentPage
}).then(res => {
this.dataList = res.data.list
this.total = res.data.count
let withdrawType = {
'bank': '银行',
'alipay': '支付宝',
'wechatpay': '微信'
};
this.dataList.forEach(item => {
item.withdraw_type_name = withdrawType[item.withdraw_type] ? withdrawType[item.withdraw_type] : '';
})
this.loading = false
}).catch(err => {
this.loading = false
})
},
setDefault(id) {
if (this.isSub) return;
this.isSub = true;
accountDefault({
id: id
}).then(res => {
if (this.back) {
this.$router.push(this.back);
} else {
this.refresh()
this.$message.success('修改默认账户成功')
}
this.isSub = false;
}).catch(err => {
this.isSub = false;
this.$message.error(err.message)
})
},
delAccount(id) {
this.$confirm("确定要删除该账户吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
delAccount({
id: id
}).then(res => {
this.refresh()
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
})
},
/**
* 添加/编辑地址
*/
addAccount(type, id) {
if (type == "edit") {
this.$router.push({path: "/member/account_edit", query: {id: id}})
} else {
this.$router.push({path: "/member/account_edit"})
}
}
}
}
</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;
}
.ns-member-address-list {
display: flex;
flex-wrap: wrap;
.ns-account-list {
cursor: pointer;
}
.text {
width: 32%;
height: 170px;
margin-right: 2%;
border-radius: 5px;
border: 1px solid #d8d8d8;
margin-bottom: 20px;
padding: 0 15px;
box-sizing: border-box;
position: relative;
.text-name {
height: 37px;
line-height: 40px;
padding: 0 10px;
border-bottom: 1px solid #eeeeee;
}
.text-default {
display: inline-block;
margin-left: 10px;
background: $base-color;
color: #ffffff;
width: 35px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 3px;
}
.text-content {
padding: 10px;
p {
font-size: 12px;
}
}
.ns-address-detail {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.text-operation {
// 操作
position: absolute;
right: 12px;
bottom: 5px;
span {
margin: 0 5px;
color: #999999;
cursor: pointer;
font-size: 12px;
}
span:hover {
color: $base-color;
}
}
}
.text:nth-child(3n) {
margin-right: 0;
}
.ns-add-address {
border: 1px dashed #d8d8d8;
text-align: center;
color: #999999;
line-height: 170px;
cursor: pointer;
}
.ns-add-address:hover {
border-color: $base-color;
color: $base-color;
}
}
</style>

View File

@@ -0,0 +1,365 @@
<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">
<nav>
<li>商品信息</li>
<li>退款金额</li>
<li>退款类型</li>
<li>退款状态</li>
<li>操作</li>
</nav>
<div class="list" v-if="refundList.length > 0">
<div class="item" v-for="(refundItem, refundIndex) in refundList" :key="refundIndex">
<div class="head">
<span class="create-time">{{ $util.timeStampTurnTime(refundItem.refund_action_time) }}</span>
<span class="order-no">退款编号{{ refundItem.refund_no }}</span>
<router-link :to="'/shop-' + refundItem.site_id" target="_blank">{{ refundItem.site_name }}</router-link>
<span class="order-type">{{ refundItem.refund_status == 3 ? '退款成功' : '退款中' }}</span>
</div>
<ul>
<li>
<div class="img-wrap" @click="$util.pushToTab('/sku/' + refundItem.sku_id)">
<img :src="$img(refundItem.sku_image, { size: 'mid' })" @error="imageError(refundIndex)" />
</div>
<div class="info-wrap">
<h5 @click="$util.pushToTab('/sku/' + refundItem.sku_id)">{{ refundItem.sku_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
</li>
<li>
<span>{{ (Number(refundItem.refund_status == 3 ? refundItem.refund_real_money : refundItem.refund_apply_money) + Number(refundItem.shop_active_refund_money)).toFixed(2) }}</span>
</li>
<li>
<span>{{ refundItem.refund_type == 1 ? '退款' : '退货' }}</span>
</li>
<li>
<span class="ns-text-color">{{ refundItem.refund_status_name }}</span>
<el-link :underline="false" @click="orderDetail(refundItem)">退款详情</el-link>
</li>
<li>
<template v-if="refundItem.refund_action.length > 0">
<el-button
type="primary"
size="mini"
:plain="true"
v-for="(operationItem, operationIndex) in refundItem.refund_action"
:key="operationIndex"
@click="operation(operationItem.event, refundItem)"
>{{ operationItem.title }}</el-button>
</template>
</li>
</ul>
</div>
</div>
<div v-else-if="!loading && refundList.length == 0" class="empty-wrap">暂无相关订单</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 {refundList, cancleRefund} from '@/api/order/refund';
export default {
name: 'activist',
layout: "member",
components: {},
data: () => {
return {
orderStatus: 'all',
loading: true,
refundList: [],
currentPage: 1,
pageSize: 10,
total: 0,
yes: true
};
},
created() {
this.orderStatus = this.$route.query.status || 'all';
this.getRefundList();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
handleClick(tab, event) {
this.currentPage = 1;
this.orderStatus = tab.name;
this.refresh();
},
getRefundList() {
refundList({
page: this.currentPage,
page_size: this.pageSize
}).then(res => {
let list = [];
if (res.code == 0 && res.data) {
list = res.data.list;
this.total = res.data.count;
}
this.refundList = list;
this.loading = false;
}).catch(res => {
this.loading = false;
});
},
handlePageSizeChange(size) {
this.pageSize = size;
this.refresh();
},
handleCurrentPageChange(page) {
this.currentPage = page;
this.refresh();
},
refresh() {
this.loading = true;
this.getRefundList();
},
operation(action, orderData) {
switch (action) {
case 'orderRefundCancel': // 撤销维权
this.cancleRefund(orderData.order_goods_id);
break;
case 'orderRefundDelivery': // 退款发货
this.$router.push({
path: '/order/refund_detail',
query: {order_goods_id: orderData.order_goods_id, action: 'returngoods'}
});
break;
case 'orderRefundAsk':
this.$router.push({path: '/order/refund?order_goods_id=' + orderData.order_goods_id});
break;
case 'orderRefundApply':
this.$router.push({
path: '/order/refund',
query: { order_goods_id: orderData.order_goods_id, order_id: orderData.order_id },
});
break;
}
},
orderDetail(data) {
this.$router.push({path: '/order/refund_detail', query: {order_goods_id: data.order_goods_id}});
},
imageError(refundIndex) {
this.refundList[refundIndex].sku_image = this.defaultGoodsImage;
},
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'
});
this.getRefundList();
} else {
this.$message({message: 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;
}
.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: 45%;
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 15%;
}
}
}
.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: 45%;
line-height: inherit;
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
h5 {
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;
cursor: pointer;
display: inline-block;
&:hover {
color: $base-color;
}
}
span {
font-size: $ns-font-size-sm;
color: #9a9a9a;
}
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 14%;
line-height: 30px;
a {
display: block;
}
}
&:nth-child(5) {
width: 15%;
line-height: initial;
button {
margin-left: 0;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
}
}
}
}
.empty-wrap {
text-align: center;
padding: 10px;
}
}
</style>

View File

@@ -0,0 +1,477 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>编辑收货地址</span>
</div>
<div v-loading="loading" class="ns-member-address-list">
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="收货人姓名" class="ns-len-input" />
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="formData.mobile" autocomplete="off" placeholder="收货人手机号" class="ns-len-input" />
</el-form-item>
<el-form-item label="电话">
<el-input v-model.trim="formData.telephone" autocomplete="off" placeholder="收货人固定电话(选填)" class="ns-len-input" />
</el-form-item>
<el-form-item label="地址" prop="full_address">
<el-select :value="formData.province_id" placeholder="请选择省" @change="changeProvice">
<el-option v-for="option in province" :key="option.id" :label="option.name" :value="option.id">
{{ option.name }}
</el-option>
</el-select>
<el-select :value="formData.city_id" placeholder="请选择市" @change="changeCity">
<el-option v-for="option in city" :key="option.id" :label="option.name" :value="option.id">
{{ option.name }}
</el-option>
</el-select>
<el-select :value="formData.district_id" placeholder="请选择区/县" @change="changeDistrict">
<el-option v-for="option in district" :key="option.id" :label="option.name" :value="option.id">
{{ option.name }}
</el-option>
</el-select>
</el-form-item>
<el-form-item label="详细地址" prop="address">
<el-input v-model.trim="formData.address" autocomplete="off" placeholder="定位到小区、街道、写字楼" class="ns-len-input" />
</el-form-item>
<el-form-item label="是否默认">
<el-radio-group v-model="formData.is_default">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" size="medium" @click="saveAddress('ruleForm')">保存</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import {
addressInfo,
saveAddress
} from "@/api/member/member"
import {
getArea
} from "@/api/address"
export default {
name: "address_edit",
layout: "member",
components: {},
data() {
let self = this
var isMobile = (rule, value, callback) => {
if (!value) {
return callback(new Error("手机号不能为空"))
} else {
if (/^\d{11}$/.test(value)) {
callback()
} else {
callback(new Error("请输入正确的手机号"))
}
}
}
var fullAddress = (rule, value, callback) => {
if (self.formData.province_id) {
if (self.formData.city_id) {
if (self.district.length > 0) {
if (self.formData.district_id) {
return callback()
} else {
return callback(new Error("请选择区/县"))
}
} else {
return callback()
}
} else {
return callback(new Error("请选择市"))
}
} else {
return callback(new Error("请选择省"))
}
}
return {
formData: {
id: 0,
name: "",
mobile: "",
telephone: "",
province_id: "",
city_id: "",
district_id: "",
community_id: "",
address: "",
full_address: "",
latitude: 0,
longitude: 0,
is_default: 1
},
addressValue: "",
flag: false, //防重复标识
defaultRegions: [],
rules: {
name: [{
required: true,
message: "请输入收货人姓名",
trigger: "blur"
}],
mobile: [{
required: true,
validator: isMobile,
trigger: "blur"
}],
address: [{
required: true,
message: "请输入详细地址",
trigger: "blur"
}],
full_address: [{
required: true,
validator: fullAddress,
trigger: "blur"
}]
},
province: [],
city: [],
district: [],
pickerValueArray: [],
multiIndex: [0, 0, 0],
isInitMultiArray: false,
// 是否加载完默认地区
isLoadDefaultAreas: false,
loading: true,
yes: true
}
},
created() {
this.formData.id = this.$route.query.id
this.getAddressDetail()
this.getDefaultAreas(0, {
level: 0
})
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
watch: {
defaultRegions: {
handler(arr, oldArr = []) {
// 避免传的是字面量的时候重复触发
if (arr.length !== 3 || arr.join("") === oldArr.join("")) return
this.handleDefaultRegions()
},
immediate: true
}
},
computed: {
pickedArr() {
// 进行初始化
if (this.isInitMultiArray) {
return [this.pickerValueArray[0], this.pickerValueArray[1], this.pickerValueArray[2]]
}
return [this.pickerValueArray[0], this.city, this.district]
}
},
methods: {
/**
* 改变省
*/
changeProvice(id) {
this.formData.province_id = id;
this.getAreas(id, data => (this.city = data))
let obj = {}
obj = this.province.find(item => {
//这里的province就是上面遍历的数据源
return item.id === id //筛选出匹配数据
})
this.formData.city_id = ""
this.formData.district_id = ""
this.formData.full_address = obj.name // 设置选中的地址
},
/**
* 改变市
*/
changeCity(id) {
this.formData.city_id = id;
this.getAreas(id, data => (this.district = data))
let obj = {}
obj = this.city.find(item => {
//这里的province就是上面遍历的数据源
return item.id === id //筛选出匹配数据
})
this.formData.district_id = ""
this.formData.full_address = this.formData.full_address + "-" + obj.name
},
/**
* 改变区
*/
changeDistrict(id) {
this.formData.district_id = id;
let obj = {}
obj = this.district.find(item => {
//这里的province就是上面遍历的数据源
return item.id === id //筛选出匹配数据
})
this.formData.full_address = this.formData.full_address + "-" + obj.name
},
/**
* 获取地址信息
*/
getAddressDetail() {
addressInfo({
id: this.formData.id
}).then(res => {
let data = res.data
if (data != null) {
this.formData.name = data.name
this.formData.mobile = data.mobile
this.formData.telephone = data.telephone
this.formData.address = data.address
this.formData.full_address = data.full_address
this.formData.latitude = data.latitude
this.formData.longitude = data.longitude
this.formData.is_default = data.is_default
this.formData.province_id = data.province_id
this.formData.city_id = data.city_id
this.formData.district_id = data.district_id
this.defaultRegions = [data.province_id, data.city_id, data.district_id]
}
})
},
// 异步获取地区
getAreas(pid, callback) {
getArea({
pid: pid
}).then(res => {
if (res.code == 0) {
var data = []
res.data.forEach((item, index) => {
data.push(item)
})
if (callback) callback(data)
}
})
},
/**
* 获取省市区列表
*/
getDefaultAreas(pid, obj) {
getArea({
pid: pid
}).then(res => {
if (res.code == 0) {
var data = []
var selected = undefined
res.data.forEach((item, index) => {
if (obj != undefined) {
if (obj.level == 0 && obj.province_id != undefined) {
selected = obj.province_id
} else if (obj.level == 1 && obj.city_id != undefined) {
selected = obj.city_id
} else if (obj.level == 2 && obj.district_id != undefined) {
selected = obj.district_id
}
}
if (selected == undefined && index == 0) {
selected = item.id
}
data.push(item)
})
this.pickerValueArray[obj.level] = data
if (obj.level + 1 < 3) {
obj.level++
this.getDefaultAreas(selected, obj)
} else {
this.isInitMultiArray = true
this.isLoadDefaultAreas = true
}
this.province = this.pickerValueArray[0]
}
setTimeout(() => {
this.loading = false
}, 500)
}).catch(err => {
this.loading = false
})
},
/**
* 渲染默认值
*/
handleDefaultRegions() {
var time = setInterval(() => {
if (!this.isLoadDefaultAreas) return
this.isInitMultiArray = false
for (let i = 0; i < this.defaultRegions.length; i++) {
for (let j = 0; j < this.pickerValueArray[i].length; j++) {
this.province = this.pickerValueArray[0]
// 匹配省
if (this.defaultRegions[i] == this.pickerValueArray[i][j].id) {
// 设置选中省
this.$set(this.multiIndex, i, j)
// 查询市
this.getAreas(this.pickerValueArray[i][j].id, data => {
this.city = data
for (let k = 0; k < this.city.length; k++) {
if (this.defaultRegions[1] == this.city[k].id) {
// 设置选中市
this.$set(this.multiIndex, 1, k)
// 查询区县
this.getAreas(this.city[k].id, data => {
this.district = data
// 设置选中区县
for (let u = 0; u < this.district.length; u++) {
if (this.defaultRegions[2] == this.district[u].id) {
this.$set(this.multiIndex, 2, u)
this.handleValueChange({
detail: {
value: [j, k, u]
}
})
break
}
}
})
break
}
}
})
}
}
}
if (this.isLoadDefaultAreas) clearInterval(time)
}, 100)
},
handleValueChange(e) {
// 结构赋值
let [index0, index1, index2] = e.detail.value
let [arr0, arr1, arr2] = this.pickedArr
let address = [arr0[index0], arr1[index1], arr2[index2]]
this.formData.full_address = ""
for (let i = 0; i < address.length; i++) {
if (this.formData.full_address) {
this.formData.full_address = this.formData.full_address + "-" + address[i].name
} else {
this.formData.full_address = this.formData.full_address + address[i].name
}
}
},
/**
* 保存地址
*/
saveAddress(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
var data = {
name: this.formData.name,
mobile: this.formData.mobile,
telephone: this.formData.telephone,
province_id: this.formData.province_id,
city_id: this.formData.city_id,
district_id: this.formData.district_id,
community_id: "",
address: this.formData.address,
full_address: this.formData.full_address,
latitude: this.formData.latitude,
longitude: this.formData.longitude,
is_default: this.formData.is_default
}
data.url = "add"
if (this.formData.id) {
data.url = "edit"
data.id = this.formData.id
}
if (this.flag) return
this.flag = true
saveAddress(data).then(res => {
if (res.code == 0) {
this.$router.push({
path: "/member/delivery_address"
})
} else {
this.flag = false
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.flag = false
this.$message.error(err.message)
})
} else {
return false
}
})
}
}
}
</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;
}
.ns-len-input {
width: 350px;
}
.el-select {
margin-right: 10px;
}
</style>

View File

@@ -0,0 +1,308 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
<el-breadcrumb-item>提现申请</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="apply-withdrawal" v-loading="loading">
<div class="apply-wrap">
<div class="apply-account" v-if="bankAccountInfo.withdraw_type" @click="goAccount()">
<span class="ns-width">提现到</span>
<div class="apply-account-info">
<!-- <span v-if="bankAccountInfo.withdraw_type == 'wechatpay'">{{ bankAccountInfo.mobile }}</span> -->
<span v-if="bankAccountInfo.withdraw_type == 'wechatpay'">暂不支持微信提现请选择支付宝</span>
<span v-else>{{ bankAccountInfo.bank_account }}</span>
<el-image v-if="bankAccountInfo.withdraw_type == 'alipay'" :src="$img('public/uniapp/member/apply_withdrawal/alipay.png')" fit="contain"/>
<el-image v-else-if="bankAccountInfo.withdraw_type == 'bank'" :src="$img('public/uniapp/member/apply_withdrawal/bank.png')" fit="contain"/>
<!-- <el-image v-else-if="bankAccountInfo.withdraw_type == 'wechatpay'" :src="$img('public/uniapp/member/apply_withdrawal/wechatpay.png')" fit="contain"></el-image> -->
<i class="iconfont iconarrow-right"></i>
</div>
</div>
<div class="apply-account" v-else @click="goAccount()">
<span class="ns-width">提现账户</span>
<div class="apply-account-info">
<span class="ns-text-color">请选择提现账户</span>
</div>
</div>
<div class="apply-account-money demo-input-suffix">
<span class="ns-width">提现金额</span>
<el-input type="number" placeholder="0" v-model="withdrawMoney" :disabled="bankAccountInfo.withdraw_type == 'wechatpay'">
<template slot="prepend"></template>
</el-input>
</div>
<div class="apply-account-desc">
<p>
<span class="ns-width"></span>
<span>可提现余额为</span>
<span class="balance">{{ withdrawInfo.member_info.balance_money | moneyFormat }}</span>
<span @click="allTx">全部提现</span>
</p>
<p>
<span class="ns-width"></span>
<span>最小提现金额为{{ withdrawInfo.config.min | moneyFormat }}手续费为{{ withdrawInfo.config.rate + '%' }}</span>
</p>
</div>
<div class="apply-account-btn">
<span class="ns-width"></span>
<el-button type="primary" size="medium" @click="withdraw" :class="{ disabled: withdrawMoney == '' || withdrawMoney == 0 }" :disabled="bankAccountInfo.withdraw_type == 'wechatpay'">提现</el-button>
<!-- <router-link to="/member/withdrawal">提现记录</router-link> -->
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {withdrawInfo, accountInfo, withdraw} from "@/api/member/account"
export default {
name: "apply_withdrawal",
layout: "member",
components: {},
data: () => {
return {
withdrawInfo: {
config: {
is_use: 0,
min: 1,
rate: 0
},
member_info: {
balance_money: 0,
balance_withdraw: 0,
balance_withdraw_apply: 0
}
},
bankAccountInfo: {},
withdrawMoney: '',
isSub: false,
loading: true,
yes: true
}
},
filters: {
/**
* 金额格式化输出
* @param {Object} money
*/
moneyFormat(money) {
return parseFloat(money).toFixed(2);
}
},
created() {
this.getWithdrawInfo();
this.getBankAccountInfo();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
/**
* 获取提现信息
*/
getWithdrawInfo() {
withdrawInfo().then(res => {
if (res.code >= 0 && res.data) {
this.withdrawInfo = res.data;
if (this.withdrawInfo.config.is_use == 0) {
this.$router.push('/member');
}
}
this.loading = false
}).catch(err => {
this.loading = false
})
},
/**
* 银行账号信息
*/
getBankAccountInfo() {
accountInfo().then(res => {
if (res.code >= 0 && res.data) {
this.bankAccountInfo = res.data;
}
})
},
/**
* 全部提现
*/
allTx() {
this.withdrawMoney = this.withdrawInfo.member_info.balance_money;
},
/**
* 账户列表
*/
goAccount() {
let back = "/member/apply_withdrawal"
this.$router.push({path: "/member/account_list", query: {back: back}})
},
withdraw() {
if (!this.bankAccountInfo.withdraw_type) {
this.$message({
message: "请先添加提现方式",
type: "warning"
})
return;
}
if (this.withdrawMoney == '' || this.withdrawMoney == 0 || isNaN(parseFloat(this.withdrawMoney))) {
this.$message({
message: '请输入提现金额',
type: "warning"
});
return false;
}
if (parseFloat(this.withdrawMoney) > parseFloat(this.withdrawInfo.member_info.balance_money)) {
this.$message({
message: '提现金额超出可提现金额',
type: "warning"
});
return false;
}
if (parseFloat(this.withdrawMoney) < parseFloat(this.withdrawInfo.config.min)) {
this.$message({
message: '提现金额小于最低提现金额',
type: "warning"
});
return false;
}
if (this.isSub) return;
this.isSub = true;
withdraw({
apply_money: this.withdrawMoney,
transfer_type: this.bankAccountInfo.withdraw_type, //转账提现类型
realname: this.bankAccountInfo.realname,
mobile: this.bankAccountInfo.mobile,
bank_name: this.bankAccountInfo.branch_bank_name,
account_number: this.bankAccountInfo.bank_account
}).then(res => {
if (res.code >= 0) {
this.$message({
message: '提现申请成功!',
type: 'success',
duration: 2000,
onClose: () => {
this.$router.push('/member/withdrawal');
}
});
} else {
this.isSub = false;
this.$message({
message: res.message,
type: "warning"
});
}
}).catch(err => {
this.isSub = false;
this.$message({
message: err.message,
type: "warning"
});
})
},
}
}
</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;
}
.apply-withdrawal {
width: 100%;
background-color: #FFFFFF;
.apply-wrap {
display: inline-block;
width: 500px;
box-sizing: border-box;
.apply-account {
display: flex;
align-items: center;
cursor: pointer;
.apply-account-info {
display: flex;
align-items: center;
span {
margin-right: 5px;
}
.el-image {
width: 20px;
height: 20px;
margin-right: 10px;
}
}
}
.apply-account-money {
display: flex;
align-items: center;
margin-top: 30px;
span {
flex-shrink: 0;
}
}
.apply-account-desc {
margin-top: 30px;
text-align: left;
p:first-child {
span.balance {
margin-right: 10px;
}
span:nth-child(4) {
color: $base-color;
cursor: pointer;
}
}
p:nth-child(2) {
color: #999999;
}
}
.apply-account-btn {
margin-top: 30px;
.el-button {
margin-right: 20px;
}
}
}
.ns-width {
display: inline-block;
width: 115px;
text-align: right;
}
}
</style>

View File

@@ -0,0 +1,431 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div class="collection" v-loading="loading">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="宝贝" name="goods">
<div v-if="goodsList.length > 0">
<div class="goods">
<div class="goods-wrap" v-for="(item, index) in goodsList" :key="item.goods_id">
<div class="goods-item">
<div class="img" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
<img :src="$img(item.goods_image.split(',')[0], { size: 'mid' })" @error="imageError(index)" />
<i class="del el-icon-delete" @click.stop="deleteGoods(item.goods_id)"></i>
</div>
<div class="goods-name">{{ item.goods_name }}</div>
<div class="price">{{ item.price }}</div>
</div>
</div>
</div>
<div class="pager">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="goodsInfo.page" :page-size="goodsInfo.page_size" background :pager-count="5" prev-text="上一页" next-text="下一页" hide-on-single-page :total="goodsTotal"></el-pagination>
</div>
</div>
<div v-else-if="!loading && !goodsList.length" class="empty">您还没有关注商品哦</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="goods-recommended">
<div class="youLike">
<span>猜你喜欢</span>
</div>
<div class="body-wrap">
<ul class="goods-list">
<li v-for="(item, index) in list" :key="index" :title="item.goods_name" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
<div class="img-wrap">
<img alt="商品图片" :src="$img(item.goods_image.split(',')[0], {size: 'mid'})" @error="imageImgError(index)" />
</div>
<h3>{{ item.goods_name }}</h3>
<p class="price">
<span class="num">{{ item.discount_price }}</span>
<del>{{ item.market_price }}</del>
</p>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import {
goodsCollect,
deleteGoods
} from "@/api/member/collection"
import {
mapGetters
} from "vuex"
import {
goodsRecommend
} from '@/api/goods/goods';
export default {
name: "collection",
layout: "member",
components: {},
data() {
return {
goodsInfo: {
page: 1,
page_size: 10
},
shopInfo: {
page: 1,
page_size: 10
},
activeName: "goods",
goodsTotal: 0,
goodsList: [],
loading: true,
yes: true,
list: [],
page: 1,
pageSize: 5
}
},
created() {
this.getGoodsCollect()
this.getGoodsRecommend()
},
computed: {
...mapGetters(["defaultGoodsImage"])
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
// 获取推荐商品列列表
getGoodsRecommend() {
goodsRecommend({
page: this.page,
page_size: this.pageSize
}).then(res => {
if (res.code == 0) this.list = res.data.list;
this.loading = false;
}).catch(res => {
this.loading = false;
});
},
//获取关注商品
getGoodsCollect() {
goodsCollect(this.goodsInfo).then(res => {
this.goodsTotal = res.data.count
this.goodsList = res.data.list
this.loading = false
}).catch(err => {
this.loading = false
this.$message.error(err.message)
})
},
//删除关注商品
deleteGoods(id) {
deleteGoods({
goods_id: id
}).then(res => {
if (res.code == 0) {
this.$message({
message: "取消关注成功",
type: "success"
})
this.getGoodsCollect()
}
}).catch(err => {
this.$message.error(err.message)
})
},
handleClick(tab, event) {
if (tab.index == "0") {
this.loading = true
this.getGoodsCollect()
}
},
handleSizeChange(size) {
this.goodsInfo.page_size = size
this.loading = true
this.getGoodsCollect()
},
handleCurrentChange(page) {
this.goodsInfo.page = page
this.loading = true
this.getGoodsCollect()
},
imageError(index) {
this.goodsList[index].sku_image = this.defaultGoodsImage
},
imageImgError(index) {
this.list[index].sku_image = this.defaultGoodsImage;
}
}
}
</script>
<style lang="scss" scoped>
.goods-recommended {
width: 100%;
margin-top: 15px;
background-color: #fff;
.youLike {
width: 955px;
box-sizing: border-box;
border-bottom: 2px solid #dedede;
margin: 0 20px 20px;
span {
display: inline-block;
font-size: 14px;
padding: 10px 0;
}
}
.body-wrap {
.goods-list {
display: flex;
flex-wrap: wrap;
li {
width: 23%;
margin-left: 19px;
margin-bottom: 20px;
background: #fff;
cursor: pointer;
padding: 10px 0;
transition: all 0.2s linear;
&:hover {
z-index: 2;
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
-webkit-transform: translate3d(0, -2px, 0);
transform: translate3d(0, -2px, 0);
}
.img-wrap {
width: 160px;
height: 160px;
margin: 0 auto 18px;
text-align: center;
line-height: 160px;
img {
max-width: 100%;
max-height: 100%;
}
}
h3 {
font-size: 14px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin: 5px 15px;
}
.desc {
margin: 0 30px 10px;
height: 20px;
font-size: 12px;
color: #b0b0b0;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.price {
margin: 0 10px 14px;
text-align: center;
color: $base-color;
del {
margin-left: 0.5em;
color: #b0b0b0;
}
}
}
}
}
.bottom-wrap {
margin-top: 10px;
width: $width;
height: 118px;
cursor: pointer;
overflow: hidden;
img {
max-width: 100%;
}
}
}
.box {
width: 100%;
position: relative;
}
.null-page {
width: 100%;
height: 730px;
background-color: #FFFFFF;
position: absolute;
top: 0;
left: 0;
z-index: 9;
}
.collection {
background: #ffffff;
padding: 10px 20px;
.goods {
display: flex;
flex-wrap: wrap;
.goods-wrap {
width: 19%;
margin-right: 1.25%;
margin-bottom: 20px;
&:nth-child(5n) {
margin-right: 0;
}
.goods-item {
border: 1px solid #f1f1f1;
box-sizing: border-box;
padding: 10px;
.img {
width: 100%;
height: 160px;
cursor: pointer;
position: relative;
img {
width: 100%;
height: 100%;
}
.del {
font-size: 20px;
position: absolute;
top: 2px;
right: 2px;
padding: 3px;
background: rgba($color: #000000, $alpha: 0.3);
display: none;
color: #ffffff;
}
&:hover {
.del {
display: block;
}
}
}
.goods-name {
width: 100%;
margin-top: 10px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
height: 55px;
}
.price {
color: $base-color;
}
}
}
}
.shop {
display: flex;
flex-wrap: wrap;
.shop-wrap {
margin: 0 15px 20px 0;
&:nth-child(5n) {
margin-right: 0;
}
.shop-item {
width: 156px;
height: 227px;
border: 1px solid #eeeeee;
padding: 0 10px;
cursor: pointer;
.head-wrap {
text-align: center;
padding: 10px 0;
border-bottom: 1px solid #eeeeee;
position: relative;
.del {
font-size: 20px;
position: absolute;
top: 0px;
right: 0px;
padding: 3px;
background: rgba($color: #000000, $alpha: 0.3);
display: none;
color: #ffffff;
cursor: pointer;
}
&:hover {
.del {
display: block;
}
}
.img-wrap {
width: 60px;
height: 60px;
line-height: 60px;
display: inline-block;
}
.name {
display: block;
width: 100%;
height: 24px;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tag {
margin-left: 5px;
}
}
.info-wrap {
padding: 10px 0;
}
}
}
}
.empty {
text-align: center;
}
.page {
text-align: center;
}
}
</style>

View File

@@ -0,0 +1,272 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card member-coupon">
<div slot="header" class="clearfix"><span>我的优惠券</span></div>
<div>
<div v-loading="loading">
<el-tabs v-model="couponstatus" @tab-click="handleClickStatus">
<el-tab-pane label="未使用" name="1"></el-tab-pane>
<el-tab-pane label="已使用" name="2"></el-tab-pane>
<el-tab-pane label="已过期" name="3"></el-tab-pane>
</el-tabs>
<div class="coupon-wrap">
<div class="text item" :class="state == '1' ? 'coupon-not-used' : state == '2' ? 'coupon-used' : 'coupon-expire'" v-for="(item, index) in couponList" :key="index" @click="useCoupon(item)">
<template>
<p class="coupon-wrap-money" v-if="item.discount == '0.00' || !item.discount">
<span>{{ item.money }}</span>
</p>
<p class="coupon-wrap-money" v-else>
<span>{{ item.discount }}</span>
</p>
</template>
<p class="coupon-wrap-name">{{ item.platformcoupon_name }}</p>
<template>
<p class="coupon-wrap-least coupon-wrap-info" v-if="item.at_least > 0">{{ item.at_least }}元可用</p>
<p class="coupon-wrap-least coupon-wrap-info" v-else>无门槛优惠券</p>
</template>
<template>
<p class="coupon-wrap-time coupon-wrap-info">{{item.end_time > 0 ? '有效期至' + $timeStampTurnTime(item.end_time) : '长期有效' }}</p>
</template>
</div>
<div class="empty-text" v-if="couponList.length == 0">{{ text }}</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>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {couponList as getCouponList} from '@/api/member/member';
import {mapGetters} from 'vuex';
export default {
name: 'my_coupon',
layout: "member",
components: {},
data: () => {
return {
total: 0,
currentPage: 1,
pageSize: 9,
couponstatus: '1',
couponList: [],
type: '',
state: 1,
text: '您还没有优惠券哦',
loading: true,
yes: true
};
},
created() {
if (this.addonIsExit && this.addonIsExit.coupon != 1) {
this.$message({
message: '优惠券插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/member');
}
});
} else {
this.getListData();
}
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['addonIsExit'])
},
watch: {
addonIsExit() {
if (this.addonIsExit.coupon != 1) {
this.$message({
message: '优惠券插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/member');
}
});
}
}
},
methods: {
/**
* 优惠券状态(未使用/已使用/已过期)
*/
handleClickStatus(tab, event) {
if (tab.name == '1') {
this.state = 1;
this.text = '您还没有优惠券哦';
} else if (tab.name == '2') {
this.state = 2;
this.text = '您还没有使用过优惠券哦';
} else {
this.state = 3;
this.text = '您还没有过期优惠券哦';
}
this.refresh();
},
handlePageSizeChange(size) {
this.pageSize = size;
this.refresh();
},
handleCurrentPageChange(page) {
this.currentPage = page;
this.refresh();
},
refresh() {
this.loading = true;
this.getListData();
},
// 获取优惠券列表
getListData() {
getCouponList({
page: this.currentPage,
page_size: this.pageSize,
state: this.state,
is_own: this.type,
}).then(res => {
if (res.code >= 0) {
this.total = res.data.count;
this.couponList = res.data.list;
}
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error(err.message);
});
},
// 去使用优惠券
useCoupon(item) {
if (item.state == 1) {
if (item.use_scenario != 1) {
this.$router.push({path: '/goods/list', query: {coupon: item.coupon_type_id}});
} else {
this.$router.push('/goods/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;
}
.coupon-wrap {
display: flex;
align-items: center;
flex-wrap: wrap;
.text {
width: 32%;
height: 140px;
margin-right: 2%;
border-radius: 5px;
border: 1px dashed #fff;
margin-bottom: 20px;
padding: 0 15px;
box-sizing: border-box;
color: #ffffff;
.coupon-wrap-money {
span {
font-size: 30px;
margin-right: 5px;
}
}
.coupon-wrap-info {
font-size: 12px;
line-height: 18px;
}
}
.text:nth-child(3n) {
margin-right: 0;
}
.coupon-not-used {
background-color: $base-color;
cursor: pointer;
}
.coupon-used {
background-color: hsl(360, 50%, 70%);
}
.coupon-expire {
background-color: #d0d0d0;
}
.coupon-wrap-info {
font-size: 12px;
line-height: 20px;
}
.empty-text {
margin: 0 auto;
}
}
</style>
<style lang="scss">
.member-coupon {
.el-tabs__active-bar,
.el-tabs__nav-wrap::after {
/* 清除tab标签底部横线 */
height: 0;
}
}
</style>

View File

@@ -0,0 +1,280 @@
<template>
<div class="box" v-loading="loading">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>收货地址</span>
</div>
<div>
<div class="ns-member-address-list">
<div class="text item ns-add-address" @click="addAddress('add')">
<span>+ 添加收货地址</span>
</div>
<div class="text item" v-for="(item, index) in addressList" :key="index">
<div class="text-name">
<span>{{ item.name }}</span>
<span v-if="item.is_default == 1" class="text-default">默认</span>
</div>
<div class="text-content">
<p>{{ item.mobile }}</p>
<p :title="item.full_address + item.address" class="ns-address-detail">
{{ item.full_address }}{{ item.address }}</p>
</div>
<div class="text-operation">
<span v-if="item.is_default != 1" @click="setDefault(item.id)">设为默认</span>
<span @click="addAddress('edit', item.id)">编辑</span>
<span v-if="item.is_default != 1" @click="delAddress(item.id, item.is_default)">删除</span>
</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>
</div>
</el-card>
</div>
</template>
<script>
import {
addressList,
setDefault,
deleteAddress
} from "@/api/member/member"
export default {
name: "delivery_address",
layout: "member",
components: {},
data: () => {
return {
addressList: [],
total: 0,
currentPage: 1,
pageSize: 8,
loading: true,
yes: true
}
},
created() {
this.getListData()
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
getListData() {
addressList({
page: this.currentPage,
page_size: this.pageSize,
type: 1
})
.then(res => {
const {
count,
page_count,
list
} = res.data
this.total = count
this.addressList = list
this.loading = false
})
.catch(err => {
this.loading = false
this.$message.error(err.message)
})
},
handlePageSizeChange(size) {
this.pageSize = size
this.refresh()
},
handleCurrentPageChange(page) {
this.currentPage = page
this.refresh()
},
refresh() {
this.loading = true
this.getListData()
},
/**
* 设为默认
*/
setDefault(id) {
setDefault({
id: id
}).then(res => {
this.refresh()
this.$message({
message: "修改默认地址成功",
type: "success"
})
}).catch(err => {
this.$message.error(err.message)
})
},
/**
* 添加/编辑地址
*/
addAddress(type, id) {
if (type == "edit") {
this.$router.push({
path: "/member/address_edit",
query: {
id: id
}
})
} else {
this.$router.push({
path: "/member/address_edit"
})
}
},
/**
* 删除地址
*/
delAddress(id, is_default) {
this.$confirm("确定要删除该地址吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (is_default == 1) {
this.$message({
type: "warning",
message: "默认地址,不能删除!"
})
return
}
deleteAddress({
id: id
}).then(res => {
this.refresh()
this.$message({
message: res.message,
type: "success"
})
}).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;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.ns-member-address-list {
display: flex;
flex-wrap: wrap;
.text {
width: 32%;
height: 140px;
margin-right: 2%;
border-radius: 5px;
border: 1px solid #d8d8d8;
margin-bottom: 20px;
padding: 0 15px;
box-sizing: border-box;
.text-name {
height: 37px;
line-height: 40px;
padding: 0 10px;
border-bottom: 1px solid #eeeeee;
}
.text-default {
display: inline-block;
margin-left: 10px;
background: $base-color;
color: #ffffff;
width: 35px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 3px;
}
.text-content {
padding: 10px;
}
.ns-address-detail {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.text-operation {
// 操作
text-align: right;
span {
margin: 0 5px;
color: #999999;
cursor: pointer;
}
span:hover {
color: $base-color;
}
}
}
.text:nth-child(3n) {
margin-right: 0;
}
.ns-add-address {
border: 1px dashed #d8d8d8;
text-align: center;
color: #999999;
line-height: 140px;
cursor: pointer;
}
.ns-add-address:hover {
border-color: $base-color;
color: $base-color;
}
}
</style>

View File

@@ -0,0 +1,223 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card foot-print">
<div slot="header" class="clearfix">
<span>我的足迹</span>
</div>
<div v-loading="loading" v-if="timesArr != ''">
<el-timeline>
<el-timeline-item class="ns-time-line" v-for="(item, index) in timesArr" :timestamp="item" placement="top" :key="index">
<el-card>
<div class="ns-goods-list">
<div class="ns-goods-li" v-for="(value, name) in footPrintData" :key="name" v-if="item == value.browse_time" @click="$util.pushToTab('/sku/' + value.sku_id)">
<span class="ns-btn-del" @click.stop="deleteFootprint(value.id)"><i class="iconfont icon-shanchu"></i></span>
<el-image :src="$img(value.goods_image, { size: 'mid' })" fit="contain" @error="imageError(name)"/>
<p class="goods-name" :title="value.goods_name">{{ value.goods_name }}</p>
<span class="goods-price">{{ value.goods_price }}</span>
</div>
</div>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<div v-else class="footprint">
<router-link to="/">暂时没有足迹~</router-link>
</div>
</el-card>
</div>
</template>
<script>
import {footPrint, delFootprint} from "@/api/member/member"
import {mapGetters} from "vuex"
export default {
name: "footprint",
layout: "member",
components: {},
data: () => {
return {
timesArr: [],
footPrintData: [],
loading: true,
yes: true
}
},
created() {
this.getFootPrintData()
},
computed: {
...mapGetters(["defaultGoodsImage"])
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
/**
* 商品列表
*/
getFootPrintData() {
footPrint({
page: 1,
page_size: 0
}).then(res => {
var data = res.data.list
this.footPrintData = []
this.timesArr = []
for (let i = 0; i < data.length; i++) {
var date = this.$util.timeStampTurnTime(data[i].browse_time).split(" ")[0]
var flag = this.$util.inArray(date, this.timesArr)
if (flag == -1) {
this.timesArr.push(date)
}
var goods = {}
goods.id = data[i].id
goods.sku_id = data[i].sku_id
goods.browse_time = date
goods.goods_image = data[i].sku_image.split(",")[0]
goods.goods_name = data[i].sku_name
goods.goods_price = data[i].discount_price
this.footPrintData.push(goods)
}
this.loading = false
}).catch(err => {
this.loading = false
})
},
/**
* 图片加载失败
*/
imageError(index) {
this.footPrintData[index].goods_image = this.defaultGoodsImage
},
/**
* 删除某个足迹
*/
deleteFootprint(id) {
delFootprint({
id: id
}).then(res => {
this.loading = false
this.getFootPrintData()
this.$message({message: res.message, type: "success"})
}).catch(err => {
this.loading = false
this.$message.error(err.message)
})
},
mouseenter(scope) {
this.$set(scope, "del", true)
},
mouseleave(scope) {
this.$set(scope, "del", false)
}
}
}
</script>
<style lang="scss" scoped>
.footprint {
width: 100%;
text-align: center;
}
.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;
}
.ns-goods-list {
display: flex;
flex-wrap: wrap;
.ns-goods-li {
width: 32%;
margin-right: 2%;
margin-bottom: 20px;
padding: 15px;
box-sizing: border-box;
background-color: #f1f1f1;
border-radius: 5px;
cursor: pointer;
position: relative;
.el-image {
width: 100%;
height: 250px;
}
.goods-name {
margin-top: 10px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-price {
color: $base-color;
font-size: 20px;
}
.ns-btn-del {
position: absolute;
top: -6px;
right: -6px;
color: #999999;
cursor: pointer;
display: none;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
i {
font-size: 20px;
}
}
&:hover {
.ns-btn-del {
display: inline-block;
}
}
}
.ns-goods-li:nth-child(3n) {
margin-right: 0;
}
}
</style>
<style lang="scss">
.foot-print .ns-time-line .el-timeline-item__timestamp.is-top {
font-size: 18px;
color: #333333;
}
</style>

View File

@@ -0,0 +1,720 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div class="member-index" v-loading="loading">
<div class="member-top">
<div class="info-wrap">
<div class="info-top">
<div class="avtar">
<router-link to="/member/info">
<img v-if="member.headimg" :src="$img(member.headimg)" @error="member.headimg = defaultHeadImage" />
<img v-else :src="$img(defaultHeadImage)" />
</router-link>
</div>
<div class="member-wrap">
<template v-if="member">
<div class="name member-name" v-if="member.nickname">
<router-link to="/member/info">{{ member.nickname }}</router-link>
</div>
<div class="level" v-if="member.member_level_name">{{ member.member_level_name }}</div>
<div class="growth">
成长值
<el-progress :text-inside="true" :stroke-width="10" :percentage="progress" :show-text="false"></el-progress>
<div></div>
</div>
</template>
<div class="no-login name" v-else>未登录</div>
</div>
</div>
<div class="account">
<div class="content">
<div class="item">
<router-link to="/member/coupon" class="item-content">
<img src="@/assets/images/coupon.png" alt />
<div class="name">优惠券</div>
<div class="num" v-if="member.member_id && couponNum">{{ couponNum }}</div>
<div class="num" v-else>0</div>
</router-link>
</div>
<div class="item">
<router-link to="/member/my_point" class="item-content">
<img src="@/assets/images/point.png" alt />
<div class="name">积分</div>
<div class="num" v-if="member.point">{{ member.point }}</div>
<div class="num" v-else>0</div>
</router-link>
</div>
<div class="item">
<router-link to="/member/account" class="item-content">
<img src="@/assets/images/balance.png" alt />
<div class="name">余额</div>
<div class="num" v-if="member.balance || member.balance_money">{{ (parseFloat(member.balance) + parseFloat(member.balance_money)).toFixed(2) }}</div>
<div class="num" v-else>0</div>
</router-link>
</div>
</div>
</div>
</div>
<div class="collection">
<router-link to="/member/collection" class="item-content">
<div class="title">我的关注</div>
<div class="xian"></div>
<div class="item-wrap">
<div class="item">
<div class="num">{{ goodsTotal }}</div>
<div class="collect">商品关注</div>
</div>
</div>
</router-link>
</div>
</div>
<div class="member-bottom">
<div class="my-order">
<div class="order-title">我的订单</div>
<div class="xian"></div>
<div class="order-item">
<router-link to="/member/order_list?status=waitpay" class="item">
<i class="iconfont icon-daifukuan"></i>
<div v-if="orderNum.waitPay" class="order-num">{{ orderNum.waitPay }}</div>
<div class="name">待付款</div>
</router-link>
<router-link to="/member/order_list?status=waitsend" class="item">
<i class="iconfont icon-daifahuo"></i>
<div v-if="orderNum.readyDelivery" class="order-num">{{ orderNum.readyDelivery }}</div>
<div class="name">待发货</div>
</router-link>
<router-link to="/member/order_list?status=waitconfirm" class="item">
<i class="iconfont icon-tubiaolunkuo-"></i>
<div v-if="orderNum.waitDelivery" class="order-num">{{ orderNum.waitDelivery }}</div>
<div class="name">待收货</div>
</router-link>
<router-link to="/member/order_list?status=waitrate" class="item">
<i class="iconfont icon-daipingjia"></i>
<div v-if="orderNum.waitEvaluate" class="order-num">{{ orderNum.waitEvaluate }}</div>
<div class="name">待评价</div>
</router-link>
<router-link to="/member/activist" class="item">
<i class="iconfont icon-shouhou"></i>
<div v-if="orderNum.refunding" class="order-num">{{ orderNum.refunding }}</div>
<div class="name">退款/售后</div>
</router-link>
</div>
<div v-if="orderList.length">
<div class="order-goods-wrap" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
<div class="order-goods" v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
<div class="goods-item">
<div class="goods-img" @click="$util.pushToTab({ path: '/sku/' + goodsItem.sku_id })">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageErrorOrder(orderIndex, goodsIndex)" />
</div>
<div class="info-wrap">
<div class="goods-name" @click="$util.pushToTab({ path: '/sku/' + goodsItem.sku_id })">{{ goodsItem.sku_name }}</div>
<div class="price">{{ goodsItem.price }}</div>
</div>
<div class="payment">{{ orderItem.order_status_name }}</div>
<div class="goods-detail" @click="orderDetail(orderItem)">
<p>查看详情</p>
</div>
</div>
</div>
</div>
</div>
<div class="empty" v-else>
<img src="@/assets/images/member-empty.png" alt />
<div>
<router-link to="/">您买的东西太少了这里都空空的快去挑选合适的商品吧</router-link>
</div>
</div>
</div>
<div class="bottom-right">
<div class="my-foot">
<div class="title">我的足迹</div>
<div class="xian"></div>
<div class="foot-content" v-for="(item, index) in footList" :key="item.goods_id">
<div class="foot-item" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
<div class="foot-img">
<img :src="$img(item.sku_image, { size: 'mid' })" @error="imageErrorFoot(index)" />
</div>
<div class="foot-info">
<div class="foot-name">{{ item.goods_name }}</div>
<div class="foot-price">{{ item.discount_price }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {
orderNum,
couponNum,
footprint,
levelList
} from '@/api/member/index';
import {
goodsCollect
} from '@/api/member/collection';
import {
apiOrderList
} from '@/api/order/order';
import {
mapGetters
} from 'vuex';
export default {
name: 'member',
components: {},
layout: 'member',
data: () => {
return {
couponNum: 0,
orderNum: {
waitPay: 0, //待付款
readyDelivery: 0, //待发货
waitDelivery: 0, //待收货
refunding: 0 // 退款中
},
orderList: [],
orderStatus: 'all',
footInfo: {
page: 1,
page_size: 6
},
total: 0,
footList: [],
currentPage: 1,
loading: true,
goodsTotal: 0,
state: '',
growth: '',
levelList: [],
member_level: {},
progress: 0,
yes: true
};
},
created() {
this.getCouponNum();
this.getOrderNum();
this.getOrderList();
this.getFootprint();
this.getGoodsCollect();
// this.$store.dispatch("member/member_detail")
this.$forceUpdate()
},
computed: {
...mapGetters(['defaultHeadImage', 'defaultGoodsImage', 'member'])
},
watch: {
member: {
handler() {
if (this.member) this.getLevelList();
},
immediate: true,
deep: true,
}
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false;
}, 300);
},
methods: {
getLevelList() {
levelList().then(res => {
if (res.data && res.code == 0) {
this.levelList = res.data;
let listIndex = this.levelList.findIndex(item => item.level_id == this.member.member_level);
const max = this.levelList.length;
if (max > listIndex + 1) {
if (this.member.growth > this.levelList[listIndex + 1].growth) {
this.progress = 100;
} else {
this.progress = (this.member.growth / this.levelList[listIndex + 1].growth) * 100;
}
} else {
this.progress = 100;
}
} else {
this.$message.error(err.message);
}
})
},
//获取优惠券数量
getCouponNum() {
couponNum().then(res => {
this.couponNum = res.data;
})
},
//获取订单数量
getOrderNum() {
orderNum({
order_status: 'waitpay,waitsend,waitconfirm,waitrate,refunding'
}).then(res => {
if (res.code == 0) {
this.orderNum.waitPay = res.data.waitpay;
this.orderNum.readyDelivery = res.data.waitsend;
this.orderNum.waitDelivery = res.data.waitconfirm;
this.orderNum.waitEvaluate = res.data.waitrate;
this.orderNum.refunding = res.data.refunding;
}
})
},
//获取订单列表
getOrderList() {
apiOrderList({
order_status: this.orderStatus,
page: 1,
page_size: 3
}).then(res => {
if (res.code == 0 && res.data) {
this.orderList = res.data.list;
}
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error(err.message);
});
},
//获取我的足迹
getFootprint() {
footprint(this.footInfo).then(res => {
if (res.code == 0 && res.data) {
this.footList = res.data.list;
this.total = res.data.count;
}
})
},
orderDetail(data) {
switch (parseInt(data.order_type)) {
case 2:
// 自提订单
this.$router.push({
path: '/member/order_detail_pickup',
query: {
order_id: data.order_id
}
});
break;
case 3:
// 本地配送订单
this.$router.push({
path: '/member/order_detail_local_delivery',
query: {
order_id: data.order_id
}
});
break;
case 4:
// 虚拟订单
this.$router.push({
path: '/member/order_detail_virtual',
query: {
order_id: data.order_id
}
});
break;
default:
this.$router.push({
path: '/member/order_detail',
query: {
order_id: data.order_id
}
});
break;
}
},
imageErrorOrder(orderIndex, goodsIndex) {
this.orderList[orderIndex].order_goods[goodsIndex].sku_image = this.defaultGoodsImage;
},
imageErrorFoot(index) {
this.footList[index].sku_image = this.defaultGoodsImage;
},
getGoodsCollect() {
goodsCollect()
.then(res => {
this.goodsTotal = res.data.count;
})
.catch(err => {
this.loading = false;
console.log(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;
}
.member-index {
.member-top {
width: 100%;
display: flex;
.info-wrap {
width: 75%;
height: 160px;
border: 1px solid #e9e9e9;
background: #ffffff;
display: flex;
.info-top {
display: flex;
align-items: center;
margin: 22px;
margin-right: 0;
width: 300px;
border-right: 1px solid #e9e9e9;
.avtar {
width: 84px;
height: 84px;
margin: 20px 0 10px 0;
border: 1px solid #e9e9e9;
border-radius: 50%;
overflow: hidden;
display: block;
cursor: pointer;
margin-left: 21px;
text-align: center;
line-height: 84px;
img {
display: inline-block;
}
}
.member-wrap {
margin-left: 20px;
.name {
font-size: 18px;
font-weight: 600;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.growth {
display: flex;
align-items: center;
}
.el-progress {
width: 100px;
}
.level {
padding: 3px 4px;
line-height: 1;
color: #ffffc1;
margin: 6px 0;
cursor: default;
background: linear-gradient(#636362, #4e4e4d);
border-radius: 3px;
display: inline-block;
}
}
}
.account {
width: 400px;
display: flex;
align-items: center;
.content {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
.item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.item-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
img {
width: 50px;
height: 50px;
}
.name {
margin-top: 5px;
color: #666666;
&:hover {
color: $base-color;
}
}
.num {
color: $ns-text-color-black;
}
}
}
}
}
.collection {
background: #ffffff;
margin-left: 20px;
width: 210px;
border: 1px solid #e9e9e9;
padding-left: 20px;
.title {
padding: 10px 0;
display: inline-block;
border-bottom: 1px solid $base-color;
}
.xian {
height: 1px;
background: #f1f1f1;
}
.item-wrap {
display: flex;
justify-content: center;
align-items: center;
.item {
flex: 1;
margin-top: 37px;
.num {
}
.collect {
color: #666666;
}
}
}
}
}
.member-bottom {
width: 100%;
margin-top: 15px;
height: 553px;
display: flex;
overflow: hidden;
.my-order {
width: 75%;
background-color: #ffffff;
.order-title {
font-size: $ns-font-size-base;
padding: 10px 0;
margin-left: 15px;
border-bottom: 1px solid $base-color;
display: inline-block;
}
.xian {
height: 1px;
background: #f1f1f1;
margin-left: 15px;
}
.order-item {
display: flex;
justify-content: center;
align-content: center;
.item {
flex: 1;
text-align: center;
height: 85px;
padding-top: 20px;
cursor: pointer;
position: relative;
&:hover {
background: #ffffff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.order-num {
position: absolute;
top: 23px;
right: 25px;
background: $base-color;
border-radius: 50%;
width: 18px;
height: 18px;
line-height: 18px;
color: #ffff;
}
i {
font-size: 30px;
}
.name {
font-size: $ns-font-size-base;
}
}
}
.order-goods {
.goods-item {
display: flex;
padding: 14px;
border-top: 1px solid #f1f1f1;
.goods-img {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
img {
width: 60px;
height: 60px;
}
}
.info-wrap {
flex: 3;
width: 80%;
.goods-name {
height: 46px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.price {
color: $base-color;
}
}
.payment {
flex: 2;
display: flex;
align-items: center;
justify-content: center;
text-overflow: ellipsis;
}
.goods-detail {
flex: 2;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover {
color: $base-color;
}
}
}
}
}
.bottom-right {
.my-foot {
background: #ffffff;
margin-left: 20px;
width: 230px;
.title {
font-size: $ns-font-size-base;
padding: 10px 0;
display: inline-block;
border-bottom: 1px solid $base-color;
margin: 0 15px;
}
.xian {
margin-left: 15px;
background: #f1f1f1;
height: 1px;
}
.foot-content {
.foot-item {
display: flex;
padding: 10px 0;
margin: 0 15px;
.foot-img {
width: 57px;
height: 57px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.foot-info {
margin-left: 5px;
display: flex;
flex-direction: column;
justify-content: space-between;
.foot-name {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1;
width: 140px;
}
.foot-price {
color: $base-color;
}
}
}
}
}
}
}
}
.empty {
text-align: center;
margin-top: 65px;
}
</style>

View File

@@ -0,0 +1,240 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div class="member-info" v-loading="loading">
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane label="基本信息" name="first">
<el-form ref="infoRef" :model="memberInfo" :rules="infoRules" label-width="80px">
<el-form-item label="账号" v-if="memberInfo.userName">
<p>{{ memberInfo.userName }}</p>
</el-form-item>
<!-- <el-form-item label="邮箱">
<p v-if="memberInfo.email">{{ memberInfo.email }}</p>
<p v-else class="toBind" @click="$router.push({ path: '/member/security' })">去绑定</p>
</el-form-item> -->
<el-form-item label="手机号">
<p v-if="memberInfo.tell">{{ memberInfo.tell }}</p>
<p v-else class="toBind" @click="$router.push({ path: '/member/security' })">去绑定</p>
</el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="memberInfo.nickName"></el-input>
</el-form-item>
</el-form>
<div class="btn">
<el-button size="medium" type="primary" @click="saveInfo">保存</el-button>
</div>
</el-tab-pane>
<el-tab-pane label="头像照片" name="second">
<div class="preview">
<div class="title">头像预览</div>
<div class="content">
完善个人信息资料上传头像图片有助于您结识更多的朋友
<br />
头像最佳默认尺寸为120x120像素
</div>
</div>
<el-upload :action="uploadActionUrl" :show-file-list="false" :on-success="handleAvatarSuccess" class="upload" accept=".png,.jpg,.jpeg">
<div class="img-wrap">
<img v-if="memberInfo.userHeadImg" :src="$img(memberInfo.userHeadImg)" />
<img v-else :src="$img(defaultHeadImage)" />
</div>
</el-upload>
<div class="btn">
<el-button size="medium" type="primary" @click="uploadHeadImg">保存</el-button>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import {info, nickName, headImg} from '@/api/member/info';
import Config from '@/plugins/config';
import {mapGetters} from 'vuex';
import {email} from '@/api/member/security';
export default {
name: 'info',
layout: "member",
components: {},
data: () => {
return {
memberInfo: {
userHeadImg: '',
userName: '', //账号
nickName: '', //昵称
email: '',
tell: ''
},
infoRules: {
nickName: [{required: true, message: '请输入昵称', trigger: 'blur'}, {
max: 30,
message: '最大长度为30个字符',
trigger: 'blur'
}]
},
activeName: 'first',
loading: true,
uploadActionUrl: Config.baseUrl + '/api/upload/headimg',
imgUrl: '',
yes: true
};
},
created() {
this.getInfo();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
getInfo() {
info().then(res => {
if (res.code == 0) {
this.memberInfo.userHeadImg = res.data.headimg;
this.memberInfo.userName = res.data.username;
this.memberInfo.nickName = res.data.nickname;
this.memberInfo.email = res.data.email;
this.memberInfo.tell = res.data.mobile;
}
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error(err.message);
});
},
handleClick(tab, event) {
},
saveInfo() {
this.$refs.infoRef.validate(valid => {
if (valid) {
nickName({nickname: this.memberInfo.nickName}).then(res => {
if (res.code == 0) {
this.$message({message: '修改昵称成功', type: 'success'});
this.getInfo();
this.$store.dispatch('member/member_detail', {refresh: 1});
}
}).catch(err => {
this.$message.error(err.message);
});
} else {
return false;
}
});
},
handleAvatarSuccess(res, file) {
this.imgUrl = res.data.pic_path;
this.memberInfo.userHeadImg = URL.createObjectURL(file.raw);
},
uploadHeadImg() {
headImg({headimg: this.imgUrl}).then(res => {
if (res.code == 0) {
this.$message({message: '头像修改成功', type: 'success'});
this.$store.dispatch('member/member_detail', {refresh: 1});
}
}).catch(err => {
this.$message.error(err.message);
});
}
},
computed: {
...mapGetters(['defaultHeadImage'])
}
};
</script>
<style>
.member-info .el-upload {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
</style>
<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;
}
.member-info {
background: #ffffff;
padding: 20px;
.el-tab-pane {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
.preview {
display: flex;
justify-content: center;
margin-bottom: 20px;
.title {
margin-right: 20px;
line-height: 3;
}
.content {
color: $base-color;
line-height: 1.5;
}
}
.upload {
display: flex;
justify-content: center;
}
.el-upload {
width: 120px;
}
.img-wrap {
width: 120px;
height: 120px;
display: block;
line-height: 120px;
overflow: hidden;
border: 1px solid #f1f1f1;
cursor: pointer;
img {
display: inline-block;
}
}
.el-form {
margin-top: 20px;
width: 500px;
margin-left: 200px;
.toBind {
cursor: pointer;
&:hover {
color: $base-color;
}
}
}
.btn {
text-align: center;
}
}
}
</style>

View File

@@ -0,0 +1,144 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div class="my-point" v-loading="loading">
<div class="member-point">
<div class="title">我的积分</div>
<div class="num">{{ memberPoint.point ? Math.ceil(memberPoint.point) : 0 }}</div>
</div>
<div class="detail">
<el-table :data="pointList" border>
<el-table-column prop="type_name" label="来源" width="150"></el-table-column>
<el-table-column prop="pointNum" label="积分" width="150"></el-table-column>
<el-table-column prop="remark" label="详细说明"></el-table-column>
<el-table-column prop="time" label="时间" width="180"></el-table-column>
</el-table>
</div>
<div class="pager">
<el-pagination
background
:pager-count="5"
:total="total"
prev-text="上一页"
next-text="下一页"
:current-page.sync="pointInfo.page"
:page-size.sync="pointInfo.page_size"
@size-change="handlePageSizeChange"
@current-change="handleCurrentPageChange"
hide-on-single-page
></el-pagination>
</div>
</div>
</div>
</template>
<script>
import {pointInfo, pointList} from "@/api/member/my_point"
export default {
name: "my_point",
layout: "member",
components: {},
data: () => {
return {
pointInfo: {
page: 1,
page_size: 10,
account_type: "point"
},
pointList: [],
memberPoint: {
point: 0
},
total: 0,
loading: true,
yes: true
}
},
created() {
this.getPointInfo();
this.getPointList()
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
getPointInfo() {
pointInfo({account_type: this.pointInfo.account_type}).then(res => {
if (res.code == 0 && res.data) {
this.memberPoint = res.data
}
this.loading = false
}).catch(err => {
this.loading = false
this.$message.error(err.message)
})
},
getPointList() {
pointList(this.pointInfo).then(res => {
if (res.code == 0 && res.data) {
this.pointList = res.data.list
this.total = res.data.count
this.pointList.forEach(item => {
item.time = this.$util.timeStampTurnTime(item.create_time)
item.pointNum = item.account_data > 0 ? "+" + parseInt(item.account_data) : parseInt(item.account_data)
})
}
}).catch(err => {
this.$message.error(err.message)
})
},
handlePageSizeChange(num) {
this.pointInfo.page_size = num
this.getPointList()
},
handleCurrentPageChange(page) {
this.pointInfo.page = page
this.getPointList()
}
}
}
</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;
}
.my-point {
background: #ffffff;
padding: 20px;
.member-point {
font-size: $ns-font-size-base;
font-weight: 600;
margin-bottom: 10px;
.num {
font-size: 30px;
font-weight: 600;
}
}
.page {
display: flex;
justify-content: center;
align-content: center;
padding-top: 20px;
}
}
</style>

View File

@@ -0,0 +1,558 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card order-detail">
<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">
<template v-if="orderDetail">
<div class="order-status">
<h4>
订单状态
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
</h4>
<div v-if="orderDetail.order_status == 0" class="go-pay">
<p>
需付款
<span>{{ orderDetail.pay_money }}</span>
</p>
</div>
<div class="operation" v-if="orderDetail.action.length > 0">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">
{{ operationItem.title }}
</el-button>
</div>
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
</div>
</div>
<div class="order-info">
<h4>订单信息</h4>
<ul>
<!-- <li>
<i class="iconfont iconmendian"></i>
店铺
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
</li> -->
<li>订单类型{{ orderDetail.order_type_name }}</li>
<li>订单编号{{ orderDetail.order_no }}</li>
<li>订单交易号{{ orderDetail.out_trade_no }}</li>
<li>配送方式{{ orderDetail.delivery_type_name }}</li>
<li v-if="orderDetail.order_status == -1">退款途径{{ orderDetail.refund_money_type == 1 ? '原路退款' : orderDetail.refund_money_type == 2 ? '线下退款' : '退款到余额' }}</li>
<li>创建时间{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
<li v-if="orderDetail.close_time > 0">关闭时间{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
<template v-if="orderDetail.pay_status > 0">
<li>支付方式{{ orderDetail.pay_type_name }}</li>
<li>支付时间{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
</template>
<li v-if="orderDetail.promotion_type_name != ''">店铺活动{{ orderDetail.promotion_type_name }}</li>
<li v-if="orderDetail.buyer_message != ''">买家留言{{ orderDetail.buyer_message }}</li>
</ul>
</div>
<div class="order-info" v-if="orderDetail.pay_type=='offlinepay'&&orderDetail.offline_pay_info">
<h4>线下支付</h4>
<ul>
<li v-if="orderDetail.offline_pay_info.status_info.const=='WAIT_AUDIT'">
支付状态审核中
</li>
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
支付状态审核被拒
</li>
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
审核备注{{orderDetail.offline_pay_info.audit_remark}}
</li>
</ul>
</div>
<div class="take-delivery-info">
<h4>收货信息</h4>
<ul>
<li>收货人{{ orderDetail.name }}</li>
<li>手机号码{{ orderDetail.mobile }}</li>
<li>收货地址{{ orderDetail.full_address }} {{ orderDetail.address }}</li>
</ul>
</div>
<!-- 发票信息 -->
<div class="take-delivery-info" v-if="orderDetail.is_invoice ==1">
<h4>发票信息</h4>
<ul>
<li>发票类型{{ orderDetail.invoice_type == 1 ? '纸质发票' : '电子发票' }}</li>
<li>发票抬头类型{{ orderDetail.invoice_title_type ==1 ? '个人' : '企业' }}</li>
<li>发票抬头{{ orderDetail.invoice_title }}</li>
<li>发票内容{{ orderDetail.invoice_content }}</li>
<li v-if="orderDetail.invoice_type == 1">发票邮寄地址地址{{ orderDetail.invoice_full_address }}</li>
<li v-else>发票接收邮箱{{ orderDetail.invoice_email }}</li>
</ul>
</div>
<nav>
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
<li>单价</li>
<li>数量</li>
<li>小计</li>
<li v-if="orderDetail.is_enable_refund">操作</li>
</nav>
<!-- 订单项·商品 -->
<div class="list">
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
</div>
<div class="info-wrap">
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
</li>
<li>
<span>{{ goodsItem.price }}</span>
</li>
<li>
<span>{{ goodsItem.num }}</span>
</li>
<li>
<span>{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
</li>
<li>
<el-button type="primary" plain size="mini" v-if="orderDetail.is_enable_refund == 1 && goodsItem.refund_status == 0 && orderDetail.order_scene == 'online' && goodsItem.promotion_type != 'blindbox'" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id, order_id: orderId } })">申请退款</el-button>
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status != 0" @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">{{goodsItem.refund_status_name}}</el-button>
</li>
</ul>
</div>
<!-- 订单总计 -->
<ul class="total">
<li>
<label>商品金额</label>
<span>{{ orderDetail.goods_money }}</span>
</li>
<li>
<label>运费</label>
<span>{{ orderDetail.delivery_money }}</span>
</li>
<li v-if="orderDetail.member_card_money > 0">
<label>会员卡</label>
<span>{{ orderDetail.member_card_money }}</span>
</li>
<li v-if="orderDetail.invoice_money > 0">
<label>税费</label>
<span>{{ orderDetail.invoice_money }}</span>
</li>
<li v-if="orderDetail.invoice_delivery_money > 0">
<label>发票邮寄费</label>
<span>{{ orderDetail.invoice_delivery_money }}</span>
</li>
<li v-if="orderDetail.adjust_money != 0">
<label>订单调整</label>
<span>
<template v-if="orderDetail.adjust_money < 0">-</template>
<template v-else>+</template>
{{ orderDetail.adjust_money | abs }}
</span>
</li>
<li v-if="orderDetail.promotion_money > 0">
<label>优惠</label>
<span>{{ orderDetail.promotion_money }}</span>
</li>
<li v-if="orderDetail.coupon_money > 0">
<label>优惠券</label>
<span>{{ orderDetail.coupon_money }}</span>
</li>
<li v-if="orderDetail.point_money > 0">
<label>积分抵扣</label>
<span>{{ orderDetail.point_money }}</span>
</li>
<li v-if="orderDetail.balance_money > 0">
<label>使用余额</label>
<span>{{ orderDetail.balance_money }}</span>
</li>
<li class="pay-money">
<label>实付款</label>
<span>{{ orderDetail.pay_money }}</span>
</li>
</ul>
</template>
</div>
</el-card>
</div>
</template>
<script>
import {
apiOrderDetail
} from '@/api/order/order';
import orderMethod from '@/utils/orderMethod';
import {
mapGetters
} from 'vuex';
export default {
name: 'order_detail',
components: {},
mixins: [orderMethod],
data: () => {
return {
orderId: 0,
orderDetail: null,
loading: true,
yes: true
};
},
created() {
this.orderId = this.$route.query.order_id;
this.getOrderDetail();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
methods: {
getOrderDetail() {
apiOrderDetail({
order_id: this.orderId
}).then(res => {
if (res.code >= 0) {
this.orderDetail = res.data;
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'
});
}
});
});
},
operation(action) {
switch (action) {
case 'orderPay': // 支付
this.orderPay(this.orderDetail);
break;
case 'orderClose': //关闭
this.orderClose(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'memberTakeDelivery': //收货
this.orderDelivery(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'trace': //查看物流
this.$router.push({
path: '/order/logistics',
query: {
order_id: this.orderDetail.order_id
}
});
break;
case 'memberOrderEvaluation': //评价
this.$util.pushToTab({
path: '/order/evaluate',
query: {
order_id: this.orderDetail.order_id
}
});
break;
case 'memberBatchRefund': //批量退款
this.$router.push({
path: '/order/batchrefund',
query: {
order_id: this.orderId
}
});
break;
case 'orderOfflinePay': //线下支付
this.$router.push({
path: '/pay',
query: {
code: this.orderDetail.offline_pay_info.out_trade_no
}
});
break;
case 'orderDelete':
this.orderDelete(this.orderDetail.order_id, () => {
this.$router.push({
path: '/member/order_list',
});
});
break;
}
},
imageError(index) {
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
}
},
filters: {
abs(value) {
return Math.abs(parseFloat(value)).toFixed(2);
}
}
};
</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-detail {
.order-status {
background-color: #fff;
margin-bottom: 20px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
.go-pay {
p {
display: inline-block;
vertical-align: middle;
span {
font-weight: bold;
color: $base-color;
font-size: 18px;
}
}
}
.operation {
margin-top: 10px;
}
}
.order-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
.take-delivery-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
nav {
overflow: hidden;
padding: 10px 0;
background: #fff;
border-bottom: 1px solid #eeeeee;
li {
float: left;
&:nth-child(1) {
width: 50%;
&.no-operation {
width: 60%;
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
.list {
border-bottom: 1px solid #eeeeee;
.item {
background-color: #fff;
padding: 10px 0;
overflow: hidden;
li {
float: left;
line-height: 60px;
&:nth-child(1) {
width: 50%;
line-height: inherit;
&.no-operation {
width: 60%;
}
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
h5 {
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;
cursor: pointer;
&:hover {
color: $base-color;
}
}
span {
font-size: $ns-font-size-sm;
color: #9a9a9a;
}
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
}
// 总计
.total {
padding: 20px;
background-color: #fff;
text-align: right;
li {
span {
width: 150px;
display: inline-block;
}
&.pay-money {
font-weight: bold;
span {
color: $base-color;
font-size: 16px;
vertical-align: middle;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,490 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card order-detail">
<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">
<template v-if="orderDetail">
<div class="order-status">
<h4>
订单状态
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
</h4>
<div v-if="orderDetail.order_status == 0" class="go-pay">
<p>
需付款
<span>{{ orderDetail.pay_money }}</span>
</p>
</div>
<div class="operation" v-if="orderDetail.action.length > 0">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">
{{ operationItem.title }}
</el-button>
</div>
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
</div>
</div>
<div class="order-info">
<h4>订单信息</h4>
<ul>
<!-- <li>
<i class="iconfont iconmendian"></i>
店铺
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
</li> -->
<li>订单类型{{ orderDetail.order_type_name }}</li>
<li>订单编号{{ orderDetail.order_no }}</li>
<li>订单交易号{{ orderDetail.out_trade_no }}</li>
<li>配送方式{{ orderDetail.delivery_type_name }}</li>
<li>创建时间{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
<li v-if="orderDetail.close_time > 0">关闭时间{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
<template v-if="orderDetail.pay_status > 0">
<li>支付方式{{ orderDetail.pay_type_name }}</li>
<li>支付时间{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
</template>
<li v-if="orderDetail.promotion_type_name != ''">店铺活动{{ orderDetail.promotion_type_name }}</li>
<li v-if="orderDetail.buyer_message != ''">买家留言{{ orderDetail.buyer_message }}</li>
</ul>
</div>
<div class="take-delivery-info">
<h4>收货信息</h4>
<ul>
<li>收货人{{ orderDetail.name }}</li>
<li>手机号码{{ orderDetail.mobile }}</li>
<li>收货地址{{ orderDetail.full_address }} {{ orderDetail.address }}</li>
</ul>
</div>
<nav>
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
<li>单价</li>
<li>数量</li>
<li>小计</li>
<li v-if="orderDetail.is_enable_refund">操作</li>
</nav>
<!-- 订单项·商品 -->
<div class="list">
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
</div>
<div class="info-wrap">
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
</li>
<li>
<span>{{ goodsItem.price }}</span>
</li>
<li>
<span>{{ goodsItem.num }}</span>
</li>
<li>
<span>{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
</li>
<li v-if="orderDetail.is_enable_refund">
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status == 0 || goodsItem.refund_status == -1" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id } })">退款</el-button>
<el-button type="primary" plain size="mini" v-else @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">查看退款</el-button>
</li>
</ul>
</div>
<!-- 订单总计 -->
<ul class="total">
<li>
<label>商品金额</label>
<span>{{ orderDetail.goods_money }}</span>
</li>
<li>
<label>运费</label>
<span>{{ orderDetail.delivery_money }}</span>
</li>
<li v-if="orderDetail.member_card_money > 0">
<label>会员卡</label>
<span>{{ orderDetail.member_card_money }}</span>
</li>
<li v-if="orderDetail.invoice_money > 0">
<label>税费</label>
<span>{{ orderDetail.invoice_money }}</span>
</li>
<li v-if="orderDetail.invoice_delivery_money > 0">
<label>发票邮寄费</label>
<span>{{ orderDetail.invoice_delivery_money }}</span>
</li>
<li v-if="orderDetail.adjust_money != 0">
<label>订单调整</label>
<span>
<template v-if="orderDetail.adjust_money < 0">-</template>
<template v-else>+</template>
{{ orderDetail.adjust_money | abs }}
</span>
</li>
<li v-if="orderDetail.promotion_money > 0">
<label>优惠</label>
<span>{{ orderDetail.promotion_money }}</span>
</li>
<li v-if="orderDetail.coupon_money > 0">
<label>优惠券</label>
<span>{{ orderDetail.coupon_money }}</span>
</li>
<li v-if="orderDetail.point_money > 0">
<label>积分抵扣</label>
<span>{{ orderDetail.point_money }}</span>
</li>
<li v-if="orderDetail.balance_money > 0">
<label>使用余额</label>
<span>{{ orderDetail.balance_money }}</span>
</li>
<li class="pay-money">
<label>实付款</label>
<span>{{ orderDetail.pay_money }}</span>
</li>
</ul>
</template>
</div>
</el-card>
</div>
</template>
<script>
import {apiOrderDetail} from '@/api/order/order';
import orderMethod from '@/utils/orderMethod';
import {mapGetters} from 'vuex';
export default {
name: 'order_detail_local_delivery',
components: {},
mixins: [orderMethod],
data: () => {
return {
orderId: 0,
orderDetail: null,
loading: true,
yes: true
};
},
created() {
this.orderId = this.$route.query.order_id;
this.getOrderDetail();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
getOrderDetail() {
apiOrderDetail({
order_id: this.orderId
}).then(res => {
if (res.code >= 0) {
this.orderDetail = res.data;
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'});
}
});
});
},
operation(action) {
switch (action) {
case 'orderPay': // 支付
this.orderPay(this.orderDetail);
break;
case 'orderClose': //关闭
this.orderClose(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'memberTakeDelivery': //收货
this.orderDelivery(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'trace': //查看物流
this.$router.push({path: '/order/logistics', query: {order_id: this.orderDetail.order_id}});
break;
case 'memberOrderEvaluation': //评价
this.$util.pushToTab({path: '/order/evaluate', query: {order_id: this.orderDetail.order_id}});
break;
}
},
imageError(index) {
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
}
},
filters: {
abs(value) {
return Math.abs(parseFloat(value)).toFixed(2);
}
}
};
</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-detail {
.order-status {
background-color: #fff;
margin-bottom: 20px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
.go-pay {
p {
display: inline-block;
vertical-align: middle;
span {
font-weight: bold;
color: $base-color;
font-size: 18px;
}
}
}
.operation {
margin-top: 10px;
}
}
.order-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
.take-delivery-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
nav {
overflow: hidden;
padding: 10px 0;
background: #fff;
border-bottom: 1px solid #eeeeee;
li {
float: left;
&:nth-child(1) {
width: 50%;
&.no-operation {
width: 60%;
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
.list {
border-bottom: 1px solid #eeeeee;
.item {
background-color: #fff;
padding: 10px 0;
overflow: hidden;
li {
float: left;
line-height: 60px;
&:nth-child(1) {
width: 55%;
line-height: inherit;
&.no-operation {
width: 60%;
}
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
h5 {
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;
cursor: pointer;
display: inline-block;
&:hover {
color: $base-color;
}
}
span {
font-size: $ns-font-size-sm;
color: #9a9a9a;
}
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
}
// 总计
.total {
padding: 20px;
background-color: #fff;
text-align: right;
li {
span {
width: 150px;
display: inline-block;
}
&.pay-money {
font-weight: bold;
span {
color: $base-color;
font-size: 16px;
vertical-align: middle;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,583 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card order-detail">
<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">
<template v-if="orderDetail">
<div class="order-status">
<h4>
订单状态
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
</h4>
<div v-if="orderDetail.order_status == 0" class="go-pay">
<p>
需付款
<span>{{ orderDetail.pay_money }}</span>
</p>
</div>
<div class="operation" v-if="orderDetail.action.length > 0">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">{{ operationItem.title }}</el-button>
</div>
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
</div>
</div>
<div class="pickup-info" v-if="orderDetail.pay_status">
<h4>
自提点
<span class="ns-text-color">{{ orderDetail.delivery_store_name }}</span>
</h4>
<ul>
<li>
提货码
<span class="ns-text-color">{{ orderDetail.delivery_code }}</span>
</li>
<li v-if="orderDetail.delivery_store_info && orderDetail.delivery_store_info.open_date">营业时间{{ orderDetail.delivery_store_info.open_date }}</li>
<li v-if="orderDetail.delivery_store_info && orderDetail.delivery_store_info.telphone">联系方式{{ orderDetail.delivery_store_info.telphone }}</li>
<li v-if="orderDetail.delivery_store_info && orderDetail.delivery_store_info.full_address">详细地址{{ orderDetail.delivery_store_info.full_address }}</li>
</ul>
<img :src="$img(orderDetail.pickup)" />
</div>
<nav>
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
<li>单价</li>
<li>数量</li>
<li>小计</li>
<li v-if="orderDetail.is_enable_refund">操作</li>
</nav>
<div class="order-info">
<h4>订单信息</h4>
<ul>
<!-- <li>
<i class="iconfont iconmendian"></i>
店铺
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
</li> -->
<li>订单类型{{ orderDetail.order_type_name }}</li>
<li>订单编号{{ orderDetail.order_no }}</li>
<li>订单交易号{{ orderDetail.out_trade_no }}</li>
<li>配送方式{{ orderDetail.delivery_type_name }}</li>
<li>创建时间{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
<li v-if="orderDetail.close_time > 0">关闭时间{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
<template v-if="orderDetail.pay_status > 0">
<li>支付方式{{ orderDetail.pay_type_name }}</li>
<li>支付时间{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
</template>
<li v-if="orderDetail.promotion_type_name != ''">店铺活动{{ orderDetail.promotion_type_name }}</li>
<li v-if="orderDetail.buyer_message != ''">买家留言{{ orderDetail.buyer_message }}</li>
</ul>
</div>
<div class="order-info" v-if="orderDetail.pay_type=='offlinepay'&&orderDetail.offline_pay_info">
<h4>线下支付</h4>
<ul>
<li v-if="orderDetail.offline_pay_info.status_info.const=='WAIT_AUDIT'">
支付状态审核中
</li>
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
支付状态审核被拒
</li>
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
审核备注{{orderDetail.offline_pay_info.audit_remark}}
</li>
</ul>
</div>
<div class="take-delivery-info">
<h4>收货信息</h4>
<ul>
<li>收货人{{ orderDetail.name }}</li>
<li>手机号码{{ orderDetail.mobile }}</li>
<li>收货地址{{ orderDetail.full_address }} {{ orderDetail.address }}</li>
</ul>
</div>
<!-- 订单项·商品 -->
<div class="list">
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
</div>
<div class="info-wrap">
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
</li>
<li>
<span>{{ goodsItem.price }}</span>
</li>
<li>
<span>{{ goodsItem.num }}</span>
</li>
<li>
<span>{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
</li>
<li v-if="orderDetail.is_enable_refund">
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status == 0 || goodsItem.refund_status == -1" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id } })">退款</el-button>
<el-button type="primary" plain size="mini" v-else @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">查看退款</el-button>
</li>
</ul>
</div>
<!-- 订单总计 -->
<ul class="total">
<li>
<label>商品金额</label>
<span>{{ orderDetail.goods_money }}</span>
</li>
<li>
<label>运费</label>
<span>{{ orderDetail.delivery_money }}</span>
</li>
<li v-if="orderDetail.member_card_money > 0">
<label>会员卡</label>
<span>{{ orderDetail.member_card_money }}</span>
</li>
<li v-if="orderDetail.invoice_money > 0">
<label>税费</label>
<span>{{ orderDetail.invoice_money }}</span>
</li>
<li v-if="orderDetail.invoice_delivery_money > 0">
<label>发票邮寄费</label>
<span>{{ orderDetail.invoice_delivery_money }}</span>
</li>
<li v-if="orderDetail.adjust_money != 0">
<label>订单调整</label>
<span>
<template v-if="orderDetail.adjust_money < 0">-</template>
<template v-else>+</template>
{{ orderDetail.adjust_money | abs }}
</span>
</li>
<li v-if="orderDetail.promotion_money > 0">
<label>优惠</label>
<span>{{ orderDetail.promotion_money }}</span>
</li>
<li v-if="orderDetail.coupon_money > 0">
<label>优惠券</label>
<span>{{ orderDetail.coupon_money }}</span>
</li>
<li v-if="orderDetail.balance_money > 0">
<label>使用余额</label>
<span>{{ orderDetail.balance_money }}</span>
</li>
<li v-if="orderDetail.point_money > 0">
<label>积分抵扣</label>
<span>{{ orderDetail.point_money }}</span>
</li>
<li class="pay-money">
<label>实付款</label>
<span>{{ orderDetail.pay_money }}</span>
</li>
</ul>
</template>
</div>
</el-card>
</div>
</template>
<script>
import {
apiOrderDetail
} from '@/api/order/order';
import orderMethod from '@/utils/orderMethod';
import {
mapGetters
} from 'vuex';
export default {
name: 'order_detail_pickup',
components: {},
mixins: [orderMethod],
data: () => {
return {
orderId: 0,
orderDetail: null,
loading: true,
yes: true
};
},
created() {
this.orderId = this.$route.query.order_id;
this.getOrderDetail();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
layout: 'member',
methods: {
getOrderDetail() {
apiOrderDetail({
order_id: this.orderId
}).then(res => {
if (res.code >= 0) {
this.orderDetail = res.data;
if (this.orderDetail.delivery_store_info != '') this.orderDetail.delivery_store_info = JSON.parse(this.orderDetail
.delivery_store_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'
});
}
});
});
},
operation(action) {
switch (action) {
case 'orderPay': // 支付
this.orderPay(this.orderDetail);
break;
case 'orderClose': //关闭
this.orderClose(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'memberTakeDelivery': //收货
this.orderDelivery(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'trace': //查看物流
this.$router.push({
path: '/order/logistics',
query: {
order_id: this.orderDetail.order_id
}
});
break;
case 'memberOrderEvaluation': //评价
this.$router.push({
path: '/order/evaluate',
query: {
order_id: this.orderDetail.order_id
}
});
break;
case 'memberBatchRefund': //批量退款
this.$router.push({
path: '/order/batchrefund',
query: {
order_id: this.orderId
}
});
break;
case 'orderOfflinePay': //线下支付
this.$router.push({
path: '/pay',
query: {
code: this.orderDetail.offline_pay_info.out_trade_no
}
});
break;
}
},
imageError(index) {
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
}
},
filters: {
abs(value) {
return Math.abs(parseFloat(value)).toFixed(2);
}
}
};
</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-detail {
.order-status {
background-color: #fff;
margin-bottom: 20px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
.go-pay {
p {
display: inline-block;
vertical-align: middle;
span {
font-weight: bold;
color: $base-color;
font-size: 18px;
}
}
}
.operation {
margin-top: 10px;
}
}
.order-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
.take-delivery-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
.pickup-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
img {
width: 100px;
}
}
nav {
overflow: hidden;
padding: 10px 0;
background: #fff;
border-bottom: 1px solid #eeeeee;
li {
float: left;
&:nth-child(1) {
width: 50%;
&.no-operation {
width: 60%;
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
.list {
border-bottom: 1px solid #eeeeee;
.item {
background-color: #fff;
padding: 10px 0;
overflow: hidden;
li {
float: left;
line-height: 60px;
&:nth-child(1) {
width: 50%;
line-height: inherit;
&.no-operation {
width: 60%;
}
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
cursor: pointer;
h5 {
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: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
}
// 总计
.total {
padding: 20px;
background-color: #fff;
text-align: right;
li {
span {
width: 150px;
display: inline-block;
}
&.pay-money {
font-weight: bold;
span {
color: $base-color;
font-size: 16px;
vertical-align: middle;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,622 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card order-detail">
<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">
<template v-if="orderDetail">
<div class="order-status">
<h4 style="position: relative;">
订单状态
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
<div class="edit-time" v-if="orderDetail.order_status == 0">
<img src="../../assets/images/order_time.png" style="width: 15px;height: 15px;margin-right: 6px;" />距离订单自动关闭剩余
<count-down
style="color: #f00;margin-left: 10px;"
class="count-down"
v-on:start_callback="countDownS_cb()"
v-on:end_callback="countDownE_cb()"
:currentTime="orderDetail.currentTime"
:startTime="orderDetail.startTime"
:endTime="orderDetail.endTime"
:dayTxt="':'"
:hourTxt="':'"
:minutesTxt="':'"
:secondsTxt="''"
></count-down>
</div>
</h4>
<div v-if="orderDetail.order_status == 0" class="go-pay">
<p>
需付款
<span>{{ orderDetail.pay_money }}</span>
</p>
</div>
<div class="operation" v-if="orderDetail.action.length > 0">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">{{ operationItem.title }}</el-button>
</div>
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
<template v-if="orderDetail.evaluate_status == 0">评价</template>
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
</el-button>
</div>
</div>
<div class="verify-code-wrap" v-if="orderDetail.virtual_goods">
<template v-if="orderDetail.goods_class == 2">
<h4>核销码</h4>
<div class="virtual-code">
<img :src="$img(orderDetail.virtualgoods)" />
<div class="tips">请将二维码出示给核销员</div>
<div>核销码{{ orderDetail.virtual_code }}</div>
</div>
<h4>核销信息</h4>
<ul>
<li>核销次数剩余{{ orderDetail.virtual_goods.total_verify_num - orderDetail.virtual_goods.verify_num }}/{{ orderDetail.virtual_goods.total_verify_num }}</li>
<li>有效期
<span v-if="orderDetail.virtual_goods.expire_time > 0"> {{ $util.timeStampTurnTime(orderDetail.virtual_goods.expire_time) }}</span>
<span v-else>永久有效</span>
</li>
</ul>
<template v-if="orderDetail.virtual_goods.verify_record.length">
<h4>核销记录</h4>
<ul v-for="(item, index) in orderDetail.virtual_goods.verify_record" :key="index">
<li>核销人{{ item.verifier_name }}</li>
<li>核销时间{{ $util.timeStampTurnTime(item.verify_time) }}</li>
</ul>
</template>
</template>
<template v-if="orderDetail.goods_class == 3">
<h4>卡密信息</h4>
<ul v-for="(item, index) in orderDetail.virtual_goods" :key="index">
<li>
<span>卡号{{ item.card_info.cardno }}</span>
</li>
<li>
<span>密码{{ item.card_info.password }}</span>
</li>
</ul>
</template>
<!-- <h4>核销信息</h4>
<ul>
<li>
核销码
<span class="ns-text-color">{{ orderDetail.virtual_code }}</span>
</li>
<template v-if="orderDetail.virtual_goods.is_veirfy">
<li>核销状态已核销</li>
<li>核销时间{{ $util.timeStampTurnTime(orderDetail.virtual_goods.verify_time) }}</li>
</template>
</ul>
<img :src="$img(orderDetail.virtualgoods)" /> -->
</div>
<div class="order-info">
<h4>订单信息</h4>
<ul>
<!-- <li>
<i class="iconfont iconmendian"></i>
店铺
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
</li> -->
<li>订单类型{{ orderDetail.order_type_name }}</li>
<li>订单编号{{ orderDetail.order_no }}</li>
<li>订单交易号{{ orderDetail.out_trade_no }}</li>
<li>创建时间{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
<li v-if="orderDetail.close_time > 0">关闭时间{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
<template v-if="orderDetail.pay_status > 0">
<li>支付方式{{ orderDetail.pay_type_name }}</li>
<li>支付时间{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
</template>
<li v-if="orderDetail.promotion_type_name != ''">店铺活动{{ orderDetail.promotion_type_name }}</li>
<li v-if="orderDetail.buyer_message != ''">买家留言{{ orderDetail.buyer_message }}</li>
</ul>
</div>
<div class="order-info" v-if="orderDetail.pay_type=='offlinepay'&&orderDetail.offline_pay_info">
<h4>线下支付</h4>
<ul>
<li v-if="orderDetail.offline_pay_info.status_info.const=='WAIT_AUDIT'">
支付状态审核中
</li>
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
支付状态审核被拒
</li>
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
审核备注{{orderDetail.offline_pay_info.audit_remark}}
</li>
</ul>
</div>
<!-- 发票信息 -->
<div class="take-delivery-info" v-if="orderDetail.is_invoice ==1">
<h4>发票信息</h4>
<ul>
<li>发票类型{{ orderDetail.invoice_type == 1 ? '纸质发票' : '电子发票' }}</li>
<li>发票抬头类型{{ orderDetail.invoice_title_type ==1 ? '个人' : '企业' }}</li>
<li>发票抬头{{ orderDetail.invoice_title }}</li>
<li>发票内容{{ orderDetail.invoice_content }}</li>
<li v-if="orderDetail.invoice_type == 1">发票邮寄地址地址{{ orderDetail.invoice_full_address }}</li>
<li v-else>发票接收邮箱{{ orderDetail.invoice_email }}</li>
</ul>
</div>
<nav>
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
<li>单价</li>
<li>数量</li>
<li>小计</li>
<li v-if="orderDetail.is_enable_refund">操作</li>
</nav>
<!-- 订单项·商品 -->
<div class="list">
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
</div>
<div class="info-wrap">
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
</li>
<li>
<span>{{ goodsItem.price }}</span>
</li>
<li>
<span>{{ goodsItem.num }}</span>
</li>
<li>
<span>{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
</li>
<li v-if="orderDetail.is_enable_refund">
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status == 0 || goodsItem.refund_status == -1" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id } })">退款</el-button>
<el-button type="primary" plain size="mini" v-else @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">查看退款</el-button>
</li>
</ul>
</div>
<!-- 订单总计 -->
<ul class="total">
<li>
<label>商品金额</label>
<span>{{ orderDetail.goods_money }}</span>
</li>
<li v-if="orderDetail.member_card_money > 0">
<label>会员卡</label>
<span>{{ orderDetail.member_card_money }}</span>
</li>
<li v-if="orderDetail.invoice_money > 0">
<label>税费</label>
<span>{{ orderDetail.invoice_money }}</span>
</li>
<li v-if="orderDetail.invoice_delivery_money > 0">
<label>发票邮寄费</label>
<span>{{ orderDetail.invoice_delivery_money }}</span>
</li>
<li v-if="orderDetail.adjust_money != 0">
<label>订单调整</label>
<span>
<template v-if="orderDetail.adjust_money < 0">-</template>
<template v-else>+</template>
{{ orderDetail.adjust_money | abs }}
</span>
</li>
<li v-if="orderDetail.promotion_money > 0">
<label>优惠</label>
<span>{{ orderDetail.promotion_money }}</span>
</li>
<li v-if="orderDetail.coupon_money > 0">
<label>优惠券</label>
<span>{{ orderDetail.coupon_money }}</span>
</li>
<li v-if="orderDetail.point_money > 0">
<label>积分抵扣</label>
<span>{{ orderDetail.point_money }}</span>
</li>
<li v-if="orderDetail.balance_money > 0">
<label>使用余额</label>
<span>{{ orderDetail.balance_money }}</span>
</li>
<li class="pay-money">
<label>实付款</label>
<span>{{ orderDetail.pay_money }}</span>
</li>
</ul>
</template>
</div>
</el-card>
</div>
</template>
<script>
import {apiOrderDetail} from '@/api/order/order';
import orderMethod from '@/utils/orderMethod';
import {mapGetters} from 'vuex';
import CountDown from "vue2-countdown"
export default {
name: 'order_detail_virtual',
components: {
CountDown
},
mixins: [orderMethod],
data: () => {
return {
orderId: 0,
orderDetail: null,
loading: true,
yes: true
};
},
created() {
this.orderId = this.$route.query.order_id;
this.getOrderDetail();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['token', 'defaultGoodsImage'])
},
layout: 'member',
methods: {
countDownS_cb() {
},
countDownE_cb() {
},
getOrderDetail() {
apiOrderDetail({
order_id: this.orderId
}).then(res => {
if (res.code >= 0) {
let date = (Date.parse(new Date())) / 1000;
res.data.currentTime = date
res.data.startTime = date
res.data.endTime = res.data.create_time + res.data.auto_close
this.orderDetail = res.data;
if (this.orderDetail.delivery_store_info != '') this.orderDetail.delivery_store_info = JSON.parse(this.orderDetail.delivery_store_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'});
}
});
});
},
operation(action) {
switch (action) {
case 'orderPay': // 支付
this.orderPay(this.orderDetail);
break;
case 'orderClose': //关闭
this.orderClose(this.orderDetail.order_id, () => {
this.getOrderDetail();
});
break;
case 'memberOrderEvaluation': //评价
this.$util.pushToTab({path: '/order/evaluate', query: {order_id: this.orderDetail.order_id}});
break;
case 'orderOfflinePay': //线下支付
this.$router.push({
path: '/pay',
query: {
code: this.orderDetail.offline_pay_info.out_trade_no
}
});
break;
}
},
imageError(index) {
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
}
},
filters: {
abs(value) {
return Math.abs(parseFloat(value)).toFixed(2);
}
}
};
</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-detail {
.order-status {
background-color: #fff;
margin-bottom: 20px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
.edit-time {
position: absolute;
left: 160px;
top: 2px;
display: flex;
align-items: center;
font-size: 10px;
}
}
.go-pay {
p {
display: inline-block;
vertical-align: middle;
span {
font-weight: bold;
color: $base-color;
font-size: 18px;
}
}
}
.operation {
margin-top: 10px;
}
}
.order-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
.verify-code-wrap {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
}
}
img {
width: 100px;
}
.virtual-code {
text-align: center;
.tips {
color: #999;
font-size: 12px;
margin-top: 5px;
}
}
}
nav {
overflow: hidden;
padding: 10px 0;
background: #fff;
border-bottom: 1px solid #eeeeee;
li {
float: left;
&:nth-child(1) {
width: 50%;
&.no-operation {
width: 60%;
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
.list {
border-bottom: 1px solid #eeeeee;
.item {
background-color: #fff;
padding: 10px 0;
overflow: hidden;
li {
float: left;
line-height: 60px;
&:nth-child(1) {
width: 50%;
line-height: inherit;
&.no-operation {
width: 60%;
}
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
h5 {
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;
cursor: pointer;
&:hover {
color: $base-color;
}
}
span {
font-size: $ns-font-size-sm;
color: #9a9a9a;
}
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 10%;
}
}
}
}
// 总计
.total {
padding: 20px;
background-color: #fff;
text-align: right;
li {
span {
width: 150px;
display: inline-block;
}
&.pay-money {
font-weight: bold;
span {
color: $base-color;
font-size: 16px;
vertical-align: middle;
}
}
}
}
}
.take-delivery-info {
background-color: #fff;
margin-bottom: 10px;
h4 {
margin: 10px 0 20px;
border-bottom: 1px solid #eeeeee;
padding-bottom: 10px;
}
ul {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 33.3333%;
margin-bottom: 10px;
&:last-child {
flex: initial;
}
}
}
}
</style>

View File

@@ -0,0 +1,461 @@
<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>
<el-tabs v-model="orderStatus" @tab-click="handleClick">
<el-tab-pane label="全部订单" name="all"></el-tab-pane>
<el-tab-pane label="待付款" name="waitpay"></el-tab-pane>
<el-tab-pane label="待发货" name="waitsend"></el-tab-pane>
<el-tab-pane label="待收货" name="waitconfirm"></el-tab-pane>
<el-tab-pane label="待评价" name="waitrate"></el-tab-pane>
</el-tabs>
<div v-loading="loading">
<nav>
<li>商品信息</li>
<li>单价</li>
<li>数量</li>
<li>实付款</li>
<li>订单状态</li>
<li>操作</li>
</nav>
<div class="list" v-if="orderList.length > 0">
<div class="item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
<div class="head">
<span class="create-time">{{ $util.timeStampTurnTime(orderItem.create_time) }}</span>
<span class="order-no">订单号{{ orderItem.order_no }}</span>
<!-- <router-link :to="'/shop-' + orderItem.site_id" target="_blank">{{ orderItem.site_name }}</router-link> -->
<span class="order-type">{{ orderItem.order_type_name }}</span>
</div>
<ul v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
<li>
<div class="img-wrap" @click="$router.push('/sku/' + goodsItem.sku_id)">
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(orderIndex, goodsIndex)" />
</div>
<div class="info-wrap" @click="$router.push('/sku/' + goodsItem.sku_id)">
<h5>{{ goodsItem.sku_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
<div class="order-time" v-if="orderItem.order_status == 0">
<img src="../../assets/images/order_time.png" style="width: 15px;height: 15px;margin-right: 6px;" />距离订单自动关闭剩余
<count-down style="color: #f00;margin-left: 10px;" class="count-down"
v-on:start_callback="countDownS_cb()" v-on:end_callback="countDownE_cb()"
:currentTime="orderItem.currentTime" :startTime="orderItem.startTime"
:endTime="orderItem.endTime"
:dayTxt="':'" :hourTxt="':'" :minutesTxt="':'" :secondsTxt="''"></count-down>
</div>
</li>
<li>
<span>{{ goodsItem.price }}</span>
</li>
<li>
<span>{{ goodsItem.num }}</span>
</li>
<li>
<span>{{ orderItem.pay_money }}</span>
</li>
<template v-if="goodsIndex == 0">
<li>
<span class="ns-text-color">{{ orderItem.order_status_name }}</span>
<el-link :underline="false" @click="orderDetail(orderItem)">订单详情</el-link>
</li>
<li>
<template v-if="orderItem.action.length > 0">
<el-button type="primary" size="mini" plain v-if="orderItem.is_evaluate == 1" @click="operation('memberOrderEvaluation', orderItem)">
<template v-if="orderItem.evaluate_status == 0">评价</template>
<template v-else-if="orderItem.evaluate_status == 1">追评</template>
</el-button>
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderItem.action" :key="operationIndex" @click="operation(operationItem.action, orderItem)">
{{ operationItem.title }}
</el-button>
</template>
<template class="order-operation" v-else-if="orderItem.action.length == 0 && orderItem.is_evaluate == 1">
<el-button type="primary" size="mini" plain v-if="orderItem.is_evaluate == 1" @click="operation('memberOrderEvaluation', orderItem)">
<template v-if="orderItem.evaluate_status == 0">评价</template>
<template v-else-if="orderItem.evaluate_status == 1">追评</template>
</el-button>
</template>
</li>
</template>
</ul>
</div>
</div>
<div v-else-if="!loading && orderList.length == 0" class="empty-wrap">暂无相关订单</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 {
apiOrderList
} from '@/api/order/order';
import orderMethod from '@/utils/orderMethod';
import CountDown from "vue2-countdown"
export default {
name: 'order_list',
components: {
CountDown
},
layout: 'member',
data: () => {
return {
orderStatus: 'all',
loading: true,
orderList: [],
currentPage: 1,
pageSize: 10,
total: 0,
yes: true
};
},
mixins: [orderMethod],
created() {
this.orderStatus = this.$route.query.status || 'all';
this.getOrderList();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
countDownS_cb() {
},
countDownE_cb() {
},
handleClick(tab, event) {
this.currentPage = 1;
this.orderStatus = tab.name;
this.refresh();
},
getOrderList() {
apiOrderList({
page: this.currentPage,
page_size: this.pageSize,
order_status: this.orderStatus
}).then(res => {
let list = [];
let auto_close = 0
if (res.code == 0 && res.data) {
auto_close = res.data.auto_close
let date = (Date.parse(new Date())) / 1000
for (let i = 0; i < res.data.list.length; i++) {
res.data.list[i].currentTime = date
res.data.list[i].startTime = date
res.data.list[i].endTime = res.data.list[i].create_time + auto_close
}
list = res.data.list;
this.total = res.data.count;
}
this.orderList = list;
this.loading = false;
}).catch(res => {
this.loading = false;
});
},
handlePageSizeChange(size) {
this.pageSize = size;
this.refresh();
},
handleCurrentPageChange(page) {
this.currentPage = page;
this.refresh();
},
refresh() {
this.loading = true;
this.getOrderList();
},
operation(action, orderData) {
let index = this.status;
switch (action) {
case 'orderPay': // 支付
this.orderPay(orderData);
break;
case 'orderClose': //关闭
this.orderClose(orderData.order_id, () => {
this.refresh();
});
break;
case 'memberTakeDelivery': //收货
this.orderDelivery(orderData.order_id, () => {
this.refresh();
});
break;
case 'trace': //查看物流
this.$router.push({
path: '/order/logistics',
query: {
order_id: orderData.order_id
}
});
break;
case 'memberOrderEvaluation': //评价
this.$router.push({
path: '/order/evaluate',
query: {
order_id: orderData.order_id
}
});
break;
case 'memberVirtualTakeDelivery': // 虚拟商品 确认使用
this.orderVirtualDelivery(orderData.order_id, () => {
this.refresh();
});
break;
case 'orderOfflinePay': //线下支付
this.$router.push({
path: '/pay',
query: {
code: orderData.offline_pay_info.out_trade_no
}
});
break;
case 'orderDelete':
this.orderDelete(orderData.order_id, () => {
this.refresh();
});
break;
}
},
orderDetail(data) {
switch (parseInt(data.order_type)) {
case 2:
// 自提订单
this.$router.push({
path: '/member/order_detail_pickup',
query: {
order_id: data.order_id
}
});
break;
case 3:
// 本地配送订单
this.$router.push({
path: '/member/order_detail_local_delivery',
query: {
order_id: data.order_id
}
});
break;
case 4:
// 虚拟订单
this.$router.push({
path: '/member/order_detail_virtual',
query: {
order_id: data.order_id
}
});
break;
default:
this.$router.push({
path: '/member/order_detail',
query: {
order_id: data.order_id
}
});
break;
}
},
imageError(orderIndex, goodsIndex) {
this.orderList[orderIndex].order_goods[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;
}
.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: 45%;
}
&:nth-child(2) {
width: 10%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 10%;
}
&:nth-child(5) {
width: 15%;
}
&:nth-child(6) {
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;
}
}
.order-time {
display: flex;
align-items: center;
font-size: 10px;
}
}
ul {
background-color: #fff;
padding: 10px;
overflow: hidden;
li {
float: left;
line-height: 60px;
&:nth-child(1) {
width: 45%;
line-height: inherit;
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info-wrap {
margin-left: 70px;
h5 {
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;
cursor: pointer;
&:hover {
color: $base-color;
}
}
span {
font-size: $ns-font-size-sm;
color: #9a9a9a;
}
}
}
&:nth-child(2) {
width: 10%;
}
&:nth-child(3) {
width: 10%;
}
&:nth-child(4) {
width: 10%;
}
&:nth-child(5) {
width: 15%;
line-height: 30px;
a {
display: block;
}
}
&:nth-child(6) {
width: 10%;
line-height: initial;
button {
margin-left: 0;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
}
}
}
}
.empty-wrap {
text-align: center;
padding: 10px;
}
}
</style>

View File

@@ -0,0 +1,164 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card recharge-detail-wrap">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/member/recharge_list' }">充值套餐列表</el-breadcrumb-item>
<el-breadcrumb-item>充值套餐详情</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="recharge-detail" v-loading="loading">
<el-image :src="$img(rechargeInfo.cover_img)" fit="contain"></el-image>
<p class="recharge-money">
<span class="buy-price">{{ rechargeInfo.buy_price }}</span>
<span class="face-price">{{ rechargeInfo.face_value }}</span>
</p>
<p class="recharge-name">{{ rechargeInfo.recharge_name }}</p>
<p class="recharge-point">额外赠送{{ rechargeInfo.point }}积分</p>
<p class="recharge-growth">额外赠送{{ rechargeInfo.growth }}成长值</p>
<div class="recharge-btn">
<el-button @click="recharge">立即充值</el-button>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {rechargeDetail, recharge} from "@/api/member/account"
import {mapGetters} from 'vuex';
export default {
name: "recharge-detail",
layout: "member",
components: {},
data: () => {
return {
id: '',
rechargeInfo: {},
loading: true,
isSub: false,
yes: true
}
},
created() {
this.id = this.$route.query.id;
this.getRechargeInfo();
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
//获取详情
getRechargeInfo() {
rechargeDetail({
recharge_id: this.id
}).then(res => {
if (res.code == 0 && res.data) {
this.rechargeInfo = res.data;
if (res.data.cover_img == '') {
this.rechargeInfo.cover_img = this.defaultGoodsImage;
}
} else {
this.$message.warning(res.message)
}
this.loading = false
}).catch(err => {
this.loading = false
})
},
recharge() {
if (this.isSub) return
this.isSub = true
recharge({
recharge_id: this.id
}).then(res => {
if (res.data && res.code == 0) {
this.$router.push({path: '/pay', query: {code: res.data}});
} else {
this.$message.warning(res.message)
}
this.isSub = false
}).catch(err => {
this.isSub = false
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;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.recharge-detail-wrap {
}
.recharge-detail {
width: 300px;
.recharge-money {
.buy-price {
font-size: 25px;
color: $base-color;
font-weight: 600;
margin-right: 10px;
}
.face-price {
text-decoration: line-through;
color: #898989;
}
}
.recharge-name {
margin: 10px 0;
font-size: 16px;
}
.recharge-btn {
margin-top: 30px;
text-align: center;
.el-button {
width: 300px;
background-color: $base-color;
color: #FFFFFF;
}
}
}
</style>

View File

@@ -0,0 +1,291 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
<el-breadcrumb-item>充值套餐列表</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="recharge-wrap" v-loading="loading">
<div class="account-wrap">
<div class="account-left">
<div class="title">我的可用余额()</div>
<div class="money">
<div class="balance-money">
<b>{{ integer }}</b>
<span>.{{ decimal }}</span>
</div>
<div class="tx" @click="rechargeOrder">充值记录</div>
</div>
</div>
<div class="account-right">
<div class="item-wrap">
<div class="item">
<div class="iconfont icon-ziyuan"></div>
<div class="title">可提现余额:</div>
<b class="num">{{ balanceInfo.balance_money }}</b>
</div>
<div class="item">
<div class="iconfont icon-ziyuan"></div>
<div class="title">不可提现余额:</div>
<b class="num">{{ balanceInfo.balance }}</b>
</div>
</div>
</div>
</div>
<div class="recharge-table">
<el-table :data="rechargeList" border>
<el-table-column label="套餐名称">
<template slot-scope="scope">
<div class="recharge-info">
<el-image :src="$img(scope.row.cover_img)" fit="contain" @error="imageError(scope.$index)"></el-image>
<p :title="scope.row.recharge_name">{{ scope.row.recharge_name }}</p>
</div>
</template>
</el-table-column>
<el-table-column label="面值" width="150">
<template slot-scope="scope">
<div>价格{{ scope.row.face_value }}</div>
<div>充值面额{{ scope.row.buy_price }}</div>
</template>
</el-table-column>
<el-table-column prop="point" label="赠送积分" width="150"></el-table-column>
<el-table-column prop="growth" label="赠送成长值" width="150"></el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button size="mini" @click="handleDetail(scope.$index, scope.row)">充值</el-button>
</template>
</el-table-column>
</el-table>
<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>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {balance, rechargeList} from "@/api/member/account"
import {mapGetters} from 'vuex';
export default {
name: "recharge_list",
layout: "member",
components: {},
data: () => {
return {
balanceInfo: {
balance: 0,
balance_money: 0
},
integer: 0,
decimal: 0,
rechargeList: [],
total: 0,
currentPage: 1,
pageSize: 10,
loading: true,
yes: true
}
},
created() {
this.getUserInfo()
this.getData()
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
methods: {
handlePageSizeChange(size) {
this.pageSize = size
this.refresh()
},
handleCurrentPageChange(page) {
this.currentPage = page
this.refresh()
},
refresh() {
this.loading = true
this.getData()
},
/**
* 获取余额信息
*/
getUserInfo() {
balance({
account_type: 'balance,balance_money'
}).then(res => {
if (res.code == 0 && res.data) {
this.balanceInfo = res.data
const price = (parseFloat(this.balanceInfo.balance) + parseFloat(this.balanceInfo.balance_money)).toFixed(2)
let priceSplit = price.split(".")
this.integer = priceSplit[0]
this.decimal = priceSplit[1]
} else {
this.$message.warning(res.message)
}
}).catch(err => {
this.$message.error(err.message)
})
},
/**
* 获取充值套餐列表
*/
getData() {
rechargeList({
page: this.currentPage,
page_size: this.pageSize
}).then(res => {
if (res.code == 0 && res.data.list) {
this.rechargeList = res.data.list
this.total = res.data.count
} else {
this.$message.warning(res.message)
}
this.loading = false
}).catch(err => {
this.loading = false
this.$message.error(err.message)
})
},
imageError(index) {
this.rechargeList[index].cover_img = this.defaultGoodsImage;
},
handleDetail(index, row) {
this.$router.push({path: '/member/recharge_detail', query: {id: row.recharge_id}})
},
rechargeOrder() {
this.$router.push('/member/recharge_order')
}
}
}
</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;
}
.account-wrap {
display: flex;
margin-bottom: 10px;
.account-left {
flex: 1;
.title {
font-size: $ns-font-size-base;
font-weight: 600;
}
.money {
display: flex;
.balance-money {
b {
font-size: 30px;
}
span {
font-weight: 600;
}
}
.tx {
color: $base-color;
margin-left: 5px;
margin-top: 20px;
cursor: pointer;
}
}
}
.account-right {
flex: 1;
font-size: $ns-font-size-base;
display: flex;
align-items: center;
.item {
display: flex;
align-items: center;
.title {
margin-left: 3px;
}
.num {
margin-left: 3px;
}
}
}
}
.recharge-table {
.recharge-info {
display: flex;
align-items: center;
.el-image {
width: 60px;
height: 60px;
margin-right: 10px;
flex-shrink: 0;
}
p {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
}
</style>

View File

@@ -0,0 +1,294 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/member/recharge_list' }">充值套餐列表</el-breadcrumb-item>
<el-breadcrumb-item>充值记录</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div v-loading="loading">
<div class="order-list">
<nav>
<li>套餐名称</li>
<li>面值</li>
<li>购买价格</li>
<li>赠送积分</li>
<li>赠送成长值</li>
</nav>
<div class="list" v-if="orderList.length > 0">
<div class="item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
<div class="head">
<span class="create-time">{{ $util.timeStampTurnTime(orderItem.create_time) }}</span>
<span class="order-no">订单号{{ orderItem.order_no }}</span>
</div>
<ul>
<li>
<div class="img-wrap">
<el-image :src="$img(orderItem.cover_img)" fit="cover" @error="imageError(orderIndex)"></el-image>
</div>
<div class="info-wrap">
<h5 :title="orderItem.recharge_name">{{ orderItem.recharge_name }}</h5>
<!-- <span>规格规格值</span> -->
</div>
</li>
<li>
<span>{{ orderItem.face_value }}</span>
</li>
<li>
<span>{{ orderItem.buy_price }}</span>
</li>
<li>
<span>{{ orderItem.point }}</span>
</li>
<li>
<span>{{ orderItem.growth }}</span>
</li>
</ul>
</div>
</div>
<div v-else-if="!loading && orderList.length == 0" class="empty-wrap">暂无相关订单</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>
</div>
</el-card>
</div>
</template>
<script>
import {rechargeOrder} from "@/api/member/account"
import {mapGetters} from 'vuex';
export default {
name: "recharge_list",
layout: "member",
components: {},
data: () => {
return {
orderList: [],
total: 0,
currentPage: 1,
pageSize: 10,
loading: true,
yes: true
}
},
created() {
this.getListData()
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
computed: {
...mapGetters(['defaultGoodsImage'])
},
methods: {
handlePageSizeChange(size) {
this.pageSize = size
this.refresh()
},
handleCurrentPageChange(page) {
this.currentPage = page
this.refresh()
},
refresh() {
this.loading = true
this.getListData()
},
getListData() {
rechargeOrder({
page: this.currentPage,
page_size: this.pageSize
}).then(res => {
if (res.code == 0 && res.data) {
this.orderList = res.data.list;
} else {
this.$message.warning(res.message)
}
this.loading = false
}).catch(err => {
this.loading = false
})
},
imageError(index) {
this.orderList[index].cover_img = 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;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: unset;
}
.el-card {
border: 0;
}
.order-list {
nav {
overflow: hidden;
padding: 10px;
background: #fff;
margin-bottom: 10px;
border-bottom: 1px solid #eeeeee;
li {
float: left;
&:nth-child(1) {
width: 40%;
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 15%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 15%;
}
}
}
.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: 40%;
line-height: inherit;
.img-wrap {
width: 60px;
height: 60px;
float: left;
margin-right: 10px;
border-radius: 5px;
overflow: hidden;
.el-image {
width: 100%;
height: 100%;
}
}
.info-wrap {
margin-left: 70px;
h5 {
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;
}
}
}
&:nth-child(2) {
width: 15%;
}
&:nth-child(3) {
width: 15%;
}
&:nth-child(4) {
width: 15%;
}
&:nth-child(5) {
width: 15%;
}
}
}
}
.empty-wrap {
text-align: center;
padding: 10px;
}
}
</style>

View File

@@ -0,0 +1,322 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<div class="security" v-loading="loading">
<div class="item-wrap" v-if="type == 'all'">
<div class="item">
<div class="item-content">
<i class="iconfont icon-xiugaidenglumima"></i>
<div class="name-wrap">
<div class="name">登录密码</div>
<div class="info">互联网账号存在被盗风险建议您定期更改密码以保护账户安全</div>
</div>
</div>
<div class="btn">
<el-button type="primary" size="medium" @click="edit('password')">修改</el-button>
</div>
</div>
<!-- <div class="item">
<div class="item-content">
<i class="iconfont iconyouxiang1"></i>
<div class="name-wrap">
<div class="name">邮箱绑定</div>
<div class="info">验证后可用于快速找回登录密码及支付密码</div>
</div>
</div>
<div class="btn"><el-button type="primary" size="medium" @click="edit('email')">修改</el-button></div>
</div> -->
<div class="item">
<div class="item-content">
<i class="iconfont icon-shoujiyanzheng"></i>
<div class="name-wrap">
<div class="name">手机验证</div>
<div class="info">验证后可用于快速找回登录密码及支付密码接收账户余额变动提醒</div>
</div>
</div>
<div class="btn">
<el-button type="primary" size="medium" @click="edit('tell')">修改</el-button>
</div>
</div>
<!-- <div class="item">
<div class="item-content">
<i class="el-icon-lock"></i>
<div class="name-wrap">
<div class="name">支付密码</div>
<div class="content">互联网支付存在被盗风险建议您定期更改支付密码以保护账户安全</div>
</div>
</div>
<div class="btn"><el-button type="primary" size="medium" @click="edit('payPassWord')">修改</el-button></div>
</div> -->
</div>
<div class="edit" v-if="type == 'password'">
<div class="title">修改登录密码</div>
<div v-if="memberInfo.password">
<div class="pass-form">
<el-form :model="passWordForm" :rules="passWordRules" ref="passWordRef" label-width="100px">
<el-form-item label="原密码" prop="oldPass">
<el-input type="password" placeholder="当前密码" v-model="passWordForm.oldPass"></el-input>
</el-form-item>
<el-form-item label="新密码" prop="pass">
<el-input type="password" placeholder="新密码" v-model="passWordForm.pass"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="checkPass">
<el-input type="password" placeholder="请确认新密码" v-model="passWordForm.checkPass"></el-input>
</el-form-item>
</el-form>
</div>
<div class="btn">
<el-button type="primary" @click="save">保存</el-button>
<el-button @click="type = 'all'">取消</el-button>
</div>
</div>
<div v-else class="tell-pass">
<el-form :model="tellPassForm" :rules="tellPassRules" ref="tellPassRef" label-width="100px">
<el-form-item label="验证码" prop="code">
<el-input placeholder="请输入验证码" maxlength="4" v-model="tellPassForm.code">
<template slot="append">
<img :src="captcha.img" mode class="captcha" @click="getcaptcha" />
</template>
</el-input>
</el-form-item>
<el-form-item label="动态码" prop="tellPassDynacode">
<el-input placeholder="请输入动态码" v-model="tellPassForm.tellPassDynacode">
<template slot="append">
<el-button type="primary" @click="getTellPassCode">{{ tellPassForm.tellPassCodeText }}</el-button>
</template>
</el-input>
</el-form-item>
<p class="tell-code">点击获取动态码将会向您已绑定的手机号{{ memberInfo.mobile | mobile }}发送验证码</p>
<el-form-item label="新密码" prop="pass">
<el-input type="password" placeholder="新密码" v-model="tellPassForm.pass"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="checkPass">
<el-input type="password" placeholder="请确认新密码" v-model="tellPassForm.checkPass"></el-input>
</el-form-item>
</el-form>
<div class="btn">
<el-button type="primary" @click="tellPassSave">保存</el-button>
<el-button @click="type = 'all'">取消</el-button>
</div>
</div>
</div>
<div class="edit" v-if="type == 'email'">
<div class="title">绑定邮箱</div>
<div class="pass-form">
<el-form :model="emailForm" :rules="emailRules" ref="emailRef" label-width="100px">
<el-form-item label="当前邮箱" prop="email" v-if="emailForm.currEmail">
<p>{{ emailForm.currEmail }}</p>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input type="email" placeholder="请输入邮箱" v-model="emailForm.email"></el-input>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input placeholder="请输入验证码" maxlength="4" v-model="emailForm.code">
<template slot="append">
<img :src="captcha.img" mode class="captcha" @click="getcaptcha" />
</template>
</el-input>
</el-form-item>
<el-form-item label="动态码" prop="emailDynacode">
<el-input placeholder="请输入动态码" v-model="emailForm.emailDynacode">
<template slot="append">
<el-button type="primary" @click="getEmailCode">{{ emailForm.emailCodeText }}</el-button>
</template>
</el-input>
</el-form-item>
</el-form>
</div>
<div class="btn">
<el-button type="primary" @click="bindEmail">保存</el-button>
<el-button @click="type = 'all'">取消</el-button>
</div>
</div>
<div class="edit" v-if="type == 'tell'">
<div class="title">绑定手机号</div>
<div class="pass-form">
<el-form :model="tellForm" :rules="tellRules" ref="tellRef" label-width="100px">
<el-form-item label="当前手机号" prop="email" v-if="tellForm.currTell">
<p>{{ tellForm.currTell }}</p>
</el-form-item>
<el-form-item label="手机号" prop="tell">
<el-input type="tell" placeholder="请输入手机号" v-model="tellForm.tell"></el-input>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input placeholder="请输入验证码" maxlength="4" v-model="tellForm.code">
<template slot="append">
<img :src="captcha.img" mode class="captcha" @click="getcaptcha" />
</template>
</el-input>
</el-form-item>
<el-form-item label="动态码" prop="tellDynacode">
<el-input placeholder="请输入动态码" v-model="tellForm.tellDynacode">
<template slot="append">
<el-button type="primary" @click="gettellCode">{{ tellForm.tellCodeText }}</el-button>
</template>
</el-input>
</el-form-item>
</el-form>
</div>
<div class="btn">
<el-button type="primary" @click="bindtell">保存</el-button>
<el-button @click="type = 'all'">取消</el-button>
</div>
</div>
<div class="edit-pay" v-if="type == 'payPassWord'">
<div class="title">绑定支付密码</div>
<div class="container">
<div class="name" v-if="step != 0">请输入6位支付密码建议不要使用重复或连续数字</div>
<div class="name" v-else-if="isSend">验证码已发送至{{ tellForm.currTell | mobile }}</div>
<div class="password-wrap">
<el-input :maxlength="step == 0 ? 4 : 6" @change="input" ref="input" :auto-focus="true" v-model="payInput" :placeholder="palceText" v-if="step == 0"/>
<el-input :maxlength="step == 0 ? 4 : 6" @change="input" ref="input" :auto-focus="true" v-model="payInput" type="password" :placeholder="palceText" v-else />
<div v-show="step == 0" class="dynacode" @click="sendMobileCode">{{ payCodeText }}</div>
</div>
</div>
<div class="btn">
<el-button type="primary" @click="bindPayPwd" :disabled="isClick">保存</el-button>
<el-button @click="type = 'all'">取消</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import security from './security';
export default {
name: 'security',
layout: "member",
mixins: [security]
};
</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;
}
.security {
background: #ffffff;
.el-form {
margin: 0 30px;
.captcha {
vertical-align: top;
max-width: inherit;
width: 74px;
max-height: 38px;
line-height: 38px;
cursor: pointer;
}
}
.item {
border-bottom: 1px solid #f1f1ff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px;
.item-content {
display: flex;
align-items: center;
i {
font-size: 40px;
}
.name-wrap {
margin-left: 20px;
}
}
}
.edit {
padding: 20px;
.title {
padding-bottom: 5px;
font-size: $ns-font-size-base;
border-bottom: 1px solid #f1f1f1;
}
.pass-form {
margin-top: 20px;
display: flex;
justify-content: center;
.el-form {
width: 500px;
}
}
.btn {
display: flex;
justify-content: center;
}
}
.tell-pass {
margin-top: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.el-form {
width: 500px;
}
.tell-code {
margin-left: 66px;
margin-bottom: 20px;
}
}
.edit-pay {
padding: 20px;
text-align: center;
.title {
font-size: $ns-font-size-base;
border-bottom: 1px solid #f1f1f1;
text-align: left;
padding-bottom: 5px;
}
.dynacode {
cursor: pointer;
text-align: right;
margin-right: 329px;
color: $base-color;
margin-bottom: 20px;
}
.el-input {
width: 300px;
margin-top: 20px;
}
.btn {
margin-top: 20px;
}
.name {
margin-top: 10px;
}
}
}
</style>

View File

@@ -0,0 +1,600 @@
import {
passWord,
emailCode,
checkEmail,
email,
tellCode,
tell,
verifyPayPwdCode,
modifyPayPassword,
payPwdCode,
pwdMoblieCode
} from "@/api/member/security"
import {
info
} from "@/api/member/info"
import {
captcha
} from "@/api/website"
export default {
name: "security",
components: {},
data() {
var validatePass = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入新密码"))
} else if (value == this.passWordForm.oldPass) {
callback(new Error("新密码不能与原密码相同!"))
} else {
if (this.passWordForm.checkPass !== "") {
this.$refs.passWordRef.validateField("checkPass")
}
callback()
}
}
var validatePass2 = (rule, value, callback) => {
if (value === "") {
callback(new Error("请再次输入密码"))
} else if (value !== this.passWordForm.pass) {
callback(new Error("两次输入密码不一致!"))
} else {
callback()
}
}
var validateTellPass = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入新密码"))
} else if (value == this.tellPassForm.oldPass) {
callback(new Error("新密码不能与原密码相同!"))
} else {
if (this.tellPassForm.checkPass !== "") {
this.$refs.tellPassRef.validateField("checkPass")
}
callback()
}
}
var validateTellPass2 = (rule, value, callback) => {
if (value === "") {
callback(new Error("请再次输入密码"))
} else if (value !== this.tellPassForm.pass) {
callback(new Error("两次输入密码不一致!"))
} else {
callback()
}
}
var checkemail = (rules, value, callback) => {
const regEmail = /^\w+@\w+(\.\w+)+$/
if (regEmail.test(value)) {
return callback()
}
callback(new Error("请输入正确的的邮箱"))
}
var checkTell = (rules, value, callback) => {
const regMobile = /^1[3|4|5|6|7|8|9][0-9]{9}$/
if (regMobile.test(value)) {
return callback()
}
callback(new Error("请输入正确的手机号"))
}
return {
type: "all",
passWordForm: {
oldPass: "",
pass: "",
checkPass: ""
},
emailForm: {
email: "",
code: "", //邮箱验证码
emailDynacode: "", //邮箱动态验证码
emailCodeText: "",
key: "",
currEmail: ""
},
passWordRules: {
oldPass: [{
required: true,
message: "请输入原密码",
trigger: "blur"
}],
pass: [{
required: true,
validator: validatePass,
trigger: "blur"
}],
checkPass: [{
required: true,
validator: validatePass2,
trigger: "blur"
}]
},
emailRules: {
email: [{
required: true,
message: "请输入正确的邮箱",
trigger: "blur"
}, {
validator: checkemail,
trigger: "blur"
}],
code: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}],
emailDynacode: [{
required: true,
message: "请输入动态验证码",
trigger: "blur"
}]
},
captcha: {
id: "",
img: ""
},
seconds: 120,
timer: null,
isSend: false,
isMobileSend: false,
tellForm: {
tell: "",
code: "", //邮箱验证码
tellDynacode: "", //邮箱动态验证码
tellCodeText: "",
key: "",
currTell: ""
},
tellRules: {
tell: [{
required: true,
message: "请输入正确的手机号",
trigger: "blur"
}, {
validator: checkTell,
trigger: "blur"
}],
code: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}],
tellDynacode: [{
required: true,
message: "请输入动态验证码",
trigger: "blur"
}]
},
isClick: true,
payCodeText: '获取验证码',
step: 0,
payCode: '', // 动态码
payPassword: '', // 支付密码
payRepassword: '', // 重复支付密码
payKey: '', // 短信key
payInput: '',
palceText: '输入短信验证码',
memberInfo: {},
tellPassForm: {
code: "",
tellPassCodeText: "",
key: "",
tellPassDynacode: "",
pass: '',
checkPass: ''
},
tellPassRules: {
code: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}],
tellPassDynacode: [{
required: true,
message: "请输入动态验证码",
trigger: "blur"
}],
pass: [{
required: true,
validator: validateTellPass,
trigger: "blur"
}],
checkPass: [{
required: true,
validator: validateTellPass2,
trigger: "blur"
}]
},
loading: true,
yes: true
}
},
created() {
this.getcaptcha()
this.seconds = 120
this.tellForm.tellCodeText = "获取动态码"
this.emailForm.emailCodeText = "获取动态码"
this.tellPassForm.tellPassCodeText = "获取动态码"
this.isSend = false
this.isMobileSend = false
clearInterval(this.timer)
this.getInfo()
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
//获取个人信息
async getInfo() {
await info().then(res => {
if (res.code == 0) {
this.memberInfo = res.data
this.emailForm.currEmail = res.data.email
this.tellForm.currTell = res.data.mobile
}
this.loading = false
}).catch(err => {
this.loading = false
this.$message.error(err.message)
})
},
async edit(type) {
await this.getInfo()
if (type == 'payPassWord') {
if (!this.tellForm.currTell) {
this.$confirm("你还未绑定手机号,请先绑定手机号?", "提示信息", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(res => {
if (res = 'confirm') {
this.type = 'tell'
} else {
this.type = 'all'
}
})
} else {
this.type = type
}
} else {
this.type = type
}
},
//获取验证码
getcaptcha() {
captcha({
captcha_id: this.captcha.id
}).then(res => {
if (res.code >= 0) {
this.captcha = res.data
this.captcha.img = this.captcha.img.replace(/\r\n/g, "")
}
}).catch(err => {
this.$message.error(err.message)
})
},
//修改密码
save() {
this.$refs.passWordRef.validate(valid => {
if (valid) {
passWord({
new_password: this.passWordForm.pass,
old_password: this.passWordForm.oldPass
}).then(res => {
this.$message({
message: "修改密码成功",
type: "success"
});
this.type = "all";
this.$store.dispatch("member/member_detail", {
refresh: 1
});
this.passWordForm.pass = "";
this.passWordForm.oldPass = "";
this.passWordForm.checkPass = "";
}).catch(err => {
this.$message.error(err.message)
})
} else {
return false
}
})
},
// 检测邮箱是否存在
async getCheckEmail() {
let result = await checkEmail({
email: this.emailForm.email
}).then(res => {
if (res.code != 0) {
this.$message({
message: res.message,
type: "success"
});
return false
}
return true
}).catch(err => {
this.$message.error(err.message)
});
return result
},
//绑定邮箱
async bindEmail() {
this.$refs.emailRef.validate(valid => {
if (valid) {
email({
email: this.emailForm.email,
captcha_id: this.captcha.id,
captcha_code: this.emailForm.code,
code: this.emailForm.emailDynacode,
key: this.emailForm.key
}).then(res => {
if (res.code == 0) {
this.$message({
message: "邮箱绑定成功",
type: "success"
});
this.type = "all";
this.emailForm.email = "";
this.emailForm.code = "";
this.emailForm.emailDynacode = "";
clearInterval(this.timer);
this.getcaptcha()
}
}).catch(err => {
this.getcaptcha();
this.$message.error(err.message)
})
} else {
return false
}
})
},
//获取手机验证码
async gettellCode() {
if (!this.isMobileSend) {
this.isMobileSend = true;
await tellCode({
mobile: this.tellForm.tell,
captcha_id: this.captcha.id,
captcha_code: this.tellForm.code
}).then(res => {
let data = res.data;
if (data.key) {
if (this.seconds == 120 && this.timer == null) {
this.timer = setInterval(() => {
this.seconds--;
this.tellForm.tellCodeText = "已发送(" + this.seconds + "s)"
}, 1000)
}
this.tellForm.key = data.key
} else {
this.$message({
message: res.message,
type: "warning"
});
this.isMobileSend = false
}
}).catch(err => {
this.getcaptcha();
this.$message.error(err.message);
if (err.message == '当前手机号已存在') {
this.isMobileSend = false
}
})
} else {
this.$message({
message: "请勿重复点击",
type: "warning"
})
}
},
//绑定手机号
bindtell() {
this.$refs.tellRef.validate(valid => {
if (valid) {
tell({
mobile: this.tellForm.tell,
captcha_id: this.captcha.id,
captcha_code: this.tellForm.code,
code: this.tellForm.tellDynacode,
key: this.tellForm.key
}).then(res => {
if (res.code == 0) {
this.$message({
message: "手机号绑定成功",
type: "success"
});
this.type = "all";
this.tellForm.email = "";
this.tellForm.code = "";
this.tellForm.emailDynacode = "";
clearInterval(this.timer);
this.getcaptcha()
}
}).catch(err => {
this.getcaptcha();
this.$message.error(err.message);
})
} else {
return false
}
})
},
//获取输入框数据
input(val) {
this.isClick = false;
if (this.step == 0 && val.length == 4) {
this.payCode = val;
} else if (this.step == 1 && val.length == 6) {
this.payPassword = val;
} else if (val.length == 6) {
this.payRepassword = val;
}
},
//获取支付验证码
sendMobileCode() {
if (!this.isSend) {
payPwdCode().then(res => {
let data = res.data;
if (data.key) {
if (this.seconds == 120 && this.timer == null) {
this.timer = setInterval(() => {
this.seconds--;
this.payCodeText =
"已发送(" + this.seconds + "s)";
}, 1000);
}
this.payKey = data.key;
} else {
this.$message({
message: res.message,
type: 'warning'
});
this.isSend = false;
}
}).catch(err => {
this.$message.error(err.message);
});
}
},
//点击确定
bindPayPwd() {
clearInterval(this.timer);
const reg = /^[0-9]*$/;
if (this.step == 0) {
verifyPayPwdCode({
code: this.payCode,
key: this.payKey
}).then(res => {
if (res.code == 0) {
this.$refs.input.clear();
this.step = 1;
this.palceText = '请设置支付密码'
}
}).catch(err => {
this.$message.error(err.message);
})
} else if (this.step == 1) {
if (reg.test(this.$refs.input.value)) {
this.$refs.input.clear();
this.step = 2;
this.palceText = '请再次输入'
} else {
this.$message.error('请输入数字');
this.step = 1;
this.$refs.input.clear();
}
} else {
if (this.payPassword == this.payRepassword) {
if (this.isSub) return;
this.isSub = true;
modifyPayPassword({
key: this.payKey,
code: this.payCode,
password: this.payPassword
}).then(res => {
if (res.code >= 0) {
this.$message({
message: "修改支付密码成功",
type: "success"
});
this.type = 'all';
this.step = 0;
this.$refs.input.clear();
clearInterval(this.timer)
}
}).catch(err => {
this.$message.error(err.message);
})
} else {
this.$message.error('两次密码输入不一样');
this.initInfo();
}
}
},
//初始化信息
initInfo() {
this.step = 1;
this.palceText = '请设置支付密码';
this.password = '';
this.repassword = '';
this.oldpassword = '';
this.isSub = false;
this.$refs.input.clear();
},
//获取动态码
getTellPassCode() {
if (!this.isSend) {
this.isSend = true;
pwdMoblieCode({
captcha_id: this.captcha.id,
captcha_code: this.tellPassForm.code,
}).then(res => {
let data = res.data;
if (data.key) {
if (this.seconds == 120 && this.timer == null) {
this.timer = setInterval(() => {
this.seconds--;
this.tellPassForm.tellPassCodeText = "已发送(" + this.seconds + "s)"
}, 1000)
}
this.tellPassForm.key = data.key
} else {
this.$message({
message: res.message,
type: "warning"
});
this.isSend = false
}
}).catch(err => {
this.getcaptcha();
this.$message.error(err.message)
})
} else {
this.$message({
message: "请勿重复点击",
type: "warning"
})
}
},
//修改密码
tellPassSave() {
this.$refs.tellPassRef.validate(valid => {
if (valid) {
passWord({
new_password: this.tellPassForm.pass,
code: this.tellPassForm.tellPassDynacode,
key: this.tellPassForm.key,
}).then(res => {
this.$message({
message: "修改密码成功",
type: "success"
});
this.type = "all";
this.$store.dispatch("member/member_detail", {
refresh: 1
});
this.tellPassForm.pass = "";
this.tellPassForm.checkPass = "";
this.tellPassForm.key = "";
this.tellPassForm.tellPassDynacode = "";
}).catch(err => {
this.$message.error(err.message)
})
} else {
return false
}
})
},
},
filters: {
mobile(mobile) {
return mobile.substring(0, 4 - 1) + '****' + mobile.substring(6 + 1);
}
},
}

View File

@@ -0,0 +1,142 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>提现记录</span>
</div>
<div v-loading="loading" class="withdrawal-list">
<el-table v-if="dataList.length > 0" :data="dataList" border>
<el-table-column prop="transfer_type_name" label="账户类型" width="150"></el-table-column>
<el-table-column prop="apply_money" label="提现金额" width="150"></el-table-column>
<el-table-column prop="apply_time" label="提现时间"></el-table-column>
<el-table-column prop="status_name" label="提现状态" width="150"></el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
<div v-else-if="!loading && dataList.length == 0" class="ns-text-align">暂无提现记录</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 {withdrawList} from "@/api/member/account"
export default {
name: 'withdrawal',
layout: "member",
components: {},
data: () => {
return {
dataList: [],
currentPage: 1,
pageSize: 10,
total: 0,
loading: true,
yes: true
};
},
created() {
this.getDateList();
},
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.getDateList()
},
getDateList() {
withdrawList({
page_size: this.pageSize,
page: this.currentPage
}).then(res => {
if (res.code == 0 && res.data) {
this.dataList = res.data.list
this.dataList.forEach(item => {
item.apply_time = this.$util.timeStampTurnTime(item.apply_time)
})
this.total = res.data.count
}
this.loading = false
}).catch(err => {
this.loading = false
})
},
handleEdit(index, row) {
this.$router.push({path: '/member/withdrawal_detail', query: {id: row.id}})
}
}
};
</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;
}
.ns-len-input {
width: 350px;
}
.el-select {
margin-right: 10px;
}
.page-wrap {
margin-top: 10px;
}
</style>

View File

@@ -0,0 +1,146 @@
<template>
<div class="box">
<div class="null-page" v-show="yes"></div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/member/withdrawal' }">提现记录</el-breadcrumb-item>
<el-breadcrumb-item>提现详情</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div v-loading="loading">
<div class="money-wrap">
<span>-{{ detail.apply_money }}</span>
</div>
<div class="line-wrap">
<span class="label">当前状态</span>
<span class="value">{{ detail.status_name }}</span>
</div>
<div class="line-wrap">
<span class="label">交易号</span>
<span class="value">{{ detail.withdraw_no }}</span>
</div>
<div class="line-wrap">
<span class="label">手续费</span>
<span class="value">{{ detail.service_money }}</span>
</div>
<div class="line-wrap">
<span class="label">申请时间</span>
<span class="value">{{ $util.timeStampTurnTime(detail.apply_time) }}</span>
</div>
<div class="line-wrap" v-if="detail.status">
<span class="label">审核时间</span>
<span class="value">{{ $util.timeStampTurnTime(detail.audit_time) }}</span>
</div>
<div class="line-wrap" v-if="detail.bank_name">
<span class="label">银行名称</span>
<span class="value">{{ detail.bank_name }}</span>
</div>
<div class="line-wrap">
<span class="label">收款账号</span>
<span class="value">{{ detail.account_number }}</span>
</div>
<div class="line-wrap" v-if="detail.status == -1 && detail.refuse_reason">
<span class="label">拒绝理由</span>
<span class="value">{{ detail.refuse_reason }}</span>
</div>
<div class="line-wrap" v-if="detail.status == 2">
<span class="label">转账方式名称</span>
<span class="value">{{ detail.transfer_type_name }}</span>
</div>
<div class="line-wrap" v-if="detail.status == 2">
<span class="label">转账时间</span>
<span class="value">{{ $util.timeStampTurnTime(detail.payment_time) }}</span>
</div>
</div>
</el-card>
</div>
</template>
<script>
import {withdrawDetail} from "@/api/member/account"
export default {
name: 'withdrawal_detail',
layout: "member",
components: {},
data: () => {
return {
loading: true,
id: '',
detail: {},
yes: true
};
},
created() {
this.getDetail();
},
mounted() {
let self = this;
setTimeout(function () {
self.yes = false
}, 300)
},
methods: {
//获得提现详情
getDetail() {
this.id = this.$route.query.id
withdrawDetail({
id: this.id
}).then(res => {
if (res.data) {
this.detail = res.data;
}
this.loading = false
}).catch(err => {
this.loading = false
})
}
}
};
</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;
}
.money-wrap {
font-size: 20px;
font-weight: 600;
}
.line-wrap {
margin-top: 20px;
.label {
display: inline-block;
width: 100px;
color: #898989;
}
}
</style>