feat: 采购到货单、库区标签打印、EBOM表格优化
- 采购到货单: 新建 arrivalnotice API,重构 Checkin 页面对齐到货通知功能 - 库区标签打印: 新增 LocationLabelPrint 组件,支持单个/批量打印(4列排版) - EBOM: 表格表头和内容不换行,过长截断显示 Made-with: Cursor
This commit is contained in:
141
erp-frontend-vue/src/api/arrivalnotice.ts
Normal file
141
erp-frontend-vue/src/api/arrivalnotice.ts
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import request from './request'
|
||||||
|
|
||||||
|
/** 到货通知单 */
|
||||||
|
export interface ArrivalNotice {
|
||||||
|
noticeId?: number
|
||||||
|
noticeCode?: string
|
||||||
|
noticeName?: string
|
||||||
|
poCode?: string
|
||||||
|
vendorId?: number
|
||||||
|
vendorCode?: string
|
||||||
|
vendorName?: string
|
||||||
|
vendorNick?: string
|
||||||
|
arrivalDate?: string
|
||||||
|
contact?: string
|
||||||
|
tel?: string
|
||||||
|
status?: string
|
||||||
|
remark?: string
|
||||||
|
createTime?: string
|
||||||
|
updateTime?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 到货通知单行 */
|
||||||
|
export interface ArrivalNoticeLine {
|
||||||
|
lineId?: number
|
||||||
|
noticeId?: number
|
||||||
|
itemId?: number
|
||||||
|
itemCode?: string
|
||||||
|
itemName?: string
|
||||||
|
specification?: string
|
||||||
|
unitOfMeasure?: string
|
||||||
|
unitName?: string
|
||||||
|
quantityArrival?: number
|
||||||
|
quantityQuanlified?: number
|
||||||
|
iqcCheck?: string
|
||||||
|
iqcId?: number
|
||||||
|
iqcCode?: string
|
||||||
|
remark?: string
|
||||||
|
createTime?: string
|
||||||
|
updateTime?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 到货通知单查询参数 */
|
||||||
|
export interface ArrivalNoticeQuery {
|
||||||
|
noticeCode?: string
|
||||||
|
noticeName?: string
|
||||||
|
poCode?: string
|
||||||
|
vendorId?: number
|
||||||
|
vendorName?: string
|
||||||
|
arrivalDate?: string
|
||||||
|
status?: string
|
||||||
|
pageNum?: number
|
||||||
|
pageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArrivalNoticeListResponse {
|
||||||
|
rows: ArrivalNotice[]
|
||||||
|
total: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArrivalNoticeLineListResponse {
|
||||||
|
rows: ArrivalNoticeLine[]
|
||||||
|
total: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const NOTICE_BASE = '/mes/wm/arrivalnotice'
|
||||||
|
const LINE_BASE = '/mes/wm/arrivalnoticeline'
|
||||||
|
|
||||||
|
// ============ 到货通知单 ============
|
||||||
|
|
||||||
|
/** 查询到货通知单列表 */
|
||||||
|
export function listArrivalNotice(query?: ArrivalNoticeQuery): Promise<ArrivalNoticeListResponse> {
|
||||||
|
return request.get(`${NOTICE_BASE}/list`, { params: query }).then((res: any) => ({
|
||||||
|
rows: res.rows || [],
|
||||||
|
total: res.total || 0
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询到货通知单详情 */
|
||||||
|
export function getArrivalNotice(noticeId: number): Promise<ArrivalNotice> {
|
||||||
|
return request.get(`${NOTICE_BASE}/${noticeId}`).then((res: any) => res.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增到货通知单 */
|
||||||
|
export function addArrivalNotice(data: Partial<ArrivalNotice>): Promise<{ data?: number }> {
|
||||||
|
return request.post(NOTICE_BASE, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改到货通知单 */
|
||||||
|
export function updateArrivalNotice(data: Partial<ArrivalNotice>): Promise<void> {
|
||||||
|
return request.put(NOTICE_BASE, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除到货通知单 */
|
||||||
|
export function deleteArrivalNotice(noticeId: number | number[]): Promise<void> {
|
||||||
|
const ids = Array.isArray(noticeId) ? noticeId.join(',') : String(noticeId)
|
||||||
|
return request.delete(`${NOTICE_BASE}/${ids}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 生成到货通知单编码 */
|
||||||
|
export function genArrivalNoticeCode(): Promise<string> {
|
||||||
|
return request.get('/system/autocode/get/ARRIVALNOTICE_CODE').then((res: any) => res.data ?? res.msg ?? '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 到货通知单行 ============
|
||||||
|
|
||||||
|
/** 查询到货通知单行列表 */
|
||||||
|
export function listArrivalNoticeLine(query?: { noticeId?: number; pageNum?: number; pageSize?: number }): Promise<ArrivalNoticeLineListResponse> {
|
||||||
|
return request.get(`${LINE_BASE}/list`, { params: query }).then((res: any) => ({
|
||||||
|
rows: res.rows || [],
|
||||||
|
total: res.total || 0
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询到货通知单行详情 */
|
||||||
|
export function getArrivalNoticeLine(lineId: number): Promise<ArrivalNoticeLine> {
|
||||||
|
return request.get(`${LINE_BASE}/${lineId}`).then((res: any) => res.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增到货通知单行 */
|
||||||
|
export function addArrivalNoticeLine(data: Partial<ArrivalNoticeLine>): Promise<void> {
|
||||||
|
return request.post(LINE_BASE, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改到货通知单行 */
|
||||||
|
export function updateArrivalNoticeLine(data: Partial<ArrivalNoticeLine>): Promise<void> {
|
||||||
|
return request.put(LINE_BASE, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除到货通知单行 */
|
||||||
|
export function deleteArrivalNoticeLine(lineId: number | number[]): Promise<void> {
|
||||||
|
const ids = Array.isArray(lineId) ? lineId.join(',') : String(lineId)
|
||||||
|
return request.delete(`${LINE_BASE}/${ids}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 状态映射 ============
|
||||||
|
|
||||||
|
export const ARRIVAL_NOTICE_STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||||
|
PREPARE: { label: '开立', type: 'info' },
|
||||||
|
APPROVING: { label: '提交中', type: 'warning' },
|
||||||
|
APPROVED: { label: '待入库', type: 'success' }
|
||||||
|
}
|
||||||
@@ -2,61 +2,63 @@
|
|||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<el-card class="search-card" shadow="never">
|
<el-card class="search-card" shadow="never">
|
||||||
<el-form :model="queryParams" inline>
|
<el-form :model="queryParams" inline>
|
||||||
<el-form-item label="跟单编号">
|
<el-form-item label="通知单编号">
|
||||||
<el-input v-model="queryParams.trackCode" placeholder="请输入" clearable style="width: 140px;" />
|
<el-input v-model="queryParams.noticeCode" placeholder="请输入" clearable style="width: 140px;" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="单据编码">
|
<el-form-item label="通知单名称">
|
||||||
<el-input v-model="queryParams.checkinCode" placeholder="请输入" clearable style="width: 140px;" />
|
<el-input v-model="queryParams.noticeName" placeholder="请输入" clearable style="width: 140px;" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="供应商">
|
<el-form-item label="采购订单编号">
|
||||||
<el-input v-model="queryParams.supplierName" placeholder="请输入" clearable style="width: 150px;" />
|
<el-input v-model="queryParams.poCode" placeholder="请输入" clearable style="width: 140px;" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="日期">
|
<el-form-item label="供应商名称">
|
||||||
<el-date-picker v-model="dateRange" type="daterange" range-separator="-" start-placeholder="开始" end-placeholder="结束" value-format="YYYY-MM-DD" style="width: 220px;" />
|
<el-input v-model="queryParams.vendorName" placeholder="请输入" clearable style="width: 150px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="到货日期">
|
||||||
|
<el-date-picker v-model="queryParams.arrivalDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" clearable style="width: 140px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单据状态">
|
||||||
|
<el-select v-model="queryParams.status" placeholder="请选择" clearable style="width: 120px;">
|
||||||
|
<el-option label="开立" value="PREPARE" />
|
||||||
|
<el-option label="提交中" value="APPROVING" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleQuery"><el-icon><Search /></el-icon>搜索</el-button>
|
<el-button type="primary" @click="handleQuery"><el-icon><Search /></el-icon>搜索</el-button>
|
||||||
|
<el-button @click="handleReset">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="table-card" shadow="never">
|
<el-card class="table-card" shadow="never">
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<el-button @click="handleDocument">单据</el-button>
|
|
||||||
<el-button @click="handleQueryAll">查询所有</el-button>
|
|
||||||
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon>新增</el-button>
|
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon>新增</el-button>
|
||||||
<el-button type="success" @click="handleExport"><el-icon><Download /></el-icon>导出</el-button>
|
<el-button @click="handleExport"><el-icon><Download /></el-icon>导出</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border>
|
<el-table v-loading="loading" :data="tableData" stripe border>
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<el-table-column label="跟单编号" width="130">
|
<el-table-column label="通知单编号" width="150">
|
||||||
<template #default="{ row }">{{ row.lines?.[0]?.trackCode || '-' }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="checkinCode" label="单据编码" width="130">
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link type="primary">{{ row.checkinCode }}</el-link>
|
<el-link type="primary" @click="handleView(row)">{{ row.noticeCode }}</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="noticeName" label="通知单名称" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="poCode" label="采购订单号" width="130" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="vendorName" label="供应商名称" min-width="160" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="contact" label="联系人" width="100" />
|
||||||
|
<el-table-column prop="tel" label="联系方式" width="120" />
|
||||||
|
<el-table-column prop="arrivalDate" label="到货日期" width="110" />
|
||||||
<el-table-column prop="status" label="单据状态" width="90" align="center">
|
<el-table-column prop="status" label="单据状态" width="90" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="row.status === '审核' ? 'success' : 'info'">{{ row.status }}</el-tag>
|
<el-tag :type="statusTagType(row.status)">{{ statusLabel(row.status) }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="supplierName" label="供应商" min-width="180" show-overflow-tooltip />
|
<el-table-column label="操作" width="160" fixed="right">
|
||||||
<el-table-column label="物料名称" width="150">
|
|
||||||
<template #default="{ row }">{{ row.lines?.[0]?.itemName || '-' }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="物料编码" width="120">
|
|
||||||
<template #default="{ row }">{{ row.lines?.[0]?.itemCode || '-' }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="totalQuantity" label="到货数量" width="100" align="right" />
|
|
||||||
<el-table-column prop="stockedQuantity" label="入库数量" width="100" align="right" />
|
|
||||||
<el-table-column prop="checkinDate" label="单据日期" width="110" />
|
|
||||||
<el-table-column label="操作" width="120" fixed="right">
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link>查看</el-button>
|
<el-button type="primary" link @click="handleView(row)">查看</el-button>
|
||||||
<el-popconfirm title="确定删除吗?" @confirm="handleDelete(row)">
|
<el-button v-if="row.status === 'PREPARE'" type="primary" link @click="handleEdit(row)">修改</el-button>
|
||||||
|
<el-popconfirm v-if="row.status === 'PREPARE'" title="确定删除吗?" @confirm="handleDelete(row)">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button type="danger" link>删除</el-button>
|
<el-button type="danger" link>删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -66,35 +68,238 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="table-footer">
|
<div class="table-footer">
|
||||||
<div class="summary">
|
|
||||||
到货数量: <span class="value">{{ totalCheckinQty.toLocaleString() }}</span>
|
|
||||||
入库数量: <span class="value">{{ totalStockedQty.toLocaleString() }}</span>
|
|
||||||
</div>
|
|
||||||
<el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :total="total" layout="total, sizes, prev, pager, next, jumper" @size-change="loadData" @current-change="loadData" />
|
<el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :total="total" layout="total, sizes, prev, pager, next, jumper" @size-change="loadData" @current-change="loadData" />
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 新增/修改/查看弹窗 -->
|
||||||
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="960px" destroy-on-close @close="handleDialogClose">
|
||||||
|
<el-form ref="formRef" :model="form" :rules="formRules" :disabled="dialogMode === 'view'" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="通知单编号" prop="noticeCode">
|
||||||
|
<el-input v-model="form.noticeCode" placeholder="可自动生成" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-form-item v-if="dialogMode !== 'view' && form.status === 'PREPARE'" label-width="80">
|
||||||
|
<el-switch v-model="autoGenCode" active-text="自动生成" @change="handleAutoGenChange" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="通知单名称" prop="noticeName">
|
||||||
|
<el-input v-model="form.noticeName" placeholder="请输入通知单名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="采购订单编号" prop="poCode">
|
||||||
|
<el-input v-model="form.poCode" placeholder="请输入采购订单编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="供应商" prop="vendorName">
|
||||||
|
<el-input v-model="form.vendorName" readonly placeholder="请选择供应商" @click="openSupplierDialog">
|
||||||
|
<template #append>
|
||||||
|
<el-button :icon="Search" @click="openSupplierDialog" :disabled="dialogMode === 'view'" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="到货日期" prop="arrivalDate">
|
||||||
|
<el-date-picker v-model="form.arrivalDate" type="date" placeholder="请选择到货日期" value-format="YYYY-MM-DD" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系人" prop="contact">
|
||||||
|
<el-input v-model="form.contact" placeholder="请输入联系人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系方式" prop="tel">
|
||||||
|
<el-input v-model="form.tel" placeholder="请输入联系方式" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 物料明细区(noticeId 存在时显示) -->
|
||||||
|
<el-divider v-if="form.noticeId" content-position="center">物料信息</el-divider>
|
||||||
|
<div v-if="form.noticeId" class="line-section">
|
||||||
|
<div class="line-toolbar">
|
||||||
|
<el-button v-if="dialogMode !== 'view'" type="primary" size="small" @click="handleAddLine">
|
||||||
|
<el-icon><Plus /></el-icon>新增
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="lineList" stripe border>
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
|
<el-table-column label="物料编码" width="130">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<div v-if="dialogMode !== 'view'" class="inline-select">
|
||||||
|
<span class="mono">{{ row.itemCode || '请选择' }}</span>
|
||||||
|
<el-button type="primary" link @click="openItemDialog($index)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<span v-else>{{ row.itemCode || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="itemName" label="物料名称" min-width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="specification" label="规格型号" width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="unitName" label="单位" width="70" align="center" />
|
||||||
|
<el-table-column label="到货数量" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input-number v-if="dialogMode !== 'view'" v-model="row.quantityArrival" :min="0" :precision="2" size="small" style="width: 90px" />
|
||||||
|
<span v-else>{{ row.quantityArrival ?? '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否检验" width="90" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-select v-if="dialogMode !== 'view'" v-model="row.iqcCheck" size="small" style="width: 70px">
|
||||||
|
<el-option label="是" value="Y" />
|
||||||
|
<el-option label="否" value="N" />
|
||||||
|
</el-select>
|
||||||
|
<span v-else>{{ row.iqcCheck === 'Y' ? '是' : '否' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="quantityQuanlified" label="合格数量" width="90" align="right" />
|
||||||
|
<el-table-column prop="iqcCode" label="检验单号" width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="remark" label="备注" min-width="100" show-overflow-tooltip />
|
||||||
|
<el-table-column v-if="dialogMode !== 'view'" label="操作" width="80" fixed="right">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-button type="danger" link @click="handleDeleteLine($index)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button v-if="dialogMode !== 'view' && form.status === 'PREPARE'" type="primary" :loading="saveLoading" @click="handleSave">保存</el-button>
|
||||||
|
<el-button v-if="dialogMode !== 'view' && form.status === 'PREPARE' && form.noticeId" type="success" :loading="saveLoading" @click="handleSubmit">提交</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 选择供应商弹窗 -->
|
||||||
|
<el-dialog v-model="showSupplierDialog" title="选择供应商" width="900px" destroy-on-close>
|
||||||
|
<div class="dialog-search">
|
||||||
|
<el-input v-model="supplierSearch.supplierName" placeholder="供应商名称" clearable style="width: 200px; margin-right: 8px" />
|
||||||
|
<el-input v-model="supplierSearch.contact1" placeholder="业务联系人" clearable style="width: 160px; margin-right: 8px" />
|
||||||
|
<el-button type="primary" @click="loadSuppliers">搜索</el-button>
|
||||||
|
<el-button @click="resetSupplierSearch">查询所有</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="supplierList" stripe border max-height="400" highlight-current-row>
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
|
<el-table-column prop="supplierName" label="供应商名称" min-width="200" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="tel" label="电话" width="130" />
|
||||||
|
<el-table-column prop="contact1" label="业务联系人" width="120" />
|
||||||
|
<el-table-column label="操作" width="80" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="handleSelectSupplier(row)">选择</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 选择物料弹窗 -->
|
||||||
|
<el-dialog v-model="showItemDialog" title="选择物料" width="960px" destroy-on-close @open="handleItemDialogOpen">
|
||||||
|
<div class="item-dialog-body">
|
||||||
|
<div class="category-tree">
|
||||||
|
<el-input v-model="itemTypeFilter" placeholder="请输入分类名称" clearable size="small" style="margin-bottom: 8px" />
|
||||||
|
<el-scrollbar height="360px">
|
||||||
|
<el-tree
|
||||||
|
ref="itemTreeRef"
|
||||||
|
:data="itemTypeTree"
|
||||||
|
:props="{ label: 'label', children: 'children' }"
|
||||||
|
node-key="id"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
:filter-node-method="filterTreeNode"
|
||||||
|
@node-click="handleTreeNodeClick"
|
||||||
|
/>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
<div class="item-table-area">
|
||||||
|
<div class="item-search-area">
|
||||||
|
<el-input v-model="itemSearch.itemCode" placeholder="物料编码" clearable style="width: 140px" @keyup.enter="loadItemTableData" />
|
||||||
|
<el-input v-model="itemSearch.itemName" placeholder="物料名称" clearable style="width: 140px" @keyup.enter="loadItemTableData" />
|
||||||
|
<el-button type="primary" @click="loadItemTableData">搜索</el-button>
|
||||||
|
<el-button @click="resetItemSearch">重置</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item-toolbar">
|
||||||
|
<el-button size="small" @click="loadAllItems">查询所有</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="itemTableData" v-loading="itemTableLoading" stripe border max-height="340" highlight-current-row>
|
||||||
|
<el-table-column prop="itemCode" label="物料编码" width="130" />
|
||||||
|
<el-table-column prop="itemName" label="物料名称" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="specification" label="型号规格" width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="unitName" label="主计量" width="80" align="center" />
|
||||||
|
<el-table-column label="操作" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="handleSelectItem(row)">选择</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, onMounted } from 'vue'
|
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { Search, Plus, Download } from '@element-plus/icons-vue'
|
import { Search, Plus, Download } from '@element-plus/icons-vue'
|
||||||
import { getCheckinList, deleteCheckin, type Checkin, type CheckinQuery } from '@/api/checkin'
|
import {
|
||||||
|
listArrivalNotice,
|
||||||
|
getArrivalNotice,
|
||||||
|
addArrivalNotice,
|
||||||
|
updateArrivalNotice,
|
||||||
|
deleteArrivalNotice,
|
||||||
|
listArrivalNoticeLine,
|
||||||
|
addArrivalNoticeLine,
|
||||||
|
updateArrivalNoticeLine,
|
||||||
|
deleteArrivalNoticeLine,
|
||||||
|
genArrivalNoticeCode,
|
||||||
|
ARRIVAL_NOTICE_STATUS_MAP,
|
||||||
|
type ArrivalNotice,
|
||||||
|
type ArrivalNoticeLine,
|
||||||
|
type ArrivalNoticeQuery
|
||||||
|
} from '@/api/arrivalnotice'
|
||||||
|
import { getPoSupplierList, type PoSupplier } from '@/api/purchaseOrder'
|
||||||
|
import { listMdItem, type MdItem } from '@/api/masterdata/item'
|
||||||
|
import { listItemType, handleTree, type ItemType } from '@/api/masterdata/itemtype'
|
||||||
|
|
||||||
const queryParams = reactive<CheckinQuery>({ trackCode: '', checkinCode: '', supplierName: '', pageNum: 1, pageSize: 10 })
|
const queryParams = reactive<ArrivalNoticeQuery>({
|
||||||
const dateRange = ref<string[]>([])
|
noticeCode: '',
|
||||||
|
noticeName: '',
|
||||||
|
poCode: '',
|
||||||
|
vendorName: '',
|
||||||
|
arrivalDate: '',
|
||||||
|
status: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
})
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const tableData = ref<Checkin[]>([])
|
const tableData = ref<ArrivalNotice[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
|
|
||||||
const totalCheckinQty = computed(() => tableData.value.reduce((sum, r) => sum + (r.totalQuantity || 0), 0))
|
const statusLabel = (status?: string) => ARRIVAL_NOTICE_STATUS_MAP[status || '']?.label ?? status ?? '-'
|
||||||
const totalStockedQty = computed(() => tableData.value.reduce((sum, r) => sum + (r.stockedQuantity || 0), 0))
|
const statusTagType = (status?: string) => ARRIVAL_NOTICE_STATUS_MAP[status || '']?.type ?? 'info'
|
||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await getCheckinList(queryParams)
|
const res = await listArrivalNotice(queryParams)
|
||||||
tableData.value = res.rows
|
tableData.value = res.rows
|
||||||
total.value = res.total
|
total.value = res.total
|
||||||
} finally {
|
} finally {
|
||||||
@@ -103,11 +308,383 @@ const loadData = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleQuery = () => { queryParams.pageNum = 1; loadData() }
|
const handleQuery = () => { queryParams.pageNum = 1; loadData() }
|
||||||
const handleQueryAll = () => { queryParams.trackCode = ''; queryParams.checkinCode = ''; queryParams.supplierName = ''; dateRange.value = []; handleQuery() }
|
const handleReset = () => {
|
||||||
const handleDocument = () => ElMessage.info('单据视图切换')
|
queryParams.noticeCode = ''
|
||||||
const handleAdd = () => ElMessage.info('新增采购到货单')
|
queryParams.noticeName = ''
|
||||||
const handleDelete = async (row: Checkin) => { await deleteCheckin(String(row.checkinId)); ElMessage.success('删除成功'); loadData() }
|
queryParams.poCode = ''
|
||||||
const handleExport = () => ElMessage.info('导出功能开发中')
|
queryParams.vendorName = ''
|
||||||
|
queryParams.arrivalDate = ''
|
||||||
|
queryParams.status = ''
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 弹窗 ============
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dialogTitle = ref('')
|
||||||
|
const dialogMode = ref<'add' | 'edit' | 'view'>('add')
|
||||||
|
const formRef = ref()
|
||||||
|
const saveLoading = ref(false)
|
||||||
|
const autoGenCode = ref(false)
|
||||||
|
|
||||||
|
const form = reactive<Partial<ArrivalNotice>>({
|
||||||
|
noticeId: undefined,
|
||||||
|
noticeCode: '',
|
||||||
|
noticeName: '',
|
||||||
|
poCode: '',
|
||||||
|
vendorId: undefined,
|
||||||
|
vendorCode: '',
|
||||||
|
vendorName: '',
|
||||||
|
vendorNick: '',
|
||||||
|
arrivalDate: '',
|
||||||
|
contact: '',
|
||||||
|
tel: '',
|
||||||
|
status: 'PREPARE',
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRules = {
|
||||||
|
noticeCode: [{ required: true, message: '通知单编号不能为空', trigger: 'blur' }],
|
||||||
|
noticeName: [{ required: true, message: '通知单名称不能为空', trigger: 'blur' }],
|
||||||
|
vendorName: [{ required: true, message: '请选择供应商', trigger: 'blur' }],
|
||||||
|
arrivalDate: [{ required: true, message: '请选择到货日期', trigger: 'change' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 明细行(本地编辑用,保存时同步到后端)
|
||||||
|
const lineList = ref<ArrivalNoticeLine[]>([])
|
||||||
|
|
||||||
|
function resetForm() {
|
||||||
|
Object.assign(form, {
|
||||||
|
noticeId: undefined,
|
||||||
|
noticeCode: '',
|
||||||
|
noticeName: '',
|
||||||
|
poCode: '',
|
||||||
|
vendorId: undefined,
|
||||||
|
vendorCode: '',
|
||||||
|
vendorName: '',
|
||||||
|
vendorNick: '',
|
||||||
|
arrivalDate: '',
|
||||||
|
contact: '',
|
||||||
|
tel: '',
|
||||||
|
status: 'PREPARE',
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
lineList.value = []
|
||||||
|
autoGenCode.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadLines() {
|
||||||
|
if (!form.noticeId) return
|
||||||
|
const res = await listArrivalNoticeLine({ noticeId: form.noticeId, pageNum: 1, pageSize: 500 })
|
||||||
|
lineList.value = res.rows.map(r => ({ ...r, iqcCheck: r.iqcCheck || 'N' }))
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
resetForm()
|
||||||
|
dialogTitle.value = '新增采购到货单'
|
||||||
|
dialogMode.value = 'add'
|
||||||
|
form.arrivalDate = new Date().toISOString().split('T')[0]
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleEdit(row: ArrivalNotice) {
|
||||||
|
resetForm()
|
||||||
|
const data = await getArrivalNotice(row.noticeId!)
|
||||||
|
Object.assign(form, data)
|
||||||
|
await loadLines()
|
||||||
|
dialogTitle.value = '修改采购到货单'
|
||||||
|
dialogMode.value = 'edit'
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleView(row: ArrivalNotice) {
|
||||||
|
resetForm()
|
||||||
|
const data = await getArrivalNotice(row.noticeId!)
|
||||||
|
Object.assign(form, data)
|
||||||
|
await loadLines()
|
||||||
|
dialogTitle.value = '查看到货通知单'
|
||||||
|
dialogMode.value = 'view'
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDialogClose() {
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleAutoGenChange(val: boolean) {
|
||||||
|
if (val) {
|
||||||
|
try {
|
||||||
|
form.noticeCode = await genArrivalNoticeCode()
|
||||||
|
} catch (e) {
|
||||||
|
ElMessage.error('生成编码失败')
|
||||||
|
autoGenCode.value = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
form.noticeCode = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSave() {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
saveLoading.value = true
|
||||||
|
try {
|
||||||
|
if (form.noticeId) {
|
||||||
|
await updateArrivalNotice(form)
|
||||||
|
// 保存明细变更
|
||||||
|
await saveLines()
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
await loadLines()
|
||||||
|
} else {
|
||||||
|
await addArrivalNotice(form)
|
||||||
|
// 后端可能不返回 noticeId,通过 noticeCode 查询获取
|
||||||
|
const listRes = await listArrivalNotice({ noticeCode: form.noticeCode, pageNum: 1, pageSize: 1 })
|
||||||
|
const added = listRes.rows[0]
|
||||||
|
if (added?.noticeId) {
|
||||||
|
form.noticeId = added.noticeId
|
||||||
|
await saveLines()
|
||||||
|
}
|
||||||
|
ElMessage.success('新增成功')
|
||||||
|
if (form.noticeId) await loadLines()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('保存失败:', e)
|
||||||
|
} finally {
|
||||||
|
saveLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveLines() {
|
||||||
|
if (!form.noticeId) return
|
||||||
|
const lines = lineList.value.filter(l => l.itemCode && (l.quantityArrival ?? 0) > 0)
|
||||||
|
for (const line of lines) {
|
||||||
|
const payload = { ...line, noticeId: form.noticeId, iqcCheck: line.iqcCheck || 'N' }
|
||||||
|
if (line.lineId) {
|
||||||
|
await updateArrivalNoticeLine(payload)
|
||||||
|
} else {
|
||||||
|
await addArrivalNoticeLine(payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!form.noticeId) {
|
||||||
|
ElMessage.warning('请先保存表头后再提交')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = await listArrivalNoticeLine({ noticeId: form.noticeId, pageNum: 1, pageSize: 1 })
|
||||||
|
if (!res.rows.length) {
|
||||||
|
ElMessage.warning('请至少添加一条物料明细')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
saveLoading.value = true
|
||||||
|
try {
|
||||||
|
form.status = 'APPROVING'
|
||||||
|
await updateArrivalNotice(form)
|
||||||
|
ElMessage.success('提交成功')
|
||||||
|
dialogVisible.value = false
|
||||||
|
loadData()
|
||||||
|
} catch (e) {
|
||||||
|
console.error('提交失败:', e)
|
||||||
|
} finally {
|
||||||
|
saveLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleDelete(row: ArrivalNotice) {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm('确定删除该到货通知单吗?', '提示', { type: 'warning' })
|
||||||
|
await deleteArrivalNotice(row.noticeId!)
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
loadData()
|
||||||
|
} catch (e) {
|
||||||
|
if (e !== 'cancel') console.error('删除失败:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleExport() {
|
||||||
|
ElMessage.info('导出功能开发中')
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 明细行操作 ============
|
||||||
|
function handleAddLine() {
|
||||||
|
if (!form.noticeId) {
|
||||||
|
ElMessage.warning('请先保存表头后再添加物料')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lineList.value.push({
|
||||||
|
noticeId: form.noticeId,
|
||||||
|
itemId: undefined,
|
||||||
|
itemCode: '',
|
||||||
|
itemName: '',
|
||||||
|
specification: '',
|
||||||
|
unitOfMeasure: '',
|
||||||
|
unitName: '',
|
||||||
|
quantityArrival: 0,
|
||||||
|
quantityQuanlified: 0,
|
||||||
|
iqcCheck: 'N',
|
||||||
|
iqcCode: '',
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDeleteLine(index: number) {
|
||||||
|
const line = lineList.value[index]
|
||||||
|
if (line.lineId) {
|
||||||
|
deleteArrivalNoticeLine(line.lineId).then(() => {
|
||||||
|
lineList.value.splice(index, 1)
|
||||||
|
}).catch(() => {})
|
||||||
|
} else {
|
||||||
|
lineList.value.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 供应商选择 ============
|
||||||
|
const showSupplierDialog = ref(false)
|
||||||
|
const supplierSearch = reactive({ supplierName: '', contact1: '' })
|
||||||
|
const supplierList = ref<PoSupplier[]>([])
|
||||||
|
|
||||||
|
function openSupplierDialog() {
|
||||||
|
if (dialogMode.value === 'view') return
|
||||||
|
showSupplierDialog.value = true
|
||||||
|
loadSuppliers()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadSuppliers() {
|
||||||
|
const res = await getPoSupplierList({
|
||||||
|
supplierName: supplierSearch.supplierName || undefined,
|
||||||
|
contact1: supplierSearch.contact1 || undefined
|
||||||
|
})
|
||||||
|
supplierList.value = res.rows
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetSupplierSearch() {
|
||||||
|
supplierSearch.supplierName = ''
|
||||||
|
supplierSearch.contact1 = ''
|
||||||
|
loadSuppliers()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelectSupplier(row: PoSupplier) {
|
||||||
|
form.vendorId = row.supplierId
|
||||||
|
form.vendorCode = row.supplierCode
|
||||||
|
form.vendorName = row.supplierName
|
||||||
|
form.vendorNick = row.supplierNick
|
||||||
|
showSupplierDialog.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 物料选择 ============
|
||||||
|
const showItemDialog = ref(false)
|
||||||
|
const itemTableLoading = ref(false)
|
||||||
|
const itemTableData = ref<MdItem[]>([])
|
||||||
|
const editingLineIndex = ref(-1)
|
||||||
|
const itemTreeRef = ref()
|
||||||
|
const itemTypeTree = ref<any[]>([])
|
||||||
|
const itemTypeFilter = ref('')
|
||||||
|
const itemSearch = reactive<{ itemCode: string; itemName: string; itemTypeId: number | undefined }>({
|
||||||
|
itemCode: '',
|
||||||
|
itemName: '',
|
||||||
|
itemTypeId: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(itemTypeFilter, (val) => {
|
||||||
|
itemTreeRef.value?.filter(val)
|
||||||
|
})
|
||||||
|
|
||||||
|
function filterTreeNode(value: string, data: any) {
|
||||||
|
if (!value) return true
|
||||||
|
return (data.label || '').includes(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function openItemDialog(idx: number) {
|
||||||
|
editingLineIndex.value = idx
|
||||||
|
showItemDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleItemDialogOpen() {
|
||||||
|
itemSearch.itemCode = ''
|
||||||
|
itemSearch.itemName = ''
|
||||||
|
itemSearch.itemTypeId = undefined
|
||||||
|
itemTypeFilter.value = ''
|
||||||
|
await Promise.all([loadItemTypeTree(), loadItemTableData()])
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadItemTypeTree() {
|
||||||
|
try {
|
||||||
|
const res = await listItemType()
|
||||||
|
const flat = (res as any).data || res || []
|
||||||
|
const list = Array.isArray(flat) ? flat : []
|
||||||
|
const tree = handleTree(list)
|
||||||
|
function toTreeNodes(items: ItemType[]): any[] {
|
||||||
|
return items.map(item => ({
|
||||||
|
id: item.itemTypeId,
|
||||||
|
label: item.itemTypeName || '',
|
||||||
|
raw: item,
|
||||||
|
children: item.children?.length ? toTreeNodes(item.children) : undefined
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
itemTypeTree.value = toTreeNodes(tree)
|
||||||
|
} catch (e) {
|
||||||
|
itemTypeTree.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadItemTableData() {
|
||||||
|
itemTableLoading.value = true
|
||||||
|
try {
|
||||||
|
const params: any = { enableFlag: 'Y', pageNum: 1, pageSize: 100 }
|
||||||
|
if (itemSearch.itemCode) params.itemCode = itemSearch.itemCode
|
||||||
|
if (itemSearch.itemName) params.itemName = itemSearch.itemName
|
||||||
|
if (itemSearch.itemTypeId) params.itemTypeId = itemSearch.itemTypeId
|
||||||
|
const res = await listMdItem(params)
|
||||||
|
itemTableData.value = res.rows || []
|
||||||
|
} catch (e) {
|
||||||
|
itemTableData.value = []
|
||||||
|
} finally {
|
||||||
|
itemTableLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTreeNodeClick(node: any) {
|
||||||
|
itemSearch.itemTypeId = node.id
|
||||||
|
loadItemTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetItemSearch() {
|
||||||
|
itemSearch.itemCode = ''
|
||||||
|
itemSearch.itemName = ''
|
||||||
|
itemSearch.itemTypeId = undefined
|
||||||
|
itemTreeRef.value?.setCurrentKey(null)
|
||||||
|
loadItemTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAllItems() {
|
||||||
|
itemSearch.itemCode = ''
|
||||||
|
itemSearch.itemName = ''
|
||||||
|
itemSearch.itemTypeId = undefined
|
||||||
|
itemTypeFilter.value = ''
|
||||||
|
itemTreeRef.value?.setCurrentKey(null)
|
||||||
|
loadItemTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelectItem(selected: MdItem) {
|
||||||
|
const idx = editingLineIndex.value
|
||||||
|
if (idx < 0 || !lineList.value[idx]) return
|
||||||
|
const row = lineList.value[idx]
|
||||||
|
row.itemId = selected.itemId
|
||||||
|
row.itemCode = selected.itemCode ?? ''
|
||||||
|
row.itemName = selected.itemName ?? ''
|
||||||
|
row.specification = selected.specification ?? ''
|
||||||
|
row.unitOfMeasure = selected.unitOfMeasure ?? ''
|
||||||
|
row.unitName = selected.unitName ?? selected.unitOfMeasure ?? ''
|
||||||
|
showItemDialog.value = false
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => loadData())
|
onMounted(() => loadData())
|
||||||
</script>
|
</script>
|
||||||
@@ -118,6 +695,20 @@ onMounted(() => loadData())
|
|||||||
.search-card :deep(.el-card__body) { padding-bottom: 0; }
|
.search-card :deep(.el-card__body) { padding-bottom: 0; }
|
||||||
.toolbar { margin-bottom: 16px; display: flex; gap: 8px; }
|
.toolbar { margin-bottom: 16px; display: flex; gap: 8px; }
|
||||||
.table-footer { margin-top: 16px; display: flex; justify-content: space-between; align-items: center; }
|
.table-footer { margin-top: 16px; display: flex; justify-content: space-between; align-items: center; }
|
||||||
.summary { font-size: 14px; color: #606266; }
|
.dialog-search { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; margin-bottom: 16px; }
|
||||||
.summary .value { color: #409eff; font-weight: bold; margin-right: 20px; }
|
.inline-select { display: flex; align-items: center; gap: 4px; }
|
||||||
|
.inline-select .mono { font-family: monospace; color: #606266; }
|
||||||
|
.line-section { margin-top: 12px; }
|
||||||
|
.line-toolbar { margin-bottom: 8px; }
|
||||||
|
|
||||||
|
.item-dialog-body { display: flex; gap: 12px; min-height: 420px; }
|
||||||
|
.category-tree {
|
||||||
|
width: 180px;
|
||||||
|
min-width: 180px;
|
||||||
|
border-right: 1px solid #e4e7ed;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
|
.item-table-area { flex: 1; overflow: hidden; }
|
||||||
|
.item-search-area { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
|
||||||
|
.item-toolbar { margin-bottom: 8px; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -162,9 +162,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="lines" border size="small" max-height="420">
|
<el-table :data="lines" border size="small" max-height="420" class="ebom-table ebom-table-nowrap">
|
||||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||||
<el-table-column label="物料编码" min-width="160">
|
<el-table-column label="物料编码" min-width="160" show-overflow-tooltip>
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<div class="inline-select">
|
<div class="inline-select">
|
||||||
<span class="mono">{{ row.bomItemCode || '请添加物料' }}</span>
|
<span class="mono">{{ row.bomItemCode || '请添加物料' }}</span>
|
||||||
@@ -260,12 +260,12 @@
|
|||||||
<el-button @click="queryAllProducts">查询所有</el-button>
|
<el-button @click="queryAllProducts">查询所有</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-table :data="productList" border size="small" max-height="380" v-loading="productLoading">
|
<el-table :data="productList" border size="small" max-height="380" v-loading="productLoading" class="ebom-table ebom-table-nowrap">
|
||||||
<el-table-column prop="itemCode" label="物料编码" width="130" />
|
<el-table-column prop="itemCode" label="物料编码" width="130" show-overflow-tooltip />
|
||||||
<el-table-column prop="itemName" label="物料名称" min-width="160" show-overflow-tooltip />
|
<el-table-column prop="itemName" label="物料名称" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column prop="specification" label="型号规格" width="130" show-overflow-tooltip />
|
<el-table-column prop="specification" label="型号规格" width="130" show-overflow-tooltip />
|
||||||
<el-table-column prop="unitName" label="主计量" width="70" align="center" />
|
<el-table-column prop="unitName" label="主计量" width="70" align="center" />
|
||||||
<el-table-column label="供应方式" width="80" align="center">
|
<el-table-column label="供应方式" width="80" align="center" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ getSupplyLabel(row.itemOrProduct) }}
|
{{ getSupplyLabel(row.itemOrProduct) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -323,12 +323,12 @@
|
|||||||
<el-button @click="queryAllItems">查询所有</el-button>
|
<el-button @click="queryAllItems">查询所有</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-table :data="itemList" border size="small" max-height="380" v-loading="itemLoading">
|
<el-table :data="itemList" border size="small" max-height="380" v-loading="itemLoading" class="ebom-table ebom-table-nowrap">
|
||||||
<el-table-column prop="itemCode" label="物料编码" width="130" />
|
<el-table-column prop="itemCode" label="物料编码" width="130" show-overflow-tooltip />
|
||||||
<el-table-column prop="itemName" label="物料名称" min-width="160" show-overflow-tooltip />
|
<el-table-column prop="itemName" label="物料名称" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column prop="specification" label="型号规格" width="130" show-overflow-tooltip />
|
<el-table-column prop="specification" label="型号规格" width="130" show-overflow-tooltip />
|
||||||
<el-table-column prop="unitName" label="主计量" width="70" align="center" />
|
<el-table-column prop="unitName" label="主计量" width="70" align="center" />
|
||||||
<el-table-column label="供应方式" width="80" align="center">
|
<el-table-column label="供应方式" width="80" align="center" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ getSupplyLabel(row.itemOrProduct) }}
|
{{ getSupplyLabel(row.itemOrProduct) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -700,10 +700,11 @@ async function loadItemTypeTree() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 左侧分类树显示物料/产品名称(itemTypeName),参考物料管理 masterdata/item */
|
||||||
function toTreeNode(item: ItemType): any {
|
function toTreeNode(item: ItemType): any {
|
||||||
return {
|
return {
|
||||||
id: item.itemTypeId,
|
id: item.itemTypeId,
|
||||||
label: `${item.itemTypeCode || ''}-${item.itemTypeName || ''}`.replace(/^-/, ''),
|
label: item.itemTypeName || item.itemTypeCode || '',
|
||||||
children: item.children?.map(toTreeNode) || []
|
children: item.children?.map(toTreeNode) || []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -732,6 +733,7 @@ function openProductDialog() {
|
|||||||
searchProductItems()
|
searchProductItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 从物料编码选择打开:显示产品/半成品分类下的数据(含未启用) */
|
||||||
async function searchProductItems() {
|
async function searchProductItems() {
|
||||||
productLoading.value = true
|
productLoading.value = true
|
||||||
try {
|
try {
|
||||||
@@ -739,7 +741,7 @@ async function searchProductItems() {
|
|||||||
itemCode: productQuery.itemCode || undefined,
|
itemCode: productQuery.itemCode || undefined,
|
||||||
itemName: productQuery.itemName || undefined,
|
itemName: productQuery.itemName || undefined,
|
||||||
itemTypeId: productQuery.itemTypeId,
|
itemTypeId: productQuery.itemTypeId,
|
||||||
enableFlag: 'Y',
|
itemOrProduct: 'PRODUCT',
|
||||||
pageNum: productQuery.pageNum,
|
pageNum: productQuery.pageNum,
|
||||||
pageSize: productQuery.pageSize
|
pageSize: productQuery.pageSize
|
||||||
})
|
})
|
||||||
@@ -799,6 +801,7 @@ function openItemDialog(idx: number) {
|
|||||||
searchSubItems()
|
searchSubItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 从新增物料按钮打开:显示原材料分类下的数据 */
|
||||||
async function searchSubItems() {
|
async function searchSubItems() {
|
||||||
itemLoading.value = true
|
itemLoading.value = true
|
||||||
try {
|
try {
|
||||||
@@ -806,6 +809,7 @@ async function searchSubItems() {
|
|||||||
itemCode: itemQuery.itemCode || undefined,
|
itemCode: itemQuery.itemCode || undefined,
|
||||||
itemName: itemQuery.itemName || undefined,
|
itemName: itemQuery.itemName || undefined,
|
||||||
itemTypeId: itemQuery.itemTypeId,
|
itemTypeId: itemQuery.itemTypeId,
|
||||||
|
itemOrProduct: 'ITEM',
|
||||||
enableFlag: 'Y',
|
enableFlag: 'Y',
|
||||||
pageNum: itemQuery.pageNum,
|
pageNum: itemQuery.pageNum,
|
||||||
pageSize: itemQuery.pageSize
|
pageSize: itemQuery.pageSize
|
||||||
@@ -959,4 +963,19 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 表格表头和内容不换行,过长截断显示 */
|
||||||
|
.ebom-table-nowrap :deep(.el-table__header th),
|
||||||
|
.ebom-table-nowrap :deep(.el-table__body td) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ebom-table-nowrap :deep(.el-table__body td .cell) {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.ebom-table-nowrap :deep(.el-table__body td .el-input),
|
||||||
|
.ebom-table-nowrap :deep(.el-table__body td .el-input-number) {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -101,9 +101,10 @@
|
|||||||
border
|
border
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:max-height="tableHeight"
|
:max-height="tableHeight"
|
||||||
|
class="ebom-table ebom-table-nowrap"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" fixed="left" />
|
<el-table-column type="index" label="序号" width="60" align="center" fixed="left" />
|
||||||
<el-table-column prop="bomCode" label="单据编码" width="140" fixed="left">
|
<el-table-column prop="bomCode" label="单据编码" width="140" fixed="left" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link type="primary" @click="handleView(row)">{{ row.bomCode }}</el-link>
|
<el-link type="primary" @click="handleView(row)">{{ row.bomCode }}</el-link>
|
||||||
</template>
|
</template>
|
||||||
@@ -114,7 +115,7 @@
|
|||||||
<el-table-column prop="version" label="版本号" width="80" align="center" />
|
<el-table-column prop="version" label="版本号" width="80" align="center" />
|
||||||
<el-table-column prop="versionDesc" label="版本说明" width="120" show-overflow-tooltip />
|
<el-table-column prop="versionDesc" label="版本说明" width="120" show-overflow-tooltip />
|
||||||
<el-table-column prop="drawingNo" label="图纸号" width="100" show-overflow-tooltip />
|
<el-table-column prop="drawingNo" label="图纸号" width="100" show-overflow-tooltip />
|
||||||
<el-table-column prop="status" label="单据状态" width="80" align="center">
|
<el-table-column prop="status" label="单据状态" width="100" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="getStatusType(row.status)" size="small">{{ getStatusLabel(row.status) }}</el-tag>
|
<el-tag :type="getStatusType(row.status)" size="small">{{ getStatusLabel(row.status) }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -142,10 +143,11 @@
|
|||||||
border
|
border
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:max-height="tableHeight"
|
:max-height="tableHeight"
|
||||||
|
class="ebom-table ebom-table-nowrap"
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<el-table-column type="selection" width="55" fixed="left" />
|
<el-table-column type="selection" width="55" fixed="left" />
|
||||||
<el-table-column prop="bomCode" label="单据编码" width="140" fixed="left">
|
<el-table-column prop="bomCode" label="单据编码" width="140" fixed="left" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link type="primary" @click="handleView(row)">{{ row.bomCode }}</el-link>
|
<el-link type="primary" @click="handleView(row)">{{ row.bomCode }}</el-link>
|
||||||
</template>
|
</template>
|
||||||
@@ -155,7 +157,7 @@
|
|||||||
{{ row.bomDate || row.createTime?.slice(0, 10) || '-' }}
|
{{ row.bomDate || row.createTime?.slice(0, 10) || '-' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="status" label="单据状态" width="80" align="center">
|
<el-table-column prop="status" label="单据状态" width="100" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="getStatusType(row.status)" size="small">{{ getStatusLabel(row.status) }}</el-tag>
|
<el-tag :type="getStatusType(row.status)" size="small">{{ getStatusLabel(row.status) }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -165,8 +167,8 @@
|
|||||||
{{ getBizTypeLabel(row.businessType) }}
|
{{ getBizTypeLabel(row.businessType) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="deptName" label="业务部门" width="100" align="center" />
|
<el-table-column prop="deptName" label="业务部门" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="operatorName" label="业务人员" width="100" align="center">
|
<el-table-column prop="operatorName" label="业务人员" width="100" align="center" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.operatorName || row.createBy || '-' }}
|
{{ row.operatorName || row.createBy || '-' }}
|
||||||
</template>
|
</template>
|
||||||
@@ -658,4 +660,14 @@ onMounted(() => {
|
|||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 表格表头和内容不换行,过长截断显示 */
|
||||||
|
.ebom-table-nowrap :deep(.el-table__header th),
|
||||||
|
.ebom-table-nowrap :deep(.el-table__body td) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ebom-table-nowrap :deep(.el-table__body td .cell) {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
171
mom-frontend-vue2/src/components/print/LocationLabelPrint.vue
Normal file
171
mom-frontend-vue2/src/components/print/LocationLabelPrint.vue
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:visible="visible"
|
||||||
|
@close="handleClose"
|
||||||
|
fullscreen
|
||||||
|
destroy-on-close
|
||||||
|
:show-close="false"
|
||||||
|
class="location-label-print-dialog"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<template slot="title">
|
||||||
|
<div class="label-print-actions">
|
||||||
|
<el-button type="primary" size="small" @click="doPrint">打印</el-button>
|
||||||
|
<el-button size="small" @click="handleClose">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="label-print-content" ref="printContentRef">
|
||||||
|
<div v-if="locations.length === 0" class="label-empty">暂无库区数据</div>
|
||||||
|
<div v-else class="label-grid">
|
||||||
|
<div
|
||||||
|
v-for="(loc, idx) in locations"
|
||||||
|
:key="loc.locationId || idx"
|
||||||
|
class="label-card"
|
||||||
|
>
|
||||||
|
<div class="label-qr">
|
||||||
|
<QrCode :value="loc.locationCode || String(loc.locationId || '')" :size="72" />
|
||||||
|
</div>
|
||||||
|
<div class="label-name">{{ loc.locationName || '-' }}</div>
|
||||||
|
<div class="label-code">{{ loc.locationCode || '-' }}</div>
|
||||||
|
<div class="label-info">
|
||||||
|
<span v-if="loc.area != null">面积:{{ loc.area }} ㎡</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import QrCode from './QrCode.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LocationLabelPrint',
|
||||||
|
components: { QrCode },
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
locations: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
doPrint() {
|
||||||
|
window.print()
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@media print {
|
||||||
|
body > *:not(.el-overlay) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.el-overlay {
|
||||||
|
position: static !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
.el-dialog__wrapper {
|
||||||
|
position: static !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
.el-dialog {
|
||||||
|
box-shadow: none !important;
|
||||||
|
border: none !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
.el-dialog__header,
|
||||||
|
.el-dialog__footer,
|
||||||
|
.label-print-actions {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
.label-print-content {
|
||||||
|
padding: 8mm !important;
|
||||||
|
}
|
||||||
|
.label-card {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.label-print-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-print-content {
|
||||||
|
padding: 24px;
|
||||||
|
background: #fff;
|
||||||
|
font-family: 'Microsoft YaHei', 'SimSun', sans-serif;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-empty {
|
||||||
|
text-align: center;
|
||||||
|
padding: 48px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-card {
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px;
|
||||||
|
text-align: center;
|
||||||
|
min-height: 120px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-qr {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-code {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-info {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #909399;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -48,6 +48,17 @@
|
|||||||
v-hasPermi="['mes:wm:location:remove']"
|
v-hasPermi="['mes:wm:location:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-printer"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleBatchPrint"
|
||||||
|
v-hasPermi="['mes:wm:location:print']"
|
||||||
|
>批量打印</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -107,6 +118,13 @@
|
|||||||
@click="handleHiPrint(scope.row)"
|
@click="handleHiPrint(scope.row)"
|
||||||
v-hasPermi="['mes:wm:location:print']"
|
v-hasPermi="['mes:wm:location:print']"
|
||||||
>标签打印</el-button>
|
>标签打印</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-document"
|
||||||
|
@click="handleSimplePrint(scope.row)"
|
||||||
|
v-hasPermi="['mes:wm:location:print']"
|
||||||
|
>简易打印</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -240,6 +258,12 @@
|
|||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="cancel">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 简易标签打印(不依赖MinIO) -->
|
||||||
|
<LocationLabelPrint
|
||||||
|
:visible.sync="printDialogVisible"
|
||||||
|
:locations="printLocations"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -247,6 +271,7 @@
|
|||||||
import { listLocation, getLocation, delLocation, addLocation, updateLocation, changeFrozenState, setProductMixing, setBatchMixing } from "@/api/mes/wm/location";
|
import { listLocation, getLocation, delLocation, addLocation, updateLocation, changeFrozenState, setProductMixing, setBatchMixing } from "@/api/mes/wm/location";
|
||||||
import {genCode} from "@/api/system/autocode/rule"
|
import {genCode} from "@/api/system/autocode/rule"
|
||||||
import BarcodeImg from "@/components/barcodeImg/index.vue"
|
import BarcodeImg from "@/components/barcodeImg/index.vue"
|
||||||
|
import LocationLabelPrint from "@/components/print/LocationLabelPrint.vue"
|
||||||
import { getBarcodeUrl } from '@/api/mes/wm/barcode';
|
import { getBarcodeUrl } from '@/api/mes/wm/barcode';
|
||||||
import {print} from "../../../../utils/print"
|
import {print} from "../../../../utils/print"
|
||||||
import {getByTemplateType} from "@/api/print/template";
|
import {getByTemplateType} from "@/api/print/template";
|
||||||
@@ -255,7 +280,7 @@ export default {
|
|||||||
name: "Location",
|
name: "Location",
|
||||||
dicts: ['sys_yes_no'],
|
dicts: ['sys_yes_no'],
|
||||||
mixins: [hiprintMixin],
|
mixins: [hiprintMixin],
|
||||||
components: { BarcodeImg } ,
|
components: { BarcodeImg, LocationLabelPrint },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
//自动生成编码
|
//自动生成编码
|
||||||
@@ -266,6 +291,7 @@ export default {
|
|||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
|
selectedRows: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
single: true,
|
single: true,
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
@@ -280,6 +306,9 @@ export default {
|
|||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
open: false,
|
open: false,
|
||||||
|
// 简易打印弹窗
|
||||||
|
printDialogVisible: false,
|
||||||
|
printLocations: [],
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
@@ -314,6 +343,16 @@ export default {
|
|||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 简易打印(不依赖MinIO,纯前端二维码+window.print)
|
||||||
|
handleSimplePrint(row) {
|
||||||
|
this.printLocations = [row]
|
||||||
|
this.printDialogVisible = true
|
||||||
|
},
|
||||||
|
// 批量打印
|
||||||
|
handleBatchPrint() {
|
||||||
|
this.printLocations = this.selectedRows || this.locationList.filter(l => this.ids.includes(l.locationId))
|
||||||
|
this.printDialogVisible = true
|
||||||
|
},
|
||||||
// 使用HiPrint打印
|
// 使用HiPrint打印
|
||||||
async handleHiPrint(row) {
|
async handleHiPrint(row) {
|
||||||
let printData = row
|
let printData = row
|
||||||
@@ -393,6 +432,7 @@ export default {
|
|||||||
// 多选框选中数据
|
// 多选框选中数据
|
||||||
handleSelectionChange(selection) {
|
handleSelectionChange(selection) {
|
||||||
this.ids = selection.map(item => item.locationId)
|
this.ids = selection.map(item => item.locationId)
|
||||||
|
this.selectedRows = selection
|
||||||
this.single = selection.length!==1
|
this.single = selection.length!==1
|
||||||
this.multiple = !selection.length
|
this.multiple = !selection.length
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user