Merge branch 'main' of http://175.6.124.250:3100/luozhun/policeSecurity
This commit is contained in:
		
						commit
						909071396c
					
				| 
						 | 
				
			
			@ -2,4 +2,5 @@
 | 
			
		|||
target
 | 
			
		||||
logs
 | 
			
		||||
temp
 | 
			
		||||
HELP.md
 | 
			
		||||
HELP.md
 | 
			
		||||
rebel.xml
 | 
			
		||||
| 
						 | 
				
			
			@ -15,5 +15,17 @@ import java.lang.annotation.Target;
 | 
			
		|||
@Target(ElementType.FIELD)
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
public @interface Desensitized {
 | 
			
		||||
    /**
 | 
			
		||||
     * 脱敏类型
 | 
			
		||||
     *
 | 
			
		||||
     * @return 脱敏类型
 | 
			
		||||
     */
 | 
			
		||||
    DesensitizedUtil.DesensitizedType value();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否保留原字段
 | 
			
		||||
     *
 | 
			
		||||
     * @return 原字段+加密字段 的map
 | 
			
		||||
     */
 | 
			
		||||
    boolean keepOriginalField() default false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
package com.changhu.common.annotation;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/6/26 上午9:41
 | 
			
		||||
 * @desc RealDelete...
 | 
			
		||||
 */
 | 
			
		||||
@Target(ElementType.TYPE)
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Documented
 | 
			
		||||
public @interface RealDelete {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -35,19 +35,19 @@ public class GlobalCacheManager {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    static void initEnum() {
 | 
			
		||||
        log.info("初始化枚举字典数据----");
 | 
			
		||||
        //在包下扫描出BaseEnum的子类
 | 
			
		||||
        Set<Class<?>> classes = ClassUtil.scanPackageBySuper("com.changhu.common.db.enums", BaseEnum.class);
 | 
			
		||||
        //序列化方法
 | 
			
		||||
        Method superSerializer = ClassUtil.getDeclaredMethod(BaseEnum.class, "serializer");
 | 
			
