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

10 months ago
10 months ago
10 months ago
8 months ago
10 months ago
10 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
9 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 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. }