Jelajahi Sumber

计件模块优化

wangxichen 1 Minggu lalu
induk
melakukan
ecebfbc60d

+ 36 - 0
db/ddl-piecework-date.sql

@@ -0,0 +1,36 @@
+-- ============================================
+-- 610 计件统计修复 - DDL
+-- 目标库:mes_cloud_610
+-- 说明:Online DDL 加字段不锁表,UPDATE 回填建议低峰执行
+-- ============================================
+
+USE mes_cloud_610;
+
+-- 步骤1:新增 piecework_date 字段(Online DDL,不锁表)
+ALTER TABLE mes_product_record
+ADD COLUMN piecework_date DATETIME NULL
+COMMENT '计件时间(首次加工完成时间)'
+AFTER update_date;
+
+-- 步骤2:历史数据回填(只处理 2026-05-01 至今)
+-- 用 update_date 作为近似首次完成时间;早于 2026-05-01 的旧数据不回填
+UPDATE mes_product_record
+SET piecework_date = update_date
+WHERE craft = '100000'
+  AND content NOT IN ('UDF', '')
+  AND piecework_date IS NULL
+  AND update_date >= '2026-05-01';
+
+-- 步骤3:验证
+SELECT
+    COUNT(*) AS total_100000,
+    SUM(CASE WHEN piecework_date IS NOT NULL THEN 1 ELSE 0 END) AS has_piecework_date,
+    SUM(CASE WHEN content = 'UDF' THEN 1 ELSE 0 END) AS udf_count,
+    SUM(CASE WHEN content = 'OK'  THEN 1 ELSE 0 END) AS ok_count,
+    SUM(CASE WHEN content = 'NG'  THEN 1 ELSE 0 END) AS ng_count
+FROM mes_product_record
+WHERE craft = '100000';
+
+-- 预期:
+-- has_piecework_date = ok_count + ng_count
+-- UDF 记录 piecework_date 应为 NULL

+ 11 - 0
src/main/java/com/jeesite/modules/mes/entity/MesProductRecord.java

@@ -43,6 +43,7 @@ import java.util.List;
 		@Column(name="create_date", attrName="createDate", label="create_date", isUpdate=false,  isUpdateForce=true),
 		@Column(name="update_by", attrName="updateBy", label="update_by", isQuery=false),
 		@Column(name="update_date", attrName="updateDate", label="update_date", isUpdateForce=true),
+		@Column(name="piecework_date", attrName="pieceworkDate", label="piecework_date"),
 	},
 //		joinTable={
 //		@JoinTable(type= JoinTable.Type.JOIN, entity=MesTemplateItems.class, attrName="this", alias="b",
@@ -77,6 +78,7 @@ public class MesProductRecord extends DataEntity<MesProductRecord> {
 	private String tid;
 	private Long cdate;
 	private Date updateDate;
+	private Date pieceworkDate;
 	private String lineSn;
 	private String zcontent;
 	private String ngType;
@@ -270,6 +272,15 @@ public class MesProductRecord extends DataEntity<MesProductRecord> {
 		this.updateDate = updateDate;
 	}
 
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getPieceworkDate() {
+		return pieceworkDate;
+	}
+
+	public void setPieceworkDate(Date pieceworkDate) {
+		this.pieceworkDate = pieceworkDate;
+	}
+
 	public String getLineSn() {
 		return lineSn;
 	}

+ 2 - 0
src/main/java/com/jeesite/modules/mes/service/MesProductGp12Service.java

@@ -307,6 +307,7 @@ public class MesProductGp12Service extends CrudService<MesProductGp12Dao, MesPro
 			record.setContent("OK");
 			record.setSource("0");
 			record.setUpdateBy(userCode);
+			mesProductRecordService.setPieceworkDateIfNeeded(record);
 			mesProductRecordService.save(record);
 		} else {
 			// 不存在则新建
@@ -324,6 +325,7 @@ public class MesProductGp12Service extends CrudService<MesProductGp12Dao, MesPro
 			r.setSource("0");
 			r.setCreateBy(userCode);
 			r.setUpdateBy(userCode);
+			mesProductRecordService.setPieceworkDateIfNeeded(r);
 			mesProductRecordService.save(r);
 		}
 	}

+ 19 - 6
src/main/java/com/jeesite/modules/mes/service/MesProductRecordService.java

@@ -124,6 +124,18 @@ public class MesProductRecordService extends CrudService<MesProductRecordDao, Me
 	@Autowired
 	private MesProductDhbService mesProductDhbService;
 
