|
|
@@ -0,0 +1,218 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="zh-CN">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>移动端头像上传测试</title>
|
|
|
+ <style>
|
|
|
+ body {
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
|
+ margin: 0;
|
|
|
+ padding: 20px;
|
|
|
+ background: #f5f5f5;
|
|
|
+ }
|
|
|
+ .container {
|
|
|
+ max-width: 400px;
|
|
|
+ margin: 0 auto;
|
|
|
+ background: white;
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 10px;
|
|
|
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
|
+ }
|
|
|
+ .avatar-preview {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #ddd;
|
|
|
+ margin: 20px auto;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ .avatar-preview img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+ }
|
|
|
+ .button {
|
|
|
+ display: block;
|
|
|
+ width: 100%;
|
|
|
+ padding: 12px;
|
|
|
+ margin: 10px 0;
|
|
|
+ background: #007bff;
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .button:disabled {
|
|
|
+ background: #ccc;
|
|
|
+ cursor: not-allowed;
|
|
|
+ }
|
|
|
+ .progress {
|
|
|
+ margin: 10px 0;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+ .error {
|
|
|
+ color: #dc3545;
|
|
|
+ margin: 10px 0;
|
|
|
+ }
|
|
|
+ .success {
|
|
|
+ color: #28a745;
|
|
|
+ margin: 10px 0;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <div class="container">
|
|
|
+ <h2>移动端头像上传测试</h2>
|
|
|
+
|
|
|
+ <div class="avatar-preview" id="avatarPreview">
|
|
|
+ <span>头像预览</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <input type="file" id="fileInput" accept="image/*" style="display: none;">
|
|
|
+
|
|
|
+ <button class="button" onclick="selectFile()">选择头像图片</button>
|
|
|
+ <button class="button" onclick="testUpload()" id="uploadBtn" disabled>测试上传</button>
|
|
|
+
|
|
|
+ <div class="progress" id="progress"></div>
|
|
|
+ <div class="error" id="error"></div>
|
|
|
+ <div class="success" id="success"></div>
|
|
|
+
|
|
|
+ <button class="button" onclick="testMinioAPI()" style="background: #28a745;">测试Minio API连接</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ let selectedFile = null;
|
|
|
+
|
|
|
+ function selectFile() {
|
|
|
+ document.getElementById('fileInput').click();
|
|
|
+ }
|
|
|
+
|
|
|
+ document.getElementById('fileInput').addEventListener('change', function(e) {
|
|
|
+ const file = e.target.files[0];
|
|
|
+ if (file) {
|
|
|
+ selectedFile = file;
|
|
|
+
|
|
|
+ // 显示预览
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = function(e) {
|
|
|
+ const preview = document.getElementById('avatarPreview');
|
|
|
+ preview.innerHTML = `<img src="${e.target.result}" alt="预览">`;
|
|
|
+ };
|
|
|
+ reader.readAsDataURL(file);
|
|
|
+
|
|
|
+ // 启用上传按钮
|
|
|
+ document.getElementById('uploadBtn').disabled = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ async function testUpload() {
|
|
|
+ if (!selectedFile) {
|
|
|
+ alert('请先选择文件');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const progress = document.getElementById('progress');
|
|
|
+ const error = document.getElementById('error');
|
|
|
+ const success = document.getElementById('success');
|
|
|
+
|
|
|
+ progress.textContent = '准备上传...';
|
|
|
+ error.textContent = '';
|
|
|
+ success.textContent = '';
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 模拟使用minio.ts上传
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('file', selectedFile);
|
|
|
+
|
|
|
+ const response = await fetch('/api/v1/files/upload-policy', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ name: selectedFile.name,
|
|
|
+ type: selectedFile.type,
|
|
|
+ size: selectedFile.size,
|
|
|
+ path: `test/avatars/${Date.now()}_${selectedFile.name}`
|
|
|
+ })
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ throw new Error('获取上传策略失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ const policy = await response.json();
|
|
|
+ progress.textContent = '获取策略成功,开始上传...';
|
|
|
+
|
|
|
+ // 模拟上传到MinIO
|
|
|
+ const uploadForm = new FormData();
|
|
|
+ Object.entries(policy.uploadPolicy).forEach(([key, value]) => {
|
|
|
+ if (key !== 'key' && key !== 'host' && key !== 'prefix' && typeof value === 'string') {
|
|
|
+ uploadForm.append(key, value);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ uploadForm.append('key', policy.uploadPolicy.key);
|
|
|
+ uploadForm.append('file', selectedFile);
|
|
|
+
|
|
|
+ const uploadResponse = await fetch(policy.uploadPolicy.host, {
|
|
|
+ method: 'POST',
|
|
|
+ body: uploadForm
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!uploadResponse.ok) {
|
|
|
+ throw new Error('上传失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ const fileUrl = `${policy.uploadPolicy.host}/${policy.uploadPolicy.key}`;
|
|
|
+ success.textContent = `上传成功!文件URL: ${fileUrl}`;
|
|
|
+ progress.textContent = '';
|
|
|
+
|
|
|
+ } catch (err) {
|
|
|
+ error.textContent = '上传失败: ' + err.message;
|
|
|
+ progress.textContent = '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async function testMinioAPI() {
|
|
|
+ const progress = document.getElementById('progress');
|
|
|
+ const error = document.getElementById('error');
|
|
|
+ const success = document.getElementById('success');
|
|
|
+
|
|
|
+ progress.textContent = '测试API连接...';
|
|
|
+ error.textContent = '';
|
|
|
+ success.textContent = '';
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await fetch('/api/v1/files/upload-policy', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ name: 'test.jpg',
|
|
|
+ type: 'image/jpeg',
|
|
|
+ size: 1024,
|
|
|
+ path: 'test/test.jpg'
|
|
|
+ })
|
|
|
+ });
|
|
|
+
|
|
|
+ if (response.ok) {
|
|
|
+ const data = await response.json();
|
|
|
+ success.textContent = 'API连接正常!';
|
|
|
+ progress.textContent = '';
|
|
|
+ } else {
|
|
|
+ throw new Error('API返回错误: ' + response.status);
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ error.textContent = 'API测试失败: ' + err.message;
|
|
|
+ progress.textContent = '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|