添加用户数据同步接口及,节点获取数据及系统定时任务添加

This commit is contained in:
junleea 2024-12-11 16:10:56 +08:00
parent 9755d73b86
commit 4918c54fc6
6 changed files with 194 additions and 17 deletions

View File

@ -101,3 +101,30 @@ func UpdateUserByID2(id int, req proto.UpdateUserInfoReq) {
func UpdateUserByID3(id int, req proto.UpdateUserInfoReq) { func UpdateUserByID3(id int, req proto.UpdateUserInfoReq) {
DB.Model(&User{}).Where("id = ?", id).Updates(User{Name: req.Username, Age: req.Age, Avatar: req.Avatar, Gender: req.Gender}) DB.Model(&User{}).Where("id = ?", id).Updates(User{Name: req.Username, Age: req.Age, Avatar: req.Avatar, Gender: req.Gender})
} }
// 用户数据同步-添加
func AddUserSync(req proto.UserAddOrUpdate) uint {
res := DB.Exec("insert into users (id, created_at, updated_at, deleted_at, name, age, email, password,gender,role,redis,run,upload,video_func,device_func,cid_func,avatar,create_time,update_time) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", req.ID, req.CreatedAt, req.UpdatedAt, req.DeletedAt, req.Name, req.Age, req.Email, req.Password, req.Gender, req.Role, req.Redis, req.Run, req.Upload, req.VideoFunc, req.DeviceFunc, req.CIDFunc, req.Avatar, req.CreateTime, req.UpdateTime)
if res.Error != nil {
return 0
}
return req.ID
}
// 用户数据同步-更新
func UpdateUserSync(req proto.UserAddOrUpdate) uint {
res := DB.Exec("update users set created_at=?, updated_at=?, deleted_at=?, name=?, age=?, email=?, password=?,gender=?,role=?,redis=?,run=?,upload=?,video_func=?,device_func=?,cid_func=?,avatar=?,create_time=?,update_time=? where id=?", req.CreatedAt, req.UpdatedAt, req.DeletedAt, req.Name, req.Age, req.Email, req.Password, req.Gender, req.Role, req.Redis, req.Run, req.Upload, req.VideoFunc, req.DeviceFunc, req.CIDFunc, req.Avatar, req.CreateTime, req.UpdateTime, req.ID)
if res.Error != nil {
return 0
}
return req.ID
}
// 用户数据同步-删除
func DeleteUserSync(req proto.UserDelID) uint {
res := DB.Delete(&User{}, req.ID)
if res.Error != nil {
return 0
}
return req.ID
}

41
main.go
View File

@ -13,6 +13,7 @@ import (
"videoplayer/dao" "videoplayer/dao"
"videoplayer/handler" "videoplayer/handler"
"videoplayer/proto" "videoplayer/proto"
"videoplayer/service"
"videoplayer/worker" "videoplayer/worker"
) )
@ -222,8 +223,25 @@ func ReadConfigToSetSystem() {
logClean.Every = 86400 logClean.Every = 86400
cron_infos = append(cron_infos, logClean) cron_infos = append(cron_infos, logClean)
} }
} }
if proto.Config.SERVER_USER_TYPE == "slave" && proto.Config.USER_SYNC_TIME > 0 {
var is_exist bool
for _, v := range cron_infos {
if v.Type == 2 {
is_exist = true
break
}
}
if !is_exist {
var userSync proto.CronInfo
userSync.Type = 2
userSync.Info = "user"
userSync.Curr = proto.Config.USER_SYNC_TIME
userSync.Every = proto.Config.USER_SYNC_TIME
cron_infos = append(cron_infos, userSync)
}
}
} else { } else {
if proto.Config.LOG_SAVE_DAYS > 0 { if proto.Config.LOG_SAVE_DAYS > 0 {
var logClean proto.CronInfo var logClean proto.CronInfo
@ -233,6 +251,14 @@ func ReadConfigToSetSystem() {
logClean.Every = 86400 logClean.Every = 86400
cron_infos = append(cron_infos, logClean) cron_infos = append(cron_infos, logClean)
} }
if proto.Config.SERVER_USER_TYPE == "slave" && proto.Config.USER_SYNC_TIME > 0 {
var userSync proto.CronInfo
userSync.Type = 2
userSync.Info = "user"
userSync.Curr = proto.Config.USER_SYNC_TIME
userSync.Every = proto.Config.USER_SYNC_TIME
cron_infos = append(cron_infos, userSync)
}
} }
//存入redis //存入redis
json_data, err := json.Marshal(cron_infos) json_data, err := json.Marshal(cron_infos)
@ -266,6 +292,18 @@ func RunGeneralCron() {
v.Curr -= 10 v.Curr -= 10
} }
} }
//2 从服务器同步数据
if v.Type == 2 {
if v.Curr <= 0 {
//执行从服务器同步数据
if proto.Config.SERVER_USER_TYPE == "slave" && v.Info == "user" {
go service.UserSyncDataFromMaster()
}
v.Curr = v.Every
} else {
v.Curr -= 10
}
}
} }
//存入redis //存入redis
json_data, err := json.Marshal(cron_infos) json_data, err := json.Marshal(cron_infos)
@ -274,7 +312,6 @@ func RunGeneralCron() {
} else { } else {
worker.SetRedis(key, string(json_data)) worker.SetRedis(key, string(json_data))
} }
} }
} }

