项目文件夹

文件
wehub-resource-sync a21fa4e11b
Go / Build (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:30:21 +08:00

493 行
15 KiB
Go

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
package controllers
import (
"fmt"
"github.com/phachon/mm-wiki/app/services"
"regexp"
"strings"
"github.com/phachon/mm-wiki/app/models"
"github.com/phachon/mm-wiki/app/utils"
)
type DocumentController struct {
BaseController
}
// document index
func (this *DocumentController) Index() {
documentId := this.GetString("document_id", "")
if documentId == "" {
this.ViewError("页面参数错误!", "/space/index")
}
document, err := models.DocumentModel.GetDocumentByDocumentId(documentId)
if err != nil {
this.ErrorLog("查找空间文档 " + documentId + " 失败:" + err.Error())
this.ViewError("查找文档失败!")
}
if len(document) == 0 {
this.ViewError("文档不存在!")
}
spaceId := document["space_id"]
space, err := models.SpaceModel.GetSpaceBySpaceId(spaceId)
if err != nil {
this.ErrorLog("查找文档 " + documentId + " 所在空间失败:" + err.Error())
this.ViewError("查找文档失败!")
}
if len(space) == 0 {
this.ViewError("文档所在空间不存在!")
}
// check space visit_level
isVisit, _, _ := this.GetDocumentPrivilege(space)
if !isVisit {
this.ViewError("您没有权限访问该空间下的文档!")
}
// get default space document
spaceDocument, err := models.DocumentModel.GetSpaceDefaultDocument(spaceId)
if err != nil {
this.ErrorLog("查找文档 " + documentId + " 失败:" + err.Error())
this.ViewError("查找文档失败!")
}
if len(spaceDocument) == 0 {
this.ViewError(" 空间首页文档不存在!")
}
// get space all document
documents, err := models.DocumentModel.GetAllSpaceDocuments(spaceId)
if err != nil {
this.ErrorLog("查找文档 " + documentId + " 所在空间失败:" + err.Error())
this.ViewError("查找文档失败!")
}
// get space privilege
_, isEditor, isDelete := this.GetDocumentPrivilege(space)
this.Data["is_editor"] = isEditor
this.Data["is_delete"] = isDelete
this.Data["documents"] = documents
this.Data["default_document_id"] = documentId
this.Data["space"] = space
this.Data["space_document"] = spaceDocument
this.viewLayout("document/index", "document")
}
// add document
func (this *DocumentController) Add() {
spaceId := this.GetString("space_id", "0")
parentId := this.GetString("parent_id", "0")
if spaceId == "0" {
this.ViewError("没有选择空间!")
}
if parentId == "0" {
this.ViewError("没有选择上级!")
}
space, err := models.SpaceModel.GetSpaceBySpaceId(spaceId)
if err != nil {
this.ErrorLog("添加文档失败:" + err.Error())
this.ViewError("添加文档失败!")
}
if len(space) == 0 {
this.ViewError("空间不存在!")
}
// check space document privilege
_, isEditor, _ := this.GetDocumentPrivilege(space)
if !isEditor {
this.ViewError("您没有权限在该空间下创建文档!")
}
parentDocument, err := models.DocumentModel.GetDocumentByDocumentId(parentId)
if err != nil {
this.ErrorLog("添加文档 " + parentId + " 失败:" + err.Error())
this.ViewError("添加文档失败!")
}
if len(parentDocument) == 0 {
this.ViewError("父文档不存在!")
}
path := parentDocument["path"] + "," + parentId
// get parent documents by path
parentDocuments, err := models.DocumentModel.GetParentDocumentsByPath(path)
if err != nil {
this.ErrorLog("查找父文档失败:" + err.Error())
this.ViewError("查找父文档失败!")
}
if len(parentDocuments) == 0 {
this.ViewError("父文档不存在!")
}
this.Data["parent_documents"] = parentDocuments
this.Data["parent_id"] = parentId
this.Data["space_id"] = spaceId
this.viewLayout("document/form", "default")
}
// save document
func (this *DocumentController) Save() {
if !this.IsPost() {
this.ViewError("请求方式有误!", "/main/index")
}
spaceId := strings.TrimSpace(this.GetString("space_id", "0"))
parentId := strings.TrimSpace(this.GetString("parent_id", "0"))
docType, _ := this.GetInt("type", models.Document_Type_Page)
name := strings.TrimSpace(this.GetString("name", ""))
if spaceId == "0" {
this.jsonError("没有选择空间!")
}
if parentId == "0" {
this.jsonError("没有选择父文档!")
}
if name == "" {
this.jsonError("文档名称不能为空!")
}
match, err := regexp.MatchString(`[\\\\/:*?\"<>、|]`, name)
if err != nil {
this.jsonError("文档名称格式不正确!")
}
if match {
this.jsonError("文档名称格式不正确!")
}
if name == utils.Document_Default_FileName {
this.jsonError("文档名称不能为 " + utils.Document_Default_FileName + " ")
}
if docType != models.Document_Type_Page &&
docType != models.Document_Type_Dir {
this.jsonError("文档类型错误!")
}
space, err := models.SpaceModel.GetSpaceBySpaceId(spaceId)
if err != nil {
this.ErrorLog("创建保存文档失败:" + err.Error())
this.jsonError("创建文档失败!")
}
if len(space) == 0 {
this.jsonError("空间不存在!")
}
// check space document privilege
_, isEditor, _ := this.GetDocumentPrivilege(space)
if !isEditor {
this.jsonError("您没有权限在该空间下创建文档!")
}
parentDocument, err := models.DocumentModel.GetDocumentByDocumentId(parentId)
if err != nil {
this.ErrorLog("创建保存文档失败:" + err.Error())
this.jsonError("创建文档失败!")
}
if len(parentDocument) == 0 {
this.jsonError("父文档不存在!")
}
if parentDocument["type"] != fmt.Sprintf("%d", models.Document_Type_Dir) {
this.jsonError("父文档不是目录!")
}
// check document name
document, err := models.DocumentModel.GetDocumentByNameParentIdAndSpaceId(name, parentId, spaceId, docType)
if err != nil {
this.ErrorLog("创建保存文档失败:" + err.Error())
this.jsonError("创建文档失败!")
}
if len(document) != 0 {
this.jsonError("该文档名称已经存在!")
}
insertDocument := map[string]interface{}{
"parent_id": parentId,
"space_id": spaceId,
"name": name,
"type": docType,
"path": parentDocument["path"] + "," + parentId,
"create_user_id": this.UserId,
"edit_user_id": this.UserId,
}
documentId, err := models.DocumentModel.Insert(insertDocument)
if err != nil {
this.ErrorLog("创建文档失败:" + err.Error())
this.jsonError("创建文档失败")
}
this.InfoLog("创建文档 " + utils.Convert.IntToString(documentId, 10) + " 成功")
this.jsonSuccess("创建文档成功", nil, "/document/index?document_id="+utils.Convert.IntToString(documentId, 10))
}
// document history
func (this *DocumentController) History() {
page, _ := this.GetInt("page", 1)
documentId := this.GetString("document_id", "0")
number, _ := this.GetRangeInt("number", 10, 10, 100)
limit := (page - 1) * number
if documentId == "0" {
this.ViewError("没有选择文档目录!")
}
document, err := models.DocumentModel.GetDocumentByDocumentId(documentId)
if err != nil {
this.ErrorLog("查看文档 " + documentId + " 修改历史失败:" + err.Error())
this.ViewError("查看文档修改历史失败!")
}
if len(document) == 0 {
this.jsonError("文档不存在!")
}
spaceId := document["space_id"]
space, err := models.SpaceModel.GetSpaceBySpaceId(spaceId)
if err != nil {
this.ErrorLog("查找文档 " + documentId + " 所在空间失败:" + err.Error())
this.ViewError("查找文档失败!")
}
if len(space) == 0 {
this.ViewError("文档所在空间不存在!")
}
// check space visit_level
isVisit, _, _ := this.GetDocumentPrivilege(space)
if !isVisit {
this.ViewError("您没有权限查看该空间修改历史!")
}
logDocuments, err := models.LogDocumentModel.GetLogDocumentsByDocumentIdAndLimit(documentId, limit, number)
if err != nil {
this.ErrorLog("查看文档 " + documentId + " 修改历史失败:" + err.Error())
this.ViewError("查看文档修改历史失败!")
}
count, err := models.LogDocumentModel.CountLogDocumentsByDocumentId(documentId)
if err != nil {
this.ErrorLog("查看文档 " + documentId + " 修改历史失败:" + err.Error())
this.ViewError("查看文档修改历史失败!")
}
userIds := []string{}
for _, logDocument := range logDocuments {
userIds = append(userIds, logDocument["user_id"])
}
users, err := models.UserModel.GetUsersByUserIds(userIds)
if err != nil {
this.ErrorLog("查看文档 " + documentId + " 修改历史失败:" + err.Error())
this.ViewError("查看文档修改历史失败!")
}
for _, logDocument := range logDocuments {
logDocument["username"] = ""
for _, user := range users {
if logDocument["user_id"] == user["user_id"] {
logDocument["username"] = user["username"]
break
}
}
}
this.Data["logDocuments"] = logDocuments
this.SetPaginator(number, count)
this.viewLayout("document/history", "default")
}
// move document
func (this *DocumentController) Move() {
documentId := this.GetString("document_id", "0")
targetId := this.GetString("target_id", "0")
moveType := this.GetString("move_type", "") // 同层文件排序
if documentId == "0" {
this.jsonError("没有选择文档节点!")
}
if targetId == "0" {
this.jsonError("没有选择目标文档节点!")
}
document, err := models.DocumentModel.GetDocumentByDocumentId(documentId)
if err != nil {
this.ErrorLog("查找移动文档失败:" + err.Error())
this.jsonError("移动文档失败!")
}
if len(document) == 0 {
this.jsonError("文档不存在!")
}
if moveType != "next" && moveType != "prev" {
if document["type"] == fmt.Sprintf("%d", models.Document_Type_Dir) {
this.jsonError("不能移动文档目录!")
}
}
targetDocument, err := models.DocumentModel.GetDocumentByDocumentId(targetId)
if err != nil {
this.ErrorLog("查找目标文档失败:" + err.Error())
this.jsonError("移动文档失败!")
}
if len(targetDocument) == 0 {
this.jsonError("目标文档不存在!")
}
if document["space_id"] != targetDocument["space_id"] {
this.jsonError("文档和目标文档不在同一空间!")
}
if moveType != "next" && moveType != "prev" {
if targetDocument["type"] != fmt.Sprintf("%d", models.Document_Type_Dir) {
this.jsonError("目标文档必须是目录!")
}
}
spaceId := document["space_id"]
space, err := models.SpaceModel.GetSpaceBySpaceId(spaceId)
if err != nil {
this.ErrorLog("移动文档失败:" + err.Error())
this.jsonError("移动文档失败!")
}
if len(space) == 0 {
this.jsonError("文档空间不存在!")
}
// check space document privilege
_, isEditor, _ := this.GetDocumentPrivilege(space)
if !isEditor {
this.jsonError("您没有权限移动该空间下的文档!")
}
// 排序逻辑:next-移动到目标文档之后 prev-移动到目标文档之前
if moveType == "next" || moveType == "prev" {
this.updateDocSequence(moveType, document, targetDocument)
return
}
_, oldPageFile, err := models.DocumentModel.GetParentDocumentsByDocument(document)
if err != nil {
this.ErrorLog("移动文档 " + documentId + " 失败:" + err.Error())
this.jsonError("移动文档失败!")
}
newDocument := map[string]string{
"space_id": document["space_id"],
"parent_id": targetId,
"name": document["name"],
"type": document["type"],
"path": targetDocument["path"] + "," + targetId,
}
_, newPageFile, err := models.DocumentModel.GetParentDocumentsByDocument(newDocument)
if err != nil {
this.ErrorLog("移动文档 " + documentId + " 失败:" + err.Error())
this.jsonError("移动文档失败!")
}
// update database and move document file
updateValue := map[string]interface{}{
"parent_id": targetId,
"path": targetDocument["path"] + "," + targetId,
"edit_user_id": this.UserId,
}
_, err = models.DocumentModel.MoveDBAndFile(documentId, spaceId, updateValue,
oldPageFile, newPageFile, document["type"], "移动文档到 "+targetDocument["name"])
if err != nil {
this.ErrorLog("移动文档 " + documentId + " 失败:" + err.Error())
this.jsonError("移动文档失败!")
}
this.InfoLog("移动文档 " + documentId + " 成功")
this.jsonSuccess("移动文档成功", nil, "/document/index?document_id="+documentId)
}
// 移动文档排序
func (this *DocumentController) updateDocSequence(moveType string, document map[string]string, targetDocument map[string]string) {
sequence := utils.Convert.StringToInt(targetDocument["sequence"])
spaceId := targetDocument["space_id"]
targetDocumentId := targetDocument["document_id"]
movedDocumentId := document["document_id"]
updateSequence := sequence
if moveType == "next" {
updateSequence = sequence + 1
}
// 批量修改序号
_, err := models.DocumentModel.MoveSequenceBySpaceIdAndGtSequence(spaceId, updateSequence, 1)
if err != nil {
this.ErrorLog("移动文档 " + movedDocumentId + "到目标文档 " + targetDocumentId + " " + moveType + " 失败:" + err.Error())
this.jsonError("移动文档失败!")
}
// 修改当前文档的序号
updateValue := map[string]interface{}{
"sequence": updateSequence,
"edit_user_id": this.UserId,
}
_, err = models.DocumentModel.Update(movedDocumentId, updateValue, fmt.Sprintf("移动文档"), spaceId)
if err != nil {
this.ErrorLog("移动文档 " + movedDocumentId + "到目标文档 " + targetDocumentId + " " + moveType + " 失败:" + err.Error())
this.jsonError("移动文档失败!")
}
this.jsonSuccess("移动文档成功", "", "/document/index?document_id="+movedDocumentId)
}
// delete document
func (this *DocumentController) Delete() {
documentId := this.GetString("document_id", "0")
if documentId == "0" {
this.jsonError("没有选择文档!")
}
document, err := models.DocumentModel.GetDocumentByDocumentId(documentId)
if err != nil {
this.ErrorLog("删除文档失败:" + err.Error())
this.jsonError("删除文档失败!")
}
if len(document) == 0 {
this.jsonError("文档不存在!")
}
if document["type"] == fmt.Sprintf("%d", models.Document_Type_Dir) {
childDocs, err := models.DocumentModel.GetDocumentsByParentId(document["document_id"])
if err != nil {
this.ErrorLog("删除文档失败:" + err.Error())
this.jsonError("删除文档失败!")
}
if len(childDocs) > 0 {
this.jsonError("请先删除或移动目录下所有文档!")
}
}
spaceId := document["space_id"]
space, err := models.SpaceModel.GetSpaceBySpaceId(document["space_id"])
if err != nil {
this.ErrorLog("删除文档失败:" + err.Error())
this.jsonError("删除文档失败!")
}
if len(space) == 0 {
this.jsonError("文档空间不存在!")
}
// check space document privilege
_, _, isManager := this.GetDocumentPrivilege(space)
if !isManager {
this.jsonError("您没有权限删除该空间下的文档!")
}
_, pageFile, err := models.DocumentModel.GetParentDocumentsByDocument(document)
if err != nil {
this.ErrorLog("删除文档 " + documentId + " 失败:" + err.Error())
this.jsonError("删除文档失败!")
}
err = models.DocumentModel.DeleteDBAndFile(documentId, spaceId, this.UserId, pageFile, document["type"])
if err != nil {
this.ErrorLog("删除文档 " + documentId + " 失败:" + err.Error())
this.jsonError("删除文档失败!")
}
// delete attachment
err = models.AttachmentModel.DeleteAttachmentsDBFileByDocumentId(documentId)
if err != nil {
this.ErrorLog("删除文档 " + documentId + " 附件失败:" + err.Error())
}
// 删除文档索引
go func(documentId string) {
services.DocIndexService.ForceDelDocIdIndex(documentId)
}(documentId)
this.InfoLog("删除文档 " + documentId + " 成功")
this.jsonSuccess("删除文档成功", "", "/document/index?document_id="+document["parent_id"])
}