当前位置: 首页 > news >正文

怎么给做的网站做百度搜索/怎么创建一个网址

怎么给做的网站做百度搜索,怎么创建一个网址,网站功能建设模块,聚名网是什么平台原项目中用到了工作流引擎,使用若依框架开发, 原二开使用项目:https://gitee.com/y_project/RuoYi-Vue 基于activiti7地址:https://gitee.com/smell2/ruoyi-vue-activiti 导入模块到原二开项目中 使用步骤 admin导入bpmn文件&am…

原项目中用到了工作流引擎,使用若依框架开发,
原二开使用项目:https://gitee.com/y_project/RuoYi-Vue
基于activiti7地址:https://gitee.com/smell2/ruoyi-vue-activiti
导入模块到原二开项目中

使用步骤

  1. admin导入bpmn文件,或者绘制工作流,并激活。
  2. post为普通员工进入我的审批可以查看所有审批(经销商角色)
  3. 数据会存入历史表和任务表
    在这里插入图片描述
  4. 历史表展现全部任务数据,task会展示对应岗位的相应条数据
  5. 登录商管账号,进入代办任务
  6. 进行审批,通过则状态变为“待财务审核”,进入下一节点;不通过则状态变为“审核失败”,流转结束
  7. 登录财务账号,进入代办任务
  8. 进行审批,通过则状态变为“审核成功”,流转结束;不通过则状态变为“审核失败”,流转结束
  9. 经销商可以查看审批,流转完成

注意事项

在这里插入图片描述
工作流程菜单在开发工具查看(没有的话需要事先插入db和相关代码),在线绘制进行bpmn格式的流程图,部署流程导入已经存在的bpmn文件,根据流程key,在java中进行声明和调用该key即可正式使用该工作流

后端相关

activiti7相关依赖

<dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.1.0.M4</version>
</dependency>
<dependency><groupId>org.activiti.dependencies</groupId><artifactId>activiti-dependencies</artifactId><version>7.1.0.M4</version><type>pom</type>
</dependency>

解决依赖冲突
activiti7新版本会和mybatis和spring security起冲突,如果项目使用shiro等安全框架会有更大的适配问题
原项目有spring security的情况下需加上配置文件属性

main:allow-bean-definition-overriding: true

activity配置文件属性如下,包括检测流程定义,自动更新和生成db系统表,历史数据级别和使用等

activiti:check-process-definitions: falsedatabase-schema-update: truehistory-level: fulldb-history-used: true

db依赖问题或mybatis版本冲突解决方法如下

<exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions>

数据源配置,给url加上如下后缀属性

%2B8&nullCatalogMeansCurrent=true

完整url格式如下:

url: jdbc:mysql://localhost:99999/test11111111?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true

在使用mysql-connect 8.+以上版本的时候需要添加***nullCatalogMeansCurrent=true***参数,否则在使用mybatis-generator生成表对应的xml等时会扫描整个服务器里面的全部数据库中的表,而不是扫描对应数据库的表。因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。

接口

流程部署
在这里插入图片描述

可以将bpmn文件放在resource下的processes目录下,activiti启动的时候会自动加载该目录下的bpmn文件,或者通过调用接口方式部署:

  • 上传文件部署
