Commit df4f9179 by chenxin

fix: 卡券&一些调整

parent e38509ec
......@@ -34,7 +34,6 @@
<script src="//web-1251519181.file.myqcloud.com/components/store-select.1.1.78.js"></script><!-- 门店选择器 -->
<script src="//web-1251519181.file.myqcloud.com/components/goods-selector.1.0.51.js"></script><!-- 商品选择器 -->
<script src="//web-1251519181.file.myqcloud.com/components/card-select.1.0.33.js"></script><!-- 卡券选择器 -->
<script src="//web-1251519181.file.myqcloud.com/components/market-event-new.1.0.22.js"></script><!-- 新版营销事件通知组件 -->
<script src="//web-1251519181.file.myqcloud.com/components/link-tools.2.1.21.js"></script><!-- 链接小工具 -->
<script src="//web-1251519181.file.myqcloud.com/components/export-data.1.1.1.js"></script><!-- 数据导出 -->
<script src="//web-1251519181.file.myqcloud.com/components/integral-select.1.0.26.js"></script><!-- 积分选择器 -->
......
/**
* api
* GIC卡券包
*/
import getFetch from './get-fetch.js';
import { welfarePrefix } from '@/config';
// 卡券包
let packages = {
savePackages: {
// 新增、编辑卡券包 /coupon-package/save-package /coupon-package/edit-package TODO:
url: '/coupon-package/{type}-package', // edit add
method: 'post',
useFormData: true,
rest: true
},
pageCouponPackage: '/page-package', // 获取卡券包列表
pagePackageLog: '/coupon-package/page-package-log', // 卡券包领取记录 TODO:
packageCouponReceiveLog: '/coupon-package/package-coupon-receive-log', // 卡券领取记录详情 TODO:
getPackageDetail: '/coupon-package/get-package-detail', // 获取卡券包详情 TODO:
deletePackage: '/coupon-package/delete-package', // 删除某个卡券包 TODO:
optPackageStock: '/coupon-package/opt-package-stock', // 调整卡券包库存 TODO:
};
packages = getFetch(packages, welfarePrefix);
export default { ...packages };
......@@ -24,7 +24,6 @@ let other = {
getMallShopList: '/outer/all-mall-shop', // 获取微商城店铺数据 没有入参
activityList: '/activity/list-marketing-page', // 数据对话分页列表
getActivityInfo: '/activity/get-marketing-activity', // 获取数据对话详情
uploadUrl: '/upload/upload-image' // 默认上传图片接口
};
o2 = getFetch(o2, welfarePrefix);
......@@ -32,3 +31,4 @@ common = getFetch(common, commonPrefix);
other = getFetch(other, marketPrefix);
export default { ...common, ...other, ...o2 };
export const uploadUrl = marketPrefix + '/upload/upload-image'; // 默认上传图片接口
\ No newline at end of file
......@@ -3,12 +3,12 @@
* GIC卡券
*/
import getFetch from './get-fetch.js';
import config, { marketPrefix } from '@/config';
import config, { welfarePrefix } from '@/config';
// 卡券相关接口
let card = {
cardList: '/coupon-gic/gic-coupon-page', // 卡券列表 TODO:
cardList: '/coupon/coupon-page', // 卡券列表
addCard: {
// 新增卡券
url: '/coupon/save-coupon',
......@@ -16,15 +16,17 @@ let card = {
useFormData: true,
},
updateCard: {
// 修改卡券 TODO:
url: '/coupon-gic/update-gic-coupon',
// 修改卡券
url: '/coupon/edit-coupon',
method: 'post',
useFormData: true,
},
copyCard: '/coupon-gic/copy-gic-coupon', // 拷贝卡券 TODO:
cardInfo: '/coupon-gic/get-gic-coupon-detail', // 卡券详情 TODO:
updateCardStock: '/coupon-gic/update-gic-coupon-stock', // 修改库存 TODO:
deleteCard: '/coupon-gic/delete-gic-coupon', // 删除卡券 TODO:
copyCard: '/coupon/copy-coupon', // 拷贝卡券
cardInfo: '/coupon/coupon-detail', // 卡券详情
updateCardStock: '/coupon/update-coupon-stock', // 修改库存
deleteCard: '/coupon/delete-coupon', // 删除卡券
disableCard: '/coupon/disable-coupon', // 禁用卡券
couponLogPage: '/coupon-log/coupon-log-page', // 卡券领取列表
giveLogList: '/coupon-gic/gic-coupon-give-log-page', // 卡券转赠记录 TODO:
groupSendAdd: {
// 新建投放 TODO:
......@@ -38,7 +40,6 @@ let card = {
couponPutonFailLogList: '/coupon-gic/coupon-puton-fail-log-page', // 卡券投放失败详情 TODO:
stopGroupSend: '/coupon-gic/stop-coupon-puton-timed-task', // 禁用投放 TODO:
codeErrorList: '/gic-coupon-code-error-page', // 查询导入券券码错误列表 TODO:
gicCardListByName: '/coupon-gic/list-coupon-names', // 根据name模糊查询卡券列表 TODO:
checkDemoCode: {
// 根据demo code TODO:
url: '/coupon-gic/check-demo-code',
......@@ -108,22 +109,6 @@ let shelf = {
getShelfCoupon: '/coupon-gic/list-shelf-coupon', // 获取展架使用的卡券 TODO:
};
// 卡券包
let packages = {
savePackages: {
// 新增、编辑卡券包 /coupon-package/save-package /coupon-package/edit-package TODO:
url: '/coupon-package/{type}-package', // edit add
method: 'post',
useFormData: true,
rest: true
},
pageCouponPackage: '/coupon-package/page-coupon-package', // 获取卡券包列表 TODO:
pagePackageLog: '/coupon-package/page-package-log', // 卡券包领取记录 TODO:
packageCouponReceiveLog: '/coupon-package/package-coupon-receive-log', // 卡券领取记录详情 TODO:
getPackageDetail: '/coupon-package/get-package-detail', // 获取卡券包详情 TODO:
deletePackage: '/coupon-package/delete-package', // 删除某个卡券包 TODO:
optPackageStock: '/coupon-package/opt-package-stock', // 调整卡券包库存 TODO:
};
// 其他接口
let other = {
auditList: '/coupon/audit-log-page', // 审核记录 TODO:
......@@ -140,17 +125,16 @@ let other = {
getCouponSendFailLogList: '/coupon-gic/coupon-send-fail-log', // 卡券发放失败记录 TODO:
};
card = getFetch(card, marketPrefix);
syncStock = getFetch(syncStock, marketPrefix);
shelf = getFetch(shelf, marketPrefix);
packages = getFetch(packages, marketPrefix);
other = getFetch(other, marketPrefix);
card = getFetch(card, welfarePrefix);
syncStock = getFetch(syncStock, welfarePrefix);
shelf = getFetch(shelf, welfarePrefix);
other = getFetch(other, welfarePrefix);
export default { ...card, ...other, ...syncStock, ...shelf, ...packages };
export default { ...card, ...other, ...syncStock, ...shelf };
export const downloadCouponCSV = config.api + marketPrefix + '/download-code-csv-template'; // 下载导入GIC券号csv示例文件 TODO:
export const importCode = config.api + marketPrefix + '/import-gic-custom-code'; // 导入券码 TODO:
export const importDestoryCode = marketPrefix + '/destroy-plugin/import-destroy-code'; // 上传销毁code列表 TODO:
export const downloadDestroyCodeTemplate = config.api + marketPrefix + '/destroy-plugin/download-destroy-code-template'; // 下载销毁模板示例 TODO:
export const downloadCouponCSV = config.api + welfarePrefix + '/download-code-csv-template'; // 下载导入GIC券号csv示例文件 TODO:
export const importCode = config.api + welfarePrefix + '/import-gic-custom-code'; // 导入券码 TODO:
export const importDestoryCode = welfarePrefix + '/destroy-plugin/import-destroy-code'; // 上传销毁code列表 TODO:
export const downloadDestroyCodeTemplate = config.api + welfarePrefix + '/destroy-plugin/download-destroy-code-template'; // 下载销毁模板示例 TODO:
......@@ -469,6 +469,9 @@ a:hover {
.black {
color: black;
}
.bg-color {
background-color: $gray-background;
}
// 文字浅色
.gray01 {
color: $gray01;
......
......@@ -54,6 +54,7 @@ export default {
* @param {string} index
*/
handleSelect(index) {
console.log(index);
let projectUrl = window.location.pathname;
projectUrl = projectUrl.split('/')[1];
projectUrl = `/${projectUrl}`;
......@@ -129,13 +130,9 @@ export default {
if(project == '' || project == 'index') {
return [];
}
const mapping = {
'gic-card': 'w-gic-card',
'card-package': 'w-card-package',
'w-card-destory': 'w-card-destory'
};
const currentRoute = this.routePath.find(v => v.menuCode == mapping[project]);
return currentRoute ? currentRoute.children : [];
// const isCard = project.includes('card');
const currentRoute = this.routePath.filter(v => v.menuCode.includes('card'));
return currentRoute || [];
}
},
watch: {
......
......@@ -9,7 +9,7 @@
<script>
import wxCardApi from '@/api/gic-card.js';
const { gicCardListByName, cardInfo: gicCardInfo } = wxCardApi;
const { cardInfo: gicCardInfo } = wxCardApi;
export default {
name: 'CardSelectFilterable',
directives: {
......@@ -83,21 +83,22 @@ export default {
this.getCardList();
},
async getCardList() {
if (this.nomore) {
return;
}
if (this.loading) {
return;
}
this.loading = true;
this.nomore = false;
let res = gicCardListByName({ ...this.listParams, memberCardId: this.memberCardId });
const tableList = res.result.result ? this.tableList.concat(res.result.result) : [];
const total = res.result.totalCount;
this.tableList = tableList;
this.total = total;
this.nomore = total <= tableList.length || total - tableList.length < this.listParams.pagesize; // 没有下一页了
this.loading = false;
return;
// if (this.nomore) {
// return;
// }
// if (this.loading) {
// return;
// }
// this.loading = true;
// this.nomore = false;
// let res = gicCardListByName({ ...this.listParams, memberCardId: this.memberCardId });
// const tableList = res.result.result ? this.tableList.concat(res.result.result) : [];
// const total = res.result.totalCount;
// this.tableList = tableList;
// this.total = total;
// this.nomore = total <= tableList.length || total - tableList.length < this.listParams.pagesize; // 没有下一页了
// this.loading = false;
}
},
watch: {
......
<template>
<el-image @click="viewClick" :src="src" :fit="fit" :lazy="lazy" :scroll-container="scrollContainer" :preview-src-list="previewSrcList" :z-index="zIndex">
<template v-slot:error>
<slot name="error" />
</template>
</el-image>
</template>
<script>
export default {
name: 'DmElImageView',
props: {
src: String,
fit: String,
lazy: Boolean,
scrollContainer: {},
previewSrcList: {
type: Array,
default: () => []
},
zIndex: {
type: Number,
default: 2000
}
},
methods: {
viewClick() {
this.$emit('click');
document.body.style = ''; // 原生js清除body样式
}
},
};
</script>
\ No newline at end of file
<template>
<div class="sort-btn">
<i class="el-icon-caret-top" :class="{ active: sortType === 'increase' }"></i>
<i class="el-icon-caret-bottom" :class="{ active: sortType === 'decrease' }"></i>
<i class="el-icon-caret-top" :class="{ active: sortType === 'asc' }"></i>
<i class="el-icon-caret-bottom" :class="{ active: sortType === 'desc' }"></i>
</div>
</template>
......
<template>
<div class="main-content">
<div class="main-content-head">
<welfare-item :welfare-id="welfareId" />
</div>
<div class="main-content-bodys" v-loading="loading">
<div class="pb20 pt5 clearfix flex-center search">
<label class="mr8 cursor">操作时间</label>
<el-date-picker class="mr10" v-model="dateTime" type="datetimerange" :default-time="['00:00:00', '23:59:59']" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh" />
<label class="ml15 mr8">库存</label>
<el-input-number class="hide-right w100" @change="refresh" v-model="listParams.modifyStockMin" controls-position="right" :precision="0" :min="1" :max="10000" placeholder="请输入" />
<label class="ml5 mr5">-</label>
<el-input-number class="hide-right w100 mr15" @change="refresh" v-model="listParams.modifyStockMax" controls-position="right" :precision="0" :min="1" :max="100000" placeholder="请输入" />
<el-select class="w220 mrAuto" collapse-tags clearable v-model="listParams.activityIdList" placeholder="所有营销活动" multiple @change="refresh">
<el-option v-for="(v, i) in activityList" :key="i" :label="v.activityName" :value="v.activityId"></el-option>
</el-select>
<!-- <el-button type="primary" icon="iconfont-market4 icon-icon_yunxiazai">下载</el-button> -->
</div>
<el-table tooltip-effect="dark" :data="tableList" style="width:100%" @sort-change="handleSort">
<template>
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else-if="v.famount">{{ scope.row[v.prop] | amountFormat(null, 0, null) }}</span>
<span v-else>{{ scope.row[v.prop] }}</span>
</template>
</el-table-column>
</template>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" hide-on-single-page background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
</div>
</div>
</template>
<script>
import { page, formate } from '@/mixins/table.js';
// import welfareItem from './welfare-item';
import { listTime } from '@/utils/index.js';
// import api from '@/api/welfare';
// const { stockLogList, activityListByWfId } = api;
export default {
name: 'StockLogList',
// components: {
// welfareItem
// },
mixins: [ page, formate ],
data() {
return {
loading: false,
welfareId: this.$route.query.id,
dateTime: [ , ],
listParams: {
search: '',
welfareId: this.$route.query.id,
modifyLogId: '',
modifyTimeBegin: '',
modifyTimeEnd: '',
modifyStockMin: undefined,
modifyStockMax: undefined,
currentPage: 1,
pageSize: 20,
},
activityList: [],
total: 0,
tableList: [],
tableHeader: [
{ label: '库存调整记录ID', prop: 'modifyLogId', align: 'left', minWidth: '140', fixed: 'left' },
{
label: '操作时间',
minWidth: '120',
align: 'left',
prop: 'modifyTime',
sortable: true,
formatter: function(row) {
return listTime(row.modifyTime);
}
},
{
label: '调整库存',
minWidth: '120',
align: 'left',
sortable: true,
formatter: function(row) {
return 1;
}
},
{
label: '调整类型',
minWidth: '120',
align: 'left',
formatter: function(row) {
return 0;
}
},
{ label: '总库存', prop: 'afterTotalStock', align: 'left', minWidth: '120' }
]
};
},
mounted() {
this.getTableList();
this.activityListByWfId();
},
methods: {
handleSort() {
console.log('sort');
},
// 获取福利列表
getTableList() {
// if(this.loading) {
// return;
// }
// this.loading = true;
// this.formatterTimeFunc('modifyTimeBegin', 'modifyTimeEnd', 'yyyy-MM-dd-HH-mm-ss');
// const params = { ...this.listParams };
// stockLogList(params).then(res => {
// this.loading = false;
// const data = res.result;
// this.tableList = data.result || [];
// this.total = data.totalCount;
// // 删除至最后一页没数据的情况,页码-1
// if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
// this.listParams.currentPage -= 1;
// this.getTableList();
// }
// }).finally(() => {
// this.loading = false;
// });
},
// 获取营销活动列表
activityListByWfId() {
// activityListByWfId({ welfareId: this.welfareId }).then(res => {
// this.activityList = res.result || [];
// });
}
},
};
</script>
<template>
<div class="welfare-item">
<div class="head">
<span class="head-type">
<el-tag type="success" v-if="item.welfareType == 'wx_card'">{{ cardType[welfareType] || '--' }}</el-tag>
<el-tag v-else-if="item.welfareType == 'gic_card'">{{ cardType[welfareType] || '--' }}</el-tag>
<el-tag type="warning" v-else-if="item.welfareType == 'gift'">{{ cardType[welfareType] || '--' }}</el-tag>
<el-tag type="success" v-else>{{ cardType[welfareType] || '--' }}</el-tag>
</span>
<label>更新时间:</label>{{ formatDateTimeByType(item.updateTime) }}<label class="ml30">福利ID:</label>{{ item.welfareId }}
</div>
<div class="content clearfix wf-content">
<div class="it1">
<div class="cover-image" v-if="item.welfareType">
<dm-el-image-view class="img" :src="require(`@/assets/images/wf-${welfareType}.png`)" fit="fill" >
<div slot="error" class="image-slot">
<img class="img" :src="require('../../../assets/images/z-loading-failure.png')" draggable="false" />
</div>
</dm-el-image-view>
</div>
<dl>
<dd><span class="ellipsis" style="max-width:400px;display:inline-block;">{{ item.welfareName }}</span><label class="fr fz13">成本</label></dd>
<dt><label>停用时间:</label>{{ formatDateTimeByType(item.expiredDate) || '--' }}<span class="fr fz14">{{ item.singleCost | amountFormat }}</span></dt>
<dt><label>创建时间:</label>{{ formatDateTimeByType(item.createTime) }}</dt>
</dl>
</div>
<div class="it2">
<template v-if="item.attributeList && item.attributeList.length">
<ul>
<li v-for="(attr, idx) in item.attributeList" :key="idx"><label>{{ attr.attributeName }}</label>{{ attr.attributeValue || '--' }}</li>
</ul>
<div class="icon" v-if="item.attributeList.length > 4">
<el-tooltip open-delay="200" placement="bottom" :offset="5">
<ul slot="content">
<li v-for="(attr, idx) in item.attributeList" :key="idx"><label>{{ attr.attributeName }}</label>{{ attr.attributeValue || '--' }}</li>
</ul>
<i class="el-icon-more"></i>
</el-tooltip>
</div>
</template>
</div>
<div class="it3">
<!-- width:100% 文字溢出 -->
<el-popover open-delay="200" style="width:100%;" v-if="dealContent(item.welfareDescContent, true) > 4" width="200" trigger="hover">
<div v-html="item.welfareDescContent"></div>
<ul slot="reference" v-html="dealContent(item.welfareDescContent)"></ul>
</el-popover>
<ul v-else v-html="dealContent(item.welfareDescContent)"></ul>
</div>
<div class="it4">
<el-row :gutter="10">
<el-col :span="24" class="oh mb8">
<label>总库存:</label>{{ item.totalStock | amountFormat(null, 0, null) }}
<span class="el-tag" :class="`t${item.stockType}`">{{ stockType[item.stockType] }}</span>
</el-col>
<el-col :span="12" class="br mb8"><label>已占用:</label>{{ item.occupyStock | amountFormat(null, 0, null) }}</el-col>
<el-col :span="12" class="mb8"><label>可占用:</label>{{ item.remainedStock | amountFormat(null, 0, null) }}</el-col>
<el-col :span="12" class="br"><label>已发放:</label>{{ item.consumedStock | amountFormat(null, 0, null) }}</el-col>
<el-col :span="12"><label>未发放:</label>{{ (item.totalStock - item.consumedStock) | amountFormat(null, 0, null) }}</el-col>
</el-row>
</div>
<!-- 操作按钮插槽 -->
<slot name="option" />
</div>
</div>
</template>
<script>
import { formatDateTimeByType } from '@/utils/index';
import { cardType, stockType } from '@/config/mapping/welfare';
export default {
name: 'WelfareItem',
props: {
item: {
type: Object,
default: () => {}
}
},
data() {
return {
cardType,
stockType
};
},
methods: {
formatDateTimeByType,
dealContent(val, flag = false) {
// flag:false 返回处理后的数据
// flag:true 返回处理后数据的长度
if(!flag) {
let str = val ? val.split('<br/>').filter(v => v).map(v => {
return `<li>${v}</li>`;
}).join('') : '';
return str;
} else {
return val ? val.split('<br/>').filter(v => v).length : 0;
}
}
},
computed: {
welfareType() {
return this.item.welfareType ? this.item.welfareType.replace(/_/g, '-') : '';
}
}
};
</script>
<style lang="scss" scoped>
.welfare-item {
border: 1px solid $gray-tab;
background: white;
.head {
font-size: 13px;
background: $gray-thead;
color: $gray01;
height: 40px;
line-height: 40px;
padding: 0 20px 0;
border-bottom: 1px solid $gray-tab;
label {
color: $gray02;
}
&-type {
margin-right: 20px;
min-width: 100px;
}
}
.content {
height: 115px;
overflow: hidden;
padding: 0;
> div {
float: left;
height: 100%;
display: -webkit-box;
display: flex;
-webkit-box-align: center;
align-items: center;
// padding-top: 12px;
border-right: 1px solid $gray-tab;
&:last-child {
border-right: none;
}
}
label {
color: $gray02;
}
.it1 {
position: relative;
padding-left: 15px;
dl {
flex-shrink: 0;
// padding-left: 110px;
-webkit-box-flex: 1;
flex: 1;
padding-left: 10px;
padding-right: 10px;
color: $gray01;
dd {
line-height: 1;
margin-bottom: 15px;
font-size: 14px;
}
dt {
margin-bottom: 8px;
line-height: 18px;
font-size: 13px;
&:last-child {
margin-bottom: 0;
}
}
}
.cover-image {
// position: absolute;
// left: 20px;
// top: 12px;
flex-shrink: 0;
width: 80px;
height: 80px;
overflow: hidden;
border-radius: 2px;
span {
position: absolute;
background-color: $blue;
left: 0;
top: 0;
z-index: 100;
color: white;
padding: 0 4px;
line-height:20px;
font-size: 12px;
border-radius:2px 0px 6px 0px;
};
}
}
.it2 {
position: relative;
.icon {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: 25px;
display: flex;
color: $blue;
align-items: center;
justify-content: center;
i {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
cursor: pointer;
display: inline-block;
line-height: 14px;
font-size: 12px;
border: 1px solid rgb(196, 198, 207);
width: 16px;
height: 16px;
border-radius: 50%;
text-align: center;
color: $gray03;
&:hover {
color: $blue;
border-color: $blue;
}
}
}
ul {
margin-left: 10px;
margin-right: 25px;
overflow: hidden;
max-height: 80%;
li {
font-size: 13px;
color: $gray01;
line-height: 18px;
margin-bottom: 6px;
text-overflow: ellipsis;
overflow: hidden;
max-width: 100%;
white-space: nowrap;
word-wrap: normal;
&:last-child {
margin-bottom: 0;
}
}
}
}
.it3 {
padding: 12px 10px;
line-height:22px;
color: $gray01;
font-size: 13px;
/deep/ ul {
// margin-left: 10px;
// margin-right: 25px;
overflow: hidden;
max-height: 80%;
width: 100%;
li {
font-size: 13px;
color: $gray01;
line-height: 18px;
margin-bottom: 6px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
&:last-child {
margin-bottom: 0;
}
}
}
}
.it4 {
padding-left: 10px;
padding-right: 10px;
.el-tag {
&.t1 {
color: #FA8C16;
background: #FFF7E6;
border-color: #FFD591;
}
color: $blue;
background: $blue-selected;
position: absolute;
right: 0;
top: -2px;
height: 22px;
line-height: 22px;
}
label {
font-size: 13px;
}
.br {
position: relative;
&::after {
position: absolute;
width: 1px;
background: $gray-tab;
content: '';
height: 100%;
right: 10px;
top: 0;
}
}
/deep/ {
.el-row {
.el-col.oh {
overflow: visible;
}
.el-col {
position: relative;
line-height: 18px;
margin-bottom: 8px;
text-overflow: ellipsis;
overflow: hidden;
max-width: 100%;
white-space: nowrap;
word-wrap: normal;
}
}
}
}
.it5 {
padding-left: 10px;
/deep/ li {
display: block;
margin-left: 0px;
font-size: 13px;
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
}
}
}
.img {
width: 80px;
height: 80px;
}
}
</style>
\ No newline at end of file
import dicMap from '@/assets/dicMap.json';
/**
* 静态值
* 微信卡券
* GCI卡券
*/
/**
* 卡券状态
* optType (1: 创建, 2: 编辑, 3: 调整库存)
* gicAuditingStatus(-1:审核失败,0:未审核(审核中),1:审核通过)
* wxAuditingStatus (-2: 微信创建失败, -1:审核失败,0:未审核(审核中),1:审核通过)
*/
export const cardStatus = {
1: 'GIC审核中', // optType:1 gicAuditingStatus:0 无法操作 详情
2: 'GIC审核失败', // optType:1 gicAuditingStatus:-1 详情删除复制
3: '编辑审核中', // optType:2 gicAuditingStatus:0 无法操作 详情
4: '编辑审核失败', // optType:2 gicAuditingStatus:-1 编辑详情删除复制
5: '调整库存审核中', // optType:3 gicAuditingStatus:0 无法操作 详情
6: '调整库存审核失败', // optType:3 gicAuditingStatus:-1 编辑详情删除复制
7: '微信创建失败', // gicAuditingStatus:1 wxAuditingStatus:-2 编辑详情删除复制
8: '微信审核失败', // gicAuditingStatus:1 wxAuditingStatus:-1 详情删除复制
9: '自定义号段上传中', // gicAuditingStatus:1 wxAuditingStatus:0 customCodeFlag:1 customCodeSyncStatus:1 无法操作 详情
10: '微信审核中', // gicAuditingStatus:1 wxAuditingStatus:0 (customCodeFlag:0) || (customCodeFlag:1 customCodeSyncStatus:0) 无法操作 详情
11: '未生效', // gicAuditingStatus:1 wxAuditingStatus:1 编辑详情删除复制
12: '使用中', // gicAuditingStatus:1 wxAuditingStatus: 1 编辑详情删除复制图表
13: '已过期', // gicAuditingStatus:1 wxAuditingStatus: 1 详情删除复制图表
1: '未生效', // 编辑详情删除复制库存
2: '使用中', // 编辑详情删除复制库存领取记录
3: '已过期', // 详情删除复制领取记录
4: '已禁用', // 详情删除复制领取记录
'-1': '已删除', // 详情复制领取记录
};
/**
......@@ -51,13 +40,17 @@ export const cardType = {
/**
* 核销状态
* 1:转赠中,2:已取消,3:已完成,4::已过期
* 3:已发放,4:已领取,5:已使用,6:已到期,7:已销毁, 8:已占用, 9:转赠中, 10: 已转赠)
*/
export const sendType = {
1: { label: '转赠中', value: 1, cl: 'state-point-loading-scale' },
2: { label: '已取消', value: 2, cl: 'state-point-default' },
3: { label: '已完成', value: 3, cl: 'state-point-success' },
4: { label: '已过期', value: 4, cl: 'state-point-default' }
3: { label: '已发放', value: 1, cl: 'state-point-success' },
4: { label: '已领取', value: 1, cl: 'state-point-success' },
5: { label: '已使用', value: 2, cl: 'state-point-success' },
6: { label: '已到期', value: 3, cl: 'state-point-default' },
7: { label: '已销毁', value: 4, cl: 'state-point-error' },
8: { label: '已占用', value: 1, cl: 'state-point-warning' },
9: { label: '转赠中', value: 2, cl: 'state-point-loading-scale' },
10: { label: '已转赠', value: 3, cl: 'state-point-success' },
};
......@@ -137,46 +130,20 @@ export const startDayOptionsMonth = Object.keys(dicMap.month).map(key => {
// 匹配卡券状态 mapping表中的数据
// wxAuditingStatus -2创建失败 -1审核失败 0审核中 1审核通过
export const mappingCardStatus = (item) => {
const { optType, gicAuditingStatus, wxAuditingStatus, customCodeSyncStatus, customCodeFlag, cardEffectiveMode, expireDate, startDate } = item;
let _status = -1;
// 判断处于哪一个状态
if (gicAuditingStatus === 1) {
// gic审核通过
if (wxAuditingStatus === -2) {
_status = 7;
} else if(wxAuditingStatus === -1) {
_status = 8;
} else if(wxAuditingStatus === 0) {
// 微信审核中
_status = 10;
} else {
// 微信审核成功
if (customCodeFlag === 1 && customCodeSyncStatus === 1) {
_status = 9;
} else {
_status = 12;
// ↑微信创建成功
if (cardEffectiveMode === 0 && expireDate < Date.now()) {
_status = 13; // ↓过期判断 固定日期
}
if (cardEffectiveMode === 0 && startDate > Date.now()) {
_status = 11; // 未生效
}
}
}
const { statusFlag, cardEffectiveMode, expireDate, startDate } = item;
let _status = -1; // eslint-disable-line
if (statusFlag == 2) { // 1: 正常; 2:已禁用
_status = 4;
} else {
if (optType === 1) {
// 创建审核
_status = gicAuditingStatus === 0 ? 1 : 2;
} else if(optType === 2) {
// 编辑审核
_status = gicAuditingStatus === 0 ? 3 : 4;
} else if(optType === 3) {
// 调整库存审核
_status = gicAuditingStatus === 0 ? 5 : 6;
if (cardEffectiveMode === 0 && expireDate < Date.now()) {
_status = 3; // ↓过期判断 固定日期
}
if (cardEffectiveMode === 0 && startDate > Date.now()) {
_status = 1; // 未生效
}
_status = 2;
}
return _status;
item._status = _status;
return item;
};
\ No newline at end of file
......@@ -11,6 +11,7 @@ import filters from '@/filters/index.js';
import { subAppAttr } from '@/mixins/subApp.js';
import store from './store/index';
import mkButton from '@/components/mk-button';
import elImageView from '@/components/libs/el-image-view';
import itemCode from '@/utils/item-code.js';
import { itemPerm, permission } from '@/utils/permission.js';
......@@ -23,6 +24,7 @@ Object.keys(filters).map(item => Vue.filter(item, filters[item])); // 全局注
Vue.mixin(subAppAttr); // 全局注册mixins
// 全局注册组件
Vue.component('mk-button', mkButton);
Vue.component(elImageView.name, elImageView);
// 请求头加isControl参数,否则没有权限
Vue.prototype.axios.interceptors.request.use(config => {
......
......@@ -15,43 +15,21 @@ export default [
},
// 领取记录
{
path: 'log/member-get',
path: 'member-get',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/member-get.vue'),
},
// 转赠列表
{
path: 'log/send-list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/send-list.vue'),
},
// 发放日志
// {
// path: 'log/grant-list',
// component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/grant-list.vue'),
// },
// 发放错误日志
{
path: 'log/grant-error-list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/grant-error-list.vue'),
meta: {
path: '/gic-card/log/grant-list'
}
},
// 卡券库存同步列表
// 库存记录
{
path: 'sync-stock/list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/sync-stock-list.vue'),
path: 'stock-list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/stock-list.vue'),
meta: {
type: 'add',
path: '/gic-card/list'
}
},
// 导入券码失败记录
// 转赠列表
{
path: 'code-error/list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/import-error-list.vue'),
meta: {
path: '/gic-card/list'
}
path: 'send-list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/send-list.vue'),
},
// 步骤页新增卡券
{
......@@ -97,83 +75,7 @@ export default [
type: 'edit',
path: '/gic-card/list'
}
},
// 卡券投放列表
{
path: 'group-send/list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/group-send-list.vue'),
},
// 新建卡券投放
{
path: 'group-send/add',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/group-send-form.vue'),
meta: {
type: 'add',
path: '/gic-card/group-send/list'
}
},
// 卡券投放-记录
{
path: 'group-send/info-log',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/group-send-info.vue'),
meta: {
path: '/gic-card/group-send/list'
}
},
// 卡券投放-详情
{
path: 'group-send/info',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/group-send-form.vue'),
meta: {
type: 'info',
path: '/gic-card/group-send/list'
}
},
// 卡券投放详情--投放失败
{
path: 'group-send/info-fail',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/group-send-fail-list.vue'),
meta: {
path: '/gic-card/group-send/list'
}
},
// 卡券展架列表
{
path: 'shelf/list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/shelf-list.vue'),
},
// 卡券展架新增
{
path: 'shelf/add',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/shelf-form.vue'),
meta: {
type: 'add',
path: '/gic-card/shelf/list'
}
},
// 卡券展架编辑
{
path: 'shelf/edit',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/shelf-form.vue'),
meta: {
type: 'edit',
path: '/gic-card/shelf/list'
}
},
// 展架计划领取详情
{
path: 'shelf/receive-list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/shelf-receive-list.vue'),
meta: {
type: 'edit',
path: '/gic-card/shelf/list'
}
},
// 卡券销毁列表
{
path: 'destroy/list',
component: () => import(/* webpackChunkName: "gic-card" */'@/views/gic-card/destroy-list.vue'),
},
}
],
},
];
\ No newline at end of file
......@@ -57,7 +57,7 @@ async function getAppMenu(menuCode) {
});
const getUserMenu = request({ url: urlList.menu[identifier] }, { appId }).then(res => {
accessPath = getProjectMenu(res.result || []);
store.commit('updateRoutePath', res.result ? res.result[0].children : []); // !!! store中放入route信息
store.commit('updateRoutePath', res.result ? res.result[0].children : []); // warning: 与默认文件不同处 store中放入route信息
});
const getUserOperation = request({ url: urlList.opera[identifier] }, { appId }).then(res => {
itemPermission = getItemPerm(res.result || []);
......@@ -99,6 +99,7 @@ function flatRoutes(routes) {
// 路由跳转拦截
function intercept(to, from, next) {
console.log(to, from);
const hasPerm = accessPath.some(el => {
return el.indexOf('/#') >= 0 ? el == `/#${to.path}` : el == to.path;
});
......
......@@ -29,6 +29,9 @@ const whiteList = [
* @param {*} code ui目前只处理如下code
*/
function handlerErr(code) {
if (process.env['NODE_ENV'] === 'development') { // eslint-disable-line
return;
}
switch (code) {
case 404:
window.location.href = origin + '/damo-system/404';
......@@ -44,7 +47,7 @@ function handlerErr(code) {
axios.defaults.baseURL = origin;
const request = (opt, params, restObj) => {
if ((!Store.state.project || (!Store.state.currentAreaId)) && !whiteList.includes(opt.url) ) {
if ((!Store.state.project || (Store.state.project.includes('card') && !Store.state.currentAreaId)) && !whiteList.includes(opt.url) ) {
// 有左侧但没有选中子应用id || 禁用
return new Promise((resolve, reject) => {
reject();
......
......@@ -99,7 +99,7 @@ export default {
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券包', breadPath: '/gic-card/merge/list' }, { breadName: this.isAdd ? '新建卡券包' : '编辑卡券包', breadPath: '' } ]);
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券包', breadPath: '/card-package/list' }, { breadName: this.isAdd ? '新建卡券包' : '编辑卡券包', breadPath: '' } ]);
},
mounted() {
if(this.currentAreaId) {
......@@ -177,7 +177,7 @@ export default {
savePackages(params, { type }).then(res => {
this.loading = false;
this.$tips({ message: `${ this.isAdd ? '新建' : '编辑' }成功`, type: 'success' });
this.$router.push('/gic-card/merge/list');
this.$router.push('/card-package/list');
}).finally(() => {
this.loading = false;
});
......
......@@ -109,7 +109,7 @@ export default {
},
toSyncList() {
this.visible = false;
this.$router.push(`/gic-card/merge/sync-list?couponPackageId=${this.couponPackageId}`);
this.$router.push(`/card-package/sync-list?couponPackageId=${this.couponPackageId}`);
}
},
watch: {
......
......@@ -44,7 +44,7 @@
import { page, formate } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import api from '@/api/gic-card.js';
const { pagePackageLog, packageCouponReceiveLog } = api;
const { couponLogPage, packageCouponReceiveLog } = api;
export default {
name: 'MergeRecordList',
mixins: [ page, formate ],
......@@ -69,7 +69,7 @@ export default {
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券包' }, { breadName: '卡券包领取记录', breadPath: '/gic-card/merge/record-list' } ]);
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券包', breadPath: '/card-package/list' }, { breadName: '卡券包领取记录', breadPath: '/card-package/record-list' } ]);
},
mounted() {
this.getTableList();
......@@ -96,7 +96,7 @@ export default {
this.loading = true;
this.formatterTimeFunc('beginTime', 'endTime', 'yyyy-MM-dd', 'dateTime');
let params = { ...this.listParams, memberCardId: this.currentAreaId };
pagePackageLog(params).then(res => {
couponLogPage(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
......
......@@ -121,7 +121,7 @@ export default {
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券库', breadPath: '/gic-card/list' }, { breadName: '同步记录' } ]);
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券包', breadPath: '/card-package/list' }, { breadName: '同步记录' } ]);
},
mounted() {
if(this.currentAreaId && this.couponId) {
......
......@@ -10,7 +10,7 @@ import sendPreview from './module/send-preview';
import importCode from './module/import-code';
import commomApi from '@/api/common.js';
const { uploadUrl } = commomApi;
const { addCard, copyCard, cardInfo, checkDemoCode } = api;
const { addCard, copyCard, checkDemoCode } = api;
const { getMallShopList } = commonApi;
// 禁止回车
......@@ -62,7 +62,7 @@ const _ruleForm1 = {
subTitle: '', // 副标题
color: '#3970b5', // 卡券颜色
denomination: 0, // 优惠金额 抵金券0时存在
costValue: 0, // 成本费用 折扣券1、兑换券2存在
costPrice: 0, // 成本费用 折扣券1、兑换券2存在
// manualGetFlag: 0,
// code类型↓
customCodeFlag: 0,
......@@ -102,8 +102,8 @@ const _ruleForm1 = {
cardJumpFlag: 0,
cardJumpLink: '',
stockUseType: 0, // (0:占用,1:动态 , 2占用+动态)
operAuth: 1, // 1所有账号2部分账号3仅创建人
groupIds: []
operAuthType: 1, // 1所有账号2部分账号3仅创建人
operAuth: []
};
const _ruleForm3 = {
......@@ -318,7 +318,7 @@ export default {
giveRule: { required: true, message: '请输入卡券转赠规则', trigger: 'blur' },
giveImage: { required: true, message: '请上传转赠封面', trigger: 'change' },
giveBannerImage: { required: true, message: '请上传转赠页面首图', trigger: 'change' },
costValue: [
costPrice: [
{ required: true, trigger: 'blur', message: '请输入成本' },
{ validator: validMin0, trigger: 'change', message: '成本必须大于0' }
],
......@@ -391,9 +391,6 @@ export default {
if (this.isCopy) {
this.getInfo();
}
if (this.isCopy || this.isAdd) {
this.getCouponId(); // 获取couponId
}
}
},
methods: {
......@@ -472,7 +469,7 @@ export default {
}
if (target === 2) {
// 去往第二步 验证ruleForm1
const { cardEffectiveMode, expireTimeCount, effectTimeMode, dateTime, customCodeFlag, cardType } = this.ruleForm1;
const { cardEffectiveMode, expireTimeCount, effectTimeMode, dateTime, customCodeFlag, cardType, operAuth, operAuthType } = this.ruleForm1;
if(isEmpty(cardEffectiveMode)) {
reject({ message: '请选择有效期类型' });
}
......@@ -511,6 +508,9 @@ export default {
if (customCodeFlag === 2 && this.fileList.length === 0) {
reject({ message: '请上传券码' });
}
if (operAuthType == 2 && !operAuth.length) {
reject({ message: '请选择部分分组账号' });
}
resolve(target);
}
if (target === 3) {
......@@ -603,12 +603,6 @@ export default {
}
},
// 新增获取卡券id
getCouponId() {
cardInfo().then(res => {
this.couponId = res.result.couponId || '';
});
},
checkErpDemoCode() {
this.ruleForm2.erpDemoCode = this.ruleForm2.erpDemoCode.replace(/[^\w\.\/]/gi, '');
},
......@@ -623,7 +617,7 @@ export default {
const coupon = res.result.gicCoupon;
this.coupon = deepClone(coupon) || {}; // 备份数据
// ruleForm1赋值
const exclude = [ 'customCodeFlag', 'couponStock', 'codeBegin', 'codeEnd', 'codePrefix', 'codeSuffix', 'codePrefixFlag', 'codeSuffixFlag' ]; // 不需要赋值的字段
const exclude = [ 'customCodeFlag', 'couponStock', 'codeBegin', 'codeEnd', 'codePrefix', 'codeSuffix', 'codePrefixFlag', 'codeSuffixFlag', 'operAuth' ]; // 不需要赋值的字段
Object.keys(this.ruleForm1).map(key => {
if (key in coupon && !exclude.includes(key)) {
this.ruleForm1[key] = coupon[key];
......@@ -641,6 +635,9 @@ export default {
if (this.ruleForm1.giveFlag && this.ruleForm1.giveBannerJumpUrl) {
this.onSave(this.ruleForm1.giveBannerJumpUrl);
}
if (coupon.operAuthType == 2) {
this.ruleForm1.operAuth = coupon.operAuth.split(',');
}
if (this.ruleForm1.cardJumpFlag) {
this.onSave2(this.ruleForm1.cardJumpLink);
}
......@@ -714,12 +711,14 @@ export default {
let params = { ...this.ruleForm1, ...this.ruleForm2, ...this.ruleForm3, goodsSearchId: this.goodsSearchId };
try {
params.memberCardId = this.currentAreaId;
params.couponId = this.couponId;
// 处理数据
params.getLimit = params.cardLimitRadio === 0 ? params.getLimit : params.cardLimitRadio;
delete params.cardLimitRadio;
// 处理useConditionLimit
params.useConditionLimit = {};
if (params.operAuthType == 2) {
params.operAuth = params.operAuth.join(',');
}
// 1限制 0不限
params.useConditionLimit.goods_adapt_number_min_limit = this.useConditionLimit.goodsDiscountCheckLower ? this.useConditionLimit.goods_adapt_number_min_limit : 0; // eslint-disable-line
params.useConditionLimit.goods_adapt_number_max_limit = this.useConditionLimit.goodsDiscountCheck ? this.useConditionLimit.goods_adapt_number_max_limit : 0; // eslint-disable-line
......
......@@ -56,9 +56,9 @@
<vue-gic-goods-selector-new real-save :waiting-save.sync="goodsSearchIdWaiting" @submit="(res) => { goodsSearchId = res.goodsSelectorId }" force-show-save />
</el-form-item>
<!-- 抵金券、兑换券 -->
<el-form-item prop="costValue" label="成本费用" v-if="ruleForm1.cardType !== 1">
<!-- <el-input-number class="prefix-amount wInput352" controls-position="right" :precision="2" :min="0" v-model="ruleForm1.costValue" /> -->
<dm-input-amount style="width:352px;" v-model="ruleForm1.costValue" :precision="2" :min="0" ></dm-input-amount>
<el-form-item prop="costPrice" label="成本费用" v-if="ruleForm1.cardType !== 1">
<!-- <el-input-number class="prefix-amount wInput352" controls-position="right" :precision="2" :min="0" v-model="ruleForm1.costPrice" /> -->
<dm-input-amount style="width:352px;" v-model="ruleForm1.costPrice" :precision="2" :min="0" ></dm-input-amount>
<span class="tips">请输入大于0的数字(限制两位小数)</span>
</el-form-item>
<el-form-item label="最低适用商品件数">
......@@ -84,6 +84,7 @@
</el-tooltip>
</el-radio>
<el-radio v-model="ruleForm1.customCodeFlag" :label="1">自定义号段</el-radio>
<!-- 20210203 后端 暂时隐藏 TODO: -->
<!-- <el-radio v-model="ruleForm1.customCodeFlag" :label="2" @change="(v) => { if(v == 2) { importVisible = true } }">
<span @click="ruleForm1.customCodeFlag = 2;importVisible = true">导入券码</span>
<span class="gray03 cursor" v-if="fileList.length > 0">
......@@ -218,7 +219,7 @@
</el-checkbox-group>
</el-form-item>
<el-form-item label="操作人权限">
<dm-acc-group-select :etype.sync="ruleForm1.operAuth" :group-ids.sync="ruleForm1.groupIds" />
<dm-acc-group-select :etype.sync="ruleForm1.operAuthType" :group-ids.sync="ruleForm1.operAuth" />
</el-form-item>
<el-form-item class="pt10">
<el-button class="w85" type="primary" @click="changeStep(2, 'ruleForm1')">下一步</el-button>
......
......@@ -84,6 +84,8 @@ export default {
importVisible: false, // 导入券码model
fileList: [], // 导入券码的的文件的列表
linkData: {}, // 首图链接
linkData2: {}, // 跳转配置
operAuth: []
};
},
created() {
......@@ -181,23 +183,29 @@ export default {
this.$emit('updateLoading', true);
cardInfo({ couponId: this.couponId }).then((res) => {
if (type === 'code') {
this.info.couponStock = res.result.gicCoupon.couponStock || 0;
this.info.couponStock = res.result.couponStock || 0;
return;
}
const info = res.result.gicCoupon || {};
const info = res.result || {};
if (info.operAuthType == 2) {
this.operAuth = info.operAuth.split(',');
}
info.useConditionLimit = info.useConditionLimit ? JSON.parse(info.useConditionLimit) : {};
this.info = info;
// 给可以编辑的属性赋值
Object.keys(this.ruleForm).map(key => {
if (key in res.result.gicCoupon) {
this.ruleForm[key] = res.result.gicCoupon[key] || '';
if (key in info) {
this.ruleForm[key] = info[key] || '';
}
});
if (this.info.giveFlag && this.info.bannerJumpUrl) {
this.linkData = JSON.parse(this.info.bannerJumpUrl);
if (this.info.giveFlag && this.info.giveBannerJumpUrl) {
this.linkData = JSON.parse(this.info.giveBannerJumpUrl);
}
if (this.info.cardJumpFlag && this.info.cardJumpLink) {
this.linkData2 = JSON.parse(this.info.cardJumpLink);
}
// 给卡券适用信息赋值
this.info.applyList.forEach(v => {
info.applyList.forEach(v => {
const { applyType, feeLimit, onlyFlag, maxDiscountAmount, maxDiscountGoodsCount, goodsFilterId, storeFilterId, shopFilter } = v;
if (applyType === 1) {
// 线下适用
......@@ -208,7 +216,6 @@ export default {
storeFilterId,
goodsFilterId,
};
// TODO:初始化门店选择器和商品选择器
}
if (applyType === 2) {
let shop;
......@@ -227,20 +234,7 @@ export default {
maxDiscountGoodsCount,
shopFilter: shop
};
// TODO:初始化商品选择器
}
// if (applyType === 3) {
// // 微盟微商城适用
// this.wmmall = {
// switch: true,
// feeLimit,
// onlyFlag,
// goodsFilterId,
// maxDiscountAmount,
// maxDiscountGoodsCount
// }
// // TODO:初始化商品选择器
// }
});
this.loading = false;
this.$emit('updateLoading', false);
......
......@@ -36,7 +36,7 @@
</el-form-item>
<el-form-item label="减免金额" v-if="info.cardType === 0">{{ info.denomination }}</el-form-item>
<el-form-item label="优惠折扣" v-if="info.cardType === 1">{{ info.denomination }}</el-form-item>
<el-form-item label="成本费用" v-if="info.cardType !== 1">{{ info.costValue }}</el-form-item>
<el-form-item label="成本费用" v-if="info.cardType !== 1">{{ info.costPrice }}</el-form-item>
<el-form-item v-if="info.useConditionLimit" label="最低适用商品件数">{{ info.useConditionLimit.goods_adapt_number_min_limit ? `${info.useConditionLimit.goods_adapt_number_min_limit} 件` : '不限' }}</el-form-item>
<el-form-item v-if="info.useConditionLimit" label="最高适用商品件数">{{ info.useConditionLimit.goods_adapt_number_max_limit ? `${info.useConditionLimit.goods_adapt_number_max_limit} 件` : '不限' }}</el-form-item>
<el-form-item label="code类型">{{ info.customCodeFlag === 0 ? '随机生成' : '自定义号段' }}</el-form-item>
......@@ -56,24 +56,35 @@
<el-switch disabled :active-value="1" :inactive-value="0" v-model="info.manualGetFlag"></el-switch>
</el-form-item>
<el-form-item label="转赠开关">
<el-switch disabled :active-value="1" :inactive-value="0" v-model="info.giveFlag"></el-switch>
<el-button type="text" class="ml15" v-if="info.giveFlag" @click="preview.visible = true">预览</el-button>
</el-form-item>
<el-switch disabled :active-value="1" :inactive-value="0" v-model="info.giveFlag"></el-switch>
<el-button type="text" class="ml15" v-if="info.giveFlag" @click="preview.visible = true">预览</el-button>
</el-form-item>
<template v-if="info.giveFlag === 1">
<el-form-item label="转赠对话框图片">
<dm-el-image-view v-if="info.giveImage" class="img-wrap ml15" style="width: 100px; height: 100px" :src="info.giveImage" fit="fill" />
</el-form-item>
<el-form-item label="转赠页面首图">
<dm-el-image-view v-if="info.bannerImage" class="img-wrap ml15" style="width: 100px; height: 100px" :src="info.bannerImage" fit="fill" />
<dm-el-image-view v-if="info.giveBannerImage" class="img-wrap ml15" style="width: 100px; height: 100px" :src="info.giveBannerImage" fit="fill" />
</el-form-item>
<template v-if="info.giveFlag === 1">
<el-form-item label="转赠对话框文字">{{ info.giveContent }}</el-form-item>
<el-form-item label="卡券转赠规则">
<pre>{{ info.giveRule }}</pre>
</el-form-item>
<el-form-item label="转赠首图链接"><span v-if="info.bannerJumpUrl">{{ linkData.name || '--' }}】【{{ linkData.url || '--' }}</span><span v-else>未添加</span></el-form-item>
<el-form-item label="转赠首图链接"><span v-if="info.giveBannerJumpUrl">{{ linkData.name || '--' }}】【{{ linkData.url || '--' }}</span><span v-else>未添加</span></el-form-item>
</template>
</template>
<el-form-item label="跳转配置">
<el-switch disabled :active-value="1" :inactive-value="0" v-model="info.cardJumpFlag"></el-switch>
<span v-if="info.cardJumpFlag" class="gray03 ml10" :title="linkData2.url">{{ linkData2.name || '--' }}】【{{ linkData2.url || '--' }}</span>
</el-form-item>
<el-form-item label="库存消耗方式">
<!-- 0:占用,1:动态 , 2占用+动态) -->
{{ info.stockUseType == 0 ? '固定库存' : info.stockUseType == 1 ? '实时库存' : '固定+实时库存' }}
</el-form-item>
<el-form-item label="操作人权限">
<dm-acc-group-select :etype.sync="info.operAuthType" :group-ids.sync="operAuth" read-only />
</el-form-item>
</el-col>
</el-row>
<p class="title mt60" id="f2">卡券适用信息</p>
......
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-date-picker class="w400 mr10" v-model="dateTime" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
<!-- <el-select class="w160 mr10" v-model="listParams.destoryMode" clearable placeholder="所有销毁方式" @change="refresh">
<el-option v-for="(item, index) in destoryType" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select> -->
<el-input v-model="listParams.search" class="w300 mrAuto" placeholder="请输入卡券名称" clearable @change="refresh"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<dm-perm-button icon="iconfont-market4 icon-icon_yunxiazai mr5" :disabled="$itemPerm($itemCode.gicCardDestory)" type="danger" @click="showDialog('add', {})">卡券销毁</dm-perm-button>
</div>
<el-table tooltip-effect="dark" :data="tableList" style="width:100%">
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] || '--' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="left" width="120px" fixed="right">
<template slot-scope="scope">
<dm-perm-button type="text" @click="showExport(scope.row)" :disabled="$itemPerm($itemCode.gicCardDestoryExport)">导出结果</dm-perm-button>
</template>
</el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
<destory-dialog :show.sync="dialog.show" v-bind="dialog" @refresh="getTableList" />
<dm-export-data ref="exportData" :visible.sync="exportVisible" :sens-value="true" :fields="fields" :label="label" :value="value" :sens-key="sensKey" :loading="loading" :is-created="isCreated" @export="onExport" @closed="isCreated = false" :default-select-keys="defaultSelectKeys"></dm-export-data>
</div>
</template>
<script>
import { page, formate } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import fetch from '@/api/gic-card.js';
import { dealExportParams } from '@/utils/common.js';
import destoryDialog from './module/destory-dialog';
const { cardDestoryList, exportDestroyLogExcel } = fetch;
export default {
name: 'SendList',
components: {
destoryDialog
},
mixins: [ page, formate ],
props: {
dialogVisible: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false,
dateTime: [],
listParams: {
beginTime: '',
endTime: '',
search: '',
destoryMode: '',
currentPage: 1,
pageSize: 20
},
// destoryType: [{ value: 0, label: '全部销毁' }, { value: 1, label: '部分销毁' }], // eslint-disable-line
total: 0,
dialog: {
show: false,
destoryItem: '',
type: 'add'
},
tableList: [],
tableHeader: [
{
label: '卡券名称',
minWidth: '120',
align: 'left',
fixed: 'left',
formatter: function(row) {
return `<span p-key="couponId" title="${row.couponId}">${ row.cardName }</span>`;
}
},
{
label: '销毁时间',
minWidth: '120',
align: 'left',
formatter: function(row) {
return listTime(row.createTime);
}
},
{
label: '销毁方式',
minWidth: '120',
align: 'left',
formatter: function(row) {
// 卡券销毁方式(0:全部销毁,1:部分销毁)
return row.destroyMode ? '部分销毁' : '全部销毁';
}
},
{
label: '计划销毁数量',
minWidth: '120',
align: 'left',
formatter: function(row) {
return (row.sucessCount + row.failCount) || '--';
}
},
{
label: '销毁结果',
minWidth: '120',
align: 'left',
formatter: function(row) {
return `<p>成功:<span style="color:#33af4a;">${ row.sucessCount }</span></p>
<p>失败:<span style="color:#F5222D;">${ row.failCount }</span></p>`;
}
}
],
// 导出组件
exportDestroyPlanId: '',
exportVisible: false,
isCreated: false,
// eslint-disable-next-line
fields: [{label:'券码',value:'cardCode',sensKey:false},{label:'销毁结果', value: 'destroyRemark', sensKey: false},{label:'错误信息',value:'errMsg',sensKey:false}],
sensKey: 'sensKey',
defaultSelectKeys: [ 'cardCode', 'destroyRemark', 'errMsg' ],
// sensValue: '',
label: 'label',
value: 'value'
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券销毁列表' } ]);
},
mounted() {
this.getTableList();
},
methods: {
showDialog(type, destoryItem) {
this.dialog.type = type;
this.dialog.show = true;
if (type !== 'add') {
this.dialog.destoryItem = destoryItem;
}
},
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
this.formatterTimeFunc('beginTime', 'endTime', 'yyyy-MM-dd', 'dateTime');
let params = { ...this.listParams, ...{ memberCardId: this.currentAreaId } };
cardDestoryList(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
},
// ********数据导出*************
showExport({ destroyPlanId }) {
// if(!this.tableList.length) {
// this.$tips({ message: '没有要导出的数据', type: 'warning' });
// return;
// }
this.exportDestroyPlanId = destroyPlanId;
this.exportVisible = true;
},
onExport(config) {
let params = dealExportParams({ config, listParams: { destroyPlanId: this.exportDestroyPlanId }, fieldList: this.fields, path: this.$route.path, pathName: 'GIC卡券-卡券销毁记录', query: { areaId: this.currentAreaId } });
console.log(params);
// 将config转换为请求参数
// const params = config;
// 导出数据完成后,必须调导出组件的applyReport方法
// applyReport方法的第一个参数表示是否生成导出数据,第二个参数为导出数据的id
exportDestroyLogExcel(params).then(res => {
this.$refs.exportData.applyReport(true, res.result);
}).catch(err => {
this.$refs.exportData.applyReport();
});
}
},
};
</script>
<template>
<div class="marking-logs" v-loading="loading">
<header>
<div>
<el-select v-model="listParams.module" placeholder="来源模块" @change="moduleChange" clearable>
<el-option v-for="(item, i) in moduleList" :key="i" :label="item" :value="i"></el-option>
</el-select>
<el-input
type="text"
placeholder="请输入来源明细"
prefix-icon="el-icon-search"
style="width: 180px;margin-right:10px"
v-model.trim="listParams.detail"
clearable
@change="refresh">
</el-input>
<!-- <el-select v-model="listParams.type" placeholder="营销类型" @change="refresh" clearable>
<el-option label="短信" value="sms"></el-option>
<el-option label="微信客服接口" value="wx_custom_send"></el-option>
<el-option label="微信群发接口" value="wx_mass_send"></el-option>
<el-option label="微信模板消息" value="wx_tmpl"></el-option>
</el-select> -->
<el-date-picker
v-model="listParams.sDate"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="refresh"
clearable>
</el-date-picker>
<el-input
type="text"
placeholder="请输入卡券名称/卡券代码/用户信息"
prefix-icon="el-icon-search"
style="width: 280px"
v-model.trim="listParams.input"
clearable
@change="refresh">
</el-input>
</div>
</header>
<el-table :data="tableData" style="width: 100%">
<el-table-column show-overflow-tooltip prop="failLogId" label="日志id"></el-table-column>
<el-table-column show-overflow-tooltip prop="appName" label="来源模块"></el-table-column>
<el-table-column show-overflow-tooltip prop="appActivityName" label="来源明细"></el-table-column>
<el-table-column show-overflow-tooltip label="发放时间">
<template slot-scope="{row}">
<div v-html="listTime(row.createTime)"></div>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip label="会员信息" min-width="180">
<template slot-scope="{row}">
<member-info :member-name="row.memberName" :member-image="row.memberImage" :member-phone="row.memberPhone"></member-info>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip label="卡券类型">
<template slot-scope="{row}">
{{ [ '抵金券', '折扣券', '兑换券' ][row.cardType] }}
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="cardName" label="卡券名称"></el-table-column>
<el-table-column show-overflow-tooltip label="发放状态"><span>失败</span></el-table-column>
<el-table-column show-overflow-tooltip prop="errorMsg" label="备注"></el-table-column>
</el-table>
<dm-pagination
v-if="listParams.total > 0"
:total="listParams.total"
:page-sizes="listParams.pageSizes"
:page-size="listParams.pageSize"
:current-page="listParams.currentPage"
background
layout="total,sizes,prev,pager,next"
style="text-align: right"
@current-change="handleCurrentChange"
@size-change="handleSizeChange">
</dm-pagination>
</div>
</template>
<script>
import { page, formate } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import fetch from '@/api/gic-card.js';
const { getCouponSendFailLogList, getMarketAppcodes } = fetch;
export default {
name: 'MarkingLogs',
mixins: [ page, formate ],
data() {
return {
loading: false,
listParams: {
module: '',
detail: '',
type: '',
sDate: '',
input: '',
total: 0,
pageSizes: [ 20, 40, 60, 80 ],
pageSize: 20,
currentPage: 1
},
moduleList: [],
tableData: [],
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券日志' }, { breadName: '卡券发放失败日志' } ]);
this.getTableList();
this.getMarketAppcodes();
},
methods: {
listTime,
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
const { module, detail, sDate, input, currentPage, pageSize } = this.listParams;
let params = {
appCode: module,
appActivityName: detail,
beginTime: sDate ? sDate[0] : undefined,
endTime: sDate ? sDate[1] : undefined,
memberCardId: this.currentAreaId,
search: input,
currentPage,
pageSize
};
getCouponSendFailLogList(params).then(res => {
const { result, totalCount } = res.result || {};
this.tableData = result || [];
this.listParams.total = totalCount;
}).finally(_ => this.loading = false);
},
getMarketAppcodes() {
getMarketAppcodes().then(res => {
this.moduleList = res.result || {};
});
},
moduleChange() {
this.listParams.detail = '';
this.refresh();
}
}
};
</script>
<style lang="scss">
.marking-logs {
padding: 20px;
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.el-select {
width: 140px;
margin-right: 10px;
}
.el-date-editor {
width: 320px;
margin-right: 10px;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="marking-logs" v-loading="loading">
<header>
<div>
<el-select v-model="listParams.module" placeholder="来源模块" @change="moduleChange" clearable>
<el-option v-for="(item, i) in moduleList" :key="i" :label="item" :value="i"></el-option>
</el-select>
<el-input
type="text"
placeholder="请输入来源明细"
prefix-icon="el-icon-search"
style="width: 180px;margin-right:10px"
v-model.trim="listParams.detail"
clearable
@change="refresh">
</el-input>
<!-- <el-select v-model="listParams.type" placeholder="营销类型" @change="refresh" clearable>
<el-option label="短信" value="sms"></el-option>
<el-option label="微信客服接口" value="wx_custom_send"></el-option>
<el-option label="微信群发接口" value="wx_mass_send"></el-option>
<el-option label="微信模板消息" value="wx_tmpl"></el-option>
</el-select> -->
<el-date-picker
v-model="listParams.sDate"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="refresh"
clearable>
</el-date-picker>
<el-input
type="text"
placeholder="请输入卡券名称/卡券代码/用户信息"
prefix-icon="el-icon-search"
style="width: 280px"
v-model.trim="listParams.input"
clearable
@change="refresh">
</el-input>
</div>
<el-button type="primary" @click="$router.push('/gic-card/log/grant-error-list')">发放失败记录</el-button>
</header>
<el-table :data="tableData" style="width: 100%">
<el-table-column show-overflow-tooltip prop="couponLogId" label="日志id"></el-table-column>
<el-table-column show-overflow-tooltip prop="appName" label="来源模块"></el-table-column>
<el-table-column show-overflow-tooltip prop="appActivityName" label="来源明细"></el-table-column>
<el-table-column show-overflow-tooltip prop="sendTime" label="发放时间">
<template slot-scope="{row}">
<div v-html="listTime(row.createTime)"></div>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="memberName" label="会员信息" min-width="180">
<template slot-scope="{row}">
<member-info :member-name="row.memberName" :member-image="row.memberImage" :member-phone="row.memberPhone"></member-info>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="marketTypeRemark" label="卡券类型">
<template slot-scope="{row}">
{{ [ '抵金券', '折扣券', '兑换券' ][row.cardType] }}
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="cardName" label="卡券名称"></el-table-column>
<el-table-column show-overflow-tooltip prop="marketTypeRemark" label="发放状态">成功</el-table-column>
</el-table>
<dm-pagination
v-if="listParams.total > 0"
:total="listParams.total"
:page-sizes="listParams.pageSizes"
:page-size="listParams.pageSize"
:current-page="listParams.currentPage"
background
layout="total,sizes,prev,pager,next"
style="text-align: right"
@current-change="handleCurrentChange"
@size-change="handleSizeChange">
</dm-pagination>
</div>
</template>
<script>
import { page, formate } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import fetch from '@/api/gic-card.js';
const { getCouponSendLogList, getMarketAppcodes } = fetch;
export default {
name: 'MarkingLogs',
mixins: [ page, formate ],
data() {
return {
loading: false,
listParams: {
module: '',
detail: '',
type: '',
sDate: '',
input: '',
total: 0,
pageSizes: [ 20, 40, 60, 80 ],
pageSize: 20,
currentPage: 1
},
moduleList: [],
tableData: [],
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券日志' }, { breadName: '卡券发放日志' } ]);
this.getTableList();
this.getMarketAppcodes();
},
methods: {
listTime,
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
const { module, detail, sDate, input, currentPage, pageSize } = this.listParams;
let params = {
appCode: module,
appActivityId: detail,
beginTime: sDate ? sDate[0] : undefined,
endTime: sDate ? sDate[1] : undefined,
memberCardId: this.currentAreaId,
search: input,
currentPage,
pageSize
};
getCouponSendLogList(params).then(res => {
const { result, totalCount } = res.result || {};
this.tableData = result || [];
this.listParams.total = totalCount;
}).finally(_ => this.loading = false);
},
getMarketAppcodes() {
getMarketAppcodes().then(res => {
this.moduleList = res.result || {};
});
},
moduleChange() {
this.listParams.detail = '';
this.refresh();
},
}
};
</script>
<style lang="scss">
.marking-logs {
padding: 20px;
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.el-select {
width: 140px;
margin-right: 10px;
}
.el-date-editor {
width: 320px;
margin-right: 10px;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="p20" v-loading="loading">
<el-table tooltip-effect="dark" :data="tableList" style="width:100%">
<el-table-column show-overflow-tooltip prop="memberName" label="会员信息" min-width="180" fixed="left">
<template slot-scope="{row}">
<member-info :member-name="row.memberName" :member-image="row.memberImage" :member-phone="row.memberPhone"></member-info>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="memberName" label="卡券信息" min-width="120">
<div slot-scope="scope" v-html="formatCardMess(scope.row)"></div>
</el-table-column>
<el-table-column label="投放时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.createTime)"></span>
</el-table-column>
<el-table-column prop="errorMsg" label="失败原因" min-width="120"> </el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
</div>
</template>
<script>
import { page, formate } from '@/mixins/table.js';
import { cardType } from '@/config/mapping/gic-card';
import { listTime } from '@/utils/index.js';
import api from '@/api/gic-card.js';
const { couponPutonFailLogList } = api;
export default {
name: 'GroupSendInfo',
mixins: [ page, formate ],
data() {
return {
loading: false,
listParams: {
couponPlanId: this.$route.query.id,
currentPage: 1,
pageSize: 20,
},
tableList: [],
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券投放', breadPath: '/gic-card/group-send/list' }, { breadName: '卡券投放记录', breadPath: `/gic-card/group-send/info-log?id=${this.$route.query.id}` }, { breadName: '卡券投放失败' } ]);
},
mounted() {
if(this.currentAreaId && this.listParams.couponPlanId) {
this.getTableList();
}
},
methods: {
listTime,
formatCardMess(row) {
const _cardType = cardType[row.cardType] || {};
return `<p class="fz14">${row.cardName}</p><p class="fz12">${_cardType.label}</p>`;
},
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
let params = { ...this.listParams, memberCardId: this.currentAreaId };
couponPutonFailLogList(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.loading = false;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
}
},
};
</script>
<template>
<div class="p20" v-loading="loading">
<el-form :model="ruleForm" ref="ruleForm" :rules="rules" label-width="120px" class="group-form pt10 pb10">
<el-form-item class="mass-input" label="计划名称" prop="name">
<dm-input :disabled="isInfo" v-model="ruleForm.name" :byte-type="1" :maxlength="20" class="w380" />
</el-form-item>
<el-form-item label="数据对话">
<activity-select :no-add="isInfo" :disabled="isInfo" :act-id.sync="ruleForm.mktActivityId" width="380"></activity-select>
</el-form-item>
<el-form-item class="is-required" label="发送时间" prop="putOnType">
<el-radio-group :disabled="isInfo" v-model="ruleForm.putOnType">
<el-radio v-for="item in putOnType" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="" prop="putOnTime" v-if="ruleForm.putOnType === 1">
<el-date-picker :disabled="isInfo" class="w380" v-model="ruleForm.putOnTime" popper-class="hide-right-now" type="datetime" :picker-options="pickerOptions" placeholder="选择日期时间" />
</el-form-item>
<el-form-item label="发送人群" class="is-required">
<dm-new-people force-show-save :disabled="isInfo" :waiting-save.sync="waitingSave" :region-id="currentAreaId" :resource="3" :reback-flag="rebackFlag" :re-id="ruleForm.memberSearchId" ref="newPeople" @pass-people-data="receivePeopleData" @reset-condition="ruleForm.memberSearchId = ''" />
</el-form-item>
<el-form-item label="通知内容">
<dm-market-event-new :read-only="isInfo" ref="mk" v-if="ruleForm.couponPlanId && currentAreaIds.length" max="1" app-code="coupon-gic" fix-member-card :member-card-ids="currentAreaIds" :mode="mode" :relation-id="ruleForm.couponPlanId" dash-width="380" @saveBack="saveBack" />
</el-form-item>
<el-form-item class="pt10" v-if="isAdd">
<el-button type="primary" @click="checkForm">{{ needCheck ? '新建并提交审核' : '确认新建' }}</el-button>
<el-button @click="$router.go(-1)">返回</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import activitySelect from '@/components/activity-select/index';
import commonApi from '@/api/common.js';
import { showConfirm } from '@/utils/common';
const { getRelationId, getMemberCount } = commonApi;
import { formatDateTimeByType } from '@/utils/index';
import api from '@/api/gic-card.js';
const { groupSendAdd, groupSendInfo } = api;
export default {
name: 'GroupSend',
components: {
activitySelect
},
data() {
const validTime = (rule, value, callback) => {
if (new Date(value).getTime() < new Date().getTime()) {
callback(new Error('发送时间不能小于当前时间'));
}
callback();
};
return {
couponId: this.$route.query.couponId,
loading: false,
mode: [ 10 ],
putOnType: [ { label: '立即发送', value: 0 }, { label: '定时发送', value: 1 } ],
selectedScenes: '',
ruleForm: {
couponPlanId: '',
name: '',
putOnType: 0, // (0:立即发送,1:定时发送)
putOnTime: '', // 定时发送时间格式
memberSearchId: '',
mktActivityId: '',
},
rebackFlag: false,
waitingSave: true, // 人群筛选器是否在保存中
rules: {
name: [ { required: true, message: '请输入计划名称', trigger: 'blur' } ],
// memberSearchId: [{ required: true, message: '请筛选人群筛选器数据', trigger: 'change' }],
putOnTime: [ { required: true, message: '请输入发送时间', trigger: 'blur' }, { validator: validTime, trigger: 'blur' } ]
},
needCheck: false, // 是否需要审核
pickerOptions: {
disabledDate(val) {
return Date.now() >= val.getTime() + 24 * 60 * 60 * 1000;
}
},
saveByAuto: false, // 是否通过query 自动调取mk的数据默认选中卡券
isAdd: this.$route.meta.type === 'add',
isInfo: this.$route.meta.type === 'info',
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券投放', breadPath: '/gic-card/group-send/list' }, { breadName: `${this.isInfo ? '卡券投放详情' : '新建卡券投放'}` } ]);
},
mounted() {
if(this.currentAreaId) {
if(this.isAdd) {
this.getNeedCheck();
this.getRelationId();
}
if(this.isInfo) {
this.getInfo();
}
}
},
methods: {
// 获取详情
getInfo() {
if(this.loading) {
return;
}
this.loading = true;
groupSendInfo({ couponPlanId: this.$route.query.id }).then(res => {
this.loading = false;
this.ruleForm = res.result || {};
if(res.result.memberCardId) {
this.rebackFlag = true;
this.waitingSave = false;
}
}).finally(() => {
this.loading = false;
});
},
receivePeopleData(data) {
this.ruleForm.memberSearchId = data.peopleId;
this.$refs.ruleForm.validateField('memberSearchId');
},
// 新建
submitForm() {
if(this.loading) {
return;
}
this.loading = true;
let params = { ...this.ruleForm, memberCardId: this.currentAreaId };
// params.couponId = mkList[0].revealData.couponId;
if (params.putOnType === 0) {
delete params.putOnTime;
} else {
params.putOnTime = formatDateTimeByType(params.putOnTime);
}
groupSendAdd(params).then(res => {
this.loading = false;
this.$tips({ message: '新建成功', type: 'success' });
this.$router.push('/gic-card/group-send/list');
}).finally(() => {
this.loading = false;
});
},
checkForm(){
this.$refs.ruleForm.validate((valid) => {
if(!valid){
PublicMethods.jumpToFormError(); // eslint-disable-line
return;
} else {
if(!this.ruleForm.memberSearchId) {
this.$tips({ message: '请保存人群筛选器', type: 'error' });
return;
} else if(this.waitingSave) {
this.$tips({ message: '人群筛选器处于编辑状态,请保存', type: 'error' });
return;
}
const mkList = this.$refs.mk.getSaveList();
if(mkList.length != 1) {
this.$tips({ message: '请保存通知内容', type: 'error' });
return;
}
this.loading = true;
getMemberCount({ memberSearchId: this.ruleForm.memberSearchId, appCode: this.$store.getters.moduleCode, areaId: this.currentAreaId }).then(res => {
this.loading = false;
const count = res.result || 0;
if(!count) {
// 人数为0定时可以新建,实时不可以this.ruleForm.putOnType === 0 &&
this.$tips({ message: '发送人数为0,请重新选择发送人群', type: 'warning' });
return;
}
showConfirm(`<div>合计发送 ${count} 人,确认发送?</div>`, () => {
this.submitForm();
}, ()=> {
return;
});
}).finally(() => {
this.loading = false;
});
}
});
},
// 获取审核配置
getNeedCheck() {
// getAuditInfo({ memberCardId: this.currentAreaId }).then(res => {
// if(res.result) {
// this.needCheck = res.result || false; // true:需要审核,false:不需要审核
// }
// })
},
getRelationId() {
getRelationId().then(res => {
this.ruleForm.couponPlanId = res.result || '';
});
},
// ***营销事件通知****
saveBack() {
// type: 10-gic卡券 1: 9-微信卡券
if(this.$route.query.couponId && !this.saveByAuto) {
this.saveByAuto = true; // 通过url的query保存过
this.$refs.mk.saveItem({ prizeNoticeFlag: 1, prizeId: this.$route.query.couponId, type: 10 });
}
}
},
};
</script>
<style lang="scss" scoped>
.w380 {
/deep/ {
.ev-select, .el-input {
width: 380px;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-input class="vertical-middle w250 mr10" v-model="listParams.search" clearable placeholder="请输入会员姓名/卡号" @change="refresh"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<el-select class="dm-select mrAuto w140" clearable v-model="listParams.status" placeholder="所有卡券状态" @change="refresh">
<el-option v-for="(v, i) in sendCardStatus" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<el-button class="ml10" @click="$router.push(`/gic-card/group-send/info-fail?id=${listParams.couponPlanId}`)">卡券投放失败列表</el-button>
<el-button type="primary" icon="iconfont-market4 icon-icon_yunxiazai mr5" @click="showExport">数据导出</el-button>
</div>
<div class="table-search-head">
领取时间:<el-date-picker class="w300 mr10" v-model="dateTime" type="daterange" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
核销时间:<el-date-picker class="w300 mrAuto" v-model="dateTime2" type="daterange" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
</div>
<el-table tooltip-effect="dark" :data="tableList" :max-height="mainHeight(52 + 50)" style="width:100%">
<el-table-column show-overflow-tooltip prop="memberName" label="会员信息" min-width="180" fixed="left">
<template slot-scope="{row}">
<member-info :member-name="row.memberName" :member-image="row.memberImage" :member-phone="row.memberPhone"></member-info>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip label="卡券状态" min-width="120">
<div slot-scope="scope" v-html="formatCardStatus(scope.row)"></div>
</el-table-column>
<el-table-column show-overflow-tooltip prop="memberName" label="卡券信息" min-width="120">
<div slot-scope="scope" v-html="formatCardMess(scope.row)"></div>
</el-table-column>
<el-table-column prop="wxCardCode" label="卡券代码" min-width="120"> </el-table-column>
<el-table-column prop="verifyOrderNumber" label="订单流水号" min-width="120"> </el-table-column>
<el-table-column label="领取时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.receiveTime)"></span>
</el-table-column>
<el-table-column label="核销时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.verifyTime)"></span>
</el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
<dm-export-data ref="exportData" :visible.sync="exportVisible" :sens-value="true" :fields="fields" :label="label" :value="value" :sens-key="sensKey" :loading="loading" :is-created="isCreated" @export="onExport" @closed="isCreated = false"></dm-export-data>
</div>
</template>
<script>
import { page, formate, getMainHeight } from '@/mixins/table.js';
import { sendCardStatus, cardType } from '@/config/mapping/gic-card';
import { listTime } from '@/utils/index.js';
import { dealExportParams } from '@/utils/common.js';
import api from '@/api/gic-card.js';
const { groupSendInfoLog, exportCouponPutonLog } = api;
export default {
name: 'GroupSendInfo',
mixins: [ page, formate, getMainHeight ],
data() {
return {
loading: false,
dateTime: [ , ],
dateTime2: [ , ],
listParams: {
search: '',
couponPlanId: this.$route.query.id,
status: '',
currentPage: 1,
pageSize: 20,
verifyBeginTime: '',
verifyEndTime: '',
receiveBeginTime: '',
receiveEndTime: '',
},
sendCardStatus: Object.keys(sendCardStatus).map(v => { return sendCardStatus[v]; }),
tableList: [],
// 导出组件
exportVisible: false,
isCreated: false,
// eslint-disable-next-line
fields: [{label:'会员头像', value: 'memberImage', sensKey: false},{label:'会员名称',value:'memberName',sensKey:false},{label:'会员手机号码',value:'memberPhone',sensKey:true},{label:'卡券状态',value:'statusRemark',sensKey:false},{label:'卡券名称',value:'cardName',sensKey:false},{label:'卡券类型',value:'cardTypeRemark',sensKey:false},{label:'卡券代码',value:'wxCardCode',sensKey:false},{label:'订单流水号',value:'verifyOrderNumber',sensKey:false},{label:'领取时间',value:'receiveTimeRemark',sensKey:false},{label:'核销时间',value:'verifyTimeRemark',sensKey:false}],
sensKey: 'sensKey',
// sensValue: '',
label: 'label',
value: 'value'
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券投放', breadPath: '/gic-card/group-send/list' }, { breadName: '卡券投放记录' } ]);
},
mounted() {
if(this.currentAreaId && this.listParams.couponPlanId) {
this.getTableList();
}
},
methods: {
listTime,
formatCardStatus(row) {
const _status = sendCardStatus[row.status] || {};
return `<span class="state-point ${_status.cl}">${_status.label}</span>`;
},
formatCardMess(row) {
const _cardType = cardType[row.cardType] || {};
return `<p class="fz14">${row.cardName}</p><p class="fz12">${_cardType.label}</p>`;
},
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
this.formatterTimeFunc('receiveBeginTime', 'receiveEndTime', 'yyyy-MM-dd', 'dateTime');
this.formatterTimeFunc('verifyBeginTime', 'verifyEndTime', 'yyyy-MM-dd', 'dateTime2');
let params = { ...this.listParams, ...{ memberCardId: this.currentAreaId } };
groupSendInfoLog(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
},
// ********数据导出*************
showExport() {
if(!this.tableList.length) {
this.$tips({ message: '没有要导出的数据', type: 'warning' });
return;
}
this.exportVisible = true;
},
onExport(config) {
const params = dealExportParams({ config, listParams: this.listParams, fieldList: this.fields, path: this.$route.path, pathName: 'GIC卡券-卡券投放记录', query: { id: this.$route.query.id, areaId: this.currentAreaId } });
exportCouponPutonLog(params).then(res => {
this.$refs.exportData.applyReport(true, res.result);
}).catch(err => {
this.$refs.exportData.applyReport();
});
}
},
};
</script>
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-select class="dm-select mr10 w140" clearable v-model="listParams.status" placeholder="所有状态" @change="refresh">
<el-option v-for="(v, i) in sendStatus" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<el-input class="vertical-middle w300 mrAuto" v-model="listParams.search" clearable placeholder="请输入创建人/计划名称" @change="refresh"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<dm-perm-button type="primary" @click="$router.push('/gic-card/group-send/add')" :disabled="$itemPerm($itemCode.gicCardGroupSendForm)">新建卡券投放</dm-perm-button>
</div>
<el-table tooltip-effect="dark" :data="tableList" style="width:100%" :max-height="mainHeight(52)">
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else-if="v.famount">{{ scope.row[v.prop] | amountFormat(null, 0, null) }}</span>
<span v-else>{{ scope.row[v.prop] }}</span>
<time-count v-if="v.timmer && scope.row.gicAuditingStatus === 1 && scope.row.status === 0" class="primary-color fz12" :default-val="scope.row.putOnTime" :auto-start="true" />
</template>
</el-table-column>
<el-table-column label="操作" align="left" width="180px" fixed="right">
<template slot-scope="scope">
<dm-perm-button :disabled="$itemPerm($itemCode.gicCardGroupSendInfo)" type="text" @click="$router.push(`/gic-card/group-send/info?id=${scope.row.couponPlanId}`)">详情</dm-perm-button>
<dm-perm-button :disabled="$itemPerm($itemCode.gicCardGroupSendInfoLog)" type="text" @click="$router.push(`/gic-card/group-send/info-log?id=${scope.row.couponPlanId}`)">记录</dm-perm-button>
<!-- gic审核投放 status待投放 可禁用 -->
<dm-perm-button :disabled="$itemPerm($itemCode.gicCardStopGroupSend)" type="text" v-if="scope.row.gicAuditingStatus === 1 && scope.row.status === 0" @click="stopOne(scope.row)">禁用</dm-perm-button>
</template>
</el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
</div>
</template>
<script>
import { page, getMainHeight } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import { showConfirm } from '@/utils/common.js';
import { sendStatus, cardType } from '@/config/mapping/gic-card';
import timeCount from '@/components/libs/time-count';
import api from '@/api/gic-card.js';
const { groupSendList, stopGroupSend } = api;
export default {
name: 'GroupSendList',
components: {
timeCount // eslint-disable-line
},
mixins: [ page, getMainHeight ],
data() {
return {
loading: false,
dateTime: [ , ],
listParams: {
search: '',
status: '',
currentPage: 1,
pageSize: 20
},
sendStatus: Object.keys(sendStatus).map(v => { return sendStatus[v]; }), // , { label: '待审核', value: -3 }, { label: '审核失败', value: -2 } -3: 待审核, -2 审核失败,
tableList: [],
total: 0,
tableHeader: [
{
label: '计划名称',
align: 'left',
minWidth: '120',
fixed: 'left',
tooltip: true,
formatter: function(row) {
return `<span p-key="couponPlanId" title="${row.couponPlanId}">${ row.name }</span>`;
}
},
{
label: '投放时间',
minWidth: '120',
align: 'left',
formatter: function(row) {
return row.putOnTime ? listTime(row.putOnTime) : '--';
}
},
{
label: '投放卡券',
minWidth: '120',
align: 'left',
formatter: function(row) {
const _cardType = cardType[row.cardType] || {};
return `<p class="fz14 ellipsis" p-key="couponId" title="${row.couponId}">${row.cardName || '--'}</p><p class="fz12">${_cardType.label || '--'}</p>`;
}
},
{ label: '投放人数', prop: 'issuingQuantity', align: 'left', minWidth: '100', famount: true },
{ label: '领取数', prop: 'getedQuantity', align: 'left', minWidth: '100', famount: true },
{
label: '领取率',
minWidth: '100',
align: 'left',
formatter: function(row) {
return ((row.getedQuantity * 100) / (row.issuingQuantity === 0 ? 1 : row.issuingQuantity)).toFixed(2) + '%';
}
},
{ label: '使用数量', prop: 'usageQuantity', align: 'left', minWidth: '100' },
{
label: '核销率',
minWidth: '100',
align: 'left',
formatter: function(row) {
return ((row.usageQuantity * 100) / (row.getedQuantity === 0 ? 1 : row.getedQuantity)).toFixed(2) + '%';
}
},
{ label: '销售额', prop: 'saleAmount', align: 'left', minWidth: '100', famount: true },
{ label: '创建人', prop: 'creatorName', align: 'left', minWidth: '100' },
{ label: '数据对话', prop: 'mktActivityName', align: 'left', minWidth: '140' },
{
label: '状态',
minWidth: '140',
align: 'left',
timmer: true,
formatter: function(row) {
// gic审核状态: (-1:审核失败,0:未审核(审核中),1:审核通过)
// 状态: (-1失效,0:待发送,1:已完成,2:发送失败,3:无可用模板;4.发送中)
const { gicAuditingStatus, status } = row;
if (gicAuditingStatus === -1) {
return '<span class="state-point state-point-error">审核失败</span>';
} else if (gicAuditingStatus === 0) {
return '<span class="state-point state-point-warnning">审核中</span>';
} else {
const _status = sendStatus[status];
if(_status) {
return `<span class="state-point ${_status.cl}">${_status.label}</span>`;
} else {
return '<span class="state-point state-point-default">未知状态</span>';
}
}
}
}
]
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券投放', breadPath: '/gic-card/group-send/list' } ]);
},
mounted() {
this.getTableList();
},
methods: {
stopOne({ couponPlanId }) {
showConfirm('<div>确认禁用?</div><div>禁用后该计划会直接失败</div>', () => {
this.loading = true;
stopGroupSend({ couponPlanId }).then(res => {
this.loading = false;
this.getTableList();
}).finally(() => {
this.loading = false;
});
}, undefined, undefined, {
dangerouslyUseHTMLString: true
});
},
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
let params = { ...this.listParams, ...{ memberCardId: this.currentAreaId } };
groupSendList(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
}
},
};
</script>
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<span class="mrAuto"></span>
<el-button type="primary" icon="iconfont-market4 icon-icon_yunxiazai mr5">数据导出</el-button>
</div>
<el-table tooltip-effect="dark" :data="tableList" style="width:100%">
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] }}</span>
</template>
</el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
</div>
</template>
<script>
import { page } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import api from '@/api/gic-card.js';
const { codeErrorList } = api;
export default {
name: 'CodeErrorList',
mixins: [ page ],
data() {
return {
loading: false,
listParams: {
currentPage: 1,
pageSize: 20,
couponId: this.$route.query.id
},
tableList: [],
total: 0,
tableHeader: [
{ label: '券码', prop: 'code', align: 'left', fixed: 'left' },
{
label: '导入时间',
align: 'left',
formatter: function(row) {
return row.createTime ? listTime(row.createTime) : '--';
}
},
{ label: '错误原因', prop: 'errMsg', align: 'left' },
]
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券库', breadPath: '/gic-card/list' }, { breadName: '导入券码失败记录' } ]);
},
mounted() {
this.getTableList();
},
methods: {
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
let params = { ...this.listParams, ...{ memberCardId: this.currentAreaId } };
codeErrorList(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
}
}
};
</script>
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-input class="vertical-middle w300 mrAuto" v-model="listParams.search" clearable placeholder="请输卡券名称/卡券代码/用户信息" @change="refresh"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<dm-perm-button :disabled="$itemPerm($itemCode.gicCardGiveLogExport)" type="primary" icon="iconfont-market4 icon-icon_yunxiazai mr5" @click="showExport">数据导出</dm-perm-button>
<el-input placeholder="请输入关键字搜索" class="w400 mr10" v-model="listParams.search" clearable @change="refresh">
<el-select v-model="listParams.searchType" slot="prepend" style="width:120px;" placeholder="请选择" @change="refresh">
<el-option label="卡券名称" :value="1"></el-option>
<el-option label="卡券代码" :value="2"></el-option>
<el-option label="转赠会员姓名" :value="3"></el-option>
<el-option label="转赠会员卡号" :value="4"></el-option>
<el-option label="受赠会员姓名" :value="5"></el-option>
<el-option label="受赠会员卡号" :value="6"></el-option>
<el-option label="受赠会员昵称" :value="7"></el-option>
</el-select>
</el-input>
<!-- <dm-perm-button :disabled="$itemPerm($itemCode.gicCardGiveLogExport)" type="primary" icon="iconfont-market4 icon-icon_yunxiazai mr5" @click="showExport">数据导出</dm-perm-button> -->
</div>
<div class="table-search-head">
<el-select class="dm-select mr10 w140" clearable v-model="listParams.status" placeholder="所有转赠状态" @change="refresh">
......@@ -11,13 +21,13 @@
领取时间:<el-date-picker class="w250 mr10" v-model="dateTime2" type="daterange" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
转赠时间:<el-date-picker class="w250" v-model="dateTime" type="daterange" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
</div>
<el-table tooltip-effect="dark" :data="tableList" :max-height="mainHeight(54 + 50)" style="width:100%">
<el-table tooltip-effect="dark" :data="tableList" :max-height="mainHeight(54 + 50)" style="width:100%" :default-sort="{prop: 'giveTime', order: 'descending'}">
<el-table-column label="转赠会员" min-width="120" fixed="left">
<template slot-scope="scope">
<member-info :member-name="scope.row.memberName" :member-image="scope.row.memberImage" :member-phone="scope.row.memberPhone"></member-info>
</template>
</el-table-column>
<el-table-column label="转赠时间" min-width="120">
<el-table-column prop="giveTime" sortable label="转赠时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.giveTime)"></span>
</el-table-column>
<el-table-column label="转赠状态" min-width="120">
......@@ -28,9 +38,6 @@
<member-info :member-name="scope.row.giveMemberName" :member-image="scope.row.giveMemberImage" :member-phone="scope.row.giveMemberPhone"></member-info>
</template>
</el-table-column>
<el-table-column label="领取时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.receiveTime)"></span>
</el-table-column>
<el-table-column label="卡券类型" min-width="120">
<span slot-scope="scope" v-html="formatCardType(scope.row)"></span>
</el-table-column>
......@@ -39,7 +46,10 @@
<span p-key="couponId" :title="scope.row.couponId">{{ scope.row.cardName }}</span>
</template>
</el-table-column>
<el-table-column prop="cardCode" label="卡券代码" min-width="120"> </el-table-column>
<el-table-column label="领取时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.receiveTime)"></span>
</el-table-column>
<el-table-column prop="couponCode" label="卡券代码" min-width="120"> </el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
......@@ -71,6 +81,7 @@ export default {
dateTime2: [ , ],
listParams: {
search: '',
searchType: 1,
status: '',
giveBeginTime: '',
giveEndTime: '',
......@@ -120,6 +131,7 @@ export default {
this.formatterTimeFunc('giveBeginTime', 'giveEndTime', 'yyyy-MM-dd', 'dateTime');
this.formatterTimeFunc('receiveBeginTime', 'receiveEndTime', 'yyyy-MM-dd', 'dateTime2');
let params = { ...this.listParams, memberCardId: this.currentAreaId };
// TODO: search
giveLogList(params).then(res => {
this.loading = false;
const data = res.result;
......
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-select v-model="listParams.timeType" clearable class="mr10" placeholder="请选择有效期类型" @change="changeTimeType">
<el-option label="长期有效" :value="1"></el-option>
<el-option label="部分时间段" :value="2"></el-option>
</el-select>
<el-date-picker v-if="listParams.timeType !== 1" class="w300 mr10" v-model="dateTime" type="daterange" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
<el-input class="vertical-middle w250 mrAuto" v-model="listParams.searchParam" clearable placeholder="请输入计划名称/创建人" @change="refresh"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<el-button type="primary" class="w85" @click="$router.push('/gic-card/shelf/add')">新建计划</el-button>
</div>
<el-table tooltip-effect="dark" :data="tableList" :max-height="mainHeight(52)" style="width:100%">
<template>
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] || '--' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="left" width="160px" fixed="right">
<template slot-scope="scope">
<el-button type="text" @click="$router.push(`/gic-card/shelf/edit?id=${scope.row.couponShelfId}`)">编辑</el-button>
<el-popover popper-class="option-dropdown" trigger="hover">
<ul>
<!-- <li @click="viewCoupon(scope.row.couponShelfId)"><span>所用卡券</span></li> -->
<!-- area_typeint(1) NULL1会员卡 2服务号 3小程序 -->
<li @click="$router.push(`/gic-card/shelf/receive-list?appCode=coupon-shelf&couponShelfId=${scope.row.couponShelfId}&title=${scope.row.title}`)"><span>领取记录</span></li>
<li @click="delOne(scope.row.couponShelfId)"><span>删除</span></li>
</ul>
<el-button class="ml16" type="text" slot="reference">更多<i class="ml5 el-icon-arrow-down"></i></el-button>
</el-popover>
</template>
</el-table-column>
</template>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
<el-dialog title="所用卡券" :visible.sync="dialogVisible" width="700px">
<el-table :data="gridData" v-loading="gridLoading">
<el-table-column property="cardName" label="卡券名称" min-width="250"></el-table-column>
<el-table-column property="couponStock" label="卡券库存" width="200"></el-table-column>
<el-table-column property="remainedStock" label="卡券领取量" width="150">
<template slot-scope="scope">{{ scope.row.couponStock - scope.row.remainedStock }}</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { page, formate, getMainHeight } from '@/mixins/table.js';
import { formatDateTimeByType } from '@/utils/index.js';
import api from '@/api/gic-card.js';
import { showConfirm } from '@/utils/common.js';
// import { sendType, } from '@/config/mapping/gic-card';
const { getShelfList, delShelf, getShelfCoupon } = api;
export default {
name: 'ShelfList',
mixins: [ page, formate, getMainHeight ],
data() {
return {
loading: false,
dateTime: [ , ],
listParams: {
timeType: '',
searchParam: '',
startTime: '',
endTime: '',
currentPage: 1,
pageSize: 20
},
total: 0,
tableList: [],
tableHeader: [
{
label: '计划名称',
align: 'left',
minWidth: '120',
fixed: 'left',
tooltip: true,
formatter: function(row) {
return `<span p-key="couponShelfId" title="${row.couponShelfId}">${ row.title }</span>`;
}
},
{
label: '计划时间',
minWidth: '150',
align: 'left',
formatter: function(row) {
return row.timeType == 1 ? '长期有效' : `
<p class="cell-time">${ formatDateTimeByType(row.startTime, 'yyyy-MM-dd HH-mm-ss') } ~</p>
<p class="cell-time">${ formatDateTimeByType(row.endTime, 'yyyy-MM-dd HH-mm-ss') }</p>
`;
}
},
{ label: '创建人', prop: 'creatorName', align: 'left', minWidth: '100' },
{ label: '卡券数量', prop: 'couponNum', align: 'left', minWidth: '100' },
{
label: '计划状态',
align: 'left',
minWidth: '120',
formatter: function(row) {
let statusBtn;
if(row.timeType !== 1 && new Date() < new Date(row.startTime)) {
statusBtn = '<span class="state-point state-point-warning">未生效</span>';
}
if(row.timeType == 1 || new Date() > new Date(row.startTime) && new Date() < new Date(row.endTime)) {
statusBtn = '<span class="state-point state-point-loading-scale">进行中</span>';
}
if(row.timeType !== 1 && new Date() > new Date(row.endTime)) {
statusBtn = '<span class="state-point state-point-default">已失效</span>';
}
return statusBtn;
}
}
],
dialogVisible: false,
gridLoading: false,
gridData: []
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券展架', breadPath: '/gic-card/shelf/list' } ]);
},
mounted() {
this.getTableList();
},
methods: {
changeTimeType() {
this.dateTime = [];
this.refresh();
},
// 查看所用卡券
viewCoupon(shelfId) {
this.dialogVisible = true;
this.gridLoading = true;
getShelfCoupon({ shelfId }).then(res => {
this.gridLoading = false;
this.gridData = res.result;
}).finally(() => {
this.gridLoading = false;
});
},
// 删除
delOne(shelfId) {
showConfirm('<div>确认删除该展架?</div>', () => {
this.loading = true;
delShelf({ shelfId }).then(res => {
this.loading = false;
this.$tips({ message: '删除成功', type: 'success' });
this.getTableList();
}).finally(() => {
this.loading = false;
});
});
},
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
this.formatterTimeFunc('startTime', 'endTime', 'yyyy-MM-dd', 'dateTime');
let params = { ...this.listParams, memberCardId: this.currentAreaId };
getShelfList(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
}
},
};
</script>
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-input class="vertical-middle w300 mr10" v-model="listParams.search" clearable placeholder="请输入卡券代码/会员信息" @change="refresh"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<el-date-picker class="w400 mr10" v-model="dateTime" type="daterange" range-separator="~" start-placeholder="领取开始时间" end-placeholder="领取结束时间" @change="refresh"></el-date-picker>
<dm-perm-button class="mlAuto" :disabled="$itemPerm($itemCode.gicCardShelfLogExportBtn)" type="primary" icon="iconfont-market4 mr5 icon-icon_yunxiazai" @click="showExport">数据导出</dm-perm-button>
</div>
<el-table tooltip-effect="dark" :data="tableList" style="width:100%" :max-height="mainHeight(52)" :empty-text="listParams.couponId || listParams.allCouponFlag ? '暂无数据' : '请选择单张卡券或开启全部卡券'">
<el-table-column label="计划名称" min-width="140" fixed="left">
<span>{{ $route.query.title || '--' }}</span>
</el-table-column>
<el-table-column label="领取时间" min-width="120">
<span slot-scope="scope" v-html="listTime(scope.row.receiveTime)"></span>
</el-table-column>
<el-table-column label="领取用户" min-width="120">
<template slot-scope="scope">
<member-info :member-name="scope.row.memberName" :member-image="scope.row.memberImage" :member-phone="scope.row.memberPhone"></member-info>
</template>
</el-table-column>
<el-table-column label="所领卡券" min-width="140" show-overflow-tooltip>
<template slot-scope="scope">
<span p-key="couponId" :title="scope.row.couponId">{{ scope.row.cardName }}</span>
</template>
</el-table-column>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
<dm-export-data ref="exportData" :visible.sync="exportVisible" :sens-value="true" :fields="fields" :label="label" :value="value" :sens-key="sensKey" :loading="loading" :is-created="isCreated" @export="onExport" @closed="isCreated = false"></dm-export-data>
</div>
</template>
<script>
import { page, formate, getMainHeight } from '@/mixins/table.js';
import { dealExportParams } from '@/utils/common.js';
import { listTime } from '@/utils/index.js';
import fetch from '@/api/gic-card.js';
const { couponlogList, exportCoupReceivedLog } = fetch;
export default {
name: 'ShelfReceiveList',
mixins: [ page, formate, getMainHeight ],
props: {
dialogVisible: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false,
dateTime: [ Date.now() - 7 * 24 * 60 * 60 * 1000, Date.now() ], // 默认7天
// dateTime2: [ , ],
listParams: {
appActivityId: this.$route.query.couponShelfId || '',
appCode: 'coupon-shelf', // 和领取记录共用接口,传特殊状态appCode
search: '',
receiveBeginTime: '',
receiveEndTime: '',
currentPage: 1,
pageSize: 20,
allCouponFlag: 1 // 展架特殊,就是全部
},
cardOrderShow: false,
currentObj: {},
tableList: [],
total: 0,
// 导出组件
exportVisible: false,
isCreated: false,
// eslint-disable-next-line
fields: [{label:'领取时间',value:'receiveTime',sensKey:false},{label:'会员名称',value:'memberName',sensKey:false},{label:'会员手机号',value:'memberPhone',sensKey:true},{label:'卡券名称',value:'cardName',sensKey:false}],
sensKey: 'sensKey',
label: 'label',
value: 'value'
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券展架' }, { breadName: '卡券展架领取记录' } ]);
},
mounted() {
if(this.currentAreaId) {
this.getTableList();
}
},
methods: {
listTime,
changeAllCouponFlag(val) {
if (val) {
this.listParams.couponId = '';
if (new Date(this.dateTime[1]).getTime() - new Date(this.dateTime[0]).getTime() > 7 * 24 * 60 * 60 * 1000) {
// 设置为默认值
this.dateTime = [ Date.now() - 7 * 24 * 60 * 60 * 1000, Date.now() ];
}
}
this.refresh();
},
getTableList() {
if(this.loading) {
return;
}
this.formatterTimeFunc('receiveBeginTime', 'receiveEndTime', 'yyyy-MM-dd', 'dateTime');
let params = { ...this.listParams, memberCardId: this.currentAreaId };
this.loading = true;
couponlogList(params).then(res => {
this.loading = false;
const data = res.result;
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
},
// ********数据导出*************
showExport() {
if(!this.tableList.length) {
this.$tips({ message: '没有要导出的数据', type: 'warning' });
return;
}
this.exportVisible = true;
},
onExport(config) {
let params = dealExportParams({ config, listParams: this.listParams, fieldList: this.fields, path: this.$route.path, pathName: 'GIC卡券-卡券展架领取记录', query: { areaId: this.currentAreaId, appActivityId: this.$route.query.couponShelfId, appCode: this.listParams.appCode } });
// 将config转换为请求参数
// const params = config;
// 导出数据完成后,必须调导出组件的applyReport方法
// applyReport方法的第一个参数表示是否生成导出数据,第二个参数为导出数据的id
exportCoupReceivedLog(params).then(res => {
this.$refs.exportData.applyReport(true, res.result);
}).catch(err => {
this.$refs.exportData.applyReport();
});
}
},
};
</script>
<template>
<stock-list welfare-id=""></stock-list>
</template>
<script>
import stockList from '@/components/welfare/list.vue';
export default {
name: 'StockList',
components: {
stockList
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券', breadPath: '/gic-card/list' }, { breadName: '库存记录' } ]);
}
};
</script>
<template>
<div class="p20" v-loading="loading">
<div class="pb20 clearfix flex-center">
<el-date-picker class="w250 mr10" v-model="dateTime" type="daterange" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="refresh"></el-date-picker>
<el-select class="dm-select w140 mr10" clearable v-model="listParams.optType" placeholder="所有操作类型" @change="refresh">
<el-option v-for="(v, i) in optType" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<el-select class="dm-select w140 mrAuto" clearable v-model="listParams.status" placeholder="所有状态" @change="refresh">
<el-option v-for="(v, i) in syncStatus" :key="i" :label="v.label" :value="v.value"></el-option>
</el-select>
<el-button @click="syncStock.type = 2; syncStock.visible = true;">返还</el-button>
<!-- <el-button @click="toWelfare">查看</el-button> -->
<el-button type="primary" @click="syncStock.type = 1; syncStock.visible = true;">同步</el-button>
</div>
<el-table tooltip-effect="dark" :data="tableList" style="width:100%">
<template>
<el-table-column v-for="(v, i) in tableHeader" :fixed="v.fixed" :show-overflow-tooltip="v.tooltip" :width="v.width" :min-width="v.minWidth" :align="v.align" :key="i" :prop="v.prop" :label="v.label" :formatter="v.formatter" :sortable="v.sortable">
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] }}</span>
</template>
</el-table-column>
</template>
</el-table>
<div class="clearfix">
<dm-pagination class="fr mb0" v-if="tableList.length" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listParams.currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="listParams.pageSize" layout="total, sizes, prev, pager, next" :total="total"></dm-pagination>
</div>
<!-- 同步库存 -->
<sync-stock :visible.sync="syncStock.visible" :coupon-id="couponId" :type="syncStock.type" :show-link="false" @syncSuccess="getTableList" />
</div>
</template>
<script>
import { page, formate } from '@/mixins/table.js';
import { listTime } from '@/utils/index.js';
import { cardType, syncStatus } from '@/config/mapping/gic-card';
import fetch from '@/api/gic-card.js';
import syncStock from './module/sync-stock';
const { getSyncWelfareList } = fetch;
export default {
name: 'SyncStockList',
components: {
syncStock
},
mixins: [ page, formate ],
props: {
dialogVisible: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false,
couponId: this.$route.query.couponId,
syncStock: {
visible: false,
type: 1,
},
couponInfo: {}, // 卡券信息
dateTime: [ , ],
listParams: {
couponId: this.$route.query.couponId,
optType: '',
beginTime: '',
endTime: '',
status: '',
currentPage: 1,
pageSize: 20
},
optType: [ { label: '同步', value: 1 }, { label: '返还', value: 2 } ],
syncStatus: Object.keys(syncStatus).map(v=> { return syncStatus[v]; }),
tableList: [],
total: 0,
tableHeader: [
{
label: '操作时间',
minWidth: '120',
align: 'left',
fixed: 'left',
formatter: function(row) {
return listTime(row.modifyTime);
}
},
{
label: '卡券',
minWidth: '120',
align: 'left',
formatter: (row) => {
const _cardType = cardType[this.couponInfo.cardType] || {};
return `<p class="fz14" p-key="couponId" title="${this.couponInfo.couponId}">${this.couponInfo.cardName}</p><p class="fz12">${_cardType.label}</p>`;
}
},
{
label: '操作类型',
align: 'left',
minWidth: '120',
formatter: function(row) {
// 1: 同步; 2: 返还
return row.modifyType === 1 ? '同步' : '返还';
}
},
{
label: '调整库存',
minWidth: '120',
align: 'left',
formatter: function(row) {
return (row.modifyType === 1 ? '- ' : '+ ') + row.modifyStock;
}
},
// { label: '操作人', prop: 'cardName', align: 'left', minWidth: '120' },
// {
// label: '状态',
// minWidth: '120',
// align: 'left',
// formatter: function(row) {
// return '??????';
// }
// }
]
};
},
created() {
this.$emit('updateBread', [ { breadName: '福利中心' }, { breadName: 'GIC卡券' }, { breadName: '卡券库', breadPath: '/gic-card/list' }, { breadName: '同步记录' } ]);
},
mounted() {
if(this.currentAreaId && this.couponId) {
this.getTableList();
}
},
methods: {
toWelfare() {
window.open(`/welfare/stock/log/list?id=${this.couponInfo.welfareId}`);
},
getTableList() {
if(this.loading) {
return;
}
this.loading = true;
this.formatterTimeFunc('beginTime', 'endTime');
let params = { ...this.listParams, ...{ memberCardId: this.currentAreaId } };
getSyncWelfareList(params).then(res => {
this.loading = false;
const data = res.result.page;
this.couponInfo = res.result.coupon || {};
this.tableList = data.result || [];
this.total = data.totalCount;
// 删除至最后一页没数据的情况,页码-1
if (this.tableList.length === 0 && this.listParams.currentPage !== 1) {
this.listParams.currentPage -= 1;
this.getTableList();
}
}).finally(() => {
this.loading = false;
});
}
},
};
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment