Files
2026-07-15 22:42:31 +08:00

247 lines
5.7 KiB
Go

package document_repo
import (
"github.com/XingfenD/yoresee_doc/internal/model"
"gorm.io/gorm"
)
type DocumentsListOperation struct {
repo *DocumentRepository
model *model.Document
userID *int64
parentID *int64
knowledgeID *int64
listOwnDoc bool
ids []int64
titleKeyword *string
docType *string
tags []string
createTimeRangeStart *string
createTimeRangeEnd *string
updateTimeRangeStart *string
updateTimeRangeEnd *string
sortField string
sortDesc bool
page int
pageSize int
directoryOnly bool
tx *gorm.DB
}
func (r *DocumentRepository) ListDocuments(documentModel *model.Document) *DocumentsListOperation {
return &DocumentsListOperation{
repo: r,
model: documentModel,
}
}
func (op *DocumentsListOperation) WithUserID(userID *int64) *DocumentsListOperation {
op.userID = userID
return op
}
func (op *DocumentsListOperation) WithParentID(parentID *int64) *DocumentsListOperation {
op.parentID = parentID
return op
}
func (op *DocumentsListOperation) WithKnowledgeID(knowledgeID *int64) *DocumentsListOperation {
op.knowledgeID = knowledgeID
return op
}
func (op *DocumentsListOperation) WithListOwnDoc(listOwnDoc bool) *DocumentsListOperation {
op.listOwnDoc = listOwnDoc
return op
}
func (op *DocumentsListOperation) WithIDs(ids []int64) *DocumentsListOperation {
op.ids = ids
return op
}
func (op *DocumentsListOperation) WithTitleKeyword(titleKeyword *string) *DocumentsListOperation {
op.titleKeyword = titleKeyword
return op
}
func (op *DocumentsListOperation) WithType(docType *string) *DocumentsListOperation {
op.docType = docType
return op
}
func (op *DocumentsListOperation) WithTags(tags []string) *DocumentsListOperation {
op.tags = tags
return op
}
func (op *DocumentsListOperation) WithCreateTimeRange(start, end *string) *DocumentsListOperation {
op.createTimeRangeStart = start
op.createTimeRangeEnd = end
return op
}
func (op *DocumentsListOperation) WithUpdateTimeRange(start, end *string) *DocumentsListOperation {
op.updateTimeRangeStart = start
op.updateTimeRangeEnd = end
return op
}
func (op *DocumentsListOperation) WithPagination(page, pageSize int) *DocumentsListOperation {
op.page = page
op.pageSize = pageSize
return op
}
func (op *DocumentsListOperation) WithSort(field string, desc bool) *DocumentsListOperation {
op.sortField = field
op.sortDesc = desc
return op
}
func (op *DocumentsListOperation) WithDirectoryOnly(with bool) *DocumentsListOperation {
op.directoryOnly = with
return op
}
func (op *DocumentsListOperation) WithTx(tx *gorm.DB) *DocumentsListOperation {
op.tx = tx
return op
}
func (op *DocumentsListOperation) buildBaseQuery() *gorm.DB {
db := op.repo.db
if op.tx != nil {
db = op.tx
}
dbQuery := db.Model(&model.Document{})
if op.directoryOnly {
dbQuery = dbQuery.Select("id, external_id, title, parent_id, type")
}
if op.model != nil {
dbQuery = dbQuery.Where(op.model)
}
if op.userID != nil {
dbQuery = dbQuery.Where("user_id = ?", *op.userID)
}
if op.parentID != nil {
dbQuery = dbQuery.Where("parent_id = ?", *op.parentID)
}
if op.listOwnDoc {
dbQuery = dbQuery.Where("knowledge_id IS NULL")
}
if op.ids != nil {
if len(op.ids) == 0 {
dbQuery = dbQuery.Where("1 = 0")
} else {
dbQuery = dbQuery.Where("id IN ?", op.ids)
}
}
if op.knowledgeID != nil {
dbQuery = dbQuery.Where("knowledge_id = ?", *op.knowledgeID)
}
if op.titleKeyword != nil && *op.titleKeyword != "" {
like := "%" + *op.titleKeyword + "%"
dbQuery = dbQuery.Where("(title LIKE ? OR content LIKE ?)", like, like)
}
if op.docType != nil && *op.docType != "" {
dbQuery = dbQuery.Where("type = ?", *op.docType)
}
if len(op.tags) > 0 {
for _, tag := range op.tags {
dbQuery = dbQuery.Where("JSON_CONTAINS(tags, ?)", "\""+tag+"\"")
}
}
if op.createTimeRangeStart != nil && *op.createTimeRangeStart != "" {
dbQuery = dbQuery.Where("created_at >= ?", *op.createTimeRangeStart)
}
if op.createTimeRangeEnd != nil && *op.createTimeRangeEnd != "" {
dbQuery = dbQuery.Where("created_at <= ?", *op.createTimeRangeEnd)
}
if op.updateTimeRangeStart != nil && *op.updateTimeRangeStart != "" {
dbQuery = dbQuery.Where("updated_at >= ?", *op.updateTimeRangeStart)
}
if op.updateTimeRangeEnd != nil && *op.updateTimeRangeEnd != "" {
dbQuery = dbQuery.Where("updated_at <= ?", *op.updateTimeRangeEnd)
}
return dbQuery
}
func (op *DocumentsListOperation) appendOtherArgs(db *gorm.DB) *gorm.DB {
dbQuery := db
sortField := op.sortField
if sortField == "" {
sortField = "created_at"
}
orderDirection := "ASC"
if op.sortDesc {
orderDirection = "DESC"
}
dbQuery = dbQuery.Order(sortField + " " + orderDirection)
page := op.page
pageSize := op.pageSize
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
if pageSize > 100 {
pageSize = 100
}
offset := (page - 1) * pageSize
dbQuery = dbQuery.Offset(offset).Limit(pageSize)
return dbQuery
}
func (op *DocumentsListOperation) Exec() ([]model.Document, error) {
dbQuery := op.buildBaseQuery()
dbQuery = op.appendOtherArgs(dbQuery)
var documents []model.Document
err := dbQuery.Find(&documents).Error
if err != nil {
return nil, err
}
return documents, nil
}
func (op *DocumentsListOperation) ExecWithTotal() ([]model.Document, int64, error) {
dbQuery := op.buildBaseQuery()
var total int64
err := dbQuery.Count(&total).Error
if err != nil {
return nil, 0, err
}
dbQuery = op.appendOtherArgs(dbQuery)
var documents []model.Document
err = dbQuery.Find(&documents).Error
if err != nil {
return nil, 0, err
}
return documents, total, nil
}