feat(example): 完善生产订单管理功能

- 新增生产订单、产线订单、机台执行订单相关实体类
- 添加生产订单控制器及服务层实现
- 集成产线选择弹窗组件优化订单生成流程
- 实现生产订单列表、详情、创建、修改、删除功能
- 添加产线分配验证和计划数量校验逻辑
- 优化订单状态管理和分配数量控制
- 重构产线选择方式从下拉框改为弹窗模式
- 更新产线查询接口支持关键词搜索功能
This commit is contained in:
zxy 2026-04-17 11:25:19 +08:00
parent 940a7a9341
commit b53d9eecd3
27 changed files with 1408 additions and 35 deletions

View File

@ -0,0 +1,17 @@
package jnpf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.model.order.ProOrderLineEntity;
/**
* 产线订单 Mapper
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProOrderLineMapper extends BaseMapper<ProOrderLineEntity> {
}

View File

@ -0,0 +1,17 @@
package jnpf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.model.order.ProOrderMachineEntity;
/**
* 机台执行订单 Mapper
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProOrderMachineMapper extends BaseMapper<ProOrderMachineEntity> {
}

View File

@ -0,0 +1,17 @@
package jnpf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.model.order.ProOrderEntity;
/**
* 生产订单 Mapper
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProOrderMapper extends BaseMapper<ProOrderEntity> {
}

View File

@ -0,0 +1,16 @@
package jnpf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.model.order.ProSoRelationEntity;
/**
* 生产订单对应销售订单 Mapper
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProSoRelationMapper extends BaseMapper<ProSoRelationEntity> {
}

View File

@ -28,6 +28,6 @@ public interface ProLineService extends IService<ProLineEntity> {
boolean update(String id, ProLineEntity entity);
String checkForm(ProLineForm form, int i);
void saveOrUpdate(ProLineForm proLineForm, String id, boolean isSave) throws Exception;
List<ProLineEntity> getSelectList();
List<ProLineEntity> getSelectList(String keyWord);
}

View File

@ -0,0 +1,33 @@
package jnpf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.model.order.ProOrderLineEntity;
import java.util.List;
/**
* 产线订单 Service
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProOrderLineService extends IService<ProOrderLineEntity> {
/**
* 根据生产订单ID获取产线列表
*
* @param proId 生产订单ID
* @return 产线订单列表
*/
List<ProOrderLineEntity> getListByProId(Integer proId);
/**
* 根据生产订单号获取产线列表
*
* @param proNo 生产订单号
* @return 产线订单列表
*/
List<ProOrderLineEntity> getListByProNo(String proNo);
}

View File

@ -0,0 +1,41 @@
package jnpf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.model.order.ProOrderMachineEntity;
import java.util.List;
/**
* 机台执行订单 Service
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProOrderMachineService extends IService<ProOrderMachineEntity> {
/**
* 根据生产订单ID获取机台列表
*
* @param proId 生产订单ID
* @return 机台执行订单列表
*/
List<ProOrderMachineEntity> getListByProId(Integer proId);
/**
* 根据生产订单号获取机台列表
*
* @param proNo 生产订单号
* @return 机台执行订单列表
*/
List<ProOrderMachineEntity> getListByProNo(String proNo);
/**
* 根据产线ID获取机台列表
*
* @param lineId 产线ID
* @return 机台执行订单列表
*/
List<ProOrderMachineEntity> getListByLineId(Integer lineId);
}

View File

@ -0,0 +1,35 @@
package jnpf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.model.order.ProOrderEntity;
import jnpf.model.order.ProOrderPagination;
import jnpf.model.order.ProOrderVO;
import java.util.List;
/**
* 生产订单 Service
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProOrderService extends IService<ProOrderEntity> {
/**
* 获取生产订单列表
*
* @param proOrderPagination 分页查询对象
* @return 生产订单列表
*/
List<ProOrderVO> getList(ProOrderPagination proOrderPagination);
/**
* 根据ID获取生产订单信息
*
* @param id 主键
* @return 生产订单信息
*/
ProOrderVO getInfoById(Integer id);
}

View File