@PostMapping("/uploadFileAndDeployment")
public BaseResponse uploadFileAndDeployment(@RequestParam("processFile")MultipartFile processFile,@RequestParam(value = "processName",required = false) String processName){String originalFilename = processFile.getOriginalFilename();String extension = FilenameUtils.getExtension(originalFilename);if (processName != null){processName = originalFilename;}try {InputStream inputStream = processFile.getInputStream();Deployment deployment = null;if ("zip".equals(extension)){// 压缩包部署方式ZipInputStream zipInputStream = new ZipInputStream(inputStream);deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).name(processName).deploy();}else if ("bpmn".equals(extension)){// bpmn文件部署方式deployment = repositoryService.createDeployment().addInputStream(originalFilename,inputStream).name(processName).deploy();}return BaseResponse.success(deployment);} catch (IOException e) {e.printStackTrace();}return BaseResponse.success();
}
  • 上传BPMN内容字符串部署
 @PostMapping("/postBPMNAndDeployment")
public BaseResponse postBPMNAndDeployment(@RequestBody AddXMLRequest addXMLRequest){Deployment deploy = repositoryService.createDeployment()// .addString 第一次参数的名字如果没有添加.bpmn的话,不会插入到 ACT_RE_DEPLOYMENT 表中.addString(addXMLRequest.getProcessName()+".bpmn", addXMLRequest.getBpmnContent()).name(addXMLRequest.getProcessName()).deploy();return BaseResponse.success(deploy);
}
  • 获取流程资源文件
@GetMapping("/getProcessDefineXML")
public void getProcessDefineXML(String deploymentId, String resourceName, HttpServletResponse response){try {InputStream inputStream = repositoryService.getResourceAsStream(deploymentId,resourceName);int count = inputStream.available();byte[] bytes = new byte[count];response.setContentType("text/xml");OutputStream outputStream = response.getOutputStream();while (inputStream.read(bytes) != -1) {outputStream.write(bytes);}inputStream.close();} catch (Exception e) {e.toString();}
}

流程实例

  • 启动
@PostMapping("/startProcess")
public BaseResponse startProcess(String processDefinitionKey, String instanceName,@AuthenticationPrincipal LocalUserDetail userDetail){ProcessInstance processInstance = null;try{StartProcessPayload startProcessPayload = ProcessPayloadBuilder.start().withProcessDefinitionKey(processDefinitionKey).withBusinessKey("businessKey").withVariable("sponsor",userDetail.getUsername()).withName(instanceName).build();processInstance = processRuntime.start(startProcessPayload);}catch (Exception e){System.out.println(e);return BaseResponse.error("开启失败:"+e.getLocalizedMessage());}return BaseResponse.success(processInstance);
}
  • 挂起
@PostMapping("/suspendInstance/{instanceId}")
public BaseResponse suspendInstance(@PathVariable String instanceId){ProcessInstance processInstance = processRuntime.suspend(ProcessPayloadBuilder.suspend().withProcessInstanceId(instanceId).build());return BaseResponse.success(processInstance);
}
  • 激活
@PostMapping("/resumeInstance/{instanceId}")
public BaseResponse resumeInstance(@PathVariable String instanceId){ProcessInstance processInstance = processRuntime.resume(ProcessPayloadBuilder.resume().withProcessInstanceId(instanceId).build());return BaseResponse.success(processInstance);
}

任务数据

  • 通过taskid完成任务
@PostMapping("/completeTask/{taskId}")
public BaseResponse completeTask(@PathVariable String taskId){Task task = taskRuntime.task(taskId);if (task.getAssignee()==null){// 说明任务需要拾取taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(taskId).build());}taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskId).build());return BaseResponse.success();
}
  • 获取自己的任务(与鉴权机制挂钩)
@GetMapping("/getTasks")
public BaseResponse getTasks(){Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 100));List<Task> tasks = taskPage.getContent();List<TaskVO> taskVOS = new ArrayList<>();for (Task task : tasks) {TaskVO taskVO = TaskVO.of(task);ProcessInstance instance = processRuntime.processInstance(task.getProcessInstanceId());taskVO.setInstanceName(instance.getName());taskVOS.add(taskVO);}return BaseResponse.success(taskVOS);
}

历史数据

  • 查询
public List<HistoricActivityInstanceVO> getProcessHistoryByBusinessKey(String businessKey) {ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(instance.getId()).orderByHistoricActivityInstanceStartTime().asc().list();List<HistoricActivityInstanceVO> historicActivityInstanceVOList = new ArrayList<>();historicActivityInstanceList.forEach(historicActivityInstance -> historicActivityInstanceVOList.add(VOConverter.getHistoricActivityInstanceVO(historicActivityInstance)));return historicActivityInstanceVOList;
}
  • 详情查询
HistoricDetailQuery historicDetailQuery = historyService.createHistoricDetailQuery();
List<HistoricDetail> historicDetails = historicDetailQuery.processInstanceId(instanceId).orderByTime().list();
for (HistoricDetail hd: historicDetails) {System.out.println("流程实例ID:"+hd.getProcessInstanceId());System.out.println("活动实例ID:"+hd.getActivityInstanceId());System.out.println("执行ID:"+hd.getTaskId());System.out.println("记录时间:"+hd.getTime());
}
  • 历史流程实例查询
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
List<HistoricProcessInstance> processInstances = historicProcessInstanceQuery.processDefinitionId(processDefinitionId).list();
for (HistoricProcessInstance hpi : processInstances) {System.out.println("业务ID:"+hpi.getBusinessKey());System.out.println("流程定义ID:"+hpi.getProcessDefinitionId());System.out.println("流程定义Key:"+hpi.getProcessDefinitionKey());System.out.println("流程定义名称:"+hpi.getProcessDefinitionName());System.out.println("流程定义版本:"+hpi.getProcessDefinitionVersion());System.out.println("流程部署ID:"+hpi.getDeploymentId());System.out.println("开始时间:"+hpi.getStartTime());System.out.println("结束时间:"+hpi.getEndTime());
}
  • 任务历史查询(某一次流程的执行经历的多少任务)
HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
List<HistoricTaskInstance> taskInstances = historicTaskInstanceQuery.taskId(taskId).list();
for (HistoricTaskInstance hti : taskInstances) {System.out.println("开始时间:"+hti.getStartTime());System.out.println("结束时间:"+hti.getEndTime());System.out.println("任务拾取时间:"+hti.getClaimTime());System.out.println("删除原因:"+hti.getDeleteReason());
}

github例子:https://github.com/Activiti/activiti-examples

鉴权机制

官方security轮子

@Component
public class SecurityUtil {// 模拟调用了SpringSecurity 登录鉴权private Logger logger = LoggerFactory.getLogger(SecurityUtil.class);@Autowiredprivate UserDetailsService userDetailsService;public void logInAs(String username) {UserDetails user = userDetailsService.loadUserByUsername(username);if (user == null) {throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");}logger.info("> Logged in as: " + username);SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return user.getAuthorities();}@Overridepublic Object getCredentials() {return user.getPassword();}@Overridepublic Object getDetails() {return user;}@Overridepublic Object getPrincipal() {return user;}@Overridepublic boolean isAuthenticated() {return true;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {} @Overridepublic String getName() {return user.getUsername();}}));org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);}
}

与原项目spring security整合
新api包括taskRuntime和processRuntime都会强制使用security,源码使用了如下注解:
@PreAuthorize(“hasRole(‘ACTIVITI_USER’)”)
直接使用接口会导致无权限不允许访问

activiti7中对原有的一些接口做了二次封装,从而进一步简化了用户的使用流程。
通过查看这个两个API的实现类源码来看,调用的话需要调用的用户含有ACTIVITI_USER角色权限。所以,如果没有使用SpringSecurity的话,这两个API便不能直接调用。

  • 先在用户验证处理中插入GROUP_的岗位post和加入ACTIVITI_USER的role
public UserDetails createLoginUser(SysUser user)
{Set<String> postCode = sysPostService.selectPostCodeByUserId(user.getUserId());postCode = postCode.parallelStream().map( s ->  "GROUP_" + s).collect(Collectors.toSet());postCode.add("ROLE_ACTIVITI_USER");List<SimpleGrantedAuthority> collect = postCode.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());return new LoginUser(user, permissionService.getMenuPermission(user), collect);//return new LoginUser(user, permissionService.getMenuPermission(user));
}
  • 在login controller中,每次登录的时候鉴权
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));