+	/**
+	 * 首次完工判定:只处理 craft=100000 主结果,且 pieceworkDate 无值、content 是 OK/NG 时设置
+	 * public 供跨 Service 调用(如 MesProductGp12Service)
+	 */
+	public void setPieceworkDateIfNeeded(MesProductRecord r) {
+		if (!"100000".equals(r.getCraft())) return;
+		if (r.getPieceworkDate() != null) return;
+		String c = r.getContent();
+		if (StringUtils.isEmpty(c) || "UDF".equals(c)) return;
+		r.setPieceworkDate(new Date());
+	}
+
 	@Override
 	public void save(MesProductRecord mesProductRecord) {
 		if (StringUtils.isEmpty(mesProductRecord.getSource())) {
@@ -712,6 +724,7 @@ public class MesProductRecordService extends CrudService<MesProductRecordDao, Me
 
 				mesProductRecord.setMaterielSn(materielSn);
 				mesProductRecord.setContent(content);
+				setPieceworkDateIfNeeded(mesProductRecord);
 				super.update(mesProductRecord);
 
 				FileUploadUtils.saveFileUpload(mesProductRecord, mesProductRecord.getId(), "mesProductRecord_image");
@@ -1171,8 +1184,8 @@ public class MesProductRecordService extends CrudService<MesProductRecordDao, Me
 				.and("a.oprno",QueryType.RIGHT_LIKE,oprno)
 				.and("craft",QueryType.EQ,"100000")
 				.and("content",QueryType.NE,"UDF")
-				.and("update_date", QueryType.GTE,sdate)
-				.and("update_date",QueryType.LT,edate);
+				.and("piecework_date", QueryType.GTE,sdate)
+				.and("piecework_date",QueryType.LT,edate);
 		Long jpp1 = super.findCount(mesProductRecord);
 		return String.valueOf(jpp1);
 	}
@@ -1184,8 +1197,8 @@ public class MesProductRecordService extends CrudService<MesProductRecordDao, Me
 		mesProductRecord.getSqlMap().getWhere()
 				.and("a.oprno",QueryType.RIGHT_LIKE,oprno)
 				.and("craft",QueryType.EQ,"100000")
-				.and("update_date", QueryType.GTE,sdate)
-				.and("update_date",QueryType.LT,edate);
+				.and("piecework_date", QueryType.GTE,sdate)
+				.and("piecework_date",QueryType.LT,edate);
 		Long jpp1 = super.findCount(mesProductRecord);
 		return String.valueOf(jpp1);
 	}
@@ -1198,8 +1211,8 @@ public class MesProductRecordService extends CrudService<MesProductRecordDao, Me
 				.and("a.sn",QueryType.RIGHT_LIKE,type)
 				.and("a.oprno",QueryType.RIGHT_LIKE,oprno)
 				.and("craft",QueryType.EQ,"100000")
-				.and("update_date", QueryType.GTE,sdate)
-				.and("update_date",QueryType.LT,edate);
+				.and("piecework_date", QueryType.GTE,sdate)
+				.and("piecework_date",QueryType.LT,edate);
 		Long jpp1 = super.findCount(mesProductRecord);
 		return String.valueOf(jpp1);
 	}

+ 11 - 11
src/main/resources/mappings/modules/mes/MesProductRecordDao.xml

@@ -51,15 +51,15 @@
     </update>
 
     <!--
-        计件统计:按工位+产品前缀+班次+结果分组
+        计件统计:按工位+产品前缀+班次+结果分组,按 piecework_date 首次完成时间
         - 固定 line_sn=XT、craft=100000、content IN (OK,NG)
-        - 班次按 TIME(update_date) 判断:08:30~20:30 为白班,其余为夜班
+        - 班次按 TIME(piecework_date) 判断:08:30~20:30 为白班,其余为夜班
     -->
     <select id="pieceworkStat" resultType="java.util.HashMap">
         SELECT
             r.oprno,
             LEFT(r.sn, 5) AS productPrefix,
-            CASE WHEN TIME(r.update_date) &gt;= '08:30:00' AND TIME(r.update_date) &lt; '20:30:00'
+            CASE WHEN TIME(r.piecework_date) &gt;= '08:30:00' AND TIME(r.piecework_date) &lt; '20:30:00'
                  THEN 'day' ELSE 'night' END AS shift,
             r.content    AS result,
             COUNT(*)     AS cnt
@@ -67,8 +67,8 @@
         WHERE r.line_sn = 'XT'
           AND r.craft   = '100000'
           AND r.content IN ('OK','NG')
-          AND r.update_date &gt;= #{params.dateStart}
-          AND r.update_date &lt;  #{params.dateEnd}
+          AND r.piecework_date &gt;= #{params.dateStart}
+          AND r.piecework_date &lt;  #{params.dateEnd}
           <if test="params.prefixes != null and params.prefixes.size() > 0">
           AND LEFT(r.sn, 5) IN
               <foreach collection="params.prefixes" item="p" open="(" separator="," close=")">
@@ -76,7 +76,7 @@
               </foreach>
           </if>
         GROUP BY r.oprno, LEFT(r.sn, 5),
-            CASE WHEN TIME(r.update_date) &gt;= '08:30:00' AND TIME(r.update_date) &lt; '20:30:00'
+            CASE WHEN TIME(r.piecework_date) &gt;= '08:30:00' AND TIME(r.piecework_date) &lt; '20:30:00'
                  THEN 'day' ELSE 'night' END,
             r.content
         ORDER BY r.oprno ASC, LEFT(r.sn, 5) ASC
@@ -85,22 +85,22 @@
     <!-- 按小时统计今日产量,用于趋势图 -->
     <select id="pieceworkHourlyStat" resultType="java.util.HashMap">
         SELECT
-            HOUR(r.update_date) AS hour,
+            HOUR(r.piecework_date) AS hour,
             LEFT(r.sn, 5)       AS productPrefix,
             COUNT(*)            AS cnt
         FROM mes_product_record r
         WHERE r.line_sn = 'XT'
           AND r.craft   = '100000'
           AND r.content = 'OK'
-          AND r.update_date &gt;= #{params.dateStart}
-          AND r.update_date &lt;  #{params.dateEnd}
+          AND r.piecework_date &gt;= #{params.dateStart}
+          AND r.piecework_date &lt;  #{params.dateEnd}
           <if test="params.prefixes != null and params.prefixes.size() > 0">
           AND LEFT(r.sn, 5) IN
               <foreach collection="params.prefixes" item="p" open="(" separator="," close=")">
                   #{p}
               </foreach>
           </if>
-        GROUP BY HOUR(r.update_date), LEFT(r.sn, 5)
-        ORDER BY HOUR(r.update_date) ASC
+        GROUP BY HOUR(r.piecework_date), LEFT(r.sn, 5)
+        ORDER BY HOUR(r.piecework_date) ASC
     </select>
 </mapper>