diff --git a/src/api/crm/customer/index.ts b/src/api/crm/customer/index.ts index 0cbba590..59260cbc 100644 --- a/src/api/crm/customer/index.ts +++ b/src/api/crm/customer/index.ts @@ -1,13 +1,14 @@ import request from '@/config/axios' export interface CustomerVO { - id: number + id?: number name: string industryId: number level: number source: number - followUpStatus: boolean - lockStatus: boolean + followUpStatus?: boolean + lockStatus?: boolean + dealStatus?: boolean mobile: string telephone: string website: string @@ -16,13 +17,20 @@ export interface CustomerVO { email: string description: string remark: string - ownerUserId: number - roUserIds: string - rwUserIds: string - areaId: number + ownerUserId?: number + ownerUserName?: string + ownerUserDept?: string + roUserIds?: string + rwUserIds?: string + areaId?: number + areaName?: string detailAddress: string - contactLastTime: Date + contactLastTime?: Date contactNextTime: Date + createTime?: Date + updateTime?: Date + creator?: string + creatorName?: string } // 查询客户列表 diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 70dc5b2f..58eb1733 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -487,6 +487,24 @@ const remainingRouter: AppRouteRecordRaw[] = [ component: () => import('@/views/mall/promotion/diy/page/decorate.vue') } ] + }, + { + path: '/crm', + component: Layout, + name: 'CrmCenter', + meta: { hidden: true }, + children: [ + { + path: 'customer/detail/:id', + name: 'CrmCustomerDetail', + meta: { + title: '客户详情', + noCache: true, + hidden: true + }, + component: () => import('@/views/crm/customer/detail/index.vue') + } + ] } ] diff --git a/src/views/crm/clue/ClueForm.vue b/src/views/crm/clue/ClueForm.vue index 877b26d9..4321f952 100644 --- a/src/views/crm/clue/ClueForm.vue +++ b/src/views/crm/clue/ClueForm.vue @@ -10,7 +10,7 @@ <el-form-item label="线索名称" prop="name"> <el-input v-model="formData.name" placeholder="请输入线索名称" /> </el-form-item> - <!-- TODO 客户选择 --> + <!-- TODO wanwan 客户选择 --> <el-form-item label="客户" prop="customerId"> <el-input v-model="formData.customerId" placeholder="请选择客户" /> </el-form-item> @@ -31,7 +31,7 @@ <el-form-item label="地址" prop="address"> <el-input v-model="formData.address" placeholder="请输入地址" /> </el-form-item> - <!-- TODO 负责人选择 --> + <!-- TODO wanwan 负责人选择 --> <el-form-item label="负责人" prop="ownerUserId"> <el-input v-model="formData.ownerUserId" placeholder="请输入负责人" /> </el-form-item> @@ -46,7 +46,6 @@ </Dialog> </template> <script setup lang="ts"> -import { DICT_TYPE, getBoolDictOptions } from '@/utils/dict' import * as ClueApi from '@/api/crm/clue' const { t } = useI18n() // 国际化 diff --git a/src/views/crm/clue/index.vue b/src/views/crm/clue/index.vue index e866a725..cf742276 100644 --- a/src/views/crm/clue/index.vue +++ b/src/views/crm/clue/index.vue @@ -96,7 +96,7 @@ :formatter="dateFormatter" width="180px" /> - <el-table-column label="操作" align="center"> + <el-table-column label="操作" align="center" min-width="110" fixed="right"> <template #default="scope"> <el-button link diff --git a/src/views/crm/customer/CustomerForm.vue b/src/views/crm/customer/CustomerForm.vue index 6e5cd62e..99f7e858 100644 --- a/src/views/crm/customer/CustomerForm.vue +++ b/src/views/crm/customer/CustomerForm.vue @@ -8,93 +8,135 @@ v-loading="formLoading" > <el-row> - <!-- TODO @wanwan:name 参数校验,必填 --> - <el-form-item label="客户名称" prop="name"> - <el-input v-model="formData.name" placeholder="请输入客户名称" /> - </el-form-item> - <el-form-item label="所属行业" prop="industryId"> - <el-select v-model="formData.industryId" placeholder="请选择所属行业"> - <el-option - v-for="dict in getStrDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)" - :key="dict.value" - :label="dict.label" - :value="dict.value" + <el-col :span="12"> + <el-form-item label="客户名称" prop="name"> + <el-input v-model="formData.name" placeholder="请输入客户名称" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="所属行业" prop="industryId"> + <el-select v-model="formData.industryId" placeholder="请选择所属行业"> + <el-option + v-for="dict in getStrDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="客户来源" prop="source"> + <el-select v-model="formData.source" placeholder="请选择客户来源"> + <el-option + v-for="dict in getStrDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="客户等级" prop="level"> + <el-select v-model="formData.level" placeholder="请选择客户等级"> + <el-option + v-for="dict in getStrDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="手机" prop="mobile"> + <el-input v-model="formData.mobile" placeholder="请输入手机" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="电话" prop="telephone"> + <el-input v-model="formData.telephone" placeholder="请输入电话" /> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="邮箱" prop="email"> + <el-input v-model="formData.email" placeholder="请输入邮箱" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="QQ" prop="qq"> + <el-input v-model="formData.qq" placeholder="请输入QQ" /> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="微信" prop="wechat"> + <el-input v-model="formData.wechat" placeholder="请输入微信" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="网址" prop="website"> + <el-input v-model="formData.website" placeholder="请输入网址" /> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="所在地" prop="areaId"> + <el-tree-select + v-model="formData.areaId" + :data="areaList" + :props="defaultProps" + :render-after-expand="true" /> - </el-select> - </el-form-item> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="详细地址" prop="detailAddress"> + <el-input v-model="formData.detailAddress" placeholder="请输入详细地址" /> + </el-form-item> + </el-col> </el-row> - <el-row> - <el-form-item label="客户来源" prop="source"> - <el-select v-model="formData.source" placeholder="请选择客户来源"> - <el-option - v-for="dict in getStrDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)" - :key="dict.value" - :label="dict.label" - :value="dict.value" - /> - </el-select> - </el-form-item> - <el-form-item label="客户等级" prop="level"> - <el-select v-model="formData.level" placeholder="请选择客户等级"> - <el-option - v-for="dict in getStrDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" - :key="dict.value" - :label="dict.label" - :value="dict.value" - /> - </el-select> - </el-form-item> - </el-row> - <el-row> - <el-form-item label="手机" prop="mobile"> - <el-input v-model="formData.mobile" placeholder="请输入手机" /> - </el-form-item> - <el-form-item label="电话" prop="telephone"> - <el-input v-model="formData.telephone" placeholder="请输入电话" /> - </el-form-item> - </el-row> - <el-row> - <el-form-item label="邮箱" prop="email"> - <el-input v-model="formData.email" placeholder="请输入邮箱" /> - </el-form-item> - <el-form-item label="QQ" prop="qq"> - <el-input v-model="formData.qq" placeholder="请输入QQ" /> - </el-form-item> - </el-row> - <el-row> - <el-form-item label="微信" prop="wechat"> - <el-input v-model="formData.wechat" placeholder="请输入微信" /> - </el-form-item> - <el-form-item label="网址" prop="website"> - <el-input v-model="formData.website" placeholder="请输入网址" /> - </el-form-item> - </el-row> - <el-row> - <!-- TODO @wanwan:地区的多级选择,可以参考 UserForm.vue 的 所在地 areaId --> - <el-form-item label="地区编号" prop="areaId"> - <el-input v-model="formData.areaId" placeholder="请输入地区编号" /> - </el-form-item> - <el-form-item label="详细地址" prop="detailAddress"> - <el-input v-model="formData.detailAddress" placeholder="请输入详细地址" /> - </el-form-item> - </el-row> - <!-- TODO @wanwan: 少一个负责人字段,默认先选中自己;可以先参考 TaskAssignRuleForm.vue 的 formData.userIds;注意,新增的时候,可以选择;修改的时候,只展示 --> - <el-row> - <el-form-item label="下次联系时间" prop="contactNextTime"> - <el-date-picker - v-model="formData.contactNextTime" - type="date" - value-format="x" - placeholder="选择下次联系时间" + <el-form-item v-if="formType === 'create'" label="负责人" prop="userIds" span="24"> + <el-select v-model="formData.ownerUserId"> + <el-option + v-for="item in userOptions" + :key="parseInt(item.id)" + :label="item.nickname" + :value="parseInt(item.id)" /> - </el-form-item> + </el-select> + </el-form-item> + <el-row> + <el-col :span="12"> + <el-form-item label="下次联系时间" prop="contactNextTime"> + <el-date-picker + v-model="formData.contactNextTime" + type="date" + value-format="x" + placeholder="选择下次联系时间" + /> + </el-form-item> + </el-col> </el-row> - <el-form-item label="客户描述" prop="description"> - <el-input v-model="formData.description" placeholder="请输入客户描述" /> - </el-form-item> - <el-form-item label="备注" prop="remark"> - <el-input v-model="formData.remark" placeholder="请输入备注" /> - </el-form-item> + <el-col :span="24"> + <el-form-item label="客户描述" prop="description"> + <el-input v-model="formData.description" placeholder="请输入客户描述" /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="备注" prop="remark"> + <el-input v-model="formData.remark" placeholder="请输入备注" /> + </el-form-item> + </el-col> </el-form> <template #footer> <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> @@ -105,6 +147,10 @@ <script setup lang="ts"> import { DICT_TYPE, getStrDictOptions } from '@/utils/dict' import * as CustomerApi from '@/api/crm/customer' +import * as AreaApi from '@/api/system/area' +import { defaultProps } from '@/utils/tree' +import * as UserApi from '@/api/system/user' +import { CACHE_KEY, useCache } from '@/hooks/web/useCache' const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 @@ -113,6 +159,8 @@ const dialogVisible = ref(false) // 弹窗的是否展示 const dialogTitle = ref('') // 弹窗的标题 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 const formType = ref('') // 表单的类型:create - 新增;update - 修改 +const areaList = ref([]) // 地区列表 +const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表 const formData = ref({ id: undefined, name: undefined, @@ -129,10 +177,12 @@ const formData = ref({ remark: undefined, areaId: undefined, detailAddress: undefined, - contactNextTime: undefined + contactNextTime: undefined, + ownerUserId: undefined }) const formRules = reactive({ - name: [{ require: true, message: '客户名称不能为空', trigger: 'blur' }] + name: [{ required: true, message: '客户名称不能为空', trigger: 'blur' }], + ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }] }) const formRef = ref() // 表单 Ref @@ -151,6 +201,16 @@ const open = async (type: string, id?: number) => { formLoading.value = false } } + // 获得地区列表 + areaList.value = await AreaApi.getAreaTree() + // 获得用户列表 + userOptions.value = await UserApi.getSimpleUserList() + // 默认新建时选中自己 + if (formType.value === 'create') { + const { wsCache } = useCache() + const user = wsCache.get(CACHE_KEY.USER).user + formData.value.ownerUserId = user.id + } } defineExpose({ open }) // 提供 open 方法,用于打开弹窗 @@ -198,7 +258,8 @@ const resetForm = () => { remark: undefined, areaId: undefined, detailAddress: undefined, - contactNextTime: undefined + contactNextTime: undefined, + ownerUserId: undefined } formRef.value?.resetFields() } diff --git a/src/views/crm/customer/detail/CustomerBasicInfo.vue b/src/views/crm/customer/detail/CustomerBasicInfo.vue new file mode 100644 index 00000000..0329db8f --- /dev/null +++ b/src/views/crm/customer/detail/CustomerBasicInfo.vue @@ -0,0 +1,18 @@ +<template> + <el-col> 客户 </el-col> + <el-col> + <el-row> + <span class="text-xl font-bold">{{ customer.name }}</span> + </el-row> + </el-col> + <el-col class="mt-10px"> + <Icon icon="ant-design:tag-filled" /> + <!-- TODO 标签 --> + </el-col> +</template> +<script setup lang="ts"> +import * as CustomerApi from '@/api/crm/customer' + +const { customer } = defineProps<{ customer: CustomerApi.CustomerVO }>() +</script> +<style scoped lang="scss"></style> diff --git a/src/views/crm/customer/detail/CustomerDetails.vue b/src/views/crm/customer/detail/CustomerDetails.vue new file mode 100644 index 00000000..f6215224 --- /dev/null +++ b/src/views/crm/customer/detail/CustomerDetails.vue @@ -0,0 +1,91 @@ +<template> + <el-collapse v-model="activeNames"> + <el-collapse-item name="basicInfo"> + <template #title> + <span class="text-base font-bold">基本信息</span> + </template> + <el-descriptions :column="2"> + <el-descriptions-item label="客户名称"> + {{ customer.name }} + </el-descriptions-item> + <el-descriptions-item label="所属行业"> + <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="customer.industryId" /> + </el-descriptions-item> + <el-descriptions-item label="客户来源"> + <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="customer.source" /> + </el-descriptions-item> + <el-descriptions-item label="客户等级"> + <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" /> + </el-descriptions-item> + <el-descriptions-item label="手机"> + {{ customer.mobile }} + </el-descriptions-item> + <el-descriptions-item label="电话"> + {{ customer.telephone }} + </el-descriptions-item> + <el-descriptions-item label="邮箱"> + {{ customer.email }} + </el-descriptions-item> + <el-descriptions-item label="QQ"> + {{ customer.qq }} + </el-descriptions-item> + <el-descriptions-item label="微信"> + {{ customer.wechat }} + </el-descriptions-item> + <el-descriptions-item label="网址"> + {{ customer.website }} + </el-descriptions-item> + <el-descriptions-item label="所在地"> + {{ customer.areaName }} + </el-descriptions-item> + <el-descriptions-item label="详细地址"> + {{ customer.detailAddress }} + </el-descriptions-item> + <el-descriptions-item label="下次联系时间"> + {{ customer.contactNextTime ? formatDate(customer.contactNextTime, 'YYYY-MM-DD') : '空' }} + </el-descriptions-item> + </el-descriptions> + <el-descriptions :column="1"> + <el-descriptions-item label="客户描述"> + {{ customer.description }} + </el-descriptions-item> + <el-descriptions-item label="备注"> + {{ customer.remark }} + </el-descriptions-item> + </el-descriptions> + </el-collapse-item> + <el-collapse-item name="systemInfo"> + <template #title> + <span class="text-base font-bold">系统信息</span> + </template> + <el-descriptions :column="2"> + <el-descriptions-item label="负责人"> + {{ customer.ownerUserName }} + </el-descriptions-item> + <el-descriptions-item label="创建人"> + {{ customer.creatorName }} + </el-descriptions-item> + <el-descriptions-item label="创建时间"> + {{ customer.createTime ? formatDate(customer.createTime) : '空' }} + </el-descriptions-item> + <el-descriptions-item label="更新时间"> + {{ customer.updateTime ? formatDate(customer.updateTime) : '空' }} + </el-descriptions-item> + <el-descriptions-item label="最后跟进时间"> + {{ customer.contactLastTime ? formatDate(customer.contactLastTime) : '空' }} + </el-descriptions-item> + </el-descriptions> + </el-collapse-item> + </el-collapse> +</template> +<script setup lang="ts"> +import * as CustomerApi from '@/api/crm/customer' +import { DICT_TYPE } from '@/utils/dict' +import { formatDate } from '@/utils/formatTime' + +const { customer } = defineProps<{ customer: CustomerApi.CustomerVO }>() + +// 展示的折叠面板 +const activeNames = ref(['basicInfo', 'systemInfo']) +</script> +<style scoped lang="scss"></style> diff --git a/src/views/crm/customer/detail/index.vue b/src/views/crm/customer/detail/index.vue new file mode 100644 index 00000000..e5c8ef43 --- /dev/null +++ b/src/views/crm/customer/detail/index.vue @@ -0,0 +1,154 @@ +<template> + <div v-loading="loading"> + <div class="flex items-start justify-between"> + <div> + <!-- 左上:客户基本信息 --> + <CustomerBasicInfo :customer="customer" /> + </div> + <div> + <!-- 右上:按钮 --> + <el-button @click="openForm('update', customer.id)" v-hasPermi="['crm:customer:update']"> + 编辑 + </el-button> + <el-button>更改成交状态</el-button> + </div> + </div> + <el-row class="mt-10px"> + <el-button> + <Icon icon="ph:calendar-fill" class="mr-5px" /> + 创建任务 + </el-button> + <el-button> + <Icon icon="carbon:email" class="mr-5px" /> + 发送邮件 + </el-button> + <el-button> + <Icon icon="system-uicons:contacts" class="mr-5px" /> + 创建联系人 + </el-button> + <el-button> + <Icon icon="ep:opportunity" class="mr-5px" /> + 创建商机 + </el-button> + <el-button> + <Icon icon="clarity:contract-line" class="mr-5px" /> + 创建合同 + </el-button> + <el-button> + <Icon icon="icon-park:income-one" class="mr-5px" /> + 创建回款 + </el-button> + <el-button> + <Icon icon="fluent:people-team-add-20-filled" class="mr-5px" /> + 添加团队成员 + </el-button> + </el-row> + </div> + <ContentWrap class="mt-10px"> + <el-descriptions :column="5" direction="vertical"> + <el-descriptions-item label="客户级别"> + <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" /> + </el-descriptions-item> + <el-descriptions-item label="成交状态"> + {{ customer.dealStatus ? '已成交' : '未成交' }} + </el-descriptions-item> + <el-descriptions-item label="负责人"> + {{ customer.ownerUserName }} + </el-descriptions-item> + <!-- TODO wanwan 首要联系人? --> + <el-descriptions-item label="首要联系人" /> + <!-- TODO wanwan 首要联系人电话? --> + <el-descriptions-item label="首要联系人电话"> + {{ customer.mobile }} + </el-descriptions-item> + </el-descriptions> + </ContentWrap> + <el-col :span="18"> + <el-tabs> + <el-tab-pane label="详细资料"> + <CustomerDetails class="ml-2" :customer="customer" /> + </el-tab-pane> + <el-tab-pane label="活动" lazy> 活动</el-tab-pane> + <el-tab-pane label="邮件" lazy> 邮件</el-tab-pane> + <el-tab-pane label="工商信息" lazy> 工商信息</el-tab-pane> + <el-tab-pane label="客户关系" lazy> 客户关系</el-tab-pane> + <!-- TODO wanwan 以下标签上的数量需要接口统计返回 --> + <el-tab-pane label="联系人" lazy> + <template #label> 联系人<el-badge :value="12" class="item" type="primary" /> </template> + 联系人 + </el-tab-pane> + <el-tab-pane label="团队成员" lazy> + <template #label> 团队成员<el-badge :value="2" class="item" type="primary" /> </template> + 团队成员 + </el-tab-pane> + <el-tab-pane label="商机" lazy> 商机</el-tab-pane> + <el-tab-pane label="合同" lazy> + <template #label> 合同<el-badge :value="3" class="item" type="primary" /> </template> + 合同 + </el-tab-pane> + <el-tab-pane label="回款" lazy> + <template #label> 回款<el-badge :value="4" class="item" type="primary" /> </template> + 回款 + </el-tab-pane> + <el-tab-pane label="回访" lazy> 回访</el-tab-pane> + <el-tab-pane label="发票" lazy> 发票</el-tab-pane> + </el-tabs> + </el-col> + + <!-- 表单弹窗:添加/修改 --> + <CustomerForm ref="formRef" @success="getCustomerData(id)" /> +</template> + +<script setup lang="ts"> +import { ElMessage } from 'element-plus' +import { useTagsViewStore } from '@/store/modules/tagsView' +import * as CustomerApi from '@/api/crm/customer' +import CustomerBasicInfo from '@/views/crm/customer/detail/CustomerBasicInfo.vue' +import { DICT_TYPE } from '@/utils/dict' +import CustomerDetails from '@/views/crm/customer/detail/CustomerDetails.vue' +import CustomerForm from '@/views/crm/customer/CustomerForm.vue' + +defineOptions({ name: 'CustomerDetail' }) + +const { delView } = useTagsViewStore() // 视图操作 +const route = useRoute() +const { currentRoute } = useRouter() // 路由 +const id = Number(route.params.id) +const loading = ref(true) // 加载中 + +// 客户详情 +const customer = ref<CustomerApi.CustomerVO>({} as CustomerApi.CustomerVO) + +/** + * 获取详情 + * + * @param id + */ +const getCustomerData = async (id: number) => { + loading.value = true + try { + customer.value = await CustomerApi.getCustomer(id) + } finally { + loading.value = false + } +} + +const formRef = ref() +const openForm = (type: string, id?: number) => { + formRef.value.open(type, id) +} + +/** + * 初始化 + */ +onMounted(() => { + if (!id) { + ElMessage.warning('参数错误,客户不能为空!') + delView(unref(currentRoute)) + return + } + getCustomerData(id) +}) +</script> + +<style scoped lang="scss"></style> diff --git a/src/views/crm/customer/index.vue b/src/views/crm/customer/index.vue index ace56dac..073bf8cb 100644 --- a/src/views/crm/customer/index.vue +++ b/src/views/crm/customer/index.vue @@ -1,7 +1,6 @@ <template> <ContentWrap> <!-- 搜索工作栏 --> - <!-- TODO @wanwan:看看怎么表单可以对齐一点; --> <el-form class="-mb-15px" :model="queryParams" @@ -27,7 +26,51 @@ class="!w-240px" /> </el-form-item> - <!-- TODO @wanwan:筛选字段,加所属行业、客户等级、客户来源 --> + <el-form-item label="所属行业" prop="industryId"> + <el-select + v-model="queryParams.industryId" + placeholder="请选择所属行业" + clearable + class="!w-240px" + > + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="客户等级" prop="level"> + <el-select + v-model="queryParams.level" + placeholder="请选择客户等级" + clearable + class="!w-240px" + > + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="客户来源" prop="source"> + <el-select + v-model="queryParams.source" + placeholder="请选择客户来源" + clearable + class="!w-240px" + > + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> <el-form-item> <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> @@ -48,7 +91,6 @@ </ContentWrap> <!-- 列表 --> - <!-- TODO @wanwan:列表,按照 docs 的再改下 --> <ContentWrap> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table-column label="编号" align="center" prop="id" /> @@ -70,8 +112,9 @@ </el-table-column> <el-table-column label="手机" align="center" prop="mobile" width="120" /> <el-table-column label="详细地址" align="center" prop="detailAddress" width="200" /> - <!-- TODO @Wanwan 负责人回显,所属部门,创建人 --> - <el-table-column label="负责人" align="center" prop="ownerUserId" /> + <el-table-column label="负责人" align="center" prop="ownerUserName" /> + <el-table-column label="所属部门" align="center" prop="ownerUserDept" /> + <el-table-column label="创建人" align="center" prop="creatorName" /> <el-table-column label="创建时间" align="center" @@ -104,9 +147,9 @@ </template> </el-table-column> <!-- TODO @wanwan 距进入公海天数 --> - <!-- TODO @wanwan:操作要 fixed 再右侧哈; --> - <el-table-column label="操作" align="center" width="160"> + <el-table-column label="操作" align="center" min-width="150" fixed="right"> <template #default="scope"> + <el-button link type="primary" @click="openDetail(scope.row.id)">详情</el-button> <el-button link type="primary" @@ -140,7 +183,7 @@ </template> <script setup lang="ts"> -import { DICT_TYPE, getBoolDictOptions } from '@/utils/dict' +import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict' import { dateFormatter } from '@/utils/formatTime' import download from '@/utils/download' import * as CustomerApi from '@/api/crm/customer' @@ -158,7 +201,10 @@ const queryParams = reactive({ pageNo: 1, pageSize: 10, name: null, - mobile: null + mobile: null, + industryId: null, + level: null, + source: null }) const queryFormRef = ref() // 搜索的表单 const exportLoading = ref(false) // 导出的加载中 @@ -187,6 +233,12 @@ const resetQuery = () => { handleQuery() } +/** 打开客户详情 */ +const { push } = useRouter() +const openDetail = (id: number) => { + push({ name: 'CrmCustomerDetail', params: { id } }) +} + /** 添加/修改操作 */ const formRef = ref() const openForm = (type: string, id?: number) => {