@ -0,0 +1,16 @@
package jnpf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.model.order.ProSoRelationEntity;
/**
* 生产订单对应销售订单 Service
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
public interface ProSoRelationService extends IService<ProSoRelationEntity> {
}

View File

@ -47,6 +47,11 @@ public class ProLineServiceImpl extends ServiceImpl<ProLineMapper, ProLineEntity
if (ObjectUtil.isNotEmpty(proLinePagination.getEnabledStatus())) {
proLineWrapper.eq(ProLineEntity::getEnabledStatus, proLinePagination.getEnabledStatus());
}
// selectKey
if (ObjectUtil.isNotEmpty(proLinePagination.getSelectKey())) {
proLineWrapper.eq(ProLineEntity::getProLineName, proLinePagination.getSelectKey()).or()
.like(ProLineEntity::getProLineCd, proLinePagination.getSelectKey());
}
proLineWrapper.eq(ProLineEntity::getDeleteMark, 0);
proLineWrapper.orderByDesc(ProLineEntity::getCreatorTime);
if ("0".equals(proLinePagination.getDataType())) {
@ -120,12 +125,12 @@ public class ProLineServiceImpl extends ServiceImpl<ProLineMapper, ProLineEntity
@Override
@Transactional
public void saveOrUpdate(ProLineForm proLineForm, String id, boolean isSave) throws Exception {
if (isSave){
if (isSave) {
ProLineEntity entity = new ProLineEntity();
BeanUtils.copyProperties(proLineForm, entity);
entity.setId(null);
this.save(entity);
}else {
} else {
ProLineEntity entity = getInfo(id);
if (entity == null) {
throw new Exception("数据不存在");
@ -136,10 +141,14 @@ public class ProLineServiceImpl extends ServiceImpl<ProLineMapper, ProLineEntity
}
@Override
public List<ProLineEntity> getSelectList() {
public List<ProLineEntity> getSelectList(String keyWord) {
LambdaQueryWrapper<ProLineEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProLineEntity::getDeleteMark, 0);
wrapper.eq(ProLineEntity::getEnabledStatus, 1);
if (ObjectUtil.isNotEmpty(keyWord)) {
wrapper.like(ProLineEntity::getProLineName, keyWord).or()
.like(ProLineEntity::getProLineCd, keyWord);
}
wrapper.select(ProLineEntity::getId, ProLineEntity::getProLineName);
wrapper.orderByAsc(ProLineEntity::getProLineName);
return this.list(wrapper);

View File

@ -0,0 +1,42 @@
package jnpf.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.mapper.ProOrderLineMapper;
import jnpf.model.order.ProOrderLineEntity;
import jnpf.service.ProOrderLineService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 产线订单 ServiceImpl
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Service
public class ProOrderLineServiceImpl extends ServiceImpl<ProOrderLineMapper, ProOrderLineEntity> implements ProOrderLineService {
@Override
public List<ProOrderLineEntity> getListByProId(Integer proId) {
QueryWrapper<ProOrderLineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderLineEntity::getProId, proId);
query.lambda().and(wrapper -> wrapper.isNull(ProOrderLineEntity::getDeleteMark)
.or().eq(ProOrderLineEntity::getDeleteMark, 1));
query.lambda().orderByAsc(ProOrderLineEntity::getLineCd);
return this.list(query);
}
@Override
public List<ProOrderLineEntity> getListByProNo(String proNo) {
QueryWrapper<ProOrderLineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderLineEntity::getProNo, proNo);
query.lambda().and(wrapper -> wrapper.isNull(ProOrderLineEntity::getDeleteMark)
.or().eq(ProOrderLineEntity::getDeleteMark, 1));
query.lambda().orderByAsc(ProOrderLineEntity::getLineCd);
return this.list(query);
}
}

View File

@ -0,0 +1,54 @@
package jnpf.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.mapper.ProOrderMachineMapper;
import jnpf.model.order.ProOrderMachineEntity;
import jnpf.service.ProOrderMachineService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 机台执行订单 ServiceImpl
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Service
public class ProOrderMachineServiceImpl extends ServiceImpl<ProOrderMachineMapper, ProOrderMachineEntity> implements ProOrderMachineService {
@Override
public List<ProOrderMachineEntity> getListByProId(Integer proId) {
QueryWrapper<ProOrderMachineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderMachineEntity::getProId, proId);
query.lambda().and(wrapper -> wrapper.isNull(ProOrderMachineEntity::getDeleteMark)
.or().eq(ProOrderMachineEntity::getDeleteMark, 1));
query.lambda().orderByAsc(ProOrderMachineEntity::getLineCd)
.orderByAsc(ProOrderMachineEntity::getMachineCd);
return this.list(query);
}
@Override
public List<ProOrderMachineEntity> getListByProNo(String proNo) {
QueryWrapper<ProOrderMachineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderMachineEntity::getProNo, proNo);
query.lambda().and(wrapper -> wrapper.isNull(ProOrderMachineEntity::getDeleteMark)
.or().eq(ProOrderMachineEntity::getDeleteMark, 1));
query.lambda().orderByAsc(ProOrderMachineEntity::getLineCd)
.orderByAsc(ProOrderMachineEntity::getMachineCd);
return this.list(query);
}
@Override
public List<ProOrderMachineEntity> getListByLineId(Integer lineId) {
QueryWrapper<ProOrderMachineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderMachineEntity::getLineId, lineId);
query.lambda().and(wrapper -> wrapper.isNull(ProOrderMachineEntity::getDeleteMark)
.or().eq(ProOrderMachineEntity::getDeleteMark, 1));
query.lambda().orderByAsc(ProOrderMachineEntity::getMachineCd);
return this.list(query);
}
}

View File

@ -0,0 +1,86 @@
package jnpf.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.mapper.ProOrderMapper;
import jnpf.model.order.ProOrderEntity;
import jnpf.model.order.ProOrderPagination;
import jnpf.model.order.ProOrderVO;
import jnpf.service.ProOrderService;
import jnpf.util.JsonUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* 生产订单 ServiceImpl
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Service
public class ProOrderServiceImpl extends ServiceImpl<ProOrderMapper, ProOrderEntity> implements ProOrderService {
@Override
public List<ProOrderVO> getList(ProOrderPagination proOrderPagination) {
QueryWrapper<ProOrderEntity> query = new QueryWrapper<>();
query.lambda().and(wrapper -> wrapper.isNull(ProOrderEntity::getDeleteMark)
.or().eq(ProOrderEntity::getDeleteMark, 1));
if (StringUtils.hasText(proOrderPagination.getProNo())) {
query.lambda().like(ProOrderEntity::getProNo, proOrderPagination.getProNo());
}
if (StringUtils.hasText(proOrderPagination.getMaterialCode())) {
query.lambda().like(ProOrderEntity::getMaterialCode, proOrderPagination.getMaterialCode());
}
if (StringUtils.hasText(proOrderPagination.getMaterialName())) {
query.lambda().like(ProOrderEntity::getMaterialName, proOrderPagination.getMaterialName());
}
if (StringUtils.hasText(proOrderPagination.getPlanStatus())) {
query.lambda().eq(ProOrderEntity::getPlanStatus, proOrderPagination.getPlanStatus());
}
if (proOrderPagination.getPlanBgDateStart() != null) {
query.lambda().ge(ProOrderEntity::getPlanBgDate, proOrderPagination.getPlanBgDateStart());
}
if (proOrderPagination.getPlanBgDateEnd() != null) {
query.lambda().le(ProOrderEntity::getPlanBgDate, proOrderPagination.getPlanBgDateEnd());
}
if (proOrderPagination.getPlanEndDateStart() != null) {
query.lambda().ge(ProOrderEntity::getPlanEndDate, proOrderPagination.getPlanEndDateStart());
}
if (proOrderPagination.getPlanEndDateEnd() != null) {
query.lambda().le(ProOrderEntity::getPlanEndDate, proOrderPagination.getPlanEndDateEnd());
}
query.lambda().orderByDesc(ProOrderEntity::getProDate)
.orderByDesc(ProOrderEntity::getId);
Page<ProOrderEntity> page = new Page<>(proOrderPagination.getCurrentPage(), proOrderPagination.getPageSize());
Page<ProOrderEntity> entityPage = this.page(page, query);
proOrderPagination.setTotal((int) entityPage.getTotal());
return JsonUtil.getJsonToList(entityPage.getRecords(), ProOrderVO.class);
}
@Override
public ProOrderVO getInfoById(Integer id) {
ProOrderEntity entity = this.getById(id);
if (entity != null) {
return JsonUtil.getJsonToBean(entity, ProOrderVO.class);
}
return null;
}
}

View File

@ -0,0 +1,20 @@
package jnpf.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.mapper.ProSoRelationMapper;
import jnpf.model.order.ProSoRelationEntity;
import jnpf.service.ProSoRelationService;
import org.springframework.stereotype.Service;
/**
* 生产订单对应销售订单 ServiceImpl
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Service
public class ProSoRelationServiceImpl extends ServiceImpl<ProSoRelationMapper, ProSoRelationEntity> implements ProSoRelationService {
}

View File

@ -118,8 +118,8 @@ public class ProLineController {
}
@Operation(summary = "获取产线下拉列表")
@GetMapping("/getSelectList")
public ActionResult getSelectList() {
List<ProLineEntity> list = proLineService.getSelectList();
public ActionResult getSelectList(@RequestParam(value = "keyWord", required = false) String selectKey) {
List<ProLineEntity> list = proLineService.getSelectList(selectKey);
List<Map<String, Object>> result = list.stream()
.map(entity -> {
Map<String, Object> map = JsonUtil.entityToMap(entity);

View File

@ -0,0 +1,122 @@
package jnpf.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.constant.MsgCode;
import jnpf.model.order.ProOrderEntity;
import jnpf.model.order.ProOrderForm;
import jnpf.model.order.ProOrderPagination;
import jnpf.model.order.ProOrderVO;
import jnpf.service.ProOrderService;
import jnpf.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 生产订单 控制类
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Tag(name = "生产订单", description = "example")
@RestController
@RequestMapping("/api/example/proOrder")
public class ProOrderController {
@Autowired
private ProOrderService proOrderService;
/**
* 列表
*
* @param proOrderPagination 分页查询对象
* @return 列表结果集
*/
@Operation(summary = "获取生产订单列表")
@PostMapping("/getList")
public ActionResult<PageListVO<ProOrderVO>> getList(ProOrderPagination proOrderPagination) {
List<ProOrderVO> voList = proOrderService.getList(proOrderPagination);
return ActionResult.page(voList, JsonUtil.getJsonToBean(proOrderPagination, PaginationVO.class));
}
/**
* 获取信息
*
* @param id 主键
* @return
*/
@Operation(summary = "获取生产订单信息")
@Parameter(name = "id", description = "主键", required = true)
@SaCheckPermission("example.proOrder")
@GetMapping("/{id}")
public ActionResult<ProOrderVO> getInfo(@PathVariable Integer id) {
ProOrderVO vo = proOrderService.getInfoById(id);
if (vo != null) {
return ActionResult.success(vo);
}
return ActionResult.fail("数据不存在");
}
/**
* 新建
*
* @param proOrderForm 实体模型
* @return
*/
@Operation(summary = "新建生产订单")
@SaCheckPermission("example.proOrder")
@Parameter(name = "proOrderForm", description = "实体模型", required = true)
@PostMapping()
public ActionResult<ProOrderForm> create(@RequestBody ProOrderForm proOrderForm) {
ProOrderEntity entity = JsonUtil.getJsonToBean(proOrderForm, ProOrderEntity.class);
proOrderService.save(entity);
return ActionResult.success(MsgCode.SU001.get());
}
/**
* 修改
*
* @param proOrderForm 实体模型
* @return
*/
@Operation(summary = "修改生产订单")
@SaCheckPermission("example.proOrder")
@Parameters({
@Parameter(name = "proOrderForm", description = "实体模型", required = true)
})
@PutMapping("/{id}")
public ActionResult<ProOrderForm> update(@RequestBody ProOrderForm proOrderForm) {
ProOrderEntity entity = JsonUtil.getJsonToBean(proOrderForm, ProOrderEntity.class);
entity.setId(proOrderForm.getId());
proOrderService.updateById(entity);
return ActionResult.success(MsgCode.SU004.get());
}
/**
* 删除
*
* @param id 主键
* @return
*/
@Operation(summary = "删除生产订单")
@DeleteMapping("/delete/{id}")
public ActionResult<String> delete(@PathVariable("id") Integer id) {
ProOrderEntity byId = proOrderService.getById(id);
if (ObjectUtil.isNotEmpty(byId)) {
proOrderService.removeById(id);
return ActionResult.success("删除成功");
}
return ActionResult.success("数据不存在,请刷新界面!");
}
}

