附近小店
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

svc_order.go 25 KiB

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