admin-vue3/src/views/crm/customer/CustomerForm.vue

556 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
<el-form
ref="formRef"
v-loading="formLoading"
:model="formData"
:rules="formRules"
label-width="100px"
>
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="name">
<el-autocomplete
v-model="formData.name"
:fetch-suggestions="querySearchAsync"
:trigger-on-focus="false"
clearable
class="inline-input w-50"
placeholder="请输入客户名称"
@select="handleSelect"
>
<template #default="{ item }">
<div class="value">{{ item.name }}</div>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="拓展人" prop="clueDeveloper">
<el-select
class="w-1/1"
placeholder="请选择拓展人"
v-model="formData.clueDeveloper"
filterable
>
<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="source">
<el-select v-model="formData.source" filterable placeholder="请选择客户来源" class="w-1/1">
<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-col>
<el-col :span="12">
<el-form-item label="公司类型" prop="cooperationType">
<el-select v-model="formData.cooperationType" filterable placeholder="请选择合作类型" class="w-1/1">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_COOPERATION_TYPE)"
: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="maintainer">
<el-select
class="w-1/1"
placeholder="请选择维护人"
v-model="formData.maintainer"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item label="合作地区" prop="cooperationArea">
<el-select v-model="formData.cooperationArea" filterable placeholder="请选择合作地区" class="w-1/1">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_COOPERATION_AREA)"
: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="legalPersonName">
<el-input v-model="formData.legalPersonName" disabled placeholder="" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<!-- <el-col :span="12">
<el-form-item label="负责人" prop="ownerUserId">
<el-select
v-model="formData.ownerUserId"
class="w-1/1"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<!-- <el-col :span="12">-->
<!-- <el-form-item label="协助人" prop="">-->
<!-- <el-select v-model="formData.assist" collapse-tags collapse-tags-tooltip multiple filterable placeholder="请选择协助人" class="w-1/1">-->
<!-- <el-option-->
<!-- v-for="item in userOptions"-->
<!-- :key="item.id"-->
<!-- :label="item.nickname"-->
<!-- :value="item.id"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- <el-col :span="12">-->
<!-- <el-form-item label="线索拓展人" prop="">-->
<!-- <el-select v-model="formData.clueDeveloper" filterable placeholder="请选择线索拓展人" class="w-1/1">-->
<!-- <el-option-->
<!-- v-for="item in userOptions"-->
<!-- :key="item.id"-->
<!-- :label="item.nickname"-->
<!-- :value="item.id"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- <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-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="客户行业" prop="industryId">
<el-select v-model="formData.industryId" placeholder="请选择客户行业" >
<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="请选择客户级别" >
<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-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-col :span="12"> -->
<!-- <el-form-item label="统一信用代码" prop="creditNo">
<el-input v-model="formData.creditNo" disabled placeholder="请输入详细地址" />
</el-form-item>
</el-col> -->
<!-- <el-col :span="12">
<el-form-item label="营业状态" prop="serviceStatus">
<el-input v-model="formData.serviceStatus" disabled placeholder="营业状态" />
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item label="注册资本" prop="registerCapital">
<el-input v-model="formData.registerCapital" disabled placeholder="" />
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item label="网站" prop="">
<el-input v-model="formData.website" placeholder="请输入网站" />
</el-form-item>
</el-col>-->
<!-- <el-col :span="12">
<el-form-item label="所属行业" prop="industryId">
<el-select v-model="formData.industryId" placeholder="所属行业" disabled>
<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="registeredAddress">
<el-select v-model="formData.registeredAddress" placeholder="请选择注册地址" >
<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-col :span="12">
<el-form-item label="注册日期" prop="contactNextTime">
<el-date-picker
disabled
v-model="formData.startDate"
placeholder=""
type="date"
value-format="x"
class="!w-1/1"
/>
</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 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="servicor">
<el-select
class="w-1/1"
placeholder="请选择服务对接人"
v-model="formData.servicor"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术对接人" prop="technicalLead">
<el-select
class="w-1/1"
placeholder="请选择技术对接人"
v-model="formData.technicalLead"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结算对接人" prop="settlementLead">
<el-select
class="w-1/1"
placeholder="请选择结算对接人"
v-model="formData.settlementLead"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="签约人" prop="contractor">
<el-select
class="w-1/1"
placeholder="请选择签约人"
v-model="formData.contractor"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item label="地址" prop="areaId">
<el-cascader
v-model="formData.areaId"
:options="areaList"
:props="defaultProps"
class="w-1/1"
clearable
filterable
placeholder="请选择地址"
/>
</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-col :span="12">
<el-form-item label="下次联系时间" prop="contactNextTime">
<el-date-picker
v-model="formData.contactNextTime"
placeholder="选择下次联系时间"
type="datetime"
value-format="x"
class="!w-1/1"
/>
</el-form-item>
</el-col>-->
</el-row>
</el-form>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } 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 { useUserStore } from '@/store/modules/user'
import { json } from 'stream/consumers'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
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,
startDate: undefined,
contactNextTime: undefined,
ownerUserId: 0,
mobile: undefined,
telephone: undefined,
qq: undefined,
wechat: undefined,
email: undefined,
areaId: undefined,
detailAddress: undefined,
industryId: undefined,
level: undefined,
source: undefined,
remark: undefined,
clueDeveloper: undefined,
assist: [],
creditNo: undefined,
clueDeveloper: undefined,
serviceStatus: undefined,
legalPersonName: undefined,
registerCapital: undefined,
website: undefined,
registeredAddress: undefined,
cooperationArea: 1
})
const formRules = reactive({
name: [{ required: true, message: '客户名称不能为空', trigger: 'blur' }],
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
clueDeveloper: [{ required: true, message: '拓展人不能为空', trigger: 'change' }],
cooperationType: [{ required: true, message: '合作类型不能为空', trigger: 'change' }],
cooperationArea: [{ required: true, message: '合作地区不能为空', trigger: 'change' }],
website: [{ required: true, message: '网站不能为空', trigger: 'change' }],
})
const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
formData.value = await CustomerApi.getCustomer(id)
} finally {
formLoading.value = false
}
}
restaurants.value = await CustomerApi.getCompanyList({companyName: '小米科技有限责任公司'})
// 获得地区列表
areaList.value = await AreaApi.getAreaTree()
// 获得用户列表
userOptions.value = await UserApi.getSimpleUserList()
// 默认新建时选中自己
if (formType.value === 'create') {
formData.value.ownerUserId = useUserStore().getUser.id
formData.value.clueDeveloper = useUserStore().getUser.id
// formData.value.assist = useUserStore().getUser.id
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as CustomerApi.CustomerVO
if (formType.value === 'create') {
await CustomerApi.createCustomer(data)
message.success(t('common.createSuccess'))
} else {
await CustomerApi.updateCustomer(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
// const loadAll = async (val) => {
// restaurants.value = await CustomerApi.getCompanyList({
// companyName: val
// })
// }
interface RestaurantItem {
value: string
link: string
}
let timeout: ReturnType<typeof setTimeout>
const restaurants = ref<RestaurantItem[]>([])
const querySearchAsync = async (queryString: string, cb: (arg: any) => void) => {
let data = await CustomerApi.getCompanyList({
companyName: queryString
})
restaurants.value = data.list.map(v => {
return Object.assign(v, {value: v.name})
})
const results = queryString
? restaurants.value.filter(createFilter(queryString))
: restaurants.value
clearTimeout(timeout)
timeout = setTimeout(() => {
cb(results)
}, 2000 * Math.random())
}
const createFilter = (queryString: string) => {
return (restaurant: RestaurantItem) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
)
}
}
const handleSelect = (item: Record<string, any>) => {
formData.value.legalPersonName = item.legalPersonName
formData.value.registerCapital = item.regCapital
formData.value.startDate = item.regDate
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: undefined,
regCapital: undefined,
regDate: undefined,
contactNextTime: undefined,
ownerUserId: 0,
mobile: undefined,
telephone: undefined,
qq: undefined,
wechat: undefined,
email: undefined,
areaId: undefined,
detailAddress: undefined,
industryId: undefined,
level: undefined,
source: undefined,
reamark: undefined,
clueDeveloper: undefined,
assist: [],
clueDeveloper: undefined,
}
formRef.value?.resetFields()
}
</script>