附近小店
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

svc_order.go 20 KiB

2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
2 miesięcy temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  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.Table("act_coupon_user").
  235. Where("store_type=? and uid = ? AND is_use = ? AND (valid_time_start < ? AND valid_time_end > ?)", 0,
  236. user.Info.Uid, 0, now, now)
  237. err = sess.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. var couponList []md.CouponList // 可使用的
  252. couponList = 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.ActivityStatement,
  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. }
  296. couponList = append(couponList, coupon)
  297. }
  298. returnData := map[string]interface{}{
  299. "total": utils.IntToStr(count),
  300. "coupon_list": couponList,
  301. }
  302. return returnData
  303. }
  304. func OrderCancel(c *gin.Context) {
  305. var arg map[string]string
  306. if err := c.ShouldBindJSON(&arg); err != nil {
  307. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  308. return
  309. }
  310. // 加锁 防止并发提取
  311. mutexKey := fmt.Sprintf("%s:team.OrderCancel:%s", c.GetString("mid"), arg["oid"])
  312. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  313. if err != nil {
  314. e.OutErr(c, e.ERR, err)
  315. return
  316. }
  317. if withdrawAvailable != "OK" {
  318. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  319. return
  320. }
  321. sess := MasterDb(c).NewSession()
  322. defer sess.Close()
  323. sess.Begin()
  324. order := db.GetOrder(sess, arg["oid"])
  325. if order == nil {
  326. sess.Rollback()
  327. e.OutErr(c, 400, e.NewErr(400, "订单不存在"))
  328. return
  329. }
  330. if order.State == 0 {
  331. now := time.Now().Unix()
  332. if now > order.CreateAt.Unix()+15*60 {
  333. order.State = 3
  334. }
  335. }
  336. if order.State > 0 {
  337. sess.Rollback()
  338. e.OutErr(c, 400, e.NewErr(400, "订单不能取消"))
  339. return
  340. }
  341. orderInfo := db.GetOrderInfo(sess, arg["oid"])
  342. if orderInfo != nil {
  343. goodsMap := make(map[int]int)
  344. skuMap := make(map[int]int)
  345. for _, v := range *orderInfo {
  346. goodsMap[v.GoodsId] += v.Num
  347. skuMap[v.SkuId] += v.Num
  348. }
  349. for k, v := range goodsMap {
  350. sql := `update community_team_goods set stock=stock+%d where id=%d`
  351. sql = fmt.Sprintf(sql, v, k)
  352. _, err := db.QueryNativeStringWithSess(sess, sql)
  353. if err != nil {
  354. sess.Rollback()
  355. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  356. return
  357. }
  358. }
  359. for k, v := range skuMap {
  360. sql := `update community_team_sku set stock=stock+%d where sku_id=%d`
  361. sql = fmt.Sprintf(sql, v, k)
  362. _, err := db.QueryNativeStringWithSess(sess, sql)
  363. if err != nil {
  364. sess.Rollback()
  365. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  366. return
  367. }
  368. }
  369. }
  370. order.State = 3
  371. order.UpdateAt = time.Now()
  372. order.CancelAt = time.Now()
  373. update, err := sess.Where("id=?", order.Id).Cols("state,update_at,cancel_at").Update(order)
  374. if update == 0 || err != nil {
  375. sess.Rollback()
  376. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  377. return
  378. }
  379. if order.CouponId > 0 {
  380. update, err = sess.Where("id=?", order.CouponId).Cols("is_use").Update(&model.CommunityTeamCouponUser{IsUse: 0})
  381. if update == 0 || err != nil {
  382. sess.Rollback()
  383. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  384. return
  385. }
  386. }
  387. sess.Commit()
  388. e.OutSuc(c, "success", nil)
  389. return
  390. }
  391. func OrderConfirm(c *gin.Context) {
  392. var arg map[string]string
  393. if err := c.ShouldBindJSON(&arg); err != nil {
  394. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  395. return
  396. }
  397. // 加锁 防止并发提取
  398. mutexKey := fmt.Sprintf("%s:team.OrderConfirm:%s", c.GetString("mid"), arg["oid"])
  399. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  400. if err != nil {
  401. e.OutErr(c, e.ERR, err)
  402. return
  403. }
  404. if withdrawAvailable != "OK" {
  405. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  406. return
  407. }
  408. sess := MasterDb(c).NewSession()
  409. defer sess.Close()
  410. sess.Begin()
  411. order := db.GetOrder(sess, arg["oid"])
  412. if order == nil {
  413. sess.Rollback()
  414. e.OutErr(c, 400, e.NewErr(400, "订单不存在"))
  415. return
  416. }
  417. if order.State != 1 {
  418. sess.Rollback()
  419. e.OutErr(c, 400, e.NewErr(400, "订单不能确认收货"))
  420. return
  421. }
  422. order.State = 2
  423. order.UpdateAt = time.Now()
  424. order.ConfirmAt = time.Now()
  425. update, err := sess.Where("id=?", order.Id).Cols("state,confirm_at,update_at").Update(order)
  426. if update == 0 || err != nil {
  427. sess.Rollback()
  428. e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
  429. return
  430. }
  431. sess.Commit()
  432. e.OutSuc(c, "success", nil)
  433. return
  434. }
  435. func OrderCreate(c *gin.Context) {
  436. var arg md.OrderTotal
  437. if err := c.ShouldBindJSON(&arg); err != nil {
  438. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  439. return
  440. }
  441. user := GetUser(c)
  442. // 加锁 防止并发提取
  443. mutexKey := fmt.Sprintf("%s:team.OrderCreate:%s", c.GetString("mid"), utils.IntToStr(user.Info.Uid))
  444. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  445. if err != nil {
  446. e.OutErr(c, e.ERR, err)
  447. return
  448. }
  449. if withdrawAvailable != "OK" {
  450. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  451. return
  452. }
  453. sess := MasterDb(c).NewSession()
  454. defer sess.Close()
  455. err = sess.Begin()
  456. if err != nil {
  457. e.OutErr(c, 400, err.Error())
  458. return
  459. }
  460. totalPrice := commGoods(c, arg)
  461. coupon := "0"
  462. totalPrice, coupon, err = CouponProcess(c, sess, totalPrice, arg)
  463. if err != nil {
  464. sess.Rollback()
  465. e.OutErr(c, 400, err.Error())
  466. return
  467. }
  468. ordId := utils.OrderUUID(user.Info.Uid)
  469. // 获取店铺信息
  470. store := db.GetStoreId(sess, arg.StoreId)
  471. num := 0
  472. for _, item := range arg.GoodsInfo {
  473. num += utils.StrToInt(item.Num)
  474. }
  475. var order = &model.CommunityTeamOrder{
  476. Uid: user.Info.Uid,
  477. StoreUid: utils.StrToInt(arg.StoreId),
  478. Commission: utils.Float64ToStr(utils.FloatFormat(utils.AnyToFloat64(totalPrice)*(utils.AnyToFloat64(store.Commission)/100), 2)),
  479. CreateAt: time.Now(),
  480. UpdateAt: time.Now(),
  481. BuyPhone: arg.BuyPhone,
  482. Coupon: coupon,
  483. Num: num,
  484. IsNow: utils.StrToInt(arg.IsNow),
  485. Timer: arg.Timer,
  486. Memo: arg.Memo,
  487. Oid: utils.StrToInt64(ordId),
  488. Amount: totalPrice,
  489. MealNum: utils.StrToInt(arg.MealNum),
  490. }
  491. if utils.StrToFloat64(coupon) > 0 {
  492. order.CouponId = utils.StrToInt(arg.CouponId)
  493. }
  494. insert, err := sess.Insert(order)
  495. if insert == 0 || err != nil {
  496. sess.Rollback()
  497. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  498. return
  499. }
  500. for _, item := range arg.GoodsInfo {
  501. // 获取详细信息
  502. goodsInterface, has, err := db.GetComm(MasterDb(c), &model.CommunityTeamGoods{Id: utils.StrToInt(item.GoodsId)})
  503. if err != nil || !has {
  504. sess.Rollback()
  505. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  506. return
  507. }
  508. goodsModel := goodsInterface.(*model.CommunityTeamGoods)
  509. var skuInterface interface{}
  510. if item.SkuId != "-1" {
  511. skuInterface, _, _ = db.GetComm(MasterDb(c), &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId), SkuId: utils.StrToInt64(item.SkuId)})
  512. } else {
  513. skuInterface, _, _ = db.GetComm(MasterDb(c), &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId)})
  514. }
  515. if err != nil || !has {
  516. sess.Rollback()
  517. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  518. return
  519. }
  520. skuModel := skuInterface.(*model.CommunityTeamSku)
  521. var goodsSaleCount int
  522. // 走普通逻辑
  523. stock := skuModel.Stock - utils.StrToInt(item.Num)
  524. saleCount := skuModel.SaleCount + utils.StrToInt(item.Num)
  525. goodsSaleCount = goodsModel.SaleCount + utils.StrToInt(item.Num)
  526. if stock < 0 {
  527. sess.Rollback()
  528. e.OutErr(c, 400, e.NewErr(400, "库存不足"))
  529. return
  530. }
  531. update, err := sess.Where("sku_id=?", skuModel.SkuId).Cols("stock", "sale_count").Update(&model.CommunityTeamSku{Stock: stock, SaleCount: saleCount})
  532. if err != nil {
  533. sess.Rollback()
  534. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  535. return
  536. }
  537. if update != 1 {
  538. sess.Rollback()
  539. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  540. return
  541. }
  542. // 更新销量
  543. goodsModel.SaleCount = goodsSaleCount
  544. goodsModel.Stock = goodsModel.Stock - utils.StrToInt(item.Num)
  545. _, err = sess.Where("id = ?", goodsModel.Id).Cols("sale_count,stock").Update(goodsModel)
  546. if err != nil {
  547. sess.Rollback()
  548. e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
  549. return
  550. }
  551. // 插入订单
  552. insert, err := sess.Insert(&model.CommunityTeamOrderInfo{
  553. Oid: utils.StrToInt64(ordId),
  554. Title: goodsModel.Title,
  555. Img: goodsModel.Img,
  556. Price: skuModel.Price,
  557. Num: utils.StrToInt(item.Num),
  558. SkuInfo: skuModel.Sku,
  559. GoodsId: skuModel.GoodsId,
  560. SkuId: int(skuModel.SkuId),
  561. })
  562. if err != nil {
  563. sess.Rollback()
  564. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  565. return
  566. }
  567. if insert != 1 {
  568. sess.Rollback()
  569. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  570. return
  571. }
  572. }
  573. // 更新优惠券使用状态
  574. if utils.StrToInt(arg.CouponId) > 0 {
  575. affect, err := sess.Where("id = ?", arg.CouponId).
  576. Update(&model.CommunityTeamCouponUser{IsUse: 1})
  577. if err != nil {
  578. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  579. return
  580. }
  581. if affect != 1 {
  582. e.OutErr(c, 400, e.NewErr(400, "下单失败"))
  583. return
  584. }
  585. }
  586. err = sess.Commit()
  587. if err != nil {
  588. sess.Rollback()
  589. e.OutErr(c, 400, err.Error())
  590. return
  591. }
  592. sess.Commit()
  593. e.OutSuc(c, map[string]string{"oid": ordId}, nil)
  594. return
  595. }
  596. func OrderTotal(c *gin.Context) {
  597. var arg md.OrderTotal
  598. if err := c.ShouldBindJSON(&arg); err != nil {
  599. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  600. return
  601. }
  602. sess := MasterDb(c).NewSession()
  603. defer sess.Close()
  604. err := sess.Begin()
  605. if err != nil {
  606. e.OutErr(c, 400, err.Error())
  607. return
  608. }
  609. totalPrice := commGoods(c, arg)
  610. oldTotalPrice := totalPrice
  611. coupon := "0"
  612. totalPrice, coupon, err = CouponProcess(c, sess, totalPrice, arg)
  613. if err != nil {
  614. sess.Rollback()
  615. e.OutErr(c, 400, err.Error())
  616. return
  617. }
  618. user := GetUser(c)
  619. result := map[string]interface{}{
  620. "balance_money": GetCommissionPrec(c, user.Profile.FinValid, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  621. "small_amount": GetCommissionPrec(c, oldTotalPrice, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  622. "all_amount": GetCommissionPrec(c, totalPrice, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  623. "coupon": GetCommissionPrec(c, coupon, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
  624. }
  625. sess.Commit()
  626. e.OutSuc(c, result, nil)
  627. return
  628. }
  629. func CouponProcess(c *gin.Context, sess *xorm.Session, total string, args md.OrderTotal) (string, string, error) {
  630. if utils.StrToInt(args.CouponId) == 0 {
  631. return total, "0", nil
  632. }
  633. now := time.Now().Format("2006-01-02 15:04:05")
  634. user := GetUser(c)
  635. var goodsIds []int
  636. var skuIds []string
  637. for _, item := range args.GoodsInfo {
  638. goodsIds = append(goodsIds, utils.StrToInt(item.GoodsId))
  639. skuIds = append(skuIds, utils.AnyToString(item.SkuId))
  640. }
  641. // 获取优惠券信息
  642. var mallUserCoupon model.CommunityTeamCouponUser
  643. isExist, err := sess.
  644. Where("id = ? AND uid = ? AND is_use = ? AND (valid_time_start < ? AND valid_time_end > ?)", args.CouponId, user.Info.Uid, 0, now, now).
  645. Get(&mallUserCoupon)
  646. if err != nil {
  647. return "", "", err
  648. }
  649. if !isExist {
  650. return "", "", errors.New("无相关优惠券信息")
  651. }
  652. var cal struct {
  653. Reach string `json:"reach"`
  654. Reduce string `json:"reduce"`
  655. }
  656. _ = json.Unmarshal([]byte(mallUserCoupon.Cal), &cal)
  657. reach, err := decimal.NewFromString(cal.Reach)
  658. reduce, err := decimal.NewFromString(cal.Reduce)
  659. if err != nil {
  660. return "", "", err
  661. }
  662. var specialTotal = total
  663. // 是否满足优惠条件
  664. if !reach.IsZero() { // 满减及有门槛折扣
  665. if utils.StrToFloat64(specialTotal) < utils.StrToFloat64(reach.String()) {
  666. return "", "", errors.New("不满足优惠条件")
  667. }
  668. } else {
  669. if mallUserCoupon.Kind == 1 { //立减
  670. if utils.StrToFloat64(specialTotal) < utils.StrToFloat64(reduce.String()) {
  671. return "", "", errors.New("付款金额有误")
  672. }
  673. }
  674. }
  675. // 计算优惠后支付金额
  676. couponTotal := "0"
  677. if mallUserCoupon.Kind == int(enum.ActCouponTypeImmediate) ||
  678. mallUserCoupon.Kind == int(enum.ActCouponTypeReachReduce) { // 立减 || 满减
  679. couponTotal = reduce.String()
  680. total = utils.Float64ToStr(utils.StrToFloat64(total) - utils.StrToFloat64(reduce.String()))
  681. } else { // 折扣
  682. couponTotal = utils.Float64ToStr(utils.StrToFloat64(total) - utils.StrToFloat64(total)*utils.StrToFloat64(reduce.String())/10)
  683. total = utils.Float64ToStr(utils.StrToFloat64(total) * utils.StrToFloat64(reduce.String()) / 10)
  684. }
  685. return total, couponTotal, nil
  686. }
  687. func commGoods(c *gin.Context, arg md.OrderTotal) (totalPrice string) {
  688. engine := MasterDb(c)
  689. var totalPriceAmt float64 = 0
  690. for _, item := range arg.GoodsInfo {
  691. goodsInterface, _, _ := db.GetComm(engine, &model.CommunityTeamGoods{Id: utils.StrToInt(item.GoodsId)})
  692. goodsModel := goodsInterface.(*model.CommunityTeamGoods)
  693. var skuInterface interface{}
  694. if item.SkuId != "-1" {
  695. skuInterface, _, _ = db.GetComm(engine, &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId), SkuId: utils.StrToInt64(item.SkuId)})
  696. } else {
  697. skuInterface, _, _ = db.GetComm(engine, &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId)})
  698. }
  699. skuModel := skuInterface.(*model.CommunityTeamSku)
  700. priceOne := goodsModel.Price
  701. if item.SkuId != "-1" {
  702. priceOne = skuModel.Price
  703. }
  704. totalPriceAmt += utils.StrToFloat64(priceOne) * utils.StrToFloat64(item.Num)
  705. }
  706. return utils.Float64ToStr(totalPriceAmt)
  707. }