|
- package svc
-
- import (
- "applet/app/db"
- "applet/app/db/model"
- "applet/app/e"
- "applet/app/enum"
- "applet/app/md"
- "applet/app/utils"
- "applet/app/utils/cache"
- "encoding/json"
- "errors"
- "fmt"
- "github.com/gin-gonic/gin"
- "github.com/shopspring/decimal"
- "time"
- "xorm.io/xorm"
- )
-
- func OrderCate(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 OrderList(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["uid"] = utils.IntToStr(user.Info.Uid)
- data := db.GetOrderList(MasterDb(c), arg)
- var state = []string{"待付款", "待提货", "已完成", "已取消"}
- list := make([]map[string]string, 0)
- if data != nil {
- now := time.Now().Unix()
- for _, v := range *data {
- store := db.GetStoreIdEg(MasterDb(c), utils.IntToStr(v.StoreUid))
- info := db.GetOrderInfoEg(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"
- }
- }
- img := ""
- title := ""
- storeName := ""
- if store != nil {
- storeName = store.Name
- }
- if info != nil {
- img = info.Img
- title = info.Title
- }
- tmp := map[string]string{
- "oid": utils.Int64ToStr(v.Oid),
- "label": "自提",
- "state": utils.IntToStr(v.State),
- "state_str": state[v.State],
- "store_name": storeName,
- "img": img,
- "title": title,
- "amount": v.Amount,
- "num": utils.IntToStr(v.Num),
- "timer": "",
- "down_time": downTime,
- }
- if v.Type == 1 {
- tmp["label"] = "外卖"
- }
- if v.IsNow == 1 {
- tmp["timer"] = "立即提货"
- } else if v.Timer != "" {
- tmp["timer"] = "提货时间:" + v.Timer
- }
- list = append(list, tmp)
- }
- }
- e.OutSuc(c, list, nil)
- return
- }
- func OrderDetail(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()
- store := db.GetStoreIdEg(MasterDb(c), utils.IntToStr(data.StoreUid))
- 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"
- }
- }
- img := ""
- title := ""
- storeName := ""
- storeAddress := ""
- lat := ""
- lng := ""
- km := ""
- if store != nil {
- storeName = store.Name
- storeAddress = store.Address
- lat = store.Lat
- lng = store.Lng
- km = ""
- if arg["lat"] != "" && arg["lng"] != "" {
- km1 := utils.CalculateDistance(utils.StrToFloat64(lat), utils.StrToFloat64(lng), utils.StrToFloat64(arg["lat"]), utils.StrToFloat64(arg["lng"]))
- if km1 < 1 {
- km = utils.Float64ToStr(km1*1000) + "m"
- } else {
- km = utils.Float64ToStr(km1) + "km"
- }
- }
- }
- confirmAt := ""
- if data.ConfirmAt.IsZero() == false {
- confirmAt = data.ConfirmAt.Format("2006-01-02 15:04:05")
- }
- payMethod := "-"
- if data.PayMethod > 0 {
- payMethod = md.PayMethodIdToName[data.PayMethod]
- }
- orderInfo := []map[string]string{
- {"title": "订单编号", "content": utils.Int64ToStr(data.Oid)},
- {"title": "下单时间", "content": data.CreateAt.Format("2006-01-02 15:04:05")},
- {"title": "提货时间", "content": confirmAt},
- {"title": "预留电话", "content": data.Phone},
- {"title": "支付方式", "content": payMethod},
- {"title": "备注信息", "content": data.Memo},
- }
- goodsInfo := make([]map[string]string, 0)
- info := db.GetOrderInfoAllEg(MasterDb(c), utils.Int64ToStr(data.Oid))
- if info != nil {
- for _, v := range *info {
- tmp := map[string]string{
- "img": 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)
- }
- }
- tmp := map[string]interface{}{
- "oid": utils.Int64ToStr(data.Oid),
- "label": "自提",
- "state": utils.IntToStr(data.State),
- "state_str": state[data.State],
- "store_name": storeName,
- "store_address": storeAddress,
- "lat": lat,
- "lng": lng,
- "km": km,
- "img": img,
- "title": title,
- "amount": data.Amount,
- "num": utils.IntToStr(data.Num),
- "timer": "",
- "code": data.Code,
- "down_time": downTime,
- "order_info": orderInfo,
- "goods_info": goodsInfo,
- "goods_count": utils.IntToStr(len(goodsInfo)),
- }
- if data.Type == 1 {
- tmp["label"] = "外卖"
- }
- if data.IsNow == 1 {
- tmp["timer"] = "立即提货"
- } else if data.Timer != "" {
- tmp["timer"] = data.Timer
- }
- e.OutSuc(c, tmp, nil)
- return
- }
- func OrderCoupon(c *gin.Context) {
- var arg md.OrderTotal
- if err := c.ShouldBindJSON(&arg); err != nil {
- e.OutErr(c, e.ERR_INVALID_ARGS, err)
- return
- }
- totalPrice := commGoods(c, arg)
- returnData := CommCoupon(c, totalPrice)
- e.OutSuc(c, returnData, nil)
- return
- }
- func CommCoupon(c *gin.Context, totalPrice string) map[string]interface{} {
- var err error
- engine := MasterDb(c)
- user := GetUser(c)
- now := time.Now().Format("2006-01-02 15:04:05")
- var ActCouponUserList []*model.CommunityTeamCouponUser
- sess := engine.Table("act_coupon_user").
- Where("store_type=? and uid = ? AND is_use = ? AND (valid_time_start < ? AND valid_time_end > ?)", 0,
- user.Info.Uid, 0, now, now)
- err = sess.Find(&ActCouponUserList)
- if err != nil {
- return map[string]interface{}{}
- }
- var ids = make([]int, 0)
- for _, v := range ActCouponUserList {
- ids = append(ids, v.MerchantSchemeId)
- }
- var merchantScheme []model.CommunityTeamCoupon
- engine.In("id", ids).Find(&merchantScheme)
- var merchantSchemeMap = make(map[int]model.CommunityTeamCoupon)
- for _, v := range merchantScheme {
- merchantSchemeMap[v.Id] = v
- }
-
- var couponList []md.CouponList // 可使用的
- couponList = make([]md.CouponList, 0)
- count := 0
- for _, item := range ActCouponUserList {
- var coupon = md.CouponList{
- Id: utils.Int64ToStr(item.Id),
- Title: item.Name,
- Timer: item.ValidTimeStart.Format("2006.01.02") + "-" + item.ValidTimeEnd.Format("2006.01.02"),
- Label: "全部商品可用",
- Img: item.Img,
- Content: item.ActivityStatement,
- IsCanUse: "0",
- NotUseStr: "",
- }
- var cal struct {
- Reach string `json:"reach"`
- Reduce string `json:"reduce"`
- }
- err = json.Unmarshal([]byte(item.Cal), &cal)
- if err != nil {
- return map[string]interface{}{}
- }
- switch item.Kind {
- case int(enum.ActCouponTypeImmediate):
- if utils.AnyToFloat64(totalPrice) >= utils.AnyToFloat64(cal.Reduce) {
- coupon.IsCanUse = "1"
- }
- case int(enum.ActCouponTypeReachReduce):
- if utils.AnyToFloat64(totalPrice) >= utils.AnyToFloat64(cal.Reduce) {
- coupon.IsCanUse = "1"
- }
- case int(enum.ActCouponTypeReachDiscount):
- if utils.AnyToFloat64(totalPrice) >= utils.AnyToFloat64(cal.Reduce) && utils.AnyToFloat64(cal.Reduce) > 0 {
- coupon.IsCanUse = "1"
- }
- if utils.AnyToFloat64(cal.Reduce) == 0 {
- coupon.IsCanUse = "1"
- }
- }
- if coupon.IsCanUse != "1" {
- coupon.NotUseStr = "订单金额未满" + cal.Reduce + "元"
- }
- if coupon.IsCanUse == "1" {
- count++
- }
- couponList = append(couponList, coupon)
- }
-
- returnData := map[string]interface{}{
- "total": utils.IntToStr(count),
- "coupon_list": couponList,
- }
-
- return returnData
- }
- func OrderCancel(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.OrderCancel:%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 > 0 {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "订单不能取消"))
- return
- }
- orderInfo := db.GetOrderInfo(sess, arg["oid"])
- if orderInfo != nil {
- goodsMap := make(map[int]int)
- skuMap := make(map[int]int)
- for _, v := range *orderInfo {
- goodsMap[v.GoodsId] += v.Num
- skuMap[v.SkuId] += v.Num
- }
- for k, v := range goodsMap {
- sql := `update community_team_goods set stock=stock+%d where id=%d`
- sql = fmt.Sprintf(sql, v, k)
- _, err := db.QueryNativeStringWithSess(sess, sql)
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
- return
- }
- }
- for k, v := range skuMap {
- sql := `update community_team_sku set stock=stock+%d where sku_id=%d`
- sql = fmt.Sprintf(sql, v, k)
- _, err := db.QueryNativeStringWithSess(sess, sql)
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
- return
- }
- }
- }
- order.State = 3
- order.UpdateAt = time.Now()
- update, err := sess.Where("id=?", order.Id).Cols("state,update_at").Update(order)
- if update == 0 || err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
- return
- }
- if order.CouponId > 0 {
- update, err = sess.Where("id=?", order.CouponId).Cols("is_use").Update(&model.CommunityTeamCouponUser{IsUse: 0})
- if update == 0 || err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "订单取消失败"))
- return
- }
- }
- sess.Commit()
- e.OutSuc(c, "success", nil)
- return
- }
- func OrderCreate(c *gin.Context) {
- var arg md.OrderTotal
- if err := c.ShouldBindJSON(&arg); err != nil {
- e.OutErr(c, e.ERR_INVALID_ARGS, err)
- return
- }
- user := GetUser(c)
- // 加锁 防止并发提取
- mutexKey := fmt.Sprintf("%s:team.OrderCreate:%s", c.GetString("mid"), utils.IntToStr(user.Info.Uid))
- 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()
- err = sess.Begin()
- if err != nil {
- e.OutErr(c, 400, err.Error())
- return
- }
- totalPrice := commGoods(c, arg)
- coupon := "0"
- totalPrice, coupon, err = CouponProcess(c, sess, totalPrice, arg)
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, err.Error())
- return
- }
- ordId := utils.OrderUUID(user.Info.Uid)
- // 获取店铺信息
- store := db.GetStoreId(sess, arg.StoreId)
- num := 0
- for _, item := range arg.GoodsInfo {
- num += utils.StrToInt(item.Num)
- }
- var order = &model.CommunityTeamOrder{
- Uid: user.Info.Uid,
- StoreUid: utils.StrToInt(arg.StoreId),
- Commission: utils.Float64ToStr(utils.FloatFormat(utils.AnyToFloat64(totalPrice)*(utils.AnyToFloat64(store.Commission)/100), 2)),
- CreateAt: time.Now(),
- UpdateAt: time.Now(),
- BuyPhone: arg.BuyPhone,
- Coupon: coupon,
- Num: num,
- IsNow: utils.StrToInt(arg.IsNow),
- Timer: arg.Timer,
- Memo: arg.Memo,
- Oid: utils.StrToInt64(ordId),
- Amount: totalPrice,
- MealNum: utils.StrToInt(arg.MealNum),
- }
- if utils.StrToFloat64(coupon) > 0 {
- order.CouponId = utils.StrToInt(arg.CouponId)
- }
- insert, err := sess.Insert(order)
- if insert == 0 || err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "下单失败"))
- return
- }
- for _, item := range arg.GoodsInfo {
- // 获取详细信息
- goodsInterface, has, err := db.GetComm(MasterDb(c), &model.CommunityTeamGoods{Id: utils.StrToInt(item.GoodsId)})
- if err != nil || !has {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
- return
- }
- goodsModel := goodsInterface.(*model.CommunityTeamGoods)
- var skuInterface interface{}
- if item.SkuId != "-1" {
- skuInterface, _, _ = db.GetComm(MasterDb(c), &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId), SkuId: utils.StrToInt64(item.SkuId)})
- } else {
- skuInterface, _, _ = db.GetComm(MasterDb(c), &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId)})
- }
- if err != nil || !has {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
- return
- }
- skuModel := skuInterface.(*model.CommunityTeamSku)
- var goodsSaleCount int
- // 走普通逻辑
- stock := skuModel.Stock - utils.StrToInt(item.Num)
- saleCount := skuModel.SaleCount + utils.StrToInt(item.Num)
- goodsSaleCount = goodsModel.SaleCount + utils.StrToInt(item.Num)
- if stock < 0 {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "库存不足"))
- return
- }
- update, err := sess.Where("sku_id=?", skuModel.SkuId).Cols("stock", "sale_count").Update(&model.CommunityTeamSku{Stock: stock, SaleCount: saleCount})
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
- return
- }
- if update != 1 {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
- return
- }
- // 更新销量
- goodsModel.SaleCount = goodsSaleCount
- goodsModel.Stock = goodsModel.Stock - utils.StrToInt(item.Num)
- _, err = sess.Where("id = ?", goodsModel.Id).Cols("sale_count,stock").Update(goodsModel)
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "商品不存在"))
- return
- }
-
- // 插入订单
- insert, err := sess.Insert(&model.CommunityTeamOrderInfo{
- Oid: utils.StrToInt64(ordId),
- Title: goodsModel.Title,
- Img: goodsModel.Img,
- Price: skuModel.Price,
- Num: utils.StrToInt(item.Num),
- SkuInfo: skuModel.Sku,
- GoodsId: skuModel.GoodsId,
- SkuId: int(skuModel.SkuId),
- })
-
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "下单失败"))
- return
- }
- if insert != 1 {
- sess.Rollback()
- e.OutErr(c, 400, e.NewErr(400, "下单失败"))
- return
- }
- }
- // 更新优惠券使用状态
- if utils.StrToInt(arg.CouponId) > 0 {
- affect, err := sess.Where("id = ?", arg.CouponId).
- Update(&model.CommunityTeamCouponUser{IsUse: 1})
- if err != nil {
- e.OutErr(c, 400, e.NewErr(400, "下单失败"))
- return
- }
- if affect != 1 {
- e.OutErr(c, 400, e.NewErr(400, "下单失败"))
- return
- }
- }
-
- err = sess.Commit()
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, err.Error())
- return
- }
- sess.Commit()
- e.OutSuc(c, map[string]string{"oid": ordId}, nil)
- return
- }
- func OrderTotal(c *gin.Context) {
- var arg md.OrderTotal
- if err := c.ShouldBindJSON(&arg); err != nil {
- e.OutErr(c, e.ERR_INVALID_ARGS, err)
- return
- }
- sess := MasterDb(c).NewSession()
- defer sess.Close()
- err := sess.Begin()
- if err != nil {
- e.OutErr(c, 400, err.Error())
- return
- }
- totalPrice := commGoods(c, arg)
- oldTotalPrice := totalPrice
- coupon := "0"
- totalPrice, coupon, err = CouponProcess(c, sess, totalPrice, arg)
- if err != nil {
- sess.Rollback()
- e.OutErr(c, 400, err.Error())
- return
- }
- user := GetUser(c)
- result := map[string]interface{}{
- "balance_money": GetCommissionPrec(c, user.Profile.FinValid, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
- "small_amount": GetCommissionPrec(c, oldTotalPrice, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
- "all_amount": GetCommissionPrec(c, totalPrice, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
- "coupon": GetCommissionPrec(c, coupon, SysCfgGet(c, "commission_prec"), SysCfgGet(c, "is_show_point")),
- }
- sess.Commit()
- e.OutSuc(c, result, nil)
- return
- }
- func CouponProcess(c *gin.Context, sess *xorm.Session, total string, args md.OrderTotal) (string, string, error) {
- if utils.StrToInt(args.CouponId) == 0 {
- return total, "0", nil
- }
- now := time.Now().Format("2006-01-02 15:04:05")
- user := GetUser(c)
- var goodsIds []int
- var skuIds []string
- for _, item := range args.GoodsInfo {
- goodsIds = append(goodsIds, utils.StrToInt(item.GoodsId))
- skuIds = append(skuIds, utils.AnyToString(item.SkuId))
- }
- // 获取优惠券信息
- var mallUserCoupon model.CommunityTeamCouponUser
- isExist, err := sess.
- Where("id = ? AND uid = ? AND is_use = ? AND (valid_time_start < ? AND valid_time_end > ?)", args.CouponId, user.Info.Uid, 0, now, now).
- Get(&mallUserCoupon)
- if err != nil {
- return "", "", err
- }
- if !isExist {
- return "", "", errors.New("无相关优惠券信息")
- }
-
- var cal struct {
- Reach string `json:"reach"`
- Reduce string `json:"reduce"`
- }
- _ = json.Unmarshal([]byte(mallUserCoupon.Cal), &cal)
- reach, err := decimal.NewFromString(cal.Reach)
- reduce, err := decimal.NewFromString(cal.Reduce)
- if err != nil {
- return "", "", err
- }
-
- var specialTotal = total
- // 是否满足优惠条件
- if !reach.IsZero() { // 满减及有门槛折扣
- if utils.StrToFloat64(specialTotal) < utils.StrToFloat64(reach.String()) {
- return "", "", errors.New("不满足优惠条件")
- }
- } else {
- if mallUserCoupon.Kind == 1 { //立减
- if utils.StrToFloat64(specialTotal) < utils.StrToFloat64(reduce.String()) {
- return "", "", errors.New("付款金额有误")
- }
- }
- }
- // 计算优惠后支付金额
- couponTotal := "0"
- if mallUserCoupon.Kind == int(enum.ActCouponTypeImmediate) ||
- mallUserCoupon.Kind == int(enum.ActCouponTypeReachReduce) { // 立减 || 满减
- couponTotal = reduce.String()
- total = utils.Float64ToStr(utils.StrToFloat64(total) - utils.StrToFloat64(reduce.String()))
- } else { // 折扣
- couponTotal = utils.Float64ToStr(utils.StrToFloat64(total) - utils.StrToFloat64(total)*utils.StrToFloat64(reduce.String())/10)
- total = utils.Float64ToStr(utils.StrToFloat64(total) * utils.StrToFloat64(reduce.String()) / 10)
- }
- return total, couponTotal, nil
- }
-
- func commGoods(c *gin.Context, arg md.OrderTotal) (totalPrice string) {
- engine := MasterDb(c)
- var totalPriceAmt float64 = 0
- for _, item := range arg.GoodsInfo {
- goodsInterface, _, _ := db.GetComm(engine, &model.CommunityTeamGoods{Id: utils.StrToInt(item.GoodsId)})
- goodsModel := goodsInterface.(*model.CommunityTeamGoods)
- var skuInterface interface{}
- if item.SkuId != "-1" {
- skuInterface, _, _ = db.GetComm(engine, &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId), SkuId: utils.StrToInt64(item.SkuId)})
- } else {
- skuInterface, _, _ = db.GetComm(engine, &model.CommunityTeamSku{GoodsId: utils.StrToInt(item.GoodsId)})
- }
- skuModel := skuInterface.(*model.CommunityTeamSku)
- priceOne := goodsModel.Price
- if item.SkuId != "-1" {
- priceOne = skuModel.Price
- }
- totalPriceAmt += utils.StrToFloat64(priceOne) * utils.StrToFloat64(item.Num)
- }
- return utils.Float64ToStr(totalPriceAmt)
-
- }
|