蛋蛋星球 后台端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

566 lines
18 KiB

  1. package financial_center
  2. import (
  3. "applet/app/cfg"
  4. "applet/app/db"
  5. "applet/app/e"
  6. md "applet/app/md/financial_center"
  7. svc "applet/app/svc/financial_center"
  8. "applet/app/utils"
  9. "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
  10. "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
  11. "code.fnuoos.com/EggPlanet/egg_system_rules.git"
  12. "code.fnuoos.com/EggPlanet/egg_system_rules.git/enum"
  13. md3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/md"
  14. "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule"
  15. md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md"
  16. "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit"
  17. "errors"
  18. "github.com/gin-gonic/gin"
  19. "github.com/jinzhu/copier"
  20. "github.com/tidwall/gjson"
  21. "strings"
  22. "time"
  23. )
  24. // GetWithdrawSetting
  25. // @Summary 财务中心-提现-基础设置(获取)
  26. // @Tags 提现
  27. // @Description 基础设置(获取)
  28. // @Accept json
  29. // @Produce json
  30. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  31. // @Success 200 {object} md.GetWithdrawSettingResp "具体数据"
  32. // @Failure 400 {object} md.Response "具体错误"
  33. // @Router /api/financialCenter/withdraw/setting [get]
  34. func GetWithdrawSetting(c *gin.Context) {
  35. // 等级列表
  36. levelDb := implement.NewUserLevelDb(db.Db)
  37. levels, err1 := levelDb.UserLevelAllByAsc()
  38. if err1 != nil {
  39. e.OutErr(c, e.ERR_DB_ORM, err1.Error())
  40. return
  41. }
  42. levelsList := make([]map[string]interface{}, 0)
  43. levelsMap := make(map[int]string)
  44. for _, level := range levels {
  45. levelsList = append(levelsList, map[string]interface{}{
  46. "id": level.Id,
  47. "name": level.LevelName,
  48. })
  49. levelsMap[level.Id] = level.LevelName
  50. }
  51. settingDb := implement.NewFinWithdrawSettingDb(db.Db)
  52. setting, err := settingDb.FinWithdrawSettingGetOne()
  53. if err != nil {
  54. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  55. return
  56. }
  57. // 不存在则初始化
  58. var emptyNum []string
  59. if setting == nil {
  60. now := time.Now()
  61. frequency := md2.WithdrawFrequencySettingStruct{
  62. Duration: 1,
  63. Num: emptyNum,
  64. }
  65. withdrawFeeSet := md2.WithdrawFeeSetStruct{
  66. Kind: 1,
  67. Value: 0,
  68. }
  69. firstWithdrawSet := md2.FirstWithdrawSet{
  70. IsNeedRealName: 0,
  71. FirstWithdrawAmountLimit: "",
  72. }
  73. frequencyStr := utils.SerializeStr(frequency)
  74. withdrawFeeSetStr := utils.SerializeStr(withdrawFeeSet)
  75. firstWithdrawSetStr := utils.SerializeStr(firstWithdrawSet)
  76. m := model.FinWithdrawSetting{
  77. FrequencySet: frequencyStr,
  78. WithdrawType: 1,
  79. VipLevelLimit: 0,
  80. IsRealName: 0,
  81. WithdrawNumsLimit: 0,
  82. WithdrawAmountLimit: "",
  83. WithdrawMultipleLimit: "",
  84. IsSupportDecimalPoint: 0,
  85. IsAuto: 0,
  86. IsAutoAmountLimit: "",
  87. WithdrawTimeInterval: "00:00-00:00",
  88. WithdrawFeeSet: withdrawFeeSetStr,
  89. PendingOrdersIsCanApply: 0,
  90. ConditionIsOpen: 0,
  91. FirstWithdrawSet: firstWithdrawSetStr,
  92. Tips: "",
  93. CreateAt: now.Format("2006-01-02 15:04:05"),
  94. }
  95. _, err2 := settingDb.FinWithdrawSettingInsert(&m)
  96. if err2 != nil {
  97. e.OutErr(c, e.ERR_DB_ORM, err2.Error())
  98. return
  99. }
  100. setting, err = settingDb.FinWithdrawSettingGetOne()
  101. if err != nil {
  102. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  103. return
  104. }
  105. }
  106. var frequency md2.WithdrawFrequencySettingStruct
  107. var withdrawFeeSet md2.WithdrawFeeSetStruct
  108. var firstWithdrawSet md2.FirstWithdrawSet
  109. utils.Unserialize([]byte(setting.FrequencySet), &frequency)
  110. utils.Unserialize([]byte(setting.WithdrawFeeSet), &withdrawFeeSet)
  111. utils.Unserialize([]byte(setting.FirstWithdrawSet), &firstWithdrawSet)
  112. withdrawTimeIntervals := strings.Split(setting.WithdrawTimeInterval, "-")
  113. withdrawTimeInterval := md2.WithdrawTimeIntervalStruct{
  114. StartAt: withdrawTimeIntervals[0],
  115. EndAt: withdrawTimeIntervals[1],
  116. }
  117. resp := md.GetWithdrawSettingResp{
  118. Id: setting.Id,
  119. FrequencySet: frequency,
  120. WithdrawType: setting.WithdrawType,
  121. VipLevelLimit: setting.VipLevelLimit,
  122. IsRealName: setting.IsRealName,
  123. WithdrawNumsLimit: setting.WithdrawNumsLimit,
  124. WithdrawAmountLimit: setting.WithdrawAmountLimit,
  125. WithdrawMultipleLimit: setting.WithdrawMultipleLimit,
  126. IsSupportDecimalPoint: setting.IsSupportDecimalPoint,
  127. IsAuto: setting.IsAuto,
  128. IsAutoAmountLimit: setting.IsAutoAmountLimit,
  129. WithdrawTimeInterval: withdrawTimeInterval,
  130. WithdrawFeeSet: withdrawFeeSet,
  131. FirstWithdrawSet: firstWithdrawSet,
  132. PendingOrdersIsCanApply: setting.PendingOrdersIsCanApply,
  133. ConditionIsOpen: setting.ConditionIsOpen,
  134. LevelList: levelsList,
  135. Tips: setting.Tips,
  136. }
  137. e.OutSuc(c, resp, nil)
  138. }
  139. // UpdateWithdrawSetting
  140. // @Summary 财务中心-提现-基础设置(更新)
  141. // @Tags 提现
  142. // @Description 基础设置(更新)
  143. // @Accept json
  144. // @Produce json
  145. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  146. // @Param req body md.UpdateWithdrawSettingReq true "id 必填"
  147. // @Success 200 {int} "修改数据条数"
  148. // @Failure 400 {object} md.Response "具体错误"
  149. // @Router /api/financialCenter/withdraw/updateWithdrawSetting [POST]
  150. func UpdateWithdrawSetting(c *gin.Context) {
  151. var req *md.UpdateWithdrawSettingReq
  152. if err1 := c.ShouldBindJSON(&req); err1 != nil {
  153. e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error())
  154. return
  155. }
  156. if req.WithdrawTimeInterval.StartAt != "" {
  157. res := utils.IsTimeFormat(req.WithdrawTimeInterval.StartAt)
  158. if req.WithdrawTimeInterval.StartAt > "23:59" {
  159. res = false
  160. }
  161. if !res {
  162. e.OutErr(c, e.ERR_INVALID_ARGS, errors.New("开始时间应为 xx:xx 且不超过 23:59").Error())
  163. return
  164. }
  165. }
  166. if req.WithdrawTimeInterval.EndAt != "" {
  167. res := utils.IsTimeFormat(req.WithdrawTimeInterval.EndAt)
  168. if req.WithdrawTimeInterval.EndAt > "23:59" {
  169. res = false
  170. }
  171. if !res {
  172. e.OutErr(c, e.ERR_INVALID_ARGS, errors.New("结束时间应为 xx:xx 且不超过 23:59").Error())
  173. return
  174. }
  175. }
  176. frequencyStr := utils.SerializeStr(req.FrequencySet)
  177. withdrawFeeSetStr := utils.SerializeStr(req.WithdrawFeeSet)
  178. firstWithdrawSetStr := utils.SerializeStr(req.FirstWithdrawSet)
  179. var withdrawTimeInterval []string
  180. withdrawTimeInterval = append(withdrawTimeInterval, req.WithdrawTimeInterval.StartAt)
  181. withdrawTimeInterval = append(withdrawTimeInterval, req.WithdrawTimeInterval.EndAt)
  182. withdrawTimeIntervalStr := strings.Join(withdrawTimeInterval, "-")
  183. m := model.FinWithdrawSetting{
  184. Id: req.Id,
  185. FrequencySet: frequencyStr,
  186. WithdrawType: req.WithdrawType,
  187. VipLevelLimit: req.VipLevelLimit,
  188. IsRealName: req.IsRealName,
  189. WithdrawNumsLimit: req.WithdrawNumsLimit,
  190. WithdrawAmountLimit: req.WithdrawAmountLimit,
  191. WithdrawMultipleLimit: req.WithdrawMultipleLimit,
  192. IsSupportDecimalPoint: req.IsSupportDecimalPoint,
  193. IsAuto: req.IsAuto,
  194. IsAutoAmountLimit: req.IsAutoAmountLimit,
  195. WithdrawTimeInterval: withdrawTimeIntervalStr,
  196. WithdrawFeeSet: withdrawFeeSetStr,
  197. PendingOrdersIsCanApply: req.PendingOrdersIsCanApply,
  198. ConditionIsOpen: req.ConditionIsOpen,
  199. FirstWithdrawSet: firstWithdrawSetStr,
  200. Tips: req.Tips,
  201. }
  202. forceColumns := []string{"withdraw_type", "is_real_name", "withdraw_nums_limit",
  203. "withdraw_amount_limit", "withdraw_multiple_limit", "is_support_decimal_point",
  204. "is_auto", "first_withdraw_set", "is_auto_amount_limit", "pending_orders_is_can_apply",
  205. "condition_is_open",
  206. }
  207. settingDb := implement.NewFinWithdrawSettingDb(db.Db)
  208. affected, err := settingDb.FinWithdrawSettingUpdate(req.Id, &m, forceColumns...)
  209. if err != nil {
  210. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  211. return
  212. }
  213. e.OutSuc(c, affected, nil)
  214. }
  215. // GetWithdrawApplyList
  216. // @Summary 财务中心-提现-提现申请列表(获取)
  217. // @Tags 提现
  218. // @Description 提现申请列表(获取)
  219. // @Accept json
  220. // @Produce json
  221. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  222. // @Param req body md.GetWithdrawApplyListReq false "筛选条件"
  223. // @Success 200 {object} md.GetWithdrawApplyListResp "具体数据"
  224. // @Failure 400 {object} md.Response "具体错误"
  225. // @Router /api/financialCenter/withdraw/applyList [POST]
  226. func GetWithdrawApplyList(c *gin.Context) {
  227. var req *md.GetWithdrawApplyListReq
  228. if err1 := c.ShouldBindJSON(&req); err1 != nil {
  229. e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error())
  230. return
  231. }
  232. levelDb := implement.NewUserLevelDb(db.Db)
  233. levels, err1 := levelDb.UserLevelAllByAsc()
  234. if err1 != nil {
  235. e.OutErr(c, e.ERR_DB_ORM, err1.Error())
  236. return
  237. }
  238. levelsList := make([]map[string]interface{}, 0)
  239. levelsMap := make(map[int]string)
  240. for _, level := range levels {
  241. levelsList = append(levelsList, map[string]interface{}{
  242. "id": level.Id,
  243. "name": level.LevelName,
  244. })
  245. levelsMap[level.Id] = level.LevelName
  246. }
  247. tagDb := implement.NewUserTagDb(db.Db)
  248. tags, err2 := tagDb.UserTagAllByAsc()
  249. if err2 != nil {
  250. e.OutErr(c, e.ERR_DB_ORM, err2.Error())
  251. return
  252. }
  253. tagsList := make([]map[string]interface{}, 0)
  254. tagsMap := make(map[int]string)
  255. for _, tag := range tags {
  256. tagsList = append(tagsList, map[string]interface{}{
  257. "id": tag.Id,
  258. "name": tag.TagName,
  259. })
  260. tagsMap[tag.Id] = tag.TagName
  261. }
  262. applies, total, err3 := svc.WithDrawManagementGetApply(db.Db, req)
  263. if err3 != nil {
  264. e.OutErr(c, e.ERR_DB_ORM, err3.Error())
  265. return
  266. }
  267. list := make([]md.GetWithdrawApplyListNode, len(*applies))
  268. parentIDs := make([]int64, len(*applies))
  269. UserIDs := make([]int64, len(*applies))
  270. for _, apply := range *applies {
  271. parentIDs = append(parentIDs, apply.ParentID)
  272. UserIDs = append(UserIDs, apply.Uid)
  273. }
  274. // 查询上级
  275. userDb := implement.NewUserDb(db.Db)
  276. parents, err := userDb.UserFindByParams(map[string]interface{}{
  277. "key": "id",
  278. "value": parentIDs,
  279. })
  280. if err != nil {
  281. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  282. return
  283. }
  284. parentsMap := make(map[int64]model.User)
  285. for _, parent := range parents {
  286. parentsMap[parent.Id] = parent
  287. }
  288. // 查询标签
  289. recordsDb := implement.NewUserTagRecordsDb(db.Db)
  290. records, err := recordsDb.UserTagRecordsFindByParams(map[string]interface{}{
  291. "key": "uid",
  292. "value": UserIDs,
  293. })
  294. if err != nil {
  295. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  296. return
  297. }
  298. recordsMap := make(map[int64][]md.TagNode)
  299. for _, record := range *records {
  300. temp := md.TagNode{
  301. TagID: record.TagId,
  302. TagName: "",
  303. }
  304. tagName, ok := tagsMap[record.TagId]
  305. temp.TagName = tagName
  306. v, ok := recordsMap[record.Uid]
  307. if ok {
  308. recordsMap[record.Uid] = append(v, temp)
  309. } else {
  310. recordsMap[record.Uid] = []md.TagNode{temp}
  311. }
  312. }
  313. amountDb := implement.NewUserVirtualAmountDb(db.Db)
  314. virtualList, _ := amountDb.UserVirtualAllWalletFindByParams(map[string]interface{}{
  315. "key": "uid",
  316. "value": UserIDs,
  317. })
  318. virtualMap := make(map[int64]model.UserVirtualAmount)
  319. virtualMap1 := make(map[int64]model.UserVirtualAmount)
  320. settingDb := implement.NewEggEnergyBasicSettingDb(db.Db)
  321. setting, _ := settingDb.EggEnergyBasicSettingGetOne()
  322. if virtualList != nil {
  323. for _, record := range *virtualList {
  324. if record.CoinId == setting.PersonEggEnergyCoinId {
  325. virtualMap[record.Uid] = record
  326. }
  327. if record.CoinId == setting.TeamEggEnergyCoinId {
  328. virtualMap1[record.Uid] = record
  329. }
  330. }
  331. }
  332. for i, apply := range *applies {
  333. list[i] = md.GetWithdrawApplyListNode{
  334. WithdrawApplyId: utils.Int64ToStr(apply.Id),
  335. UserID: apply.Uid,
  336. Nickname: apply.Nickname,
  337. ParentID: apply.ParentID,
  338. AliPayName: apply.AliPayName,
  339. WechatPayName: apply.WxPayName,
  340. AliPayAccount: apply.AliPayAccount,
  341. WechatPayAccount: apply.WxPayAccount,
  342. WithdrawType: apply.WithdrawKind,
  343. InviteCode: apply.InviteCode,
  344. Amount: apply.Amount,
  345. ActualReceipt: apply.RealAmount,
  346. SysFee: apply.Fee,
  347. State: apply.State,
  348. ApplyAt: apply.CreateAt,
  349. PayAt: apply.UpdateAt,
  350. Memo: apply.Memo,
  351. ErrorMsg: gjson.Get(apply.ErrorMsg, "sub_msg").String(),
  352. }
  353. virAmount, ok := virtualMap[apply.Uid]
  354. if ok {
  355. list[i].CoinAmount = virAmount.Amount
  356. }
  357. virAmount1, ok1 := virtualMap1[apply.Uid]
  358. if ok1 {
  359. list[i].WaitCoinAmount = virAmount1.Amount
  360. }
  361. if apply.CustomInviteCode != "" {
  362. list[i].InviteCode = apply.CustomInviteCode
  363. }
  364. if apply.Amount != "" && apply.Fee != "" {
  365. actualReceipt := utils.StrToFloat64(apply.Amount) - utils.StrToFloat64(apply.Fee)
  366. list[i].ActualReceipt = utils.Float64ToStr(actualReceipt)
  367. }
  368. if apply.ParentID != 0 {
  369. v, ok := parentsMap[apply.ParentID]
  370. if ok {
  371. list[i].ParentPhone = v.Phone
  372. }
  373. }
  374. tagList, ok := recordsMap[apply.Uid]
  375. if ok {
  376. list[i].Tag = tagList
  377. }
  378. }
  379. resp := md.GetWithdrawApplyListResp{
  380. AuditList: []map[string]interface{}{
  381. {
  382. "value": 1,
  383. "name": "同意",
  384. },
  385. {
  386. "value": 2,
  387. "name": "拒绝",
  388. },
  389. },
  390. ReasonList: []map[string]interface{}{
  391. {
  392. "value": enum.FinWithdrawApplyReasonForNotRule,
  393. "name": enum.FinWithdrawApplyReasonForNotRule.String(),
  394. },
  395. {
  396. "value": enum.FinWithdrawApplyReasonForAccountAbnormal,
  397. "name": enum.FinWithdrawApplyReasonForAccountAbnormal.String(),
  398. },
  399. {
  400. "value": enum.FinWithdrawApplyReasonForFundAbnormal,
  401. "name": enum.FinWithdrawApplyReasonForFundAbnormal.String(),
  402. },
  403. },
  404. LevelsList: levelsList,
  405. TagsList: tagsList,
  406. List: list,
  407. Paginate: md.Paginate{
  408. Limit: req.Limit,
  409. Page: req.Page,
  410. Total: total,
  411. },
  412. }
  413. e.OutSuc(c, resp, nil)
  414. }
  415. // GetWithdrawApplyTotal
  416. // @Summary 财务中心-提现-提现统计
  417. // @Tags 提现
  418. // @Description 提现统计(获取)
  419. // @Accept json
  420. // @Produce json
  421. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  422. // @Param req body md.GetWithdrawApplyListReq false "筛选条件"
  423. // @Success 200 {object} md.GetWithdrawApplyListResp "具体数据"
  424. // @Failure 400 {object} md.Response "具体错误"
  425. // @Router /api/financialCenter/withdraw/total [POST]
  426. func GetWithdrawApplyTotal(c *gin.Context) {
  427. var req *md.GetWithdrawApplyListReq
  428. if err1 := c.ShouldBindJSON(&req); err1 != nil {
  429. e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error())
  430. return
  431. }
  432. applies, err3 := svc.WithDrawManagementGetApplyTotal(db.Db, req)
  433. if err3 != nil {
  434. e.OutErr(c, e.ERR_DB_ORM, err3.Error())
  435. return
  436. }
  437. resp := md.GetWithdrawApplyListResp{
  438. PendingAmount: applies.PendingAmount,
  439. PayFailedAmount: applies.FailAmount,
  440. PaySucceedAmount: applies.Amount,
  441. }
  442. e.OutSuc(c, resp, nil)
  443. }
  444. // WithdrawApplyAudit
  445. // @Summary 财务中心-提现-审核
  446. // @Tags 提现
  447. // @Description 提现审核
  448. // @Accept json
  449. // @Produce json
  450. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  451. // @Param req body md.WithdrawApplyAuditReq false "筛选条件"
  452. // @Success 200 {string} "success"
  453. // @Failure 400 {object} md.Response "具体错误"
  454. // @Router /api/financialCenter/withdraw/audit [POST]
  455. func WithdrawApplyAudit(c *gin.Context) {
  456. var req *md.WithdrawApplyAuditReq
  457. if err1 := c.ShouldBindJSON(&req); err1 != nil {
  458. e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error())
  459. return
  460. }
  461. //1、查找对应提现申请单
  462. finWithdrawApplyDb := implement.NewFinWithdrawApplyDb(db.Db)
  463. finWithdrawApply, err := finWithdrawApplyDb.FinWithdrawApplyGet(utils.StrToInt64(req.WithdrawApplyId))
  464. if err != nil {
  465. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  466. return
  467. }
  468. if finWithdrawApply == nil {
  469. e.OutErr(c, e.ERR_NOT_FAN, "提现记录不存在")
  470. return
  471. }
  472. //2、判断审核状态
  473. if req.AuditState == 1 {
  474. //通过(推mq、修改提现单成功)
  475. finWithdrawApply.State = int(enum.FinWithdrawApplyStateForIng)
  476. updateAffected, err1 := finWithdrawApplyDb.UpdateFinWithdrawApply(finWithdrawApply, "state")
  477. if err1 != nil {
  478. e.OutErr(c, e.ERR_DB_ORM, err1.Error())
  479. return
  480. }
  481. if updateAffected <= 0 {
  482. e.OutErr(c, e.ERR_DB_ORM, "更新提现单状态失败")
  483. return
  484. }
  485. ch, err1 := rabbit.Cfg.Pool.GetChannel()
  486. if err1 != nil {
  487. e.OutErr(c, e.ERR_INIT_RABBITMQ, err1.Error())
  488. return
  489. }
  490. defer ch.Release()
  491. var data md2.EggFinWithdrawApplyData
  492. err = copier.Copy(&data, &finWithdrawApply)
  493. if err != nil {
  494. e.OutErr(c, e.ERR, err.Error())
  495. return
  496. }
  497. ch.Publish(md2.EggAppExchange, data, md2.EggFinWithdrawApply)
  498. } else {
  499. //拒绝(退余额、修改提现单失败)
  500. session := db.Db.NewSession()
  501. defer session.Close()
  502. session.Begin()
  503. finWithdrawApply.State = int(enum.FinWithdrawApplyStateForBad)
  504. updateAffected, err1 := finWithdrawApplyDb.UpdateFinWithdrawApplyBySession(session, finWithdrawApply, "state")
  505. if err1 != nil {
  506. e.OutErr(c, e.ERR_DB_ORM, err1.Error())
  507. return
  508. }
  509. if updateAffected <= 0 {
  510. e.OutErr(c, e.ERR_DB_ORM, "更新提现单状态失败")
  511. return
  512. }
  513. dealUserWalletReq := md3.DealUserWalletReq{
  514. Direction: "add",
  515. Kind: int(enum.UserWithdrawBad),
  516. Title: enum.UserWithdrawBad.String(),
  517. Uid: finWithdrawApply.Uid,
  518. Amount: utils.StrToFloat64(finWithdrawApply.Amount),
  519. }
  520. egg_system_rules.Init(cfg.RedisAddr)
  521. err = rule.DealUserWallet(session, dealUserWalletReq)
  522. if err != nil {
  523. session.Rollback()
  524. e.OutErr(c, e.ERR, err.Error())
  525. return
  526. }
  527. err = session.Commit()
  528. if err != nil {
  529. _ = session.Rollback()
  530. e.OutErr(c, e.ERR_DB_ORM, err)
  531. return
  532. }
  533. }
  534. e.OutSuc(c, "success", nil)
  535. }