Authored by 邱骏

增加发放优惠券,商家详情,招商人

... ... @@ -30,6 +30,15 @@ class Api {
}).catch(this.catch);
}
_postForm(url, data, options = {}) {
if (!PRODUCTION) { //eslint-disable-line
url += (url.indexOf('?') >= 0 ? '&' : '?') + 'debug=XYZ';
}
return util.ajax.post(url, data, options).then(result => {
return result.data;
}).catch(this.catch);
}
catch({message}) {
iView.Message.destroy();
iView.Message.warning(message || '接口错误');
... ... @@ -43,7 +52,10 @@ class Api {
const params = {};
Object.keys(data).forEach(k => {
if (data[k] || data[k] === 0) {
if (k === 'investName') {
params[k] = data[k] || '';
} else if (data[k] || data[k] === 0) {
params[k] = data[k];
}
});
... ...
... ... @@ -92,17 +92,18 @@ export default {
width: 100
}, {
title: '操作',
width: 270,
align: 'center',
render: (h, {row}) => {
return (
<div>
<i-button type="success" size="small" onClick={() => this.onEditCoupon(row, true)}>查看详情</i-button>&nbsp;
<i-button type="success" size="small" onClick={() => this.onEditCoupon(row, true)}>查看详情</i-button>
{(row.status === '未生效' || row.status === '生效中') ?
(<i-button type="primary" size="small" onClick={() => this.onEditCoupon(row)}>修改</i-button>) :
void 0}
&nbsp;
<i-button type="warning" size="small" onClick={() => this.onToRecord(row)}>发放记录</i-button>
{(row.status === '未生效' || row.status === '生效中') ?
(<i-button type="success" size="small" onClick={() => this.onSendCoupon(row)}>发券</i-button>) : void 0}
</div>
);
}
... ... @@ -136,6 +137,14 @@ export default {
}
})}`;
},
onSendCoupon({id, token}) {
if (id && token) {
location.href= `send-coupon.html?${qs.stringify({
id,
token
})}`;
}
},
onCreated() {
this.fetchData(this.filter);
},
... ... @@ -210,5 +219,7 @@ export default {
</script>
<style>
button {
margin: 5px;
}
</style>
... ...
import App from './index.vue';
import createApp from 'create-app';
createApp(App);
\ No newline at end of file
... ...
<template>
<LayoutContent :breads="[{url: parentUrl, title: '优惠券列表'}, {title: '优惠券发放'}]">
<i-form>
<i-card class="manual-send-wrapper">
<p slot="title">手动发放</p>
<div>
<i-row class="manual-send-container">
<i-col span="4" class="title">
UID<span class="red">*</span>
</i-col>
<i-col span="14" class="content">
<textarea rows="5" id="txt_uids" placeholder="请输入UID,多个UID用英文逗号分隔,单次限制输入50个UID" v-model="uidValue"></textarea>
</i-col>
<i-col span="5" class="button">
<i-button type="success" @click="manualSend">发送</i-button>
</i-col>
</i-row>
</div>
</i-card>
<i-card class="import-send-wrapper">
<p slot="title">批量发放</p>
<div>
<i-row class="import-send-container">
<i-col span="3">&nbsp;</i-col>
<i-col span="4">
<div class="button-upload">
上传文件
<form id="formUpload">
<input type="file" id="upload" @change="fileChange" accept=".csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
</form>
</div>
<span class="file-name">{{fileName}}</span>
</i-col>
<i-col span="2">&nbsp;</i-col>
<i-col span="8">&nbsp;</i-col>
</i-row>
<i-row style="margin-top: 20px;">
<i-col span="3">&nbsp;</i-col>
<i-col span="4">
<a href="..\..\common/uid_import.xlsx" class="btn-download" target="_blank">下载样例</a>
<p>1.表头:UID</p>
<p>2.同一张券可以给同一个用户发多张?</p>
</i-col>
<i-col span="2">&nbsp;</i-col>
<i-col span="8">
<a href="javascript:void(0)" style="color: red;">校验场景</a>
<p>1.优惠券数量</p>
<p>2.优惠券状态是否为未生效,或生效中</p>
</i-col>
</i-row>
<i-row>
<p style="color: red;text-align: center;margin-top: 30px; font-size: 30px;">{{uploadMessage}}</p>
</i-row>
</div>
</i-card>
<div class="bottom">
<i-button type="success" id="btn_import_send" @click="importSend">批量发送</i-button>
</div>
</i-form>
</LayoutContent>
</template>
<script>
import Api from '@/api/api';
import dayjs from 'dayjs';
import BlobUtil from 'libs/blob';
import qs from 'qs';
const api = new Api();
export default {
components: {},
name: 'SendCouponPage',
data() {
return {
parentUrl: '',
couponId: 0,
couponToken: '',
uidValue: '',
fileName: '',
showModal: false,
message: '',
uploadMessage: '',
isSending: false
};
},
created() {
this.$nextTick(() => {
const queryString = qs.parse(location.search ? location.search.slice(1) : '');
this.parentUrl = `coupon.html?${qs.stringify(queryString.param)}`;
this.couponId = queryString.id;
this.couponToken = queryString.token;
});
},
methods: {
manualSend() { // 手动发放优惠券
if(this.uidValue && !this.isSending) {
let uidArr = this.uidValue.replace(/,/g, ',').split(',');
if (uidArr.length > 50) {
uidArr.length = 50;
}
if (uidArr.length > 0) {
this.isSending = true;
api._get('/ufoPlatform/coupon/couponSend', {
couponToken: this.couponToken,
uids: uidArr.join(',')
}).then(result => {
this.showModal = true;
this.message = result.message;
this.isSending = false;
this.$Modal.info({
title: '提示' + 'code:' + result.code,
content: result.message,
onOK: this.ok
});
}).catch(() => {
this.isSending = false;
this.$Modal.info({
title: '提示',
content: '发送失败',
onOK: this.ok
});
});
}
}
},
fileChange() {
let fileUpload = document.getElementById('upload');
if (fileUpload.files.length > 0) {
this.fileName = fileUpload.files[0].name;
}
},
importSend() {
if (this.fileName && !this.isSending) {
let formData = new FormData();
let file = document.getElementById('upload').files[0];
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
};
formData.append('file', file);
formData.append('couponToken', this.couponToken);
this.isSending = true;
this.uploadMessage = '文件上传中...';
api._postForm('/ufoPlatform/coupon/couponSendByImport', formData, false, config).then(result => {
this.isSending = false;
this.uploadMessage = '';
this.$Modal.info({
title: '提示' + 'code:' + result.code,
content: result.message,
onOK: this.ok
});
}).catch(() => {
this.isSending = false;
this.uploadMessage = '';
this.$Modal.info({
title: '提示',
content: '上传失败',
onOK: this.ok
});
});
}
},
ok() {
this.showModal = false;
}
},
};
</script>
<style>
.manual-send-wrapper {
height: 205px;
}
.import-send-wrapper {
height: 100%;
}
.ivu-card-body {
padding: 0;
margin: 0;
}
.ivu-card-bordered {
/*border: none;*/
border-bottom: none;
}
.ivu-card-head {
background-color: #f7f7f7;
}
.manual-send-container {
margin-top: 20px;
height: 130px;
}
.import-send-container {
margin-top: 40px;
/*margin-bottom: 200px;*/
}
.manual-send-container .title {
text-align: right;
margin-right: 20px;
}
.manual-send-container .content {
}
#txt_uids {
width: 98%;
height: 100%;
}
#upload {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
left: 0;
top: 0;
}
.button-upload {
position: relative;
display: inline-block;
background-color: #17b566;
-webkit-border-radius: 5px;
border-radius: 5px;
color: #fff;
width: 80px;
height: 32px;
line-height: 32px;
text-align: center;
overflow: hidden;
}
.file-name {
height: 32px;
line-height: 32px;
margin-left: 20px;
color: #2b85e4;
display: inline-table;
vertical-align: middle;
}
.red {
color: #ff0000;
}
.bottom {
position: absolute;
bottom: 0;
width: 100%;
height: 80px;
background-color: #f7f7f7;
line-height: 80px;
text-align: center;
}
a {
text-decoration: none;
}
</style>
... ...
... ... @@ -19,9 +19,9 @@
</i-form-item>
<i-form-item prop="entryType">
<i-select placeholder="商家类型" v-model="filter.entryType" style="width: 100px">
<i-option :value="1">普通入驻</i-option>
<i-option :value="1">入驻卖家</i-option>
<i-option :value="2">超级入驻</i-option>
<i-option :value="3">前期白名单</i-option>
<i-option :value="4">普通卖家</i-option>
</i-select>
</i-form-item>
</i-form>
... ... @@ -33,6 +33,76 @@
:data="data"
@on-page-change="onPageChange">
</LayoutTable>
<!--弹出框展示商家详情-->
<div class="popup-detail-wrapper" :class="{ show: isShowDetail}">
<i-card class="popup-detail-container">
<p slot="title">商家详情</p>
<i-button slot="extra" class="btn-close" @click="closePopup">X</i-button>
<div class="pop-detail-content">
<i-row>
<i-col span="4" class="detail-title">UID</i-col>
<i-col span="8">{{detail.uid || '&nbsp;'}}</i-col>
<i-col span="4" class="detail-title">商家类型</i-col>
<i-col span="8">{{['','入驻卖家', '超级入驻', '', '普通卖家'][detail.entryType]}}</i-col>
</i-row>
<i-row>
<i-col span="4" class="detail-title">商家名称</i-col>
<i-col span="8">{{detail.certName || '--'}}</i-col>
<i-col span="4" class="detail-title">手机号</i-col>
<i-col span="8">{{detail.mobile || '--'}}</i-col>
</i-row>
<i-row>
<i-col span="4" class="detail-title">招商人员</i-col>
<i-col span="8">{{detail.investName || '--'}}</i-col>
<i-col span="4" class="detail-title">违规次数</i-col>
<i-col span="8">{{detail.breakRuleTimes || '0'}}</i-col>
</i-row>
<i-row>
<i-col span="4" class="detail-title">账户余额</i-col>
<i-col span="8" style="color: red;">{{detail.money || '0.00'}}</i-col>
<i-col span="4" class="detail-title">入驻状态</i-col>
<i-col span="8">{{detail.validStatusDesc || '--'}}</i-col>
</i-row>
<i-row>
<i-col span="4" class="detail-title">入驻时间</i-col>
<i-col span="8">{{detail.enterTime || '--'}}</i-col>
<i-col span="4" class="detail-title">退出入驻时间</i-col>
<i-col span="8">{{detail.quitTime || '--'}}</i-col>
</i-row>
<i-row>
<i-col span="4" class="detail-title">身份证号</i-col>
<i-col span="20">{{detail.certNo || '--'}}</i-col>
</i-row>
<i-row>
<i-col span="4" class="detail-title no-border-right" style="min-height: 150px;line-height: 150px;">身份证照片</i-col>
<i-col span="20" class="border-left" style="min-height: 150px;">
<img v-if="detail.idCardFrontUrl" class="cert-image" :src="detail.idCardFrontUrl">
<img v-if="detail.idCardBackUrl" class="cert-image" :src="detail.idCardBackUrl">
</i-col>
</i-row>
</div>
</i-card>
</div>
<!--弹出框绑定招商人员-->
<div class="popup-invist-wrapper" :class="{ show: isShowInvest}">
<i-card class="popup-invist-container">
<p slot="title">绑定招商人</p>
<i-button slot="extra" class="btn-close" @click="closePopup">X</i-button>
<div class="popup-invist-content">
<i-row>
<i-col class="invist-title" span="8">招商人员</i-col>
<i-col span="16">
<input type="text" v-model="investInfo.investName" placeholder="请输入招商人" style="width: 80%">
</i-col>
</i-row>
<i-row>
<i-col span="24" style="text-align: center;">
<i-button type="success" @click="submitInvist">保存</i-button>
</i-col>
</i-row>
</div>
</i-card>
</div>
</LayoutContent>
</template>
... ... @@ -40,10 +110,16 @@
import dayjs from 'dayjs';
import Api from '@/api/api';
import qs from 'qs';
import {Button} from 'iview'; //eslint-disable-line
import ICol from "../../../node_modules/iview/src/components/grid/col"; //eslint-disable-line
import Input from "../../../node_modules/iview/src/components/input/input"; //eslint-disable-line
const api = new Api();
export default {
components: {
Input,
ICol},
name: 'SendRecordPage',
data() {
return {
... ... @@ -57,68 +133,101 @@ export default {
page: 1,
total: 0,
data: [],
detail: {},
investInfo: {},
nowSelectedRow: {},
isShowDetail: false, // 显示详情弹框
isShowInvest: false, // 显示绑定招商人员
columns: [{
title: 'UID',
key: 'uid',
align: 'center',
width: 100
},
{
title: '商家类型',
align: 'center',
render(h, {row}) {
return h('span', {}, ['','普通入驻', '超级入驻', '前期白名单'][row.entryType]);
return h('span', {}, ['','入驻卖家', '超级入驻', '', '普通卖家'][row.entryType]);
},
width: 100
width: 90
},
{
title: '商家名称',
key: 'certName',
align: 'center',
width: 100
}, {
title: '手机号',
align: 'center',
key: 'mobile',
width: 150
width: 120
}, {
title: '身份证',
align: 'center',
key: 'certNo',
width: 200
width: 140
}, {
title: '上架SKUP',
align: 'center',
key: 'selfSkuNum',
width: 100
width: 95
}, {
title: '违规次数',
key: 'breakRuleTimes',
width: 100
width: 90
},
{
title: '账户余额',
align: 'center',
render(h, {row}) {
let color = parseInt(row.money, 10) > 999 ? 'inherit' : 'red';
return h('span', {style: {color: color}}, row.money);
},
width: 100
width: 90
},
{
title: '入驻时间',
align: 'center',
render(h, {row}) {
return (
<span>{dayjs(row.enterTime).format('YYYY-MM-DD HH:mm:ss')}</span>
<span>{dayjs(row.enterTime).format('YYYY-MM-DD')}</span>
);
},
width: 150
width: 100
}, {
title: '退出入驻时间',
align: 'center',
render(h, {row}) {
return (
<span>{row.quitTime ? dayjs(row.quitTime).format('YYYY-MM-DD HH:mm:ss') : ''}</span>
<span>{row.quitTime ? dayjs(row.quitTime).format('YYYY-MM-DD') : ''}</span>
);
},
width: 150
width: 100
}, {
title: '入驻状态',
align: 'center',
key: 'validStatusDesc',
width: 100
}]
}, {
title: '招商人员',
align: 'center',
key: 'investName',
}, {
title: '操作',
align: 'center',
width: 150,
render:(h, {row}) => {
return (
<div>
<i-button type="primary" size="small" onClick={() => this.onShowDetail(row)}>查看</i-button>
{(row.investName) ?
(<i-button type="primary" size="small" onClick={() => this.onEditInvest(row)}>修改招商人</i-button>) :
<i-button type="success" size="small" onClick={() => this.onEditInvest(row)}>绑定招商人</i-button>}
</div>
);
}
}
]
};
},
created() {
... ... @@ -153,7 +262,6 @@ export default {
}, this.getParams(params)));
if (result.code === 200) {
// console.log('listData:', result);
this.total = result.data.total;
this.data = result.data.list;
this.$Loading.finish();
... ... @@ -162,6 +270,51 @@ export default {
this.$Loading.error();
}
},
onShowDetail(row) {
let detail = Object.assign({}, row);
detail.enterTime = row.enterTime ? dayjs(row.enterTime).format('YYYY-MM-DD HH:mm:ss') : '--';
detail.quitTime = row.quitTime ? dayjs(row.quitTime).format('YYYY-MM-DD HH:mm:ss') : '--';
this.detail = detail;
this.isShowDetail = true;
},
onEditInvest(row) {
this.nowSelectedRow = row;
this.isShowInvest = true;
this.investInfo = {
uid: row.uid,
investName: row.investName || ''
};
},
submitInvist() {
if(this.investInfo.uid) {
api._post('/ufoPlatform/storedSeller/saveInvestUser', this.investInfo).then(result => {
if (result.code === 200) {
// this.nowSelectedRow.investName = this.investInfo.investName;
this.closePopup();
this.fetchData(this.filter, this.page);
this.$Modal.info({
title: '提示',
content: result.message
});
} else {
this.closePopup();
this.$Modal.info({
title: '提示',
content: '保存失败'
});
}
});
}
},
closePopup() {
this.detail = {};
this.investInfo = {};
this.isShowDetail = false;
this.isShowInvest = false;
},
getParams(params) {
return {
certName: params.certName,
... ... @@ -176,5 +329,100 @@ export default {
</script>
<style>
.ivu-btn {
margin: 0 2px;
}
.ivu-table-cell {
padding: 10px;
}
.show {
display: block !important;
}
.btn-close {
width: 30px;
height: 30px;
border: none;
-webkit-border-radius: 50%;
border-radius: 50%;
text-align: center;
padding: 0;
color: red;
}
.popup-detail-wrapper,
.popup-invist-wrapper {
display: none;
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
background-color: rgba(0, 0, 0, 0.7);
z-index: 99;
}
.popup-detail-container {
width: 900px;
min-height: 500px;
margin: 100px auto;
}
.popup-invist-container {
width: 500px;
height: 200px;
margin: 100px auto;
}
.ivu-row:hover {
background-color: lightblue;
}
.ivu-row, .ivu-col {
overflow: hidden;
}
.detail-title, .invist-title {
color: #2db7f5;
}
.cert-image {
width: 200px;
min-height: 126px;
margin: 4px 10px;
}
.popup-detail-container .ivu-row {
border-left: 1px solid lightgray;
border-bottom: 1px solid lightgray;
}
.popup-detail-container .ivu-col{
border: 1px solid lightgray;
padding: 8px 0;
text-align: center;
border-bottom: none;
border-left: none;
}
.no-border-right {
border-right: none !important;
}
.border-left {
border-left: 1px solid lightgray !important;
}
.popup-invist-container .ivu-row {
padding: 10px 0;
text-align: center;
}
input {
width: 80%;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
</style>
... ...