Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
92b120380e
|
@ -1,7 +1,7 @@
|
|||
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
|
||||
TARO_APP_ID="wx0acd1c4fcf94bdd3"
|
||||
# TARO_APP_BASE_API="http://172.10.10.93:8765"
|
||||
TARO_APP_BASE_API="https://www.hnjinglian.cn:5678"
|
||||
TARO_APP_BASE_API="http://172.10.10.93:8765"
|
||||
# TARO_APP_BASE_API="https://www.hnjinglian.cn:5678"
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package com.changhu.common.annotation;
|
||||
|
||||
import com.changhu.common.enums.OpenApiType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/10/9 下午5:14
|
||||
* @desc 检查openApi
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface CheckOpenApi {
|
||||
OpenApiType value();
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.changhu.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/10/9 下午5:10
|
||||
* @desc OpenApiType...
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OpenApiType {
|
||||
Information_on_enterprises_and_institutions("获取企事业单位信息", Arrays.asList("1fe0aaf3-45a4-4be3-a989-75e914a3f36e", "1fe0aaf3-45a4-a989-75e914a3f36e")),
|
||||
data_view("数据总览", List.of("8da74bbf-c686-4393-b4ec-692091e6d381"));
|
||||
|
||||
private final String desc;
|
||||
private final List<String> openApiKeys;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.changhu.common.pojo.params;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.locationtech.jts.geom.Point;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/21 上午11:18
|
||||
* @desc MapVisionParams...
|
||||
*/
|
||||
@Data
|
||||
public class MapVisionParams {
|
||||
@Schema(description = "左上角")
|
||||
private Point upperLeft;
|
||||
@Schema(description = "右上角")
|
||||
private Point upperRight;
|
||||
@Schema(description = "左下角")
|
||||
private Point lowerLeft;
|
||||
@Schema(description = "右下角")
|
||||
private Point lowerRight;
|
||||
}
|
|
@ -2,10 +2,13 @@ package com.changhu.config;
|
|||
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.changhu.support.filter.BodyWrapperFilter;
|
||||
import com.changhu.support.interceptor.JsonBodyInterceptor;
|
||||
import com.changhu.support.interceptor.OpenApiInterceptor;
|
||||
import com.changhu.support.interceptor.SignInterceptor;
|
||||
import com.changhu.support.interceptor.UserTypeInterceptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
|
@ -59,10 +62,19 @@ public class WebConfig implements WebMvcConfigurer {
|
|||
// 注册clientType 拦截器 用于校验当前用户是否匹配操作客户端
|
||||
registry.addInterceptor(new UserTypeInterceptor());
|
||||
// 注册开放接口 拦截器 用于校验第三方是否携带指定apiKey
|
||||
registry.addInterceptor(new OpenApiInterceptor())
|
||||
registry.addInterceptor(new SignInterceptor())
|
||||
.addPathPatterns("/open/**");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<BodyWrapperFilter> loggingFilter() {
|
||||
FilterRegistrationBean<BodyWrapperFilter> registrationBean = new FilterRegistrationBean<>();
|
||||
registrationBean.setFilter(new BodyWrapperFilter());
|
||||
registrationBean.addUrlPatterns("/open/*"); // 指定过滤的URL模式
|
||||
registrationBean.setOrder(1000);
|
||||
return registrationBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.changhu.controller;
|
|||
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.changhu.common.annotation.CheckUserType;
|
||||
import com.changhu.common.annotation.JsonBody;
|
||||
import com.changhu.common.db.enums.UserType;
|
||||
|
@ -67,23 +66,4 @@ public class AccessKeysController {
|
|||
return accessKeysService.list();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Class<OpenController> openControllerClass = OpenController.class;
|
||||
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(openControllerClass, RequestMapping.class);
|
||||
String controllerPath = requestMapping.value()[0];
|
||||
|
||||
List<SelectNodeVo<String>> method = Arrays.stream(openControllerClass.getMethods())
|
||||
.filter(m -> AnnotationUtil.hasAnnotation(m, RequestMapping.class))
|
||||
.map(m -> {
|
||||
Operation operation = m.getAnnotation(Operation.class);
|
||||
RequestMapping mReq = AnnotatedElementUtils.findMergedAnnotation(m, RequestMapping.class);
|
||||
return SelectNodeVo.<String>builder()
|
||||
.value(controllerPath + mReq.value()[0])
|
||||
.label(operation.summary())
|
||||
.extData(Dict.of("method", mReq.method()))
|
||||
.build();
|
||||
})
|
||||
.toList();
|
||||
method.forEach(i -> System.out.println(JSON.toJSONString(i)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.changhu.controller;
|
||||
|
||||
import com.changhu.common.annotation.CheckOpenApi;
|
||||
import com.changhu.common.annotation.JsonBody;
|
||||
import com.changhu.common.enums.OpenApiType;
|
||||
import com.changhu.common.pojo.vo.SelectNodeVo;
|
||||
import com.changhu.pojo.dto.DataViewDTO;
|
||||
import com.changhu.pojo.dto.EnterprisesUnitDetailDTO;
|
||||
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
|
||||
import com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO;
|
||||
import com.changhu.pojo.dto.SecurityUserRosterDTO;
|
||||
import com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType;
|
||||
import com.changhu.service.OpenApiService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
@ -33,7 +32,6 @@ public class OpenController {
|
|||
private OpenApiService openApiService;
|
||||
|
||||
@Operation(summary = "获取企事业单位列表")
|
||||
@CheckOpenApi(value = OpenApiType.Information_on_enterprises_and_institutions)
|
||||
@GetMapping("/getEnterprisesUnit")
|
||||
public List<SelectNodeVo<Long>> getEnterprisesUnit(@Schema(description = "代码") @RequestParam String code,
|
||||
@Schema(description = "等级") @RequestParam Integer level) {
|
||||
|
@ -41,31 +39,29 @@ public class OpenController {
|
|||
}
|
||||
|
||||
@Operation(summary = "企事业单位详情")
|
||||
@CheckOpenApi(value = OpenApiType.Information_on_enterprises_and_institutions)
|
||||
@GetMapping("/enterprisesUnitDetailById")
|
||||
public EnterprisesUnitDetailDTO enterprisesUnitDetailById(@Schema(description = "企事业单位id") @RequestParam Long enterprisesUnitId) {
|
||||
return openApiService.enterprisesUnitDetailById(enterprisesUnitId);
|
||||
}
|
||||
|
||||
@Operation(summary = "数据总览")
|
||||
@CheckOpenApi(value = OpenApiType.data_view)
|
||||
@GetMapping("/dataView")
|
||||
public DataViewDTO dataView() {
|
||||
return openApiService.dataView();
|
||||
}
|
||||
|
||||
@Operation(summary = "保安单位使用情况统计")
|
||||
@CheckOpenApi(value = OpenApiType.Information_on_enterprises_and_institutions)
|
||||
@GetMapping("/securityUnitUseStatistics")
|
||||
public List<SecurityUnitUseStatisticsDTO> securityUnitUseStatistics(@Schema(description = "代码") @RequestParam String code,
|
||||
@Schema(description = "等级") @RequestParam Integer level) {
|
||||
return openApiService.securityUnitUseStatistics(code, level);
|
||||
}
|
||||
|
||||
@Operation(summary = "服务项目安保人员花名册")
|
||||
@CheckOpenApi(value = OpenApiType.Information_on_enterprises_and_institutions)
|
||||
@GetMapping("/serviceProjectUserRoster")
|
||||
public List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(@Schema(description = "服务项目id") Long serviceProjectId) {
|
||||
return openApiService.serviceProjectUserRoster(serviceProjectId);
|
||||
@Operation(summary = "安保人员花名册")
|
||||
@GetMapping("/securityUserRoster")
|
||||
public List<SecurityUserRosterDTO> securityUserRoster(@Schema(description = "事业单位或服务项目id") Long id,
|
||||
@Schema(description = "类型") EnterprisesUnitOrServiceProjectType type) {
|
||||
return openApiService.securityUserRoster(id, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ package com.changhu.mapper;
|
|||
|
||||
import com.changhu.common.pojo.vo.SelectNodeVo;
|
||||
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
|
||||
import com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO;
|
||||
import com.changhu.pojo.dto.SecurityUserRosterDTO;
|
||||
import com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -38,9 +39,7 @@ public interface OpenApiMapper {
|
|||
|
||||
/**
|
||||
* 获取服务人员花名册
|
||||
*
|
||||
* @param serviceProjectId 服务项目id
|
||||
* @return 结果
|
||||
*/
|
||||
List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(@Param("serviceProjectId") Long serviceProjectId);
|
||||
List<SecurityUserRosterDTO> securityUserRoster(@Param("id") Long id,
|
||||
@Param("type") EnterprisesUnitOrServiceProjectType type);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.changhu.common.annotation.JsonBody;
|
|||
import com.changhu.common.db.enums.UserType;
|
||||
import com.changhu.common.exception.MessageException;
|
||||
import com.changhu.common.pojo.vo.SelectNodeVo;
|
||||
import com.changhu.module.management.pojo.entity.EnterprisesUnit;
|
||||
import com.changhu.module.management.pojo.params.EnterprisesUnitSaveOrUpdateParams;
|
||||
import com.changhu.module.management.pojo.queryParams.EnterprisesUnitPagerQueryParams;
|
||||
import com.changhu.module.management.pojo.vo.EnterprisesUnitPagerVo;
|
||||
|
@ -64,10 +63,4 @@ public class EnterprisesUnitController {
|
|||
return enterprisesUnitService.queryListByAdministrativeDivisionCodes(administrativeDivisionCodes);
|
||||
}
|
||||
|
||||
@Operation(summary = "企事业单位地图点位")
|
||||
@GetMapping("/mapPoint")
|
||||
public List<EnterprisesUnit> mapPoint() {
|
||||
return enterprisesUnitService.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.changhu.module.superManagement.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
import com.changhu.common.annotation.JsonBody;
|
||||
import com.changhu.module.management.pojo.entity.EnterprisesUnit;
|
||||
import com.changhu.module.superManagement.service.SuperIndexService;
|
||||
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.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/21 上午11:31
|
||||
* @desc SuperIndexController...
|
||||
*/
|
||||
@JsonBody
|
||||
@Tag(name = "超级后台首页")
|
||||
@RequestMapping("/super/index")
|
||||
public class SuperIndexController {
|
||||
|
||||
@Autowired
|
||||
private SuperIndexService superIndexService;
|
||||
|
||||
@Operation(summary = "企事业单位地图点位")
|
||||
@GetMapping("/mapPoint")
|
||||
public List<EnterprisesUnit> mapPoint() {
|
||||
return Db.lambdaQuery(EnterprisesUnit.class).list();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.changhu.module.superManagement.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/21 上午11:32
|
||||
* @desc SuperIndexMapper...
|
||||
*/
|
||||
@Mapper
|
||||
public interface SuperIndexMapper {
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.changhu.module.superManagement.service;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/21 上午11:31
|
||||
* @desc SuperIndexService...
|
||||
*/
|
||||
public interface SuperIndexService {
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.changhu.module.superManagement.service.impl;
|
||||
|
||||
import com.changhu.module.superManagement.service.SuperIndexService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/21 上午11:31
|
||||
* @desc SuperIndexServiceImpl...
|
||||
*/
|
||||
@Service
|
||||
public class SuperIndexServiceImpl implements SuperIndexService {
|
||||
}
|
|
@ -7,6 +7,8 @@ import com.changhu.module.management.pojo.model.LegalPersonInfo;
|
|||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/18 上午10:32
|
||||
|
@ -14,31 +16,63 @@ import lombok.Data;
|
|||
*/
|
||||
@Data
|
||||
public class SecurityUnitUseStatisticsDTO {
|
||||
@Schema(description = "服务项目id")
|
||||
private Long serviceProjectId;
|
||||
@Schema(description = "事业单位id")
|
||||
private Long enterprisesUnitId;
|
||||
@Schema(description = "事业单位名称")
|
||||
private String enterprisesUnitName;
|
||||
@Schema(description = "省编码")
|
||||
private String province;
|
||||
@Schema(description = "省")
|
||||
private String provinceName;
|
||||
@Schema(description = "市编码")
|
||||
private String city;
|
||||
@Schema(description = "市")
|
||||
private String cityName;
|
||||
@Schema(description = "区/县编码")
|
||||
private String districts;
|
||||
@Schema(description = "区/县")
|
||||
private String districtsName;
|
||||
@Schema(description = "街道编码")
|
||||
private String street;
|
||||
@Schema(description = "街道")
|
||||
private String streetName;
|
||||
@Schema(description = "事业单位详细地址")
|
||||
private String address;
|
||||
@Schema(description = "服务项目列表")
|
||||
List<_ServiceProjectVo> serviceProjectList;
|
||||
|
||||
@Schema(description = "公安单位id")
|
||||
private Long policeUnitId;
|
||||
@Schema(description = "公安单位名称")
|
||||
private String policeUnitName;
|
||||
@Schema(description = "保安单位名称")
|
||||
private String securityUnitName;
|
||||
|
||||
@Data
|
||||
static class _ServiceProjectVo {
|
||||
@Schema(description = "服务项目id")
|
||||
private Long snowFlakeId;
|
||||
@Schema(description = "服务项目名称")
|
||||
private String serviceProjectName;
|
||||
private String name;
|
||||
@Schema(description = "保安服务类别")
|
||||
private ServiceProjectType type;
|
||||
@Schema(description = "二级类型")
|
||||
private ServiceProjectTwoType twoType;
|
||||
|
||||
@Schema(description = "外包公司名称")
|
||||
private String outsourceName;
|
||||
@Schema(description = "是否备案")
|
||||
private IsOrNot isFiling;
|
||||
@Schema(description = "证件号(保安服务许可证/备案证)")
|
||||
private String idNumber;
|
||||
|
||||
@Schema(description = "保安人员总数")
|
||||
private Integer securityUserTotal;
|
||||
@Schema(description = "持证保安数量")
|
||||
private Integer haveCardSecurityUserCount;
|
||||
|
||||
@Schema(description = "是否备案")
|
||||
private IsOrNot isFiling;
|
||||
@Schema(description = "证件号(保安服务许可证/备案证)")
|
||||
private String idNumber;
|
||||
|
||||
@Schema(description = "保安单位id")
|
||||
private Long securityUnitId;
|
||||
@Schema(description = "保安单位名称")
|
||||
private String securityUnitName;
|
||||
@Schema(description = "保安单位法人信息")
|
||||
private LegalPersonInfo securityUnitLegalPersonInfo;
|
||||
|
||||
|
@ -48,3 +82,5 @@ public class SecurityUnitUseStatisticsDTO {
|
|||
private String serviceProjectManagerTelephone;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@ import lombok.Data;
|
|||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/18 上午10:43
|
||||
* @desc ServiceProjectSecurityUserRosterDTO...
|
||||
* @desc SecurityUserRosterDTO...
|
||||
*/
|
||||
@Data
|
||||
public class ServiceProjectSecurityUserRosterDTO {
|
||||
public class SecurityUserRosterDTO {
|
||||
@Schema(description = "id")
|
||||
private Long snowFlakeId;
|
||||
@Schema(description = "名称")
|
|
@ -0,0 +1,16 @@
|
|||
package com.changhu.pojo.params;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/21 上午10:35
|
||||
* @desc EnterprisesUnitOrServiceProjectType...
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum EnterprisesUnitOrServiceProjectType {
|
||||
ENTERPRISES_UNIT,
|
||||
SERVICE_PROJECT
|
||||
}
|
|
@ -4,7 +4,8 @@ import com.changhu.common.pojo.vo.SelectNodeVo;
|
|||
import com.changhu.pojo.dto.DataViewDTO;
|
||||
import com.changhu.pojo.dto.EnterprisesUnitDetailDTO;
|
||||
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
|
||||
import com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO;
|
||||
import com.changhu.pojo.dto.SecurityUserRosterDTO;
|
||||
import com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -50,8 +51,9 @@ public interface OpenApiService {
|
|||
/**
|
||||
* 服务项目安保人员花名册
|
||||
*
|
||||
* @param serviceProjectId 服务项目id
|
||||
* @param id 事业单位服务项目id
|
||||
* @param type 类型
|
||||
* @return 花名册
|
||||
*/
|
||||
List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(Long serviceProjectId);
|
||||
List<SecurityUserRosterDTO> securityUserRoster(Long id, EnterprisesUnitOrServiceProjectType type);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import com.changhu.module.miniProgram.pojo.entity.SecurityUser;
|
|||
import com.changhu.pojo.dto.DataViewDTO;
|
||||
import com.changhu.pojo.dto.EnterprisesUnitDetailDTO;
|
||||
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
|
||||
import com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO;
|
||||
import com.changhu.pojo.dto.SecurityUserRosterDTO;
|
||||
import com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType;
|
||||
import com.changhu.service.OpenApiService;
|
||||
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
|
||||
import lombok.SneakyThrows;
|
||||
|
@ -103,7 +104,7 @@ public class OpenApiServiceImpl implements OpenApiService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(Long serviceProjectId) {
|
||||
return openApiMapper.serviceProjectUserRoster(serviceProjectId);
|
||||
public List<SecurityUserRosterDTO> securityUserRoster(Long id, EnterprisesUnitOrServiceProjectType type) {
|
||||
return openApiMapper.securityUserRoster(id, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,8 @@ public class FastJson2Config {
|
|||
|
||||
//4.解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
|
||||
fastConverter.setSupportedMediaTypes(List.of(
|
||||
MediaType.APPLICATION_JSON
|
||||
MediaType.APPLICATION_JSON,
|
||||
MediaType.APPLICATION_FORM_URLENCODED
|
||||
));
|
||||
return fastConverter;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package com.changhu.support.filter;
|
||||
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/19 下午3:07
|
||||
* @desc BodyWrapperFilter...
|
||||
*/
|
||||
@Slf4j
|
||||
public class BodyWrapperFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
log.info("进入filter:{}", servletRequest.getRemoteAddr());
|
||||
ServletRequest requestWrapper = null;
|
||||
if (servletRequest instanceof HttpServletRequest) {
|
||||
requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
|
||||
}
|
||||
filterChain.doFilter(Objects.requireNonNullElse(requestWrapper, servletRequest), servletResponse);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.changhu.support.filter;
|
||||
|
||||
import jakarta.servlet.ReadListener;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/19 下午3:12
|
||||
* @desc CustomHttpServletRequestWrapper...
|
||||
*/
|
||||
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
private final byte[] body;
|
||||
|
||||
public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
|
||||
super(request);
|
||||
BufferedReader reader = request.getReader();
|
||||
try (StringWriter writer = new StringWriter()) {
|
||||
int read;
|
||||
char[] buf = new char[1024 * 8];
|
||||
while ((read = reader.read(buf)) != -1) {
|
||||
writer.write(buf, 0, read);
|
||||
}
|
||||
this.body = writer.getBuffer().toString().getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return new String(body, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() {
|
||||
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
|
||||
return new ServletInputStream() {
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
return byteArrayInputStream.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() {
|
||||
return new BufferedReader(new InputStreamReader(this.getInputStream()));
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package com.changhu.support.interceptor;
|
||||
|
||||
import com.changhu.common.annotation.CheckOpenApi;
|
||||
import com.changhu.common.exception.MessageException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/10/9 下午5:05
|
||||
* @desc OpenApiInterceptor...
|
||||
*/
|
||||
@Slf4j
|
||||
public class OpenApiInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
|
||||
String header = request.getHeader("X-API-KEY");
|
||||
log.info("apiKey:{} {} 请求:{}", header, LocalDateTime.now(), request.getRequestURI());
|
||||
if (handler instanceof HandlerMethod handlerMethod) {
|
||||
CheckOpenApi methodAnnotation = handlerMethod.getMethodAnnotation(CheckOpenApi.class);
|
||||
if (methodAnnotation != null) {
|
||||
List<String> openApiKeys = methodAnnotation.value().getOpenApiKeys();
|
||||
if (!openApiKeys.contains(header)) {
|
||||
throw new MessageException("openApiKey error!");
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package com.changhu.support.interceptor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
import com.changhu.common.db.enums.IsEnable;
|
||||
import com.changhu.common.exception.MessageException;
|
||||
import com.changhu.common.utils.IpUtil;
|
||||
import com.changhu.pojo.entity.AccessKeys;
|
||||
import com.changhu.support.filter.CustomHttpServletRequestWrapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 20252
|
||||
* @createTime 2024/11/19 下午1:58
|
||||
* @desc SignInterceptor...
|
||||
*/
|
||||
@Slf4j
|
||||
public class SignInterceptor implements HandlerInterceptor {
|
||||
|
||||
private static final String ACCESS_KEY = "Access-Key";//调用者身份唯一标识
|
||||
private static final String TIMESTAMP = "Time-Stamp";//时间戳
|
||||
private static final String SIGN = "Sign";//签名
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NotNull HttpServletRequest request,
|
||||
@NotNull HttpServletResponse response,
|
||||
@NotNull Object handler) throws Exception {
|
||||
if (handler instanceof HandlerMethod) {
|
||||
String ip = IpUtil.getIp(request);
|
||||
try {
|
||||
return checkSign(request);
|
||||
} catch (MessageException e) {
|
||||
log.error("开放接口访问失败:{} 访问时间:{} IP:{} 访问接口:{} ", e.getMessage(), LocalDateTime.now(), ip, request.getRequestURI());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkSign(HttpServletRequest request) throws MessageException {
|
||||
|
||||
String accessKey = request.getHeader(ACCESS_KEY);
|
||||
String timestamp = request.getHeader(TIMESTAMP);
|
||||
String sign = request.getHeader(SIGN);
|
||||
|
||||
if (StrUtil.isBlank(accessKey) || StrUtil.isBlank(timestamp) || StrUtil.isBlank(sign)) {
|
||||
throw new MessageException("请求体缺失");
|
||||
}
|
||||
|
||||
AccessKeys accessKeyEntity = Db.lambdaQuery(AccessKeys.class)
|
||||
.eq(AccessKeys::getAccessKey, accessKey)
|
||||
.oneOpt()
|
||||
.orElseThrow(() -> new MessageException("无效的accessKey"));
|
||||
|
||||
if (IsEnable.FALSE.equals(accessKeyEntity.getIsEnable())) {
|
||||
throw new MessageException("accessKey已禁用");
|
||||
}
|
||||
|
||||
if (accessKeyEntity.getEffectiveTime() > 0 && System.currentTimeMillis() - Long.parseLong(timestamp) > accessKeyEntity.getEffectiveTime()) {
|
||||
throw new MessageException("请求已过期");
|
||||
}
|
||||
|
||||
List<String> allowedResources = Optional.ofNullable(accessKeyEntity.getAllowedResources()).orElseThrow(() -> new MessageException("暂无允许访问的资源"));
|
||||
if (!allowedResources.contains(request.getRequestURI())) {
|
||||
throw new MessageException("无效的请求资源");
|
||||
}
|
||||
|
||||
Map<String, Object> hashMap = new HashMap<>();
|
||||
hashMap.put(ACCESS_KEY, accessKey);
|
||||
hashMap.put(TIMESTAMP, timestamp);
|
||||
//添加请求url参数
|
||||
Optional.ofNullable(HttpUtil.decodeParamMap(request.getQueryString(), StandardCharsets.UTF_8))
|
||||
.ifPresent(hashMap::putAll);
|
||||
//添加body参数
|
||||
Optional.ofNullable(JSON.<Map<String, Object>>parseObject(((CustomHttpServletRequestWrapper) request).getBody(), Map.class))
|
||||
.ifPresent(hashMap::putAll);
|
||||
//生成签名
|
||||
String nowSign = generatedSign(hashMap, accessKeyEntity.getSecretKey());
|
||||
//比对签名
|
||||
if (!sign.equals(nowSign)) {
|
||||
throw new MessageException("签名错误");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取签名
|
||||
*
|
||||
* @param map 参数结果
|
||||
* @param secretKey 密钥
|
||||
* @return 签名字符串
|
||||
*/
|
||||
private String generatedSign(Map<String, Object> map, String secretKey) {
|
||||
List<Map.Entry<String, Object>> entries = new ArrayList<>(map.entrySet());
|
||||
String str = entries.stream()
|
||||
.filter(en -> null == en.getValue() || StrUtil.isNotBlank(en.getValue().toString()))
|
||||
.sorted(Comparator.comparing(o -> o.getKey().toLowerCase()))
|
||||
.map(en -> StrUtil.format("{}={}", en.getKey(), URLUtil.encodeAll(en.getValue() + "")))
|
||||
.collect(Collectors.joining("&"));
|
||||
str += ("&Secret-Key=" + secretKey);
|
||||
return MD5.create().digestHex(str).toUpperCase();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,8 +14,8 @@
|
|||
from ck_assessment_record car
|
||||
left join enterprises_unit eu on car.enterprises_unit_id = eu.snow_flake_id and eu.delete_flag = 0
|
||||
left join ck_project cp on car.ck_project_id = cp.snow_flake_id and cp.delete_flag = 0
|
||||
left join mini_program_user mpu on mpu.identity = 'police' and car.create_by = mpu.snow_flake_id and mpu.delete_flag = 0
|
||||
left join police_unit pu on mpu.unit_id = pu.snow_flake_id and pu.delete_flag = 0
|
||||
left join mini_program_user mpu on mpu.identity = 'police' and car.create_by = mpu.snow_flake_id
|
||||
left join police_unit pu on mpu.unit_id = pu.snow_flake_id
|
||||
left join ck_assessment_record_details card on car.snow_flake_id = card.ck_assessment_record_id and card.delete_flag = 0
|
||||
left join ck_standard cs on card.ck_standard_id = cs.snow_flake_id
|
||||
where car.delete_flag = 0
|
||||
|
|
|
@ -30,33 +30,64 @@
|
|||
</select>
|
||||
<resultMap id="SecurityUnitUseStatisticsDTOResultMap" type="com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO">
|
||||
<result
|
||||
column="securityUnitLegalPersonInfo"
|
||||
column="serviceProjectList"
|
||||
typeHandler="com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler"
|
||||
property="securityUnitLegalPersonInfo"/>
|
||||
property="serviceProjectList"/>
|
||||
</resultMap>
|
||||
<select id="securityUnitUseStatistics" resultMap="SecurityUnitUseStatisticsDTOResultMap">
|
||||
WITH security_user_counts AS (
|
||||
SELECT
|
||||
service_project_id,
|
||||
COUNT(1) AS securityUserTotal,
|
||||
SUM(IF(security_number != '', 1, 0)) AS haveCardSecurityUserCount
|
||||
FROM
|
||||
security_user
|
||||
WHERE delete_flag = 0
|
||||
GROUP BY service_project_id )
|
||||
select
|
||||
sp.snow_flake_id as 'serviceProjectId',
|
||||
eu.snow_flake_id as 'enterprisesUnitId',
|
||||
eu.name as 'enterprisesUnitName',
|
||||
eu.province,
|
||||
eu.city,
|
||||
eu.districts,
|
||||
eu.street,
|
||||
ad1.name as 'provinceName',
|
||||
ad2.name as 'cityName',
|
||||
ad3.name as 'districtsName',
|
||||
ad4.name as 'streetName',
|
||||
eu.address as 'address',
|
||||
pu.snow_flake_id as 'policeUnitId',
|
||||
pu.name as 'policeUnitName',
|
||||
su.name as 'securityUnitName',
|
||||
sp.name as 'serviceProjectName',
|
||||
sp.type as 'type',
|
||||
sp.two_type as 'twoType',
|
||||
sp.outsource_name as 'outsourceName',
|
||||
count(suu.snow_flake_id) as 'securityUserTotal',
|
||||
SUM(IF(suu.security_number != '', 1, 0)) as 'haveCardSecurityUserCount',
|
||||
sp.is_filing as 'isFiling',
|
||||
sp.id_number,
|
||||
su.legal_person_info as 'securityUnitLegalPersonInfo',
|
||||
mpu.name as 'serviceProjectManagerName',
|
||||
mpu.telephone as 'serviceProjectManagerTelephone'
|
||||
from police_unit pu
|
||||
json_arrayagg(
|
||||
json_object(
|
||||
'snowFlakeId', sp.snow_flake_id,
|
||||
'name', sp.name,
|
||||
'type', sp.type,
|
||||
'twoType', sp.two_type,
|
||||
'outsourceName', sp.outsource_name,
|
||||
'isFiling', sp.is_filing,
|
||||
'idNumber', sp.id_number,
|
||||
'securityUserTotal', suc.securityUserTotal,
|
||||
'haveCardSecurityUserCount', suc.haveCardSecurityUserCount,
|
||||
'securityUnitId',su.snow_flake_id,
|
||||
'securityUnitName',su.name,
|
||||
'securityUnitLegalPersonInfo',su.legal_person_info,
|
||||
'serviceProjectManagerName',mpu.name,
|
||||
'serviceProjectManagerTelephone',mpu.telephone
|
||||
)) as 'serviceProjectList'
|
||||
from
|
||||
police_unit pu
|
||||
join enterprises_unit eu on pu.snow_flake_id = eu.police_unit_id and eu.delete_flag = 0
|
||||
join service_project sp on eu.snow_flake_id = sp.enterprises_unit_id and sp.delete_flag = 0
|
||||
join security_unit su on sp.security_unit_id = su.snow_flake_id and su.delete_flag = 0
|
||||
LEFT join mini_program_user mpu on sp.project_manager_mini_program_user_id = mpu.snow_flake_id
|
||||
LEFT join security_user suu on suu.service_project_id = sp.snow_flake_id and suu.delete_flag = 0
|
||||
where pu.delete_flag = 0
|
||||
left join administrative_division ad1 on eu.province = ad1.code and ad1.delete_flag = 0
|
||||
left join administrative_division ad2 on eu.city = ad2.code and ad2.delete_flag = 0
|
||||
left join administrative_division ad3 on eu.districts = ad3.code and ad3.delete_flag = 0
|
||||
left join administrative_division ad4 on eu.street = ad4.code and ad4.delete_flag = 0
|
||||
left JOIN security_user_counts suc ON sp.snow_flake_id = suc.service_project_id
|
||||
where
|
||||
pu.delete_flag = 0
|
||||
<choose>
|
||||
<when test="level==1">
|
||||
and eu.province = #{code}
|
||||
|
@ -75,11 +106,11 @@
|
|||
</when>
|
||||
<otherwise>and eu.snow_flake_id = -1</otherwise>
|
||||
</choose>
|
||||
group by sp.snow_flake_id
|
||||
order by sp.create_time desc
|
||||
group by eu.snow_flake_id
|
||||
order by eu.create_time desc
|
||||
</select>
|
||||
<select id="serviceProjectUserRoster"
|
||||
resultType="com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO">
|
||||
<select id="securityUserRoster"
|
||||
resultType="com.changhu.pojo.dto.SecurityUserRosterDTO">
|
||||
select su.snow_flake_id,
|
||||
su.name,
|
||||
su.sex,
|
||||
|
@ -90,11 +121,21 @@
|
|||
suu.name as 'securityUnitName',
|
||||
su.security_number
|
||||
from enterprises_unit eu
|
||||
left join service_project sp on sp.enterprises_unit_id = eu.snow_flake_id and sp.delete_flag = 0
|
||||
left join security_user su on su.service_project_id = sp.snow_flake_id and su.delete_flag = 0
|
||||
left join security_unit suu on su.security_unit_id = suu.snow_flake_id and suu.delete_flag = 0
|
||||
LEFT JOIN service_project sp ON sp.enterprises_unit_id = eu.snow_flake_id AND sp.delete_flag = 0
|
||||
JOIN security_user su ON su.service_project_id = sp.snow_flake_id AND su.delete_flag = 0
|
||||
LEFT JOIN security_unit suu ON su.security_unit_id = suu.snow_flake_id AND suu.delete_flag = 0
|
||||
where eu.delete_flag = 0
|
||||
and sp.snow_flake_id = #{serviceProjectId}
|
||||
<choose>
|
||||
<when test="type==@com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType@ENTERPRISES_UNIT">
|
||||
and eu.snow_flake_id = #{id}
|
||||
</when>
|
||||
<when test="type==@com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType@SERVICE_PROJECT">
|
||||
and sp.snow_flake_id = #{id}
|
||||
</when>
|
||||
<otherwise>
|
||||
and eu.snow_flake_id = -1
|
||||
</otherwise>
|
||||
</choose>
|
||||
order by su.create_time desc
|
||||
</select>
|
||||
</mapper>
|
|
@ -1,8 +1,7 @@
|
|||
VITE_APP_NAME=超级后台
|
||||
VITE_APP_NAME=保安管理
|
||||
VITE_APP_ENV=development
|
||||
VITE_APP_PORT=1000
|
||||
VITE_DROP_CONSOLE=false
|
||||
VITE_APP_MODULE_NAME=superManagement
|
||||
|
||||
# axios
|
||||
VITE_APP_BASE_API=/api
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
VITE_APP_NAME=超级后台
|
||||
VITE_APP_NAME=保安管理
|
||||
VITE_APP_ENV=production
|
||||
VITE_APP_PORT=1001
|
||||
VITE_DROP_CONSOLE=true
|
||||
VITE_APP_MODULE_NAME=superManagement
|
||||
|
||||
# axios
|
||||
VITE_APP_BASE_API=/api
|
||||
|
|
|
@ -32,13 +32,13 @@ pipeline {
|
|||
remote.password = "${password}"
|
||||
}
|
||||
sshCommand remote: remote, command: 'pwd=$(pwd) echo "ssh连接成功!当前工作目录:$(pwd)"'
|
||||
sshCommand remote: remote, command: 'echo "删除:superManagement..."'
|
||||
sshRemove remote: remote, path: '/home/app/apps/1panel/apps/openresty/openresty/www/sites/policeSecurityServer/index/superManagement'
|
||||
sshCommand remote: remote, command: 'echo "删除:superManagement成功!"'
|
||||
sshCommand remote: remote, command: 'echo "删除:super_management..."'
|
||||
sshRemove remote: remote, path: '/home/app/apps/1panel/apps/openresty/openresty/www/sites/policeSecurityServer/index/super_management'
|
||||
sshCommand remote: remote, command: 'echo "删除:super_management成功!"'
|
||||
|
||||
sshCommand remote: remote, command: 'echo "将构建的superManagement发送到服务器..."'
|
||||
sshPut remote: remote, from: '/var/jenkins_home/workspace/警保联动-超级后台/superManagement/superManagement', into: '/home/app/apps/1panel/apps/openresty/openresty/www/sites/policeSecurityServer/index'
|
||||
sshCommand remote: remote, command: 'echo "superManagement发送成功!"'
|
||||
sshCommand remote: remote, command: 'echo "将构建的super_management发送到服务器..."'
|
||||
sshPut remote: remote, from: '/var/jenkins_home/workspace/警保联动-超级后台/superManagement/super_management', into: '/home/app/apps/1panel/apps/openresty/openresty/www/sites/policeSecurityServer/index'
|
||||
sshCommand remote: remote, command: 'echo "super_management发送成功!"'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<script type="module" src="/src/assets/iconfont/iconfont.js"></script>
|
||||
|
||||
<title>超级后台</title>
|
||||
<title>保安管理</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "supermanagement",
|
||||
"appName": "超级后台",
|
||||
"name": "super_management",
|
||||
"appName": "保安管理",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
|
@ -14,6 +14,7 @@
|
|||
"@vueuse/core": "^11.0.3",
|
||||
"ant-design-vue": "^4.2.3",
|
||||
"axios": "^1.7.5",
|
||||
"js-md5": "^0.8.3",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"pinia": "^2.2.2",
|
||||
|
|
|
@ -19,7 +19,6 @@ const props = withDefaults(defineProps<MapContainerProps>(), {
|
|||
viewMode: "3D",
|
||||
// 初始化地图级别
|
||||
zoom: 11,
|
||||
mapStyle: 'amap://styles/darkblue'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
collapsible
|
||||
>
|
||||
<div v-if="!collapsed" class="title flex-center">
|
||||
<div>超级后台</div>
|
||||
<div>{{ appInfo.appName }}</div>
|
||||
</div>
|
||||
<div v-else class="logo flex-center">
|
||||
<img src="@/assets/vue.svg" title="超级后台" alt="xx">
|
||||
<img src="@/assets/vue.svg" :title="appInfo.appName" alt="xx">
|
||||
</div>
|
||||
<SystemMenus/>
|
||||
</a-layout-sider>
|
||||
|
@ -40,6 +40,8 @@ import {ref} from "vue";
|
|||
import LayoutHeader from "@/components/layout/header/LayoutHeader.vue";
|
||||
import SystemMenus from "@/components/layout/SystemMenus.vue";
|
||||
|
||||
const appInfo = __APP_INFO
|
||||
|
||||
const collapsed = ref<boolean>(false);
|
||||
|
||||
const keepAliveNames = ref<string[]>([])
|
||||
|
|
|
@ -52,13 +52,6 @@ export const SYSTEM_MENUS: SystemMenu[] = [
|
|||
component: () => import('@/views/unitManage/securityUnit/index.vue')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
title: '数据总览',
|
||||
name: 'dataOverview',
|
||||
path: '/dataOverview',
|
||||
type: 'menu',
|
||||
isFull: true,
|
||||
component: () => import('@/views/data/dataOverview.vue')
|
||||
}, {
|
||||
title: '开放平台',
|
||||
name: 'openPlatform',
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
declare const __APP_ENV: ImportMetaEnv;
|
||||
declare const __APP_INFO: {
|
||||
moduleName: string,
|
||||
appName: string,
|
||||
version: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局返回
|
||||
|
|
|
@ -10,7 +10,7 @@ import {ROUTER_WHITE_LIST} from "@/config";
|
|||
* createWebHashHistory: 路径带#号 这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,影响SEO
|
||||
*/
|
||||
const router = createRouter({
|
||||
history: createWebHistory(__APP_ENV.VITE_APP_MODULE_NAME),
|
||||
history: createWebHistory(__APP_INFO.moduleName),
|
||||
routes: [...staticRouter],
|
||||
strict: false,
|
||||
scrollBehavior: () => ({left: 0, top: 0}),
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {EnterprisesUnit} from "@/types/views/data/dataOverview.ts";
|
||||
import {EnterprisesUnit} from "@/types/views/index.ts";
|
||||
|
||||
defineProps<EnterprisesUnit>()
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
<template>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>警保联动数据总览</h1>
|
||||
</div>
|
||||
<MapContainer class="map-container" ref="mapRef" :init-callback="initMap">
|
||||
<div class="left-panel panel">
|
||||
<h2>左侧统计面板</h2>
|
||||
<!-- 添加你的统计数据 -->
|
||||
</div>
|
||||
<div class="right-panel panel">
|
||||
<h2>右侧统计面板</h2>
|
||||
<!-- 添加你的统计数据 -->
|
||||
</div>
|
||||
</MapContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MapContainer from "@/components/aMap/MapContainer.vue";
|
||||
import {createApp, h, ref} from "vue";
|
||||
import {ComponentExposed} from "vue-component-type-helpers";
|
||||
import api from "@/axios";
|
||||
import EnterprisesUnitInfoWindowContent from "@/views/data/components/EnterprisesUnitInfoWindowContent.vue";
|
||||
import {EnterprisesUnit} from "@/types/views/data/dataOverview.ts";
|
||||
|
||||
const mapRef = ref<ComponentExposed<typeof MapContainer>>(null)
|
||||
|
||||
let infoWindow: AMap.InfoWindow = null;
|
||||
|
||||
const initMap = async () => {
|
||||
const {data} = await api.get<EnterprisesUnit[]>('/enterprisesUnit/mapPoint')
|
||||
mapRef.value?.mapInstance?.clearMap()
|
||||
const markers = data.map(item => {
|
||||
if (!item.point) {
|
||||
return null;
|
||||
}
|
||||
const marker = new AMap.Marker({
|
||||
icon: new AMap.Icon({
|
||||
image: __APP_ENV.VITE_APP_MINIO_URL + item.type.extData.icon,
|
||||
size: new AMap.Size(66, 66),
|
||||
imageSize: new AMap.Size(66, 66),
|
||||
}),
|
||||
position: item.point,
|
||||
offset: new AMap.Pixel(-33, -66)
|
||||
})
|
||||
marker.on('click', () => {
|
||||
if (!infoWindow) {
|
||||
infoWindow = new AMap.InfoWindow({
|
||||
isCustom: true,
|
||||
offset: new AMap.Pixel(66, -66),
|
||||
closeWhenClickMap: true
|
||||
});
|
||||
}
|
||||
const element = document.createElement('div')
|
||||
//h 渲染组件 跟vue一样的用法
|
||||
const _InfoWindow = h(EnterprisesUnitInfoWindowContent, item)
|
||||
const app = createApp(_InfoWindow)
|
||||
app.mount(element)
|
||||
infoWindow.setContent(element)
|
||||
infoWindow.open(mapRef.value?.mapInstance, item.point)
|
||||
})
|
||||
return marker
|
||||
}).filter(Boolean)
|
||||
mapRef.value.mapInstance.add(markers)
|
||||
mapRef.value.mapInstance.setFitView()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
color: #333;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.map-container {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
top: 100px; /* 调整顶部距离以避免与标题重叠 */
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 15%;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
width: 15%;
|
||||
right: 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,13 +1,112 @@
|
|||
<template>
|
||||
<div>
|
||||
index页面
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>警保联动数据总览</h1>
|
||||
</div>
|
||||
<MapContainer class="map-container" ref="mapRef" :init-callback="initMap">
|
||||
<div class="left-panel panel">
|
||||
<h2>左侧统计面板</h2>
|
||||
<!-- 添加你的统计数据 -->
|
||||
</div>
|
||||
<div class="right-panel panel">
|
||||
<h2>右侧统计面板</h2>
|
||||
<!-- 添加你的统计数据 -->
|
||||
</div>
|
||||
</MapContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MapContainer from "@/components/aMap/MapContainer.vue";
|
||||
import {createApp, h, ref} from "vue";
|
||||
import {ComponentExposed} from "vue-component-type-helpers";
|
||||
import api from "@/axios";
|
||||
import EnterprisesUnitInfoWindowContent from "@/views/components/EnterprisesUnitInfoWindowContent.vue";
|
||||
import {EnterprisesUnit} from "@/types/views/index.ts";
|
||||
|
||||
const mapRef = ref<ComponentExposed<typeof MapContainer>>(null)
|
||||
|
||||
let infoWindow: AMap.InfoWindow = null;
|
||||
|
||||
const initMap = async () => {
|
||||
const {data} = await api.get<EnterprisesUnit[]>('/super/index/mapPoint')
|
||||
mapRef.value?.mapInstance?.clearMap()
|
||||
const markers = data.map(item => {
|
||||
if (!item.point) {
|
||||
return null;
|
||||
}
|
||||
const marker = new AMap.Marker({
|
||||
icon: new AMap.Icon({
|
||||
image: __APP_ENV.VITE_APP_MINIO_URL + item.type.extData.icon,
|
||||
size: new AMap.Size(66, 66),
|
||||
imageSize: new AMap.Size(66, 66),
|
||||
}),
|
||||
position: item.point,
|
||||
offset: new AMap.Pixel(-33, -66)
|
||||
})
|
||||
marker.on('click', () => {
|
||||
if (!infoWindow) {
|
||||
infoWindow = new AMap.InfoWindow({
|
||||
isCustom: true,
|
||||
offset: new AMap.Pixel(66, -66),
|
||||
closeWhenClickMap: true
|
||||
});
|
||||
}
|
||||
const element = document.createElement('div')
|
||||
//h 渲染组件 跟vue一样的用法
|
||||
const _InfoWindow = h(EnterprisesUnitInfoWindowContent, item)
|
||||
const app = createApp(_InfoWindow)
|
||||
app.mount(element)
|
||||
infoWindow.setContent(element)
|
||||
infoWindow.open(mapRef.value?.mapInstance, item.point)
|
||||
})
|
||||
return marker
|
||||
}).filter(Boolean)
|
||||
mapRef.value.mapInstance.add(markers)
|
||||
mapRef.value.mapInstance.setFitView()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
color: #333;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.map-container {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
top: 100px; /* 调整顶部距离以避免与标题重叠 */
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 15%;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
width: 15%;
|
||||
right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -29,8 +29,8 @@ import TableProMax from "@/components/table/TableProMax.vue";
|
|||
import {TableProMaxProps} from "@/types/components/table";
|
||||
import {AccessKeyRes, GeneratedAccessKeyParams} from "@/types/views/openPlatform/openPlatform.ts";
|
||||
import {ComponentExposed} from "vue-component-type-helpers";
|
||||
import {md5} from "js-md5";
|
||||
import axios from "axios";
|
||||
import {useUserStore} from "@/stores/modules/userStore.ts";
|
||||
|
||||
type TableProps = TableProMaxProps<AccessKeyRes>
|
||||
|
||||
|
@ -123,29 +123,64 @@ const saveOrUpdateAccessKey = (params: GeneratedAccessKeyParams) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
const userStore = useUserStore()
|
||||
|
||||
const a = () => {
|
||||
axios.get('http://127.0.0.1:8765/open/dataView', {
|
||||
headers: {
|
||||
'X-API-KEY': '123',
|
||||
'access-key': '123',
|
||||
'time-stamp': '123',
|
||||
'sign': '123',
|
||||
'nonce': '123'
|
||||
const accessKey = "w2wzi0wefmmo6s735z2el8tfzitya5gj"
|
||||
const secretKey = "db1b5214-02ee-497f-957c-88323b4351bf"
|
||||
const now = Date.now()
|
||||
const params = {
|
||||
id: "1855852231820054528",
|
||||
type: 'ENTERPRISES_UNIT'
|
||||
}
|
||||
const sign = generatedSign(params, now, accessKey, secretKey)
|
||||
const headers2 = {
|
||||
'Access-Key': accessKey,
|
||||
'Time-Stamp': now,
|
||||
'Sign': sign
|
||||
}
|
||||
console.log(headers2);
|
||||
axios.get('http://127.0.0.1:8765/open/dataView', {
|
||||
params: params,
|
||||
headers: {
|
||||
...headers2
|
||||
}
|
||||
}).then(resp => {
|
||||
console.log(resp);
|
||||
})
|
||||
// api.get('/open/dataView', null, {
|
||||
// headers: {
|
||||
// 'X-API-KEY': '123',
|
||||
// 'access-key': '123',
|
||||
// 'time-stamp': '123',
|
||||
// 'sign': '123',
|
||||
// 'nonce': '123'
|
||||
// }
|
||||
|
||||
|
||||
// api.get('/open/dataView', paramsMap, {
|
||||
// headers
|
||||
// })
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
* @param params 参数
|
||||
* @param timeStamp 时间戳
|
||||
* @param accessKey
|
||||
* @param secretKey
|
||||
*/
|
||||
const generatedSign = (params: Record<string, any>,
|
||||
timeStamp: number,
|
||||
accessKey: string,
|
||||
secretKey: string): string => {
|
||||
const paramsMap = new Map<string, any>();
|
||||
if (params) {
|
||||
for (let paramsKey in params) {
|
||||
paramsMap.set(paramsKey, params[paramsKey])
|
||||
}
|
||||
}
|
||||
paramsMap.set('Access-Key', accessKey)
|
||||
paramsMap.set('Time-Stamp', timeStamp)
|
||||
// 将 Map 转换为数组并排序
|
||||
const entries = Array.from(paramsMap.entries());
|
||||
// 拼接成 URL 编码的字符串
|
||||
const encodedParams = entries
|
||||
.filter(([_, value]) => value !== null && value !== undefined && value !== '')
|
||||
.sort((a, b) => a[0].localeCompare(b[0], undefined, {sensitivity: 'base', caseFirst: 'upper'}))
|
||||
.map(([key, value]) => `${key}=${encodeURIComponent(value).replace(/%([0-9A-Fa-f]{2})/g, (_, p1) => '%' + p1.toUpperCase())}`)
|
||||
.join('&') + "&Secret-Key=" + secretKey;
|
||||
return md5(encodedParams).toUpperCase();
|
||||
}
|
||||
|
||||
const allowedResources = ref<SelectNodeVo<string>[]>([])
|
||||
|
|
|
@ -6,8 +6,6 @@ interface ImportMetaEnv {
|
|||
readonly VITE_APP_ENV: 'development' | 'production';
|
||||
// 启动端口
|
||||
readonly VITE_APP_PORT: number;
|
||||
// 模块名称
|
||||
readonly VITE_APP_MODULE_NAME: string;
|
||||
|
||||
// axios
|
||||
readonly VITE_APP_BASE_API: string;
|
||||
|
|
|
@ -4,6 +4,7 @@ import Components from 'unplugin-vue-components/vite';
|
|||
import {AntDesignVueResolver} from 'unplugin-vue-components/resolvers';
|
||||
import * as path from "node:path";
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import {appName, version, name as moduleName} from './package.json'
|
||||
|
||||
const pathSrc = path.resolve(__dirname, 'src');
|
||||
|
||||
|
@ -12,9 +13,14 @@ export default defineConfig(({mode}) => {
|
|||
const env: Record<string, string> = loadEnv(mode, process.cwd(), '')
|
||||
return {
|
||||
define: {
|
||||
__APP_ENV: JSON.stringify(env)
|
||||
__APP_ENV: JSON.stringify(env),
|
||||
__APP_INFO: JSON.stringify({
|
||||
moduleName,
|
||||
appName,
|
||||
version
|
||||
})
|
||||
},
|
||||
base: `/${env['VITE_APP_MODULE_NAME']}/`,
|
||||
base: `/${moduleName}/`,
|
||||
plugins: [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
|
@ -43,7 +49,7 @@ export default defineConfig(({mode}) => {
|
|||
}
|
||||
},
|
||||
build: {
|
||||
outDir: env['VITE_APP_MODULE_NAME'],
|
||||
outDir: moduleName,
|
||||
target: 'modules',
|
||||
chunkSizeWarningLimit: 1500,
|
||||
minify: 'terser',
|
||||
|
|
Loading…
Reference in New Issue