liuwei 2 kuukautta sitten
vanhempi
commit
730f5a7361

+ 15 - 4
db/mes_product_screen.sql

@@ -1,14 +1,18 @@
+-- 已有表 mes_product_screen 字段:people_num / machine_num / plan_output / create_by
+-- 为兼容 JeeSite 保存(字符串 id、时间戳),执行以下变更:
 
 ALTER TABLE `mes_product_screen`
-  MODIFY COLUMN `id` varchar(64) NOT NULL COMMENT '编号',
-  ADD COLUMN IF NOT EXISTS `create_date` datetime DEFAULT NULL COMMENT '创建时间' AFTER `create_by`,
-  ADD COLUMN IF NOT EXISTS `update_by` varchar(64) DEFAULT NULL COMMENT '更新者' AFTER `create_date`,
-  ADD COLUMN IF NOT EXISTS `update_date` datetime DEFAULT NULL COMMENT '更新时间' AFTER `update_by`;
+  MODIFY COLUMN `id` varchar(64) NOT NULL COMMENT '缂栧彿',
+  ADD COLUMN IF NOT EXISTS `create_date` datetime DEFAULT NULL COMMENT '鍒涘缓鏃堕棿' AFTER `create_by`,
+  ADD COLUMN IF NOT EXISTS `update_by` varchar(64) DEFAULT NULL COMMENT '更新者' AFTER `create_date`,
+  ADD COLUMN IF NOT EXISTS `update_date` datetime DEFAULT NULL COMMENT '鏇存柊鏃堕棿' AFTER `update_by`;
 
+-- MySQL 5.7 鑻ヤ笉鏀�寔 IF NOT EXISTS锛屽彲鏀圭敤涓嬮潰锛堝凡鏈夊垪浼氭姤閿欏彲蹇界暐锛夛細
+-- ALTER TABLE `mes_product_screen` MODIFY COLUMN `id` varchar(64) NOT NULL COMMENT '缂栧彿';
+-- ALTER TABLE `mes_product_screen` ADD COLUMN `create_date` datetime DEFAULT NULL COMMENT '鍒涘缓鏃堕棿' AFTER `create_by`;
+-- ALTER TABLE `mes_product_screen` ADD COLUMN `update_by` varchar(64) DEFAULT NULL COMMENT '更新者' AFTER `create_date`;
+-- ALTER TABLE `mes_product_screen` ADD COLUMN `update_date` datetime DEFAULT NULL COMMENT '鏇存柊鏃堕棿' AFTER `update_by`;
+
+-- 工位当天计划(JSON:{"OP060":30,"OP070":30})
+ALTER TABLE `mes_product_screen`
+  ADD COLUMN `op_plan` varchar(2000) DEFAULT NULL COMMENT '宸ヤ綅褰撳ぉ璁″垝' AFTER `plan_output`;

+ 12 - 0
src/main/java/com/jeesite/modules/mes/entity/MesProductScreen.java

@@ -20,6 +20,7 @@ import javax.validation.constraints.Size;
 		@Column(name="people_num", attrName="peopleNum", label="生产人数"),
 		@Column(name="machine_num", attrName="machineNum", label="设备数量"),
 		@Column(name="plan_output", attrName="planOutput", label="每日计划"),
+		@Column(name="op_plan", attrName="opPlan", label="工位当天计划", isQuery=false),
 		@Column(name="create_by", attrName="createBy", label="创建人", isUpdate=false, isQuery=false),
 		@Column(name="create_date", attrName="createDate", label="创建日期", isUpdate=false, isQuery=false, isUpdateForce=true),
 		@Column(name="update_by", attrName="updateBy", label="update_by", isQuery=false),
