Merge remote-tracking branch 'origin/master'
New file |
| | |
| | | package com.panzhihua.common.enums; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 是否状态 |
| | | * |
| | | * @author huanghongfa |
| | | */ |
| | | @Getter |
| | | public enum PopulIsOkEnum |
| | | { |
| | | YES(1, "是"), NO(0, "否"); |
| | | |
| | | private final Integer code; |
| | | private final String name; |
| | | |
| | | PopulIsOkEnum(Integer code, String name) |
| | | { |
| | | this.code = code; |
| | | this.name = name; |
| | | } |
| | | |
| | | public static int getCodeByName(String name) { |
| | | for (PopulIsOkEnum item : PopulIsOkEnum.values()) { |
| | | if (item.name.equals(name)) { |
| | | return item.getCode(); |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | public static String getCnDescByName(Integer code) { |
| | | for (PopulIsOkEnum item : PopulIsOkEnum.values()) { |
| | | if (item.code.equals(code)) { |
| | | return item.getName(); |
| | | } |
| | | } |
| | | return "否"; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.enums; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 政治面貌 |
| | | * |
| | | * @author huanghongfa |
| | | */ |
| | | @Getter |
| | | public enum PopulPoliticalOutlookEnum |
| | | { |
| | | PARTY_MEMBER(1, "中共党员"), |
| | | PROBATIONARY_PARTY_MEMBER(2, "中共预备党员"), |
| | | COMMUNIST_YOUTH_LEAGUE_MEMBER(3, "共青团员"), |
| | | MEMBERS_OF_THE_DEMOCRATIC_REVOLUTION(4, "民革党员"), |
| | | LEAGUE_MEMBER(5, "民盟盟员"), |
| | | MEMBER_OF_CIVIL_CONSTRUCTION(6, "民建会员"), |
| | | A_MEMBER_OF_THE_RURAL_LABOR_PARTY(8, "农工党党员"), |
| | | ZHIGONG_PARTY_MEMBER(9, "致公党党员"), |
| | | MEMBER_OF_JIUSAN_SOCIETY(10, "九三学社社员"), |
| | | MEMBER_OF_THE_TAIWAN_LEAGUE(11, "台盟盟员"), |
| | | INDEPENDENTS(12, "无党派人士"), |
| | | THE_MASSES(13, "群众"); |
| | | |
| | | private final Integer code; |
| | | private final String name; |
| | | |
| | | PopulPoliticalOutlookEnum(Integer code, String name) |
| | | { |
| | | this.code = code; |
| | | this.name = name; |
| | | } |
| | | |
| | | public static int getCodeByName(String name) { |
| | | for (PopulPoliticalOutlookEnum item : PopulPoliticalOutlookEnum.values()) { |
| | | if (item.name.equals(name)) { |
| | | return item.getCode(); |
| | | } |
| | | } |
| | | return 13; |
| | | } |
| | | |
| | | public static String getCnDescByName(Integer code) { |
| | | for (PopulPoliticalOutlookEnum item : PopulPoliticalOutlookEnum.values()) { |
| | | if (item.code.equals(code)) { |
| | | return item.getName(); |
| | | } |
| | | } |
| | | return "群众"; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.enums; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 性别枚举 |
| | | * |
| | | * @author huanghongfa |
| | | */ |
| | | @Getter |
| | | public enum PopulSexEnum { |
| | | nan(1, "男"), nv(2, "女"), weizhi(3, "未知"); |
| | | |
| | | private final Integer code; |
| | | private final String name; |
| | | |
| | | PopulSexEnum(Integer code, String name) { |
| | | this.code = code; |
| | | this.name = name; |
| | | } |
| | | |
| | | public static int getCodeByName(String name) { |
| | | for (PopulSexEnum item : PopulSexEnum.values()) { |
| | | if (item.name.equals(name)) { |
| | | return item.getCode(); |
| | | } |
| | | } |
| | | return 3; |
| | | } |
| | | |
| | | public static String getCnDescByName(Integer code) { |
| | | for (PopulSexEnum item : PopulSexEnum.values()) { |
| | | if (item.code.equals(code)) { |
| | | return item.getName(); |
| | | } |
| | | } |
| | | return "未知"; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | import com.alibaba.excel.event.AnalysisEventListener; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.google.common.collect.Lists; |
| | | import com.panzhihua.common.enums.PopulIsOkEnum; |
| | | import com.panzhihua.common.enums.PopulPoliticalOutlookEnum; |
| | | import com.panzhihua.common.enums.PopulSexEnum; |
| | | import com.panzhihua.common.exceptions.ServiceException; |
| | | import com.panzhihua.common.model.vos.R; |
| | | import com.panzhihua.common.model.vos.community.ComMngPopulationServeExcelVO; |
| | |
| | | for (Map<Integer, String> oneData : list) { |
| | | ComMngPopulationServeExcelVO vo = new ComMngPopulationServeExcelVO(); |
| | | vo.setName(oneData.get(0)); |
| | | vo.setSex(oneData.get(1)); |
| | | vo.setSex(PopulSexEnum.getCodeByName(oneData.get(1))); |
| | | if(oneData.get(2) == null){ |
| | | throw new ServiceException("500", "年龄不可为空:第" + index + "行,第3列"); |
| | | } |
| | | vo.setAge(Integer.valueOf(oneData.get(2))); |
| | | vo.setIsRent(oneData.get(3)); |
| | | if(oneData.get(3) == null){ |
| | | throw new ServiceException("500", "是否租住不可为空:第" + index + "行,第4列"); |
| | | } |
| | | vo.setIsRent(PopulIsOkEnum.getCodeByName(oneData.get(3))); |
| | | vo.setRoad(oneData.get(4)); |
| | | if(oneData.get(5) == null){ |
| | | throw new ServiceException("500", "门牌号不可为空:第" + index + "行,第6列"); |
| | | } |
| | | vo.setDoorNo(Integer.valueOf(oneData.get(5))); |
| | | vo.setFloor(oneData.get(6)); |
| | | if(oneData.get(7) == null){ |
| | | throw new ServiceException("500", "单元号不可为空:第" + index + "行,第8列"); |
| | | } |
| | | vo.setUnitNo(Integer.valueOf(oneData.get(7))); |
| | | if(oneData.get(8) == null){ |
| | | throw new ServiceException("500", "户室不可为空:第" + index + "行,第9列"); |
| | | } |
| | | vo.setHouseNo(Integer.valueOf(oneData.get(8))); |
| | | vo.setNation(oneData.get(9)); |
| | | vo.setPoliticalOutlook(oneData.get(10)); |
| | | if(oneData.get(10) == null){ |
| | | throw new ServiceException("500", "政治面貌不可为空:第" + index + "行,第11列"); |
| | | } |
| | | vo.setPoliticalOutlook(PopulPoliticalOutlookEnum.getCodeByName(oneData.get(10))); |
| | | vo.setCardNo(oneData.get(11)); |
| | | vo.setPhone(oneData.get(12)); |
| | | vo.setNativePlace(oneData.get(13)); |
| | |
| | | throw new ServiceException(r.getMsg()); |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | throw new ServiceException("500", "填写数据类型错误:第" + index + "行" + e.getMessage()); |
| | | throw new ServiceException("500", "填写数据格式错误:第" + index + "行" + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | |
| | | package com.panzhihua.common.model.dtos.community; |
| | | |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptQuery; |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptQueryClass; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import java.io.Serializable; |
| | |
| | | * 实有人口DTO |
| | | */ |
| | | @Data |
| | | @EncryptQueryClass |
| | | public class ComMngPopulationDTO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | |
| | | * 身份证号码 |
| | | */ |
| | | @ApiModelProperty(value="身份证号码") |
| | | @EncryptQuery |
| | | private String cardNo; |
| | | /** |
| | | * 街路巷 |
New file |
| | |
| | | package com.panzhihua.common.model.helper; |
| | | |
| | | import javax.crypto.*; |
| | | import javax.crypto.spec.IvParameterSpec; |
| | | import javax.crypto.spec.PBEKeySpec; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.security.InvalidKeyException; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.spec.KeySpec; |
| | | import java.util.Arrays; |
| | | import java.util.Base64; |
| | | |
| | | /** |
| | | * AES 工具类 |
| | | */ |
| | | public class AESUtil { |
| | | |
| | | |
| | | /** |
| | | * AES 256 加密 |
| | | * @param strToEncrypt 要加密的字符串 |
| | | * @param secKey 秘钥 |
| | | * @param salt 盐 |
| | | * @return 加密后的字符串 |
| | | */ |
| | | public static String encrypt256(String strToEncrypt, String secKey, String salt) { |
| | | try { |
| | | byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
| | | IvParameterSpec ivspec = new IvParameterSpec(iv); |
| | | |
| | | SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); |
| | | KeySpec spec = new PBEKeySpec(secKey.toCharArray(), salt.getBytes(), 65536, 256); |
| | | SecretKey tmp = factory.generateSecret(spec); |
| | | SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); |
| | | |
| | | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
| | | cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec); |
| | | return Base64.getEncoder() |
| | | .encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8))); |
| | | } catch (Exception e) { |
| | | System.out.println("Error while encrypting: " + e.toString()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * AES 256 解密 |
| | | * @param strToDecrypt 要解密的字符串 |
| | | * @param secKey 秘钥 |
| | | * @param salt 盐 |
| | | * @return 解密后的字符串 |
| | | */ |
| | | public static String decrypt256( String strToDecrypt, String secKey, String salt) { |
| | | try { |
| | | byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
| | | IvParameterSpec ivspec = new IvParameterSpec(iv); |
| | | |
| | | SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); |
| | | KeySpec spec = new PBEKeySpec(secKey.toCharArray(), salt.getBytes(), 65536, 256); |
| | | SecretKey tmp = factory.generateSecret(spec); |
| | | SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); |
| | | |
| | | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); |
| | | cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec); |
| | | return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))); |
| | | } catch (Exception e) { |
| | | System.out.println("Error while decrypting: " + e.toString()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | private static SecretKeySpec secretKey; |
| | | private static byte[] key; |
| | | |
| | | public static void setKey(String myKey) |
| | | { |
| | | MessageDigest sha = null; |
| | | try { |
| | | key = myKey.getBytes("UTF-8"); |
| | | sha = MessageDigest.getInstance("SHA-1"); |
| | | key = sha.digest(key); |
| | | key = Arrays.copyOf(key, 16); |
| | | secretKey = new SecretKeySpec(key, "AES"); |
| | | } |
| | | catch (NoSuchAlgorithmException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * AES 128 加密 |
| | | * @param strToEncrypt 要加密的字符串 |
| | | * @param secret 秘钥 |
| | | * @return 加密后的字符串 |
| | | */ |
| | | public static String encrypt128(String strToEncrypt, String secret) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException { |
| | | setKey(secret); |
| | | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); |
| | | cipher.init(Cipher.ENCRYPT_MODE, secretKey); |
| | | return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))); |
| | | } |
| | | |
| | | /** |
| | | * AES 128 解密 |
| | | * @param strToDecrypt 要解密的字符串 |
| | | * @param secret 秘钥 |
| | | * @return 解密后的字符串 |
| | | */ |
| | | public static String decrypt128(String strToDecrypt, String secret) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException { |
| | | setKey(secret); |
| | | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); |
| | | cipher.init(Cipher.DECRYPT_MODE, secretKey); |
| | | return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))); |
| | | } |
| | | |
| | | } |
| | | |
| | | class AES256Example { |
| | | public static void main(String[] args) { |
| | | String originalString = "howtodoinjava.com"; |
| | | |
| | | String secKey = "this is my super secrt key"; |
| | | String salt = "salt for me!!!"; |
| | | String encryptedString = AESUtil.encrypt256(originalString, secKey, salt); |
| | | String decryptedString = AESUtil.decrypt256(encryptedString, secKey, salt); |
| | | |
| | | System.out.println(originalString); |
| | | System.out.println(encryptedString); |
| | | System.out.println(decryptedString); |
| | | } |
| | | } |
| | | |
| | | class AES128Example { |
| | | public static void main(String[] args) { |
| | | String[] originalString = new String[]{"51011234567892013", "13612345678", "四川省成都市高新区", "四川省成都市高新"}; |
| | | |
| | | String key = "5165465461dsfas"; |
| | | |
| | | |
| | | Arrays.stream(originalString).forEach(os ->{ |
| | | try { |
| | | String encryptedString = AESUtil.encrypt128(os, key); |
| | | String decryptedString = AESUtil.decrypt128(encryptedString, key); |
| | | |
| | | System.out.println(os); |
| | | System.out.println(encryptedString); |
| | | System.out.println(decryptedString); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | }); |
| | | } |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.encrypt; |
| | | |
| | | import com.panzhihua.common.model.helper.AESUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Field; |
| | | |
| | | /*** |
| | | * 默认实现: AES 128 加密、解密 |
| | | * 可自定义实现{@link IEncryptDecrypt }接口 |
| | | * |
| | | * @author cedoo |
| | | * @since 2021-4-1 10:40:52 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class DoEncrytDecrypt implements IEncryptDecrypt{ |
| | | |
| | | @Value("${domain.aesKey:}") |
| | | private String aesKey; |
| | | |
| | | @Override |
| | | public <T> T encrypt(Field[] declaredFields, T parameterObject) throws IllegalAccessException { |
| | | for (Field field : declaredFields) { |
| | | if (field.getType() == String.class) { |
| | | field.setAccessible(true); |
| | | for (Annotation annotation : field.getAnnotations()) { |
| | | if (annotation.annotationType() == EncryptDecryptField.class || annotation.annotationType() == EncryptQuery.class) { |
| | | log.debug("加密字段:" + field.getName()); |
| | | Object fieldVal = field.get(parameterObject); |
| | | if(fieldVal!=null) { |
| | | try { |
| | | String encryptedStr = AESUtil.encrypt128(fieldVal.toString(), aesKey); |
| | | field.set(parameterObject, encryptedStr); |
| | | }catch (Exception e){ |
| | | log.debug("加密失败"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return parameterObject; |
| | | } |
| | | |
| | | @Override |
| | | public <T> T decrypt(T result) throws IllegalAccessException { |
| | | |
| | | for (Field field : result.getClass().getDeclaredFields()) { |
| | | try { |
| | | field.setAccessible(true); |
| | | if (field.get(result) != null) { |
| | | for (Annotation annotation : field.getAnnotations()) { |
| | | if (annotation.annotationType() == EncryptDecryptField.class) { |
| | | log.debug("解密密字段:" + field.getName()); |
| | | String fieldVal = field.get(result).toString(); |
| | | try { |
| | | String decryptVal = AESUtil.decrypt128(fieldVal, aesKey); |
| | | field.set(result, decryptVal != null ? decryptVal : fieldVal); |
| | | }catch (Exception e){ |
| | | /** |
| | | * 兼容原始未加密数据 |
| | | */ |
| | | field.set(result, fieldVal); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } catch (IllegalAccessException e) { |
| | | throw e; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.encrypt; |
| | | |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 需要加解密的类注解 |
| | | */ |
| | | @Documented |
| | | @Inherited |
| | | @Target({ ElementType.TYPE }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | public @interface EncryptDecryptClass { |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.encrypt; |
| | | |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 加密字段注解 |
| | | */ |
| | | @Documented |
| | | @Inherited |
| | | @Target({ ElementType.FIELD }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | public @interface EncryptDecryptField { |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.encrypt; |
| | | |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 加密字段搜索 |
| | | */ |
| | | @Documented |
| | | @Inherited |
| | | @Target({ ElementType.FIELD }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | public @interface EncryptQuery { |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.encrypt; |
| | | |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 加密字段搜索 |
| | | */ |
| | | @Documented |
| | | @Inherited |
| | | @Target({ ElementType.TYPE }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | public @interface EncryptQueryClass { |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.encrypt; |
| | | |
| | | import java.lang.reflect.Field; |
| | | |
| | | public interface IEncryptDecrypt { |
| | | |
| | | /** |
| | | * 加密方法 |
| | | * @param declaredFields 反射bean成员变量 |
| | | * @param parameterObject Mybatis入参 |
| | | * @param <T> |
| | | * @return |
| | | */ |
| | | public <T> T encrypt(Field[] declaredFields, T parameterObject) throws IllegalAccessException; |
| | | |
| | | |
| | | /** |
| | | * 解密方法 |
| | | * @param result Mybatis 返回值,需要判断是否是ArrayList类型 |
| | | * @param <T> |
| | | * @return |
| | | */ |
| | | public <T> T decrypt(T result) throws IllegalAccessException; |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.sensitive; |
| | | |
| | | |
| | | import java.util.function.Function; |
| | | |
| | | public interface Desensitizer extends Function<String,String> { |
| | | |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.sensitive; |
| | | |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Target(ElementType.FIELD) |
| | | public @interface Sensitive { |
| | | SensitiveStrategy strategy(); |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.helper.sensitive; |
| | | |
| | | /** |
| | | * 脱敏策略. |
| | | * |
| | | * @author cedoo |
| | | * @since 2021-4-1 10:40:52 |
| | | */ |
| | | public enum SensitiveStrategy { |
| | | /** |
| | | * Username sensitive strategy. |
| | | */ |
| | | USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), |
| | | /** |
| | | * Id card sensitive type. |
| | | */ |
| | | ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")), |
| | | /** |
| | | * Phone sensitive type. |
| | | */ |
| | | PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), |
| | | |
| | | /** |
| | | * Address sensitive type. |
| | | */ |
| | | ADDRESS(s -> s.replaceAll("(\\S{8})\\S{4}(\\S*)\\S{4}", "$1****$2****")), |
| | | |
| | | /** |
| | | * 中文地址 |
| | | */ |
| | | ADDRESS_CN(s -> { |
| | | //List<Word> words = WordSegmenter.seg(s); |
| | | //Arrays.toString(words.toArray()); |
| | | return s.replaceAll("(\\S{8})(\\S*)\\S{4}", "$1****$2****"); |
| | | }); |
| | | |
| | | private final Desensitizer desensitizer; |
| | | |
| | | SensitiveStrategy(Desensitizer desensitizer) { |
| | | this.desensitizer = desensitizer; |
| | | } |
| | | |
| | | /** |
| | | * Gets desensitizer. |
| | | * |
| | | * @return the desensitizer |
| | | */ |
| | | public Desensitizer getDesensitizer() { |
| | | return desensitizer; |
| | | } |
| | | } |
New file |
| | |
| | | package com.panzhihua.common.model.vos.community; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class ComMngPopulationExcelVo { |
| | | |
| | | @ExcelProperty(value = "姓名" ,index = 0) |
| | | private String name; |
| | | |
| | | @ExcelProperty(value = "性别" ,index = 1) |
| | | private String sex; |
| | | |
| | | @ExcelProperty(value = "年龄" ,index = 2) |
| | | private Integer age; |
| | | |
| | | @ExcelProperty(value = "是否租住" ,index = 3) |
| | | private String isRent; |
| | | |
| | | @ExcelProperty(value = "街路巷" ,index = 4) |
| | | private String road; |
| | | |
| | | @ExcelProperty(value = "楼排号" ,index = 5) |
| | | private Integer doorNo; |
| | | |
| | | @ExcelProperty(value = "门牌号" ,index = 6) |
| | | private String floor; |
| | | |
| | | @ExcelProperty(value = "单元号" ,index = 7) |
| | | private Integer unitNo; |
| | | |
| | | @ExcelProperty(value = "户室" ,index = 8) |
| | | private Integer houseNo; |
| | | |
| | | @ExcelProperty(value = "民族" ,index = 9) |
| | | private String nation; |
| | | |
| | | @ExcelProperty(value = "政治面貌" ,index = 10) |
| | | private String politicalOutlook; |
| | | |
| | | @ExcelProperty(value = "身份证号码" ,index = 11) |
| | | private String cardNo; |
| | | |
| | | @ExcelProperty(value = "联系方式" ,index = 12) |
| | | private String phone; |
| | | |
| | | @ExcelProperty(value = "籍贯" ,index = 13) |
| | | private String nativePlace; |
| | | |
| | | @ExcelProperty(value = "工作单位" ,index = 14) |
| | | private String workCompany; |
| | | |
| | | @ExcelProperty(value = "标签" ,index = 15) |
| | | private String label; |
| | | } |
| | |
| | | private String name; |
| | | |
| | | @ExcelProperty(value = "性别(1.男 2.女 3.未知)", index = 1) |
| | | private String sex; |
| | | private Integer sex; |
| | | |
| | | @ExcelProperty(value = "年龄", index = 2) |
| | | private Integer age; |
| | | |
| | | @ExcelProperty(value = "是否租住", index = 3) |
| | | private String isRent; |
| | | private Integer isRent; |
| | | |
| | | @ExcelProperty(value = "街路巷", index = 4) |
| | | private String road; |
| | |
| | | private String nation; |
| | | |
| | | @ExcelProperty(value = "政治面貌(1.中共党员2.中共预备党员3.共青团员4.民革党员5.民盟盟员6.民建会员7.8.农工党党员9.致公党党员10.九三学社社员11.台盟盟员12.无党派人士13.群众)", index = 10) |
| | | private String politicalOutlook; |
| | | private Integer politicalOutlook; |
| | | |
| | | @ExcelProperty(value = "身份证号码", index = 11) |
| | | private String cardNo; |
| | |
| | | package com.panzhihua.common.model.vos.community; |
| | | |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptDecryptField; |
| | | import com.panzhihua.common.model.helper.sensitive.Sensitive; |
| | | import com.panzhihua.common.model.helper.sensitive.SensitiveStrategy; |
| | | import com.panzhihua.common.model.vos.user.ComMngFamilyInfoVO; |
| | | import com.panzhihua.common.validated.AddGroup; |
| | | import io.swagger.annotations.ApiModel; |
| | |
| | | */ |
| | | @Data |
| | | @ApiModel("实有人口表") |
| | | @EncryptDecryptClass |
| | | public class ComMngPopulationVO { |
| | | |
| | | /** |
| | |
| | | */ |
| | | @ApiModelProperty("身份证号码") |
| | | @NotBlank(groups = {AddGroup.class},message = "身份证号码不可为空") |
| | | @EncryptDecryptField |
| | | @Sensitive(strategy = SensitiveStrategy.ID_CARD) |
| | | private String cardNo; |
| | | /** |
| | | * 街路巷 |
| | |
| | | */ |
| | | @ApiModelProperty("联系方式") |
| | | @NotBlank(groups = {AddGroup.class},message = "联系方式不可为空") |
| | | @EncryptDecryptField |
| | | @Sensitive(strategy = SensitiveStrategy.PHONE) |
| | | private String phone; |
| | | /** |
| | | * 备注 |
| | |
| | | @ApiModelProperty("是否租住") |
| | | @NotBlank(groups = {AddGroup.class},message = "是否租住不可为空") |
| | | private Integer isRent; |
| | | |
| | | /** |
| | | * 性别(1.男 2.女 3.未知) |
| | | */ |
| | | public interface sex{ |
| | | int nan = 1; |
| | | int nv = 2; |
| | | int no = 3; |
| | | } |
| | | |
| | | /** |
| | | * 是否租住 |
| | | */ |
| | | public interface isOk{ |
| | | int yes = 1; |
| | | int no = 0; |
| | | } |
| | | |
| | | /** |
| | | * 政治面貌 |
| | | */ |
| | | public interface politicalOutlook{ |
| | | int dang = 1; |
| | | int tuan = 3; |
| | | int wu = 12; |
| | | int qun = 13; |
| | | int no = 13; |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 查询省下所有区域 tree结构 |
| | | * |
| | | * @param provinceAdcode |
| | | * @return |
| | | * @param provinceAdcode 省份code |
| | | * @return 查询结果 |
| | | */ |
| | | @GetMapping("/common/data/area/all") |
| | | R getCityTreeByProvinceCode(@RequestParam(value = "provinceAdcode") Integer provinceAdcode); |
| | |
| | | /** |
| | | * 分页查询街道 |
| | | * |
| | | * @param pageComStreetDTO |
| | | * @return |
| | | * @param pageComStreetDTO 查询条件 |
| | | * @return 查询结果 |
| | | */ |
| | | @PostMapping("/pagestreet") |
| | | R pageStreet(@RequestBody PageComStreetDTO pageComStreetDTO); |
| | |
| | | /** |
| | | * 新增街道 |
| | | * |
| | | * @param comStreetVOO |
| | | * @return |
| | | * @param comStreetVOO 需要新增的街道数据 |
| | | * @return 新增结果 |
| | | */ |
| | | @PostMapping("/addstreet") |
| | | R pageStreet(@RequestBody ComStreetVO comStreetVOO); |
| | |
| | | /** |
| | | * 删除街道 |
| | | * |
| | | * @param Ids |
| | | * @return |
| | | * @param Ids 需要删除街道id集合 |
| | | * @return 删除结果 |
| | | */ |
| | | @PostMapping("/deletestreet") |
| | | R delectStreat(@RequestBody List<Long> Ids); |
| | |
| | | /** |
| | | * 查询街道 |
| | | * |
| | | * @param comStreetVO |
| | | * @return |
| | | * @param comStreetVO 查询条件 |
| | | * @return 返回结果 |
| | | */ |
| | | @PostMapping("/liststreet") |
| | | R listStreet(ComStreetVO comStreetVO); |
| | |
| | | /** |
| | | * 分页查询实有房屋 |
| | | * |
| | | * @param pageComMngVillageDTO |
| | | * @return |
| | | * @param pageComMngVillageDTO 查询条件 |
| | | * @return 返回结果 |
| | | */ |
| | | @PostMapping("/pagevillage") |
| | | R pageVillage(@RequestBody PageComMngVillageDTO pageComMngVillageDTO); |
| | |
| | | /** |
| | | * 新增实有房屋 |
| | | * |
| | | * @param comMngVillageVO |
| | | * @return |
| | | * @param comMngVillageVO 新增的实有房屋数据 |
| | | * @return 新增结果 |
| | | */ |
| | | @PostMapping("/addvillage") |
| | | R addVillage(@RequestBody ComMngVillageVO comMngVillageVO); |
| | |
| | | /** |
| | | * 删除实有房屋 |
| | | * |
| | | * @param Ids |
| | | * @return |
| | | * @param Ids 需要删除的id集合 |
| | | * @return 删除结果 |
| | | */ |
| | | @PostMapping("/deletevillage") |
| | | R delectVillage(@RequestBody List<Long> Ids); |
| | |
| | | /** |
| | | * 查询实有房屋 |
| | | * |
| | | * @param comMngVillageVO |
| | | * @return |
| | | * @param comMngVillageVO 查询条件 |
| | | * @return 查询结果 |
| | | */ |
| | | @PostMapping("/listvillage") |
| | | R listVillage(ComMngVillageVO comMngVillageVO); |
| | |
| | | /** |
| | | * 批量导入实有房屋 |
| | | * |
| | | * @param list |
| | | * @param communityId |
| | | * @return |
| | | * @param list 实有房屋数据 |
| | | * @param communityId 社区id |
| | | * @return 导入结果 |
| | | */ |
| | | @PostMapping("/village/import") |
| | | R listSaveVillageServeExcelVO(@RequestBody List<ComMngVillageServeExcelVO> list, @RequestParam(value = "communityId") Long communityId); |
| | |
| | | /** |
| | | * 批量导入实有人口 |
| | | * |
| | | * @param list |
| | | * @param communityId |
| | | * @return |
| | | * @param list 实有人口数据 |
| | | * @param communityId 社区id |
| | | * @return 导入结果 |
| | | */ |
| | | @PostMapping("/common/data/population/import") |
| | | R listSavePopulationServeExcelVO(@RequestBody List<ComMngPopulationServeExcelVO> list, @RequestParam(value = "communityId") Long communityId); |
| | |
| | | @PostMapping("/common/data/population/delete") |
| | | R deletePopulations(@RequestBody List<Long> Ids); |
| | | |
| | | /** |
| | | * 根据社区id查询所有实有人口 |
| | | * @param communityId 社区id |
| | | * @return 查询结果 |
| | | */ |
| | | @PostMapping("/common/data/population/getAll") |
| | | R getPopulationListByCommunityId(@RequestParam(value = "communityId") Long communityId); |
| | | |
| | | /** |
| | | * 根据id集合查询实有人口 |
| | | * @param Ids 实有人口id集合 |
| | | * @return 查询结果 |
| | | */ |
| | | @PostMapping("/common/data/population/getList") |
| | | R getPopulationLists(@RequestBody List<Long> Ids); |
| | | |
| | | } |
| | |
| | | import com.alibaba.excel.enums.CellExtraTypeEnum; |
| | | import com.alibaba.excel.write.metadata.WriteSheet; |
| | | import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.jcraft.jsch.SftpException; |
| | | import com.panzhihua.common.constants.Constants; |
| | | import com.panzhihua.common.controller.BaseController; |
| | | import com.panzhihua.common.enums.PopulIsOkEnum; |
| | | import com.panzhihua.common.enums.PopulPoliticalOutlookEnum; |
| | | import com.panzhihua.common.enums.PopulSexEnum; |
| | | import com.panzhihua.common.listen.*; |
| | | import com.panzhihua.common.model.dtos.community.*; |
| | | import com.panzhihua.common.model.dtos.user.*; |
| | |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiParam; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | |
| | | data.add("阿里巴巴"); |
| | | return data; |
| | | } |
| | | |
| | | @ApiOperation(value = "实有人口-数据导出") |
| | | @PostMapping("/population/data/export") |
| | | public R dataExportPopulation(@RequestBody List<Long> Ids) { |
| | | //获取登陆用户 |
| | | LoginUserInfoVO loginUserInfo = this.getLoginUserInfo(); |
| | | //获取登陆用户绑定社区id |
| | | Long communityId = loginUserInfo.getCommunityId(); |
| | | //生成动态模板excel通过ftp工具上传到主节点,然后返回模板下载地址 |
| | | String ftpUrl = "/mnt/data/web/excel/"; |
| | | String name = "实有人口数据.xlsx"; |
| | | try { |
| | | SFTPUtil sftp = new SFTPUtil(userName, password, host, port); |
| | | sftp.login(); |
| | | boolean existDir = sftp.isExistDir(ftpUrl + name); |
| | | if (!existDir) { |
| | | String property = System.getProperty("user.dir"); |
| | | String fileName = property + File.separator + name; |
| | | // 这里 需要指定写用哪个class去写 |
| | | // 这里 需要指定写用哪个class去写 |
| | | ExcelWriter excelWriter = null; |
| | | InputStream inputStream = null; |
| | | try { |
| | | List<ComMngPopulationVO> populList = null; |
| | | if(Ids.size() > 0){//导出部分 |
| | | populList = JSON.parseArray(JSON.toJSONString(communityService.getPopulationLists(Ids).getData()),ComMngPopulationVO.class); |
| | | }else{//导出全部 |
| | | populList = JSON.parseArray(JSON.toJSONString(communityService.getPopulationListByCommunityId(communityId).getData()),ComMngPopulationVO.class); |
| | | } |
| | | |
| | | List<ComMngPopulationExcelVo> populationExcelVoList = new ArrayList<>(); |
| | | if(populList != null && populList.size() > 0){ |
| | | for (ComMngPopulationVO popul:populList){ |
| | | ComMngPopulationExcelVo populationExcelVo = new ComMngPopulationExcelVo(); |
| | | BeanUtils.copyProperties(popul,populationExcelVo); |
| | | //设置性别 |
| | | populationExcelVo.setSex(PopulSexEnum.getCnDescByName(popul.getSex())); |
| | | //设置政治面貌 |
| | | populationExcelVo.setPoliticalOutlook(PopulPoliticalOutlookEnum.getCnDescByName(popul.getPoliticalOutlook())); |
| | | //设置是否租住 |
| | | populationExcelVo.setIsRent(PopulIsOkEnum.getCnDescByName(popul.getIsRent())); |
| | | populationExcelVoList.add(populationExcelVo); |
| | | } |
| | | } |
| | | |
| | | excelWriter = EasyExcel.write(fileName, ComMngPopulationExcelVo.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).registerWriteHandler(new CustomSheetWriteHandler()).build(); |
| | | WriteSheet writeSheet = EasyExcel.writerSheet("实有人口导出数据").build(); |
| | | excelWriter.write(populationExcelVoList, writeSheet); |
| | | excelWriter.finish(); |
| | | File file = new File(fileName); |
| | | inputStream = new FileInputStream(file); |
| | | sftp.uploadMore(ftpUrl, name, inputStream); |
| | | sftp.logout(); |
| | | inputStream.close(); |
| | | String absolutePath = file.getAbsolutePath(); |
| | | boolean delete = file.delete(); |
| | | log.info("删除excel【{}】结果【{}】", absolutePath, delete); |
| | | } finally { |
| | | // 千万别忘记finish 会帮忙关闭流 |
| | | if (inputStream != null) { |
| | | inputStream.close(); |
| | | } |
| | | if (excelWriter != null) { |
| | | excelWriter.finish(); |
| | | } |
| | | } |
| | | } |
| | | return R.ok(excelUrl + name); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("文件传输失败【{}】", e.getMessage()); |
| | | return R.fail(); |
| | | } |
| | | } |
| | | } |
| | |
| | | LOGGER.info("第{}个Sheet写入成功。", writeSheetHolder.getSheetNo()); |
| | | |
| | | // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行 |
| | | CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2000, 2, 2); |
| | | CellRangeAddressList cellRangeAddressList1 = new CellRangeAddressList(1, 2000, 4 ,4); |
| | | CellRangeAddressList cellRangeAddressList2 = new CellRangeAddressList(1, 2000, 11 ,11); |
| | | CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2000, 1, 1); |
| | | CellRangeAddressList cellRangeAddressList1 = new CellRangeAddressList(1, 2000, 3 ,3); |
| | | CellRangeAddressList cellRangeAddressList2 = new CellRangeAddressList(1, 2000, 10 ,10); |
| | | DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); |
| | | DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"是", "否"}); |
| | | DataValidationConstraint constraint1 = helper.createExplicitListConstraint(new String[] {"中共党员","中共预备党员","共青团员","民革党员","民盟盟员","民建会员","农工党党员","致公党党员","九三学社社员","台盟盟员","无党派人士","群众"}); |
| | |
| | | public R deletePopulations(@RequestBody List<Long> Ids) { |
| | | return comMngPopulationService.deletePopulations(Ids); |
| | | } |
| | | |
| | | /** |
| | | * 根据社区id查询所有实有人口 |
| | | * @param communityId 社区id |
| | | * @return 查询结果 |
| | | */ |
| | | @ApiOperation(value = "根据社区id查询所有实有人口") |
| | | @PostMapping("/population/getAll") |
| | | public R getPopulationListByCommunityId(@RequestParam(value = "communityId") Long communityId) { |
| | | return comMngPopulationService.getPopulationListByCommunityId(communityId); |
| | | } |
| | | |
| | | /** |
| | | * 根据id集合查询实有人口 |
| | | * @param Ids 实有人口id集合 |
| | | * @return 查询结果 |
| | | */ |
| | | @ApiOperation(value = "批量删除实有人口") |
| | | @PostMapping("/population/getList") |
| | | public R getPopulationLists(@RequestBody List<Long> Ids) { |
| | | return comMngPopulationService.getPopulationLists(Ids); |
| | | } |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptDecryptField; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | |
| | | |
| | | @Data |
| | | @TableName(value = "com_mng_population") |
| | | @EncryptDecryptClass |
| | | public class ComMngPopulationDO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | |
| | | /** |
| | | * 身份证号码 |
| | | */ |
| | | @EncryptDecryptField |
| | | private String cardNo; |
| | | /** |
| | | * 街路巷 |
| | |
| | | /** |
| | | * 联系方式 |
| | | */ |
| | | @EncryptDecryptField |
| | | private String phone; |
| | | /** |
| | | * 备注 |
New file |
| | |
| | | package com.panzhihua.service_community.model.helper.encrypt; |
| | | |
| | | |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptQuery; |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptQueryClass; |
| | | import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt; |
| | | import com.panzhihua.common.model.helper.sensitive.Sensitive; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.binding.BindingException; |
| | | import org.apache.ibatis.binding.MapperMethod; |
| | | import org.apache.ibatis.executor.parameter.ParameterHandler; |
| | | import org.apache.ibatis.plugin.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.core.annotation.AnnotationUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.sql.PreparedStatement; |
| | | import java.util.*; |
| | | import java.util.stream.Stream; |
| | | |
| | | /** |
| | | * 加密拦截器 |
| | | * 包含加密字段查询时 的加密步骤 |
| | | * @author cedoo |
| | | * @since 2021-4-1 10:40:52 |
| | | */ |
| | | @Intercepts({ |
| | | @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class), |
| | | }) |
| | | @ConditionalOnProperty(value = "domain.encrypt", havingValue = "true") |
| | | @Component |
| | | @Slf4j |
| | | public class ParammeterInterceptor implements Interceptor { |
| | | |
| | | @Autowired |
| | | private IEncryptDecrypt encryptDecrypt; |
| | | |
| | | @Override |
| | | public Object intercept(Invocation invocation) throws Throwable { |
| | | |
| | | //拦截 ParameterHandler 的 setParameters 方法 动态设置参数 |
| | | if (invocation.getTarget() instanceof ParameterHandler) { |
| | | ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget(); |
| | | PreparedStatement ps = (PreparedStatement) invocation.getArgs()[0]; |
| | | |
| | | // 反射获取 参数对像 |
| | | Field parameterField = |
| | | parameterHandler.getClass().getDeclaredField("parameterObject"); |
| | | parameterField.setAccessible(true); |
| | | Object parameterObject = parameterField.get(parameterHandler); |
| | | if (Objects.nonNull(parameterObject)) { |
| | | Class<?> parameterObjectClass = parameterObject.getClass(); |
| | | EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(parameterObjectClass, EncryptDecryptClass.class); |
| | | if (Objects.nonNull(encryptDecryptClass)) { |
| | | Field[] declaredFields = parameterObjectClass.getDeclaredFields(); |
| | | final Object encrypt = encryptDecrypt.encrypt(declaredFields, parameterObject); |
| | | } |
| | | /** |
| | | * 通过加密字段查询时, 将查询参数中的加密字段加密后查询 |
| | | */ |
| | | if(parameterObjectClass == MapperMethod.ParamMap.class) { |
| | | MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) parameterObject; |
| | | boolean encrypted = false; |
| | | try{ |
| | | /** |
| | | * 分页插件,会再分页查询时 进行多次查询,需要判断是否已对加密参数加密,防止多次加密后,查询失败 |
| | | */ |
| | | encrypted = paramMap.get("encrypted")!=null; |
| | | }catch (BindingException be){ |
| | | encrypted = false; |
| | | } |
| | | if(!encrypted) { |
| | | Iterator iterator = paramMap.entrySet().iterator(); |
| | | while(iterator.hasNext()){ |
| | | Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iterator.next(); |
| | | if (entry.getKey().startsWith("param")) { |
| | | Object v = entry.getValue(); |
| | | EncryptQueryClass encryptQueryClass = AnnotationUtils.findAnnotation(v.getClass(), EncryptQueryClass.class); |
| | | if (Objects.nonNull(encryptQueryClass)) { |
| | | Field[] declaredFields = v.getClass().getDeclaredFields(); |
| | | for (Field field : declaredFields) { |
| | | if (field.isAnnotationPresent(EncryptQuery.class)) { |
| | | try { |
| | | final Object encrypt = encryptDecrypt.encrypt(new Field[]{field}, v); |
| | | paramMap.put("encrypted", true); |
| | | } catch (IllegalAccessException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | return invocation.proceed(); |
| | | } |
| | | |
| | | @Override |
| | | public Object plugin(Object o) { |
| | | return Plugin.wrap(o, this); |
| | | } |
| | | |
| | | @Override |
| | | public void setProperties(Properties properties) { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.panzhihua.service_community.model.helper.encrypt; |
| | | |
| | | import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; |
| | | import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.executor.resultset.ResultSetHandler; |
| | | import org.apache.ibatis.plugin.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.core.annotation.AnnotationUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.sql.Statement; |
| | | import java.util.ArrayList; |
| | | import java.util.Objects; |
| | | import java.util.Properties; |
| | | |
| | | /** |
| | | * 解密拦截器 |
| | | * |
| | | * @author cedoo |
| | | * @since 2021-4-1 10:40:52 |
| | | */ |
| | | @Intercepts({ |
| | | @Signature(type = ResultSetHandler.class, method = "handleResultSets", args={Statement.class}) |
| | | }) |
| | | @ConditionalOnProperty(value = "domain.decrypt", havingValue = "true") |
| | | @Component |
| | | @Slf4j |
| | | public class ResultInterceptor implements Interceptor { |
| | | |
| | | @Autowired |
| | | private IEncryptDecrypt encryptDecrypt; |
| | | |
| | | @Override |
| | | public Object intercept(Invocation invocation) throws Throwable { |
| | | Object result = invocation.proceed(); |
| | | if (Objects.isNull(result)){ |
| | | return null; |
| | | } |
| | | |
| | | if (result instanceof ArrayList) { |
| | | ArrayList resultList = (ArrayList) result; |
| | | if (resultList!=null && resultList.size()>0 && needToDecrypt(resultList.get(0))){ |
| | | for (int i = 0; i < resultList.size(); i++) { |
| | | encryptDecrypt.decrypt(resultList.get(i)); |
| | | } |
| | | } |
| | | }else { |
| | | if (needToDecrypt(result)){ |
| | | encryptDecrypt.decrypt(result); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public boolean needToDecrypt(Object object){ |
| | | Class<?> objectClass = object.getClass(); |
| | | EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(objectClass, EncryptDecryptClass.class); |
| | | if (Objects.nonNull(encryptDecryptClass)){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public Object plugin(Object target) { |
| | | return Plugin.wrap(target, this); |
| | | } |
| | | |
| | | @Override |
| | | public void setProperties(Properties properties) { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.panzhihua.service_community.model.helper.sensitive; |
| | | |
| | | import com.panzhihua.common.model.helper.sensitive.Sensitive; |
| | | import com.panzhihua.common.model.helper.sensitive.SensitiveStrategy; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.executor.resultset.ResultSetHandler; |
| | | import org.apache.ibatis.plugin.Interceptor; |
| | | import org.apache.ibatis.plugin.Intercepts; |
| | | import org.apache.ibatis.plugin.Invocation; |
| | | import org.apache.ibatis.plugin.Signature; |
| | | import org.apache.ibatis.reflection.MetaObject; |
| | | import org.apache.ibatis.reflection.SystemMetaObject; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.sql.Statement; |
| | | import java.util.List; |
| | | import java.util.stream.Stream; |
| | | |
| | | /** |
| | | * 字段脱敏拦截器 |
| | | * @author cedoo |
| | | * @since 2021-4-1 10:40:52 |
| | | */ |
| | | @Intercepts(@Signature(type = ResultSetHandler.class, |
| | | method = "handleResultSets", |
| | | args = {Statement.class})) |
| | | @Slf4j |
| | | @ConditionalOnProperty(value = "domain.sensitive", havingValue = "true") |
| | | @Component |
| | | public class SensitiveInterceptor implements Interceptor { |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public Object intercept(Invocation invocation) throws Throwable { |
| | | //log.debug("脱敏拦截器"); |
| | | List<Object> records = (List<Object>) invocation.proceed(); |
| | | // 对结果集脱敏 |
| | | records.forEach(this::sensitive); |
| | | return records; |
| | | } |
| | | |
| | | |
| | | private void sensitive(Object source) { |
| | | // 拿到返回值类型 |
| | | Class<?> sourceClass = source.getClass(); |
| | | // 初始化返回值类型的 MetaObject |
| | | MetaObject metaObject = SystemMetaObject.forObject(source); |
| | | // 捕捉到属性上的标记注解 @Sensitive 并进行对应的脱敏处理 |
| | | Stream.of(sourceClass.getDeclaredFields()) |
| | | .filter(field -> field.isAnnotationPresent(Sensitive.class)) |
| | | .forEach(field -> doSensitive(metaObject, field)); |
| | | } |
| | | |
| | | |
| | | private void doSensitive(MetaObject metaObject, Field field) { |
| | | // 拿到属性名 |
| | | String name = field.getName(); |
| | | // 获取属性值 |
| | | Object value = metaObject.getValue(name); |
| | | // 只有字符串类型才能脱敏 而且不能为null |
| | | if (String.class == metaObject.getGetterType(name) && value != null) { |
| | | Sensitive annotation = field.getAnnotation(Sensitive.class); |
| | | // 获取对应的脱敏策略 并进行脱敏 |
| | | SensitiveStrategy type = annotation.strategy(); |
| | | Object o = type.getDesensitizer().apply((String) value); |
| | | // 把脱敏后的值塞回去 |
| | | metaObject.setValue(name, o); |
| | | } |
| | | } |
| | | } |
| | |
| | | */ |
| | | R deletePopulations(List<Long> Ids); |
| | | |
| | | /** |
| | | * 根据社区id查询所有实有人口 |
| | | * @param communityId 社区id |
| | | * @return 查询结果 |
| | | */ |
| | | R getPopulationListByCommunityId(Long communityId); |
| | | |
| | | /** |
| | | * 根据id集合查询实有人口 |
| | | * @param Ids 实有人口id集合 |
| | | * @return 查询结果 |
| | | */ |
| | | R getPopulationLists(List<Long> Ids); |
| | | |
| | | |
| | | } |
| | |
| | | if (comMngVillageDO == null) { |
| | | throw new ServiceException("街道巷:" + vo.getRoad() + "不存在!"); |
| | | } |
| | | //性别判断 |
| | | if(!StringUtils.isEmpty(vo.getSex())){ |
| | | if(vo.getSex().equals(ComMngPopulationServeExcelVO.sex.nan)){ |
| | | comMngPopulationDO.setSex(ComMngPopulationDO.sex.nan); |
| | | }else if(vo.getSex().equals(ComMngPopulationServeExcelVO.sex.nv)){ |
| | | comMngPopulationDO.setSex(ComMngPopulationDO.sex.nv); |
| | | }else{ |
| | | comMngPopulationDO.setSex(ComMngPopulationDO.sex.no); |
| | | } |
| | | } |
| | | //是否租住判断 |
| | | if(!StringUtils.isEmpty(vo.getIsRent())){ |
| | | if(vo.getIsRent().equals(ComMngPopulationServeExcelVO.isOk.no)){ |
| | | comMngPopulationDO.setIsRent(ComMngPopulationDO.isOk.no); |
| | | }else{ |
| | | comMngPopulationDO.setIsRent(ComMngPopulationDO.isOk.yes); |
| | | } |
| | | } |
| | | //政治面貌判断 |
| | | if(!StringUtils.isEmpty(vo.getPoliticalOutlook())){ |
| | | if(vo.getPoliticalOutlook().equals(ComMngPopulationServeExcelVO.politicalOutlook.qun)){ |
| | | comMngPopulationDO.setPoliticalOutlook(ComMngPopulationDO.politicalOutlook.qun); |
| | | }else if(vo.getPoliticalOutlook().equals(ComMngPopulationServeExcelVO.politicalOutlook.tuan)){ |
| | | comMngPopulationDO.setPoliticalOutlook(ComMngPopulationDO.politicalOutlook.tuan); |
| | | }else if(vo.getPoliticalOutlook().equals(ComMngPopulationServeExcelVO.politicalOutlook.dang)){ |
| | | comMngPopulationDO.setPoliticalOutlook(ComMngPopulationDO.politicalOutlook.dang); |
| | | }else if(vo.getPoliticalOutlook().equals(ComMngPopulationServeExcelVO.politicalOutlook.wu)){ |
| | | comMngPopulationDO.setPoliticalOutlook(ComMngPopulationDO.politicalOutlook.wu); |
| | | }else{ |
| | | comMngPopulationDO.setPoliticalOutlook(ComMngPopulationDO.politicalOutlook.no); |
| | | } |
| | | } |
| | | comMngPopulationDO.setVillageId(comMngVillageDO.getVillageId()); |
| | | comMngPopulationDO.setActId(comActDO.getCommunityId()); |
| | | comMngPopulationDO.setStreetId(comActDO.getStreetId()); |
| | |
| | | } |
| | | return R.fail(); |
| | | } |
| | | |
| | | /** |
| | | * 根据社区id查询所有实有人口 |
| | | * @param communityId 社区id |
| | | * @return 查询结果 |
| | | */ |
| | | @Override |
| | | public R getPopulationListByCommunityId(Long communityId) { |
| | | List<ComMngPopulationDO> list = populationDAO.selectList(new QueryWrapper<ComMngPopulationDO>().eq("act_id",communityId)); |
| | | List<ComMngPopulationVO> resultList = new ArrayList<>(); |
| | | if(list.size() > 0){ |
| | | list.forEach(populationDO -> { |
| | | ComMngPopulationVO populationVO=new ComMngPopulationVO(); |
| | | BeanUtils.copyProperties(populationDO,populationVO); |
| | | resultList.add(populationVO); |
| | | }); |
| | | } |
| | | return R.ok(resultList); |
| | | } |
| | | |
| | | /** |
| | | * 根据id集合查询实有人口 |
| | | * @param Ids 实有人口id集合 |
| | | * @return 查询结果 |
| | | */ |
| | | @Override |
| | | public R getPopulationLists(List<Long> Ids) { |
| | | List<ComMngPopulationDO> list = populationDAO.selectBatchIds(Ids); |
| | | List<ComMngPopulationVO> resultList = new ArrayList<>(); |
| | | if(list.size() > 0){ |
| | | list.forEach(populationDO -> { |
| | | ComMngPopulationVO populationVO = new ComMngPopulationVO(); |
| | | BeanUtils.copyProperties(populationDO,populationVO); |
| | | resultList.add(populationVO); |
| | | }); |
| | | } |
| | | return R.ok(resultList); |
| | | } |
| | | } |
| | |
| | | service-url: |
| | | defaultZone: http://${EUREKA_URL:localhost}:8192/eureka |
| | | |
| | | |
| | | |
| | | #实体加密、解密、字段脱敏拦截设置 |
| | | domain: |
| | | decrypt: true |
| | | encrypt: true |
| | | aesKey: Ryo7M3n8loC5 |
| | | sensitive: true |
| | | |