fix: 移动端工作计划/商机跟单/要客拜访新增快速新建客户

三个移动端表单现均支持搜索时直接新建客户(el-select #empty 插槽)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-12 18:29:41 +08:00
parent 4453ee2ca0
commit 3879cdc7ef
3 changed files with 102 additions and 3 deletions
+34 -1
View File
@@ -42,6 +42,8 @@ onMounted(async () => {
} }
}) })
const customerSearch = ref('')
async function loadCustomers(q?: string) { async function loadCustomers(q?: string) {
try { try {
const params: any = { page_size: 100 } const params: any = { page_size: 100 }
@@ -51,6 +53,28 @@ async function loadCustomers(q?: string) {
} catch (_) {} } catch (_) {}
} }
async function handleCustomerSearch(query: string) {
customerSearch.value = query
if (query) { await loadCustomers(query) }
else { await loadCustomers() }
}
async function handleQuickCreate() {
const name = customerSearch.value.trim()
if (!name) { ElMessage.warning('请输入单位名称'); return }
try {
const res = await api.post('/customers/quick-create', null, { params: { name } })
const newCust = res.data
customers.value.unshift(newCust)
form.value.customer_id = newCust.id
customerSearch.value = ''
ElMessage.success(`已创建客户:${name}`)
await loadCustomers()
} catch (e: any) {
ElMessage.error('创建失败: ' + (e.response?.data?.detail || e.message))
}
}
async function loadUsers() { async function loadUsers() {
try { try {
const res = await api.get('/users/') const res = await api.get('/users/')
@@ -90,8 +114,14 @@ async function handleSubmit() {
<el-form label-position="top" class="editorial-form"> <el-form label-position="top" class="editorial-form">
<el-form-item> <el-form-item>
<template #label><span class="form-label">客户单位</span></template> <template #label><span class="form-label">客户单位</span></template>
<el-select v-model="form.customer_id" filterable remote :remote-method="loadCustomers" placeholder="搜索客户" style="width:100%"> <el-select v-model="form.customer_id" filterable remote :remote-method="handleCustomerSearch" placeholder="搜索客户" style="width:100%">
<el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" /> <el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" />
<template #empty>
<div v-if="customerSearch" class="select-empty-create">
<p style="color:var(--warm-gray);font-size:13px;margin:0 0 8px">未找到{{ customerSearch }}</p>
<button type="button" class="quick-create-btn" @click.stop="handleQuickCreate">新建客户{{ customerSearch }}</button>
</div>
</template>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -245,4 +275,7 @@ async function handleSubmit() {
animation: spin 0.6s linear infinite; animation: spin 0.6s linear infinite;
} }
@keyframes spin { to { transform: rotate(360deg); } } @keyframes spin { to { transform: rotate(360deg); } }
.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 8px 14px; color: var(--gold-dark); font-family: var(--font-body); font-size: 13px; cursor: pointer; transition: all 0.2s; letter-spacing: 0.03em; }
.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); }
.select-empty-create { padding: 8px 12px; text-align: center; }
</style> </style>
+34 -1
View File
@@ -30,6 +30,8 @@ onMounted(() => {
} }
}) })
const customerSearch = ref('')
async function loadCustomers(q?: string) { async function loadCustomers(q?: string) {
try { try {
const params: any = { page_size: 100 } const params: any = { page_size: 100 }
@@ -39,6 +41,28 @@ async function loadCustomers(q?: string) {
} catch (_) {} } catch (_) {}
} }
async function handleCustomerSearch(query: string) {
customerSearch.value = query
if (query) { await loadCustomers(query) }
else { await loadCustomers() }
}
async function handleQuickCreate() {
const name = customerSearch.value.trim()
if (!name) { ElMessage.warning('请输入单位名称'); return }
try {
const res = await api.post('/customers/quick-create', null, { params: { name } })
const newCust = res.data
customers.value.unshift(newCust)
form.value.customer_id = newCust.id
customerSearch.value = ''
ElMessage.success(`已创建客户:${name}`)
await loadCustomers()
} catch (e: any) {
ElMessage.error('创建失败: ' + (e.response?.data?.detail || e.message))
}
}
async function handleSubmit() { async function handleSubmit() {
if (!form.value.customer_id) { ElMessage.warning('请选择客户'); return } if (!form.value.customer_id) { ElMessage.warning('请选择客户'); return }
submitLoading.value = true submitLoading.value = true
@@ -71,8 +95,14 @@ async function handleSubmit() {
<el-form label-position="top" class="editorial-form"> <el-form label-position="top" class="editorial-form">
<el-form-item> <el-form-item>
<template #label><span class="form-label">客户单位</span></template> <template #label><span class="form-label">客户单位</span></template>
<el-select v-model="form.customer_id" filterable remote :remote-method="loadCustomers" placeholder="搜索客户" style="width:100%"> <el-select v-model="form.customer_id" filterable remote :remote-method="handleCustomerSearch" placeholder="搜索客户" style="width:100%">
<el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" /> <el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" />
<template #empty>
<div v-if="customerSearch" class="select-empty-create">
<p style="color:var(--warm-gray);font-size:13px;margin:0 0 8px">未找到{{ customerSearch }}</p>
<button type="button" class="quick-create-btn" @click.stop="handleQuickCreate">新建客户{{ customerSearch }}</button>
</div>
</template>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -184,4 +214,7 @@ async function handleSubmit() {
animation: spin 0.6s linear infinite; animation: spin 0.6s linear infinite;
} }
@keyframes spin { to { transform: rotate(360deg); } } @keyframes spin { to { transform: rotate(360deg); } }
.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 8px 14px; color: var(--gold-dark); font-family: var(--font-body); font-size: 13px; cursor: pointer; transition: all 0.2s; letter-spacing: 0.03em; }
.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); }
.select-empty-create { padding: 8px 12px; text-align: center; }
</style> </style>
+34 -1
View File
@@ -29,6 +29,8 @@ onMounted(() => {
} }
}) })
const customerSearch = ref('')
async function loadCustomers(q?: string) { async function loadCustomers(q?: string) {
try { try {
const params: any = { page_size: 100 } const params: any = { page_size: 100 }
@@ -38,6 +40,28 @@ async function loadCustomers(q?: string) {
} catch (_) {} } catch (_) {}
} }
async function handleCustomerSearch(query: string) {
customerSearch.value = query
if (query) { await loadCustomers(query) }
else { await loadCustomers() }
}
async function handleQuickCreate() {
const name = customerSearch.value.trim()
if (!name) { ElMessage.warning('请输入单位名称'); return }
try {
const res = await api.post('/customers/quick-create', null, { params: { name } })
const newCust = res.data
customers.value.unshift(newCust)
form.value.customer_id = newCust.id
customerSearch.value = ''
ElMessage.success(`已创建客户:${name}`)
await loadCustomers()
} catch (e: any) {
ElMessage.error('创建失败: ' + (e.response?.data?.detail || e.message))
}
}
async function handleSubmit() { async function handleSubmit() {
if (!form.value.customer_id) { ElMessage.warning('请选择客户'); return } if (!form.value.customer_id) { ElMessage.warning('请选择客户'); return }
submitLoading.value = true submitLoading.value = true
@@ -70,8 +94,14 @@ async function handleSubmit() {
<el-form label-position="top" class="editorial-form"> <el-form label-position="top" class="editorial-form">
<el-form-item> <el-form-item>
<template #label><span class="form-label">客户单位</span></template> <template #label><span class="form-label">客户单位</span></template>
<el-select v-model="form.customer_id" filterable remote :remote-method="loadCustomers" placeholder="搜索客户" style="width:100%"> <el-select v-model="form.customer_id" filterable remote :remote-method="handleCustomerSearch" placeholder="搜索客户" style="width:100%">
<el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" /> <el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" />
<template #empty>
<div v-if="customerSearch" class="select-empty-create">
<p style="color:var(--warm-gray);font-size:13px;margin:0 0 8px">未找到{{ customerSearch }}</p>
<button type="button" class="quick-create-btn" @click.stop="handleQuickCreate">新建客户{{ customerSearch }}</button>
</div>
</template>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -164,4 +194,7 @@ async function handleSubmit() {
animation: spin 0.6s linear infinite; animation: spin 0.6s linear infinite;
} }
@keyframes spin { to { transform: rotate(360deg); } } @keyframes spin { to { transform: rotate(360deg); } }
.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 8px 14px; color: var(--gold-dark); font-family: var(--font-body); font-size: 13px; cursor: pointer; transition: all 0.2s; letter-spacing: 0.03em; }
.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); }
.select-empty-create { padding: 8px 12px; text-align: center; }
</style> </style>