附近小店
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_store_order.go 10 KiB

2 months ago
2 months ago
2 months ago
4 weeks ago
2 months ago
2 months ago
2 months ago
4 weeks ago
2 months ago
3 weeks 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. package svc
  2. import (
  3. "applet/app/db"
  4. "applet/app/db/model"
  5. "applet/app/e"
  6. "applet/app/md"
  7. "applet/app/utils"
  8. "applet/app/utils/cache"
  9. "encoding/json"
  10. "fmt"
  11. "github.com/gin-gonic/gin"
  12. "strings"
  13. "time"
  14. "xorm.io/xorm"
  15. )
  16. func StoreOrderCate(c *gin.Context) {
  17. var cate = []map[string]string{
  18. {"name": "全部", "value": ""},
  19. {"name": "待付款", "value": "0"},
  20. {"name": "待提货", "value": "1"},
  21. {"name": "已完成", "value": "2"},
  22. {"name": "已取消", "value": "3"},
  23. }
  24. e.OutSuc(c, cate, nil)
  25. return
  26. }
  27. func GetDate(c *gin.Context, arg map[string]string) (time.Time, time.Time) {
  28. var stime, etime time.Time
  29. t := time.Now()
  30. if arg["type"] == "day" {
  31. stime = utils.TimeParseStd(arg["date"] + " 00:00:00")
  32. etime = time.Unix(stime.Unix()+86400, 0)
  33. }
  34. if arg["type"] == "month" {
  35. ex := strings.Split(arg["date"], "-")
  36. year := utils.StrToInt(ex[0])
  37. stime = time.Date(year, time.Month(utils.StrToInt(ex[1])-1), 1, 0, 0, 0, 0, t.Location())
  38. if utils.StrToInt(ex[1]) == 12 {
  39. year++
  40. ex[1] = "1"
  41. }
  42. etime = time.Date(year, time.Month(utils.StrToInt(ex[1])), 1, 0, 0, 0, 0, t.Location())
  43. }
  44. if arg["type"] == "year" {
  45. year := utils.StrToInt(arg["date"])
  46. stime = time.Date(year, time.Month(0), 1, 0, 0, 0, 0, t.Location())
  47. etime = time.Date(year+1, time.Month(0), 1, 0, 0, 0, 0, t.Location())
  48. }
  49. return stime, etime
  50. }
  51. func StoreOrderList(c *gin.Context) {
  52. var arg map[string]string
  53. if err := c.ShouldBindJSON(&arg); err != nil {
  54. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  55. return
  56. }
  57. user := GetUser(c)
  58. arg["store_uid"] = utils.IntToStr(user.Info.Uid)
  59. if arg["type"] != "" && arg["date"] != "" {
  60. stime, etime := GetDate(c, arg)
  61. arg["start_time"] = stime.Format("2006-01-02 15:04:05")
  62. arg["end_time"] = etime.Format("2006-01-02 15:04:05")
  63. }
  64. data := db.GetOrderList(c, MasterDb(c), arg)
  65. var state = []string{"待付款", "待提货", "已完成", "已取消"}
  66. list := make([]map[string]interface{}, 0)
  67. if data != nil {
  68. scheme, host := ImageBucket(c)
  69. now := time.Now().Unix()
  70. for _, v := range *data {
  71. store := db.GetStoreIdEg(MasterDb(c), utils.IntToStr(v.StoreUid))
  72. info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(v.Oid))
  73. downTime := "0"
  74. if v.State == 0 {
  75. downTime = utils.IntToStr(int(v.CreateAt.Unix() + 15*60 - now))
  76. if now > v.CreateAt.Unix()+15*60 {
  77. v.State = 3
  78. }
  79. if utils.StrToInt(downTime) < 0 {
  80. downTime = "0"
  81. }
  82. }
  83. storeName := ""
  84. if store != nil {
  85. storeName = store.Name
  86. }
  87. goodsInfo := make([]map[string]string, 0)
  88. if info != nil {
  89. for _, v1 := range *info {
  90. skuData := make([]md.Sku, 0)
  91. json.Unmarshal([]byte(v1.SkuInfo), &skuData)
  92. skuStr := ""
  93. for _, v2 := range skuData {
  94. if skuStr != "" {
  95. skuStr += ";"
  96. }
  97. skuStr += v2.Value
  98. }
  99. if skuStr != "" {
  100. skuStr = "(" + skuStr + ")"
  101. }
  102. tmp := map[string]string{
  103. "title": v1.Title + skuStr,
  104. "num": utils.IntToStr(v1.Num),
  105. "img": ImageFormatWithBucket(scheme, host, v1.Img),
  106. }
  107. goodsInfo = append(goodsInfo, tmp)
  108. }
  109. }
  110. user1, _ := db.UserFindByID(MasterDb(c), v.Uid)
  111. userProfile, _ := db.UserProfileFindByID(MasterDb(c), v.Uid)
  112. nickname := ""
  113. headImg := ""
  114. if userProfile != nil {
  115. headImg = userProfile.AvatarUrl
  116. }
  117. if user1 != nil {
  118. if user1.Nickname != user1.Phone {
  119. user1.Nickname += " " + user1.Phone
  120. }
  121. nickname = user1.Nickname
  122. }
  123. tmp := map[string]interface{}{
  124. "goods_info": goodsInfo,
  125. "oid": utils.Int64ToStr(v.Oid),
  126. "label": "自提",
  127. "state": utils.IntToStr(v.State),
  128. "state_str": state[v.State],
  129. "store_name": storeName,
  130. "coupon": v.Coupon,
  131. "commission": v.Commission,
  132. "username": nickname,
  133. "head_img": headImg,
  134. "table_num": v.TableNum,
  135. "amount": v.Amount,
  136. "num": utils.IntToStr(v.Num),
  137. "down_time": downTime,
  138. "create_at": v.CreateAt.Format("2006-01-02 15:04:05"),
  139. "pay_at": "",
  140. "confirm_at": "",
  141. }
  142. if v.PayAt.IsZero() == false {
  143. tmp["pay_at"] = v.PayAt.Format("2006-01-02 15:04:05")
  144. }
  145. if v.ConfirmAt.IsZero() == false {
  146. tmp["confirm_at"] = v.ConfirmAt.Format("2006-01-02 15:04:05")
  147. } else {
  148. if v.IsNow == 1 {
  149. tmp["confirm_at"] = "立即提货"
  150. } else if v.Timer != "" {
  151. tmp["confirm_at"] = v.Timer
  152. }
  153. }
  154. if v.Type == 1 {
  155. tmp["label"] = "外卖"
  156. }
  157. list = append(list, tmp)
  158. }
  159. }
  160. e.OutSuc(c, list, nil)
  161. return
  162. }
  163. func StoreOrderDetail(c *gin.Context) {
  164. var arg map[string]string
  165. if err := c.ShouldBindJSON(&arg); err != nil {
  166. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  167. return
  168. }
  169. data := db.GetOrderEg(MasterDb(c), arg["oid"])
  170. var state = []string{"待付款", "待提货", "已完成", "已取消"}
  171. now := time.Now().Unix()
  172. downTime := "0"
  173. if data.State == 0 {
  174. downTime = utils.IntToStr(int(data.CreateAt.Unix() + 15*60 - now))
  175. if now > data.CreateAt.Unix()+15*60 {
  176. data.State = 3
  177. }
  178. if utils.StrToInt(downTime) < 0 {
  179. downTime = "0"
  180. }
  181. }
  182. confirmAt := ""
  183. if data.ConfirmAt.IsZero() == false {
  184. confirmAt = data.ConfirmAt.Format("2006-01-02 15:04:05")
  185. }
  186. payAt := ""
  187. if data.PayAt.IsZero() == false {
  188. payAt = data.PayAt.Format("2006-01-02 15:04:05")
  189. }
  190. timer := ""
  191. if data.IsNow == 1 {
  192. timer = "立即提货"
  193. } else if data.Timer != "" {
  194. timer = data.Timer
  195. }
  196. orderInfo := []map[string]string{
  197. {"title": "订单编号", "content": utils.Int64ToStr(data.Oid)},
  198. {"title": "提货码", "content": data.Code},
  199. {"title": "下单时间", "content": data.CreateAt.Format("2006-01-02 15:04:05")},
  200. {"title": "付款时间", "content": payAt},
  201. {"title": "预计提货时间", "content": timer},
  202. {"title": "提货时间", "content": confirmAt},
  203. {"title": "预留电话", "content": data.Phone},
  204. {"title": "备注信息", "content": data.Memo},
  205. }
  206. goodsInfo := make([]map[string]string, 0)
  207. info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(data.Oid))
  208. if info != nil {
  209. scheme, host := ImageBucket(c)
  210. for _, v := range *info {
  211. tmp := map[string]string{
  212. "img": ImageFormatWithBucket(scheme, host, v.Img),
  213. "title": v.Title,
  214. "price": v.Price,
  215. "num": utils.IntToStr(v.Num),
  216. "sku_str": "",
  217. }
  218. skuData := make([]md.Sku, 0)
  219. json.Unmarshal([]byte(v.SkuInfo), &skuData)
  220. skuStr := ""
  221. for _, v1 := range skuData {
  222. if skuStr != "" {
  223. skuStr += ";"
  224. }
  225. skuStr += v1.Value
  226. }
  227. tmp["sku_str"] = skuStr
  228. goodsInfo = append(goodsInfo, tmp)
  229. }
  230. }
  231. user1, _ := db.UserFindByID(MasterDb(c), data.Uid)
  232. userProfile, _ := db.UserProfileFindByID(MasterDb(c), data.Uid)
  233. nickname := ""
  234. headImg := ""
  235. if userProfile != nil {
  236. headImg = userProfile.AvatarUrl
  237. }
  238. if user1 != nil {
  239. if user1.Nickname != user1.Phone {
  240. user1.Nickname += " " + user1.Phone
  241. }
  242. nickname = user1.Nickname
  243. }
  244. tmp := map[string]interface{}{
  245. "oid": utils.Int64ToStr(data.Oid),
  246. "label": "自提",
  247. "username": nickname,
  248. "head_img": headImg,
  249. "commission": data.Commission,
  250. "state": utils.IntToStr(data.State),
  251. "state_str": state[data.State],
  252. "amount": data.Amount,
  253. "all_amount": utils.Float64ToStr(utils.StrToFloat64(data.Amount) + utils.StrToFloat64(data.Coupon)),
  254. "coupon": data.Coupon,
  255. "num": utils.IntToStr(data.Num),
  256. "code": data.Code,
  257. "down_time": downTime,
  258. "order_info": orderInfo,
  259. "goods_info": goodsInfo,
  260. "goods_count": utils.IntToStr(len(goodsInfo)),
  261. }
  262. if data.Type == 1 {
  263. tmp["label"] = "外卖"
  264. }
  265. e.OutSuc(c, tmp, nil)
  266. return
  267. }
  268. func StoreOrderConfirm(c *gin.Context) {
  269. var arg map[string]string
  270. if err := c.ShouldBindJSON(&arg); err != nil {
  271. e.OutErr(c, e.ERR_INVALID_ARGS, err)
  272. return
  273. }
  274. // 加锁 防止并发提取
  275. mutexKey := fmt.Sprintf("%s:team.StoreOrderConfirm:%s", c.GetString("mid"), arg["oid"])
  276. withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
  277. if err != nil {
  278. e.OutErr(c, e.ERR, err)
  279. return
  280. }
  281. if withdrawAvailable != "OK" {
  282. e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试"))
  283. return
  284. }
  285. sess := MasterDb(c).NewSession()
  286. defer sess.Close()
  287. sess.Begin()
  288. order := db.GetOrder(sess, arg["oid"])
  289. if order == nil {
  290. sess.Rollback()
  291. e.OutErr(c, 400, e.NewErr(400, "订单不存在"))
  292. return
  293. }
  294. if order.State != 1 {
  295. sess.Rollback()
  296. e.OutErr(c, 400, e.NewErr(400, "订单不能确认"))
  297. return
  298. }
  299. order.State = 2
  300. order.UpdateAt = time.Now()
  301. order.ConfirmAt = time.Now()
  302. update, err := sess.Where("id=?", order.Id).Cols("state,confirm_at,update_at").Update(order)
  303. if update == 0 || err != nil {
  304. sess.Rollback()
  305. e.OutErr(c, 400, e.NewErr(400, "订单确认失败"))
  306. return
  307. }
  308. money := utils.StrToFloat64(order.Commission)
  309. if order.ParentUid > 0 {
  310. money = utils.StrToFloat64(order.Amount) - utils.StrToFloat64(order.AgentCommission)
  311. }
  312. if order.StoreType == 1 {
  313. money = utils.StrToFloat64(order.Amount) - utils.StrToFloat64(order.PlatformCommission)
  314. }
  315. bools := MoneyCheck(c, sess, order.StoreUid, order.ParentUid, order.StoreType, 0, 1, money, "订单核销", order.Oid)
  316. if bools == false {
  317. sess.Rollback()
  318. e.OutErr(c, 400, e.NewErr(400, "订单确认失败"))
  319. return
  320. }
  321. sess.Commit()
  322. e.OutSuc(c, "success", nil)
  323. return
  324. }
  325. func MoneyCheck(c *gin.Context, sess *xorm.Session, storeId, ParentUid, StoreType, types, ordType int, money float64, title string, oid int64) bool {
  326. amountData := db.GetStoreAmount(sess, storeId, ParentUid, StoreType)
  327. if amountData == nil {
  328. amountData = &model.CommunityTeamStoreAmount{
  329. Uid: storeId,
  330. ParentUid: ParentUid,
  331. StoreType: StoreType,
  332. }
  333. insert, err := sess.Insert(amountData)
  334. if insert == 0 || err != nil {
  335. return false
  336. }
  337. }
  338. before := amountData.Amount
  339. if types == 1 {
  340. amountData.Amount = utils.Float64ToStr(utils.StrToFloat64(amountData.Amount) - money)
  341. if utils.StrToFloat64(amountData.Amount) < 0 {
  342. return false
  343. }
  344. } else {
  345. amountData.Amount = utils.Float64ToStr(utils.StrToFloat64(amountData.Amount) + money)
  346. }
  347. update, err := sess.Where("id=?", amountData.Id).Cols("amount").Update(amountData)
  348. if update == 0 || err != nil {
  349. return false
  350. }
  351. var flow = &model.CommunityTeamStoreAmountFlow{
  352. Uid: storeId,
  353. StoreType: StoreType,
  354. ParentUid: ParentUid,
  355. Amount: utils.Float64ToStr(money),
  356. BeforeAmount: before,
  357. AfterAmount: amountData.Amount,
  358. Oid: oid,
  359. Type: types,
  360. Title: title,
  361. OrdType: ordType,
  362. CreateAt: time.Now(),
  363. }
  364. insert, err := sess.Insert(flow)
  365. if insert == 0 || err != nil {
  366. return false
  367. }
  368. return true
  369. }