Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
提交反馈
为 GitLab 提交贡献
登录
切换导航
I
ibzdst
项目
项目
详情
动态
版本
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
议题
1
议题
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
ibiz4jteam
ibzdst
提交
3c81632a
提交
3c81632a
编写于
8月 31, 2022
作者:
ibizdev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
lab_xuhui 发布系统代码 [ibz-dst,应用]
上级
a740f537
变更
10
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
115 行增加
和
28 行删除
+115
-28
rule-engines.ts
app_web/src/mock/entity/rule-engines/rule-engines.ts
+38
-0
rule-engine-service-base.ts
app_web/src/service/rule-engine/rule-engine-service-base.ts
+28
-0
default-searchform-base.vue
...ct-catalog/default-searchform/default-searchform-base.vue
+2
-2
default-searchform-base.vue
.../rule-item/default-searchform/default-searchform-base.vue
+2
-2
main-grid-base.vue
app_web/src/widgets/rule-item/main-grid/main-grid-base.vue
+8
-22
IRuleEngineService.java
...java/cn/ibizlab/core/rule/service/IRuleEngineService.java
+2
-0
RuleEngineServiceImpl.java
...ibizlab/core/rule/service/impl/RuleEngineServiceImpl.java
+16
-0
h2_table.xml
ibzdst-core/src/main/resources/liquibase/h2_table.xml
+1
-1
systemResource.json
...st-core/src/main/resources/permission/systemResource.json
+1
-1
RuleEngineResource.java
...src/main/java/cn/ibizlab/api/rest/RuleEngineResource.java
+17
-0
未找到文件。
app_web/src/mock/entity/rule-engines/rule-engines.ts
浏览文件 @
3c81632a
...
...
@@ -281,6 +281,44 @@ mock.onPost(new RegExp(/^\/ruleengines\/?([a-zA-Z0-9\-\;]{0,35})\/save$/)).reply
return
[
status
,
data
];
});
// SyncRun
mock
.
onPost
(
new
RegExp
(
/^
\/
ruleengines
\/?([
a-zA-Z0-9
\-\;]{0,35})\/
syncrun$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:ruleengine 方法: SyncRun"
);
console
.
table
({
url
:
config
.
url
,
method
:
config
.
method
,
data
:
config
.
data
});
let
status
=
MockAdapter
.
mockStatus
(
config
);
if
(
status
!==
200
)
{
return
[
status
,
null
];
}
const
paramArray
:
Array
<
any
>
=
[
'engine_id'
];
const
matchArray
:
any
=
new
RegExp
(
/^
\/
ruleengines
\/([
a-zA-Z0-9
\-\;]{1,35})\/
syncrun$/
).
exec
(
config
.
url
);
let
tempValue
:
any
=
{};
if
(
matchArray
&&
matchArray
.
length
>
1
&&
paramArray
&&
paramArray
.
length
>
0
){
paramArray
.
forEach
((
item
:
any
,
index
:
number
)
=>
{
Object
.
defineProperty
(
tempValue
,
item
,
{
enumerable
:
true
,
value
:
matchArray
[
index
+
1
]
});
});
}
//let items = mockDatas ? mockDatas : [];
//let _items = items.find((item: any) => Object.is(item.engine_id, tempValue.engine_id));
let
data
=
JSON
.
parse
(
config
.
data
);
mockDatas
.
forEach
((
item
)
=>
{
if
(
item
[
'engine_id'
]
==
tempValue
[
'engine_id'
]
){
for
(
let
value
in
data
){
if
(
item
.
hasOwnProperty
(
value
)){
item
[
value
]
=
data
[
value
];
}
}
}
})
console
.
groupCollapsed
(
"response数据 status: "
+
status
+
" data: "
);
console
.
table
(
data
);
console
.
groupEnd
();
console
.
groupEnd
();
return
[
status
,
data
];
});
// Update
mock
.
onPut
(
new
RegExp
(
/^
\/
ruleengines
\/?([
a-zA-Z0-9
\-\;]{0,35})
$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:ruleengine 方法: Update"
);
...
...
app_web/src/service/rule-engine/rule-engine-service-base.ts
浏览文件 @
3c81632a
...
...
@@ -194,6 +194,34 @@ export default class RuleEngineServiceBase extends EntityService {
return
res
;
}
/**
* SyncRun接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof RuleEngineServiceBase
*/
public
async
SyncRun
(
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
let
res
:
any
=
Http
.
getInstance
().
post
(
`/ruleengines/
${
context
.
ruleengine
}
/syncrun`
,
data
,
isloading
);
return
res
;
}
/**
* SyncRunBatch接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof RuleEngineServiceBase
*/
public
async
SyncRunBatch
(
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
let
tempData
:
any
=
JSON
.
parse
(
JSON
.
stringify
(
data
));
return
await
Http
.
getInstance
().
post
(
`/ruleengines/syncrunbatch`
,
tempData
,
isloading
);
}
/**
* Update接口方法
*
...
...
app_web/src/widgets/dict-catalog/default-searchform/default-searchform-base.vue
浏览文件 @
3c81632a
...
...
@@ -698,7 +698,7 @@ export default class DefaultBase extends Vue implements ControlInterface {
*/
public
load
(
opt
:
any
=
{}):
void
{
if
(
!
this
.
loadAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'DictCatalogGridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'DictCatalog
Pickup
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
};
...
...
@@ -734,7 +734,7 @@ export default class DefaultBase extends Vue implements ControlInterface {
*/
public
loadDraft
(
opt
:
any
=
{},
mode
?:
string
):
void
{
if
(
!
this
.
loaddraftAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'DictCatalogGridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'DictCatalog
Pickup
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
}
;
...
...
app_web/src/widgets/rule-item/default-searchform/default-searchform-base.vue
浏览文件 @
3c81632a
...
...
@@ -838,7 +838,7 @@ export default class DefaultBase extends Vue implements ControlInterface {
*/
public
load
(
opt
:
any
=
{}):
void
{
if
(
!
this
.
loadAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
};
...
...
@@ -874,7 +874,7 @@ export default class DefaultBase extends Vue implements ControlInterface {
*/
public
loadDraft
(
opt
:
any
=
{},
mode
?:
string
):
void
{
if
(
!
this
.
loaddraftAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
}
;
...
...
app_web/src/widgets/rule-item/main-grid/main-grid-base.vue
浏览文件 @
3c81632a
...
...
@@ -392,20 +392,6 @@ export default class MainBase extends Vue implements ControlInterface {
return
this
.
selections
[
0
];
}
/**
* 打开新建数据视图
*
* @type {any}
* @memberof MainBase
*/
@
Prop
()
public
newdata
:
any
;
/**
* 打开编辑数据视图
*
* @type {any}
* @memberof MainBase
*/
@
Prop
()
public
opendata
:
any
;
/**
* 是否嵌入关系界面
...
...
@@ -973,7 +959,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public
load
(
opt
:
any
=
{},
pageReset
:
boolean
=
false
):
void
{
if
(
!
this
.
fetchAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.fetchAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.fetchAction'
)
as
string
)
});
return
;
}
if
(
pageReset
){
...
...
@@ -1068,7 +1054,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public
async
remove
(
datas
:
any
[]):
Promise
<
any
>
{
if
(
!
this
.
removeAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.removeAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.removeAction'
)
as
string
)
});
return
;
}
let
_datas
:
any
[]
=
[];
...
...
@@ -1174,7 +1160,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public
addBatch
(
arg
:
any
=
{}):
void
{
if
(
!
this
.
fetchAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.fetchAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.fetchAction'
)
as
string
)
});
return
;
}
if
(
!
arg
){
...
...
@@ -1990,7 +1976,7 @@ export default class MainBase extends Vue implements ControlInterface {
public
setColState
()
{
this
.
resetColModel
=
Util
.
deepCopy
(
this
.
allColumns
);
const
viewParams
:
any
=
Util
.
deepCopy
(
this
.
viewparams
);
Object
.
assign
(
viewParams
,{
utilServiceName
:
'grid_dynaconfig'
,
modelid
:
'ibzdst_web_ruleitemgridview_grid_main'
});
Object
.
assign
(
viewParams
,{
utilServiceName
:
'grid_dynaconfig'
,
modelid
:
'ibzdst_web_ruleitem
pickup
gridview_grid_main'
});
const
post
=
this
.
service
.
loadModel
(
'grid_dynaconfig'
,
this
.
context
,
viewParams
);
post
.
then
((
response
:
any
)
=>
{
if
(
response
.
status
==
200
&&
response
.
data
)
{
...
...
@@ -2057,7 +2043,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public
saveDynaConfig
()
{
const
viewParams
:
any
=
Util
.
deepCopy
(
this
.
viewparams
);
Object
.
assign
(
viewParams
,{
utilServiceName
:
'grid_dynaconfig'
,
modelid
:
'ibzdst_web_ruleitemgridview_grid_main'
,
model
:
this
.
allColumns
});
Object
.
assign
(
viewParams
,{
utilServiceName
:
'grid_dynaconfig'
,
modelid
:
'ibzdst_web_ruleitem
pickup
gridview_grid_main'
,
model
:
this
.
allColumns
});
const
post
=
this
.
service
.
saveModel
(
'grid_dynaconfig'
,
this
.
context
,
viewParams
);
post
.
then
((
response
:
any
)
=>
{
if
(
response
.
status
==
200
)
{
...
...
@@ -2128,7 +2114,7 @@ export default class MainBase extends Vue implements ControlInterface {
try
{
if
(
Object
.
is
(
item
.
rowDataState
,
'create'
)){
if
(
!
this
.
createAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.createAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.createAction'
)
as
string
)
});
}
else
{
Object
.
assign
(
item
,{
viewparams
:
this
.
viewparams
});
let
response
=
await
this
.
service
.
add
(
this
.
createAction
,
JSON
.
parse
(
JSON
.
stringify
(
this
.
context
)),
item
,
this
.
showBusyIndicator
);
...
...
@@ -2136,7 +2122,7 @@ export default class MainBase extends Vue implements ControlInterface {
}
}
else
if
(
Object
.
is
(
item
.
rowDataState
,
'update'
)){
if
(
!
this
.
updateAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.updateAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.updateAction'
)
as
string
)
});
}
else
{
Object
.
assign
(
item
,{
viewparams
:
this
.
viewparams
});
if
(
item
.
ruleitem
){
...
...
@@ -2209,7 +2195,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public
newRow
(
args
:
any
[],
params
?:
any
,
$event
?:
any
,
xData
?:
any
):
void
{
if
(
!
this
.
loaddraftAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItemGridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.loaddraftAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'RuleItem
Pickup
GridView'
+
(
this
.
$t
(
'app.gridpage.notConfig.loaddraftAction'
)
as
string
)
});
return
;
}
let
_this
=
this
;
...
...
ibzdst-core/src/main/java/cn/ibizlab/core/rule/service/IRuleEngineService.java
浏览文件 @
3c81632a
...
...
@@ -40,6 +40,8 @@ public interface IRuleEngineService extends IService<RuleEngine> {
boolean
runBatch
(
List
<
RuleEngine
>
etList
);
boolean
save
(
RuleEngine
et
);
void
saveBatch
(
List
<
RuleEngine
>
list
);
RuleEngine
syncRun
(
RuleEngine
et
);
boolean
syncRunBatch
(
List
<
RuleEngine
>
etList
);
Page
<
RuleEngine
>
searchDefault
(
RuleEngineSearchContext
context
);
List
<
RuleEngine
>
selectByModelId
(
String
id
);
void
removeByModelId
(
String
id
);
...
...
ibzdst-core/src/main/java/cn/ibizlab/core/rule/service/impl/RuleEngineServiceImpl.java
浏览文件 @
3c81632a
...
...
@@ -217,6 +217,22 @@ public class RuleEngineServiceImpl extends ServiceImpl<RuleEngineMapper, RuleEng
}
}
@Override
@Transactional
public
RuleEngine
syncRun
(
RuleEngine
et
)
{
//自定义代码
return
et
;
}
@Override
@Transactional
public
boolean
syncRunBatch
(
List
<
RuleEngine
>
etList
)
{
for
(
RuleEngine
et
:
etList
)
{
syncRun
(
et
);
}
return
true
;
}
@Override
public
List
<
RuleEngine
>
selectByModelId
(
String
id
)
{
...
...
ibzdst-core/src/main/resources/liquibase/h2_table.xml
浏览文件 @
3c81632a
...
...
@@ -468,7 +468,7 @@
<!--输出实体[RU_ENGINE]数据结构 -->
<changeSet
author=
"root"
id=
"tab-ru_engine-
3
-17"
>
<changeSet
author=
"root"
id=
"tab-ru_engine-
5
-17"
>
<createTable
tableName=
"IBZRULEENGINE"
>
<column
name=
"ENGINEID"
remarks=
""
type=
"VARCHAR(100)"
>
<constraints
primaryKey=
"true"
primaryKeyName=
"PK_RU_ENGINE_ENGINEID"
/>
...
...
ibzdst-core/src/main/resources/permission/systemResource.json
浏览文件 @
3c81632a
...
...
@@ -161,7 +161,7 @@
"delogicname"
:
"规则引擎"
,
"sysmoudle"
:{
"id"
:
"RULE"
,
"name"
:
"rule"
},
"dedataset"
:[{
"id"
:
"Default"
,
"name"
:
"数据集"
}],
"deaction"
:[{
"id"
:
"Create"
,
"name"
:
"Create"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Update"
,
"name"
:
"Update"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Remove"
,
"name"
:
"Remove"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Get"
,
"name"
:
"Get"
,
"type"
:
"BUILTIN"
},{
"id"
:
"GetDraft"
,
"name"
:
"GetDraft"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Check"
,
"name"
:
"校验"
,
"type"
:
"USERCUSTOM"
},{
"id"
:
"CheckKey"
,
"name"
:
"CheckKey"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Run"
,
"name"
:
"运行"
,
"type"
:
"USERCUSTOM"
},{
"id"
:
"Save"
,
"name"
:
"Save"
,
"type"
:
"BUILTIN"
}],
"deaction"
:[{
"id"
:
"Create"
,
"name"
:
"Create"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Update"
,
"name"
:
"Update"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Remove"
,
"name"
:
"Remove"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Get"
,
"name"
:
"Get"
,
"type"
:
"BUILTIN"
},{
"id"
:
"GetDraft"
,
"name"
:
"GetDraft"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Check"
,
"name"
:
"校验"
,
"type"
:
"USERCUSTOM"
},{
"id"
:
"CheckKey"
,
"name"
:
"CheckKey"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Run"
,
"name"
:
"运行"
,
"type"
:
"USERCUSTOM"
},{
"id"
:
"Save"
,
"name"
:
"Save"
,
"type"
:
"BUILTIN"
}
,{
"id"
:
"SyncRun"
,
"name"
:
"同步运行"
,
"type"
:
"USERCUSTOM"
}
],
"datascope"
:[{
"id"
:
"all"
,
"name"
:
"全部数据"
}]
}
,
{
...
...
ibzdst-provider/ibzdst-provider-api/src/main/java/cn/ibizlab/api/rest/RuleEngineResource.java
浏览文件 @
3c81632a
...
...
@@ -176,6 +176,23 @@ public class RuleEngineResource {
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
true
);
}
@ApiOperation
(
value
=
"同步运行"
,
tags
=
{
"规则引擎"
},
notes
=
"同步运行"
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
value
=
"/ruleengines/{ruleengine_id}/syncrun"
)
public
ResponseEntity
<
RuleEngineDTO
>
syncRun
(
@PathVariable
(
"ruleengine_id"
)
String
ruleengine_id
,
@RequestBody
RuleEngineDTO
ruleenginedto
)
{
RuleEngine
domain
=
ruleengineMapping
.
toDomain
(
ruleenginedto
);
domain
.
setEngineId
(
ruleengine_id
);
domain
=
ruleengineService
.
syncRun
(
domain
);
ruleenginedto
=
ruleengineMapping
.
toDto
(
domain
);
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
ruleenginedto
);
}
@ApiOperation
(
value
=
"批量处理[同步运行]"
,
tags
=
{
"规则引擎"
},
notes
=
"批量处理[同步运行]"
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
value
=
"/ruleengines/syncrunbatch"
)
public
ResponseEntity
<
Boolean
>
syncRunBatch
(
@RequestBody
List
<
RuleEngineDTO
>
ruleenginedtos
)
{
List
<
RuleEngine
>
domains
=
ruleengineMapping
.
toDomain
(
ruleenginedtos
);
boolean
result
=
ruleengineService
.
syncRunBatch
(
domains
);
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
result
);
}
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibzdst-RuleEngine-searchDefault-all')"
)
@ApiOperation
(
value
=
"获取数据集"
,
tags
=
{
"规则引擎"
}
,
notes
=
"获取数据集"
)
@RequestMapping
(
method
=
RequestMethod
.
GET
,
value
=
"/ruleengines/fetchdefault"
)
...
...
编辑
预览
Markdown
格式
0%
请重试
or
添加新附件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
先完成此消息的编辑!
取消
想要评论请
注册
或
登录