Commit 30bd7e3c authored by Mac's avatar Mac

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

parents 72c1c0eb c9096f9d
......@@ -21,10 +21,10 @@ interface ClueParams {
OrderBy: number //排序
AddCondition: number //查询条件
}
class customerService {
// 获取用户列表数据
static async getCustomerList(data: ClueParams): Promise<HttpResponse> {
return Axios('/QYCustomer/GetCustomerInfoPageList', {
class clueService {
// 获取客户线索规则列表
static async getCustomerClueRuleList(data: ClueParams): Promise<HttpResponse> {
return Axios('/QYCustomer/GetCustomerCluePageList', {
method: 'post',
responseType: 'json',
data
......@@ -33,4 +33,4 @@ class customerService {
}
export { ClueParams }
export default customerService
export default clueService
......@@ -41,7 +41,7 @@
}
// 获取客户线索规则列表
static async getCustomerClueRuleList(data:any): Promise<HttpResponse> {
return Axios('QYCustomer/GetCustomerClueRuleList', {
return Axios('/QYCustomer/GetCustomerClueRuleList', {
method: 'post',
responseType: 'json',
data
......
import { boot } from 'quasar/wrappers'
import axios, { AxiosInstance } from 'axios'
import { Cascader } from 'ant-design-vue'
import { Cascader, DatePicker } from 'ant-design-vue'
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$axios: AxiosInstance
......@@ -20,7 +20,7 @@ export default boot(({ app }) => {
app.config.globalProperties.$axios = axios
// ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
// so you won't necessarily have to import axios in each vue file
app.use(Cascader)
app.use(Cascader, DatePicker)
/**
* @deprecated 弃用的方法
*/
......
<template>
<div :class="classStr" :id="id">
<!--多选-->
<template v-if="multiple">
<q-select
filled
v-model="resultObj"
:options="selectList"
clearable
@clear="clearData()"
:label="tipText"
:multiple="multiple"
emit-value
map-options
>
<template v-slot:option="scope">
<q-item v-if="scope.index == -1">
<q-item-section>
<q-tree
:nodes="treeData"
:node-key="nodeKey"
:label-key="labelKey"
:children-key="childrenKey"
tick-strategy="strict"
:default-expand-all="defaultExpandAll"
no-connectors
v-model:ticked="chooseTreeNodeArray"
></q-tree>
</q-item-section>
</q-item>
</template>
<template v-slot:after-options>
<q-item>
<q-item-section>
<q-tree
:nodes="treeData"
:node-key="nodeKey"
:label-key="labelKey"
:children-key="childrenKey"
tick-strategy="strict"
:default-expand-all="defaultExpandAll"
no-connectors
v-model:ticked="chooseTreeNodeArray"
></q-tree>
</q-item-section>
</q-item>
</template>
</q-select>
</template>
<!--单选-->
<template v-else>
<q-select
filled
v-model="resultObj[0]"
:options="selectList"
clearable
@clear="clearData()"
:label="tipText"
:multiple="multiple"
emit-value
map-options
>
<template #option="scope">
<q-item v-if="scope.index == 0">
<q-item-section>
<q-tree
:nodes="treeData"
:node-key="nodeKey"
:label-key="labelKey"
:children-key="childrenKey"
tick-strategy="strict"
:default-expand-all="defaultExpandAll"
no-connectors
v-model:ticked="chooseTreeNodeArray"
></q-tree>
</q-item-section>
</q-item>
</template>
</q-select>
</template>
</div>
</template>
<script lang="ts">
import { ref, toRefs, watch } from 'vue'
interface itemParams {
[propName: string]: any
}
export default {
props: {
//样式字符串
classStr: {
type: String,
default: ''
},
//树形结构列表
treeData: {
type: Array,
required: true
},
//是否默认展开
defaultExpandAll: {
type: Boolean,
default: false
},
//是否多选
multiple: {
type: Boolean,
default: false
},
//默认选中值
defaultArray: {
type: Array,
required: true,
},
//节点Key
nodeKey: {
type: String,
default: 'id'
},
//节点名称
labelKey: {
type: String,
default: 'name'
},
//子节点名称
childrenKey: {
type: String,
default: 'children'
},
//下拉框提示信息
tipText: {
type: String,
default: '请选择'
}
},
setup(props: itemParams, ctx: itemParams) {
let id = ref('selectTree' + (Math.floor((Math.random() * 10000) + 1)))
let selectList = ref<Array<itemParams>>([{
value: "",
label: ""
}])//下拉框列表
let chooseTreeNodeArray = ref<Array<itemParams>>([])//节点选择列表
let resultObj = ref<Array<itemParams>>([]) //下拉框选择列表
//Tree节点选中或取消选中
watch(
() => [...chooseTreeNodeArray.value],
() => {
if (!props.multiple && chooseTreeNodeArray.value && chooseTreeNodeArray.value.length > 1) {
let lastItem = chooseTreeNodeArray.value[chooseTreeNodeArray.value.length - 1];
chooseTreeNodeArray.value = [lastItem];
}
setTreeCheckNode()
})
//有默认值
watch(
() => [...props.defaultArray],
() => {
chooseTreeNodeArray.value = [];
if (props.defaultArray && props.defaultArray.length > 0) {
props.defaultArray.forEach(item => {
if (item != '') {
if (props.multiple) {
chooseTreeNodeArray.value.push(item)
} else {
chooseTreeNodeArray.value = [item];
}
}
})
}
setTreeCheckNode();
})
watch(
() => [...resultObj.value],
() => {
let resultStr = ref("");
if (resultObj.value && resultObj.value.length > 0) {
if (props.multiple) {
let newarr = Array.from(new Set(resultObj.value)) //数组去重
resultStr.value = newarr.toString();
} else {
resultStr.value = resultObj.value[0].toString();
}
}
ctx.emit('getChild', resultStr);
})
//清空数据
let clearData = () => {
selectList.value = [{
value: "",
label: ""
}];
chooseTreeNodeArray.value = [];
resultObj.value = [];
}
//设置下拉框选择
let setTreeCheckNode = () => {
selectList.value = [];
resultObj.value = [];
let nodes = findTreeNode(props.treeData);
if (chooseTreeNodeArray.value.length > 0 && nodes && nodes.value.length > 0) {
chooseTreeNodeArray.value.forEach(id => {
nodes.value.forEach((item) => {
if (item.value == id) {
selectList.value.push({
value: item.value,
label: item.label
});
if (props.multiple) {
resultObj.value.push(item.value);
console.log(214, resultObj.value)
} else {
resultObj.value = [item.value];
}
}
})
})
}
if (selectList.value.length == 0) {
selectList.value = [{
value: "",
label: ""
}];
}
}
//获取树中所有节点
let findTreeNode = (tree: Array<any>) => {
let temp = ref<Array<any>>([]);
//获取子节点
var getChildNodes = function (tree: Array<any>) {
if (tree && tree.length > 0) {
for (var i = 0; i < tree.length; i++) {
temp.value.push({
label: tree[i][props.labelKey],
value: tree[i][props.nodeKey]
});
if (tree[i][props.childrenKey]) {
getChildNodes(tree[i][props.childrenKey]);
}
}
}
};
getChildNodes(tree);
return temp;
}
return {
...toRefs(props),
id,
selectList,
chooseTreeNodeArray,
resultObj,
clearData,
setTreeCheckNode,
findTreeNode
}
}
}
</script>
\ No newline at end of file
// import { ref, reactive } from 'vue'
import customerService, { ClueParams } from '@/api/clue'
// interface dataType{
// }
// let data = reactive({})
import { ref, reactive } from 'vue'
import clueService, { ClueParams } from '@/api/clue'
const ClueModule = () => {
// 定义tab
const useTab = () => {
const tab = ref(1)
const setTab = (name: number) => {
tab.value = name
}
return [tab, setTab]
}
const msg = reactive({
PageIndex: 1,
PageSize: 10,
pageCount: 0,
CorpName: '', //企业名称
CustomerName: '', //备注名
WeChatName: '', //昵称
CustomerMobile: '', //手机号码
CreateSTime: '', //创建开始时间
CreateETime: '', //创建结束时间
FriendSTime: '', //好友开始时间
FriendETime: '', //好友结束时间
Q_NotFollowUpDay: 0, //几天未跟进
Q_Friends: '', //好友关系 多选逗号分隔、
Q_AddWay: '', //获取来源 多选英文逗号分隔
EmpId: 0, //员工id
CustomerType: 0, //类型1微信用户 2企业微信用户
SelectList: [], //自定义查询
OrderBy: 1, //排序
AddCondition: 0 //查询条件
})
const data = reactive({
columns: [
{
name: 'CustomerName',
label: '客户',
field: 'CustomerName',
align: 'left'
},
{ name: 'StageName', align: 'center', field: 'StageName', label: '客户阶段' },
{ name: 'LableList', label: '客户标签', field: 'LableList', align: 'left' },
{ name: 'carbs', label: '内容标签', field: 'carbs', align: 'left' },
{ name: 'CreateTime', label: '创建时间', field: 'CreateTime', align: 'left' },
{ name: 'sodium', label: '负责人', field: 'sodium', align: 'left' },
{ name: 'LastFollowUpTime', label: '上次跟进', field: 'LastFollowUpTime', align: 'left' },
{ name: 'Source', label: '渠道活码来源', field: 'Source', align: 'left' },
// { name: 'num', label: '7日内客户回复消息数', align: 'left'},
// { name: 'num', label: '7日内员工发送消息数', align: 'left'},
{ name: 'FriendTime', label: '添加好友时间', field: 'FriendTime', align: 'left' },
{ name: 'CheckInNum', label: '签到拜访', field: 'CheckInNum', align: 'left' }
],
selected: [],
dataList: [],
WayList: [],
EmployeeList: [],
rowsPerPage: 0
})
//获取线索列表
const getCluerList = (param: ClueParams) => {
customerService.getCustomerList(param).then(res => {
clueService.getCustomerClueRuleList(param).then(res => {
console.log(res, '数据')
})
}
return { getCluerList }
return { useTab, msg,data, getCluerList }
}
export default ClueModule
\ No newline at end of file
export default ClueModule
......@@ -6,8 +6,8 @@
// import { dispatchAction, getStoreGetter, setStoreState } from '@/store/utils'
// import message from '@/utils/message'
import { StaticConfig } from '@/config/app'
import { ref,reactive } from 'vue'
import customer2,{CutomerParams} from '@/api/customer2'
import { ref, reactive } from 'vue'
import customer2, { CutomerParams } from '@/api/customer2'
interface Params {
selectVal: string
selectWay: number
......@@ -22,64 +22,94 @@ interface friendParams {
frendArr: Array<number>
wayArr: Array<number>
}
interface memberParams {
newId: number | string
DataType: number | string
DeptId: number
ChildList: Array<any>
}
interface dataParams {
columns: Array<any>
dataList: Array<any>
WayList: Array<any>
selected: Array<any>
EmployeeList: Array<memberParams>
defaultArray: Array<number|string>
}
const CustomerModule = () => {
//调用方法
const getCustomerList =(param:CutomerParams)=>{
customer2.getCustomerList(param).then(res=>{
console.log(res,'数据');
if(res.data.Code==1){
data.dataList = res.data.Data.PageData;
msg.pageCount = res.data.Data.PageCount;
const getCustomerList = (param: CutomerParams) => {
customer2.getCustomerList(param).then(res => {
console.log(res, '数据')
if (res.data.Code == 1) {
data.dataList = res.data.Data.PageData
msg.pageCount = res.data.Data.PageCount
}
})
}
//调用获取下拉
const getWayList =(param:any)=>{
customer2.getWayList(param).then(res=>{
if(res.data.Code==1){
data.WayList = res.data.Data;
const getWayList = (param: any) => {
customer2.getWayList(param).then(res => {
if (res.data.Code == 1) {
data.WayList = res.data.Data
}
})
}
//获取员工数据
const getEmployeeData =(param:any)=>{
customer2.getEmployeeData(param).then(res=>{
console.log(res,'员工数据');
if(res.data.Code==1){
data.EmployeeList = res.data.Data;
const getEmployeeData = (param: any) => {
customer2.getEmployeeData(param).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.ChildList && x.ChildList.length > 0) {
getChildList(x.ChildList)
}
})
})
}
const getChildList = (ChildList: Array<any>) => {
ChildList.forEach(x => {
x.newId = x.DataType + '-' + x.DeptId
if (x.ChildList && x.ChildList.length > 0) {
getChildList(x.ChildList)
}
})
}
const title = ref(StaticConfig.appsuffix)
//控制页显示条数
const pagination = reactive({
rowsPerPage:0
rowsPerPage: 0
})
//日期对象
// const daySelect =
const data = reactive({
columns:[{
// const daySelect =
const data = reactive<dataParams>({
columns: [
{
name: 'CustomerName',
label: '客户',
field: 'CustomerName',
align: 'left',
align: 'left'
},
{ name: 'StageName', align: 'center', field:'StageName', label: '客户阶段'},
{ name: 'LableList', label: '客户标签', field:'LableList', align: 'left'},
{ name: 'carbs', label: '内容标签', field:'carbs', align: 'left' },
{ name: 'CreateTime', label: '创建时间', field:'CreateTime', align: 'left' },
{ name: 'sodium', label: '负责人', field:'sodium', align: 'left' },
{ name: 'LastFollowUpTime', label: '上次跟进', field:'LastFollowUpTime', align: 'left' },
{ name: 'Source', label: '渠道活码来源', field:'Source', align: 'left'},
{ name: 'StageName', align: 'center', field: 'StageName', label: '客户阶段' },
{ name: 'LableList', label: '客户标签', field: 'LableList', align: 'left' },
{ name: 'carbs', label: '内容标签', field: 'carbs', align: 'left' },
{ name: 'CreateTime', label: '创建时间', field: 'CreateTime', align: 'left' },
{ name: 'sodium', label: '负责人', field: 'sodium', align: 'left' },
{ name: 'LastFollowUpTime', label: '上次跟进', field: 'LastFollowUpTime', align: 'left' },
{ name: 'Source', label: '渠道活码来源', field: 'Source', align: 'left' },
// { name: 'num', label: '7日内客户回复消息数', align: 'left'},
// { name: 'num', label: '7日内员工发送消息数', align: 'left'},
{ name: 'FriendTime', label: '添加好友时间', field:'FriendTime', align: 'left'},
{ name: 'CheckInNum', label: '签到拜访', field:'CheckInNum', align: 'left'},
{ name: 'FriendTime', label: '添加好友时间', field: 'FriendTime', align: 'left' },
{ name: 'CheckInNum', label: '签到拜访', field: 'CheckInNum', align: 'left' }
],
selected:[],
dataList:[],
WayList:[],
EmployeeList:[]
selected: [],
dataList: [],
WayList: [],
EmployeeList: [],
defaultArray: [] //
})
const msg = reactive({
PageIndex: 1,
......@@ -102,88 +132,115 @@ const CustomerModule = () => {
OrderBy: 1, //排序
AddCondition: 0 //查询条件
})
const TypeList = reactive([{
Name:'企业',
Id:0
},{
Name:'昵称',
Id:1
},{
Name:'备注名',
Id:2
},{
Name:'电话',
Id:3
}])
const TimeList = reactive([{
Name:'客户创建时间',
Id:1
},{
Name:'好友添加时间',
Id:2
}])
const TypeList = reactive([
{
Name: '企业',
Id: 0
},
{
Name: '昵称',
Id: 1
},
{
Name: '备注名',
Id: 2
},
{
Name: '电话',
Id: 3
}
])
const TimeList = reactive([
{
Name: '客户创建时间',
Id: 1
},
{
Name: '好友添加时间',
Id: 2
}
])
//自定义客户筛选
const CustomList = reactive([{
Name:'好友关系',
Id:1
},{
Name:'获取途径',
Id:2
},{
Name:'未跟进客户',
Id:3
}])
const friendOptions = reactive([{
Name:'好友客户',
Id:1
},{
Name:'待添加',
Id:2
},{
Name:'已申请',
Id:3
}])
const SeletObj:Params = reactive({
selectVal:'',
selectWay:0
const CustomList = reactive([
{
Name: '好友关系',
Id: 1
},
{
Name: '获取途径',
Id: 2
},
{
Name: '未跟进客户',
Id: 3
}
])
const friendOptions = reactive([
{
Name: '好友客户',
Id: 1
},
{
Name: '待添加',
Id: 2
},
{
Name: '已申请',
Id: 3
}
])
const SeletObj: Params = reactive({
selectVal: '',
selectWay: 0
})
const TimeObj:timeParams = reactive({
timeWay:1
const TimeObj: timeParams = reactive({
timeWay: 1
})
const customSetObj:customParams = reactive({
customWay:1
const customSetObj: customParams = reactive({
customWay: 1
})
const friendObj:friendParams = reactive({
frendArr:[],
wayArr:[]
const friendObj: friendParams = reactive({
frendArr: [],
wayArr: []
})
//选择方式
const getSelectWay = () => {
msg.CorpName = '';
msg.WeChatName = '';
msg.CustomerName = '';
msg.CustomerMobile = '';
msg.CorpName = ''
msg.WeChatName = ''
msg.CustomerName = ''
msg.CustomerMobile = ''
//1企业名称 2姓名 3备注名 4手机号
if(SeletObj.selectWay==0){
msg.CorpName = SeletObj.selectVal;
if (SeletObj.selectWay == 0) {
msg.CorpName = SeletObj.selectVal
}
if(SeletObj.selectWay==1){
msg.WeChatName = SeletObj.selectVal;
if (SeletObj.selectWay == 1) {
msg.WeChatName = SeletObj.selectVal
}
if(SeletObj.selectWay==2){
msg.CustomerName = SeletObj.selectVal;
if (SeletObj.selectWay == 2) {
msg.CustomerName = SeletObj.selectVal
}
if(SeletObj.selectWay==3){
msg.CustomerMobile = SeletObj.selectVal;
if (SeletObj.selectWay == 3) {
msg.CustomerMobile = SeletObj.selectVal
}
}
const changePage = (val:any) => {
msg.PageIndex = val;
getCustomerList(msg);
const changePage = (val: any) => {
msg.PageIndex = val
getCustomerList(msg)
}
const getChild = (deptArray: any) => {
console.log('getChild', deptArray)
//数据处理 获取夏利是 1-2 前面代表部门还是人员 后面是原生ID
}
const getCkedFriend = (e)=>{
const Ids = e.map(x=>{
return x.Id
}).toString();
msg.Q_Friends = Ids;
getCustomerList(msg)
}
return { getCustomerList,getWayList,getEmployeeData,data,msg,title,TypeList,SeletObj,getSelectWay,TimeObj,TimeList,changePage,pagination,
CustomList,customSetObj,friendObj,friendOptions}
return { getCustomerList, getWayList, getEmployeeData, data, msg, title, TypeList, SeletObj, getSelectWay, TimeObj, TimeList, changePage, pagination,
CustomList, customSetObj, friendObj, friendOptions, getChild, getCkedFriend}
}
export default CustomerModule
......@@ -26,7 +26,8 @@
<tr v-if="data.length == 0&&defaultData.length == 0">
<td :colspan="9" align="center">暂无数据</td>
</tr>
<tr v-for="(item,index) in defaultData" v-if="defaultData.length > 0" :key="index">
<template v-if="defaultData.length > 0">
<tr v-for="(item,index) in defaultData" :key="index">
<td>
<span v-if="item.RuleSelectType === 1">并且</span>
<span v-if="item.RuleSelectType === 2">或者</span>
......@@ -65,6 +66,7 @@
<td>
</td>
</tr>
</template>
<draggable v-model="data" tag="tbody" item-key="Id" @update="datadragEnd" v-if="data.length > 0">
<template #item="{ element }">
<tr>
......
<template>
<div class="q-pa-md customer">
<q-page padding style="background: #FFF;border-radius: 10px;">
<q-tabs
v-model="tab"
dense
class="text-grey"
align="left"
active-color="primary"
indicator-color="primary"
narrow-indicator
>
<q-tab name="1" label="业务模式" />
<q-tab name="2" label="客户字段" />
<q-tab name="3" label="标签" />
<q-tab name="4" label="线索分配规则" />
</q-tabs>
<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" label='请输入'>
<!-- <q-input filled v-model="SeletObj.selectVal" label='请输入'>
<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="选择类型" />
</template>
</q-input>
</q-input> -->
</div>
<div class="col-3">
<!-- <q-select filled style="width:120px;" @update:model-value="getSelectTime" option-value="Id" option-label="Name" v-model="TimeObj.timeWay"
......@@ -23,7 +37,7 @@
:columns="data.columns"
class="my-sticky-header-column-table"
row-key="name"
v-model:pagination="pagination"
v-model:pagination="data.pagination"
selection="multiple">
<template v-slot:bottom>
<q-pagination class="full-width justify-end" v-model="msg.PageIndex" color="primary" :max="msg.pageCount"
......@@ -36,18 +50,20 @@
</template>
<script lang='ts'>
import {defineComponent,onMounted} from 'vue'
import CustomerModule from '@/module/customer/customerModule'
import ClueModule from '@/module/customer/clueModule'
export default defineComponent({
setup() {
let {
getCustomerList,data,msg,title,TypeList,SeletObj,getSelectWay,TimeObj,TimeList,changePage,pagination
} = CustomerModule()
useTab, getCluerList,msg,data
} = ClueModule()
let [ tab ,setTab]=useTab()
onMounted(()=>{
getCustomerList(msg)
getCluerList(msg)
})
return {
getCustomerList,data,msg,title,TypeList,SeletObj,getSelectWay,TimeObj,TimeList,changePage,pagination
tab,setTab,msg, getCluerList,data
}
}
})
......
This diff is collapsed.
......@@ -2,6 +2,7 @@
"extends": "@quasar/app/tsconfig-preset",
"compilerOptions": {
"baseUrl": ".",
"noImplicitAny": false,
"paths": {
"@/*": ["src/*"]
},
......
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