View File

@ -0,0 +1,104 @@
package jnpf.model.order;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 生产订单表
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
@TableName("tpl_pro_order")
public class ProOrderEntity {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(value = "f_creator_user_id", fill = FieldFill.INSERT)
private String creatorUserId;
@TableField(value = "f_creator_time", fill = FieldFill.INSERT)
private Date creatorTime;
@TableField(value = "f_last_modify_user_id", fill = FieldFill.INSERT_UPDATE)
private String lastModifyUserId;
@TableField(value = "f_last_modify_time", fill = FieldFill.INSERT_UPDATE)
private Date lastModifyTime;
@TableField(value = "f_delete_user_id", fill = FieldFill.UPDATE)
private String deleteUserId;
@TableField(value = "f_delete_time", fill = FieldFill.UPDATE)
private Date deleteTime;
@TableField(value = "f_delete_mark", updateStrategy = FieldStrategy.IGNORED)
private Integer deleteMark;
@TableField(value = "f_flow_id")
private String flowId;
@TableField(value = "f_flow_task_id")
private String flowTaskId;
@TableField("pro_no")
private String proNo;
@TableField("pro_date")
private Date proDate;
@TableField(value = "remark", updateStrategy = FieldStrategy.IGNORED)
private String remark;
@TableField("material_id")
private Integer materialId;
@TableField("material_code")
private String materialCode;
@TableField("material_name")
private String materialName;
@TableField("spec")
private String spec;
@TableField("unit")
private String unit;
@TableField("plan_qty")
private BigDecimal planQty;
@TableField("plan_bg_date")
private Date planBgDate;
@TableField("plan_end_date")
private Date planEndDate;
@TableField("process_flow")
private String processFlow;
@TableField("plan_status")
private String planStatus;
@TableField("plan_emp_id")
private String planEmpId;
@TableField("plan_emp_name")
private String planEmpName;
@TableField("complete_qty")
private BigDecimal completeQty;
@TableField("is_all_line")
private String isAllLine;
@TableField("store_in_qty")
private BigDecimal storeInQty;
}

