challenge.go 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "strconv"
  7. "time"
  8. "go-common/app/admin/main/workflow/model"
  9. "go-common/app/admin/main/workflow/model/param"
  10. "go-common/app/admin/main/workflow/model/search"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. "github.com/pkg/errors"
  14. )
  15. // SetChallResult will set a challenge result
  16. func (s *Service) SetChallResult(c context.Context, crp *param.ChallResParam) (err error) {
  17. var (
  18. chall *model.Chall
  19. g *model.Group
  20. rows int64
  21. )
  22. // Check challenge and group is exist
  23. if chall, err = s.dao.Chall(c, crp.Cid); err != nil {
  24. log.Error("s.dao.Chall() error(%v)", err)
  25. return
  26. }
  27. if chall == nil {
  28. log.Error("Challenge(%d) not exist", crp.Cid)
  29. err = ecode.NothingFound
  30. return
  31. }
  32. chall.SetState(uint32(crp.State), 0)
  33. chall.AdminID = crp.AdminID
  34. tx := s.dao.ORM.Begin()
  35. if err = tx.Error; err != nil {
  36. log.Error("s.dao.ORM.Begin() error(%v)", err)
  37. return
  38. }
  39. defer func() {
  40. if r := recover(); r != nil {
  41. tx.Rollback()
  42. log.Error("wocao jingran recover le error(%v)", r)
  43. }
  44. }()
  45. if rows, err = s.dao.TxUpChall(tx, chall); err != nil {
  46. tx.Rollback()
  47. log.Error("s.dao.TxUpChall(%v) err(%v)", chall, err)
  48. return
  49. }
  50. if g, err = s.dao.GroupByID(c, chall.Gid); err != nil {
  51. tx.Rollback()
  52. log.Error("s.dao.GroupByID() error(%v)", err)
  53. return
  54. }
  55. if g == nil {
  56. tx.Rollback()
  57. log.Error("Group(%d) not exist", chall.Gid)
  58. err = ecode.NothingFound
  59. return
  60. }
  61. // decrease group pending stat count
  62. g.Handling -= int32(rows)
  63. if g.Handling < 0 {
  64. g.Handling = 0
  65. }
  66. if err = s.dao.TxUpGroupHandling(tx, g.ID, g.Handling); err != nil {
  67. tx.Rollback()
  68. log.Error("Failed to update group stat count(%d) all(%d) by gid %d, error(%v)",
  69. g.Count, g.Handling, g.ID, err)
  70. return
  71. }
  72. if err = tx.Commit().Error; err != nil {
  73. tx.Rollback()
  74. log.Error("tx.Commit() error(%v)", err)
  75. return
  76. }
  77. s.task(func() {
  78. s.afterSetChallResult(crp, chall)
  79. })
  80. return
  81. }
  82. // BatchSetChallResult will set a set of challenges result
  83. func (s *Service) BatchSetChallResult(c context.Context, bcrp *param.BatchChallResParam) (err error) {
  84. var (
  85. cids []int64 // all requested cids
  86. pcids []int64 // pending cids
  87. gids []int64
  88. challs map[int64]*model.Chall
  89. groups map[int64]*model.Group
  90. gidToDecr map[int64]int32
  91. )
  92. // collect cids
  93. cids = append(cids, bcrp.Cids...)
  94. if challs, err = s.dao.StateChalls(c, cids, model.Pending); err != nil {
  95. log.Error("s.dao.StateChalls() error(%v)", err)
  96. return
  97. }
  98. // collect gids
  99. gidToDecr = make(map[int64]int32, len(challs))
  100. for _, c := range challs {
  101. pcids = append(pcids, int64(c.Cid))
  102. gids = append(gids, int64(c.Gid))
  103. if _, ok := gidToDecr[c.Gid]; !ok {
  104. gidToDecr[c.Gid] = 0
  105. }
  106. gidToDecr[c.Gid]++
  107. }
  108. if groups, err = s.dao.Groups(c, gids); err != nil {
  109. log.Error("s.dao.Groups() error(%v)", err)
  110. return
  111. }
  112. tx := s.dao.ORM.Begin()
  113. if err = tx.Error; err != nil {
  114. log.Error("s.dao.ORM.Begin() error(%v)", err)
  115. return
  116. }
  117. defer func() {
  118. if r := recover(); r != nil {
  119. tx.Rollback()
  120. log.Error("wocao jingran recover le error(%v)", r)
  121. }
  122. }()
  123. if err = s.dao.TxBatchUpChallByIDs(tx, pcids, bcrp.State); err != nil {
  124. tx.Rollback()
  125. log.Error("s.dao.TxBatchUpChallByIDs(%+v) error(%v)", bcrp, err)
  126. return
  127. }
  128. // decrease pending stat count by gidToDesc
  129. for gid, decr := range gidToDecr {
  130. g, ok := groups[gid]
  131. if !ok {
  132. log.Error("Failed to retrive group by gid %d", gid)
  133. continue
  134. }
  135. // decr group handling counts
  136. g.Handling -= decr
  137. if g.Handling < 0 {
  138. g.Handling = 0
  139. }
  140. if err = s.dao.TxUpGroupHandling(tx, gid, g.Handling); err != nil {
  141. tx.Rollback()
  142. log.Error("Failed to update group stat count(%d) all(%d) by gid %d, error(%v)",
  143. g.Count, g.Handling, g.ID, err)
  144. return
  145. }
  146. }
  147. if err = tx.Commit().Error; err != nil {
  148. tx.Rollback()
  149. log.Error("tx.Commit() error(%v)", err)
  150. return
  151. }
  152. //double write state to dispatch_state field
  153. changedChalls, err := s.dao.Challs(c, pcids)
  154. for cid := range changedChalls {
  155. changedChalls[cid].SetState(uint32(bcrp.State), 0)
  156. if err = s.dao.BatchUpChallByIDs([]int64{int64(cid)}, changedChalls[cid].DispatchState, bcrp.AdminID); err != nil {
  157. log.Error("s.dao.BatchUpChallByIDs(%v,%d,%d) error(%v)", cid, changedChalls[cid].DispatchState, bcrp.AdminID, err)
  158. return
  159. }
  160. }
  161. s.task(func() {
  162. s.afterBatchSetChallResult(bcrp, challs)
  163. })
  164. return
  165. }
  166. // UpChallExtraV2 will update extra data of a challenge by cid
  167. func (s *Service) UpChallExtraV2(c context.Context, cep *param.ChallExtraParam) (err error) {
  168. var (
  169. obj *model.Business
  170. chall *model.Chall
  171. )
  172. if chall, err = s.dao.Chall(c, cep.Cid); err != nil {
  173. log.Error("s.dao.Chall(%d) error(%v)", cep.Cid, err)
  174. return
  175. }
  176. if obj, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
  177. log.Error("s.dao.LastBusRec(%d, %d) error(%v)", chall.Business, chall.Oid, err)
  178. return
  179. }
  180. if obj == nil {
  181. err = ecode.NothingFound
  182. return
  183. }
  184. parsed := make(map[string]interface{})
  185. if obj.Extra != "" {
  186. if err1 := json.Unmarshal([]byte(obj.Extra), &parsed); err1 != nil {
  187. log.Error("json.Unmarshal(%s) error(%v)", obj.Extra, err1)
  188. }
  189. }
  190. tx := s.dao.ORM.Begin()
  191. if err = tx.Error; err != nil {
  192. log.Error("s.dao.ORM.Begin() error(%v)", err)
  193. return
  194. }
  195. defer func() {
  196. if r := recover(); r != nil {
  197. tx.Rollback()
  198. log.Error("s.UpChallExtra() panic(%v)", r)
  199. }
  200. }()
  201. for k, v := range cep.Extra {
  202. parsed[k] = v
  203. }
  204. if _, err = s.dao.TxUpChallExtraV2(tx, chall.Business, chall.Oid, cep.AdminID, parsed); err != nil {
  205. tx.Rollback()
  206. log.Error("s.dao.UpChallExtra(%d, %d, %v) error(%v)", cep.Cid, cep.AdminID, parsed, err)
  207. return
  208. }
  209. if err = tx.Commit().Error; err != nil {
  210. tx.Rollback()
  211. log.Error("tx.Commit() error(%v)", err)
  212. return
  213. }
  214. return
  215. }
  216. // BatchUpChallExtraV2 update business object extra field by business oid
  217. func (s *Service) BatchUpChallExtraV2(c context.Context, bcep *param.BatchChallExtraParam) (err error) {
  218. var (
  219. challs map[int64]*model.Chall
  220. bs *model.Business
  221. )
  222. if challs, err = s.dao.Challs(c, bcep.Cids); err != nil {
  223. log.Error("s.dao.Challs(%v) error(%v)", bcep.Cids, err)
  224. return
  225. }
  226. parsed := make(map[int64]map[string]interface{}, len(challs))
  227. for cid, chall := range challs {
  228. if bs, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
  229. log.Error("s.dao.LastBusRec(%d, %d) error(%v)", chall.Business, chall.Oid, err)
  230. return
  231. }
  232. inner := make(map[string]interface{})
  233. if bs.Extra != "" {
  234. if err1 := json.Unmarshal([]byte(bs.Extra), &inner); err1 != nil {
  235. log.Error("json.Unmarshal(%s) error(%v)", bs.Extra, err1)
  236. }
  237. }
  238. parsed[cid] = inner
  239. }
  240. tx := s.dao.ORM.Begin()
  241. if err = tx.Error; err != nil {
  242. log.Error("s.dao.ORM.Begin() error(%v)", err)
  243. return
  244. }
  245. for _, ex := range parsed {
  246. for k, v := range bcep.Extra {
  247. ex[k] = v
  248. }
  249. }
  250. for cid, ex := range parsed {
  251. chall := challs[cid]
  252. if _, err = s.dao.TxUpChallExtraV2(tx, chall.Business, chall.Oid, bcep.AdminID, ex); err != nil {
  253. tx.Rollback()
  254. log.Error("s.dao.TxUpChallExtra(%d, %d, %v) error(%v)", cid, bcep.AdminID, ex, err)
  255. return
  256. }
  257. }
  258. if err = tx.Commit().Error; err != nil {
  259. tx.Rollback()
  260. log.Error("tx.Commit() error(%v)", err)
  261. return
  262. }
  263. return
  264. }
  265. // UpChallExtraV3 .
  266. func (s *Service) UpChallExtraV3(c context.Context, cep3 *param.ChallExtraParamV3) (err error) {
  267. //todo
  268. return
  269. }
  270. // ChallList will list challenges by several conditions
  271. // Deprecated
  272. func (s *Service) ChallList(c context.Context, cond *search.ChallSearchCommonCond) (challPage *search.ChallListPageCommon, err error) {
  273. var (
  274. resp *search.ChallSearchCommonResp
  275. cids []int64
  276. challs map[int64]*model.Chall
  277. challLastLog map[int64]string
  278. attPaths map[int64][]string
  279. t *model.TagMeta
  280. )
  281. if resp, err = s.dao.SearchChallenge(c, cond); err != nil {
  282. log.Error("s.dao.SearchChall() error(%v)", err)
  283. return
  284. }
  285. cids = make([]int64, 0, len(resp.Result))
  286. for _, r := range resp.Result {
  287. cids = append(cids, r.ID)
  288. }
  289. if challs, err = s.dao.Challs(c, cids); err != nil {
  290. log.Error("s.dao.Challs() error(%v)", err)
  291. return
  292. }
  293. // read state from new state field
  294. for cid := range challs {
  295. challs[cid].FromState()
  296. }
  297. if challLastLog, err = s.LastLog(c, cids, []int{model.WLogModuleChallenge}); err != nil {
  298. log.Error("s.dao.BatchLastLog() error(%v)", err)
  299. err = nil
  300. }
  301. if attPaths, err = s.dao.AttPathsByCids(c, cids); err != nil {
  302. log.Error("s.dao.AttPathsByCids() error(%v)", err)
  303. return
  304. }
  305. challPage = &search.ChallListPageCommon{}
  306. challList := make([]*model.Chall, 0, len(resp.Result))
  307. for _, r := range resp.Result {
  308. cid := r.ID
  309. c, ok := challs[cid]
  310. if !ok {
  311. log.Warn("Invalid challenge id %d", r.ID)
  312. continue
  313. }
  314. // fill tag
  315. if t, err = s.tag(c.Business, c.Tid); err != nil {
  316. log.Error("Failed to retrive tag by bid(%d) tag_id(%d)", c.Business, c.Tid)
  317. err = nil
  318. } else {
  319. c.Tag = t.Name
  320. c.Round = t.RID
  321. }
  322. // fill last log
  323. if l, ok := challLastLog[cid]; ok {
  324. c.LastLog = l
  325. }
  326. // fill attachments
  327. c.Attachments = make([]string, 0)
  328. if ps, ok := attPaths[cid]; ok {
  329. c.Attachments = ps
  330. c.FixAttachments()
  331. }
  332. c.FormatState()
  333. challList = append(challList, c)
  334. }
  335. challPage.Items = challList
  336. challPage.Page = &model.Page{
  337. Num: resp.Page.Num,
  338. Size: resp.Page.Size,
  339. Total: resp.Page.Total,
  340. }
  341. return
  342. }
  343. // ChallListCommon will list challenges by several conditions
  344. func (s *Service) ChallListCommon(c context.Context, cond *search.ChallSearchCommonCond) (challPage *search.ChallListPageCommon, err error) {
  345. var (
  346. challSearchResp *search.ChallSearchCommonResp
  347. business int8
  348. cids []int64
  349. uids []int64
  350. oids []int64
  351. uNames map[int64]string
  352. mids []int64
  353. challs map[int64]*model.Chall
  354. challLastLog map[int64]string
  355. challLastEvent map[int64]*model.Event
  356. attPaths map[int64][]string
  357. archives map[int64]*model.Archive
  358. authors map[int64]*model.Account
  359. lastAuditLogSchRes *search.AuditLogSearchResult // 最近的稿件操作日志
  360. lastAuditLogExtraMap map[int64]*search.ArchiveAuditLogExtra // 稿件操作日志 extra 信息
  361. chall *model.Chall
  362. ps []string //attachments
  363. ok bool
  364. l string
  365. )
  366. business = cond.Business
  367. if challSearchResp, err = s.dao.SearchChallenge(c, cond); err != nil {
  368. log.Error("s.dao.SearchChallenge() error(%v)", err)
  369. return
  370. }
  371. // no result in es
  372. if challSearchResp.Page.Total == 0 {
  373. challPage = &search.ChallListPageCommon{}
  374. challPage.Items = make([]*model.Chall, 0)
  375. challPage.Page = &model.Page{
  376. Num: challSearchResp.Page.Num,
  377. Size: challSearchResp.Page.Size,
  378. Total: challSearchResp.Page.Total,
  379. }
  380. return
  381. }
  382. cids = make([]int64, 0, len(challSearchResp.Result))
  383. oids = make([]int64, 0, len(challSearchResp.Result))
  384. for _, r := range challSearchResp.Result {
  385. cids = append(cids, r.ID)
  386. }
  387. if challs, err = s.dao.Challs(c, cids); err != nil {
  388. log.Error("s.dao.Challs(%v) error(%v)", cids, err)
  389. return
  390. }
  391. // read state from new state field
  392. for cid, c := range challs {
  393. challs[cid].FromState()
  394. uids = append(uids, int64(c.AdminID))
  395. uids = append(uids, int64(c.AssigneeAdminID))
  396. oids = append(oids, c.Oid)
  397. mids = append(mids, c.Mid)
  398. }
  399. if challLastLog, err = s.LastLog(c, cids, []int{model.WLogModuleChallenge}); err != nil {
  400. log.Error("s.batchLastLog(%v,%v) error(%v)", cids, model.WLogModuleChallenge, err)
  401. err = nil
  402. }
  403. // admin unames
  404. if uNames, err = s.dao.BatchUNameByUID(c, uids); err != nil {
  405. log.Error("s.dao.SearchUNameByUid(%v) error(%v)", uids, err)
  406. err = nil
  407. }
  408. if attPaths, err = s.dao.AttPathsByCids(c, cids); err != nil {
  409. log.Error("s.dao.AttPathsByCids() error(%v)", err)
  410. return
  411. }
  412. if challLastEvent, err = s.batchLastEvent(c, cids); err != nil {
  413. log.Error("s.batchLastEvent(%v) error(%v)", cids, err)
  414. return
  415. }
  416. switch business {
  417. case model.ArchiveAppeal:
  418. if archives, err = s.dao.ArchiveRPC(c, oids); err != nil {
  419. log.Error("s.dao.ArchiveInfos(%v) error(%v)", oids, err)
  420. err = nil
  421. } else {
  422. cond := &search.AuditLogGroupSearchCond{
  423. Businesses: []int64{3},
  424. Order: "ctime",
  425. PS: 100,
  426. PN: 1,
  427. Sort: "desc",
  428. Oids: oids,
  429. Group: []string{"oid"},
  430. }
  431. if lastAuditLogSchRes, err = s.dao.SearchAuditLogGroup(c, cond); err != nil {
  432. log.Error("s.dao.SearchAuditLogGroup(%+v) error(%v)", cond, err)
  433. err = nil
  434. }
  435. lastAuditLogExtraMap = make(map[int64]*search.ArchiveAuditLogExtra)
  436. for _, l := range lastAuditLogSchRes.Data.Result {
  437. extra := new(search.ArchiveAuditLogExtra)
  438. if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
  439. log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
  440. continue
  441. }
  442. lastAuditLogExtraMap[l.Oid] = extra
  443. }
  444. }
  445. case model.CreditAppeal:
  446. authors = s.dao.AccountInfoRPC(c, mids)
  447. case model.ArchiveAudit:
  448. if archives, err = s.dao.ArchiveRPC(c, oids); err != nil {
  449. log.Error("s.dao.ArchiveInfos(%v) error(%v)", oids, err)
  450. err = nil
  451. } else {
  452. cond := &search.AuditLogGroupSearchCond{
  453. Businesses: []int64{3},
  454. Order: "ctime",
  455. PS: 100,
  456. PN: 1,
  457. Sort: "desc",
  458. Oids: oids,
  459. Group: []string{"oid"},
  460. }
  461. if lastAuditLogSchRes, err = s.dao.SearchAuditLogGroup(c, cond); err != nil {
  462. log.Error("s.dao.SearchAuditLogGroup(%+v) error(%v)", cond, err)
  463. err = nil
  464. }
  465. lastAuditLogExtraMap = make(map[int64]*search.ArchiveAuditLogExtra)
  466. for _, l := range lastAuditLogSchRes.Data.Result {
  467. extra := new(search.ArchiveAuditLogExtra)
  468. if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
  469. log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
  470. continue
  471. }
  472. lastAuditLogExtraMap[l.Oid] = extra
  473. }
  474. }
  475. }
  476. challPage = &search.ChallListPageCommon{}
  477. challList := make([]*model.Chall, 0, len(challSearchResp.Result))
  478. for _, r := range challSearchResp.Result {
  479. cid := r.ID
  480. chall, ok = challs[cid]
  481. if !ok {
  482. log.Warn("Invalid challenge id %d", r.ID)
  483. continue
  484. }
  485. // fill tag
  486. var t *model.TagMeta
  487. if t, err = s.tag(chall.Business, chall.Tid); err != nil {
  488. log.Error("s.tag(%d,%d) error(%v)", chall.Business, chall.Tid, err)
  489. err = nil
  490. } else {
  491. chall.Tag = t.Name
  492. chall.Round = t.RID
  493. }
  494. // fill last log
  495. if l, ok = challLastLog[cid]; ok {
  496. chall.LastLog = l
  497. }
  498. // fill last event
  499. chall.LastEvent = challLastEvent[cid]
  500. // fill attachments
  501. chall.Attachments = make([]string, 0)
  502. if ps, ok = attPaths[cid]; ok {
  503. chall.Attachments = ps
  504. chall.FixAttachments()
  505. }
  506. chall.FormatState()
  507. //fill business object
  508. if chall.BusinessObject, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
  509. log.Error("s.dao.LastBusRec(%d, %d) error(%v)", chall.Business, chall.Oid, err)
  510. err = nil
  511. }
  512. //todo: add challenge meta
  513. switch business {
  514. case model.ArchiveAppeal: // 稿件申诉
  515. var (
  516. archive *model.Archive
  517. extra *search.ArchiveAuditLogExtra
  518. )
  519. if archive, ok = archives[chall.Oid]; !ok {
  520. log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, r.ID)
  521. }
  522. if extra, ok = lastAuditLogExtraMap[chall.Oid]; !ok {
  523. log.Warn("not exist archive operate last audit log extra oid(%d) cid(%d)", chall.Oid, r.ID)
  524. }
  525. if extra != nil && archive != nil {
  526. archive.OPName = extra.Content.UName
  527. archive.OPContent = extra.Diff
  528. archive.OPRemark = extra.Content.Note
  529. }
  530. chall.Meta = archive
  531. case model.CreditAppeal: //小黑屋
  532. chall.Meta = chall.BusinessObject
  533. if _, ok = authors[chall.Mid]; ok {
  534. chall.MName = authors[chall.Mid].Name
  535. }
  536. case model.ArchiveAudit: //稿件审核
  537. var archive *model.Archive
  538. var extra *search.ArchiveAuditLogExtra
  539. if archive, ok = archives[chall.Oid]; !ok {
  540. log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, r.ID)
  541. }
  542. if extra, ok = lastAuditLogExtraMap[chall.Oid]; !ok {
  543. log.Warn("not exist archive operate last audit log extra oid(%d) cid(%d)", chall.Oid, r.ID)
  544. }
  545. if extra != nil && archive != nil {
  546. archive.OPName = extra.Content.UName
  547. archive.OPContent = extra.Diff
  548. archive.OPRemark = extra.Content.Note
  549. }
  550. chall.Meta = archive
  551. }
  552. chall.AssigneeAdminName = uNames[chall.AssigneeAdminID]
  553. chall.AdminName = uNames[chall.AdminID]
  554. challList = append(challList, chall)
  555. }
  556. challPage.Items = challList
  557. challPage.Page = &model.Page{
  558. Num: challSearchResp.Page.Num,
  559. Size: challSearchResp.Page.Size,
  560. Total: challSearchResp.Page.Total,
  561. }
  562. return
  563. }
  564. // ChallDetail will retrive challenge by cid
  565. func (s *Service) ChallDetail(c context.Context, cid int64) (chall *model.Chall, err error) {
  566. var (
  567. cl map[int64]string
  568. attPaths []string
  569. t *model.TagMeta
  570. bs *model.Business
  571. lastEvent *model.Event
  572. archives map[int64]*model.Archive
  573. authors map[int64]*model.Account
  574. ok bool
  575. l string
  576. )
  577. if chall, err = s.dao.Chall(c, cid); err != nil || chall == nil {
  578. log.Error("Failed to s.dao.Chall(%d) or chall not found: %v", cid, err)
  579. err = ecode.NothingFound
  580. return
  581. }
  582. // read state from new state field
  583. chall.FromState()
  584. if attPaths, err = s.dao.AttPathsByCid(c, cid); err != nil {
  585. log.Error("Failed to s.dao.AttPathsByCid(%d): %v", cid, err)
  586. err = nil
  587. }
  588. if cl, err = s.LastLog(c, []int64{cid}, []int{model.WLogModuleChallenge}); err != nil {
  589. log.Error("Failed to s.dao.LastLog(%d): %v", cid, err)
  590. err = nil
  591. }
  592. if lastEvent, err = s.dao.LastEventByCid(c, cid); err != nil {
  593. log.Error("Failed to s.dao.EventsByCid(%d): %v", cid, err)
  594. err = nil
  595. }
  596. if t, err = s.tag(chall.Business, chall.Tid); err != nil {
  597. log.Error("Failed to s.tag(%d,%d) error(%v)", chall.Business, chall.Tid, err)
  598. // fixme: to debug
  599. err = nil
  600. } else {
  601. chall.Tag = t.Name
  602. chall.Round = t.RID
  603. }
  604. if bs, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
  605. log.Error("Failed to s.dao.BusRecByCid(%d): %v", cid, err)
  606. err = nil
  607. }
  608. business := chall.Business
  609. switch business {
  610. case model.ArchiveAppeal:
  611. if archives, err = s.dao.ArchiveRPC(c, []int64{chall.Oid}); err != nil {
  612. log.Error("s.dao.ArchiveInfos(%v) error(%v)", chall.Oid, err)
  613. err = nil
  614. }
  615. }
  616. switch business {
  617. case model.ArchiveAppeal: // 稿件申诉
  618. if chall.Meta, ok = archives[chall.Oid]; !ok {
  619. log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, chall.Cid)
  620. }
  621. case model.CreditAppeal: //小黑屋
  622. chall.Meta = chall.BusinessObject
  623. if authors = s.dao.AccountInfoRPC(c, []int64{chall.Mid}); authors != nil {
  624. if _, ok = authors[chall.Mid]; ok {
  625. chall.MName = authors[chall.Mid].Name
  626. }
  627. }
  628. }
  629. if l, ok = cl[cid]; ok {
  630. chall.LastLog = l
  631. } else {
  632. log.Info("cid(%d) not found last log", cid)
  633. }
  634. chall.LastEvent = lastEvent
  635. chall.BusinessObject = bs
  636. chall.Attachments = attPaths
  637. chall.FixAttachments()
  638. return
  639. }
  640. // UpChallBusState will update business_state field of a challenge
  641. func (s *Service) UpChallBusState(c context.Context, cid int64, assigneeAdminid int64, assigneeAdminName string, busState int8) (err error) {
  642. // TODO(zhoujiahui): record in log?
  643. if cid <= 0 {
  644. err = ecode.WkfChallNotFound
  645. return
  646. }
  647. if err = s.dao.UpChallBusState(c, cid, busState, assigneeAdminid); err != nil {
  648. return
  649. }
  650. s.task(func() {
  651. var (
  652. result []*search.ChallSearchCommonData
  653. challs []*model.Chall
  654. )
  655. cond := &search.ChallSearchCommonCond{
  656. Fields: []string{"id", "oid", "business", "mid", "typeid"},
  657. IDs: []int64{cid},
  658. }
  659. if result, err = s.dao.SearchChallengeMultiPage(context.Background(), cond); err != nil {
  660. log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
  661. return
  662. }
  663. for _, r := range result {
  664. c := &model.Chall{
  665. Cid: r.ID,
  666. Oid: r.Oid,
  667. Business: r.Business,
  668. BusinessState: busState,
  669. AssigneeAdminID: assigneeAdminid,
  670. AssigneeAdminName: assigneeAdminName,
  671. Mid: r.Mid,
  672. TypeID: r.TypeID,
  673. }
  674. challs = append(challs, c)
  675. }
  676. s.afterSetBusinessState(challs)
  677. })
  678. return
  679. }
  680. // BatchUpChallBusState will update business_state field of a set of challenges
  681. func (s *Service) BatchUpChallBusState(c context.Context, cids []int64, assigneeAdminid int64, assigneeAdminName string, busState int8) (err error) {
  682. // TODO(zhoujiahui): record in log?
  683. if len(cids) <= 0 {
  684. return
  685. }
  686. if err = s.dao.BatchUpChallBusState(c, cids, busState, assigneeAdminid); err != nil {
  687. return
  688. }
  689. s.task(func() {
  690. var (
  691. result []*search.ChallSearchCommonData
  692. challs []*model.Chall
  693. )
  694. cond := &search.ChallSearchCommonCond{
  695. Fields: []string{"id", "oid", "business", "mid", "typeid"},
  696. IDs: cids,
  697. }
  698. if result, err = s.dao.SearchChallengeMultiPage(context.Background(), cond); err != nil {
  699. log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
  700. return
  701. }
  702. for _, r := range result {
  703. c := &model.Chall{
  704. Cid: r.ID,
  705. Oid: r.Oid,
  706. Business: r.Business,
  707. BusinessState: busState,
  708. AssigneeAdminID: assigneeAdminid,
  709. AssigneeAdminName: assigneeAdminName,
  710. Mid: r.Mid,
  711. TypeID: r.TypeID,
  712. }
  713. challs = append(challs, c)
  714. }
  715. s.afterSetBusinessState(challs)
  716. })
  717. return
  718. }
  719. // SetChallBusState will update business_state field of a set of challenges
  720. func (s *Service) SetChallBusState(c context.Context, bcbsp *param.BatchChallBusStateParam) (err error) {
  721. // TODO(zhoujiahui): record in log?
  722. if len(bcbsp.Cids) <= 0 {
  723. return
  724. }
  725. if err = s.dao.BatchUpChallBusState(c, bcbsp.Cids, bcbsp.BusState, bcbsp.AssigneeAdminID); err != nil {
  726. return
  727. }
  728. s.task(func() {
  729. var (
  730. result []*search.ChallSearchCommonData
  731. challs []*model.Chall
  732. )
  733. cond := &search.ChallSearchCommonCond{
  734. Fields: []string{"id", "oid", "business", "mid", "typeid"},
  735. IDs: bcbsp.Cids,
  736. }
  737. if result, err = s.dao.SearchChallengeMultiPage(context.Background(), cond); err != nil {
  738. log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
  739. return
  740. }
  741. for _, r := range result {
  742. c := &model.Chall{
  743. Cid: r.ID,
  744. Oid: r.Oid,
  745. Business: r.Business,
  746. BusinessState: bcbsp.BusState,
  747. AssigneeAdminID: bcbsp.AssigneeAdminID,
  748. AssigneeAdminName: bcbsp.AssigneeAdminName,
  749. Mid: r.Mid,
  750. TypeID: r.TypeID,
  751. }
  752. challs = append(challs, c)
  753. }
  754. s.afterSetBusinessState(challs)
  755. })
  756. return
  757. }
  758. // UpBusChallsBusState will update business_state field of a set of challenges with same business and oid
  759. func (s *Service) UpBusChallsBusState(c context.Context, business, busState int8, preBusStates []int8, oid int64, assigneeAdminid int64, extra map[string]interface{}) (cids []int64, err error) {
  760. // TODO(zhoujiahui): record in log?
  761. tx := s.dao.ORM.Begin()
  762. if err = tx.Error; err != nil {
  763. log.Error("s.dao.ORM.Begin() error(%v)", err)
  764. return
  765. }
  766. defer func() {
  767. if r := recover(); r != nil {
  768. tx.Rollback()
  769. log.Error("wocao jingran recover le error(%v)", r)
  770. }
  771. }()
  772. if cids, err = s.dao.TxChallsByBusStates(tx, business, oid, preBusStates); err != nil {
  773. tx.Rollback()
  774. log.Error("s.dao.TxChallsByBusStates(%d, %d, %s) error(%v)", business, oid, preBusStates, err)
  775. return
  776. }
  777. if err = s.dao.TxUpChallsBusStateByIDs(tx, cids, busState, assigneeAdminid); err != nil {
  778. tx.Rollback()
  779. log.Error("s.dao.TxUpChallsBusStateByIDs(%s, %d) error(%v)", cids, busState, err)
  780. return
  781. }
  782. if err = tx.Commit().Error; err != nil {
  783. tx.Rollback()
  784. log.Error("tx.Commit() error(%v)", err)
  785. return
  786. }
  787. bcep := &param.BatchChallExtraParam{
  788. Cids: cids,
  789. AdminID: assigneeAdminid,
  790. Extra: extra,
  791. }
  792. if err = s.BatchUpChallExtraV2(c, bcep); err != nil {
  793. log.Error("s.BatchUpChallExtra(%v) error(%v)", bcep, err)
  794. return
  795. }
  796. // double write to new field
  797. challs, err := s.dao.Challs(c, cids)
  798. if err != nil {
  799. return
  800. }
  801. for cid := range challs {
  802. challs[cid].SetState(uint32(busState), uint8(1))
  803. if err = s.dao.ORM.Table("workflow_chall").Where("id=?", cid).Update("dispatch_state", challs[cid].DispatchState).Error; err != nil {
  804. err = errors.Wrapf(err, "cid(%d), dispatch_state(%d)", cid, challs[cid].DispatchState)
  805. return
  806. }
  807. }
  808. return
  809. }
  810. // RstChallResult will reset challenge and its linked group state as Pending
  811. func (s *Service) RstChallResult(c context.Context, crp *param.ChallRstParam) (err error) {
  812. var (
  813. chall *model.Chall
  814. group *model.Group
  815. )
  816. if chall, err = s.dao.Chall(c, crp.Cid); err != nil || chall == nil {
  817. log.Error("Failed to query challenge(%d) or it not exist: %v", crp.Cid, err)
  818. return
  819. }
  820. if group, err = s.dao.GroupByID(c, chall.Gid); err != nil || group == nil {
  821. log.Error("Failed to query group(%d) or it not exist: %v", chall.Gid, err)
  822. return
  823. }
  824. // update new field
  825. chall.SetState(uint32(crp.State), 0)
  826. tx := s.dao.ORM.Begin()
  827. if err = tx.Error; err != nil {
  828. log.Error("s.dao.ORM.Begin() error(%v)", err)
  829. return
  830. }
  831. defer func() {
  832. if r := recover(); r != nil {
  833. tx.Rollback()
  834. log.Error("s.RstChallResult() panic(%v)", r)
  835. }
  836. }()
  837. if err = tx.Model(chall).UpdateColumn(map[string]interface{}{
  838. "state": crp.State,
  839. "dispatch_state": chall.DispatchState,
  840. }).Error; err != nil {
  841. tx.Rollback()
  842. log.Error("Failed to set chall(%v) as pending: %v", chall, err)
  843. return
  844. }
  845. if err = tx.Model(group).UpdateColumn(map[string]interface{}{
  846. "state": crp.State,
  847. }).Error; err != nil {
  848. tx.Rollback()
  849. log.Error("Failed to set group(%v) as pending: %v", group, err)
  850. return
  851. }
  852. if err = tx.Commit().Error; err != nil {
  853. tx.Rollback()
  854. log.Error("Failed to tx.Commit() in RstChallResult: %v", err)
  855. return
  856. }
  857. s.task(func() {
  858. cl := &model.WLog{
  859. AdminID: crp.AdminID,
  860. Admin: crp.AdminName,
  861. Oid: chall.Oid,
  862. Business: chall.Business,
  863. Target: chall.Cid,
  864. Module: model.WLogModuleChallenge,
  865. Remark: fmt.Sprintf(`“工单详情编号 %d”设置为 %s 移交复审`, chall.Cid, s.StateDescr(chall.Business, 0, crp.State)),
  866. Note: crp.Reason,
  867. }
  868. gl := &model.WLog{
  869. AdminID: crp.AdminID,
  870. Admin: crp.AdminName,
  871. Oid: group.Oid,
  872. Business: group.Business,
  873. Target: group.ID,
  874. Module: model.WLogModuleGroup,
  875. Remark: fmt.Sprintf(`“工单编号 %d”设置为 %s 移交复审`, group.ID, s.StateDescr(chall.Business, 0, crp.State)),
  876. Note: crp.Reason,
  877. }
  878. s.writeAuditLog(cl)
  879. s.writeAuditLog(gl)
  880. })
  881. return
  882. }
  883. // BusinessList will retrive business object by cids
  884. // Deprecated
  885. func (s *Service) BusinessList(c context.Context, cids []int64) (cidToBus map[int64]*model.Business, err error) {
  886. if cidToBus, err = s.dao.BatchBusRecByCids(c, cids); err != nil {
  887. log.Error("s.dao.BatchBusRecByCids(%v) error(%v)", cids, err)
  888. return
  889. }
  890. return
  891. }
  892. // UpChall will update challenge tid
  893. func (s *Service) UpChall(c context.Context, cup *param.ChallUpParam) (err error) {
  894. var (
  895. chall *model.Chall
  896. t *model.TagMeta
  897. )
  898. // Check group and tag is exist
  899. if chall, err = s.dao.Chall(c, cup.Cid); err != nil {
  900. log.Error("s.dao.Chall(%d) error(%v)", cup.Cid, err)
  901. return
  902. }
  903. if chall == nil {
  904. log.Error("Challenge(%d) not exist", cup.Cid)
  905. err = ecode.WkfChallNotFound
  906. return
  907. }
  908. if t, err = s.tag(chall.Business, cup.Tid); err != nil {
  909. log.Error("bid(%d) tag_id(%d) not found in cache", chall.Business, cup.Tid)
  910. return
  911. }
  912. tx := s.dao.ORM.Begin()
  913. if err = tx.Error; err != nil {
  914. log.Error("s.dao.ORM.Begin() error(%v)", err)
  915. return
  916. }
  917. defer func() {
  918. if r := recover(); r != nil {
  919. tx.Rollback()
  920. log.Error("wocao jingran recover le error(%v)", r)
  921. }
  922. }()
  923. if err = s.dao.TxUpChallTag(tx, cup.Cid, cup.Tid); err != nil {
  924. tx.Rollback()
  925. log.Error("s.TxUpChallTag(%d, %d) error(%v)", cup.Cid, cup.Tid, err)
  926. return
  927. }
  928. if err = tx.Commit().Error; err != nil {
  929. tx.Rollback()
  930. log.Error("tx.Commit() error(%v)", err)
  931. return
  932. }
  933. s.task(func() {
  934. l := &model.WLog{
  935. Oid: chall.Oid,
  936. Business: chall.Business,
  937. Target: chall.Cid,
  938. Module: model.WLogModuleChallenge,
  939. AdminID: cup.AdminID,
  940. Admin: cup.AdminName,
  941. Remark: fmt.Sprintf(`工单编号 %d “管理 Tag”更新为“%s”`, cup.Cid, t.Name),
  942. }
  943. s.writeAuditLog(l)
  944. })
  945. return
  946. }
  947. // ChallListV3 .
  948. func (s *Service) ChallListV3(c context.Context, cond *search.ChallSearchCommonCond) (challPage *search.ChallListPageCommon, err error) {
  949. var (
  950. challSearchResp *search.ChallSearchCommonResp
  951. uNames map[int64]string
  952. challs map[int64]*model.Chall
  953. challLastLog map[int64]string
  954. challLastEvent map[int64]*model.Event
  955. attPaths map[int64][]string
  956. gidToBus map[int64]*model.Business
  957. users map[int64]*model.Account
  958. b *model.Business
  959. chall *model.Chall
  960. ps []string //attachments
  961. ok bool
  962. meta interface{}
  963. )
  964. if challSearchResp, err = s.dao.SearchChallenge(c, cond); err != nil {
  965. log.Error("s.dao.SearchChallenge() error(%v)", err)
  966. err = ecode.WkfSearchChallFailed
  967. return
  968. }
  969. // no result in es
  970. if challSearchResp.Page.Total == 0 {
  971. challPage = &search.ChallListPageCommon{}
  972. challPage.Items = make([]*model.Chall, 0)
  973. challPage.Page = &model.Page{
  974. Num: challSearchResp.Page.Num,
  975. Size: challSearchResp.Page.Size,
  976. Total: challSearchResp.Page.Total,
  977. }
  978. return
  979. }
  980. cids := make([]int64, 0, len(challSearchResp.Result))
  981. oids := make([]int64, 0, len(challSearchResp.Result))
  982. mids := make([]int64, 0, len(challSearchResp.Result))
  983. gids := make([]int64, 0, len(challSearchResp.Result))
  984. uids := make([]int64, 0, len(challSearchResp.Result)*2)
  985. for _, r := range challSearchResp.Result {
  986. cids = append(cids, r.ID)
  987. oids = append(oids, r.Oid)
  988. mids = append(mids, r.Mid)
  989. gids = append(gids, r.Gid)
  990. }
  991. if challs, err = s.dao.Challs(c, cids); err != nil {
  992. log.Error("s.dao.Challs(%v) error(%v)", cids, err)
  993. return
  994. }
  995. // read state from new state field
  996. for cid, c := range challs {
  997. challs[cid].FromState()
  998. uids = append(uids, int64(c.AdminID))
  999. uids = append(uids, int64(c.AssigneeAdminID))
  1000. }
  1001. if challLastLog, err = s.LastLog(c, cids, []int{model.WLogModuleChallenge}); err != nil {
  1002. log.Error("s.LastLog(%v,%v) error(%v)", cids, model.WLogModuleChallenge, err)
  1003. err = nil
  1004. }
  1005. // admin unames
  1006. if uNames, err = s.dao.BatchUNameByUID(c, uids); err != nil {
  1007. log.Error("s.dao.SearchUNameByUid(%v) error(%v)", uids, err)
  1008. err = nil
  1009. }
  1010. if attPaths, err = s.dao.AttPathsByCids(c, cids); err != nil {
  1011. log.Error("s.dao.AttPathsByCids() error(%v)", err)
  1012. return
  1013. }
  1014. if gidToBus, err = s.dao.BusObjectByGids(c, gids); err != nil {
  1015. log.Error("s.dao.BusObjectByGids(%v) error(%v)", gids, err)
  1016. return
  1017. }
  1018. if challLastEvent, err = s.batchLastEvent(c, cids); err != nil {
  1019. log.Error("s.batchLastEvent(%v) error(%v)", cids, err)
  1020. return
  1021. }
  1022. // user account
  1023. users = s.dao.AccountInfoRPC(c, mids)
  1024. // load meta
  1025. meta = s.searchChallMeta(c, cond.Business, oids, users)
  1026. challPage = &search.ChallListPageCommon{}
  1027. challList := make([]*model.Chall, 0, len(challSearchResp.Result))
  1028. for _, r := range challSearchResp.Result {
  1029. var (
  1030. t *model.TagMeta
  1031. l string
  1032. )
  1033. cid := r.ID
  1034. chall, ok = challs[cid]
  1035. if !ok {
  1036. log.Warn("Invalid challenge id %d", r.ID)
  1037. continue
  1038. }
  1039. // fill tag
  1040. if t, err = s.tag(chall.Business, chall.Tid); err != nil {
  1041. log.Error("s.tag(%d,%d) error(%v)", chall.Business, chall.Tid, err)
  1042. err = nil
  1043. } else {
  1044. chall.Tag = t.Name
  1045. chall.Round = t.RID
  1046. }
  1047. // fill last log
  1048. if l, ok = challLastLog[cid]; ok {
  1049. chall.LastLog = l
  1050. }
  1051. // fill last event
  1052. chall.LastEvent = challLastEvent[cid]
  1053. // fill attachments
  1054. chall.Attachments = make([]string, 0)
  1055. if ps, ok = attPaths[cid]; ok {
  1056. chall.Attachments = ps
  1057. chall.FixAttachments()
  1058. }
  1059. chall.FormatState()
  1060. //fill business object
  1061. if b, ok = gidToBus[chall.Gid]; ok {
  1062. chall.BusinessObject = b
  1063. }
  1064. //fill meta
  1065. s.wrapChallMeta(cond.Business, chall, meta)
  1066. chall.AssigneeAdminName = uNames[chall.AssigneeAdminID]
  1067. chall.AdminName = uNames[chall.AdminID]
  1068. if chall.Producer, ok = users[chall.Mid]; !ok {
  1069. log.Warn("failed get producer info mid(%d)", chall.Mid)
  1070. }
  1071. chall.OidStr = strconv.FormatInt(chall.Oid, 10)
  1072. challList = append(challList, chall)
  1073. }
  1074. challPage.Items = challList
  1075. challPage.Page = &model.Page{
  1076. Num: challSearchResp.Page.Num,
  1077. Size: challSearchResp.Page.Size,
  1078. Total: challSearchResp.Page.Total,
  1079. }
  1080. return
  1081. }
  1082. func (s *Service) searchChallMeta(c context.Context, business int8, oids []int64, users map[int64]*model.Account) (meta interface{}) {
  1083. var (
  1084. ok bool
  1085. err error
  1086. archives map[int64]*model.Archive
  1087. )
  1088. switch business {
  1089. case model.ArchiveAppeal, model.ArchiveAudit:
  1090. var (
  1091. resp *search.AuditLogSearchCommonResult
  1092. lastAuditLogExtraMap = make(map[int64]*search.ArchiveAuditLogExtra)
  1093. )
  1094. if archives, err = s.dao.ArchiveRPC(c, oids); err != nil {
  1095. log.Error("s.dao.ArchiveInfosV3(%v) error(%v)", oids, err)
  1096. err = nil
  1097. return archives
  1098. }
  1099. cond := &search.AuditReportSearchCond{
  1100. Business: 3,
  1101. Fields: []string{"oid", "extra_data"},
  1102. Order: "ctime",
  1103. Sort: "desc",
  1104. Oid: oids,
  1105. Distinct: "oid",
  1106. IndexTimeType: "month",
  1107. IndexTimeFrom: time.Now().AddDate(0, -6, 0),
  1108. IndexTimeEnd: time.Now(),
  1109. }
  1110. if resp, err = s.dao.SearchAuditReportLog(c, cond); err != nil {
  1111. log.Error("s.dao.SearchAuditReportLog(%+v) error(%v)", cond, err)
  1112. err = nil
  1113. }
  1114. for _, l := range resp.Result {
  1115. extra := new(search.ArchiveAuditLogExtra)
  1116. if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
  1117. log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
  1118. continue
  1119. }
  1120. lastAuditLogExtraMap[l.Oid] = extra
  1121. }
  1122. for _, l := range resp.Result {
  1123. extra := new(search.ArchiveAuditLogExtra)
  1124. if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
  1125. log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
  1126. continue
  1127. }
  1128. }
  1129. for oid, a := range archives {
  1130. if a.Composer, ok = users[a.Mid]; !ok {
  1131. log.Warn("failed get account info mid(%d)", a.Mid)
  1132. a.Composer = &model.Account{}
  1133. continue
  1134. }
  1135. var extra *search.ArchiveAuditLogExtra
  1136. if extra, ok = lastAuditLogExtraMap[oid]; !ok {
  1137. log.Warn("failed get audit log of archive(%d)", oid)
  1138. continue
  1139. } else {
  1140. a.OPName = extra.Content.UName
  1141. a.OPContent = extra.Diff
  1142. a.OPRemark = extra.Content.Note
  1143. }
  1144. }
  1145. }
  1146. return
  1147. }
  1148. func (s *Service) wrapChallMeta(business int8, chall *model.Chall, meta interface{}) {
  1149. switch business {
  1150. case model.ArchiveAppeal: // 稿件申诉
  1151. var (
  1152. a *model.Archive
  1153. archives map[int64]*model.Archive
  1154. ok bool
  1155. )
  1156. if archives, ok = meta.(map[int64]*model.Archive); !ok {
  1157. return
  1158. }
  1159. if a, ok = archives[chall.Oid]; !ok {
  1160. log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, chall.Cid)
  1161. chall.Meta = struct{}{}
  1162. break
  1163. }
  1164. chall.Meta = a
  1165. case model.CreditAppeal: //小黑屋
  1166. if chall.BusinessObject == nil {
  1167. log.Warn("can not get credit appeal info oid(%d) cid(%d) business(%d)", chall.Oid, chall.Cid, chall.Business)
  1168. break
  1169. }
  1170. cMeta := &model.CreditMeta{
  1171. Business: chall.BusinessObject,
  1172. }
  1173. chall.Meta = cMeta
  1174. case model.ArchiveAudit: //稿件审核
  1175. var (
  1176. a *model.Archive
  1177. archives map[int64]*model.Archive
  1178. ok bool
  1179. )
  1180. if archives, ok = meta.(map[int64]*model.Archive); !ok {
  1181. return
  1182. }
  1183. if a, ok = archives[chall.Oid]; !ok {
  1184. log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, chall.Cid)
  1185. }
  1186. chall.Meta = a
  1187. }
  1188. }