mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-05 03:12:34 -06:00
136 lines
3.6 KiB
Go
136 lines
3.6 KiB
Go
package telegram
|
||
|
||
import (
|
||
"sync"
|
||
|
||
"github.com/google/uuid"
|
||
)
|
||
|
||
// Состояния пользователя
|
||
type State int
|
||
|
||
const (
|
||
StateNone State = iota
|
||
StateAddServerURL
|
||
StateAddServerLogin
|
||
StateAddServerPassword
|
||
StateAddServerConfirmName
|
||
StateAddServerInputName
|
||
StateBillingGiftURL
|
||
|
||
// Состояния редактора черновиков (начиная с 100)
|
||
StateDraftEditItemName State = 100 // Ожидание ввода нового названия позиции
|
||
StateDraftEditItemQty State = 101 // Ожидание ввода количества
|
||
StateDraftEditItemPrice State = 102 // Ожидание ввода цены
|
||
)
|
||
|
||
// UserContext хранит временные данные в процессе диалога
|
||
type UserContext struct {
|
||
State State
|
||
|
||
// Поля для добавления сервера
|
||
TempURL string
|
||
TempLogin string
|
||
TempPassword string
|
||
TempServerName string
|
||
|
||
// Поля для биллинга
|
||
BillingTargetURL string
|
||
|
||
// Поля редактора черновиков
|
||
EditingDraftID uuid.UUID // ID редактируемого черновика
|
||
EditingItemID uuid.UUID // ID редактируемой позиции (DraftInvoiceItem)
|
||
EditingItemIndex int // Порядковый номер позиции (1-based, для отображения пользователю)
|
||
DraftMenuMsgID int // ID сообщения со списком позиций (для обновления через EditMessage)
|
||
DraftCurrentPage int // Текущая страница пагинации (0-based)
|
||
}
|
||
|
||
// StateManager управляет состояниями
|
||
type StateManager struct {
|
||
mu sync.RWMutex
|
||
states map[int64]*UserContext
|
||
}
|
||
|
||
func NewStateManager() *StateManager {
|
||
return &StateManager{
|
||
states: make(map[int64]*UserContext),
|
||
}
|
||
}
|
||
|
||
func (sm *StateManager) GetState(userID int64) State {
|
||
sm.mu.RLock()
|
||
defer sm.mu.RUnlock()
|
||
if ctx, ok := sm.states[userID]; ok {
|
||
return ctx.State
|
||
}
|
||
return StateNone
|
||
}
|
||
|
||
func (sm *StateManager) SetState(userID int64, state State) {
|
||
sm.mu.Lock()
|
||
defer sm.mu.Unlock()
|
||
|
||
if _, ok := sm.states[userID]; !ok {
|
||
sm.states[userID] = &UserContext{}
|
||
}
|
||
sm.states[userID].State = state
|
||
}
|
||
|
||
func (sm *StateManager) GetContext(userID int64) *UserContext {
|
||
sm.mu.RLock()
|
||
defer sm.mu.RUnlock()
|
||
if ctx, ok := sm.states[userID]; ok {
|
||
return ctx
|
||
}
|
||
return &UserContext{} // Return empty safe struct
|
||
}
|
||
|
||
func (sm *StateManager) UpdateContext(userID int64, updater func(*UserContext)) {
|
||
sm.mu.Lock()
|
||
defer sm.mu.Unlock()
|
||
|
||
if _, ok := sm.states[userID]; !ok {
|
||
sm.states[userID] = &UserContext{}
|
||
}
|
||
updater(sm.states[userID])
|
||
}
|
||
|
||
func (sm *StateManager) Reset(userID int64) {
|
||
sm.mu.Lock()
|
||
defer sm.mu.Unlock()
|
||
delete(sm.states, userID)
|
||
}
|
||
|
||
// ResetDraftEditor сбрасывает только поля редактора черновика
|
||
func (sm *StateManager) ResetDraftEditor(userID int64) {
|
||
sm.mu.Lock()
|
||
defer sm.mu.Unlock()
|
||
|
||
if ctx, ok := sm.states[userID]; ok {
|
||
ctx.State = StateNone
|
||
ctx.EditingDraftID = uuid.Nil
|
||
ctx.EditingItemID = uuid.Nil
|
||
ctx.EditingItemIndex = 0
|
||
ctx.DraftMenuMsgID = 0
|
||
ctx.DraftCurrentPage = 0
|
||
}
|
||
}
|
||
|
||
// InitDraftEditor инициализирует FSM для редактора черновика
|
||
func (sm *StateManager) InitDraftEditor(userID int64, draftID uuid.UUID) {
|
||
sm.mu.Lock()
|
||
defer sm.mu.Unlock()
|
||
|
||
if _, ok := sm.states[userID]; !ok {
|
||
sm.states[userID] = &UserContext{}
|
||
}
|
||
|
||
ctx := sm.states[userID]
|
||
ctx.State = StateNone
|
||
ctx.EditingDraftID = draftID
|
||
ctx.EditingItemID = uuid.Nil
|
||
ctx.EditingItemIndex = 0
|
||
ctx.DraftMenuMsgID = 0
|
||
ctx.DraftCurrentPage = 0
|
||
}
|