230 lines
7.6 KiB
Vue
230 lines
7.6 KiB
Vue
<template>
|
|
<el-dialog
|
|
title="选择客户"
|
|
v-model="dialogVisible"
|
|
width="1280px"
|
|
align-center
|
|
class="dialog-form-layout"
|
|
modal-class="order-module-dialog-mask"
|
|
:close-on-click-modal="false"
|
|
append-to-body
|
|
>
|
|
<!-- 查询表单 -->
|
|
<el-form :model="queryParams" ref="queryFormRef" :inline="true" class="mb-3 search-form-inline">
|
|
<el-form-item label="客户名称" prop="customerName">
|
|
<el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable @keyup.enter="handleQuery" style="width: 180px" />
|
|
</el-form-item>
|
|
<el-form-item label="客户编号" prop="customerNo">
|
|
<el-input v-model="queryParams.customerNo" placeholder="请输入客户编号" clearable @keyup.enter="handleQuery" style="width: 150px" />
|
|
</el-form-item>
|
|
<el-form-item label="客户类型" prop="customerType">
|
|
<el-select v-model="queryParams.customerType" placeholder="请选择客户类型" clearable style="width: 150px">
|
|
<el-option v-for="dict in dictStore.getOptions('crm_customer_type')" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="手机号码" prop="mobile">
|
|
<el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery" style="width: 150px" />
|
|
</el-form-item>
|
|
<el-form-item class="form-buttons-right">
|
|
<el-button type="primary" :loading="loading" @click="handleQuery">
|
|
<el-icon><Search /></el-icon>搜索
|
|
</el-button>
|
|
<el-button :loading="loading" @click="resetQuery">
|
|
<el-icon><Refresh /></el-icon>重置
|
|
</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<!-- 客户列表 -->
|
|
<el-table v-loading="loading" :data="customerList" @current-change="handleCurrentChange" :max-height="400" border highlight-current-row>
|
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
<el-table-column label="客户名称" prop="customerName" min-width="230" :show-overflow-tooltip="true" />
|
|
<el-table-column label="客户类型" prop="customerType" width="150" align="center">
|
|
<template #default="scope">
|
|
<DictTag dict-type="crm_customer_type" :value="scope.row.customerType" />
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="所属行业" prop="industry" width="120" :show-overflow-tooltip="true">
|
|
<template #default="scope">
|
|
<DictTag dict-type="crm_customer_industry" :value="scope.row.industry" />
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="客户级别" prop="level" width="100" align="center">
|
|
<template #default="scope">
|
|
<DictTag dict-type="crm_customer_level" :value="scope.row.level" />
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="联系人" prop="contactName" width="100" :show-overflow-tooltip="true" />
|
|
<el-table-column label="手机号码" prop="mobile" width="120" />
|
|
<el-table-column label="地区" prop="province" width="120">
|
|
<template #default="scope">
|
|
<span>{{ scope.row.province }} {{ scope.row.city }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="负责人" prop="ownerUserName" width="100" :show-overflow-tooltip="true" />
|
|
</el-table>
|
|
|
|
<!-- 分页 -->
|
|
<ListPagination
|
|
v-show="total > 0"
|
|
:total="total"
|
|
v-model:page="queryParams.pageNum"
|
|
v-model:limit="queryParams.pageSize"
|
|
@pagination="getList"
|
|
class="mt-3"
|
|
/>
|
|
|
|
<!-- 当前选中客户 -->
|
|
<template v-if="currentCustomer">
|
|
<el-divider content-position="left">当前选中客户</el-divider>
|
|
<div class="selected-customer">
|
|
<el-descriptions :column="2" border>
|
|
<el-descriptions-item label="客户名称">{{ currentCustomer.customerName }}</el-descriptions-item>
|
|
<el-descriptions-item label="客户类型">
|
|
<DictTag dict-type="crm_customer_type" :value="currentCustomer.customerType" />
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="客户级别">
|
|
<DictTag dict-type="crm_customer_level" :value="currentCustomer.level" />
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="所属行业">
|
|
<DictTag dict-type="crm_customer_industry" :value="currentCustomer.industry" />
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="联系人">{{ currentCustomer.contactName || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="手机号码">{{ currentCustomer.mobile || '-' }}</el-descriptions-item>
|
|
</el-descriptions>
|
|
</div>
|
|
</template>
|
|
|
|
<template #footer>
|
|
<div class="dialog-footer">
|
|
<el-button class="btn-ghost" @click="handleClose">
|
|
<el-icon><Close /></el-icon>取消
|
|
</el-button>
|
|
<el-button class="btn-main" type="primary" @click="handleConfirm" :disabled="!currentCustomer">
|
|
<el-icon><Check /></el-icon>确定
|
|
</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts" name="CustomerSelector">
|
|
import { useDictStore } from '@/store/modules/dict'
|
|
import DictTag from '@/components/DictTag/index.vue'
|
|
import ListPagination from '@/components/ListPagination/index.vue'
|
|
import { Check, Close, Refresh, Search } from '@element-plus/icons-vue'
|
|
import { ref, watch } from 'vue'
|
|
import type { ElFormInstance } from 'element-plus'
|
|
import { fetchCustomerList } from '@/api/crm/customer'
|
|
|
|
const dictStore = useDictStore()
|
|
|
|
interface Props {
|
|
visible: boolean
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
const emit = defineEmits(['update:visible', 'confirm'])
|
|
|
|
const dialogVisible = ref(false)
|
|
|
|
watch(
|
|
() => props.visible,
|
|
async (val) => {
|
|
dialogVisible.value = val
|
|
if (val) {
|
|
await dictStore.loadAllDict()
|
|
getList()
|
|
}
|
|
}
|
|
)
|
|
|
|
watch(dialogVisible, (val) => {
|
|
emit('update:visible', val)
|
|
})
|
|
|
|
const queryParams = ref<Record<string, any>>({
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
customerName: undefined,
|
|
customerNo: undefined,
|
|
customerType: undefined,
|
|
mobile: undefined
|
|
})
|
|
|
|
const customerList = ref<any[]>([])
|
|
const loading = ref(false)
|
|
const total = ref(0)
|
|
const currentCustomer = ref<any | null>(null)
|
|
const queryFormRef = ref<ElFormInstance>()
|
|
|
|
const getList = async () => {
|
|
loading.value = true
|
|
try {
|
|
const res = await fetchCustomerList({
|
|
page: queryParams.value.pageNum,
|
|
pageSize: queryParams.value.pageSize,
|
|
customerName: queryParams.value.customerName,
|
|
customerNo: queryParams.value.customerNo,
|
|
customerType: queryParams.value.customerType,
|
|
mobile: queryParams.value.mobile
|
|
})
|
|
customerList.value = res.list || res.rows || []
|
|
total.value = res.total ?? 0
|
|
} catch (error) {
|
|
console.error('获取客户列表失败:', error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const handleQuery = () => {
|
|
queryParams.value.pageNum = 1
|
|
getList()
|
|
}
|
|
|
|
const resetQuery = () => {
|
|
queryFormRef.value?.resetFields()
|
|
handleQuery()
|
|
}
|
|
|
|
const handleCurrentChange = (row: any) => {
|
|
currentCustomer.value = row
|
|
}
|
|
|
|
const handleConfirm = () => {
|
|
emit('confirm', currentCustomer.value)
|
|
handleClose()
|
|
}
|
|
|
|
const handleClose = () => {
|
|
currentCustomer.value = null
|
|
dialogVisible.value = false
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.selected-customer {
|
|
padding: 10px;
|
|
background-color: #f5f7fa;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.mb-3 {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.mt-3 {
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.search-form-inline {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.form-buttons-right {
|
|
margin-left: auto !important;
|
|
}
|
|
</style>
|