Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
workflow-core
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
黄夏豪
workflow-core
Commits
03e8fa58
提交
03e8fa58
authored
3月 09, 2021
作者:
HASEE
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master'
上级
d027b7f1
5088737b
隐藏空白字符变更
内嵌
并排
正在显示
26 个修改的文件
包含
692 行增加
和
195 行删除
+692
-195
WebMvcConfig.java
src/main/java/com/tykj/workflowcore/WebMvcConfig.java
+37
-0
Callable.java
.../java/com/tykj/workflowcore/api/annotations/Callable.java
+11
-0
CallableApi.java
...va/com/tykj/workflowcore/api/annotations/CallableApi.java
+15
-0
ApiController.java
...a/com/tykj/workflowcore/api/controller/ApiController.java
+26
-0
ApiInfo.java
src/main/java/com/tykj/workflowcore/api/entity/ApiInfo.java
+21
-0
ClassInfo.java
...main/java/com/tykj/workflowcore/api/entity/ClassInfo.java
+18
-0
EntityInfo.java
...ain/java/com/tykj/workflowcore/api/entity/EntityInfo.java
+20
-0
Parameter.java
...main/java/com/tykj/workflowcore/api/entity/Parameter.java
+16
-0
ApiService.java
...in/java/com/tykj/workflowcore/api/service/ApiService.java
+196
-0
SpringBeanService.java
.../com/tykj/workflowcore/api/service/SpringBeanService.java
+42
-0
ResultObj.java
...ain/java/com/tykj/workflowcore/base/result/ResultObj.java
+30
-0
ResultUtil.java
...in/java/com/tykj/workflowcore/base/result/ResultUtil.java
+85
-0
FlowsInfoController.java
...wcore/workflow_editer/controller/FlowsInfoController.java
+27
-11
WorkFlowController.java
...owcore/workflow_editer/controller/WorkFlowController.java
+7
-9
NodePage.java
...om/tykj/workflowcore/workflow_editer/entity/NodePage.java
+4
-0
WorkFlowRole.java
...ykj/workflowcore/workflow_editer/entity/WorkFlowRole.java
+9
-7
WorkFlowUser.java
...ykj/workflowcore/workflow_editer/entity/WorkFlowUser.java
+4
-7
RoleMapper.java
.../tykj/workflowcore/workflow_editer/mapper/RoleMapper.java
+0
-17
UserMapper.java
.../tykj/workflowcore/workflow_editer/mapper/UserMapper.java
+0
-17
NodePageService.java
...workflowcore/workflow_editer/service/NodePageService.java
+8
-0
UserService.java
...ykj/workflowcore/workflow_editer/service/UserService.java
+25
-15
WorkFlowService.java
...workflowcore/workflow_editer/service/WorkFlowService.java
+7
-21
NodePageServiceImpl.java
...ore/workflow_editer/service/impl/NodePageServiceImpl.java
+7
-0
WorkFlowServiceImpl.java
...ore/workflow_editer/service/impl/WorkFlowServiceImpl.java
+42
-91
FlowsInfoVo.java
...com/tykj/workflowcore/workflow_editer/vo/FlowsInfoVo.java
+8
-0
NextTaskVo.java
.../com/tykj/workflowcore/workflow_editer/vo/NextTaskVo.java
+27
-0
没有找到文件。
src/main/java/com/tykj/workflowcore/WebMvcConfig.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.servlet.config.annotation.CorsRegistry
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
/**
* @author zsp
* @version V1.0
* @class WebMvcConfig
* @packageName com.example.personnelmanager.common.config
* @data 2020/6/11
**/
@Configuration
public
class
WebMvcConfig
{
@Bean
public
WebMvcConfigurer
corsConfigurer
()
{
return
new
WebMvcConfigurer
()
{
@Override
public
void
addCorsMappings
(
CorsRegistry
registry
)
{
registry
.
addMapping
(
"/**"
)
.
allowedOriginPatterns
(
"*"
)
.
allowCredentials
(
true
)
.
allowedMethods
(
"GET"
,
"POST"
,
"DELETE"
,
"PUT"
,
"PATCH"
)
.
maxAge
(
3600
);
}
};
}
}
src/main/java/com/tykj/workflowcore/api/annotations/Callable.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
annotations
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
Callable
{
}
src/main/java/com/tykj/workflowcore/api/annotations/CallableApi.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
annotations
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
METHOD
)
public
@interface
CallableApi
{
String
name
()
default
""
;
String
description
()
default
""
;
}
src/main/java/com/tykj/workflowcore/api/controller/ApiController.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
controller
;
import
com.tykj.workflowcore.api.entity.ClassInfo
;
import
com.tykj.workflowcore.api.service.ApiService
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
@RestController
(
"/api/info"
)
public
class
ApiController
{
private
final
ApiService
apiService
;
public
ApiController
(
ApiService
apiService
)
{
this
.
apiService
=
apiService
;
}
@GetMapping
public
ResponseEntity
<
List
<
ClassInfo
>>
findAll
(){
return
ResponseEntity
.
ok
(
apiService
.
findAll
());
}
}
src/main/java/com/tykj/workflowcore/api/entity/ApiInfo.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.util.List
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
ApiInfo
{
private
String
name
;
private
List
<
EntityInfo
>
params
;
private
EntityInfo
ret
;
}
src/main/java/com/tykj/workflowcore/api/entity/ClassInfo.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.util.List
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
ClassInfo
{
private
String
name
;
private
List
<
ApiInfo
>
apiInfos
;
}
src/main/java/com/tykj/workflowcore/api/entity/EntityInfo.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.util.List
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
EntityInfo
{
private
String
type
;
private
String
name
;
private
List
<
EntityInfo
>
fields
;
}
src/main/java/com/tykj/workflowcore/api/entity/Parameter.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
Parameter
{
private
String
className
;
private
Object
obj
;
}
src/main/java/com/tykj/workflowcore/api/service/ApiService.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
service
;
import
com.tykj.workflowcore.api.annotations.Callable
;
import
com.tykj.workflowcore.api.annotations.CallableApi
;
import
com.tykj.workflowcore.api.entity.ApiInfo
;
import
com.tykj.workflowcore.api.entity.ClassInfo
;
import
com.tykj.workflowcore.api.entity.EntityInfo
;
import
com.tykj.workflowcore.api.entity.Parameter
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
java.io.File
;
import
java.io.IOException
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.net.URL
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
java
.
lang
.
String
.
format
;
@Slf4j
@Service
public
class
ApiService
{
private
final
SpringBeanService
springBeanService
;
public
ApiService
(
SpringBeanService
springBeanService
)
{
this
.
springBeanService
=
springBeanService
;
}
/**
* 读取主项目中的所有带有@CallAble注解的类中带有@CallAbleApi注解的方法
* 解析成一个结构化列表数据并返回
*
* @return 结构化列表数据,内容为带有指定注解的方法列表,也就是列出主项目中可调用的方法。
*/
public
List
<
ClassInfo
>
findAll
()
{
List
<
ClassInfo
>
classInfos
=
load
();
for
(
ClassInfo
classInfo
:
classInfos
)
{
System
.
out
.
println
(
classInfo
);
}
return
classInfos
;
}
private
List
<
ClassInfo
>
load
()
{
//获取所有类
List
<
Class
<?>>
classes
=
loadClassByLoader
(
getClass
().
getClassLoader
());
return
classes
.
stream
()
.
map
(
this
::
classInfo
)
.
filter
(
Objects:
:
nonNull
)
.
collect
(
Collectors
.
toList
());
}
private
ClassInfo
classInfo
(
Class
<?>
clz
)
{
try
{
//确认Callable注解
if
(
clz
.
isAnnotationPresent
(
Callable
.
class
))
{
List
<
ApiInfo
>
apiInfos
=
Arrays
.
stream
(
clz
.
getMethods
())
.
map
(
this
::
apiInfo
)
.
filter
(
Objects:
:
nonNull
)
.
collect
(
Collectors
.
toList
());
return
new
ClassInfo
(
clz
.
getName
(),
apiInfos
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
private
ApiInfo
apiInfo
(
Method
method
)
{
//确认CallableApi注解
if
(
method
.
isAnnotationPresent
(
CallableApi
.
class
))
{
List
<
EntityInfo
>
params
=
Arrays
.
stream
(
method
.
getParameters
())
.
map
(
parameter
->
entityInfo
(
parameter
.
getType
(),
parameter
.
getName
()))
.
collect
(
Collectors
.
toList
());
EntityInfo
ret
=
entityInfo
(
method
.
getReturnType
(),
null
);
return
new
ApiInfo
(
method
.
getName
(),
params
,
ret
);
}
else
{
return
null
;
}
}
private
EntityInfo
entityInfo
(
Class
<?>
clz
,
String
name
)
{
String
classType
=
clz
.
getName
();
List
<
EntityInfo
>
fields
=
new
ArrayList
<>();
if
(
isNotBasicClass
(
clz
))
{
for
(
Field
field
:
clz
.
getDeclaredFields
())
{
Class
<?>
fieldClass
=
field
.
getType
();
String
fieldName
=
field
.
getName
();
field
.
setAccessible
(
true
);
//确认类中是否嵌套了相同类型的字段 防止死循环
boolean
isDifferentClass
=
!
Objects
.
equals
(
clz
,
fieldClass
);
EntityInfo
fieldClassInfo
;
if
(
isDifferentClass
)
{
fieldClassInfo
=
entityInfo
(
fieldClass
,
fieldName
);
}
else
{
fieldClassInfo
=
new
EntityInfo
(
fieldClass
.
getSimpleName
(),
field
.
getName
(),
new
ArrayList
<>());
}
fields
.
add
(
fieldClassInfo
);
}
}
return
new
EntityInfo
(
classType
,
name
,
fields
);
}
private
static
Boolean
isNotBasicClass
(
Class
<?>
clz
)
{
String
packagePath
=
clz
.
getPackage
().
getName
();
return
!
Objects
.
equals
(
packagePath
,
"java.lang"
)
&&
!
Objects
.
equals
(
packagePath
,
"java.util"
);
}
/**
* 提供参数,调用指定类的指定方法,返回调用后的结果。
* 出异常时返回null
*
* @param className 类名
* @param apiName 方法名
* @param parameters 参数数据
* @return 调用后的返回值
*/
public
Object
invoke
(
String
className
,
String
apiName
,
List
<
Parameter
>
parameters
)
{
try
{
Class
<?>
clz
=
getClass
(
className
);
Class
<?>[]
parameterTypes
=
parameters
.
stream
()
.
map
(
Parameter:
:
getClassName
)
.
map
(
this
::
getClass
)
.
toArray
(
Class
[]::
new
);
Method
method
=
clz
.
getMethod
(
apiName
,
parameterTypes
);
Object
bean
=
springBeanService
.
getBean
(
clz
);
Object
[]
params
=
parameters
.
stream
()
.
map
(
Parameter:
:
getObj
)
.
toArray
();
return
method
.
invoke
(
bean
,
params
);
}
catch
(
RuntimeException
|
NoSuchMethodException
|
IllegalAccessException
|
InvocationTargetException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
private
Class
<?>
getClass
(
String
className
)
{
try
{
return
Class
.
forName
(
className
);
}
catch
(
ClassNotFoundException
e
)
{
log
.
error
(
format
(
"未能找到该类:%s"
,
className
));
throw
new
RuntimeException
();
}
}
//通过loader加载所有类
private
List
<
Class
<?>>
loadClassByLoader
(
ClassLoader
load
)
{
List
<
Class
<?>>
classes
=
new
ArrayList
<>();
try
{
Enumeration
<
URL
>
urls
=
load
.
getResources
(
""
);
//放所有类型
while
(
urls
.
hasMoreElements
())
{
URL
url
=
urls
.
nextElement
();
//文件类型(其实是文件夹)
if
(
url
.
getProtocol
().
equals
(
"file"
))
{
loadClassByPath
(
null
,
url
.
getPath
(),
classes
,
load
);
}
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
return
classes
;
}
//通过文件路径加载所有类 root 主要用来替换path中前缀(除包路径以外的路径)
private
void
loadClassByPath
(
String
root
,
String
path
,
List
<
Class
<?>>
list
,
ClassLoader
load
)
{
File
f
=
new
File
(
path
);
if
(
root
==
null
)
root
=
f
.
getPath
();
//判断是否是class文件
if
(
f
.
isFile
()
&&
f
.
getName
().
matches
(
"^.*\\.class$"
))
{
try
{
String
classPath
=
f
.
getPath
();
//截取出className 将路径分割符替换为.(windows是\ linux、mac是/)
String
className
=
classPath
.
substring
(
root
.
length
()
+
1
,
classPath
.
length
()
-
6
).
replace
(
'/'
,
'.'
).
replace
(
'\\'
,
'.'
);
list
.
add
(
load
.
loadClass
(
className
));
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
}
}
else
{
File
[]
fs
=
f
.
listFiles
();
if
(
fs
==
null
)
return
;
for
(
File
file
:
fs
)
{
loadClassByPath
(
root
,
file
.
getPath
(),
list
,
load
);
}
}
}
}
src/main/java/com/tykj/workflowcore/api/service/SpringBeanService.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
api
.
service
;
import
org.springframework.beans.BeansException
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.stereotype.Component
;
import
static
java
.
util
.
Objects
.
isNull
;
@Component
public
class
SpringBeanService
implements
ApplicationContextAware
{
private
ApplicationContext
applicationContext
;
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
if
(
isNull
(
this
.
applicationContext
))
{
this
.
applicationContext
=
applicationContext
;
}
}
//获取applicationContext
public
ApplicationContext
getApplicationContext
()
{
return
this
.
applicationContext
;
}
//通过name获取 Bean.
public
Object
getBean
(
String
name
){
return
getApplicationContext
().
getBean
(
name
);
}
//通过class获取Bean.
public
<
T
>
T
getBean
(
Class
<
T
>
clazz
){
return
getApplicationContext
().
getBean
(
clazz
);
}
//通过name,以及Clazz返回指定的Bean
public
<
T
>
T
getBean
(
String
name
,
Class
<
T
>
clazz
){
return
getApplicationContext
().
getBean
(
name
,
clazz
);
}
}
\ No newline at end of file
src/main/java/com/tykj/workflowcore/base/result/ResultObj.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
base
.
result
;
import
com.fasterxml.jackson.annotation.JsonPropertyOrder
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* @author dengdiyi
* @description 接口返回统一标准类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonPropertyOrder
(
value
=
{
"message"
,
"data"
})
public
class
ResultObj
<
T
>
{
private
T
data
;
private
String
message
;
public
ResultObj
(
T
o
)
{
this
.
data
=
o
;
this
.
message
=
"no message"
;
}
public
ResultObj
(
String
m
)
{
this
.
message
=
m
;
}
}
src/main/java/com/tykj/workflowcore/base/result/ResultUtil.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
base
.
result
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
/**
* @author HuangXiahao
* @version V1.0
* @class ResultMessage
* @packageName com.example.hello.demo.resultObject
**/
public
class
ResultUtil
<
T
>
{
/**
* 成功返回结果
*
* @param data 获取的数据
*/
public
static
<
T
>
ResponseEntity
<
ResultObj
<
T
>>
success
(
T
data
)
{
return
ResponseEntity
.
ok
(
new
ResultObj
<>(
data
));
}
/**
* 成功返回结果
*
* @param data 获取的数据
*/
public
static
<
T
>
ResponseEntity
success
(
T
data
,
HttpHeaders
headers
)
{
return
new
ResponseEntity
(
new
ResultObj
(
data
),
headers
,
HttpStatus
.
OK
);
}
/**
* 失败返回结果
*/
public
static
<
T
>
ResponseEntity
failed
()
{
return
ResponseEntity
.
status
(
500
).
body
(
new
ResultObj
(
"服务器内部发生错误"
));
}
/**
* 失败返回结果
*/
public
static
<
T
>
ResponseEntity
failed
(
T
content
)
{
return
new
ResponseEntity
(
new
ResultObj
(
content
),
HttpStatus
.
INTERNAL_SERVER_ERROR
);
}
/**
* 失败返回结果
*/
public
static
<
T
>
ResponseEntity
failed
(
HttpStatus
httpStatus
)
{
return
new
ResponseEntity
(
httpStatus
);
}
/**
* 失败返回结果
*/
public
static
<
T
>
ResponseEntity
failed
(
HttpStatus
httpStatus
,
T
content
)
{
return
new
ResponseEntity
(
new
ResultObj
(
content
),
httpStatus
);
}
/**
* 参数验证失败返回结果
*/
public
static
<
T
>
ResponseEntity
validateFailed
(
T
content
)
{
return
failed
(
HttpStatus
.
INTERNAL_SERVER_ERROR
,
content
);
}
/**
* 未登录返回结果
*/
public
static
<
T
>
ResponseEntity
unauthorized
()
{
return
failed
(
HttpStatus
.
UNAUTHORIZED
);
}
/**
* 未授权返回结果
*/
public
static
<
T
>
ResponseEntity
forbidden
()
{
return
failed
(
HttpStatus
.
FORBIDDEN
);
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/controller/FlowsInfoController.java
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
controller
;
import
com.tykj.workflowcore.workflow_editer.entity.FlowsInfo
;
import
com.tykj.workflowcore.workflow_editer.service.FlowInfoService
;
import
com.tykj.workflowcore.workflow_editer.service.NodePageService
;
import
com.tykj.workflowcore.workflow_editer.service.VariableStorageService
;
import
com.tykj.workflowcore.workflow_editer.service.WorkFlowService
;
import
com.tykj.workflowcore.workflow_editer.entity.NodePage
;
import
com.tykj.workflowcore.workflow_editer.entity.WorkFlowUser
;
import
com.tykj.workflowcore.workflow_editer.service.*
;
import
com.tykj.workflowcore.workflow_editer.vo.DeployedVo
;
import
com.tykj.workflowcore.workflow_editer.vo.FlowsInfoVo
;
import
com.tykj.workflowcore.workflow_editer.vo.PageVo
;
...
...
@@ -14,7 +13,6 @@ import org.springframework.beans.BeanUtils;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Page
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.FileNotFoundException
;
import
java.util.ArrayList
;
...
...
@@ -32,6 +30,7 @@ import java.util.List;
@Api
(
"流程管理接口"
)
@RequestMapping
(
"/flowsInfo"
)
public
class
FlowsInfoController
{
@Autowired
private
FlowInfoService
flowInfoService
;
...
...
@@ -41,8 +40,12 @@ public class FlowsInfoController {
@Autowired
private
NodePageService
nodePageService
;
@Autowired
private
UserService
userService
;
@Autowired
private
VariableStorageService
variableStorageService
;
@PostMapping
(
"/getAllFlowsInfo"
)
@ApiOperation
(
value
=
"查询所有流程"
,
notes
=
"分页查询"
)
public
Page
<
FlowsInfo
>
getAllFlowsInfo
(
@RequestBody
PageVo
pageVo
){
...
...
@@ -73,12 +76,13 @@ public class FlowsInfoController {
return
deployedVos
;
}
@PostMapping
(
"/saveXml"
)
@ApiOperation
(
"保存xml"
)
public
String
saveXml
(
@RequestParam
(
"file"
)
MultipartFile
file
){
String
xml
=
workFlowService
.
saveXml
(
file
);
return
xml
;
}
// @PostMapping("/saveXml")
// @ApiOperation("保存xml")
// public String saveXml(@RequestParam("file") MultipartFile file){
// String xml = workFlowService.saveXml(file);
// return xml;
// }
@GetMapping
(
"/deploy/{id}"
)
@ApiOperation
(
value
=
"部署流程"
,
notes
=
"0 部署成功"
)
public
Integer
deploy
(
@PathVariable
(
"id"
)
Long
id
)
throws
FileNotFoundException
{
...
...
@@ -94,6 +98,8 @@ public class FlowsInfoController {
@PostMapping
(
"/saveXml02"
)
@ApiOperation
(
value
=
"保存xml02"
)
public
void
saveXml02
(
@RequestBody
FlowsInfoVo
flowsInfoVo
)
{
List
<
NodePage
>
nodePages
=
flowsInfoVo
.
getNodePages
();
nodePageService
.
saveNodePages
(
nodePages
);
workFlowService
.
flowXml
(
flowsInfoVo
);
}
...
...
@@ -109,4 +115,14 @@ public class FlowsInfoController {
flowInfoService
.
findByDesc
(
flowsInfoVo
);
}
@PostMapping
(
"/createFlow"
)
public
Long
createFlow
(
@RequestBody
FlowsInfoVo
flowsInfovo
){
return
workFlowService
.
createFlow
(
flowsInfovo
.
toEntity
());
}
@PostMapping
(
"/test"
)
public
WorkFlowUser
test
(){
return
userService
.
getCurrentUser
();
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/controller/WorkFlowController.java
浏览文件 @
03e8fa58
...
...
@@ -4,12 +4,10 @@ import com.tykj.workflowcore.workflow_editer.entity.FlowsInfo;
import
com.tykj.workflowcore.workflow_editer.service.FlowInfoService
;
import
com.tykj.workflowcore.workflow_editer.service.WorkFlowService
;
import
com.tykj.workflowcore.workflow_editer.util.PageUtil
;
import
com.tykj.workflowcore.workflow_editer.vo.PageVo
;
import
com.tykj.workflowcore.workflow_editer.vo.StartFlowVo
;
import
com.tykj.workflowcore.workflow_editer.vo.SuspendVo
;
import
com.tykj.workflowcore.workflow_editer.vo.TaskVo
;
import
com.tykj.workflowcore.workflow_editer.vo.*
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.flowable.task.api.Task
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -56,15 +54,15 @@ public class WorkFlowController {
@PostMapping
(
"/findUserTask"
)
@ApiOperation
(
"任务个人待办列表"
)
public
List
<
Map
<
String
,
Object
>>
findUserTask
(
@RequestBody
PageVo
page
Vo
){
List
<
Map
<
String
,
Object
>>
mapList
=
workFlowService
.
findTaskByUserId
(
pageVo
.
getUserId
());
List
list
=
PageUtil
.
startPage
(
mapList
,
pageVo
.
getPageNum
(),
pageVo
.
getPageSize
()
);
return
list
;
public
List
<
Map
<
String
,
Object
>>
findUserTask
(
@RequestBody
NextTaskVo
nextTask
Vo
){
return
workFlowService
.
findTaskByUserId
(
nextTaskVo
);
}
@PostMapping
(
"/findTaskDetail"
)
@ApiOperation
(
"任务个人待办详情"
)
public
List
<
Map
<
String
,
Object
>
>
findTaskDetail
(
Long
userId
,
String
taskId
){
public
Map
<
String
,
Object
>
findTaskDetail
(
Long
userId
,
String
taskId
){
return
workFlowService
.
findTaskDetail
(
userId
,
taskId
);
}
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/entity/NodePage.java
浏览文件 @
03e8fa58
...
...
@@ -37,4 +37,8 @@ public class NodePage {
@ApiModelProperty
(
"页面id"
)
private
long
pageId
;
private
String
flowKey
;
private
String
flowName
;
}
src/main/java/com/tykj/workflowcore/workflow_editer/entity/Role.java
→
src/main/java/com/tykj/workflowcore/workflow_editer/entity/
WorkFlow
Role.java
浏览文件 @
03e8fa58
...
...
@@ -18,12 +18,14 @@ import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public
class
Role
{
@Id
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
private
Long
id
;
public
class
WorkFlowRole
{
private
String
roleName
;
@Transient
List
<
User
>
userList
;
/**
* 例如: department,subject 等
*/
private
String
type
;
}
src/main/java/com/tykj/workflowcore/workflow_editer/entity/User.java
→
src/main/java/com/tykj/workflowcore/workflow_editer/entity/
WorkFlow
User.java
浏览文件 @
03e8fa58
...
...
@@ -22,14 +22,11 @@ import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Api
(
"用户表"
)
public
class
User
implements
Serializable
{
@Id
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
public
class
WorkFlowUser
implements
Serializable
{
private
Long
id
;
private
String
userName
;
private
String
passWord
;
private
String
age
;
private
String
birthday
;
}
src/main/java/com/tykj/workflowcore/workflow_editer/mapper/RoleMapper.java
deleted
100644 → 0
浏览文件 @
d027b7f1
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
mapper
;
import
com.tykj.workflowcore.workflow_editer.entity.Role
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
/**
* ClassName: RoleMapper
* Package: com.tykj.mapper
* Description:
* Datetime: 2021/2/23 15:08
*
* @Author: zsp
*/
public
interface
RoleMapper
extends
JpaRepository
<
Role
,
Long
>,
JpaSpecificationExecutor
<
Role
>
{
}
src/main/java/com/tykj/workflowcore/workflow_editer/mapper/UserMapper.java
deleted
100644 → 0
浏览文件 @
d027b7f1
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
mapper
;
import
com.tykj.workflowcore.workflow_editer.entity.User
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
/**
* ClassName: UserMapper
* Package: com.tykj.mapper
* Description:
* Datetime: 2021/2/23 14:49
*
* @Author: zsp
*/
public
interface
UserMapper
extends
JpaRepository
<
User
,
Long
>,
JpaSpecificationExecutor
<
User
>
{
}
src/main/java/com/tykj/workflowcore/workflow_editer/service/NodePageService.java
浏览文件 @
03e8fa58
...
...
@@ -2,6 +2,8 @@ package com.tykj.workflowcore.workflow_editer.service;
import
com.tykj.workflowcore.workflow_editer.entity.NodePage
;
import
java.util.List
;
/**
* ClassName: NodePageService
* Package: com.tykj.service
...
...
@@ -23,4 +25,10 @@ public interface NodePageService {
* @param nodePage
*/
void
saveNodePage
(
NodePage
nodePage
);
/**
* @param nodePages 集合
*/
void
saveNodePages
(
List
<
NodePage
>
nodePages
);
}
src/main/java/com/tykj/workflowcore/workflow_editer/service/UserService.java
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
service
;
//import org.springframework.security.core.userdetails.UserDetails;
import
com.tykj.workflowcore.workflow_editer.entity.WorkFlowRole
;
import
com.tykj.workflowcore.workflow_editer.entity.WorkFlowUser
;
import
java.util.List
;
/**
* ClassName: UserService
...
...
@@ -11,17 +13,25 @@ package com.tykj.workflowcore.workflow_editer.service;
*
* @Author: zsp
*/
//@Service
//public interface UserService {
// /**
// * 获取当前登录人的id
// * @return User对象
// */
// UserDetails getCurrentUserId();
//
// /**
// * 获取所有用户
// * @return 所有用户
// */
// List<User> getAllUser();
//}
public
interface
UserService
{
/**
* 获取当前登录人的id
* @return User对象
*/
WorkFlowUser
getCurrentUser
();
/**
* 获取所有用户
* @return 所有用户
*/
List
<
WorkFlowUser
>
getAllUser
();
/**
* 获取当前系统中的用户以及用户分组
* @return
*/
List
<
WorkFlowRole
>
getAllRole
();
}
src/main/java/com/tykj/workflowcore/workflow_editer/service/WorkFlowService.java
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
service
;
import
com.tykj.workflowcore.workflow_editer.entity.FlowsInfo
;
import
com.tykj.workflowcore.workflow_editer.vo.FlowsInfoVo
;
import
com.tykj.workflowcore.workflow_editer.vo.StartFlowVo
;
import
com.tykj.workflowcore.workflow_editer.vo.SuspendVo
;
import
com.tykj.workflowcore.workflow_editer.vo.TaskVo
;
import
com.tykj.workflowcore.workflow_editer.vo.*
;
import
org.flowable.task.api.Task
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -40,10 +38,10 @@ public interface WorkFlowService {
/**
* 创建流程
* @param flowsInfo
Vo
* @param flowsInfo
* @return 主键id
*/
Long
createFlow
(
@RequestBody
FlowsInfo
Vo
flowsInfoV
o
);
Long
createFlow
(
@RequestBody
FlowsInfo
flowsInf
o
);
/**
* 部署xml流程文件
...
...
@@ -68,10 +66,10 @@ public interface WorkFlowService {
/**
* 根据用户id进行任务待办查询
* @param
userId 用户id
* @param
nextTaskVo
* @return 任务列表
*/
List
<
Map
<
String
,
Object
>>
findTaskByUserId
(
Long
userId
);
List
<
Map
<
String
,
Object
>>
findTaskByUserId
(
NextTaskVo
nextTaskVo
);
/**
* 查看具体的任务详情
...
...
@@ -79,16 +77,7 @@ public interface WorkFlowService {
* @param taskId 任务Id
* @return 任务列表
*/
List
<
Map
<
String
,
Object
>>
findTaskDetail
(
Long
userId
,
String
taskId
);
/**
* 根据角色id进行任务待办查询
* @param roleId 角色id
* @return 任务列表
*/
List
<
Map
<
String
,
Object
>>
findByRoleId
(
Long
roleId
);
Map
<
String
,
Object
>
findTaskDetail
(
Long
userId
,
String
taskId
);
/**
...
...
@@ -107,9 +96,6 @@ public interface WorkFlowService {
//历史查询
//建立用户和组的关系
/**
* 任务的转交
* @param taskId 任务id
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/service/impl/NodePageServiceImpl.java
浏览文件 @
03e8fa58
...
...
@@ -6,6 +6,8 @@ import com.tykj.workflowcore.workflow_editer.service.NodePageService;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
/**
* ClassName: NodePageServiceImpl
* Package: com.tykj.service.impl
...
...
@@ -29,4 +31,9 @@ public class NodePageServiceImpl implements NodePageService {
nodePageMapper
.
save
(
nodePage
);
}
@Override
public
void
saveNodePages
(
List
<
NodePage
>
nodePages
)
{
nodePageMapper
.
saveAll
(
nodePages
);
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/service/impl/WorkFlowServiceImpl.java
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
service
.
impl
;
import
com.tykj.workflowcore.workflow_editer.entity.FlowsInfo
;
import
com.tykj.workflowcore.workflow_editer.entity.NodePage
;
import
com.tykj.workflowcore.workflow_editer.entity.Role
;
import
com.tykj.workflowcore.workflow_editer.entity.User
;
import
com.tykj.workflowcore.workflow_editer.entity.WorkFlowUser
;
import
com.tykj.workflowcore.workflow_editer.mapper.FlowsInfoMapper
;
import
com.tykj.workflowcore.workflow_editer.mapper.RoleMapper
;
import
com.tykj.workflowcore.workflow_editer.mapper.UserMapper
;
import
com.tykj.workflowcore.workflow_editer.service.NodePageService
;
import
com.tykj.workflowcore.workflow_editer.service.UserService
;
import
com.tykj.workflowcore.workflow_editer.service.WorkFlowService
;
import
com.tykj.workflowcore.workflow_editer.vo.FlowsInfoVo
;
import
com.tykj.workflowcore.workflow_editer.vo.StartFlowVo
;
import
com.tykj.workflowcore.workflow_editer.vo.SuspendVo
;
import
com.tykj.workflowcore.workflow_editer.vo.TaskVo
;
import
com.tykj.workflowcore.workflow_editer.vo.*
;
import
org.dom4j.Attribute
;
import
org.dom4j.Document
;
import
org.dom4j.DocumentException
;
import
org.dom4j.Element
;
import
org.dom4j.io.SAXReader
;
import
org.flowable.common.engine.impl.identity.Authentication
;
import
org.flowable.engine.HistoryService
;
import
org.flowable.engine.RepositoryService
;
import
org.flowable.engine.RuntimeService
;
import
org.flowable.engine.TaskService
;
import
org.flowable.engine.repository.Deployment
;
import
org.flowable.engine.runtime.ProcessInstance
;
import
org.flowable.task.api.Task
;
import
org.flowable.task.api.TaskQuery
;
import
org.flowable.task.api.history.HistoricTaskInstance
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
...
...
@@ -55,10 +52,9 @@ public class WorkFlowServiceImpl implements WorkFlowService {
@Autowired
private
FlowsInfoMapper
flowsInfoMapper
;
@Autowired
private
User
Mapper
userMapper
;
private
User
Service
userService
;
@Autowired
private
RoleMapper
roleMapper
;
private
HistoryService
historyService
;
@Autowired
private
NodePageService
nodePageService
;
...
...
@@ -134,15 +130,11 @@ public class WorkFlowServiceImpl implements WorkFlowService {
Long
id
=
flowsInfoVo
.
getId
();
String
flowKey
=
flowsInfoVo
.
getFlowKey
();
String
fileXml
=
flowsInfoVo
.
getFileXml
();
List
<
NodePage
>
nodePages
=
flowsInfoVo
.
getNodePages
();
for
(
NodePage
nodePage
:
nodePages
)
{
nodePageService
.
saveNodePage
(
nodePage
);
}
//生成xml文件
File
f
=
null
;
try
{
f
=
new
File
(
classLoader
.
getResource
(
""
).
getPath
()+
"/xml/"
+
flowKey
+
"bpmn20.xml"
);
f
=
new
File
(
classLoader
.
getResource
(
""
).
getPath
()+
"/xml/"
+
flowKey
+
"bpmn20.xml"
);
// 判断文件是否存在
if
(!
f
.
exists
()){
f
.
createNewFile
();
...
...
@@ -192,12 +184,8 @@ public class WorkFlowServiceImpl implements WorkFlowService {
}
@Override
public
Long
createFlow
(
FlowsInfo
Vo
flowsInfoVo
)
{
public
Long
createFlow
(
FlowsInfo
flowsInfo
)
{
FlowsInfo
flowsInfo
=
new
FlowsInfo
();
flowsInfo
.
setFlowKey
(
flowsInfoVo
.
getFlowKey
());
flowsInfo
.
setFlowName
(
flowsInfoVo
.
getFlowName
());
flowsInfo
.
setFlowDescribe
(
flowsInfoVo
.
getFlowDescribe
());
FlowsInfo
flowsInfo1
=
flowsInfoMapper
.
save
(
flowsInfo
);
return
flowsInfo1
.
getId
();
}
...
...
@@ -226,86 +214,49 @@ public class WorkFlowServiceImpl implements WorkFlowService {
//获取流程主键
String
flowKey
=
startFlowVo
.
getFlowKey
();
//设置流程发起人
WorkFlowUser
currentUser
=
userService
.
getCurrentUser
();
//调用业务服务接口 插入数据到记录表中 例如请假是插入请假表
Authentication
.
setAuthenticatedUserId
(
currentUser
.
getId
()+
""
);
//获取变量池
Map
<
String
,
Object
>
map
=
startFlowVo
.
getMap
();
ProcessInstance
processInstance
=
runtimeService
.
startProcessInstanceByKey
(
flowKey
,
map
);
Task
task
=
taskService
.
createTaskQuery
().
processInstanceId
(
processInstance
.
getProcessInstanceId
()).
singleResult
();
//获取当前人登录的id
// UserDetails userDetails = userService.getCurrentUserId();
// String username = userDetails.getUsername();
//通过用户名得到用户id
Long
userId
=
123L
;
taskService
.
setAssignee
(
task
.
getId
(),
Long
.
toString
(
userId
));
//调用业务服务接口 插入数据到记录表中 例如请假是插入请假表
taskService
.
complete
(
task
.
getId
());
}
@Override
public
List
<
Map
<
String
,
Object
>>
findTaskByUserId
(
Long
userId
)
{
// 查询个人待办,指定个人任务 流程变量就是${userId == 具体的数字}
List
<
Task
>
taskList
=
taskService
.
createTaskQuery
().
taskAssignee
(
Long
.
toString
(
userId
)).
orderByTaskCreateTime
().
desc
().
list
();
ArrayList
<
Map
<
String
,
Object
>>
list
=
new
ArrayList
<>();
//通过userId查询出userName
if
(
userMapper
.
findById
(
userId
).
isPresent
()){
User
user
=
userMapper
.
findById
(
userId
).
get
();
for
(
Task
task
:
taskList
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"taskId"
,
task
.
getId
());
map
.
put
(
"taskName"
,
task
.
getName
());
map
.
put
(
"taskAssigne"
,
user
.
getUserName
());
map
.
put
(
"time"
,
task
.
getCreateTime
());
map
.
put
(
"description"
,
task
.
getDescription
());
map
.
put
(
"processInstanceId"
,
task
.
getProcessInstanceId
());
list
.
add
(
map
);
}
}
return
list
;
}
public
List
<
Map
<
String
,
Object
>>
findTaskByUserId
(
NextTaskVo
nextTaskVo
)
{
@Override
public
List
<
Map
<
String
,
Object
>>
findTaskDetail
(
Long
userId
,
String
taskId
)
{
List
<
Map
<
String
,
Object
>>
listMap
=
new
ArrayList
<
Map
<
String
,
Object
>>();
TaskQuery
taskQuery
=
taskService
.
createTaskQuery
().
or
();
if
(
nextTaskVo
.
getUserId
()!=
null
){
taskQuery
.
taskCandidateUser
(
nextTaskVo
.
getUserId
()).
orderByTaskCreateTime
().
desc
();
}
if
(
nextTaskVo
.
getRoleId
()!=
null
&&
nextTaskVo
.
getRoleId
().
size
()>
0
){
taskQuery
.
taskCandidateGroupIn
(
nextTaskVo
.
getRoleId
()).
orderByTaskCreateTime
().
desc
();
}
List
<
Task
>
listTask
=
taskQuery
.
endOr
().
list
();
for
(
Task
task
:
listTask
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
ProcessInstance
processInstance
=
runtimeService
.
createProcessInstanceQuery
().
processInstanceId
(
task
.
getProcessInstanceId
()).
singleResult
();
String
startUserId
=
processInstance
.
getStartUserId
();
map
.
put
(
"taskName"
,
task
.
getName
());
map
.
put
(
"taskDesc"
,
task
.
getDescription
());
map
.
put
(
"createTime"
,
task
.
getCreateTime
());
map
.
put
(
"promoter"
,
startUserId
);
listMap
.
add
(
map
);
}
return
listMap
;
List
<
Map
<
String
,
Object
>>
mapList
=
findTaskByUserId
(
userId
);
Map
<
String
,
Object
>
variables
=
taskService
.
getVariables
(
taskId
);
mapList
.
add
(
variables
);
return
mapList
;
}
@Override
public
List
<
Map
<
String
,
Object
>>
findByRoleId
(
Long
roleId
)
{
//流程变量 ${roleId == 具体的数值}
// 先获取当前登录人的id
//通过userId来获取roleId
//根据roleId来查询userName
Role
role
=
roleMapper
.
findById
(
roleId
).
get
();
List
<
User
>
userList
=
role
.
getUserList
();
List
<
Task
>
taskList
=
taskService
.
createTaskQuery
().
taskCandidateUser
(
Long
.
toString
(
roleId
)).
list
();
ArrayList
<
Map
<
String
,
Object
>>
list
=
new
ArrayList
<>();
for
(
User
user
:
userList
)
{
for
(
Task
task
:
taskList
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"taskId"
,
task
.
getId
());
map
.
put
(
"taskName"
,
task
.
getName
());
map
.
put
(
"taskAssigne"
,
user
.
getUserName
());
map
.
put
(
"time"
,
task
.
getCreateTime
());
map
.
put
(
"description"
,
task
.
getDescription
());
map
.
put
(
"processInstanceId"
,
task
.
getProcessInstanceId
());
list
.
add
(
map
);
}
}
return
list
;
public
Map
<
String
,
Object
>
findTaskDetail
(
Long
userId
,
String
taskId
)
{
Map
<
String
,
Object
>
variables
=
taskService
.
getVariables
(
taskId
);
return
variables
;
}
@Override
...
...
@@ -336,7 +287,7 @@ public class WorkFlowServiceImpl implements WorkFlowService {
@Override
public
void
transferTask
(
String
taskId
,
Long
userId
)
{
taskService
.
setAssignee
(
taskId
,
Long
.
toString
(
userId
));
taskService
.
setAssignee
(
taskId
,
Long
.
toString
(
userId
));
}
@Override
...
...
src/main/java/com/tykj/workflowcore/workflow_editer/vo/FlowsInfoVo.java
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
vo
;
import
com.tykj.workflowcore.workflow_editer.entity.FlowsInfo
;
import
com.tykj.workflowcore.workflow_editer.entity.NodePage
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
org.springframework.beans.BeanUtils
;
import
java.util.Date
;
import
java.util.List
;
...
...
@@ -53,4 +55,10 @@ public class FlowsInfoVo {
@ApiModelProperty
()
private
List
<
NodePage
>
nodePages
;
public
FlowsInfo
toEntity
(){
FlowsInfo
flowsInfo
=
new
FlowsInfo
();
BeanUtils
.
copyProperties
(
this
,
flowsInfo
);
return
flowsInfo
;
}
}
src/main/java/com/tykj/workflowcore/workflow_editer/vo/NextTaskVo.java
0 → 100644
浏览文件 @
03e8fa58
package
com
.
tykj
.
workflowcore
.
workflow_editer
.
vo
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.util.List
;
/**
* ClassName: NextTaskVo
* Package: com.tykj.workflowcore.workflow_editer.vo
* Description:
* Datetime: 2021/3/5 17:47
*
* @Author: zsp
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
NextTaskVo
{
private
String
userId
;
private
List
<
String
>
roleId
;
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论