蛋蛋星球 后台端
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.
 
 
 
 

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