Commit 179b482d by crushh

update: dist

parent d93b434a
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
</div> </div>
<span slot="reference"> <span slot="reference">
<a :href="'/member/#/wechatmemberDetail?memberId=' + row.memberId" target="_blank"> <a :href="'/member/#/wechatmemberDetail?memberId=' + row.memberId" target="_blank">
<img class="vertical-middle table__avatar--40" :src="filterAvatar(row.imageUrl)" width="40" height="40" alt="" srcset="" /> <img v-if="showImg" class="vertical-middle table__avatar--40" :src="filterAvatar(row.imageUrl)" width="40" height="40" alt="" srcset="" />
<div class="inline-block vertical-middle"> <div class="inline-block vertical-middle">
<p class="table-name--ellipsis">{{ row.memberName || '--' }}</p> <p class="table-name--ellipsis">{{ row.memberName || '--' }}</p>
<p class="table-name--ellipsis fz13">{{ row.cardNum || '--' }}</p> <p class="table-name--ellipsis fz13">{{ row.cardNum || '--' }}</p>
...@@ -63,6 +63,10 @@ export default { ...@@ -63,6 +63,10 @@ export default {
default() { default() {
return {}; return {};
} }
},
showImg:{
type:Boolean,
default:true
} }
}, },
data() { data() {
......
...@@ -21,6 +21,9 @@ export default { ...@@ -21,6 +21,9 @@ export default {
case 4: case 4:
str = '客户复购'; str = '客户复购';
break; break;
case 5:
str = '开卡场景';
break;
case 0: case 0:
str = '其它场景'; str = '其它场景';
break; break;
......
...@@ -129,3 +129,6 @@ export const continueActivityPlan = params => requests('/api-marketing/ai/contin ...@@ -129,3 +129,6 @@ export const continueActivityPlan = params => requests('/api-marketing/ai/contin
// 【Ai活动计划】手动暂停活动计划 // 【Ai活动计划】手动暂停活动计划
export const suspendActivityPlan = params => requests('/api-marketing/ai/suspend-activity-plan', params, true, false, 'get'); export const suspendActivityPlan = params => requests('/api-marketing/ai/suspend-activity-plan', params, true, false, 'get');
// 【Ai活动计划】非会员开卡 - 导入Excel
export const importAiCallPhone = params => requests('/api-marketing/ai/import-ai-call-phone', params, true);
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
<div class="section"> <div class="section">
<birthSense ref="activeTime1" :data="birthTimeData" v-show="form.scene == 1" @change="getMemberCount" /> <birthSense ref="activeTime1" :data="birthTimeData" v-show="form.scene == 1" @change="getMemberCount" />
<holidaySense ref="activeTime2" :data="holidayTimeData" v-show="form.scene == 2" @change="getMemberCount" /> <holidaySense ref="activeTime2" :data="holidayTimeData" v-show="form.scene == 2" @change="getMemberCount" />
<activeTime ref="activeTime" :data="activeTimeData" v-show="form.scene == 3 || form.scene == 4 || form.scene == 0" :scene="scene" @change="getMemberCount" /> <activeTime ref="activeTime" :data="activeTimeData" v-show="form.scene == 3 || form.scene == 4 || form.scene == 0 || form.scene == 5" :scene="scene" @change="getMemberCount" />
</div> </div>
<dm-sub-title type="line">人群规则<span class="tips ml20">针对选择的客户仅会执行一次外呼任务。</span></dm-sub-title> <dm-sub-title type="line">人群规则<span class="tips ml20">针对选择的客户仅会执行一次外呼任务。</span></dm-sub-title>
<div class="section"> <div class="section" v-if="form.scene != 5">
<el-form-item prop="memberType" required> <el-form-item prop="memberType" required>
<template slot="label"> <template slot="label">
<span>参与人群</span> <span>参与人群</span>
...@@ -65,16 +65,20 @@ ...@@ -65,16 +65,20 @@
<span class="tips ml10">勾选消费条件后,添加规则不支持选择【金字塔分层】</span> <span class="tips ml10">勾选消费条件后,添加规则不支持选择【金字塔分层】</span>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="预计覆盖人数"> <el-form-item label="预计覆盖人数">
<span class="bold">{{ planMemberCountShow }}</span> <span class="bold">{{ planMemberCountShow }}</span>
<span class="tips ml20">不包含无手机号的客户,以最终活动覆盖人数为准</span> <span class="tips ml20">不包含无手机号的客户,以最终活动覆盖人数为准</span>
</el-form-item> </el-form-item>
</div> </div>
<div class="section" v-else>
<el-form-item label="号码导入" prop="phoneList">
<dm-import-file ref="importFile" :options="importFileOption"></dm-import-file>
</el-form-item>
</div>
<dm-sub-title type="line">外呼规则配置</dm-sub-title> <dm-sub-title type="line">外呼规则配置</dm-sub-title>
<div class="section" style="padding-bottom: 40px;"> <div class="section" style="padding-bottom: 40px;">
<!--根据客户意向打标签 --> <!--根据客户意向打标签 -->
<div class="card"> <div class="card" v-if="form.scene != 5">
<div class="tagHead"> <div class="tagHead">
<div class="left"> <div class="left">
<div class="title">根据客户意向打标签</div> <div class="title">根据客户意向打标签</div>
...@@ -257,6 +261,7 @@ ...@@ -257,6 +261,7 @@
</div> </div>
</div> </div>
<dm-form-bottom> <dm-form-bottom>
<el-button @click="handleImport">test</el-button>
<el-button type="primary" @click="handleSubmit" :loading="btnLoading">保 存</el-button> <el-button type="primary" @click="handleSubmit" :loading="btnLoading">保 存</el-button>
</dm-form-bottom> </dm-form-bottom>
</el-form> </el-form>
...@@ -279,7 +284,7 @@ ...@@ -279,7 +284,7 @@
<script> <script>
import filterAvater from '@/mixins/filterAvater.js'; import filterAvater from '@/mixins/filterAvater.js';
import { templateList, aiDictList, initActivity, getActivityDetail, getMemberCount, getAiCalcSingle, rechargeCenter } from '@/service/api/aiApi.js'; import { templateList, aiDictList, initActivity, getActivityDetail, getMemberCount, getAiCalcSingle, rechargeCenter, importAiCallPhone } from '@/service/api/aiApi.js';
import birthSense from '@/views/ai/task/components/birthActiveTime.vue'; import birthSense from '@/views/ai/task/components/birthActiveTime.vue';
import holidaySense from '@/views/ai/task/components/holidayActiveTime.vue'; import holidaySense from '@/views/ai/task/components/holidayActiveTime.vue';
import LibMessage from '@/views/ecm/marketing-event/components/lib-message.vue'; import LibMessage from '@/views/ecm/marketing-event/components/lib-message.vue';
...@@ -314,6 +319,13 @@ export default { ...@@ -314,6 +319,13 @@ export default {
cb(); cb();
} }
}); });
const phoneListVal = (rule, value, callback) => {
if (this.form.scene == 5 && !this.form.phoneList.length) {
return callback(new Error('请上传文件'));
}
callback();
};
return { return {
validateOption, validateOption,
validateVal, validateVal,
...@@ -338,7 +350,8 @@ export default { ...@@ -338,7 +350,8 @@ export default {
recallFlag: 0, //是否根据未接通状态设置重拨 recallFlag: 0, //是否根据未接通状态设置重拨
planMemberCount: '- -', //覆盖人数 planMemberCount: '- -', //覆盖人数
analyseDays: 14, //分析天数 analyseDays: 14, //分析天数
analyseAmount: '' //销售额 analyseAmount: '', //销售额
phoneList: []
}, },
birthTimeData: { birthTimeData: {
// 生日场景 活动时间的回显 // 生日场景 活动时间的回显
...@@ -385,7 +398,8 @@ export default { ...@@ -385,7 +398,8 @@ export default {
{ required: true, message: '活动目标不能为空' }, { required: true, message: '活动目标不能为空' },
{ type: 'number', message: '请输入长度不超过五位的正整数', max: 99999, min: 1 } { type: 'number', message: '请输入长度不超过五位的正整数', max: 99999, min: 1 }
], ],
memberType: { required: true, validator: memberType } memberType: { required: true, validator: memberType },
phoneList: { required: true, validator: phoneListVal }
}, },
tagMatchList: [ tagMatchList: [
// 打标签列表 // 打标签列表
...@@ -427,6 +441,18 @@ export default { ...@@ -427,6 +441,18 @@ export default {
3: '默认为未添加企微好友', 3: '默认为未添加企微好友',
4: '默认为权限范围内', 4: '默认为权限范围内',
0: '默认为权限范围内' 0: '默认为权限范围内'
},
importFileOption: {
desc: '手机号数量单次最多不超过5000条,上传文件不能大于2M,支持格式:.xlsx、.xls、.csv',
maxSize: 2097152,
maxSizeDesc: '2M',
downloadTemplate: [
{
url: '/api-marketing/ai/download-import-ai-temp?requestProject=gic-web',
name: '下载模板'
}
]
} }
}; };
}, },
...@@ -605,10 +631,10 @@ export default { ...@@ -605,10 +631,10 @@ export default {
}); });
} }
} }
this.handleImport();
this.$refs.form.validate(async (val, obj) => { this.$refs.form.validate(async (val, obj) => {
console.log(val, obj);
if (val) { if (val) {
let { activityName, scene, analyseFlag, analyseDays, analyseAmount, planName, memberType, aiTemplateId, labelFlag, smsFlag, recallFlag, activityId, planId, aiEventId, eventId, planMemberCount, consume_days_flag, consume_days, consume_times_flag, consume_times, consume_amount_flag, consume_amount } = this.form; let { phoneList, activityName, scene, analyseFlag, analyseDays, analyseAmount, planName, memberType, aiTemplateId, labelFlag, smsFlag, recallFlag, activityId, planId, aiEventId, eventId, planMemberCount, consume_days_flag, consume_days, consume_times_flag, consume_times, consume_amount_flag, consume_amount } = this.form;
let sceneJson = {}; let sceneJson = {};
if (isNaN(planMemberCount)) { if (isNaN(planMemberCount)) {
planMemberCount = 0; planMemberCount = 0;
...@@ -642,6 +668,7 @@ export default { ...@@ -642,6 +668,7 @@ export default {
startDate, startDate,
endDate, endDate,
analyseFlag, analyseFlag,
phoneList: scene == 5 ? phoneList : undefined,
analyseDays: analyseFlag == 1 ? analyseDays : undefined, analyseDays: analyseFlag == 1 ? analyseDays : undefined,
analyseAmount: analyseFlag == 1 ? analyseAmount : undefined, analyseAmount: analyseFlag == 1 ? analyseAmount : undefined,
activityPlanList: [ activityPlanList: [
...@@ -813,7 +840,31 @@ export default { ...@@ -813,7 +840,31 @@ export default {
this.unitPrice = (result.unit / 1000).toFixed(2); this.unitPrice = (result.unit / 1000).toFixed(2);
console.log(this.unitPrice); console.log(this.unitPrice);
}, },
async handleImport() {
this.$refs.importFile.getFileData().then(({ files }) => {
const [file] = files;
const formData = new FormData();
formData.append('file', file);
formData.append('requestProject', 'gic-web');
if (this.extendData) {
Object.keys(this.extendData).forEach(k => {
formData[k] = this.extendData[k];
formData.append(k, this.extendData[k]);
});
}
importAiCallPhone(formData).then(res => {
const { phoneList, phoneCount, errorPhoneList } = res.result;
if (res.errorCode == 0) {
this.form.phoneList = phoneList;
if (errorPhoneList && errorPhoneList.length) {
this.$message.error(`导入数据${phoneCount}条,其中${errorPhoneList.length}条号码格式有误,已过滤`);
}
} else {
this.$message.error(res.data.message);
}
});
});
},
handleChangeNum: _debounce(function(val) { handleChangeNum: _debounce(function(val) {
val && this.getMemberCount(); val && this.getMemberCount();
}, 600), }, 600),
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<el-descriptions-item label="外呼周期">{{ holidayTimeData.activeTime }}</el-descriptions-item> <el-descriptions-item label="外呼周期">{{ holidayTimeData.activeTime }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
<div class="section" v-if="form.scene == 3 || form.scene == 4 || form.scene == 0"> <div class="section" v-if="form.scene == 3 || form.scene == 4 || form.scene == 0 || form.scene == 5">
<el-descriptions column="4"> <el-descriptions column="4">
<el-descriptions-item label="外呼时段"> {{ activeTimeData.callTime }}</el-descriptions-item> <el-descriptions-item label="外呼时段"> {{ activeTimeData.callTime }}</el-descriptions-item>
<el-descriptions-item label="外呼周期">{{ activeTimeData.activeTime }}</el-descriptions-item> <el-descriptions-item label="外呼周期">{{ activeTimeData.activeTime }}</el-descriptions-item>
......
...@@ -242,6 +242,12 @@ export default { ...@@ -242,6 +242,12 @@ export default {
scene: 0, scene: 0,
iconName: 'icon-qitachangjing', iconName: 'icon-qitachangjing',
content: '自定义营销场景' content: '自定义营销场景'
},
{
title: '开卡场景',
scene: 5,
iconName: 'icon-kaika',
content: '针对非会员营销,提升开卡率'
} }
], ],
optionScenes: [ optionScenes: [
...@@ -489,7 +495,7 @@ export default { ...@@ -489,7 +495,7 @@ export default {
}); });
}, },
handleSuspend({ planId }) { handleSuspend({ planId }) {
this.$confirm('任务正在进行中,暂停任务后,计划将中止', '提示', { this.$confirm('任务正在进行中,暂停任务后,计划将暂停', '提示', {
confirmButtonText: '暂停', confirmButtonText: '暂停',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
...@@ -562,17 +568,15 @@ export default { ...@@ -562,17 +568,15 @@ export default {
margin: 0 20px; margin: 0 20px;
.cardList { .cardList {
display: flex; display: flex;
flex-wrap: wrap;
gap: 12px;
.card { .card {
width: 20%; min-width: 224px;
height: 140px; height: 140px;
background: #f0f3fd; background: #f0f3fd;
border-radius: 4px; border-radius: 4px;
padding: 12px 16px; padding: 12px 16px;
box-sizing: border-box; box-sizing: border-box;
margin-right: 12px;
&:last-child {
margin-right: 0;
}
} }
.cardTitle { .cardTitle {
i { i {
...@@ -592,6 +596,7 @@ export default { ...@@ -592,6 +596,7 @@ export default {
font-size: 14px; font-size: 14px;
line-height: 20px; line-height: 20px;
height: 40px; height: 40px;
width: 192px;
color: #606266; color: #606266;
} }
} }
......
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
<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"> <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-scope="scope"> <template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span> <span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<component v-else-if="v.component" :is="v.component" :row="scope.row"></component> <component v-else-if="v.component" :is="v.component" :row="scope.row" :showImg="v.showImg"></component>
<span v-else>{{ scope.row[v.prop] || '--' }}</span> <span v-else>{{ scope.row[v.prop] || '--' }}</span>
</template> </template>
</el-table-column> </el-table-column>
...@@ -167,7 +167,7 @@ export default { ...@@ -167,7 +167,7 @@ export default {
return row.title || '--'; return row.title || '--';
} }
}, },
{ label: '会员信息', prop: 'marketingType', minWidth: '120', align: 'left', component: 'member-info' }, { label: '会员信息', prop: 'marketingType', minWidth: '120', align: 'left', component: 'member-info', showImg: 0 },
{ label: '手机号码', prop: 'phoneNumber', minWidth: '120', align: 'left' }, { label: '手机号码', prop: 'phoneNumber', minWidth: '120', align: 'left' },
{ label: '主门店', prop: 'mainStoreName', minWidth: '120', align: 'left' }, { label: '主门店', prop: 'mainStoreName', minWidth: '120', align: 'left' },
{ label: '专属导购', prop: 'mainClerkName', minWidth: '120', align: 'left' }, { label: '专属导购', prop: 'mainClerkName', minWidth: '120', align: 'left' },
......
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