|
@@ -0,0 +1,306 @@
|
|
|
|
|
+import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify'
|
|
|
|
|
+import { MemberService } from '../services/member.service'
|
|
|
|
|
+import { CreateMemberBody, UpdateMemberBody, ListMemberQuery, MemberResponse } from '../dto/member.dto'
|
|
|
|
|
+import { VipLevel, MemberStatus } from '../entities/member.entity'
|
|
|
|
|
+
|
|
|
|
|
+export class MemberController {
|
|
|
|
|
+ private memberService: MemberService
|
|
|
|
|
+
|
|
|
|
|
+ constructor(app: FastifyInstance) {
|
|
|
|
|
+ this.memberService = new MemberService(app)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async createGuest(request: FastifyRequest<{ Querystring: { code?: string } }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { code } = request.query || {}
|
|
|
|
|
+
|
|
|
|
|
+ // 获取客户端IP地址
|
|
|
|
|
+ const ip = request.ip ||
|
|
|
|
|
+ request.headers['x-forwarded-for'] as string ||
|
|
|
|
|
+ request.headers['x-real-ip'] as string ||
|
|
|
|
|
+ 'unknown'
|
|
|
|
|
+
|
|
|
|
|
+ await this.memberService.createGuest(code, ip)
|
|
|
|
|
+ return reply.code(201).send({ message: '创建游客成功' })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '创建游客失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async create(request: FastifyRequest<{ Body: CreateMemberBody }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { userId, email, phone, vipLevel, status, vipExpireTime } = request.body
|
|
|
|
|
+
|
|
|
|
|
+ // 检查用户是否已存在
|
|
|
|
|
+ const existingMember = await this.memberService.findByUserId(userId)
|
|
|
|
|
+ if (existingMember) {
|
|
|
|
|
+ return reply.code(400).send({ message: '该用户已经是会员' })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查邮箱是否已存在
|
|
|
|
|
+ if (email) {
|
|
|
|
|
+ const existingEmail = await this.memberService.findByEmail(email)
|
|
|
|
|
+ if (existingEmail) {
|
|
|
|
|
+ return reply.code(400).send({ message: '邮箱已被使用' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查手机号是否已存在
|
|
|
|
|
+ if (phone) {
|
|
|
|
|
+ const existingPhone = await this.memberService.findByPhone(phone)
|
|
|
|
|
+ if (existingPhone) {
|
|
|
|
|
+ return reply.code(400).send({ message: '手机号已被使用' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const member = await this.memberService.create({
|
|
|
|
|
+ userId,
|
|
|
|
|
+ email,
|
|
|
|
|
+ phone,
|
|
|
|
|
+ vipLevel,
|
|
|
|
|
+ status,
|
|
|
|
|
+ vipExpireTime
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ return reply.code(201).send({ message: '创建会员成功' })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '创建会员失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async getById(request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const id = parseInt(request.params.id)
|
|
|
|
|
+ const member = await this.memberService.findById(id)
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send({
|
|
|
|
|
+ member: {
|
|
|
|
|
+ id: member.id,
|
|
|
|
|
+ userId: member.userId,
|
|
|
|
|
+ email: member.email,
|
|
|
|
|
+ phone: member.phone,
|
|
|
|
|
+ vipLevel: member.vipLevel,
|
|
|
|
|
+ status: member.status,
|
|
|
|
|
+ vipExpireTime: member.vipExpireTime,
|
|
|
|
|
+ lastLoginAt: member.lastLoginAt,
|
|
|
|
|
+ createdAt: member.createdAt,
|
|
|
|
|
+ updatedAt: member.updatedAt
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(404).send({ message: '会员不存在' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async getByUserId(request: FastifyRequest<{ Params: { userId: string } }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const userId = parseInt(request.params.userId)
|
|
|
|
|
+ const member = await this.memberService.findByUserId(userId)
|
|
|
|
|
+
|
|
|
|
|
+ if (!member) {
|
|
|
|
|
+ return reply.code(404).send({ message: '会员不存在' })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send({
|
|
|
|
|
+ member: {
|
|
|
|
|
+ id: member.id,
|
|
|
|
|
+ userId: member.userId,
|
|
|
|
|
+ email: member.email,
|
|
|
|
|
+ phone: member.phone,
|
|
|
|
|
+ vipLevel: member.vipLevel,
|
|
|
|
|
+ status: member.status,
|
|
|
|
|
+ vipExpireTime: member.vipExpireTime,
|
|
|
|
|
+ lastLoginAt: member.lastLoginAt,
|
|
|
|
|
+ createdAt: member.createdAt,
|
|
|
|
|
+ updatedAt: member.updatedAt
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '查询会员失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async list(request: FastifyRequest<{ Querystring: ListMemberQuery }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { page, size, vipLevel, status, userId } = request.query
|
|
|
|
|
+
|
|
|
|
|
+ const result = await this.memberService.list(page || 0, size || 20, { vipLevel, status, userId })
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send(result)
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '查询会员列表失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async update(request: FastifyRequest<{ Body: UpdateMemberBody }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { id, userId, email, phone, vipLevel, status, vipExpireTime } = request.body
|
|
|
|
|
+
|
|
|
|
|
+ // 检查会员是否存在
|
|
|
|
|
+ try {
|
|
|
|
|
+ await this.memberService.findById(id)
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(404).send({ message: '会员不存在' })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查邮箱是否已被其他会员使用
|
|
|
|
|
+ if (email) {
|
|
|
|
|
+ const existingEmail = await this.memberService.findByEmail(email)
|
|
|
|
|
+ if (existingEmail && existingEmail.id !== id) {
|
|
|
|
|
+ return reply.code(400).send({ message: '邮箱已被其他会员使用' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查手机号是否已被其他会员使用
|
|
|
|
|
+ if (phone) {
|
|
|
|
|
+ const existingPhone = await this.memberService.findByPhone(phone)
|
|
|
|
|
+ if (existingPhone && existingPhone.id !== id) {
|
|
|
|
|
+ return reply.code(400).send({ message: '手机号已被其他会员使用' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const updatedMember = await this.memberService.update(id, {
|
|
|
|
|
+ userId,
|
|
|
|
|
+ email,
|
|
|
|
|
+ phone,
|
|
|
|
|
+ vipLevel,
|
|
|
|
|
+ status,
|
|
|
|
|
+ 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: '更新会员失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async delete(request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const id = parseInt(request.params.id)
|
|
|
|
|
+
|
|
|
|
|
+ // 检查会员是否存在
|
|
|
|
|
+ try {
|
|
|
|
|
+ await this.memberService.findById(id)
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(404).send({ message: '会员不存在' })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ await this.memberService.delete(id)
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send({ message: '删除会员成功' })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '删除会员失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async getAllMembers(request: FastifyRequest, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const members = await this.memberService.findAllMembers()
|
|
|
|
|
+ return reply.send({ members })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '获取所有会员失败', 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: {
|
|
|
|
|
+ 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 }
|
|
|
|
|
+ Body: { status: MemberStatus }
|
|
|
|
|
+ }>,
|
|
|
|
|
+ reply: FastifyReply
|
|
|
|
|
+ ) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const id = parseInt(request.params.id)
|
|
|
|
|
+ const { status } = request.body
|
|
|
|
|
+
|
|
|
|
|
+ const updatedMember = await this.memberService.updateStatus(id, status)
|
|
|
|
|
+
|
|
|
|
|
+ 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: '更新会员状态失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async updateLastLogin(request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const id = parseInt(request.params.id)
|
|
|
|
|
+ await this.memberService.updateLastLogin(id)
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send({ message: '更新最后登录时间成功' })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '更新最后登录时间失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async getStatistics(request: FastifyRequest, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const vipLevelStats = await this.memberService.countByVipLevel()
|
|
|
|
|
+ const statusStats = await this.memberService.countByStatus()
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send({
|
|
|
|
|
+ vipLevelStats,
|
|
|
|
|
+ statusStats
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return reply.code(500).send({ message: '获取统计数据失败', error })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|