166 lines
5.3 KiB
Go
166 lines
5.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"octopus/internal/dal"
|
|
"octopus/internal/dal/model"
|
|
"octopus/internal/dal/query"
|
|
"octopus/internal/schema"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
|
|
"github.com/rs/xid"
|
|
"gorm.io/gen/field"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func ListDocs(ctx context.Context, auth *casdoorsdk.User, param *schema.ListDocQuery) ([]*model.Doc, int64, error) {
|
|
base := query.Doc.Where(query.Doc.OrgID.Eq(auth.Owner))
|
|
if param.FolderIDs != nil {
|
|
base = base.Where(query.Doc.FolderID.In(*param.FolderIDs...))
|
|
}
|
|
if orders := param.GetOrderByFields(query.Doc); len(orders) != 0 {
|
|
base = base.Order(orders...)
|
|
}
|
|
return base.FindByPage(param.GetOffset(), param.GetLimit())
|
|
}
|
|
|
|
func CreateDoc(ctx context.Context, auth *casdoorsdk.User, param *schema.CreateDoc) (*model.Doc, error) {
|
|
storage := dal.GetStorage()
|
|
// 检查oss对象
|
|
stat, exists, err := storage.ObjectStats(ctx, param.ObjectName)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get object stats: %w", err)
|
|
}
|
|
if !exists {
|
|
return nil, fmt.Errorf("object not exists")
|
|
}
|
|
|
|
// 检查文件夹
|
|
folder, err := GetDocFolder(ctx, auth, param.FolderID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 将对象从临时地址移动到新地址
|
|
newPath := fmt.Sprintf("%s/%s/%s", auth.Owner, folder.ParentPath, param.Name)
|
|
if err := storage.MoveObject(ctx, param.ObjectName, newPath); err != nil {
|
|
return nil, fmt.Errorf("failed to move object: %w", err)
|
|
}
|
|
|
|
doc := model.Doc{
|
|
Base: model.Base{OrgID: auth.Owner},
|
|
Name: param.Name,
|
|
IsDeletable: true,
|
|
IsEditable: true,
|
|
FolderID: param.FolderID,
|
|
ObjectName: newPath,
|
|
UploadedAt: stat.LastModified,
|
|
CreatedBy: auth.Id,
|
|
}
|
|
if err := query.Doc.Create(&doc); err != nil {
|
|
return nil, fmt.Errorf("failed to create doc: %w", err)
|
|
}
|
|
return &doc, nil
|
|
}
|
|
|
|
func GetDoc(ctx context.Context, auth *casdoorsdk.User, id string) (*model.Doc, error) {
|
|
doc, err := query.Doc.Where(query.Doc.OrgID.Eq(auth.Owner), query.Doc.ID.Eq(id)).Take()
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, fmt.Errorf("specified doc not exists")
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return doc, nil
|
|
}
|
|
|
|
func UpdateDoc(ctx context.Context, auth *casdoorsdk.User, id string, body *schema.UpdateDoc) (*model.Doc, error) {
|
|
doc, err := GetDoc(ctx, auth, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get doc: %w", err)
|
|
}
|
|
|
|
var updates []field.AssignExpr
|
|
if body.Name != nil {
|
|
updates = append(updates, query.Doc.Name.Value(*body.Name))
|
|
}
|
|
|
|
if body.FolderID != nil {
|
|
if _, err := GetDocFolder(ctx, auth, *body.FolderID); err != nil {
|
|
return nil, fmt.Errorf("failed to get doc folder: %w", err)
|
|
}
|
|
|
|
// 将对象从临时地址移动到新地址
|
|
parts := strings.Split(doc.ObjectName, "/")
|
|
objname := parts[len(parts)-1]
|
|
newObjectName := fmt.Sprintf("%s/%s/%s", auth.Owner, time.Now().UTC().Format(time.DateOnly), objname)
|
|
if err := dal.GetStorage().MoveObject(ctx, doc.ObjectName, newObjectName); err != nil {
|
|
return nil, fmt.Errorf("failed to move object: %w", err)
|
|
}
|
|
updates = append(updates, query.Doc.ObjectName.Value(newObjectName))
|
|
updates = append(updates, query.Doc.FolderID.Value(*body.FolderID))
|
|
}
|
|
|
|
if _, err := query.Doc.UpdateColumnSimple(updates...); err != nil {
|
|
return nil, fmt.Errorf("failed to update doc: %w", err)
|
|
}
|
|
return GetDoc(ctx, auth, id)
|
|
}
|
|
|
|
func DeleteDoc(ctx context.Context, auth *casdoorsdk.User, id string) error {
|
|
doc, err := GetDoc(ctx, auth, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get doc: %w", err)
|
|
}
|
|
if err := dal.GetStorage().DeleteObject(ctx, doc.ObjectName); err != nil {
|
|
return fmt.Errorf("failed to delete object: %w", err)
|
|
}
|
|
_, err = query.Doc.Where(query.Doc.OrgID.Eq(auth.Owner), query.Doc.ID.Eq(id)).Delete()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete doc: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DeleteDocBatch(ctx context.Context, auth *casdoorsdk.User, param *schema.DocsBatchDelete) *schema.DocBatchResults {
|
|
results := make(schema.DocBatchResults, 0, len(param.IDs))
|
|
// NOTE: 后面应该需要优化一下
|
|
for _, docID := range param.IDs {
|
|
err := DeleteDoc(ctx, auth, docID)
|
|
if err != nil {
|
|
results = append(results, schema.DocBatchResult{ID: docID, Success: false, Error: err.Error()})
|
|
} else {
|
|
results = append(results, schema.DocBatchResult{ID: docID, Success: true})
|
|
}
|
|
}
|
|
return &results
|
|
}
|
|
|
|
func UpdateDocBatch(ctx context.Context, auth *casdoorsdk.User, param *schema.DocsBatchUpdate) *schema.DocBatchResults {
|
|
results := make(schema.DocBatchResults, 0, len(param.IDs))
|
|
// NOTE: 后面应该需要优化一下
|
|
for _, docID := range param.IDs {
|
|
_, err := UpdateDoc(ctx, auth, docID, &schema.UpdateDoc{FolderID: ¶m.FolderID})
|
|
if err != nil {
|
|
results = append(results, schema.DocBatchResult{ID: docID, Success: false, Error: err.Error()})
|
|
} else {
|
|
results = append(results, schema.DocBatchResult{ID: docID, Success: true})
|
|
}
|
|
}
|
|
return &results
|
|
}
|
|
|
|
func CreateUploadURL(ctx context.Context, auth *casdoorsdk.User, param *schema.CreateUploadURL) (u *url.URL, objectName string, err error) {
|
|
tmpObjectName := fmt.Sprintf("/tmp/%s/%s-%s", auth.Owner, param.FileName, xid.New())
|
|
u, err = dal.GetStorage().PresignedPutObject(ctx, tmpObjectName, time.Hour)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("failed to create presigned url: %w", err)
|
|
}
|
|
return u, tmpObjectName, nil
|
|
}
|