附录A全接入:7新页面+路由菜单+库存大盘抽屉 / P1-2真机非法值拦截全绿 / 文档终版510+514
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
<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>
|
||||
</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>
|
||||
<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-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' }],
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
onMounted(() => { loadLevels(); loadContacts() })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar { display: flex; gap: 10px; margin-bottom: 14px; align-items: center; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user