• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

NXCheckPart: 基于nx check-mate的三维模型质量检测分布式系统

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

NXCheckPart

开源软件地址:

https://gitee.com/mumulx/nxcheck-part

开源软件介绍:

基于Spring Cloud的NX三维模型检测系统的设计与实现

毕设题目:基于Spring Cloud的NX三维模型检测系统的设计与实现

项目名:NXCheckPart

本项目不用做任何商用用途,仅供自己学习使用,如有侵权请联系本人[email protected]

介绍

NXCheckPart是一个基于SpringBoot、SpringCloud、Spring Security、FastDfs、NX1926的分布式三维模型检测系统。将传统的NX的CheckMate功能进行扩展,使之不再拘束于只能在本地进行部件检查,而将其功能集成到web中,使得用户能够实时的进行三维模型的检测并且用户能够实时获取测试结果。

Spring Cloud是一个微服务治理框架,提供了一套服务拆分与管理的工具,对于分布式的开发有着很好的支持,因此是本系统主框架的不二之选。

本系统的优点如下:

  • 可扩展

    采用Spring Cloud微服务的思想,本项目是一个分布式项目,采用多模块进行开发,将服务进行拆分,每个服务都需要单独进行部署,并且每个服务都可以部署集群,能够轻易的进行扩展

  • 文件存储安全

    采用FastDfs分布式文件的存储系统,对测试的部件和测试的结果文件进行存储,FastDfs也可以部署集群,提供良好的数据安全服务

  • 操作简单

    用户不再需要安装NX,只需要一个浏览器用户就可以完成部件的检测,通过简单的两步操作用户就可以进行部件的测试和获取测试结果(1.选择测试的规则。2.上传测试的部件文件)支持在线的测试结果的阅读。

  • 界面美化

    对于传统的测试结果文档xml+xsl的形式进行优化,使用户能够在网页上查看测试结果。

    当然了,如果您仍然想使用以前的形式,本站也提供了下载功能,使得用户能够将结果文件下载到本地,再由您进行结果查看。

  • 系统安全

    采用spring Security来保障系统的安全进行权限控制,可以有效的预防许多因用户操作失误,或用户越权限操作带来的各种问题。

    采用熔断器,服务降级、部署集群等措施来提高系统的可用性与安全性。

本项目不用做任何商用用途,仅供自己学习使用,如有侵权请联系本人[email protected]

项目说明

技术选型

  • 系统环境
    • java EE 8
      • 多线程
      • 设计模式
    • Servlet 3.0
    • Apache Maven 3
    • NX1926
  • 分布式文件系统
    • fastdfs
    • Nginx
  • 主框架
    • spring Cloud
      • eureka
      • feign
      • ribbon
      • hystrix
      • dashborad
      • config
    • spring Security
    • spring Boot 2.2.5
    • rabbitMQ
  • 持久层
    • mysql
    • mybatis
    • redis
    • Hibernet Validation 6.0
  • 其他
    • 接口文档
      • swagger
    • 日志
      • loback
  • 视图
    • 前端
      • jquery
      • ajax
      • bootstrap
      • json
    • Thymeleaf

项目结构

  • NXCheckpartAdmin ----项目核心代码
    • check-model ----实体类层
    • check-mapper ----Mapper层
    • check-service ----Service层
    • check-web ----控制层
    • check-scheduler ----定时任务
  • NXRemoteServerProvider ----NX服务提供方---调用nx服务进行一系列操作
  • NXCheckpartEureka ----服务注册中心
  • NXCheckpartHystrixDashboard ----服务监控中心
  • NXCheckpartApi ----共享Api
    • api-feign ----Feign公共接口模块
    • api-redis ----Redis工具模块
    • api-entity ----公共的实体类模块
  • NXCheckPartConfig ----配置中心
  • NXCheckpartFastDfs ----FastDfs服务模块
  • 网关--计划中

功能模块

  • 个人中心
    • 个人信息
    • 项目中心
  • 提交检查
    • 测试规则
    • 测试文件
    • 等待界面
  • 测试记录
    • 测试记录
    • 回收站
  • 测试结果
  • 站内通知

checkpart

项目架构图

项目架构图

主要功能UML图

文件上传

文件上传

部件测试

部件测试

获取测试结果

测试结果查看

数据库表设计

数据库设计

项目规划

  • 优化系统Bug
  • 增加团队项目内容
  • springsecurity动态权限认证
  • 优化界面
  • 登录方式整合第三方
  • 站内消息通知

项目主要功能介绍

