feat: 支持用户管理
This commit is contained in:
@@ -2,9 +2,10 @@
|
||||
|
||||
import { useState, useRef } from 'react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Upload, X, Image as ImageIcon } from 'lucide-react'
|
||||
import { X, Image as ImageIcon } from 'lucide-react'
|
||||
import Image from 'next/image'
|
||||
import { Spinner } from '@/components/ui/spinner'
|
||||
import COS from 'cos-js-sdk-v5'
|
||||
|
||||
interface ImageUploaderProps {
|
||||
value: string
|
||||
@@ -47,49 +48,42 @@ export function ImageUploader({ value, onChange }: ImageUploaderProps) {
|
||||
const ext = file.name.split('.').pop() || 'jpg'
|
||||
const timestamp = Date.now()
|
||||
const randomStr = Math.random().toString(36).substring(2, 8)
|
||||
const filename = `levels/${timestamp}_${randomStr}.${ext}`
|
||||
const filename = `mini_game/images/${timestamp}_${randomStr}.${ext}`
|
||||
|
||||
// Upload to COS
|
||||
const formData = new FormData()
|
||||
formData.append('key', filename)
|
||||
formData.append('Signature', keyData.credentials.sessionToken)
|
||||
formData.append('success_action_status', '200')
|
||||
|
||||
const uploadUrl = `https://${keyData.bucket}.cos.${keyData.region}.myqcloud.com`
|
||||
|
||||
// Use XMLHttpRequest for COS upload with temp credentials
|
||||
const uploadResult = await new Promise<string>((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.open('POST', uploadUrl)
|
||||
|
||||
// Set temp credentials headers
|
||||
xhr.setRequestHeader('Authorization', getCOSAuthorization(
|
||||
keyData.credentials.tmpSecretId,
|
||||
keyData.credentials.tmpSecretKey,
|
||||
keyData.credentials.sessionToken,
|
||||
'post',
|
||||
filename,
|
||||
keyData.bucket,
|
||||
keyData.region
|
||||
))
|
||||
|
||||
xhr.onload = () => {
|
||||
if (xhr.status === 200) {
|
||||
resolve(`${uploadUrl}/${filename}`)
|
||||
} else {
|
||||
reject(new Error('上传失败'))
|
||||
}
|
||||
}
|
||||
xhr.onerror = () => reject(new Error('上传失败'))
|
||||
|
||||
const cosFormData = new FormData()
|
||||
cosFormData.append('key', filename)
|
||||
cosFormData.append('file', file)
|
||||
|
||||
xhr.send(cosFormData)
|
||||
// Initialize COS with temp credentials
|
||||
const cos = new COS({
|
||||
getAuthorization: (_options, callback) => {
|
||||
callback({
|
||||
TmpSecretId: keyData.credentials.tmpSecretId,
|
||||
TmpSecretKey: keyData.credentials.tmpSecretKey,
|
||||
SecurityToken: keyData.credentials.sessionToken,
|
||||
StartTime: keyData.startTime,
|
||||
ExpiredTime: keyData.expiredTime,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
onChange(uploadResult)
|
||||
// Upload file
|
||||
const uploadUrl = await new Promise<string>((resolve, reject) => {
|
||||
cos.putObject(
|
||||
{
|
||||
Bucket: keyData.bucket,
|
||||
Region: keyData.region,
|
||||
Key: filename,
|
||||
Body: file,
|
||||
},
|
||||
(err, data) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message || '上传失败'))
|
||||
return
|
||||
}
|
||||
const url = `https://${keyData.bucket}.cos.${keyData.region}.myqcloud.com/${filename}`
|
||||
resolve(url)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
onChange(uploadUrl)
|
||||
} catch (err) {
|
||||
console.error('Upload error:', err)
|
||||
setError(err instanceof Error ? err.message : '上传失败')
|
||||
@@ -162,21 +156,3 @@ export function ImageUploader({ value, onChange }: ImageUploaderProps) {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Helper function to generate COS authorization header
|
||||
function getCOSAuthorization(
|
||||
secretId: string,
|
||||
secretKey: string,
|
||||
sessionToken: string,
|
||||
method: string,
|
||||
pathname: string,
|
||||
bucket: string,
|
||||
region: string
|
||||
): string {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const exp = now + 1800
|
||||
const keyTime = `${now};${exp}`
|
||||
|
||||
// Simple authorization string for temp credentials
|
||||
return `q-sign-algorithm=sha1&q-ak=${secretId}&q-sign-time=${keyTime}&q-key-time=${keyTime}&q-header-list=&q-url-param-list=&q-signature=placeholder&x-cos-security-token=${sessionToken}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user