style(refactor): 重构供应商管理页面布局与交互逻辑
1. 将原有单页表单式页面重构为左右分栏布局,左侧展示供应商列表,右侧展示详情/编辑/供货清单/异议标签页 2. 新增供应商选中默认逻辑,刷新页面保持选中状态 3. 补充供货清单、订单异议的列表展示与数据加载逻辑 4. 优化搜索、分页、新增编辑删除的交互流程与样式
This commit is contained in:
@@ -168,8 +168,8 @@ export default {
|
||||
}
|
||||
|
||||
.supplier-name {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
font-size: 8px;
|
||||
font-weight: 200;
|
||||
color: #303133;
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.4;
|
||||
|
||||
@@ -1,103 +1,829 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
|
||||
<el-form-item label="供应商名称" prop="supplierName">
|
||||
<el-input v-model="queryParams.supplierName" placeholder="请输入供应商名称" clearable @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table v-loading="loading" :data="list" @selection-change="s => { this.multiple = !s.length; this.ids = s.map(r => r.supplierId) }">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="供应商名称" prop="supplierName" />
|
||||
<el-table-column label="联系人" prop="contact" width="100" />
|
||||
<el-table-column label="手机" prop="phone" width="130" />
|
||||
<el-table-column label="邮箱" prop="email" />
|
||||
<el-table-column label="地址" prop="address" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status === '0' ? 'success' : 'danger'">{{ scope.row.status === '0' ? '启用' : '禁用' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
<div class="supplier-manage">
|
||||
<!-- ====== 左侧面板:供应商列表 ====== -->
|
||||
<div class="left-panel">
|
||||
<!-- Header -->
|
||||
<div class="panel-header">
|
||||
<span class="panel-title">供应商列表</span>
|
||||
<div class="search-row">
|
||||
<el-input
|
||||
v-model="queryParams.supplierName"
|
||||
placeholder="搜索供应商名称"
|
||||
size="small"
|
||||
prefix-icon="el-icon-search"
|
||||
clearable
|
||||
@keyup.enter.native="handleSearch"
|
||||
/>
|
||||
<el-button type="primary" size="small" icon="el-icon-search" @click="handleSearch" />
|
||||
<el-button type="primary" size="small" icon="el-icon-plus" @click="handleAdd" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="title" :visible.sync="open" width="580px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="90px">
|
||||
<!-- Body: 列表 -->
|
||||
<el-scrollbar class="list-scrollbar">
|
||||
<div
|
||||
v-for="item in list"
|
||||
:key="item.supplierId"
|
||||
class="supplier-item"
|
||||
:class="{ active: currentSupplier && currentSupplier.supplierId === item.supplierId }"
|
||||
@click="selectSupplier(item)"
|
||||
>
|
||||
<div class="item-left">
|
||||
<div class="item-code">{{ formatCode(item.supplierId) }}</div>
|
||||
<div class="item-name">{{ item.supplierName }}</div>
|
||||
<div class="item-contact">
|
||||
<span v-if="item.contact">{{ item.contact }}</span>
|
||||
<span v-if="item.phone" class="contact-sep">/</span>
|
||||
<span v-if="item.phone">{{ item.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-right">
|
||||
<el-button
|
||||
type="danger"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
@click.stop="handleDelete(item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!list.length && !loading" class="empty-list">暂无数据</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<!-- Footer: 分页 -->
|
||||
<div class="panel-footer">
|
||||
<el-pagination
|
||||
small
|
||||
:total="total"
|
||||
:page-size="queryParams.pageSize"
|
||||
:current-page.sync="queryParams.pageNum"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 右侧面板:供应商详情 ====== -->
|
||||
<div class="right-panel">
|
||||
<template v-if="currentSupplier">
|
||||
<el-tabs v-model="activeTab" class="detail-tabs">
|
||||
<!-- Tab 1: 供应商详情(只读) -->
|
||||
<el-tab-pane label="供应商详情" name="detail">
|
||||
<div class="detail-grid">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">供应商编号</span>
|
||||
<span class="detail-value">{{ formatCode(currentSupplier.supplierId) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">供应商名称</span>
|
||||
<span class="detail-value">{{ currentSupplier.supplierName || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">联系人</span>
|
||||
<span class="detail-value">{{ currentSupplier.contact || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">手机</span>
|
||||
<span class="detail-value">{{ currentSupplier.phone || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">邮箱</span>
|
||||
<span class="detail-value">{{ currentSupplier.email || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">地址</span>
|
||||
<span class="detail-value">{{ currentSupplier.address || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">状态</span>
|
||||
<span class="detail-value">
|
||||
<el-tag :type="currentSupplier.status === '0' ? 'success' : 'danger'" size="small">
|
||||
{{ currentSupplier.status === '0' ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- Tab 2: 信息编辑 -->
|
||||
<el-tab-pane label="信息编辑" name="edit">
|
||||
<el-form ref="editForm" :model="editForm" :rules="editRules" label-width="100px" size="small" class="edit-form">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="供应商名称" prop="supplierName">
|
||||
<el-input v-model="editForm.supplierName" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人" prop="contact">
|
||||
<el-input v-model="editForm.contact" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机" prop="phone">
|
||||
<el-input v-model="editForm.phone" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="editForm.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="地址" prop="address">
|
||||
<el-input v-model="editForm.address" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="editForm.status">
|
||||
<el-radio label="0">启用</el-radio>
|
||||
<el-radio label="1">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="small" @click="handleSaveEdit">保存</el-button>
|
||||
<el-button size="small" @click="resetEditForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- Tab 3: 供货清单 -->
|
||||
<el-tab-pane label="供货清单" name="orders">
|
||||
<div class="tab-content">
|
||||
<el-table :data="orderList" v-loading="orderLoading" border size="small" style="width:100%">
|
||||
<el-table-column label="采购单号" prop="poNo" min-width="150" />
|
||||
<el-table-column label="供应商" prop="supplierName" min-width="140" />
|
||||
<el-table-column label="采购标题" prop="rfqTitle" min-width="160" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="总金额" prop="totalAmount" width="120" align="right">
|
||||
<template slot-scope="scope">
|
||||
<span class="price-text">{{ scope.row.totalAmount ? '¥' + Number(scope.row.totalAmount).toLocaleString() : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交货日期" prop="deliveryDate" width="110" align="center" />
|
||||
<el-table-column label="状态" width="90" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="orderStatusType(scope.row.status)" size="small">{{ orderStatusText(scope.row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="!orderList.length && !orderLoading" class="table-empty">暂无供货记录</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- Tab 4: 订单异议 -->
|
||||
<el-tab-pane label="订单异议" name="objections">
|
||||
<div class="tab-content">
|
||||
<el-table :data="objectionList" v-loading="objectionLoading" border size="small" style="width:100%">
|
||||
<el-table-column label="采购单号" prop="poNo" min-width="150" />
|
||||
<el-table-column label="供应商" prop="supplierName" min-width="140" />
|
||||
<el-table-column label="异议原因" prop="reason" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="objStatusType(scope.row.status)" size="small">{{ objStatusText(scope.row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="处理结果" prop="resolution" min-width="160" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="提交时间" prop="createTime" width="160" align="center" />
|
||||
</el-table>
|
||||
<div v-if="!objectionList.length && !objectionLoading" class="table-empty">暂无订单异议</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<!-- 未选中时占位 -->
|
||||
<div v-else class="right-placeholder">
|
||||
<i class="el-icon-document"></i>
|
||||
<p>请从左侧选择一个供应商查看详情</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 新增供应商弹窗 ====== -->
|
||||
<el-dialog title="新增供应商" :visible.sync="addDialogOpen" width="580px" append-to-body @close="cancelAdd">
|
||||
<el-form ref="addForm" :model="addForm" :rules="editRules" label-width="100px" size="small">
|
||||
<el-form-item label="供应商名称" prop="supplierName">
|
||||
<el-input v-model="form.supplierName" placeholder="请输入供应商名称" />
|
||||
<el-input v-model="addForm.supplierName" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人" prop="contact"><el-input v-model="form.contact" /></el-form-item>
|
||||
<el-form-item label="联系人" prop="contact">
|
||||
<el-input v-model="addForm.contact" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机" prop="phone"><el-input v-model="form.phone" /></el-form-item>
|
||||
<el-form-item label="手机" prop="phone">
|
||||
<el-input v-model="addForm.phone" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="addForm.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="地址" prop="address">
|
||||
<el-input v-model="addForm.address" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="邮箱" prop="email"><el-input v-model="form.email" /></el-form-item>
|
||||
<el-form-item label="地址" prop="address"><el-input v-model="form.address" /></el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
<el-button @click="cancelAdd">取消</el-button>
|
||||
<el-button type="primary" @click="submitAdd">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listSupplier, getSupplier, addSupplier, updateSupplier, delSupplier } from "@/api/bid/supplier";
|
||||
import { listPurchaseorder } from "@/api/bid/purchaseorder";
|
||||
import { listObjection } from "@/api/bid/objection";
|
||||
|
||||
export default {
|
||||
name: "Supplier",
|
||||
name: "SupplierManage",
|
||||
data() {
|
||||
return {
|
||||
loading: false, multiple: true, total: 0, list: [], ids: [],
|
||||
open: false, title: "",
|
||||
queryParams: { pageNum: 1, pageSize: 10, supplierName: null },
|
||||
form: {},
|
||||
rules: { supplierName: [{ required: true, message: "供应商名称不能为空", trigger: "blur" }] }
|
||||
// ---- 左侧列表 ----
|
||||
loading: false,
|
||||
list: [],
|
||||
total: 0,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
supplierName: null
|
||||
},
|
||||
currentSupplier: null,
|
||||
|
||||
// ---- 右侧Tab ----
|
||||
activeTab: "detail",
|
||||
|
||||
// ---- 编辑表单 ----
|
||||
editForm: {},
|
||||
editRules: {
|
||||
supplierName: [
|
||||
{ required: true, message: "供应商名称不能为空", trigger: "blur" }
|
||||
]
|
||||
},
|
||||
|
||||
// ---- 新增弹窗 ----
|
||||
addDialogOpen: false,
|
||||
addForm: {},
|
||||
|
||||
// ---- 供货清单 ----
|
||||
orderLoading: false,
|
||||
orderList: [],
|
||||
|
||||
// ---- 订单异议 ----
|
||||
objectionLoading: false,
|
||||
objectionList: []
|
||||
};
|
||||
},
|
||||
created() { this.getList(); },
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/* ========== 左侧列表 ========== */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listSupplier(this.queryParams).then(res => { this.list = res.rows; this.total = res.total; this.loading = false; });
|
||||
},
|
||||
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
|
||||
resetQuery() { this.resetForm("queryForm"); this.handleQuery(); },
|
||||
handleAdd() { this.form = { status: "0" }; this.open = true; this.title = "新增供应商"; },
|
||||
handleUpdate(row) {
|
||||
getSupplier(row.supplierId).then(res => { this.form = res.data; this.open = true; this.title = "修改供应商"; });
|
||||
},
|
||||
handleDelete(row) {
|
||||
const ids = row.supplierId || this.ids.join(",");
|
||||
this.$modal.confirm("确认删除?").then(() => delSupplier(ids)).then(() => { this.getList(); this.$modal.msgSuccess("删除成功"); });
|
||||
},
|
||||
cancel() { this.open = false; },
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (!valid) return;
|
||||
const action = this.form.supplierId ? updateSupplier : addSupplier;
|
||||
action(this.form).then(() => { this.$modal.msgSuccess("操作成功"); this.open = false; this.getList(); });
|
||||
listSupplier(this.queryParams).then(res => {
|
||||
this.list = res.rows || [];
|
||||
this.total = res.total || 0;
|
||||
this.loading = false;
|
||||
// 默认选中第一条
|
||||
if (this.list.length && !this.currentSupplier) {
|
||||
this.selectSupplier(this.list[0]);
|
||||
} else if (this.list.length && this.currentSupplier) {
|
||||
// 刷新后保持选中(如果还在列表中)
|
||||
const still = this.list.find(
|
||||
s => s.supplierId === this.currentSupplier.supplierId
|
||||
);
|
||||
if (still) {
|
||||
this.currentSupplier = still;
|
||||
} else {
|
||||
this.selectSupplier(this.list[0]);
|
||||
}
|
||||
} else {
|
||||
this.currentSupplier = null;
|
||||
this.orderList = [];
|
||||
this.objectionList = [];
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
handleSearch() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
handleSizeChange(size) {
|
||||
this.queryParams.pageSize = size;
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
handleCurrentChange(page) {
|
||||
this.queryParams.pageNum = page;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
selectSupplier(item) {
|
||||
this.currentSupplier = item;
|
||||
this.activeTab = "detail";
|
||||
// 初始化编辑表单
|
||||
this.editForm = {
|
||||
supplierId: item.supplierId,
|
||||
supplierName: item.supplierName,
|
||||
contact: item.contact,
|
||||
phone: item.phone,
|
||||
email: item.email,
|
||||
address: item.address,
|
||||
status: item.status || "0"
|
||||
};
|
||||
// 清空子列表
|
||||
this.orderList = [];
|
||||
this.objectionList = [];
|
||||
},
|
||||
|
||||
formatCode(id) {
|
||||
if (!id) return 'KLP--';
|
||||
return 'KLP' + String(id).padStart(2, '0');
|
||||
},
|
||||
|
||||
/* ========== 新增 ========== */
|
||||
handleAdd() {
|
||||
this.addForm = { status: "0" };
|
||||
this.addDialogOpen = true;
|
||||
},
|
||||
|
||||
cancelAdd() {
|
||||
this.addDialogOpen = false;
|
||||
this.addForm = {};
|
||||
this.$refs.addForm && this.$refs.addForm.resetFields();
|
||||
},
|
||||
|
||||
submitAdd() {
|
||||
this.$refs.addForm.validate(valid => {
|
||||
if (!valid) return;
|
||||
addSupplier(this.addForm).then(() => {
|
||||
this.$message.success("新增成功");
|
||||
this.addDialogOpen = false;
|
||||
this.addForm = {};
|
||||
this.getList();
|
||||
}).catch(err => {
|
||||
this.$message.error("新增失败:" + (err.msg || "未知错误"));
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/* ========== 删除 ========== */
|
||||
handleDelete(row) {
|
||||
this.$confirm("确认删除供应商【" + row.supplierName + "】?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
delSupplier(row.supplierId).then(() => {
|
||||
this.$message.success("删除成功");
|
||||
if (this.currentSupplier && this.currentSupplier.supplierId === row.supplierId) {
|
||||
this.currentSupplier = null;
|
||||
}
|
||||
this.getList();
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
/* ========== 编辑保存 ========== */
|
||||
handleSaveEdit() {
|
||||
this.$refs.editForm.validate(valid => {
|
||||
if (!valid) return;
|
||||
updateSupplier(this.editForm).then(() => {
|
||||
this.$message.success("保存成功");
|
||||
// 刷新当前供应商数据
|
||||
getSupplier(this.editForm.supplierId).then(res => {
|
||||
this.currentSupplier = res.data;
|
||||
this.editForm = {
|
||||
supplierId: res.data.supplierId,
|
||||
supplierName: res.data.supplierName,
|
||||
contact: res.data.contact,
|
||||
phone: res.data.phone,
|
||||
email: res.data.email,
|
||||
address: res.data.address,
|
||||
status: res.data.status || "0"
|
||||
};
|
||||
});
|
||||
}).catch(err => {
|
||||
this.$message.error("保存失败:" + (err.msg || "未知错误"));
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
resetEditForm() {
|
||||
if (this.currentSupplier) {
|
||||
this.editForm = {
|
||||
supplierId: this.currentSupplier.supplierId,
|
||||
supplierName: this.currentSupplier.supplierName,
|
||||
contact: this.currentSupplier.contact,
|
||||
phone: this.currentSupplier.phone,
|
||||
email: this.currentSupplier.email,
|
||||
address: this.currentSupplier.address,
|
||||
status: this.currentSupplier.status || "0"
|
||||
};
|
||||
}
|
||||
this.$refs.editForm && this.$refs.editForm.resetFields();
|
||||
},
|
||||
|
||||
/* ========== Tab: 供货清单 ========== */
|
||||
loadOrders() {
|
||||
if (!this.currentSupplier) return;
|
||||
this.orderLoading = true;
|
||||
listPurchaseorder({ supplierId: this.currentSupplier.supplierId, pageSize: 200 })
|
||||
.then(res => {
|
||||
this.orderList = res.rows || [];
|
||||
this.orderLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.orderLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
orderStatusType(status) {
|
||||
const map = { confirmed: "success", pending: "warning", cancelled: "danger", draft: "info" };
|
||||
return map[status] || "info";
|
||||
},
|
||||
|
||||
orderStatusText(status) {
|
||||
const map = { confirmed: "已确认", pending: "待处理", cancelled: "已取消", draft: "草稿" };
|
||||
return map[status] || status || "-";
|
||||
},
|
||||
|
||||
/* ========== Tab: 订单异议 ========== */
|
||||
loadObjections() {
|
||||
if (!this.currentSupplier) return;
|
||||
this.objectionLoading = true;
|
||||
listObjection({ supplierId: this.currentSupplier.supplierId, pageSize: 200 })
|
||||
.then(res => {
|
||||
this.objectionList = res.rows || [];
|
||||
this.objectionLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.objectionLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
objStatusType(status) {
|
||||
const map = { resolved: "success", processing: "primary", pending: "warning", rejected: "danger" };
|
||||
return map[status] || "info";
|
||||
},
|
||||
|
||||
objStatusText(status) {
|
||||
const map = { resolved: "已解决", processing: "处理中", pending: "待处理", rejected: "已拒绝" };
|
||||
return map[status] || status || "-";
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeTab(val) {
|
||||
if (val === "orders" && !this.orderList.length) {
|
||||
this.loadOrders();
|
||||
}
|
||||
if (val === "objections" && !this.objectionList.length) {
|
||||
this.loadObjections();
|
||||
}
|
||||
},
|
||||
currentSupplier() {
|
||||
// 切换供应商时清除子列表
|
||||
this.orderList = [];
|
||||
this.objectionList = [];
|
||||
// 如果当前在采购单或异议Tab,自动加载
|
||||
if (this.activeTab === "orders") {
|
||||
this.$nextTick(() => this.loadOrders());
|
||||
}
|
||||
if (this.activeTab === "objections") {
|
||||
this.$nextTick(() => this.loadObjections());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* ====== 整体布局 ====== */
|
||||
.supplier-manage {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
background: #f5f7fa;
|
||||
min-height: calc(100vh - 84px);
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* ====== 左侧面板 ====== */
|
||||
.left-panel {
|
||||
width: 340px;
|
||||
flex-shrink: 0;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 108px);
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
padding: 16px 16px 12px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.search-row .el-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 列表滚动区 */
|
||||
.list-scrollbar {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 供应商列表项 */
|
||||
.supplier-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.supplier-item:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.supplier-item.active {
|
||||
background-color: #ecf5ff;
|
||||
border-left: 3px solid #409eff;
|
||||
padding-left: 13px;
|
||||
}
|
||||
|
||||
.item-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.item-code {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin-bottom: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.item-contact {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.contact-sep {
|
||||
margin: 0 4px;
|
||||
color: #dcdfe6;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
flex-shrink: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
text-align: center;
|
||||
color: #c0c4cc;
|
||||
padding: 40px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 底部分页(在 340px 面板内塞下 total+sizes+prev+pager+next+jumper) */
|
||||
.panel-footer {
|
||||
padding: 4px 6px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel-footer .el-pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 总条数 */
|
||||
.panel-footer .el-pagination >>> .el-pagination__total {
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
margin-right: 2px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 每页条数下拉 */
|
||||
.panel-footer .el-pagination >>> .el-pagination__sizes {
|
||||
margin-right: 2px;
|
||||
}
|
||||
.panel-footer .el-pagination >>> .el-pagination__sizes .el-input--mini .el-input__inner {
|
||||
font-size: 11px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
width: 50px;
|
||||
padding: 0 18px 0 4px;
|
||||
}
|
||||
.panel-footer .el-pagination >>> .el-pagination__sizes .el-input .el-select__caret {
|
||||
line-height: 22px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* 翻页按钮 */
|
||||
.panel-footer .el-pagination >>> .btn-prev,
|
||||
.panel-footer .el-pagination >>> .btn-next {
|
||||
min-width: 20px;
|
||||
padding: 0;
|
||||
}
|
||||
.panel-footer .el-pagination >>> .btn-prev i,
|
||||
.panel-footer .el-pagination >>> .btn-next i {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* 页码按钮 */
|
||||
.panel-footer .el-pagination >>> .el-pager li {
|
||||
min-width: 20px;
|
||||
font-size: 11px;
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
/* 跳转区域 */
|
||||
.panel-footer .el-pagination >>> .el-pagination__jump {
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
margin-left: 2px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.panel-footer .el-pagination >>> .el-pagination__jump .el-input--mini {
|
||||
width: auto;
|
||||
}
|
||||
.panel-footer .el-pagination >>> .el-pagination__jump .el-input__inner {
|
||||
font-size: 11px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
width: 36px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
/* ====== 右侧面板 ====== */
|
||||
.right-panel {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
min-height: calc(100vh - 108px);
|
||||
}
|
||||
|
||||
/* Tab 导航自定义 */
|
||||
.detail-tabs >>> .el-tabs__header {
|
||||
margin: 0;
|
||||
padding: 0 16px;
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.detail-tabs >>> .el-tabs__item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
padding: 0 18px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.detail-tabs >>> .el-tabs__item.is-active {
|
||||
color: #409eff;
|
||||
background: #ecf5ff;
|
||||
border-radius: 4px 4px 0 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.detail-tabs >>> .el-tabs__item:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.detail-tabs >>> .el-tabs__active-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.detail-tabs >>> .el-tabs__content {
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
/* 详情网格(两列) */
|
||||
.detail-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0 40px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
width: 100px;
|
||||
flex-shrink: 0;
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
flex: 1;
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
min-width: 0;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* 编辑表单 */
|
||||
.edit-form {
|
||||
max-width: 640px;
|
||||
}
|
||||
|
||||
/* 表格内容区 */
|
||||
.tab-content {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.table-empty {
|
||||
text-align: center;
|
||||
color: #c0c4cc;
|
||||
padding: 40px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 价格 */
|
||||
.price-text {
|
||||
color: #f56c6c;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 右侧占位 */
|
||||
.right-placeholder {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: calc(100vh - 160px);
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
.right-placeholder i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.right-placeholder p {
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user