@@ -34,6 +35,8 @@ public class MesProductScreen extends DataEntity<MesProductScreen> {
 	private String peopleNum;
 	private String machineNum;
 	private String planOutput;
+	/** 工位当天计划 JSON,如 {"OP060":30,"OP070":30} */
+	private String opPlan;
 
 	public MesProductScreen() {
 		this(null);
@@ -82,4 +85,13 @@ public class MesProductScreen extends DataEntity<MesProductScreen> {
 	public void setPlanOutput(String planOutput) {
 		this.planOutput = planOutput;
 	}
+
+	@Size(min=0, max=2000, message="工位当天计划长度不能超过 2000 个字符")
+	public String getOpPlan() {
+		return opPlan;
+	}
+
+	public void setOpPlan(String opPlan) {
+		this.opPlan = opPlan;
+	}
 }

+ 34 - 0
src/main/java/com/jeesite/modules/mes/service/MesProductScreenService.java

@@ -1,14 +1,19 @@
 package com.jeesite.modules.mes.service;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.jeesite.common.entity.Page;
 import com.jeesite.common.lang.ObjectUtils;
+import com.jeesite.common.lang.StringUtils;
 import com.jeesite.common.service.CrudService;
 import com.jeesite.modules.mes.dao.MesProductScreenDao;
 import com.jeesite.modules.mes.entity.MesProductScreen;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 大屏展示配置Service
@@ -91,4 +96,33 @@ public class MesProductScreenService extends CrudService<MesProductScreenDao, Me
 		}
 		return s.toUpperCase();
 	}
+
+	public static Map<String, Integer> parseOpPlanMap(String json) {
+		Map<String, Integer> map = new LinkedHashMap<>();
+		if (StringUtils.isBlank(json)) {
+			return map;
+		}
+		try {
+			JSONObject obj = JSON.parseObject(json);
+			if (obj == null) {
+				return map;
+			}
+			for (String key : obj.keySet()) {
+				if (StringUtils.isBlank(key)) {
+					continue;
+				}
+				String code = key.trim().toUpperCase();
+				int val = 0;
+				try {
+					val = obj.getIntValue(key);
+				} catch (Exception ignore) {
+					val = 0;
+				}
+				map.put(code, val);
+			}
+		} catch (Exception ignore) {
+			return map;
+		}
+		return map;
+	}
 }

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

@@ -131,6 +131,7 @@ public class MesProductScreenController extends BaseController {
 		data.put("peopleNums", parseIntSafe(latest == null ? null : latest.getPeopleNum()));
 		data.put("deviceNums", parseIntSafe(latest == null ? null : latest.getMachineNum()));
 		data.put("planNums", parseIntSafe(latest == null ? null : latest.getPlanOutput()));
+		data.put("opPlans", MesProductScreenService.parseOpPlanMap(latest == null ? null : latest.getOpPlan()));
 		resp.setData(data);
 		resp.setResult(Global.TRUE);
 		return resp;

+ 109 - 0
src/main/resources/views/modules/mes/mesProductScreenForm.html

@@ -56,6 +56,76 @@
 						</div>
 					</div>
 				</div>
+				<#form:hidden path="opPlan"/>
+				<div class="form-unit hide" id="opPlanTitle">${text('工位当天计划')}</div>
+				<div id="opPlanMp" class="hide">
+					<div class="row">
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP060')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP060" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP080')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP080" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP090')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP090" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP100')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP100" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div id="opPlanJj" class="hide">
+					<div class="row">
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP110')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP110" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP120')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP120" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP130')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP130" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP140')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP140" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP150')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP150" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+						<div class="col-xs-4">
+							<div class="form-group">
+								<label class="control-label col-sm-5">${text('OP160')}:</label>
+								<div class="col-sm-7"><input type="text" id="plan_OP160" class="form-control digits" maxlength="8"/></div>
+							</div>
+						</div>
+					</div>
+				</div>
 			</div>
 			<div class="box-footer">
 				<div class="row">
@@ -72,8 +142,44 @@
 </div>
 <% } %>
 <script>