View File

@ -0,0 +1,86 @@
package jnpf.model.order;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 生产订单 Form
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
@Schema(description = "ProOrderForm对象", name = "生产订单表单对象")
public class ProOrderForm implements Serializable {
@Schema(description = "主键")
private Integer id;
@Schema(description = "生产订单号(MO+年份+月份+3位流水号)")
private String proNo;
@Schema(description = "生成日期")
private Date proDate;
@Schema(description = "备注")
private String remark;
@Schema(description = "产品id")
private Integer materialId;
@Schema(description = "产品编码")
private String materialCode;
@Schema(description = "产品名称")
private String materialName;
@Schema(description = "规格型号")
private String spec;
@Schema(description = "单位")
private String unit;
@Schema(description = "计划数量")
private BigDecimal planQty;
@Schema(description = "计划开始日期")
private Date planBgDate;
@Schema(description = "计划完成日期")
private Date planEndDate;
@Schema(description = "工艺流程")
private String processFlow;
@Schema(description = "订单状态0 未下发 1已下发 2 执行中 3 已完成 4 暂停 5 关闭)")
private String planStatus;
@Schema(description = "编制人id")
private String planEmpId;
@Schema(description = "编制人名称")
private String planEmpName;
@Schema(description = "完成数量")
private BigDecimal completeQty;
@Schema(description = "是否所有产线(0 是 1否)")
private String isAllLine;
@Schema(description = "入库数量")
private BigDecimal storeInQty;
@Schema(description = "流程id")
private String flowId;
@Schema(description = "流程任务主键")
private String flowTaskId;
}

