|
|
@@ -1,13 +1,24 @@
|
|
|
import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify'
|
|
|
import { MemberService } from '../services/member.service'
|
|
|
-import { CreateMemberBody, UpdateMemberBody, ListMemberQuery, MemberResponse } from '../dto/member.dto'
|
|
|
+import {
|
|
|
+ CreateMemberBody,
|
|
|
+ UpdateMemberBody,
|
|
|
+ ListMemberQuery,
|
|
|
+ MemberResponse,
|
|
|
+ UpdateGuestBody,
|
|
|
+ MemberLoginBody,
|
|
|
+ ResetPasswordBody
|
|
|
+} from '../dto/member.dto'
|
|
|
import { VipLevel, MemberStatus } from '../entities/member.entity'
|
|
|
+import { UserService } from '../services/user.service'
|
|
|
|
|
|
export class MemberController {
|
|
|
private memberService: MemberService
|
|
|
+ private userService: UserService
|
|
|
|
|
|
constructor(app: FastifyInstance) {
|
|
|
this.memberService = new MemberService(app)
|
|
|
+ this.userService = new UserService(app)
|
|
|
}
|
|
|
|
|
|
async createGuest(request: FastifyRequest<{ Querystring: { code?: string } }>, reply: FastifyReply) {
|
|
|
@@ -26,7 +37,8 @@ export class MemberController {
|
|
|
return reply.code(201).send({
|
|
|
user: {
|
|
|
id: user.id,
|
|
|
- name: user.name
|
|
|
+ name: user.name,
|
|
|
+ vipLevel: VipLevel.GUEST
|
|
|
},
|
|
|
token
|
|
|
})
|
|
|
@@ -35,6 +47,130 @@ export class MemberController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ async upgradeGuest(request: FastifyRequest<{ Body: UpdateGuestBody }>, reply: FastifyReply) {
|
|
|
+ try {
|
|
|
+ const { userId, name, password, email, phone } = request.body
|
|
|
+
|
|
|
+ if (!name || !password) {
|
|
|
+ return reply.code(400).send({ message: '用户名和密码为必填字段' })
|
|
|
+ }
|
|
|
+ if (name.length < 3 || name.length > 20) {
|
|
|
+ return reply.code(400).send({ message: '用户名长度必须在3-20个字符之间' })
|
|
|
+ }
|
|
|
+ if (password.length < 6) {
|
|
|
+ return reply.code(400).send({ message: '密码长度不能少于6个字符' })
|
|
|
+ }
|
|
|
+ if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
|
+ return reply.code(400).send({ message: '邮箱格式不正确' })
|
|
|
+ }
|
|
|
+ if (phone && !/^1[3-9]\d{9}$/.test(phone)) {
|
|
|
+ return reply.code(400).send({ message: '手机号格式不正确' })
|
|
|
+ }
|
|
|
+
|
|
|
+ await this.memberService.upgradeGuest(userId, name, password, email, phone)
|
|
|
+
|
|
|
+ return reply.send({ message: '游客账户转换成功' })
|
|
|
+ } catch (error) {
|
|
|
+ const errorMessage = error instanceof Error ? error.message : '更新游客失败'
|
|
|
+ if (errorMessage.includes('不存在')) {
|
|
|
+ return reply.code(404).send({ message: errorMessage })
|
|
|
+ } else if (errorMessage.includes('已被使用') || errorMessage.includes('格式')) {
|
|
|
+ return reply.code(400).send({ message: errorMessage })
|
|
|
+ }
|
|
|
+
|
|
|
+ return reply.code(500).send({ message: '更新游客失败', error: errorMessage })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async memberLogin(request: FastifyRequest<{ Body: MemberLoginBody }>, reply: FastifyReply) {
|
|
|
+ try {
|
|
|
+ const { name, password } = request.body
|
|
|
+
|
|
|
+ if (!name || !password) {
|
|
|
+ return reply.code(400).send({ message: '请输入用户名和密码' })
|
|
|
+ }
|
|
|
+ const loginResult = await this.memberService.validateMemberLogin(name, password)
|
|
|
+ if (!loginResult) {
|
|
|
+ return reply.code(401).send({ message: '用户名或密码错误' })
|
|
|
+ }
|
|
|
+ const { user, member } = loginResult
|
|
|
+ const token = await reply.jwtSign({ id: user.id, name: user.name, role: user.role })
|
|
|
+ await this.memberService.checkVipExpireTime(member)
|
|
|
+
|
|
|
+ return reply.send({
|
|
|
+ user: {
|
|
|
+ id: user.id,
|
|
|
+ name: user.name,
|
|
|
+ role: user.role,
|
|
|
+ vipLevel: member.vipLevel
|
|
|
+ },
|
|
|
+ token
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ return reply.code(500).send(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async profile(request: FastifyRequest, reply: FastifyReply) {
|
|
|
+ try {
|
|
|
+ const user = await this.userService.findById(request.user.id)
|
|
|
+ if (!user) {
|
|
|
+ return reply.code(404).send({ message: '会员信息不存在' })
|
|
|
+ }
|
|
|
+ const member = await this.memberService.findByUserId(user.id)
|
|
|
+ if (!member) {
|
|
|
+ return reply.code(404).send({ message: '会员信息不存在' })
|
|
|
+ }
|
|
|
+ await this.memberService.checkVipExpireTime(member)
|
|
|
+ return reply.send({
|
|
|
+ id: user.id,
|
|
|
+ name: user.name,
|
|
|
+ role: user.role,
|
|
|
+ vipLevel: member.vipLevel
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ return reply.code(500).send(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async resetPassword(request: FastifyRequest<{ Body: ResetPasswordBody }>, reply: FastifyReply) {
|
|
|
+ try {
|
|
|
+ const { password } = request.body
|
|
|
+ if (password.length < 8 || !/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(password)) {
|
|
|
+ return reply.code(400).send({ message: '密码长度必须至少8位,包含大小写字母和数字' })
|
|
|
+ }
|
|
|
+
|
|
|
+ await this.userService.resetPassword(request.user.id, password)
|
|
|
+ return reply.send({ message: '密码重置成功' })
|
|
|
+ } catch (error) {
|
|
|
+ return reply.code(500).send(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async updateVipLevel(
|
|
|
+ request: FastifyRequest<{
|
|
|
+ Params: { id: string }
|
|
|
+ Body: { vipLevel: VipLevel; vipExpireTime?: Date }
|
|
|
+ }>,
|
|
|
+ reply: FastifyReply
|
|
|
+ ) {
|
|
|
+ try {
|
|
|
+ const id = parseInt(request.params.id)
|
|
|
+ const { vipLevel, vipExpireTime } = request.body
|
|
|
+
|
|
|
+ const updatedMember = await this.memberService.updateVipLevel(id, vipLevel, vipExpireTime)
|
|
|
+
|
|
|
+ return reply.send({
|
|
|
+ member: {
|
|
|
+ vipLevel: updatedMember.vipLevel,
|
|
|
+ vipExpireTime: updatedMember.vipExpireTime
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ return reply.code(500).send({ message: '更新VIP等级失败', error })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
async create(request: FastifyRequest<{ Body: CreateMemberBody }>, reply: FastifyReply) {
|
|
|
try {
|
|
|
const { userId, email, phone, vipLevel, status, vipExpireTime } = request.body
|
|
|
@@ -223,38 +359,6 @@ export class MemberController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async updateVipLevel(
|
|
|
- request: FastifyRequest<{
|
|
|
- Params: { id: string }
|
|
|
- Body: { vipLevel: VipLevel; vipExpireTime?: Date }
|
|
|
- }>,
|
|
|
- reply: FastifyReply
|
|
|
- ) {
|
|
|
- try {
|
|
|
- const id = parseInt(request.params.id)
|
|
|
- const { vipLevel, vipExpireTime } = request.body
|
|
|
-
|
|
|
- const updatedMember = await this.memberService.updateVipLevel(id, vipLevel, vipExpireTime)
|
|
|
-
|
|
|
- return reply.send({
|
|
|
- member: {
|
|
|
- id: updatedMember.id,
|
|
|
- userId: updatedMember.userId,
|
|
|
- email: updatedMember.email,
|
|
|
- phone: updatedMember.phone,
|
|
|
- vipLevel: updatedMember.vipLevel,
|
|
|
- status: updatedMember.status,
|
|
|
- vipExpireTime: updatedMember.vipExpireTime,
|
|
|
- lastLoginAt: updatedMember.lastLoginAt,
|
|
|
- createdAt: updatedMember.createdAt,
|
|
|
- updatedAt: updatedMember.updatedAt
|
|
|
- }
|
|
|
- })
|
|
|
- } catch (error) {
|
|
|
- return reply.code(500).send({ message: '更新VIP等级失败', error })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
async updateStatus(
|
|
|
request: FastifyRequest<{
|
|
|
Params: { id: string }
|