附近小店
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 

724 рядки
21 KiB

  1. package svc
  2. import (
  3. "applet/app/db"
  4. "applet/app/db/model"
  5. "applet/app/e"
  6. "applet/app/enum"
  7. "applet/app/md"
  8. "applet/app/utils"
  9. "applet/app/utils/cache"
  10. "encoding/json"
  11. "errors"
  12. "fmt"
  13. "github.com/gin-gonic/gin"
  14. "github.com/shopspring/decimal"
  15. "time"
  16. "xorm.io/xorm"
  17. )
  18. func OrderCate(c *gin.Context) {
  19. var cate = []map[string]string{
  20. {"name": "全部", "value": ""},
  21. {"name": "待付款", "value": "0"},
  22. {"name": "待提货", "value": "1"},
  23. {"name": "已完成", "value": "2"},
  24. {"name": "已取消", "value": "3"},
  25. }
  26. e.OutSuc(c, cate, nil)
  27. return
  28. }
  29. func OrderList(c *gin.Context) {
  30. var arg map[string]string
  31. if err := c.ShouldBindJSON(&arg); err != nil {
  32. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  33. return
  34. }
  35. user := GetUser(c)
  36. arg["uid"] = utils.IntToStr(user.Info.Uid)
  37. data := db.GetOrderList(MasterDb(c), arg)
  38. var state = []string{"待付款", "待提货", "已完成", "已取消"}
  39. list := make([]map[string]interface{}, 0)
  40. if data != nil {
  41. now := time.Now().Unix()
  42. for _, v := range *data {
  43. store := db.GetStoreIdEg(MasterDb(c), utils.IntToStr(v.StoreUid))
  44. info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(v.Oid))
  45. goodsInfo := make([]map[string]string, 0)
  46. if info != nil {
  47. for _, v1 := range *info {
  48. tmp := map[string]string{
  49. "img": v1.Img,
  50. "title": v1.Title,
  51. "sku_str": "",
  52. }
  53. skuData := make([]md.Sku, 0)
  54. json.Unmarshal([]byte(v1.SkuInfo), &skuData)
  55. skuStr := ""
  56. for _, v2 := range skuData {
  57. if skuStr != "" {
  58. skuStr += ";"
  59. }
  60. skuStr += v2.Value
  61. }
  62. tmp["sku_str"] = skuStr
  63. goodsInfo = append(goodsInfo, tmp)
  64. }
  65. }
  66. downTime := "0"
  67. if v.State == 0 {
  68. downTime = utils.IntToStr(int(v.CreateAt.Unix() + 15*60 - now))
  69. if now > v.CreateAt.Unix()+15*60 {
  70. v.State = 3
  71. }
  72. if utils.StrToInt(downTime) < 0 {
  73. downTime = "0"
  74. }
  75. }
  76. storeName := ""
  77. if store != nil {
  78. storeName = store.Name
  79. }
  80. tmp := map[string]interface{}{
  81. "oid": utils.Int64ToStr(v.Oid),
  82. "label": "自提",
  83. "state": utils.IntToStr(v.State),
  84. "state_str": state[v.State],
  85. "store_name": storeName,
  86. "goods_info": goodsInfo,
  87. "amount": v.Amount,
  88. "num": utils.IntToStr(v.Num),
  89. "timer": "",
  90. "code": v.Code,
  91. "down_time": downTime,
  92. }
  93. if v.Type == 1 {
  94. tmp["label"] = "外卖"
  95. }
  96. if v.IsNow == 1 {
  97. tmp["timer"] = "立即提货"
  98. } else if v.Timer != "" {
  99. tmp["timer"] = "提货时间:" + v.Timer
  100. }
  101. list = append(list, tmp)
  102. }
  103. }
  104. e.OutSuc(c, list, nil)
  105. return
  106. }
  107. func OrderDetail(c *gin.Context) {
  108. var arg map[string]string
  109. if err := c.ShouldBindJSON(&arg); err != nil {
  110. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  111. return
  112. }
  113. data := db.GetOrderEg(MasterDb(c), arg["oid"])
  114. var state = []string{"待付款", "待提货", "已完成", "已取消"}
  115. now := time.Now().Unix()
  116. store := db.GetStoreIdEg(MasterDb(c), utils.IntToStr(data.StoreUid))
  117. downTime := "0"
  118. if data.State == 0 {
  119. downTime = utils.IntToStr(int(data.CreateAt.Unix() + 15*60 - now))
  120. if now > data.CreateAt.Unix()+15*60 {
  121. data.State = 3
  122. }
  123. if utils.StrToInt(downTime) < 0 {
  124. downTime = "0"
  125. }
  126. }
  127. storeName := ""
  128. storeAddress := ""
  129. lat := ""
  130. lng := ""
  131. km := ""
  132. if store != nil {
  133. storeName = store.Name
  134. storeAddress = store.Address
  135. lat = store.Lat
  136. lng = store.Lng
  137. km = ""
  138. if arg["lat"] != "" && arg["lng"] != "" {
  139. km1 := utils.CalculateDistance(utils.StrToFloat64(lat), utils.StrToFloat64(lng), utils.StrToFloat64(arg["lat"]), utils.StrToFloat64(arg["lng"]))
  140. if km1 < 1 {
  141. km = utils.Float64ToStr(km1*1000) + "m"
  142. } else {
  143. km = utils.Float64ToStr(km1) + "km"
  144. }
  145. }
  146. }
  147. confirmAt := ""
  148. if data.ConfirmAt.IsZero() == false {
  149. confirmAt = data.ConfirmAt.Format("2006-01-02 15:04:05")
  150. }
  151. payMethod := "-"
  152. if data.PayMethod > 0 {
  153. payMethod = md.PayMethodIdToName[data.PayMethod]
  154. }
  155. orderInfo := []map[string]string{
  156. {"title": "订单编号", "content": utils.Int64ToStr(data.Oid)},
  157. {"title": "下单时间", "content": data.CreateAt.Format("2006-01-02 15:04:05")},
  158. {"title": "提货时间", "content": confirmAt},
  159. {"title": "预留电话", "content": data.Phone},
  160. {"title": "支付方式", "content": payMethod},
  161. {"title": "备注信息", "content": data.Memo},
  162. }
  163. goodsInfo := make([]map[string]string, 0)
  164. info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(data.Oid))
  165. if info != nil {
  166. for _, v := range *info {
  167. tmp := map[string]string{
  168. "img": v.Img,
  169. "title": v.Title,
  170. "price": v.Price,
  171. "num": utils.IntToStr(v.Num),
  172. "sku_str": "",
  173. }
  174. skuData := make([]md.Sku, 0)
  175. json.Unmarshal([]byte(v.SkuInfo), &skuData)
  176. skuStr := ""
  177. for _, v1 := range skuData {
  178. if skuStr != "" {
  179. skuStr += ";"
  180. }
  181. skuStr += v1.Value
  182. }
  183. tmp["sku_str"] = skuStr
  184. goodsInfo = append(goodsInfo, tmp)
  185. }
  186. }
  187. tmp := map[string]interface{}{
  188. "oid": utils.Int64ToStr(data.Oid),
  189. "label": "自提",
  190. "state": utils.IntToStr(data.State),
  191. "state_str": state[data.State],
  192. "store_name": storeName,
  193. "store_address": storeAddress,
  194. "lat": lat,
  195. "lng": lng,
  196. "km": km,
  197. "amount": data.Amount,
  198. "num": utils.IntToStr(data.Num),
  199. "timer": "",
  200. "code": data.Code,
  201. "down_time": downTime,
  202. "order_info": orderInfo,
  203. "goods_info": goodsInfo,
  204. "goods_count": utils.IntToStr(len(goodsInfo)),
  205. }
  206. if data.Type == 1 {
  207. tmp["label"] = "外卖"
  208. }
  209. if data.IsNow == 1 {
  210. tmp["timer"] = "立即提货"
  211. } else if data.Timer != "" {
  212. tmp["timer"] = data.Timer
  213. }
  214. e.OutSuc(c, tmp, nil)
  215. return
  216. }
  217. func OrderCoupon(c *gin.Context) {
  218. var arg md.OrderTotal
  219. if err := c.ShouldBindJSON(&arg); err != nil {
  220. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  221. return
  222. }
  223. totalPrice := commGoods(c, arg)
  224. returnData := CommCoupon(c, totalPrice)
  225. e.OutSuc(c, returnData, nil)
  226. return
  227. }
  228. func CommCoupon(c *gin.Context, totalPrice string) map[string]interface{} {
  229. var err error
  230. engine := MasterDb(c)
  231. user := GetUser(c)
  232. now := time.Now().Format("2006-01-02 15:04:05")
  233. var ActCouponUserList []*model.CommunityTeamCouponUser
  234. sess := engine.
  235. Where("store_type=? and uid = ? AND is_use = ? AND (valid_time_start < ? AND valid_time_end > ?)", 0,
  236. user.Info.Uid, 1, now, now)
  237. err = sess.Limit(100).OrderBy("valid_time_end asc,id asc").Find(&ActCouponUserList)
  238. if err != nil {
  239. return map[string]interface{}{}
  240. }
  241. var ids = make([]int, 0)
  242. for _, v := range ActCouponUserList {
  243. ids = append(ids, v.MerchantSchemeId)
  244. }
  245. var merchantScheme []model.CommunityTeamCoupon
  246. engine.In("id", ids).Find(&merchantScheme)
  247. var merchantSchemeMap = make(map[int]model.CommunityTeamCoupon)
  248. for _, v := range merchantScheme {
  249. merchantSchemeMap[v.Id] = v
  250. }
  251. couponList := make([]md.CouponList, 0)
  252. notCouponList := make([]md.CouponList, 0)
  253. count := 0
  254. for _, item := range ActCouponUserList {
  255. var coupon = md.CouponList{
  256. Id: utils.Int64ToStr(item.Id),
  257. Title: item.Name,
  258. Timer: item.ValidTimeStart.Format("2006.01.02") + "-" + item.ValidTimeEnd.Format("2006.01.02"),
  259. Label: "全部商品可用",
  260. Img: item.Img,
  261. Content: item.Info,
  262. IsCanUse: "0",
  263. NotUseStr: "",
  264. }
  265. var cal struct {
  266. Reach string `json:"reach"`
  267. Reduce string `json:"reduce"`
  268. }
  269. err = json.Unmarshal([]byte(item.Cal), &cal)
  270. if err != nil {
  271. return map[string]interface{}{}
  272. }
  273. switch item.Kind {
  274. case int(enum.ActCouponTypeImmediate):
  275. if utils.AnyToFloat64(totalPrice) >= utils.AnyToFloat64(cal.Reduce) {
  276. coupon.IsCanUse = "1"
  277. }
  278. case int(enum.ActCouponTypeReachReduce):
  279. if utils.AnyToFloat64(totalPrice) >= utils.AnyToFloat64(cal.Reduce) {
  280. coupon.IsCanUse = "1"
  281. }
  282. case int(enum.ActCouponTypeReachDiscount):
  283. if utils.AnyToFloat64(totalPrice) >= utils.AnyToFloat64(cal.Reduce) && utils.AnyToFloat64(cal.Reduce) > 0 {
  284. coupon.IsCanUse = "1"
  285. }
  286. if utils.AnyToFloat64(cal.Reduce) == 0 {
  287. coupon.IsCanUse = "1"
  288. }
  289. }
  290. if coupon.IsCanUse != "1" {
  291. coupon.NotUseStr = "订单金额未满" + cal.Reduce + "元"
  292. }
  293. if coupon.IsCanUse == "1" {
  294. count++
  295. couponList = append(couponList, coupon)
  296. } else {
  297. notCouponList = append(notCouponList, coupon)
  298. }
  299. }
  300. for _, v := range notCouponList {
  301. couponList = append(couponList, v)
  302. }
  303. returnData := map[string]interface{}{
  304. "total": utils.IntToStr(count),
  305. "coupon_list": couponList,
  306. }
  307. return returnData
  308. }
  309. func OrderCancel(c *gin.Context) {
  310. var arg map[string]string
  311. if err := c.ShouldBindJSON(&arg); err != nil {
  312. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  313. return
  314. }
  315. // 加锁 防止并发提取
  316. mutexKey := fmt.Sprintf("%s:team.OrderCancel:%s", c.GetString("mid"), arg["oid"])
  317. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  318. if err != nil {
  319. e.OutErr(c, e.ERR, err)
  320. return
  321. }
  322. if withdrawAvailable != "OK" {
  323. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  324. return
  325. }
  326. sess := MasterDb(c).NewSession()
  327. defer sess.Close()
  328. sess.Begin()
  329. order := db.GetOrder(sess, arg["oid"])
  330. if order == nil {
  331. sess.Rollback()
  332. e.OutErr(c, 400, e.NewErr(400, "订单不存在"))
  333. return
  334. }
  335. if order.State == 0 {
  336. now := time.Now().Unix()
  337. if now > order.CreateAt.Unix()+15*60 {
  338. order.State = 3
  339. }
  340. }
  341. if order.State > 0 {
  342. sess.Rollback()
  343. e.OutErr(c, 400, e.NewErr(400, "订单不能取消"))
  344. return
  345. }
  346. orderInfo := db.GetOrderInfo(sess, arg["oid"])
  347. if orderInfo != nil {
  348. goodsMap := make(map[int]int)
  349. skuMap := make(map[int]int)
  350. for _, v := range *orderInfo {
  351. goodsMap[v.GoodsId] += v.Num
  352. skuMap[v.SkuId] += v.Num
  353. }
  354. for k, v := range goodsMap {
  355. sql := `update community_team_goods set stock=stock+%d where id=%d`
  356. sql = fmt.Sprintf(sql, v, k)
  357. _, err := db.QueryNativeStringWithSess(sess, sql)
  358. if err != nil {
  359. sess.Rollback()
  360. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  361. return
  362. }
  363. }
  364. for k, v := range skuMap {
  365. sql := `update community_team_sku set stock=stock+%d where sku_id=%d`
  366. sql = fmt.Sprintf(sql, v, k)
  367. _, err := db.QueryNativeStringWithSess(sess, sql)
  368. if err != nil {
  369. sess.Rollback()
  370. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  371. return
  372. }
  373. }
  374. }
  375. order.State = 3
  376. order.UpdateAt = time.Now()
  377. order.CancelAt = time.Now()
  378. update, err := sess.Where("id=?", order.Id).Cols("state,update_at,cancel_at").Update(order)
  379. if update == 0 || err != nil {
  380. sess.Rollback()
  381. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  382. return
  383. }
  384. if order.CouponId > 0 {
  385. update, err = sess.Where("id=?", order.CouponId).Cols("is_use").Update(&model.CommunityTeamCouponUser{IsUse: 0})
  386. if update == 0 || err != nil {
  387. sess.Rollback()
  388. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  389. return
  390. }
  391. }
  392. sess.Commit()
  393. e.OutSuc(c, "success", nil)
  394. return
  395. }
  396. func OrderConfirm(c *gin.Context) {
  397. var arg map[string]string
  398. if err := c.ShouldBindJSON(&arg); err != nil {
  399. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  400. return
  401. }
  402. // 加锁 防止并发提取
  403. mutexKey := fmt.Sprintf("%s:team.OrderConfirm:%s", c.GetString("mid"), arg["oid"])
  404. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  405. if err != nil {
  406. e.OutErr(c, e.ERR, err)
  407. return
  408. }
  409. if withdrawAvailable != "OK" {
  410. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  411. return
  412. }
  413. sess := MasterDb(c).NewSession()
  414. defer sess.Close()
  415. sess.Begin()
  416. order := db.GetOrder(sess, arg["oid"])
  417. if order == nil {
  418. sess.Rollback()
  419. e.OutErr(c, 400, e.NewErr(400, "订单不存在"))
  420. return
  421. }
  422. if order.State != 1 {
  423. sess.Rollback()
  424. e.OutErr(c, 400, e.NewErr(400, "订单不能确认收货"))
  425. return
  426. }
  427. order.State = 2
  428. order.UpdateAt = time.Now()
  429. order.ConfirmAt = time.Now()
  430. update, err := sess.Where("id=?", order.Id).Cols("state,confirm_at,update_at").Update(order)
  431. if update == 0 || err != nil {
  432. sess.Rollback()
  433. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  434. return
  435. }
  436. sess.Commit()
  437. e.OutSuc(c, "success", nil)
  438. return
  439. }
  440. func OrderCreate(c *gin.Context) {
  441. var arg md.OrderTotal
  442. if err := c.ShouldBindJSON(&arg); err != nil {
  443. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  444. return
  445. }
  446. user := GetUser(c)
  447. // 加锁 防止并发提取
  448. mutexKey := fmt.Sprintf("%s:team.OrderCreate:%s", c.GetString("mid"), utils.IntToStr(user.Info.Uid))
  449. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  450. if err != nil {
  451. e.OutErr(c, e.ERR, err)
  452. return
  453. }
  454. if withdrawAvailable != "OK" {
  455. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  456. return
  457. }
  458. sess := MasterDb(c).NewSession()
  459. defer sess.Close()
  460. err = sess.Begin()
  461. if err != nil {
  462. e.OutErr(c, 400, err.Error())
  463. return
  464. }
  465. totalPrice := commGoods(c, arg)
  466. coupon := "0"
  467. totalPrice, coupon, err = CouponProcess(c, sess, totalPrice, arg)
  468. if err != nil {
  469. sess.Rollback()
  470. e.OutErr(c, 400, err.Error())
  471. return
  472. }
  473. ordId := utils.OrderUUID(user.Info.Uid)
  474. // 获取店铺信息
  475. store := db.GetStoreId(sess, arg.StoreId)
  476. num := 0
  477. for _, item := range arg.GoodsInfo {
  478. num += utils.StrToInt(item.Num)
  479. }
  480. var order = &model.CommunityTeamOrder{
  481. Uid: user.Info.Uid,
  482. StoreUid: utils.StrToInt(arg.StoreId),
  483. Commission: utils.Float64ToStr(utils.FloatFormat(utils.AnyToFloat64(totalPrice)*(utils.AnyToFloat64(store.Commission)/100), 2)),
  484. CreateAt: time.Now(),
  485. UpdateAt: time.Now(),
  486. BuyPhone: arg.BuyPhone,
  487. Coupon: coupon,
  488. Num: num,
  489. IsNow: utils.StrToInt(arg.IsNow),
  490. Timer: arg.Timer,
  491. Memo: arg.Memo,
  492. Oid: utils.StrToInt64(ordId),
  493. Amount: totalPrice,
  494. MealNum: utils.StrToInt(arg.MealNum),
  495. }
  496. if utils.StrToFloat64(coupon) > 0 {
  497. order.CouponId = utils.StrToInt(arg.CouponId)
  498. }
  499. insert, err := sess.Insert(order)
  500. if insert == 0 || err != nil {
  501. sess.Rollback()
  502. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  503. return
  504. }
  505. for _, item := range arg.GoodsInfo {
  506. // 获取详细信息
  507. goodsInterface, has, err := db.GetComm(MasterDb(c), &model.CommunityTeamGoods{Id: utils.StrToInt(item.GoodsId)})
  508. if err != nil || !has {
  509. sess.Rollback()
  510. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  511. return
  512. }
  513. goodsModel := goodsInterface.(*model.CommunityTeamGoods)
  514. var skuInterface interface{}
  515. if item.SkuId != "-1" {
  516. skuInterface, _, _ = db.GetComm(MasterDb(c), &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId), SkuId: utils.StrToInt64(item.SkuId)})
  517. } else {
  518. skuInterface, _, _ = db.GetComm(MasterDb(c), &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId)})
  519. }
  520. if err != nil || !has {
  521. sess.Rollback()
  522. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  523. return
  524. }
  525. skuModel := skuInterface.(*model.CommunityTeamSku)
  526. var goodsSaleCount int
  527. // 走普通逻辑
  528. stock := skuModel.Stock - utils.StrToInt(item.Num)
  529. saleCount := skuModel.SaleCount + utils.StrToInt(item.Num)
  530. goodsSaleCount = goodsModel.SaleCount + utils.StrToInt(item.Num)
  531. if stock < 0 {
  532. sess.Rollback()
  533. e.OutErr(c, 400, e.NewErr(400, "库存不足"))
  534. return
  535. }
  536. update, err := sess.Where("sku_id=?", skuModel.SkuId).Cols("stock", "sale_count").Update(&model.CommunityTeamSku{Stock: stock, SaleCount: saleCount})
  537. if err != nil {
  538. sess.Rollback()
  539. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  540. return
  541. }
  542. if update != 1 {
  543. sess.Rollback()
  544. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  545. return
  546. }
  547. // 更新销量
  548. goodsModel.SaleCount = goodsSaleCount
  549. goodsModel.Stock = goodsModel.Stock - utils.StrToInt(item.Num)
  550. _, err = sess.Where("id = ?", goodsModel.Id).Cols("sale_count,stock").Update(goodsModel)
  551. if err != nil {
  552. sess.Rollback()
  553. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  554. return
  555. }
  556. // 插入订单
  557. insert, err := sess.Insert(&model.CommunityTeamOrderInfo{
  558. Oid: utils.StrToInt64(ordId),
  559. Title: goodsModel.Title,
  560. Img: goodsModel.Img,
  561. Price: skuModel.Price,
  562. Num: utils.StrToInt(item.Num),
  563. SkuInfo: skuModel.Sku,
  564. GoodsId: skuModel.GoodsId,
  565. SkuId: int(skuModel.SkuId),
  566. })
  567. if err != nil {
  568. sess.Rollback()
  569. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  570. return
  571. }
  572. if insert != 1 {
  573. sess.Rollback()
  574. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  575. return
  576. }
  577. }
  578. // 更新优惠券使用状态
  579. if utils.StrToInt(arg.CouponId) > 0 {
  580. affect, err := sess.Where("id = ?", arg.CouponId).
  581. Update(&model.CommunityTeamCouponUser{IsUse: 1})
  582. if err != nil {
  583. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  584. return
  585. }
  586. if affect != 1 {
  587. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  588. return
  589. }
  590. }
  591. err = sess.Commit()
  592. if err != nil {
  593. sess.Rollback()
  594. e.OutErr(c, 400, err.Error())
  595. return
  596. }
  597. sess.Commit()
  598. e.OutSuc(c, map[string]string{"oid": ordId}, nil)
  599. return
  600. }
  601. func OrderTotal(c *gin.Context) {
  602. var arg md.OrderTotal
  603. if err := c.ShouldBindJSON(&arg); err != nil {
  604. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  605. return
  606. }
  607. sess := MasterDb(c).NewSession()
  608. defer sess.Close()
  609. err := sess.Begin()
  610. if err != nil {
  611. e.OutErr(c, 400, err.Error())
  612. return
  613. }
  614. totalPrice := commGoods(c, arg)
  615. oldTotalPrice := totalPrice
  616. coupon := "0"
  617. totalPrice, coupon, err = CouponProcess(c, sess, totalPrice, arg)
  618. if err != nil {
  619. sess.Rollback()
  620. e.OutErr(c, 400, err.Error())
  621. return
  622. }
  623. user := GetUser(c)
  624. result := map[string]interface{}{
  625. "balance_money": GetCommissionPrec(c, user.Profile.FinValid, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  626. "small_amount": GetCommissionPrec(c, oldTotalPrice, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  627. "all_amount": GetCommissionPrec(c, totalPrice, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  628. "coupon": GetCommissionPrec(c, coupon, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  629. }
  630. sess.Commit()
  631. e.OutSuc(c, result, nil)
  632. return
  633. }
  634. func CouponProcess(c *gin.Context, sess *xorm.Session, total string, args md.OrderTotal) (string, string, error) {
  635. if utils.StrToInt(args.CouponId) == 0 {
  636. return total, "0", nil
  637. }
  638. now := time.Now().Format("2006-01-02 15:04:05")
  639. user := GetUser(c)
  640. var goodsIds []int
  641. var skuIds []string
  642. for _, item := range args.GoodsInfo {
  643. goodsIds = append(goodsIds, utils.StrToInt(item.GoodsId))
  644. skuIds = append(skuIds, utils.AnyToString(item.SkuId))
  645. }
  646. // 获取优惠券信息
  647. var mallUserCoupon model.CommunityTeamCouponUser
  648. isExist, err := sess.
  649. Where("id = ? AND uid = ? AND is_use = ? AND (valid_time_start < ? AND valid_time_end > ?)", args.CouponId, user.Info.Uid, 1, now, now).
  650. Get(&mallUserCoupon)
  651. if err != nil {
  652. return "", "", err
  653. }
  654. if !isExist {
  655. return "", "", errors.New("无相关优惠券信息")
  656. }
  657. var cal struct {
  658. Reach string `json:"reach"`
  659. Reduce string `json:"reduce"`
  660. }
  661. _ = json.Unmarshal([]byte(mallUserCoupon.Cal), &cal)
  662. reach, err := decimal.NewFromString(cal.Reach)
  663. reduce, err := decimal.NewFromString(cal.Reduce)
  664. if err != nil {
  665. return "", "", err
  666. }
  667. var specialTotal = total
  668. // 是否满足优惠条件
  669. if !reach.IsZero() { // 满减及有门槛折扣
  670. if utils.StrToFloat64(specialTotal) < utils.StrToFloat64(reach.String()) {
  671. return "", "", errors.New("不满足优惠条件")
  672. }
  673. } else {
  674. if mallUserCoupon.Kind == 1 { //立减
  675. if utils.StrToFloat64(specialTotal) < utils.StrToFloat64(reduce.String()) {
  676. return "", "", errors.New("不满足优惠条件")
  677. }
  678. }
  679. }
  680. // 计算优惠后支付金额
  681. couponTotal := "0"
  682. if mallUserCoupon.Kind == int(enum.ActCouponTypeImmediate) ||
  683. mallUserCoupon.Kind == int(enum.ActCouponTypeReachReduce) { // 立减 || 满减
  684. couponTotal = reduce.String()
  685. total = utils.Float64ToStr(utils.StrToFloat64(total) - utils.StrToFloat64(reduce.String()))
  686. } else { // 折扣
  687. couponTotal = utils.Float64ToStr(utils.StrToFloat64(total) - utils.StrToFloat64(total)*utils.StrToFloat64(reduce.String())/10)
  688. total = utils.Float64ToStr(utils.StrToFloat64(total) * utils.StrToFloat64(reduce.String()) / 10)
  689. }
  690. return total, couponTotal, nil
  691. }
  692. func commGoods(c *gin.Context, arg md.OrderTotal) (totalPrice string) {
  693. engine := MasterDb(c)
  694. var totalPriceAmt float64 = 0
  695. for _, item := range arg.GoodsInfo {
  696. goodsInterface, _, _ := db.GetComm(engine, &model.CommunityTeamGoods{Id: utils.StrToInt(item.GoodsId)})
  697. goodsModel := goodsInterface.(*model.CommunityTeamGoods)
  698. var skuInterface interface{}
  699. if item.SkuId != "-1" {
  700. skuInterface, _, _ = db.GetComm(engine, &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId), SkuId: utils.StrToInt64(item.SkuId)})
  701. } else {
  702. skuInterface, _, _ = db.GetComm(engine, &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId)})
  703. }
  704. skuModel := skuInterface.(*model.CommunityTeamSku)
  705. priceOne := goodsModel.Price
  706. if item.SkuId != "-1" {
  707. priceOne = skuModel.Price
  708. }
  709. totalPriceAmt += utils.StrToFloat64(priceOne) * utils.StrToFloat64(item.Num)
  710. }
  711. return utils.Float64ToStr(totalPriceAmt)
  712. }