View File

@ -0,0 +1,80 @@
package jnpf.model.order;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 产线订单表
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
@TableName("tpl_pro_order_line")
public class ProOrderLineEntity {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(value = "f_creator_user_id", fill = FieldFill.INSERT)
private String creatorUserId;
@TableField(value = "f_creator_time", fill = FieldFill.INSERT)
private Date creatorTime;
@TableField(value = "f_last_modify_user_id", fill = FieldFill.INSERT_UPDATE)
private String lastModifyUserId;
@TableField(value = "f_last_modify_time", fill = FieldFill.INSERT_UPDATE)
private Date lastModifyTime;
@TableField(value = "f_delete_user_id", fill = FieldFill.UPDATE)
private String deleteUserId;
@TableField(value = "f_delete_time", fill = FieldFill.UPDATE)
private Date deleteTime;
@TableField(value = "f_delete_mark", updateStrategy = FieldStrategy.IGNORED)
private Integer deleteMark;
@TableField(value = "f_flow_id")
private String flowId;
@TableField(value = "f_flow_task_id")
private String flowTaskId;
@TableField("pro_no")
private String proNo;
@TableField("pro_id")
private Integer proId;
@TableField(value = "remark", updateStrategy = FieldStrategy.IGNORED)
private String remark;
@TableField("pro_bg_date")
private Date proBgDate;
@TableField("pro_end_date")
private Date proEndDate;
@TableField("line_cd")
private String lineCd;
@TableField("line_name")
private String lineName;
@TableField("line_id")
private Integer lineId;
@TableField("complete_qty")
private BigDecimal completeQty;
@TableField("plan_qty")
private BigDecimal planQty;
}

View File

