2024-04-11 14:24:55 +08:00

285 lines
6.8 KiB
Go

package system
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"sun-panel/api/api_v1/common/apiReturn"
"sun-panel/api/api_v1/common/base"
"sun-panel/global"
"sun-panel/lib/cmn"
"sun-panel/lib/cmn/systemSetting"
"sun-panel/models"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
)
type LoginApi struct {
}
// 登录输入验证
type LoginLoginVerify struct {
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required,max=50"`
VCode string `json:"vcode" validate:"max=6"`
Email string `json:"email"`
}
type getTokenVerify struct {
Username string `json:"username" validate:"required"`
}
// @Summary 登录账号
// @Accept application/json
// @Produce application/json
// @Param LoginLoginVerify body LoginLoginVerify true "登陆验证信息"
// @Tags user
// @Router /login [post]
func (l LoginApi) Login(c *gin.Context) {
param := LoginLoginVerify{}
if err := c.ShouldBindJSON(&param); err != nil {
apiReturn.ErrorParamFomat(c, err.Error())
return
}
if errMsg, err := base.ValidateInputStruct(param); err != nil {
apiReturn.ErrorParamFomat(c, errMsg)
return
}
settings := systemSetting.ApplicationSetting{}
global.SystemSetting.GetValueByInterface("system_application", &settings)
mUser := models.User{}
var (
err error
info models.User
)
bToken := ""
param.Username = strings.TrimSpace(param.Username)
if info, err = mUser.GetUserInfoByUsernameAndPassword(param.Username, cmn.PasswordEncryption(param.Password)); err != nil {
// 未找到记录 账号或密码错误
if err == gorm.ErrRecordNotFound {
apiReturn.ErrorByCode(c, 1003)
return
} else {
// 未知错误
apiReturn.Error(c, err.Error())
return
}
}
// 停用或未激活
if info.Status != 1 {
apiReturn.ErrorByCode(c, 1004)
return
}
bToken = info.Token
if info.Token == "" {
// 生成token
buildTokenOver := false
for !buildTokenOver {
bToken = cmn.BuildRandCode(32, cmn.RAND_CODE_MODE2)
if _, err := mUser.GetUserInfoByToken(bToken); err != nil {
// 保存token
mUser.UpdateUserInfoByUserId(info.ID, map[string]interface{}{
"token": bToken,
})
buildTokenOver = true
}
}
info.Token = bToken
}
info.Password = ""
info.ReferralCode = ""
// global.UserToken.SetDefault(bToken, info)
cToken := uuid.NewString() + "-" + cmn.Md5(cmn.Md5("userId"+strconv.Itoa(int(info.ID))))
global.CUserToken.SetDefault(cToken, bToken)
global.Logger.Debug("token:", cToken, "|", bToken)
global.Logger.Debug(global.CUserToken.Get(cToken))
// 设置当前用户信息
c.Set("userInfo", info)
info.Token = cToken // 重要 采用cToken,隐藏真实token
apiReturn.SuccessData(c, info)
}
// 安全退出
func (l *LoginApi) Logout(c *gin.Context) {
// userInfo, _ := base.GetCurrentUserInfo(c)
cToken := c.GetHeader("token")
global.CUserToken.Delete(cToken)
apiReturn.Success(c)
}
/**
* @Author: wintsa
* @Date: 2024-04-09 11:01:55
* @LastEditors: wintsa
* @Description: token生成
* @return {*}
*/
func (l LoginApi) GetToken(c *gin.Context) {
param := getTokenVerify{}
if err := c.ShouldBindJSON(&param); err != nil {
apiReturn.ErrorParamFomat(c, err.Error())
return
}
if errMsg, err := base.ValidateInputStruct(param); err != nil {
apiReturn.ErrorParamFomat(c, errMsg)
return
}
fmt.Print("-----------2")
settings := systemSetting.ApplicationSetting{}
global.SystemSetting.GetValueByInterface("system_application", &settings)
fmt.Print("-----------2")
mUser := models.User{}
var (
err error
info models.User
)
bToken := ""
param.Username = strings.TrimSpace(param.Username)
info, err = mUser.GetUserInfoByUsername(param.Username)
if err != nil {
// 未找到记录 账号
if err == gorm.ErrRecordNotFound {
fmt.Print("-----------2")
client := &http.Client{}
data := url.Values{}
data.Set("appid", "a2a6cab8-42e2-46d0-b0d2-4013e6708103")
data.Set("loginid", param.Username)
// 创建 HTTP 请求
req, err := http.NewRequest("POST", "https://oa.zwgczx.com/ssologin/getToken", strings.NewReader(data.Encode()))
if err != nil {
panic(err)
}
// 设置请求头
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// 发送POST请求
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
if strings.Contains(string(body), "Token获取失败") {
fmt.Println("请求失败: Token获取失败")
apiReturn.ErrorNoAccess(c)
panic("请求失败: Token获取失败")
return
}
mUser := models.User{
Username: strings.TrimSpace(param.Username),
Password: cmn.PasswordEncryption("zw.123456"),
Name: param.Username,
HeadImage: "",
Status: 1,
Role: 2,
// Mail: param.Username, 不再保存邮箱账号字段
}
userInfo, err := mUser.CreateOne()
if err != nil {
apiReturn.ErrorDatabase(c, err.Error())
return
}
info = userInfo
} else {
// 未知错误
apiReturn.Error(c, err.Error())
return
}
}
// 停用或未激活
if info.Status != 1 {
apiReturn.ErrorByCode(c, 1004)
return
}
bToken = info.Token
if info.Token == "" {
// 生成token
buildTokenOver := false
for !buildTokenOver {
bToken = cmn.BuildRandCode(32, cmn.RAND_CODE_MODE2)
if _, err := mUser.GetUserInfoByToken(bToken); err != nil {
// 保存token
mUser.UpdateUserInfoByUserId(info.ID, map[string]interface{}{
"token": bToken,
})
buildTokenOver = true
}
}
info.Token = bToken
}
info.Password = ""
info.ReferralCode = ""
// global.UserToken.SetDefault(bToken, info)
cToken := uuid.NewString() + "-" + cmn.Md5(cmn.Md5("userId"+strconv.Itoa(int(info.ID))))
global.CUserToken.SetDefault(cToken, bToken)
global.Logger.Debug("token:", cToken, "|", bToken)
global.Logger.Debug(global.CUserToken.Get(cToken))
fmt.Println("info", info)
// 设置当前用户信息
c.Set("userInfo", info)
apiReturn.SuccessData(c, cToken)
}
/**
* @Author: wintsa
* @Date: 2024-04-09 11:02:30
* @LastEditors: wintsa
* @Description: token验证
* @return {*}
*/
func (l LoginApi) VerifyToken(c *gin.Context) {
// 从请求参数中获取 token
token := c.Query("token")
fmt.Println("---------------------------", token)
// 检查 token 的有效性(这里仅做示例,实际需要根据业务逻辑来验证)
if bToken, err := global.CUserToken.Get(token); err != false {
// Token 有效,返回验证成功的响应
mUser := models.User{}
userInfo, err := mUser.GetUserInfoByToken(bToken)
if err != nil {
apiReturn.ErrorNoAccess(c)
return
}
apiReturn.SuccessData(c, userInfo)
} else {
// Token 无效,返回验证失败的响应
apiReturn.ErrorNoAccess(c)
}
}