260 行
8.1 KiB
Plaintext
260 行
8.1 KiB
Plaintext
<template>
|
||
<view style="flex-direction: row;" id="rootview">
|
||
<radio-group @change="switchCacheOrData">
|
||
<radio value="data" :checked="true">数据目录</radio>
|
||
<radio value="cache"
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
disabled
|
||
<!-- #endif -->
|
||
>缓存目录</radio>
|
||
</radio-group>
|
||
<button @click="refreshFile">刷新</button>
|
||
<!-- #ifdef APP -->
|
||
<button @click="clearFile">清空缓存</button>
|
||
<!-- #endif -->
|
||
<button @click="snapshot">截图</button>
|
||
</view>
|
||
<text>文件总数:{{ count }};\n文件总大小:{{size}} M</text>
|
||
<text style="border: 1px solid #ccc;margin: 5px;">根路径:{{rootPath}}</text>
|
||
<list-view style="flex: 1;">
|
||
<list-item v-for="(item, index) in fileList" :key="index" style="padding: 5px;border-bottom: 1px solid #ccc;" :style="getIndentStyle(item.shotPath)"
|
||
@click="showDialog(item)">
|
||
<view style="flex-direction: row;">
|
||
<!-- <text style="font-family: uni-icon;" v-if="!item.isFile">\uE661</text> -->
|
||
<!-- #ifdef APP -->
|
||
<!-- TODO: 微信小程序不支持uni内置字体,还得再找一个图标-->
|
||
<text style="font-family: uni-icon;" v-if="!item.isFile">{{uniIcon}}</text> <!-- TODO @颜伊林 必须写响应式变量,多端表现不一致-->
|
||
<!-- #endif -->
|
||
<text >{{(item.shotPath as string)}}</text>
|
||
</view>
|
||
<text style="font-size: 12px;color: #ccc;" v-if="item.isFile" >{{item.size}}k</text>
|
||
</list-item>
|
||
</list-view>
|
||
<view v-if="dialogShow" style="position: fixed; top: 0; bottom: 0; left: 0; right: 0; align-items: center; justify-content: center; z-index: 1000; background-color: rgba(16, 16, 16, 0.5);">
|
||
<view style="background-color: #fff;padding: 10px;border-radius: 10px;width: 90%;margin: 0 auto;">
|
||
<text style="font-size: 20px;font-weight: bold;">{{currentFile.shotPath}}</text>
|
||
<text>类型:{{currentFile.isFile ? '文件' : '目录'}}</text>
|
||
<text>路径:{{currentFile.path}}</text>
|
||
<text>大小:{{currentFile.size}}k</text>
|
||
<text>修改时间:{{currentFile.modifyTime}}</text>
|
||
<view style="flex-direction: row;width: 100%;justify-content: space-between;padding: 10px;">
|
||
<button @click="openFile(currentFile)" size="mini" v-if="currentFile.isFile">打开</button>
|
||
<button @click="deleteFile(currentFile)" size="mini">删除</button>
|
||
<button @click="closeDialog" size="mini">关闭</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
type fileListType = {
|
||
path : string,
|
||
shotPath : string,
|
||
size : number,
|
||
isFile : boolean,
|
||
modifyTime : string
|
||
}
|
||
let fileList = ref([] as fileListType[])
|
||
let count = ref(0), size = ref(0)
|
||
let rootPath = ref("")
|
||
let dialogShow = ref(false)
|
||
const uniIcon = ref("\uE661")
|
||
let currentFile = ref({"path":"","shotPath":"","size":0,isFile:false,modifyTime:''} as fileListType)
|
||
let cacheOrData = ref(uni.env.USER_DATA_PATH)
|
||
|
||
const switchCacheOrData = (e : UniRadioGroupChangeEvent) => {
|
||
cacheOrData.value = (e.detail.value=="cache") ? uni.env.CACHE_PATH : uni.env.USER_DATA_PATH
|
||
}
|
||
|
||
// 遍历文件刷新列表
|
||
const refreshFile = () => {
|
||
const fileManager = uni.getFileSystemManager()
|
||
fileManager.stat({
|
||
// path: uni.env.CACHE_PATH, //沙盒cache目录
|
||
// path: uni.env.USER_DATA_PATH, //沙盒根目录
|
||
path: cacheOrData.value,
|
||
recursive: true,
|
||
success: (res : StatSuccessResult) => {
|
||
// log.value += 'statFileInfoTest success:' + JSON.stringify(res) + '\n\n'
|
||
console.log('statFileInfo success1')
|
||
console.log('res.stats', res.stats)
|
||
console.log('uni.env.CACHE_PATH: ',uni.env.CACHE_PATH);
|
||
console.log('uni.env.USER_DATA_PATH: ',uni.env.USER_DATA_PATH);
|
||
console.log('uni.env.SANDBOX_PATH: ',uni.env.SANDBOX_PATH);
|
||
let tempFileList = [] as fileListType[]
|
||
let tempSize = 0
|
||
for (let i=0;i<res.stats.length;i++) {
|
||
console.log("resitem",res.stats[i].path);
|
||
if (i==0) {
|
||
rootPath.value = res.stats[i].path
|
||
continue
|
||
}
|
||
let tempFileItem = {
|
||
"path":"",
|
||
"shotPath":"",
|
||
"size":0,
|
||
isFile:false,
|
||
modifyTime:''
|
||
} as fileListType
|
||
|
||
tempFileItem.shotPath = res.stats[i].path.replace(rootPath.value, "")
|
||
tempFileItem.path = res.stats[i].path
|
||
tempFileItem.size = res.stats[i].stats.size/1024
|
||
tempFileItem.isFile = res.stats[i].stats.isFile()
|
||
const mdate = new Date(res.stats[i].stats.lastModifiedTime * 1000)
|
||
tempFileItem.modifyTime = mdate.getFullYear().toString() + "-" + (mdate.getMonth()+1).toString() + "-" + mdate.getDate().toString() + " "
|
||
+ mdate.getHours().toString() + ":" + mdate.getMinutes().toString() + ":" + mdate.getSeconds().toString()
|
||
tempSize = tempSize + res.stats[i].stats.size
|
||
tempFileList.push(tempFileItem)
|
||
}
|
||
fileList.value = tempFileList
|
||
size.value = tempSize/1024/1024
|
||
count.value = tempFileList.length
|
||
},
|
||
fail: (res : IUniError) => {
|
||
uni.showModal({
|
||
title: '获取文件状态失败',
|
||
content: res.errMsg,
|
||
showCancel: false
|
||
})
|
||
console.error('statFileInfo fail', res)
|
||
},
|
||
complete: (res : any) => {
|
||
console.log("statFileInfo complete", res)
|
||
}
|
||
} as StatOptions)
|
||
}
|
||
|
||
const showDialog = (item: fileListType) => {
|
||
currentFile.value = item
|
||
dialogShow.value = true
|
||
}
|
||
const closeDialog = () => {
|
||
dialogShow.value = false
|
||
}
|
||
|
||
const deleteFile = (fileItem: fileListType) => {
|
||
const fileManager = uni.getFileSystemManager()
|
||
let path = cacheOrData.value + fileItem.path
|
||
if (fileItem.isFile) {
|
||
fileManager.unlink({
|
||
filePath: path,
|
||
success: () => {
|
||
refreshFile()
|
||
closeDialog()
|
||
},
|
||
fail: (err : IFileSystemManagerFail) => {
|
||
uni.showModal({
|
||
title: '删除文件失败',
|
||
content: err.errMsg,
|
||
showCancel: false
|
||
})
|
||
}
|
||
})
|
||
} else {
|
||
fileManager.rmdir({
|
||
dirPath: path,
|
||
recursive: true,
|
||
success: () => {
|
||
refreshFile()
|
||
closeDialog()
|
||
},
|
||
fail: (err : IFileSystemManagerFail) => {
|
||
uni.showModal({
|
||
title: '删除目录失败',
|
||
content: err.errMsg,
|
||
showCancel: false
|
||
})
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
const clearFile = () => {
|
||
const fileManager = uni.getFileSystemManager()
|
||
// TODO 3个App平台表现不一致 @颜伊林
|
||
fileManager.rmdir({
|
||
"dirPath":uni.env.CACHE_PATH,
|
||
"recursive":true,
|
||
success: (res : FileManagerSuccessResult) => {
|
||
console.log("rmdir success", res)
|
||
fileList.value = [] as fileListType[]
|
||
size.value = 0
|
||
count.value = 0
|
||
uni.showToast({
|
||
title:"清空缓存目录成功",
|
||
icon:"success"
|
||
})
|
||
},
|
||
fail: (res : IFileSystemManagerFail) => {
|
||
console.error('清空缓存目录失败', res)
|
||
uni.showModal({
|
||
title: '清空缓存目录失败',
|
||
content: res.errMsg,
|
||
showCancel: false
|
||
})
|
||
},
|
||
complete: (res : any) => {
|
||
console.log("rmdir complete", res)
|
||
}
|
||
})
|
||
}
|
||
|
||
const openFile = (fileItem: fileListType) => {
|
||
let path = cacheOrData.value + fileItem.path
|
||
let suffix = path.split('.').pop()
|
||
switch(suffix) {
|
||
case 'jpg':
|
||
case 'png':
|
||
case 'gif':
|
||
case 'jpeg':
|
||
case 'webp':
|
||
case 'bmp':
|
||
case 'ico':
|
||
case 'heic':
|
||
case 'heif':
|
||
case 'tif':
|
||
console.log("path:", path)
|
||
uni.previewImage({
|
||
urls: [path]
|
||
})
|
||
break
|
||
|
||
default:
|
||
uni.openDocument({
|
||
filePath: path,
|
||
success: (res) => {
|
||
console.log("openDocument success", res)
|
||
},
|
||
fail: (res) => {
|
||
console.error("openDocument fail", res)
|
||
uni.showModal({
|
||
title: '打开文件失败',
|
||
content: res.errMsg,
|
||
showCancel: false
|
||
})
|
||
}
|
||
})
|
||
|
||
}
|
||
}
|
||
const snapshot = () => {
|
||
uni.getElementById("rootview")!.takeSnapshot({})
|
||
}
|
||
|
||
// 根据路径中/的数量计算缩进样式
|
||
const getIndentStyle = (path: string) => {
|
||
const matches = path.match(/\//g)
|
||
// console.log("matches", matches)
|
||
let level = 0
|
||
if (matches!=null) {
|
||
level = matches.length
|
||
}
|
||
return {
|
||
paddingLeft: `${level * 20}px`
|
||
|
||
}
|
||
}
|
||
|
||
</script>
|