|
@@ -1,5 +1,6 @@
|
|
|
import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify'
|
|
import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify'
|
|
|
import { FishService } from '../services/fish.service'
|
|
import { FishService } from '../services/fish.service'
|
|
|
|
|
+import { SenderService } from '../services/sender.service'
|
|
|
import { ResultEnum } from '../entities/fish.entity'
|
|
import { ResultEnum } from '../entities/fish.entity'
|
|
|
import { UserRole } from '../entities/user.entity'
|
|
import { UserRole } from '../entities/user.entity'
|
|
|
import {
|
|
import {
|
|
@@ -8,17 +9,21 @@ import {
|
|
|
UpdateFishBody,
|
|
UpdateFishBody,
|
|
|
DeleteFishBody,
|
|
DeleteFishBody,
|
|
|
StatisticsQuery,
|
|
StatisticsQuery,
|
|
|
- BatchUpdateFishBody
|
|
|
|
|
|
|
+ BatchUpdateFishBody,
|
|
|
|
|
+ ConvertFishToSenderBody
|
|
|
} from '../dto/fish.dto'
|
|
} from '../dto/fish.dto'
|
|
|
import { getClientIP } from '../utils/ip.util'
|
|
import { getClientIP } from '../utils/ip.util'
|
|
|
|
|
+import { buildStringSession } from '../utils/tg.util'
|
|
|
|
|
|
|
|
export class FishController {
|
|
export class FishController {
|
|
|
private fishService: FishService
|
|
private fishService: FishService
|
|
|
|
|
+ private senderService: SenderService
|
|
|
private app: FastifyInstance
|
|
private app: FastifyInstance
|
|
|
|
|
|
|
|
constructor(app: FastifyInstance) {
|
|
constructor(app: FastifyInstance) {
|
|
|
this.app = app
|
|
this.app = app
|
|
|
this.fishService = new FishService(app)
|
|
this.fishService = new FishService(app)
|
|
|
|
|
+ this.senderService = new SenderService(app)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async create(request: FastifyRequest<{ Body: CreateFishBody }>, reply: FastifyReply) {
|
|
async create(request: FastifyRequest<{ Body: CreateFishBody }>, reply: FastifyReply) {
|
|
@@ -302,4 +307,95 @@ export class FishController {
|
|
|
return reply.code(500).send({ message: '批量更新失败' })
|
|
return reply.code(500).send({ message: '批量更新失败' })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ async convertFishToSender(request: FastifyRequest<{ Body: ConvertFishToSenderBody }>, reply: FastifyReply) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { minDate } = request.body
|
|
|
|
|
+
|
|
|
|
|
+ let minDateObj: Date | undefined
|
|
|
|
|
+ if (minDate) {
|
|
|
|
|
+ minDateObj = new Date(minDate)
|
|
|
|
|
+ if (isNaN(minDateObj.getTime())) {
|
|
|
|
|
+ return reply.code(400).send({ message: '日期格式无效' })
|
|
|
|
|
+ }
|
|
|
|
|
+ minDateObj.setHours(0, 0, 0, 0)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const fishList = await this.fishService.findFishForConversion(minDateObj)
|
|
|
|
|
+
|
|
|
|
|
+ if (fishList.length === 0) {
|
|
|
|
|
+ return reply.send({
|
|
|
|
|
+ message: '没有找到符合条件的 fish 记录',
|
|
|
|
|
+ total: 0,
|
|
|
|
|
+ converted: 0,
|
|
|
|
|
+ skipped: 0,
|
|
|
|
|
+ failed: 0,
|
|
|
|
|
+ details: []
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const results = {
|
|
|
|
|
+ converted: 0,
|
|
|
|
|
+ skipped: 0,
|
|
|
|
|
+ failed: 0,
|
|
|
|
|
+ details: [] as Array<{ fishId: string; status: string; message?: string }>
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (const fish of fishList) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (!fish.session) {
|
|
|
|
|
+ results.skipped++
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let convertedSessionStr: string
|
|
|
|
|
+ try {
|
|
|
|
|
+ convertedSessionStr = buildStringSession(fish.session)
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ results.failed++
|
|
|
|
|
+ results.details.push({
|
|
|
|
|
+ fishId: fish.id,
|
|
|
|
|
+ status: 'failed',
|
|
|
|
|
+ message: `session 转换失败: ${error instanceof Error ? error.message : String(error)}`
|
|
|
|
|
+ })
|
|
|
|
|
+ this.app.log.error(error, `转换 fish ${fish.id} 的 session 失败`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const existingSender = await this.senderService.findById(fish.id)
|
|
|
|
|
+
|
|
|
|
|
+ if (existingSender) {
|
|
|
|
|
+ await this.senderService.update(fish.id, { sessionStr: convertedSessionStr })
|
|
|
|
|
+ results.converted++
|
|
|
|
|
+ } else {
|
|
|
|
|
+ await this.senderService.create(fish.id, undefined, undefined, convertedSessionStr)
|
|
|
|
|
+ results.converted++
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ results.failed++
|
|
|
|
|
+ results.details.push({
|
|
|
|
|
+ fishId: fish.id,
|
|
|
|
|
+ status: 'failed',
|
|
|
|
|
+ message: error instanceof Error ? error.message : String(error)
|
|
|
|
|
+ })
|
|
|
|
|
+ this.app.log.error(error, `转换 fish ${fish.id} 到 sender 失败`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return reply.send({
|
|
|
|
|
+ message: `转换完成:成功 ${results.converted} 条,跳过 ${results.skipped} 条,失败 ${results.failed} 条`,
|
|
|
|
|
+ total: fishList.length,
|
|
|
|
|
+ converted: results.converted,
|
|
|
|
|
+ skipped: results.skipped,
|
|
|
|
|
+ failed: results.failed,
|
|
|
|
|
+ details: results.details
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ this.app.log.error(error, '转换 fish 到 sender 失败')
|
|
|
|
|
+ return reply.code(500).send({
|
|
|
|
|
+ message: '转换失败',
|
|
|
|
|
+ error: error instanceof Error ? error.message : String(error)
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|