diff --git a/frontend/src/views/desktop/KeyVisits.vue b/frontend/src/views/desktop/KeyVisits.vue index 3bfb9a4..23490a7 100644 --- a/frontend/src/views/desktop/KeyVisits.vue +++ b/frontend/src/views/desktop/KeyVisits.vue @@ -88,6 +88,8 @@ async function loadUsers() { } catch (_) {} } +const customerSearch = ref('') + async function loadCustomers(q?: string) { try { const params: any = { page_size: 500 } @@ -97,6 +99,28 @@ async function loadCustomers(q?: string) { } 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 loadItems() { loading.value = true try { @@ -270,9 +294,12 @@ async function quickStatusChange(row: any, newStatus: string) { - + +
+ +
@@ -329,4 +356,6 @@ async function quickStatusChange(row: any, newStatus: string) { .filter-item { display: flex; align-items: center; gap: 8px; } .filter-label { font-size: 13px; color: var(--warm-gray); font-family: var(--font-body); white-space: nowrap; } .filter-count { font-size: 12px; color: var(--c-text-muted); font-family: var(--font-mono); margin-left: auto; } +.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 6px 12px; color: var(--gold-dark); font-family: var(--font-body); font-size: 12px; cursor: pointer; transition: all 0.2s; } +.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); } diff --git a/frontend/src/views/desktop/ManagerWorkspace.vue b/frontend/src/views/desktop/ManagerWorkspace.vue index ceba295..abe08ab 100644 --- a/frontend/src/views/desktop/ManagerWorkspace.vue +++ b/frontend/src/views/desktop/ManagerWorkspace.vue @@ -53,6 +53,8 @@ function typeLabel(t: string) { return labels[t] || '' } +const customerSearch = ref('') + async function loadCustomers(q?: string) { try { const params: any = { page_size: 100 } @@ -62,6 +64,28 @@ async function loadCustomers(q?: string) { } 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 loadAll() { loading.value = true try { @@ -446,9 +470,12 @@ const notesByDate = computed(() => { - + +
+ +
@@ -542,4 +569,6 @@ const notesByDate = computed(() => { .date-group { margin-bottom: 20px; } .date-title { display: flex; align-items: center; margin: 12px 0 8px; font-family: var(--font-heading); font-size: 14px; color: var(--ink); letter-spacing: 0.04em; } .empty { text-align: center; color: var(--c-text-muted); padding: 40px 0; font-family: var(--font-body); } +.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 6px 12px; color: var(--gold-dark); font-family: var(--font-body); font-size: 12px; cursor: pointer; transition: all 0.2s; } +.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); } diff --git a/frontend/src/views/desktop/MiniBusiness.vue b/frontend/src/views/desktop/MiniBusiness.vue index 0f7df0a..2418741 100644 --- a/frontend/src/views/desktop/MiniBusiness.vue +++ b/frontend/src/views/desktop/MiniBusiness.vue @@ -66,6 +66,8 @@ onMounted(async () => { await Promise.all([loadItems(), loadCustomers(), loadManagerColors()]) }) +const customerSearch = ref('') + async function loadCustomers(q?: string) { try { const params: any = { page_size: 500 } @@ -75,6 +77,28 @@ async function loadCustomers(q?: string) { } 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 loadItems() { loading.value = true try { @@ -237,9 +261,12 @@ async function quickStatusChange(row: any, newStatus: string) { - + +
+ +
@@ -284,4 +311,6 @@ async function quickStatusChange(row: any, newStatus: string) { .filter-item { display: flex; align-items: center; gap: 8px; } .filter-label { font-size: 13px; color: var(--warm-gray); font-family: var(--font-body); white-space: nowrap; } .filter-count { font-size: 12px; color: var(--c-text-muted); font-family: var(--font-mono); margin-left: auto; } +.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 6px 12px; color: var(--gold-dark); font-family: var(--font-body); font-size: 12px; cursor: pointer; transition: all 0.2s; } +.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); } diff --git a/frontend/src/views/desktop/WorkPlans.vue b/frontend/src/views/desktop/WorkPlans.vue index 55771db..1a6bc13 100644 --- a/frontend/src/views/desktop/WorkPlans.vue +++ b/frontend/src/views/desktop/WorkPlans.vue @@ -67,6 +67,8 @@ onMounted(async () => { await Promise.all([loadPlans(), loadCustomers(), loadManagerColors()]) }) +const customerSearch = ref('') + async function loadCustomers(q?: string) { try { const params: any = { page_size: 500 } @@ -76,6 +78,28 @@ async function loadCustomers(q?: string) { } 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 loadPlans() { loading.value = true try { @@ -236,9 +260,12 @@ async function quickStatusChange(row: any, newStatus: string) { - + +
+ +
@@ -285,4 +312,6 @@ async function quickStatusChange(row: any, newStatus: string) { .filter-item { display: flex; align-items: center; gap: 8px; } .filter-label { font-size: 13px; color: var(--warm-gray); font-family: var(--font-body); white-space: nowrap; } .filter-count { font-size: 12px; color: var(--c-text-muted); font-family: var(--font-mono); margin-left: auto; } +.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 6px 12px; color: var(--gold-dark); font-family: var(--font-body); font-size: 12px; cursor: pointer; transition: all 0.2s; } +.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); }