<!DOCTYPE html>
|
<html lang="en">
|
<head>
|
<meta charset="UTF-8">
|
<title>主表与子表详情页面</title>
|
<link rel="stylesheet" href="../../static/css/element.css">
|
<link rel="stylesheet" href="../../static/css/element-ui.css">
|
<link rel="icon" href="../../static/images/favicon.ico" type="image/x-icon">
|
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
|
<script type="text/javascript" src="../../static/js/common.js"></script>
|
<script type="text/javascript" src="../../static/js/vue.min.js"></script>
|
<script type="text/javascript" src="../../static/js/element.js"></script>
|
<style>
|
.container {
|
padding: 20px;
|
width: 100%;
|
max-width: 1200px;
|
margin: 0 auto;
|
}
|
.table-container {
|
margin-bottom: 20px;
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
border-radius: 4px;
|
overflow: hidden;
|
}
|
.detail-dialog .el-dialog__body {
|
padding: 20px;
|
}
|
.pagination-container {
|
margin-top: 15px;
|
text-align: right;
|
}
|
.operation-cell {
|
display: flex;
|
justify-content: center;
|
gap: 8px;
|
}
|
/* 搜索栏样式 */
|
.search-container {
|
background: #f5f7fa;
|
padding: 15px;
|
margin-bottom: 20px;
|
border-radius: 4px;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
}
|
.search-form {
|
display: flex;
|
flex-wrap: wrap;
|
align-items: center;
|
gap: 15px;
|
}
|
.search-item {
|
display: flex;
|
align-items: center;
|
margin-right: 15px;
|
}
|
.search-label {
|
min-width: 80px;
|
text-align: right;
|
margin-right: 10px;
|
font-size: 14px;
|
color: #606266;
|
}
|
.search-actions {
|
display: flex;
|
gap: 10px;
|
margin-left: auto;
|
}
|
</style>
|
</head>
|
<body>
|
<div id="app" style="display: flex;justify-content: center;flex-wrap: wrap;">
|
<!-- 搜索栏 -->
|
<div class="search-container" style="width: 100%;">
|
<el-form :inline="true" class="search-form">
|
<div class="search-item">
|
<span class="search-label">组货单号:</span>
|
<el-input
|
v-model="searchForm.A1"
|
placeholder="请输入组货单号"
|
clearable
|
style="width: 150px;"
|
@keyup.enter.native="handleSearch"
|
></el-input>
|
</div>
|
<div class="search-item">
|
<span class="search-label">客户名称:</span>
|
<el-input
|
v-model="searchForm.A2"
|
placeholder="请输入客户名称"
|
clearable
|
style="width: 180px;"
|
@keyup.enter.native="handleSearch"
|
></el-input>
|
</div>
|
<div class="search-item">
|
<span class="search-label">状态:</span>
|
<el-input
|
v-model="searchForm.A3"
|
placeholder="请输入状态"
|
clearable
|
style="width: 150px;"
|
@keyup.enter.native="handleSearch"
|
></el-input>
|
</div>
|
<div class="search-item">
|
<span class="search-label">属性A4:</span>
|
<el-input
|
v-model="searchForm.A4"
|
placeholder="请输入属性A4"
|
clearable
|
style="width: 150px;"
|
@keyup.enter.native="handleSearch"
|
></el-input>
|
</div>
|
<div class="search-actions">
|
<el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
</div>
|
</el-form>
|
</div>
|
|
<!-- 主表A -->
|
<div class="table-container" style="width: 100%;">
|
<el-table
|
border
|
ref="mainTable"
|
:data="tableDataA"
|
highlight-current-row
|
style="width: 100%"
|
v-loading="loading">
|
<el-table-column prop="A1" label="组货单号" width="100" align="center"></el-table-column>
|
<el-table-column prop="A2" label="客户名称" min-width="120" align="center"></el-table-column>
|
<el-table-column prop="A3" label="状态" min-width="120" align="center"></el-table-column>
|
<el-table-column prop="A4" label="属性A4" min-width="120" align="center"></el-table-column>
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
<template slot-scope="scope">
|
<div class="operation-cell">
|
<el-button
|
type="primary"
|
size="mini"
|
@click="showDetail(scope.row)">
|
明细查看
|
</el-button>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 分页控件 -->
|
<div class="pagination-container">
|
<el-pagination
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
:current-page="currentPage"
|
:page-sizes="[10, 20, 50, 100]"
|
:page-size="pageSize"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="total">
|
</el-pagination>
|
</div>
|
</div>
|
|
<!-- 子表B详情弹窗 -->
|
<el-dialog
|
title="明细"
|
:visible.sync="detailDialogVisible"
|
width="80%"
|
class="detail-dialog"
|
@close="closeDetailDialog">
|
<div v-if="currentRow">
|
<h3>组货单主表 (组货单号: {{ currentRow.A1 }})</h3>
|
<el-descriptions :column="2" border>
|
<el-descriptions-item label="客户名称">{{ currentRow.A2 }}</el-descriptions-item>
|
<el-descriptions-item label="状态">{{ currentRow.A3 }}</el-descriptions-item>
|
<el-descriptions-item label="属性A4">{{ currentRow.A4 }}</el-descriptions-item>
|
</el-descriptions>
|
|
<h3 style="margin-top: 20px;">组货单明细</h3>
|
<el-table
|
border
|
:data="tableDataB"
|
style="width: 100%"
|
v-loading="detailLoading">
|
<el-table-column prop="B2" label="客户名称" min-width="120" align="center"></el-table-column>
|
<el-table-column prop="B3" label="状态" min-width="120" align="center"></el-table-column>
|
<el-table-column prop="B4" label="流水号" min-width="120" align="center"></el-table-column>
|
<!-- 可根据实际需求添加更多子表列 -->
|
</el-table>
|
|
<!-- 子表分页 -->
|
<div class="pagination-container">
|
<el-pagination
|
@size-change="handleDetailSizeChange"
|
@current-change="handleDetailCurrentChange"
|
:current-page="detailCurrentPage"
|
:page-sizes="[5, 10, 20]"
|
:page-size="detailPageSize"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="detailTotal">
|
</el-pagination>
|
</div>
|
</div>
|
|
<div slot="footer">
|
<el-button @click="closeDetailDialog">关闭</el-button>
|
</div>
|
</el-dialog>
|
</div>
|
|
<script>
|
var app = new Vue({
|
el: '#app',
|
data: {
|
// 搜索表单
|
searchForm: {
|
A1: '',
|
A2: '',
|
A3: '',
|
A4: ''
|
},
|
// 主表A数据
|
tableDataA: [],
|
// 子表B数据
|
tableDataB: [],
|
// 分页相关
|
currentPage: 1,
|
pageSize: 10,
|
total: 0,
|
// 详情弹窗控制
|
detailDialogVisible: false,
|
currentRow: null,
|
// 子表分页
|
detailCurrentPage: 1,
|
detailPageSize: 5,
|
detailTotal: 0,
|
// 加载状态
|
loading: false,
|
detailLoading: false,
|
// 原始数据备份(用于搜索)
|
originalTableDataA: []
|
},
|
created() {
|
this.init();
|
},
|
methods: {
|
init() {
|
setInterval(() => {
|
this.getTableDataA();
|
}, 2000);
|
},
|
|
// 获取主表A数据
|
getTableDataA() {
|
let that = this;
|
that.loading = true;
|
|
// 模拟API调用 - 替换为实际API
|
$.ajax({
|
url: baseUrl + "/api/tableA/data",
|
headers: {
|
'token': localStorage.getItem('token')
|
},
|
data: {
|
page: that.currentPage,
|
size: that.pageSize
|
},
|
dataType: 'json',
|
contentType: 'application/json;charset=UTF-8',
|
method: 'post',
|
success: function (res) {
|
that.tableDataA = res.data || [];
|
that.originalTableDataA = JSON.parse(JSON.stringify(that.tableDataA)); // 备份原始数据
|
that.total = res.total || 0;
|
that.loading = false;
|
},
|
error: function() {
|
that.loading = false;
|
// 实际项目中应使用真实API,这里使用模拟数据
|
that.mockTableAData();
|
}
|
});
|
},
|
|
// 获取子表B数据
|
getTableDataB(A1) {
|
let that = this;
|
that.detailLoading = true;
|
|
// 模拟API调用 - 替换为实际API
|
$.ajax({
|
url: baseUrl + "/api/tableB/data",
|
headers: {
|
'token': localStorage.getItem('token')
|
},
|
data: {
|
A1: A1,
|
page: that.detailCurrentPage,
|
size: that.detailPageSize
|
},
|
dataType: 'json',
|
contentType: 'application/json;charset=UTF-8',
|
method: 'post',
|
success: function (res) {
|
that.tableDataB = res.data || [];
|
that.detailTotal = res.total || 0;
|
that.detailLoading = false;
|
},
|
error: function() {
|
that.detailLoading = false;
|
// 实际项目中应使用真实API,这里使用模拟数据
|
that.mockTableBData(A1);
|
}
|
});
|
},
|
|
// 搜索处理[1,5](@ref)
|
handleSearch() {
|
this.currentPage = 1;
|
this.loading = true;
|
|
// 如果有后端搜索API,可以调用后端搜索
|
// 这里使用前端过滤作为示例
|
if (this.isSearchFormEmpty()) {
|
// 如果搜索条件为空,显示所有数据
|
this.getTableDataA();
|
} else {
|
// 使用前端过滤进行搜索[2,4](@ref)
|
this.filterTableData();
|
}
|
},
|
|
// 前端过滤表格数据[2,4](@ref)
|
filterTableData() {
|
let that = this;
|
// 模拟API调用 - 实际项目中可以调用后端搜索接口
|
$.ajax({
|
url: baseUrl + "/api/tableA/search",
|
headers: {
|
'token': localStorage.getItem('token')
|
},
|
data: {
|
...that.searchForm,
|
page: that.currentPage,
|
size: that.pageSize
|
},
|
dataType: 'json',
|
contentType: 'application/json;charset=UTF-8',
|
method: 'post',
|
success: function (res) {
|
that.tableDataA = res.data || [];
|
that.total = res.total || 0;
|
that.loading = false;
|
},
|
error: function() {
|
that.loading = false;
|
// 如果API调用失败,使用前端过滤作为备选方案
|
that.frontendFilter();
|
}
|
});
|
},
|
|
// 前端过滤备选方案[2,4](@ref)
|
frontendFilter() {
|
const filteredData = this.originalTableDataA.filter(item => {
|
// 检查每个搜索条件[4](@ref)
|
const matchA1 = !this.searchForm.A1 ||
|
(item.A1 && item.A1.toString().toLowerCase().includes(this.searchForm.A1.toLowerCase()));
|
const matchA2 = !this.searchForm.A2 ||
|
(item.A2 && item.A2.toString().toLowerCase().includes(this.searchForm.A2.toLowerCase()));
|
const matchA3 = !this.searchForm.A3 ||
|
(item.A3 && item.A3.toString().toLowerCase().includes(this.searchForm.A3.toLowerCase()));
|
const matchA4 = !this.searchForm.A4 ||
|
(item.A4 && item.A4.toString().toLowerCase().includes(this.searchForm.A4.toLowerCase()));
|
|
return matchA1 && matchA2 && matchA3 && matchA4;
|
});
|
|
this.tableDataA = filteredData;
|
this.total = filteredData.length;
|
this.loading = false;
|
},
|
|
// 重置搜索条件[5](@ref)
|
handleReset() {
|
this.searchForm = {
|
A1: '',
|
A2: '',
|
A3: '',
|
A4: ''
|
};
|
this.currentPage = 1;
|
this.getTableDataA();
|
},
|
|
// 检查搜索条件是否为空
|
isSearchFormEmpty() {
|
return !this.searchForm.A1 && !this.searchForm.A2 &&
|
!this.searchForm.A3 && !this.searchForm.A4;
|
},
|
|
// 显示详情弹窗
|
showDetail(row) {
|
this.currentRow = row;
|
this.detailDialogVisible = true;
|
this.detailCurrentPage = 1;
|
this.getTableDataB(row.A1);
|
},
|
|
// 关闭详情弹窗
|
closeDetailDialog() {
|
this.detailDialogVisible = false;
|
this.currentRow = null;
|
this.tableDataB = [];
|
},
|
|
// 主表分页大小改变
|
handleSizeChange(val) {
|
this.pageSize = val;
|
this.currentPage = 1;
|
this.getTableDataA();
|
},
|
|
// 主表页码改变
|
handleCurrentChange(val) {
|
this.currentPage = val;
|
this.getTableDataA();
|
},
|
|
// 子表分页大小改变
|
handleDetailSizeChange(val) {
|
this.detailPageSize = val;
|
this.detailCurrentPage = 1;
|
if (this.currentRow) {
|
this.getTableDataB(this.currentRow.A1);
|
}
|
},
|
|
// 子表页码改变
|
handleDetailCurrentChange(val) {
|
this.detailCurrentPage = val;
|
if (this.currentRow) {
|
this.getTableDataB(this.currentRow.A1);
|
}
|
},
|
|
// 模拟主表数据 - 实际项目中应删除
|
mockTableAData() {
|
this.tableDataA = [
|
{ A1: '1001', A2: '示例数据A2-1', A3: '示例数据A3-1', A4: '示例数据A4-1' },
|
{ A1: '1002', A2: '示例数据A2-2', A3: '示例数据A3-2', A4: '示例数据A4-2' },
|
{ A1: '1003', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '10033', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '100333', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '10032', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '10031', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '100312', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '1003123', A2: '示例数据A2-3', A3: '示例数据A3-3', A4: '示例数据A4-3' },
|
{ A1: '1004', A2: '示例数据A2-4', A3: '示例数据A3-4', A4: '示例数据A4-4' }
|
];
|
this.originalTableDataA = JSON.parse(JSON.stringify(this.tableDataA)); // 备份原始数据
|
this.total = 4;
|
this.loading = false;
|
},
|
|
// 模拟子表数据 - 实际项目中应删除
|
mockTableBData(A1) {
|
this.tableDataB = [
|
{ B2: `子表数据B2-${A1}-1`, B3: `子表数据B3-${A1}-1`, B4: `子表数据B4-${A1}-1` },
|
{ B2: `子表数据B2-${A1}-2`, B3: `子表数据B3-${A1}-2`, B4: `子表数据B4-${A1}-2` },
|
{ B2: `子表数据B2-${A1}-3`, B3: `子表数据B3-${A1}-3`, B4: `子表数据B4-${A1}-3` }
|
];
|
this.detailTotal = 3;
|
this.detailLoading = false;
|
}
|
}
|
});
|
</script>
|
</body>
|
</html>
|