This commit is contained in:
Rue Ji
2026-03-10 21:57:18 +08:00
5 changed files with 553 additions and 33 deletions

View File

@ -2,7 +2,11 @@ package com.sipai.controller.mpoint;
import com.sipai.entity.scada.MPointData;
import com.sipai.service.scada.MPointDataService;
import com.sipai.tools.CommString;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@ -16,6 +20,7 @@ import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
@ -26,21 +31,53 @@ import java.util.Map;
@Controller
@RequestMapping("/mpoint/data")
public class MPointDataController {
@Resource
private RedissonClient redissonClient;
@Resource
private MPointDataService mPointDataService;
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@RequestMapping("/getCurrentValue.do")
public ModelAndView getStatistics(HttpServletRequest request, Model model,
@RequestParam(value = "mPointKey") String mPointKey) {
JSONObject result = new JSONObject();
// 参数校验
if (mPointKey == null || mPointKey.trim().isEmpty()) {
result.put("success", false);
result.put("message", "mPointKey参数不能为空");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
// 获取最新数据(当前值)
int num = mPointKey.hashCode() % 25;
RMapCache<String, String> map_redis_data = redissonClient.getMapCache(CommString.RedisMpointFlag + num);
if (map_redis_data.get(mPointKey) != null && !"".equals(map_redis_data.get(mPointKey))) {
String[] str = map_redis_data.get(mPointKey).split(";");
if (str.length >= 3 && str[1] != null && !str[1].isEmpty() && !"null".equals(str[1])) {
result.put("currentValue", formatAmount(new BigDecimal(str[1])));
result.put("currentMeasureTime", str[2]);
} else {
result.put("currentValue", BigDecimal.ZERO);
result.put("currentMeasureTime", null);
}
}
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
/**
* 获取测点统计数据
*
* @param mPointKey 测点编码DO1必填
* @param companyKey 公司编码可选用于筛选userid字段
*
* @param mPointKey 测点编码DO1必填
* @param companyKey 公司编码可选用于筛选userid字段
* @param startTimeStr 开始时间可选格式yyyy-MM-dd HH:mm:ss
* @param endTimeStr 结束时间可选格式yyyy-MM-dd HH:mm:ss
* @param endTimeStr 结束时间可选格式yyyy-MM-dd HH:mm:ss
* @return 统计数据JSON
*
* <p>
* 返回内容:
* - currentValue: 当前值(最新一条数据)
* - currentMeasureTime: 当前值的测量时间
@ -48,18 +85,18 @@ public class MPointDataController {
* - maxValue: 最高值
* - minValue: 最低值
* - totalCount: 数据总条数
*
* <p>
* 示例请求:/mpoint/data/getStatistics.do?mPointKey=DO1&companyKey=DEV022&startTime=2026-03-01 00:00:00&endTime=2026-03-08 23:59:59
*/
@RequestMapping("/getStatistics.do")
public ModelAndView getStatistics(HttpServletRequest request, Model model,
@RequestParam(value = "mPointKey") String mPointKey,
@RequestParam(value = "companyKey", required = false) String companyKey,
@RequestParam(value = "startTime", required = false) String startTimeStr,
@RequestParam(value = "endTime", required = false) String endTimeStr) {
@RequestParam(value = "mPointKey") String mPointKey,
@RequestParam(value = "companyKey", required = false) String companyKey,
@RequestParam(value = "startTime", required = false) String startTimeStr,
@RequestParam(value = "endTime", required = false) String endTimeStr) {
JSONObject result = new JSONObject();
try {
// 参数校验
if (mPointKey == null || mPointKey.trim().isEmpty()) {
@ -68,16 +105,16 @@ public class MPointDataController {
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
mPointKey = mPointKey.trim();
if (companyKey != null) {
companyKey = companyKey.trim();
}
// 解析时间参数
Date startTime = null;
Date endTime = null;
if (startTimeStr != null && !startTimeStr.trim().isEmpty()) {
try {
startTime = DATE_FORMAT.parse(startTimeStr.trim());
@ -88,7 +125,7 @@ public class MPointDataController {
return new ModelAndView("result");
}
}
if (endTimeStr != null && !endTimeStr.trim().isEmpty()) {
try {
endTime = DATE_FORMAT.parse(endTimeStr.trim());
@ -99,7 +136,7 @@ public class MPointDataController {
return new ModelAndView("result");
}
}
// 检查时间范围有效性
if (startTime != null && endTime != null && startTime.after(endTime)) {
result.put("success", false);
@ -107,7 +144,7 @@ public class MPointDataController {
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
// 检查表是否存在
if (!mPointDataService.checkTableExists(mPointKey)) {
result.put("success", false);
@ -116,7 +153,7 @@ public class MPointDataController {
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
// 获取最新数据(当前值)
MPointData latestData = mPointDataService.getLatestData(mPointKey, companyKey, startTime, endTime);
if (latestData != null) {
@ -126,16 +163,16 @@ public class MPointDataController {
result.put("currentValue", null);
result.put("currentMeasureTime", null);
}
// 获取统计数据
Map<String, Object> stats = mPointDataService.getStatistics(mPointKey, companyKey, startTime, endTime);
if (stats != null) {
Object avgObj = stats.get("avgValue");
Object maxObj = stats.get("maxValue");
Object minObj = stats.get("minValue");
Object countObj = stats.get("totalCount");
if (avgObj instanceof BigDecimal) {
result.put("avgValue", formatAmount((BigDecimal) avgObj));
} else if (avgObj instanceof Number) {
@ -143,7 +180,7 @@ public class MPointDataController {
} else {
result.put("avgValue", "0.00");
}
if (maxObj instanceof BigDecimal) {
result.put("maxValue", formatAmount((BigDecimal) maxObj));
} else if (maxObj instanceof Number) {
@ -151,7 +188,7 @@ public class MPointDataController {
} else {
result.put("maxValue", "0.00");
}
if (minObj instanceof BigDecimal) {
result.put("minValue", formatAmount((BigDecimal) minObj));
} else if (minObj instanceof Number) {
@ -159,7 +196,7 @@ public class MPointDataController {
} else {
result.put("minValue", "0.00");
}
if (countObj instanceof Number) {
result.put("totalCount", ((Number) countObj).intValue());
} else {
@ -171,7 +208,7 @@ public class MPointDataController {
result.put("minValue", "0.00");
result.put("totalCount", 0);
}
result.put("success", true);
result.put("mPointKey", mPointKey);
result.put("tableName", mPointDataService.buildTableName(mPointKey));
@ -184,16 +221,155 @@ public class MPointDataController {
if (endTime != null) {
result.put("endTime", formatDate(endTime));
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "获取统计数据失败:" + e.getMessage());
}
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
/**
* 获取测点每日汇总数据
*
* @param mPointKey 测点编码DO1必填
* @param startTimeStr 开始时间格式yyyy-MM-dd HH:mm:ss
* @param endTimeStr 结束时间格式yyyy-MM-dd HH:mm:ss
* @return 每日汇总数据JSON
* <p>
* 返回内容:
* - dailyData: 每日汇总数组
* - dateStr: 日期yyyy-MM-dd
* - totalValue: 当日ParamValue汇总值
* - dataCount: 当日数据条数
* - grandTotal: 总汇总值
* - totalDays: 总天数
* <p>
* 示例请求:/mpoint/data/getDailyAggregation.do?mPointKey=DO1&startTime=2026-03-01 00:00:00&endTime=2026-03-08 23:59:59
*/
@RequestMapping("/getDailyAggregation.do")
public ModelAndView getDailyAggregation(HttpServletRequest request, Model model,
@RequestParam(value = "mPointKey") String mPointKey,
@RequestParam(value = "startTime") String startTimeStr,
@RequestParam(value = "endTime") String endTimeStr) {
JSONObject result = new JSONObject();
try {
// 参数校验
if (mPointKey == null || mPointKey.trim().isEmpty()) {
result.put("success", false);
result.put("message", "mPointKey参数不能为空");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
if (startTimeStr == null || startTimeStr.trim().isEmpty()) {
result.put("success", false);
result.put("message", "startTime参数不能为空");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
if (endTimeStr == null || endTimeStr.trim().isEmpty()) {
result.put("success", false);
result.put("message", "endTime参数不能为空");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
mPointKey = mPointKey.trim();
// 解析时间参数
Date startTime;
Date endTime;
try {
startTime = DATE_FORMAT.parse(startTimeStr.trim());
} catch (ParseException e) {
result.put("success", false);
result.put("message", "startTime格式错误正确格式yyyy-MM-dd HH:mm:ss");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
try {
endTime = DATE_FORMAT.parse(endTimeStr.trim());
} catch (ParseException e) {
result.put("success", false);
result.put("message", "endTime格式错误正确格式yyyy-MM-dd HH:mm:ss");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
// 检查时间范围有效性
if (startTime.after(endTime)) {
result.put("success", false);
result.put("message", "开始时间不能晚于结束时间");
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
// 检查表是否存在
if (!mPointDataService.checkTableExists(mPointKey)) {
result.put("success", false);
result.put("message", "未找到测点[" + mPointKey + "]对应的数据表");
result.put("tableName", mPointDataService.buildTableName(mPointKey));
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
// 获取每日汇总数据
List<Map<String, Object>> dailyList = mPointDataService.getDailyAggregation(mPointKey, startTime, endTime);
JSONArray dailyData = new JSONArray();
BigDecimal grandTotal = BigDecimal.ZERO;
int totalDays = 0;
if (dailyList != null && !dailyList.isEmpty()) {
for (Map<String, Object> dayItem : dailyList) {
JSONObject dayObj = new JSONObject();
dayObj.put("dateStr", dayItem.get("dateStr"));
dayObj.put("dataCount", dayItem.get("dataCount"));
Object totalValueObj = dayItem.get("totalValue");
BigDecimal dayTotal;
if (totalValueObj instanceof BigDecimal) {
dayTotal = (BigDecimal) totalValueObj;
} else if (totalValueObj instanceof Number) {
dayTotal = new BigDecimal(totalValueObj.toString());
} else {
dayTotal = BigDecimal.ZERO;
}
dayObj.put("totalValue", formatAmount(dayTotal));
dailyData.add(dayObj);
grandTotal = grandTotal.add(dayTotal);
totalDays++;
}
}
result.put("success", true);
result.put("mPointKey", mPointKey);
result.put("tableName", mPointDataService.buildTableName(mPointKey));
result.put("startTime", formatDate(startTime));
result.put("endTime", formatDate(endTime));
result.put("dailyData", dailyData);
result.put("grandTotal", formatAmount(grandTotal));
result.put("totalDays", totalDays);
} catch (Exception e) {
result.put("success", false);
result.put("message", "获取每日汇总数据失败:" + e.getMessage());
}
model.addAttribute("result", result.toString());
return new ModelAndView("result");
}
/**
* 格式化数值保留2位小数
*/
@ -203,7 +379,7 @@ public class MPointDataController {
}
return amount.setScale(2, RoundingMode.HALF_UP).toPlainString();
}
/**
* 格式化日期
*/

View File

@ -4,6 +4,7 @@ import com.sipai.dao.base.CommDaoImpl;
import com.sipai.entity.scada.MPointData;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository
@ -61,4 +62,21 @@ public class MPointDataDao extends CommDaoImpl<MPointData> {
Integer count = this.getSqlSession().selectOne(MAPPER_NAMESPACE + ".checkTableExists", tableName);
return count != null && count > 0;
}
/**
* 按天汇总统计
* @param tableName 表名
* @param startTime 开始时间
* @param endTime 结束时间
* @return 每天汇总数据列表dateStr, totalValue, dataCount
*/
public List<Map<String, Object>> selectDailyAggregation(String tableName,
java.util.Date startTime,
java.util.Date endTime) {
Map<String, Object> params = new java.util.HashMap<>();
params.put("tableName", tableName);
params.put("startTime", startTime);
params.put("endTime", endTime);
return this.getSqlSession().selectList(MAPPER_NAMESPACE + ".selectDailyAggregation", params);
}
}

View File

@ -60,4 +60,23 @@
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #{tableName}
</select>
<!-- 按天汇总统计每天ParamValue的总量 -->
<select id="selectDailyAggregation" resultType="java.util.Map">
SELECT
CONVERT(VARCHAR(10), MeasureDT, 120) as dateStr,
ISNULL(SUM(ParmValue), 0) as totalValue,
COUNT(*) as dataCount
FROM ${tableName}
<where>
<if test="startTime != null">
AND MeasureDT >= #{startTime}
</if>
<if test="endTime != null">
AND MeasureDT &lt;= #{endTime}
</if>
</where>
GROUP BY CONVERT(VARCHAR(10), MeasureDT, 120)
ORDER BY dateStr ASC
</select>
</mapper>

View File

@ -66,6 +66,19 @@ public class MPointDataService implements CommService<MPointData> {
return mPointDataDao.selectStatistics(tableName, companyKey, startTime, endTime);
}
/**
* 获取每日汇总数据
* @param mPointKey 测点编码
* @param startTime 开始时间
* @param endTime 结束时间
* @return 每天汇总数据列表
*/
public List<Map<String, Object>> getDailyAggregation(String mPointKey,
Date startTime, Date endTime) {
String tableName = buildTableName(mPointKey);
return mPointDataDao.selectDailyAggregation(tableName, startTime, endTime);
}
@Override
public MPointData selectById(String id) {
return null;

View File

@ -0,0 +1,294 @@
GET _search
{
"query": {
"match_all": {}
}
}
# Elasticsearch Index Initialization Script for MPoint
# Index: es_measurepoint
# Type: esmeasurepoint
# Generated from: MPoint.java entity
# Step 1: Delete existing index (if exists)
DELETE /es_measurepoint
PUT /es_measurepoint
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"normalizer": {
"my_normalizer": {
"type": "custom",
"char_filter": [],
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"esmeasurepoint": {
"properties": {
"mpointcode": {
"type": "keyword",
"normalizer": "my_normalizer"
},
"parmname": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"id": {
"type": "keyword"
},
"mpointid": {
"type": "keyword"
},
"unit": {
"type": "keyword"
},
"alarmmax": {
"type": "scaled_float",
"scaling_factor": 100
},
"alarmmin": {
"type": "scaled_float",
"scaling_factor": 100
},
"halarmmax": {
"type": "scaled_float",
"scaling_factor": 100
},
"lalarmmin": {
"type": "scaled_float",
"scaling_factor": 100
},
"parmvalue": {
"type": "scaled_float",
"scaling_factor": 100
},
"parmvalueStr": {
"type": "keyword"
},
"measuredt": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss'Z'||yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"rate": {
"type": "scaled_float",
"scaling_factor": 1000
},
"freq": {
"type": "integer"
},
"frequnit": {
"type": "keyword"
},
"signaltype": {
"type": "keyword"
},
"signaltag": {
"type": "keyword"
},
"ledtype": {
"type": "keyword"
},
"ledcolor": {
"type": "keyword"
},
"directtype": {
"type": "keyword"
},
"bizid": {
"type": "keyword"
},
"biztype": {
"type": "keyword"
},
"numtail": {
"type": "keyword"
},
"prochour": {
"type": "keyword"
},
"procday": {
"type": "keyword"
},
"procmonth": {
"type": "keyword"
},
"showname": {
"type": "text",
"analyzer": "standard",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"exp": {
"type": "text"
},
"forcemin": {
"type": "scaled_float",
"scaling_factor": 100
},
"forcemax": {
"type": "scaled_float",
"scaling_factor": 100
},
"avgmax": {
"type": "scaled_float",
"scaling_factor": 100
},
"avgmin": {
"type": "scaled_float",
"scaling_factor": 100
},
"remoteup": {
"type": "keyword"
},
"morder": {
"type": "integer"
},
"triggeralarm": {
"type": "keyword"
},
"confirmalarm": {
"type": "keyword"
},
"flowset": {
"type": "scaled_float",
"scaling_factor": 100
},
"triggercycle": {
"type": "keyword"
},
"cyclemax": {
"type": "scaled_float",
"scaling_factor": 100
},
"cyclemin": {
"type": "scaled_float",
"scaling_factor": 100
},
"triggermutation": {
"type": "keyword"
},
"mutationset": {
"type": "scaled_float",
"scaling_factor": 100
},
"causeset": {
"type": "scaled_float",
"scaling_factor": 100
},
"operateset": {
"type": "scaled_float",
"scaling_factor": 100
},
"resultset": {
"type": "scaled_float",
"scaling_factor": 100
},
"triggerequoff": {
"type": "keyword"
},
"mathop": {
"type": "keyword"
},
"valuetype": {
"type": "keyword"
},
"valuemeaning": {
"type": "text"
},
"active": {
"type": "keyword"
},
"soundalarm": {
"type": "keyword"
},
"scdtype": {
"type": "keyword"
},
"spanrange": {
"type": "scaled_float",
"scaling_factor": 100
},
"modbusfigid": {
"type": "keyword"
},
"register": {
"type": "keyword"
},
"processsectioncode": {
"type": "keyword"
},
"equipmentid": {
"type": "keyword"
},
"source_type": {
"type": "keyword"
},
"patrol_type": {
"type": "keyword"
},
"remark": {
"type": "text"
},
"alarmLevel": {
"type": "integer"
},
"structureId": {
"type": "keyword"
},
"bizname": {
"type": "text",
"analyzer": "standard",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"disname": {
"type": "text",
"analyzer": "standard",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"subscriptionStatus": {
"type": "integer"
},
"text": {
"type": "text",
"analyzer": "standard"
}
}
}
}
}
POST /es_measurepoint/_close
POST /es_measurepoint/_open
# Step 3: Verify index creation
GET /es_measurepoint/_mapping
# Step 4: Check index settings
GET /es_measurepoint/_settings