Quellcode durchsuchen

生产计划看板

wuhb vor 9 Monaten
Ursprung
Commit
9074d576fa

+ 153 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/controller/ProPlanController.java

@@ -0,0 +1,153 @@
+package com.ktg.mes.pro.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.json.JSONUtil;
+import com.ktg.common.utils.DateUtils;
+import org.aspectj.weaver.loadtime.Aj;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ktg.common.annotation.Log;
+import com.ktg.common.core.controller.BaseController;
+import com.ktg.common.core.domain.AjaxResult;
+import com.ktg.common.enums.BusinessType;
+import com.ktg.mes.pro.domain.ProPlan;
+import com.ktg.mes.pro.service.IProPlanService;
+import com.ktg.common.utils.poi.ExcelUtil;
+import com.ktg.common.core.page.TableDataInfo;
+
+/**
+ * 生产计划Controller
+ *
+ * @author wuhb
+ * @date 2025-08-29
+ */
+@RestController
+@RequestMapping("/pro/plan")
+public class ProPlanController extends BaseController
+{
+    @Autowired
+    private IProPlanService proPlanService;
+
+    /**
+     * 查询生产计划列表
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(ProPlan proPlan)
+    {
+        startPage();
+        List<ProPlan> list = proPlanService.selectProPlanList(proPlan);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出生产计划列表
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:export')")
+    @Log(title = "生产计划", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ProPlan proPlan)
+    {
+        List<ProPlan> list = proPlanService.selectProPlanList(proPlan);
+        ExcelUtil<ProPlan> util = new ExcelUtil<ProPlan>(ProPlan.class);
+        util.exportExcel(response, list, "生产计划数据");
+    }
+
+    /**
+     * 获取生产计划详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:query')")
+    @GetMapping(value = "/{planId}")
+    public AjaxResult getInfo(@PathVariable("planId") Long planId)
+    {
+        return AjaxResult.success(proPlanService.selectProPlanByPlanId(planId));
+    }
+
+    /**
+     * 新增生产计划
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:add')")
+    @Log(title = "生产计划", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody ProPlan proPlan)
+    {
+        AjaxResult rs = checkProPlan(proPlan);
+        if(rs != null)return rs;
+        return toAjax(proPlanService.insertProPlan(proPlan));
+    }
+
+    /**
+     * 修改生产计划
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:edit')")
+    @Log(title = "生产计划", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody ProPlan proPlan)
+    {
+        AjaxResult rs = checkProPlan(proPlan);
+        if(rs != null)return rs;
+        return toAjax(proPlanService.updateProPlan(proPlan));
+    }
+
+    /**
+     * 删除生产计划
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:remove')")
+    @Log(title = "生产计划", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{planIds}")
+    public AjaxResult remove(@PathVariable Long[] planIds)
+    {
+        return toAjax(proPlanService.deleteProPlanByPlanIds(planIds));
+    }
+
+    private AjaxResult checkProPlan(ProPlan proPlan){
+        ProPlan proPlan1 = new ProPlan();
+        proPlan1.setPlanDate(proPlan.getPlanDate());
+        List<ProPlan> list = proPlanService.selectProPlanList(proPlan1);
+        boolean rs = list.stream().anyMatch(item->!item.getPlanId().equals(proPlan.getPlanId()));
+        if(rs){
+            String date = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, proPlan.getPlanDate());
+            return AjaxResult.error(date+ "计划已存在");
+        }
+        proPlan1 = new ProPlan();
+        proPlan1.setPlanCode(proPlan.getPlanCode());
+        list = proPlanService.selectProPlanList(proPlan1);
+        rs = list.stream().anyMatch(item->!item.getPlanId().equals(proPlan.getPlanId()));
+        if(rs){
+            return AjaxResult.error(proPlan.getPlanCode() + "计划已存在");
+        }
+        return null;
+    }
+
+    /**
+     * 获取生产计划详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('mes:pro:plan:query')")
+    @GetMapping(value = "/getToday")
+    public AjaxResult getToday()
+    {
+        ProPlan proPlan = new ProPlan();
+        proPlan.setPlanDate(DateUtil.parseDate(DateUtil.today()));
+        List<ProPlan> list = proPlanService.selectProPlanList(proPlan);
+        if(list.size()>1){
+            return AjaxResult.error("今天计划超过1个");
+        }
+        if(list.size() == 1){
+            proPlan = list.get(0);
+            proPlan = proPlanService.selectProPlanByPlanId(proPlan.getPlanId());
+        }
+        return AjaxResult.success(proPlan);
+    }
+}

+ 104 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/controller/ProPlanLineController.java

@@ -0,0 +1,104 @@
+package com.ktg.mes.pro.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ktg.common.annotation.Log;
+import com.ktg.common.core.controller.BaseController;
+import com.ktg.common.core.domain.AjaxResult;
+import com.ktg.common.enums.BusinessType;
+import com.ktg.mes.pro.domain.ProPlanLine;
+import com.ktg.mes.pro.service.IProPlanLineService;
+import com.ktg.common.utils.poi.ExcelUtil;
+import com.ktg.common.core.page.TableDataInfo;
+
+/**
+ * 生产计划明细Controller
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+@RestController
+@RequestMapping("/pro/line")
+public class ProPlanLineController extends BaseController
+{
+    @Autowired
+    private IProPlanLineService proPlanLineService;
+
+    /**
+     * 查询生产计划明细列表
+     */
+    @PreAuthorize("@ss.hasPermi('pro:line:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(ProPlanLine proPlanLine)
+    {
+        startPage();
+        List<ProPlanLine> list = proPlanLineService.selectProPlanLineList(proPlanLine);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出生产计划明细列表
+     */
+    @PreAuthorize("@ss.hasPermi('pro:line:export')")
+    @Log(title = "生产计划明细", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ProPlanLine proPlanLine)
+    {
+        List<ProPlanLine> list = proPlanLineService.selectProPlanLineList(proPlanLine);
+        ExcelUtil<ProPlanLine> util = new ExcelUtil<ProPlanLine>(ProPlanLine.class);
+        util.exportExcel(response, list, "生产计划明细数据");
+    }
+
+    /**
+     * 获取生产计划明细详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('pro:line:query')")
+    @GetMapping(value = "/{lineId}")
+    public AjaxResult getInfo(@PathVariable("lineId") Long lineId)
+    {
+        return AjaxResult.success(proPlanLineService.selectProPlanLineByLineId(lineId));
+    }
+
+    /**
+     * 新增生产计划明细
+     */
+    @PreAuthorize("@ss.hasPermi('pro:line:add')")
+    @Log(title = "生产计划明细", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody ProPlanLine proPlanLine)
+    {
+        return toAjax(proPlanLineService.insertProPlanLine(proPlanLine));
+    }
+
+    /**
+     * 修改生产计划明细
+     */
+    @PreAuthorize("@ss.hasPermi('pro:line:edit')")
+    @Log(title = "生产计划明细", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody ProPlanLine proPlanLine)
+    {
+        return toAjax(proPlanLineService.updateProPlanLine(proPlanLine));
+    }
+
+    /**
+     * 删除生产计划明细
+     */
+    @PreAuthorize("@ss.hasPermi('pro:line:remove')")
+    @Log(title = "生产计划明细", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{lineIds}")
+    public AjaxResult remove(@PathVariable Long[] lineIds)
+    {
+        return toAjax(proPlanLineService.deleteProPlanLineByLineIds(lineIds));
+    }
+}

+ 172 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/domain/ProPlan.java

@@ -0,0 +1,172 @@
+package com.ktg.mes.pro.domain;
+
+import java.util.List;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ktg.common.annotation.Excel;
+import com.ktg.common.core.domain.BaseEntity;
+
+/**
+ * 生产计划对象 pro_plan
+ *
+ * @author wuhb
+ * @date 2025-08-29
+ */
+public class ProPlan extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /**  */
+    private Long planId;
+
+    /** 计划编号 */
+    @Excel(name = "计划编号")
+    private String planCode;
+
+    /** 计划名称 */
+    @Excel(name = "计划名称")
+    private String planName;
+
+    /** 制单时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "制单时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date planDate;
+
+    /** 单据状态 */
+    @Excel(name = "单据状态")
+    private String status;
+
+    /** 预留字段1 */
+    @Excel(name = "预留字段1")
+    private String attr1;
+
+    /** 预留字段2 */
+    @Excel(name = "预留字段2")
+    private String attr2;
+
+    /** 预留字段3 */
+    @Excel(name = "预留字段3")
+    private Long attr3;
+
+    /** 预留字段4 */
+    @Excel(name = "预留字段4")
+    private Long attr4;
+
+    /** 生产计划明细信息 */
+    private List<ProPlanLine> proPlanLineList;
+
+    public void setPlanId(Long planId)
+    {
+        this.planId = planId;
+    }
+
+    public Long getPlanId()
+    {
+        return planId;
+    }
+    public void setPlanCode(String planCode)
+    {
+        this.planCode = planCode;
+    }
+
+    public String getPlanCode()
+    {
+        return planCode;
+    }
+    public void setPlanName(String planName)
+    {
+        this.planName = planName;
+    }
+
+    public String getPlanName()
+    {
+        return planName;
+    }
+    public void setPlanDate(Date planDate)
+    {
+        this.planDate = planDate;
+    }
+
+    public Date getPlanDate()
+    {
+        return planDate;
+    }
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+    public void setAttr1(String attr1)
+    {
+        this.attr1 = attr1;
+    }
+
+    public String getAttr1()
+    {
+        return attr1;
+    }
+    public void setAttr2(String attr2)
+    {
+        this.attr2 = attr2;
+    }
+
+    public String getAttr2()
+    {
+        return attr2;
+    }
+    public void setAttr3(Long attr3)
+    {
+        this.attr3 = attr3;
+    }
+
+    public Long getAttr3()
+    {
+        return attr3;
+    }
+    public void setAttr4(Long attr4)
+    {
+        this.attr4 = attr4;
+    }
+
+    public Long getAttr4()
+    {
+        return attr4;
+    }
+
+    public List<ProPlanLine> getProPlanLineList()
+    {
+        return proPlanLineList;
+    }
+
+    public void setProPlanLineList(List<ProPlanLine> proPlanLineList)
+    {
+        this.proPlanLineList = proPlanLineList;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("planId", getPlanId())
+            .append("planCode", getPlanCode())
+            .append("planName", getPlanName())
+            .append("planDate", getPlanDate())
+            .append("status", getStatus())
+            .append("remark", getRemark())
+            .append("attr1", getAttr1())
+            .append("attr2", getAttr2())
+            .append("attr3", getAttr3())
+            .append("attr4", getAttr4())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("proPlanLineList", getProPlanLineList())
+            .toString();
+    }
+}

+ 312 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/domain/ProPlanLine.java

@@ -0,0 +1,312 @@
+package com.ktg.mes.pro.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ktg.common.annotation.Excel;
+import com.ktg.common.core.domain.BaseEntity;
+
+/**
+ * 生产计划明细对象 pro_plan_line
+ *
+ * @author wuhb
+ * @date 2025-08-29
+ */
+public class ProPlanLine extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long lineId;
+
+    /** 计划ID */
+    private Long planId;
+
+    /** 设备ID */
+    private Long machineryId;
+
+    /** 设备名称 */
+    @Excel(name = "设备名称")
+    private String machineryName;
+
+    /** 设备编号 */
+    @Excel(name = "设备编号")
+    private String machineryCode;
+
+    private String machineryStatus;
+
+    /** 模具工装 */
+    @Excel(name = "模具工装")
+    private String moldName;
+
+    /** 物料ID */
+    private Long itemId;
+
+    /** 物料CODE */
+    @Excel(name = "物料CODE")
+    private Long itemCode;
+
+    /** 物料名称 */
+    @Excel(name = "物料名称")
+    private String itemName;
+
+    /** 规格型号 */
+    @Excel(name = "规格型号")
+    private String specification;
+
+    /** 排产数量 */
+    @Excel(name = "排产数量")
+    private Long plannedQty;
+
+    /** 生产数量 */
+    @Excel(name = "生产数量")
+    private Long producedQty;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date startDate;
+
+    /** 结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date endDate;
+
+    /** 备注 */
+    @Excel(name = "备注")
+    private String remark;
+
+    /** 生产状态 */
+    private String status;
+
+    /** 预留字段1 */
+    private String attr1;
+
+    /** 预留字段2 */
+    private String attr2;
+
+    /** 预留字段3 */
+    private Long attr3;
+
+    /** 预留字段4 */
+    private Long attr4;
+
+    public void setLineId(Long lineId)
+    {
+        this.lineId = lineId;
+    }
+
+    public Long getLineId()
+    {
+        return lineId;
+    }
+    public void setPlanId(Long planId)
+    {
+        this.planId = planId;
+    }
+
+    public Long getPlanId()
+    {
+        return planId;
+    }
+    public void setMachineryId(Long machineryId)
+    {
+        this.machineryId = machineryId;
+    }
+
+    public Long getMachineryId()
+    {
+        return machineryId;
+    }
+    public void setMachineryName(String machineryName)
+    {
+        this.machineryName = machineryName;
+    }
+
+    public String getMachineryName()
+    {
+        return machineryName;
+    }
+    public void setMachineryCode(String machineryCode)
+    {
+        this.machineryCode = machineryCode;
+    }
+
+    public String getMachineryCode()
+    {
+        return machineryCode;
+    }
+    public void setMoldName(String moldName)
+    {
+        this.moldName = moldName;
+    }
+
+    public String getMoldName()
+    {
+        return moldName;
+    }
+    public void setItemId(Long itemId)
+    {
+        this.itemId = itemId;
+    }
+
+    public Long getItemId()
+    {
+        return itemId;
+    }
+    public void setItemName(String itemName)
+    {
+        this.itemName = itemName;
+    }
+
+    public Long getItemCode() {
+        return itemCode;
+    }
+
+    public void setItemCode(Long itemCode) {
+        this.itemCode = itemCode;
+    }
+
+    public String getItemName()
+    {
+        return itemName;
+    }
+    public void setSpecification(String specification)
+    {
+        this.specification = specification;
+    }
+
+    public String getSpecification()
+    {
+        return specification;
+    }
+    public void setPlannedQty(Long plannedQty)
+    {
+        this.plannedQty = plannedQty;
+    }
+
+    public Long getPlannedQty()
+    {
+        return plannedQty;
+    }
+    public void setProducedQty(Long producedQty)
+    {
+        this.producedQty = producedQty;
+    }
+
+    public Long getProducedQty()
+    {
+        return producedQty;
+    }
+    public void setStartDate(Date startDate)
+    {
+        this.startDate = startDate;
+    }
+
+    public Date getStartDate()
+    {
+        return startDate;
+    }
+    public void setEndDate(Date endDate)
+    {
+        this.endDate = endDate;
+    }
+
+    public Date getEndDate()
+    {
+        return endDate;
+    }
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+    public void setAttr1(String attr1)
+    {
+        this.attr1 = attr1;
+    }
+
+    public String getAttr1()
+    {
+        return attr1;
+    }
+    public void setAttr2(String attr2)
+    {
+        this.attr2 = attr2;
+    }
+
+    public String getAttr2()
+    {
+        return attr2;
+    }
+    public void setAttr3(Long attr3)
+    {
+        this.attr3 = attr3;
+    }
+
+    public Long getAttr3()
+    {
+        return attr3;
+    }
+    public void setAttr4(Long attr4)
+    {
+        this.attr4 = attr4;
+    }
+
+    public Long getAttr4()
+    {
+        return attr4;
+    }
+
+    @Override
+    public String getRemark() {
+        return remark;
+    }
+
+    @Override
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getMachineryStatus() {
+        return machineryStatus;
+    }
+
+    public void setMachineryStatus(String machineryStatus) {
+        this.machineryStatus = machineryStatus;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("lineId", getLineId())
+            .append("planId", getPlanId())
+            .append("machineryId", getMachineryId())
+            .append("machineryName", getMachineryName())
+            .append("machineryCode", getMachineryCode())
+            .append("moldName", getMoldName())
+            .append("itemId", getItemId())
+            .append("itemName", getItemName())
+            .append("specification", getSpecification())
+            .append("plannedQty", getPlannedQty())
+            .append("producedQty", getProducedQty())
+            .append("startDate", getStartDate())
+            .append("endDate", getEndDate())
+            .append("status", getStatus())
+            .append("remark", getRemark())
+            .append("attr1", getAttr1())
+            .append("attr2", getAttr2())
+            .append("attr3", getAttr3())
+            .append("attr4", getAttr4())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 61 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/mapper/ProPlanLineMapper.java

@@ -0,0 +1,61 @@
+package com.ktg.mes.pro.mapper;
+
+import java.util.List;
+import com.ktg.mes.pro.domain.ProPlanLine;
+
+/**
+ * 生产计划明细Mapper接口
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+public interface ProPlanLineMapper 
+{
+    /**
+     * 查询生产计划明细
+     * 
+     * @param lineId 生产计划明细主键
+     * @return 生产计划明细
+     */
+    public ProPlanLine selectProPlanLineByLineId(Long lineId);
+
+    /**
+     * 查询生产计划明细列表
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 生产计划明细集合
+     */
+    public List<ProPlanLine> selectProPlanLineList(ProPlanLine proPlanLine);
+
+    /**
+     * 新增生产计划明细
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 结果
+     */
+    public int insertProPlanLine(ProPlanLine proPlanLine);
+
+    /**
+     * 修改生产计划明细
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 结果
+     */
+    public int updateProPlanLine(ProPlanLine proPlanLine);
+
+    /**
+     * 删除生产计划明细
+     * 
+     * @param lineId 生产计划明细主键
+     * @return 结果
+     */
+    public int deleteProPlanLineByLineId(Long lineId);
+
+    /**
+     * 批量删除生产计划明细
+     * 
+     * @param lineIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteProPlanLineByLineIds(Long[] lineIds);
+}

+ 87 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/mapper/ProPlanMapper.java

@@ -0,0 +1,87 @@
+package com.ktg.mes.pro.mapper;
+
+import java.util.List;
+import com.ktg.mes.pro.domain.ProPlan;
+import com.ktg.mes.pro.domain.ProPlanLine;
+
+/**
+ * 生产计划Mapper接口
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+public interface ProPlanMapper 
+{
+    /**
+     * 查询生产计划
+     * 
+     * @param planId 生产计划主键
+     * @return 生产计划
+     */
+    public ProPlan selectProPlanByPlanId(Long planId);
+
+    /**
+     * 查询生产计划列表
+     * 
+     * @param proPlan 生产计划
+     * @return 生产计划集合
+     */
+    public List<ProPlan> selectProPlanList(ProPlan proPlan);
+
+    /**
+     * 新增生产计划
+     * 
+     * @param proPlan 生产计划
+     * @return 结果
+     */
+    public int insertProPlan(ProPlan proPlan);
+
+    /**
+     * 修改生产计划
+     * 
+     * @param proPlan 生产计划
+     * @return 结果
+     */
+    public int updateProPlan(ProPlan proPlan);
+
+    /**
+     * 删除生产计划
+     * 
+     * @param planId 生产计划主键
+     * @return 结果
+     */
+    public int deleteProPlanByPlanId(Long planId);
+
+    /**
+     * 批量删除生产计划
+     * 
+     * @param planIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteProPlanByPlanIds(Long[] planIds);
+
+    /**
+     * 批量删除生产计划明细
+     * 
+     * @param planIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteProPlanLineByPlanIds(Long[] planIds);
+    
+    /**
+     * 批量新增生产计划明细
+     * 
+     * @param proPlanLineList 生产计划明细列表
+     * @return 结果
+     */
+    public int batchProPlanLine(List<ProPlanLine> proPlanLineList);
+    
+
+    /**
+     * 通过生产计划主键删除生产计划明细信息
+     * 
+     * @param planId 生产计划ID
+     * @return 结果
+     */
+    public int deleteProPlanLineByPlanId(Long planId);
+}

+ 61 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/service/IProPlanLineService.java

@@ -0,0 +1,61 @@
+package com.ktg.mes.pro.service;
+
+import java.util.List;
+import com.ktg.mes.pro.domain.ProPlanLine;
+
+/**
+ * 生产计划明细Service接口
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+public interface IProPlanLineService 
+{
+    /**
+     * 查询生产计划明细
+     * 
+     * @param lineId 生产计划明细主键
+     * @return 生产计划明细
+     */
+    public ProPlanLine selectProPlanLineByLineId(Long lineId);
+
+    /**
+     * 查询生产计划明细列表
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 生产计划明细集合
+     */
+    public List<ProPlanLine> selectProPlanLineList(ProPlanLine proPlanLine);
+
+    /**
+     * 新增生产计划明细
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 结果
+     */
+    public int insertProPlanLine(ProPlanLine proPlanLine);
+
+    /**
+     * 修改生产计划明细
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 结果
+     */
+    public int updateProPlanLine(ProPlanLine proPlanLine);
+
+    /**
+     * 批量删除生产计划明细
+     * 
+     * @param lineIds 需要删除的生产计划明细主键集合
+     * @return 结果
+     */
+    public int deleteProPlanLineByLineIds(Long[] lineIds);
+
+    /**
+     * 删除生产计划明细信息
+     * 
+     * @param lineId 生产计划明细主键
+     * @return 结果
+     */
+    public int deleteProPlanLineByLineId(Long lineId);
+}

+ 61 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/service/IProPlanService.java

@@ -0,0 +1,61 @@
+package com.ktg.mes.pro.service;
+
+import java.util.List;
+import com.ktg.mes.pro.domain.ProPlan;
+
+/**
+ * 生产计划Service接口
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+public interface IProPlanService 
+{
+    /**
+     * 查询生产计划
+     * 
+     * @param planId 生产计划主键
+     * @return 生产计划
+     */
+    public ProPlan selectProPlanByPlanId(Long planId);
+
+    /**
+     * 查询生产计划列表
+     * 
+     * @param proPlan 生产计划
+     * @return 生产计划集合
+     */
+    public List<ProPlan> selectProPlanList(ProPlan proPlan);
+
+    /**
+     * 新增生产计划
+     * 
+     * @param proPlan 生产计划
+     * @return 结果
+     */
+    public int insertProPlan(ProPlan proPlan);
+
+    /**
+     * 修改生产计划
+     * 
+     * @param proPlan 生产计划
+     * @return 结果
+     */
+    public int updateProPlan(ProPlan proPlan);
+
+    /**
+     * 批量删除生产计划
+     * 
+     * @param planIds 需要删除的生产计划主键集合
+     * @return 结果
+     */
+    public int deleteProPlanByPlanIds(Long[] planIds);
+
+    /**
+     * 删除生产计划信息
+     * 
+     * @param planId 生产计划主键
+     * @return 结果
+     */
+    public int deleteProPlanByPlanId(Long planId);
+}

