Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
fuyue82
o2oa
提交
97510379
o2oa
项目概览
fuyue82
/
o2oa
与 Fork 源项目一致
Fork自
浙江兰德纵横网络技术股份有限公司 / o2oa
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
o2oa
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
97510379
编写于
3月 11, 2022
作者:
O
o2sword
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
内容管理增加发布提醒接口
上级
765c0424
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
200 addition
and
101 deletion
+200
-101
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionNotify.java
...m/x/cms/assemble/control/jaxrs/document/ActionNotify.java
+65
-0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishAndNotify.java
...control/jaxrs/document/ActionPersistPublishAndNotify.java
+6
-33
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishContent.java
...e/control/jaxrs/document/ActionPersistPublishContent.java
+1
-29
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/DocumentAction.java
...x/cms/assemble/control/jaxrs/document/DocumentAction.java
+19
-0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/queue/QueueSendDocumentNotify.java
...x/cms/assemble/control/queue/QueueSendDocumentNotify.java
+50
-39
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/Document.java
..._entity/src/main/java/com/x/cms/core/entity/Document.java
+1
-0
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/query/DocumentNotify.java
...main/java/com/x/cms/core/entity/query/DocumentNotify.java
+58
-0
未找到文件。
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionNotify.java
0 → 100644
浏览文件 @
97510379
package
com.x.cms.assemble.control.jaxrs.document
;
import
com.google.gson.JsonElement
;
import
com.x.base.core.project.exception.ExceptionAccessDenied
;
import
com.x.base.core.project.exception.ExceptionEntityNotExist
;
import
com.x.base.core.project.http.ActionResult
;
import
com.x.base.core.project.http.EffectivePerson
;
import
com.x.base.core.project.jaxrs.WrapBoolean
;
import
com.x.base.core.project.logger.Logger
;
import
com.x.base.core.project.logger.LoggerFactory
;
import
com.x.cms.assemble.control.Business
;
import
com.x.cms.assemble.control.ThisApplication
;
import
com.x.cms.core.entity.AppInfo
;
import
com.x.cms.core.entity.Document
;
import
com.x.cms.core.entity.query.DocumentNotify
;
/**
* 文档发送消息通知
* @author sword
*/
public
class
ActionNotify
extends
BaseAction
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ActionNotify
.
class
);
protected
ActionResult
<
Wo
>
execute
(
EffectivePerson
effectivePerson
,
String
id
,
JsonElement
jsonElement
)
throws
Exception
{
logger
.
debug
(
effectivePerson
.
getDistinguishedName
());
ActionResult
<
Wo
>
result
=
new
ActionResult
<>();
Wi
wi
=
this
.
convertToWrapIn
(
jsonElement
,
Wi
.
class
);
Document
document
=
documentQueryService
.
get
(
id
);
if
(
document
==
null
){
throw
new
ExceptionEntityNotExist
(
id
);
}
if
(!
Document
.
DOC_STATUS_PUBLISH
.
equals
(
document
.
getDocStatus
())){
throw
new
IllegalStateException
(
"文档未发布"
);
}
wi
.
setDocumentId
(
id
);
AppInfo
appInfo
=
appInfoServiceAdv
.
get
(
document
.
getAppId
());
if
(
appInfo
==
null
){
if
(
document
==
null
){
throw
new
ExceptionEntityNotExist
(
document
.
getAppId
(),
AppInfo
.
class
);
}
}
Business
business
=
new
Business
(
null
);
if
(!
effectivePerson
.
getDistinguishedName
().
equals
(
document
.
getCreatorPerson
())
&&
!
business
.
isAppInfoManager
(
effectivePerson
,
appInfo
)){
throw
new
ExceptionAccessDenied
(
effectivePerson
);
}
ThisApplication
.
queueSendDocumentNotify
.
send
(
wi
);
result
.
setData
(
new
Wo
(
true
));
return
result
;
}
public
static
class
Wi
extends
DocumentNotify
{
}
public
static
class
Wo
extends
WrapBoolean
{
public
Wo
(
Boolean
value
){
super
(
value
);
}
}
}
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishAndNotify.java
浏览文件 @
97510379
...
...
@@ -16,7 +16,6 @@ import com.x.base.core.project.logger.Logger;
import
com.x.base.core.project.logger.LoggerFactory
;
import
com.x.cms.assemble.control.ThisApplication
;
import
com.x.cms.assemble.control.jaxrs.permission.element.PermissionInfo
;
import
com.x.cms.core.entity.CategoryInfo
;
import
com.x.cms.core.entity.Document
;
import
com.x.cms.core.entity.FileInfo
;
...
...
@@ -25,6 +24,9 @@ import java.util.ArrayList;
import
java.util.Date
;
import
java.util.List
;
/**
* @author sword
*/
public
class
ActionPersistPublishAndNotify
extends
BaseAction
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ActionPersistPublishAndNotify
.
class
);
...
...
@@ -65,8 +67,8 @@ public class ActionPersistPublishAndNotify extends BaseAction {
}
if
(
check
)
{
try
{
modifyDocStatus
(
id
,
"published"
,
effectivePerson
.
getDistinguishedName
()
);
document
.
setDocStatus
(
"published"
);
modifyDocStatus
(
id
,
Document
.
DOC_STATUS_PUBLISH
,
effectivePerson
.
getDistinguishedName
()
);
document
.
setDocStatus
(
Document
.
DOC_STATUS_PUBLISH
);
document
.
setPublishTime
(
new
Date
());
document
=
documentPersistService
.
refreshDocInfoData
(
document
);
...
...
@@ -177,43 +179,14 @@ public class ActionPersistPublishAndNotify extends BaseAction {
//将读者以及作者信息持久化到数据库中
if
(
!
wi
.
getSkipPermission
()
)
{
try
{
document
=
document
PersistService
.
refreshDocumentPermission
(
id
,
wi
.
getReaderList
(),
wi
.
getAuthorList
()
);
documentPersistService
.
refreshDocumentPermission
(
id
,
wi
.
getReaderList
(),
wi
.
getAuthorList
()
);
}
catch
(
Exception
e
)
{
check
=
false
;
Exception
exception
=
new
ExceptionDocumentInfoProcess
(
e
,
"系统在核对文档访问管理权限信息时发生异常!"
);
result
.
error
(
exception
);
logger
.
error
(
e
,
effectivePerson
,
request
,
null
);
}
}
//判断是否需要发送通知消息
if
(
check
)
{
try
{
CategoryInfo
categoryInfo
=
categoryInfoServiceAdv
.
getWithFlag
(
document
.
getCategoryId
()
);
if
(
categoryInfo
!=
null
){
// Boolean notify = false;
// if( categoryInfo.getSendNotify() == null ) {
// if( StringUtils.equals("信息", categoryInfo.getDocumentType()) ) {
// notify = true;
// }
// }else {
// if( categoryInfo.getSendNotify() ) {
// notify = true;
// }
// }
if
(
categoryInfo
.
getSendNotify
()
){
logger
.
info
(
"try to add notify object to queue for document:"
+
document
.
getTitle
()
);
ThisApplication
.
queueSendDocumentNotify
.
send
(
document
.
getId
()
);
}
}
}
catch
(
Exception
e
)
{
check
=
false
;
Exception
exception
=
new
ExceptionDocumentInfoProcess
(
e
,
"根据ID查询分类信息对象时发生异常。Flag:"
+
document
.
getCategoryId
()
);
result
.
error
(
exception
);
logger
.
error
(
e
,
effectivePerson
,
request
,
null
);
}
}
CacheManager
.
notify
(
Document
.
class
);
return
result
;
...
...
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishContent.java
浏览文件 @
97510379
...
...
@@ -12,7 +12,6 @@ import com.x.base.core.project.config.StorageMapping;
import
com.x.base.core.project.exception.ExceptionWhen
;
import
com.x.processplatform.core.entity.content.Attachment
;
import
org.apache.commons.io.FilenameUtils
;
import
org.apache.commons.lang3.BooleanUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
com.google.gson.JsonElement
;
...
...
@@ -22,7 +21,6 @@ import com.x.base.core.project.annotation.AuditLog;
import
com.x.base.core.project.annotation.FieldDescribe
;
import
com.x.base.core.project.bean.WrapCopier
;
import
com.x.base.core.project.bean.WrapCopierFactory
;
import
com.x.base.core.project.gson.XGsonBuilder
;
import
com.x.base.core.project.http.ActionResult
;
import
com.x.base.core.project.http.EffectivePerson
;
import
com.x.base.core.project.jaxrs.WoId
;
...
...
@@ -417,40 +415,14 @@ public class ActionPersistPublishContent extends BaseAction {
if
(
check
&&
!
wi
.
getSkipPermission
()
)
{
//将读者以及作者信息持久化到数据库中
try
{
document
=
document
PersistService
.
refreshDocumentPermission
(
document
.
getId
(),
wi
.
getReaderList
(),
wi
.
getAuthorList
()
);
documentPersistService
.
refreshDocumentPermission
(
document
.
getId
(),
wi
.
getReaderList
(),
wi
.
getAuthorList
()
);
}
catch
(
Exception
e
)
{
check
=
false
;
Exception
exception
=
new
ExceptionDocumentInfoProcess
(
e
,
"系统在核对文档访问管理权限信息时发生异常!"
);
result
.
error
(
exception
);
logger
.
error
(
e
,
effectivePerson
,
request
,
null
);
}
}
//判断是否需要发送通知消息
if
(
check
)
{
try
{
Boolean
notify
=
false
;
if
(
categoryInfo
.
getSendNotify
()
==
null
)
{
if
(
StringUtils
.
equals
(
"信息"
,
categoryInfo
.
getDocumentType
())
)
{
notify
=
true
;
}
}
else
{
if
(
categoryInfo
.
getSendNotify
()
)
{
notify
=
true
;
}
}
if
(
notify
&&
!
BooleanUtils
.
isFalse
(
wi
.
getNotice
())){
logger
.
debug
(
"try to add notify object to queue for document:"
+
document
.
getTitle
()
);
ThisApplication
.
queueSendDocumentNotify
.
send
(
document
.
getId
()
);
}
}
catch
(
Exception
e
)
{
check
=
false
;
Exception
exception
=
new
ExceptionDocumentInfoProcess
(
e
,
"根据ID查询分类信息对象时发生异常。Flag:"
+
document
.
getCategoryId
()
);
result
.
error
(
exception
);
logger
.
error
(
e
,
effectivePerson
,
request
,
null
);
}
}
CacheManager
.
notify
(
FileInfo
.
class
);
CacheManager
.
notify
(
Document
.
class
);
return
result
;
...
...
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/DocumentAction.java
浏览文件 @
97510379
...
...
@@ -1050,4 +1050,23 @@ public class DocumentAction extends StandardJaxrsAction {
}
asyncResponse
.
resume
(
ResponseFactory
.
getEntityTagActionResultResponse
(
request
,
result
));
}
@JaxrsMethodDescribe
(
value
=
"已发布文档消息通知。"
,
action
=
ActionNotify
.
class
)
@POST
@Path
(
"{id}/notify"
)
@Produces
(
HttpMediaType
.
APPLICATION_JSON_UTF_8
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
public
void
publishNotify
(
@Suspended
final
AsyncResponse
asyncResponse
,
@Context
HttpServletRequest
request
,
@JaxrsParameterDescribe
(
"文档ID"
)
@PathParam
(
"id"
)
String
id
,
JsonElement
jsonElement
)
{
EffectivePerson
effectivePerson
=
this
.
effectivePerson
(
request
);
ActionResult
<
ActionNotify
.
Wo
>
result
=
new
ActionResult
<>();
try
{
result
=
new
ActionNotify
().
execute
(
effectivePerson
,
id
,
jsonElement
);
}
catch
(
Exception
e
)
{
result
.
error
(
e
);
logger
.
error
(
e
,
effectivePerson
,
request
,
jsonElement
);
}
asyncResponse
.
resume
(
ResponseFactory
.
getEntityTagActionResultResponse
(
request
,
result
));
}
}
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/queue/QueueSendDocumentNotify.java
浏览文件 @
97510379
...
...
@@ -5,10 +5,8 @@ import com.x.base.core.entity.JpaObject;
import
com.x.base.core.project.annotation.FieldDescribe
;
import
com.x.base.core.project.bean.WrapCopier
;
import
com.x.base.core.project.bean.WrapCopierFactory
;
import
com.x.base.core.project.config.Config
;
import
com.x.base.core.project.logger.Logger
;
import
com.x.base.core.project.logger.LoggerFactory
;
import
com.x.base.core.project.message.MessageConnector
;
import
com.x.base.core.project.queue.AbstractQueue
;
import
com.x.base.core.project.tools.ListTools
;
import
com.x.cms.assemble.control.MessageFactory
;
...
...
@@ -17,6 +15,7 @@ import com.x.cms.assemble.control.service.UserManagerService;
import
com.x.cms.core.entity.AppInfo
;
import
com.x.cms.core.entity.CategoryInfo
;
import
com.x.cms.core.entity.Document
;
import
com.x.cms.core.entity.query.DocumentNotify
;
import
org.apache.commons.lang3.BooleanUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -29,35 +28,48 @@ import java.util.stream.Collectors;
* Document正式发布后,向通知对象或者所有的阅读者推送消息通知
* @author sword
*/
public
class
QueueSendDocumentNotify
extends
AbstractQueue
<
String
>
{
public
class
QueueSendDocumentNotify
extends
AbstractQueue
<
DocumentNotify
>
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
QueueSendDocumentNotify
.
class
);
private
UserManagerService
userManagerService
=
new
UserManagerService
();
@Override
public
void
execute
(
String
documentId
)
throws
Exception
{
logger
.
debug
(
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>start QueueSendDocumentNotify:"
+
documentId
);
if
(
StringUtils
.
isEmpty
(
documentId
)
)
{
logger
.
debug
(
"can not send publish notify , document is NULL!"
);
public
void
execute
(
DocumentNotify
documentNotify
)
throws
Exception
{
logger
.
debug
(
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>start QueueSendDocumentNotify:{}"
,
documentNotify
);
if
(
StringUtils
.
isEmpty
(
documentNotify
.
getDocumentId
())
)
{
return
;
}
final
List
<
String
>
persons
=
new
ArrayList
<>();
Document
document
=
null
;
AppInfo
appInfo
=
null
;
CategoryInfo
category
=
null
;
try
(
EntityManagerContainer
emc
=
EntityManagerContainerFactory
.
instance
().
create
())
{
document
=
emc
.
find
(
documentId
,
Document
.
class
);
if
(
document
!=
null
&&
StringUtils
.
equals
(
"信息"
,
document
.
getDocumentType
())
&&
Config
.
messages
().
get
(
MessageConnector
.
TYPE_CMS_PUBLISH
)!=
null
)
{
logger
.
debug
(
"send publish notify for new document:"
+
document
.
getTitle
()
);
AppInfo
appInfo
=
emc
.
find
(
document
.
getAppId
(),
AppInfo
.
class
);
CategoryInfo
category
=
emc
.
find
(
document
.
getCategoryId
(),
CategoryInfo
.
class
);
if
(
appInfo
!=
null
&&
category
!=
null
)
{
document
=
emc
.
find
(
documentNotify
.
getDocumentId
(),
Document
.
class
);
if
(
document
!=
null
){
appInfo
=
emc
.
find
(
document
.
getAppId
(),
AppInfo
.
class
);
category
=
emc
.
find
(
document
.
getCategoryId
(),
CategoryInfo
.
class
);
if
(
appInfo
==
null
||
category
==
null
){
return
;
}
}
else
{
return
;
}
}
if
(
BooleanUtils
.
isFalse
(
category
.
getSendNotify
())){
return
;
}
if
(
ListTools
.
isNotEmpty
(
documentNotify
.
getNotifyPersonList
())
&&
!
BooleanUtils
.
isTrue
(
documentNotify
.
getNotifyByDocumentReadPerson
())){
documentNotify
.
getNotifyPersonList
().
stream
().
forEach
(
name
->
{
persons
.
addAll
(
userManagerService
.
listPersonWithName
(
name
));
});
}
else
{
ReviewService
reviewService
=
new
ReviewService
();
persons
.
addAll
(
reviewService
.
listPermissionPersons
(
appInfo
,
category
,
document
));
if
(
ListTools
.
isNotEmpty
(
persons
))
{
//有可能是*, 一般是所有的人员标识列表
if
(
persons
.
contains
(
"*"
)
&&
!
BooleanUtils
.
isFalse
(
category
.
getBlankToAllNotify
()))
{
if
(
persons
.
contains
(
"*"
)){
String
topUnitName
=
document
.
getCreatorTopUnitName
();
logger
.
debug
(
">>>>>document.getCreatorTopUnitName()="
+
topUnitName
);
if
(
StringUtils
.
equalsAnyIgnoreCase
(
"cipher"
,
topUnitName
)
||
StringUtils
.
equalsAnyIgnoreCase
(
"xadmin"
,
topUnitName
))
{
if
(
StringUtils
.
equalsAnyIgnoreCase
(
"cipher"
,
topUnitName
)
||
StringUtils
.
equalsAnyIgnoreCase
(
"xadmin"
,
topUnitName
))
{
//取发起人所有顶层组织
if
(!
StringUtils
.
equalsAnyIgnoreCase
(
"cipher"
,
document
.
getCreatorIdentity
())
&&
!
StringUtils
.
equalsAnyIgnoreCase
(
"xadmin"
,
document
.
getCreatorIdentity
()))
{
...
...
@@ -69,13 +81,11 @@ public class QueueSendDocumentNotify extends AbstractQueue<String> {
}
if
(
StringUtils
.
isNotEmpty
(
topUnitName
))
{
//取顶层组织的所有人
persons
.
clear
();
persons
.
addAll
(
listPersonWithUnit
(
topUnitName
));
}
}
}
}
}
}
if
(
ListTools
.
isNotEmpty
(
persons
))
{
List
<
String
>
personList
=
persons
.
stream
().
distinct
().
collect
(
Collectors
.
toList
());
persons
.
clear
();
...
...
@@ -87,13 +97,15 @@ public class QueueSendDocumentNotify extends AbstractQueue<String> {
}
}
personList
.
clear
();
logger
.
debug
(
document
Id
+
" cms send total count:"
+
persons
.
size
()
);
logger
.
debug
(
document
Notify
.
getDocumentId
()
+
" cms send total count:"
+
persons
.
size
()
);
}
if
(
document
!=
null
&&
StringUtils
.
isNotBlank
(
document
.
getCreatorPerson
())){
boolean
flag
=
document
!=
null
&&
StringUtils
.
isNotBlank
(
document
.
getCreatorPerson
())
&&
!
BooleanUtils
.
isFalse
(
documentNotify
.
getNotifyCreatePerson
());
if
(
flag
){
MessageWo
wo
=
MessageWo
.
copier
.
copy
(
document
);
MessageFactory
.
cms_publish_creator
(
wo
);
}
logger
.
debug
(
document
Id
+
" QueueSendDocumentNotify cms send publish notify for new document completed! "
);
logger
.
debug
(
document
Notify
.
getDocumentId
()
+
" QueueSendDocumentNotify cms send publish notify for new document completed! "
);
}
/**
...
...
@@ -102,7 +114,6 @@ public class QueueSendDocumentNotify extends AbstractQueue<String> {
* @return
*/
private
List
<
String
>
listPersonWithUnit
(
String
unitName
)
{
UserManagerService
userManagerService
=
new
UserManagerService
();
List
<
String
>
persons
=
null
;
try
{
persons
=
userManagerService
.
listPersonWithUnit
(
unitName
);
...
...
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/Document.java
浏览文件 @
97510379
...
...
@@ -48,6 +48,7 @@ public class Document extends SliceJpaObject {
private
static
final
long
serialVersionUID
=
7668822947307502058L
;
private
static
final
String
TABLE
=
PersistenceProperties
.
Document
.
table
;
public
static
final
int
STRING_VALUE_MAX_LENGTH
=
JpaObject
.
length_255B
;
public
static
final
String
DOC_STATUS_PUBLISH
=
"published"
;
/* 以上为 JpaObject 默认字段 */
@Override
...
...
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/query/DocumentNotify.java
0 → 100644
浏览文件 @
97510379
package
com.x.cms.core.entity.query
;
import
com.x.base.core.project.annotation.FieldDescribe
;
import
com.x.base.core.project.gson.GsonPropertyObject
;
import
java.util.List
;
/**
* 消息通知对象
*
* @author sword
* @date 2022/03/10 16:45
**/
public
class
DocumentNotify
extends
GsonPropertyObject
{
@FieldDescribe
(
"文档ID"
)
private
String
documentId
;
@FieldDescribe
(
"消息通知对象:人员、组织或者群组"
)
private
List
<
String
>
notifyPersonList
;
@FieldDescribe
(
"是否根据文档的可见范围发送:true(忽略notifyPersonList的值)|false(默认)"
)
private
Boolean
notifyByDocumentReadPerson
;
@FieldDescribe
(
"是否通知文档创建人:true(默认)|false"
)
private
Boolean
notifyCreatePerson
;
public
String
getDocumentId
()
{
return
documentId
;
}
public
void
setDocumentId
(
String
documentId
)
{
this
.
documentId
=
documentId
;
}
public
List
<
String
>
getNotifyPersonList
()
{
return
notifyPersonList
;
}
public
void
setNotifyPersonList
(
List
<
String
>
notifyPersonList
)
{
this
.
notifyPersonList
=
notifyPersonList
;
}
public
Boolean
getNotifyByDocumentReadPerson
()
{
return
notifyByDocumentReadPerson
;
}
public
void
setNotifyByDocumentReadPerson
(
Boolean
notifyByDocumentReadPerson
)
{
this
.
notifyByDocumentReadPerson
=
notifyByDocumentReadPerson
;
}
public
Boolean
getNotifyCreatePerson
()
{
return
notifyCreatePerson
;
}
public
void
setNotifyCreatePerson
(
Boolean
notifyCreatePerson
)
{
this
.
notifyCreatePerson
=
notifyCreatePerson
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录