package app import ( "time" "douyu_go/internal/constants" "douyu_go/internal/logger" "douyu_go/internal/types" "douyu_go/internal/utils" ) const seckillStateEvent = "seckill:state" // StartSeckill 立即启动抢购。 func (a *App) StartSeckill(accountProducts map[string]string) types.MessageResult { // 兼容旧前端/旧构建:和平小店只能走 livebuy 专用链路,不能进入 CSRF 兑换流程。 if a.getClient().Activity.IsXiaodian { return a.startXiaodianSeckill(types.FixedSeckillRequest{ AccountProducts: accountProducts, }, "和平小店抢购已启动") } if len(accountProducts) == 0 { return types.MessageResult{Error: "请选择账号和商品"} } if !a.scheduler.TryStartRun() { return types.MessageResult{Error: "抢购任务正在运行,请勿重复提交"} } go a.scheduler.RunNow(utils.CloneStringMap(accountProducts)) return types.MessageResult{Success: true, Msg: "抢购已启动"} } // StartXiaodianSeckill 启动和平小店专用次数/间隔抢购。 func (a *App) StartXiaodianSeckill(req types.FixedSeckillRequest) types.MessageResult { return a.startXiaodianSeckill(req, "和平小店抢购已启动") } // StopSeckill 停止当前正在运行的抢购任务。 func (a *App) StopSeckill() types.MessageResult { if !a.scheduler.StopRun() { return types.MessageResult{Success: true, Msg: "当前没有正在运行的抢购任务"} } return types.MessageResult{Success: true, Msg: "已发送停止指令"} } // GetSeckillStatus 返回当前抢购运行状态。 func (a *App) GetSeckillStatus() types.SimpleResult { return types.SimpleResult{Success: a.scheduler.IsRunning()} } // StartFixedSeckill 启动和平小店固定次数/间隔抢购。 func (a *App) StartFixedSeckill(req types.FixedSeckillRequest) types.MessageResult { return a.startXiaodianSeckill(req, "固定次数抢购已启动") } func (a *App) startXiaodianSeckill(req types.FixedSeckillRequest, message string) types.MessageResult { if !a.getClient().Activity.IsXiaodian { return types.MessageResult{Error: "固定次数抢购仅支持和平小店"} } if len(req.AccountProducts) == 0 { return types.MessageResult{Error: "请选择账号和商品"} } if req.Attempts < 1 || req.Attempts > 100000 { return types.MessageResult{Error: "抢购次数需在 1-100000 之间"} } if req.DelayMs < 0 || req.DelayMs > 60000 { return types.MessageResult{Error: "抢购间隔需在 0-60000 毫秒之间"} } if !a.scheduler.TryStartRun() { return types.MessageResult{Error: "抢购任务正在运行,请勿重复提交"} } go a.scheduler.RunXiaodian(utils.CloneStringMap(req.AccountProducts), req.Attempts, req.DelayMs) return types.MessageResult{Success: true, Msg: message} } // SetSchedule 设置定时抢购。 func (a *App) SetSchedule(req types.SeckillRequest) (types.ScheduleResult, error) { return a.scheduler.ScheduleRun(req) } // CancelSchedule 取消未触发的定时抢购。 func (a *App) CancelSchedule() types.CancelScheduleResult { stopped := a.scheduler.CancelSchedule() return types.CancelScheduleResult{Success: true, Stopped: stopped} } // GetResults 返回当前抢购结果。 func (a *App) GetResults() map[string]string { return a.scheduler.Results() } // GetLogs 返回后端内存日志,支持增量获取。 func (a *App) GetLogs(since int64) types.LogsResult { entries := a.logStore.Since(since) nextSince := since if len(entries) > 0 { nextSince = entries[len(entries)-1].ID } return types.LogsResult{ Success: true, Logs: entries, Since: nextSince, File: a.logStore.FilePath(), } } // GetTime 返回服务端时间和本地时间。 func (a *App) GetTime() types.TimeResult { serverTime, err := a.getClient().ServerTime() source := "currentTime" if err != nil { source = "localFallback" logger.LogEvent("时间", "warn", "时间接口降级: %v", err) } return types.TimeResult{ ServerTime: serverTime.In(constants.CST).Format("2006-01-02 15:04:05.000"), LocalTime: time.Now().In(constants.CST).Format("2006-01-02 15:04:05.000"), Source: source, } } // ClearResults 清空抢购结果。 func (a *App) ClearResults() types.SimpleResult { a.scheduler.ClearResults() return types.SimpleResult{Success: true} }