+ 96 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/service/impl/ProPlanLineServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ktg.mes.pro.service.impl;
+
+import java.util.List;
+import com.ktg.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ktg.mes.pro.mapper.ProPlanLineMapper;
+import com.ktg.mes.pro.domain.ProPlanLine;
+import com.ktg.mes.pro.service.IProPlanLineService;
+
+/**
+ * 生产计划明细Service业务层处理
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+@Service
+public class ProPlanLineServiceImpl implements IProPlanLineService 
+{
+    @Autowired
+    private ProPlanLineMapper proPlanLineMapper;
+
+    /**
+     * 查询生产计划明细
+     * 
+     * @param lineId 生产计划明细主键
+     * @return 生产计划明细
+     */
+    @Override
+    public ProPlanLine selectProPlanLineByLineId(Long lineId)
+    {
+        return proPlanLineMapper.selectProPlanLineByLineId(lineId);
+    }
+
+    /**
+     * 查询生产计划明细列表
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 生产计划明细
+     */
+    @Override
+    public List<ProPlanLine> selectProPlanLineList(ProPlanLine proPlanLine)
+    {
+        return proPlanLineMapper.selectProPlanLineList(proPlanLine);
+    }
+
+    /**
+     * 新增生产计划明细
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 结果
+     */
+    @Override
+    public int insertProPlanLine(ProPlanLine proPlanLine)
+    {
+        proPlanLine.setCreateTime(DateUtils.getNowDate());
+        return proPlanLineMapper.insertProPlanLine(proPlanLine);
+    }
+
+    /**
+     * 修改生产计划明细
+     * 
+     * @param proPlanLine 生产计划明细
+     * @return 结果
+     */
+    @Override
+    public int updateProPlanLine(ProPlanLine proPlanLine)
+    {
+        proPlanLine.setUpdateTime(DateUtils.getNowDate());
+        return proPlanLineMapper.updateProPlanLine(proPlanLine);
+    }
+
+    /**
+     * 批量删除生产计划明细
+     * 
+     * @param lineIds 需要删除的生产计划明细主键
+     * @return 结果
+     */
+    @Override
+    public int deleteProPlanLineByLineIds(Long[] lineIds)
+    {
+        return proPlanLineMapper.deleteProPlanLineByLineIds(lineIds);
+    }
+
+    /**
+     * 删除生产计划明细信息
+     * 
+     * @param lineId 生产计划明细主键
+     * @return 结果
+     */
+    @Override
+    public int deleteProPlanLineByLineId(Long lineId)
+    {
+        return proPlanLineMapper.deleteProPlanLineByLineId(lineId);
+    }
+}