最后将信息放入token中处理

if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{tokenService.verifyToken(loginUser);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
  • SecurityConfig也别忘记配
httpSecurity// CSRF禁用,因为不使用session.csrf().disable()// 认证失败处理类.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()// 基于token,所以不需要session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 过滤请求.authorizeRequests()// 对于登录login 验证码captchaImage 允许匿名访问.antMatchers("/ssologin/token", "/ssologin","/login", "/captchaImage","/getssourl","/ssologin").anonymous().antMatchers(HttpMethod.GET,"/*.html","/**/*.html","/**/*.css","/**/*.js").permitAll().antMatchers("/processDefinition/**").permitAll().antMatchers("/activitiHistory/**").permitAll().antMatchers("/profile/**").anonymous().antMatchers("/common/download**").anonymous().antMatchers("/common/download/resource**").anonymous().antMatchers("/swagger-ui.html").anonymous().antMatchers("/swagger-resources/**").anonymous().antMatchers("/webjars/**").anonymous().antMatchers("/*/api-docs").anonymous().antMatchers("/druid/**").anonymous()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated().and().headers().frameOptions().disable();
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加JWT filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

查询当前用户任务

  • taskservice方法
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到TaskService对象
TaskService taskService = processEngine.getTaskService();
//3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询Task task = taskService.createTaskQuery().processDefinitionKey("holiday").taskAssignee(SecurityUtils.getUsername() //通过鉴权拿到当前角色).singleResult();
//4.任务列表的展示System.out.println("流程实例ID:"+task.getProcessInstanceId());System.out.println("任务ID:"+task.getId());  //5002System.out.println("任务负责人:"+task.getAssignee());System.out.println("任务名称:"+task.getName());
  • taskruntime方法(新版本api)
    通过taskRuntime.tasks获取任务列表并分页,在实例化一条工作流后,activiti会将数据存到ACT_RU_TASK和ACT_RU_IDENTITYLINK表中,IDENTITYLINK通过task_id作为外键关联TASK表,IDENTITYLINK根据用户身份鉴别相应的角色,通过GROUP_ID筛选出对应数据,TYPE_字段则显示该角色是参与者还是贡献者,db如下:
    在这里插入图片描述
    若衣源码:
@Override
public Page<ActTaskDTO> selectProcessDefinitionList(PageDomain pageDomain) {	Page<ActTaskDTO> list = new Page<ActTaskDTO>();org.activiti.api.runtime.shared.query.Page<Task> pageTasks = taskRuntime.tasks(Pageable.of((pageDomain.getPageNum() - 1) * pageDomain.getPageSize(), pageDomain.getPageSize()));List<Task> tasks = pageTasks.getContent();int totalItems = pageTasks.getTotalItems();list.setTotal(totalItems);if (totalItems != 0) {Set<String> processInstanceIdIds = tasks.parallelStream().map(t -> t.getProcessInstanceId()).collect(Collectors.toSet());List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdIds).list();List<ActTaskDTO> actTaskDTOS = tasks.stream().map(t -> new ActTaskDTO(t, processInstanceList.parallelStream().filter(pi -> t.getProcessInstanceId().equals(pi.getId())).findAny().get())).collect(Collectors.toList());list.addAll(actTaskDTOS);}return list;
}