		||||
        for (Class<?> aClass : classes) {
 | 
			
		||||
            Method childrenSerializer = ClassUtil.getDeclaredMethod(aClass, "serializer");
 | 
			
		||||
            BaseEnum<?>[] enumConstants = (BaseEnum<?>[]) aClass.getEnumConstants();
 | 
			
		||||
            if (enumConstants == null) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // 获取所有字段
 | 
			
		||||
            Field[] fields = aClass.getDeclaredFields();
 | 
			
		||||
            // 过滤出非静态字段并带有 IsExtData 注解的字段
 | 
			
		||||
            List<Field> extDataFields = Arrays.stream(fields)
 | 
			
		||||
            //子类是否重写了父类的serializer方法
 | 
			
		||||
            boolean isRewriteSerializer = !superSerializer.equals(ClassUtil.getDeclaredMethod(aClass, "serializer"));
 | 
			
		||||
            // 获取所有字段并过滤出非静态字段并带有 IsExtData 注解的字段
 | 
			
		||||
            List<Field> extDataFields = Arrays.stream(aClass.getDeclaredFields())
 | 
			
		||||
                    .filter(field -> !Modifier.isStatic(field.getModifiers()))
 | 
			
		||||
                    .filter(field -> field.getAnnotation(IsExtData.class) != null)
 | 
			
		||||
                    .collect(Collectors.toList());
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ public class GlobalCacheManager {
 | 
			
		|||
 | 
			
		||||
            Stream.of(enumConstants).forEach(v -> {
 | 
			
		||||
                //如果子类重写父类的方法 则直接使用子类的结果
 | 
			
		||||
                if (!superSerializer.equals(childrenSerializer)) {
 | 
			
		||||
                if (isRewriteSerializer) {
 | 
			
		||||
                    map.put(v, v.serializer());
 | 
			
		||||
                } else {
 | 
			
		||||
                    SelectNodeVo<Object> vo = new SelectNodeVo<>();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
package com.changhu.common.db.enums;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.IEnum;
 | 
			
		||||
import com.changhu.common.annotation.IsExtData;
 | 
			
		||||
import com.changhu.common.db.BaseEnum;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/9/5 上午11:04
 | 
			
		||||
 * @desc 服务项目二级类型
 | 
			
		||||
 */
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@Getter
 | 
			
		||||
public enum ServiceProjectTwoType implements BaseEnum<String>, IEnum<String> {
 | 
			
		||||
 | 
			
		||||
    SECURITY("outsource", "外包", ServiceProjectType.SECURITY.getValue()),
 | 
			
		||||
    PROPERTY_RECRUITMENT("property_recruitment", "物业自招", ServiceProjectType.SECURITY.getValue()),
 | 
			
		||||
    OTHER_RECRUITMENT("other_recruitment", "其他自招", ServiceProjectType.SECURITY.getValue()),
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private final String value;
 | 
			
		||||
    private final String label;
 | 
			
		||||
    @IsExtData
 | 
			
		||||
    private final String parentType;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,6 @@ import lombok.Getter;
 | 
			
		|||
public enum ServiceProjectType implements BaseEnum<String>, IEnum<String> {
 | 
			
		||||
 | 
			
		||||
    SECURITY("security", "安保"),
 | 
			
		||||
    PROPERTY("property", "物业"),
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
package com.changhu.common.pojo.vo;
 | 
			
		||||
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Builder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/11/19 上午9:17
 | 
			
		||||
 * @desc 脱敏数据
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@Builder
 | 
			
		||||
public class DesensitizedVo {
 | 
			
		||||
    /**
 | 
			
		||||
     * 原始数据
 | 
			
		||||
     */
 | 
			
		||||
    private String originalValue;
 | 
			
		||||
    /**
 | 
			
		||||
     * 脱敏数据
 | 
			
		||||
     */
 | 
			
		||||
    private String desensitizedValue;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
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;
 | 
			
		||||
import com.changhu.common.pojo.vo.SelectNodeVo;
 | 
			
		||||
import com.changhu.pojo.entity.AccessKeys;
 | 
			
		||||
import com.changhu.pojo.params.GeneratedAccessKeyParams;
 | 
			
		||||
import com.changhu.service.AccessKeysService;
 | 
			
		||||
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.core.annotation.AnnotatedElementUtils;
 | 
			
		||||
import org.springframework.web.bind.annotation.GetMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.PostMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestBody;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/11/19 上午10:38
 | 
			
		||||
 * @desc AccessKeysController...
 | 
			
		||||
 */
 | 
			
		||||
@Tag(name = "开放平台")
 | 
			
		||||
@RequestMapping("/accessKeys")
 | 
			
		||||
@JsonBody
 | 
			
		||||
@CheckUserType(userTypes = UserType.MANAGEMENT_SUPER)
 | 
			
		||||
public class AccessKeysController {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private AccessKeysService accessKeysService;
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/listOpenApi")
 | 
			
		||||
    public List<SelectNodeVo<String>> listOpenApi() {
 | 
			
		||||
        Class<OpenController> openControllerClass = OpenController.class;
 | 
			
		||||
        RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(openControllerClass, RequestMapping.class);
 | 
			
		||||
        String controllerPath = requestMapping.value()[0];
 | 
			
		||||
        return 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("methods", mReq.method()))
 | 
			
		||||
                            .build();
 | 
			
		||||
                })
 | 
			
		||||
                .toList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Operation(summary = "生成访问凭证")
 | 
			
		||||
    @PostMapping("/generatedAccessKey")
 | 
			
		||||
    public void generatedAccessKey(@RequestBody GeneratedAccessKeyParams params) {
 | 
			
		||||
        accessKeysService.generatedAccessKey(params);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Operation(summary = "访问凭证列表")
 | 
			
		||||
    @GetMapping("/tableList")
 | 
			
		||||
    public List<AccessKeys> tableList() {
 | 
			
		||||
        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)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,8 @@ 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.service.OpenApiService;
 | 
			
		||||
import io.swagger.v3.oas.annotations.Operation;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
| 
						 | 
				
			
			@ -51,4 +53,19 @@ public class OpenController {
 | 
			
		|||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
package com.changhu.mapper;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 | 
			
		||||
import com.changhu.pojo.entity.AccessKeys;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * access_keys (开放接口的授权)  固化类
 | 
			
		||||
 * author: luozhun
 | 
			
		||||
 * desc 由groovy脚本自动生成
 | 
			
		||||
 */
 | 
			
		||||
@Mapper
 | 
			
		||||
public interface AccessKeysMapper extends BaseMapper<AccessKeys> {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,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 org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Param;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,4 +25,22 @@ public interface OpenApiMapper {
 | 
			
		|||
     */
 | 
			
		||||
    List<SelectNodeVo<Long>> getEnterprisesUnit(@Param("code") String code,
 | 
			
		||||
                                                @Param("level") Integer level);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保安单位使用情况统计
 | 
			
		||||
     *
 | 
			
		||||
     * @param code  代码
 | 
			
		||||
     * @param level 等级
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    List<SecurityUnitUseStatisticsDTO> securityUnitUseStatistics(@Param("code") String code,
 | 
			
		||||
                                                                 @Param("level") Integer level);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取服务人员花名册
 | 
			
		||||
     *
 | 
			
		||||
     * @param serviceProjectId 服务项目id
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(@Param("serviceProjectId") Long serviceProjectId);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ package com.changhu.module.management.pojo.entity;
 | 
			
		|||
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableName;
 | 
			
		||||
import com.changhu.common.db.enums.IsOrNot;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectTwoType;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectType;
 | 
			
		||||
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
| 
						 | 
				
			
			@ -56,12 +57,22 @@ public class ServiceProject extends BaseEntity implements Serializable {
 | 
			
		|||
    private ServiceProjectType type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否自招保安(只有当type为property 此字段必填)
 | 
			
		||||
     * 二级类型(外包/物业自招/其他自招)
 | 
			
		||||
     */
 | 
			
		||||
    private IsOrNot isRecruitSecurity;
 | 
			
		||||
    private ServiceProjectTwoType twoType;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 证件号(服务类型为保安必填 服务类型为物业则需自招保安为必填)
 | 
			
		||||
     * 若二级类型选择外包 这里需填写外包公司名称
 | 
			
		||||
     */
 | 
			
		||||
    private String outsourceName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否备案
 | 
			
		||||
     */
 | 
			
		||||
    private IsOrNot isFiling;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 证件号(保安服务许可证/备案证)
 | 
			
		||||
     */
 | 
			
		||||
    private String idNumber;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package com.changhu.module.management.pojo.params;
 | 
			
		||||
 | 
			
		||||
import com.changhu.common.db.enums.IsOrNot;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectTwoType;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectType;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import jakarta.validation.constraints.NotNull;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,10 +33,16 @@ public class ServiceProjectSaveOrUpdateParams {
 | 
			
		|||
    @NotNull(message = "服务类型不能为空")
 | 
			
		||||
    private ServiceProjectType type;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "是否自招保安(只有当type为property 此字段必填)")
 | 
			
		||||
    private IsOrNot isRecruitSecurity;
 | 
			
		||||
    @Schema(description = "二级类型")
 | 
			
		||||
    private ServiceProjectTwoType twoType;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "证件号(服务类型为保安必填 服务类型为物业则需自招保安为必填)")
 | 
			
		||||
    @Schema(description = "外包公司名称")
 | 
			
		||||
    private String outsourceName;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "是否备案")
 | 
			
		||||
    private IsOrNot isFiling;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "证件号(保安服务许可证/备案证)")
 | 
			
		||||
    private String idNumber;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "服务区域面积")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package com.changhu.module.management.pojo.vo;
 | 
			
		||||
 | 
			
		||||
import com.changhu.common.db.enums.IsOrNot;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectTwoType;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectType;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
| 
						 | 
				
			
			@ -36,10 +37,13 @@ public class ServiceProjectPagerVo {
 | 
			
		|||
 | 
			
		||||
    @Schema(description = "服务类型")
 | 
			
		||||
    private ServiceProjectType type;
 | 
			
		||||
    @Schema(description = "二级类型")
 | 
			
		||||
    private ServiceProjectTwoType twoType;
 | 
			
		||||
    @Schema(description = "外包公司名称")
 | 
			
		||||
    private String outsourceName;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "是否自招保安(只有当type为property 此字段必填)")
 | 
			
		||||
    private IsOrNot isRecruitSecurity;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "是否备案")
 | 
			
		||||
    private IsOrNot isFiling;
 | 
			
		||||
    @Schema(description = "证件号(服务类型为保安必填 服务类型为物业则需自招保安为必填)")
 | 
			
		||||
    private String idNumber;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ package com.changhu.module.miniProgram.pojo.vo;
 | 
			
		|||
 | 
			
		||||
import cn.hutool.core.lang.Dict;
 | 
			
		||||
import com.changhu.common.db.enums.EnterprisesUnitType;
 | 
			
		||||
import com.changhu.common.db.enums.IsOrNot;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectType;
 | 
			
		||||
import com.changhu.module.management.pojo.model.ContactPersonInfo;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
| 
						 | 
				
			
			@ -69,8 +68,6 @@ public class IndexServiceProjectListVo {
 | 
			
		|||
        private String name;
 | 
			
		||||
        @Schema(description = "服务项目类型")
 | 
			
		||||
        private ServiceProjectType type;
 | 
			
		||||
        @Schema(description = "是否自招保安(只有当type为property 此字段必填)")
 | 
			
		||||
        private IsOrNot isRecruitSecurity;
 | 
			
		||||
        @Schema(description = "证件号(服务类型为保安必填 服务类型为物业则需自招保安为必填)")
 | 
			
		||||
        private String idNumber;
 | 
			
		||||
        @Schema(description = "服务区域面积")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ public class ServiceProjectSecurityUserPagerVo {
 | 
			
		|||
    @Schema(description = "名称")
 | 
			
		||||
    private String name;
 | 
			
		||||
 | 
			
		||||
    @Desensitized(value = DesensitizedUtil.DesensitizedType.MOBILE_PHONE)
 | 
			
		||||
    @Desensitized(value = DesensitizedUtil.DesensitizedType.MOBILE_PHONE, keepOriginalField = true)
 | 
			
		||||
    @Schema(description = "手机号")
 | 
			
		||||
    private String telephone;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ public class ServiceProjectSecurityUserPagerVo {
 | 
			
		|||
    @Schema(description = "籍贯")
 | 
			
		||||
    private String nativePlace;
 | 
			
		||||
 | 
			
		||||
    @Desensitized(value = DesensitizedUtil.DesensitizedType.ID_CARD)
 | 
			
		||||
    @Desensitized(value = DesensitizedUtil.DesensitizedType.ID_CARD, keepOriginalField = true)
 | 
			
		||||
    @Schema(description = "身份证")
 | 
			
		||||
    private String idCard;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
package com.changhu.pojo.dto;
 | 
			
		||||
 | 
			
		||||
import com.changhu.common.db.enums.IsOrNot;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectTwoType;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectType;
 | 
			
		||||
import com.changhu.module.management.pojo.model.LegalPersonInfo;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/11/18 上午10:32
 | 
			
		||||
 * @desc SecurityUnitUseStatisticsDTO...
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class SecurityUnitUseStatisticsDTO {
 | 
			
		||||
    @Schema(description = "服务项目id")
 | 
			
		||||
    private Long serviceProjectId;
 | 
			
		||||
    @Schema(description = "公安单位名称")
 | 
			
		||||
    private String policeUnitName;
 | 
			
		||||
    @Schema(description = "保安单位名称")
 | 
			
		||||
    private String securityUnitName;
 | 
			
		||||
    @Schema(description = "服务项目名称")
 | 
			
		||||
    private String serviceProjectName;
 | 
			
		||||
    @Schema(description = "保安服务类别")
 | 
			
		||||
    private ServiceProjectType type;
 | 
			
		||||
    @Schema(description = "二级类型")
 | 
			
		||||
    private ServiceProjectTwoType twoType;
 | 
			
		||||
    @Schema(description = "外包公司名称")
 | 
			
		||||
    private String outsourceName;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "保安人员总数")
 | 
			
		||||
    private Integer securityUserTotal;
 | 
			
		||||
    @Schema(description = "持证保安数量")
 | 
			
		||||
    private Integer haveCardSecurityUserCount;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "是否备案")
 | 
			
		||||
    private IsOrNot isFiling;
 | 
			
		||||
    @Schema(description = "证件号(保安服务许可证/备案证)")
 | 
			
		||||
    private String idNumber;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "保安单位法人信息")
 | 
			
		||||
    private LegalPersonInfo securityUnitLegalPersonInfo;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "项目经理")
 | 
			
		||||
    private String serviceProjectManager;
 | 
			
		||||
    @Schema(description = "项目经理联系方式")
 | 
			
		||||
    private String serviceProjectManagerTelephone;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
package com.changhu.pojo.dto;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.fastjson2.annotation.JSONField;
 | 
			
		||||
import com.changhu.common.db.enums.IsOrNot;
 | 
			
		||||
import com.changhu.common.db.enums.ServiceProjectType;
 | 
			
		||||
import com.changhu.common.db.enums.Sex;
 | 
			
		||||
import com.changhu.module.management.pojo.model.LegalPersonInfo;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +28,6 @@ public class ServiceProjectDTO {
 | 
			
		|||
    private String name;
 | 
			
		||||
    @Schema(description = "类型")
 | 
			
		||||
    private ServiceProjectType type;
 | 
			
		||||
    @Schema(description = "是否自招保安")
 | 
			
		||||
    private IsOrNot isRecruitSecurity;
 | 
			
		||||
    @Schema(description = "保安证号")
 | 
			
		||||
    private String idNumber;
 | 
			
		||||
    @Schema(description = "服务面积")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
package com.changhu.pojo.dto;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.DesensitizedUtil;
 | 
			
		||||
import com.changhu.common.annotation.Desensitized;
 | 
			
		||||
import com.changhu.common.db.enums.Sex;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/11/18 上午10:43
 | 
			
		||||
 * @desc ServiceProjectSecurityUserRosterDTO...
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class ServiceProjectSecurityUserRosterDTO {
 | 
			
		||||
    @Schema(description = "id")
 | 
			
		||||
    private Long snowFlakeId;
 | 
			
		||||
    @Schema(description = "名称")
 | 
			
		||||
    private String name;
 | 
			
		||||
    @Schema(description = "性别")
 | 
			
		||||
    private Sex sex;
 | 
			
		||||
    @Schema(description = "年龄")
 | 
			
		||||
    private Integer age;
 | 
			
		||||
    @Desensitized(value = DesensitizedUtil.DesensitizedType.ID_CARD, keepOriginalField = true)
 | 
			
		||||
    @Schema(description = "身份证")
 | 
			
		||||
    private String idCard;
 | 
			
		||||
    @Desensitized(value = DesensitizedUtil.DesensitizedType.MOBILE_PHONE, keepOriginalField = true)
 | 
			
		||||
    @Schema(description = "手机号")
 | 
			
		||||
    private String telephone;
 | 
			
		||||
    @Schema(description = "企事业单位名")
 | 
			
		||||
    private String enterprisesUnitName;
 | 
			
		||||
    @Schema(description = "保安单位名")
 | 
			
		||||
    private String securityUnitName;
 | 
			
		||||
    @Schema(description = "保安证号")
 | 
			
		||||
    private String securityNumber;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
package com.changhu.pojo.entity;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableField;
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableName;
 | 
			
		||||
import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
 | 
			
		||||
import com.changhu.common.db.enums.IsEnable;
 | 
			
		||||
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
import lombok.experimental.SuperBuilder;
 | 
			
		||||
 | 
			
		||||
import java.io.Serial;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 开放接口的授权 实体类
 | 
			
		||||
 * author: luozhun
 | 
			
		||||
 * desc 由groovy脚本自动生成
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@SuperBuilder
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@TableName(autoResultMap = true)
 | 
			
		||||
public class AccessKeys extends BaseEntity implements Serializable {
 | 
			
		||||
 | 
			
		||||
    @Serial
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 调用方
 | 
			
		||||
     */
 | 
			
		||||
    private String name;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 有效时间
 | 
			
		||||
     */
 | 
			
		||||
    private Integer effectiveTime;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * AccessKey
 | 
			
		||||
     */
 | 
			
		||||
    private String accessKey;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SecretKey
 | 
			
		||||
     */
 | 
			
		||||
    private String secretKey;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 允许访问的资源
 | 
			
		||||
     */
 | 
			
		||||
    @TableField(typeHandler = Fastjson2TypeHandler.class)
 | 
			
		||||
    private List<String> allowedResources;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否启用
 | 
			
		||||
     */
 | 
			
		||||
    private IsEnable isEnable;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 备注
 | 
			
		||||
     */
 | 
			
		||||
    private String remark;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
package com.changhu.pojo.params;
 | 
			
		||||
 | 
			
		||||
import com.changhu.common.db.enums.IsEnable;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import jakarta.validation.constraints.NotBlank;
 | 
			
		||||
import jakarta.validation.constraints.NotNull;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author 20252
 | 
			
		||||
 * @createTime 2024/11/19 上午11:19
 | 
			
		||||
 * @desc GeneratedAccessKeyParams...
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class GeneratedAccessKeyParams {
 | 
			
		||||
    private Long snowFlakeId;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "调用方")
 | 
			
		||||
    @NotBlank(message = "调用方不能为空")
 | 
			
		||||
    private String name;
 | 
			
		||||
 | 
			
		||||
    @NotNull(message = "请输入有效时间")
 | 
			
		||||
    @Schema(description = "有效时间")
 | 
			
		||||
    private Integer effectiveTime;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "允许访问的资源")
 | 
			
		||||
    private List<String> allowedResources;
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @Schema(description = "是否启用")
 | 
			
		||||
    private IsEnable isEnable;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "备注")
 | 
			
		||||
    private String remark;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
package com.changhu.service;
 | 
			
		||||
 | 
			
		||||
import com.baomidou.mybatisplus.extension.service.IService;
 | 
			
		||||
import com.changhu.pojo.entity.AccessKeys;
 | 
			
		||||
import com.changhu.pojo.params.GeneratedAccessKeyParams;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * access_keys (开放接口的授权)  服务类
 | 
			
		||||
 * author: luozhun
 | 
			
		||||
 * desc 由groovy脚本自动生成
 | 
			
		||||
 */
 | 
			
		||||
public interface AccessKeysService extends IService<AccessKeys> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 生成访问凭证
 | 
			
		||||
     *
 | 
			
		||||
     * @param params 参数
 | 
			
		||||
     */
 | 
			
		||||
    void generatedAccessKey(GeneratedAccessKeyParams params);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,7 +3,8 @@ package com.changhu.service;
 | 
			
		|||
import com.changhu.common.pojo.vo.SelectNodeVo;
 | 
			
		||||
import com.changhu.pojo.dto.DataViewDTO;
 | 
			
		||||
import com.changhu.pojo.dto.EnterprisesUnitDetailDTO;
 | 
			
		||||
import com.changhu.pojo.queryParams.OpenGetEnterprisesUnit;
 | 
			
		||||
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
 | 
			
		||||
import com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,4 +37,21 @@ public interface OpenApiService {
 | 
			
		|||
     * @return 数据总览
 | 
			
		||||
     */
 | 
			
		||||
    DataViewDTO dataView();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保安单位使用情况统计
 | 
			
		||||
     *
 | 
			
		||||
     * @param code  代码
 | 
			
		||||
     * @param level 等级
 | 
			
		||||
     * @return 使用情况
 | 
			
		||||
     */
 | 
			
		||||
    List<SecurityUnitUseStatisticsDTO> securityUnitUseStatistics(String code, Integer level);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 服务项目安保人员花名册
 | 
			
		||||
     *
 | 
			
		||||
     * @param serviceProjectId 服务项目id
 | 
			
		||||
     * @return 花名册
 | 
			
		||||
     */
 | 
			
		||||
    List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(Long serviceProjectId);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
package com.changhu.service.impl;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.bean.BeanUtil;
 | 
			
		||||
import cn.hutool.core.util.IdUtil;
 | 
			
		||||
import cn.hutool.core.util.RandomUtil;
 | 
			
		||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 | 
			
		||||
import com.changhu.mapper.AccessKeysMapper;
 | 
			
		||||
import com.changhu.pojo.entity.AccessKeys;
 | 
			
		||||
import com.changhu.pojo.params.GeneratedAccessKeyParams;
 | 
			
		||||
import com.changhu.service.AccessKeysService;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * access_keys (开放接口的授权)  服务实现类
 | 
			
		||||
 * author: luozhun
 | 
			
		||||
 * desc 由groovy脚本自动生成
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
public class AccessKeysServiceImpl extends ServiceImpl<AccessKeysMapper, AccessKeys> implements AccessKeysService {
 | 
			
		||||
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generatedAccessKey(GeneratedAccessKeyParams params) {
 | 
			
		||||
        AccessKeys accessKeys = BeanUtil.copyProperties(params, AccessKeys.class);
 | 
			
		||||
        if (accessKeys.getSnowFlakeId() == null) {
 | 
			
		||||
            // 生成一个32位的随机字符串,包含大小写字母和数字
 | 
			
		||||
            String accessKey = RandomUtil.randomString(RandomUtil.BASE_CHAR + RandomUtil.BASE_NUMBER, 32);
 | 
			
		||||
            String secretKey = IdUtil.randomUUID();
 | 
			
		||||
            accessKeys.setAccessKey(accessKey);
 | 
			
		||||
            accessKeys.setSecretKey(secretKey);
 | 
			
		||||
        }
 | 
			
		||||
        this.saveOrUpdate(accessKeys);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        String randomPart = RandomUtil.randomString(RandomUtil.BASE_CHAR + RandomUtil.BASE_NUMBER, 32);
 | 
			
		||||
        System.out.println(randomPart);
 | 
			
		||||
        System.out.println(IdUtil.randomUUID());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,8 @@ import com.changhu.module.management.service.ServiceProjectService;
 | 
			
		|||
import com.changhu.module.miniProgram.pojo.entity.SecurityUser;
 | 
			
		||||
import com.changhu.pojo.dto.DataViewDTO;
 | 
			
		||||
import com.changhu.pojo.dto.EnterprisesUnitDetailDTO;
 | 
			
		||||
import com.changhu.pojo.queryParams.OpenGetEnterprisesUnit;
 | 
			
		||||
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
 | 
			
		||||
import com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO;
 | 
			
		||||
import com.changhu.service.OpenApiService;
 | 
			
		||||
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
 | 
			
		||||
import lombok.SneakyThrows;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,4 +96,14 @@ public class OpenApiServiceImpl implements OpenApiService {
 | 
			
		|||
        countDownLatch.await();
 | 
			
		||||
        return dataViewDTO;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<SecurityUnitUseStatisticsDTO> securityUnitUseStatistics(String code, Integer level) {
 | 
			
		||||
        return openApiMapper.securityUnitUseStatistics(code, level);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<ServiceProjectSecurityUserRosterDTO> serviceProjectUserRoster(Long serviceProjectId) {
 | 
			
		||||
        return openApiMapper.serviceProjectUserRoster(serviceProjectId);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,16 @@
 | 
			
		|||
package com.changhu.support.fastjson2.filter;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.annotation.AnnotationUtil;
 | 
			
		||||
import cn.hutool.core.util.ClassUtil;
 | 
			
		||||
import cn.hutool.core.util.DesensitizedUtil;
 | 
			
		||||
import com.alibaba.fastjson2.filter.ValueFilter;
 | 
			
		||||
import com.changhu.common.annotation.Desensitized;
 | 
			
		||||
import com.changhu.common.pojo.vo.DesensitizedVo;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -19,41 +23,62 @@ public class DesensitizedFilter implements ValueFilter {
 | 
			
		|||
 | 
			
		||||
    public static final DesensitizedFilter instance = new DesensitizedFilter();
 | 
			
		||||
 | 
			
		||||
    private final Map<String, DesensitizedUtil.DesensitizedType> cache = new ConcurrentHashMap<>();
 | 
			
		||||
    private static final Map<FieldKey, Desensitized> cache = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
    private DesensitizedFilter() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        preProcessAnnotations();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object apply(Object object, String name, Object value) {
 | 
			
		||||
        //只针对string类型生效
 | 
			
		||||
        if (value instanceof String strValue && !strValue.isEmpty()) {
 | 
			
		||||
            try {
 | 
			
		||||
                String path = object.getClass().getName() + "$$" + name;
 | 
			
		||||
                //先看是否有缓存
 | 
			
		||||
                if (cache.containsKey(path)) {
 | 
			
		||||
                    return DesensitizedUtil.desensitized(strValue, cache.get(path));
 | 
			
		||||
            FieldKey fieldKey = new FieldKey(object.getClass(), name);
 | 
			
		||||
            Desensitized desensitized = cache.get(fieldKey);
 | 
			
		||||
            if (desensitized != null) {
 | 
			
		||||
                if (desensitized.keepOriginalField()) {
 | 
			
		||||
                    return DesensitizedVo.builder()
 | 
			
		||||
                            .originalValue(strValue)
 | 
			
		||||
                            .desensitizedValue(DesensitizedUtil.desensitized(strValue, desensitized.value()))
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                Class<?> aClass = object.getClass();
 | 
			
		||||
                Field declaredField = aClass.getDeclaredField(name);
 | 
			
		||||
                Desensitized annotation = declaredField.getAnnotation(Desensitized.class);
 | 
			
		||||
                if (annotation == null) {
 | 
			
		||||
                    return value;
 | 
			
		||||
                }
 | 
			
		||||
                //加入缓存
 | 
			
		||||
                cache.put(path, annotation.value());
 | 
			
		||||
                return DesensitizedUtil.desensitized(strValue, annotation.value());
 | 
			
		||||
            } catch (NoSuchFieldException e) {
 | 
			
		||||
                return value;
 | 
			
		||||
            } catch (SecurityException e) {
 | 
			
		||||
                log.error("字段:{} 安全异常: {}", name, e.getMessage());
 | 
			
		||||
                return null;
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                log.error("数据脱敏失败:{}", e.getMessage());
 | 
			
		||||
                return null;
 | 
			
		||||
                return DesensitizedUtil.desensitized(strValue, desensitized.value());
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            return value;
 | 
			
		||||
        }
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 脱敏字段预处理 初始化缓存信息
 | 
			
		||||
     */
 | 
			
		||||
    private static void preProcessAnnotations() {
 | 
			
		||||
        Set<Class<?>> classes = ClassUtil.scanPackage("com.changhu");
 | 
			
		||||
        for (Class<?> clazz : classes) {
 | 
			
		||||
            Field[] fields = clazz.getDeclaredFields();
 | 
			
		||||
            for (Field field : fields) {
 | 
			
		||||
                Desensitized annotation = AnnotationUtil.getAnnotation(field, Desensitized.class);
 | 
			
		||||
                if (annotation != null) {
 | 
			
		||||
                    cache.put(new FieldKey(clazz, field.getName()), annotation);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private record FieldKey(Class<?> clazz, String fieldName) {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean equals(Object o) {
 | 
			
		||||
            if (this == o) return true;
 | 
			
		||||
            if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
            FieldKey fieldKey = (FieldKey) o;
 | 
			
		||||
            return clazz.equals(fieldKey.clazz) && fieldName.equals(fieldKey.fieldName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int hashCode() {
 | 
			
		||||
            return clazz.hashCode() ^ fieldName.hashCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,4 +28,73 @@
 | 
			
		|||
        </choose>
 | 
			
		||||
        order by eu.create_time desc
 | 
			
		||||
    </select>
 | 
			
		||||
    <resultMap id="SecurityUnitUseStatisticsDTOResultMap" type="com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO">
 | 
			
		||||
        <result
 | 
			
		||||
                column="securityUnitLegalPersonInfo"
 | 
			
		||||
                typeHandler="com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler"
 | 
			
		||||
                property="securityUnitLegalPersonInfo"/>
 | 
			
		||||
    </resultMap>
 | 
			
		||||
    <select id="securityUnitUseStatistics" resultMap="SecurityUnitUseStatisticsDTOResultMap">
 | 
			
		||||
        select
 | 
			
		||||
        sp.snow_flake_id as 'serviceProjectId',
 | 
			
		||||
        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
 | 
			
		||||
        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
 | 
			
		||||
        <choose>
 | 
			
		||||
            <when test="level==1">
 | 
			
		||||
                and eu.province = #{code}
 | 
			
		||||
            </when>
 | 
			
		||||
            <when test="level==2">
 | 
			
		||||
                and eu.city = #{code}
 | 
			
		||||
            </when>
 | 
			
		||||
            <when test="level==3">
 | 
			
		||||
                and eu.districts = #{code}
 | 
			
		||||
            </when>
 | 
			
		||||
            <when test="level==4">
 | 
			
		||||
                and eu.street = #{code}
 | 
			
		||||
            </when>
 | 
			
		||||
            <when test="level==5">
 | 
			
		||||
                and pu.code = #{code}
 | 
			
		||||
            </when>
 | 
			
		||||
            <otherwise>and eu.snow_flake_id = -1</otherwise>
 | 
			
		||||
        </choose>
 | 
			
		||||
        group by sp.snow_flake_id
 | 
			
		||||
        order by sp.create_time desc
 | 
			
		||||
    </select>
 | 
			
		||||
    <select id="serviceProjectUserRoster"
 | 
			
		||||
            resultType="com.changhu.pojo.dto.ServiceProjectSecurityUserRosterDTO">
 | 
			
		||||
        select su.snow_flake_id,
 | 
			
		||||
               su.name,
 | 
			
		||||
               su.sex,
 | 
			
		||||
               TIMESTAMPDIFF(YEAR, su.date_of_birth, CURDATE()) AS 'age',
 | 
			
		||||
               su.id_card,
 | 
			
		||||
               su.telephone,
 | 
			
		||||
               eu.name                                          as 'enterprisesUnitName',
 | 
			
		||||
               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
 | 
			
		||||
        where eu.delete_flag = 0
 | 
			
		||||
          and sp.snow_flake_id = #{serviceProjectId}
 | 
			
		||||
        order by su.create_time desc
 | 
			
		||||
    </select>
 | 
			
		||||
</mapper>
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,6 @@
 | 
			
		|||
                       'securityUnitName',su.name,
 | 
			
		||||
                       'name', sp.name,
 | 
			
		||||
                       'type', sp.type,
 | 
			
		||||
                       'isRecruitSecurity', sp.is_recruit_security,
 | 
			
		||||
                       'idNumber', sp.id_number,
 | 
			
		||||
                       'serviceArea', sp.service_area,
 | 
			
		||||
                       'buildingTotal', sp.building_total,
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +64,7 @@
 | 
			
		|||
                                                        'idCard',mpu.id_card),
 | 
			
		||||
                       'remark', sp.remark)) as 'service_project_list'
 | 
			
		||||
        from enterprises_unit eu
 | 
			
		||||
                 join service_project sp on eu.snow_flake_id = sp.enterprises_unit_id and sp.delete_flag = 0
 | 
			
		||||
                 left join service_project sp on eu.snow_flake_id = sp.enterprises_unit_id and sp.delete_flag = 0
 | 
			
		||||
                 left 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 and mpu.delete_flag = 0
 | 
			
		||||
                 left join administrative_division ad1 on eu.province = ad1.code and ad1.delete_flag = 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,5 +59,11 @@ export const SYSTEM_MENUS: SystemMenu[] = [
 | 
			
		|||
        type: 'menu',
 | 
			
		||||
        isFull: true,
 | 
			
		||||
        component: () => import('@/views/data/dataOverview.vue')
 | 
			
		||||
    }, {
 | 
			
		||||
        title: '开放平台',
 | 
			
		||||
        name: 'openPlatform',
 | 
			
		||||
        path: '/openPlatform',
 | 
			
		||||
        type: 'menu',
 | 
			
		||||
        component: () => import('@/views/openPlatform/index.vue')
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,3 +62,11 @@ interface BaseEnum<T> {
 | 
			
		|||
    label: string,
 | 
			
		||||
    extData?: Record<string, any>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 脱敏数据
 | 
			
		||||
 */
 | 
			
		||||
interface DesensitizedVo {
 | 
			
		||||
    originalValue: string;
 | 
			
		||||
    desensitizedValue: string;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ export const useUserStore = defineStore({
 | 
			
		|||
        getTokenInfo: (state): TokenInfo => state.tokenInfo as TokenInfo,
 | 
			
		||||
    },
 | 
			
		||||
    persist: {
 | 
			
		||||
        key: "useUserStore",
 | 
			
		||||
        key: "spUserStore",
 | 
			
		||||
        storage: window.localStorage,
 | 
			
		||||
        paths: ["tokenInfo"],
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
// Parameter interface
 | 
			
		||||
import {BaseTableRowRecord} from "@/types/components/table";
 | 
			
		||||
 | 
			
		||||
export interface GeneratedAccessKeyParams {
 | 
			
		||||
    /* */
 | 
			
		||||
    snowFlakeId?: string;
 | 
			
		||||
    /*调用方 */
 | 
			
		||||
    name: string;
 | 
			
		||||
    /*有效时间 */
 | 
			
		||||
    effectiveTime: number;
 | 
			
		||||
    /*允许访问的资源 */
 | 
			
		||||
    allowedResources?: string[];
 | 
			
		||||
    /*是否启用,可用值:TRUE,FALSE */
 | 
			
		||||
    isEnable: number;
 | 
			
		||||
    /*备注 */
 | 
			
		||||
    remark?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Response interface
 | 
			
		||||
export interface AccessKeyRes extends BaseTableRowRecord {
 | 
			
		||||
    name: string;
 | 
			
		||||
    effectiveTime: number;
 | 
			
		||||
    accessKey: string;
 | 
			
		||||
    secretKey: string;
 | 
			
		||||
    allowedResources: string[];
 | 
			
		||||
    isEnable: BaseEnum<number>;
 | 
			
		||||
    remark: string;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,163 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <table-pro-max
 | 
			
		||||
      ref="tableRef"
 | 
			
		||||
      :request-api="reqApi"
 | 
			
		||||
      :is-pagination="false"
 | 
			
		||||
      :columns="columns"
 | 
			
		||||
  >
 | 
			
		||||
    <template #tableHeader>
 | 
			
		||||
      <a-space>
 | 
			
		||||
        <a-button class="btn-success" @click="saveOrUpdateAccessKey({
 | 
			
		||||
            name: '',
 | 
			
		||||
            effectiveTime: 300000,
 | 
			
		||||
            isEnable:0
 | 
			
		||||
            })">添加accessKey
 | 
			
		||||
        </a-button>
 | 
			
		||||
        <a-button @click="a">a</a-button>
 | 
			
		||||
      </a-space>
 | 
			
		||||
    </template>
 | 
			
		||||
  </table-pro-max>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="tsx">
 | 
			
		||||
import {message} from "ant-design-vue";
 | 
			
		||||
import api from "@/axios";
 | 
			
		||||
import {onMounted, ref} from "vue";
 | 
			
		||||
import {submitSimpleFormModal} from "@/components/tsx/ModalPro.tsx";
 | 
			
		||||
import {dictSelectNodes} from "@/config/dict.ts";
 | 
			
		||||
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 axios from "axios";
 | 
			
		||||
import {useUserStore} from "@/stores/modules/userStore.ts";
 | 
			
		||||
 | 
			
		||||
type TableProps = TableProMaxProps<AccessKeyRes>
 | 
			
		||||
 | 
			
		||||
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null)
 | 
			
		||||
const columns: TableProps['columns'] = [
 | 
			
		||||
  {
 | 
			
		||||
    dataIndex: 'name',
 | 
			
		||||
    title: '调用方'
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'accessKey',
 | 
			
		||||
    title: 'accessKey'
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'secretKey',
 | 
			
		||||
    title: 'secretKey'
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'effectiveTime',
 | 
			
		||||
    title: '有效时间(ms)'
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'isEnable',
 | 
			
		||||
    title: '状态',
 | 
			
		||||
    customRender: ({text}) => <a-tag color={text.extData?.color}>{text.label}</a-tag>
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'remark',
 | 
			
		||||
    title: '备注',
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'createTime',
 | 
			
		||||
    title: '创建时间'
 | 
			
		||||
  }, {
 | 
			
		||||
    dataIndex: 'opt',
 | 
			
		||||
    title: '操作',
 | 
			
		||||
    customRender: ({record}) => {
 | 
			
		||||
      return <a-space>
 | 
			
		||||
        <a-button class="btn-warn" onClick={() => saveOrUpdateAccessKey({
 | 
			
		||||
          snowFlakeId: record.snowFlakeId,
 | 
			
		||||
          name: record.name,
 | 
			
		||||
          effectiveTime: record.effectiveTime,
 | 
			
		||||
          isEnable: record.isEnable.value,
 | 
			
		||||
          allowedResources: record.allowedResources,
 | 
			
		||||
          remark: record.remark
 | 
			
		||||
        })}>编辑
 | 
			
		||||
        </a-button>
 | 
			
		||||
 | 
			
		||||
      </a-space>
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const reqApi: TableProps["requestApi"] = () => api.get('/accessKeys/tableList')
 | 
			
		||||
 | 
			
		||||
const saveOrUpdateAccessKey = (params: GeneratedAccessKeyParams) => {
 | 
			
		||||
  submitSimpleFormModal<GeneratedAccessKeyParams>({
 | 
			
		||||
    title: '',
 | 
			
		||||
    formOptions: {
 | 
			
		||||
      name: {
 | 
			
		||||
        type: 'input',
 | 
			
		||||
        label: '调用方',
 | 
			
		||||
        required: true
 | 
			
		||||
      },
 | 
			
		||||
      effectiveTime: {
 | 
			
		||||
        type: 'inputNumber',
 | 
			
		||||
        label: '有效时间(ms)',
 | 
			
		||||
        required: true,
 | 
			
		||||
        componentsProps: {
 | 
			
		||||
          precision: 0
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      allowedResources: {
 | 
			
		||||
        type: 'select',
 | 
			
		||||
        label: '可访问资源',
 | 
			
		||||
        options: allowedResources.value,
 | 
			
		||||
        componentsProps: {
 | 
			
		||||
          mode: 'multiple'
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      isEnable: {
 | 
			
		||||
        type: "radioGroup",
 | 
			
		||||
        label: '是否启用',
 | 
			
		||||
        options: dictSelectNodes("IsEnable")
 | 
			
		||||
      },
 | 
			
		||||
      remark: {
 | 
			
		||||
        type: 'inputTextArea',
 | 
			
		||||
        label: '备注'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    formParams: {...params},
 | 
			
		||||
    submit: async (p) => {
 | 
			
		||||
      const resp = await api.post('/accessKeys/generatedAccessKey', p, {loading: true})
 | 
			
		||||
      message.success(resp.message)
 | 
			
		||||
      await tableRef.value?.requestGetTableData()
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
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'
 | 
			
		||||
    }
 | 
			
		||||
  }).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'
 | 
			
		||||
  //   }
 | 
			
		||||
  // })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const allowedResources = ref<SelectNodeVo<string>[]>([])
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  api.get<SelectNodeVo<string>[]>('/accessKeys/listOpenApi').then(resp => {
 | 
			
		||||
    allowedResources.value = resp.data
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
		Loading…
	
		Reference in New Issue