Commit a6b68aed by 杨子

feat: 新增RFID标签管理功能并优化相关模块

refactor(预警记录): 增加批量处理功能并优化物资选择交互
feat(盘点任务): 新增任务管理功能并优化详情展示
fix(物资选择): 修复物资选择对话框的交互问题
style(库存汇总): 优化表格展示和操作按钮布局
docs: 更新POSTEK打印相关文档和工具
parent 89b3f420
......@@ -42,3 +42,12 @@ export function delWmsAlertRecord(recordId) {
method: 'delete'
})
}
// 批量处理预警记录
export function batchEditWmsAlertRecord(data) {
return request({
url: '/ware/wmsAlertRecord/batchEditHandle',
method: 'post',
data: data
})
}
......@@ -54,7 +54,8 @@ export function generateAllInventoryPlan() {
// 执行单个盘点计划
export function generateInventoryPlan(planId) {
return request({
url: '/ware/wmsInventoryTask/generateForPlan/' + planId,
method: 'get'
url: '/ware/wmsInventoryTask/generateForPlan',
method: 'get',
params: { planId: planId }
})
}
......@@ -358,6 +358,9 @@ const exposeMethods = {
getTreeselect
}
// 初始化时加载物资分类树
getTreeselect()
defineExpose(exposeMethods)
</script>
......
......@@ -41,6 +41,7 @@
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="success" icon="Plus" @click="handleAddTag">新增标签</el-button>
</el-form-item>
</el-form>
......@@ -49,12 +50,31 @@
<el-table-column label="标签编码" align="center" prop="tagCode" />
<el-table-column label="EPC编码" align="center" prop="epcCode" />
<el-table-column label="TID编码" align="center" prop="tidCode" />
<el-table-column label="标签类型" align="center" prop="tagType" />
<el-table-column label="标签类型" align="center" prop="tagType">
<template #default="scope">
<dict-tag :options="rfidtag_type" :value="scope.row.tagType" />
</template>
</el-table-column>
<el-table-column label="标签状态" align="center" prop="tagStatus">
<template #default="scope">
<dict-tag :options="is_used" :value="scope.row.tagStatus" />
</template>
</el-table-column>
<el-table-column label="绑定时间" align="center" prop="bindTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.bindTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="解绑时间" align="center" prop="unbindTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.unbindTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="最后读取时间" align="center" prop="lastReadTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.lastReadTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
</el-table>
<pagination
......@@ -72,14 +92,45 @@
</div>
</template>
</el-dialog>
<!-- 新增RFID标签对话框 -->
<el-dialog :title="addDialogTitle" v-model="addDialogVisible" width="500px" append-to-body>
<el-form ref="addTagFormRef" :model="addTagForm" :rules="addTagRules" label-width="80px">
<el-form-item label="标签编码" prop="tagCode">
<el-input v-model="addTagForm.tagCode" placeholder="请输入标签编码" />
</el-form-item>
<el-form-item label="EPC编码" prop="epcCode">
<el-input v-model="addTagForm.epcCode" placeholder="请输入EPC编码" />
</el-form-item>
<el-form-item label="TID编码" prop="tidCode">
<el-input v-model="addTagForm.tidCode" placeholder="请输入TID编码" />
</el-form-item>
<el-form-item label="标签类型" prop="tagType">
<el-select v-model="addTagForm.tagType" placeholder="请选择标签类型">
<el-option v-for="item in rfidtag_type" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="addTagForm.remark" type="textarea" placeholder="请输入备注信息" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitAddTagForm"> </el-button>
<el-button @click="cancelAddTag"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup name="RfidTagSelectDialog">
import { ref, reactive, watch } from 'vue'
import { listWmsRfidTag } from "@/api/ware/wmsRfidTag"
import { parseTime } from "@/utils/ruoyi"
import { listWmsRfidTag, addWmsRfidTag } from "@/api/ware/wmsRfidTag"
import { ElMessage } from 'element-plus'
import { parseTime } from '@/utils/ruoyi'
const {proxy} = getCurrentInstance()
const { is_used } = proxy.useDict('is_used')
const { is_used, rfidtag_type } = proxy.useDict('is_used', 'rfidtag_type')
const props = defineProps({
visible: {
type: Boolean,
......@@ -129,6 +180,30 @@ const rfidTagList = ref([])
// 选中的数据
const selectionList = ref([])
// 新增标签对话框
const addDialogVisible = ref(false)
const addDialogTitle = ref('新增RFID标签')
const addTagFormRef = ref(null)
// 新增标签表单数据
const addTagForm = reactive({
tagCode: '',
epcCode: '',
tidCode: '',
tagType: '',
remark: ''
})
// 新增标签表单验证规则
const addTagRules = reactive({
tagCode: [
{ required: true, message: '标签编码不能为空', trigger: 'blur' }
],
tagType: [
{ required: true, message: '标签类型不能为空', trigger: 'change' }
]
})
// 初始化
const init = () => {
selectionList.value = []
......@@ -183,6 +258,58 @@ const handleCancel = () => {
dialogVisible.value = false
}
// 打开新增标签对话框
const handleAddTag = () => {
resetAddTagForm()
addDialogVisible.value = true
addDialogTitle.value = '新增RFID标签'
}
// 重置新增标签表单
const resetAddTagForm = () => {
addTagForm.tagCode = ''
addTagForm.epcCode = ''
addTagForm.tidCode = ''
addTagForm.tagType = ''
addTagForm.remark = ''
if (addTagFormRef.value) {
addTagFormRef.value.resetFields()
}
}
// 取消新增标签
const cancelAddTag = () => {
addDialogVisible.value = false
resetAddTagForm()
}
// 提交新增标签表单
const submitAddTagForm = () => {
if (!addTagFormRef.value) return
addTagFormRef.value.validate(valid => {
if (valid) {
// 设置标签状态为未使用
const tagData = {
...addTagForm,
tagStatus: '0' // 0表示未使用
}
// 调用新增API
addWmsRfidTag(tagData).then(response => {
ElMessage.success('RFID标签新增成功')
addDialogVisible.value = false
// 刷新标签列表
handleQuery()
}).catch(error => {
ElMessage.error('RFID标签新增失败:' + error.message)
console.error('新增RFID标签失败:', error)
})
}
})
}
// 当对话框打开时初始化数据
watch(() => dialogVisible.value, (newVal) => {
if (newVal) {
......
......@@ -32,6 +32,7 @@
import { ref, reactive, toRefs, onMounted, watch } from 'vue'
import { updateWmsAlertRecord } from "@/api/ware/wmsAlertRecord"
import useUserStore from "@/store/modules/user"
import {dayjs} from 'element-plus'
const props = defineProps({
visible: {
......@@ -62,7 +63,7 @@ const data = reactive({
recordId: null,
handlerId: userStore.id,
handleResult: '',
handleTime: '',
handleTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
alertStatus: '1'
},
rules: {
......@@ -93,7 +94,7 @@ function resetForm() {
recordId: props.recordInfo.recordId || null,
handlerId: userStore.id,
handleResult: '',
handleTime: '',
handleTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
alertStatus: '1'
}
if (handleFormRef.value) {
......
......@@ -2,7 +2,18 @@
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="物资" prop="materialId">
<el-input v-model="queryParams.materialId" placeholder="请输入物资ID" clearable @keyup.enter="handleQuery" />
<el-input
v-model="queryParams.materialName"
placeholder="请选择物资"
readonly
clearable
@click="handleMaterialSelect"
/>
<el-button
slot="append"
icon="Search"
@click="handleMaterialSelect"
></el-button>
</el-form-item>
<el-form-item label="预警级别" prop="alertLevel">
<el-select v-model="queryParams.alertLevel" placeholder="请选择预警级别">
......@@ -25,7 +36,20 @@
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="Edit"
:disabled="multiple"
@click="handleBatchEdit"
v-hasPermi="['ware:wmsAlertRecord:batchEdit']"
>批量处理</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="wmsAlertRecordList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="规则" align="center" prop="alertRule.ruleName" />
<el-table-column label="预警类型" align="center" prop="alertType">
<template #default="scope">
......@@ -144,13 +168,38 @@
<!-- 处理对话框 -->
<HandleAlert :visible="handleOpen" :record-info="handleForm" @update:visible="val => handleOpen = val"
@handle-success="getList" />
<!-- 物资选择对话框 -->
<MaterialSelectDialog
ref="materialSelectRef"
v-model:visible="materialSelectVisible"
:title="'选择物资'"
@confirm="handleMaterialConfirm"
@cancel="handleMaterialCancel"
/>
<!-- 批量处理对话框 -->
<el-dialog :title="'批量处理预警记录'" v-model="batchEditDialogVisible" width="500px" append-to-body>
<el-form ref="batchEditFormRef" :model="batchEditForm" :rules="batchEditRules" label-width="80px">
<el-form-item label="处理结果" prop="handleResult">
<el-input v-model="batchEditForm.handleResult" type="textarea" placeholder="请输入处理结果" rows="4" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitBatchEditForm"> </el-button>
<el-button @click="cancelBatchEdit"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="WmsAlertRecord">
import { listWmsAlertRecord, getWmsAlertRecord, delWmsAlertRecord, addWmsAlertRecord, updateWmsAlertRecord } from "@/api/ware/wmsAlertRecord"
import { listWmsAlertRecord, getWmsAlertRecord, delWmsAlertRecord, addWmsAlertRecord, updateWmsAlertRecord, batchEditWmsAlertRecord } from "@/api/ware/wmsAlertRecord"
import HandleAlert from './components/HandleAlert.vue'
import DetailInfo from './components/DetailInfo.vue'
import MaterialSelectDialog from '@/components/MaterialSelectDialog.vue'
const { proxy } = getCurrentInstance()
......@@ -172,6 +221,24 @@ const detailForm = ref({})
const handleOpen = ref(false)
const handleForm = ref({})
// 物资选择对话框
const materialSelectRef = ref(null)
const materialSelectVisible = ref(false)
// 选中的物资信息
const selectedMaterial = ref({})
// 批量处理对话框
const batchEditDialogVisible = ref(false)
const batchEditFormRef = ref(null)
const batchEditForm = reactive({
handleResult: ''
})
const batchEditRules = reactive({
handleResult: [
{ required: true, message: '处理结果不能为空', trigger: 'blur' }
]
})
const data = reactive({
form: {},
queryParams: {
......@@ -180,6 +247,7 @@ const data = reactive({
ruleId: null,
alertType: null,
materialId: null,
materialName: '',
warehouseId: null,
locationId: null,
currentValue: null,
......@@ -251,6 +319,7 @@ function handleQuery() {
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
queryParams.value.materialName = ''
handleQuery()
}
......@@ -330,5 +399,75 @@ function handleHandle(row) {
handleOpen.value = true
}
/** 物资选择按钮操作 */
function handleMaterialSelect() {
materialSelectVisible.value = true
materialSelectRef.value?.handleQuery()
}
/** 物资选择确认 */
function handleMaterialConfirm(materials) {
if (materials && materials.length > 0) {
selectedMaterial.value = materials[0]
queryParams.value.materialId = materials[0].materialId
queryParams.value.materialName = materials[0].materialName
}
}
/** 物资选择取消 */
function handleMaterialCancel() {
materialSelectVisible.value = false
}
/** 批量处理按钮操作 */
function handleBatchEdit() {
if (ids.value.length === 0) {
proxy.$modal.msgWarning('请选择要处理的预警记录')
return
}
resetBatchEditForm()
batchEditDialogVisible.value = true
}
// 重置批量处理表单
const resetBatchEditForm = () => {
batchEditForm.handleResult = ''
if (batchEditFormRef.value) {
batchEditFormRef.value.resetFields()
}
}
// 取消批量处理
const cancelBatchEdit = () => {
batchEditDialogVisible.value = false
resetBatchEditForm()
}
// 提交批量处理表单
const submitBatchEditForm = () => {
if (!batchEditFormRef.value) return
batchEditFormRef.value.validate(valid => {
if (valid) {
// 准备批量处理数据
const batchData = {
ids: ids.value,
handleResult: batchEditForm.handleResult
}
// 调用批量处理API
batchEditWmsAlertRecord(batchData).then(response => {
proxy.$modal.msgSuccess('批量处理成功')
batchEditDialogVisible.value = false
// 刷新列表
getList()
}).catch(error => {
proxy.$modal.msgError('批量处理失败:' + error.message)
console.error('批量处理失败:', error)
})
}
})
}
getList()
</script>
......@@ -12,10 +12,16 @@
<el-form-item label="物资" prop="materialId">
<el-input
v-model="queryParams.materialName"
placeholder="请输入物资名称"
placeholder="请选择物资"
readonly
clearable
@keyup.enter="handleQuery"
@click="handleQueryMaterialSelect"
/>
<el-button
slot="append"
icon="Search"
@click="handleQueryMaterialSelect"
></el-button>
</el-form-item>
<el-form-item label="预警类型" prop="alertType">
......@@ -232,6 +238,8 @@ const title = ref("")
const materialSelectDialogRef = ref(null)
const materialSelectVisible = ref(false)
const materialInfo = ref(null)
// 标识当前是表单选择还是搜索条件选择
const isQueryMaterialSelect = ref(false)
const data = reactive({
form: {},
......@@ -332,6 +340,7 @@ function handleQuery() {
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
queryParams.value.materialName = null
handleQuery()
}
......@@ -361,8 +370,9 @@ function handleUpdate(row) {
})
}
// 打开物资选择对话框
// 打开物资选择对话框(表单)
function openMaterialSelectDialog() {
isQueryMaterialSelect.value = false
materialSelectVisible.value = true
materialSelectDialogRef.value?.handleQuery()
}
......@@ -371,10 +381,20 @@ function openMaterialSelectDialog() {
function handleMaterialSelectConfirm(materials) {
if (materials && materials.length > 0) {
const selectedMaterial = materials[0]
form.value.materialId = selectedMaterial.materialId
form.value.materialName = selectedMaterial.materialName
// 可以选择存储更多物资信息,方便显示
materialInfo.value = selectedMaterial
if (isQueryMaterialSelect.value) {
// 更新搜索条件
queryParams.value.materialId = selectedMaterial.materialId
queryParams.value.materialName = selectedMaterial.materialName
} else {
// 更新表单
form.value.materialId = selectedMaterial.materialId
form.value.materialName = selectedMaterial.materialName
// 可以选择存储更多物资信息,方便显示
materialInfo.value = selectedMaterial
}
materialSelectVisible.value = false
}
}
......@@ -383,6 +403,15 @@ function handleMaterialSelectCancel() {
materialSelectVisible.value = false
}
// 处理搜索条件中的物资选择
function handleQueryMaterialSelect() {
isQueryMaterialSelect.value = true
materialSelectVisible.value = true
materialSelectDialogRef.value?.handleQuery()
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["wmsAlertRuleRef"].validate(valid => {
......
......@@ -11,8 +11,8 @@
</el-form-item>
</el-form>
<el-table ref="inventoryTableRef" :data="inventoryDetailList" row-key="itemDetailId" border height="calc(100vh - 200px)"
@expand-change="handleExpandChange">
<el-table ref="inventoryTableRef" :data="inventoryDetailList" row-key="itemDetailId" border
height="calc(100vh - 200px)" @expand-change="handleExpandChange">
<el-table-column type="expand" fixed="left">
<template #default="props">
<el-table :data="props.row.inBoundItem" row-key="itemId" border>
......@@ -23,10 +23,11 @@
</template>
</el-table-column>
<el-table-column prop="unitPrice" label="单价(元)" />
<el-table-column label="金额(元)" prop="amount" />
<el-table-column label="金额(元)" prop="amount" />
<el-table-column label="仓库/库区/货架">
<template #default="scope">
{{ scope.row.wmsWarehouse?.warehouseName || '-' }}/{{ scope.row.wmsArea?.areaName || '-' }}/{{ scope.row.wmsLocation?.locationName || '-' }}
{{ scope.row.wmsWarehouse?.warehouseName || '-' }}/{{ scope.row.wmsArea?.areaName || '-' }}/{{
scope.row.wmsLocation?.locationName || '-' }}
</template>
</el-table-column>
<el-table-column prop="storageLocation" label="PTL标签" />
......@@ -45,9 +46,10 @@
<el-table-column prop="wmsMaterial.materialName" label="物资名称" width="150" />
<el-table-column prop="wmsMaterial.materialCode" label="物资编码" width="150" />
<el-table-column prop="wmsMaterial.specification" label="规格型号" width="150" />
<el-table-column prop="planQuantity" label="计划入库" width="100" >
<el-table-column prop="planQuantity" label="计划入库" width="100">
<template #default="scope">
<el-tag type="primary" effect="dark" class="bg-[#409eff] border-[#409eff]">{{ scope.row.planQuantity }}</el-tag>
<el-tag type="primary" effect="dark" class="bg-[#409eff] border-[#409eff]">{{ scope.row.planQuantity
}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="actualQuantity" label="实际入库" width="100">
......@@ -194,7 +196,7 @@ function handleAddInBoundItemSubmit(inBoundOrderItem) {
// 调用更新接口
updateWmsInboundOrderItem(inBoundOrderItem).then(response => {
// 获取当前行
// 获取当前行
const currentRow = inventoryDetailList.value.find(item => item.itemDetailId === inBoundOrderItem.itemDetailId)
getWmsInboundOrderItemDetail(currentRow.itemDetailId).then(response => {
currentRow.actualQuantity = response.data?.actualQuantity
......@@ -310,7 +312,7 @@ function handlePrintQrcode(row) {
materialName: row.wmsMaterial?.materialName || '',
specification: row.wmsMaterial?.specification || ''
}
// 打开二维码打印对话框
qrcodePrintDialogRef.value?.handleOpen()
}
......@@ -325,7 +327,6 @@ function handlePrintRfidTag(row) {
specification: row.wmsMaterial?.specification || ''
}
alert('打印RFID标签:' + row.rfidTagIds)
}
......
......@@ -136,10 +136,11 @@
<span>{{ scope.row.rfidTag || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Document" @click="handleFlowQuery(scope.row)" v-hasPermi="['ware:wmsInventory:flow']">库存履历</el-button>
<el-button link type="primary" icon="View" @click="handleLocationVisualization(scope.row)" v-hasPermi="['ware:wmsInventory:visualization']">货架可视化</el-button>
<el-button link type="primary" icon="EditPen" @click="handleChangeRfidTag(scope.row)" v-hasPermi="['ware:wmsInventory:updaterfid']">更换标签</el-button>
</template>
</el-table-column>
</el-table>
......@@ -175,18 +176,28 @@
v-model:inventory-id="selectedInventoryId"
title="库存履历"
/>
<!-- RFID标签选择对话框 -->
<RfidTagSelectDialog
ref="rfidTagSelectDialogRef"
v-model:visible="rfidTagDialogVisible"
title="选择RFID标签"
@confirm="handleRfidTagConfirm"
@cancel="handleRfidTagCancel"
/>
</div>
</template>
<script setup name="InventorySummary">
import { ref, reactive, onMounted, watch } from 'vue'
import { listMaterialInventory, getMaterialInventoryDetail } from '@/api/ware/wmsInventory'
import { listMaterialInventory, getMaterialInventoryDetail, updateWmsInventory } from '@/api/ware/wmsInventory'
import { listWmsMaterialCategory } from '@/api/ware/wmsMaterialCategory'
import { listWmsWarehouse } from '@/api/ware/wmsWarehouse'
import { listWmsArea } from '@/api/ware/wmsArea'
import { ElMessage } from 'element-plus'
import LocationVisualDialog from './components/LocationVisualDialog.vue'
import InventoryFlowDialog from '@/components/InventoryFlowDialog.vue'
import RfidTagSelectDialog from '@/components/RfidTagSelectDialog.vue'
import { listWmsLocation } from '@/api/ware/wmsLocation'
const { proxy } = getCurrentInstance()
......@@ -234,6 +245,11 @@ const locations = ref([])
const inventoryFlowVisible = ref(false)
const selectedInventoryId = ref(null)
// RFID标签选择对话框
const rfidTagDialogVisible = ref(false)
const selectedInventory = ref(null)
const rfidTagSelectDialogRef = ref(null)
// 获取库存列表
const getInventoryList = () => {
listMaterialInventory(queryParams).then(response => {
......@@ -398,6 +414,66 @@ const handleFlowQuery = (row) => {
inventoryFlowVisible.value = true
}
// 更换RFID标签
const handleChangeRfidTag = (row) => {
// 保存当前选中的库存信息
selectedInventory.value = row
// 显示RFID标签选择对话框
rfidTagDialogVisible.value = true
}
// 处理RFID标签选择确认
const handleRfidTagConfirm = (selectedTags) => {
if (!selectedTags || selectedTags.length === 0) {
ElMessage.warning('请选择一个RFID标签')
return
}
// 获取选中的标签
const selectedTag = selectedTags[0]
// 准备更新数据
const updateData = {
inventoryId: selectedInventory.value.inventoryId,
rfidTag: selectedTag.tagCode,
rfidTagId: selectedTag.tagId
}
// 调用API更新库存的RFID标签
updateWmsInventory(updateData).then(response => {
ElMessage.success('RFID标签更换成功')
// 刷新当前展开行的数据
const expandedRow = inventoryList.value.find(row =>
row.materialId === selectedInventory.value.material.materialId
)
if (expandedRow) {
const params = {
materialId: expandedRow.materialId,
warehouseId: queryParams.warehouseId,
areaId: queryParams.areaId,
showzerostock: queryParams.showzerostock
}
getMaterialInventoryDetail(params).then(response => {
expandedRow.inventoryList = response.data
})
}
}).catch(error => {
ElMessage.error('RFID标签更换失败:' + error.message)
console.error('RFID标签更换失败:', error)
})
// 关闭对话框
rfidTagDialogVisible.value = false
}
// 处理RFID标签选择取消
const handleRfidTagCancel = () => {
// 关闭对话框
rfidTagDialogVisible.value = false
// 清空选中的库存信息
selectedInventory.value = null
}
// 初始化
onMounted(() => {
initWarehouseList()
......
......@@ -34,11 +34,15 @@
v-hasPermi="['ware:wmsInventoryPlan:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
<el-button type="success" plain icon="Edit"
:disabled="single || !canBatchEditOrDelete"
@click="handleUpdate"
v-hasPermi="['ware:wmsInventoryPlan:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
<el-button type="danger" plain icon="Delete"
:disabled="multiple || !canBatchEditOrDelete"
@click="handleDelete"
v-hasPermi="['ware:wmsInventoryPlan:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
......@@ -58,14 +62,14 @@
</template>
</el-table-column>
<el-table-column label="仓库" align="center" prop="warehouseId" />
<el-table-column label="库区" align="center" prop="areaNames" />
<el-table-column label="物资" align="center" prop="materialNames" />
<el-table-column label="计划开始时间" align="center" prop="startTime" width="180">
<el-table-column label="库区" align="center" prop="areaNames" width="180" />
<el-table-column label="物资" align="center" prop="materialNames" width="180" />
<el-table-column label="计划开始时间" align="center" prop="startTime">
<template #default="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="计划结束时间" align="center" prop="endTime" width="180">
<el-table-column label="计划结束时间" align="center" prop="endTime">
<template #default="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
</template>
......@@ -91,8 +95,10 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-if="scope.row.planStatus === '0'"
v-hasPermi="['ware:wmsInventoryPlan:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-if="scope.row.planStatus === '0'"
v-hasPermi="['ware:wmsInventoryPlan:remove']">删除</el-button>
<el-button link type="primary" icon="VideoPlay" @click="handleGenerate(scope.row)"
v-hasPermi="['ware:wmsInventoryPlan:generate']">执行</el-button>
......@@ -184,6 +190,7 @@
</template>
<script setup name="WmsInventoryPlan">
import { computed, ref, reactive } from 'vue'
import { listWmsInventoryPlan, getWmsInventoryPlan, delWmsInventoryPlan, addWmsInventoryPlan, updateWmsInventoryPlan, generateAllInventoryPlan, generateInventoryPlan } from "@/api/ware/wmsInventoryPlan"
import WarehouseSelectDialog from "@/components/WarehouseSelectDialog.vue"
import AreaSelectTreeDialog from "@/components/AreaSelectTreeDialog.vue"
......@@ -268,6 +275,14 @@ const data = reactive({
const { queryParams, form, rules } = toRefs(data)
// 计算是否可以批量编辑或删除
const canBatchEditOrDelete = computed(() => {
// 只有当所有选中的记录都是未开始状态(planStatus === '0')时,才允许批量操作
return ids.value.length > 0 && wmsInventoryPlanList.value.every(item => {
return !ids.value.includes(item.planId) || item.planStatus === '0'
})
})
/** 查询盘点计划列表 */
function getList() {
loading.value = true
......@@ -373,6 +388,7 @@ function handleSelectionChange(selection) {
ids.value = selection.map(item => item.planId)
single.value = selection.length != 1
multiple.value = !selection.length
// 每次选择变化时,canBatchEditOrDelete 会自动重新计算
}
/** 新增按钮操作 */
......
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="盘点任务ID" prop="taskId">
<el-input
v-model="queryParams.taskId"
placeholder="请输入盘点任务ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘点计划ID" prop="planId">
<el-input
v-model="queryParams.planId"
placeholder="请输入盘点计划ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="仓库ID" prop="warehouseId">
<el-input
v-model="queryParams.warehouseId"
placeholder="请输入仓库ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="仓库名称" prop="warehouseName">
<el-input
v-model="queryParams.warehouseName"
......@@ -33,31 +9,7 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="库区ID" prop="areaId">
<el-input
v-model="queryParams.areaId"
placeholder="请输入库区ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="库区名称" prop="areaName">
<el-input
v-model="queryParams.areaName"
placeholder="请输入库区名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘点员ID" prop="checkerId">
<el-input
v-model="queryParams.checkerId"
placeholder="请输入盘点员ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘点员姓名" prop="checkerName">
<el-form-item label="盘点员" prop="checkerName">
<el-input
v-model="queryParams.checkerName"
placeholder="请输入盘点员姓名"
......@@ -65,110 +17,6 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘点开始时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择盘点开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="盘点结束时间" prop="endTime">
<el-date-picker clearable
v-model="queryParams.endTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择盘点结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="盘点总项数" prop="totalItems">
<el-input
v-model="queryParams.totalItems"
placeholder="请输入盘点总项数"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="已盘项数" prop="countedItems">
<el-input
v-model="queryParams.countedItems"
placeholder="请输入已盘项数"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘盈项数" prop="surplusItems">
<el-input
v-model="queryParams.surplusItems"
placeholder="请输入盘盈项数"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘亏项数" prop="deficitItems">
<el-input
v-model="queryParams.deficitItems"
placeholder="请输入盘亏项数"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘盈总量" prop="totalSurplus">
<el-input
v-model="queryParams.totalSurplus"
placeholder="请输入盘盈总量"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="盘亏总量" prop="totalDeficit">
<el-input
v-model="queryParams.totalDeficit"
placeholder="请输入盘亏总量"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="总差异价值" prop="totalDifferenceValue">
<el-input
v-model="queryParams.totalDifferenceValue"
placeholder="请输入总差异价值"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="差异率" prop="differenceRate">
<el-input
v-model="queryParams.differenceRate"
placeholder="请输入差异率"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="审核人ID" prop="auditorId">
<el-input
v-model="queryParams.auditorId"
placeholder="请输入审核人ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="审核人姓名" prop="auditorName">
<el-input
v-model="queryParams.auditorName"
placeholder="请输入审核人姓名"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="审核时间" prop="auditTime">
<el-date-picker clearable
v-model="queryParams.auditTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择审核时间">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
......
<template>
<el-form ref="addFormRef" :model="form" :rules="rules" label-width="110px">
<el-form-item label="任务名称" prop="taskName">
<el-input v-model="form.taskName" placeholder="请输入任务名称" />
</el-form-item>
<el-form-item label="仓库" prop="warehouseId">
<div style="display: flex; align-items: center;">
<el-input v-model="form.warehouseName" placeholder="请选择仓库" readonly style="flex: 1;" />
<el-button type="primary" @click="openWarehouseSelectDialog">选择</el-button>
</div>
</el-form-item>
<el-form-item label="库区" prop="areaIds">
<div style="display: flex; align-items: center;">
<el-input v-model="form.areaNames" placeholder="请选择库区" readonly style="flex: 1;" />
<el-button type="primary" @click="openAreaSelectDialog">选择</el-button>
</div>
</el-form-item>
<el-form-item label="物资" prop="materialIds">
<div style="display: flex; align-items: center;">
<el-input v-model="form.materialNames" placeholder="请选择物资" readonly style="flex: 1;" />
<el-button type="primary" @click="openMaterialSelectDialog">选择</el-button>
</div>
</el-form-item>
<el-form-item label="是否使用RFID" prop="useRfid">
<el-switch v-model="form.useRfid" active-text="是" inactive-text="否" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<!-- 仓库选择对话框 -->
<WarehouseSelectDialog ref="warehouseSelectDialogRef" v-model:visible="warehouseSelectVisible"
@confirm="handleWarehouseConfirm" />
<!-- 库区选择对话框 -->
<AreaSelectTreeDialog ref="areaSelectDialogRef" v-model:visible="areaSelectVisible" @confirm="handleAreaConfirm" />
<!-- 物资选择对话框 -->
<MaterialSelectDialog ref="materialSelectDialogRef" v-model:visible="materialSelectVisible"
@confirm="handleMaterialConfirm" />
</template>
<script setup name="AddForm">
import { ref, reactive, toRefs, defineEmits, getCurrentInstance } from 'vue'
import WarehouseSelectDialog from "@/components/WarehouseSelectDialog.vue"
import AreaSelectTreeDialog from "@/components/AreaSelectTreeDialog.vue"
import MaterialSelectDialog from "@/components/MaterialSelectDialog.vue"
const emit = defineEmits(['submit', 'cancel'])
// 获取当前实例
const { proxy } = getCurrentInstance()
// 表单引用
const addFormRef = ref(null)
// 选择对话框控制变量
const warehouseSelectDialogRef = ref(null)
const areaSelectDialogRef = ref(null)
const materialSelectDialogRef = ref(null)
const warehouseSelectVisible = ref(false)
const areaSelectVisible = ref(false)
const materialSelectVisible = ref(false)
const data = reactive({
form: {
taskName: '',
warehouseId: null,
warehouseName: '',
areaIds: [],
areaNames: '',
materialIds: [],
materialNames: '',
useRfid: false,
remark: ''
},
rules: {
taskName: [
{ required: true, message: "任务名称不能为空", trigger: "blur" }
],
warehouseId: [
{ required: true, message: "仓库不能为空", trigger: "change" }
],
areaIds: [
{ required: true, message: "库区不能为空", trigger: "change" }
],
materialIds: [
{ required: true, message: "物资不能为空", trigger: "change" }
]
}
})
const { form, rules } = toRefs(data)
// 打开仓库选择对话框
function openWarehouseSelectDialog() {
warehouseSelectVisible.value = true
warehouseSelectDialogRef.value?.handleQuery()
}
// 打开库区选择对话框
function openAreaSelectDialog() {
if (!form.value.warehouseId) {
proxy.$modal.msgWarning("请先选择仓库")
return
}
areaSelectVisible.value = true
areaSelectDialogRef.value?.handleQuery()
}
// 打开物资选择对话框
function openMaterialSelectDialog() {
materialSelectVisible.value = true
materialSelectDialogRef.value?.handleQuery()
}
// 处理仓库选择确认
function handleWarehouseConfirm(selection) {
if (selection && selection.length > 0) {
const warehouse = selection[0]
form.value.warehouseId = warehouse.warehouseId
form.value.warehouseName = warehouse.warehouseName
// 清空已选择的库区和物资
form.value.areaIds = []
form.value.areaNames = ''
form.value.materialIds = []
form.value.materialNames = ''
}
}
// 处理库区选择确认
function handleAreaConfirm(selection) {
if (selection && selection.length > 0) {
form.value.areaIds = selection.map(item => item.areaId)
form.value.areaNames = selection.map(item => item.areaName).join(',')
}
}
// 处理物资选择确认
function handleMaterialConfirm(selection) {
if (selection && selection.length > 0) {
form.value.materialIds = selection.map(item => item.materialId)
form.value.materialNames = selection.map(item => item.materialName).join(',')
}
}
// 提交表单
function submitForm(callback) {
addFormRef.value.validate(valid => {
if (valid) {
emit('submit', form.value)
callback && callback(form.value)
}
})
}
// 取消操作
function handleCancel() {
emit('cancel')
}
// 重置表单
function resetForm() {
form.value = {
taskName: '',
warehouseId: null,
warehouseName: '',
areaIds: [],
areaNames: '',
materialIds: [],
materialNames: '',
useRfid: false,
remark: ''
}
addFormRef.value?.resetFields()
}
// 暴露方法
defineExpose({
submitForm,
resetForm
})
</script>
\ No newline at end of file
......@@ -5,8 +5,8 @@
<h3>任务基础信息</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="盘点计划ID">{{ taskInfo.planId }}</el-descriptions-item>
<el-descriptions-item label="盘点任务编号">{{ taskInfo.taskNo }}</el-descriptions-item>
<el-descriptions-item label="任务状态">{{ taskInfo.taskStatus }}</el-descriptions-item>
<el-descriptions-item label="任务编号">{{ taskInfo.taskNo }}</el-descriptions-item>
<el-descriptions-item label="任务名称">{{ taskInfo.taskName }}</el-descriptions-item>
<el-descriptions-item label="总盘点数">{{ taskInfo.totalItems }}</el-descriptions-item>
<el-descriptions-item label="已盘数">{{ taskInfo.countedItems }}</el-descriptions-item>
<!-- <el-descriptions-item label="盘点设备">{{ taskInfo.inventoryDevice }}</el-descriptions-item> -->
......
......@@ -9,7 +9,7 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="EPC编码" prop="epcCode">
<el-form-item label="EPC编码" prop="epcCode" label-width="80px">
<el-input
v-model="queryParams.epcCode"
placeholder="请输入EPC编码"
......@@ -25,14 +25,6 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="绑定物资ID" prop="materialId">
<el-input
v-model="queryParams.materialId"
placeholder="请输入绑定物资ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="批次号" prop="batchNo">
<el-input
v-model="queryParams.batchNo"
......@@ -41,14 +33,6 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="库存ID" prop="inventoryId">
<el-input
v-model="queryParams.inventoryId"
placeholder="请输入库存ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="绑定时间" prop="bindTime">
<el-date-picker clearable
v-model="queryParams.bindTime"
......@@ -57,38 +41,6 @@
placeholder="请选择绑定时间">
</el-date-picker>
</el-form-item>
<el-form-item label="绑定人" prop="binderId">
<el-input
v-model="queryParams.binderId"
placeholder="请输入绑定人"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="解绑时间" prop="unbindTime">
<el-date-picker clearable
v-model="queryParams.unbindTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择解绑时间">
</el-date-picker>
</el-form-item>
<el-form-item label="最后读取时间" prop="lastReadTime">
<el-date-picker clearable
v-model="queryParams.lastReadTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择最后读取时间">
</el-date-picker>
</el-form-item>
<el-form-item label="最后读取设备" prop="lastReadDevice">
<el-input
v-model="queryParams.lastReadDevice"
placeholder="请输入最后读取设备"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
......@@ -125,35 +77,30 @@
v-hasPermi="['ware:wmsRfidTag:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['ware:wmsRfidTag:export']"
>导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="wmsRfidTagList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="标签ID" align="center" prop="tagId" />
<el-table-column label="标签编码" align="center" prop="tagCode" />
<el-table-column label="EPC编码" align="center" prop="epcCode" />
<el-table-column label="TID编码" align="center" prop="tidCode" />
<el-table-column label="绑定物资ID" align="center" prop="materialId" />
<el-table-column label="批次号" align="center" prop="batchNo" />
<el-table-column label="库存ID" align="center" prop="inventoryId" />
<el-table-column label="标签类型" align="center" prop="tagType" />
<el-table-column label="标签状态" align="center" prop="tagStatus" />
<el-table-column label="标签类型" align="center" prop="tagType">
<template #default="scope">
<dict-tag :options="rfidtag_type" :value="scope.row.tagType" />
</template>
</el-table-column>
<el-table-column label="标签状态" align="center" prop="tagStatus">
<template #default="scope">
<dict-tag :options="is_used" :value="scope.row.tagStatus" />
</template>
</el-table-column>
<el-table-column label="绑定时间" align="center" prop="bindTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.bindTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="绑定人" align="center" prop="binderId" />
<el-table-column label="解绑时间" align="center" prop="unbindTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.unbindTime, '{y}-{m}-{d}') }}</span>
......@@ -164,12 +111,11 @@
<span>{{ parseTime(scope.row.lastReadTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="最后读取设备" align="center" prop="lastReadDevice" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['ware:wmsRfidTag:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['ware:wmsRfidTag:remove']">删除</el-button>
<el-button v-if="scope.row.tagStatus === '0'" link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['ware:wmsRfidTag:edit']">修改</el-button>
<el-button v-if="scope.row.tagStatus === '0'" link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['ware:wmsRfidTag:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
......@@ -194,44 +140,10 @@
<el-form-item label="TID编码" prop="tidCode">
<el-input v-model="form.tidCode" placeholder="请输入TID编码" />
</el-form-item>
<el-form-item label="绑定物资ID" prop="materialId">
<el-input v-model="form.materialId" placeholder="请输入绑定物资ID" />
</el-form-item>
<el-form-item label="批次号" prop="batchNo">
<el-input v-model="form.batchNo" placeholder="请输入批次号" />
</el-form-item>
<el-form-item label="库存ID" prop="inventoryId">
<el-input v-model="form.inventoryId" placeholder="请输入库存ID" />
</el-form-item>
<el-form-item label="绑定时间" prop="bindTime">
<el-date-picker clearable
v-model="form.bindTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择绑定时间">
</el-date-picker>
</el-form-item>
<el-form-item label="绑定人" prop="binderId">
<el-input v-model="form.binderId" placeholder="请输入绑定人" />
</el-form-item>
<el-form-item label="解绑时间" prop="unbindTime">
<el-date-picker clearable
v-model="form.unbindTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择解绑时间">
</el-date-picker>
</el-form-item>
<el-form-item label="最后读取时间" prop="lastReadTime">
<el-date-picker clearable
v-model="form.lastReadTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择最后读取时间">
</el-date-picker>
</el-form-item>
<el-form-item label="最后读取设备" prop="lastReadDevice">
<el-input v-model="form.lastReadDevice" placeholder="请输入最后读取设备" />
<el-form-item label="标签类型" prop="tagType">
<el-select v-model="form.tagType" placeholder="请选择标签类型">
<el-option v-for="item in rfidtag_type" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
......@@ -252,6 +164,8 @@ import { listWmsRfidTag, getWmsRfidTag, delWmsRfidTag, addWmsRfidTag, updateWmsR
const { proxy } = getCurrentInstance()
const {rfidtag_type,is_used} = proxy.useDict("rfidtag_type", "is_used")
const wmsRfidTagList = ref([])
const open = ref(false)
const loading = ref(true)
......@@ -285,6 +199,9 @@ const data = reactive({
tagCode: [
{ required: true, message: "标签编码不能为空", trigger: "blur" }
],
tagType: [
{ required: true, message: "标签类型不能为空", trigger: "change" }
],
}
})
......@@ -316,7 +233,7 @@ function reset() {
materialId: null,
batchNo: null,
inventoryId: null,
tagType: null,
tagType: '0', // 标签类型:0-柔性标签,1-抗金属标签
tagStatus: null,
bindTime: null,
binderId: null,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment