对比新文件 |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>iailab-framework</artifactId> |
| | | <groupId>com.iailab</groupId> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <artifactId>iailab-common-biz-data-permission</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <name>${project.artifactId}</name> |
| | | <description>数据权限</description> |
| | | <url>http://172.16.8.100:8888/summary/iailab-plat.git</url> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Web 相关 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common-security</artifactId> |
| | | <optional>true</optional> <!-- 可选,如果使用 DeptDataPermissionRule 必须提供 --> |
| | | </dependency> |
| | | |
| | | <!-- DB 相关 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common-mybatis</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.postgresql</groupId> |
| | | <artifactId>postgresql</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- RPC 远程调用相关 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common-rpc</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | |
| | | <!-- 业务组件 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-module-system-api</artifactId> <!-- 需要使用它,进行数据权限的获取 --> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- Test 测试相关 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common-test</artifactId> |
| | | <scope>test</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.config; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; |
| | | import com.iailab.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor; |
| | | import com.iailab.framework.datapermission.core.db.DataPermissionRuleHandler; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRule; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactoryImpl; |
| | | import com.iailab.framework.mybatis.core.util.MyBatisUtils; |
| | | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 数据权限的自动配置类 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @AutoConfiguration |
| | | public class IailabDataPermissionAutoConfiguration { |
| | | |
| | | @Bean |
| | | public DataPermissionRuleFactory dataPermissionRuleFactory(List<DataPermissionRule> rules) { |
| | | return new DataPermissionRuleFactoryImpl(rules); |
| | | } |
| | | |
| | | @Bean |
| | | public DataPermissionRuleHandler dataPermissionRuleHandler(MybatisPlusInterceptor interceptor, |
| | | DataPermissionRuleFactory ruleFactory) { |
| | | // 创建 DataPermissionInterceptor 拦截器 |
| | | DataPermissionRuleHandler handler = new DataPermissionRuleHandler(ruleFactory); |
| | | DataPermissionInterceptor inner = new DataPermissionInterceptor(handler); |
| | | // 添加到 interceptor 中 |
| | | // 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定 |
| | | MyBatisUtils.addInterceptor(interceptor, inner, 0); |
| | | return handler; |
| | | } |
| | | |
| | | |
| | | @Bean |
| | | public DataPermissionAnnotationAdvisor dataPermissionAnnotationAdvisor() { |
| | | return new DataPermissionAnnotationAdvisor(); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.config; |
| | | |
| | | import com.iailab.framework.datapermission.core.rpc.DataPermissionRequestInterceptor; |
| | | import com.iailab.framework.datapermission.core.rpc.DataPermissionRpcWebFilter; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
| | | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import static com.iailab.framework.common.enums.WebFilterOrderEnum.TENANT_CONTEXT_FILTER; |
| | | |
| | | |
| | | /** |
| | | * 数据权限针对 RPC 的自动配置类 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @AutoConfiguration |
| | | @ConditionalOnClass(name = "feign.RequestInterceptor") |
| | | public class IailabDataPermissionRpcAutoConfiguration { |
| | | |
| | | @Bean |
| | | public DataPermissionRequestInterceptor dataPermissionRequestInterceptor() { |
| | | return new DataPermissionRequestInterceptor(); |
| | | } |
| | | |
| | | @Bean |
| | | public FilterRegistrationBean<DataPermissionRpcWebFilter> dataPermissionRpcFilter() { |
| | | FilterRegistrationBean<DataPermissionRpcWebFilter> registrationBean = new FilterRegistrationBean<>(); |
| | | registrationBean.setFilter(new DataPermissionRpcWebFilter()); |
| | | registrationBean.setOrder(TENANT_CONTEXT_FILTER - 1); // 顺序没有绝对的要求,在租户 Filter 前面稳妥点 |
| | | return registrationBean; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.config; |
| | | |
| | | import cn.hutool.extra.spring.SpringUtil; |
| | | import com.iailab.framework.datapermission.core.rule.dept.DeptDataPermissionRule; |
| | | import com.iailab.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer; |
| | | import com.iailab.framework.security.core.LoginUser; |
| | | import com.iailab.module.system.api.permission.PermissionApi; |
| | | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
| | | import org.springframework.context.annotation.Bean; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 基于部门的数据权限 AutoConfiguration |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @AutoConfiguration |
| | | @ConditionalOnClass(LoginUser.class) |
| | | @ConditionalOnBean(value = DeptDataPermissionRuleCustomizer.class) |
| | | public class IailabDeptDataPermissionAutoConfiguration { |
| | | |
| | | @Bean |
| | | public DeptDataPermissionRule deptDataPermissionRule(PermissionApi permissionApi, |
| | | List<DeptDataPermissionRuleCustomizer> customizers) { |
| | | // Cloud 专属逻辑:优先使用本地的 PermissionApi 实现类,而不是 Feign 调用 |
| | | // 原因:在创建租户时,租户还没创建好,导致 Feign 调用获取数据权限时,报“租户不存在”的错误 |
| | | try { |
| | | PermissionApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionApi.class); |
| | | if (permissionApiImpl != null) { |
| | | permissionApi = permissionApiImpl; |
| | | } |
| | | } catch (Exception ignored) {} |
| | | |
| | | // 创建 DeptDataPermissionRule 对象 |
| | | DeptDataPermissionRule rule = new DeptDataPermissionRule(permissionApi); |
| | | // 补全表配置 |
| | | customizers.forEach(customizer -> customizer.customize(rule)); |
| | | return rule; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.annotation; |
| | | |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRule; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 数据权限注解 |
| | | * 可声明在类或者方法上,标识使用的数据权限规则 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @Target({ElementType.TYPE, ElementType.METHOD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface DataPermission { |
| | | |
| | | /** |
| | | * 当前类或方法是否开启数据权限 |
| | | * 即使不添加 @DataPermission 注解,默认是开启状态 |
| | | * 可通过设置 enable 为 false 禁用 |
| | | */ |
| | | boolean enable() default true; |
| | | |
| | | /** |
| | | * 生效的数据权限规则数组,优先级高于 {@link #excludeRules()} |
| | | */ |
| | | Class<? extends DataPermissionRule>[] includeRules() default {}; |
| | | |
| | | /** |
| | | * 排除的数据权限规则数组,优先级最低 |
| | | */ |
| | | Class<? extends DataPermissionRule>[] excludeRules() default {}; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.aop; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.Getter; |
| | | import org.aopalliance.aop.Advice; |
| | | import org.springframework.aop.Pointcut; |
| | | import org.springframework.aop.support.AbstractPointcutAdvisor; |
| | | import org.springframework.aop.support.ComposablePointcut; |
| | | import org.springframework.aop.support.annotation.AnnotationMatchingPointcut; |
| | | |
| | | /** |
| | | * {@link com.iailab.framework.datapermission.core.annotation.DataPermission} 注解的 Advisor 实现类 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @Getter |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class DataPermissionAnnotationAdvisor extends AbstractPointcutAdvisor { |
| | | |
| | | private final Advice advice; |
| | | |
| | | private final Pointcut pointcut; |
| | | |
| | | public DataPermissionAnnotationAdvisor() { |
| | | this.advice = new DataPermissionAnnotationInterceptor(); |
| | | this.pointcut = this.buildPointcut(); |
| | | } |
| | | |
| | | protected Pointcut buildPointcut() { |
| | | Pointcut classPointcut = new AnnotationMatchingPointcut(DataPermission.class, true); |
| | | Pointcut methodPointcut = new AnnotationMatchingPointcut(null, DataPermission.class, true); |
| | | return new ComposablePointcut(classPointcut).union(methodPointcut); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.aop; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import lombok.Getter; |
| | | import org.aopalliance.intercept.MethodInterceptor; |
| | | import org.aopalliance.intercept.MethodInvocation; |
| | | import org.springframework.core.MethodClassKey; |
| | | import org.springframework.core.annotation.AnnotationUtils; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * {@link DataPermission} 注解的拦截器 |
| | | * 1. 在执行方法前,将 @DataPermission 注解入栈 |
| | | * 2. 在执行方法后,将 @DataPermission 注解出栈 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @DataPermission // 该注解,用于 {@link DATA_PERMISSION_NULL} 的空对象 |
| | | public class DataPermissionAnnotationInterceptor implements MethodInterceptor { |
| | | |
| | | /** |
| | | * DataPermission 空对象,用于方法无 {@link DataPermission} 注解时,使用 DATA_PERMISSION_NULL 进行占位 |
| | | */ |
| | | static final DataPermission DATA_PERMISSION_NULL = DataPermissionAnnotationInterceptor.class.getAnnotation(DataPermission.class); |
| | | |
| | | @Getter |
| | | private final Map<MethodClassKey, DataPermission> dataPermissionCache = new ConcurrentHashMap<>(); |
| | | |
| | | @Override |
| | | public Object invoke(MethodInvocation methodInvocation) throws Throwable { |
| | | // 入栈 |
| | | DataPermission dataPermission = this.findAnnotation(methodInvocation); |
| | | if (dataPermission != null) { |
| | | DataPermissionContextHolder.add(dataPermission); |
| | | } |
| | | try { |
| | | // 执行逻辑 |
| | | return methodInvocation.proceed(); |
| | | } finally { |
| | | // 出栈 |
| | | if (dataPermission != null) { |
| | | DataPermissionContextHolder.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private DataPermission findAnnotation(MethodInvocation methodInvocation) { |
| | | // 1. 从缓存中获取 |
| | | Method method = methodInvocation.getMethod(); |
| | | Object targetObject = methodInvocation.getThis(); |
| | | Class<?> clazz = targetObject != null ? targetObject.getClass() : method.getDeclaringClass(); |
| | | MethodClassKey methodClassKey = new MethodClassKey(method, clazz); |
| | | DataPermission dataPermission = dataPermissionCache.get(methodClassKey); |
| | | if (dataPermission != null) { |
| | | return dataPermission != DATA_PERMISSION_NULL ? dataPermission : null; |
| | | } |
| | | |
| | | // 2.1 从方法中获取 |
| | | dataPermission = AnnotationUtils.findAnnotation(method, DataPermission.class); |
| | | // 2.2 从类上获取 |
| | | if (dataPermission == null) { |
| | | dataPermission = AnnotationUtils.findAnnotation(clazz, DataPermission.class); |
| | | } |
| | | // 2.3 添加到缓存中 |
| | | dataPermissionCache.put(methodClassKey, dataPermission != null ? dataPermission : DATA_PERMISSION_NULL); |
| | | return dataPermission; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.aop; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import com.alibaba.ttl.TransmittableThreadLocal; |
| | | |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * {@link DataPermission} 注解的 Context 上下文 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class DataPermissionContextHolder { |
| | | |
| | | /** |
| | | * 使用 List 的原因,可能存在方法的嵌套调用 |
| | | */ |
| | | private static final ThreadLocal<LinkedList<DataPermission>> DATA_PERMISSIONS = |
| | | TransmittableThreadLocal.withInitial(LinkedList::new); |
| | | |
| | | /** |
| | | * 获得当前的 DataPermission 注解 |
| | | * |
| | | * @return DataPermission 注解 |
| | | */ |
| | | public static DataPermission get() { |
| | | return DATA_PERMISSIONS.get().peekLast(); |
| | | } |
| | | |
| | | /** |
| | | * 入栈 DataPermission 注解 |
| | | * |
| | | * @param dataPermission DataPermission 注解 |
| | | */ |
| | | public static void add(DataPermission dataPermission) { |
| | | DATA_PERMISSIONS.get().addLast(dataPermission); |
| | | } |
| | | |
| | | /** |
| | | * 出栈 DataPermission 注解 |
| | | * |
| | | * @return DataPermission 注解 |
| | | */ |
| | | public static DataPermission remove() { |
| | | DataPermission dataPermission = DATA_PERMISSIONS.get().removeLast(); |
| | | // 无元素时,清空 ThreadLocal |
| | | if (DATA_PERMISSIONS.get().isEmpty()) { |
| | | DATA_PERMISSIONS.remove(); |
| | | } |
| | | return dataPermission; |
| | | } |
| | | |
| | | /** |
| | | * 获得所有 DataPermission |
| | | * |
| | | * @return DataPermission 队列 |
| | | */ |
| | | public static List<DataPermission> getAll() { |
| | | return DATA_PERMISSIONS.get(); |
| | | } |
| | | |
| | | /** |
| | | * 清空上下文 |
| | | * |
| | | * 目前仅仅用于单测 |
| | | */ |
| | | public static void clear() { |
| | | DATA_PERMISSIONS.remove(); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.db; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRule; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; |
| | | import com.iailab.framework.mybatis.core.util.MyBatisUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import net.sf.jsqlparser.expression.operators.conditional.AndExpression; |
| | | import net.sf.jsqlparser.schema.Table; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 基于 {@link DataPermissionRule} 的数据权限处理器 |
| | | * |
| | | * 它的底层,是基于 MyBatis Plus 的 <a href="https://baomidou.com/plugins/data-permission/">数据权限插件</a> |
| | | * 核心原理:它会在 SQL 执行前拦截 SQL 语句,并根据用户权限动态添加权限相关的 SQL 片段。这样,只有用户有权限访问的数据才会被查询出来 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @RequiredArgsConstructor |
| | | public class DataPermissionRuleHandler implements MultiDataPermissionHandler { |
| | | |
| | | private final DataPermissionRuleFactory ruleFactory; |
| | | |
| | | @Override |
| | | public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { |
| | | // 获得 Mapper 对应的数据权限的规则 |
| | | List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(mappedStatementId); |
| | | if (CollUtil.isEmpty(rules)) { |
| | | return null; |
| | | } |
| | | |
| | | // 生成条件 |
| | | Expression allExpression = null; |
| | | for (DataPermissionRule rule : rules) { |
| | | // 判断表名是否匹配 |
| | | String tableName = MyBatisUtils.getTableName(table); |
| | | if (!rule.getTableNames().contains(tableName)) { |
| | | continue; |
| | | } |
| | | |
| | | // 单条规则的条件 |
| | | Expression oneExpress = rule.getExpression(tableName, table.getAlias()); |
| | | if (oneExpress == null) { |
| | | continue; |
| | | } |
| | | // 拼接到 allExpression 中 |
| | | allExpression = allExpression == null ? oneExpress |
| | | : new AndExpression(allExpression, oneExpress); |
| | | } |
| | | return allExpression; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rpc; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import com.iailab.framework.datapermission.core.aop.DataPermissionContextHolder; |
| | | import feign.RequestInterceptor; |
| | | import feign.RequestTemplate; |
| | | |
| | | /** |
| | | * DataPermission 的 RequestInterceptor 实现类:Feign 请求时,将 {@link DataPermission} 设置到 header 中,继续透传给被调用的服务 |
| | | * |
| | | * 注意:由于 {@link DataPermission} 不支持序列化和反序列化,所以暂时只能传递它的 enable 属性 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class DataPermissionRequestInterceptor implements RequestInterceptor { |
| | | |
| | | public static final String ENABLE_HEADER_NAME = "data-permission-enable"; |
| | | |
| | | @Override |
| | | public void apply(RequestTemplate requestTemplate) { |
| | | DataPermission dataPermission = DataPermissionContextHolder.get(); |
| | | if (dataPermission != null && Boolean.FALSE.equals(dataPermission.enable())) { |
| | | requestTemplate.header(ENABLE_HEADER_NAME, "false"); |
| | | } |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rpc; |
| | | |
| | | import com.iailab.framework.datapermission.core.util.DataPermissionUtils; |
| | | import org.springframework.web.filter.OncePerRequestFilter; |
| | | |
| | | import javax.servlet.FilterChain; |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 针对 {@link DataPermissionRequestInterceptor} 的 RPC 调用,设置 {@link com.iailab.framework.datapermission.core.aop.DataPermissionContextHolder} 的上下文 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class DataPermissionRpcWebFilter extends OncePerRequestFilter { |
| | | |
| | | @Override |
| | | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) |
| | | throws ServletException, IOException { |
| | | String enable = request.getHeader(DataPermissionRequestInterceptor.ENABLE_HEADER_NAME); |
| | | if (Objects.equals(enable, Boolean.FALSE.toString())) { |
| | | DataPermissionUtils.executeIgnore(() -> { |
| | | try { |
| | | chain.doFilter(request, response); |
| | | } catch (IOException | ServletException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | }); |
| | | } else { |
| | | chain.doFilter(request, response); |
| | | } |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; |
| | | import net.sf.jsqlparser.expression.Alias; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 数据权限规则接口 |
| | | * 通过实现接口,自定义数据规则。例如说, |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public interface DataPermissionRule { |
| | | |
| | | /** |
| | | * 返回需要生效的表名数组 |
| | | * 为什么需要该方法?Data Permission 数组基于 SQL 重写,通过 Where 返回只有权限的数据 |
| | | * |
| | | * 如果需要基于实体名获得表名,可调用 {@link TableInfoHelper#getTableInfo(Class)} 获得 |
| | | * |
| | | * @return 表名数组 |
| | | */ |
| | | Set<String> getTableNames(); |
| | | |
| | | /** |
| | | * 根据表名和别名,生成对应的 WHERE / OR 过滤条件 |
| | | * |
| | | * @param tableName 表名 |
| | | * @param tableAlias 别名,可能为空 |
| | | * @return 过滤条件 Expression 表达式 |
| | | */ |
| | | Expression getExpression(String tableName, Alias tableAlias); |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * {@link DataPermissionRule} 工厂接口 |
| | | * 作为 {@link DataPermissionRule} 的容器,提供管理能力 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public interface DataPermissionRuleFactory { |
| | | |
| | | /** |
| | | * 获得所有数据权限规则数组 |
| | | * |
| | | * @return 数据权限规则数组 |
| | | */ |
| | | List<DataPermissionRule> getDataPermissionRules(); |
| | | |
| | | /** |
| | | * 获得指定 Mapper 的数据权限规则数组 |
| | | * |
| | | * @param mappedStatementId 指定 Mapper 的编号 |
| | | * @return 数据权限规则数组 |
| | | */ |
| | | List<DataPermissionRule> getDataPermissionRule(String mappedStatementId); |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import com.iailab.framework.datapermission.core.aop.DataPermissionContextHolder; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 默认的 DataPermissionRuleFactoryImpl 实现类 |
| | | * 支持通过 {@link DataPermissionContextHolder} 过滤数据权限 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @RequiredArgsConstructor |
| | | public class DataPermissionRuleFactoryImpl implements DataPermissionRuleFactory { |
| | | |
| | | /** |
| | | * 数据权限规则数组 |
| | | */ |
| | | private final List<DataPermissionRule> rules; |
| | | |
| | | @Override |
| | | public List<DataPermissionRule> getDataPermissionRules() { |
| | | return rules; |
| | | } |
| | | |
| | | @Override // mappedStatementId 参数,暂时没有用。以后,可以基于 mappedStatementId + DataPermission 进行缓存 |
| | | public List<DataPermissionRule> getDataPermissionRule(String mappedStatementId) { |
| | | // 1. 无数据权限 |
| | | if (CollUtil.isEmpty(rules)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // 2. 未配置,则默认开启 |
| | | DataPermission dataPermission = DataPermissionContextHolder.get(); |
| | | if (dataPermission == null) { |
| | | return rules; |
| | | } |
| | | // 3. 已配置,但禁用 |
| | | if (!dataPermission.enable()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 4. 已配置,只选择部分规则 |
| | | if (ArrayUtil.isNotEmpty(dataPermission.includeRules())) { |
| | | return rules.stream().filter(rule -> ArrayUtil.contains(dataPermission.includeRules(), rule.getClass())) |
| | | .collect(Collectors.toList()); // 一般规则不会太多,所以不采用 HashSet 查询 |
| | | } |
| | | // 5. 已配置,只排除部分规则 |
| | | if (ArrayUtil.isNotEmpty(dataPermission.excludeRules())) { |
| | | return rules.stream().filter(rule -> !ArrayUtil.contains(dataPermission.excludeRules(), rule.getClass())) |
| | | .collect(Collectors.toList()); // 一般规则不会太多,所以不采用 HashSet 查询 |
| | | } |
| | | // 6. 已配置,全部规则 |
| | | return rules; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule.dept; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.iailab.framework.common.enums.UserTypeEnum; |
| | | import com.iailab.framework.common.util.collection.CollectionUtils; |
| | | import com.iailab.framework.common.util.json.JsonUtils; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRule; |
| | | import com.iailab.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.iailab.framework.mybatis.core.util.MyBatisUtils; |
| | | import com.iailab.framework.security.core.LoginUser; |
| | | import com.iailab.framework.security.core.util.SecurityFrameworkUtils; |
| | | import com.iailab.module.system.api.permission.PermissionApi; |
| | | import com.iailab.module.system.api.permission.dto.DeptDataPermissionRespDTO; |
| | | import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import net.sf.jsqlparser.expression.*; |
| | | import net.sf.jsqlparser.expression.operators.conditional.OrExpression; |
| | | import net.sf.jsqlparser.expression.operators.relational.EqualsTo; |
| | | import net.sf.jsqlparser.expression.operators.relational.ExpressionList; |
| | | import net.sf.jsqlparser.expression.operators.relational.InExpression; |
| | | import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 基于部门的 {@link DataPermissionRule} 数据权限规则实现 |
| | | * |
| | | * 注意,使用 DeptDataPermissionRule 时,需要保证表中有 dept_id 部门编号的字段,可自定义。 |
| | | * |
| | | * 实际业务场景下,会存在一个经典的问题?当用户修改部门时,冗余的 dept_id 是否需要修改? |
| | | * 1. 一般情况下,dept_id 不进行修改,则会导致用户看不到之前的数据。【iailab-server 采用该方案】 |
| | | * 2. 部分情况下,希望该用户还是能看到之前的数据,则有两种方式解决:【需要你改造该 DeptDataPermissionRule 的实现代码】 |
| | | * 1)编写洗数据的脚本,将 dept_id 修改成新部门的编号;【建议】 |
| | | * 最终过滤条件是 WHERE dept_id = ? |
| | | * 2)洗数据的话,可能涉及的数据量较大,也可以采用 user_id 进行过滤的方式,此时需要获取到 dept_id 对应的所有 user_id 用户编号; |
| | | * 最终过滤条件是 WHERE user_id IN (?, ?, ? ...) |
| | | * 3)想要保证原 dept_id 和 user_id 都可以看的到,此时使用 dept_id 和 user_id 一起过滤; |
| | | * 最终过滤条件是 WHERE dept_id = ? OR user_id IN (?, ?, ? ...) |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class DeptDataPermissionRule implements DataPermissionRule { |
| | | |
| | | /** |
| | | * LoginUser 的 Context 缓存 Key |
| | | */ |
| | | protected static final String CONTEXT_KEY = DeptDataPermissionRule.class.getSimpleName(); |
| | | |
| | | private static final String DEPT_COLUMN_NAME = "dept_id"; |
| | | private static final String USER_COLUMN_NAME = "user_id"; |
| | | |
| | | static final Expression EXPRESSION_NULL = new NullValue(); |
| | | |
| | | private final PermissionApi permissionApi; |
| | | |
| | | /** |
| | | * 基于部门的表字段配置 |
| | | * 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。 |
| | | * |
| | | * key:表名 |
| | | * value:字段名 |
| | | */ |
| | | private final Map<String, String> deptColumns = new HashMap<>(); |
| | | /** |
| | | * 基于用户的表字段配置 |
| | | * 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。 |
| | | * |
| | | * key:表名 |
| | | * value:字段名 |
| | | */ |
| | | private final Map<String, String> userColumns = new HashMap<>(); |
| | | /** |
| | | * 所有表名,是 {@link #deptColumns} 和 {@link #userColumns} 的合集 |
| | | */ |
| | | private final Set<String> TABLE_NAMES = new HashSet<>(); |
| | | |
| | | @Override |
| | | public Set<String> getTableNames() { |
| | | return TABLE_NAMES; |
| | | } |
| | | |
| | | @Override |
| | | public Expression getExpression(String tableName, Alias tableAlias) { |
| | | // 只有有登陆用户的情况下,才进行数据权限的处理 |
| | | LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); |
| | | if (loginUser == null) { |
| | | return null; |
| | | } |
| | | // 只有管理员类型的用户,才进行数据权限的处理 |
| | | if (ObjectUtil.notEqual(loginUser.getUserType(), UserTypeEnum.ADMIN.getValue())) { |
| | | return null; |
| | | } |
| | | |
| | | // 获得数据权限 |
| | | DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class); |
| | | // 从上下文中拿不到,则调用逻辑进行获取 |
| | | if (deptDataPermission == null) { |
| | | deptDataPermission = permissionApi.getDeptDataPermission(loginUser.getId()).getCheckedData(); |
| | | if (deptDataPermission == null) { |
| | | log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser)); |
| | | throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限", |
| | | loginUser.getId(), tableName, tableAlias.getName())); |
| | | } |
| | | // 添加到上下文中,避免重复计算 |
| | | loginUser.setContext(CONTEXT_KEY, deptDataPermission); |
| | | } |
| | | |
| | | // 情况一,如果是 ALL 可查看全部,则无需拼接条件 |
| | | if (deptDataPermission.getAll()) { |
| | | return null; |
| | | } |
| | | |
| | | // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限 |
| | | if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) |
| | | && Boolean.FALSE.equals(deptDataPermission.getSelf())) { |
| | | return new EqualsTo(null, null); // WHERE null = null,可以保证返回的数据为空 |
| | | } |
| | | |
| | | // 情况三,拼接 Dept 和 User 的条件,最后组合 |
| | | Expression deptExpression = buildDeptExpression(tableName,tableAlias, deptDataPermission.getDeptIds()); |
| | | Expression userExpression = buildUserExpression(tableName, tableAlias, deptDataPermission.getSelf(), loginUser.getId()); |
| | | if (deptExpression == null && userExpression == null) { |
| | | // TODO iailab:获得不到条件的时候,暂时不抛出异常,而是不返回数据 |
| | | log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]", |
| | | JsonUtils.toJsonString(loginUser), tableName, tableAlias, JsonUtils.toJsonString(deptDataPermission)); |
| | | // throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 构建的条件为空", |
| | | // loginUser.getId(), tableName, tableAlias.getName())); |
| | | return EXPRESSION_NULL; |
| | | } |
| | | if (deptExpression == null) { |
| | | return userExpression; |
| | | } |
| | | if (userExpression == null) { |
| | | return deptExpression; |
| | | } |
| | | // 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即,WHERE (dept_id IN ? OR user_id = ?) |
| | | return new ParenthesedExpressionList(new OrExpression(deptExpression, userExpression)); |
| | | } |
| | | |
| | | private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) { |
| | | // 如果不存在配置,则无需作为条件 |
| | | String columnName = deptColumns.get(tableName); |
| | | if (StrUtil.isEmpty(columnName)) { |
| | | return null; |
| | | } |
| | | // 如果为空,则无条件 |
| | | if (CollUtil.isEmpty(deptIds)) { |
| | | return null; |
| | | } |
| | | // 拼接条件 |
| | | return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), |
| | | // Parenthesis 的目的,是提供 (1,2,3) 的 () 左右括号 |
| | | new ParenthesedExpressionList(new ExpressionList<LongValue>(CollectionUtils.convertList(deptIds, LongValue::new)))); |
| | | } |
| | | |
| | | private Expression buildUserExpression(String tableName, Alias tableAlias, Boolean self, Long userId) { |
| | | // 如果不查看自己,则无需作为条件 |
| | | if (Boolean.FALSE.equals(self)) { |
| | | return null; |
| | | } |
| | | String columnName = userColumns.get(tableName); |
| | | if (StrUtil.isEmpty(columnName)) { |
| | | return null; |
| | | } |
| | | // 拼接条件 |
| | | return new EqualsTo(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), new LongValue(userId)); |
| | | } |
| | | |
| | | // ==================== 添加配置 ==================== |
| | | |
| | | public void addDeptColumn(Class<? extends BaseDO> entityClass) { |
| | | addDeptColumn(entityClass, DEPT_COLUMN_NAME); |
| | | } |
| | | |
| | | public void addDeptColumn(Class<? extends BaseDO> entityClass, String columnName) { |
| | | String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName(); |
| | | addDeptColumn(tableName, columnName); |
| | | } |
| | | |
| | | public void addDeptColumn(String tableName, String columnName) { |
| | | deptColumns.put(tableName, columnName); |
| | | TABLE_NAMES.add(tableName); |
| | | } |
| | | |
| | | public void addUserColumn(Class<? extends BaseDO> entityClass) { |
| | | addUserColumn(entityClass, USER_COLUMN_NAME); |
| | | } |
| | | |
| | | public void addUserColumn(Class<? extends BaseDO> entityClass, String columnName) { |
| | | String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName(); |
| | | addUserColumn(tableName, columnName); |
| | | } |
| | | |
| | | public void addUserColumn(String tableName, String columnName) { |
| | | userColumns.put(tableName, columnName); |
| | | TABLE_NAMES.add(tableName); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule.dept; |
| | | |
| | | /** |
| | | * {@link DeptDataPermissionRule} 的自定义配置接口 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @FunctionalInterface |
| | | public interface DeptDataPermissionRuleCustomizer { |
| | | |
| | | /** |
| | | * 自定义该权限规则 |
| | | * 1. 调用 {@link DeptDataPermissionRule#addDeptColumn(Class, String)} 方法,配置基于 dept_id 的过滤规则 |
| | | * 2. 调用 {@link DeptDataPermissionRule#addUserColumn(Class, String)} 方法,配置基于 user_id 的过滤规则 |
| | | * |
| | | * @param rule 权限规则 |
| | | */ |
| | | void customize(DeptDataPermissionRule rule); |
| | | |
| | | } |
对比新文件 |
| | |
| | | /** |
| | | * 基于部门的数据权限规则 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | package com.iailab.framework.datapermission.core.rule.dept; |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.util; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import com.iailab.framework.datapermission.core.aop.DataPermissionContextHolder; |
| | | import lombok.SneakyThrows; |
| | | |
| | | import java.util.concurrent.Callable; |
| | | |
| | | /** |
| | | * 数据权限 Util |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class DataPermissionUtils { |
| | | |
| | | private static DataPermission DATA_PERMISSION_DISABLE; |
| | | |
| | | @DataPermission(enable = false) |
| | | @SneakyThrows |
| | | private static DataPermission getDisableDataPermissionDisable() { |
| | | if (DATA_PERMISSION_DISABLE == null) { |
| | | DATA_PERMISSION_DISABLE = DataPermissionUtils.class |
| | | .getDeclaredMethod("getDisableDataPermissionDisable") |
| | | .getAnnotation(DataPermission.class); |
| | | } |
| | | return DATA_PERMISSION_DISABLE; |
| | | } |
| | | |
| | | /** |
| | | * 忽略数据权限,执行对应的逻辑 |
| | | * |
| | | * @param runnable 逻辑 |
| | | */ |
| | | public static void executeIgnore(Runnable runnable) { |
| | | DataPermission dataPermission = getDisableDataPermissionDisable(); |
| | | DataPermissionContextHolder.add(dataPermission); |
| | | try { |
| | | // 执行 runnable |
| | | runnable.run(); |
| | | } finally { |
| | | DataPermissionContextHolder.remove(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 忽略数据权限,执行对应的逻辑 |
| | | * |
| | | * @param callable 逻辑 |
| | | * @return 执行结果 |
| | | */ |
| | | @SneakyThrows |
| | | public static <T> T executeIgnore(Callable<T> callable) { |
| | | DataPermission dataPermission = getDisableDataPermissionDisable(); |
| | | DataPermissionContextHolder.add(dataPermission); |
| | | try { |
| | | // 执行 callable |
| | | return callable.call(); |
| | | } finally { |
| | | DataPermissionContextHolder.remove(); |
| | | } |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | /** |
| | | * 基于 JSqlParser 解析 SQL,增加数据权限的 WHERE 条件 |
| | | */ |
| | | package com.iailab.framework.datapermission; |
对比新文件 |
| | |
| | | com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration |
| | | com.iailab.framework.datapermission.config.IailabDeptDataPermissionAutoConfiguration |
| | | com.iailab.framework.datapermission.config.IailabDataPermissionRpcAutoConfiguration |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.aop; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; |
| | | import org.aopalliance.intercept.MethodInvocation; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.*; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | /** |
| | | * {@link DataPermissionAnnotationInterceptor} 的单元测试 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class DataPermissionAnnotationInterceptorTest extends BaseMockitoUnitTest { |
| | | |
| | | @InjectMocks |
| | | private DataPermissionAnnotationInterceptor interceptor; |
| | | |
| | | @Mock |
| | | private MethodInvocation methodInvocation; |
| | | |
| | | @BeforeEach |
| | | public void setUp() { |
| | | interceptor.getDataPermissionCache().clear(); |
| | | } |
| | | |
| | | @Test // 无 @DataPermission 注解 |
| | | public void testInvoke_none() throws Throwable { |
| | | // 参数 |
| | | mockMethodInvocation(TestNone.class); |
| | | |
| | | // 调用 |
| | | Object result = interceptor.invoke(methodInvocation); |
| | | // 断言 |
| | | assertEquals("none", result); |
| | | assertEquals(1, interceptor.getDataPermissionCache().size()); |
| | | assertTrue(CollUtil.getFirst(interceptor.getDataPermissionCache().values()).enable()); |
| | | } |
| | | |
| | | @Test // 在 Method 上有 @DataPermission 注解 |
| | | public void testInvoke_method() throws Throwable { |
| | | // 参数 |
| | | mockMethodInvocation(TestMethod.class); |
| | | |
| | | // 调用 |
| | | Object result = interceptor.invoke(methodInvocation); |
| | | // 断言 |
| | | assertEquals("method", result); |
| | | assertEquals(1, interceptor.getDataPermissionCache().size()); |
| | | assertFalse(CollUtil.getFirst(interceptor.getDataPermissionCache().values()).enable()); |
| | | } |
| | | |
| | | @Test // 在 Class 上有 @DataPermission 注解 |
| | | public void testInvoke_class() throws Throwable { |
| | | // 参数 |
| | | mockMethodInvocation(TestClass.class); |
| | | |
| | | // 调用 |
| | | Object result = interceptor.invoke(methodInvocation); |
| | | // 断言 |
| | | assertEquals("class", result); |
| | | assertEquals(1, interceptor.getDataPermissionCache().size()); |
| | | assertFalse(CollUtil.getFirst(interceptor.getDataPermissionCache().values()).enable()); |
| | | } |
| | | |
| | | private void mockMethodInvocation(Class<?> clazz) throws Throwable { |
| | | Object targetObject = clazz.newInstance(); |
| | | Method method = targetObject.getClass().getMethod("echo"); |
| | | when(methodInvocation.getThis()).thenReturn(targetObject); |
| | | when(methodInvocation.getMethod()).thenReturn(method); |
| | | when(methodInvocation.proceed()).then(invocationOnMock -> method.invoke(targetObject)); |
| | | } |
| | | |
| | | static class TestMethod { |
| | | |
| | | @DataPermission(enable = false) |
| | | public String echo() { |
| | | return "method"; |
| | | } |
| | | |
| | | } |
| | | |
| | | @DataPermission(enable = false) |
| | | static class TestClass { |
| | | |
| | | public String echo() { |
| | | return "class"; |
| | | } |
| | | |
| | | } |
| | | |
| | | static class TestNone { |
| | | |
| | | public String echo() { |
| | | return "none"; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.aop; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | import static org.junit.jupiter.api.Assertions.assertSame; |
| | | import static org.mockito.Mockito.mock; |
| | | |
| | | /** |
| | | * {@link DataPermissionContextHolder} 的单元测试 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | class DataPermissionContextHolderTest { |
| | | |
| | | @BeforeEach |
| | | public void setUp() { |
| | | DataPermissionContextHolder.clear(); |
| | | } |
| | | |
| | | @Test |
| | | public void testGet() { |
| | | // mock 方法 |
| | | DataPermission dataPermission01 = mock(DataPermission.class); |
| | | DataPermissionContextHolder.add(dataPermission01); |
| | | DataPermission dataPermission02 = mock(DataPermission.class); |
| | | DataPermissionContextHolder.add(dataPermission02); |
| | | |
| | | // 调用 |
| | | DataPermission result = DataPermissionContextHolder.get(); |
| | | // 断言 |
| | | assertSame(result, dataPermission02); |
| | | } |
| | | |
| | | @Test |
| | | public void testPush() { |
| | | // 调用 |
| | | DataPermission dataPermission01 = mock(DataPermission.class); |
| | | DataPermissionContextHolder.add(dataPermission01); |
| | | DataPermission dataPermission02 = mock(DataPermission.class); |
| | | DataPermissionContextHolder.add(dataPermission02); |
| | | // 断言 |
| | | DataPermission first = DataPermissionContextHolder.getAll().get(0); |
| | | DataPermission second = DataPermissionContextHolder.getAll().get(1); |
| | | assertSame(dataPermission01, first); |
| | | assertSame(dataPermission02, second); |
| | | } |
| | | |
| | | @Test |
| | | public void testRemove() { |
| | | // mock 方法 |
| | | DataPermission dataPermission01 = mock(DataPermission.class); |
| | | DataPermissionContextHolder.add(dataPermission01); |
| | | DataPermission dataPermission02 = mock(DataPermission.class); |
| | | DataPermissionContextHolder.add(dataPermission02); |
| | | |
| | | // 调用 |
| | | DataPermission result = DataPermissionContextHolder.remove(); |
| | | // 断言 |
| | | assertSame(result, dataPermission02); |
| | | assertEquals(1, DataPermissionContextHolder.getAll().size()); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.db; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRule; |
| | | import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; |
| | | import com.iailab.framework.mybatis.core.util.MyBatisUtils; |
| | | import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; |
| | | import net.sf.jsqlparser.expression.Alias; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import net.sf.jsqlparser.expression.LongValue; |
| | | import net.sf.jsqlparser.expression.Parenthesis; |
| | | import net.sf.jsqlparser.expression.operators.relational.EqualsTo; |
| | | import net.sf.jsqlparser.expression.operators.relational.ExpressionList; |
| | | import net.sf.jsqlparser.expression.operators.relational.InExpression; |
| | | import net.sf.jsqlparser.schema.Column; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Set; |
| | | |
| | | import static com.iailab.framework.common.util.collection.SetUtils.asSet; |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | import static org.mockito.ArgumentMatchers.any; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | /** |
| | | * {@link DataPermissionRuleHandler} 的单元测试 |
| | | * 主要复用了 MyBatis Plus 的 TenantLineInnerInterceptorTest 的单元测试 |
| | | * 不过它的单元测试不是很规范,考虑到是复用的,所以暂时不进行修改~ |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class DataPermissionRuleHandlerTest extends BaseMockitoUnitTest { |
| | | |
| | | @InjectMocks |
| | | private DataPermissionRuleHandler handler; |
| | | |
| | | @Mock |
| | | private DataPermissionRuleFactory ruleFactory; |
| | | |
| | | private DataPermissionInterceptor interceptor; |
| | | |
| | | @BeforeEach |
| | | public void setUp() { |
| | | interceptor = new DataPermissionInterceptor(handler); |
| | | |
| | | // 租户的数据权限规则 |
| | | DataPermissionRule tenantRule = new DataPermissionRule() { |
| | | |
| | | private static final String COLUMN = "tenant_id"; |
| | | |
| | | @Override |
| | | public Set<String> getTableNames() { |
| | | return asSet("entity", "entity1", "entity2", "entity3", "t1", "t2", "sys_dict_item", // 支持 MyBatis Plus 的单元测试 |
| | | "t_user", "t_role"); // 满足自己的单元测试 |
| | | } |
| | | |
| | | @Override |
| | | public Expression getExpression(String tableName, Alias tableAlias) { |
| | | Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN); |
| | | LongValue value = new LongValue(1L); |
| | | return new EqualsTo(column, value); |
| | | } |
| | | |
| | | }; |
| | | // 部门的数据权限规则 |
| | | DataPermissionRule deptRule = new DataPermissionRule() { |
| | | |
| | | private static final String COLUMN = "dept_id"; |
| | | |
| | | @Override |
| | | public Set<String> getTableNames() { |
| | | return asSet("t_user"); // 满足自己的单元测试 |
| | | } |
| | | |
| | | @Override |
| | | public Expression getExpression(String tableName, Alias tableAlias) { |
| | | Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN); |
| | | ExpressionList<LongValue> values = new ExpressionList<>(new LongValue(10L), |
| | | new LongValue(20L)); |
| | | return new InExpression(column, new Parenthesis((values))); |
| | | } |
| | | |
| | | }; |
| | | // 设置到上下文 |
| | | when(ruleFactory.getDataPermissionRule(any())).thenReturn(Arrays.asList(tenantRule, deptRule)); |
| | | } |
| | | |
| | | @Test |
| | | void delete() { |
| | | assertSql("delete from entity where id = ?", |
| | | "DELETE FROM entity WHERE id = ? AND entity.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void update() { |
| | | assertSql("update entity set name = ? where id = ?", |
| | | "UPDATE entity SET name = ? WHERE id = ? AND entity.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSingle() { |
| | | // 单表 |
| | | assertSql("select * from entity where id = ?", |
| | | "SELECT * FROM entity WHERE id = ? AND entity.tenant_id = 1"); |
| | | |
| | | assertSql("select * from entity where id = ? or name = ?", |
| | | "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)", |
| | | "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1"); |
| | | |
| | | /* not */ |
| | | assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)", |
| | | "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND entity.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSubSelectIn() { |
| | | /* in */ |
| | | assertSql("SELECT * FROM entity e WHERE e.id IN (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE e.id IN (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | // 在最前 |
| | | assertSql("SELECT * FROM entity e WHERE e.id IN " + |
| | | "(select e1.id from entity1 e1 where e1.id = ?) and e.id = ?", |
| | | "SELECT * FROM entity e WHERE e.id IN " + |
| | | "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ? AND e.tenant_id = 1"); |
| | | // 在最后 |
| | | assertSql("SELECT * FROM entity e WHERE e.id = ? and e.id IN " + |
| | | "(select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE e.id = ? AND e.id IN " + |
| | | "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | // 在中间 |
| | | assertSql("SELECT * FROM entity e WHERE e.id = ? and e.id IN " + |
| | | "(select e1.id from entity1 e1 where e1.id = ?) and e.id = ?", |
| | | "SELECT * FROM entity e WHERE e.id = ? AND e.id IN " + |
| | | "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ? AND e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSubSelectEq() { |
| | | /* = */ |
| | | assertSql("SELECT * FROM entity e WHERE e.id = (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSubSelectInnerNotEq() { |
| | | /* inner not = */ |
| | | assertSql("SELECT * FROM entity e WHERE not (e.id = (select e1.id from entity1 e1 where e1.id = ?))", |
| | | "SELECT * FROM entity e WHERE NOT (e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1)) AND e.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e WHERE not (e.id = (select e1.id from entity1 e1 where e1.id = ?) and e.id = ?)", |
| | | "SELECT * FROM entity e WHERE NOT (e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ?) AND e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSubSelectExists() { |
| | | /* EXISTS */ |
| | | assertSql("SELECT * FROM entity e WHERE EXISTS (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE EXISTS (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | |
| | | |
| | | /* NOT EXISTS */ |
| | | assertSql("SELECT * FROM entity e WHERE NOT EXISTS (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE NOT EXISTS (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSubSelect() { |
| | | /* >= */ |
| | | assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE e.id >= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | |
| | | |
| | | /* <= */ |
| | | assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE e.id <= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | |
| | | |
| | | /* <> */ |
| | | assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)", |
| | | "SELECT * FROM entity e WHERE e.id <> (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectFromSelect() { |
| | | assertSql("SELECT * FROM (select e.id from entity e WHERE e.id = (select e1.id from entity1 e1 where e1.id = ?))", |
| | | "SELECT * FROM (SELECT e.id FROM entity e WHERE e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1)"); |
| | | } |
| | | |
| | | @Test |
| | | void selectBodySubSelect() { |
| | | assertSql("select t1.col1,(select t2.col2 from t2 t2 where t1.col1=t2.col1) from t1 t1", |
| | | "SELECT t1.col1, (SELECT t2.col2 FROM t2 t2 WHERE t1.col1 = t2.col1 AND t2.tenant_id = 1) FROM t1 t1 WHERE t1.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectLeftJoin() { |
| | | // left join |
| | | assertSql("SELECT * FROM entity e " + |
| | | "left join entity1 e1 on e1.id = e.id " + |
| | | "WHERE e.id = ? OR e.name = ?", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "left join entity1 e1 on e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.name = ?)", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "left join entity1 e1 on e1.id = e.id " + |
| | | "left join entity2 e2 on e1.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " + |
| | | "WHERE e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectRightJoin() { |
| | | // right join |
| | | assertSql("SELECT * FROM entity e " + |
| | | "right join entity1 e1 on e1.id = e.id", |
| | | "SELECT * FROM entity e " + |
| | | "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + |
| | | "WHERE e1.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM with_as_1 e " + |
| | | "right join entity1 e1 on e1.id = e.id", |
| | | "SELECT * FROM with_as_1 e " + |
| | | "RIGHT JOIN entity1 e1 ON e1.id = e.id " + |
| | | "WHERE e1.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "right join entity1 e1 on e1.id = e.id " + |
| | | "WHERE e.id = ? OR e.name = ?", |
| | | "SELECT * FROM entity e " + |
| | | "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "right join entity1 e1 on e1.id = e.id " + |
| | | "right join entity2 e2 on e1.id = e2.id ", |
| | | "SELECT * FROM entity e " + |
| | | "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + |
| | | "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " + |
| | | "WHERE e2.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectMixJoin() { |
| | | assertSql("SELECT * FROM entity e " + |
| | | "right join entity1 e1 on e1.id = e.id " + |
| | | "left join entity2 e2 on e1.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + |
| | | "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " + |
| | | "WHERE e1.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "left join entity1 e1 on e1.id = e.id " + |
| | | "right join entity2 e2 on e1.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 " + |
| | | "WHERE e2.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "left join entity1 e1 on e1.id = e.id " + |
| | | "inner join entity2 e2 on e1.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "INNER JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 AND e2.tenant_id = 1"); |
| | | } |
| | | |
| | | |
| | | @Test |
| | | void selectJoinSubSelect() { |
| | | assertSql("select * from (select * from entity) e1 " + |
| | | "left join entity2 e2 on e1.id = e2.id", |
| | | "SELECT * FROM (SELECT * FROM entity WHERE entity.tenant_id = 1) e1 " + |
| | | "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1"); |
| | | |
| | | assertSql("select * from entity1 e1 " + |
| | | "left join (select * from entity2) e2 " + |
| | | "on e1.id = e2.id", |
| | | "SELECT * FROM entity1 e1 " + |
| | | "LEFT JOIN (SELECT * FROM entity2 WHERE entity2.tenant_id = 1) e2 " + |
| | | "ON e1.id = e2.id " + |
| | | "WHERE e1.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectSubJoin() { |
| | | |
| | | assertSql("select * FROM " + |
| | | "(entity1 e1 right JOIN entity2 e2 ON e1.id = e2.id)", |
| | | "SELECT * FROM " + |
| | | "(entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " + |
| | | "WHERE e2.tenant_id = 1"); |
| | | |
| | | assertSql("select * FROM " + |
| | | "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id)", |
| | | "SELECT * FROM " + |
| | | "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + |
| | | "WHERE e1.tenant_id = 1"); |
| | | |
| | | |
| | | assertSql("select * FROM " + |
| | | "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id) " + |
| | | "right join entity3 e3 on e1.id = e3.id", |
| | | "SELECT * FROM " + |
| | | "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + |
| | | "RIGHT JOIN entity3 e3 ON e1.id = e3.id AND e1.tenant_id = 1 " + |
| | | "WHERE e3.tenant_id = 1"); |
| | | |
| | | |
| | | assertSql("select * FROM entity e " + |
| | | "LEFT JOIN (entity1 e1 right join entity2 e2 ON e1.id = e2.id) " + |
| | | "on e.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN (entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " + |
| | | "ON e.id = e2.id AND e2.tenant_id = 1 " + |
| | | "WHERE e.tenant_id = 1"); |
| | | |
| | | assertSql("select * FROM entity e " + |
| | | "LEFT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " + |
| | | "on e.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + |
| | | "ON e.id = e2.id AND e1.tenant_id = 1 " + |
| | | "WHERE e.tenant_id = 1"); |
| | | |
| | | assertSql("select * FROM entity e " + |
| | | "RIGHT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " + |
| | | "on e.id = e2.id", |
| | | "SELECT * FROM entity e " + |
| | | "RIGHT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + |
| | | "ON e.id = e2.id AND e.tenant_id = 1 " + |
| | | "WHERE e1.tenant_id = 1"); |
| | | } |
| | | |
| | | |
| | | @Test |
| | | void selectLeftJoinMultipleTrailingOn() { |
| | | // 多个 on 尾缀的 |
| | | assertSql("SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 " + |
| | | "LEFT JOIN entity2 e2 ON e2.id = e1.id " + |
| | | "ON e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.NAME = ?)", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 " + |
| | | "LEFT JOIN entity2 e2 ON e2.id = e1.id AND e2.tenant_id = 1 " + |
| | | "ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.NAME = ?) AND e.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 " + |
| | | "LEFT JOIN with_as_A e2 ON e2.id = e1.id " + |
| | | "ON e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.NAME = ?)", |
| | | "SELECT * FROM entity e " + |
| | | "LEFT JOIN entity1 e1 " + |
| | | "LEFT JOIN with_as_A e2 ON e2.id = e1.id " + |
| | | "ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.NAME = ?) AND e.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | void selectInnerJoin() { |
| | | // inner join |
| | | assertSql("SELECT * FROM entity e " + |
| | | "inner join entity1 e1 on e1.id = e.id " + |
| | | "WHERE e.id = ? OR e.name = ?", |
| | | "SELECT * FROM entity e " + |
| | | "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " + |
| | | "WHERE e.id = ? OR e.name = ?"); |
| | | |
| | | assertSql("SELECT * FROM entity e " + |
| | | "inner join entity1 e1 on e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.name = ?)", |
| | | "SELECT * FROM entity e " + |
| | | "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?)"); |
| | | |
| | | // 隐式内连接 |
| | | assertSql("SELECT * FROM entity,entity1 " + |
| | | "WHERE entity.id = entity1.id", |
| | | "SELECT * FROM entity, entity1 " + |
| | | "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); |
| | | |
| | | // 隐式内连接 |
| | | assertSql("SELECT * FROM entity a, with_as_entity1 b " + |
| | | "WHERE a.id = b.id", |
| | | "SELECT * FROM entity a, with_as_entity1 b " + |
| | | "WHERE a.id = b.id AND a.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM with_as_entity a, with_as_entity1 b " + |
| | | "WHERE a.id = b.id", |
| | | "SELECT * FROM with_as_entity a, with_as_entity1 b " + |
| | | "WHERE a.id = b.id"); |
| | | |
| | | // SubJoin with 隐式内连接 |
| | | assertSql("SELECT * FROM (entity,entity1) " + |
| | | "WHERE entity.id = entity1.id", |
| | | "SELECT * FROM (entity, entity1) " + |
| | | "WHERE entity.id = entity1.id " + |
| | | "AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM ((entity,entity1),entity2) " + |
| | | "WHERE entity.id = entity1.id and entity.id = entity2.id", |
| | | "SELECT * FROM ((entity, entity1), entity2) " + |
| | | "WHERE entity.id = entity1.id AND entity.id = entity2.id " + |
| | | "AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1"); |
| | | |
| | | assertSql("SELECT * FROM (entity,(entity1,entity2)) " + |
| | | "WHERE entity.id = entity1.id and entity.id = entity2.id", |
| | | "SELECT * FROM (entity, (entity1, entity2)) " + |
| | | "WHERE entity.id = entity1.id AND entity.id = entity2.id " + |
| | | "AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1"); |
| | | |
| | | // 沙雕的括号写法 |
| | | assertSql("SELECT * FROM (((entity,entity1))) " + |
| | | "WHERE entity.id = entity1.id", |
| | | "SELECT * FROM (((entity, entity1))) " + |
| | | "WHERE entity.id = entity1.id " + |
| | | "AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); |
| | | |
| | | } |
| | | |
| | | |
| | | @Test |
| | | void selectWithAs() { |
| | | assertSql("with with_as_A as (select * from entity) select * from with_as_A", |
| | | "WITH with_as_A AS (SELECT * FROM entity WHERE entity.tenant_id = 1) SELECT * FROM with_as_A"); |
| | | } |
| | | |
| | | |
| | | @Test |
| | | void selectIgnoreTable() { |
| | | assertSql(" SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)", |
| | | "SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id AND item.tenant_id = 1 WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)"); |
| | | } |
| | | |
| | | private void assertSql(String sql, String targetSql) { |
| | | assertEquals(targetSql, interceptor.parserSingle(sql, null)); |
| | | } |
| | | |
| | | // ========== 额外的测试 ========== |
| | | |
| | | @Test |
| | | public void testSelectSingle() { |
| | | // 单表 |
| | | assertSql("select * from t_user where id = ?", |
| | | "SELECT * FROM t_user WHERE id = ? AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); |
| | | |
| | | assertSql("select * from t_user where id = ? or name = ?", |
| | | "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); |
| | | |
| | | assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)", |
| | | "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); |
| | | |
| | | /* not */ |
| | | assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)", |
| | | "SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); |
| | | } |
| | | |
| | | @Test |
| | | public void testSelectLeftJoin() { |
| | | // left join |
| | | assertSql("SELECT * FROM t_user e " + |
| | | "left join t_role e1 on e1.id = e.id " + |
| | | "WHERE e.id = ? OR e.name = ?", |
| | | "SELECT * FROM t_user e " + |
| | | "LEFT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); |
| | | |
| | | // 条件 e.id = ? OR e.name = ? 带括号 |
| | | assertSql("SELECT * FROM t_user e " + |
| | | "left join t_role e1 on e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.name = ?)", |
| | | "SELECT * FROM t_user e " + |
| | | "LEFT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); |
| | | } |
| | | |
| | | @Test |
| | | public void testSelectRightJoin() { |
| | | // right join |
| | | assertSql("SELECT * FROM t_user e " + |
| | | "right join t_role e1 on e1.id = e.id " + |
| | | "WHERE e.id = ? OR e.name = ?", |
| | | "SELECT * FROM t_user e " + |
| | | "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1"); |
| | | |
| | | // 条件 e.id = ? OR e.name = ? 带括号 |
| | | assertSql("SELECT * FROM t_user e " + |
| | | "right join t_role e1 on e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.name = ?)", |
| | | "SELECT * FROM t_user e " + |
| | | "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " + |
| | | "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1"); |
| | | } |
| | | |
| | | @Test |
| | | public void testSelectInnerJoin() { |
| | | // inner join |
| | | assertSql("SELECT * FROM t_user e " + |
| | | "inner join entity1 e1 on e1.id = e.id " + |
| | | "WHERE e.id = ? OR e.name = ?", |
| | | "SELECT * FROM t_user e " + |
| | | "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " + |
| | | "WHERE e.id = ? OR e.name = ?"); |
| | | |
| | | // 条件 e.id = ? OR e.name = ? 带括号 |
| | | assertSql("SELECT * FROM t_user e " + |
| | | "inner join entity1 e1 on e1.id = e.id " + |
| | | "WHERE (e.id = ? OR e.name = ?)", |
| | | "SELECT * FROM t_user e " + |
| | | "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " + |
| | | "WHERE (e.id = ? OR e.name = ?)"); |
| | | |
| | | // 没有 On 的 inner join |
| | | assertSql("SELECT * FROM entity,entity1 " + |
| | | "WHERE entity.id = entity1.id", |
| | | "SELECT * FROM entity, entity1 " + |
| | | "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule; |
| | | |
| | | import com.iailab.framework.datapermission.core.annotation.DataPermission; |
| | | import com.iailab.framework.datapermission.core.aop.DataPermissionContextHolder; |
| | | import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; |
| | | import net.sf.jsqlparser.expression.Alias; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Spy; |
| | | import org.springframework.core.annotation.AnnotationUtils; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import static com.iailab.framework.test.core.util.RandomUtils.randomString; |
| | | import static org.junit.jupiter.api.Assertions.*; |
| | | |
| | | /** |
| | | * {@link DataPermissionRuleFactoryImpl} 单元测试 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | class DataPermissionRuleFactoryImplTest extends BaseMockitoUnitTest { |
| | | |
| | | @InjectMocks |
| | | private DataPermissionRuleFactoryImpl dataPermissionRuleFactory; |
| | | |
| | | @Spy |
| | | private List<DataPermissionRule> rules = Arrays.asList(new DataPermissionRule01(), |
| | | new DataPermissionRule02()); |
| | | |
| | | @BeforeEach |
| | | public void setUp() { |
| | | DataPermissionContextHolder.clear(); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetDataPermissionRule_02() { |
| | | // 准备参数 |
| | | String mappedStatementId = randomString(); |
| | | |
| | | // 调用 |
| | | List<DataPermissionRule> result = dataPermissionRuleFactory.getDataPermissionRule(mappedStatementId); |
| | | // 断言 |
| | | assertSame(rules, result); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetDataPermissionRule_03() { |
| | | // 准备参数 |
| | | String mappedStatementId = randomString(); |
| | | // mock 方法 |
| | | DataPermissionContextHolder.add(AnnotationUtils.findAnnotation(TestClass03.class, DataPermission.class)); |
| | | |
| | | // 调用 |
| | | List<DataPermissionRule> result = dataPermissionRuleFactory.getDataPermissionRule(mappedStatementId); |
| | | // 断言 |
| | | assertTrue(result.isEmpty()); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetDataPermissionRule_04() { |
| | | // 准备参数 |
| | | String mappedStatementId = randomString(); |
| | | // mock 方法 |
| | | DataPermissionContextHolder.add(AnnotationUtils.findAnnotation(TestClass04.class, DataPermission.class)); |
| | | |
| | | // 调用 |
| | | List<DataPermissionRule> result = dataPermissionRuleFactory.getDataPermissionRule(mappedStatementId); |
| | | // 断言 |
| | | assertEquals(1, result.size()); |
| | | assertEquals(DataPermissionRule01.class, result.get(0).getClass()); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetDataPermissionRule_05() { |
| | | // 准备参数 |
| | | String mappedStatementId = randomString(); |
| | | // mock 方法 |
| | | DataPermissionContextHolder.add(AnnotationUtils.findAnnotation(TestClass05.class, DataPermission.class)); |
| | | |
| | | // 调用 |
| | | List<DataPermissionRule> result = dataPermissionRuleFactory.getDataPermissionRule(mappedStatementId); |
| | | // 断言 |
| | | assertEquals(1, result.size()); |
| | | assertEquals(DataPermissionRule02.class, result.get(0).getClass()); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetDataPermissionRule_06() { |
| | | // 准备参数 |
| | | String mappedStatementId = randomString(); |
| | | // mock 方法 |
| | | DataPermissionContextHolder.add(AnnotationUtils.findAnnotation(TestClass06.class, DataPermission.class)); |
| | | |
| | | // 调用 |
| | | List<DataPermissionRule> result = dataPermissionRuleFactory.getDataPermissionRule(mappedStatementId); |
| | | // 断言 |
| | | assertSame(rules, result); |
| | | } |
| | | |
| | | @DataPermission(enable = false) |
| | | static class TestClass03 {} |
| | | |
| | | @DataPermission(includeRules = DataPermissionRule01.class) |
| | | static class TestClass04 {} |
| | | |
| | | @DataPermission(excludeRules = DataPermissionRule01.class) |
| | | static class TestClass05 {} |
| | | |
| | | @DataPermission |
| | | static class TestClass06 {} |
| | | |
| | | static class DataPermissionRule01 implements DataPermissionRule { |
| | | |
| | | @Override |
| | | public Set<String> getTableNames() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public Expression getExpression(String tableName, Alias tableAlias) { |
| | | return null; |
| | | } |
| | | |
| | | } |
| | | |
| | | static class DataPermissionRule02 implements DataPermissionRule { |
| | | |
| | | @Override |
| | | public Set<String> getTableNames() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public Expression getExpression(String tableName, Alias tableAlias) { |
| | | return null; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.rule.dept; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ReflectUtil; |
| | | import com.iailab.framework.common.enums.UserTypeEnum; |
| | | import com.iailab.framework.common.util.collection.SetUtils; |
| | | import com.iailab.framework.security.core.LoginUser; |
| | | import com.iailab.framework.security.core.util.SecurityFrameworkUtils; |
| | | import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; |
| | | import com.iailab.module.system.api.permission.PermissionApi; |
| | | import com.iailab.module.system.api.permission.dto.DeptDataPermissionRespDTO; |
| | | import net.sf.jsqlparser.expression.Alias; |
| | | import net.sf.jsqlparser.expression.Expression; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | import org.mockito.MockedStatic; |
| | | |
| | | import java.util.Map; |
| | | |
| | | import static com.iailab.framework.common.pojo.CommonResult.success; |
| | | import static com.iailab.framework.datapermission.core.rule.dept.DeptDataPermissionRule.EXPRESSION_NULL; |
| | | import static com.iailab.framework.test.core.util.RandomUtils.randomPojo; |
| | | import static com.iailab.framework.test.core.util.RandomUtils.randomString; |
| | | import static org.junit.jupiter.api.Assertions.*; |
| | | import static org.mockito.ArgumentMatchers.eq; |
| | | import static org.mockito.ArgumentMatchers.same; |
| | | import static org.mockito.Mockito.mockStatic; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | /** |
| | | * {@link DeptDataPermissionRule} 的单元测试 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { |
| | | |
| | | @InjectMocks |
| | | private DeptDataPermissionRule rule; |
| | | |
| | | @Mock |
| | | private PermissionApi permissionApi; |
| | | |
| | | @BeforeEach |
| | | @SuppressWarnings("unchecked") |
| | | public void setUp() { |
| | | // 清空 rule |
| | | rule.getTableNames().clear(); |
| | | ((Map<String, String>) ReflectUtil.getFieldValue(rule, "deptColumns")).clear(); |
| | | ((Map<String, String>) ReflectUtil.getFieldValue(rule, "deptColumns")).clear(); |
| | | } |
| | | |
| | | @Test // 无 LoginUser |
| | | public void testGetExpression_noLoginUser() { |
| | | // 准备参数 |
| | | String tableName = randomString(); |
| | | Alias tableAlias = new Alias(randomString()); |
| | | // mock 方法 |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertNull(expression); |
| | | } |
| | | |
| | | @Test // 无数据权限时 |
| | | public void testGetExpression_noDeptDataPermission() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法 |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(permissionApi 返回 null) |
| | | when(permissionApi.getDeptDataPermission(eq(loginUser.getId()))).thenReturn(success(null)); |
| | | |
| | | // 调用 |
| | | NullPointerException exception = assertThrows(NullPointerException.class, |
| | | () -> rule.getExpression(tableName, tableAlias)); |
| | | // 断言 |
| | | assertEquals("LoginUser(1) Table(t_user/u) 未返回数据权限", exception.getMessage()); |
| | | } |
| | | } |
| | | |
| | | @Test // 全部数据权限 |
| | | public void testGetExpression_allDeptDataPermission() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法(LoginUser) |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(DeptDataPermissionRespDTO) |
| | | DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true); |
| | | when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(success(deptDataPermission)); |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertNull(expression); |
| | | assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); |
| | | } |
| | | } |
| | | |
| | | @Test // 即不能查看部门,又不能查看自己,则说明 100% 无权限 |
| | | public void testGetExpression_noDept_noSelf() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法(LoginUser) |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(DeptDataPermissionRespDTO) |
| | | DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO(); |
| | | when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(success(deptDataPermission)); |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertEquals("null = null", expression.toString()); |
| | | assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); |
| | | } |
| | | } |
| | | |
| | | @Test // 拼接 Dept 和 User 的条件(字段都不符合) |
| | | public void testGetExpression_noDeptColumn_noSelfColumn() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法(LoginUser) |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(DeptDataPermissionRespDTO) |
| | | DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() |
| | | .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true); |
| | | when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(success(deptDataPermission)); |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertSame(EXPRESSION_NULL, expression); |
| | | assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); |
| | | } |
| | | } |
| | | |
| | | @Test // 拼接 Dept 和 User 的条件(self 符合) |
| | | public void testGetExpression_noDeptColumn_yesSelfColumn() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法(LoginUser) |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(DeptDataPermissionRespDTO) |
| | | DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() |
| | | .setSelf(true); |
| | | when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(success(deptDataPermission)); |
| | | // 添加 user 字段配置 |
| | | rule.addUserColumn("t_user", "id"); |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertEquals("u.id = 1", expression.toString()); |
| | | assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); |
| | | } |
| | | } |
| | | |
| | | @Test // 拼接 Dept 和 User 的条件(dept 符合) |
| | | public void testGetExpression_yesDeptColumn_noSelfColumn() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法(LoginUser) |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(DeptDataPermissionRespDTO) |
| | | DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() |
| | | .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)); |
| | | when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(success(deptDataPermission)); |
| | | // 添加 dept 字段配置 |
| | | rule.addDeptColumn("t_user", "dept_id"); |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertEquals("u.dept_id IN (10, 20)", expression.toString()); |
| | | assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); |
| | | } |
| | | } |
| | | |
| | | @Test // 拼接 Dept 和 User 的条件(dept + self 符合) |
| | | public void testGetExpression_yesDeptColumn_yesSelfColumn() { |
| | | try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock |
| | | = mockStatic(SecurityFrameworkUtils.class)) { |
| | | // 准备参数 |
| | | String tableName = "t_user"; |
| | | Alias tableAlias = new Alias("u"); |
| | | // mock 方法(LoginUser) |
| | | LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L) |
| | | .setUserType(UserTypeEnum.ADMIN.getValue())); |
| | | securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser); |
| | | // mock 方法(DeptDataPermissionRespDTO) |
| | | DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO() |
| | | .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true); |
| | | when(permissionApi.getDeptDataPermission(same(1L))).thenReturn(success(deptDataPermission)); |
| | | // 添加 user 字段配置 |
| | | rule.addUserColumn("t_user", "id"); |
| | | // 添加 dept 字段配置 |
| | | rule.addDeptColumn("t_user", "dept_id"); |
| | | |
| | | // 调用 |
| | | Expression expression = rule.getExpression(tableName, tableAlias); |
| | | // 断言 |
| | | assertEquals("(u.dept_id IN (10, 20) OR u.id = 1)", expression.toString()); |
| | | assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); |
| | | } |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.datapermission.core.util; |
| | | |
| | | import com.iailab.framework.datapermission.core.aop.DataPermissionContextHolder; |
| | | import org.junit.jupiter.api.Test; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.*; |
| | | |
| | | public class DataPermissionUtilsTest { |
| | | |
| | | @Test |
| | | public void testExecuteIgnore() { |
| | | DataPermissionUtils.executeIgnore(() -> assertFalse(DataPermissionContextHolder.get().enable())); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-framework</artifactId> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <artifactId>iailab-common-biz-ip</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <name>${project.artifactId}</name> |
| | | <description>IP 拓展,支持如下功能: |
| | | 1. IP 功能:查询 IP 对应的城市信息 |
| | | 基于 https://gitee.com/lionsoul/ip2region 实现 |
| | | 2. 城市功能:查询城市编码对应的城市信息 |
| | | 基于 https://github.com/modood/Administrative-divisions-of-China 实现 |
| | | </description> |
| | | <url>http://172.16.8.100:8888/summary/iailab-plat.git</url> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- IP地址检索 --> |
| | | <dependency> |
| | | <groupId>org.lionsoul</groupId> |
| | | <artifactId>ip2region</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.slf4j</groupId> |
| | | <artifactId>slf4j-api</artifactId> |
| | | <scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 --> |
| | | </dependency> |
| | | |
| | | <!-- Test 测试相关 --> |
| | | <dependency> |
| | | <groupId>com.iailab</groupId> |
| | | <artifactId>iailab-common-test</artifactId> |
| | | <scope>test</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
对比新文件 |
| | |
| | | package com.iailab.framework.ip.core; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonManagedReference; |
| | | import com.iailab.framework.ip.core.enums.AreaTypeEnum; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.ToString; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 区域节点,包括国家、省份、城市、地区等信息 |
| | | * |
| | | * 数据可见 resources/area.csv 文件 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @Data |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | @ToString(exclude = {"parent"}) |
| | | public class Area { |
| | | |
| | | /** |
| | | * 编号 - 全球,即根目录 |
| | | */ |
| | | public static final Integer ID_GLOBAL = 0; |
| | | /** |
| | | * 编号 - 中国 |
| | | */ |
| | | public static final Integer ID_CHINA = 1; |
| | | |
| | | /** |
| | | * 编号 |
| | | */ |
| | | private Integer id; |
| | | /** |
| | | * 名字 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 类型 |
| | | * |
| | | * 枚举 {@link AreaTypeEnum} |
| | | */ |
| | | private Integer type; |
| | | |
| | | /** |
| | | * 父节点 |
| | | */ |
| | | @JsonManagedReference |
| | | private Area parent; |
| | | /** |
| | | * 子节点 |
| | | */ |
| | | @JsonManagedReference |
| | | private List<Area> children; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.ip.core.enums; |
| | | |
| | | import com.iailab.framework.common.core.IntArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * 区域类型枚举 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @AllArgsConstructor |
| | | @Getter |
| | | public enum AreaTypeEnum implements IntArrayValuable { |
| | | |
| | | COUNTRY(1, "国家"), |
| | | PROVINCE(2, "省份"), |
| | | CITY(3, "城市"), |
| | | DISTRICT(4, "地区"), // 县、镇、区等 |
| | | ; |
| | | |
| | | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AreaTypeEnum::getType).toArray(); |
| | | |
| | | /** |
| | | * 类型 |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * 名字 |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public int[] array() { |
| | | return ARRAYS; |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.ip.core.utils; |
| | | |
| | | import cn.hutool.core.io.resource.ResourceUtil; |
| | | import cn.hutool.core.lang.Assert; |
| | | import cn.hutool.core.text.csv.CsvRow; |
| | | import cn.hutool.core.text.csv.CsvUtil; |
| | | import com.iailab.framework.common.util.object.ObjectUtils; |
| | | import com.iailab.framework.ip.core.Area; |
| | | import com.iailab.framework.ip.core.enums.AreaTypeEnum; |
| | | import lombok.NonNull; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.function.Function; |
| | | |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.findFirst; |
| | | |
| | | /** |
| | | * 区域工具类 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @Slf4j |
| | | public class AreaUtils { |
| | | |
| | | /** |
| | | * 初始化 SEARCHER |
| | | */ |
| | | @SuppressWarnings("InstantiationOfUtilityClass") |
| | | private final static AreaUtils INSTANCE = new AreaUtils(); |
| | | |
| | | /** |
| | | * Area 内存缓存,提升访问速度 |
| | | */ |
| | | private static Map<Integer, Area> areas; |
| | | |
| | | private AreaUtils() { |
| | | long now = System.currentTimeMillis(); |
| | | areas = new HashMap<>(); |
| | | areas.put(Area.ID_GLOBAL, new Area(Area.ID_GLOBAL, "全球", 0, |
| | | null, new ArrayList<>())); |
| | | // 从 csv 中加载数据 |
| | | List<CsvRow> rows = CsvUtil.getReader().read(ResourceUtil.getUtf8Reader("area.csv")).getRows(); |
| | | rows.remove(0); // 删除 header |
| | | for (CsvRow row : rows) { |
| | | // 创建 Area 对象 |
| | | Area area = new Area(Integer.valueOf(row.get(0)), row.get(1), Integer.valueOf(row.get(2)), |
| | | null, new ArrayList<>()); |
| | | // 添加到 areas 中 |
| | | areas.put(area.getId(), area); |
| | | } |
| | | |
| | | // 构建父子关系:因为 Area 中没有 parentId 字段,所以需要重复读取 |
| | | for (CsvRow row : rows) { |
| | | Area area = areas.get(Integer.valueOf(row.get(0))); // 自己 |
| | | Area parent = areas.get(Integer.valueOf(row.get(3))); // 父 |
| | | Assert.isTrue(area != parent, "{}:父子节点相同", area.getName()); |
| | | area.setParent(parent); |
| | | parent.getChildren().add(area); |
| | | } |
| | | log.info("启动加载 AreaUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now); |
| | | } |
| | | |
| | | /** |
| | | * 获得指定编号对应的区域 |
| | | * |
| | | * @param id 区域编号 |
| | | * @return 区域 |
| | | */ |
| | | public static Area getArea(Integer id) { |
| | | return areas.get(id); |
| | | } |
| | | |
| | | /** |
| | | * 获得指定区域对应的编号 |
| | | * |
| | | * @param pathStr 区域路径,例如说:河南省/石家庄市/新华区 |
| | | * @return 区域 |
| | | */ |
| | | public static Area parseArea(String pathStr) { |
| | | String[] paths = pathStr.split("/"); |
| | | Area area = null; |
| | | for (String path : paths) { |
| | | if (area == null) { |
| | | area = findFirst(areas.values(), item -> item.getName().equals(path)); |
| | | } else { |
| | | area = findFirst(area.getChildren(), item -> item.getName().equals(path)); |
| | | } |
| | | } |
| | | return area; |
| | | } |
| | | |
| | | /** |
| | | * 获取所有节点的全路径名称如:河南省/石家庄市/新华区 |
| | | * |
| | | * @param areas 地区树 |
| | | * @return 所有节点的全路径名称 |
| | | */ |
| | | public static List<String> getAreaNodePathList(List<Area> areas) { |
| | | List<String> paths = new ArrayList<>(); |
| | | areas.forEach(area -> getAreaNodePathList(area, "", paths)); |
| | | return paths; |
| | | } |
| | | |
| | | /** |
| | | * 构建一棵树的所有节点的全路径名称,并将其存储为 "祖先/父级/子级" 的形式 |
| | | * |
| | | * @param node 父节点 |
| | | * @param path 全路径名称 |
| | | * @param paths 全路径名称列表,省份/城市/地区 |
| | | */ |
| | | private static void getAreaNodePathList(Area node, String path, List<String> paths) { |
| | | if (node == null) { |
| | | return; |
| | | } |
| | | // 构建当前节点的路径 |
| | | String currentPath = path.isEmpty() ? node.getName() : path + "/" + node.getName(); |
| | | paths.add(currentPath); |
| | | // 递归遍历子节点 |
| | | for (Area child : node.getChildren()) { |
| | | getAreaNodePathList(child, currentPath, paths); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 格式化区域 |
| | | * |
| | | * @param id 区域编号 |
| | | * @return 格式化后的区域 |
| | | */ |
| | | public static String format(Integer id) { |
| | | return format(id, " "); |
| | | } |
| | | |
| | | /** |
| | | * 格式化区域 |
| | | * |
| | | * 例如说: |
| | | * 1. id = “静安区”时:上海 上海市 静安区 |
| | | * 2. id = “上海市”时:上海 上海市 |
| | | * 3. id = “上海”时:上海 |
| | | * 4. id = “美国”时:美国 |
| | | * 当区域在中国时,默认不显示中国 |
| | | * |
| | | * @param id 区域编号 |
| | | * @param separator 分隔符 |
| | | * @return 格式化后的区域 |
| | | */ |
| | | public static String format(Integer id, String separator) { |
| | | // 获得区域 |
| | | Area area = areas.get(id); |
| | | if (area == null) { |
| | | return null; |
| | | } |
| | | |
| | | // 格式化 |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (int i = 0; i < AreaTypeEnum.values().length; i++) { // 避免死循环 |
| | | sb.insert(0, area.getName()); |
| | | // “递归”父节点 |
| | | area = area.getParent(); |
| | | if (area == null |
| | | || ObjectUtils.equalsAny(area.getId(), Area.ID_GLOBAL, Area.ID_CHINA)) { // 跳过父节点为中国的情况 |
| | | break; |
| | | } |
| | | sb.insert(0, separator); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 获取指定类型的区域列表 |
| | | * |
| | | * @param type 区域类型 |
| | | * @param func 转换函数 |
| | | * @param <T> 结果类型 |
| | | * @return 区域列表 |
| | | */ |
| | | public static <T> List<T> getByType(AreaTypeEnum type, Function<Area, T> func) { |
| | | return convertList(areas.values(), func, area -> type.getType().equals(area.getType())); |
| | | } |
| | | |
| | | /** |
| | | * 根据区域编号、上级区域类型,获取上级区域编号 |
| | | * |
| | | * @param id 区域编号 |
| | | * @param type 区域类型 |
| | | * @return 上级区域编号 |
| | | */ |
| | | public static Integer getParentIdByType(Integer id, @NonNull AreaTypeEnum type) { |
| | | for (int i = 0; i < Byte.MAX_VALUE; i++) { |
| | | Area area = AreaUtils.getArea(id); |
| | | if (area == null) { |
| | | return null; |
| | | } |
| | | // 情况一:匹配到,返回它 |
| | | if (type.getType().equals(area.getType())) { |
| | | return area.getId(); |
| | | } |
| | | // 情况二:找到根节点,返回空 |
| | | if (area.getParent() == null || area.getParent().getId() == null) { |
| | | return null; |
| | | } |
| | | // 其它:继续向上查找 |
| | | id = area.getParent().getId(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.ip.core.utils; |
| | | |
| | | import cn.hutool.core.io.resource.ResourceUtil; |
| | | import com.iailab.framework.ip.core.Area; |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.lionsoul.ip2region.xdb.Searcher; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * IP 工具类 |
| | | * |
| | | * IP 数据源来自 ip2region.xdb 精简版,基于 <a href="https://gitee.com/zhijiantianya/ip2region"/> 项目 |
| | | * |
| | | * @author wanglhup |
| | | */ |
| | | @Slf4j |
| | | public class IPUtils { |
| | | |
| | | /** |
| | | * 初始化 SEARCHER |
| | | */ |
| | | @SuppressWarnings("InstantiationOfUtilityClass") |
| | | private final static IPUtils INSTANCE = new IPUtils(); |
| | | |
| | | /** |
| | | * IP 查询器,启动加载到内存中 |
| | | */ |
| | | private static Searcher SEARCHER; |
| | | |
| | | /** |
| | | * 私有化构造 |
| | | */ |
| | | private IPUtils() { |
| | | try { |
| | | long now = System.currentTimeMillis(); |
| | | byte[] bytes = ResourceUtil.readBytes("ip2region.xdb"); |
| | | SEARCHER = Searcher.newWithBuffer(bytes); |
| | | log.info("启动加载 IPUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now); |
| | | } catch (IOException e) { |
| | | log.error("启动加载 IPUtils 失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 查询 IP 对应的地区编号 |
| | | * |
| | | * @param ip IP 地址,格式为 127.0.0.1 |
| | | * @return 地区id |
| | | */ |
| | | @SneakyThrows |
| | | public static Integer getAreaId(String ip) { |
| | | return Integer.parseInt(SEARCHER.search(ip.trim())); |
| | | } |
| | | |
| | | /** |
| | | * 查询 IP 对应的地区编号 |
| | | * |
| | | * @param ip IP 地址的时间戳,格式参考{@link Searcher#checkIP(String)} 的返回 |
| | | * @return 地区编号 |
| | | */ |
| | | @SneakyThrows |
| | | public static Integer getAreaId(long ip) { |
| | | return Integer.parseInt(SEARCHER.search(ip)); |
| | | } |
| | | |
| | | /** |
| | | * 查询 IP 对应的地区 |
| | | * |
| | | * @param ip IP 地址,格式为 127.0.0.1 |
| | | * @return 地区 |
| | | */ |
| | | public static Area getArea(String ip) { |
| | | return AreaUtils.getArea(getAreaId(ip)); |
| | | } |
| | | |
| | | /** |
| | | * 查询 IP 对应的地区 |
| | | * |
| | | * @param ip IP 地址的时间戳,格式参考{@link Searcher#checkIP(String)} 的返回 |
| | | * @return 地区 |
| | | */ |
| | | public static Area getArea(long ip) { |
| | | return AreaUtils.getArea(getAreaId(ip)); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | /** |
| | | * IP 拓展,支持如下功能: |
| | | * |
| | | * 1. IP 功能:查询 IP 对应的城市信息 |
| | | * 基于 https://gitee.com/lionsoul/ip2region 实现 |
| | | * 2. 城市功能:查询城市编码对应的城市信息 |
| | | * 基于 https://github.com/modood/Administrative-divisions-of-China 实现 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | package com.iailab.framework.ip; |
对比新文件 |
| | |
| | | id,name,type,parentId |
| | | 1,中国,1,0 |
| | | 2,蒙古,1,0 |
| | | 3,朝鲜,1,0 |
| | | 4,韩国,1,0 |
| | | 5,日本,1,0 |
| | | 6,菲律宾,1,0 |
| | | 7,越南,1,0 |
| | | 8,老挝,1,0 |
| | | 9,柬埔寨,1,0 |
| | | 10,缅甸,1,0 |
| | | 11,泰国,1,0 |
| | | 12,马来西亚,1,0 |
| | | 13,文莱,1,0 |
| | | 14,新加坡,1,0 |
| | | 15,印度尼西亚,1,0 |
| | | 16,东帝汶,1,0 |
| | | 17,尼泊尔,1,0 |
| | | 18,不丹,1,0 |
| | | 19,孟加拉国,1,0 |
| | | 20,印度,1,0 |
| | | 21,巴基斯坦,1,0 |
| | | 22,斯里兰卡,1,0 |
| | | 23,马尔代夫,1,0 |
| | | 24,哈萨克斯坦,1,0 |
| | | 25,吉尔吉斯斯坦,1,0 |
| | | 26,塔吉克斯坦,1,0 |
| | | 27,乌兹别克斯坦,1,0 |
| | | 28,土库曼斯坦,1,0 |
| | | 29,阿富汗,1,0 |
| | | 30,伊拉克,1,0 |
| | | 31,伊朗,1,0 |
| | | 32,叙利亚,1,0 |
| | | 33,约旦,1,0 |
| | | 34,黎巴嫩,1,0 |
| | | 35,以色列,1,0 |
| | | 36,巴勒斯坦,1,0 |
| | | 37,沙特阿拉伯,1,0 |
| | | 38,巴林,1,0 |
| | | 39,卡塔尔,1,0 |
| | | 40,科威特,1,0 |
| | | 41,阿拉伯联合酋长国,1,0 |
| | | 42,阿曼,1,0 |
| | | 43,也门,1,0 |
| | | 44,格鲁吉亚,1,0 |
| | | 45,亚美尼亚,1,0 |
| | | 46,阿塞拜疆,1,0 |
| | | 47,土耳其,1,0 |
| | | 48,塞浦路斯,1,0 |
| | | 49,芬兰,1,0 |
| | | 50,瑞典,1,0 |
| | | 51,挪威,1,0 |
| | | 52,冰岛,1,0 |
| | | 53,丹麦,1,0 |
| | | 54,爱沙尼亚,1,0 |
| | | 55,拉脱维亚,1,0 |
| | | 56,立陶宛,1,0 |
| | | 57,白俄罗斯,1,0 |
| | | 58,俄罗斯,1,0 |
| | | 59,乌克兰,1,0 |
| | | 60,摩尔多瓦,1,0 |
| | | 61,波兰,1,0 |
| | | 62,捷克,1,0 |
| | | 63,斯洛伐克,1,0 |
| | | 64,匈牙利,1,0 |
| | | 65,德国,1,0 |
| | | 66,奥地利,1,0 |
| | | 67,瑞士,1,0 |
| | | 68,列支敦士登,1,0 |
| | | 69,英国,1,0 |
| | | 70,爱尔兰,1,0 |
| | | 71,荷兰,1,0 |
| | | 72,比利时,1,0 |
| | | 73,卢森堡,1,0 |
| | | 74,法国,1,0 |
| | | 75,摩纳哥,1,0 |
| | | 76,罗马尼亚,1,0 |
| | | 77,保加利亚,1,0 |
| | | 78,塞尔维亚,1,0 |
| | | 79,马其顿,1,0 |
| | | 80,阿尔巴尼亚,1,0 |
| | | 81,希腊,1,0 |
| | | 82,斯洛文尼亚,1,0 |
| | | 83,克罗地亚,1,0 |
| | | 84,波斯尼亚和墨塞哥维那,1,0 |
| | | 85,意大利,1,0 |
| | | 86,梵蒂冈,1,0 |
| | | 87,圣马力诺,1,0 |
| | | 88,马耳他,1,0 |
| | | 89,西班牙,1,0 |
| | | 90,葡萄牙,1,0 |
| | | 91,安道尔共和国,1,0 |
| | | 92,埃及,1,0 |
| | | 93,利比亚,1,0 |
| | | 94,苏丹,1,0 |
| | | 95,突尼斯,1,0 |
| | | 96,阿尔及利亚,1,0 |
| | | 97,摩洛哥,1,0 |
| | | 98,亚速尔群岛,1,0 |
| | | 99,马德拉群岛,1,0 |
| | | 100,埃塞俄比亚,1,0 |
| | | 101,厄立特里亚,1,0 |
| | | 102,索马里,1,0 |
| | | 103,吉布提,1,0 |
| | | 104,肯尼亚,1,0 |
| | | 105,坦桑尼亚,1,0 |
| | | 106,乌干达,1,0 |
| | | 107,卢旺达,1,0 |
| | | 108,布隆迪,1,0 |
| | | 109,塞舌尔,1,0 |
| | | 110,圣多美及普林西比,1,0 |
| | | 111,塞内加尔,1,0 |
| | | 112,冈比亚,1,0 |
| | | 113,马里,1,0 |
| | | 114,布基纳法索,1,0 |
| | | 115,几内亚,1,0 |
| | | 116,几内亚比绍,1,0 |
| | | 117,佛得角,1,0 |
| | | 118,塞拉利昂,1,0 |
| | | 119,利比里亚,1,0 |
| | | 120,科特迪瓦,1,0 |
| | | 121,加纳,1,0 |
| | | 122,多哥,1,0 |
| | | 123,贝宁,1,0 |
| | | 124,尼日尔,1,0 |
| | | 125,加那利群岛,1,0 |
| | | 126,赞比亚,1,0 |
| | | 127,安哥拉,1,0 |
| | | 128,津巴布韦,1,0 |
| | | 129,马拉维,1,0 |
| | | 130,莫桑比克,1,0 |
| | | 131,博茨瓦纳,1,0 |
| | | 132,纳米比亚,1,0 |
| | | 133,南非,1,0 |
| | | 134,斯威士兰,1,0 |
| | | 135,莱索托,1,0 |
| | | 136,马达加斯加,1,0 |
| | | 137,科摩罗,1,0 |
| | | 138,毛里求斯,1,0 |
| | | 139,留尼旺,1,0 |
| | | 140,圣赫勒拿,1,0 |
| | | 141,澳大利亚,1,0 |
| | | 142,新西兰,1,0 |
| | | 143,巴布亚新几内亚,1,0 |
| | | 144,所罗门群岛,1,0 |
| | | 145,瓦努阿图共和国,1,0 |
| | | 146,密克罗尼西亚,1,0 |
| | | 147,马绍尔群岛,1,0 |
| | | 148,帕劳,1,0 |
| | | 149,瑙鲁,1,0 |
| | | 150,基里巴斯,1,0 |
| | | 151,图瓦卢,1,0 |
| | | 152,萨摩亚,1,0 |
| | | 153,斐济,1,0 |
| | | 154,汤加,1,0 |
| | | 155,库克群岛,1,0 |
| | | 156,关岛,1,0 |
| | | 157,新喀里多尼亚,1,0 |
| | | 158,法属波利尼西亚,1,0 |
| | | 159,皮特凯恩岛,1,0 |
| | | 160,瓦利斯与富图纳,1,0 |
| | | 161,纽埃,1,0 |
| | | 162,托克劳,1,0 |
| | | 163,美属萨摩亚,1,0 |
| | | 164,北马里亚纳,1,0 |
| | | 165,加拿大,1,0 |
| | | 166,美国,1,0 |
| | | 167,墨西哥,1,0 |
| | | 168,格陵兰,1,0 |
| | | 169,危地马拉,1,0 |
| | | 170,伯利兹,1,0 |
| | | 171,萨尔瓦多,1,0 |
| | | 172,洪都拉斯,1,0 |
| | | 173,尼加拉瓜,1,0 |
| | | 174,哥斯达黎加,1,0 |
| | | 175,巴拿马,1,0 |
| | | 176,巴哈马,1,0 |
| | | 177,古巴,1,0 |
| | | 178,牙买加,1,0 |
| | | 179,海地,1,0 |
| | | 180,多米尼加共和国,1,0 |
| | | 181,安提瓜和巴布达,1,0 |
| | | 182,圣基茨和尼维斯,1,0 |
| | | 183,多米尼克,1,0 |
| | | 184,圣卢西亚,1,0 |
| | | 185,圣文森特和格林纳丁斯,1,0 |
| | | 186,格林纳达,1,0 |
| | | 187,巴巴多斯,1,0 |
| | | 188,特立尼达和多巴哥,1,0 |
| | | 189,波多黎各,1,0 |
| | | 190,英属维尔京群岛,1,0 |
| | | 191,美属维尔京群岛,1,0 |
| | | 192,安圭拉,1,0 |
| | | 193,蒙特塞拉特岛,1,0 |
| | | 194,瓜德罗普,1,0 |
| | | 195,马提尼克,1,0 |
| | | 196,荷属安的列斯,1,0 |
| | | 197,阿鲁巴,1,0 |
| | | 198,特克斯和凯科斯群岛,1,0 |
| | | 199,开曼群岛,1,0 |
| | | 200,百慕大,1,0 |
| | | 201,哥伦比亚,1,0 |
| | | 202,委内瑞拉,1,0 |
| | | 203,圭亚那,1,0 |
| | | 204,法属圭亚那,1,0 |
| | | 205,苏里南,1,0 |
| | | 206,厄瓜多尔,1,0 |
| | | 207,秘鲁,1,0 |
| | | 208,玻利维亚,1,0 |
| | | 209,巴西,1,0 |
| | | 210,智利,1,0 |
| | | 211,阿根廷,1,0 |
| | | 212,乌拉圭,1,0 |
| | | 213,巴拉圭,1,0 |
| | | 214,波黑,1,0 |
| | | 215,直布罗陀,1,0 |
| | | 216,新喀里多尼亚群岛,1,0 |
| | | 217,瓦利斯和富图纳群岛,1,0 |
| | | 218,泽西岛,1,0 |
| | | 219,黑山,1,0 |
| | | 220,英属马恩岛,1,0 |
| | | 221,尼日利亚,1,0 |
| | | 222,喀麦隆,1,0 |
| | | 223,加蓬,1,0 |
| | | 224,乍得,1,0 |
| | | 225,刚果共和国,1,0 |
| | | 226,中非共和国,1,0 |
| | | 227,南苏丹,1,0 |
| | | 228,赤道几内亚,1,0 |
| | | 229,毛里塔尼亚,1,0 |
| | | 230,刚果民主共和国,1,0 |
| | | 231,留尼汪岛,1,0 |
| | | 232,格陵兰岛,1,0 |
| | | 233,法罗群岛,1,0 |
| | | 234,根西岛,1,0 |
| | | 235,百慕大群岛,1,0 |
| | | 236,圣皮埃尔和密克隆群岛,1,0 |
| | | 237,法属圣马丁,1,0 |
| | | 238,奥兰群岛,1,0 |
| | | 239,北马里亚纳群岛,1,0 |
| | | 240,库拉索,1,0 |
| | | 241,博内尔岛,1,0 |
| | | 242,圣马丁岛,1,0 |
| | | 243,圣巴泰勒米岛,1,0 |
| | | 244,福克兰群岛,1,0 |
| | | 245,圣多美和普林西比,1,0 |
| | | 246,英属印度洋领地,1,0 |
| | | 247,东萨摩亚,1,0 |
| | | 248,诺福克岛,1,0 |
| | | 110000,北京,2,1 |
| | | 120000,天津,2,1 |
| | | 130000,河北省,2,1 |
| | | 140000,山西省,2,1 |
| | | 150000,内蒙古自治区,2,1 |
| | | 210000,辽宁省,2,1 |
| | | 220000,吉林省,2,1 |
| | | 230000,黑龙江省,2,1 |
| | | 310000,上海,2,1 |
| | | 320000,江苏省,2,1 |
| | | 330000,浙江省,2,1 |
| | | 340000,安徽省,2,1 |
| | | 350000,福建省,2,1 |
| | | 360000,江西省,2,1 |
| | | 370000,山东省,2,1 |
| | | 410000,河南省,2,1 |
| | | 420000,湖北省,2,1 |
| | | 430000,湖南省,2,1 |
| | | 440000,广东省,2,1 |
| | | 450000,广西壮族自治区,2,1 |
| | | 460000,海南省,2,1 |
| | | 500000,重庆,2,1 |
| | | 510000,四川省,2,1 |
| | | 520000,贵州省,2,1 |
| | | 530000,云南省,2,1 |
| | | 540000,西藏自治区,2,1 |
| | | 610000,陕西省,2,1 |
| | | 620000,甘肃省,2,1 |
| | | 630000,青海省,2,1 |
| | | 640000,宁夏回族自治区,2,1 |
| | | 650000,新疆维吾尔自治区,2,1 |
| | | 110100,北京市,3,110000 |
| | | 120100,天津市,3,120000 |
| | | 130100,石家庄市,3,130000 |
| | | 130200,唐山市,3,130000 |
| | | 130300,秦皇岛市,3,130000 |
| | | 130400,邯郸市,3,130000 |
| | | 130500,邢台市,3,130000 |
| | | 130600,保定市,3,130000 |
| | | 130700,张家口市,3,130000 |
| | | 130800,承德市,3,130000 |
| | | 130900,沧州市,3,130000 |
| | | 131000,廊坊市,3,130000 |
| | | 131100,衡水市,3,130000 |
| | | 140100,太原市,3,140000 |
| | | 140200,大同市,3,140000 |
| | | 140300,阳泉市,3,140000 |
| | | 140400,长治市,3,140000 |
| | | 140500,晋城市,3,140000 |
| | | 140600,朔州市,3,140000 |
| | | 140700,晋中市,3,140000 |
| | | 140800,运城市,3,140000 |
| | | 140900,忻州市,3,140000 |
| | | 141000,临汾市,3,140000 |
| | | 141100,吕梁市,3,140000 |
| | | 150100,呼和浩特市,3,150000 |
| | | 150200,包头市,3,150000 |
| | | 150300,乌海市,3,150000 |
| | | 150400,赤峰市,3,150000 |
| | | 150500,通辽市,3,150000 |
| | | 150600,鄂尔多斯市,3,150000 |
| | | 150700,呼伦贝尔市,3,150000 |
| | | 150800,巴彦淖尔市,3,150000 |
| | | 150900,乌兰察布市,3,150000 |
| | | 152200,兴安盟,3,150000 |
| | | 152500,锡林郭勒盟,3,150000 |
| | | 152900,阿拉善盟,3,150000 |
| | | 210100,沈阳市,3,210000 |
| | | 210200,大连市,3,210000 |
| | | 210300,鞍山市,3,210000 |
| | | 210400,抚顺市,3,210000 |
| | | 210500,本溪市,3,210000 |
| | | 210600,丹东市,3,210000 |
| | | 210700,锦州市,3,210000 |
| | | 210800,营口市,3,210000 |
| | | 210900,阜新市,3,210000 |
| | | 211000,辽阳市,3,210000 |
| | | 211100,盘锦市,3,210000 |
| | | 211200,铁岭市,3,210000 |
| | | 211300,朝阳市,3,210000 |
| | | 211400,葫芦岛市,3,210000 |
| | | 220100,长春市,3,220000 |
| | | 220200,吉林市,3,220000 |
| | | 220300,四平市,3,220000 |
| | | 220400,辽源市,3,220000 |
| | | 220500,通化市,3,220000 |
| | | 220600,白山市,3,220000 |
| | | 220700,松原市,3,220000 |
| | | 220800,白城市,3,220000 |
| | | 222400,延边朝鲜族自治州,3,220000 |
| | | 230100,哈尔滨市,3,230000 |
| | | 230200,齐齐哈尔市,3,230000 |
| | | 230300,鸡西市,3,230000 |
| | | 230400,鹤岗市,3,230000 |
| | | 230500,双鸭山市,3,230000 |
| | | 230600,大庆市,3,230000 |
| | | 230700,伊春市,3,230000 |
| | | 230800,佳木斯市,3,230000 |
| | | 230900,七台河市,3,230000 |
| | | 231000,牡丹江市,3,230000 |
| | | 231100,黑河市,3,230000 |
| | | 231200,绥化市,3,230000 |
| | | 232700,大兴安岭地区,3,230000 |
| | | 310100,上海市,3,310000 |
| | | 320100,南京市,3,320000 |
| | | 320200,无锡市,3,320000 |
| | | 320300,徐州市,3,320000 |
| | | 320400,常州市,3,320000 |
| | | 320500,苏州市,3,320000 |
| | | 320600,南通市,3,320000 |
| | | 320700,连云港市,3,320000 |
| | | 320800,淮安市,3,320000 |
| | | 320900,盐城市,3,320000 |
| | | 321000,扬州市,3,320000 |
| | | 321100,镇江市,3,320000 |
| | | 321200,泰州市,3,320000 |
| | | 321300,宿迁市,3,320000 |
| | | 330100,杭州市,3,330000 |
| | | 330200,宁波市,3,330000 |
| | | 330300,温州市,3,330000 |
| | | 330400,嘉兴市,3,330000 |
| | | 330500,湖州市,3,330000 |
| | | 330600,绍兴市,3,330000 |
| | | 330700,金华市,3,330000 |
| | | 330800,衢州市,3,330000 |
| | | 330900,舟山市,3,330000 |
| | | 331000,台州市,3,330000 |
| | | 331100,丽水市,3,330000 |
| | | 340100,合肥市,3,340000 |
| | | 340200,芜湖市,3,340000 |
| | | 340300,蚌埠市,3,340000 |
| | | 340400,淮南市,3,340000 |
| | | 340500,马鞍山市,3,340000 |
| | | 340600,淮北市,3,340000 |
| | | 340700,铜陵市,3,340000 |
| | | 340800,安庆市,3,340000 |
| | | 341000,黄山市,3,340000 |
| | | 341100,滁州市,3,340000 |
| | | 341200,阜阳市,3,340000 |
| | | 341300,宿州市,3,340000 |
| | | 341500,六安市,3,340000 |
| | | 341600,亳州市,3,340000 |
| | | 341700,池州市,3,340000 |
| | | 341800,宣城市,3,340000 |
| | | 350100,福州市,3,350000 |
| | | 350200,厦门市,3,350000 |
| | | 350300,莆田市,3,350000 |
| | | 350400,三明市,3,350000 |
| | | 350500,泉州市,3,350000 |
| | | 350600,漳州市,3,350000 |
| | | 350700,南平市,3,350000 |
| | | 350800,龙岩市,3,350000 |
| | | 350900,宁德市,3,350000 |
| | | 360100,南昌市,3,360000 |
| | | 360200,景德镇市,3,360000 |
| | | 360300,萍乡市,3,360000 |
| | | 360400,九江市,3,360000 |
| | | 360500,新余市,3,360000 |
| | | 360600,鹰潭市,3,360000 |
| | | 360700,赣州市,3,360000 |
| | | 360800,吉安市,3,360000 |
| | | 360900,宜春市,3,360000 |
| | | 361000,抚州市,3,360000 |
| | | 361100,上饶市,3,360000 |
| | | 370100,济南市,3,370000 |
| | | 370200,青岛市,3,370000 |
| | | 370300,淄博市,3,370000 |
| | | 370400,枣庄市,3,370000 |
| | | 370500,东营市,3,370000 |
| | | 370600,烟台市,3,370000 |
| | | 370700,潍坊市,3,370000 |
| | | 370800,济宁市,3,370000 |
| | | 370900,泰安市,3,370000 |
| | | 371000,威海市,3,370000 |
| | | 371100,日照市,3,370000 |
| | | 371300,临沂市,3,370000 |
| | | 371400,德州市,3,370000 |
| | | 371500,聊城市,3,370000 |
| | | 371600,滨州市,3,370000 |
| | | 371700,菏泽市,3,370000 |
| | | 410100,郑州市,3,410000 |
| | | 410200,开封市,3,410000 |
| | | 410300,洛阳市,3,410000 |
| | | 410400,平顶山市,3,410000 |
| | | 410500,安阳市,3,410000 |
| | | 410600,鹤壁市,3,410000 |
| | | 410700,新乡市,3,410000 |
| | | 410800,焦作市,3,410000 |
| | | 410900,濮阳市,3,410000 |
| | | 411000,许昌市,3,410000 |
| | | 411100,漯河市,3,410000 |
| | | 411200,三门峡市,3,410000 |
| | | 411300,南阳市,3,410000 |
| | | 411400,商丘市,3,410000 |
| | | 411500,信阳市,3,410000 |
| | | 411600,周口市,3,410000 |
| | | 411700,驻马店市,3,410000 |
| | | 419000,省直辖县级行政区划,3,410000 |
| | | 420100,武汉市,3,420000 |
| | | 420200,黄石市,3,420000 |
| | | 420300,十堰市,3,420000 |
| | | 420500,宜昌市,3,420000 |
| | | 420600,襄阳市,3,420000 |
| | | 420700,鄂州市,3,420000 |
| | | 420800,荆门市,3,420000 |
| | | 420900,孝感市,3,420000 |
| | | 421000,荆州市,3,420000 |
| | | 421100,黄冈市,3,420000 |
| | | 421200,咸宁市,3,420000 |
| | | 421300,随州市,3,420000 |
| | | 422800,恩施土家族苗族自治州,3,420000 |
| | | 429000,省直辖县级行政区划,3,420000 |
| | | 430100,长沙市,3,430000 |
| | | 430200,株洲市,3,430000 |
| | | 430300,湘潭市,3,430000 |
| | | 430400,衡阳市,3,430000 |
| | | 430500,邵阳市,3,430000 |
| | | 430600,岳阳市,3,430000 |
| | | 430700,常德市,3,430000 |
| | | 430800,张家界市,3,430000 |
| | | 430900,益阳市,3,430000 |
| | | 431000,郴州市,3,430000 |
| | | 431100,永州市,3,430000 |
| | | 431200,怀化市,3,430000 |
| | | 431300,娄底市,3,430000 |
| | | 433100,湘西土家族苗族自治州,3,430000 |
| | | 440100,广州市,3,440000 |
| | | 440200,韶关市,3,440000 |
| | | 440300,深圳市,3,440000 |
| | | 440400,珠海市,3,440000 |
| | | 440500,汕头市,3,440000 |
| | | 440600,佛山市,3,440000 |
| | | 440700,江门市,3,440000 |
| | | 440800,湛江市,3,440000 |
| | | 440900,茂名市,3,440000 |
| | | 441200,肇庆市,3,440000 |
| | | 441300,惠州市,3,440000 |
| | | 441400,梅州市,3,440000 |
| | | 441500,汕尾市,3,440000 |
| | | 441600,河源市,3,440000 |
| | | 441700,阳江市,3,440000 |
| | | 441800,清远市,3,440000 |
| | | 441900,东莞市,3,440000 |
| | | 441901,莞城区,4,441900 |
| | | 441902,南城区,4,441900 |
| | | 441904,万江区,4,441900 |
| | | 441905,石碣镇,4,441900 |
| | | 441906,石龙镇,4,441900 |
| | | 441907,茶山镇,4,441900 |
| | | 441908,石排镇,4,441900 |
| | | 441909,企石镇,4,441900 |
| | | 441910,横沥镇,4,441900 |
| | | 441911,桥头镇,4,441900 |
| | | 441912,谢岗镇,4,441900 |
| | | 441913,东坑镇,4,441900 |
| | | 441914,常平镇,4,441900 |
| | | 441915,寮步镇,4,441900 |
| | | 441916,大朗镇,4,441900 |
| | | 441917,麻涌镇,4,441900 |
| | | 441918,中堂镇,4,441900 |
| | | 441919,高埗镇,4,441900 |
| | | 441920,樟木头镇,4,441900 |
| | | 441921,大岭山镇,4,441900 |
| | | 441922,望牛墩镇,4,441900 |
| | | 441923,黄江镇,4,441900 |
| | | 441924,洪梅镇,4,441900 |
| | | 441925,清溪镇,4,441900 |
| | | 441926,沙田镇,4,441900 |
| | | 441927,道滘镇,4,441900 |
| | | 441928,塘厦镇,4,441900 |
| | | 441929,虎门镇,4,441900 |
| | | 441930,厚街镇,4,441900 |
| | | 441931,凤岗镇,4,441900 |
| | | 441932,长安镇,4,441900 |
| | | 442000,中山市,3,440000 |
| | | 442001,石岐街道,4,442000 |
| | | 442002,东区街道,4,442000 |
| | | 442003,中山港街道,4,442000 |
| | | 442004,西区街道,4,442000 |
| | | 442005,南区街道,4,442000 |
| | | 442006,五桂山街道,4,442000 |
| | | 442007,民众街道,4,442000 |
| | | 442008,南朗街道,4,442000 |
| | | 442009,黄圃镇,4,442000 |
| | | 442010,东凤镇,4,442000 |
| | | 442011,古镇镇,4,442000 |
| | | 442012,沙溪镇,4,442000 |
| | | 442013,坦洲镇,4,442000 |
| | | 442014,港口镇,4,442000 |
| | | 442015,三角镇,4,442000 |
| | | 442016,横栏镇,4,442000 |
| | | 442017,南头镇,4,442000 |
| | | 442018,阜沙镇,4,442000 |
| | | 442019,三乡镇,4,442000 |
| | | 442020,板芙镇,4,442000 |
| | | 442021,大涌镇,4,442000 |
| | | 442022,神湾镇,4,442000 |
| | | 442023,小榄镇,4,442000 |
| | | 445100,潮州市,3,440000 |
| | | 445200,揭阳市,3,440000 |
| | | 445300,云浮市,3,440000 |
| | | 450100,南宁市,3,450000 |
| | | 450200,柳州市,3,450000 |
| | | 450300,桂林市,3,450000 |
| | | 450400,梧州市,3,450000 |
| | | 450500,北海市,3,450000 |
| | | 450600,防城港市,3,450000 |
| | | 450700,钦州市,3,450000 |
| | | 450800,贵港市,3,450000 |
| | | 450900,玉林市,3,450000 |
| | | 451000,百色市,3,450000 |
| | | 451100,贺州市,3,450000 |
| | | 451200,河池市,3,450000 |
| | | 451300,来宾市,3,450000 |
| | | 451400,崇左市,3,450000 |
| | | 460100,海口市,3,460000 |
| | | 460200,三亚市,3,460000 |
| | | 460300,三沙市,3,460000 |
| | | 460400,儋州市,3,460000 |
| | | 469000,省直辖县级行政区划,3,460000 |
| | | 500100,重庆市,3,500000 |
| | | 510100,成都市,3,510000 |
| | | 510300,自贡市,3,510000 |
| | | 510400,攀枝花市,3,510000 |
| | | 510500,泸州市,3,510000 |
| | | 510600,德阳市,3,510000 |
| | | 510700,绵阳市,3,510000 |
| | | 510800,广元市,3,510000 |
| | | 510900,遂宁市,3,510000 |
| | | 511000,内江市,3,510000 |
| | | 511100,乐山市,3,510000 |
| | | 511300,南充市,3,510000 |
| | | 511400,眉山市,3,510000 |
| | | 511500,宜宾市,3,510000 |
| | | 511600,广安市,3,510000 |
| | | 511700,达州市,3,510000 |
| | | 511800,雅安市,3,510000 |
| | | 511900,巴中市,3,510000 |
| | | 512000,资阳市,3,510000 |
| | | 513200,阿坝藏族羌族自治州,3,510000 |
| | | 513300,甘孜藏族自治州,3,510000 |
| | | 513400,凉山彝族自治州,3,510000 |
| | | 520100,贵阳市,3,520000 |
| | | 520200,六盘水市,3,520000 |
| | | 520300,遵义市,3,520000 |
| | | 520400,安顺市,3,520000 |
| | | 520500,毕节市,3,520000 |
| | | 520600,铜仁市,3,520000 |
| | | 522300,黔西南布依族苗族自治州,3,520000 |
| | | 522600,黔东南苗族侗族自治州,3,520000 |
| | | 522700,黔南布依族苗族自治州,3,520000 |
| | | 530100,昆明市,3,530000 |
| | | 530300,曲靖市,3,530000 |
| | | 530400,玉溪市,3,530000 |
| | | 530500,保山市,3,530000 |
| | | 530600,昭通市,3,530000 |
| | | 530700,丽江市,3,530000 |
| | | 530800,普洱市,3,530000 |
| | | 530900,临沧市,3,530000 |
| | | 532300,楚雄彝族自治州,3,530000 |
| | | 532500,红河哈尼族彝族自治州,3,530000 |
| | | 532600,文山壮族苗族自治州,3,530000 |
| | | 532800,西双版纳傣族自治州,3,530000 |
| | | 532900,大理白族自治州,3,530000 |
| | | 533100,德宏傣族景颇族自治州,3,530000 |
| | | 533300,怒江傈僳族自治州,3,530000 |
| | | 533400,迪庆藏族自治州,3,530000 |
| | | 540100,拉萨市,3,540000 |
| | | 540200,日喀则市,3,540000 |
| | | 540300,昌都市,3,540000 |
| | | 540400,林芝市,3,540000 |
| | | 540500,山南市,3,540000 |
| | | 540600,那曲市,3,540000 |
| | | 542500,阿里地区,3,540000 |
| | | 610100,西安市,3,610000 |
| | | 610200,铜川市,3,610000 |
| | | 610300,宝鸡市,3,610000 |
| | | 610400,咸阳市,3,610000 |
| | | 610500,渭南市,3,610000 |
| | | 610600,延安市,3,610000 |
| | | 610700,汉中市,3,610000 |
| | | 610800,榆林市,3,610000 |
| | | 610900,安康市,3,610000 |
| | | 611000,商洛市,3,610000 |
| | | 620100,兰州市,3,620000 |
| | | 620200,嘉峪关市,3,620000 |
| | | 620300,金昌市,3,620000 |
| | | 620400,白银市,3,620000 |
| | | 620500,天水市,3,620000 |
| | | 620600,武威市,3,620000 |
| | | 620700,张掖市,3,620000 |
| | | 620800,平凉市,3,620000 |
| | | 620900,酒泉市,3,620000 |
| | | 621000,庆阳市,3,620000 |
| | | 621100,定西市,3,620000 |
| | | 621200,陇南市,3,620000 |
| | | 622900,临夏回族自治州,3,620000 |
| | | 623000,甘南藏族自治州,3,620000 |
| | | 630100,西宁市,3,630000 |
| | | 630200,海东市,3,630000 |
| | | 632200,海北藏族自治州,3,630000 |
| | | 632300,黄南藏族自治州,3,630000 |
| | | 632500,海南藏族自治州,3,630000 |
| | | 632600,果洛藏族自治州,3,630000 |
| | | 632700,玉树藏族自治州,3,630000 |
| | | 632800,海西蒙古族藏族自治州,3,630000 |
| | | 640100,银川市,3,640000 |
| | | 640200,石嘴山市,3,640000 |
| | | 640300,吴忠市,3,640000 |
| | | 640400,固原市,3,640000 |
| | | 640500,中卫市,3,640000 |
| | | 650100,乌鲁木齐市,3,650000 |
| | | 650200,克拉玛依市,3,650000 |
| | | 650400,吐鲁番市,3,650000 |
| | | 650500,哈密市,3,650000 |
| | | 652300,昌吉回族自治州,3,650000 |
| | | 652700,博尔塔拉蒙古自治州,3,650000 |
| | | 652800,巴音郭楞蒙古自治州,3,650000 |
| | | 652900,阿克苏地区,3,650000 |
| | | 653000,克孜勒苏柯尔克孜自治州,3,650000 |
| | | 653100,喀什地区,3,650000 |
| | | 653200,和田地区,3,650000 |
| | | 654000,伊犁哈萨克自治州,3,650000 |
| | | 654200,塔城地区,3,650000 |
| | | 654300,阿勒泰地区,3,650000 |
| | | 659000,自治区直辖县级行政区划,3,650000 |
| | | 110101,东城区,4,110100 |
| | | 110102,西城区,4,110100 |
| | | 110105,朝阳区,4,110100 |
| | | 110106,丰台区,4,110100 |
| | | 110107,石景山区,4,110100 |
| | | 110108,海淀区,4,110100 |
| | | 110109,门头沟区,4,110100 |
| | | 110111,房山区,4,110100 |
| | | 110112,通州区,4,110100 |
| | | 110113,顺义区,4,110100 |
| | | 110114,昌平区,4,110100 |
| | | 110115,大兴区,4,110100 |
| | | 110116,怀柔区,4,110100 |
| | | 110117,平谷区,4,110100 |
| | | 110118,密云区,4,110100 |
| | | 110119,延庆区,4,110100 |
| | | 120101,和平区,4,120100 |
| | | 120102,河东区,4,120100 |
| | | 120103,河西区,4,120100 |
| | | 120104,南开区,4,120100 |
| | | 120105,河北区,4,120100 |
| | | 120106,红桥区,4,120100 |
| | | 120110,东丽区,4,120100 |
| | | 120111,西青区,4,120100 |
| | | 120112,津南区,4,120100 |
| | | 120113,北辰区,4,120100 |
| | | 120114,武清区,4,120100 |
| | | 120115,宝坻区,4,120100 |
| | | 120116,滨海新区,4,120100 |
| | | 120117,宁河区,4,120100 |
| | | 120118,静海区,4,120100 |
| | | 120119,蓟州区,4,120100 |
| | | 130102,长安区,4,130100 |
| | | 130104,桥西区,4,130100 |
| | | 130105,新华区,4,130100 |
| | | 130107,井陉矿区,4,130100 |
| | | 130108,裕华区,4,130100 |
| | | 130109,藁城区,4,130100 |
| | | 130110,鹿泉区,4,130100 |
| | | 130111,栾城区,4,130100 |
| | | 130121,井陉县,4,130100 |
| | | 130123,正定县,4,130100 |
| | | 130125,行唐县,4,130100 |
| | | 130126,灵寿县,4,130100 |
| | | 130127,高邑县,4,130100 |
| | | 130128,深泽县,4,130100 |
| | | 130129,赞皇县,4,130100 |
| | | 130130,无极县,4,130100 |
| | | 130131,平山县,4,130100 |
| | | 130132,元氏县,4,130100 |
| | | 130133,赵县,4,130100 |
| | | 130171,石家庄高新技术产业开发区,4,130100 |
| | | 130172,石家庄循环化工园区,4,130100 |
| | | 130181,辛集市,4,130100 |
| | | 130183,晋州市,4,130100 |
| | | 130184,新乐市,4,130100 |
| | | 130202,路南区,4,130200 |
| | | 130203,路北区,4,130200 |
| | | 130204,古冶区,4,130200 |
| | | 130205,开平区,4,130200 |
| | | 130207,丰南区,4,130200 |
| | | 130208,丰润区,4,130200 |
| | | 130209,曹妃甸区,4,130200 |
| | | 130224,滦南县,4,130200 |
| | | 130225,乐亭县,4,130200 |
| | | 130227,迁西县,4,130200 |
| | | 130229,玉田县,4,130200 |
| | | 130271,河北唐山芦台经济开发区,4,130200 |
| | | 130272,唐山市汉沽管理区,4,130200 |
| | | 130273,唐山高新技术产业开发区,4,130200 |
| | | 130274,河北唐山海港经济开发区,4,130200 |
| | | 130281,遵化市,4,130200 |
| | | 130283,迁安市,4,130200 |
| | | 130284,滦州市,4,130200 |
| | | 130302,海港区,4,130300 |
| | | 130303,山海关区,4,130300 |
| | | 130304,北戴河区,4,130300 |
| | | 130306,抚宁区,4,130300 |
| | | 130321,青龙满族自治县,4,130300 |
| | | 130322,昌黎县,4,130300 |
| | | 130324,卢龙县,4,130300 |
| | | 130371,秦皇岛市经济技术开发区,4,130300 |
| | | 130372,北戴河新区,4,130300 |
| | | 130402,邯山区,4,130400 |
| | | 130403,丛台区,4,130400 |
| | | 130404,复兴区,4,130400 |
| | | 130406,峰峰矿区,4,130400 |
| | | 130407,肥乡区,4,130400 |
| | | 130408,永年区,4,130400 |
| | | 130423,临漳县,4,130400 |
| | | 130424,成安县,4,130400 |
| | | 130425,大名县,4,130400 |
| | | 130426,涉县,4,130400 |
| | | 130427,磁县,4,130400 |
| | | 130430,邱县,4,130400 |
| | | 130431,鸡泽县,4,130400 |
| | | 130432,广平县,4,130400 |
| | | 130433,馆陶县,4,130400 |
| | | 130434,魏县,4,130400 |
| | | 130435,曲周县,4,130400 |
| | | 130471,邯郸经济技术开发区,4,130400 |
| | | 130473,邯郸冀南新区,4,130400 |
| | | 130481,武安市,4,130400 |
| | | 130502,襄都区,4,130500 |
| | | 130503,信都区,4,130500 |
| | | 130505,任泽区,4,130500 |
| | | 130506,南和区,4,130500 |
| | | 130522,临城县,4,130500 |
| | | 130523,内丘县,4,130500 |
| | | 130524,柏乡县,4,130500 |
| | | 130525,隆尧县,4,130500 |
| | | 130528,宁晋县,4,130500 |
| | | 130529,巨鹿县,4,130500 |
| | | 130530,新河县,4,130500 |
| | | 130531,广宗县,4,130500 |
| | | 130532,平乡县,4,130500 |
| | | 130533,威县,4,130500 |
| | | 130534,清河县,4,130500 |
| | | 130535,临西县,4,130500 |
| | | 130571,河北邢台经济开发区,4,130500 |
| | | 130581,南宫市,4,130500 |
| | | 130582,沙河市,4,130500 |
| | | 130602,竞秀区,4,130600 |
| | | 130606,莲池区,4,130600 |
| | | 130607,满城区,4,130600 |
| | | 130608,清苑区,4,130600 |
| | | 130609,徐水区,4,130600 |
| | | 130623,涞水县,4,130600 |
| | | 130624,阜平县,4,130600 |
| | | 130626,定兴县,4,130600 |
| | | 130627,唐县,4,130600 |
| | | 130628,高阳县,4,130600 |
| | | 130629,容城县,4,130600 |
| | | 130630,涞源县,4,130600 |
| | | 130631,望都县,4,130600 |
| | | 130632,安新县,4,130600 |
| | | 130633,易县,4,130600 |
| | | 130634,曲阳县,4,130600 |
| | | 130635,蠡县,4,130600 |
| | | 130636,顺平县,4,130600 |
| | | 130637,博野县,4,130600 |
| | | 130638,雄县,4,130600 |
| | | 130671,保定高新技术产业开发区,4,130600 |
| | | 130672,保定白沟新城,4,130600 |
| | | 130681,涿州市,4,130600 |
| | | 130682,定州市,4,130600 |
| | | 130683,安国市,4,130600 |
| | | 130684,高碑店市,4,130600 |
| | | 130702,桥东区,4,130700 |
| | | 130703,桥西区,4,130700 |
| | | 130705,宣化区,4,130700 |
| | | 130706,下花园区,4,130700 |
| | | 130708,万全区,4,130700 |
| | | 130709,崇礼区,4,130700 |
| | | 130722,张北县,4,130700 |
| | | 130723,康保县,4,130700 |
| | | 130724,沽源县,4,130700 |
| | | 130725,尚义县,4,130700 |
| | | 130726,蔚县,4,130700 |
| | | 130727,阳原县,4,130700 |
| | | 130728,怀安县,4,130700 |
| | | 130730,怀来县,4,130700 |
| | | 130731,涿鹿县,4,130700 |
| | | 130732,赤城县,4,130700 |
| | | 130771,张家口经济开发区,4,130700 |
| | | 130772,张家口市察北管理区,4,130700 |
| | | 130773,张家口市塞北管理区,4,130700 |
| | | 130802,双桥区,4,130800 |
| | | 130803,双滦区,4,130800 |
| | | 130804,鹰手营子矿区,4,130800 |
| | | 130821,承德县,4,130800 |
| | | 130822,兴隆县,4,130800 |
| | | 130824,滦平县,4,130800 |
| | | 130825,隆化县,4,130800 |
| | | 130826,丰宁满族自治县,4,130800 |
| | | 130827,宽城满族自治县,4,130800 |
| | | 130828,围场满族蒙古族自治县,4,130800 |
| | | 130871,承德高新技术产业开发区,4,130800 |
| | | 130881,平泉市,4,130800 |
| | | 130902,新华区,4,130900 |
| | | 130903,运河区,4,130900 |
| | | 130921,沧县,4,130900 |
| | | 130922,青县,4,130900 |
| | | 130923,东光县,4,130900 |
| | | 130924,海兴县,4,130900 |
| | | 130925,盐山县,4,130900 |
| | | 130926,肃宁县,4,130900 |
| | | 130927,南皮县,4,130900 |
| | | 130928,吴桥县,4,130900 |
| | | 130929,献县,4,130900 |
| | | 130930,孟村回族自治县,4,130900 |
| | | 130971,河北沧州经济开发区,4,130900 |
| | | 130972,沧州高新技术产业开发区,4,130900 |
| | | 130973,沧州渤海新区,4,130900 |
| | | 130981,泊头市,4,130900 |
| | | 130982,任丘市,4,130900 |
| | | 130983,黄骅市,4,130900 |
| | | 130984,河间市,4,130900 |
| | | 131002,安次区,4,131000 |
| | | 131003,广阳区,4,131000 |
| | | 131022,固安县,4,131000 |
| | | 131023,永清县,4,131000 |
| | | 131024,香河县,4,131000 |
| | | 131025,大城县,4,131000 |
| | | 131026,文安县,4,131000 |
| | | 131028,大厂回族自治县,4,131000 |
| | | 131071,廊坊经济技术开发区,4,131000 |
| | | 131081,霸州市,4,131000 |
| | | 131082,三河市,4,131000 |
| | | 131102,桃城区,4,131100 |
| | | 131103,冀州区,4,131100 |
| | | 131121,枣强县,4,131100 |
| | | 131122,武邑县,4,131100 |
| | | 131123,武强县,4,131100 |
| | | 131124,饶阳县,4,131100 |
| | | 131125,安平县,4,131100 |
| | | 131126,故城县,4,131100 |
| | | 131127,景县,4,131100 |
| | | 131128,阜城县,4,131100 |
| | | 131171,河北衡水高新技术产业开发区,4,131100 |
| | | 131172,衡水滨湖新区,4,131100 |
| | | 131182,深州市,4,131100 |
| | | 140105,小店区,4,140100 |
| | | 140106,迎泽区,4,140100 |
| | | 140107,杏花岭区,4,140100 |
| | | 140108,尖草坪区,4,140100 |
| | | 140109,万柏林区,4,140100 |
| | | 140110,晋源区,4,140100 |
| | | 140121,清徐县,4,140100 |
| | | 140122,阳曲县,4,140100 |
| | | 140123,娄烦县,4,140100 |
| | | 140171,山西转型综合改革示范区,4,140100 |
| | | 140181,古交市,4,140100 |
| | | 140212,新荣区,4,140200 |
| | | 140213,平城区,4,140200 |
| | | 140214,云冈区,4,140200 |
| | | 140215,云州区,4,140200 |
| | | 140221,阳高县,4,140200 |
| | | 140222,天镇县,4,140200 |
| | | 140223,广灵县,4,140200 |
| | | 140224,灵丘县,4,140200 |
| | | 140225,浑源县,4,140200 |
| | | 140226,左云县,4,140200 |
| | | 140271,山西大同经济开发区,4,140200 |
| | | 140302,城区,4,140300 |
| | | 140303,矿区,4,140300 |
| | | 140311,郊区,4,140300 |
| | | 140321,平定县,4,140300 |
| | | 140322,盂县,4,140300 |
| | | 140403,潞州区,4,140400 |
| | | 140404,上党区,4,140400 |
| | | 140405,屯留区,4,140400 |
| | | 140406,潞城区,4,140400 |
| | | 140423,襄垣县,4,140400 |
| | | 140425,平顺县,4,140400 |
| | | 140426,黎城县,4,140400 |
| | | 140427,壶关县,4,140400 |
| | | 140428,长子县,4,140400 |
| | | 140429,武乡县,4,140400 |
| | | 140430,沁县,4,140400 |
| | | 140431,沁源县,4,140400 |
| | | 140471,山西长治高新技术产业园区,4,140400 |
| | | 140502,城区,4,140500 |
| | | 140521,沁水县,4,140500 |
| | | 140522,阳城县,4,140500 |
| | | 140524,陵川县,4,140500 |
| | | 140525,泽州县,4,140500 |
| | | 140581,高平市,4,140500 |
| | | 140602,朔城区,4,140600 |
| | | 140603,平鲁区,4,140600 |
| | | 140621,山阴县,4,140600 |
| | | 140622,应县,4,140600 |
| | | 140623,右玉县,4,140600 |
| | | 140671,山西朔州经济开发区,4,140600 |
| | | 140681,怀仁市,4,140600 |
| | | 140702,榆次区,4,140700 |
| | | 140703,太谷区,4,140700 |
| | | 140721,榆社县,4,140700 |
| | | 140722,左权县,4,140700 |
| | | 140723,和顺县,4,140700 |
| | | 140724,昔阳县,4,140700 |
| | | 140725,寿阳县,4,140700 |
| | | 140727,祁县,4,140700 |
| | | 140728,平遥县,4,140700 |
| | | 140729,灵石县,4,140700 |
| | | 140781,介休市,4,140700 |
| | | 140802,盐湖区,4,140800 |
| | | 140821,临猗县,4,140800 |
| | | 140822,万荣县,4,140800 |
| | | 140823,闻喜县,4,140800 |
| | | 140824,稷山县,4,140800 |
| | | 140825,新绛县,4,140800 |
| | | 140826,绛县,4,140800 |
| | | 140827,垣曲县,4,140800 |
| | | 140828,夏县,4,140800 |
| | | 140829,平陆县,4,140800 |
| | | 140830,芮城县,4,140800 |
| | | 140881,永济市,4,140800 |
| | | 140882,河津市,4,140800 |
| | | 140902,忻府区,4,140900 |
| | | 140921,定襄县,4,140900 |
| | | 140922,五台县,4,140900 |
| | | 140923,代县,4,140900 |
| | | 140924,繁峙县,4,140900 |
| | | 140925,宁武县,4,140900 |
| | | 140926,静乐县,4,140900 |
| | | 140927,神池县,4,140900 |
| | | 140928,五寨县,4,140900 |
| | | 140929,岢岚县,4,140900 |
| | | 140930,河曲县,4,140900 |
| | | 140931,保德县,4,140900 |
| | | 140932,偏关县,4,140900 |
| | | 140971,五台山风景名胜区,4,140900 |
| | | 140981,原平市,4,140900 |
| | | 141002,尧都区,4,141000 |
| | | 141021,曲沃县,4,141000 |
| | | 141022,翼城县,4,141000 |
| | | 141023,襄汾县,4,141000 |
| | | 141024,洪洞县,4,141000 |
| | | 141025,古县,4,141000 |
| | | 141026,安泽县,4,141000 |
| | | 141027,浮山县,4,141000 |
| | | 141028,吉县,4,141000 |
| | | 141029,乡宁县,4,141000 |
| | | 141030,大宁县,4,141000 |
| | | 141031,隰县,4,141000 |
| | | 141032,永和县,4,141000 |
| | | 141033,蒲县,4,141000 |
| | | 141034,汾西县,4,141000 |
| | | 141081,侯马市,4,141000 |
| | | 141082,霍州市,4,141000 |
| | | 141102,离石区,4,141100 |
| | | 141121,文水县,4,141100 |
| | | 141122,交城县,4,141100 |
| | | 141123,兴县,4,141100 |
| | | 141124,临县,4,141100 |
| | | 141125,柳林县,4,141100 |
| | | 141126,石楼县,4,141100 |
| | | 141127,岚县,4,141100 |
| | | 141128,方山县,4,141100 |
| | | 141129,中阳县,4,141100 |
| | | 141130,交口县,4,141100 |
| | | 141181,孝义市,4,141100 |
| | | 141182,汾阳市,4,141100 |
| | | 150102,新城区,4,150100 |
| | | 150103,回民区,4,150100 |
| | | 150104,玉泉区,4,150100 |
| | | 150105,赛罕区,4,150100 |
| | | 150121,土默特左旗,4,150100 |
| | | 150122,托克托县,4,150100 |
| | | 150123,和林格尔县,4,150100 |
| | | 150124,清水河县,4,150100 |
| | | 150125,武川县,4,150100 |
| | | 150172,呼和浩特经济技术开发区,4,150100 |
| | | 150202,东河区,4,150200 |
| | | 150203,昆都仑区,4,150200 |
| | | 150204,青山区,4,150200 |
| | | 150205,石拐区,4,150200 |
| | | 150206,白云鄂博矿区,4,150200 |
| | | 150207,九原区,4,150200 |
| | | 150221,土默特右旗,4,150200 |
| | | 150222,固阳县,4,150200 |
| | | 150223,达尔罕茂明安联合旗,4,150200 |
| | | 150271,包头稀土高新技术产业开发区,4,150200 |
| | | 150302,海勃湾区,4,150300 |
| | | 150303,海南区,4,150300 |
| | | 150304,乌达区,4,150300 |
| | | 150402,红山区,4,150400 |
| | | 150403,元宝山区,4,150400 |
| | | 150404,松山区,4,150400 |
| | | 150421,阿鲁科尔沁旗,4,150400 |
| | | 150422,巴林左旗,4,150400 |
| | | 150423,巴林右旗,4,150400 |
| | | 150424,林西县,4,150400 |
| | | 150425,克什克腾旗,4,150400 |
| | | 150426,翁牛特旗,4,150400 |
| | | 150428,喀喇沁旗,4,150400 |
| | | 150429,宁城县,4,150400 |
| | | 150430,敖汉旗,4,150400 |
| | | 150502,科尔沁区,4,150500 |
| | | 150521,科尔沁左翼中旗,4,150500 |
| | | 150522,科尔沁左翼后旗,4,150500 |
| | | 150523,开鲁县,4,150500 |
| | | 150524,库伦旗,4,150500 |
| | | 150525,奈曼旗,4,150500 |
| | | 150526,扎鲁特旗,4,150500 |
| | | 150571,通辽经济技术开发区,4,150500 |
| | | 150581,霍林郭勒市,4,150500 |
| | | 150602,东胜区,4,150600 |
| | | 150603,康巴什区,4,150600 |
| | | 150621,达拉特旗,4,150600 |
| | | 150622,准格尔旗,4,150600 |
| | | 150623,鄂托克前旗,4,150600 |
| | | 150624,鄂托克旗,4,150600 |
| | | 150625,杭锦旗,4,150600 |
| | | 150626,乌审旗,4,150600 |
| | | 150627,伊金霍洛旗,4,150600 |
| | | 150702,海拉尔区,4,150700 |
| | | 150703,扎赉诺尔区,4,150700 |
| | | 150721,阿荣旗,4,150700 |
| | | 150722,莫力达瓦达斡尔族自治旗,4,150700 |
| | | 150723,鄂伦春自治旗,4,150700 |
| | | 150724,鄂温克族自治旗,4,150700 |
| | | 150725,陈巴尔虎旗,4,150700 |
| | | 150726,新巴尔虎左旗,4,150700 |
| | | 150727,新巴尔虎右旗,4,150700 |
| | | 150781,满洲里市,4,150700 |
| | | 150782,牙克石市,4,150700 |
| | | 150783,扎兰屯市,4,150700 |
| | | 150784,额尔古纳市,4,150700 |
| | | 150785,根河市,4,150700 |
| | | 150802,临河区,4,150800 |
| | | 150821,五原县,4,150800 |
| | | 150822,磴口县,4,150800 |
| | | 150823,乌拉特前旗,4,150800 |
| | | 150824,乌拉特中旗,4,150800 |
| | | 150825,乌拉特后旗,4,150800 |
| | | 150826,杭锦后旗,4,150800 |
| | | 150902,集宁区,4,150900 |
| | | 150921,卓资县,4,150900 |
| | | 150922,化德县,4,150900 |
| | | 150923,商都县,4,150900 |
| | | 150924,兴和县,4,150900 |
| | | 150925,凉城县,4,150900 |
| | | 150926,察哈尔右翼前旗,4,150900 |
| | | 150927,察哈尔右翼中旗,4,150900 |
| | | 150928,察哈尔右翼后旗,4,150900 |
| | | 150929,四子王旗,4,150900 |
| | | 150981,丰镇市,4,150900 |
| | | 152201,乌兰浩特市,4,152200 |
| | | 152202,阿尔山市,4,152200 |
| | | 152221,科尔沁右翼前旗,4,152200 |
| | | 152222,科尔沁右翼中旗,4,152200 |
| | | 152223,扎赉特旗,4,152200 |
| | | 152224,突泉县,4,152200 |
| | | 152501,二连浩特市,4,152500 |
| | | 152502,锡林浩特市,4,152500 |
| | | 152522,阿巴嘎旗,4,152500 |
| | | 152523,苏尼特左旗,4,152500 |
| | | 152524,苏尼特右旗,4,152500 |
| | | 152525,东乌珠穆沁旗,4,152500 |
| | | 152526,西乌珠穆沁旗,4,152500 |
| | | 152527,太仆寺旗,4,152500 |
| | | 152528,镶黄旗,4,152500 |
| | | 152529,正镶白旗,4,152500 |
| | | 152530,正蓝旗,4,152500 |
| | | 152531,多伦县,4,152500 |
| | | 152571,乌拉盖管委会,4,152500 |
| | | 152921,阿拉善左旗,4,152900 |
| | | 152922,阿拉善右旗,4,152900 |
| | | 152923,额济纳旗,4,152900 |
| | | 152971,内蒙古阿拉善高新技术产业开发区,4,152900 |
| | | 210102,和平区,4,210100 |
| | | 210103,沈河区,4,210100 |
| | | 210104,大东区,4,210100 |
| | | 210105,皇姑区,4,210100 |
| | | 210106,铁西区,4,210100 |
| | | 210111,苏家屯区,4,210100 |
| | | 210112,浑南区,4,210100 |
| | | 210113,沈北新区,4,210100 |
| | | 210114,于洪区,4,210100 |
| | | 210115,辽中区,4,210100 |
| | | 210123,康平县,4,210100 |
| | | 210124,法库县,4,210100 |
| | | 210181,新民市,4,210100 |
| | | 210202,中山区,4,210200 |
| | | 210203,西岗区,4,210200 |
| | | 210204,沙河口区,4,210200 |
| | | 210211,甘井子区,4,210200 |
| | | 210212,旅顺口区,4,210200 |
| | | 210213,金州区,4,210200 |
| | | 210214,普兰店区,4,210200 |
| | | 210224,长海县,4,210200 |
| | | 210281,瓦房店市,4,210200 |
| | | 210283,庄河市,4,210200 |
| | | 210302,铁东区,4,210300 |
| | | 210303,铁西区,4,210300 |
| | | 210304,立山区,4,210300 |
| | | 210311,千山区,4,210300 |
| | | 210321,台安县,4,210300 |
| | | 210323,岫岩满族自治县,4,210300 |
| | | 210381,海城市,4,210300 |
| | | 210402,新抚区,4,210400 |
| | | 210403,东洲区,4,210400 |
| | | 210404,望花区,4,210400 |
| | | 210411,顺城区,4,210400 |
| | | 210421,抚顺县,4,210400 |
| | | 210422,新宾满族自治县,4,210400 |
| | | 210423,清原满族自治县,4,210400 |
| | | 210502,平山区,4,210500 |
| | | 210503,溪湖区,4,210500 |
| | | 210504,明山区,4,210500 |
| | | 210505,南芬区,4,210500 |
| | | 210521,本溪满族自治县,4,210500 |
| | | 210522,桓仁满族自治县,4,210500 |
| | | 210602,元宝区,4,210600 |
| | | 210603,振兴区,4,210600 |
| | | 210604,振安区,4,210600 |
| | | 210624,宽甸满族自治县,4,210600 |
| | | 210681,东港市,4,210600 |
| | | 210682,凤城市,4,210600 |
| | | 210702,古塔区,4,210700 |
| | | 210703,凌河区,4,210700 |
| | | 210711,太和区,4,210700 |
| | | 210726,黑山县,4,210700 |
| | | 210727,义县,4,210700 |
| | | 210781,凌海市,4,210700 |
| | | 210782,北镇市,4,210700 |
| | | 210802,站前区,4,210800 |
| | | 210803,西市区,4,210800 |
| | | 210804,鲅鱼圈区,4,210800 |
| | | 210811,老边区,4,210800 |
| | | 210881,盖州市,4,210800 |
| | | 210882,大石桥市,4,210800 |
| | | 210902,海州区,4,210900 |
| | | 210903,新邱区,4,210900 |
| | | 210904,太平区,4,210900 |
| | | 210905,清河门区,4,210900 |
| | | 210911,细河区,4,210900 |
| | | 210921,阜新蒙古族自治县,4,210900 |
| | | 210922,彰武县,4,210900 |
| | | 211002,白塔区,4,211000 |
| | | 211003,文圣区,4,211000 |
| | | 211004,宏伟区,4,211000 |
| | | 211005,弓长岭区,4,211000 |
| | | 211011,太子河区,4,211000 |
| | | 211021,辽阳县,4,211000 |
| | | 211081,灯塔市,4,211000 |
| | | 211102,双台子区,4,211100 |
| | | 211103,兴隆台区,4,211100 |
| | | 211104,大洼区,4,211100 |
| | | 211122,盘山县,4,211100 |
| | | 211202,银州区,4,211200 |
| | | 211204,清河区,4,211200 |
| | | 211221,铁岭县,4,211200 |
| | | 211223,西丰县,4,211200 |
| | | 211224,昌图县,4,211200 |
| | | 211281,调兵山市,4,211200 |
| | | 211282,开原市,4,211200 |
| | | 211302,双塔区,4,211300 |
| | | 211303,龙城区,4,211300 |
| | | 211321,朝阳县,4,211300 |
| | | 211322,建平县,4,211300 |
| | | 211324,喀喇沁左翼蒙古族自治县,4,211300 |
| | | 211381,北票市,4,211300 |
| | | 211382,凌源市,4,211300 |
| | | 211402,连山区,4,211400 |
| | | 211403,龙港区,4,211400 |
| | | 211404,南票区,4,211400 |
| | | 211421,绥中县,4,211400 |
| | | 211422,建昌县,4,211400 |
| | | 211481,兴城市,4,211400 |
| | | 220102,南关区,4,220100 |
| | | 220103,宽城区,4,220100 |
| | | 220104,朝阳区,4,220100 |
| | | 220105,二道区,4,220100 |
| | | 220106,绿园区,4,220100 |
| | | 220112,双阳区,4,220100 |
| | | 220113,九台区,4,220100 |
| | | 220122,农安县,4,220100 |
| | | 220171,长春经济技术开发区,4,220100 |
| | | 220172,长春净月高新技术产业开发区,4,220100 |
| | | 220173,长春高新技术产业开发区,4,220100 |
| | | 220174,长春汽车经济技术开发区,4,220100 |
| | | 220182,榆树市,4,220100 |
| | | 220183,德惠市,4,220100 |
| | | 220184,公主岭市,4,220100 |
| | | 220202,昌邑区,4,220200 |
| | | 220203,龙潭区,4,220200 |
| | | 220204,船营区,4,220200 |
| | | 220211,丰满区,4,220200 |
| | | 220221,永吉县,4,220200 |
| | | 220271,吉林经济开发区,4,220200 |
| | | 220272,吉林高新技术产业开发区,4,220200 |
| | | 220273,吉林中国新加坡食品区,4,220200 |
| | | 220281,蛟河市,4,220200 |
| | | 220282,桦甸市,4,220200 |
| | | 220283,舒兰市,4,220200 |
| | | 220284,磐石市,4,220200 |
| | | 220302,铁西区,4,220300 |
| | | 220303,铁东区,4,220300 |
| | | 220322,梨树县,4,220300 |
| | | 220323,伊通满族自治县,4,220300 |
| | | 220382,双辽市,4,220300 |
| | | 220402,龙山区,4,220400 |
| | | 220403,西安区,4,220400 |
| | | 220421,东丰县,4,220400 |
| | | 220422,东辽县,4,220400 |
| | | 220502,东昌区,4,220500 |
| | | 220503,二道江区,4,220500 |
| | | 220521,通化县,4,220500 |
| | | 220523,辉南县,4,220500 |
| | | 220524,柳河县,4,220500 |
| | | 220581,梅河口市,4,220500 |
| | | 220582,集安市,4,220500 |
| | | 220602,浑江区,4,220600 |
| | | 220605,江源区,4,220600 |
| | | 220621,抚松县,4,220600 |
| | | 220622,靖宇县,4,220600 |
| | | 220623,长白朝鲜族自治县,4,220600 |
| | | 220681,临江市,4,220600 |
| | | 220702,宁江区,4,220700 |
| | | 220721,前郭尔罗斯蒙古族自治县,4,220700 |
| | | 220722,长岭县,4,220700 |
| | | 220723,乾安县,4,220700 |
| | | 220771,吉林松原经济开发区,4,220700 |
| | | 220781,扶余市,4,220700 |
| | | 220802,洮北区,4,220800 |
| | | 220821,镇赉县,4,220800 |
| | | 220822,通榆县,4,220800 |
| | | 220871,吉林白城经济开发区,4,220800 |
| | | 220881,洮南市,4,220800 |
| | | 220882,大安市,4,220800 |
| | | 222401,延吉市,4,222400 |
| | | 222402,图们市,4,222400 |
| | | 222403,敦化市,4,222400 |
| | | 222404,珲春市,4,222400 |
| | | 222405,龙井市,4,222400 |
| | | 222406,和龙市,4,222400 |
| | | 222424,汪清县,4,222400 |
| | | 222426,安图县,4,222400 |
| | | 230102,道里区,4,230100 |
| | | 230103,南岗区,4,230100 |
| | | 230104,道外区,4,230100 |
| | | 230108,平房区,4,230100 |
| | | 230109,松北区,4,230100 |
| | | 230110,香坊区,4,230100 |
| | | 230111,呼兰区,4,230100 |
| | | 230112,阿城区,4,230100 |
| | | 230113,双城区,4,230100 |
| | | 230123,依兰县,4,230100 |
| | | 230124,方正县,4,230100 |
| | | 230125,宾县,4,230100 |
| | | 230126,巴彦县,4,230100 |
| | | 230127,木兰县,4,230100 |
| | | 230128,通河县,4,230100 |
| | | 230129,延寿县,4,230100 |
| | | 230183,尚志市,4,230100 |
| | | 230184,五常市,4,230100 |
| | | 230202,龙沙区,4,230200 |
| | | 230203,建华区,4,230200 |
| | | 230204,铁锋区,4,230200 |
| | | 230205,昂昂溪区,4,230200 |
| | | 230206,富拉尔基区,4,230200 |
| | | 230207,碾子山区,4,230200 |
| | | 230208,梅里斯达斡尔族区,4,230200 |
| | | 230221,龙江县,4,230200 |
| | | 230223,依安县,4,230200 |
| | | 230224,泰来县,4,230200 |
| | | 230225,甘南县,4,230200 |
| | | 230227,富裕县,4,230200 |
| | | 230229,克山县,4,230200 |
| | | 230230,克东县,4,230200 |
| | | 230231,拜泉县,4,230200 |
| | | 230281,讷河市,4,230200 |
| | | 230302,鸡冠区,4,230300 |
| | | 230303,恒山区,4,230300 |
| | | 230304,滴道区,4,230300 |
| | | 230305,梨树区,4,230300 |
| | | 230306,城子河区,4,230300 |
| | | 230307,麻山区,4,230300 |
| | | 230321,鸡东县,4,230300 |
| | | 230381,虎林市,4,230300 |
| | | 230382,密山市,4,230300 |
| | | 230402,向阳区,4,230400 |
| | | 230403,工农区,4,230400 |
| | | 230404,南山区,4,230400 |
| | | 230405,兴安区,4,230400 |
| | | 230406,东山区,4,230400 |
| | | 230407,兴山区,4,230400 |
| | | 230421,萝北县,4,230400 |
| | | 230422,绥滨县,4,230400 |
| | | 230502,尖山区,4,230500 |
| | | 230503,岭东区,4,230500 |
| | | 230505,四方台区,4,230500 |
| | | 230506,宝山区,4,230500 |
| | | 230521,集贤县,4,230500 |
| | | 230522,友谊县,4,230500 |
| | | 230523,宝清县,4,230500 |
| | | 230524,饶河县,4,230500 |
| | | 230602,萨尔图区,4,230600 |
| | | 230603,龙凤区,4,230600 |
| | | 230604,让胡路区,4,230600 |
| | | 230605,红岗区,4,230600 |
| | | 230606,大同区,4,230600 |
| | | 230621,肇州县,4,230600 |
| | | 230622,肇源县,4,230600 |
| | | 230623,林甸县,4,230600 |
| | | 230624,杜尔伯特蒙古族自治县,4,230600 |
| | | 230671,大庆高新技术产业开发区,4,230600 |
| | | 230717,伊美区,4,230700 |
| | | 230718,乌翠区,4,230700 |
| | | 230719,友好区,4,230700 |
| | | 230722,嘉荫县,4,230700 |
| | | 230723,汤旺县,4,230700 |
| | | 230724,丰林县,4,230700 |
| | | 230725,大箐山县,4,230700 |
| | | 230726,南岔县,4,230700 |
| | | 230751,金林区,4,230700 |
| | | 230781,铁力市,4,230700 |
| | | 230803,向阳区,4,230800 |
| | | 230804,前进区,4,230800 |
| | | 230805,东风区,4,230800 |
| | | 230811,郊区,4,230800 |
| | | 230822,桦南县,4,230800 |
| | | 230826,桦川县,4,230800 |
| | | 230828,汤原县,4,230800 |
| | | 230881,同江市,4,230800 |
| | | 230882,富锦市,4,230800 |
| | | 230883,抚远市,4,230800 |
| | | 230902,新兴区,4,230900 |
| | | 230903,桃山区,4,230900 |
| | | 230904,茄子河区,4,230900 |
| | | 230921,勃利县,4,230900 |
| | | 231002,东安区,4,231000 |
| | | 231003,阳明区,4,231000 |
| | | 231004,爱民区,4,231000 |
| | | 231005,西安区,4,231000 |
| | | 231025,林口县,4,231000 |
| | | 231071,牡丹江经济技术开发区,4,231000 |
| | | 231081,绥芬河市,4,231000 |
| | | 231083,海林市,4,231000 |
| | | 231084,宁安市,4,231000 |
| | | 231085,穆棱市,4,231000 |
| | | 231086,东宁市,4,231000 |
| | | 231102,爱辉区,4,231100 |
| | | 231123,逊克县,4,231100 |
| | | 231124,孙吴县,4,231100 |
| | | 231181,北安市,4,231100 |
| | | 231182,五大连池市,4,231100 |
| | | 231183,嫩江市,4,231100 |
| | | 231202,北林区,4,231200 |
| | | 231221,望奎县,4,231200 |
| | | 231222,兰西县,4,231200 |
| | | 231223,青冈县,4,231200 |
| | | 231224,庆安县,4,231200 |
| | | 231225,明水县,4,231200 |
| | | 231226,绥棱县,4,231200 |
| | | 231281,安达市,4,231200 |
| | | 231282,肇东市,4,231200 |
| | | 231283,海伦市,4,231200 |
| | | 232701,漠河市,4,232700 |
| | | 232721,呼玛县,4,232700 |
| | | 232722,塔河县,4,232700 |
| | | 232761,加格达奇区,4,232700 |
| | | 232762,松岭区,4,232700 |
| | | 232763,新林区,4,232700 |
| | | 232764,呼中区,4,232700 |
| | | 310101,黄浦区,4,310100 |
| | | 310104,徐汇区,4,310100 |
| | | 310105,长宁区,4,310100 |
| | | 310106,静安区,4,310100 |
| | | 310107,普陀区,4,310100 |
| | | 310109,虹口区,4,310100 |
| | | 310110,杨浦区,4,310100 |
| | | 310112,闵行区,4,310100 |
| | | 310113,宝山区,4,310100 |
| | | 310114,嘉定区,4,310100 |
| | | 310115,浦东新区,4,310100 |
| | | 310116,金山区,4,310100 |
| | | 310117,松江区,4,310100 |
| | | 310118,青浦区,4,310100 |
| | | 310120,奉贤区,4,310100 |
| | | 310151,崇明区,4,310100 |
| | | 320102,玄武区,4,320100 |
| | | 320104,秦淮区,4,320100 |
| | | 320105,建邺区,4,320100 |
| | | 320106,鼓楼区,4,320100 |
| | | 320111,浦口区,4,320100 |
| | | 320113,栖霞区,4,320100 |
| | | 320114,雨花台区,4,320100 |
| | | 320115,江宁区,4,320100 |
| | | 320116,六合区,4,320100 |
| | | 320117,溧水区,4,320100 |
| | | 320118,高淳区,4,320100 |
| | | 320205,锡山区,4,320200 |
| | | 320206,惠山区,4,320200 |
| | | 320211,滨湖区,4,320200 |
| | | 320213,梁溪区,4,320200 |
| | | 320214,新吴区,4,320200 |
| | | 320281,江阴市,4,320200 |
| | | 320282,宜兴市,4,320200 |
| | | 320302,鼓楼区,4,320300 |
| | | 320303,云龙区,4,320300 |
| | | 320305,贾汪区,4,320300 |
| | | 320311,泉山区,4,320300 |
| | | 320312,铜山区,4,320300 |
| | | 320321,丰县,4,320300 |
| | | 320322,沛县,4,320300 |
| | | 320324,睢宁县,4,320300 |
| | | 320371,徐州经济技术开发区,4,320300 |
| | | 320381,新沂市,4,320300 |
| | | 320382,邳州市,4,320300 |
| | | 320402,天宁区,4,320400 |
| | | 320404,钟楼区,4,320400 |
| | | 320411,新北区,4,320400 |
| | | 320412,武进区,4,320400 |
| | | 320413,金坛区,4,320400 |
| | | 320481,溧阳市,4,320400 |
| | | 320505,虎丘区,4,320500 |
| | | 320506,吴中区,4,320500 |
| | | 320507,相城区,4,320500 |
| | | 320508,姑苏区,4,320500 |
| | | 320509,吴江区,4,320500 |
| | | 320571,苏州工业园区,4,320500 |
| | | 320581,常熟市,4,320500 |
| | | 320582,张家港市,4,320500 |
| | | 320583,昆山市,4,320500 |
| | | 320585,太仓市,4,320500 |
| | | 320612,通州区,4,320600 |
| | | 320613,崇川区,4,320600 |
| | | 320614,海门区,4,320600 |
| | | 320623,如东县,4,320600 |
| | | 320671,南通经济技术开发区,4,320600 |
| | | 320681,启东市,4,320600 |
| | | 320682,如皋市,4,320600 |
| | | 320685,海安市,4,320600 |
| | | 320703,连云区,4,320700 |
| | | 320706,海州区,4,320700 |
| | | 320707,赣榆区,4,320700 |
| | | 320722,东海县,4,320700 |
| | | 320723,灌云县,4,320700 |
| | | 320724,灌南县,4,320700 |
| | | 320771,连云港经济技术开发区,4,320700 |
| | | 320772,连云港高新技术产业开发区,4,320700 |
| | | 320803,淮安区,4,320800 |
| | | 320804,淮阴区,4,320800 |
| | | 320812,清江浦区,4,320800 |
| | | 320813,洪泽区,4,320800 |
| | | 320826,涟水县,4,320800 |
| | | 320830,盱眙县,4,320800 |
| | | 320831,金湖县,4,320800 |
| | | 320871,淮安经济技术开发区,4,320800 |
| | | 320902,亭湖区,4,320900 |
| | | 320903,盐都区,4,320900 |
| | | 320904,大丰区,4,320900 |
| | | 320921,响水县,4,320900 |
| | | 320922,滨海县,4,320900 |
| | | 320923,阜宁县,4,320900 |
| | | 320924,射阳县,4,320900 |
| | | 320925,建湖县,4,320900 |
| | | 320971,盐城经济技术开发区,4,320900 |
| | | 320981,东台市,4,320900 |
| | | 321002,广陵区,4,321000 |
| | | 321003,邗江区,4,321000 |
| | | 321012,江都区,4,321000 |
| | | 321023,宝应县,4,321000 |
| | | 321071,扬州经济技术开发区,4,321000 |
| | | 321081,仪征市,4,321000 |
| | | 321084,高邮市,4,321000 |
| | | 321102,京口区,4,321100 |
| | | 321111,润州区,4,321100 |
| | | 321112,丹徒区,4,321100 |
| | | 321171,镇江新区,4,321100 |
| | | 321181,丹阳市,4,321100 |
| | | 321182,扬中市,4,321100 |
| | | 321183,句容市,4,321100 |
| | | 321202,海陵区,4,321200 |
| | | 321203,高港区,4,321200 |
| | | 321204,姜堰区,4,321200 |
| | | 321271,泰州医药高新技术产业开发区,4,321200 |
| | | 321281,兴化市,4,321200 |
| | | 321282,靖江市,4,321200 |
| | | 321283,泰兴市,4,321200 |
| | | 321302,宿城区,4,321300 |
| | | 321311,宿豫区,4,321300 |
| | | 321322,沭阳县,4,321300 |
| | | 321323,泗阳县,4,321300 |
| | | 321324,泗洪县,4,321300 |
| | | 321371,宿迁经济技术开发区,4,321300 |
| | | 330102,上城区,4,330100 |
| | | 330105,拱墅区,4,330100 |
| | | 330106,西湖区,4,330100 |
| | | 330108,滨江区,4,330100 |
| | | 330109,萧山区,4,330100 |
| | | 330110,余杭区,4,330100 |
| | | 330111,富阳区,4,330100 |
| | | 330112,临安区,4,330100 |
| | | 330113,临平区,4,330100 |
| | | 330114,钱塘区,4,330100 |
| | | 330122,桐庐县,4,330100 |
| | | 330127,淳安县,4,330100 |
| | | 330182,建德市,4,330100 |
| | | 330203,海曙区,4,330200 |
| | | 330205,江北区,4,330200 |
| | | 330206,北仑区,4,330200 |
| | | 330211,镇海区,4,330200 |
| | | 330212,鄞州区,4,330200 |
| | | 330213,奉化区,4,330200 |
| | | 330225,象山县,4,330200 |
| | | 330226,宁海县,4,330200 |
| | | 330281,余姚市,4,330200 |
| | | 330282,慈溪市,4,330200 |
| | | 330302,鹿城区,4,330300 |
| | | 330303,龙湾区,4,330300 |
| | | 330304,瓯海区,4,330300 |
| | | 330305,洞头区,4,330300 |
| | | 330324,永嘉县,4,330300 |
| | | 330326,平阳县,4,330300 |
| | | 330327,苍南县,4,330300 |
| | | 330328,文成县,4,330300 |
| | | 330329,泰顺县,4,330300 |
| | | 330371,温州经济技术开发区,4,330300 |
| | | 330381,瑞安市,4,330300 |
| | | 330382,乐清市,4,330300 |
| | | 330383,龙港市,4,330300 |
| | | 330402,南湖区,4,330400 |
| | | 330411,秀洲区,4,330400 |
| | | 330421,嘉善县,4,330400 |
| | | 330424,海盐县,4,330400 |
| | | 330481,海宁市,4,330400 |
| | | 330482,平湖市,4,330400 |
| | | 330483,桐乡市,4,330400 |
| | | 330502,吴兴区,4,330500 |
| | | 330503,南浔区,4,330500 |
| | | 330521,德清县,4,330500 |
| | | 330522,长兴县,4,330500 |
| | | 330523,安吉县,4,330500 |
| | | 330602,越城区,4,330600 |
| | | 330603,柯桥区,4,330600 |
| | | 330604,上虞区,4,330600 |
| | | 330624,新昌县,4,330600 |
| | | 330681,诸暨市,4,330600 |
| | | 330683,嵊州市,4,330600 |
| | | 330702,婺城区,4,330700 |
| | | 330703,金东区,4,330700 |
| | | 330723,武义县,4,330700 |
| | | 330726,浦江县,4,330700 |
| | | 330727,磐安县,4,330700 |
| | | 330781,兰溪市,4,330700 |
| | | 330782,义乌市,4,330700 |
| | | 330783,东阳市,4,330700 |
| | | 330784,永康市,4,330700 |
| | | 330802,柯城区,4,330800 |
| | | 330803,衢江区,4,330800 |
| | | 330822,常山县,4,330800 |
| | | 330824,开化县,4,330800 |
| | | 330825,龙游县,4,330800 |
| | | 330881,江山市,4,330800 |
| | | 330902,定海区,4,330900 |
| | | 330903,普陀区,4,330900 |
| | | 330921,岱山县,4,330900 |
| | | 330922,嵊泗县,4,330900 |
| | | 331002,椒江区,4,331000 |
| | | 331003,黄岩区,4,331000 |
| | | 331004,路桥区,4,331000 |
| | | 331022,三门县,4,331000 |
| | | 331023,天台县,4,331000 |
| | | 331024,仙居县,4,331000 |
| | | 331081,温岭市,4,331000 |
| | | 331082,临海市,4,331000 |
| | | 331083,玉环市,4,331000 |
| | | 331102,莲都区,4,331100 |
| | | 331121,青田县,4,331100 |
| | | 331122,缙云县,4,331100 |
| | | 331123,遂昌县,4,331100 |
| | | 331124,松阳县,4,331100 |
| | | 331125,云和县,4,331100 |
| | | 331126,庆元县,4,331100 |
| | | 331127,景宁畲族自治县,4,331100 |
| | | 331181,龙泉市,4,331100 |
| | | 340102,瑶海区,4,340100 |
| | | 340103,庐阳区,4,340100 |
| | | 340104,蜀山区,4,340100 |
| | | 340111,包河区,4,340100 |
| | | 340121,长丰县,4,340100 |
| | | 340122,肥东县,4,340100 |
| | | 340123,肥西县,4,340100 |
| | | 340124,庐江县,4,340100 |
| | | 340171,合肥高新技术产业开发区,4,340100 |
| | | 340172,合肥经济技术开发区,4,340100 |
| | | 340173,合肥新站高新技术产业开发区,4,340100 |
| | | 340181,巢湖市,4,340100 |
| | | 340202,镜湖区,4,340200 |
| | | 340207,鸠江区,4,340200 |
| | | 340209,弋江区,4,340200 |
| | | 340210,湾沚区,4,340200 |
| | | 340212,繁昌区,4,340200 |
| | | 340223,南陵县,4,340200 |
| | | 340271,芜湖经济技术开发区,4,340200 |
| | | 340272,安徽芜湖三山经济开发区,4,340200 |
| | | 340281,无为市,4,340200 |
| | | 340302,龙子湖区,4,340300 |
| | | 340303,蚌山区,4,340300 |
| | | 340304,禹会区,4,340300 |
| | | 340311,淮上区,4,340300 |
| | | 340321,怀远县,4,340300 |
| | | 340322,五河县,4,340300 |
| | | 340323,固镇县,4,340300 |
| | | 340371,蚌埠市高新技术开发区,4,340300 |
| | | 340372,蚌埠市经济开发区,4,340300 |
| | | 340402,大通区,4,340400 |
| | | 340403,田家庵区,4,340400 |
| | | 340404,谢家集区,4,340400 |
| | | 340405,八公山区,4,340400 |
| | | 340406,潘集区,4,340400 |
| | | 340421,凤台县,4,340400 |
| | | 340422,寿县,4,340400 |
| | | 340503,花山区,4,340500 |
| | | 340504,雨山区,4,340500 |
| | | 340506,博望区,4,340500 |
| | | 340521,当涂县,4,340500 |
| | | 340522,含山县,4,340500 |
| | | 340523,和县,4,340500 |
| | | 340602,杜集区,4,340600 |
| | | 340603,相山区,4,340600 |
| | | 340604,烈山区,4,340600 |
| | | 340621,濉溪县,4,340600 |
| | | 340705,铜官区,4,340700 |
| | | 340706,义安区,4,340700 |
| | | 340711,郊区,4,340700 |
| | | 340722,枞阳县,4,340700 |
| | | 340802,迎江区,4,340800 |
| | | 340803,大观区,4,340800 |
| | | 340811,宜秀区,4,340800 |
| | | 340822,怀宁县,4,340800 |
| | | 340825,太湖县,4,340800 |
| | | 340826,宿松县,4,340800 |
| | | 340827,望江县,4,340800 |
| | | 340828,岳西县,4,340800 |
| | | 340871,安徽安庆经济开发区,4,340800 |
| | | 340881,桐城市,4,340800 |
| | | 340882,潜山市,4,340800 |
| | | 341002,屯溪区,4,341000 |
| | | 341003,黄山区,4,341000 |
| | | 341004,徽州区,4,341000 |
| | | 341021,歙县,4,341000 |
| | | 341022,休宁县,4,341000 |
| | | 341023,黟县,4,341000 |
| | | 341024,祁门县,4,341000 |
| | | 341102,琅琊区,4,341100 |
| | | 341103,南谯区,4,341100 |
| | | 341122,来安县,4,341100 |
| | | 341124,全椒县,4,341100 |
| | | 341125,定远县,4,341100 |
| | | 341126,凤阳县,4,341100 |
| | | 341171,中新苏滁高新技术产业开发区,4,341100 |
| | | 341172,滁州经济技术开发区,4,341100 |
| | | 341181,天长市,4,341100 |
| | | 341182,明光市,4,341100 |
| | | 341202,颍州区,4,341200 |
| | | 341203,颍东区,4,341200 |
| | | 341204,颍泉区,4,341200 |
| | | 341221,临泉县,4,341200 |
| | | 341222,太和县,4,341200 |
| | | 341225,阜南县,4,341200 |
| | | 341226,颍上县,4,341200 |
| | | 341271,阜阳合肥现代产业园区,4,341200 |
| | | 341272,阜阳经济技术开发区,4,341200 |
| | | 341282,界首市,4,341200 |
| | | 341302,埇桥区,4,341300 |
| | | 341321,砀山县,4,341300 |
| | | 341322,萧县,4,341300 |
| | | 341323,灵璧县,4,341300 |
| | | 341324,泗县,4,341300 |
| | | 341371,宿州马鞍山现代产业园区,4,341300 |
| | | 341372,宿州经济技术开发区,4,341300 |
| | | 341502,金安区,4,341500 |
| | | 341503,裕安区,4,341500 |
| | | 341504,叶集区,4,341500 |
| | | 341522,霍邱县,4,341500 |
| | | 341523,舒城县,4,341500 |
| | | 341524,金寨县,4,341500 |
| | | 341525,霍山县,4,341500 |
| | | 341602,谯城区,4,341600 |
| | | 341621,涡阳县,4,341600 |
| | | 341622,蒙城县,4,341600 |
| | | 341623,利辛县,4,341600 |
| | | 341702,贵池区,4,341700 |
| | | 341721,东至县,4,341700 |
| | | 341722,石台县,4,341700 |
| | | 341723,青阳县,4,341700 |
| | | 341802,宣州区,4,341800 |
| | | 341821,郎溪县,4,341800 |
| | | 341823,泾县,4,341800 |
| | | 341824,绩溪县,4,341800 |
| | | 341825,旌德县,4,341800 |
| | | 341871,宣城市经济开发区,4,341800 |
| | | 341881,宁国市,4,341800 |
| | | 341882,广德市,4,341800 |
| | | 350102,鼓楼区,4,350100 |
| | | 350103,台江区,4,350100 |
| | | 350104,仓山区,4,350100 |
| | | 350105,马尾区,4,350100 |
| | | 350111,晋安区,4,350100 |
| | | 350112,长乐区,4,350100 |
| | | 350121,闽侯县,4,350100 |
| | | 350122,连江县,4,350100 |
| | | 350123,罗源县,4,350100 |
| | | 350124,闽清县,4,350100 |
| | | 350125,永泰县,4,350100 |
| | | 350128,平潭县,4,350100 |
| | | 350181,福清市,4,350100 |
| | | 350203,思明区,4,350200 |
| | | 350205,海沧区,4,350200 |
| | | 350206,湖里区,4,350200 |
| | | 350211,集美区,4,350200 |
| | | 350212,同安区,4,350200 |
| | | 350213,翔安区,4,350200 |
| | | 350302,城厢区,4,350300 |
| | | 350303,涵江区,4,350300 |
| | | 350304,荔城区,4,350300 |
| | | 350305,秀屿区,4,350300 |
| | | 350322,仙游县,4,350300 |
| | | 350404,三元区,4,350400 |
| | | 350405,沙县区,4,350400 |
| | | 350421,明溪县,4,350400 |
| | | 350423,清流县,4,350400 |
| | | 350424,宁化县,4,350400 |
| | | 350425,大田县,4,350400 |
| | | 350426,尤溪县,4,350400 |
| | | 350428,将乐县,4,350400 |
| | | 350429,泰宁县,4,350400 |
| | | 350430,建宁县,4,350400 |
| | | 350481,永安市,4,350400 |
| | | 350502,鲤城区,4,350500 |
| | | 350503,丰泽区,4,350500 |
| | | 350504,洛江区,4,350500 |
| | | 350505,泉港区,4,350500 |
| | | 350521,惠安县,4,350500 |
| | | 350524,安溪县,4,350500 |
| | | 350525,永春县,4,350500 |
| | | 350526,德化县,4,350500 |
| | | 350527,金门县,4,350500 |
| | | 350581,石狮市,4,350500 |
| | | 350582,晋江市,4,350500 |
| | | 350583,南安市,4,350500 |
| | | 350602,芗城区,4,350600 |
| | | 350603,龙文区,4,350600 |
| | | 350604,龙海区,4,350600 |
| | | 350605,长泰区,4,350600 |
| | | 350622,云霄县,4,350600 |
| | | 350623,漳浦县,4,350600 |
| | | 350624,诏安县,4,350600 |
| | | 350626,东山县,4,350600 |
| | | 350627,南靖县,4,350600 |
| | | 350628,平和县,4,350600 |
| | | 350629,华安县,4,350600 |
| | | 350702,延平区,4,350700 |
| | | 350703,建阳区,4,350700 |
| | | 350721,顺昌县,4,350700 |
| | | 350722,浦城县,4,350700 |
| | | 350723,光泽县,4,350700 |
| | | 350724,松溪县,4,350700 |
| | | 350725,政和县,4,350700 |
| | | 350781,邵武市,4,350700 |
| | | 350782,武夷山市,4,350700 |
| | | 350783,建瓯市,4,350700 |
| | | 350802,新罗区,4,350800 |
| | | 350803,永定区,4,350800 |
| | | 350821,长汀县,4,350800 |
| | | 350823,上杭县,4,350800 |
| | | 350824,武平县,4,350800 |
| | | 350825,连城县,4,350800 |
| | | 350881,漳平市,4,350800 |
| | | 350902,蕉城区,4,350900 |
| | | 350921,霞浦县,4,350900 |
| | | 350922,古田县,4,350900 |
| | | 350923,屏南县,4,350900 |
| | | 350924,寿宁县,4,350900 |
| | | 350925,周宁县,4,350900 |
| | | 350926,柘荣县,4,350900 |
| | | 350981,福安市,4,350900 |
| | | 350982,福鼎市,4,350900 |
| | | 360102,东湖区,4,360100 |
| | | 360103,西湖区,4,360100 |
| | | 360104,青云谱区,4,360100 |
| | | 360111,青山湖区,4,360100 |
| | | 360112,新建区,4,360100 |
| | | 360113,红谷滩区,4,360100 |
| | | 360121,南昌县,4,360100 |
| | | 360123,安义县,4,360100 |
| | | 360124,进贤县,4,360100 |
| | | 360202,昌江区,4,360200 |
| | | 360203,珠山区,4,360200 |
| | | 360222,浮梁县,4,360200 |
| | | 360281,乐平市,4,360200 |
| | | 360302,安源区,4,360300 |
| | | 360313,湘东区,4,360300 |
| | | 360321,莲花县,4,360300 |
| | | 360322,上栗县,4,360300 |
| | | 360323,芦溪县,4,360300 |
| | | 360402,濂溪区,4,360400 |
| | | 360403,浔阳区,4,360400 |
| | | 360404,柴桑区,4,360400 |
| | | 360423,武宁县,4,360400 |
| | | 360424,修水县,4,360400 |
| | | 360425,永修县,4,360400 |
| | | 360426,德安县,4,360400 |
| | | 360428,都昌县,4,360400 |
| | | 360429,湖口县,4,360400 |
| | | 360430,彭泽县,4,360400 |
| | | 360481,瑞昌市,4,360400 |
| | | 360482,共青城市,4,360400 |
| | | 360483,庐山市,4,360400 |
| | | 360502,渝水区,4,360500 |
| | | 360521,分宜县,4,360500 |
| | | 360602,月湖区,4,360600 |
| | | 360603,余江区,4,360600 |
| | | 360681,贵溪市,4,360600 |
| | | 360702,章贡区,4,360700 |
| | | 360703,南康区,4,360700 |
| | | 360704,赣县区,4,360700 |
| | | 360722,信丰县,4,360700 |
| | | 360723,大余县,4,360700 |
| | | 360724,上犹县,4,360700 |
| | | 360725,崇义县,4,360700 |
| | | 360726,安远县,4,360700 |
| | | 360728,定南县,4,360700 |
| | | 360729,全南县,4,360700 |
| | | 360730,宁都县,4,360700 |
| | | 360731,于都县,4,360700 |
| | | 360732,兴国县,4,360700 |
| | | 360733,会昌县,4,360700 |
| | | 360734,寻乌县,4,360700 |
| | | 360735,石城县,4,360700 |
| | | 360781,瑞金市,4,360700 |
| | | 360783,龙南市,4,360700 |
| | | 360802,吉州区,4,360800 |
| | | 360803,青原区,4,360800 |
| | | 360821,吉安县,4,360800 |
| | | 360822,吉水县,4,360800 |
| | | 360823,峡江县,4,360800 |
| | | 360824,新干县,4,360800 |
| | | 360825,永丰县,4,360800 |
| | | 360826,泰和县,4,360800 |
| | | 360827,遂川县,4,360800 |
| | | 360828,万安县,4,360800 |
| | | 360829,安福县,4,360800 |
| | | 360830,永新县,4,360800 |
| | | 360881,井冈山市,4,360800 |
| | | 360902,袁州区,4,360900 |
| | | 360921,奉新县,4,360900 |
| | | 360922,万载县,4,360900 |
| | | 360923,上高县,4,360900 |
| | | 360924,宜丰县,4,360900 |
| | | 360925,靖安县,4,360900 |
| | | 360926,铜鼓县,4,360900 |
| | | 360981,丰城市,4,360900 |
| | | 360982,樟树市,4,360900 |
| | | 360983,高安市,4,360900 |
| | | 361002,临川区,4,361000 |
| | | 361003,东乡区,4,361000 |
| | | 361021,南城县,4,361000 |
| | | 361022,黎川县,4,361000 |
| | | 361023,南丰县,4,361000 |
| | | 361024,崇仁县,4,361000 |
| | | 361025,乐安县,4,361000 |
| | | 361026,宜黄县,4,361000 |
| | | 361027,金溪县,4,361000 |
| | | 361028,资溪县,4,361000 |
| | | 361030,广昌县,4,361000 |
| | | 361102,信州区,4,361100 |
| | | 361103,广丰区,4,361100 |
| | | 361104,广信区,4,361100 |
| | | 361123,玉山县,4,361100 |
| | | 361124,铅山县,4,361100 |
| | | 361125,横峰县,4,361100 |
| | | 361126,弋阳县,4,361100 |
| | | 361127,余干县,4,361100 |
| | | 361128,鄱阳县,4,361100 |
| | | 361129,万年县,4,361100 |
| | | 361130,婺源县,4,361100 |
| | | 361181,德兴市,4,361100 |
| | | 370102,历下区,4,370100 |
| | | 370103,市中区,4,370100 |
| | | 370104,槐荫区,4,370100 |
| | | 370105,天桥区,4,370100 |
| | | 370112,历城区,4,370100 |
| | | 370113,长清区,4,370100 |
| | | 370114,章丘区,4,370100 |
| | | 370115,济阳区,4,370100 |
| | | 370116,莱芜区,4,370100 |
| | | 370117,钢城区,4,370100 |
| | | 370124,平阴县,4,370100 |
| | | 370126,商河县,4,370100 |
| | | 370171,济南高新技术产业开发区,4,370100 |
| | | 370202,市南区,4,370200 |
| | | 370203,市北区,4,370200 |
| | | 370211,黄岛区,4,370200 |
| | | 370212,崂山区,4,370200 |
| | | 370213,李沧区,4,370200 |
| | | 370214,城阳区,4,370200 |
| | | 370215,即墨区,4,370200 |
| | | 370271,青岛高新技术产业开发区,4,370200 |
| | | 370281,胶州市,4,370200 |
| | | 370283,平度市,4,370200 |
| | | 370285,莱西市,4,370200 |
| | | 370302,淄川区,4,370300 |
| | | 370303,张店区,4,370300 |
| | | 370304,博山区,4,370300 |
| | | 370305,临淄区,4,370300 |
| | | 370306,周村区,4,370300 |
| | | 370321,桓台县,4,370300 |
| | | 370322,高青县,4,370300 |
| | | 370323,沂源县,4,370300 |
| | | 370402,市中区,4,370400 |
| | | 370403,薛城区,4,370400 |
| | | 370404,峄城区,4,370400 |
| | | 370405,台儿庄区,4,370400 |
| | | 370406,山亭区,4,370400 |
| | | 370481,滕州市,4,370400 |
| | | 370502,东营区,4,370500 |
| | | 370503,河口区,4,370500 |
| | | 370505,垦利区,4,370500 |
| | | 370522,利津县,4,370500 |
| | | 370523,广饶县,4,370500 |
| | | 370571,东营经济技术开发区,4,370500 |
| | | 370572,东营港经济开发区,4,370500 |
| | | 370602,芝罘区,4,370600 |
| | | 370611,福山区,4,370600 |
| | | 370612,牟平区,4,370600 |
| | | 370613,莱山区,4,370600 |
| | | 370614,蓬莱区,4,370600 |
| | | 370671,烟台高新技术产业开发区,4,370600 |
| | | 370672,烟台经济技术开发区,4,370600 |
| | | 370681,龙口市,4,370600 |
| | | 370682,莱阳市,4,370600 |
| | | 370683,莱州市,4,370600 |
| | | 370685,招远市,4,370600 |
| | | 370686,栖霞市,4,370600 |
| | | 370687,海阳市,4,370600 |
| | | 370702,潍城区,4,370700 |
| | | 370703,寒亭区,4,370700 |
| | | 370704,坊子区,4,370700 |
| | | 370705,奎文区,4,370700 |
| | | 370724,临朐县,4,370700 |
| | | 370725,昌乐县,4,370700 |
| | | 370772,潍坊滨海经济技术开发区,4,370700 |
| | | 370781,青州市,4,370700 |
| | | 370782,诸城市,4,370700 |
| | | 370783,寿光市,4,370700 |
| | | 370784,安丘市,4,370700 |
| | | 370785,高密市,4,370700 |
| | | 370786,昌邑市,4,370700 |
| | | 370811,任城区,4,370800 |
| | | 370812,兖州区,4,370800 |
| | | 370826,微山县,4,370800 |
| | | 370827,鱼台县,4,370800 |
| | | 370828,金乡县,4,370800 |
| | | 370829,嘉祥县,4,370800 |
| | | 370830,汶上县,4,370800 |
| | | 370831,泗水县,4,370800 |
| | | 370832,梁山县,4,370800 |
| | | 370871,济宁高新技术产业开发区,4,370800 |
| | | 370881,曲阜市,4,370800 |
| | | 370883,邹城市,4,370800 |
| | | 370902,泰山区,4,370900 |
| | | 370911,岱岳区,4,370900 |
| | | 370921,宁阳县,4,370900 |
| | | 370923,东平县,4,370900 |
| | | 370982,新泰市,4,370900 |
| | | 370983,肥城市,4,370900 |
| | | 371002,环翠区,4,371000 |
| | | 371003,文登区,4,371000 |
| | | 371071,威海火炬高技术产业开发区,4,371000 |
| | | 371072,威海经济技术开发区,4,371000 |
| | | 371073,威海临港经济技术开发区,4,371000 |
| | | 371082,荣成市,4,371000 |
| | | 371083,乳山市,4,371000 |
| | | 371102,东港区,4,371100 |
| | | 371103,岚山区,4,371100 |
| | | 371121,五莲县,4,371100 |
| | | 371122,莒县,4,371100 |
| | | 371171,日照经济技术开发区,4,371100 |
| | | 371302,兰山区,4,371300 |
| | | 371311,罗庄区,4,371300 |
| | | 371312,河东区,4,371300 |
| | | 371321,沂南县,4,371300 |
| | | 371322,郯城县,4,371300 |
| | | 371323,沂水县,4,371300 |
| | | 371324,兰陵县,4,371300 |
| | | 371325,费县,4,371300 |
| | | 371326,平邑县,4,371300 |
| | | 371327,莒南县,4,371300 |
| | | 371328,蒙阴县,4,371300 |
| | | 371329,临沭县,4,371300 |
| | | 371371,临沂高新技术产业开发区,4,371300 |
| | | 371402,德城区,4,371400 |
| | | 371403,陵城区,4,371400 |
| | | 371422,宁津县,4,371400 |
| | | 371423,庆云县,4,371400 |
| | | 371424,临邑县,4,371400 |
| | | 371425,齐河县,4,371400 |
| | | 371426,平原县,4,371400 |
| | | 371427,夏津县,4,371400 |
| | | 371428,武城县,4,371400 |
| | | 371471,德州经济技术开发区,4,371400 |
| | | 371472,德州运河经济开发区,4,371400 |
| | | 371481,乐陵市,4,371400 |
| | | 371482,禹城市,4,371400 |
| | | 371502,东昌府区,4,371500 |
| | | 371503,茌平区,4,371500 |
| | | 371521,阳谷县,4,371500 |
| | | 371522,莘县,4,371500 |
| | | 371524,东阿县,4,371500 |
| | | 371525,冠县,4,371500 |
| | | 371526,高唐县,4,371500 |
| | | 371581,临清市,4,371500 |
| | | 371602,滨城区,4,371600 |
| | | 371603,沾化区,4,371600 |
| | | 371621,惠民县,4,371600 |
| | | 371622,阳信县,4,371600 |
| | | 371623,无棣县,4,371600 |
| | | 371625,博兴县,4,371600 |
| | | 371681,邹平市,4,371600 |
| | | 371702,牡丹区,4,371700 |
| | | 371703,定陶区,4,371700 |
| | | 371721,曹县,4,371700 |
| | | 371722,单县,4,371700 |
| | | 371723,成武县,4,371700 |
| | | 371724,巨野县,4,371700 |
| | | 371725,郓城县,4,371700 |
| | | 371726,鄄城县,4,371700 |
| | | 371728,东明县,4,371700 |
| | | 371771,菏泽经济技术开发区,4,371700 |
| | | 371772,菏泽高新技术开发区,4,371700 |
| | | 410102,中原区,4,410100 |
| | | 410103,二七区,4,410100 |
| | | 410104,管城回族区,4,410100 |
| | | 410105,金水区,4,410100 |
| | | 410106,上街区,4,410100 |
| | | 410108,惠济区,4,410100 |
| | | 410122,中牟县,4,410100 |
| | | 410171,郑州经济技术开发区,4,410100 |
| | | 410172,郑州高新技术产业开发区,4,410100 |
| | | 410173,郑州航空港经济综合实验区,4,410100 |
| | | 410181,巩义市,4,410100 |
| | | 410182,荥阳市,4,410100 |
| | | 410183,新密市,4,410100 |
| | | 410184,新郑市,4,410100 |
| | | 410185,登封市,4,410100 |
| | | 410202,龙亭区,4,410200 |
| | | 410203,顺河回族区,4,410200 |
| | | 410204,鼓楼区,4,410200 |
| | | 410205,禹王台区,4,410200 |
| | | 410212,祥符区,4,410200 |
| | | 410221,杞县,4,410200 |
| | | 410222,通许县,4,410200 |
| | | 410223,尉氏县,4,410200 |
| | | 410225,兰考县,4,410200 |
| | | 410302,老城区,4,410300 |
| | | 410303,西工区,4,410300 |
| | | 410304,瀍河回族区,4,410300 |
| | | 410305,涧西区,4,410300 |
| | | 410307,偃师区,4,410300 |
| | | 410308,孟津区,4,410300 |
| | | 410311,洛龙区,4,410300 |
| | | 410323,新安县,4,410300 |
| | | 410324,栾川县,4,410300 |
| | | 410325,嵩县,4,410300 |
| | | 410326,汝阳县,4,410300 |
| | | 410327,宜阳县,4,410300 |
| | | 410328,洛宁县,4,410300 |
| | | 410329,伊川县,4,410300 |
| | | 410371,洛阳高新技术产业开发区,4,410300 |
| | | 410402,新华区,4,410400 |
| | | 410403,卫东区,4,410400 |
| | | 410404,石龙区,4,410400 |
| | | 410411,湛河区,4,410400 |
| | | 410421,宝丰县,4,410400 |
| | | 410422,叶县,4,410400 |
| | | 410423,鲁山县,4,410400 |
| | | 410425,郏县,4,410400 |
| | | 410471,平顶山高新技术产业开发区,4,410400 |
| | | 410472,平顶山市城乡一体化示范区,4,410400 |
| | | 410481,舞钢市,4,410400 |
| | | 410482,汝州市,4,410400 |
| | | 410502,文峰区,4,410500 |
| | | 410503,北关区,4,410500 |
| | | 410505,殷都区,4,410500 |
| | | 410506,龙安区,4,410500 |
| | | 410522,安阳县,4,410500 |
| | | 410523,汤阴县,4,410500 |
| | | 410526,滑县,4,410500 |
| | | 410527,内黄县,4,410500 |
| | | 410571,安阳高新技术产业开发区,4,410500 |
| | | 410581,林州市,4,410500 |
| | | 410602,鹤山区,4,410600 |
| | | 410603,山城区,4,410600 |
| | | 410611,淇滨区,4,410600 |
| | | 410621,浚县,4,410600 |
| | | 410622,淇县,4,410600 |
| | | 410671,鹤壁经济技术开发区,4,410600 |
| | | 410702,红旗区,4,410700 |
| | | 410703,卫滨区,4,410700 |
| | | 410704,凤泉区,4,410700 |
| | | 410711,牧野区,4,410700 |
| | | 410721,新乡县,4,410700 |
| | | 410724,获嘉县,4,410700 |
| | | 410725,原阳县,4,410700 |
| | | 410726,延津县,4,410700 |
| | | 410727,封丘县,4,410700 |
| | | 410771,新乡高新技术产业开发区,4,410700 |
| | | 410772,新乡经济技术开发区,4,410700 |
| | | 410773,新乡市平原城乡一体化示范区,4,410700 |
| | | 410781,卫辉市,4,410700 |
| | | 410782,辉县市,4,410700 |
| | | 410783,长垣市,4,410700 |
| | | 410802,解放区,4,410800 |
| | | 410803,中站区,4,410800 |
| | | 410804,马村区,4,410800 |
| | | 410811,山阳区,4,410800 |
| | | 410821,修武县,4,410800 |
| | | 410822,博爱县,4,410800 |
| | | 410823,武陟县,4,410800 |
| | | 410825,温县,4,410800 |
| | | 410871,焦作城乡一体化示范区,4,410800 |
| | | 410882,沁阳市,4,410800 |
| | | 410883,孟州市,4,410800 |
| | | 410902,华龙区,4,410900 |
| | | 410922,清丰县,4,410900 |
| | | 410923,南乐县,4,410900 |
| | | 410926,范县,4,410900 |
| | | 410927,台前县,4,410900 |
| | | 410928,濮阳县,4,410900 |
| | | 410971,河南濮阳工业园区,4,410900 |
| | | 410972,濮阳经济技术开发区,4,410900 |
| | | 411002,魏都区,4,411000 |
| | | 411003,建安区,4,411000 |
| | | 411024,鄢陵县,4,411000 |
| | | 411025,襄城县,4,411000 |
| | | 411071,许昌经济技术开发区,4,411000 |
| | | 411081,禹州市,4,411000 |
| | | 411082,长葛市,4,411000 |
| | | 411102,源汇区,4,411100 |
| | | 411103,郾城区,4,411100 |
| | | 411104,召陵区,4,411100 |
| | | 411121,舞阳县,4,411100 |
| | | 411122,临颍县,4,411100 |
| | | 411171,漯河经济技术开发区,4,411100 |
| | | 411202,湖滨区,4,411200 |
| | | 411203,陕州区,4,411200 |
| | | 411221,渑池县,4,411200 |
| | | 411224,卢氏县,4,411200 |
| | | 411271,河南三门峡经济开发区,4,411200 |
| | | 411281,义马市,4,411200 |
| | | 411282,灵宝市,4,411200 |
| | | 411302,宛城区,4,411300 |
| | | 411303,卧龙区,4,411300 |
| | | 411321,南召县,4,411300 |
| | | 411322,方城县,4,411300 |
| | | 411323,西峡县,4,411300 |
| | | 411324,镇平县,4,411300 |
| | | 411325,内乡县,4,411300 |
| | | 411326,淅川县,4,411300 |
| | | 411327,社旗县,4,411300 |
| | | 411328,唐河县,4,411300 |
| | | 411329,新野县,4,411300 |
| | | 411330,桐柏县,4,411300 |
| | | 411371,南阳高新技术产业开发区,4,411300 |
| | | 411372,南阳市城乡一体化示范区,4,411300 |
| | | 411381,邓州市,4,411300 |
| | | 411402,梁园区,4,411400 |
| | | 411403,睢阳区,4,411400 |
| | | 411421,民权县,4,411400 |
| | | 411422,睢县,4,411400 |
| | | 411423,宁陵县,4,411400 |
| | | 411424,柘城县,4,411400 |
| | | 411425,虞城县,4,411400 |
| | | 411426,夏邑县,4,411400 |
| | | 411471,豫东综合物流产业聚集区,4,411400 |
| | | 411472,河南商丘经济开发区,4,411400 |
| | | 411481,永城市,4,411400 |
| | | 411502,浉河区,4,411500 |
| | | 411503,平桥区,4,411500 |
| | | 411521,罗山县,4,411500 |
| | | 411522,光山县,4,411500 |
| | | 411523,新县,4,411500 |
| | | 411524,商城县,4,411500 |
| | | 411525,固始县,4,411500 |
| | | 411526,潢川县,4,411500 |
| | | 411527,淮滨县,4,411500 |
| | | 411528,息县,4,411500 |
| | | 411571,信阳高新技术产业开发区,4,411500 |
| | | 411602,川汇区,4,411600 |
| | | 411603,淮阳区,4,411600 |
| | | 411621,扶沟县,4,411600 |
| | | 411622,西华县,4,411600 |
| | | 411623,商水县,4,411600 |
| | | 411624,沈丘县,4,411600 |
| | | 411625,郸城县,4,411600 |
| | | 411627,太康县,4,411600 |
| | | 411628,鹿邑县,4,411600 |
| | | 411671,河南周口经济开发区,4,411600 |
| | | 411681,项城市,4,411600 |
| | | 411702,驿城区,4,411700 |
| | | 411721,西平县,4,411700 |
| | | 411722,上蔡县,4,411700 |
| | | 411723,平舆县,4,411700 |
| | | 411724,正阳县,4,411700 |
| | | 411725,确山县,4,411700 |
| | | 411726,泌阳县,4,411700 |
| | | 411727,汝南县,4,411700 |
| | | 411728,遂平县,4,411700 |
| | | 411729,新蔡县,4,411700 |
| | | 411771,河南驻马店经济开发区,4,411700 |
| | | 419001,济源市,4,419000 |
| | | 420102,江岸区,4,420100 |
| | | 420103,江汉区,4,420100 |
| | | 420104,硚口区,4,420100 |
| | | 420105,汉阳区,4,420100 |
| | | 420106,武昌区,4,420100 |
| | | 420107,青山区,4,420100 |
| | | 420111,洪山区,4,420100 |
| | | 420112,东西湖区,4,420100 |
| | | 420113,汉南区,4,420100 |
| | | 420114,蔡甸区,4,420100 |
| | | 420115,江夏区,4,420100 |
| | | 420116,黄陂区,4,420100 |
| | | 420117,新洲区,4,420100 |
| | | 420202,黄石港区,4,420200 |
| | | 420203,西塞山区,4,420200 |
| | | 420204,下陆区,4,420200 |
| | | 420205,铁山区,4,420200 |
| | | 420222,阳新县,4,420200 |
| | | 420281,大冶市,4,420200 |
| | | 420302,茅箭区,4,420300 |
| | | 420303,张湾区,4,420300 |
| | | 420304,郧阳区,4,420300 |
| | | 420322,郧西县,4,420300 |
| | | 420323,竹山县,4,420300 |
| | | 420324,竹溪县,4,420300 |
| | | 420325,房县,4,420300 |
| | | 420381,丹江口市,4,420300 |
| | | 420502,西陵区,4,420500 |
| | | 420503,伍家岗区,4,420500 |
| | | 420504,点军区,4,420500 |
| | | 420505,猇亭区,4,420500 |
| | | 420506,夷陵区,4,420500 |
| | | 420525,远安县,4,420500 |
| | | 420526,兴山县,4,420500 |
| | | 420527,秭归县,4,420500 |
| | | 420528,长阳土家族自治县,4,420500 |
| | | 420529,五峰土家族自治县,4,420500 |
| | | 420581,宜都市,4,420500 |
| | | 420582,当阳市,4,420500 |
| | | 420583,枝江市,4,420500 |
| | | 420602,襄城区,4,420600 |
| | | 420606,樊城区,4,420600 |
| | | 420607,襄州区,4,420600 |
| | | 420624,南漳县,4,420600 |
| | | 420625,谷城县,4,420600 |
| | | 420626,保康县,4,420600 |
| | | 420682,老河口市,4,420600 |
| | | 420683,枣阳市,4,420600 |
| | | 420684,宜城市,4,420600 |
| | | 420702,梁子湖区,4,420700 |
| | | 420703,华容区,4,420700 |
| | | 420704,鄂城区,4,420700 |
| | | 420802,东宝区,4,420800 |
| | | 420804,掇刀区,4,420800 |
| | | 420822,沙洋县,4,420800 |
| | | 420881,钟祥市,4,420800 |
| | | 420882,京山市,4,420800 |
| | | 420902,孝南区,4,420900 |
| | | 420921,孝昌县,4,420900 |
| | | 420922,大悟县,4,420900 |
| | | 420923,云梦县,4,420900 |
| | | 420981,应城市,4,420900 |
| | | 420982,安陆市,4,420900 |
| | | 420984,汉川市,4,420900 |
| | | 421002,沙市区,4,421000 |
| | | 421003,荆州区,4,421000 |
| | | 421022,公安县,4,421000 |
| | | 421024,江陵县,4,421000 |
| | | 421071,荆州经济技术开发区,4,421000 |
| | | 421081,石首市,4,421000 |
| | | 421083,洪湖市,4,421000 |
| | | 421087,松滋市,4,421000 |
| | | 421088,监利市,4,421000 |
| | | 421102,黄州区,4,421100 |
| | | 421121,团风县,4,421100 |
| | | 421122,红安县,4,421100 |
| | | 421123,罗田县,4,421100 |
| | | 421124,英山县,4,421100 |
| | | 421125,浠水县,4,421100 |
| | | 421126,蕲春县,4,421100 |
| | | 421127,黄梅县,4,421100 |
| | | 421171,龙感湖管理区,4,421100 |
| | | 421181,麻城市,4,421100 |
| | | 421182,武穴市,4,421100 |
| | | 421202,咸安区,4,421200 |
| | | 421221,嘉鱼县,4,421200 |
| | | 421222,通城县,4,421200 |
| | | 421223,崇阳县,4,421200 |
| | | 421224,通山县,4,421200 |
| | | 421281,赤壁市,4,421200 |
| | | 421303,曾都区,4,421300 |
| | | 421321,随县,4,421300 |
| | | 421381,广水市,4,421300 |
| | | 422801,恩施市,4,422800 |
| | | 422802,利川市,4,422800 |
| | | 422822,建始县,4,422800 |
| | | 422823,巴东县,4,422800 |
| | | 422825,宣恩县,4,422800 |
| | | 422826,咸丰县,4,422800 |
| | | 422827,来凤县,4,422800 |
| | | 422828,鹤峰县,4,422800 |
| | | 429004,仙桃市,4,429000 |
| | | 429005,潜江市,4,429000 |
| | | 429006,天门市,4,429000 |
| | | 429021,神农架林区,4,429000 |
| | | 430102,芙蓉区,4,430100 |
| | | 430103,天心区,4,430100 |
| | | 430104,岳麓区,4,430100 |
| | | 430105,开福区,4,430100 |
| | | 430111,雨花区,4,430100 |
| | | 430112,望城区,4,430100 |
| | | 430121,长沙县,4,430100 |
| | | 430181,浏阳市,4,430100 |
| | | 430182,宁乡市,4,430100 |
| | | 430202,荷塘区,4,430200 |
| | | 430203,芦淞区,4,430200 |
| | | 430204,石峰区,4,430200 |
| | | 430211,天元区,4,430200 |
| | | 430212,渌口区,4,430200 |
| | | 430223,攸县,4,430200 |
| | | 430224,茶陵县,4,430200 |
| | | 430225,炎陵县,4,430200 |
| | | 430271,云龙示范区,4,430200 |
| | | 430281,醴陵市,4,430200 |
| | | 430302,雨湖区,4,430300 |
| | | 430304,岳塘区,4,430300 |
| | | 430321,湘潭县,4,430300 |
| | | 430371,湖南湘潭高新技术产业园区,4,430300 |
| | | 430372,湘潭昭山示范区,4,430300 |
| | | 430373,湘潭九华示范区,4,430300 |
| | | 430381,湘乡市,4,430300 |
| | | 430382,韶山市,4,430300 |
| | | 430405,珠晖区,4,430400 |
| | | 430406,雁峰区,4,430400 |
| | | 430407,石鼓区,4,430400 |
| | | 430408,蒸湘区,4,430400 |
| | | 430412,南岳区,4,430400 |
| | | 430421,衡阳县,4,430400 |
| | | 430422,衡南县,4,430400 |
| | | 430423,衡山县,4,430400 |
| | | 430424,衡东县,4,430400 |
| | | 430426,祁东县,4,430400 |
| | | 430471,衡阳综合保税区,4,430400 |
| | | 430472,湖南衡阳高新技术产业园区,4,430400 |
| | | 430473,湖南衡阳松木经济开发区,4,430400 |
| | | 430481,耒阳市,4,430400 |
| | | 430482,常宁市,4,430400 |
| | | 430502,双清区,4,430500 |
| | | 430503,大祥区,4,430500 |
| | | 430511,北塔区,4,430500 |
| | | 430522,新邵县,4,430500 |
| | | 430523,邵阳县,4,430500 |
| | | 430524,隆回县,4,430500 |
| | | 430525,洞口县,4,430500 |
| | | 430527,绥宁县,4,430500 |
| | | 430528,新宁县,4,430500 |
| | | 430529,城步苗族自治县,4,430500 |
| | | 430581,武冈市,4,430500 |
| | | 430582,邵东市,4,430500 |
| | | 430602,岳阳楼区,4,430600 |
| | | 430603,云溪区,4,430600 |
| | | 430611,君山区,4,430600 |
| | | 430621,岳阳县,4,430600 |
| | | 430623,华容县,4,430600 |
| | | 430624,湘阴县,4,430600 |
| | | 430626,平江县,4,430600 |
| | | 430671,岳阳市屈原管理区,4,430600 |
| | | 430681,汨罗市,4,430600 |
| | | 430682,临湘市,4,430600 |
| | | 430702,武陵区,4,430700 |
| | | 430703,鼎城区,4,430700 |
| | | 430721,安乡县,4,430700 |
| | | 430722,汉寿县,4,430700 |
| | | 430723,澧县,4,430700 |
| | | 430724,临澧县,4,430700 |
| | | 430725,桃源县,4,430700 |
| | | 430726,石门县,4,430700 |
| | | 430771,常德市西洞庭管理区,4,430700 |
| | | 430781,津市市,4,430700 |
| | | 430802,永定区,4,430800 |
| | | 430811,武陵源区,4,430800 |
| | | 430821,慈利县,4,430800 |
| | | 430822,桑植县,4,430800 |
| | | 430902,资阳区,4,430900 |
| | | 430903,赫山区,4,430900 |
| | | 430921,南县,4,430900 |
| | | 430922,桃江县,4,430900 |
| | | 430923,安化县,4,430900 |
| | | 430971,益阳市大通湖管理区,4,430900 |
| | | 430972,湖南益阳高新技术产业园区,4,430900 |
| | | 430981,沅江市,4,430900 |
| | | 431002,北湖区,4,431000 |
| | | 431003,苏仙区,4,431000 |
| | | 431021,桂阳县,4,431000 |
| | | 431022,宜章县,4,431000 |
| | | 431023,永兴县,4,431000 |
| | | 431024,嘉禾县,4,431000 |
| | | 431025,临武县,4,431000 |
| | | 431026,汝城县,4,431000 |
| | | 431027,桂东县,4,431000 |
| | | 431028,安仁县,4,431000 |
| | | 431081,资兴市,4,431000 |
| | | 431102,零陵区,4,431100 |
| | | 431103,冷水滩区,4,431100 |
| | | 431122,东安县,4,431100 |
| | | 431123,双牌县,4,431100 |
| | | 431124,道县,4,431100 |
| | | 431125,江永县,4,431100 |
| | | 431126,宁远县,4,431100 |
| | | 431127,蓝山县,4,431100 |
| | | 431128,新田县,4,431100 |
| | | 431129,江华瑶族自治县,4,431100 |
| | | 431171,永州经济技术开发区,4,431100 |
| | | 431173,永州市回龙圩管理区,4,431100 |
| | | 431181,祁阳市,4,431100 |
| | | 431202,鹤城区,4,431200 |
| | | 431221,中方县,4,431200 |
| | | 431222,沅陵县,4,431200 |
| | | 431223,辰溪县,4,431200 |
| | | 431224,溆浦县,4,431200 |
| | | 431225,会同县,4,431200 |
| | | 431226,麻阳苗族自治县,4,431200 |
| | | 431227,新晃侗族自治县,4,431200 |
| | | 431228,芷江侗族自治县,4,431200 |
| | | 431229,靖州苗族侗族自治县,4,431200 |
| | | 431230,通道侗族自治县,4,431200 |
| | | 431271,怀化市洪江管理区,4,431200 |
| | | 431281,洪江市,4,431200 |
| | | 431302,娄星区,4,431300 |
| | | 431321,双峰县,4,431300 |
| | | 431322,新化县,4,431300 |
| | | 431381,冷水江市,4,431300 |
| | | 431382,涟源市,4,431300 |
| | | 433101,吉首市,4,433100 |
| | | 433122,泸溪县,4,433100 |
| | | 433123,凤凰县,4,433100 |
| | | 433124,花垣县,4,433100 |
| | | 433125,保靖县,4,433100 |
| | | 433126,古丈县,4,433100 |
| | | 433127,永顺县,4,433100 |
| | | 433130,龙山县,4,433100 |
| | | 440103,荔湾区,4,440100 |
| | | 440104,越秀区,4,440100 |
| | | 440105,海珠区,4,440100 |
| | | 440106,天河区,4,440100 |
| | | 440111,白云区,4,440100 |
| | | 440112,黄埔区,4,440100 |
| | | 440113,番禺区,4,440100 |
| | | 440114,花都区,4,440100 |
| | | 440115,南沙区,4,440100 |
| | | 440117,从化区,4,440100 |
| | | 440118,增城区,4,440100 |
| | | 440203,武江区,4,440200 |
| | | 440204,浈江区,4,440200 |
| | | 440205,曲江区,4,440200 |
| | | 440222,始兴县,4,440200 |
| | | 440224,仁化县,4,440200 |
| | | 440229,翁源县,4,440200 |
| | | 440232,乳源瑶族自治县,4,440200 |
| | | 440233,新丰县,4,440200 |
| | | 440281,乐昌市,4,440200 |
| | | 440282,南雄市,4,440200 |
| | | 440303,罗湖区,4,440300 |
| | | 440304,福田区,4,440300 |
| | | 440305,南山区,4,440300 |
| | | 440306,宝安区,4,440300 |
| | | 440307,龙岗区,4,440300 |
| | | 440308,盐田区,4,440300 |
| | | 440309,龙华区,4,440300 |
| | | 440310,坪山区,4,440300 |
| | | 440311,光明区,4,440300 |
| | | 440402,香洲区,4,440400 |
| | | 440403,斗门区,4,440400 |
| | | 440404,金湾区,4,440400 |
| | | 440507,龙湖区,4,440500 |
| | | 440511,金平区,4,440500 |
| | | 440512,濠江区,4,440500 |
| | | 440513,潮阳区,4,440500 |
| | | 440514,潮南区,4,440500 |
| | | 440515,澄海区,4,440500 |
| | | 440523,南澳县,4,440500 |
| | | 440604,禅城区,4,440600 |
| | | 440605,南海区,4,440600 |
| | | 440606,顺德区,4,440600 |
| | | 440607,三水区,4,440600 |
| | | 440608,高明区,4,440600 |
| | | 440703,蓬江区,4,440700 |
| | | 440704,江海区,4,440700 |
| | | 440705,新会区,4,440700 |
| | | 440781,台山市,4,440700 |
| | | 440783,开平市,4,440700 |
| | | 440784,鹤山市,4,440700 |
| | | 440785,恩平市,4,440700 |
| | | 440802,赤坎区,4,440800 |
| | | 440803,霞山区,4,440800 |
| | | 440804,坡头区,4,440800 |
| | | 440811,麻章区,4,440800 |
| | | 440823,遂溪县,4,440800 |
| | | 440825,徐闻县,4,440800 |
| | | 440881,廉江市,4,440800 |
| | | 440882,雷州市,4,440800 |
| | | 440883,吴川市,4,440800 |
| | | 440902,茂南区,4,440900 |
| | | 440904,电白区,4,440900 |
| | | 440981,高州市,4,440900 |
| | | 440982,化州市,4,440900 |
| | | 440983,信宜市,4,440900 |
| | | 441202,端州区,4,441200 |
| | | 441203,鼎湖区,4,441200 |
| | | 441204,高要区,4,441200 |
| | | 441223,广宁县,4,441200 |
| | | 441224,怀集县,4,441200 |
| | | 441225,封开县,4,441200 |
| | | 441226,德庆县,4,441200 |
| | | 441284,四会市,4,441200 |
| | | 441302,惠城区,4,441300 |
| | | 441303,惠阳区,4,441300 |
| | | 441322,博罗县,4,441300 |
| | | 441323,惠东县,4,441300 |
| | | 441324,龙门县,4,441300 |
| | | 441402,梅江区,4,441400 |
| | | 441403,梅县区,4,441400 |
| | | 441422,大埔县,4,441400 |
| | | 441423,丰顺县,4,441400 |
| | | 441424,五华县,4,441400 |
| | | 441426,平远县,4,441400 |
| | | 441427,蕉岭县,4,441400 |
| | | 441481,兴宁市,4,441400 |
| | | 441502,城区,4,441500 |
| | | 441521,海丰县,4,441500 |
| | | 441523,陆河县,4,441500 |
| | | 441581,陆丰市,4,441500 |
| | | 441602,源城区,4,441600 |
| | | 441621,紫金县,4,441600 |
| | | 441622,龙川县,4,441600 |
| | | 441623,连平县,4,441600 |
| | | 441624,和平县,4,441600 |
| | | 441625,东源县,4,441600 |
| | | 441702,江城区,4,441700 |
| | | 441704,阳东区,4,441700 |
| | | 441721,阳西县,4,441700 |
| | | 441781,阳春市,4,441700 |
| | | 441802,清城区,4,441800 |
| | | 441803,清新区,4,441800 |
| | | 441821,佛冈县,4,441800 |
| | | 441823,阳山县,4,441800 |
| | | 441825,连山壮族瑶族自治县,4,441800 |
| | | 441826,连南瑶族自治县,4,441800 |
| | | 441881,英德市,4,441800 |
| | | 441882,连州市,4,441800 |
| | | 445102,湘桥区,4,445100 |
| | | 445103,潮安区,4,445100 |
| | | 445122,饶平县,4,445100 |
| | | 445202,榕城区,4,445200 |
| | | 445203,揭东区,4,445200 |
| | | 445222,揭西县,4,445200 |
| | | 445224,惠来县,4,445200 |
| | | 445281,普宁市,4,445200 |
| | | 445302,云城区,4,445300 |
| | | 445303,云安区,4,445300 |
| | | 445321,新兴县,4,445300 |
| | | 445322,郁南县,4,445300 |
| | | 445381,罗定市,4,445300 |
| | | 450102,兴宁区,4,450100 |
| | | 450103,青秀区,4,450100 |
| | | 450105,江南区,4,450100 |
| | | 450107,西乡塘区,4,450100 |
| | | 450108,良庆区,4,450100 |
| | | 450109,邕宁区,4,450100 |
| | | 450110,武鸣区,4,450100 |
| | | 450123,隆安县,4,450100 |
| | | 450124,马山县,4,450100 |
| | | 450125,上林县,4,450100 |
| | | 450126,宾阳县,4,450100 |
| | | 450181,横州市,4,450100 |
| | | 450202,城中区,4,450200 |
| | | 450203,鱼峰区,4,450200 |
| | | 450204,柳南区,4,450200 |
| | | 450205,柳北区,4,450200 |
| | | 450206,柳江区,4,450200 |
| | | 450222,柳城县,4,450200 |
| | | 450223,鹿寨县,4,450200 |
| | | 450224,融安县,4,450200 |
| | | 450225,融水苗族自治县,4,450200 |
| | | 450226,三江侗族自治县,4,450200 |
| | | 450302,秀峰区,4,450300 |
| | | 450303,叠彩区,4,450300 |
| | | 450304,象山区,4,450300 |
| | | 450305,七星区,4,450300 |
| | | 450311,雁山区,4,450300 |
| | | 450312,临桂区,4,450300 |
| | | 450321,阳朔县,4,450300 |
| | | 450323,灵川县,4,450300 |
| | | 450324,全州县,4,450300 |
| | | 450325,兴安县,4,450300 |
| | | 450326,永福县,4,450300 |
| | | 450327,灌阳县,4,450300 |
| | | 450328,龙胜各族自治县,4,450300 |
| | | 450329,资源县,4,450300 |
| | | 450330,平乐县,4,450300 |
| | | 450332,恭城瑶族自治县,4,450300 |
| | | 450381,荔浦市,4,450300 |
| | | 450403,万秀区,4,450400 |
| | | 450405,长洲区,4,450400 |
| | | 450406,龙圩区,4,450400 |
| | | 450421,苍梧县,4,450400 |
| | | 450422,藤县,4,450400 |
| | | 450423,蒙山县,4,450400 |
| | | 450481,岑溪市,4,450400 |
| | | 450502,海城区,4,450500 |
| | | 450503,银海区,4,450500 |
| | | 450512,铁山港区,4,450500 |
| | | 450521,合浦县,4,450500 |
| | | 450602,港口区,4,450600 |
| | | 450603,防城区,4,450600 |
| | | 450621,上思县,4,450600 |
| | | 450681,东兴市,4,450600 |
| | | 450702,钦南区,4,450700 |
| | | 450703,钦北区,4,450700 |
| | | 450721,灵山县,4,450700 |
| | | 450722,浦北县,4,450700 |
| | | 450802,港北区,4,450800 |
| | | 450803,港南区,4,450800 |
| | | 450804,覃塘区,4,450800 |
| | | 450821,平南县,4,450800 |
| | | 450881,桂平市,4,450800 |
| | | 450902,玉州区,4,450900 |
| | | 450903,福绵区,4,450900 |
| | | 450921,容县,4,450900 |
| | | 450922,陆川县,4,450900 |
| | | 450923,博白县,4,450900 |
| | | 450924,兴业县,4,450900 |
| | | 450981,北流市,4,450900 |
| | | 451002,右江区,4,451000 |
| | | 451003,田阳区,4,451000 |
| | | 451022,田东县,4,451000 |
| | | 451024,德保县,4,451000 |
| | | 451026,那坡县,4,451000 |
| | | 451027,凌云县,4,451000 |
| | | 451028,乐业县,4,451000 |
| | | 451029,田林县,4,451000 |
| | | 451030,西林县,4,451000 |
| | | 451031,隆林各族自治县,4,451000 |
| | | 451081,靖西市,4,451000 |
| | | 451082,平果市,4,451000 |
| | | 451102,八步区,4,451100 |
| | | 451103,平桂区,4,451100 |
| | | 451121,昭平县,4,451100 |
| | | 451122,钟山县,4,451100 |
| | | 451123,富川瑶族自治县,4,451100 |
| | | 451202,金城江区,4,451200 |
| | | 451203,宜州区,4,451200 |
| | | 451221,南丹县,4,451200 |
| | | 451222,天峨县,4,451200 |
| | | 451223,凤山县,4,451200 |
| | | 451224,东兰县,4,451200 |
| | | 451225,罗城仫佬族自治县,4,451200 |
| | | 451226,环江毛南族自治县,4,451200 |
| | | 451227,巴马瑶族自治县,4,451200 |
| | | 451228,都安瑶族自治县,4,451200 |
| | | 451229,大化瑶族自治县,4,451200 |
| | | 451302,兴宾区,4,451300 |
| | | 451321,忻城县,4,451300 |
| | | 451322,象州县,4,451300 |
| | | 451323,武宣县,4,451300 |
| | | 451324,金秀瑶族自治县,4,451300 |
| | | 451381,合山市,4,451300 |
| | | 451402,江州区,4,451400 |
| | | 451421,扶绥县,4,451400 |
| | | 451422,宁明县,4,451400 |
| | | 451423,龙州县,4,451400 |
| | | 451424,大新县,4,451400 |
| | | 451425,天等县,4,451400 |
| | | 451481,凭祥市,4,451400 |
| | | 460105,秀英区,4,460100 |
| | | 460106,龙华区,4,460100 |
| | | 460107,琼山区,4,460100 |
| | | 460108,美兰区,4,460100 |
| | | 460202,海棠区,4,460200 |
| | | 460203,吉阳区,4,460200 |
| | | 460204,天涯区,4,460200 |
| | | 460205,崖州区,4,460200 |
| | | 460321,西沙群岛,4,460300 |
| | | 460322,南沙群岛,4,460300 |
| | | 460323,中沙群岛的岛礁及其海域,4,460300 |
| | | 469001,五指山市,4,469000 |
| | | 469002,琼海市,4,469000 |
| | | 469005,文昌市,4,469000 |
| | | 469006,万宁市,4,469000 |
| | | 469007,东方市,4,469000 |
| | | 469021,定安县,4,469000 |
| | | 469022,屯昌县,4,469000 |
| | | 469023,澄迈县,4,469000 |
| | | 469024,临高县,4,469000 |
| | | 469025,白沙黎族自治县,4,469000 |
| | | 469026,昌江黎族自治县,4,469000 |
| | | 469027,乐东黎族自治县,4,469000 |
| | | 469028,陵水黎族自治县,4,469000 |
| | | 469029,保亭黎族苗族自治县,4,469000 |
| | | 469030,琼中黎族苗族自治县,4,469000 |
| | | 500101,万州区,4,500100 |
| | | 500102,涪陵区,4,500100 |
| | | 500103,渝中区,4,500100 |
| | | 500104,大渡口区,4,500100 |
| | | 500105,江北区,4,500100 |
| | | 500106,沙坪坝区,4,500100 |
| | | 500107,九龙坡区,4,500100 |
| | | 500108,南岸区,4,500100 |
| | | 500109,北碚区,4,500100 |
| | | 500110,綦江区,4,500100 |
| | | 500111,大足区,4,500100 |
| | | 500112,渝北区,4,500100 |
| | | 500113,巴南区,4,500100 |
| | | 500114,黔江区,4,500100 |
| | | 500115,长寿区,4,500100 |
| | | 500116,江津区,4,500100 |
| | | 500117,合川区,4,500100 |
| | | 500118,永川区,4,500100 |
| | | 500119,南川区,4,500100 |
| | | 500120,璧山区,4,500100 |
| | | 500151,铜梁区,4,500100 |
| | | 500152,潼南区,4,500100 |
| | | 500153,荣昌区,4,500100 |
| | | 500154,开州区,4,500100 |
| | | 500155,梁平区,4,500100 |
| | | 500156,武隆区,4,500100 |
| | | 500229,城口县,4,500100 |
| | | 500230,丰都县,4,500100 |
| | | 500231,垫江县,4,500100 |
| | | 500233,忠县,4,500100 |
| | | 500235,云阳县,4,500100 |
| | | 500236,奉节县,4,500100 |
| | | 500237,巫山县,4,500100 |
| | | 500238,巫溪县,4,500100 |
| | | 500240,石柱土家族自治县,4,500100 |
| | | 500241,秀山土家族苗族自治县,4,500100 |
| | | 500242,酉阳土家族苗族自治县,4,500100 |
| | | 500243,彭水苗族土家族自治县,4,500100 |
| | | 510104,锦江区,4,510100 |
| | | 510105,青羊区,4,510100 |
| | | 510106,金牛区,4,510100 |
| | | 510107,武侯区,4,510100 |
| | | 510108,成华区,4,510100 |
| | | 510112,龙泉驿区,4,510100 |
| | | 510113,青白江区,4,510100 |
| | | 510114,新都区,4,510100 |
| | | 510115,温江区,4,510100 |
| | | 510116,双流区,4,510100 |
| | | 510117,郫都区,4,510100 |
| | | 510118,新津区,4,510100 |
| | | 510121,金堂县,4,510100 |
| | | 510129,大邑县,4,510100 |
| | | 510131,蒲江县,4,510100 |
| | | 510181,都江堰市,4,510100 |
| | | 510182,彭州市,4,510100 |
| | | 510183,邛崃市,4,510100 |
| | | 510184,崇州市,4,510100 |
| | | 510185,简阳市,4,510100 |
| | | 510302,自流井区,4,510300 |
| | | 510303,贡井区,4,510300 |
| | | 510304,大安区,4,510300 |
| | | 510311,沿滩区,4,510300 |
| | | 510321,荣县,4,510300 |
| | | 510322,富顺县,4,510300 |
| | | 510402,东区,4,510400 |
| | | 510403,西区,4,510400 |
| | | 510411,仁和区,4,510400 |
| | | 510421,米易县,4,510400 |
| | | 510422,盐边县,4,510400 |
| | | 510502,江阳区,4,510500 |
| | | 510503,纳溪区,4,510500 |
| | | 510504,龙马潭区,4,510500 |
| | | 510521,泸县,4,510500 |
| | | 510522,合江县,4,510500 |
| | | 510524,叙永县,4,510500 |
| | | 510525,古蔺县,4,510500 |
| | | 510603,旌阳区,4,510600 |
| | | 510604,罗江区,4,510600 |
| | | 510623,中江县,4,510600 |
| | | 510681,广汉市,4,510600 |
| | | 510682,什邡市,4,510600 |
| | | 510683,绵竹市,4,510600 |
| | | 510703,涪城区,4,510700 |
| | | 510704,游仙区,4,510700 |
| | | 510705,安州区,4,510700 |
| | | 510722,三台县,4,510700 |
| | | 510723,盐亭县,4,510700 |
| | | 510725,梓潼县,4,510700 |
| | | 510726,北川羌族自治县,4,510700 |
| | | 510727,平武县,4,510700 |
| | | 510781,江油市,4,510700 |
| | | 510802,利州区,4,510800 |
| | | 510811,昭化区,4,510800 |
| | | 510812,朝天区,4,510800 |
| | | 510821,旺苍县,4,510800 |
| | | 510822,青川县,4,510800 |
| | | 510823,剑阁县,4,510800 |
| | | 510824,苍溪县,4,510800 |
| | | 510903,船山区,4,510900 |
| | | 510904,安居区,4,510900 |
| | | 510921,蓬溪县,4,510900 |
| | | 510923,大英县,4,510900 |
| | | 510981,射洪市,4,510900 |
| | | 511002,市中区,4,511000 |
| | | 511011,东兴区,4,511000 |
| | | 511024,威远县,4,511000 |
| | | 511025,资中县,4,511000 |
| | | 511071,内江经济开发区,4,511000 |
| | | 511083,隆昌市,4,511000 |
| | | 511102,市中区,4,511100 |
| | | 511111,沙湾区,4,511100 |
| | | 511112,五通桥区,4,511100 |
| | | 511113,金口河区,4,511100 |
| | | 511123,犍为县,4,511100 |
| | | 511124,井研县,4,511100 |
| | | 511126,夹江县,4,511100 |
| | | 511129,沐川县,4,511100 |
| | | 511132,峨边彝族自治县,4,511100 |
| | | 511133,马边彝族自治县,4,511100 |
| | | 511181,峨眉山市,4,511100 |
| | | 511302,顺庆区,4,511300 |
| | | 511303,高坪区,4,511300 |
| | | 511304,嘉陵区,4,511300 |
| | | 511321,南部县,4,511300 |
| | | 511322,营山县,4,511300 |
| | | 511323,蓬安县,4,511300 |
| | | 511324,仪陇县,4,511300 |
| | | 511325,西充县,4,511300 |
| | | 511381,阆中市,4,511300 |
| | | 511402,东坡区,4,511400 |
| | | 511403,彭山区,4,511400 |
| | | 511421,仁寿县,4,511400 |
| | | 511423,洪雅县,4,511400 |
| | | 511424,丹棱县,4,511400 |
| | | 511425,青神县,4,511400 |
| | | 511502,翠屏区,4,511500 |
| | | 511503,南溪区,4,511500 |
| | | 511504,叙州区,4,511500 |
| | | 511523,江安县,4,511500 |
| | | 511524,长宁县,4,511500 |
| | | 511525,高县,4,511500 |
| | | 511526,珙县,4,511500 |
| | | 511527,筠连县,4,511500 |
| | | 511528,兴文县,4,511500 |
| | | 511529,屏山县,4,511500 |
| | | 511602,广安区,4,511600 |
| | | 511603,前锋区,4,511600 |
| | | 511621,岳池县,4,511600 |
| | | 511622,武胜县,4,511600 |
| | | 511623,邻水县,4,511600 |
| | | 511681,华蓥市,4,511600 |
| | | 511702,通川区,4,511700 |
| | | 511703,达川区,4,511700 |
| | | 511722,宣汉县,4,511700 |
| | | 511723,开江县,4,511700 |
| | | 511724,大竹县,4,511700 |
| | | 511725,渠县,4,511700 |
| | | 511771,达州经济开发区,4,511700 |
| | | 511781,万源市,4,511700 |
| | | 511802,雨城区,4,511800 |
| | | 511803,名山区,4,511800 |
| | | 511822,荥经县,4,511800 |
| | | 511823,汉源县,4,511800 |
| | | 511824,石棉县,4,511800 |
| | | 511825,天全县,4,511800 |
| | | 511826,芦山县,4,511800 |
| | | 511827,宝兴县,4,511800 |
| | | 511902,巴州区,4,511900 |
| | | 511903,恩阳区,4,511900 |
| | | 511921,通江县,4,511900 |
| | | 511922,南江县,4,511900 |
| | | 511923,平昌县,4,511900 |
| | | 511971,巴中经济开发区,4,511900 |
| | | 512002,雁江区,4,512000 |
| | | 512021,安岳县,4,512000 |
| | | 512022,乐至县,4,512000 |
| | | 513201,马尔康市,4,513200 |
| | | 513221,汶川县,4,513200 |
| | | 513222,理县,4,513200 |
| | | 513223,茂县,4,513200 |
| | | 513224,松潘县,4,513200 |
| | | 513225,九寨沟县,4,513200 |
| | | 513226,金川县,4,513200 |
| | | 513227,小金县,4,513200 |
| | | 513228,黑水县,4,513200 |
| | | 513230,壤塘县,4,513200 |
| | | 513231,阿坝县,4,513200 |
| | | 513232,若尔盖县,4,513200 |
| | | 513233,红原县,4,513200 |
| | | 513301,康定市,4,513300 |
| | | 513322,泸定县,4,513300 |
| | | 513323,丹巴县,4,513300 |
| | | 513324,九龙县,4,513300 |
| | | 513325,雅江县,4,513300 |
| | | 513326,道孚县,4,513300 |
| | | 513327,炉霍县,4,513300 |
| | | 513328,甘孜县,4,513300 |
| | | 513329,新龙县,4,513300 |
| | | 513330,德格县,4,513300 |
| | | 513331,白玉县,4,513300 |
| | | 513332,石渠县,4,513300 |
| | | 513333,色达县,4,513300 |
| | | 513334,理塘县,4,513300 |
| | | 513335,巴塘县,4,513300 |
| | | 513336,乡城县,4,513300 |
| | | 513337,稻城县,4,513300 |
| | | 513338,得荣县,4,513300 |
| | | 513401,西昌市,4,513400 |
| | | 513402,会理市,4,513400 |
| | | 513422,木里藏族自治县,4,513400 |
| | | 513423,盐源县,4,513400 |
| | | 513424,德昌县,4,513400 |
| | | 513426,会东县,4,513400 |
| | | 513427,宁南县,4,513400 |
| | | 513428,普格县,4,513400 |
| | | 513429,布拖县,4,513400 |
| | | 513430,金阳县,4,513400 |
| | | 513431,昭觉县,4,513400 |
| | | 513432,喜德县,4,513400 |
| | | 513433,冕宁县,4,513400 |
| | | 513434,越西县,4,513400 |
| | | 513435,甘洛县,4,513400 |
| | | 513436,美姑县,4,513400 |
| | | 513437,雷波县,4,513400 |
| | | 520102,南明区,4,520100 |
| | | 520103,云岩区,4,520100 |
| | | 520111,花溪区,4,520100 |
| | | 520112,乌当区,4,520100 |
| | | 520113,白云区,4,520100 |
| | | 520115,观山湖区,4,520100 |
| | | 520121,开阳县,4,520100 |
| | | 520122,息烽县,4,520100 |
| | | 520123,修文县,4,520100 |
| | | 520181,清镇市,4,520100 |
| | | 520201,钟山区,4,520200 |
| | | 520203,六枝特区,4,520200 |
| | | 520204,水城区,4,520200 |
| | | 520281,盘州市,4,520200 |
| | | 520302,红花岗区,4,520300 |
| | | 520303,汇川区,4,520300 |
| | | 520304,播州区,4,520300 |
| | | 520322,桐梓县,4,520300 |
| | | 520323,绥阳县,4,520300 |
| | | 520324,正安县,4,520300 |
| | | 520325,道真仡佬族苗族自治县,4,520300 |
| | | 520326,务川仡佬族苗族自治县,4,520300 |
| | | 520327,凤冈县,4,520300 |
| | | 520328,湄潭县,4,520300 |
| | | 520329,余庆县,4,520300 |
| | | 520330,习水县,4,520300 |
| | | 520381,赤水市,4,520300 |
| | | 520382,仁怀市,4,520300 |
| | | 520402,西秀区,4,520400 |
| | | 520403,平坝区,4,520400 |
| | | 520422,普定县,4,520400 |
| | | 520423,镇宁布依族苗族自治县,4,520400 |
| | | 520424,关岭布依族苗族自治县,4,520400 |
| | | 520425,紫云苗族布依族自治县,4,520400 |
| | | 520502,七星关区,4,520500 |
| | | 520521,大方县,4,520500 |
| | | 520523,金沙县,4,520500 |
| | | 520524,织金县,4,520500 |
| | | 520525,纳雍县,4,520500 |
| | | 520526,威宁彝族回族苗族自治县,4,520500 |
| | | 520527,赫章县,4,520500 |
| | | 520581,黔西市,4,520500 |
| | | 520602,碧江区,4,520600 |
| | | 520603,万山区,4,520600 |
| | | 520621,江口县,4,520600 |
| | | 520622,玉屏侗族自治县,4,520600 |
| | | 520623,石阡县,4,520600 |
| | | 520624,思南县,4,520600 |
| | | 520625,印江土家族苗族自治县,4,520600 |
| | | 520626,德江县,4,520600 |
| | | 520627,沿河土家族自治县,4,520600 |
| | | 520628,松桃苗族自治县,4,520600 |
| | | 522301,兴义市,4,522300 |
| | | 522302,兴仁市,4,522300 |
| | | 522323,普安县,4,522300 |
| | | 522324,晴隆县,4,522300 |
| | | 522325,贞丰县,4,522300 |
| | | 522326,望谟县,4,522300 |
| | | 522327,册亨县,4,522300 |
| | | 522328,安龙县,4,522300 |
| | | 522601,凯里市,4,522600 |
| | | 522622,黄平县,4,522600 |
| | | 522623,施秉县,4,522600 |
| | | 522624,三穗县,4,522600 |
| | | 522625,镇远县,4,522600 |
| | | 522626,岑巩县,4,522600 |
| | | 522627,天柱县,4,522600 |
| | | 522628,锦屏县,4,522600 |
| | | 522629,剑河县,4,522600 |
| | | 522630,台江县,4,522600 |
| | | 522631,黎平县,4,522600 |
| | | 522632,榕江县,4,522600 |
| | | 522633,从江县,4,522600 |
| | | 522634,雷山县,4,522600 |
| | | 522635,麻江县,4,522600 |
| | | 522636,丹寨县,4,522600 |
| | | 522701,都匀市,4,522700 |
| | | 522702,福泉市,4,522700 |
| | | 522722,荔波县,4,522700 |
| | | 522723,贵定县,4,522700 |
| | | 522725,瓮安县,4,522700 |
| | | 522726,独山县,4,522700 |
| | | 522727,平塘县,4,522700 |
| | | 522728,罗甸县,4,522700 |
| | | 522729,长顺县,4,522700 |
| | | 522730,龙里县,4,522700 |
| | | 522731,惠水县,4,522700 |
| | | 522732,三都水族自治县,4,522700 |
| | | 530102,五华区,4,530100 |
| | | 530103,盘龙区,4,530100 |
| | | 530111,官渡区,4,530100 |
| | | 530112,西山区,4,530100 |
| | | 530113,东川区,4,530100 |
| | | 530114,呈贡区,4,530100 |
| | | 530115,晋宁区,4,530100 |
| | | 530124,富民县,4,530100 |
| | | 530125,宜良县,4,530100 |
| | | 530126,石林彝族自治县,4,530100 |
| | | 530127,嵩明县,4,530100 |
| | | 530128,禄劝彝族苗族自治县,4,530100 |
| | | 530129,寻甸回族彝族自治县,4,530100 |
| | | 530181,安宁市,4,530100 |
| | | 530302,麒麟区,4,530300 |
| | | 530303,沾益区,4,530300 |
| | | 530304,马龙区,4,530300 |
| | | 530322,陆良县,4,530300 |
| | | 530323,师宗县,4,530300 |
| | | 530324,罗平县,4,530300 |
| | | 530325,富源县,4,530300 |
| | | 530326,会泽县,4,530300 |
| | | 530381,宣威市,4,530300 |
| | | 530402,红塔区,4,530400 |
| | | 530403,江川区,4,530400 |
| | | 530423,通海县,4,530400 |
| | | 530424,华宁县,4,530400 |
| | | 530425,易门县,4,530400 |
| | | 530426,峨山彝族自治县,4,530400 |
| | | 530427,新平彝族傣族自治县,4,530400 |
| | | 530428,元江哈尼族彝族傣族自治县,4,530400 |
| | | 530481,澄江市,4,530400 |
| | | 530502,隆阳区,4,530500 |
| | | 530521,施甸县,4,530500 |
| | | 530523,龙陵县,4,530500 |
| | | 530524,昌宁县,4,530500 |
| | | 530581,腾冲市,4,530500 |
| | | 530602,昭阳区,4,530600 |
| | | 530621,鲁甸县,4,530600 |
| | | 530622,巧家县,4,530600 |
| | | 530623,盐津县,4,530600 |
| | | 530624,大关县,4,530600 |
| | | 530625,永善县,4,530600 |
| | | 530626,绥江县,4,530600 |
| | | 530627,镇雄县,4,530600 |
| | | 530628,彝良县,4,530600 |
| | | 530629,威信县,4,530600 |
| | | 530681,水富市,4,530600 |
| | | 530702,古城区,4,530700 |
| | | 530721,玉龙纳西族自治县,4,530700 |
| | | 530722,永胜县,4,530700 |
| | | 530723,华坪县,4,530700 |
| | | 530724,宁蒗彝族自治县,4,530700 |
| | | 530802,思茅区,4,530800 |
| | | 530821,宁洱哈尼族彝族自治县,4,530800 |
| | | 530822,墨江哈尼族自治县,4,530800 |
| | | 530823,景东彝族自治县,4,530800 |
| | | 530824,景谷傣族彝族自治县,4,530800 |
| | | 530825,镇沅彝族哈尼族拉祜族自治县,4,530800 |
| | | 530826,江城哈尼族彝族自治县,4,530800 |
| | | 530827,孟连傣族拉祜族佤族自治县,4,530800 |
| | | 530828,澜沧拉祜族自治县,4,530800 |
| | | 530829,西盟佤族自治县,4,530800 |
| | | 530902,临翔区,4,530900 |
| | | 530921,凤庆县,4,530900 |
| | | 530922,云县,4,530900 |
| | | 530923,永德县,4,530900 |
| | | 530924,镇康县,4,530900 |
| | | 530925,双江拉祜族佤族布朗族傣族自治县,4,530900 |
| | | 530926,耿马傣族佤族自治县,4,530900 |
| | | 530927,沧源佤族自治县,4,530900 |
| | | 532301,楚雄市,4,532300 |
| | | 532302,禄丰市,4,532300 |
| | | 532322,双柏县,4,532300 |
| | | 532323,牟定县,4,532300 |
| | | 532324,南华县,4,532300 |
| | | 532325,姚安县,4,532300 |
| | | 532326,大姚县,4,532300 |
| | | 532327,永仁县,4,532300 |
| | | 532328,元谋县,4,532300 |
| | | 532329,武定县,4,532300 |
| | | 532501,个旧市,4,532500 |
| | | 532502,开远市,4,532500 |
| | | 532503,蒙自市,4,532500 |
| | | 532504,弥勒市,4,532500 |
| | | 532523,屏边苗族自治县,4,532500 |
| | | 532524,建水县,4,532500 |
| | | 532525,石屏县,4,532500 |
| | | 532527,泸西县,4,532500 |
| | | 532528,元阳县,4,532500 |
| | | 532529,红河县,4,532500 |
| | | 532530,金平苗族瑶族傣族自治县,4,532500 |
| | | 532531,绿春县,4,532500 |
| | | 532532,河口瑶族自治县,4,532500 |
| | | 532601,文山市,4,532600 |
| | | 532622,砚山县,4,532600 |
| | | 532623,西畴县,4,532600 |
| | | 532624,麻栗坡县,4,532600 |
| | | 532625,马关县,4,532600 |
| | | 532626,丘北县,4,532600 |
| | | 532627,广南县,4,532600 |
| | | 532628,富宁县,4,532600 |
| | | 532801,景洪市,4,532800 |
| | | 532822,勐海县,4,532800 |
| | | 532823,勐腊县,4,532800 |
| | | 532901,大理市,4,532900 |
| | | 532922,漾濞彝族自治县,4,532900 |
| | | 532923,祥云县,4,532900 |
| | | 532924,宾川县,4,532900 |
| | | 532925,弥渡县,4,532900 |
| | | 532926,南涧彝族自治县,4,532900 |
| | | 532927,巍山彝族回族自治县,4,532900 |
| | | 532928,永平县,4,532900 |
| | | 532929,云龙县,4,532900 |
| | | 532930,洱源县,4,532900 |
| | | 532931,剑川县,4,532900 |
| | | 532932,鹤庆县,4,532900 |
| | | 533102,瑞丽市,4,533100 |
| | | 533103,芒市,4,533100 |
| | | 533122,梁河县,4,533100 |
| | | 533123,盈江县,4,533100 |
| | | 533124,陇川县,4,533100 |
| | | 533301,泸水市,4,533300 |
| | | 533323,福贡县,4,533300 |
| | | 533324,贡山独龙族怒族自治县,4,533300 |
| | | 533325,兰坪白族普米族自治县,4,533300 |
| | | 533401,香格里拉市,4,533400 |
| | | 533422,德钦县,4,533400 |
| | | 533423,维西傈僳族自治县,4,533400 |
| | | 540102,城关区,4,540100 |
| | | 540103,堆龙德庆区,4,540100 |
| | | 540104,达孜区,4,540100 |
| | | 540121,林周县,4,540100 |
| | | 540122,当雄县,4,540100 |
| | | 540123,尼木县,4,540100 |
| | | 540124,曲水县,4,540100 |
| | | 540127,墨竹工卡县,4,540100 |
| | | 540171,格尔木藏青工业园区,4,540100 |
| | | 540172,拉萨经济技术开发区,4,540100 |
| | | 540173,西藏文化旅游创意园区,4,540100 |
| | | 540174,达孜工业园区,4,540100 |
| | | 540202,桑珠孜区,4,540200 |
| | | 540221,南木林县,4,540200 |
| | | 540222,江孜县,4,540200 |
| | | 540223,定日县,4,540200 |
| | | 540224,萨迦县,4,540200 |
| | | 540225,拉孜县,4,540200 |
| | | 540226,昂仁县,4,540200 |
| | | 540227,谢通门县,4,540200 |
| | | 540228,白朗县,4,540200 |
| | | 540229,仁布县,4,540200 |
| | | 540230,康马县,4,540200 |
| | | 540231,定结县,4,540200 |
| | | 540232,仲巴县,4,540200 |
| | | 540233,亚东县,4,540200 |
| | | 540234,吉隆县,4,540200 |
| | | 540235,聂拉木县,4,540200 |
| | | 540236,萨嘎县,4,540200 |
| | | 540237,岗巴县,4,540200 |
| | | 540302,卡若区,4,540300 |
| | | 540321,江达县,4,540300 |
| | | 540322,贡觉县,4,540300 |
| | | 540323,类乌齐县,4,540300 |
| | | 540324,丁青县,4,540300 |
| | | 540325,察雅县,4,540300 |
| | | 540326,八宿县,4,540300 |
| | | 540327,左贡县,4,540300 |
| | | 540328,芒康县,4,540300 |
| | | 540329,洛隆县,4,540300 |
| | | 540330,边坝县,4,540300 |
| | | 540402,巴宜区,4,540400 |
| | | 540421,工布江达县,4,540400 |
| | | 540422,米林县,4,540400 |
| | | 540423,墨脱县,4,540400 |
| | | 540424,波密县,4,540400 |
| | | 540425,察隅县,4,540400 |
| | | 540426,朗县,4,540400 |
| | | 540502,乃东区,4,540500 |
| | | 540521,扎囊县,4,540500 |
| | | 540522,贡嘎县,4,540500 |
| | | 540523,桑日县,4,540500 |
| | | 540524,琼结县,4,540500 |
| | | 540525,曲松县,4,540500 |
| | | 540526,措美县,4,540500 |
| | | 540527,洛扎县,4,540500 |
| | | 540528,加查县,4,540500 |
| | | 540529,隆子县,4,540500 |
| | | 540530,错那县,4,540500 |
| | | 540531,浪卡子县,4,540500 |
| | | 540602,色尼区,4,540600 |
| | | 540621,嘉黎县,4,540600 |
| | | 540622,比如县,4,540600 |
| | | 540623,聂荣县,4,540600 |
| | | 540624,安多县,4,540600 |
| | | 540625,申扎县,4,540600 |
| | | 540626,索县,4,540600 |
| | | 540627,班戈县,4,540600 |
| | | 540628,巴青县,4,540600 |
| | | 540629,尼玛县,4,540600 |
| | | 540630,双湖县,4,540600 |
| | | 542521,普兰县,4,542500 |
| | | 542522,札达县,4,542500 |
| | | 542523,噶尔县,4,542500 |
| | | 542524,日土县,4,542500 |
| | | 542525,革吉县,4,542500 |
| | | 542526,改则县,4,542500 |
| | | 542527,措勤县,4,542500 |
| | | 610102,新城区,4,610100 |
| | | 610103,碑林区,4,610100 |
| | | 610104,莲湖区,4,610100 |
| | | 610111,灞桥区,4,610100 |
| | | 610112,未央区,4,610100 |
| | | 610113,雁塔区,4,610100 |
| | | 610114,阎良区,4,610100 |
| | | 610115,临潼区,4,610100 |
| | | 610116,长安区,4,610100 |
| | | 610117,高陵区,4,610100 |
| | | 610118,鄠邑区,4,610100 |
| | | 610122,蓝田县,4,610100 |
| | | 610124,周至县,4,610100 |
| | | 610202,王益区,4,610200 |
| | | 610203,印台区,4,610200 |
| | | 610204,耀州区,4,610200 |
| | | 610222,宜君县,4,610200 |
| | | 610302,渭滨区,4,610300 |
| | | 610303,金台区,4,610300 |
| | | 610304,陈仓区,4,610300 |
| | | 610305,凤翔区,4,610300 |
| | | 610323,岐山县,4,610300 |
| | | 610324,扶风县,4,610300 |
| | | 610326,眉县,4,610300 |
| | | 610327,陇县,4,610300 |
| | | 610328,千阳县,4,610300 |
| | | 610329,麟游县,4,610300 |
| | | 610330,凤县,4,610300 |
| | | 610331,太白县,4,610300 |
| | | 610402,秦都区,4,610400 |
| | | 610403,杨陵区,4,610400 |
| | | 610404,渭城区,4,610400 |
| | | 610422,三原县,4,610400 |
| | | 610423,泾阳县,4,610400 |
| | | 610424,乾县,4,610400 |
| | | 610425,礼泉县,4,610400 |
| | | 610426,永寿县,4,610400 |
| | | 610428,长武县,4,610400 |
| | | 610429,旬邑县,4,610400 |
| | | 610430,淳化县,4,610400 |
| | | 610431,武功县,4,610400 |
| | | 610481,兴平市,4,610400 |
| | | 610482,彬州市,4,610400 |
| | | 610502,临渭区,4,610500 |
| | | 610503,华州区,4,610500 |
| | | 610522,潼关县,4,610500 |
| | | 610523,大荔县,4,610500 |
| | | 610524,合阳县,4,610500 |
| | | 610525,澄城县,4,610500 |
| | | 610526,蒲城县,4,610500 |
| | | 610527,白水县,4,610500 |
| | | 610528,富平县,4,610500 |
| | | 610581,韩城市,4,610500 |
| | | 610582,华阴市,4,610500 |
| | | 610602,宝塔区,4,610600 |
| | | 610603,安塞区,4,610600 |
| | | 610621,延长县,4,610600 |
| | | 610622,延川县,4,610600 |
| | | 610625,志丹县,4,610600 |
| | | 610626,吴起县,4,610600 |
| | | 610627,甘泉县,4,610600 |
| | | 610628,富县,4,610600 |
| | | 610629,洛川县,4,610600 |
| | | 610630,宜川县,4,610600 |
| | | 610631,黄龙县,4,610600 |
| | | 610632,黄陵县,4,610600 |
| | | 610681,子长市,4,610600 |
| | | 610702,汉台区,4,610700 |
| | | 610703,南郑区,4,610700 |
| | | 610722,城固县,4,610700 |
| | | 610723,洋县,4,610700 |
| | | 610724,西乡县,4,610700 |
| | | 610725,勉县,4,610700 |
| | | 610726,宁强县,4,610700 |
| | | 610727,略阳县,4,610700 |
| | | 610728,镇巴县,4,610700 |
| | | 610729,留坝县,4,610700 |
| | | 610730,佛坪县,4,610700 |
| | | 610802,榆阳区,4,610800 |
| | | 610803,横山区,4,610800 |
| | | 610822,府谷县,4,610800 |
| | | 610824,靖边县,4,610800 |
| | | 610825,定边县,4,610800 |
| | | 610826,绥德县,4,610800 |
| | | 610827,米脂县,4,610800 |
| | | 610828,佳县,4,610800 |
| | | 610829,吴堡县,4,610800 |
| | | 610830,清涧县,4,610800 |
| | | 610831,子洲县,4,610800 |
| | | 610881,神木市,4,610800 |
| | | 610902,汉滨区,4,610900 |
| | | 610921,汉阴县,4,610900 |
| | | 610922,石泉县,4,610900 |
| | | 610923,宁陕县,4,610900 |
| | | 610924,紫阳县,4,610900 |
| | | 610925,岚皋县,4,610900 |
| | | 610926,平利县,4,610900 |
| | | 610927,镇坪县,4,610900 |
| | | 610929,白河县,4,610900 |
| | | 610981,旬阳市,4,610900 |
| | | 611002,商州区,4,611000 |
| | | 611021,洛南县,4,611000 |
| | | 611022,丹凤县,4,611000 |
| | | 611023,商南县,4,611000 |
| | | 611024,山阳县,4,611000 |
| | | 611025,镇安县,4,611000 |
| | | 611026,柞水县,4,611000 |
| | | 620102,城关区,4,620100 |
| | | 620103,七里河区,4,620100 |
| | | 620104,西固区,4,620100 |
| | | 620105,安宁区,4,620100 |
| | | 620111,红古区,4,620100 |
| | | 620121,永登县,4,620100 |
| | | 620122,皋兰县,4,620100 |
| | | 620123,榆中县,4,620100 |
| | | 620171,兰州新区,4,620100 |
| | | 620201,嘉峪关市,4,620200 |
| | | 620302,金川区,4,620300 |
| | | 620321,永昌县,4,620300 |
| | | 620402,白银区,4,620400 |
| | | 620403,平川区,4,620400 |
| | | 620421,靖远县,4,620400 |
| | | 620422,会宁县,4,620400 |
| | | 620423,景泰县,4,620400 |
| | | 620502,秦州区,4,620500 |
| | | 620503,麦积区,4,620500 |
| | | 620521,清水县,4,620500 |
| | | 620522,秦安县,4,620500 |
| | | 620523,甘谷县,4,620500 |
| | | 620524,武山县,4,620500 |
| | | 620525,张家川回族自治县,4,620500 |
| | | 620602,凉州区,4,620600 |
| | | 620621,民勤县,4,620600 |
| | | 620622,古浪县,4,620600 |
| | | 620623,天祝藏族自治县,4,620600 |
| | | 620702,甘州区,4,620700 |
| | | 620721,肃南裕固族自治县,4,620700 |
| | | 620722,民乐县,4,620700 |
| | | 620723,临泽县,4,620700 |
| | | 620724,高台县,4,620700 |
| | | 620725,山丹县,4,620700 |
| | | 620802,崆峒区,4,620800 |
| | | 620821,泾川县,4,620800 |
| | | 620822,灵台县,4,620800 |
| | | 620823,崇信县,4,620800 |
| | | 620825,庄浪县,4,620800 |
| | | 620826,静宁县,4,620800 |
| | | 620881,华亭市,4,620800 |
| | | 620902,肃州区,4,620900 |
| | | 620921,金塔县,4,620900 |
| | | 620922,瓜州县,4,620900 |
| | | 620923,肃北蒙古族自治县,4,620900 |
| | | 620924,阿克塞哈萨克族自治县,4,620900 |
| | | 620981,玉门市,4,620900 |
| | | 620982,敦煌市,4,620900 |
| | | 621002,西峰区,4,621000 |
| | | 621021,庆城县,4,621000 |
| | | 621022,环县,4,621000 |
| | | 621023,华池县,4,621000 |
| | | 621024,合水县,4,621000 |
| | | 621025,正宁县,4,621000 |
| | | 621026,宁县,4,621000 |
| | | 621027,镇原县,4,621000 |
| | | 621102,安定区,4,621100 |
| | | 621121,通渭县,4,621100 |
| | | 621122,陇西县,4,621100 |
| | | 621123,渭源县,4,621100 |
| | | 621124,临洮县,4,621100 |
| | | 621125,漳县,4,621100 |
| | | 621126,岷县,4,621100 |
| | | 621202,武都区,4,621200 |
| | | 621221,成县,4,621200 |
| | | 621222,文县,4,621200 |
| | | 621223,宕昌县,4,621200 |
| | | 621224,康县,4,621200 |
| | | 621225,西和县,4,621200 |
| | | 621226,礼县,4,621200 |
| | | 621227,徽县,4,621200 |
| | | 621228,两当县,4,621200 |
| | | 622901,临夏市,4,622900 |
| | | 622921,临夏县,4,622900 |
| | | 622922,康乐县,4,622900 |
| | | 622923,永靖县,4,622900 |
| | | 622924,广河县,4,622900 |
| | | 622925,和政县,4,622900 |
| | | 622926,东乡族自治县,4,622900 |
| | | 622927,积石山保安族东乡族撒拉族自治县,4,622900 |
| | | 623001,合作市,4,623000 |
| | | 623021,临潭县,4,623000 |
| | | 623022,卓尼县,4,623000 |
| | | 623023,舟曲县,4,623000 |
| | | 623024,迭部县,4,623000 |
| | | 623025,玛曲县,4,623000 |
| | | 623026,碌曲县,4,623000 |
| | | 623027,夏河县,4,623000 |
| | | 630102,城东区,4,630100 |
| | | 630103,城中区,4,630100 |
| | | 630104,城西区,4,630100 |
| | | 630105,城北区,4,630100 |
| | | 630106,湟中区,4,630100 |
| | | 630121,大通回族土族自治县,4,630100 |
| | | 630123,湟源县,4,630100 |
| | | 630202,乐都区,4,630200 |
| | | 630203,平安区,4,630200 |
| | | 630222,民和回族土族自治县,4,630200 |
| | | 630223,互助土族自治县,4,630200 |
| | | 630224,化隆回族自治县,4,630200 |
| | | 630225,循化撒拉族自治县,4,630200 |
| | | 632221,门源回族自治县,4,632200 |
| | | 632222,祁连县,4,632200 |
| | | 632223,海晏县,4,632200 |
| | | 632224,刚察县,4,632200 |
| | | 632301,同仁市,4,632300 |
| | | 632322,尖扎县,4,632300 |
| | | 632323,泽库县,4,632300 |
| | | 632324,河南蒙古族自治县,4,632300 |
| | | 632521,共和县,4,632500 |
| | | 632522,同德县,4,632500 |
| | | 632523,贵德县,4,632500 |
| | | 632524,兴海县,4,632500 |
| | | 632525,贵南县,4,632500 |
| | | 632621,玛沁县,4,632600 |
| | | 632622,班玛县,4,632600 |
| | | 632623,甘德县,4,632600 |
| | | 632624,达日县,4,632600 |
| | | 632625,久治县,4,632600 |
| | | 632626,玛多县,4,632600 |
| | | 632701,玉树市,4,632700 |
| | | 632722,杂多县,4,632700 |
| | | 632723,称多县,4,632700 |
| | | 632724,治多县,4,632700 |
| | | 632725,囊谦县,4,632700 |
| | | 632726,曲麻莱县,4,632700 |
| | | 632801,格尔木市,4,632800 |
| | | 632802,德令哈市,4,632800 |
| | | 632803,茫崖市,4,632800 |
| | | 632821,乌兰县,4,632800 |
| | | 632822,都兰县,4,632800 |
| | | 632823,天峻县,4,632800 |
| | | 632857,大柴旦行政委员会,4,632800 |
| | | 640104,兴庆区,4,640100 |
| | | 640105,西夏区,4,640100 |
| | | 640106,金凤区,4,640100 |
| | | 640121,永宁县,4,640100 |
| | | 640122,贺兰县,4,640100 |
| | | 640181,灵武市,4,640100 |
| | | 640202,大武口区,4,640200 |
| | | 640205,惠农区,4,640200 |
| | | 640221,平罗县,4,640200 |
| | | 640302,利通区,4,640300 |
| | | 640303,红寺堡区,4,640300 |
| | | 640323,盐池县,4,640300 |
| | | 640324,同心县,4,640300 |
| | | 640381,青铜峡市,4,640300 |
| | | 640402,原州区,4,640400 |
| | | 640422,西吉县,4,640400 |
| | | 640423,隆德县,4,640400 |
| | | 640424,泾源县,4,640400 |
| | | 640425,彭阳县,4,640400 |
| | | 640502,沙坡头区,4,640500 |
| | | 640521,中宁县,4,640500 |
| | | 640522,海原县,4,640500 |
| | | 650102,天山区,4,650100 |
| | | 650103,沙依巴克区,4,650100 |
| | | 650104,新市区,4,650100 |
| | | 650105,水磨沟区,4,650100 |
| | | 650106,头屯河区,4,650100 |
| | | 650107,达坂城区,4,650100 |
| | | 650109,米东区,4,650100 |
| | | 650121,乌鲁木齐县,4,650100 |
| | | 650202,独山子区,4,650200 |
| | | 650203,克拉玛依区,4,650200 |
| | | 650204,白碱滩区,4,650200 |
| | | 650205,乌尔禾区,4,650200 |
| | | 650402,高昌区,4,650400 |
| | | 650421,鄯善县,4,650400 |
| | | 650422,托克逊县,4,650400 |
| | | 650502,伊州区,4,650500 |
| | | 650521,巴里坤哈萨克自治县,4,650500 |
| | | 650522,伊吾县,4,650500 |
| | | 652301,昌吉市,4,652300 |
| | | 652302,阜康市,4,652300 |
| | | 652323,呼图壁县,4,652300 |
| | | 652324,玛纳斯县,4,652300 |
| | | 652325,奇台县,4,652300 |
| | | 652327,吉木萨尔县,4,652300 |
| | | 652328,木垒哈萨克自治县,4,652300 |
| | | 652701,博乐市,4,652700 |
| | | 652702,阿拉山口市,4,652700 |
| | | 652722,精河县,4,652700 |
| | | 652723,温泉县,4,652700 |
| | | 652801,库尔勒市,4,652800 |
| | | 652822,轮台县,4,652800 |
| | | 652823,尉犁县,4,652800 |
| | | 652824,若羌县,4,652800 |
| | | 652825,且末县,4,652800 |
| | | 652826,焉耆回族自治县,4,652800 |
| | | 652827,和静县,4,652800 |
| | | 652828,和硕县,4,652800 |
| | | 652829,博湖县,4,652800 |
| | | 652871,库尔勒经济技术开发区,4,652800 |
| | | 652901,阿克苏市,4,652900 |
| | | 652902,库车市,4,652900 |
| | | 652922,温宿县,4,652900 |
| | | 652924,沙雅县,4,652900 |
| | | 652925,新和县,4,652900 |
| | | 652926,拜城县,4,652900 |
| | | 652927,乌什县,4,652900 |
| | | 652928,阿瓦提县,4,652900 |
| | | 652929,柯坪县,4,652900 |
| | | 653001,阿图什市,4,653000 |
| | | 653022,阿克陶县,4,653000 |
| | | 653023,阿合奇县,4,653000 |
| | | 653024,乌恰县,4,653000 |
| | | 653101,喀什市,4,653100 |
| | | 653121,疏附县,4,653100 |
| | | 653122,疏勒县,4,653100 |
| | | 653123,英吉沙县,4,653100 |
| | | 653124,泽普县,4,653100 |
| | | 653125,莎车县,4,653100 |
| | | 653126,叶城县,4,653100 |
| | | 653127,麦盖提县,4,653100 |
| | | 653128,岳普湖县,4,653100 |
| | | 653129,伽师县,4,653100 |
| | | 653130,巴楚县,4,653100 |
| | | 653131,塔什库尔干塔吉克自治县,4,653100 |
| | | 653201,和田市,4,653200 |
| | | 653221,和田县,4,653200 |
| | | 653222,墨玉县,4,653200 |
| | | 653223,皮山县,4,653200 |
| | | 653224,洛浦县,4,653200 |
| | | 653225,策勒县,4,653200 |
| | | 653226,于田县,4,653200 |
| | | 653227,民丰县,4,653200 |
| | | 654002,伊宁市,4,654000 |
| | | 654003,奎屯市,4,654000 |
| | | 654004,霍尔果斯市,4,654000 |
| | | 654021,伊宁县,4,654000 |
| | | 654022,察布查尔锡伯自治县,4,654000 |
| | | 654023,霍城县,4,654000 |
| | | 654024,巩留县,4,654000 |
| | | 654025,新源县,4,654000 |
| | | 654026,昭苏县,4,654000 |
| | | 654027,特克斯县,4,654000 |
| | | 654028,尼勒克县,4,654000 |
| | | 654201,塔城市,4,654200 |
| | | 654202,乌苏市,4,654200 |
| | | 654203,沙湾市,4,654200 |
| | | 654221,额敏县,4,654200 |
| | | 654224,托里县,4,654200 |
| | | 654225,裕民县,4,654200 |
| | | 654226,和布克赛尔蒙古自治县,4,654200 |
| | | 654301,阿勒泰市,4,654300 |
| | | 654321,布尔津县,4,654300 |
| | | 654322,富蕴县,4,654300 |
| | | 654323,福海县,4,654300 |
| | | 654324,哈巴河县,4,654300 |
| | | 654325,青河县,4,654300 |
| | | 654326,吉木乃县,4,654300 |
| | | 659001,石河子市,4,659000 |
| | | 659002,阿拉尔市,4,659000 |
| | | 659003,图木舒克市,4,659000 |
| | | 659004,五家渠市,4,659000 |
| | | 659005,北屯市,4,659000 |
| | | 659006,铁门关市,4,659000 |
| | | 659007,双河市,4,659000 |
| | | 659008,可克达拉市,4,659000 |
| | | 659009,昆玉市,4,659000 |
| | | 659010,胡杨河市,4,659000 |
| | | 659011,新星市,4,659000 |
对比新文件 |
| | |
| | | package com.iailab.framework.ip.core.utils; |
| | | |
| | | |
| | | import com.iailab.framework.ip.core.Area; |
| | | import com.iailab.framework.ip.core.enums.AreaTypeEnum; |
| | | import org.junit.jupiter.api.Test; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | |
| | | /** |
| | | * {@link AreaUtils} 的单元测试 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | public class AreaUtilsTest { |
| | | |
| | | @Test |
| | | public void testGetArea() { |
| | | // 调用:北京 |
| | | Area area = AreaUtils.getArea(110100); |
| | | // 断言 |
| | | assertEquals(area.getId(), 110100); |
| | | assertEquals(area.getName(), "北京市"); |
| | | assertEquals(area.getType(), AreaTypeEnum.CITY.getType()); |
| | | assertEquals(area.getParent().getId(), 110000); |
| | | assertEquals(area.getChildren().size(), 16); |
| | | } |
| | | |
| | | @Test |
| | | public void testFormat() { |
| | | assertEquals(AreaUtils.format(110105), "北京 北京市 朝阳区"); |
| | | assertEquals(AreaUtils.format(1), "中国"); |
| | | assertEquals(AreaUtils.format(2), "蒙古"); |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.iailab.framework.ip.core.utils; |
| | | |
| | | import com.iailab.framework.ip.core.Area; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.lionsoul.ip2region.xdb.Searcher; |
| | | |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | |
| | | /** |
| | | * {@link IPUtils} 的单元测试 |
| | | * |
| | | * @author wanglhup |
| | | */ |
| | | public class IPUtilsTest { |
| | | |
| | | @Test |
| | | public void testGetAreaId_string() { |
| | | // 120.202.4.0|120.202.4.255|420600 |
| | | Integer areaId = IPUtils.getAreaId("120.202.4.50"); |
| | | assertEquals(420600, areaId); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetAreaId_long() throws Exception { |
| | | // 120.203.123.0|120.203.133.255|360900 |
| | | long ip = Searcher.checkIP("120.203.123.250"); |
| | | Integer areaId = IPUtils.getAreaId(ip); |
| | | assertEquals(360900, areaId); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetArea_string() { |
| | | // 120.202.4.0|120.202.4.255|420600 |
| | | Area area = IPUtils.getArea("120.202.4.50"); |
| | | assertEquals("襄阳市", area.getName()); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetArea_long() throws Exception { |
| | | // 120.203.123.0|120.203.133.255|360900 |
| | | long ip = Searcher.checkIP("120.203.123.252"); |
| | | Area area = IPUtils.getArea(ip); |
| | | assertEquals("宜春市", area.getName()); |
| | | } |
| | | |
| | | } |