@ -0,0 +1,85 @@
package jnpf.model.order;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
/**
* 机台执行订单表
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
@TableName("tpl_pro_order_machine")
public class ProOrderMachineEntity {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(value = "f_creator_user_id", fill = FieldFill.INSERT)
private String creatorUserId;
@TableField(value = "f_creator_time", fill = FieldFill.INSERT)
private Date creatorTime;
@TableField(value = "f_last_modify_user_id", fill = FieldFill.INSERT_UPDATE)
private String lastModifyUserId;
@TableField(value = "f_last_modify_time", fill = FieldFill.INSERT_UPDATE)
private Date lastModifyTime;
@TableField(value = "f_delete_user_id", fill = FieldFill.UPDATE)
private String deleteUserId;
@TableField(value = "f_delete_time", fill = FieldFill.UPDATE)
private Date deleteTime;
@TableField(value = "f_delete_mark", updateStrategy = FieldStrategy.IGNORED)
private Integer deleteMark;
@TableField(value = "f_flow_id")
private String flowId;
@TableField(value = "f_flow_task_id")
private String flowTaskId;
@TableField("pro_no")
private String proNo;
@TableField("pro_id")
private Integer proId;
@TableField(value = "remark", updateStrategy = FieldStrategy.IGNORED)
private String remark;
@TableField("pro_bg_date")
private Date proBgDate;
@TableField("pro_end_date")
private Date proEndDate;
@TableField("pro_status")
private String proStatus;
@TableField("machine_cd")
private String machineCd;
@TableField("machine_name")
private String machineName;
@TableField("machine_id")
private Integer machineId;
@TableField("line_cd")
private String lineCd;
@TableField("line_name")
private String lineName;
@TableField("line_id")
private Integer lineId;
}

View File

@ -0,0 +1,43 @@
package jnpf.model.order;
import io.swagger.v3.oas.annotations.media.Schema;
import jnpf.base.Pagination;
import lombok.Data;
import java.util.Date;
/**
* 生产订单分页查询对象
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
public class ProOrderPagination extends Pagination {
@Schema(description = "生产订单号")
private String proNo;
@Schema(description = "产品编码")
private String materialCode;
@Schema(description = "产品名称")
private String materialName;
@Schema(description = "订单状态")
private String planStatus;
@Schema(description = "计划开始日期-开始")
private Date planBgDateStart;
@Schema(description = "计划开始日期-结束")
private Date planBgDateEnd;
@Schema(description = "计划完成日期-开始")
private Date planEndDateStart;
@Schema(description = "计划完成日期-结束")
private Date planEndDateEnd;
}

View File

@ -0,0 +1,105 @@
package jnpf.model.order;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 生产订单 VO
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
@Schema(description = "ProOrder对象", name = "生产订单")
public class ProOrderVO implements Serializable {
@Schema(description = "主键")
private Integer id;
@Schema(description = "创建人")
private String creatorUserId;
@Schema(description = "创建时间")
private Date creatorTime;
@Schema(description = "修改人")
private String lastModifyUserId;
@Schema(description = "修改时间")
private Date lastModifyTime;
@Schema(description = "删除或者禁用的用户")
private String deleteUserId;
@Schema(description = "删除或者禁用的时间")
private Date deleteTime;
@Schema(description = "删除标记0表示已删除1表示正常")
private Integer deleteMark;
@Schema(description = "流程id")
private String flowId;
@Schema(description = "流程任务主键")
private String flowTaskId;
@Schema(description = "生产订单号(MO+年份+月份+3位流水号)")
private String proNo;
@Schema(description = "生成日期")
private Date proDate;
@Schema(description = "备注")
private String remark;
@Schema(description = "产品id")
private Integer materialId;
@Schema(description = "产品编码")
private String materialCode;
@Schema(description = "产品名称")
private String materialName;
@Schema(description = "规格型号")
private String spec;
@Schema(description = "单位")
private String unit;
@Schema(description = "计划数量")
private BigDecimal planQty;
@Schema(description = "计划开始日期")
private Date planBgDate;
@Schema(description = "计划完成日期")
private Date planEndDate;
@Schema(description = "工艺流程")
private String processFlow;
@Schema(description = "订单状态0 未下发 1已下发 2 执行中 3 已完成 4 暂停 5 关闭)")
private String planStatus;
@Schema(description = "编制人id")
private String planEmpId;
@Schema(description = "编制人名称")
private String planEmpName;
@Schema(description = "完成数量")
private BigDecimal completeQty;
@Schema(description = "是否所有产线(0 是 1否)")
private String isAllLine;
@Schema(description = "入库数量")
private BigDecimal storeInQty;
}

View File

@ -0,0 +1,89 @@
package jnpf.model.order;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 生产订单对应销售订单表
*
* @版本 V3.5
* @版权 引迈信息技术有限公司https://www.jnpfsoft.com
* @作者 JNPF开发平台组
* @日期 2024-04-17
*/
@Data
@TableName("tpl_pro_so_relation")
public class ProSoRelationEntity {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(value = "f_creator_user_id", fill = FieldFill.INSERT)
private String creatorUserId;
@TableField(value = "f_creator_time", fill = FieldFill.INSERT)
private Date creatorTime;
@TableField(value = "f_last_modify_user_id", fill = FieldFill.INSERT_UPDATE)
private String lastModifyUserId;
@TableField(value = "f_last_modify_time", fill = FieldFill.INSERT_UPDATE)
private Date lastModifyTime;
@TableField(value = "f_delete_user_id", fill = FieldFill.UPDATE)
private String deleteUserId;
@TableField(value = "f_delete_time", fill = FieldFill.UPDATE)
private Date deleteTime;
@TableField(value = "f_delete_mark", updateStrategy = FieldStrategy.IGNORED)
private Integer deleteMark;
@TableField(value = "f_flow_id")
private String flowId;
@TableField(value = "f_flow_task_id")
private String flowTaskId;
@TableField("pro_no")
private String proNo;
@TableField("pro_id")
private Integer proId;
@TableField(value = "remark", updateStrategy = FieldStrategy.IGNORED)
private String remark;
@TableField("sale_ord_id")
private Integer saleOrdId;
@TableField("sale_ord_no")
private String saleOrdNo;
@TableField("chang_pro_qty")
private BigDecimal changProQty;
@TableField("cust_id")
private Integer custId;
@TableField("cust_name")
private String custName;
@TableField("material_name")
private String materialName;
@TableField("spec")
private String spec;
@TableField("unit")
private String unit;
@TableField("material_id")
private Integer materialId;
@TableField("material_code")
private String materialCode;
}

