用户信息部分统一删除,之后所有用户信息走认证中心
This commit is contained in:
parent
79cf18a2ef
commit
ef55731bfa
|
|
@ -278,7 +278,7 @@ func UploadFileV2(c *gin.Context) {
|
||||||
|
|
||||||
//查看用户上传的所有文件大小是否超过限制
|
//查看用户上传的所有文件大小是否超过限制
|
||||||
userFileSpace := dao.GetUserFileSpace(id1)
|
userFileSpace := dao.GetUserFileSpace(id1)
|
||||||
user := service.GetUserByIDWithCache(id1)
|
user := service.GetUserByIDFromUserCenter(id1)
|
||||||
if userFileSpace.TotalSize > proto.UserMaxUploadSize && user.Role != "admin" {
|
if userFileSpace.TotalSize > proto.UserMaxUploadSize && user.Role != "admin" {
|
||||||
c.JSON(http.StatusOK, gin.H{"error": "user file space is full", "code": proto.NoUploadPermissions, "message": "failed"})
|
c.JSON(http.StatusOK, gin.H{"error": "user file space is full", "code": proto.NoUploadPermissions, "message": "failed"})
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -438,7 +438,7 @@ func checkAndSetModelTemperatureParam(modelParam *proto.ModelParam, data *proto.
|
||||||
func SendMessageForeignAI(c *gin.Context) {
|
func SendMessageForeignAI(c *gin.Context) {
|
||||||
id, _ := c.Get("user_id")
|
id, _ := c.Get("user_id")
|
||||||
userID := id.(int)
|
userID := id.(int)
|
||||||
user := service.GetUserByIDWithCache(userID)
|
user := service.GetUserByIDFromUserCenter(userID)
|
||||||
var resp proto.GenerateResp
|
var resp proto.GenerateResp
|
||||||
var req proto.SendMessageForeignAIRRequest
|
var req proto.SendMessageForeignAIRRequest
|
||||||
if user.Role == "admin" {
|
if user.Role == "admin" {
|
||||||
|
|
@ -471,7 +471,7 @@ func SendMessageForeignAI(c *gin.Context) {
|
||||||
func ReceiveMessageForeignAI(c *gin.Context) {
|
func ReceiveMessageForeignAI(c *gin.Context) {
|
||||||
id, _ := c.Get("user_id")
|
id, _ := c.Get("user_id")
|
||||||
userID := id.(int)
|
userID := id.(int)
|
||||||
user := service.GetUserByIDWithCache(userID)
|
user := service.GetUserByIDFromUserCenter(userID)
|
||||||
var resp proto.GenerateResp
|
var resp proto.GenerateResp
|
||||||
var req proto.ReceiveMessageForeignAIRRequest
|
var req proto.ReceiveMessageForeignAIRRequest
|
||||||
if user.Role == "admin" {
|
if user.Role == "admin" {
|
||||||
|
|
|
||||||
|
|
@ -972,7 +972,7 @@ func GetTextDocxSet(c *gin.Context) {
|
||||||
var resp proto.GenerateResp
|
var resp proto.GenerateResp
|
||||||
userID, _ := c.Get("user_id")
|
userID, _ := c.Get("user_id")
|
||||||
//查看用户是否是管理员
|
//查看用户是否是管理员
|
||||||
user := service.GetUserByIDWithCache(int(userID.(float64)))
|
user := service.GetUserByIDFromUserCenter(int(userID.(float64)))
|
||||||
if user.Role != "admin" {
|
if user.Role != "admin" {
|
||||||
resp.Code = proto.PermissionDenied
|
resp.Code = proto.PermissionDenied
|
||||||
resp.Message = "没有权限"
|
resp.Message = "没有权限"
|
||||||
|
|
|
||||||
2
main.go
2
main.go
|
|
@ -360,7 +360,7 @@ func RunGeneralCron() {
|
||||||
// 用户功能拦截,返回true表示拦截,false表示不拦截
|
// 用户功能拦截,返回true表示拦截,false表示不拦截
|
||||||
func UserFuncIntercept(id int, url string) bool {
|
func UserFuncIntercept(id int, url string) bool {
|
||||||
//先查看是否有权限
|
//先查看是否有权限
|
||||||
user := service.GetUserByIDWithCache(id)
|
user := service.GetUserByIDFromUserCenter(id)
|
||||||
//如果用户有权限,则不拦截
|
//如果用户有权限,则不拦截
|
||||||
for k, v := range proto.Per_menu_map {
|
for k, v := range proto.Per_menu_map {
|
||||||
if strings.Contains(url, k) {
|
if strings.Contains(url, k) {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ func CheckUploadRequestParameters(req *proto.FileUploadReq) error {
|
||||||
|
|
||||||
func CreateConfigFile(req *proto.AddConfigFileReq, userId int) error {
|
func CreateConfigFile(req *proto.AddConfigFileReq, userId int) error {
|
||||||
var err error
|
var err error
|
||||||
user := GetUserByIDWithCache(userId)
|
user := GetUserByIDFromUserCenter(userId)
|
||||||
if user.ID == 0 || user.Role != "admin" {
|
if user.ID == 0 || user.Role != "admin" {
|
||||||
err = fmt.Errorf("user not found or no permission")
|
err = fmt.Errorf("user not found or no permission")
|
||||||
return err
|
return err
|
||||||
|
|
@ -126,7 +126,7 @@ func CreateConfigFile(req *proto.AddConfigFileReq, userId int) error {
|
||||||
|
|
||||||
func DeleteConfigFile(req *proto.ConfigFileReq, userId int) error {
|
func DeleteConfigFile(req *proto.ConfigFileReq, userId int) error {
|
||||||
var err error
|
var err error
|
||||||
user := GetUserByIDWithCache(userId)
|
user := GetUserByIDFromUserCenter(userId)
|
||||||
if user.ID == 0 || user.Role != "admin" {
|
if user.ID == 0 || user.Role != "admin" {
|
||||||
err = fmt.Errorf("user not found or no permission")
|
err = fmt.Errorf("user not found or no permission")
|
||||||
return err
|
return err
|
||||||
|
|
@ -154,7 +154,7 @@ type ConfigFileService struct {
|
||||||
|
|
||||||
func (c *ConfigFileService) UpdateConfigFile(req *proto.ConfigFileReq, userId int) error {
|
func (c *ConfigFileService) UpdateConfigFile(req *proto.ConfigFileReq, userId int) error {
|
||||||
var err error
|
var err error
|
||||||
user := GetUserByIDWithCache(userId)
|
user := GetUserByIDFromUserCenter(userId)
|
||||||
if user.ID == 0 || user.Role != "admin" {
|
if user.ID == 0 || user.Role != "admin" {
|
||||||
err = fmt.Errorf("user not found or no permission")
|
err = fmt.Errorf("user not found or no permission")
|
||||||
return err
|
return err
|
||||||
|
|
@ -196,7 +196,7 @@ func (c *ConfigFileService) UpdateConfigFile(req *proto.ConfigFileReq, userId in
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigFileService) SearchOneConfigFile(req *proto.ConfigFileReq, userId int) ([]proto.SearchOneConfigFileResp, error) {
|
func (c *ConfigFileService) SearchOneConfigFile(req *proto.ConfigFileReq, userId int) ([]proto.SearchOneConfigFileResp, error) {
|
||||||
user := GetUserByIDWithCache(userId)
|
user := GetUserByIDFromUserCenter(userId)
|
||||||
if user.ID == 0 || user.Role != "admin" {
|
if user.ID == 0 || user.Role != "admin" {
|
||||||
return []proto.SearchOneConfigFileResp{}, fmt.Errorf("user not found or no permission")
|
return []proto.SearchOneConfigFileResp{}, fmt.Errorf("user not found or no permission")
|
||||||
}
|
}
|
||||||
|
|
@ -214,7 +214,7 @@ func (c *ConfigFileService) SearchOneConfigFile(req *proto.ConfigFileReq, userId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigFileService) SearchAllConfigFile(userId int) ([]dao.ConfigFile, error) {
|
func (c *ConfigFileService) SearchAllConfigFile(userId int) ([]dao.ConfigFile, error) {
|
||||||
user := GetUserByIDWithCache(userId)
|
user := GetUserByIDFromUserCenter(userId)
|
||||||
if user.ID == 0 || user.Role != "admin" {
|
if user.ID == 0 || user.Role != "admin" {
|
||||||
return []dao.ConfigFile{}, fmt.Errorf("user not found or no permission")
|
return []dao.ConfigFile{}, fmt.Errorf("user not found or no permission")
|
||||||
}
|
}
|
||||||
|
|
@ -331,7 +331,7 @@ func FindFileContent(userID int, userReq *proto.FileContentReq) ([]dao.FileConte
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateFileContent(userID, fileID int, fileContent string) (uint, error) {
|
func CreateFileContent(userID, fileID int, fileContent string) (uint, error) {
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.Role != "admin" {
|
if user.Role != "admin" {
|
||||||
return 0, errors.New("no permission")
|
return 0, errors.New("no permission")
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +349,7 @@ func CreateFileContent(userID, fileID int, fileContent string) (uint, error) {
|
||||||
|
|
||||||
func UpdateFileContent(userID, fileID int, fileContent string) (uint, error) {
|
func UpdateFileContent(userID, fileID int, fileContent string) (uint, error) {
|
||||||
fileAuth := dao.FindFileAuthByID(fileID)
|
fileAuth := dao.FindFileAuthByID(fileID)
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if fileAuth.ID == 0 {
|
if fileAuth.ID == 0 {
|
||||||
return 0, errors.New("file auth not found")
|
return 0, errors.New("file auth not found")
|
||||||
}
|
}
|
||||||
|
|
@ -370,7 +370,7 @@ func UpdateFileContent(userID, fileID int, fileContent string) (uint, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFileWillConvertContentFileList(userID int) ([]dao.File, error) {
|
func GetFileWillConvertContentFileList(userID int) ([]dao.File, error) {
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.Role != "admin" {
|
if user.Role != "admin" {
|
||||||
return nil, errors.New("no permission")
|
return nil, errors.New("no permission")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ func ReceiveSparkSession(userID, sessionID int, channel string, msg proto.WSMess
|
||||||
func CheckUserCreatePPTSessionPermission(userID int) error {
|
func CheckUserCreatePPTSessionPermission(userID int) error {
|
||||||
sessionCount := dao.FindUserSessionCount(userID, proto.SessionTypeUserCreatePPT)
|
sessionCount := dao.FindUserSessionCount(userID, proto.SessionTypeUserCreatePPT)
|
||||||
var err error
|
var err error
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.Role == "admin" {
|
if user.Role == "admin" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
// 创建模型信息
|
// 创建模型信息
|
||||||
func CreateModel(userID uint, modelType, url, parameter, description string) (error, uint) {
|
func CreateModel(userID uint, modelType, url, parameter, description string) (error, uint) {
|
||||||
//查看用户是否有权限创建模型
|
//查看用户是否有权限创建模型
|
||||||
user := GetUserByIDWithCache(int(userID))
|
user := GetUserByIDFromUserCenter(int(userID))
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return errors.New("user not exist"), 0
|
return errors.New("user not exist"), 0
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +60,7 @@ func FindModelByUserID(userID int) []dao.ModelResponse {
|
||||||
// 根据id删除模型
|
// 根据id删除模型
|
||||||
func DeleteModelByID(id, userID int) error {
|
func DeleteModelByID(id, userID int) error {
|
||||||
//查看用户是否有权限删除模型
|
//查看用户是否有权限删除模型
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
model := dao.FindModelByID(id, userID)
|
model := dao.FindModelByID(id, userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return errors.New("user not exist")
|
return errors.New("user not exist")
|
||||||
|
|
@ -79,7 +79,7 @@ func UpdateModelByID(id int, userID uint, modelType, url, parameter, description
|
||||||
|
|
||||||
func CreateFuncModel(userID, modelID int, name, info, function, modelIDs string) (error, uint) {
|
func CreateFuncModel(userID, modelID int, name, info, function, modelIDs string) (error, uint) {
|
||||||
//查看用户是否有权限创建模型
|
//查看用户是否有权限创建模型
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return errors.New("user not exist"), 0
|
return errors.New("user not exist"), 0
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ func CreateFuncModel(userID, modelID int, name, info, function, modelIDs string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindFuncModelByID(id, userID int) ([]dao.FunctionModel, error) {
|
func FindFuncModelByID(id, userID int) ([]dao.FunctionModel, error) {
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return nil, errors.New("user not exist")
|
return nil, errors.New("user not exist")
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +102,7 @@ func FindFuncModelByID(id, userID int) ([]dao.FunctionModel, error) {
|
||||||
|
|
||||||
// 根据userID查找功能模型
|
// 根据userID查找功能模型
|
||||||
func FindFuncModelByUserID(userID int) ([]dao.FunctionModel, error) {
|
func FindFuncModelByUserID(userID int) ([]dao.FunctionModel, error) {
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return nil, errors.New("user not exist")
|
return nil, errors.New("user not exist")
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ func FindFuncModelByUserID(userID int) ([]dao.FunctionModel, error) {
|
||||||
|
|
||||||
func DeleteFuncModelByID(id, userID int) error {
|
func DeleteFuncModelByID(id, userID int) error {
|
||||||
//查看用户是否有权限删除模型
|
//查看用户是否有权限删除模型
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
model := dao.FindFunctionModelByID(id, userID)
|
model := dao.FindFunctionModelByID(id, userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return errors.New("user not exist")
|
return errors.New("user not exist")
|
||||||
|
|
@ -130,7 +130,7 @@ func DeleteFuncModelByID(id, userID int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateFuncModelByID(id int, userID, modelID uint, name, info, function, modelIDs string) error {
|
func UpdateFuncModelByID(id int, userID, modelID uint, name, info, function, modelIDs string) error {
|
||||||
user := GetUserByIDWithCache(int(userID))
|
user := GetUserByIDFromUserCenter(int(userID))
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return errors.New("user not exist")
|
return errors.New("user not exist")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,7 @@ func HandleThirdPartyLoginStatus(state *proto.ThirdPartyLoginState, thirdPartyLo
|
||||||
} else {
|
} else {
|
||||||
thirdPartyUserInfo := thirdPartyUserInfoList[0]
|
thirdPartyUserInfo := thirdPartyUserInfoList[0]
|
||||||
//获取用户信息
|
//获取用户信息
|
||||||
user := GetUserByIDWithCache(thirdPartyUserInfo.UserID)
|
user := GetUserByIDFromUserCenter(thirdPartyUserInfo.UserID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
thirdPartyLoginStatus.Status = proto.ThirdPartyUserNotBinded
|
thirdPartyLoginStatus.Status = proto.ThirdPartyUserNotBinded
|
||||||
log.Println("get user by id error")
|
log.Println("get user by id error")
|
||||||
|
|
@ -370,7 +370,7 @@ func HandleThirdPartyLoginStatus(state *proto.ThirdPartyLoginState, thirdPartyLo
|
||||||
//字符串转int
|
//字符串转int
|
||||||
userID, _ := strconv.Atoi(userIDStr)
|
userID, _ := strconv.Atoi(userIDStr)
|
||||||
//根据用户ID获取用户信息
|
//根据用户ID获取用户信息
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
thirdPartyLoginStatus.Status = 4 //添加用户信息错误
|
thirdPartyLoginStatus.Status = 4 //添加用户信息错误
|
||||||
log.Println("get user by id error")
|
log.Println("get user by id error")
|
||||||
|
|
@ -412,7 +412,7 @@ func HandleThirdPartyLoginStatusV2(state *proto.ThirdPartyLoginState, thirdParty
|
||||||
} else {
|
} else {
|
||||||
thirdPartyUserInfo := thirdPartyUserInfoList[0]
|
thirdPartyUserInfo := thirdPartyUserInfoList[0]
|
||||||
//获取用户信息
|
//获取用户信息
|
||||||
user := GetUserByIDWithCache(thirdPartyUserInfo.UserID)
|
user := GetUserByIDFromUserCenter(thirdPartyUserInfo.UserID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
thirdPartyLoginStatus.Status = proto.ThirdPartyUserNotBinded
|
thirdPartyLoginStatus.Status = proto.ThirdPartyUserNotBinded
|
||||||
log.Println("get user by id error")
|
log.Println("get user by id error")
|
||||||
|
|
@ -439,7 +439,7 @@ func HandleThirdPartyLoginStatusV2(state *proto.ThirdPartyLoginState, thirdParty
|
||||||
//字符串转int
|
//字符串转int
|
||||||
userID, _ := strconv.Atoi(userIDStr)
|
userID, _ := strconv.Atoi(userIDStr)
|
||||||
//根据用户ID获取用户信息
|
//根据用户ID获取用户信息
|
||||||
user := GetUserByIDWithCache(userID)
|
user := GetUserByIDFromUserCenter(userID)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
thirdPartyLoginStatus.Status = 4 //添加用户信息错误
|
thirdPartyLoginStatus.Status = 4 //添加用户信息错误
|
||||||
log.Println("get user by id error")
|
log.Println("get user by id error")
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ func GetUserByID(id int) []dao.User {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户信息,有redis缓存
|
// 获取用户信息,有redis缓存
|
||||||
func GetUserByIDWithCache(id int) dao.User {
|
func GetUserByIDFromUserCenter(id int) dao.User {
|
||||||
if id <= 0 {
|
if id <= 0 {
|
||||||
return dao.User{}
|
return dao.User{}
|
||||||
}
|
}
|
||||||
|
|
@ -74,14 +74,14 @@ func GetUserByIDWithCache(id int) dao.User {
|
||||||
return dao.User{}
|
return dao.User{}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
user = dao.FindUserByID2(id)
|
user = GetUserInfoByIDFromUserCenterHttp(id)
|
||||||
if user.ID != 0 {
|
if user.ID != 0 {
|
||||||
userJson, err := json.Marshal(user)
|
userJson, err := json.Marshal(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("get user info , json marshal error:", err)
|
fmt.Println("get user info , json marshal error:", err)
|
||||||
return dao.User{}
|
return dao.User{}
|
||||||
}
|
}
|
||||||
success := worker.SetRedis(key, string(userJson))
|
success := worker.SetRedisWithExpire(key, string(userJson), time.Second*10)
|
||||||
if !success {
|
if !success {
|
||||||
fmt.Println("set redis error,user json:", string(userJson))
|
fmt.Println("set redis error,user json:", string(userJson))
|
||||||
}
|
}
|
||||||
|
|
@ -90,6 +90,39 @@ func GetUserByIDWithCache(id int) dao.User {
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserInfoResponse struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data dao.User `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserInfoByIDFromUserCenterHttp(id int) dao.User {
|
||||||
|
var resp UserInfoResponse
|
||||||
|
url := "https://uc.ljsea.top/user/info?super_id=1"
|
||||||
|
tokens := worker.GetRedisSetMembers("super_permission_tokens")
|
||||||
|
if len(tokens) == 0 {
|
||||||
|
return resp.Data
|
||||||
|
}
|
||||||
|
token := tokens[0]
|
||||||
|
//请求参数
|
||||||
|
req := map[string]int{
|
||||||
|
"id": id,
|
||||||
|
}
|
||||||
|
headers := map[string]string{
|
||||||
|
"token": token,
|
||||||
|
}
|
||||||
|
reqByte, _ := json.Marshal(req)
|
||||||
|
err, respBytes := worker.DoPostRequestJSON(url, reqByte, headers)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("GetUserInfoByIDFromUserCenterHttp error:", err)
|
||||||
|
return resp.Data
|
||||||
|
}
|
||||||
|
if err2 := json.Unmarshal(respBytes, &resp); err2 != nil {
|
||||||
|
log.Println("GetUserInfoByIDFromUserCenterHttp json unmarshal error:", err2)
|
||||||
|
}
|
||||||
|
return resp.Data
|
||||||
|
}
|
||||||
|
|
||||||
func GetUserByNameLike(name string) []dao.User {
|
func GetUserByNameLike(name string) []dao.User {
|
||||||
users := dao.FindUserByNameLike(name)
|
users := dao.FindUserByNameLike(name)
|
||||||
for i, _ := range users {
|
for i, _ := range users {
|
||||||
|
|
@ -452,7 +485,7 @@ func GetUserInfoByToken(token string) (dao.User, error) {
|
||||||
return user, errors.New("token is invalid")
|
return user, errors.New("token is invalid")
|
||||||
}
|
}
|
||||||
id := int(claims["id"].(float64))
|
id := int(claims["id"].(float64))
|
||||||
user = GetUserByIDWithCache(id)
|
user = GetUserByIDFromUserCenter(id)
|
||||||
if user.ID == 0 {
|
if user.ID == 0 {
|
||||||
return user, errors.New("user not found")
|
return user, errors.New("user not found")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue