document.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. package controllers
  2. import (
  3. "os"
  4. "time"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. "net/http"
  9. "path/filepath"
  10. "encoding/json"
  11. "html/template"
  12. "container/list"
  13. "github.com/lifei6671/godoc/models"
  14. "github.com/lifei6671/godoc/conf"
  15. "github.com/astaxie/beego"
  16. "github.com/astaxie/beego/orm"
  17. "github.com/lifei6671/godoc/utils"
  18. )
  19. //DocumentController struct.
  20. type DocumentController struct {
  21. BaseController
  22. }
  23. //判断用户是否可以阅读文档.
  24. func isReadable (identify,token string,c *DocumentController) *models.BookResult {
  25. book, err := models.NewBook().FindByFieldFirst("identify", identify)
  26. if err != nil {
  27. beego.Error(err)
  28. c.Abort("500")
  29. }
  30. if c.Member != nil && c.Member.Role == conf.MemberSuperRole {
  31. bookResult := book.ToBookResult()
  32. return bookResult
  33. }
  34. //如果文档是私有的
  35. if book.PrivatelyOwned == 1 {
  36. is_ok := false
  37. if c.Member != nil {
  38. _, err := models.NewRelationship().FindForRoleId(book.BookId, c.Member.MemberId)
  39. if err == nil {
  40. is_ok = true
  41. }
  42. }
  43. if book.PrivateToken != "" && !is_ok {
  44. //如果有访问的Token,并且该项目设置了访问Token,并且和用户提供的相匹配,则记录到Session中.
  45. //如果用户未提供Token且用户登录了,则判断用户是否参与了该项目.
  46. //如果用户未登录,则从Session中读取Token.
  47. if token != "" && strings.EqualFold(token, book.PrivateToken) {
  48. c.SetSession(identify, token)
  49. } else if token, ok := c.GetSession(identify).(string); !ok || !strings.EqualFold(token, book.PrivateToken) {
  50. c.Abort("403")
  51. }
  52. } else if !is_ok {
  53. c.Abort("403")
  54. }
  55. }
  56. bookResult := book.ToBookResult()
  57. if c.Member != nil {
  58. rel, err := models.NewRelationship().FindByBookIdAndMemberId(bookResult.BookId, c.Member.MemberId)
  59. if err == nil {
  60. bookResult.MemberId = rel.MemberId
  61. bookResult.RoleId = rel.RoleId
  62. bookResult.RelationshipId = rel.RelationshipId
  63. }
  64. }
  65. //判断是否需要显示评论框
  66. if bookResult.CommentStatus == "closed" {
  67. bookResult.IsDisplayComment = false
  68. } else if bookResult.CommentStatus == "open" {
  69. bookResult.IsDisplayComment = true
  70. } else if bookResult.CommentStatus == "group_only" {
  71. bookResult.IsDisplayComment = bookResult.RelationshipId > 0
  72. } else if bookResult.CommentStatus == "registered_only" {
  73. bookResult.IsDisplayComment = true
  74. }
  75. return bookResult
  76. }
  77. //文档首页.
  78. func (c *DocumentController) Index() {
  79. c.Prepare()
  80. identify := c.Ctx.Input.Param(":key")
  81. token := c.GetString("token")
  82. if identify == "" {
  83. c.Abort("404")
  84. }
  85. //如果没有开启你们访问则跳转到登录
  86. if !c.EnableAnonymous && c.Member == nil {
  87. c.Redirect(beego.URLFor("AccountController.Login"),302)
  88. return
  89. }
  90. bookResult := isReadable(identify,token,c)
  91. c.TplName = "document/" + bookResult.Theme + "_read.tpl"
  92. tree,err := models.NewDocument().CreateDocumentTreeForHtml(bookResult.BookId,0)
  93. if err != nil {
  94. beego.Error(err)
  95. c.Abort("500")
  96. }
  97. c.Data["Model"] = bookResult
  98. c.Data["Result"] = template.HTML(tree)
  99. c.Data["Title"] = "概要"
  100. c.Data["Content"] = bookResult.Description
  101. }
  102. //阅读文档.
  103. func (c *DocumentController) Read() {
  104. c.Prepare()
  105. identify := c.Ctx.Input.Param(":key")
  106. token := c.GetString("token")
  107. id := c.GetString(":id")
  108. if identify == "" || id == ""{
  109. c.Abort("404")
  110. }
  111. //如果没有开启你们访问则跳转到登录
  112. if !c.EnableAnonymous && c.Member == nil {
  113. c.Redirect(beego.URLFor("AccountController.Login"),302)
  114. return
  115. }
  116. bookResult := isReadable(identify,token,c)
  117. c.TplName = "document/" + bookResult.Theme + "_read.tpl"
  118. doc := models.NewDocument()
  119. if doc_id,err := strconv.Atoi(id);err == nil {
  120. doc,err = doc.Find(doc_id)
  121. if err != nil {
  122. beego.Error(err)
  123. c.Abort("500")
  124. }
  125. }else{
  126. doc,err = doc.FindByFieldFirst("identify",id)
  127. if err != nil {
  128. beego.Error(err)
  129. c.Abort("500")
  130. }
  131. }
  132. if doc.BookId != bookResult.BookId {
  133. c.Abort("403")
  134. }
  135. if c.IsAjax() {
  136. var data struct{
  137. DocTitle string `json:"doc_title"`
  138. Body string `json:"body"`
  139. Title string `json:"title"`
  140. }
  141. data.DocTitle = doc.DocumentName
  142. data.Body = doc.Release
  143. data.Title = doc.DocumentName + " - Powered by MinDoc"
  144. c.JsonResult(0,"ok",data)
  145. }
  146. tree,err := models.NewDocument().CreateDocumentTreeForHtml(bookResult.BookId,doc.DocumentId)
  147. if err != nil {
  148. beego.Error(err)
  149. c.Abort("500")
  150. }
  151. c.Data["Model"] = bookResult
  152. c.Data["Result"] = template.HTML(tree)
  153. c.Data["Title"] = doc.DocumentName
  154. c.Data["Content"] = template.HTML(doc.Release)
  155. }
  156. //编辑文档.
  157. func (c *DocumentController) Edit() {
  158. c.Prepare()
  159. identify := c.Ctx.Input.Param(":key")
  160. if identify == "" {
  161. c.Abort("404")
  162. }
  163. bookResult := models.NewBookResult()
  164. var err error
  165. //如果是超级管理者,则不判断权限
  166. if c.Member.Role == conf.MemberSuperRole {
  167. book,err := models.NewBook().FindByFieldFirst("identify",identify)
  168. if err != nil {
  169. c.JsonResult(6002, "项目不存在或权限不足")
  170. }
  171. bookResult = book.ToBookResult()
  172. }else {
  173. bookResult, err = models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
  174. if err != nil {
  175. beego.Error("DocumentController.Edit => ", err)
  176. c.Abort("403")
  177. }
  178. if bookResult.RoleId == conf.BookObserver {
  179. c.JsonResult(6002, "项目不存在或权限不足")
  180. }
  181. }
  182. //根据不同编辑器类型加载编辑器
  183. if bookResult.Editor == "markdown" {
  184. c.TplName = "document/markdown_edit_template.tpl"
  185. }else if bookResult.Editor == "html"{
  186. c.TplName = "document/html_edit_template.tpl"
  187. }else{
  188. c.TplName = "document/" + bookResult.Editor + "_edit_template.tpl"
  189. }
  190. c.Data["Model"] = bookResult
  191. r,_ := json.Marshal(bookResult)
  192. c.Data["ModelResult"] = template.JS(string(r))
  193. c.Data["Result"] = template.JS("[]")
  194. trees ,err := models.NewDocument().FindDocumentTree(bookResult.BookId)
  195. if err != nil {
  196. beego.Error("FindDocumentTree => ", err)
  197. }else{
  198. if len(trees) > 0 {
  199. if jtree, err := json.Marshal(trees); err == nil {
  200. c.Data["Result"] = template.JS(string(jtree))
  201. }
  202. }else{
  203. c.Data["Result"] = template.JS("[]")
  204. }
  205. }
  206. c.Data["BaiDuMapKey"] = beego.AppConfig.DefaultString("baidumapkey","")
  207. }
  208. //创建一个文档.
  209. func (c *DocumentController) Create() {
  210. identify := c.GetString("identify")
  211. doc_identify := c.GetString("doc_identify")
  212. doc_name := c.GetString("doc_name")
  213. parent_id,_ := c.GetInt("parent_id",0)
  214. doc_id,_ := c.GetInt("doc_id",0)
  215. if identify == "" {
  216. c.JsonResult(6001,"参数错误")
  217. }
  218. if doc_name == "" {
  219. c.JsonResult(6004,"文档名称不能为空")
  220. }
  221. if doc_identify != "" {
  222. if ok, err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`, doc_identify); !ok || err != nil {
  223. c.JsonResult(6003, "文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头")
  224. }
  225. d,_ := models.NewDocument().FindByFieldFirst("identify",doc_identify);
  226. if d.DocumentId > 0 && d.DocumentId != doc_id{
  227. c.JsonResult(6006,"文档标识已被使用")
  228. }
  229. }
  230. book_id := 0
  231. //如果是超级管理员则不判断权限
  232. if c.Member.Role == conf.MemberSuperRole {
  233. book,err := models.NewBook().FindByFieldFirst("identify",identify)
  234. if err != nil {
  235. beego.Error(err)
  236. c.JsonResult(6002, "项目不存在或权限不足")
  237. }
  238. book_id = book.BookId
  239. }else{
  240. bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
  241. if err != nil || bookResult.RoleId == conf.BookObserver {
  242. beego.Error("FindByIdentify => ", err)
  243. c.JsonResult(6002, "项目不存在或权限不足")
  244. }
  245. book_id = bookResult.BookId
  246. }
  247. if parent_id > 0 {
  248. doc,err := models.NewDocument().Find(parent_id)
  249. if err != nil || doc.BookId != book_id {
  250. c.JsonResult(6003,"父分类不存在")
  251. }
  252. }
  253. document,_ := models.NewDocument().Find(doc_id)
  254. document.MemberId = c.Member.MemberId
  255. document.BookId = book_id
  256. if doc_identify != ""{
  257. document.Identify = doc_identify
  258. }
  259. document.Version = time.Now().Unix()
  260. document.DocumentName = doc_name
  261. document.ParentId = parent_id
  262. if err := document.InsertOrUpdate();err != nil {
  263. beego.Error("InsertOrUpdate => ",err)
  264. c.JsonResult(6005,"保存失败")
  265. }else{
  266. c.JsonResult(0,"ok",document)
  267. }
  268. }
  269. //上传附件或图片.
  270. func (c *DocumentController) Upload() {
  271. identify := c.GetString("identify")
  272. doc_id,_ := c.GetInt("doc_id")
  273. is_attach := true
  274. if identify == "" {
  275. c.JsonResult(6001,"参数错误")
  276. }
  277. name := "editormd-file-file"
  278. file,moreFile,err := c.GetFile(name)
  279. if err == http.ErrMissingFile {
  280. name = "editormd-image-file"
  281. file,moreFile,err = c.GetFile(name);
  282. if err == http.ErrMissingFile {
  283. c.JsonResult(6003,"没有发现需要上传的文件")
  284. }
  285. }
  286. if err != nil {
  287. c.JsonResult(6002,err.Error())
  288. }
  289. defer file.Close()
  290. ext := filepath.Ext(moreFile.Filename)
  291. if ext == "" {
  292. c.JsonResult(6003,"无法解析文件的格式")
  293. }
  294. if !conf.IsAllowUploadFileExt(ext) {
  295. c.JsonResult(6004,"不允许的文件类型")
  296. }
  297. book_id := 0
  298. //如果是超级管理员,则不判断权限
  299. if c.Member.Role == conf.MemberSuperRole {
  300. book,err := models.NewBook().FindByFieldFirst("identify",identify)
  301. if err != nil {
  302. c.JsonResult(6006, "文档不存在或权限不足")
  303. }
  304. book_id = book.BookId
  305. }else{
  306. book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
  307. if err != nil {
  308. beego.Error("DocumentController.Edit => ", err)
  309. if err == orm.ErrNoRows {
  310. c.JsonResult(6006, "权限不足")
  311. }
  312. c.JsonResult(6001, err.Error())
  313. }
  314. //如果没有编辑权限
  315. if book.RoleId != conf.BookEditor && book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder {
  316. c.JsonResult(6006, "权限不足")
  317. }
  318. book_id = book.BookId
  319. }
  320. if doc_id > 0 {
  321. doc,err := models.NewDocument().Find(doc_id);
  322. if err != nil {
  323. c.JsonResult(6007,"文档不存在")
  324. }
  325. if doc.BookId != book_id {
  326. c.JsonResult(6008,"文档不属于指定的项目")
  327. }
  328. }
  329. fileName := "attach_" + strconv.FormatInt(time.Now().UnixNano(), 16)
  330. filePath := "uploads/" + time.Now().Format("200601") + "/" + fileName + ext
  331. path := filepath.Dir(filePath)
  332. os.MkdirAll(path, os.ModePerm)
  333. err = c.SaveToFile(name,filePath)
  334. if err != nil {
  335. beego.Error("SaveToFile => ",err)
  336. c.JsonResult(6005,"保存文件失败")
  337. }
  338. attachment := models.NewAttachment()
  339. attachment.BookId = book_id
  340. attachment.FileName = moreFile.Filename
  341. attachment.CreateAt = c.Member.MemberId
  342. attachment.FileExt = ext
  343. attachment.FilePath = filePath
  344. attachment.DocumentId = doc_id
  345. if fileInfo, err := os.Stat(filePath); err == nil {
  346. attachment.FileSize = float64(fileInfo.Size())
  347. }
  348. if doc_id > 0{
  349. attachment.DocumentId = doc_id
  350. }
  351. if strings.EqualFold(ext,".jpg") || strings.EqualFold(ext,".jpeg") || strings.EqualFold(ext,"png") || strings.EqualFold(ext,"gif") {
  352. attachment.HttpPath = "/" + filePath
  353. is_attach = false
  354. }
  355. err = attachment.Insert();
  356. if err != nil {
  357. os.Remove(filePath)
  358. beego.Error("Attachment Insert => ",err)
  359. c.JsonResult(6006,"文件保存失败")
  360. }
  361. if attachment.HttpPath == "" {
  362. attachment.HttpPath = beego.URLFor("DocumentController.DownloadAttachment",":key", identify, ":attach_id", attachment.AttachmentId)
  363. if err := attachment.Update();err != nil {
  364. beego.Error("SaveToFile => ",err)
  365. c.JsonResult(6005,"保存文件失败")
  366. }
  367. }
  368. result := map[string]interface{}{
  369. "errcode" : 0,
  370. "success" : 1,
  371. "message" :"ok",
  372. "url" : attachment.HttpPath,
  373. "alt" : attachment.FileName,
  374. "is_attach" : is_attach,
  375. "attach" : attachment,
  376. }
  377. c.Data["json"] = result
  378. c.ServeJSON(true)
  379. c.StopRun()
  380. }
  381. //DownloadAttachment 下载附件.
  382. func (c *DocumentController) DownloadAttachment() {
  383. c.Prepare()
  384. identify := c.Ctx.Input.Param(":key")
  385. attach_id,_ := strconv.Atoi(c.Ctx.Input.Param(":attach_id"))
  386. token := c.GetString("token")
  387. member_id := 0
  388. if c.Member != nil {
  389. member_id = c.Member.MemberId
  390. }
  391. book_id := 0
  392. //判断用户是否参与了项目
  393. bookResult,err := models.NewBookResult().FindByIdentify(identify,member_id)
  394. if err != nil {
  395. //判断项目公开状态
  396. book, err := models.NewBook().FindByFieldFirst("identify", identify)
  397. if err != nil {
  398. c.Abort("404")
  399. }
  400. //如果不是超级管理员则判断权限
  401. if c.Member == nil || c.Member.Role != conf.MemberSuperRole {
  402. //如果项目是私有的,并且token不正确
  403. if (book.PrivatelyOwned == 1 && token == "" ) || ( book.PrivatelyOwned == 1 && book.PrivateToken != token ) {
  404. c.Abort("403")
  405. }
  406. }
  407. book_id = book.BookId
  408. }else{
  409. book_id = bookResult.BookId
  410. }
  411. //查找附件
  412. attachment,err := models.NewAttachment().Find(attach_id)
  413. if err != nil {
  414. beego.Error("DownloadAttachment => ", err)
  415. if err == orm.ErrNoRows {
  416. c.Abort("404")
  417. } else {
  418. c.Abort("500")
  419. }
  420. }
  421. if attachment.BookId != book_id {
  422. c.Abort("404")
  423. }
  424. c.Ctx.Output.Download(attachment.FilePath,attachment.FileName)
  425. c.StopRun()
  426. }
  427. //删除附件.
  428. func (c *DocumentController) RemoveAttachment() {
  429. c.Prepare()
  430. attach_id ,_ := c.GetInt("attach_id")
  431. if attach_id <= 0 {
  432. c.JsonResult(6001,"参数错误")
  433. }
  434. attach,err := models.NewAttachment().Find(attach_id)
  435. if err != nil {
  436. beego.Error(err)
  437. c.JsonResult(6002,"附件不存在")
  438. }
  439. document,err := models.NewDocument().Find(attach.DocumentId)
  440. if err != nil {
  441. beego.Error(err)
  442. c.JsonResult(6003,"文档不存在")
  443. }
  444. if c.Member.Role != conf.MemberSuperRole {
  445. rel,err := models.NewRelationship().FindByBookIdAndMemberId(document.BookId,c.Member.MemberId)
  446. if err != nil {
  447. beego.Error(err)
  448. c.JsonResult(6004,"权限不足")
  449. }
  450. if rel.RoleId == conf.BookObserver {
  451. c.JsonResult(6004,"权限不足")
  452. }
  453. }
  454. err = attach.Delete()
  455. if err != nil {
  456. beego.Error(err)
  457. c.JsonResult(6005,"删除失败")
  458. }
  459. c.JsonResult(0,"ok",attach)
  460. }
  461. //删除文档.
  462. func (c *DocumentController) Delete() {
  463. c.Prepare()
  464. identify := c.GetString("identify")
  465. doc_id,err := c.GetInt("doc_id",0)
  466. book_id := 0
  467. //如果是超级管理员则忽略权限判断
  468. if c.Member.Role == conf.MemberSuperRole {
  469. book,err := models.NewBook().FindByFieldFirst("identify",identify)
  470. if err != nil {
  471. beego.Error("FindByIdentify => ", err)
  472. c.JsonResult(6002, "项目不存在或权限不足")
  473. }
  474. book_id = book.BookId
  475. }else {
  476. bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
  477. if err != nil || bookResult.RoleId == conf.BookObserver {
  478. beego.Error("FindByIdentify => ", err)
  479. c.JsonResult(6002, "项目不存在或权限不足")
  480. }
  481. book_id = bookResult.BookId
  482. }
  483. if doc_id <= 0 {
  484. c.JsonResult(6001,"参数错误")
  485. }
  486. doc,err := models.NewDocument().Find(doc_id)
  487. if err != nil {
  488. beego.Error("Delete => ",err)
  489. c.JsonResult(6003,"删除失败")
  490. }
  491. //如果文档所属项目错误
  492. if doc.BookId != book_id {
  493. c.JsonResult(6004,"参数错误")
  494. }
  495. //递归删除项目下的文档以及子文档
  496. err = doc.RecursiveDocument(doc.DocumentId)
  497. if err != nil {
  498. c.JsonResult(6005,"删除失败")
  499. }
  500. //重置文档数量统计
  501. models.NewBook().ResetDocumentNumber(doc.BookId)
  502. c.JsonResult(0,"ok")
  503. }
  504. //获取文档内容.
  505. func (c *DocumentController) Content() {
  506. c.Prepare()
  507. identify := c.Ctx.Input.Param(":key")
  508. doc_id,err := c.GetInt("doc_id")
  509. if err != nil {
  510. doc_id,_ = strconv.Atoi(c.Ctx.Input.Param(":id"))
  511. }
  512. book_id := 0
  513. //如果是超级管理员,则忽略权限
  514. if c.Member.Role == conf.MemberSuperRole {
  515. book ,err := models.NewBook().FindByFieldFirst("identify",identify)
  516. if err != nil {
  517. c.JsonResult(6002, "项目不存在或权限不足")
  518. }
  519. book_id = book.BookId
  520. }else {
  521. bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
  522. if err != nil || bookResult.RoleId == conf.BookObserver {
  523. beego.Error("FindByIdentify => ", err)
  524. c.JsonResult(6002, "项目不存在或权限不足")
  525. }
  526. book_id = bookResult.BookId
  527. }
  528. if doc_id <= 0 {
  529. c.JsonResult(6001,"参数错误")
  530. }
  531. if c.Ctx.Input.IsPost() {
  532. markdown := strings.TrimSpace(c.GetString("markdown",""))
  533. content := c.GetString("html")
  534. version,_ := c.GetInt64("version",0)
  535. is_cover := c.GetString("cover")
  536. doc ,err := models.NewDocument().Find(doc_id);
  537. if err != nil {
  538. c.JsonResult(6003,"读取文档错误")
  539. }
  540. if doc.BookId != book_id {
  541. c.JsonResult(6004,"保存的文档不属于指定项目")
  542. }
  543. if doc.Version != version && !strings.EqualFold(is_cover,"yes"){
  544. beego.Info("%d|",version,doc.Version)
  545. c.JsonResult(6005,"文档已被修改确定要覆盖吗?")
  546. }
  547. if markdown == "" && content != ""{
  548. doc.Markdown = content
  549. }else{
  550. doc.Markdown = markdown
  551. }
  552. doc.Version = time.Now().Unix()
  553. doc.Content = content
  554. if err := doc.InsertOrUpdate();err != nil {
  555. beego.Error("InsertOrUpdate => ",err)
  556. c.JsonResult(6006,"保存失败")
  557. }
  558. c.JsonResult(0,"ok",doc)
  559. }
  560. doc,err := models.NewDocument().Find(doc_id)
  561. if err != nil {
  562. c.JsonResult(6003,"文档不存在")
  563. }
  564. attach,err := models.NewAttachment().FindListByDocumentId(doc.DocumentId)
  565. if err == nil {
  566. doc.AttachList = attach
  567. }
  568. c.JsonResult(0,"ok",doc)
  569. }
  570. //导出文件
  571. func (c *DocumentController) Export() {
  572. c.Prepare()
  573. c.TplName = "document/export.tpl"
  574. identify := c.Ctx.Input.Param(":key")
  575. output := c.GetString("output")
  576. token := c.GetString("token")
  577. if identify == "" {
  578. c.Abort("404")
  579. }
  580. //如果没有开启你们访问则跳转到登录
  581. if !c.EnableAnonymous && c.Member == nil {
  582. c.Redirect(beego.URLFor("AccountController.Login"),302)
  583. return
  584. }
  585. bookResult := models.NewBookResult()
  586. if c.Member != nil && c.Member.Role == conf.MemberSuperRole {
  587. book,err := models.NewBook().FindByIdentify(identify)
  588. if err != nil {
  589. beego.Error(err)
  590. c.Abort("500")
  591. }
  592. bookResult = book.ToBookResult()
  593. }else {
  594. bookResult = isReadable(identify, token, c)
  595. }
  596. docs, err := models.NewDocument().FindListByBookId(bookResult.BookId)
  597. if err != nil {
  598. beego.Error(err)
  599. c.Abort("500")
  600. }
  601. if output == "pdf" {
  602. exe := beego.AppConfig.String("wkhtmltopdf")
  603. if exe == "" {
  604. c.TplName = "errors/error.tpl";
  605. c.Data["ErrorMessage"] = "没有配置PDF导出程序"
  606. c.Data["ErrorCode"] = 50010
  607. return
  608. }
  609. dpath := "cache/" + bookResult.Identify
  610. os.MkdirAll(dpath, 0766)
  611. pathList := list.New()
  612. RecursiveFun(0, "", dpath, c, bookResult, docs, pathList)
  613. defer os.RemoveAll(dpath)
  614. os.MkdirAll("./cache", 0766)
  615. pdfpath := "cache/" + identify + "_" + c.CruSession.SessionID() + ".pdf"
  616. if _,err := os.Stat(pdfpath); os.IsNotExist(err){
  617. paths := make([]string, len(docs))
  618. index := 0
  619. for e := pathList.Front(); e != nil; e = e.Next() {
  620. paths[index] = e.Value.(string)
  621. index ++
  622. }
  623. beego.Info(paths,pdfpath)
  624. utils.ConverterHtmlToPdf(paths, pdfpath)
  625. }
  626. c.Ctx.Output.Download(pdfpath, identify + ".pdf")
  627. defer os.Remove(pdfpath)
  628. c.StopRun()
  629. }
  630. c.Abort("404")
  631. }
  632. //递归生成文档序列数组.
  633. func RecursiveFun(parent_id int,prefix,dpath string,c *DocumentController,book *models.BookResult,docs []*models.Document,paths *list.List) {
  634. for _, item := range docs {
  635. if item.ParentId == parent_id {
  636. name := prefix + strconv.Itoa(item.ParentId) + strconv.Itoa(item.OrderSort) + strconv.Itoa(item.DocumentId)
  637. fpath := dpath + "/" + name + ".html"
  638. paths.PushBack(fpath)
  639. f, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0777)
  640. if err != nil {
  641. beego.Error(err)
  642. c.Abort("500")
  643. }
  644. html, err := c.ExecuteViewPathTemplate("document/export.tpl", map[string]interface{}{"Model" : book, "Lists":item,"BaseUrl" : c.BaseUrl()})
  645. if err != nil {
  646. f.Close()
  647. beego.Error(err)
  648. c.Abort("500")
  649. }
  650. beego.Info(fpath,html)
  651. f.WriteString(html)
  652. f.Close()
  653. for _, sub := range docs {
  654. if sub.ParentId == item.DocumentId {
  655. RecursiveFun(item.DocumentId,name,dpath,c,book,docs,paths)
  656. break;
  657. }
  658. }
  659. }
  660. }
  661. }