subtitle.go 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "time"
  7. "go-common/app/admin/main/dm/model"
  8. accountApi "go-common/app/service/main/account/api"
  9. "go-common/app/service/main/archive/api"
  10. archiveMdl "go-common/app/service/main/archive/model/archive"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. "go-common/library/sync/errgroup"
  14. )
  15. const (
  16. _workFlowSubtitleBid = 14
  17. )
  18. // SubtitleLanList .
  19. func (s *Service) SubtitleLanList(c context.Context) (res map[int64]string, err error) {
  20. var (
  21. sLans []*model.SubtitleLan
  22. )
  23. if sLans, err = s.dao.SubtitleLans(c); err != nil {
  24. return
  25. }
  26. res = make(map[int64]string)
  27. for _, sLan := range sLans {
  28. res[sLan.Code] = sLan.DocZh
  29. }
  30. return
  31. }
  32. // WorkFlowEditSubtitle .
  33. func (s *Service) WorkFlowEditSubtitle(c context.Context, arg *model.WorkFlowSubtitleArg) (err error) {
  34. var (
  35. argEdit *model.EditSubtitleArg
  36. status model.SubtitleStatus
  37. )
  38. if arg == nil || arg.Object == nil || len(arg.Object.Ids) == 0 || len(arg.Targets) == 0 {
  39. err = ecode.RequestErr
  40. return
  41. }
  42. switch arg.Object.DisposeMode {
  43. case model.WorkFlowSubtitleDisposeManagerBack:
  44. status = model.SubtitleStatusManagerBack
  45. case model.WorkFlowSubtitleDisposeManagerDelete:
  46. status = model.SubtitleStatusManagerRemove
  47. default:
  48. return
  49. }
  50. for _, target := range arg.Targets {
  51. if target == nil {
  52. continue
  53. }
  54. argEdit = &model.EditSubtitleArg{
  55. Oid: target.Oid,
  56. SubtileID: target.Eid,
  57. Status: uint8(status),
  58. }
  59. // 容错
  60. if argEdit.Oid == 0 {
  61. continue
  62. }
  63. if err = s.editSubtitle(c, argEdit, false); err != nil {
  64. log.Error("s.EditSubtitle(arg:%+v),error(%v)", argEdit, err)
  65. err = nil // ignore error
  66. return
  67. }
  68. }
  69. return
  70. }
  71. // EditSubtitle .
  72. func (s *Service) EditSubtitle(c context.Context, arg *model.EditSubtitleArg) (err error) {
  73. return s.editSubtitle(c, arg, true)
  74. }
  75. func (s *Service) editSubtitle(c context.Context, arg *model.EditSubtitleArg, removeWorkFlow bool) (err error) {
  76. // 更新表
  77. var (
  78. subtitle *model.Subtitle
  79. argStatus = model.SubtitleStatus(arg.Status)
  80. subtitleLans model.SubtitleLans
  81. sLans []*model.SubtitleLan
  82. err1 error
  83. lanDoc string
  84. archiveInfo *api.Arc
  85. archiveName string
  86. )
  87. if subtitle, err = s.dao.GetSubtitle(c, arg.Oid, arg.SubtileID); err != nil {
  88. log.Error("params(oid:%v,subtitleID:%v),error(%v)", arg.Oid, arg.SubtileID, err)
  89. return
  90. }
  91. if subtitle == nil {
  92. err = ecode.NothingFound
  93. return
  94. }
  95. if argStatus == subtitle.Status {
  96. err = ecode.SubtitleStatusUnValid
  97. return
  98. }
  99. if subtitle.Status != model.SubtitleStatusPublish && argStatus != model.SubtitleStatusPublish {
  100. arg.NotifyUpper = false
  101. }
  102. switch argStatus {
  103. case model.SubtitleStatusDraft, model.SubtitleStatusToAudit,
  104. model.SubtitleStatusAuditBack, model.SubtitleStatusRemove,
  105. model.SubtitleStatusPublish, model.SubtitleStatusManagerBack,
  106. model.SubtitleStatusManagerRemove:
  107. default:
  108. err = ecode.SubtitleStatusUnValid
  109. return
  110. }
  111. if err = s.changeSubtitleStatus(c, subtitle, argStatus); err != nil {
  112. log.Error("params(subtitle:%+v,status:%v),error(%v)", subtitle, arg.Status, err)
  113. return
  114. }
  115. if arg.NotifyAuthor || arg.NotifyUpper {
  116. if sLans, err1 = s.dao.SubtitleLans(c); err1 == nil {
  117. subtitleLans = model.SubtitleLans(sLans)
  118. }
  119. _, lanDoc = subtitleLans.GetByID(int64(subtitle.Lan))
  120. if archiveInfo, err1 = s.arcRPC.Archive3(c, &archiveMdl.ArgAid2{
  121. Aid: subtitle.Aid,
  122. }); err1 != nil {
  123. log.Error("s.arcRPC.Archive3(aid:%v),error(%v)", subtitle.Aid, err1)
  124. err1 = nil
  125. } else {
  126. archiveName = archiveInfo.Title
  127. }
  128. }
  129. if arg.NotifyAuthor {
  130. argUser := &model.NotifySubtitleUser{
  131. Mid: subtitle.Mid,
  132. Aid: subtitle.Aid,
  133. Oid: subtitle.Oid,
  134. SubtitleID: subtitle.ID,
  135. ArchiveName: archiveName,
  136. LanDoc: lanDoc,
  137. Status: model.StatusContent[uint8(subtitle.Status)],
  138. }
  139. if err1 = s.dao.SendMsgToSubtitleUser(c, argUser); err1 != nil {
  140. log.Error("SendMsgToSubtitleUser(argUser:%+v),error(%v)", argUser, err1)
  141. err1 = nil
  142. }
  143. }
  144. if arg.NotifyUpper {
  145. var (
  146. accountInfo *accountApi.InfoReply
  147. authorName string
  148. )
  149. if accountInfo, err1 = s.accountRPC.Info3(c, &accountApi.MidReq{
  150. Mid: subtitle.Mid,
  151. }); err1 != nil {
  152. log.Error("s.accRPC.Info3(mid:%v),error(%v)", subtitle.Mid, err1)
  153. err1 = nil
  154. } else {
  155. authorName = accountInfo.GetInfo().GetName()
  156. }
  157. argUp := &model.NotifySubtitleUp{
  158. Mid: subtitle.UpMid,
  159. AuthorID: subtitle.Mid,
  160. AuthorName: authorName,
  161. Aid: subtitle.Aid,
  162. Oid: subtitle.Oid,
  163. SubtitleID: subtitle.ID,
  164. ArchiveName: archiveName,
  165. LanDoc: lanDoc,
  166. Status: model.StatusContent[uint8(subtitle.Status)],
  167. }
  168. if err1 = s.dao.SendMsgToSubtitleUp(c, argUp); err1 != nil {
  169. log.Error("SendMsgToSubtitleUp(argUp:%+v),error(%v)", argUp, err1)
  170. err1 = nil
  171. }
  172. }
  173. if removeWorkFlow && (argStatus == model.SubtitleStatusRemove || argStatus == model.SubtitleStatusManagerRemove) {
  174. if err1 := s.dao.WorkFlowAppealDelete(c, _workFlowSubtitleBid, subtitle.Oid, subtitle.ID); err1 != nil {
  175. log.Error("s.dao.WorkFlowAppealDelete(oid:%v,subtitleID:%v),error(%v)", subtitle.Oid, subtitle.ID, err1)
  176. return
  177. }
  178. }
  179. return
  180. }
  181. // TODO 确认状态扭转
  182. func (s *Service) changeSubtitleStatus(c context.Context, subtitle *model.Subtitle, status model.SubtitleStatus) (err error) {
  183. var (
  184. sc *model.SubtitleContext
  185. hasDraft bool
  186. )
  187. sc = &model.SubtitleContext{}
  188. sc.Build(subtitle.Status, status)
  189. subtitle.PubTime = time.Now().Unix()
  190. if sc.CheckHasDraft {
  191. if hasDraft, err = s.CheckHasDraft(c, subtitle); err != nil {
  192. log.Error("params(subtitle:%+v),error(%v)", subtitle, err)
  193. return
  194. }
  195. if hasDraft {
  196. err = ecode.SubtitleAlreadyHasDraft
  197. return
  198. }
  199. subtitle.PubTime = 0
  200. }
  201. subtitle.Status = status
  202. if sc.RebuildPub {
  203. if err = s.RebuildSubtitle(c, subtitle); err != nil {
  204. log.Error("RebuildSubtitle.params(subtitle:%+v),error(%v)", subtitle, err)
  205. return
  206. }
  207. } else {
  208. if err = s.dao.UpdateSubtitle(c, subtitle); err != nil {
  209. log.Error("UpdateSubtitle.params(subtitle:%+v),error(%v)", subtitle, err)
  210. return
  211. }
  212. }
  213. if sc.DraftCache {
  214. s.dao.DelSubtitleDraftCache(c, subtitle.Oid, subtitle.Type, subtitle.Mid, subtitle.Lan)
  215. }
  216. if sc.SubtitleCache {
  217. s.dao.DelSubtitleCache(c, subtitle.Oid, subtitle.ID)
  218. }
  219. if sc.RebuildPub {
  220. s.dao.DelVideoSubtitleCache(c, subtitle.Oid, subtitle.Type)
  221. }
  222. return
  223. }
  224. // SubtitleList .
  225. func (s *Service) SubtitleList(c context.Context, arg *model.SubtitleArg) (res *model.SubtitleList, err error) {
  226. var (
  227. searchResult *model.SearchSubtitleResult
  228. oidSubtitleIds map[int64][]int64
  229. eg errgroup.Group
  230. lock sync.Mutex
  231. subtitleMap map[string]*model.Subtitle
  232. searchSubtitles []*model.SearchSubtitle
  233. searchSubtitle *model.SearchSubtitle
  234. subtitle *model.Subtitle
  235. ok bool
  236. aids []int64
  237. aidMap map[int64]struct{}
  238. archives map[int64]*api.Arc
  239. archive *api.Arc
  240. archiveVideo *api.Page
  241. subtitleLans model.SubtitleLans
  242. searchArg *model.SubtitleSearchArg
  243. )
  244. if arg.Ps > 100 {
  245. err = ecode.RequestErr
  246. return
  247. }
  248. key := func(oid, subtitleID int64) string {
  249. return fmt.Sprintf("%d_%d", oid, subtitleID)
  250. }
  251. if sLans, err1 := s.dao.SubtitleLans(c); err1 == nil {
  252. subtitleLans = model.SubtitleLans(sLans)
  253. }
  254. lanCode := subtitleLans.GetByLan(arg.Lan)
  255. searchArg = &model.SubtitleSearchArg{
  256. Aid: arg.Aid,
  257. Oid: arg.Oid,
  258. Mid: arg.Mid,
  259. UpperMid: arg.UpperMid,
  260. Status: arg.Status,
  261. Lan: uint8(lanCode),
  262. Ps: arg.Ps,
  263. Pn: arg.Pn,
  264. }
  265. if searchResult, err = s.dao.SearchSubtitle(c, searchArg); err != nil {
  266. log.Error("params(arg:%+v).error(%v)", arg, err)
  267. return
  268. }
  269. if searchResult == nil || len(searchResult.Result) == 0 {
  270. err = ecode.NothingFound
  271. return
  272. }
  273. oidSubtitleIds = make(map[int64][]int64)
  274. subtitleMap = make(map[string]*model.Subtitle)
  275. aidMap = make(map[int64]struct{})
  276. for _, r := range searchResult.Result {
  277. oidSubtitleIds[r.Oid] = append(oidSubtitleIds[r.Oid], r.ID)
  278. }
  279. for oid, subtitleIds := range oidSubtitleIds {
  280. tempOid := oid
  281. tempSubtitleIds := subtitleIds
  282. eg.Go(func() (err error) {
  283. var subtitles []*model.Subtitle
  284. if subtitles, err = s.dao.GetSubtitles(context.Background(), tempOid, tempSubtitleIds); err != nil {
  285. log.Error("params(oid:%v,subtitleIds:%+v).error(%v)", tempOid, tempSubtitleIds, err)
  286. return
  287. }
  288. for _, subtitle := range subtitles {
  289. lock.Lock()
  290. aidMap[subtitle.Aid] = struct{}{}
  291. subtitleMap[key(subtitle.Oid, subtitle.ID)] = subtitle
  292. lock.Unlock()
  293. }
  294. return
  295. })
  296. }
  297. if err = eg.Wait(); err != nil {
  298. return
  299. }
  300. for aid := range aidMap {
  301. aids = append(aids, aid)
  302. }
  303. if archives, err = s.arcRPC.Archives3(c, &archiveMdl.ArgAids2{
  304. Aids: aids,
  305. }); err != nil {
  306. log.Error("prams(aid:%v),error(%v)", aids, err)
  307. archives = make(map[int64]*api.Arc)
  308. err = nil
  309. }
  310. searchSubtitles = make([]*model.SearchSubtitle, 0, len(searchResult.Result))
  311. for _, r := range searchResult.Result {
  312. if subtitle, ok = subtitleMap[key(r.Oid, r.ID)]; !ok {
  313. continue
  314. }
  315. lan, lanDoc := subtitleLans.GetByID(int64(subtitle.Lan))
  316. searchSubtitle = &model.SearchSubtitle{
  317. ID: subtitle.ID,
  318. Oid: subtitle.Oid,
  319. Aid: subtitle.Aid,
  320. AuthorID: subtitle.Mid,
  321. Status: uint8(subtitle.Status),
  322. Lan: lan,
  323. LanDoc: lanDoc,
  324. IsSign: subtitle.IsSign,
  325. IsLock: subtitle.IsLock,
  326. Mtime: subtitle.Mtime,
  327. SubtitleURL: subtitle.SubtitleURL,
  328. }
  329. if archive, ok = archives[subtitle.Aid]; ok {
  330. searchSubtitle.ArchiveName = archive.Title
  331. }
  332. if archiveVideo, err = s.arcRPC.Video3(c, &archiveMdl.ArgVideo2{
  333. Aid: subtitle.Aid,
  334. Cid: subtitle.Oid,
  335. }); err != nil {
  336. log.Error("params(aid:%v,oid:%v) error(%v)", subtitle.Aid, subtitle.Oid, err)
  337. err = nil
  338. } else {
  339. searchSubtitle.VideoName = archiveVideo.Part
  340. }
  341. searchSubtitles = append(searchSubtitles, searchSubtitle)
  342. }
  343. res = &model.SubtitleList{
  344. Page: searchResult.Page,
  345. }
  346. res.Subtitles = searchSubtitles
  347. return
  348. }