Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
workflow2
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
黄夏豪
workflow2
Commits
e3966687
提交
e3966687
authored
9月 22, 2021
作者:
1239068511@qq.com
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[代码更新] 加了一点东西
上级
49d728d4
显示空白字符变更
内嵌
并排
正在显示
18 个修改的文件
包含
579 行增加
和
121 行删除
+579
-121
pom.xml
pom.xml
+36
-17
Swagger2Config.java
...ava/com/tykj/workflowcore/base/config/Swagger2Config.java
+2
-2
WorkflowCoreRunner.java
...com/tykj/workflowcore/base/config/WorkflowCoreRunner.java
+1
-1
SecurityWebConfig.java
...ykj/workflowcore/user/authencation/SecurityWebConfig.java
+34
-4
CustomJwtAuthenticationFilter.java
...er/authencation/filter/CustomJwtAuthenticationFilter.java
+131
-0
JwtAuthenticationProvider.java
...user/authencation/provider/JwtAuthenticationProvider.java
+99
-0
DataHistoryController.java
...ore/workflow_editer/controller/DataHistoryController.java
+6
-0
DataHistoryMapper.java
...j/workflowcore/workflow_editer/dao/DataHistoryMapper.java
+1
-0
DataHistory.java
...tykj/workflowcore/workflow_editer/entity/DataHistory.java
+22
-0
DataHistoryVo.java
...workflowcore/workflow_editer/entity/vo/DataHistoryVo.java
+100
-0
ProcessEndListener.java
...flowcore/workflow_editer/listener/ProcessEndListener.java
+93
-52
DataHistoryService.java
...kflowcore/workflow_editer/service/DataHistoryService.java
+2
-0
DataHistoryServiceImpl.java
.../workflow_editer/service/impl/DataHistoryServiceImpl.java
+24
-0
WorkFlowServiceImpl.java
...ore/workflow_editer/service/impl/WorkFlowServiceImpl.java
+6
-29
application-mysql.yml
src/main/resources/application-mysql.yml
+4
-14
application.yml
src/main/resources/application.yml
+16
-0
tinymce-example.0e433876.css
src/main/resources/workflow/css/tinymce-example.0e433876.css
+0
-0
index.html
src/main/resources/workflow/index.html
+2
-2
没有找到文件。
pom.xml
浏览文件 @
e3966687
...
@@ -14,8 +14,10 @@
...
@@ -14,8 +14,10 @@
<name>
workflow-core
</name>
<name>
workflow-core
</name>
<description>
Demo project for Spring Boot
</description>
<description>
Demo project for Spring Boot
</description>
<properties>
<properties>
<spring-cloud.version>
2020.0.3
</spring-cloud.version>
<java.version>
1.8
</java.version>
<java.version>
1.8
</java.version>
</properties>
</properties>
<packaging>
jar
</packaging>
<dependencies>
<dependencies>
<dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<groupId>
org.springframework.boot
</groupId>
...
@@ -222,8 +224,24 @@
...
@@ -222,8 +224,24 @@
<version>
0.11.2
</version>
<version>
0.11.2
</version>
<scope>
runtime
</scope>
<scope>
runtime
</scope>
</dependency>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-server
</artifactId>
</dependency>
</dependencies>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-dependencies
</artifactId>
<version>
${spring-cloud.version}
</version>
<type>
pom
</type>
<scope>
import
</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<build>
<resources>
<resources>
<!-- <resource>-->
<!-- <resource>-->
...
@@ -242,26 +260,27 @@
...
@@ -242,26 +260,27 @@
<!-- </resource>-->
<!-- </resource>-->
</resources>
</resources>
<plugins>
<plugins>
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- </plugin>-->
<plugin>
<plugin>
<artifactId>
maven-surefire-plugin
</artifactId>
<groupId>
org.springframework.boot
</groupId>
<configuration>
<artifactId>
spring-boot-maven-plugin
</artifactId>
<skipTests>
true
</skipTests>
<version>
2.4.1
</version>
</configuration>
</plugin>
</plugin>
<plugin>
<!-- <plugin>-->
<groupId>
org.apache.maven.plugins
</groupId>
<!-- <artifactId>maven-surefire-plugin</artifactId>-->
<artifactId>
maven-compiler-plugin
</artifactId>
<!-- <configuration>-->
<configuration>
<!-- <skipTests>true</skipTests>-->
<source>
1.8
</source>
<!--指明源码用的Jdk版本-->
<!-- </configuration>-->
<target>
1.8
</target>
<!--指明打包后的Jdk版本-->
<!-- </plugin>-->
</configuration>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <source>1.8</source> <!–指明源码用的Jdk版本–>-->
<!-- <target>1.8</target> <!–指明打包后的Jdk版本–>-->
<!-- </configuration>-->
<!-- </plugin>-->
</plugins>
</plugins>
</build>
</build>
...
...
src/main/java/com/tykj/workflowcore/base/config/Swagger2Config.java
浏览文件 @
e3966687
...
@@ -47,9 +47,9 @@ public class Swagger2Config {
...
@@ -47,9 +47,9 @@ public class Swagger2Config {
private
ApiInfo
apiInfo
()
{
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
return
new
ApiInfoBuilder
()
// 文档标题
// 文档标题
.
title
(
"
装备系统
接口文档"
)
.
title
(
"
工作流
接口文档"
)
// 文档描述
// 文档描述
.
description
(
"
装备系统的接口文档与测试页面
"
)
.
description
(
"
工作流
"
)
.
termsOfServiceUrl
(
"git地址待更新"
)
.
termsOfServiceUrl
(
"git地址待更新"
)
.
version
(
"v1"
)
.
version
(
"v1"
)
.
contact
(
new
Contact
(
"efs"
,
"git"
,
"ty@example.com"
))
.
contact
(
new
Contact
(
"efs"
,
"git"
,
"ty@example.com"
))
...
...
src/main/java/com/tykj/workflowcore/base/config/WorkflowCoreRunner.java
浏览文件 @
e3966687
...
@@ -40,7 +40,7 @@ public class WorkflowCoreRunner implements CommandLineRunner {
...
@@ -40,7 +40,7 @@ public class WorkflowCoreRunner implements CommandLineRunner {
}
}
public
void
createXmlMkdir
(){
public
void
createXmlMkdir
(){
File
file
=
new
File
(
System
.
getProperty
(
"user.dir"
)+
"\\
xml"
);
File
file
=
new
File
(
System
.
getProperty
(
"user.dir"
)+
File
.
separator
+
"
xml"
);
if
(!
file
.
exists
()){
if
(!
file
.
exists
()){
file
.
mkdir
();
file
.
mkdir
();
}
}
...
...
src/main/java/com/tykj/workflowcore/user/authencation/SecurityWebConfig.java
浏览文件 @
e3966687
...
@@ -2,12 +2,16 @@ package com.tykj.workflowcore.user.authencation;
...
@@ -2,12 +2,16 @@ package com.tykj.workflowcore.user.authencation;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.tykj.workflowcore.user.authencation.filter.CustomJwtAuthenticationFilter
;
import
com.tykj.workflowcore.user.authencation.filter.CustomUsernamePasswordAuthenticationFilter
;
import
com.tykj.workflowcore.user.authencation.filter.CustomUsernamePasswordAuthenticationFilter
;
import
com.tykj.workflowcore.user.authencation.filter.SuccessHandler
;
import
com.tykj.workflowcore.user.authencation.filter.SuccessHandler
;
import
com.tykj.workflowcore.user.authencation.provider.JwtAuthenticationProvider
;
import
com.tykj.workflowcore.user.authencation.provider.UsernamePasswordAuthenticationProvider
;
import
com.tykj.workflowcore.user.authencation.provider.UsernamePasswordAuthenticationProvider
;
import
com.tykj.workflowcore.user.service.CenterUserService
;
import
com.tykj.workflowcore.user.service.CenterUserService
;
import
com.tykj.workflowcore.user.service.StorageKeyService
;
import
com.tykj.workflowcore.user.util.AuthenticationUtils
;
import
com.tykj.workflowcore.user.util.AuthenticationUtils
;
import
com.tykj.workflowcore.user.util.JwtTokenUtils
;
import
com.tykj.workflowcore.user.util.JwtTokenUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpHeaders
;
...
@@ -69,11 +73,23 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
...
@@ -69,11 +73,23 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
final
JwtTokenUtils
jwtTokenUtils
;
final
JwtTokenUtils
jwtTokenUtils
;
public
SecurityWebConfig
(
UsernamePasswordAuthenticationProvider
usernamePasswordAuthenticationProvider
,
CenterUserService
centerUserService
,
AuthenticationUtils
authenticationUtils
,
JwtTokenUtils
jwtTokenUtils
)
{
final
StorageKeyService
storageKeyService
;
/**
*自定义Jwt用户验证类
**/
final
JwtAuthenticationProvider
jwtAuthenticationProvider
;
public
SecurityWebConfig
(
UsernamePasswordAuthenticationProvider
usernamePasswordAuthenticationProvider
,
CenterUserService
centerUserService
,
AuthenticationUtils
authenticationUtils
,
JwtTokenUtils
jwtTokenUtils
,
JwtAuthenticationProvider
jwtAuthenticationProvider
,
StorageKeyService
storageKeyService
)
{
this
.
usernamePasswordAuthenticationProvider
=
usernamePasswordAuthenticationProvider
;
this
.
usernamePasswordAuthenticationProvider
=
usernamePasswordAuthenticationProvider
;
this
.
centerUserService
=
centerUserService
;
this
.
centerUserService
=
centerUserService
;
this
.
authenticationUtils
=
authenticationUtils
;
this
.
authenticationUtils
=
authenticationUtils
;
this
.
jwtTokenUtils
=
jwtTokenUtils
;
this
.
jwtTokenUtils
=
jwtTokenUtils
;
this
.
jwtAuthenticationProvider
=
jwtAuthenticationProvider
;
this
.
storageKeyService
=
storageKeyService
;
}
}
/**
/**
...
@@ -137,7 +153,9 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
...
@@ -137,7 +153,9 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
out
.
close
();
out
.
close
();
}),
ConcurrentSessionFilter
.
class
)
}),
ConcurrentSessionFilter
.
class
)
.
addFilterAt
(
customUsernamePasswordAuthenticationFilter
(),
UsernamePasswordAuthenticationFilter
.
class
);
.
addFilterAt
(
customUsernamePasswordAuthenticationFilter
(),
UsernamePasswordAuthenticationFilter
.
class
);
// .addFilterAt(new JwtAuthenticationTokenFilter(jwtTokenUtils), BasicAuthenticationFilter.class);
http
.
addFilterAt
(
customJwtUsernamePasswordAuthenticationFilter
(),
UsernamePasswordAuthenticationFilter
.
class
);
// .addFilterAt(new JwtAuthenticationTokenFilter(jwtTokenUtils), BasicAuthenticationFilter.class);
}
}
/***
/***
...
@@ -156,8 +174,13 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
...
@@ -156,8 +174,13 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
}
}
@Bean
@Bean
public
SessionRegistryImpl
sessionRegistry
()
{
CustomJwtAuthenticationFilter
customJwtUsernamePasswordAuthenticationFilter
()
throws
Exception
{
return
new
SessionRegistryImpl
();
CustomJwtAuthenticationFilter
filter
=
new
CustomJwtAuthenticationFilter
();
filter
.
setStorageKeyService
(
storageKeyService
);
filter
.
setAuthenticationManager
(
authenticationManager
());
filter
.
setAuthenticationSuccessHandler
(
new
CustomAuthenticationSuccessHandler
());
filter
.
setAuthenticationFailureHandler
(
new
CustomAuthenticationFailureHandler
());
return
filter
;
}
}
/***
/***
...
@@ -168,9 +191,16 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
...
@@ -168,9 +191,16 @@ public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
*/
*/
@Override
@Override
protected
void
configure
(
AuthenticationManagerBuilder
auth
)
{
protected
void
configure
(
AuthenticationManagerBuilder
auth
)
{
auth
.
authenticationProvider
(
jwtAuthenticationProvider
);
auth
.
authenticationProvider
(
usernamePasswordAuthenticationProvider
);
auth
.
authenticationProvider
(
usernamePasswordAuthenticationProvider
);
}
}
@Bean
public
SessionRegistryImpl
sessionRegistry
()
{
return
new
SessionRegistryImpl
();
}
/***
/***
* 登录成功后干些啥
* 登录成功后干些啥
*/
*/
...
...
src/main/java/com/tykj/workflowcore/user/authencation/filter/CustomJwtAuthenticationFilter.java
0 → 100644
浏览文件 @
e3966687
/*
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
tykj
.
workflowcore
.
user
.
authencation
.
filter
;
import
com.tykj.workflowcore.base.result.ApiException
;
import
com.tykj.workflowcore.user.authencation.token.JwtAuthencationToken
;
import
com.tykj.workflowcore.user.pojo.StorageKey
;
import
com.tykj.workflowcore.user.pojo.User
;
import
com.tykj.workflowcore.user.service.StorageKeyService
;
import
com.tykj.workflowcore.user.util.CipherUtil
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Jws
;
import
io.jsonwebtoken.Jwts
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
;
import
org.springframework.security.web.util.matcher.AntPathRequestMatcher
;
import
org.springframework.util.StringUtils
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
/**
* Jwt凭证验证拦截器
*
* @author HuangXiahao
* @version V1.0
* @class CustomJWTAuthenticationFilter
* @packageName com.example.personnelmanager.common.authencation.filter
* @data 2020/6/13
**/
public
class
CustomJwtAuthenticationFilter
extends
AbstractAuthenticationProcessingFilter
{
public
static
final
String
JWT_KEY
=
"jwt"
;
/**
* Jwt公钥路径
*/
String
jwtFilePath
;
StorageKeyService
storageKeyService
;
public
void
setStorageKeyService
(
StorageKeyService
storageKeyService
)
{
this
.
storageKeyService
=
storageKeyService
;
}
public
CustomJwtAuthenticationFilter
()
{
//设置用户接口的路径以及访问方式
super
(
new
AntPathRequestMatcher
(
"/user/login"
,
"GET"
));
}
/***
* 在这个方法中执行验证操作
* @param request
* @param response
* @Return : org.springframework.security.core.Authentication
*/
@Override
public
Authentication
attemptAuthentication
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
AuthenticationException
{
JwtAuthencationToken
authRequest
;
User
userByJwt
;
//如果请求头中没有jwt凭证的话说明不应该使用该类进行验证,直接报错
if
(!
StringUtils
.
isEmpty
(
request
.
getHeader
(
JWT_KEY
)))
{
//通过请求头获取jwt凭证中的用户信息
userByJwt
=
getuserbyjwt
(
request
);
authRequest
=
new
JwtAuthencationToken
(
userByJwt
);
//为用于验证的用户注入session信息
setDetails
(
request
,
authRequest
);
//进行验证
return
getAuthenticationManager
().
authenticate
(
authRequest
);
}
else
{
throw
new
ApiException
(
"未设置token"
);
}
}
/***
* 为用户注入session信息
* @param request
* @param authRequest
* @Return : void
*/
protected
void
setDetails
(
HttpServletRequest
request
,
JwtAuthencationToken
authRequest
)
{
authRequest
.
setDetails
(
authenticationDetailsSource
.
buildDetails
(
request
));
}
/***
* 通过请求头获取请求头中的用户信息
*
* @param request
* @Return : com.example.personnelmanager.entity.User
*/
public
User
getuserbyjwt
(
HttpServletRequest
request
)
{
StorageKey
storageKey
=
storageKeyService
.
getKeys
();
String
rsaPrivateKey
=
storageKey
.
getRsaPrivateKey
();
String
signPublicKey
=
storageKey
.
getSignPublicKey
();
String
jwt
=
request
.
getHeader
(
"jwt"
);
try
{
String
decrypt
=
CipherUtil
.
decrypt
(
jwt
,
CipherUtil
.
string2PrivateKey
(
rsaPrivateKey
));
Jws
<
Claims
>
claimsJws
=
Jwts
.
parser
().
setSigningKey
(
CipherUtil
.
string2PublicKey
(
signPublicKey
)).
parseClaimsJws
(
decrypt
);
logger
.
info
(
"接收到的用户信息为:"
+
claimsJws
.
getBody
());
User
userRight
=
new
User
();
Claims
body
=
claimsJws
.
getBody
();
userRight
.
setUsername
((
String
)
body
.
get
(
"username"
));
userRight
.
setPhone
((
String
)
body
.
get
(
"phone"
));
return
userRight
;
}
catch
(
Exception
e
){
logger
.
error
(
"用户凭证无效"
);
throw
new
UsernameNotFoundException
(
"用户凭证无效"
);
}
}
}
src/main/java/com/tykj/workflowcore/user/authencation/provider/JwtAuthenticationProvider.java
0 → 100644
浏览文件 @
e3966687
package
com
.
tykj
.
workflowcore
.
user
.
authencation
.
provider
;
import
com.tykj.workflowcore.user.authencation.checks.DefaultPreAuthenticationChecks
;
import
com.tykj.workflowcore.user.authencation.token.JwtAuthencationToken
;
import
com.tykj.workflowcore.user.pojo.User
;
import
com.tykj.workflowcore.user.service.CenterUserService
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.authentication.InternalAuthenticationServiceException
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsChecker
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.Assert
;
/**
* 自定义SpringSecurity的用户处理类类
* 当用户通过统一登录平台访问本系统时由该类进行用户验证
*
* @author HuangXiahao
* @version V1.0
* @class JWTAuthenticationProvider
* @packageName com.example.personnelmanager.common.SpringSecurityProvider
* @data 2020/6/13
**/
@Component
public
class
JwtAuthenticationProvider
implements
AuthenticationProvider
{
private
final
CenterUserService
userDetailsService
;
/**
* 用户可用性检查类
*/
private
final
UserDetailsChecker
preAuthenticationChecks
=
new
DefaultPreAuthenticationChecks
();
public
JwtAuthenticationProvider
(
CenterUserService
centerUserService
)
{
this
.
userDetailsService
=
centerUserService
;
}
/***
* 验证用户
*
* @param authentication
* @Return : org.springframework.security.core.Authentication
*/
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
Assert
.
isInstanceOf
(
JwtAuthencationToken
.
class
,
authentication
,
"错误的凭证"
);
String
username
=
(
authentication
.
getPrincipal
()
==
null
)
?
"NONE_PROVIDED"
:
((
User
)
authentication
.
getPrincipal
()).
getUsername
();
UserDetails
user
=
retrieveUser
(
username
);
preAuthenticationChecks
.
check
(
user
);
return
createSuccessAuthentication
(
user
,
authentication
,
user
);
}
/***
* 返回True则由该对象进行用户验证
*
* @param authentication
* @Return : boolean
*/
@Override
public
boolean
supports
(
Class
<?>
authentication
)
{
return
(
JwtAuthencationToken
.
class
.
isAssignableFrom
(
authentication
));
}
/***
* 通过用户名获取对应的用户
*
* @param username
* @Return : org.springframework.security.core.userdetails.UserDetails
*/
protected
final
UserDetails
retrieveUser
(
String
username
)
{
UserDetails
loadedUser
=
userDetailsService
.
selectByUserName
(
username
);
if
(
loadedUser
==
null
)
{
throw
new
InternalAuthenticationServiceException
(
"UserDetailsService returned null, which is an interface contract violation"
);
}
return
loadedUser
;
}
/***
* 创建一个已经通过验证的用户实例
* 该方法由SpringSecurity源码魔改得到
* @param principal
* @param authentication
* @param user
* @Return : org.springframework.security.core.Authentication
*/
protected
Authentication
createSuccessAuthentication
(
Object
principal
,
Authentication
authentication
,
UserDetails
user
)
{
JwtAuthencationToken
result
=
new
JwtAuthencationToken
(
principal
,
user
.
getAuthorities
());
result
.
setDetails
(
authentication
.
getDetails
());
return
result
;
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/controller/DataHistoryController.java
浏览文件 @
e3966687
...
@@ -34,5 +34,11 @@ public class DataHistoryController {
...
@@ -34,5 +34,11 @@ public class DataHistoryController {
dataHistoryService
.
save
(
dataHistory
);
dataHistoryService
.
save
(
dataHistory
);
}
}
@PostMapping
(
"/test"
)
@ApiOperation
(
value
=
"test"
)
public
void
test
(){
dataHistoryService
.
test
();
}
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/dao/DataHistoryMapper.java
浏览文件 @
e3966687
...
@@ -4,6 +4,7 @@ package com.tykj.workflowcore.workflow_editer.dao;
...
@@ -4,6 +4,7 @@ package com.tykj.workflowcore.workflow_editer.dao;
import
com.tykj.workflowcore.workflow_editer.entity.DataHistory
;
import
com.tykj.workflowcore.workflow_editer.entity.DataHistory
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.data.jpa.repository.Query
;
/**
/**
* ClassName: FlowsInfoMapper
* ClassName: FlowsInfoMapper
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/entity/DataHistory.java
浏览文件 @
e3966687
...
@@ -11,6 +11,7 @@ import org.hibernate.annotations.Where;
...
@@ -11,6 +11,7 @@ import org.hibernate.annotations.Where;
import
javax.persistence.Entity
;
import
javax.persistence.Entity
;
import
javax.persistence.Lob
;
import
javax.persistence.Lob
;
import
java.util.Date
;
/**
/**
* ClassName: DataHistory
* ClassName: DataHistory
...
@@ -77,6 +78,27 @@ public class DataHistory extends BaseEntity {
...
@@ -77,6 +78,27 @@ public class DataHistory extends BaseEntity {
@Lob
@Lob
private
String
IndexKey
;
private
String
IndexKey
;
@ApiModelProperty
(
"流程KEY"
)
private
String
processKey
;
@ApiModelProperty
(
"节点类型"
)
private
String
activityType
;
@ApiModelProperty
(
"流程发起人"
)
private
String
businessKey
;
@ApiModelProperty
(
"任务执行人"
)
private
String
taskAssign
;
@ApiModelProperty
(
"任务名称"
)
private
String
taskName
;
@ApiModelProperty
private
Date
startTime
;
@ApiModelProperty
private
Date
endTime
;
public
static
String
initUniqueString
(
String
executionId
,
String
processInstanceId
,
String
activityId
){
public
static
String
initUniqueString
(
String
executionId
,
String
processInstanceId
,
String
activityId
){
return
executionId
+
"_"
+
processInstanceId
+
"_"
+
activityId
;
return
executionId
+
"_"
+
processInstanceId
+
"_"
+
activityId
;
}
}
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/entity/vo/DataHistoryVo.java
0 → 100644
浏览文件 @
e3966687
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
entity
.
vo
;
import
com.tykj.workflowcore.base.entity.BaseEntity
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
org.hibernate.annotations.SQLDelete
;
import
org.hibernate.annotations.Where
;
import
javax.persistence.Entity
;
import
javax.persistence.Lob
;
/**
* ClassName: DataHistory
* Package: com.tykj.workflowcore.workflow_editer.entity
* Description:
* Datetime: 2021/4/16 15:21
*
* @Author: zsp
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Api
(
"历史数据"
)
public
class
DataHistoryVo
extends
BaseEntity
{
@ApiModelProperty
(
"执行实例ID"
)
private
String
executionId
;
@ApiModelProperty
(
"流程实例id"
)
private
String
processInstanceId
;
@ApiModelProperty
(
"节点Id"
)
private
String
activityId
;
@ApiModelProperty
(
"执行实例ID_流程实例id_节点Id 用于作为索引"
)
private
String
uniqueString
;
@ApiModelProperty
(
"页面id"
)
private
String
pageId
;
@ApiModelProperty
(
"页面名称"
)
private
String
pageName
;
@ApiModelProperty
(
"页面描述"
)
private
String
pageDesc
;
@ApiModelProperty
(
"模板"
)
@Lob
private
String
template
;
@ApiModelProperty
(
"页面js"
)
@Lob
private
String
js
;
@ApiModelProperty
(
"页面css"
)
@Lob
private
String
css
;
@ApiModelProperty
(
"json描述文件"
)
@Lob
private
String
descFile
;
@ApiModelProperty
(
"变量数据"
)
@Lob
private
String
datas
;
@ApiModelProperty
(
"页面操作用户id"
)
private
Integer
userId
;
@ApiModelProperty
(
"索引Key"
)
@Lob
private
String
IndexKey
;
@ApiModelProperty
(
"流程KEY"
)
private
String
processKey
;
@ApiModelProperty
(
"节点类型"
)
private
String
activityType
;
@ApiModelProperty
(
"流程发起人"
)
private
String
businessKey
;
@ApiModelProperty
(
"任务执行人"
)
private
String
taskAssign
;
@ApiModelProperty
(
"任务名称"
)
private
String
taskName
;
private
String
processName
;
private
String
processDes
;
public
static
String
initUniqueString
(
String
executionId
,
String
processInstanceId
,
String
activityId
){
return
executionId
+
"_"
+
processInstanceId
+
"_"
+
activityId
;
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/listener/ProcessEndListener.java
浏览文件 @
e3966687
...
@@ -3,22 +3,30 @@ package com.tykj.workflowcore.workflow_editer.listener;
...
@@ -3,22 +3,30 @@ package com.tykj.workflowcore.workflow_editer.listener;
import
com.alibaba.fastjson.JSONObject
;
import
com.alibaba.fastjson.JSONObject
;
import
com.tykj.workflowcore.base.result.ApiException
;
import
com.tykj.workflowcore.base.result.ApiException
;
import
com.tykj.workflowcore.workflow_editer.entity.DataHistory
;
import
com.tykj.workflowcore.workflow_editer.entity.DataHistory
;
import
com.tykj.workflowcore.workflow_editer.entity.FlowsInfo
;
import
com.tykj.workflowcore.workflow_editer.entity.FormPage
;
import
com.tykj.workflowcore.workflow_editer.entity.FormPage
;
import
com.tykj.workflowcore.workflow_editer.entity.enums.JavaTypeEnum
;
import
com.tykj.workflowcore.workflow_editer.entity.enums.JavaTypeEnum
;
import
com.tykj.workflowcore.workflow_editer.entity.vo.ParameterVo
;
import
com.tykj.workflowcore.workflow_editer.entity.vo.ParameterVo
;
import
com.tykj.workflowcore.workflow_editer.service.DataHistoryService
;
import
com.tykj.workflowcore.workflow_editer.service.DataHistoryService
;
import
com.tykj.workflowcore.workflow_editer.service.FlowInfoService
;
import
com.tykj.workflowcore.workflow_editer.service.FormPageService
;
import
com.tykj.workflowcore.workflow_editer.service.FormPageService
;
import
org.flowable.bpmn.model.StartEvent
;
import
org.flowable.bpmn.model.StartEvent
;
import
org.flowable.bpmn.model.UserTask
;
import
org.flowable.bpmn.model.UserTask
;
import
org.flowable.common.engine.api.delegate.Expression
;
import
org.flowable.common.engine.api.delegate.Expression
;
import
org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent
;
import
org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent
;
import
org.flowable.common.engine.api.delegate.event.FlowableEngineEvent
;
import
org.flowable.common.engine.api.delegate.event.FlowableEvent
;
import
org.flowable.common.engine.api.delegate.event.FlowableEvent
;
import
org.flowable.engine.*
;
import
org.flowable.engine.*
;
import
org.flowable.engine.delegate.DelegateExecution
;
import
org.flowable.engine.delegate.DelegateExecution
;
import
org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener
;
import
org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener
;
import
org.flowable.engine.delegate.event.FlowableActivityEvent
;
import
org.flowable.engine.delegate.event.FlowableActivityEvent
;
import
org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl
;
import
org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl
;
import
org.flowable.engine.delegate.event.impl.FlowableEntityWithVariablesEventImpl
;
import
org.flowable.engine.history.HistoricProcessInstance
;
import
org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl
;
import
org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl
;
import
org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl
;
import
org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntityImpl
;
import
org.flowable.task.service.impl.persistence.entity.TaskEntityImpl
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
...
@@ -56,6 +64,12 @@ public class ProcessEndListener extends AbstractFlowableEngineEventListener {
...
@@ -56,6 +64,12 @@ public class ProcessEndListener extends AbstractFlowableEngineEventListener {
@Autowired
@Autowired
FormPageService
formPageService
;
FormPageService
formPageService
;
@Autowired
HistoryService
historyService
;
@Autowired
FlowInfoService
flowInfoService
;
@Override
@Override
protected
void
processCompleted
(
FlowableEngineEntityEvent
event
)
{
protected
void
processCompleted
(
FlowableEngineEntityEvent
event
)
{
}
}
...
@@ -63,6 +77,7 @@ public class ProcessEndListener extends AbstractFlowableEngineEventListener {
...
@@ -63,6 +77,7 @@ public class ProcessEndListener extends AbstractFlowableEngineEventListener {
@Override
@Override
protected
void
taskCompleted
(
FlowableEngineEntityEvent
event
)
{
protected
void
taskCompleted
(
FlowableEngineEntityEvent
event
)
{
super
.
taskCompleted
(
event
);
super
.
taskCompleted
(
event
);
initDataHistory
(
event
);
}
}
@Override
@Override
...
@@ -74,80 +89,106 @@ public class ProcessEndListener extends AbstractFlowableEngineEventListener {
...
@@ -74,80 +89,106 @@ public class ProcessEndListener extends AbstractFlowableEngineEventListener {
@Override
@Override
protected
void
activityCompleted
(
FlowableActivityEvent
event
)
{
protected
void
activityCompleted
(
FlowableActivityEvent
event
)
{
super
.
activityCompleted
(
event
);
super
.
activityCompleted
(
event
);
if
(
event
instanceof
FlowableActivityEventImpl
){
initDataHistory
(
event
);
DelegateExecution
execution
=
((
FlowableActivityEventImpl
)
event
).
getExecution
();
}
initDataHistory
(
execution
);
// //开始节点
public
void
initDataHistory
(
FlowableEngineEvent
event
){
// if (execution.getCurrentFlowElement() instanceof StartEvent){
//页面ID
// DataHistory dataHistory = new DataHistory();
String
formKey
;
// StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
//页面信息
// //流程id 实例id pageId datas userId
// String processInstanceBusinessKey = execution.getProcessInstanceBusinessKey();
// dataHistory.setFlowKey(processInstanceBusinessKey);
// dataHistory.setProcessInstanceId(execution.getProcessInstanceId());
// dataHistory.setPageId(startEvent.getFormKey());
//// dataHistory.setUserId();
//// dataHistory.setDatas();
// System.out.println(processInstanceBusinessKey);
//
// String formKey = startEvent.getFormKey();
// //通过formKey查询出页面
//
// }
// if (execution.getCurrentFlowElement() instanceof UserTask){
// //查询任务
// Task task = taskService.createTaskQuery().singleResult();
// Map<String, Object> variables = taskService.getVariables(task.getId());
// DataHistory dataHistory = new DataHistory();
// String datas = JSON.toJSONString(variables);
// //流程实例id
// String processInstanceId = task.getProcessInstanceId();
// //当前节点id
// String processInstanceBusinessKey = execution.getProcessInstanceBusinessKey();
//
//// dataHistory.setTaskId(taskId);
// dataHistory.setDatas(datas);
// dataHistory.setProcessInstanceId(processInstanceId);
// dataHistoryService.saveData(dataHistory);
// }
}
}
public
void
initDataHistory
(
DelegateExecution
execution
){
FormPage
page
=
null
;
FormPage
page
=
null
;
if
(
execution
.
getCurrentFlowElement
()
instanceof
UserTask
){
//流程信息
UserTask
userTask
=
(
UserTask
)
execution
.
getCurrentFlowElement
();
FlowsInfo
flowsInfo
;
String
formKey
=
userTask
.
getFormKey
();
//执行节点信息
//查询出这个节点的页面
DelegateExecution
execution
;
page
=
formPageService
.
getPage
(
Integer
.
valueOf
(
formKey
));
//流程执行用户
}
else
String
taskAssign
=
""
;
//流程发起人
String
businessKey
=
""
;
//流程实例
HistoricProcessInstance
historicProcessInstance
;
//processKey
String
processKey
;
//任务名称
String
taskName
;
//节点类型
String
activityType
;
if
(
event
instanceof
FlowableActivityEventImpl
){
//从这里取出了startEvent开始事件的信息
execution
=
((
FlowableActivityEventImpl
)
event
).
getExecution
();
if
(
execution
.
getCurrentFlowElement
()
instanceof
StartEvent
){
if
(
execution
.
getCurrentFlowElement
()
instanceof
StartEvent
){
StartEvent
startEvent
=
(
StartEvent
)
execution
.
getCurrentFlowElement
();
StartEvent
startEvent
=
(
StartEvent
)
execution
.
getCurrentFlowElement
();
String
formKey
=
startEvent
.
getFormKey
();
formKey
=
startEvent
.
getFormKey
();
//查出这个节点的流程实例信息(获取流程发起的用户)
historicProcessInstance
=
historyService
.
createHistoricProcessInstanceQuery
()
.
processInstanceId
(
execution
.
getProcessInstanceId
())
.
list
().
get
(
0
);
taskAssign
=
historicProcessInstance
.
getBusinessKey
();
businessKey
=
historicProcessInstance
.
getBusinessKey
();
taskName
=
startEvent
.
getName
();
activityType
=
"StartEvent"
;
}
else
{
return
;
}
}
else
if
(
event
instanceof
FlowableEntityWithVariablesEventImpl
){
//从这里取出了UserTask用户任务的信息
execution
=
((
FlowableEntityWithVariablesEventImpl
)
event
).
getExecution
();
if
(
execution
.
getCurrentFlowElement
()
instanceof
UserTask
){
UserTask
userTask
=
(
UserTask
)
execution
.
getCurrentFlowElement
();
formKey
=
userTask
.
getFormKey
();
//查询出这个节点的页面
//查询出这个节点的页面
page
=
formPageService
.
getPage
(
Integer
.
valueOf
(
formKey
));
page
=
formPageService
.
getPage
(
Integer
.
valueOf
(
formKey
));
//查出这个这个任务的执行人
taskAssign
=
((
TaskEntityImpl
)((
FlowableEntityWithVariablesEventImpl
)
event
).
getEntity
()).
getAssignee
();
//查出这个节点的流程实例信息(获取流程发起的用户)
historicProcessInstance
=
historyService
.
createHistoricProcessInstanceQuery
()
.
processInstanceId
(
execution
.
getProcessInstanceId
())
.
list
().
get
(
0
);
businessKey
=
historicProcessInstance
.
getBusinessKey
();
taskName
=
userTask
.
getName
();
activityType
=
"UserTask"
;
}
else
{
}
else
{
return
;
return
;
}
}
DataHistory
dataHistory
=
new
DataHistory
();
}
else
{
return
;
}
//获取processKey
processKey
=
historicProcessInstance
.
getProcessDefinitionKey
();
//查询出这个节点的页面
page
=
formPageService
.
getPage
(
Integer
.
valueOf
(
formKey
));
//查出这个节点内的临时数据
//查出这个节点内的临时数据
Map
<
String
,
Object
>
variables
=
execution
.
getVariables
();
Map
<
String
,
Object
>
variables
=
execution
.
getVariables
();
DataHistory
dataHistory
=
new
DataHistory
();
//设置processInstanceId
//设置processInstanceId
dataHistory
.
setProcessInstanceId
(
execution
.
getProcessInstanceId
());
dataHistory
.
setProcessInstanceId
(
execution
.
getProcessInstanceId
());
//设置
节点
Id
//设置
执行
Id
dataHistory
.
setExecutionId
(
execution
.
getId
());
dataHistory
.
setExecutionId
(
execution
.
getId
());
dataHistory
.
setProcessInstanceId
(
execution
.
getProcessInstanceId
());
//设置节点ID
dataHistory
.
setActivityId
(
execution
.
getCurrentFlowElement
().
getId
());
dataHistory
.
setActivityId
(
execution
.
getCurrentFlowElement
().
getId
());
//生成查询索引字符串
dataHistory
.
setUniqueString
(
DataHistory
.
initUniqueString
(
dataHistory
.
getExecutionId
(),
dataHistory
.
getProcessInstanceId
(),
dataHistory
.
getActivityId
()));
dataHistory
.
setUniqueString
(
DataHistory
.
initUniqueString
(
dataHistory
.
getExecutionId
(),
dataHistory
.
getProcessInstanceId
(),
dataHistory
.
getActivityId
()));
//生成索引JSON 预留字段以后方便前端使用
dataHistory
.
setIndexKey
(
initDataHistoryIndexKey
(
dataHistory
));
//下面试一下前端的内容
dataHistory
.
setTaskName
(
taskName
);
dataHistory
.
setActivityType
(
activityType
);
dataHistory
.
setJs
(
page
.
getJs
());
dataHistory
.
setJs
(
page
.
getJs
());
dataHistory
.
setCss
(
page
.
getCss
());
dataHistory
.
setCss
(
page
.
getCss
());
dataHistory
.
setTemplate
(
page
.
getTemplate
());
dataHistory
.
setTemplate
(
page
.
getTemplate
());
dataHistory
.
setDescFile
(
page
.
getDescFile
());
dataHistory
.
setDescFile
(
page
.
getDescFile
());
dataHistory
.
setDatas
(
JSONObject
.
toJSONString
(
variables
));
dataHistory
.
setDatas
(
JSONObject
.
toJSONString
(
variables
));
dataHistory
.
setIndexKey
(
initDataHistoryIndexKey
(
dataHistory
));
dataHistory
.
setProcessKey
(
processKey
);
dataHistory
.
setStartTime
(((
ExecutionEntityImpl
)
execution
).
getStartTime
());
dataHistory
.
setEndTime
(
new
Date
());
//拼接用户信息
dataHistory
.
setTaskAssign
(
taskAssign
);
dataHistory
.
setBusinessKey
(
businessKey
);
if
(
StringUtils
.
isEmpty
(
dataHistory
.
getProcessKey
())){
System
.
out
.
println
(
"1"
);
}
//保存下来
//保存下来
dataHistoryService
.
save
(
dataHistory
);
dataHistoryService
.
save
(
dataHistory
);
}
}
public
String
initDataHistoryIndexKey
(
DataHistory
dataHistory
){
public
String
initDataHistoryIndexKey
(
DataHistory
dataHistory
){
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/service/DataHistoryService.java
浏览文件 @
e3966687
...
@@ -21,6 +21,8 @@ public interface DataHistoryService {
...
@@ -21,6 +21,8 @@ public interface DataHistoryService {
DataHistory
findByUniqueString
(
String
uniqueString
);
DataHistory
findByUniqueString
(
String
uniqueString
);
public
Object
test
();
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/service/impl/DataHistoryServiceImpl.java
浏览文件 @
e3966687
...
@@ -2,10 +2,19 @@ package com.tykj.workflowcore.workflow_editer.service.impl;
...
@@ -2,10 +2,19 @@ package com.tykj.workflowcore.workflow_editer.service.impl;
import
com.tykj.workflowcore.workflow_editer.dao.DataHistoryMapper
;
import
com.tykj.workflowcore.workflow_editer.dao.DataHistoryMapper
;
import
com.tykj.workflowcore.workflow_editer.entity.DataHistory
;
import
com.tykj.workflowcore.workflow_editer.entity.DataHistory
;
import
com.tykj.workflowcore.workflow_editer.entity.FlowsInfo
;
import
com.tykj.workflowcore.workflow_editer.entity.vo.DataHistoryVo
;
import
com.tykj.workflowcore.workflow_editer.service.DataHistoryService
;
import
com.tykj.workflowcore.workflow_editer.service.DataHistoryService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.jpa.domain.Specification
;
import
org.springframework.data.support.PageableExecutionUtils
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
javax.persistence.EntityManager
;
import
javax.persistence.criteria.*
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
/**
* ClassName: DataHistoryServiceImpl
* ClassName: DataHistoryServiceImpl
* Package: com.tykj.workflowcore.workflow_editer.service.impl
* Package: com.tykj.workflowcore.workflow_editer.service.impl
...
@@ -20,6 +29,9 @@ public class DataHistoryServiceImpl implements DataHistoryService {
...
@@ -20,6 +29,9 @@ public class DataHistoryServiceImpl implements DataHistoryService {
@Autowired
@Autowired
private
DataHistoryMapper
dataHistoryMapper
;
private
DataHistoryMapper
dataHistoryMapper
;
@Autowired
private
EntityManager
entityManager
;
@Override
@Override
public
DataHistory
save
(
DataHistory
dataHistory
)
{
public
DataHistory
save
(
DataHistory
dataHistory
)
{
return
dataHistoryMapper
.
save
(
dataHistory
);
return
dataHistoryMapper
.
save
(
dataHistory
);
...
@@ -31,4 +43,16 @@ public class DataHistoryServiceImpl implements DataHistoryService {
...
@@ -31,4 +43,16 @@ public class DataHistoryServiceImpl implements DataHistoryService {
return
byUniqueString
;
return
byUniqueString
;
}
}
public
Object
test
(){
CriteriaBuilder
cb
=
entityManager
.
getCriteriaBuilder
();
CriteriaQuery
<
DataHistoryVo
>
query
=
cb
.
createQuery
(
DataHistoryVo
.
class
);
Root
<
DataHistory
>
root
=
query
.
from
(
DataHistory
.
class
);
List
<
Selection
<?>>
list
=
new
ArrayList
<
Selection
<?>>();
list
.
add
(
root
.
get
(
"uniqueString"
));
Selection
<?>[]
selections
=
list
.
toArray
(
new
Selection
<?>[
list
.
size
()]);
query
.
multiselect
(
selections
);
List
<
DataHistoryVo
>
resultList
=
entityManager
.
createQuery
(
query
).
getResultList
();
return
null
;
}
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/service/impl/WorkFlowServiceImpl.java
浏览文件 @
e3966687
...
@@ -452,7 +452,6 @@ public class WorkFlowServiceImpl implements WorkFlowService {
...
@@ -452,7 +452,6 @@ public class WorkFlowServiceImpl implements WorkFlowService {
}
else
{
}
else
{
throw
new
ApiException
(
null
,
"流程不存在"
);
throw
new
ApiException
(
null
,
"流程不存在"
);
}
}
}
}
@Override
@Override
...
@@ -505,22 +504,6 @@ public class WorkFlowServiceImpl implements WorkFlowService {
...
@@ -505,22 +504,6 @@ public class WorkFlowServiceImpl implements WorkFlowService {
@Override
@Override
public
PageReturnVo
<
List
<
TaskHistoryReturnVo
>>
findHistoryTask
(
MyTaskSelectVo
myTaskSelectVo
)
{
public
PageReturnVo
<
List
<
TaskHistoryReturnVo
>>
findHistoryTask
(
MyTaskSelectVo
myTaskSelectVo
)
{
//拼接processInstance查询器
// HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
// historicProcessInstanceQuery.processInstanceBusinessKey(myTaskSelectVo.getUserId());
// List<HistoricProcessInstance> myStartProcessInstance = historicProcessInstanceQuery.list();
// //根据processInstance查询出所有开始节点的信息
// List<HistoricActivityInstance> userHistoricStartActivityInstance = new ArrayList<>();
// for (HistoricProcessInstance historicProcessInstance : myStartProcessInstance) {
// HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
// historicActivityInstanceQuery.processInstanceId(historicProcessInstance.getId());
// if (!StringUtils.isEmpty(myTaskSelectVo.getTaskName())){
// }
// List<HistoricActivityInstance> startEvent = historyService.createHistoricActivityInstanceQuery()
// .processInstanceId(historicProcessInstance.getId())
// .activityType("startEvent")
// .list();
// }
//由于这里存在两种数据的查询 无法正常分页 所以需要一点特殊的手段
//由于这里存在两种数据的查询 无法正常分页 所以需要一点特殊的手段
//前区的偏移
//前区的偏移
long
offset1
=
0
;
long
offset1
=
0
;
...
@@ -587,6 +570,12 @@ public class WorkFlowServiceImpl implements WorkFlowService {
...
@@ -587,6 +570,12 @@ public class WorkFlowServiceImpl implements WorkFlowService {
taskHistoryReturnVo
.
setCreateUser
(
centerUserService
.
findById
(
historicProcessInstance
.
getBusinessKey
()).
getRealName
());
taskHistoryReturnVo
.
setCreateUser
(
centerUserService
.
findById
(
historicProcessInstance
.
getBusinessKey
()).
getRealName
());
taskHistoryReturnVo
.
setId
(
historicActivityInstance
.
getId
());
taskHistoryReturnVo
.
setId
(
historicActivityInstance
.
getId
());
taskHistoryReturnVo
.
setProcessInstanceId
(
historicProcessInstance
.
getId
());
taskHistoryReturnVo
.
setProcessInstanceId
(
historicProcessInstance
.
getId
());
if
(
historicProcessInstance
.
getEndTime
()!=
null
){
taskHistoryReturnVo
.
setState
(
0
);
}
else
{
taskHistoryReturnVo
.
setState
(
1
);
}
taskHistoryReturnVoList
.
add
(
taskHistoryReturnVo
);
taskHistoryReturnVoList
.
add
(
taskHistoryReturnVo
);
}
}
//查出我执行的任务,并添加到最后返回的列表
//查出我执行的任务,并添加到最后返回的列表
...
@@ -628,18 +617,6 @@ public class WorkFlowServiceImpl implements WorkFlowService {
...
@@ -628,18 +617,6 @@ public class WorkFlowServiceImpl implements WorkFlowService {
taskHistoryReturnVo
.
setProcessInstanceId
(
historicProcessInstance
.
getId
());
taskHistoryReturnVo
.
setProcessInstanceId
(
historicProcessInstance
.
getId
());
taskHistoryReturnVoList
.
add
(
taskHistoryReturnVo
);
taskHistoryReturnVoList
.
add
(
taskHistoryReturnVo
);
}
}
// List<HistoricActivityInstance> taskInstanceList =
// historyService
// .createHistoricActivityInstanceQuery()
// .taskAssignee(userService.getCurrentUser().getId()+"")
// .finished()
// .orderByHistoricActivityInstanceStartTime()
// .desc()
// .list();
// ArrayList<Object> arrayList = new ArrayList<>();
// arrayList.addAll(taskInstanceList);
return
new
PageReturnVo
<>(
allCount
,
taskHistoryReturnVoList
return
new
PageReturnVo
<>(
allCount
,
taskHistoryReturnVoList
);
);
...
...
src/main/resources/application-mysql.yml
浏览文件 @
e3966687
...
@@ -4,8 +4,8 @@ spring:
...
@@ -4,8 +4,8 @@ spring:
time-zone
:
GMT+8
time-zone
:
GMT+8
datasource
:
datasource
:
username
:
root
username
:
root
password
:
Huang123+
password
:
root
url
:
jdbc:mysql://
47.106.142.73:3306/www2
?useSSL=true&verifyServerCertificate=false&useUnicode=true&autoReconnect=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
url
:
jdbc:mysql://
192.168.100.248:3306/workflow
?useSSL=true&verifyServerCertificate=false&useUnicode=true&autoReconnect=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
driver-class-name
:
com.mysql.cj.jdbc.Driver
driver-class-name
:
com.mysql.cj.jdbc.Driver
hikari
:
hikari
:
read-only
:
false
read-only
:
false
...
@@ -23,18 +23,8 @@ spring:
...
@@ -23,18 +23,8 @@ spring:
physical-strategy
:
com.tykj.workflowcore.base.config.ToUpperCase
physical-strategy
:
com.tykj.workflowcore.base.config.ToUpperCase
ddl-auto
:
update
ddl-auto
:
update
database-platform
:
org.hibernate.dialect.MySQL8Dialect
database-platform
:
org.hibernate.dialect.MySQL8Dialect
application
:
name
:
workflow
sync
:
sync
:
ip
:
192.168.102.
171
ip
:
192.168.102.
248
port
:
8880
port
:
8880
server
:
server
:
port
:
8088
port
:
13765
eureka
:
instance
:
prefer-ip-address
:
true
lease-expiration-duration-in-seconds
:
3
lease-renewal-interval-in-seconds
:
7
client
:
service-url
:
defaultZone
:
http://192.168.100.248:1111/eureka/
src/main/resources/application.yml
浏览文件 @
e3966687
spring
:
spring
:
profiles
:
profiles
:
active
:
mysql
active
:
mysql
application
:
name
:
workflow
jwt
:
jwt
:
header
:
Authorization
header
:
Authorization
tokenStartWith
:
Bearer
tokenStartWith
:
Bearer
base64Secret
:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJb8U08NrX0XplcemWh2JiJ7O6274GmqnYkH0zKpp7FE3xmmeSJ9tcSij9s8RK4HRxUlBQLsAzsS9+ZDRbdtGz+ITmGTRmidpWAR61tX8AaB/PrRWAWHLrMr7keMN6B9aUVxCXm58j5HO2d77OoIvpC6SzwH1E1xtu8lk51kxJSvAgMBAAECgYBh5EkzWR/hmgLMO1elZe0FsDaaRtSSTf+Dx+ID2AGUqp2nqMqjNTQzwF5a+3FgD/HjYLQmF9VkaMD3tygta/0crQyNJwv82xKxXYq8TmHvkVx8XDgWzWzSwQSVSBjvc+Cvg5FNC6p1xVZxtXqacHEXBlpcMu6TvZNu+vh07Uq1iQJBANc8cCNV7MdT5bFBYimSGSnGPfvkTHxDzmtzS577Ro9EXDdPKJQfJCN3CWv4l5ub/u20uLCLEzl0uzETxG/nzNsCQQCzlMCh+wcZpe/od+6nsvGGJYhPsttL7W3OG0KbCbvMXkhsAw6JpxBtz4Thb1rihnIpBjKTocB5wNKrjGXUezW9AkBHUcuGqe4vjmlJ9vRj+flEkl/vm5KMiptXl3izUWfsCSbVXPGBQ2BiMAt7L4BtG5+5fGzGcw8HttpgRMCOpCyJAkEApT6e1y5XhTlU/fPGDlgxuL+2o6ev9TkADmS1MFaPkWm8eG+DpBSvoGwRGSPPXJxcVfWW+pQfuak98Y8acKADfQJBAL4UcsTdfkwycQqnCJepOyJtqxW8HHo8raqC0b8D2UGvmoPE3/fCVhdco8yBdrvvWErMEz+PxGwZS4VkPezSs0w=
base64Secret
:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJb8U08NrX0XplcemWh2JiJ7O6274GmqnYkH0zKpp7FE3xmmeSJ9tcSij9s8RK4HRxUlBQLsAzsS9+ZDRbdtGz+ITmGTRmidpWAR61tX8AaB/PrRWAWHLrMr7keMN6B9aUVxCXm58j5HO2d77OoIvpC6SzwH1E1xtu8lk51kxJSvAgMBAAECgYBh5EkzWR/hmgLMO1elZe0FsDaaRtSSTf+Dx+ID2AGUqp2nqMqjNTQzwF5a+3FgD/HjYLQmF9VkaMD3tygta/0crQyNJwv82xKxXYq8TmHvkVx8XDgWzWzSwQSVSBjvc+Cvg5FNC6p1xVZxtXqacHEXBlpcMu6TvZNu+vh07Uq1iQJBANc8cCNV7MdT5bFBYimSGSnGPfvkTHxDzmtzS577Ro9EXDdPKJQfJCN3CWv4l5ub/u20uLCLEzl0uzETxG/nzNsCQQCzlMCh+wcZpe/od+6nsvGGJYhPsttL7W3OG0KbCbvMXkhsAw6JpxBtz4Thb1rihnIpBjKTocB5wNKrjGXUezW9AkBHUcuGqe4vjmlJ9vRj+flEkl/vm5KMiptXl3izUWfsCSbVXPGBQ2BiMAt7L4BtG5+5fGzGcw8HttpgRMCOpCyJAkEApT6e1y5XhTlU/fPGDlgxuL+2o6ev9TkADmS1MFaPkWm8eG+DpBSvoGwRGSPPXJxcVfWW+pQfuak98Y8acKADfQJBAL4UcsTdfkwycQqnCJepOyJtqxW8HHo8raqC0b8D2UGvmoPE3/fCVhdco8yBdrvvWErMEz+PxGwZS4VkPezSs0w=
tokenValidityInSeconds
:
43200000
tokenValidityInSeconds
:
43200000
eureka
:
instance
:
prefer-ip-address
:
true
lease-expiration-duration-in-seconds
:
3
lease-renewal-interval-in-seconds
:
7
client
:
service-url
:
defaultZone
:
http://192.168.100.248:1111/eureka/
server
:
servlet
:
session
:
cookie
:
name
:
workflow1
\ No newline at end of file
src/main/resources/workflow/css/tinymce-example.0e433876.css
deleted
100644 → 0
浏览文件 @
49d728d4
src/main/resources/workflow/index.html
浏览文件 @
e3966687
<!doctype html>
<html
lang=
"zh"
><head><meta
charset=
"utf-8"
><meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
><meta
name=
"viewport"
content=
"width=device-width,initial-scale=0,maximum-scale=0,user-scalable=yes,shrink-to-fit=no"
><link
rel=
"icon"
href=
"favicon.ico"
><title>
workFlow
</title><style>
.pre-loader
{
position
:
absolute
;
top
:
calc
(
50%
-
32px
);
left
:
calc
(
50%
-
32px
);
width
:
64px
;
height
:
64px
;
border-radius
:
50%
;
perspective
:
800px
}
.pre-loader
.inner
{
position
:
absolute
;
box-sizing
:
border-box
;
width
:
100%
;
height
:
100%
;
border-radius
:
50%
}
.pre-loader
.inner.one
{
left
:
0
;
top
:
0
;
-webkit-animation
:
rotate-one
1s
linear
infinite
;
animation
:
rotate-one
1s
linear
infinite
;
border-bottom
:
3px
solid
#bc9048
}
.pre-loader
.inner.two
{
right
:
0
;
top
:
0
;
-webkit-animation
:
rotate-two
1s
linear
infinite
;
animation
:
rotate-two
1s
linear
infinite
;
border-right
:
3px
solid
#74aeff
}
.pre-loader
.inner.three
{
right
:
0
;
bottom
:
0
;
-webkit-animation
:
rotate-three
1s
linear
infinite
;
animation
:
rotate-three
1s
linear
infinite
;
border-top
:
3px
solid
#caef74
}
@keyframes
rotate-one
{
0
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
0
);
transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
0
)}
100
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
360deg
);
transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
360deg
)}}
@keyframes
rotate-two
{
0
%
{
-webkit-transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
0
);
transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
0
)}
100
%
{
-webkit-transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
360deg
);
transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
360deg
)}}
@keyframes
rotate-three
{
0
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
0
);
transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
0
)}
100
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
360deg
);
transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
360deg
)}}
</style><link
href=
"https://lib.baomitu.com/element-ui/2.13.2/theme-chalk/index.css"
rel=
"stylesheet"
><link
href=
"https://lib.baomitu.com/monaco-editor/0.19.3/min/vs/editor/editor.main.css"
rel=
"stylesheet"
><script
src=
"https://lib.baomitu.com/vue/2.6.11/vue.min.js"
></script><script
src=
"https://lib.baomitu.com/vue-router/3.1.3/vue-router.min.js"
></script><script
src=
"https://lib.baomitu.com/element-ui/2.13.2/index.js"
></script><link
href=
"css/chunk-02a5a3a9.5ca0b091.css"
rel=
"prefetch"
><link
href=
"css/chunk-18e0ea77.04c9f0cf.css"
rel=
"prefetch"
><link
href=
"css/chunk-29fd0152.5ca0b091.css"
rel=
"prefetch"
><link
href=
"css/chunk-3006e7c0.263a45f1.css"
rel=
"prefetch"
><link
href=
"css/chunk-30179e6c.f89cccc5.css"
rel=
"prefetch"
><link
href=
"css/chunk-358e2103.ad6bf27a.css"
rel=
"prefetch"
><link
href=
"css/chunk-525fc2d8.84a55126.css"
rel=
"prefetch"
><link
href=
"css/chunk-5a68d65e.265b8789.css"
rel=
"prefetch"
><link
href=
"css/chunk-5b2534c0.404c0fca.css"
rel=
"prefetch"
><link
href=
"css/chunk-6aa30806.5ca0b091.css"
rel=
"prefetch"
><link
href=
"css/chunk-7c52297c.61b80532.css"
rel=
"prefetch"
><link
href=
"css/chunk-e78c3d4c.2ab27357.css"
rel=
"prefetch"
><link
href=
"css/parser-home.b5026cff.css"
rel=
"prefetch"
><link
href=
"css/tinymce-example.0e433876.css"
rel=
"prefetch"
><link
href=
"js/chunk-02a5a3a9.78f2297b.js"
rel=
"prefetch"
><link
href=
"js/chunk-18e0ea77.71a934e6.js"
rel=
"prefetch"
><link
href=
"js/chunk-29fd0152.ac2e6d8a.js"
rel=
"prefetch"
><link
href=
"js/chunk-3006e7c0.3c1f4d0c.js"
rel=
"prefetch"
><link
href=
"js/chunk-30179e6c.485a62e2.js"
rel=
"prefetch"
><link
href=
"js/chunk-358e2103.62d5b25a.js"
rel=
"prefetch"
><link
href=
"js/chunk-525fc2d8.4b415298.js"
rel=
"prefetch"
><link
href=
"js/chunk-5a68d65e.33db689d.js"
rel=
"prefetch"
><link
href=
"js/chunk-5b2534c0.a0d64759.js"
rel=
"prefetch"
><link
href=
"js/chunk-6aa30806.fc92c339.js"
rel=
"prefetch"
><link
href=
"js/chunk-7c52297c.c0a80b51.js"
rel=
"prefetch"
><link
href=
"js/chunk-e78c3d4c.09ead955.js"
rel=
"prefetch"
><link
href=
"js/chunk-fec0be80.46ae2c64.js"
rel=
"prefetch"
><link
href=
"js/parser-home.1cbe416e.js"
rel=
"prefetch"
><link
href=
"js/tinymce-example.0f8d90cb.js"
rel=
"prefetch"
><link
href=
"css/index.4307d532.css"
rel=
"preload"
as=
"style"
><link
href=
"js/chunk-vendors.0fa4ad9a.js"
rel=
"preload"
as=
"script"
><link
href=
"js/index.f19c1f4f.js"
rel=
"preload"
as=
"script"
><link
href=
"css/index.4307d532.css"
rel=
"stylesheet"
></head><body><noscript><strong>
抱歉,javascript被禁用,请开启后重试。
</strong></noscript><div
id=
"app"
></div><div
class=
"pre-loader"
id=
"pre-loader"
><div
class=
"inner one"
></div><div
class=
"inner two"
></div><div
class=
"inner three"
></div></div><script
src=
"js/chunk-vendors.0fa4ad9a.js"
></script><script
src=
"js/index.f19c1f4f.js"
></script></body></html>
<!doctype html>
<html
lang=
"zh"
><head><meta
charset=
"utf-8"
><meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
><meta
name=
"viewport"
content=
"width=device-width,initial-scale=0,maximum-scale=0,user-scalable=yes,shrink-to-fit=no"
><link
rel=
"icon"
href=
"favicon.ico"
><title>
workFlow
</title><style>
.pre-loader
{
position
:
absolute
;
top
:
calc
(
50%
-
32px
);
left
:
calc
(
50%
-
32px
);
width
:
64px
;
height
:
64px
;
border-radius
:
50%
;
perspective
:
800px
}
.pre-loader
.inner
{
position
:
absolute
;
box-sizing
:
border-box
;
width
:
100%
;
height
:
100%
;
border-radius
:
50%
}
.pre-loader
.inner.one
{
left
:
0
;
top
:
0
;
-webkit-animation
:
rotate-one
1s
linear
infinite
;
animation
:
rotate-one
1s
linear
infinite
;
border-bottom
:
3px
solid
#bc9048
}
.pre-loader
.inner.two
{
right
:
0
;
top
:
0
;
-webkit-animation
:
rotate-two
1s
linear
infinite
;
animation
:
rotate-two
1s
linear
infinite
;
border-right
:
3px
solid
#74aeff
}
.pre-loader
.inner.three
{
right
:
0
;
bottom
:
0
;
-webkit-animation
:
rotate-three
1s
linear
infinite
;
animation
:
rotate-three
1s
linear
infinite
;
border-top
:
3px
solid
#caef74
}
@keyframes
rotate-one
{
0
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
0
);
transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
0
)}
100
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
360deg
);
transform
:
rotateX
(
35deg
)
rotateY
(
-45deg
)
rotateZ
(
360deg
)}}
@keyframes
rotate-two
{
0
%
{
-webkit-transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
0
);
transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
0
)}
100
%
{
-webkit-transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
360deg
);
transform
:
rotateX
(
50deg
)
rotateY
(
10deg
)
rotateZ
(
360deg
)}}
@keyframes
rotate-three
{
0
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
0
);
transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
0
)}
100
%
{
-webkit-transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
360deg
);
transform
:
rotateX
(
35deg
)
rotateY
(
55deg
)
rotateZ
(
360deg
)}}
</style><link
href=
"https://lib.baomitu.com/element-ui/2.13.2/theme-chalk/index.css"
rel=
"stylesheet"
><link
href=
"https://lib.baomitu.com/monaco-editor/0.19.3/min/vs/editor/editor.main.css"
rel=
"stylesheet"
><script
src=
"https://lib.baomitu.com/vue/2.6.11/vue.min.js"
></script><script
src=
"https://lib.baomitu.com/vue-router/3.1.3/vue-router.min.js"
></script><script
src=
"https://lib.baomitu.com/element-ui/2.13.2/index.js"
></script><link
href=
"css/chunk-02a5a3a9.5ca0b091.css"
rel=
"prefetch"
><link
href=
"css/chunk-18e0ea77.04c9f0cf.css"
rel=
"prefetch"
><link
href=
"css/chunk-29fd0152.5ca0b091.css"
rel=
"prefetch"
><link
href=
"css/chunk-3006e7c0.263a45f1.css"
rel=
"prefetch"
><link
href=
"css/chunk-30179e6c.f89cccc5.css"
rel=
"prefetch"
><link
href=
"css/chunk-525fc2d8.84a55126.css"
rel=
"prefetch"
><link
href=
"css/chunk-5a68d65e.265b8789.css"
rel=
"prefetch"
><link
href=
"css/chunk-5b2534c0.404c0fca.css"
rel=
"prefetch"
><link
href=
"css/chunk-6aa30806.5ca0b091.css"
rel=
"prefetch"
><link
href=
"css/chunk-7c52297c.61b80532.css"
rel=
"prefetch"
><link
href=
"css/chunk-d57021c4.e910a08a.css"
rel=
"prefetch"
><link
href=
"css/chunk-e78c3d4c.2ab27357.css"
rel=
"prefetch"
><link
href=
"css/parser-home.49a6f01c.css"
rel=
"prefetch"
><link
href=
"js/chunk-02a5a3a9.78f2297b.js"
rel=
"prefetch"
><link
href=
"js/chunk-18e0ea77.71a934e6.js"
rel=
"prefetch"
><link
href=
"js/chunk-29fd0152.ac2e6d8a.js"
rel=
"prefetch"
><link
href=
"js/chunk-3006e7c0.f130947b.js"
rel=
"prefetch"
><link
href=
"js/chunk-30179e6c.485a62e2.js"
rel=
"prefetch"
><link
href=
"js/chunk-525fc2d8.4b415298.js"
rel=
"prefetch"
><link
href=
"js/chunk-5a68d65e.33db689d.js"
rel=
"prefetch"
><link
href=
"js/chunk-5b2534c0.a0d64759.js"
rel=
"prefetch"
><link
href=
"js/chunk-6aa30806.b84291da.js"
rel=
"prefetch"
><link
href=
"js/chunk-7c52297c.c0a80b51.js"
rel=
"prefetch"
><link
href=
"js/chunk-d57021c4.30f0b978.js"
rel=
"prefetch"
><link
href=
"js/chunk-e78c3d4c.d6819a29.js"
rel=
"prefetch"
><link
href=
"js/parser-home.b9b583f2.js"
rel=
"prefetch"
><link
href=
"css/index.4307d532.css"
rel=
"preload"
as=
"style"
><link
href=
"js/chunk-vendors.0fa4ad9a.js"
rel=
"preload"
as=
"script"
><link
href=
"js/index.ed799595.js"
rel=
"preload"
as=
"script"
><link
href=
"css/index.4307d532.css"
rel=
"stylesheet"
></head><body><noscript><strong>
抱歉,javascript被禁用,请开启后重试。
</strong></noscript><div
id=
"app"
></div><div
class=
"pre-loader"
id=
"pre-loader"
><div
class=
"inner one"
></div><div
class=
"inner two"
></div><div
class=
"inner three"
></div></div><script
src=
"js/chunk-vendors.0fa4ad9a.js"
></script><script
src=
"js/index.ed799595.js"
></script></body></html>
\ No newline at end of file
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论