feat: 新增账号状态
This commit is contained in:
parent
f6e1caad8b
commit
112d3907be
@ -170,27 +170,28 @@ func HandleError(c *gin.Context, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := CleanErrorMessage(err)
|
msg := CleanErrorMessage(err)
|
||||||
msgLower := strings.ToLower(msg)
|
|
||||||
|
|
||||||
// 根据错误类型返回对应的 HTTP 状态码
|
// 根据错误类型返回对应的 HTTP 状态码
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(msgLower, "not found") || strings.Contains(msgLower, "不存在"):
|
case strings.Contains(msg, "not found") || strings.Contains(msg, "不存在"):
|
||||||
NotFound(c, msg)
|
NotFound(c, msg)
|
||||||
case strings.Contains(msgLower, "unauthorized") ||
|
case strings.Contains(msg, "unauthorized") ||
|
||||||
strings.Contains(msgLower, "token") ||
|
strings.Contains(msg, "token") ||
|
||||||
strings.Contains(msgLower, "请先登录"):
|
strings.Contains(msg, "请先登录"):
|
||||||
Unauthorized(c, msg)
|
Unauthorized(c, msg)
|
||||||
case strings.Contains(msgLower, "invalid") ||
|
case strings.Contains(msg, "invalid") ||
|
||||||
strings.Contains(msgLower, "格式不正确") ||
|
strings.Contains(msg, "格式不正确") ||
|
||||||
strings.Contains(msgLower, "过长") ||
|
strings.Contains(msg, "过长") ||
|
||||||
strings.Contains(msgLower, "过短"):
|
strings.Contains(msg, "过短"):
|
||||||
BadRequest(c, msg)
|
BadRequest(c, msg)
|
||||||
case strings.Contains(msgLower, "already exists") ||
|
case strings.Contains(msg, "already exists") ||
|
||||||
strings.Contains(msgLower, "已被注册"):
|
strings.Contains(msg, "已被注册"):
|
||||||
Error(c, http.StatusConflict, msg)
|
Error(c, http.StatusConflict, msg)
|
||||||
case strings.Contains(msgLower, "forbidden") ||
|
case strings.Contains(msg, "forbidden") ||
|
||||||
strings.Contains(msgLower, "permission denied") ||
|
strings.Contains(msg, "permission denied") ||
|
||||||
strings.Contains(msgLower, "权限不足"):
|
strings.Contains(msg, "权限不足") ||
|
||||||
|
strings.Contains(msg, "账号已被冻结") ||
|
||||||
|
strings.Contains(msg, "账号已被封禁"):
|
||||||
Forbidden(c, msg)
|
Forbidden(c, msg)
|
||||||
default:
|
default:
|
||||||
InternalError(c, msg)
|
InternalError(c, msg)
|
||||||
|
|||||||
@ -55,6 +55,10 @@ var (
|
|||||||
ErrInvalidAssetStatus = errors.New("资产状态无效")
|
ErrInvalidAssetStatus = errors.New("资产状态无效")
|
||||||
ErrInvalidMintOrderStatus = errors.New("订单状态无效")
|
ErrInvalidMintOrderStatus = errors.New("订单状态无效")
|
||||||
|
|
||||||
|
// 账号状态相关错误
|
||||||
|
ErrAccountFrozen = errors.New("账号已被冻结")
|
||||||
|
ErrAccountBanned = errors.New("账号已被封禁")
|
||||||
|
|
||||||
// 活动服务相关错误
|
// 活动服务相关错误
|
||||||
ErrActivityNotFound = errors.New("活动不存在")
|
ErrActivityNotFound = errors.New("活动不存在")
|
||||||
ErrActivityItemNotFound = errors.New("活动道具不存在")
|
ErrActivityItemNotFound = errors.New("活动道具不存在")
|
||||||
@ -79,7 +83,7 @@ func ToStatusCode(err error) pb.StatusCode {
|
|||||||
return pb.StatusCode_STATUS_BAD_REQUEST
|
return pb.StatusCode_STATUS_BAD_REQUEST
|
||||||
case ErrInvalidPassword, ErrInvalidToken, ErrTokenExpired, ErrTokenMismatch:
|
case ErrInvalidPassword, ErrInvalidToken, ErrTokenExpired, ErrTokenMismatch:
|
||||||
return pb.StatusCode_STATUS_UNAUTHORIZED
|
return pb.StatusCode_STATUS_UNAUTHORIZED
|
||||||
case ErrUserInactive:
|
case ErrAccountFrozen, ErrAccountBanned:
|
||||||
return pb.StatusCode_STATUS_FORBIDDEN
|
return pb.StatusCode_STATUS_FORBIDDEN
|
||||||
case ErrInvalidMobile, ErrPasswordTooShort, ErrInvalidStarID, ErrInvalidUserID, ErrMaxIdentitiesReached, ErrInvalidNickname:
|
case ErrInvalidMobile, ErrPasswordTooShort, ErrInvalidStarID, ErrInvalidUserID, ErrMaxIdentitiesReached, ErrInvalidNickname:
|
||||||
return pb.StatusCode_STATUS_BAD_REQUEST
|
return pb.StatusCode_STATUS_BAD_REQUEST
|
||||||
|
|||||||
67
backend/pkg/models/user_account_status.go
Normal file
67
backend/pkg/models/user_account_status.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UserAccountStatus 用户账号状态表模型
|
||||||
|
type UserAccountStatus struct {
|
||||||
|
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||||
|
UserID int64 `gorm:"not null;uniqueIndex:uk_user_account_status_user_id;column:user_id"`
|
||||||
|
Status string `gorm:"type:varchar(20);not null;column:status"` // frozen/normal/banned
|
||||||
|
Reason *string `gorm:"type:text;column:reason"` // 冻结/封号原因
|
||||||
|
FrozenUntil *int64 `gorm:"column:frozen_until"` // 冻结解封时间(毫秒时间戳)
|
||||||
|
CreatedAt int64 `gorm:"not null;column:created_at"`
|
||||||
|
UpdatedAt int64 `gorm:"not null;column:updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 指定表名
|
||||||
|
func (UserAccountStatus) TableName() string {
|
||||||
|
return "user_account_status"
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeCreate 创建前钩子
|
||||||
|
func (u *UserAccountStatus) BeforeCreate(tx *gorm.DB) error {
|
||||||
|
now := time.Now().UnixMilli()
|
||||||
|
u.CreatedAt = now
|
||||||
|
u.UpdatedAt = now
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeUpdate 更新前钩子
|
||||||
|
func (u *UserAccountStatus) BeforeUpdate(tx *gorm.DB) error {
|
||||||
|
u.UpdatedAt = time.Now().UnixMilli()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status constants
|
||||||
|
const (
|
||||||
|
AccountStatusNormal = "normal"
|
||||||
|
AccountStatusFrozen = "frozen"
|
||||||
|
AccountStatusBanned = "banned"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsNormal 判断账号状态是否正常
|
||||||
|
func (u *UserAccountStatus) IsNormal() bool {
|
||||||
|
return u.Status == AccountStatusNormal
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFrozen 判断账号是否被冻结
|
||||||
|
func (u *UserAccountStatus) IsFrozen() bool {
|
||||||
|
return u.Status == AccountStatusFrozen
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBanned 判断账号是否被封号
|
||||||
|
func (u *UserAccountStatus) IsBanned() bool {
|
||||||
|
return u.Status == AccountStatusBanned
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFrozenUntilTime 返回冻结解封时间(如果是被冻结状态)
|
||||||
|
func (u *UserAccountStatus) GetFrozenUntilTime() time.Time {
|
||||||
|
if u.FrozenUntil != nil {
|
||||||
|
return time.UnixMilli(*u.FrozenUntil)
|
||||||
|
}
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
@ -38,6 +38,9 @@ type UserRepository interface {
|
|||||||
|
|
||||||
// UpdateAvatar 更新用户头像
|
// UpdateAvatar 更新用户头像
|
||||||
UpdateAvatar(userID int64, avatarURL string) error
|
UpdateAvatar(userID int64, avatarURL string) error
|
||||||
|
|
||||||
|
// GetAccountStatus 获取用户账号状态
|
||||||
|
GetAccountStatus(userID int64) (*models.UserAccountStatus, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// userRepository 用户Repository实现
|
// userRepository 用户Repository实现
|
||||||
@ -228,3 +231,20 @@ func (r *userRepository) UpdateAvatar(userID int64, avatarURL string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAccountStatus 获取用户账号状态
|
||||||
|
func (r *userRepository) GetAccountStatus(userID int64) (*models.UserAccountStatus, error) {
|
||||||
|
if userID <= 0 {
|
||||||
|
return nil, errors.New("invalid user id")
|
||||||
|
}
|
||||||
|
|
||||||
|
var status models.UserAccountStatus
|
||||||
|
if err := r.db.Where("user_id = ?", userID).First(&status).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, nil // 没有记录表示正常
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &status, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -106,6 +106,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex';
|
||||||
import { validatePhone, validatePassword } from '@/utils/validator';
|
import { validatePhone, validatePassword } from '@/utils/validator';
|
||||||
import { AGREEMENT_CONTENT } from '@/utils/agreement';
|
import { AGREEMENT_CONTENT } from '@/utils/agreement';
|
||||||
@ -125,6 +126,22 @@ const agreementContent = ref('');
|
|||||||
const showAgreementDialog = ref(false);
|
const showAgreementDialog = ref(false);
|
||||||
const showTipDialog = ref(false);
|
const showTipDialog = ref(false);
|
||||||
|
|
||||||
|
// 获取页面参数(用于显示错误信息)
|
||||||
|
const getPageParams = () => {
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
if (pages.length > 0) {
|
||||||
|
const currentPage = pages[pages.length - 1]
|
||||||
|
if (currentPage.options && currentPage.options.error) {
|
||||||
|
errorMessage.value = decodeURIComponent(currentPage.options.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载时获取错误信息
|
||||||
|
onLoad(() => {
|
||||||
|
getPageParams()
|
||||||
|
})
|
||||||
|
|
||||||
// 获取协议内容
|
// 获取协议内容
|
||||||
const getAgreementContent = () => {
|
const getAgreementContent = () => {
|
||||||
return AGREEMENT_CONTENT;
|
return AGREEMENT_CONTENT;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// API 基础配置
|
// API 基础配置
|
||||||
const baseURL = 'http://101.132.250.62:8080'
|
// const baseURL = 'http://101.132.250.62:8080'
|
||||||
// const baseURL = 'http://192.168.110.60:8080'
|
// const baseURL = 'http://192.168.110.60:8080'
|
||||||
// const baseURL = 'http://localhost:8080'
|
const baseURL = 'http://localhost:8080'
|
||||||
|
|
||||||
// 是否使用模拟数据(开发调试时设为 true,后端API准备好后改为 false)
|
// 是否使用模拟数据(开发调试时设为 true,后端API准备好后改为 false)
|
||||||
const USE_MOCK_API = false
|
const USE_MOCK_API = false
|
||||||
@ -60,17 +60,18 @@ export function request(options) {
|
|||||||
if (res.data && res.data.code !== undefined) {
|
if (res.data && res.data.code !== undefined) {
|
||||||
if (res.data.code === 200) {
|
if (res.data.code === 200) {
|
||||||
resolve(res.data)
|
resolve(res.data)
|
||||||
} else if (res.data.code === 401 || res.data.code === 400 || res.data
|
} else if (res.data.code === 401 || res.data.code === 400 || res.data.code === 403) {
|
||||||
.code === 403) {
|
// 业务状态码401/400/403(未授权/冻结/封号),清除缓存并跳转到登录页
|
||||||
// 业务状态码401(未授权),清除缓存并跳转到登录页
|
|
||||||
uni.removeStorageSync('access_token')
|
uni.removeStorageSync('access_token')
|
||||||
uni.removeStorageSync('user')
|
uni.removeStorageSync('user')
|
||||||
|
|
||||||
|
// 保留错误消息用于显示
|
||||||
|
const errorMsg = res.data.message || '登录已过期,请重新登录'
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
url: '/pages/login/login'
|
url: '/pages/login/login?error=' + encodeURIComponent(errorMsg)
|
||||||
})
|
})
|
||||||
|
|
||||||
reject(new Error('登录已过期,请重新登录'))
|
reject(new Error(errorMsg))
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// 其他业务错误,返回包含 message 的错误
|
// 其他业务错误,返回包含 message 的错误
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user