<template> <div> <div class="relative"> <el-tabs v-model="queryType" size="small" @tab-change="quickChange"> <el-tab-pane label="全部" name="0" /> <el-tab-pane name="1"> <template #label> <Tooltip message="除了无效线索和已成交的线索" /> <el-badge v-if="clueCount.unSignNum" :value="clueCount.unSignNum" :max="9999"> <span class="ml-3px">未成交</span> </el-badge> <span v-else class="ml-3px">未成交</span> </template> </el-tab-pane> <el-tab-pane name="2"> <template #label> <Tooltip message="下次跟进时间在今日之前的未成交线索" /> <el-badge v-if="clueCount.followNum" :value="clueCount.followNum" :max="9999"> <span class="ml-3px">待跟进</span> </el-badge> <span v-else class="ml-3px">待跟进</span> </template> </el-tab-pane> <el-tab-pane name="3"> <template #label> <Tooltip message="只有创建时间,无下次跟进时间的未成交线索" /> <el-badge v-if="clueCount.newNum" :value="clueCount.newNum" :max="9999"> <span class="ml-3px">新线索</span> </el-badge> <span v-else class="ml-3px">新线索</span> </template> </el-tab-pane> <el-tab-pane label="公海" name="4" /> <el-tab-pane v-if="appStore.getAppInfo?.instanceType == 1" label="地图总览" name="5" style="height: calc(100vh - 160px)" > <ClueMap ref="mapClue" v-if="queryType == 5" /> </el-tab-pane> </el-tabs> <div class="absolute" style="right: 10px; top: 0"> <el-button plain v-hasPermi="['clue:pool:import']">导入</el-button> <el-button type="primary" @click="handleInsert" v-hasPermi="['clue:pool:add']"> 新增线索 </el-button> </div> </div> <template v-if="queryType != 5"> <!-- 搜索工作栏 --> <Search v-if="!loading" ref="searchRef" :schema="allSchemas.searchSchema" labelWidth="0"> <template #actionMore> <el-button @click="getTableList" v-hasPermi="['clue:pool:search']"> 搜索 </el-button> <el-button @click="resetQuery" v-hasPermi="['clue:pool:reset']"> 重置 </el-button> <el-button @click="handleBatchChangeFollow" v-hasPermi="['clue:pool:batch-update-follow']" > 批量修改跟进人 </el-button> </template> </Search> <!-- 列表 --> <SSTable v-if="!loading" class="mt-20px" v-model:tableObject="tableObject" :tableColumns="allSchemas.tableColumns" @get-list="getTableList" @get-checked-columns="getCheckedColumns" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="60" /> <el-table-column v-for="item in showColumns" :key="item.field" :prop="item.field" :label="item.label" min-width="120px" > <template #default="{ row }"> <div v-if="item.field == 'followRecord'"> <el-button type="primary" text style="padding: 0" @click="handleFollow(row)" v-if="queryType != 4" v-hasPermi="['clue:pool:update']" > 快速新增 </el-button> </div> <div v-else-if="item.field == 'contact'"> <span>{{ row[item.field] }}</span> <Icon class="ml-5px" icon="ep:phone" @click="makeCall(row.contact)" /> </div> <div v-else-if="item.form?.component == 'DatePicker'"> <span>{{ formatDate(row[item.field]) }}</span> </div> <div v-else-if="item.field == 'remark' || item.form?.component == 'Editor'"> <el-popover placement="top" width="500px" trigger="click" v-if="row[item.field]"> <template #reference> <el-button type="primary" style="padding: 0" text>点击查看</el-button> </template> <div v-dompurify-html="row[item.field]"></div> </el-popover> </div> <span v-else>{{ row[item.field] }}</span> </template> </el-table-column> <el-table-column label="操作" width="200px" fixed="right"> <template #default="scope"> <el-button type="primary" link @click="handleDetail(scope.row)" v-hasPermi="['clue:pool:detail']" > 详情 </el-button> <template v-if="queryType != 4"> <el-button type="primary" link @click="handleEdit(scope.row)" v-hasPermi="['clue:pool:update']" > 修改 </el-button> <el-button type="primary" link :disabled="scope.row.state == '成交'" @click="handleSuccess(scope.row)" v-hasPermi="['clue:pool:enroll']" > 登记 </el-button> <el-button type="primary" link :disabled="scope.row.state == '成交'" v-hasPermi="['clue:pool:release']" @click="handleRelease(scope.row.clueId)" > 释放 </el-button> </template> <template v-else> <el-button type="primary" link v-hasPermi="['clue:pool:gain']" @click="handleGain(scope.row.clueId)" > 获取 </el-button> </template> </template> </el-table-column> </SSTable> </template> <DialogClue v-if="!loading" ref="formRef" :userOptions="userOptions" :allUserOptions="allUserOptions" :schema="allSchemas.formSchema" @success="getTableList" /> <DrawerClue v-if="!loading" ref="drawerRef" :schema="allSchemas.detailSchema" @get-list="getTableList" @update="handleEdit" /> <DialogSuccess ref="successRef" :schema="allSchemas.detailSchema" :allUserOptions="allUserOptions" :userOptions="userOptions" @success="getTableList" /> <DialogFollow ref="followRef" @success="getTableList" /> <DialogBatchChangeFollow ref="batchChangeFollowDialog" :userOptions="userOptions" @success="getTableList" /> </div> </template> <script setup name="CluePool"> import { useAppStore } from '@/store/modules/app' import { getSimpleFieldList } from '@/api/clue/clueField' import DialogClue from './Comp/DialogClue.vue' import DrawerClue from './Comp/DrawerClue.vue' import DialogSuccess from './Comp/DialogSuccess.vue' import DialogFollow from './Comp/DialogFollow.vue' import ClueMap from './Comp/ClueMap.vue' import DialogBatchChangeFollow from './Comp/DialogBatchChangeFollow.vue' import { getSimpleUserList as getUserOption, getAllUserList } from '@/api/system/user' import { removeNullField } from '@/utils' import { formatDate } from '@/utils/formatTime' import * as ClueApi from '@/api/clue' const message = useMessage() // 消息弹窗 const appStore = useAppStore() const searchRef = ref() const queryType = ref('2') const formRef = ref() const drawerRef = ref() const successRef = ref() const followRef = ref() const loading = ref(true) const allSchemas = ref({}) async function getCurdSchemas() { loading.value = true try { const data = await getSimpleFieldList() data.forEach((elem) => { if (['followUser', 'convertPeople', 'firstFollowUser'].includes(elem.field)) { elem.search.options = userOptions.value } }) allSchemas.value = useCrudSchemas(data).allSchemas } finally { loading.value = false nextTick(() => { getTableList() }) } } const tableObject = ref({ tableList: [], loading: false, total: 1, pageSize: 20, pageNo: 1 }) const showColumns = ref([]) // 初始化表格 function getCheckedColumns(list) { showColumns.value = list && list.length ? list : allSchemas.value.tableColumns } const mapClue = ref() function quickChange(name) { try { if (name != '5') { resetQuery() mapClue.value && mapClue.value.destroyMap() } } catch (error) { console.log(error) } } function resetQuery() { nextTick(() => { searchRef.value && searchRef.value.reset() tableObject.value.pageNo = 1 getTableList() }) } async function getTableList() { // 查询 tableObject.value.loading = true getSearchCount() try { const queryParams = await searchRef.value.getFormModel() const params = { ...queryParams, pageNo: tableObject.value.pageNo, pageSize: tableObject.value.pageSize, queryType: queryType.value } const data = await ClueApi.getCluePage(removeNullField(params)) tableObject.value.tableList = data.list.map((it) => ({ ...it, ...it.diyParams })) tableObject.value.total = data.total } finally { tableObject.value.loading = false } } const clueCount = ref({ unSignNum: 0, followNum: 0, newNum: 0 }) function getSearchCount() { ClueApi.getClueCount().then((data) => { clueCount.value = data }) } const batchIds = ref([]) function handleSelectionChange(val) { batchIds.value = val.map((it) => it.clueId) } const batchChangeFollowDialog = ref() function handleBatchChangeFollow() { if (batchIds.value.length) { batchChangeFollowDialog.value.open(batchIds.value) } else { message.info('请选择表格中的数据!') } } // 新增 function handleInsert() { formRef.value.open('create', null) } // 编辑 function handleEdit(row) { formRef.value.open('update', row.clueId) } // 详情 function handleDetail(row) { drawerRef.value.open(row.clueId) } function handleFollow(row) { followRef.value.open(row.clueId, row.intentionState) } async function makeCall(phone) { console.log('打电话:' + phone) } // 登记 function handleSuccess(row) { successRef.value.open(row.clueId) } // 释放 function handleRelease(id) { message.prompt('请先输入释放原因', '是否确认释放线索?').then((res) => { if (res.value) { try { ClueApi.releaseClue({ clueId: id, publicClue: true, discardReason: res.value }).then(() => { message.success('释放成功') }) } finally { getTableList() } } else { message.info('请将释放原因填写完整!') } }) } function handleGain(id) { message.confirm('是否确认获取公海线索?').then(() => { try { ClueApi.getPublicClue({ clueId: id, publicClue: false }).then(() => { message.success('获取成功') }) } finally { getTableList() } }) } const userOptions = ref([]) const allUserOptions = ref([]) onMounted(async () => { userOptions.value = await getUserOption() allUserOptions.value = await getAllUserList() getCurdSchemas() }) </script> <style lang="scss" scoped></style>