293 lines
8.2 KiB
Vue
293 lines
8.2 KiB
Vue
<template>
|
|
<div class="crm-customer">
|
|
<div class="customer-container">
|
|
<!-- 顶部操作栏 -->
|
|
<div class="toolbar">
|
|
<el-button type="primary" @click="handleAdd">新增供应商</el-button>
|
|
<el-button @click="handleRefresh">刷新</el-button>
|
|
<div class="search-bar">
|
|
<el-input
|
|
v-model="searchQuery"
|
|
placeholder="搜索供应商名称/联系人/电话"
|
|
clearable
|
|
@clear="handleSearch"
|
|
>
|
|
<template #append>
|
|
<el-button :icon="Search" @click="handleSearch" />
|
|
</template>
|
|
</el-input>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 供应商列表 -->
|
|
<el-table
|
|
:data="customerList"
|
|
v-loading="loading"
|
|
stripe
|
|
border
|
|
style="width: 100%"
|
|
>
|
|
<el-table-column prop="supplier_name" label="供应商名称" width="360" fixed="left">
|
|
<template #default="{ row }">
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<el-tag :type="row.status === '1' ? 'success' : 'info'" size="small">
|
|
{{ row.status === '1' ? '正常' : '停用' }}
|
|
</el-tag>
|
|
<el-link type="primary" @click="handleView(row)">{{ row.supplier_name }}</el-link>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="contact_person" label="法人" width="100" />
|
|
<el-table-column prop="contact_phone" label="联系电话" width="160" />
|
|
<el-table-column prop="contact_email" label="邮箱" min-width="180" />
|
|
<el-table-column prop="address" label="地址" min-width="300" show-overflow-tooltip />
|
|
<el-table-column label="操作" width="250" fixed="right">
|
|
<template #default="{ row }">
|
|
<el-button link type="info" @click="handleContactView(row)">联系人</el-button>
|
|
<el-button link type="info" @click="handleInvoiceView(row)">开票信息</el-button>
|
|
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
|
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 分页 -->
|
|
<div class="pagination">
|
|
<el-pagination
|
|
v-model:current-page="currentPage"
|
|
v-model:page-size="pageSize"
|
|
:total="total"
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
@size-change="handleSizeChange"
|
|
@current-change="handleCurrentChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 编辑弹窗 -->
|
|
<Edit
|
|
v-model="dialogVisible"
|
|
:is-edit="isEdit"
|
|
:model="currentRow"
|
|
@saved="onSaved"
|
|
/>
|
|
|
|
<!-- 详情抽屉 -->
|
|
<Detail v-model="detailVisible" :model="currentRow" />
|
|
|
|
<!-- 联系人抽屉 -->
|
|
<Contact v-model="contactVisible" :model="currentRow" />
|
|
|
|
<!-- 开票信息抽屉 -->
|
|
<Invoice v-model="invoiceVisible" :model="currentRow" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
import { Search } from '@element-plus/icons-vue';
|
|
import Edit from './components/edit.vue'
|
|
import Detail from './components/detail.vue'
|
|
import Contact from './components/contact.vue'
|
|
import Invoice from './components/invoice.vue'
|
|
import { listSuppliers, getSupplier, deleteSupplier } from '../../../../api/supplier.js'
|
|
|
|
const loading = ref(false);
|
|
const customerList = ref([]);
|
|
const searchQuery = ref('');
|
|
const currentPage = ref(1);
|
|
const pageSize = ref(10);
|
|
const total = ref(0);
|
|
const dialogVisible = ref(false);
|
|
const detailVisible = ref(false);
|
|
const contactVisible = ref(false);
|
|
const invoiceVisible = ref(false);
|
|
const isEdit = ref(false);
|
|
const currentRow = ref(null);
|
|
|
|
async function fetchCustomerList() {
|
|
loading.value = true
|
|
try {
|
|
const { data } = await listSuppliers({
|
|
keyword: searchQuery.value,
|
|
page: currentPage.value,
|
|
pageSize: pageSize.value,
|
|
})
|
|
customerList.value = data.list || []
|
|
total.value = data.total || 0
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function handleAdd() {
|
|
isEdit.value = false;
|
|
currentRow.value = null;
|
|
dialogVisible.value = true;
|
|
}
|
|
|
|
function handleEdit(row) {
|
|
isEdit.value = true;
|
|
currentRow.value = { ...row };
|
|
dialogVisible.value = true;
|
|
}
|
|
|
|
function handleView(row) {
|
|
currentRow.value = { ...row }
|
|
detailVisible.value = true
|
|
getSupplier(row.id).then((res) => {
|
|
const resp = res && res.data ? res.data : res
|
|
if (resp && resp.code === 0 && resp.data) {
|
|
const m = resp.data
|
|
currentRow.value = {
|
|
id: m.id,
|
|
name: m.supplier_name || m.name || '',
|
|
contact: m.contact_person || m.contact || '',
|
|
phone: m.contact_phone || m.phone || '',
|
|
email: m.contact_email || m.email || '',
|
|
address: m.address || '',
|
|
status: typeof m.status === 'number' ? m.status : (m.status === '0' ? 0 : 1),
|
|
_raw: m,
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
function handleContactView(row) {
|
|
currentRow.value = { ...row }
|
|
contactVisible.value = true
|
|
getSupplier(row.id).then((res) => {
|
|
const resp = res && res.data ? res.data : res
|
|
if (resp && resp.code === 0 && resp.data) {
|
|
const m = resp.data
|
|
currentRow.value = {
|
|
id: m.id,
|
|
name: m.supplier_name || m.name || '',
|
|
contact: m.contact_person || m.contact || '',
|
|
phone: m.contact_phone || m.phone || '',
|
|
email: m.contact_email || m.email || '',
|
|
address: m.address || '',
|
|
status: typeof m.status === 'number' ? m.status : (m.status === '0' ? 0 : 1),
|
|
supplier_type: m.supplier_type,
|
|
supplier_level: m.supplier_level,
|
|
industry: m.industry,
|
|
_raw: m,
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
function handleInvoiceView(row) {
|
|
currentRow.value = { ...row }
|
|
invoiceVisible.value = true
|
|
getSupplier(row.id).then((res) => {
|
|
const resp = res && res.data ? res.data : res
|
|
if (resp && resp.code === 0 && resp.data) {
|
|
const m = resp.data
|
|
currentRow.value = {
|
|
id: m.id,
|
|
name: m.supplier_name || m.name || '',
|
|
contact: m.contact_person || m.contact || '',
|
|
phone: m.contact_phone || m.phone || '',
|
|
email: m.contact_email || m.email || '',
|
|
address: m.address || '',
|
|
status: typeof m.status === 'number' ? m.status : (m.status === '0' ? 0 : 1),
|
|
supplier_type: m.supplier_type,
|
|
supplier_level: m.supplier_level,
|
|
industry: m.industry,
|
|
// 开票相关(如果后端返回则透传给抽屉)
|
|
invoice_title: m.invoice_title,
|
|
tax_number: m.tax_number,
|
|
bank_name: m.bank_name,
|
|
bank_account: m.bank_account,
|
|
registered_address: m.registered_address,
|
|
registered_phone: m.registered_phone,
|
|
_raw: m,
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
function handleDelete(row) {
|
|
ElMessageBox.confirm('确定要删除该供应商吗?', '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
deleteSupplier(row.id)
|
|
.then((res) => {
|
|
const resp = res && res.data ? res.data : res
|
|
if (resp && resp.code === 0) {
|
|
ElMessage.success('删除成功');
|
|
fetchCustomerList();
|
|
} else {
|
|
ElMessage.error((resp && resp.message) || '删除失败')
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
function onSaved() {
|
|
fetchCustomerList();
|
|
}
|
|
|
|
function handleSearch() {
|
|
currentPage.value = 1;
|
|
fetchCustomerList();
|
|
}
|
|
|
|
function handleRefresh() {
|
|
searchQuery.value = '';
|
|
currentPage.value = 1;
|
|
fetchCustomerList();
|
|
}
|
|
|
|
function handleSizeChange() {
|
|
fetchCustomerList();
|
|
}
|
|
|
|
function handleCurrentChange() {
|
|
fetchCustomerList();
|
|
}
|
|
|
|
onMounted(() => {
|
|
fetchCustomerList();
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.crm-customer {
|
|
padding: 20px;
|
|
height: 100%;
|
|
background: #f5f7fa;
|
|
|
|
.customer-container {
|
|
background: #fff;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.toolbar {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-bottom: 20px;
|
|
|
|
.search-bar {
|
|
margin-left: auto;
|
|
width: 300px;
|
|
}
|
|
}
|
|
|
|
.pagination {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
}
|
|
}
|
|
</style>
|