From f3b789aa66233b0a56384f885af0614c70a2e7cb Mon Sep 17 00:00:00 2001 From: liyongde <1419499670@qq.com> Date: Thu, 25 May 2023 18:50:38 +0800 Subject: [PATCH] =?UTF-8?q?add:=20=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nladmin-system/doc/wms.xls | Bin 302080 -> 340480 bytes .../org/nl/common/utils/SecurityUtils.java | 2 +- .../org/nl/common/utils/dto/CurrentUser.java | 2 +- .../service/dept/impl/SysDeptServiceImpl.java | 2 +- .../secutiry/impl/OnlineUserService.java | 2 +- .../dao/SchBaseVehiclematerialgroup.java | 29 ++- .../dto/SchBaseVehiclematerialgroupDto.java | 3 + ...chBaseVehiclematerialgroupServiceImpl.java | 11 +- .../service/impl/SchBasePointServiceImpl.java | 17 +- .../controller/SchBaseTaskController.java | 18 ++ .../sch/task/service/ISchBaseTaskService.java | 23 ++ .../task/service/dao/SchBaseTaskconfig.java | 3 + .../service/dto/SchBaseTaskconfigDto.java | 3 + .../service/impl/SchBaseTaskServiceImpl.java | 98 +++++++- .../nl/wms/sch/task_manage/AbstractTask.java | 148 ++++++++--- .../wms/sch/task_manage/AutoCreateTask.java | 6 +- .../enums/GroupBindMaterialStatusEnum.java | 42 ++++ .../task_manage/enums/GroupStatusEnum.java | 23 ++ .../task_manage/enums/PointStatusEnum.java | 21 ++ .../task_manage/enums/TaskDirectionEnum.java | 47 ++++ .../wms/sch/task_manage/task/TaskFactory.java | 19 +- .../sch/task_manage/task/core/TaskStatus.java | 4 +- .../sch/task_manage/task/tasks/HNMLTask.java | 84 ------- .../sch/task_manage/task/tasks/HNQKTask.java | 6 - .../task_manage/task/tasks/hn/HNMLTask.java | 206 +++++++++++++++ .../task_manage/task/tasks/hn/HNQKTask.java | 139 +++++++++++ .../task_manage/task/tasks/yz/YZQLTask.java | 185 ++++++++++++++ .../org/nl/wms/utils/MyEventListener.java | 20 ++ .../main/java/org/nl/wms/utils/PointUtil.java | 20 ++ .../java/org/nl/enums/GetEnumOnSqlTest.java | 30 +++ .../src/views/wms/pdm/workerorder/index.vue | 8 +- nladmin-ui/src/views/wms/sch/group/index.vue | 7 +- nladmin-ui/src/views/wms/sch/point/index.vue | 13 +- nladmin-ui/src/views/wms/sch/task/index.vue | 236 +++++++++++------- .../src/views/wms/sch/task/schBaseTask.js | 17 +- 35 files changed, 1230 insertions(+), 264 deletions(-) create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupBindMaterialStatusEnum.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupStatusEnum.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/PointStatusEnum.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/TaskDirectionEnum.java delete mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNMLTask.java delete mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNQKTask.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNMLTask.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNQKTask.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/yz/YZQLTask.java create mode 100644 nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/MyEventListener.java create mode 100644 nladmin-system/nlsso-server/src/test/java/org/nl/enums/GetEnumOnSqlTest.java diff --git a/nladmin-system/doc/wms.xls b/nladmin-system/doc/wms.xls index b01cdb9246ed8c3b39db9f937bdd65af3bb6d7ca..995b66a619ffe91eabebbb03a197641d0b58283f 100644 GIT binary patch delta 101277 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 No^04e^@Es({|CVx|JVQk delta 69630 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 KRy4*#L;o-SU$zzi diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/SecurityUtils.java b/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/SecurityUtils.java index b434369..67f854f 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/SecurityUtils.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/SecurityUtils.java @@ -49,7 +49,7 @@ public class SecurityUtils { * @return 系统用户名称 */ public static String getCurrentNickName() { - return getCurrentUser().getPresonName(); + return getCurrentUser().getPreson_name(); } /** diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/dto/CurrentUser.java b/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/dto/CurrentUser.java index 440752f..c305dc5 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/dto/CurrentUser.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/common/utils/dto/CurrentUser.java @@ -22,7 +22,7 @@ public class CurrentUser implements Serializable { //账号 private String username; //姓名 - private String presonName; + private String preson_name; //用户详细信息 private SysUser user; diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java b/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java index 93ea266..36a46bb 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/dept/impl/SysDeptServiceImpl.java @@ -168,7 +168,7 @@ public class SysDeptServiceImpl extends ServiceImpl impl dept.setDept_id(IdUtil.getStringId()); CurrentUser user = SecurityUtils.getCurrentUser(); dept.setCreate_id(user.getId()); - dept.setCreate_name(user.getPresonName()); + dept.setCreate_name(user.getPreson_name()); dept.setCreate_time(new Date()); this.save(dept); // 清理缓存 diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java b/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java index b63ef55..0b6a493 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/secutiry/impl/OnlineUserService.java @@ -244,7 +244,7 @@ public class OnlineUserService { CurrentUser user = new CurrentUser(); user.setId(userInfo.getUser_id()); user.setUsername(userInfo.getUsername()); - user.setPresonName((userInfo.getPerson_name())); + user.setPreson_name((userInfo.getPerson_name())); user.setUser(userInfo); user.setPermissions(permissionList); diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java index 2dfc2ad..4f71d0a 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java @@ -8,28 +8,33 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; -import java.math.BigDecimal; import java.io.Serializable; +import java.math.BigDecimal; /** -* @description / -* @author lyd -* @date 2023-05-16 -**/ + * @author lyd + * @description / + * @date 2023-05-16 + **/ @Data @EqualsAndHashCode(callSuper = false) @TableName("sch_base_vehiclematerialgroup") public class SchBaseVehiclematerialgroup implements Serializable { - private static final long serialVersionUID = 1L; + @TableId(value = "group_id", type = IdType.NONE) + @ApiModelProperty(value = "组盘标识") + private String group_id; - @TableId(value = "vehicle_code", type = IdType.NONE) @ApiModelProperty(value = "载具编码") private String vehicle_code; @ApiModelProperty(value = "物料标识") private String material_id; + @ApiModelProperty(value = "载具类型") + private String vehicle_type; + + @ApiModelProperty(value = "子载具编码") private String child_vehicle_code; @@ -52,10 +57,10 @@ public class SchBaseVehiclematerialgroup implements Serializable { private String instorage_time; @ApiModelProperty(value = "静置时间(分钟)") - private BigDecimal standing_time; + private Integer standing_time; @ApiModelProperty(value = "物料数量") - private BigDecimal material_qty; + private Integer material_qty; @ApiModelProperty(value = "物料重量") private BigDecimal material_weight; @@ -64,7 +69,7 @@ public class SchBaseVehiclematerialgroup implements Serializable { private String workorder_code; @ApiModelProperty(value = "组盘次数") - private BigDecimal group_number; + private Integer group_number; @ApiModelProperty(value = "任务编码") private String task_code; @@ -108,6 +113,9 @@ public class SchBaseVehiclematerialgroup implements Serializable { @ApiModelProperty(value = "备注") private String remark; + @ApiModelProperty(value = "1:待绑定,2:已绑定,3:已解绑") + private String group_bind_material_status; + @ApiModelProperty(value = "是否删除") private Boolean is_delete; @@ -129,6 +137,7 @@ public class SchBaseVehiclematerialgroup implements Serializable { @ApiModelProperty(value = "修改时间") private String update_time; + @TableField(exist = false) private String material_name; @TableField(exist = false) diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dto/SchBaseVehiclematerialgroupDto.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dto/SchBaseVehiclematerialgroupDto.java index d4e5509..9da91f8 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dto/SchBaseVehiclematerialgroupDto.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dto/SchBaseVehiclematerialgroupDto.java @@ -12,6 +12,9 @@ import java.io.Serializable; @Data public class SchBaseVehiclematerialgroupDto implements Serializable { + /** 组盘id */ + private String group_id; + /** 载具编码 */ private String vehicle_code; diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java index a830d83..f729ac1 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java @@ -2,6 +2,7 @@ package org.nl.wms.sch.group.service.impl; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -41,15 +42,11 @@ public class SchBaseVehiclematerialgroupServiceImpl extends ServiceImpl() - .eq(SchBaseVehiclematerialgroup::getVehicle_code, entity.getVehicle_code()) - .eq(SchBaseVehiclematerialgroup::getIs_delete, false)); - Assert.isNull(schBaseVehiclematerialgroup, "载具编码[" + entity.getVehicle_code() + "]已存在"); - String currentUserId = SecurityUtils.getCurrentUserId(); String nickName = SecurityUtils.getCurrentNickName(); String now = DateUtil.now(); + entity.setGroup_id(IdUtil.getSnowflake(1,1).nextIdStr()); entity.setCreate_id(currentUserId); entity.setCreate_name(nickName); entity.setCreate_time(now); @@ -61,16 +58,12 @@ public class SchBaseVehiclematerialgroupServiceImpl extends ServiceImpl lam = new LambdaQueryWrapper<>(); lam.like(ObjectUtil.isNotEmpty(blurry), SchBasePoint::getPoint_code, blurry) .or(ObjectUtil.isNotEmpty(blurry), lam1 -> lam1.like(SchBasePoint::getPoint_name, blurry)) @@ -58,7 +58,12 @@ public class SchBasePointServiceImpl extends ServiceImpl slam.isNull(SchBasePoint::getIng_task_code) + .or() + .eq(SchBasePoint::getIng_task_code, "")) + .and(lock_type, slam -> slam.isNotNull(SchBasePoint::getIng_task_code) + .ne(SchBasePoint::getIng_task_code, "")); IPage pages = new Page<>(page.getPage() + 1, page.getSize()); pointMapper.selectPage(pages, lam); // 可以存放的载具类型 @@ -122,8 +127,10 @@ public class SchBasePointServiceImpl extends ServiceImpl(HttpStatus.OK); } + @GetMapping("/taskStatusList") + @Log("任务状态下拉框") + @ApiOperation("任务状态下拉框") + @SaIgnore + //@SaCheckPermission("@el.check('schBaseTask:list')") + public ResponseEntity getTaskStatusList(){ + return new ResponseEntity<>(TableDataInfo.build(schBaseTaskService.getTaskStatusList()),HttpStatus.OK); + } + @PostMapping("/apply") @Log("新增任务管理") @ApiOperation("新增任务管理") @@ -78,4 +87,13 @@ public class SchBaseTaskController { return new ResponseEntity<>(HttpStatus.CREATED); } + @PutMapping("/operation") + @Log("任务操作") + @ApiOperation("任务操作") + //@SaCheckPermission("task:edit") + public ResponseEntity update(@RequestBody Map map) { + schBaseTaskService.operation(map); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + } diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/ISchBaseTaskService.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/ISchBaseTaskService.java index 457c585..b04e381 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/ISchBaseTaskService.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/ISchBaseTaskService.java @@ -1,5 +1,6 @@ package org.nl.wms.sch.task.service; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import org.nl.common.domain.query.PageQuery; @@ -67,6 +68,15 @@ public interface ISchBaseTaskService extends IService { */ List findUnFinishTasksByTaskConfig(String config_code, String task_code); + /** + * 根据任务配置查询同台设备未完成的任务列表 + * + * @param config_code 任务配置 + * @param device_code 设备 + * @return + */ + List findUnFinishTasksByTaskConfig(String config_code, String device_code, String direction); + List findTasksByTaskStatus(String config_code, TaskStatus status); @@ -76,4 +86,17 @@ public interface ISchBaseTaskService extends IService { * @param param / */ void apply(JSONObject param); + + /** + * 获取任务状态下拉框 + * @return + */ + JSONArray getTaskStatusList(); + + /** + * 任务操作 + * + * @param param + */ + void operation(Map param); } diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dao/SchBaseTaskconfig.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dao/SchBaseTaskconfig.java index 45caffb..cd1885b 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dao/SchBaseTaskconfig.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dao/SchBaseTaskconfig.java @@ -43,6 +43,9 @@ public class SchBaseTaskconfig implements Serializable { @ApiModelProperty(value = "任务类型") private String task_type; + @ApiModelProperty(value = "任务方向") + private String task_direction; + @ApiModelProperty(value = "优先级") private String priority; diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dto/SchBaseTaskconfigDto.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dto/SchBaseTaskconfigDto.java index d146744..a559dbd 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dto/SchBaseTaskconfigDto.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/dto/SchBaseTaskconfigDto.java @@ -33,6 +33,9 @@ public class SchBaseTaskconfigDto implements Serializable { /** 优先级 */ private String priority; + /** 任务方向 **/ + private String task_direction; + /** 允许最大任务生成数 */ private Integer task_create_max_num; diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/impl/SchBaseTaskServiceImpl.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/impl/SchBaseTaskServiceImpl.java index d42b4e7..58238d8 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/impl/SchBaseTaskServiceImpl.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task/service/impl/SchBaseTaskServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -14,8 +15,8 @@ import org.nl.common.domain.query.PageQuery; import org.nl.common.exception.BadRequestException; import org.nl.common.utils.SecurityUtils; import org.nl.wms.sch.task.service.ISchBaseTaskService; -import org.nl.wms.sch.task.service.dao.mapper.SchBaseTaskMapper; import org.nl.wms.sch.task.service.dao.SchBaseTask; +import org.nl.wms.sch.task.service.dao.mapper.SchBaseTaskMapper; import org.nl.wms.sch.task.service.dao.mapper.SchBaseTaskconfigMapper; import org.nl.wms.sch.task_manage.AbstractTask; import org.nl.wms.sch.task_manage.task.TaskFactory; @@ -23,9 +24,11 @@ import org.nl.wms.sch.task_manage.task.core.TaskStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * @author lyd @@ -41,6 +44,9 @@ public class SchBaseTaskServiceImpl extends ServiceImpl queryAll(Map whereJson, PageQuery page) { String task_code = ObjectUtil.isNotEmpty(whereJson.get("task_code")) ? whereJson.get("task_code").toString() : null; @@ -48,12 +54,16 @@ public class SchBaseTaskServiceImpl extends ServiceImpl collect = ObjectUtil.isNotEmpty(more_task_status)?Arrays.stream(more_task_status.split(",")).collect(Collectors.toList()):null; LambdaQueryWrapper lam = new LambdaQueryWrapper<>(); lam.eq(ObjectUtil.isNotEmpty(task_code), SchBaseTask::getTask_code, task_code) .eq(ObjectUtil.isNotEmpty(vehicle_code), SchBaseTask::getVehicle_code, vehicle_code) .eq(ObjectUtil.isNotEmpty(point_code), SchBaseTask::getPoint_code1, point_code) .ge(ObjectUtil.isNotEmpty(begin_time), SchBaseTask::getCreate_time, begin_time) - .le(ObjectUtil.isNotEmpty(end_time), SchBaseTask::getCreate_time, end_time); + .le(ObjectUtil.isNotEmpty(end_time), SchBaseTask::getCreate_time, end_time) + .in(ObjectUtil.isNotEmpty(collect), SchBaseTask::getTask_status, collect) + .orderByDesc(SchBaseTask::getUpdate_time); IPage pages = new Page<>(page.getPage() + 1, page.getSize()); schBaseTaskMapper.selectPage(pages, lam); return pages; @@ -104,6 +114,19 @@ public class SchBaseTaskServiceImpl extends ServiceImpl findUnFinishTasksByTaskConfig(String config_code, String device_code, String direction) { + Assert.notNull(config_code, "任务配置编码不能为空!"); + LambdaQueryWrapper lam = new LambdaQueryWrapper<>(); + lam.eq(SchBaseTask::getConfig_code, config_code) + .lt(SchBaseTask::getTask_status, TaskStatus.FINISHED.getCode()) + .eq(direction.equals("1"), SchBaseTask::getPoint_code1, device_code) + .eq(direction.equals("2"), SchBaseTask::getPoint_code2, device_code) + .eq(SchBaseTask::getIs_delete, false); + List schBaseTasks = schBaseTaskMapper.selectList(lam); + return schBaseTasks; + } + @Override public List findTasksByTaskStatus(String config_code, TaskStatus status) { Assert.notNull(config_code, "任务配置编码不能为空!"); @@ -121,7 +144,6 @@ public class SchBaseTaskServiceImpl extends ServiceImpl param) { + String task_code = ObjectUtil.isNotEmpty(param.get("task_code")) ? param.get("task_code").toString() : null; + String method_name = ObjectUtil.isNotEmpty(param.get("method_name")) ? param.get("method_name").toString() : null; + // 根据标识找到任务 + SchBaseTask taskOne = schBaseTaskMapper.selectById(task_code); + if (Integer.parseInt(taskOne.getTask_status()) >= Integer.parseInt(TaskStatus.FINISHED.getCode())) { + throw new BadRequestException("任务已完成或已取消!"); + } + // 根据配置去工厂类获得类对象 + String processing_class = "YZQLTask"; + String message = ""; + // 根据任务类型获取对应的任务操作类 + AbstractTask abstractTask = taskFactory.getTask(processing_class); + // 调用每个任务类的method_name()强制结束方法 + JSONObject result; + switch (method_name) { + case "immediateNotifyAcs": + // + break; + case "forceFinish": // 强制完成 + abstractTask.forceFinish(task_code); + break; + case "cancel": + abstractTask.cancel(task_code); + break; + default: + break; + } + } + } diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AbstractTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AbstractTask.java index ac2e2a3..674ed4b 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AbstractTask.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AbstractTask.java @@ -1,18 +1,24 @@ package org.nl.wms.sch.task_manage; import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSON; +import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; -import org.nl.config.SpringContextHolder; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.nl.common.exception.BadRequestException; +import org.nl.common.utils.SecurityUtils; +import org.nl.wms.pdm.service.IPdmBdWorkorderService; +import org.nl.wms.pdm.service.dao.PdmBdWorkorder; +import org.nl.wms.sch.point.service.ISchBasePointService; +import org.nl.wms.sch.point.service.dao.SchBasePoint; import org.nl.wms.sch.task.service.ISchBaseTaskService; +import org.nl.wms.sch.task.service.ISchBaseTaskconfigService; import org.nl.wms.sch.task.service.dao.SchBaseTask; import org.nl.wms.sch.task.service.dao.SchBaseTaskconfig; -import org.nl.wms.sch.task.service.impl.SchBaseTaskServiceImpl; -import org.nl.wms.sch.task.service.impl.SchBaseTaskconfigServiceImpl; +import org.nl.wms.sch.task_manage.enums.TaskDirectionEnum; import org.nl.wms.sch.task_manage.task.AcsUtil; import org.nl.wms.sch.task_manage.task.core.TaskStatus; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; @@ -23,16 +29,22 @@ import java.util.List; * @date 2023年05月16日 16:42 * @desc desc */ - +@Component public abstract class AbstractTask { @Autowired private ISchBaseTaskService taskService; + @Autowired + private ISchBaseTaskconfigService taskConfigService; + @Autowired + private ISchBasePointService pointService; + @Autowired + private IPdmBdWorkorderService workorderService; /** * 任务创建 * 根据配置生成任务,如并发控制等 */ - protected abstract void create(); + protected abstract void create() throws BadRequestException; /** * 下发 @@ -116,7 +128,7 @@ public abstract class AbstractTask { } private AcsTaskDto setTask(String config_code, AcsTaskDto taskDto) { - SchBaseTaskconfig taskConfig = SpringContextHolder.getBean(SchBaseTaskconfigServiceImpl.class).getById(config_code); + SchBaseTaskconfig taskConfig = taskConfigService.getById(config_code); taskDto.setPriority(taskConfig.getPriority()); taskDto.setTask_type(taskConfig.getAcs_task_type()); taskDto.setRoute_plan_code("normal"); @@ -140,7 +152,7 @@ public abstract class AbstractTask { } - protected abstract void updateStatus(String config_code, TaskStatus status); + protected abstract void updateStatus(String task_code, TaskStatus status); /** * 寻找合适的点位 @@ -150,34 +162,98 @@ public abstract class AbstractTask { protected abstract List findPoints(); - public void apply(JSONObject param) { - String point_code = ""; - String config_code = "HNMLTask"; - //1、校验数据 - SchBaseTaskconfig taskConfig = SpringContextHolder.getBean(SchBaseTaskconfigServiceImpl.class).getById(config_code); - Integer tcmn = taskConfig.getTask_create_max_num(); - SchBaseTaskServiceImpl taskService = SpringContextHolder.getBean(SchBaseTaskServiceImpl.class); - List unFinishTasksByTaskConfig = taskService.findUnFinishTasksByTaskConfig(taskConfig.getConfig_code()); - - Assert.isFalse(unFinishTasksByTaskConfig.size() > tcmn, "该点位申请的任务未完成数已超过上限,无法申请任务"); - - - SchBaseTask task = new SchBaseTask(); - task.setAcs_trace_id(""); - task.setConfig_code(config_code); - task.setCreate_id(""); - task.setCreate_mode(""); - task.setPoint_code1(""); - task.setVehicle_code(""); - task.setTask_status(TaskStatus.APPLY.getCode()); - SpringContextHolder.getBean(SchBaseTaskServiceImpl.class).create(task); - //1、如果是送料,检测载具状态 - //2、送空载具 - //3、叫料 - //4、叫空载具 - - //校验 + /** + * 设置起点或者终点 + * + * @param taskConfig + * @param task + * @param apply_point_code + */ + protected void setTaskPoint(SchBaseTaskconfig taskConfig, SchBaseTask task, String apply_point_code) { + String taskDirection = taskConfig.getTask_direction(); + if (TaskDirectionEnum.SEND.getValue().equals(taskDirection)) { + task.setPoint_code1(apply_point_code); + } else { + task.setPoint_code2(apply_point_code); + } } + /** + * @param task_code 任务标识 + * @return + * @discription 强制结束完成任务 + * @author ldjun + * @created 2020年6月19日 上午10:34:58 + */ + public abstract void forceFinish(String task_code); + + /** + * 取消任务,货物搬回原点 + * + * @param task_code + */ + public abstract void cancel(String task_code); + + + /** + * 申请任务 + * + * @param param + * @throws BadRequestException + */ + public void apply(JSONObject param) throws BadRequestException { + // 申请任务 + SchBaseTask task = new SchBaseTask(); // 任务实体 + String apply_point_code = param.getString("device_code"); + String config_code = "YZQLTask"; + // 1、校验数据 + SchBaseTaskconfig taskConfig = taskConfigService.getById(config_code); + // 最大任务数 + Integer tcmn = taskConfig.getTask_create_max_num(); + List unFinishTasksByTaskConfig = taskService + .findUnFinishTasksByTaskConfig(taskConfig.getConfig_code(), apply_point_code, taskConfig.getTask_direction()); + + Assert.isFalse(unFinishTasksByTaskConfig.size() >= tcmn, "该点位申请的任务未完成数已超过上限,无法申请任务"); + // 获取设备 + SchBasePoint pointObj = pointService.getOne(new LambdaQueryWrapper().eq(SchBasePoint::getPoint_code, apply_point_code)); + // 判断是否校验工单 + if (taskConfig.getIs_check_workorder()) { + // 校验工单 + // 根据设备的父点位编码找到工单设备 + SchBasePoint one = pointService + .getOne(new LambdaQueryWrapper().eq(SchBasePoint::getPoint_code, pointObj.getParent_point_code())); + // 查找当前设备、生产中、 + PdmBdWorkorder workorder = workorderService.getOne(new LambdaQueryWrapper() + .eq(PdmBdWorkorder::getPoint_code, one.getPoint_code()) + .eq(PdmBdWorkorder::getWorkorder_status, "3")); + if (ObjectUtil.isEmpty(workorder)) { + throw new BadRequestException("当前设备工单未生产!"); + } + // 将组盘所需的数据装成jsonObject跟着任务走 + param.put("material_id", workorder.getMaterial_id()); // 物料标识 + param.put("standing_time", workorder.getStanding_time()); // 静置时间 + param.put("workorder_code", workorder.getWorkorder_code()); // 静置时间 + param.put("vehicle_type", workorder.getVehicle_type()); // 载具类型 + // 设置任务数据 + task.setVehicle_type(workorder.getVehicle_type()); + } + // 2、创建申请任务 + task.setAcs_trace_id(""); + task.setConfig_code(config_code); + task.setCreate_id(SecurityUtils.getCurrentUserId()); + task.setCreate_mode(""); + task.setVehicle_code(param.getString("vehicle_code")); + task.setTask_status(TaskStatus.APPLY.getCode()); + // 设置起/终点 + this.setTaskPoint(taskConfig, task, apply_point_code); + task.setExt_group_data(JSONObject.toJSONString(param)); + taskService.create(task); + + // 3、判断是否直接找点下发 + if (taskConfig.getIs_immediate_create()) { + this.create(); + } + } + } diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AutoCreateTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AutoCreateTask.java index 27e829c..b0d2197 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AutoCreateTask.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/AutoCreateTask.java @@ -4,6 +4,7 @@ package org.nl.wms.sch.task_manage; import cn.hutool.core.util.ObjectUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.nl.config.SpringContextHolder; import org.reflections.Reflections; import org.springframework.stereotype.Component; @@ -38,7 +39,10 @@ public class AutoCreateTask { subTypes.forEach(clz -> { // 调用AbstractAcsTask类的每个子类的schedule()方法 try { - Object obj = clz.newInstance(); + Object obj = SpringContextHolder.getBean(clz); +// if (ObjectUtil.isEmpty(obj)) { // 如果spring中获取不到,就用newInstance创建 +// obj = clz.newInstance(); +// } //Method m = obj.getClass().getDeclaredMethod("schedule"); Method m = obj.getClass().getMethod("schedule"); List tasks = (List) m.invoke(obj); diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupBindMaterialStatusEnum.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupBindMaterialStatusEnum.java new file mode 100644 index 0000000..4415856 --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupBindMaterialStatusEnum.java @@ -0,0 +1,42 @@ +package org.nl.wms.sch.task_manage.enums; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.Getter; +import org.nl.config.SpringContextHolder; +import org.nl.system.service.dict.dao.Dict; +import org.nl.system.service.dict.impl.SysDictServiceImpl; + +import java.util.List; + +/** + * @Author: lyd + * @Description: 组盘绑定物料状态枚举 + * @Date: 2023/5/25 + */ +@Getter +public enum GroupBindMaterialStatusEnum { + /** + * 待绑定 + */WAIT_BIND, + /** + * 已绑定 + */BOUND, + /** + * 已解绑 + */UNBOUND; + + private String value; + private String label; + + static { + SysDictServiceImpl bean = SpringContextHolder.getBean(SysDictServiceImpl.class); + List taskDirection = bean.list(new LambdaQueryWrapper() + .eq(Dict::getCode, "group_bind_material_status") + .orderByAsc(Dict::getDict_sort)); + GroupBindMaterialStatusEnum[] values = GroupBindMaterialStatusEnum.values(); + for (int i = 0; i < values.length; i++) { + values[i].value = taskDirection.get(i).getValue(); + values[i].label = taskDirection.get(i).getLabel(); + } + } +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupStatusEnum.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupStatusEnum.java new file mode 100644 index 0000000..1e0c579 --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/GroupStatusEnum.java @@ -0,0 +1,23 @@ +package org.nl.wms.sch.task_manage.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @Author: lyd + * @Description: 组盘状态枚举 + * @Date: 2023/5/24 + */ +@Getter +@AllArgsConstructor +public enum GroupStatusEnum { + OUT_SYSTEM("1", "系统外"), + IN_STORAGE("2", "存储中"), + IN_PROCESS("3", "处理中"), + IN_CARRY("4", "搬运中"), + DISCHARGE_MATERIAL("5", "可放料"), + CABLE_RETRIEVABLE_MATERIAL("6", "可取料"); + + private final String type; + private final String name; +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/PointStatusEnum.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/PointStatusEnum.java new file mode 100644 index 0000000..b324f18 --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/PointStatusEnum.java @@ -0,0 +1,21 @@ +package org.nl.wms.sch.task_manage.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @Author: lyd + * @Description: + * @Date: 2023/5/25 + */ +@Getter +@AllArgsConstructor +public enum PointStatusEnum { + + EMPTY_POINT("1", "空位"), + FULL_POINT("2", "有料"), + EMPTY_VEHICLE("3", "空载具"); + + private final String value; + private final String label; +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/TaskDirectionEnum.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/TaskDirectionEnum.java new file mode 100644 index 0000000..19a6e3e --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/enums/TaskDirectionEnum.java @@ -0,0 +1,47 @@ +package org.nl.wms.sch.task_manage.enums; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.nl.config.SpringContextHolder; +import org.nl.system.service.dict.dao.Dict; +import org.nl.system.service.dict.impl.SysDictServiceImpl; + +import java.util.List; + +/** + * @Author: lyd + * @Description: 任务配置 - 任务去向枚举 + * @Date: 2023/5/25 + */ +@Getter +public enum TaskDirectionEnum { + + /** + * 送货 + */ + SEND, + /** + * 取货 + */ + CALL, + /** + * 移货 + */ + MOVE; + + private String value; + private String label; + + static { + SysDictServiceImpl bean = SpringContextHolder.getBean(SysDictServiceImpl.class); + List taskDirection = bean.list(new LambdaQueryWrapper() + .eq(Dict::getCode, "task_direction") + .orderByAsc(Dict::getDict_sort)); + TaskDirectionEnum[] values = TaskDirectionEnum.values(); + for (int i = 0; i < values.length; i++) { + values[i].value = taskDirection.get(i).getValue(); + values[i].label = taskDirection.get(i).getLabel(); + } + } +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java index a81e91b..e14e40b 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/TaskFactory.java @@ -1,7 +1,11 @@ package org.nl.wms.sch.task_manage.task; import org.nl.wms.sch.task_manage.AbstractTask; -import org.nl.wms.sch.task_manage.task.tasks.HNMLTask; +import org.nl.wms.sch.task_manage.task.tasks.hn.HNMLTask; +import org.nl.wms.sch.task_manage.task.tasks.hn.HNQKTask; +import org.nl.wms.sch.task_manage.task.tasks.yz.YZQLTask; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; /** * @author ldjun @@ -9,14 +13,25 @@ import org.nl.wms.sch.task_manage.task.tasks.HNMLTask; * @date 2023年05月16日 16:42 * @desc desc */ +@Component public class TaskFactory { + + @Autowired + private HNMLTask hnmlTask; + + @Autowired + private YZQLTask yzqlTask; + //使用 getShape 方法获取形状类型的对象 public AbstractTask getTask(String taskType) { if (taskType == null) { return null; } if (taskType.equalsIgnoreCase("HNMLTask")) { - return new HNMLTask(); + return hnmlTask; + } + if (taskType.equalsIgnoreCase("YZQLTask")) { + return yzqlTask; } return null; } diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/core/TaskStatus.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/core/TaskStatus.java index c4ae7c2..a6ad4c5 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/core/TaskStatus.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/core/TaskStatus.java @@ -5,7 +5,7 @@ public enum TaskStatus { CREATED("2", "创建完成", "创建完成"), ISSUED("3", "下发", "下发"), EXECUTING("4", "执行中", "执行中"), - FINISHED("5", "完成", "执行中"), + FINISHED("5", "完成", "完成"), CANCELED("6", "已取消", "已取消"); @@ -42,4 +42,4 @@ public enum TaskStatus { public void setDesc(String desc) { this.desc = desc; } -} \ No newline at end of file +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNMLTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNMLTask.java deleted file mode 100644 index 9d84892..0000000 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNMLTask.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.nl.wms.sch.task_manage.task.tasks; - -import cn.hutool.core.util.ObjectUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.nl.config.SpringContextHolder; -import org.nl.wms.sch.point.service.ISchBasePointService; -import org.nl.wms.sch.point.service.dao.SchBasePoint; -import org.nl.wms.sch.point.service.impl.SchBasePointServiceImpl; -import org.nl.wms.sch.task.service.ISchBaseTaskService; -import org.nl.wms.sch.task.service.dao.SchBaseTask; -import org.nl.wms.sch.task.service.dao.SchBaseTaskconfig; -import org.nl.wms.sch.task.service.impl.SchBaseTaskServiceImpl; -import org.nl.wms.sch.task.service.impl.SchBaseTaskconfigServiceImpl; -import org.nl.wms.sch.task_manage.AbstractTask; -import org.nl.wms.sch.task_manage.task.core.TaskStatus; - -import java.util.List; - -/** - * @author ldjun 混碾满料任务 - * @version 1.0 - * @date 2023年05月16日 16:44 - * @desc desc - */ -public class HNMLTask extends AbstractTask { - private static String TASK_CONFIG_CODE = "HNMLTask"; - - @Override - protected void updateStatus(String task_code, TaskStatus status) { - ISchBaseTaskService taskService = SpringContextHolder.getBean(SchBaseTaskServiceImpl.class); - taskService.updateById(null); - - } - - @Override - protected void create() { - ISchBaseTaskService taskService = SpringContextHolder.getBean(SchBaseTaskServiceImpl.class); - ISchBasePointService pointService = SpringContextHolder.getBean(SchBasePointServiceImpl.class); - List tasks = taskService.findTasksByTaskStatus(TASK_CONFIG_CODE, TaskStatus.APPLY); - - SchBaseTaskconfig taskConfig = SpringContextHolder.getBean(SchBaseTaskconfigServiceImpl.class).getById(TASK_CONFIG_CODE); - for (SchBaseTask task : tasks) { - String[] nextRegionStr = taskConfig.getNext_region_str().split(","); - - - SchBasePoint point = getSchBasePoint(pointService, nextRegionStr); - if (ObjectUtil.isEmpty(point)) continue; - - task.setPoint_code2(point.getPoint_code()); - - - taskService.update(task); - - point.setIng_task_code(task.getTask_code()); - pointService.update(point); - - //下发 - this.renotifyAcs(task); - - } - - } - - private SchBasePoint getSchBasePoint(ISchBasePointService pointService, String[] nextRegionStr) { - for (String nextRegion : nextRegionStr) { - LambdaQueryWrapper lam = new LambdaQueryWrapper<>(); - lam.eq(SchBasePoint::getRegion_code, nextRegion) - .eq(SchBasePoint::getPoint_status, "1"); - SchBasePoint p = pointService.getBaseMapper().selectOne(lam); - if (p != null) return p; - } - return null; - } - - @Override - protected void issue() { - - } - - @Override - protected List findPoints() { - return null; - } -} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNQKTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNQKTask.java deleted file mode 100644 index 5429c90..0000000 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/HNQKTask.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.nl.wms.sch.task_manage.task.tasks;/** -* @Author: lyd -* @Description: -* @Date: 2023/5/19 -*/public class HNQKTask { -} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNMLTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNMLTask.java new file mode 100644 index 0000000..2faeec2 --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNMLTask.java @@ -0,0 +1,206 @@ +package org.nl.wms.sch.task_manage.task.tasks.hn; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.Data; +import org.nl.common.enums.wms.PointStatusEnum; +import org.nl.common.exception.BadRequestException; +import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService; +import org.nl.wms.sch.group.service.dao.SchBaseVehiclematerialgroup; +import org.nl.wms.sch.point.service.ISchBasePointService; +import org.nl.wms.sch.point.service.dao.SchBasePoint; +import org.nl.wms.sch.task.service.ISchBaseTaskService; +import org.nl.wms.sch.task.service.ISchBaseTaskconfigService; +import org.nl.wms.sch.task.service.dao.SchBaseTask; +import org.nl.wms.sch.task.service.dao.SchBaseTaskconfig; +import org.nl.wms.sch.task_manage.AbstractTask; +import org.nl.wms.sch.task_manage.enums.GroupStatusEnum; +import org.nl.wms.sch.task_manage.task.core.TaskStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author ldjun 混碾满料任务 + * @version 1.0 + * @date 2023年05月16日 16:44 + * @desc desc + */ +@Component +@Data +public class HNMLTask extends AbstractTask { + + private static String TASK_CONFIG_CODE = "HNMLTask"; + + // 空位 + private final String EMPTY_POINT = "1"; + // 有料 + private final String FULL_POINT = "2"; + // 空载具 + private final String EMPTY_VEHICLE = "3"; + @Autowired + private ISchBasePointService pointService; + @Autowired + private ISchBaseTaskService taskService; + @Autowired + private ISchBaseTaskconfigService taskConfigService; + @Autowired + private ISchBaseVehiclematerialgroupService vehiclematerialgroupService; + + @Override + protected void updateStatus(String task_code, TaskStatus status) { + // 校验任务 + SchBaseTask taskObj = taskService.getById(task_code); + if (taskObj.getTask_status().equals(TaskStatus.FINISHED.getCode())) { + throw new BadRequestException("该任务已完成!"); + } + if (taskObj.getTask_status().equals(TaskStatus.CANCELED.getCode())) { + throw new BadRequestException("该任务已取消!"); + } + // 获取参数 + String endPoint = taskObj.getPoint_code2(); // 终点 + JSONObject extGroupData = ObjectUtil.isNotEmpty(taskObj.getExt_group_data()) + ? JSONObject.parseObject(taskObj.getExt_group_data()) + : null; + // 载具编码:没有就创建一个 + String vehicle_code = ObjectUtil.isNotEmpty(taskObj.getVehicle_code()) ? taskObj.getVehicle_code() : IdUtil.getSnowflake(1, 1).nextIdStr(); + SchBaseTaskconfig configObj = taskConfigService.getById(TASK_CONFIG_CODE); + SchBasePoint endPointObj = pointService.getById(endPoint); + // 根据传来的类型去对任务进行操作 + if (status.equals(TaskStatus.EXECUTING)) { // 执行中 + taskObj.setTask_status(TaskStatus.EXECUTING.getCode()); + taskObj.setRemark("执行中"); + } + if (status.equals(TaskStatus.FINISHED)) { // 完成 + // 要把数据存到组盘表 + SchBaseVehiclematerialgroup groupEntity = new SchBaseVehiclematerialgroup(); + groupEntity.setMaterial_id(ObjectUtil.isNotEmpty(extGroupData) && ObjectUtil.isNotEmpty(extGroupData.getString("material_id")) + ? extGroupData.getString("material_id") + : ""); + groupEntity.setStanding_time(ObjectUtil.isNotEmpty(extGroupData) && ObjectUtil.isNotEmpty(extGroupData.getString("standing_time")) + ? extGroupData.getInteger("standing_time") + : 0); + groupEntity.setIs_full(ObjectUtil.isNotEmpty(extGroupData) + ? extGroupData.getBoolean("is_full") + : true); + groupEntity.setMaterial_qty(ObjectUtil.isNotEmpty(extGroupData) + ? extGroupData.getInteger("material_qty") + : 0); + groupEntity.setMaterial_weight(ObjectUtil.isNotEmpty(extGroupData) + ? extGroupData.getBigDecimal("material_weight") + : BigDecimal.valueOf(0)); + groupEntity.setWorkorder_code(ObjectUtil.isNotEmpty(extGroupData) && ObjectUtil.isNotEmpty(extGroupData.getString("workorder_code")) + ? extGroupData.getString("workorder_code") + : ""); + groupEntity.setVehicle_code(vehicle_code); + groupEntity.setVehicle_type(taskObj.getVehicle_type()); + groupEntity.setPoint_code(endPoint); + groupEntity.setPoint_name(endPointObj.getPoint_name()); + groupEntity.setPcsn(IdUtil.simpleUUID()); + groupEntity.setInstorage_time(DateUtil.now()); + groupEntity.setTask_code(taskObj.getTask_code()); + groupEntity.setGroup_status(GroupStatusEnum.IN_STORAGE.getType()); // 暂时不维护。 + groupEntity.setIs_delete(false); + vehiclematerialgroupService.create(groupEntity); + // 终点去除正在执行的任务, 设置载具编码、载具类型、载具数量 + if (ObjectUtil.isNotEmpty(endPointObj)) { + endPointObj.setIng_task_code(""); + endPointObj.setVehicle_code(vehicle_code); + endPointObj.setVehicle_type(taskObj.getVehicle_type()); + endPointObj.setVehicle_qty(1); + endPointObj.setPoint_status(PointStatusEnum.FULL_MATERIAL.getValue()); // 有料 + pointService.updateById(endPointObj); + } + taskObj.setRemark("任务完成"); + taskObj.setTask_status(TaskStatus.FINISHED.getCode()); + } + if (status.equals(TaskStatus.CANCELED)) { // 取消 + SchBasePoint one = ObjectUtil.isNotEmpty(endPoint) + ? pointService.getOne(new LambdaQueryWrapper().eq(SchBasePoint::getPoint_code, endPoint)) + : null; + if (one != null) { + one.setIng_task_code(""); + pointService.updateById(one); + } + taskObj.setRemark("任务取消"); + taskObj.setTask_status(TaskStatus.CANCELED.getCode()); + } + taskObj.setUpdate_time(DateUtil.now()); + taskService.updateById(taskObj); + + } + + /** + * 具体业务 + */ + @Override + protected void create() { // 找点+下发、 定时任务 + // 获取任务 + List tasks = taskService.findTasksByTaskStatus(TASK_CONFIG_CODE, TaskStatus.APPLY); + // 配置信息 + SchBaseTaskconfig taskConfig = taskConfigService.getById(TASK_CONFIG_CODE); + for (SchBaseTask task : tasks) { + List nextRegionStr = Arrays.stream(taskConfig.getNext_region_str().split(",")).collect(Collectors.toList()); + // 找终点 + SchBasePoint point = findNextPoint(nextRegionStr); + if (ObjectUtil.isEmpty(point)) { + task.setRemark("未找到所需点位!"); + taskService.update(task); + // 消息通知 + continue; + } + // 设置终点并修改创建成功状态 + task.setPoint_code2(point.getPoint_code()); + task.setTask_status(TaskStatus.CREATED.getCode()); + taskService.update(task); + + point.setIng_task_code(task.getTask_code()); + pointService.update(point); + + //下发 +// this.renotifyAcs(task); + } + + } + + private SchBasePoint findNextPoint(List nextRegionStr) { + LambdaQueryWrapper lam = new LambdaQueryWrapper<>(); + lam.in(SchBasePoint::getRegion_code, nextRegionStr) + .eq(SchBasePoint::getPoint_status, EMPTY_POINT) + .and(la -> la.isNull(SchBasePoint::getIng_task_code) // 当前执行的任务为空或者NULL,有数据表示锁住 + .or() + .eq(SchBasePoint::getIng_task_code, "")) + .orderByAsc(SchBasePoint::getIn_order_seq) + .orderByAsc(SchBasePoint::getPoint_code); + List schBasePoints = pointService.list(lam); + return ObjectUtil.isNotEmpty(schBasePoints) ? schBasePoints.get(0) : null; + } + + @Override + protected void issue() { + + } + + @Override + protected List findPoints() { + return null; + } + + @Override + public void forceFinish(String task_code) { + this.updateStatus(task_code, TaskStatus.FINISHED); + } + + @Override + public void cancel(String task_code) { + this.updateStatus(task_code, TaskStatus.CANCELED); + } + +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNQKTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNQKTask.java new file mode 100644 index 0000000..2c01561 --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/hn/HNQKTask.java @@ -0,0 +1,139 @@ +package org.nl.wms.sch.task_manage.task.tasks.hn; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.nl.common.exception.BadRequestException; +import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService; +import org.nl.wms.sch.point.service.ISchBasePointService; +import org.nl.wms.sch.point.service.dao.SchBasePoint; +import org.nl.wms.sch.task.service.ISchBaseTaskService; +import org.nl.wms.sch.task.service.ISchBaseTaskconfigService; +import org.nl.wms.sch.task.service.dao.SchBaseTask; +import org.nl.wms.sch.task.service.dao.SchBaseTaskconfig; +import org.nl.wms.sch.task_manage.AbstractTask; +import org.nl.wms.sch.task_manage.task.core.TaskStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author: lyd + * @Description: 混捻缺空:呼叫空载具 + * @Date: 2023/5/19 + */ +@Component +public class HNQKTask extends AbstractTask { + private static String TASK_CONFIG_CODE = "HNQKTask"; + + // 空位 + private final String EMPTY_POINT = "1"; + // 有料 + private final String FULL_POINT = "2"; + // 空载具 + private final String EMPTY_VEHICLE = "3"; + + @Autowired + private ISchBasePointService pointService; + @Autowired + private ISchBaseTaskService taskService; + @Autowired + private ISchBaseTaskconfigService taskConfigService; + @Autowired + private ISchBaseVehiclematerialgroupService vehiclematerialgroupService; + + /** + * 具体业务 + */ + @Override + protected void create() { + // 获取任务 + List tasks = taskService.findTasksByTaskStatus(TASK_CONFIG_CODE, TaskStatus.APPLY); + // 配置信息 + SchBaseTaskconfig taskConfig = taskConfigService.getById(TASK_CONFIG_CODE); + for (SchBaseTask task : tasks) { + List startRegionStr = Arrays.stream(taskConfig.getStart_region_str().split(",")).collect(Collectors.toList()); + // 找终点 + SchBasePoint point = findStartPoint(startRegionStr); + if (ObjectUtil.isEmpty(point)) { + task.setRemark("未找到所需点位!"); + taskService.update(task); + // 消息通知 + continue; + } + // 设置终点并修改创建成功状态 + task.setPoint_code1(point.getPoint_code()); + task.setTask_status(TaskStatus.CREATED.getCode()); + taskService.update(task); + + point.setIng_task_code(task.getTask_code()); + pointService.update(point); + + //下发 +// this.renotifyAcs(task); + } + } + + /** + * 找起点 + * @param startRegionStr + * @return + */ + private SchBasePoint findStartPoint(List startRegionStr) { + LambdaQueryWrapper lam = new LambdaQueryWrapper<>(); + lam.in(SchBasePoint::getRegion_code, startRegionStr) + .eq(SchBasePoint::getPoint_status, EMPTY_VEHICLE) + // 可添加对托盘类型的校验 + .eq(SchBasePoint::getVehicle_type, "1") + .and(la -> la.isNull(SchBasePoint::getIng_task_code) // 当前执行的任务为空或者NULL,有数据表示锁住 + .or() + .eq(SchBasePoint::getIng_task_code, "")) + .orderByAsc(SchBasePoint::getIn_order_seq) + .orderByAsc(SchBasePoint::getPoint_code); + List schBasePoints = pointService.list(lam); + return ObjectUtil.isNotEmpty(schBasePoints) ? schBasePoints.get(0) : null; + } + + @Override + protected void issue() { + + } + + @Override + protected void updateStatus(String task_code, TaskStatus status) { + // 校验任务 + SchBaseTask taskObj = taskService.getById(task_code); + if (taskObj.getTask_status().equals(TaskStatus.FINISHED.getCode())) { + throw new BadRequestException("该任务已完成!"); + } + if (taskObj.getTask_status().equals(TaskStatus.CANCELED.getCode())) { + throw new BadRequestException("该任务已取消!"); + } + // 获取参数 + String pointCode1 = taskObj.getPoint_code1(); // 获取起点 + // 获取外部参数 + JSONObject extGroupData = ObjectUtil.isNotEmpty(taskObj.getExt_group_data()) + ? JSONObject.parseObject(taskObj.getExt_group_data()) + : null; + + } + + @Override + protected List findPoints() { + return null; + } + + @Override + public void forceFinish(String task_code) { + this.updateStatus(task_code, TaskStatus.FINISHED); + } + + @Override + public void cancel(String task_code) { + this.updateStatus(task_code, TaskStatus.CANCELED); + } +} + diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/yz/YZQLTask.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/yz/YZQLTask.java new file mode 100644 index 0000000..e9969cf --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/yz/YZQLTask.java @@ -0,0 +1,185 @@ +package org.nl.wms.sch.task_manage.task.tasks.yz; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.nl.common.exception.BadRequestException; +import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService; +import org.nl.wms.sch.group.service.dao.SchBaseVehiclematerialgroup; +import org.nl.wms.sch.point.service.ISchBasePointService; +import org.nl.wms.sch.point.service.dao.SchBasePoint; +import org.nl.wms.sch.task.service.ISchBaseTaskService; +import org.nl.wms.sch.task.service.ISchBaseTaskconfigService; +import org.nl.wms.sch.task.service.dao.SchBaseTask; +import org.nl.wms.sch.task.service.dao.SchBaseTaskconfig; +import org.nl.wms.sch.task_manage.AbstractTask; +import org.nl.wms.sch.task_manage.enums.GroupBindMaterialStatusEnum; +import org.nl.wms.sch.task_manage.task.core.TaskStatus; +import org.nl.wms.utils.PointUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author: lyd + * @Description: 压制缺料任务 + * @Date: 2023/5/25 + */ +@Slf4j +@Component +public class YZQLTask extends AbstractTask { + private static String TASK_CONFIG_CODE = "YZQLTask"; + + // 空位 + private final String EMPTY_POINT = "1"; + // 有料 + private final String FULL_POINT = "2"; + // 空载具 + private final String EMPTY_VEHICLE = "3"; + @Autowired + private ISchBasePointService pointService; + @Autowired + private ISchBaseTaskService taskService; + @Autowired + private ISchBaseTaskconfigService taskConfigService; + @Autowired + private ISchBaseVehiclematerialgroupService vehiclematerialgroupService; + @Override + protected void create() throws BadRequestException { + // 获取任务 + List tasks = taskService.findTasksByTaskStatus(TASK_CONFIG_CODE, TaskStatus.APPLY); + // 配置信息 + SchBaseTaskconfig taskConfig = taskConfigService.getById(TASK_CONFIG_CODE); + for (SchBaseTask task : tasks) { + List startRegionStr = Arrays.stream(taskConfig.getStart_region_str().split(",")).collect(Collectors.toList()); + // 找起点 + String extGroupData = task.getExt_group_data(); + JSONObject jsonObject = JSONObject.parseObject(extGroupData); + SchBasePoint point = findStartPoint(startRegionStr, jsonObject); + if (ObjectUtil.isEmpty(point)) { + task.setRemark("未找到所需点位!"); + taskService.update(task); + // 消息通知 + continue; + } + // 设置起点并修改创建成功状态 + task.setPoint_code1(point.getPoint_code()); + task.setTask_status(TaskStatus.CREATED.getCode()); + task.setVehicle_code(point.getVehicle_code()); + taskService.update(task); + + point.setIng_task_code(task.getTask_code()); + pointService.update(point); + + //下发 +// this.renotifyAcs(task); + } + } + + /** + * 找起点业务:根据起点区域寻找所需点位 + * @param startRegionStr : 区域列表 + * @param extGroupData : 外部参数,包含条件所需的信息 + * @description : JSONObject获取不到就是null + * @return + */ + private SchBasePoint findStartPoint(List startRegionStr, JSONObject extGroupData) { + String materialId = extGroupData.getString("material_id"); + String vehicleType = extGroupData.getString("vehicle_type"); + int standingTime = extGroupData.getInteger("standing_time"); // 静置时间 + Assert.notNull(materialId, "物料不能为空!"); + Assert.notNull(vehicleType, "载具类型不能为空!"); + Assert.notNull(standingTime, "静置时间不能为空!"); + // 找到所需要物料的载具编号 + List list = vehiclematerialgroupService.list(new LambdaQueryWrapper() + .eq(SchBaseVehiclematerialgroup::getMaterial_id, materialId) + .eq(SchBaseVehiclematerialgroup::getVehicle_type, vehicleType) + .eq(SchBaseVehiclematerialgroup::getGroup_bind_material_status, GroupBindMaterialStatusEnum.BOUND.getValue()) + .apply("DATE_ADD(instorage_time, INTERVAL " + standingTime + " MINUTE) <= NOW()") + .orderByAsc(SchBaseVehiclematerialgroup::getPoint_code)); + // 获取第一个 + SchBaseVehiclematerialgroup vehiclematerialgroup = ObjectUtil.isNotEmpty(list) ? list.get(0) : null; + if (ObjectUtil.isEmpty(vehiclematerialgroup)) return null; + SchBasePoint one = pointService.getOne(new LambdaQueryWrapper() + .in(SchBasePoint::getRegion_code, startRegionStr) + .eq(SchBasePoint::getPoint_status, FULL_POINT) + .eq(SchBasePoint::getVehicle_code, vehiclematerialgroup.getVehicle_code()) + .eq(SchBasePoint::getVehicle_type, vehicleType)); + return one; + } + + @Override + protected void issue() { + + } + + @Override + protected void updateStatus(String task_code, TaskStatus status) { + // 校验任务 + SchBaseTask taskObj = taskService.getById(task_code); + if (taskObj.getTask_status().equals(TaskStatus.FINISHED.getCode())) { + throw new BadRequestException("该任务已完成!"); + } + if (taskObj.getTask_status().equals(TaskStatus.CANCELED.getCode())) { + throw new BadRequestException("该任务已取消!"); + } + // 获取参数 + String startPoint = taskObj.getPoint_code1(); // 起点 + JSONObject extGroupData = ObjectUtil.isNotEmpty(taskObj.getExt_group_data()) + ? JSONObject.parseObject(taskObj.getExt_group_data()) + : null; + SchBasePoint startPointObj = pointService.getById(startPoint); + // 根据传来的类型去对任务进行操作 + if (status.equals(TaskStatus.EXECUTING)) { // 执行中 + taskObj.setTask_status(TaskStatus.EXECUTING.getCode()); + taskObj.setRemark("执行中"); + } + if (status.equals(TaskStatus.FINISHED)) { // 完成 + // 任务上有载具编码 -> 获取当前载具编码的组盘信息 + SchBaseVehiclematerialgroup one = vehiclematerialgroupService.getOne(new LambdaQueryWrapper() + .eq(SchBaseVehiclematerialgroup::getVehicle_code, taskObj.getVehicle_code()) + .eq(SchBaseVehiclematerialgroup::getVehicle_type, taskObj.getVehicle_type()) + .eq(SchBaseVehiclematerialgroup::getGroup_bind_material_status, GroupBindMaterialStatusEnum.BOUND.getValue())); + // 将载具设置为已解绑 + one.setGroup_bind_material_status(GroupBindMaterialStatusEnum.UNBOUND.getValue()); + vehiclematerialgroupService.update(one); + // 释放点位,将点位设置为空位,清空数据 + if (ObjectUtil.isNotEmpty(startPointObj)) { + PointUtil.clearPoint(startPointObj); + } + // 任务修改成完成 + taskObj.setTask_status(TaskStatus.FINISHED.getCode()); + } + if (status.equals(TaskStatus.CANCELED)) { // 取消 + taskObj.setTask_status(TaskStatus.CANCELED.getCode()); + // 释放点位,起点正在执行的任务清空 + if (ObjectUtil.isNotEmpty(startPointObj)) { + startPointObj.setIng_task_code(""); + pointService.updateById(startPointObj); + } + } + taskObj.setUpdate_time(DateUtil.now()); + taskService.updateById(taskObj); + } + + @Override + protected List findPoints() { + return null; + } + + @Override + public void forceFinish(String task_code) { + this.updateStatus(task_code, TaskStatus.FINISHED); + } + + @Override + public void cancel(String task_code) { + this.updateStatus(task_code, TaskStatus.CANCELED); + } +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/MyEventListener.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/MyEventListener.java new file mode 100644 index 0000000..3ca2263 --- /dev/null +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/MyEventListener.java @@ -0,0 +1,20 @@ +package org.nl.wms.utils; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Author: lyd + * @Description: 监听事件,用来debug查看bean工厂等信息 + * @Date: 2023/5/23 + */ +@Component +public class MyEventListener { + + @EventListener + public void handleContextRefresh(ContextRefreshedEvent event) { + ApplicationContext applicationContext = event.getApplicationContext(); + } +} diff --git a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/PointUtil.java b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/PointUtil.java index b6f25fd..4a2ede5 100644 --- a/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/PointUtil.java +++ b/nladmin-system/nlsso-server/src/main/java/org/nl/wms/utils/PointUtil.java @@ -1,6 +1,11 @@ package org.nl.wms.utils; +import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONObject; +import org.nl.config.SpringContextHolder; +import org.nl.wms.sch.point.service.dao.SchBasePoint; +import org.nl.wms.sch.point.service.impl.SchBasePointServiceImpl; +import org.nl.wms.sch.task_manage.enums.PointStatusEnum; /** * @Author: lyd @@ -25,4 +30,19 @@ public class PointUtil { // 设置 return statusArr.getString(label); } + + /** + * 清空点位 + * @param point + */ + public static void clearPoint(SchBasePoint point) { + SchBasePointServiceImpl pointService = SpringContextHolder.getBean(SchBasePointServiceImpl.class); + point.setPoint_status(PointStatusEnum.EMPTY_POINT.getValue()); + point.setVehicle_type(""); + point.setVehicle_code(""); + point.setIng_task_code(""); + point.setVehicle_qty(0); + point.setUpdate_time(DateUtil.now()); + pointService.updateById(point); + } } diff --git a/nladmin-system/nlsso-server/src/test/java/org/nl/enums/GetEnumOnSqlTest.java b/nladmin-system/nlsso-server/src/test/java/org/nl/enums/GetEnumOnSqlTest.java new file mode 100644 index 0000000..f979ebc --- /dev/null +++ b/nladmin-system/nlsso-server/src/test/java/org/nl/enums/GetEnumOnSqlTest.java @@ -0,0 +1,30 @@ +package org.nl.enums; + +import org.junit.jupiter.api.Test; +import org.nl.wms.sch.task_manage.enums.GroupBindMaterialStatusEnum; +import org.nl.wms.sch.task_manage.enums.TaskDirectionEnum; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * @Author: lyd + * @Description: + * @Date: 2023/5/25 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class GetEnumOnSqlTest { + @Test + public void TaskDirectionEnum() { + TaskDirectionEnum[] values = TaskDirectionEnum.values(); + for (TaskDirectionEnum value : values) { + System.out.println(value.getValue() + ", " + value.getLabel()); + } + } + + @Test + public void GroupBindMaterialStatusEnum() { + GroupBindMaterialStatusEnum[] values = GroupBindMaterialStatusEnum.values(); + for (GroupBindMaterialStatusEnum value : values) { + System.out.println(value.getValue() + ", " + value.getLabel()); + } + } +} diff --git a/nladmin-ui/src/views/wms/pdm/workerorder/index.vue b/nladmin-ui/src/views/wms/pdm/workerorder/index.vue index c351347..1cb6448 100644 --- a/nladmin-ui/src/views/wms/pdm/workerorder/index.vue +++ b/nladmin-ui/src/views/wms/pdm/workerorder/index.vue @@ -249,7 +249,11 @@ prop="workorder_status" label="工单状态" :min-width="flexWidth('workorder_status',crud.data,'工单状态')" - /> + > + +