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

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
1 month ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
1 month ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  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. "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 := c.GetHeader("store_id")
  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. }