梅州做网站设计公司,seo外包公司怎么样,上海装修公司排名榜十大品牌,展厅装修设计这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r
员工信息-删除修改
前面我们已经实现了员工信息的条件分页查询以及新增操作。 关于员工管理的功能#xff0c;还有两个需要实现#xff1a; 删除员工 修改员工 除了员工管理的功能之外#x… 这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r
员工信息-删除修改
前面我们已经实现了员工信息的条件分页查询以及新增操作。 关于员工管理的功能还有两个需要实现 删除员工 修改员工 除了员工管理的功能之外我们还要再完成员工信息统计的功能开发。 首先我们先完成 删除员工 的功能开发再完成 修改员工 的功能开发。再来完成员工信息统计的接口开发 。 综上所述我们今天的课程内容包含以下四个部分 删除员工 修改员工 异常处理 员工信息统计 1. 删除员工
3.3.1 需求 当我们勾选列表前面的复选框然后点击 批量删除 按钮就可以将这一批次的员工信息删除掉了。也可以只勾选一个复选框仅删除一个员工信息。
问题我们需要开发两个功能接口吗一个删除单个员工一个删除多个员工
答案不需要。 只需要开发一个功能接口即可删除多个员工包含只删除一个员工 3.3.2 接口文档
删除员工 基本信息 请求路径/emps 请求方式DELETE 接口描述该接口用于批量删除员工的数据信息 请求参数 参数格式查询参数 参数说明 参数名类型示例是否必须备注ids数组 array1,2,3必须员工的id数组请求参数样例 /emps?ids1,2,3 响应数据 参数格式application/json 参数说明 参数名类型是否必须备注codenumber必须响应码1 代表成功0 代表失败msgstring非必须提示信息dataobject非必须返回的数据响应数据样例 {code:1,msg:success,data:null
}
3.3.3 思路分析 3.3.4 功能开发
3.3.4.1 Controller接收参数
在 EmpController 中增加如下方法 delete 来执行批量删除员工的操作。
方式一在Controller方法中通过数组来接收
多个参数默认可以将其封装到一个数组中需要保证前端传递的参数名 与 方法形参名称保持一致。
/**
* 批量删除员工
*/
DeleteMapping
public Result delete(Integer[] ids){log.info(批量删除部门: ids{} , Arrays.asList(ids));return Result.success();
} 方式二在Controller方法中通过集合来接收
也可以将其封装到一个ListInteger 集合中如果要将其封装到一个集合中需要在集合前面加上 RequestParam 注解。
/**
* 批量删除员工
*/
DeleteMapping
public Result delete(RequestParam ListInteger ids){log.info(批量删除部门: ids{} , ids);empService.deleteByIds(ids);return Result.success();
} 两种方式选择其中一种就可以我们一般推荐选择集合因为基于集合操作其中的元素会更加方便。 3.3.4.2 Service
1). 在接口中 EmpService 中定义接口方法 deleteByIds
/**
* 批量删除员工
*/
void deleteByIds(ListInteger ids); 2). 在实现类 EmpServiceImpl 中实现接口方法 deleteByIds
在删除员工信息时既需要删除 emp 表中的员工基本信息还需要删除 emp_expr 表中员工的工作经历信息
Transactional
Override
public void deleteByIds(ListInteger ids) {//1. 根据ID批量删除员工基本信息empMapper.deleteByIds(ids);
//2. 根据员工的ID批量删除员工的工作经历信息empExprMapper.deleteByEmpIds(ids);
}
由于删除员工信息既要删除员工基本信息又要删除工作经历信息操作多次数据库的删除所以需要进行事务控制。 3.3.4.3 Mapper
1). 在 EmpMapper 接口中增加 deleteByIds 方法实现批量删除员工基本信息
/**
* 批量删除员工信息
*/
void deleteByIds(ListInteger ids); 2). 在 EmpMapper.xml 配置文件中, 配置对应的SQL语句
!--批量删除员工信息--
delete iddeleteByIdsdelete from emp where id inforeach collectionids itemid open( close) separator,#{id}/foreach
/delete 3). 在 EmpExprMapper 接口中增加 deleteByEmpIds 方法实现根据员工ID批量删除员工的工作经历信息
/**
* 根据员工的ID批量删除工作经历信息
*/
void deleteByEmpIds(ListInteger empIds); 4). 在 EmpExprMapper.xml 配置文件中, 配置对应的SQL语句
!--根据员工的ID批量删除工作经历信息--
delete iddeleteByEmpIdsdelete from emp_expr where emp_id inforeach collectionempIds itemempId open( close) separator,#{empId}/foreach
/delete
3.3.5 功能测试
功能开发完成后重启项目工程打开 Apifox发起DELETE请求 控制台SQL语句 3.3.6 前后端联调
打开浏览器测试后端功能接口 2. 修改员工
需求修改员工信息 在进行修改员工信息的时候我们首先先要根据员工的ID查询员工的详细信息用于页面回显展示然后用户修改员工数据之后点击保存按钮就可以将修改的数据提交到服务端保存到数据库。 具体操作为 根据ID查询员工信息 保存修改的员工信息 2.1 查询回显
2.1.1 接口文档
根据ID查询员工数据 基本信息 请求路径/emps/{id}
请求方式GET
接口描述该接口用于根据主键ID查询员工的信息 请求参数 参数格式路径参数 参数说明 参数名类型是否必须备注idnumber必须员工ID请求参数样例 /emps/1 响应数据 参数格式application/json 参数说明 名称类型是否必须备注codenumber必须响应码, 1 成功 , 0 失败msgstring非必须提示信息dataobject必须返回的数据|- idnumber非必须id|- usernamestring非必须用户名|- namestring非必须姓名|- passwordstring非必须密码|- entryDatestring非必须入职日期|- gendernumber非必须性别 , 1 男 ; 2 女|- imagestring非必须图像|- jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师|- salarynumber非必须薪资|- deptIdnumber非必须部门id|- createTimestring非必须创建时间|- updateTimestring非必须更新时间|- exprListobject[]非必须工作经历列表|- idnumber非必须ID|- companystring非必须所在公司|- jobstring非必须职位|- beginstring非必须开始时间|- endstring非必须结束时间|- empIdnumber非必须员工ID响应数据样例 {code: 1,msg: success,data: {id: 2,username: zhangwuji,password: 123456,name: 张无忌,gender: 1,image: https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg,job: 2,salary: 8000,entryDate: 2015-01-01,deptId: 2,createTime: 2022-09-01T23:06:30,updateTime: 2022-09-02T00:29:04,exprList: [{id: 1,begin: 2012-07-01,end: 2019-03-03company: 百度科技股份有限公司job: java开发,empId: 2},{id: 2,begin: 2019-3-15,end: 2023-03-01company: 阿里巴巴科技股份有限公司job: 架构师,empId: 2}]}
}
2.1.2 实现思路
在查询回显时既需要查询出员工的基本信息又需要查询出该员工的工作经历信息。 我们可以先通过一条SQL语句查询出指定员工的基本信息及其员工的工作经历信息。SQL如下
select e.*,ee.id ee_id,ee.begin ee_begin,ee.end ee_end,ee.company ee_company,ee.job ee_job
from emp e left join emp_expr ee on e.id ee.emp_id where e.id 39; 具体的实现思路如下 2.1.3 代码实现
1). EmpController 添加 getInfo 用来根据ID查询员工数据用于页面回显
/*** 查询回显*/
GetMapping(/{id})
public Result getInfo(PathVariable Integer id){log.info(根据id查询员工的详细信息);Emp emp empService.getInfo(id);return Result.success(emp);
} 2). EmpService 接口中增加 getInfo 方法
/*** 根据ID查询员工的详细信息*/
Emp getInfo(Integer id); 3). EmpServiceImpl 实现类中实现 getInfo 方法
Override
public Emp getInfo(Integer id) {return empMapper.getById(id);
} 4). EmpMapper 接口中增加 getById 方法
/*** 根据ID查询员工详细信息*/
Emp getById(Integer id); 5). EmpMapper.xml 配置文件中定义对应的SQL
!--自定义结果集ResultMap--
resultMap idempResultMap typecom.itheima.pojo.Empid columnid propertyid /result columnusername propertyusername /result columnpassword propertypassword /result columnname propertyname /result columngender propertygender /result columnphone propertyphone /result columnjob propertyjob /result columnsalary propertysalary /result columnimage propertyimage /result columnentry_date propertyentryDate /result columndept_id propertydeptId /result columncreate_time propertycreateTime /result columnupdate_time propertyupdateTime /
!--封装exprList--collection propertyexprList ofTypecom.itheima.pojo.EmpExprid columnee_id propertyid/result columnee_company propertycompany/result columnee_job propertyjob/result columnee_begin propertybegin/result columnee_end propertyend/result columnee_empid propertyempId//collection
/resultMap
!--根据ID查询员工的详细信息--
select idgetById resultMapempResultMapselect e.*,ee.id ee_id,ee.emp_id ee_empid,ee.begin ee_begin,ee.end ee_end,ee.company ee_company,ee.job ee_jobfrom emp e left join emp_expr ee on e.id ee.emp_idwhere e.id #{id}
/select
在这种一对多的查询中我们要想成功的封装的结果需要手动的基于 resultMap 来进行封装结果。 Mybatis中封装查询结果什么时候用 resultType什么时候用resultMap 如果查询返回的字段名与实体的属性名可以直接对应上用resultType 。 如果查询返回的字段名与实体的属性名对应不上或实体属性比较复杂可以通过resultMap手动封装 。 2.1.4 Apifox测试
重新启动服务基于Apifox进行接口测试。 2.1.5 前后端联调测试
打开浏览器进行前后端联调测试。 2.2 修改员工
查询回显之后就可以在页面上修改员工的信息了。 当用户修改完数据之后点击保存按钮就需要将数据提交到服务端然后服务端需要将修改后的数据更新到数据库中 。 而此次更新的时候既需要更新员工的基本信息 又需要更新员工的工作经历信息 。 2.2.1 接口文档 基本信息 请求路径/emps
请求方式PUT
接口描述该接口用于修改员工的数据信息 请求参数 参数格式application/json 参数说明 名称类型是否必须备注idnumber必须idusernamestring必须用户名namestring必须姓名gendernumber必须性别, 说明: 1 男, 2 女imagestring非必须图像deptIdnumber非必须部门identryDatestring非必须入职日期jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师salarynumber非必须薪资exprListobject[]非必须工作经历列表|- idnumber非必须ID|- companystring非必须所在公司|- jobstring非必须职位|- beginstring非必须开始时间|- endstring非必须结束时间|- empIdnumber非必须员工ID请求数据样例 {id: 2,username: zhangwuji,name: 张无忌,gender: 1,image: https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg,job: 2,salary: 8000,entryDate: 2015-01-01,deptId: 2,exprList: [{id: 1,begin: 2012-07-01,end: 2015-06-20company: 中软国际股份有限公司job: java开发,empId: 2},{id: 2,begin: 2015-07-01,end: 2019-03-03company: 百度科技股份有限公司job: java开发,empId: 2}]} 响应数据 参数格式application/json 参数说明 参数名类型是否必须备注codenumber必须响应码1 代表成功0 代表失败msgstring非必须提示信息dataobject非必须返回的数据响应数据样例 {code:1,msg:success,data:null
}
2.2.2 实现思路 2.2.3 代码实现
1). EmpController 增加 update 方法接收请求参数响应数据
/**
* 更新员工信息
*/
PutMapping
public Result update(RequestBody Emp emp){log.info(修改员工信息, {}, emp);empService.update(emp);return Result.success();
} 2). EmpService 接口增加 update 方法
/**
* 更新员工信息
* param emp
*/
void update(Emp emp); 3). EmpServiceImpl 实现类实现 update 方法
Transactional
Override
public void update(Emp emp) {//1. 根据ID更新员工基本信息emp.setUpdateTime(LocalDateTime.now());empMapper.updateById(emp);
//2. 根据员工ID删除员工的工作经历信息 【删除老的】empExprMapper.deleteByEmpIds(Arrays.asList(emp.getId()));
//3. 新增员工的工作经历数据 【新增新的】Integer empId emp.getId();ListEmpExpr exprList emp.getExprList();if(!CollectionUtils.isEmpty(exprList)){exprList.forEach(empExpr - empExpr.setEmpId(empId));empExprMapper.insertBatch(exprList);}
} 4). EmpMapper 接口中增加 updateById 方法
/**
* 更新员工基本信息
*/
void updateById(Emp emp); 5). EmpMapper.xml 配置文件中定义对应的SQL语句基于动态SQL更新员工信息
!--根据ID更新员工信息--
update idupdateByIdupdate empsetif testusername ! null and username ! username #{username},/ifif testpassword ! null and password ! password #{password},/ifif testname ! null and name ! name #{name},/ifif testgender ! nullgender #{gender},/ifif testphone ! null and phone ! phone #{phone},/ifif testjob ! nulljob #{job},/ifif testsalary ! nullsalary #{salary},/ifif testimage ! null and image ! image #{image},/ifif testentryDate ! nullentry_date #{entryDate},/ifif testdeptId ! nulldept_id #{deptId},/ifif testupdateTime ! nullupdate_time #{updateTime},/if/setwhere id #{id}
/update 2.2.4 Apifox测试
重新启动服务打开 Apifox 进行接口测试。 2.2.5 前后端联调测试 点击保存之后查看更新后的数据。 3. 异常处理
3.1 当前问题
当我们在修改部门数据的时候如果输入一个在数据库表中已经存在的手机号点击保存按钮之后前端提示了错误信息但是返回的结果并不是统一的响应结果而是框架默认返回的错误结果 。 状态码为500表示服务器端异常我们打开idea来看一下服务器端出了什么问题。 上述错误信息的含义是emp员工表的phone手机号字段的值重复了因为在数据库表emp中已经有了13309090001这个手机号了我们之前设计这张表时为phone字段建议了唯一约束所以该字段的值是不能重复的。
而当我们再将该员工的手机号也设置为 13309090001就违反了唯一约束此时就会报错。 我们来看一下出现异常之后最终服务端给前端响应回来的数据长什么样。 响应回来的数据是一个JSON格式的数据。但这种JSON格式的数据还是我们开发规范当中所提到的统一响应结果Result吗显然并不是。由于返回的数据不符合开发规范所以前端并不能解析出响应的JSON数据 。 接下来我们需要思考的是出现异常之后当前案例项目的异常是怎么处理的 答案没有做任何的异常处理 当我们没有做任何的异常处理时我们三层架构处理异常的方案 Mapper接口在操作数据库的时候出错了此时异常会往上抛(谁调用Mapper就抛给谁)会抛给service。 service 中也存在异常了会抛给controller。 而在controller当中我们也没有做任何的异常处理所以最终异常会再往上抛。最终抛给框架之后框架就会返回一个JSON格式的数据里面封装的就是错误的信息但是框架返回的JSON格式的数据并不符合我们的开发规范。
3.2 解决方案
那么在三层构架项目中出现了异常该如何处理? 方案一在所有Controller的所有方法中进行try…catch处理 缺点代码臃肿不推荐 方案二全局异常处理器 好处简单、优雅推荐 3.3 全局异常处理器
我们该怎么样定义全局异常处理器 定义全局异常处理器非常简单就是定义一个类在类上加上一个注解RestControllerAdvice加上这个注解就代表我们定义了一个全局异常处理器。 在全局异常处理器当中需要定义一个方法来捕获异常在这个方法上需要加上注解ExceptionHandler。通过ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。
RestControllerAdvice
public class GlobalExceptionHandler {
//处理异常ExceptionHandlerpublic Result ex(Exception e){//方法形参中指定能够处理的异常类型e.printStackTrace();//打印堆栈中的异常信息//捕获到异常之后响应一个标准的Resultreturn Result.error(对不起,操作失败,请联系管理员);}
} RestControllerAdvice ControllerAdvice ResponseBody 处理异常的方法返回值会转换为json后再响应给前端 重新启动SpringBoot服务打开浏览器再来测试一下 修改员工 这个操作我们依然设置已存在的 13309090001 这个手机号 此时我们可以看到出现异常之后异常已经被全局异常处理器捕获了。然后返回的错误信息被前端程序正常解析然后提示出了对应的错误提示信息。 以上就是全局异常处理器的使用主要涉及到两个注解 RestControllerAdvice //表示当前类为全局异常处理器 ExceptionHandler //指定可以捕获哪种类型的异常进行处理 3.4 如何抛出自定义异常信息 package com.itheima.exception;
public class BusinessException extends RuntimeException{public BusinessException() {super();}public BusinessException(String message) {super(message);}
}
package com.itheima.exception;
import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/*** 全局异常处理器*/
Slf4j
RestControllerAdvice
public class GlobalExceptionHandler {
ExceptionHandlerpublic Result handleException(Exception e){log.error(程序运行出错啦 .... , e);return Result.error(对不起, 系统访问异常, 请联系管理员 ~);}
ExceptionHandlerpublic Result handleBussinessException(BusinessException e){log.error(程序运行出错啦 .... , e);return Result.error(e.getMessage());}
} 4. 员工信息统计
员工管理的增删改查功能我们已开发完成接下来我们再来完成员工信息统计的接口开发。 对于这些图形报表的开发其实呢都是基于现成的一些图形报表的组件开发的比如Echarts、HighCharts等。
而报表的制作主要是前端人员开发引入对应的组件比如ECharts即可。 服务端开发人员仅为其提供数据即可。
官网Apache ECharts 4.1 职位统计
4.1.1 需求 对于这类的图形报表服务端要做的就是为其提供数据即可。 我们可以通过官方的示例看到提供的数据其实就是X轴展示的信息和对应的数据。 4.1.2 接口文档
1). 基本信息 请求路径/report/empJobData 请求方式GET 接口描述统计各个职位的员工人数 2). 请求参数
无 3). 响应数据
参数格式application/json
参数说明
参数名类型是否必须备注codenumber必须响应码1 代表成功0 代表失败msgstring非必须提示信息dataobject非必须返回的数据|- jobListstring[]必须职位列表|- dataListnumber[]必须人数列表
响应数据样例
{code: 1,msg: success,data: {jobList: [教研主管,学工主管,其他,班主任,咨询师,讲师],dataList: [1,1,2,6,8,13]}
} 为了封装上面需要给前端返回的数据在pojo包下再创建一个实体类 JobOption封装给前端返回的结果
/*** 员工职位人数统计*/
Data
NoArgsConstructor
AllArgsConstructor
public class JobOption {private List jobList; //职位列表private List dataList; //人数列表
} 4.1.3 代码实现
1). 定义ReportController并添加方法。
Slf4j
RequestMapping(/report)
RestController
public class ReportController {
Autowiredprivate ReportService reportService;
/*** 统计各个职位的员工人数*/GetMapping(/empJobData)public Result getEmpJobData(){log.info(统计各个职位的员工人数);JobOption jobOption reportService.getEmpJobData();return Result.success(jobOption);}
} 2). 定义ReportService接口并添加接口方法。
public interface ReportService {/*** 统计各个职位的员工人数* return*/JobOption getEmpJobData();
} 3). 定义ReportServiceImpl实现类并实现方法
Service
public class ReportServiceImpl implements ReportService {
Autowiredprivate EmpMapper empMapper;Overridepublic JobOption getEmpJobData() {ListMapString,Object list empMapper.countEmpJobData();ListObject jobList list.stream().map(dataMap - dataMap.get(pos)).toList();ListObject dataList list.stream().map(dataMap - dataMap.get(total)).toList();return new JobOption(jobList, dataList);}
} 4). 定义EmpMapper 接口
统计的是员工的信息所以需要操作的是员工表。 所以代码我们就写在 EmpMapper 接口中即可。
/*** 统计各个职位的员工人数*/
MapKey(pos)
ListMapString,Object countEmpJobData(); 如果查询的记录往Map中封装可以通过MapKey注解指定返回的map中的唯一标识是那个字段。【也可以不指定】 5). 定义EmpMapper.xml
!-- 统计各个职位的员工人数 --
select idcountEmpJobData resultTypejava.util.Mapselect(case job when 1 then 班主任 when 2 then 讲师 when 3 then 学工主管 when 4 then 教研主管 when 5 then 咨询师 else 其他 end) pos,count(*) totalfrom emp group by joborder by total
/select case流程控制函数 语法一case when cond1 then res1 [ when cond2 then res2 ] else res end ; 含义如果 cond1 成立 取 res1。 如果 cond2 成立取 res2。 如果前面的条件都不成立则取 res。 语法二仅适用于等值匹配case expr when val1 then res1 [ when val2 then res2 ] else res end ; 含义如果 expr 的值为 val1 取 res1。 如果 expr 的值为 val2 取 res2。 如果前面的条件都不成立则取 res。 4.1.4 Apifox测试
重新启动服务打开Apifox进行测试。 4.1.5 联调测试 4.2 性别统计
4.2.1 需求 对于这类的图形报表服务端要做的就是为其提供数据即可。 我们可以通过官方的示例看到提供的数据就是一个json格式的数据。 4.2.2 接口文档
1). 基本信息 请求路径/report/empGenderData 请求方式GET 接口描述统计员工性别信息 2). 请求参数
无 3). 响应数据
参数格式application/json
参数说明
参数名类型是否必须备注codenumber必须响应码1 代表成功0 代表失败msgstring非必须提示信息dataobject[]非必须返回的数据|- namestring非必须性别|- valuenumber非必须人数
响应数据样例
{code: 1,msg: success,data: [{name: 男性,value: 5},{name: 女性,value: 6}]
} 4.2.3 代码实现
1). 在ReportController添加方法。
/*** 统计员工性别信息*/
GetMapping(/empGenderData)
public Result getEmpGenderData(){log.info(统计员工性别信息);ListMap genderList reportService.getEmpGenderData();return Result.success(genderList);
} 2). 在ReportService接口添加接口方法。
/*** 统计员工性别信息*/
ListMap getEmpGenderData(); 3). 在ReportServiceImpl实现类实现方法
Override
public ListMap getEmpGenderData() {return empMapper.countEmpGenderData();
} 4). 定义EmpMapper 接口
统计的是员工的信息所以需要操作的是员工表。 所以代码我们就写在 EmpMapper 接口中即可。
/*** 统计员工性别信息*/
MapKey(name)
ListMap countEmpGenderData(); 5). 定义EmpMapper.xml
!-- 统计员工的性别信息 --
select idcountEmpGenderData resultTypejava.util.Mapselectif(gender 1, 男, 女) as name,count(*) as valuefrom emp group by gender ;
/select if函数语法if(条件, 条件为true取值, 条件为false取值) ifnull函数语法ifnull(expr, val1) 如果expr不为null取自身否则取val1 4.2.4 Apifox测试 4.2.5 联调测试 文章转载自: http://www.morning.zdsqb.cn.gov.cn.zdsqb.cn http://www.morning.rsnd.cn.gov.cn.rsnd.cn http://www.morning.yltyz.cn.gov.cn.yltyz.cn http://www.morning.ctfwl.cn.gov.cn.ctfwl.cn http://www.morning.wmmjw.cn.gov.cn.wmmjw.cn http://www.morning.mfnjk.cn.gov.cn.mfnjk.cn http://www.morning.knlbg.cn.gov.cn.knlbg.cn http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn http://www.morning.bpmft.cn.gov.cn.bpmft.cn http://www.morning.xnwjt.cn.gov.cn.xnwjt.cn http://www.morning.qjmnl.cn.gov.cn.qjmnl.cn http://www.morning.ngqty.cn.gov.cn.ngqty.cn http://www.morning.txhls.cn.gov.cn.txhls.cn http://www.morning.qnzpg.cn.gov.cn.qnzpg.cn http://www.morning.dzpnl.cn.gov.cn.dzpnl.cn http://www.morning.jlschmy.com.gov.cn.jlschmy.com http://www.morning.rywn.cn.gov.cn.rywn.cn http://www.morning.nqgds.cn.gov.cn.nqgds.cn http://www.morning.hzryl.cn.gov.cn.hzryl.cn http://www.morning.pqndg.cn.gov.cn.pqndg.cn http://www.morning.qyllw.cn.gov.cn.qyllw.cn http://www.morning.rlbfp.cn.gov.cn.rlbfp.cn http://www.morning.lgnbr.cn.gov.cn.lgnbr.cn http://www.morning.wnrcj.cn.gov.cn.wnrcj.cn http://www.morning.smwlr.cn.gov.cn.smwlr.cn http://www.morning.saletj.com.gov.cn.saletj.com http://www.morning.myzfz.com.gov.cn.myzfz.com http://www.morning.grryh.cn.gov.cn.grryh.cn http://www.morning.nlkm.cn.gov.cn.nlkm.cn http://www.morning.wqcbr.cn.gov.cn.wqcbr.cn http://www.morning.ygrdb.cn.gov.cn.ygrdb.cn http://www.morning.sbqrm.cn.gov.cn.sbqrm.cn http://www.morning.hybmz.cn.gov.cn.hybmz.cn http://www.morning.jrhcp.cn.gov.cn.jrhcp.cn http://www.morning.bsjpd.cn.gov.cn.bsjpd.cn http://www.morning.bydpr.cn.gov.cn.bydpr.cn http://www.morning.jzlkq.cn.gov.cn.jzlkq.cn http://www.morning.xprzq.cn.gov.cn.xprzq.cn http://www.morning.cxlys.cn.gov.cn.cxlys.cn http://www.morning.cbpkr.cn.gov.cn.cbpkr.cn http://www.morning.rczrq.cn.gov.cn.rczrq.cn http://www.morning.gbybx.cn.gov.cn.gbybx.cn http://www.morning.sqgqh.cn.gov.cn.sqgqh.cn http://www.morning.btqqh.cn.gov.cn.btqqh.cn http://www.morning.rwmqp.cn.gov.cn.rwmqp.cn http://www.morning.fxzlg.cn.gov.cn.fxzlg.cn http://www.morning.rmpkn.cn.gov.cn.rmpkn.cn http://www.morning.zxhhy.cn.gov.cn.zxhhy.cn http://www.morning.sjjtz.cn.gov.cn.sjjtz.cn http://www.morning.fbhmn.cn.gov.cn.fbhmn.cn http://www.morning.zqcdl.cn.gov.cn.zqcdl.cn http://www.morning.smpmn.cn.gov.cn.smpmn.cn http://www.morning.nqbpz.cn.gov.cn.nqbpz.cn http://www.morning.gtjkh.cn.gov.cn.gtjkh.cn http://www.morning.bysey.com.gov.cn.bysey.com http://www.morning.qjxkx.cn.gov.cn.qjxkx.cn http://www.morning.rhkmn.cn.gov.cn.rhkmn.cn http://www.morning.gkgb.cn.gov.cn.gkgb.cn http://www.morning.lzttq.cn.gov.cn.lzttq.cn http://www.morning.rcqyk.cn.gov.cn.rcqyk.cn http://www.morning.fthcq.cn.gov.cn.fthcq.cn http://www.morning.rwzc.cn.gov.cn.rwzc.cn http://www.morning.rxxdk.cn.gov.cn.rxxdk.cn http://www.morning.hffpy.cn.gov.cn.hffpy.cn http://www.morning.wqpm.cn.gov.cn.wqpm.cn http://www.morning.rdkgw.cn.gov.cn.rdkgw.cn http://www.morning.mhnrx.cn.gov.cn.mhnrx.cn http://www.morning.qgjp.cn.gov.cn.qgjp.cn http://www.morning.ns3nt8.cn.gov.cn.ns3nt8.cn http://www.morning.mnqz.cn.gov.cn.mnqz.cn http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn http://www.morning.cwlxs.cn.gov.cn.cwlxs.cn http://www.morning.xrwbc.cn.gov.cn.xrwbc.cn http://www.morning.bnmfq.cn.gov.cn.bnmfq.cn http://www.morning.qnsmk.cn.gov.cn.qnsmk.cn http://www.morning.yqqgp.cn.gov.cn.yqqgp.cn http://www.morning.ygpdm.cn.gov.cn.ygpdm.cn http://www.morning.hytr.cn.gov.cn.hytr.cn http://www.morning.bzlfw.cn.gov.cn.bzlfw.cn http://www.morning.rknhd.cn.gov.cn.rknhd.cn