Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2026-05-14 15:12:38 +08:00
4 changed files with 661 additions and 135 deletions

View File

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

View File

@@ -5,24 +5,28 @@
<i class="el-icon-setting"></i> <i class="el-icon-setting"></i>
</div> </div>
<div class="custom-tabs"> <div class="custom-tabs">
<div class="tab-header"> <div class="tab-nav">
<div <button v-if="planSheetList.length > 0 && queryParams.pageNum > 1" class="nav-btn prev" @click="prevPage">
v-for="planSheet in planSheetList" <i class="el-icon-arrow-left"></i>
:key="planSheet.planSheetId" </button>
class="tab-item" <div class="tab-header">
:class="{ active: activeTab === planSheet.planSheetId.toString() }" <div v-for="planSheet in planSheetList" :key="planSheet.planSheetId" class="tab-item"
@click="handleTabClick(planSheet)" :class="{ active: activeTab === planSheet.planSheetId.toString() }" @click="handleTabClick(planSheet)">
> <div class="tab-title">{{ planSheet.planCode }}</div>
<div class="tab-title">{{ planSheet.planCode }}</div> <div class="tab-info">
<div class="tab-info"> <span>{{ planSheet.lineName }}</span>
<span>{{ planSheet.lineName }}</span> <span class="date">{{ parseTime(planSheet.planDate, '{y}-{m}-{d}') }}</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> </div>
<div v-if="planSheetList.length === 0" class="tab-item disabled"> <button v-if="planSheetList.length > 0 && queryParams.pageNum < totalPage" class="nav-btn next" @click="nextPage">
<div class="tab-title">暂无排产单</div> <i class="el-icon-arrow-right"></i>
<div class="tab-info">请点击齿轮图标选择排产单</div> </button>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -37,16 +41,20 @@
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="产线名称" prop="lineName"> <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>
<el-form-item label="排产单号" prop="planCode"> <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>
<el-form-item label="排产人" prop="scheduler"> <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-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 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-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
@@ -64,9 +72,12 @@
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-download" @click.stop="handleExport(scope.row)">导出</el-button> <el-button size="mini" type="text" icon="el-icon-download"
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(scope.row)">修改</el-button> @click.stop="handleExport(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 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> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -120,6 +131,11 @@ export default {
default: false default: false
} }
}, },
computed: {
totalPage() {
return Math.ceil(this.total / this.queryParams.pageSize)
}
},
data() { data() {
return { return {
// 按钮loading // 按钮loading
@@ -229,6 +245,21 @@ export default {
this.planSheetDialogVisible = false; this.planSheetDialogVisible = false;
this.handleRowClick(planSheet); 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() { openPlanSheetDialog() {
this.getList(); this.getList();
@@ -419,10 +450,52 @@ export default {
border-bottom: 1px solid #e4e7ed; 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 { .tab-header {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 4px; gap: 4px;
flex: 1;
overflow: hidden;
}
.tab-pagination {
text-align: right;
font-size: 12px;
color: #909399;
margin-top: 4px;
margin-right: 8px;
} }
.tab-item { .tab-item {

View File

@@ -10,6 +10,10 @@
<div> <div>
<el-button type="primary" plain @click="handleAdd">新增明细</el-button> <el-button type="primary" plain @click="handleAdd">新增明细</el-button>
<el-button type="success" plain @click="handleBatchAdd">批量新增</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> <el-button type="info" plain @click="getList">刷新</el-button>
</div> </div>
</div> </div>
@@ -35,12 +39,16 @@
</div> </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"> <template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleSave(scope.row)">保存</el-button> <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="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
<el-button type="success" size="mini" @click="handleTransfer(scope.row)">转单</el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -153,7 +161,8 @@
</el-table-column> </el-table-column>
<el-table-column label="表面处理" align="center" prop="surfaceTreatmentDesc" width="100"> <el-table-column label="表面处理" align="center" prop="surfaceTreatmentDesc" width="100">
<template slot-scope="scope"> <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> </template>
</el-table-column> </el-table-column>
<el-table-column label="切边要求" align="center" prop="widthReq" width="100"> <el-table-column label="切边要求" align="center" prop="widthReq" width="100">
@@ -209,7 +218,10 @@
</el-table-column> </el-table-column>
<el-table-column label="取样" align="center" prop="sampleReq" width="100"> <el-table-column label="取样" align="center" prop="sampleReq" width="100">
<template slot-scope="scope"> <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> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark"> <el-table-column label="备注" align="center" prop="remark">
@@ -289,72 +301,194 @@
</el-table> </el-table>
</el-dialog> </el-dialog>
<!-- 批量新增对话框 --> <!-- 转单对话框 -->
<el-dialog title="批量新增" :visible.sync="batchAddDialogVisible" width="80%" append-to-body> <el-dialog title="转单" :visible.sync="transferDialogVisible" width="60%" append-to-body>
<div class="batch-add-content"> <div class="transfer-content">
<!-- 合同选择 --> <div class="section-title">选择目标排产单</div>
<div class="contract-section"> <el-form :model="transferQueryParams" ref="transferQueryForm" size="small" :inline="true" label-width="68px">
<div class="section-title">选择合同</div> <el-form-item label="排产日期" prop="planDate">
<el-form :model="batchQueryParams" ref="batchQueryForm" size="small" :inline="true" label-width="80px"> <el-date-picker clearable v-model="transferQueryParams.planDate" type="date" value-format="yyyy-MM-dd"
<el-form-item label="合同号" prop="contractCode"> placeholder="请选择排产日期">
<el-input v-model="batchQueryParams.contractCode" placeholder="请输入合同号" style="width: 180px" /> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="客户"> <el-form-item label="产线名称" prop="lineName">
<el-input v-model="batchQueryParams.customerName" placeholder="请输入客户名称" style="width: 180px" /> <el-input v-model="transferQueryParams.lineName" placeholder="请输入产线名称" clearable />
</el-form-item> </el-form-item>
<el-form-item label="业务员"> <el-form-item label="排产单号" prop="planCode">
<el-input v-model="batchQueryParams.salesman" placeholder="请输入业务员" style="width: 120px" /> <el-input v-model="transferQueryParams.planCode" placeholder="请输入排产单号" clearable />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getBatchOrderList">搜索</el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="getTransferPlanSheetList">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetBatchQuery">重置</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetTransferQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-table v-loading="batchOrderLoading" :data="batchOrderList" style="width: 100%" border @row-click="selectBatchContract" <el-table v-loading="transferLoading" :data="transferPlanSheetList" style="width: 100%" border
highlight-current-row> :highlight-current-row="true" @row-click="selectTransferPlanSheet">
<el-table-column prop="contractCode" label="合同号" /> <el-table-column label="排产日期" align="center" prop="planDate" width="140">
<el-table-column prop="signTime" label="签订时间" width="150" /> <template slot-scope="scope">
<el-table-column prop="signLocation" label="签订地点" /> <span>{{ parseTime(scope.row.planDate, '{y}-{m}-{d}') }}</span>
<el-table-column prop="companyName" label="客户公司" /> </template>
<el-table-column prop="salesman" label="业务员" width="100" /> </el-table-column>
<el-table-column prop="deliveryDate" label="交货日期" width="150" /> <el-table-column label="产线名称" align="center" prop="lineName" />
<el-table-column label="操作" width="80" fixed="right"> <el-table-column label="排产单号" align="center" prop="planCode" />
<template slot-scope="scope"> <el-table-column label="排产人" align="center" prop="scheduler" />
<el-button type="text" size="small" @click.stop="selectBatchContract(scope.row)">选择</el-button> <el-table-column label="备注" align="center" prop="remark" />
</template> </el-table>
</el-table-column> <div class="pagination-container">
</el-table> <el-pagination background layout="prev, pager, next, jumper" :total="transferTotal"
<div class="pagination-container"> :page-size="transferQueryParams.pageSize" :current-page.sync="transferQueryParams.pageNum"
<el-pagination background layout="prev, pager, next, jumper" :total="batchOrderTotal" @current-change="getTransferPlanSheetList" />
: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> </div>
</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"> <div slot="footer" class="dialog-footer">
<el-button @click="batchAddDialogVisible = false">取消</el-button> <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> </div>
</el-dialog> </el-dialog>
</div> </div>
@@ -362,7 +496,7 @@
<script> <script>
import { updatePlanDetail, listPlanDetail, addPlanDetail, delPlanDetail } from "@/api/aps/planDetail"; 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 { listOrder } from '@/api/crm/order';
import { listOrderItem } from '@/api/crm/orderItem' import { listOrderItem } from '@/api/crm/orderItem'
import PlanSheetList from "@/views/aps/planSheet/PlanSheetList.vue"; import PlanSheetList from "@/views/aps/planSheet/PlanSheetList.vue";
@@ -387,10 +521,12 @@ export default {
recentPlanSheets: [], recentPlanSheets: [],
// 排产单明细表格数据 // 排产单明细表格数据
planDetailList: [], planDetailList: [],
// 总条数 // 总条数
total: 0, total: 0,
// 加载状态 // 加载状态
loading: false, loading: false,
buttonLoading: false,
// 查询参数 // 查询参数
queryParams: { queryParams: {
@@ -424,7 +560,9 @@ export default {
currentEditingRow: null, currentEditingRow: null,
// 批量新增对话框 // 批量新增对话框
batchAddDialogVisible: false, batchAddDialogVisible: false,
// 批量查询参数 // 当前激活的批量新增tab
activeBatchTab: 'orderItem',
// 批量查询参数(合同选择模式)
batchQueryParams: { batchQueryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
@@ -432,6 +570,20 @@ export default {
customerName: undefined, customerName: undefined,
salesman: 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: [], batchOrderList: [],
// 批量订单总数 // 批量订单总数
@@ -440,12 +592,39 @@ export default {
batchOrderLoading: false, batchOrderLoading: false,
// 批量明细列表 // 批量明细列表
batchItemList: [], batchItemList: [],
// 批量明细总数
batchItemTotal: 0,
// 批量明细加载状态 // 批量明细加载状态
batchItemLoading: false, batchItemLoading: false,
// 选中的合同 // 选中的合同
selectedContract: null, 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() { created() {
@@ -453,6 +632,23 @@ export default {
this.loadRecentPlanSheets(); this.loadRecentPlanSheets();
}, },
methods: { 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() { openDialog() {
this.dialogVisible = true; this.dialogVisible = true;
@@ -595,11 +791,13 @@ export default {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.buttonLoading = true;
delPlanDetail(row.planDetailId).then(response => { delPlanDetail(row.planDetailId).then(response => {
this.$message({ this.$message({
message: "删除成功", message: "删除成功",
type: "success" type: "success"
}); });
this.buttonLoading = false;
this.getList(); this.getList();
}); });
}); });
@@ -680,9 +878,11 @@ export default {
// 打开批量新增对话框 // 打开批量新增对话框
handleBatchAdd() { handleBatchAdd() {
this.batchAddDialogVisible = true; this.batchAddDialogVisible = true;
this.activeBatchTab = 'orderItem';
this.selectedContract = null; this.selectedContract = null;
this.selectedBatchItems = []; this.selectedBatchItems = [];
this.getBatchOrderList(); this.getBatchOrderList();
this.getBatchItemList();
}, },
// 获取批量订单列表 // 获取批量订单列表
getBatchOrderList() { getBatchOrderList() {
@@ -704,6 +904,32 @@ export default {
}; };
this.getBatchOrderList(); 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) { selectBatchContract(row) {
this.selectedContract = row; this.selectedContract = row;
@@ -718,6 +944,177 @@ export default {
handleBatchItemSelectionChange(selection) { handleBatchItemSelectionChange(selection) {
this.selectedBatchItems = 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() { confirmBatchAdd() {
if (this.selectedBatchItems.length === 0) { if (this.selectedBatchItems.length === 0) {
@@ -735,14 +1132,15 @@ export default {
: 0; : 0;
const addPromises = this.selectedBatchItems.map((item, index) => { const addPromises = this.selectedBatchItems.map((item, index) => {
const contract = this.selectedContract || item;
const newRow = { const newRow = {
planSheetId: this.currentPlanSheetId, planSheetId: this.currentPlanSheetId,
bizSeqNo: currentMaxSeqNo + index + 1, bizSeqNo: currentMaxSeqNo + index + 1,
orderCode: this.selectedContract.orderCode, orderCode: contract.orderCode,
contractCode: this.selectedContract.contractCode, contractCode: contract.contractCode,
customerName: this.selectedContract.companyName, customerName: contract.companyName || contract.customerName,
salesman: this.selectedContract.salesman, salesman: contract.salesman,
orderId: this.selectedContract.orderId, orderId: contract.orderId,
productName: item.productType, productName: item.productType,
productMaterial: item.material, productMaterial: item.material,
productWidth: item.width, productWidth: item.width,

View File

@@ -1,4 +1,4 @@
<template> +<template>
<div> <div>
<el-empty v-if="!orderId || orderId == ''" description="未选中订单" /> <el-empty v-if="!orderId || orderId == ''" description="未选中订单" />
@@ -10,9 +10,16 @@
<!-- <el-button type="primary" plain icon="el-icon-printer" size="mini" @click="handlePrint">打印</el-button> --> <!-- <el-button type="primary" plain icon="el-icon-printer" size="mini" @click="handlePrint">打印</el-button> -->
<el-button type="primary" plain icon="el-icon-refresh" size="mini" @click="getList">刷新</el-button> <el-button type="primary" plain icon="el-icon-refresh" size="mini" @click="getList">刷新</el-button>
</el-col> </el-col>
<el-col :span="1.5" v-if="editable">
<el-button type="success" plain icon="el-icon-document" size="mini"
@click="handleBatchWriteToContract" :disabled="selectedItems.length === 0">
批量写入合同
</el-button>
</el-col>
</el-row> </el-row>
<el-table v-loading="loading" :data="orderItemList"> <el-table v-loading="loading" :data="orderItemList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="产品类型" align="center" prop="productType" /> <el-table-column label="产品类型" align="center" prop="productType" />
<el-table-column label="成品宽度" align="center" prop="width" /> <el-table-column label="成品宽度" align="center" prop="width" />
<el-table-column label="成品厚度" align="center" prop="thickness" /> <el-table-column label="成品厚度" align="center" prop="thickness" />
@@ -63,7 +70,11 @@
<el-input v-model="form.productType" placeholder="请输入产品类型" /> <el-input v-model="form.productType" placeholder="请输入产品类型" />
</el-form-item> </el-form-item>
<el-form-item label="成品规格" prop="finishedProductSpec"> <el-form-item label="成品规格" prop="finishedProductSpec">
<el-input v-model="form.finishedProductSpec" placeholder="请输入成品规格" /> <el-select v-model="form.finishedProductSpec" placeholder="请选择或输入成品规格" style="width: 100%" allow-create filterable>
<el-option label="SPCC" value="SPCC" />
<el-option label="DCO1" value="DCO1" />
<el-option label="DX51D+Z" value="DX51D+Z" />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="成品宽度" prop="width"> <el-form-item label="成品宽度" prop="width">
<el-input v-model="form.width" placeholder="请输入宽度" /> <el-input v-model="form.width" placeholder="请输入宽度" />
@@ -172,6 +183,8 @@ export default {
loading: true, loading: true,
// 选中数组 // 选中数组
ids: [], ids: [],
// 选中的订单明细项(用于批量操作)
selectedItems: [],
// 非单个禁用 // 非单个禁用
single: true, single: true,
// 非多个禁用 // 非多个禁用
@@ -296,13 +309,15 @@ export default {
let content = parseProductContent(data.productContent); let content = parseProductContent(data.productContent);
const product = convertOrderItemToProduct(row); const product = convertOrderItemToProduct(row);
content = addProduct(content, product); content = addProduct(content, product);
const jsonContent = stringifyProductContent(content); const jsonContent = stringifyProductContent(content);
updateOrder({ updateOrder({
...this.orderContent, ...this.orderContent,
productContent: jsonContent productContent: jsonContent
}).then(response => { }).then(response => {
this.$modal.msgSuccess("写入成功,请刷新合同内容查看"); this.$modal.msgSuccess("写入成功");
// 自动刷新合同内容
this.refreshContractContent();
}); });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
@@ -310,6 +325,51 @@ export default {
return; return;
} }
}, },
/** 批量写入合同 */
async handleBatchWriteToContract() {
if (this.selectedItems.length === 0) {
this.$modal.msgWarning("请先选择要写入的订单明细");
return;
}
const { data } = await getOrder(this.orderId);
try {
let content = parseProductContent(data.productContent);
// 批量添加选中的产品
this.selectedItems.forEach(row => {
const product = convertOrderItemToProduct(row);
content = addProduct(content, product);
});
const jsonContent = stringifyProductContent(content);
updateOrder({
...this.orderContent,
productContent: jsonContent
}).then(response => {
this.$modal.msgSuccess(`成功写入 ${this.selectedItems.length} 条产品信息`);
// 自动刷新合同内容
this.refreshContractContent();
// 清空选中状态
this.$refs.orderTable.clearSelection();
this.selectedItems = [];
});
} catch (error) {
console.error(error);
this.$modal.msgError("产品内容格式错误");
return;
}
},
/** 刷新合同内容(通知父组件刷新) */
refreshContractContent() {
// 通过事件通知父组件刷新合同内容
this.$emit('refreshContract');
// 如果没有父组件监听,直接刷新页面
setTimeout(() => {
window.location.reload();
}, 500);
},
printOrder() { printOrder() {
this.$refs["printer"].print(); this.$refs["printer"].print();
this.orderOpen = false; this.orderOpen = false;
@@ -324,6 +384,7 @@ export default {
this.ids = selection.map(item => item.itemId) this.ids = selection.map(item => item.itemId)
this.single = selection.length !== 1 this.single = selection.length !== 1
this.multiple = !selection.length this.multiple = !selection.length
this.selectedItems = selection;
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {