Files

1214 lines
31 KiB
Go
Raw Permalink Normal View History

2025-08-03 00:11:15 +08:00
package service
import (
"context"
"fmt"
"strings"
"time"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"nl-video-api/internal/dao"
"nl-video-api/internal/model/entity"
"nl-video-api/utility/response"
)
// AttachmentService 附件管理服务
type AttachmentService struct{}
// NewAttachmentService 创建附件管理服务实例
func NewAttachmentService() *AttachmentService {
return &AttachmentService{}
}
// 定义请求和响应结构体,避免循环导入
type AttachmentListReq struct {
Page int `json:"page"`
Size int `json:"size"`
Type string `json:"type"`
Category string `json:"category"`
Keyword string `json:"keyword"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
MinSize int64 `json:"min_size"`
MaxSize int64 `json:"max_size"`
UserId uint `json:"user_id"`
}
type AttachmentListRes struct {
List []AttachmentItem `json:"list"`
Total int `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
}
type AttachmentItem struct {
Id uint `json:"id"`
Filename string `json:"filename"`
OriginalName string `json:"original_name"`
Url string `json:"url"`
Size int64 `json:"size"`
Type string `json:"type"`
Category string `json:"category"`
Description string `json:"description"`
UserId uint `json:"user_id"`
Username string `json:"username"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
type AttachmentDetailReq struct {
Id uint `json:"id"`
}
type AttachmentDetailRes struct {
Attachment AttachmentDetail `json:"attachment"`
}
type AttachmentDetail struct {
Id uint `json:"id"`
Filename string `json:"filename"`
OriginalName string `json:"original_name"`
Url string `json:"url"`
Size int64 `json:"size"`
Type string `json:"type"`
Category string `json:"category"`
Description string `json:"description"`
UserId uint `json:"user_id"`
Username string `json:"username"`
DownloadCount int `json:"download_count"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
type AttachmentUpdateReq struct {
Id uint `json:"id"`
Category string `json:"category"`
Description string `json:"description"`
}
type AttachmentDeleteReq struct {
Id uint `json:"id"`
}
type AttachmentBatchDeleteReq struct {
Ids []uint `json:"ids"`
}
type AttachmentDownloadReq struct {
Id uint `json:"id"`
}
type AttachmentDownloadRes struct {
Url string `json:"url"`
Filename string `json:"filename"`
}
type AttachmentCategoryListReq struct {
Type string `json:"type"`
}
type AttachmentCategoryListRes struct {
Categories []AttachmentCategoryItem `json:"categories"`
}
type AttachmentCategoryItem struct {
Category string `json:"category"`
Count int `json:"count"`
}
type AttachmentStatisticsReq struct {
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Type string `json:"type"`
}
type AttachmentStatisticsRes struct {
TotalCount int `json:"total_count"`
TotalSize int64 `json:"total_size"`
TypeStats []AttachmentTypeStatItem `json:"type_stats"`
CategoryStats []AttachmentCategoryStatItem `json:"category_stats"`
UploadChart []AttachmentUploadChartItem `json:"upload_chart"`
SizeChart []AttachmentSizeChartItem `json:"size_chart"`
PopularFiles []AttachmentPopularItem `json:"popular_files"`
RecentUploads []AttachmentRecentItem `json:"recent_uploads"`
}
type AttachmentTypeStatItem struct {
Type string `json:"type"`
Count int `json:"count"`
Size int64 `json:"size"`
Percentage string `json:"percentage"`
}
type AttachmentCategoryStatItem struct {
Category string `json:"category"`
Count int `json:"count"`
Size int64 `json:"size"`
Percentage string `json:"percentage"`
}
type AttachmentUploadChartItem struct {
Date string `json:"date"`
Count int `json:"count"`
Size int64 `json:"size"`
}
type AttachmentSizeChartItem struct {
SizeRange string `json:"size_range"`
Count int `json:"count"`
}
type AttachmentPopularItem struct {
Id uint `json:"id"`
Filename string `json:"filename"`
Type string `json:"type"`
Size int64 `json:"size"`
DownloadCount int `json:"download_count"`
CreatedAt int64 `json:"created_at"`
}
type AttachmentRecentItem struct {
Id uint `json:"id"`
Filename string `json:"filename"`
OriginalName string `json:"original_name"`
Type string `json:"type"`
Size int64 `json:"size"`
UserId uint `json:"user_id"`
Username string `json:"username"`
CreatedAt int64 `json:"created_at"`
}
type AttachmentMoveReq struct {
Ids []uint `json:"ids"`
NewCategory string `json:"new_category"`
}
type AttachmentCopyReq struct {
Id uint `json:"id"`
NewCategory string `json:"new_category"`
Description string `json:"description"`
}
type AttachmentCopyRes struct {
Id uint `json:"id"`
Filename string `json:"filename"`
Url string `json:"url"`
}
type AttachmentRenameReq struct {
Id uint `json:"id"`
Filename string `json:"filename"`
}
type AttachmentSearchReq struct {
Query string `json:"query"`
Type string `json:"type"`
Category string `json:"category"`
Page int `json:"page"`
Size int `json:"size"`
}
type AttachmentSearchRes struct {
List []AttachmentItem `json:"list"`
Total int `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
}
type AttachmentUserListReq struct {
Page int `json:"page"`
Size int `json:"size"`
Type string `json:"type"`
Category string `json:"category"`
Keyword string `json:"keyword"`
}
type AttachmentUserListRes struct {
List []AttachmentUserItem `json:"list"`
Total int `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
}
type AttachmentUserItem struct {
Id uint `json:"id"`
Filename string `json:"filename"`
OriginalName string `json:"original_name"`
Url string `json:"url"`
Size int64 `json:"size"`
Type string `json:"type"`
Category string `json:"category"`
Description string `json:"description"`
CreatedAt int64 `json:"created_at"`
}
// Upload 上传附件
func (s *AttachmentService) Upload(r *ghttp.Request) {
// 获取请求参数
attachmentType := r.Get("type").String()
category := r.Get("category").String()
description := r.Get("description").String()
_ = description // 避免未使用变量错误
// 获取当前用户ID
userId := uint(1) // 临时设置,实际应该从请求中获取
if userId == 0 {
response.Error(r, response.CodeUnauthorized, "用户未登录")
return
}
// 这里应该处理文件上传逻辑
// 由于这是API结构设计,暂时模拟文件上传结果
filename := fmt.Sprintf("%s_%d.%s", attachmentType, time.Now().Unix(), "jpg")
url := fmt.Sprintf("/uploads/%s/%s", category, filename)
size := int64(1024 * 100) // 模拟文件大小
// 保存附件信息到数据库
data := &entity.Attachment{
Name: filename,
Path: url, // 使用URL作为路径
Url: url,
Size: size,
MimeType: attachmentType,
Extension: "jpg", // 从文件名提取扩展名
UserId: int(userId),
Status: 1, // 默认启用
CreatedAt: gtime.Now(),
UpdatedAt: gtime.Now(),
}
id, err := dao.Attachment.Ctx(r.Context()).Data(data).InsertAndGetId()
if err != nil {
response.Error(r, response.CodeInternalError, "保存附件信息失败")
return
}
response.Success(r, g.Map{
"id": uint(id),
"name": filename,
"url": url,
"size": size,
"type": attachmentType,
})
}
// List 获取附件列表
func (s *AttachmentService) List(ctx context.Context, req *AttachmentListReq) (*AttachmentListRes, error) {
// 设置默认值
if req.Page <= 0 {
req.Page = 1
}
if req.Size <= 0 {
req.Size = 10
}
// 构建查询条件
query := dao.Attachment.Ctx(ctx)
// 类型筛选
if req.Type != "" {
query = query.Where("mime_type", req.Type)
}
// 关键词搜索
if req.Keyword != "" {
keyword := "%" + req.Keyword + "%"
query = query.Where("name LIKE ?", keyword)
}
// 日期范围筛选
if req.StartDate != "" {
query = query.Where("created_at >= ?", req.StartDate+" 00:00:00")
}
if req.EndDate != "" {
query = query.Where("created_at <= ?", req.EndDate+" 23:59:59")
}
// 文件大小筛选
if req.MinSize > 0 {
query = query.Where("size >= ?", req.MinSize)
}
if req.MaxSize > 0 {
query = query.Where("size <= ?", req.MaxSize)
}
// 用户筛选
if req.UserId > 0 {
query = query.Where("user_id", req.UserId)
}
// 获取总数
total, err := query.Count()
if err != nil {
return nil, gerror.New("获取附件总数失败")
}
// 获取列表数据
var attachments []entity.Attachment
err = query.Order("id DESC").
Limit((req.Page-1)*req.Size, req.Size).
Scan(&attachments)
if err != nil {
return nil, gerror.New("获取附件列表失败")
}
// 获取用户信息
userIds := make([]int, 0, len(attachments))
for _, attachment := range attachments {
userIds = append(userIds, attachment.UserId)
}
userMap := make(map[int]string)
if len(userIds) > 0 {
var users []entity.NlUser
g.DB().Model("nl_user").WhereIn("id", userIds).Fields("id, username").Scan(&users)
for _, user := range users {
userMap[int(user.Id)] = user.Username
}
}
// 转换为响应格式
list := make([]AttachmentItem, 0, len(attachments))
for _, attachment := range attachments {
username := userMap[attachment.UserId]
list = append(list, AttachmentItem{
Id: attachment.Id,
Filename: attachment.Name,
OriginalName: attachment.Name, // 使用Name作为原始名称
Url: attachment.Url,
Size: attachment.Size,
Type: attachment.MimeType,
Category: "default", // 默认分类
Description: "", // 默认描述
UserId: uint(attachment.UserId),
Username: username,
CreatedAt: attachment.CreatedAt.Unix(),
UpdatedAt: attachment.UpdatedAt.Unix(),
})
}
return &AttachmentListRes{
List: list,
Total: total,
Page: req.Page,
Size: req.Size,
}, nil
}
// Detail 获取附件详情
func (s *AttachmentService) Detail(ctx context.Context, req *AttachmentDetailReq) (*AttachmentDetailRes, error) {
var attachment entity.Attachment
err := dao.Attachment.Ctx(ctx).Where("id", req.Id).Scan(&attachment)
if err != nil {
return nil, gerror.New("获取附件详情失败")
}
if attachment.Id == 0 {
return nil, gerror.New("附件不存在")
}
// 获取用户信息
var user entity.NlUser
g.DB().Model("nl_user").Where("id", attachment.UserId).Fields("username").Scan(&user)
return &AttachmentDetailRes{
Attachment: AttachmentDetail{
Id: attachment.Id,
Filename: attachment.Name,
OriginalName: attachment.Name,
Url: attachment.Url,
Size: attachment.Size,
Type: attachment.MimeType,
Category: "default",
Description: "",
UserId: uint(attachment.UserId),
Username: user.Username,
DownloadCount: 0, // 实体中没有此字段,设为0
CreatedAt: attachment.CreatedAt.Unix(),
UpdatedAt: attachment.UpdatedAt.Unix(),
},
}, nil
}
// Update 更新附件
func (s *AttachmentService) Update(ctx context.Context, req *AttachmentUpdateReq) error {
// 检查附件是否存在
count, err := dao.Attachment.Ctx(ctx).Where("id", req.Id).Count()
if err != nil {
return gerror.New("检查附件失败")
}
if count == 0 {
return gerror.New("附件不存在")
}
// 更新附件信息(实体中没有category和description字段,只更新状态)
data := g.Map{
"status": 1, // 保持启用状态
"updated_at": gtime.Now(),
}
_, err = dao.Attachment.Ctx(ctx).Where("id", req.Id).Data(data).Update()
if err != nil {
return gerror.New("更新附件失败")
}
return nil
}
// Delete 删除附件
func (s *AttachmentService) Delete(ctx context.Context, req *AttachmentDeleteReq) error {
// 获取附件信息
var attachment entity.Attachment
err := dao.Attachment.Ctx(ctx).Where("id", req.Id).Scan(&attachment)
if err != nil {
return gerror.New("获取附件信息失败")
}
if attachment.Id == 0 {
return gerror.New("附件不存在")
}
// 删除数据库记录
_, err = dao.Attachment.Ctx(ctx).Where("id", req.Id).Delete()
if err != nil {
return gerror.New("删除附件记录失败")
}
// 删除物理文件(这里应该根据实际存储方式处理)
// 例如:os.Remove(attachment.Url)
return nil
}
// BatchDelete 批量删除附件
func (s *AttachmentService) BatchDelete(ctx context.Context, req *AttachmentBatchDeleteReq) error {
if len(req.Ids) == 0 {
return gerror.New("请选择要删除的附件")
}
// 获取附件信息
var attachments []entity.Attachment
err := dao.Attachment.Ctx(ctx).WhereIn("id", req.Ids).Scan(&attachments)
if err != nil {
return gerror.New("获取附件信息失败")
}
// 删除数据库记录
_, err = dao.Attachment.Ctx(ctx).WhereIn("id", req.Ids).Delete()
if err != nil {
return gerror.New("批量删除附件记录失败")
}
// 删除物理文件
for _, attachment := range attachments {
// 这里应该根据实际存储方式处理
// 例如:os.Remove(attachment.Url)
_ = attachment // 避免未使用变量错误
}
return nil
}
// Download 下载附件
func (s *AttachmentService) Download(ctx context.Context, req *AttachmentDownloadReq) (*AttachmentDownloadRes, error) {
// 获取附件信息
var attachment entity.Attachment
err := dao.Attachment.Ctx(ctx).Where("id", req.Id).Scan(&attachment)
if err != nil {
return nil, gerror.New("获取附件信息失败")
}
if attachment.Id == 0 {
return nil, gerror.New("附件不存在")
}
// 这里可以更新下载次数,但实体中没有download_count字段,所以跳过
return &AttachmentDownloadRes{
Url: attachment.Url,
Filename: attachment.Name,
}, nil
}
// GetCategoryList 获取附件分类列表
func (s *AttachmentService) GetCategoryList(ctx context.Context, req *AttachmentCategoryListReq) (*AttachmentCategoryListRes, error) {
query := dao.Attachment.Ctx(ctx).Fields("mime_type as category, COUNT(*) as count")
// 类型筛选
if req.Type != "" {
query = query.Where("mime_type", req.Type)
}
var categories []g.Map
err := query.Group("mime_type").Order("count DESC").Scan(&categories)
if err != nil {
return nil, gerror.New("获取分类列表失败")
}
// 转换为响应格式
list := make([]AttachmentCategoryItem, 0, len(categories))
for _, category := range categories {
list = append(list, AttachmentCategoryItem{
Category: gconv.String(category["category"]),
Count: gconv.Int(category["count"]),
})
}
return &AttachmentCategoryListRes{
Categories: list,
}, nil
}
// GetStatistics 获取附件统计
func (s *AttachmentService) GetStatistics(ctx context.Context, req *AttachmentStatisticsReq) (*AttachmentStatisticsRes, error) {
// 构建查询条件
query := dao.Attachment.Ctx(ctx)
if req.StartDate != "" {
query = query.Where("created_at >= ?", req.StartDate+" 00:00:00")
}
if req.EndDate != "" {
query = query.Where("created_at <= ?", req.EndDate+" 23:59:59")
}
if req.Type != "" {
query = query.Where("mime_type", req.Type)
}
// 获取基础统计
var totalCount int
var totalSize int64
query.Fields("COUNT(*) as total_count, COALESCE(SUM(size), 0) as total_size").
Scan(&g.Map{
"total_count": &totalCount,
"total_size": &totalSize,
})
// 获取类型统计
typeStats := make([]AttachmentTypeStatItem, 0)
var typeStatsData []g.Map
dao.Attachment.Ctx(ctx).Fields("mime_type as type, COUNT(*) as count, COALESCE(SUM(size), 0) as size").
Group("mime_type").Order("count DESC").Scan(&typeStatsData)
for _, stat := range typeStatsData {
count := gconv.Int(stat["count"])
size := gconv.Int64(stat["size"])
percentage := "0.00"
if totalCount > 0 {
percentage = fmt.Sprintf("%.2f", float64(count)/float64(totalCount)*100)
}
typeStats = append(typeStats, AttachmentTypeStatItem{
Type: gconv.String(stat["type"]),
Count: count,
Size: size,
Percentage: percentage,
})
}
// 获取分类统计(使用mime_type作为分类)
categoryStats := make([]AttachmentCategoryStatItem, 0)
var categoryStatsData []g.Map
dao.Attachment.Ctx(ctx).Fields("mime_type as category, COUNT(*) as count, COALESCE(SUM(size), 0) as size").
Group("mime_type").Order("count DESC").Limit(10).Scan(&categoryStatsData)
for _, stat := range categoryStatsData {
count := gconv.Int(stat["count"])
size := gconv.Int64(stat["size"])
percentage := "0.00"
if totalCount > 0 {
percentage = fmt.Sprintf("%.2f", float64(count)/float64(totalCount)*100)
}
categoryStats = append(categoryStats, AttachmentCategoryStatItem{
Category: gconv.String(stat["category"]),
Count: count,
Size: size,
Percentage: percentage,
})
}
// 获取上传图表数据(简化处理)
uploadChart := make([]AttachmentUploadChartItem, 0)
if req.StartDate != "" && req.EndDate != "" {
uploadChart = append(uploadChart, AttachmentUploadChartItem{
Date: req.StartDate,
Count: totalCount,
Size: totalSize,
})
}
// 获取大小图表数据
sizeChart := []AttachmentSizeChartItem{
{SizeRange: "0-1MB", Count: 0},
{SizeRange: "1-10MB", Count: 0},
{SizeRange: "10-100MB", Count: 0},
{SizeRange: "100MB+", Count: 0},
}
// 获取热门文件
popularFiles := make([]AttachmentPopularItem, 0)
var popularData []entity.Attachment
dao.Attachment.Ctx(ctx).Order("created_at DESC").Limit(10).Scan(&popularData)
for _, file := range popularData {
popularFiles = append(popularFiles, AttachmentPopularItem{
Id: file.Id,
Filename: file.Name,
Type: file.MimeType,
Size: file.Size,
DownloadCount: 0, // 实体中没有此字段
CreatedAt: file.CreatedAt.Unix(),
})
}
// 获取最近上传
recentUploads := make([]AttachmentRecentItem, 0)
var recentData []entity.Attachment
dao.Attachment.Ctx(ctx).Order("created_at DESC").Limit(10).Scan(&recentData)
// 获取用户信息
userIds := make([]int, 0, len(recentData))
for _, file := range recentData {
userIds = append(userIds, file.UserId)
}
userMap := make(map[int]string)
if len(userIds) > 0 {
var users []entity.NlUser
g.DB().Model("nl_user").WhereIn("id", userIds).Fields("id, username").Scan(&users)
for _, user := range users {
userMap[int(user.Id)] = user.Username
}
}
for _, file := range recentData {
username := userMap[file.UserId]
recentUploads = append(recentUploads, AttachmentRecentItem{
Id: file.Id,
Filename: file.Name,
OriginalName: file.Name,
Type: file.MimeType,
Size: file.Size,
UserId: uint(file.UserId),
Username: username,
CreatedAt: file.CreatedAt.Unix(),
})
}
return &AttachmentStatisticsRes{
TotalCount: totalCount,
TotalSize: totalSize,
TypeStats: typeStats,
CategoryStats: categoryStats,
UploadChart: uploadChart,
SizeChart: sizeChart,
PopularFiles: popularFiles,
RecentUploads: recentUploads,
}, nil
}
// Move 移动附件
func (s *AttachmentService) Move(ctx context.Context, req *AttachmentMoveReq) error {
if len(req.Ids) == 0 {
return gerror.New("请选择要移动的附件")
}
// 更新状态(实体中没有category字段,只能更新状态)
_, err := dao.Attachment.Ctx(ctx).WhereIn("id", req.Ids).Data(g.Map{
"status": 1,
"updated_at": gtime.Now(),
}).Update()
if err != nil {
return gerror.New("移动附件失败")
}
return nil
}
// Copy 复制附件
func (s *AttachmentService) Copy(ctx context.Context, req *AttachmentCopyReq) (*AttachmentCopyRes, error) {
// 获取源附件信息
var sourceAttachment entity.Attachment
err := dao.Attachment.Ctx(ctx).Where("id", req.Id).Scan(&sourceAttachment)
if err != nil {
return nil, gerror.New("获取源附件信息失败")
}
if sourceAttachment.Id == 0 {
return nil, gerror.New("源附件不存在")
}
// 获取当前用户ID
userId := GetUserIdFromContext(ctx)
if userId == 0 {
return nil, gerror.New("用户未登录")
}
// 生成新文件名
newFilename := fmt.Sprintf("copy_%d_%s", time.Now().Unix(), sourceAttachment.Name)
newUrl := strings.Replace(sourceAttachment.Url, sourceAttachment.Name, newFilename, 1)
// 创建新附件记录
data := &entity.Attachment{
Name: newFilename,
Path: newUrl,
Url: newUrl,
Size: sourceAttachment.Size,
MimeType: sourceAttachment.MimeType,
Extension: sourceAttachment.Extension,
UserId: int(userId),
Status: 1,
CreatedAt: gtime.Now(),
UpdatedAt: gtime.Now(),
}
id, err := dao.Attachment.Ctx(ctx).Data(data).InsertAndGetId()
if err != nil {
return nil, gerror.New("复制附件失败")
}
// 这里应该复制物理文件
return &AttachmentCopyRes{
Id: uint(id),
Filename: newFilename,
Url: newUrl,
}, nil
}
// Rename 重命名附件
func (s *AttachmentService) Rename(ctx context.Context, req *AttachmentRenameReq) error {
// 检查附件是否存在
count, err := dao.Attachment.Ctx(ctx).Where("id", req.Id).Count()
if err != nil {
return gerror.New("检查附件失败")
}
if count == 0 {
return gerror.New("附件不存在")
}
// 更新文件名
_, err = dao.Attachment.Ctx(ctx).Where("id", req.Id).Data(g.Map{
"name": req.Filename,
"updated_at": gtime.Now(),
}).Update()
if err != nil {
return gerror.New("重命名附件失败")
}
return nil
}
// Search 搜索附件
func (s *AttachmentService) Search(ctx context.Context, req *AttachmentSearchReq) (*AttachmentSearchRes, error) {
// 设置默认值
if req.Page <= 0 {
req.Page = 1
}
if req.Size <= 0 {
req.Size = 10
}
// 构建查询条件
query := dao.Attachment.Ctx(ctx)
// 关键词搜索
if req.Query != "" {
keyword := "%" + req.Query + "%"
query = query.Where("name LIKE ?", keyword)
}
// 类型筛选
if req.Type != "" {
query = query.Where("mime_type", req.Type)
}
// 获取总数
total, err := query.Count()
if err != nil {
return nil, gerror.New("获取搜索结果总数失败")
}
// 获取列表数据
var attachments []entity.Attachment
err = query.Order("id DESC").
Limit((req.Page-1)*req.Size, req.Size).
Scan(&attachments)
if err != nil {
return nil, gerror.New("获取搜索结果失败")
}
// 转换为响应格式
list := make([]AttachmentItem, 0, len(attachments))
for _, attachment := range attachments {
list = append(list, AttachmentItem{
Id: attachment.Id,
Filename: attachment.Name,
OriginalName: attachment.Name,
Url: attachment.Url,
Size: attachment.Size,
Type: attachment.MimeType,
Category: "default",
Description: "",
UserId: uint(attachment.UserId),
CreatedAt: attachment.CreatedAt.Unix(),
})
}
return &AttachmentSearchRes{
List: list,
Total: total,
Page: req.Page,
Size: req.Size,
}, nil
}
// UserList 用户获取附件列表
func (s *AttachmentService) UserList(ctx context.Context, req *AttachmentUserListReq) (*AttachmentUserListRes, error) {
// 设置默认值
if req.Page <= 0 {
req.Page = 1
}
if req.Size <= 0 {
req.Size = 10
}
// 获取当前用户ID
userId := GetUserIdFromContext(ctx)
if userId == 0 {
return nil, gerror.New("用户未登录")
}
// 构建查询条件
query := dao.Attachment.Ctx(ctx).Where("user_id", userId)
// 类型筛选
if req.Type != "" {
query = query.Where("mime_type", req.Type)
}
// 关键词搜索
if req.Keyword != "" {
keyword := "%" + req.Keyword + "%"
query = query.Where("name LIKE ?", keyword)
}
// 获取总数
total, err := query.Count()
if err != nil {
return nil, gerror.New("获取附件总数失败")
}
// 获取列表数据
var attachments []entity.Attachment
err = query.Order("id DESC").
Limit((req.Page-1)*req.Size, req.Size).
Scan(&attachments)
if err != nil {
return nil, gerror.New("获取附件列表失败")
}
// 转换为响应格式
list := make([]AttachmentUserItem, 0, len(attachments))
for _, attachment := range attachments {
list = append(list, AttachmentUserItem{
Id: attachment.Id,
Filename: attachment.Name,
OriginalName: attachment.Name,
Url: attachment.Url,
Size: attachment.Size,
Type: attachment.MimeType,
Category: "default",
Description: "",
CreatedAt: attachment.CreatedAt.Unix(),
})
}
return &AttachmentUserListRes{
List: list,
Total: total,
Page: req.Page,
Size: req.Size,
}, nil
}
// GetUserIdFromContext 从上下文获取用户ID
func GetUserIdFromContext(ctx context.Context) uint {
// 这里应该从JWT token或session中获取用户ID
// 临时返回固定值
return 1
}
// UserUpload 用户上传附件
func (s *AttachmentService) UserUpload(r *ghttp.Request) {
s.Upload(r)
}
// UserGetList 用户获取附件列表
func (s *AttachmentService) UserGetList(r *ghttp.Request) {
// 获取请求参数并转换为内部请求结构
req := &AttachmentUserListReq{
Page: r.Get("page", 1).Int(),
Size: r.Get("size", 10).Int(),
Type: r.Get("type").String(),
Category: r.Get("category").String(),
Keyword: r.Get("keyword").String(),
}
// 调用服务方法
res, err := s.UserList(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// UserGetDetail 用户获取附件详情
func (s *AttachmentService) UserGetDetail(r *ghttp.Request) {
req := &AttachmentDetailReq{
Id: uint(r.Get("id").Int()),
}
res, err := s.Detail(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// UserUpdate 用户更新附件
func (s *AttachmentService) UserUpdate(r *ghttp.Request) {
req := &AttachmentUpdateReq{
Id: uint(r.Get("id").Int()),
Category: r.Get("category").String(),
Description: r.Get("description").String(),
}
err := s.Update(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, "更新成功")
}
// UserDelete 用户删除附件
func (s *AttachmentService) UserDelete(r *ghttp.Request) {
req := &AttachmentDeleteReq{
Id: uint(r.Get("id").Int()),
}
err := s.Delete(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, "删除成功")
}
// UserDownload 用户下载附件
func (s *AttachmentService) UserDownload(r *ghttp.Request) {
req := &AttachmentDownloadReq{
Id: uint(r.Get("id").Int()),
}
res, err := s.Download(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// UserCopy 用户复制附件
func (s *AttachmentService) UserCopy(r *ghttp.Request) {
req := &AttachmentCopyReq{
Id: uint(r.Get("id").Int()),
NewCategory: r.Get("new_category").String(),
Description: r.Get("description").String(),
}
res, err := s.Copy(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// UserRename 用户重命名附件
func (s *AttachmentService) UserRename(r *ghttp.Request) {
req := &AttachmentRenameReq{
Id: uint(r.Get("id").Int()),
Filename: r.Get("filename").String(),
}
err := s.Rename(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, "重命名成功")
}
// UserSearch 用户搜索附件
func (s *AttachmentService) UserSearch(r *ghttp.Request) {
req := &AttachmentSearchReq{
Query: r.Get("query").String(),
Type: r.Get("type").String(),
Category: r.Get("category").String(),
Page: r.Get("page", 1).Int(),
Size: r.Get("size", 10).Int(),
}
res, err := s.Search(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// UserGetCategoryList 用户获取附件分类列表
func (s *AttachmentService) UserGetCategoryList(r *ghttp.Request) {
req := &AttachmentCategoryListReq{
Type: r.Get("type").String(),
}
res, err := s.GetCategoryList(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// AdminGetList 管理员获取附件列表
func (s *AttachmentService) AdminGetList(r *ghttp.Request) {
req := &AttachmentListReq{
Page: r.Get("page", 1).Int(),
Size: r.Get("size", 10).Int(),
Type: r.Get("type").String(),
Category: r.Get("category").String(),
Keyword: r.Get("keyword").String(),
StartDate: r.Get("start_date").String(),
EndDate: r.Get("end_date").String(),
MinSize: r.Get("min_size").Int64(),
MaxSize: r.Get("max_size").Int64(),
UserId: uint(r.Get("user_id").Int()),
}
res, err := s.List(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}
// AdminGetDetail 管理员获取附件详情
func (s *AttachmentService) AdminGetDetail(r *ghttp.Request) {
s.UserGetDetail(r)
}
// AdminUpdate 管理员更新附件
func (s *AttachmentService) AdminUpdate(r *ghttp.Request) {
s.UserUpdate(r)
}
// AdminDelete 管理员删除附件
func (s *AttachmentService) AdminDelete(r *ghttp.Request) {
s.UserDelete(r)
}
// AdminBatchDelete 管理员批量删除附件
func (s *AttachmentService) AdminBatchDelete(r *ghttp.Request) {
var ids []uint
r.Parse(&ids)
req := &AttachmentBatchDeleteReq{
Ids: ids,
}
err := s.BatchDelete(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, "批量删除成功")
}
// AdminDownload 管理员下载附件
func (s *AttachmentService) AdminDownload(r *ghttp.Request) {
s.UserDownload(r)
}
// AdminMove 管理员移动附件
func (s *AttachmentService) AdminMove(r *ghttp.Request) {
var ids []uint
r.Parse(&ids)
req := &AttachmentMoveReq{
Ids: ids,
NewCategory: r.Get("new_category").String(),
}
err := s.Move(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, "移动成功")
}
// AdminCopy 管理员复制附件
func (s *AttachmentService) AdminCopy(r *ghttp.Request) {
s.UserCopy(r)
}
// AdminRename 管理员重命名附件
func (s *AttachmentService) AdminRename(r *ghttp.Request) {
s.UserRename(r)
}
// AdminSearch 管理员搜索附件
func (s *AttachmentService) AdminSearch(r *ghttp.Request) {
s.UserSearch(r)
}
// AdminGetCategoryList 管理员获取附件分类列表
func (s *AttachmentService) AdminGetCategoryList(r *ghttp.Request) {
s.UserGetCategoryList(r)
}
// AdminGetStatistics 管理员获取附件统计
func (s *AttachmentService) AdminGetStatistics(r *ghttp.Request) {
req := &AttachmentStatisticsReq{
StartDate: r.Get("start_date").String(),
EndDate: r.Get("end_date").String(),
Type: r.Get("type").String(),
}
res, err := s.GetStatistics(r.Context(), req)
if err != nil {
response.Error(r, response.CodeInternalError, err.Error())
return
}
response.Success(r, res)
}