yunzer_go/pc/src/views/apps/crm/customer/components/edit.vue
2026-01-07 08:43:14 +08:00

236 lines
7.7 KiB
Vue

<template>
<el-dialog
v-model="visible"
:title="isEdit ? '编辑客户' : '新增客户'"
width="600px"
:close-on-click-modal="false"
>
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
<el-form-item label="客户名称" prop="name">
<el-input v-model="form.name" placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="客户类型" prop="customer_type">
<el-select v-model="form.customer_type" placeholder="请选择客户类型" filterable clearable>
<el-option
v-for="item in customerTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="客户等级" prop="customer_level">
<el-select v-model="form.customer_level" placeholder="请选择客户等级" filterable clearable>
<el-option
v-for="item in customerLevelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="所属行业" prop="industry">
<el-select v-model="form.industry" placeholder="请选择所属行业" filterable clearable>
<el-option
v-for="item in industryOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="法人" prop="contact">
<el-input v-model="form.contact" placeholder="请输入法人" />
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="form.address" type="textarea" placeholder="请输入地址" />
</el-form-item>
<el-form-item label="经营范围" prop="business_scope">
<el-input
v-model="form.business_scope"
type="textarea"
:rows="5"
placeholder="请输入经营范围"
/>
</el-form-item>
<el-form-item label="客户状态" prop="status">
<el-select v-model="form.status" placeholder="请选择客户状态" clearable>
<el-option
v-for="item in customerStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="onCancel">取消</el-button>
<el-button type="primary" @click="onSubmit" :loading="submitting">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, watch, computed, onMounted } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { createCustomer, updateCustomer } from '@/api/customer.js'
import request from '@/utils/request'
const props = defineProps<{ modelValue: boolean, isEdit: boolean, model?: any }>()
const emit = defineEmits(['update:modelValue', 'saved'])
const visible = computed({
get: () => props.modelValue,
set: (v: boolean) => emit('update:modelValue', v)
})
const formRef = ref<FormInstance>()
const submitting = ref(false)
const form = reactive({
id: null as string | null,
name: '',
customer_type: '',
customer_level: '3',
industry: '',
contact: '',
phone: '',
email: '',
address: '',
business_scope: '',
status: '1'
})
const rules: FormRules = {
name: [{ required: true, message: '请输入客户名称', trigger: 'blur' }],
customer_type: [{ required: true, message: '请选择客户类型', trigger: 'change' }],
customer_level: [{ required: true, message: '请选择客户等级', trigger: 'change' }],
industry: [{ required: true, message: '请选择所属行业', trigger: 'change' }],
}
const customerTypeOptions = ref<{label:string,value:string}[]>([])
const customerLevelOptions = ref<{label:string,value:string}[]>([])
const industryOptions = ref<{label:string,value:string}[]>([])
const customerStatusOptions = ref<{label:string,value:string}[]>([])
function mapDictItems(items: any[]) {
return (items || []).map(it => ({ label: it.dict_label, value: it.dict_value }))
}
async function loadDictOptions() {
const [typeRes, levelRes, industryRes, statusRes] = await Promise.all([
request({ url: '/api/dict/items/code/customer_type', method: 'get' }),
request({ url: '/api/dict/items/code/customer_level', method: 'get' }),
request({ url: '/api/dict/items/code/industry', method: 'get' }),
request({ url: '/api/dict/items/code/customer_status', method: 'get' }),
])
const getData = (r:any) => (r && r.data && (r.data.data || r.data)) || []
customerTypeOptions.value = mapDictItems(getData(typeRes))
customerLevelOptions.value = mapDictItems(getData(levelRes))
industryOptions.value = mapDictItems(getData(industryRes))
customerStatusOptions.value = mapDictItems(getData(statusRes))
}
watch(() => props.model, (m) => {
if (m) {
form.id = m.id ?? null
form.name = (m.customer_name ?? m.name) ?? ''
form.customer_type = m.customer_type != null && m.customer_type !== undefined ? String(m.customer_type) : ''
form.customer_level = m.customer_level != null && m.customer_level !== undefined ? String(m.customer_level) : ''
form.industry = m.industry != null && m.industry !== undefined ? String(m.industry) : ''
form.contact = (m.contact_person ?? m.contact) ?? ''
form.phone = (m.contact_phone ?? m.phone) ?? ''
form.email = (m.contact_email ?? m.email) ?? ''
form.address = m.address ?? ''
form.business_scope = m.business_scope ?? ''
form.status = m.status != null && m.status !== undefined ? String(m.status) : ''
} else {
resetForm()
}
}, { immediate: true, deep: true })
function resetForm() {
form.id = null
form.name = ''
form.customer_type = ''
form.customer_level = '3'
form.industry = ''
form.contact = ''
form.phone = ''
form.email = ''
form.address = ''
form.business_scope = ''
form.status = '1'
formRef.value?.clearValidate()
}
async function onSubmit() {
if (!formRef.value) return
await formRef.value.validate()
try {
submitting.value = true
const tenantId = (() => {
try {
const ui = localStorage.getItem('userInfo')
if (ui) {
const u = JSON.parse(ui)
const tid = u.tenant_id || u.tenantId || ''
return tid != null && tid !== undefined ? String(tid) : ''
}
} catch (e) {}
return ''
})()
const payload: any = {
customer_name: form.name,
customer_type: form.customer_type,
customer_level: form.customer_level,
industry: form.industry,
contact_person: form.contact,
contact_phone: form.phone,
contact_email: form.email,
address: form.address,
business_scope: form.business_scope,
status: String(form.status),
tenant_id: tenantId,
}
if (props.isEdit && form.id) {
await updateCustomer(form.id, payload)
} else {
await createCustomer(payload)
}
ElMessage.success(props.isEdit ? '修改成功' : '新增成功')
emit('saved')
visible.value = false
} finally {
submitting.value = false
}
}
function onCancel() {
visible.value = false
}
watch(() => visible.value, (v) => {
if (v) {
loadDictOptions()
}
})
onMounted(() => {
if (visible.value) {
loadDictOptions()
}
})
</script>
<style scoped>
</style>