This commit is contained in:
高云鹏 2024-11-07 17:44:59 +08:00
commit 805f0d1906
9 changed files with 1911 additions and 593 deletions

View File

@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@ -17,6 +18,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/**
* 计算模块API接口
@ -48,6 +50,9 @@ public class CalcController {
@PostMapping("/module/register")
public R<?> registerCalcModule(MultipartFile file) throws IOException {
try {
if (file.isEmpty()){
throw new IOException("无效的计算模块脚本文件");
}
String content = new String(file.getBytes(), StandardCharsets.UTF_8);
calcService.registerCalcModule(content);
}
@ -61,13 +66,17 @@ public class CalcController {
/**
* 移除计算模块
* @param moduleName 计算模块名称
* @param params moduleName 模块名称
* @return
* @throws IOException
*/
@PostMapping("/module/remove")
public R<?> removeCalcModule(String moduleName) throws IOException {
public R<?> removeCalcModule(@RequestBody Map<String,Object> params) throws IOException {
try {
String moduleName = (String) params.get("moduleName");
if (moduleName == null){
return R.fail("参数错误");
}
calcService.removeCalcModule(moduleName);
}
catch (Exception ex){
@ -80,13 +89,17 @@ public class CalcController {
/**
* 激活计算模块
* @param moduleName
* @param params moduleName 模块名称
* @return
* @throws IOException
*/
@PostMapping("/module/active")
public R<?> activeCalcModule(String moduleName){
public R<?> activeCalcModule(@RequestBody Map<String,Object> params){
try {
String moduleName = (String) params.get("moduleName");
if (moduleName == null){
return R.fail("参数错误");
}
calcService.activeCalcModule(moduleName);
} catch (Exception e) {
log.error("激活计算模块失败", e);
@ -97,8 +110,12 @@ public class CalcController {
@PostMapping("/module/deactive")
public R<?> deActiveCalcModule(String moduleName){
public R<?> deActiveCalcModule(@RequestBody Map<String,Object> params){
try {
String moduleName = (String) params.get("moduleName");
if (moduleName == null){
return R.fail("参数错误");
}
calcService.deActiveCalcModule(moduleName);
} catch (Exception e) {
log.error("禁用计算模块失败", e);
@ -108,4 +125,24 @@ public class CalcController {
}
/**
* 获取计算模块脚本内容
* @param params moduleName 模块名称
* @return
*/
@PostMapping("/module/script")
public R<String> getScriptContent(@RequestBody Map<String,Object> params){
try {
String moduleName = (String) params.get("moduleName");
if (moduleName == null){
return R.fail("参数错误");
}
return R.data(calcService.getScriptContent(moduleName));
} catch (Exception e) {
log.error("获取计算模块脚本内容失败", e);
return R.fail(String.format("获取计算模块脚本内容失败, %s",e.getMessage()));
}
}
}

View File

@ -1,5 +1,6 @@
package com.das.modules.calc.service;
import cn.hutool.core.codec.Base64Encoder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.das.modules.cache.service.CacheService;
import com.das.modules.calc.domain.entity.CalcModule;
@ -23,6 +24,8 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@ -213,4 +216,12 @@ public class CalcService {
stopCalcJob(moduleName);
}
}
public String getScriptContent(String moduleName) throws IOException {
CalcModule calcModule = calcModuleMapper.selectById(moduleName);
if (calcModule != null) {
return Base64Encoder.encode(calcModule.getScript(), StandardCharsets.UTF_8);
}
throw new IOException("无效的模块名");
}
}

View File

@ -33,14 +33,21 @@ public class ManualOperatorController {
@PostMapping("/command")
public R<String> deviceCommand(HttpServletRequest request, @RequestBody CommandInfoDto cmdInfo) {
cmdInfo.setMeasType(MeasType.TYPE_PSR_CONTROL);
log.info("{}", cmdInfo);
//判断是否有权限
boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_CTRL.toString());
if(!hasPermission){
return R.fail("没有设备遥控权限");
}
String deviceId = optService.executeOperation(request, cmdInfo);
String deviceId = String.valueOf(cmdInfo.getDeviceId());
try {
optService.executeOperation(request, cmdInfo);
log.info("设备[{}]遥控成功", deviceId);
}
catch (Exception ex){
log.error("设备遥控失败", ex);
return R.fail(String.format("设备遥控失败, %s",ex.getMessage()));
}
return R.success(deviceId);
}
@ -56,8 +63,14 @@ public class ManualOperatorController {
if(!hasPermission){
return R.fail("没有设备遥控权限");
}
String deviceId = optService.executeOperation(request, cmdInfo);
String deviceId = String.valueOf(cmdInfo.getDeviceId());
try{
optService.executeOperation(request, cmdInfo);
}
catch (Exception ex){
log.error("设备遥调失败", ex);
return R.fail(String.format("设备遥调失败, %s",ex.getMessage()));
}
return R.success(deviceId);
}
@ -75,7 +88,14 @@ public class ManualOperatorController {
if (cmdInfo.getDeviceId() ==null || StringUtils.isBlank(cmdInfo.getServiceCode())){
throw new ServiceException("参数缺失");
}
String deviceId = optService.executeOperation(request, cmdInfo);
String deviceId = String.valueOf(cmdInfo.getDeviceId());
try {
optService.executeOperation(request, cmdInfo);
}
catch (Exception ex){
log.error("设备手工至位失败", ex);
return R.fail(String.format("设备手工至位失败, %s",ex.getMessage()));
}
return R.success(deviceId);
}
}

View File

@ -62,7 +62,7 @@ public class OperationService {
* @param request HttpServletRequest
* @param cmdInfo 命令信息
*/
public String executeOperation(HttpServletRequest request, CommandInfoDto cmdInfo) {
public void executeOperation(HttpServletRequest request, CommandInfoDto cmdInfo) {
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
if (cmdInfo.getMeasType().equals(MeasType.TYPE_PSR_CALCULATED_VALUE)) {
//人工置位不需要下令
@ -94,7 +94,6 @@ public class OperationService {
log.error("获取客户端ip地址失败 ", e);
}
sysOperationLogMapper.insert(sysOperationLog);
return cmdInfo.getDeviceId().toString();
}
/**
@ -130,7 +129,6 @@ public class OperationService {
.build();
terminalMessageEventHandler.sendTerminalMessageWithResult(activeNodeId, configUpdate);
} catch (Exception e) {
log.error("设备控制失败 ", e);
throw new ServiceException("设备控制失败 "+ e);
}
}

View File

@ -91,8 +91,9 @@ das:
logging:
level:
root: ERROR
com:
das: DEBUG
das: ERROR
tdengine:
password: taosdata

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,8 @@
- [人工操作接口](api/operation.md)
- [页面访问接口](api/pages/)
- [告警事件接口](api/event.md)
- [首页](api/pages/home.md)
- [计算模块接口](api/calc.md)
- [首页](api/pages/home.md)
- [报表管理](api/pages/report.md)
- [数据采集](datacollect/)
- [系统部署](deploy/)

172
docs/api/calc.md Normal file
View File

@ -0,0 +1,172 @@
# 计算模块
# API接口一览表
| 接口分类 | 接口描述 | API接口 | 权限 |
|-------|-----------------|----------------------------------| ---------------------------- |
| 1.计算模块 | 1.1.1获取所有计算模块列表 | /api/calc/module/list | SYS_AUTHORITY_ID_ADMIN |
| | 1.1.2注册或者更新计算模块 | /api/calc/module/register | SYS_AUTHORITY_ID_ADMIN |
| | 1.1.3卸载计算模块 | /api/calc/module/remove | SYS_AUTHORITY_ID_ADMIN |
| | 1.1.4激活计算模块 | /api/node/module/active | |
| | 1.1.5禁用计算模块 | /api/calc/module/deactive | |
| | 1.1.5获取计算模块脚本 | /api/calc/module/script | |
## 1.1 计算模块相关接口
### 1.1.1 获取所有计算模块列表
POST 请求接口
> /api/calc/module/list
请求参数
返回报文
```json
{
"code": 200,
"success": true,
"data": [
{
"name": "WindFarmStatistics",
"localName": "风场计实时统计量",
"version": "1.0.1",
"description": "计算风场的实时统计量,包括:全场总有功功率、全场总无功功率、全场平均风速、并网机组台数、故障机组台数、待机机组台、断连机组台数。",
"disabled": 0,
"cron": "0 */5 * * ?"
}
],
"msg": "操作成功"
}
```
返参描述
| 参数名 | 参数类型 | 可选 | 描述 |
| ------------- | -------- | ---- |------|
| name | String | 否 | 计算模块名称 |
| localName | String | 否 | 计算模块中文名 |
| version | String | 否 | 版本号 |
| description | String | 否 | 计算模块备注 |
| disabled | String | 否 | 是否禁用 |
| cron | String | 否 | 计算任务定时表达式 |
### 1.1.2 注册或者关联计算模块
POST 请求接口, form-data方式
> /api/calc/module/register
入参描述
| 参数名 | 参数类型 | 可选 | 描述 |
| ------------- | -------- | ---- |------|
| file | String | 否 | 计算模块脚本文件 |
返回报文
```json
{
"code": 200,
"success": true,
"msg": "操作成功"
}
```
### 1.1.3 卸载计算模块
POST 请求接口
> /api/calc/module/remove
请求参数
```json
{
"moduleName": "WindFarmStatistics"
}
```
返回报文
```json
{
"code": 200,
"success": true,
"msg": "删除成功"
}
```
### 1.1.4 激活计算模块
POST 请求接口
> /api/node/module/active
请求参数
```json
{
"moduleName": "WindFarmStatistics"
}
```
返回报文
```json
{
"code": 200,
"success": true,
"msg": "激活成功"
}
```
### 1.1.5 禁用计算模块
POST 请求接口
> /api/node/module/deactive
请求参数
```json
{
"moduleName": "WindFarmStatistics"
}
```
返回报文
```json
{
"code": 200,
"success": true,
"msg": "禁用成功"
}
### 1.1.6 获取指定计算模块脚本内容
POST 请求接口
> /api/node/module/script
请求参数
```json
{
"moduleName": "WindFarmStatistics"
}
```
返回报文
```json
{
"code": 200,
"success": true,
"data": "IyMgTmFtZTogV2luZEZhcm1TdGF0aXN0aWNzDQojIyBMb2NhbE5hbWU6IOmjjuWcuuiuoeWunuaXtue7n+iuoemHjw0KIyMgVmVyc2lvbjoxLjAuMQ0KIyMgQ3JvbjowICovNSAqICogPw0KIyMgRGVzY3JpcHRpb246IOiuoeeul+mjjuWcuueahOWunuaXtue7n+iuoemHj++8jOWMheaLrO+8muWFqOWcuuaAu+acieWKn+WKn+eOh+OAgeWFqOWcuuaAu+aXoOWKn+WKn+eOh+OAgeWFqOWcuuW5s+Wdh+mjjumAn+OAgeW5tue9keacuue7hOWPsOaVsOOAgeaVhemanOacuue7hOWPsOaVsOOAgeW+heacuuacuue7hOWPsOOAgeaWrei/nuacuue7hOWPsOaVsOOAgg0KDQojIyDmraTohJrmnKzorqHnrpfpo47lnLrnmoTkuIDkupvnu5/orqHmlbDmja46DQojIyDohJrmnKznmoTliY3kupTooYzms6jph4rkuLrohJrmnKzlpLTljLrln5/vvIzloavlhpnohJrmnKzln7rnoYDkv6Hmga8uDQoNCiMjIOiOt+WPlumjjuWcuuS/oeaBr+WIl+ihqA0KbGV0IEdFTlMgPWZpbHRlciggR19ERVZJQ0VTLCBsYW1iZGEoZGV2KS0+IGRldi5vYmplY3RUeXBlID09IDEwMDAyIGVuZCk7DQoNCiMjIOWumuS5iemcgOimgeiOt+WPlueahOWunuaXtuaVsOaNrg0KbGV0IGF0dHJzID0gc2VxLmxpc3QoImlHZW5Qb3dlcjFzIiwiaVJlYWN0aXZlUG93ZXIiLCJpV2luZFNwZWVkMXMiLCJpVHVyYmluZU9wZXJhdGlvbk1vZGUiKTsNCg0KIyMg57uT5p6c5Y+Y6YePIC0g5YWo5Zy65oC75pyJ5Yqf5Yqf546HDQpsZXQgV2luZEZhcm1BY3RpdmVQb3dlciA9IDAuMDsNCiMjIOe7k+aenOWPmOmHjyAtIOWFqOWcuuaAu+aXoOWKn+WKn+eOhw0KbGV0IFdpbmRGYXJtUmVhY3RpdmVQb3dlciA9IDAuMDsNCiMjIOe7k+aenOWPmOmHjyAtIOWFqOWcuuW5s+Wdh+mjjumAnw0KbGV0IFdpbmRGYXJtQXZnV2luZFNwZWVkID0gbmlsOw0KIyMg57uT5p6c5Y+Y6YePIC0g5bm2572R5py657uE5Y+w5pWwDQpsZXQgVHVyYmluZUNvdW50UG93ZXJQcm9kID0gMDsNCiMjIOe7k+aenOWPmOmHjyAtIOaVhemanOacuue7hOWPsOaVsA0KVHVyYmluZUNvdW50RmF1bHRlZCA9IDA7DQojIyDnu5Pmnpzlj5jph48gLSDlvoXmnLrmnLrnu4Tlj7DmlbANClR1cmJpbmVDb3VudElkbGUgPSAwOw0KIyMg57uT5p6c5Y+Y6YePIC0g5pat6L+e5py657uE5Y+w5pWwDQpUdXJiaW5lQ291bnREaXNjb25uZWN0ZWQgPSAwOw0KDQojIyDkuLTml7blj5jph48NCg0KbGV0IHRfd2luZEZhcm1Ub3RhbCA9IDAuMDsNCmxldCB0X3dpbmRGYXJtQXZhaWxhYmxlQ291bnQgPSAwOw0KDQpmb3IgZyBpbiBHRU5TIHsNCiAgICAjIyDojrflj5bpo47mnLrlrp7ml7bmlbDmja4NCglsZXQgdiA9IHJ0KGcuZGV2aWNlQ29kZSwgYXR0cnMpOw0KDQogICAgIyMg57Sv5Yqg6K6h566XIOWFqOWcuuaAu+acieWKn+WKn+eOhw0KCWlmICh2LmlHZW5Qb3dlcjFzICE9IG5pbCkgew0KCQlXaW5kRmFybUFjdGl2ZVBvd2VyID0gV2luZEZhcm1BY3RpdmVQb3dlciArIHYuaUdlblBvd2VyMXM7DQoJfQ0KDQogICAgIyMg57Sv5Yqg6K6h566XIOWcuuaAu+aXoOWKn+WKn+eOhw0KCWlmICh2LmlSZWFjdGl2ZVBvd2VyICE9IG5pbCkgew0KCQlXaW5kRmFybVJlYWN0aXZlUG93ZXIgPSBXaW5kRmFybVJlYWN0aXZlUG93ZXIgKyB2LmlSZWFjdGl2ZVBvd2VyOw0KCX0NCg0KICAgICMjIOe0r+WKoOacieaViOeahOW5s+Wdh+mjjumAn+WPiumjjuWcuuS4quaVsA0KCWlmICh2LmlXaW5kU3BlZWQxcyAhPSBuaWwpIHsNCiAgICAgICAgdF93aW5kRmFybVRvdGFsID0gdF93aW5kRmFybVRvdGFsICsgdi5pV2luZFNwZWVkMXM7DQogICAgICAgIHRfd2luZEZhcm1BdmFpbGFibGVDb3VudCA9IHRfd2luZEZhcm1BdmFpbGFibGVDb3VudCArIDE7DQoJfQ0KDQoJIyMg6K6h566X5bm2572R5Y+w5pWw77yM5b6F5py65py657uE5Y+w5pWw77yM5pat6L+e5py657uE5Y+w5pWwDQoJaWYgKCB2LmlUdXJiaW5lT3BlcmF0aW9uTW9kZSA9PSAyMCB8fCB2LmlUdXJiaW5lT3BlcmF0aW9uTW9kZSA9PSAyMSApIHsNCgkJVHVyYmluZUNvdW50UG93ZXJQcm9kID0gVHVyYmluZUNvdW50UG93ZXJQcm9kICsgMTsNCgl9DQoJZWxzaWYgKCB2LmlUdXJiaW5lT3BlcmF0aW9uTW9kZSA9PSAxMSApIHsNCgkJVHVyYmluZUNvdW50SWRsZSA9IFR1cmJpbmVDb3VudElkbGUgKyAxOw0KCX0NCgllbHNpZiAoIHYuaVR1cmJpbmVPcGVyYXRpb25Nb2RlID09IDAgKSB7DQoJCVR1cmJpbmVDb3VudERpc2Nvbm5lY3RlZCA9IFR1cmJpbmVDb3VudERpc2Nvbm5lY3RlZCArIDE7DQoJfQ0KfQ0KDQojIyDorqHnrpcg5YWo5Zy65bmz5Z2H6aOO6YCfDQppZiAoIHRfd2luZEZhcm1BdmFpbGFibGVDb3VudCAhPSAwICl7DQogICAgV2luZEZhcm1BdmdXaW5kU3BlZWQgPSB0X3dpbmRGYXJtVG90YWwgLyB0X3dpbmRGYXJtQXZhaWxhYmxlQ291bnQ7DQp9DQojIyDkv53lrZjpo47lnLrnmoTorqHnrpfph48NCmxldCBjdXJyVGltZSA9IHN5c2RhdGUoKTsNCnNhdmUoIkEwIiwgY3VyclRpbWUsICJXaW5kRmFybUFjdGl2ZVBvd2VyIiwgV2luZEZhcm1BY3RpdmVQb3dlciwNCgkJCWN1cnJUaW1lLCAiV2luZEZhcm1SZWFjdGl2ZVBvd2VyIiwgV2luZEZhcm1SZWFjdGl2ZVBvd2VyLA0KCQkJY3VyclRpbWUsICJXaW5kRmFybUF2Z1dpbmRTcGVlZCIsIFdpbmRGYXJtQXZnV2luZFNwZWVkLA0KCQkJY3VyclRpbWUsICJUdXJiaW5lQ291bnRQb3dlclByb2QiLCBUdXJiaW5lQ291bnRQb3dlclByb2QsDQoJCQljdXJyVGltZSwgIlR1cmJpbmVDb3VudEZhdWx0ZWQiLCBUdXJiaW5lQ291bnRGYXVsdGVkLA0KCQkJY3VyclRpbWUsICJUdXJiaW5lQ291bnRJZGxlIiwgVHVyYmluZUNvdW50SWRsZSwNCgkJCWN1cnJUaW1lLCAiVHVyYmluZUNvdW50RGlzY29ubmVjdGVkIiwgVHVyYmluZUNvdW50RGlzY29ubmVjdGVkKTsNCg0K",
"msg": "操作成功"
}
```
返参描述
| 参数名 | 参数类型 | 可选 | 描述 |
| ------------- | -------- | ---- |------|
| data | String | 否 | 脚本内容(Base64编码) |

View File

@ -1182,12 +1182,12 @@ onUnmounted(() => {
<style scoped lang="scss">
.default-main {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
color: #4E5969;
background-color: #F2F3F5;
overflow-x: hidden;
.content-number{
color: #333333;
font-size: 20px;
@ -1267,7 +1267,12 @@ onUnmounted(() => {
.power{
.power-chart{
width: 100%;
height: 250px;
height: 260px;
}
@media screen and (max-width: 1920px) {
.power-chart{
height: 250px;
}
}
}
.matrix{
@ -1296,7 +1301,7 @@ onUnmounted(() => {
}
.trend{
height: 350px;
height: 365px;
overflow: hidden;
.trend-tabs{
:deep(.el-tabs__item){
@ -1337,9 +1342,19 @@ onUnmounted(() => {
height: 260px;
}
}
@media screen and (max-width: 1920px) {
.trend{
height: 350px;
}
}
}
}
@media screen and (max-width: 1920px) {
.default-main{
height: auto;
}
}
</style>