Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Kwan的解忧杂货铺@新空间代码工作室
elasticsearch-demo
提交
dd43ec00
E
elasticsearch-demo
项目概览
Kwan的解忧杂货铺@新空间代码工作室
/
elasticsearch-demo
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
elasticsearch-demo
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
dd43ec00
编写于
5月 13, 2023
作者:
Kwan的解忧杂货铺@新空间代码工作室
🐭
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix:课程搜索项目
上级
055c0541
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
503 addition
and
14 deletion
+503
-14
pom.xml
pom.xml
+20
-5
src/main/java/com/kwan/shuyu/SearchApplication.java
src/main/java/com/kwan/shuyu/SearchApplication.java
+1
-2
src/main/java/com/kwan/shuyu/controller/EsCourseController.java
...in/java/com/kwan/shuyu/controller/EsCourseController.java
+25
-0
src/main/java/com/kwan/shuyu/domain/CommonCode.java
src/main/java/com/kwan/shuyu/domain/CommonCode.java
+53
-0
src/main/java/com/kwan/shuyu/domain/CoursePub.java
src/main/java/com/kwan/shuyu/domain/CoursePub.java
+44
-0
src/main/java/com/kwan/shuyu/domain/CourseSearchParam.java
src/main/java/com/kwan/shuyu/domain/CourseSearchParam.java
+38
-0
src/main/java/com/kwan/shuyu/domain/QueryResponseResult.java
src/main/java/com/kwan/shuyu/domain/QueryResponseResult.java
+16
-0
src/main/java/com/kwan/shuyu/domain/QueryResult.java
src/main/java/com/kwan/shuyu/domain/QueryResult.java
+20
-0
src/main/java/com/kwan/shuyu/domain/Response.java
src/main/java/com/kwan/shuyu/domain/Response.java
+7
-0
src/main/java/com/kwan/shuyu/domain/ResponseResult.java
src/main/java/com/kwan/shuyu/domain/ResponseResult.java
+33
-0
src/main/java/com/kwan/shuyu/domain/ResultCode.java
src/main/java/com/kwan/shuyu/domain/ResultCode.java
+19
-0
src/main/java/com/kwan/shuyu/service/EsCourseServiceImpl.java
...main/java/com/kwan/shuyu/service/EsCourseServiceImpl.java
+168
-0
src/main/java/com/kwan/shuyu/service/impl/EsCourseService.java
...ain/java/com/kwan/shuyu/service/impl/EsCourseService.java
+19
-0
src/main/resources/application.yml
src/main/resources/application.yml
+3
-1
src/main/resources/logback-spring.xml
src/main/resources/logback-spring.xml
+0
-6
src/test/java/es_06_log/TestLog.java
src/test/java/es_06_log/TestLog.java
+37
-0
未找到文件。
pom.xml
浏览文件 @
dd43ec00
...
...
@@ -15,7 +15,7 @@
<dependency>
<groupId>
org.elasticsearch.client
</groupId>
<artifactId>
elasticsearch-rest-high-level-client
</artifactId>
<version>
7.
3
.0
</version>
<version>
7.
12
.0
</version>
<exclusions>
<exclusion>
<groupId>
org.elasticsearch
</groupId>
...
...
@@ -26,7 +26,7 @@
<dependency>
<groupId>
org.elasticsearch
</groupId>
<artifactId>
elasticsearch
</artifactId>
<version>
7.
3
.0
</version>
<version>
7.
12
.0
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
...
...
@@ -39,15 +39,30 @@
<scope>
test
</scope>
<version>
2.0.6.RELEASE
</version>
</dependency>
<dependency>
<groupId>
org.elasticsearch.plugin
</groupId>
<artifactId>
x-pack-sql-jdbc
</artifactId>
<version>
7.3.0
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
<version>
2.0.1.RELEASE
</version>
</dependency>
<dependency>
<groupId>
org.projectlombok
</groupId>
<artifactId>
lombok
</artifactId>
<version>
1.16.10
</version>
</dependency>
<dependency>
<groupId>
org.elasticsearch.plugin
</groupId>
<artifactId>
x-pack-sql-jdbc
</artifactId>
<version>
7.3.0
</version>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-io
</artifactId>
<version>
1.3.2
</version>
</dependency>
<dependency>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<version>
3.1
</version>
</dependency>
</dependencies>
<repositories>
...
...
src/main/java/com/kwan/shuyu/SearchApplication.java
浏览文件 @
dd43ec00
...
...
@@ -3,10 +3,9 @@ package com.kwan.shuyu;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
@SpringBootApplication
public
class
SearchApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
SearchApplication
.
class
,
args
);
SpringApplication
.
run
(
SearchApplication
.
class
,
args
);
}
}
src/main/java/com/kwan/shuyu/controller/EsCourseController.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.controller
;
import
com.kwan.shuyu.domain.CoursePub
;
import
com.kwan.shuyu.domain.CourseSearchParam
;
import
com.kwan.shuyu.domain.QueryResponseResult
;
import
com.kwan.shuyu.service.EsCourseServiceImpl
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
@RequestMapping
(
"/search/course"
)
public
class
EsCourseController
{
@Autowired
private
EsCourseServiceImpl
esCourseServiceImpl
;
@GetMapping
(
value
=
"/list/{page}/{size}"
)
public
QueryResponseResult
<
CoursePub
>
list
(
@PathVariable
(
"page"
)
int
page
,
@PathVariable
(
"size"
)
int
size
,
CourseSearchParam
courseSearchParam
)
{
return
esCourseServiceImpl
.
list
(
page
,
size
,
courseSearchParam
);
}
}
\ No newline at end of file
src/main/java/com/kwan/shuyu/domain/CommonCode.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
import
lombok.ToString
;
/**
* @author : qinyingjie
* @version : 2.2.0
* @date : 2023/5/13 22:20
*/
@ToString
public
enum
CommonCode
implements
ResultCode
{
INVALID_PARAM
(
false
,
10003
,
"非法参数!"
),
SUCCESS
(
true
,
10000
,
"操作成功!"
),
FAIL
(
false
,
11111
,
"操作失败!"
),
UNAUTHENTICATED
(
false
,
10001
,
"此操作需要登陆系统!"
),
UNAUTHORISE
(
false
,
10002
,
"权限不足,无权操作!"
),
SERVER_ERROR
(
false
,
99999
,
"抱歉,系统繁忙,请稍后重试!"
);
/**
* 操作是否成功
*/
boolean
success
;
/**
* 操作代码
*/
int
code
;
/**
* 提示信息
*/
String
message
;
private
CommonCode
(
boolean
success
,
int
code
,
String
message
)
{
this
.
success
=
success
;
this
.
code
=
code
;
this
.
message
=
message
;
}
@Override
public
boolean
success
()
{
return
success
;
}
@Override
public
int
code
()
{
return
code
;
}
@Override
public
String
message
()
{
return
message
;
}
}
src/main/java/com/kwan/shuyu/domain/CoursePub.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
import
lombok.Data
;
import
lombok.ToString
;
import
java.io.Serializable
;
import
java.util.Date
;
@Data
@ToString
public
class
CoursePub
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
916357110051689487L
;
private
String
id
;
private
String
name
;
private
String
users
;
private
String
mt
;
private
String
st
;
private
String
grade
;
private
String
studymodel
;
private
String
teachmode
;
private
String
description
;
/**
* 图片
*/
private
String
pic
;
/**
* 时间戳
*/
private
Date
timestamp
;
private
String
charge
;
private
String
valid
;
private
String
qq
;
private
Double
price
;
private
Double
price_old
;
private
String
expires
;
/**
* 课程计划
*/
private
String
teachplan
;
/**
* 课程发布时间
*/
private
String
pubTime
;
}
\ No newline at end of file
src/main/java/com/kwan/shuyu/domain/CourseSearchParam.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
import
lombok.Data
;
import
lombok.ToString
;
@Data
@ToString
public
class
CourseSearchParam
{
/**
* 关键字
*/
String
keyword
;
/**
* 一级分类
*/
String
mt
;
/**
* 二级分类
*/
String
st
;
/**
* 难度等级
*/
String
grade
;
/**
* 价格区间
*/
Float
price_min
;
Float
price_max
;
/**
* 排序字段
*/
String
sort
;
/**
* 过虑字段
*/
String
filter
;
}
\ No newline at end of file
src/main/java/com/kwan/shuyu/domain/QueryResponseResult.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
import
lombok.Data
;
import
lombok.ToString
;
@Data
@ToString
public
class
QueryResponseResult
<
T
>
extends
ResponseResult
{
QueryResult
<
T
>
queryResult
;
public
QueryResponseResult
(
ResultCode
resultCode
,
QueryResult
queryResult
)
{
super
(
resultCode
);
this
.
queryResult
=
queryResult
;
}
}
\ No newline at end of file
src/main/java/com/kwan/shuyu/domain/QueryResult.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
import
lombok.Data
;
import
lombok.ToString
;
import
java.util.List
;
@Data
@ToString
public
class
QueryResult
<
T
>
{
/**
* 数据列表
*/
private
List
<
T
>
list
;
/**
* 数据总数
*/
private
long
total
;
}
src/main/java/com/kwan/shuyu/domain/Response.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
public
interface
Response
{
public
static
final
boolean
SUCCESS
=
true
;
public
static
final
int
SUCCESS_CODE
=
10000
;
}
src/main/java/com/kwan/shuyu/domain/ResponseResult.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.ToString
;
@Data
@ToString
@NoArgsConstructor
public
class
ResponseResult
implements
Response
{
/**
* 操作是否成功
*/
boolean
success
=
SUCCESS
;
/**
* 操作代码
*/
int
code
=
SUCCESS_CODE
;
/**
* 提示信息
*/
String
message
;
public
ResponseResult
(
ResultCode
resultCode
)
{
this
.
success
=
resultCode
.
success
();
this
.
code
=
resultCode
.
code
();
this
.
message
=
resultCode
.
message
();
}
}
src/main/java/com/kwan/shuyu/domain/ResultCode.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.domain
;
public
interface
ResultCode
{
/**
* 操作是否成功,true为成功,false操作失败
*/
boolean
success
();
/**
* 操作代码
*/
int
code
();
/**
* 提示信息
*/
String
message
();
}
src/main/java/com/kwan/shuyu/service/EsCourseServiceImpl.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.service
;
import
com.kwan.shuyu.domain.*
;
import
com.kwan.shuyu.service.impl.EsCourseService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.elasticsearch.action.search.SearchRequest
;
import
org.elasticsearch.action.search.SearchResponse
;
import
org.elasticsearch.client.RequestOptions
;
import
org.elasticsearch.client.RestHighLevelClient
;
import
org.elasticsearch.common.text.Text
;
import
org.elasticsearch.index.query.BoolQueryBuilder
;
import
org.elasticsearch.index.query.MultiMatchQueryBuilder
;
import
org.elasticsearch.index.query.QueryBuilders
;
import
org.elasticsearch.search.SearchHit
;
import
org.elasticsearch.search.SearchHits
;
import
org.elasticsearch.search.builder.SearchSourceBuilder
;
import
org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder
;
import
org.elasticsearch.search.fetch.subphase.highlight.HighlightField
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
@Service
public
class
EsCourseServiceImpl
implements
EsCourseService
{
@Value
(
"${kwan.course.source_field}"
)
private
String
source_field
;
@Autowired
private
RestHighLevelClient
restHighLevelClient
;
/**
* 课程搜索
*
* @param page
* @param size
* @param courseSearchParam
* @return
*/
@Override
public
QueryResponseResult
<
CoursePub
>
list
(
int
page
,
int
size
,
CourseSearchParam
courseSearchParam
)
{
if
(
courseSearchParam
==
null
)
{
courseSearchParam
=
new
CourseSearchParam
();
}
//1创建搜索请求对象
SearchRequest
searchRequest
=
new
SearchRequest
(
"xc_course"
);
SearchSourceBuilder
searchSourceBuilder
=
new
SearchSourceBuilder
();
//过虑源字段
String
[]
source_field_array
=
source_field
.
split
(
","
);
searchSourceBuilder
.
fetchSource
(
source_field_array
,
new
String
[]{});
//创建布尔查询对象
BoolQueryBuilder
boolQueryBuilder
=
QueryBuilders
.
boolQuery
();
//搜索条件
//根据关键字搜索
if
(
StringUtils
.
isNotEmpty
(
courseSearchParam
.
getKeyword
()))
{
MultiMatchQueryBuilder
multiMatchQueryBuilder
=
QueryBuilders
.
multiMatchQuery
(
courseSearchParam
.
getKeyword
(),
"name"
,
"description"
,
"teachplan"
)
.
minimumShouldMatch
(
"70%"
)
.
field
(
"name"
,
10
);
boolQueryBuilder
.
must
(
multiMatchQueryBuilder
);
}
if
(
StringUtils
.
isNotEmpty
(
courseSearchParam
.
getMt
()))
{
//根据一级分类
boolQueryBuilder
.
filter
(
QueryBuilders
.
termQuery
(
"mt"
,
courseSearchParam
.
getMt
()));
}
if
(
StringUtils
.
isNotEmpty
(
courseSearchParam
.
getSt
()))
{
//根据二级分类
boolQueryBuilder
.
filter
(
QueryBuilders
.
termQuery
(
"st"
,
courseSearchParam
.
getSt
()));
}
if
(
StringUtils
.
isNotEmpty
(
courseSearchParam
.
getGrade
()))
{
//根据难度等级
boolQueryBuilder
.
filter
(
QueryBuilders
.
termQuery
(
"grade"
,
courseSearchParam
.
getGrade
()));
}
//设置boolQueryBuilder到searchSourceBuilder
searchSourceBuilder
.
query
(
boolQueryBuilder
);
//设置分页参数
if
(
page
<=
0
)
{
page
=
1
;
}
if
(
size
<=
0
)
{
size
=
12
;
}
//起始记录下标
int
from
=
(
page
-
1
)
*
size
;
searchSourceBuilder
.
from
(
from
);
searchSourceBuilder
.
size
(
size
);
//设置高亮
HighlightBuilder
highlightBuilder
=
new
HighlightBuilder
();
highlightBuilder
.
preTags
(
"<font class='eslight'>"
);
highlightBuilder
.
postTags
(
"</font>"
);
//设置高亮字段
highlightBuilder
.
fields
().
add
(
new
HighlightBuilder
.
Field
(
"name"
));
searchSourceBuilder
.
highlighter
(
highlightBuilder
);
searchRequest
.
source
(
searchSourceBuilder
);
QueryResult
<
CoursePub
>
queryResult
=
new
QueryResult
();
List
<
CoursePub
>
list
=
new
ArrayList
<>();
try
{
//2执行搜索
SearchResponse
searchResponse
=
restHighLevelClient
.
search
(
searchRequest
,
RequestOptions
.
DEFAULT
);
//3获取响应结果
SearchHits
hits
=
searchResponse
.
getHits
();
long
totalHits
=
hits
.
getTotalHits
().
value
;
//匹配的总记录数
queryResult
.
setTotal
(
totalHits
);
SearchHit
[]
searchHits
=
hits
.
getHits
();
for
(
SearchHit
hit
:
searchHits
)
{
CoursePub
coursePub
=
new
CoursePub
();
//源文档
Map
<
String
,
Object
>
sourceAsMap
=
hit
.
getSourceAsMap
();
//取出id
String
id
=
(
String
)
sourceAsMap
.
get
(
"id"
);
coursePub
.
setId
(
id
);
//取出name
String
name
=
(
String
)
sourceAsMap
.
get
(
"name"
);
//取出高亮字段name
Map
<
String
,
HighlightField
>
highlightFields
=
hit
.
getHighlightFields
();
if
(
highlightFields
!=
null
)
{
HighlightField
highlightFieldName
=
highlightFields
.
get
(
"name"
);
if
(
highlightFieldName
!=
null
)
{
Text
[]
fragments
=
highlightFieldName
.
fragments
();
StringBuffer
stringBuffer
=
new
StringBuffer
();
for
(
Text
text
:
fragments
)
{
stringBuffer
.
append
(
text
);
}
name
=
stringBuffer
.
toString
();
}
}
coursePub
.
setName
(
name
);
//图片
String
pic
=
(
String
)
sourceAsMap
.
get
(
"pic"
);
coursePub
.
setPic
(
pic
);
//价格
Double
price
=
null
;
try
{
if
(
sourceAsMap
.
get
(
"price"
)
!=
null
)
{
price
=
(
Double
)
sourceAsMap
.
get
(
"price"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
coursePub
.
setPrice
(
price
);
//旧价格
Double
price_old
=
null
;
try
{
if
(
sourceAsMap
.
get
(
"price_old"
)
!=
null
)
{
price_old
=
(
Double
)
sourceAsMap
.
get
(
"price_old"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
coursePub
.
setPrice_old
(
price_old
);
//将coursePub对象放入list
list
.
add
(
coursePub
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
queryResult
.
setList
(
list
);
QueryResponseResult
<
CoursePub
>
queryResponseResult
=
new
QueryResponseResult
<>(
CommonCode
.
SUCCESS
,
queryResult
);
return
queryResponseResult
;
}
}
\ No newline at end of file
src/main/java/com/kwan/shuyu/service/impl/EsCourseService.java
0 → 100644
浏览文件 @
dd43ec00
package
com.kwan.shuyu.service.impl
;
import
com.kwan.shuyu.domain.CoursePub
;
import
com.kwan.shuyu.domain.CourseSearchParam
;
import
com.kwan.shuyu.domain.QueryResponseResult
;
public
interface
EsCourseService
{
/**
* 查询课程
*
* @param page
* @param size
* @param courseSearchParam
* @return
*/
QueryResponseResult
<
CoursePub
>
list
(
int
page
,
int
size
,
CourseSearchParam
courseSearchParam
);
}
\ No newline at end of file
src/main/resources/application.yml
浏览文件 @
dd43ec00
...
...
@@ -7,3 +7,5 @@ spring:
kwan
:
elasticsearch
:
hostlist
:
47.119.160.231:9200
#多个节点用逗号分隔
course
:
#课程字段
source_field
:
id,name,grade,mt,st,charge,valid,pic,qq,price,price_old,status,studymodel,teachmode,expires,pub_time,start_time,end_time
\ No newline at end of file
src/main/resources/logback-spring.xml
浏览文件 @
dd43ec00
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--定义日志文件的存储地址,使用绝对路径-->
<property
name=
"LOG_HOME"
value=
"/Users/qinyingjie/Downloads/"
/>
<!-- Console 输出设置 -->
<appender
name=
"CONSOLE"
class=
"ch.qos.logback.core.ConsoleAppender"
>
<encoder>
...
...
@@ -12,7 +10,6 @@
<charset>
utf8
</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender
name=
"FILE"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
...
...
@@ -23,7 +20,6 @@
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<!-- 异步输出 -->
<appender
name=
"ASYNC"
class=
"ch.qos.logback.classic.AsyncAppender"
>
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
...
...
@@ -33,8 +29,6 @@
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref
ref=
"FILE"
/>
</appender>
<logger
name=
"org.apache.ibatis.cache.decorators.LoggingCache"
level=
"DEBUG"
additivity=
"false"
>
<appender-ref
ref=
"CONSOLE"
/>
</logger>
...
...
src/test/java/es_06_log/TestLog.java
0 → 100644
浏览文件 @
dd43ec00
package
es_06_log
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
java.util.Random
;
/**
* 测试ELK查看log
*
* @author : qinyingjie
* @version : 2.2.0
* @date : 2023/5/13 22:14
*/
@SpringBootTest
@RunWith
(
SpringRunner
.
class
)
public
class
TestLog
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
TestLog
.
class
);
@Test
public
void
testLog
()
{
Random
random
=
new
Random
();
while
(
true
)
{
int
userid
=
random
.
nextInt
(
10
);
LOGGER
.
info
(
"userId:{},send:{}"
,
userid
,
"hello world.I am "
+
userid
);
try
{
Thread
.
sleep
(
500
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录