附近小店
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

861 líneas
25 KiB

  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. }