修复用户和文件管理,增加文件预览
This commit is contained in:
+98
-44
@@ -1,42 +1,46 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
)
|
||||
|
||||
// FileInfo 文件信息模型
|
||||
// 对应 yz_files 表结构
|
||||
type FileInfo struct {
|
||||
ID int64 `orm:"column(id);auto" json:"id"`
|
||||
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
|
||||
|
||||
ID int64 `orm:"column(id);auto" json:"id"`
|
||||
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
|
||||
|
||||
// 用户关联信息(通过JWT认证获取)
|
||||
UserID int `orm:"column(user_id);default(0)" json:"user_id"`
|
||||
|
||||
UserID int `orm:"column(user_id);default(0)" json:"user_id"`
|
||||
|
||||
// 文件基础信息
|
||||
FileName string `orm:"column(file_name);size(255)" json:"file_name"`
|
||||
OriginalName string `orm:"column(original_name);size(255)" json:"original_name"`
|
||||
FilePath string `orm:"column(file_path);size(500)" json:"file_path"`
|
||||
FileURL string `orm:"column(file_url);size(500);null" json:"file_url"`
|
||||
FileSize int64 `orm:"column(file_size);default(0)" json:"file_size"`
|
||||
FileType string `orm:"column(file_type);size(50)" json:"file_type"`
|
||||
FileExt string `orm:"column(file_ext);size(20)" json:"file_ext"`
|
||||
|
||||
FileName string `orm:"column(file_name);size(255)" json:"file_name"`
|
||||
OriginalName string `orm:"column(original_name);size(255)" json:"original_name"`
|
||||
FilePath string `orm:"column(file_path);size(500)" json:"file_path"`
|
||||
FileURL string `orm:"column(file_url);size(500);null" json:"file_url"`
|
||||
FileSize int64 `orm:"column(file_size);default(0)" json:"file_size"`
|
||||
FileType string `orm:"column(file_type);size(50)" json:"file_type"`
|
||||
FileExt string `orm:"column(file_ext);size(20)" json:"file_ext"`
|
||||
MD5 string `orm:"column(md5);size(32);null" json:"md5"`
|
||||
|
||||
// 分类信息
|
||||
Category string `orm:"column(category);size(100)" json:"category"`
|
||||
SubCategory string `orm:"column(sub_category);size(100);null" json:"sub_category"`
|
||||
|
||||
Category string `orm:"column(category);size(100)" json:"category"`
|
||||
SubCategory string `orm:"column(sub_category);size(100);null" json:"sub_category"`
|
||||
|
||||
// 状态信息
|
||||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||||
IsPublic int8 `orm:"column(is_public);default(0)" json:"is_public"`
|
||||
|
||||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||||
IsPublic int8 `orm:"column(is_public);default(0)" json:"is_public"`
|
||||
|
||||
// 上传信息
|
||||
UploadBy string `orm:"column(upload_by);size(100)" json:"upload_by"`
|
||||
UploadTime time.Time `orm:"column(upload_time);type(datetime);auto_now_add" json:"upload_time"`
|
||||
|
||||
UploadBy string `orm:"column(upload_by);size(100)" json:"upload_by"`
|
||||
UploadTime time.Time `orm:"column(upload_time);type(datetime);auto_now_add" json:"upload_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time,omitempty"`
|
||||
|
||||
// 关联的用户信息(非数据库字段)
|
||||
User *User `orm:"-" json:"user,omitempty"`
|
||||
User *User `orm:"-" json:"user,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
@@ -44,6 +48,31 @@ func (f *FileInfo) TableName() string {
|
||||
return "yz_files"
|
||||
}
|
||||
|
||||
// CanPreview 判断文件是否可以在线预览
|
||||
func (f *FileInfo) CanPreview() bool {
|
||||
previewableExts := map[string]bool{
|
||||
// 图片格式
|
||||
".jpg": true,
|
||||
".jpeg": true,
|
||||
".png": true,
|
||||
".gif": true,
|
||||
".bmp": true,
|
||||
".webp": true,
|
||||
".svg": true,
|
||||
// 文档格式(仅支持 .docx,不支持旧的 .doc、Excel、PPT)
|
||||
".pdf": true,
|
||||
".txt": true,
|
||||
".docx": true,
|
||||
// 视频格式
|
||||
".mp4": true,
|
||||
".webm": true,
|
||||
// 音频格式
|
||||
".mp3": true,
|
||||
".wav": true,
|
||||
}
|
||||
return previewableExts[strings.ToLower(f.FileExt)]
|
||||
}
|
||||
|
||||
// GetAllFiles 获取所有文件信息
|
||||
func GetAllFiles() ([]*FileInfo, error) {
|
||||
o := orm.NewOrm()
|
||||
@@ -109,7 +138,7 @@ func UpdateFile(file *FileInfo) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteFile 删除文件信息(软删除,设置状态为0)
|
||||
// DeleteFile 删除文件信息(软删除,设置状态为0并记录删除时间)
|
||||
func DeleteFile(id int64) error {
|
||||
o := orm.NewOrm()
|
||||
file := &FileInfo{ID: id}
|
||||
@@ -117,7 +146,9 @@ func DeleteFile(id int64) error {
|
||||
return err
|
||||
}
|
||||
file.Status = 0
|
||||
_, err := o.Update(file, "Status")
|
||||
now := time.Now()
|
||||
file.DeleteTime = &now
|
||||
_, err := o.Update(file, "Status", "DeleteTime")
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -131,50 +162,73 @@ func HardDeleteFile(id int64) error {
|
||||
// GetFileStatistics 获取文件统计信息
|
||||
func GetFileStatistics(tenantID string) (map[string]interface{}, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
|
||||
// 总文件数
|
||||
totalCount, err := o.QueryTable("yz_files").Filter("tenant_id", tenantID).Filter("status", 1).Count()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// 总文件大小
|
||||
var totalSize int64
|
||||
err = o.Raw("SELECT COALESCE(SUM(file_size), 0) FROM yz_files WHERE tenant_id = ? AND status = 1", tenantID).QueryRow(&totalSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// 按分类统计
|
||||
var categoryStats []orm.Params
|
||||
_, err = o.Raw("SELECT category, COUNT(*) as count, COALESCE(SUM(file_size), 0) as size FROM yz_files WHERE tenant_id = ? AND status = 1 GROUP BY category", tenantID).Values(&categoryStats)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
return map[string]interface{}{
|
||||
"total_count": totalCount,
|
||||
"total_size": totalSize,
|
||||
"total_count": totalCount,
|
||||
"total_size": totalSize,
|
||||
"category_stats": categoryStats,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SearchFiles 搜索文件
|
||||
// SearchFiles 搜索文件(通过原始文件名搜索)
|
||||
func SearchFiles(keyword string, tenantID string) ([]*FileInfo, error) {
|
||||
o := orm.NewOrm()
|
||||
var files []*FileInfo
|
||||
|
||||
// 构建查询条件
|
||||
|
||||
// 构建查询条件 - 只通过原始文件名搜索
|
||||
qs := o.QueryTable("yz_files").Filter("tenant_id", tenantID).Filter("status", 1)
|
||||
|
||||
// 搜索文件名、原始文件名、分类(使用or条件)
|
||||
cond := orm.NewCondition()
|
||||
cond = cond.Or("file_name__icontains", keyword).
|
||||
Or("original_name__icontains", keyword).
|
||||
Or("category__icontains", keyword)
|
||||
|
||||
qs = qs.SetCond(cond)
|
||||
|
||||
|
||||
// 搜索原始文件名
|
||||
qs = qs.Filter("original_name__icontains", keyword)
|
||||
|
||||
_, err := qs.OrderBy("-upload_time").All(&files)
|
||||
return files, err
|
||||
}
|
||||
}
|
||||
|
||||
// GetFileByMD5 根据MD5获取文件信息(获取唯一的文件记录)
|
||||
func GetFileByMD5(md5 string) (*FileInfo, error) {
|
||||
o := orm.NewOrm()
|
||||
var file FileInfo
|
||||
err := o.QueryTable("yz_files").Filter("md5", md5).Filter("status", 1).OrderBy("upload_time").One(&file)
|
||||
if err == orm.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &file, nil
|
||||
}
|
||||
|
||||
// GetFileByMD5AndTenant 根据MD5和租户ID获取文件信息
|
||||
func GetFileByMD5AndTenant(md5 string, tenantID string) (*FileInfo, error) {
|
||||
o := orm.NewOrm()
|
||||
var file FileInfo
|
||||
err := o.QueryTable("yz_files").Filter("md5", md5).Filter("tenant_id", tenantID).Filter("status", 1).OrderBy("upload_time").One(&file)
|
||||
if err == orm.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &file, nil
|
||||
}
|
||||
|
||||
+35
-4
@@ -24,6 +24,8 @@ type User struct {
|
||||
Email string
|
||||
Avatar string
|
||||
Nickname string
|
||||
Status int `orm:"column(status);default(1)" json:"status"`
|
||||
Role int `orm:"column(role);default(0)" json:"role"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time"`
|
||||
LastLoginTime *time.Time `orm:"column(last_login_time);null;type(datetime)" json:"last_login_time"`
|
||||
}
|
||||
@@ -147,6 +149,20 @@ func GetAllUsers(tenantId int) []*User {
|
||||
return users
|
||||
}
|
||||
|
||||
// GetTenantUsers 获取指定租户下的所有用户(排除已删除的用户)
|
||||
func GetTenantUsers(tenantId int) ([]*User, error) {
|
||||
o := orm.NewOrm()
|
||||
var users []*User
|
||||
|
||||
// 查询指定租户下未删除的用户
|
||||
_, err := o.Raw("SELECT * FROM yz_users WHERE tenant_id = ? AND delete_time IS NULL ORDER BY id DESC", tenantId).QueryRows(&users)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询租户用户失败: %v", err)
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// GetUserInfo 根据用户ID或用户名获取用户
|
||||
func GetUserInfo(userId int, username string, tenantId int) (*User, error) {
|
||||
o := orm.NewOrm()
|
||||
@@ -221,7 +237,7 @@ func ValidateUser(username, password string, tenantName string) (*User, error) {
|
||||
}
|
||||
|
||||
// AddUser 向数据库添加新用户
|
||||
func AddUser(username, password, email, nickname, avatar string, tenantId int) (*User, error) {
|
||||
func AddUser(username, password, email, nickname, avatar string, tenantId, role int) (*User, error) {
|
||||
// 1. 验证租户是否存在且有效
|
||||
o := orm.NewOrm()
|
||||
var tenantExists bool
|
||||
@@ -258,11 +274,12 @@ func AddUser(username, password, email, nickname, avatar string, tenantId int) (
|
||||
user := &User{
|
||||
TenantId: tenantId,
|
||||
Username: username,
|
||||
Password: hashedPassword, // 存储加密后的密码
|
||||
Salt: salt, // 存储盐值(用于后续验证)
|
||||
Password: hashedPassword,
|
||||
Salt: salt,
|
||||
Email: email,
|
||||
Nickname: nickname,
|
||||
Avatar: avatar,
|
||||
Role: role, // 设置角色ID
|
||||
}
|
||||
|
||||
// 5. 插入数据库(使用之前定义的 o)
|
||||
@@ -276,7 +293,7 @@ func AddUser(username, password, email, nickname, avatar string, tenantId int) (
|
||||
}
|
||||
|
||||
// EditUser 更新用户信息
|
||||
func EditUser(id int, username, email, nickname, avatar string) (*User, error) {
|
||||
func EditUser(id int, username, email, nickname, avatar, status string, roleId int) (*User, error) {
|
||||
// 根据ID查询用户
|
||||
o := orm.NewOrm()
|
||||
user := &User{}
|
||||
@@ -307,6 +324,20 @@ func EditUser(id int, username, email, nickname, avatar string) (*User, error) {
|
||||
user.Avatar = avatar
|
||||
}
|
||||
|
||||
// 更新状态(将字符串转换为数字)
|
||||
if status != "" {
|
||||
if status == "active" {
|
||||
user.Status = 1
|
||||
} else if status == "inactive" {
|
||||
user.Status = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 更新角色ID
|
||||
if roleId > 0 {
|
||||
user.Role = roleId
|
||||
}
|
||||
|
||||
// 执行数据库更新
|
||||
_, err = o.Update(user)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user