附近小店
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.

svc_order.go 19 KiB

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