229 lines
6.4 KiB
Vue
229 lines
6.4 KiB
Vue
<template>
|
|
<div class="list-page">
|
|
<div class="page-title">供应商库</div>
|
|
<div class="toolbar">
|
|
<el-button v-if="isAdmin" type="primary" @click="openCreate">新增供应商</el-button>
|
|
</div>
|
|
<div class="table-wrap">
|
|
<el-table v-loading="tableLoading" :data="factories" border height="100%">
|
|
<el-table-column prop="factory_name" label="供应商全称" />
|
|
<el-table-column prop="short_name" label="供应商简称" />
|
|
<el-table-column prop="dealer_name" label="经销商" />
|
|
<el-table-column label="用户账号">
|
|
<template #default="scope">
|
|
{{ (scope.row.usernames || []).join('、') || '-' }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="地区">
|
|
<template #default="scope">
|
|
{{ formatRegion(scope.row.province, scope.row.city, scope.row.district) }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作" width="200">
|
|
<template #default="scope">
|
|
<div class="table-actions">
|
|
<el-button size="small" @click="goDetail(scope.row)">详情</el-button>
|
|
<el-button size="small" @click="openEdit(scope.row)">编辑</el-button>
|
|
<el-button v-if="isAdmin" size="small" type="danger" @click="onDelete(scope.row)">删除</el-button>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
<div class="pagination">
|
|
<el-pagination
|
|
background
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
:page-sizes="[10, 20, 50]"
|
|
:current-page="pagination.page"
|
|
:page-size="pagination.pageSize"
|
|
:total="pagination.total"
|
|
@current-change="onPageChange"
|
|
@size-change="onPageSizeChange"
|
|
/>
|
|
</div>
|
|
|
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="640px" class="dialog-scroll">
|
|
<el-form :model="form" label-width="100px">
|
|
<el-form-item label="经销商">
|
|
<el-input v-model="form.dealer_name" />
|
|
</el-form-item>
|
|
<el-form-item label="产品分类">
|
|
<el-input v-model="form.product_category" />
|
|
</el-form-item>
|
|
<el-form-item label="供应商全称" required>
|
|
<el-input v-model="form.factory_name" />
|
|
</el-form-item>
|
|
<el-form-item label="供应商简称" required>
|
|
<el-input v-model="form.short_name" />
|
|
</el-form-item>
|
|
<el-form-item label="省市区" required>
|
|
<el-cascader
|
|
v-model="regionValue"
|
|
:options="regionOptions"
|
|
:props="{ value: 'label' }"
|
|
clearable
|
|
@change="onRegionChange"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="地址">
|
|
<el-input v-model="form.address" type="textarea" />
|
|
</el-form-item>
|
|
<el-form-item label="官网">
|
|
<el-input v-model="form.website" />
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="onSubmit">保存</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, reactive, onMounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import { regionData } from 'element-china-area-data'
|
|
import { useAuth } from '@/store/auth'
|
|
import { formatRegion, regionLabel } from '@/utils/region'
|
|
import { fetchFactories, fetchFactoryDetail, createFactory, updateFactory, deleteFactory } from '@/api/factory'
|
|
|
|
const router = useRouter()
|
|
const { isAdmin } = useAuth()
|
|
const factories = ref([])
|
|
const tableLoading = ref(false)
|
|
const pagination = reactive({
|
|
page: 1,
|
|
pageSize: 10,
|
|
total: 0
|
|
})
|
|
const dialogVisible = ref(false)
|
|
const dialogTitle = ref('')
|
|
const isEdit = ref(false)
|
|
const currentId = ref(null)
|
|
|
|
const regionOptions = regionData
|
|
const regionValue = ref([])
|
|
|
|
const form = reactive({
|
|
dealer_name: '',
|
|
product_category: '',
|
|
factory_name: '',
|
|
short_name: '',
|
|
province: '',
|
|
city: '',
|
|
district: '',
|
|
address: '',
|
|
website: ''
|
|
})
|
|
|
|
const loadFactories = async () => {
|
|
tableLoading.value = true
|
|
try {
|
|
const data = await fetchFactories({ page: pagination.page, page_size: pagination.pageSize })
|
|
factories.value = data.results || data
|
|
pagination.total = data.count || factories.value.length
|
|
} finally {
|
|
tableLoading.value = false
|
|
}
|
|
}
|
|
|
|
const resetForm = () => {
|
|
form.dealer_name = ''
|
|
form.product_category = ''
|
|
form.factory_name = ''
|
|
form.short_name = ''
|
|
form.province = ''
|
|
form.city = ''
|
|
form.district = ''
|
|
form.address = ''
|
|
form.website = ''
|
|
regionValue.value = []
|
|
}
|
|
|
|
const onRegionChange = (val) => {
|
|
form.province = val?.[0] || ''
|
|
form.city = val?.[1] || ''
|
|
form.district = val?.[2] || ''
|
|
}
|
|
|
|
const openCreate = () => {
|
|
resetForm()
|
|
isEdit.value = false
|
|
dialogTitle.value = '新增供应商'
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
const openEdit = async (row) => {
|
|
resetForm()
|
|
isEdit.value = true
|
|
currentId.value = row.id
|
|
const detail = await fetchFactoryDetail(row.id)
|
|
Object.assign(form, detail)
|
|
regionValue.value = [detail.province, detail.city, detail.district].filter(Boolean).map(regionLabel)
|
|
dialogTitle.value = '编辑供应商'
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
const onSubmit = async () => {
|
|
try {
|
|
if (isEdit.value) {
|
|
await updateFactory(currentId.value, { ...form })
|
|
} else {
|
|
await createFactory({ ...form })
|
|
}
|
|
ElMessage.success('保存成功')
|
|
dialogVisible.value = false
|
|
loadFactories()
|
|
} catch (error) {
|
|
ElMessage.error(error.response?.data?.detail || '保存失败')
|
|
}
|
|
}
|
|
|
|
const onDelete = (row) => {
|
|
ElMessageBox.confirm(`确认删除供应商 ${row.factory_name} 吗?`, '提示', { type: 'warning' })
|
|
.then(async () => {
|
|
await deleteFactory(row.id)
|
|
ElMessage.success('删除成功')
|
|
loadFactories()
|
|
})
|
|
.catch(() => {})
|
|
}
|
|
|
|
const goDetail = (row) => {
|
|
router.push(`/factories/${row.id}`)
|
|
}
|
|
|
|
const onPageChange = (page) => {
|
|
pagination.page = page
|
|
loadFactories()
|
|
}
|
|
|
|
const onPageSizeChange = (size) => {
|
|
pagination.pageSize = size
|
|
pagination.page = 1
|
|
loadFactories()
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadFactories()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.pagination {
|
|
margin-top: 16px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.dialog-scroll :deep(.el-dialog__body) {
|
|
max-height: 60vh;
|
|
overflow: auto;
|
|
padding-right: 8px;
|
|
}
|
|
</style>
|
|
|