html
复制代码
<template>
<div>
<el-card shadow="never">
<el-form ref="queryDOM" :model="queryForm" label-width="80">
<el-form-item label="客户简称" prop="customerShortName">
<el-input clearable v-model="queryForm.customerShortName" class="max-w-260px" maxlength="6"></el-input>
<el-checkbox class="ml-2" label="仅显示经营正常" v-model="queryForm.isNormal"></el-checkbox>
</el-form-item>
<div v-show="filteredSwtich">
<el-form-item label="客户全称" prop="customerFullName">
<company-complete v-model="queryForm.customerFullName" maxlength="40" class="max-w-260px" />
</el-form-item>
<el-form-item label="客户类别" prop="customerTypes">
<el-checkbox-group v-model="queryForm.customerTypes">
<el-checkbox v-for="item in crm_customer_type" :key="item.dictValue" :value="item.dictValue"
:label="item.dictLabel"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="级别" prop="customerLevels">
<el-checkbox class="important-mr-4" v-model="checkAllLevels" :indeterminate="levelsIndeterminate"
@change="handleCheckAllLevels">
全选
</el-checkbox>
<el-checkbox-group class="contents" v-model="queryForm.customerLevels" @change="handleCheckedLevelsChange">
<el-checkbox v-for="item in customer_level" :key="item.dictValue" :value="item.dictValue"
:label="item.dictLabel"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="行业" prop="industries">
<el-checkbox class="important-mr-4" v-model="checkAllIndustries" :indeterminate="industriesIndeterminate"
@change="handleCheckAllIndustries">
全选
</el-checkbox>
<el-checkbox-group class="contents" v-model="queryForm.industries" @change="handleCheckedIndustriesChange">
<el-checkbox v-for="item in customer_industry" :key="item.dictValue" :value="item.dictValue"
:label="item.dictLabel"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="所在地区" prop="address">
<District v-model="queryForm.address" v-model:value="address" class="max-w-260px" />
</el-form-item>
<!-- <el-form-item label="商机" prop="industry">
<el-checkbox class="ml-2" label="有赢单" v-model="queryForm.status"></el-checkbox>
</el-form-item> -->
<!-- <el-form-item label="需求\项目" prop="industry">
<el-checkbox-group v-model="queryForm.customerType">
<el-checkbox label="有进行中"></el-checkbox>
<el-checkbox label="有已完成"></el-checkbox>
</el-checkbox-group>
</el-form-item> -->
<el-form-item label="创建人" prop="createUserId">
<user-dropdown v-model="queryForm.createUserId" class="max-w-260px" />
</el-form-item>
<el-form-item label="创建时间" prop="createTimePeriod">
<el-date-picker v-model="queryForm.createTimePeriod" value-format="YYYY-MM-DD" type="daterange"
@visible-change="e => { if (e) { queryForm.createTimePeriod = [] } }"
class="max-w-260px"></el-date-picker>
</el-form-item>
</div>
<div class="text-right">
<el-button icon="Search" @click="searchData" type="primary" :loading="loading">搜索</el-button>
<el-button icon="Refresh" @click="resetData" :loading="loading">重置</el-button>
<el-button :icon="filteredSwtich ? 'ArrowUp' : 'ArrowDown'" @click="filteredSwtich = !filteredSwtich" text>
{{ filteredSwtich ? "收起" : "展开" }}
</el-button>
</div>
</el-form>
</el-card>
<el-card shadow="never" class="mt-5">
<div class="fillter-tag">
<strong v-show="filteredView.length">筛选:</strong>
<el-tag disable-transitions class="mr-2" v-for="tag in filteredView" :key="tag.label" closable
:title="tag.label" @close="removeFilteredTag(tag)">
{{ tag.label }}
</el-tag>
</div>
<cit-table :loading="tableLoading" :data="tableData" :total="dataTotal" :page-size="queryForm.pageSize"
:current-page="queryForm.pageNum" @current-change="handleCurrentChange" @size-change="dataSizeChange">
<template #columns>
<el-table-column prop="customerFullName" label="客户全称" min-width="220">
<template #default="scope">
<router-link :to="'/customer/list/detail/' + scope.row.id">
<el-button link type="primary">{{ scope.row.customerFullName }}</el-button>
</router-link>
</template>
</el-table-column>
<el-table-column prop="customerShortName" label="客户简称" />
<el-table-column prop="customerType" label="客户类别">
<template #default="scope">
<dict-tag :options="crm_customer_type" :value="scope.row.customerType" />
</template>
</el-table-column>
<el-table-column prop="operateStatus" label="经营情况">
<template #default="scope">
<dict-tag :options="customer_operate_status" :value="scope.row.operateStatus" />
</template>
</el-table-column>
<el-table-column prop="customerLevel" label="级别">
<template #default="scope">
<dict-tag :options="customer_level" :value="scope.row.customerLevel" />
</template>
</el-table-column>
<el-table-column prop="industry" label="行业">
<template #default="scope">
<dict-tag :options="customer_industry" :value="scope.row.industry" />
</template>
</el-table-column>
<el-table-column prop="customerType" label="所在地址">
<template #default="scope">
{{ scope.row.districtName }} {{ scope.row.address }}
</template>
</el-table-column>
<!-- <el-table-column prop="customerType" label="商机数(赢单)" sortable />
<el-table-column prop="customerType" label="报障数" /> -->
</template>
</cit-table>
</el-card>
</div>
</template>
<script setup name="CustomerListIndex">
/**
* @author 全易
* @time 2025-10-24 15:21:32 星期五
* @description 客户列表
* @example
**/
import { getUserList } from "@/service/dictionarys.js";
import { customerList } from '../api/customer.js';
import filterLabels from './assets/filterLabels.json';
const instance = getCurrentInstance();
const filteredSwtich = ref(false); // 是否显示更多过滤条件
const {
customer_operate_status,
customer_level,
crm_customer_type,
customer_industry
} = instance.proxy.useDict(
"customer_operate_status",
"customer_level",
"crm_customer_type",
"customer_industry"
);
// 监听事件总线 [提交了客户信息]
eventBus?.on('customer-updata', () => {
getData()
});
const { queryForm, tableData, dictionarys } = toRefs(reactive({
queryForm: {
pageNum: 1,
pageSize: Number(import.meta.env.VITE_APP_DATA_SIZE),
isNormal: true
},
tableData: [],
dictionarys: {
customer_level,
crm_customer_type,
customer_industry
}
}));
// 赋值创建时间范围(用两个字段)
watch(() => queryForm.value.createTimePeriod, (time) => {
queryForm.value.createTimeStart = time && time[0] || null;
queryForm.value.createTimeEnd = time && time[1] || null;
});
// 所在地区字段重新定义(取最后一位)
watch(() => queryForm.value.address, (now) => {
queryForm.value.districtCode = now && now[2] || null;
});
function getDictionarys() {
// 平台用户
getUserList().then((res) => {
if (res.code === 200) {
dictionarys.value.systemUsers = res.data;
}
})
}
getDictionarys()
/* 过滤条件回显 */
const address = ref([]);
const filteredView = computed(() => {
let tags = []
for (const item of filterLabels) {
if (item.type === 'array') {
queryForm.value[item.key]?.forEach((val, index) => {
if (index !== 0) { return; }
if (item.key === 'address') {
tags.push({ type: item.key, data: queryForm.value[item.key], label: `${item.label} - ${address.value?.fullName}` })
} else if (item.key === 'createTimePeriod') {
tags.push({ type: item.key, data: queryForm.value[item.key], label: `${item.label} - ${queryForm.value?.createTimeStart} ~ ${queryForm.value?.createTimeEnd}` })
} else {
const dictionary = instance.proxy.selectDictLabel(dictionarys.value?.[item.dictionary], queryForm.value[item.key], { name: 'dictLabel', code: 'dictValue' })
tags.push({ type: item.key, data: queryForm.value[item.key], label: `${item.label} - ${dictionary}` })
}
});
} else if (item.type === 'string' && queryForm.value[item.key]) {
if (item.key === 'createUserId') {
const systemUserInfo = instance.proxy.selectDictLabel(dictionarys.value?.systemUsers, queryForm.value[item.key], { name: 'realName', code: 'id' })
tags.push({ type: item.key, data: queryForm.value[item.key], label: `${item.label} - ${systemUserInfo}` })
} else {
tags.push({ type: item.key, data: queryForm.value[item.key], label: `${item.label} - ${queryForm.value[item.key]}` })
}
}
}
return tags
})
/* ---------- 删除filteredView标签 ---------- */
function removeFilteredTag(tag) {
for (const item of filterLabels) {
if (item.key === tag.type) {
if (Array.isArray(queryForm.value[item.key])) {
queryForm.value[item.key] = [];
} else {
queryForm.value[item.key] = null;
}
break;
}
}
}
// 级别全选
const checkAllLevels = ref(false)
const levelsIndeterminate = ref(false)
watch(() => queryForm.value.customerLevels, (now) => {
const checkedCount = now?.length || 0;
const totalCount = customer_level.value?.length || 0;
if (checkedCount === 0) {
// 无选
checkAllLevels.value = false;
levelsIndeterminate.value = false;
} else if (checkedCount === totalCount) {
// 全选
checkAllLevels.value = true;
levelsIndeterminate.value = false;
} else {
// 半选
checkAllLevels.value = false;
levelsIndeterminate.value = true;
}
});
const handleCheckAllLevels = (val) => {
queryForm.value.customerLevels = val ? customer_level.value.map(item => item.dictValue) : []
}
const handleCheckedLevelsChange = (value) => {
const checkedCount = value.length;
checkAllLevels.value = checkedCount === customer_level.value.length
levelsIndeterminate.value = checkedCount > 0 && checkedCount < customer_level.value.length
}
// 行业全选
const checkAllIndustries = ref(false)
const industriesIndeterminate = ref(false)
watch(() => queryForm.value.industries, (now) => {
const checkedCount = now?.length || 0;
const totalCount = customer_industry.value?.length || 0;
if (checkedCount === 0) {
// 无选
checkAllIndustries.value = false;
industriesIndeterminate.value = false;
} else if (checkedCount === totalCount) {
// 全选
checkAllIndustries.value = true;
industriesIndeterminate.value = false;
} else {
// 半选
checkAllIndustries.value = false;
industriesIndeterminate.value = true;
}
});
const handleCheckAllIndustries = (val) => {
queryForm.value.industries = val ? customer_industry.value.map(item => item.dictValue) : []
}
const handleCheckedIndustriesChange = (value) => {
const checkedCount = value.length;
checkAllIndustries.value = checkedCount === customer_industry.value.length
industriesIndeterminate.value = checkedCount > 0 && checkedCount < customer_industry.value.length
}
// 获取数据
const dataTotal = ref(0);
const tableLoading = ref(false);
function getData() {
tableLoading.value = true;
tableData.value = [];
customerList(queryForm.value).then((res) => {
if (res.code === 200) {
dataTotal.value = res.data.total;
tableData.value = res.data.list;
}
}).finally(() => {
tableLoading.value = false;
})
}
getData()
// 翻页
function handleCurrentChange(now) {
queryForm.value.pageNum = now;
getData()
}
// 页量
function dataSizeChange(size) {
queryForm.value.pageSize = size;
getData()
}
// 过滤数据
function searchData() {
queryForm.value.pageNum = 1;
getData()
}
// 重置条件
async function resetData() {
instance.proxy.$refs.queryDOM.resetFields()
await nextTick()
getData()
}
</script>
<style scoped>
.fillter-tag {
white-space: nowrap;
overflow-y: auto;
}
</style>