fix: scope **
This commit is contained in:
parent
18e0f49b0c
commit
0036200d1f
|
|
@ -29,18 +29,7 @@
|
||||||
"assetProtocol": {
|
"assetProtocol": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"scope": [
|
"scope": [
|
||||||
"$HOME/**",
|
"**"
|
||||||
"$DESKTOP/**",
|
|
||||||
"$DOCUMENT/**",
|
|
||||||
"$DOWNLOAD/**",
|
|
||||||
"$APPDATA/**",
|
|
||||||
"$LOCALAPPDATA/**",
|
|
||||||
"C:\\Users\\imeep\\**",
|
|
||||||
"C:\\Users\\imeep\\.mixvideo\\**",
|
|
||||||
"C:\\Users\\**",
|
|
||||||
"C:\\**",
|
|
||||||
"/Users/**",
|
|
||||||
"/home/**"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"freezePrototype": true
|
"freezePrototype": true
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { convertFileSrc, invoke } from '@tauri-apps/api/core'
|
||||||
|
import { CheckCircle, XCircle, AlertCircle } from 'lucide-react'
|
||||||
|
|
||||||
|
interface TestResult {
|
||||||
|
path: string
|
||||||
|
status: 'success' | 'error' | 'pending'
|
||||||
|
message: string
|
||||||
|
url?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const AssetAccessTest: React.FC = () => {
|
||||||
|
const [results, setResults] = useState<TestResult[]>([])
|
||||||
|
const [customPath, setCustomPath] = useState('C:\\Users\\imeep\\.mixvideo\\temp\\video_segments')
|
||||||
|
|
||||||
|
const addResult = (result: TestResult) => {
|
||||||
|
setResults(prev => [...prev, result])
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateLastResult = (updates: Partial<TestResult>) => {
|
||||||
|
setResults(prev => {
|
||||||
|
const newResults = [...prev]
|
||||||
|
const lastIndex = newResults.length - 1
|
||||||
|
if (lastIndex >= 0) {
|
||||||
|
newResults[lastIndex] = { ...newResults[lastIndex], ...updates }
|
||||||
|
}
|
||||||
|
return newResults
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const testPath = async (path: string) => {
|
||||||
|
addResult({ path, status: 'pending', message: '测试中...' })
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 检查文件是否存在
|
||||||
|
const exists = await invoke<boolean>('check_file_exists', { filePath: path })
|
||||||
|
if (!exists) {
|
||||||
|
updateLastResult({
|
||||||
|
status: 'error',
|
||||||
|
message: '文件不存在'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 转换为 asset URL
|
||||||
|
const assetUrl = convertFileSrc(path)
|
||||||
|
console.log(`Converting ${path} -> ${assetUrl}`)
|
||||||
|
|
||||||
|
// 3. 尝试访问
|
||||||
|
const response = await fetch(assetUrl)
|
||||||
|
if (response.ok) {
|
||||||
|
const contentLength = response.headers.get('content-length')
|
||||||
|
updateLastResult({
|
||||||
|
status: 'success',
|
||||||
|
message: `访问成功 (${contentLength} bytes)`,
|
||||||
|
url: assetUrl
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
updateLastResult({
|
||||||
|
status: 'error',
|
||||||
|
message: `HTTP ${response.status}: ${response.statusText}`,
|
||||||
|
url: assetUrl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
updateLastResult({
|
||||||
|
status: 'error',
|
||||||
|
message: `访问失败: ${error}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testCommonPaths = async () => {
|
||||||
|
const paths = [
|
||||||
|
'C:\\Users\\imeep\\Desktop',
|
||||||
|
'C:\\Users\\imeep\\Documents',
|
||||||
|
'C:\\Users\\imeep\\.mixvideo',
|
||||||
|
'C:\\Users\\imeep\\.mixvideo\\temp',
|
||||||
|
'C:\\Users\\imeep\\.mixvideo\\temp\\video_segments',
|
||||||
|
'C:\\Users\\imeep\\.mixvideo\\temp\\original_videos',
|
||||||
|
'C:\\Users\\imeep\\.mixvideo\\temp\\cache'
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const path of paths) {
|
||||||
|
await testPath(path)
|
||||||
|
// 添加小延迟避免请求过快
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearResults = () => {
|
||||||
|
setResults([])
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusIcon = (status: TestResult['status']) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'success':
|
||||||
|
return <CheckCircle className="h-5 w-5 text-green-500" />
|
||||||
|
case 'error':
|
||||||
|
return <XCircle className="h-5 w-5 text-red-500" />
|
||||||
|
case 'pending':
|
||||||
|
return <AlertCircle className="h-5 w-5 text-yellow-500 animate-pulse" />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusColor = (status: TestResult['status']) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'success':
|
||||||
|
return 'bg-green-50 border-green-200'
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-50 border-red-200'
|
||||||
|
case 'pending':
|
||||||
|
return 'bg-yellow-50 border-yellow-200'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-6 max-w-4xl mx-auto">
|
||||||
|
<h1 className="text-2xl font-bold mb-6">Asset Protocol 访问测试</h1>
|
||||||
|
|
||||||
|
{/* 控制面板 */}
|
||||||
|
<div className="bg-white rounded-lg shadow p-4 mb-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
自定义路径测试
|
||||||
|
</label>
|
||||||
|
<div className="flex space-x-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={customPath}
|
||||||
|
onChange={(e) => setCustomPath(e.target.value)}
|
||||||
|
className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
placeholder="输入要测试的路径"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => testPath(customPath)}
|
||||||
|
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
>
|
||||||
|
测试
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex space-x-2">
|
||||||
|
<button
|
||||||
|
onClick={testCommonPaths}
|
||||||
|
className="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500"
|
||||||
|
>
|
||||||
|
测试常用路径
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={clearResults}
|
||||||
|
className="px-4 py-2 bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500"
|
||||||
|
>
|
||||||
|
清除结果
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 测试结果 */}
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h2 className="text-lg font-semibold">测试结果</h2>
|
||||||
|
{results.length === 0 ? (
|
||||||
|
<div className="text-gray-500 text-center py-8">
|
||||||
|
暂无测试结果,点击上方按钮开始测试
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
results.map((result, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`p-4 rounded-lg border ${getStatusColor(result.status)}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-start space-x-3">
|
||||||
|
{getStatusIcon(result.status)}
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="font-medium text-gray-900 break-all">
|
||||||
|
{result.path}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-600 mt-1">
|
||||||
|
{result.message}
|
||||||
|
</div>
|
||||||
|
{result.url && (
|
||||||
|
<div className="text-xs text-gray-500 mt-1 break-all">
|
||||||
|
Asset URL: {result.url}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 说明信息 */}
|
||||||
|
<div className="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||||
|
<h3 className="font-medium text-blue-900 mb-2">说明</h3>
|
||||||
|
<ul className="text-sm text-blue-800 space-y-1">
|
||||||
|
<li>• 此工具用于测试 Tauri AssetProtocol 的文件访问权限</li>
|
||||||
|
<li>• 绿色表示可以正常访问,红色表示访问被拒绝</li>
|
||||||
|
<li>• 如果 .mixvideo 路径访问失败,请检查 tauri.conf.json 中的 scope 配置</li>
|
||||||
|
<li>• 修改配置后需要重启应用才能生效</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AssetAccessTest
|
||||||
Loading…
Reference in New Issue