2023-03-23 22:28:17 +08:00

164 lines
5.0 KiB
Go

package service
import (
"context"
"errors"
"fmt"
"net/url"
"octopus/internal/dal"
"octopus/internal/dal/model"
"octopus/internal/dal/query"
"octopus/internal/schema"
"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)).
Preload(query.Doc.Folder)
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
}
// 将对象从临时地址移动到新地址
newObjectName := fmt.Sprintf("%s/%s/%s", auth.Owner, time.Now().UTC().Format(time.DateOnly), param.Name)
if err := storage.MoveObject(ctx, param.ObjectName, newObjectName); 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: newObjectName,
UploadedAt: stat.LastModified,
CreatedBy: auth.Id,
Folder: folder,
}
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),
).
Preload(query.Doc.Folder).
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) {
if _, err := GetDoc(ctx, auth, id); 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)
}
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: param.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, xid.New(), param.FileName)
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
}