📖 CRM:线索 clue 新增/修改的完善

This commit is contained in:
YunaiV 2024-02-19 19:02:03 +08:00
parent e7bb17dc4e
commit 1047c5b097
11 changed files with 201 additions and 80 deletions

View File

@ -2,22 +2,33 @@ import request from '@/config/axios'
import { TransferReqVO } from '@/api/crm/customer' import { TransferReqVO } from '@/api/crm/customer'
export interface ClueVO { export interface ClueVO {
id: number id: number // 编号
transformStatus: boolean name: string // 线索名称
followUpStatus: boolean followUpStatus: boolean // 跟进状态
name: string contactLastTime: Date // 最后跟进时间
customerId: number contactLastContent: string // 最后跟进内容
contactNextTime: Date contactNextTime: Date // 下次联系时间
telephone: string ownerUserId: number // 负责人的用户编号
mobile: string ownerUserName?: string // 负责人的用户名称
address: string ownerUserDept?: string // 负责人的部门名称
ownerUserId: number transformStatus: boolean // 转化状态
contactLastTime: Date customerId: number // 客户编号
remark: string customerName?: string // 客户名称
mobile: string // 手机号
telephone: string // 电话
qq: string // QQ
wechat: string // wechat
email: string // email
areaId: number // 所在地
detailAddress: string // 详细地址
industryId: number // 所属行业
level: number // 客户等级
source: number // 客户来源
remark: string // 备注
} }
// 查询线索列表 // 查询线索列表
export const getCluePage = async (params) => { export const getCluePage = async (params: any) => {
return await request.get({ url: `/crm/clue/page`, params }) return await request.get({ url: `/crm/clue/page`, params })
} }

View File

@ -51,7 +51,7 @@
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="客户级" prop="level" width="120"> <el-table-column align="center" label="客户" prop="level" width="120">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>

View File

@ -49,7 +49,7 @@
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="客户级" prop="level" width="120"> <el-table-column align="center" label="客户" prop="level" width="120">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>

View File

@ -63,7 +63,7 @@
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="客户级" prop="level" width="120"> <el-table-column align="center" label="客户" prop="level" width="120">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>

View File

@ -36,7 +36,7 @@
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户级" align="center" prop="level" width="120"> <el-table-column label="客户" align="center" prop="level" width="120">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>

View File

@ -1,74 +1,178 @@
<template> <template>
<Dialog :title="dialogTitle" v-model="dialogVisible"> <Dialog v-model="dialogVisible" :title="dialogTitle">
<el-form <el-form
ref="formRef" ref="formRef"
v-loading="formLoading"
:model="formData" :model="formData"
:rules="formRules" :rules="formRules"
label-width="100px" label-width="100px"
v-loading="formLoading"
> >
<el-form-item label="线索名称" prop="name"> <el-row>
<el-input v-model="formData.name" placeholder="请输入线索名称" /> <el-col :span="12">
</el-form-item> <el-form-item label="线索名称" prop="name">
<el-form-item label="下次联系时间" prop="contactNextTime"> <el-input v-model="formData.name" placeholder="请输入线索名称" />
<el-date-picker </el-form-item>
v-model="formData.contactNextTime" </el-col>
type="date" <el-col :span="12">
value-format="x" <el-form-item label="客户来源" prop="source">
placeholder="选择下次联系时间" <el-select v-model="formData.source" placeholder="请选择客户来源" class="w-1/1">
/> <el-option
</el-form-item> v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
<el-form-item label="电话" prop="telephone"> :key="dict.value"
<el-input v-model="formData.telephone" placeholder="请输入电话" /> :label="dict.label"
</el-form-item> :value="dict.value"
<el-form-item label="手机号" prop="mobile"> />
<el-input v-model="formData.mobile" placeholder="请输入手机号" /> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="地址" prop="address"> </el-col>
<el-input v-model="formData.address" placeholder="请输入地址" /> </el-row>
</el-form-item> <el-row>
<el-form-item v-if="formType === 'create'" label="负责人" prop="userIds" span="24"> <el-col :span="12">
<el-select v-model="formData.ownerUserId"> <el-form-item label="手机" prop="mobile">
<el-option <el-input v-model="formData.mobile" placeholder="请输入手机" />
v-for="item in userOptions" </el-form-item>
:key="item.id" </el-col>
:label="item.nickname" <el-col :span="12">
:value="item.id" <el-form-item label="负责人" prop="ownerUserId">
/> <el-select
</el-select> v-model="formData.ownerUserId"
</el-form-item> :disabled="formType !== 'create'"
<el-form-item label="备注" prop="remark"> class="w-1/1"
<el-input v-model="formData.remark" placeholder="请输入备注" /> >
</el-form-item> <el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="电话" prop="telephone">
<el-input v-model="formData.telephone" placeholder="请输入电话" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱" />
</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="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="industryId">
<el-select v-model="formData.industryId" placeholder="请选择客户行业" class="w-1/1">
<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-col>
<el-col :span="12">
<el-form-item label="客户级别" prop="level">
<el-select v-model="formData.level" placeholder="请选择客户级别" class="w-1/1">
<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-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"
class="w-1/1"
/>
</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-col :span="12">
<el-form-item label="下次联系时间" prop="contactNextTime">
<el-date-picker
v-model="formData.contactNextTime"
placeholder="选择下次联系时间"
type="datetime"
value-format="x"
/>
</el-form-item>
</el-col>
</el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button :disabled="formLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false"> </el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
<script setup lang="ts"> <script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as ClueApi from '@/api/crm/clue' import * as ClueApi from '@/api/crm/clue'
import {CACHE_KEY, useCache} from "@/hooks/web/useCache"; import * as AreaApi from '@/api/system/area'
import * as UserApi from "@/api/system/user"; import { defaultProps } from '@/utils/tree'
import * as UserApi from '@/api/system/user'
import { useUserStore } from '@/store/modules/user'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
const dialogVisible = ref(false) // const dialogVisible = ref(false) //
const dialogTitle = ref('') // const dialogTitle = ref('') //
const formLoading = ref(false) // 12 const formLoading = ref(false) // 12
const formType = ref('') // create - update - const formType = ref('') // create - update -
const areaList = ref([]) //
const userOptions = ref<UserApi.UserVO[]>([]) // const userOptions = ref<UserApi.UserVO[]>([]) //
const formData = ref({ const formData = ref({
id: undefined, id: undefined,
name: undefined, name: undefined,
contactNextTime: undefined, contactNextTime: undefined,
telephone: undefined, ownerUserId: 0,
mobile: undefined, mobile: undefined,
address: undefined, telephone: undefined,
ownerUserId: undefined, qq: undefined,
contactLastTime: undefined, wechat: undefined,
email: undefined,
areaId: undefined,
detailAddress: undefined,
industryId: undefined,
level: undefined,
source: undefined,
remark: undefined remark: undefined
}) })
const formRules = reactive({ const formRules = reactive({
@ -92,13 +196,13 @@ const open = async (type: string, id?: number) => {
formLoading.value = false formLoading.value = false
} }
} }
//
areaList.value = await AreaApi.getAreaTree()
// //
userOptions.value = await UserApi.getSimpleUserList() userOptions.value = await UserApi.getSimpleUserList()
// //
if (formType.value === 'create') { if (formType.value === 'create') {
const { wsCache } = useCache() formData.value.ownerUserId = useUserStore().getUser.id
const user = wsCache.get(CACHE_KEY.USER).user
formData.value.ownerUserId = user.id
} }
} }
defineExpose({ open }) // open defineExpose({ open }) // open
@ -135,11 +239,17 @@ const resetForm = () => {
id: undefined, id: undefined,
name: undefined, name: undefined,
contactNextTime: undefined, contactNextTime: undefined,
telephone: undefined, ownerUserId: 0,
mobile: undefined, mobile: undefined,
address: undefined, telephone: undefined,
ownerUserId: undefined, qq: undefined,
contactLastTime: undefined, wechat: undefined,
email: undefined,
areaId: undefined,
detailAddress: undefined,
industryId: undefined,
level: undefined,
source: undefined,
remark: undefined remark: undefined
} }
formRef.value?.resetFields() formRef.value?.resetFields()

