package services import ( "encoding/json" "qteam/app/constants/common" "qteam/app/constants/errorcode" "qteam/app/http/entities/front" "qteam/app/models/ordersmodel" "qteam/app/models/productsmodel" "qteam/app/models/usersmodel" "qteam/app/third/market" "qteam/app/third/youchu" "qteam/app/utils" redis_util "qteam/app/utils/redis" "qteam/config" "strconv" "time" "xorm.io/builder" ) func CreateOrderService(userId int, productId int) (code int, data front.InsertOrderResponse) { var err error { // redis保证用户当前抽奖结束才能开始下次抽奖 key := utils.GetRealKey("lottery_code:" + strconv.Itoa(userId) + strconv.Itoa(productId)) ok, err := redis_util.AcquireLock(key, time.Second*10) if ok { defer redis_util.Del(key) } else { if err != nil { utils.Log(nil, "CreateOrderService", err.Error()) } code = errorcode.OrderLottery return code, data } } session := ordersmodel.GetInstance().GetDb().NewSession() defer func() { if err != nil { _ = session.Rollback() return } _ = session.Close() }() var product productsmodel.Products has, err := productsmodel.GetInstance().GetDb().Where("id = ?", productId).Get(&product) if err != nil { return errorcode.SystemError, data } if !has { return errorcode.UserNotExist, data } stock, _ := strconv.Atoi(product.Stock) if stock <= 0 { return errorcode.ProductStockFAIL, data } var user usersmodel.Users has, err = usersmodel.GetInstance().GetDb().Where("id =?", userId).Get(&user) if err != nil { return errorcode.SystemError, data } order := ordersmodel.Orders{ OrderNo: utils.GenerateOrderNumber(), UserId: userId, ProductId: productId, ProductName: product.Name, CustNo: user.CustNo, Price: product.Price, VoucherId: product.ThirdProductId, State: common.STATUSABLED, CreateTime: time.Now(), } if err = session.Begin(); err != nil { return errorcode.SystemError, data } if _, err := session.Insert(order); err != nil { utils.Log(nil, "CreateOrderService", err.Error()) return errorcode.SystemError, data } else { _ = session.Commit() } data.OrderNo = order.OrderNo data.NotifyUrl = config.GetConf().YouChu.NotifyUrl return errorcode.Success, data } func OrderQueryService(userId int, OrderRequest *front.OrderListRequest) (code int, data []ordersmodel.OrdersProductsList, count int64) { repo := ordersmodel.GetInstance().GetDb() conn := builder.NewCond() conn = conn.And(builder.Eq{"a.user_id": userId}) if OrderRequest.State != 0 { conn = conn.And(builder.Eq{"a.state": OrderRequest.State}) } count, err := repo.Where(conn).Alias("a"). Join("INNER", "Products b", "a.product_id = b.id").Select("a.*,b.main_image"). Desc("id").Limit(OrderRequest.PageSize, (OrderRequest.Page-1)*OrderRequest.PageSize).FindAndCount(&data) code = handErr(err) return } func OrderDetailService(order *ordersmodel.Orders) (has bool, err error) { repo := ordersmodel.GetInstance().GetDb() conn := builder.NewCond() if order.Id != 0 { conn = conn.And(builder.Eq{"id": order.Id}) } if order.OrderNo != "" { conn = conn.And(builder.Eq{"order_no": order.OrderNo}) } return repo.Where(conn).Get(order) } func OrdersUpdateService(req front.OrdersUpdateRequest) (err error) { repo := ordersmodel.GetInstance().GetDb() var order ordersmodel.Orders if req.Id != 0 { order.Id = req.Id } if req.Status != 0 { order.State = req.Status } if req.VoucherLink != "" { order.VoucherLink = req.VoucherLink } if req.OrgTxnSeq != "" { order.OrgTxnSeq = req.OrgTxnSeq } _, err = repo.Where("Id = ?", req.Id).Update(&order) return } func OrderRefundService(userId int, orderId int) (code int) { { // redis保证用户当前抽奖结束才能开始下次抽奖 key := utils.GetRealKey("lottery_code:" + strconv.Itoa(userId) + strconv.Itoa(orderId)) ok, err := redis_util.AcquireLock(key, time.Second*10) if ok { defer redis_util.Del(key) } else { if err != nil { utils.Log(nil, "CreateOrderService", err.Error()) } return errorcode.SystemError } } order := ordersmodel.Orders{} order.Id = orderId has, err := OrderDetailService(&order) if err != nil || !has { return errorcode.NotFound } if order.State >= common.ORDER_STATUS_PAY { return errorcode.OrderNOTAuthREFUND } code, response := YouChuOrderRefund(order) if code != errorcode.Success { return code } else { if response.RefundOrderSta != "03" { return errorcode.OrderRefundFail } else { order.State = common.ORDER_STATUS_ReFUNDING order.RefundOrderNo = response.RefundOrderNo order.RefundOrderSta = response.RefundOrderSta order.RefundTime = time.Now() _, err := ordersmodel.GetInstance().GetDb().Update(order) if err != nil { return errorcode.OrderRefundUpdateFail } return errorcode.Success } } } func OrderNotify(request front.YouChuRequest) (NotifyResponse front.YouChuOrderNotifyResponse) { requestStr, _ := json.Marshal(request) utils.Log(nil, "订单回调请求--原始数据:", string(requestStr)) response := youchu.DecryptResponse(string(requestStr), false) utils.Log(nil, "订单回调请求--解密数据:", response) var YouChuOrderNotifyRequest front.YouChuOrderNotifyRequest err := json.Unmarshal([]byte(response), &YouChuOrderNotifyRequest) if err != nil { return front.YouChuOrderNotifyResponse{RespCode: "000001", RespMsg: "解析失败"} } // 03-支付成功 04-支付失败 05-检查失败 if YouChuOrderNotifyRequest.OrderSta != "03" { return front.YouChuOrderNotifyResponse{RespCode: "000002", RespMsg: "交易失败"} } else { //支付成功 utils.Log(nil, "OrderNotify-success", YouChuOrderNotifyRequest) var orderDetail ordersmodel.Orders var order ordersmodel.Orders has, err := ordersmodel.GetInstance().GetDb().Where("state = ?", common.ORDER_STATUS_DEFAULT).Where("order_no = ?", YouChuOrderNotifyRequest.ReqTraceId).Get(&orderDetail) if err != nil || !has { return front.YouChuOrderNotifyResponse{RespCode: "000003", RespMsg: "订单不存在"} } var productDetail productsmodel.Products has, err = productsmodel.GetInstance().GetDb().Where("id = ?", orderDetail.ProductId).Get(&productDetail) if err != nil || !has { return front.YouChuOrderNotifyResponse{RespCode: "000003", RespMsg: "商品不存在"} } //01-消费 03-退货 if YouChuOrderNotifyRequest.TxnFlag == "01" { client := market.NewMarketClient(config.GetConf().OpenApiMarketConfig) send, err := client.MarketSend(orderDetail.OrderNo, strconv.Itoa(orderDetail.VoucherId), "", "1") utils.Log(nil, "OrderNotify-MarketSend", send) if err != nil { return front.YouChuOrderNotifyResponse{RespCode: "000004", RespMsg: "充值失败"} } order.OrgTxnSeq = YouChuOrderNotifyRequest.OrderNo if send.ErrCode != "00" { order.State = common.ORDER_STATUS_FAIL } else { order.State = common.ORDER_STATUS_FINISH order.VoucherLink = send.Data.ShortUrl Stock, _ := strconv.Atoi(productDetail.Stock) productDetail.Stock = strconv.Itoa(Stock - 1) } } else { //order.RefundOrderNo = YouChuOrderNotifyRequest.OrgTxnSeq //order.RefundOrderSta = YouChuOrderNotifyRequest.OrderSta return front.YouChuOrderNotifyResponse{RespCode: "000005", RespMsg: "订单标识错误"} } _, err = ordersmodel.GetInstance().GetDb().Where("order_no = ?", YouChuOrderNotifyRequest.ReqTraceId).Update(&order) _, err = productsmodel.GetInstance().GetDb().Where("id = ?", orderDetail.ProductId).Update(&productDetail) if err != nil { utils.Log(nil, "OrderNotify-MarketSend", err.Error()) return front.YouChuOrderNotifyResponse{RespCode: "000004", RespMsg: "操作失败"} } } return }