Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
0d8417a5
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
6067
Star
93
Fork
166
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
19
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
19
Issue
19
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
0d8417a5
编写于
4月 15, 2024
作者:
WOSHIMAHAIFENG
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev_file' into 'dev'
补充测试file用例 See merge request
!11
上级
e3331e17
e9ed3187
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
167 addition
and
73 deletion
+167
-73
pages/API/get-file-system-manager/get-file-system-manager.test.js
...I/get-file-system-manager/get-file-system-manager.test.js
+61
-1
pages/API/get-file-system-manager/get-file-system-manager.uvue
.../API/get-file-system-manager/get-file-system-manager.uvue
+106
-72
未找到文件。
pages/API/get-file-system-manager/get-file-system-manager.test.js
浏览文件 @
0d8417a5
...
...
@@ -936,8 +936,13 @@ describe('ExtApi-FileManagerTest', () => {
expect
(
JSON
.
stringify
(
fileListSuccess
)).
toEqual
(
'
[]
'
)
});
it
(
'
appendFileTest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
await
page
.
setData
({
recursiveVal
:
true
,
logAble
:
false
,
...
...
@@ -989,6 +994,11 @@ describe('ExtApi-FileManagerTest', () => {
//renameFileSync copyFileSyncTest appendFileSyncTest truncateFileTest truncateFileSyncTest
it
(
'
sync test
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
await
page
.
setData
({
recursiveVal
:
false
,
logAble
:
false
,
...
...
@@ -1123,9 +1133,30 @@ describe('ExtApi-FileManagerTest', () => {
await
btnClear
.
tap
()
await
isDone
()
}
function
isAndroid
()
{
if
(
process
.
env
.
uniTestPlatformInfo
.
indexOf
(
'
web
'
)
>
-
1
||
process
.
env
.
UNI_AUTOMATOR_APP_WEBVIEW
===
'
true
'
)
{
it
(
'
web
'
,
()
=>
{
expect
(
1
).
toBe
(
1
)
})
return
false
}
if
(
process
.
env
.
uniTestPlatformInfo
.
toLocaleLowerCase
().
startsWith
(
'
ios
'
))
{
it
(
'
ios
'
,
()
=>
{
expect
(
1
).
toBe
(
1
)
})
return
false
}
return
true
}
//saveFileTest saveFileSyncTest getSavedFileListTest removeSavedFileTest
it
(
'
savefile test
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
let
globalTempPath
=
await
getData
(
'
globalTempPath
'
)
let
basePath
=
await
getData
(
'
basePath
'
)
await
page
.
setData
({
...
...
@@ -1161,6 +1192,11 @@ describe('ExtApi-FileManagerTest', () => {
it
(
'
saveFileSyncTest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
let
globalTempPath
=
await
getData
(
'
globalTempPath
'
)
let
basePath
=
await
getData
(
'
basePath
'
)
await
page
.
setData
({
...
...
@@ -1206,6 +1242,11 @@ describe('ExtApi-FileManagerTest', () => {
it
(
'
getSavedFileListTest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
let
globalTempPath
=
await
getData
(
'
globalTempPath
'
)
let
basePath
=
await
getData
(
'
basePath
'
)
await
page
.
setData
({
...
...
@@ -1241,6 +1282,11 @@ describe('ExtApi-FileManagerTest', () => {
it
(
'
removeSavedFileTest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
let
globalTempPath
=
await
getData
(
'
globalTempPath
'
)
let
basePath
=
await
getData
(
'
basePath
'
)
await
page
.
setData
({
...
...
@@ -1272,6 +1318,11 @@ describe('ExtApi-FileManagerTest', () => {
//openFiletest openFileSynctest closeTest closeTestSync writeTest writeSyncTest
it
(
'
openFiletest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
await
clearDir
(
''
)
await
page
.
setData
({
mkdirFile
:
'
fd
'
,
...
...
@@ -1298,6 +1349,11 @@ describe('ExtApi-FileManagerTest', () => {
});
// closeTest closeTestSync
it
(
'
closeTest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
await
clearDir
(
''
)
await
page
.
setData
({
mkdirFile
:
'
fd
'
,
...
...
@@ -1324,6 +1380,10 @@ describe('ExtApi-FileManagerTest', () => {
});
//writeTest writeSyncTest
it
(
'
writeTest
'
,
async
()
=>
{
if
(
!
isAndroid
()){
return
}
await
clearDir
(
''
)
await
page
.
setData
({
mkdirFile
:
'
fd
'
,
...
...
pages/API/get-file-system-manager/get-file-system-manager.uvue
浏览文件 @
0d8417a5
<template>
<!-- #ifdef APP -->
<text>显示简易操作日志,详细日志需真机运行查看</text><button size="mini" @click="log=''">清空日志</button>
<text style="margin: 2px; padding: 2px; border: 1px solid #000000;">{{ log }}</text>
<scroll-view style="flex: 1;">
<!-- #endif -->
<text>显示简易操作日志,详细日志需真机运行查看</text><button size="mini" @click="log=''">清空日志</button>
<text style="margin: 2px; padding: 2px; border: 1px solid #000000;">{{ log }}</text>
<button type="primary" @tap="statFileInfoTest" id="btn-stat-file">递归获取目录files的Stats对象{{statFile}}</button>
<button type="primary" @tap="mkdirTest" id="btn-mkdir">创建文件夹{{mkdirFile}}</button>
<button type="primary" @tap="writeFileTest" id="btn-write-file">覆盖写入文件{{writeFile}}</button>
<button type="primary" @tap="readDirTest" id="btn-read-dir">读取文件夹{{readDir}}</button>
<button type="primary" @tap="readFileTest" id="btn-read-file">读取文件{{readFile}}</button>
<button type="primary" @tap="copyFileTest" id="btn-copy-file">复制文件{{copyFromFile}}到{{copyToFile}}</button>
<button type="primary" @tap="renameFileTest" id="btn-rename-file">重命名文件{{renameFromFile}}到{{renameToFile}}</button>
<button type="primary" @tap="accessFileTest" id="btn-access-file">判断文件{{accessFile}}是否存在</button>
<button type="primary" @tap="getFileInfoTest" id="btn-get-file-info">获取文件信息{{getFileInfoFile}}</button>
<button type="primary" @tap="unlinkTest" id="btn-unlink-file">删除文件{{unlinkFile}}</button>
<button type="primary" @tap="copyStaticToFilesTest" id="btn-copyStatic-file">从static目录复制文件到a目录</button>
<button type="primary" @tap="unlinkAllFileTest" id="btn-clear-file">删除文件夹{{rmDirFile}}下的所有文件</button>
<button type="primary" @tap="rmdirTest" id="btn-remove-dir">删除文件夹{{rmDirFile}}</button>
<button class="btnstyle" type="primary" @tap="statFileInfoTest" id="btn-stat-file">递归获取目录files的Stats对象{{statFile}}</button>
<button class="btnstyle" type="primary" @tap="mkdirTest" id="btn-mkdir">创建文件夹{{mkdirFile}}</button>
<button class="btnstyle" type="primary" @tap="writeFileTest" id="btn-write-file">覆盖写入文件{{writeFile}}</button>
<button class="btnstyle" type="primary" @tap="readDirTest" id="btn-read-dir">读取文件夹{{readDir}}</button>
<button class="btnstyle" type="primary" @tap="readFileTest" id="btn-read-file">读取文件{{readFile}}</button>
<button class="btnstyle" type="primary" @tap="copyFileTest" id="btn-copy-file">复制文件{{copyFromFile}}到{{copyToFile}}</button>
<button class="btnstyle" type="primary" @tap="renameFileTest" id="btn-rename-file">重命名文件{{renameFromFile}}到{{renameToFile}}</button>
<button class="btnstyle" type="primary" @tap="accessFileTest" id="btn-access-file">判断文件{{accessFile}}是否存在</button>
<button class="btnstyle" type="primary" @tap="getFileInfoTest" id="btn-get-file-info">获取文件信息{{getFileInfoFile}}</button>
<button class="btnstyle" type="primary" @tap="unlinkTest" id="btn-unlink-file">删除文件{{unlinkFile}}</button>
<button class="btnstyle" type="primary" @tap="copyStaticToFilesTest" id="btn-copyStatic-file">从static目录复制文件到a目录</button>
<button class="btnstyle" type="primary" @tap="unlinkAllFileTest" id="btn-clear-file">删除文件夹{{rmDirFile}}下的所有文件</button>
<button class="btnstyle" type="primary" @tap="rmdirTest" id="btn-remove-dir">删除文件夹{{rmDirFile}}</button>
<button type="primary" @tap="statFileInfoSyncTest"
<!-- #ifdef APP-ANDROID -->
<button class="btnstyle" type="primary" @tap="statFileInfoSyncTest"
id="btn-stat-file-sync">同步递归获取目录files的Stats对象{{statFile}}</button>
<button type="primary" @tap="appendFileTest" id="btn-append-file">在文件{{readFile}}结尾追加内容</button>
<button type="primary" @tap="appendFileSyncTest" id="btn-append-file-sync">同步在文件{{readFile}}结尾追加内容</button>
<button type="primary" @tap="writeFileSyncTest" id="btn-write-file-sync">同步覆盖写入文件{{writeFile}}</button>
<button type="primary" @tap="readFileSyncTest" id="btn-read-file-sync">同步读取文件{{readFile}}</button>
<button type="primary" @tap="unlinkSyncTest" id="btn-unlink-file-sync">同步删除文件{{unlinkFile}}</button>
<button type="primary" @tap="mkdirSyncTest" id="btn-mkdir-sync">同步创建文件夹{{mkdirFile}}</button>
<button type="primary" @tap="rmdirSyncTest" id="btn-remove-dir-sync">同步删除文件夹{{rmDirFile}}</button>
<button type="primary" @tap="readDirSyncTest" id="btn-read-dir-sync">同步读取文件夹{{readDir}}</button>
<button type="primary" @tap="accessFileSyncTest" id="btn-access-file-sync">同步判断文件{{accessFile}}是否存在</button>
<button type="primary" @tap="renameFileSync"
<button
class="btnstyle"
type="primary" @tap="appendFileTest" id="btn-append-file">在文件{{readFile}}结尾追加内容</button>
<button
class="btnstyle"
type="primary" @tap="appendFileSyncTest" id="btn-append-file-sync">同步在文件{{readFile}}结尾追加内容</button>
<button
class="btnstyle"
type="primary" @tap="writeFileSyncTest" id="btn-write-file-sync">同步覆盖写入文件{{writeFile}}</button>
<button
class="btnstyle"
type="primary" @tap="readFileSyncTest" id="btn-read-file-sync">同步读取文件{{readFile}}</button>
<button
class="btnstyle"
type="primary" @tap="unlinkSyncTest" id="btn-unlink-file-sync">同步删除文件{{unlinkFile}}</button>
<button
class="btnstyle"
type="primary" @tap="mkdirSyncTest" id="btn-mkdir-sync">同步创建文件夹{{mkdirFile}}</button>
<button
class="btnstyle"
type="primary" @tap="rmdirSyncTest" id="btn-remove-dir-sync">同步删除文件夹{{rmDirFile}}</button>
<button
class="btnstyle"
type="primary" @tap="readDirSyncTest" id="btn-read-dir-sync">同步读取文件夹{{readDir}}</button>
<button
class="btnstyle"
type="primary" @tap="accessFileSyncTest" id="btn-access-file-sync">同步判断文件{{accessFile}}是否存在</button>
<button
class="btnstyle"
type="primary" @tap="renameFileSync"
id="btn-rename-file-sync">同步重命名文件{{renameFromFile}}到{{renameToFile}}</button>
<button type="primary" @tap="copyFileSyncTest"
<button
class="btnstyle"
type="primary" @tap="copyFileSyncTest"
id="btn-copy-file-sync">同步复制文件{{copyFromFile}}到{{copyToFile}}</button>
<button type="primary" @tap="saveFileTest" id="btn-save-file">保存临时文件到本地</button>
<button type="primary" @tap="saveFileSyncTest" id="btn-save-file-sync">同步保存临时文件到本地</button>
<button type="primary" @tap="removeSavedFileTest" id="btn-remove-saved-file">删除已保存的本地文件</button>
<button type="primary" @tap="unzipFileTest" id="btn-unzip-file-sync">解压文件</button>
<button type="primary" @tap="getSavedFileListTest" id="btn-getsaved-filelist">获取该已保存的本地缓存文件列表</button>
<button type="primary" @tap="truncateFileTest" id="btn-truncate-file">对文件{{writeFile}}内容进行截断操作</button>
<button type="primary" @tap="truncateFileSyncTest" id="btn-truncate-file-sync">同步对文件{{writeFile}}内容进行截断操作</button>
<button type="primary" @tap="readCompressedFileTest" id="btn-compressed-file">读取指定压缩类型的本地文件内容</button>
<button type="primary" @tap="readCompressedFileSyncTest" id="btn-compressed-file-sync">同步读取指定压缩类型的本地文件内容</button>
<button type="primary" @tap="openFileTest" id="btn-open-file">打开文件{{readFile}},返回描述符</button>
<button type="primary" @tap="openFileSyncTest" id="btn-open-file-sync">同步打开文件{{readFile}},返回描述符</button>
<button type="primary" @tap="closeTest" id="btn-close-file">通过文件描述符关闭文件{{readFile}}</button>
<button type="primary" @tap="closeSyncTest" id="btn-close-file-sync">通过文件描述符同步关闭文件{{readFile}}</button>
<button type="primary" @tap="writeTest" id="btn-write">通过文件描述符写入文件{{readFile}}</button>
<button type="primary" @tap="writeSyncTest" id="btn-read-file">同步通过文件描述符写入文件{{readFile}}</button>
<button type="primary" @tap="fstatTest" id="btn-fstat-file">通过文件描述符获取{{statFile}}的状态信息</button>
<button type="primary" @tap="fstatSyncTest" id="btn-fstat-file-sync">同步通过文件描述符获取{{statFile}}的状态信息</button>
<button type="primary" @tap="ftruncateFileTest" id="btn-ftruncate-file">通过文件描述符对文件{{writeFile}}内容进行截断操作</button>
<button type="primary" @tap="ftruncateFileSyncTest"
id="btn-ftruncate-file-sync">同步通过文件描述符对文件{{writeFile}}内容进行截断操作</button>
<button class="btnstyle" type="primary" @tap="saveFileTest" id="btn-save-file">保存临时文件到本地</button>
<button class="btnstyle" type="primary" @tap="saveFileSyncTest" id="btn-save-file-sync">同步保存临时文件到本地</button>
<button class="btnstyle" type="primary" @tap="removeSavedFileTest" id="btn-remove-saved-file">删除已保存的本地文件</button>
<button class="btnstyle" type="primary" @tap="unzipFileTest" id="btn-unzip-file-sync">解压文件</button>
<button class="btnstyle" type="primary" @tap="getSavedFileListTest" id="btn-getsaved-filelist">获取该已保存的本地缓存文件列表</button>
<button class="btnstyle" type="primary" @tap="truncateFileTest" id="btn-truncate-file">对文件{{writeFile}}内容进行截断操作</button>
<button class="btnstyle" type="primary" @tap="truncateFileSyncTest" id="btn-truncate-file-sync">同步对文件{{writeFile}}内容进行截断操作</button>
<button class="btnstyle" type="primary" @tap="readCompressedFileTest" id="btn-compressed-file">读取指定压缩类型的本地文件内容</button>
<button class="btnstyle" type="primary" @tap="readCompressedFileSyncTest" id="btn-compressed-file-sync">同步读取指定压缩类型的本地文件内容</button>
<button class="btnstyle" type="primary" @tap="openFileTest" id="btn-open-file">打开文件{{readFile}},返回描述符</button>
<button class="btnstyle" type="primary" @tap="openFileSyncTest" id="btn-open-file-sync">同步打开文件{{readFile}},返回描述符</button>
<button class="btnstyle" type="primary" @tap="closeTest" id="btn-close-file">通过文件描述符关闭文件{{readFile}}</button>
<button class="btnstyle" type="primary" @tap="closeSyncTest" id="btn-close-file-sync">通过文件描述符同步关闭文件{{readFile}}</button>
<button class="btnstyle" type="primary" @tap="writeTest" id="btn-write">通过文件描述符写入文件{{readFile}}</button>
<button class="btnstyle" type="primary" @tap="writeSyncTest" id="btn-read-file">同步通过文件描述符写入文件{{readFile}}</button>
<button class="btnstyle" type="primary" @tap="fstatTest" id="btn-fstat-file">通过文件描述符获取{{statFile}}的状态信息</button>
<button class="btnstyle" type="primary" @tap="fstatSyncTest" id="btn-fstat-file-sync">同步通过文件描述符获取{{statFile}}的状态信息</button>
<button class="btnstyle" type="primary" @tap="ftruncateFileTest" id="btn-ftruncate-file">通过文件描述符对文件{{writeFile}}内容进行截断</button>
<button class="btnstyle" type="primary" @tap="ftruncateFileSyncTest"
id="btn-ftruncate-file-sync">同步通过文件描述符对文件{{writeFile}}内容进行截断</button>
<button class="btnstyle" type="primary" @tap="readZipEntry" id="btn-readzip-entry">读取压缩包内的文件</button>
<view style="height: 4px;"></view>
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
...
...
@@ -112,7 +114,8 @@
closeFileRet: '',
bytesWritten: 0,
fstat: new Stats(),
ftruncateRet:'',
ftruncateRet: '',
readZipFile: 'to.zip',
/**
* 待测试的全局环境变量
*/
...
...
@@ -733,7 +736,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
} as SaveFileOptions)
...
...
@@ -772,7 +775,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
} as UnzipFileOptions)
...
...
@@ -813,13 +816,13 @@
length: 7,
success: (res : FileManagerSuccessResult) => {
if (this.logAble) {
this.log += '
getSavedFileList
Test success:' + JSON.stringify(res) + '\n\n'
this.log += '
truncateFile
Test success:' + JSON.stringify(res) + '\n\n'
}
console.log("success", res)
},
fail: (res : UniError) => {
if (this.logAble) {
this.log += '
getSavedFileList
Test fail:' + JSON.stringify(res) + '\n\n'
this.log += '
truncateFile
Test fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
...
...
@@ -863,7 +866,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
} as ReadCompressedFileOptions)
...
...
@@ -881,7 +884,7 @@
this.done = true
} catch (e) {
if (this.logAble) {
this.log += 'r
mdir
SyncTest fail:' + e + '\n\n'
this.log += 'r
eadCompressedFile
SyncTest fail:' + e + '\n\n'
}
this.done = true
}
...
...
@@ -905,7 +908,7 @@
}
console.log('removeSavedFileTest fail', res)
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
} as RemoveSavedFileOptions)
...
...
@@ -919,13 +922,13 @@
`${this.globalTempPath}${this.statFile}`, //CACHE_PATH
this.recursiveVal)
if (this.logAble) {
this.log += 'statFileInfoTest success:' + JSON.stringify(res) + '\n\n'
this.log += 'statFileInfo
Sync
Test success:' + JSON.stringify(res) + '\n\n'
}
this.statsRet = res
this.done = true
} catch (e) {
if (this.logAble) {
this.log += '
rmdir
SyncTest fail:' + e + '\n\n'
this.log += '
statFileInfo
SyncTest fail:' + e + '\n\n'
}
this.done = true
}
...
...
@@ -950,7 +953,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
} as OpenFileOptions)
...
...
@@ -1013,9 +1016,6 @@
console.log('fail', res)
this.lastFailError = res
this.done = true
},
complete: (res) => {
}
} as OpenFileOptions)
...
...
@@ -1047,7 +1047,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
...
...
@@ -1092,7 +1092,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
...
...
@@ -1126,14 +1126,14 @@
encoding: "utf-8"
} as WriteSyncOptions)
if (this.logAble) {
this.log += 'writeTest success:' + JSON.stringify(ret) + '\n\n'
this.log += 'write
Sync
Test success:' + JSON.stringify(ret) + '\n\n'
}
console.log("success", ret)
this.done = true
this.bytesWritten = ret.bytesWritten
} catch (e) {
if (this.logAble) {
this.log += 'writeTest fail:' + JSON.stringify(e) + '\n\n'
this.log += 'write
Sync
Test fail:' + JSON.stringify(e) + '\n\n'
}
console.log('fail', e)
this.done = true
...
...
@@ -1168,7 +1168,7 @@
console.log('fail', res)
this.lastFailError = res
},
complete: (
res
) => {
complete: (
_
) => {
this.done = true
}
...
...
@@ -1202,7 +1202,7 @@
if (this.logAble) {
this.log += 'ftruncateFileTest success:' + JSON.stringify(res) + '\n\n'
}
this.ftruncateRet
=
res.errMsg
this.ftruncateRet
=
res.errMsg
},
fail: (res : UniError) => {
if (this.logAble) {
...
...
@@ -1231,14 +1231,46 @@
this.log += 'ftruncateFileSyncTest success:' + '\n\n'
}
this.done = true
this.ftruncateRet=
''
this.ftruncateRet =
''
} catch (e) {
if (this.logAble) {
this.log += 'ftruncateFileSyncTest fail:' + JSON.stringify(e) + '\n\n'
}
this.done = true
}
}
},
readZipEntry() {
const fileManager = uni.getFileSystemManager()
fileManager.readZipEntry({
filePath: `${this.basePath}${this.readZipFile}`,
encoding: 'utf-8',
entries: [{
path: 'kkkk',
encoding: 'utf-8'
} as EntryItem,
{
path: 'log/log1.txt',
encoding: 'utf-8'
} as EntryItem,
{
path: 'hello.txt',
encoding: 'utf-8'
} as EntryItem],
success: (res : EntriesResult) => {
if (this.logAble) {
this.log += 'readZipEntry success:' + JSON.stringify(res) + '\n\n'
}
console.log("success", res)
},
fail: (res : UniError) => {
if (this.logAble) {
this.log += 'readZipEntry fail:' + JSON.stringify(res) + '\n\n'
}
console.log('fail', res)
this.lastFailError = res
}
} as ReadZipEntryOptions)
},
},
...
...
@@ -1246,5 +1278,7 @@
</script>
<style>
.btnstyle{
margin: 4px;
}
</style>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录