12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280 |
- package service
- import (
- "context"
- "encoding/json"
- "fmt"
- "strconv"
- "time"
- "go-common/app/admin/main/workflow/model"
- "go-common/app/admin/main/workflow/model/param"
- "go-common/app/admin/main/workflow/model/search"
- "go-common/library/ecode"
- "go-common/library/log"
- "github.com/pkg/errors"
- )
- // SetChallResult will set a challenge result
- func (s *Service) SetChallResult(c context.Context, crp *param.ChallResParam) (err error) {
- var (
- chall *model.Chall
- g *model.Group
- rows int64
- )
- // Check challenge and group is exist
- if chall, err = s.dao.Chall(c, crp.Cid); err != nil {
- log.Error("s.dao.Chall() error(%v)", err)
- return
- }
- if chall == nil {
- log.Error("Challenge(%d) not exist", crp.Cid)
- err = ecode.NothingFound
- return
- }
- chall.SetState(uint32(crp.State), 0)
- chall.AdminID = crp.AdminID
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Error("wocao jingran recover le error(%v)", r)
- }
- }()
- if rows, err = s.dao.TxUpChall(tx, chall); err != nil {
- tx.Rollback()
- log.Error("s.dao.TxUpChall(%v) err(%v)", chall, err)
- return
- }
- if g, err = s.dao.GroupByID(c, chall.Gid); err != nil {
- tx.Rollback()
- log.Error("s.dao.GroupByID() error(%v)", err)
- return
- }
- if g == nil {
- tx.Rollback()
- log.Error("Group(%d) not exist", chall.Gid)
- err = ecode.NothingFound
- return
- }
- // decrease group pending stat count
- g.Handling -= int32(rows)
- if g.Handling < 0 {
- g.Handling = 0
- }
- if err = s.dao.TxUpGroupHandling(tx, g.ID, g.Handling); err != nil {
- tx.Rollback()
- log.Error("Failed to update group stat count(%d) all(%d) by gid %d, error(%v)",
- g.Count, g.Handling, g.ID, err)
- return
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("tx.Commit() error(%v)", err)
- return
- }
- s.task(func() {
- s.afterSetChallResult(crp, chall)
- })
- return
- }
- // BatchSetChallResult will set a set of challenges result
- func (s *Service) BatchSetChallResult(c context.Context, bcrp *param.BatchChallResParam) (err error) {
- var (
- cids []int64 // all requested cids
- pcids []int64 // pending cids
- gids []int64
- challs map[int64]*model.Chall
- groups map[int64]*model.Group
- gidToDecr map[int64]int32
- )
- // collect cids
- cids = append(cids, bcrp.Cids...)
- if challs, err = s.dao.StateChalls(c, cids, model.Pending); err != nil {
- log.Error("s.dao.StateChalls() error(%v)", err)
- return
- }
- // collect gids
- gidToDecr = make(map[int64]int32, len(challs))
- for _, c := range challs {
- pcids = append(pcids, int64(c.Cid))
- gids = append(gids, int64(c.Gid))
- if _, ok := gidToDecr[c.Gid]; !ok {
- gidToDecr[c.Gid] = 0
- }
- gidToDecr[c.Gid]++
- }
- if groups, err = s.dao.Groups(c, gids); err != nil {
- log.Error("s.dao.Groups() error(%v)", err)
- return
- }
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Error("wocao jingran recover le error(%v)", r)
- }
- }()
- if err = s.dao.TxBatchUpChallByIDs(tx, pcids, bcrp.State); err != nil {
- tx.Rollback()
- log.Error("s.dao.TxBatchUpChallByIDs(%+v) error(%v)", bcrp, err)
- return
- }
- // decrease pending stat count by gidToDesc
- for gid, decr := range gidToDecr {
- g, ok := groups[gid]
- if !ok {
- log.Error("Failed to retrive group by gid %d", gid)
- continue
- }
- // decr group handling counts
- g.Handling -= decr
- if g.Handling < 0 {
- g.Handling = 0
- }
- if err = s.dao.TxUpGroupHandling(tx, gid, g.Handling); err != nil {
- tx.Rollback()
- log.Error("Failed to update group stat count(%d) all(%d) by gid %d, error(%v)",
- g.Count, g.Handling, g.ID, err)
- return
- }
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("tx.Commit() error(%v)", err)
- return
- }
- //double write state to dispatch_state field
- changedChalls, err := s.dao.Challs(c, pcids)
- for cid := range changedChalls {
- changedChalls[cid].SetState(uint32(bcrp.State), 0)
- if err = s.dao.BatchUpChallByIDs([]int64{int64(cid)}, changedChalls[cid].DispatchState, bcrp.AdminID); err != nil {
- log.Error("s.dao.BatchUpChallByIDs(%v,%d,%d) error(%v)", cid, changedChalls[cid].DispatchState, bcrp.AdminID, err)
- return
- }
- }
- s.task(func() {
- s.afterBatchSetChallResult(bcrp, challs)
- })
- return
- }
- // UpChallExtraV2 will update extra data of a challenge by cid
- func (s *Service) UpChallExtraV2(c context.Context, cep *param.ChallExtraParam) (err error) {
- var (
- obj *model.Business
- chall *model.Chall
- )
- if chall, err = s.dao.Chall(c, cep.Cid); err != nil {
- log.Error("s.dao.Chall(%d) error(%v)", cep.Cid, err)
- return
- }
- if obj, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
- log.Error("s.dao.LastBusRec(%d, %d) error(%v)", chall.Business, chall.Oid, err)
- return
- }
- if obj == nil {
- err = ecode.NothingFound
- return
- }
- parsed := make(map[string]interface{})
- if obj.Extra != "" {
- if err1 := json.Unmarshal([]byte(obj.Extra), &parsed); err1 != nil {
- log.Error("json.Unmarshal(%s) error(%v)", obj.Extra, err1)
- }
- }
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Error("s.UpChallExtra() panic(%v)", r)
- }
- }()
- for k, v := range cep.Extra {
- parsed[k] = v
- }
- if _, err = s.dao.TxUpChallExtraV2(tx, chall.Business, chall.Oid, cep.AdminID, parsed); err != nil {
- tx.Rollback()
- log.Error("s.dao.UpChallExtra(%d, %d, %v) error(%v)", cep.Cid, cep.AdminID, parsed, err)
- return
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("tx.Commit() error(%v)", err)
- return
- }
- return
- }
- // BatchUpChallExtraV2 update business object extra field by business oid
- func (s *Service) BatchUpChallExtraV2(c context.Context, bcep *param.BatchChallExtraParam) (err error) {
- var (
- challs map[int64]*model.Chall
- bs *model.Business
- )
- if challs, err = s.dao.Challs(c, bcep.Cids); err != nil {
- log.Error("s.dao.Challs(%v) error(%v)", bcep.Cids, err)
- return
- }
- parsed := make(map[int64]map[string]interface{}, len(challs))
- for cid, chall := range challs {
- if bs, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
- log.Error("s.dao.LastBusRec(%d, %d) error(%v)", chall.Business, chall.Oid, err)
- return
- }
- inner := make(map[string]interface{})
- if bs.Extra != "" {
- if err1 := json.Unmarshal([]byte(bs.Extra), &inner); err1 != nil {
- log.Error("json.Unmarshal(%s) error(%v)", bs.Extra, err1)
- }
- }
- parsed[cid] = inner
- }
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- for _, ex := range parsed {
- for k, v := range bcep.Extra {
- ex[k] = v
- }
- }
- for cid, ex := range parsed {
- chall := challs[cid]
- if _, err = s.dao.TxUpChallExtraV2(tx, chall.Business, chall.Oid, bcep.AdminID, ex); err != nil {
- tx.Rollback()
- log.Error("s.dao.TxUpChallExtra(%d, %d, %v) error(%v)", cid, bcep.AdminID, ex, err)
- return
- }
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("tx.Commit() error(%v)", err)
- return
- }
- return
- }
- // UpChallExtraV3 .
- func (s *Service) UpChallExtraV3(c context.Context, cep3 *param.ChallExtraParamV3) (err error) {
- //todo
- return
- }
- // ChallList will list challenges by several conditions
- // Deprecated
- func (s *Service) ChallList(c context.Context, cond *search.ChallSearchCommonCond) (challPage *search.ChallListPageCommon, err error) {
- var (
- resp *search.ChallSearchCommonResp
- cids []int64
- challs map[int64]*model.Chall
- challLastLog map[int64]string
- attPaths map[int64][]string
- t *model.TagMeta
- )
- if resp, err = s.dao.SearchChallenge(c, cond); err != nil {
- log.Error("s.dao.SearchChall() error(%v)", err)
- return
- }
- cids = make([]int64, 0, len(resp.Result))
- for _, r := range resp.Result {
- cids = append(cids, r.ID)
- }
- if challs, err = s.dao.Challs(c, cids); err != nil {
- log.Error("s.dao.Challs() error(%v)", err)
- return
- }
- // read state from new state field
- for cid := range challs {
- challs[cid].FromState()
- }
- if challLastLog, err = s.LastLog(c, cids, []int{model.WLogModuleChallenge}); err != nil {
- log.Error("s.dao.BatchLastLog() error(%v)", err)
- err = nil
- }
- if attPaths, err = s.dao.AttPathsByCids(c, cids); err != nil {
- log.Error("s.dao.AttPathsByCids() error(%v)", err)
- return
- }
- challPage = &search.ChallListPageCommon{}
- challList := make([]*model.Chall, 0, len(resp.Result))
- for _, r := range resp.Result {
- cid := r.ID
- c, ok := challs[cid]
- if !ok {
- log.Warn("Invalid challenge id %d", r.ID)
- continue
- }
- // fill tag
- if t, err = s.tag(c.Business, c.Tid); err != nil {
- log.Error("Failed to retrive tag by bid(%d) tag_id(%d)", c.Business, c.Tid)
- err = nil
- } else {
- c.Tag = t.Name
- c.Round = t.RID
- }
- // fill last log
- if l, ok := challLastLog[cid]; ok {
- c.LastLog = l
- }
- // fill attachments
- c.Attachments = make([]string, 0)
- if ps, ok := attPaths[cid]; ok {
- c.Attachments = ps
- c.FixAttachments()
- }
- c.FormatState()
- challList = append(challList, c)
- }
- challPage.Items = challList
- challPage.Page = &model.Page{
- Num: resp.Page.Num,
- Size: resp.Page.Size,
- Total: resp.Page.Total,
- }
- return
- }
- // ChallListCommon will list challenges by several conditions
- func (s *Service) ChallListCommon(c context.Context, cond *search.ChallSearchCommonCond) (challPage *search.ChallListPageCommon, err error) {
- var (
- challSearchResp *search.ChallSearchCommonResp
- business int8
- cids []int64
- uids []int64
- oids []int64
- uNames map[int64]string
- mids []int64
- challs map[int64]*model.Chall
- challLastLog map[int64]string
- challLastEvent map[int64]*model.Event
- attPaths map[int64][]string
- archives map[int64]*model.Archive
- authors map[int64]*model.Account
- lastAuditLogSchRes *search.AuditLogSearchResult // 最近的稿件操作日志
- lastAuditLogExtraMap map[int64]*search.ArchiveAuditLogExtra // 稿件操作日志 extra 信息
- chall *model.Chall
- ps []string //attachments
- ok bool
- l string
- )
- business = cond.Business
- if challSearchResp, err = s.dao.SearchChallenge(c, cond); err != nil {
- log.Error("s.dao.SearchChallenge() error(%v)", err)
- return
- }
- // no result in es
- if challSearchResp.Page.Total == 0 {
- challPage = &search.ChallListPageCommon{}
- challPage.Items = make([]*model.Chall, 0)
- challPage.Page = &model.Page{
- Num: challSearchResp.Page.Num,
- Size: challSearchResp.Page.Size,
- Total: challSearchResp.Page.Total,
- }
- return
- }
- cids = make([]int64, 0, len(challSearchResp.Result))
- oids = make([]int64, 0, len(challSearchResp.Result))
- for _, r := range challSearchResp.Result {
- cids = append(cids, r.ID)
- }
- if challs, err = s.dao.Challs(c, cids); err != nil {
- log.Error("s.dao.Challs(%v) error(%v)", cids, err)
- return
- }
- // read state from new state field
- for cid, c := range challs {
- challs[cid].FromState()
- uids = append(uids, int64(c.AdminID))
- uids = append(uids, int64(c.AssigneeAdminID))
- oids = append(oids, c.Oid)
- mids = append(mids, c.Mid)
- }
- if challLastLog, err = s.LastLog(c, cids, []int{model.WLogModuleChallenge}); err != nil {
- log.Error("s.batchLastLog(%v,%v) error(%v)", cids, model.WLogModuleChallenge, err)
- err = nil
- }
- // admin unames
- if uNames, err = s.dao.BatchUNameByUID(c, uids); err != nil {
- log.Error("s.dao.SearchUNameByUid(%v) error(%v)", uids, err)
- err = nil
- }
- if attPaths, err = s.dao.AttPathsByCids(c, cids); err != nil {
- log.Error("s.dao.AttPathsByCids() error(%v)", err)
- return
- }
- if challLastEvent, err = s.batchLastEvent(c, cids); err != nil {
- log.Error("s.batchLastEvent(%v) error(%v)", cids, err)
- return
- }
- switch business {
- case model.ArchiveAppeal:
- if archives, err = s.dao.ArchiveRPC(c, oids); err != nil {
- log.Error("s.dao.ArchiveInfos(%v) error(%v)", oids, err)
- err = nil
- } else {
- cond := &search.AuditLogGroupSearchCond{
- Businesses: []int64{3},
- Order: "ctime",
- PS: 100,
- PN: 1,
- Sort: "desc",
- Oids: oids,
- Group: []string{"oid"},
- }
- if lastAuditLogSchRes, err = s.dao.SearchAuditLogGroup(c, cond); err != nil {
- log.Error("s.dao.SearchAuditLogGroup(%+v) error(%v)", cond, err)
- err = nil
- }
- lastAuditLogExtraMap = make(map[int64]*search.ArchiveAuditLogExtra)
- for _, l := range lastAuditLogSchRes.Data.Result {
- extra := new(search.ArchiveAuditLogExtra)
- if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
- log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
- continue
- }
- lastAuditLogExtraMap[l.Oid] = extra
- }
- }
- case model.CreditAppeal:
- authors = s.dao.AccountInfoRPC(c, mids)
- case model.ArchiveAudit:
- if archives, err = s.dao.ArchiveRPC(c, oids); err != nil {
- log.Error("s.dao.ArchiveInfos(%v) error(%v)", oids, err)
- err = nil
- } else {
- cond := &search.AuditLogGroupSearchCond{
- Businesses: []int64{3},
- Order: "ctime",
- PS: 100,
- PN: 1,
- Sort: "desc",
- Oids: oids,
- Group: []string{"oid"},
- }
- if lastAuditLogSchRes, err = s.dao.SearchAuditLogGroup(c, cond); err != nil {
- log.Error("s.dao.SearchAuditLogGroup(%+v) error(%v)", cond, err)
- err = nil
- }
- lastAuditLogExtraMap = make(map[int64]*search.ArchiveAuditLogExtra)
- for _, l := range lastAuditLogSchRes.Data.Result {
- extra := new(search.ArchiveAuditLogExtra)
- if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
- log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
- continue
- }
- lastAuditLogExtraMap[l.Oid] = extra
- }
- }
- }
- challPage = &search.ChallListPageCommon{}
- challList := make([]*model.Chall, 0, len(challSearchResp.Result))
- for _, r := range challSearchResp.Result {
- cid := r.ID
- chall, ok = challs[cid]
- if !ok {
- log.Warn("Invalid challenge id %d", r.ID)
- continue
- }
- // fill tag
- var t *model.TagMeta
- if t, err = s.tag(chall.Business, chall.Tid); err != nil {
- log.Error("s.tag(%d,%d) error(%v)", chall.Business, chall.Tid, err)
- err = nil
- } else {
- chall.Tag = t.Name
- chall.Round = t.RID
- }
- // fill last log
- if l, ok = challLastLog[cid]; ok {
- chall.LastLog = l
- }
- // fill last event
- chall.LastEvent = challLastEvent[cid]
- // fill attachments
- chall.Attachments = make([]string, 0)
- if ps, ok = attPaths[cid]; ok {
- chall.Attachments = ps
- chall.FixAttachments()
- }
- chall.FormatState()
- //fill business object
- if chall.BusinessObject, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
- log.Error("s.dao.LastBusRec(%d, %d) error(%v)", chall.Business, chall.Oid, err)
- err = nil
- }
- //todo: add challenge meta
- switch business {
- case model.ArchiveAppeal: // 稿件申诉
- var (
- archive *model.Archive
- extra *search.ArchiveAuditLogExtra
- )
- if archive, ok = archives[chall.Oid]; !ok {
- log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, r.ID)
- }
- if extra, ok = lastAuditLogExtraMap[chall.Oid]; !ok {
- log.Warn("not exist archive operate last audit log extra oid(%d) cid(%d)", chall.Oid, r.ID)
- }
- if extra != nil && archive != nil {
- archive.OPName = extra.Content.UName
- archive.OPContent = extra.Diff
- archive.OPRemark = extra.Content.Note
- }
- chall.Meta = archive
- case model.CreditAppeal: //小黑屋
- chall.Meta = chall.BusinessObject
- if _, ok = authors[chall.Mid]; ok {
- chall.MName = authors[chall.Mid].Name
- }
- case model.ArchiveAudit: //稿件审核
- var archive *model.Archive
- var extra *search.ArchiveAuditLogExtra
- if archive, ok = archives[chall.Oid]; !ok {
- log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, r.ID)
- }
- if extra, ok = lastAuditLogExtraMap[chall.Oid]; !ok {
- log.Warn("not exist archive operate last audit log extra oid(%d) cid(%d)", chall.Oid, r.ID)
- }
- if extra != nil && archive != nil {
- archive.OPName = extra.Content.UName
- archive.OPContent = extra.Diff
- archive.OPRemark = extra.Content.Note
- }
- chall.Meta = archive
- }
- chall.AssigneeAdminName = uNames[chall.AssigneeAdminID]
- chall.AdminName = uNames[chall.AdminID]
- challList = append(challList, chall)
- }
- challPage.Items = challList
- challPage.Page = &model.Page{
- Num: challSearchResp.Page.Num,
- Size: challSearchResp.Page.Size,
- Total: challSearchResp.Page.Total,
- }
- return
- }
- // ChallDetail will retrive challenge by cid
- func (s *Service) ChallDetail(c context.Context, cid int64) (chall *model.Chall, err error) {
- var (
- cl map[int64]string
- attPaths []string
- t *model.TagMeta
- bs *model.Business
- lastEvent *model.Event
- archives map[int64]*model.Archive
- authors map[int64]*model.Account
- ok bool
- l string
- )
- if chall, err = s.dao.Chall(c, cid); err != nil || chall == nil {
- log.Error("Failed to s.dao.Chall(%d) or chall not found: %v", cid, err)
- err = ecode.NothingFound
- return
- }
- // read state from new state field
- chall.FromState()
- if attPaths, err = s.dao.AttPathsByCid(c, cid); err != nil {
- log.Error("Failed to s.dao.AttPathsByCid(%d): %v", cid, err)
- err = nil
- }
- if cl, err = s.LastLog(c, []int64{cid}, []int{model.WLogModuleChallenge}); err != nil {
- log.Error("Failed to s.dao.LastLog(%d): %v", cid, err)
- err = nil
- }
- if lastEvent, err = s.dao.LastEventByCid(c, cid); err != nil {
- log.Error("Failed to s.dao.EventsByCid(%d): %v", cid, err)
- err = nil
- }
- if t, err = s.tag(chall.Business, chall.Tid); err != nil {
- log.Error("Failed to s.tag(%d,%d) error(%v)", chall.Business, chall.Tid, err)
- // fixme: to debug
- err = nil
- } else {
- chall.Tag = t.Name
- chall.Round = t.RID
- }
- if bs, err = s.dao.LastBusRec(c, chall.Business, chall.Oid); err != nil {
- log.Error("Failed to s.dao.BusRecByCid(%d): %v", cid, err)
- err = nil
- }
- business := chall.Business
- switch business {
- case model.ArchiveAppeal:
- if archives, err = s.dao.ArchiveRPC(c, []int64{chall.Oid}); err != nil {
- log.Error("s.dao.ArchiveInfos(%v) error(%v)", chall.Oid, err)
- err = nil
- }
- }
- switch business {
- case model.ArchiveAppeal: // 稿件申诉
- if chall.Meta, ok = archives[chall.Oid]; !ok {
- log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, chall.Cid)
- }
- case model.CreditAppeal: //小黑屋
- chall.Meta = chall.BusinessObject
- if authors = s.dao.AccountInfoRPC(c, []int64{chall.Mid}); authors != nil {
- if _, ok = authors[chall.Mid]; ok {
- chall.MName = authors[chall.Mid].Name
- }
- }
- }
- if l, ok = cl[cid]; ok {
- chall.LastLog = l
- } else {
- log.Info("cid(%d) not found last log", cid)
- }
- chall.LastEvent = lastEvent
- chall.BusinessObject = bs
- chall.Attachments = attPaths
- chall.FixAttachments()
- return
- }
- // UpChallBusState will update business_state field of a challenge
- func (s *Service) UpChallBusState(c context.Context, cid int64, assigneeAdminid int64, assigneeAdminName string, busState int8) (err error) {
- // TODO(zhoujiahui): record in log?
- if cid <= 0 {
- err = ecode.WkfChallNotFound
- return
- }
- if err = s.dao.UpChallBusState(c, cid, busState, assigneeAdminid); err != nil {
- return
- }
- s.task(func() {
- var (
- result []*search.ChallSearchCommonData
- challs []*model.Chall
- )
- cond := &search.ChallSearchCommonCond{
- Fields: []string{"id", "oid", "business", "mid", "typeid"},
- IDs: []int64{cid},
- }
- if result, err = s.dao.SearchChallengeMultiPage(context.Background(), cond); err != nil {
- log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
- return
- }
- for _, r := range result {
- c := &model.Chall{
- Cid: r.ID,
- Oid: r.Oid,
- Business: r.Business,
- BusinessState: busState,
- AssigneeAdminID: assigneeAdminid,
- AssigneeAdminName: assigneeAdminName,
- Mid: r.Mid,
- TypeID: r.TypeID,
- }
- challs = append(challs, c)
- }
- s.afterSetBusinessState(challs)
- })
- return
- }
- // BatchUpChallBusState will update business_state field of a set of challenges
- func (s *Service) BatchUpChallBusState(c context.Context, cids []int64, assigneeAdminid int64, assigneeAdminName string, busState int8) (err error) {
- // TODO(zhoujiahui): record in log?
- if len(cids) <= 0 {
- return
- }
- if err = s.dao.BatchUpChallBusState(c, cids, busState, assigneeAdminid); err != nil {
- return
- }
- s.task(func() {
- var (
- result []*search.ChallSearchCommonData
- challs []*model.Chall
- )
- cond := &search.ChallSearchCommonCond{
- Fields: []string{"id", "oid", "business", "mid", "typeid"},
- IDs: cids,
- }
- if result, err = s.dao.SearchChallengeMultiPage(context.Background(), cond); err != nil {
- log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
- return
- }
- for _, r := range result {
- c := &model.Chall{
- Cid: r.ID,
- Oid: r.Oid,
- Business: r.Business,
- BusinessState: busState,
- AssigneeAdminID: assigneeAdminid,
- AssigneeAdminName: assigneeAdminName,
- Mid: r.Mid,
- TypeID: r.TypeID,
- }
- challs = append(challs, c)
- }
- s.afterSetBusinessState(challs)
- })
- return
- }
- // SetChallBusState will update business_state field of a set of challenges
- func (s *Service) SetChallBusState(c context.Context, bcbsp *param.BatchChallBusStateParam) (err error) {
- // TODO(zhoujiahui): record in log?
- if len(bcbsp.Cids) <= 0 {
- return
- }
- if err = s.dao.BatchUpChallBusState(c, bcbsp.Cids, bcbsp.BusState, bcbsp.AssigneeAdminID); err != nil {
- return
- }
- s.task(func() {
- var (
- result []*search.ChallSearchCommonData
- challs []*model.Chall
- )
- cond := &search.ChallSearchCommonCond{
- Fields: []string{"id", "oid", "business", "mid", "typeid"},
- IDs: bcbsp.Cids,
- }
- if result, err = s.dao.SearchChallengeMultiPage(context.Background(), cond); err != nil {
- log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
- return
- }
- for _, r := range result {
- c := &model.Chall{
- Cid: r.ID,
- Oid: r.Oid,
- Business: r.Business,
- BusinessState: bcbsp.BusState,
- AssigneeAdminID: bcbsp.AssigneeAdminID,
- AssigneeAdminName: bcbsp.AssigneeAdminName,
- Mid: r.Mid,
- TypeID: r.TypeID,
- }
- challs = append(challs, c)
- }
- s.afterSetBusinessState(challs)
- })
- return
- }
- // UpBusChallsBusState will update business_state field of a set of challenges with same business and oid
- func (s *Service) UpBusChallsBusState(c context.Context, business, busState int8, preBusStates []int8, oid int64, assigneeAdminid int64, extra map[string]interface{}) (cids []int64, err error) {
- // TODO(zhoujiahui): record in log?
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Error("wocao jingran recover le error(%v)", r)
- }
- }()
- if cids, err = s.dao.TxChallsByBusStates(tx, business, oid, preBusStates); err != nil {
- tx.Rollback()
- log.Error("s.dao.TxChallsByBusStates(%d, %d, %s) error(%v)", business, oid, preBusStates, err)
- return
- }
- if err = s.dao.TxUpChallsBusStateByIDs(tx, cids, busState, assigneeAdminid); err != nil {
- tx.Rollback()
- log.Error("s.dao.TxUpChallsBusStateByIDs(%s, %d) error(%v)", cids, busState, err)
- return
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("tx.Commit() error(%v)", err)
- return
- }
- bcep := ¶m.BatchChallExtraParam{
- Cids: cids,
- AdminID: assigneeAdminid,
- Extra: extra,
- }
- if err = s.BatchUpChallExtraV2(c, bcep); err != nil {
- log.Error("s.BatchUpChallExtra(%v) error(%v)", bcep, err)
- return
- }
- // double write to new field
- challs, err := s.dao.Challs(c, cids)
- if err != nil {
- return
- }
- for cid := range challs {
- challs[cid].SetState(uint32(busState), uint8(1))
- if err = s.dao.ORM.Table("workflow_chall").Where("id=?", cid).Update("dispatch_state", challs[cid].DispatchState).Error; err != nil {
- err = errors.Wrapf(err, "cid(%d), dispatch_state(%d)", cid, challs[cid].DispatchState)
- return
- }
- }
- return
- }
- // RstChallResult will reset challenge and its linked group state as Pending
- func (s *Service) RstChallResult(c context.Context, crp *param.ChallRstParam) (err error) {
- var (
- chall *model.Chall
- group *model.Group
- )
- if chall, err = s.dao.Chall(c, crp.Cid); err != nil || chall == nil {
- log.Error("Failed to query challenge(%d) or it not exist: %v", crp.Cid, err)
- return
- }
- if group, err = s.dao.GroupByID(c, chall.Gid); err != nil || group == nil {
- log.Error("Failed to query group(%d) or it not exist: %v", chall.Gid, err)
- return
- }
- // update new field
- chall.SetState(uint32(crp.State), 0)
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Error("s.RstChallResult() panic(%v)", r)
- }
- }()
- if err = tx.Model(chall).UpdateColumn(map[string]interface{}{
- "state": crp.State,
- "dispatch_state": chall.DispatchState,
- }).Error; err != nil {
- tx.Rollback()
- log.Error("Failed to set chall(%v) as pending: %v", chall, err)
- return
- }
- if err = tx.Model(group).UpdateColumn(map[string]interface{}{
- "state": crp.State,
- }).Error; err != nil {
- tx.Rollback()
- log.Error("Failed to set group(%v) as pending: %v", group, err)
- return
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("Failed to tx.Commit() in RstChallResult: %v", err)
- return
- }
- s.task(func() {
- cl := &model.WLog{
- AdminID: crp.AdminID,
- Admin: crp.AdminName,
- Oid: chall.Oid,
- Business: chall.Business,
- Target: chall.Cid,
- Module: model.WLogModuleChallenge,
- Remark: fmt.Sprintf(`“工单详情编号 %d”设置为 %s 移交复审`, chall.Cid, s.StateDescr(chall.Business, 0, crp.State)),
- Note: crp.Reason,
- }
- gl := &model.WLog{
- AdminID: crp.AdminID,
- Admin: crp.AdminName,
- Oid: group.Oid,
- Business: group.Business,
- Target: group.ID,
- Module: model.WLogModuleGroup,
- Remark: fmt.Sprintf(`“工单编号 %d”设置为 %s 移交复审`, group.ID, s.StateDescr(chall.Business, 0, crp.State)),
- Note: crp.Reason,
- }
- s.writeAuditLog(cl)
- s.writeAuditLog(gl)
- })
- return
- }
- // BusinessList will retrive business object by cids
- // Deprecated
- func (s *Service) BusinessList(c context.Context, cids []int64) (cidToBus map[int64]*model.Business, err error) {
- if cidToBus, err = s.dao.BatchBusRecByCids(c, cids); err != nil {
- log.Error("s.dao.BatchBusRecByCids(%v) error(%v)", cids, err)
- return
- }
- return
- }
- // UpChall will update challenge tid
- func (s *Service) UpChall(c context.Context, cup *param.ChallUpParam) (err error) {
- var (
- chall *model.Chall
- t *model.TagMeta
- )
- // Check group and tag is exist
- if chall, err = s.dao.Chall(c, cup.Cid); err != nil {
- log.Error("s.dao.Chall(%d) error(%v)", cup.Cid, err)
- return
- }
- if chall == nil {
- log.Error("Challenge(%d) not exist", cup.Cid)
- err = ecode.WkfChallNotFound
- return
- }
- if t, err = s.tag(chall.Business, cup.Tid); err != nil {
- log.Error("bid(%d) tag_id(%d) not found in cache", chall.Business, cup.Tid)
- return
- }
- tx := s.dao.ORM.Begin()
- if err = tx.Error; err != nil {
- log.Error("s.dao.ORM.Begin() error(%v)", err)
- return
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Error("wocao jingran recover le error(%v)", r)
- }
- }()
- if err = s.dao.TxUpChallTag(tx, cup.Cid, cup.Tid); err != nil {
- tx.Rollback()
- log.Error("s.TxUpChallTag(%d, %d) error(%v)", cup.Cid, cup.Tid, err)
- return
- }
- if err = tx.Commit().Error; err != nil {
- tx.Rollback()
- log.Error("tx.Commit() error(%v)", err)
- return
- }
- s.task(func() {
- l := &model.WLog{
- Oid: chall.Oid,
- Business: chall.Business,
- Target: chall.Cid,
- Module: model.WLogModuleChallenge,
- AdminID: cup.AdminID,
- Admin: cup.AdminName,
- Remark: fmt.Sprintf(`工单编号 %d “管理 Tag”更新为“%s”`, cup.Cid, t.Name),
- }
- s.writeAuditLog(l)
- })
- return
- }
- // ChallListV3 .
- func (s *Service) ChallListV3(c context.Context, cond *search.ChallSearchCommonCond) (challPage *search.ChallListPageCommon, err error) {
- var (
- challSearchResp *search.ChallSearchCommonResp
- uNames map[int64]string
- challs map[int64]*model.Chall
- challLastLog map[int64]string
- challLastEvent map[int64]*model.Event
- attPaths map[int64][]string
- gidToBus map[int64]*model.Business
- users map[int64]*model.Account
- b *model.Business
- chall *model.Chall
- ps []string //attachments
- ok bool
- meta interface{}
- )
- if challSearchResp, err = s.dao.SearchChallenge(c, cond); err != nil {
- log.Error("s.dao.SearchChallenge() error(%v)", err)
- err = ecode.WkfSearchChallFailed
- return
- }
- // no result in es
- if challSearchResp.Page.Total == 0 {
- challPage = &search.ChallListPageCommon{}
- challPage.Items = make([]*model.Chall, 0)
- challPage.Page = &model.Page{
- Num: challSearchResp.Page.Num,
- Size: challSearchResp.Page.Size,
- Total: challSearchResp.Page.Total,
- }
- return
- }
- cids := make([]int64, 0, len(challSearchResp.Result))
- oids := make([]int64, 0, len(challSearchResp.Result))
- mids := make([]int64, 0, len(challSearchResp.Result))
- gids := make([]int64, 0, len(challSearchResp.Result))
- uids := make([]int64, 0, len(challSearchResp.Result)*2)
- for _, r := range challSearchResp.Result {
- cids = append(cids, r.ID)
- oids = append(oids, r.Oid)
- mids = append(mids, r.Mid)
- gids = append(gids, r.Gid)
- }
- if challs, err = s.dao.Challs(c, cids); err != nil {
- log.Error("s.dao.Challs(%v) error(%v)", cids, err)
- return
- }
- // read state from new state field
- for cid, c := range challs {
- challs[cid].FromState()
- uids = append(uids, int64(c.AdminID))
- uids = append(uids, int64(c.AssigneeAdminID))
- }
- if challLastLog, err = s.LastLog(c, cids, []int{model.WLogModuleChallenge}); err != nil {
- log.Error("s.LastLog(%v,%v) error(%v)", cids, model.WLogModuleChallenge, err)
- err = nil
- }
- // admin unames
- if uNames, err = s.dao.BatchUNameByUID(c, uids); err != nil {
- log.Error("s.dao.SearchUNameByUid(%v) error(%v)", uids, err)
- err = nil
- }
- if attPaths, err = s.dao.AttPathsByCids(c, cids); err != nil {
- log.Error("s.dao.AttPathsByCids() error(%v)", err)
- return
- }
- if gidToBus, err = s.dao.BusObjectByGids(c, gids); err != nil {
- log.Error("s.dao.BusObjectByGids(%v) error(%v)", gids, err)
- return
- }
- if challLastEvent, err = s.batchLastEvent(c, cids); err != nil {
- log.Error("s.batchLastEvent(%v) error(%v)", cids, err)
- return
- }
- // user account
- users = s.dao.AccountInfoRPC(c, mids)
- // load meta
- meta = s.searchChallMeta(c, cond.Business, oids, users)
- challPage = &search.ChallListPageCommon{}
- challList := make([]*model.Chall, 0, len(challSearchResp.Result))
- for _, r := range challSearchResp.Result {
- var (
- t *model.TagMeta
- l string
- )
- cid := r.ID
- chall, ok = challs[cid]
- if !ok {
- log.Warn("Invalid challenge id %d", r.ID)
- continue
- }
- // fill tag
- if t, err = s.tag(chall.Business, chall.Tid); err != nil {
- log.Error("s.tag(%d,%d) error(%v)", chall.Business, chall.Tid, err)
- err = nil
- } else {
- chall.Tag = t.Name
- chall.Round = t.RID
- }
- // fill last log
- if l, ok = challLastLog[cid]; ok {
- chall.LastLog = l
- }
- // fill last event
- chall.LastEvent = challLastEvent[cid]
- // fill attachments
- chall.Attachments = make([]string, 0)
- if ps, ok = attPaths[cid]; ok {
- chall.Attachments = ps
- chall.FixAttachments()
- }
- chall.FormatState()
- //fill business object
- if b, ok = gidToBus[chall.Gid]; ok {
- chall.BusinessObject = b
- }
- //fill meta
- s.wrapChallMeta(cond.Business, chall, meta)
- chall.AssigneeAdminName = uNames[chall.AssigneeAdminID]
- chall.AdminName = uNames[chall.AdminID]
- if chall.Producer, ok = users[chall.Mid]; !ok {
- log.Warn("failed get producer info mid(%d)", chall.Mid)
- }
- chall.OidStr = strconv.FormatInt(chall.Oid, 10)
- challList = append(challList, chall)
- }
- challPage.Items = challList
- challPage.Page = &model.Page{
- Num: challSearchResp.Page.Num,
- Size: challSearchResp.Page.Size,
- Total: challSearchResp.Page.Total,
- }
- return
- }
- func (s *Service) searchChallMeta(c context.Context, business int8, oids []int64, users map[int64]*model.Account) (meta interface{}) {
- var (
- ok bool
- err error
- archives map[int64]*model.Archive
- )
- switch business {
- case model.ArchiveAppeal, model.ArchiveAudit:
- var (
- resp *search.AuditLogSearchCommonResult
- lastAuditLogExtraMap = make(map[int64]*search.ArchiveAuditLogExtra)
- )
- if archives, err = s.dao.ArchiveRPC(c, oids); err != nil {
- log.Error("s.dao.ArchiveInfosV3(%v) error(%v)", oids, err)
- err = nil
- return archives
- }
- cond := &search.AuditReportSearchCond{
- Business: 3,
- Fields: []string{"oid", "extra_data"},
- Order: "ctime",
- Sort: "desc",
- Oid: oids,
- Distinct: "oid",
- IndexTimeType: "month",
- IndexTimeFrom: time.Now().AddDate(0, -6, 0),
- IndexTimeEnd: time.Now(),
- }
- if resp, err = s.dao.SearchAuditReportLog(c, cond); err != nil {
- log.Error("s.dao.SearchAuditReportLog(%+v) error(%v)", cond, err)
- err = nil
- }
- for _, l := range resp.Result {
- extra := new(search.ArchiveAuditLogExtra)
- if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
- log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
- continue
- }
- lastAuditLogExtraMap[l.Oid] = extra
- }
- for _, l := range resp.Result {
- extra := new(search.ArchiveAuditLogExtra)
- if err = json.Unmarshal([]byte(l.ExtraData), extra); err != nil {
- log.Error("json.Unmarshal(%s) error(%v)", l.ExtraData, err)
- continue
- }
- }
- for oid, a := range archives {
- if a.Composer, ok = users[a.Mid]; !ok {
- log.Warn("failed get account info mid(%d)", a.Mid)
- a.Composer = &model.Account{}
- continue
- }
- var extra *search.ArchiveAuditLogExtra
- if extra, ok = lastAuditLogExtraMap[oid]; !ok {
- log.Warn("failed get audit log of archive(%d)", oid)
- continue
- } else {
- a.OPName = extra.Content.UName
- a.OPContent = extra.Diff
- a.OPRemark = extra.Content.Note
- }
- }
- }
- return
- }
- func (s *Service) wrapChallMeta(business int8, chall *model.Chall, meta interface{}) {
- switch business {
- case model.ArchiveAppeal: // 稿件申诉
- var (
- a *model.Archive
- archives map[int64]*model.Archive
- ok bool
- )
- if archives, ok = meta.(map[int64]*model.Archive); !ok {
- return
- }
- if a, ok = archives[chall.Oid]; !ok {
- log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, chall.Cid)
- chall.Meta = struct{}{}
- break
- }
- chall.Meta = a
- case model.CreditAppeal: //小黑屋
- if chall.BusinessObject == nil {
- log.Warn("can not get credit appeal info oid(%d) cid(%d) business(%d)", chall.Oid, chall.Cid, chall.Business)
- break
- }
- cMeta := &model.CreditMeta{
- Business: chall.BusinessObject,
- }
- chall.Meta = cMeta
- case model.ArchiveAudit: //稿件审核
- var (
- a *model.Archive
- archives map[int64]*model.Archive
- ok bool
- )
- if archives, ok = meta.(map[int64]*model.Archive); !ok {
- return
- }
- if a, ok = archives[chall.Oid]; !ok {
- log.Warn("failed get archive info oid(%d) cid(%d)", chall.Oid, chall.Cid)
- }
- chall.Meta = a
- }
- }
|