无锡网站建设哪家公司好,企业所得税优惠政策2021年计算,怎么在百度建设网站,WordPress 发表文章apiGitEgg框架集成weixin-java-miniapp工具包以实现微信小程序相关接口调用功能#xff0c;weixin-java-miniapp底层支持多租户扩展。每个小程序都有唯一的appid#xff0c;weixin-java-miniapp的多租户实现并不是以租户标识TenantId来区分的#xff0c;而是在接口调用时#… GitEgg框架集成weixin-java-miniapp工具包以实现微信小程序相关接口调用功能weixin-java-miniapp底层支持多租户扩展。每个小程序都有唯一的appidweixin-java-miniapp的多租户实现并不是以租户标识TenantId来区分的而是在接口调用时传入appid动态切换ThreadLocal的appid来实现多租户的。并且其多个微信小程序的配置都是在配置yml文件中的在实际业务运营过程中如果需要新增多租户小程序就修改配置文件显然是不合适的。 现在我们需要结合weixin-java-miniapp的多租户实现整合到我们的框架中使多租户可通过系统配置界面来新增多租户小程序。前面我们讲了如何集成以及如何使用weixin-java-miniapp实现微信授权登录及账号绑定等现在只需要在原来的基础上增加数据配置存储在服务启动时由原先的读取配置文件加载相应的微信小程序接口实例修改为可以通过读取配置文件和读取缓存配置来生成相应的微信小程序接口实例。
一、新增微信小程序配置界面
1. 微信小程序配置数据库设计 在数据库设计的时候我们需要知道微信小程序授权时哪些字段需要配置是可选字段还是必填字段这里我们通过weixin-java-miniapp的springboot工程配置文件可知所需字段有
# 公众号配置(必填)
wx.miniapp.appid appId
wx.miniapp.secret secret
wx.miniapp.token token
wx.miniapp.aesKey aesKey
wx.miniapp.msgDataFormat msgDataFormat # 消息格式XML或者JSON.
# 存储配置redis(可选)
# 注意: 指定redis.host值后不会使用容器注入的redis连接(JedisPool)
wx.miniapp.config-storage.type Jedis # 配置类型: Memory(默认), Jedis, RedisTemplate
wx.miniapp.config-storage.key-prefix wa # 相关redis前缀配置: wa(默认)
wx.miniapp.config-storage.redis.host 127.0.0.1
wx.miniapp.config-storage.redis.port 6379
# http客户端配置
wx.miniapp.config-storage.http-client-typeHttpClient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp
wx.miniapp.config-storage.http-proxy-host
wx.miniapp.config-storage.http-proxy-port
wx.miniapp.config-storage.http-proxy-username
wx.miniapp.config-storage.http-proxy-password根据我们的设计配置文件中需要增加租户字段我们需要兼容即使用配置文件来配置微信小程序又可以使用配置界面将微信小程序配置信息配置到数据库中同时增加md5字段配置用于在读取配置时比较配置信息是否有更改。所以保存微信小程序配置的数据库设计如下
CREATE TABLE t_wechat_miniapp (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键,tenant_id bigint(20) NOT NULL DEFAULT 0 COMMENT 租户id,miniapp_name varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 微信小程序名称,appid varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 微信小程序appid,secret varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 微信小程序secret,token varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 微信小程序token,aes_key varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 微信小程序aesKey,msg_data_format varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 消息格式XML或者JSON,storage_type varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 配置类型: Memory(默认), Jedis, RedisTemplate,key_prefix varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 相关redis前缀配置: wa(默认),redis_host varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT Redis服务器地址,redis_port int(11) NULL DEFAULT NULL COMMENT Redis服务器端口,http_client_type varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT http客户端类型: HttpClient(默认), OkHttp, JoddHttp,http_proxy_host varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT http_proxy_host,http_proxy_port varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT http_proxy_port,http_proxy_username varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT http_proxy_username,http_proxy_password varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT http_proxy_password,status varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 1 COMMENT 状态 1有效 0禁用,md5 varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT MD5,comments varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 描述,create_time datetime(0) NULL DEFAULT NULL COMMENT 创建时间,creator bigint(20) NULL DEFAULT NULL COMMENT 创建者,update_time datetime(0) NULL DEFAULT NULL COMMENT 更新时间,operator bigint(20) NULL DEFAULT NULL COMMENT 更新者,del_flag tinyint(2) NOT NULL DEFAULT 0 COMMENT 是否删除,PRIMARY KEY (id) USING BTREE
) ENGINE InnoDB AUTO_INCREMENT 1 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 微信小程序配置 ROW_FORMAT DYNAMIC;
2. 通过代码生成器生成微信小程序配置的增删查改代码 通过代码生成器根据新设计的表进行CRUD代码生成详细步骤不再赘述前面有详细讲解如何根据数据库表设计生成前后端代码。只是这里需要增加业务逻辑处理以及更新到缓存配置。
新增时将配置信息添加到Redis并且需要根据系统是否开启多租户来判断生成缓存key /*** 创建微信小程序配置* param miniapp* return*/Overridepublic boolean createMiniapp(CreateMiniappDTO miniapp) {Miniapp miniappEntity BeanCopierUtils.copyByClass(miniapp, Miniapp.class);try {String miniappEntityStr JsonUtils.objToJson(miniappEntity);miniappEntity.setMd5(SecureUtil.md5(miniappEntityStr));} catch (Exception e) {log.error(创建微信小程序配置时md5加密失败:{}, e);throw new BusinessException(创建微信小程序配置时md5加密失败: e);}boolean result this.save(miniappEntity);if (result){// 更新到缓存Miniapp miniappEntityLocal this.getById(miniappEntity.getId());MiniappDTO miniappDTO BeanCopierUtils.copyByClass(miniappEntityLocal, MiniappDTO.class);this.addOrUpdateMiniappCache(miniappDTO);}return result;}编辑时需要更新Redis配置信息因为会有key也同时修改的情况所以需要先删除旧的配置信息再新增新的配置信息 /*** 更新微信小程序配置* param miniapp* return*/Overridepublic boolean updateMiniapp(UpdateMiniappDTO miniapp) {Miniapp miniappEntity BeanCopierUtils.copyByClass(miniapp, Miniapp.class);Miniapp miniappEntityOld this.getById(miniappEntity.getId());try {String miniappEntityStr JsonUtils.objToJson(miniappEntity);miniappEntity.setMd5(SecureUtil.md5(miniappEntityStr));} catch (Exception e) {log.error(创建微信小程序配置时md5加密失败:{}, e);throw new BusinessException(创建微信小程序配置时md5加密失败: e);}boolean result this.updateById(miniappEntity);if (result){// 把旧的删掉MiniappDTO miniappDTOOld BeanCopierUtils.copyByClass(miniappEntityOld, MiniappDTO.class);this.deleteMiniappCache(miniappDTOOld);// 更新到缓存Miniapp miniappEntityLocal this.getById(miniappEntity.getId());MiniappDTO miniappDTO BeanCopierUtils.copyByClass(miniappEntityLocal, MiniappDTO.class);this.addOrUpdateMiniappCache(miniappDTO);}return result;}删除时直接根据条件生成缓存key然后进行删除即可 /*** 删除微信小程序配置* param miniappId* return*/Overridepublic boolean deleteMiniapp(Long miniappId) {// 从缓存删除Miniapp miniappEntity this.getById(miniappId);MiniappDTO miniappDTO BeanCopierUtils.copyByClass(miniappEntity, MiniappDTO.class);this.deleteMiniappCache(miniappDTO);// 从数据库中删除boolean result this.removeById(miniappId);return result;}新增/更新缓存的公共方法 private void addOrUpdateMiniappCache(MiniappDTO miniappDTO) {try {String redisKey MiniappConstant.WX_MINIAPP_CONFIG_KEY;if (enable) {redisKey MiniappConstant.WX_MINIAPP_TENANT_CONFIG_KEY miniappDTO.getAppid();}redisTemplate.opsForHash().put(redisKey, miniappDTO.getTenantId().toString(), JsonUtils.objToJson(miniappDTO));// wxMaService增加configthis.addConfig(miniappDTO);} catch (Exception e) {log.error(初始化微信小程序配置失败{} , e);}}删除缓存的公共方法 private void deleteMiniappCache(MiniappDTO miniappDTO) {try {String redisKey MiniappConstant.WX_MINIAPP_CONFIG_KEY;if (enable) {redisKey MiniappConstant.WX_MINIAPP_TENANT_CONFIG_KEY miniappDTO.getAppid();}redisTemplate.opsForHash().delete(redisKey, miniappDTO.getTenantId().toString(), JsonUtils.objToJson(miniappDTO));// wxMaService删除configthis.removeConfig(miniappDTO);} catch (Exception e) {log.error(初始化微信小程序配置失败{} , e);}}3. 修改相关配置文件使微信小程序配置既支持配置文件又支持数据库配置
新增GitEggWxMaRedissonConfigImpl类继承自WxMaRedissonConfigImpl增加我们需要的租户配置字段configKey、tenantId、md5。
/*** author GitEgg* date 2023/7/21*/
public class GitEggWxMaRedissonConfigImpl extends WxMaRedissonConfigImpl {protected String configKey;protected String tenantId;protected String md5;public GitEggWxMaRedissonConfigImpl(NonNull RedissonClient redissonClient, String keyPrefix) {super(redissonClient, keyPrefix);}public GitEggWxMaRedissonConfigImpl(NonNull RedissonClient redissonClient) {super(redissonClient);}
......
}修改WxMaProperties类增加我们需要的字段tenantId因为configKey和md5是系统生成的只有动态可配置时才会用到这几个字段去判断这里如果是配置文件配置修改后生效必须重启系统所以这里不需要这几个字段。
Data
ConfigurationProperties(prefix wx.miniapp)
public class WxMaProperties {private ListConfig configs;Datapublic static class Config {/*** 租户*/private Long tenantId;/*** 设置微信小程序的appid*/private String appid;/*** 设置微信小程序的Secret*/private String secret;/*** 设置微信小程序消息服务器配置的token*/private String token;/*** 设置微信小程序消息服务器配置的EncodingAESKey*/private String aesKey;/*** 消息格式XML或者JSON*/private String msgDataFormat;}}修改WxMaConfiguration类我们使用自己定义的缓存方式和Config类进行相关操作,这里的缓存我们使用Redisson。 Beanpublic WxMaService wxMaService() {ListWxMaProperties.Config configs this.properties.getConfigs();//已添加缓存配置如果配置文件没有那么在缓存新增时仍然可以setConfigs
// if (configs null) {
// throw new WxRuntimeException(大哥拜托先看下项目首页的说明readme文件添加下相关配置注意别配错了);
// }WxMaService maService new WxMaServiceImpl();if (null ! configs){maService.setMultiConfigs(configs.stream().map(a - {
// WxMaDefaultConfigImpl config new WxMaDefaultConfigImpl();
// WxMaDefaultConfigImpl config new WxMaRedisConfigImpl(new JedisPool());GitEggWxMaRedissonConfigImpl config new GitEggWxMaRedissonConfigImpl(redissonClient);// 使用上面的配置时需要同时引入jedis-lock的依赖否则会报类无法找到的异常config.setTenantId(null ! a.getTenantId() ? a.getTenantId().toString() : AuthConstant.DEFAULT_TENANT_ID.toString());config.setConfigKey(config.getTenantId() StrPool.UNDERLINE a.getAppid());config.setAppid(a.getAppid());config.setSecret(a.getSecret());config.setToken(a.getToken());config.setAesKey(a.getAesKey());config.setMsgDataFormat(a.getMsgDataFormat());return config;}).collect(Collectors.toMap( GitEggWxMaRedissonConfigImpl::getConfigKey, a - a, (o, n) - o)));}return maService;}二、服务启动时加载微信小程序配置信息
1. 新增加载方法服务启动时加载配置数据需要排除多租户插件之所以在启动时加载配置信息到缓存是因为配置的微服务和小程序相关功能的服务不是同一个服务所以将缓存作为相关配置的存储。
MiniappMapper中新增initMiniappList数据库查询方法一定要加InterceptorIgnore(tenantLine “true”)注解表示此查询不需要多租户控制在服务启动时不区分租户加载所有配置。 /*** 排除多租户插件查询微信配置列表* param miniappDTO* return*/InterceptorIgnore(tenantLine true)ListMiniappDTO initMiniappList(Param(miniapp) QueryMiniappDTO miniappDTO);!-- 不区分租户查询微信小程序配置信息 --select idgetMiniapp resultTypecom.gitegg.boot.extension.wx.miniapp.dto.MiniappDTO parameterTypecom.gitegg.boot.extension.wx.miniapp.dto.QueryMiniappDTOSELECTinclude refidBase_Column_List/FROM t_wechat_miniappWHERE del_flag 0if testminiapp.miniappName ! null and miniapp.miniappName ! AND miniapp_name #{miniapp.miniappName}/ifif testminiapp.appid ! null and miniapp.appid ! AND appid #{miniapp.appid}/ifif testminiapp.secret ! null and miniapp.secret ! AND secret #{miniapp.secret}/ifif testminiapp.status ! null and miniapp.status ! AND status #{miniapp.status}/ifORDER BY id DESC/selectMiniappServiceImpl中新增initMiniappList接口的实现方法缓存配置的增删查改方法也在此类中实现这里不再赘述更多了解可以查看框架代码。 /*** 初始化微信小程序配置表列表* return*/Overridepublic void initMiniappList() {QueryMiniappDTO miniappDTO new QueryMiniappDTO();miniappDTO.setStatus(String.valueOf(GitEggConstant.ENABLE));// 这里初始化所有的配置不再只初始化已启用的配置ListMiniappDTO miniappInfoList miniappMapper.initMiniappList(miniappDTO);// 判断是否开启了租户模式如果开启了那么需要按租户进行分类存储if (enable) {MapString, ListMiniappDTO miniappListMap miniappInfoList.stream().collect(Collectors.groupingBy(MiniappDTO::getAppid));miniappListMap.forEach((key, value) - {String redisKey MiniappConstant.WX_MINIAPP_TENANT_CONFIG_KEY key;redisTemplate.delete(redisKey);addMiniapp(redisKey, value);});} else {redisTemplate.delete(MiniappConstant.WX_MINIAPP_CONFIG_KEY);addMiniapp(MiniappConstant.WX_MINIAPP_CONFIG_KEY, miniappInfoList);}}在InitExtensionCacheRunner系统配置加载类中新增initMiniappList的调用
/*** 容器启动完成加载扩展信息数据到缓存* author GitEgg*/
Slf4j
RequiredArgsConstructor(onConstructor_ Autowired)
Component
public class InitExtensionCacheRunner implements CommandLineRunner {private final IJustAuthConfigService justAuthConfigService;private final IJustAuthSourceService justAuthSourceService;private final IMailChannelService mailChannelService;private final IMiniappService miniappService;Overridepublic void run(String... args) {log.info(InitExtensionCacheRunner running);// 初始化第三方登录主配置justAuthConfigService.initJustAuthConfigList();// 初始化第三方登录 第三方配置justAuthSourceService.initJustAuthSourceList();// 初始化邮件配置信息mailChannelService.initMailChannelList();// 初始化微信配置信息miniappService.initMiniappList();}
}2. 实现动态选择某个租户微信小程序接口的方法我们需要在保证原先读取配置文件的方式仍然可用的基础上扩展读取数据库缓存配置信息所以在接口实现时需要充分考虑原先配置方式可用。
通过appid获取组装后的key值在WxMaService中存储着默认以appid为key值的配置configMap这里我们将key值修改为tenantId_appid的格式作为多租户的扩展同时在获取配置信息时也需要传入多租户信息。如果前端传了租户那么先使用前端的租户如果没有传租户那么从系统中查询租户从缓存获取配置对象如果md5配置和系统配置不一样那么需要重新add缓存配置中没有也需要直接返回因为有可能是配置文件配置的取缓存中所有appid的配置租户如果存在多个租户那么提示错误让前端选择租户如果只有一个租户那么返回 /*** 通过appid获取appid忽略租户插件* param miniappId* return*/Overridepublic String getMiniappId(String miniappId) {if (enable) {// 如果前端传了租户那么先使用前端的租户如果没有传租户那么从系统中查询租户String tenantId GitEggAuthUtils.getTenantId();if (!StringUtils.isEmpty(tenantId)){String miniappStr (String) redisTemplate.opsForHash().get(MiniappConstant.WX_MINIAPP_TENANT_CONFIG_KEY miniappId, tenantId);if (!StringUtils.isEmpty(miniappStr)){// 转为系统配置对象try {// 从缓存获取配置对象如果md5配置和系统配置不一样那么需要重新addMiniappDTO miniappDTO JsonUtils.jsonToPojo(miniappStr, MiniappDTO.class);return this.ifConfig(miniappDTO);} catch (Exception e) {log.error(获取微信小程序配置时发生异常{}, e);throw new BusinessException(获取微信小程序配置时发生异常。);}}// 缓存配置中没有也需要直接返回因为有可能是配置文件配置的return tenantId StrPool.UNDERLINE miniappId;} else {String redisKey MiniappConstant.WX_MINIAPP_TENANT_CONFIG_KEY miniappId;// 取缓存中所有appid的配置租户如果存在多个租户那么提示错误让前端选择租户如果只有一个租户那么返回ListObject values redisTemplate.opsForHash().values(redisKey);if (!CollectionUtils.isEmpty(values)){if (values.size() GitEggConstant.Number.ONE){throw new BusinessException(此小程序配置在多个租户下请选择所需要操作的租户。);}String miniappConfig (String) values.stream().findFirst().orElse(null);try {MiniappDTO miniappConfigDTO JsonUtils.jsonToPojo(miniappConfig, MiniappDTO.class);return this.ifConfig(miniappConfigDTO);} catch (Exception e) {log.error(获取缓存小程序配置失败:{}, e);throw new BusinessException(小程序已被禁用请联系管理员);}}else{return AuthConstant.DEFAULT_TENANT_ID StrPool.UNDERLINE miniappId;}}} else {return AuthConstant.DEFAULT_TENANT_ID StrPool.UNDERLINE miniappId;}}3. 修改原先的切换租户方法调用在WxMaUserController中将原来的wxMaService.switchover(appid)修改为我们自己的实现miniappService.switchover(appid)其它有切换租户调用的都改为此方法。 if (!miniappService.switchover(appid)) {throw new IllegalArgumentException(String.format(未找到对应appid[%s]的配置请核实, appid));}4. 微信小程序前端代码不需要修改还是按照前面章节的说明进行调用即可。在请求中加入appid在请求头中加入租户id。
import request from /common/utils/requestconst wechatLoginApi {Login: /extension/wx/user/
}export default wechatLoginApi/*** 微信登录* param {Object} appId* param {Object} parameter*/
export function wechatLogin (appId, parameter) {return request({url: wechatLoginApi.Login appId /login,method: get,params: parameter})
}/*** 获取微信信息* param {Object} appId* param {Object} parameter*/
export function wechatInfo (appId, parameter) {return request({url: wechatLoginApi.Login appId /info,method: get,params: parameter})
}/*** 获取手机号* param {Object} appId* param {Object} parameter*/
export function wechatPhone (appId, parameter) {return request({url: wechatLoginApi.Login appId /phone,method: get,params: parameter})
}在修改配置时一定需要注意权限问题一般情况下在不同的租户下不允许配置相同的微信小程序因为appid是唯一的在发布微信小程序后微信小程序是唯一的。当然也有特殊的情况比如同一个小程序作为多个租户相同的商户管理端那么在此时需要让用户在前端选择输入租户标识以确定登录用户属于那个租户即多个租户共用同一个微信小程序。
GitEgg-Cloud是一款基于SpringCloud整合搭建的企业级微服务应用开发框架开源项目地址:
Gitee: https://gitee.com/wmz1930/GitEgg
GitHub: https://github.com/wmz1930/GitEgg 文章转载自: http://www.morning.sgtq.cn.gov.cn.sgtq.cn http://www.morning.sqhlx.cn.gov.cn.sqhlx.cn http://www.morning.pbzgj.cn.gov.cn.pbzgj.cn http://www.morning.fksyq.cn.gov.cn.fksyq.cn http://www.morning.lsgsn.cn.gov.cn.lsgsn.cn http://www.morning.qkdbz.cn.gov.cn.qkdbz.cn http://www.morning.wyrsn.cn.gov.cn.wyrsn.cn http://www.morning.xwzsq.cn.gov.cn.xwzsq.cn http://www.morning.krjyq.cn.gov.cn.krjyq.cn http://www.morning.fnjrh.cn.gov.cn.fnjrh.cn http://www.morning.rhjhy.cn.gov.cn.rhjhy.cn http://www.morning.jgmlb.cn.gov.cn.jgmlb.cn http://www.morning.rszyf.cn.gov.cn.rszyf.cn http://www.morning.trwkz.cn.gov.cn.trwkz.cn http://www.morning.wjjxr.cn.gov.cn.wjjxr.cn http://www.morning.pjjkz.cn.gov.cn.pjjkz.cn http://www.morning.kkwgg.cn.gov.cn.kkwgg.cn http://www.morning.kflzy.cn.gov.cn.kflzy.cn http://www.morning.ydfr.cn.gov.cn.ydfr.cn http://www.morning.xfyjn.cn.gov.cn.xfyjn.cn http://www.morning.kpxzq.cn.gov.cn.kpxzq.cn http://www.morning.qnkqk.cn.gov.cn.qnkqk.cn http://www.morning.zylzk.cn.gov.cn.zylzk.cn http://www.morning.kpxnz.cn.gov.cn.kpxnz.cn http://www.morning.pjtnk.cn.gov.cn.pjtnk.cn http://www.morning.clbsd.cn.gov.cn.clbsd.cn http://www.morning.xstfp.cn.gov.cn.xstfp.cn http://www.morning.zgnng.cn.gov.cn.zgnng.cn http://www.morning.jkzq.cn.gov.cn.jkzq.cn http://www.morning.fosfox.com.gov.cn.fosfox.com http://www.morning.nrxsl.cn.gov.cn.nrxsl.cn http://www.morning.zpyh.cn.gov.cn.zpyh.cn http://www.morning.dwgcx.cn.gov.cn.dwgcx.cn http://www.morning.nmkbl.cn.gov.cn.nmkbl.cn http://www.morning.hqjtp.cn.gov.cn.hqjtp.cn http://www.morning.gwxsk.cn.gov.cn.gwxsk.cn http://www.morning.rbhqz.cn.gov.cn.rbhqz.cn http://www.morning.gpfuxiu.cn.gov.cn.gpfuxiu.cn http://www.morning.lqpzb.cn.gov.cn.lqpzb.cn http://www.morning.dkzrs.cn.gov.cn.dkzrs.cn http://www.morning.wrlff.cn.gov.cn.wrlff.cn http://www.morning.rmltt.cn.gov.cn.rmltt.cn http://www.morning.dschz.cn.gov.cn.dschz.cn http://www.morning.zlgr.cn.gov.cn.zlgr.cn http://www.morning.rmdsd.cn.gov.cn.rmdsd.cn http://www.morning.mjtgt.cn.gov.cn.mjtgt.cn http://www.morning.gbqgr.cn.gov.cn.gbqgr.cn http://www.morning.flfdm.cn.gov.cn.flfdm.cn http://www.morning.tdwjj.cn.gov.cn.tdwjj.cn http://www.morning.joinyun.com.gov.cn.joinyun.com http://www.morning.tjkth.cn.gov.cn.tjkth.cn http://www.morning.qngcq.cn.gov.cn.qngcq.cn http://www.morning.wslr.cn.gov.cn.wslr.cn http://www.morning.dhmll.cn.gov.cn.dhmll.cn http://www.morning.rhmt.cn.gov.cn.rhmt.cn http://www.morning.bswnf.cn.gov.cn.bswnf.cn http://www.morning.cbchz.cn.gov.cn.cbchz.cn http://www.morning.smspc.cn.gov.cn.smspc.cn http://www.morning.mrqwy.cn.gov.cn.mrqwy.cn http://www.morning.zdqsc.cn.gov.cn.zdqsc.cn http://www.morning.fjfjm.cn.gov.cn.fjfjm.cn http://www.morning.grryh.cn.gov.cn.grryh.cn http://www.morning.sqskm.cn.gov.cn.sqskm.cn http://www.morning.yrmpz.cn.gov.cn.yrmpz.cn http://www.morning.plchy.cn.gov.cn.plchy.cn http://www.morning.ryxdr.cn.gov.cn.ryxdr.cn http://www.morning.kqqk.cn.gov.cn.kqqk.cn http://www.morning.ygqhd.cn.gov.cn.ygqhd.cn http://www.morning.knqzd.cn.gov.cn.knqzd.cn http://www.morning.gcszn.cn.gov.cn.gcszn.cn http://www.morning.llcsd.cn.gov.cn.llcsd.cn http://www.morning.paxkhqq.cn.gov.cn.paxkhqq.cn http://www.morning.prhfc.cn.gov.cn.prhfc.cn http://www.morning.rmxwm.cn.gov.cn.rmxwm.cn http://www.morning.qfbzj.cn.gov.cn.qfbzj.cn http://www.morning.kxbry.cn.gov.cn.kxbry.cn http://www.morning.qrsm.cn.gov.cn.qrsm.cn http://www.morning.pnmnl.cn.gov.cn.pnmnl.cn http://www.morning.ksqzd.cn.gov.cn.ksqzd.cn http://www.morning.jrkzk.cn.gov.cn.jrkzk.cn