1、增加座席业务状态机模块。
This commit is contained in:
parent
e467ba3028
commit
9219363b7c
84
pkg/http/http.go
Normal file
84
pkg/http/http.go
Normal file
@ -0,0 +1,84 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
core *http.Client
|
||||
}
|
||||
|
||||
func NewClient() *Client {
|
||||
return &Client{
|
||||
core: http.DefaultClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) JSONGet(ctx context.Context, url string, header, params map[string]string, resp interface{}) error {
|
||||
return c.JSONDo(ctx, http.MethodGet, getCompleteURL(url, params), header, nil, resp)
|
||||
}
|
||||
|
||||
func (c *Client) JSONPost(ctx context.Context, url string, header map[string]string, req, resp interface{}) error {
|
||||
return c.JSONDo(ctx, http.MethodPost, url, header, req, resp)
|
||||
}
|
||||
|
||||
func (c *Client) JSONDo(ctx context.Context, method, url string, header map[string]string, req, resp interface{}) error {
|
||||
var reqReader io.Reader
|
||||
if req != nil {
|
||||
body, _ := json.Marshal(req)
|
||||
reqReader = bytes.NewReader(body)
|
||||
}
|
||||
|
||||
request, err := http.NewRequestWithContext(ctx, method, url, reqReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if request.Header == nil {
|
||||
request.Header = make(http.Header)
|
||||
}
|
||||
for k, v := range header {
|
||||
request.Header.Add(k, v)
|
||||
}
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err := c.core.Do(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("invalid status: %d", response.StatusCode)
|
||||
}
|
||||
|
||||
if resp == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
respBody, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return json.Unmarshal(respBody, resp)
|
||||
}
|
||||
|
||||
func getCompleteURL(origin string, params map[string]string) string {
|
||||
if len(params) == 0 {
|
||||
return origin
|
||||
}
|
||||
values := url.Values{}
|
||||
for k, v := range params {
|
||||
values.Add(k, v)
|
||||
}
|
||||
|
||||
queriesStr, _ := url.QueryUnescape(values.Encode())
|
||||
return fmt.Sprintf("%s?%s", origin, queriesStr)
|
||||
}
|
368
services/uniss/fsm.go
Normal file
368
services/uniss/fsm.go
Normal file
@ -0,0 +1,368 @@
|
||||
package uniss
|
||||
|
||||
import (
|
||||
"context"
|
||||
"dashboard/pkg/fsm"
|
||||
"time"
|
||||
|
||||
"git.zhangshuocauc.cn/redhat/timewheel"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
unisFsmEventReset fsm.EventName = "unisFsmEventReset"
|
||||
|
||||
unisFsmEventOfline fsm.EventName = "unisFsmEventOfline"
|
||||
unisFsmEventOnline fsm.EventName = "unisFsmEventOnline"
|
||||
unisFsmEventLoginId fsm.EventName = "unisFsmEventLoginId"
|
||||
unisFsmEventLoginSync fsm.EventName = "unisFsmEventLoginSync"
|
||||
unisFsmEventLoginForce fsm.EventName = "unisFsmEventLoginForce"
|
||||
unisFsmEventLoginServer fsm.EventName = "unisFsmEventLoginServer"
|
||||
unisFsmEventLogout fsm.EventName = "unisFsmEventLogout"
|
||||
unisFsmEventLogoutForce fsm.EventName = "unisFsmEventLogoutForce"
|
||||
unisFsmEventLogoutServer fsm.EventName = "unisFsmEventLogoutServer"
|
||||
unisFsmEventLogin fsm.EventName = "unisFsmEventLogin"
|
||||
unisFsmEventLoginSyncFailed fsm.EventName = "unisFsmEventLoginSyncFailed"
|
||||
unisFsmEventLoginSyncSuccess fsm.EventName = "unisFsmEventLoginSyncSuccess"
|
||||
|
||||
unisFsmEventLoginSuccess fsm.EventName = "unisFsmEventLoginSuccess"
|
||||
unisFsmEventLoginFailed fsm.EventName = "unisFsmEventLoginFailed"
|
||||
unisFsmEventLogoutSuccess fsm.EventName = "unisFsmEventLogoutSuccess"
|
||||
unisFsmEventLogoutFailed fsm.EventName = "unisFsmEventLogoutFailed"
|
||||
)
|
||||
|
||||
var events = fsm.Events{
|
||||
unisFsmEventReset,
|
||||
unisFsmEventLoginSuccess,
|
||||
unisFsmEventLoginFailed,
|
||||
unisFsmEventLogoutSuccess,
|
||||
unisFsmEventLogoutFailed,
|
||||
}
|
||||
|
||||
type fsmService struct {
|
||||
unisMSystemFsm *unisMSystemFsm
|
||||
unisMStateFsm *unisMStateFsm
|
||||
}
|
||||
|
||||
func (f *fsmService) reset(ctx context.Context) {
|
||||
f.unisMSystemFsm.reset(ctx)
|
||||
f.unisMStateFsm.reset(ctx)
|
||||
}
|
||||
|
||||
func newfsmService() (fsm *fsmService, err error) {
|
||||
fsm = &fsmService{}
|
||||
|
||||
fsm.unisMSystemFsm, err = newunisMSystemFsm()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fsm.unisMStateFsm, err = newunisMStateFsm()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*******************************主逻辑在线离线状态机************************************/
|
||||
type unisMSystemFsm struct {
|
||||
fsm *fsm.FSM
|
||||
}
|
||||
|
||||
const (
|
||||
unisMSystem = "unisMSystem"
|
||||
unisMIdle = "unisMIdle"
|
||||
unisMOnLine = "unisMOnLine"
|
||||
unisMOfLine = "unisMOfLine"
|
||||
|
||||
unisMOnLineIdle = "unisMOnLineIdle"
|
||||
unisMOnLineLoginId = "unisMOnLineLoginId"
|
||||
unisMOnLineLoginning = "unisMOnLineLoginning"
|
||||
unisMOnLineLogouting = "unisMOnLineLogouting"
|
||||
unisMOnLineLoginSync = "unisMOnLineLoginSync"
|
||||
)
|
||||
|
||||
func newunisMSystemFsm() (*unisMSystemFsm, error) {
|
||||
res := new(unisMSystemFsm)
|
||||
|
||||
fsm, err := fsm.NewFsm(unisMSystem, unisMIdle, events, []*fsm.StateRule{
|
||||
{Name: unisMSystem, Parent: "", InitState: unisMIdle, Processor: res.unisMSystem, Dst: []string{}},
|
||||
{Name: unisMIdle, Parent: unisMSystem, InitState: "", Processor: res.unisMIdle, Dst: []string{}},
|
||||
{Name: unisMOnLine, Parent: unisMSystem, InitState: unisMOnLineIdle, Processor: res.unisMOnLine, Dst: []string{}},
|
||||
{Name: unisMOfLine, Parent: unisMSystem, InitState: "", Processor: res.unisMOfLine, Dst: []string{}},
|
||||
|
||||
{Name: unisMOnLineIdle, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineIdle, Dst: []string{}},
|
||||
{Name: unisMOnLineLoginId, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLoginId, Dst: []string{}},
|
||||
{Name: unisMOnLineLoginning, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLoginning, Dst: []string{}},
|
||||
{Name: unisMOnLineLogouting, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLogouting, Dst: []string{}},
|
||||
{Name: unisMOnLineLoginSync, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLoginSync, Dst: []string{}},
|
||||
}, zap.NewStdLog(log.Logger))
|
||||
|
||||
if err != nil {
|
||||
log.Sugar().Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.fsm = fsm
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) reset(ctx context.Context) {
|
||||
f.fsm.ExecuteEvent(ctx, unisFsmEventReset, nil)
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMSystem(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventReset:
|
||||
e.FSM.StateChange(ctx, unisMIdle, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMIdle(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventOfline:
|
||||
e.FSM.StateChange(ctx, unisMOfLine, nil)
|
||||
case unisFsmEventOnline:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLoginSync, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMOnLine(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventOfline:
|
||||
e.FSM.StateChange(ctx, unisMOfLine, nil)
|
||||
case unisFsmEventLoginId:
|
||||
case unisFsmEventLoginSync:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLoginSync, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMOfLine(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventOnline:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLoginSync, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
/**********************************主逻辑登录状态机***********************************/
|
||||
func (f *unisMSystemFsm) unisMOnLineIdle(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventLoginId:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLoginId, e.Args)
|
||||
case unisFsmEventLoginForce:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLoginning, e.Args)
|
||||
case unisFsmEventLoginServer:
|
||||
case unisFsmEventLogout:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLogouting, e.Args)
|
||||
case unisFsmEventLogoutForce:
|
||||
fallthrough
|
||||
case unisFsmEventLogoutServer:
|
||||
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMOnLineLoginId(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*5, nil)
|
||||
case fsm.EventExit:
|
||||
e.FSM.StopEventTimer()
|
||||
case unisFsmEventLogin:
|
||||
e.FSM.StateChange(ctx, unisMOnLineLoginning, e.Args)
|
||||
case fsm.EventTimeOut:
|
||||
e.FSM.StateChange(ctx, unisMOnLineIdle, nil)
|
||||
case unisFsmEventLoginFailed:
|
||||
e.FSM.StateChange(ctx, unisMOnLineIdle, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMOnLineLoginning(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*5, nil)
|
||||
case fsm.EventExit:
|
||||
e.FSM.StopEventTimer()
|
||||
case fsm.EventTimeOut:
|
||||
e.FSM.StateChange(ctx, unisMOnLineIdle, nil)
|
||||
case unisFsmEventLoginFailed:
|
||||
e.FSM.StateChange(ctx, unisMOnLineIdle, nil)
|
||||
case unisFsmEventLoginSuccess:
|
||||
e.FSM.StateChange(ctx, unisMOnLineIdle, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMOnLineLogouting(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*5, nil)
|
||||
case fsm.EventExit:
|
||||
e.FSM.StopEventTimer()
|
||||
case fsm.EventTimeOut:
|
||||
fallthrough
|
||||
case unisFsmEventLogoutFailed:
|
||||
fallthrough
|
||||
case unisFsmEventLogoutSuccess:
|
||||
e.FSM.StateChange(ctx, unisMOnLineIdle, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMSystemFsm) unisMOnLineLoginSync(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*10, nil)
|
||||
case fsm.EventExit:
|
||||
e.FSM.StopEventTimer()
|
||||
case fsm.EventTimeOut:
|
||||
|
||||
case unisFsmEventLoginSyncFailed:
|
||||
case unisFsmEventLoginSyncSuccess:
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
/***************************主登录状态机********************************************/
|
||||
type unisMStateFsm struct {
|
||||
fsm *fsm.FSM
|
||||
}
|
||||
|
||||
const (
|
||||
unisMState = "unisMState"
|
||||
unisMStateIdle = "unisMStateIdle"
|
||||
unisMStateLogin = "unisMStateLogin"
|
||||
unisMStateLogout = "unisMStateLogout"
|
||||
)
|
||||
|
||||
func newunisMStateFsm() (*unisMStateFsm, error) {
|
||||
res := new(unisMStateFsm)
|
||||
|
||||
fsm, err := fsm.NewFsm(unisMState, unisMState, events, []*fsm.StateRule{
|
||||
{Name: unisMState, Parent: "", InitState: unisMStateIdle, Processor: res.unisMState, Dst: []string{}},
|
||||
{Name: unisMStateIdle, Parent: unisMState, InitState: "", Processor: res.unisMStateIdle, Dst: []string{}},
|
||||
{Name: unisMStateLogin, Parent: unisMState, InitState: "", Processor: res.unisMStateLogin, Dst: []string{}},
|
||||
{Name: unisMStateLogout, Parent: unisMState, InitState: "", Processor: res.unisMStateLogout, Dst: []string{}},
|
||||
{},
|
||||
}, zap.NewStdLog(log.Logger))
|
||||
|
||||
if err != nil {
|
||||
log.Sugar().Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.fsm = fsm
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (f *unisMStateFsm) reset(ctx context.Context) {
|
||||
f.fsm.ExecuteEvent(ctx, unisFsmEventReset, nil)
|
||||
}
|
||||
|
||||
func (f *unisMStateFsm) unisMState(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventReset:
|
||||
e.FSM.StateChange(ctx, unisMStateIdle, nil)
|
||||
case unisFsmEventLoginFailed:
|
||||
case unisFsmEventLogoutFailed:
|
||||
e.FSM.StateChange(ctx, unisMStateLogout, nil)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMStateFsm) unisMStateIdle(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventLoginSuccess:
|
||||
e.FSM.StateChange(ctx, unisMStateLogin, e.Args)
|
||||
case unisFsmEventLogoutSuccess:
|
||||
e.FSM.StateChange(ctx, unisMStateLogout, e.Args)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMStateFsm) unisMStateLogin(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Minute*5, nil)
|
||||
case fsm.EventExit:
|
||||
e.FSM.StopEventTimer()
|
||||
case fsm.EventTimeOut:
|
||||
e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Minute*5, nil)
|
||||
case unisFsmEventLoginSuccess:
|
||||
case unisFsmEventLogoutSuccess:
|
||||
e.FSM.StateChange(ctx, unisMStateLogout, e.Args)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
||||
|
||||
func (f *unisMStateFsm) unisMStateLogout(ctx context.Context, e *fsm.Event) error {
|
||||
switch e.Event {
|
||||
case fsm.EventEntry:
|
||||
case fsm.EventExit:
|
||||
case unisFsmEventLoginSuccess:
|
||||
e.FSM.StateChange(ctx, unisMStateLogin, e.Args)
|
||||
default:
|
||||
return fsm.EventNoProc
|
||||
}
|
||||
|
||||
return fsm.EventOK
|
||||
}
|
@ -20,6 +20,7 @@ type UnisStation struct {
|
||||
commonService *commonService
|
||||
communicateService *communicateService
|
||||
dataCenterService *dataCenterService
|
||||
fsmService *fsmService
|
||||
}
|
||||
|
||||
func NewUnis(_log *logger.Logger, conf *settings.UnisConfig) (res *UnisStation, err error) {
|
||||
@ -32,6 +33,11 @@ func NewUnis(_log *logger.Logger, conf *settings.UnisConfig) (res *UnisStation,
|
||||
return
|
||||
}
|
||||
|
||||
res.fsmService, err = newfsmService()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
res.commonService = newcommonService(res)
|
||||
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user