实际项目遇到的问题及解决方法

Error updating database. Cause: java.sql.SQLSyntaxErrorException: Unknown column ‘VERSION_’ in ‘field list’
Error updating database. Cause: java.sql.SQLSyntaxErrorException: Unknown column ‘PROJECT_RELEASE_VERSION_’ in ‘field list’
原因:
创建表缺少VERSION_字段
添加两个字段。

新版bug问题解决

alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255) DEFAULT NULL;
alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255) DEFAULT NULL;

在这里插入图片描述

前端相关

基于BPMN2.0的工作流
demo实例https://demo.bpmn.io/s/start
节点如下,教程https://www.jianshu.com/p/a8a21870986a
在这里插入图片描述

审批流程图:
在这里插入图片描述
bpmnjs引入
导入相关代码,包括我的审批,代办任务,历史流程等的表单设计和模块划分,其他的调整等

http://www.jmfq.cn/news/5273065.html

相关文章:

  • 郑州网站建设预订/做一个推广网站大概多少钱
  • 网站接入服务商是什么/网络培训心得体会总结
  • 佛山网站制作建设/2023年7 8月十大新闻
  • b2b网站建设方案/企业网站建设报价表
  • 深圳建设网站费用/朝阳网站seo
  • 黄骅网站建设/google官网
  • 网站开发能用udp协议吗/市场调研的方法有哪些
  • 深圳企搜网站建设/网络营销的内涵
  • wordpress电影采集/seo研究中心倒闭
  • 南通网站建设排名公司/网站快速优化排名软件
  • 天津 交友 网站建设/在线crm
  • 桂林小学网站建设/品牌营销公司
  • p2p网上贷款网站建设方案.docx/seoaoo
  • 蚌埠百度做网站/社群营销是什么意思
  • 济南企业网站制/搜索广告是什么意思
  • 有独立IP如何建设网站/百度推广关键词排名规则
  • 免费的网站生成app/网站网络营销公司
  • 个人网站怎么设计/重庆网站推广软件
  • 怎么做淘宝网站赚钱技巧/竞价排名采用什么计费方式
  • 网站的域名分为哪些/珠海百度seo
  • 湛江网站设计/灯塔网站seo
  • 网站用什么做备份/seo策略分析
  • 做亚马逊运营要看哪些网站/b站怎么推广
  • 设计网站的一般过程/产品推广活动策划方案
  • 江门网站开发/成免费的crm
  • 娱乐彩票网站建设制作/手机百度电脑版入口
  • 做企业网站设计价格是多少/网络营销比较常用的营销模式
  • wp网站打开太慢怎么做优化/合肥网络公司排名
  • 网站添加悬浮二维码/视频外链平台
  • 港湾有巢网站建设/热点事件