feat: 新增检测单关联、基础数据优化与入库单升级
1. 新增出库单检测单号字段并添加索引支持溯源 2. 优化基础数据页面物料类型展示与选择逻辑 3. 升级入库单导入功能,支持自动生成单号并返回导入结果 4. 优化接驳台查询排序方式 5. 修复字符串拼接空格问题
This commit is contained in:
@@ -917,8 +917,8 @@ async function onMaterialFile(e) {
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.manageMode === 2 ? 'warning' : 'info'" size="small">
|
||||
{{ row.manageMode === 2 ? '电气件(SN)' : '结构件(批次)' }}
|
||||
<el-tag :type="row.itemType === 4 ? 'info' : (row.manageMode === 2 ? 'warning' : 'primary')" size="small">
|
||||
{{ row.itemType === 4 ? '其他' : (row.manageMode === 2 ? '电气件(SN)' : '结构件(批次)') }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -967,8 +967,13 @@ async function onMaterialFile(e) {
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" required>
|
||||
<el-select v-model="mForm.manageMode" placeholder="请选择" style="width:100%" :disabled="Number(mForm.itemType) === 4">
|
||||
<el-option :value="1" label="结构件(批次管理)" />
|
||||
<el-option :value="2" label="电气件(SN 管理)" />
|
||||
<template v-if="Number(mForm.itemType) === 4">
|
||||
<el-option :value="1" label="其他(辅料/工装/试验设备)" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-option :value="1" label="结构件(批次管理)" />
|
||||
<el-option :value="2" label="电气件(SN 管理)" />
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="安全库存" required>
|
||||
|
||||
@@ -91,7 +91,7 @@ const batchRef = ref()
|
||||
const submitting1 = ref(false)
|
||||
const lastInboundNo = ref('')
|
||||
const form1 = reactive({
|
||||
materialCode: '', batchNo: '', quantity: 1,
|
||||
inboundNo: '', materialCode: '', batchNo: '', quantity: 1,
|
||||
zoneCode: '', shelfNo: '', layerNo: '', positionNo: '',
|
||||
ownershipType: '', ownershipNo: '',
|
||||
productionDate: '', supplier: '', remark: '', inspectionNo: ''
|
||||
@@ -124,6 +124,7 @@ async function submitBatch() {
|
||||
submitting1.value = true
|
||||
try {
|
||||
const data = await request.post('/inbound/create', {
|
||||
inboundNo: form1.inboundNo.trim(),
|
||||
inboundType: 'purchase',
|
||||
materialCode: form1.materialCode,
|
||||
batchNo: form1.batchNo.trim(),
|
||||
@@ -157,7 +158,7 @@ async function submitBatch() {
|
||||
const snInput = ref('')
|
||||
const submitting2 = ref(false)
|
||||
const snList = ref([])
|
||||
const form2 = reactive({ materialCode: '', zoneCode: '', shelfNo: '', layerNo: '', positionNo: '', ownershipType: '', ownershipNo: '', remark: '', inspectionNo: '' })
|
||||
const form2 = reactive({ inboundNo: '', materialCode: '', zoneCode: '', shelfNo: '', layerNo: '', positionNo: '', ownershipType: '', ownershipNo: '', remark: '', inspectionNo: '' })
|
||||
// 与 Tab1/Tab3 对齐:走 el-form 校验,必填项既爆红又弹窗
|
||||
const form2Ref = ref(null)
|
||||
const rules2 = {
|
||||
@@ -205,6 +206,7 @@ async function submitSn() {
|
||||
submitting2.value = true
|
||||
try {
|
||||
const data = await request.post('/inbound/create', {
|
||||
inboundNo: form2.inboundNo.trim(),
|
||||
inboundType: 'purchase',
|
||||
materialCode: form2.materialCode,
|
||||
zoneCode: form2.zoneCode,
|
||||
@@ -275,6 +277,7 @@ async function importExcel(mode, which) {
|
||||
const otherRef = ref()
|
||||
const submitting3 = ref(false)
|
||||
const form3 = reactive({
|
||||
inboundNo: '',
|
||||
materialCode: '', batchNo: '', quantity: 1, zoneCode: '',
|
||||
shelfNo: '', layerNo: '', positionNo: '',
|
||||
ownershipType: '', ownershipNo: '',
|
||||
@@ -322,6 +325,7 @@ async function submitOther() {
|
||||
submitting3.value = true
|
||||
try {
|
||||
const data = await request.post('/inbound/create', {
|
||||
inboundNo: form3.inboundNo.trim(),
|
||||
inboundType: 'other',
|
||||
materialCode: form3.materialCode,
|
||||
batchNo: form3.batchNo.trim(),
|
||||
@@ -352,7 +356,7 @@ async function submitOther() {
|
||||
|
||||
/* ===================== Tab4 入库记录(统一主表 + 抽屉明细,不分页内嵌子表) ===================== */
|
||||
// 查询条件
|
||||
const filters = reactive({ inboundNo: '', materialCode: '', manageMode: '', materialName: '', voided: '' })
|
||||
const filters = reactive({ inboundNo: '', materialCode: '', manageMode: '', materialName: '', voided: '', inspectionNo: '' })
|
||||
const dateRange = ref([]) // [开始日期, 结束日期] YYYY-MM-DD
|
||||
const loadingRec = ref(false)
|
||||
const list = ref([])
|
||||
@@ -370,6 +374,7 @@ async function loadRecords() {
|
||||
manageMode: filters.manageMode === 'other' ? '' : filters.manageMode,
|
||||
inboundType: filters.manageMode === 'other' ? 'other' : '',
|
||||
materialName: filters.materialName.trim(),
|
||||
inspectionNo: filters.inspectionNo.trim(),
|
||||
voided: filters.voided,
|
||||
startDate: dateRange.value?.[0] || '',
|
||||
endDate: dateRange.value?.[1] || '',
|
||||
@@ -393,6 +398,7 @@ function resetFilters() {
|
||||
filters.materialCode = ''
|
||||
filters.manageMode = ''
|
||||
filters.materialName = ''
|
||||
filters.inspectionNo = ''
|
||||
filters.voided = ''
|
||||
dateRange.value = []
|
||||
search()
|
||||
@@ -437,6 +443,7 @@ async function exportCsv() {
|
||||
manageMode: filters.manageMode === 'other' ? '' : filters.manageMode,
|
||||
inboundType: filters.manageMode === 'other' ? 'other' : '',
|
||||
materialName: filters.materialName.trim(),
|
||||
inspectionNo: filters.inspectionNo.trim(),
|
||||
voided: filters.voided,
|
||||
startDate: dateRange.value?.[0] || '',
|
||||
endDate: dateRange.value?.[1] || ''
|
||||
@@ -447,10 +454,10 @@ async function exportCsv() {
|
||||
}
|
||||
|
||||
// 入库单明细:点击"明细"用右侧抽屉懒加载 + 分页(不在列表内嵌子表,避免表格套表格)
|
||||
const detailDrawer = reactive({ visible: false, inboundNo: '', list: [], total: 0, page: 1, size: 50, loading: false, loaded: false })
|
||||
const detailDrawer = reactive({ visible: false, inboundNo: '', list: [], total: 0, page: 1, size: 20, loading: false, loaded: false })
|
||||
async function openDetail(row) {
|
||||
const no = row.inboundNo
|
||||
Object.assign(detailDrawer, { visible: true, inboundNo: no, list: [], total: 0, page: 1, size: 50, loaded: false })
|
||||
Object.assign(detailDrawer, { visible: true, inboundNo: no, list: [], total: 0, page: 1, size: 20, loaded: false })
|
||||
await fetchDetailPage()
|
||||
}
|
||||
async function fetchDetailPage() {
|
||||
@@ -657,6 +664,9 @@ onActivated(() => {
|
||||
placeholder="请填写归属编号" clearable style="width:260px" />
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
<el-form-item label="入库单号">
|
||||
<el-input v-model="form1.inboundNo" placeholder="留空自动生成(如 IB20260921-001)" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="检测单号" prop="inspectionNo">
|
||||
<el-input v-model="form1.inspectionNo" placeholder="入库检报告单号(必填)" clearable />
|
||||
</el-form-item>
|
||||
@@ -747,6 +757,9 @@ onActivated(() => {
|
||||
placeholder="请填写归属编号" clearable style="width:260px" />
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
<el-form-item label="入库单号">
|
||||
<el-input v-model="form2.inboundNo" placeholder="留空自动生成(如 IB20260921-001)" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="检测单号" prop="inspectionNo">
|
||||
<el-input v-model="form2.inspectionNo" placeholder="入库检报告单号(必填)" clearable />
|
||||
</el-form-item>
|
||||
@@ -855,6 +868,9 @@ onActivated(() => {
|
||||
<el-form-item label="供应商">
|
||||
<el-input v-model="form3.supplier" placeholder="供应商名称(可空)" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="入库单号">
|
||||
<el-input v-model="form3.inboundNo" placeholder="留空自动生成(如 IB20260921-001)" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="检测单号" prop="inspectionNo">
|
||||
<el-input v-model="form3.inspectionNo" placeholder="入库检报告单号(必填)" clearable />
|
||||
</el-form-item>
|
||||
@@ -898,6 +914,9 @@ onActivated(() => {
|
||||
<el-form-item label="物料名称">
|
||||
<el-input v-model="filters.materialName" placeholder="物料名称(模糊)" clearable style="width:160px" @keyup.enter="search" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检测单号">
|
||||
<el-input v-model="filters.inspectionNo" placeholder="检测单号(模糊)" clearable style="width:180px" @keyup.enter="search" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="filters.voided" placeholder="全部" clearable style="width:120px" @change="search">
|
||||
<el-option label="有效" value="false" />
|
||||
|
||||
@@ -211,11 +211,7 @@ async function submitInspection() {
|
||||
manufacturer.value = ''
|
||||
await loadRecords()
|
||||
if (allPass && passedNo) {
|
||||
try {
|
||||
await ElMessageBox.confirm(`检验合格,是否携检测单号 ${passedNo} 前往入库?`, '前往入库',
|
||||
{ type: 'success', confirmButtonText: '去入库', cancelButtonText: '留在本页' })
|
||||
router.push({ path: '/inbound', query: { inspectionNo: passedNo } })
|
||||
} catch { /* 用户选择留在本页 */ }
|
||||
ElMessage.success(`检验合格,检测单号 ${passedNo}`)
|
||||
}
|
||||
} finally {
|
||||
submitting.value = false
|
||||
@@ -228,7 +224,44 @@ const pendingLoading = ref(false)
|
||||
const pendingRows = ref([])
|
||||
const pendingTotal = ref(0)
|
||||
const pendingPage = reactive({ current: 1, size: 20 })
|
||||
const pendingSelected = ref([]) // 选中的明细 targetId 集合(跨行)
|
||||
|
||||
// 抽屉:右侧滑出,分页加载该入库单+物料的未检明细(替代原 el-table type="expand" 嵌套子表)
|
||||
const detailDrawer = reactive({
|
||||
visible: false,
|
||||
row: null, // 主行快照(inboundNo/materialCode/ownership 等,整单送检/带入时用)
|
||||
list: [], // 当前页明细
|
||||
total: 0, // 明细总数
|
||||
page: 1,
|
||||
size: 20,
|
||||
loading: false,
|
||||
selected: [] // 抽屉内勾选的 targetId 集合
|
||||
})
|
||||
const detailDrawerSelectedIds = computed(() => new Set(detailDrawer.selected))
|
||||
|
||||
function openDetailDrawer(row) {
|
||||
Object.assign(detailDrawer, {
|
||||
visible: true, row: { ...row },
|
||||
list: [], total: 0, page: 1, size: 20, loading: false, selected: []
|
||||
})
|
||||
fetchDetailDrawerPage()
|
||||
}
|
||||
async function fetchDetailDrawerPage() {
|
||||
const st = detailDrawer
|
||||
st.loading = true
|
||||
try {
|
||||
const d = await request.get('/inspection/pending/details', {
|
||||
params: { inboundNo: st.row.inboundNo, materialCode: st.row.materialCode, page: st.page, pageSize: st.size }
|
||||
})
|
||||
st.list = d?.list || []
|
||||
st.total = d?.total || 0
|
||||
} finally {
|
||||
st.loading = false
|
||||
}
|
||||
}
|
||||
function changeDetailDrawerPage(p) {
|
||||
detailDrawer.page = p
|
||||
fetchDetailDrawerPage()
|
||||
}
|
||||
|
||||
const inboundTypeLabel = (t) => {
|
||||
const m = { purchase: '采购入库', semi: '半成品入库', finished: '成品入库', return: '退库入库', other: '其他入库' }
|
||||
@@ -259,28 +292,37 @@ function searchPending() {
|
||||
pendingPage.current = 1
|
||||
loadPending()
|
||||
}
|
||||
// 整单送检 / 单条送检 / 选中送检
|
||||
function sendWhole(row) {
|
||||
sendToEntry(row.details || [], row)
|
||||
|
||||
// 整单送检:直接按 inboundNo+materialCode 拉全量未检明细(pageSize=99999,一次入库单 3000 条可接受)
|
||||
async function sendWhole(row) {
|
||||
const d = await request.get('/inspection/pending/details', {
|
||||
params: { inboundNo: row.inboundNo, materialCode: row.materialCode, page: 1, pageSize: 99999 }
|
||||
})
|
||||
const details = d?.list || []
|
||||
sendToEntry(details, row)
|
||||
}
|
||||
function sendOne(row, detail) {
|
||||
sendToEntry([detail], row)
|
||||
function sendOneFromDrawer(detail) {
|
||||
sendToEntry([detail], detailDrawer.row)
|
||||
}
|
||||
function sendSelected() {
|
||||
if (!pendingSelected.value.length) {
|
||||
function sendSelectedFromDrawer() {
|
||||
if (!detailDrawer.selected.length) {
|
||||
ElMessage.warning('请先勾选要送检的批次/SN')
|
||||
return
|
||||
}
|
||||
const details = []
|
||||
for (const row of pendingRows.value) {
|
||||
for (const d of row.details || []) {
|
||||
if (pendingSelected.value.includes(d.targetId)) details.push(d)
|
||||
}
|
||||
if (detailDrawer.selected.length > 100) {
|
||||
ElMessageBox.confirm('单次送检上限 100 条,请分批送检。', '提示', { type: 'warning', confirmButtonText: '知道了', showCancelButton: false })
|
||||
return
|
||||
}
|
||||
// 归属取首个命中行的入库单
|
||||
const firstRow = pendingRows.value.find((r) => (r.details || []).some((d) => pendingSelected.value.includes(d.targetId)))
|
||||
sendToEntry(details, firstRow)
|
||||
pendingSelected.value = []
|
||||
// 合并已加载页里的选中项 + 翻页选中的项(用 total details 拉全量过滤,避免跨页丢选)
|
||||
// 但跨页选中无法从当前抽屉 list 覆盖,用全量过滤 targetId
|
||||
const ids = new Set(detailDrawer.selected)
|
||||
request.get('/inspection/pending/details', {
|
||||
params: { inboundNo: detailDrawer.row.inboundNo, materialCode: detailDrawer.row.materialCode, page: 1, pageSize: 99999 }
|
||||
}).then((d) => {
|
||||
const details = (d?.list || []).filter((x) => ids.has(x.targetId))
|
||||
sendToEntry(details, detailDrawer.row)
|
||||
detailDrawer.selected = []
|
||||
})
|
||||
}
|
||||
|
||||
/* ===================== 不合格处置 ===================== */
|
||||
@@ -590,38 +632,11 @@ onMounted(() => {
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="pendingLoading" @click="searchPending">查询</el-button>
|
||||
<el-button :disabled="!pendingSelected.length" @click="sendSelected">送检选中 ({{ pendingSelected.length }})</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="待检清单(quality_status=未检,按入库单分组,点开看批次/SN 明细)">
|
||||
<el-table :data="pendingRows" border size="small" v-loading="pendingLoading" empty-text="暂无待检(全部已检)" row-key="inboundNo">
|
||||
<el-table-column type="expand">
|
||||
<template #default="{ row }">
|
||||
<el-table :data="row.details" border size="small" style="width:100%">
|
||||
<el-table-column width="50" align="center">
|
||||
<template #default="{ row: d }">
|
||||
<el-checkbox :model-value="pendingSelected.includes(d.targetId)" @change="(v)=>{ v ? pendingSelected.push(d.targetId) : pendingSelected = pendingSelected.filter(x=>x!==d.targetId) }" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="编号" prop="targetId" min-width="160" />
|
||||
<el-table-column label="类型" width="80" align="center">
|
||||
<template #default="{ row: d }">{{ pendingTargetLabel(d) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" width="80" align="center">
|
||||
<template #default="{ row: d }">{{ d.quantity }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="区域" width="100" align="center">
|
||||
<template #default="{ row: d }">{{ d.zoneCode || '未分区' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template #default="{ row: d }">
|
||||
<el-button link type="success" size="small" @click="sendOne(row, d)">送检此条</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-card shadow="never" header="待检清单(quality_status=未检,按入库单分组;点「查看明细」右侧抽屉)">
|
||||
<el-table :data="pendingRows" border size="small" v-loading="pendingLoading" empty-text="暂无待检(全部已检)">
|
||||
<el-table-column prop="inboundNo" label="入库单号" min-width="160" />
|
||||
<el-table-column label="入库类型" width="110" align="center">
|
||||
<template #default="{ row }">{{ inboundTypeLabel(row.inboundType) }}</template>
|
||||
@@ -633,8 +648,8 @@ onMounted(() => {
|
||||
<el-table-column label="未检数量" width="100" align="center">
|
||||
<template #default="{ row }">{{ row.unInspectedQty }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批次/SN数" width="100" align="center">
|
||||
<template #default="{ row }">{{ row.batchSnCount }}</template>
|
||||
<el-table-column label="未检条数" width="100" align="center">
|
||||
<template #default="{ row }">{{ row.detailsTotal }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="归属" min-width="160" align="center">
|
||||
<template #default="{ row }">
|
||||
@@ -645,8 +660,9 @@ onMounted(() => {
|
||||
<el-table-column label="入库时间" width="155" align="center">
|
||||
<template #default="{ row }">{{ row.inboundTime ? fmtTime(row.inboundTime) : '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="110" align="center" fixed="right">
|
||||
<el-table-column label="操作" width="170" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" size="small" @click="openDetailDrawer(row)">查看明细</el-button>
|
||||
<el-button link type="success" size="small" @click="sendWhole(row)">整单送检</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -813,6 +829,53 @@ onMounted(() => {
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 待检清单明细抽屉(替代原 expand 嵌套子表,后端分页每页 20) -->
|
||||
<el-drawer v-model="detailDrawer.visible"
|
||||
:title="`待检明细:${detailDrawer.row?.inboundNo} · ${detailDrawer.row?.materialCode}`"
|
||||
size="640px" destroy-on-close>
|
||||
<div v-if="detailDrawer.row" style="margin-bottom:10px">
|
||||
<el-tag type="info" size="small">{{ inboundTypeLabel(detailDrawer.row.inboundType) }}</el-tag>
|
||||
<el-tag size="small" style="margin-left:6px">{{ detailDrawer.row.materialName || '-' }}</el-tag>
|
||||
<el-tag size="small" style="margin-left:6px">{{ ownershipTypeLabel(detailDrawer.row.ownershipType) }}:{{ detailDrawer.row.ownershipNo || '-' }}</el-tag>
|
||||
</div>
|
||||
<el-table :data="detailDrawer.list" border size="small" v-loading="detailDrawer.loading" empty-text="暂无明细">
|
||||
<el-table-column width="50" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-checkbox :model-value="detailDrawerSelectedIds.has(row.targetId)"
|
||||
@change="(v) => { v ? detailDrawer.selected.push(row.targetId) : (detailDrawer.selected = detailDrawer.selected.filter(x => x !== row.targetId)) }" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="编号" prop="targetId" min-width="170" />
|
||||
<el-table-column label="类型" width="80" align="center">
|
||||
<template #default="{ row }">{{ pendingTargetLabel(row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" width="70" align="center">
|
||||
<template #default="{ row }">{{ row.quantity }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="区域" width="90" align="center">
|
||||
<template #default="{ row }">{{ row.zoneCode || '未分区' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="success" size="small" @click="sendOneFromDrawer(row)">送检</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="detailDrawer.total > detailDrawer.size" class="pager" style="margin-top:12px">
|
||||
<el-pagination background layout="total, prev, pager, next"
|
||||
:total="detailDrawer.total" :current-page="detailDrawer.page"
|
||||
:page-size="detailDrawer.size"
|
||||
@current-change="changeDetailDrawerPage" />
|
||||
<span style="margin-left:12px;color:#909399;font-size:12px">共 {{ detailDrawer.total }} 条,已加载 {{ detailDrawer.list.length }} / 页 {{ detailDrawer.page }}</span>
|
||||
</div>
|
||||
<div v-if="detailDrawer.total > 0" style="margin-top:12px;display:flex;gap:12px;align-items:center">
|
||||
<el-button type="primary" :disabled="!detailDrawer.selected.length" @click="sendSelectedFromDrawer">
|
||||
批量送检 ({{ detailDrawer.selected.length }})<span v-if="detailDrawer.selected.length>100" style="color:#f56c6c"> 上限 100</span>
|
||||
</el-button>
|
||||
<el-button type="success" plain @click="sendWhole(detailDrawer.row)">整单送检(全部 {{ detailDrawer.total }} 条)</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 不合格处置弹窗 -->
|
||||
<el-dialog v-model="disposeDialog.visible" title="不合格品处置" width="480px">
|
||||
<el-form label-width="96px">
|
||||
|
||||
@@ -131,10 +131,12 @@ const batchOptions = ref([])
|
||||
// 选中物料的展示类型(问题18:类型含「其他」):other=其他品类(按批次管理)/sn=电气件/batch=结构件
|
||||
const pickedType = ref('')
|
||||
const genForm = reactive({
|
||||
outboundNo: '',
|
||||
materialCode: '', mode: 1, batchNo: '', qty: 1, zoneCode: '',
|
||||
shelfNo: '', layerNo: '', positionNo: '',
|
||||
boxNo: '', contractNo: '', remark: '',
|
||||
outboundCategory: 'other', ownershipType: 'other', ownershipNo: '', targetStation: ''
|
||||
outboundCategory: 'other', ownershipType: 'other', ownershipNo: '', targetStation: '',
|
||||
inspectionNo: ''
|
||||
})
|
||||
const snInput = ref('')
|
||||
const snList = ref([])
|
||||
@@ -297,8 +299,10 @@ async function submitGen() {
|
||||
ElMessage.warning('出库类别选「其他」时,请在备注中填写具体原因'); return
|
||||
}
|
||||
const payload = {
|
||||
outboundNo: genForm.outboundNo.trim() || undefined,
|
||||
materialCode: genForm.materialCode, operator,
|
||||
outboundCategory: genForm.outboundCategory,
|
||||
batchNo: batchVal,
|
||||
ownershipType: genForm.ownershipType,
|
||||
ownershipNo: genForm.ownershipNo.trim() || undefined,
|
||||
targetStation: genForm.targetStation.trim() || undefined,
|
||||
@@ -308,7 +312,8 @@ async function submitGen() {
|
||||
positionNo: genForm.positionNo || undefined,
|
||||
boxNo: genForm.boxNo.trim() || undefined,
|
||||
contractNo: genForm.contractNo.trim() || undefined,
|
||||
remark: genForm.remark.trim() || undefined
|
||||
remark: genForm.remark.trim() || undefined,
|
||||
inspectionNo: genForm.inspectionNo.trim() || undefined
|
||||
}
|
||||
if (genForm.mode === 1) {
|
||||
if (!genForm.batchNo) { ElMessage.warning('请从该物料可用批次中选择出库批次'); return }
|
||||
@@ -345,7 +350,7 @@ function recDefaultRange() {
|
||||
const end = new Date(); const start = new Date(); start.setMonth(start.getMonth() - 3)
|
||||
return [fmt(start), fmt(end)]
|
||||
}
|
||||
const recFilters = reactive({ outboundType: '', status: '', materialCode: '', boxNo: '', ownershipNo: '', dateRange: recDefaultRange() })
|
||||
const recFilters = reactive({ outboundType: '', status: '', materialCode: '', boxNo: '', ownershipNo: '', inspectionNo: '', dateRange: recDefaultRange() })
|
||||
const recRows = ref([])
|
||||
const recTotal = ref(0)
|
||||
const loadingRec = ref(false)
|
||||
@@ -362,6 +367,7 @@ async function loadRecords() {
|
||||
materialCode: recFilters.materialCode.trim(),
|
||||
boxNo: recFilters.boxNo.trim(),
|
||||
ownershipNo: recFilters.ownershipNo.trim(),
|
||||
inspectionNo: recFilters.inspectionNo.trim(),
|
||||
page: recPage.current, pageSize: recPage.size
|
||||
}
|
||||
if (Array.isArray(recFilters.dateRange) && recFilters.dateRange.length === 2) {
|
||||
@@ -385,6 +391,7 @@ function downloadCSV() {
|
||||
materialCode: recFilters.materialCode.trim(),
|
||||
boxNo: recFilters.boxNo.trim(),
|
||||
ownershipNo: recFilters.ownershipNo.trim(),
|
||||
inspectionNo: recFilters.inspectionNo.trim(),
|
||||
startDate: dr[0],
|
||||
endDate: dr[1]
|
||||
}, '出库管理.xlsx', { countUrl: '/outbound/query', name: '出库记录' })
|
||||
@@ -482,11 +489,18 @@ onMounted(loadDicts)
|
||||
<span v-else style="color:#909399;font-size:12px">请先选择物料,系统自动带出类型(电气件/结构件)</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="出库单号">
|
||||
<el-input v-model="genForm.outboundNo" placeholder="留空自动生成(如 OB20260921-001)" clearable style="width:100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="出库类别" required>
|
||||
<el-select v-model="genForm.outboundCategory" style="width:100%">
|
||||
<el-option v-for="c in CATEGORY_OPTIONS" :key="c.value" :value="c.value" :label="c.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="检测单号">
|
||||
<el-input v-model="genForm.inspectionNo" placeholder="退货/报废需溯源检验单据时填写(选填)" clearable style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="归属">
|
||||
<el-select v-model="genForm.ownershipType" style="width:160px;margin-right:8px">
|
||||
<el-option v-for="o in OWNERSHIP_OPTIONS" :key="o.value" :value="o.value" :label="o.label" />
|
||||
@@ -642,6 +656,9 @@ onMounted(loadDicts)
|
||||
<el-form-item label="归属单号">
|
||||
<el-input v-model="recFilters.ownershipNo" placeholder="工单号/科技项目号" clearable style="width:160px" @keyup.enter="searchRec" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检测单号">
|
||||
<el-input v-model="recFilters.inspectionNo" placeholder="检测单号(模糊)" clearable style="width:180px" @keyup.enter="searchRec" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时间">
|
||||
<el-date-picker v-model="recFilters.dateRange" type="daterange" value-format="YYYY-MM-DD"
|
||||
range-separator="至" start-placeholder="开始" end-placeholder="结束" style="width:240px" />
|
||||
|
||||
Reference in New Issue
Block a user