Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pic-reader
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
龙菲
pic-reader
Commits
79d95f31
提交
79d95f31
authored
6月 19, 2025
作者:
龙菲
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加pc端的抽屉
上级
016d0c67
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
176 行增加
和
42 行删除
+176
-42
components.d.ts
src/components.d.ts
+8
-2
index.vue
src/components/BookReader/index.vue
+69
-34
bookMarks.vue
src/components/GuideMobile/bookMarks.vue
+0
-0
index.vue
src/components/GuideMobile/index.vue
+9
-3
bookMarks.vue
src/components/GuidePc/bookMarks.vue
+30
-0
index.vue
src/components/GuidePc/index.vue
+50
-0
index.vue
src/views/detail/index.vue
+4
-2
vite.config.js
vite.config.js
+6
-1
没有找到文件。
src/components.d.ts
浏览文件 @
79d95f31
...
@@ -8,14 +8,17 @@ export {}
...
@@ -8,14 +8,17 @@ export {}
/* prettier-ignore */
/* prettier-ignore */
declare
module
'vue'
{
declare
module
'vue'
{
export
interface
GlobalComponents
{
export
interface
GlobalComponents
{
BookMarks
:
typeof
import
(
'./components/
B
ookMarks.vue'
)[
'default'
]
BookMarks
:
typeof
import
(
'./components/
GuideMobile/b
ookMarks.vue'
)[
'default'
]
BookReader
:
typeof
import
(
'./components/BookReader/index.vue'
)[
'default'
]
BookReader
:
typeof
import
(
'./components/BookReader/index.vue'
)[
'default'
]
ElButton
:
typeof
import
(
'element-plus/es'
)[
'ElButton'
]
ElButton
:
typeof
import
(
'element-plus/es'
)[
'ElButton'
]
ElCol
:
typeof
import
(
'element-plus/es'
)[
'ElCol'
]
ElCol
:
typeof
import
(
'element-plus/es'
)[
'ElCol'
]
ElDrawer
:
typeof
import
(
'element-plus/es'
)[
'ElDrawer'
]
ElHeader
:
typeof
import
(
'element-plus/es'
)[
'ElHeader'
]
ElHeader
:
typeof
import
(
'element-plus/es'
)[
'ElHeader'
]
ElRow
:
typeof
import
(
'element-plus/es'
)[
'ElRow'
]
ElRow
:
typeof
import
(
'element-plus/es'
)[
'ElRow'
]
FileUpload
:
typeof
import
(
'./components/FileUpload.vue'
)[
'default'
]
FileUpload
:
typeof
import
(
'./components/FileUpload.vue'
)[
'default'
]
Guide
:
typeof
import
(
'./components/BookReader/guide.vue'
)[
'default'
]
Guide
:
typeof
import
(
'./components/GuideMobile/guide.vue'
)[
'default'
]
GuideMobile
:
typeof
import
(
'./components/GuideMobile/index.vue'
)[
'default'
]
GuidePc
:
typeof
import
(
'./components/GuidePc/index.vue'
)[
'default'
]
IconCommunity
:
typeof
import
(
'./components/icons/IconCommunity.vue'
)[
'default'
]
IconCommunity
:
typeof
import
(
'./components/icons/IconCommunity.vue'
)[
'default'
]
IconDocumentation
:
typeof
import
(
'./components/icons/IconDocumentation.vue'
)[
'default'
]
IconDocumentation
:
typeof
import
(
'./components/icons/IconDocumentation.vue'
)[
'default'
]
IconEcosystem
:
typeof
import
(
'./components/icons/IconEcosystem.vue'
)[
'default'
]
IconEcosystem
:
typeof
import
(
'./components/icons/IconEcosystem.vue'
)[
'default'
]
...
@@ -29,4 +32,7 @@ declare module 'vue' {
...
@@ -29,4 +32,7 @@ declare module 'vue' {
VanNavBar
:
typeof
import
(
'vant/es'
)[
'NavBar'
]
VanNavBar
:
typeof
import
(
'vant/es'
)[
'NavBar'
]
VanPopup
:
typeof
import
(
'vant/es'
)[
'Popup'
]
VanPopup
:
typeof
import
(
'vant/es'
)[
'Popup'
]
}
}
export
interface
GlobalDirectives
{
vLoading
:
typeof
import
(
'element-plus/es'
)[
'ElLoadingDirective'
]
}
}
}
src/components/BookReader/index.vue
浏览文件 @
79d95f31
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
class=
"book-reader"
class=
"book-reader"
@
touchstart=
"handleTouchStart"
@
touchstart=
"handleTouchStart"
@
touchend=
"handleTouchEnd"
@
touchend=
"handleTouchEnd"
v-loading=
"loading"
>
>
<div
class=
"magazine-viewport"
>
<div
class=
"magazine-viewport"
>
<div
ref=
"magazine"
class=
"magazine"
>
<div
ref=
"magazine"
class=
"magazine"
>
...
@@ -69,7 +70,16 @@
...
@@ -69,7 +70,16 @@
<!--
<div
class=
"mobile-gesture-hint"
v-if=
"isMobile"
>
左右滑动切换页面
</div>
-->
<!--
<div
class=
"mobile-gesture-hint"
v-if=
"isMobile"
>
左右滑动切换页面
</div>
-->
<!-- Replace directory modal with Element Plus dialog -->
<!-- Replace directory modal with Element Plus dialog -->
<Guide
ref=
"guideRef"
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
></Guide>
<GuideMobile
ref=
"guideMobileRef"
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
></GuideMobile>
<GuidePc
ref=
"guidePcRef"
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
></GuidePc>
</div>
</div>
<div
class=
"footer"
>
<div
class=
"footer"
>
<el-row
:gutter=
"10"
class=
"tab-bar"
>
<el-row
:gutter=
"10"
class=
"tab-bar"
>
...
@@ -91,7 +101,7 @@
...
@@ -91,7 +101,7 @@
<svg-icon
name=
"to-left"
size=
"22"
@
click=
"previous"
></svg-icon>
<svg-icon
name=
"to-left"
size=
"22"
@
click=
"previous"
></svg-icon>
<div
class=
"page-count"
>
第
{{
currentPage
}}
页
</div>
<div
class=
"page-count"
>
第
{{
currentPage
}}
页
</div>
<svg-icon
name=
"to-right"
size=
"22"
@
click=
"next"
></svg-icon>
<svg-icon
name=
"to-right"
size=
"22"
@
click=
"next"
></svg-icon>
<svg-icon
name=
"to-end"
size=
"30"
@
clic
l
=
"toEnd"
></svg-icon>
<svg-icon
name=
"to-end"
size=
"30"
@
clic
k
=
"toEnd"
></svg-icon>
</el-col>
</el-col>
<el-col
class=
"right"
:span=
"8"
>
<el-col
class=
"right"
:span=
"8"
>
<!--
<svg-icon
name=
"download"
size=
"20"
></svg-icon>
-->
<!--
<svg-icon
name=
"download"
size=
"20"
></svg-icon>
-->
...
@@ -107,8 +117,7 @@ import "turn.js";
...
@@ -107,8 +117,7 @@ import "turn.js";
// import * as 'turn' from '/public/js/turn'
// import * as 'turn' from '/public/js/turn'
import
{
ref
,
onMounted
,
onUnmounted
,
watch
,
nextTick
,
computed
}
from
"vue"
;
import
{
ref
,
onMounted
,
onUnmounted
,
watch
,
nextTick
,
computed
}
from
"vue"
;
import
VueEasyLightbox
from
"vue-easy-lightbox"
;
import
VueEasyLightbox
from
"vue-easy-lightbox"
;
import
Guide
from
"./guide.vue"
;
import
GuideMobile
from
"../GuideMobile/index.vue"
;
import
{
showImagePreview
}
from
"vant"
;
import
audioFlip
from
"@/assets/audio/flip.mp3"
;
import
audioFlip
from
"@/assets/audio/flip.mp3"
;
const
props
=
defineProps
({
const
props
=
defineProps
({
pages
:
{
pages
:
{
...
@@ -148,7 +157,8 @@ const processedPages = ref([]);
...
@@ -148,7 +157,8 @@ const processedPages = ref([]);
const
pageTurnSound
=
ref
(
null
);
const
pageTurnSound
=
ref
(
null
);
const
audioInitialized
=
ref
(
false
);
const
audioInitialized
=
ref
(
false
);
const
directoryImages
=
ref
([]);
const
directoryImages
=
ref
([]);
const
guideRef
=
ref
(
null
);
const
guideMobileRef
=
ref
(
null
);
const
guidePcRef
=
ref
(
null
);
const
currentPage
=
ref
(
0
);
const
currentPage
=
ref
(
0
);
const
isMuted
=
ref
(
false
);
// 默认不静音
const
isMuted
=
ref
(
false
);
// 默认不静音
...
@@ -198,7 +208,6 @@ const processPages = (pages) => {
...
@@ -198,7 +208,6 @@ const processPages = (pages) => {
}));
}));
};
};
// 修改图片加载函数
const
loadImage
=
async
(
pageIndex
)
=>
{
const
loadImage
=
async
(
pageIndex
)
=>
{
const
page
=
processedPages
.
value
[
pageIndex
];
const
page
=
processedPages
.
value
[
pageIndex
];
if
(
!
page
||
page
.
isLoaded
)
return
true
;
if
(
!
page
||
page
.
isLoaded
)
return
true
;
...
@@ -224,7 +233,8 @@ const loadImage = async (pageIndex) => {
...
@@ -224,7 +233,8 @@ const loadImage = async (pageIndex) => {
try
{
try
{
const
img
=
new
Image
();
const
img
=
new
Image
();
await
new
Promise
((
resolve
,
reject
)
=>
{
await
Promise
.
race
([
new
Promise
((
resolve
,
reject
)
=>
{
img
.
onload
=
()
=>
{
img
.
onload
=
()
=>
{
clearTimeout
(
timeoutId
);
clearTimeout
(
timeoutId
);
loadingTimeouts
.
value
.
delete
(
pageIndex
);
loadingTimeouts
.
value
.
delete
(
pageIndex
);
...
@@ -239,9 +249,19 @@ const loadImage = async (pageIndex) => {
...
@@ -239,9 +249,19 @@ const loadImage = async (pageIndex) => {
reject
(
new
Error
(
"Image load failed"
));
reject
(
new
Error
(
"Image load failed"
));
};
};
img
.
src
=
src
;
img
.
src
=
src
;
});
}),
new
Promise
((
_
,
reject
)
=>
setTimeout
(()
=>
reject
(
new
Error
(
"Timeout"
)),
3000
)
),
]);
return
true
;
return
true
;
}
catch
(
error
)
{
}
catch
(
error
)
{
// 如果加载失败,直接显示占位图
const
$img
=
$
(
magazine
.
value
).
find
(
`.p
${
pageIndex
+
1
}
img`
);
if
(
$img
.
length
)
{
$img
[
0
].
src
=
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iI2YwZjBmMCIvPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IiM5OTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGR5PSIuM2VtIj7lvIDlp4vmlbDmja7lupM8L3RleHQ+PC9zdmc+"
;
}
return
false
;
return
false
;
}
finally
{
}
finally
{
loadingQueue
.
value
.
delete
(
pageIndex
);
loadingQueue
.
value
.
delete
(
pageIndex
);
...
@@ -255,9 +275,9 @@ const loadVisiblePages = async (currentPage) => {
...
@@ -255,9 +275,9 @@ const loadVisiblePages = async (currentPage) => {
const
$magazine
=
$
(
magazine
.
value
);
const
$magazine
=
$
(
magazine
.
value
);
const
totalPages
=
$magazine
.
turn
(
"pages"
);
const
totalPages
=
$magazine
.
turn
(
"pages"
);
//
只加载当前页和下一
页
//
加载当前页、上一页、下一页和下下
页
const
startPage
=
currentPage
;
const
startPage
=
Math
.
max
(
1
,
currentPage
-
1
)
;
const
endPage
=
Math
.
min
(
totalPages
,
currentPage
+
1
);
const
endPage
=
Math
.
min
(
totalPages
,
currentPage
+
2
);
const
loadTasks
=
[];
const
loadTasks
=
[];
for
(
let
i
=
startPage
;
i
<=
endPage
;
i
++
)
{
for
(
let
i
=
startPage
;
i
<=
endPage
;
i
++
)
{
...
@@ -272,9 +292,12 @@ const loadVisiblePages = async (currentPage) => {
...
@@ -272,9 +292,12 @@ const loadVisiblePages = async (currentPage) => {
}
}
try
{
try
{
loading
.
value
=
true
;
await
Promise
.
all
(
loadTasks
);
await
Promise
.
all
(
loadTasks
);
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"加载页面失败:"
,
error
);
console
.
error
(
"加载页面失败:"
,
error
);
}
finally
{
loading
.
value
=
false
;
}
}
};
};
...
@@ -356,6 +379,11 @@ const initBook = async () => {
...
@@ -356,6 +379,11 @@ const initBook = async () => {
turning
:
async
(
event
,
page
)
=>
{
turning
:
async
(
event
,
page
)
=>
{
loading
.
value
=
true
;
loading
.
value
=
true
;
await
loadVisiblePages
(
page
);
await
loadVisiblePages
(
page
);
// 确保加载完成后才继续翻页
setTimeout
(()
=>
{
event
.
preventDefault
();
$magazine
.
turn
(
"page"
,
page
);
},
100
);
},
},
turned
:
async
(
event
,
page
)
=>
{
turned
:
async
(
event
,
page
)
=>
{
currentPage
.
value
=
page
;
// 更新当前页码
currentPage
.
value
=
page
;
// 更新当前页码
...
@@ -375,13 +403,13 @@ const initBook = async () => {
...
@@ -375,13 +403,13 @@ const initBook = async () => {
};
};
// 修改加载图片函数
// 修改加载图片函数
const
loadImages
=
async
()
=>
{
const
loadImages
=
async
()
=>
{
loading
.
value
=
true
;
//
loading.value = true;
try
{
try
{
await
initBook
();
await
initBook
();
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"加载图片失败:"
,
error
);
console
.
error
(
"加载图片失败:"
,
error
);
}
finally
{
}
finally
{
loading
.
value
=
false
;
//
loading.value = false;
}
}
};
};
...
@@ -478,13 +506,13 @@ const previous = () => {
...
@@ -478,13 +506,13 @@ const previous = () => {
};
};
const
toFirst
=
()
=>
{
const
toFirst
=
()
=>
{
const
firstPage
=
props
.
pages
[
0
].
page
;
const
firstPage
=
props
.
pages
[
0
].
page
_num
;
$magazine
.
turn
(
"page"
,
firstPage
);
goToPage
(
firstPage
);
};
};
const
toEnd
=
()
=>
{
const
toEnd
=
()
=>
{
const
endPage
=
props
.
pages
[
props
.
pages
.
length
-
1
].
page
;
const
endPage
=
props
.
pages
[
props
.
pages
.
length
-
1
].
page
_num
;
$magazine
.
turn
(
"page"
,
endPage
);
goToPage
(
endPage
);
};
};
const
zoomIn
=
()
=>
{
const
zoomIn
=
()
=>
{
...
@@ -772,7 +800,11 @@ const goToPage = (pageNum) => {
...
@@ -772,7 +800,11 @@ const goToPage = (pageNum) => {
};
};
const
showGuide
=
()
=>
{
const
showGuide
=
()
=>
{
guideRef
.
value
.
show
();
if
(
isMobile
.
value
)
{
guideMobileRef
.
value
.
show
();
}
else
{
guidePcRef
.
value
.
show
();
}
};
};
</
script
>
</
script
>
...
@@ -843,22 +875,22 @@ const showGuide = () => {
...
@@ -843,22 +875,22 @@ const showGuide = () => {
transform-style
:
preserve-3d
;
transform-style
:
preserve-3d
;
}
}
.
magazine
:
:
after
{
//
.magazine::after {
content
:
""
;
//
content: "";
position
:
absolute
;
//
position: absolute;
top
:
0
;
//
top: 0;
left
:
50%
;
//
left: 50%;
width
:
1px
;
//
width: 1px;
height
:
100%
;
//
height: 100%;
background
:
linear-gradient
(
//
background: linear-gradient(
to
bottom
,
//
to bottom,
rgba
(
0
,
0
,
0
,
0
.1
)
0%
,
//
rgba(0, 0, 0, 0.1) 0%,
rgba
(
0
,
0
,
0
,
0
.2
)
50%
,
//
rgba(0, 0, 0, 0.2) 50%,
rgba
(
0
,
0
,
0
,
0
.1
)
100%
//
rgba(0, 0, 0, 0.1) 100%
);
//
);
z-index
:
10
;
//
z-index: 10;
pointer-events
:
none
;
//
pointer-events: none;
}
//
}
.page
{
.page
{
background-color
:
white
;
background-color
:
white
;
...
@@ -1034,6 +1066,9 @@ const showGuide = () => {
...
@@ -1034,6 +1066,9 @@ const showGuide = () => {
color
:
#ccc
;
color
:
#ccc
;
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
.svg-icon
{
cursor
:
pointer
;
}
.left
,
.left
,
.right
,
.right
,
.center
{
.center
{
...
...
src/components/
B
ookMarks.vue
→
src/components/
GuideMobile/b
ookMarks.vue
浏览文件 @
79d95f31
File moved
src/components/
BookReader/guide
.vue
→
src/components/
GuideMobile/index
.vue
浏览文件 @
79d95f31
<
template
>
<
template
>
<!-- 圆角弹窗(底部) -->
<!-- 圆角弹窗(底部) -->
<van-popup
v-model:show=
"showDirectory"
round
position=
"bottom"
:style=
"
{ height: '80%' }">
<van-popup
<van-nav-bar
title=
"目录"
/>
v-model:show=
"showDirectory"
round
position=
"bottom"
:style=
"
{ height: '80%' }"
>
<van-nav-bar
title=
"目录"
/>
<van-list
:finished=
"true"
finished-text=
"没有更多了"
>
<van-list
:finished=
"true"
finished-text=
"没有更多了"
>
<BookMarks
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
/>
<BookMarks
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
/>
</van-list>
</van-list>
</van-popup>
</van-popup>
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
BookMarks
from
"./bookMarks.vue"
;
const
$emit
=
defineEmits
([
"goToPage"
]);
const
$emit
=
defineEmits
([
"goToPage"
]);
const
props
=
defineProps
({
const
props
=
defineProps
({
bookmarks
:
{
bookmarks
:
{
...
...
src/components/GuidePc/bookMarks.vue
0 → 100644
浏览文件 @
79d95f31
<
template
>
<template
v-for=
"item in bookmarks"
:key=
"item"
>
<van-cell
:title=
"item.title"
:style=
"
{ paddingLeft: `${level * 20 + 30}px` }"
@click.prevent="clickCell(item.page)"
/>
<template
v-if=
"item.children"
>
<BookMarks
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
/>
</
template
>
</template>
</template>
<
script
setup
name=
"BookMarksPc"
>
const
$emit
=
defineEmits
([
"goToPage"
]);
const
props
=
defineProps
({
bookmarks
:
{
type
:
Array
,
default
:
()
=>
[],
},
level
:
{
type
:
Number
,
default
:
0
,
// 默认层级是 0(第一层)
},
});
const
clickCell
=
(
page
)
=>
{
$emit
(
"goToPage"
,
page
);
};
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
src/components/GuidePc/index.vue
0 → 100644
浏览文件 @
79d95f31
<
template
>
<el-drawer
title=
"目录"
v-model=
"visible"
direction=
"ltr"
size=
"30%"
:before-close=
"close"
:destroy-on-close=
"true"
:show-close=
"true"
:wrapperClosable=
"true"
>
<BookMarks
:bookmarks=
"bookmarks"
@
goToPage=
"goToPage"
/>
</el-drawer>
</
template
>
<
script
lang=
"ts"
setup
>
/* props */
const
props
=
defineProps
({
bookmarks
:
{
type
:
Array
,
default
:
()
=>
[],
},
currentPage
:
{
type
:
Number
,
default
:
0
,
},
});
/* emit */
const
$emit
=
defineEmits
([
"goToPage"
]);
/* data */
const
visible
=
ref
(
false
);
/* computed */
/* methods */
function
close
()
{
visible
.
value
=
false
;
}
function
goToPage
(
pageNum
)
{
$emit
(
"goToPage"
,
pageNum
);
close
();
}
function
show
()
{
visible
.
value
=
true
;
}
defineExpose
({
show
,
});
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
src/views/detail/index.vue
浏览文件 @
79d95f31
<
template
>
<
template
>
<div>
<div>
<div
class=
"header"
>
<div
class=
"header"
>
<el-button
type=
"primary"
link
class=
"back"
>
返回
</el-button>
<el-button
type=
"primary"
link
class=
"back"
@
click=
"goBack"
>
返回
</el-button
>
微方志
微方志
</div>
</div>
<BookReader
:pages=
"pages"
:bookmarks=
"bookmarks"
/>
<BookReader
:pages=
"pages"
:bookmarks=
"bookmarks"
/>
...
@@ -36,7 +38,7 @@ async function loadData(id) {
...
@@ -36,7 +38,7 @@ async function loadData(id) {
});
});
}
}
function
onClickLeft
()
{
function
goBack
()
{
router
.
go
(
-
1
);
router
.
go
(
-
1
);
}
}
onMounted
(()
=>
{
onMounted
(()
=>
{
...
...
vite.config.js
浏览文件 @
79d95f31
...
@@ -61,7 +61,12 @@ export default defineConfig(({ mode, command }) => {
...
@@ -61,7 +61,12 @@ export default defineConfig(({ mode, command }) => {
'/api'
:
{
'/api'
:
{
target
:
'http://222.85.214.245:9666'
,
target
:
'http://222.85.214.245:9666'
,
changeOrigin
:
true
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api/
,
''
)
rewrite
:
(
path
)
=>
path
.
replace
(
new
RegExp
(
'^'
+
env
.
VITE_API_BASE_URL
),
'/api'
),
bypass
(
req
,
res
,
options
)
{
const
realUrl
=
options
.
target
+
(
options
.
rewrite
?
options
.
rewrite
(
req
.
url
)
:
''
);
console
.
log
(
realUrl
);
// 在终端显示
res
.
setHeader
(
'A-Real-Url'
,
realUrl
);
// 添加响应标头(A-Real-Url为自定义命名),在浏览器中显示
},
}
}
},
},
host
:
'0.0.0.0'
,
host
:
'0.0.0.0'
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论