diff --git a/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java b/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java index 7f8f0844..27b97792 100644 --- a/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java +++ b/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java @@ -35,6 +35,12 @@ public class SysLogDTO { */ private String createBy; + /** + * 创建时间 + */ + private LocalDateTime createTime; + private String[] createTimeArr; + /** * 更新时间 */ @@ -85,11 +91,6 @@ public class SysLogDTO { */ private String serviceId; - /** - * 创建时间区间 [开始时间,结束时间] - */ - private LocalDateTime[] createTime; - /** * 租户编号 */ diff --git a/common/src/main/java/com/sdm/common/service/lyric/HkCloudSignObject.java b/common/src/main/java/com/sdm/common/service/lyric/HkCloudSignObject.java new file mode 100644 index 00000000..8826f8d3 --- /dev/null +++ b/common/src/main/java/com/sdm/common/service/lyric/HkCloudSignObject.java @@ -0,0 +1,8 @@ +package com.sdm.common.service.lyric; + +public class HkCloudSignObject { + + public String jobNo; + + public String appKey; +} diff --git a/common/src/main/java/com/sdm/common/service/lyric/HkUploadFileReq.java b/common/src/main/java/com/sdm/common/service/lyric/HkUploadFileReq.java new file mode 100644 index 00000000..28d7e5b4 --- /dev/null +++ b/common/src/main/java/com/sdm/common/service/lyric/HkUploadFileReq.java @@ -0,0 +1,41 @@ +package com.sdm.common.service.lyric; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +public class HkUploadFileReq { + @Schema(description = "权限编码") + public String filePower = "2456236750149124114"; + + @Schema(description = "是否加水印") + public boolean waterMarkFlag = false; + + @Schema(description = "水印内容") + public String waterMarkContent = ""; + + @Schema(description = "系统ID") + public long sysId = 1691399963692630016L; + + @Schema(description = "表单ID") + public long formId = 1847115435993071616L; + + @Schema(description = "控件ID") + public long componentInstId = 8000004142460000204L; + + @Schema(description = "表名称") + public String tableName = "oa_threee_d_review"; + + @Schema(description = "字段名称") + public String columnName = "simulation_table;"; + + @Schema(description = "项目号") + public String xmh = ""; + + @Schema(description = "工位号") + public String gwh = ""; + + @Schema(description = "上传文件") + public List files = new ArrayList(); +} diff --git a/common/src/main/java/com/sdm/common/service/lyric/LyricIntegrateService.java b/common/src/main/java/com/sdm/common/service/lyric/LyricIntegrateService.java new file mode 100644 index 00000000..828d6520 --- /dev/null +++ b/common/src/main/java/com/sdm/common/service/lyric/LyricIntegrateService.java @@ -0,0 +1,293 @@ +package com.sdm.common.service.lyric; + +import com.alibaba.fastjson2.JSONObject; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.utils.HttpUtil; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.DigestUtils; + +import javax.net.ssl.SSLContext; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + +@Service +public class LyricIntegrateService { + + //测试开发环境 + private final String appKey = "e9eb516aa02a43a29e227a0d901ec5f1"; + + private final String appSecret = "9fac43db08634aaf8a9fe5fb9468de9d"; + //海葵云url + private final String HK_CLOUD_URL = "https://v15.lyh.haikuicloud.com"; + //海葵云获取用户token url后缀 + private final String HK_USER_TOKEN_URL_SUFFIX = "/merchant/openapi/user/login/jobNo"; + //海葵云获取单个用户信息url后缀 + private final String HK_SIMPLE_USER_URL_SUFFIX = "/merchant/api/user/getSimpleUserInfo"; + //海葵云上传文件url后缀 + private final String HK_UPLOAD_FILE_URL_SUFFIX = "/haikui-oa/autoCreateFlow/uploadFile"; + //EP系统URL + private final String EP_URL = "https://ep-url.dev.haikuicloud.com"; + //推送代办状态url后缀 + private final String QUERY_TODO_STATUS_SUFFIX = "/todoApi/todo/emulation/dm/status"; + //查询待办结果url后缀 + private final String QUERY_TODO_RESULT_SUFFIX = "/todoApi/todo/emulation/dm/result"; + //查询待办附加url后缀 + private final String QUERY_TOD_ATTACHMENT_SUFFIX = "/todoApi/todo/emulation/dm/attachments"; + + //生产环境 + /** + + + private final String EP_URL = "https://ep-url.lyh.haikuicloud.com; + */ + + /** + * 生成海葵云token签名 + * + * @param appKey + * @param appSecret + * @param jobNo + * @return + */ + private String calculateSignHkcloud(String appKey, String appSecret, String jobNo) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("appKey", appKey); + jsonObject.put("appSecret", appSecret); + jsonObject.put("jobNo", jobNo); + String addSalStr = JSONObject.toJSONString(jsonObject); + return DigestUtils.md5DigestAsHex(addSalStr.getBytes(StandardCharsets.UTF_8)); + } + + /** + * 获取根据工号获取用户token + * + * @param appKey + * @param appSecret + * @param jobNo + * @param tokenUrl + * @return + */ + public String getHKCloudToken(String appKey, String appSecret, String jobNo, String tokenUrl) { + String sign = calculateSignHkcloud(appKey, appSecret, jobNo); + String token = null; + JSONObject jsonObject = new JSONObject(); + jsonObject.put("jobNo", jobNo); + jsonObject.put("appKey", appKey); + jsonObject.put("sign", sign); + try { + String result = HttpUtil.httpPost(tokenUrl, null, jsonObject.toJSONString()); + JSONObject resultJson = JSONObject.parseObject(result); + String code = resultJson.getString("code"); + if (code.equals("0000")) { + JSONObject dataObject = resultJson.getJSONObject("data"); + if (dataObject != null) { + token = dataObject.getString("token"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return token; + } + + /** + * 获取当前用户的 + * + * @param jobNo + * @return + */ + public SdmResponse getHKCloudSimpleUserInfo(String jobNo) { + SdmResponse response = SdmResponse.success(); + String tokenUrl = HK_CLOUD_URL + HK_USER_TOKEN_URL_SUFFIX; + String token = getHKCloudToken(appKey, appSecret, jobNo, tokenUrl); + if (token == null || token.isEmpty()) { + response = SdmResponse.failed("获取海葵云token失败"); + } else { + String simpleUserUrl = HK_CLOUD_URL + HK_SIMPLE_USER_URL_SUFFIX; + Map headers = new HashMap(); + headers.put("authorization", token); + try { + String result = HttpUtil.httpPost(simpleUserUrl, headers, ""); + JSONObject resultJson = JSONObject.parseObject(result); + String code = resultJson.getString("code"); + if (code.equals("0000")) { + JSONObject dataObject = resultJson.getJSONObject("data"); + if (dataObject != null) { + response.setData(dataObject); + } + } else { + response = SdmResponse.failed("获取海葵云单个用户信息失败"); + } + } catch (Exception e) { + e.printStackTrace(); + response = SdmResponse.failed("获取海葵云单个用户信息失败"); + } + } + return response; + } + + /** + * 构建信任所有证书的CloseableHttpClient + * @return + */ + private static CloseableHttpClient createHttpsClient() { + try { + // 1. 构建SSL上下文(信任所有证书) + SSLContext sslContext = SSLContextBuilder.create() + .loadTrustMaterial(null, (chain, authType) -> true) // 信任所有证书 + .build(); + + // 2. 创建SSL连接工厂(忽略主机名验证) + SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory( + sslContext, + NoopHostnameVerifier.INSTANCE // 信任所有主机名 + ); + + // 3. 配置超时参数 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(30000) // 连接超时30秒 + .setSocketTimeout(300000) // 读取超时5分钟 + .setConnectionRequestTimeout(5000) // 连接池超时5秒 + .build(); + + // 4. 构建HttpClient + return HttpClients.custom() + .setSSLSocketFactory(sslSocketFactory) + .setDefaultRequestConfig(requestConfig) + .build(); + } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { + throw new RuntimeException("创建HTTPS客户端失败", e); + } + } + + /** + * 上传仿真报告 + * + * @param jobNo + * @param hkUploadFileReq + * @return + */ + public SdmResponse uploadHkFile(String jobNo, HkUploadFileReq hkUploadFileReq) { + SdmResponse response = SdmResponse.failed("文件上传失败"); + String token = getHKCloudToken(appKey, appSecret, jobNo, HK_CLOUD_URL); + if (token == null || token.isEmpty()) + { + response = SdmResponse.failed("获取token失败"); + } + else + { + String url = HK_CLOUD_URL + HK_UPLOAD_FILE_URL_SUFFIX; + HttpPost httpPost = new HttpPost(url); + MultipartEntityBuilder builder = MultipartEntityBuilder.create() + .setCharset(StandardCharsets.UTF_8); // 解决中文乱码 + + // 添加普通参数 + builder.addPart("filePower", new StringBody(hkUploadFileReq.filePower, + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("waterMarkFlag", new StringBody(String.valueOf(hkUploadFileReq.waterMarkFlag), + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("waterMarkContent", new StringBody(hkUploadFileReq.waterMarkContent, + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("sysId", new StringBody(String.valueOf(hkUploadFileReq.sysId), + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("formId", new StringBody(String.valueOf(hkUploadFileReq.formId), + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("ComponentInstId", new StringBody(String.valueOf(hkUploadFileReq.componentInstId), + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("tableName", new StringBody(hkUploadFileReq.tableName, + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("columnName", new StringBody(hkUploadFileReq.columnName, + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("xmh", new StringBody(hkUploadFileReq.xmh, + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + builder.addPart("gwh", new StringBody(hkUploadFileReq.gwh, + ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))); + + // 追加多个文件(同一字段名files) + for (String filePath : hkUploadFileReq.files) { + File file = new File(filePath); + if (file.exists()) + builder.addPart("files", new FileBody(file, ContentType.DEFAULT_BINARY, file.getName())); + } + + // 构建HttpPost请求 + httpPost.setEntity(builder.build()); + try + { + CloseableHttpClient httpclient = createHttpsClient(); + CloseableHttpResponse fileResponse = httpclient.execute(httpPost); + String responseContent = EntityUtils.toString(fileResponse.getEntity(), StandardCharsets.UTF_8); + if(responseContent != null && !responseContent.isEmpty()) + { + JSONObject responseJson = JSONObject.parseObject(responseContent); + if(responseJson.containsKey("code")) + { + String code = responseJson.getString("code"); + if(code != null && code.equals("0000")) + { + response = SdmResponse.success(); + } + } + } + } + catch (Exception e) + { + e.printStackTrace(); + response = SdmResponse.failed("上传文件异常"); + } + } + return response; + } + + /** + * 推送代办状态 + * @param todoId + * @param reason + * @param progress + * @param progressDescription + * @param userNo + * @param statusType doing(启动),turnDown(驳回),pause(暂停),restart(重启),updateProgress(提交进度),finished(完成),closed(关闭) + * @return + */ + public SdmResponse pushTodoStatus(int todoId,String reason,int progress,String progressDescription,String userNo,String statusType) + { + return null; + } + + public SdmResponse getTodoAttachments() + { + return null; + } + + public SdmResponse getTodoList() + { + return null; + } + + + + + +} + + diff --git a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java new file mode 100644 index 00000000..d47a1b8f --- /dev/null +++ b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java @@ -0,0 +1,32 @@ +package com.sdm.project.controller; + +import com.alibaba.excel.util.StringUtils; +import com.sdm.common.common.SdmResponse; +import com.sdm.project.common.ApprovalStatusEnum; +import com.sdm.project.model.entity.SimulationNode; +import com.sdm.project.service.ISimulationLyricNodeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; + +@RestController +@RequestMapping(value = "/node") +@Tag(name = "利元亨定制节点相关接口", description = "利元亨定制节点相关接口") +public class SimulationLyricNodeController { + + @Autowired + private ISimulationLyricNodeService nodeService; + + @GetMapping("/updateApprovalStatus") + @Operation(summary = "仿真节点审批状态更新", description = "仿真节点审批状态更新") + public SdmResponse updateApprovalStatus(@RequestParam(value = "projectName") @Validated String projectName, @RequestParam(value = "workspaceName") @Validated String workspaceName, @RequestParam(value = "approvalStatus") @Validated Integer approvalStatus) { + return nodeService.updateApprovalStatus(projectName,workspaceName,approvalStatus); + } + + + +} diff --git a/project/src/main/java/com/sdm/project/dao/SimulationLyricNodeMapper.java b/project/src/main/java/com/sdm/project/dao/SimulationLyricNodeMapper.java new file mode 100644 index 00000000..5eda66c5 --- /dev/null +++ b/project/src/main/java/com/sdm/project/dao/SimulationLyricNodeMapper.java @@ -0,0 +1,12 @@ +package com.sdm.project.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.sdm.project.model.entity.SimulationBaseQuantities; +import com.sdm.project.model.entity.SimulationNode; +import org.apache.ibatis.annotations.Mapper; + + +@Mapper +public interface SimulationLyricNodeMapper extends BaseMapper { + +} diff --git a/project/src/main/java/com/sdm/project/model/entity/SimulationNode.java b/project/src/main/java/com/sdm/project/model/entity/SimulationNode.java index f8e86363..b1bf057d 100644 --- a/project/src/main/java/com/sdm/project/model/entity/SimulationNode.java +++ b/project/src/main/java/com/sdm/project/model/entity/SimulationNode.java @@ -143,5 +143,7 @@ public class SimulationNode implements Serializable { @TableField("tag10") private String tag10; + @TableField("approval_status") + private String approvalStatus; } diff --git a/project/src/main/java/com/sdm/project/service/ISimulationLyricDemandService.java b/project/src/main/java/com/sdm/project/service/ISimulationLyricDemandService.java new file mode 100644 index 00000000..2cb9b294 --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/ISimulationLyricDemandService.java @@ -0,0 +1,10 @@ +package com.sdm.project.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.project.model.entity.SimulationDemand; +import org.springframework.stereotype.Service; + +public interface ISimulationLyricDemandService extends IService { + + +} diff --git a/project/src/main/java/com/sdm/project/service/ISimulationLyricNodeService.java b/project/src/main/java/com/sdm/project/service/ISimulationLyricNodeService.java new file mode 100644 index 00000000..09f644c5 --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/ISimulationLyricNodeService.java @@ -0,0 +1,12 @@ +package com.sdm.project.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.common.common.SdmResponse; +import com.sdm.project.model.entity.SimulationNode; +import org.springframework.stereotype.Service; + +public interface ISimulationLyricNodeService extends IService { + + SdmResponse updateApprovalStatus(String projectName, String workspaceName, Integer approvalStatus); + +} diff --git a/project/src/main/java/com/sdm/project/service/impl/ISimulationLyricNodeServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/ISimulationLyricNodeServiceImpl.java new file mode 100644 index 00000000..822df49d --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/impl/ISimulationLyricNodeServiceImpl.java @@ -0,0 +1,44 @@ +package com.sdm.project.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.entity.enums.NodeTypeEnum; +import com.sdm.project.common.ApprovalStatusEnum; +import com.sdm.project.dao.SimulationLyricNodeMapper; +import com.sdm.project.model.entity.SimulationNode; +import com.sdm.project.service.ISimulationLyricNodeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Slf4j +public class ISimulationLyricNodeServiceImpl extends ServiceImpl implements ISimulationLyricNodeService { + + @Override + public SdmResponse updateApprovalStatus(String projectName, String workspaceName, Integer approvalStatus) { + + // 0:未通过,1:已通过 + String approvalStatusValue = String.valueOf(approvalStatus == 0 ? ApprovalStatusEnum.REJECTED.getCode() : ApprovalStatusEnum.PASSED.getCode()); + List projectNodeList = this.lambdaQuery().eq(SimulationNode::getNodeName, projectName) + .eq(SimulationNode::getNodeType, NodeTypeEnum.PROJECT.getValue()).list(); + if (CollectionUtils.isEmpty(projectNodeList)) { + log.error("根据项目名称:{},未查询到节点信息", projectName); + return SdmResponse.failed("根据项目名称:" + projectName + ",未查询到节点信息,请确认后重试"); + } + if (projectNodeList.size() > 1) { + log.error("根据项目名称:{},查询到{}个项目信息", projectName, projectNodeList.size()); + return SdmResponse.failed("根据项目名称:" + projectName + ",查询到" + projectNodeList.size() + "个项目信息,请确认处理后重试"); + } + SimulationNode projectNode = projectNodeList.get(0); + log.info("查询到的节点为:{}", projectNode); + boolean updateFlag = this.lambdaUpdate().set(SimulationNode::getApprovalStatus, approvalStatusValue) + .eq(SimulationNode::getTag1, projectNode.getUuid()) + .eq(SimulationNode::getNodeName, workspaceName) + .update(); + return updateFlag ? SdmResponse.success("仿真节点审批状态成功") : SdmResponse.failed("仿真节点审批状态更新失败"); + } + +} diff --git a/project/src/main/resources/mapper/SimulationNodeMapper.xml b/project/src/main/resources/mapper/SimulationNodeMapper.xml index 92dd6b91..33901a39 100644 --- a/project/src/main/resources/mapper/SimulationNodeMapper.xml +++ b/project/src/main/resources/mapper/SimulationNodeMapper.xml @@ -52,6 +52,9 @@ endTime = #{editNode.endTime}, + + finishTime = #{editNode.finishTime}, + description = #{editNode.description}, diff --git a/project/src/main/resources/mapper/SimulationTaskMapper.xml b/project/src/main/resources/mapper/SimulationTaskMapper.xml index 3b5eb04a..ff20a322 100644 --- a/project/src/main/resources/mapper/SimulationTaskMapper.xml +++ b/project/src/main/resources/mapper/SimulationTaskMapper.xml @@ -70,34 +70,25 @@ ) - - = #{req.beginTime} - ]]> - + = #{req.beginSTime} + and STR_TO_DATE(begin_time,'%Y-%m-%d %H:%i:%s') >= #{req.beginSTime} ]]> - - - = #{req.endSTime} ]]> @@ -106,19 +97,15 @@ and STR_TO_DATE(end_time,'%Y-%m-%d') <= DATE_ADD(CURRENT_DATE(), INTERVAL 2 DAY) ]]> - - - + = #{req.finishSTime} ]]> diff --git a/system/src/main/java/com/sdm/system/controller/SystemLogController.java b/system/src/main/java/com/sdm/system/controller/SystemLogController.java index 339104d9..ae203a46 100644 --- a/system/src/main/java/com/sdm/system/controller/SystemLogController.java +++ b/system/src/main/java/com/sdm/system/controller/SystemLogController.java @@ -1,16 +1,20 @@ package com.sdm.system.controller; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.sdm.common.common.SdmResponse; import com.sdm.common.feign.inter.system.ISysLogFeignClient; import com.sdm.common.log.dto.SysLogDTO; -import com.sdm.system.service.ISimulationLogService; +import com.sdm.system.model.resp.DailyOnlineStateResp; +import com.sdm.system.model.resp.LoginStateResp; +import com.sdm.system.service.ISysLogService; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; +import org.springdoc.core.annotations.ParameterObject; 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.bind.annotation.*; + +import java.util.List; /** *

@@ -25,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController; public class SystemLogController implements ISysLogFeignClient { @Autowired - private ISimulationLogService logService; + private ISysLogService logService; @PostMapping("/saveLog") public SdmResponse saveLog(@RequestBody SysLogDTO req) @@ -33,4 +37,32 @@ public class SystemLogController implements ISysLogFeignClient { return logService.saveLog(req); } + /** + * 分页查询 + * @param page 分页对象 + * @param sysLog 系统日志 + * @return + */ + @GetMapping("/page") + public SdmResponse getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) { + return logService.getLogByPage(page, sysLog); + } + + /** + * 统计某时间段的用户登录数 + * @param sysLog + * @return + */ + @GetMapping("/getUserLoginStatistics") + public SdmResponse> getUserLoginStatistics(@ParameterObject SysLogDTO sysLog) { + return logService.getUserLoginStatistics(sysLog); + } + + /** + * 获取某天每小时在线用户统计 + */ + @GetMapping("/getHourlyOnlineStatistics") + public SdmResponse getHourlyOnlineStatistics(@RequestParam @NotNull(message = "日期不能为空") String date) { + return logService.getHourlyOnlineStatistics(date); + } } diff --git a/system/src/main/java/com/sdm/system/dao/SysLogMapper.java b/system/src/main/java/com/sdm/system/dao/SysLogMapper.java new file mode 100644 index 00000000..a6a1fc26 --- /dev/null +++ b/system/src/main/java/com/sdm/system/dao/SysLogMapper.java @@ -0,0 +1,21 @@ +package com.sdm.system.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.sdm.system.model.dto.HourlyOnlineDto; +import com.sdm.system.model.entity.SysLog; +import com.sdm.system.model.resp.LoginStateResp; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +@Mapper +public interface SysLogMapper extends BaseMapper { + + List countDailyLoginUsers(@Param("startTime") String startTime, + @Param("endTime") String endTime); + + List getHourlyOnlineUsers(@Param("date") String date); + +} diff --git a/system/src/main/java/com/sdm/system/model/dto/HourlyOnlineDto.java b/system/src/main/java/com/sdm/system/model/dto/HourlyOnlineDto.java new file mode 100644 index 00000000..fab3d58b --- /dev/null +++ b/system/src/main/java/com/sdm/system/model/dto/HourlyOnlineDto.java @@ -0,0 +1,15 @@ +package com.sdm.system.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class HourlyOnlineDto { + + @Schema(description = "小时") + private String hour; + + @Schema(description = "在线用户数") + private Integer onlineCount; + +} diff --git a/system/src/main/java/com/sdm/system/model/entity/SysLog.java b/system/src/main/java/com/sdm/system/model/entity/SysLog.java new file mode 100644 index 00000000..6cf8dc8b --- /dev/null +++ b/system/src/main/java/com/sdm/system/model/entity/SysLog.java @@ -0,0 +1,133 @@ +package com.sdm.system.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 日志表 + *

+ * + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("sys_log") +@ApiModel(value="SysLog对象", description="日志表") +public class SysLog implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @Schema(description = "日志编号") + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 日志类型 + */ + @Schema(description = "日志类型") + @TableField("logType") + private String logType; + + /** + * 日志标题 + */ + @Schema(description = "日志标题") + @TableField("title") + private String title; + + /** + * 创建者 + */ + @Schema(description = "创建人") + @TableField("createBy") + private String createBy; + + /** + * 创建时间 + */ + @Schema(description = "创建时间") + @TableField("createTime") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Schema(description = "更新时间") + @TableField("updateTime") + private LocalDateTime updateTime; + + /** + * 操作IP地址 + */ + @Schema(description = "操作ip地址") + @TableField("remoteAddr") + private String remoteAddr; + + /** + * 用户代理 + */ + @Schema(description = "用户代理") + @TableField("userAgent") + private String userAgent; + + /** + * 请求URI + */ + @Schema(description = "请求uri") + @TableField("requestUri") + private String requestUri; + + /** + * 操作方式 + */ + @Schema(description = "操作方式") + @TableField("method") + private String method; + + /** + * 操作提交的数据 + */ + @Schema(description = "提交数据") + @TableField("params") + private String params; + + /** + * 执行时间 + */ + @Schema(description = "方法执行时间") + @TableField("time") + private Long time; + + /** + * 异常信息 + */ + @Schema(description = "异常信息") + @TableField("exception") + private String exception; + + /** + * 服务ID + */ + @Schema(description = "应用标识") + @TableField("serviceId") + private String serviceId; + + /** + * 删除标记 + */ + @Schema(description = "删除标记,1:已删除,0:正常") + @TableField("delFlag") + private String delFlag; + +} diff --git a/system/src/main/java/com/sdm/system/model/resp/DailyOnlineStateResp.java b/system/src/main/java/com/sdm/system/model/resp/DailyOnlineStateResp.java new file mode 100644 index 00000000..98688262 --- /dev/null +++ b/system/src/main/java/com/sdm/system/model/resp/DailyOnlineStateResp.java @@ -0,0 +1,17 @@ +package com.sdm.system.model.resp; + +import com.sdm.system.model.dto.HourlyOnlineDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class DailyOnlineStateResp { + + @Schema(description = "日期") + private String date; + + @Schema(description = "每小时统计") + private List hourlyStats; +} diff --git a/system/src/main/java/com/sdm/system/model/resp/LoginStateResp.java b/system/src/main/java/com/sdm/system/model/resp/LoginStateResp.java new file mode 100644 index 00000000..e9b654d8 --- /dev/null +++ b/system/src/main/java/com/sdm/system/model/resp/LoginStateResp.java @@ -0,0 +1,15 @@ +package com.sdm.system.model.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class LoginStateResp { + + @Schema(description = "日期") + private String date; + + @Schema(description = "登录用户数") + private Integer loginUserCount; + +} diff --git a/system/src/main/java/com/sdm/system/service/ISysLogService.java b/system/src/main/java/com/sdm/system/service/ISysLogService.java new file mode 100644 index 00000000..bf232787 --- /dev/null +++ b/system/src/main/java/com/sdm/system/service/ISysLogService.java @@ -0,0 +1,46 @@ + +package com.sdm.system.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.system.model.entity.SysLog; +import com.sdm.system.model.resp.DailyOnlineStateResp; +import com.sdm.system.model.resp.LoginStateResp; + +import java.util.List; + + +/** + *

+ * 日志表 服务类 + *

+ */ +public interface ISysLogService extends IService { + + /** + * 分页查询日志 + * @param page + * @param sysLog + * @return + */ + SdmResponse getLogByPage(Page page, SysLogDTO sysLog); + + /** + * 统计某时间段的用户登录数 + * @param sysLog + * @return + */ + SdmResponse> getUserLoginStatistics(SysLogDTO sysLog); + + SdmResponse getHourlyOnlineStatistics(String dateStr); + + /** + * 插入日志 + * @param sysLog 日志对象 + * @return true/false + */ + SdmResponse saveLog(SysLogDTO sysLog); + +} diff --git a/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java b/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java new file mode 100644 index 00000000..bce9f6a3 --- /dev/null +++ b/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java @@ -0,0 +1,128 @@ + +package com.sdm.system.service.impl; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.entity.req.system.UserQueryReq; +import com.sdm.common.entity.resp.system.CIDUserResp; +import com.sdm.common.feign.impl.system.SysUserFeignClientImpl; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.common.utils.CidSysUserUtil; +import com.sdm.system.dao.SysLogMapper; +import com.sdm.system.model.dto.HourlyOnlineDto; +import com.sdm.system.model.entity.SysLog; +import com.sdm.system.model.resp.DailyOnlineStateResp; +import com.sdm.system.model.resp.LoginStateResp; +import com.sdm.system.service.ISysLogService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + *

+ * 日志表 服务实现类 + *

+ */ +@Service +public class ISysLogServiceImpl extends ServiceImpl implements ISysLogService { + + @Autowired + SysUserFeignClientImpl sysUserFeignClient; + + @Override + public SdmResponse getLogByPage(Page page, SysLogDTO sysLog) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + if (StrUtil.isNotBlank(sysLog.getLogType())) { + wrapper.eq(SysLog::getLogType, sysLog.getLogType()); + } + if (StrUtil.isNotBlank(sysLog.getCreateBy())) { + wrapper.eq(SysLog::getCreateBy, sysLog.getCreateBy()); + } + + if (ArrayUtil.isNotEmpty(sysLog.getCreateTime())) { + wrapper.ge(SysLog::getCreateTime, sysLog.getCreateTimeArr()[0]) + .le(SysLog::getCreateTime, sysLog.getCreateTimeArr()[1]); + } + + Page pageData = baseMapper.selectPage(page, wrapper); + setCreatorNames(pageData.getRecords()); + return SdmResponse.success(pageData); + } + + @Override + public SdmResponse> getUserLoginStatistics(SysLogDTO sysLog) { + List respList = baseMapper.countDailyLoginUsers(sysLog.getCreateTimeArr()[0], sysLog.getCreateTimeArr()[1]); + return SdmResponse.success(respList); + } + + @Override + public SdmResponse getHourlyOnlineStatistics(String dateStr) { + // 获取每小时在线用户数 + List hourlyStats = baseMapper.getHourlyOnlineUsers(dateStr); + + DailyOnlineStateResp result = new DailyOnlineStateResp(); + result.setDate(dateStr); + result.setHourlyStats(hourlyStats); + return SdmResponse.success(result); + } + + private void setCreatorNames(List list) { + try { + if (ObjectUtils.isNotEmpty(list)) { + // 提取去重的 creatorId + List creatorIds = list.stream() + .map(SysLog::getCreateBy) + .filter(createBy -> !"anonymousUser".equals(createBy)) + .distinct() + .toList(); + + // 远程查询用户信息 + SdmResponse> userListSdmRsp = sysUserFeignClient.listUserByIds( + UserQueryReq.builder().userIds(creatorIds.stream().map(Long::valueOf).toList()).build() + ); + // 批量设置 creatorName + if (userListSdmRsp.isSuccess() && CollectionUtils.isNotEmpty(userListSdmRsp.getData())) { + Map cidUserMap = CidSysUserUtil.getCidUserToMap(userListSdmRsp.getData()); + list.forEach(sysLog -> { + Long creatorId = Long.valueOf(sysLog.getCreateBy()); + CIDUserResp cidUser = cidUserMap.get(creatorId); + String username = Objects.isNull(cidUser) ? "" : org.apache.commons.lang3.StringUtils.firstNonBlank( + cidUser.getNickname(), + cidUser.getUsername(), + cidUser.getRealName() + ); + sysLog.setCreateBy(username); + }); + } + } + } catch (Exception e) { + log.error("[getLogByPage] setCreatorNames error", e); + } + } + + /** + * 插入日志 + * @param sysLog 日志对象 + * @return true/false + */ + @Override + @Transactional(rollbackFor = Exception.class) + public SdmResponse saveLog(SysLogDTO sysLog) { + SysLog log = new SysLog(); + BeanUtils.copyProperties(sysLog, log); + return SdmResponse.success(this.save(log)); + } + +} diff --git a/system/src/main/resources/mapper/SysLogMapper.xml b/system/src/main/resources/mapper/SysLogMapper.xml new file mode 100644 index 00000000..9d9e2f50 --- /dev/null +++ b/system/src/main/resources/mapper/SysLogMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + + diff --git a/task/src/main/java/com/sdm/task/service/impl/SimulationTaskPoolServiceImpl.java b/task/src/main/java/com/sdm/task/service/impl/SimulationTaskPoolServiceImpl.java index 794ccef1..885db8da 100644 --- a/task/src/main/java/com/sdm/task/service/impl/SimulationTaskPoolServiceImpl.java +++ b/task/src/main/java/com/sdm/task/service/impl/SimulationTaskPoolServiceImpl.java @@ -163,7 +163,6 @@ public class SimulationTaskPoolServiceImpl extends BaseService implements ISimul String fileId = standardIds[1].trim(); fileIdList.add(Long.valueOf(fileId)); } - } SaveFileSimulationMappingReq req = new SaveFileSimulationMappingReq(); req.setSimulationPoolTaskId(taskPoolItem.uuid); @@ -172,7 +171,9 @@ public class SimulationTaskPoolServiceImpl extends BaseService implements ISimul req.setFileIds(fileIdList); saveFileSimulationMappingReq.add(req); } - simulationMappingFeignClient.batchSaveFileSimulationMapping(saveFileSimulationMappingReq); + if(!saveFileSimulationMappingReq.isEmpty()) { + simulationMappingFeignClient.batchSaveFileSimulationMapping(saveFileSimulationMappingReq); + } } /** @@ -1444,7 +1445,7 @@ public class SimulationTaskPoolServiceImpl extends BaseService implements ISimul response = SdmResponse.failed("分析项库不存在"); return response; } - int oldPoolId = oldPoolBrief.id; + int oldPoolId = currPoolBrief.id; if(updateBean.bNewVersion) { //在当前分析项库活动版本记录中生成新版本