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

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