mirror of
https://github.com/stackblitz/bolt.new
synced 2025-06-26 18:17:50 +00:00
feat(auth): 优化注册头像上传及用户注册流程
This commit is contained in:
parent
21b1d9262e
commit
2ffa0b61d1
@ -1,10 +1,8 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate } from '@remix-run/react';
|
||||
import { useAuth } from '~/hooks/useAuth';
|
||||
import { getOSSUploadPolicy } from '~/utils/aliyunOSS';
|
||||
|
||||
// 导入我们刚刚定义的接口
|
||||
import type { RegisterResponse } from '~/routes/api.auth.register';
|
||||
import { uploadToOSS } from '~/utils/uploadToOSS';
|
||||
|
||||
export function Register() {
|
||||
const [phone, setPhone] = useState('');
|
||||
@ -26,26 +24,8 @@ export function Register() {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// 获取OSS上传策略
|
||||
const ossPolicy = await getOSSUploadPolicy();
|
||||
|
||||
// 上传头像到OSS
|
||||
const formData = new FormData();
|
||||
Object.entries(ossPolicy).forEach(([key, value]) => {
|
||||
formData.append(key, value as string);
|
||||
});
|
||||
formData.append('file', avatar);
|
||||
|
||||
const uploadResponse = await fetch(ossPolicy.host, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!uploadResponse.ok) {
|
||||
throw new Error('头像上传失败');
|
||||
}
|
||||
|
||||
const avatarUrl = `${ossPolicy.host}/${ossPolicy.key}`;
|
||||
const avatarUrl = await uploadToOSS(avatar);
|
||||
|
||||
// 注册用户
|
||||
const registerResponse = await fetch('/api/auth/register', {
|
||||
@ -65,6 +45,7 @@ export function Register() {
|
||||
if (registerResponse.ok && data.token && data.user) {
|
||||
// 注册成功后直接登录
|
||||
login(data.token, data.user);
|
||||
navigate('/dashboard');
|
||||
} else {
|
||||
alert(data.error || '注册失败,请稍后再试');
|
||||
}
|
||||
|
||||
13
app/routes/api.oss.upload-policy.ts
Normal file
13
app/routes/api.oss.upload-policy.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { json } from '@remix-run/node';
|
||||
import type { LoaderFunction } from '@remix-run/node';
|
||||
import { getOSSUploadPolicy, type OSSPolicy } from '~/utils/aliyunOSS.server';
|
||||
|
||||
export const loader: LoaderFunction = async () => {
|
||||
try {
|
||||
const policy: OSSPolicy = await getOSSUploadPolicy();
|
||||
return json(policy);
|
||||
} catch (error) {
|
||||
console.error('Error generating OSS upload policy:', error);
|
||||
return json({ error: '获取上传策略失败' }, { status: 500 });
|
||||
}
|
||||
};
|
||||
47
app/utils/aliyunOSS.server.ts
Normal file
47
app/utils/aliyunOSS.server.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import OSS from 'ali-oss';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { env } from 'node:process';
|
||||
|
||||
// 更新 OSSPolicy 接口以匹配实际返回的数据
|
||||
export interface OSSPolicy {
|
||||
OSSAccessKeyId: string;
|
||||
policy: string;
|
||||
Signature: string;
|
||||
host: string;
|
||||
expire: number;
|
||||
key: string;
|
||||
}
|
||||
|
||||
const ossConfig = {
|
||||
region: env.ALIYUN_OSS_REGION!,
|
||||
accessKeyId: env.ALIYUN_OSS_ACCESS_KEY_ID!,
|
||||
accessKeySecret: env.ALIYUN_OSS_ACCESS_KEY_SECRET!,
|
||||
bucket: env.ALIYUN_OSS_BUCKET!,
|
||||
};
|
||||
|
||||
if (Object.values(ossConfig).some(value => value === undefined)) {
|
||||
throw new Error('缺少必要的阿里云 OSS 配置');
|
||||
}
|
||||
|
||||
export async function getOSSUploadPolicy(): Promise<OSSPolicy> {
|
||||
const client = new OSS(ossConfig);
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() + 1);
|
||||
const policy = {
|
||||
expiration: date.toISOString(),
|
||||
conditions: [
|
||||
['content-length-range', 0, 1048576000], // 限制文件大小最大为1GB
|
||||
['starts-with', '$key', 'avatars/']
|
||||
]
|
||||
};
|
||||
|
||||
const formData = await client.calculatePostSignature(policy);
|
||||
const key = `avatars/${uuidv4()}`;
|
||||
|
||||
return {
|
||||
...formData,
|
||||
key,
|
||||
host: `https://${ossConfig.bucket}.${ossConfig.region}.aliyuncs.com`,
|
||||
expire: Math.floor(date.getTime() / 1000)
|
||||
};
|
||||
}
|
||||
34
app/utils/uploadToOSS.ts
Normal file
34
app/utils/uploadToOSS.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import type { OSSPolicy } from './aliyunOSS.server';
|
||||
|
||||
export async function uploadToOSS(file: File): Promise<string> {
|
||||
try {
|
||||
// 获取OSS上传策略
|
||||
const policyResponse = await fetch('/api/oss/upload-policy');
|
||||
if (!policyResponse.ok) {
|
||||
throw new Error('获取上传策略失败');
|
||||
}
|
||||
const ossPolicy: OSSPolicy = await policyResponse.json();
|
||||
|
||||
// 上传文件到OSS
|
||||
const formData = new FormData();
|
||||
Object.entries(ossPolicy).forEach(([key, value]) => {
|
||||
formData.append(key, value.toString());
|
||||
});
|
||||
formData.append('file', file);
|
||||
|
||||
const uploadResponse = await fetch(ossPolicy.host, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!uploadResponse.ok) {
|
||||
throw new Error('文件上传失败');
|
||||
}
|
||||
|
||||
// 返回文件的URL
|
||||
return `${ossPolicy.host}/${ossPolicy.key}`;
|
||||
} catch (error) {
|
||||
console.error('Upload to OSS failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user