feat(aps): 新增产需明细转排产功能并优化页面布局

1.  新增convertRequirementDetail接口实现产需明细下发排产
2.  为排产明细BO添加日期格式化注解
3.  产需单页面添加拖拽分栏、产需转化弹窗、撤回按钮和下发进度展示
4.  移除订单状态查询和列表展示,简化排产页面标签页结构
5.  优化产需单列表和详情页的布局样式
This commit is contained in:
砂糖
2026-07-10 13:11:30 +08:00
parent 025980e36a
commit a59bb05239
6 changed files with 447 additions and 61 deletions

View File

@@ -82,6 +82,15 @@ export function delRequirementDetail(detailIds) {
})
}
// 产需明细逐条下发到排产明细sch_prod_schedule_item
export function convertRequirementDetail(data) {
return request({
url: '/flow/prodScheduleItem/receiveFromDetail',
method: 'post',
data
})
}
// ====== 销售订单-产需单关联SchSaleScheduleRel ======
// 查询关联列表

View File

@@ -53,11 +53,6 @@
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="订单状态" prop="orderStatus">
<el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable style="width: 140px;">
<el-option v-for="(value, key) in ORDER_STATUS" :key="value" :label="key" :value="value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button class="aps-btn-silver" icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
@@ -96,7 +91,6 @@
<div style="font-size: 12px; color: #909399;">
签订地点: {{ item.signLocation || '-' }}
</div>
<el-tag :type="statusTagType(item.orderStatus)" size="small">{{ statusLabel(item.orderStatus) }}</el-tag>
</div>
</div>
<div v-if="orderList.length === 0 && !orderLoading"

View File

@@ -62,11 +62,6 @@
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="订单状态" prop="orderStatus">
<el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable style="width: 140px;">
<el-option v-for="(value, key) in ORDER_STATUS" :key="value" :label="key" :value="value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button class="aps-btn-silver" icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
@@ -96,7 +91,6 @@
<div style="font-size: 12px; color: #909399;">
签订地点: {{ item.signLocation || '-' }}
</div>
<el-tag :type="statusTagType(item.orderStatus)" size="small">{{ statusLabel(item.orderStatus) }}</el-tag>
</div>
</div>
<div v-if="orderList.length === 0 && !orderLoading"

View File