+var OPS_MP = ['OP060','OP080','OP090','OP100'];
+var OPS_JJ = ['OP110','OP120','OP130','OP140','OP150','OP160'];
+function collectOpPlan() {
+	var st = $("#screenType").val();
+	var keys = st === 'MP' ? OPS_MP : (st === 'JJ' ? OPS_JJ : []);
+	var obj = {};
+	for (var i = 0; i < keys.length; i++) {
+		obj[keys[i]] = parseInt($("#plan_" + keys[i]).val(), 10) || 0;
+	}
+	$("#opPlan").val(keys.length ? JSON.stringify(obj) : '');
+}
+function toggleOpPlanFields() {
+	var st = $("#screenType").val();
+	if (st === 'MP') {
+		$("#opPlanTitle, #opPlanMp").removeClass('hide');
+		$("#opPlanJj").addClass('hide');
+	} else if (st === 'JJ') {
+		$("#opPlanTitle, #opPlanJj").removeClass('hide');
+		$("#opPlanMp").addClass('hide');
+	} else {
+		$("#opPlanTitle, #opPlanMp, #opPlanJj").addClass('hide');
+	}
+}
+function fillOpPlanInputs() {
+	var raw = $("#opPlan").val();
+	var obj = {};
+	try { obj = raw ? JSON.parse(raw) : {}; } catch (e) { obj = {}; }
+	var keys = OPS_MP.concat(OPS_JJ);
+	for (var i = 0; i < keys.length; i++) {
+		var k = keys[i];
+		var v = obj[k];
+		if (v == null) v = obj[k.replace('OP0','OP')];
+		$("#plan_" + k).val(v == null || v === '' ? '' : v);
+	}
+}
 $("#inputForm").validate({
 	submitHandler: function(form){
+		collectOpPlan();
 		js.ajaxSubmitForm($(form), function(data){
 			js.showMessage(data.message);
 			if(data.result == Global.TRUE){
@@ -89,5 +195,8 @@ $("#inputForm").validate({
 	var eq = st.indexOf('=');
 	if (eq > 0) st = st.substring(0, eq);
 	$("#screenType").val(st);
+	fillOpPlanInputs();
+	toggleOpPlanFields();
+	$("#screenType").on('change', toggleOpPlanFields);
 })();
 </script>

+ 37 - 12
src/main/resources/views/modules/mes/mesScreen4.html

@@ -329,7 +329,7 @@
 				<tr>
 					<th style="width:160px">工位</th>
 					<th style="width:300px">工位名称</th>
-					<th id="thDayCapacity">当天产量</th>
+					<th id="thDayPlan">当天计划</th>
 					<th id="thShiftCapacity">当班产量</th>
 					<th id="thPrevShiftCapacity">上班产量</th>
 				</tr>
@@ -419,20 +419,23 @@
 		var today = formatMd(now);
 		var yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
 		var ymd = formatMd(yesterday);
-		var dayEl = document.getElementById('thDayCapacity');
+		var dayEl = document.getElementById('thDayPlan');
 		var shiftEl = document.getElementById('thShiftCapacity');
 		var prevEl = document.getElementById('thPrevShiftCapacity');
-		if (dayEl) dayEl.textContent = today + '产量';
+		var curShift, prevShift;
 		if (hour >= 8 && hour < 20) {
-			if (shiftEl) shiftEl.textContent = today + '白班';
-			if (prevEl) prevEl.textContent = ymd + '夜班';
+			curShift = today + '白班';
+			prevShift = ymd + '夜班';
 		} else if (hour >= 20) {
-			if (shiftEl) shiftEl.textContent = today + '夜班';
-			if (prevEl) prevEl.textContent = today + '白班';
+			curShift = today + '夜班';
+			prevShift = today + '白班';
 		} else {
-			if (shiftEl) shiftEl.textContent = ymd + '夜班';
-			if (prevEl) prevEl.textContent = ymd + '白班';
+			curShift = ymd + '夜班';
+			prevShift = ymd + '白班';
 		}
+		if (dayEl) dayEl.textContent = curShift + '计划';
+		if (shiftEl) shiftEl.textContent = curShift + '实际';
+		if (prevEl) prevEl.textContent = prevShift + '产量';
 	}
 
 	function updateClock() {
@@ -940,7 +943,7 @@
 			html += '<tr>';
 			html += '<td class="op-col">' + r.code + '</td>';
 			html += '<td class="op-name">' + r.name + '</td>';
-			html += '<td class="op-val">' + r.real + '</td>';
+			html += '<td class="op-val">' + (r.plan || 0) + '</td>';
 			html += '<td class="op-val">' + r.shift + '</td>';
 			html += '<td class="op-val">' + (r.prevShift || 0) + '</td>';
 			html += '</tr>';
@@ -959,6 +962,26 @@
 		return n >= fromNum && n <= toNum;
 	}
 
+	function lookupOpPlan(code) {
+		var plans = mockData.opPlans || {};
+		var c = String(code || '').toUpperCase();
+		if (plans[c] != null && plans[c] !== '') return Number(plans[c]) || 0;
+		var n = parseOprnoNum(c);
+		if (n < 0) return 0;
+		var k3 = 'OP' + ('000' + n).slice(-3);
+		if (plans[k3] != null && plans[k3] !== '') return Number(plans[k3]) || 0;
+		var k2 = 'OP' + n;
+		if (plans[k2] != null && plans[k2] !== '') return Number(plans[k2]) || 0;
+		return 0;
+	}
+	function applyOpPlansToTable() {
+		var list = mockData.opTable || [];
+		for (var i = 0; i < list.length; i++) {
+			list[i].plan = lookupOpPlan(list[i].code);
+		}
+		renderTable();
+	}
+
 	function applyLatestPlanNumsToTable(planNums) {}
 	function calcRatePercent(actual, plan) {
 		actual = Number(actual) || 0;
@@ -987,10 +1010,11 @@
 					if (ls !== LINE_SN) continue;
 					var code = p.oprno || '';
 					if (!isOprnoInRange(code, 60, 100)) continue;
+					if (parseOprnoNum(code) === 70) continue;
 					out.push({
 						code: code,
 						name: p.title || '',
-						real: 0,
+						plan: lookupOpPlan(code),
 						shift: 0,
 						prevShift: 0,
 						_opNum: parseOprnoNum(code)
@@ -1015,7 +1039,6 @@
 			if (list[i] && list[i].code) oprnos.push(list[i].code);
 		}
 		if (!oprnos.length) return;
-		fetchCapacityInto('dayCapacityData', LINE_SN, oprnos, 'real', {});
 		fetchCapacityInto('shiftCapacityData', LINE_SN, oprnos, 'shift', { fixedTwoShift: 'true' });
 		fetchCapacityInto('prevShiftCapacityData', LINE_SN, oprnos, 'prevShift', { fixedTwoShift: 'true' });
 	}
@@ -1152,6 +1175,8 @@
 				if (elPeople) elPeople.textContent = mockData.cards.productionPeople;
 				if (elDevice) elDevice.textContent = mockData.cards.deviceCount;
 				if (elPlan) elPlan.textContent = mockData.cards.planProduction;
+				mockData.opPlans = d.opPlans || {};
+				applyOpPlansToTable();
 			}
 		});
 	}

+ 36 - 12
src/main/resources/views/modules/mes/mesScreen5.html

@@ -347,7 +347,7 @@
 				<tr>
 					<th style="width:160px">工位</th>
 					<th style="width:300px">工位名称</th>
-					<th id="thDayCapacity">当天产量</th>
+					<th id="thDayPlan">当天计划</th>
 					<th id="thShiftCapacity">当班产量</th>
 					<th id="thPrevShiftCapacity">上班产量</th>
 				</tr>
@@ -437,20 +437,23 @@
 		var today = formatMd(now);
 		var yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
 		var ymd = formatMd(yesterday);
-		var dayEl = document.getElementById('thDayCapacity');
+		var dayEl = document.getElementById('thDayPlan');
 		var shiftEl = document.getElementById('thShiftCapacity');
 		var prevEl = document.getElementById('thPrevShiftCapacity');
-		if (dayEl) dayEl.textContent = today + '产量';
+		var curShift, prevShift;
 		if (hour >= 8 && hour < 20) {
-			if (shiftEl) shiftEl.textContent = today + '白班';
-			if (prevEl) prevEl.textContent = ymd + '夜班';
+			curShift = today + '白班';
+			prevShift = ymd + '夜班';
 		} else if (hour >= 20) {
-			if (shiftEl) shiftEl.textContent = today + '夜班';
-			if (prevEl) prevEl.textContent = today + '白班';
+			curShift = today + '夜班';
+			prevShift = today + '白班';
 		} else {
-			if (shiftEl) shiftEl.textContent = ymd + '夜班';
-			if (prevEl) prevEl.textContent = ymd + '白班';
+			curShift = ymd + '夜班';
+			prevShift = ymd + '白班';
 		}
+		if (dayEl) dayEl.textContent = curShift + '计划';
+		if (shiftEl) shiftEl.textContent = curShift + '实际';
+		if (prevEl) prevEl.textContent = prevShift + '产量';
 	}
 
 	/** 工位表:每页条数与自动翻页间隔(毫秒) */
@@ -1012,7 +1015,7 @@
 			html += '<tr' + ((i % 2 === 1) ? ' class="op-row-alt"' : '') + '>';
 			html += '<td class="op-col">' + r.code + '</td>';
 			html += '<td class="op-name">' + r.name + '</td>';
-			html += '<td class="op-val">' + r.real + '</td>';
+			html += '<td class="op-val">' + (r.plan || 0) + '</td>';
 			html += '<td class="op-val">' + r.shift + '</td>';
 			html += '<td class="op-val">' + (r.prevShift || 0) + '</td>';
 			html += '</tr>';
@@ -1032,6 +1035,26 @@
 		}
 	}
 
