蛋蛋星球-客户端
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

svc_withdraw_apply.go 11 KiB

1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
1ヶ月前
2週間前
1週間前
1ヶ月前
1週間前
2週間前
1ヶ月前
2週間前
1ヶ月前
2週間前
1ヶ月前
2週間前
1ヶ月前
2週間前
1ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package svc
  2. import (
  3. "applet/app/db"
  4. "applet/app/e"
  5. md2 "applet/app/md"
  6. "applet/app/utils"
  7. "code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
  8. "code.fnuoos.com/EggPlanet/egg_models.git/src/model"
  9. "code.fnuoos.com/EggPlanet/egg_system_rules.git/enum"
  10. "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md"
  11. "errors"
  12. "github.com/gin-gonic/gin"
  13. "github.com/shopspring/decimal"
  14. "math"
  15. "strings"
  16. "time"
  17. )
  18. func CheckWithdraw(c *gin.Context, amount string) (err error, realAmount, fee string, isAuto, isFirst bool) {
  19. realAmount = amount
  20. user := GetUser(c)
  21. now := time.Now()
  22. amountValue, _ := decimal.NewFromString(amount)
  23. //1、查询 fin_withdraw_setting 提现设置表
  24. finWithdrawSettingDb := implement.NewFinWithdrawSettingDb(db.Db)
  25. withdrawSetting, err := finWithdrawSettingDb.FinWithdrawSettingGetOne()
  26. if err != nil {
  27. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  28. return
  29. }
  30. //2、判断是否为第一次提现
  31. var isCompleteFirstWithdraw bool
  32. has, err := db.Db.Where("uid =?", user.Id).Get(&model.FinWithdrawApply{})
  33. if err != nil {
  34. return
  35. }
  36. if !has { //第一次提现
  37. isFirst = true
  38. var firstWithdrawSet md.FirstWithdrawSet
  39. utils.Unserialize([]byte(withdrawSetting.FrequencySet), &firstWithdrawSet)
  40. if firstWithdrawSet.IsNeedRealName == 0 && firstWithdrawSet.FirstWithdrawAmountLimit >= amount {
  41. isCompleteFirstWithdraw = true
  42. }
  43. }
  44. //2、判断“是否实名”
  45. if isCompleteFirstWithdraw && withdrawSetting.IsRealName == 1 && user.IsRealName != 1 {
  46. return errors.New("非实名用户不可提现"), realAmount, fee, isAuto, isFirst
  47. }
  48. //3、判断“提现金额”
  49. if isCompleteFirstWithdraw && utils.StrToFloat64(withdrawSetting.WithdrawAmountLimit) > 0 {
  50. withdrawAmountLimitValue, _ := decimal.NewFromString(withdrawSetting.WithdrawAmountLimit)
  51. if amountValue.LessThan(withdrawAmountLimitValue) {
  52. return errors.New("非可提现金额"), realAmount, fee, isAuto, isFirst
  53. }
  54. }
  55. //4、判断“提现倍数”
  56. if isCompleteFirstWithdraw && utils.StrToFloat64(withdrawSetting.WithdrawMultipleLimit) > 0 {
  57. result := utils.StrToFloat64(amount) / utils.StrToFloat64(withdrawSetting.WithdrawMultipleLimit)
  58. // 检查结果是否非常接近一个整数
  59. roundedResult := math.Round(result)
  60. if !(math.Abs(roundedResult-result) < 1e-9) {
  61. return errors.New("非可提现倍数"), realAmount, fee, isAuto, isFirst
  62. }
  63. }
  64. //5、验证会员等级
  65. if isCompleteFirstWithdraw && withdrawSetting.VipLevelLimit > 0 && withdrawSetting.VipLevelLimit > user.Level {
  66. return errors.New("非可提现会员等级"), realAmount, fee, isAuto, isFirst
  67. }
  68. //6、 验证小数点
  69. if isCompleteFirstWithdraw && withdrawSetting.IsSupportDecimalPoint == 0 && strings.Contains(amount, ".") {
  70. return errors.New("不支持的提现金额"), realAmount, fee, isAuto, isFirst
  71. }
  72. //7、验证时段
  73. if withdrawSetting.WithdrawTimeInterval != "" {
  74. withdrawTimeInterval := strings.Split(withdrawSetting.WithdrawTimeInterval, "-")
  75. // 定义要比较的时间格式
  76. layout := "15:04"
  77. // 解析给定的时间字符串
  78. start, _ := time.Parse(layout, withdrawTimeInterval[0])
  79. end, _ := time.Parse(layout, withdrawTimeInterval[1])
  80. // 设置为今天的日期
  81. start = time.Date(now.Year(), now.Month(), now.Day(), start.Hour(), start.Minute(), 0, 0, now.Location())
  82. end = time.Date(now.Year(), now.Month(), now.Day(), end.Hour(), end.Minute(), 0, 0, now.Location())
  83. // 如果结束时间小于开始时间,说明跨天了
  84. if end.Before(start) {
  85. if !(now.After(start) || now.Before(end)) {
  86. return errors.New("非可提现时间段"), realAmount, fee, isAuto, isFirst
  87. }
  88. } else { // 否则,在同一天内比较
  89. if !(now.After(start) && now.Before(end)) {
  90. return errors.New("非可提现时间段"), realAmount, fee, isAuto, isFirst
  91. }
  92. }
  93. }
  94. //8、验证“提现频率”
  95. var frequency md.WithdrawFrequencySettingStruct
  96. utils.Unserialize([]byte(withdrawSetting.FrequencySet), &frequency)
  97. if frequency.Duration == 2 {
  98. day := now.Weekday()
  99. if !utils.InArr(utils.IntToStr(int(day)), frequency.Num) {
  100. return errors.New("非可提现日期"), realAmount, fee, isAuto, isFirst
  101. }
  102. }
  103. if frequency.Duration == 3 {
  104. day := now.Day()
  105. if !utils.InArr(utils.IntToStr(day), frequency.Num) {
  106. return errors.New("非可提现日期"), realAmount, fee, isAuto, isFirst
  107. }
  108. }
  109. if withdrawSetting.WithdrawNumsLimit > 0 {
  110. var withdrawNums int64
  111. var startOfDay, endOfDay time.Time
  112. if frequency.Duration == 1 { //按天
  113. startOfDay = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
  114. endOfDay = startOfDay.Add(24 * time.Hour)
  115. }
  116. if frequency.Duration == 2 { //按周
  117. startOfDay = utils.GetStartOfWeek(now)
  118. endOfDay = startOfDay.Add(7 * 24 * time.Hour)
  119. }
  120. if frequency.Duration == 3 { //按月
  121. startOfDay = utils.GetFirstDateOfMonth(now)
  122. endOfDay = utils.GetLastDateOfMonth(now)
  123. }
  124. withdrawNums, err = db.Db.Where("create_at >= ?", startOfDay.Format("2006-01-02 15:04:05")).
  125. And("create_at < ?", endOfDay.Format("2006-01-02 15:04:05")).
  126. And("uid =?", user.Id).
  127. And("state != 3"). //失败不计入
  128. Count(&model.FinWithdrawApply{})
  129. if err != nil {
  130. return err, realAmount, fee, isAuto, isFirst
  131. }
  132. if int(withdrawNums) >= withdrawSetting.WithdrawNumsLimit {
  133. return errors.New("当前已无可提现次数"), realAmount, fee, isAuto, isFirst
  134. }
  135. }
  136. //9、计算手续费
  137. var feeSet md.WithdrawFeeSetStruct
  138. utils.Unserialize([]byte(withdrawSetting.WithdrawFeeSet), &feeSet)
  139. if feeSet.Value > 0 {
  140. feeSerValue := decimal.NewFromInt(int64(feeSet.Value))
  141. if feeSet.Kind == 2 { //固定比例
  142. feeSerValue = amountValue.Mul(feeSerValue.Div(decimal.NewFromInt(100)))
  143. fee = amountValue.Mul(feeSerValue.Div(decimal.NewFromInt(100))).String()
  144. }
  145. fee = feeSerValue.String()
  146. realAmount = amountValue.Sub(feeSerValue).String()
  147. }
  148. //10、判断是否为自动提现
  149. if withdrawSetting.IsAuto > 0 {
  150. autoAmountLimit, _ := decimal.NewFromString(withdrawSetting.IsAutoAmountLimit)
  151. if amountValue.LessThanOrEqual(autoAmountLimit) {
  152. isAuto = true
  153. }
  154. }
  155. if utils.StrToFloat64(realAmount) <= 0 {
  156. return errors.New("当前提现金额有误"), realAmount, fee, isAuto, isFirst
  157. }
  158. return
  159. }
  160. func GetWithdrawCondition(user *model.User, setting *model.FinWithdrawSetting, isFirst bool) md2.GetWithdrawConditionResp {
  161. resp := md2.GetWithdrawConditionResp{
  162. IsCanWithdraw: true,
  163. IsBindAlipay: false,
  164. IsBindWx: false,
  165. }
  166. now := time.Now()
  167. // 1.判断是否需要实名
  168. switch setting.IsRealName {
  169. case 0:
  170. resp.IsNeedRealName = false
  171. case 1:
  172. resp.IsNeedRealName = true
  173. default:
  174. resp.IsNeedRealName = true
  175. }
  176. // 2.判断是否实名
  177. switch user.IsRealName {
  178. case 0:
  179. resp.IsRealName = false
  180. if resp.IsNeedRealName {
  181. // 2.1 需要实名但未实名
  182. resp.IsCanWithdraw = false
  183. resp.NotWithdrawReason = enum.FinWithdrawApplyWithdrawConditionDissatisfyKind.
  184. String(enum.FinWithdrawApplyWithdrawConditionDissatisfyKindNotRealName)
  185. }
  186. case 1:
  187. resp.IsRealName = true
  188. default:
  189. resp.IsRealName = false
  190. }
  191. // 3. 首次提现判断
  192. if isFirst {
  193. resp.IsFirst = true
  194. resp.IsCanWithdraw = true
  195. resp.NotWithdrawReason = ""
  196. var firstWithdrawSet md.FirstWithdrawSet
  197. utils.Unserialize([]byte(setting.FirstWithdrawSet), &firstWithdrawSet)
  198. resp.FirstNeedRealName = func(firstWithdrawSetIsNeedRealName int) bool {
  199. if firstWithdrawSet.IsNeedRealName == 1 {
  200. return true
  201. }
  202. return false
  203. }(firstWithdrawSet.IsNeedRealName)
  204. resp.FirstWithdrawAmountLimit = firstWithdrawSet.FirstWithdrawAmountLimit
  205. } else {
  206. // 4. 验证会员等级
  207. if setting.VipLevelLimit > 0 && setting.VipLevelLimit > user.Level {
  208. resp.IsCanWithdraw = false
  209. resp.NotWithdrawReason = enum.FinWithdrawApplyWithdrawConditionDissatisfyKind.
  210. String(enum.FinWithdrawApplyWithdrawConditionDissatisfyKindNotEnoughLevel)
  211. }
  212. //5、验证“提现频率”
  213. var frequency md.WithdrawFrequencySettingStruct
  214. utils.Unserialize([]byte(setting.FrequencySet), &frequency)
  215. if frequency.Duration == 2 {
  216. day := now.Weekday()
  217. if !utils.InArr(utils.IntToStr(int(day)), frequency.Num) {
  218. resp.IsCanWithdraw = false
  219. resp.NotWithdrawReason = "非可提现日期"
  220. }
  221. }
  222. if frequency.Duration == 3 {
  223. day := now.Day()
  224. if !utils.InArr(utils.IntToStr(day), frequency.Num) {
  225. resp.IsCanWithdraw = false
  226. resp.NotWithdrawReason = "非可提现日期"
  227. }
  228. }
  229. if setting.WithdrawNumsLimit > 0 {
  230. var withdrawNums int64
  231. var startOfDay, endOfDay time.Time
  232. if frequency.Duration == 1 { //按天
  233. startOfDay = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
  234. endOfDay = startOfDay.Add(24 * time.Hour)
  235. }
  236. if frequency.Duration == 2 { //按周
  237. startOfDay = utils.GetStartOfWeek(now)
  238. endOfDay = startOfDay.Add(7 * 24 * time.Hour)
  239. }
  240. if frequency.Duration == 3 { //按月
  241. startOfDay = utils.GetFirstDateOfMonth(now)
  242. endOfDay = utils.GetLastDateOfMonth(now)
  243. }
  244. withdrawNums, err := db.Db.Where("create_at >= ?", startOfDay.Format("2006-01-02 15:04:05")).
  245. And("create_at < ?", endOfDay.Format("2006-01-02 15:04:05")).
  246. And("uid =?", user.Id).
  247. And("state != 3"). //失败不计入
  248. Count(&model.FinWithdrawApply{})
  249. if err != nil {
  250. resp.IsCanWithdraw = false
  251. resp.NotWithdrawReason = err.Error()
  252. }
  253. if int(withdrawNums) >= setting.WithdrawNumsLimit {
  254. resp.IsCanWithdraw = false
  255. resp.NotWithdrawReason = "当前已无可提现次数"
  256. }
  257. }
  258. }
  259. //6、验证时段
  260. if setting.WithdrawTimeInterval != "" {
  261. withdrawTimeInterval := strings.Split(setting.WithdrawTimeInterval, "-")
  262. // 定义要比较的时间格式
  263. layout := "15:04"
  264. // 解析给定的时间字符串
  265. start, _ := time.Parse(layout, withdrawTimeInterval[0])
  266. end, _ := time.Parse(layout, withdrawTimeInterval[1])
  267. // 设置为今天的日期
  268. start = time.Date(now.Year(), now.Month(), now.Day(), start.Hour(), start.Minute(), 0, 0, now.Location())
  269. end = time.Date(now.Year(), now.Month(), now.Day(), end.Hour(), end.Minute(), 0, 0, now.Location())
  270. // 如果结束时间小于开始时间,说明跨天了
  271. if end.Before(start) {
  272. if !(now.After(start) || now.Before(end)) {
  273. resp.IsCanWithdraw = false
  274. resp.NotWithdrawReason = enum.FinWithdrawApplyWithdrawConditionDissatisfyKind.
  275. String(enum.FinWithdrawApplyWithdrawConditionDissatisfyKindNotInTime)
  276. }
  277. } else { // 否则,在同一天内比较
  278. if !(now.After(start) && now.Before(end)) {
  279. resp.IsCanWithdraw = false
  280. resp.NotWithdrawReason = enum.FinWithdrawApplyWithdrawConditionDissatisfyKind.
  281. String(enum.FinWithdrawApplyWithdrawConditionDissatisfyKindNotInTime)
  282. }
  283. }
  284. }
  285. return resp
  286. }