<template>
<section>
<!-- title -->
<el-card>
<h2>全部客户列表</h2>
<el-row>
<!-- 搜索 -->
<el-col :span="5">
<el-input v-model.trim="queryInfo.csr_name" placeholder="请输入客户名称搜索" clearable @clear="search()" @keyup.enter.native="search()">
<el-button slot="append" icon="el-icon-search" @click="search()" />
</el-input>
</el-col>
<el-col :span="4" :offset="15">
<el-button type="primary" size="small" @click="exportClient">导出客户</el-button>
<el-button type="primary" size="small" @click="bathImportAction('action:show')">批量导入</el-button>
<el-button type="primary" size="small" plain @click="addCustomer('add')">添加客户</el-button>
</el-col>
</el-row>
</el-card>
<!-- table -->
<el-card>
<el-table v-loading="loading" :data="tableData.row">
<el-table-column prop="id" label="id" width="80" />
<el-table-column prop="csr_name" label="客户姓名" />
<el-table-column prop="csr_status_name" label="客户状态" />
<el-table-column prop="source_type_name" label="来源" />
<el-table-column prop="csr_mobile" label="电话" />
<el-table-column prop="created_at" label="客户添加时间" />
<el-table-column label="操作" fixed="right" width="150">
<template slot-scope="{row}">
<router-link :to="`clientDetail/${row.id}`">
<el-button type="primary" size="small" plain style="margin-right:5px">查看</el-button>
</router-link>
<el-button type="success" size="small" plain @click="allotCustomer(row)">分配</el-button>
<!-- <el-button type="warning" size="small" plain @click="changeStatus(row)">修改状态</el-button> -->
</template>
</el-table-column>
</el-table>
<!-- page -->
<el-row type="flex" justify="center">
<el-pagination
layout="total, sizes, prev, pager, next, jumper"
background
:total="pagination.total"
:current-page.sync="pagination.current"
:page-size.sync="pagination.limit"
/>
</el-row>
</el-card>
<el-dialog title="批量导入客户" width="500px" :visible.sync="bathImportDialog.visible" @close="bathImportDialogClose('bathImportUpload')">
<el-form label-width="100px">
<el-form-item label="请选择excel">
<el-upload
ref="bathImportUpload"
action="javascript:;"
:auto-upload="false"
:limit="1"
:http-request="bathImportActionRequest"
:on-exceed="bathImportExceed"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
>
<el-button slot="trigger" size="small" type="primary">点击上传</el-button>
<section style="text-align: right;">
<a href="https://img.cdn.heshecasa.com/hhserp/system/customer/demo.xlsx">
<el-button type="primary" size="small" plain>下载模板</el-button>
</a>
</section>
<div slot="tip" class="el-upload__tip">
<!-- <p style="font-size: 14px">{{ bathImportName }}</p> -->
<p style="color: #9c9c9c;">只能上传xlsx文件</p>
</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="bathImportAction('action:hide')">取消</el-button>
<el-button type="primary" @click="bathImportAction('action:submit')">提交</el-button>
</div>
</el-dialog>
<!-- addCustomerDialog -->
<el-dialog
:title="dialog.title"
:visible.sync="dialog.addDialogVisible"
width="35%"
:close-on-click-modal="false"
@close="dialogOnClose('formData')"
>
<el-row>
<el-form
ref="formData"
:model="formData"
:rules="rules"
label-width="100px"
>
<el-col :span="20">
<el-form-item label="客户姓名" prop="csr_name">
<el-input v-model="formData.csr_name" placeholder="请输入客户姓名" clearable>
</el-input>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="性别" prop="csr_sex">
<el-radio-group v-model="formData.csr_sex" size="medium">
<el-radio
v-for="(item, index) in formOptions.genderOptions"
:key="index"
:label="item.value"
:disabled="item.disabled"
>{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="手机号" prop="csr_mobile">
<el-input v-model="formData.csr_mobile" placeholder="请输入手机号" clearable>
</el-input>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="微信号" prop="csr_wechat">
<el-input v-model="formData.csr_wechat" placeholder="请输入微信号" clearable>
</el-input>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="所在地区" prop="city_id">
<el-row :gutter="10" type="flex" justify="space-between">
<el-col>
<el-select
v-model="address.country"
placeholder="请选择国家"
style="width: 100%"
@change="countryChange"
>
<el-option
v-for="item in countryOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-col>
<el-col>
<el-select
v-model="address.prov"
placeholder="请选择省份"
style="width: 100%"
@change="provinceChange"
>
<el-option
v-for="item in provOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-col>
<el-col>
<el-select
v-model="address.city"
placeholder="请选择城市/地区"
style="width: 100%"
>
<el-option
v-for="item in cityOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="客户来源" prop="source_type">
<el-select v-model="formData.source_type" placeholder="请选择客户来源" clearable>
<el-option
v-for="(item, index) in formOptions.sourceOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="邮箱地址" prop="csr_email">
<el-input v-model="formData.csr_email" placeholder="请输入邮箱地址" clearable>
</el-input>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="公司名称" prop="csr_comp_name">
<el-input v-model="formData.csr_comp_name" placeholder="请输入公司名称" clearable>
</el-input>
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item label="备注" prop="csr_remark">
<el-input
v-model="formData.csr_remark"
type="textarea"
placeholder="请输入备注"
:autosize="{minRows: 4, maxRows: 4}"
></el-input>
</el-form-item>
</el-col>
</el-form>
</el-row>
<div slot="footer">
<el-button @click="action('action:hide')">取 消</el-button>
<el-button type="primary" @click="action('action:submit')">确 定</el-button>
</div>
</el-dialog>
<!-- 分配弹框 -->
<el-dialog
title="分配客户"
:visible.sync="allotDialog.allotDialogVisible"
width="50%"
@close="dialogOnClose('allotForm')"
>
<el-form ref="allotForm" :model="allotForm" label-width="80px">
<el-form-item label="选择销售">
<el-row :gutter="10">
<el-col :span="5">
<el-select v-model="allotForm.seller_id" placeholder="请选择销售" clearable>
<el-option
v-for="(item, index) in allotDialog.sellerOption"
:key="index"
:label="item.label"
:value="item.value"
>{{ item.label }}</el-option>
</el-select>
</el-col>
<el-col :span="2"><el-button type="primary" @click="getAllotCustomer">分配</el-button></el-col>
</el-row>
</el-form-item>
</el-form>
<el-table :data="allotDialog.sellerList">
<el-table-column prop="seller_name" label="客户跟进销售名称"></el-table-column>
<el-table-column prop="follow_status_name" label="状态"></el-table-column>
<el-table-column prop="add_time" label="创建时间"></el-table-column>
<el-table-column label="操作">
<template slot-scope="{row}">
<el-popconfirm
title="确定删除当前客户指定跟进销售吗?"
confirm-button-text="确定"
cancel-button-text="取消"
@onConfirm="deleteAllot(row.id)"
>
<el-button v-if="row.del_btn ===1" slot="reference" type="danger" size="mini" plain>删除</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div slot="footer">
<el-button @click="allotDialog.allotDialogVisible = false">关 闭</el-button>
</div>
</el-dialog>
<el-dialog
title="修改客户状态"
:visible.sync="clientDialog.changeStatusDialogVisible"
width="30%"
>
<el-form ref="clientForm" :model="clientDialog.form" label-width="80px">
<el-form-item label="客户状态">
<el-select v-model="clientDialog.form.status" placeholder="选择客户状态">
<el-option v-for="item in clientDialog.list" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="action('action:changeStatusHide')">取 消</el-button>
<el-button type="primary" @click="action('action:statusSubmit')">确 定</el-button>
</div>
</el-dialog>
</section>
</template>
<script>
import {
allCsrUserList,
csrAddEditPreParam,
addCustomer,
customerAssignData,
assignCustomerToSeller,
delCustomerFollowSeller,
importCustomerData,
getCsrStatusList,
changeCustomerStatus,
outCustomerListExcel
} from '@/api/client/newClientManagement'
import paginationMixin from '@/mixins/pagination'
import addressMixin from '@/views/client/newClientManagement/mixins/address'
export default {
name: 'AllClientList',
mixins: [paginationMixin, addressMixin],
data() {
return {
tableData: {
row: []
},
loading: false,
queryInfo: {
csr_name: ''
},
dialog: {
title: '添加客户',
id: null,
addDialogVisible: false,
type: 'submit'
},
// 客服修改客户状态
clientDialog: {
changeStatusDialogVisible: false,
list: [],
form: {
status: null
}
},
formData: {
// 默认选中男
csr_sex: 1,
/** 国家id */
country_id: 7,
/** 省份 */
province_id: null,
/** 城市 */
city_id: null,
},
rules: {
csr_name: [
{ required: true, message: '客户名称不能为空', trigger: 'blur' }
],
csr_mobile: [
{ required: true, message: '客户手机号不能为空', trigger: 'blur' }
],
source_type: [
{ required: true, message: '客户来源不能为空', trigger: 'blur' }
],
},
formOptions: {
genderOptions: [
{value: 1, label: '男'},
{value: 2, label: '女' },
{value: 3, label: '未知' },
],
cityOptions: [],
sourceOptions: [],
},
allotDialog: {
allotDialogVisible: false,
sellerList: [],
sellerOption: []
},
allotForm: {id: null, customer_id: null, seller_id: null},
bathImportDialog: {
visible: false,
}
}
},
watch: {
address: {
handler(val) {
this.formData.country_id = val.country
this.formData.province_id = val.prov
this.formData.city_id = val.city
},
deep: true
}
},
created() {
this._fetchData()
this.getCsrAddEditPreParam()
this.getClientParams()
},
methods: {
async _fetchData(params) {
this.loading = true
try {
const {data: res } = await allCsrUserList({...params, csr_name: this.queryInfo.csr_name})
this.tableData.row = res.list
this.pagination.total = res.totalnum
this.pagination.current = res.pagenum
} finally {
this.loading = false
}
},
// 获取add/edit客户预数据
async getCsrAddEditPreParam() {
const {data: {data: res}} = await csrAddEditPreParam()
this.formOptions.sourceOptions = res.csr_customer_from.data.map(item => {
return {value: item.data_id, label: item.data_name}
})
},
// 获取修改客户弹窗 - params
async getClientParams() {
const { data } = await getCsrStatusList()
this.clientDialog.list = data.data.map(item => {
return { label: item.data_name, value: item.data_id }
})
console.log(this.clientDialog.list)
},
// 添加客户弹框
addCustomer() {
this.formData.csr_sex = 1
this.dialog.type = 'add'
this.action('action:show')
},
// 分配客户弹框
allotCustomer(row) {
this.allotDialog.allotDialogVisible = true
this.allotForm.id = row.id
this.getCustomerAssignData(this.allotForm.id)
},
// 获取分配预数据
async getCustomerAssignData(id) {
const {data: res} = await customerAssignData({customer_id: id})
this.allotDialog.sellerOption = res.seller.map(item => {
return {value: item.id, label: item.name}
})
this.allotDialog.sellerList = res.follow
},
// 给销售分配客户
async getAllotCustomer() {
const params = {
seller_id: this.allotForm.seller_id,
customer_id: this.allotForm.id,
}
await assignCustomerToSeller({...params})
this.getCustomerAssignData(this.allotForm.id)
this.allotForm.seller_id = null
this.$message.success('分配成功')
},
// 移除当前客户指定跟进销售
async deleteAllot(id) {
try {
await delCustomerFollowSeller({follow_id: id})
this.$message.success('移除当前客户指定跟进销售成功')
this.getCustomerAssignData(this.allotForm.id)
} catch (error) {
throw new Error(error.message)
}
// this.allotDialog.allotDialogVisible = false
},
// 统一控制
action(type) {
const action = this.dialog.type
switch (type) {
case 'action:show':
this.dialog.addDialogVisible = true
break;
case 'action:changeStatusShow':
this.clientDialog.changeStatusDialogVisible = true
break;
case 'action:changeStatusHide':
this.clientDialog.changeStatusDialogVisible = false
this.clientDialog.form = {
status: null
}
break;
case 'action:hide':
this.dialog.addDialogVisible = false
break;
case 'action:statusSubmit':
(async () => {
console.log(this.clientDialog.form)
const { message } = await changeCustomerStatus(this.clientDialog.form)
this.$message.success(message)
this.action('action:changeStatusHide')
this._fetchData()
})()
break;
case 'action:submit':
(async () => {
const data = function() {
if (action === 'add') {
return this.formData
}
return {...this.formData, id: this.dialog.id}
}.call(this)
const {message} = await this.actionHandl(data, action)
this.$message.success(message)
this.action('action:hide')
this._fetchData()
})()
}
},
actionHandl(data, action) {
if (action === 'add') return addCustomer(data)
},
dialogOnClose(name) {
this.$refs[name].resetFields()
this.allotForm = {}
this.formData = {}
},
/**
* @param {'action:show'|'action:hide'|'action:submit'} type
*/
bathImportAction(type) {
switch (type) {
case 'action:show':
this.bathImportDialog.visible = true
break
case 'action:hide':
this.bathImportDialog.visible = false
break
case 'action:submit':
this.$refs.bathImportUpload.submit()
}
},
async bathImportActionRequest(data) {
const { message } = await importCustomerData({ file: data.file })
this.$message.success(message)
this.bathImportAction('action:hide')
},
bathImportExceed() {
this.$message.warning('最多选择一个文件')
},
bathImportDialogClose(name) {
this.$refs[name].clearFiles()
},
changeStatus(row) {
this.clientDialog.form.customer_id = row.id
this.clientDialog.form.status = row.csr_status
this.action('action:changeStatusShow')
},
// 导出客户
async exportClient() {
const link = document.createElement('a')
link.href = `${process.env.VUE_APP_PUBLIC_PATH}customer/outCustomerListExcel`
link.target = '_blank'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
}
}
</script>
【vue】excel导出
于 2021-02-01 15:33:30 首次发布