feat: 新增账号状态
This commit is contained in:
parent
f6e1caad8b
commit
112d3907be
@ -170,27 +170,28 @@ func HandleError(c *gin.Context, err error) {
|
||||
}
|
||||
|
||||
msg := CleanErrorMessage(err)
|
||||
msgLower := strings.ToLower(msg)
|
||||
|
||||
// 根据错误类型返回对应的 HTTP 状态码
|
||||
switch {
|
||||
case strings.Contains(msgLower, "not found") || strings.Contains(msgLower, "不存在"):
|
||||
case strings.Contains(msg, "not found") || strings.Contains(msg, "不存在"):
|
||||
NotFound(c, msg)
|
||||
case strings.Contains(msgLower, "unauthorized") ||
|
||||
strings.Contains(msgLower, "token") ||
|
||||
strings.Contains(msgLower, "请先登录"):
|
||||
case strings.Contains(msg, "unauthorized") ||
|
||||
strings.Contains(msg, "token") ||
|
||||
strings.Contains(msg, "请先登录"):
|
||||
Unauthorized(c, msg)
|
||||
case strings.Contains(msgLower, "invalid") ||
|
||||
strings.Contains(msgLower, "格式不正确") ||
|
||||
strings.Contains(msgLower, "过长") ||
|
||||
strings.Contains(msgLower, "过短"):
|
||||
case strings.Contains(msg, "invalid") ||
|
||||
strings.Contains(msg, "格式不正确") ||
|
||||
strings.Contains(msg, "过长") ||
|
||||
strings.Contains(msg, "过短"):
|
||||
BadRequest(c, msg)
|
||||
case strings.Contains(msgLower, "already exists") ||
|
||||
strings.Contains(msgLower, "已被注册"):
|
||||
case strings.Contains(msg, "already exists") ||
|
||||
strings.Contains(msg, "已被注册"):
|
||||
Error(c, http.StatusConflict, msg)
|
||||
case strings.Contains(msgLower, "forbidden") ||
|
||||
strings.Contains(msgLower, "permission denied") ||
|
||||
strings.Contains(msgLower, "权限不足"):
|
||||
case strings.Contains(msg, "forbidden") ||
|
||||
strings.Contains(msg, "permission denied") ||
|
||||
strings.Contains(msg, "权限不足") ||
|
||||
strings.Contains(msg, "账号已被冻结") ||
|
||||
strings.Contains(msg, "账号已被封禁"):
|
||||
Forbidden(c, msg)
|
||||
default:
|
||||
InternalError(c, msg)
|
||||
|
||||
@ -55,6 +55,10 @@ var (
|
||||
ErrInvalidAssetStatus = errors.New("资产状态无效")
|
||||
ErrInvalidMintOrderStatus = errors.New("订单状态无效")
|
||||
|
||||
// 账号状态相关错误
|
||||
ErrAccountFrozen = errors.New("账号已被冻结")
|
||||
ErrAccountBanned = errors.New("账号已被封禁")
|
||||
|
||||
// 活动服务相关错误
|
||||
ErrActivityNotFound = errors.New("活动不存在")
|
||||
ErrActivityItemNotFound = errors.New("活动道具不存在")
|
||||
@ -79,7 +83,7 @@ func ToStatusCode(err error) pb.StatusCode {
|
||||
return pb.StatusCode_STATUS_BAD_REQUEST
|
||||
case ErrInvalidPassword, ErrInvalidToken, ErrTokenExpired, ErrTokenMismatch:
|
||||
return pb.StatusCode_STATUS_UNAUTHORIZED
|
||||
case ErrUserInactive:
|
||||
case ErrAccountFrozen, ErrAccountBanned:
|
||||
return pb.StatusCode_STATUS_FORBIDDEN
|
||||
case ErrInvalidMobile, ErrPasswordTooShort, ErrInvalidStarID, ErrInvalidUserID, ErrMaxIdentitiesReached, ErrInvalidNickname:
|
||||
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(userID int64, avatarURL string) error
|
||||
|
||||
// GetAccountStatus 获取用户账号状态
|
||||
GetAccountStatus(userID int64) (*models.UserAccountStatus, error)
|
||||
}
|
||||
|
||||
// userRepository 用户Repository实现
|
||||
@ -228,3 +231,20 @@ func (r *userRepository) UpdateAvatar(userID int64, avatarURL string) error {
|
||||
|
||||
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>
|
||||
import { ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { useStore } from 'vuex';
|
||||
import { validatePhone, validatePassword } from '@/utils/validator';
|
||||
import { AGREEMENT_CONTENT } from '@/utils/agreement';
|
||||
@ -125,6 +126,22 @@ const agreementContent = ref('');
|
||||
const showAgreementDialog = 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 = () => {
|
||||
return AGREEMENT_CONTENT;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// 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://localhost:8080'
|
||||
const baseURL = 'http://localhost:8080'
|
||||
|
||||
// 是否使用模拟数据(开发调试时设为 true,后端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.code === 200) {
|
||||
resolve(res.data)
|
||||
} else if (res.data.code === 401 || res.data.code === 400 || res.data
|
||||
.code === 403) {
|
||||
// 业务状态码401(未授权),清除缓存并跳转到登录页
|
||||
} else if (res.data.code === 401 || res.data.code === 400 || res.data.code === 403) {
|
||||
// 业务状态码401/400/403(未授权/冻结/封号),清除缓存并跳转到登录页
|
||||
uni.removeStorageSync('access_token')
|
||||
uni.removeStorageSync('user')
|
||||
|
||||
// 保留错误消息用于显示
|
||||
const errorMsg = res.data.message || '登录已过期,请重新登录'
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
url: '/pages/login/login?error=' + encodeURIComponent(errorMsg)
|
||||
})
|
||||
|
||||
reject(new Error('登录已过期,请重新登录'))
|
||||
reject(new Error(errorMsg))
|
||||
return
|
||||
} else {
|
||||
// 其他业务错误,返回包含 message 的错误
|
||||
|
||||
Loading…
Reference in New Issue
Block a user