新增用户系统

部分bug修复
11月21日
This commit is contained in:
杨学谦 2025-11-21 09:39:38 +08:00
parent 7e201dd001
commit c7eebdab59
43 changed files with 2923 additions and 1123 deletions

View File

@ -5,11 +5,28 @@ import request from "@/http/request";
*/
export const getGoodsInfoByPage = (params) => {
return request({
url: '/goods/getGoodsInfoByPage',
url: '/taskQuery/queryOutsByPage',
method: 'post',
data: params
})
}
export const upOutsType = (params) => {
return request({
url: '/taskQuery/upOutsType',
method: 'post',
data: params
})
}
export const editDate = (params) => {
return request({
url: '/taskQuery/editDate',
method: 'post',
data: params
})
}
/**
* 根据物料id查询物料信息
*/

View File

@ -16,6 +16,14 @@ export const requireStockOut = (params) => {
})
}
export const requireStockOutEmpty = (params) => {
return request({
url: '/task/requireStockOutEmpty',
method: 'post',
data: params
})
}
export const getCompareData = (params) => {
return request({
url: '/task/getCompareData',

View File

@ -32,6 +32,15 @@ export const queryPickTasksByPage = (params) => {
data: params
})
}
export const updatePickTaskInfo = (params) => {
return request({
url: '/taskQuery/updatePickTaskInfo',
method: 'post',
data: params
})
}
// 分页查询出库单
export const queryOutsByPage = (params) => {
return request({

View File

@ -147,3 +147,12 @@ export function deleteUserInfo(params) {
timeout: 5000
})
}
export function changePasswordInfo(params) {
return request({
url: '/user/changePasswordInfo',
method: 'post',
data: params,
timeout: 5000
})
}

View File

@ -177,39 +177,47 @@ export const wmsTaskStatusOptions = [
},
]
// 拣选任务状态枚举
// export const pickingTaskStatusOptions = [
// // {
// // value: -2,
// // label: '入库用'
// // },
// // {
// // value: -1,
// // label: '暂存中'
// // },
// {
// value: 0,
// label: '待下发'
// },
// {
// value: 1,
// label: '已下发'
// },
// {
// value: 2,
// label: '执行中'
// },
// {
// value: 3,
// label: '已到达'
// },
// // {
// // value: 4,
// // label: '已离开'
// // },
// // {
// // value: 5,
// // label: '已取消'
// // },
// ]
// 确认选项定义类似这样
export const pickingTaskStatusOptions = [
{
value: -2,
label: '入库用'
},
{
value: -1,
label: '暂存中'
},
{
value: 0,
label: '待下发'
},
{
value: 1,
label: '已下发'
},
{
value: 2,
label: '执行中'
},
{
value: 3,
label: '已到达'
},
{
value: 4,
label: '已离开'
},
{
value: 5,
label: '已取消'
},
{ value: -1, label: '暂存' },
{ value: 0, label: '待下发' },
{ value: 1, label: '已下发' },
{ value: 3, label: '已到达' }
]
// 是否枚举
export const yesOrNoOptions = [

View File

@ -11,24 +11,28 @@
<el-input v-model="searchQueryFormEntity.goodsId" @keyup.enter="search()"
clearable/>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="searchQueryFormEntity.goodsDesc" @keyup.enter="search()"
<el-form-item label="工单详情">
<el-input v-model="searchQueryFormEntity.workOrder" @keyup.enter="search()"
clearable/>
</el-form-item>
<!-- <el-form-item label="工单号">-->
<!-- <el-input v-model="searchQueryFormEntity.goodsDesc" @keyup.enter="search()"-->
<!-- clearable/>-->
<!-- </el-form-item>-->
</el-row>
<div style="align-content: center;">
<el-row>
<el-button type="primary" class="btn-search" @click="search()">查询</el-button>
<el-button type="warning" class="btn-search" @click="clearQuery()">清除输入</el-button>
</el-row>
<el-row>
<el-button style="background-color: #00CED1;" class="btn-search"
@click="openUploadDialog()">导入数据
</el-button>
<el-button type="success" class="btn-search"
@click="exportExcel()">导出excel
</el-button>
</el-row>
<!-- <el-row>-->
<!-- <el-button style="background-color: #00CED1;" class="btn-search"-->
<!-- @click="openUploadDialog()">导入数据-->
<!-- </el-button>-->
<!-- <el-button type="success" class="btn-search"-->
<!-- @click="exportExcel()">导出excel-->
<!-- </el-button>-->
<!-- </el-row>-->
</div>
</div>
</el-form>
@ -43,28 +47,48 @@
<el-radio :label="scope.row.goodsId" v-model="goodsId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="workOrder" label="工单详情" fixed="left" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="goodsId" label="料号" fixed="left" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="goodsDescription" label="描述" min-width="120px" sortable="custom"
<el-table-column prop="needNum" label="需求数量" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="plant" label="工厂" min-width="120px" sortable="custom"
<el-table-column prop="distributeNum" label="已分配数量" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="vendorName" label="供应商" min-width="120px" sortable="custom"
<el-table-column prop="pickNum" label="已拣选数量" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="isSled" label="SLED管理" min-width="120px" sortable="custom"
<el-table-column prop="outType" label="优先级" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="sledDays" label="SLED天数" min-width="120px" sortable="custom"
<el-table-column prop="destination" label="呼叫站台" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="feedingType" label="补料类型" min-width="120px" sortable="custom"
<el-table-column prop="specialStock" label="特殊库存" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="boxQty" label="每盒数量" min-width="120px" sortable="custom"
<el-table-column prop="specialStockNo" label="特殊库存号" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="maxBoxNum" label="最大盒数" min-width="120px" sortable="custom"
<el-table-column prop="specialStockItemNo" label="特殊库存Item号" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="putArea" label="存放区域" min-width="120px" sortable="custom"
<el-table-column prop="batchNo" label="批次号" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column prop="hotPoint" label="热点区域" min-width="120px" sortable="custom"
<el-table-column prop="taskId" label="任务号" min-width="120px" sortable="custom"
show-overflow-tooltip/>
<el-table-column
prop="pickingDate"
label="执行时间"
fixed="right"
min-width="120px"
sortable="custom"
:formatter="(row, column, cellValue) => formatDateToDay(cellValue)"
show-overflow-tooltip/>
<el-table-column label="操作" fixed="right" min-width="180px">
<template v-slot="scope">
<div style="display: flex; gap: 5px; justify-content: center;">
<el-button size="default" type="success" @click.stop="handleEdit(scope.row)">编辑</el-button>
<el-button size="default" type="warning" @click.stop="handleDelete(scope.row)">加急</el-button>
</div>
</template>
</el-table-column>
</el-table>
<br/>
<el-pagination v-model:current-page="baseTableQuery.currentPage"
@ -73,16 +97,27 @@
@current-change="search" layout="total, sizes, prev, pager, next, jumper"
:total="baseTableQuery.total"/>
</div>
<el-dialog v-model="showUploadDialog" title="上传物料信息" width="40%" draggable :show-close="true">
<fieldset class="search-area">
<legend>导入基础信息</legend>
<UploadExcelBaseGoods></UploadExcelBaseGoods>
</fieldset>
<fieldset class="search-area">
<legend>导入看板信息</legend>
<UploadExcelKanban></UploadExcelKanban>
</fieldset>
<el-dialog v-model="showEditDialog" title="编辑执行日期" width="30%" draggable>
<el-form ref="editFormRef" :model="editForm" label-width="100px">
<el-form-item label="执行时间">
<el-date-picker
v-model="editForm.pickingDate"
type="date"
placeholder="请选择执行时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showEditDialog = false">取消</el-button>
<el-button type="primary" @click="saveEdit(editForm)">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</el-container>
</el-config-provider>
@ -91,7 +126,7 @@
<script setup>
import store from '@/store'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import {getGoodsInfoByPage} from '@/api/goods.js'
import {editDate, getGoodsInfoByPage, upOutsType} from '@/api/goods.js'
import {ref, reactive, onMounted, nextTick, onBeforeUnmount} from 'vue'
import {ElMessage} from 'element-plus'
import {genTableRequest} from '@/utils/generator.js'
@ -122,7 +157,8 @@ let baseTableQuery = reactive({
})
let searchQueryFormEntity = reactive({
goodsId: '',
goodsDesc: ''
goodsDesc: '',
workOrder: '',
})
let searchQueryFormRef = ref()
let rowEditFlag = ref(false)
@ -147,6 +183,81 @@ onBeforeUnmount(() => {
const resizeHeight = () => {
maxHeight.value = window.innerHeight * 0.55
}
//
const saveEdit = (editForm) => {
let request = {
taskId: editForm.taskId,
pickingDate: editForm.pickingDate
}
editDate( request).then((res) => {
if (res.data.code === 0) {
ElMessage({
message: '操作成功',
type: 'success',
});
search()
} else {
ElMessage({
message: res.data.message,
type: 'error',
});
}
})
showEditDialog.value = false
search() //
}
//
const handleDelete = (row) => {
//
let request = {
taskId: row.taskId,
}
upOutsType( request).then((res) => {
if (res.data.code === 0) {
ElMessage({
message: '操作成功',
type: 'success',
});
search()
} else {
ElMessage({
message: res.data.message,
type: 'error',
});
}
})
}
//
const showEditDialog = ref(false)
const editForm = reactive({
pickingDate: '',
taskId: ''
})
const editFormRef = ref()
//
const handleEdit = (row) => {
editForm.taskId = row.taskId
// 使 formatDateToDay
editForm.pickingDate = row.pickingDate ? formatDateToDay(row.pickingDate) : ''
showEditDialog.value = true
}
const formatDateToDay = (dateString) => {
if (!dateString) return '';
//
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
/**
* 自定义方法
*/
@ -155,8 +266,10 @@ const search = () => {
tableLoading.value = true
let request = genTableRequest(baseTableQuery)
//
request.queryType = 1
request.goodsId = searchQueryFormEntity.goodsId.trim()
request.goodsDesc = searchQueryFormEntity.goodsDesc.trim()
request.vehicleId = searchQueryFormEntity.goodsDesc.trim()
request.workOrder = searchQueryFormEntity.workOrder.trim()
getGoodsInfoByPage(request).then((res) => {
const response = res.data
if (response.code === 0) {
@ -180,6 +293,7 @@ const search = () => {
const clearQuery = () => {
searchQueryFormEntity.goodsId = ''
searchQueryFormEntity.goodsDesc = ''
searchQueryFormEntity.workOrder = ''
}
const handleSortChange = (data) => {
if (baseTableQuery.sortBy.has(data.prop)) {

View File

@ -253,7 +253,7 @@ const route = useRoute()// 路由
//
onMounted(() => {
nextTick(() => {
startTimer() //
//startTimer() //
})
})
onBeforeUnmount(() => {

View File

@ -216,6 +216,8 @@ const getInventory = () => {
childStandOrder = ['P16', 'P15', 'P14']
} else if (STAND_ID === 'P3') {
childStandOrder = ['P19', 'P18', 'P17']
} else {
childStandOrder = ['P23', 'P22', 'P21']
}
//
@ -267,6 +269,8 @@ const getChildStandIdByIndex = (index) => {
childStandOrder = ['P16', 'P15', 'P14']
} else if (STAND_ID === 'P3') {
childStandOrder = ['P19', 'P18', 'P17']
} else {
childStandOrder = ['P23', 'P22', 'P21']
}
return childStandOrder[index] || ''

View File

@ -116,7 +116,9 @@ export default {
warningQty: null,
containerNo: '',
standId: '',
remark: ''
remark: '',
totalQty: '',
isEmpty: ''
},
transferList: [],
inventoryList: [],
@ -191,6 +193,8 @@ export default {
planPickQty: this.bindingData.planPickQty,
realPickQty: this.bindingData.realPickQty,
containerNo: this.bindingData.containerNo,
totalQty: this.bindingData.totalQty,
isEmpty: this.bindingData.isEmpty
},
stockConfirm: {
stockId: this.bindingData.stockId,
@ -246,6 +250,7 @@ export default {
})
}).catch(() => {
//
this.showLoading = false;
})
},
@ -294,6 +299,8 @@ export default {
this.bindingData.planPickQty = result.taskConfirm.planPickQty
this.bindingData.realPickQty = result.taskConfirm.realPickQty
this.bindingData.containerNo = result.taskConfirm.containerNo || '' // containerNo
this.bindingData.totalQty = result.taskConfirm.totalQty
this.bindingData.isEmpty = result.taskConfirm.isEmpty
}
// stockConfirm

View File

@ -54,14 +54,14 @@
show-overflow-tooltip />
<el-table-column prop="leaveTime" label="离开时间" :formatter="timeFormat" min-width="120px" sortable="custom"
show-overflow-tooltip />
<!-- <el-table-column fixed="right" label="操作" width="170px">
<el-table-column fixed="right" label="操作" width="120px">
<template v-slot="scope">
<div style="display: inline-block; align-content: center;">
<el-button type="primary"
@click="editCurrentRowFormEntity(scope.row)">编辑</el-button>
</div>
</template>
</el-table-column> -->
</el-table-column>
</el-table>
<br />
<el-pagination v-model:current-page="baseTableQuery.currentPage"
@ -72,13 +72,53 @@
</div>
</div>
</el-container>
<el-dialog v-model="dialogVisible" title="拣选任务详细信息" width="40%" draggable :show-close="false">
<div style="max-width: 100%; max-height: 500px; overflow: auto; display: flex; justify-content: center;">
<el-form ref="pickTaskFormRef" :model="pickTaskFormEntity" :label-position="labelPosition"
label-width="100px" style="width: 95%;" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="任务号" prop="pickId">
<el-input v-model="pickTaskFormEntity.pickId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="箱号" prop="vehicleId">
<el-input v-model="pickTaskFormEntity.vehicleId" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="目标站台" prop="pickStand">
<el-input v-model="pickTaskFormEntity.pickStand" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务状态" prop="pickStatus">
<el-select-v2 v-model="pickTaskFormEntity.pickStatus" placeholder="请选择任务状态"
:options="pickingTaskStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitInfo(pickTaskFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</template>
<script setup>
import store from '@/store'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { queryPickTasksByPage } from '@/api/taskQuery.js'
import { queryPickTasksByPage,updatePickTaskInfo } from '@/api/taskQuery.js'
import { timeFormatter, pickTaskStatusFormatter } from '@/utils/formatter.js'
import { ref, reactive, onMounted, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
@ -87,6 +127,7 @@ import { labelPosition } from '@/constant/form.js'
import {pickingTaskStatusOptions} from '@/constant/options.js'
import { addAllOptionOfOptions } from '@/utils/generator.js'
import { loading } from '@/utils/loading'
import {errorBox} from "@/utils/myMessageBox";
/**
* 常量定义
*/
@ -95,6 +136,10 @@ const USER_NAME = store.getters.getUserName
/**
* 变量定义
*/
//
let dialogVisible = ref(false)
let pickTaskFormEntity = reactive({})
let pickTaskFormRef = ref()
let maxHeight = ref(window.innerHeight * 0.55)
let tableLoading = ref(false)
let tableData = ref([])
@ -130,6 +175,43 @@ onBeforeUnmount(() => {
const resizeHeight = () => {
maxHeight.value = window.innerHeight * 0.55
}
const editCurrentRowFormEntity = (row) => {
pickId = row.pickId
Object.assign(pickTaskFormEntity, {
pickId: row.pickId,
vehicleId: row.vehicleId,
pickStand: row.pickStand,
pickStatus: parseInt(row.pickStatus) //
})
console.log('编辑行数据:', pickTaskFormEntity) //
dialogVisible.value = true
}
const submitInfo = (formData) => {
const params = {
pickId: formData.pickId,
pickStatus: formData.pickStatus,
userName: store.getters.getUserName
}
updatePickTaskInfo(params).then(res => {
console.log('更新拣选任务参数:', res.data.code)
if (res.data.code === 0) {
dialogVisible.value = false
ElMessage.success('更新拣选任务成功。')
} else {
console.log(res)
errorBox(res.data.message)
}
}).catch(err => {
console.log(err)
errorBox('更新拣选任务失败。')
})
dialogVisible.value = false
search() //
}
/**
* 自定义方法
*/

View File

@ -18,24 +18,22 @@
:cell-style="{ 'text-align': 'center' }">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.userId" v-model="userId">&nbsp;</el-radio>
<el-radio :label="scope.row.loginAccount" v-model="loginAccount">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="userId" label="id" fixed="left" min-width="120px" show-overflow-tooltip />
<el-table-column prop="userName" label="用户名" min-width="120px" show-overflow-tooltip />
<el-table-column prop="roleId" label="角色" :formatter="roleFormat" min-width="120px"
show-overflow-tooltip />
<el-table-column prop="loginAccount" label="登录账户" min-width="120px" show-overflow-tooltip/>
<el-table-column prop="addTime" label="增加时间" :formatter="timeFormat" show-overflow-tooltip
<el-table-column prop="userName" label="用户名" min-width="120px" show-overflow-tooltip/>
<el-table-column prop="addTime" label="添加时间" :formatter="timeFormat" show-overflow-tooltip
min-width="120px"/>
<el-table-column prop="updateTime" label="更新时间" :formatter="timeFormat" min-width="120px"
show-overflow-tooltip/>
<el-table-column prop="addUser" label="添加用户" min-width="120px" show-overflow-tooltip/>
<el-table-column fixed="right" label="操作" min-width="120px">
<el-table-column fixed="right" label="操作" min-width="140px">
<template v-slot="scope">
<div style="display: flex;justify-content: space-between;">
<el-button plain type="primary" @click="editCurrentRow(scope.row)">编辑</el-button>
<el-button plain type="danger" @click="deleteCurrentRow(scope.row)">删除</el-button>
<el-button style="width: 80px" plain type="primary" @click="editCurrentRow(scope.row)">编辑</el-button>
<el-button style="width: 80px" plain type="warning" @click="changePassword(scope.row)">改密</el-button>
<el-button style="width: 80px" plain type="danger" @click="deleteCurrentRow(scope.row)">删除</el-button>
</div>
</template>
</el-table-column>
@ -52,8 +50,8 @@
label-width="100px" style="width: 95%;" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="用户id" prop="userId">
<el-input v-model="userFormEntity.userId" disabled />
<el-form-item label="登录账户" prop="loginAccount">
<el-input v-model="userFormEntity.loginAccount" disabled/>
</el-form-item>
</el-col>
<el-col :span="12">
@ -62,19 +60,6 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="登录账户" prop="loginAccount">
<el-input v-model="userFormEntity.loginAccount" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="角色" prop="roleId">
<el-select-v2 v-model="userFormEntity.roleId" placeholder="请选择角色"
:options="roleOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
@ -92,12 +77,6 @@
<el-form ref="addUserFormRef" :model="addUserFormEntity" :label-position="labelPosition"
label-width="100px" style="width: 95%;" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="角色" prop="roleIdUpdate">
<el-select-v2 v-model="addUserFormEntity.roleIdUpdate" placeholder="请选择角色"
:options="roleOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户名" prop="userNameUpdate">
<el-input v-model="addUserFormEntity.userNameUpdate" clearable/>
@ -127,13 +106,56 @@
</span>
</template>
</el-dialog>
<el-dialog v-model="passwordDialogVisible" title="修改密码" width="40%" draggable :show-close="false">
<div style="max-width: 100%; max-height: 350px; overflow: auto; display: flex; justify-content: center;">
<el-form ref="passwordFormRef" :model="passwordFormEntity" :label-position="labelPosition"
label-width="100px" style="width: 95%;" :rules="passwordRules" status-icon>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="登录账户">
<el-input v-model="passwordFormEntity.loginAccount" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="passwordFormEntity.oldPassword" show-password clearable/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="passwordFormEntity.newPassword" show-password clearable/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="确认新密码" prop="confirmPassword">
<el-input v-model="passwordFormEntity.confirmPassword" show-password clearable/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="passwordDialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitPasswordChange(passwordFormEntity)">
确认修改
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</div>
</template>
<script setup>
import store from '@/store'
import { getUserList, getRoleOptions, updateUserInfo, addUserInfo, deleteUserInfo } from '@/api/user.js'
import {getUserList, getRoleOptions, updateUserInfo, addUserInfo, deleteUserInfo, changePasswordInfo} from '@/api/user.js'
import {errorBox} from '@/utils/myMessageBox.js'
import {ElMessageBox, ElMessage} from 'element-plus'
import {ref, reactive} from 'vue'
@ -142,9 +164,20 @@ import { Search } from '@element-plus/icons-vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
</script>
<script>
export default {
name: 'role_user',
data() {
//
const validateConfirmPassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入新密码'))
} else if (value !== this.passwordFormEntity.newPassword) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
return {
userList: [],
currentPage: 1,
@ -153,7 +186,7 @@ export default {
userNameQuery: '',
loading: true,
dialogVisible: false,
userId: '',
loginAccount: '',
userFormEntity: reactive({}),
userFormRef: ref(),
labelPosition: 'top',
@ -162,13 +195,47 @@ export default {
addUserDialogVisible: false,
addUserFormEntity: reactive({}),
addUserFormRef: ref(),
passwordDialogVisible: false,
passwordFormEntity: reactive({
loginAccount: '',
oldPassword: '',
newPassword: '',
confirmPassword: ''
}),
passwordFormRef: ref(),
passwordRules: {
oldPassword: [
{ required: true, message: '请输入旧密码', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请确认新密码', trigger: 'blur' },
{ validator: validateConfirmPassword, trigger: 'blur' }
]
}
}
},
mounted() {
this.getRoleOptions()
this.search()
},
methods: {
//
changePassword(row) {
this.passwordFormEntity = {
loginAccount: row.loginAccount,
oldPassword: '',
newPassword: '',
confirmPassword: ''
}
this.passwordDialogVisible = true
},
getRoleOptions() {
const request = {
roleId: store.getters.getUser.roleId,
@ -176,7 +243,7 @@ export default {
getRoleOptions(request).then(res => {
const tableResponse = res.data
if (tableResponse.code == 0) {
this.roleOptions = tableResponse.returnData
this.roleOptions = tableResponse.data
} else {
this.roleOptions = []
}
@ -190,14 +257,14 @@ export default {
const request = {
pageNo: this.currentPage,
pageSize: this.pageSize,
userName: this.userNameQuery.trim(),
userName: store.getters.getUserName,
roleId: store.getters.getUser.roleId,
}
getUserList(request).then(res => {
const tableResponse = res.data
if (tableResponse.code == 0) {
this.userList = tableResponse.returnData.lists
this.total = tableResponse.returnData.total
this.userList = tableResponse.data.lists
this.total = tableResponse.data.total
} else {
errorBox(tableResponse.message)
}
@ -231,14 +298,37 @@ export default {
loginAccount: row.loginAccount,
roleId: row.roleId,
}
// this.getRoleOptions()
this.dialogVisible = true
},
deleteCurrentRow(row) {
this.userId = row.userId
if (store.getters.getUser.roleId != 1) {
errorBox("操作人员必须是管理员级别。")
return
submitPasswordChange(formData) {
this.$refs.passwordFormRef.validate((valid) => {
if (valid) {
const params = {
loginAccountUpdate: formData.loginAccount,
oldPassword: formData.oldPassword,
newPassword: formData.newPassword,
roleIdOp: store.getters.getUser.roleId,
userName: store.getters.getUserName
}
// API changePassword API
changePasswordInfo(params).then(res => {
if (res.data.code === 0) {
this.passwordDialogVisible = false
ElMessage.success('密码修改成功。')
} else {
errorBox(res.data.message)
}
}).catch(err => {
console.log(err)
errorBox('密码修改失败。')
})
}
})
},
deleteCurrentRow(row) {
this.loginAccount = row.loginAccount
ElMessageBox.confirm(
'该操作会从数据库中删除用户。\n是否继续',
'警告',
@ -249,8 +339,8 @@ export default {
}
).then(() => {
const params = {
userIdUpdate: row.userId,
roleId1: store.getters.getUser.roleId,
loginAccountUpdate: row.loginAccount,
roleIdOp: store.getters.getUser.roleId,
userName: store.getters.getUserName
}
deleteUserInfo(params).then(res => {
@ -275,15 +365,15 @@ export default {
loginAccountUpdate: '',
loginPasswordUpdate: '',
}
this.getRoleOptions()
this.addUserDialogVisible = true
},
submitInfo(formData) {
const params = {
roleIdUpdate: formData.roleId,
userIdUpdate: formData.userId,
userNameUpdate: formData.userName,
loginAccountUpdate: formData.loginAccount,
roleId1: store.getters.getUser.roleId,
roleIdOp: store.getters.getUser.roleId,
userName: store.getters.getUserName
}
updateUserInfo(params).then(res => {
@ -305,11 +395,11 @@ export default {
userNameUpdate: formData.userNameUpdate,
loginAccountUpdate: formData.loginAccountUpdate,
loginPasswordUpdate: formData.loginPasswordUpdate,
roleId1: store.getters.getUser.roleId,
roleIdOp: store.getters.getUser.roleId,
userName: store.getters.getUserName
}
addUserInfo(params).then(res => {
if (res.data.code == 0) {
if (res.data.code === 0) {
this.addUserDialogVisible = false
ElMessage.success('添加用户信息成功。')
this.search()

View File

@ -33,6 +33,7 @@
</el-row>
<div style="align-content: center;">
<el-row>
<el-button type="danger" class="btn-search" @click="openEmptyBoxDialog()">出空箱</el-button>
<el-button type="primary" class="btn-search" @click="search()">查询</el-button>
<el-button type="warning" class="btn-search" @click="clearQuery()">清除输入</el-button>
</el-row>
@ -80,94 +81,42 @@
@current-change="search" layout="total, sizes, prev, pager, next, jumper"
:total="baseTableQuery.total" />
</div>
<el-dialog v-model="rowEditFlag" title="工作信息" width="40%" draggable :show-close="false">
<el-form ref="rowEditFormRef" :model="rowFormEntity" :label-position="labelPosition"
label-width="100px" style="max-width: 100%" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="工作编号">
<el-input v-model="rowFormEntity.workIndex" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工单号">
<el-input v-model="rowFormEntity.workOrder" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="总成号">
<el-input v-model="rowFormEntity.productId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="成品号">
<el-input v-model="rowFormEntity.singleProductId" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料盒号">
<el-input v-model="rowFormEntity.boxNo" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="料号">
<el-input v-model="rowFormEntity.goodsId" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="需求数量">
<el-input-number v-model.number="rowFormEntity.needNum" controls-position="right"
:min="0" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="已完成数量">
<el-input-number v-model.number="rowFormEntity.finishNum" controls-position="right"
:min="0" :max="rowFormEntity.needNum" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="已分配数量">
<el-input-number v-model.number="rowFormEntity.distributeNum"
controls-position="right" :min="0" :max="rowFormEntity.needNum" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="工作状态">
<el-select-v2 v-model="rowFormEntity.workStatus" placeholder="请选择工作状态"
:options="workStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="缺料状态">
<el-select-v2 v-model="rowFormEntity.lackStatus" placeholder="请选择缺料状态"
:options="lackStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="rowEditFlag = false">取消</el-button>
<el-button type="success" @click="submitUpdateRow(rowFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</el-container>
</el-config-provider>
<el-dialog v-model="emptyBoxDialogVisible" title="出空箱" width="30%" draggable :show-close="false">
<el-form ref="emptyBoxFormRef" :model="emptyBoxFormEntity" label-width="100px" status-icon>
<el-form-item label="箱号" prop="vehicleId">
<el-input
v-model="emptyBoxFormEntity.vehicleId"
placeholder="请输入箱号"
clearable
@input="handleVehicleIdInput"
/>
</el-form-item>
<el-form-item
label="出空箱数量"
prop="quantity"
:rules="[{ required: true, message: '请输入数量', trigger: 'blur' }]">
<el-input-number
v-model="emptyBoxFormEntity.quantity"
controls-position="right"
:min="1"
:max="9999"
:disabled="!!(emptyBoxFormEntity.vehicleId && emptyBoxFormEntity.vehicleId.trim() !== '')"
style="width: 100%"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="cancelEmptyBox()">取消</el-button>
<el-button type="primary" @click="submitEmptyBox()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
@ -182,9 +131,20 @@ import { labelPosition } from '@/constant/form.js'
import { yesOrNoOptions, vehicleStatusOptions } from '@/constant/options.js'
import { addAllOptionOfOptions } from '@/utils/generator.js'
import { loading } from '@/utils/loading'
import {requireStockOutEmpty} from "@/api/task";
import {errorBox} from "@/utils/myMessageBox";
// API
/**
* 常量定义
*/
//
const emptyBoxDialogVisible = ref(false)
const emptyBoxFormRef = ref()
const emptyBoxFormEntity = reactive({
quantity: 1,
vehicleId: '' //
})
const STAND_ID = store.getters.getStandId
const USER_NAME = store.getters.getUserName
/**
@ -230,9 +190,17 @@ onBeforeUnmount(() => {
const resizeHeight = () => {
maxHeight.value = window.innerHeight * 0.55
}
/**
* 自定义方法
*/
const handleVehicleIdInput = (value) => {
// 1
if (value && value.trim() !== '') {
emptyBoxFormEntity.quantity = 1
}
}
//
const search = () => {
tableLoading.value = true
@ -357,6 +325,59 @@ const submitUpdateRow = (rowFormEntity) => {
loading.close()
})
}
/**
* 出空箱功能相关方法
*/
const openEmptyBoxDialog = () => {
emptyBoxDialogVisible.value = true
}
const cancelEmptyBox = () => {
emptyBoxDialogVisible.value = false
emptyBoxFormEntity.quantity = 1
}
const submitEmptyBox = async () => {
try {
//
if (!emptyBoxFormRef.value) return
await emptyBoxFormRef.value.validate()
//
const request = {
outType: 1,
needNum: emptyBoxFormEntity.quantity,
vehicleId: emptyBoxFormEntity.vehicleId,
standId: STAND_ID,
userName: USER_NAME,
destination: STAND_ID
}
//
loading.open('提交中...')
requireStockOutEmpty(request).then(res => {
const response = res.data
if (response.code === 0) {
//
ElMessage.success(response.message)
} else {
errorBox(response.message)
}
}).catch(err => {
console.log(err)
errorBox('请求错误。')
}).finally(() => {
loading.close()
})
} catch (error) {
loading.close()
console.error('提交出空箱数量失败:', error)
ElMessage.error('提交出空箱数量失败')
}
}
</script>
<style scoped>
.content {

View File

@ -1,18 +1,18 @@
package com.wms_main.controller.wms;
import com.wms_main.model.po.TAppInventory;
import com.wms_main.model.po.TAppOuts;
import com.wms_main.model.po.TAppPickTask;
import com.wms_main.model.po.TAppTask;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms_main.dao.impl.TAppLocationServiceImpl;
import com.wms_main.dao.impl.TAppStockServiceImpl;
import com.wms_main.model.po.TAppLocation;
import com.wms_main.model.po.TAppStock;
import com.wms_main.service.controller.IDataControllerService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 看板数据类
@ -24,6 +24,161 @@ import java.util.List;
@RequestMapping("/wms/board")
public class DataController {
private final IDataControllerService dataControllerService;
private final TAppStockServiceImpl tAppStockService;
private final TAppLocationServiceImpl tAppLocationService;
@GetMapping("/api/query/queryRecentTask")
public Map<String, Object> queryRecentTask() {
try {
List<Map<String, Object>> result = dataControllerService.queryRecentTask();
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", true);
response.put("responseCode", 0);
response.put("responseMessage", "查询成功");
response.put("returnData", result);
return response;
} catch (Exception e) {
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", false);
response.put("responseCode", -1);
response.put("responseMessage", "查询失败: " + e.getMessage());
return response;
}
}
@PostMapping("/api/query/queryStockDetail")
public Map<String, Object> queryStockDetail(@RequestBody Map<String, Object> request) {
try {
// 提取请求参数
String requestDate = (String) request.get("requestDate");
String locationId = (String) request.get("locationId");
// 验证请求时间参数
if (requestDate == null || requestDate.isEmpty()) {
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", false);
response.put("responseCode", 500);
response.put("responseMessage", "请求时间不能为空");
return response;
}
// 调用服务层查询库存详情
//List<Map<String, Object>> stockDetails = dataControllerService.queryStockDetail(locationId);
List<Map<String, Object>> stockDetails = new ArrayList<>();
// 1. 构造查询条件
LambdaQueryWrapper<TAppStock> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(TAppStock::getLocationId, locationId);
// 2. 查询库存数据
List<TAppStock> stockList = tAppStockService.list(queryWrapper);
if (stockList.isEmpty()){
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", false);
response.put("responseCode", 500);
response.put("responseMessage", "库存数据为空");
return response;
}
// 3. 转换为 Map 格式返回
for (TAppStock stock : stockList) {
Map<String, Object> item = new HashMap<>();
item.put("goodsId", stock.getGoodsId()); // 物料编号
item.put("goodsName", stock.getGoodsDesc()); // 物料名称
item.put("goodsNum", stock.getRealNum()); // 物料数量
item.put("wareDate", stock.getFirstInTime()); // 库上架时间
item.put("specialStock", stock.getSpecialStock()); // 质量kg
item.put("specialStockNo", stock.getSpecialStockNo()); // 产期
item.put("specialStockItemNo", stock.getSpecialStockItemNo()); // 到期期
item.put("batchId", stock.getBatchNo()); // 批次号
stockDetails.add(item);
}
// 构造符合要求的返回数据结构
Map<String, Object> locationInfo = new HashMap<>();
locationInfo.put("locationId", locationId); // 使用传入的locationId
locationInfo.put("vesselNo", stockList.getFirst().getVehicleId()); // 这里需要根据实际业务获取vesselNo
locationInfo.put("locationData", stockDetails);
List<Map<String, Object>> result = new ArrayList<>();
result.add(locationInfo);
// 构造成功响应
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", true);
response.put("responseCode", 0);
response.put("responseMessage", "查询成功");
response.put("returnData", result);
return response;
} catch (Exception e) {
// 构造失败响应
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", false);
response.put("responseCode", 500);
response.put("responseMessage", "查询失败: " + e.getMessage());
return response;
}
}
@GetMapping("/api/query/queryLocationDetail")
public Map<String, Object> queryLocationDetail() {
try {
// 查询所有库位数据
List<TAppLocation> locationList = tAppLocationService.list();
// 转换为所需格式
List<Map<String, Object>> result = new ArrayList<>();
for (TAppLocation location : locationList) {
Map<String, Object> item = new HashMap<>();
item.put("locationId", location.getLocationId()); // 库位编号
item.put("row", location.getLRow());
item.put("line", location.getLCol());
item.put("layer", location.getLLayer());
item.put("deep", 1); // 深度默认返回1
item.put("locationStatus", location.getIsOccupy());
// 设置库位状态根据是否有库存判断
result.add(item);
}
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", true);
response.put("responseCode", 0);
response.put("responseMessage", "查询成功");
response.put("returnData", result);
return response;
} catch (Exception e) {
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", false);
response.put("responseCode", 500);
response.put("responseMessage", "查询失败: " + e.getMessage());
return response;
}
}
@GetMapping("/api/query/queryRunningTask")
public Map<String, Object> queryRunningTask() {
try {
// 调用服务层查询运行中的任务数据
List<Map<String, Object>> result = dataControllerService.queryRunningTask();
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", true);
response.put("responseCode", 0);
response.put("responseMessage", "查询成功");
response.put("returnData", result);
return response;
} catch (Exception e) {
Map<String, Object> response = new HashMap<>();
response.put("isSuccess", false);
response.put("responseCode", 500);
response.put("responseMessage", "查询失败: " + e.getMessage());
return response;
}
}
/**

View File

@ -63,6 +63,16 @@ public class TaskController {
return taskControllerService.requireStockOut(stockOutRequest);
}
/**
* 请求出库空箱
* @param stockOutRequest 获取请求
* @return 处理结果
*/
@PostMapping("/requireStockOutEmpty")
public BaseWmsApiResponse requireStockOutEmpty(@RequestBody StockOutRequest stockOutRequest) {
return taskControllerService.requireStockOutEmpty(stockOutRequest);
}
/**
* 拉取EWM系统的库存信息进行比对
*/
@ -104,9 +114,9 @@ public class TaskController {
* @return 处理结果
*/
// @PostMapping("/requireVehiclesForIn")
// public BaseWmsApiResponse requireVehiclesForIn(@RequestBody VehicleOutForInRequest voiRequest) {
// return taskControllerService.requireVehiclesForIn(voiRequest);
// }
public BaseWmsApiResponse requireVehiclesForIn(@RequestBody VehicleOutForInRequest voiRequest) {
return taskControllerService.requireVehiclesForIn(voiRequest);
}
/**
* 接收wcs反馈任务状态

View File

@ -5,6 +5,7 @@ import com.wms_main.model.dto.query.OutsQuery;
import com.wms_main.model.dto.query.PickTaskQuery;
import com.wms_main.model.dto.query.WmsTaskQuery;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.po.TAppPickTask;
import com.wms_main.model.vo.wms.*;
import com.wms_main.service.controller.ITaskQueryControllerService;
import lombok.RequiredArgsConstructor;
@ -77,6 +78,39 @@ public class TaskQueryController {
return taskQueryControllerService.queryOutsByPage(outsQuery);
}
/**
* 更新出库单信息
*
* @param appTask 出库单信息
* @return 结果
*/
@PostMapping("/updatePickTaskInfo")
public WmsApiResponse<String> updatePickTaskInfo(@RequestBody TAppPickTask appTask) {
return taskQueryControllerService.updateOutsInfo(appTask);
}
/**
* 出库提高优先级
* @param outsVo 修改参数
* @return 修改结果
*/
@PostMapping("/upOutsType")
public WmsApiResponse<String> upOutsType(@RequestBody OutsVo outsVo)
{
return taskQueryControllerService.upOutsType(outsVo);
}
/*
outs修改出库日期
*/
@PostMapping("/editDate")
public WmsApiResponse<String> editDate(@RequestBody OutsVo outsVo)
{
return taskQueryControllerService.editDate(outsVo);
}
/**
* 盘点信息分页查询
* @param inventoryQuery 查询参数

View File

@ -1,10 +1,14 @@
package com.wms_main.controller.wms;
import com.wms_main.model.dto.query.UserQuery;
import com.wms_main.model.dto.query.UserUpdateRequest;
import com.wms_main.model.dto.response.wms.BaseWmsApiResponse;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.vo.wms.PageVo;
import com.wms_main.model.vo.wms.UserVo;
import com.wms_main.service.controller.IUserControllerService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* 用户控制类
@ -16,4 +20,57 @@ import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RequestMapping("/wms/user")
public class UserController {
private final IUserControllerService userControllerService;
/**
* 查询用户列表
* @param userQuery 查询参数
* @return 查询结果
*/
@PostMapping("/getUserList")
WmsApiResponse<PageVo<UserVo>> getUserList(@RequestBody UserQuery userQuery) {
return userControllerService.getUserList(userQuery);
}
/**
* 添加用户信息
* @param userUpdateRequest 添加参数
* @return 添加结果
*/
@PostMapping("/addUserInfo")
BaseWmsApiResponse addUserInfo(@RequestBody UserUpdateRequest userUpdateRequest) {
return userControllerService.addUserInfo(userUpdateRequest);
}
/**
* 删除用户信息
* @param userUpdateRequest 删除参数
* @return 删除结果
*/
@PostMapping("/deleteUserInfo")
BaseWmsApiResponse deleteUserInfo(@RequestBody UserUpdateRequest userUpdateRequest) {
return userControllerService.deleteUserInfo(userUpdateRequest);
}
/**
* 更新用户信息
* @param userUpdateRequest 更新参数
* @return 更新结果
*/
@PostMapping("/updateUserInfo")
BaseWmsApiResponse updateUserInfo(@RequestBody UserUpdateRequest userUpdateRequest) {
return userControllerService.updateUserInfo(userUpdateRequest);
}
/**
* 修改用户密码
* @param userUpdateRequest 密码修改参数
* @return 修改结果
*/
@PostMapping("/changePasswordInfo")
BaseWmsApiResponse changePassword(@RequestBody UserUpdateRequest userUpdateRequest) {
return userControllerService.changePassword(userUpdateRequest);
}
}

View File

@ -5,6 +5,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* 任务确认实体
*/
@ -53,4 +55,17 @@ public class TaskConfirmEntity {
*/
@JsonProperty("containerNo")
private String containerNo;
/**
* 需求合并数量
*/
@JsonProperty("totalQty")
private Integer totalQty;
/**
* 是否空
*/
@JsonProperty("isEmpty")
private int isEmpty;
}

View File

@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 出库单查询
@ -83,4 +84,18 @@ public class OutsQuery extends PageQuery {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime requestTime;
/**
* 拣货日期
*/
@JsonProperty("pickingDate")
private Date pickingDate;
/**
* 工单号
*/
@JsonProperty("workOrder")
private String workOrder;
}

View File

@ -0,0 +1,87 @@
package com.wms_main.model.dto.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* 用户查询类
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserQuery extends PageQuery{
/**
* 登录账号
*/
@JsonProperty("loginAccount")
private String loginAccount;
/**
* 登录密码
*/
@JsonProperty("loginPassword")
private String loginPassword;
/**
* 用户名---显示
*/
@JsonProperty("userName")
private String userName;
/**
* 角色id
*/
@JsonProperty("roleId")
private String roleId;
/**
* 登录状态
*/
@JsonProperty("loginStatus")
private Integer loginStatus;
/**
* 账号状态
*/
@JsonProperty("accountStatus")
private Integer accountStatus;
/**
* 上次登录设备
*/
@JsonProperty("lastLoginDevice")
private String lastLoginDevice;
/**
* 上次登录时间
*/
@JsonProperty("lastLoginTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastLoginTime;
/**
* 添加用户
*/
@JsonProperty("addUser")
private String addUser;
/**
* 添加时间
*/
@JsonProperty("addTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime addTime;
/**
* 上次更新用户
*/
@JsonProperty("lastUpdateUser")
private String lastUpdateUser;
/**
* 上次更新时间
*/
@JsonProperty("lastUpdateTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastUpdateTime;
}

View File

@ -0,0 +1,55 @@
package com.wms_main.model.dto.query;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms_main.model.dto.request.wms.BaseWmsRequest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* 用户更新请求
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserUpdateRequest extends BaseWmsRequest {
/**
* 角色id1
*/
@JsonProperty("roleIdOp")
private String roleIdOp;
/**
* 新增用户角色
*/
@JsonProperty("roleIdUpdate")
private String roleIdUpdate;
/**
* 用户名
*/
@JsonProperty("userNameUpdate")
private String userNameUpdate;
/**
* 登录账号
*/
@JsonProperty("loginAccountUpdate")
private String loginAccountUpdate;
/**
* 登录密码
*/
@JsonProperty("loginPasswordUpdate")
private String loginPasswordUpdate;
/**
* 旧密码
*/
@JsonProperty("oldPassword")
private String oldPassword;
/**
* 新密码
*/
@JsonProperty("newPassword")
private String newPassword;
}

View File

@ -15,6 +15,7 @@ public class EwmApiLocalResponse {
private String billNo; // 单据号ASN
private String billType; // 单据类型
private String containerNo; // 容器号可选
private boolean emptyContainer; // 是否空箱
private List<TaskDetailInfo> taskDetailInfo; // 任务明细列表
}

View File

@ -1,5 +1,6 @@
package com.wms_main.model.po;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@ -141,4 +142,14 @@ public class TAppOuts {
*/
@TableField(value = "picking_date")
private Date pickingDate;
/**
* 拣货计划ID
*/
@TableField(value = "pick_plan_id")
private String pickPlanId;
@TableField(value = "pick_plan_id_times")
private int pickPlanIdTimes;
}

View File

@ -3,6 +3,7 @@ package com.wms_main.model.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -78,4 +79,5 @@ public class TAppOutsRecord {
*/
@TableField(value = "work_order")
private String workOrder;
}

View File

@ -52,4 +52,16 @@ public class TAppPickPlan {
*/
@TableField(value = "stand_id")
private String standId;
/**
* 客户工单号
*/
@TableField(value = "order_no")
private String orderNo;
/**
* 箱子是否用完
*/
@TableField(value = "is_empty")
private Integer isEmpty;
}

View File

@ -10,6 +10,7 @@ import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 出库单Vo
@ -77,6 +78,43 @@ public class OutsVo {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime requestTime;
/**
* 特殊库存标识可选
*/
@JsonProperty("specialStock")
private String specialStock;
/**
* so单号与供应商编号出库指定SO号或者供应商编号出库可选
*/
@JsonProperty("specialStockNo")
private String specialStockNo;
/**
* 特殊库存item号可选
*/
@JsonProperty("specialStockItemNo")
private String specialStockItemNo;
/**
* 批次号可选
*/
@JsonProperty("batchNo")
private String batchNo;
/**
* 工单
*/
@JsonProperty("workOrder")
private String workOrder;
/**
* 拣货日期
*/
@JsonProperty("pickingDate")
private Date pickingDate;
/**
* 将po转换为vo
* @param po 数据库实体
@ -97,7 +135,13 @@ public class OutsVo {
po.getDestination(),
po.getUserName(),
po.getReason(),
po.getRequestTime()
po.getRequestTime(),
po.getSpecialStock(),
po.getSpecialStockNo(),
po.getSpecialStockItemNo(),
po.getBatchNo(),
po.getWorkOrder(),
po.getPickingDate()
);
}
@ -121,7 +165,10 @@ public class OutsVo {
po.getDestination(),
po.getUserName(),
po.getReason(),
po.getRequestTime()
po.getRequestTime(),
null,null,null,null,
po.getWorkOrder(),
null
);
}
}

View File

@ -1,10 +1,14 @@
package com.wms_main.model.vo.wms;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms_main.model.po.TSysUser;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* 用户Vo
@ -14,20 +18,71 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class UserVo {
/**
* 登录账
* 登录账
*/
@JsonProperty("loginAccount")
private String loginAccount;
/**
* 用户名
* 登录密码
*/
@JsonProperty("loginPassword")
private String loginPassword;
/**
* 用户名---显示
*/
@JsonProperty("userName")
private String userName;
/**
* 角色Id
* 角色id
*/
@JsonProperty("roleId")
private String roleId;
/**
* 登录状态
*/
@JsonProperty("loginStatus")
private Integer loginStatus;
/**
* 账号状态
*/
@JsonProperty("accountStatus")
private Integer accountStatus;
/**
* 上次登录设备
*/
@JsonProperty("lastLoginDevice")
private String lastLoginDevice;
/**
* 上次登录时间
*/
@JsonProperty("lastLoginTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastLoginTime;
/**
* 添加用户
*/
@JsonProperty("addUser")
private String addUser;
/**
* 添加时间
*/
@JsonProperty("addTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime addTime;
/**
* 上次更新用户
*/
@JsonProperty("lastUpdateUser")
private String lastUpdateUser;
/**
* 上次更新时间
*/
@JsonProperty("lastUpdateTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastUpdateTime;
/**
* 从po转化为vo
@ -39,6 +94,14 @@ public class UserVo {
userVo.setLoginAccount(userPo.getLoginAccount());
userVo.setUserName(userPo.getUserName());
userVo.setRoleId(userPo.getRoleId());
userVo.setLoginStatus(userPo.getLoginStatus());
userVo.setAccountStatus(userPo.getAccountStatus());
userVo.setLastLoginDevice(userPo.getLastLoginDevice());
userVo.setLastLoginTime(userPo.getLastLoginTime());
userVo.setAddUser(userPo.getAddUser());
userVo.setAddTime(userPo.getAddTime());
userVo.setLastUpdateUser(userPo.getLastUpdateUser());
userVo.setLastUpdateTime(userPo.getLastUpdateTime());
return userVo;
}
}

View File

@ -0,0 +1,33 @@
package com.wms_main.repository.utils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Component
@RequiredArgsConstructor
public class DbTransUtils {
private final PlatformTransactionManager transactionManager;
/**
* 执行一个事务方法
* @param baseTran 事务类
* @return 执行结果
*/
public boolean useTran(Runnable baseTran) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
baseTran.run();
transactionManager.commit(status);
return true;
} catch (Exception e) {
transactionManager.rollback(status);
return false;
}
}
}

View File

@ -62,6 +62,23 @@ public class StringUtils {
return str + c.repeat(Math.max(0, length - str.length()));
}
/**
* 验证密码是否正确
* @param inputPassword 用户输入的明文密码
* @param storedPassword 数据库中存储的加密密码
* @return 验证结果 true:密码正确
*/
public static boolean verifyPassword(String inputPassword, String storedPassword) {
if (isEmpty(inputPassword) || isEmpty(storedPassword)) {
return false;
}
// 对输入的明文密码进行相同的加密处理
String encryptedInput = encryptPassword(inputPassword);
// 比较加密后的结果是否与存储的密码一致
return encryptedInput.equals(storedPassword);
}
/**
* 判断一个字符串是否为数字
* @param str 要判断的字符串

View File

@ -17,6 +17,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* Wcs接口服务实现
*/
@ -32,38 +34,120 @@ public class WcsApiServiceImpl implements IWcsApiService {
* @param request 任务请求
* @return 响应结果
*/
// @Override
// public WcsApiResponse<WcsStackerTask> sendWcsStackerTask(WcsStackerTaskRequest request) {
// // 设置http请求
// HttpRequest httpRequest = HttpRequest.postInstanceOf(appCommon.getConfigByKey(AppConfigKeyEnums.WCS_STACKER_TASK_URL.getKey()), request);
// httpRequest.setTimeout(30000);
// HttpResponse httpResponse = httpClient.httpPost(httpRequest);
// if (httpResponse != null && httpResponse.isSuccess()) {
// WcsApiResponse<WcsStackerTask> response = new WcsApiResponse<>();
// response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
// return response;
// }
// return WcsApiResponse.error("请求未获得响应信息。", null);
// }
@Override
public WcsApiResponse<WcsStackerTask> sendWcsStackerTask(WcsStackerTaskRequest request) {
final long startNs = System.nanoTime();
try {
// 设置http请求
HttpRequest httpRequest = HttpRequest.postInstanceOf(appCommon.getConfigByKey(AppConfigKeyEnums.WCS_STACKER_TASK_URL.getKey()), request);
httpRequest.setTimeout(30000);
HttpResponse httpResponse = httpClient.httpPost(httpRequest);
final long durationMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
// 记录请求日志
log.info("[WCS堆垛机任务调用] 接口={}, 耗时={}ms" ,
appCommon.getConfigByKey(AppConfigKeyEnums.WCS_STACKER_TASK_URL.getKey()),
durationMs);
// 慢请求报警阈值按需调整
if (durationMs > 5000) {
log.warn("慢请求告警: 调用wcs系统堆垛机任务接口超时{} 耗时{}ms",
appCommon.getConfigByKey(AppConfigKeyEnums.WCS_STACKER_TASK_URL.getKey()),
durationMs);
}
if (httpResponse != null && httpResponse.isSuccess()) {
WcsApiResponse<WcsStackerTask> response = new WcsApiResponse<>();
response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
return response;
}
return WcsApiResponse.error("请求未获得响应信息。", null);
} catch (Exception e) {
final long durationMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
log.error("[WCS堆垛机任务调用] 接口={} 异常, 耗时={}ms, 错误信息={}",
appCommon.getConfigByKey(AppConfigKeyEnums.WCS_STACKER_TASK_URL.getKey()),
durationMs,
e.getMessage(), e);
throw e;
}
}
/**
* 发送拣选任务
* @param request 任务请求
* @return 响应结果
*/
// @Override
// public WcsApiResponse<WcsPickTask> sendPickTask(WcsPickTaskRequest request) {
// // 设置http请求
// HttpRequest httpRequest = HttpRequest.postInstanceOf(appCommon.getConfigByKey(AppConfigKeyEnums.WCS_PICK_TASK_URL.getKey()), request);
// httpRequest.setTimeout(30000);
// HttpResponse httpResponse = httpClient.httpPost(httpRequest);
// if (httpResponse != null && httpResponse.isSuccess()) {
// WcsApiResponse<WcsPickTask> response = new WcsApiResponse<>();
// response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
// return response;
// }
// return WcsApiResponse.error("请求未获得响应信息。", null);
// }
@Override
public WcsApiResponse<WcsPickTask> sendPickTask(WcsPickTaskRequest request) {
final long startNs = System.nanoTime();
try {
// 设置http请求
HttpRequest httpRequest = HttpRequest.postInstanceOf(appCommon.getConfigByKey(AppConfigKeyEnums.WCS_PICK_TASK_URL.getKey()), request);
httpRequest.setTimeout(30000);
HttpResponse httpResponse = httpClient.httpPost(httpRequest);
final long durationMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
// 记录请求日志
log.info("[WCS拣选任务调用] 接口={}, 耗时={}ms",
appCommon.getConfigByKey(AppConfigKeyEnums.WCS_PICK_TASK_URL.getKey()),
durationMs);
// 慢请求报警阈值按需调整
if (durationMs > 500) {
log.warn("慢请求告警: 调用wcs系统拣选任务接口{}耗时{}ms",
appCommon.getConfigByKey(AppConfigKeyEnums.WCS_PICK_TASK_URL.getKey()),
durationMs);
}
if (httpResponse != null && httpResponse.isSuccess()) {
WcsApiResponse<WcsPickTask> response = new WcsApiResponse<>();
response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class));
return response;
}
return WcsApiResponse.error("请求未获得响应信息。", null);
} catch (Exception e) {
final long durationMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
log.error("[WCS拣选任务调用] 接口={} 异常, 耗时={}ms, 错误信息={}",
appCommon.getConfigByKey(AppConfigKeyEnums.WCS_PICK_TASK_URL.getKey()),
durationMs,
e.getMessage(), e);
throw e;
}
}
/**
* 发送释放载具请求

View File

@ -257,7 +257,10 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
.set(TAppStock::getLocationId, "")
.eq(TAppStock::getVehicleId, targetPickTask.getVehicleId())
.eq(TAppStock::getStockStatus, WmsStockStatusEnums.OUTING.getCode()));
.eq(TAppStock::getStockStatus, WmsStockStatusEnums.OUTING.getCode())
);
// 更新当前载具到达当前点位的拣选任务为已到达
updateVehicleArriveStatus(targetPickTask);
}
// 更新拣选任务信息添加拣选任务记录信息
pickRecords.add(new TAppPickTaskBak(
@ -270,10 +273,9 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
targetPickTask.getArriveTime(),
LocalDateTime.now()
));
log.info("保存拣选任务记录:{}", pickRecords);
try {
appPickTaskBakService.saveBatch(pickRecords);
// 更新当前载具到达当前点位的拣选任务为已到达
updateVehicleArriveStatus(targetPickTask);
// 删除当前载具在当前站台的拣选任务
// appPickTaskService.remove(new LambdaQueryWrapper<TAppPickTask>()
// .eq(TAppPickTask::getVehicleId, targetPickTask.getVehicleId())
@ -316,7 +318,7 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
TAppPickTask waitPickTask = appPickTaskService.getOne(queryWrapper);
if (waitPickTask == null) {
log.warn("没有找到符合条件的 WAIT 状态任务。载具号: {}", targetPickTask.getVehicleId());
log.error("没有找到符合条件的 WAIT 状态任务。载具号: {}", targetPickTask.getVehicleId());
return;
}
// 更新当前载具到达当前点位的拣选任务为已到达
@ -457,19 +459,37 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
// 计划拣选数量
int planPickQty = pickPlan.getPlanPickQty();
// 先查询对应的工作存不存在
TAppOuts thisOuts = appOutsService.getById(pickPlan.getWorkIndex());
// 根据plan的is_empty决定查询条件如果是1根据work_index查询如果是0根据plan_id查询
List<TAppOuts> thisOuts = new ArrayList<>();
if (pickPlan.getIsEmpty() == 1){
TAppOuts outs = appOutsService.getById(pickPlan.getWorkIndex());
if (outs != null) {
thisOuts.add(outs);
}
} else if (pickPlan.getIsEmpty() == 0) {
thisOuts = appOutsService.list(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getPickPlanId, pickPlan.getPlanId())
);
} else {
log.info("is_empty is not 0 or 1");
return null;
}
// 判断这条工作还存在否
if (thisOuts == null) {
if (thisOuts == null || thisOuts.isEmpty()) {
needRemovePlans.add(pickPlan);
continue;
}
// 统计剩余需求量
int totalPickNum = thisOuts.stream().mapToInt(TAppOuts::getPickNum).sum();
int totalNeedNum = thisOuts.stream().mapToInt(TAppOuts::getNeedNum).sum();
// 判断有没有需求
if (thisOuts.getPickNum() >= thisOuts.getNeedNum()) {
if (totalPickNum >= totalNeedNum) {
needRemovePlans.add(pickPlan);
continue;
}
// 剩余需求量
int remainNeedNum = thisOuts.getNeedNum() - thisOuts.getPickNum();
int remainNeedNum = totalNeedNum - totalPickNum;
if (remainNeedNum < planPickQty) {
// 需求不足将计划拣选数量更新成实际需求数量
planPickQty = remainNeedNum;
@ -477,7 +497,7 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
// 查询这个箱子上库存是否足够
List<TAppStock> stockList = appStockService.list(new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getVehicleId, thisPickTask.getVehicleId())
.eq(TAppStock::getGoodsId, thisOuts.getGoodsId())
.eq(TAppStock::getGoodsId, thisOuts.getFirst().getGoodsId())
.gt(TAppStock::getRealNum, 0).orderByAsc(TAppStock::getFirstInTime));
if (stockList == null || stockList.isEmpty()) {
needRemovePlans.add(pickPlan);
@ -491,14 +511,16 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
}
// 命中开始设置返回数据
TaskConfirmEntity taskConfirmVo = new TaskConfirmEntity(
thisOuts.getTaskId(),
thisOuts.getOutType(),
thisOuts.getGoodsId(),
thisOuts.getNeedNum(),
thisOuts.getFirst().getTaskId(),//
thisOuts.getFirst().getOutType(),
thisOuts.getFirst().getGoodsId(),
totalNeedNum,
remainNeedNum,
planPickQty,
planPickQty,
null
null,
thisOuts.size(),
pickPlan.getIsEmpty()
);
StockConfirmEntity stockConfirmVo = new StockConfirmEntity(
pickPlan.getPlanId(),
@ -509,12 +531,11 @@ public class ConveyTaskServiceImpl implements IConveyTaskService {
0,
"ASRS",
stockDataService.getWarningQty(),
thisOuts.getWorkOrder(),
thisOuts.getSpecialStock() ,
thisOuts.getBatchNo(),
thisOuts.getSpecialStockNo(),
thisOuts.getSpecialStockItemNo()
thisOuts.getFirst().getWorkOrder(),
thisOuts.getFirst().getSpecialStock() ,
thisOuts.getFirst().getBatchNo(),
thisOuts.getFirst().getSpecialStockNo(),
thisOuts.getFirst().getSpecialStockItemNo()
);
resultVo = new TaskConfirmVo(thisPickTask.getPickStand(),false,taskConfirmVo, stockConfirmVo);

View File

@ -10,6 +10,7 @@ import com.wms_main.model.dto.request.ewm.SendWarehouseInCompletedRequest;
import com.wms_main.model.dto.response.ewm.EwmApiBackResponse;
import com.wms_main.model.po.*;
import com.wms_main.repository.utils.ConvertUtils;
import com.wms_main.repository.utils.DbTransUtils;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.api.IEwmApiService;
@ -80,7 +81,7 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
private final ITempEwmInboundDataService tempEwmInboundDataService;
private final IEwmApiService ewmApiService;
private final DbTransUtils dbTransUtils;// 数据库事务工具
/**
* 存WcsTask表
* 更新WmsTask表
@ -370,7 +371,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
* @param stackerInTasks 已完成的入库任务
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void finishStackerInTasks(List<TAppTask> stackerInTasks) {
// 入库任务完成需要做以下几件事情
// 1. 生成库存如果是已有库存则更新库存状态数量库位这些信息
@ -518,12 +518,14 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
thisVehicle.setLastInTime(LocalDateTime.now());
thisVehicle.setLocationId(thisVehicleInTasks.getFirst().getDestination());
}
final TAppVehicle finalThisVehicle = thisVehicle;
boolean doTransResult = dbTransUtils.useTran(() -> {
// 保存载具信息
appVehicleService.saveOrUpdate(thisVehicle);
appVehicleService.saveOrUpdate(finalThisVehicle);
// 将目标库位的工作状态设置为未工作
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
.set(TAppLocation::getIsWorking, 0)
.eq(TAppLocation::getLocationId, thisVehicle.getLocationId())
.eq(TAppLocation::getLocationId, finalThisVehicle.getLocationId())
);
// 需要更新下当前载具下的库存其他信息
appStockService.update(new LambdaUpdateWrapper<TAppStock>()
@ -556,7 +558,7 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
if(!needDeleteTempIds.isEmpty()){
tempEwmInboundDataService.removeByIds(needDeleteTempIds);
}
if(!thisVehicleInTasks.getFirst().getTaskId().startsWith("BACK_")){
if(!Objects.equals(thisVehicleInTasks.getFirst().getGoodsId(), AppConstant.EMPTY_GOODS_ID)){
// 回告ewm系统入库完成
SendWarehouseInCompletedRequest request = new SendWarehouseInCompletedRequest();
request.setContainerNo(vehicleId);
@ -575,7 +577,7 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
0,
9,
vehicleId,
emptyVehicle.getLocationId(),
thisVehicleInTasks.getFirst().getDestination(),
null,
null,
LocalDateTime.now(),
@ -583,16 +585,20 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
AppConstant.EMPTY_GOODS_ID,
0,
0,
appOuts.getUserName(),
"",
appOuts.getDestination(),
"EWM接口异常回退",
"P21",
""
);
appTaskService.save(outTask);
}else {
log.info("调用EWM系统接口成功请求参数: {}", request);
}
}
});
if (!doTransResult) {
log.error("执行出库单,数据库事务失败。");
}
}
}
@ -906,29 +912,53 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
.eq(TAppTask::getVehicleId, vehicleId));
continue;
}
// 释放当前库位
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
.set(TAppLocation::getVehicleId, "")
.set(TAppLocation::getIsWorking, 0)
.eq(TAppLocation::getLocationId, thisVehicle.getLocationId())
.eq(TAppLocation::getVehicleId, vehicleId));
// 更新载具信息
thisVehicle.setVehicleStatus(WmsVehicleStatusEnums.OUT.getCode());
thisVehicle.setLocationId("");
appVehicleService.updateById(thisVehicle);
// 检查是否是EWM回退任务
List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
boolean isEwmRollback = thisVehicleOutTasks.stream()
.anyMatch(task -> "EWM接口异常回退".equals(task.getRemark()));
final TAppVehicle finalThisVehicle = thisVehicle;
boolean doTransResult = dbTransUtils.useTran(() -> {
if (isEwmRollback) {
// 如果是EWM回退任务完全删除库存
appStockService.remove(new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getVehicleId, vehicleId));
} else {
// 更新当前载具对应的所有库存的状态为已出库
appStockService.update(new LambdaUpdateWrapper<TAppStock>()
.set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
.set(TAppStock::getLocationId, "")
.eq(TAppStock::getVehicleId, vehicleId));
// 释放当前载具对应的拣选任务
appPickTaskService.update(new LambdaUpdateWrapper<TAppPickTask>()
.set(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.WAIT.getCode())
.eq(TAppPickTask::getVehicleId, vehicleId)
.eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.TEMP.getCode()));
}
// 释放当前库位
appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
.set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode())
.set(TAppLocation::getVehicleId, "")
.set(TAppLocation::getIsWorking, 0)
.eq(TAppLocation::getLocationId, finalThisVehicle.getLocationId())
.eq(TAppLocation::getVehicleId, vehicleId));
// 更新载具信息
finalThisVehicle.setVehicleStatus(WmsVehicleStatusEnums.OUT.getCode());
finalThisVehicle.setLocationId("");
appVehicleService.updateById(finalThisVehicle);
// // 更新当前载具对应的所有库存的状态为已出库
// appStockService.update(new LambdaUpdateWrapper<TAppStock>()
// .set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
// .set(TAppStock::getLocationId, "")
// .eq(TAppStock::getVehicleId, vehicleId));
// 释放当前载具对应的拣选任务
// appPickTaskService.update(new LambdaUpdateWrapper<TAppPickTask>()
// .set(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.WAIT.getCode())
// .eq(TAppPickTask::getVehicleId, vehicleId)
// .eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.TEMP.getCode()));
// 当前载具的任务列表
List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
//List<TAppTask> thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId);
if (!thisVehicleOutTasks.isEmpty()) {
// 存储出库记录
List<TAppTaskBak> stockOutRecordList = thisVehicleOutTasks.stream()
@ -958,6 +988,11 @@ public class StackerTaskServiceImpl implements IStackerTaskService {
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.OUT.getCode())
.in(TAppTask::getTaskId, thisVehicleOutTasks.stream().map(TAppTask::getTaskId).toList()));
}
});
if (!doTransResult) {
log.error("执行出库任务完成处理,数据库事务失败。");
}
}
}
}

View File

@ -112,23 +112,24 @@ public class StockDataServiceImpl implements IStockDataService {
if (!removeStocks.isEmpty()) {
appStockService.removeBatchByIds(removeStocks.stream().map(TAppStock::getStockId).toList());
}
// 查询对应的库存信息
List<TAppStock> stockLists = appStockService.list(new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getVehicleId, stockConfirm.getVehicleId())
.eq(TAppStock::getGoodsId, stockConfirm.getGoodsId())
.gt(TAppStock::getRemainNum, 0)
);
if (stockLists == null || stockLists.isEmpty()){
// 回告EWM系统
SendEwmVehicleForInRequest request = new SendEwmVehicleForInRequest();
request.setContainerNo(stockConfirm.getVehicleId());
EwmApiBackResponse ewmApiBackResponse = ewmApiService.sendContainerEmpty(request);
if (!Objects.equals(ewmApiBackResponse.getState(), "successful")) {
log.error("容器置空调用EWM系统接口异常请求参数: {}", request);
}else {
log.info("容器置空调用EWM系统接口成功请求参数: {}", request);
}
}
// // 查询对应的库存信息
// List<TAppStock> stockLists = appStockService.list(new LambdaQueryWrapper<TAppStock>()
// .eq(TAppStock::getVehicleId, stockConfirm.getVehicleId())
// .eq(TAppStock::getGoodsId, stockConfirm.getGoodsId())
// .gt(TAppStock::getRemainNum, 0)
// );
// if (stockLists == null || stockLists.isEmpty()){
// reason = "移除载具";
//// // 回告EWM系统
//// SendEwmVehicleForInRequest request = new SendEwmVehicleForInRequest();
//// request.setContainerNo(stockConfirm.getVehicleId());
//// EwmApiBackResponse ewmApiBackResponse = ewmApiService.sendContainerEmpty(request);
//// if (!Objects.equals(ewmApiBackResponse.getState(), "successful")) {
//// log.error("容器置空调用EWM系统接口异常请求参数: {}", request);
//// }else {
//// log.info("容器置空调用EWM系统接口成功请求参数: {}", request);
//// }
// }
// 更新库存数量
if (!updateStocks.isEmpty()) {
appStockService.updateBatchById(updateStocks);

View File

@ -5,6 +5,7 @@ import com.wms_main.model.po.TAppPickTask;
import com.wms_main.model.po.TAppTask;
import java.util.List;
import java.util.Map;
public interface IDataControllerService {
@ -40,4 +41,15 @@ public interface IDataControllerService {
* @return 拣选任务信息
*/
List<TAppPickTask> getPickTaskDataP3(int pageNum, int pageSize);
List<Map<String, Object>> queryRecentTask();
List<Map<String, Object>> queryStockDetail(String locationId);
/**
* 查询运行中的任务
* @return 运行中的任务列表
*/
List<Map<String, Object>> queryRunningTask();
}

View File

@ -40,6 +40,14 @@ public interface ITaskControllerService {
*/
BaseWmsApiResponse requireStockOut(StockOutRequest stockOutRequest);
/**
* 出库空箱
* @param stockOutRequest 请求信息
* @return 处理结果
*/
BaseWmsApiResponse requireStockOutEmpty(StockOutRequest stockOutRequest);
/**
* 入库用出库请求
* @param voiRequest 请求信息

View File

@ -5,6 +5,7 @@ import com.wms_main.model.dto.query.OutsQuery;
import com.wms_main.model.dto.query.PickTaskQuery;
import com.wms_main.model.dto.query.WmsTaskQuery;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.po.TAppPickTask;
import com.wms_main.model.vo.wms.*;
/**
@ -46,10 +47,26 @@ public interface ITaskQueryControllerService {
*/
WmsApiResponse<PageVo<OutsVo>> queryOutsByPage(OutsQuery outsQuery);
WmsApiResponse<String> upOutsType(OutsVo outsVo);
/**
* 查询盘点相关信息
* @param inventoryQuery 查询参数
* @return 查询结果---分页
*/
WmsApiResponse<PageVo<InventoryRecordVo>> queryInventoryRecordByPage(InventoryQuery inventoryQuery);
WmsApiResponse<String> editDate(OutsVo outsVo);
/**
* 更新出库单信息
*
* @param appTask 出库单信息
* @return 更新结果
*/
WmsApiResponse<String> updateOutsInfo(TAppPickTask appTask);
}

View File

@ -1,7 +1,53 @@
package com.wms_main.service.controller;
import com.wms_main.model.dto.query.UserQuery;
import com.wms_main.model.dto.query.UserUpdateRequest;
import com.wms_main.model.dto.response.wms.BaseWmsApiResponse;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.vo.wms.PageVo;
import com.wms_main.model.vo.wms.UserVo;
/**
* 用户控制类服务
*/
public interface IUserControllerService {
/**
* 查询用户列表
* @param userQuery 查询参数
* @return 查询结果
*/
WmsApiResponse<PageVo<UserVo>> getUserList(UserQuery userQuery);
/**
* 新增用户信息
* @param userUpdateRequest 新增用户信息请求
* @return 新增结果
*/
BaseWmsApiResponse addUserInfo(UserUpdateRequest userUpdateRequest);
/**
* 删除用户信息
* @param userUpdateRequest 删除用户信息请求
* @return 删除结果
*/
BaseWmsApiResponse deleteUserInfo(UserUpdateRequest userUpdateRequest);
/**
* 修改用户信息
* @param userUpdateRequest 修改用户信息请求
* @return 修改结果
*/
BaseWmsApiResponse updateUserInfo(UserUpdateRequest userUpdateRequest);
/**
* 修改用户密码
* @param userUpdateRequest 密码修改参数
* @return 修改结果
*/
BaseWmsApiResponse changePassword(UserUpdateRequest userUpdateRequest);
}

View File

@ -1,19 +1,20 @@
package com.wms_main.service.controller.serviceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms_main.dao.impl.TAppOutsServiceImpl;
import com.wms_main.dao.impl.TAppPickTaskServiceImpl;
import com.wms_main.dao.impl.TAppTaskServiceImpl;
import com.wms_main.model.po.TAppOuts;
import com.wms_main.model.po.TAppPickTask;
import com.wms_main.dao.impl.*;
import com.wms_main.model.po.*;
import com.wms_main.service.controller.IDataControllerService;
import com.wms_main.model.po.TAppTask;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 数据控制器服务实现类
@ -25,6 +26,8 @@ public class DataControllerServiceImpl implements IDataControllerService {
private final TAppTaskServiceImpl tAppTaskService;
private final TAppOutsServiceImpl tAppOutsService;
private final TAppPickTaskServiceImpl tAppPickTaskService;
private final TAppTaskBakServiceImpl tAppTaskBakService;
private final TAppStockServiceImpl tAppStockService;
/**
* 获取任务类型为1的任务数据
@ -91,4 +94,136 @@ public class DataControllerServiceImpl implements IDataControllerService {
.orderByDesc(TAppPickTask::getPickStatus);;
return tAppPickTaskService.page(new Page<>(pageNum, pageSize), queryWrapper).getRecords();
}
@Override
public List<Map<String, Object>> queryRecentTask() {
List<Map<String, Object>> result = new ArrayList<>();
// 获取最近7天的日期
List<LocalDate> recentDays = new ArrayList<>();
for (int i = 6; i >= 0; i--) {
recentDays.add(LocalDate.now().minusDays(i));
}
// 查询最近7天的数据
for (LocalDate date : recentDays) {
LocalDateTime startOfDay = date.atStartOfDay();
LocalDateTime endOfDay = date.atTime(23, 59, 59);
LambdaQueryWrapper<TAppTaskBak> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.between(TAppTaskBak::getCreateTime, startOfDay, endOfDay);
List<TAppTaskBak> tasks = tAppTaskBakService.list(queryWrapper);
// 统计各类任务数量
int inTaskCount = 0;
int outTaskCount = 0;
int moveTaskCount = 0;
for (TAppTaskBak task : tasks) {
switch (task.getTaskType()) {
case 1: // 入库任务
inTaskCount++;
break;
case 2: // 出库任务
outTaskCount++;
break;
case 3: // 移库任务
moveTaskCount++;
break;
}
}
Map<String, Object> item = new HashMap<>();
item.put("dataDate", date.toString());
item.put("inTaskCount", inTaskCount);
item.put("outTaskCount", outTaskCount);
item.put("moveTaskCount", moveTaskCount);
result.add(item);
}
return result;
}
/**
* 根据库位ID查询库存详情
* @param locationId 库位ID
* @return 库存详情列表
*/
@Override
public List<Map<String, Object>> queryStockDetail(String locationId) {
List<Map<String, Object>> result = new ArrayList<>();
// 1. 构造查询条件
LambdaQueryWrapper<TAppStock> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(TAppStock::getLocationId, locationId);
// 2. 查询库存数据
List<TAppStock> stockList = tAppStockService.list(queryWrapper);
// 3. 转换为 Map 格式返回
for (TAppStock stock : stockList) {
Map<String, Object> item = new HashMap<>();
item.put("goodsId", stock.getGoodsId()); // 物料编号
item.put("goodsName", stock.getGoodsDesc()); // 物料名称
item.put("goodsNum", stock.getRealNum()); // 物料数量
item.put("wareDate", stock.getFirstInTime()); // 库上架时间
item.put("specialStock", stock.getSpecialStock()); // 质量kg
item.put("specialStockNo", stock.getSpecialStockNo()); // 产期
item.put("specialStockItemNo", stock.getSpecialStockItemNo()); // 到期期
item.put("batchId", stock.getBatchNo()); // 批次号
item.put("subpool", stock.getLocationId()); // 库编码
result.add(item);
}
return result;
}
@Override
public List<Map<String, Object>> queryRunningTask() {
List<Map<String, Object>> result = new ArrayList<>();
// 1. 查询运行中的任务数据优先从 TAppTask 表中查询最多10条
LambdaQueryWrapper<TAppTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.last("LIMIT 10");
List<TAppTask> taskList = tAppTaskService.list(queryWrapper);
// 2. 添加实时任务到结果中
for (TAppTask task : taskList) {
Map<String, Object> item = new HashMap<>();
item.put("goodsId", task.getGoodsId()); // 物品编号
item.put("goodsName", task.getGoodsDesc()); // 物品名称
item.put("goodsNum", task.getOpNum()); // 物品数量
item.put("origin", task.getOrigin()); // 搬运起点
item.put("taskType", task.getTaskType()); // 任务类型
item.put("destination", task.getDestination()); // 搬运终点
result.add(item);
}
// 3. 如果实时任务不足10条则从 TAppTaskBak 表中查询最近的任务记录来补足
if (result.size() < 10) {
int remainingCount = 10 - result.size();
LambdaQueryWrapper<TAppTaskBak> bakQueryWrapper = new LambdaQueryWrapper<>();
bakQueryWrapper.orderByDesc(TAppTaskBak::getCreateTime);
bakQueryWrapper.last("LIMIT " + remainingCount);
List<TAppTaskBak> bakTaskList = tAppTaskBakService.list(bakQueryWrapper);
for (TAppTaskBak task : bakTaskList) {
Map<String, Object> item = new HashMap<>();
item.put("goodsId", task.getGoodsId()); // 物品编号
item.put("goodsName", task.getGoodsDesc()); // 物品名称
item.put("goodsNum", task.getOpNum()); // 物品数量
item.put("origin", task.getOrigin()); // 搬运起点
item.put("taskType", task.getTaskType()); // 任务类型
item.put("destination", task.getDestination()); // 搬运终点
result.add(item);
}
}
return result;
}
}

View File

@ -102,7 +102,7 @@ public class LoginControllerServiceImpl implements ILoginControllerService {
return Collections.emptyList();
}
List<TSysMenu> menuPoList;
if (roleId.equals(AppConstant.ADMIN_ID)) {
if (roleId.equals(AppConstant.ADMIN_ID) || roleId.equals("2")) {
// 管理员获得所得菜单权限
menuPoList = menuService.list();
} else {

View File

@ -32,6 +32,7 @@ import com.wms_main.model.vo.wms.InventoryConfirmVo;
import com.wms_main.model.vo.wms.TaskConfirmVo;
import com.wms_main.model.vo.wms.WorkConfirmVo;
import com.wms_main.repository.utils.ConvertUtils;
import com.wms_main.repository.utils.DbTransUtils;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.api.IEwmApiService;
@ -42,13 +43,12 @@ import com.wms_main.service.controller.ITaskControllerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 任务控制类 服务实现
@ -81,7 +81,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
private final ITempEwmInboundDataService tempEwmInboundDataService;
private final ITAppStockCompareService appStockCompareService;
private final DbTransUtils dbTransUtils;// 数据库事务工具
/**
* 实现
@ -243,6 +243,82 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
return BaseWmsApiResponse.success("生成入库任务成功。");
}
/**
* 请求出库空箱---实现
*
* @param stockOutRequest 请求信息
* @return 处理结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public BaseWmsApiResponse requireStockOutEmpty(StockOutRequest stockOutRequest) {
// 保存
if (stockOutRequest == null || stockOutRequest.getOutType() == null || stockOutRequest.getNeedNum() == null
|| stockOutRequest.getNeedNum() <= 0 || StringUtils.isEmpty(stockOutRequest.getDestination())) {
return BaseWmsApiResponse.error("请求参数不完整。");
}
// 判断终点对不对
if (!stockOutRequest.getDestination().equals("P4")) {
return BaseWmsApiResponse.error("请在入库端电脑操作!");
}
// 针对不同的出库类型验证请求
if (stockOutRequest.getOutType().equals(WmsOutTypeEnums.EMPTY.getCode())) {
List<TAppVehicle> emptyVehicles;
if (stockOutRequest.getVehicleId() == null || stockOutRequest.getVehicleId().isEmpty()) {
// 判断空载具数量够不够
emptyVehicles = appVehicleService.list(new LambdaQueryWrapper<TAppVehicle>()
.eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
.eq(TAppVehicle::getIsEmpty, 1)
);
}else {
emptyVehicles = appVehicleService.list(new LambdaQueryWrapper<TAppVehicle>()
.eq(TAppVehicle::getVehicleId, stockOutRequest.getVehicleId())
.eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
.eq(TAppVehicle::getIsEmpty, 1)
);
}
if (emptyVehicles == null || emptyVehicles.isEmpty()) {
return BaseWmsApiResponse.error("请求错误:库内无可用空箱。");
}
if (emptyVehicles.size() < stockOutRequest.getNeedNum()) {
return BaseWmsApiResponse.error("请求错误:库内空箱数量" + emptyVehicles.size() + ",小于请求数量" + stockOutRequest.getNeedNum() + "");
}
} else {
return BaseWmsApiResponse.error("请求错误:未知的出库类型。");
}
// 添加任务
TAppOuts task = new TAppOuts(
UUIDUtils.getNewUUID(),
stockOutRequest.getGoodsId(),
stockOutRequest.getVehicleId(),
stockOutRequest.getNeedNum(),
0,
0,
stockOutRequest.getOutType(),
stockOutRequest.getDestination(),
stockOutRequest.getUserName(),
stockOutRequest.getReason(),
LocalDateTime.now(),
stockOutRequest.getWorkOrder(),
null,
null,
null,
null,
null,
null,
null,
null,
null,
new Date(),
null,
-2
);
appOutsService.save(task);
return BaseWmsApiResponse.success("添加出库请求成功。");
}
/**
* 请求出库---实现
*
@ -407,7 +483,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
stockOutRequest.getSpecialStockItemNo(),
stockOutRequest.getBatchNo(),
null,
null,null, null,new Date()
null,null, null,new Date(),"",-1
);
appOutsService.save(task);
return BaseWmsApiResponse.success("添加出库请求成功。");
@ -420,6 +496,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
* @return 处理结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public EwmApiBackResponse ewmRequestOutTask(EwmOutTaskRequest ewmOutTaskRequest) {
// 保存
if (ewmOutTaskRequest == null || ewmOutTaskRequest.getTaskDetailInfo() == null
@ -438,7 +515,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// .eq(TAppOuts::getWorkOrder, ewmOutTaskRequest.getWaveNo())
// );
//List<TAppOuts> appOuts = new ArrayList<>();
List<TAppOuts> appOuts = new ArrayList<>();
for (EwmOutTaskRequest.TaskDetailInfo task : ewmOutTaskRequest.getTaskDetailInfo()){
// // 判断有没有出库数据相同的如果有直接在已有的outs上做累加
@ -464,22 +541,29 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
return EwmApiBackResponse.error("请求错误:紧急出库必须输入有效数量。");
}
String targetDestination;
// 判断
List<TAppOuts> ret = appOutsService.list(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getOrderNo, task.getOrderNo())
);
//查询是否有orderNo相同的数据
if(!ret.isEmpty()){
targetDestination = ret.getFirst().getDestination();
}else {
// 使用Stream API直接找出任务数最少的站台
targetDestination = pickStands.stream()
.min(Comparator.comparingInt(stand ->
Math.toIntExact(appOutsService.count(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getDestination, stand.getStandId())))))
.map(TAppStand::getStandId)
.orElse(null);
}
// 方法一基于任务数最小的站台
// // 判断
// List<TAppOuts> ret = appOutsService.list(new LambdaQueryWrapper<TAppOuts>()
// .eq(TAppOuts::getOrderNo, task.getOrderNo())
// );
// //查询是否有orderNo相同的数据
// if(!ret.isEmpty()){
// targetDestination = ret.getFirst().getDestination();
// }else {
// // 使用Stream API直接找出任务数最少的站台
// targetDestination = pickStands.stream()
// .min(Comparator.comparingInt(stand ->
// Math.toIntExact(appOutsService.count(new LambdaQueryWrapper<TAppOuts>()
// .eq(TAppOuts::getDestination, stand.getStandId())))))
// .map(TAppStand::getStandId)
// .orElse(null);
// }
// 方法二基于当前时间戳的轮询分配
int standIndex = (int) (System.currentTimeMillis() % pickStands.size());
targetDestination = pickStands.get(standIndex).getStandId();
if (targetDestination == null) {
return EwmApiBackResponse.error("无法找到合适的站台进行任务分配。");
}
@ -571,11 +655,12 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
ewmOutTaskRequest.getWaveNo(),
task.getSkuUnit(),
task.getSecondPickingKey(),
ewmOutTaskRequest.getPickingDate()
ewmOutTaskRequest.getPickingDate(),"",-1
);
//appOuts.add(outs);
appOutsService.save(outs);
appOuts.add(outs);
//appOutsService.save(outs);
}
appOutsService.saveBatch(appOuts);
return EwmApiBackResponse.success("添加出库请求成功。");
}
@ -636,7 +721,6 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// 构造唯一键
String key = String.join("|",
matNo != null ? matNo : "",
matDesc != null ? matDesc : "",
specialStock != null ? specialStock : "",
specialStockNo != null ? specialStockNo : "",
specialStockItemNo != null ? specialStockItemNo : "",
@ -653,7 +737,6 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// 创建新的BinStock记录
EwmApiStockResponse.BinStock binStock = new EwmApiStockResponse.BinStock();
binStock.setMatNo(matNo);
binStock.setMatDesc(matDesc);
binStock.setTotalQuantity((double) localStock.getRealNum());
binStock.setSpecialStock(specialStock);
binStock.setSpecialStockNo(specialStockNo);
@ -885,7 +968,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
null,
null,null,
null,
null
null,"",-1
));
}
@ -1000,7 +1083,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
wcsVehicleInRequest.getVehicleNo(),
response != null ? response.getMessage() : "响应为空");
}
saveEwmDataToTempTable(response, wcsVehicleInRequest.getVehicleNo());
//saveEwmDataToTempTable(response, wcsVehicleInRequest.getVehicleNo());
return response;
} catch (Exception e) {
// 记录错误日志
@ -1020,37 +1103,21 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
return;
}
try {
// 先查询要删除的数据
List<TAppTempEwmInboundData> existingData = tempEwmInboundDataService.list(
new LambdaQueryWrapper<TAppTempEwmInboundData>()
boolean deletedCount = tempEwmInboundDataService.remove(new LambdaQueryWrapper<TAppTempEwmInboundData>()
.eq(TAppTempEwmInboundData::getContainerNo, vehicleNo)
.eq(TAppTempEwmInboundData::getProcessStatus, 0)
);
log.debug("删除前查询到 {} 条待处理数据,载具号: {}", existingData.size(), vehicleNo);
.eq(TAppTempEwmInboundData::getProcessStatus, 0));
// 先删除该载具号之前可能存在的未处理数据
boolean removeResult = tempEwmInboundDataService.remove(new LambdaQueryWrapper<TAppTempEwmInboundData>()
.eq(TAppTempEwmInboundData::getContainerNo, vehicleNo));
log.info("删除操作结果: {},载具号: {},删除条件: containerNo={}, processStatus=0",
removeResult, vehicleNo, vehicleNo);
// 再次查询确认是否删除成功
List<TAppTempEwmInboundData> afterDeleteData = tempEwmInboundDataService.list(
new LambdaQueryWrapper<TAppTempEwmInboundData>()
.eq(TAppTempEwmInboundData::getContainerNo, vehicleNo)
.eq(TAppTempEwmInboundData::getProcessStatus, 0)
);
log.debug("删除后剩余 {} 条待处理数据,载具号: {}", afterDeleteData.size(), vehicleNo);
log.info("删除旧的EWM临时数据: {} 条,载具号: {}", deletedCount, vehicleNo);
// 转换并保存数据
List<TAppTempEwmInboundData> dataList = new ArrayList<>();
for (TaskDetailInfo taskDetail : response.getContent().getTaskDetailInfo()) {
EwmApiLocalResponse.Content content = response.getContent();
for (TaskDetailInfo taskDetail : content.getTaskDetailInfo()) {
TAppTempEwmInboundData data = new TAppTempEwmInboundData();
data.setId(UUIDUtils.getNewUUID()); // 不要使用固定值"123"
data.setBillNo(response.getContent().getBillNo());
data.setBillType(response.getContent().getBillType());
data.setContainerNo(response.getContent().getContainerNo() != null ? response.getContent().getContainerNo() : vehicleNo);
data.setBillNo(content.getBillNo());
data.setBillType(content.getBillType());
data.setContainerNo(content.getContainerNo() != null ? content.getContainerNo() : vehicleNo);
data.setTaskNo(taskDetail.getTaskNo());
data.setOrderNo(taskDetail.getOrderNo());
data.setOrderType(taskDetail.getOrderType());
@ -1133,13 +1200,15 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
}
// 更新临时表中对应记录的状态为已处理
boolean updateResult = tempEwmInboundDataService.update(
new LambdaUpdateWrapper<TAppTempEwmInboundData>()
.set(TAppTempEwmInboundData::getProcessStatus, 1) // 已处理状态
LambdaUpdateWrapper<TAppTempEwmInboundData> updateWrapper = new LambdaUpdateWrapper<TAppTempEwmInboundData>()
.set(TAppTempEwmInboundData::getProcessStatus, 1)
.set(TAppTempEwmInboundData::getUpdateTime, LocalDateTime.now())
.in(TAppTempEwmInboundData::getContainerNo, wcsVehicleInRequest.getVehicleNo())
);
.eq(TAppTempEwmInboundData::getContainerNo, wcsVehicleInRequest.getVehicleNo())
.eq(TAppTempEwmInboundData::getProcessStatus, 0);
boolean updateResult = tempEwmInboundDataService.update(updateWrapper);
log.info("更新临时数据状态完成,载具号: {},更新记录数: {}", wcsVehicleInRequest.getVehicleNo(), updateResult);
if (updateResult) {
log.info("成功更新临时数据状态为已处理,载具号: {}", wcsVehicleInRequest.getVehicleNo());
@ -1167,35 +1236,78 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) {
return WcsApiResponse.error("请求缺少关键信息:载具号。", null);
}
// // 0. 验证任务是否已经存在
// List<TAppTask> wmsTaskIsExist = appWmsTaskService.list(
// new LambdaQueryWrapper<TAppTask>()
// .eq(TAppTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
// .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
// );
// // 1. 验证WCS任务是否已经存在
// List<TAppWcsTask> wcsTaskIsExist = appWcsTaskService.list(
// new LambdaQueryWrapper<TAppWcsTask>()
// .eq(TAppWcsTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
// .eq(TAppWcsTask::getWcsTaskType, WmsTaskTypeEnums.IN.getCode())
// );
// if (!wmsTaskIsExist.isEmpty() && !wcsTaskIsExist.isEmpty()){
// appWcsTaskService.update(new LambdaUpdateWrapper<TAppWcsTask>()
// .set(TAppWcsTask::getWcsTaskStatus, 0)
// .eq(TAppWcsTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
// .eq(TAppWcsTask::getWcsTaskType, WcsStackerTaskTypeEnums.IN.getCode()));
// return WcsApiResponse.error("该载具号已经存在入库任务修改wcs状态重新下发。", null);
// }
// if (!wmsTaskIsExist.isEmpty() || !wcsTaskIsExist.isEmpty()){
// return WcsApiResponse.error("该载具号已经存在入库任务,请检查。", null);
// }
// -1. 验证载具号在check表是否有数据
List<TAppOutsCheck> outsCheckList = appOutsCheckService.list(
new LambdaQueryWrapper<TAppOutsCheck>()
.eq(TAppOutsCheck::getContainerNo, wcsVehicleInRequest.getVehicleNo()) // vehicleId 是你要查询的载具号
);
// 0. 验证任务是否已经存在
List<TAppTask> wmsTaskIsExist = appWmsTaskService.list(
new LambdaQueryWrapper<TAppTask>()
.eq(TAppTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
.eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
// 0. 验证库存信息
List<TAppStock> stockList = appStockService.list(
new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getVehicleId, wcsVehicleInRequest.getVehicleNo())
);
// 1. 验证WCS任务是否已经存在
List<TAppWcsTask> wcsTaskIsExist = appWcsTaskService.list(
new LambdaQueryWrapper<TAppWcsTask>()
.eq(TAppWcsTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
.eq(TAppWcsTask::getWcsTaskType, WmsTaskTypeEnums.IN.getCode())
);
if (!wmsTaskIsExist.isEmpty() && !wcsTaskIsExist.isEmpty()){
appWcsTaskService.update(new LambdaUpdateWrapper<TAppWcsTask>()
.set(TAppWcsTask::getWcsTaskStatus, 0)
.eq(TAppWcsTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
.eq(TAppWcsTask::getWcsTaskType, WcsStackerTaskTypeEnums.IN.getCode()));
return WcsApiResponse.error("该载具号已经存在入库任务修改wcs状态重新下发。", null);
}
if (!wmsTaskIsExist.isEmpty() || !wcsTaskIsExist.isEmpty()){
return WcsApiResponse.error("该载具号已经存在入库任务,请检查。", null);
}
// 1. 获取EWM数据
EwmApiLocalResponse response = ewmInformationBack(wcsVehicleInRequest);
if (!response.isSuccess()) {
return WcsApiResponse.error(response.getMessage(), null);
}
// 判断是否为空箱
if (response.getContent().isEmptyContainer()) {
if (!outsCheckList.isEmpty() || !stockList.isEmpty()){
return WcsApiResponse.error("该容器已作为拣选任务绑定的目标容器,请检查。", null);
}
return WcsApiResponse.success("该容器为空箱,请检查。", null);
// 创建空载具入库任务
// TAppTask task = new TAppTask(
// UUIDUtils.getNewUUID(),
// WmsTaskTypeEnums.IN.getCode(),
// WmsStackerTaskStatusEnums.TEMP.getCode(),
// 1,
// wcsVehicleInRequest.getVehicleNo(),
// wcsVehicleInRequest.getPoint(),
// null,
// null,
// LocalDateTime.now(),
// null,
// AppConstant.EMPTY_GOODS_ID,
// 0,
// 0,
// "空箱",
// "空箱入库",
// "R1",
// ""
// );
// try {
// // 保存任务
// appWmsTaskService.save(task);
// } catch (Exception e) {
// return WcsApiResponse.error("空箱入库申请失败,请检查。", null);
// }
}else{
try {
// 2. 将EWM数据保存到临时表
saveEwmDataToTempTable(response, wcsVehicleInRequest.getVehicleNo());
@ -1207,7 +1319,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
log.error("处理EWM数据异常载具号: {}", wcsVehicleInRequest.getVehicleNo(), e);
return WcsApiResponse.error("处理EWM数据失败: " + e.getMessage(), null);
}
}
// 查询该载具对应的wms任务
List<TAppTask> wmsTasks = appWmsTaskService.list(
@ -1239,25 +1351,25 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
}
// 判断是否已经分配库位
String locationId = "";
List<String> goodsIds = new ArrayList<>();
//List<String> goodsIds = new ArrayList<>();
for (TAppTask wmsTask : wmsTasks) {
if (StringUtils.isNotEmpty(wmsTask.getDestination())) {
locationId = wmsTask.getDestination();
break;
}
if (!goodsIds.contains(wmsTask.getGoodsId())) {
goodsIds.add(wmsTask.getGoodsId());
}
// if (!goodsIds.contains(wmsTask.getGoodsId())) {
// goodsIds.add(wmsTask.getGoodsId());
// }
}
if (StringUtils.isEmpty(locationId)) {
// 如果只有一个料号那么分配优先存放区域
TAppLocation locationFilter = new TAppLocation();
if (goodsIds.size() == 1) {
TAppGoods thisGoods = appCommon.getInstantGoodsByGoodsId(goodsIds.getFirst());
if (thisGoods != null && StringUtils.isNotEmpty(thisGoods.getPutArea())) {
locationFilter.setSubArea(thisGoods.getPutArea());
}
}
// TAppLocation locationFilter = new TAppLocation();
// if (goodsIds.size() == 1) {
// TAppGoods thisGoods = appCommon.getInstantGoodsByGoodsId(goodsIds.getFirst());
// if (thisGoods != null && StringUtils.isNotEmpty(thisGoods.getPutArea())) {
// locationFilter.setSubArea(thisGoods.getPutArea());
// }
// }
// 需要申请库位
TAppLocation targetLocation = stackerTaskService.requestOneLocation(null, wcsVehicleInRequest.getVehicleNo());
locationId = targetLocation.getLocationId();
@ -1333,8 +1445,6 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
* @return 响应信息
*/
@Override
//@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
public BaseWcsApiResponse boxArrive(WcsBoxArriveRequest boxArriveRequest) {
if (boxArriveRequest == null
|| StringUtils.isEmpty(boxArriveRequest.getVehicleNo())
@ -1347,6 +1457,13 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
return BaseWcsApiResponse.error("没有找到当前载具的拣选任务。");
}
if (pickTask.getPickType() == 3){
// 直接删除
appPickTaskService.remove(new LambdaQueryWrapper<TAppPickTask>()
.eq(TAppPickTask::getPickId, pickTask.getPickId()));
return BaseWcsApiResponse.success("空载具出库成功,已自动删除拣选任务。");
}
String pickStand = pickTask.getPickStand();
// 判断当前站台有没有别的已到达的拣选任务
@ -1354,17 +1471,17 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
.eq(TAppPickTask::getPickStand, boxArriveRequest.getLocation())
.eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode()));
boolean doTransResult = dbTransUtils.useTran(() -> {
// 如果有其他已到达的拣选任务将它们的状态设置为0等待状态
if (pickTaskList != null && !pickTaskList.isEmpty()) {
for (TAppPickTask otherTask : pickTaskList) {
appPickTaskService.update(new LambdaUpdateWrapper<TAppPickTask>()
.set(TAppPickTask::getPickStatus, 0) // 设置为等待状态
.set(TAppPickTask::getPickId, UUIDUtils.getNewUUID()) // 重新设置ID
.set(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.SEND.getCode()) // 设置为等待状态
.eq(TAppPickTask::getPickId, otherTask.getPickId()));
}
}
// 更新当前载具到达当前点位的拣选任务为已到达
boolean isUpdateSuccess = appPickTaskService.update(new LambdaUpdateWrapper<TAppPickTask>()
appPickTaskService.update(new LambdaUpdateWrapper<TAppPickTask>()
.set(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode())
.set(TAppPickTask::getArriveTime, LocalDateTime.now())
.set(TAppPickTask::getPickStand, boxArriveRequest.getLocation())
@ -1373,21 +1490,17 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
.ne(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.FOR_IN.getCode()));
// 更新拣选PLAN
boolean isUpdatePlanSuccess = appPickPlanService.update(new LambdaUpdateWrapper<TAppPickPlan>()
appPickPlanService.update(new LambdaUpdateWrapper<TAppPickPlan>()
.set(TAppPickPlan::getStandId, boxArriveRequest.getLocation())
.eq(TAppPickPlan::getVehicleId, boxArriveRequest.getVehicleNo())
.eq(TAppPickPlan::getStandId, pickStand)
.last("LIMIT 1"));
//boolean isUpdatePlanSuccess = updatePickPlanInNewTransaction(boxArriveRequest, pickStand);
if (isUpdateSuccess && isUpdatePlanSuccess) {
// 更新成功返回成功
return BaseWcsApiResponse.success("处理成功。");
} else {
// 更新失败返回失败
});
if (!doTransResult) {
log.error("执行出库单,数据库事务失败。");
return BaseWcsApiResponse.error("处理失败。");
}
return BaseWcsApiResponse.success("处理成功。");
}
@ -1428,7 +1541,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
* @return 获取结果
*/
@Override
//@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class)
public WmsApiResponse<List<TaskConfirmVo>> getCurrentTask(BaseWmsRequest wmsRequest) {
if (wmsRequest == null || StringUtils.isEmpty(wmsRequest.getStandId())) {
// 缺少站台号
@ -1545,32 +1658,55 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
if (pickTaskList.size() > 1) {
return BaseWmsApiResponse.error("当前站台有多个箱子到达,请检查。");
}
TAppOuts thisOut = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
if (!Objects.equals(pickTaskList.getFirst().getVehicleId(), confirmTaskRequest.getStockConfirm().getVehicleId())){
return BaseWmsApiResponse.error("当前站台载具与实际任务不一致,请刷新页面后重试。");
}
if (StringUtils.isEmpty(confirmTaskRequest.getStockConfirm().getVehicleId()) || StringUtils.isEmpty(confirmTaskRequest.getStockConfirm().getGoodsId())
|| confirmTaskRequest.getStockConfirm().getRealRemainQty() == null) {
return BaseWmsApiResponse.error("网络超时导致数据丢失,请刷新页面后重新拣选。");
}
List<TAppOuts> thisOut = new ArrayList<>();
if (confirmTaskRequest.getTaskConfirm().getIsEmpty() == 0){
thisOut = appOutsService.list(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getPickPlanId, confirmTaskRequest.getStockConfirm().getStockId())
);
} else if (confirmTaskRequest.getTaskConfirm().getIsEmpty() == 1) {
TAppOuts out = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getTaskId, confirmTaskRequest.getTaskConfirm().getTaskId()));
if (out != null){
thisOut.add(out);
}
}else {
return BaseWmsApiResponse.error("字段isEmpty获取失败请重试");
}
if (thisOut == null) {
return BaseWmsApiResponse.error("当前任务不存在或已经拣选完毕,请刷新后重试。");
}
if (thisOut.size() != confirmTaskRequest.getTaskConfirm().getTotalQty()){
return BaseWmsApiResponse.error("EWM下发新需求请刷新后重新合并");
}
// 调用EWM系统检验箱子
SendEwmCheckContainerNo request = new SendEwmCheckContainerNo();
request.setContainerNo(confirmTaskRequest.getTaskConfirm().getContainerNo());
request.setType(thisOut.getPickingType());
request.setType(thisOut.getFirst().getPickingType());
request.setFirstOrSecond(false);
request.setCheckKey(thisOut.getSecondPickingCode());
request.setCheckKey(thisOut.getFirst().getSecondPickingCode());
EwmApiBackResponse ewmResponse = ewmApiService.sendEwmCheckContainerNo(request);
// 检查 EWM 系统返回结果
if (ewmResponse == null) {
return BaseWmsApiResponse.error("EWM系统无响应请检查网络连接。");
if (Objects.equals(ewmResponse.getState(), "failed")) {
return BaseWmsApiResponse.error("调用EWM系统检验容器接口异常{}。" + ewmResponse.getMessage());
}
// 检查返回内容是否为空
if (ewmResponse.getContent() == null) {
// 根据 state 状态处理
if ("successfully".equals(ewmResponse.getState())) {
return BaseWmsApiResponse.success("操作成功,但无返回内容。");
//return BaseWmsApiResponse.success("操作成功,但无返回内容。");
log.info("EWM系统检验容器接口无返回内容。");
} else {
return BaseWmsApiResponse.error("EWM系统返回异常:" + (ewmResponse.getMessage() != null ? ewmResponse.getMessage() : "未知错误"));
return BaseWmsApiResponse.error("EWM系统检验容器接口返回异常:" + (ewmResponse.getMessage() != null ? ewmResponse.getMessage() : "未知错误"));
}
}
@ -1582,7 +1718,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// 1. 检测是否是颗粒度相同考虑 null empty
String existingSecondPickingCode = existingCheck.getSecondPickingCode();
String newSecondPickingCode = thisOut.getSecondPickingCode();
String newSecondPickingCode = thisOut.getFirst().getSecondPickingCode();
boolean isSecondPickingCodeMatch = (StringUtils.isEmpty(existingSecondPickingCode) && StringUtils.isEmpty(newSecondPickingCode))
|| Objects.equals(existingSecondPickingCode, newSecondPickingCode);
@ -1593,106 +1729,93 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// 2. 如果颗粒度一致包括都为空再检测工单号是否相同
String existingOrderNo = existingCheck.getOrderNo();
String newOrderNo = thisOut.getOrderNo();
String newOrderNo = thisOut.getFirst().getOrderNo();
boolean isOrderNoMatch = Objects.equals(existingOrderNo, newOrderNo);
if (!isOrderNoMatch) {
return BaseWmsApiResponse.error("当前目标箱号已存在其他工单号物料,请检查。");
}
}
// 将出库完成需要反馈的信息插入outsCheck表中
List<TAppOutsCheck> outsChecks = new ArrayList<>();
outsChecks.add(new TAppOutsCheck(
UUIDUtils.getNewUUID("CHECK_"),
thisOut.getWaveNo(),
confirmTaskRequest.getTaskConfirm().getTaskId(),
confirmTaskRequest.getTaskConfirm().getGoodsId(),
confirmTaskRequest.getTaskConfirm().getTotalNeed(),
confirmTaskRequest.getTaskConfirm().getRealPickQty(),
thisOut.getUnit(),
confirmTaskRequest.getTaskConfirm().getContainerNo(),
thisOut.getSecondPickingCode(),
thisOut.getOrderNo()
));
appOutsCheckService.saveBatch(outsChecks);
// 当前站台到达的拣选任务
TAppPickTask thisPickTask = pickTaskList.getFirst();
SendWarehouseOutCompletedRequest requestForCompleted = new SendWarehouseOutCompletedRequest();
if (confirmTaskRequest.getTaskConfirm() != null && StringUtils.isNotEmpty(confirmTaskRequest.getTaskConfirm().getTaskId())) {
// 更新工作信息
String updateTaskResult = updateTaskInfo(confirmTaskRequest);
String updateTaskResult = updateTaskInfo(confirmTaskRequest, requestForCompleted);
if (StringUtils.isNotEmpty(updateTaskResult)) {
return BaseWmsApiResponse.error("更新任务信息失败:" + updateTaskResult + ",请重试。");
}
}
// 更新库存信息
stockDataService.updateStockInfo(confirmTaskRequest.getStockConfirm(), confirmTaskRequest.getStandId(), confirmTaskRequest.getUserName(), "出库拣选", null);
// 查询库存获得当前载具中存储的库存列表
// LambdaQueryWrapper<TAppStock> stockQueryWrapper = new LambdaQueryWrapper<TAppStock>()
// .eq(TAppStock::getVehicleId, thisPickTask.getVehicleId())
// .gt(TAppStock::getRealNum, 0);
// List<TAppStock> stockList = appStockService.list(stockQueryWrapper);
// 界面直接点击确认/放行
// if (stockList.isEmpty()) {
// conveyTaskService.cancelOtherStandPickTasks(thisPickTask.getVehicleId(), thisPickTask.getPickStand());
// 判断还有没有当前站台的其他拣选任务
// TaskConfirmVo taskConfirmVo = conveyTaskService.getCurrentStandTask(thisPickTask);
// if (taskConfirmVo != null) {
// return BaseWmsApiResponse.warn("当前载具还有其他拣选任务,请根据界面信息进行拣配。");
// }
// WorkConfirmVo resultVo = conveyTaskService.getCurrentStandWork(thisPickTask);
// if (resultVo != null) {
// return BaseWmsApiResponse.warn("当前载具还有工作,请切换到拣配界面进行拣配。");
// }
// 判断当前载具是否还有盘点任务
// List<String> goodsIds = stockList.stream().map(TAppStock::getGoodsId).distinct().toList();
// List<TAppInventory> inventoryTasks = appInventoryService.list(new LambdaQueryWrapper<TAppInventory>()
// .eq(TAppInventory::getVehicleId, thisPickTask.getVehicleId())
// .in(TAppInventory::getGoodsId, goodsIds));
// if (inventoryTasks != null && !inventoryTasks.isEmpty()) {
// return BaseWmsApiResponse.warn("当前载具还有盘点任务,请切换到盘点界面进行拣配。");
// }
// }
// else {
// // 取消后续拣选任务
// conveyTaskService.cancelOtherStandPickTasks(thisPickTask.getVehicleId(), thisPickTask.getPickStand());
// }
// 放行
if (conveyTaskService.releaseStandVehicle(thisPickTask)) {
if (requestForCompleted.getPickingDetail() != null && !requestForCompleted.getPickingDetail().isEmpty()){
//1. 回告EWM系统出库完成
EwmApiBackResponse ewmApiBackResponse = ewmApiService.sendWarehouseOutCompleted(requestForCompleted);
if (Objects.equals(ewmApiBackResponse.getState(), "successfully")) {
log.info("调用回告EWM系统出库完成成功请求参数: {}", requestForCompleted);
// 重试机制处理remove操作防止死锁
int maxRetries = 3;
int retryCount = 0;
while (retryCount < maxRetries) {
try {
for (SendWarehouseOutCompletedRequest.PickingDetail deleteCheck : requestForCompleted.getPickingDetail()){
appOutsCheckService.remove(new LambdaQueryWrapper<TAppOutsCheck>()
.eq(TAppOutsCheck::getTaskNo, deleteCheck.getTaskNo()));
}
break; // 成功则跳出循环
} catch (Exception e) {
retryCount++;
log.warn("删除TAppOutsCheck记录失败第{}次重试,错误: {}", retryCount, e.getMessage());
if (retryCount >= maxRetries) {
log.error("删除TAppOutsCheck记录最终失败已重试{}次", maxRetries, e);
// 可以选择是否抛出异常或记录到错误表中
} else {
try {
Thread.sleep(100L * retryCount); // 简单的退避策略
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}
}
}
}else {
log.error("调用回告EWM系统出库完成接口异常请求参数: {}", requestForCompleted);
return BaseWmsApiResponse.error("调用回告EWM系统出库完成接口异常: " + ewmResponse.getMessage());
}
}
} else {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return BaseWmsApiResponse.error("释放箱子失败。");
}
//2. 回告EWM容器置空
// 查询对应的库存信息
List<TAppStock> stockLists = appStockService.list(new LambdaQueryWrapper<TAppStock>()
.eq(TAppStock::getVehicleId, confirmTaskRequest.getStockConfirm().getVehicleId())
);
if (stockLists == null || stockLists.isEmpty()){
// 回告EWM系统
SendEwmVehicleForInRequest requestForEmptyVehicle = new SendEwmVehicleForInRequest();
request.setContainerNo(confirmTaskRequest.getStockConfirm().getVehicleId());
EwmApiBackResponse ewmApiBackResponseByEmpty = ewmApiService.sendContainerEmpty(requestForEmptyVehicle);
if (!Objects.equals(ewmApiBackResponseByEmpty.getState(), "successful")) {
log.error("容器置空调用EWM系统接口异常请求参数: {}", request);
}else {
log.info("容器置空调用EWM系统接口成功请求参数: {}", request);
}
}
if (appPickTaskService.exists(new LambdaQueryWrapper<TAppPickTask>()
.eq(TAppPickTask::getVehicleId, thisPickTask.getVehicleId())
.eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode())
)){
return BaseWmsApiResponse.success("继续拣选");
}
// // 回告EWm系统出库完成
// SendWarehouseOutCompletedRequest request = new SendWarehouseOutCompletedRequest();
// List<SendWarehouseOutCompletedRequest.PickingDetail> pickingDetails = new ArrayList<>();
// SendWarehouseOutCompletedRequest.PickingDetail pickingDetail = new SendWarehouseOutCompletedRequest.PickingDetail();
// pickingDetail.setTaskNo(confirmTaskRequest.getTaskConfirm().getTaskId());
// pickingDetail.setMatNo(confirmTaskRequest.getTaskConfirm().getGoodsId());
// pickingDetail.setPickingQty(Double.valueOf(confirmTaskRequest.getTaskConfirm().getTotalNeed()));
// pickingDetail.setActQty(Double.valueOf(confirmTaskRequest.getTaskConfirm().getRealPickQty()));
// pickingDetail.setUnit(thisOut.getUnit());
// pickingDetail.setContainerNo(confirmTaskRequest.getTaskConfirm().getContainerNo());
// pickingDetails.add(pickingDetail);
// request.setPickingDetail(pickingDetails);
// request.setWaveNo(thisOut.getWaveNo());
// request.setPickingType(thisOut.getPickingType());
//
// EwmApiBackResponse ewmApiBackResponse = ewmApiService.sendWarehouseOutCompleted(request);
// if (Objects.equals(ewmApiBackResponse.getState(), "successfully")) {
// log.info("调用EWM系统接口成功请求参数: {}", request);
//
// }else {
// log.error("调用EWM系统接口异常请求参数: {}", request);
// //return BaseWmsApiResponse.error("调用EWM系统接口异常: " + ewmApiBackResponse.getMessage());
// }
return BaseWmsApiResponse.success("确认成功。");
} else {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return BaseWmsApiResponse.error("释放箱子失败。");
}
}
/**
@ -2100,7 +2223,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
*
* @param confirmTaskRequest 确认信息
*/
private String updateTaskInfo(ConfirmTaskRequest confirmTaskRequest) {
private String updateTaskInfo(ConfirmTaskRequest confirmTaskRequest,SendWarehouseOutCompletedRequest requestForCompleted) {
if (confirmTaskRequest == null) {
return "请求参数为空";
}
@ -2109,21 +2232,65 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
return "请求参数不全";
}
// 查询对应的任务
TAppOuts outs = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getTaskId, taskConfirm.getTaskId()));
if (outs == null || taskConfirm.getRealPickQty() == null) {
List<TAppOuts> thisOut = new ArrayList<>();
if (confirmTaskRequest.getTaskConfirm().getIsEmpty() == 0){
thisOut = appOutsService.list(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getPickPlanId, confirmTaskRequest.getStockConfirm().getStockId())
.orderByDesc(TAppOuts::getPickPlanIdTimes)
);
} else if (confirmTaskRequest.getTaskConfirm().getIsEmpty() == 1) {
TAppOuts out = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getTaskId, confirmTaskRequest.getTaskConfirm().getTaskId()));
if (out != null){
thisOut.add(out);
}
}else {
return "字段isEmpty获取失败请重试";
}
if (thisOut == null) {
return "未查到对应的任务或者实际拣选数量未填写";
}
outs.setPickNum(outs.getPickNum() + taskConfirm.getRealPickQty());
if (thisOut.size() != confirmTaskRequest.getTaskConfirm().getTotalQty()){
return "EWM下发新需求请刷新后重新合并";
}
List<SendWarehouseOutCompletedRequest.PickingDetail> pickingDetails = new ArrayList<>();
for (TAppOuts outs : thisOut){
int startPickNum = outs.getPickNum();
if (taskConfirm.getRealPickQty() >= (outs.getDistributeNum() - outs.getPickNum())){
taskConfirm.setRealPickQty(taskConfirm.getRealPickQty() - outs.getDistributeNum() + outs.getPickNum());
outs.setPickNum(outs.getDistributeNum() - outs.getPickNum());
}else {
outs.setPickNum(taskConfirm.getRealPickQty());
}
//outs.setPickNum(outs.getPickNum() + taskConfirm.getRealPickQty());
outs.setUserName(confirmTaskRequest.getUserName());
// 将出库完成需要反馈的信息插入outsCheck表中
List<TAppOutsCheck> outsChecks = new ArrayList<>();
outsChecks.add(new TAppOutsCheck(
UUIDUtils.getNewUUID("CHECK_"),
outs.getWaveNo(),
outs.getTaskId(),
outs.getGoodsId(),
outs.getNeedNum(),
outs.getPickNum(),
outs.getUnit(),
confirmTaskRequest.getTaskConfirm().getContainerNo(),
outs.getSecondPickingCode(),
outs.getOrderNo()
));
appOutsCheckService.saveBatch(outsChecks);
outs.setPickNum(outs.getPickNum() + startPickNum);
if (outs.getPickNum() >= outs.getNeedNum()) {
// 读取所有wave_no的outs_check表的数据全部反馈给EWM
List<TAppOutsCheck> checkList = appOutsCheckService.list(new LambdaQueryWrapper<TAppOutsCheck>()
.eq(TAppOutsCheck::getTaskNo, taskConfirm.getTaskId()));
.eq(TAppOutsCheck::getTaskNo, outs.getTaskId()));
// 回告EWm系统出库完成
SendWarehouseOutCompletedRequest request = new SendWarehouseOutCompletedRequest();
List<SendWarehouseOutCompletedRequest.PickingDetail> pickingDetails = new ArrayList<>();
for (TAppOutsCheck check : checkList){
SendWarehouseOutCompletedRequest.PickingDetail pickingDetail = new SendWarehouseOutCompletedRequest.PickingDetail();
pickingDetail.setTaskNo(check.getTaskNo());
@ -2134,23 +2301,6 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
pickingDetail.setContainerNo(check.getContainerNo());
pickingDetails.add(pickingDetail);
}
request.setPickingDetail(pickingDetails);
request.setWaveNo(outs.getWaveNo());
request.setPickingType(outs.getPickingType());
EwmApiBackResponse ewmApiBackResponse = ewmApiService.sendWarehouseOutCompleted(request);
if (Objects.equals(ewmApiBackResponse.getState(), "successfully")) {
log.info("调用EWM系统接口成功请求参数: {}", request);
appOutsCheckService.remove(new LambdaQueryWrapper<TAppOutsCheck>()
.eq(TAppOutsCheck::getTaskNo, taskConfirm.getTaskId())
);
}else {
log.error("调用EWM系统接口异常请求参数: {}", request);
// 触发事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// 返回错误信息
return ewmApiBackResponse.toString();
}
// 生成记录
TAppOutsRecord record = new TAppOutsRecord(
@ -2175,38 +2325,11 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// 更新出库单
appOutsService.updateById(outs);
}
// 判断是否是紧急出库且是缺料
// if (Objects.equals(outs.getOutType(), WmsOutTypeEnums.EMERGE.getCode())
// && outs.getReason().contains(EmergencyOutReasonEnums.GOODS_LACK.getReason()) && StringUtils.isNotEmpty(outs.getWorkOrder())) {
// // 查询此工单下缺料的工作
// List<TAppWork> lackGoodsWorks = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
// .eq(TAppWork::getWorkOrder, outs.getWorkOrder())
// .eq(TAppWork::getWorkStatus, 2)
// .eq(TAppWork::getLackStatus, 1));
// int canDistributeNum = taskConfirm.getRealPickQty();
// List<TAppWork> needUpdateWorks = new ArrayList<>();
// for (TAppWork lackGoodsWork : lackGoodsWorks) {
// if (canDistributeNum == 0) {
// // 本次拣选数量不够分了
// break;
// }
// if (lackGoodsWork.getFinishNum() >= lackGoodsWork.getNeedNum()) {
// continue;
// }
// int remainNeedNum = lackGoodsWork.getNeedNum() - lackGoodsWork.getFinishNum();
// // 这里需要重新设置完成数量
// if (remainNeedNum >= canDistributeNum) {
// canDistributeNum = 0;
// lackGoodsWork.setFinishNum(lackGoodsWork.getFinishNum() + canDistributeNum);
// } else {
// canDistributeNum -= remainNeedNum;
// lackGoodsWork.setFinishNum(lackGoodsWork.getNeedNum());
// lackGoodsWork.setLackStatus(0);
// }
// needUpdateWorks.add(lackGoodsWork);
// }
// appWorkService.updateBatchById(needUpdateWorks);
// }
}
requestForCompleted.setPickingDetail(pickingDetails);
requestForCompleted.setWaveNo(thisOut.getFirst().getWaveNo());
requestForCompleted.setPickingType(thisOut.getFirst().getPickingType());
// 清除拣选计划
LambdaQueryWrapper<TAppPickPlan> pickPlanQueryWrapper = new LambdaQueryWrapper<TAppPickPlan>()
.eq(TAppPickPlan::getWorkIndex, confirmTaskRequest.getTaskConfirm().getTaskId());

View File

@ -155,9 +155,10 @@ public class TaskQueryControllerServiceImpl implements ITaskQueryControllerServi
// 查询未关闭
Page<TAppOuts> page = outsQuery.toMpPage();
LambdaQueryWrapper<TAppOuts> lambdaQueryWrapper = new LambdaQueryWrapper<TAppOuts>()
.like(StringUtils.isNotEmpty(outsQuery.getTaskId()), TAppOuts::getTaskId, outsQuery.getTaskId())
.ge(outsQuery.getPickingDate() != null, TAppOuts::getPickingDate, outsQuery.getPickingDate()) // 大于等于
.le(outsQuery.getPickingDate() != null, TAppOuts::getPickingDate, outsQuery.getPickingDate()) // 小于等于
.like(StringUtils.isNotEmpty(outsQuery.getGoodsId()), TAppOuts::getGoodsId, outsQuery.getGoodsId())
.like(StringUtils.isNotEmpty(outsQuery.getVehicleId()), TAppOuts::getVehicleId, outsQuery.getVehicleId())
.like(StringUtils.isNotEmpty(outsQuery.getWorkOrder()), TAppOuts::getWorkOrder, outsQuery.getWorkOrder())
.eq(outsQuery.getOutType() != null, TAppOuts::getOutType, outsQuery.getOutType());
Page<TAppOuts> outsPage = appOutsService.page(page, lambdaQueryWrapper);
@ -179,6 +180,48 @@ public class TaskQueryControllerServiceImpl implements ITaskQueryControllerServi
}
/**
* 通过任务ID更新任务优先级
* @param outsVo 包含任务ID和新优先级的参数
* @return 更新结果
*/
@Override
public WmsApiResponse<String> upOutsType(OutsVo outsVo) {
// 1. 参数校验
if (outsVo == null || StringUtils.isEmpty(outsVo.getTaskId())) {
return WmsApiResponse.error("任务ID不能为空", null);
}
// 2. 查询原任务
TAppOuts existingOuts = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getTaskId, outsVo.getTaskId()));
if (existingOuts == null) {
return WmsApiResponse.error("未找到对应的任务", null);
}
if (existingOuts.getDistributeNum() > 0) {
return WmsApiResponse.error("任务已经开始执行!", null);
}
if (existingOuts.getOutType() == 1){
return WmsApiResponse.error("空箱出库无需提高优先级", null);
}
// 3. 更新优先级字段假设outsVo中的outType代表优先级
existingOuts.setOutType(existingOuts.getOutType() + 1);
// 4. 执行更新操作
boolean updateSuccess = appOutsService.updateById(existingOuts);
if (updateSuccess) {
return WmsApiResponse.success("任务优先级更新成功", null);
} else {
return WmsApiResponse.error("任务优先级更新失败", null);
}
}
/**
* 分页查询盘点相关信息---实现
* @param inventoryQuery 查询参数
@ -213,4 +256,68 @@ public class TaskQueryControllerServiceImpl implements ITaskQueryControllerServi
return WmsApiResponse.success("查询盘点记录成功。", pageVo);
}
}
@Override
public WmsApiResponse<String> editDate(OutsVo outsVo) {
// 1. 参数校验
if (outsVo == null || StringUtils.isEmpty(outsVo.getTaskId())) {
return WmsApiResponse.error("任务ID不能为空", null);
}
if (outsVo.getPickingDate() == null){
return WmsApiResponse.error("请选择执行时间", null);
}
// 2. 查询原任务
TAppOuts existingOuts = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getTaskId, outsVo.getTaskId()));
if (existingOuts == null) {
return WmsApiResponse.error("未找到对应的任务", null);
}
if (existingOuts.getDistributeNum() > 0) {
return WmsApiResponse.error("任务已经开始执行!", null);
}
if (existingOuts.getPickingDate() == outsVo.getPickingDate()){
return WmsApiResponse.error("请勿重复修改", null);
}
// 3. 更新优先级字段假设outsVo中的outType代表优先级
existingOuts.setPickingDate(outsVo.getPickingDate());
// 4. 执行更新操作
boolean updateSuccess = appOutsService.updateById(existingOuts);
if (updateSuccess) {
return WmsApiResponse.success("执行时间更新成功", null);
} else {
return WmsApiResponse.error("执行时间更新失败", null);
}
}
@Override
public WmsApiResponse<String> updateOutsInfo(TAppPickTask appTask) {
if (appTask == null || StringUtils.isEmpty(appTask.getPickId())) {
return WmsApiResponse.error("缺少ID号。", null);
}
TAppPickTask pickTask = appPickTaskService.getOne(new LambdaQueryWrapper<TAppPickTask>()
.eq(TAppPickTask::getPickId, appTask.getPickId()));
if (pickTask == null){
return WmsApiResponse.error("未找到对应的任务", null);
}
// 设置需要更新的字段这里可以根据实际业务需求设置
pickTask.setPickStatus(appTask.getPickStatus());
if (appPickTaskService.updateById(pickTask)) {
return WmsApiResponse.success("更新出库单信息成功。", null);
} else {
return WmsApiResponse.error("更新出库单信息失败。", null);
}
}
}

View File

@ -1,12 +1,225 @@
package com.wms_main.service.controller.serviceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms_main.constant.AppConstant;
import com.wms_main.dao.ITSysUserService;
import com.wms_main.model.dto.query.UserQuery;
import com.wms_main.model.dto.query.UserUpdateRequest;
import com.wms_main.model.dto.response.wms.BaseWmsApiResponse;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.po.TSysRole;
import com.wms_main.model.po.TSysUser;
import com.wms_main.model.vo.wms.PageVo;
import com.wms_main.model.vo.wms.UserVo;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.service.controller.IUserControllerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service
@Slf4j
@RequiredArgsConstructor
public class UserControllerServiceImpl implements IUserControllerService {
private final ITSysUserService sysUserService;// 用户服务
@Override
public WmsApiResponse<PageVo<UserVo>> getUserList(UserQuery userQuery) {
// 参数校验可选
if (userQuery == null) {
return WmsApiResponse.error("查询参数不能为空", null);
}
// 直接执行用户分页查询不考虑角色过滤
Page<TSysUser> page = userQuery.toMpPage();
LambdaQueryWrapper<TSysUser> queryWrapper = new LambdaQueryWrapper<>();
// 根据roleId进行条件过滤
if ("0".equals(userQuery.getRoleId())) {
// roleId为0时显示所有用户不添加过滤条件
queryWrapper.orderByAsc(TSysUser::getRoleId);
} else if ("2".equals(userQuery.getRoleId())) {
// roleId为2时只显示该角色的用户
queryWrapper.eq(TSysUser::getUserName, userQuery.getUserName());
} else {
// 其他情况也显示所有用户可根据需求调整
queryWrapper.orderByAsc(TSysUser::getRoleId);
}
Page<TSysUser> usersPage = sysUserService.page(page, queryWrapper);
if (usersPage == null) {
return WmsApiResponse.error("获取用户列表发生异常", null);
}
// 返回结果
return WmsApiResponse.success("获取用户列表成功", PageVo.of(usersPage, UserVo::ofPo));
}
/**
* 添加用户信息---实现
*
* @param userUpdateRequest 新增用户信息请求
* @return 添加结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public BaseWmsApiResponse addUserInfo(UserUpdateRequest userUpdateRequest) {
// 参数校验
if (userUpdateRequest == null ||
StringUtils.isEmpty(userUpdateRequest.getLoginAccountUpdate()) ||
StringUtils.isEmpty(userUpdateRequest.getLoginPasswordUpdate())) {
return BaseWmsApiResponse.error("请求参数不完整,必须包含登录账号和密码。");
}
if (!Objects.equals(userUpdateRequest.getRoleIdOp(), "0")){
return BaseWmsApiResponse.error("您没有权限添加用户。");
}
// 查询用户是否已存在
boolean ifExist = sysUserService.exists(new LambdaQueryWrapper<TSysUser>()
.eq(TSysUser::getLoginAccount, userUpdateRequest.getLoginAccountUpdate()));
if (ifExist) {
return BaseWmsApiResponse.error("用户已存在,请勿重复添加。");
}
// 检查用户名是否已存在
boolean userNameExists = sysUserService.exists(new LambdaQueryWrapper<TSysUser>()
.eq(TSysUser::getUserName, userUpdateRequest.getUserNameUpdate()));
if (userNameExists) {
return BaseWmsApiResponse.error("用户名已存在,请使用其他用户名。");
}
// 添加新用户
TSysUser newUser = new TSysUser();
newUser.setLoginAccount(userUpdateRequest.getLoginAccountUpdate());
newUser.setLoginPassword(StringUtils.encryptPassword(userUpdateRequest.getLoginPasswordUpdate()));
newUser.setUserName(userUpdateRequest.getUserNameUpdate());
newUser.setRoleId("2");
newUser.setAddUser(userUpdateRequest.getUserName());
newUser.setAddTime(LocalDateTime.now());
boolean addResult = sysUserService.save(newUser);
return addResult ? BaseWmsApiResponse.success("添加用户信息成功") : BaseWmsApiResponse.error("添加用户信息失败");
}
/**
* 删除用户信息---实现
*
* @param userUpdateRequest 删除用户信息请求
* @return 删除结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public BaseWmsApiResponse deleteUserInfo(UserUpdateRequest userUpdateRequest) {
if (userUpdateRequest == null || StringUtils.isEmpty(userUpdateRequest.getRoleIdOp())) {
return BaseWmsApiResponse.error("请求以及操作人员的角色必须输入。");
}
// 查询被更新人员的角色
TSysUser needDeleteUser = sysUserService.getById(userUpdateRequest.getLoginAccountUpdate());
if (needDeleteUser == null) {
return BaseWmsApiResponse.error("无法删除查询不到的用户。");
}
if (!Objects.equals(userUpdateRequest.getRoleIdOp(), "0")) {
return BaseWmsApiResponse.error("您没有权限删除用户。");
}
// 删除对应用户
boolean deleteResult = sysUserService.removeById(userUpdateRequest.getLoginAccountUpdate());
return deleteResult ? BaseWmsApiResponse.success("删除用户成功。") : BaseWmsApiResponse.error("删除用户失败。");
}
/**
* 修改用户密码---实现
*
* @param userUpdateRequest 密码修改参数
* @return 修改结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public BaseWmsApiResponse changePassword(UserUpdateRequest userUpdateRequest) {
// 参数校验
if (userUpdateRequest == null ||
StringUtils.isEmpty(userUpdateRequest.getLoginAccountUpdate()) ||
StringUtils.isEmpty(userUpdateRequest.getOldPassword()) ||
StringUtils.isEmpty(userUpdateRequest.getNewPassword())) {
return BaseWmsApiResponse.error("请求参数不完整,必须包含账号、旧密码和新密码。");
}
// 查询用户是否存在
TSysUser user = sysUserService.getOne(new LambdaQueryWrapper<TSysUser>()
.eq(TSysUser::getLoginAccount, userUpdateRequest.getLoginAccountUpdate()));
if (user == null) {
return BaseWmsApiResponse.error("用户不存在。");
}
// 验证旧密码是否正确
if (!StringUtils.verifyPassword(userUpdateRequest.getOldPassword(), user.getLoginPassword())) {
return BaseWmsApiResponse.error("旧密码错误。");
}
// 更新密码
user.setLoginPassword(StringUtils.encryptPassword(userUpdateRequest.getNewPassword()));
user.setLastUpdateTime(LocalDateTime.now());
user.setLastUpdateUser(userUpdateRequest.getUserName());
boolean updateResult = sysUserService.updateById(user);
return updateResult ? BaseWmsApiResponse.success("密码修改成功") : BaseWmsApiResponse.error("密码修改失败");
}
/**
* 修改用户信息---实现
*
* @param userUpdateRequest 修改用户信息请求
* @return 修改结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public BaseWmsApiResponse updateUserInfo(UserUpdateRequest userUpdateRequest) {
// 参数校验
if (userUpdateRequest == null ||
StringUtils.isEmpty(userUpdateRequest.getLoginAccountUpdate()) ||
StringUtils.isEmpty(userUpdateRequest.getUserNameUpdate())) {
return BaseWmsApiResponse.error("请求参数不完整,必须包含登录账号和用户名。");
}
// 查询被更新人员
TSysUser needUpdateUser = sysUserService.getById(userUpdateRequest.getLoginAccountUpdate());
if (needUpdateUser == null) {
return BaseWmsApiResponse.error("无法找到该用户。");
}
// 检查用户名是否已存在
boolean userNameExists = sysUserService.exists(new LambdaQueryWrapper<TSysUser>()
.eq(TSysUser::getUserName, userUpdateRequest.getUserNameUpdate()));
if (userNameExists) {
return BaseWmsApiResponse.error("用户名已存在,请使用其他用户名。");
}
// 更新用户名
needUpdateUser.setUserName(userUpdateRequest.getUserNameUpdate());
needUpdateUser.setLastUpdateUser(userUpdateRequest.getUserName());
needUpdateUser.setLastUpdateTime(LocalDateTime.now());
boolean updateResult = sysUserService.updateById(needUpdateUser);
return updateResult ? BaseWmsApiResponse.success("修改用户信息成功") : BaseWmsApiResponse.error("修改用户信息失败");
}
}

View File

@ -27,27 +27,17 @@ public class OutsExecutor implements Job {
*/
@Override
public void execute(JobExecutionContext jobExecutionContext) {
// 解析工作配料
// try {
// outsExecutorService.executeKateWorks();
// } catch (Exception e) {
// log.error("解析工作(配料)失败{}", StringUtils.objectToString(e));
// }
// 处理出库单
// log.info("处理出库单开始");
try {
outsExecutorService.executeOuts();
} catch (Exception e) {
log.error("处理出库单失败{}", StringUtils.objectToString(e));
}
// 处理盘点单
try {
outsExecutorService.executeInventory();
} catch (Exception e) {
log.error("处理盘点单失败{}", StringUtils.objectToString(e));
}
// 处理出库单
try {
outsExecutorService.executeOuts();
} catch (Exception e) {
log.error("处理出库单失败{}", StringUtils.objectToString(e));
}
}
}

View File

@ -1,5 +1,6 @@
package com.wms_main.service.quartz_job.serviceImpl;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -8,6 +9,7 @@ import com.wms_main.constant.AppConstant;
import com.wms_main.constant.enums.wms.*;
import com.wms_main.dao.*;
import com.wms_main.model.po.*;
import com.wms_main.repository.utils.DbTransUtils;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.business.IStockDataService;
@ -43,33 +45,21 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
private final ITAppOutsRecordService appOutsRecordService;// 出库单记录服务
private final ITAppInventoryService appInventoryService;// 盘点任务服务
private final AppCommon appCommon;// 应用共通数据
private final DbTransUtils dbTransUtils;// 数据库事务工具
/**
* 解析出库单 实现
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void executeOuts() {
try {
// 查询到对应的出库单
// List<TAppOuts> appOutsList = appOutsService.list(
// new LambdaQueryWrapper<TAppOuts>().orderByDesc(TAppOuts::getOutType)
// );
// List<TAppOuts> appOutsList = appOutsService.list(
// new LambdaQueryWrapper<TAppOuts>()
// .le(TAppOuts::getPickingDate, LocalDate.now())
// .orderByDesc(TAppOuts::getOutType)
// );
List<TAppOuts> appOutsList = appOutsService.list(
new LambdaQueryWrapper<TAppOuts>()
.le(TAppOuts::getPickingDate, LocalDate.now())
.orderByDesc(TAppOuts::getOutType)
.last("LIMIT 15") // 限制只查询15条记录
).stream()
.filter(appOuts -> appOuts.getDistributeNum() < appOuts.getNeedNum())
.filter(appOuts -> appOuts.getOutType() == 1 || appOuts.getDistributeNum() < appOuts.getNeedNum())
.toList();
if (appOutsList.isEmpty()) {
return;
}
@ -81,15 +71,14 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
// 拣选任务
List<TAppPickTask> pickTasks = appPickTaskService.list();
// 查询库存条件剩余数量>0回库中锁定以外的库存状态
// List<TAppStock> allStocks = appStockService.list(new LambdaQueryWrapper<TAppStock>()
// .le(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode())
// .gt(TAppStock::getRemainNum, 0)
// .orderByAsc(TAppStock::getFirstInTime));
Set<String> requiredGoodsIds = appOutsList.stream()
.map(TAppOuts::getGoodsId)
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toSet());
List<TAppVehicle> emptyVehicles = appVehicleService.list(new LambdaQueryWrapper<TAppVehicle>()
.eq(TAppVehicle::getIsEmpty, 1)
.eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
.orderByDesc(TAppVehicle::getLastInTime));// 先进先出
List<TAppStock> allStocks = new ArrayList<>();
if (!requiredGoodsIds.isEmpty()) {
@ -100,37 +89,42 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
.orderByAsc(TAppStock::getFirstInTime));
}
// List<TAppVehicle> emptyVehicles = appVehicleService.list(new LambdaQueryWrapper<TAppVehicle>()
// .eq(TAppVehicle::getIsEmpty, 1)
// .eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
// .orderByAsc(TAppVehicle::getLastInTime)); // 先进先出
// // 获取可用堆垛机
List<TAppEquipment> usableStackers = appEquipmentService.list(new LambdaQueryWrapper<TAppEquipment>()
.eq(TAppEquipment::getEquipmentType, 1)
.eq(TAppEquipment::getEquipmentStatus, WmsUsableStatusEnums.USABLE.getCode()));
Map<Integer, String> equipVehicleMap = new HashMap<>();
getVehicleEquipMap("", true, equipVehicleMap, usableStackers);
for (TAppOuts appOuts : appOutsList) {
if (appOuts.getDistributeNum() >= appOuts.getNeedNum()) {
if (appOuts.getDistributeNum() >= appOuts.getNeedNum() && appOuts.getOutType() != 1) {
continue;
}
// // 判断目前是否是空箱任务
// if (Objects.equals(appOuts.getOutType(), WmsOutTypeEnums.EMPTY.getCode())) {
// solveEmpty(appOuts, emptyVehicles, equipVehicleMap, newOutWmsTasks, thisTimeOutVehicleIds);
// } else if (Objects.equals(appOuts.getOutType(), WmsOutTypeEnums.FOR_IN.getCode())) {
// solveOutForIn(equipVehicleMap, appOuts, allStocks, pickTasks, newOutWmsTasks, newPickTasks, thisTimeOutVehicleIds);
// } else if (Objects.equals(appOuts.getOutType(), WmsOutTypeEnums.EMERGE.getCode())) {
// 紧急出库
// 判断目前是否是空箱任务
if (Objects.equals(appOuts.getOutType(), WmsOutTypeEnums.EMPTY.getCode())) {
solveEmpty(appOuts, emptyVehicles, equipVehicleMap, newOutWmsTasks, thisTimeOutVehicleIds, newPickTasks);
}
solveEmerge(equipVehicleMap, appOuts, allStocks, pickTasks, newOutWmsTasks, newPickTasks, thisTimeOutVehicleIds, newPickPlans);
//}
}
// 保存出库单---只更新分配数量
List<TAppOuts> onlyDistributeNumOuts = appOutsList.stream().map(outs -> {
TAppOuts outCopy = new TAppOuts();
outCopy.setTaskId(outs.getTaskId());
outCopy.setDistributeNum(outs.getDistributeNum());
outCopy.setPickPlanId(outs.getPickPlanId());
outCopy.setPickPlanIdTimes(outs.getPickPlanIdTimes());
return outCopy;
}).toList();
// 创建一个只复制剩余数量的库存列表
List<TAppStock> onlyRemainNumStocks = allStocks.stream().map(stock -> {
TAppStock stockCopy = new TAppStock();
stockCopy.setStockId(stock.getStockId());
stockCopy.setRemainNum(stock.getRemainNum());
if (!thisTimeOutVehicleIds.isEmpty() && thisTimeOutVehicleIds.contains(stock.getVehicleId())) {
stockCopy.setStockStatus(WmsStockStatusEnums.OUTING.getCode());
}
return stockCopy;
}).toList();
boolean doTransResult = dbTransUtils.useTran(() -> {
appOutsService.updateBatchById(onlyDistributeNumOuts);
// 保存出库任务
if (!newOutWmsTasks.isEmpty()) {
@ -144,16 +138,6 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
if (!newPickPlans.isEmpty()) {
appPickPlanService.saveOrUpdateBatch(mergedPickPlan(newPickPlans));
}
// 创建一个只复制剩余数量的库存列表
List<TAppStock> onlyRemainNumStocks = allStocks.stream().map(stock -> {
TAppStock stockCopy = new TAppStock();
stockCopy.setStockId(stock.getStockId());
stockCopy.setRemainNum(stock.getRemainNum());
if (!thisTimeOutVehicleIds.isEmpty() && thisTimeOutVehicleIds.contains(stock.getVehicleId())) {
stockCopy.setStockStatus(WmsStockStatusEnums.OUTING.getCode());
}
return stockCopy;
}).toList();
// 更新库存信息
appStockService.updateBatchById(onlyRemainNumStocks);
// 更新载具信息
@ -162,10 +146,9 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
.set(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.OUT.getCode())
.in(TAppVehicle::getVehicleId, thisTimeOutVehicleIds));
}
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
log.error("解析出库单发生异常。{}", StringUtils.objectToString(e));
});
if (!doTransResult) {
log.error("执行出库单,数据库事务失败。");
}
}
@ -178,11 +161,14 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
* @param newOutWmsTasks 新的出库任务
* @param thisTimeOutVehicleIds 本次出库的载具列表
*/
private void solveEmpty(TAppOuts appOuts, List<TAppVehicle> emptyVehicles, Map<Integer, String> equipVehicleMap, List<TAppTask> newOutWmsTasks, List<String> thisTimeOutVehicleIds) {
private void solveEmpty(TAppOuts appOuts, List<TAppVehicle> emptyVehicles, Map<Integer, String> equipVehicleMap, List<TAppTask> newOutWmsTasks, List<String> thisTimeOutVehicleIds, List<TAppPickTask> newPickTasks) {
int needNum = appOuts.getNeedNum() - appOuts.getDistributeNum();
if (needNum <= 0) {
// 删除出库单
appOutsService.removeById(appOuts.getTaskId());
return;
}
String optimalDestination = getOptimalSubStand(appOuts.getDestination());
// 生成空箱出库任务
for (TAppVehicle emptyVehicle : emptyVehicles) {
if (needNum <= 0) {
@ -215,10 +201,19 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
0,
0,
appOuts.getUserName(),
"",
appOuts.getDestination(),
"空箱出库",
optimalDestination,
""
));
// 生成达到既删除的拣选任务type设置为3
newPickTasks.add(new TAppPickTask(
UUIDUtils.getNewUUID(),
optimalDestination,
emptyVehicle.getVehicleId(),
WmsPickTaskStatusEnum.TEMP.getCode(),
LocalDateTime.now(),
null, null, null,3
));
emptyVehicle.setVehicleStatus(WmsVehicleStatusEnums.OUT.getCode());
thisTimeOutVehicleIds.add(emptyVehicle.getVehicleId());
updateVehicleEquipMapByLocation(equipVehicleMap, emptyVehicle.getVehicleId(), emptyVehicle.getLocationId());
@ -409,26 +404,39 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
continue;
}
// 判断当前的这条库存当前站台是否需要
int stockIsEmpty;
int originNum = stock.getRemainNum();
int remainNum = stock.getRemainNum();
int needNum = appOuts.getNeedNum() - appOuts.getDistributeNum();
if (needNum < remainNum) {
if (needNum <= remainNum) {
appOuts.setDistributeNum(appOuts.getNeedNum());
remainNum = remainNum - needNum;
stockIsEmpty = 0;
} else {
appOuts.setDistributeNum(appOuts.getDistributeNum() + remainNum);
remainNum = 0;
stockIsEmpty = 1;
}
if (remainNum == originNum) {
// 没用到这条库存
continue;
}
// // 查找该workIndex的计划有没有有的话计划需要合并拣选任务不生产
// // 如果没有的话拣选任务不会合并而且对应的拣选任务要生成
// // 查询到对应的出库单
// List<TAppPickPlan> appPickPlans = appPickPlanService.list(
// new LambdaQueryWrapper<TAppPickPlan>().eq(TAppPickPlan::getWorkIndex, appOuts.getTaskId())
// );
// 查找该工单号orderNo的且goodsId一样的计划有没有有的话计划需要合并拣选任务不生产
// 如果没有的话拣选任务不会合并而且对应的拣选任务要生成
// 查询到对应的出库单
List<TAppPickPlan> appPickPlansByData = appPickPlanService.list(
new LambdaQueryWrapper<TAppPickPlan>()
.eq(TAppPickPlan::getOrderNo, appOuts.getSecondPickingCode())
.eq(TAppPickPlan::getGoodsId, appOuts.getGoodsId())
.eq(TAppPickPlan::getVehicleId, stock.getVehicleId())
.eq(TAppPickPlan::getIsEmpty, stockIsEmpty)
);
List<TAppPickPlan> appPickPlansByMemory = newPickPlans.stream()
.filter(plan -> Objects.equals(plan.getOrderNo(), appOuts.getSecondPickingCode())
&& Objects.equals(plan.getGoodsId(), appOuts.getGoodsId())
&& Objects.equals(plan.getVehicleId(), stock.getVehicleId())
&& Objects.equals(plan.getIsEmpty(), stockIsEmpty)
).toList();
// 生成拣选计划
TAppPickPlan pickPlan = new TAppPickPlan(
@ -438,7 +446,9 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
originNum - remainNum,
2,
appOuts.getTaskId(),
optimalDestination
optimalDestination,
appOuts.getSecondPickingCode(),
stockIsEmpty
);
newPickPlans.add(pickPlan);
// 库存变动了需要更新库存信息
@ -489,7 +499,9 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
// && !Objects.equals(pickTask.getPickStatus(), WmsPickTaskStatusEnum.FOR_IN.getCode())).toList();
// 生成拣选任务
//if (oldPickTasks.isEmpty() && newOldPickTasks.isEmpty() && appPickPlans.isEmpty()) {
// if (appPickPlans.isEmpty()) {
appOuts.setPickPlanIdTimes(newPickPlans.size());
if (appPickPlansByData.isEmpty() && appPickPlansByMemory.isEmpty()) {
newPickTasks.add(new TAppPickTask(
UUIDUtils.getNewUUID(),
optimalDestination,
@ -498,7 +510,15 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
LocalDateTime.now(),
null, null, null,1
));
// }
appOuts.setPickPlanId(pickPlan.getPlanId());
}else{
if (appPickPlansByData.isEmpty()){
appOuts.setPickPlanId(appPickPlansByMemory.getFirst().getPlanId());
}else {
appOuts.setPickPlanId(appPickPlansByData.getFirst().getPlanId());
}
}
}
}
@ -515,7 +535,8 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
standMapping.put("P1", List.of("P12"));
standMapping.put("P2", List.of("P15"));
standMapping.put("P3", List.of("P18"));
standMapping.put("P4", Arrays.asList("P21", "P22", "P23"));
// 修改P4映射为多个子站台
standMapping.put("P4", List.of("P21", "P22", "P23"));
// 如果不是主站台直接返回原站台
if (!standMapping.containsKey(mainStand)) {
@ -546,7 +567,7 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
* 实现
*/
@Override
@Transactional(rollbackFor = Exception.class)
//@Transactional(rollbackFor = Exception.class)
public void executeKateWorks() {
try {
// 查询所有的未完成的工作
@ -700,7 +721,7 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
thisTimePickNum,
1,
thisWork.getWorkIndex(),
stand.getStandId()
stand.getStandId(),null,null
);
newPickPlans.add(pickPlan);
}
@ -1429,11 +1450,11 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
// 循环merge
for (TAppPickPlan beforeMergePickPlan : beforeMergePickPlanList) {
// key站台+箱号+料号+拣选类型+index
String key = beforeMergePickPlan.getPlanId() + "_"
+beforeMergePickPlan.getVehicleId() + "_"
String key = beforeMergePickPlan.getVehicleId() + "_"
+ beforeMergePickPlan.getGoodsId() + "_"
+ beforeMergePickPlan.getPickType() + "_"
+ beforeMergePickPlan.getWorkIndex();
+ beforeMergePickPlan.getOrderNo() + "_"
+ beforeMergePickPlan.getIsEmpty();
if (mergedPickPlanMap.containsKey(key)) {
// 之前已经合并过
@ -1442,11 +1463,13 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
mergedPickPlanMap.replace(key, mergedPickPlan);
} else {
// 之前没有合并过
TAppPickPlan existPickPlan = existPickPlanList.stream().filter(pickPlan -> Objects.equals(pickPlan.getPlanId(), beforeMergePickPlan.getPlanId())
&& Objects.equals(pickPlan.getVehicleId(), beforeMergePickPlan.getVehicleId())
TAppPickPlan existPickPlan = existPickPlanList.stream().filter(pickPlan ->
Objects.equals(pickPlan.getVehicleId(), beforeMergePickPlan.getVehicleId())
&& Objects.equals(pickPlan.getGoodsId(), beforeMergePickPlan.getGoodsId())
&& Objects.equals(pickPlan.getPickType(), beforeMergePickPlan.getPickType())
&& Objects.equals(pickPlan.getWorkIndex(), beforeMergePickPlan.getWorkIndex())).findFirst().orElse(null);
&& Objects.equals(pickPlan.getOrderNo(), beforeMergePickPlan.getOrderNo())
&& Objects.equals(pickPlan.getIsEmpty(), beforeMergePickPlan.getIsEmpty())
).findFirst().orElse(null);
if (existPickPlan != null) {
// 已经存过表
existPickPlan.setPlanPickQty(existPickPlan.getPlanPickQty() + beforeMergePickPlan.getPlanPickQty());
@ -1460,7 +1483,9 @@ public class OutsExecutorServiceImpl implements IOutsExecutorService {
beforeMergePickPlan.getPlanPickQty(),
beforeMergePickPlan.getPickType(),
beforeMergePickPlan.getWorkIndex(),
beforeMergePickPlan.getStandId()
beforeMergePickPlan.getStandId(),
beforeMergePickPlan.getOrderNo(),
beforeMergePickPlan.getIsEmpty()
);
}
mergedPickPlanMap.put(key, existPickPlan);