capsule.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. package v1
  2. import (
  3. "context"
  4. "encoding/json"
  5. "go-common/library/ecode"
  6. "regexp"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "google.golang.org/grpc/status"
  11. v1pb "go-common/app/admin/live/live-admin/api/http/v1"
  12. "go-common/app/admin/live/live-admin/conf"
  13. rspb "go-common/app/service/live/xlottery/api/grpc/v1"
  14. "go-common/library/log"
  15. )
  16. // CapsuleService struct
  17. type CapsuleService struct {
  18. conf *conf.Config
  19. // optionally add other properties here, such as dao
  20. // dao *dao.Dao
  21. capsuleCli *rspb.Client
  22. }
  23. //NewCapsuleService init
  24. func NewCapsuleService(c *conf.Config) (s *CapsuleService) {
  25. s = &CapsuleService{
  26. conf: c,
  27. }
  28. var svc *rspb.Client
  29. var err error
  30. log.Info("CapsuleService Init: %+v", s.conf.CapsuleClient)
  31. if svc, err = rspb.NewClient(s.conf.CapsuleClient); err != nil {
  32. panic(err)
  33. }
  34. s.capsuleCli = svc
  35. return s
  36. }
  37. // GetCoinList implementation
  38. func (s *CapsuleService) GetCoinList(ctx context.Context, req *v1pb.GetCoinListReqAdmin) (resp *v1pb.GetCoinListRespAdmin, err error) {
  39. var RPCResponse *rspb.GetCoinListResp
  40. RPCReq := &rspb.GetCoinListReq{
  41. Page: req.Page,
  42. PageSize: req.PageSize,
  43. }
  44. if RPCReq.Page < 1 {
  45. RPCReq.Page = 1
  46. }
  47. if RPCReq.PageSize < 1 {
  48. RPCReq.PageSize = 16
  49. }
  50. RPCResponse, err = s.capsuleCli.GetCoinList(ctx, RPCReq)
  51. if err != nil {
  52. return
  53. }
  54. coinListResp := make([]*v1pb.GetCoinListRespAdmin_List, 0)
  55. for _, singleCoinList := range RPCResponse.List {
  56. coinList := &v1pb.GetCoinListRespAdmin_List{}
  57. coinList.Id = singleCoinList.Id
  58. coinList.Status = singleCoinList.Status
  59. coinList.Title = singleCoinList.Title
  60. coinList.GiftConfig = singleCoinList.GiftConfig
  61. coinList.GiftType = singleCoinList.GiftType
  62. coinList.ChangeNum = singleCoinList.ChangeNum
  63. startTimeUnix := time.Unix(singleCoinList.StartTime, 0)
  64. coinList.StartTime = startTimeUnix.Format("2006-01-02 15:04:05")
  65. endTimeUnix := time.Unix(singleCoinList.EndTime, 0)
  66. coinList.EndTime = endTimeUnix.Format("2006-01-02 15:04:05")
  67. areaIds := make([]*v1pb.GetCoinListRespAdmin_List_AreaIds, 0)
  68. for _, areaId := range singleCoinList.AreaIds {
  69. singleAreaId := &v1pb.GetCoinListRespAdmin_List_AreaIds{}
  70. singleAreaId.IsAll = areaId.IsAll
  71. singleAreaId.List = areaId.List
  72. singleAreaId.ParentId = areaId.ParentId
  73. areaIds = append(areaIds, singleAreaId)
  74. }
  75. coinList.AreaIds = areaIds
  76. coinListResp = append(coinListResp, coinList)
  77. }
  78. resp = &v1pb.GetCoinListRespAdmin{
  79. Total: RPCResponse.Total,
  80. TotalPage: RPCResponse.TotalPage,
  81. List: coinListResp,
  82. }
  83. return
  84. }
  85. // UpdateCoinConfig implementation
  86. func (s *CapsuleService) UpdateCoinConfig(ctx context.Context, req *v1pb.UpdateCoinConfigReqAdmin) (resp *v1pb.UpdateCoinConfigRespAdmin, err error) {
  87. var RPCResponse *rspb.UpdateCoinConfigResp
  88. loc, _ := time.LoadLocation("Local")
  89. var endTime, startTime time.Time
  90. startTime, err = time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, loc)
  91. if err != nil {
  92. err = ecode.Error(ecode.InvalidParam, "参数错误")
  93. return nil, err
  94. }
  95. endTime, err = time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, loc)
  96. if err != nil {
  97. err = ecode.Error(ecode.InvalidParam, "参数错误")
  98. return nil, err
  99. }
  100. var areaIds []*rspb.UpdateCoinConfigReq_AreaIds
  101. err = json.Unmarshal([]byte(req.AreaIds), &areaIds)
  102. if err != nil {
  103. err = ecode.Error(ecode.InvalidParam, "参数错误")
  104. return nil, err
  105. }
  106. if len(areaIds) == 0 {
  107. err = ecode.Error(ecode.InvalidParam, "参数错误")
  108. return nil, err
  109. }
  110. var isHasArea bool
  111. for _, areaInfo := range areaIds {
  112. if areaInfo.IsAll == 1 {
  113. isHasArea = true
  114. break
  115. }
  116. if len(areaInfo.List) > 0 {
  117. isHasArea = true
  118. break
  119. }
  120. }
  121. if !isHasArea {
  122. err = ecode.Error(ecode.XLotteryCapsuleAreaParamErr, "必须设置生效分区")
  123. return nil, err
  124. }
  125. var giftIds = make([]int64, 0)
  126. if req.GiftType == 3 {
  127. if req.GiftConfig == "" {
  128. err = ecode.Error(ecode.InvalidParam, "参数错误")
  129. return nil, err
  130. }
  131. giftConfig := strings.Split(req.GiftConfig, ",")
  132. for _, giftStr := range giftConfig {
  133. var giftId int64
  134. giftId, err = strconv.ParseInt(giftStr, 10, 64)
  135. if err != nil {
  136. err = ecode.Error(ecode.InvalidParam, "参数错误")
  137. return nil, err
  138. }
  139. giftIds = append(giftIds, giftId)
  140. }
  141. if len(giftIds) == 0 {
  142. err = ecode.Error(ecode.InvalidParam, "参数错误")
  143. return nil, err
  144. }
  145. match, _ := regexp.Compile("^([0-9]+,)*[0-9]+$")
  146. if !match.MatchString(req.GiftConfig) {
  147. err = ecode.Error(ecode.InvalidParam, "参数错误")
  148. return nil, err
  149. }
  150. }
  151. RPCReq := &rspb.UpdateCoinConfigReq{
  152. Id: req.Id,
  153. Title: req.Title,
  154. ChangeNum: req.ChangeNum,
  155. StartTime: startTime.Unix(),
  156. EndTime: endTime.Unix(),
  157. Status: req.Status,
  158. GiftType: req.GiftType,
  159. GiftIds: giftIds,
  160. AreaIds: areaIds,
  161. }
  162. RPCResponse, err = s.capsuleCli.UpdateCoinConfig(ctx, RPCReq)
  163. if err != nil {
  164. return
  165. }
  166. resp = &v1pb.UpdateCoinConfigRespAdmin{
  167. Status: RPCResponse.Status,
  168. }
  169. return
  170. }
  171. // UpdateCoinStatus implementation
  172. func (s *CapsuleService) UpdateCoinStatus(ctx context.Context, req *v1pb.UpdateCoinStatusReqAdmin) (resp *v1pb.UpdateCoinStatusRespAdmin, err error) {
  173. var RPCResponse *rspb.UpdateCoinStatusResp
  174. RPCReq := &rspb.UpdateCoinStatusReq{
  175. Id: req.Id,
  176. Status: req.Status,
  177. }
  178. if RPCReq.Status != 1 {
  179. RPCReq.Status = 0
  180. }
  181. RPCResponse, err = s.capsuleCli.UpdateCoinStatus(ctx, RPCReq)
  182. if err != nil {
  183. return
  184. }
  185. resp = &v1pb.UpdateCoinStatusRespAdmin{
  186. Status: RPCResponse.Status,
  187. }
  188. return
  189. }
  190. // DeleteCoin implementation
  191. func (s *CapsuleService) DeleteCoin(ctx context.Context, req *v1pb.DeleteCoinReqAdmin) (resp *v1pb.DeleteCoinRespAdmin, err error) {
  192. var RPCResponse *rspb.DeleteCoinResp
  193. RPCReq := &rspb.DeleteCoinReq{
  194. Id: req.Id,
  195. }
  196. RPCResponse, err = s.capsuleCli.DeleteCoin(ctx, RPCReq)
  197. if err != nil {
  198. return
  199. }
  200. resp = &v1pb.DeleteCoinRespAdmin{
  201. Status: RPCResponse.Status,
  202. }
  203. return
  204. }
  205. // GetPoolList implementation
  206. // `internal:"true"`
  207. func (s *CapsuleService) GetPoolList(ctx context.Context, req *v1pb.GetPoolListReqAdmin) (resp *v1pb.GetPoolListRespAdmin, err error) {
  208. var RPCResponse *rspb.GetPoolListResp
  209. RPCReq := &rspb.GetPoolListReq{
  210. Page: req.Page,
  211. PageSize: req.PageSize,
  212. }
  213. if RPCReq.Page < 1 {
  214. RPCReq.Page = 1
  215. }
  216. if RPCReq.PageSize < 1 {
  217. RPCReq.PageSize = 16
  218. }
  219. RPCResponse, err = s.capsuleCli.GetPoolList(ctx, RPCReq)
  220. if err != nil {
  221. return
  222. }
  223. poolList := make([]*v1pb.GetPoolListRespAdmin_List, 0)
  224. for _, singleList := range RPCResponse.List {
  225. poolInfo := &v1pb.GetPoolListRespAdmin_List{}
  226. poolInfo.Id = singleList.Id
  227. startTimeUnix := time.Unix(singleList.StartTime, 0)
  228. poolInfo.StartTime = startTimeUnix.Format("2006-01-02 15:04:05")
  229. endTimeUnix := time.Unix(singleList.EndTime, 0)
  230. poolInfo.EndTime = endTimeUnix.Format("2006-01-02 15:04:05")
  231. poolInfo.Title = singleList.Title
  232. poolInfo.CoinTitle = singleList.CoinTitle
  233. poolInfo.Status = singleList.Status
  234. poolInfo.Rule = singleList.Rule
  235. poolInfo.CoinId = singleList.CoinId
  236. poolList = append(poolList, poolInfo)
  237. }
  238. resp = &v1pb.GetPoolListRespAdmin{
  239. Total: RPCResponse.Total,
  240. TotalPage: RPCResponse.TotalPage,
  241. List: poolList,
  242. }
  243. return
  244. }
  245. // UpdatePool implementation
  246. // `method:"POST" internal:"true"`
  247. func (s *CapsuleService) UpdatePool(ctx context.Context, req *v1pb.UpdatePoolReqAdmin) (resp *v1pb.UpdatePoolRespAdmin, err error) {
  248. var RPCResponse *rspb.UpdatePoolResp
  249. loc, _ := time.LoadLocation("Local")
  250. startTime, err := time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, loc)
  251. if err != nil {
  252. err = ecode.Error(ecode.InvalidParam, "参数错误")
  253. return nil, err
  254. }
  255. endTime, err := time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, loc)
  256. if err != nil {
  257. err = ecode.Error(ecode.InvalidParam, "参数错误")
  258. return nil, err
  259. }
  260. RPCReq := &rspb.UpdatePoolReq{
  261. Id: req.Id,
  262. CoinId: req.CoinId,
  263. Title: req.Title,
  264. StartTime: startTime.Unix(),
  265. EndTime: endTime.Unix(),
  266. Rule: req.Rule,
  267. }
  268. RPCResponse, err = s.capsuleCli.UpdatePool(ctx, RPCReq)
  269. if err != nil {
  270. return
  271. }
  272. resp = &v1pb.UpdatePoolRespAdmin{
  273. Status: RPCResponse.Status,
  274. }
  275. return
  276. }
  277. // DeletePool implementation
  278. func (s *CapsuleService) DeletePool(ctx context.Context, req *v1pb.DeletePoolReqAdmin) (resp *v1pb.DeletePoolRespAdmin, err error) {
  279. var RPCResponse *rspb.DeletePoolResp
  280. RPCReq := &rspb.DeletePoolReq{
  281. Id: req.Id,
  282. }
  283. RPCResponse, err = s.capsuleCli.DeletePool(ctx, RPCReq)
  284. if err != nil {
  285. return
  286. }
  287. resp = &v1pb.DeletePoolRespAdmin{
  288. Status: RPCResponse.Status,
  289. }
  290. return
  291. }
  292. // UpdatePoolStatus implementation
  293. func (s *CapsuleService) UpdatePoolStatus(ctx context.Context, req *v1pb.UpdatePoolStatusReqAdmin) (resp *v1pb.UpdatePoolStatusRespAdmin, err error) {
  294. resp = &v1pb.UpdatePoolStatusRespAdmin{}
  295. data, err := s.capsuleCli.UpdatePoolStatus(ctx, &rspb.UpdatePoolStatusReq{Id: req.Id, Status: req.Status})
  296. if err != nil {
  297. return
  298. }
  299. resp.Status = data.Status
  300. return
  301. }
  302. // GetPoolPrize implementation
  303. // `internal:"true"`
  304. func (s *CapsuleService) GetPoolPrize(ctx context.Context, req *v1pb.GetPoolPrizeReqAdmin) (resp *v1pb.GetPoolPrizeRespAdmin, err error) {
  305. var RPCResponse *rspb.GetPoolPrizeResp
  306. RPCReq := &rspb.GetPoolPrizeReq{
  307. PoolId: req.PoolId,
  308. }
  309. RPCResponse, err = s.capsuleCli.GetPoolPrize(ctx, RPCReq)
  310. if err != nil {
  311. return
  312. }
  313. list := make([]*v1pb.GetPoolPrizeRespAdmin_List, 0)
  314. for _, poolDetail := range RPCResponse.List {
  315. singleDetail := &v1pb.GetPoolPrizeRespAdmin_List{}
  316. singleDetail.Id = poolDetail.Id
  317. singleDetail.Limit = poolDetail.Limit
  318. singleDetail.Loop = poolDetail.Loop
  319. singleDetail.Chance = poolDetail.Chance
  320. singleDetail.ProType = poolDetail.ProType
  321. singleDetail.JumpUrl = poolDetail.JumpUrl
  322. singleDetail.Description = poolDetail.Description
  323. singleDetail.MobileUrl = poolDetail.MobileUrl
  324. singleDetail.WebUrl = poolDetail.WebUrl
  325. singleDetail.Num = poolDetail.Num
  326. singleDetail.Type = poolDetail.Type
  327. singleDetail.ObjectId = poolDetail.ObjectId
  328. singleDetail.Expire = poolDetail.Expire
  329. singleDetail.PoolId = poolDetail.PoolId
  330. singleDetail.Name = poolDetail.Name
  331. singleDetail.Weight = poolDetail.Weight
  332. singleDetail.WhiteUids = ""
  333. wlen := len(poolDetail.WhiteUids)
  334. if wlen > 0 {
  335. wUids := make([]string, wlen)
  336. for ix, uid := range poolDetail.WhiteUids {
  337. wUids[ix] = strconv.FormatInt(uid, 10)
  338. }
  339. singleDetail.WhiteUids = strings.Join(wUids, ",")
  340. }
  341. list = append(list, singleDetail)
  342. }
  343. resp = &v1pb.GetPoolPrizeRespAdmin{
  344. List: list,
  345. }
  346. return
  347. }
  348. // UpdatePoolPrize implementation
  349. // `method:"POST" internal:"true"`
  350. func (s *CapsuleService) UpdatePoolPrize(ctx context.Context, req *v1pb.UpdatePoolPrizeReqAdmin) (resp *v1pb.UpdatePoolPrizeRespAdmin, err error) {
  351. chance, err := strconv.ParseFloat(req.Chance, 64)
  352. if err != nil || chance > 1 {
  353. err = ecode.Error(ecode.InvalidParam, "参数错误")
  354. return
  355. }
  356. chance = chance*10000 + 0.5
  357. whiteUids := make([]int64, 0)
  358. if req.ProType == 1 {
  359. if chance < 1 {
  360. err = ecode.Error(ecode.InvalidParam, "参数错误")
  361. return
  362. }
  363. req.Loop = 0
  364. req.Limit = 0
  365. } else if req.ProType == 2 {
  366. chance = 0
  367. if req.Loop < 1 || req.Limit < 1 {
  368. err = ecode.Error(ecode.InvalidParam, "参数错误")
  369. return
  370. }
  371. } else if req.ProType == 3 {
  372. chance = 0
  373. if req.Loop < 1 || req.Limit < 1 {
  374. err = ecode.Error(ecode.InvalidParam, "参数错误")
  375. return
  376. }
  377. } else if req.ProType == 4 {
  378. chance = 0
  379. req.Loop = 0
  380. req.Limit = 0
  381. if req.WhiteUids == "" {
  382. err = ecode.Error(ecode.InvalidParam, "参数错误")
  383. return
  384. }
  385. wUids := strings.Split(req.WhiteUids, ",")
  386. for _, uidStr := range wUids {
  387. var uid int64
  388. uid, err = strconv.ParseInt(uidStr, 10, 64)
  389. if err != nil {
  390. err = ecode.Error(ecode.InvalidParam, "参数错误")
  391. return nil, err
  392. }
  393. whiteUids = append(whiteUids, uid)
  394. }
  395. wlen := len(whiteUids)
  396. if wlen == 0 || wlen > 1000 {
  397. err = ecode.Error(ecode.InvalidParam, "参数错误")
  398. return nil, err
  399. }
  400. } else {
  401. err = ecode.Error(ecode.InvalidParam, "参数错误")
  402. return
  403. }
  404. var RPCResponse *rspb.UpdatePoolPrizeResp
  405. RPCReq := &rspb.UpdatePoolPrizeReq{
  406. Id: req.Id,
  407. PoolId: req.PoolId,
  408. Type: req.Type,
  409. Num: req.Num,
  410. ObjectId: req.ObjectId,
  411. Expire: req.Expire,
  412. WebUrl: req.WebUrl,
  413. MobileUrl: req.MobileUrl,
  414. Description: req.Description,
  415. JumpUrl: req.JumpUrl,
  416. ProType: req.ProType,
  417. Chance: int64(chance),
  418. Loop: req.Loop,
  419. Limit: req.Limit,
  420. Weight: req.Weight,
  421. WhiteUids: whiteUids,
  422. }
  423. RPCResponse, err = s.capsuleCli.UpdatePoolPrize(ctx, RPCReq)
  424. if err != nil {
  425. return
  426. }
  427. resp = &v1pb.UpdatePoolPrizeRespAdmin{
  428. Status: RPCResponse.Status,
  429. PrizeId: RPCResponse.PrizeId,
  430. }
  431. return
  432. }
  433. // DeletePoolPrize implementation
  434. // `method:"POST" internal:"true" `
  435. func (s *CapsuleService) DeletePoolPrize(ctx context.Context, req *v1pb.DeletePoolPrizeReqAdmin) (resp *v1pb.DeletePoolPrizeRespAdmin, err error) {
  436. var RPCResponse *rspb.DeletePoolPrizeResp
  437. RPCReq := &rspb.DeletePoolPrizeReq{
  438. Id: req.Id,
  439. }
  440. RPCResponse, err = s.capsuleCli.DeletePoolPrize(ctx, RPCReq)
  441. if err != nil {
  442. return
  443. }
  444. resp = &v1pb.DeletePoolPrizeRespAdmin{
  445. Status: RPCResponse.Status,
  446. }
  447. return
  448. }
  449. // GetPrizeType implementation
  450. // `internal:"true"`
  451. func (s *CapsuleService) GetPrizeType(ctx context.Context, req *v1pb.GetPrizeTypeReq) (resp *v1pb.GetPrizeTypeResp, err error) {
  452. resp = &v1pb.GetPrizeTypeResp{}
  453. prizeType, err := s.capsuleCli.GetPrizeType(ctx, &rspb.GetPrizeTypeReq{})
  454. if err != nil || prizeType == nil {
  455. return
  456. }
  457. resp.List = make([]*v1pb.GetPrizeTypeResp_List, len(prizeType.List))
  458. for ix, data := range prizeType.List {
  459. resp.List[ix] = &v1pb.GetPrizeTypeResp_List{Type: data.Type, Name: data.Name}
  460. }
  461. return
  462. }
  463. // GetPrizeExpire implementation
  464. // `internal:"true"`
  465. func (s *CapsuleService) GetPrizeExpire(ctx context.Context, req *v1pb.GetPrizeExpireReq) (resp *v1pb.GetPrizeExpireResp, err error) {
  466. resp = &v1pb.GetPrizeExpireResp{}
  467. prizeExpire, err := s.capsuleCli.GetPrizeExpire(ctx, &rspb.GetPrizeExpireReq{})
  468. if err != nil || prizeExpire == nil {
  469. return
  470. }
  471. resp.List = make([]*v1pb.GetPrizeExpireResp_List, len(prizeExpire.List))
  472. for ix, data := range prizeExpire.List {
  473. resp.List[ix] = &v1pb.GetPrizeExpireResp_List{Expire: data.Expire, Name: data.Name}
  474. }
  475. return
  476. }
  477. // FormatErr format error msg
  478. func (s *CapsuleService) FormatErr(statusCode *status.Status) (code int32, msg string) {
  479. gCode := statusCode.Code()
  480. code = 1
  481. if gCode == 2 {
  482. code, _ := strconv.Atoi(statusCode.Message())
  483. switch code {
  484. case -400:
  485. msg = "参数错误"
  486. case -401:
  487. msg = "上线失败,概率设置不为1"
  488. case -402:
  489. msg = "保底奖池的上下线时间不可修改"
  490. case -403:
  491. msg = "保底奖池不可下线"
  492. case -404:
  493. msg = "普通扭蛋币不可更改道具类型"
  494. case -500:
  495. msg = "内部错误"
  496. default:
  497. msg = "内部错误"
  498. }
  499. } else {
  500. msg = "内部错误"
  501. }
  502. return
  503. }
  504. // GetCouponList implementation
  505. // `internal:"true"`
  506. func (s *CapsuleService) GetCouponList(ctx context.Context, req *v1pb.CapsuleGetCouponListReq) (resp *v1pb.CapsuleGetCouponListResp, err error) {
  507. resp = &v1pb.CapsuleGetCouponListResp{}
  508. couponList, err := s.capsuleCli.GetCouponList(ctx, &rspb.CapsuleGetCouponListReq{Uid: req.Uid})
  509. if err != nil || couponList == nil {
  510. return
  511. }
  512. resp.List = make([]*v1pb.CapsuleGetCouponListResp_List, len(couponList.List))
  513. for ix, conpon := range couponList.List {
  514. resp.List[ix] = &v1pb.CapsuleGetCouponListResp_List{}
  515. resp.List[ix].Uid = req.Uid
  516. resp.List[ix].Status = conpon.Status
  517. resp.List[ix].AwardTime = conpon.AwardTime
  518. resp.List[ix].RetryTime = conpon.RetryTime
  519. resp.List[ix].AwardName = conpon.AwardName
  520. resp.List[ix].AwardCode = conpon.AwardCode
  521. }
  522. return
  523. }