feat: init
This commit is contained in:
262
modules/web/route_device.go
Normal file
262
modules/web/route_device.go
Normal file
@@ -0,0 +1,262 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"dyproxy/.gen/model"
|
||||
"dyproxy/.gen/table"
|
||||
|
||||
"github.com/go-jet/jet/v2/qrm"
|
||||
. "github.com/go-jet/jet/v2/sqlite"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/samber/lo"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type ExpertConfig struct {
|
||||
Voice string
|
||||
Hello string
|
||||
Wechat string
|
||||
Region []string
|
||||
NameKeyword []string
|
||||
Produce bool
|
||||
DefaultName bool
|
||||
DefaultAvatar bool
|
||||
}
|
||||
|
||||
func (s *WebServer) routeGetDevices(c fiber.Ctx) error {
|
||||
devices := []model.Device{}
|
||||
stmt := table.Device.SELECT(table.Device.AllColumns).ORDER_BY(table.Device.ID)
|
||||
if err := stmt.QueryContext(c.UserContext(), s.db, &devices); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expertsIds := lo.FilterMap(devices, func(device model.Device, _ int) (Expression, bool) {
|
||||
if device.Expert == "" {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return String(device.Expert), true
|
||||
})
|
||||
|
||||
if len(expertsIds) == 0 {
|
||||
return c.JSON(devices)
|
||||
}
|
||||
|
||||
type listDevice struct {
|
||||
model.Device `json:",inline"`
|
||||
ExpertName string
|
||||
}
|
||||
|
||||
// find experts by ids
|
||||
experts := []model.Expert{}
|
||||
stmt = table.Expert.SELECT(table.Expert.AllColumns).WHERE(table.Expert.UID.IN(expertsIds...))
|
||||
if err := stmt.QueryContext(c.UserContext(), s.db, &experts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expertsMap := make(map[string]string)
|
||||
for _, expert := range experts {
|
||||
expertsMap[expert.UID] = expert.RealName
|
||||
}
|
||||
|
||||
list := make([]listDevice, 0, len(devices))
|
||||
for _, device := range devices {
|
||||
if expertName, ok := expertsMap[device.Expert]; ok {
|
||||
list = append(list, listDevice{
|
||||
Device: device,
|
||||
ExpertName: expertName,
|
||||
})
|
||||
} else {
|
||||
list = append(list, listDevice{
|
||||
Device: device,
|
||||
ExpertName: "未设置",
|
||||
})
|
||||
}
|
||||
}
|
||||
return c.JSON(list)
|
||||
}
|
||||
|
||||
func (s *WebServer) routeGetDevice(c fiber.Ctx) error {
|
||||
deviceID := c.Params("uuid")
|
||||
var device model.Device
|
||||
err := table.Device.SELECT(table.Device.AllColumns).WHERE(table.Device.UUID.EQ(String(deviceID))).QueryContext(c.UserContext(), s.db, &device)
|
||||
if err != nil {
|
||||
if errors.Is(err, qrm.ErrNoRows) {
|
||||
// create new device
|
||||
device.UUID = deviceID
|
||||
_, err = table.Device.INSERT(table.Device.AllColumns.Except(table.Device.ID)).MODEL(device).ExecContext(c.UserContext(), s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.JSON(nil)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(device)
|
||||
}
|
||||
|
||||
func (s *WebServer) routeGetDeviceFollower(c fiber.Ctx) error {
|
||||
if s.pendingItems == nil {
|
||||
s.pendingItems = make(map[int32]time.Time)
|
||||
}
|
||||
|
||||
// get device
|
||||
deviceID := c.Params("uuid")
|
||||
var device model.Device
|
||||
err := table.Device.SELECT(table.Device.AllColumns).WHERE(table.Device.UUID.EQ(String(deviceID))).QueryContext(c.UserContext(), s.db, &device)
|
||||
if err != nil {
|
||||
if errors.Is(err, qrm.ErrNoRows) {
|
||||
// create new device
|
||||
device.UUID = deviceID
|
||||
_, err = table.Device.INSERT(table.Device.AllColumns.Except(table.Device.ID)).MODEL(device).ExecContext(c.UserContext(), s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.JSON(nil)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if device.Expert == "" {
|
||||
return c.JSON(nil)
|
||||
}
|
||||
|
||||
if device.State == StateStop {
|
||||
return c.JSON(nil)
|
||||
}
|
||||
|
||||
tbl := table.Follower
|
||||
|
||||
lastID := c.Query("last", "")
|
||||
if lastID != "" {
|
||||
id, err := strconv.Atoi(lastID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove from pending
|
||||
s.listLock.Lock()
|
||||
delete(s.pendingItems, int32(id))
|
||||
s.listLock.Unlock()
|
||||
|
||||
tbl.
|
||||
UPDATE(table.Follower.Followed).
|
||||
SET(Int32(1)).
|
||||
WHERE(table.Follower.ID.EQ(Int32(int32(id)))).
|
||||
ExecContext(c.UserContext(), s.db)
|
||||
}
|
||||
|
||||
pendingIDs := []Expression{}
|
||||
for i := range s.pendingItems {
|
||||
pendingIDs = append(pendingIDs, Int32(i))
|
||||
}
|
||||
|
||||
pendingIDs = []Expression{}
|
||||
|
||||
// get device expert
|
||||
|
||||
var expert model.Expert
|
||||
err = table.Expert.SELECT(table.Expert.AllColumns).WHERE(table.Expert.UID.EQ(String(device.Expert))).QueryContext(c.UserContext(), s.db, &expert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Response().Header.Set("x-expert-uid", expert.UID)
|
||||
c.Response().Header.Set("x-config-at", fmt.Sprintf("%d", expert.ConfigAt))
|
||||
|
||||
if expert.State == StateStop {
|
||||
return c.JSON(nil)
|
||||
}
|
||||
|
||||
condition := tbl.Followed.EQ(Int32(0)).
|
||||
AND(tbl.ExpertUID.EQ(String(device.Expert))).
|
||||
AND(tbl.ID.NOT_IN(pendingIDs...)).
|
||||
AND(tbl.CreatedAt.GT(Int32(expert.Since)))
|
||||
|
||||
stmt := tbl.
|
||||
SELECT(tbl.AllColumns).
|
||||
WHERE(condition).
|
||||
ORDER_BY(table.Follower.ID.DESC()).
|
||||
LIMIT(1)
|
||||
logrus.Debug(stmt.DebugSql())
|
||||
|
||||
var follower model.Follower
|
||||
if err := stmt.QueryContext(c.UserContext(), s.db, &follower); err != nil {
|
||||
if errors.Is(err, qrm.ErrNoRows) {
|
||||
return c.JSON(nil)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
s.listLock.Lock()
|
||||
s.pendingItems[int32(follower.ID)] = time.Now()
|
||||
s.listLock.Unlock()
|
||||
|
||||
return c.JSON(follower)
|
||||
}
|
||||
|
||||
// routeSetDeviceExpert
|
||||
func (s *WebServer) routeSetDeviceExpert(c fiber.Ctx) error {
|
||||
deviceID := c.Params("uuid")
|
||||
uid := c.Params("uid")
|
||||
|
||||
type body struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
b := &body{}
|
||||
if err := c.Bind().JSON(b); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var device model.Device
|
||||
err := table.Device.SELECT(table.Device.AllColumns).WHERE(table.Device.UUID.EQ(String(deviceID))).QueryContext(c.UserContext(), s.db, &device)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var expert model.Expert
|
||||
err = table.Expert.SELECT(table.Expert.UID).WHERE(table.Expert.UID.EQ(String(uid))).QueryContext(c.UserContext(), s.db, &expert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
device.Expert = expert.UID
|
||||
_, err = table.Device.UPDATE().SET(
|
||||
table.Device.Expert.SET(String(device.Expert)),
|
||||
table.Device.Name.SET(String(b.Name)),
|
||||
).WHERE(table.Device.UUID.EQ(String(deviceID))).ExecContext(c.UserContext(), s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(nil)
|
||||
}
|
||||
|
||||
func (s *WebServer) routePatchDeviceState(c fiber.Ctx) error {
|
||||
var state struct {
|
||||
State string `json:"state"`
|
||||
Note string `json:"note"`
|
||||
}
|
||||
if err := c.Bind().JSON(&state); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uuid := c.Params("uuid")
|
||||
|
||||
tbl := table.Device
|
||||
_, err := tbl.
|
||||
UPDATE().
|
||||
SET(
|
||||
tbl.State.SET(String(state.State)),
|
||||
tbl.Note.SET(String(state.Note)),
|
||||
).
|
||||
WHERE(tbl.UUID.EQ(String(uuid))).
|
||||
ExecContext(c.UserContext(), s.db)
|
||||
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user