+ 134 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/pro/service/impl/ProPlanServiceImpl.java

@@ -0,0 +1,134 @@
+package com.ktg.mes.pro.service.impl;
+
+import java.util.List;
+import com.ktg.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.ArrayList;
+import com.ktg.common.utils.StringUtils;
+import org.springframework.transaction.annotation.Transactional;
+import com.ktg.mes.pro.domain.ProPlanLine;
+import com.ktg.mes.pro.mapper.ProPlanMapper;
+import com.ktg.mes.pro.domain.ProPlan;
+import com.ktg.mes.pro.service.IProPlanService;
+
+/**
+ * 生产计划Service业务层处理
+ * 
+ * @author wuhb
+ * @date 2025-08-29
+ */
+@Service
+public class ProPlanServiceImpl implements IProPlanService 
+{
+    @Autowired
+    private ProPlanMapper proPlanMapper;
+
+    /**
+     * 查询生产计划
+     * 
+     * @param planId 生产计划主键
+     * @return 生产计划
+     */
+    @Override
+    public ProPlan selectProPlanByPlanId(Long planId)
+    {
+        return proPlanMapper.selectProPlanByPlanId(planId);
+    }
+
+    /**
+     * 查询生产计划列表
+     * 
+     * @param proPlan 生产计划
+     * @return 生产计划
+     */
+    @Override
+    public List<ProPlan> selectProPlanList(ProPlan proPlan)
+    {
+        return proPlanMapper.selectProPlanList(proPlan);
+    }
+
+    /**
+     * 新增生产计划
+     * 
+     * @param proPlan 生产计划
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int insertProPlan(ProPlan proPlan)
+    {
+        proPlan.setCreateTime(DateUtils.getNowDate());
+        int rows = proPlanMapper.insertProPlan(proPlan);
+        insertProPlanLine(proPlan);
+        return rows;
+    }
+
+    /**
+     * 修改生产计划
+     * 
+     * @param proPlan 生产计划
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int updateProPlan(ProPlan proPlan)
+    {
+        proPlan.setUpdateTime(DateUtils.getNowDate());
+        proPlanMapper.deleteProPlanLineByPlanId(proPlan.getPlanId());
+        insertProPlanLine(proPlan);
+        return proPlanMapper.updateProPlan(proPlan);
+    }
+
+    /**
+     * 批量删除生产计划
+     * 
+     * @param planIds 需要删除的生产计划主键
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int deleteProPlanByPlanIds(Long[] planIds)
+    {
+        proPlanMapper.deleteProPlanLineByPlanIds(planIds);
+        return proPlanMapper.deleteProPlanByPlanIds(planIds);
+    }
+
+    /**
+     * 删除生产计划信息
+     * 
+     * @param planId 生产计划主键
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int deleteProPlanByPlanId(Long planId)
+    {
+        proPlanMapper.deleteProPlanLineByPlanId(planId);
+        return proPlanMapper.deleteProPlanByPlanId(planId);
+    }
+
+    /**
+     * 新增生产计划明细信息
+     * 
+     * @param proPlan 生产计划对象
+     */
+    public void insertProPlanLine(ProPlan proPlan)
+    {
+        List<ProPlanLine> proPlanLineList = proPlan.getProPlanLineList();
+        Long planId = proPlan.getPlanId();
+        if (StringUtils.isNotNull(proPlanLineList))
+        {
+            List<ProPlanLine> list = new ArrayList<ProPlanLine>();
+            for (ProPlanLine proPlanLine : proPlanLineList)
+            {
+                proPlanLine.setPlanId(planId);
+                list.add(proPlanLine);
+            }
+            if (list.size() > 0)
+            {
+                proPlanMapper.batchProPlanLine(list);
+            }
+        }
+    }
+}

