蛋蛋星球-客户端
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.
 
 
 
 
 

483 lines
13 KiB

  1. package hdl
  2. import (
  3. "applet/app/db"
  4. "applet/app/e"
  5. "applet/app/md"
  6. "applet/app/svc"
  7. "applet/app/utils"
  8. "applet/app/utils/cache"
  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/enum"
  12. md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/md"
  13. "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule"
  14. md3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md"
  15. "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit"
  16. "errors"
  17. "fmt"
  18. "github.com/gin-gonic/gin"
  19. "github.com/jinzhu/copier"
  20. "time"
  21. )
  22. // GetAmountFlow
  23. // @Summary 蛋蛋星球-钱包-余额明细(获取)
  24. // @Tags 钱包
  25. // @Description 余额明细(获取)
  26. // @Accept json
  27. // @Produce json
  28. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  29. // @Param limit query string true "每页大小"
  30. // @Param page query string true "页数"
  31. // @Param startAt query string false "开始时间"
  32. // @Param endAt query string false "结束时间"
  33. // @Param direction query string false "流水方向(1.收入 2.支出 0.全部)"
  34. // @Success 200 {object} md.GetAmountFlowResp "具体数据"
  35. // @Failure 400 {object} md.Response "具体错误"
  36. // @Router /api/v1/wallet/amountFlow [GET]
  37. func GetAmountFlow(c *gin.Context) {
  38. pageStr := c.DefaultQuery("page", "1")
  39. limitStr := c.DefaultQuery("limit", "10")
  40. startAt := c.Query("startAt")
  41. endAt := c.Query("endAt")
  42. directionStr := c.Query("direction")
  43. val, exists := c.Get("user")
  44. if !exists {
  45. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  46. return
  47. }
  48. user, ok := val.(*model.User)
  49. if !ok {
  50. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  51. return
  52. }
  53. direction := 0
  54. switch directionStr {
  55. case "1":
  56. direction = 1
  57. case "2":
  58. direction = 2
  59. }
  60. page := utils.StrToInt(pageStr)
  61. limit := utils.StrToInt(limitStr)
  62. flowDb := implement.NewUserWalletFlowDb(db.Db)
  63. flows, total, err := flowDb.UserWalletFlowFindByCoinAndUser(page, limit, user.Id, startAt, endAt, direction, false, 0, 0)
  64. if err != nil {
  65. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  66. return
  67. }
  68. list := make([]md.WalletFlowNode, 0, len(flows))
  69. for _, flow := range flows {
  70. temp := md.WalletFlowNode{
  71. Id: flow.Id,
  72. Uid: flow.Uid,
  73. Direction: flow.Direction,
  74. Amount: flow.Amount,
  75. BeforeAmount: flow.BeforeAmount,
  76. AfterAmount: flow.AfterAmount,
  77. SysFee: flow.SysFee,
  78. OrdId: flow.OrdId,
  79. Title: flow.Title,
  80. Kind: flow.Kind,
  81. State: flow.State,
  82. Memo: flow.Memo,
  83. CreateTime: flow.CreateAt,
  84. UpdateTime: flow.UpdateAt,
  85. }
  86. list = append(list, temp)
  87. }
  88. resp := md.GetAmountFlowResp{
  89. List: list,
  90. Paginate: md.Paginate{
  91. Limit: limit,
  92. Page: page,
  93. Total: total,
  94. },
  95. }
  96. e.OutSuc(c, resp, nil)
  97. }
  98. // WithdrawGetAmount
  99. // @Summary 蛋蛋星球-钱包-提现余额(获取)
  100. // @Tags 钱包
  101. // @Description 提现余额(获取)
  102. // @Accept json
  103. // @Produce json
  104. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  105. // @Success 200 {object} md.WithdrawGetAmountResp "具体数据"
  106. // @Failure 400 {object} md.Response "具体错误"
  107. // @Router /api/v1/wallet/withdraw/index [GET]
  108. func WithdrawGetAmount(c *gin.Context) {
  109. val, exists := c.Get("user")
  110. if !exists {
  111. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  112. return
  113. }
  114. user, ok := val.(*model.User)
  115. if !ok {
  116. e.OutErr(c, e.ERR_USER_CHECK_ERR, nil)
  117. return
  118. }
  119. walletDb := implement.NewUserWalletDb(db.Db)
  120. wallet, err := walletDb.GetUserVirtualWallet(user.Id)
  121. if err != nil {
  122. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  123. return
  124. }
  125. resp := md.WithdrawGetAmountResp{
  126. Amount: wallet.Amount,
  127. }
  128. e.OutSuc(c, resp, nil)
  129. }
  130. // WithdrawApply
  131. // @Summary 蛋蛋星球-钱包-发起提现
  132. // @Tags 钱包
  133. // @Description 发起提现
  134. // @Accept json
  135. // @Produce json
  136. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  137. // @Param req body md.WithdrawApplyReq true "具体参数"
  138. // @Success 200 {string} "success"
  139. // @Failure 400 {object} md.Response "具体错误"
  140. // @Router /api/v1/wallet/withdraw/apply [POST]
  141. func WithdrawApply(c *gin.Context) {
  142. var req md.WithdrawApplyReq
  143. err := c.ShouldBindJSON(&req)
  144. if err != nil {
  145. err = svc.HandleValidateErr(err)
  146. err1 := err.(e.E)
  147. e.OutErr(c, err1.Code, err1.Error())
  148. return
  149. }
  150. user := svc.GetUser(c)
  151. var userId, openId string
  152. //sysCfgDb := implement.NewSysCfgDb(db.Db, cache.GetPool().Get())
  153. //sysCfgMap := sysCfgDb.SysCfgFindWithDb(enum.AlipayAppId, enum.WxAppId)
  154. if req.Kind == int(enum.FinWithdrawApplyWithdrawKindForAli) {
  155. alipayUserInfoDb := implement.NewAlipayUserInfoDb(db.Db)
  156. aliInfo, err := alipayUserInfoDb.GetAlipayUserInfo(user.Id)
  157. if err != nil {
  158. e.OutErr(c, e.ERR, err.Error())
  159. return
  160. }
  161. if aliInfo == nil {
  162. e.OutErr(c, e.ERR, "支付宝用户信息未授权")
  163. return
  164. }
  165. //appId = sysCfgMap[enum.AlipayAppId]
  166. userId = aliInfo.UserId
  167. openId = aliInfo.OpenId
  168. } else if req.Kind == int(enum.FinWithdrawApplyWithdrawKindForWx) {
  169. wxUserInfoDb := implement.NewWxUserInfoDb(db.Db)
  170. wxInfo, err := wxUserInfoDb.GetWxUserInfo(user.Id)
  171. if err != nil {
  172. e.OutErr(c, e.ERR, err.Error())
  173. return
  174. }
  175. if wxInfo == nil {
  176. e.OutErr(c, e.ERR, "微信用户信息未授权")
  177. return
  178. }
  179. //appId = sysCfgMap[enum.WxAppId]
  180. userId = wxInfo.UserId
  181. openId = wxInfo.OpenId
  182. } else {
  183. e.OutErr(c, e.ERR, "未知的提现类型")
  184. return
  185. }
  186. //1、判断是否可以提现
  187. err, realAmount, fee, isAuto, isFirst := svc.CheckWithdraw(c, req.Amount)
  188. if err != nil {
  189. e.OutErr(c, e.ERR, err.Error())
  190. return
  191. }
  192. // 2、加锁 防止并发提取
  193. mutexKey := fmt.Sprintf("egg_app_withdraw_apply:%s", utils.Int64ToStr(user.Id))
  194. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  195. if err != nil {
  196. e.OutErr(c, e.ERR, err)
  197. return
  198. }
  199. if withdrawAvailable != "OK" {
  200. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  201. return
  202. }
  203. // 开启事务
  204. session := db.Db.NewSession()
  205. defer session.Close()
  206. err = session.Begin()
  207. if err != nil {
  208. session.Rollback()
  209. e.OutErr(c, e.ERR_DB_ORM, err)
  210. return
  211. }
  212. //3、处理用户余额
  213. dealUserWalletReq := md2.DealUserWalletReq{
  214. Direction: "sub",
  215. Kind: int(enum.UserWithdrawApply),
  216. Title: enum.UserWithdrawApply.String(),
  217. Uid: user.Id,
  218. Amount: utils.StrToFloat64(req.Amount),
  219. }
  220. err = rule.DealUserWallet(session, dealUserWalletReq)
  221. if err != nil {
  222. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  223. session.Rollback()
  224. return
  225. }
  226. //4、新增提现记录
  227. now := time.Now()
  228. finWithdrawApplyDb := implement.NewFinWithdrawApplyDb(db.Db)
  229. finWithdrawApply := &model.FinWithdrawApply{
  230. Uid: user.Id,
  231. AdmId: 0,
  232. Amount: req.Amount,
  233. RealAmount: realAmount,
  234. Fee: fee,
  235. Type: func(isAuto bool) int {
  236. if isAuto {
  237. return 2
  238. }
  239. return 1
  240. }(isAuto),
  241. WithdrawAccount: userId,
  242. WithdrawName: openId,
  243. Reason: 0,
  244. PaymentDate: "",
  245. State: 0,
  246. WithdrawKind: req.Kind,
  247. IsFirst: func(isFirst bool) int {
  248. if isFirst {
  249. return 1
  250. }
  251. return 0
  252. }(isFirst),
  253. Memo: "",
  254. UpdateAt: now.Format("2006-01-02 15:04:05"),
  255. CreateAt: now.Format("2006-01-02 15:04:05"),
  256. }
  257. insertAffected, err := finWithdrawApplyDb.FinWithdrawApplyInsertOneBySession(session, finWithdrawApply)
  258. if err != nil {
  259. session.Rollback()
  260. e.OutErr(c, e.ERR_DB_ORM, err)
  261. return
  262. }
  263. if insertAffected <= 0 {
  264. session.Rollback()
  265. e.OutErr(c, e.ERR_DB_ORM, "生成提现单失败")
  266. return
  267. }
  268. err = session.Begin()
  269. if err != nil {
  270. session.Rollback()
  271. e.OutErr(c, e.ERR_DB_ORM, err)
  272. return
  273. }
  274. err = session.Commit()
  275. if err != nil {
  276. _ = session.Rollback()
  277. e.OutErr(c, e.ERR_DB_ORM, err)
  278. return
  279. }
  280. //5、推入mq
  281. if isAuto {
  282. ch, err1 := rabbit.Cfg.Pool.GetChannel()
  283. if err1 != nil {
  284. e.OutErr(c, e.ERR_INIT_RABBITMQ, err1.Error())
  285. return
  286. }
  287. defer ch.Release()
  288. var data md3.EggFinWithdrawApplyData
  289. err = copier.Copy(&data, &finWithdrawApply)
  290. if err != nil {
  291. e.OutErr(c, e.ERR, err.Error())
  292. return
  293. }
  294. ch.Publish(md3.EggAppExchange, utils.SerializeStr(data), md3.EggFinWithdrawApply)
  295. }
  296. e.OutSuc(c, "success", nil)
  297. }
  298. // GetWithdrawCondition
  299. // @Summary 蛋蛋星球-钱包-提现条件(获取)
  300. // @Tags 钱包
  301. // @Description 提现条件(获取)
  302. // @Accept json
  303. // @Produce json
  304. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  305. // @Success 200 {object} md.GetWithdrawConditionResp "具体数据"
  306. // @Failure 400 {object} md.Response "具体错误"
  307. // @Router /api/v1/wallet/withdraw/condition [GET]
  308. func GetWithdrawCondition(c *gin.Context) {
  309. user := svc.GetUser(c)
  310. alipayUserInfoDb := implement.NewAlipayUserInfoDb(db.Db)
  311. alipayInfo, err := alipayUserInfoDb.GetAlipayUserInfo(user.Id)
  312. if err != nil {
  313. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  314. return
  315. }
  316. userInfoDb := implement.NewWxUserInfoDb(db.Db)
  317. wxUserInfo, err := userInfoDb.GetWxUserInfo(user.Id)
  318. if err != nil {
  319. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  320. return
  321. }
  322. resp := md.GetWithdrawConditionResp{
  323. IsRealName: func(isRealName int) bool {
  324. switch isRealName {
  325. case 0:
  326. return false
  327. case 1:
  328. return true
  329. default:
  330. return false
  331. }
  332. }(user.IsRealName),
  333. IsBindAlipay: func(alipayInfo *model.AlipayUserInfo) bool {
  334. if alipayInfo == nil {
  335. return false
  336. } else {
  337. return true
  338. }
  339. }(alipayInfo),
  340. IsBindWx: func(wxUserInfo *model.WxUserInfo) bool {
  341. if wxUserInfo == nil {
  342. return false
  343. } else {
  344. return true
  345. }
  346. }(wxUserInfo),
  347. }
  348. e.OutSuc(c, resp, nil)
  349. }
  350. // BindAlipayAccount
  351. // @Summary 蛋蛋星球-钱包-绑定支付宝
  352. // @Tags 钱包
  353. // @Description 绑定支付宝
  354. // @Accept json
  355. // @Produce json
  356. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  357. // @Param req body md.BindAlipayAccountReq true "具体参数"
  358. // @Success 200 {string} "success"
  359. // @Failure 400 {object} md.Response "具体错误"
  360. // @Router /api/v1/wallet/withdraw/bindAlipay [POST]
  361. func BindAlipayAccount(c *gin.Context) {
  362. var req md.BindAlipayAccountReq
  363. err := c.ShouldBindJSON(&req)
  364. if err != nil {
  365. err = svc.HandleValidateErr(err)
  366. err1 := err.(e.E)
  367. e.OutErr(c, err1.Code, err1.Error())
  368. return
  369. }
  370. user := svc.GetUser(c)
  371. alipayUserInfoDb := implement.NewAlipayUserInfoDb(db.Db)
  372. alipayUserInfo, err := alipayUserInfoDb.GetAlipayUserInfo(user.Id)
  373. if err != nil {
  374. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  375. return
  376. }
  377. if alipayUserInfo != nil {
  378. e.OutErr(c, e.ERR, errors.New("用户已绑定支付宝").Error())
  379. return
  380. }
  381. now := time.Now()
  382. newAlipayUserInfo := model.AlipayUserInfo{
  383. Uid: user.Id,
  384. UserId: req.UserId,
  385. OpenId: req.OpenId,
  386. AppId: req.AppId,
  387. Ext: req.Ext,
  388. CreateAt: now.Format("2006-01-02 15:04:05"),
  389. UpdateAt: now.Format("2006-01-02 15:04:05"),
  390. }
  391. affected, err := alipayUserInfoDb.AlipayUserInfoInsert(&newAlipayUserInfo)
  392. if err != nil {
  393. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  394. return
  395. }
  396. if affected <= 0 {
  397. e.OutErr(c, e.ERR, errors.New("绑定失败"))
  398. return
  399. }
  400. e.OutSuc(c, "success", nil)
  401. }
  402. // BindWxPayAccount
  403. // @Summary 蛋蛋星球-钱包-绑定微信支付
  404. // @Tags 钱包
  405. // @Description 绑定微信支付
  406. // @Accept json
  407. // @Produce json
  408. // @param Authorization header string true "验证参数Bearer和token空格拼接"
  409. // @Param req body md.BindWxPayAccountReq true "具体参数"
  410. // @Success 200 {string} "success"
  411. // @Failure 400 {object} md.Response "具体错误"
  412. // @Router /api/v1/wallet/withdraw/bindWxPay [POST]
  413. func BindWxPayAccount(c *gin.Context) {
  414. var req md.BindWxPayAccountReq
  415. err := c.ShouldBindJSON(&req)
  416. if err != nil {
  417. err = svc.HandleValidateErr(err)
  418. err1 := err.(e.E)
  419. e.OutErr(c, err1.Code, err1.Error())
  420. return
  421. }
  422. user := svc.GetUser(c)
  423. wxUserInfoDb := implement.NewWxUserInfoDb(db.Db)
  424. wxUserInfo, err := wxUserInfoDb.GetWxUserInfo(user.Id)
  425. if err != nil {
  426. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  427. return
  428. }
  429. if wxUserInfo != nil {
  430. e.OutErr(c, e.ERR, errors.New("用户已绑定过微信").Error())
  431. return
  432. }
  433. now := time.Now()
  434. newWxUserInfo := model.WxUserInfo{
  435. Uid: user.Id,
  436. UserId: req.UserId,
  437. OpenId: req.OpenId,
  438. AppId: req.AppId,
  439. Ext: req.Ext,
  440. CreateAt: now.Format("2006-01-02 15:04:05"),
  441. UpdateAt: now.Format("2006-01-02 15:04:05"),
  442. }
  443. affected, err := wxUserInfoDb.WxUserInfoInsert(&newWxUserInfo)
  444. if err != nil {
  445. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  446. return
  447. }
  448. if affected <= 0 {
  449. e.OutErr(c, e.ERR, errors.New("绑定失败"))
  450. }
  451. e.OutSuc(c, "success", nil)
  452. }