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

10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
10 月之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  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. }