检测是否绑定过wifi、绑定wifi、增加用户使用记录、获取用户使用记录、添加设备使用人、设备使用人列表

This commit is contained in:
2026-10-06 17:38:13 +08:00
parent cb53a94c75
commit 1825fff38b
22 changed files with 866 additions and 34 deletions
@@ -0,0 +1,25 @@
package dao
import (
"lone-services/pkg/utils"
)
type Group struct {
Id int64 `gorm:"column:id;type:int;not null;autoIncrement" json:"id"`
HostUserId int64 `gorm:"column:host_user_id;type:int;default:NULL" json:"host_user_id"` // 设备所有者ID
HostCode string `gorm:"column:host_code;type:varchar(255);default:NULL" json:"host_code"` // 设备号
UserId int64 `gorm:"column:user_id;type:int;default:NULL" json:"user_id"` // 用户ID
Status int32 `gorm:"column:status;type:tinyint(1);not null;default:1" json:"status"` // 状态,1为正常,2为禁用
}
type GroupInfo struct {
Id int64 `gorm:"column:id;type:int;not null;autoIncrement" json:"id"`
HostUserId int64 `gorm:"column:host_user_id;type:int;default:NULL" json:"host_user_id"` // 设备所有者ID
HostCode string `gorm:"column:host_code;type:varchar(255);default:NULL" json:"host_code"` // 设备号
UserId int64 `gorm:"column:user_id;type:int;default:NULL" json:"user_id"` // 用户ID
Status int32 `gorm:"column:status;type:tinyint(1);not null;default:1" json:"status"` // 状态,1为正常,2为禁用
UpdateTime utils.CustomTime `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;onUpdate:CURRENT_TIMESTAMP" json:"update_time"`
CreateTime utils.CustomTime `json:"create_time" gorm:"create_time"` // 时间
UserName string `json:"user_name" gorm:"-"`
UserAvatar string `json:"user_avatar" gorm:"-"`
}
+6 -4
View File
@@ -11,16 +11,18 @@ const (
)
type Wifi struct {
Id int64 `json:"id" gorm:"id"`
UserId int64 `json:"user_id" gorm:"user_id"` // 用户ID
UserType int32 `json:"user_type" gorm:"user_type"` // 用户类型,1为用户,2为门店
Done int32 `json:"done" gorm:"done"` // 是否配置了wifi,2为没有配置,1为配置了
Id int64 `json:"id" gorm:"id"`
UserId int64 `json:"user_id" gorm:"user_id"` // 用户ID
UserType int32 `json:"user_type" gorm:"user_type"` // 用户类型,1为用户,2为门店
HostCode string `json:"host_code" gorm:"host_code"` // 设备
Done int32 `json:"done" gorm:"done"` // 是否配置了wifi,2为没有配置,1为配置了
}
type WifiInfo struct {
Id int64 `json:"id" gorm:"id"`
UserId int64 `json:"user_id" gorm:"user_id"` // 用户ID
UserType int32 `json:"user_type" gorm:"user_type"` // 用户类型,1为用户,2为门店
HostCode string `json:"host_code" gorm:"host_code"` // 设备
Done int32 `json:"done" gorm:"done"` // 是否配置了wifi,2为没有配置,1为配置了
UpdateTime utils.CustomTime `json:"update_time" gorm:"update_time"`
CarteTime utils.CustomTime `json:"carte_time" gorm:"carte_time"`
@@ -0,0 +1,65 @@
package logic
import (
"context"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
"lone-services/services/percutaneous/internal/dao"
"lone-services/services/percutaneous/internal/model"
"lone-services/services/percutaneous/validator"
"strconv"
"lone-services/rpc/percutaneous/pb"
"lone-services/services/percutaneous/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type AddUserLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
BaseLogic
}
func NewAddUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddUserLogic {
return &AddUserLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *AddUserLogic) AddUser(in *percutaneous.AddUserRequest) (*percutaneous.Response, error) {
var v validator.GroupValidator
if fail := l.checkParams(in, &v); fail != nil {
return fail, nil
}
adminInfo := utils.GetUserFromCtx(l.ctx)
if adminInfo.ID < utils.NumberOne {
return l.fail(utils.ErrorNoLoginInfo)
}
w := modelbase.Params{Eq: map[string]string{
"host_code": in.HostCode,
"host_user_id": strconv.FormatInt(adminInfo.ID, utils.NumberTen),
"user_id": strconv.FormatInt(in.UserId, utils.NumberTen),
}}
var info dao.Group
err := model.GroupModel{}.Init().GetOne(w, &info)
if err != nil {
l.Logger.Error(err)
return l.fail(utils.Fail)
}
if info.Id < utils.NumberOne {
info.HostCode = in.HostCode
info.HostUserId = adminInfo.ID
info.UserId = in.UserId
err = model.GroupModel{}.Init().Create(&info)
if err != nil {
l.Logger.Error(err)
return l.fail(utils.Fail)
}
}
return l.ok(utils.NumberOne)
}
@@ -3,6 +3,8 @@ package logic
import (
"context"
"lone-services/pkg/utils"
"lone-services/services/percutaneous/internal/dao"
"lone-services/services/percutaneous/internal/model"
"lone-services/services/percutaneous/validator"
"lone-services/rpc/percutaneous/pb"
@@ -36,5 +38,21 @@ func (l *UseLogic) Use(in *percutaneous.UseRequest) (*percutaneous.Response, err
return l.fail(utils.ErrorNoLoginInfo)
}
return l.ok(nil)
stamp, err := utils.ParseCustomTime(in.Stamp)
if err != nil {
return l.fail(utils.Fail)
}
info := dao.UsedLog{
HostUserId: adminInfo.ID,
HostCode: in.HostCode,
UserId: in.UserId,
Data: in.Data,
Stamp: stamp,
Position: in.Position,
}
err = model.UsedLogModel{}.Init().Create(&info)
if err != nil {
return l.fail(utils.Fail)
}
return l.ok(utils.NumberOne)
}
@@ -2,9 +2,13 @@ package logic
import (
"context"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
"lone-services/rpc/percutaneous/pb"
"lone-services/services/percutaneous/internal/dao"
"lone-services/services/percutaneous/internal/model"
"lone-services/services/percutaneous/internal/svc"
"strconv"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -30,7 +34,33 @@ func (l *UsedLogLogic) UsedLog(in *percutaneous.UsedLogRequest) (*percutaneous.R
return l.fail(utils.ErrorNoLoginInfo)
}
//items.Items = info
//return l.ok(items)
return l.ok(nil)
var info []dao.UsedLogInfo
if in.Stamp != utils.StringEmpty {
w := modelbase.Params{
Eq: map[string]string{
"stamp": in.Stamp,
"user_id": strconv.FormatInt(adminInfo.ID, utils.NumberTen),
},
}
err := model.UsedLogModel{}.Init().Items(w, &info)
if err != nil {
l.Logger.Error(err)
return l.fail(utils.ErrorNotFund)
}
return l.ok(info)
} else {
w := modelbase.Params{
Page: int(in.Page),
Size: int(in.Size),
Order: "id desc",
Eq: map[string]string{"user_id": strconv.FormatInt(adminInfo.ID, utils.NumberTen)},
}
items, err := model.UsedLogModel{}.Init().Page(w, &info)
if err != nil {
l.Logger.Error(err)
return l.fail(utils.ErrorNotFund)
}
return l.ok(items)
}
}
@@ -0,0 +1,106 @@
package logic
import (
"context"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
user "lone-services/rpc/user/pb"
"lone-services/services/percutaneous/internal/dao"
"lone-services/services/percutaneous/internal/model"
"lone-services/services/percutaneous/validator"
"strconv"
"lone-services/rpc/percutaneous/pb"
"lone-services/services/percutaneous/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type UserItemsLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
BaseLogic
}
func NewUserItemsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserItemsLogic {
return &UserItemsLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *UserItemsLogic) UserItems(in *percutaneous.UserItemsRequest) (*percutaneous.Response, error) {
var v validator.GroupItemsValidator
if fail := l.checkParams(in, &v); fail != nil {
return fail, nil
}
adminInfo := utils.GetUserFromCtx(l.ctx)
if adminInfo.ID < utils.NumberOne {
return l.fail(utils.ErrorNoLoginInfo)
}
w := modelbase.Params{
Eq: map[string]string{
"host_user_id": strconv.FormatInt(adminInfo.ID, utils.NumberTen),
"host_code": in.HostCode,
"status": utils.StringStatusOk,
},
Page: int(in.Page),
Size: int(in.Size),
Order: "id desc",
}
var info []dao.GroupInfo
items, err := model.GroupModel{}.Init().Page(w, &info)
if err != nil {
logx.Errorf("get group err: %v", err)
return l.fail(utils.Fail)
}
var ids []int64
for _, item := range info {
ids = append(ids, item.UserId)
}
l.setUserItems(&info, ids)
items.Items = info
return l.ok(items)
}
func (l *UserItemsLogic) setUserItems(info *[]dao.GroupInfo, ids []int64) {
if len(ids) == utils.NumberZero {
return
}
cli, err := svc.GetRpcClient(l.svcCtx.UserName)
if err != nil {
logx.Errorf("get user err: %v", err)
return
}
client := user.NewUserClient(cli.Conn())
data := user.InternalUsersByIdsReq{
Ids: ids,
}
res, err := client.InternalUsersByIds(context.Background(), &data)
if err != nil {
logx.Errorf("get order err: %v", err)
return
}
type UserItem struct {
Name string `json:"name"`
Avatar string `json:"avatar"`
}
names := make(map[int64]UserItem)
for _, item := range res.Items {
names[item.Id] = UserItem{Name: item.Name, Avatar: item.Avatar}
}
for key, item := range *info {
(*info)[key].UserName = names[item.UserId].Name
(*info)[key].UserAvatar = names[item.UserId].Avatar
}
return
}
@@ -0,0 +1,30 @@
package logic
import (
"context"
"lone-services/rpc/percutaneous/pb"
"lone-services/services/percutaneous/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type WeatherLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewWeatherLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WeatherLogic {
return &WeatherLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *WeatherLogic) Weather(in *percutaneous.EmptyRequest) (*percutaneous.Response, error) {
// todo: add your logic here and delete this line
return &percutaneous.Response{}, nil
}
@@ -2,7 +2,10 @@ package logic
import (
"context"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
"lone-services/services/percutaneous/internal/dao"
"lone-services/services/percutaneous/internal/model"
"lone-services/services/percutaneous/validator"
"lone-services/rpc/percutaneous/pb"
@@ -36,5 +39,17 @@ func (l *WifiCheckLogic) WifiCheck(in *percutaneous.WifiCheckRequest) (*percutan
return l.fail(utils.ErrorNoLoginInfo)
}
return l.ok(nil)
w := modelbase.Params{Eq: map[string]string{"host_code": in.HostCode}}
var info dao.WifiInfo
err := model.WifiModel{}.Init().Items(w, &info)
if err != nil {
return l.fail(utils.Fail)
}
if info.Id < utils.NumberOne {
return l.ok(false)
}
if info.Done == dao.WifiNotDone {
return l.ok(false)
}
return l.ok(true)
}
@@ -2,7 +2,10 @@ package logic
import (
"context"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
"lone-services/services/percutaneous/internal/dao"
"lone-services/services/percutaneous/internal/model"
"lone-services/services/percutaneous/validator"
"lone-services/rpc/percutaneous/pb"
@@ -35,6 +38,30 @@ func (l *WifiSetLogic) WifiSet(in *percutaneous.WifiSetRequest) (*percutaneous.R
if adminInfo.ID < utils.NumberOne {
return l.fail(utils.ErrorNoLoginInfo)
}
return l.ok(nil)
w := modelbase.Params{Eq: map[string]string{"host_code": in.HostCode}}
var info dao.Wifi
err := model.WifiModel{}.Init().Items(w, &info)
if err != nil {
return l.fail(utils.Fail)
}
if info.Id < utils.NumberOne {
info.UserId = adminInfo.ID
info.UserType = int32(adminInfo.Type)
info.HostCode = in.HostCode
info.Done = dao.WifiDone
err = model.WifiModel{}.Init().Create(&info)
if err != nil {
return l.fail(utils.Fail)
}
return l.ok(utils.NumberOne)
}
if info.Done == dao.WifiNotDone {
info.Done = dao.WifiDone
_, err = model.WifiModel{}.Init().Edit(w, &info)
if err != nil {
return l.fail(utils.Fail)
}
return l.ok(utils.NumberOne)
}
return l.ok(utils.NumberOne)
}
@@ -0,0 +1,23 @@
package model
import (
"lone-services/pkg/modelbase"
"lone-services/services/percutaneous/internal/dao"
)
type GroupModel struct {
modelbase.Base
}
func (m GroupModel) TableName() string {
return modelbase.Prefix() + "group"
}
func (m GroupModel) Init() GroupModel {
m.Table = m.TableName()
return m
}
func (m GroupModel) Create(data *dao.Group) error {
return m.Base.Create(data)
}
@@ -42,3 +42,18 @@ func (s *PercutaneousServer) UsedLog(ctx context.Context, in *percutaneous.UsedL
l := logic.NewUsedLogLogic(ctx, s.svcCtx)
return l.UsedLog(in)
}
func (s *PercutaneousServer) AddUser(ctx context.Context, in *percutaneous.AddUserRequest) (*percutaneous.Response, error) {
l := logic.NewAddUserLogic(ctx, s.svcCtx)
return l.AddUser(in)
}
func (s *PercutaneousServer) UserItems(ctx context.Context, in *percutaneous.UserItemsRequest) (*percutaneous.Response, error) {
l := logic.NewUserItemsLogic(ctx, s.svcCtx)
return l.UserItems(in)
}
func (s *PercutaneousServer) Weather(ctx context.Context, in *percutaneous.EmptyRequest) (*percutaneous.Response, error) {
l := logic.NewWeatherLogic(ctx, s.svcCtx)
return l.Weather(in)
}
@@ -1,22 +1,94 @@
package svc
import (
"fmt"
"lone-services/pkg/discovery"
"lone-services/pkg/utils"
"lone-services/services/percutaneous/internal/config"
"net"
"strconv"
"sync"
"time"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/zrpc"
"gorm.io/gorm"
)
type rpcClientCacheEntry struct {
cli zrpc.Client
target string
expireAt time.Time
}
const rpcClientCacheTTL = 30 * time.Second //缓存过期时间
var (
rpcCacheLock sync.Mutex
rpcCache = make(map[string]*rpcClientCacheEntry)
)
func GetRpcClient(serviceName string) (zrpc.Client, error) {
if serviceName == utils.StringEmpty {
err := fmt.Errorf("rpc serviceName is empty")
logx.Error(err)
return nil, err
}
cacheKey := serviceName
rpcCacheLock.Lock()
entry, ok := rpcCache[cacheKey]
if ok && time.Now().Before(entry.expireAt) {
rpcCacheLock.Unlock()
return entry.cli, nil
}
delete(rpcCache, cacheKey)
rpcCacheLock.Unlock()
inst, err := discovery.Pick(serviceName)
if err != nil {
err = fmt.Errorf("discovery pick %s failed: %w", serviceName, err)
logx.Error(err)
return nil, err
}
target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen))
cli := zrpc.MustNewClient(zrpc.RpcClientConf{
Target: target,
Timeout: utils.RpcTimeOut, //rpc调用超时5s
})
rpcCacheLock.Lock()
rpcCache[cacheKey] = &rpcClientCacheEntry{
cli: cli,
target: target,
expireAt: time.Now().Add(rpcClientCacheTTL),
}
rpcCacheLock.Unlock()
return cli, nil
}
type ServiceContext struct {
Config config.Config
DB *gorm.DB
Prefix string
Config config.Config
DB *gorm.DB
Prefix string
UserName string
}
func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext {
//启动仅读取配置,不建立rpc连接 多个服务就多个
UserSvc := utils.GetConfigString("services.user")
if UserSvc == utils.StringEmpty {
logx.Error("config services.user empty")
}
return &ServiceContext{
Config: c,
DB: db,
Prefix: utils.GetConfigString("mysql.prefix"),
Config: c,
DB: db,
Prefix: utils.GetConfigString("mysql.prefix"),
UserName: UserSvc,
}
}
@@ -14,9 +14,12 @@ import (
)
type (
AddUserRequest = percutaneous.AddUserRequest
EmptyRequest = percutaneous.EmptyRequest
Response = percutaneous.Response
UseRequest = percutaneous.UseRequest
UsedLogRequest = percutaneous.UsedLogRequest
UserItemsRequest = percutaneous.UserItemsRequest
WifiCheckRequest = percutaneous.WifiCheckRequest
WifiSetRequest = percutaneous.WifiSetRequest
@@ -25,6 +28,9 @@ type (
WifiSet(ctx context.Context, in *WifiSetRequest, opts ...grpc.CallOption) (*Response, error)
Use(ctx context.Context, in *UseRequest, opts ...grpc.CallOption) (*Response, error)
UsedLog(ctx context.Context, in *UsedLogRequest, opts ...grpc.CallOption) (*Response, error)
AddUser(ctx context.Context, in *AddUserRequest, opts ...grpc.CallOption) (*Response, error)
UserItems(ctx context.Context, in *UserItemsRequest, opts ...grpc.CallOption) (*Response, error)
Weather(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*Response, error)
}
defaultPercutaneous struct {
@@ -57,3 +63,18 @@ func (m *defaultPercutaneous) UsedLog(ctx context.Context, in *UsedLogRequest, o
client := percutaneous.NewPercutaneousClient(m.cli.Conn())
return client.UsedLog(ctx, in, opts...)
}
func (m *defaultPercutaneous) AddUser(ctx context.Context, in *AddUserRequest, opts ...grpc.CallOption) (*Response, error) {
client := percutaneous.NewPercutaneousClient(m.cli.Conn())
return client.AddUser(ctx, in, opts...)
}
func (m *defaultPercutaneous) UserItems(ctx context.Context, in *UserItemsRequest, opts ...grpc.CallOption) (*Response, error) {
client := percutaneous.NewPercutaneousClient(m.cli.Conn())
return client.UserItems(ctx, in, opts...)
}
func (m *defaultPercutaneous) Weather(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*Response, error) {
client := percutaneous.NewPercutaneousClient(m.cli.Conn())
return client.Weather(ctx, in, opts...)
}
+2
View File
@@ -42,5 +42,7 @@
password = 'lLMLcuPpzSj'
port = 6379
db = 3
[services]
user = "user-service"
[encrypt]
data_key = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a" #内容数据,
Binary file not shown.
+28
View File
@@ -0,0 +1,28 @@
package validator
import "lone-services/pkg/validate"
// GroupValidator 查看列表
type GroupValidator struct {
HostCode string `validate:"required"`
UserId int64 `validate:"required"`
}
// GetMessage 查看列表 - 提示消息
func (p GroupValidator) GetMessage() validate.ValidatorMessages {
return validate.ValidatorMessages{
"HostCode.required": "设备不能为空",
"UserId.required": "用户不能为空",
}
}
type GroupItemsValidator struct {
HostCode string `validate:"required"`
}
// GetMessage 查看列表 - 提示消息
func (p GroupItemsValidator) GetMessage() validate.ValidatorMessages {
return validate.ValidatorMessages{
"HostCode.required": "设备不能为空",
}
}
+2 -2
View File
@@ -7,8 +7,8 @@ type UseValidator struct {
HostCode string `validate:"required"`
UserId int64 `validate:"required"`
Data string `validate:"required"`
Stamp int32 `validate:"required"`
Position string
Stamp string `validate:"required"`
Position int32
}
// GetMessage 查看列表 - 提示消息