+ 162 - 0
mes/ktg-mes/src/main/resources/mapper/pro/ProPlanLineMapper.xml

@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ktg.mes.pro.mapper.ProPlanLineMapper">
+
+    <resultMap type="ProPlanLine" id="ProPlanLineResult">
+        <result property="lineId"    column="line_id"    />
+        <result property="planId"    column="plan_id"    />
+        <result property="machineryId"    column="machinery_id"    />
+        <result property="machineryName"    column="machinery_name"    />
+        <result property="machineryCode"    column="machinery_code"    />
+        <result property="machineryStatus"  column="machinery_status"/>
+        <result property="moldName"    column="mold_name"    />
+        <result property="itemId"    column="item_id"    />
+        <result property="itemCode"    column="item_code"    />
+        <result property="itemName"    column="item_name"    />
+        <result property="specification"    column="specification"    />
+        <result property="plannedQty"    column="planned_qty"    />
+        <result property="producedQty"    column="produced_qty"    />
+        <result property="startDate"    column="start_date"    />
+        <result property="endDate"    column="end_date"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="attr1"    column="attr1"    />
+        <result property="attr2"    column="attr2"    />
+        <result property="attr3"    column="attr3"    />
+        <result property="attr4"    column="attr4"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectProPlanLineVo">
+        select line_id, plan_id, machinery_id, (select status from dv_machinery where machinery_id = pro_plan_line.machinery_id) machinery_status, machinery_name, machinery_code, mold_name, item_id, item_code, item_name, specification, planned_qty, produced_qty, start_date, end_date, status, remark, attr1, attr2, attr3, attr4, create_by, create_time, update_by, update_time from pro_plan_line
+    </sql>
+
+    <select id="selectProPlanLineList" parameterType="ProPlanLine" resultMap="ProPlanLineResult">
+        <include refid="selectProPlanLineVo"/>
+        <where>
+            <if test="planId != null "> and plan_id = #{planId}</if>
+            <if test="machineryId != null "> and machinery_id = #{machineryId}</if>
+            <if test="machineryName != null  and machineryName != ''"> and machinery_name like concat('%', #{machineryName}, '%')</if>
+            <if test="machineryCode != null  and machineryCode != ''"> and machinery_code = #{machineryCode}</if>
+            <if test="moldName != null  and moldName != ''"> and mold_name like concat('%', #{moldName}, '%')</if>
+            <if test="itemId != null "> and item_id = #{itemId}</if>
+            <if test="itemCode != null "> and item_code = #{itemCode}</if>
+            <if test="itemName != null  and itemName != ''"> and item_name like concat('%', #{itemName}, '%')</if>
+            <if test="specification != null  and specification != ''"> and specification = #{specification}</if>
+            <if test="plannedQty != null "> and planned_qty = #{plannedQty}</if>
+            <if test="producedQty != null "> and produced_qty = #{producedQty}</if>
+            <if test="startDate != null "> and start_date = #{startDate}</if>
+            <if test="endDate != null "> and end_date = #{endDate}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="attr1 != null  and attr1 != ''"> and attr1 = #{attr1}</if>
+            <if test="attr2 != null  and attr2 != ''"> and attr2 = #{attr2}</if>
+            <if test="attr3 != null "> and attr3 = #{attr3}</if>
+            <if test="attr4 != null "> and attr4 = #{attr4}</if>
+        </where>
+    </select>
+
+    <select id="selectProPlanLineByLineId" parameterType="Long" resultMap="ProPlanLineResult">
+        <include refid="selectProPlanLineVo"/>
+        where line_id = #{lineId}
+    </select>
+
+    <insert id="insertProPlanLine" parameterType="ProPlanLine" useGeneratedKeys="true" keyProperty="lineId">
+        insert into pro_plan_line
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="planId != null">plan_id,</if>
+            <if test="machineryId != null">machinery_id,</if>
+            <if test="machineryName != null">machinery_name,</if>
+            <if test="machineryCode != null">machinery_code,</if>
+            <if test="moldName != null">mold_name,</if>
+            <if test="itemId != null">item_id,</if>
+            <if test="itemCode != null ">item_code,</if>
+            <if test="itemName != null">item_name,</if>
+            <if test="specification != null">specification,</if>
+            <if test="plannedQty != null">planned_qty,</if>
+            <if test="producedQty != null">produced_qty,</if>
+            <if test="startDate != null">start_date,</if>
+            <if test="endDate != null">end_date,</if>
+            <if test="status != null">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="attr1 != null">attr1,</if>
+            <if test="attr2 != null">attr2,</if>
+            <if test="attr3 != null">attr3,</if>
+            <if test="attr4 != null">attr4,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="planId != null">#{planId},</if>
+            <if test="machineryId != null">#{machineryId},</if>
+            <if test="machineryName != null">#{machineryName},</if>
+            <if test="machineryCode != null">#{machineryCode},</if>
+            <if test="moldName != null">#{moldName},</if>
+            <if test="itemId != null">#{itemId},</if>
+            <if test="itemCode != null ">#{itemCode},</if>
+            <if test="itemName != null">#{itemName},</if>
+            <if test="specification != null">#{specification},</if>
+            <if test="plannedQty != null">#{plannedQty},</if>
+            <if test="producedQty != null">#{producedQty},</if>
+            <if test="startDate != null">#{startDate},</if>
+            <if test="endDate != null">#{endDate},</if>
+            <if test="status != null">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="attr1 != null">#{attr1},</if>
+            <if test="attr2 != null">#{attr2},</if>
+            <if test="attr3 != null">#{attr3},</if>
+            <if test="attr4 != null">#{attr4},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateProPlanLine" parameterType="ProPlanLine">
+        update pro_plan_line
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="planId != null">plan_id = #{planId},</if>
+            <if test="machineryId != null">machinery_id = #{machineryId},</if>
+            <if test="machineryName != null">machinery_name = #{machineryName},</if>
+            <if test="machineryCode != null">machinery_code = #{machineryCode},</if>
+            <if test="moldName != null">mold_name = #{moldName},</if>
+            <if test="itemId != null">item_id = #{itemId},</if>
+            <if test="itemCode != null "> and item_code = #{itemCode}</if>
+            <if test="itemName != null">item_name = #{itemName},</if>
+            <if test="specification != null">specification = #{specification},</if>
+            <if test="plannedQty != null">planned_qty = #{plannedQty},</if>
+            <if test="producedQty != null">produced_qty = #{producedQty},</if>
+            <if test="startDate != null">start_date = #{startDate},</if>
+            <if test="endDate != null">end_date = #{endDate},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="attr1 != null">attr1 = #{attr1},</if>
+            <if test="attr2 != null">attr2 = #{attr2},</if>
+            <if test="attr3 != null">attr3 = #{attr3},</if>
+            <if test="attr4 != null">attr4 = #{attr4},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where line_id = #{lineId}
+    </update>
+
+    <delete id="deleteProPlanLineByLineId" parameterType="Long">
+        delete from pro_plan_line where line_id = #{lineId}
+    </delete>
+
+    <delete id="deleteProPlanLineByLineIds" parameterType="String">
+        delete from pro_plan_line where line_id in
+        <foreach item="lineId" collection="array" open="(" separator="," close=")">
+            #{lineId}
+        </foreach>
+    </delete>
+</mapper>

+ 168 - 0
mes/ktg-mes/src/main/resources/mapper/pro/ProPlanMapper.xml

@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ktg.mes.pro.mapper.ProPlanMapper">
+
+    <resultMap type="ProPlan" id="ProPlanResult">
+        <result property="planId"    column="plan_id"    />
+        <result property="planCode"    column="plan_code"    />
+        <result property="planName"    column="plan_name"    />
+        <result property="planDate"    column="plan_date"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="attr1"    column="attr1"    />
+        <result property="attr2"    column="attr2"    />
+        <result property="attr3"    column="attr3"    />
+        <result property="attr4"    column="attr4"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <resultMap id="ProPlanProPlanLineResult" type="ProPlan" extends="ProPlanResult">
+        <collection property="proPlanLineList" notNullColumn="sub_line_id" javaType="java.util.List" resultMap="ProPlanLineResult" />
+    </resultMap>
+
+    <resultMap type="ProPlanLine" id="ProPlanLineResult">
+        <result property="lineId"    column="sub_line_id"    />
+        <result property="planId"    column="sub_plan_id"    />
+        <result property="machineryId"    column="sub_machinery_id"    />
+        <result property="machineryName"    column="sub_machinery_name"    />
+        <result property="machineryCode"    column="sub_machinery_code"    />
+        <result property="machineryStatus"  column="sub_machinery_status"/>
+        <result property="moldName"    column="sub_mold_name"    />
+        <result property="itemId"    column="sub_item_id"    />
+        <result property="itemCode"    column="sub_item_code"    />
+        <result property="itemName"    column="sub_item_name"    />
+        <result property="specification"    column="sub_specification"    />
+        <result property="plannedQty"    column="sub_planned_qty"    />
+        <result property="producedQty"    column="sub_produced_qty"    />
+        <result property="startDate"    column="sub_start_date"    />
+        <result property="endDate"    column="sub_end_date"    />
+        <result property="status"    column="sub_status"    />
+        <result property="remark"    column="sub_remark"    />
+        <result property="attr1"    column="sub_attr1"    />
+        <result property="attr2"    column="sub_attr2"    />
+        <result property="attr3"    column="sub_attr3"    />
+        <result property="attr4"    column="sub_attr4"    />
+        <result property="createBy"    column="sub_create_by"    />
+        <result property="createTime"    column="sub_create_time"    />
+        <result property="updateBy"    column="sub_update_by"    />
+        <result property="updateTime"    column="sub_update_time"    />
+    </resultMap>
+
+    <sql id="selectProPlanVo">
+        select plan_id, plan_code, plan_name, plan_date, status, remark, attr1, attr2, attr3, attr4, create_by, create_time, update_by, update_time from pro_plan
+    </sql>
+
+    <select id="selectProPlanList" parameterType="ProPlan" resultMap="ProPlanResult">
+        <include refid="selectProPlanVo"/>
+        <where>
+            <if test="planCode != null and planCode != ''"> and plan_code = #{planCode}</if>
+            <if test="planName != null  and planName != ''"> and plan_name like concat('%', #{planName}, '%')</if>
+            <if test="planDate != null "> and plan_date = #{planDate}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="attr1 != null  and attr1 != ''"> and attr1 = #{attr1}</if>
+            <if test="attr2 != null  and attr2 != ''"> and attr2 = #{attr2}</if>
+            <if test="attr3 != null "> and attr3 = #{attr3}</if>
+            <if test="attr4 != null "> and attr4 = #{attr4}</if>
+        </where>
+    </select>
+
+    <select id="selectProPlanByPlanId" parameterType="Long" resultMap="ProPlanProPlanLineResult">
+        select a.plan_id, a.plan_code, a.plan_name, a.plan_date, a.status, a.remark, a.attr1, a.attr2, a.attr3, a.attr4, a.create_by, a.create_time, a.update_by, a.update_time,
+            b.line_id as sub_line_id, b.plan_id as sub_plan_id, b.machinery_id as sub_machinery_id,
+            (select status from dv_machinery where machinery_id = b.machinery_id) sub_machinery_status,
+            COALESCE((select res2 from dv_machinery_data where run_data = 'get_product_infos' and machinery_code=b.machinery_code and create_time like concat('%', a.plan_date, '%') order by create_time DESC LIMIT 1) -
+            (select res2 from dv_machinery_data where run_data = 'get_product_infos' and machinery_code=b.machinery_code and create_time like concat('%', a.plan_date, '%') order by create_time ASC LIMIT 1), 0) as sub_produced_qty,
+            b.machinery_name as sub_machinery_name, b.machinery_code as sub_machinery_code, b.mold_name as sub_mold_name, b.item_id as sub_item_id, b.item_code as sub_item_code, b.item_name as sub_item_name, b.specification as sub_specification, b.planned_qty as sub_planned_qty, b.start_date as sub_start_date, b.end_date as sub_end_date, b.status as sub_status, b.remark as sub_remark, b.attr1 as sub_attr1, b.attr2 as sub_attr2, b.attr3 as sub_attr3, b.attr4 as sub_attr4, b.create_by as sub_create_by, b.create_time as sub_create_time, b.update_by as sub_update_by, b.update_time as sub_update_time
+        from pro_plan a
+        left join pro_plan_line b on b.plan_id = a.plan_id
+        where a.plan_id = #{planId}
+    </select>
+
+    <insert id="insertProPlan" parameterType="ProPlan" useGeneratedKeys="true" keyProperty="planId">
+        insert into pro_plan
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="planCode != null">plan_code,</if>
+            <if test="planName != null">plan_name,</if>
+            <if test="planDate != null">plan_date,</if>
+            <if test="status != null">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="attr1 != null">attr1,</if>
+            <if test="attr2 != null">attr2,</if>
+            <if test="attr3 != null">attr3,</if>
+            <if test="attr4 != null">attr4,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="planCode != null">#{planCode},</if>
+            <if test="planName != null">#{planName},</if>
+            <if test="planDate != null">#{planDate},</if>
+            <if test="status != null">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="attr1 != null">#{attr1},</if>
+            <if test="attr2 != null">#{attr2},</if>
+            <if test="attr3 != null">#{attr3},</if>
+            <if test="attr4 != null">#{attr4},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateProPlan" parameterType="ProPlan">
+        update pro_plan
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="planCode != null">plan_code = #{planCode},</if>
+            <if test="planName != null">plan_name = #{planName},</if>
+            <if test="planDate != null">plan_date = #{planDate},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="attr1 != null">attr1 = #{attr1},</if>
+            <if test="attr2 != null">attr2 = #{attr2},</if>
+            <if test="attr3 != null">attr3 = #{attr3},</if>
+            <if test="attr4 != null">attr4 = #{attr4},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where plan_id = #{planId}
+    </update>
+
+    <delete id="deleteProPlanByPlanId" parameterType="Long">
+        delete from pro_plan where plan_id = #{planId}
+    </delete>
+
+    <delete id="deleteProPlanByPlanIds" parameterType="String">
+        delete from pro_plan where plan_id in
+        <foreach item="planId" collection="array" open="(" separator="," close=")">
+            #{planId}
+        </foreach>
+    </delete>
+
+    <delete id="deleteProPlanLineByPlanIds" parameterType="String">
+        delete from pro_plan_line where plan_id in
+        <foreach item="planId" collection="array" open="(" separator="," close=")">
+            #{planId}
+        </foreach>
+    </delete>
+
+    <delete id="deleteProPlanLineByPlanId" parameterType="Long">
+        delete from pro_plan_line where plan_id = #{planId}
+    </delete>
+
+    <insert id="batchProPlanLine">
+        insert into pro_plan_line( line_id, plan_id, machinery_id, machinery_name, machinery_code, mold_name, item_id, item_code, item_name, specification, planned_qty, produced_qty, start_date, end_date, status, remark, attr1, attr2, attr3, attr4, create_by, create_time, update_by, update_time) values
+		<foreach item="item" index="index" collection="list" separator=",">
+            ( #{item.lineId}, #{item.planId}, #{item.machineryId}, #{item.machineryName}, #{item.machineryCode}, #{item.moldName}, #{item.itemId}, #{item.itemCode}, #{item.itemName}, #{item.specification}, #{item.plannedQty}, #{item.producedQty}, #{item.startDate}, #{item.endDate}, #{item.status}, #{item.remark}, #{item.attr1}, #{item.attr2}, #{item.attr3}, #{item.attr4}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime})
+        </foreach>
+    </insert>
+</mapper>

+ 52 - 0
mes/mes-ui/src/api/mes/pro/plan.js

@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 查询生产计划列表
+export function listPlan(query) {
+  return request({
+    url: '/pro/plan/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询生产计划详细
+export function getPlan(planId) {
+  return request({
+    url: '/pro/plan/' + planId,
+    method: 'get'
+  })
+}
+
+// 新增生产计划
+export function addPlan(data) {
+  return request({
+    url: '/pro/plan',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改生产计划
+export function updatePlan(data) {
+  return request({
+    url: '/pro/plan',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除生产计划
+export function delPlan(planId) {
+  return request({
+    url: '/pro/plan/' + planId,
+    method: 'delete'
+  })
+}
+
+// 查询生产计划详细
+export function getToday() {
+  return request({
+    url: '/pro/plan/getToday',
+    method: 'get'
+  })
+}

+ 295 - 0
mes/mes-ui/src/views/dashboard/PanelGroupMes.vue

@@ -0,0 +1,295 @@
+<template>
+  <el-row :gutter="40" class="panel-group">
+    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col" style="padding-left: 10px; padding-right: 10px;">
+      <div class="card-panel cp1" @click="handleOpen('instock')">
+        <div class="card-panel-icon-wrapper icon-shopping">
+          <svg-icon icon-class="dingdan" class-name="card-panel-icon" />
+        </div>
+        <div class="card-panel-description">
+
+          <count-to :start-val="0" :end-val="instockQuantity" :duration="3600" class="card-panel-num" />
+          <div class="card-panel-text">
+            今日入库数量
+          </div>
+        </div>
+      </div>
+    </el-col>
+    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col" style="padding-left: 10px; padding-right: 10px;">
+      <div class="card-panel cp2" @click="handleOpen('outstock')">
+        <div class="card-panel-icon-wrapper icon-message ">
+          <svg-icon icon-class="listdo" class-name="card-panel-icon" />
+        </div>
+        <div class="card-panel-description">
+
+          <count-to :start-val="0" :end-val="outstockQuantity" :duration="2600" class="card-panel-num" />
+          <div class="card-panel-text">
+            今日出库数量
+          </div>
+        </div>
+      </div>
+    </el-col>
+    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col" style="padding-left: 10px; padding-right: 10px;">
+      <div class="card-panel cp3" @click="handleOpen('box')">
+        <div class="card-panel-icon-wrapper icon-message">
+          <svg-icon icon-class="listing" class-name="card-panel-icon" />
+        </div>
+        <div class="card-panel-description">
+<!--          <count-to :start-val="0" :end-val="emptyBoxNum" :duration="3000" class="card-panel-num" />-->
+          <div class="card-panel-num" >{{totalItem}}</div>
+          <div class="card-panel-text">
+            物料总数
+          </div>
+        </div>
+      </div>
+    </el-col>
+    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col" style="padding-left: 10px; padding-right: 10px;">
+      <div class="card-panel cp4" @click="handleOpen('area')">
+        <div class="card-panel-icon-wrapper icon-money">
+          <svg-icon icon-class="jixiao" class-name="card-panel-icon" />
+        </div>
+        <div class="card-panel-description">
+          <count-to :start-val="0" :end-val="emptyAreaNum" :duration="3200" class="card-panel-num" />
+          <div class="card-panel-text">
+            库位数量
+          </div>
+        </div>
+      </div>
+    </el-col>
+  </el-row>
+</template>
+
+<script>
+import CountTo from 'vue-count-to'
+import {indexCount, wmsIndexCount} from "@/api/mes/index";
+
+export default {
+  components: {
+    CountTo
+  },
+  data() {
+    return{
+      instockQuantity:0,
+      emptyAreaNum: 0,
+      outstockQuantity: 0,
+      emptyBoxNum: 0,
+      areaBoxNum: 0,
+      liftNum:0,
+      liftGdcNum:0,
+      liftAgvNum:0,
+      liftXcNum:0,
+      pushSuccessNum: 0,
+      pushTotalNum: 0,
+      pullSuccessNum: 0,
+      pullTotalNum: 0,
+      agvSuccessNum: 0,
+      agvTotalNum: 0,
+      liftAvgTime: 0,
+      liftGdcAvgTime: 0,
+      liftAgvAvgTime: 0,
+      liftXcAvgTime: 0,
+      taskWaitNum: 0,
+      totalItem:0,
+    }
+  },
+  methods: {
+    handleSetLineChartData(type) {
+      this.$emit('handleSetLineChartData', type)
+    },
+    initData(){
+      wmsIndexCount().then(response => {
+        debugger
+        let resp = response.data;
+        this.instockQuantity = resp.instockQuantity;
+        this.outstockQuantity = resp.outstockQuantity;
+        this.emptyAreaNum = resp.emptyAreaNum;
+        this.emptyBoxNum = resp.emptyBoxNum;
+        this.areaBoxNum = resp.areaBoxNum;
+        this.liftNum = resp.liftNum;
+        this.pushSuccessNum = resp.pushSuccessNum;
+        this.pushTotalNum = resp.pushTotalNum;
+        this.pullSuccessNum = resp.pullSuccessNum;
+        this.pullTotalNum = resp.pullTotalNum;
+        this.agvSuccessNum = resp.agvSuccessNum;
+        this.agvTotalNum = resp.agvTotalNum;
+        this.liftAvgTime = resp.liftAvgTime;
+        this.taskWaitNum = resp.taskWaitNum;
+        this.totalItem = resp.totalItem;
+      });
+    },
+    handleOpen(type,detail){
+      if(type === "instock"){
+        this.$router.push({ path: '/mes/rms/instock', query: {} })
+      }else if(type === "outstock"){
+        this.$router.push({ path: '/mes/rms/outstock', query: {} })
+      }else if(type === "box"){
+        this.$router.push({ path: '/mes/rms/box', query: {} })
+      }else if(type === "area"){
+        this.$router.push({ path: '/mes/wm/area/index', query: {} })
+      }else if(type === "lift"){
+        this.$router.push({ path: '/mes/rms/lift', query: {} })
+      }else if(type === "taskPool"){
+        if(detail === "push"){
+          this.$router.push({ path: '/mes/rms/taskPool', query: {taskType:'PUSH'} })
+        }else if(detail === "pull"){
+          this.$router.push({ path: '/mes/rms/taskPool', query: {taskType:'PULL'} })
+        }else if(detail === "agv"){
+          this.$router.push({ path: '/mes/rms/taskPool', query: {deviceType:'2'} })
+        }else if(detail === "lift"){
+          this.$router.push({ path: '/mes/rms/taskPool', query: {deviceType:'1'} })
+        }else{
+          this.$router.push({ path: '/mes/rms/taskPool', query: {} })
+        }
+      }
+    },
+  },
+  created(){
+    this.initData();
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.panel-group {
+  margin-top: 18px;
+
+
+  .card-panel-col {
+    margin-bottom: 24px;
+  }
+  .cp1{
+    background: #CC74E5;
+  }
+  .cp2{
+    background: #339EF6;
+  }
+  .cp3{
+    background: #1EBEA8;
+  }
+  .cp4{
+    background: #FF9F2B;
+  }
+  .card-panel {
+    height: 108px;
+    cursor: pointer;
+    font-size: 12px;
+    position: relative;
+    overflow: hidden;
+    color: #666;
+    // background: #fff;
+  }
+
+  .card-panel {
+    height: 108px;
+    cursor: pointer;
+    font-size: 12px;
+    position: relative;
+    overflow: hidden;
+    color: #666;
+    // background: #fff;
+    box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
+    border-color: rgba(0, 0, 0, .05);
+    border-radius: 10px;
+
+    &:hover {
+      .card-panel-icon-wrapper {
+        color: #fff;
+
+      }
+      // .icon-people {
+      // color: #ffffff;
+      // }
+
+
+      // .icon-message {
+      //   background: #36a3f7;
+      // }
+
+      // .icon-money {
+      //   background: #f4516c;
+      // }
+
+      // .icon-shopping {
+      //   background: #34bfa3
+      // }
+    }
+    .bg-people{
+      background:#40c9c6;
+       width: 100%;
+    }
+    .icon-people {
+      color: #ffffff;
+    }
+
+    .icon-message {
+      color: #36a3f7;
+    }
+
+    .icon-money {
+      color: #f4516c;
+    }
+
+    .icon-shopping {
+      color: #34bfa3
+    }
+
+    .card-panel-icon-wrapper {
+      float: left;
+      margin: 5px;
+      padding: 16px 0 16px 16px;
+      transition: all 0.38s ease-out;
+      border-radius: 6px;
+    }
+
+    .card-panel-icon {
+      float: left;
+      font-size: 64px;
+      // color: #fff;
+    }
+
+    .card-panel-description {
+      float: right;
+      font-weight: bold;
+      margin: 26px 10px 26px 0;
+      width: 55%;
+      text-align: right;
+
+
+      .card-panel-text {
+        line-height: 18px;
+        color:#ffffffd1;
+        font-size: 14px;
+        margin-bottom: 10px;
+        margin-top: 5px;
+      }
+
+      .card-panel-num {
+        font-size: 20px;
+        text-align: right;
+        color:#fff;
+      }
+    }
+  }
+
+}
+
+
+@media (max-width:550px) {
+  .card-panel-description {
+    display: none;
+  }
+
+  .card-panel-icon-wrapper {
+    float: none !important;
+    width: 100%;
+    height: 100%;
+    margin: 0 !important;
+
+    .svg-icon {
+      display: block;
+      margin: 14px auto !important;
+      float: none !important;
+
+    }
+  }
+}
+</style>

+ 175 - 0
mes/mes-ui/src/views/index_mes.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="dashboard-editor-container">
+
+    <panel-group-mes @handleSetLineChartData="handleSetLineChartData" />
+    <el-row :gutter="32">
+      <el-col :xs="24" :sm="24" :lg="8">
+        <div class="chart-wrapper">
+          <pie-chart-lift-count />
+        </div>
+      </el-col>
+      <!-- <el-col :xs="24" :sm="24" :lg="8">
+        <div class="chart-wrapper">
+          <pie-chart-task-time />
+        </div>
+      </el-col> -->
+      <el-col :xs="24" :sm="24" :lg="8">
+        <div class="chart-wrapper">
+          <pie-chart />
+        </div>
+      </el-col>
+      <el-col :xs="24" :sm="24" :lg="8">
+        <div class="chart-wrapper">
+          <bar-chart-location />
+        </div>
+      </el-col>
+    </el-row>
+    <el-row :gutter="32">
+      <el-col :xs="24" :sm="24" :lg="24">
+        <div class="chart-wrapper">
+          <line-chart-instock />
+        </div>
+      </el-col>
+    </el-row>
+    <el-row :gutter="32">
+      <el-col :xs="24" :sm="24" :lg="24">
+        <div class="chart-wrapper">
+          <line-chart-outstock />
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { listWorkorder, listConFiCountYear } from "@/api/mes/pro/workorder";
+import PanelGroupMes from './dashboard/PanelGroupMes'
+import LineChart from './dashboard/LineChart'
+import RaddarChart from './dashboard/RaddarChart'
+import BarChart1 from './dashboard/BarChart1'
+import { listAllUnitmeasure} from "@/api/mes/md/unitmeasure";
+import LineChartInstock from './dashboard/LineChartInstock'
+import LineChartOutstock from './dashboard/LineChartOutstock'
+import BarChart from "./dashboard/BarChart.vue";
+import PieChart from "./dashboard/PieChart.vue";
+import PieChartLiftCount from "./dashboard/PieChartLiftCount.vue";
+import PieChartTaskTime from "./dashboard/PieChartTaskTime.vue";
+import BarChartLocation from './dashboard/BarChartLocation'
+
+const lineChartData = {
+  newVisitis: {
+    expectedData: [100, 120, 161, 134, 105, 160, 165, 120, 161, 134, 105, 160],
+    actualData: [120, 82, 91, 154, 162, 140, 145, 82, 91, 154, 162, 140]
+  },
+  messages: {
+    expectedData: [200, 192, 120, 144, 160, 130, 140],
+    actualData: [180, 160, 151, 106, 145, 150, 130]
+  },
+  purchases: {
+    expectedData: [80, 100, 121, 104, 105, 90, 100],
+    actualData: [120, 90, 100, 138, 142, 130, 130]
+  },
+  shoppings: {
+    expectedData: [130, 140, 141, 142, 145, 150, 160],
+    actualData: [120, 82, 91, 154, 162, 140, 130]
+  },
+  conFiCountYear: {
+    expectedData: [],
+    actualData: []
+  },
+}
+
+export default {
+  name: 'Index',
+  components: {
+    PieChart,
+    BarChart,
+    PanelGroupMes,
+    LineChart,
+    RaddarChart,
+    BarChart1,
+    LineChartInstock,
+    LineChartOutstock,
+    PieChartLiftCount,
+    PieChartTaskTime,
+    BarChartLocation
+  },
+  data() {
+    return {
+        loading: true,
+        queryParams: {status:'CONFIRMED'},
+        workorderList: [],
+        //lineChartData: lineChartData.newVisitis,
+        //单位列表
+        measureOptions: [],
+        conFiCountYear: {
+          expectedData: [],
+          actualData: []
+        },
+    }
+  },
+  created(){
+      this.getList();
+      this.getUnits();
+      this.fetchConFiCountYearData();
+  },
+  methods: {
+    getList() {
+      this.loading = true;
+      listWorkorder(this.queryParams).then(response => {
+        this.workorderList = response.rows;
+        this.loading = false;
+      });
+    },
+    handleSetLineChartData(type) {
+      this.lineChartData = lineChartData[type]
+    },
+    handleView(val){
+      this.$router.push({ name: 'indexWorkorder', params: { workorderCode: val.workorderCode}});
+    },
+    getMeasureName(e) {
+      for (var i = 0; i < this.measureOptions.length; i++) {
+        if (this.measureOptions[i].measureCode == e) {
+          return this.measureOptions[i].measureName;
+        }
+      }
+    },
+    getUnits(){
+      listAllUnitmeasure().then(response =>{
+        this.measureOptions = response.data;
+      });
+    },
+
+    fetchConFiCountYearData() {
+      listConFiCountYear().then(response => {
+        let data = response.data;
+        let confirmCount = data.map(item => item.confirmCount);
+        let finishCount = data.map(item => item.finishCount);
+        this.conFiCountYear.expectedData = confirmCount
+        this.conFiCountYear.actualData = finishCount
+      });
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.dashboard-editor-container {
+  padding: 24px;
+  background-color: rgb(240, 242, 245);
+  position: relative;
+
+  .chart-wrapper {
+    background: #fff;
+    padding: 16px 16px 0;
+    margin-bottom: 24px;
+    border-radius: 10px;
+  }
+}
+
+@media (max-width:1024px) {
+  .chart-wrapper {
+    padding: 8px;
+  }
+}
+</style>

+ 150 - 0
mes/mes-ui/src/views/mes/dv/dashboard/planMachine.vue

@@ -0,0 +1,150 @@
+<template>
+    <div class="dashboard" @dblclick="click">
+        <div class="header">
+            <div class="title">生产计划看板</div>
+            <div class="datetime-info">
+                <div class="datetime">{{ currentTime }}</div>
+            </div>
+        </div>
+        <div class="devices">
+            <div>
+                <span>单据编号:{{ proPlan.planCode }}</span>
+            </div>
+            <div>
+                <span>制单日期:{{ proPlan.planDate }}</span>
+            </div>
+        </div>
+        <div class="devices">
+            <el-table border :data="proPlan.proPlanLineList" 
+            :cell-style="{ color: '#fff' }"
+            :header-cell-style="{ color: '#fff' }">
+                <el-table-column label="设备(#)" prop="machineryName" min-width="15%" /> 
+                <el-table-column label="机台状态(#)" prop="machineryStatus" min-width="8%">
+                    <template slot-scope="scope">
+                        <dict-tag :options="dict.type.mes_machinery_status" :value="scope.row.machineryStatus"/>
+                    </template>
+                </el-table-column> 
+                <el-table-column label="模具工装" prop="moldName" min-width="10%" />
+                <el-table-column label="物料名称" prop="itemName" min-width="15%" />
+                <el-table-column label="规格型号" prop="specification" min-width="15%" />
+                <el-table-column label="排产数量" prop="plannedQty" min-width="8%" />
+                <el-table-column label="开始时间" prop="startDate" min-width="10%" />  
+                <el-table-column label="结束时间" prop="endDate" min-width="10%" />   
+                <el-table-column label="生产数量" prop="producedQty" min-width="8%" />
+                <el-table-column label="备注" prop="remark" min-width="10%" />
+            </el-table>
+        </div>
+    </div>
+</template>
+
+<script>
+import screenfull from 'screenfull'
+import { getToday } from "@/api/mes/pro/plan";
+
+export default {
+    name: 'planMachine',
+    dicts: ['mes_machinery_status'],
+    data() {
+        return {
+            proPlan: '',
+            currentTime: '',
+            timeTimer: '',
+            reloadTimer: '',
+            isFullscreen: false
+        };
+    },
+    mounted() {
+        this.updateTime();
+        this.timeTimer = setInterval(this.updateTime, 1000);
+        this.reloadTimer = setInterval(this.getTodayPlan, 10000);
+    },
+    beforeDestroy() {
+        clearInterval(this.timeTimer);
+        clearInterval(this.reloadTimer);
+    },
+    created() {
+        this.getTodayPlan();
+    },
+    methods: {
+        updateTime() {
+            const now = new Date();
+            const pad = n => (n < 10 ? '0' + n : n);
+            this.currentTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
+        },
+        click() {
+            if (!screenfull.isEnabled) {
+                this.$message({ message: '你的浏览器不支持全屏', type: 'warning' })
+                return false
+            }
+            localStorage.setItem("toPage", "/proplan");
+            localStorage.setItem("fromPage", "/dashboard/proplan");
+            screenfull.toggle()
+        },
+        getTodayPlan(){
+            getToday().then(response => {
+                if (response.code === 200) {
+                    this.proPlan = response.data;
+                } else {
+                    this.$message.error(response.msg);
+                }
+            }).catch(error => {
+                this.$message.error("获取计划失败");
+            });
+        }
+    }
+};
+</script>
+
+<style scoped>
+.dashboard {
+    background: url('~@/assets/images/bg.png');
+    background-size: 100% 100%;
+    color: #fff;
+    min-height: 100vh;
+    padding: 0;
+    font-family: 'Microsoft YaHei', Arial, sans-serif;
+    overflow: hidden;
+}
+.header {
+    background: url('~@/assets/images/head.png');
+    background-size: 100% 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+    padding: 20px 32px 8px 32px;
+    height: 85px;
+}
+.title {
+    font-size: 1.6rem;
+    font-weight: bold;
+    text-align: center;
+    color: #57E0FF;
+    flex: 1;
+}
+.datetime-info {
+    position: absolute;
+    right: 10px;
+}
+.datetime-info .datetime {
+    font-size: 1rem;
+}
+
+.devices {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    padding: 0px 16px;
+}
+
+/*最外层透明*/
+::v-deep .el-table,
+::v-deep .el-table__expanded-cell {
+  background-color: transparent !important;
+}
+/* 表格内背景颜色 */
+::v-deep .el-table th,
+::v-deep .el-table tr,
+::v-deep .el-table td {
+  background-color: transparent !important;
+}
+</style>

+ 566 - 0
mes/mes-ui/src/views/mes/pro/plan/index.vue

@@ -0,0 +1,566 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="计划编号" prop="planCode">
+        <el-input
+          v-model="queryParams.planCode"
+          placeholder="请输入计划编号"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="计划名称" prop="planName">
+        <el-input
+          v-model="queryParams.planName"
+          placeholder="请输入计划名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="制单时间" prop="planDate">
+        <el-date-picker clearable
+          v-model="queryParams.planDate"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="请选择制单时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="单据状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="单据状态" clearable>
+          <el-option
+            v-for="dict in dict.type.sys_normal_disable"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['ems:pro:plan:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['ems:pro:plan:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['ems:pro:plan:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['ems:pro:plan:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="planList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="计划编号" align="center" prop="planCode" >
+        <template slot-scope="scope">
+          <el-button
+            type="text"
+            @click="handleView(scope.row)"
+          >{{scope.row.planCode}}</el-button>
+        </template>
+      </el-table-column>
+      <el-table-column label="计划名称" align="center" prop="planName" />
+      <el-table-column label="制单时间" align="center" prop="planDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.planDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="单据状态" align="center" prop="status" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['ems:pro:plan:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['ems:pro:plan:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改生产计划对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="60%" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="计划编号" prop="planCode">
+              <el-input v-model="form.planCode" placeholder="请输入计划编号" :readonly="optType == 'view'"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="4">
+            <el-form-item  label-width="80">
+              <el-switch v-model="autoGenFlag"
+                  active-color="#13ce66"
+                  active-text="自动生成"
+                  @change="handleAutoGenChange(autoGenFlag)" v-if="optType != 'view'">
+              </el-switch>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="计划名称" prop="planName">
+              <el-input v-model="form.planName" placeholder="请输入计划名称" :readonly="optType == 'view'"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+         <el-row>
+          <el-col :span="12">
+            <el-form-item label="制单时间" prop="planDate">
+              <el-date-picker clearable
+                v-model="form.planDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="请选择制单时间"
+                :readonly="optType == 'view'">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="单据状态">
+              <el-radio-group v-model="form.status" :disabled="optType == 'view'">
+                <el-radio
+                  v-for="dict in dict.type.sys_normal_disable"
+                  :key="dict.value"
+                  :label="dict.value"
+                >{{dict.label}}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :readonly="optType == 'view'"/>
+        </el-form-item>
+        <el-divider content-position="center">生产计划明细信息</el-divider>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" v-if="optType !='view'" icon="el-icon-plus" size="mini" @click="handleAddProPlanLine">添加</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" v-if="optType !='view'" icon="el-icon-delete" size="mini" @click="handleDeleteProPlanLine">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleLineExport"
+              v-hasPermi="['ems:pro:plan:export']"
+            >导出</el-button>
+          </el-col>
+        </el-row>
+        <el-table :data="proPlanLineList" :row-class-name="rowProPlanLineIndex" @selection-change="handleProPlanLineSelectionChange" ref="proPlanLine">
+          <el-table-column type="selection" width="50" align="center" />
+          <el-table-column label="设备名称" prop="machineryName" width="220">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.machineryName" placeholder="设备名称" readonly />
+              <el-input v-model="scope.row.machineryCode" placeholder="请选择设备编号" readonly>
+                <el-button style="border-color: #46a6ff; background-color: #46a6ff;color: white;" slot="append"
+                           @click="handleSelectMachinery(scope.row.index)" icon="el-icon-search" v-if="optType !='view'"></el-button>
+              </el-input>
+              <MachinerySelectSingle ref="machinerySelect" @onSelected="onMachineryAdd"></MachinerySelectSingle>
+            </template>
+          </el-table-column>
+          <el-table-column label="物料名称/编号" prop="itemName" width="220">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.itemName" placeholder="物料名称" readonly />
+              <el-input v-model="scope.row.itemCode" placeholder="请选择物料编号" readonly>
+                <el-button style="border-color: #46a6ff; background-color: #46a6ff;color: white;" slot="append"
+                           @click="handleSelect(scope.row.index)" icon="el-icon-search" v-if="optType !='view'"></el-button>
+              </el-input>
+              <ItemSelectSingle ref="itemSelect" @onSelected="onItemAdd"></ItemSelectSingle>
+            </template>
+          </el-table-column>
+          <el-table-column label="模具工装" prop="moldName" width="200">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.moldName" placeholder="请输入模具工装" :readonly="optType == 'view'"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="排产数量" prop="plannedQty" width="180">
+            <template slot-scope="scope">
+              <el-input-number v-model="scope.row.plannedQty" placeholder="请输入排产数量" style="width: 150px;" :disabled="optType == 'view'"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="开始时间" prop="startDate" width="180">
+            <template slot-scope="scope">
+              <el-date-picker clearable v-model="scope.row.startDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择开始时间" style="width: 160px;" :readonly="optType == 'view'"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="结束时间" prop="endDate" width="180">
+            <template slot-scope="scope">
+              <el-date-picker clearable v-model="scope.row.endDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择结束时间" style="width: 160px;" :readonly="optType == 'view'"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="备注" prop="remark" width="200">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.remark" type="textarea" placeholder="请输入内容" :readonly="optType == 'view'"/>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm" v-if="optType != 'view'">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listPlan, getPlan, delPlan, addPlan, updatePlan } from "@/api/mes/pro/plan";
+import {genCode} from "@/api/system/autocode/rule"
+import ItemSelectSingle from "@/views/mes/md/mditem/components/single.vue";
+import MachinerySelectSingle from "@/components/machinerySelect/single.vue";
+
+export default {
+  name: "Plan",
+  components: {ItemSelectSingle, MachinerySelectSingle},
+  dicts: ['sys_normal_disable'],
+  data() {
+    return {
+      autoGenFlag:false,
+      optType: undefined,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 子表选中数据
+      checkedProPlanLine: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 生产计划表格数据
+      planList: [],
+      // 生产计划明细表格数据
+      proPlanLineList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        planId: null,
+        planCode: null,
+        planName: null,
+        planDate: null,
+        status: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        planCode: [
+          { required: true, message: "计划编号不能为空", trigger: "blur" }
+        ],
+        planName: [
+          { required: true, message: "计划名称不能为空", trigger: "blur" }
+        ],
+        planDate: [
+          { required: true, message: "制单日期不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询生产计划列表 */
+    getList() {
+      this.loading = true;
+      listPlan(this.queryParams).then(response => {
+        this.planList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        planId: null,
+        planCode: null,
+        planName: null,
+        planDate: null,
+        status: "0",
+        remark: null,
+        attr1: null,
+        attr2: null,
+        attr3: null,
+        attr4: null,
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null
+      };
+      this.proPlanLineList = [];
+      this.autoGenFlag = false;
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.planId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加生产计划";
+      this.optType = "add";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const planId = row.planId || this.ids
+      getPlan(planId).then(response => {
+        this.form = response.data;
+        this.proPlanLineList = response.data.proPlanLineList;
+        this.open = true;
+        this.title = "修改生产计划";
+        this.optType = "edit";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          let isExit = this.proPlanLineList.every((item, index) => {
+            if(item.plannedQty == null || item.plannedQty === '' || item.plannedQty <= 0){
+              this.$message.error("第" + (index + 1) + "行排产数量必须大于0");
+              return false;
+            }
+            if(item.startDate == null || item.startDate === ''){
+              this.$message.error("第" + (index + 1) + "行开始时间不能为空");
+              return false;
+            }
+            if(item.endDate == null || item.endDate === ''){
+              this.$message.error("第" + (index + 1) + "行结束时间不能为空");
+              return false;
+            }
+            if(new Date(item.startDate).getTime() > new Date(item.endDate).getTime()){
+              this.$message.error("第" + (index + 1) + "行开始时间不能大于结束时间");
+              return false;
+            }
+            if(item.machineryId == null || item.machineryId === ''){
+              this.$message.error("第" + (index + 1) + "行设备名称不能为空");
+              return false;
+            }
+            if(item.itemId == null || item.itemId === ''){
+              this.$message.error("第" + (index + 1) + "行物料名称不能为空");
+              return false;
+            }
+            return true;
+          });
+          if(isExit == false){
+            return;
+          }
+          this.form.proPlanLineList = this.proPlanLineList;
+          if (this.form.planId != null) {
+            updatePlan(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addPlan(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const planIds = row.planId || this.ids;
+      this.$modal.confirm('是否确认删除生产计划编号为"' + planIds + '"的数据项?').then(function() {
+        return delPlan(planIds);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+	/** 生产计划明细序号 */
+    rowProPlanLineIndex({ row, rowIndex }) {
+      row.index = rowIndex + 1;
+    },
+    /** 生产计划明细添加按钮操作 */
+    handleAddProPlanLine() {
+      let obj = {};
+      obj.machineryId = "";
+      obj.machineryName = "";
+      obj.machineryCode = "";
+      obj.moldName = "";
+      obj.itemId = "";
+      obj.itemName = "";
+      obj.specification = "";
+      obj.plannedQty = "";
+      obj.producedQty = "";
+      obj.startDate = "";
+      obj.endDate = "";
+      obj.status = "";
+      obj.remark = "";
+      obj.attr1 = "";
+      obj.attr2 = "";
+      obj.attr3 = "";
+      obj.attr4 = "";
+      this.proPlanLineList.push(obj);
+    },
+    /** 生产计划明细删除按钮操作 */
+    handleDeleteProPlanLine() {
+      if (this.checkedProPlanLine.length == 0) {
+        this.$modal.msgError("请先选择要删除的生产计划明细数据");
+      } else {
+        const proPlanLineList = this.proPlanLineList;
+        const checkedProPlanLine = this.checkedProPlanLine;
+        this.proPlanLineList = proPlanLineList.filter(function(item) {
+          return checkedProPlanLine.indexOf(item.index) == -1
+        });
+      }
+    },
+    /** 复选框选中数据 */
+    handleProPlanLineSelectionChange(selection) {
+      this.checkedProPlanLine = selection.map(item => item.index)
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('pro/plan/export', {
+        ...this.queryParams
+      }, `plan_${new Date().getTime()}.xlsx`)
+    },
+    /** 导出按钮操作 */
+    handleLineExport() {
+      this.queryParams.planId = this.form.planId;
+      this.download('pro/line/export', {
+        ...this.queryParams
+      }, `plan_${new Date().getTime()}.xlsx`)
+    },
+    /** 设备选择 */
+    handleSelectMachinery(index){
+      this.addIndex = index;
+      this.$refs.machinerySelect.showFlag = true;
+    },
+    //设备资源选择回调
+    onMachineryAdd(rows){
+      console.log("=====" + rows);
+      const item = this.proPlanLineList[this.addIndex-1];
+      item.machineryId = rows.machineryId;
+      item.machineryCode = rows.machineryCode;
+      item.machineryName = rows.machineryName;
+    },
+
+    /** 物料选择 */
+    handleSelect(index) {
+      this.addIndex = index;
+      this.$refs.itemSelect.showFlag = true;
+    },
+    //物料资源选择回调
+    onItemAdd(rows){
+      console.log("=====" + rows);
+      const item = this.proPlanLineList[this.addIndex-1];
+      item.itemId = rows.itemId;
+      item.itemCode = rows.itemCode;
+      item.itemName = rows.itemName;
+      item.specification = rows.specification;
+    },
+    handleView(row){
+      this.reset();
+      const planId = row.planId || this.ids
+      getPlan(planId).then(response => {
+        this.form = response.data;
+        this.proPlanLineList = response.data.proPlanLineList;
+        this.open = true;
+        this.title = "修改生产计划";
+        this.optType = "view";
+      });
+    },
+      //自动生成编码
+    handleAutoGenChange(autoGenFlag){
+      if(autoGenFlag){
+        genCode('PRO_PLAN_CODE').then(response =>{
+          this.form.planCode = response;
+        });
+      }else{
+        this.form.planCode = null;
+      }
+    },
+  }
+};
+</script>