925 lines
23 KiB
Go
925 lines
23 KiB
Go
package controllers
|
||
|
||
import (
|
||
"crypto/md5"
|
||
"encoding/hex"
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"os"
|
||
"path/filepath"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"server/models"
|
||
"server/pkg/jwtutil"
|
||
|
||
beego "github.com/beego/beego/v2/server/web"
|
||
)
|
||
|
||
// PlatformFileController 平台端文件管理(yz_system_files / yz_system_files_category)
|
||
type PlatformFileController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
const fileUploadMaxBytes = 50 * 1024 * 1024
|
||
|
||
var fileTypeByCategory = map[string]uint8{
|
||
"image": 1,
|
||
"document": 2,
|
||
"video": 3,
|
||
"audio": 4,
|
||
}
|
||
|
||
var allowedExtByCategory = map[string][]string{
|
||
"image": {"jpg", "jpeg", "png", "gif", "bmp", "webp"},
|
||
"document": {"pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt"},
|
||
"video": {"mp4", "webm", "mov"},
|
||
"audio": {"mp3", "wav", "ogg"},
|
||
}
|
||
|
||
func (c *PlatformFileController) platformClaims() (*jwtutil.Claims, error) {
|
||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||
if auth == "" {
|
||
return nil, fmt.Errorf("未登录")
|
||
}
|
||
parts := strings.SplitN(auth, " ", 2)
|
||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||
return nil, fmt.Errorf("认证信息格式错误")
|
||
}
|
||
claims, err := jwtutil.ParseToken(parts[1])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的token")
|
||
}
|
||
if claims.UserType != "platform" {
|
||
return nil, fmt.Errorf("无权访问")
|
||
}
|
||
return claims, nil
|
||
}
|
||
|
||
func (c *PlatformFileController) effectiveTid(claims *jwtutil.Claims) uint64 {
|
||
_ = c.ParseForm(1 << 20)
|
||
if tid, err := c.GetUint64("tid"); err == nil && tid > 0 {
|
||
return tid
|
||
}
|
||
if h := strings.TrimSpace(c.Ctx.Request.Header.Get("X-Tenant-Id")); h != "" {
|
||
if v, e := strconv.ParseUint(h, 10, 64); e == nil {
|
||
return v
|
||
}
|
||
}
|
||
if claims != nil && claims.TenantId > 0 {
|
||
return uint64(claims.TenantId)
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func (c *PlatformFileController) jsonErr(httpStatus, bizCode int, msg string) {
|
||
c.Ctx.Output.SetStatus(httpStatus)
|
||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
func (c *PlatformFileController) jsonOK(data interface{}) {
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": data}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
func detectFileType(ext string) uint8 {
|
||
ext = strings.ToLower(strings.TrimPrefix(ext, "."))
|
||
for cat, exts := range allowedExtByCategory {
|
||
for _, e := range exts {
|
||
if e == ext {
|
||
return fileTypeByCategory[cat]
|
||
}
|
||
}
|
||
}
|
||
return 2
|
||
}
|
||
|
||
func fileExt(name string) string {
|
||
name = strings.TrimSpace(name)
|
||
if i := strings.LastIndex(name, "."); i >= 0 && i < len(name)-1 {
|
||
return strings.ToLower(name[i+1:])
|
||
}
|
||
return ""
|
||
}
|
||
|
||
func fileToMap(f *models.SystemFile) map[string]interface{} {
|
||
ct := f.CreateTime.Format("2006-01-02 15:04:05")
|
||
m := map[string]interface{}{
|
||
"id": f.ID,
|
||
"tid": f.Tid,
|
||
"name": f.Name,
|
||
"type": f.Type,
|
||
"cate": f.Cate,
|
||
"size": f.Size,
|
||
"src": f.Src,
|
||
"uploader": f.Uploader,
|
||
"md5": f.Md5,
|
||
"create_time": ct,
|
||
"createTime": ct,
|
||
"groupId": f.Cate,
|
||
"url": f.Src,
|
||
}
|
||
if f.Uid != nil {
|
||
m["uid"] = *f.Uid
|
||
}
|
||
if f.Tuid != nil {
|
||
m["tuid"] = *f.Tuid
|
||
}
|
||
return m
|
||
}
|
||
|
||
func removePhysicalBySrc(webSrc string) {
|
||
webSrc = strings.TrimSpace(webSrc)
|
||
if webSrc == "" {
|
||
return
|
||
}
|
||
webSrc = strings.TrimPrefix(webSrc, "/")
|
||
_ = os.Remove(webSrc)
|
||
}
|
||
|
||
// GetAllFiles GET /platform/allfiles
|
||
func (c *PlatformFileController) GetAllFiles() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
page, _ := c.GetInt("page", 1)
|
||
pageSize, _ := c.GetInt("pageSize", 10)
|
||
if page < 1 {
|
||
page = 1
|
||
}
|
||
if pageSize < 1 {
|
||
pageSize = 10
|
||
}
|
||
cate, _ := c.GetUint64("cate")
|
||
keyword := strings.TrimSpace(c.GetString("keyword"))
|
||
|
||
qs := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true)
|
||
if cate > 0 {
|
||
qs = qs.Filter("cate", cate)
|
||
}
|
||
if keyword != "" {
|
||
qs = qs.Filter("name__icontains", keyword)
|
||
}
|
||
total, err := qs.Count()
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "获取文件列表失败: "+err.Error())
|
||
return
|
||
}
|
||
var rows []models.SystemFile
|
||
_, err = qs.OrderBy("-create_time").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "获取文件列表失败: "+err.Error())
|
||
return
|
||
}
|
||
list := make([]map[string]interface{}, 0, len(rows))
|
||
for i := range rows {
|
||
list = append(list, fileToMap(&rows[i]))
|
||
}
|
||
c.jsonOK(map[string]interface{}{
|
||
"list": list,
|
||
"total": total,
|
||
"page": page,
|
||
"pageSize": pageSize,
|
||
})
|
||
}
|
||
|
||
// GetUserCate GET /platform/usercate
|
||
func (c *PlatformFileController) GetUserCate() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
|
||
var cates []models.SystemFilesCategory
|
||
_, err = models.Orm.QueryTable(new(models.SystemFilesCategory)).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
OrderBy("id").
|
||
All(&cates)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "获取用户分类失败: "+err.Error())
|
||
return
|
||
}
|
||
out := make([]map[string]interface{}, 0, len(cates))
|
||
for i := range cates {
|
||
cnt, _ := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("tid", tid).
|
||
Filter("cate", cates[i].ID).
|
||
Filter("delete_time__isnull", true).
|
||
Count()
|
||
out = append(out, map[string]interface{}{
|
||
"id": cates[i].ID,
|
||
"name": cates[i].Name,
|
||
"total": cnt,
|
||
})
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
type createCateBody struct {
|
||
Name string `json:"name"`
|
||
Tuid *uint64 `json:"tuid"`
|
||
}
|
||
|
||
// CreateFileCate POST /platform/createfilecate
|
||
func (c *PlatformFileController) CreateFileCate() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body createCateBody
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
name := strings.TrimSpace(body.Name)
|
||
if name == "" {
|
||
c.jsonErr(400, 400, "分组名称不能为空")
|
||
return
|
||
}
|
||
uid := uint64(claims.UserID)
|
||
row := &models.SystemFilesCategory{
|
||
Tid: tid,
|
||
Name: name,
|
||
Uid: &uid,
|
||
Tuid: body.Tuid,
|
||
}
|
||
id, err := models.Orm.Insert(row)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "新建文件分组失败: "+err.Error())
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "新建文件分组成功",
|
||
"data": map[string]interface{}{"id": uint64(id)},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
type renameCateBody struct {
|
||
Name string `json:"name"`
|
||
}
|
||
|
||
// RenameFileCate POST /platform/renamefilecate/:id
|
||
func (c *PlatformFileController) RenameFileCate() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的分组ID")
|
||
return
|
||
}
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body renameCateBody
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
name := strings.TrimSpace(body.Name)
|
||
if name == "" {
|
||
c.jsonErr(400, 400, "分组名称不能为空")
|
||
return
|
||
}
|
||
n, err := models.Orm.QueryTable(new(models.SystemFilesCategory)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"name": name})
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "重命名文件分组失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "分组不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "重命名文件分组成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// DeleteFileCate DELETE /platform/deletefilecate/:id
|
||
func (c *PlatformFileController) DeleteFileCate() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的分组ID")
|
||
return
|
||
}
|
||
cnt, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("cate", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Count()
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "删除文件分组失败: "+err.Error())
|
||
return
|
||
}
|
||
if cnt > 0 {
|
||
c.jsonErr(400, 400, fmt.Sprintf("该分组下还有 %d 个文件,请先删除分组内文件!", cnt))
|
||
return
|
||
}
|
||
now := time.Now()
|
||
n, err := models.Orm.QueryTable(new(models.SystemFilesCategory)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"delete_time": now})
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "删除文件分组失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "分组不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除文件分组成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// GetCateFiles GET /platform/catefiles/:id
|
||
func (c *PlatformFileController) GetCateFiles() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
cateID, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "无效的分类ID")
|
||
return
|
||
}
|
||
page, _ := c.GetInt("page", 1)
|
||
pageSize, _ := c.GetInt("pageSize", 24)
|
||
if page < 1 {
|
||
page = 1
|
||
}
|
||
if pageSize < 1 {
|
||
pageSize = 24
|
||
}
|
||
keyword := strings.TrimSpace(c.GetString("keyword"))
|
||
|
||
qs := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("tid", tid).
|
||
Filter("cate", cateID).
|
||
Filter("delete_time__isnull", true)
|
||
if keyword != "" {
|
||
qs = qs.Filter("name__icontains", keyword)
|
||
}
|
||
total, err := qs.Count()
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "获取分类文件失败: "+err.Error())
|
||
return
|
||
}
|
||
var rows []models.SystemFile
|
||
_, err = qs.OrderBy("-create_time").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "获取分类文件失败: "+err.Error())
|
||
return
|
||
}
|
||
list := make([]map[string]interface{}, 0, len(rows))
|
||
for i := range rows {
|
||
list = append(list, fileToMap(&rows[i]))
|
||
}
|
||
c.jsonOK(map[string]interface{}{
|
||
"list": list,
|
||
"total": total,
|
||
"page": page,
|
||
"pageSize": pageSize,
|
||
"categoryId": cateID,
|
||
})
|
||
}
|
||
|
||
// GetFileByID GET /platform/file/:id
|
||
func (c *PlatformFileController) GetFileByID() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的文件ID")
|
||
return
|
||
}
|
||
var f models.SystemFile
|
||
err = models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
One(&f)
|
||
if err != nil {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.jsonOK(fileToMap(&f))
|
||
}
|
||
|
||
// UploadFile POST /platform/uploadfile
|
||
func (c *PlatformFileController) UploadFile() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
if err := c.Ctx.Request.ParseMultipartForm(fileUploadMaxBytes); err != nil {
|
||
c.jsonErr(400, 400, "解析上传失败: "+err.Error())
|
||
return
|
||
}
|
||
fh, header, err := c.GetFile("file")
|
||
if err != nil || fh == nil {
|
||
c.jsonErr(400, 400, "请选择要上传的文件")
|
||
return
|
||
}
|
||
defer fh.Close()
|
||
|
||
if header != nil && header.Size > fileUploadMaxBytes {
|
||
c.jsonErr(400, 400, "文件大小不能超过50MB")
|
||
return
|
||
}
|
||
|
||
ext := fileExt(header.Filename)
|
||
if ext == "" {
|
||
c.jsonErr(400, 400, "无法识别文件扩展名")
|
||
return
|
||
}
|
||
|
||
tmpPath := filepath.Join(os.TempDir(), fmt.Sprintf("up_%d_%s", time.Now().UnixNano(), header.Filename))
|
||
tmp, err := os.Create(tmpPath)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "创建临时文件失败")
|
||
return
|
||
}
|
||
n, copyErr := io.Copy(tmp, fh)
|
||
_ = tmp.Close()
|
||
if copyErr != nil {
|
||
_ = os.Remove(tmpPath)
|
||
c.jsonErr(500, 500, "读取文件失败")
|
||
return
|
||
}
|
||
if n > fileUploadMaxBytes {
|
||
_ = os.Remove(tmpPath)
|
||
c.jsonErr(400, 400, "文件大小不能超过50MB")
|
||
return
|
||
}
|
||
sum, err := md5HashFile(tmpPath)
|
||
if err != nil {
|
||
_ = os.Remove(tmpPath)
|
||
c.jsonErr(500, 500, "计算文件摘要失败")
|
||
return
|
||
}
|
||
|
||
var exist models.SystemFile
|
||
err = models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("md5", sum).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
One(&exist)
|
||
if err == nil {
|
||
_ = os.Remove(tmpPath)
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 201,
|
||
"msg": "文件已存在",
|
||
"data": map[string]interface{}{
|
||
"url": exist.Src,
|
||
"id": exist.ID,
|
||
"name": exist.Name,
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
datePath := time.Now().Format("2006/01/02")
|
||
saveName := fmt.Sprintf("%s/%d.%s", datePath, time.Now().UnixNano(), ext)
|
||
destDir := filepath.Join("uploads", filepath.FromSlash(datePath))
|
||
if err := os.MkdirAll(destDir, 0755); err != nil {
|
||
_ = os.Remove(tmpPath)
|
||
c.jsonErr(500, 500, "创建目录失败: "+err.Error())
|
||
return
|
||
}
|
||
destPath := filepath.Join("uploads", filepath.FromSlash(saveName))
|
||
if err := os.Rename(tmpPath, destPath); err != nil {
|
||
_ = os.Remove(tmpPath)
|
||
c.jsonErr(500, 500, "保存文件失败: "+err.Error())
|
||
return
|
||
}
|
||
|
||
webURL := "/" + strings.ReplaceAll(filepath.ToSlash(destPath), "\\", "/")
|
||
|
||
cateStr := c.GetString("cate")
|
||
var cate uint64
|
||
if cateStr != "" {
|
||
cate, _ = strconv.ParseUint(cateStr, 10, 64)
|
||
}
|
||
|
||
adminID := uint64(claims.UserID)
|
||
var tuidPtr *uint64
|
||
if ts := strings.TrimSpace(c.GetString("tuid")); ts != "" {
|
||
if v, e := strconv.ParseUint(ts, 10, 64); e == nil {
|
||
tuidPtr = &v
|
||
}
|
||
}
|
||
|
||
row := &models.SystemFile{
|
||
Tid: tid,
|
||
Uid: &adminID,
|
||
Tuid: tuidPtr,
|
||
Name: header.Filename,
|
||
Type: detectFileType(ext),
|
||
Cate: cate,
|
||
Size: uint64(n),
|
||
Src: webURL,
|
||
Uploader: adminID,
|
||
Md5: sum,
|
||
}
|
||
id, err := models.Orm.Insert(row)
|
||
if err != nil {
|
||
removePhysicalBySrc(webURL)
|
||
c.jsonErr(500, 500, "上传失败: "+err.Error())
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "上传成功",
|
||
"data": map[string]interface{}{
|
||
"url": webURL,
|
||
"id": uint64(id),
|
||
"name": header.Filename,
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
func md5HashFile(path string) (string, error) {
|
||
f, err := os.Open(path)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
defer f.Close()
|
||
h := md5.New()
|
||
if _, err := io.Copy(h, f); err != nil {
|
||
return "", err
|
||
}
|
||
return hex.EncodeToString(h.Sum(nil)), nil
|
||
}
|
||
|
||
type updateFileBody struct {
|
||
Name *string `json:"name"`
|
||
Cate *uint64 `json:"cate"`
|
||
}
|
||
|
||
// UpdateFile POST /platform/updatefile/:id
|
||
func (c *PlatformFileController) UpdateFile() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的文件ID")
|
||
return
|
||
}
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body updateFileBody
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
up := map[string]interface{}{}
|
||
if body.Name != nil {
|
||
up["name"] = strings.TrimSpace(*body.Name)
|
||
}
|
||
if body.Cate != nil {
|
||
up["cate"] = *body.Cate
|
||
}
|
||
if len(up) == 0 {
|
||
c.jsonErr(400, 400, "无更新数据")
|
||
return
|
||
}
|
||
now := time.Now()
|
||
up["update_time"] = now
|
||
n, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(up)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "更新失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "更新成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// DeleteFile DELETE /platform/deletefile/:id
|
||
func (c *PlatformFileController) DeleteFile() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的文件ID")
|
||
return
|
||
}
|
||
now := time.Now()
|
||
n, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"delete_time": now})
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "删除失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// DeleteFilePermanently DELETE /platform/deletefilepermanently/:id
|
||
func (c *PlatformFileController) DeleteFilePermanently() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的文件ID")
|
||
return
|
||
}
|
||
var f models.SystemFile
|
||
err = models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
One(&f)
|
||
if err != nil {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
removePhysicalBySrc(f.Src)
|
||
_, err = models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Delete()
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "永久删除失败: "+err.Error())
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "永久删除成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// MoveFile GET /platform/movefile/:id
|
||
func (c *PlatformFileController) MoveFile() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效的文件ID")
|
||
return
|
||
}
|
||
cate, _ := c.GetUint64("cate")
|
||
now := time.Now()
|
||
n, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"cate": cate, "update_time": now})
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "移动失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "移动成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
type idsBody struct {
|
||
IDs []uint64 `json:"ids"`
|
||
Cate *uint64 `json:"cate"`
|
||
}
|
||
|
||
// BatchDeleteFiles POST /platform/batchdeletefiles
|
||
func (c *PlatformFileController) BatchDeleteFiles() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body idsBody
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if len(body.IDs) == 0 {
|
||
c.jsonErr(400, 400, "请选择要删除的文件")
|
||
return
|
||
}
|
||
now := time.Now()
|
||
for _, id := range body.IDs {
|
||
var f models.SystemFile
|
||
e := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
One(&f)
|
||
if e == nil && f.Src != "" {
|
||
removePhysicalBySrc(f.Src)
|
||
}
|
||
}
|
||
n, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id__in", body.IDs).
|
||
Filter("tid", tid).
|
||
Update(map[string]interface{}{"delete_time": now})
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "批量删除失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量删除成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// BatchDeleteFilesPermanently POST /platform/batchDeleteFilesPermanently
|
||
func (c *PlatformFileController) BatchDeleteFilesPermanently() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body idsBody
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if len(body.IDs) == 0 {
|
||
c.jsonErr(400, 400, "请选择要彻底删除的文件")
|
||
return
|
||
}
|
||
var rows []models.SystemFile
|
||
_, err = models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id__in", body.IDs).
|
||
Filter("tid", tid).
|
||
All(&rows)
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "批量彻底删除失败: "+err.Error())
|
||
return
|
||
}
|
||
for i := range rows {
|
||
removePhysicalBySrc(rows[i].Src)
|
||
}
|
||
n, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id__in", body.IDs).
|
||
Filter("tid", tid).
|
||
Delete()
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "批量彻底删除失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量彻底删除成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// UploadAvatar POST /platform/uploadavatar(占位)
|
||
func (c *PlatformFileController) UploadAvatar() {
|
||
c.Data["json"] = map[string]interface{}{"code": 501, "msg": "上传头像暂未实现"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// UpdateAvatar POST /platform/uploadavatar/:id(占位)
|
||
func (c *PlatformFileController) UpdateAvatar() {
|
||
c.Data["json"] = map[string]interface{}{"code": 501, "msg": "更新头像暂未实现"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// BatchMoveFiles POST /platform/batchMoveFiles
|
||
func (c *PlatformFileController) BatchMoveFiles() {
|
||
claims, err := c.platformClaims()
|
||
if err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := c.effectiveTid(claims)
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body idsBody
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if len(body.IDs) == 0 {
|
||
c.jsonErr(400, 400, "请选择要移动的文件")
|
||
return
|
||
}
|
||
if body.Cate == nil {
|
||
c.jsonErr(400, 400, "缺少目标分类")
|
||
return
|
||
}
|
||
now := time.Now()
|
||
n, err := models.Orm.QueryTable(new(models.SystemFile)).
|
||
Filter("id__in", body.IDs).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"cate": *body.Cate, "update_time": now})
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "批量移动失败: "+err.Error())
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.jsonErr(404, 404, "文件不存在")
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量移动成功"}
|
||
_ = c.ServeJSON()
|
||
}
|