diff --git a/gear-mes/src/main/java/com/gear/mes/production/controller/GearProductionTaskController.java b/gear-mes/src/main/java/com/gear/mes/production/controller/GearProductionTaskController.java new file mode 100644 index 0000000..cae7f26 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/controller/GearProductionTaskController.java @@ -0,0 +1,57 @@ +package com.gear.mes.production.controller; + +import com.gear.common.core.controller.BaseController; +import com.gear.common.core.domain.AjaxResult; +import com.gear.common.core.domain.R; +import com.gear.common.core.page.TableDataInfo; +import com.gear.mes.production.domain.GearProductionTask; +import com.gear.mes.production.domain.vo.GearProductionTaskListVo; +import com.gear.mes.production.domain.vo.GearProductionTaskWithDetailVo; +import com.gear.mes.production.service.IGearProductionTaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/mes/production/task") +public class GearProductionTaskController extends BaseController { + + @Autowired + private IGearProductionTaskService productionTaskService; + + @GetMapping("/list") + public TableDataInfo list(GearProductionTask query) { + startPage(); + List list = productionTaskService.selectTaskList(query); + return getDataTable(list); + } + + @GetMapping("/{taskId}") + public AjaxResult getInfo(@PathVariable("taskId") Long taskId) { + return AjaxResult.success(productionTaskService.selectTaskWithDetail(taskId)); + } + + @PostMapping + public R add(@RequestBody GearProductionTaskWithDetailVo bo) { + Long taskId = productionTaskService.insertTaskWithDetail(bo); + if (taskId == null) { + return R.fail("新增失败"); + } + return R.ok(taskId); + } + + @PostMapping("/{taskId}/complete") + public R complete(@PathVariable("taskId") Long taskId) { + boolean ok = productionTaskService.completeTask(taskId); + if (!ok) { + return R.fail("完成失败"); + } + return R.ok(); + } +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTask.java b/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTask.java new file mode 100644 index 0000000..d29f93c --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTask.java @@ -0,0 +1,39 @@ +package com.gear.mes.production.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +@Data +public class GearProductionTask extends BaseEntity { + private static final long serialVersionUID = 1L; + + private Long taskId; + + private String taskCode; + + private String taskName; + + private String status; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date planStartTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date planEndTime; + + private String remark; + + private String delFlag; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date beginTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTaskMaterial.java b/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTaskMaterial.java new file mode 100644 index 0000000..d0cd83e --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTaskMaterial.java @@ -0,0 +1,24 @@ +package com.gear.mes.production.domain; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GearProductionTaskMaterial { + private Long lineId; + + private Long taskId; + + private Long materialId; + + private String materialRole; + + private BigDecimal planQty; + + private BigDecimal usedQty; + + private String unit; + + private String remark; +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTaskProduct.java b/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTaskProduct.java new file mode 100644 index 0000000..7f3bbd4 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/GearProductionTaskProduct.java @@ -0,0 +1,25 @@ +package com.gear.mes.production.domain; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GearProductionTaskProduct { + private Long lineId; + + private Long taskId; + + private Long productId; + + private BigDecimal planQty; + + private BigDecimal finishedQty; + + private BigDecimal badQty; + + private String unit; + + private String remark; +} + diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskListVo.java b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskListVo.java new file mode 100644 index 0000000..86fc75e --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskListVo.java @@ -0,0 +1,41 @@ +package com.gear.mes.production.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class GearProductionTaskListVo { + private Long taskId; + + private String taskCode; + + private String taskName; + + private String status; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date planStartTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date planEndTime; + + private String remark; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + private BigDecimal planQty; + + private BigDecimal finishedQty; + + private BigDecimal badQty; + + private BigDecimal unfinishedQty; +} + diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskMaterialVo.java b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskMaterialVo.java new file mode 100644 index 0000000..6d35d26 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskMaterialVo.java @@ -0,0 +1,34 @@ +package com.gear.mes.production.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GearProductionTaskMaterialVo { + private Long lineId; + + private Long taskId; + + private Long materialId; + + private String materialRole; + + private BigDecimal planQty; + + private BigDecimal usedQty; + + private String unit; + + private String remark; + + private String materialName; + + private Integer materialType; + + private String spec; + + private String model; + + private String factory; +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskProductVo.java b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskProductVo.java new file mode 100644 index 0000000..6737d48 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskProductVo.java @@ -0,0 +1,35 @@ +package com.gear.mes.production.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class GearProductionTaskProductVo { + private Long lineId; + + private Long taskId; + + private Long productId; + + private BigDecimal planQty; + + private BigDecimal finishedQty; + + private BigDecimal badQty; + + private String unit; + + private String remark; + + private String productName; + + private String productCode; + + private String productType; + + private String spec; + + private String model; +} + diff --git a/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskWithDetailVo.java b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskWithDetailVo.java new file mode 100644 index 0000000..68bf2f2 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/domain/vo/GearProductionTaskWithDetailVo.java @@ -0,0 +1,16 @@ +package com.gear.mes.production.domain.vo; + +import com.gear.mes.production.domain.GearProductionTask; +import lombok.Data; + +import java.util.List; + +@Data +public class GearProductionTaskWithDetailVo { + private GearProductionTask task; + + private List products; + + private List materials; +} + diff --git a/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskMapper.java b/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskMapper.java new file mode 100644 index 0000000..d82476e --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskMapper.java @@ -0,0 +1,23 @@ +package com.gear.mes.production.mapper; + +import com.gear.mes.production.domain.GearProductionTask; +import com.gear.mes.production.domain.vo.GearProductionTaskListVo; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +public interface GearProductionTaskMapper { + List selectTaskList(GearProductionTask query); + + GearProductionTask selectTaskById(@Param("taskId") Long taskId); + + int insertTask(GearProductionTask task); + + int updateTask(GearProductionTask task); + + int updateTaskStatus(@Param("taskId") Long taskId, + @Param("status") String status, + @Param("updateBy") String updateBy, + @Param("updateTime") Date updateTime); +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskMaterialMapper.java b/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskMaterialMapper.java new file mode 100644 index 0000000..25d112c --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskMaterialMapper.java @@ -0,0 +1,17 @@ +package com.gear.mes.production.mapper; + +import com.gear.mes.production.domain.GearProductionTaskMaterial; +import com.gear.mes.production.domain.vo.GearProductionTaskMaterialVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface GearProductionTaskMaterialMapper { + List selectByTaskId(@Param("taskId") Long taskId); + + List selectRequirementByTaskId(@Param("taskId") Long taskId); + + int insertBatch(@Param("list") List list); + + int deleteByTaskId(@Param("taskId") Long taskId); +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskProductMapper.java b/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskProductMapper.java new file mode 100644 index 0000000..c638df1 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/mapper/GearProductionTaskProductMapper.java @@ -0,0 +1,14 @@ +package com.gear.mes.production.mapper; + +import com.gear.mes.production.domain.vo.GearProductionTaskProductVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface GearProductionTaskProductMapper { + List selectByTaskId(@Param("taskId") Long taskId); + + int insertBatch(@Param("list") List list); + + int deleteByTaskId(@Param("taskId") Long taskId); +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/service/IGearProductionTaskService.java b/gear-mes/src/main/java/com/gear/mes/production/service/IGearProductionTaskService.java new file mode 100644 index 0000000..91c3d94 --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/service/IGearProductionTaskService.java @@ -0,0 +1,17 @@ +package com.gear.mes.production.service; + +import com.gear.mes.production.domain.GearProductionTask; +import com.gear.mes.production.domain.vo.GearProductionTaskListVo; +import com.gear.mes.production.domain.vo.GearProductionTaskWithDetailVo; + +import java.util.List; + +public interface IGearProductionTaskService { + List selectTaskList(GearProductionTask query); + + GearProductionTaskWithDetailVo selectTaskWithDetail(Long taskId); + + Long insertTaskWithDetail(GearProductionTaskWithDetailVo bo); + + boolean completeTask(Long taskId); +} diff --git a/gear-mes/src/main/java/com/gear/mes/production/service/impl/GearProductionTaskServiceImpl.java b/gear-mes/src/main/java/com/gear/mes/production/service/impl/GearProductionTaskServiceImpl.java new file mode 100644 index 0000000..db8e67f --- /dev/null +++ b/gear-mes/src/main/java/com/gear/mes/production/service/impl/GearProductionTaskServiceImpl.java @@ -0,0 +1,145 @@ +package com.gear.mes.production.service.impl; + +import cn.hutool.core.util.IdUtil; +import com.gear.mes.production.domain.GearProductionTask; +import com.gear.mes.production.domain.GearProductionTaskMaterial; +import com.gear.mes.production.domain.GearProductionTaskProduct; +import com.gear.mes.production.domain.vo.GearProductionTaskListVo; +import com.gear.mes.production.domain.vo.GearProductionTaskMaterialVo; +import com.gear.mes.production.domain.vo.GearProductionTaskWithDetailVo; +import com.gear.common.utils.DateUtils; +import com.gear.mes.production.mapper.GearProductionTaskMapper; +import com.gear.mes.production.mapper.GearProductionTaskMaterialMapper; +import com.gear.mes.production.mapper.GearProductionTaskProductMapper; +import com.gear.mes.production.service.IGearProductionTaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +@Service +public class GearProductionTaskServiceImpl implements IGearProductionTaskService { + + @Autowired + private GearProductionTaskMapper taskMapper; + + @Autowired + private GearProductionTaskProductMapper productMapper; + + @Autowired + private GearProductionTaskMaterialMapper materialMapper; + + @Override + public List selectTaskList(GearProductionTask query) { + return taskMapper.selectTaskList(query); + } + + @Override + public GearProductionTaskWithDetailVo selectTaskWithDetail(Long taskId) { + GearProductionTask task = taskMapper.selectTaskById(taskId); + GearProductionTaskWithDetailVo vo = new GearProductionTaskWithDetailVo(); + vo.setTask(task); + if (taskId == null) { + vo.setProducts(null); + vo.setMaterials(null); + return vo; + } + vo.setProducts(productMapper.selectByTaskId(taskId)); + List materials = materialMapper.selectByTaskId(taskId); + if (task != null && "2".equals(String.valueOf(task.getStatus())) && (materials == null || materials.isEmpty())) { + regenerateReceiptMaterials(taskId); + materials = materialMapper.selectByTaskId(taskId); + } + vo.setMaterials(materials); + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long insertTaskWithDetail(GearProductionTaskWithDetailVo bo) { + if (bo == null || bo.getTask() == null) { + return null; + } + GearProductionTask task = bo.getTask(); + Long taskId = task.getTaskId() != null ? task.getTaskId() : IdUtil.getSnowflakeNextId(); + task.setTaskId(taskId); + if (task.getDelFlag() == null) { + task.setDelFlag("0"); + } + if (task.getStatus() == null || String.valueOf(task.getStatus()).trim().isEmpty()) { + task.setStatus("1"); + } + task.setCreateTime(DateUtils.getNowDate()); + task.setUpdateTime(DateUtils.getNowDate()); + taskMapper.insertTask(task); + + List products = new ArrayList<>(); + if (bo.getProducts() != null) { + bo.getProducts().forEach(p -> { + if (p == null || p.getProductId() == null) return; + GearProductionTaskProduct row = new GearProductionTaskProduct(); + row.setLineId(IdUtil.getSnowflakeNextId()); + row.setTaskId(taskId); + row.setProductId(p.getProductId()); + row.setPlanQty(p.getPlanQty() == null ? BigDecimal.ZERO : p.getPlanQty()); + row.setFinishedQty(p.getFinishedQty() == null ? BigDecimal.ZERO : p.getFinishedQty()); + row.setBadQty(p.getBadQty() == null ? BigDecimal.ZERO : p.getBadQty()); + row.setUnit(p.getUnit()); + row.setRemark(p.getRemark()); + products.add(row); + }); + } + if (!products.isEmpty()) { + productMapper.insertBatch(products); + } + + return taskId; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean completeTask(Long taskId) { + if (taskId == null) { + return false; + } + GearProductionTask task = taskMapper.selectTaskById(taskId); + if (task == null) { + return false; + } + int updated = taskMapper.updateTaskStatus(taskId, "2", task.getUpdateBy(), DateUtils.getNowDate()); + if (updated <= 0) { + return false; + } + regenerateReceiptMaterials(taskId); + return true; + } + + private void regenerateReceiptMaterials(Long taskId) { + materialMapper.deleteByTaskId(taskId); + List required = materialMapper.selectRequirementByTaskId(taskId); + if (required == null || required.isEmpty()) { + return; + } + List rows = new ArrayList<>(); + required.forEach(r -> { + if (r == null || r.getMaterialId() == null) return; + GearProductionTaskMaterial row = new GearProductionTaskMaterial(); + row.setLineId(IdUtil.getSnowflakeNextId()); + row.setTaskId(taskId); + row.setMaterialId(r.getMaterialId()); + row.setMaterialRole(r.getMaterialRole()); + BigDecimal planQty = r.getPlanQty() == null ? BigDecimal.ZERO : r.getPlanQty(); + row.setPlanQty(planQty); + row.setUsedQty(planQty); + row.setUnit(r.getUnit()); + row.setRemark(null); + rows.add(row); + }); + if (!rows.isEmpty()) { + materialMapper.insertBatch(rows); + } + } +} diff --git a/gear-mes/src/main/resources/mapper/production/GearProductionTaskMapper.xml b/gear-mes/src/main/resources/mapper/production/GearProductionTaskMapper.xml new file mode 100644 index 0000000..f462b0a --- /dev/null +++ b/gear-mes/src/main/resources/mapper/production/GearProductionTaskMapper.xml @@ -0,0 +1,110 @@ + + + + + + + + + + INSERT INTO gear_production_task ( + task_id, + task_code, + task_name, + status, + plan_start_time, + plan_end_time, + remark, + del_flag, + create_by, + create_time, + update_by, + update_time + ) VALUES ( + #{taskId}, + #{taskCode}, + #{taskName}, + #{status}, + #{planStartTime}, + #{planEndTime}, + #{remark}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime} + ) + + + + UPDATE gear_production_task + SET + task_code = #{taskCode}, + task_name = #{taskName}, + status = #{status}, + plan_start_time = #{planStartTime}, + plan_end_time = #{planEndTime}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = #{updateTime} + WHERE task_id = #{taskId} + AND del_flag = '0' + + + + UPDATE gear_production_task + SET + status = #{status}, + update_by = #{updateBy}, + update_time = #{updateTime} + WHERE task_id = #{taskId} + AND del_flag = '0' + + + diff --git a/gear-mes/src/main/resources/mapper/production/GearProductionTaskMaterialMapper.xml b/gear-mes/src/main/resources/mapper/production/GearProductionTaskMaterialMapper.xml new file mode 100644 index 0000000..54b90b1 --- /dev/null +++ b/gear-mes/src/main/resources/mapper/production/GearProductionTaskMaterialMapper.xml @@ -0,0 +1,79 @@ + + + + + + + + + + INSERT INTO gear_production_task_material ( + line_id, + task_id, + material_id, + material_role, + plan_qty, + used_qty, + unit, + remark + ) + VALUES + + ( + #{i.lineId}, + #{i.taskId}, + #{i.materialId}, + #{i.materialRole}, + #{i.planQty}, + #{i.usedQty}, + #{i.unit}, + #{i.remark} + ) + + + + + DELETE FROM gear_production_task_material WHERE task_id = #{taskId} + + + diff --git a/gear-mes/src/main/resources/mapper/production/GearProductionTaskProductMapper.xml b/gear-mes/src/main/resources/mapper/production/GearProductionTaskProductMapper.xml new file mode 100644 index 0000000..00b6778 --- /dev/null +++ b/gear-mes/src/main/resources/mapper/production/GearProductionTaskProductMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + INSERT INTO gear_production_task_product ( + line_id, + task_id, + product_id, + plan_qty, + finished_qty, + bad_qty, + unit, + remark + ) + VALUES + + ( + #{i.lineId}, + #{i.taskId}, + #{i.productId}, + #{i.planQty}, + #{i.finishedQty}, + #{i.badQty}, + #{i.unit}, + #{i.remark} + ) + + + + + DELETE FROM gear_production_task_product WHERE task_id = #{taskId} + + + diff --git a/gear-ui3/src/api/mes/productionTask.js b/gear-ui3/src/api/mes/productionTask.js new file mode 100644 index 0000000..ee06999 --- /dev/null +++ b/gear-ui3/src/api/mes/productionTask.js @@ -0,0 +1,31 @@ +import request from '@/utils/request' + +export function listProductionTask(query) { + return request({ + url: '/mes/production/task/list', + method: 'get', + params: query + }) +} + +export function getProductionTask(taskId) { + return request({ + url: '/mes/production/task/' + taskId, + method: 'get' + }) +} + +export function addProductionTask(data) { + return request({ + url: '/mes/production/task', + method: 'post', + data + }) +} + +export function completeProductionTask(taskId) { + return request({ + url: '/mes/production/task/' + taskId + '/complete', + method: 'post' + }) +} diff --git a/gear-ui3/src/router/index.js b/gear-ui3/src/router/index.js index dc79199..4d7fbd6 100644 --- a/gear-ui3/src/router/index.js +++ b/gear-ui3/src/router/index.js @@ -96,6 +96,19 @@ export const constantRoutes = [ } ] }, + { + path: '/mes', + component: Layout, + hidden: true, + children: [ + { + path: 'production', + component: () => import('@/views/mes/production/index.vue'), + name: 'Production', + meta: { title: '生产', icon: 'list', noCache: true } + } + ] + }, { path: '/user', component: Layout, hidden: true, redirect: 'noredirect', children: [ { path: 'profile/:activeTab?', component: () => import('@/views/system/user/profile/index'), name: 'Profile', meta: { title: '个人中心', icon: 'user' } } ] }, { path: '/mat/product', component: Layout, hidden: true, children: [ { path: 'detail/:id(\\d+)', component: () => import('@/views/mat/product/detail'), name: 'ProductDetail', meta: { title: '产品详情', activeMenu: '/mat/product' } } ] } ] diff --git a/gear-ui3/src/views/mat/auxiliary/index.vue b/gear-ui3/src/views/mat/auxiliary/index.vue index e2fd1d1..3dd2885 100644 --- a/gear-ui3/src/views/mat/auxiliary/index.vue +++ b/gear-ui3/src/views/mat/auxiliary/index.vue @@ -91,7 +91,7 @@ - + diff --git a/gear-ui3/src/views/mat/raw/index.vue b/gear-ui3/src/views/mat/raw/index.vue index de6c3cf..4551dc5 100644 --- a/gear-ui3/src/views/mat/raw/index.vue +++ b/gear-ui3/src/views/mat/raw/index.vue @@ -54,7 +54,7 @@ @@ -95,7 +95,7 @@ - + diff --git a/gear-ui3/src/views/mes/production/index.vue b/gear-ui3/src/views/mes/production/index.vue new file mode 100644 index 0000000..e80e76e --- /dev/null +++ b/gear-ui3/src/views/mes/production/index.vue @@ -0,0 +1,782 @@ + + + + +