Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦中观雨
cat
提交
d60ab812
C
cat
项目概览
梦中观雨
/
cat
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
cat
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d60ab812
编写于
8月 21, 2012
作者:
F
Frankie Wu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
further implementation
上级
16ebe4b3
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
442 addition
and
29 deletion
+442
-29
bee-engine/pom.xml
bee-engine/pom.xml
+1
-0
bee-engine/src/main/java/com/dianping/bee/engine/build/ComponentsConfigurator.java
...com/dianping/bee/engine/build/ComponentsConfigurator.java
+14
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/DatabaseProvider.java
...in/java/com/dianping/bee/engine/spi/DatabaseProvider.java
+8
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/Index.java
...gine/src/main/java/com/dianping/bee/engine/spi/Index.java
+6
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/RowFilter.java
.../src/main/java/com/dianping/bee/engine/spi/RowFilter.java
+4
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/Statement.java
.../src/main/java/com/dianping/bee/engine/spi/Statement.java
+7
-1
bee-engine/src/main/java/com/dianping/bee/engine/spi/StatementManager.java
...in/java/com/dianping/bee/engine/spi/StatementManager.java
+7
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/TableProvider.java
.../main/java/com/dianping/bee/engine/spi/TableProvider.java
+4
-7
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/BadSQLSyntaxException.java
...anping/bee/engine/spi/internal/BadSQLSyntaxException.java
+13
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/DefaultStatement.java
...om/dianping/bee/engine/spi/internal/DefaultStatement.java
+42
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/DefaultStatementManager.java
...ping/bee/engine/spi/internal/DefaultStatementManager.java
+41
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/SingleTableStatementVisitor.java
.../bee/engine/spi/internal/SingleTableStatementVisitor.java
+132
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/TableHelper.java
...ava/com/dianping/bee/engine/spi/internal/TableHelper.java
+14
-0
bee-engine/src/main/java/com/dianping/bee/engine/spi/meta/TableMeta.java
...main/java/com/dianping/bee/engine/spi/meta/TableMeta.java
+0
-5
bee-engine/src/main/java/com/dianping/bee/engine/visitor/DefaultVisitor.java
.../java/com/dianping/bee/engine/visitor/DefaultVisitor.java
+1
-0
bee-engine/src/main/resources/META-INF/plexus/components.xml
bee-engine/src/main/resources/META-INF/plexus/components.xml
+9
-0
bee-engine/src/test/java/com/dianping/bee/db/CatDatabase.java
...engine/src/test/java/com/dianping/bee/db/CatDatabase.java
+131
-0
bee-engine/src/test/java/com/dianping/bee/engine/spi/SpiTest.java
...ne/src/test/java/com/dianping/bee/engine/spi/SpiTest.java
+6
-14
cat-hadoop/src/main/resources/META-INF/dal/jdbc/dal.xml
cat-hadoop/src/main/resources/META-INF/dal/jdbc/dal.xml
+2
-2
未找到文件。
bee-engine/pom.xml
浏览文件 @
d60ab812
...
...
@@ -35,6 +35,7 @@
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<version>
3.1
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
</project>
...
...
bee-engine/src/main/java/com/dianping/bee/engine/build/ComponentsConfigurator.java
浏览文件 @
d60ab812
...
...
@@ -3,8 +3,14 @@ package com.dianping.bee.engine.build;
import
java.util.ArrayList
;
import
java.util.List
;
import
com.dianping.bee.engine.spi.Statement
;
import
com.dianping.bee.engine.spi.StatementManager
;
import
com.dianping.bee.engine.spi.TableProviderManager
;
import
com.dianping.bee.engine.spi.internal.DefaultStatement
;
import
com.dianping.bee.engine.spi.internal.DefaultStatementManager
;
import
com.dianping.bee.engine.spi.internal.DefaultTableProviderManager
;
import
com.dianping.bee.engine.spi.internal.SingleTableStatementVisitor
;
import
com.dianping.bee.engine.spi.internal.TableHelper
;
import
com.site.lookup.configuration.AbstractResourceConfigurator
;
import
com.site.lookup.configuration.Component
;
...
...
@@ -14,6 +20,14 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
List
<
Component
>
all
=
new
ArrayList
<
Component
>();
all
.
add
(
C
(
TableProviderManager
.
class
,
DefaultTableProviderManager
.
class
));
all
.
add
(
C
(
StatementManager
.
class
,
DefaultStatementManager
.
class
));
all
.
add
(
C
(
Statement
.
class
,
DefaultStatement
.
class
).
is
(
PER_LOOKUP
));
all
.
add
(
C
(
TableHelper
.
class
)
//
.
req
(
TableProviderManager
.
class
));
all
.
add
(
C
(
SingleTableStatementVisitor
.
class
).
is
(
PER_LOOKUP
)
//
.
req
(
TableHelper
.
class
,
Statement
.
class
));
return
all
;
}
...
...
bee-engine/src/main/java/com/dianping/bee/engine/spi/DatabaseProvider.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi
;
public
interface
DatabaseProvider
{
public
String
getName
();
public
TableProvider
[]
getTables
();
}
\ No newline at end of file
bee-engine/src/main/java/com/dianping/bee/engine/spi/Index.java
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi
;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
public
interface
Index
{
public
int
getLength
();
public
ColumnMeta
getColumn
(
int
index
);
public
boolean
isAscend
(
int
index
);
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/RowFilter.java
浏览文件 @
d60ab812
...
...
@@ -2,6 +2,10 @@ package com.dianping.bee.engine.spi;
import
java.util.List
;
import
com.alibaba.cobar.parser.ast.expression.Expression
;
public
interface
RowFilter
{
public
boolean
filter
(
List
<
Object
>
values
);
public
void
setExpression
(
Expression
where
);
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/Statement.java
浏览文件 @
d60ab812
...
...
@@ -5,9 +5,15 @@ import java.util.List;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
public
interface
Statement
{
public
List
<
ColumnMeta
>
getSelect
ed
Columns
();
public
List
<
ColumnMeta
>
getSelectColumns
();
public
Index
getIndex
();
public
RowFilter
getRowFilter
();
public
String
getTableName
();
public
void
setRowFilter
(
RowFilter
rowFilter
);
public
void
setSelectColumns
(
List
<
ColumnMeta
>
selectColumns
);
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/StatementManager.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi
;
import
java.sql.SQLSyntaxErrorException
;
public
interface
StatementManager
{
public
Statement
parse
(
String
sql
)
throws
SQLSyntaxErrorException
;
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/TableProvider.java
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi
;
import
java.util.List
;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
import
com.dianping.bee.engine.spi.meta.TableMeta
;
public
interface
TableProvider
{
public
TableMeta
getMeta
();
public
String
getName
();
public
List
<
ColumnMeta
>
getColumns
();
public
ColumnMeta
[]
getColumns
();
public
List
<
Index
>
getIndexes
();
public
Index
[]
getIndexes
();
public
RowSet
query
(
List
<
ColumnMeta
>
selectedColumns
,
Index
index
,
RowFilter
filter
);
public
RowSet
query
(
Statement
stmt
);
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/BadSQLSyntaxException.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi.internal
;
public
class
BadSQLSyntaxException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
4674438101686847844L
;
public
BadSQLSyntaxException
(
String
message
)
{
super
(
message
);
}
public
BadSQLSyntaxException
(
String
pattern
,
Object
...
args
)
{
super
(
String
.
format
(
pattern
,
args
));
}
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/DefaultStatement.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi.internal
;
import
java.util.List
;
import
com.dianping.bee.engine.spi.Index
;
import
com.dianping.bee.engine.spi.RowFilter
;
import
com.dianping.bee.engine.spi.Statement
;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
public
class
DefaultStatement
implements
Statement
{
@Override
public
List
<
ColumnMeta
>
getSelectColumns
()
{
// TODO Auto-generated method stub
return
null
;
}
@Override
public
Index
getIndex
()
{
// TODO Auto-generated method stub
return
null
;
}
@Override
public
RowFilter
getRowFilter
()
{
// TODO Auto-generated method stub
return
null
;
}
@Override
public
String
getTableName
()
{
// TODO Auto-generated method stub
return
null
;
}
@Override
public
void
setRowFilter
(
RowFilter
rowFilter
)
{
// TODO Auto-generated method stub
}
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/DefaultStatementManager.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi.internal
;
import
java.sql.SQLSyntaxErrorException
;
import
java.util.HashMap
;
import
java.util.Map
;
import
com.alibaba.cobar.parser.ast.stmt.SQLStatement
;
import
com.alibaba.cobar.parser.recognizer.SQLParserDelegate
;
import
com.dianping.bee.engine.spi.Statement
;
import
com.dianping.bee.engine.spi.StatementManager
;
import
com.site.lookup.ContainerHolder
;
public
class
DefaultStatementManager
extends
ContainerHolder
implements
StatementManager
{
private
Map
<
String
,
Statement
>
m_statements
=
new
HashMap
<
String
,
Statement
>();
@Override
public
Statement
parse
(
String
sql
)
throws
SQLSyntaxErrorException
{
Statement
statement
=
m_statements
.
get
(
sql
);
if
(
statement
==
null
)
{
synchronized
(
m_statements
)
{
statement
=
m_statements
.
get
(
sql
);
if
(
statement
==
null
)
{
statement
=
parseSQL
(
sql
);
m_statements
.
put
(
sql
,
statement
);
}
}
}
return
statement
;
}
private
Statement
parseSQL
(
String
sql
)
throws
SQLSyntaxErrorException
{
SingleTableStatementVisitor
visitor
=
lookup
(
SingleTableStatementVisitor
.
class
);
SQLStatement
statement
=
SQLParserDelegate
.
parse
(
sql
);
statement
.
accept
(
visitor
);
return
visitor
.
getStatement
();
}
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/SingleTableStatementVisitor.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi.internal
;
import
java.util.ArrayList
;
import
java.util.List
;
import
com.alibaba.cobar.parser.ast.expression.Expression
;
import
com.alibaba.cobar.parser.ast.expression.primary.Identifier
;
import
com.alibaba.cobar.parser.ast.fragment.tableref.TableRefFactor
;
import
com.alibaba.cobar.parser.ast.fragment.tableref.TableReference
;
import
com.alibaba.cobar.parser.ast.stmt.dml.DMLSelectStatement
;
import
com.alibaba.cobar.parser.util.Pair
;
import
com.alibaba.cobar.parser.visitor.EmptySQLASTVisitor
;
import
com.dianping.bee.engine.spi.RowFilter
;
import
com.dianping.bee.engine.spi.Statement
;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
import
com.site.lookup.annotation.Inject
;
public
class
SingleTableStatementVisitor
extends
EmptySQLASTVisitor
{
@Inject
private
TableHelper
m_helper
;
@Inject
private
Statement
m_stmt
;
@Inject
private
RowFilter
m_rowFilter
;
private
String
m_alias
;
private
String
m_tableName
;
private
Clause
m_clause
;
private
List
<
ColumnMeta
>
m_selectColumns
=
new
ArrayList
<
ColumnMeta
>();
private
List
<
ColumnMeta
>
m_whereColumns
=
new
ArrayList
<
ColumnMeta
>();
public
Statement
getStatement
()
{
return
m_stmt
;
}
@Override
public
void
visit
(
DMLSelectStatement
node
)
{
TableReference
tr
=
node
.
getTables
();
m_clause
=
Clause
.
TABLE
;
if
(
tr
.
isSingleTable
())
{
tr
.
accept
(
this
);
}
else
{
throw
new
RuntimeException
(
"Not a single table query!"
);
}
List
<
Pair
<
Expression
,
String
>>
exprList
=
node
.
getSelectExprList
();
m_clause
=
Clause
.
SELECT
;
for
(
Pair
<
Expression
,
String
>
pair
:
exprList
)
{
String
alias
=
pair
.
getValue
();
if
(
alias
!=
null
&&
!
alias
.
equals
(
m_alias
))
{
throw
new
BadSQLSyntaxException
(
"Invalid select alias(%s)!"
,
alias
);
}
pair
.
getKey
().
accept
(
this
);
}
m_stmt
.
setSelectColumns
(
m_selectColumns
);
m_clause
=
Clause
.
WHERE
;
Expression
where
=
node
.
getWhere
();
if
(
where
!=
null
)
{
// to get columns from where clause
where
.
accept
(
this
);
// to evaluate where clause
m_rowFilter
.
setExpression
(
where
);
m_stmt
.
setRowFilter
(
m_rowFilter
);
}
}
@Override
public
void
visit
(
Identifier
node
)
{
switch
(
m_clause
)
{
case
SELECT:
String
selectColumnName
=
node
.
getIdTextUpUnescape
();
findOrCreateColumnFrom
(
m_selectColumns
,
selectColumnName
);
break
;
case
WHERE:
String
whereColumnName
=
node
.
getIdTextUpUnescape
();
findOrCreateColumnFrom
(
m_whereColumns
,
whereColumnName
);
break
;
}
}
private
ColumnMeta
findOrCreateColumnFrom
(
List
<
ColumnMeta
>
columns
,
String
columnName
)
{
for
(
ColumnMeta
column
:
columns
)
{
if
(
column
.
getName
().
equals
(
columnName
))
{
return
column
;
}
}
ColumnMeta
column
=
m_helper
.
findColumn
(
m_tableName
,
columnName
);
columns
.
add
(
column
);
return
column
;
}
@Override
public
void
visit
(
TableRefFactor
node
)
{
m_alias
=
node
.
getAlias
();
m_tableName
=
node
.
getTable
().
getIdTextUpUnescape
();
}
static
enum
Clause
{
SELECT
,
TABLE
,
WHERE
,
GROUP
,
HAVING
,
ORDER
;
}
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/internal/TableHelper.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi.internal
;
import
com.dianping.bee.engine.spi.TableProviderManager
;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
import
com.site.lookup.annotation.Inject
;
public
class
TableHelper
{
@Inject
private
TableProviderManager
m_manager
;
public
ColumnMeta
findColumn
(
String
table
,
String
column
)
{
return
null
;
}
}
bee-engine/src/main/java/com/dianping/bee/engine/spi/meta/TableMeta.java
已删除
100644 → 0
浏览文件 @
16ebe4b3
package
com.dianping.bee.engine.spi.meta
;
public
interface
TableMeta
{
}
bee-engine/src/main/java/com/dianping/bee/engine/visitor/DefaultVisitor.java
浏览文件 @
d60ab812
...
...
@@ -337,6 +337,7 @@ public class DefaultVisitor implements SQLASTVisitor {
selectStep
=
SELECT_STEP
.
WHERE
;
Expression
where
=
node
.
getWhere
();
visitChild
(
2
,
where
);
this
.
whereExpression
=
where
;
...
...
bee-engine/src/main/resources/META-INF/plexus/components.xml
浏览文件 @
d60ab812
...
...
@@ -4,5 +4,14 @@
<role>
com.dianping.bee.engine.spi.TableProviderManager
</role>
<implementation>
com.dianping.bee.engine.spi.internal.DefaultTableProviderManager
</implementation>
</component>
<component>
<role>
com.dianping.bee.engine.spi.StatementManager
</role>
<implementation>
com.dianping.bee.engine.spi.internal.DefaultStatementManager
</implementation>
</component>
<component>
<role>
com.dianping.bee.engine.spi.Statement
</role>
<implementation>
com.dianping.bee.engine.spi.internal.DefaultStatement
</implementation>
<instantiation-strategy>
per-lookup
</instantiation-strategy>
</component>
</components>
</plexus>
bee-engine/src/test/java/com/dianping/bee/db/CatDatabase.java
0 → 100644
浏览文件 @
d60ab812
package
com.dianping.bee.db
;
import
com.dianping.bee.engine.spi.DatabaseProvider
;
import
com.dianping.bee.engine.spi.Index
;
import
com.dianping.bee.engine.spi.RowSet
;
import
com.dianping.bee.engine.spi.Statement
;
import
com.dianping.bee.engine.spi.TableProvider
;
import
com.dianping.bee.engine.spi.meta.ColumnMeta
;
public
class
CatDatabase
implements
DatabaseProvider
{
@Override
public
String
getName
()
{
return
"cat"
;
}
@Override
public
CatTable
[]
getTables
()
{
return
CatTable
.
values
();
}
public
static
enum
CatTable
implements
TableProvider
{
Transaction
(
"transaction"
)
{
@Override
public
TransactionColumn
[]
getColumns
()
{
return
TransactionColumn
.
values
();
}
@Override
public
TransactionIndex
[]
getIndexes
()
{
return
TransactionIndex
.
values
();
}
},
Event
(
"event"
),
Heartbeat
(
"heartbeat"
),
Problem
(
"problem"
);
private
String
m_name
;
private
CatTable
(
String
name
)
{
m_name
=
name
;
}
@Override
public
ColumnMeta
[]
getColumns
()
{
// TODO Auto-generated method stub
return
null
;
}
@Override
public
Index
[]
getIndexes
()
{
// TODO Auto-generated method stub
return
null
;
}
@Override
public
String
getName
()
{
return
m_name
;
}
@Override
public
RowSet
query
(
Statement
stmt
)
{
// TODO Auto-generated method stub
return
null
;
}
}
public
static
enum
TransactionColumn
implements
ColumnMeta
{
Type
(
String
.
class
),
Name
(
String
.
class
),
TotalCount
(
Integer
.
class
),
Failures
(
Integer
.
class
),
SampleLink
(
String
.
class
),
MinDuration
(
Integer
.
class
),
MaxDuration
(
Integer
.
class
),
SumDuration
(
Long
.
class
),
Sum2Duration
(
Long
.
class
),
Line95
(
Integer
.
class
);
private
String
m_name
;
private
Class
<?>
m_type
;
private
TransactionColumn
(
Class
<?>
type
)
{
m_type
=
type
;
m_name
=
name
().
toLowerCase
();
}
@Override
public
Object
getName
()
{
return
m_name
;
}
}
public
static
enum
TransactionIndex
implements
Index
{
IDX_TYPE_NAME
{
@Override
public
ColumnMeta
getColumn
(
int
index
)
{
switch
(
index
)
{
case
0
:
return
TransactionColumn
.
Type
;
case
1
:
return
TransactionColumn
.
Name
;
}
throw
new
RuntimeException
(
"Internal error happened!"
);
}
@Override
public
int
getLength
()
{
return
2
;
}
@Override
public
boolean
isAscend
(
int
index
)
{
return
true
;
}
};
}
}
bee-engine/src/test/java/com/dianping/bee/engine/spi/SpiTest.java
浏览文件 @
d60ab812
package
com.dianping.bee.engine.spi
;
import
java.util.List
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.JUnit4
;
...
...
@@ -11,19 +9,13 @@ import com.site.lookup.ComponentTestCase;
@RunWith
(
JUnit4
.
class
)
public
class
SpiTest
extends
ComponentTestCase
{
// select a, sum(a) from t1 where c=? and d=?
@Test
public
void
sample
()
throws
Exception
{
TableProviderManager
manager
=
lookup
(
TableProviderManager
.
class
);
TableProvider
table
=
manager
.
getTableProvider
(
"t1"
);
Statement
stmt
=
null
;
// stmt.accept(visitor);
List
<
ColumnMeta
>
cols
=
stmt
.
getSelectedColumns
();
Index
index
=
stmt
.
getIndex
();
RowFilter
filter
=
stmt
.
getRowFilter
();
RowSet
rowset
=
table
.
query
(
cols
,
index
,
filter
);
TableProviderManager
tableProviderManager
=
lookup
(
TableProviderManager
.
class
);
StatementManager
statementManager
=
lookup
(
StatementManager
.
class
);
Statement
stmt
=
statementManager
.
parse
(
"select a, sum(a) from t1 where c=? and d=?"
);
TableProvider
table
=
tableProviderManager
.
getTableProvider
(
stmt
.
getTableName
());
RowSet
rowset
=
table
.
query
(
stmt
);
display
(
rowset
);
}
...
...
@@ -55,7 +47,7 @@ public class SpiTest extends ComponentTestCase {
}
sb
.
append
(
rows
).
append
(
" rows selected."
);
System
.
out
.
println
(
sb
);
}
}
cat-hadoop/src/main/resources/META-INF/dal/jdbc/dal.xml
浏览文件 @
d60ab812
...
...
@@ -24,11 +24,11 @@
AND
<FIELD
name=
'tag-request'
/>
= ${tag-request}
</IF>
<IF
type=
'EQ'
field=
'direction'
value=
'true'
>
AND
<FIELD
name=
'message-id'
/>
\
\
> ${message-id}
AND
<FIELD
name=
'message-id'
/>
\> ${message-id}
ORDER BY
<FIELD
name=
'message-id'
/>
ASC
</IF>
<IF
type=
'EQ'
field=
'direction'
value=
'false'
>
AND
<FIELD
name=
'message-id'
/>
\
\
<
${message-id}
AND
<FIELD
name=
'message-id'
/>
\
<
${message-id}
ORDER BY
<FIELD
name=
'message-id'
/>
DESC
</IF>
LIMIT 1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录