package svc import ( "applet/app/db" "applet/app/db/model" "applet/app/e" "applet/app/md" "applet/app/utils" "applet/app/utils/cache" "encoding/json" "fmt" "github.com/gin-gonic/gin" "strings" "time" "xorm.io/xorm" ) func StoreOrderCate(c *gin.Context) { var cate = []map[string]string{ {"name": "全部", "value": ""}, {"name": "待付款", "value": "0"}, {"name": "待提货", "value": "1"}, {"name": "已完成", "value": "2"}, {"name": "已取消", "value": "3"}, } e.OutSuc(c, cate, nil) return } func GetDate(c *gin.Context, arg map[string]string) (time.Time, time.Time) { var stime, etime time.Time t := time.Now() if arg["type"] == "day" { stime = utils.TimeParseStd(arg["date"] + " 00:00:00") etime = time.Unix(stime.Unix()+86400, 0) } if arg["type"] == "month" { ex := strings.Split(arg["date"], "-") year := utils.StrToInt(ex[0]) stime = time.Date(year, time.Month(utils.StrToInt(ex[1])-1), 1, 0, 0, 0, 0, t.Location()) if utils.StrToInt(ex[1]) == 12 { year++ ex[1] = "1" } etime = time.Date(year, time.Month(utils.StrToInt(ex[1])), 1, 0, 0, 0, 0, t.Location()) } if arg["type"] == "year" { year := utils.StrToInt(arg["date"]) stime = time.Date(year, time.Month(0), 1, 0, 0, 0, 0, t.Location()) etime = time.Date(year+1, time.Month(0), 1, 0, 0, 0, 0, t.Location()) } return stime, etime } func StoreOrderList(c *gin.Context) { var arg map[string]string if err := c.ShouldBindJSON(&arg); err != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err) return } user := GetUser(c) arg["store_uid"] = utils.IntToStr(user.Info.Uid) if arg["type"] != "" && arg["date"] != "" { stime, etime := GetDate(c, arg) arg["start_time"] = stime.Format("2006-01-02 15:04:05") arg["end_time"] = etime.Format("2006-01-02 15:04:05") } data := db.GetOrderList(c, MasterDb(c), arg) var state = []string{"待付款", "待提货", "已完成", "已取消"} list := make([]map[string]interface{}, 0) if data != nil { scheme, host := ImageBucket(c) now := time.Now().Unix() for _, v := range *data { store := db.GetStoreIdEg(MasterDb(c), utils.IntToStr(v.StoreUid)) info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(v.Oid)) downTime := "0" if v.State == 0 { downTime = utils.IntToStr(int(v.CreateAt.Unix() + 15*60 - now)) if now > v.CreateAt.Unix()+15*60 { v.State = 3 } if utils.StrToInt(downTime) < 0 { downTime = "0" } } storeName := "" if store != nil { storeName = store.Name } goodsInfo := make([]map[string]string, 0) if info != nil { for _, v1 := range *info { skuData := make([]md.Sku, 0) json.Unmarshal([]byte(v1.SkuInfo), &skuData) skuStr := "" for _, v2 := range skuData { if skuStr != "" { skuStr += ";" } skuStr += v2.Value } if skuStr != "" { skuStr = "(" + skuStr + ")" } tmp := map[string]string{ "title": v1.Title + skuStr, "num": utils.IntToStr(v1.Num), "img": ImageFormatWithBucket(scheme, host, v1.Img), } goodsInfo = append(goodsInfo, tmp) } } user1, _ := db.UserFindByID(MasterDb(c), v.Uid) userProfile, _ := db.UserProfileFindByID(MasterDb(c), v.Uid) nickname := "" headImg := "" if userProfile != nil { headImg = userProfile.AvatarUrl } if user1 != nil { if user1.Nickname != user1.Phone { user1.Nickname += " " + user1.Phone } nickname = user1.Nickname } tmp := map[string]interface{}{ "goods_info": goodsInfo, "oid": utils.Int64ToStr(v.Oid), "label": "自提", "state": utils.IntToStr(v.State), "state_str": state[v.State], "store_name": storeName, "coupon": v.Coupon, "commission": v.Commission, "username": nickname, "head_img": headImg, "table_num": v.TableNum, "amount": v.Amount, "num": utils.IntToStr(v.Num), "down_time": downTime, "create_at": v.CreateAt.Format("2006-01-02 15:04:05"), "pay_at": "", "confirm_at": "", } if v.PayAt.IsZero() == false { tmp["pay_at"] = v.PayAt.Format("2006-01-02 15:04:05") } if v.ConfirmAt.IsZero() == false { tmp["confirm_at"] = v.ConfirmAt.Format("2006-01-02 15:04:05") } else { if v.IsNow == 1 { tmp["confirm_at"] = "立即提货" } else if v.Timer != "" { tmp["confirm_at"] = v.Timer } } if v.Type == 1 { tmp["label"] = "外卖" } list = append(list, tmp) } } e.OutSuc(c, list, nil) return } func StoreOrderDetail(c *gin.Context) { var arg map[string]string if err := c.ShouldBindJSON(&arg); err != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err) return } data := db.GetOrderEg(MasterDb(c), arg["oid"]) var state = []string{"待付款", "待提货", "已完成", "已取消"} now := time.Now().Unix() downTime := "0" if data.State == 0 { downTime = utils.IntToStr(int(data.CreateAt.Unix() + 15*60 - now)) if now > data.CreateAt.Unix()+15*60 { data.State = 3 } if utils.StrToInt(downTime) < 0 { downTime = "0" } } confirmAt := "" if data.ConfirmAt.IsZero() == false { confirmAt = data.ConfirmAt.Format("2006-01-02 15:04:05") } payAt := "" if data.PayAt.IsZero() == false { payAt = data.PayAt.Format("2006-01-02 15:04:05") } timer := "" if data.IsNow == 1 { timer = "立即提货" } else if data.Timer != "" { timer = data.Timer } orderInfo := []map[string]string{ {"title": "订单编号", "content": utils.Int64ToStr(data.Oid)}, {"title": "提货码", "content": data.Code}, {"title": "下单时间", "content": data.CreateAt.Format("2006-01-02 15:04:05")}, {"title": "付款时间", "content": payAt}, {"title": "预计提货时间", "content": timer}, {"title": "提货时间", "content": confirmAt}, {"title": "预留电话", "content": data.Phone}, {"title": "备注信息", "content": data.Memo}, } goodsInfo := make([]map[string]string, 0) info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(data.Oid)) if info != nil { scheme, host := ImageBucket(c) for _, v := range *info { tmp := map[string]string{ "img": ImageFormatWithBucket(scheme, host, v.Img), "title": v.Title, "price": v.Price, "num": utils.IntToStr(v.Num), "sku_str": "", } skuData := make([]md.Sku, 0) json.Unmarshal([]byte(v.SkuInfo), &skuData) skuStr := "" for _, v1 := range skuData { if skuStr != "" { skuStr += ";" } skuStr += v1.Value } tmp["sku_str"] = skuStr goodsInfo = append(goodsInfo, tmp) } } user1, _ := db.UserFindByID(MasterDb(c), data.Uid) userProfile, _ := db.UserProfileFindByID(MasterDb(c), data.Uid) nickname := "" headImg := "" if userProfile != nil { headImg = userProfile.AvatarUrl } if user1 != nil { if user1.Nickname != user1.Phone { user1.Nickname += " " + user1.Phone } nickname = user1.Nickname } tmp := map[string]interface{}{ "oid": utils.Int64ToStr(data.Oid), "label": "自提", "username": nickname, "head_img": headImg, "commission": data.Commission, "state": utils.IntToStr(data.State), "state_str": state[data.State], "amount": data.Amount, "all_amount": utils.Float64ToStr(utils.StrToFloat64(data.Amount) + utils.StrToFloat64(data.Coupon)), "coupon": data.Coupon, "num": utils.IntToStr(data.Num), "code": data.Code, "down_time": downTime, "order_info": orderInfo, "goods_info": goodsInfo, "goods_count": utils.IntToStr(len(goodsInfo)), } if data.Type == 1 { tmp["label"] = "外卖" } e.OutSuc(c, tmp, nil) return } func StoreOrderConfirm(c *gin.Context) { var arg map[string]string if err := c.ShouldBindJSON(&arg); err != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err) return } // 加锁 防止并发提取 mutexKey := fmt.Sprintf("%s:team.StoreOrderConfirm:%s", c.GetString("mid"), arg["oid"]) withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX") if err != nil { e.OutErr(c, e.ERR, err) return } if withdrawAvailable != "OK" { e.OutErr(c, e.ERR, e.NewErr(400000, "请求过于频繁,请稍后再试")) return } sess := MasterDb(c).NewSession() defer sess.Close() sess.Begin() order := db.GetOrder(sess, arg["oid"]) if order == nil { sess.Rollback() e.OutErr(c, 400, e.NewErr(400, "订单不存在")) return } if order.State != 1 { sess.Rollback() e.OutErr(c, 400, e.NewErr(400, "订单不能确认")) return } order.State = 2 order.UpdateAt = time.Now() order.ConfirmAt = time.Now() update, err := sess.Where("id=?", order.Id).Cols("state,confirm_at,update_at").Update(order) if update == 0 || err != nil { sess.Rollback() e.OutErr(c, 400, e.NewErr(400, "订单确认失败")) return } money := utils.StrToFloat64(order.Commission) if order.ParentUid > 0 { money = utils.StrToFloat64(order.Amount) - utils.StrToFloat64(order.AgentCommission) } if order.StoreType == 1 { money = utils.StrToFloat64(order.Amount) - utils.StrToFloat64(order.PlatformCommission) } bools := MoneyCheck(c, sess, order.StoreUid, order.ParentUid, order.StoreType, 0, 1, money, "订单核销", order.Oid) if bools == false { sess.Rollback() e.OutErr(c, 400, e.NewErr(400, "订单确认失败")) return } sess.Commit() e.OutSuc(c, "success", nil) return } func MoneyCheck(c *gin.Context, sess *xorm.Session, storeId, ParentUid, StoreType, types, ordType int, money float64, title string, oid int64) bool { amountData := db.GetStoreAmount(sess, storeId, ParentUid, StoreType) if amountData == nil { amountData = &model.CommunityTeamStoreAmount{ Uid: storeId, ParentUid: ParentUid, StoreType: StoreType, } insert, err := sess.Insert(amountData) if insert == 0 || err != nil { return false } } before := amountData.Amount if types == 1 { amountData.Amount = utils.Float64ToStr(utils.StrToFloat64(amountData.Amount) - money) if utils.StrToFloat64(amountData.Amount) < 0 { return false } } else { amountData.Amount = utils.Float64ToStr(utils.StrToFloat64(amountData.Amount) + money) } update, err := sess.Where("id=?", amountData.Id).Cols("amount").Update(amountData) if update == 0 || err != nil { return false } var flow = &model.CommunityTeamStoreAmountFlow{ Uid: storeId, StoreType: StoreType, ParentUid: ParentUid, Amount: utils.Float64ToStr(money), BeforeAmount: before, AfterAmount: amountData.Amount, Oid: oid, Type: types, Title: title, OrdType: ordType, CreateAt: time.Now(), } insert, err := sess.Insert(flow) if insert == 0 || err != nil { return false } return true }