merchant.active.config.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. package shanghu
  2. import (
  3. "duoduo/apis/common"
  4. "duoduo/apis/pdd"
  5. "duoduo/apis/shanghu/models"
  6. "duoduo/models/shanghu"
  7. "duoduo/tools"
  8. "duoduo/tools/app"
  9. "encoding/base64"
  10. "encoding/json"
  11. "errors"
  12. "fmt"
  13. "github.com/gin-gonic/gin"
  14. "github.com/go-pay/gopay"
  15. "github.com/go-pay/gopay/wechat"
  16. "github.com/shopspring/decimal"
  17. "math/rand"
  18. "strconv"
  19. "time"
  20. )
  21. // 一个活动对应一个抽奖,一个抽奖对应多个奖品
  22. // 一个活动对应多个拼团,一个拼团对应一个张主图,一个拼团对应多个商品(多个商品是为了核销)
  23. func ActiveConfigCreate(c *gin.Context) {
  24. var inData models.CreateActiveConfigRequest
  25. var sqlData shanghu.MerchantActiveConfig
  26. var drawProduct shanghu.MerchantActiveDrawProduct
  27. err := c.ShouldBindJSON(&inData)
  28. if err != nil {
  29. app.Error(c, 400, err, err.Error())
  30. return
  31. }
  32. if inData.DrawMode != 0 {
  33. if len(inData.DrawId) <= 0 {
  34. app.Error(c, 500, errors.New("奖品未配置"), "奖品未配置")
  35. return
  36. }
  37. //校验总概率 总概率相加不能大于100
  38. drawList, _, err := drawProduct.GetDrawProductListById(inData.DrawId)
  39. if err != nil {
  40. app.Error(c, 500, err, err.Error())
  41. return
  42. }
  43. sumOdds := 0
  44. for _, v := range drawList {
  45. sumOdds = sumOdds + v.DrawOdds
  46. }
  47. if sumOdds != 100 {
  48. app.Error(c, 500, errors.New("配置的总中奖率不满100%"), "配置的总中奖率不满100%")
  49. return
  50. }
  51. }
  52. if inData.GroupBuyMode == 0 && inData.DrawMode == 0 {
  53. app.Error(c, 500, errors.New("请选择抽奖与开团"), "请选择抽奖与开团")
  54. return
  55. }
  56. sqlData.ActivityEndTime, err = tools.TimeToInt64(inData.ActivityEndTime, "2006-01-02")
  57. if err != nil {
  58. app.Error(c, 400, err, err.Error())
  59. return
  60. }
  61. sqlData.ActivityStartTime, err = tools.TimeToInt64(inData.ActivityStartTime, "2006-01-02")
  62. if err != nil {
  63. app.Error(c, 400, err, err.Error())
  64. return
  65. }
  66. //必中校验
  67. //if inData.DrawOneBiZhong > 0 {
  68. // var checkBZ shanghu.MerchantActiveDrawProduct
  69. // checkBZ.ID = inData.DrawOneBiZhong
  70. // bZInfo, err := checkBZ.GetDrawProductById()
  71. // if err != nil {
  72. // app.Error(c, 500, err, err.Error())
  73. // return
  74. // }
  75. //
  76. // if !bZInfo.IsPrize { //
  77. // app.Error(c, 500, err, err.Error())
  78. // return
  79. // }
  80. //}
  81. sqlData.ActiveName = inData.ActiveName
  82. sqlData.MerchantOpenID = inData.MerchantOpenID
  83. sqlData.CreatedAt = time.Now()
  84. sqlData.UpdatedAt = time.Now()
  85. sqlData.ConfigMode = 1
  86. sqlData.DrawOneBiZhong = inData.DrawOneBiZhong
  87. sqlData.DrawMode = inData.DrawMode
  88. sqlData.GroupBuyMode = inData.GroupBuyMode
  89. sqlData.GroupBuyUrl = inData.GroupBuyUrl
  90. sqlData.GroupBuy = `{}`
  91. sqlData.DrawProduct = `{}`
  92. sqlData.BackgroundImage = inData.BackgroundImage
  93. configData, err := sqlData.Create()
  94. if err != nil {
  95. app.Error(c, 500, err, err.Error())
  96. return
  97. }
  98. for _, v := range inData.DrawId {
  99. var drawData shanghu.MerchantActiveDrawProduct
  100. drawData.ActiveConfigID = configData.ID
  101. err = drawData.UpdateConfigId(v)
  102. if err != nil {
  103. app.Error(c, 500, err, err.Error())
  104. return
  105. }
  106. }
  107. for _, v := range inData.GroupBuyId {
  108. var groupBuy shanghu.MerchantActiveGroupBuy
  109. groupBuy.ActiveConfigID = configData.ID
  110. err = groupBuy.UpdateConfigId(v)
  111. if err != nil {
  112. app.Error(c, 500, err, err.Error())
  113. return
  114. }
  115. }
  116. app.OK(c, nil, app.Success)
  117. }
  118. // 活动配置信息
  119. func ActiveConfigInfo(c *gin.Context) {
  120. var inData models.ActiveConfigRequest
  121. var sqlData shanghu.MerchantActiveConfig
  122. var outData models.ActiveConfigReply
  123. var drawInfoSql shanghu.MerchantActiveDrawProduct
  124. var groupBuy shanghu.MerchantActiveGroupBuy
  125. var merchant shanghu.Merchant
  126. err := c.ShouldBindJSON(&inData)
  127. if err != nil {
  128. app.Error(c, 400, err, err.Error())
  129. return
  130. }
  131. sqlData.MerchantOpenID = inData.MerchantOpenID
  132. sqlData.ID = inData.ActiveConfigId
  133. configInfo, err := sqlData.GetConfigInfoById()
  134. if err != nil {
  135. app.Error(c, 500, err, err.Error())
  136. return
  137. }
  138. outData.GroupBuyMode = configInfo.GroupBuyMode
  139. outData.DrawMode = configInfo.DrawMode
  140. outData.GroupBuyUrl = configInfo.GroupBuyUrl
  141. outData.DrawOneBiZhong = configInfo.DrawOneBiZhong
  142. outData.ActivityEndTime = tools.TimeToStr(configInfo.ActivityEndTime)
  143. outData.ActivityStartTime = tools.TimeToStr(configInfo.ActivityStartTime)
  144. outData.ActiveName = configInfo.ActiveName
  145. outData.BackgroundImage = configInfo.BackgroundImage
  146. //中奖商品
  147. drawInfoSql.ActiveConfigID = configInfo.ID
  148. drawInfo, _, err := drawInfoSql.GetDrawProductList()
  149. if err != nil {
  150. app.Error(c, 500, err, err.Error())
  151. return
  152. }
  153. for _, v := range drawInfo {
  154. var drawProduct models.DrawProduct
  155. drawProduct.DrawProductName = v.DrawProductName
  156. drawProduct.DrawUrl = v.DrawUrl
  157. drawProduct.DrawOdds = v.DrawOdds
  158. drawProduct.IsPrize = v.IsPrize
  159. drawProduct.TotalStock = v.TotalStock
  160. drawProduct.Stock = v.Stock
  161. outData.DrawProduct = append(outData.DrawProduct, drawProduct)
  162. }
  163. // 查询拼团列表
  164. groupBuy.ActiveConfigID = configInfo.ID
  165. groupBuyInfoList, _, err := groupBuy.GetGroupBuyList()
  166. if err != nil {
  167. app.Error(c, 500, err, err.Error())
  168. return
  169. }
  170. for _, v := range groupBuyInfoList {
  171. var groupBuyInfo models.DrawGroupBuy
  172. var groupBuyProject shanghu.MerchantActiveGroupByProject
  173. groupBuyInfo.GroupBuyName = v.GroupBuyName
  174. groupBuyInfo.GroupBuyMode = v.GroupBuyMode
  175. groupBuyInfo.GroupBuyUrl = v.GroupBuyUrl
  176. groupBuyInfo.GroupBuyThreeNum = v.GroupBuyThreeNum
  177. groupBuyInfo.GroupBuyThreePrice = v.GroupBuyThreePrice
  178. groupBuyInfo.GroupBuyFourNum = v.GroupBuyFourNum
  179. groupBuyInfo.GroupBuyFourPrice = v.GroupBuyFourPrice
  180. groupBuyInfo.GroupBuyTwoNum = v.GroupBuyTwoNum
  181. groupBuyInfo.GroupBuyTwoPrice = v.GroupBuyTwoPrice
  182. groupBuyInfo.GroupBuyOneNum = v.GroupBuyOneNum
  183. groupBuyInfo.GroupBuyOnePrice = v.GroupBuyOnePrice
  184. groupBuyInfo.MerchantOpenID = v.MerchantOpenID
  185. groupBuyInfo.OriginalPrice = v.OriginalPrice
  186. groupBuyInfo.RebateRate = v.RebateRate
  187. groupBuyProject.GroupBuyID = v.ID
  188. projectList, _, err := groupBuyProject.GetGroupBuyProjectList()
  189. if err != nil {
  190. app.Error(c, 500, err, err.Error())
  191. return
  192. }
  193. for _, v := range projectList {
  194. var groupBuyProjectInfo models.GroupBuyProject
  195. groupBuyProjectInfo.ProjectName = v.ProjectName
  196. groupBuyProjectInfo.CancelNum = v.CancelNum
  197. groupBuyInfo.GroupBuyProject = append(groupBuyInfo.GroupBuyProject, groupBuyProjectInfo)
  198. }
  199. outData.DrawGroupBuy = append(outData.DrawGroupBuy, groupBuyInfo)
  200. }
  201. merchant.OpenId = inData.MerchantOpenID
  202. merchantInfo, err := merchant.GetMerchant()
  203. if err != nil {
  204. app.Error(c, 500, err, err.Error())
  205. return
  206. }
  207. outData.MerchantName = merchantInfo.MerchantName
  208. app.OK(c, outData, app.Success)
  209. }
  210. // whxy
  211. func UpdateActiveConfigWHXY(c *gin.Context) {
  212. var inData models.ActiveConfigWHXYRequest
  213. var sqlData shanghu.MerchantActiveConfig
  214. var whxy []models.WHXYStr
  215. err := c.ShouldBindJSON(&inData)
  216. if err != nil {
  217. app.Error(c, 400, err, err.Error())
  218. return
  219. }
  220. err = json.Unmarshal([]byte(inData.WHXY), &whxy)
  221. if err != nil {
  222. app.Error(c, 400, err, err.Error())
  223. return
  224. }
  225. for i := 0; i < len(whxy); i++ {
  226. if !whxy[i].Y.IsZero() {
  227. sqlData.W = whxy[i].W.String()
  228. sqlData.X = whxy[i].X.String()
  229. sqlData.Y = whxy[i].Y.String()
  230. sqlData.H = whxy[i].H.String()
  231. }
  232. }
  233. sqlData.ID = inData.ActiveConfigId
  234. err = sqlData.UpdateMerchantWHXY()
  235. if err != nil {
  236. app.Error(c, 400, err, err.Error())
  237. return
  238. }
  239. app.OK(c, nil, app.Success)
  240. }
  241. // 活动列表
  242. func ActiveConfigList(c *gin.Context) {
  243. var inData models.ActiveConfigListRequest
  244. var sqlData shanghu.MerchantActiveConfig
  245. var outData []models.ActiveConfigListReply
  246. err := c.ShouldBindJSON(&inData)
  247. if err != nil {
  248. app.Error(c, 400, err, err.Error())
  249. return
  250. }
  251. sqlData.MerchantOpenID = inData.OpenId
  252. var pageSize = 10
  253. var pageIndex = 1
  254. if inData.PageSize != 0 {
  255. pageSize = inData.PageSize
  256. }
  257. if inData.PageIndex != 0 {
  258. pageIndex = inData.PageIndex
  259. }
  260. activeConfigList, count, err := sqlData.GetActiveConfigList(pageSize, pageIndex)
  261. if err != nil {
  262. app.Error(c, 500, err, err.Error())
  263. return
  264. }
  265. for _, v := range activeConfigList {
  266. var activeConfig models.ActiveConfigListReply
  267. activeConfig.ID = v.ID
  268. activeConfig.ActivityStart = tools.TimeToStr(v.ActivityStartTime)
  269. activeConfig.ActivityEnd = tools.TimeToStr(v.ActivityEndTime)
  270. activeConfig.ActiveName = v.ActiveName
  271. activeConfig.CreatedAt = v.CreatedAt.Format(time.DateTime)
  272. outData = append(outData, activeConfig)
  273. }
  274. app.PageOK(c, outData, count, pageIndex, pageSize, app.Success)
  275. }
  276. // 抽奖
  277. func Draw(c *gin.Context) {
  278. var inData models.DrawRequest
  279. var sqlData shanghu.MerchantActiveConfig
  280. var drawNumSql shanghu.ClientActiveDrawNum
  281. var draw shanghu.ClientActiveDrawLog
  282. var outData models.DrawReply
  283. err := c.ShouldBindJSON(&inData)
  284. if err != nil {
  285. app.Error(c, 400, err, err.Error())
  286. return
  287. }
  288. // 校验抽奖次数
  289. drawNumSql.ActiveConfigID = inData.ActiveConfigID
  290. drawNumSql.ClientOpenID = inData.ClientOpenID
  291. drawNum, err := drawNumSql.GetDrawNum()
  292. if err != nil {
  293. app.Error(c, 500, err, err.Error())
  294. return
  295. }
  296. //校验数量
  297. draw.ActiveConfigID = inData.ActiveConfigID
  298. draw.ClientOpenID = inData.ClientOpenID
  299. clientDrawNum, err := draw.GetClientActiveDrawLogNum()
  300. if err != nil {
  301. app.Error(c, 500, err, err.Error())
  302. return
  303. }
  304. if drawNum+1 < clientDrawNum {
  305. app.Error(c, 500, errors.New("抽奖次数用完"), "抽奖次数用完")
  306. return
  307. }
  308. // 先校验是否有必中抽奖
  309. sqlData.ID = inData.ActiveConfigID
  310. config, err := sqlData.GetConfigInfoById()
  311. if err != nil {
  312. app.Error(c, 500, err, err.Error())
  313. return
  314. }
  315. if config.DrawOneBiZhong > 0 {
  316. // 必中抽奖需要产看中奖记录是否中过,没有中过直接中,中过了走正常的中奖概率
  317. var drawConfig shanghu.ClientActiveDrawLog
  318. drawConfig.ActiveConfigID = inData.ActiveConfigID
  319. drawConfig.ClientOpenID = inData.ClientOpenID
  320. drawConfig.DrawProductID = config.DrawOneBiZhong
  321. count, err := drawConfig.GetClientActiveDrawLogByBiZHong()
  322. if err != nil {
  323. app.Error(c, 500, err, err.Error())
  324. return
  325. }
  326. // 为0直接中奖 写中奖记录并且返回 查询中奖
  327. if count == 0 {
  328. //var draw shanghu.ClientActiveDrawLog
  329. var drawProduct shanghu.MerchantActiveDrawProduct
  330. drawProduct.ID = config.DrawOneBiZhong
  331. drawProductInfo, err := drawProduct.GetDrawProductById()
  332. if err != nil {
  333. app.Error(c, 500, err, err.Error())
  334. return
  335. }
  336. if drawProductInfo.ActiveConfigID != inData.ActiveConfigID {
  337. app.Error(c, 500, errors.New("必中配置活动不一致"), "必中配置活动不一致")
  338. return
  339. }
  340. if drawProductInfo.Stock <= 0 {
  341. app.Error(c, 500, errors.New("库存不足"), "库存不足")
  342. return
  343. }
  344. fmt.Println(drawProductInfo)
  345. //新建log 减库存
  346. err = subStockAddLog(drawProductInfo, inData.ClientOpenID)
  347. if err != nil {
  348. app.Error(c, 500, err, err.Error())
  349. return
  350. }
  351. //draw.DrawProductID = config.DrawOneBiZhong
  352. //draw.ActiveConfigID = inData.ActiveConfigID
  353. //draw.ClientOpenID = inData.ClientOpenID
  354. //
  355. //if drawProductInfo.IsPrize {
  356. // draw.IsPrize = models.NotClaimed //未兑奖 必中一定是要能兑奖的。
  357. //} else {
  358. // draw.IsPrize = models.NotWon //未中奖
  359. //}
  360. //
  361. //draw.CreatedAt = time.Now()
  362. //draw.UpdatedAt = time.Now()
  363. //_, err = draw.Create() //创建完成
  364. //if err != nil {
  365. // app.Error(c, 500, err, err.Error())
  366. // return
  367. //}
  368. outData.DrawProductName = drawProductInfo.DrawProductName
  369. outData.DrawUrl = drawProductInfo.DrawUrl
  370. outData.ID = config.DrawOneBiZhong
  371. app.OK(c, outData, app.Success)
  372. return
  373. }
  374. }
  375. var drawProductList shanghu.MerchantActiveDrawProduct
  376. var prizeList []Prize
  377. drawProductList.ActiveConfigID = inData.ActiveConfigID
  378. drawProductInfo, _, err := drawProductList.GetDrawProductListByActiveId()
  379. if err != nil {
  380. app.Error(c, 500, err, err.Error())
  381. return
  382. }
  383. for _, v := range drawProductInfo {
  384. var prize Prize
  385. if v.Stock <= 0 {
  386. continue
  387. }
  388. prize.Name = v.DrawProductName
  389. prize.ID = v.ID
  390. prize.Weight = v.DrawOdds
  391. prize.InitStock = v.TotalStock
  392. prize.Stock = v.Stock
  393. prizeList = append(prizeList, prize)
  394. }
  395. //fmt.Println(prizeList)
  396. // 创建抽奖实例
  397. lottery := NewLottery(prizeList)
  398. // 执行1次抽奖
  399. results, err := lottery.Draw(1)
  400. if err != nil {
  401. app.Error(c, 500, err, err.Error())
  402. return
  403. }
  404. fmt.Println(results)
  405. var drawProduct shanghu.MerchantActiveDrawProduct
  406. for _, v := range drawProductInfo {
  407. if results[0].ID == v.ID {
  408. outData.ID = v.ID
  409. outData.DrawUrl = v.DrawUrl
  410. outData.DrawProductName = v.DrawProductName
  411. drawProduct = v
  412. break
  413. }
  414. }
  415. //库存减一 并且新增记录
  416. err = subStockAddLog(drawProduct, inData.ClientOpenID)
  417. if err != nil {
  418. app.Error(c, 500, err, err.Error())
  419. return
  420. }
  421. app.OK(c, outData, app.Success)
  422. }
  423. type Prize struct {
  424. ID int64 // 奖品ID
  425. Name string // 奖品名称
  426. Weight int // 权重
  427. Stock int // 库存数量
  428. InitStock int // 初始库存(用于展示)
  429. }
  430. // 带权重和库存的抽奖
  431. type Lottery struct {
  432. Prizes []Prize
  433. TotalWeight int
  434. }
  435. func NewLottery(prizes []Prize) *Lottery {
  436. totalWeight := 0
  437. for _, prize := range prizes {
  438. totalWeight += prize.Weight
  439. }
  440. // 深拷贝奖品列表并初始化初始库存
  441. prizeCopy := make([]Prize, len(prizes))
  442. for i, p := range prizes {
  443. prizeCopy[i] = p
  444. prizeCopy[i].InitStock = p.Stock
  445. }
  446. return &Lottery{
  447. Prizes: prizeCopy,
  448. TotalWeight: totalWeight,
  449. }
  450. }
  451. func (l *Lottery) Draw(times int) ([]Prize, error) {
  452. // 检查总库存是否足够
  453. totalStock := 0
  454. for _, prize := range l.Prizes {
  455. totalStock += prize.Stock
  456. }
  457. if totalStock < times {
  458. return nil, fmt.Errorf("剩余总库存(%d)不足以支持%d次抽奖", totalStock, times)
  459. }
  460. rand.Seed(time.Now().UnixNano())
  461. results := make([]Prize, 0, times)
  462. for i := 0; i < times; i++ {
  463. // 如果没有可用奖品了就停止
  464. if l.TotalWeight <= 0 {
  465. break
  466. }
  467. randNum := rand.Intn(l.TotalWeight)
  468. currentWeight := 0
  469. for j := range l.Prizes {
  470. if l.Prizes[j].Stock <= 0 {
  471. continue
  472. }
  473. currentWeight += l.Prizes[j].Weight
  474. if randNum < currentWeight {
  475. // 中奖
  476. results = append(results, l.Prizes[j])
  477. // 减少库存
  478. l.Prizes[j].Stock--
  479. // 如果库存耗尽,更新总权重
  480. if l.Prizes[j].Stock == 0 {
  481. l.TotalWeight -= l.Prizes[j].Weight
  482. }
  483. break
  484. }
  485. }
  486. }
  487. return results, nil
  488. }
  489. // 新建记录,减库存
  490. func subStockAddLog(drawProductInfo shanghu.MerchantActiveDrawProduct, clientOpenId string) error {
  491. var draw shanghu.ClientActiveDrawLog
  492. //var drawProduct shanghu.MerchantActiveDrawProduct
  493. if drawProductInfo.Stock <= 0 {
  494. return errors.New("库存不足")
  495. }
  496. //减库存
  497. err := drawProductInfo.SubStock()
  498. if err != nil {
  499. return err
  500. }
  501. // 新建记录
  502. draw.DrawProductID = drawProductInfo.ID
  503. draw.ActiveConfigID = drawProductInfo.ActiveConfigID
  504. draw.ClientOpenID = clientOpenId
  505. if drawProductInfo.IsPrize {
  506. draw.IsPrize = models.NotClaimed //未兑奖 必中一定是要能兑奖的。
  507. } else {
  508. draw.IsPrize = models.NotWon //未中奖
  509. }
  510. draw.CreatedAt = time.Now()
  511. draw.UpdatedAt = time.Now()
  512. _, err = draw.Create() //创建完成
  513. if err != nil {
  514. return err
  515. }
  516. return nil
  517. }
  518. func GetClientActiveQR(c *gin.Context) {
  519. var inData models.ClientActiveQRRequest
  520. //var sqlData shanghu.MerchantClientCard
  521. var outData models.ClientCardQRReply
  522. var qr models.QRRequest
  523. var getQR models.GetQRRequest
  524. err := c.ShouldBindJSON(&inData)
  525. if err != nil {
  526. app.Error(c, 400, err, err.Error())
  527. return
  528. }
  529. // sqlData.ID = inData.ActiveConfigId
  530. val, err := pdd.DuoDuoGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx8595c589dd736486&secret=668f87d2bc24199688e53ee8a88434b8")
  531. if err != nil {
  532. app.Error(c, 500, err, err.Error())
  533. return
  534. }
  535. err = tools.JsonUnmarshal(val, &outData)
  536. if err != nil {
  537. app.Error(c, 500, err, err.Error())
  538. return
  539. }
  540. if outData.AccessToken == "" {
  541. app.Error(c, 500, err, "token error")
  542. return
  543. }
  544. url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + outData.AccessToken
  545. qr.CheckPath = true
  546. qr.Page = "pages/home/home"
  547. qr.EnvVersion = "release"
  548. qr.Scene = strconv.FormatInt(inData.ActiveConfigId, 10)
  549. data, err := json.Marshal(&qr)
  550. if err != nil {
  551. app.Error(c, 500, err, err.Error())
  552. return
  553. }
  554. reply, err := common.Post(data, url)
  555. if err != nil {
  556. app.Error(c, 500, err, err.Error())
  557. return
  558. }
  559. //err = json.Unmarshal(reply, &getQR)
  560. //if err != nil {
  561. // app.Error(c, 500, err, err.Error())
  562. // return
  563. //}
  564. if getQR.Errcode != 0 {
  565. app.Error(c, 500, err, getQR.Errmsg)
  566. return
  567. }
  568. //fmt.Println(string(reply))
  569. encoded := base64.StdEncoding.EncodeToString(reply)
  570. app.OK(c, encoded, app.Success)
  571. }
  572. func GroupByUnifiedOrder(c *gin.Context) {
  573. var inData models.GroupBuyUnifiedOrderRequest
  574. var sqlData shanghu.ClientActivePayTrans
  575. var activeConfig shanghu.MerchantActiveConfig
  576. var outData models.GroupBuyUnifiedOrderReply
  577. err := c.ShouldBindJSON(&inData)
  578. if err != nil {
  579. app.Error(c, 400, err, err.Error())
  580. return
  581. }
  582. //校验活动id
  583. activeConfig.ID = inData.ActiveConfigId
  584. activeConfigInfo, err := activeConfig.GetConfigInfoById()
  585. if err != nil {
  586. app.Error(c, 400, err, err.Error())
  587. return
  588. }
  589. if activeConfigInfo.DrawMode != 1 { //虚拟开团
  590. app.Error(c, 500, errors.New("非虚拟开团,不允许下单"), "非虚拟开团,不允许下单.")
  591. return
  592. }
  593. if inData.ClientOpenId == "" {
  594. app.OK(c, nil, app.Success)
  595. return
  596. }
  597. //校验 防止同一笔记录存在
  598. sqlData.RequestID = inData.RequestId
  599. if sqlData.GetRequestNum() > 0 {
  600. app.Error(c, 400, errors.New("交易已存在"), "交易已存在")
  601. return
  602. }
  603. //校验金额
  604. //检查微信相关参数
  605. if !inData.Amount.GreaterThan(decimal.NewFromInt(0)) {
  606. app.Error(c, 400, errors.New("amount:金额必须大于0"), "amount:金额必须大于0")
  607. return
  608. }
  609. if inData.Amount.Round(2).String() != inData.Amount.String() {
  610. app.Error(c, 400, errors.New("total_fee:金额最多只能保留两位小数"), "total_fee:金额最多只能保留两位小数")
  611. return
  612. }
  613. //创建支付记录
  614. sqlData.ClientOpenID = inData.ClientOpenId
  615. sqlData.RequestID = inData.RequestId
  616. sqlData.CreatedAt = time.Now()
  617. sqlData.UpdatedAt = time.Now()
  618. sqlData.Amount = inData.Amount
  619. sqlData.OutTradeNo = strconv.FormatInt(inData.ActiveConfigId, 10) + strconv.FormatInt(time.Now().UnixNano(), 10)
  620. sqlData.Status = 1 //未支付
  621. sqlData.ActiveConfigID = inData.ActiveConfigId
  622. sqlData.InvitationCode = inData.InvitationCode
  623. _, err = sqlData.Create()
  624. if err != nil {
  625. app.Error(c, 400, err, "创建支付失败")
  626. return
  627. }
  628. fmt.Println(sqlData.OutTradeNo)
  629. bm := make(gopay.BodyMap)
  630. bm.Set("nonce_str", common.GetRandomString(32))
  631. bm.Set("body", "商户卡")
  632. bm.Set("out_trade_no", sqlData.OutTradeNo)
  633. bm.Set("total_fee", inData.Amount.Mul(decimal.NewFromInt(100)).IntPart())
  634. bm.Set("spbill_create_ip", "127.0.0.1")
  635. bm.Set("notify_url", "https://tao1024.com/v1/client/pay/callback")
  636. bm.Set("device_info", "WEB")
  637. bm.Set("trade_type", "JSAPI")
  638. bm.Set("sign_type", wechat.SignType_MD5)
  639. bm.Set("openid", inData.ClientOpenId)
  640. client := NewWechatService()
  641. //请求支付下单,成功后得到结果
  642. wxResp, err := client.UnifiedOrder(c, bm)
  643. if err != nil {
  644. app.Error(c, 400, err, "下单失败")
  645. return
  646. }
  647. if wxResp.ReturnCode != "SUCCESS" {
  648. app.Error(c, 400, errors.New(wxResp.ReturnMsg), "下单失败")
  649. return
  650. }
  651. if wxResp.ResultCode != "SUCCESS" {
  652. app.Error(c, 400, errors.New(wxResp.ErrCode+"--"+wxResp.ErrCodeDes), "下单失败")
  653. return
  654. }
  655. timestamp := strconv.FormatInt(time.Now().Unix(), 10)
  656. pac := "prepay_id=" + wxResp.PrepayId
  657. paySign := wechat.GetMiniPaySign("wx8595c589dd736486", wxResp.NonceStr, pac, wechat.SignType_MD5, timestamp, "33c424fAa69942086f82A003e283E9C8")
  658. outData.Timestamp = timestamp
  659. outData.NonceStr = wxResp.NonceStr
  660. outData.Package = pac
  661. outData.PaySign = paySign
  662. outData.SignType = wechat.SignType_MD5
  663. //merchant, count, err := sqlData.GetOpenIdList(pageSize, pageIndex)
  664. //if err != nil {
  665. // app.Error(c, 500, err, err.Error())
  666. // return
  667. //}
  668. app.OK(c, outData, app.Success)
  669. }
  670. func Pay(c *gin.Context) {
  671. // 获取参数
  672. //
  673. }