feat(aps-plan): 新增排产单分页、批量操作与转单功能

1. 为PlanSheetList添加分页导航按钮与空状态提示
2. 优化排产单列表项样式与布局
3. 为排产单详情页新增批量删除、批量转单功能
4. 新增转单对话框,支持单条/批量转单到其他排产单
5. 优化批量新增弹窗,新增合同选择/明细选择双tab页
6. 修复部分组件的换行与代码格式问题
7. 优化ContractSelect组件的代码排版
This commit is contained in:
2026-05-14 13:14:53 +08:00
parent 4a5b9544a4
commit 7a3aaf1973
3 changed files with 595 additions and 130 deletions

View File

@@ -6,7 +6,8 @@
:label="item.contractCode" />
</el-select>
<!-- 编辑按钮点击打开弹窗 -->
<el-button v-if="mode == 'today'" @click="openSelectDialog" type="primary" size="small" style="margin-left: 8px; padding: 0 12px;">
<el-button v-if="mode == 'today'" @click="openSelectDialog" type="primary" size="small"
style="margin-left: 8px; padding: 0 12px;">
<i class="el-icon-setting"></i>
</el-button>
@@ -50,15 +51,16 @@
</el-table-column>
</el-table>
</el-tab-pane>
<!-- 所有合同tab -->
<el-tab-pane label="所有合同" name="all">
<div style="margin-bottom: 16px;">
<el-input v-model="searchKeyword" placeholder="搜索合同" @input="handleSearch" clearable size="small">
<el-input v-model="searchKeyword" placeholder="搜索合同" @input="handleSearch" clearable
size="small">
<el-button slot="append" icon="el-icon-search" size="small"></el-button>
</el-input>
</div>
<el-table :data="allContracts" style="width: 100%" size="mini" height="600">
<el-table-column prop="contractCode" label="合同编号" width="160" />
<el-table-column prop="contractName" label="合同名称" width="180" />
@@ -72,34 +74,25 @@
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
<el-table-column label="状态" width="80">
<template slot-scope="scope">
<el-tag v-if="isContractInList(scope.row.orderId)" type="success" size="small">已添加</el-tag>
<el-tag v-if="isContractInList(scope.row.orderId)" type="success"
size="small">已添加</el-tag>
<el-tag v-else type="info" size="small">未添加</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button
v-if="!isContractInList(scope.row.orderId)"
type="primary"
size="mini"
@click="addContract(scope.row)"
plain
>
<el-button v-if="!isContractInList(scope.row.orderId)" type="primary" size="mini"
@click="addContract(scope.row)" plain>
添加
</el-button>
<el-button
v-else
type="danger"
size="mini"
@click="removeContract(scope.row.orderId)"
plain
>
<el-button v-else type="danger" size="mini" @click="removeContract(scope.row.orderId)"
plain>
移除
</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="allContracts.length === 0" style="text-align: center; padding: 20px;">
暂无合同数据
</div>
@@ -159,16 +152,17 @@ export default {
const storedContracts = localStorage.getItem('todayContracts');
if (storedContracts) {
this.contractList = JSON.parse(storedContracts);
} else {
// 如果localStorage中没有从接口获取
this.loadContractList();
}
// else {
// 如果localStorage中没有从接口获取
this.loadContractList();
// }
} catch (error) {
console.error('Failed to load contracts from localStorage:', error);
this.loadContractList();
}
},
// 保存合同列表到localStorage
saveToLocalStorage() {
try {
@@ -177,7 +171,7 @@ export default {
console.error('Failed to save contracts to localStorage:', error);
}
},
// 加载合同列表
async loadContractList(keyword) {
if (this.mode == "all") {
@@ -200,7 +194,7 @@ export default {
// 合并合同列表,保留手动添加的合同
this.contractList = [...apiContracts, ...existingManualContracts];
// 去重,避免重复合同
this.contractList = this.contractList.filter((item, index, self) =>
this.contractList = this.contractList.filter((item, index, self) =>
index === self.findIndex(t => t.orderId === item.orderId)
);
// 保存到localStorage
@@ -213,7 +207,7 @@ export default {
// 加载所有合同供选择
await this.loadAllContracts();
},
// 加载所有合同
async loadAllContracts() {
try {
@@ -224,7 +218,7 @@ export default {
});
// 合并现有合同(包括手动添加的)
const existingContracts = this.contractList;
this.allContracts = [...res.rows || [], ...existingContracts].filter((item, index, self) =>
this.allContracts = [...res.rows || [], ...existingContracts].filter((item, index, self) =>
index === self.findIndex(t => t.orderId === item.orderId)
);
} catch (error) {
@@ -232,17 +226,17 @@ export default {
this.allContracts = [];
}
},
// 搜索合同
handleSearch() {
this.loadAllContracts();
},
// 检查合同是否在列表中
isContractInList(orderId) {
return this.contractList.some(item => item.orderId === orderId);
},
// 添加合同
addContract(contract) {
if (!this.isContractInList(contract.orderId)) {
@@ -253,13 +247,13 @@ export default {
this.saveToLocalStorage();
}
},
// 移除合同
removeContract(orderId) {
this.contractList = this.contractList.filter(item => item.orderId !== orderId);
this.saveToLocalStorage();
},
// 刷新合同列表
handleRefresh() {
this.loadContractList();

View File

@@ -5,24 +5,28 @@
<i class="el-icon-setting"></i>
</div>
<div class="custom-tabs">
<div class="tab-header">
<div
v-for="planSheet in planSheetList"
:key="planSheet.planSheetId"
class="tab-item"
:class="{ active: activeTab === planSheet.planSheetId.toString() }"
@click="handleTabClick(planSheet)"
>
<div class="tab-title">{{ planSheet.planCode }}</div>
<div class="tab-info">
<span>{{ planSheet.lineName }}</span>
<span class="date">{{ parseTime(planSheet.planDate, '{y}-{m}-{d}') }}</span>
<div class="tab-nav">
<button v-if="planSheetList.length > 0 && queryParams.pageNum > 1" class="nav-btn prev" @click="prevPage">
<i class="el-icon-arrow-left"></i>
</button>
<div class="tab-header">
<div v-for="planSheet in planSheetList" :key="planSheet.planSheetId" class="tab-item"
:class="{ active: activeTab === planSheet.planSheetId.toString() }" @click="handleTabClick(planSheet)">
<div class="tab-title">{{ planSheet.planCode }}</div>
<div class="tab-info">
<span>{{ planSheet.lineName }}</span>
<span class="date">{{ parseTime(planSheet.planDate, '{y}-{m}-{d}') }}</span>
</div>
</div>
<div v-if="planSheetList.length === 0" class="tab-item disabled">
<div class="tab-title">暂无排产单</div>
<div class="tab-info">请点击齿轮图标选择排产单</div>
</div>
</div>
<div v-if="planSheetList.length === 0" class="tab-item disabled">
<div class="tab-title">暂无排产单</div>
<div class="tab-info">请点击齿轮图标选择排产单</div>
</div>
<button v-if="planSheetList.length > 0 && queryParams.pageNum < totalPage" class="nav-btn next" @click="nextPage">
<i class="el-icon-arrow-right"></i>
</button>
</div>
</div>
</div>
@@ -37,16 +41,20 @@
</el-date-picker>
</el-form-item>
<el-form-item label="产线名称" prop="lineName">
<el-input v-model="queryParams.lineName" placeholder="请输入产线名称" clearable @keyup.enter.native="handleQuery" />
<el-input v-model="queryParams.lineName" placeholder="请输入产线名称" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="排产单号" prop="planCode">
<el-input v-model="queryParams.planCode" placeholder="请输入排产单号" clearable @keyup.enter.native="handleQuery" />
<el-input v-model="queryParams.planCode" placeholder="请输入排产单号" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="排产人" prop="scheduler">
<el-input v-model="queryParams.scheduler" placeholder="请输入排产人" clearable @keyup.enter.native="handleQuery" />
<el-input v-model="queryParams.scheduler" placeholder="请输入排产人" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-if="!readonly">新增</el-button>
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-if="!readonly">新增</el-button>
<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>
@@ -64,9 +72,12 @@
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-download" @click.stop="handleExport(scope.row)">导出</el-button>
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(scope.row)">修改</el-button>
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(scope.row)">删除</el-button>
<el-button size="mini" type="text" icon="el-icon-download"
@click.stop="handleExport(scope.row)">导出</el-button>
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-edit"
@click.stop="handleUpdate(scope.row)">修改</el-button>
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-delete"
@click.stop="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -120,6 +131,11 @@ export default {
default: false
}
},
computed: {
totalPage() {
return Math.ceil(this.total / this.queryParams.pageSize)
}
},
data() {
return {
// 按钮loading
@@ -229,6 +245,21 @@ export default {
this.planSheetDialogVisible = false;
this.handleRowClick(planSheet);
},
// 上一页
prevPage() {
if (this.queryParams.pageNum > 1) {
this.queryParams.pageNum--;
this.getList();
}
},
// 下一页
nextPage() {
if (this.queryParams.pageNum < this.totalPage) {
this.queryParams.pageNum++;
this.getList();
}
},
// 打开排产单选择对话框
openPlanSheetDialog() {
this.getList();
@@ -419,10 +450,52 @@ export default {
border-bottom: 1px solid #e4e7ed;
}
.tab-nav {
display: flex;
align-items: flex-end;
gap: 4px;
}
.nav-btn {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 52px;
border: 1px solid #e4e7ed;
border-bottom: none;
border-radius: 4px 4px 0 0;
background-color: #f9f9f9;
cursor: pointer;
transition: all 0.3s ease;
color: #606266;
}
.nav-btn:hover {
background-color: #ecf5ff;
border-color: #c6e2ff;
color: #409eff;
}
.nav-btn:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.tab-header {
display: flex;
flex-wrap: wrap;
gap: 4px;
flex: 1;
overflow: hidden;
}
.tab-pagination {
text-align: right;
font-size: 12px;
color: #909399;
margin-top: 4px;
margin-right: 8px;
}
.tab-item {

View File

@@ -10,6 +10,10 @@
<div>
<el-button type="primary" plain @click="handleAdd">新增明细</el-button>
<el-button type="success" plain @click="handleBatchAdd">批量新增</el-button>
<el-button type="danger" plain @click="handleBatchDelete"
:disabled="selectedRows.length === 0">批量删除</el-button>
<el-button type="warning" plain @click="handleBatchTransfer"
:disabled="selectedRows.length === 0">批量转单</el-button>
<el-button type="info" plain @click="getList">刷新</el-button>
</div>
</div>
@@ -35,12 +39,16 @@
</div>
<!-- 可编辑表格 -->
<el-table v-loading="loading" :data="planDetailList" style="width: 100%" border>
<el-table v-loading="loading" :data="planDetailList" style="width: 100%" border
@selection-change="handleSelectionChange">
<!-- 多选列 -->
<el-table-column type="selection" width="55" fixed="left" />
<!-- 操作列 -->
<el-table-column label="操作" align="center" width="120" fixed="left">
<el-table-column label="操作" align="center" width="160" fixed="left">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleSave(scope.row)">保存</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
<el-button type="success" size="mini" @click="handleTransfer(scope.row)">转单</el-button>
</template>
</el-table-column>
@@ -153,7 +161,8 @@
</el-table-column>
<el-table-column label="表面处理" align="center" prop="surfaceTreatmentDesc" width="100">
<template slot-scope="scope">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="scope.row.surfaceTreatment" style="background-color: #f6ffed;" />
<MemoInput storageKey="surfaceTreatmentDesc" v-model="scope.row.surfaceTreatment"
style="background-color: #f6ffed;" />
</template>
</el-table-column>
<el-table-column label="切边要求" align="center" prop="widthReq" width="100">
@@ -209,7 +218,10 @@
</el-table-column>
<el-table-column label="取样" align="center" prop="sampleReq" width="100">
<template slot-scope="scope">
<el-input v-model="scope.row.sampleReq" style="background-color: #fff0f6;" />
<el-select v-model="scope.row.sampleReq" style="width: 100%; background-color: #fff0f6;">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark">
@@ -289,72 +301,194 @@
</el-table>
</el-dialog>
<!-- 批量新增对话框 -->
<el-dialog title="批量新增" :visible.sync="batchAddDialogVisible" width="80%" append-to-body>
<div class="batch-add-content">
<!-- 合同选择 -->
<div class="contract-section">
<div class="section-title">选择合同</div>
<el-form :model="batchQueryParams" ref="batchQueryForm" size="small" :inline="true" label-width="80px">
<el-form-item label="合同号" prop="contractCode">
<el-input v-model="batchQueryParams.contractCode" placeholder="请输入合同号" style="width: 180px" />
</el-form-item>
<el-form-item label="客户">
<el-input v-model="batchQueryParams.customerName" placeholder="请输入客户名称" style="width: 180px" />
</el-form-item>
<el-form-item label="业务员">
<el-input v-model="batchQueryParams.salesman" placeholder="请输入业务员" style="width: 120px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getBatchOrderList">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetBatchQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="batchOrderLoading" :data="batchOrderList" style="width: 100%" border @row-click="selectBatchContract"
highlight-current-row>
<el-table-column prop="contractCode" label="合同号" />
<el-table-column prop="signTime" label="签订时间" width="150" />
<el-table-column prop="signLocation" label="签订地点" />
<el-table-column prop="companyName" label="客户公司" />
<el-table-column prop="salesman" label="业务员" width="100" />
<el-table-column prop="deliveryDate" label="交货日期" width="150" />
<el-table-column label="操作" width="80" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="small" @click.stop="selectBatchContract(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination background layout="prev, pager, next, jumper" :total="batchOrderTotal"
:page-size="batchQueryParams.pageSize" :current-page.sync="batchQueryParams.pageNum"
@current-change="getBatchOrderList" />
</div>
</div>
<!-- 明细选择 -->
<div class="item-section" v-if="selectedContract">
<div class="section-title">选择明细多选</div>
<el-table v-loading="batchItemLoading" :data="batchItemList" style="width: 100%" border
@selection-change="handleBatchItemSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="产品类型" align="center" prop="productType" />
<el-table-column label="成品宽度" align="center" prop="width" />
<el-table-column label="成品厚度" align="center" prop="thickness" />
<el-table-column label="成品规格" align="center" prop="finishedProductSpec" />
<el-table-column label="材质" align="center" prop="material" />
<el-table-column label="重量" align="center" prop="weight" />
<el-table-column label="卷数" align="center" prop="productNum" />
<el-table-column label="表面处理" align="center" prop="surfaceTreatment" />
<el-table-column label="包装要求" align="center" prop="packagingReq" />
<el-table-column label="切边要求" align="center" prop="edgeCuttingReq" />
<el-table-column label="用途" align="center" prop="purpose" />
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
<!-- 转单对话框 -->
<el-dialog title="转单" :visible.sync="transferDialogVisible" width="60%" append-to-body>
<div class="transfer-content">
<div class="section-title">选择目标排产单</div>
<el-form :model="transferQueryParams" ref="transferQueryForm" size="small" :inline="true" label-width="68px">
<el-form-item label="排产日期" prop="planDate">
<el-date-picker clearable v-model="transferQueryParams.planDate" type="date" value-format="yyyy-MM-dd"
placeholder="请选择排产日期">
</el-date-picker>
</el-form-item>
<el-form-item label="产线名称" prop="lineName">
<el-input v-model="transferQueryParams.lineName" placeholder="请输入产线名称" clearable />
</el-form-item>
<el-form-item label="排产单号" prop="planCode">
<el-input v-model="transferQueryParams.planCode" placeholder="请输入排产单号" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="getTransferPlanSheetList">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetTransferQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="transferLoading" :data="transferPlanSheetList" style="width: 100%" border
:highlight-current-row="true" @row-click="selectTransferPlanSheet">
<el-table-column label="排产日期" align="center" prop="planDate" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.planDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="产线名称" align="center" prop="lineName" />
<el-table-column label="排产单号" align="center" prop="planCode" />
<el-table-column label="排产人" align="center" prop="scheduler" />
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
<div class="pagination-container">
<el-pagination background layout="prev, pager, next, jumper" :total="transferTotal"
:page-size="transferQueryParams.pageSize" :current-page.sync="transferQueryParams.pageNum"
@current-change="getTransferPlanSheetList" />
</div>
</div>
<div slot="footer" class="dialog-footer">
<div v-if="isBatchTransfer">
<el-button @click="transferDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmTransfer" :disabled="!selectedTransferPlanSheet"
:loading="buttonLoading">确认批量转单</el-button>
</div>
<div v-if="transferRowData && !isBatchTransfer">
<el-button @click="transferDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmSingleTransfer" :disabled="!selectedTransferPlanSheet"
:loading="buttonLoading">确认转单</el-button>
</div>
</div>
</el-dialog>
<!-- 批量新增对话框 -->
<el-dialog title="批量新增" :visible.sync="batchAddDialogVisible" width="80%" append-to-body>
<div class="batch-add-content">
<el-tabs v-model="activeBatchTab">
<el-tab-pane label="合同选择" name="contract">
<div class="contract-section">
<div class="section-title">选择合同</div>
<el-form :model="batchQueryParams" ref="batchQueryForm" size="small" :inline="true" label-width="80px">
<el-form-item label="合同号" prop="contractCode">
<el-input v-model="batchQueryParams.contractCode" placeholder="请输入合同号" style="width: 180px" />
</el-form-item>
<el-form-item label="客户">
<el-input v-model="batchQueryParams.customerName" placeholder="请输入客户名称" style="width: 180px" />
</el-form-item>
<el-form-item label="业务员">
<el-input v-model="batchQueryParams.salesman" placeholder="请输入业务员" style="width: 120px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getBatchOrderList">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetBatchQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="batchOrderLoading" :data="batchOrderList" style="width: 100%" border
@row-click="selectBatchContract" highlight-current-row>
<el-table-column prop="contractCode" label="合同号" />
<el-table-column prop="signTime" label="签订时间" width="150" />
<el-table-column prop="signLocation" label="签订地点" />
<el-table-column prop="companyName" label="客户公司" />
<el-table-column prop="salesman" label="业务员" width="100" />
<el-table-column prop="deliveryDate" label="交货日期" width="150" />
<el-table-column label="操作" width="80" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="small" @click.stop="selectBatchContract(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination background layout="prev, pager, next, jumper" :total="batchOrderTotal"
:page-size="batchQueryParams.pageSize" :current-page.sync="batchQueryParams.pageNum"
@current-change="getBatchOrderList" />
</div>
</div>
<div class="item-section" v-if="selectedContract">
<div class="section-title">选择明细多选</div>
<el-table v-loading="batchItemLoading" :data="batchItemList" style="width: 100%" border
@selection-change="handleBatchItemSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="产品类型" align="center" prop="productType" />
<el-table-column label="成品宽度" align="center" prop="width" />
<el-table-column label="成品厚度" align="center" prop="thickness" />
<el-table-column label="成品规格" align="center" prop="finishedProductSpec" />
<el-table-column label="材质" align="center" prop="material" />
<el-table-column label="重量" align="center" prop="weight" />
<el-table-column label="卷数" align="center" prop="productNum" />
<el-table-column label="表面处理" align="center" prop="surfaceTreatment" />
<el-table-column label="包装要求" align="center" prop="packagingReq" />
<el-table-column label="切边要求" align="center" prop="edgeCuttingReq" />
<el-table-column label="用途" align="center" prop="purpose" />
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
</div>
</el-tab-pane>
<el-tab-pane label="明细选择" name="orderItem">
<el-form :model="itemQueryParams" ref="itemQueryForm" size="small" :inline="true" label-width="60px">
<el-form-item label="产品类型">
<el-input clearable v-model="itemQueryParams.productType" placeholder="请输入产品类型" style="width: 120px" />
</el-form-item>
<el-form-item label="成品宽度">
<el-input clearable v-model="itemQueryParams.width" placeholder="请输入成品宽度" style="width: 120px" />
</el-form-item>
<el-form-item label="成品厚度">
<el-input clearable v-model="itemQueryParams.thickness" placeholder="请输入成品厚度" style="width: 120px" />
</el-form-item>
<el-form-item label="成品规格">
<el-input clearable v-model="itemQueryParams.finishedProductSpec" placeholder="请输入成品规格"
style="width: 120px" />
</el-form-item>
<el-form-item label="材质">
<el-input clearable v-model="itemQueryParams.material" placeholder="请输入材质" style="width: 120px" />
</el-form-item>
<el-form-item label="表面处理">
<el-input clearable v-model="itemQueryParams.surfaceTreatment" placeholder="请输入表面处理"
style="width: 120px" />
</el-form-item>
<el-form-item label="包装要求">
<el-input clearable v-model="itemQueryParams.packagingReq" placeholder="请输入包装要求" style="width: 120px" />
</el-form-item>
<el-form-item label="切边要求">
<el-input clearable v-model="itemQueryParams.edgeCuttingReq" placeholder="请输入切边要求"
style="width: 120px" />
</el-form-item>
<el-form-item label="用途">
<el-input clearable v-model="itemQueryParams.purpose" placeholder="请输入用途" style="width: 120px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getBatchItemList">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetItemQuery">重置</el-button>
</el-form-item>
</el-form>
<div class="item-section">
<div class="section-title">选择明细多选</div>
<el-table v-loading="batchItemLoading" :data="batchItemList" style="width: 100%" border
@selection-change="handleBatchItemSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="合同号" align="center" prop="contractCode" width="120" />
<el-table-column label="客户" align="center" prop="companyName" width="150" />
<el-table-column label="产品类型" align="center" prop="productType" />
<el-table-column label="成品宽度" align="center" prop="width" />
<el-table-column label="成品厚度" align="center" prop="thickness" />
<el-table-column label="成品规格" align="center" prop="finishedProductSpec" />
<el-table-column label="材质" align="center" prop="material" />
<el-table-column label="重量" align="center" prop="weight" />
<el-table-column label="卷数" align="center" prop="productNum" />
<el-table-column label="表面处理" align="center" prop="surfaceTreatment" />
<el-table-column label="包装要求" align="center" prop="packagingReq" />
<el-table-column label="切边要求" align="center" prop="edgeCuttingReq" />
<el-table-column label="用途" align="center" prop="purpose" />
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
<div class="pagination-container">
<el-pagination background layout="prev, pager, next, jumper" :total="batchItemTotal"
:page-size="itemQueryParams.pageSize" :current-page.sync="itemQueryParams.pageNum"
@current-change="getBatchItemList" />
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="batchAddDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmBatchAdd" :disabled="selectedBatchItems.length === 0">确认新增</el-button>
<el-button type="primary" @click="confirmBatchAdd" :disabled="selectedBatchItems.length === 0"
:loading="buttonLoading">确认新增</el-button>
</div>
</el-dialog>
</div>
@@ -362,7 +496,7 @@
<script>
import { updatePlanDetail, listPlanDetail, addPlanDetail, delPlanDetail } from "@/api/aps/planDetail";
import { getPlanSheet } from "@/api/aps/planSheet";
import { getPlanSheet, listPlanSheet } from "@/api/aps/planSheet";
import { listOrder } from '@/api/crm/order';
import { listOrderItem } from '@/api/crm/orderItem'
import PlanSheetList from "@/views/aps/planSheet/PlanSheetList.vue";
@@ -387,10 +521,12 @@ export default {
recentPlanSheets: [],
// 排产单明细表格数据
planDetailList: [],
// 总条数
total: 0,
// 加载状态
loading: false,
buttonLoading: false,
// 查询参数
queryParams: {
@@ -424,7 +560,9 @@ export default {
currentEditingRow: null,
// 批量新增对话框
batchAddDialogVisible: false,
// 批量查询参数
// 当前激活的批量新增tab
activeBatchTab: 'orderItem',
// 批量查询参数(合同选择模式)
batchQueryParams: {
pageNum: 1,
pageSize: 10,
@@ -432,6 +570,20 @@ export default {
customerName: undefined,
salesman: undefined
},
// 明细查询参数(直接明细选择模式)
itemQueryParams: {
pageNum: 1,
pageSize: 10,
productType: undefined,
width: undefined,
thickness: undefined,
finishedProductSpec: undefined,
material: undefined,
surfaceTreatment: undefined,
packagingReq: undefined,
edgeCuttingReq: undefined,
purpose: undefined
},
// 批量订单列表
batchOrderList: [],
// 批量订单总数
@@ -440,12 +592,39 @@ export default {
batchOrderLoading: false,
// 批量明细列表
batchItemList: [],
// 批量明细总数
batchItemTotal: 0,
// 批量明细加载状态
batchItemLoading: false,
// 选中的合同
selectedContract: null,
// 选中的明细
selectedBatchItems: []
selectedBatchItems: [],
// 转单对话框
transferDialogVisible: false,
// 转单查询参数
transferQueryParams: {
pageNum: 1,
pageSize: 10,
planDate: undefined,
lineName: undefined,
planCode: undefined,
scheduler: undefined
},
// 转单排产单列表
transferPlanSheetList: [],
// 转单排产单总数
transferTotal: 0,
// 转单加载状态
transferLoading: false,
// 选中的转单目标排产单
selectedTransferPlanSheet: null,
// 当前要转单的行数据
transferRowData: null,
// 选中的行(用于批量操作)
selectedRows: [],
// 是否批量操作(批量转单)
isBatchTransfer: false,
};
},
created() {
@@ -453,6 +632,23 @@ export default {
this.loadRecentPlanSheets();
},
methods: {
parseTime(time, pattern) {
if (!time) return '';
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
const date = new Date(time);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
return format.replace('{y}', year)
.replace('{m}', month.toString().padStart(2, '0'))
.replace('{d}', day.toString().padStart(2, '0'))
.replace('{h}', hour.toString().padStart(2, '0'))
.replace('{i}', minute.toString().padStart(2, '0'))
.replace('{s}', second.toString().padStart(2, '0'));
},
// 打开管理排产单对话框
openDialog() {
this.dialogVisible = true;
@@ -595,11 +791,13 @@ export default {
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.buttonLoading = true;
delPlanDetail(row.planDetailId).then(response => {
this.$message({
message: "删除成功",
type: "success"
});
this.buttonLoading = false;
this.getList();
});
});
@@ -680,9 +878,11 @@ export default {
// 打开批量新增对话框
handleBatchAdd() {
this.batchAddDialogVisible = true;
this.activeBatchTab = 'orderItem';
this.selectedContract = null;
this.selectedBatchItems = [];
this.getBatchOrderList();
this.getBatchItemList();
},
// 获取批量订单列表
getBatchOrderList() {
@@ -704,6 +904,32 @@ export default {
};
this.getBatchOrderList();
},
// 获取批量明细列表(直接选择模式)
getBatchItemList() {
this.batchItemLoading = true;
listOrderItem(this.itemQueryParams).then(response => {
this.batchItemList = response.rows;
this.batchItemTotal = response.total;
this.batchItemLoading = false;
});
},
// 重置明细查询参数
resetItemQuery() {
this.itemQueryParams = {
pageNum: 1,
pageSize: 10,
productType: undefined,
width: undefined,
thickness: undefined,
finishedProductSpec: undefined,
material: undefined,
surfaceTreatment: undefined,
packagingReq: undefined,
edgeCuttingReq: undefined,
purpose: undefined
};
this.getBatchItemList();
},
// 选择批量合同
selectBatchContract(row) {
this.selectedContract = row;
@@ -718,6 +944,177 @@ export default {
handleBatchItemSelectionChange(selection) {
this.selectedBatchItems = selection;
},
// 打开转单对话框
handleTransfer(row) {
this.transferRowData = row;
this.selectedTransferPlanSheet = null;
this.isBatchTransfer = false;
this.transferDialogVisible = true;
this.getTransferPlanSheetList();
},
// 获取转单排产单列表
getTransferPlanSheetList() {
this.transferLoading = true;
listPlanSheet(this.transferQueryParams).then(response => {
this.transferPlanSheetList = response.rows;
this.transferTotal = response.total;
this.transferLoading = false;
});
},
// 重置转单查询参数
resetTransferQuery() {
this.transferQueryParams = {
pageNum: 1,
pageSize: 10,
planDate: undefined,
lineName: undefined,
planCode: undefined,
scheduler: undefined
};
this.getTransferPlanSheetList();
},
// 选择转单目标排产单
selectTransferPlanSheet(row) {
this.selectedTransferPlanSheet = row;
},
// 确认批量转单
confirmTransfer() {
if (!this.selectedTransferPlanSheet) {
this.$message.warning('请选择目标排产单');
return;
}
if (this.selectedTransferPlanSheet.planSheetId === this.currentPlanSheetId) {
this.$message.warning('目标排产单不能与当前排产单相同');
return;
}
this.$confirm(`确认将选中的 ${this.selectedRows.length} 条明细转单到排产单 ${this.selectedTransferPlanSheet.planCode} `, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
listPlanDetail({
pageNum: 1,
pageSize: 1,
planSheetId: this.selectedTransferPlanSheet.planSheetId
}).then(response => {
const targetList = response.rows;
let currentMaxSeqNo = targetList.length > 0
? Math.max(...targetList.map(item => parseInt(item.bizSeqNo) || 0))
: 0;
let successCount = 0;
let failCount = 0;
const transferPromises = [];
for (let i = 0; i < this.selectedRows.length; i++) {
const row = this.selectedRows[i];
const newRow = {
...row,
planDetailId: undefined,
planSheetId: this.selectedTransferPlanSheet.planSheetId,
bizSeqNo: currentMaxSeqNo + i + 1
};
transferPromises.push(addPlanDetail(newRow));
}
this.buttonLoading = true;
Promise.all(transferPromises).then(() => {
this.$message.success(`批量转单成功,共转单 ${this.selectedRows.length}`);
this.transferDialogVisible = false;
this.getList();
this.buttonLoading = false;
}).catch(error => {
this.$message.error('批量转单失败');
this.buttonLoading = false;
});
});
});
},
// 确认单行转单
confirmSingleTransfer() {
if (!this.selectedTransferPlanSheet) {
this.$message.warning('请选择目标排产单');
return;
}
if (this.selectedTransferPlanSheet.planSheetId === this.currentPlanSheetId) {
this.$message.warning('目标排产单不能与当前排产单相同');
return;
}
this.$confirm(`确认将当前明细转单到排产单 ${this.selectedTransferPlanSheet.planCode} `, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
listPlanDetail({
pageNum: 1,
pageSize: 1,
planSheetId: this.selectedTransferPlanSheet.planSheetId
}).then(response => {
const targetList = response.rows;
const currentMaxSeqNo = targetList.length > 0
? Math.max(...targetList.map(item => parseInt(item.bizSeqNo) || 0))
: 0;
const newRow = {
...this.transferRowData,
planDetailId: undefined,
planSheetId: this.selectedTransferPlanSheet.planSheetId,
bizSeqNo: currentMaxSeqNo + 1
};
addPlanDetail(newRow).then(() => {
this.$message.success('转单成功');
this.transferDialogVisible = false;
this.getList();
}).catch(error => {
this.$message.error('转单失败');
});
});
});
},
// 处理表格选择变化
handleSelectionChange(selection) {
this.selectedRows = selection;
},
// 批量删除
handleBatchDelete() {
if (this.selectedRows.length === 0) {
this.$message.warning('请至少选择一条明细');
return;
}
this.$confirm(`确认删除选中的 ${this.selectedRows.length} 条明细?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const ids = this.selectedRows.map(row => row.planDetailId).join(',');
this.buttonLoading = true;
delPlanDetail(ids).then(() => {
this.$message.success('批量删除成功');
this.getList();
this.buttonLoading = false;
}).catch(error => {
this.$message.error('批量删除失败');
this.buttonLoading = false;
});
});
},
// 批量转单
handleBatchTransfer() {
if (this.selectedRows.length === 0) {
this.$message.warning('请至少选择一条明细');
return;
}
this.isBatchTransfer = true;
this.selectedTransferPlanSheet = null;
this.transferDialogVisible = true;
this.getTransferPlanSheetList();
},
// 确认批量新增
confirmBatchAdd() {
if (this.selectedBatchItems.length === 0) {
@@ -735,14 +1132,15 @@ export default {
: 0;
const addPromises = this.selectedBatchItems.map((item, index) => {
const contract = this.selectedContract || item;
const newRow = {
planSheetId: this.currentPlanSheetId,
bizSeqNo: currentMaxSeqNo + index + 1,
orderCode: this.selectedContract.orderCode,
contractCode: this.selectedContract.contractCode,
customerName: this.selectedContract.companyName,
salesman: this.selectedContract.salesman,
orderId: this.selectedContract.orderId,
orderCode: contract.orderCode,
contractCode: contract.contractCode,
customerName: contract.companyName || contract.customerName,
salesman: contract.salesman,
orderId: contract.orderId,
productName: item.productType,
productMaterial: item.material,
productWidth: item.width,