Commit 40257284 by 黑潮

update: 群发消息

parent 051e9438
......@@ -8,5 +8,6 @@ export const ecmTypes = [
{ value: 'teltask', label: '话务', visible: true },
{ value: 'integral', label: '积分', visible: true },
{ value: 'grade', label: '会员卡升级', visible: false },
{ value: 'qywx', label: '企微任务', visible: false }
{ value: 'qywx', label: '企微任务', visible: false },
{ value: 'qfxx', label: '群发消息', visible: false }
];
......@@ -6,6 +6,14 @@ export default {
redirect: '/ecm/list',
children: [
{
path: 'log',
name: '操作日志',
component: () => import(/* webpackChunkName: "ecm" */ '../../views/ecm/operator-log.vue'),
meta: {
path: '/ecm/list'
}
},
{
path: 'list',
name: '智能营销',
component: () => import(/* webpackChunkName: "ecm" */ '../../views/ecm/list.vue'),
......
......@@ -69,3 +69,5 @@ export const ecmGuideCluesTouchEffectTabTotalHead1 = params => requests(PREFIX +
export const getUseStoredFalg = params => requests(PREFIX + 'get-ecm-store-flag', params);
export const getXsxsFalg = params => requests(PREFIX + 'get-xsxs-open-flag', params);
export const getEcmLog = params => requests(PREFIX + 'get-ecm-operator_log', params);
......@@ -121,7 +121,8 @@ export default {
created() {
getXsxsFalg().then(res => {
if (res.result) {
// this.typeOptions.find(el => el.value == 'qywx').visible = true;
this.typeOptions.find(el => el.value == 'qywx').visible = true;
this.typeOptions.find(el => el.value == 'qfxx').visible = true;
}
});
getUseStoredFalg().then(res => {
......
......@@ -153,7 +153,7 @@ export default {
discount_limit: { type: 1, count: undefined, flag: false }, // 适用商品折扣
useStoredFlag: 0, //显示储值触发和会员卡升级事件
analyseConfig: {
open_flag: 0,
open_flag: '',
crowd_flag: 0,
crowd_send: 4,
crowd_no_send: 1,
......@@ -675,7 +675,10 @@ export default {
}
}
if (this.xsxsFlag == 1) {
if (this.analyseConfig.crowd_send === undefined) {
if (this.analyseConfig.open_flag === '') {
this.$tips({ type: 'warning', message: '请选择是否开启营销分析' });
return;
} else if (this.analyseConfig.crowd_send === undefined) {
this.$tips({ type: 'warning', message: '请填写实验组' });
return;
} else if (this.analyseConfig.crowd_no_send === undefined) {
......
......@@ -389,46 +389,64 @@
<section class="dm-form__wrap" v-if="xsxsFlag == 1">
<h3 class="dm-title__label">
<span class="inline-block mr10">营销分析设置</span>
<el-switch :disabled="!isAdd" v-model="analyseConfig.open_flag" :active-value="1" :inactive-value="0" @change="onChangeAnalyseConfig($event, true)"></el-switch>
<span class="gray fz12">开启后,可用于统计这次线索挖掘计划的收益情况。</span>
<!-- <el-switch :disabled="!isAdd" v-model="analyseConfig.open_flag" :active-value="1" :inactive-value="0" @change="onChangeAnalyseConfig($event, true)"></el-switch> -->
</h3>
<div v-if="analyseConfig.open_flag == 1" style="padding-bottom:10px;color:#303133">
<div style="padding-bottom:10px;color:#303133">
<div class="mt20">
<div class="w150 text-right inline-block mr10">
<label class="cursor required">
<span>设置营销效果时长</span>
<el-tooltip slot="label" open-delay="200" placement="top">
<span>是否开启营销分析</span>
<!-- <el-tooltip slot="label" open-delay="200" placement="top">
<i style="cursor:pointer;color:#909399;font-size:14px;" class="iconfont icon-xinxixianshi"></i>
<div slot="content" style="width:376px;line-height: 22px;">设置线索在被营销触达之后的{{ analyseConfig.marke_days || '--' }}天内,客户所产生的消费纳入到该线索收益统计中</div>
</el-tooltip>
<div slot="content" style="line-height: 22px;">用于统计本次线索挖掘计划的收益情况</div>
</el-tooltip> -->
</label>
</div>
<el-input-number :disabled="!isAdd" controls-position="right" class="w150" :min="3" :max="31" v-model="analyseConfig.marke_days"></el-input-number>
<span class="ml10">天之内</span>
<el-radio-group :disabled="!isAdd" v-model="analyseConfig.open_flag" @change="onChangeAnalyseConfig($event, true)">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</div>
<div style="margin-top:6px;color:#A5A7AD;font-size:12px;margin-left:164px">最长 31 天,最短 3 天 (以自然日计算)</div>
<div class="mt20" v-show="[1, 2].includes(form.effectType)">
<div class="w150 text-right inline-block mr10">
<label class="cursor">
<span>设置参照组</span>
<el-tooltip slot="label" open-delay="200" placement="top">
<i style="cursor:pointer;color:#909399;font-size:14px;" class="iconfont icon-xinxixianshi"></i>
<div slot="content" style="width:376px;line-height: 22px;">设置后,系统按下方比例随机抽取部分营销人群作为参照,不触发任务。后续可在【触达效果】中查看对照数据结果</div>
</el-tooltip>
</label>
<template v-if="analyseConfig.open_flag == 1">
<div class="mt20">
<div class="w150 text-right inline-block mr10">
<label class="cursor required">
<span>设置营销效果时长</span>
<el-tooltip slot="label" open-delay="200" placement="top">
<i style="cursor:pointer;color:#909399;font-size:14px;" class="iconfont icon-xinxixianshi"></i>
<div slot="content" style="width:376px;line-height: 22px;">设置线索在被营销触达之后的{{ analyseConfig.marke_days || '--' }}天内,客户所产生的消费纳入到该线索收益统计中</div>
</el-tooltip>
</label>
</div>
<el-input-number :disabled="!isAdd" controls-position="right" class="w150" :min="3" :max="31" v-model="analyseConfig.marke_days"></el-input-number>
<span class="ml10">天之内</span>
</div>
<el-switch :disabled="!isAdd" v-model="analyseConfig.crowd_flag" :active-value="1" :inactive-value="0" @change="onChangeAnalyseConfig($event, false)"></el-switch>
</div>
<div v-if="analyseConfig.crowd_flag == 1" class="mt20">
<label class="w150 text-right inline-block mr10">实验组 (触发任务人群)</label>
<el-input-number :disabled="!isAdd" controls-position="right" class="w150" :min="1" v-model="analyseConfig.crowd_send"></el-input-number>
<span class="ml10 mr10">:</span>
<el-input-number :disabled="!isAdd" controls-position="right" class="w150" :min="1" v-model="analyseConfig.crowd_no_send"></el-input-number>
<span class="ml10">参照组 (不触发任务人群)</span>
<el-tooltip v-if="analyseConfig.crowd_no_send > 1" class="item" effect="dark" placement="top" :open-delay="300">
<i style="cursor:pointer;color:#909399;font-size:14px;vertical-align: middle;" class="iconfont icon-xinxixianshi"></i>
<div slot="content" style="width:376px;line-height: 22px;">原则:同一用户在同一计划中不会既存在实验组中,又存在于参照组中。 在计划允许对同一个用户重复营销的情况下,如果首次触发时,某些用户已经被归为实验组了,那么下一次触发时,这些用户还会被默认归入到实验组,剩余的再按照比例进行触发。<br />因此对于这些允许对用户进行重复营销的计划,最终在【触达效果】中所呈现的实验组与参照组的人数比例可能和配置的比例不一致。</div>
</el-tooltip>
</div>
<div style="margin-top:6px;color:#A5A7AD;font-size:12px;margin-left:164px">最长 31 天,最短 3 天 (以自然日计算)</div>
<div class="mt20" v-show="[1, 2].includes(form.effectType)">
<div class="w150 text-right inline-block mr10">
<label class="cursor">
<span>设置参照组</span>
<el-tooltip slot="label" open-delay="200" placement="top">
<i style="cursor:pointer;color:#909399;font-size:14px;" class="iconfont icon-xinxixianshi"></i>
<div slot="content" style="width:376px;line-height: 22px;">设置后,系统按下方比例随机抽取部分营销人群作为参照,不触发任务。后续可在【触达效果】中查看对照数据结果</div>
</el-tooltip>
</label>
</div>
<el-switch :disabled="!isAdd" v-model="analyseConfig.crowd_flag" :active-value="1" :inactive-value="0" @change="onChangeAnalyseConfig($event, false)"></el-switch>
</div>
<div v-if="analyseConfig.crowd_flag == 1" class="mt20">
<label class="w150 text-right inline-block mr10">实验组 (触发任务人群)</label>
<el-input-number :disabled="!isAdd" controls-position="right" class="w150" :min="1" v-model="analyseConfig.crowd_send"></el-input-number>
<span class="ml10 mr10">:</span>
<el-input-number :disabled="!isAdd" controls-position="right" class="w150" :min="1" v-model="analyseConfig.crowd_no_send"></el-input-number>
<span class="ml10">参照组 (不触发任务人群)</span>
<el-tooltip v-if="analyseConfig.crowd_no_send > 1" class="item" effect="dark" placement="top" :open-delay="300">
<i style="cursor:pointer;color:#909399;font-size:14px;vertical-align: middle;" class="iconfont icon-xinxixianshi"></i>
<div slot="content" style="width:376px;line-height: 22px;">原则:同一用户在同一计划中不会既存在实验组中,又存在于参照组中。 在计划允许对同一个用户重复营销的情况下,如果首次触发时,某些用户已经被归为实验组了,那么下一次触发时,这些用户还会被默认归入到实验组,剩余的再按照比例进行触发。<br />因此对于这些允许对用户进行重复营销的计划,最终在【触达效果】中所呈现的实验组与参照组的人数比例可能和配置的比例不一致。</div>
</el-tooltip>
</div>
</template>
</div>
</section>
<!-- 操作区 -->
......
......@@ -14,9 +14,20 @@
<el-input v-model="listParams.searchName" class="w200" placeholder="输入计划名称" clearable @change="search"><i slot="prefix" class="el-input__icon el-icon-search"></i></el-input>
<el-checkbox class="vertical-middle" v-if="$store.state.marketing.isShowSelf" v-model="listParams.showSelfFlag" :true-label="1" :false-label="0" label="仅看本人" border @change="search" />
<el-button class="fr" type="primary" @click="$router.push('/ecm/add')">新建计划</el-button>
<el-tooltip class="fr" content="只记录删除计划或编辑“进行中”计划的操作日志" placement="top" open-delay="200">
<el-button style="margin-right:10px" @click="$router.push('/ecm/log')">操作日志</el-button>
</el-tooltip>
</div>
<el-table tooltipEffect="light" :data="tableList" style="width: 100%" element-loading-text="拼命加载中">
<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">
<template slot="header" slot-scope="scope">
<span>
<span>{{ v.label }}</span>
<el-tooltip v-if="v.prop == 'timesForPeople'" content="刷新获取最新营销人次统计" placement="top" :open-delay="200">
<i class="el-icon-refresh" @click="loadEcmList"></i>
</el-tooltip>
</span>
</template>
<template slot-scope="scope">
<span class="vertical-middle" v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] }}</span>
......@@ -43,6 +54,7 @@
<el-dropdown-item :command="1">记录</el-dropdown-item>
<el-dropdown-item v-if="scope.row.effectType !== 2 && scope.row.onlineStatus === 1 && scope.row.canEdit !== false" @confirm="offlineEcmPlan(scope.row)" :command="2">下线</el-dropdown-item>
<el-dropdown-item v-if="xsxsFlag && isOpenFlag(scope.row.analyseJson)" :command="3">触达效果</el-dropdown-item>
<el-dropdown-item :command="3">复制新建</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
......@@ -68,10 +80,10 @@ export default {
{ value: 2, label: '单次' }
], // eslint-disable-line
onlineOptions: [
{ value: '', label: '所有上线状态' },
{ value: 0, label: '待上线' },
{ value: 1, label: '已上线' },
{ value: 2, label: '已下线' }
{ value: '', label: '所有状态' },
{ value: 0, label: '未开始' },
{ value: 1, label: '进行中(待执行)' },
{ value: 2, label: '已结束(执行完毕)' }
], // eslint-disable-line
marketingTypeOptions,
listParams: {
......@@ -131,13 +143,13 @@ export default {
let result = '--';
switch (row.onlineStatus) {
case 0:
result = '<span class="dm-status--primary">待上线</span>';
result = '<span class="dm-status--primary">未开始</span>';
break;
case 1:
result = '<span class="dm-status--success">已上线</span>';
result = row.effectType == 2 ? '<span class="dm-status--primary">待执行</span>' : '<span class="dm-status--primary">进行中</span>';
break;
case 2:
result = '<span class="dm-status--info">已下线</span>';
result = row.effectType == 2 ? '<span class="dm-status--info">执行完毕</span>' : '<span class="dm-status--info">已结束</span>';
break;
}
return result;
......@@ -291,7 +303,8 @@ export default {
this.tableHeader = arr;
}
if (this.xsxsFlag) {
// this.marketingTypeOptions.find(el => el.value == 'qywx').visible = true;
this.marketingTypeOptions.find(el => el.value == 'qywx').visible = true;
this.marketingTypeOptions.find(el => el.value == 'qfxx').visible = true;
}
});
},
......@@ -329,3 +342,13 @@ export default {
}
};
</script>
<style lang="scss" scoped>
.el-icon-refresh {
color: #909399;
cursor: pointer;
&:hover {
color: #606266;
}
}
</style>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" fill="#1890ff" xml:space="preserve">
<path d="M192.9,180.5H19.3c-10.5,0-18.6-8.7-18.6-18.6V38c0-10.5,8.7-18.6,18.6-18.6h160.5c10.5,0,18.6,8.7,18.6,18.6v60.1
c0,3.7-3.1,6.2-6.2,6.2c-3.1,0-6.2-3.1-6.2-6.2V38c0-3.1-2.5-6.2-6.2-6.2H19.3c-3.1,0-6.2,2.5-6.2,6.2v123.9c0,3.1,2.5,6.2,6.2,6.2
h173.5c3.7,0,6.2,3.1,6.2,6.2S196,180.5,192.9,180.5L192.9,180.5z"/>
<path d="M99.9,115.4c-1.2,0-3.1-0.6-3.7-1.2L24.9,55.3c-2.5-2.5-3.1-6.2-0.6-8.7c2.5-2.5,6.2-3.1,8.7-0.6l66.9,55.1L166.8,46
c2.5-2.5,6.8-1.9,8.7,0.6c2.5,2.5,1.9,6.8-0.6,8.7l-71.2,58.9C102.4,114.8,101.1,115.4,99.9,115.4z M191.6,129.1h-63.2
c-3.7,0-6.2-3.1-6.2-6.2c0-3.1,3.1-6.2,6.2-6.2h63.2c3.7,0,6.2,3.1,6.2,6.2C197.8,126,194.7,129.1,191.6,129.1z M191.6,154.5h-80.6
c-3.7,0-6.2-3.1-6.2-6.2s3.1-6.2,6.2-6.2H191c3.7,0,6.2,3.1,6.2,6.2S194.7,154.5,191.6,154.5L191.6,154.5z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" fill="#c0c4cc" xml:space="preserve">
<path d="M192.9,180.5H19.3c-10.5,0-18.6-8.7-18.6-18.6V38c0-10.5,8.7-18.6,18.6-18.6h160.5c10.5,0,18.6,8.7,18.6,18.6v60.1
c0,3.7-3.1,6.2-6.2,6.2c-3.1,0-6.2-3.1-6.2-6.2V38c0-3.1-2.5-6.2-6.2-6.2H19.3c-3.1,0-6.2,2.5-6.2,6.2v123.9c0,3.1,2.5,6.2,6.2,6.2
h173.5c3.7,0,6.2,3.1,6.2,6.2S196,180.5,192.9,180.5L192.9,180.5z"/>
<path d="M99.9,115.4c-1.2,0-3.1-0.6-3.7-1.2L24.9,55.3c-2.5-2.5-3.1-6.2-0.6-8.7c2.5-2.5,6.2-3.1,8.7-0.6l66.9,55.1L166.8,46
c2.5-2.5,6.8-1.9,8.7,0.6c2.5,2.5,1.9,6.8-0.6,8.7l-71.2,58.9C102.4,114.8,101.1,115.4,99.9,115.4z M191.6,129.1h-63.2
c-3.7,0-6.2-3.1-6.2-6.2c0-3.1,3.1-6.2,6.2-6.2h63.2c3.7,0,6.2,3.1,6.2,6.2C197.8,126,194.7,129.1,191.6,129.1z M191.6,154.5h-80.6
c-3.7,0-6.2-3.1-6.2-6.2s3.1-6.2,6.2-6.2H191c3.7,0,6.2,3.1,6.2,6.2S194.7,154.5,191.6,154.5L191.6,154.5z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" fill="#909399" xml:space="preserve">
<path d="M192.9,180.5H19.3c-10.5,0-18.6-8.7-18.6-18.6V38c0-10.5,8.7-18.6,18.6-18.6h160.5c10.5,0,18.6,8.7,18.6,18.6v60.1
c0,3.7-3.1,6.2-6.2,6.2c-3.1,0-6.2-3.1-6.2-6.2V38c0-3.1-2.5-6.2-6.2-6.2H19.3c-3.1,0-6.2,2.5-6.2,6.2v123.9c0,3.1,2.5,6.2,6.2,6.2
h173.5c3.7,0,6.2,3.1,6.2,6.2S196,180.5,192.9,180.5L192.9,180.5z"/>
<path d="M99.9,115.4c-1.2,0-3.1-0.6-3.7-1.2L24.9,55.3c-2.5-2.5-3.1-6.2-0.6-8.7c2.5-2.5,6.2-3.1,8.7-0.6l66.9,55.1L166.8,46
c2.5-2.5,6.8-1.9,8.7,0.6c2.5,2.5,1.9,6.8-0.6,8.7l-71.2,58.9C102.4,114.8,101.1,115.4,99.9,115.4z M191.6,129.1h-63.2
c-3.7,0-6.2-3.1-6.2-6.2c0-3.1,3.1-6.2,6.2-6.2h63.2c3.7,0,6.2,3.1,6.2,6.2C197.8,126,194.7,129.1,191.6,129.1z M191.6,154.5h-80.6
c-3.7,0-6.2-3.1-6.2-6.2s3.1-6.2,6.2-6.2H191c3.7,0,6.2,3.1,6.2,6.2S194.7,154.5,191.6,154.5L191.6,154.5z"/>
</svg>
<template>
<div class="dm-qywx__item__wrap">
<div class="fz16">{{ qfxx.qfxxEnterpriseName }}</div>
<div class="divider"></div>
<div>{{ item.title }}</div>
<div style="margin-top:12px;color:#606266;white-space:pre-wrap;word-break:break-word">{{ qfxx.remark }}</div>
<p style="margin-top:12px;color:#606266">
<span>群发内容:</span>
<span v-for="(el, index) in materials" :key="el">
<template v-if="index !== 0">/</template>
{{ el }}
</span>
</p>
</div>
</template>
<script>
export default {
name: 'item-qfxx',
props: {
item: {
type: Object,
default() {
return {};
}
}
},
computed: {
qfxx() {
return this.item.qfxx || {};
},
materials() {
let mapName = {
1: '文本',
2: '图片',
3: '网页',
4: '视频',
5: '文件',
6: '小程序'
};
let res = JSON.parse(this.item.qfxx.chatContent || '[]');
return [...new Set(res.map(el => el.type))].map(el => mapName[el]);
}
}
};
</script>
<style lang="scss" scoped>
.divider {
margin-top: 12px;
margin-bottom: 18px;
height: 1px;
background-color: #dcdfe6;
}
/deep/ .el-checkbox {
margin: 0;
margin-right: 20px;
}
</style>
<template>
<div>
<el-dialog :title="isEdit && !readOnly ? '编辑群发消息' : '群发信息'" :visible.sync="show" width="660px" @closed="close">
<el-form ref="form" :model="form" :rules="rules" label-width="110px">
<el-form-item label="选择企业" prop="qfxxEnterpriseId">
<el-select v-model="form.qfxxEnterpriseId" @change="onChangeEnterprise" :disabled="isEdit || readOnly">
<el-option v-for="el in entepriseList" :key="el.wxEnterpriseId" :value="el.wxEnterpriseId" :label="el.corpName"></el-option>
</el-select>
</el-form-item>
<el-form-item label="任务标题" prop="title">
<el-input show-word-limit v-model="form.title" :maxlength="20" :disabled="readOnly"></el-input>
</el-form-item>
<el-form-item label="任务描述" prop="remark">
<el-input class="task-desc" type="textarea" show-word-limit v-model="form.remark" :rows="4" :maxlength="200" resize="none" :disabled="readOnly"></el-input>
</el-form-item>
<el-form-item label="任务逾期判定" prop="expireDays">
<el-input-number v-model="form.expireDays" :min="0" controls-position="right" :disabled="readOnly"></el-input-number>
<span>天之后</span>
</el-form-item>
<el-form-item label="添加群发内容" prop="">
<div style="font-size:12px;color:#6B6D71;margin-bottom:10px">建议以文本+其他类型组合创建群发内容;文本内容最多只能添加 1 个</div>
<div style="margin-bottom:16px;display:flex;flex-wrap:wrap;margin-top:12px">
<material-item class="card-item" v-for="item in materials" :key="item.relation_id" :item="item" @delete="onDeleteMaterial" :read-only="readOnly"></material-item>
<div v-show="materials.length < 5 && !readOnly" class="chat-item card-item" @click="openMaterialDialog">
<i class="el-icon-plus"></i>
<span class="add-text">添加素材 (最多3个)</span>
</div>
</div>
</el-form-item>
</el-form>
<template slot="footer">
<el-button style="width:74px" @click="close">取消</el-button>
<el-button style="width:74px" type="primary" @click="addItem">确定</el-button>
</template>
</el-dialog>
<dm-material :visible.sync="materialVisible" @select="onSelectMaterial" :wx-enterprise-id="this.form.qfxxEnterpriseId" projectName="marketing" :material-ids="materials.map(el => el.relation_id)"></dm-material>
</div>
</template>
<script>
import { getEntepriseList } from '../assets/api';
import MaterialItem from './material-item';
export default {
name: 'lib-qfxx',
props: {
item: {
type: Object,
default() {
return {};
}
},
show: {
type: Boolean,
default: false
},
readOnly: {
type: Boolean,
default: false
}
},
components: {
MaterialItem
},
data() {
return {
form: {
qfxxEnterpriseId: '',
qfxxEnterpriseName: '',
remark: '',
title: '',
expireDays: 0,
chatContent: null
},
rules: {
qfxxEnterpriseId: { required: true, message: '请选择企业', trigger: 'change' },
title: { required: true, message: '请填写任务标题', trigger: 'blur' },
remark: { required: true, message: '请填写任务描述', trigger: 'blur' },
expireDays: { required: true, message: '请填写', trigger: 'blur' }
},
entepriseList: [],
isEdit: false,
ecmMarketingTypeRelationId: '',
materials: [],
materialVisible: false
};
},
created() {
this.getEntepriseList();
},
methods: {
openMaterialDialog() {
if (!this.form.qfxxEnterpriseId) {
return this.$message.warning('请选择企业');
}
this.materialVisible = true;
},
close() {
this.form = {
qfxxEnterpriseId: '',
qfxxEnterpriseName: '',
remark: '',
title: '',
expireDays: 0,
chatContent: null
};
this.ecmMarketingTypeRelationId = '';
this.materials = [];
this.$refs.form.resetFields();
this.$emit('update:show', false);
},
addItem() {
let qfxx = { ...this.form };
if (this.materials.length == 0) {
this.$message.warning('请添加群发内容');
return;
} else if (this.materials.every(el => el.type != 1)) {
this.$message.warning('请添加一条文本内容');
return;
}
delete qfxx.title;
qfxx.chatContent = JSON.stringify(this.materials.map(el => ({ relation_id: el.relation_id })));
this.$emit('sendItem', { title: this.form.title, qfxx, comName: 'qfxx', ecmMarketingTypeRelationId: this.ecmMarketingTypeRelationId });
this.close();
},
getEntepriseList() {
getEntepriseList()
.then(res => {
if (res.errorCode === 0) {
this.entepriseList = res.result || [];
} else {
this.$message({ message: res.message, type: 'error' });
}
})
.catch(err => {
this.$message({ message: err.data.message, type: 'error' });
});
},
onChangeEnterprise(v) {
let item = this.entepriseList.find(el => el.wxEnterpriseId == v);
this.materials = [];
if (item) {
this.form.qfxxEnterpriseName = item.corpName;
} else {
this.form.qfxxEnterpriseName = '';
}
},
onDeleteMaterial(id) {
this.materials = this.materials.filter(el => el.relation_id != id);
},
onSelectMaterial(item) {
this.materials.push({
type: item.materialType,
relation_id: item.materialId,
title: item.materialTitle,
content: item.materialContent || item.link,
img: item.imgUrl
});
}
},
watch: {
show: {
handler() {
if (Object.keys(this.item).length > 0) {
this.isEdit = true;
for (let key in this.form) {
if (this.item.qfxx[key] !== undefined) {
this.form[key] = this.item.qfxx[key];
}
}
if (this.item.qfxx && this.item.qfxx.chatContent) {
this.materials = JSON.parse(this.item.qfxx.chatContent || '[]');
}
this.form.title = this.item.title;
this.ecmMarketingTypeRelationId = this.item.ecmMarketingTypeRelationId;
} else {
this.isEdit = false;
}
},
immediate: true,
deep: true
}
}
};
</script>
<style lang="scss" scoped>
.chat-item {
width: 240px;
height: 100px;
border: 1px dotted #dcdfe6;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
cursor: pointer;
.el-icon-plus {
color: #1890ff;
font-size: 24px;
}
.add-text {
margin-top: 12px;
font-size: 14px;
font-weight: 400;
color: #303133;
}
&:hover {
border-color: #1890ff;
}
}
.task-desc {
/deep/ .el-input__count {
background-color: transparent;
bottom: 0;
}
}
.card-item {
margin-top: 10px;
margin-right: 10px;
}
</style>
......@@ -17,12 +17,12 @@
<i class="dm-marketing__content--index">{{ i + 1 }}</i>
<component :is="v.comName" :item="v.item" :isSupportVar="isSupportVar"></component>
<template v-if="!readOnly">
<i class="el-icon-edit dm-marketing__opt--icon" v-if="showEdit(v) && (v.comName === 'item-teltask' || v.comName === 'item-text' || v.comName === 'item-wxa' || v.comName === 'item-integral' || v.comName === 'item-qywx')" @click="editItem(v)"></i>
<i class="el-icon-edit dm-marketing__opt--icon" v-if="showEdit(v) && (v.comName === 'item-teltask' || v.comName === 'item-text' || v.comName === 'item-wxa' || v.comName === 'item-integral' || v.comName === 'item-qywx' || v.comName === 'item-qfxx')" @click="editItem(v)"></i>
<dm-delete @confirm="delItem(v)">
<i class="el-icon-delete dm-marketing__opt--icon"></i>
</dm-delete>
</template>
<i v-else-if="v.comName == 'item-qywx'" class="el-icon-view dm-marketing__opt--icon" @click="editItem(v)"></i>
<i v-else-if="v.comName == 'item-qywx' || v.comName == 'item-qfxx'" class="el-icon-view dm-marketing__opt--icon" @click="editItem(v)"></i>
</div>
</div>
</div>
......@@ -54,6 +54,7 @@ import itemTeltask from './components/item-teltask.vue';
import itemIntegral from './components/item-integral.vue';
import itemGrade from './components/item-grade';
import itemQywx from './components/item-qywx';
import itemQfxx from './components/item-qfxx';
//弹窗组件
import libTeletext from './components/lib-teletext.vue';
import libMessage from './components/lib-Message.vue';
......@@ -65,10 +66,11 @@ import libTeltask from './components/lib-teltask.vue';
import libIntegral from './components/lib-integral.vue';
import libGrade from './components/lib-grade';
import libQywx from './components/lib-qywx';
import libQfxx from './components/lib-qfxx';
// 全部的操作项
// eslint-disable-next-line
let allOptions = [{ name: '企微任务', value: 'qywx', key: 10, img: require('./assets/img/qywx.svg'), hoverImg: require('./assets/img/qywx-1.svg'), show: true }, { name: '图文', value: 'teletext', key: 1, img: require('./assets/img/teletext.svg'), hoverImg: require('./assets/img/teletext-1.svg'), show: true }, { name: '文本', value: 'text', key: 2, img: require('./assets/img/text.svg'), hoverImg: require('./assets/img/text-1.svg'), show: true }, { name: '小程序', value: 'wxa', key: 3, img: require('./assets/img/wxa.svg'), hoverImg: require('./assets/img/wxa-1.svg'), show: true }, { name: '图片', value: 'image', key: 4, img: require('./assets/img/image.svg'), hoverImg: require('./assets/img/image-1.svg'), show: true }, { name: '卡券', value: 'card', key: 5, img: require('./assets/img/card.svg'), hoverImg: require('./assets/img/card-1.svg'), show: true }, { name: '短信', value: 'message', key: 6, img: require('./assets/img/message.svg'), hoverImg: require('./assets/img/message-1.svg'), show: true }, { name: '话务', value: 'teltask', key: 7, img: require('./assets/img/teltask.svg'), hoverImg: require('./assets/img/teltask-1.svg'), show: true }, { name: '积分', value: 'integral', key: 8, img: require('./assets/img/integral.svg'), hoverImg: require('./assets/img/integral-1.svg'), show: true },{ name: '会员卡升级', value: 'grade', key: 9, img: require('./assets/img/grade.svg'), hoverImg: require('./assets/img/grade-1.svg'), disabledImg: require('./assets/img/grade-2.svg'), show: false, disabled: false }];
let allOptions = [{ name: '企微任务', value: 'qywx', key: 10, img: require('./assets/img/qywx.svg'), hoverImg: require('./assets/img/qywx-1.svg'), show: true }, { name: '群发任务', value: 'qfxx', key: 11, img: require('./assets/img/qfxx.svg'), hoverImg: require('./assets/img/qfxx-1.svg'), disabledImg: require('./assets/img/qfxx-2.svg'), show: false, disabled: false }, { name: '图文', value: 'teletext', key: 1, img: require('./assets/img/teletext.svg'), hoverImg: require('./assets/img/teletext-1.svg'), show: true }, { name: '文本', value: 'text', key: 2, img: require('./assets/img/text.svg'), hoverImg: require('./assets/img/text-1.svg'), show: true }, { name: '小程序', value: 'wxa', key: 3, img: require('./assets/img/wxa.svg'), hoverImg: require('./assets/img/wxa-1.svg'), show: true }, { name: '图片', value: 'image', key: 4, img: require('./assets/img/image.svg'), hoverImg: require('./assets/img/image-1.svg'), show: true }, { name: '卡券', value: 'card', key: 5, img: require('./assets/img/card.svg'), hoverImg: require('./assets/img/card-1.svg'), show: true }, { name: '短信', value: 'message', key: 6, img: require('./assets/img/message.svg'), hoverImg: require('./assets/img/message-1.svg'), show: true }, { name: '话务', value: 'teltask', key: 7, img: require('./assets/img/teltask.svg'), hoverImg: require('./assets/img/teltask-1.svg'), show: true }, { name: '积分', value: 'integral', key: 8, img: require('./assets/img/integral.svg'), hoverImg: require('./assets/img/integral-1.svg'), show: true },{ name: '会员卡升级', value: 'grade', key: 9, img: require('./assets/img/grade.svg'), hoverImg: require('./assets/img/grade-1.svg'), disabledImg: require('./assets/img/grade-2.svg'), show: false, disabled: false }];
export default {
name: 'vue-gic-marketing-event',
components: {
......@@ -95,7 +97,9 @@ export default {
'item-grade': itemGrade,
'lib-grade': libGrade,
'item-qywx': itemQywx,
'lib-qywx': libQywx
'lib-qywx': libQywx,
'lib-qfxx': libQfxx,
'item-qfxx': itemQfxx
},
props: {
// 页面编码——- 1001-智能引擎; 1002-微信营销; 1003-被关注回复; 1004-关键字回复
......@@ -184,13 +188,13 @@ export default {
}
if (this.useQywx) {
this.options.forEach(item => {
if (item.value == 'qywx') {
if (item.value == 'qywx' || item.value == 'qfxx') {
item.show = true;
}
});
} else {
this.options.forEach(item => {
if (item.value == 'qywx') {
if (item.value == 'qywx' || item.value == 'qfxx') {
item.show = false;
}
});
......@@ -238,15 +242,15 @@ export default {
// },
// },
list() {
if (this.list.some(item => item.comName === 'item-grade')) {
if (this.list.some(item => item.comName === 'item-grade' || item.comName === 'item-qfxx')) {
this.options.forEach(item => {
if (item.value == 'grade') {
if (item.value == 'grade' || item.value == 'qfxx') {
item.disabled = true;
}
});
} else {
this.options.forEach(item => {
if (item.value == 'grade') {
if (item.value == 'grade' || item.value == 'qfxx') {
item.disabled = false;
}
});
......@@ -318,6 +322,9 @@ export default {
case 'qywx': // 8 积分
this.list.push({ comName: 'item-qywx', item: { title: v.title, qywx: v.qywx, ecmMarketingTypeRelationId: v.ecmMarketingTypeRelationId, relationId: v.relationId, ecmPlanId: v.ecmPlanId } });
break;
case 'qfxx': // 8 积分
this.list.push({ comName: 'item-qfxx', item: { title: v.title, qfxx: v.qfxx, ecmMarketingTypeRelationId: v.ecmMarketingTypeRelationId, relationId: v.relationId, ecmPlanId: v.ecmPlanId } });
break;
}
});
this.hasReturnCard();
......@@ -408,7 +415,7 @@ export default {
params.title = val.title;
params.relationId = val.relationId;
}
if (val.comName === 'qywx') {
if (val.comName === 'qywx' || val.comName === 'qfxx') {
params = { ...params, ...val };
delete params.comName;
}
......
<template>
<div class="dm-wrap" v-loading="loading">
<el-row>
<el-input class="w300" v-model="listParams.search" placeholder="请输入操作对象/操作内容" clearable @change="onSearch">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="onSearch"></el-date-picker>
</el-row>
<el-table class="mt20" :data="list">
<el-table-column prop="prop" label="操作人" width="width"></el-table-column>
<el-table-column prop="prop" label="操作对象" width="width"></el-table-column>
<el-table-column prop="prop" label="操作时间" width="width"></el-table-column>
<el-table-column prop="prop" label="操作内容" width="width"></el-table-column>
</el-table>
<dm-pagination v-show="tableList.length" background class="dm-pagination" @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>
</template>
<script>
import { getEcmLog } from '@/service/api/ecmApi.js';
export default {
name: 'ecm-operator-Log',
data() {
return {
loading: false,
tableList: [],
total: 0,
dateRange: [],
listParams: {
pageSize: 20,
currentPage: 1,
beginTime: '',
endTime: '',
search: ''
}
};
},
mounted() {
this.getList();
},
methods: {
handleSizeChange(val) {
this.listParams.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listParams.currentPage = val;
this.getList();
},
async getList() {
this.loading = true;
const { errorCode, result, message } = await getEcmLog(this.listParams).finally(() => (this.loading = false));
if (errorCode == 0) {
this.tableList = result || [];
} else {
this.$message.warning(message);
}
},
onSearch() {
this.listParams.currentPage = 1;
this.getList();
}
},
watch: {
dateRange(val) {
if (val) {
this.listParams.beginTime = val[0];
this.listParams.endTime = val[1];
} else {
this.listParams.beginTime = '';
this.listParams.endTime = '';
}
}
}
};
</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