Commit df16fe20 authored by 沈良进's avatar 沈良进

save

parent 731d34c4
This diff is collapsed.
......@@ -8,6 +8,7 @@
},
"dependencies": {
"@tinymce/tinymce-vue": "^3.1.0",
"@vue/composition-api": "^1.7.1",
"axios": "^0.18.0",
"chart.js": "^2.9.3",
"co": "^4.6.0",
......@@ -19,7 +20,7 @@
"jspdf": "^1.4.1",
"less-loader": "^5.0.0",
"moment": "^2.22.2",
"pinyin": "^2.9.0",
"pinyin": "^2.8.3",
"register-service-worker": "^1.0.0",
"sass-loader": "^8.0.2",
"tinymce": "^5.1.6",
......@@ -30,12 +31,12 @@
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.0.1",
"vue2.0-zoom": "^2.1.1",
"vuedraggable": "^2.24.3",
"vuex": "^3.0.1",
"vxe-table": "^2.7.24",
"webpack-require-http": "^0.4.3",
"x-data-spreadsheet": "^1.0.31",
"xe-utils": "^2.3.0",
"pinyin": "^2.8.3"
"xe-utils": "^2.3.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.1",
......@@ -49,7 +50,7 @@
"stylus-loader": "^3.0.2",
"typescript": "^3.8.2",
"vue-cli-plugin-element": "^1.0.0",
"vue-template-compiler": "^2.5.17"
"vue-template-compiler": "^2.6.14"
},
"postcss": {
"plugins": {
......
......@@ -41,6 +41,11 @@
<rankConfig v-if="selectTitle==3"></rankConfig>
<!-- 管理配置 -->
<ManageConfiguration v-if="selectTitle==4"></ManageConfiguration>
<!-- 客户字段 -->
<customerField v-if="selectTitle==5"></customerField>
<!-- 标签 -->
<!-- <customerlabel v-if="selectTitle==6"></customerlabel> -->
</div>
</template>
<script>
......@@ -48,12 +53,16 @@
import distributionRules from "./distributionRules";
import rankConfig from "./rankConfig";
import ManageConfiguration from "./ManageConfiguration";
import customerField from '../../views/customerSet/components/customerField.vue'
// import customerlabel from '../../views/customerSet/components/customerlabel.vue'
export default {
components: {
customerSource,
distributionRules,
rankConfig,
ManageConfiguration
ManageConfiguration,
customerField,
// customerlabel
},
data() {
return {
......@@ -75,6 +84,14 @@
title: '管理配置',
id: 4
},
{
title: '客户字段',
id: 5
},
{
title: '标签',
id: 6
},
]
};
},
......
......@@ -24,6 +24,8 @@ import vueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import pinyin from 'pinyin'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
Vue.prototype.pinyin = pinyin
// 使用Vue.use()方法就会调用工具方法中的install方法
Vue.use(htmlToPdf)
......
import axios from 'axios'
import domainManager from './domainManager'
const getLocalStorage = function () {
var localStorageData = window.localStorage["userInfo"];
if (localStorageData != undefined) {
return JSON.parse(localStorageData);
} else {
return null;
}
}
//CRM接口
export default function(cmd,content, msg, successCall, faildCall) {
console.log('CRM接口', content)
if (msg == null || msg == "") {
msg = {}
}
var apiurl = domainManager().PostUrl + cmd;
var timestamp = (new Date()).valueOf();
var token = "";
var key = "";
if (getLocalStorage() != null) {
token = getLocalStorage().token;
key = getLocalStorage().secretKey;
}
var encodeMsg = encodeURIComponent(JSON.stringify(msg)).toLowerCase();
var md5Str = md5(`cmd=${cmd}&msg=${encodeMsg}&timestamp=${timestamp}&token=${token}&key=${key}`);
var postData = {
"msg": msg,
"timestamp": timestamp,
"token": token,
"sign": md5Str
}
if (localStorage.g && localStorage.g != 'undefined') {
postData.groupId = 2;
}
axios.post(apiurl, postData, {
headers: {
'Content-Type': 'application/json',
'Referer-Viitto': content.$route.path
}
})
.then(res => {
if (res.data.resultCode == 10000 || res.data.resultCode == 10001) {
content.$router.push({
path: '/login'
})
} else if (res.data.resultCode == 10005) {
content.$router.go(-1)
} else {
successCall(res)
}
}, faildCall)
}
\ No newline at end of file
const isOnline = function() {
return process.env.NODE_ENV !== 'development';
}
export default function() {
//CRM API
let domainUrl = "";
// domainUrl = "http://192.168.10.46:8500";
domainUrl = "http://192.168.10.128:8098";
// domainUrl = "http://crm.oytour.com"
//domainUrl = "http://localhost:5003";
let locationName = window.location.hostname;
//旅游ERPApi
let domainPostUrl = ""
domainPostUrl = "http://192.168.10.9:8083";
//domainPostUrl = "http://192.168.10.46";
if (isOnline()) {
if (window.location.host.indexOf('fcrmyx.oytour.com') != -1) {
domainUrl = "http://crm.oytour.com"
domainPostUrl = "http://reborn.oytour.com"
} else {
domainUrl = "http://testcrm.oytour.com"
domainPostUrl = "http://testapi.oytour.com"
}
}
var obj = {
//主地址
DomainUrl: domainUrl,
DownLoadContractUrl: domainPostUrl,
//阿里服务器地址
AliUrl: "https://reborndev.oss-cn-hangzhou.aliyuncs.com",
//CRMApi地址
PostUrl: domainUrl,
//旅游ERPApi地址
ERPApiUrl: domainPostUrl + "/api/common/post",
javaUrl: locationName.indexOf('testb2b') == -1 ? "http://efficient.oytour.com" : locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://47.96.12.235:9001" : "http://192.168.10.215:9000",
ViittoFileUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://staticfile.oytour.com" : 'http://192.168.10.214:8130',
UploadUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://uploadfile.oytour.com" : "http://192.168.10.214:8120",
erpRoutingUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://yx.oytour.com/#/" : "http://localhost:8081/#/"// "http://www.test.com:8081/#/",
};
return obj;
}
\ No newline at end of file
import md5 from 'js-md5'
import domainManager from './domainManager'
export default {
data: {
loginUser: {},
apiurl: ''
},
domainManager,
install(Vue, options) {
Vue.prototype.isOnline = function() {
return process.env.NODE_ENV !== 'development';
},
//域名管理对象
Vue.prototype.domainManager = function() {
//CRM API
let domainUrl = "";
// domainUrl = "http://192.168.10.46:8500";
domainUrl = "http://192.168.10.9:8098";
// domainUrl = "http://crm.oytour.com"
//domainUrl = "http://localhost:5003";
let locationName = window.location.hostname;
//旅游ERPApi
let domainPostUrl = ""
domainPostUrl = "http://192.168.10.9:8083";
//domainPostUrl = "http://192.168.10.46";
if (this.isOnline()) {
if (window.location.host.indexOf('fcrmyx.oytour.com') != -1) {
domainUrl = "http://crm.oytour.com"
domainPostUrl = "http://reborn.oytour.com"
} else {
domainUrl = "http://testcrm.oytour.com"
domainPostUrl = "http://testapi.oytour.com"
}
}
var obj = {
//主地址
DomainUrl: domainUrl,
DownLoadContractUrl: domainPostUrl,
//阿里服务器地址
AliUrl: "https://reborndev.oss-cn-hangzhou.aliyuncs.com",
//CRMApi地址
PostUrl: domainUrl,
//旅游ERPApi地址
ERPApiUrl: domainPostUrl + "/api/common/post",
javaUrl: locationName.indexOf('testb2b') == -1 ? "http://efficient.oytour.com" : locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://47.96.12.235:9001" : "http://192.168.10.215:9000",
ViittoFileUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://staticfile.oytour.com" : 'http://192.168.10.214:8130',
UploadUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://uploadfile.oytour.com" : "http://192.168.10.214:8120",
erpRoutingUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('testb2b.oytour.com') !== -1 ? "http://yx.oytour.com/#/" : "http://localhost:8081/#/"// "http://www.test.com:8081/#/",
};
return obj;
},
Vue.prototype.domainManager = domainManager,
//消息成功提示
Vue.prototype.Success = function(msg) {
......@@ -171,6 +135,7 @@ export default {
if (msg == null || msg == "") {
msg = {}
}
console.log('CRM接口', this)
var apiurl = this.domainManager().PostUrl + cmd;
var timestamp = (new Date()).valueOf();
var token = "";
......
<template>
<div class="q-pa-md customerLib">
<div class="q-py-md">
<div class="flex justify-between q-mb-md">
<div>
<q-btn color="primary" unelevated label="+新增客户库" class="q-mr-md" @click="jumpPage('/editor/editCustomerLib')"/>
<n-popover trigger="hover" :width="620" placement="right">
<template #trigger>
<span>了解多客户库的好处</span>
</template>
<div class="q-pa-md">
<div class="tip-title">
有效实现业务独立,提高管理效率,降低客户资源浪费
</div>
<div class="tip-content">
<div class="tip-header">
多公海
</div>
<div class="tip-text">
每个客户库都有自己独立的公海,对本客户库外的数据隔离,有效提高线索流转的效率。
</div>
<div class="tip-list-text">
<div style="white-space:nowrap">
例如:
</div>
<div>
场景一:设置“北京客户库”、“南京客户库” 保持业务的独立性;<br/>
场景二:设置“市场客户库”、“电销客户库”、“面销客户库”,区分客户的流转阶段/属性;
</div>
</div>
</div>
<div class="tip-content">
<div class="tip-header">
多规则
</div>
<div class="tip-text">
每个客户库都有自己独立的规则,不同部门之间可能存在不同的规则:
</div>
<div class="tip-list-text">
<div style="white-space:nowrap">
例如:
</div>
<div>
回收客户的规则:不同的部门/员工,可设置不同的客户回收规则,合理利用资源;<br/>
员工的客户上限:不同的部门/员工,设置不同的客户上限,降低资源浪费的可能;<br/>
录入客户的标准:有的部门支持创建重复客户,有的部门则不支持;
</div>
</div>
</div>
</div>
</n-popover>
</div>
<q-btn text-color="accent" outline unelevated label="设置查重规则" @click="showRuleDig=true" />
</div>
<q-table class="sticky-right-column-table" :rows="list" flat :columns="columns" hide-bottom row-key="Id">
<template v-slot:body-cell-range="props">
<q-td :props="props">
<div v-for="(item,index) in props.row.DeptList" :key="index">{{item.DeptName}}</div>
</q-td>
</template>
<template v-slot:body-cell-seasRule="props">
<q-td :props="props">
<div>查看规则</div>
</q-td>
</template>
<template v-slot:body-cell-libRule="props">
<q-td :props="props">
<div>查看规则</div>
</q-td>
</template>
<template v-slot:body-cell-IsAllowRepeat="props">
<q-td :props="props">
<div v-if="props.row.IsAllowRepeat===1"></div>
<div v-if="props.row.IsAllowRepeat===2"></div>
</q-td>
</template>
<template v-slot:body-cell-operate="props">
<q-td :props="props">
<q-btn color="accent" flat label="编辑" />
<q-btn color="negative" flat label="删除" />
</q-td>
</template>
</q-table>
</div>
<!-- 查重规则弹窗 -->
<q-dialog v-model="showRuleDig" full-height maximized position="right" transition-show="slide-left">
<q-card>
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">查重规则设置 </div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section>
<div style="width:750px">
<q-item tag="label">
<q-item-section avatar top>
<q-radio v-model="LookRepeat" :val="1" color="primary" />
</q-item-section>
<q-item-section>
<div class="ruleset-title" style="color:#858598"><span style="color:#606266">全局查重</span> (一个客户在<span
style="color:#f00">整个企业</span>内,只允许被一个员工跟进)</div>
<div class="ruleset-box">
<div class="ruleset-txt">
一个客户,在整个企业内查重(整个企业不允许创建重复客户)
</div>
<div class="ruleset-img">
<img src="@/assets/images/customer/customerSet/rule1.jpg" />
</div>
</div>
</q-item-section>
</q-item>
<q-item tag="label">
<q-item-section avatar top>
<q-radio v-model="LookRepeat" :val="2" color="primary" />
</q-item-section>
<q-item-section>
<div class="ruleset-title" style="color:#858598"><span style="color:#606266">客户库查重</span> (一个客户在<span
style="color:#f00">单个客户库</span>内,只允许被一个员工跟进)</div>
<div class="ruleset-box">
<div class="ruleset-txt">
一个客户,在整个企业内查重(整个企业不允许创建重复客户)
</div>
<div class="ruleset-img">
<img src="@/assets/images/customer/customerSet/rule2.jpg" />
</div>
</div>
</q-item-section>
</q-item>
</div>
</q-card-section>
<q-card-actions align="left" class="bg-white text-teal">
<q-btn color="primary" unelevated label="确定" class="q-ml-lg" @click="setLookRepeatRule" />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>
<script lang="ts">
import {
defineComponent,
reactive,
toRefs,
onMounted
} from 'vue'
// import { Dialog } from 'quasar'
import message from '@/utils/message'
import customerSetService from '@/api/customerSet';
import router from '@/router/index'
export default defineComponent({
setup() {
const msg = reactive({
Name: ""
})
const data = reactive({
list: [],
columns: [{
name: 'Name',
label: '名称',
field: 'Name',
align: 'left',
}, {
name: 'range',
label: '适用范围',
field: 'range',
align: 'left',
}, {
name: 'seasRule',
label: '公海回收规则',
field: 'seasRule',
align: 'left',
}, {
name: 'libRule',
label: '私库限额规则',
field: 'libRule',
align: 'left',
}, {
name: 'IsAllowRepeat',
label: '是否允许重复客户',
field: 'IsAllowRepeat',
align: 'left',
}, {
name: 'UpdateTime',
label: '创建时间',
field: 'UpdateTime',
align: 'left',
}, {
name: 'operate',
label: '操作',
field: 'operate',
align: 'left',
style: 'width: 200px'
}],
showRuleDig: false
})
const getList = () => {
customerSetService.getCustomerLibraryList(msg).then(res => {
data.list = res.data.Data
})
}
const LookRepeatMsg = reactive({ //查重规则 1客户库查重 2全局查重
LookRepeat: 1
})
const getLookRepeatRule = () => {
customerSetService.getCustomerLibraryLookRepeat({}).then(res => {
LookRepeatMsg.LookRepeat = res.data.Data
})
}
const setLookRepeatRule = () => {
customerSetService.setCustomerLibraryLookRepeat(LookRepeatMsg).then(res => {
message.successMsg(res.data.Message)
data.showRuleDig = false
})
}
const jumpPage = (url: string, Id = 0) => {
router.push({
path: url,
query: {
Id
}
})
}
onMounted(() => {
getList()
getLookRepeatRule()
})
return {
...toRefs(data),
...toRefs(LookRepeatMsg),
setLookRepeatRule,
jumpPage
}
}
})
</script>
<style lang="scss" scoped>
.ruleset-title {
line-height: 40px;
}
.ruleset-box {
width: 606px;
align-items: center;
color: #333;
padding: 30px 0 42px 0;
margin: 10px 0;
border-radius: 8px;
border: 1px solid #ccc;
.ruleset-txt {
text-align: center;
}
.ruleset-img {
margin-top: 24px;
display: flex;
justify-content: center;
}
}
.tip-title {
font-size: 18px;
margin-bottom: 15px;
font-weight: bolder;
}
.tip-content {
background-color: #f4f4f6;
padding: 30px;
border-radius: 10px;
margin-bottom: 15px;
}
.tip-header {
color: var(--q-accent);
font-size: 18px;
font-weight: bolder;
margin-bottom: 15px;
}
.tip-text {
font-size: 14px;
margin-bottom: 5px;
}
.tip-list-text {
color: var(--q-accent);
font-size: 12px;
display: flex;
align-items: baseline;
justify-content: flex-start;
font-weight: 500;
line-height:22px;
}
</style>
This diff is collapsed.
This diff is collapsed.
<template>
<div class="q-pa-md businessModel">
<div class="full-width business-header">
请选择您的业务模式:
</div>
<div class="box-businessModel" :class="{ 'checked-border': msg.type == 1 }" @click="chooseChange(1)">
<i class="iconfont icon-customer" style="font-size:38px"></i>
<div>个人客户</div>
<div class="right" v-if="msg.type == 1">
<q-icon name="check" class="check-icon" />
</div>
</div>
<div class="box-businessModel" :class="{ 'checked-border': msg.type == 2 }" @click="chooseChange(2)">
<div >
<i class="iconfont icon-customer" style="font-size:38px"></i>
<span class="q-mx-md" style="font-size:28px">+</span>
<i class="iconfont icon-qiye" style="font-size:38px"></i>
</div>
<div>个人客户 + 企业客户</div>
<div class="right" v-if="msg.type == 2">
<q-icon name="check" class="check-icon" />
</div>
</div>
</div>
</template>
<script lang="ts">
import {
defineComponent,
reactive,
} from 'vue'
export default defineComponent({
setup() {
const msg = reactive({
type: 1
})
const chooseChange = (n) => {
msg.type = n;
console.log(msg)
}
return {
msg,
chooseChange
}
}
})
</script>
<style lang="scss" scoped>
.businessModel {
overflow: hidden;
display: flex;
flex-wrap: wrap;
margin: 0 auto;
width: 700px;
justify-content: space-between;
margin-top: 191px;
.business-header {
font-size: 16px;
font-weight: 700;
margin-bottom: 15px;
}
.box-businessModel {
cursor: pointer;
width: 311px;
height: 198px;
background: #f9f9f9;
border-radius: 5px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
position: relative;
.right {
position: absolute;
right: -20px;
bottom: -20px;
display: block;
width: 0;
height: 0;
transform: rotate(45deg);
border: 20px solid transparent;
border-left: 20px solid #3470ff;
.check-icon {
position: absolute;
top: -8px;
left: -19px;
transform: rotate(-45deg);
font-size: 14px;
font-weight: 700;
color: #fff;
}
}
}
}
.checked-border {
background-color: #edf2fd !important;
border: 2px solid #3470ff !important;
color: #3470ff;
}
</style>
This diff is collapsed.
This diff is collapsed.
<template>
<div class="customerPhase page-body">
<div style="display: flex;align-items: center;justify-content: space-between;">
<div style="display: flex;align-items: center;">
<q-btn
v-if="state.data.length < 20"
color="accent"
style="margin-bottom: 10px;"
class="q-mr-md"
label="创建阶段流程"
@click="jumpPage('/editor/createStageRange')"
size="sm"
></q-btn>
<span
style="margin-left: 20px;color: rgb(133, 133, 152);"
>已添加:{{ state.data.length }}/20</span>
</div>
<q-btn
color="white"
text-color="black"
style="margin-bottom: 10px;"
class="q-mr-md"
label="阶段管理"
size="sm"
@click="jumpPage('/editor/manageStageRange')"
></q-btn>
</div>
<table class="payTable">
<thead>
<tr>
<th>名称</th>
<th>适用范围</th>
<th>启用</th>
<th>阶段</th>
<th width="13%">操作信息</th>
<th width="12%">操作</th>
</tr>
</thead>
<tr v-if="state.data.length == 0">
<td :colspan="6" align="center">暂无数据</td>
</tr>
<tr v-for="(item,index) in state.data" :key="index">
<td>
<span>{{ item.FlowName }}</span>
</td>
<td>
<div v-if="item.DeptEmpList && item.DeptEmpList.length > 0">
<span v-for="(x,y) in item.DeptEmpList" :key="y">
<q-chip
color="blue-1"
text-color="blue"
icon="folder"
size="sm"
v-if="x.Type == 1"
>{{ x.Name }}</q-chip>
<q-chip
color="green-1"
text-color="green"
icon="person"
size="sm"
v-if="x.Type == 2"
>{{ x.Name }}</q-chip>
</span>
</div>
<span v-else>未适配其他规则的阶段</span>
</td>
<td>
<q-toggle
v-if="item.IsDefault == 1"
v-model="item.Enable"
:true-value="1"
:false-value="2"
icon="lock"
disable
/>
<q-toggle
v-else
v-model="item.Enable"
:true-value="1"
:false-value="2"
@update:model-value="setFiledState(item.Id, 1)"
/>
</td>
<td>
<span
v-for="(x,y) in item.StageList"
:key="y"
>{{ x }}{{ item.StageList.length != y + 1 ? '->' : '' }}</span>
</td>
<td>
<div>{{ item.UpdateByName }}</div>
<div>{{ item.UpdateTime }}</div>
</td>
<td>
<q-btn
v-if="item.IsDefault != 1"
flat
size="xs"
icon="edit"
style="font-weight:400;color: #3FC4FF"
class="q-mr-xs"
label="编辑"
@click="goedit(item.Id)"
/>
<q-btn
v-if="item.IsDefault != 1"
flat
size="xs"
icon="delete"
color="negative"
class="q-mr-xs"
label="删除"
@click="godelete(item.Id)"
/>
</td>
</tr>
</table>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive } from 'vue'
import customerSetService from '@/api/customerSet'
import { useQuasar } from 'quasar'
import router from '@/router/index'
export default defineComponent({
setup() {
const $q = useQuasar()
const state = reactive({
data: [],
})
const getList = () => {
customerSetService.getCustomerStageFlowList({ Enable: 0 }).then((res) => {
if (res.data.Code == 1) {
state.data = res.data.Data
} else {//如果移动失败 重新获取列表
}
})
}
const godelete = (Id: number) => {
$q.dialog({
title: "提示信息",
message: '是否删除该阶段流程',
cancel: {
label: "取消",
flat: true
},
ok: {
label: "确认",
flat: true,
}
}).onOk(() => {
setFiledState(Id, 2)
});
}
const setFiledState = (Id: number, Type: number) => {
console.log(Id, Type)
let msg = {
Type: Type,
FlowId: Id,
}
customerSetService.setCustomerStageFlowState(msg).then((res) => {
if (res.data.Code == 1) {
$q.notify({
icon: 'iconfont icon-chenggong',
color: 'accent',
timeout: 2000,
message: res.data.Message,
position: 'top'
})
getList()
} else {//如果移动失败 重新获取列表
}
})
}
const jumpPage = (url: string) => {
router.push({
path: url,
query: {
}
})
}
const goedit = (Id: number) => {
router.push({
path: '/editor/createStageRange',
query: {
FlowId:Id
}
})
}
onMounted(() => {
getList()
})
return {
getList,
state,
setFiledState,
godelete,
jumpPage,
goedit
}
}
})
</script>
<style>
.customerPhase .payTable {
width: 100%;
border-collapse: collapse;
}
.customerPhase .payTable tr th {
background: #fff;
height: 40px;
font-size: 12px;
font-weight: bold;
color: #2d2d2d;
background: #f5f5fa;
}
.customerPhase .payTable tr {
background: #fff;
text-align: center;
height: 40px;
}
.customerPhase .payTable tr td {
font-size: 13px;
text-align: center;
color: #2d2d2d;
padding: 10px 0;
font-weight: bold;
border-bottom: 1px solid #e5e5e5;
}
</style>
\ No newline at end of file
This diff is collapsed.
<template>
<div class="customerPhase page-body">
<div style="display: flex;align-items: center;justify-content: space-between;">
<div style="display: flex;align-items: center;">
<q-btn
color="accent"
style="margin-bottom: 10px;"
class="q-mr-md"
label="新增分配规则 "
@click="Addallocation('/editor/editlaqun')"
size="sm"
></q-btn>
<span style="margin-left: 10px;color: #3470ff;cursor: pointer;" @click="icon = true">查看拉群分配流程</span>
</div>
<div style="display: flex;align-items: center;">
<span
style="font-size: 14px; color: #858598;margin-right: 10px;"
>若客户满足多条规则,会优先按照编号顺序执行规则</span>
<q-btn
color="accent"
style="margin-bottom: 10px;"
class="q-mr-md"
label="新增分配规则 "
@click="Addallocation('/editor/editlaqun')"
size="sm"
></q-btn>
</div>
</div>
<q-dialog v-model="icon">
<q-card style="max-width: 1300px;">
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">拉群分配客户流程 <span style="color: #858598;font-size: 14px;">(销售分配更公平,客服拉群更便捷)</span></div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<div style="display: flex;align-items: flex-start;justify-content: space-around;padding: 0 40px">
<div class="text-wrapper" v-for="(x,y) in textList " :key='y'>{{x.Name}}</div>
</div>
<div class="flow-line">
<div class="flow-line-slide1" style="width: 110px;"></div>
<div class="flow-line-center" style="width: 220px;"></div>
<div class="flow-line-center" style="width: 220px;"></div>
<div class="flow-line-center" style="width: 220px;"></div>
<div class="flow-line-center" style="width: 220px;"></div>
<div class="flow-line-slide2" style="width: 110px;">
<div class="right-arrow"></div>
</div>
</div>
<div class="flow-content-wrapper" style="padding: 0 40px">
<div class="flow-content">
<div class="arrow"></div>
<div>
<li class='setting-text'> 选择可拉群的SDR </li>
<li class='setting-text'> 选择适用的客户 </li>
<li class='setting-text'> 选择可分配的销售 </li>
<li class='setting-text'> 顺序分配或随机分配 </li>
</div>
</div>
<div class="flow-content">
<div class="arrow"></div>
<img class="flow-image" src="../../../../assets/images/customer/flow1.a3a1048d.png" alt="">
</div>
<div class="flow-content">
<div class="arrow"></div>
<img class="flow-image" src="../../../../assets/images/customer/flow2.61729a6c.png" alt="">
</div>
<div class="flow-content">
<div class="arrow"></div>
<img class="flow-image" src="../../../../assets/images/customer/flow3.85769e1f.png" alt="">
</div>
<div class="flow-content">
<div class="arrow"></div>
<div class="setting-text">自定义销售身份</div>
<div class="setting-text">负责人 or 协作人</div>
</div>
</div>
</q-card>
</q-dialog>
</div>
</template>
<script lang="ts">
import {
defineComponent,
ref,
// onMounted
} from 'vue'
// import { useQuasar } from 'quasar'
import router from '@/router/index'
export default defineComponent({
setup() {
const textList = ref < Array < {Name:string} >> ([
{Name:' 设置分配规则 '},
{Name:' SDR(售前客服) 在客户详情点击“更多” '},
{Name:' 点击“拉群分配客户” '},
{Name:' 建群成功,系统自动分配销售 '},
{Name:' 根据设置自动指定负责人 '},
])
const Addallocation = (url: string) => {//新增分配规则
console.log('新增匹配规则')
router.push({
path: url,
query: {
}
})
}
// onMounted(() => {
// })
return {
Addallocation,
icon:ref(false),
textList
}
}
})
</script>
<style lang="scss">
.text-wrapper{
width: 200px;
font-size: 14px;
color: #333;
font-weight: 500;
line-height: 20px;
text-align: center;
margin: 20px 6px 0;
}
.flow-line{
margin-top: 20px;
display: flex;
justify-content: center;
.flow-line-slide1{
height: 30px;
border-top: 1px dashed #3470ff;
border-right: 1px dashed #3470ff;
}
.flow-line-center{
border-top: 1px dashed #3470ff;
border-right: 1px dashed #3470ff;
height: 30px;
}
.flow-line-slide2{
position: relative;
height: 30px;
border-top: 1px dashed #3470ff;
.right-arrow{
position: absolute;
top: -7px;
right: -9px;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
border-left: 9px solid #3470ff;
}
}
}
.flow-content-wrapper{
height: 430px;
display: flex;
justify-content: space-around;
.flow-content{
position: relative;
width: 220px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.arrow{
position: absolute;
top: 0;
margin: 0 auto;
height: 0;
width: 0;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 9px solid #3470ff;
}
.setting-text{
color: #333;
border-radius: 20px;
height: 40px;
line-height: 40px;
background: #f9f9f9;
padding: 0 10px;
margin: 10px 0;
text-align: center;
list-style: none outside none;
}
.flow-image{
width: 190px;
height: 400px;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="q-pa-md">
<q-page padding class="page" :style-fn="myTweak(640)">
<q-tabs
v-model="tab"
dense
class="text-grey"
align="left"
active-color="primary"
indicator-color="primary"
narrow-indicator
>
<q-tab name="model" label="业务模式" />
<q-tab name="field" label="客户字段" />
<q-tab name="label" label="标签" />
<q-tab name="clue" label="线索分配规则" />
<q-tab name="laqun" label="拉群分配客人" />
<q-tab name="phase" label="客户阶段" />
<q-tab name="operation" label="客户操作" />
<q-tab name="lib" label="客户库-公海" />
</q-tabs>
<div class="container fit">
<businessModel v-if="tab == 'model'"></businessModel>
<customer-Field v-if="tab == 'field'"></customer-Field>
<clue-rule v-if="tab == 'clue'"></clue-rule>
<laqundistribution v-if="tab == 'laqun'"></laqundistribution>
<customer-phase v-if="tab == 'phase'"></customer-phase>
<customerlabel v-if="tab == 'label'"></customerlabel>
<CustomerOperation v-if="tab == 'operation'"></CustomerOperation>
<CustomerLibrary v-if="tab == 'lib'"></CustomerLibrary>
</div>
</q-page>
</div>
</template>
<script lang="ts">
import businessModel from './components/businessModel.vue'
import customerField from './components/customerField.vue'
import clueRule from './components/clueRule.vue'
import laqundistribution from './components/laqundistribution.vue'//拉群分配客人
import customerPhase from './components/customerPhase.vue'
import customerlabel from './components/customerlabel.vue'
import CustomerOperation from "./components/CustomerOperation.vue"
import CustomerLibrary from "./components/CustomerLibrary.vue"
import router from '@/router/index'
import { useMeta } from 'quasar'
import {
defineComponent,
ref
} from 'vue'
export default defineComponent({
components: {
businessModel,
customerField,
clueRule,
customerPhase,
customerlabel,
CustomerOperation,
CustomerLibrary,
laqundistribution
},
setup() {
useMeta({title: '客户设置'})
let tab = ref<string>('field')
if (router.currentRoute.value.query && router.currentRoute.value.query.type) {
tab.value = router.currentRoute.value.query.type as string
}
let myTweak= (offset)=> {
return { minHeight: offset ? `calc(100vh - ${offset}px)` : '100vh' }
}
return {
tab,
myTweak
}
}
})
</script>
<style lang="scss" scoped>
.page{
background: #FFF;
box-sizing: border-box;
border-radius: 10px;
}
.container{
box-sizing: border-box;
overflow: scroll;
}
</style>
\ No newline at end of file
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