作者:于佳鑫
国土基线地址:http://52.83.103.252:8086/NatureResource/#/Portal
用户名/ 密码:*** / ***
运维地址:http://52.83.103.252:8086/dgpoms/#/pc/roleperm/domain
用户名/密码:*** / ***
业务库地址:*** / ***
先看下整个系统使用到的表和他们之间的关系吧,下面介绍的时候会提及到:
整个系统的核心是审查任务表,审查任务表中有一个核心的概念就是”五级三类“,“五级”为:国家级、省级、市级、县级、乡镇级,“三类”为:总规、控规、专规。审查任务的区域级别在数据库中采用 areaLevel 字段表示,规划类型采用 planType 表示。
当点击新建任务的时候,会弹出选择成果包的对话框,选择对应的成果包进行上传即可。
注:此处上传成果包时的要求
- 此处上传的成果包是报批成果包(需要被审查的成果包)
报批成果包:链接: https://pan.baidu.com/s/1tL6BKvMMB8yhaM0Qf6s78g 密码: 6drb
- 仅能上传本级或下级行政区划的成果包。
那么怎样确定用户所属级别呢?
进入运维:
![]()
我们解压下成果包看下其中的“成果数据基本信息.txt”文件,其中规划类型和区域级别两个字段的来源已经在图上标注出来了。
当点击“新建任务”的时候,“成果数据基本信息.txt”文件中的这些数据将会保存到项目表(ProjectInfo)中进行存储,同时会在审查任务表中新建一条记录与这个项目绑定,其中核心字段如下:reviewState(审查状态)、taskAreaLevel(任务是哪个级别的用户上传的)、rolesName(上传用户拥有的角色)。
我们将用户上传的成果包的层级结构保存在成果树(CatalogNode)表中,每个文件上传至 mongoDB 中,文件的详细信息存在资源文件表(ResourceFile)中。
由于历史遗留问题,这部分涉及到了 CS 档案系统,而且代码质量不高,好在这部分代码比较稳定,所以只需要了解下面画的流程即可,不建议大家阅读代码。
不启动机器审查也可以点进去查看,那么我们先点进去看一下,在最左侧两个按钮,“规划成果”和“审查依据”。
其中规划成果展示的就是用户上传的成果包中的信息,我们可以在这里对其进行预览(部分矢量数据需要结合模型计算才能实现预览,会在下一篇文章中提及到的)。
审查依据中又分为工作依据和相关依据。
其中工作依据是通过任务首页中的“上传工作依据”按钮进行上传的:
注:上传工作依据的时候,需要调用全文检索系统进行文件索引的建立。
相关依据是在从档案系统同步成果包数据的时候同步过来的(看上面的流程图),数据来源为上传的成果包所在区域的上位和相邻区域的“规划文本”目录下的文件。
接下来,我们点击“启动机器审查”,那么机器审查到底是在做什么呢,这就又要引入一张表了:审查要点表(ReviewPoint),审查要点就是这个任务审查时需要考虑的要点,其中的数据来源全部来自于用户上传的成果包中(一些是成果包中的 excel、图片等文件,一些是通过成果包中的一些矢量数据,调用模型系统计算出来的数据),由于不同的区域级别和规划类型他们关注的要点也不同,所以在 ReviewPoint 表中也有这两个字段(belongAreaLevel、belongPlanType)来标识不同级别、规划类型的要点。
上面说了审查要点的一部分是来自于模型计算的结果,所以在审查要点表中有一个字段 fromModelCalculation 来标识是否来自模型计算,另外还有一个字段 participateCalc 来控制是否参与模型计算(也就是点击“机器审查”时是否计算这个模型)。
注:启动模型计算这个地方逻辑过于复杂,准备独立成一个模块放到下一篇文章中介绍,下面你可以假设模型已经计算完成了。
接下来就开始人工审查的流程了,流程图如下:
此时,我们可以点击进来,选择一个审查要点进行意见的填写:
当意见填写完成之后,可以点击生成报告,生成报告之后才可以点击完成审查:
完成审查时会将最近的审查报告复制一份到规划成果下,如下图:
然后这个任务的整个生命周期就结束了,之后他就会进入“成果管理”中。
接口:/v5/reviewTask/page
**入参:**planType(规划类型)、level(区域等级,对应的 ProjectInfo 表中的 areaLevel 字段)、keyword(搜索关键词)、pageIndex、pageSize
代码逻辑:
---------- controller
---------- service
获取传过来 query 对象中的“用户所在区域代码”,调用 ims 系统获取区域代码所在层级(ReviewTask 表中的 taskAreaLevel)
调用 dmn 层,根据 planType、areaLevel、keyword、taskAreaLevel、roles 查询出符合条件的报批任务
采用“尾部去零法”过滤不是本级下的任务
因为需要展示成那种折叠的格式,所以需要根据 projectCode 进行分组折叠
使用分页工具类分页,返回 controller 层
---------- controller
**常见迷惑点:**用户在页面上点击的市、县、乡对应的是 ProjectInfo 表的 areaLevel,而当前登录用户所处的级别对应的是 ReviewTask 表中的 taskAreaLevel,也就是说一个用户只能看到同一级别用户上传的市、县、乡的任务。
例 1:县级(taskAreaLevel)用户上传的县级(areaLevel)任务,市级(taskAreaLevel)用户是没法看到的
例 2:市级(taskAreaLevel)用户上传的县级(areaLevel)任务,市级(taskAreaLevel)用户是能看到的
注:当然还要考虑角色,查询的时候还要根据角色进行一次过滤。
这个是个隐藏功能,我觉得产品在设计有缺陷,遇到问题再找我吧,不想讲了。
注:是否能看到向上提交是由前端控制的。
接口:/v2/fileUrl/{resourceId}
**入参:**resourceId(资源文件 id,对应的是 ResourceFile 表的 id)
代码逻辑:
注:此处的代码逻辑只讲 officeOnline 的预览,图片的预览没啥可讲的,mdb、gdb 的参见下一篇文章。
@GetMapping("/v2/fileUrl/{resourceId}")
@ApiOperation(value = "根据资源文件id,返回url实现文件预览", httpMethod = "GET")
public ResponseData getFileUrlByResourceId(@PathVariable(value = "resourceId") Long resourceId) {
if (resourceId < 0) {
throw new IllegalParameterException("输入的资源文件id错误!");
}
// 1)
ResourceCommand<?> command = resourceCommandFactory.createCommand(resourceId);
// 2)
ResourceFileUrlVO<?> resourceFileUrlVO = CommandExecuteService.execute(command, resourceId, this.httpServletRequest);
return ResponseUtil.success(resourceFileUrlVO);
}
本部分代码采用了简单工厂和命令模式,第一句就是根据一系列判断条件找到合适的命令:
第二句就是执行命令,没啥可说的,我们看具体的命令对象:OfficeOnlineCommand
/**
* 执行命令
*
* @param resourceId 资源文件id
* @param request 本次请求对象
* @return 资源文件信息的实体(url或数据)
*/
@Override
public ResourceFileUrlVO<Void> execute(Long resourceId, HttpServletRequest request) {
// 获取应用url
String applicationUrl = ContextPathUtil.getBaseURL(request);
// 获取相应文件类型的uri
// 获取文件信息
ResourceFileDTO resourceFileDTO = reviewResourceBizService.getResourceFileByResourceFileId(resourceId);
// 获取文件后缀(不带.的)
String suffix = resourceFileDTO.getSuffix();
if (suffix.contains(".")) {
suffix = suffix.substring(1, suffix.length()).toLowerCase();
}
String uri = GlobalConstant.OFFICE_ONLINE_PROPERTIES.get(suffix);
// 拼装重定向url
String url = officeOnlineUrl + uri + applicationUrl + OFFICE_WOPI + resourceId;
// 封装返回的信息
ResourceFileUrlVO<Void> resourceFileUrlVO = new ResourceFileUrlVO<>();
resourceFileUrlVO.setType(resourceFileType);
resourceFileUrlVO.setStream(Boolean.FALSE);
resourceFileUrlVO.setUrl(url);
return resourceFileUrlVO;
}
注释应该写的很清楚了,返回的 url 格式为:
OfficeOnline 接收到请求的时候首先会请求:http://52.83.103.252:8086/dgp-server-web-nr/wopi/files/14779581这个地址,将会被我们系统的 WopiFilter 进行拦截,此时我们会返回 14779581(这个是 resourceFileId) 对应的文件的元数据,此时 OfficeOnline 就会检查是否本地已经有这个文件了,如果没有的话,则会请求 http://52.83.103.252:8086/dgp-server-web-nr/wopi/files/14779581/contents 进行文件的下载(这个地址也会被 WopiFilter 拦截,具体可以看代码),然后就可以预览了。
所以加入 OfficeOnline 预览有了问题,可以进行 F12 抓包,抓到这个地址:http://52.83.96.20/x/_layouts/xlviewerinternal.aspx?WOPISrc=http://52.83.103.252:8086/dgp-server-web-nr/wopi/files/14779581,然后我们请求 http://52.83.103.252:8086/dgp-server-web-nr/wopi/files/14779581/contents 看看下载下的文件是否有问题,如果文件没问题,那么就是 OfficeOnline 服务器的问题了,就可以找实施了。
注:返回给 officeOnline 的文件元数据必须要有后缀名。
接口:/v1/workBasis/{planType}/{areaLevel}/{path}(上传接口:/v1/temp/workBasis)
入参:planType、areaLevel、path(在 mongo 中的唯一标识)
代码逻辑:没啥可讲的,主要想说的是这句代码:
// 推送文件到全文检索
searchService.createSearchIndex(workBasisNodeType);
上传工作依据的时候需要向全文检索系统建立索引,调用时采用的 Feign,所以当上传工作依据报错 FeignException 的话,请直接找实施启动全文检索系统。
第一步:因为部分任务状态(例如:已完成、机审中)不能进行任务的删除,所以需要进入审查任务表中,将需要删除的审查任务的 ReviewState 改为 0。
第二步:找到 http://52.83.103.252:8086/dgp-server-web-nr/swagger-ui.html#/ARS-ReviewTaskController/batchDelReviewTaskUsingDELETE 接口,将需要删除的审查任务 id 写到请求的数组中。
之前也提到过,成果管理页面展示的是最近一次审查完成的任务和批复成果包,所以我们先看下批复成果包的上传
批复成果包:链接: https://pan.baidu.com/s/1jMAAhLX4LNo9dj6_iauQ5g 密码: 8eo4
上传完成的时候,你可以看到展示的这条记录的成果版本从【报批稿】变成了【批复稿】,成果阶段从【一审】变成了【已批复】,此时没有办法再从成果审查上传相同【区域+规划类型+区域级别+起始年+目标年 => 版本】的批复成果包,证明这个版本的成果包已经彻底审查完成。
区域树只会展示有批复或者已经审查完成的区域。
折叠方式为:区域代码 + 区域名称 + 规划类型 + ( + 规划目标年 + )
完结撒花~