- 浏览: 207611 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
小月峰:
AppInitServlet 26行,取到的值为null,提示 ...
完整工作流JBPM项目实战全过程教程2---项目详细讲解 -
电竞杀神张无忌:
楼主可以留个联系方式?有问题要问你。
完整工作流JBPM项目实战全过程教程2---项目详细讲解 -
lvjingtao2005:
挺好学习了,继续关注
完整工作流JBPM项目实战全过程教程3----项目后续DIY -
lvjingtao2005:
...
完整工作流JBPM项目实战全过程教程3----项目后续DIY -
hello-world-1314:
折腾了两天 终于跑通了
完整工作流JBPM项目实战全过程教程2---项目详细讲解
继续上一篇。
当数据库建立完成后,下载源代码,部署到服务器后,即可以开始体验完整的JBPM+SSH应用了。
项目采用的是ssh+jbpm开发模式,而且,项目功能比较齐全,代码量比较大,所以,本教程就不介绍开发过程了。
如果你对SSH整合开发应用已经够熟悉了的话,相信本项目对你来说将并不会有多大难度 。
下面我们把重点放在JBPM上。当然你得先把项目部署成功,才好边做边理解jbpm是怎么在项目中管理流程的。
ok,假定你已经把项目跑起来了吧。
先以管理员manager登录系统,管理员具有添加新文章类型的权限。当你添加一个文章类型后,需要指定该类型的文章到时候是按哪个流程来进行审批的。你需要上传一个zip格式的流程定义文件文件(其中压缩了gpd.xml,processdifinition.xml,和processimage.jpg)。点击发布,系统转到articletypeaddsub.do,执行ArticleTypeAddSubAction.java
......
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.ProcessDefinition;
........
/**
*
* 增加文章类型操作Action类
*
* @struts.action path="/articletypeaddsub" scope="request" validate="false"
*/
public class ArticleTypeAddSubAction extends Action {
private static final Log log = LogFactory.getLog(MainAction.class);
/**
* JBPM服务接口实现对象
*/
private JbpmConfiguration jbpmConfiguration; //参见spring的配置文件applicationContext.xml
/**
* 文章类型服务接口实现对象
*/
private ArticleTypeService articleTypeService;
/**
* Method execute
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
log.debug("MainAction.execute()");
UploadDeployForm theForm = (UploadDeployForm) form;
FormFile file = theForm.getFiles();// 取得上传的文件
//得到JBPM环境
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
//解压zip文件流
ZipInputStream zipInputStream = new ZipInputStream(file
.getInputStream());
ProcessDefinition processDefinition = ProcessDefinition
.parseParZipInputStream(zipInputStream);
//发布流程文件
jbpmContext.deployProcessDefinition(processDefinition);
jbpmContext.close();
zipInputStream.close();
//增加文章类型
ArticleType articleType = new ArticleType();
articleType.setPdName(processDefinition.getName());
articleType.setTypeName(theForm.getTypeName());
articleTypeService.addArticleType(articleType);
} catch (IOException e) {
log.error("exception", e);
}
request.setAttribute("success","发布成功");
return mapping.findForward("success");
}
/**
* 得到JBPM服务接口实现对象
* @return jbpmConfiguration
*/
public JbpmConfiguration getJbpmConfiguration() {
return jbpmConfiguration;
}
/**
* 设置JBPM服务接口实现对象
* @param jbpmConfiguration
* 要设置的 jbpmConfiguration
*/
public void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) {
this.jbpmConfiguration = jbpmConfiguration;
}
/**
* 得到文章类型服务接口实现对象
* @return articleTypeService
*/
public ArticleTypeService getArticleTypeService() {
return articleTypeService;
}
/**
* 设置文章类型服务接口实现对象
* @param articleTypeService 要设置的 articleTypeService
*/
public void setArticleTypeService(ArticleTypeService articleTypeService) {
this.articleTypeService = articleTypeService;
}
}
执行到这步后,你可以去查看下数据库中表jbpm_processdifinition,你会发现表中多出里一条记录,并且名字就是你上传的压缩文件中processdifinition.xml中的name属性的值。其他的表也会有相应的变化,具体看字段的定义就会大概明白了。
好了,流程已经发布到了系统中了。当然你还可以增加其他的文章类型并且指定不同的流程定义。
我们退出系统,以guest用户登录系统,然后编写文章,这里需要说明的是,当你选择不同的文章类型后,该文章的审批过程就会与你刚才定义的执行流程相关了。
点击保存,
系统调用的ACTION为:
MyArticleAddSubAction.java
.........
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
........
/**
*
* 撰写文章操作Action类
* @struts.action path="/myarticleaddsub" scope="request" validate="false"
*/
public class MyArticleAddSubAction extends Action{
private static final Log log = LogFactory.getLog(MyArticleAddSubAction.class);
/**
* 文章服务接口实现对象
*/
private ArticleService articleService;
/**
* 文章类型服务接口实现对象
*/
private ArticleTypeService articleTypeService;
/**
* JBPM服务接口实现对象
*/
private JbpmConfiguration jbpmConfiguration;
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
log.debug("MyArticleAction.execute()");
UserSession userSesssion = UserSession.getSession(request, response);
//得到文章信息
String stypeNo = request.getParameter("typeNo");
int typeNo = ConvertUtil.convertInt(stypeNo);
String articleName = request.getParameter("articleName");
String content = request.getParameter("content");
Article article = new Article();
article.setArticleName(articleName);
article.setContent(content);
article.setState(Article.EDITED);
article.setTypeNo(new Integer(typeNo));
article.setUserNo(new Integer(userSesssion.getUserNo()));
//得到相应的文章类型
ArticleType articleType = articleTypeService.getArticleType(article.getTypeNo().intValue());
//得到相应的流程定义,启动流程实例
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition(articleType.getPdName());
ProcessInstance processInstance = new ProcessInstance(processDefinition);
//让流程往下进行一步
Token token = processInstance.getRootToken();
token.signal();
//保存流程实例与状态
jbpmContext.save(processInstance);
jbpmContext.save(token);
jbpmContext.close();
article.setPiId(processInstance.getId());
//增加文章
articleService.addArticle(article);
return mapping.findForward("success");
}
/**
* 得到文章服务接口实现对象
* @return articleService
*/
public ArticleService getArticleService() {
return articleService;
}
/**
* 设置文章服务接口实现对象
* @param articleService 要设置的 articleService
*/
public void setArticleService(ArticleService articleService) {
this.articleService = articleService;
}
/**
* 得到文章类型服务接口实现对象
* @return articleTypeService
*/
public ArticleTypeService getArticleTypeService() {
return articleTypeService;
}
/**
* 设置文章类型服务接口实现对象
* @param articleTypeService 要设置的 articleTypeService
*/
public void setArticleTypeService(ArticleTypeService articleTypeService) {
this.articleTypeService = articleTypeService;
}
/**
* 得到JBPM服务接口实现对象
* @return jbpmConfiguration
*/
public JbpmConfiguration getJbpmConfiguration() {
return jbpmConfiguration;
}
/**
* 设置JBPM服务接口实现对象
* @param jbpmConfiguration 要设置的 jbpmConfiguration
*/
public void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) {
this.jbpmConfiguration = jbpmConfiguration;
}
}
执行该action后,则就创建了一个与之匹配的流程实例。
查看数据库中article表的变化。可以发现
PiId记录了一个数字编号,同时jbpm_processinstance表中最大的一个id号与之匹配,这说明当保存文章时,系统后台创建了一个流程实例,该流程实例就是记录该文章的审批过程的JBPM实例。(你可以运行一个文章的审批全过程来跟踪与之匹配的流程实例变化情况)。
下一步就是发布该文章了。
到你的文章列表中点击“发布”。
系统调用ACTION:MyArticlePubAction.java继而转到MyArticlePubSubAction.java
.......
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
.........
/**
*
* 发布文章操作Action类
* @struts.action path="/myarticle" scope="request" validate="false"
*/
public class MyArticlePubAction extends Action{
private static final Log log = LogFactory.getLog(MyArticlePubAction.class);
private ArticleService articleService;
private ArticleTypeService articleTypeService;
private JbpmConfiguration jbpmConfiguration;
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
log.debug("MyArticleAction.execute()");
UserSession userSesssion = UserSession.getSession(request, response);
//得到文章信息
//得到文章号
String sarticleNo = request.getParameter("articleNo");
int articleNo = ConvertUtil.convertInt(sarticleNo);
Article article = articleService.getArticle(articleNo);
request.setAttribute("article", article);
//判断是否是此用户文章
if(article.getUserNo() != null && article.getUserNo().intValue() == userSesssion.getUserNo()){
//创建相应的流程实例
//得到相应的文章类型
ArticleType articleType = articleTypeService.getArticleType(article.getTypeNo().intValue());
request.setAttribute("articleType", articleType);
//得到相应的流程
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
ProcessInstance processInstance = jbpmContext.getProcessInstance(article.getPiId());
log.error("instance:" + processInstance.getId());
//得到当前的执行令牌
Token token = processInstance.getRootToken();
//得到当前的可执行转换
//Set transitions = token.getNode().getArrivingTransitions();
List transitions = token.getNode().getLeavingTransitions();
Set transitionnames = new HashSet();
if(transitions != null){
for(int i=0; i<transitions.size(); i++){
Transition transition = (Transition)transitions.get(i);
System.err.println("transition.getName()" + transition.getName());
transitionnames.add(transition.getName());
}
}
request.setAttribute("transitionnames", transitionnames);
jbpmContext.close();
}
return mapping.findForward("success");
}
public ArticleService getArticleService() {
return articleService;
}
public void setArticleService(ArticleService articleService) {
this.articleService = articleService;
}
public JbpmConfiguration getJbpmConfiguration() {
return jbpmConfiguration;
}
public void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) {
this.jbpmConfiguration = jbpmConfiguration;
}
public ArticleTypeService getArticleTypeService() {
return articleTypeService;
}
public void setArticleTypeService(ArticleTypeService articleTypeService) {
this.articleTypeService = articleTypeService;
}
}
ok,到这里,你仍然可以去查看数据库中article表的变化情况。你会发现表中的Auditstate字段
由null变成了一级审批,这是为什么,因为该文章对应的流程的下一个节点就是一级审批。
然后我们以one(一级审批)用户登录,就可以看到需要一级审批用户审批的文章列表了。
需要说明的是:这些文章是按照登录用户的权限来显示的,只要是该权限级别的用户,就可以看到系统中所有的Auditstate为该状态(权限名和状态名相同,方便查询)的文章article了 。
执行相关的审批操作。继续调用相应的action,然后按照流程定义,一直执行下去,知道该文章的审批流程结束(这里就不再一一说明了)。
OK,流程执行完成。一个完整的JBPM实例执行结束。
思考的问题来了!
我们并不知道articl表中的Auditstate是怎么变化的啊?
在Struts的action中并没有看见显示的代码调用来修改数据库Auditstate字段啊,难道是JBPM自动做的处理?
当然不是!不过我们可以让JBPM帮助我们来完成。
你注意到了processdefinition.xml配置文件吗?
-<state name="编辑完成">
-<transition name="发布" to="一级审批">
<action name="action" class="c20.jbpm.action.PubActionHandler" />
</transition>
</state>
没错,就是<action name="action" class="c20.jbpm.action.PubActionHandler" /> 的功劳。
当一个流程中一个state执行完,需要transition 到下一个State时,JBPM将会自动执行class指定的句柄。
.......
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.def.Node;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
........
/**
* 文章发布处理器
* @author yuxd
*
*/
public class PubActionHandler implements ActionHandler {
private static final long serialVersionUID = 1L;
/**
* A message process variable is assigned the value of the message
* member. The process variable is created if it doesn't exist yet.
*/
public void execute(ExecutionContext context) throws Exception {
//得到对应实例ID
ProcessInstance processInstance = context.getContextInstance().getProcessInstance();
//得到当前执行转换
Transition transition = context.getTransition();
Node node = transition.getTo();
//得到对应的文章
ArticleService articleService = (ArticleService)BeanFactory.getBean("articleService");
List list = articleService.getArticlesByPdInstance(processInstance.getId());
//设置文章状态为发布中
if(list != null){
for(int i=0; i<list.size(); i++){
Article article = (Article)list.get(i);
if(article.getState() != null && article.getState().intValue() == Article.EDITED){
article.setState(new Integer(Article.PUBLISH));
article.setAuditState(node.getName());
articleService.modArticle(article);
}
}
}
}
}
由此,可以得知,JBPM中句柄是怎么在流程运作的过程中对业务数据做出处理的吧!,这也正是JBPM句柄的作用之所在!
到这里,JBPM的具体应用就介绍的已经很详细了。
下面来说说项目中是怎么巧妙的将业务和JBPM流程结合使用的吧。
我们来看看业务表article的结构,
article CREATE TABLE `article` (
`ArticleNo` int(11) NOT NULL auto_increment COMMENT '文章号',
`UserNo` int(11) default NULL COMMENT '用户号',
`TypeNo` int(11) default NULL COMMENT '文章类型号',
`ArticleName` varchar(128) default NULL COMMENT '文章名称',
`Content` text COMMENT '文章内容',
`PiId` bigint(20) default NULL COMMENT '对应流程实例号',
`AuditState` varchar(64) default NULL COMMENT '审批状态',
`AuditComment` varchar(255) default NULL COMMENT '审批说明',
`State` int(11) default NULL COMMENT '文章状态',
PRIMARY KEY (`ArticleNo`),
KEY `FK_Relationship_1` (`TypeNo`),
KEY `FK_Relationship_2` (`UserNo`),
CONSTRAINT `FK_Relationship_1` FOREIGN KEY (`TypeNo`) REFERENCES `articletype` (`TypeNo`),
CONSTRAINT `FK_Relationship_2` FOREIGN KEY (`UserNo`) REFERENCES `user` (`UserNo`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=gb2312 COMMENT='文章表'
不然看出,恰恰是表中的 `PiId` bigint(20) default NULL COMMENT '对应流程实例号字段,完美的和流程的ID映射起来,使得一篇文章绑定到一个具体的流程实例。并且文章的状态在流程的运作当中利用JBPM句柄ActionHandler动态变化。最终实现业务的运作。
so,JBPM在web项目中的具体应用就介绍完了。希望通过本教程学习的朋友,能够得到确实的提高。并且在教程中的一些个人拙见,望大侠们积极的批正!
- 项目源代码(全,不含jar包).rar (353.7 KB)
- 下载次数: 3379
- 项目用到的JAR包1.rar (6 MB)
- 下载次数: 3665
- 项目用到的JAR包2.rar (5.9 MB)
- 下载次数: 2798
- 项目用到的JAR包3.rar (8.1 MB)
- 下载次数: 2794
- spring-modules-jbpm31.jar (30.3 KB)
- 描述: 似乎少了这个包
- 下载次数: 1586
评论



找到了
E:\workspacejbpm\zpchen\项目源代码(全,不含jar包).rar=>source\articleaudit\WebContent\articleauditlistenter.jsp Trojan.IFrame.G 已删除
E:\workspacejbpm\zpchen\项目源代码(全,不含jar包).rar=>source\articleaudit\WebContent\articletypeenter.jsp Trojan.IFrame.G 已删除
E:\workspacejbpm\zpchen\项目源代码(全,不含jar包).rar=>source\articleaudit\WebContent\myarticleenter.jsp Trojan.IFrame.G 已删除
E:\workspacejbpm\zpchen\项目源代码(全,不含jar包).rar=>source\articleaudit\WebContent\myarticlelistenter.jsp Trojan.IFrame.G 已删除
E:\workspacejbpm\zpchen\项目源代码(全,不含jar包).rar=>source\articleaudit\WebContent\userdutyenter.jsp Trojan.IFrame.G 已删除
E:\workspacejbpm\zpchen\项目源代码(全,不含jar包).rar=>source\articleaudit\WebContent\userenter.jsp Trojan.IFrame.G 已删除
我把这个工程导入到MyEclipse中,怎么不能发布呢?请指教。
不能正常解压 !!
出现错误提示:
信息: validateJarFile(E:\workspace\jbpm4\WebRoot\WEB-INF\lib\javax.servlet_2.4.0.v200706111738.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
2008-10-31 16:42:30 org.apache.catalina.core.StandardContext filterStart
严重: Exception starting filter gbkFilter
java.lang.ClassNotFoundException: c20.helper.GbkFilter
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:249)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3709)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4363)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
2008-10-31 16:42:30 org.apache.catalina.core.StandardContext start
严重: Error filterStart
LZ,我的下载忒慢了 ```,有时间你给我发一个吧``谢谢!
e-Mail:illun_j2ee@163.com
发表评论
-
谈谈JBPM几种节点的不同用法及适合的应用场景
2008-11-08 21:20 6780最近都在学习JBPM的东西,发现用起来还真不是那么的 ... -
完整工作流JBPM项目实战全过程教程4----关于Spring整合jbpm时页面显示流程图出错处理
2008-11-05 15:48 6514在原来项目的基础上来实现流程图动态显示的功能,发现利 ... -
揭秘jbpm流程引擎内核设计思想及构架(经典之作,收藏之)
2008-10-28 20:13 8502申明:偶然发现一篇很精辟的JBPM文章,觉得写得甚好,故收 ... -
完整工作流JBPM项目实战全过程教程3----项目后续DIY
2008-10-28 16:37 6666接着上一篇。 从数据库中表的定义不难看出,每篇文章的审批 ... -
完整工作流JBPM项目实战全过程教程1---准备工作
2008-10-26 01:02 38087偶然机会,认识 ...
相关推荐
JBPM,全称是Java Business Process Management,是一款开源的工作流管理系统,由JBoss组织开发。本教程旨在通过一个具体的Struts+Hibernate+Spring+JBPM的文章审批系统项目,详细介绍JBPM的实战应用。 首先,对于...
通过本教程的学习,读者可以全面了解JBPM的基本概念、安装配置过程以及如何基于JBPM开发实际项目中的工作流应用。无论是初学者还是有一定经验的开发者,都能够从中获得有价值的信息和技术指导。希望读者能够在实践中...
### JBPM实战讲解知识点概述 #### 一、JBPM概览与重要性 JBPM,全称为Java Business Process Management,是JBoss旗下的一款强大的工作流和业务流程管理框架。它旨在帮助企业通过自动化业务流程,提高效率和灵活性...
绘制箱型图所用到的数据
# 基于PythonFastAPI框架的桌面管理系统 ## 项目简介 本项目是一个基于FastAPI框架搭建的桌面管理系统。它集成了Pydantic进行数据验证和类型安全保障,SQLAlchemy实现数据库操作,Dynaconf完成配置管理。系统涵盖用户管理、桌面管理、日志管理、数据库迁移、异常处理以及API测试等多个模块,能够为用户提供创建、查询、更新和删除桌面等功能。 ## 项目的主要特性和功能 1. 用户管理支持用户的创建、获取、更新和删除操作,同时可对用户信息进行查询和修改。 2. 桌面管理实现桌面的基本信息和状态管理,包括创建、查询、更新和删除桌面。 3. 日志管理记录操作的详细信息、时间戳、用户信息和操作结果等,支持日志的查询和记录。 4. 数据库迁移利用Alembic库进行数据库迁移,可对数据库结构进行变更和版本控制。 5. 异常处理定义多个自定义异常类,处理特定错误情况,如身份验证失败、资源未找到等。
房地产活动策划 -常州花博会 花的知识.pptx
面向个人开发人员的 Autumoon 代码库标准版。
内容概要:本文详细介绍了基于非线性磁链观测器的永磁同步电机(PMSM)转子位置估计方法及其在无传感器磁场定向控制(FOC)中的应用。主要内容涵盖相电压重构、相位补偿、观测器离散化建模以及稳定性分析。文中提供了具体的MATLAB代码片段,展示了如何处理PWM开关噪声、优化相位补偿算法、选择合适的非线性增益,并确保系统的稳定性。此外,还讨论了将MATLAB代码移植到嵌入式平台(如STM32F4)的关键技术和注意事项。 适合人群:从事电机驱动控制系统设计的研发工程师和技术人员,尤其是对无传感器控制感兴趣的从业者。 使用场景及目标:适用于需要提高永磁同步电机在低速和零速工况下转子位置估计精度的应用场合,如家电、工业自动化等领域。目标是实现高精度的位置估计,减少对外部传感器的依赖,提升系统的鲁棒性和可靠性。 其他说明:文中提到的技术细节对于理解和实现高性能无传感器FOC控制至关重要。建议读者结合实际项目进行深入研究和实践,特别是在参数调整和稳定性验证方面。
内容概要:本文详细介绍了一种基于MATLAB的疲劳驾驶检测系统的实现过程。该系统通过计算机视觉和数字图像处理技术,从视频处理开始,逐步实现了视频分帧、有效区域提取、人脸定位、人眼区域分割、二值化处理、边缘提取、去噪、闭眼率计算等功能,并最终通过GUI界面展示了检测结果。系统的核心在于通过对驾驶员的眼睛状态进行监测,从而及时发现疲劳驾驶现象,提高道路安全性。 适合人群:对计算机视觉、图像处理感兴趣的开发者和技术爱好者,尤其是有一定MATLAB基础的研究人员。 使用场景及目标:适用于交通安全管理领域,旨在通过监控驾驶员的眼睛状态,预防因疲劳驾驶引发的交通事故。具体应用场景包括但不限于长途运输、出租车管理、私家车安全辅助等。 其他说明:文中提供了详细的代码示例和优化技巧,如使用行列投影法分割人眼区域、采用自适应阈值进行二值化处理等。此外,系统还具备良好的可扩展性,支持远程调试和运行,能够根据实际需求灵活添加新功能。
# 基于Qt框架的Qt Designer插件封装工具 ## 项目简介 本项目是一个使用Qt框架开发的Qt Designer插件封装工具。它允许Qt开发者将自定义组件封装为Qt Designer插件,使得这些自定义组件能够像Qt基础组件一样在Qt Designer中直接使用。该工具提供了一套简单明了的流程,帮助开发者轻松地将自定义组件封装为Qt Designer插件。 ## 项目的主要特性和功能 1. 封装自定义组件工具支持将已开发的自定义组件封装为Qt Designer插件,使这些组件能够在Qt Designer中直接使用。 2. 支持多种Qt组件类型工具支持各种Qt组件类型,如按钮、文本框、滑块等,以及其他自定义类型的组件。 3. 自定义组件管理工具提供了一个友好的界面,用于管理已封装的自定义组件,包括添加、编辑和删除组件。 4. 生成插件代码工具自动生成Qt Designer插件所需的代码和文件,包括必要的接口定义和代码实现。
# 基于Spring Boot的翻译与语音合成系统 ## 项目简介 本项目是一个基于Spring Boot框架的翻译与语音合成系统,旨在通过调用百度翻译API实现多种语言的翻译功能,并支持将翻译结果进行语音朗读。系统还集成了用户登录和注册功能,使用户能够个性化使用翻译服务。 ## 项目的主要特性和功能 1. 翻译功能 支持多种语言的翻译,通过调用百度翻译API实现。 提供HTTP GET请求封装,方便与百度翻译API进行交互。 2. 语音合成 支持将翻译结果转换为语音输出,增强用户体验。 3. 用户管理 提供用户登录和注册功能,确保用户数据的安全性和个性化服务。 4. 安全性 使用MD5加密技术对敏感信息进行加密处理,确保数据传输的安全性。 ## 安装使用步骤 1. 复制项目 bash 2. 配置环境
# 基于Arduino和蓝牙的智能小车控制系统 ## 项目简介 本项目是一个基于Arduino的智能小车控制系统,通过蓝牙模块HC06与Android应用进行通信,实现对小车的远程控制。用户可以通过Android应用上的按钮来控制小车的前进、后退、左转、右转和停止。 ## 项目的主要特性和功能 远程控制通过Android应用实现对小车的远程控制。 蓝牙通信使用蓝牙模块HC06进行设备间的通信。 电机驱动采用L298N电机驱动模块控制小车的两个直流电机。 多功能控制支持前进、后退、左转、右转和停止等基本操作。 ## 安装使用步骤 1. 硬件组装 将所有组件安装在底盘上。 连接蓝牙模块HC06的VCC引脚到Arduino Uno的5V引脚。 连接蓝牙模块HC06的GND引脚到Arduino Uno的GND引脚。 连接蓝牙模块HC06的TXD引脚到Arduino Uno的数字引脚3。
内容概要:本文详细介绍了如何使用Python复现轴承动力学模型,重点关注内圈质心运动轨迹的计算。首先解析了核心微分方程,特别是非线性赫兹接触力的计算方法。接着展示了如何通过自定义四阶龙格库塔法求解微分方程,并讨论了常见陷阱如绝对值和符号函数的处理。文中还提供了详细的参数设置指导,包括质量、刚度、阻尼系数等,并强调了无量纲化处理的重要性。最后,通过Matplotlib进行了结果可视化,展示了不同转速下的运动轨迹和接触力时域图,揭示了系统的周期性和混沌特征。 适合人群:机械工程专业学生、从事机械设备故障诊断的研究人员以及对非线性动力学感兴趣的工程师。 使用场景及目标:①用于教学,帮助学生理解轴承内部复杂的力学关系;②作为科研工具,辅助研究人员探索轴承的动力学特性及其故障机理;③为企业提供理论支持,优化轴承设计和维护策略。 其他说明:文中提供的完整代码已托管在GitHub上,方便读者下载和实验。建议读者从简单的参数调整入手,逐步深入理解模型的工作原理。
# 基于ESP32的TinyCI Hub项目 ## 项目简介 TinyCI Hub(Tiny Communication Infrastructure Hub)是一个用于物联网(IoT)的中间件解决方案,旨在桥接IoT设备与Web平台之间的通信。通过高效地收集来自IoT设备传感器的数据,并将其传输到Web平台进行处理和分析,TinyCI Hub实现了边缘设备与Web平台的无缝连接。 ## 主要特性和功能 1. 设备发现通过扫描整个IP子网自动注册边缘设备到Hub,实现设备的自动发现和配置。 2. 配置管理允许用户通过MQTT协议对设备进行远程配置和管理。 3. 数据通信实现边缘设备与Web平台之间的数据通信,通过MQTT协议传输传感器数据。 4. WebSocket通信支持WebSocket协议,用于实时数据交互和通知。 ## 安装使用步骤 1. 下载源码下载并解压项目源码文件。 2. 硬件准备连接ESP32开发板,确保硬件要求满足项目需求。
内容概要:本文详细探讨了虚拟同步发电机(VSG)并网控制系统中小信号建模的重要性和具体实现方法。首先介绍了VSG技术在分布式发电和微电网领域的应用背景及其优势,强调了小信号建模对于评估系统稳定性和并网控制性能的基础作用。接着,通过具体的Matlab Simulink建模实例展示了如何构建VSG小信号模型,包括模型组件的选择、仿真参数的设定以及结果的分析与保存。文中还深入讨论了功率回路动态特性的线性化处理,特别是惯性时间和阻尼系数的影响,并提供了多个代码示例来辅助理解和实践。此外,文章分享了一些实用的经验技巧,如离散化控制器的设计、PWM载波频率与控制器采样率的匹配、阻抗扫描法的应用等。 适用人群:从事电力系统自动化、分布式能源管理和微电网技术研发的专业人士,尤其是对VSG技术和小信号建模感兴趣的工程师和技术研究人员。 使用场景及目标:①帮助读者掌握VSG并网控制系统的工作原理;②指导读者利用Matlab Simulink平台完成VSG小信号建模;③提高读者对VSG系统参数选择的理解,从而优化控制器设计。 其他说明:文章不仅提供了详细的理论推导和仿真案例,还结合实际操作中的常见问题给出了针对性的解决方案,旨在为相关领域的从业者提供全面的技术支持。
mac 虚拟机
# 基于Django框架的个人博客 ## 项目简介 这是一个基于Django框架的个人博客项目,旨在为用户提供一个简单易用的博客平台。项目包括后台管理界面和前台展示功能,使用MySQL数据库存储数据,并集成了CKEditor富文本编辑器,方便用户创建和编辑博客内容。 ## 项目的主要特性和功能 1. 博客创建与管理 通过后台管理界面创建、编辑和删除博客文章。 支持设置博客标题、内容、类型等信息。 管理博客类型和用户信息。 2. 博客浏览 用户可以通过前台页面浏览博客文章。 支持按类型、日期等分类查看博客文章。 3. 富文本编辑 使用CKEditor富文本编辑器,支持插入图片、链接等富文本内容。 4. 分页与排序 博客文章列表支持分页显示。 按创建时间降序排序。 ## 安装使用步骤 1. 安装依赖 确保已安装Python和Django。
内容概要:报告深入分析了2024年中国美妆个护跨境电商的发展现状与趋势。首先,概述了中国美妆个护行业的总体趋势,指出2023年国内化妆品零售额达4142亿元,同比增长5.1%,出口额为65.1亿美元,同比增长16.7%。产业集群已形成,如上海的“东方美谷”和广州的“白云美湾”。其次,报告详细探讨了中国美妆个护外贸趋势,特别是出口市场和品类,广东省在出口中占据领先地位,出口额达22.8亿美元,占全国35%。再次,聚焦亚马逊平台,作为跨境电商的龙头,亚马逊拥有超过3.1亿活跃客户,占据美国市场37.6%的份额。报告还提到,2024年Q1亚马逊彩妆和身体护理产品快速占领榜单,基础护肤品类份额被挤占,产品均价略有下跌。最后,强调了品牌建设和渠道控制的重要性,建议商家注重品牌推广,如利用TikTok和线下活动进行营销。 适合人群:从事或关注美妆个护跨境电商的企业主、运营人员、市场营销人员以及相关研究人员。 使用场景及目标:①了解中国美妆个护行业的最新发展动态和出口趋势;②掌握亚马逊平台的市场表现和竞争格局;③学习品牌推广和渠道管理的最佳实践,以提高跨境电商的盈利能力。 其他说明:报告引用了大量权威数据和案例,提供了详实的参考依据,帮助从业者更好地把握市场机会并制定有效的营销策略。
题目:多方位车距监测系统的设计与实现 主控:STM32 显示:oled 超声波*4 声光报警 按键 功能: 1.实时显示相关数据 2.任意一个方向距离障碍物距离低于阈值,启动声光报警 3.阈值可以按键修改