View File

@ -15,7 +15,7 @@ import lombok.Data;
@Data
public class ProLinePagination extends Pagination {
/** 查询key */
private String[] selectKey;
private String selectKey;
/** json */
private String json;
/** 数据类型 0-当前页1-全部数据 */

View File

@ -87,6 +87,5 @@ const baseRouter = [{
icon: 'icon-ym icon-ym-btn-add',
}
},
]
export default baseRouter

View File

@ -0,0 +1,190 @@
<template>
<el-dialog title="产线信息" :visible.sync="visible" width="800px">
<div class="modal-content">
<div class="search-bar">
<el-input v-model="search.selectKey" placeholder="检索条件" class="search-input" />
<el-button type="primary" @click="searchProLine">搜索</el-button>
<el-button @click="resetProLine">重置</el-button>
</div>
<el-table
ref="proLineTable"
:data="proLineList"
border
:height="300"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="proLineCd" label="产线编码" align="center" />
<el-table-column prop="proLineName" label="产线名称" align="center" />
<el-table-column prop="remark" label="备注" align="center" />
</el-table>
<div class="pagination-container">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 50]"
:page-size="page.pageSize"
:total="page.total"
layout="total, sizes, prev, pager, next, jumper"
/>
</div>
</div>
<template slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmSelection"> </el-button>
<el-button @click="visible = false"> </el-button>
</template>
</el-dialog>
</template>
<script>
import request from "@/utils/request";
export default {
name: "ProLineSelect",
props: {
visible: {
type: Boolean,
default: false
},
selectedLineCodes: {
type: Array,
default: () => []
}
},
data() {
return {
proLineList: [],
selectedLines: [],
search: {
selectKey: ""
},
page: {
currentPage: 1,
pageSize: 10,
total: 0
}
};
},
watch: {
visible(val) {
if (val) {
this.loadProLineList();
}
}
},
methods: {
loadProLineList() {
request({
url: "/api/example/proLine/getList",
method: "post",
data: {
currentPage: this.page.currentPage,
pageSize: this.page.pageSize,
selectKey: this.search.selectKey,
dataType: 0,
enabledStatus: 1
}
}).then(res => {
if (res.code === 200) {
this.proLineList = res.data.list || [];
this.page.total = res.data.pagination ? res.data.pagination.total : 0;
this.$nextTick(() => {
this.setDefaultSelection();
});
}
});
},
setDefaultSelection() {
if (this.selectedLineCodes.length > 0) {
const table = this.$refs.proLineTable;
if (table) {
table.clearSelection();
const defaultSelected = this.proLineList.filter(line =>
this.selectedLineCodes.includes(line.proLineCd)
);
this.selectedLines = [...defaultSelected];
defaultSelected.forEach(line => {
table.toggleRowSelection(line, true);
});
}
}
},
searchProLine() {
this.page.currentPage = 1;
this.loadProLineList();
},
resetProLine() {
this.search.selectKey = "";
this.page.currentPage = 1;
this.loadProLineList();
},
handleSizeChange(val) {
this.page.pageSize = val;
this.loadProLineList();
},
handleCurrentChange(val) {
this.page.currentPage = val;
this.loadProLineList();
},
handleSelectionChange(val) {
this.selectedLines = val;
},
confirmSelection() {
if (this.selectedLines.length === 0) {
this.$message.warning("请选择产线");
return;
}
const selectedData = this.selectedLines.map(line => ({
lineCode: line.proLineCd,
lineName: line.proLineName,
remark: line.remark || ""
}));
this.$emit("confirm", selectedData);
this.$emit("update:visible", false);
this.selectedLines = [];
}
}
};
</script>
<style scoped>
.modal-content {
padding: 16px;
}
.search-bar {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.search-input {
width: 200px;
}
.pagination-container {
display: flex;
justify-content: center;
margin-top: 16px;
}
.dialog-footer {
display: flex;
justify-content: center;
gap: 16px;
}
</style>

View File

@ -17,7 +17,7 @@
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="订单编号" prop="orderNo">
<el-input disabled placeholder="" />
<el-input disabled placeholder="" />
</el-form-item>
</el-col>
<el-col :span="8">
@ -156,20 +156,8 @@
<div class="section-body">
<el-table :data="lineList" border :height="200">
<el-table-column prop="index" label="序号" align="center" type="index" />
<el-table-column prop="lineCode" label="产线编码" align="center">
<template slot-scope="scope">
<el-select v-model="scope.row.lineCode" placeholder="选择产线">
<el-option label="C0001" value="C0001" />
<el-option label="C0002" value="C0002" />
<el-option label="C0003" value="C0003" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="lineName" label="产线名称" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.lineName" placeholder="产线名称" />
</template>
</el-table-column>
<el-table-column prop="lineCode" label="产线编码" align="center" />
<el-table-column prop="lineName" label="产线名称" align="center" />
<el-table-column prop="allocateQty" label="分配数量(件)" align="center">
<template slot-scope="scope">
<el-input v-model.number="scope.row.allocateQty" placeholder="分配数量" />
@ -177,7 +165,7 @@
</el-table-column>
<el-table-column prop="completedQty" label="已完成数量" align="center">
<template slot-scope="scope">
<el-input v-model.number="scope.row.completedQty" placeholder="已完成数量" />
<el-input v-model.number="scope.row.completedQty" placeholder="已完成数量" disabled />
</template>
</el-table-column>
<el-table-column prop="planStartDate" label="计划开工日期" align="center">
@ -210,16 +198,29 @@
<el-button type="primary" @click="submit">下发</el-button>
<el-button @click="goBack">取消</el-button>
</div>
<!-- 产线选择弹窗 -->
<ProLineSelect
:visible.sync="lineModalVisible"
:selected-line-codes="selectedLineCodes"
@confirm="handleProLineConfirm"
/>
</div>
</template>
<script>
import request from "@/utils/request";
import jnpf from "@/utils/jnpf";
import ProLineSelect from "@/views/example/proline/select";
export default {
name: "GenerateOrder",
components: {
ProLineSelect
},
data() {
return {
lineModalVisible: false,
baseForm: {
orderNo: "",
orderDate: new Date(),
@ -236,9 +237,16 @@ export default {
allLines: false
},
orderList: [],
lineList: []
lineList: [],
orderLoading: false,
selectedLineCodes: []
};
},
computed: {
jnpf() {
return jnpf;
}
},
mounted() {
this.initData();
},
@ -292,11 +300,11 @@ export default {
handlePlanQtyInput(row) {
if (row.planQty > row.remainingQty) {
row.planQty = row.remainingQty;
this.$message.warning('转生成数量不能大于剩余数量');
this.$message.warning('转生产订单数量大于生产数量,请确认!');
}
if (row.planQty < 0) {
row.planQty = 0;
this.$message.warning('转生成数量不能为负数');
this.$message.warning('转生产订单数量不能为0请确认');
}
this.updateTotalPlanQty();
},
@ -325,19 +333,31 @@ export default {
},
addLine() {
this.lineList.push({
lineCode: "",
lineName: "",
allocateQty: null,
completedQty: null,
planStartDate: "",
planEndDate: "",
remark: ""
this.lineModalVisible = true;
},
handleProLineConfirm(selectedLines) {
selectedLines.forEach(line => {
const exists = this.lineList.some(item => item.lineCode === line.lineCode);
if (!exists) {
this.lineList.push({
lineCode: line.lineCode,
lineName: line.lineName,
allocateQty: null,
completedQty: null,
planStartDate: "",
planEndDate: "",
remark: ""
});
}
});
this.selectedLineCodes = this.lineList.map(item => item.lineCode);
},
deleteLine(index) {
const deletedLine = this.lineList[index];
this.lineList.splice(index, 1);
this.selectedLineCodes = this.lineList.map(item => item.lineCode);
},
goBack() {
@ -345,6 +365,7 @@ export default {
},
save() {
if (!this.validateProLine()) return;
if (!this.validatePlanQty()) return;
const submitData = this.prepareSubmitData();
request({
@ -360,6 +381,7 @@ export default {
},
submit() {
if (!this.validateProLine()) return;
if (!this.validatePlanQty()) return;
const submitData = this.prepareSubmitData();
submitData.orderStatus = "1";
@ -375,6 +397,14 @@ export default {
});
},
validateProLine() {
if (this.lineList.length === 0) {
this.$message.warning("生产订单下发必须指定产线,请确认!");
return false;
}
return true;
},
validatePlanQty() {
for (let item of this.orderList) {
if (!item.planQty || item.planQty <= 0) {
@ -386,6 +416,15 @@ export default {
return false;
}
}
const totalPlanQty = this.orderList.reduce((sum, item) => sum + Number(item.planQty || 0), 0);
const totalAllocateQty = this.lineList.reduce((sum, item) => sum + Number(item.allocateQty || 0), 0);
if (totalPlanQty !== totalAllocateQty) {
this.$message.warning("产线分配数量不等于计划数量,请确认!");
return false;
}
return true;
},
@ -488,4 +527,32 @@ export default {
.page-footer el-button {
padding: 8px 24px;
}
/* 产线选择弹窗样式 */
.modal-content {
padding: 16px;
}
.search-bar {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.search-input {
width: 200px;
}
.pagination-container {
display: flex;
justify-content: center;
margin-top: 16px;
}
.dialog-footer {
display: flex;
justify-content: center;
gap: 16px;
}
</style>