View File

@ -63,20 +63,23 @@ type User struct {
} }
type ConfigStruct struct { type ConfigStruct struct {
DB int `json:"db"` // 0: mysql, 1: pg DB int `json:"db"` // 0: mysql, 1: pg
MYSQL_DSN string `json:"mysql_dsn"` MYSQL_DSN string `json:"mysql_dsn"`
PG_DSN string `json:"pg_dsn"` PG_DSN string `json:"pg_dsn"`
REDIS_ADDR string `json:"redis_addr"` REDIS_ADDR string `json:"redis_addr"`
TOKEN_USE_REDIS bool `json:"token_use_redis"` TOKEN_USE_REDIS bool `json:"token_use_redis"`
REDIS_User_PW bool `json:"redis_user_pw"` // 是否使用密码 REDIS_User_PW bool `json:"redis_user_pw"` // 是否使用密码
REDIS_PASSWORD string `json:"redis_password"` REDIS_PASSWORD string `json:"redis_password"`
REDIS_DB int `json:"redis_db"` REDIS_DB int `json:"redis_db"`
TOKEN_SECRET string `json:"token_secret"` TOKEN_SECRET string `json:"token_secret"`
CID_BASE_DIR string `json:"cid_base_dir"` CID_BASE_DIR string `json:"cid_base_dir"`
FILE_BASE_DIR string `json:"file_base_dir"` FILE_BASE_DIR string `json:"file_base_dir"`
MONITOR bool `json:"monitor"` // 状态监控及邮件通知 MONITOR bool `json:"monitor"` // 状态监控及邮件通知
SERVER_PORT string `json:"server_port"` // 服务端口 SERVER_PORT string `json:"server_port"` // 服务端口
LOG_SAVE_DAYS int `json:"log_save_days"` // 日志保存天数,-1表示不保存0表示永久保存 LOG_SAVE_DAYS int `json:"log_save_days"` // 日志保存天数,-1表示不保存0表示永久保存
SERVER_USER_TYPE string `json:"user_type"` // 服务器用户类型master: 主服务器slave: 从服务器,从服务器会定时同步数据
MASTER_SERVER_DOMAIN string `json:"master_server_domain"` // 主服务器域名
USER_SYNC_TIME int `json:"user_sync_time"` // 用户数据同步时间,单位秒
} }
// 读取配置文件 // 读取配置文件

View File

