manager.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "html/template"
  5. "regexp"
  6. "strings"
  7. "math"
  8. "path/filepath"
  9. "strconv"
  10. "github.com/astaxie/beego"
  11. "github.com/astaxie/beego/logs"
  12. "github.com/astaxie/beego/orm"
  13. "github.com/lifei6671/mindoc/conf"
  14. "github.com/lifei6671/mindoc/models"
  15. "github.com/lifei6671/mindoc/utils"
  16. "github.com/lifei6671/mindoc/utils/filetil"
  17. "github.com/lifei6671/mindoc/utils/pagination"
  18. "gopkg.in/russross/blackfriday.v2"
  19. )
  20. type ManagerController struct {
  21. BaseController
  22. }
  23. func (c *ManagerController) Prepare() {
  24. c.BaseController.Prepare()
  25. if !c.Member.IsAdministrator() {
  26. c.Abort("403")
  27. }
  28. }
  29. func (c *ManagerController) Index() {
  30. c.TplName = "manager/index.tpl"
  31. c.Data["Model"] = models.NewDashboard().Query()
  32. }
  33. // 用户列表.
  34. func (c *ManagerController) Users() {
  35. c.Prepare()
  36. c.TplName = "manager/users.tpl"
  37. pageIndex, _ := c.GetInt("page", 0)
  38. members, totalCount, err := models.NewMember().FindToPager(pageIndex, conf.PageSize)
  39. if err != nil {
  40. c.Data["ErrorMessage"] = err.Error()
  41. return
  42. }
  43. if totalCount > 0 {
  44. pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
  45. c.Data["PageHtml"] = pager.HtmlPages()
  46. } else {
  47. c.Data["PageHtml"] = ""
  48. }
  49. b, err := json.Marshal(members)
  50. if err != nil {
  51. c.Data["Result"] = template.JS("[]")
  52. } else {
  53. c.Data["Result"] = template.JS(string(b))
  54. }
  55. }
  56. // 添加用户.
  57. func (c *ManagerController) CreateMember() {
  58. c.Prepare()
  59. account := strings.TrimSpace(c.GetString("account"))
  60. password1 := strings.TrimSpace(c.GetString("password1"))
  61. password2 := strings.TrimSpace(c.GetString("password2"))
  62. email := strings.TrimSpace(c.GetString("email"))
  63. phone := strings.TrimSpace(c.GetString("phone"))
  64. role, _ := c.GetInt("role", 1)
  65. status, _ := c.GetInt("status", 0)
  66. if ok, err := regexp.MatchString(conf.RegexpAccount, account); account == "" || !ok || err != nil {
  67. c.JsonResult(6001, "账号只能由英文字母数字组成,且在3-50个字符")
  68. }
  69. if l := strings.Count(password1, ""); password1 == "" || l > 50 || l < 6 {
  70. c.JsonResult(6002, "密码必须在6-50个字符之间")
  71. }
  72. if password1 != password2 {
  73. c.JsonResult(6003, "确认密码不正确")
  74. }
  75. if ok, err := regexp.MatchString(conf.RegexpEmail, email); !ok || err != nil || email == "" {
  76. c.JsonResult(6004, "邮箱格式不正确")
  77. }
  78. if role != 0 && role != 1 && role != 2 {
  79. role = 1
  80. }
  81. if status != 0 && status != 1 {
  82. status = 0
  83. }
  84. member := models.NewMember()
  85. if _, err := member.FindByAccount(account); err == nil && member.MemberId > 0 {
  86. c.JsonResult(6005, "账号已存在")
  87. }
  88. member.Account = account
  89. member.Password = password1
  90. member.Role = role
  91. member.Avatar = conf.GetDefaultAvatar()
  92. member.CreateAt = c.Member.MemberId
  93. member.Email = email
  94. member.RealName = strings.TrimSpace(c.GetString("real_name", ""))
  95. if phone != "" {
  96. member.Phone = phone
  97. }
  98. if err := member.Add(); err != nil {
  99. c.JsonResult(6006, err.Error())
  100. }
  101. c.JsonResult(0, "ok", member)
  102. }
  103. //更新用户状态.
  104. func (c *ManagerController) UpdateMemberStatus() {
  105. c.Prepare()
  106. member_id, _ := c.GetInt("member_id", 0)
  107. status, _ := c.GetInt("status", 0)
  108. if member_id <= 0 {
  109. c.JsonResult(6001, "参数错误")
  110. }
  111. if status != 0 && status != 1 {
  112. status = 0
  113. }
  114. member := models.NewMember()
  115. if _, err := member.Find(member_id); err != nil {
  116. c.JsonResult(6002, "用户不存在")
  117. }
  118. if member.MemberId == c.Member.MemberId {
  119. c.JsonResult(6004, "不能变更自己的状态")
  120. }
  121. if member.Role == conf.MemberSuperRole {
  122. c.JsonResult(6005, "不能变更超级管理员的状态")
  123. }
  124. member.Status = status
  125. if err := member.Update(); err != nil {
  126. logs.Error("", err)
  127. c.JsonResult(6003, "用户状态设置失败")
  128. }
  129. c.JsonResult(0, "ok", member)
  130. }
  131. //变更用户权限.
  132. func (c *ManagerController) ChangeMemberRole() {
  133. c.Prepare()
  134. member_id, _ := c.GetInt("member_id", 0)
  135. role, _ := c.GetInt("role", 0)
  136. if member_id <= 0 {
  137. c.JsonResult(6001, "参数错误")
  138. }
  139. if role != conf.MemberAdminRole && role != conf.MemberGeneralRole {
  140. c.JsonResult(6001, "用户权限不正确")
  141. }
  142. member := models.NewMember()
  143. if _, err := member.Find(member_id); err != nil {
  144. c.JsonResult(6002, "用户不存在")
  145. }
  146. if member.MemberId == c.Member.MemberId {
  147. c.JsonResult(6004, "不能变更自己的权限")
  148. }
  149. if member.Role == conf.MemberSuperRole {
  150. c.JsonResult(6005, "不能变更超级管理员的权限")
  151. }
  152. member.Role = role
  153. if err := member.Update(); err != nil {
  154. c.JsonResult(6003, "用户权限设置失败")
  155. }
  156. member.ResolveRoleName()
  157. c.JsonResult(0, "ok", member)
  158. }
  159. //编辑用户信息.
  160. func (c *ManagerController) EditMember() {
  161. c.Prepare()
  162. c.TplName = "manager/edit_users.tpl"
  163. member_id, _ := c.GetInt(":id", 0)
  164. if member_id <= 0 {
  165. c.Abort("404")
  166. }
  167. member, err := models.NewMember().Find(member_id)
  168. if err != nil {
  169. beego.Error(err)
  170. c.Abort("404")
  171. }
  172. if c.Ctx.Input.IsPost() {
  173. password1 := c.GetString("password1")
  174. password2 := c.GetString("password2")
  175. email := c.GetString("email")
  176. phone := c.GetString("phone")
  177. description := c.GetString("description")
  178. member.Email = email
  179. member.Phone = phone
  180. member.Description = description
  181. member.RealName = c.GetString("real_name")
  182. if password1 != "" && password2 != password1 {
  183. c.JsonResult(6001, "确认密码不正确")
  184. }
  185. if password1 != "" && member.AuthMethod != conf.AuthMethodLDAP {
  186. member.Password = password1
  187. }
  188. if err := member.Valid(password1 == ""); err != nil {
  189. c.JsonResult(6002, err.Error())
  190. }
  191. if password1 != "" {
  192. password, err := utils.PasswordHash(password1)
  193. if err != nil {
  194. beego.Error(err)
  195. c.JsonResult(6003, "对用户密码加密时出错")
  196. }
  197. member.Password = password
  198. }
  199. if err := member.Update(); err != nil {
  200. c.JsonResult(6004, err.Error())
  201. }
  202. c.JsonResult(0, "ok")
  203. }
  204. c.Data["Model"] = member
  205. }
  206. //删除一个用户,并将该用户的所有信息转移到超级管理员上.
  207. func (c *ManagerController) DeleteMember() {
  208. c.Prepare()
  209. member_id, _ := c.GetInt("id", 0)
  210. if member_id <= 0 {
  211. c.JsonResult(404, "参数错误")
  212. }
  213. member, err := models.NewMember().Find(member_id)
  214. if err != nil {
  215. beego.Error(err)
  216. c.JsonResult(500, "用户不存在")
  217. }
  218. if member.Role == conf.MemberSuperRole {
  219. c.JsonResult(500, "不能删除超级管理员")
  220. }
  221. superMember, err := models.NewMember().FindByFieldFirst("role", 0)
  222. if err != nil {
  223. beego.Error(err)
  224. c.JsonResult(5001, "未能找到超级管理员")
  225. }
  226. err = models.NewMember().Delete(member_id, superMember.MemberId)
  227. if err != nil {
  228. beego.Error(err)
  229. c.JsonResult(5002, "删除失败")
  230. }
  231. c.JsonResult(0, "ok")
  232. }
  233. //项目列表.
  234. func (c *ManagerController) Books() {
  235. c.Prepare()
  236. c.TplName = "manager/books.tpl"
  237. pageIndex, _ := c.GetInt("page", 1)
  238. books, totalCount, err := models.NewBookResult().FindToPager(pageIndex, conf.PageSize)
  239. if err != nil {
  240. c.Abort("500")
  241. }
  242. if totalCount > 0 {
  243. //html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, 8, totalCount)
  244. pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
  245. c.Data["PageHtml"] = pager.HtmlPages()
  246. } else {
  247. c.Data["PageHtml"] = ""
  248. }
  249. for i, book := range books {
  250. books[i].Description = utils.StripTags(string(blackfriday.Run([]byte(book.Description))))
  251. books[i].ModifyTime = book.ModifyTime.Local()
  252. books[i].CreateTime = book.CreateTime.Local()
  253. }
  254. c.Data["Lists"] = books
  255. }
  256. //编辑项目.
  257. func (c *ManagerController) EditBook() {
  258. c.Prepare()
  259. c.TplName = "manager/edit_book.tpl"
  260. identify := c.GetString(":key")
  261. if identify == "" {
  262. c.Abort("404")
  263. }
  264. book, err := models.NewBook().FindByFieldFirst("identify", identify)
  265. if err != nil {
  266. c.Abort("500")
  267. }
  268. if c.Ctx.Input.IsPost() {
  269. bookName := strings.TrimSpace(c.GetString("book_name"))
  270. description := strings.TrimSpace(c.GetString("description", ""))
  271. commentStatus := c.GetString("comment_status")
  272. tag := strings.TrimSpace(c.GetString("label"))
  273. orderIndex, _ := c.GetInt("order_index", 0)
  274. isDownload := strings.TrimSpace(c.GetString("is_download")) == "on"
  275. enableShare := strings.TrimSpace(c.GetString("enable_share")) == "on"
  276. isUseFirstDocument := strings.TrimSpace(c.GetString("is_use_first_document")) == "on"
  277. autoRelease := strings.TrimSpace(c.GetString("auto_release")) == "on"
  278. publisher := strings.TrimSpace(c.GetString("publisher"))
  279. historyCount, _ := c.GetInt("history_count", 0)
  280. if strings.Count(description, "") > 500 {
  281. c.JsonResult(6004, "项目描述不能大于500字")
  282. }
  283. if commentStatus != "open" && commentStatus != "closed" && commentStatus != "group_only" && commentStatus != "registered_only" {
  284. commentStatus = "closed"
  285. }
  286. if tag != "" {
  287. tags := strings.Split(tag, ";")
  288. if len(tags) > 10 {
  289. c.JsonResult(6005, "最多允许添加10个标签")
  290. }
  291. }
  292. book.Publisher = publisher
  293. book.HistoryCount = historyCount
  294. book.BookName = bookName
  295. book.Description = description
  296. book.CommentStatus = commentStatus
  297. book.Label = tag
  298. book.OrderIndex = orderIndex
  299. if autoRelease {
  300. book.AutoRelease = 1
  301. } else {
  302. book.AutoRelease = 0
  303. }
  304. if isDownload {
  305. book.IsDownload = 0
  306. } else {
  307. book.IsDownload = 1
  308. }
  309. if enableShare {
  310. book.IsEnableShare = 0
  311. } else {
  312. book.IsEnableShare = 1
  313. }
  314. if isUseFirstDocument {
  315. book.IsUseFirstDocument = 1
  316. } else {
  317. book.IsUseFirstDocument = 0
  318. }
  319. if err := book.Update(); err != nil {
  320. c.JsonResult(6006, "保存失败")
  321. }
  322. c.JsonResult(0, "ok")
  323. }
  324. if book.PrivateToken != "" {
  325. book.PrivateToken = conf.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken)
  326. }
  327. bookResult := models.NewBookResult()
  328. bookResult.ToBookResult(*book)
  329. c.Data["Model"] = bookResult
  330. }
  331. // 删除项目.
  332. func (c *ManagerController) DeleteBook() {
  333. c.Prepare()
  334. bookId, _ := c.GetInt("book_id", 0)
  335. if bookId <= 0 {
  336. c.JsonResult(6001, "参数错误")
  337. }
  338. book := models.NewBook()
  339. err := book.ThoroughDeleteBook(bookId)
  340. if err == orm.ErrNoRows {
  341. c.JsonResult(6002, "项目不存在")
  342. }
  343. if err != nil {
  344. logs.Error("DeleteBook => ", err)
  345. c.JsonResult(6003, "删除失败")
  346. }
  347. c.JsonResult(0, "ok")
  348. }
  349. // CreateToken 创建访问来令牌.
  350. func (c *ManagerController) CreateToken() {
  351. c.Prepare()
  352. action := c.GetString("action")
  353. identify := c.GetString("identify")
  354. book, err := models.NewBook().FindByFieldFirst("identify", identify)
  355. if err != nil {
  356. c.JsonResult(6001, "项目不存在")
  357. }
  358. if action == "create" {
  359. if book.PrivatelyOwned == 0 {
  360. c.JsonResult(6001, "公开项目不能创建阅读令牌")
  361. }
  362. book.PrivateToken = string(utils.Krand(conf.GetTokenSize(), utils.KC_RAND_KIND_ALL))
  363. if err := book.Update(); err != nil {
  364. logs.Error("生成阅读令牌失败 => ", err)
  365. c.JsonResult(6003, "生成阅读令牌失败")
  366. }
  367. c.JsonResult(0, "ok", conf.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken))
  368. } else {
  369. book.PrivateToken = ""
  370. if err := book.Update(); err != nil {
  371. logs.Error("CreateToken => ", err)
  372. c.JsonResult(6004, "删除令牌失败")
  373. }
  374. c.JsonResult(0, "ok", "")
  375. }
  376. }
  377. //项目设置.
  378. func (c *ManagerController) Setting() {
  379. c.Prepare()
  380. c.TplName = "manager/setting.tpl"
  381. options, err := models.NewOption().All()
  382. if c.Ctx.Input.IsPost() {
  383. for _, item := range options {
  384. item.OptionValue = c.GetString(item.OptionName)
  385. item.InsertOrUpdate()
  386. }
  387. c.JsonResult(0, "ok")
  388. }
  389. if err != nil {
  390. c.Abort("500")
  391. }
  392. c.Data["SITE_TITLE"] = c.Option["SITE_NAME"]
  393. for _, item := range options {
  394. c.Data[item.OptionName] = item.OptionValue
  395. }
  396. }
  397. // Transfer 转让项目.
  398. func (c *ManagerController) Transfer() {
  399. c.Prepare()
  400. account := c.GetString("account")
  401. if account == "" {
  402. c.JsonResult(6004, "接受者账号不能为空")
  403. }
  404. member, err := models.NewMember().FindByAccount(account)
  405. if err != nil {
  406. logs.Error("FindByAccount => ", err)
  407. c.JsonResult(6005, "接受用户不存在")
  408. }
  409. if member.Status != 0 {
  410. c.JsonResult(6006, "接受用户已被禁用")
  411. }
  412. if !c.Member.IsAdministrator() {
  413. c.Abort("403")
  414. }
  415. identify := c.GetString("identify")
  416. book, err := models.NewBook().FindByFieldFirst("identify", identify)
  417. if err != nil {
  418. c.JsonResult(6001, err.Error())
  419. }
  420. rel, err := models.NewRelationship().FindFounder(book.BookId)
  421. if err != nil {
  422. beego.Error("FindFounder => ", err)
  423. c.JsonResult(6009, "查询项目创始人失败")
  424. }
  425. if member.MemberId == rel.MemberId {
  426. c.JsonResult(6007, "不能转让给自己")
  427. }
  428. err = models.NewRelationship().Transfer(book.BookId, rel.MemberId, member.MemberId)
  429. if err != nil {
  430. logs.Error("Transfer => ", err)
  431. c.JsonResult(6008, err.Error())
  432. }
  433. c.JsonResult(0, "ok")
  434. }
  435. func (c *ManagerController) Comments() {
  436. c.Prepare()
  437. c.TplName = "manager/comments.tpl"
  438. if !c.Member.IsAdministrator() {
  439. c.Abort("403")
  440. }
  441. }
  442. //DeleteComment 标记评论为已删除
  443. func (c *ManagerController) DeleteComment() {
  444. c.Prepare()
  445. comment_id, _ := c.GetInt("comment_id", 0)
  446. if comment_id <= 0 {
  447. c.JsonResult(6001, "参数错误")
  448. }
  449. comment := models.NewComment()
  450. if _, err := comment.Find(comment_id); err != nil {
  451. c.JsonResult(6002, "评论不存在")
  452. }
  453. comment.Approved = 3
  454. if err := comment.Update("approved"); err != nil {
  455. c.JsonResult(6003, "删除评论失败")
  456. }
  457. c.JsonResult(0, "ok", comment)
  458. }
  459. //设置项目私有状态.
  460. func (c *ManagerController) PrivatelyOwned() {
  461. c.Prepare()
  462. status := c.GetString("status")
  463. identify := c.GetString("identify")
  464. if status != "open" && status != "close" {
  465. c.JsonResult(6003, "参数错误")
  466. }
  467. state := 0
  468. if status == "open" {
  469. state = 0
  470. } else {
  471. state = 1
  472. }
  473. if !c.Member.IsAdministrator() {
  474. c.Abort("403")
  475. }
  476. book, err := models.NewBook().FindByFieldFirst("identify", identify)
  477. if err != nil {
  478. c.JsonResult(6001, err.Error())
  479. }
  480. book.PrivatelyOwned = state
  481. logs.Info("", state, status)
  482. err = book.Update()
  483. if err != nil {
  484. logs.Error("PrivatelyOwned => ", err)
  485. c.JsonResult(6004, "保存失败")
  486. }
  487. c.JsonResult(0, "ok")
  488. }
  489. //附件列表.
  490. func (c *ManagerController) AttachList() {
  491. c.Prepare()
  492. c.TplName = "manager/attach_list.tpl"
  493. pageIndex, _ := c.GetInt("page", 1)
  494. attachList, totalCount, err := models.NewAttachment().FindToPager(pageIndex, conf.PageSize)
  495. if err != nil {
  496. c.Abort("500")
  497. }
  498. if totalCount > 0 {
  499. pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
  500. c.Data["PageHtml"] = pager.HtmlPages()
  501. } else {
  502. c.Data["PageHtml"] = ""
  503. }
  504. for _, item := range attachList {
  505. p := filepath.Join(conf.WorkingDirectory, item.FilePath)
  506. item.IsExist = filetil.FileExists(p)
  507. }
  508. c.Data["Lists"] = attachList
  509. }
  510. //附件详情.
  511. func (c *ManagerController) AttachDetailed() {
  512. c.Prepare()
  513. c.TplName = "manager/attach_detailed.tpl"
  514. attach_id, _ := strconv.Atoi(c.Ctx.Input.Param(":id"))
  515. if attach_id <= 0 {
  516. c.Abort("404")
  517. }
  518. attach, err := models.NewAttachmentResult().Find(attach_id)
  519. if err != nil {
  520. beego.Error("AttachDetailed => ", err)
  521. if err == orm.ErrNoRows {
  522. c.Abort("404")
  523. } else {
  524. c.Abort("500")
  525. }
  526. }
  527. attach.FilePath = filepath.Join(conf.WorkingDirectory, attach.FilePath)
  528. attach.HttpPath = conf.URLForWithCdnImage(attach.HttpPath)
  529. attach.IsExist = filetil.FileExists(attach.FilePath)
  530. c.Data["Model"] = attach
  531. }
  532. //删除附件.
  533. func (c *ManagerController) AttachDelete() {
  534. c.Prepare()
  535. attach_id, _ := c.GetInt("attach_id")
  536. if attach_id <= 0 {
  537. c.Abort("404")
  538. }
  539. attach, err := models.NewAttachment().Find(attach_id)
  540. if err != nil {
  541. beego.Error("AttachDelete => ", err)
  542. c.JsonResult(6001, err.Error())
  543. }
  544. if err := attach.Delete(); err != nil {
  545. beego.Error("AttachDelete => ", err)
  546. c.JsonResult(6002, err.Error())
  547. }
  548. c.JsonResult(0, "ok")
  549. }
  550. //标签列表
  551. func (c *ManagerController) LabelList() {
  552. c.Prepare()
  553. c.TplName = "manager/label_list.tpl"
  554. pageIndex, _ := c.GetInt("page", 1)
  555. labels, totalCount, err := models.NewLabel().FindToPager(pageIndex, conf.PageSize)
  556. if err != nil {
  557. c.ShowErrorPage(50001, err.Error())
  558. }
  559. if totalCount > 0 {
  560. pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
  561. c.Data["PageHtml"] = pager.HtmlPages()
  562. } else {
  563. c.Data["PageHtml"] = ""
  564. }
  565. c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(conf.PageSize)))
  566. c.Data["Lists"] = labels
  567. }
  568. //删除标签
  569. func (c *ManagerController) LabelDelete() {
  570. labelId, err := strconv.Atoi(c.Ctx.Input.Param(":id"))
  571. if err != nil {
  572. beego.Error("获取删除标签参数时出错:", err)
  573. c.JsonResult(50001, "参数错误")
  574. }
  575. if labelId <= 0 {
  576. c.JsonResult(50001, "参数错误")
  577. }
  578. label, err := models.NewLabel().FindFirst("label_id", labelId)
  579. if err != nil {
  580. beego.Error("查询标签时出错:", err)
  581. c.JsonResult(50001, "查询标签时出错:"+err.Error())
  582. }
  583. if err := label.Delete(); err != nil {
  584. c.JsonResult(50002, "删除失败:"+err.Error())
  585. } else {
  586. c.JsonResult(0, "ok")
  587. }
  588. }