Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
提交反馈
为 GitLab 提交贡献
登录
切换导航
I
ibztask
项目
项目
详情
动态
版本
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
ibiz4jteam
ibztask
提交
125378c4
提交
125378c4
编写于
4年前
作者:
ibizdev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ibiz4j 发布系统代码
上级
219f5a0a
变更
8
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
253 行增加
和
2 行删除
+253
-2
jobs-infos.ts
app_web/src/mock/entity/jobs-infos/jobs-infos.ts
+114
-0
jobs-info-service-base.ts
app_web/src/service/jobs-info/jobs-info-service-base.ts
+39
-0
JobsInfoServiceEx.java
...cn/ibizlab/core/extensions.service/JobsInfoServiceEx.java
+35
-0
IJobsInfoService.java
...n/java/cn/ibizlab/core/task/service/IJobsInfoService.java
+3
-0
JobsInfoServiceImpl.java
...n/ibizlab/core/task/service/impl/JobsInfoServiceImpl.java
+24
-0
h2_table.xml
ibztask-core/src/main/resources/liquibase/h2_table.xml
+1
-1
systemResource.json
...sk-core/src/main/resources/permission/systemResource.json
+1
-1
JobsInfoResource.java
...i/src/main/java/cn/ibizlab/api/rest/JobsInfoResource.java
+36
-0
未找到文件。
app_web/src/mock/entity/jobs-infos/jobs-infos.ts
浏览文件 @
125378c4
...
...
@@ -115,6 +115,44 @@ mock.onGet(new RegExp(/^\/jobsinfos\/([a-zA-Z0-9\-\;]{1,35})\/select$/)).reply((
return
[
status
,
_items
];
});
// Start
mock
.
onPost
(
new
RegExp
(
/^
\/
jobsinfos
\/?([
a-zA-Z0-9
\-\;]{0,35})\/
start$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:jobsinfo 方法: Start"
);
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
>
=
[
'id'
];
const
matchArray
:
any
=
new
RegExp
(
/^
\/
jobsinfos
\/([
a-zA-Z0-9
\-\;]{1,35})\/
start$/
).
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.id, tempValue.id));
let
data
=
JSON
.
parse
(
config
.
data
);
mockDatas
.
forEach
((
item
)
=>
{
if
(
item
[
'id'
]
==
tempValue
[
'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
(
/^
\/
jobsinfos
\/?([
a-zA-Z0-9
\-\;]{0,35})
$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:jobsinfo 方法: Update"
);
...
...
@@ -191,6 +229,44 @@ mock.onPost(new RegExp(/^\/jobsinfos\/?([a-zA-Z0-9\-\;]{0,35})\/checkkey$/)).rep
return
[
status
,
data
];
});
// Execute
mock
.
onPost
(
new
RegExp
(
/^
\/
jobsinfos
\/?([
a-zA-Z0-9
\-\;]{0,35})\/
execute$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:jobsinfo 方法: Execute"
);
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
>
=
[
'id'
];
const
matchArray
:
any
=
new
RegExp
(
/^
\/
jobsinfos
\/([
a-zA-Z0-9
\-\;]{1,35})\/
execute$/
).
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.id, tempValue.id));
let
data
=
JSON
.
parse
(
config
.
data
);
mockDatas
.
forEach
((
item
)
=>
{
if
(
item
[
'id'
]
==
tempValue
[
'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
];
});
// Save
mock
.
onPost
(
new
RegExp
(
/^
\/
jobsinfos
\/?([
a-zA-Z0-9
\-\;]{0,35})\/
save$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:jobsinfo 方法: Save"
);
...
...
@@ -270,6 +346,44 @@ mock.onPost(new RegExp(/^\/jobsinfos\/?([a-zA-Z0-9\-\;]{0,35})$/)).reply((config
console
.
groupEnd
();
return
[
status
,
mockDatas
[
0
]];
});
// Stop
mock
.
onPost
(
new
RegExp
(
/^
\/
jobsinfos
\/?([
a-zA-Z0-9
\-\;]{0,35})\/
stop$/
)).
reply
((
config
:
any
)
=>
{
console
.
groupCollapsed
(
"实体:jobsinfo 方法: Stop"
);
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
>
=
[
'id'
];
const
matchArray
:
any
=
new
RegExp
(
/^
\/
jobsinfos
\/([
a-zA-Z0-9
\-\;]{1,35})\/
stop$/
).
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.id, tempValue.id));
let
data
=
JSON
.
parse
(
config
.
data
);
mockDatas
.
forEach
((
item
)
=>
{
if
(
item
[
'id'
]
==
tempValue
[
'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
];
});
// FetchDefault
mock
.
onGet
(
new
RegExp
(
/^
\/
jobsinfos
\/
fetchdefault$/
)).
reply
((
config
:
any
)
=>
{
...
...
This diff is collapsed.
Click to expand it.
app_web/src/service/jobs-info/jobs-info-service-base.ts
浏览文件 @
125378c4
...
...
@@ -51,6 +51,19 @@ export default class JobsInfoServiceBase extends EntityService {
return
Http
.
getInstance
().
get
(
`/jobsinfos/
${
context
.
jobsinfo
}
/select`
,
isloading
);
}
/**
* Start接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof JobsInfoServiceBase
*/
public
async
Start
(
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
return
Http
.
getInstance
().
post
(
`/jobsinfos/
${
context
.
jobsinfo
}
/start`
,
data
,
isloading
);
}
/**
* Update接口方法
*
...
...
@@ -80,6 +93,19 @@ export default class JobsInfoServiceBase extends EntityService {
return
Http
.
getInstance
().
post
(
`/jobsinfos/
${
context
.
jobsinfo
}
/checkkey`
,
data
,
isloading
);
}
/**
* Execute接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof JobsInfoServiceBase
*/
public
async
Execute
(
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
return
Http
.
getInstance
().
post
(
`/jobsinfos/
${
context
.
jobsinfo
}
/execute`
,
data
,
isloading
);
}
/**
* Save接口方法
*
...
...
@@ -163,6 +189,19 @@ export default class JobsInfoServiceBase extends EntityService {
return
res
;
}
/**
* Stop接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof JobsInfoServiceBase
*/
public
async
Stop
(
context
:
any
=
{},
data
:
any
=
{},
isloading
?:
boolean
):
Promise
<
any
>
{
return
Http
.
getInstance
().
post
(
`/jobsinfos/
${
context
.
jobsinfo
}
/stop`
,
data
,
isloading
);
}
/**
* FetchDefault接口方法
*
...
...
This diff is collapsed.
Click to expand it.
ibztask-core/src/main/java/cn/ibizlab/core/extensions.service/JobsInfoServiceEx.java
0 → 100644
浏览文件 @
125378c4
package
cn
.
ibizlab
.
core
.
extensions
.
service
;
import
cn.ibizlab.core.task.service.impl.JobsInfoServiceImpl
;
import
lombok.extern.slf4j.Slf4j
;
import
cn.ibizlab.core.task.domain.JobsInfo
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.context.annotation.Primary
;
/**
* 实体[任务信息] 自定义服务对象
*/
@Slf4j
@Primary
@Service
(
"JobsInfoServiceEx"
)
public
class
JobsInfoServiceEx
extends
JobsInfoServiceImpl
{
@Override
protected
Class
currentModelClass
()
{
return
com
.
baomidou
.
mybatisplus
.
core
.
toolkit
.
ReflectionKit
.
getSuperClassGenericType
(
this
.
getClass
().
getSuperclass
(),
1
);
}
/**
* 自定义行为[Execute]用户扩展
* @param et
* @return
*/
@Override
@Transactional
public
JobsInfo
execute
(
JobsInfo
et
)
{
return
super
.
execute
(
et
);
}
}
This diff is collapsed.
Click to expand it.
ibztask-core/src/main/java/cn/ibizlab/core/task/service/IJobsInfoService.java
浏览文件 @
125378c4
...
...
@@ -25,9 +25,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public
interface
IJobsInfoService
extends
IService
<
JobsInfo
>{
JobsInfo
start
(
JobsInfo
et
)
;
boolean
update
(
JobsInfo
et
)
;
void
updateBatch
(
List
<
JobsInfo
>
list
)
;
boolean
checkKey
(
JobsInfo
et
)
;
JobsInfo
execute
(
JobsInfo
et
)
;
boolean
save
(
JobsInfo
et
)
;
void
saveBatch
(
List
<
JobsInfo
>
list
)
;
JobsInfo
getDraft
(
JobsInfo
et
)
;
...
...
@@ -36,6 +38,7 @@ public interface IJobsInfoService extends IService<JobsInfo>{
JobsInfo
get
(
BigInteger
key
)
;
boolean
create
(
JobsInfo
et
)
;
void
createBatch
(
List
<
JobsInfo
>
list
)
;
JobsInfo
stop
(
JobsInfo
et
)
;
Page
<
JobsInfo
>
searchDefault
(
JobsInfoSearchContext
context
)
;
/**
*自定义查询SQL
...
...
This diff is collapsed.
Click to expand it.
ibztask-core/src/main/java/cn/ibizlab/core/task/service/impl/JobsInfoServiceImpl.java
浏览文件 @
125378c4
...
...
@@ -47,6 +47,14 @@ public class JobsInfoServiceImpl extends ServiceImpl<JobsInfoMapper, JobsInfo> i
private
int
batchSize
=
500
;
@Override
@Transactional
public
JobsInfo
start
(
JobsInfo
et
)
{
et
.
set
(
"Id"
,
null
);
et
.
set
(
"Status"
,
"1"
);
et
.
set
(
"Last_time"
,
"0"
);
return
et
;
}
@Override
@Transactional
public
boolean
update
(
JobsInfo
et
)
{
...
...
@@ -65,6 +73,13 @@ public class JobsInfoServiceImpl extends ServiceImpl<JobsInfoMapper, JobsInfo> i
public
boolean
checkKey
(
JobsInfo
et
)
{
return
(!
ObjectUtils
.
isEmpty
(
et
.
getId
()))&&(!
Objects
.
isNull
(
this
.
getById
(
et
.
getId
())));
}
@Override
@Transactional
public
JobsInfo
execute
(
JobsInfo
et
)
{
//自定义代码
return
et
;
}
@Override
@Transactional
public
boolean
save
(
JobsInfo
et
)
{
...
...
@@ -140,6 +155,15 @@ public class JobsInfoServiceImpl extends ServiceImpl<JobsInfoMapper, JobsInfo> i
this
.
saveBatch
(
list
,
batchSize
);
}
@Override
@Transactional
public
JobsInfo
stop
(
JobsInfo
et
)
{
et
.
set
(
"Id"
,
null
);
et
.
set
(
"Last_time"
,
"0"
);
et
.
set
(
"Status"
,
"0"
);
et
.
set
(
"Next_time"
,
"0"
);
return
et
;
}
/**
...
...
This diff is collapsed.
Click to expand it.
ibztask-core/src/main/resources/liquibase/h2_table.xml
浏览文件 @
125378c4
...
...
@@ -4,7 +4,7 @@
<!--输出实体[JOBS_INFO]数据结构 -->
<changeSet
author=
"a_A_5d9d78509"
id=
"tab-jobs_info-
43
-1"
>
<changeSet
author=
"a_A_5d9d78509"
id=
"tab-jobs_info-
50
-1"
>
<createTable
tableName=
"JOBS_INFO"
>
<column
name=
"ID"
remarks=
""
type=
"BIGINT"
>
<constraints
primaryKey=
"true"
primaryKeyName=
"PK_JOBS_INFO_ID"
/>
...
...
This diff is collapsed.
Click to expand it.
ibztask-core/src/main/resources/permission/systemResource.json
浏览文件 @
125378c4
...
...
@@ -8,7 +8,7 @@
"delogicname"
:
"任务信息"
,
"sysmoudle"
:{
"id"
:
"TASK"
,
"name"
:
"task"
},
"dedataset"
:[{
"id"
:
"Default"
,
"name"
:
"DEFAULT"
}],
"deaction"
:[{
"id"
:
"
Update"
,
"name"
:
"Update"
,
"type"
:
"BUILTIN"
},{
"id"
:
"CheckKey"
,
"name"
:
"CheckKey"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Save"
,
"name"
:
"Save"
,
"type"
:
"BUILTIN"
},{
"id"
:
"GetDraft"
,
"name"
:
"GetDraft"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Remove"
,
"name"
:
"Remove"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Get"
,
"name"
:
"Get"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Create"
,
"name"
:
"Create"
,
"type"
:
"BUILTIN
"
}],
"deaction"
:[{
"id"
:
"
Start"
,
"name"
:
"开始"
,
"type"
:
"USERUPDATE"
},{
"id"
:
"Update"
,
"name"
:
"Update"
,
"type"
:
"BUILTIN"
},{
"id"
:
"CheckKey"
,
"name"
:
"CheckKey"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Execute"
,
"name"
:
"执行"
,
"type"
:
"USERCUSTOM"
},{
"id"
:
"Save"
,
"name"
:
"Save"
,
"type"
:
"BUILTIN"
},{
"id"
:
"GetDraft"
,
"name"
:
"GetDraft"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Remove"
,
"name"
:
"Remove"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Get"
,
"name"
:
"Get"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Create"
,
"name"
:
"Create"
,
"type"
:
"BUILTIN"
},{
"id"
:
"Stop"
,
"name"
:
"停止"
,
"type"
:
"USERUPDATE
"
}],
"datascope"
:[{
"id"
:
"all"
,
"name"
:
"全部数据"
}]
}
,
{
...
...
This diff is collapsed.
Click to expand it.
ibztask-provider/ibztask-provider-api/src/main/java/cn/ibizlab/api/rest/JobsInfoResource.java
浏览文件 @
125378c4
...
...
@@ -46,6 +46,18 @@ public class JobsInfoResource {
@Lazy
public
JobsInfoMapping
jobsinfoMapping
;
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibztask-JobsInfo-Start-all')"
)
@ApiOperation
(
value
=
"开始"
,
tags
=
{
"任务信息"
},
notes
=
"开始"
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
value
=
"/jobsinfos/{jobsinfo_id}/start"
)
@Transactional
public
ResponseEntity
<
JobsInfoDTO
>
start
(
@PathVariable
(
"jobsinfo_id"
)
BigInteger
jobsinfo_id
,
@RequestBody
JobsInfoDTO
jobsinfodto
)
{
JobsInfo
jobsinfo
=
jobsinfoMapping
.
toDomain
(
jobsinfodto
);
jobsinfo
.
setId
(
jobsinfo_id
);
jobsinfo
=
jobsinfoService
.
start
(
jobsinfo
);
jobsinfodto
=
jobsinfoMapping
.
toDto
(
jobsinfo
);
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
jobsinfodto
);
}
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibztask-JobsInfo-Update-all')"
)
@ApiOperation
(
value
=
"更新任务信息"
,
tags
=
{
"任务信息"
},
notes
=
"更新任务信息"
)
@RequestMapping
(
method
=
RequestMethod
.
PUT
,
value
=
"/jobsinfos/{jobsinfo_id}"
)
...
...
@@ -72,6 +84,18 @@ public class JobsInfoResource {
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
jobsinfoService
.
checkKey
(
jobsinfoMapping
.
toDomain
(
jobsinfodto
)));
}
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibztask-JobsInfo-Execute-all')"
)
@ApiOperation
(
value
=
"执行"
,
tags
=
{
"任务信息"
},
notes
=
"执行"
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
value
=
"/jobsinfos/{jobsinfo_id}/execute"
)
@Transactional
public
ResponseEntity
<
JobsInfoDTO
>
execute
(
@PathVariable
(
"jobsinfo_id"
)
BigInteger
jobsinfo_id
,
@RequestBody
JobsInfoDTO
jobsinfodto
)
{
JobsInfo
jobsinfo
=
jobsinfoMapping
.
toDomain
(
jobsinfodto
);
jobsinfo
.
setId
(
jobsinfo_id
);
jobsinfo
=
jobsinfoService
.
execute
(
jobsinfo
);
jobsinfodto
=
jobsinfoMapping
.
toDto
(
jobsinfo
);
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
jobsinfodto
);
}
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibztask-JobsInfo-Save-all')"
)
@ApiOperation
(
value
=
"保存任务信息"
,
tags
=
{
"任务信息"
},
notes
=
"保存任务信息"
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
value
=
"/jobsinfos/save"
)
...
...
@@ -137,6 +161,18 @@ public class JobsInfoResource {
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
true
);
}
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibztask-JobsInfo-Stop-all')"
)
@ApiOperation
(
value
=
"停止"
,
tags
=
{
"任务信息"
},
notes
=
"停止"
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
value
=
"/jobsinfos/{jobsinfo_id}/stop"
)
@Transactional
public
ResponseEntity
<
JobsInfoDTO
>
stop
(
@PathVariable
(
"jobsinfo_id"
)
BigInteger
jobsinfo_id
,
@RequestBody
JobsInfoDTO
jobsinfodto
)
{
JobsInfo
jobsinfo
=
jobsinfoMapping
.
toDomain
(
jobsinfodto
);
jobsinfo
.
setId
(
jobsinfo_id
);
jobsinfo
=
jobsinfoService
.
stop
(
jobsinfo
);
jobsinfodto
=
jobsinfoMapping
.
toDto
(
jobsinfo
);
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
jobsinfodto
);
}
@PreAuthorize
(
"hasAnyAuthority('ROLE_SUPERADMIN','ibztask-JobsInfo-Default-all')"
)
@ApiOperation
(
value
=
"获取DEFAULT"
,
tags
=
{
"任务信息"
}
,
notes
=
"获取DEFAULT"
)
@RequestMapping
(
method
=
RequestMethod
.
GET
,
value
=
"/jobsinfos/fetchdefault"
)
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
格式
0%
请重试
or
添加新附件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
先完成此消息的编辑!
取消
想要评论请
注册
或
登录