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

370 lines
10 KiB

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