Merge remote-tracking branch 'origin/master'
| | |
| | | - id: report-jimu # 路由的编号(积木报表) |
| | | uri: grayLb://report-server |
| | | predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 |
| | | - Path=/jmreport/** |
| | | - Path=/jmreport/**, /drag/** |
| | | ## statistics-server 服务 |
| | | - id: statistics-admin-api # 路由的编号 |
| | | uri: grayLb://statistics-server |
| | |
| | | - name: model-server |
| | | service-name: model-server |
| | | url: /admin-api/model/v3/api-docs |
| | | - name: report-server |
| | | service-name: report-server |
| | | url: /admin-api/report/v3/api-docs |
| | | --- #################### 平台相关配置 #################### |
| | | |
| | | iailab: |
| | |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.security.config.Customizer; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | |
| | | import javax.annotation.Resource; |
| | |
| | | * @author iailab |
| | | */ |
| | | public abstract class AuthorizeRequestsCustomizer |
| | | implements Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry>, Ordered { |
| | | implements Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry>, Ordered { |
| | | |
| | | @Resource |
| | | private WebProperties webProperties; |
| | |
| | | // 设置每个请求的权限 |
| | | httpSecurity |
| | | // ①:全局共享规则 |
| | | .authorizeRequests() |
| | | .authorizeHttpRequests(c -> c |
| | | // 1.1 静态资源,可匿名访问 |
| | | .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() |
| | | .requestMatchers(HttpMethod.GET, "/*.html", "/*.html", "/*.css", "/*.js").permitAll() |
| | | // 1.2 设置 @PermitAll 无需认证 |
| | | .antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll() |
| | | .antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll() |
| | | .antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll() |
| | | .antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll() |
| | | // 1.3 基于 iailab.security.permit-all-urls 无需认证 |
| | | .antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll() |
| | | // 1.4 设置 App API 无需认证 |
| | | .antMatchers(buildAppApi("/**")).permitAll() |
| | | // 1.5 验证码captcha 允许匿名访问 |
| | | .antMatchers("/captcha/get", "/captcha/check").permitAll() |
| | | .requestMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll() |
| | | .requestMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll() |
| | | .requestMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll() |
| | | .requestMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll() |
| | | .requestMatchers(HttpMethod.HEAD, permitAllUrls.get(HttpMethod.HEAD).toArray(new String[0])).permitAll() |
| | | .requestMatchers(HttpMethod.PATCH, permitAllUrls.get(HttpMethod.PATCH).toArray(new String[0])).permitAll() |
| | | // 1.3 基于 yudao.security.permit-all-urls 无需认证 |
| | | .requestMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll() |
| | | ) |
| | | // ②:每个项目的自定义规则 |
| | | .and().authorizeRequests(registry -> // 下面,循环设置自定义规则 |
| | | authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry))) |
| | | .authorizeHttpRequests(c -> authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(c))) |
| | | // ③:兜底规则,必须认证 |
| | | .authorizeRequests() |
| | | .anyRequest().authenticated(); |
| | | .authorizeHttpRequests(c -> c.anyRequest().authenticated()); |
| | | |
| | | // 添加 Token Filter |
| | | httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); |
| | |
| | | import com.iailab.framework.websocket.config.WebSocketProperties; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * WebSocket 的权限自定义 |
| | |
| | | private final WebSocketProperties webSocketProperties; |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | registry.antMatchers(webSocketProperties.getPath()).permitAll(); |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | registry.requestMatchers(webSocketProperties.getPath()).permitAll(); |
| | | } |
| | | |
| | | } |
| | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * Bpm 模块的 Security 配置 |
| | |
| | | return new AuthorizeRequestsCustomizer() { |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案 |
| | | // Swagger 接口文档 |
| | | registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | registry.requestMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .requestMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | // Druid 监控 |
| | | registry.antMatchers("/druid/**").anonymous(); |
| | | registry.requestMatchers("/druid/**").anonymous(); |
| | | // Spring Boot Actuator 的安全配置 |
| | | registry.antMatchers("/actuator").anonymous() |
| | | .antMatchers("/actuator/**").anonymous(); |
| | | registry.requestMatchers("/actuator").anonymous() |
| | | .requestMatchers("/actuator/**").anonymous(); |
| | | } |
| | | |
| | | }; |
| | |
| | | PRIMARY KEY (id) USING BTREE, |
| | | UNIQUE INDEX `uk_item_no` (`item_no`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT = '计划数据项'; |
| | | |
| | | CREATE TABLE t_da_cumulate_point( |
| | | `id` VARCHAR(36) NOT NULL COMMENT 'ID' , |
| | | `point_id` VARCHAR(36) COMMENT '测点ID' , |
| | | `moment_point` VARCHAR(36) COMMENT '瞬时测点' , |
| | | `length` int COMMENT '累计长度', |
| | | `divisor` int COMMENT '除数', |
| | | PRIMARY KEY (id) USING BTREE, |
| | | UNIQUE KEY `uk_point_id` (`point_id`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT = '累计点表'; |
| | | INSERT INTO `iailab_expert_tenant_shasteel`.`t_da_sequence_num` (`id`, `code`, `name`, `sequence_num`, `prefix`) VALUES ('8', 'POINT_L', '累计点编码', 100001, 'L'); |
| | | INSERT INTO `iailab_plat_system`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1657, 4, '累计点', 'CUMULATE', 'data_point_type', 0, '', '', '', '142', '2024-11-29 10:13:12', '142', '2024-11-29 10:13:12', b'0'); |
| | |
| | | * @date 2021年05月24日 9:41 |
| | | */ |
| | | public enum IncreaseCodeEnum { |
| | | POINT_M, POINT_C, POINT_F, IND_A, IND_D, IND_C, PLAN; |
| | | POINT_M, POINT_C, POINT_F, POINT_L, IND_A, IND_D, IND_C, PLAN; |
| | | } |
| | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * System 模块的 Security 配置 |
| | |
| | | return new AuthorizeRequestsCustomizer() { |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案 |
| | | // Swagger 接口文档 |
| | | registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | registry.requestMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .requestMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | // Druid 监控 |
| | | registry.antMatchers("/druid/**").anonymous(); |
| | | registry.requestMatchers("/druid/**").anonymous(); |
| | | // Spring Boot Actuator 的安全配置 |
| | | registry.antMatchers("/actuator").anonymous() |
| | | .antMatchers("/actuator/**").anonymous(); |
| | | registry.requestMatchers("/actuator").anonymous() |
| | | .requestMatchers("/actuator/**").anonymous(); |
| | | // RPC 服务的安全配置 |
| | | registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | } |
| | | |
| | | }; |
| | |
| | | import com.iailab.module.data.common.utils.R; |
| | | import com.iailab.module.data.channel.kio.collector.KingIOCollector; |
| | | import com.iailab.module.data.point.collection.handler.CalculateHandle; |
| | | import com.iailab.module.data.point.collection.handler.CumulateHandle; |
| | | import com.iailab.module.data.point.common.PointTypeEnum; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.service.DaPointService; |
| | |
| | | @Resource |
| | | private OpcUaCollector opcUaCollector; |
| | | |
| | | @Resource |
| | | private CumulateHandle cumulateHandle; |
| | | |
| | | /** |
| | | * 采集 |
| | | * |
| | |
| | | List<DaPointDTO> pointCalculateList = daPointService.getMathPoint(minfreq); |
| | | pointValues.addAll(calculateHandle.handle(collectTime, pointCalculateList, dataMap)); |
| | | |
| | | log.info("读取累计点"); |
| | | List<DaPointDTO> pointCumulateList = daPointService.getCumulatePoint(minfreq); |
| | | pointValues.addAll(cumulateHandle.handle(collectTime, pointCumulateList)); |
| | | |
| | | log.info("存入数据库"); |
| | | influxDBService.asyncWritePointValues(pointValues); |
| | | |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.collection.handler; |
| | | |
| | | import com.iailab.module.data.api.point.DataPointApi; |
| | | import com.iailab.module.data.api.point.dto.ApiPointDTO; |
| | | import com.iailab.module.data.api.point.dto.ApiPointValueDTO; |
| | | import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO; |
| | | import com.iailab.module.data.common.enums.CommonConstant; |
| | | import com.iailab.module.data.enums.DataPointFreqEnum; |
| | | import com.iailab.module.data.influxdb.pojo.InfluxPointValuePOJO; |
| | | import com.iailab.module.data.point.collection.utils.GenInfluxPointValueUtils; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 累计点处理 |
| | | * |
| | | * @author PanZhibao |
| | | * @Description |
| | | * @createTime 2024年11月29日 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class CumulateHandle { |
| | | |
| | | @Autowired |
| | | @Lazy |
| | | private DataPointApi dataPointApi; |
| | | |
| | | public List<InfluxPointValuePOJO> handle(Date collectTime, List<DaPointDTO> dtos) { |
| | | List<InfluxPointValuePOJO> result = new ArrayList<>(); |
| | | try { |
| | | log.info("累计点处理开始"); |
| | | if (CollectionUtils.isEmpty(dtos)) { |
| | | return result; |
| | | } |
| | | dtos.forEach(dto -> { |
| | | try { |
| | | Object value = singleCompute(dto, collectTime); |
| | | InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(dto, value); |
| | | pojo.setTimestamp(collectTime.toInstant()); |
| | | result.add(pojo); |
| | | } catch (Exception ex) { |
| | | ex.printStackTrace(); |
| | | log.info("累计点异常!PointNo=" + dto.getPointNo()); |
| | | } |
| | | }); |
| | | |
| | | } catch (Exception ex) { |
| | | ex.printStackTrace(); |
| | | log.info("累计点处理异常!"); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | private Object singleCompute(DaPointDTO dto, Date collectTime) { |
| | | ApiPointDTO pointDTO = dataPointApi.getInfoByNo(dto.getMomentPoint()); |
| | | if (pointDTO == null) { |
| | | return CommonConstant.BAD_VALUE; |
| | | } |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(collectTime); |
| | | calendar.add(Calendar.MINUTE, -1); |
| | | Date endTime = calendar.getTime(); |
| | | calendar.add(Calendar.MINUTE, dto.getLength() * -1); |
| | | Date startTime = calendar.getTime(); |
| | | ApiPointValueQueryDTO queryDto = new ApiPointValueQueryDTO(); |
| | | queryDto.setStart(startTime); |
| | | queryDto.setEnd(endTime); |
| | | queryDto.setPointNo(dto.getMomentPoint()); |
| | | |
| | | List<ApiPointValueDTO> dataList = dataPointApi.queryPointHistoryValue(queryDto); |
| | | if (CollectionUtils.isEmpty(dataList)) { |
| | | return BigDecimal.ZERO; |
| | | } else if (dataList.size() < dto.getLength()) { |
| | | // 补全数据 |
| | | dataList = completionData(dto.getLength(), dataList, startTime, endTime, pointDTO); |
| | | } |
| | | double total = dataList.stream().mapToDouble(ApiPointValueDTO::getV).sum(); |
| | | return new BigDecimal(total).divide(new BigDecimal(dto.getDivisor()), 2, BigDecimal.ROUND_HALF_UP); |
| | | } |
| | | |
| | | private List<ApiPointValueDTO> completionData(int length, List<ApiPointValueDTO> dataList, Date startTime, Date endTime, ApiPointDTO pointDTO) { |
| | | if (CollectionUtils.isEmpty(dataList) || length == dataList.size()) { |
| | | return dataList; |
| | | } else if (length < dataList.size()) { |
| | | return dataList.subList(dataList.size() - length, dataList.size()); |
| | | } |
| | | |
| | | List<ApiPointValueDTO> result = new ArrayList<>(); |
| | | long start = startTime.getTime(); |
| | | long end = endTime.getTime(); |
| | | long oneMin = 1000L * DataPointFreqEnum.getEumByCode(pointDTO.getMinfreqid()).getValue(); |
| | | long mins = (end - start) / oneMin; |
| | | |
| | | //找出缺少项 |
| | | Map<Long, Double> sourceDataMap = new HashMap<>(dataList.size()); |
| | | Map<Long, Double> dataMap = new LinkedHashMap<>(); |
| | | for (int i = 0; i < mins; i++) { |
| | | Long key = start + oneMin * i; |
| | | Double value = sourceDataMap.get(key); |
| | | dataMap.put(key, value); |
| | | } |
| | | |
| | | //补充缺少项 |
| | | int k = 0; |
| | | Map.Entry<Long, Double> lastItem = null; |
| | | for (Map.Entry<Long, Double> item : dataMap.entrySet()) { |
| | | if (k == 0 && item.getValue() == null) { |
| | | item.setValue(getFirstValue(dataMap)); |
| | | } else if (item.getValue() == null) { |
| | | item.setValue(lastItem.getValue()); |
| | | } |
| | | k++; |
| | | lastItem = item; |
| | | |
| | | ApiPointValueDTO dataEntity = new ApiPointValueDTO(); |
| | | dataEntity.setT(new Date(item.getKey())); |
| | | dataEntity.setV(item.getValue()); |
| | | result.add(dataEntity); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private Double getFirstValue(Map<Long, Double> dataMap) { |
| | | for (Map.Entry<Long, Double> item : dataMap.entrySet()) { |
| | | if (item.getValue() != null) { |
| | | return item.getValue(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| | |
| | | public enum PointTypeEnum { |
| | | MEASURE_POINT("MEASURE", "测量点"), |
| | | CALCULATE_POINT("CALCULATE", "计算点"), |
| | | CONSTANT("CONSTANT", "常量点"); |
| | | CONSTANT("CONSTANT", "常量点"), |
| | | CUMULATE("CUMULATE", "累计点"); |
| | | |
| | | private String code; |
| | | |
| | |
| | | dataList.addAll(ConvertUtils.sourceToTarget(mathPointList, DaPointExcelVO.class)); |
| | | List<DaPointDTO> constantPointList = daPointService.getConstantPoint(exportReqVO); |
| | | dataList.addAll(ConvertUtils.sourceToTarget(constantPointList, DaPointExcelVO.class)); |
| | | List<DaPointDTO> cumulatePointList = daPointService.getCumulatePoint(exportReqVO); |
| | | dataList.addAll(ConvertUtils.sourceToTarget(cumulatePointList, DaPointExcelVO.class)); |
| | | ExcelUtils.write(response, "测点列表.xls", "测点列表", DaPointExcelVO.class, dataList); |
| | | } |
| | | |
| | |
| | | @Parameter(name = "file", description = "Excel 文件", required = true), |
| | | @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") |
| | | }) |
| | | // @PreAuthorize("@ss.hasPermission('data:point:import')") |
| | | public CommonResult<PointImportRespVO> importExcel(@RequestParam("file") MultipartFile file, |
| | | @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { |
| | | List<PointImportExcelVO> list = ExcelUtils.read(file, PointImportExcelVO.class); |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.dao; |
| | | |
| | | import com.iailab.framework.common.dao.BaseDao; |
| | | import com.iailab.framework.tenant.core.db.dynamic.TenantDS; |
| | | import com.iailab.module.data.point.entity.DaCumulatePointEntity; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * @author PanZhibao |
| | | * @Description |
| | | * @createTime 2024年11月28日 |
| | | */ |
| | | @TenantDS |
| | | @Mapper |
| | | public interface DaCumulatePointDao extends BaseDao<DaCumulatePointEntity> { |
| | | } |
| | |
| | | |
| | | List<DaPointDTO> getMathPoint(Map<String, Object> params); |
| | | |
| | | List<DaPointDTO> getCumulatePoint(Map<String, Object> params); |
| | | |
| | | default IPage<DaPointDTO> selectPageList(DaPointPageReqVO reqVO) { |
| | | return getPageList(getPage(reqVO), reqVO); |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.dto; |
| | | |
| | | import com.iailab.framework.common.validation.group.AddGroup; |
| | | import com.iailab.framework.common.validation.group.UpdateGroup; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import javax.validation.constraints.Null; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * @author PanZhibao |
| | | * @Description |
| | | * @createTime 2024年11月28日 |
| | | */ |
| | | @Data |
| | | @Tag(name = "累计点表") |
| | | public class DaCumulatePointDTO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Schema(description = "id") |
| | | @Null(message="{id.null}", groups = AddGroup.class) |
| | | @NotNull(message="{id.require}", groups = UpdateGroup.class) |
| | | private String id; |
| | | |
| | | @Schema(description = "测点ID", required = true) |
| | | private String pointId; |
| | | |
| | | @Schema(description = "瞬时测点", required = true) |
| | | private String momentPoint; |
| | | |
| | | @Schema(description = "累计长度", required = true) |
| | | private Integer length; |
| | | |
| | | @Schema(description = "除数", required = true) |
| | | private Integer divisor; |
| | | } |
| | |
| | | @Schema(description = "计算公式", required = true) |
| | | private String expression; |
| | | |
| | | @Schema(description = "瞬时测点") |
| | | private String momentPoint; |
| | | |
| | | @Schema(description = "累计长度") |
| | | private Integer length; |
| | | |
| | | @Schema(description = "除数") |
| | | private Integer divisor; |
| | | |
| | | @Schema(description = "数据源选项") |
| | | private List<String> sourceOption; |
| | | |
| | |
| | | |
| | | @Schema(description = "测量点") |
| | | private DaMeasurePointDTO measurePoint; |
| | | |
| | | @Schema(description = "累计点") |
| | | private DaCumulatePointDTO cumulatePoint; |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 累计点表 |
| | | * |
| | | * @author PanZhibao |
| | | * @Description |
| | | * @createTime 2024年11月28日 |
| | | */ |
| | | @Data |
| | | @TableName("t_da_cumulate_point") |
| | | public class DaCumulatePointEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * id |
| | | */ |
| | | @TableId(type = IdType.ASSIGN_UUID) |
| | | private String id; |
| | | |
| | | /** |
| | | * 测点ID |
| | | */ |
| | | private String pointId; |
| | | |
| | | /** |
| | | * 累计测点 |
| | | */ |
| | | private String momentPoint; |
| | | |
| | | /** |
| | | * 累计长度 |
| | | */ |
| | | private Integer length; |
| | | |
| | | /** |
| | | * 除数 |
| | | */ |
| | | private Integer divisor; |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.service; |
| | | |
| | | import com.iailab.framework.common.service.BaseService; |
| | | import com.iailab.module.data.point.dto.DaCumulatePointDTO; |
| | | import com.iailab.module.data.point.entity.DaCumulatePointEntity; |
| | | |
| | | /** |
| | | * @author PanZhibao |
| | | * @Description |
| | | * @createTime 2024年11月28日 |
| | | */ |
| | | public interface DaCumulatePointService extends BaseService<DaCumulatePointEntity> { |
| | | |
| | | void add(DaCumulatePointDTO dto, String pointId); |
| | | |
| | | DaCumulatePointDTO getByPoint(String pointId); |
| | | |
| | | void update(DaCumulatePointDTO dto); |
| | | |
| | | void deleteBatch(String[] ids); |
| | | |
| | | void deleteByPoint(String[] ids); |
| | | } |
| | |
| | | package com.iailab.module.data.point.service; |
| | | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.module.data.common.utils.PageUtils; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.entity.DaPointEntity; |
| | | import com.iailab.module.data.point.vo.*; |
| | | |
| | | import java.util.List; |
| | |
| | | |
| | | List<DaPointDTO> getMathPoint(List<String> pointNos); |
| | | |
| | | List<DaPointDTO> getCumulatePoint(String freq); |
| | | |
| | | List<DaPointDTO> getCumulatePoint(DaPointPageReqVO reqVO); |
| | | |
| | | DaPointDTO getByNo(String pointNo); |
| | | |
| | | List<DaPointDTO> getByNos(List<String> pointNos); |
对比新文件 |
| | |
| | | package com.iailab.module.data.point.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.iailab.framework.common.service.impl.BaseServiceImpl; |
| | | import com.iailab.framework.common.util.object.ConvertUtils; |
| | | import com.iailab.module.data.point.dao.DaCumulatePointDao; |
| | | import com.iailab.module.data.point.dto.DaCumulatePointDTO; |
| | | import com.iailab.module.data.point.entity.DaCumulatePointEntity; |
| | | import com.iailab.module.data.point.service.DaCumulatePointService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * @author PanZhibao |
| | | * @Description |
| | | * @createTime 2024年11月28日 |
| | | */ |
| | | @Service |
| | | public class DaCumulatePointServiceImpl extends BaseServiceImpl<DaCumulatePointDao, DaCumulatePointEntity> implements DaCumulatePointService { |
| | | |
| | | @Override |
| | | public void add(DaCumulatePointDTO dto, String pointId) { |
| | | DaCumulatePointEntity entity = ConvertUtils.sourceToTarget(dto, DaCumulatePointEntity.class); |
| | | entity.setPointId(pointId); |
| | | baseDao.insert(entity); |
| | | } |
| | | |
| | | @Override |
| | | public DaCumulatePointDTO getByPoint(String pointId) { |
| | | QueryWrapper<DaCumulatePointEntity> wrapper = new QueryWrapper<>(); |
| | | wrapper.eq("point_id", pointId); |
| | | DaCumulatePointEntity entity = baseDao.selectOne(wrapper); |
| | | return ConvertUtils.sourceToTarget(entity, DaCumulatePointDTO.class); |
| | | } |
| | | |
| | | @Override |
| | | public void update(DaCumulatePointDTO dto) { |
| | | DaCumulatePointEntity entity = ConvertUtils.sourceToTarget(dto, DaCumulatePointEntity.class); |
| | | this.updateById(entity); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteBatch(String[] ids) { |
| | | baseDao.deleteBatchIds(Arrays.asList(ids)); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteByPoint(String[] ids) { |
| | | QueryWrapper<DaCumulatePointEntity> wrapper = new QueryWrapper<>(); |
| | | wrapper.in("point_id", Arrays.asList(ids)); |
| | | baseDao.delete(wrapper); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.iailab.module.data.common.enums.IncreaseCodeEnum; |
| | | import com.iailab.module.data.point.common.PointTypeEnum; |
| | | import com.iailab.module.data.point.dao.DaPointDao; |
| | | import com.iailab.module.data.point.dto.DaCumulatePointDTO; |
| | | import com.iailab.module.data.point.dto.DaMathPointDTO; |
| | | import com.iailab.module.data.point.dto.DaMeasurePointDTO; |
| | | import com.iailab.module.data.point.dto.DaPointDTO; |
| | | import com.iailab.module.data.point.entity.DaMeasurePointEntity; |
| | | import com.iailab.module.data.point.entity.DaPointEntity; |
| | | import com.iailab.module.data.point.service.DaMathPointService; |
| | | import com.iailab.module.data.point.service.DaMeasurePointService; |
| | | import com.iailab.module.data.point.service.DaPointService; |
| | | import com.iailab.module.data.point.service.DaSequenceNumService; |
| | | import com.iailab.module.data.point.service.*; |
| | | import com.iailab.module.data.point.vo.DaPointPageReqVO; |
| | | import com.iailab.module.data.point.vo.PointImportExcelVO; |
| | | import com.iailab.module.data.point.vo.PointImportRespVO; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | |
| | | @Service |
| | | public class DaPointServiceImpl extends ServiceImpl<DaPointDao, DaPointEntity> implements DaPointService { |
| | | |
| | | @Resource |
| | | @Autowired |
| | | private DaMeasurePointService daMeasurePointService; |
| | | |
| | | @Resource |
| | | @Autowired |
| | | private DaMathPointService daMathPointService; |
| | | |
| | | @Resource |
| | | @Autowired |
| | | private DaCumulatePointService daCumulatePointService; |
| | | |
| | | @Autowired |
| | | private DaSequenceNumService daSequenceNumService; |
| | | |
| | | @Resource |
| | |
| | | public DaPointDTO info(String id) { |
| | | DaPointEntity entity = daPointDao.selectById(id); |
| | | DaPointDTO result = ConvertUtils.sourceToTarget(entity, DaPointDTO.class); |
| | | if (PointTypeEnum.MEASURE_POINT.getCode().equals(result.getPointType())) { |
| | | result.setMeasurePoint(new DaMeasurePointDTO()); |
| | | result.setMathPoint(new DaMathPointDTO()); |
| | | result.setCumulatePoint(new DaCumulatePointDTO()); |
| | | switch (PointTypeEnum.getEumByCode(result.getPointType())) { |
| | | case MEASURE_POINT: |
| | | DaMeasurePointDTO measurePoint = daMeasurePointService.getByPoint(id); |
| | | result.setMeasurePoint(measurePoint); |
| | | List<String> sourceOption = new ArrayList<>(); |
| | |
| | | sourceOption.add(measurePoint.getSourceId()); |
| | | sourceOption.add(measurePoint.getTagNo()); |
| | | result.setSourceOption(sourceOption); |
| | | } else if (PointTypeEnum.CALCULATE_POINT.getCode().equals(result.getPointType())) { |
| | | break; |
| | | case CALCULATE_POINT: |
| | | result.setMathPoint(daMathPointService.getByPoint(id)); |
| | | break; |
| | | case CUMULATE: |
| | | result.setCumulatePoint(daCumulatePointService.getByPoint(id)); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | return result; |
| | | } |
| | |
| | | case CONSTANT: |
| | | daPointEntity.setPointNo(daSequenceNumService.getAndIncreaseByCode(IncreaseCodeEnum.POINT_F.name())); |
| | | break; |
| | | case CUMULATE: |
| | | daCumulatePointService.add(dataPoint.getCumulatePoint(), daPointEntity.getId()); |
| | | daPointEntity.setPointNo(daSequenceNumService.getAndIncreaseByCode(IncreaseCodeEnum.POINT_L.name())); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | |
| | | case CALCULATE_POINT: |
| | | daMathPointService.update(dataPoint.getMathPoint()); |
| | | break; |
| | | case CUMULATE: |
| | | daCumulatePointService.update(dataPoint.getCumulatePoint()); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | |
| | | |
| | | @Override |
| | | @DSTransactional(rollbackFor = Exception.class) |
| | | public void delete(String[] id) { |
| | | daPointDao.deleteBatchIds(Arrays.asList(id)); |
| | | daMeasurePointService.deleteByPoint(id); |
| | | daMathPointService.deleteByPoint(id); |
| | | public void delete(String[] ids) { |
| | | daPointDao.deleteBatchIds(Arrays.asList(ids)); |
| | | daMeasurePointService.deleteByPoint(ids); |
| | | daMathPointService.deleteByPoint(ids); |
| | | daCumulatePointService.deleteByPoint(ids); |
| | | // 清空缓存 |
| | | clearCache(); |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<DaPointDTO> getCumulatePoint(String freq) { |
| | | Map<String, Object> params = new HashMap<>(3); |
| | | params.put("pointType", PointTypeEnum.CUMULATE.getCode()); |
| | | params.put("isEnable", CommonConstant.IS_ENABLE); |
| | | params.put("minfreqid", freq); |
| | | return daPointDao.getCumulatePoint(params); |
| | | } |
| | | |
| | | @Override |
| | | public List<DaPointDTO> getCumulatePoint(DaPointPageReqVO reqVO) { |
| | | Map<String, Object> params = new HashMap<>(3); |
| | | params.put("pointType", PointTypeEnum.CUMULATE.getCode()); |
| | | params.put("pointNo", reqVO.getPointNo()); |
| | | params.put("pointName", reqVO.getPointName()); |
| | | return daPointDao.getCumulatePoint(params); |
| | | } |
| | | |
| | | @Override |
| | | public DaPointDTO getByNo(String pointNo) { |
| | | if (pointNoMap.containsKey(pointNo)) { |
| | | return pointNoMap.get(pointNo); |
| | |
| | | case CONSTANT: |
| | | daPointEntity.setPointNo(daSequenceNumService.getAndIncreaseByCode(IncreaseCodeEnum.POINT_F.name())); |
| | | break; |
| | | case CUMULATE: |
| | | DaCumulatePointDTO cumulatePoint = new DaCumulatePointDTO(); |
| | | cumulatePoint.setMomentPoint(importPoint.getMomentPoint()); |
| | | cumulatePoint.setLength(importPoint.getLength()); |
| | | cumulatePoint.setDivisor(importPoint.getDivisor()); |
| | | daCumulatePointService.add(cumulatePoint, daPointEntity.getId()); |
| | | daPointEntity.setPointNo(daSequenceNumService.getAndIncreaseByCode(IncreaseCodeEnum.POINT_L.name())); |
| | | default: |
| | | break; |
| | | } |
| | |
| | | measurePoint.setSourceId(sourcesIdMap.get(importPoint.getSourceType()).get(importPoint.getSourceName())); |
| | | measurePoint.setTagNo(importPoint.getTagNo()); |
| | | daMeasurePointService.update(measurePoint, new QueryWrapper<DaMeasurePointEntity>().eq("point_id",updatePoint.getId())); |
| | | |
| | | |
| | | |
| | | respVO.getUpdatePointnames().add(importPoint.getPointName()); |
| | | }); |
| | | return respVO; |
| | |
| | | @Schema(description = "计算公式") |
| | | @ExcelProperty("计算公式") |
| | | private String expression; |
| | | |
| | | @Schema(description = "瞬时测点") |
| | | @ExcelProperty("瞬时测点") |
| | | private String momentPoint; |
| | | |
| | | @Schema(description = "累计长度") |
| | | @ExcelProperty("累计长度") |
| | | private Integer length; |
| | | |
| | | @Schema(description = "除数") |
| | | @ExcelProperty("除数") |
| | | private Integer divisor; |
| | | } |
| | |
| | | @ExcelProperty("计算公式") |
| | | private String expression; |
| | | |
| | | @ExcelProperty("瞬时测点") |
| | | private String momentPoint; |
| | | |
| | | @ExcelProperty("累计长度") |
| | | private Integer length; |
| | | |
| | | @ExcelProperty("除数") |
| | | private Integer divisor; |
| | | |
| | | } |
| | |
| | | |
| | | influx-db: |
| | | org: IAILab |
| | | bucket: whs_data |
| | | token: gxhXM4H1VOBv07kYXKWyPag_zJ8_oChP4ooZ3u-BkSae9LS8R1wWzJYlmUjL3Qe9t1hDU3DtoYD5HTgjWoTGOg== |
| | | url: http://localhost:8086 |
| | | token: 50m9Kl-7_tvJY9kejwgSwxQpVG258EKKRt4qZeDntRnWetHGpkBhYtOOXrd9gmh85cuikKFZMzkTsw9pm1xlcA== |
| | | url: http://127.0.0.1:8086 |
| | | username: root |
| | | password: root123456 |
| | | |
| | | iems: |
| | | upload-dir: D:/DLUT/upload/ |
| | |
| | | - t_plan_data_set |
| | | - t_plan_item_category |
| | | - t_plan_item |
| | | - t_da_cumulate_point |
| | | app: |
| | | app-key: data |
| | | app-secret: 85b0df7edc3df3611913df34ed695011 |
| | |
| | | </where> |
| | | </select> |
| | | |
| | | <select id="getCumulatePoint" resultType="com.iailab.module.data.point.dto.DaPointDTO"> |
| | | SELECT |
| | | t1.point_no, |
| | | t1.point_name, |
| | | t1.default_value, |
| | | t1.point_type, |
| | | t1.data_type, |
| | | t1.store_type, |
| | | t1.minfreqid, |
| | | t2.moment_point, |
| | | t2.length, |
| | | t2.divisor |
| | | FROM t_da_point t1 |
| | | LEFT JOIN t_da_cumulate_point t2 ON t2.point_id = t1.id |
| | | <where> |
| | | t1.point_type = #{pointType} |
| | | <if test="isEnable != null"> |
| | | AND t1.is_enable = #{isEnable} |
| | | </if> |
| | | <if test="minfreqid != null and minfreqid != ''"> |
| | | AND t1.minfreqid = #{minfreqid} |
| | | </if> |
| | | </where> |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | </dependency> |
| | | |
| | | <!-- Job 定时任务相关 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common-job</artifactId> |
| | | </dependency> |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>com.iailab</groupId>--> |
| | | <!-- <artifactId>iailab-common-job</artifactId>--> |
| | | <!-- </dependency>--> |
| | | |
| | | <!-- 消息队列相关 --> |
| | | <!-- <dependency>--> |
| | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * Infra 模块的 Security 配置 |
| | |
| | | return new AuthorizeRequestsCustomizer() { |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | // Swagger 接口文档 |
| | | registry.antMatchers("/v3/api-docs/**").permitAll() |
| | | .antMatchers("/webjars/**").permitAll() |
| | | .antMatchers("/swagger-ui").permitAll() |
| | | .antMatchers("/swagger-ui/**").permitAll(); |
| | | registry.requestMatchers("/v3/api-docs/**").permitAll() |
| | | .requestMatchers("/webjars/**").permitAll() |
| | | .requestMatchers("/swagger-ui").permitAll() |
| | | .requestMatchers("/swagger-ui/**").permitAll(); |
| | | // Spring Boot Actuator 的安全配置 |
| | | registry.antMatchers("/actuator").anonymous() |
| | | .antMatchers("/actuator/**").anonymous(); |
| | | registry.requestMatchers("/actuator").permitAll() |
| | | .requestMatchers("/actuator/**").permitAll(); |
| | | // Druid 监控 |
| | | registry.antMatchers("/druid/**").anonymous(); |
| | | registry.requestMatchers("/druid/**").permitAll(); |
| | | // Spring Boot Admin Server 的安全配置 |
| | | registry.antMatchers(adminSeverContextPath).anonymous() |
| | | .antMatchers(adminSeverContextPath + "/**").anonymous(); |
| | | registry.requestMatchers(adminSeverContextPath).permitAll() |
| | | .requestMatchers(adminSeverContextPath + "/**").permitAll(); |
| | | // 文件读取 |
| | | registry.antMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll(); |
| | | registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll(); |
| | | |
| | | // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案 |
| | | // RPC 服务的安全配置 |
| | | registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | } |
| | | |
| | | }; |
| | |
| | | package com.iailab.module.infra.job.demo; |
| | | |
| | | import com.iailab.framework.tenant.core.job.TenantJob; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | @Component |
| | | public class DemoJob { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(getClass()); |
| | | |
| | | private final AtomicInteger counts = new AtomicInteger(); |
| | | |
| | | private static final Object lock = new Object(); |
| | | |
| | | |
| | | @XxlJob("demoJob") |
| | | // @TenantJob |
| | | public void execute() { |
| | | synchronized (lock) { |
| | | logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); |
| | | System.out.println(new Date() + ": 我是基础设施定时任务"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | //package com.iailab.module.infra.job.demo; |
| | | // |
| | | //import com.iailab.framework.tenant.core.job.TenantJob; |
| | | //import com.xxl.job.core.handler.annotation.XxlJob; |
| | | //import org.slf4j.Logger; |
| | | //import org.slf4j.LoggerFactory; |
| | | //import org.springframework.stereotype.Component; |
| | | // |
| | | //import java.util.Date; |
| | | //import java.util.concurrent.atomic.AtomicInteger; |
| | | // |
| | | //@Component |
| | | //public class DemoJob { |
| | | // |
| | | // private Logger logger = LoggerFactory.getLogger(getClass()); |
| | | // |
| | | // private final AtomicInteger counts = new AtomicInteger(); |
| | | // |
| | | // private static final Object lock = new Object(); |
| | | // |
| | | // |
| | | // @XxlJob("demoJob") |
| | | //// @TenantJob |
| | | // public void execute() { |
| | | // synchronized (lock) { |
| | | // logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); |
| | | // System.out.println(new Date() + ": 我是基础设施定时任务"); |
| | | // } |
| | | // } |
| | | // |
| | | //} |
| | |
| | | package com.iailab.module.infra.job.logger; |
| | | |
| | | import com.iailab.framework.tenant.core.aop.TenantIgnore; |
| | | import com.iailab.module.infra.service.logger.ApiAccessLogService; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * 物理删除 N 天前的访问日志的 Job |
| | | * |
| | | * @author j-sentinel |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class AccessLogCleanJob { |
| | | |
| | | @Resource |
| | | private ApiAccessLogService apiAccessLogService; |
| | | |
| | | /** |
| | | * 清理超过(14)天的日志 |
| | | */ |
| | | private static final Integer JOB_CLEAN_RETAIN_DAY = 14; |
| | | |
| | | /** |
| | | * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大 |
| | | */ |
| | | private static final Integer DELETE_LIMIT = 100; |
| | | |
| | | @XxlJob("accessLogCleanJob") |
| | | @TenantIgnore |
| | | public void execute() { |
| | | Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); |
| | | log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count); |
| | | } |
| | | |
| | | } |
| | | //package com.iailab.module.infra.job.logger; |
| | | // |
| | | //import com.iailab.framework.tenant.core.aop.TenantIgnore; |
| | | //import com.iailab.module.infra.service.logger.ApiAccessLogService; |
| | | //import com.xxl.job.core.handler.annotation.XxlJob; |
| | | //import lombok.extern.slf4j.Slf4j; |
| | | //import org.springframework.stereotype.Component; |
| | | // |
| | | //import javax.annotation.Resource; |
| | | // |
| | | ///** |
| | | // * 物理删除 N 天前的访问日志的 Job |
| | | // * |
| | | // * @author j-sentinel |
| | | // */ |
| | | //@Component |
| | | //@Slf4j |
| | | //public class AccessLogCleanJob { |
| | | // |
| | | // @Resource |
| | | // private ApiAccessLogService apiAccessLogService; |
| | | // |
| | | // /** |
| | | // * 清理超过(14)天的日志 |
| | | // */ |
| | | // private static final Integer JOB_CLEAN_RETAIN_DAY = 14; |
| | | // |
| | | // /** |
| | | // * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大 |
| | | // */ |
| | | // private static final Integer DELETE_LIMIT = 100; |
| | | // |
| | | // @XxlJob("accessLogCleanJob") |
| | | // @TenantIgnore |
| | | // public void execute() { |
| | | // Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); |
| | | // log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count); |
| | | // } |
| | | // |
| | | //} |
| | |
| | | package com.iailab.module.infra.job.logger; |
| | | |
| | | import com.iailab.framework.tenant.core.aop.TenantIgnore; |
| | | import com.iailab.module.infra.service.logger.ApiErrorLogService; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * 物理删除 N 天前的错误日志的 Job |
| | | * |
| | | * @author j-sentinel |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class ErrorLogCleanJob { |
| | | |
| | | @Resource |
| | | private ApiErrorLogService apiErrorLogService; |
| | | |
| | | /** |
| | | * 清理超过(14)天的日志 |
| | | */ |
| | | private static final Integer JOB_CLEAN_RETAIN_DAY = 14; |
| | | |
| | | /** |
| | | * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大 |
| | | */ |
| | | private static final Integer DELETE_LIMIT = 100; |
| | | |
| | | @XxlJob("errorLogCleanJob") |
| | | @TenantIgnore |
| | | public void execute() { |
| | | Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT); |
| | | log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count); |
| | | } |
| | | |
| | | } |
| | | //package com.iailab.module.infra.job.logger; |
| | | // |
| | | //import com.iailab.framework.tenant.core.aop.TenantIgnore; |
| | | //import com.iailab.module.infra.service.logger.ApiErrorLogService; |
| | | //import com.xxl.job.core.handler.annotation.XxlJob; |
| | | //import lombok.extern.slf4j.Slf4j; |
| | | //import org.springframework.stereotype.Component; |
| | | // |
| | | //import javax.annotation.Resource; |
| | | // |
| | | ///** |
| | | // * 物理删除 N 天前的错误日志的 Job |
| | | // * |
| | | // * @author j-sentinel |
| | | // */ |
| | | //@Slf4j |
| | | //@Component |
| | | //public class ErrorLogCleanJob { |
| | | // |
| | | // @Resource |
| | | // private ApiErrorLogService apiErrorLogService; |
| | | // |
| | | // /** |
| | | // * 清理超过(14)天的日志 |
| | | // */ |
| | | // private static final Integer JOB_CLEAN_RETAIN_DAY = 14; |
| | | // |
| | | // /** |
| | | // * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大 |
| | | // */ |
| | | // private static final Integer DELETE_LIMIT = 100; |
| | | // |
| | | // @XxlJob("errorLogCleanJob") |
| | | // @TenantIgnore |
| | | // public void execute() { |
| | | // Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT); |
| | | // log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count); |
| | | // } |
| | | // |
| | | //} |
| | |
| | | @Schema(description = "调度方案时间") |
| | | @NotNull(message="调度方案时间不能为空") |
| | | private Date scheduleTime; |
| | | |
| | | private String modelCode; |
| | | |
| | | private Map<String, Object> params; |
| | | } |
| | |
| | | ( |
| | | id varchar(36) not null, |
| | | itemid varchar(36), |
| | | expression varchar(255), |
| | | expression varchar(1000), |
| | | num integer, |
| | | primary key (id), |
| | | UNIQUE INDEX uk_itemid (itemid) |
| | |
| | | |
| | | |
| | | alter table t_mm_item_output add column `result_name` varchar(50) DEFAULT NULL; |
| | | |
| | | |
| | | alter table t_st_schedule_scheme add column `mpkprojectid` varchar(36) DEFAULT NULL; |
| | |
| | | resp.setScheduleTime(reqDTO.getScheduleTime()); |
| | | try { |
| | | log.info("调度计算开始: " + System.currentTimeMillis()); |
| | | ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getModelCode(), reqDTO.getScheduleTime()); |
| | | ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getScheduleCode(), reqDTO.getScheduleTime()); |
| | | resp.setResult(scheduleResult.getResult()); |
| | | log.info("预测计算结束: " + System.currentTimeMillis()); |
| | | } catch (Exception ex) { |
| | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * System 模块的 Security 配置 |
| | |
| | | return new AuthorizeRequestsCustomizer() { |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案 |
| | | // Swagger 接口文档 |
| | | registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | registry.requestMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .requestMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | // Druid 监控 |
| | | registry.antMatchers("/druid/**").anonymous(); |
| | | registry.requestMatchers("/druid/**").anonymous(); |
| | | // Spring Boot Actuator 的安全配置 |
| | | registry.antMatchers("/actuator").anonymous() |
| | | .antMatchers("/actuator/**").anonymous(); |
| | | registry.requestMatchers("/actuator").anonymous() |
| | | .requestMatchers("/actuator/**").anonymous(); |
| | | |
| | | registry.antMatchers("/admin-api/model/pre/item/upload-model").anonymous(); |
| | | registry.requestMatchers("/admin-api/model/pre/item/upload-model").anonymous(); |
| | | // RPC 服务的安全配置 |
| | | registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | } |
| | | |
| | | }; |
| | |
| | | * 备注 |
| | | */ |
| | | private String remark; |
| | | |
| | | /** |
| | | * 项目ID |
| | | */ |
| | | private String mpkprojectid; |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void update(StScheduleSchemeSaveReqVO createReqVO) { |
| | | StScheduleSchemeEntity entity = BeanUtils.toBean(createReqVO, StScheduleSchemeEntity.class); |
| | | public void update(StScheduleSchemeSaveReqVO updateReqVO) { |
| | | StScheduleSchemeEntity entity = BeanUtils.toBean(updateReqVO, StScheduleSchemeEntity.class); |
| | | baseDao.updateById(entity); |
| | | } |
| | | |
| | |
| | | @Schema(description = "状态(0正常 1停用)", example = "0") |
| | | private Integer status; |
| | | |
| | | |
| | | @Schema(description = "项目ID") |
| | | private String mpkprojectid; |
| | | } |
| | |
| | | public class StScheduleSchemeSaveReqVO { |
| | | |
| | | @Schema(description = "ID") |
| | | private Long id; |
| | | private String id; |
| | | |
| | | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "编号不能为空") |
| | |
| | | |
| | | @Schema(description = "备注") |
| | | private String remark; |
| | | |
| | | @Schema(description = "项目ID") |
| | | private String mpkprojectid; |
| | | } |
| | |
| | | import com.iailab.module.data.api.point.dto.ApiPointDTO; |
| | | import com.iailab.module.data.enums.DataPointFreqEnum; |
| | | import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity; |
| | | import com.iailab.module.model.mcs.pre.service.MmItemOutputService; |
| | | import com.iailab.module.model.mcs.pre.service.MmItemResultService; |
| | | import com.iailab.module.model.mdk.common.enums.ItemPredictStatus; |
| | | import com.iailab.module.model.mdk.common.exceptions.ItemInvokeException; |
| | | import com.iailab.module.model.mdk.factory.ItemEntityFactory; |
| | |
| | | @Autowired |
| | | private PredictResultHandler predictResultHandler; |
| | | |
| | | @Autowired |
| | | private MmItemResultService mmItemResultService; |
| | | |
| | | @Autowired |
| | | private MmItemOutputService mmItemOutputService; |
| | | |
| | | /** |
| | | * MergeItem预测 |
| | | * |
| | |
| | | int predictLength = itemEntityFactory.getItemById(itemId).getPredictLength(); |
| | | double[][] predictResultMat = new double[predictLength][1]; |
| | | Map<String, List<DataValueVO>> predictValueMap = new HashMap<>(); |
| | | String[] mathItem = expression.split("[\\+ \\-]"); |
| | | String[] mathOutPutId = expression.split("[\\+ \\-]"); |
| | | ArrayList<Character> operator = new ArrayList<>(); |
| | | for (int i = 0; i < expression.length(); i++) { |
| | | if (expression.charAt(i)=='+' || expression.charAt(i)=='-'){ |
| | |
| | | } |
| | | String[] compositionItem = expression.split(String.valueOf("&".toCharArray())); |
| | | //是否为计算预测项 |
| | | if (mathItem.length > 1) { |
| | | for (String itemNo : mathItem) { |
| | | if (itemNo.length() > 4) { |
| | | if (mathOutPutId.length > 1) { |
| | | for (String outPutId : mathOutPutId) { |
| | | if (outPutId.length() > 4) { |
| | | Date endTime = predictTime; |
| | | ItemVO itemEntity = itemEntityFactory.getItemByItemNo(itemNo); |
| | | List<MmItemOutputEntity> outPutList = itemEntityFactory.getOutPutByItemId(itemEntity.getId()); |
| | | ApiPointDTO pointEntity = dataPointApi.getInfoById(outPutList.get(0).getPointid()); |
| | | // ItemVO itemEntity = itemEntityFactory.getItemByItemNo(itemNo); |
| | | // List<MmItemOutputEntity> outPutList = itemEntityFactory.getOutPutByItemId(itemEntity.getId()); |
| | | MmItemOutputEntity outPut = mmItemOutputService.getOutPutById(outPutId); |
| | | ApiPointDTO pointEntity = dataPointApi.getInfoById(outPut.getPointid()); |
| | | |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(endTime); |
| | | calendar.add(Calendar.SECOND, (predictLength - 1) * DataPointFreqEnum.getEumByCode(pointEntity.getMinfreqid()).getValue()); |
| | | endTime = new Timestamp(calendar.getTime().getTime()); |
| | | List<DataValueVO> predictValueList = predictResultHandler.getPredictValueByItemNo(itemNo, predictTime, endTime); |
| | | // List<DataValueVO> predictValueList = predictResultHandler.getPredictValueByItemNo(itemNo, predictTime, endTime); |
| | | List<DataValueVO> predictValueList = mmItemResultService.getPredictValue(outPutId, predictTime, endTime); |
| | | if (predictValueList.size() != predictLength) { |
| | | log.debug("merge项融合失败:缺少子项预测数据,对应子项ItemNo=" + itemNo); |
| | | log.debug("merge项融合失败:缺少子项预测数据,对应子项outPutId=" + outPutId); |
| | | return null; |
| | | } |
| | | predictValueMap.put(itemNo, predictValueList); |
| | | predictValueMap.put(outPutId, predictValueList); |
| | | } |
| | | } |
| | | for (Integer i = 0; i < predictLength; i++) { |
| | | double sum =0.0; |
| | | sum = predictValueMap.get(mathItem[0]).get(i).getDataValue(); |
| | | for (int j = 1; j < mathItem.length; j++) { |
| | | sum = predictValueMap.get(mathOutPutId[0]).get(i).getDataValue(); |
| | | for (int j = 1; j < mathOutPutId.length; j++) { |
| | | if (operator.get(j-1)=='+') |
| | | {sum += predictValueMap.get(mathItem[j]).get(i).getDataValue();} |
| | | {sum += predictValueMap.get(mathOutPutId[j]).get(i).getDataValue();} |
| | | if (operator.get(j-1)=='-') |
| | | {sum -= predictValueMap.get(mathItem[j]).get(i).getDataValue();} |
| | | {sum -= predictValueMap.get(mathOutPutId[j]).get(i).getDataValue();} |
| | | } |
| | | predictResultMat[i][0] = sum; |
| | | } |
| | |
| | | } |
| | | modelResult = (HashMap<String, Object>) modelResult.get(CommonConstant.MDK_RESULT); |
| | | //打印结果 |
| | | log.info("模型计算完成:modelId=" + modelId + modelResult); |
| | | log.info("预测模型计算完成:modelId=" + modelId + modelResult); |
| | | JSONObject jsonObjResult = new JSONObject(); |
| | | jsonObjResult.put("result", modelResult); |
| | | log.info(String.valueOf(jsonObjResult)); |
| | |
| | | lastItem = item; |
| | | |
| | | DataValueVO dataEntity = new DataValueVO(); |
| | | dataEntity.setDataTime(new Timestamp(item.getKey())); |
| | | dataEntity.setDataTime(new Date(item.getKey())); |
| | | dataEntity.setDataValue(item.getValue()); |
| | | completionDataEntityList.add(dataEntity); |
| | | } |
| | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.iail.IAILMDK; |
| | | import com.iail.model.IAILModel; |
| | | import com.iailab.module.model.common.enums.CommonConstant; |
| | | import com.iailab.module.model.mcs.sche.entity.StScheduleModelEntity; |
| | | import com.iailab.module.model.mcs.sche.entity.StScheduleModelSettingEntity; |
| | | import com.iailab.module.model.mcs.sche.entity.StScheduleSchemeEntity; |
| | |
| | | import com.iailab.module.model.mdk.sample.dto.SampleData; |
| | | import com.iailab.module.model.mdk.schedule.ScheduleModelHandler; |
| | | import com.iailab.module.model.mdk.vo.ScheduleResultVO; |
| | | import com.iailab.module.model.mpk.common.utils.DllUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | param2Values[count] = settings_predict; |
| | | |
| | | //打印参数 |
| | | log.info("##############调度模型:modelId=" + modelId + " ##########################"); |
| | | log.info("##############调度模型:scheduleScheme=" + scheduleScheme.getCode() + " ##########################"); |
| | | JSONObject jsonObjNewModelBean = new JSONObject(); |
| | | jsonObjNewModelBean.put("newModelBean", newModelBean); |
| | | log.info(String.valueOf(jsonObjNewModelBean)); |
| | |
| | | jsonObjParam2Values.put("param2Values", param2Values); |
| | | log.info(String.valueOf(jsonObjParam2Values)); |
| | | |
| | | //IAILMDK.run |
| | | HashMap<String, Object> result = IAILMDK.run(newModelBean, param2Values); |
| | | //运行模型 |
| | | HashMap<String, Object> modelResult = DllUtils.run(newModelBean, param2Values, scheduleScheme.getMpkprojectid()); |
| | | if (!modelResult.containsKey(CommonConstant.MDK_STATUS_CODE) || !modelResult.containsKey(CommonConstant.MDK_RESULT) || |
| | | !modelResult.get(CommonConstant.MDK_STATUS_CODE).toString().equals(CommonConstant.MDK_STATUS_100)) { |
| | | throw new RuntimeException("模型结果异常:" + modelResult); |
| | | } |
| | | modelResult = (HashMap<String, Object>) modelResult.get(CommonConstant.MDK_RESULT); |
| | | |
| | | //打印结果 |
| | | JSONObject jsonObjResult = new JSONObject(); |
| | | jsonObjResult.put("result", result); |
| | | jsonObjResult.put("result", modelResult); |
| | | log.info(String.valueOf(jsonObjResult)); |
| | | log.info("调度模型计算完成:modelId=" + modelId + result); |
| | | |
| | | //5.返回调度结果 |
| | | scheduleResult.setResult(result); |
| | | scheduleResult.setResult(modelResult); |
| | | scheduleResult.setModelId(modelId); |
| | | scheduleResult.setSchemeId(scheduleScheme.getId()); |
| | | scheduleResult.setScheduleTime(scheduleTime); |
| | |
| | | <result property="itemname" column="ITEMNAME"/> |
| | | <result property="itemtypeid" column="ITEMTYPEID"/> |
| | | <result property="itemtypename" column="ITEMTYPENAME"/> |
| | | <result property="predictlength" column="predictlength"/> |
| | | <result property="granularity" column="GRANULARITY"/> |
| | | <result property="isfuse" column="ISFUSE"/> |
| | | <result property="workchecked" column="WORKCHECKED"/> |
| | |
| | | TMPI.ITEMNAME, |
| | | TMPI.ITEMTYPEID, |
| | | TMIT.ITEMTYPENAME, |
| | | TMPI.predictlength, |
| | | TMPI.GRANULARITY, |
| | | TMPI.ISFUSE, |
| | | TMPI.WORKCHECKED, |
| | |
| | | <groupId>org.jeecgframework.jimureport</groupId> |
| | | <artifactId>jimureport-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | <!-- 积木仪表盘--> |
| | | <dependency> |
| | | <groupId>org.jeecgframework.jimureport</groupId> |
| | | <artifactId>jimureport-dashboard-spring-boot-starter</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>autopoi-web</artifactId> |
| | | <groupId>org.jeecgframework</groupId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>org.jeecgframework.jimureport</groupId> |
| | | <artifactId>jimureport-spring-boot-starter</artifactId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>com.github.jsqlparser</groupId> |
| | | <artifactId>jsqlparser</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <!-- 单独依赖升级版本,解决低版本validator失败问题 --> |
| | | <dependency> |
| | | <groupId>xerces</groupId> |
| | |
| | | /** |
| | | * 项目的启动类 |
| | | * |
| | | * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @SpringBootApplication |
| | | public class ReportServerApplication { |
| | | |
| | | public static void main(String[] args) { |
| | | // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | |
| | | SpringApplication.run(ReportServerApplication.class, args); |
| | | |
| | | // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章 |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | @Override |
| | | public String[] getRoles(String token) { |
| | | // 设置租户上下文。原因是:/jmreport/** 纯前端地址,不会走 buildLoginUserByToken 逻辑 |
| | | LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); |
| | | if (loginUser == null) { |
| | | return null; |
| | | } |
| | | TenantContextHolder.setTenantId(loginUser.getTenantId()); |
| | | |
| | | // 参见文档 https://help.jeecg.com/jimureport/prodSafe.html 文档 |
| | | // 适配:如果是本系统的管理员,则转换成 jimu 报表的管理员 |
| | | Long userId = SecurityFrameworkUtils.getLoginUserId(); |
| | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * Report 模块的 Security 配置 |
| | |
| | | return new AuthorizeRequestsCustomizer() { |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | // Swagger 接口文档 |
| | | registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | registry.requestMatchers("/v3/api-docs/**").permitAll() |
| | | .requestMatchers("/webjars/**").permitAll() |
| | | .requestMatchers("/swagger-ui").permitAll() |
| | | .requestMatchers("/swagger-ui/**").permitAll(); |
| | | // Spring Boot Actuator 的安全配置 |
| | | registry.antMatchers("/actuator").anonymous() |
| | | .antMatchers("/actuator/**").anonymous(); |
| | | registry.requestMatchers("/actuator").permitAll() |
| | | .requestMatchers("/actuator/**").permitAll(); |
| | | // Druid 监控 |
| | | registry.antMatchers("/druid/**").anonymous(); |
| | | registry.requestMatchers("/druid/**").permitAll(); |
| | | // 积木报表 |
| | | registry.antMatchers("/jmreport/**").permitAll(); |
| | | registry.requestMatchers("/jmreport/**").permitAll(); |
| | | // 积木仪表盘排除 |
| | | registry.requestMatchers("/drag/**").permitAll(); |
| | | } |
| | | |
| | | }; |
| | | } |
| | | |
| | | } |
| | |
| | | primary: master |
| | | datasource: |
| | | master: |
| | | url: jdbc:mysql://127.0.0.1:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| | | url: jdbc:mysql://172.16.8.100:3306/iailab_jmreport?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| | | username: root |
| | | password: 123456 |
| | | slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改 |
| | | lazy: true # 开启懒加载,保证启动速度 |
| | | url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| | | url: jdbc:mysql://127.0.0.1:3306/jimureport?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| | | username: root |
| | | password: 123456 |
| | | |
| | |
| | | port: 6379 # 端口 |
| | | database: 1 # 数据库索引 |
| | | password: 123456 # 密码,建议生产环境开启 |
| | | |
| | | --- #################### MQ 消息队列相关配置 #################### |
| | | |
| | | --- #################### 定时任务相关配置 #################### |
| | | |
| | | --- #################### 服务保障相关配置 #################### |
| | | |
| | | # Lock4j 配置项 |
| | | lock4j: |
| | |
| | | |
| | | # 平台配置项,设置当前项目所有自定义的配置 |
| | | iailab: |
| | | xss: |
| | | enable: false |
| | | exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 |
| | | - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 |
| | | - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 |
| | | demo: true # 开启演示模式 |
| | | demo: false # 开启演示模式 |
| | |
| | | multipart: |
| | | max-file-size: 16MB # 单个文件大小 |
| | | max-request-size: 32MB # 设置总上传的文件大小 |
| | | mvc: |
| | | pathmatch: |
| | | matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类 |
| | | |
| | | # Jackson 配置项 |
| | | jackson: |
| | |
| | | path: /v3/api-docs |
| | | swagger-ui: |
| | | enabled: true # 2.1 是否开启 Swagger 文档的官方 UI 界面 |
| | | path: /swagger-ui.html |
| | | path: /swagger-ui |
| | | default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档 |
| | | |
| | | knife4j: |
| | |
| | | # VO 转换(数据翻译)相关 |
| | | easy-trans: |
| | | is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口 |
| | | is-enable-cloud: false # 禁用 TransType.RPC 微服务模式 |
| | | |
| | | --- #################### RPC 远程调用相关配置 #################### |
| | | |
| | | --- #################### MQ 消息队列相关配置 #################### |
| | | |
| | | --- #################### 定时任务相关配置 #################### |
| | | |
| | | # 积木报表配置 |
| | | jeecg: |
| | | jmreport: |
| | | saas-mode: tenant |
| | | |
| | | --- #################### 平台相关配置 #################### |
| | | |
| | |
| | | description: 提供管理员管理的所有功能 |
| | | version: ${iailab.info.version} |
| | | tenant: # 多租户相关配置项 |
| | | enable: false |
| | | enable: true |
| | | |
| | | debug: false |
| | | jeecg: |
| | | uploadType: local |
| | | path: |
| | | upload: D:/DLUT/IailabPlat |
| | | #大屏报表参数设置 |
| | | jmreport: |
| | | #多租户模式,默认值为空(created:按照创建人隔离、tenant:按照租户隔离) (v1.6.2+ 新增) |
| | | saasMode: tenant |
| | | # 平台上线安全配置(v1.6.2+ 新增) |
| | | firewall: |
| | | # 数据源安全 (开启后,不允许使用平台数据源、SQL解析加签并且不允许查询数据库) |
| | | dataSourceSafe: false |
| | | # 低代码开发模式(dev:开发模式,prod:发布模式—关闭在线报表设计功能,分配角色admin、lowdeveloper可以放开限制) |
| | | lowCodeMode: dev |
| | | |
| | | minidao : |
| | | base-package: org.jeecg.modules.jmreport.desreport.dao*, org.jeecg.modules.drag.dao* |
| | | |
| | | debug: true |
| | |
| | | Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId)); |
| | | List<MenuDO> menuList = menuService.getMenuList(menuIds); |
| | | menuList = menuService.filterDisableMenus(menuList); |
| | | menuList = menuService.filterMenus(menuList, "system"); |
| | | |
| | | // 2. 拼接结果返回 |
| | | return success(AuthConvert.INSTANCE.convert(user, roles, menuList)); |
| | |
| | | * |
| | | * 注意,默认需要传递 client_id + client_secret 参数 |
| | | */ |
| | | @PostMapping("/fast/token") |
| | | @PermitAll |
| | | @Operation(summary = "脚手架获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") |
| | | @Parameters({ |
| | | @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"), |
| | | @Parameter(name = "code", description = "授权范围", example = "userinfo.read"), |
| | | @Parameter(name = "redirect_uri", description = "重定向 URI", example = "https://www.iocoder.cn"), |
| | | @Parameter(name = "state", description = "状态", example = "1"), |
| | | @Parameter(name = "username", example = "tudou"), |
| | | @Parameter(name = "password", example = "cai"), // 多个使用空格分隔 |
| | | @Parameter(name = "scope", example = "user_info"), |
| | | @Parameter(name = "refresh_token", example = "123424233"), |
| | | }) |
| | | public CommonResult<OAuth2OpenAccessTokenRespVO> FastAccessToken(HttpServletRequest request, |
| | | @RequestParam("grant_type") String grantType, |
| | | @RequestParam(value = "code", required = false) String code, // 授权码模式 |
| | | @RequestParam(value = "redirect_uri", required = false) String redirectUri, // 授权码模式 |
| | | @RequestParam(value = "state", required = false) String state, // 授权码模式 |
| | | @RequestParam(value = "username", required = false) String username, // 密码模式 |
| | | @RequestParam(value = "password", required = false) String password, // 密码模式 |
| | | @RequestParam(value = "scope", required = false) String scope, // 密码模式 |
| | | @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式 |
| | | OAuth2AccessTokenDO accessTokenDO = getAccessToken(request, grantType, code, redirectUri, state, username, password, scope, refreshToken); |
| | | Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 |
| | | return success(OAuth2OpenConvert.INSTANCE.convert(accessTokenDO)); |
| | | } |
| | | |
| | | /** |
| | | * 对应 Spring Security OAuth 的 TokenEndpoint 类的 postAccessToken 方法 |
| | | * |
| | | * 外部平台专用授权方式 |
| | | * |
| | | * 注意,默认需要传递 client_id + client_secret 参数 |
| | | */ |
| | | @PostMapping("/token") |
| | | @PermitAll |
| | | @Operation(summary = "获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") |
| | | @Operation(summary = "外部平台获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") |
| | | @Parameters({ |
| | | @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"), |
| | | @Parameter(name = "code", description = "授权码", example = "asdfasdfasdf"), |
| | |
| | | @RequestParam(value = "password", required = false) String password, // 密码模式 |
| | | @RequestParam(value = "scope", required = false) String scope, // 密码模式 |
| | | @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式 |
| | | OAuth2AccessTokenDO accessTokenDO = getAccessToken(request, grantType, code, redirectUri, state, username, password, scope, refreshToken); |
| | | Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("access_token", accessTokenDO.getAccessToken()); |
| | | map.put("refresh_token", accessTokenDO.getRefreshToken()); |
| | | map.put("expires_time", LocalDateTimeUtil.toEpochMilli(accessTokenDO.getExpiresTime()) / 1000L); |
| | | map.put("client_id", accessTokenDO.getClientId()); |
| | | return map; |
| | | } |
| | | |
| | | private OAuth2AccessTokenDO getAccessToken(HttpServletRequest request, String grantType, String code, String redirectUri, String state, String username, String password, String scope, String refreshToken) { |
| | | List<String> scopes = OAuth2Utils.buildScopes(scope); |
| | | // 1.1 校验授权类型 |
| | | OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGrantType(grantType); |
| | |
| | | throw new IllegalArgumentException("未知授权类型:" + grantType); |
| | | } |
| | | Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("access_token", accessTokenDO.getAccessToken()); |
| | | map.put("refresh_token", accessTokenDO.getRefreshToken()); |
| | | map.put("expires_time", LocalDateTimeUtil.toEpochMilli(accessTokenDO.getExpiresTime()) / 1000L); |
| | | map.put("client_id", accessTokenDO.getClientId()); |
| | | return map; |
| | | return accessTokenDO; |
| | | } |
| | | |
| | | @DeleteMapping("/token") |
| | |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | |
| | | @Schema(description = "状态", example = "1") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "套餐图标", example = "http://localhost/xxx") |
| | | private String icon; |
| | | |
| | | @Schema(description = "套餐标签", example = "模型管理") |
| | | private List<String> labels; |
| | | |
| | | @Schema(description = "描述", example = "好") |
| | | private String description; |
| | | |
| | | @Schema(description = "备注", example = "好") |
| | | private String remark; |
| | | |
| | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotEmpty; |
| | | import javax.validation.constraints.NotNull; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | @Schema(description = "管理后台 - 租户套餐 Response VO") |
| | |
| | | @Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP") |
| | | private String name; |
| | | |
| | | @Schema(description = "套餐图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://localhost/xxx") |
| | | private String icon; |
| | | |
| | | @Schema(description = "套餐标签", example = "模型管理") |
| | | private List<String> labels; |
| | | |
| | | @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "好") |
| | | private String description; |
| | | |
| | | @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Integer status; |
| | | |
| | |
| | | |
| | | import javax.validation.constraints.NotEmpty; |
| | | import javax.validation.constraints.NotNull; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | @Schema(description = "管理后台 - 租户套餐创建/修改 Request VO") |
| | |
| | | @NotEmpty(message = "套餐名不能为空") |
| | | private String name; |
| | | |
| | | @Schema(description = "套餐图标", example = "http://localhost/xxx") |
| | | @NotEmpty(message = "套餐图标不能为空") |
| | | private String icon; |
| | | |
| | | @Schema(description = "套餐标签", example = "模型管理") |
| | | private List<String> labels; |
| | | |
| | | @Schema(description = "描述", example = "好") |
| | | @NotNull(message = "描述不能为空") |
| | | private String description; |
| | | |
| | | @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "状态不能为空") |
| | | @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}") |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * 套餐图标 |
| | | */ |
| | | private String icon; |
| | | /** |
| | | * 套餐标签 |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private List<String> labels; |
| | | /** |
| | | * 套餐介绍 |
| | | */ |
| | | private String description; |
| | | /** |
| | | * 备注 |
| | | */ |
| | | private String remark; |
| | |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<AppDO>() |
| | | .likeIfPresent(AppDO::getAppCode, reqVO.getAppCode()) |
| | | .likeIfPresent(AppDO::getAppName, reqVO.getAppName()) |
| | | .orderByDesc(AppDO::getType) |
| | | .orderByDesc(AppDO::getId)); |
| | | } |
| | | } |
| | |
| | | .eqIfPresent(MenuDO::getStatus, reqVO.getStatus())); |
| | | } |
| | | |
| | | default List<MenuDO> selectAppMenuList(Long tenantId, MenuListReqVO reqVO) { |
| | | default List<MenuDO> selectAppMenuList(MenuListReqVO reqVO) { |
| | | return selectList(new LambdaQueryWrapperX<MenuDO>() |
| | | .likeIfPresent(MenuDO::getName, reqVO.getName()) |
| | | .eqIfPresent(MenuDO::getStatus, reqVO.getStatus()) |
| | | .eq(MenuDO::getTenantId, tenantId)); |
| | | .eqIfPresent(MenuDO::getStatus, reqVO.getStatus())); |
| | | } |
| | | |
| | | default List<MenuDO> selectListByPermission(String permission) { |
| | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; |
| | | |
| | | /** |
| | | * System 模块的 Security 配置 |
| | |
| | | return new AuthorizeRequestsCustomizer() { |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { |
| | | // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案 |
| | | // Swagger 接口文档 |
| | | registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据 |
| | | .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI |
| | | registry.requestMatchers("/v3/api-docs/**").permitAll() |
| | | .requestMatchers("/webjars/**").permitAll() |
| | | .requestMatchers("/swagger-ui").permitAll() |
| | | .requestMatchers("/swagger-ui/**").permitAll(); |
| | | // Druid 监控 |
| | | registry.antMatchers("/druid/**").anonymous(); |
| | | registry.requestMatchers("/druid/**").permitAll(); |
| | | // Spring Boot Actuator 的安全配置 |
| | | registry.antMatchers("/actuator").anonymous() |
| | | .antMatchers("/actuator/**").anonymous(); |
| | | registry.requestMatchers("/actuator").permitAll() |
| | | .requestMatchers("/actuator/**").permitAll(); |
| | | // RPC 服务的安全配置 |
| | | registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll(); |
| | | } |
| | | |
| | | }; |
| | |
| | | package com.iailab.module.system.job.demo; |
| | | |
| | | import com.iailab.framework.tenant.core.job.TenantJob; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | @Component |
| | | public class DemoJob { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(getClass()); |
| | | |
| | | private final AtomicInteger counts = new AtomicInteger(); |
| | | |
| | | private static final Object lock = new Object(); |
| | | |
| | | |
| | | @XxlJob("demoJob") |
| | | @TenantJob |
| | | public void execute() { |
| | | synchronized (lock) { |
| | | logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); |
| | | System.out.println(new Date() + ": 我是系统定时任务"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | //package com.iailab.module.system.job.demo; |
| | | // |
| | | //import com.iailab.framework.tenant.core.job.TenantJob; |
| | | //import com.xxl.job.core.handler.annotation.XxlJob; |
| | | //import org.slf4j.Logger; |
| | | //import org.slf4j.LoggerFactory; |
| | | //import org.springframework.stereotype.Component; |
| | | // |
| | | //import java.util.Date; |
| | | //import java.util.concurrent.atomic.AtomicInteger; |
| | | // |
| | | //@Component |
| | | //public class DemoJob { |
| | | // |
| | | // private Logger logger = LoggerFactory.getLogger(getClass()); |
| | | // |
| | | // private final AtomicInteger counts = new AtomicInteger(); |
| | | // |
| | | // private static final Object lock = new Object(); |
| | | // |
| | | // |
| | | // @XxlJob("demoJob") |
| | | // @TenantJob |
| | | // public void execute() { |
| | | // synchronized (lock) { |
| | | // logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); |
| | | // System.out.println(new Date() + ": 我是系统定时任务"); |
| | | // } |
| | | // } |
| | | // |
| | | //} |
| | |
| | | if(type == 1){ |
| | | menuDO.setCreator(loginUserNickname); |
| | | menuDO.setCreateTime(app.getCreateTime()); |
| | | menuDO.setIcon("fa-solid:border-none"); //默认icon |
| | | menuMapper.insert(menuDO); |
| | | // //内置租户角色分配菜单 |
| | | // assignRoleMenu(menuDO.getId(), app.getTenantId()); |
| | |
| | | List<MenuDO> filterDisableMenus(List<MenuDO> list); |
| | | |
| | | /** |
| | | * 过滤掉业务菜单或系统菜单及其子菜单 |
| | | * |
| | | * @param list 菜单列表 |
| | | * @return 过滤后的菜单列表 |
| | | */ |
| | | List<MenuDO> filterMenus(List<MenuDO> list, String type); |
| | | |
| | | /** |
| | | * 筛选菜单列表 |
| | | * |
| | | * @param reqVO 筛选条件请求 VO |
| | |
| | | import com.iailab.module.system.controller.admin.permission.vo.menu.MenuSaveVO; |
| | | import com.iailab.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO; |
| | | import com.iailab.module.system.dal.dataobject.app.AppDO; |
| | | import com.iailab.module.system.dal.dataobject.app.AppMenuDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.MenuDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.RoleDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.RoleMenuDO; |
| | | import com.iailab.module.system.dal.dataobject.tenant.TenantDO; |
| | | import com.iailab.module.system.dal.dataobject.tenant.TenantPackageDO; |
| | | import com.iailab.module.system.dal.mysql.app.AppMapper; |
| | | import com.iailab.module.system.dal.mysql.app.AppMenuMapper; |
| | | import com.iailab.module.system.dal.mysql.permission.MenuMapper; |
| | | import com.iailab.module.system.dal.mysql.permission.RoleMenuMapper; |
| | | import com.iailab.module.system.dal.redis.RedisKeyConstants; |
| | |
| | | import com.iailab.module.system.service.tenant.TenantPackageService; |
| | | import com.iailab.module.system.service.tenant.TenantService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.context.annotation.Lazy; |
| | |
| | | |
| | | @Resource |
| | | private RoleMenuMapper roleMenuMapper; |
| | | @Autowired |
| | | private AppMapper appMapper; |
| | | @Autowired |
| | | private AppMenuMapper appMenuMapper; |
| | | |
| | | @Override |
| | | @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#createReqVO.permission", |
| | |
| | | //菜单归属租户和应用 |
| | | Long tenantId = getTenantId(); |
| | | AppDO appDO = appService.getAppByTenantId(tenantId); |
| | | if(appDO.getTenantId() != 1) { |
| | | updateObj.setTenantId(tenantId); |
| | | updateObj.setAppId(appDO.getId()); |
| | | } |
| | | menuMapper.updateById(updateObj); |
| | | } |
| | | |
| | |
| | | return enabledMenus; |
| | | } |
| | | |
| | | @Override |
| | | public List<MenuDO> filterMenus(List<MenuDO> menuList, String type) { |
| | | if (CollUtil.isEmpty(menuList)){ |
| | | return Collections.emptyList(); |
| | | } |
| | | Map<Long, MenuDO> menuMap = convertMap(menuList, MenuDO::getId); |
| | | LambdaQueryWrapper<AppDO> queryWrapper = new LambdaQueryWrapper<>(); |
| | | |
| | | //查询所有的系统应用菜单 |
| | | if("system".equals(type)) { |
| | | queryWrapper.eq(AppDO::getType, 0); |
| | | } else if("app".equals(type)) { |
| | | queryWrapper.eq(AppDO::getType, 1); |
| | | } |
| | | List<AppDO> appDOS = appMapper.selectList(queryWrapper); |
| | | List<Long> appIds = appDOS.stream().map(AppDO::getId).collect(Collectors.toList()); |
| | | List<MenuDO> menuDOS = menuMapper.selectList(new LambdaQueryWrapper<MenuDO>().in(MenuDO::getAppId, appIds)); |
| | | List<Long> systemMenuIds = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toList()); |
| | | |
| | | // 遍历 menu 菜单,查找不是禁用的菜单,添加到 系统菜单(应用菜单) 结果 |
| | | List<MenuDO> systemMenus = new ArrayList<>(); |
| | | Set<Long> appMenuCache = new HashSet<>(); // 存下递归搜索过被禁用的菜单,防止重复的搜索 |
| | | for (MenuDO menu : menuList) { |
| | | if (isAppMenu(menu, menuMap, appMenuCache, systemMenuIds)) { |
| | | continue; |
| | | } |
| | | systemMenus.add(menu); |
| | | } |
| | | return systemMenus; |
| | | } |
| | | |
| | | private boolean isMenuDisabled(MenuDO node, Map<Long, MenuDO> menuMap, Set<Long> disabledMenuCache) { |
| | | // 如果已经判定是禁用的节点,直接结束 |
| | | if (disabledMenuCache.contains(node.getId())) { |
| | |
| | | return false; |
| | | } |
| | | |
| | | private boolean isAppMenu(MenuDO node, Map<Long, MenuDO> menuMap, Set<Long> menuCache, List<Long> systemMenuIds) { |
| | | // 如果已经判定是禁用的节点,直接结束 |
| | | if (menuCache.contains(node.getId())) { |
| | | return true; |
| | | } |
| | | |
| | | // 2. 遍历到 parentId 为根节点,则无需判断 |
| | | Long parentId = node.getParentId(); |
| | | if (ObjUtil.equal(parentId, ID_ROOT)) { |
| | | if (!systemMenuIds.contains(node.getId())) { |
| | | menuCache.add(node.getId()); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // 3. 继续遍历 parent 节点 |
| | | MenuDO parent = menuMap.get(parentId); |
| | | if (parent == null || isAppMenu(parent, menuMap, menuCache, systemMenuIds)) { |
| | | menuCache.add(node.getId()); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public List<MenuDO> getMenuList(MenuListReqVO reqVO) { |
| | | return menuMapper.selectList(reqVO); |
| | |
| | | |
| | | @Override |
| | | public List<MenuDO> getAppMenuList(Long tenantId, MenuListReqVO reqVO) { |
| | | List<MenuDO> menuDOS = menuMapper.selectAppMenuList(tenantId, reqVO); |
| | | List<MenuDO> menuDOS = menuMapper.selectAppMenuList(reqVO); |
| | | menuDOS = filterMenus(menuDOS, "app"); |
| | | Set<Long> menuDOIds = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toSet()); |
| | | TenantDO tenant = tenantService.getTenant(tenantId); |
| | | TenantPackageDO tenantPackage = tenantPackageService.getTenantPackage(tenant.getPackageId()); |
| | | Set<Long> tenantMenuIds = tenantPackage.getMenuIds(); |
| | | menuDOS = menuDOS.stream().filter(menuDO -> tenantMenuIds.contains(menuDO.getId())).collect(Collectors.toList()); |
| | | // 获得角色列表 |
| | | Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId()); |
| | | List<RoleDO> roles = roleService.getRoleList(roleIds); |
| | |
| | | <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> |
| | | <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version> |
| | | <!-- 统一依赖管理 --> |
| | | <spring.framework.version>5.3.39</spring.framework.version> |
| | | <spring.security.version>5.8.14</spring.security.version> |
| | | <spring.boot.version>2.7.18</spring.boot.version> |
| | | <spring.cloud.version>2021.0.9</spring.cloud.version> |
| | | <spring.cloud.alibaba.version>2021.0.6.1</spring.cloud.alibaba.version> |
| | |
| | | <ip2region.version>2.7.0</ip2region.version> |
| | | <bizlog-sdk.version>3.0.6</bizlog-sdk.version> |
| | | <reflections.version>0.10.2</reflections.version> |
| | | <netty.version>4.1.113.Final</netty.version> |
| | | <!-- 三方云服务相关 --> |
| | | <okio.version>3.5.0</okio.version> |
| | | <okhttp3.version>4.11.0</okhttp3.version> |
| | |
| | | <aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version> |
| | | <tencentcloud-sdk-java.version>3.1.880</tencentcloud-sdk-java.version> |
| | | <justauth.version>1.0.8</justauth.version> |
| | | <jimureport.version>1.6.6</jimureport.version> |
| | | <jimureport.version>1.9.0</jimureport.version> |
| | | <xercesImpl.version>2.12.2</xercesImpl.version> |
| | | <weixin-java.version>4.6.0</weixin-java.version> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | |
| | | <nacos.metadata.version>1.0.0</nacos.metadata.version> |
| | | <log.path>D:\DLUT\iailab-plat</log.path> |
| | | <logstash.address>127.0.0.1:4560</logstash.address> |
| | | <deploy.server>127.0.0.1</deploy.server> |
| | | <deploy.server>192.168.56.1</deploy.server> |
| | | </properties> |
| | | <activation> |
| | | <!-- 默认环境 --> |
| | |
| | | <profile> |
| | | <id>prod</id> |
| | | <properties> |
| | | <!-- 环境标识,需要与配置文件的名称相对应 --> |
| | | <profiles.active>prod</profiles.active> |
| | | <nacos.server>127.0.0.1:8848</nacos.server> |
| | | <nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group> |
| | | <nacos.config.group>DEFAULT_GROUP</nacos.config.group> |
| | | <nacos.namespace>a7112341-c9e2-4177-bc5b-0d2e8cf0b3bb</nacos.namespace> |
| | | <nacos.username>nacos</nacos.username> |
| | | <nacos.password>nacos</nacos.password> |
| | | <nacos.metadata.version>1.0.0</nacos.metadata.version> |
| | | <log.path>D:\iailab\logs</log.path> |
| | | <logstash.address>127.0.0.1:4560</logstash.address> |
| | | <deploy.server>10.88.4.131</deploy.server> |
| | | </properties> |
| | | </profile> |
| | | </profiles> |
| | |
| | | <dependencyManagement> |
| | | <dependencies> |
| | | <!-- 统一依赖管理 --> |
| | | <dependency> |
| | | <groupId>io.netty</groupId> |
| | | <artifactId>netty-bom</artifactId> |
| | | <version>${netty.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-framework-bom</artifactId> <!-- JDK8 版本独有:保证 Spring Framework 尽量高 --> |
| | | <version>${spring.framework.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.security</groupId> |
| | | <artifactId>spring-security-bom</artifactId> <!-- JDK8 版本独有:保证 Spring Security 尽量高 --> |
| | | <version>${spring.security.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-dependencies</artifactId> |
| | |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <!-- 积木仪表盘--> |
| | | <dependency> |
| | | <groupId>org.jeecgframework.jimureport</groupId> |
| | | <artifactId>jimureport-dashboard-spring-boot-starter</artifactId> |
| | | <version>${jimureport.version}</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>autopoi-web</artifactId> |
| | | <groupId>org.jeecgframework</groupId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>org.jeecgframework.jimureport</groupId> |
| | | <artifactId>jimureport-spring-boot-starter</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>xerces</groupId> |
| | | <artifactId>xercesImpl</artifactId> |