Files
dealerhub/frontend/src/pages/PriceLevels.vue
T

232 lines
9.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<el-card shadow="never">
<el-tabs v-model="tab">
<el-tab-pane label="价格等级" name="levels">
<div class="toolbar">
<el-button type="primary" @click="openLevelCreate">新建等级</el-button>
</div>
<el-table :data="levels" v-loading="levelsLoading" size="small" stripe>
<el-table-column prop="code" label="等级编码" width="140" />
<el-table-column prop="name" label="等级名称" min-width="160" />
<el-table-column prop="discount_rate" label="折扣率" width="120" />
<el-table-column prop="sort_order" label="排序" width="100" />
<el-table-column label="操作" width="150">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="openLevelEdit(row)">编辑</el-button>
<el-button link type="danger" size="small" @click="removeLevel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="联系人" name="contacts">
<div class="toolbar">
<el-input v-model="contactSearch" placeholder="搜索联系人姓名" style="width: 240px" clearable @keyup.enter="loadContacts" />
<el-button type="primary" @click="loadContacts">查询</el-button>
<el-button type="primary" @click="openContactCreate">新建联系人</el-button>
</div>
<el-table :data="contacts" v-loading="contactsLoading" size="small" stripe>
<el-table-column prop="name" label="姓名" width="140" />
<el-table-column prop="phone" label="电话" width="150" />
<el-table-column prop="email" label="邮箱" min-width="160" />
<el-table-column prop="title" label="职位" width="140" />
<el-table-column label="归属" width="180">
<template #default="{ row }">
{{ row.customer_code || row.supplier_code || '—' }}
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="openContactEdit(row)">编辑</el-button>
<el-button link type="danger" size="small" @click="removeContact(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
style="margin-top: 14px"
layout="prev, pager, next, total"
:total="contactsCount"
:page-size="20"
v-model:current-page="contactsPage"
@current-change="loadContacts"
/>
</el-tab-pane>
</el-tabs>
<el-dialog v-model="dialogVisible" :title="editing ? '编辑价格等级' : '新建价格等级'" width="480px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="等级编码" prop="code"><el-input v-model="form.code" /></el-form-item>
<el-form-item label="等级名称" prop="name"><el-input v-model="form.name" /></el-form-item>
<el-form-item label="折扣率" prop="discount_rate">
<el-input-number v-model="form.discount_rate" :min="0" :max="1" :precision="4" style="width: 100%" />
</el-form-item>
<el-form-item label="排序" prop="sort_order">
<el-input-number v-model="form.sort_order" :precision="0" style="width: 100%" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="saveLevel">保存</el-button>
</template>
</el-dialog>
<el-dialog v-model="contactDialogVisible" :title="contactEditing ? '编辑联系人' : '新建联系人'" width="480px">
<el-form ref="contactFormRef" :model="contactForm" :rules="contactRules" label-width="100px">
<el-form-item label="姓名" prop="name"><el-input v-model="contactForm.name" /></el-form-item>
<el-form-item label="电话" prop="phone"><el-input v-model="contactForm.phone" /></el-form-item>
<el-form-item label="邮箱" prop="email"><el-input v-model="contactForm.email" /></el-form-item>
<el-form-item label="职位" prop="title"><el-input v-model="contactForm.title" /></el-form-item>
<el-form-item label="客户ID" prop="customer">
<el-input-number v-model="contactForm.customer" :min="0" :precision="0" style="width: 100%" placeholder="可选:挂靠客户" />
</el-form-item>
<el-form-item label="供应商ID" prop="supplier">
<el-input-number v-model="contactForm.supplier" :min="0" :precision="0" style="width: 100%" placeholder="可选:挂靠供应商" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="contactDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="contactSaving" @click="saveContact">保存</el-button>
</template>
</el-dialog>
</el-card>
</template>
<script setup>
import { onMounted, ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import api from '../api/client'
const tab = ref('levels')
const levels = ref([])
const levelsLoading = ref(false)
const contacts = ref([])
const contactsCount = ref(0)
const contactsPage = ref(1)
const contactSearch = ref('')
const contactsLoading = ref(false)
const dialogVisible = ref(false)
const editing = ref(null)
const saving = ref(false)
const formRef = ref(null)
const form = reactive({ code: '', name: '', discount_rate: 0, sort_order: 0 })
const rules = {
code: [{ required: true, message: '请输入等级编码', trigger: 'blur' }],
name: [{ required: true, message: '请输入等级名称', trigger: 'blur' }],
}
const contactDialogVisible = ref(false)
const contactEditing = ref(null)
const contactSaving = ref(false)
const contactFormRef = ref(null)
const contactForm = reactive({ name: '', phone: '', email: '', title: '', customer: null, supplier: null })
const contactRules = {
name: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
email: [{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }],
}
async function loadLevels() {
levelsLoading.value = true
try {
const data = await api.get('/partner/price-levels/', { params: { page_size: 100 } })
levels.value = data.results || []
} finally {
levelsLoading.value = false
}
}
async function loadContacts() {
contactsLoading.value = true
try {
const data = await api.get('/partner/contacts/', {
params: { page: contactsPage.value, page_size: 20, search: contactSearch.value },
})
contacts.value = data.results || []
contactsCount.value = data.count || 0
} finally {
contactsLoading.value = false
}
}
function openLevelCreate() {
editing.value = null
Object.assign(form, { code: '', name: '', discount_rate: 0, sort_order: 0 })
dialogVisible.value = true
}
function openLevelEdit(row) {
editing.value = row
Object.assign(form, { code: row.code, name: row.name, discount_rate: Number(row.discount_rate), sort_order: row.sort_order })
dialogVisible.value = true
}
async function saveLevel() {
const ok = await formRef.value.validate().catch(() => false)
if (!ok) return
saving.value = true
try {
if (editing.value) await api.patch(`/partner/price-levels/${editing.value.id}/`, { ...form })
else await api.post('/partner/price-levels/', { ...form })
ElMessage.success('已保存')
dialogVisible.value = false
await loadLevels()
} finally {
saving.value = false
}
}
async function removeLevel(row) {
try {
await ElMessageBox.confirm(`删除等级 ${row.code}(${row.name})?`, '删除确认', { type: 'warning' })
} catch (e) { return }
await api.delete(`/partner/price-levels/${row.id}/`)
ElMessage.success('已删除')
await loadLevels()
}
function openContactCreate() {
contactEditing.value = null
Object.assign(contactForm, { name: '', phone: '', email: '', title: '', customer: null, supplier: null })
contactDialogVisible.value = true
}
function openContactEdit(row) {
contactEditing.value = row
Object.assign(contactForm, {
name: row.name || '', phone: row.phone || '', email: row.email || '',
title: row.title || '', customer: row.customer || null, supplier: row.supplier || null,
})
contactDialogVisible.value = true
}
async function saveContact() {
const ok = await contactFormRef.value.validate().catch(() => false)
if (!ok) return
contactSaving.value = true
try {
const payload = { ...contactForm }
if (!payload.customer) delete payload.customer
if (!payload.supplier) delete payload.supplier
if (contactEditing.value) await api.patch(`/partner/contacts/${contactEditing.value.id}/`, payload)
else await api.post('/partner/contacts/', payload)
ElMessage.success('已保存')
contactDialogVisible.value = false
await loadContacts()
} finally {
contactSaving.value = false
}
}
async function removeContact(row) {
try {
await ElMessageBox.confirm(`删除联系人 ${row.name}?`, '删除确认', { type: 'warning' })
} catch (e) { return }
await api.delete(`/partner/contacts/${row.id}/`)
ElMessage.success('已删除')
await loadContacts()
}
onMounted(() => { loadLevels(); loadContacts() })
</script>
<style scoped>
.toolbar { display: flex; gap: 10px; margin-bottom: 14px; align-items: center; }
</style>