Commit 6765bb83 by crushh

Merge branch 'feature/3月迭代' into dev

parents a2634e76 0f2b4e7d
......@@ -8,7 +8,9 @@
<!-- <title>GIC后台</title> -->
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.BASE_URL %>static/fonts/iconfont.css">
<link rel="stylesheet" type="text/css" href="<%= htmlWebpackPlugin.options.BASE_URL %>static/css/common.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_2996579_93aeeozj35q.css">
<!-- <link rel="stylesheet" href="//at.alicdn.com/t/font_2996579_93aeeozj35q.css"> -->
<link rel="stylesheet" href="//at.alicdn.com/t/font_3229694_b36vgmw8y2d.css"> <!--GIC3.0营销-->
<link rel="stylesheet" href="//at.alicdn.com/t/font_3229694_b36vgmw8y2d.js"> <!--GIC3.0营销-->
<!-- <link rel="stylesheet" href="//web-1251519181.file.myqcloud.com/components/element.2.12.0.css"> -->
<!-- element 皮肤 -->
<!-- <link rel="stylesheet" type="text/css" href="http://web-1251519181.file.myqcloud.com/lib/elementUI/theme.1.0.1/index.css"> -->
......
......@@ -253,6 +253,9 @@ a:hover {
.w300{
width: 300px!important;
}
.w340{
width: 340px!important;
}
.w350{
width: 350px!important;
}
......@@ -554,3 +557,18 @@ img::after {
color: #096dd9 !important;
}
}
.delIcon {
width: 24px;
display: inline-block;
height: 24px;
border-radius: 2px;
text-align: center;
color: #f5222d;
line-height: 24px;
margin-left: 6px;
cursor: pointer;
&:hover {
background: #f6e1e5;
}
}
\ No newline at end of file
<template>
<div>
<el-button v-for="item in notDropdownList" :disabled="typeof item.disabled === 'function' ? item.disabled(scopeData) : item.disabled" v-bind="{ type: 'text', ...item.props }" :key="item.text" @click="handleCommand(item)">{{ item.text }}</el-button>
<el-dropdown v-if="buttonArray.length > max" v-bind="{ type: 'text', ...dropdownProps }" @click="() => emitEventHandler('click')" @command="handleCommand" @visible-change="bool => emitEventHandler('visible-change', bool)">
<span class="el-dropdown-link">
<i class="iconfont icon-more"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item in dropdownList" :class="{ 'item-disabled': typeof item.disabled === 'function' ? item.disabled(scopeData) : item.disabled }" :command="item" :key="item.text">
<el-button :disabled="typeof item.disabled === 'function' ? item.disabled(scopeData) : item.disabled" v-bind="{ type: 'text', ...item.props }">{{ item.text }}</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
export default {
name: 'dm-dropdown',
components: {},
props: {
dropdownProps: {
//Dropdown Attributes
type: Object,
default: () => {}
},
configs: {
type: Array,
default: () => []
},
max: {
type: [Number, String],
default: 3
},
scopeData: Object
},
methods: {
emitEventHandler(event) {
this.$emit(event, ...Array.from(arguments).slice(1));
},
handleCommand(config) {
if (typeof config.disabled == 'function' ? config.disabled(this.scopeData) : config.disabled) return;
config.handler && config.handler(this.scopeData);
this.emitEventHandler('command', { config, data: this.scopeData });
}
},
computed: {
buttonArray() {
return this.configs.filter(item => {
let visible = item.visible;
if (typeof visible === 'boolean') {
return item.visible;
} else if (typeof visible === 'function') {
return item.visible(this.scopeData);
} else {
return true;
}
});
},
notDropdownList() {
return this.buttonArray.length > this.max ? this.buttonArray.slice(0, this.max - 1) : this.buttonArray;
},
dropdownList() {
return this.buttonArray.length > this.max ? this.buttonArray.slice(this.max - 1) : [];
}
}
};
</script>
<style lang="scss" scoped>
.el-dropdown-link {
cursor: pointer;
color: #1890ff;
}
.el-button--text + .el-dropdown {
margin-left: 8px;
}
.item-disabled {
cursor: not-allowed;
}
</style>
## 示例
```
<el-table-column
fixed="right"
label="操作"
>
<template slot-scope="scope">
<dm-dropdown :scope-data="scope.row" :configs="btnArr" @command="onCommand"/>
</template>
</el-table-column>
export default {
name: 'btn',
data() {
return {
dropdownAttr: {
// splitButton: true
},
btnArr: [
{
text: '查看',
visible: (row)=>row.status === 2, // 不写visible属性默认为true
handler: (row) =>{
console.log(row)
console.log('查看')
},
},
{
text: '编辑',
handler: (row) =>{
console.log(row)
console.log('编辑')
},
},
{
text: '删除',
handler: (row) =>{
console.log(row)
console.log('删除')
}
},
{
text: '复制',
handler: (row) =>{
console.log(row)
console.log('复制')
},
},
{
text: '禁用',
handler: (row) =>{
console.log(row)
console.log('禁用')
},
}
],
}
},
methods: {
onCommand(item) {
console.log(item)
},
}
}
```
### props
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 是否必传 |
| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ |
| scopeData | - | Object | -- | -- | 否 |
| configs | 按钮数组 | Array | [{text:string(必传), visible: boolean \| function, handler: function,props:按钮属性配置(非必传)}] | -- | 是 |
| dropdownProps | el-dropDown的属性 | Object | -- | -- | 否 |
| max | 最多展示几个按钮 | String/Number | -- | 3 | 否 |
#### events
| 事件名称 | 说明 | 参数 |
| ------------ | ------------ | ------------ |
| command | 按钮触发事件 | {config, data} |
### 更新日志:
- v1.0.0 cr by 黄冷<br>
......@@ -5,6 +5,29 @@ export default {
defaultAvatar: require('../assets/img/head_default.png')
};
},
filters: {
sceneFilter(val) {
let str = '- -';
switch (val) {
case 1:
str = '客户生日';
break;
case 2:
str = '节日活动邀约';
break;
case 3:
str = '加企微好友';
break;
case 4:
str = '客户复购';
break;
case 5:
str = '其它场景';
break;
}
return str;
}
},
methods: {
filterAvatar(img) {
return img ? img.replace(/^http(s)?/, 'https') : this.defaultAvatar;
......
export default {
path: 'ai',
name: 'ai营销',
component: () => import('../../views/ai/index.vue'),
meta: {},
redirect: 'ai/list',
children: [
{
path: 'list',
name: '列表',
component: () => import('../../views/ai/list.vue'),
meta: {}
},
{
path: 'form',
name: '活动详情',
component: () => import('../../views/ai/form.vue'),
meta: {}
}
]
};
......@@ -32,7 +32,8 @@ import activity from './modules/activity';
import cdKey from './modules/cdKey';
//弹窗推广
import pop from './modules/pop';
// ai营销
import ai from './modules/ai';
//签到
import signIn from './modules/signIn';
export default [
......@@ -61,7 +62,8 @@ export default [
activity,
cdKey,
pop,
signIn
signIn,
ai
]
},
{
......
import { requests } from './index';
const PREFIX = 'api-marketing/ai/';
//活动分页查询-统计
export const pageStatistics = params => requests(PREFIX + 'page-statistics', params, true);
//活动分页查询
export const page = params => requests(PREFIX + 'page', params, true);
//计费中心--获取账号余额, 今日消费
export const rechargeCenter = params => requests('/api-marketing/recharge-center', params);
//查看话术模板列表
export const templateList = params => requests(PREFIX + 'get-template-list', params, true);
//营销活动场景/客户意向等级/重拨状态
export const aiDictList = params => requests('/api-marketing/ai-dict-list', params, true, false, 'get');
//新建ai活动
export const initActivity = params => requests(PREFIX + '/init-activity', params, true);
......@@ -110,7 +110,7 @@ const requests = (url, data = {}, contentTypeIsJSON = false, isSilence = false,
_opts.data = qs.stringify(Object.assign({ requestProject: 'gic-web' }, data));
}
} else {
_opts.params = _query;
_opts.params = Object.assign({ requestProject: 'gic-web' }, data);
}
let key = JSON.stringify(_opts);
......@@ -134,7 +134,7 @@ const requests = (url, data = {}, contentTypeIsJSON = false, isSilence = false,
.then(res => {
clearTimeout(_timer);
popRequest(_random);
if (res.data.errorCode !== 0) {
if (res.data.errorCode !== 0 && res.data.code != 0) {
reject(res);
// handlerErr(res.data.errorCode, res.data.message, alertError);
if (res.data.message.indexOf('抱歉') >= 0) {
......
......@@ -29,6 +29,10 @@ export const callData = params => requests(PREFIX + 'call-data', params);
//计费中心--通话录音消费详情
export const recordData = params => requests(PREFIX + 'call-record-data', params);
//计费中心--ai电话详情
export const aiCallData = params => requests(PREFIX + 'ai-billling-page', params);
//计费中心--AI电话详情消费总额
export const getAiTotalFee = params => requests(PREFIX + 'get-ai-total-fee', params);
//计费中心--点击充值后--第一步:获取余额, 各项服务单价
export const rechargeStep0 = params => requests(PREFIX + 'recharge-step-1', params);
......
<template>
<el-form :model="form" ref="form" label-width="100px" :rules="rules">
<el-form-item label="外呼时间" required>
<el-radio v-model="form.birth_type" :label="1" @change="onChangeEffectType">生日当天</el-radio>
<el-radio v-model="form.birth_type" :label="2" @change="onChangeEffectType">生日当月</el-radio>
<el-radio v-model="form.birth_type" :label="3" @change="onChangeEffectType">生日前<el-input class="w100" style="margin:0 5px;" v-model="form.birth_days" /></el-radio>
</el-form-item>
<el-form-item label="生日范围" prop="birthDate1" v-show="form.birth_type == 1 || form.birth_type == 3">
<el-date-picker value-format="timestamp" format="MM-dd" v-model="form.birthDate1" @change="handleDateChange" :picker-options="pickerOptions" type="daterange" placeholder="请选择生日范围" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期"> </el-date-picker>
</el-form-item>
<el-form-item label="生日范围" prop="birthDate2" v-show="form.birth_type == 2">
<el-date-picker type="monthrange" value-format="timestamp" format="MM月" v-model="form.birthDate2" @change="handleDateMonthChange" :picker-options="pickerOptionsMonth" placeholder="请选择生日范围" range-separator="~" start-placeholder="开始月份" end-placeholder="结束月份"> </el-date-picker>
</el-form-item>
<el-form-item label="外呼时段" required>
<el-radio v-model="form.call_flag" :label="0" @change="onChangeEffectType">默认时段</el-radio>
<el-radio v-model="form.call_flag" :label="1" @change="onChangeEffectType">自定义时段</el-radio>
<div v-show="form.call_flag == 0" style="line-height: 20px;">
每天 09:00-20:00
</div>
<defineTime v-show="form.call_flag == 1" ref="defineTime" />
</el-form-item>
<el-form-item label="活动有效期" required>
<span v-if="!activeTime" class="tips" style="font-size: 14px;margin:0">设置【生日范围】和【外呼时间】后自动生成</span>
<span v-else>{{ activeTime }}</span>
</el-form-item>
</el-form>
</template>
<script>
import defineTime from './defineTime.vue';
import { formatDateTimeByType } from '@/utils/index';
let minTime = null;
let maxTime = null;
let minTimeMonth = null;
let maxTimeMonth = null;
export default {
data() {
const birthDateValidtor = (rule, value, callback) => {
if ((this.form.birth_type == 1 || this.form.birth_type == 3) && !this.form.birthDate1.length) {
return callback(new Error('生日范围不能为空'));
} else if (this.form.birth_type == 2 && !this.form.birthDate2.length) {
return callback(new Error('生日范围不能为空'));
}
callback();
};
return {
formatDateTimeByType,
form: {
birthDate1: '', //生日范围 当天
birthDate2: '', //生日范围 当月
birth_type: 1, //外呼时间 1当天 2当月 3生日前
call_flag: 0 //外呼时段 0 默认 1 自定义
},
rules: {
birthDate1: { validator: birthDateValidtor },
birthDate2: { validator: birthDateValidtor }
},
pickerOptions: {
onPick(time) {
// 起始时间:仅半年范围内 && 结束时间:跨度最多3个月,即所选起始时间往后+90天为上限;
if (!time.maxDate) {
const timeRange = 90 * 24 * 60 * 60 * 1000; // 3个月
minTime = time.minDate.getTime(); // 最小时间
maxTime = time.minDate.getTime() + timeRange; // 最大时间
}
},
disabledDate: time => {
const timeRange = 30 * 24 * 60 * 60 * 1000; // 3个月
if (minTime && maxTime) {
return time.getTime() < minTime || time.getTime() > maxTime;
} else {
return time.getTime() < new Date().getTime() - 24 * 60 * 60 * 1000 || time.getTime() > new Date().getTime() + timeRange;
}
}
},
pickerOptionsMonth: {
onPick(time) {
// 起始时间:仅半年范围内 && 结束时间:跨度最多3个月,即所选起始时间往后+90天为上限;
if (!time.maxDate) {
const timeRange = 90 * 24 * 60 * 60 * 1000; // 3个月
minTimeMonth = time.minDate.getTime(); // 最小时间
maxTimeMonth = time.minDate.getTime() + timeRange; // 最大时间
}
},
disabledDate: time => {
const timeRange = 180 * 24 * 60 * 60 * 1000; // 3个月
if (minTimeMonth && maxTimeMonth) {
return time.getTime() < minTimeMonth || time.getTime() > maxTimeMonth;
} else {
return time.getTime() < new Date().getTime() || time.getTime() > new Date().getTime() + timeRange;
}
}
}
};
},
computed: {
activeTime() {
let str = '';
if (this.form.birth_type == 1 && this.form.birthDate1.length) {
str = formatDateTimeByType(this.form.birthDate1[0], 'yyyy-MM-dd') + ' 至 ' + formatDateTimeByType(this.form.birthDate1[1], 'yyyy-MM-dd');
} else if (this.form.birth_type == 2 && this.form.birthDate2.length) {
str = formatDateTimeByType(this.form.birthDate2[0], 'yyyy-MM-dd') + ' 至 ' + formatDateTimeByType(this.form.birthDate2[1], 'yyyy-MM-dd');
}
return str;
}
},
components: {
defineTime
},
methods: {
submit() {
return new Promise(async resolve => {
const res = await this.$refs.defineTime.submit();
let arr = [];
if (!res) return;
res.timeRangeList.forEach(item => {
if (Object.keys(item).length) {
arr.push(`${item.startTime}-${item.endTime}`);
}
});
this.$refs.form.validate(val => {
if (val) {
const { birth_type, call_flag, birthDate1, birthDate2, callTime } = this.form;
const obj = {
startDate: birth_type == 2 ? birthDate2[0] : birthDate1[0],
endDate: birth_type == 2 ? birthDate2[1] : birthDate1[1],
call_flag,
birth_type,
callTime
};
if (arr.length) {
obj.callTime = arr;
}
resolve(obj);
} else {
resolve(false);
}
});
});
},
handleDateChange(val) {
console.log(val);
if (!val) {
minTime = maxTime = null;
}
},
handleDateMonthChange(val) {
console.log(val);
if (!val) {
minTimeMonth = maxTimeMonth = null;
}
}
}
};
</script>
<style></style>
<template>
<!--根据客户意向打标签 -->
<div class="card">
<div class="tagHead">
<div class="left">
<div class="title">{{ text.title }}</div>
<el-switch v-model="form.labelFlag" />
<div class="tips" v-show="text.tips">{{ text.tips }}</div>
</div>
<el-button type="text">{{ text.explanation }}</el-button>
</div>
<div v-show="form.labelFlag">
<div class="tagBody">
<table>
<thead>
<tr>
<th class="tableHead" v-for="(item, index) in tableColumn" :key="index">{{ item.text }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableData" :key="index">
<td class="tagSelectCell" style="width:420px">
<el-select filterable v-model="item.options" placeholder="请选择意向等级(多选)" @change="effectActionChange">
<el-option v-for="item in options" :key="item.aiTemplateId" :label="item.name" :value="item.aiTemplateId"></el-option>
</el-select>
</td>
<td class="tagSelectCell" style="width:170px">
<el-button type="text" v-if="!Object.keys(item.labels).length" @click="openTagsDialog(index)">选择标签</el-button>
<el-tag type="mini" v-else closable @close="handleTagClose(item.id)">{{ item.labels.name }}</el-tag>
</td>
<td class="tagSelectCell">
<div class="delIcon" type="text" @click="delTagList(index)">
<i class="iconfont icon-Delete"></i>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="tagFooter">
<el-button type="text" @click="addGrade"> <i class="iconfont icon-Plus"></i> {{ text.addText }} </el-button>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
tableData: {
type: Array,
default: () => []
},
options: {
type: Array,
default: () => []
},
text: {
type: Object,
default: () => {
return {
title: '客户意向等级',
tips: '开启后,可提高接通率',
explanation: '意向等级说明',
addText: '添加等级'
};
}
},
tableColumn: {
type: Array,
default: () => [
{
text: '客户意向等级',
prop: 'options'
},
{
text: '选择标签',
prop: 'select'
},
{
text: '操作',
prop: 'operate'
}
]
}
}
};
</script>
<style lang="scss" scoped>
.card {
width: 730px;
background: #f7f8fa;
border-radius: 4px;
box-sizing: border-box;
margin-top: 20px;
&:first-child {
margin-top: 0;
}
.tagHead {
width: 100%;
height: 60px;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 0 20px;
.left {
display: flex;
align-items: center;
.title {
width: 173px;
margin-right: 15px;
}
}
}
.tagBody {
border-top: 1px solid #e4e7ed;
box-sizing: border-box;
padding: 0 20px;
table {
width: 100%;
}
.tagSelectCell {
padding: 0 30px 12px 0;
}
}
.tagFooter {
padding: 0 20px 17px 20px;
}
.tableHead {
text-align: left;
font-weight: bold;
line-height: 20px;
color: #303133;
font-size: 14px;
height: 52px;
line-height: 52px;
}
}
</style>
<template>
<div class="defineTime">
<p class="tips">自定义时段不少于4个小时</p>
<el-form :model="form" ref="defineTime">
<el-form-item class="mt10" v-for="(v, i) in form.timeRangeList" :key="i" :prop="'timeRangeList.' + i + '.timeRange'" :rules="[{ validator: validateTime, trigger: 'change' }]">
<div style="display: flex;align-items: center;">
<el-time-select
placeholder="起始时间"
v-model="v.startTime"
:picker-options="{
start: '09:00',
step: '00:30',
end: '20:00'
}"
>
</el-time-select>
<el-time-select
placeholder="结束时间"
v-model="v.endTime"
:picker-options="{
start: '09:00',
step: '00:30',
end: '20:00',
minTime: startTime
}"
>
</el-time-select>
<div class="delIcon" type="text" @click="delTimeRange(i)">
<i class="iconfont icon-Delete"></i>
</div>
</div>
</el-form-item>
</el-form>
<el-button type="text" @click="addTimeRange"> <i class="iconfont icon-Plus"></i> 添加时间段 </el-button>
</div>
</template>
<script>
export default {
data() {
const validateTime = (rule, value, callback) => {
// if (!value) {
// return callback(new Error('请输入时间'));
// } else {
// callback();
// }
callback();
};
return {
validateTime,
form: {
timeRangeList: [{}]
}
};
},
methods: {
// 删除兑换时段
delTimeRange(index) {
this.form.timeRangeList.splice(index, 1);
},
// 添加兑换时段
addTimeRange() {
if (this.form.timeRangeList.length >= 5) {
this.$message.error('最多五个时间段');
return false;
}
this.form.timeRangeList.push({});
},
submit() {
return new Promise(resolve => {
this.$refs.defineTime.validate(val => {
if (val) {
resolve(this.form);
} else {
resolve(false);
}
});
});
}
}
};
</script>
<style lang="scss" scoped>
.defineTime {
width: 400px;
// height: 164px;
background: #f7f8fa;
border-radius: 4px;
padding: 16px;
box-sizing: border-box;
}
.tips {
font-size: 12px;
font-weight: 400;
color: #909399;
line-height: 17px;
}
</style>
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!this.$route.meta.keepAlive" />
</div>
</template>
<script></script>
<template>
<div>
<el-tabs v-model="activeName">
<el-tab-pane label="外呼任务" name="first">
<task />
</el-tab-pane>
<el-tab-pane label="话术管理" name="second">
<manage />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import task from './task.vue';
import manage from './manage.vue';
export default {
data() {
return {
activeName: 'first'
};
},
components: {
task,
manage
},
watch: {}
};
</script>
<style></style>
<template>
<div>
话术管理
</div>
</template>
<script>
export default {};
</script>
<style></style>
......@@ -44,7 +44,7 @@
<h3 class="dm-title__label border-top">今日消费</h3>
<select-depart v-if="config.isMoreAccount && config.showAllDepartment" :data="deparment1" class="mb20" @load="() => load('one')" @getDepartId="id => getDepartId(id, 'one')" @remote-search="val => remoteSearch(val, 'one')" :loading="deparment1.loading" />
<el-row class="recharge-today" :gutter="20" v-loading="loading1">
<el-col :span="8" style="padding: 0 2px">
<el-col :span="6" style="padding: 0 2px">
<div class="recharge-today-item border2 flex_between">
<div class="text-center">
<div class="icon-box">
......@@ -63,7 +63,7 @@
</div>
</div>
</el-col>
<el-col :span="8" style="padding: 0 2px">
<el-col :span="6" style="padding: 0 2px">
<div class="recharge-today-item border2 flex_between">
<div class="text-center">
<div class="icon-box color2">
......@@ -82,7 +82,7 @@
</div>
</div>
</el-col>
<el-col :span="8" style="padding: 0 2px">
<el-col :span="6" style="padding: 0 2px">
<div class="recharge-today-item border2 flex_between">
<div class="text-center">
<div class="icon-box color3">
......@@ -101,6 +101,25 @@
</div>
</div>
</el-col>
<el-col :span="6" style="padding: 0 2px">
<div class="recharge-today-item border2 flex_between">
<div class="text-center">
<div class="icon-box color4">
<i class="iconfont icon-AIdianhua fz36"></i>
</div>
</div>
<div class="flex_between flex1 pl10">
<div class="flex_column">
<p>AI电话</p>
<p>
<span class="fz22">{{ recharge.aiCount || 0 }}</span>
分钟
</p>
</div>
<p class="regular-font-color">合计费用:¥{{ (recharge.aiFee / 1000) | amount }}</p>
</div>
</div>
</el-col>
</el-row>
</div>
<div class="dm-wrap" style="margin-top: 12px">
......@@ -287,8 +306,16 @@ export default {
let res = await consumeRecord(para);
const result = res.result;
// , { name: '视频流量', type: 'video', fee: result.allTraffic, count: result.allTrafficCost }
if (type != 'one') this.tableList = [{ name: '短信营销', type: 'marketing', fee: result.messageFee, count: result.messageCount }, { name: '短信验证码', type: 'sms', fee: result.smsFee, count: result.smsCount }, { name: '双向呼叫', type: 'call', fee: result.callFee, count: result.callTime }]; // eslint-disable-line
else this.recharge = res.result;
if (type != 'one') {
this.tableList = [
{ name: '短信营销', type: 'marketing', fee: result.messageFee, count: result.messageCount },
{ name: '短信验证码', type: 'sms', fee: result.smsFee, count: result.smsCount },
{ name: '双向呼叫', type: 'call', fee: result.callFee, count: result.callTime },
{ name: 'AI电话', type: 'ai-call', fee: result.aiFee, count: result.aiCount }
];
} else {
this.recharge = res.result;
}
} catch (err) {
console.log(err);
}
......
......@@ -75,11 +75,25 @@
</el-radio-group>
</el-form-item>
</template>
<hr class="dashed mb20" v-if="isMoreAccount" />
<template v-if="isMoreAccount">
<h2 class="icon-type-title mb20">
<div class="mark" />
AI营销
</h2>
<el-form-item label="AI电话(包含短信):" prop="aiRule" class="mb20">
<el-radio-group v-model="form.aiRule">
<el-radio :label="2">会员所属服务门店</el-radio>
<el-radio :label="3">活动创建人</el-radio>
</el-radio-group>
</el-form-item>
</template>
</template>
</el-form>
<div class="footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="save">保 存</el-button>
<el-button type="primary" :loading="loading" @click="save">保 存</el-button>
</div>
</el-drawer>
</template>
......@@ -98,6 +112,7 @@ export default {
cb();
}
return {
loading: false,
form: {
status: 0, // 是否多账户
smsPlanRule: 2, // 短信营销
......@@ -106,7 +121,8 @@ export default {
smsOpenCardRule: 1, // 认证
smsHaobanRule: 4, // 好办
callRule: 4, // 双向呼叫
gytRule: 1 // 观云台小程序
gytRule: 1, // 观云台小程序
aiRule: 3 // AI营销
},
isMoreAccount: false,
rules: {
......@@ -116,7 +132,8 @@ export default {
smsOpenCardRule: [{ required: true, validator: (rule, val, cb) => validate(val, cb, [1]) }],
gytRule: [{ required: true, validator: (rule, val, cb) => validate(val, cb, [1]) }],
smsHaobanRule: [{ required: true, validator: (rule, val, cb) => validate(val, cb, [4]) }],
callRule: [{ required: true, validator: (rule, val, cb) => validate(val, cb, [3, 4]) }]
callRule: [{ required: true, validator: (rule, val, cb) => validate(val, cb, [3, 4]) }],
aiRule: [{ required: true, validator: (rule, val, cb) => validate(val, cb, [2, 3]) }]
}
};
},
......@@ -134,9 +151,10 @@ export default {
const para = this.form.status ? this.form : {};
// 比较字段值是否有改变
if (this.compareIsEdit(para, this.data)) {
this.loading = true;
if (!this.isMoreAccount) {
await this.$confirm('开启多账户计费模式次日凌晨生效,并且开启后不允许关闭', '确认开启多账户模式?', options1);
await saveAccountRule(para);
await saveAccountRule(para).finally(() => (this.loading = false));
this.$emit('getNewData', !this.isMoreAccount);
try {
await this.$confirm('赶紧去设置不同的计费账户吧,也可点击【计费中心-账户明细】配置不同的计费账户', '保存成功', options2);
......@@ -146,7 +164,7 @@ export default {
return false;
}
} else {
await saveAccountRule(para);
await saveAccountRule(para).finally(() => (this.loading = false));
this.$emit('getNewData', this.isMoreAccount);
this.$emit('update:visible', false);
return this.$message.success('保存成功');
......
......@@ -31,7 +31,7 @@
<p class="fz12 gray line-height2">1、我们提供在线充值服务(目前仅支持微信)</p>
<p class="fz12 gray line-height2">2、请尽量保障账户余额大于您日常使用的额度,避免因余额不足导致业务中断</p>
<p class="fz12 gray line-height2">3、若未能及时充值或其他问题,请联系客户经理或客服人员</p>
<p class="fz12 gray line-height2">4、各项服务单价:国内短信验证码0.050元/条,国际短信验证码0.500元/条,双向呼叫0.420元/分钟</p>
<p class="fz12 gray line-height2">4、各项服务单价:国内短信验证码0.050元/条,国际短信验证码0.500元/条,双向呼叫0.420元/分钟,AI电话0.020元/分钟</p>
<!-- <p class="fz12 gray line-height2">5、通话录音存储收费标准:「三个月{{ allUnitFee.storageThreeFee }}元/分钟」「六个月{{ allUnitFee.storageSixFee }}元/分钟」「十二个月{{ allUnitFee.storageTwelveFee }}元/分钟」,不满一分钟按一分钟收费</p> -->
</div>
</article>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
@font-face {
font-family: "iconfont"; /* Project id 688955 */
src: url('iconfont.woff2?t=1637225676006') format('woff2'),
url('iconfont.woff?t=1637225676006') format('woff'),
url('iconfont.ttf?t=1637225676006') format('truetype');
src: url('iconfont.woff2?t=1647333727991') format('woff2'),
url('iconfont.woff?t=1647333727991') format('woff'),
url('iconfont.ttf?t=1647333727991') format('truetype');
}
.iconfont {
......@@ -13,20 +13,188 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-a-1_heimingdanguanli:before {
content: "\e68d";
.icon-shuangxianghujiao:before {
content: "\ec79";
}
.icon-weixinquguan:before {
content: "\e68c";
.icon-AIdianhua:before {
content: "\ec78";
}
.icon-yingxiaohuodongbiaoqian:before {
content: "\ec75";
}
.icon-jinzitakehu:before {
content: "\ec68";
}
.icon-reload-outlined:before {
content: "\e6aa";
}
.icon-kehufenzu:before {
content: "\ec67";
}
.icon-biaoqian:before {
content: "\e70a";
}
.icon-jifen1:before {
.icon-qudaobiaoqian:before {
content: "\ec62";
}
.icon-changyongbiaoqian:before {
content: "\ec61";
}
.icon-weimengbiaoqian:before {
content: "\ec60";
}
.icon-qitabiaoqian:before {
content: "\ec5f";
}
.icon-daogoubiaoqian:before {
content: "\ec5e";
}
.icon-PlusOutlined:before {
content: "\e6a9";
}
.icon-yonghuguiji:before {
content: "\ec5d";
}
.icon-yingxiaohuodong:before {
content: "\ec5c";
}
.icon-xiaofeihuodong:before {
content: "\ec5b";
}
.icon-jibenxinxi:before {
content: "\ec5a";
}
.icon-peizhiweikong:before {
content: "\ec56";
}
.icon-arrow-right1:before {
content: "\e808";
}
.icon-yuanyin:before {
content: "\e6a7";
}
.icon-jifenguanli:before {
content: "\e6a8";
}
.icon-jiaoseliebiao:before {
content: "\e6a1";
}
.icon-yonghuliebiao1:before {
content: "\e6a0";
}
.icon-tingyezhengdun:before {
content: "\e69f";
}
.icon-yishangxian:before {
content: "\e689";
}
.icon-yingxiao:before {
content: "\e765";
.icon-weishangxian:before {
content: "\e69d";
}
.icon-daishangxian:before {
content: "\e69e";
}
.icon-huodongliebiao:before {
content: "\e698";
}
.icon-huodongtongji:before {
content: "\e699";
}
.icon-yongjinguanli:before {
content: "\e69c";
}
.icon-error_403:before {
content: "\ebd0";
}
.icon-no-access:before {
content: "\ebc9";
}
.icon-jifenjiabei:before {
content: "\e696";
}
.icon-jifenduihuan:before {
content: "\e697";
}
.icon-xiangqing1:before {
content: "\e695";
}
.icon-qiwei:before {
content: "\e694";
}
.icon-waibu:before {
content: "\e673";
}
.icon-search:before {
content: "\e672";
}
.icon-renwuwancheng:before {
content: "\ec13";
}
.icon-QuestionCircleOutlined:before {
content: "\e693";
}
.icon-tonghuajilu1:before {
content: "\e68f";
}
.icon-yingxiaojilu:before {
content: "\e691";
}
.icon-a-weimeng2:before {
content: "\eba7";
}
.icon-zhangdan:before {
content: "\e74b";
}
.icon-a-1_heimingdanguanli:before {
content: "\e68d";
}
.icon-weixinquguan:before {
content: "\e68c";
}
.icon-shouqi1:before {
......@@ -45,10 +213,6 @@
content: "\e684";
}
.icon-weimeng:before {
content: "\e6e4";
}
.icon-weixin1:before {
content: "\e685";
}
......@@ -113,18 +277,14 @@
content: "\e677";
}
.icon-SwapOutlined:before {
content: "\e672";
}
.icon-BellOutlined:before {
content: "\e673";
}
.icon-chakanxiangqing:before {
content: "\e892";
}
.icon-chakanxiangqing-copy:before {
content: "\eba8";
}
.icon-jiaocheng:before {
content: "\e6f8";
}
......@@ -625,22 +785,6 @@
content: "\e791";
}
.icon-guijijiansuo:before {
content: "\e78c";
}
.icon-xiaofei2:before {
content: "\e78d";
}
.icon-jibenxinxi:before {
content: "\e78e";
}
.icon-yingxiaohuodongguanli:before {
content: "\e78f";
}
.icon-fengefu:before {
content: "\e61f";
}
......@@ -757,10 +901,6 @@
content: "\ea17";
}
.icon-shuangxianghujiao:before {
content: "\e617";
}
.icon-yuyinxiaoxi:before {
content: "\e65d";
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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