diff --git a/galvanize1.sql b/galvanize1.sql deleted file mode 100644 index e69de29b..00000000 diff --git a/klp-admin/src/main/resources/db/migration/V8__aps_quick_sheet.sql b/klp-admin/src/main/resources/db/migration/V8__aps_quick_sheet.sql new file mode 100644 index 00000000..55244d70 --- /dev/null +++ b/klp-admin/src/main/resources/db/migration/V8__aps_quick_sheet.sql @@ -0,0 +1,28 @@ +CREATE TABLE IF NOT EXISTS aps_quick_sheet ( + quick_sheet_id BIGINT AUTO_INCREMENT PRIMARY KEY, + plan_date DATE NOT NULL COMMENT '计划日期', + line_id BIGINT NULL COMMENT '产线ID', + line_name VARCHAR(120) NULL COMMENT '产线名称', + plan_code VARCHAR(60) NOT NULL COMMENT '计划号', + order_code VARCHAR(80) NULL COMMENT '订单号', + customer_name VARCHAR(120) NULL COMMENT '客户', + salesman VARCHAR(60) NULL COMMENT '业务员', + product_name VARCHAR(120) NULL COMMENT '产品', + raw_material_id VARCHAR(64) NULL COMMENT '原料钢卷', + raw_coil_nos VARCHAR(255) NULL COMMENT '原料卷号', + raw_location VARCHAR(120) NULL COMMENT '钢卷位置', + raw_packaging VARCHAR(120) NULL COMMENT '包装要求', + raw_edge_req VARCHAR(120) NULL COMMENT '切边要求', + raw_coating_type VARCHAR(120) NULL COMMENT '镀层种类', + raw_net_weight DECIMAL(18, 3) NULL COMMENT '原料净重', + plan_qty DECIMAL(18, 3) NULL COMMENT '计划数量', + start_time DATETIME NULL COMMENT '开始时间', + end_time DATETIME NULL COMMENT '结束时间', + del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)', + create_by VARCHAR(64) NULL, + update_by VARCHAR(64) NULL, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_aps_quick_sheet_plan_date (plan_date), + INDEX idx_aps_quick_sheet_line_id (line_id) +) COMMENT = '快速排产表(Excel样式)'; diff --git a/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql b/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql new file mode 100644 index 00000000..69a7fa6c --- /dev/null +++ b/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql @@ -0,0 +1,47 @@ +CREATE TABLE IF NOT EXISTS wms_furnace ( + furnace_id BIGINT AUTO_INCREMENT PRIMARY KEY, + furnace_code VARCHAR(50) NOT NULL COMMENT '炉编号', + furnace_name VARCHAR(100) NOT NULL COMMENT '名称', + busy_flag TINYINT DEFAULT 0 COMMENT '是否忙碌(0否1是)', + status TINYINT DEFAULT 1 COMMENT '状态(0停用1启用)', + remark VARCHAR(500) NULL COMMENT '备注', + del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)', + create_by VARCHAR(64) NULL, + update_by VARCHAR(64) NULL, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_wms_furnace_code (furnace_code) +) COMMENT = '退火炉信息表'; + +CREATE TABLE IF NOT EXISTS wms_furnace_plan ( + plan_id BIGINT AUTO_INCREMENT PRIMARY KEY, + plan_no VARCHAR(60) NOT NULL COMMENT '计划号', + plan_start_time DATETIME NULL COMMENT '计划开始时间', + actual_start_time DATETIME NULL COMMENT '实际开始时间', + end_time DATETIME NULL COMMENT '结束时间', + target_furnace_id BIGINT NOT NULL COMMENT '目标炉子ID', + status TINYINT DEFAULT 0 COMMENT '计划状态(0草稿 1已下发 2执行中 3已完成 4已取消)', + remark VARCHAR(500) NULL COMMENT '备注', + del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)', + create_by VARCHAR(64) NULL, + update_by VARCHAR(64) NULL, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_wms_furnace_plan_no (plan_no), + INDEX idx_wms_furnace_plan_furnace (target_furnace_id), + INDEX idx_wms_furnace_plan_status (status) +) COMMENT = '退火计划表'; + +CREATE TABLE IF NOT EXISTS wms_furnace_plan_coil ( + plan_coil_id BIGINT AUTO_INCREMENT PRIMARY KEY, + plan_id BIGINT NOT NULL COMMENT '计划ID', + coil_id BIGINT NOT NULL COMMENT '钢卷ID', + del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)', + create_by VARCHAR(64) NULL, + update_by VARCHAR(64) NULL, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_wms_furnace_plan_coil (plan_id, coil_id), + INDEX idx_wms_furnace_plan_coil_plan (plan_id), + INDEX idx_wms_furnace_plan_coil_coil (coil_id) +) COMMENT = '退火计划钢卷关系表'; diff --git a/klp-ui/src/api/wms/annealFurnace.js b/klp-ui/src/api/wms/annealFurnace.js new file mode 100644 index 00000000..87406878 --- /dev/null +++ b/klp-ui/src/api/wms/annealFurnace.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 查询退火炉列表 +export function listAnnealFurnace(query) { + return request({ + url: '/wms/anneal/furnace/list', + method: 'get', + params: query + }) +} + +// 查询退火炉详情 +export function getAnnealFurnace(furnaceId) { + return request({ + url: '/wms/anneal/furnace/' + furnaceId, + method: 'get' + }) +} + +// 新增退火炉 +export function addAnnealFurnace(data) { + return request({ + url: '/wms/anneal/furnace/add', + method: 'post', + data: data + }) +} + +// 修改退火炉 +export function updateAnnealFurnace(data) { + return request({ + url: '/wms/anneal/furnace/edit', + method: 'put', + data: data + }) +} + +// 启用停用 +export function changeAnnealFurnaceStatus(data) { + return request({ + url: '/wms/anneal/furnace/status', + method: 'put', + data: data + }) +} + +// 置忙/置闲 +export function changeAnnealFurnaceBusy(data) { + return request({ + url: '/wms/anneal/furnace/busy', + method: 'put', + data: data + }) +} + +// 删除退火炉 +export function delAnnealFurnace(furnaceId) { + return request({ + url: '/wms/anneal/furnace/' + furnaceId, + method: 'delete' + }) +} diff --git a/klp-ui/src/api/wms/annealOverview.js b/klp-ui/src/api/wms/annealOverview.js new file mode 100644 index 00000000..c2057170 --- /dev/null +++ b/klp-ui/src/api/wms/annealOverview.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 查询退火总览信息 +export function getAnnealOverview() { + return request({ + url: '/wms/anneal/overview', + method: 'get' + }) +} diff --git a/klp-ui/src/api/wms/annealPerformance.js b/klp-ui/src/api/wms/annealPerformance.js new file mode 100644 index 00000000..bf0b6bf1 --- /dev/null +++ b/klp-ui/src/api/wms/annealPerformance.js @@ -0,0 +1,10 @@ +import request from '@/utils/request' + +// 查询炉火实绩 +export function getAnnealPerformance(query) { + return request({ + url: '/wms/anneal/performance', + method: 'get', + params: query + }) +} diff --git a/klp-ui/src/api/wms/annealPlan.js b/klp-ui/src/api/wms/annealPlan.js new file mode 100644 index 00000000..ee169ed4 --- /dev/null +++ b/klp-ui/src/api/wms/annealPlan.js @@ -0,0 +1,98 @@ +import request from '@/utils/request' + +// 查询退火计划列表 +export function listAnnealPlan(query) { + return request({ + url: '/wms/anneal/plan/list', + method: 'get', + params: query + }) +} + +// 查询退火计划详情 +export function getAnnealPlan(planId) { + return request({ + url: '/wms/anneal/plan/' + planId, + method: 'get' + }) +} + +// 新增退火计划 +export function addAnnealPlan(data) { + return request({ + url: '/wms/anneal/plan/add', + method: 'post', + data: data + }) +} + +// 修改退火计划 +export function updateAnnealPlan(data) { + return request({ + url: '/wms/anneal/plan/edit', + method: 'put', + data: data + }) +} + +// 删除退火计划 +export function delAnnealPlan(planId) { + return request({ + url: '/wms/anneal/plan/' + planId, + method: 'delete' + }) +} + +// 更新计划状态 +export function changeAnnealPlanStatus(data) { + return request({ + url: '/wms/anneal/plan/status', + method: 'put', + data: data + }) +} + +// 入炉 +export function inFurnace(data) { + return request({ + url: '/wms/anneal/plan/in-furnace', + method: 'put', + data: data + }) +} + +// 完成退火 +export function completeAnnealPlan(data) { + return request({ + url: '/wms/anneal/plan/complete', + method: 'put', + data: data + }) +} + +// 查询计划钢卷列表 +export function listAnnealPlanCoils(planId) { + return request({ + url: '/wms/anneal/plan/coil/list', + method: 'get', + params: { planId } + }) +} + +// 绑定钢卷 +export function bindAnnealPlanCoils(data) { + return request({ + url: '/wms/anneal/plan/coil/bind', + method: 'post', + data: data + }) +} + +// 解绑钢卷 +export function unbindAnnealPlanCoil(data) { + return request({ + url: '/wms/anneal/plan/coil/unbind', + method: 'delete', + data: data + }) +} diff --git a/klp-ui/src/assets/icons/svg/furnace.svg b/klp-ui/src/assets/icons/svg/furnace.svg new file mode 100644 index 00000000..12942b12 --- /dev/null +++ b/klp-ui/src/assets/icons/svg/furnace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/klp-ui/src/views/wms/anneal/furnace/index.vue b/klp-ui/src/views/wms/anneal/furnace/index.vue new file mode 100644 index 00000000..d6ca7938 --- /dev/null +++ b/klp-ui/src/views/wms/anneal/furnace/index.vue @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + 新增 + + + 修改 + + + 删除 + + + + + + + + + + + 启用 + 停用 + + + + + 忙碌 + 空闲 + + + + + + 修改 + 删除 + + {{ scope.row.status === 1 ? '停用' : '启用' }} + + + {{ scope.row.busyFlag === 1 ? '置闲' : '置忙' }} + + + + + + + + + + + + + + + + + + 启用 + 停用 + + + + + 忙碌 + 空闲 + + + + + + + + + + + + diff --git a/klp-ui/src/views/wms/anneal/overview/index.vue b/klp-ui/src/views/wms/anneal/overview/index.vue new file mode 100644 index 00000000..79f3ce21 --- /dev/null +++ b/klp-ui/src/views/wms/anneal/overview/index.vue @@ -0,0 +1,336 @@ +· + + + + + 当前计划数 + {{ overview.totalPlanCount || 0 }} + + + + + 退火炉(忙碌/全部) + {{ overview.furnaceBusyCount || 0 }}/{{ overview.furnaceTotal || 0 }} + + + + + 待退火钢卷 + {{ overview.pendingCoilCount || 0 }} + + + + + 今日已完成 + + 计划 {{ overview.todayDonePlanCount || 0 }} | 钢卷 {{ overview.todayDoneCoilCount || 0 }} + + + + + + + 退火炉状态 + + + + + + {{ item.furnaceName }} + {{ item.furnaceCode }} + + + + 状态:{{ item.busyFlag === 1 ? '忙碌' : '空闲' }} + + 计划:{{ item.currentPlanNo || '-' }} + + + 当前钢卷:{{ item.coilCount || 0 }} + + + 预计剩余:{{ formatCountdown(item.planEndTime) }} + + 待入炉计划:{{ planQueueCount(item.furnaceId) }} + + + + + + + 计划队列 + + + + + + {{ statusLabel(scope.row.status) }} + + + + + {{ parseTime(scope.row.planStartTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + + 入炉 + 完成 + + + + + + + 请为每条钢卷分配实际库位,未分配将无法完成。 + + + + + + + + + + + + + + + + + + diff --git a/klp-ui/src/views/wms/anneal/performance/index.vue b/klp-ui/src/views/wms/anneal/performance/index.vue new file mode 100644 index 00000000..2b1c658f --- /dev/null +++ b/klp-ui/src/views/wms/anneal/performance/index.vue @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + 查询 + 重置 + + + + + {{ summary.planCount || 0 }} + {{ summary.coilCount || 0 }} + {{ summary.totalWeight || 0 }} t + + + + + + + + {{ parseTime(scope.row.actualStartTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + {{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + + + + + + + + diff --git a/klp-ui/src/views/wms/anneal/plan/index.vue b/klp-ui/src/views/wms/anneal/plan/index.vue new file mode 100644 index 00000000..dd8524dc --- /dev/null +++ b/klp-ui/src/views/wms/anneal/plan/index.vue @@ -0,0 +1,610 @@ + + + + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + 新增 + + + 修改 + + + 删除 + + + + + + + + + + {{ parseTime(scope.row.planStartTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + + {{ statusLabel(scope.row.status) }} + + + + + {{ parseTime(scope.row.actualStartTime || scope.row.planStartTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + {{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + 修改 + 删除 + 状态 + 入炉 + 完成 + + + + + + + + + + + 领料列表 + 刷新 + + + + + + + + + + 搜索 + 重置 + + + + + + + + + + {{ item.currentCoilNo || '-' }} + 入场:{{ item.enterCoilNo || '-' }} + + 加入计划 + + + 厂家:{{ item.supplierCoilNo || '-' }} + 库位:{{ item.actualWarehouseName || '-' }} + 重量:{{ item.netWeight || '-' }}t + + + + + + + + + + 退火计划 + + 刷新 + 完成退火 + + + + + + + + 计划号:{{ currentPlan.planNo }} + 目标炉:{{ currentPlan.targetFurnaceName || '-' }} + 状态:{{ statusLabel(currentPlan.status) }} + + + + + + {{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }} + + + + + + + + + + + + 解绑 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/klp-wms/src/main/java/com/klp/controller/WmsAnnealOverviewController.java b/klp-wms/src/main/java/com/klp/controller/WmsAnnealOverviewController.java new file mode 100644 index 00000000..552aa789 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/controller/WmsAnnealOverviewController.java @@ -0,0 +1,31 @@ +package com.klp.controller; + +import com.klp.common.core.domain.R; +import com.klp.domain.vo.anneal.WmsAnnealOverviewVo; +import com.klp.service.IWmsAnnealOverviewService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 退火总览 + * + * @author klp + * @date 2026-03-14 + */ +@RequiredArgsConstructor +@RestController +@RequestMapping("/wms/anneal/overview") +public class WmsAnnealOverviewController { + + private final IWmsAnnealOverviewService overviewService; + + /** + * 总览数据 + */ + @GetMapping + public R getOverview() { + return R.ok(overviewService.queryOverview()); + } +} diff --git a/klp-wms/src/main/java/com/klp/controller/WmsAnnealPerformanceController.java b/klp-wms/src/main/java/com/klp/controller/WmsAnnealPerformanceController.java new file mode 100644 index 00000000..ced6d9ef --- /dev/null +++ b/klp-wms/src/main/java/com/klp/controller/WmsAnnealPerformanceController.java @@ -0,0 +1,31 @@ +package com.klp.controller; + +import com.klp.common.core.domain.R; +import com.klp.domain.bo.WmsAnnealPerformanceBo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceVo; +import com.klp.service.IWmsAnnealPerformanceService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 炉火实绩 + * + * @author klp + * @date 2026-03-14 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/wms/anneal/performance") +public class WmsAnnealPerformanceController { + + private final IWmsAnnealPerformanceService performanceService; + + @GetMapping + public R getPerformance(WmsAnnealPerformanceBo bo) { + return R.ok(performanceService.queryPerformance(bo)); + } +} diff --git a/klp-wms/src/main/java/com/klp/controller/WmsFurnaceController.java b/klp-wms/src/main/java/com/klp/controller/WmsFurnaceController.java new file mode 100644 index 00000000..85129d5a --- /dev/null +++ b/klp-wms/src/main/java/com/klp/controller/WmsFurnaceController.java @@ -0,0 +1,103 @@ +package com.klp.controller; + +import com.klp.common.annotation.Log; +import com.klp.common.annotation.RepeatSubmit; +import com.klp.common.core.controller.BaseController; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.domain.R; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.validate.AddGroup; +import com.klp.common.core.validate.EditGroup; +import com.klp.common.enums.BusinessType; +import com.klp.domain.bo.WmsFurnaceBo; +import com.klp.domain.bo.WmsFurnaceBusyBo; +import com.klp.domain.bo.WmsFurnaceStatusBo; +import com.klp.domain.vo.WmsFurnaceVo; +import com.klp.service.IWmsFurnaceService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; + +/** + * 退火炉管理 + * + * @author klp + * @date 2026-03-14 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/wms/anneal/furnace") +public class WmsFurnaceController extends BaseController { + + private final IWmsFurnaceService iWmsFurnaceService; + + /** + * 查询炉子列表 + */ + @GetMapping("/list") + public TableDataInfo list(WmsFurnaceBo bo, PageQuery pageQuery) { + return iWmsFurnaceService.queryPageList(bo, pageQuery); + } + + /** + * 获取炉子详情 + */ + @GetMapping("/{furnaceId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long furnaceId) { + return R.ok(iWmsFurnaceService.queryById(furnaceId)); + } + + /** + * 新增炉子 + */ + @Log(title = "退火炉", businessType = BusinessType.INSERT) + @RepeatSubmit + @PostMapping("/add") + public R add(@Validated(AddGroup.class) @RequestBody WmsFurnaceBo bo) { + return toAjax(iWmsFurnaceService.insertByBo(bo)); + } + + /** + * 修改炉子 + */ + @Log(title = "退火炉", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/edit") + public R edit(@Validated(EditGroup.class) @RequestBody WmsFurnaceBo bo) { + return toAjax(iWmsFurnaceService.updateByBo(bo)); + } + + /** + * 启用停用 + */ + @Log(title = "退火炉", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/status") + public R changeStatus(@Validated @RequestBody WmsFurnaceStatusBo bo) { + return toAjax(iWmsFurnaceService.updateStatus(bo.getFurnaceId(), bo.getStatus())); + } + + /** + * 置忙/置闲 + */ + @Log(title = "退火炉", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/busy") + public R changeBusy(@Validated @RequestBody WmsFurnaceBusyBo bo) { + return toAjax(iWmsFurnaceService.updateBusy(bo.getFurnaceId(), bo.getBusyFlag())); + } + + /** + * 删除炉子 + */ + @Log(title = "退火炉", businessType = BusinessType.DELETE) + @DeleteMapping("/{furnaceIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] furnaceIds) { + return toAjax(iWmsFurnaceService.deleteWithValidByIds(Arrays.asList(furnaceIds), true)); + } +} diff --git a/klp-wms/src/main/java/com/klp/controller/WmsFurnacePlanController.java b/klp-wms/src/main/java/com/klp/controller/WmsFurnacePlanController.java new file mode 100644 index 00000000..ff568d2a --- /dev/null +++ b/klp-wms/src/main/java/com/klp/controller/WmsFurnacePlanController.java @@ -0,0 +1,145 @@ +package com.klp.controller; + +import com.klp.common.annotation.Log; +import com.klp.common.annotation.RepeatSubmit; +import com.klp.common.core.controller.BaseController; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.domain.R; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.validate.AddGroup; +import com.klp.common.core.validate.EditGroup; +import com.klp.common.enums.BusinessType; +import com.klp.domain.bo.WmsFurnacePlanBo; +import com.klp.domain.bo.WmsFurnacePlanCoilBo; +import com.klp.domain.bo.WmsFurnacePlanInFurnaceBo; +import com.klp.domain.bo.WmsFurnacePlanLocationBo; +import com.klp.domain.bo.WmsFurnacePlanStatusBo; +import com.klp.domain.vo.WmsFurnacePlanCoilVo; +import com.klp.domain.vo.WmsFurnacePlanVo; +import com.klp.service.IWmsFurnacePlanService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 退火计划 + * + * @author klp + * @date 2026-03-14 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/wms/anneal/plan") +public class WmsFurnacePlanController extends BaseController { + + private final IWmsFurnacePlanService iWmsFurnacePlanService; + + /** + * 查询退火计划列表 + */ + @GetMapping("/list") + public TableDataInfo list(WmsFurnacePlanBo bo, PageQuery pageQuery) { + return iWmsFurnacePlanService.queryPageList(bo, pageQuery); + } + + /** + * 查询退火计划详情 + */ + @GetMapping("/{planId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long planId) { + return R.ok(iWmsFurnacePlanService.queryById(planId)); + } + + /** + * 新增退火计划 + */ + @Log(title = "退火计划", businessType = BusinessType.INSERT) + @RepeatSubmit + @PostMapping("/add") + public R add(@Validated(AddGroup.class) @RequestBody WmsFurnacePlanBo bo) { + return toAjax(iWmsFurnacePlanService.insertByBo(bo)); + } + + /** + * 修改退火计划 + */ + @Log(title = "退火计划", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/edit") + public R edit(@Validated(EditGroup.class) @RequestBody WmsFurnacePlanBo bo) { + return toAjax(iWmsFurnacePlanService.updateByBo(bo)); + } + + /** + * 更新计划状态 + */ + @Log(title = "退火计划", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/status") + public R changeStatus(@Validated @RequestBody WmsFurnacePlanStatusBo bo) { + return toAjax(iWmsFurnacePlanService.updateStatus(bo.getPlanId(), bo.getStatus())); + } + + /** + * 入炉 + */ + @Log(title = "退火计划", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/in-furnace") + public R inFurnace(@Validated @RequestBody WmsFurnacePlanInFurnaceBo bo) { + return toAjax(iWmsFurnacePlanService.inFurnace(bo.getPlanId())); + } + + /** + * 完成退火 + */ + @Log(title = "退火计划", businessType = BusinessType.UPDATE) + @RepeatSubmit + @PutMapping("/complete") + public R complete(@Validated @RequestBody WmsFurnacePlanLocationBo bo) { + return toAjax(iWmsFurnacePlanService.completePlan(bo.getPlanId(), bo.getLocations())); + } + + /** + * 删除退火计划 + */ + @Log(title = "退火计划", businessType = BusinessType.DELETE) + @DeleteMapping("/{planIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] planIds) { + return toAjax(iWmsFurnacePlanService.deleteWithValidByIds(Arrays.asList(planIds), true)); + } + + /** + * 查询计划钢卷列表 + */ + @GetMapping("/coil/list") + public R> listCoils(@NotNull(message = "计划ID不能为空") @RequestParam Long planId) { + return R.ok(iWmsFurnacePlanService.queryPlanCoils(planId)); + } + + /** + * 绑定钢卷 + */ + @Log(title = "退火计划钢卷", businessType = BusinessType.INSERT) + @RepeatSubmit + @PostMapping("/coil/bind") + public R bindCoils(@Validated(AddGroup.class) @RequestBody WmsFurnacePlanCoilBo bo) { + return toAjax(iWmsFurnacePlanService.bindPlanCoils(bo)); + } + + /** + * 解绑钢卷 + */ + @Log(title = "退火计划钢卷", businessType = BusinessType.DELETE) + @RepeatSubmit + @DeleteMapping("/coil/unbind") + public R unbindCoil(@Validated @RequestBody WmsFurnacePlanCoilBo bo) { + return toAjax(iWmsFurnacePlanService.unbindPlanCoil(bo)); + } +} diff --git a/klp-wms/src/main/java/com/klp/domain/WmsFurnace.java b/klp-wms/src/main/java/com/klp/domain/WmsFurnace.java new file mode 100644 index 00000000..a01bcb55 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/WmsFurnace.java @@ -0,0 +1,59 @@ +package com.klp.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 退火炉信息表对象 wms_furnace + * + * @author klp + * @date 2026-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("wms_furnace") +public class WmsFurnace extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 炉子ID + */ + @TableId(value = "furnace_id") + private Long furnaceId; + + /** + * 炉编号 + */ + private String furnaceCode; + + /** + * 名称 + */ + private String furnaceName; + + /** + * 是否忙碌(0=否,1=是) + */ + private Integer busyFlag; + + /** + * 状态(0=停用,1=启用) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; +} diff --git a/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlan.java b/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlan.java new file mode 100644 index 00000000..aedcd38f --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlan.java @@ -0,0 +1,71 @@ +package com.klp.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 退火计划对象 wms_furnace_plan + * + * @author klp + * @date 2026-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("wms_furnace_plan") +public class WmsFurnacePlan extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 计划ID + */ + @TableId(value = "plan_id") + private Long planId; + + /** + * 计划号 + */ + private String planNo; + + /** + * 计划开始时间 + */ + private Date planStartTime; + + /** + * 实际开始时间 + */ + private Date actualStartTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 目标炉子ID + */ + private Long targetFurnaceId; + + /** + * 计划状态(0草稿 1已下发 2执行中 3已完成 4已取消) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; +} diff --git a/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java b/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java new file mode 100644 index 00000000..0e412227 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java @@ -0,0 +1,44 @@ +package com.klp.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 退火计划钢卷关系对象 wms_furnace_plan_coil + * + * @author klp + * @date 2026-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("wms_furnace_plan_coil") +public class WmsFurnacePlanCoil extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 计划钢卷ID + */ + @TableId(value = "plan_coil_id") + private Long planCoilId; + + /** + * 计划ID + */ + private Long planId; + + /** + * 钢卷ID + */ + private Long coilId; + + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsAnnealPerformanceBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsAnnealPerformanceBo.java new file mode 100644 index 00000000..8fe83675 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsAnnealPerformanceBo.java @@ -0,0 +1,31 @@ +package com.klp.domain.bo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * 炉火实绩查询业务对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealPerformanceBo { + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + private Long targetFurnaceId; + + private String planNo; + + private String enterCoilNo; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceBo.java new file mode 100644 index 00000000..e7093c74 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceBo.java @@ -0,0 +1,57 @@ +package com.klp.domain.bo; + +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 退火炉业务对象 wms_furnace + * + * @author klp + * @date 2026-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WmsFurnaceBo extends BaseEntity { + + /** + * 炉子ID + */ + private Long furnaceId; + + /** + * 炉编号 + */ + @NotBlank(message = "炉编号不能为空") + private String furnaceCode; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空") + private String furnaceName; + + /** + * 是否忙碌(0=否,1=是) + */ + private Integer busyFlag; + + /** + * 状态(0=停用,1=启用) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 批量操作ID + */ + @NotNull(message = "主键不能为空", groups = {com.klp.common.core.validate.EditGroup.class}) + private Long[] furnaceIds; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceBusyBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceBusyBo.java new file mode 100644 index 00000000..2bc03970 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceBusyBo.java @@ -0,0 +1,21 @@ +package com.klp.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 退火炉忙碌状态更新业务对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsFurnaceBusyBo { + + @NotNull(message = "炉子ID不能为空") + private Long furnaceId; + + @NotNull(message = "忙碌状态不能为空") + private Integer busyFlag; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanBo.java new file mode 100644 index 00000000..86cafad5 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanBo.java @@ -0,0 +1,70 @@ +package com.klp.domain.bo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 退火计划业务对象 wms_furnace_plan + * + * @author klp + * @date 2026-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WmsFurnacePlanBo extends BaseEntity { + + /** + * 计划ID + */ + private Long planId; + + /** + * 计划号 + */ + @NotBlank(message = "计划号不能为空") + private String planNo; + + /** + * 计划开始时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date planStartTime; + + /** + * 实际开始时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date actualStartTime; + + /** + * 结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + /** + * 目标炉子ID + */ + @NotNull(message = "目标炉子不能为空") + private Long targetFurnaceId; + + /** + * 计划状态(0草稿 1已下发 2执行中 3已完成 4已取消) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java new file mode 100644 index 00000000..a099dc07 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java @@ -0,0 +1,49 @@ +package com.klp.domain.bo; + +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; + +/** + * 退火计划钢卷关系业务对象 wms_furnace_plan_coil + * + * @author klp + * @date 2026-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WmsFurnacePlanCoilBo extends BaseEntity { + + /** + * 计划钢卷ID + */ + private Long planCoilId; + + /** + * 计划ID + */ + @NotNull(message = "计划ID不能为空") + private Long planId; + + /** + * 钢卷ID + */ + private Long coilId; + + /** + * 钢卷ID列表(逗号分隔) + */ + private String coilIds; + + /** + * 入场钢卷号(逗号分隔) + */ + private String enterCoilNos; + + /** + * 当前钢卷号(逗号分隔) + */ + private String currentCoilNos; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanInFurnaceBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanInFurnaceBo.java new file mode 100644 index 00000000..e1b39bd9 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanInFurnaceBo.java @@ -0,0 +1,18 @@ +package com.klp.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 退火计划入炉业务对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsFurnacePlanInFurnaceBo { + + @NotNull(message = "计划ID不能为空") + private Long planId; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanLocationBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanLocationBo.java new file mode 100644 index 00000000..d991f049 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanLocationBo.java @@ -0,0 +1,23 @@ +package com.klp.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 退火计划库位分配业务对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsFurnacePlanLocationBo { + + @NotNull(message = "计划ID不能为空") + private Long planId; + + @NotEmpty(message = "库位分配不能为空") + private List locations; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanLocationItemBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanLocationItemBo.java new file mode 100644 index 00000000..d060ff86 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanLocationItemBo.java @@ -0,0 +1,21 @@ +package com.klp.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 退火计划钢卷库位分配项 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsFurnacePlanLocationItemBo { + + @NotNull(message = "钢卷ID不能为空") + private Long coilId; + + @NotNull(message = "实际库位不能为空") + private Long actualWarehouseId; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanStatusBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanStatusBo.java new file mode 100644 index 00000000..bc50279e --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanStatusBo.java @@ -0,0 +1,21 @@ +package com.klp.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 退火计划状态更新业务对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsFurnacePlanStatusBo { + + @NotNull(message = "计划ID不能为空") + private Long planId; + + @NotNull(message = "状态不能为空") + private Integer status; +} diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceStatusBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceStatusBo.java new file mode 100644 index 00000000..d50e908e --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnaceStatusBo.java @@ -0,0 +1,21 @@ +package com.klp.domain.bo; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 退火炉启用状态更新业务对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsFurnaceStatusBo { + + @NotNull(message = "炉子ID不能为空") + private Long furnaceId; + + @NotNull(message = "状态不能为空") + private Integer status; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsAnnealFurnaceOverviewVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsAnnealFurnaceOverviewVo.java new file mode 100644 index 00000000..aa28f125 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsAnnealFurnaceOverviewVo.java @@ -0,0 +1,37 @@ +package com.klp.domain.vo; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 退火炉总览信息 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealFurnaceOverviewVo { + + private Long furnaceId; + private String furnaceCode; + private String furnaceName; + private Integer busyFlag; + private Integer status; + + /** + * 正在执行的计划 + */ + private WmsFurnacePlanVo runningPlan; + + /** + * 当前炉内钢卷 + */ + private List runningCoils; + + /** + * 计划结束时间(用于倒计时) + */ + private Date planEndTime; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsAnnealOverviewStatsVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsAnnealOverviewStatsVo.java new file mode 100644 index 00000000..9ebab732 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsAnnealOverviewStatsVo.java @@ -0,0 +1,43 @@ +package com.klp.domain.vo; + +import lombok.Data; + +/** + * 退火总览统计信息 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealOverviewStatsVo { + + /** + * 当前计划数 + */ + private Long planCount; + + /** + * 炉子总数 + */ + private Long furnaceTotal; + + /** + * 炉子忙碌数 + */ + private Long furnaceBusy; + + /** + * 待退火钢卷数 + */ + private Long pendingCoilCount; + + /** + * 今日已完成计划数 + */ + private Long todayFinishedPlanCount; + + /** + * 今日已完成钢卷数 + */ + private Long todayFinishedCoilCount; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java new file mode 100644 index 00000000..b5dcd58e --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java @@ -0,0 +1,33 @@ +package com.klp.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 退火计划钢卷关系视图对象 wms_furnace_plan_coil + * + * @author klp + * @date 2026-03-14 + */ +@Data +@ExcelIgnoreUnannotated +public class WmsFurnacePlanCoilVo { + + @ExcelProperty(value = "计划钢卷ID") + private Long planCoilId; + + @ExcelProperty(value = "计划ID") + private Long planId; + + @ExcelProperty(value = "钢卷ID") + private Long coilId; + + @ExcelProperty(value = "入场钢卷号") + private String enterCoilNo; + + @ExcelProperty(value = "创建时间") + private Date createTime; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanVo.java new file mode 100644 index 00000000..777691d9 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanVo.java @@ -0,0 +1,51 @@ +package com.klp.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 退火计划视图对象 wms_furnace_plan + * + * @author klp + * @date 2026-03-14 + */ +@Data +@ExcelIgnoreUnannotated +public class WmsFurnacePlanVo { + + @ExcelProperty(value = "计划ID") + private Long planId; + + @ExcelProperty(value = "计划号") + private String planNo; + + @ExcelProperty(value = "计划开始时间") + private Date planStartTime; + + @ExcelProperty(value = "实际开始时间") + private Date actualStartTime; + + @ExcelProperty(value = "结束时间") + private Date endTime; + + @ExcelProperty(value = "目标炉子ID") + private Long targetFurnaceId; + + @ExcelProperty(value = "目标炉子名称") + private String targetFurnaceName; + + @ExcelProperty(value = "计划状态") + private Integer status; + + @ExcelProperty(value = "备注") + private String remark; + + @ExcelProperty(value = "创建时间") + private Date createTime; + + private List coilIds; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnaceVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnaceVo.java new file mode 100644 index 00000000..1f3b9773 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnaceVo.java @@ -0,0 +1,39 @@ +package com.klp.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 退火炉视图对象 wms_furnace + * + * @author klp + * @date 2026-03-14 + */ +@Data +@ExcelIgnoreUnannotated +public class WmsFurnaceVo { + + @ExcelProperty(value = "炉子ID") + private Long furnaceId; + + @ExcelProperty(value = "炉编号") + private String furnaceCode; + + @ExcelProperty(value = "名称") + private String furnaceName; + + @ExcelProperty(value = "是否忙碌") + private Integer busyFlag; + + @ExcelProperty(value = "状态") + private Integer status; + + @ExcelProperty(value = "备注") + private String remark; + + @ExcelProperty(value = "创建时间") + private Date createTime; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealFurnaceStatusVo.java b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealFurnaceStatusVo.java new file mode 100644 index 00000000..df72d3c1 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealFurnaceStatusVo.java @@ -0,0 +1,33 @@ +package com.klp.domain.vo.anneal; + +import lombok.Data; + +import java.util.Date; + +/** + * 退火炉状态视图对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealFurnaceStatusVo { + + private Long furnaceId; + + private String furnaceCode; + + private String furnaceName; + + private Integer busyFlag; + + private Integer status; + + private Long currentPlanId; + + private String currentPlanNo; + + private Date planEndTime; + + private Long coilCount; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealOverviewVo.java b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealOverviewVo.java new file mode 100644 index 00000000..bebd8e7e --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealOverviewVo.java @@ -0,0 +1,31 @@ +package com.klp.domain.vo.anneal; + +import lombok.Data; + +import java.util.List; + +/** + * 退火总览视图对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealOverviewVo { + + private Long totalPlanCount; + + private Long furnaceTotal; + + private Long furnaceBusyCount; + + private Long pendingCoilCount; + + private Long todayDonePlanCount; + + private Long todayDoneCoilCount; + + private List furnaces; + + private List planQueue; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceDetailVo.java b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceDetailVo.java new file mode 100644 index 00000000..82f8e4d6 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceDetailVo.java @@ -0,0 +1,36 @@ +package com.klp.domain.vo.anneal; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 炉火实绩明细视图对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealPerformanceDetailVo { + + private Long planId; + + private String planNo; + + private Long targetFurnaceId; + + private String targetFurnaceName; + + private Date actualStartTime; + + private Date endTime; + + private Long coilId; + + private String enterCoilNo; + + private String currentCoilNo; + + private BigDecimal netWeight; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceSummaryVo.java b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceSummaryVo.java new file mode 100644 index 00000000..dfb0a5c5 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceSummaryVo.java @@ -0,0 +1,21 @@ +package com.klp.domain.vo.anneal; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 炉火实绩统计视图对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealPerformanceSummaryVo { + + private Long planCount; + + private Long coilCount; + + private BigDecimal totalWeight; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceVo.java b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceVo.java new file mode 100644 index 00000000..e19664db --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPerformanceVo.java @@ -0,0 +1,19 @@ +package com.klp.domain.vo.anneal; + +import lombok.Data; + +import java.util.List; + +/** + * 炉火实绩返回视图对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealPerformanceVo { + + private WmsAnnealPerformanceSummaryVo summary; + + private List details; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPlanQueueVo.java b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPlanQueueVo.java new file mode 100644 index 00000000..6f2e42e2 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/anneal/WmsAnnealPlanQueueVo.java @@ -0,0 +1,33 @@ +package com.klp.domain.vo.anneal; + +import lombok.Data; + +import java.util.Date; + +/** + * 退火计划队列视图对象 + * + * @author klp + * @date 2026-03-14 + */ +@Data +public class WmsAnnealPlanQueueVo { + + private Long planId; + + private String planNo; + + private Long targetFurnaceId; + + private String targetFurnaceName; + + private Integer status; + + private Date planStartTime; + + private Date actualStartTime; + + private Date endTime; + + private Long coilCount; +} diff --git a/klp-wms/src/main/java/com/klp/mapper/WmsAnnealOverviewMapper.java b/klp-wms/src/main/java/com/klp/mapper/WmsAnnealOverviewMapper.java new file mode 100644 index 00000000..fb628100 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/mapper/WmsAnnealOverviewMapper.java @@ -0,0 +1,33 @@ +package com.klp.mapper; + +import com.klp.domain.vo.anneal.WmsAnnealFurnaceStatusVo; +import com.klp.domain.vo.anneal.WmsAnnealPlanQueueVo; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 退火总览Mapper接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface WmsAnnealOverviewMapper { + + Long selectTotalPlanCount(); + + Long selectFurnaceTotal(); + + Long selectFurnaceBusyCount(); + + Long selectPendingCoilCount(); + + Long selectTodayDonePlanCount(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd); + + Long selectTodayDoneCoilCount(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd); + + List selectFurnaceStatusList(); + + List selectPlanQueueList(); +} diff --git a/klp-wms/src/main/java/com/klp/mapper/WmsAnnealPerformanceMapper.java b/klp-wms/src/main/java/com/klp/mapper/WmsAnnealPerformanceMapper.java new file mode 100644 index 00000000..7398e324 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/mapper/WmsAnnealPerformanceMapper.java @@ -0,0 +1,20 @@ +package com.klp.mapper; + +import com.klp.domain.bo.WmsAnnealPerformanceBo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceDetailVo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceSummaryVo; + +import java.util.List; + +/** + * 炉火实绩Mapper + * + * @author klp + * @date 2026-03-14 + */ +public interface WmsAnnealPerformanceMapper { + + WmsAnnealPerformanceSummaryVo selectSummary(WmsAnnealPerformanceBo bo); + + List selectDetails(WmsAnnealPerformanceBo bo); +} diff --git a/klp-wms/src/main/java/com/klp/mapper/WmsFurnaceMapper.java b/klp-wms/src/main/java/com/klp/mapper/WmsFurnaceMapper.java new file mode 100644 index 00000000..888f68d6 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/mapper/WmsFurnaceMapper.java @@ -0,0 +1,14 @@ +package com.klp.mapper; + +import com.klp.common.core.mapper.BaseMapperPlus; +import com.klp.domain.WmsFurnace; +import com.klp.domain.vo.WmsFurnaceVo; + +/** + * 退火炉Mapper接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface WmsFurnaceMapper extends BaseMapperPlus { +} diff --git a/klp-wms/src/main/java/com/klp/mapper/WmsFurnacePlanCoilMapper.java b/klp-wms/src/main/java/com/klp/mapper/WmsFurnacePlanCoilMapper.java new file mode 100644 index 00000000..8d9193b1 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/mapper/WmsFurnacePlanCoilMapper.java @@ -0,0 +1,14 @@ +package com.klp.mapper; + +import com.klp.common.core.mapper.BaseMapperPlus; +import com.klp.domain.WmsFurnacePlanCoil; +import com.klp.domain.vo.WmsFurnacePlanCoilVo; + +/** + * 退火计划钢卷关系Mapper接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface WmsFurnacePlanCoilMapper extends BaseMapperPlus { +} diff --git a/klp-wms/src/main/java/com/klp/mapper/WmsFurnacePlanMapper.java b/klp-wms/src/main/java/com/klp/mapper/WmsFurnacePlanMapper.java new file mode 100644 index 00000000..318ddf7e --- /dev/null +++ b/klp-wms/src/main/java/com/klp/mapper/WmsFurnacePlanMapper.java @@ -0,0 +1,14 @@ +package com.klp.mapper; + +import com.klp.common.core.mapper.BaseMapperPlus; +import com.klp.domain.WmsFurnacePlan; +import com.klp.domain.vo.WmsFurnacePlanVo; + +/** + * 退火计划Mapper接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface WmsFurnacePlanMapper extends BaseMapperPlus { +} diff --git a/klp-wms/src/main/java/com/klp/service/IWmsAnnealOverviewService.java b/klp-wms/src/main/java/com/klp/service/IWmsAnnealOverviewService.java new file mode 100644 index 00000000..7c398ccb --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/IWmsAnnealOverviewService.java @@ -0,0 +1,14 @@ +package com.klp.service; + +import com.klp.domain.vo.anneal.WmsAnnealOverviewVo; + +/** + * 退火总览Service接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface IWmsAnnealOverviewService { + + WmsAnnealOverviewVo queryOverview(); +} diff --git a/klp-wms/src/main/java/com/klp/service/IWmsAnnealPerformanceService.java b/klp-wms/src/main/java/com/klp/service/IWmsAnnealPerformanceService.java new file mode 100644 index 00000000..7f021e38 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/IWmsAnnealPerformanceService.java @@ -0,0 +1,15 @@ +package com.klp.service; + +import com.klp.domain.bo.WmsAnnealPerformanceBo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceVo; + +/** + * 炉火实绩Service接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface IWmsAnnealPerformanceService { + + WmsAnnealPerformanceVo queryPerformance(WmsAnnealPerformanceBo bo); +} diff --git a/klp-wms/src/main/java/com/klp/service/IWmsFurnacePlanService.java b/klp-wms/src/main/java/com/klp/service/IWmsFurnacePlanService.java new file mode 100644 index 00000000..a6ebed77 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/IWmsFurnacePlanService.java @@ -0,0 +1,44 @@ +package com.klp.service; + +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.page.TableDataInfo; +import com.klp.domain.bo.WmsFurnacePlanBo; +import com.klp.domain.bo.WmsFurnacePlanCoilBo; +import com.klp.domain.vo.WmsFurnacePlanCoilVo; +import com.klp.domain.vo.WmsFurnacePlanVo; + +import java.util.Collection; +import java.util.List; + +/** + * 退火计划Service接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface IWmsFurnacePlanService { + + WmsFurnacePlanVo queryById(Long planId); + + TableDataInfo queryPageList(WmsFurnacePlanBo bo, PageQuery pageQuery); + + List queryList(WmsFurnacePlanBo bo); + + Boolean insertByBo(WmsFurnacePlanBo bo); + + Boolean updateByBo(WmsFurnacePlanBo bo); + + Boolean updateStatus(Long planId, Integer status); + + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + List queryPlanCoils(Long planId); + + Boolean bindPlanCoils(WmsFurnacePlanCoilBo bo); + + Boolean unbindPlanCoil(WmsFurnacePlanCoilBo bo); + + Boolean inFurnace(Long planId); + + Boolean completePlan(Long planId, List locations); +} diff --git a/klp-wms/src/main/java/com/klp/service/IWmsFurnaceService.java b/klp-wms/src/main/java/com/klp/service/IWmsFurnaceService.java new file mode 100644 index 00000000..6227b7d7 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/IWmsFurnaceService.java @@ -0,0 +1,34 @@ +package com.klp.service; + +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.page.TableDataInfo; +import com.klp.domain.bo.WmsFurnaceBo; +import com.klp.domain.vo.WmsFurnaceVo; + +import java.util.Collection; +import java.util.List; + +/** + * 退火炉Service接口 + * + * @author klp + * @date 2026-03-14 + */ +public interface IWmsFurnaceService { + + WmsFurnaceVo queryById(Long furnaceId); + + TableDataInfo queryPageList(WmsFurnaceBo bo, PageQuery pageQuery); + + List queryList(WmsFurnaceBo bo); + + Boolean insertByBo(WmsFurnaceBo bo); + + Boolean updateByBo(WmsFurnaceBo bo); + + Boolean updateStatus(Long furnaceId, Integer status); + + Boolean updateBusy(Long furnaceId, Integer busyFlag); + + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsAnnealOverviewServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsAnnealOverviewServiceImpl.java new file mode 100644 index 00000000..1ad5afc4 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsAnnealOverviewServiceImpl.java @@ -0,0 +1,43 @@ +package com.klp.service.impl; + +import com.klp.domain.vo.anneal.WmsAnnealOverviewVo; +import com.klp.mapper.WmsAnnealOverviewMapper; +import com.klp.service.IWmsAnnealOverviewService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * 退火总览Service业务层处理 + * + * @author klp + * @date 2026-03-14 + */ +@RequiredArgsConstructor +@Service +public class WmsAnnealOverviewServiceImpl implements IWmsAnnealOverviewService { + + private final WmsAnnealOverviewMapper overviewMapper; + + @Override + public WmsAnnealOverviewVo queryOverview() { + WmsAnnealOverviewVo vo = new WmsAnnealOverviewVo(); + vo.setTotalPlanCount(overviewMapper.selectTotalPlanCount()); + vo.setFurnaceTotal(overviewMapper.selectFurnaceTotal()); + vo.setFurnaceBusyCount(overviewMapper.selectFurnaceBusyCount()); + vo.setPendingCoilCount(overviewMapper.selectPendingCoilCount()); + + LocalDate today = LocalDate.now(); + Date dayStart = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant()); + Date dayEnd = Date.from(today.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant()); + + vo.setTodayDonePlanCount(overviewMapper.selectTodayDonePlanCount(dayStart, dayEnd)); + vo.setTodayDoneCoilCount(overviewMapper.selectTodayDoneCoilCount(dayStart, dayEnd)); + vo.setFurnaces(overviewMapper.selectFurnaceStatusList()); + vo.setPlanQueue(overviewMapper.selectPlanQueueList()); + return vo; + } +} diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsAnnealPerformanceServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsAnnealPerformanceServiceImpl.java new file mode 100644 index 00000000..293c15c0 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsAnnealPerformanceServiceImpl.java @@ -0,0 +1,35 @@ +package com.klp.service.impl; + +import com.klp.domain.bo.WmsAnnealPerformanceBo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceDetailVo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceSummaryVo; +import com.klp.domain.vo.anneal.WmsAnnealPerformanceVo; +import com.klp.mapper.WmsAnnealPerformanceMapper; +import com.klp.service.IWmsAnnealPerformanceService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 炉火实绩Service业务层处理 + * + * @author klp + * @date 2026-03-14 + */ +@RequiredArgsConstructor +@Service +public class WmsAnnealPerformanceServiceImpl implements IWmsAnnealPerformanceService { + + private final WmsAnnealPerformanceMapper performanceMapper; + + @Override + public WmsAnnealPerformanceVo queryPerformance(WmsAnnealPerformanceBo bo) { + WmsAnnealPerformanceSummaryVo summary = performanceMapper.selectSummary(bo); + List details = performanceMapper.selectDetails(bo); + WmsAnnealPerformanceVo vo = new WmsAnnealPerformanceVo(); + vo.setSummary(summary); + vo.setDetails(details); + return vo; + } +} diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java new file mode 100644 index 00000000..bdd680c0 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java @@ -0,0 +1,431 @@ +package com.klp.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.exception.ServiceException; +import com.klp.common.utils.StringUtils; +import com.klp.domain.WmsFurnace; +import com.klp.domain.WmsFurnacePlan; +import com.klp.domain.WmsFurnacePlanCoil; +import com.klp.domain.WmsMaterialCoil; +import com.klp.domain.WmsActualWarehouse; +import com.klp.domain.bo.WmsFurnacePlanBo; +import com.klp.domain.bo.WmsFurnacePlanCoilBo; +import com.klp.domain.vo.WmsFurnacePlanCoilVo; +import com.klp.domain.vo.WmsFurnacePlanVo; +import com.klp.mapper.WmsActualWarehouseMapper; +import com.klp.mapper.WmsFurnaceMapper; +import com.klp.mapper.WmsFurnacePlanCoilMapper; +import com.klp.mapper.WmsFurnacePlanMapper; +import com.klp.mapper.WmsMaterialCoilMapper; +import com.klp.service.IWmsFurnacePlanService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 退火计划Service业务层处理 + * + * @author klp + * @date 2026-03-14 + */ +@RequiredArgsConstructor +@Service +public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService { + + private final WmsFurnacePlanMapper baseMapper; + private final WmsFurnacePlanCoilMapper planCoilMapper; + private final WmsFurnaceMapper furnaceMapper; + private final WmsMaterialCoilMapper materialCoilMapper; + private final WmsActualWarehouseMapper actualWarehouseMapper; + + @Override + public WmsFurnacePlanVo queryById(Long planId) { + WmsFurnacePlanVo plan = baseMapper.selectVoById(planId); + if (plan != null) { + plan.setCoilIds(queryPlanCoils(planId).stream() + .map(WmsFurnacePlanCoilVo::getCoilId) + .collect(Collectors.toList())); + fillFurnaceNames(java.util.Collections.singletonList(plan)); + } + return plan; + } + + @Override + public TableDataInfo queryPageList(WmsFurnacePlanBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + fillFurnaceNames(result.getRecords()); + return TableDataInfo.build(result); + } + + @Override + public List queryList(WmsFurnacePlanBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + List list = baseMapper.selectVoList(lqw); + fillFurnaceNames(list); + return list; + } + + private LambdaQueryWrapper buildQueryWrapper(WmsFurnacePlanBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getPlanNo()), WmsFurnacePlan::getPlanNo, bo.getPlanNo()); + lqw.eq(bo.getTargetFurnaceId() != null, WmsFurnacePlan::getTargetFurnaceId, bo.getTargetFurnaceId()); + lqw.eq(bo.getStatus() != null, WmsFurnacePlan::getStatus, bo.getStatus()); + lqw.ge(bo.getPlanStartTime() != null, WmsFurnacePlan::getPlanStartTime, bo.getPlanStartTime()); + lqw.orderByDesc(WmsFurnacePlan::getPlanStartTime); + return lqw; + } + + private void fillFurnaceNames(List plans) { + if (plans == null || plans.isEmpty()) { + return; + } + List furnaceIds = plans.stream() + .map(WmsFurnacePlanVo::getTargetFurnaceId) + .filter(id -> id != null) + .distinct() + .collect(Collectors.toList()); + if (furnaceIds.isEmpty()) { + return; + } + List furnaces = furnaceMapper.selectBatchIds(furnaceIds); + java.util.Map nameMap = furnaces.stream() + .collect(Collectors.toMap(WmsFurnace::getFurnaceId, WmsFurnace::getFurnaceName, (a, b) -> a)); + plans.forEach(plan -> { + if (plan.getTargetFurnaceId() != null) { + plan.setTargetFurnaceName(nameMap.get(plan.getTargetFurnaceId())); + } + }); + } + + @Override + public Boolean insertByBo(WmsFurnacePlanBo bo) { + WmsFurnacePlan add = BeanUtil.toBean(bo, WmsFurnacePlan.class); + validEntityBeforeSave(add, true); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setPlanId(add.getPlanId()); + } + return flag; + } + + @Override + public Boolean updateByBo(WmsFurnacePlanBo bo) { + WmsFurnacePlan update = BeanUtil.toBean(bo, WmsFurnacePlan.class); + validEntityBeforeSave(update, false); + return baseMapper.updateById(update) > 0; + } + + private void validEntityBeforeSave(WmsFurnacePlan entity, boolean isNew) { + LambdaQueryWrapper planNoQuery = Wrappers.lambdaQuery(); + planNoQuery.eq(WmsFurnacePlan::getPlanNo, entity.getPlanNo()); + if (!isNew) { + planNoQuery.ne(WmsFurnacePlan::getPlanId, entity.getPlanId()); + } + if (baseMapper.selectCount(planNoQuery) > 0) { + throw new ServiceException("计划号已存在"); + } + + WmsFurnace furnace = furnaceMapper.selectById(entity.getTargetFurnaceId()); + if (furnace == null || furnace.getDelFlag() != null && furnace.getDelFlag() == 1) { + throw new ServiceException("目标炉子不存在"); + } + } + + @Override + public Boolean updateStatus(Long planId, Integer status) { + WmsFurnacePlan plan = baseMapper.selectById(planId); + if (plan == null) { + throw new ServiceException("计划不存在"); + } + WmsFurnacePlan update = new WmsFurnacePlan(); + update.setPlanId(planId); + update.setStatus(status); + boolean updated = baseMapper.updateById(update) > 0; + if (updated && plan.getTargetFurnaceId() != null) { + if (status != null && (status == 2)) { + updateFurnaceBusy(plan.getTargetFurnaceId(), 1); + } + if (status != null && (status == 3 || status == 4)) { + updateFurnaceBusy(plan.getTargetFurnaceId(), 0); + } + } + return updated; + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid && ids != null && !ids.isEmpty()) { + for (Long planId : ids) { + if (planCoilMapper.selectCount(Wrappers.lambdaQuery() + .eq(WmsFurnacePlanCoil::getPlanId, planId)) > 0) { + throw new ServiceException("计划下存在钢卷,请先解绑"); + } + } + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + @Override + public List queryPlanCoils(Long planId) { + List list = planCoilMapper.selectVoList(Wrappers.lambdaQuery() + .eq(WmsFurnacePlanCoil::getPlanId, planId)); + if (list == null || list.isEmpty()) { + return list; + } + List coilIds = list.stream() + .map(WmsFurnacePlanCoilVo::getCoilId) + .filter(id -> id != null) + .distinct() + .collect(Collectors.toList()); + if (coilIds.isEmpty()) { + return list; + } + java.util.Map enterNoMap = materialCoilMapper.selectBatchIds(coilIds).stream() + .collect(Collectors.toMap(WmsMaterialCoil::getCoilId, WmsMaterialCoil::getEnterCoilNo, (a, b) -> a)); + list.forEach(item -> item.setEnterCoilNo(enterNoMap.get(item.getCoilId()))); + return list; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean bindPlanCoils(WmsFurnacePlanCoilBo bo) { + if (bo.getPlanId() == null) { + throw new ServiceException("计划ID不能为空"); + } + List coilIds = parseCoilIds(bo); + if (coilIds.isEmpty()) { + throw new ServiceException("请至少选择一条钢卷"); + } + WmsFurnacePlan plan = ensurePlanExist(bo.getPlanId()); + if (plan.getStatus() != null && plan.getStatus() == 2) { + throw new ServiceException("计划进行中,无法再领料"); + } + + for (Long coilId : coilIds) { + if (planCoilMapper.selectCount(Wrappers.lambdaQuery() + .eq(WmsFurnacePlanCoil::getPlanId, bo.getPlanId()) + .eq(WmsFurnacePlanCoil::getCoilId, coilId)) > 0) { + continue; + } + WmsFurnacePlanCoil entity = new WmsFurnacePlanCoil(); + entity.setPlanId(bo.getPlanId()); + entity.setCoilId(coilId); + planCoilMapper.insert(entity); + } + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean unbindPlanCoil(WmsFurnacePlanCoilBo bo) { + if (bo.getPlanId() == null || bo.getCoilId() == null) { + throw new ServiceException("计划ID和钢卷ID不能为空"); + } + return planCoilMapper.delete(Wrappers.lambdaQuery() + .eq(WmsFurnacePlanCoil::getPlanId, bo.getPlanId()) + .eq(WmsFurnacePlanCoil::getCoilId, bo.getCoilId())) > 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean inFurnace(Long planId) { + WmsFurnacePlan plan = baseMapper.selectById(planId); + if (plan == null) { + throw new ServiceException("计划不存在"); + } + if (plan.getActualStartTime() != null) { + throw new ServiceException("计划已入炉"); + } + if (planCoilMapper.selectCount(Wrappers.lambdaQuery() + .eq(WmsFurnacePlanCoil::getPlanId, planId)) <= 0) { + throw new ServiceException("计划未绑定钢卷"); + } + + Date now = new Date(); + Date endTime = new Date(now.getTime() + 48L * 60 * 60 * 1000); + + WmsFurnacePlan update = new WmsFurnacePlan(); + update.setPlanId(planId); + update.setActualStartTime(now); + update.setEndTime(endTime); + update.setStatus(2); + baseMapper.updateById(update); + + updateFurnaceBusy(plan.getTargetFurnaceId(), 1); + + List coils = queryPlanCoils(planId); + for (WmsFurnacePlanCoilVo coil : coils) { + releaseActualWarehouse(coil.getCoilId()); + } + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean completePlan(Long planId, List locations) { + WmsFurnacePlan plan = baseMapper.selectById(planId); + if (plan == null) { + throw new ServiceException("计划不存在"); + } + if (plan.getStatus() == null || plan.getStatus() != 2) { + throw new ServiceException("计划未进行中,无法完成"); + } + List coils = queryPlanCoils(planId); + if (coils == null || coils.isEmpty()) { + throw new ServiceException("计划未绑定钢卷"); + } + if (locations == null || locations.isEmpty()) { + throw new ServiceException("请先分配实际库位"); + } + java.util.Map locationMap = locations.stream() + .collect(Collectors.toMap(com.klp.domain.bo.WmsFurnacePlanLocationItemBo::getCoilId, + com.klp.domain.bo.WmsFurnacePlanLocationItemBo::getActualWarehouseId, (a, b) -> a)); + for (WmsFurnacePlanCoilVo coil : coils) { + Long targetLocation = locationMap.get(coil.getCoilId()); + if (targetLocation == null) { + throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未分配库位"); + } + occupyActualWarehouse(coil.getCoilId(), targetLocation); + } + Date now = new Date(); + WmsFurnacePlan update = new WmsFurnacePlan(); + update.setPlanId(planId); + update.setStatus(3); + update.setEndTime(now); + baseMapper.updateById(update); + updateFurnaceBusy(plan.getTargetFurnaceId(), 0); + return true; + } + + private void releaseActualWarehouse(Long coilId) { + WmsMaterialCoil coil = materialCoilMapper.selectById(coilId); + if (coil == null) { + return; + } + Long actualWarehouseId = coil.getActualWarehouseId(); + if (actualWarehouseId != null) { + WmsActualWarehouse warehouse = new WmsActualWarehouse(); + warehouse.setActualWarehouseId(actualWarehouseId); + warehouse.setIsEnabled(1); + actualWarehouseMapper.updateById(warehouse); + } + WmsMaterialCoil updateCoil = new WmsMaterialCoil(); + updateCoil.setCoilId(coilId); + updateCoil.setActualWarehouseId(null); + materialCoilMapper.updateById(updateCoil); + } + + private void occupyActualWarehouse(Long coilId, Long actualWarehouseId) { + if (actualWarehouseId == null) { + throw new ServiceException("实际库位不能为空"); + } + WmsActualWarehouse warehouse = actualWarehouseMapper.selectById(actualWarehouseId); + if (warehouse == null || warehouse.getDelFlag() != null && warehouse.getDelFlag() == 1) { + throw new ServiceException("实际库位不存在"); + } + if (warehouse.getIsEnabled() != null && warehouse.getIsEnabled() == 0) { + throw new ServiceException("实际库位已被占用"); + } + WmsActualWarehouse updateWarehouse = new WmsActualWarehouse(); + updateWarehouse.setActualWarehouseId(actualWarehouseId); + updateWarehouse.setIsEnabled(0); + actualWarehouseMapper.updateById(updateWarehouse); + + WmsMaterialCoil updateCoil = new WmsMaterialCoil(); + updateCoil.setCoilId(coilId); + updateCoil.setActualWarehouseId(actualWarehouseId); + materialCoilMapper.updateById(updateCoil); + } + + private List parseCoilIds(WmsFurnacePlanCoilBo bo) { + List coilIds = new ArrayList<>(); + if (bo.getCoilId() != null) { + coilIds.add(bo.getCoilId()); + } + if (StringUtils.isNotBlank(bo.getCoilIds())) { + String[] parts = bo.getCoilIds().split(","); + for (String part : parts) { + if (StringUtils.isNotBlank(part)) { + coilIds.add(Long.parseLong(part.trim())); + } + } + } + if (StringUtils.isNotBlank(bo.getEnterCoilNos())) { + coilIds.addAll(resolveCoilIdsByEnterNos(bo.getEnterCoilNos())); + } + if (StringUtils.isNotBlank(bo.getCurrentCoilNos())) { + coilIds.addAll(resolveCoilIdsByCurrentNos(bo.getCurrentCoilNos())); + } + return coilIds.stream().distinct().collect(Collectors.toList()); + } + + private List resolveCoilIdsByEnterNos(String enterCoilNos) { + List nos = splitCommaValues(enterCoilNos); + if (nos.isEmpty()) { + return new ArrayList<>(); + } + return materialCoilMapper.selectList(Wrappers.lambdaQuery() + .in(WmsMaterialCoil::getEnterCoilNo, nos) + .eq(WmsMaterialCoil::getDelFlag, 0)) + .stream() + .map(WmsMaterialCoil::getCoilId) + .collect(Collectors.toList()); + } + + private List resolveCoilIdsByCurrentNos(String currentCoilNos) { + List nos = splitCommaValues(currentCoilNos); + if (nos.isEmpty()) { + return new ArrayList<>(); + } + return materialCoilMapper.selectList(Wrappers.lambdaQuery() + .in(WmsMaterialCoil::getCurrentCoilNo, nos) + .eq(WmsMaterialCoil::getDelFlag, 0)) + .stream() + .map(WmsMaterialCoil::getCoilId) + .collect(Collectors.toList()); + } + + private List splitCommaValues(String values) { + List result = new ArrayList<>(); + if (StringUtils.isBlank(values)) { + return result; + } + String[] parts = values.split(","); + for (String part : parts) { + if (StringUtils.isNotBlank(part)) { + result.add(part.trim()); + } + } + return result; + } + + private WmsFurnacePlan ensurePlanExist(Long planId) { + WmsFurnacePlan plan = baseMapper.selectById(planId); + if (plan == null) { + throw new ServiceException("计划不存在"); + } + return plan; + } + + private void updateFurnaceBusy(Long furnaceId, Integer busyFlag) { + if (furnaceId == null) { + return; + } + WmsFurnace update = new WmsFurnace(); + update.setFurnaceId(furnaceId); + update.setBusyFlag(busyFlag); + furnaceMapper.updateById(update); + } +} diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsFurnaceServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnaceServiceImpl.java new file mode 100644 index 00000000..f991f5b2 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnaceServiceImpl.java @@ -0,0 +1,114 @@ +package com.klp.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.exception.ServiceException; +import com.klp.common.utils.StringUtils; +import com.klp.domain.WmsFurnace; +import com.klp.domain.bo.WmsFurnaceBo; +import com.klp.domain.vo.WmsFurnaceVo; +import com.klp.mapper.WmsFurnaceMapper; +import com.klp.service.IWmsFurnaceService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +/** + * 退火炉Service业务层处理 + * + * @author klp + * @date 2026-03-14 + */ +@RequiredArgsConstructor +@Service +public class WmsFurnaceServiceImpl implements IWmsFurnaceService { + + private final WmsFurnaceMapper baseMapper; + + @Override + public WmsFurnaceVo queryById(Long furnaceId) { + return baseMapper.selectVoById(furnaceId); + } + + @Override + public TableDataInfo queryPageList(WmsFurnaceBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + @Override + public List queryList(WmsFurnaceBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(WmsFurnaceBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getFurnaceCode()), WmsFurnace::getFurnaceCode, bo.getFurnaceCode()); + lqw.like(StringUtils.isNotBlank(bo.getFurnaceName()), WmsFurnace::getFurnaceName, bo.getFurnaceName()); + lqw.eq(bo.getStatus() != null, WmsFurnace::getStatus, bo.getStatus()); + lqw.eq(bo.getBusyFlag() != null, WmsFurnace::getBusyFlag, bo.getBusyFlag()); + lqw.orderByAsc(WmsFurnace::getFurnaceCode); + return lqw; + } + + @Override + public Boolean insertByBo(WmsFurnaceBo bo) { + WmsFurnace add = BeanUtil.toBean(bo, WmsFurnace.class); + validEntityBeforeSave(add, true); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setFurnaceId(add.getFurnaceId()); + } + return flag; + } + + @Override + public Boolean updateByBo(WmsFurnaceBo bo) { + WmsFurnace update = BeanUtil.toBean(bo, WmsFurnace.class); + validEntityBeforeSave(update, false); + return baseMapper.updateById(update) > 0; + } + + private void validEntityBeforeSave(WmsFurnace entity, boolean isNew) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(WmsFurnace::getFurnaceCode, entity.getFurnaceCode()); + if (!isNew) { + lqw.ne(WmsFurnace::getFurnaceId, entity.getFurnaceId()); + } + if (baseMapper.selectCount(lqw) > 0) { + throw new ServiceException("炉编号已存在"); + } + } + + @Override + public Boolean updateStatus(Long furnaceId, Integer status) { + WmsFurnace update = new WmsFurnace(); + update.setFurnaceId(furnaceId); + update.setStatus(status); + return baseMapper.updateById(update) > 0; + } + + @Override + public Boolean updateBusy(Long furnaceId, Integer busyFlag) { + WmsFurnace update = new WmsFurnace(); + update.setFurnaceId(furnaceId); + update.setBusyFlag(busyFlag); + return baseMapper.updateById(update) > 0; + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid && ids != null && !ids.isEmpty()) { + // 暂无额外校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} diff --git a/klp-wms/src/main/resources/mapper/WmsAnnealOverviewMapper.xml b/klp-wms/src/main/resources/mapper/WmsAnnealOverviewMapper.xml new file mode 100644 index 00000000..3b52c367 --- /dev/null +++ b/klp-wms/src/main/resources/mapper/WmsAnnealOverviewMapper.xml @@ -0,0 +1,92 @@ + + + + + + SELECT COUNT(1) + FROM wms_furnace_plan + WHERE del_flag = 0 + + + + SELECT COUNT(1) + FROM wms_furnace + WHERE del_flag = 0 AND status = 1 + + + + SELECT COUNT(1) + FROM wms_furnace + WHERE del_flag = 0 AND status = 1 AND busy_flag = 1 + + + + SELECT COUNT(1) + FROM wms_furnace_plan_coil pc + INNER JOIN wms_furnace_plan p ON p.plan_id = pc.plan_id AND p.del_flag = 0 + WHERE pc.del_flag = 0 AND p.status IN (0, 1) + + + + SELECT COUNT(1) + FROM wms_furnace_plan + WHERE del_flag = 0 AND status = 3 + AND end_time >= #{dayStart} AND end_time < #{dayEnd} + + + + SELECT COUNT(1) + FROM wms_furnace_plan_coil pc + INNER JOIN wms_furnace_plan p ON p.plan_id = pc.plan_id AND p.del_flag = 0 + WHERE pc.del_flag = 0 AND p.status = 3 + AND p.end_time >= #{dayStart} AND p.end_time < #{dayEnd} + + + + SELECT f.furnace_id AS furnaceId, + f.furnace_code AS furnaceCode, + f.furnace_name AS furnaceName, + f.busy_flag AS busyFlag, + f.status AS status, + p.plan_id AS currentPlanId, + p.plan_no AS currentPlanNo, + p.end_time AS planEndTime, + COALESCE(pc.coil_count, 0) AS coilCount + FROM wms_furnace f + LEFT JOIN wms_furnace_plan p + ON p.target_furnace_id = f.furnace_id + AND p.del_flag = 0 + AND p.status = 2 + LEFT JOIN ( + SELECT plan_id, COUNT(1) AS coil_count + FROM wms_furnace_plan_coil + WHERE del_flag = 0 + GROUP BY plan_id + ) pc ON pc.plan_id = p.plan_id + WHERE f.del_flag = 0 + ORDER BY f.furnace_code + + + + SELECT p.plan_id AS planId, + p.plan_no AS planNo, + p.target_furnace_id AS targetFurnaceId, + f.furnace_name AS targetFurnaceName, + p.status AS status, + p.plan_start_time AS planStartTime, + p.actual_start_time AS actualStartTime, + p.end_time AS endTime, + COALESCE(pc.coil_count, 0) AS coilCount + FROM wms_furnace_plan p + LEFT JOIN wms_furnace f ON f.furnace_id = p.target_furnace_id + LEFT JOIN ( + SELECT plan_id, COUNT(1) AS coil_count + FROM wms_furnace_plan_coil + WHERE del_flag = 0 + GROUP BY plan_id + ) pc ON pc.plan_id = p.plan_id + WHERE p.del_flag = 0 + ORDER BY p.status ASC, p.plan_start_time ASC + + + diff --git a/klp-wms/src/main/resources/mapper/WmsAnnealPerformanceMapper.xml b/klp-wms/src/main/resources/mapper/WmsAnnealPerformanceMapper.xml new file mode 100644 index 00000000..6e490b79 --- /dev/null +++ b/klp-wms/src/main/resources/mapper/WmsAnnealPerformanceMapper.xml @@ -0,0 +1,54 @@ + + + + + + + p.del_flag = 0 + + AND p.actual_start_time =]]> #{startTime} + + + AND p.actual_start_time #{endTime} + + + AND p.target_furnace_id = #{targetFurnaceId} + + + AND p.plan_no LIKE CONCAT('%', #{planNo}, '%') + + + AND mc.enter_coil_no LIKE CONCAT('%', #{enterCoilNo}, '%') + + + + + + SELECT COUNT(DISTINCT p.plan_id) AS plan_count, + COUNT(mc.coil_id) AS coil_count, + COALESCE(SUM(mc.net_weight), 0) AS total_weight + FROM wms_furnace_plan p + INNER JOIN wms_furnace_plan_coil pc ON pc.plan_id = p.plan_id AND pc.del_flag = 0 + INNER JOIN wms_material_coil mc ON mc.coil_id = pc.coil_id AND mc.del_flag = 0 + + + + + SELECT p.plan_id AS planId, + p.plan_no AS planNo, + p.target_furnace_id AS targetFurnaceId, + f.furnace_name AS targetFurnaceName, + p.actual_start_time AS actualStartTime, + p.end_time AS endTime, + mc.coil_id AS coilId, + mc.enter_coil_no AS enterCoilNo, + mc.current_coil_no AS currentCoilNo, + mc.net_weight AS netWeight + FROM wms_furnace_plan p + INNER JOIN wms_furnace_plan_coil pc ON pc.plan_id = p.plan_id AND pc.del_flag = 0 + INNER JOIN wms_material_coil mc ON mc.coil_id = pc.coil_id AND mc.del_flag = 0 + LEFT JOIN wms_furnace f ON f.furnace_id = p.target_furnace_id + + ORDER BY p.actual_start_time DESC, p.plan_no DESC + + diff --git a/klp-wms/src/main/resources/mapper/WmsFurnacePlanMapper.xml b/klp-wms/src/main/resources/mapper/WmsFurnacePlanMapper.xml new file mode 100644 index 00000000..fb695cae --- /dev/null +++ b/klp-wms/src/main/resources/mapper/WmsFurnacePlanMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + SELECT p.plan_id, + p.plan_no, + p.plan_start_time, + p.actual_start_time, + p.end_time, + p.target_furnace_id, + p.status, + p.remark, + p.create_time + FROM wms_furnace_plan p + ${ew.customSqlSegment} + + + + SELECT p.plan_id, + p.plan_no, + p.plan_start_time, + p.actual_start_time, + p.end_time, + p.target_furnace_id, + p.status, + p.remark, + p.create_time + FROM wms_furnace_plan p + ${ew.customSqlSegment} + + +