@ -1,5 +1,9 @@
package proto package proto
import (
"time"
)
type UpdateUserInfoReq struct { type UpdateUserInfoReq struct {
ID int `json:"id" form:"id"` //用户id ID int `json:"id" form:"id"` //用户id
Username string `json:"name" form:"name"` //用户名 Username string `json:"name" form:"name"` //用户名
@ -23,8 +27,41 @@ type CIDRUN struct {
// 用于执行函数,方法 // 用于执行函数,方法
type CronInfo struct { type CronInfo struct {
Type int `json:"type" form:"type"` //类型编码,1日志清理且只会有一个其他待定 Type int `json:"type" form:"type"` //类型编码,1日志清理且只会有一个其他待定2从服务器同步数据
Info string `json:"info" form:"info"` //信息 Info string `json:"info" form:"info"` //信息
Curr int `json:"curr" form:"curr"` //当前剩余时间每次执行减10s小于等于0则执行 Curr int `json:"curr" form:"curr"` //当前剩余时间每次执行减10s小于等于0则执行
Every int `json:"every" form:"every"` //每隔多少秒执行一次,小于等于0表示不执行时间粒度为10s Every int `json:"every" form:"every"` //每隔多少秒执行一次,小于等于0表示不执行时间粒度为10s
} }
// 用户数据同步
type UserSync struct {
Update []UserAddOrUpdate `json:"update" form:"update"` //更新用户
Add []UserAddOrUpdate `json:"add" form:"add"` //添加用户
Delete []UserDelID `json:"delete" form:"delete"` //删除用户
}
type UserDelID struct {
ID uint `json:"ID" form:"ID"` //用户id
}
type UserAddOrUpdate struct {
ID uint `json:"ID" form:"ID"` //用户id
CreatedAt time.Time `json:"CreatedAt" form:"CreatedAt"` //创建时间
UpdatedAt time.Time `json:"UpdatedAt" form:"UpdatedAt"` //更新时间
DeletedAt time.Time `json:"DeletedAt" form:"DeletedAt"` //删除时间
Name string `json:"Name" form:"Name"` //用户名
Age int `json:"Age" form:"Age"` //年龄
Email string `json:"Email" form:"Email"` //邮箱
Password string `json:"Password" form:"Password"` //密码
Gender string `json:"Gender" form:"Gender"` //性别
Role string `json:"Role" form:"Role"` //角色
Redis bool `json:"Redis" form:"Redis"` //是否刷新redis
Run bool `json:"Run" form:"Run"` //是否运行
Upload bool `json:"Upload" form:"Upload"` //是否上传头像
VideoFunc bool `json:"VideoFunc" form:"VideoFunc"` //视频功能
DeviceFunc bool `json:"DeviceFunc" form:"DeviceFunc"`
CIDFunc bool `json:"CIDFunc" form:"CIDFunc"`
Avatar string `json:"Avatar" form:"Avatar"` //头像
CreateTime string `json:"CreateTime" form:"CreateTime"`
UpdateTime string `json:"UpdateTime" form:"UpdateTime"`
}

View File

@ -4,6 +4,7 @@ import (
"regexp" "regexp"
"videoplayer/dao" "videoplayer/dao"
"videoplayer/proto" "videoplayer/proto"
"videoplayer/worker"
) )
func CreateUser(name, password, email, gender string, age int) uint { func CreateUser(name, password, email, gender string, age int) uint {
@ -55,3 +56,37 @@ func UpdateUser(user_id int, req proto.UpdateUserInfoReq) (int, error) {
return 0, nil return 0, nil
} }
} }
func UserSyncDataFromMaster() {
//从接口获取数据
url := "http://" + proto.Config.MASTER_SERVER_DOMAIN + "/user/sync"
tokens := worker.GetRedisSetMembers("super_permission_tokens")
user_sync_data := worker.SyncDataFromMasterReq(url, tokens[0])
add_users := user_sync_data.Add
update_users := user_sync_data.Update
delete_users := user_sync_data.Delete
//未成功操作的id
var fail_ids []uint
//添加用户
for _, v := range add_users {
res := dao.AddUserSync()
if res == 0 {
fail_ids = append(fail_ids, v.ID)
}
}
//更新用户
for _, v := range update_users {
res := dao.UpdateUserSync(v)
if res == 0 {
fail_ids = append(fail_ids, v.ID)
}
}
//删除用户
for _, v := range delete_users {
res := dao.DeleteUserSync(v)
if res == 0 {
fail_ids = append(fail_ids, v.ID)
}
}
}

View File

@ -3,10 +3,12 @@ package worker
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
"videoplayer/proto"
) )
var client *http.Client var client *http.Client
@ -80,3 +82,39 @@ func GenerateCompletion(url, prompt string, model string) (map[string]interface{
return result, nil return result, nil
} }
// 获取同步数据通用方法
func SyncDataFromMasterReq(url string, token string) proto.UserSync {
//从接口获取数据
req, err := http.NewRequest("POST", url, nil)
if err != nil {
return proto.UserSync{}
}
req.Header.Set("token", token)
client := &http.Client{}
//获取数据
resp, err := client.Do(req)
if err != nil {
return proto.UserSync{}
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return proto.UserSync{}
}
var result map[string]interface{}
err = json.Unmarshal(body, &result)
if err != nil {
return proto.UserSync{}
}
fmt.Println("SyncDataFromMasterReq result:", result)
if result["code"].(float64) != 0 {
return proto.UserSync{}
}
var userSync proto.UserSync
err = json.Unmarshal([]byte(result["data"].(string)), &userSync)
if err != nil {
return proto.UserSync{}
}
return userSync
}