+	function lookupOpPlan(code) {
+		var plans = mockData.opPlans || {};
+		var c = String(code || '').toUpperCase();
+		if (plans[c] != null && plans[c] !== '') return Number(plans[c]) || 0;
+		var n = parseOprnoNum(c);
+		if (n < 0) return 0;
+		var k3 = 'OP' + ('000' + n).slice(-3);
+		if (plans[k3] != null && plans[k3] !== '') return Number(plans[k3]) || 0;
+		var k2 = 'OP' + n;
+		if (plans[k2] != null && plans[k2] !== '') return Number(plans[k2]) || 0;
+		return 0;
+	}
+	function applyOpPlansToTable() {
+		var list = mockData.opTable || [];
+		for (var i = 0; i < list.length; i++) {
+			list[i].plan = lookupOpPlan(list[i].code);
+		}
+		renderTable();
+	}
+
 	function applyLatestPlanNumsToTable(planNums) {}
 	function syncAchieveRateWithPlan() {}
 
@@ -1067,7 +1090,7 @@
 					out.push({
 						code: code,
 						name: p.title || '',
-						real: 0,
+						plan: lookupOpPlan(code),
 						shift: 0,
 						prevShift: 0,
 						_opNum: parseOprnoNum(code)
@@ -1094,7 +1117,6 @@
 			if (list[i] && list[i].code) oprnos.push(list[i].code);
 		}
 		if (!oprnos.length) return;
-		fetchCapacityInto('dayCapacityData', LINE_SN, oprnos, 'real', {});
 		fetchCapacityInto('shiftCapacityData', LINE_SN, oprnos, 'shift', { fixedTwoShift: 'true' });
 		fetchCapacityInto('prevShiftCapacityData', LINE_SN, oprnos, 'prevShift', { fixedTwoShift: 'true' });
 	}
@@ -1233,6 +1255,8 @@
 				if (elPeople) elPeople.textContent = mockData.cards.productionPeople;
 				if (elDevice) elDevice.textContent = mockData.cards.deviceCount;
 				if (elPlan) elPlan.textContent = mockData.cards.planProduction;
+				mockData.opPlans = d.opPlans || {};
+				applyOpPlansToTable();
 			}
 		});
 	}