View File

@ -67,13 +67,13 @@
<el-table-column label="手机号" align="center" prop="mobile" width="120" /> <el-table-column label="手机号" align="center" prop="mobile" width="120" />
<el-table-column label="电话" align="center" prop="telephone" width="130" /> <el-table-column label="电话" align="center" prop="telephone" width="130" />
<el-table-column label="邮箱" align="center" prop="email" width="180" /> <el-table-column label="邮箱" align="center" prop="email" width="180" />
<el-table-column label="地址" align="center" prop="address" width="180" /> <el-table-column label="地址" align="center" prop="detailAddress" width="180" />
<el-table-column align="center" label="客户行业" prop="industryId" width="100"> <el-table-column align="center" label="客户行业" prop="industryId" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="客户级" prop="level" width="130"> <el-table-column align="center" label="客户" prop="level" width="135">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>

View File

@ -40,8 +40,8 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="客户级" prop="level"> <el-form-item label="客户" prop="level">
<el-select v-model="formData.level" placeholder="请选择客户级"> <el-select v-model="formData.level" placeholder="请选择客户">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
:key="dict.value" :key="dict.value"

View File

@ -15,7 +15,7 @@
<el-descriptions-item label="客户来源"> <el-descriptions-item label="客户来源">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="customer.source" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="customer.source" />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="客户级"> <el-descriptions-item label="客户">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="手机">{{ customer.mobile }}</el-descriptions-item> <el-descriptions-item label="手机">{{ customer.mobile }}</el-descriptions-item>

View File

@ -41,12 +41,12 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="客户级" prop="level"> <el-form-item label="客户" prop="level">
<el-select <el-select
v-model="queryParams.level" v-model="queryParams.level"
class="!w-240px" class="!w-240px"
clearable clearable
placeholder="请选择客户级" placeholder="请选择客户"
> >
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
@ -130,7 +130,7 @@
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="客户级" prop="level" width="130"> <el-table-column align="center" label="客户" prop="level" width="130">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>

View File

@ -41,12 +41,12 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="客户级" prop="level"> <el-form-item label="客户" prop="level">
<el-select <el-select
v-model="queryParams.level" v-model="queryParams.level"
class="!w-240px" class="!w-240px"
clearable clearable
placeholder="请选择客户级" placeholder="请选择客户"
> >
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
@ -117,7 +117,7 @@
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="客户级" prop="level" width="120"> <el-table-column align="center" label="客户" prop="level" width="120">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template> </template>