@@ -1,8 +1,10 @@
<template>
<div class="aps-req-page">
<el-row :gutter="20" class="aps-req-row">
<drag-resize-panel direction="horizontal" :initial-size="360" :min-size="260" class="aps-req-row">
<template #panelA>
<!-- 左侧产需单列表 -->
<el-col :span="8" class="aps-req-left" v-loading="reqLoading">
<div class="aps-req-left" v-loading="reqLoading">
<div class="aps-req-scroll">
<!-- 筛选区 -->
<div class="filter-section" style="padding: 10px; border-bottom: 1px solid #e4e7ed;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
@@ -45,7 +47,7 @@
</div>
</div>
<div class="list-item-right">
<el-button size="mini" plain @click.stop="handleJumpToSchedule(item)">跳转排</el-button>
<el-button v-if="item.scheduleStatus === 1 || item.scheduleStatus === 2" size="mini" plain @click.stop="openConvertDialogForReq(item)">需转化</el-button>
</div>
</div>
</div>
@@ -57,10 +59,13 @@
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList"
style="padding: 10px; margin-bottom: 10px !important;" />
</el-col>
</div>
</div>
</template>
<template #panelB>
<!-- 右侧详情区 -->
<el-col :span="16" class="aps-req-right">
<div class="aps-req-right">
<div class="aps-req-scroll">
<el-empty v-if="!currentReq" description="选择产需单查看更多信息" />
<div v-else class="detail-panel">
@@ -74,6 +79,11 @@
<button v-if="currentReq.scheduleStatus === 0 || currentReq.scheduleStatus === 3" class="header-btn"
style="background:rgba(255,255,255,0.4);border-color:rgba(255,255,255,0.7);"
@click="handleDispatch">{{ currentReq.scheduleStatus === 3 ? '重新下发' : '下发' }}</button>
<button v-if="currentReq.scheduleStatus === 1" class="header-btn"
style="background:rgba(255,255,255,0.4);border-color:rgba(255,255,255,0.7);"
@click="handleRecall">撤回</button>
<button v-if="currentReq.scheduleStatus === 1 || currentReq.scheduleStatus === 2" class="header-btn"
@click="openConvertDialogForReq(currentReq)">产需转化</button>
</div>
</div>
<div class="detail-card-body">
@@ -194,13 +204,30 @@
<div class="detail-card">
<div class="detail-card-header">
<span>排产明细{{ requirementDetailList.length }} 合计 {{ detailTotalWeight }} T</span>
<button v-if="canEdit" class="header-btn" @click="handleDetailAdd">+ 新增</button>
<span style="display:flex;align-items:center;gap:8px;">
<span v-if="detailDispatchProgress.total > 0" style="font-size:12px;font-weight:400;opacity:0.9;">
已下发 {{ detailDispatchProgress.issued }} / {{ detailDispatchProgress.total }}{{ detailDispatchProgress.percent }}%
</span>
<button v-if="canEdit" class="header-btn" @click="handleDetailAdd">+ 新增</button>
</span>
</div>
<div class="detail-card-body" style="padding:0;">
<el-table :data="requirementDetailList" border size="small" v-loading="detailLoading" class="aps-table">
<el-table-column label="规格" prop="spec" min-width="120" />
<el-table-column label="材质" prop="material" width="90" align="center" />
<el-table-column label="排产吨数" prop="scheduleWeight" width="100" align="right" />
<el-table-column label="工序步骤" min-width="130">
<template slot-scope="scope">
<span style="font-size:12px;">{{ getStepNamesByProcessId(scope.row.processId) || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="排产日期" prop="scheduleDate" width="110" align="center" />
<el-table-column label="下发状态" width="90" align="center">
<template slot-scope="scope">
<span v-if="scope.row.isIssued === 1 || scope.row.isIssued === '1'" style="color:#52c41a;font-size:12px;">已下发</span>
<span v-else style="color:#c0c4cc;font-size:12px;">未下发</span>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="120" />
<el-table-column label="操作" width="130" align="center" fixed="right">
<template slot-scope="scope">
@@ -217,8 +244,10 @@
</div>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
</drag-resize-panel>
<!-- 新增/编辑对话框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="900px" append-to-body
@@ -350,7 +379,7 @@
<!-- 左侧订单列表 -->
<div style="width: 45%; display: flex; flex-direction: column;">
<div style="display: flex; gap: 6px; margin-bottom: 10px;">
<el-input v-model="bindQuery.keyword" placeholder="搜索订单编号/客户名" size="small" clearable style="flex:1;"
<el-input v-model="bindQuery.keyword" placeholder="搜索订单编号/客户名/业务员" size="small" clearable style="flex:1;"
@change="searchBindOrders" />
<el-button size="small" class="aps-btn-red" icon="el-icon-search" @click="searchBindOrders">搜索</el-button>
</div>
@@ -449,6 +478,68 @@
<el-button @click="detailDialogVisible = false"> </el-button>
</div>
</el-dialog>
<!-- 产需转化对话框 -->
<el-dialog title="产需转化" :visible.sync="convertDialogVisible" width="1100px" append-to-body
:close-on-click-modal="false">
<div style="margin-bottom:12px; font-size:13px; color:#2c3e50;">
产需单号<strong>{{ convertReqNo }}</strong>
<span style="margin-left:16px;"> {{ convertDetailList.length }} 条明细</span>
</div>
<el-table :data="convertDetailList" border size="small" class="aps-table"
@selection-change="(val) => convertSelection = val">
<el-table-column type="selection" width="40" />
<el-table-column label="规格" prop="spec" min-width="100" />
<el-table-column label="材质" prop="material" width="80" align="center" />
<el-table-column label="排产吨数" prop="scheduleWeight" width="90" align="right" />
<el-table-column label="工序ID" width="150" align="center">
<template slot-scope="scope">
<el-select v-model="scope.row.processId" placeholder="选择工序" size="small" clearable filterable
style="width:130px;" @change="(val) => onConvertProcessChange(scope.row, val)">
<el-option v-for="p in processList" :key="p.processId" :label="p.processName" :value="p.processId">
<span>{{ p.processName }}</span>
<span v-if="p._steps" style="display:block;font-size:11px;color:#909399;">{{ p._steps }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="工序步骤" min-width="140">
<template slot-scope="scope">
<span v-if="scope.row._stepNames" style="font-size:12px; color:#2c3e50;">{{ scope.row._stepNames }}</span>
<span v-else style="font-size:12px; color:#c0c4cc;">-</span>
</template>
</el-table-column>
<el-table-column label="排产日期" width="150" align="center">
<template slot-scope="scope">
<el-date-picker v-model="scope.row.scheduleDate" type="date" value-format="yyyy-MM-dd" placeholder="排产日期"
size="small" clearable style="width:130px;" />
</template>
</el-table-column>
<el-table-column label="下发状态" width="80" align="center">
<template slot-scope="scope">
<span v-if="scope.row.isIssued === 1 || scope.row.isIssued === '1'" style="color:#52c41a;font-size:12px;">已下发</span>
<span v-else style="color:#c0c4cc;font-size:12px;">未下发</span>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="100" />
<el-table-column label="操作" width="70" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="small" style="color:#ff4d4f;"
:disabled="!scope.row.processId || !scope.row.scheduleDate"
@click="handleConvertSingle(scope.row)">下发</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="convertProgressShow" style="margin-top:12px;">
<el-progress :percentage="convertProgress" :status="convertProgress === 100 ? 'success' : ''" />
</div>
<div slot="footer" class="dialog-footer" style="margin-top:12px;">
<el-button :loading="convertBtnLoading" type="danger" :disabled="convertSelection.length === 0"
@click="confirmConvertSelected">批量下发({{ convertSelection.length }}</el-button>
<el-button :loading="convertBtnLoading" type="danger" :disabled="!convertAllValid" @click="confirmConvertAll">全部下发</el-button>
<el-button @click="convertDialogVisible = false">关 闭</el-button>
</div>
</el-dialog>
</div>
</template>
@@ -464,13 +555,17 @@ import {
listRel,
addRequirementDetail,
updateRequirementDetail,
delRequirementDetail
delRequirementDetail,
convertRequirementDetail
} from '@/api/aps/requirement'
import { listCrmOrder } from '@/api/aps/order'
import { listProcess } from '@/api/aps/process'
import { parseProductContent } from '@/utils/productContent'
import DragResizePanel from '@/components/DragResizePanel'
export default {
name: 'ApsRequirement',
components: { DragResizePanel },
data() {
return {
// 左侧列表
@@ -520,6 +615,16 @@ export default {
scheduleWeight: [{ required: true, message: '排产吨数不能为空', trigger: 'change' }]
},
// 产需转化对话框
convertDialogVisible: false,
convertDetailList: [],
convertBtnLoading: false,
convertReqNo: '',
convertProgress: 0,
convertProgressShow: false,
convertSelection: [],
processList: [],
// 新增/编辑对话框
dialogVisible: false,
dialogTitle: '新增产需单',
@@ -541,6 +646,16 @@ export default {
const n = Number(item.scheduleWeight)
return isNaN(n) ? sum : sum + n
}, 0)
},
convertAllValid() {
return this.convertDetailList.length > 0 &&
this.convertDetailList.every(d => d.processId && d.scheduleDate)
},
detailDispatchProgress() {
const total = this.requirementDetailList.length
if (total === 0) return { issued: 0, total: 0, percent: 0 }
const issued = this.requirementDetailList.filter(d => d.isIssued === 1 || d.isIssued === '1').length
return { issued, total, percent: Math.round((issued / total) * 100) }
}
},
created() {
@@ -582,6 +697,9 @@ export default {
spec: '',
material: '',
scheduleWeight: 0,
processId: '',
scheduleDate: '',
isIssued: 0,
productType: '',
remark: ''
}
@@ -592,18 +710,6 @@ export default {
this.getList()
},
// 跳转到排产单页面(路由跳转)
handleJumpToSchedule(item) {
this.$router.push({
path: '/aps/schedule',
query: {
prodDate: item.prodDate || '',
scheduleNo: item.scheduleNo || '',
scheduleStatus: item.scheduleStatus
}
})
},
statusBadgeType(status) {
return this.statusBadgeMap[status] || 'gray'
},
@@ -624,11 +730,22 @@ export default {
handleReqClick(item) {
this.currentReq = item
this.detailLoading = true
getRequirement(item.scheduleId).then(res => {
Promise.all([
getRequirement(item.scheduleId),
listProcess({ pageNum: 1, pageSize: 1000 })
]).then(([res, processRes]) => {
if (res.data) {
this.currentReq = res.data
this.requirementDetailList = res.data.detailList || []
}
// 构建工序查找表
this.processList = (processRes.rows || []).map(p => ({
...p,
_steps: (p.stepList && p.stepList.length > 0)
? p.stepList.slice().sort((a, b) => (a.stepOrder || 0) - (b.stepOrder || 0))
.map(s => s.stepName).join(' → ')
: ''
}))
}).catch(() => {
this.requirementDetailList = []
}).finally(() => {
@@ -963,6 +1080,286 @@ export default {
}).catch(() => { })
},
handleRecall() {
this.$confirm('确认撤回该产需单吗?撤回后将恢复为草稿状态。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
updateRequirement({
scheduleId: this.currentReq.scheduleId,
scheduleStatus: 0
}).then(() => {
this.$modal.msgSuccess('撤回成功')
this.getList()
this.handleReqClick(this.currentReq)
}).catch(() => {
this.$modal.msgError('撤回失败')
})
}).catch(() => { })
},
// ====== 产需转化 ======
openConvertDialogForReq(item) {
// 确保加载了该产需单的详情
this.convertReqNo = item.scheduleNo || ''
this.convertProgressShow = false
this.convertProgress = 0
const loadDetail = item.scheduleId === (this.currentReq && this.currentReq.scheduleId)
? Promise.resolve(this.currentReq)
: getRequirement(item.scheduleId)
// 同时加载工序列表和明细
Promise.all([
loadDetail,
listProcess({ pageNum: 1, pageSize: 1000 })
]).then(([res, processRes]) => {
const data = res.data || res
const detailList = (data.detailList || []).map(d => ({ ...d }))
// 构建工序查找表
const processRows = processRes.rows || []
const processMap = new Map()
processRows.forEach(p => {
processMap.set(p.processId, p)
})
this.processList = processRows.map(p => ({
...p,
_steps: (p.stepList && p.stepList.length > 0)
? p.stepList.slice().sort((a, b) => (a.stepOrder || 0) - (b.stepOrder || 0))
.map(s => s.stepName).join(' → ')
: ''
}))
// 为已有 processId 的明细填充 _stepNames默认 scheduleDate 为今天
const today = this.getTodayStr()
detailList.forEach(d => {
if (!d.scheduleDate) {
d.scheduleDate = today
}
if (d.processId) {
this.fillProcessStepInfo(d)
}
})
this.convertDetailList = detailList
this.convertDialogVisible = true
}).catch(() => {
this.convertDetailList = []
this.convertDialogVisible = true
})
},
fillProcessStepInfo(row) {
const pid = row.processId ? String(row.processId) : ''
if (!pid) return
const process = this.processList.find(p => String(p.processId) === pid)
if (process) {
const steps = (process.stepList || []).slice().sort((a, b) => (a.stepOrder || 0) - (b.stepOrder || 0))
row._stepNames = steps.map(s => s.stepName).join(' → ')
row._stepList = steps
} else {
row._stepNames = ''
row._stepList = []
}
},
onConvertProcessChange(row, val) {
if (!val) {
row._stepNames = ''
row._stepList = []
return
}
this.fillProcessStepInfo(row)
},
getStepNamesByProcessId(processId) {
if (!processId) return ''
const pid = String(processId)
const process = this.processList.find(p => String(p.processId) === pid)
if (!process || !process.stepList || process.stepList.length === 0) return ''
return process.stepList.slice().sort((a, b) => (a.stepOrder || 0) - (b.stepOrder || 0))
.map(s => s.stepName).join(' → ')
},
handleConvertSingle(row) {
if (!row.processId) {
this.$message.warning('请先选择工序')
return
}
if (!row.scheduleDate) {
this.$message.warning('请先填写排产日期')
return
}
this.$confirm(`确认下发明细「${row.spec} / ${row.material}」吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.convertBtnLoading = true
// 先保存 processId、scheduleDate 并标记已下发
updateRequirementDetail({
scheduleDetailId: row.scheduleDetailId,
processId: row.processId,
scheduleDate: row.scheduleDate,
isIssued: 1
}).then(() => {
// 构建下发 BO逐条下发
return convertRequirementDetail({
detailList: [{
scheduleDetailId: row.scheduleDetailId,
processId: row.processId || null,
stepList: (row._stepList || []).map(s => ({
stepId: s.stepId,
stepOrder: s.stepOrder,
stepName: s.stepName
}))
}]
})
}).then(() => {
this.$modal.msgSuccess('下发成功')
row.isIssued = 1
this.refreshDetailList()
}).catch(() => {
this.$modal.msgError('下发失败')
}).finally(() => {
this.convertBtnLoading = false
})
}).catch(() => { })
},
confirmConvertAll() {
if (this.convertDetailList.length === 0) {
this.$message.warning('没有可下发的明细')
return
}
const invalidItems = this.convertDetailList.filter(d => !d.processId || !d.scheduleDate)
if (invalidItems.length > 0) {
this.$message.warning(`还有 ${invalidItems.length} 条明细未填写工序或排产日期,请完善后再下发`)
return
}
this.$confirm(`确认下发全部 ${this.convertDetailList.length} 条明细吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.convertBtnLoading = true
this.convertProgressShow = true
this.convertProgress = 0
const total = this.convertDetailList.length
let completed = 0
let failed = 0
const processNext = (index) => {
if (index >= total) {
this.convertBtnLoading = false
this.refreshDetailList()
if (failed === 0) {
this.$modal.msgSuccess(`成功下发 ${completed} 条明细`)
} else if (completed === 0) {
this.$modal.msgError('下发失败,请重试')
} else {
this.$modal.msgWarning(`成功下发 ${completed} 条,${failed} 条失败`)
}
return
}
const row = this.convertDetailList[index]
updateRequirementDetail({
scheduleDetailId: row.scheduleDetailId,
processId: row.processId,
scheduleDate: row.scheduleDate,
isIssued: 1
}).then(() => {
return convertRequirementDetail({
detailList: [{
scheduleDetailId: row.scheduleDetailId,
processId: row.processId,
stepList: (row._stepList || []).map(s => ({
stepId: s.stepId,
stepOrder: s.stepOrder,
stepName: s.stepName
}))
}]
})
}).then(() => {
completed++
row.isIssued = 1
}).catch(() => {
failed++
}).finally(() => {
this.convertProgress = Math.round(((completed + failed) / total) * 100)
processNext(index + 1)
})
}
processNext(0)
}).catch(() => { })
},
confirmConvertSelected() {
if (this.convertSelection.length === 0) {
this.$message.warning('请勾选要下发的明细')
return
}
const invalidItems = this.convertSelection.filter(d => !d.processId || !d.scheduleDate)
if (invalidItems.length > 0) {
this.$message.warning(`所选明细中有 ${invalidItems.length} 条未填写工序或排产日期,请完善后再下发`)
return
}
this.$confirm(`确认下发所选 ${this.convertSelection.length} 条明细吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.convertBtnLoading = true
this.convertProgressShow = true
this.convertProgress = 0
const list = [...this.convertSelection]
const total = list.length
let completed = 0
let failed = 0
const processNext = (index) => {
if (index >= total) {
this.convertBtnLoading = false
this.refreshDetailList()
if (failed === 0) {
this.$modal.msgSuccess(`成功下发 ${completed} 条明细`)
} else if (completed === 0) {
this.$modal.msgError('下发失败,请重试')
} else {
this.$modal.msgWarning(`成功下发 ${completed} 条,${failed} 条失败`)
}
return
}
const row = list[index]
updateRequirementDetail({
scheduleDetailId: row.scheduleDetailId,
processId: row.processId,
scheduleDate: row.scheduleDate,
isIssued: 1
}).then(() => {
return convertRequirementDetail({
detailList: [{
scheduleDetailId: row.scheduleDetailId,
processId: row.processId,
stepList: (row._stepList || []).map(s => ({
stepId: s.stepId,
stepOrder: s.stepOrder,
stepName: s.stepName
}))
}]
})
}).then(() => {
completed++
row.isIssued = 1
}).catch(() => {
failed++
}).finally(() => {
this.convertProgress = Math.round(((completed + failed) / total) * 100)
processNext(index + 1)
})
}
processNext(0)
}).catch(() => { })
},
// ====== 排产明细新增/编辑/删除 ======
resetDetailForm() {
this.detailForm = this.getEmptyDetailForm()
@@ -1058,8 +1455,7 @@ export default {
@import './scss/aps-theme.scss';
.aps-req-page {
height: 100%;
padding: 8px;
height: calc(100vh - 84px);
box-sizing: border-box;
background: $aps-silver-1;
}
@@ -1070,17 +1466,19 @@ export default {
// ====== 左侧(参照 HTML 产需单列表) ======
.aps-req-left {
display: flex;
flex-direction: column;
height: 100%;
background: #fff;
border: 1px solid $aps-silver-3;
border-radius: 6px;
box-sizing: border-box;
overflow: hidden;
min-height: 0;
}
.aps-req-scroll {
height: 100%;
overflow-y: auto;
}
.panel-header {
background: $aps-silver-mid;
padding: 8px 12px;
@@ -1088,15 +1486,12 @@ export default {
font-weight: 600;
color: $aps-text;
border-bottom: 1px solid $aps-border;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.list-container {
flex: 1;
overflow-y: auto;
min-height: 0;
}
@@ -1198,21 +1593,15 @@ export default {
border: 1px solid $aps-silver-3;
border-radius: 6px;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
}
.detail-panel {
flex: 1;
overflow-y: auto;
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
background: $aps-bg;
min-height: 0;
}
// ====== 右侧详情卡片 ======

View File

@@ -13,18 +13,17 @@
@change="handleDateChange"
/>
<el-button size="small" class="aps-btn-red" icon="el-icon-search" @click="handleQuery">查询</el-button>
<el-tabs v-model="activeTab" size="small" style="margin:0 0 0 16px;" @tab-click="handleQuery">
<!-- <el-tabs v-model="activeTab" size="small" style="margin:0 0 0 16px;" @tab-click="handleQuery">
<el-tab-pane label="待审核" name="pending" />
<el-tab-pane label="已接收" name="accepted" />
<el-tab-pane label="已排产" name="scheduled" />
</el-tabs>
<div v-if="summaryText" class="aps-sch-summary">
<span>{{ summaryText }}</span>
</div>
</div> -->
</div>
<!-- 待审核 Tab -->
<div v-loading="loading" v-show="activeTab === 'pending'" class="detail-card aps-sch-card">
<!-- <div v-loading="loading" v-show="activeTab === 'pending'" class="detail-card aps-sch-card">
<div class="detail-card-header">
<span>待审核产需单明细</span>
<span v-if="pendingScheduleList.length > 0" style="font-weight:normal;font-size:12px;opacity:0.8;">
@@ -34,7 +33,6 @@
<div element-loading-text="正在加载待审核产需单..." class="detail-card-body" style="padding:0;">
<div v-if="pendingScheduleList.length > 0" class="aps-sch-list">
<div v-for="sch in pendingScheduleList" :key="sch.scheduleId" class="aps-sch-item">
<!-- 产需单头部排产单号 + 状态标签 + 操作 -->
<div class="aps-sch-item-header">
<div class="aps-sch-item-header-left">
<span class="aps-sch-no">{{ sch.scheduleNo }}</span>
@@ -49,7 +47,6 @@
</div>
</div>
<!-- 产需单完整信息表 -->
<table class="req-info-table">
<colgroup>
<col style="width: 88px;">
@@ -131,7 +128,6 @@
</tbody>
</table>
<!-- 明细列表 -->
<div v-if="(sch.detailList || []).length > 0" class="aps-sch-item-details">
<div class="aps-sch-detail-header">
<span class="aps-sch-detail-col col-spec">规格</span>
@@ -162,7 +158,6 @@
</div>
</div>
<!-- 已接收 Tab -->
<div v-loading="acceptedLoading" v-show="activeTab === 'accepted'" class="detail-card aps-sch-card">
<div class="detail-card-header">
<span>已接收产需单</span>
@@ -283,10 +278,10 @@
{{ hasQueried ? '该日期暂无已接收产需单' : '请选择日期查询' }}
</div>
</div>
</div>
</div> -->
<!-- 已排产 Tab -->
<div v-loading="schLoading" v-show="activeTab === 'scheduled'" class="detail-card aps-sch-card">
<div v-loading="schLoading" class="detail-card aps-sch-card">
<div class="detail-card-header">
<span>已排产明细</span>
<div style="display:flex; align-items:center; gap:8px;">
@@ -696,7 +691,7 @@ export default {
const d = String(today.getDate()).padStart(2, '0')
return {
queryDate: `${y}-${m}-${d}`,
activeTab: 'pending',
activeTab: 'scheduled',
loading: false,
schLoading: false,
hasQueried: false,