附近小店
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

svc_order.go 25 KiB

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