Commit 7def1715 authored by 罗超's avatar 罗超

Merge branch 'master' of http://gitlab.oytour.com/xiangwei/horse

parents 528bcda8 90b38508
......@@ -14,24 +14,24 @@ import Axios from './axios'
* @property {string} password -用户密码
*/
interface CutomerParams {
PageIndex: number,
PageSize: number,
pageCount: number,
CorpName: string, //企业名称
CustomerName: string, //备注名
WeChatName: string, //昵称
CustomerMobile: string, //手机号码
CreateSTime: string, //创建开始时间
CreateETime: string, //创建结束时间
FriendSTime: string, //好友开始时间
FriendETime: string, //好友结束时间
Q_NotFollowUpDay: number, //几天未跟进
Q_Friends: string, //好友关系 多选逗号分隔、
Q_AddWay: string, //获取来源 多选英文逗号分隔
EmpId: number, //员工id
CustomerType: number, //类型1微信用户 2企业微信用户
SelectList: Array<any>, //自定义查询
OrderBy: number, //排序
PageIndex: number
PageSize: number
pageCount: number
CorpName: string //企业名称
CustomerName: string //备注名
WeChatName: string //昵称
CustomerMobile: string //手机号码
CreateSTime: string //创建开始时间
CreateETime: string //创建结束时间
FriendSTime: string //好友开始时间
FriendETime: string //好友结束时间
Q_NotFollowUpDay: number //几天未跟进
Q_Friends: string //好友关系 多选逗号分隔、
Q_AddWay: string //获取来源 多选英文逗号分隔
EmpId: number //员工id
CustomerType: number //类型1微信用户 2企业微信用户
SelectList: Array<any> //自定义查询
OrderBy: number //排序
AddCondition: number //查询条件
}
......
......@@ -29,7 +29,7 @@
<div class="flex-center">
<q-icon name="work" color="primary" v-if="item.Type == '1'" />
<q-icon name="person" color="accent" v-if="item.Type == '2'" />
<span class="q-ml-sm">{{ item.Name }}</span>
<span class="q-ml-sm">{{ item.DeptName }}</span>
</div>
<q-icon name="cancel" @click="delItem(item.Id, index)"></q-icon>
</div>
......@@ -40,7 +40,7 @@
<q-card-actions align="right" class="bg-white text-teal">
<q-btn flat label="取消" v-close-popup />
<q-btn color="primary" @click="goback" flat label="确定" />
<q-btn color="primary" @click="goback" unelevated label="确定" />
</q-card-actions>
</q-card>
</q-dialog>
......@@ -56,7 +56,7 @@
}
interface SelectParams {
Id: string
Name: string
DeptName: string
Type: number
}
export default {
......@@ -153,7 +153,7 @@
flag = false
} else {
ticketArr.value = JSON.parse(JSON.stringify(props.defaultArray))
console.log('默认值',ticketArr.value)
console.log('默认值',ticketArr.value)
}
}
......@@ -181,7 +181,7 @@
if (flag == true) {
selectArray.value.push({
Id: j[props.nodeKey],
Name: j.DeptName,
DeptName: j.DeptName,
Type: j.DataType
})
} else {
......
......@@ -31,11 +31,10 @@ export default {
const myAllCol = computed(() => {
return props.allCol
})
const showCol = computed(() => {
console.log(props.modelValue)
return props.modelValue
})
const changeVisible = (e) => {
if (e.visible) {
showCol.value.push(e.value)
......@@ -43,7 +42,6 @@ export default {
showCol.value.splice(showCol.value.indexOf(e.value), 1)
}
context.emit('update:modelValue', showCol.value)
console.log(showCol.value)
}
return { myAllCol, scrollStyle, changeVisible }
......
......@@ -283,7 +283,6 @@
}
]
const init = () => {
console.log('init', props.defaultData)
if (props.defaultData && props.defaultData.length > 0) {
addMsg.value = []
props.defaultData.map((e: any) => {
......@@ -410,7 +409,6 @@
IsCustom: 2
}
filedList.value.unshift(obj2)
console.log('标签', filedList.value)
})
}
const deleteadd = index => {
......@@ -463,7 +461,6 @@
let find2: any = addMsg.value.find(e => {
return e.Id == 17
})
console.log('生日2', find2)
if (find2) {
filedList.value.map(_e => {
if (_e.Id == 17) {
......@@ -568,7 +565,6 @@
const newVal=JSON.parse(JSON.stringify(val))
const s= dayjs(newVal[0]).format(format)
const e= dayjs(newVal[1]).format(format)
console.log(570,val,s,e)
addMsg.value[y].StartValue = s
addMsg.value[y].EndValue = e
}
......
// import { ResultType } from '@/@types/enumHelper'
// import router from '@/router'
// import UserActions from '@/store/modules/user/actions'//{ UserActionsType }
// import { UserGetter } from '@/store/modules/user/getters'
// import { dispatchAction, getStoreGetter, setStoreState } from '@/store/utils'
// import message from '@/utils/message'
import {
StaticConfig
} from '@/config/app'
import {
ref,
reactive
} from 'vue'
import customer, {
CutomerParams
} from '@/api/customer'
interface Params {
selectVal: string
selectWay: number
}
interface timeParams {
timeWay: number
}
interface customParams {
customWay: number
}
interface friendParams {
frendArr: Array < number >
wayArr: Array < number >
}
import dayjs from 'dayjs'
import { reactive } from 'vue'
import customer, { CutomerParams } from '@/api/customer'
import customerSetService from '@/api/customerSet'
import { ColumnDefaultState } from '@/@types/enumHelper'
interface memberParams {
newId: number | string
DataType: number | string
DeptId: number
ChildList: Array < any >|null
ChildList: Array < any > | null
}
interface dataParams {
columns: Array < any >
dataList: Array < any >
WayList: Array < any >
selected: Array < any >
EmployeeList: Array < memberParams >
defaultArray: Array < number | string >
CascaderValue: Array < any > | string
loading: boolean
columns: Array<any>
sysColumns:Array<any>
showColumns: Array<any>
allColumns: Array<any>
dataList: Array<any>
WayList: Array<any>
selected: Array<any>
EmployeeList: Array<memberParams>
defaultArray: Array<number | string>
customerCascaderValue: Array<any> | string
deptCascaderValue: string | null
colLoadingFinish:boolean
}
const CustomerModule = () => {
//调用方法
const getCustomerList = (param: CutomerParams) => {
customer.getCustomerList(param).then(res => {
console.log(res, '数据')
//获取列表
const getCustomerList = () => {
data.loading=true
customer.getCustomerList(msg).then(res => {
if (res.data.Code == 1) {
data.loading = false
data.dataList = res.data.Data.PageData
msg.pageCount = res.data.Data.PageCount
}
......@@ -64,20 +47,19 @@ const CustomerModule = () => {
})
}
//获取员工数据
const getEmployeeData = (param: any) => {
customer.getEmployeeData(param).then(res => {
const getEmployeeData = () => {
customer.getEmployeeData({}).then(res => {
data.EmployeeList = res.data.Data
console.log(data, '员工数据')
// 重组唯一id
if (data.EmployeeList.length == 0) return
data.EmployeeList.forEach(x => {
x.newId = x.DataType + '-' + x.DeptId
if (x.DataType === 2) {
x.ChildList = null
}
if (x.ChildList && x.ChildList.length > 0) {
getChildList(x.ChildList)
}
if (x.DataType === 2) {
x.ChildList = null
}
if (x.ChildList && x.ChildList.length > 0) {
getChildList(x.ChildList)
}
})
})
}
......@@ -92,25 +74,27 @@ const CustomerModule = () => {
}
})
}
const title = ref(StaticConfig.appsuffix)
//控制页显示条数
const pagination = reactive({
rowsPerPage: 0
})
//日期对象
// const daySelect =
const data = reactive < dataParams > ({
columns: [{
const data = reactive<dataParams>({
loading: false,
columns: [
{
name: 'CustomerName',
label: '客户',
field: 'CustomerName',
align: 'left'
},
}
],
sysColumns: [
{
name: 'StageName',
align: 'center',
label: '客户阶段',
field: 'StageName',
label: '客户阶段'
align: 'left'
},
{
name: 'LableList',
......@@ -124,12 +108,6 @@ const CustomerModule = () => {
field: 'carbs',
align: 'left'
},
{
name: 'CreateTime',
label: '创建时间',
field: 'CreateTime',
align: 'left'
},
{
name: 'sodium',
label: '负责人',
......@@ -148,8 +126,6 @@ const CustomerModule = () => {
field: 'Source',
align: 'left'
},
// { name: 'num', label: '7日内客户回复消息数', align: 'left'},
// { name: 'num', label: '7日内员工发送消息数', align: 'left'},
{
name: 'FriendTime',
label: '添加好友时间',
......@@ -163,14 +139,18 @@ const CustomerModule = () => {
align: 'left'
}
],
showColumns: ['CustomerName'], //对应allColumns的value
allColumns: [],
selected: [],
dataList: [],
WayList: [],
EmployeeList: [],
defaultArray: [], //
CascaderValue: ""
deptCascaderValue: null,
customerCascaderValue: '',
colLoadingFinish: false
})
const msg = reactive({
const msg = reactive<CutomerParams>({
PageIndex: 1,
PageSize: 10,
pageCount: 0,
......@@ -186,7 +166,6 @@ const CustomerModule = () => {
Q_Friends: '', //好友关系 多选逗号分隔、
Q_AddWay: '', //获取来源 多选英文逗号分隔
EmpId: 0, //员工id
DeptId: 0, //部门id
CustomerType: 0, //类型1微信用户 2企业微信用户
SelectList: [], //自定义查询
OrderBy: 1, //排序
......@@ -218,46 +197,65 @@ const CustomerModule = () => {
Id: 2
}
])
//自定义客户筛选
const CustomList = reactive([{
Name: '好友关系',
Id: 1
},
{
Name: '获取途径',
Id: 2
},
{
Name: '未跟进客户',
Id: 3
//切换时间范围
const changeTime = () => {
msg.FriendSTime = ''
msg.FriendETime = ''
msg.CreateSTime = ''
msg.CreateETime = ''
TimeObj.timeRange=null
}
//选择时间范围
const changeTimeRange = val => {
if (val) {
const s = dayjs(val[0]).format('YYYY-MM-DD HH:mm:ss')
const e = dayjs(val[1]).format('YYYY-MM-DD HH:mm:ss')
if (TimeObj.timeWay == 1) {
msg.CreateSTime = s
msg.CreateETime = e
} else {
msg.FriendSTime = s
msg.FriendETime = e
}
} else {
msg.FriendSTime = ''
msg.FriendETime = ''
msg.CreateSTime = ''
msg.CreateETime = ''
}
])
const friendOptions = reactive([{
Name: '好友客户',
Id: 1
getCustomerList()
}
//客户筛选
const CustomList = reactive([{
label: '好友关系',
value: '1',
children: [{
label: '未添加',
value: '1-1'
},
{
label: '已添加',
value: '1-2'
}
]
},
{
Name: '待添加',
Id: 2
label: '获取途径',
value: 2
},
{
Name: '已申请',
Id: 3
label: '未跟进客户',
value: 3
}
])
const SeletObj = reactive < Params > ({
const SeletObj = reactive ({
selectVal: '',
selectWay: 0
})
const TimeObj = reactive < timeParams > ({
timeWay: 1
})
const customSetObj = reactive < customParams > ({
customWay: 1
})
const friendObj = reactive < friendParams > ({
frendArr: [],
wayArr: []
const TimeObj = reactive ({
timeWay: 1,
timeRange: null
})
//选择方式
const getSelectWay = () => {
......@@ -281,39 +279,52 @@ const CustomerModule = () => {
}
const changePage = (val: any) => {
msg.PageIndex = val
getCustomerList(msg)
getCustomerList()
}
const getChild = (deptArray: any) => {
//数据处理 获取夏利是 1-2 前面代表部门还是人员 后面是原生ID
if (deptArray._value) {
const Type = deptArray._value.split('-')[0]
const MyId = deptArray._value.split('-')[1]
//1部门
if (Type == 1) {
msg.DeptId = MyId
}
//2人员
if (Type == 2) {
msg.EmpId = MyId
}
const getDept = (id: any) => {
//数据处理 获取id是 1-id,2-id 前面1代表部门2代表人员 后面是原生ID
if (id) {
msg.EmpId = id.slice(2)
} else {
msg.DeptId = 0
msg.EmpId = 0
}
getCustomerList(msg)
}
const getCkedFriend = (e: any) => {
const Ids = e
.map((x: any) => {
return x.Id
})
.toString()
msg.Q_Friends = Ids
getCustomerList(msg)
getCustomerList()
}
const CascaderUpdateValue = (val) => {
console.log('val', val)
const customerUpdateValue = val => {
console.log('customerUpdateValue', val)
}
data.sysColumns.map(e => {
data.columns.push(e)
data.showColumns.push(e.field)
data.allColumns.push({ name: e.label, value: e.field, visible: true, IsCustom: 0 })
})
customerSetService
.getCustomerFiledList({
Enable: 1
})
.then(r => {
const tempCol = r.data.Data
if (tempCol && tempCol.length > 0) {
tempCol.sort((x, y) => {
return x.Sort - y.Sort
})
tempCol.forEach(x => {
const tempRow = { name: x.Name, label: x.Name, field: x.Name, align: 'left' }
data.columns.push(tempRow)
if (x.IsDefault == ColumnDefaultState.Yes) {
data.showColumns.push(x.Name)
}
data.allColumns.push({ name: x.Name, value: x.Name, visible: x.IsDefault == ColumnDefaultState.Yes, data: x, IsCustom: 1 })
})
}
//#region 添加菜单权限
data.columns.push({ name: 'setting', label: '自定义列', field: 'setting', align: 'left' })
data.showColumns.push('setting')
//#endregion
data.colLoadingFinish = true
})
return {
getCustomerList,
......@@ -321,21 +332,18 @@ const CustomerModule = () => {
getEmployeeData,
data,
msg,
title,
TypeList,
SeletObj,
getSelectWay,
TimeObj,
TimeList,
changeTime,
changeTimeRange,
changePage,
pagination,
CustomList,
customSetObj,
friendObj,
friendOptions,
getChild,
getCkedFriend,
CascaderUpdateValue
getDept,
customerUpdateValue,
}
}
......
<template>
<div class="q-pa-md customer">
<q-page padding style="background: #FFF;border-radius: 10px;">
<q-page padding style="background: #fff; border-radius: 10px">
<div class="page-search row items-center">
<div class="col row wrap q-mr-lg q-col-gutter-md">
<div class="col-3">
<q-input filled v-model="SeletObj.selectVal" clearable @clear="getCustomerList(msg)"
@update:model-value="getSelectWay(), getCustomerList(msg)" label="请输入">
<q-input filled v-model="SeletObj.selectVal" clearable @clear="getCustomerList"
@update:model-value="getSelectWay(), getCustomerList" placeholder="请输入">
<template #before>
<q-select filled style="width:120px;" @update:model-value="getSelectWay" option-value="Id"
option-label="Name" v-model="SeletObj.selectWay" :options="TypeList" emit-value map-options
label="选择类型" />
<div style="border-right: 1px solid #999">
<q-select filled @update:model-value="getSelectWay" option-value="Id" option-label="Name"
v-model="SeletObj.selectWay" :options="TypeList" emit-value map-options />
</div>
</template>
</q-input>
</div>
<div class="col-3">
<div class="flex no-wrap">
<q-select filled option-value="Id" option-label="Name" v-model="TimeObj.timeWay" :options="TimeList"
emit-value map-options />
</div>
<template v-if="TimeObj.timeWay == 1">
<div class="col-3">
<q-input filled v-model="msg.CreateSTime" mask="date" @update:model-value="getCustomerList(msg)"
placeholder="创建时间">
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy ref="qDateProxy" cover transition-show="scale" transition-hide="scale">
<q-date v-model="msg.CreateSTime">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Close" color="primary" flat />
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
<div class="col-3">
<q-input filled v-model="msg.CreateETime" mask="date" @range-end="getCustomerList(msg)"
placeholder="创建时间">
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy ref="qDateProxy" cover transition-show="scale" transition-hide="scale">
<q-date v-model="msg.CreateETime">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Close" color="primary" flat />
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
</template>
<template v-if="TimeObj.timeWay == 2">
<div class="col-3">
<q-input filled v-model="msg.FriendSTime" mask="date" placeholder="添加时间">
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy ref="qDateProxy" cover transition-show="scale" transition-hide="scale">
<q-date v-model="msg.FriendSTime">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Close" color="primary" flat />
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
<div class="col-3">
<q-input filled v-model="msg.FriendETime" mask="date" placeholder="添加时间">
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy ref="qDateProxy" cover transition-show="scale" transition-hide="scale">
<q-date v-model="msg.FriendETime">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Close" color="primary" flat />
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
</template>
<div class="col-3">
<q-select filled option-value="Id" option-label="Name" v-model="customSetObj.customWay"
:options="CustomList" emit-value map-options />
</div>
<div class="col-3" v-if="customSetObj.customWay == 1">
<q-select filled label="请选择" use-chips @update:model-value="getCkedFriend" option-value="Id"
option-label="Name" :options="friendOptions" v-model="friendObj.frendArr" multiple />
emit-value map-options @update:model-value="changeTime"> </q-select>
<n-config-provider :locale="zhCN" :date-locale="dateZhCN">
<n-date-picker v-model:value="TimeObj.timeRange" type="datetimerange" size="large" separator="至" clearable
class="full-height" @update:value='changeTimeRange'/>
</n-config-provider>
</div>
<div class="col-3" v-if="customSetObj.customWay == 2">
<q-select filled label="请选择" use-chips option-value="Id" option-label="Name" :options="data.WayList"
v-model="friendObj.wayArr" multiple />
<div class="col-2">
<n-cascader v-model:value="data.customerCascaderValue" clearable placeholder="客户筛选" check-strategy="child"
size="large" :show-path="false" max-tag-count="responsive" multiple :options="CustomList" cascade
@update:value="customerUpdateValue" />
</div>
<div class="col-3" v-if="customSetObj.customWay == 3">
<q-input filled v-model="msg.Q_NotFollowUpDay" label="几天未跟进"></q-input>
</div>
<div class="col-3">
<n-cascader v-model:value="data.CascaderValue" clearable placeholder="选择部门/人员" check-strategy="all"
<div class="col-2">
<n-cascader v-model:value="data.deptCascaderValue" clearable placeholder="选择部门/人员" check-strategy="all"
value-field="newId" label-field="DeptName" size="large" :show-path="false" max-tag-count="responsive"
:options="data.EmployeeList" cascade children-field="ChildList"
@update:value="CascaderUpdateValue" />
:options="data.EmployeeList" cascade children-field="ChildList" @update:value="getDept" />
</div>
<div class="col-3">
<div class="col-2">
<q-btn color="primary" size="sm" label="导入" />
<q-btn color="primary" size="sm" style="margin-left:20px;" label="导出" />
<q-btn color="primary" size="sm" style="margin-left: 20px" label="导出" />
</div>
</div>
</div>
<div class="page-content" style="margin-top:20px;">
<q-table :rows="data.dataList" :columns="data.columns" class="my-sticky-header-column-table" row-key="name"
v-model:pagination="pagination" selection="multiple">
<div class="page-content" style="margin-top: 20px">
<q-table :rows="data.dataList" :columns="data.columns" class="sticky-tow-column-table full-height sticky-right-column-table" row-key="Id" :loading="data.loading"
v-model:pagination="pagination" selection="multiple" v-model:selected="data.selected" :visible-columns="data.showColumns">
<template v-slot:body-cell-CustomerName="props">
<q-td auto-width :props="props">
<div class="cutomer_Header">
<div class="customer_Img">
<img :src="props.row.WeChatPhoto" style="width:100%;height:100%" />
<img :src="props.row.WeChatPhoto" style="width: 100%; height: 100%" />
</div>
<div>
<div class="cutomer_Free" @click="getCustomInfo(props)">{{ props.row.CustomerName }}</div>
......@@ -128,20 +57,37 @@
</template>
<template v-slot:body-cell-LableList="props">
<q-td auto-width :props="props">
<q-chip v-for="(item,index) in props.row.LableList" :key="index">{{ item }}</q-chip>
<q-chip v-for="(item, index) in props.row.LableList" :key="index">{{ item }}</q-chip>
</q-td>
</template>
<template v-slot:bottom>
<q-pagination class="full-width justify-end" v-model="msg.PageIndex" color="primary" :max="msg.pageCount"
:input="true" @update:model-value="changePage" />
</template>
<template v-for="x in data.allColumns.filter(x=>x.IsCustom>0)" :key="x.value" v-slot:[`body-cell-${x.value}`]="props">
<q-td auto-width :props="props">
{{props.row.CustomFiledList.find(y=>y.Name==x.name).ShowValue}}
</q-td>
</template>
<template v-slot:body-cell-setting="props">
<q-td :props="props" style="background:rgba(0,0,0,0)"></q-td>
</template>
<template v-slot:header-cell-setting="props">
<q-th class="mysetting" :props="props">
<i class="iconfont icon-tiaojieqi cursor-pointer" style="font-size:20px;">
<q-popup-proxy>
<visible-columns v-model="data.showColumns" :allCol="data.allColumns"></visible-columns>
</q-popup-proxy>
</i>
</q-th>
</template>
</q-table>
<customRight v-if="isShowCustom" :CustomerId="CustomerId" @close="closeCustomer"></customRight>
</div>
</q-page>
</div>
</template>
<script lang='ts'>
<script lang="ts">
import {
ref,
defineComponent,
......@@ -149,9 +95,15 @@
} from 'vue'
import CustomerModule from '@/module/customer/customerModule'
import customRight from '@/components/common/customRight.vue'
import visibleColumns from '@/components/common/visibleColumns.vue'
import {
zhCN,
dateZhCN
} from 'naive-ui'
export default defineComponent({
components: {
customRight,
visibleColumns
},
setup() {
let {
......@@ -159,64 +111,58 @@
getWayList,
data,
msg,
title,
TypeList,
SeletObj,
getSelectWay,
TimeObj,
TimeList,
changeTime,
changeTimeRange,
changePage,
pagination,
CustomList,
customSetObj,
friendObj,
friendOptions,
getEmployeeData,
getChild,
getCkedFriend,
CascaderUpdateValue
getDept,
customerUpdateValue,
} = CustomerModule()
let isShowCustom = ref(false)
const closeCustomer = () => {
isShowCustom.value = false;
isShowCustom.value = false
}
let CustomerId = ref(0);
const getCustomInfo = (item) => {
CustomerId.value = item.row.Id;
isShowCustom.value = true;
let CustomerId = ref(0)
const getCustomInfo = item => {
CustomerId.value = item.row.Id
isShowCustom.value = true
}
onMounted(() => {
getCustomerList(msg)
getCustomerList()
getWayList({})
getEmployeeData({})
getEmployeeData()
})
return {
zhCN,
dateZhCN,
getCustomerList,
getWayList,
data,
msg,
title,
TypeList,
SeletObj,
getSelectWay,
TimeObj,
TimeList,
changeTime,
changeTimeRange,
changePage,
pagination,
CustomList,
customSetObj,
friendObj,
friendOptions,
getEmployeeData,
getChild,
getCkedFriend,
isShowCustom,
closeCustomer,
getDept,
CustomerId,
getCustomInfo,
CascaderUpdateValue
customerUpdateValue,
}
}
})
......@@ -250,15 +196,30 @@
.customer_Wechat {
color: #9999a8;
}
::v-deep .n-base-selection-label{
height: 54px;
background-color: rgba(0, 0, 0, 0.05);
border: none !important;
}
::v-deep .n-base-selection-input{
height: 54px;
display: flex;
align-items: center;
border: none !important;
}
::v-deep .n-base-selection-label {
height: 54px;
background-color: rgba(0, 0, 0, 0.05);
border: none !important;
}
::v-deep .n-base-selection-input {
height: 54px;
display: flex;
align-items: center;
border: none !important;
}
::v-deep .n-input {
height: 100%;
border: none;
display: flex;
align-items: center;
}
::v-deep .n-base-selection-tags {
height: 54px;
background-color: rgba(0, 0, 0, 0.05);
}
</style>
<template>
<div class="q-mt-md q-pa-md CustomerOperation flex">
<div class="customer-operation-category">
<q-btn label="保存" @click="setCustomerConfig"></q-btn>
<div v-for="item in leftList" :key="item.Id" :class="{ active: curItem == item.Id }"
class="customer-operation-category--item" @click="changeActive(item)">{{ item.Name }}</div>
</div>
......@@ -17,104 +18,22 @@
<q-btn color="primary" :disable="!PublicGetDeptState" unelevated label="修改" size="xs" class="q-ml-lg"
@click="checkedPublicGetDept" />
</div>
<div>
<div v-for="(item,index) in data.PublicGetDeptList" :key="index" class="dept-item">
<div v-if="PublicGetDeptState">
<div v-for="(item,index) in PublicGetDeptNameList" :key="index" class="dept-item">
<div class="flex justify-center items-center">
<q-icon name="work" color="primary" />
<span class="q-ml-sm">{{ item.Name }}</span>
<q-icon name="work" color="primary" v-if="item.Type==1" />
<q-icon name="person" color="primary" v-if="item.Type==2" />
<span class="q-ml-sm">{{ item.DeptName }}</span>
</div>
</div>
</div>
</div>
</div>
<div v-if="curItem == 2">
<div class="row">
<div class="collaborator-title">可放弃客户:</div>
<div class="col-10">
<div class="q-gutter-sm">
<q-radio v-model="data.AbandonType" :val="1" label="全部客户" />
<q-radio v-model="data.AbandonType" :val="2" label="部分客户" />
</div>
<div v-if="data.AbandonType == 2">
<requestGroup />
</div>
</div>
</div>
<div class="row">
<div class="collaborator-title">可操作员工:</div>
<div class="col-10">
<div class="flex items-center">
<q-toggle v-model="AbandonDeptState" @update:model-value="ChangeAbandonDeptState" />以下部门允许将客户放弃到公海
<q-btn color="primary" :disable="!AbandonDeptState" label="修改" unelevated size="xs" class="q-ml-lg"
@click="checkedPublicGetDept" />
</div>
<div>
<div v-for="(item,index) in data.AbandonDeptList" :key="index" class="dept-item">
<div class="flex justify-center items-center">
<q-icon name="work" color="primary" />
<span class="q-ml-sm">{{ item.Name }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="collaborator-title">放弃后审核:</div>
<div class="col-10">
<div class="flex items-center">
<q-toggle v-model="data.AbandonAudit" false-value="-1" />开启后,员工放弃客户时需要企微端设置的部门上级审批,审批同意后才可放弃。</div>
</div>
</div>
<div class="row">
<div class="collaborator-title" style="padding-top: 15px">放弃原因:</div>
<div class="col-10">
<draggable v-model="data.AbandonReasonList" tag="div" item-key="Id">
<template #item="{ element,index }">
<div class="flex items-center">
<i class="iconfont icon-drag" style="font-size: 20px; color: #777"></i>
<div class="AbandonReasonItem flex items-center">{{ element }}</div>
<n-popover trigger="hover">
<template #trigger>
<i class="iconfont icon-edit_light" style="font-size: 20px; color: #111"
@click="editAbandonReason(element,index)"></i>
</template>
<span>编辑</span>
</n-popover>
<n-popover trigger="hover">
<template #trigger>
<i class="iconfont icon-delete_light q-ml-md" style="font-size: 20px; color: #111"
@click="delAbandonReaso(index)"></i>
</template>
<span>删除</span>
</n-popover>
</div>
</template>
</draggable>
<div class="flex items-center q-pl-sm q-mt-md">
<q-btn color="primary" label="添加" unelevated class="q-ml-lg q-mr-md" @click="addAbandonReason" />
已设/可设上限:{{data.AbandonReasonList.length}}/10</div>
<q-dialog v-model="AbandonReasonDialog">
<q-card>
<q-card-section class="row items-center q-pb-none">
<div class="text-h6" v-if="AbandonReasonType==0">添加</div>
<div class="text-h6" v-if="AbandonReasonType==1">编辑</div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section class="q-py-lg" style="width: 460px;max-width: 600px;">
<n-input maxlength="10" size="large" v-model:value="AbandonReasonText" show-count clearable
placeholder="请输入放弃原因" />
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="取消" color="primary" v-close-popup />
<q-btn unelevated label="确定" color="primary" @click="saveAbandonReason" />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</div>
<Abandon v-model:AabandonType="data.AbandonType" v-model:AbandonDept="data.AbandonDept"
v-model:AbandonAudit="data.AbandonAudit" :AbandonReasonList="data.AbandonReasonList"
v-model:AbandonReason="data.AbandonReason" v-model:AbandonSelectType="data.AbandonSelectType"
:AbandonEmpList="data.AbandonEmpList" :AbandonDeptList="data.AbandonDeptList" />
</div>
<div v-if="curItem == 3" class="row">
<div class="collaborator-title">申请成为协作人:</div>
......@@ -124,7 +43,7 @@
<q-btn color="primary" label="修改" unelevated size="xs" class="q-ml-lg" @click="checkedPublicGetDept" />
</div>
<div>
<div v-for="item in items" :key="item.id">{{ item }}</div>
<!-- <div v-for="item in items" :key="item.id">{{ item }}</div> -->
</div>
</div>
</div>
......@@ -136,7 +55,7 @@
<q-btn color="primary" label="修改" unelevated size="xs" class="q-ml-lg" @click="checkedPublicGetDept" />
</div>
<div>
<div v-for="item in items" :key="item.id">{{ item }}</div>
<!-- <div v-for="item in items" :key="item.id">{{ item }}</div> -->
</div>
<div class="flex">
<q-checkbox v-model="data.AddTeamDept" label="协作人被移除后(若该协作人已添加客户为好友),自动创建新的客户" />
......@@ -226,8 +145,8 @@
</div>
</div>
</div>
<departmentStaff v-model="showDptDialog" :defaultArray="DptDataTreeDefault" nodeKey="DeptId"
labelKey="DeptName" childrenKey="ChildList" strategy="leaf" :treeData="DptDataTree" @select="getdpt" />
<departmentStaff v-model="showDptDialog" :defaultArray="DptDataTreeDefault" nodeKey="newId" labelKey="DeptName"
childrenKey="ChildList" strategy="leaf" :treeData="DptDataTree" @select="getdpt" />
</div>
</template>
<script lang="ts">
......@@ -236,14 +155,15 @@
toRefs,
reactive,
defineComponent,
onMounted
onMounted,
provide,
watch,
} from 'vue'
import message from '@/utils/message'
import customerSetService from '@/api/customerSet'
import customerService from '@/api/customer'
import departmentStaff from '@/components/common/departmentStaff.vue'
import requestGroup from '@/components/customer/request-group.vue'
import draggable from 'vuedraggable'
import message from '@/utils/message'
import Abandon from "./CustomerOperationComponents/Abandon.vue"
interface dataParams {
data: {
AbandonReasonList: string[]
......@@ -254,8 +174,7 @@
export default defineComponent({
components: {
departmentStaff,
requestGroup,
draggable
Abandon
},
setup() {
const leftList = ref([{
......@@ -296,6 +215,7 @@
}
])
let curItem = ref(1)
let DptDataTree = ref < any[] > ([])
let data = reactive < dataParams > ({
data: {
IsPublicAudit: 1,
......@@ -305,35 +225,41 @@
AbandonReasonList: [],
},
PublicGetDeptState: false, //以下部门允许领取公海客户
AbandonDeptState: false, //以下部门允许将客户放弃到公海
PublicGetDeptNameList: [], //允许领取公海客户列表
showDptDialog: false,
AbandonReasonDialog: false, //放弃原因弹窗
AbandonReasonText: "", //放弃原因
AbandonReasonIndex: 0, //放弃原因index
AbandonReasonType: 0, // 修改类型 0:新增,1:编辑
DptDataTree: [],
DptDataTreeDefault: [], //部门默认值
})
provide('DptDataTree', DptDataTree)
provide('data', data)
const changeActive = item => {
curItem.value = item.Id
}
//获取客户操作配置
const getConfig = () => {
customerSetService.getCustomerConfig({}).then(res => {
console.log('CONFIG', res.data.Data)
console.log('客户操作配置', res.data.Data)
data.data = res.data.Data
if (data.data.PublicGetDept == -1) {
data.PublicGetDeptState = false
} else {
data.PublicGetDeptState = true
}
const PublicGetDeptList = data.data.PublicGetDeptList.map(e => {
e.Type = 1
return e
})
const PublicGetEmpList = data.data.PublicGetEmpList.map(e => {
e.Type = 2
return e
})
data.PublicGetDeptNameList=[...PublicGetDeptList,...PublicGetEmpList]
})
}
const getDptTree = () => {
customerService.getEmployeeData({}).then(res => {
data.DptDataTree = res.data.Data
if (data.dataTree.length == 0) return
data.DptDataTree.forEach(x => {
DptDataTree.value = res.data.Data
if (DptDataTree.value.length == 0) return
DptDataTree.value.forEach(x => {
x.newId = x.DataType + '-' + x.DeptId
if (x.ChildList && x.ChildList.length > 0) {
getChildList(x.ChildList)
......@@ -351,33 +277,34 @@
}
//保存客户操作配置
const setCustomerConfig = () => {
customerSetService.setCustomerConfig(data.data).then(res => {
console.log('set', res.data.Data)
customerSetService.setCustomerConfig(data.data).then(() => {
message.successMsg('设置成功')
getConfig()
})
}
//部门弹窗
const checkedPublicGetDept = () => {
data.showDptDialog = true
if (curItem.value === 1) {
data.DptDataTreeDefault = data.data.PublicGetDept.split(',')
// data.DptDataTreeDefault = data.data.PublicGetDept.split(',')
} else if (curItem.value === 2) {
data.DptDataTreeDefault = data.data.AbandonDept.split(',')
// data.DptDataTreeDefault = data.data.AbandonDept.split(',')
}
}
const getdpt = val => {
data.showDptDialog = false
const ids = val.map(e => e.Id).toString()
const ids = val.map(e => e.Id.slice(2)).toString()
const dept = JSON.parse(JSON.stringify(val))
if (curItem.value === 1) {
data.data.PublicGetDept = ids
data.data.PublicGetDeptList = dept
data.PublicGetDeptNameList = dept
}
if (curItem.value === 2) {
data.data.AbandonDept = ids
data.data.AbandonDeptList = dept
}
console.log('dpt', ids)
console.log('dpt', dept)
}
//以下部门允许领取公海客户
const ChangePublicGetDeptState = (val) => {
......@@ -385,44 +312,13 @@
data.data.PublicGetDept = '-1'
}
}
//以下部门允许将客户放弃到公海
const ChangeAbandonDeptState = (val) => {
if (!val) {
data.data.AbandonDept = '-1'
}
}
//新增放弃原因
const addAbandonReason = () => {
data.AbandonReasonDialog = true
data.AbandonReasonText = '',
data.AbandonReasonIndex = 0
data.AbandonReasonType = 0
}
//修改放弃原因
const editAbandonReason = (val, index) => {
data.AbandonReasonDialog = true
data.AbandonReasonText = val,
data.AbandonReasonIndex = index
data.AbandonReasonType = 1
}
//保存放弃原因
const saveAbandonReason = () => {
if (!data.AbandonReasonText) {
message.warnMsg('不能为空')
return
}
if (data.AbandonReasonType === 0) {
data.data.AbandonReasonList.push(data.AbandonReasonText)
} else {
data.data.AbandonReasonList[data.AbandonReasonIndex] = data.AbandonReasonText
}
data.AbandonReasonDialog = false
data.AbandonReasonText = ''
}
// 删除放弃原因
const delAbandonReaso = (index) => {
data.data.AbandonReasonList.splice(index, 1)
}
watch(() => data.data, val => {
console.log('watch', val)
}, {
deep: true
})
onMounted(() => {
getDptTree()
getConfig()
......@@ -432,15 +328,11 @@
curItem,
changeActive,
...toRefs(data),
DptDataTree,
getdpt,
checkedPublicGetDept,
setCustomerConfig,
addAbandonReason,
editAbandonReason,
saveAbandonReason,
delAbandonReaso,
ChangePublicGetDeptState,
ChangeAbandonDeptState,
}
}
})
......@@ -483,17 +375,6 @@
overflow: auto;
}
.AbandonReasonItem {
width: 453px;
height: 50px;
line-height: 50px;
padding-left: 22px;
background-color: #fff;
border-radius: 5px;
border: 1px solid #d7d7d7;
margin: 10px;
}
.collaborator-title {
min-width: 80px;
line-height: 40px;
......
<template>
<div>
<div class="row">
<div class="collaborator-title">可放弃客户:</div>
<div class="col-10">
<div class="q-gutter-sm">
<q-radio v-model="Type" :val="1" @update:model-value="changeAbandonType" label="全部客户" />
<q-radio v-model="Type" :val="2" @update:model-value="changeAbandonType" label="部分客户" />
</div>
<div v-if="Type == 2">
<requestGroup v-model:addCondition="SelectType" :defaultData="AbandonKHSelect" @change="getCondition"/>
</div>
</div>
</div>
<div class="row">
<div class="collaborator-title">可操作员工:</div>
<div class="col-10">
<div class="flex items-center">
<q-toggle v-model="AbandonDeptState" @update:model-value="ChangeAbandonDeptState" />以下部门允许将客户放弃到公海
<q-btn color="primary" :disable="!AbandonDeptState" label="修改" unelevated size="xs" class="q-ml-lg"
@click="checkedPublicGetDept" />
</div>
<div>
<div v-for="(item, index) in AbandonDeptNameList" :key="index" class="dept-item">
<div class="flex justify-center items-center">
<q-icon name="work" color="primary" v-if="item.Type == 1" />
<q-icon name="person" color="primary" v-if="item.Type == 2" />
<span class="q-ml-sm">{{ item.DeptName }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="collaborator-title">放弃后审核:</div>
<div class="col-10">
<div class="flex items-center">
<q-toggle v-model="Audit" :true-value="1" :false-value="2" @update:model-value="ChangeAbandonAuditState" />
开启后,员工放弃客户时需要企微端设置的部门上级审批,审批同意后才可放弃。</div>
</div>
</div>
<div class="row">
<div class="collaborator-title" style="padding-top: 15px">放弃原因:</div>
<div class="col-10">
<draggable v-model="ReasonList" tag="div" item-key="Id">
<template #item="{ element, index }">
<div class="flex items-center">
<i class="iconfont icon-drag" style="font-size: 20px; color: #777"></i>
<div class="AbandonReasonItem flex items-center">{{ element }}</div>
<n-popover trigger="hover">
<template #trigger>
<i class="iconfont icon-edit_light" style="font-size: 20px; color: #111"
@click="editAbandonReason(element, index)"></i>
</template>
<span>编辑</span>
</n-popover>
<n-popover trigger="hover">
<template #trigger>
<i class="iconfont icon-delete_light q-ml-md" style="font-size: 20px; color: #111"
@click="delAbandonReaso(index)"></i>
</template>
<span>删除</span>
</n-popover>
</div>
</template>
</draggable>
<div class="flex items-center q-pl-sm q-mt-md">
<q-btn color="primary" label="添加" unelevated class="q-ml-lg q-mr-md" @click="addAbandonReason" />
已设/可设上限:{{ ReasonList.length }}/10
</div>
<q-dialog v-model="AbandonReasonDialog">
<q-card>
<q-card-section class="row items-center q-pb-none">
<div class="text-h6" v-if="AbandonReasonType == 0">添加</div>
<div class="text-h6" v-if="AbandonReasonType == 1">编辑</div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section class="q-py-lg" style="width: 460px; max-width: 600px">
<n-input maxlength="10" size="large" v-model:value="AbandonReasonText" show-count clearable
placeholder="请输入放弃原因" />
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="取消" color="primary" v-close-popup />
<q-btn unelevated label="确定" color="primary" @click="saveAbandonReason" />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</div>
<departmentStaff v-model="DptDialog" :defaultArray="DptDataDefault" nodeKey="newId" labelKey="DeptName"
childrenKey="ChildList" strategy="leaf" :treeData="DptDataTree" @select="getAbandonDpt" />
</div>
</template>
<script lang="ts">
import {
ref,
toRefs,
reactive,
defineComponent,
inject,
} from 'vue'
import departmentStaff from '@/components/common/departmentStaff.vue'
import requestGroup from '@/components/customer/request-group.vue'
import draggable from 'vuedraggable'
import message from '@/utils/message'
interface dataParams {
AbandonReasonList: string[]
[key: string]: any
}
export default defineComponent({
components: {
departmentStaff,
requestGroup,
draggable
},
props: {
AabandonType: {
type: Number,
default: 1
},
AbandonDept: {
type: String,
default: "-1"
},
AbandonDeptList: {
type: Array,
default: () => []
},
AbandonEmpList: {
type: Array,
default: () => []
},
AbandonAudit: {
type: Number,
default: 2
},
AbandonReason: {
type: String,
default: ''
},
AbandonReasonList: {
type: Array,
default: () => []
},
AbandonSelectType: { //可放弃部分客户的查询类型 1并且 2或者
type: Number,
default: 1
},
},
setup(props, ctx) {
const DptDataTree: any = inject('DptDataTree')
const FaData: any = inject('data')
let DptDialog = ref(false)
let DptDataDefault = ref < string[] > ([])
let data = reactive < dataParams > ({
AbandonDeptNameList: [], //可放弃到公海的部门
AbandonReasonDialog: false, //放弃原因弹窗
AbandonReasonText: '', //放弃原因
AbandonReasonIndex: 0, //放弃原因index
AbandonReasonType: 0, //修改类型 0:新增,1:编辑
AbandonDeptState: false, //以下部门允许将客户放弃到公海
AbandonReasonList: [],
})
const ReasonList = ref(props.AbandonReasonList)
if (props.AbandonDept == '-1') {
data.AbandonDeptState = false
} else {
data.AbandonDeptState = true
const dept = props.AbandonDeptList.map((e: any) => '1-' + e.DeptId)
const deptName = props.AbandonDeptList.map((e: any) => {
e.Type = 1
return e
})
const emp = props.AbandonEmpList.map((e: any) => '2-' + e.DeptId)
const empName = props.AbandonEmpList.map((e: any) => {
e.Type = 2
return e
})
DptDataDefault.value = [...dept, ...emp]
data.AbandonDeptNameList = [...deptName, ...empName]
}
//以下部门允许将客户放弃到公海
const ChangeAbandonDeptState = (val) => {
if (!val) {
ctx.emit("update:AbandonDept", '-1')
}
}
//放弃后是否需要审核
const ChangeAbandonAuditState = (val) => {
ctx.emit("update:AbandonAudit", val)
}
//部门弹窗
const checkedPublicGetDept = () => {
DptDialog.value = true
}
const getAbandonDpt = val => {
DptDialog.value = false
const ids = val.map(e => e.Id.slice(2)).toString()
const dept = JSON.parse(JSON.stringify(val))
data.AbandonDeptNameList = dept
ctx.emit("update:AbandonDept", ids)
}
//新增放弃原因
const addAbandonReason = () => {
data.AbandonReasonDialog = true
data.AbandonReasonText = '',
data.AbandonReasonIndex = 0
data.AbandonReasonType = 0
}
//修改放弃原因
const editAbandonReason = (val, index) => {
data.AbandonReasonDialog = true
data.AbandonReasonText = val,
data.AbandonReasonIndex = index
data.AbandonReasonType = 1
}
//保存放弃原因
const saveAbandonReason = () => {
if (!data.AbandonReasonText) {
message.warnMsg('不能为空')
return
}
if (data.AbandonReasonType === 0) {
ReasonList.value.push(data.AbandonReasonText)
} else {
ReasonList.value[data.AbandonReasonIndex] = data.AbandonReasonText
}
ctx.emit("update:AbandonReason", ReasonList.value.toString())
data.AbandonReasonDialog = false
data.AbandonReasonText = ''
}
// 删除放弃原因
const delAbandonReaso = (index: number) => {
ReasonList.value.splice(index, 1)
}
const changeAbandonType = (val: number) => {
ctx.emit('update:AabandonType', val)
}
const getCondition=(val)=>{
FaData.data.AbandonKHSelect=JSON.parse(JSON.stringify(val))
}
return {
Type: ref(props.AabandonType),
Audit: ref(props.AbandonAudit),
SelectType: ref(props.AbandonSelectType),
AbandonKHSelect:ref(FaData.data.AbandonKHSelect),
ReasonList,
DptDataTree,
...toRefs(data),
DptDialog,
DptDataDefault,
ChangeAbandonDeptState,
ChangeAbandonAuditState,
addAbandonReason,
editAbandonReason,
saveAbandonReason,
delAbandonReaso,
checkedPublicGetDept,
getAbandonDpt,
changeAbandonType,
getCondition
}
}
})
</script>
<style lang="scss" scoped>
.collaborator-title {
min-width: 80px;
line-height: 40px;
text-align: right;
margin-right: 10px;
font-weight: 600;
white-space: nowrap;
}
.AbandonReasonItem {
width: 453px;
height: 50px;
line-height: 50px;
padding-left: 22px;
background-color: #fff;
border-radius: 5px;
border: 1px solid #d7d7d7;
margin: 10px;
}
.dept-item {
border: 1px solid #e1f3d8;
background-color: #f0f9eb;
color: #67c23a;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
height: 32px;
line-height: 32px;
border-radius: 3px;
padding: 0 14px;
margin: 6px;
}
</style>
......@@ -36,14 +36,14 @@
v-if="x.Id.slice(0, 1) == '1'"
text-color="white"
icon="work"
:label="x.Name"
:label="x.DeptName"
></q-chip>
<q-chip
color="primary"
v-if="x.Id.slice(0, 1) == '2'"
text-color="white"
icon="person"
:label="x.Name"
:label="x.DeptName"
></q-chip>
</div>
</div>
......
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