|
|
@@ -60,6 +60,19 @@
|
|
|
}
|
|
|
]"
|
|
|
>
|
|
|
+ <div class="plan-table-status-tabs">
|
|
|
+ <el-tabs
|
|
|
+ v-model="planTableStatusTab"
|
|
|
+ @tab-click="handlePlanTableStatusTabClick"
|
|
|
+ >
|
|
|
+ <el-tab-pane
|
|
|
+ v-for="item in planTableStatusTabs"
|
|
|
+ :key="item.name"
|
|
|
+ :name="item.name"
|
|
|
+ :label="item.label"
|
|
|
+ />
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
<ele-pro-table
|
|
|
:key="planTableRenderKey"
|
|
|
width="100%"
|
|
|
@@ -268,6 +281,7 @@
|
|
|
planPickerSelectionAll: [],
|
|
|
planPickerSelectionSyncing: false,
|
|
|
planTableSelectionSyncing: false,
|
|
|
+ planTableStatusTab: 'published',
|
|
|
planTableRenderKey: 0,
|
|
|
dialogRenderKey: 0,
|
|
|
dotLineLoading: false,
|
|
|
@@ -348,6 +362,30 @@
|
|
|
schedulingTitle() {
|
|
|
return this.isOrderScheduling ? '班组排程' : '工厂排产';
|
|
|
},
|
|
|
+ planTableStatusTabs() {
|
|
|
+ if (this.isOrderScheduling) {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ name: 'dispatched',
|
|
|
+ label: '已派单'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'undispatched',
|
|
|
+ label: '未派单'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ name: 'published',
|
|
|
+ label: '已发布'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'unpublished',
|
|
|
+ label: '未发布'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ },
|
|
|
isCompactSchedulingLayout() {
|
|
|
return this.viewportWidth <= 1180;
|
|
|
},
|
|
|
@@ -386,16 +424,17 @@
|
|
|
return '585px';
|
|
|
},
|
|
|
planTableHeight() {
|
|
|
+ const tabHeight = 52;
|
|
|
if (this.isOrderScheduling) {
|
|
|
// ele-pro-table 的 height 只作用在表格主体,工具栏和分页器会继续占用额外高度。
|
|
|
// 班组排产右侧是自定义 flex 分页区,左侧需要略收表格主体高度,保证两个分页器垂直位置一致。
|
|
|
- if (this.viewportHeight <= 760) return '360px';
|
|
|
- if (this.viewportHeight <= 900) return '420px';
|
|
|
- return '470px';
|
|
|
+ if (this.viewportHeight <= 760) return `${360 - tabHeight}px`;
|
|
|
+ if (this.viewportHeight <= 900) return `${420 - tabHeight}px`;
|
|
|
+ return `${470 - tabHeight}px`;
|
|
|
}
|
|
|
- if (this.viewportHeight <= 760) return '360px';
|
|
|
- if (this.viewportHeight <= 900) return '420px';
|
|
|
- return '455px';
|
|
|
+ if (this.viewportHeight <= 760) return `${360 - tabHeight}px`;
|
|
|
+ if (this.viewportHeight <= 900) return `${420 - tabHeight}px`;
|
|
|
+ return `${455 - tabHeight}px`;
|
|
|
},
|
|
|
planPaginationClass() {
|
|
|
return this.isOrderScheduling
|
|
|
@@ -461,6 +500,79 @@
|
|
|
? '查看'
|
|
|
: '布点';
|
|
|
},
|
|
|
+ getDefaultPlanTableStatusTab(mode = this.schedulingMode) {
|
|
|
+ return mode === 'order' ? 'dispatched' : 'published';
|
|
|
+ },
|
|
|
+ getPlanTableStatusRequestWhere(tabName = this.planTableStatusTab) {
|
|
|
+ if (this.isOrderScheduling) {
|
|
|
+ return tabName === 'dispatched'
|
|
|
+ ? { statusList: [4, 5, 6, 7] }
|
|
|
+ : { statusList: [8] };
|
|
|
+ }
|
|
|
+ return tabName === 'published'
|
|
|
+ ? { status: ['4'] }
|
|
|
+ : { status: ['2', '3'] };
|
|
|
+ },
|
|
|
+ getPlanTableStatusRequestWhereList(tabName = this.planTableStatusTab) {
|
|
|
+ return [this.getPlanTableStatusRequestWhere(tabName)];
|
|
|
+ },
|
|
|
+ async handlePlanTableStatusTabClick() {
|
|
|
+ await this.reloadPlanTableByStatus();
|
|
|
+ },
|
|
|
+ async reloadPlanTableByStatus() {
|
|
|
+ if (this.isOrderScheduling) {
|
|
|
+ await this.reloadOrderSchedulingOrdersByDateRange(this.dateRange);
|
|
|
+ } else {
|
|
|
+ await this.reloadPlanSchedulingPlansByStatus();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async reloadPlanSchedulingPlansByStatus() {
|
|
|
+ const loading = this.$loading({
|
|
|
+ lock: true,
|
|
|
+ text: '加载计划中...'
|
|
|
+ });
|
|
|
+ try {
|
|
|
+ const requestWhereList = this.getPlanTableStatusRequestWhereList();
|
|
|
+ const resultList = await Promise.all(
|
|
|
+ requestWhereList.map((where) =>
|
|
|
+ getList({
|
|
|
+ pageNum: 1,
|
|
|
+ size: -1,
|
|
|
+ ...this.getSchedulingDateRangeParams(),
|
|
|
+ ...where
|
|
|
+ })
|
|
|
+ )
|
|
|
+ );
|
|
|
+ const rows = resultList.reduce(
|
|
|
+ (list, data) => list.concat(data?.list || []),
|
|
|
+ []
|
|
|
+ );
|
|
|
+ this.allPlanDataList = deepClone(rows);
|
|
|
+ this.planDataList = this.buildPlanTableRows(rows, rows);
|
|
|
+ this.planTableRenderKey += 1;
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error(e.message || '获取计划数据失败');
|
|
|
+ } finally {
|
|
|
+ loading.close();
|
|
|
+ }
|
|
|
+ this.selection = [];
|
|
|
+ this.currentPlan = null;
|
|
|
+ this.planRoutingPayload = null;
|
|
|
+ this.taskList = [];
|
|
|
+ this.syncTableSelection('planTable', []);
|
|
|
+ },
|
|
|
+ getSchedulingDateRangeParams() {
|
|
|
+ if (!Array.isArray(this.dateRange) || this.dateRange.length !== 2) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ if (!this.dateRange[0] || !this.dateRange[1]) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ startDate: this.dateRange[0],
|
|
|
+ endDate: this.dateRange[1]
|
|
|
+ };
|
|
|
+ },
|
|
|
async loadPlansByIds(ids = []) {
|
|
|
const uniqueIds = Array.from(
|
|
|
new Set(
|
|
|
@@ -1523,6 +1635,9 @@
|
|
|
async handleTabChange(tabKey) {
|
|
|
this.activeTab = tabKey;
|
|
|
await this.refreshSchedulingView();
|
|
|
+ if (!this.isOrderScheduling) {
|
|
|
+ await this.reloadPlanSchedulingPlansByStatus();
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
async handleDateChange(val) {
|
|
|
@@ -1532,6 +1647,7 @@
|
|
|
return;
|
|
|
}
|
|
|
await this.refreshSchedulingView();
|
|
|
+ await this.reloadPlanSchedulingPlansByStatus();
|
|
|
},
|
|
|
|
|
|
handleDateInput(val) {
|
|
|
@@ -1568,7 +1684,10 @@
|
|
|
text: '加载订单中...'
|
|
|
});
|
|
|
try {
|
|
|
- const list = await this.orderListLoader(dateRange);
|
|
|
+ const list = await this.orderListLoader(
|
|
|
+ dateRange,
|
|
|
+ this.getPlanTableStatusRequestWhere()
|
|
|
+ );
|
|
|
this.selectedWorkOrders = this.buildWorkOrderTableRows(list);
|
|
|
this.planDataList = this.selectedWorkOrders;
|
|
|
this.planTableRenderKey += 1;
|
|
|
@@ -1994,6 +2113,7 @@
|
|
|
this.dialogRenderKey += 1;
|
|
|
this.planTableRenderKey += 1;
|
|
|
this.schedulingMode = mode;
|
|
|
+ this.planTableStatusTab = this.getDefaultPlanTableStatusTab(mode);
|
|
|
this.orderListLoader = orderListLoader;
|
|
|
// 弹窗复用同一个组件,但入口数据不同:
|
|
|
// - plan:生产计划行,使用工厂排程列 createSchedulingColumns。
|
|
|
@@ -2062,7 +2182,12 @@
|
|
|
// 工厂排程仍使用班组主数据作为自制执行对象,不走人员/工位混合逻辑。
|
|
|
await this.loadTeamOptions();
|
|
|
}
|
|
|
- await this.refreshSchedulingView();
|
|
|
+ if (mode === 'order') {
|
|
|
+ await this.reloadPlanTableByStatus();
|
|
|
+ } else {
|
|
|
+ await this.refreshSchedulingView();
|
|
|
+ await this.reloadPlanSchedulingPlansByStatus();
|
|
|
+ }
|
|
|
|
|
|
this.visible = true;
|
|
|
},
|
|
|
@@ -2439,6 +2564,7 @@
|
|
|
this.planPickerTimeDimensionPlanType = '';
|
|
|
this.planPickerWhere = createPlanPickerWhere();
|
|
|
this.schedulingMode = 'plan';
|
|
|
+ this.planTableStatusTab = this.getDefaultPlanTableStatusTab('plan');
|
|
|
this.selectedWorkOrders = [];
|
|
|
this.orderListLoader = null;
|
|
|
this.columns = createSchedulingColumns();
|
|
|
@@ -2490,16 +2616,74 @@
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
+ .plan-table-status-tabs {
|
|
|
+ height: 42px;
|
|
|
+ padding: 0 12px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ border-bottom: 1px solid #edf2f7;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .plan-table-status-tabs ::v-deep {
|
|
|
+ .el-tabs__header {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs__nav-wrap::after {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs__item {
|
|
|
+ height: 42px;
|
|
|
+ line-height: 42px;
|
|
|
+ padding: 0 18px;
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs__item.is-active {
|
|
|
+ color: #1890ff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs__active-bar {
|
|
|
+ height: 3px;
|
|
|
+ border-radius: 3px 3px 0 0;
|
|
|
+ background: #1890ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.form-wrapper ::v-deep .ele-pro-table {
|
|
|
+ height: calc(100% - 42px);
|
|
|
+ min-height: 0;
|
|
|
+ overflow: hidden;
|
|
|
background: #fff;
|
|
|
}
|
|
|
|
|
|
+ .form-wrapper.is-order-scheduling ::v-deep .ele-pro-table,
|
|
|
+ .form-wrapper.is-plan-scheduling ::v-deep .ele-pro-table {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-wrapper.is-order-scheduling ::v-deep .ele-pro-table > .el-table {
|
|
|
+ flex: 0 0 auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-wrapper.is-order-scheduling ::v-deep .ele-pro-table > .el-pagination {
|
|
|
+ margin-top: auto !important;
|
|
|
+ }
|
|
|
+
|
|
|
.form-wrapper ::v-deep .el-table {
|
|
|
color: #364152;
|
|
|
border-color: #edf2f7;
|
|
|
font-size: 14px;
|
|
|
}
|
|
|
|
|
|
+ .form-wrapper ::v-deep .el-table__body-wrapper {
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+
|
|
|
.form-wrapper ::v-deep .el-table th.el-table__cell {
|
|
|
background: #f7fafc;
|
|
|
color: #263445;
|
|
|
@@ -2572,7 +2756,6 @@
|
|
|
.form-wrapper.is-plan-scheduling ::v-deep .ele-pro-table {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- height: 100%;
|
|
|
min-height: 0;
|
|
|
}
|
|
|
|