report.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "go-common/app/admin/main/reply/model"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. "go-common/library/queue/databus/report"
  12. "go-common/library/sync/errgroup"
  13. xtime "go-common/library/time"
  14. )
  15. func forbidResult(ftime int64) string {
  16. if ftime == -1 {
  17. return "永久"
  18. }
  19. return fmt.Sprintf("%d天", ftime)
  20. }
  21. func (s *Service) report(c context.Context, oid, rpID int64) (report *model.Report, err error) {
  22. if report, err = s.dao.Report(c, oid, rpID); err != nil {
  23. return
  24. }
  25. if report == nil {
  26. err = ecode.ReplyReportNotExist
  27. }
  28. return
  29. }
  30. func (s *Service) reports(c context.Context, oids, rpIDs []int64) (res map[int64]*model.Report, err error) {
  31. if res, err = s.dao.Reports(c, oids, rpIDs); err != nil {
  32. return
  33. }
  34. return
  35. }
  36. // ReportSearch return report result from search.
  37. func (s *Service) ReportSearch(c context.Context, sp *model.SearchReportParams, page, pageSize int64) (res *model.SearchReportResult, err error) {
  38. if res, err = s.dao.SearchReport(c, sp, page, pageSize); err != nil {
  39. log.Error("s.dao.SearchReport(%+v,%d,%d) error(%v)", sp, page, pageSize, err)
  40. return
  41. }
  42. filterIds := map[int64]string{}
  43. oids := map[int64]string{}
  44. admins := map[int64]string{}
  45. titles := map[int64]string{}
  46. for _, r := range res.Result {
  47. r.OidStr = strconv.FormatInt(r.Oid, 10)
  48. if strings.Contains(r.Message, "*") {
  49. filterIds[r.ID] = ""
  50. } else if len(r.Attr) > 0 {
  51. for _, attr := range r.Attr {
  52. if attr == 4 {
  53. filterIds[r.ID] = ""
  54. }
  55. }
  56. }
  57. admins[r.AdminID] = ""
  58. if r.ReplyMid == r.ArcMid {
  59. r.IsUp = 1
  60. }
  61. oids[r.Oid] = ""
  62. if int32(r.Type) == model.SubTypeArchive {
  63. titles[r.Oid] = ""
  64. }
  65. }
  66. s.linkByOids(c, oids, sp.Type)
  67. s.titlesByOids(c, titles)
  68. s.dao.AdminName(c, admins)
  69. s.dao.FilterContents(c, filterIds)
  70. for i, data := range res.Result {
  71. res.Result[i].AdminName = admins[res.Result[i].AdminID]
  72. if content, ok := filterIds[data.ID]; ok && content != "" {
  73. data.Message = content
  74. }
  75. if content, ok := oids[data.Oid]; ok {
  76. data.RedirectURL = fmt.Sprintf("%s#reply%d", content, data.ID)
  77. }
  78. if int32(data.Type) == model.SubTypeArchive && data.Title == "" {
  79. if title := titles[data.Oid]; title != "" {
  80. data.Title = title
  81. }
  82. }
  83. }
  84. return
  85. }
  86. // ReportIgnore ignore a report.
  87. func (s *Service) ReportIgnore(c context.Context, oids, rpIDs []int64, adminID int64, adName string, typ, audit int32, remark string, delReport bool) (err error) {
  88. var (
  89. state int32
  90. op int32
  91. result string
  92. action string
  93. )
  94. if audit == model.AuditTypeFirst {
  95. result = "一审忽略"
  96. op = model.AdminOperRptIgnore1
  97. state = model.ReportStateIgnore1
  98. action = model.ReportActionReportIgnore1
  99. } else if audit == model.AuditTypeSecond {
  100. result = "二审忽略"
  101. op = model.AdminOperRptIgnore2
  102. state = model.ReportStateIgnore2
  103. action = model.ReportActionReportIgnore2
  104. } else {
  105. err = ecode.RequestErr
  106. return
  107. }
  108. subs, err := s.subjects(c, oids, typ)
  109. if err != nil {
  110. log.Error("ReportIgnore subjects(%v,%v,%d) error(%v)", oids, typ, state, err)
  111. return
  112. }
  113. rps, err := s.replies(c, oids, rpIDs)
  114. if err != nil {
  115. log.Error("ReportIgnore replies(%v,%v,%d) error(%v)", oids, rpIDs, state, err)
  116. return
  117. }
  118. rpts, err := s.reports(c, oids, rpIDs)
  119. if err != nil {
  120. log.Error("ReportIgnore reports(%v,%v,%d) error(%v)", oids, rpIDs, state, err)
  121. return
  122. }
  123. now := time.Now()
  124. rows, err := s.dao.UpReportsState(c, oids, rpIDs, state, now)
  125. if err != nil {
  126. log.Error("ReportIgnore UpReportsState(%v,%v,%d) rows:%d error(%v)", oids, rpIDs, state, rows, err)
  127. return
  128. } else if rows == 0 {
  129. return
  130. }
  131. for _, rp := range rps {
  132. rpt, ok := rpts[rp.ID]
  133. if !ok {
  134. continue
  135. }
  136. sub, ok := subs[rpt.Oid]
  137. if !ok {
  138. continue
  139. }
  140. s.pubEvent(c, model.EventReportDel, rpt.Mid, sub, rp, rpt)
  141. }
  142. for _, rpt := range rpts {
  143. report.Manager(&report.ManagerInfo{
  144. UID: adminID,
  145. Uname: adName,
  146. Business: 41,
  147. Type: int(typ),
  148. Oid: rpt.Oid,
  149. Ctime: now,
  150. Action: action,
  151. Index: []interface{}{
  152. rpt.RpID,
  153. rpt.State,
  154. state,
  155. },
  156. Content: map[string]interface{}{
  157. "remark": remark,
  158. },
  159. })
  160. rpt.State = state
  161. rpt.MTime = xtime.Time(now.Unix())
  162. if delReport {
  163. s.cache.Do(c, func(ctx context.Context) {
  164. s.dao.DelReport(ctx, rpt.Oid, rpt.RpID)
  165. })
  166. }
  167. }
  168. s.addAdminLogs(c, rps, adminID, typ, model.AdminIsNew, model.AdminIsReport, op, result, remark, now)
  169. s.cache.Do(c, func(ctx context.Context) {
  170. s.pubSearchReport(ctx, rpts, nil)
  171. })
  172. return
  173. }
  174. // ReportDel delete reply by report.
  175. func (s *Service) ReportDel(c context.Context, oids, rpIDs []int64, adminID, ftime int64, typ, audit, moral, reason, freason int32, notify bool, adminName, remark, content string) (err error) {
  176. return s.reportDel(c, oids, rpIDs, adminID, ftime, typ, audit, moral, reason, freason, notify, adminName, remark, content)
  177. }
  178. func (s *Service) reportDel(c context.Context, oids, rpIDs []int64, adminID, ftime int64, typ, audit, moral, reason, freason int32, notify bool, adminName, remark, content string) (err error) {
  179. var (
  180. op int32
  181. rptState int32
  182. action string
  183. )
  184. if audit == model.AuditTypeFirst {
  185. op = model.AdminOperRptDel1
  186. rptState = model.ReportStateDelete1
  187. action = model.ReportActionReportDel1
  188. } else if audit == model.AuditTypeSecond {
  189. op = model.AdminOperRptDel2
  190. rptState = model.ReportStateDelete2
  191. action = model.ReportActionReportDel2
  192. } else {
  193. err = ecode.RequestErr
  194. return
  195. }
  196. now := time.Now()
  197. rpts, err := s.reports(c, oids, rpIDs)
  198. if err != nil {
  199. log.Error("reportDel reports(%v, %v) error(%v)", oids, rpIDs, err)
  200. return
  201. }
  202. wg, ctx := errgroup.WithContext(c)
  203. for _, rept := range rpts {
  204. rpt := rept
  205. wg.Go(func() (err error) {
  206. isPunish := false
  207. var sub *model.Subject
  208. var rp *model.Reply
  209. sub, rp, err = s.delReply(ctx, rpt.Oid, rpt.RpID, model.StateDelAdmin, now)
  210. if err != nil {
  211. if ecode.ReplyDeleted.Equal(err) && rp.IsDeleted() {
  212. isPunish = true
  213. err = nil
  214. } else {
  215. log.Error("reportDel tranDel(%d, %d) error(%v)", rpt.Oid, rpt.RpID, err)
  216. return err
  217. }
  218. }
  219. s.delCache(ctx, sub, rp)
  220. rea := reason
  221. if reason == -1 {
  222. rea = rpt.Reason
  223. }
  224. report.Manager(&report.ManagerInfo{
  225. UID: adminID,
  226. Uname: adminName,
  227. Business: 41,
  228. Type: int(typ),
  229. Oid: rpt.Oid,
  230. Ctime: now,
  231. Action: action,
  232. Index: []interface{}{
  233. rpt.RpID,
  234. rpt.State,
  235. rptState,
  236. },
  237. Content: map[string]interface{}{
  238. "moral": moral,
  239. "notify": notify,
  240. "ftime": ftime,
  241. "freason": freason,
  242. "reason": rea,
  243. "remark": remark,
  244. },
  245. })
  246. rpt.State = rptState
  247. rpt.MTime = xtime.Time(now.Unix())
  248. rpt.ReplyCtime = rp.CTime
  249. s.pubEvent(ctx, model.EventReportDel, rpt.Mid, sub, rp, rpt)
  250. s.cache.Do(c, func(ctx context.Context) {
  251. s.dao.DelReport(ctx, rp.Oid, rp.ID)
  252. s.moralAndNotify(ctx, rp, moral, notify, rp.Mid, adminID, adminName, remark, rea, freason, ftime, isPunish)
  253. })
  254. return nil
  255. })
  256. }
  257. if err = wg.Wait(); err != nil {
  258. return
  259. }
  260. var rows int64
  261. if reason == -1 {
  262. rows, err = s.dao.UpReportsState(c, oids, rpIDs, rptState, now)
  263. } else {
  264. rows, err = s.dao.UpReportsStateWithReason(c, oids, rpIDs, rptState, reason, content, now)
  265. }
  266. if err != nil || rows == 0 {
  267. return
  268. }
  269. s.cache.Do(c, func(ctx context.Context) {
  270. state := model.StateDelAdmin
  271. s.pubSearchReport(ctx, rpts, &state)
  272. })
  273. s.addAdminIDLogs(c, oids, rpIDs, adminID, typ, model.AdminIsNew, model.AdminIsReport, op, fmt.Sprintf("已通过举报并删除封禁%s/扣除%d节操", forbidResult(ftime), moral), remark, now)
  274. return
  275. }
  276. // ReportRecover recover a report reply.
  277. func (s *Service) ReportRecover(c context.Context, oids, rpIDs []int64, adminID int64, typ, audit int32, remark string) (err error) {
  278. s.reportRecover(c, oids, rpIDs, adminID, typ, audit, remark)
  279. return
  280. }
  281. func (s *Service) reportRecover(c context.Context, oids, rpIDs []int64, adminID int64, typ, audit int32, remark string) (err error) {
  282. var (
  283. rptState int32
  284. op int32
  285. result string
  286. )
  287. if audit == model.AuditTypeFirst {
  288. result = "一审恢复评论"
  289. op = model.AdminOperRptRecover1
  290. rptState = model.ReportStateIgnore1
  291. } else if audit == model.AuditTypeSecond {
  292. result = "二审恢复评论"
  293. op = model.AdminOperRptRecover2
  294. rptState = model.ReportStateIgnore2
  295. } else {
  296. err = ecode.RequestErr
  297. return
  298. }
  299. now := time.Now()
  300. rpts, err := s.reports(c, oids, rpIDs)
  301. if err != nil {
  302. log.Error("ReportRecover reports(%v, %v) error(%v)", oids, rpIDs, err)
  303. return
  304. }
  305. var rps = map[int64]*model.Reply{}
  306. wg, ctx := errgroup.WithContext(c)
  307. for _, report := range rpts {
  308. rpt := report
  309. wg.Go(func() (err error) {
  310. sub, rp, err := s.recReply(ctx, rpt.Oid, rpt.RpID, model.StateNormal, now)
  311. if err != nil {
  312. log.Error("ReportRecover tranRecover(%d, %d) error(%v)", rpt.Oid, rpt.RpID, err)
  313. return
  314. }
  315. rpt.MTime = xtime.Time(now.Unix())
  316. rpt.State = rptState
  317. s.pubEvent(ctx, model.EventReportRecover, rpt.Mid, sub, rp, rpt)
  318. rps[rp.ID] = rp
  319. return
  320. })
  321. }
  322. if err = wg.Wait(); err != nil {
  323. return
  324. }
  325. rows, err := s.dao.UpReportsState(c, oids, rpIDs, rptState, now)
  326. if err != nil {
  327. return
  328. } else if rows == 0 {
  329. return
  330. }
  331. s.addAdminIDLogs(c, oids, rpIDs, adminID, typ, model.AdminIsNew, model.AdminIsReport, op, result, remark, now)
  332. s.cache.Do(c, func(ctx context.Context) {
  333. s.pubSearchReply(ctx, rps, model.StateNormal)
  334. })
  335. return
  336. }
  337. // ReportTransfer transfer a report.
  338. func (s *Service) ReportTransfer(c context.Context, oids, rpIDs []int64, adminID int64, adName string, typ, audit int32, remark string) (err error) {
  339. var (
  340. state int32
  341. op int32
  342. result string
  343. action string
  344. )
  345. if audit == model.AuditTypeFirst {
  346. result = "二审转一审"
  347. op = model.AdminOperRptTransfer1
  348. state = model.ReportStateNew
  349. action = model.ReportActionReport2To1
  350. } else if audit == model.AuditTypeSecond {
  351. result = "一审转二审"
  352. op = model.AdminOperRptTransfer2
  353. state = model.ReportStateNew2
  354. action = model.ReportActionReport1To2
  355. } else {
  356. err = ecode.RequestErr
  357. return
  358. }
  359. rpts, err := s.reports(c, oids, rpIDs)
  360. if err != nil {
  361. return
  362. }
  363. now := time.Now()
  364. var tranOids, tranRpIDs []int64
  365. var tranRpt []*model.Report
  366. for _, rpt := range rpts {
  367. if rpt.AttrVal(model.ReportAttrTransferred) == model.AttrNo {
  368. rpt.State = state
  369. rpt.MTime = xtime.Time(now.Unix())
  370. tranOids = append(tranOids, rpt.Oid)
  371. tranRpIDs = append(tranRpIDs, rpt.RpID)
  372. tranRpt = append(tranRpt, rpt)
  373. }
  374. }
  375. rows, err := s.dao.UpReportsState(c, tranOids, tranRpIDs, state, now)
  376. if err != nil {
  377. log.Error("s.dao.UpReportState(%v,%v,%d) rows:%d error(%v)", oids, rpIDs, state, rows, err)
  378. return
  379. } else if rows == 0 {
  380. return
  381. }
  382. for _, rpt := range tranRpt {
  383. report.Manager(&report.ManagerInfo{
  384. UID: adminID,
  385. Uname: adName,
  386. Business: 41,
  387. Type: int(typ),
  388. Oid: rpt.Oid,
  389. Ctime: now,
  390. Action: action,
  391. Index: []interface{}{
  392. rpt.RpID,
  393. rpt.State,
  394. state,
  395. },
  396. Content: map[string]interface{}{
  397. "remark": remark,
  398. },
  399. })
  400. }
  401. if _, err = s.dao.UpReportsAttrBit(c, tranOids, tranRpIDs, model.ReportAttrTransferred, model.AttrYes, now); err != nil {
  402. log.Error("s.dao.UpReportAttrBit(%v,%v) transfered errror(%v)", tranOids, tranRpIDs, err)
  403. return
  404. }
  405. s.addAdminIDLogs(c, oids, rpIDs, adminID, typ, model.AdminIsNew, model.AdminIsReport, op, result, remark, now)
  406. s.cache.Do(c, func(ctx context.Context) {
  407. s.pubSearchReport(ctx, rpts, nil)
  408. })
  409. return
  410. }
  411. // ReportStateSet transfer a report.
  412. func (s *Service) ReportStateSet(c context.Context, oids, rpIDs []int64, adminID int64, adname string, typ, state int32, remark string, delReport bool) (err error) {
  413. if state != model.ReportStateTransferred {
  414. return
  415. }
  416. var (
  417. op int32
  418. result string
  419. action string
  420. )
  421. op = model.AdminOperRptTransferArbitration
  422. action = model.ReportActionReportArbitration
  423. if adminID == 0 {
  424. result = "系统自动移交至风纪委"
  425. } else {
  426. result = "管理员移交至风纪委"
  427. }
  428. rpts, err := s.reports(c, oids, rpIDs)
  429. if err != nil {
  430. return
  431. }
  432. rps, err := s.replies(c, oids, rpIDs)
  433. if err != nil {
  434. log.Error("s.replies (%v,%v) error(%v)", oids, rpIDs, err)
  435. return
  436. }
  437. links := make(map[int64]string, 0)
  438. titles := make(map[int64]string, 0)
  439. for _, rp := range rps {
  440. title, link, _ := s.TitleLink(c, rp.Oid, rp.Type)
  441. links[rp.ID] = link
  442. titles[rp.ID] = title
  443. }
  444. err = s.dao.TransferArbitration(c, rps, rpts, adminID, adname, titles, links)
  445. if err != nil {
  446. log.Error("s.dao.TransferArbitration (%v,%v) error(%v)", rps, rpts, err)
  447. return
  448. }
  449. mtime := time.Now()
  450. for _, rpt := range rpts {
  451. report.Manager(&report.ManagerInfo{
  452. UID: adminID,
  453. Uname: adname,
  454. Business: 41,
  455. Type: int(typ),
  456. Oid: rpt.Oid,
  457. Ctime: mtime,
  458. Action: action,
  459. Index: []interface{}{
  460. rpt.RpID,
  461. rpt.State,
  462. state,
  463. },
  464. Content: map[string]interface{}{
  465. "remark": remark,
  466. },
  467. })
  468. rpt.State = state
  469. rpt.MTime = xtime.Time(mtime.Unix())
  470. if delReport {
  471. s.cache.Do(c, func(ctx context.Context) {
  472. s.dao.DelReport(ctx, rpt.Oid, rpt.RpID)
  473. })
  474. }
  475. }
  476. rows, err := s.dao.UpReportsState(c, oids, rpIDs, state, mtime)
  477. if err != nil {
  478. log.Error("s.dao.UpReportState(%v,%v,%d) rows:%d error(%v)", oids, rpIDs, state, rows, err)
  479. return
  480. } else if rows == 0 {
  481. return
  482. }
  483. s.addAdminIDLogs(c, oids, rpIDs, adminID, typ, model.AdminIsNew, model.AdminIsReport, op, result, remark, mtime)
  484. s.cache.Do(c, func(ctx context.Context) {
  485. s.pubSearchReport(ctx, rpts, nil)
  486. })
  487. return
  488. }