放弃properties配置文件类型,采用更为直观的yml文件格式来作为项目的配置文件。

项目结构说明

NXCheckpartAdmin

项目的核心代码模块,采用经典的三层模型

check-model

dodel层里面存放了各个实体类,与数据库中的数据相对应

check-mapper

存放了mybatis所需要的xml文件和与之对应的接口文件

check-service

service层存放了我们service层的接口及其实现类

check-web

controller层,是我们控制器所在的模块,里面也存放了一些配置信息包括:speingsecurity、exception统一处理、swagger配置、rabbitMq配置、

check-scheduler

定时任务模块,我们采用springboot默认的Scheduler定时任务功能,首先在springboot启动类上加上

@EnableScheduling

注解用于开启基于注解的定时任务

/* *  Created by IntelliJ IDEA. *  User: 木木 *  Date: 2020/10/23 *  Time: 13:58 * 定时任务 */@Component@Slf4jpublic class SchedulerTask {    @Resource    RedisUtil redisUtil;    @Resource    CheckpartSendLogService checkpartSendLogService;    @Autowired    RabbitTemplate rabbitTemplate;    @Resource    SubmitRecordService submitRecordService;    @Resource    SubmitFileRecordService submitFileRecordService;    @Resource    SubmitRuleRecordService submitRuleRecordService;    /*     * @author mumulx     * @creed: mumulx编写     * @email: [email protected]     * @date 2020/10/23 13:59     * @param     * @return void     * 每6小时执行一次 将结果放到redis中     */    @Scheduled(fixedRate = 21600000)    public void process() {        RestTemplate restTemplate = new RestTemplate();        String url = "https://chp.shadiao.app/api.php";        LinkedMultiValueMap<String, String> lv = new LinkedMultiValueMap<>();        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);        String body = responseEntity.getBody();        body.replaceAll(" ", "<br/>");        redisUtil.set(RedisKeyType.TALK_LOVE.getKey(), body);        log.info("-------定时任务开启:" + body);    }    /*     * 用于重试消息发送     * @author mumulx     * @creed: mumulx编写     * @email: [email protected]     * @date 2020/11/4 9:52     * @param     * @return void     * 1分钟执行一次     */    @Scheduled(fixedRate = 60000)    public void mailResendTask() {        log.info("消息重发定时任务开启");        List<CheckpartSendLog> CheckpartSendLogs = checkpartSendLogService.getMailSendLogsByStatus();        CheckpartSendLogs.forEach(checkpartSendLog -> {            log.info("重试发送消息");            /**当超过重试次数后会标记消息发送失败--不再重复发送消息*/            if (checkpartSendLog.getCount() >= CheckPartContants.MAX_TRY_COUNT) {                log.info("消息重试次数过多---消息发送失败");                checkpartSendLogService.updateMailSendLogStatus(checkpartSendLog.getMsgId(), 2);//直接设置该条消息发送失败            } else {                log.info("准备发送消息");                checkpartSendLogService.updateCount(checkpartSendLog.getMsgId(), new Date());                Integer srId = checkpartSendLog.getSrId();                //获取需要重发消息的  测试记录                SubmitRecord submitRecord = submitRecordService.queryRecordBySrId(srId);                //获取prts                Map<Integer, String> parts = submitFileRecordService.queryFileRecordListBysrid(srId).stream().collect(Collectors.toMap(SubmitFileRecord::getSfrId, SubmitFileRecord::getSfrFileName));                //获取rules                List<String> rules = submitRuleRecordService.queryCheckerListBySrId(srId);                //对象包装                PartTestBoxed partTestBoxed = new PartTestBoxed();                partTestBoxed.setUserId(submitRecord.getSrUserId());                partTestBoxed.setParts(parts);                partTestBoxed.setRules(rules);                partTestBoxed.setTestRecordId(srId);                log.info("重发的消息的基本信息:"+partTestBoxed.toString());                //重新发送消息                rabbitTemplate.convertAndSend(CheckPartContants.MAIL_EXCHANGE_NAME, CheckPartContants.MAIL_ROUTING_KEY_NAME, partTestBoxed, new CorrelationData(checkpartSendLog.getMsgId()));                log.info("消息重发成功");            }        });    }    /*     * 用于删除 测试记录---保存时间默认为30天     * @author mumulx     * @creed: mumulx编写     * @email: [email protected]     * @date 2020/11/6 16:16     * @param     * @return void     */    @Scheduled(fixedRate = 1800000)    public void deleteSubmitRecordByexpiredTime() {        List<Integer> srIds = submitRecordService                .queryExpiredTimeList()                .stream()                .mapToInt(e -> e.getSrId())                .boxed()                .collect(Collectors.toList());        //删除 测试规则记录信息        srIds.forEach(srId->{            log.info("检测到有测试记录要删除---已过期:srid="+srId);            //删除测试文件记录信息--删除文件服务器上的文件--删除数据库中的数据            submitFileRecordService.deleteFileRecordBySrId(srId);            //删除测试规则记录信息            submitRuleRecordService.deleteRuleRecordBySrId(srId);            //删除测试记录            submitRecordService.deleteRecordBySrId(srId);            log.info(srId+"记录删除成功");        });    }}

process任务用于向redis中存储一段文字,该文字会出现在用户登录的界面上,并且每6小时更新一次。主要是对第三方的api的url发起请求获取响应结果,我们将结果放到redis中进行缓存。在使用时我们只需要向redis中获取值就可以了。

mailResendTask任务时消息重发任务,这部分放到RabbitMQ幂等性解决方案中详细介绍,主要的功能时重发失败的消息,确保消息的可用性。

deleteSubmitRecordByexpiredTime任务是用于删除测试记录的。当用户删除一条测试记录的时候,我们默认有一个存储时间为30天的回收站,当时间超过30天后就会被监听到,然后触发真正的删除记录的方法。删除包括了以下几个部分

  • 删除数据库中的测试文件记录信息
  • 删除文件服务器上的文件
  • 删除数据库中的测试规则记录信息
  • 删除数据库中的测试记录信息

NXRemoteServerProvider

这里采用NX二次开发的远程模式,对NX的Check-mate功能进行二次开发。远程模式最重要的就是获取NX 的Session对象。我们这里采用Java设计模式中的单例模式可以有效的获取Session对象,即保证了Session的重复获取,也保证了Session在高并发场景下的安全问题。

NX二次开发环境的搭建

我们这里采用Java来进行NX的二次开发,环境搭建必然是第一步,对于Java来说想要开发某一个功能我们必须要获取该功能的jar包。本项目也不例外,我们可以在NX的安装目录下(NX安装根目录/NXBIN)找到我们开发所需要的jar包。jar包名称如下:

NXOpen.jarNXOpenRun.jarNXOpenRemote.jarNXOpenUI.jarNXOpenUIRun.jarNXOpenUIRemote.jarNXOpenUF.jarNXOpenUFRun.jarNXOpenUFRemote.jar

我们将jar包复制一份保存到本地的某一个文件夹中,继续后续的操作。

由于项目采用SpringBoot搭建,默认使用的时Maven项目构建工具,因此需要把我们获取的jar包存储到我们本地的Maven仓库中进行保存。打开命令提示符,cd到上一步我们jar包保存的位置,执行以下代码:

mvn install:install-file -Dfile=NXOpen.jar -DgroupId=com.nx -DartifactId=NXOpen -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenRun.jar -DgroupId=com.nx -DartifactId=NXOpenRun -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenRemote.jar -DgroupId=com.nx -DartifactId=NXOpenRemote -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenUI.jar -DgroupId=com.nx -DartifactId=NXOpenUI -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenUIRun.jar -DgroupId=com.nx -DartifactId=NXOpenUIRun -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenUIRemote.jar -DgroupId=com.nx -DartifactId=NXOpenUIRemote -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenUF.jar -DgroupId=com.nx -DartifactId=NXOpenUF -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenUFRun.jar -DgroupId=com.nx -DartifactId=NXOpenUFRun -Dversion=1.0.0 -Dpackaging=jarmvn install:install-file -Dfile=NXOpenUFRemote.jar -DgroupId=com.nx -DartifactId=NXOpenUFRemote -Dversion=1.0.0 -Dpackaging=jar

项目添加依赖:

为了方便统以控制NX的jar包的版本因此我们定义一个属性来控制jar包的版本

<properties>    <NXOpen.version>1.0.0</NXOpen.version></properties>

导入jar包

<dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpen</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenRun</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenRemote</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenUF</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenUFRemote</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenUFRun</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenUI</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenUIRun</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency><dependency>    <groupId>com.nx</groupId>    <artifactId>NXOpenUIRemote</artifactId>    <version>${NXOpen.version}</version>    <scope>compile</scope></dependency>

NX远程服务

获取NX的Session,采用单例模式进行获取

@Slf4jpublic class SingleNxSession {    private volatile static  Session theSession=null;    // 双重检测锁模式的 懒汉式单例  DCL懒汉式    public static Session getInstance(){        log.info("获取NX Session实例");        if (theSession==null){//第一层加测            //锁            synchronized (SingleNxSession.class){                //第二层检测                if (theSession==null){                    NXRemotableObject.RemotingProtocol remotingProtocol = NXRemotableObject.RemotingProtocol.create();                    try {                        theSession = (Session) SessionFactory.get("Session", remotingProtocol);                    } catch (Exception e) {                        log.error("获取nx session失败--可能是服务器没有nx许可证,出错信息如下:");                        e.printStackTrace();                    }                }            }        }        return theSession;    }}

单例模式的DCL懒汉式说明:

Check-Mate测试进行方法封装

/*** 执行prt文件的测试** @param partSaveUrl    部件位置  如D:\\workplace\\nx\\prt\\model1.prt* @param rules          测试的规则  如%mqc_check_feature_rollback* @param resultFilesDir 测试结果保存的位置  如D:\\workplace\\nx\\log\\* @return int  返回结果位测试的状态* @author mumulx* @creed: mumulx编写* @email: [email protected]* @date 2020/9/12 16:46*/public int execute(Map<Integer, String> partSaveUrl, List<String> rules, String resultFilesDir) throws RemoteException, NXException {    //获取value集合---测试部件的存储位置    //不能强制转换    List<String> parts = partSaveUrl.values().stream().collect(Collectors.toList());    log.info("----开始部件检查");    Validation.Result result = null;    int rs = -1;    Session theSession = SingleNxSession.getInstance();    log.info("获取nxsession成功" + theSession);    nxopen.validate.Validator[] validators1;    validators1 = theSession.validationManager().findValidator("Check-Mate");    nxopen.validate.ValidatorOptions validatorOptions1;    validatorOptions1 = validators1[0].validatorOptions();    validatorOptions1.setSkipChecking(false);    validatorOptions1.setSkipCheckingDontLoadPart(false);    validatorOptions1.setSaveResultInTeamcenter(nxopen.validate.ValidatorOptions.SaveModeTypes.DO_NOT_SAVE);    validatorOptions1.setSavePartFile(nxopen.validate.ValidatorOptions.SaveModeTypes.DO_NOT_SAVE);    validatorOptions1.setSaveResultInPart(false);    //一个部件一个结果文件    validatorOptions1.setLogFileMode(nxopen.validate.ValidatorOptions.LogModeTypes.LOG_PER_PART);    //保存结果文件    validatorOptions1.setGenerateLogFile(true);    //结果文件保存位置    validatorOptions1.setLogFileDirectory(resultFilesDir);    validators1[0].clearPartNodes();    for (String s : parts) {        validators1[0].appendPartNode(s + ".prt");    }    for (String s : rules) {        validators1[0].appendCheckerNode("%" + s);    }    log.info("准备提交测试了");    result = validators1[0].commit();    if (Validation.Result.PASS == result) {        rs = Validation.Result._PASS;    } else if (result == Validation.Result.WARNING) {        rs = Validation.Result._WARNING;    } else if (result == Validation.Result.FAILED) {        rs = Validation.Result._FAILED;    } else if (result == Validation.Result.UNKNOWN) {        rs = Validation.Result._UNKNOWN;    } else if (result == Validation.Result.SKIPPED) {        rs = Validation.Result._SKIPPED;    } else {        rs = -1;    }    log.info("----=====文件最终测试结果为" + rs);    return rs;}

获取文件预览图

/** 获取部件的预览图* @author mumulx* @creed: mumulx编写* @email: [email protected]* @date 2020/11/5 16:11* @param partPath 文件在本地的存储位置--不加后缀:D:\workplace\nxdownload\9\122\285\model1* @return boolean**/private String getPrtPreviewImage(String partPath) throws NXException, IOException {    //获取session    Session theSession = SingleNxSession.getInstance();    //加载部件    theSession.parts().openActiveDisplay(partPath + ".prt", DisplayPartOption.ALLOW_ADDITIONAL);    Part workPart = theSession.parts().work();    //调整视图 ----好像没什么用    workPart.modelingViews().workView().orient(View.Canned.TRIMETRIC, View.ScaleAdjustment.FIT);    //获取预览图    BasePart.PreviewImageData previewImage = workPart.getPreviewImage();    //获取预览图数据    int height = previewImage.height;    int width = previewImage.width;    int[] pixels = previewImage.pixels;    //构建图片    Buf 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
AMapPoi: POI搜索工具、地理编码工具发布时间:2022-03-25
下一篇:
Vueopenlayers: Vue + openlayers地图展示基本功能发布时间:2022-03-25
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap