소스 검색

Merge remote-tracking branch 'origin/master'

zhanghe 5 달 전
부모
커밋
4145ca1137

+ 15 - 0
src/main/java/com/jeesite/modules/erp/dao/MesMaterialOrderDao.java

@@ -0,0 +1,15 @@
+package com.jeesite.modules.erp.dao;
+
+import com.jeesite.common.dao.CrudDao;
+import com.jeesite.common.mybatis.annotation.MyBatisDao;
+import com.jeesite.modules.erp.entity.MesMaterialOrder;
+
+/**
+ * 订单领料表DAO接口
+ * @author sxl
+ * @version 2026-05-09
+ */
+@MyBatisDao
+public interface MesMaterialOrderDao extends CrudDao<MesMaterialOrder> {
+	
+}

+ 81 - 0
src/main/java/com/jeesite/modules/erp/entity/MesMaterialOrder.java

@@ -0,0 +1,81 @@
+package com.jeesite.modules.erp.entity;
+
+import javax.validation.constraints.Size;
+import java.util.Date;
+import com.jeesite.common.mybatis.annotation.JoinTable;
+import com.jeesite.common.mybatis.annotation.JoinTable.Type;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import com.jeesite.common.entity.DataEntity;
+import com.jeesite.common.mybatis.annotation.Column;
+import com.jeesite.common.mybatis.annotation.Table;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+
+/**
+ * 订单领料表Entity
+ * @author sxl
+ * @version 2026-05-09
+ */
+@Table(name="mes_material_order", alias="a", label="订单领料表信息", columns={
+		@Column(name="id", attrName="id", label="id", isPK=true),
+		@Column(name="order_id", attrName="orderId", label="订单编号"),
+		@Column(name="requisition_no", attrName="requisitionNo", label="领料单号"),
+		@Column(name="update_by", attrName="updateBy", label="更新人", isQuery=false),
+		@Column(name="update_time", attrName="updateTime", label="更新时间", isUpdateForce=true),
+		@Column(name="create_by", attrName="createBy", label="创建人", isUpdate=false, isQuery=false),
+		@Column(name="create_time", attrName="createTime", label="创建时间", isUpdateForce=true),
+	}, orderBy="a.id DESC"
+)
+public class MesMaterialOrder extends DataEntity<MesMaterialOrder> {
+	
+	private static final long serialVersionUID = 1L;
+	private String orderId;		// 订单编号
+	private String requisitionNo;		// 领料单号
+	private Date updateTime;		// 更新时间
+	private Date createTime;		// 创建时间
+
+	public MesMaterialOrder() {
+		this(null);
+	}
+	
+	public MesMaterialOrder(String id){
+		super(id);
+	}
+	
+	@Size(min=0, max=64, message="订单编号长度不能超过 64 个字符")
+	public String getOrderId() {
+		return orderId;
+	}
+
+	public void setOrderId(String orderId) {
+		this.orderId = orderId;
+	}
+	
+	@Size(min=0, max=64, message="领料单号长度不能超过 64 个字符")
+	public String getRequisitionNo() {
+		return requisitionNo;
+	}
+
+	public void setRequisitionNo(String requisitionNo) {
+		this.requisitionNo = requisitionNo;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getUpdateTime() {
+		return updateTime;
+	}
+
+	public void setUpdateTime(Date updateTime) {
+		this.updateTime = updateTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+	
+}

+ 11 - 0
src/main/java/com/jeesite/modules/erp/entity/MesProductOrder.java

@@ -19,6 +19,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
 @Table(name="mes_product_order", alias="a", label="生产订单信息", columns={
 		@Column(name="id", attrName="id", label="id", isPK=true),
 		@Column(name="sn", attrName="sn", label="订单编号"),
+		@Column(name="line_sn", attrName="lineSn", label="产线编号"),
 		@Column(name="nums", attrName="nums", label="生产数量", isUpdateForce=true),
 		@Column(name="delivery_date", attrName="deliveryDate", label="交货日期", isUpdateForce=true),
 		@Column(name="remark", attrName="remark", label="备注"),
@@ -34,6 +35,7 @@ public class MesProductOrder extends DataEntity<MesProductOrder> {
 	
 	private static final long serialVersionUID = 1L;
 	private String sn;		// 订单编号
+	private String lineSn;		// 产线编号
 	private Integer nums;		// 生产数量
 	private Date deliveryDate;		// 交货日期
 	private String remark;		// 备注
@@ -55,6 +57,15 @@ public class MesProductOrder extends DataEntity<MesProductOrder> {
 	public void setSn(String sn) {
 		this.sn = sn;
 	}
+
+	@Size(min=0, max=64, message="产线编号长度不能超过 64 个字符")
+	public String getLineSn() {
+		return lineSn;
+	}
+
+	public void setLineSn(String lineSn) {
+		this.lineSn = lineSn;
+	}
 	
 	public Integer getNums() {
 		return nums;

+ 81 - 0
src/main/java/com/jeesite/modules/erp/service/MesMaterialOrderService.java

@@ -0,0 +1,81 @@
+package com.jeesite.modules.erp.service;
+
+import java.util.List;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.service.CrudService;
+import com.jeesite.modules.erp.entity.MesMaterialOrder;
+import com.jeesite.modules.erp.dao.MesMaterialOrderDao;
+
+/**
+ * 订单领料表Service
+ * @author sxl
+ * @version 2026-05-09
+ */
+@Service
+public class MesMaterialOrderService extends CrudService<MesMaterialOrderDao, MesMaterialOrder> {
+	
+	/**
+	 * 获取单条数据
+	 * @param mesMaterialOrder
+	 * @return
+	 */
+	@Override
+	public MesMaterialOrder get(MesMaterialOrder mesMaterialOrder) {
+		return super.get(mesMaterialOrder);
+	}
+	
+	/**
+	 * 查询分页数据
+	 * @param mesMaterialOrder 查询条件
+	 * @param mesMaterialOrder.page 分页对象
+	 * @return
+	 */
+	@Override
+	public Page<MesMaterialOrder> findPage(MesMaterialOrder mesMaterialOrder) {
+		return super.findPage(mesMaterialOrder);
+	}
+	
+	/**
+	 * 查询列表数据
+	 * @param mesMaterialOrder
+	 * @return
+	 */
+	@Override
+	public List<MesMaterialOrder> findList(MesMaterialOrder mesMaterialOrder) {
+		return super.findList(mesMaterialOrder);
+	}
+	
+	/**
+	 * 保存数据(插入或更新)
+	 * @param mesMaterialOrder
+	 */
+	@Override
+	@Transactional
+	public void save(MesMaterialOrder mesMaterialOrder) {
+		super.save(mesMaterialOrder);
+	}
+	
+	/**
+	 * 更新状态
+	 * @param mesMaterialOrder
+	 */
+	@Override
+	@Transactional
+	public void updateStatus(MesMaterialOrder mesMaterialOrder) {
+		super.updateStatus(mesMaterialOrder);
+	}
+	
+	/**
+	 * 删除数据
+	 * @param mesMaterialOrder
+	 */
+	@Override
+	@Transactional
+	public void delete(MesMaterialOrder mesMaterialOrder) {
+		super.delete(mesMaterialOrder);
+	}
+	
+}

+ 110 - 0
src/main/java/com/jeesite/modules/erp/web/MesMaterialOrderController.java

@@ -0,0 +1,110 @@
+package com.jeesite.modules.erp.web;
+
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.jeesite.modules.erp.entity.MesMaterialErp;
+import com.jeesite.modules.erp.service.MesMaterialErpService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.erp.entity.MesMaterialOrder;
+import com.jeesite.modules.erp.service.MesMaterialOrderService;
+
+/**
+ * 订单领料表Controller
+ * @author sxl
+ * @version 2026-05-09
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/erp/mesMaterialOrder")
+public class MesMaterialOrderController extends BaseController {
+
+	@Autowired
+	private MesMaterialOrderService mesMaterialOrderService;
+	@Autowired
+	private MesMaterialErpService mesMaterialErpService;
+
+	/**
+	 * 获取数据
+	 */
+	@ModelAttribute
+	public MesMaterialOrder get(String id, boolean isNewRecord) {
+		return mesMaterialOrderService.get(id, isNewRecord);
+	}
+
+	/**
+	 * 查询列表
+	 */
+	@RequiresPermissions("erp:mesMaterialOrder:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesMaterialOrder mesMaterialOrder, Model model) {
+		model.addAttribute("mesMaterialOrder", mesMaterialOrder);
+		return "modules/erp/mesMaterialOrderList";
+	}
+
+	//跳转到详情页面
+	@RequestMapping(value = {"list2", ""})
+	public String list2(MesMaterialOrder mesMaterialOrder, Model model) {
+		MesMaterialErp mesMaterialErp = new MesMaterialErp();
+		mesMaterialErp.setRequisitionNo(mesMaterialOrder.getRequisitionNo());
+		model.addAttribute("mesMaterialErp", mesMaterialErp);
+		return "modules/erp/mesMaterialErpList";
+	}
+
+	/**
+	 * 查询列表数据
+	 */
+	@RequiresPermissions("erp:mesMaterialOrder:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesMaterialOrder> listData(MesMaterialOrder mesMaterialOrder, HttpServletRequest request, HttpServletResponse response) {
+		mesMaterialOrder.setPage(new Page<>(request, response));
+		Page<MesMaterialOrder> page = mesMaterialOrderService.findPage(mesMaterialOrder);
+		return page;
+	}
+
+	/**
+	 * 查看编辑表单
+	 */
+	@RequiresPermissions("erp:mesMaterialOrder:view")
+	@RequestMapping(value = "form")
+	public String form(MesMaterialOrder mesMaterialOrder, Model model) {
+		model.addAttribute("mesMaterialOrder", mesMaterialOrder);
+		return "modules/erp/mesMaterialOrderForm";
+	}
+
+	/**
+	 * 保存数据
+	 */
+	@RequiresPermissions("erp:mesMaterialOrder:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesMaterialOrder mesMaterialOrder) {
+		mesMaterialOrderService.save(mesMaterialOrder);
+		return renderResult(Global.TRUE, text("保存订单领料表成功!"));
+	}
+
+	/**
+	 * 删除数据
+	 */
+	@RequiresPermissions("erp:mesMaterialOrder:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesMaterialOrder mesMaterialOrder) {
+		mesMaterialOrderService.delete(mesMaterialOrder);
+		return renderResult(Global.TRUE, text("删除订单领料表成功!"));
+	}
+
+}

+ 1 - 1
src/main/java/com/jeesite/modules/mes/web/MesProductController.java

@@ -287,7 +287,7 @@ public class MesProductController extends BaseController {
 
 	@RequestMapping(value = {"screen", ""})
 	public String screen(Model model) {
-		return "modules/mes/mesScreen4";
+		return "modules/mes/mesScreen3";
 	}
 
 	@RequestMapping(value = {"screen3"})

+ 15 - 0
src/main/resources/mappings/modules/erp/MesMaterialOrderDao.xml

@@ -0,0 +1,15 @@
+<?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.jeesite.modules.erp.dao.MesMaterialOrderDao">
+	
+	<!-- 查询数据
+	<select id="findList" resultType="MesMaterialOrder">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select> -->
+	
+</mapper>

+ 5 - 7
src/main/resources/views/modules/erp/mesMaterialErpList.html

@@ -62,13 +62,11 @@
 $('#dataGrid').dataGrid({
 	searchForm: $("#searchForm"),
 	columnModel: [
-		{header:'${text("物料单号")}', name:'materialCode', index:'a.material_code', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
-			return '<a href="${ctx}/erp/mesMaterialErp/form?id='+row.id+'" class="btnList" data-title="${text("编辑mes_material_erp")}">'+(val||row.id)+'</a>';
-		}},
-		{header:'${text("物料名称")}', name:'materialName', index:'a.material_name', width:150, align:"left"},
-		{header:'${text("物料数量")}', name:'materialNumber', index:'a.material_number', width:150, align:"left"},
-		{header:'${text("物料规格")}', name:'materiarSize', index:'a.materiar_size', width:150, align:"left"},
-		{header:'${text("生产领料单")}', name:'requisitionNo', index:'a.requisition_no', width:150, align:"left"},
+		{header:'${text("物料单号")}', name:'materialCode', index:'a.material_code', width:150, align:"center"},
+		{header:'${text("物料名称")}', name:'materialName', index:'a.material_name', width:150, align:"center"},
+		{header:'${text("物料数量")}', name:'materialNumber', index:'a.material_number', width:150, align:"center"},
+		{header:'${text("物料规格")}', name:'materiarSize', index:'a.materiar_size', width:150, align:"center"},
+		{header:'${text("生产领料单")}', name:'requisitionNo', index:'a.requisition_no', width:150, align:"center"},
 		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
 			var actions = [];
 			//<% if(hasPermi('erp:mesMaterialErp:edit')){ %>

+ 84 - 0
src/main/resources/views/modules/erp/mesMaterialOrderForm.html

@@ -0,0 +1,84 @@
+<% layout('/layouts/default.html', {title: '订单领料表管理', libs: ['validate']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header with-border">
+			<div class="box-title">
+				<i class="fa icon-note"></i> ${text(mesMaterialOrder.isNewRecord ? '新增订单领料表' : '编辑订单领料表')}
+			</div>
+			<div class="box-tools pull-right">
+				<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
+			</div>
+		</div>
+		<#form:form id="inputForm" model="${mesMaterialOrder}" action="${ctx}/erp/mesMaterialOrder/save" method="post" class="form-horizontal">
+			<div class="box-body">
+				<div class="form-unit">${text('基本信息')}</div>
+				<#form:hidden path="id"/>
+				<div class="row">
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('订单编号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="orderId" maxlength="64" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('领料单号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="requisitionNo" maxlength="64" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('更新时间')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="updateTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('创建时间')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="createTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+			<div class="box-footer">
+				<div class="row">
+					<div class="col-sm-offset-2 col-sm-10">
+						<% if (hasPermi('erp:mesMaterialOrder:edit')){ %>
+							<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
+						<% } %>
+						<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
+					</div>
+				</div>
+			</div>
+		</#form:form>
+	</div>
+</div>
+<% } %>
+<script>
+$("#inputForm").validate({
+	submitHandler: function(form){
+		js.ajaxSubmitForm($(form), function(data){
+			js.showMessage(data.message);
+			if(data.result == Global.TRUE){
+				js.closeCurrentTabPage(function(contentWindow){
+					contentWindow.page();
+				});
+			}
+		}, "json");
+    }
+});
+</script>

+ 86 - 0
src/main/resources/views/modules/erp/mesMaterialOrderList.html

@@ -0,0 +1,86 @@
+<% layout('/layouts/default.html', {title: '订单领料表管理', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa icon-notebook"></i> ${text('订单领料表管理')}
+			</div>
+			<div class="box-tools pull-right">
+				<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
+				<% if(hasPermi('erp:mesMaterialOrder:edit')){ %>
+					<a href="${ctx}/erp/mesMaterialOrder/form" class="btn btn-default btnTool" title="${text('新增订单领料表')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
+				<% } %>
+				<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
+			</div>
+		</div>
+		<div class="box-body">
+			<#form:form id="searchForm" model="${mesMaterialOrder}" action="${ctx}/erp/mesMaterialOrder/listData" method="post" class="form-inline hide"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<div class="form-group">
+					<label class="control-label">${text('订单编号')}:</label>
+					<div class="control-inline">
+						<#form:input path="orderId" maxlength="64" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('领料单号')}:</label>
+					<div class="control-inline">
+						<#form:input path="requisitionNo" maxlength="64" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('更新时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="updateTime" readonly="true" maxlength="20" class="form-control laydate width-datetime"
+							dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('创建时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="createTime" readonly="true" maxlength="20" class="form-control laydate width-datetime"
+							dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+// 初始化DataGrid对象
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("订单编号")}', name:'orderId', index:'a.order_id', width:150, align:"center"},
+		{header:'${text("领料单号")}', name:'requisitionNo', index:'a.requisition_no', width:150, align:"center", formatter: function(val, obj, row, act){
+				if (val) {
+					// 使用 class="btnList" 通常会结合底层框架自动弹窗或打开新Tab
+					// 【注意】请将 href 中的 URL 替换为你实际查询领料单详情的 Controller 路由
+					return '<a href="${ctx}/erp/mesMaterialOrder/list2?requisitionNo=' + val + '" class="btnList" data-title="${text("领料单详情")}">' + val + '</a>';
+				}
+				return '';
+			}},
+		{header:'${text("更新时间")}', name:'updateTime', index:'a.update_time', width:150, align:"center"},
+		{header:'${text("创建时间")}', name:'createTime', index:'a.create_time', width:150, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('erp:mesMaterialOrder:edit')){ %>
+				actions.push('<a href="${ctx}/erp/mesMaterialOrder/form?id='+row.id+'" class="btnList" title="${text("编辑订单领料表")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/erp/mesMaterialOrder/delete?id='+row.id+'" class="btnList" title="${text("删除订单领料表")}" data-confirm="${text("确认要删除该订单领料表吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+			//<% } %>
+			return actions.join('');
+		}}
+	],
+	// 加载成功后执行事件
+	ajaxSuccess: function(data){
+
+	}
+});
+</script>

+ 9 - 0
src/main/resources/views/modules/erp/mesProductOrderForm.html

@@ -26,6 +26,15 @@
 					<div class="col-xs-6">
 						<div class="form-group">
 							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('产线编号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="lineSn" maxlength="64" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
 								<span class="required hide">*</span> ${text('生产数量')}:<i class="fa icon-question hide"></i></label>
 							<div class="col-sm-8">
 								<#form:input path="nums" maxlength="8" class="form-control digits"/>

+ 13 - 5
src/main/resources/views/modules/erp/mesProductOrderList.html

@@ -23,6 +23,12 @@
 					</div>
 				</div>
 				<div class="form-group">
+					<label class="control-label">${text('产线编号')}:</label>
+					<div class="control-inline">
+						<#form:input path="lineSn" maxlength="64" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
 					<label class="control-label">${text('生产数量')}:</label>
 					<div class="control-inline">
 						<#form:input path="nums" maxlength="8" class="form-control width-120"/>
@@ -69,13 +75,15 @@
 $('#dataGrid').dataGrid({
 	searchForm: $("#searchForm"),
 	columnModel: [
-		{header:'${text("订单编号")}', name:'sn', index:'a.sn', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
-			return '<a href="${ctx}/erp/mesProductOrder/form?id='+row.id+'" class="btnList" data-title="${text("编辑生产订单")}">'+(val||row.id)+'</a>';
-		}},
+		// {header:'${text("订单编号")}', name:'sn', index:'a.sn', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
+		// 	return '<a href="${ctx}/erp/mesProductOrder/form?id='+row.id+'" class="btnList" data-title="${text("编辑生产订单")}">'+(val||row.id)+'</a>';
+		// }},
+		{header:'${text("订单编号")}', name:'sn', index:'a.sn', width:150, align:"center"},
+		{header:'${text("产线编号")}', name:'lineSn', index:'a.line_sn', width:120, align:"center"},
 		{header:'${text("生产数量")}', name:'nums', index:'a.nums', width:150, align:"center"},
 		{header:'${text("交货日期")}', name:'deliveryDate', index:'a.delivery_date', width:150, align:"center"},
-		{header:'${text("备注")}', name:'remark', index:'a.remark', width:150, align:"left"},
-		{header:'${text("状态")}', name:'state', index:'a.state', width:150, align:"left"},
+		{header:'${text("备注")}', name:'remark', index:'a.remark', width:150, align:"center"},
+		{header:'${text("状态")}', name:'state', index:'a.state', width:150, align:"center"},
 		{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
 		// {header:'${text("状态")}', name:'status', index:'a.status', width:150, align:"center", formatter: function(val, obj, row, act){
 		// 	return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text("未知")}', true);

+ 289 - 11
src/main/resources/views/modules/mes/mesScreen3.html

@@ -672,7 +672,7 @@
 					<div class="card-value" id="actualProduction">225</div>
 				</div>
 				<div class="mes3-data-card">
-					<div class="card-label">近修数量</div>
+					<div class="card-label">返修数量</div>
 					<div class="card-value" id="repairCount">11</div>
 				</div>
 				<div class="mes3-data-card">
@@ -755,7 +755,7 @@
 
 		<!-- 右侧面板3: 报警信息 -->
 		<div class="mes3-panel-right3">
-			<div class="panel-header">报警信息</div>
+			<div class="panel-header">设备报警(类型)</div>
 			<div class="panel-body" style="padding: 0 15px;">
 				<div id="alertList" class="mes3-alert-list"></div>
 			</div>
@@ -842,13 +842,8 @@
 			max: 120
 		};
 
-		// 6. 报警信息 (右3)
-		mockData.alerts = [
-			{ no: 1, text: '产线不良率超过3%' },
-			{ no: 2, text: '产线不良率超过5%' },
-			{ no: 3, text: '产线不良率超过3%' },
-			{ no: 4, text: '产线不良率超过7%' }
-		];
+		// 6. 报警信息由 updateDeviceAlarmAlertsByApi 拉取 mesDeviceAlarm/listData,展示 type
+		mockData.alerts = [];
 
 		// 7. 设备故障统计分析 - 故障类型排名
 		mockData.faultRank = [
@@ -1339,14 +1334,23 @@
 		if (el) el.innerHTML = html;
 	}
 
-	// 渲染报警信息列表
+	function escapeHtml(s) {
+		if (s == null || s === '') return '';
+		return String(s)
+			.replace(/&/g, '&amp;')
+			.replace(/</g, '&lt;')
+			.replace(/>/g, '&gt;')
+			.replace(/"/g, '&quot;');
+	}
+
+	// 渲染报警信息列表(text 为设备报警记录的 type 字段)
 	function renderAlerts() {
 		var list = mockData.alerts || [];
 		var html = '';
 		for (var i = 0; i < list.length; i++) {
 			html += '<div class="mes3-alert-item">';
 			html += '<div class="alert-no">' + list[i].no + '</div>';
-			html += '<div class="alert-text">' + list[i].text + '</div>';
+			html += '<div class="alert-text">' + escapeHtml(list[i].text) + '</div>';
 			html += '</div>';
 		}
 		var el = document.getElementById('alertList');
@@ -1372,10 +1376,284 @@
 		}
 	}
 
+	function extractList(resp) {
+		if (!resp) return [];
+		if (Object.prototype.toString.call(resp.list) === '[object Array]') return resp.list;
+		if (Object.prototype.toString.call(resp.rows) === '[object Array]') return resp.rows;
+		if (resp.data) {
+			if (Object.prototype.toString.call(resp.data.list) === '[object Array]') return resp.data.list;
+			if (Object.prototype.toString.call(resp.data.rows) === '[object Array]') return resp.data.rows;
+		}
+		return [];
+	}
+
+	function updateDeviceAlarmAlertsByApi() {
+		$.ajax({
+			url: '${ctx}/mes/mesDeviceAlarm/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 50
+			},
+			success: function(resp) {
+				var rows = extractList(resp);
+				var alerts = [];
+				for (var i = 0; i < rows.length; i++) {
+					var r = rows[i] || {};
+					var typ = (r.type != null && r.type !== undefined) ? String(r.type) : '';
+					alerts.push({ no: i + 1, text: typ });
+				}
+				mockData.alerts = alerts;
+				renderAlerts();
+			},
+			error: function() {
+				mockData.alerts = [];
+				renderAlerts();
+			}
+		});
+	}
+
+	function updateProductionPeopleByApi() {
+		$.ajax({
+			url: '${ctx}/sys/empUser/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 5000,
+				'employee.office.officeName': '生产部'
+			},
+			success: function(resp) {
+				var peopleCount = 0;
+				var users = extractList(resp);
+				for (var i = 0; i < users.length; i++) {
+					var u = users[i] || {};
+					var office = (u.employee && u.employee.office) ? u.employee.office : {};
+					var officeName = office.officeName || '';
+					var normalizedOfficeName = (officeName + '').replace(/\s/g, '');
+					if (normalizedOfficeName === '生产部' || /[/\\>]+生产部$/.test(normalizedOfficeName)) {
+						peopleCount++;
+					}
+				}
+				mockData.cards = mockData.cards || {};
+				mockData.cards.productionPeople = peopleCount;
+				var target = document.getElementById('productionPeople');
+				if (target) target.textContent = peopleCount;
+			}
+		});
+	}
+
+	function updateDeviceCountByApi() {
+		$.ajax({
+			url: '${ctx}/mes/mesDevice/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 1
+			},
+			success: function(resp) {
+				var deviceCount = 0;
+				if (resp && typeof resp.count === 'number') {
+					deviceCount = resp.count;
+				} else {
+					deviceCount = extractList(resp).length;
+				}
+				mockData.cards = mockData.cards || {};
+				mockData.cards.deviceCount = deviceCount;
+				var target = document.getElementById('deviceCount');
+				if (target) target.textContent = deviceCount;
+			}
+		});
+	}
+
+	function isOpr240Family(oprno) {
+		var op = (oprno || '').replace(/\s/g, '').toUpperCase();
+		if (op.length < 5 || op.indexOf('OP240') !== 0) return false;
+		if (op.length === 5) return op === 'OP240';
+		return /^OP240[A-Z0-9_-]+$/.test(op);
+	}
+
+	function isRecordContentOk(content) {
+		var c = (content || '').replace(/\s/g, '').toUpperCase();
+		return c === 'OK';
+	}
+
+	function getCalendarDayUpdateDateRange() {
+		var now = new Date();
+		var p = function(n) { return n < 10 ? '0' + n : '' + n; };
+		var dateStr = now.getFullYear() + '-' + p(now.getMonth() + 1) + '-' + p(now.getDate());
+		return {
+			gte: dateStr + ' 00:00:00',
+			lte: dateStr + ' 23:59:59',
+			startMs: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime(),
+			endMs: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999).getTime()
+		};
+	}
+
+	function parseRecordDateMs(val) {
+		if (val == null || val === '') return NaN;
+		if (typeof val === 'number' && !isNaN(val)) return val;
+		var s = String(val).trim().replace(/-/g, '/');
+		var t = Date.parse(s);
+		return isNaN(t) ? NaN : t;
+	}
+
+	function isRecordWithinToday(r, day) {
+		var t = parseRecordDateMs(r.updateDate || r.update_date);
+		if (isNaN(t)) return false;
+		return t >= day.startMs && t <= day.endMs;
+	}
+
+	function updateActualProductionByApi() {
+		var dayRange = getCalendarDayUpdateDateRange();
+		var pageSize = 3000;
+		var maxPages = 200;
+		var pageNo = 1;
+		var totalOk = 0;
+		function fetchPage() {
+			$.ajax({
+				url: '${ctx}/mes/mesProductRecord/listData',
+				type: 'POST',
+				dataType: 'json',
+				data: {
+					pageNo: pageNo,
+					pageSize: pageSize,
+					oprno: 'OP240',
+					content: 'OK',
+					lineSn: 'XT',
+					updateDate_gte: dayRange.gte,
+					updateDate_lte: dayRange.lte
+				},
+				success: function(resp) {
+					var list = extractList(resp);
+					for (var i = 0; i < list.length; i++) {
+						var r = list[i] || {};
+						if (isOpr240Family(r.oprno) && isRecordContentOk(r.content) && isRecordWithinToday(r, dayRange) && String(r.lineSn || r.line_sn || '').toUpperCase() === 'XT') {
+							totalOk++;
+						}
+					}
+					if (list.length === pageSize && pageNo < maxPages) {
+						pageNo++;
+						fetchPage();
+					} else {
+						mockData.cards = mockData.cards || {};
+						mockData.cards.actualProduction = totalOk;
+						var target = document.getElementById('actualProduction');
+						if (target) target.textContent = totalOk;
+					}
+				},
+				error: function() {
+					mockData.cards = mockData.cards || {};
+					mockData.cards.actualProduction = totalOk;
+					var target = document.getElementById('actualProduction');
+					if (target) target.textContent = totalOk;
+				}
+			});
+		}
+		fetchPage();
+	}
+
+	function matchesXtOp240OkRecord(r) {
+		var t = parseRecordDateMs(r.updateDate || r.update_date);
+		if (isNaN(t)) return false;
+		if (!isOpr240Family(r.oprno) || !isRecordContentOk(r.content)) return false;
+		if (String(r.lineSn || r.line_sn || '').toUpperCase() !== 'XT') return false;
+		return true;
+	}
+
+	function dateKeyFromMs(ms, padFn) {
+		var d = new Date(ms);
+		return d.getFullYear() + '-' + padFn(d.getMonth() + 1) + '-' + padFn(d.getDate());
+	}
+
+	function updateProductTrend7DaysByApi() {
+		var now = new Date();
+		var padFn = function(n) { return n < 10 ? '0' + n : '' + n; };
+		var labels = [];
+		var dayKeys = [];
+		var i;
+		for (i = 6; i >= 0; i--) {
+			var d = new Date(now.getFullYear(), now.getMonth(), now.getDate() - i);
+			labels.push((d.getMonth() + 1) + '月' + d.getDate() + '日');
+			dayKeys.push(d.getFullYear() + '-' + padFn(d.getMonth() + 1) + '-' + padFn(d.getDate()));
+		}
+		var oldest = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6);
+		var gte = oldest.getFullYear() + '-' + padFn(oldest.getMonth() + 1) + '-' + padFn(oldest.getDate()) + ' 00:00:00';
+		var lte = now.getFullYear() + '-' + padFn(now.getMonth() + 1) + '-' + padFn(now.getDate()) + ' 23:59:59';
+
+		var counts = {};
+		for (i = 0; i < dayKeys.length; i++) {
+			counts[dayKeys[i]] = 0;
+		}
+
+		var pageSize = 3000;
+		var maxPages = 500;
+		var pageNo = 1;
+
+		function fetchPage() {
+			$.ajax({
+				url: '${ctx}/mes/mesProductRecord/listData',
+				type: 'POST',
+				dataType: 'json',
+				data: {
+					pageNo: pageNo,
+					pageSize: pageSize,
+					oprno: 'OP240',
+					content: 'OK',
+					lineSn: 'XT',
+					updateDate_gte: gte,
+					updateDate_lte: lte
+				},
+				success: function(resp) {
+					var list = extractList(resp);
+					var j;
+					for (j = 0; j < list.length; j++) {
+						var r = list[j] || {};
+						if (!matchesXtOp240OkRecord(r)) continue;
+						var t = parseRecordDateMs(r.updateDate || r.update_date);
+						var key = dateKeyFromMs(t, padFn);
+						if (Object.prototype.hasOwnProperty.call(counts, key)) {
+							counts[key]++;
+						}
+					}
+					if (list.length === pageSize && pageNo < maxPages) {
+						pageNo++;
+						fetchPage();
+					} else {
+						var data = [];
+						for (j = 0; j < dayKeys.length; j++) {
+							data.push(counts[dayKeys[j]] || 0);
+						}
+						var mx = Math.max.apply(null, data.concat([0]));
+						var maxV = mx <= 0 ? 10 : Math.ceil(mx * 1.15);
+						mockData.productTrend = {
+							labels: labels,
+							data: data,
+							max: maxV,
+							min: 0
+						};
+						drawAllCharts();
+					}
+				},
+				error: function() {
+					drawAllCharts();
+				}
+			});
+		}
+		fetchPage();
+	}
+
 	function refreshData() {
 		// 暂未修改后台接口,直接使用 mock 数据
 		generateMockData();
 		renderTextData();
+		updateProductionPeopleByApi();
+		updateDeviceCountByApi();
+		updateActualProductionByApi();
+		updateProductTrend7DaysByApi();
+		updateDeviceAlarmAlertsByApi();
 		renderFaultRank();
 		renderAlerts();
 		drawAllCharts();

+ 248 - 13
src/main/resources/views/modules/mes/mesScreen4.html

@@ -270,7 +270,7 @@
 
 	<div class="mes4-header">
 		<img class="mes4-logo" src="${ctxStatic}/screen/imgs/ljrLogo.png" alt="logo">
-		<div class="mes4-title">半成品【P10-P70】阶段统计大屏</div>
+		<div class="mes4-title">半成品阶段统计大屏</div>
 		<div class="mes4-datetime">
 			<span class="mes4-date" id="mes4Date"></span>
 			<span class="mes4-time" id="mes4Time"></span>
@@ -280,7 +280,7 @@
 	<div class="mes4-panel p-alert">
 		<div class="mes4-ptitle">  产线阶段报警信息  </div>
 		<div class="mes4-pbody" style="padding:0">
-			<div class="alert-head"><div>序号</div><div>报警信息</div></div>
+			<div class="alert-head"><div>序号</div><div>报警类型</div></div>
 			<div id="alertList"></div>
 		</div>
 	</div>
@@ -402,15 +402,8 @@
 			weekLabels.push((d.getMonth() + 1) + '月' + d.getDate() + '日');
 		}
 
-		// 报警信息
-		mockData.alerts = [
-			{ no: 1, text: '产线不良率超过3%' },
-			{ no: 2, text: '产线不良率超过5%' },
-			{ no: 3, text: '产线不良率超过3%' },
-			{ no: 4, text: '产线不良率超过7%' },
-			{ no: 5, text: '产线不良率超过3%' },
-			{ no: 6, text: '产线不良率超过7%' }
-		];
+		// 报警信息由 updateDeviceAlarmAlertsByApi 拉取 mesDeviceAlarm/listData,展示 type
+		mockData.alerts = [];
 
 		// OP 表格
 		mockData.opTable = [
@@ -777,12 +770,21 @@
 		ctx.stroke();
 	}
 
-	// ====== 渲染列表 ======
+	function escapeHtml(s) {
+		if (s == null || s === '') return '';
+		return String(s)
+			.replace(/&/g, '&amp;')
+			.replace(/</g, '&lt;')
+			.replace(/>/g, '&gt;')
+			.replace(/"/g, '&quot;');
+	}
+
+	// ====== 渲染列表(text 为设备报警记录的 type 字段)======
 	function renderAlerts() {
 		var html = '';
 		var list = mockData.alerts || [];
 		for (var i = 0; i < list.length; i++) {
-			html += '<div class="alert-row"><div>' + list[i].no + '</div><div>' + list[i].text + '</div></div>';
+			html += '<div class="alert-row"><div>' + list[i].no + '</div><div>' + escapeHtml(list[i].text) + '</div></div>';
 		}
 		var el = document.getElementById('alertList');
 		if (el) el.innerHTML = html;
@@ -804,6 +806,40 @@
 		var el = document.getElementById('opTableBody');
 		if (el) el.innerHTML = html;
 	}
+
+	function updateLineProcessTableByApi() {
+		$.ajax({
+			url: '${ctx}/mes/mesLineProcess/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 5000,
+				lineSn: 'MP'
+			},
+			success: function(resp) {
+				var rows = extractUserList(resp);
+				var out = [];
+				for (var i = 0; i < rows.length; i++) {
+					var p = rows[i] || {};
+					var ls = String(p.lineSn || p.line_sn || '').toUpperCase();
+					if (ls !== 'MP') continue;
+					out.push({
+						code: p.oprno || '',
+						name: p.title || '',
+						plan: 0,
+						hour: 0,
+						real: 0,
+						shift: 0
+					});
+				}
+				if (out.length > 0) {
+					mockData.opTable = out;
+					renderTable();
+				}
+			}
+		});
+	}
 	function renderCards() {
 		var c = mockData.cards || {};
 		var m = {
@@ -819,6 +855,200 @@
 		}
 	}
 
+	function extractUserList(resp) {
+		if (!resp) return [];
+		if (Object.prototype.toString.call(resp.list) === '[object Array]') return resp.list;
+		if (Object.prototype.toString.call(resp.rows) === '[object Array]') return resp.rows;
+		if (resp.data) {
+			if (Object.prototype.toString.call(resp.data.list) === '[object Array]') return resp.data.list;
+			if (Object.prototype.toString.call(resp.data.rows) === '[object Array]') return resp.data.rows;
+		}
+		return [];
+	}
+
+	function updateDeviceAlarmAlertsByApi() {
+		$.ajax({
+			url: '${ctx}/mes/mesDeviceAlarm/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 50
+			},
+			success: function(resp) {
+				var rows = extractUserList(resp);
+				var alerts = [];
+				for (var i = 0; i < rows.length; i++) {
+					var r = rows[i] || {};
+					var typ = (r.type != null && r.type !== undefined) ? String(r.type) : '';
+					alerts.push({ no: i + 1, text: typ });
+				}
+				mockData.alerts = alerts;
+				renderAlerts();
+			},
+			error: function() {
+				mockData.alerts = [];
+				renderAlerts();
+			}
+		});
+	}
+
+	function updateProductionPeopleByApi() {
+		$.ajax({
+			url: '${ctx}/sys/empUser/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 5000,
+				'employee.office.officeName': '生产部'
+			},
+			success: function(resp) {
+				var peopleCount = 0;
+				var users = extractUserList(resp);
+				for (var i = 0; i < users.length; i++) {
+					var u = users[i] || {};
+					var office = (u.employee && u.employee.office) ? u.employee.office : {};
+					var officeName = office.officeName || '';
+					var normalizedOfficeName = (officeName + '').replace(/\s/g, '');
+					if (
+						normalizedOfficeName === '生产部' ||
+						/[/\\>]+生产部$/.test(normalizedOfficeName)
+					) {
+						peopleCount++;
+					}
+				}
+				mockData.cards = mockData.cards || {};
+				mockData.cards.productionPeople = peopleCount;
+				var target = document.getElementById('productionPeople');
+				if (target) target.textContent = peopleCount;
+			}
+		});
+	}
+
+	function updateDeviceCountByApi() {
+		$.ajax({
+			url: '${ctx}/mes/mesDevice/listData',
+			type: 'POST',
+			dataType: 'json',
+			data: {
+				pageNo: 1,
+				pageSize: 1
+			},
+			success: function(resp) {
+				var deviceCount = 0;
+				if (resp && typeof resp.count === 'number') {
+					deviceCount = resp.count;
+				} else {
+					var devices = extractUserList(resp);
+					deviceCount = devices.length;
+				}
+				mockData.cards = mockData.cards || {};
+				mockData.cards.deviceCount = deviceCount;
+				var target = document.getElementById('deviceCount');
+				if (target) target.textContent = deviceCount;
+			}
+		});
+	}
+
+	function isOpr190Family(oprno) {
+		var op = (oprno || '').replace(/\s/g, '').toUpperCase();
+		if (op.length < 5 || op.indexOf('OP190') !== 0) {
+			return false;
+		}
+		if (op.length === 5) {
+			return op === 'OP190';
+		}
+		return /^OP190[A-Z0-9_-]+$/.test(op);
+	}
+
+	function isRecordContentOk(content) {
+		var c = (content || '').replace(/\s/g, '').toUpperCase();
+		return c === 'OK';
+	}
+
+	function applyActualProductionCount(n) {
+		mockData.cards = mockData.cards || {};
+		mockData.cards.actualProduction = n;
+		var target = document.getElementById('actualProduction');
+		if (target) target.textContent = n;
+	}
+
+	function getCalendarDayUpdateDateRange() {
+		var now = new Date();
+		var pad = function(n) { return n < 10 ? '0' + n : '' + n; };
+		var dateStr = now.getFullYear() + '-' + pad(now.getMonth() + 1) + '-' + pad(now.getDate());
+		return {
+			gte: dateStr + ' 00:00:00',
+			lte: dateStr + ' 23:59:59',
+			startMs: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime(),
+			endMs: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999).getTime()
+		};
+	}
+
+	function parseRecordDateMs(val) {
+		if (val == null || val === '') {
+			return NaN;
+		}
+		if (typeof val === 'number' && !isNaN(val)) {
+			return val;
+		}
+		var s = String(val).trim().replace(/-/g, '/');
+		var t = Date.parse(s);
+		return isNaN(t) ? NaN : t;
+	}
+
+	function isRecordWithinToday(r, day) {
+		var t = parseRecordDateMs(r.updateDate || r.update_date);
+		if (isNaN(t)) {
+			return false;
+		}
+		return t >= day.startMs && t <= day.endMs;
+	}
+
+	function updateActualProductionByApi() {
+		var dayRange = getCalendarDayUpdateDateRange();
+		var pageSize = 3000;
+		var maxPages = 200;
+		var pageNo = 1;
+		var totalOk = 0;
+		function fetchPage() {
+			$.ajax({
+				url: '${ctx}/mes/mesProductRecord/listData',
+				type: 'POST',
+				dataType: 'json',
+				data: {
+					pageNo: pageNo,
+					pageSize: pageSize,
+					oprno: 'OP190',
+					content: 'OK',
+					lineSn: 'MP',
+					updateDate_gte: dayRange.gte,
+					updateDate_lte: dayRange.lte
+				},
+				success: function(resp) {
+					var list = extractUserList(resp);
+					for (var i = 0; i < list.length; i++) {
+						var r = list[i] || {};
+						if (isOpr190Family(r.oprno) && isRecordContentOk(r.content) && isRecordWithinToday(r, dayRange) && String(r.lineSn || r.line_sn || '').toUpperCase() === 'MP') {
+							totalOk++;
+						}
+					}
+					if (list.length === pageSize && pageNo < maxPages) {
+						pageNo++;
+						fetchPage();
+					} else {
+						applyActualProductionCount(totalOk);
+					}
+				},
+				error: function() {
+					applyActualProductionCount(totalOk);
+				}
+			});
+		}
+		fetchPage();
+	}
+
 	function drawAllCharts() {
 		var q = mockData.qualityInspect;
 		if (q) drawDoubleBar('chartQuality', q.produced, q.defect, q.labels, q.max);
@@ -838,6 +1068,11 @@
 		renderAlerts();
 		renderTable();
 		renderCards();
+		updateLineProcessTableByApi();
+		updateProductionPeopleByApi();
+		updateDeviceCountByApi();
+		updateActualProductionByApi();
+		updateDeviceAlarmAlertsByApi();
 		drawAllCharts();
 	}