videoplayer/service/userService.go

320 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"errors"
"fmt"
"regexp"
"strconv"
"time"
"videoplayer/dao"
"videoplayer/proto"
"videoplayer/worker"
)
func CreateUser(name, password, email, gender string, age int) uint {
id := dao.CreateUser(name, password, email, gender, age)
if id != 0 {
//添加用户信息到同步列表
err := setSyncUserDataSet("add", int(id))
if err != nil {
return id
}
}
return id
}
func GetUser(name, email, password string) dao.User {
emailRegex := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
re := regexp.MustCompile(emailRegex)
var user dao.User
if re.MatchString(name) {
user = dao.FindUserByEmail(name)
} else {
user = dao.FindUserByName(name)
}
if user.ID != 0 && user.Password == password {
return user
}
return dao.User{}
}
func ContainsUser(name, email string) bool {
user := dao.FindUserByName(name)
user2 := dao.FindUserByEmail(email)
if user.ID != 0 || user2.ID != 0 {
return true
}
return false
}
func GetUserByID(id int) []proto.User {
return dao.FindUserByID(id)
}
func GetUserByNameLike(name string) []proto.User {
return dao.FindUserByNameLike(name)
}
func UpdateUser(user_id int, req proto.UpdateUserInfoReq) (int, error) {
cur_user := dao.FindUserByID2(user_id)
//fmt.Println("cur_user:", cur_user, "req:", req)
if user_id == req.ID && cur_user.Role != "admin" {
err := dao.UpdateUserByID3(user_id, req) //用户修改自己的信息,不能修改权限信息
//添加修改用户信息到同步列表
if err == nil {
err2 := setSyncUserDataSet("update", user_id)
if err2 != nil {
fmt.Println("set sync user data set error:", err2)
return user_id, nil
}
}
return user_id, err
} else if cur_user.Role == "admin" {
err := dao.UpdateUserByID2(req.ID, req)
if err == nil {
//添加修改用户信息到同步列表
err2 := setSyncUserDataSet("update", req.ID)
if err2 != nil {
fmt.Println("set sync user data set error:", err2)
return req.ID, nil
}
}
return req.ID, nil
} else {
return 0, nil
}
}
func DeleteUserService(id, user_id int) int {
res := 0
if user_id == id {
res = dao.DeleteUserByID(id)
} else {
user := dao.FindUserByID2(user_id)
if user.Role == "admin" {
res = dao.DeleteUserByID(id)
}
}
if res != 0 {
//添加删除用户信息到同步列表
err := setSyncUserDataSet("delete", id)
if err != nil {
return res
}
}
return res
}
func UserSyncDataFromMaster() {
//从接口获取数据
url := "https://" + proto.Config.MASTER_SERVER_DOMAIN + "/user/sync"
tokens := worker.GetRedisSetMembers("super_permission_tokens")
var req proto.SyncUserReq
req.Token = tokens[0]
req.Device = proto.Config.SERVER_NAME
all := worker.GetRedis("user_sync_all")
var is_all bool //是否全量同步
if all == "" || all == "1" {
is_all = true
//清空数据表
err := dao.ClearAllUsers()
if err != nil {
fmt.Println("All ClearAllUsers error:", err)
return
}
worker.SetRedis("user_sync_all", "1")
req.Types = 1
} else {
worker.SetRedis("user_sync_all", "2")
req.Types = 2
}
user_sync_data, err := worker.SyncDataFromMasterReq2(url, req)
if err != nil {
fmt.Println("UserSyncDataFromMaster error:", err)
return
}
add_users := user_sync_data.Add
update_users := user_sync_data.Update
delete_users := user_sync_data.Delete
//未成功操作的id
var fail_ids []uint
//添加用户
var add_confirm []proto.UserConfirmID
for _, v := range add_users {
res := dao.AddUserSync(v)
if res == 0 {
fail_ids = append(fail_ids, v.ID)
} else {
add_confirm = append(add_confirm, proto.UserConfirmID{ID: v.ID})
}
}
//更新用户
var update_confirm []proto.UserConfirmID
for _, v := range update_users {
res := dao.UpdateUserSync(v)
if res == 0 {
fail_ids = append(fail_ids, v.ID)
} else {
update_confirm = append(update_confirm, proto.UserConfirmID{ID: v.ID})
}
}
//删除用户
var delete_confirm []proto.UserConfirmID
for _, v := range delete_users {
res := dao.DeleteUserSync(v)
if res == 0 {
fail_ids = append(fail_ids, v.ID)
} else {
delete_confirm = append(delete_confirm, proto.UserConfirmID{ID: v.ID})
}
}
//确认同步数据
if is_all == false {
var data proto.UserSyncConfirm
data.Add = add_confirm
data.Update = update_confirm
data.Delete = delete_confirm
//确认同步数据请求
var confirm_req proto.SyncUserReq
confirm_req.Token = tokens[0]
confirm_req.Device = proto.Config.SERVER_NAME
confirm_req.Types = 3
confirm_req.Confirm = data
worker.SyncDataFromMasterReq2(url, confirm_req)
} else {
worker.SetRedis("user_sync_all", "2")
}
}
// 同步数据到主服务器-增删改数据
func GetUserSyncData(device string) dao.UserSyncResp {
key := device + "_sync_user_ids"
add_temp_key := device + "_sync_user_ids_add_confirm_temp"
update_temp_key := device + "_sync_user_ids_update_confirm_temp"
delete_temp_key := device + "_sync_user_ids_delete_confirm_temp"
//需要获取暂存集合的并集,清空暂存集合,存入待确认集合
add_user_ids := worker.GetRedisSetUnion(key+"_add", add_temp_key)
update_user_ids := worker.GetRedisSetUnion(key+"_update", update_temp_key)
delete_user_ids := worker.GetRedisSetUnion(key+"_delete", delete_temp_key)
add_users := []dao.User{}
update_users := []dao.User{}
delete_users := []proto.UserDelID{}
for _, v := range add_user_ids {
id, _ := strconv.Atoi(v)
user := dao.FindUserByUserID(id)
add_users = append(add_users, user)
}
for _, v := range update_user_ids {
id, _ := strconv.Atoi(v)
user := dao.FindUserByUserID(id)
update_users = append(update_users, user)
}
for _, v := range delete_user_ids {
id, _ := strconv.Atoi(v)
delete_users = append(delete_users, proto.UserDelID{ID: uint(id)})
}
//将id存入暂存集合清空原集合存入待确认集合主要保证在确认时有新的数据加入不会在确认时漏掉
worker.SetRedisSetUnionAndStore(add_temp_key, key+"_add")
worker.ClearRedisSet(key + "_add")
worker.SetRedisSetUnionAndStore(update_temp_key, key+"_update")
worker.ClearRedisSet(key + "_update")
worker.SetRedisSetUnionAndStore(delete_temp_key, key+"_delete")
worker.ClearRedisSet(key + "_delete")
return dao.UserSyncResp{Add: add_users, Update: update_users, Delete: delete_users}
}
func setSyncUserDataSet(t string, id int) error {
devices := worker.GetRedisSetMembers("sync_devices_ids") //主服务器查看从服务器的设备列表
fmt.Println("set sync user data set devices:", devices, "t:", t, "id:", id)
var err error
for _, device := range devices {
key := device + "_sync_user_ids"
if t == "add" {
key_ := key + "_add"
worker.SetRedisSetAdd(key_, strconv.Itoa(id))
} else if t == "update" {
key_ := key + "_update"
worker.SetRedisSetAdd(key_, strconv.Itoa(id))
} else if t == "delete" {
key_ := key + "_delete"
worker.SetRedisSetAdd(key_, strconv.Itoa(id))
} else {
err = errors.New("error")
}
}
return err
}
// 确认同步数据
func ConfirmSyncUserData(device string, data proto.UserSyncConfirm) error {
var err error
if len(data.Add) > 0 {
var ids_add []string
for _, v := range data.Add {
ids_add = append(ids_add, strconv.Itoa(int(v.ID)))
}
add_key := device + "_sync_user_ids_add_confirm"
isSuccess := worker.SetRedisSetAddBatchWithExpire(add_key, ids_add, time.Second*30)
if !isSuccess {
err = errors.New("set add confirm error")
return err
}
ids_add_confirm_temp := device + "_sync_user_ids_add_confirm_temp"
//取差集
add_diff := worker.SetRedisSetDiffAndStore(ids_add_confirm_temp, add_key)
if add_diff == false {
err = errors.New("add diff error")
return err
}
}
if len(data.Update) > 0 {
var ids_update []string
for _, v := range data.Update {
ids_update = append(ids_update, strconv.Itoa(int(v.ID)))
}
update_key := device + "_sync_user_ids_update_confirm"
isSuccess := worker.SetRedisSetAddBatchWithExpire(update_key, ids_update, time.Second*30)
if !isSuccess {
err = errors.New("set update confirm error")
return err
}
ids_update_confirm_temp := device + "_sync_user_ids_update_confirm_temp"
update_diff := worker.SetRedisSetDiffAndStore(ids_update_confirm_temp, update_key)
if update_diff == false {
err = errors.New("update diff error")
return err
}
}
if len(data.Delete) > 0 {
var ids_delete []string
for _, v := range data.Delete {
ids_delete = append(ids_delete, strconv.Itoa(int(v.ID)))
}
del_key := device + "_sync_user_ids_delete_confirm"
isSuccess := worker.SetRedisSetAddBatchWithExpire(del_key, ids_delete, time.Second*30)
if !isSuccess {
err = errors.New("set del confirm error")
return err
}
//待确认集合暂存
ids_delete_confirm_temp := device + "_sync_user_ids_delete_confirm_temp"
delete_diff := worker.SetRedisSetDiffAndStore(ids_delete_confirm_temp, del_key)
if delete_diff == false {
err = errors.New("delete diff error")
return err
}
}
return err
}