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 React, { useState } from 'react';
|
||||||
import { useNavigate } from '@remix-run/react';
|
import { useNavigate } from '@remix-run/react';
|
||||||
import { useAuth } from '~/hooks/useAuth';
|
import { useAuth } from '~/hooks/useAuth';
|
||||||
import { getOSSUploadPolicy } from '~/utils/aliyunOSS';
|
|
||||||
|
|
||||||
// 导入我们刚刚定义的接口
|
|
||||||
import type { RegisterResponse } from '~/routes/api.auth.register';
|
import type { RegisterResponse } from '~/routes/api.auth.register';
|
||||||
|
import { uploadToOSS } from '~/utils/uploadToOSS';
|
||||||
|
|
||||||
export function Register() {
|
export function Register() {
|
||||||
const [phone, setPhone] = useState('');
|
const [phone, setPhone] = useState('');
|
||||||
@ -26,26 +24,8 @@ export function Register() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 获取OSS上传策略
|
|
||||||
const ossPolicy = await getOSSUploadPolicy();
|
|
||||||
|
|
||||||
// 上传头像到OSS
|
// 上传头像到OSS
|
||||||
const formData = new FormData();
|
const avatarUrl = await uploadToOSS(avatar);
|
||||||
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 registerResponse = await fetch('/api/auth/register', {
|
const registerResponse = await fetch('/api/auth/register', {
|
||||||
@ -65,6 +45,7 @@ export function Register() {
|
|||||||
if (registerResponse.ok && data.token && data.user) {
|
if (registerResponse.ok && data.token && data.user) {
|
||||||
// 注册成功后直接登录
|
// 注册成功后直接登录
|
||||||
login(data.token, data.user);
|
login(data.token, data.user);
|
||||||
|
navigate('/dashboard');
|
||||||
} else {
|
} else {
|
||||||
alert(data.error || '注册失败,请稍后再试');
|
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