pet-house/business/api/order.go

744 lines
30 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"encoding/json"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"go.uber.org/zap"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"io"
"pet-house.com/business/models"
"pet-house.com/business/utils"
"pet-house.com/core/server/database"
"pet-house.com/core/server/web/web_iris"
"pet-house.com/core/server/zap_server"
"strconv"
"strings"
"sync"
"time"
)
type PetGoodsInfo struct {
PetId int64
GoodsIds []int64
}
type OrderCreateRequest struct {
PetGoodsInfos []PetGoodsInfo //宠物商品信息列表
ServiceTime string //预约时间 yyyy-MM-dd HH:mm
ServiceAddrId int64 //预约服务地址
}
type OrderCreateResponse struct {
OrderDetail OrderDetail `json:"orderDetail"`
}
type OrderCreatePreCheckResponse struct {
HasAlert bool `json:"hasAlert"` //是否弹窗提示 返回false直接下单返回ture弹出确认框确认框点击是之后调用下单接口
AlertMsg string `json:"alertMsg"` //弹窗消息
}
func (p DefParty) orderCreatePreCheck() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderCreatePreCheck", func(ctx *context.Context) {
headerBaseInfo := GetHeaderBaseInfo(ctx)
body, _ := io.ReadAll(ctx.Request().Body)
var orderCreateRequest OrderCreateRequest
json.Unmarshal(body, &orderCreateRequest)
if len(orderCreateRequest.PetGoodsInfos) == 0 {
ParamError.Fail(ctx, orderCreateRequest)
return
}
var userInfo *models.User
database.Instance().Model(&models.User{}).Where("id = ?", headerBaseInfo.Uid).Find(&userInfo)
var orderTotalAmount = 0
for _, value := range orderCreateRequest.PetGoodsInfos {
for _, value := range value.GoodsIds {
goods := GoodsMap[value]
orderTotalAmount = orderTotalAmount + int(goods.Price)
}
}
orderCreatePreCheckResponse := OrderCreatePreCheckResponse{
HasAlert: false,
}
var discountAmount = orderTotalAmount
if userInfo.Discount > 0 {
discount := float64(userInfo.Discount)
discountAmount = int(utils.RoundToOneDecimalPlace(float64(orderTotalAmount)*(discount/100.0)) * 10)
if userInfo.Amount < discountAmount {
orderCreatePreCheckResponse.HasAlert = true
orderCreatePreCheckResponse.AlertMsg = "您的会员余额不够,需要进行线下支付,当前订单将不享受会员折扣优惠价格"
}
}
Success(ctx, orderCreateRequest, orderCreatePreCheckResponse)
})
}}
}
var orderLock sync.Mutex
// 创建
func (p DefParty) orderCreate() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderCreate", func(ctx *context.Context) {
headerBaseInfo := GetHeaderBaseInfo(ctx)
body, _ := io.ReadAll(ctx.Request().Body)
var orderCreateRequest OrderCreateRequest
json.Unmarshal(body, &orderCreateRequest)
var userServiceAddr models.UserServiceAddr
database.Instance().Model(&models.UserServiceAddr{}).Where("uid = ? and id = ?", headerBaseInfo.Uid, orderCreateRequest.ServiceAddrId).Find(&userServiceAddr)
if userServiceAddr.Id == 0 {
UserServiceAddrNotExistError.Fail(ctx, nil)
return
}
//serviceAddr := ServiceAddrMap[orderCreateRequest.ServiceAreaId]
//if serviceAddr.Id == 0 {
// NotInServiceExistError.Fail(ctx, nil)
// return
//}
/*if len(serviceAddr.ServiceArea) > 0 && serviceAddr.ServiceArea != userServiceAddr.AddrArea {
ServiceAddrNotExistError.Fail(ctx, nil)
return
}*/
var projectionServiceTime = 0
for _, value := range orderCreateRequest.PetGoodsInfos {
for _, value := range value.GoodsIds {
goods := GoodsMap[value]
if goods.Time != "/" && len(goods.Time) > 0 {
goodsTime, _ := strconv.Atoi(goods.Time)
projectionServiceTime += goodsTime
}
}
}
haveReserve := checkOrderServiceTime(orderCreateRequest.ServiceTime, projectionServiceTime)
if haveReserve {
OrderCreateError.DefFail(ctx, orderCreateRequest, "当前订单预估服务时长预计:"+strconv.Itoa(projectionServiceTime)+"分钟,服务时间过长,请更换时间段预约或联系客服协助预约")
return
}
for _, value := range orderCreateRequest.PetGoodsInfos {
userPet := GetUserPet(headerBaseInfo.Uid, value.PetId)
if userPet.PetInfo.Vaccine == 0 {
OrderCreateError.DefFail(ctx, orderCreateRequest, "当前订单存在未接种疫苗的宠物,无法下单")
return
}
}
var orderTotalAmount = 0
orderLock.Lock()
orderId := NextId.Generate().String()
orderMain := models.OrderMain{
OrderId: orderId,
Uid: headerBaseInfo.Uid,
OrderStatus: 1,
PayType: 1,
ServiceTime: orderCreateRequest.ServiceTime,
ServiceAddrId: orderCreateRequest.ServiceAddrId,
ServiceRemark: "",
}
var projectionServiceTimeAll = 0
var orderSubList []models.OrderSub
var orderSubDetailList []models.OrderDetail
var mainGoods = 0
for _, value := range orderCreateRequest.PetGoodsInfos {
subOrderId := NextId.Generate().String()
var totalAmount int = 0
var projectionServiceTime = 0
var goodsName string
for _, value := range value.GoodsIds {
goods := GoodsMap[value]
totalAmount = totalAmount + goods.Price
orderSubDetailList = append(orderSubDetailList, models.OrderDetail{SubOrderId: subOrderId, GoodsId: value, Amount: goods.Price})
if goods.Time != "/" && len(goods.Time) > 0 {
goodsTime, _ := strconv.Atoi(goods.Time)
projectionServiceTime += goodsTime
}
if goods.GoodsType == 1 || goods.GoodsType == 2 {
mainGoods++
}
goodsName = goods.Name + "、" + goodsName
}
userPetInfo := GetUserPet(headerBaseInfo.Uid, value.PetId)
var petInfo = "宠物名称:" + userPetInfo.PetInfo.NickName + "</br>品种:" + userPetInfo.PetBaseInfo.Assortment + "</br>服务项目:" + goodsName
projectionServiceTimeAll += projectionServiceTime
orderSub := models.OrderSub{
OrderId: subOrderId,
MainOrderId: orderMain.OrderId,
OrderStatus: 1,
PetId: value.PetId,
PayType: 1,
Discount: 100,
TotalAmount: totalAmount,
PayAmount: totalAmount,
PetInfo: petInfo,
//PayTime: time.Now(),
ProjectionServiceTime: projectionServiceTime,
}
orderTotalAmount = orderTotalAmount + int(totalAmount)
orderSubList = append(orderSubList, orderSub)
}
if mainGoods == 0 {
OrderCreateError.DefFail(ctx, orderCreateRequest, "订单未选择主商品,创建失败")
orderLock.Unlock()
return
}
orderMain.ProjectionServiceTime = projectionServiceTimeAll
var userInfo *models.User
database.Instance().Model(&models.User{}).Where("id = ?", headerBaseInfo.Uid).Find(&userInfo)
var discountAmount = orderTotalAmount
if userInfo.Discount > 0 {
discount := float64(userInfo.Discount)
discountAmount = int(utils.RoundToOneDecimalPlace(float64(orderTotalAmount)*(discount/100.0)) * 10)
//discountAmount = int(math.Round(float64(orderTotalAmount)*(discount/100.0)) * 10)
}
orderMain.TotalAmount = orderTotalAmount
tx := database.Instance().Begin()
var db4 *gorm.DB
if userInfo.Amount >= discountAmount {
var currAmount = userInfo.Amount
orderMain.PayStatus = 1
orderMain.PayTotalAmount = discountAmount
userInfo.Amount = userInfo.Amount - discountAmount
updateValues := map[string]interface{}{
"Amount": userInfo.Amount,
}
db4 = tx.Model(&userInfo).Updates(&updateValues)
orderMain.PayDiscount = userInfo.Discount
orderMain.PayType = 3
for index := range orderSubList {
orderSubList[index].PayType = 3
}
zap_server.ZAPLOG.Info("会员金额扣除", zap.Any("用户ID", userInfo.Id), zap.Any("订单号", orderMain.OrderId), zap.Any("当前余额", currAmount), zap.Any("扣除余额", discountAmount), zap.Any("剩余余额", userInfo.Amount), zap.Any("折扣", userInfo.Discount))
discount := float64(userInfo.Discount)
for index, _ := range orderSubList {
orderSubList[index].Discount = userInfo.Discount
//orderSubList[index].PayAmount = int32(math.Round(float64(orderSubList[index].TotalAmount) * (discount / 100.0)))
orderSubList[index].PayAmount = int(utils.RoundToOneDecimalPlace(float64(orderSubList[index].TotalAmount)*(discount/100.0)) * 10)
}
}
var findUserServiceAddr models.UserServiceAddr
database.Instance().Model(&models.UserServiceAddr{}).Where("id = ? and uid = ?", orderCreateRequest.ServiceAddrId, headerBaseInfo.Uid).Find(&findUserServiceAddr)
userInfo.Mobile = findUserServiceAddr.Mobile
updateValues := map[string]interface{}{
"Mobile": userInfo.Mobile,
}
tx.Model(&userInfo).Updates(&updateValues)
db := tx.Model(&models.OrderDetail{}).CreateInBatches(&orderSubDetailList, len(orderSubDetailList))
db1 := tx.Model(&models.OrderSub{}).CreateInBatches(&orderSubList, len(orderSubList))
db2 := tx.Model(&models.OrderMain{}).Create(&orderMain)
if (db4 != nil && db4.Error != nil) || db.Error != nil || db1.Error != nil || db2.Error != nil {
tx.Callback()
orderLock.Unlock()
zap_server.ZAPLOG.Error("订单插入失败", zap.Any("db", db.Error), zap.Any("db1", db1.Error), zap.Any("db2", db2.Error), zap.Any("db4", db4.Error))
OrderCreateError.Fail(ctx, orderCreateRequest)
return
}
tx.Commit()
orderLock.Unlock()
Success(ctx, orderCreateRequest, OrderCreateResponse{GetOrderDetail(orderMain.OrderId)})
})
}}
}
func GetOrderDetail(orderId string) OrderDetail {
var orderMain models.OrderMain
database.Instance().Model(&models.OrderMain{}).Where("order_id = ?", orderId).Find(&orderMain)
var findUserServiceAddr models.UserServiceAddr
database.Instance().Model(&models.UserServiceAddr{}).Where("id = ?", orderMain.ServiceAddrId).Find(&findUserServiceAddr)
orderDetail := OrderDetail{
OrderId: orderMain.OrderId,
Status: orderMain.OrderStatus,
ServiceTime: orderMain.ServiceTime,
ServiceAddr: findUserServiceAddr,
ServiceRemark: orderMain.ServiceRemark,
CreateTime: orderMain.CreateTime.Format("2006-01-02 15:04:05"),
PayStatus: orderMain.PayStatus,
DispatchStatus: orderMain.DispatchStatus,
TotalAmount: orderMain.TotalAmount,
DiscountAmount: strconv.Itoa(orderMain.TotalAmount),
Discount: float64(orderMain.PayDiscount) / 100,
Uid: orderMain.Uid,
}
if orderMain.PayDiscount > 0 {
orderDetail.DiscountAmount = strconv.FormatFloat(float64(orderMain.PayTotalAmount)/10.0, 'f', 1, 64)
}
var subOrderList []SubOrder
var orderSubList []models.OrderSub
database.Instance().Model(&models.OrderSub{}).Where("main_order_id = ? ", orderMain.OrderId).Find(&orderSubList)
for _, orderSub := range orderSubList {
var orderDetailList []models.OrderDetail
database.Instance().Model(&models.OrderDetail{}).Where("sub_order_id = ? ", orderSub.OrderId).Find(&orderDetailList)
var goods []models.Goods
for _, orderDetail := range orderDetailList {
good := GoodsMap[orderDetail.GoodsId]
goods = append(goods, good)
}
orderSubR1 := SubOrder{
OrderId: orderSub.OrderId,
Status: orderSub.OrderStatus,
UserPetInfo: GetUserPet(orderMain.Uid, orderSub.PetId),
TotalAmount: orderSub.TotalAmount,
PayAmount: strconv.Itoa(int(orderSub.PayAmount)),
Discount: float64(orderSub.Discount),
Goods: goods,
}
if orderSubR1.Discount < 100 {
//orderSubR1.PayAmount = int32(math.Round(float64(orderSubR1.TotalAmount) * (orderSubR1.Discount / 100.0)))
//x := float64(orderSubR1.TotalAmount) * (orderSubR1.Discount / 100.0) / 10
x := float64(orderSub.PayAmount) / 10
orderSubR1.PayAmount = strconv.FormatFloat(x, 'f', 1, 64)
orderSubR1.DiscountAmount = orderSubR1.PayAmount
} else {
orderSubR1.DiscountAmount = strconv.Itoa(int(orderSubR1.TotalAmount))
}
subOrderList = append(subOrderList, orderSubR1)
}
var carOrder models.CarOrder
database.Instance().Model(&models.CarOrder{}).Where("order_id = ?", orderMain.OrderId).Find(&carOrder)
if carOrder.Id > 0 {
car := CarMap[carOrder.CarId]
orderDetail.ServiceCar = &car
} else {
orderDetail.ServiceCar = &models.ServiceCar{}
}
orderDetail.SubOrderList = subOrderList
return orderDetail
}
func checkOrderServiceTime(serviceTime string, projectionServiceTime int) bool {
type orderMainTmp struct {
ServiceTime string
ProjectionServiceTime int
}
serviceTimeD, _ := time.Parse("2006-01-02 15:04", serviceTime)
hour := serviceTimeD.Hour()
if hour == 20 && projectionServiceTime > 2*60 {
return true
}
if hour == 21 && projectionServiceTime > 1*60 {
return true
}
var orderMainTmpList []orderMainTmp
//服务时间>=预约时间 and 服务时间<=预计结束时间 时间范围内无订单才可预约
database.Instance().Model(&models.OrderMain{}).Where("service_time >= ? and service_time <= DATE_FORMAT(DATE_ADD('"+serviceTime+"', INTERVAL "+strconv.Itoa(projectionServiceTime)+" MINUTE), '%Y-%m-%d %H:%i') and order_status != 3 and order_status != 4", serviceTime).Find(&orderMainTmpList)
//时间点订单数量<服务车辆*车辆单次服务数量 才可接受预约
if len(orderMainTmpList) > 0 {
return len(orderMainTmpList) >= len(CarMap)*CarServiceNum
}
return false
}
type OrderListRequest struct {
Status int //订单状态 0所有 1待服务 2服务中 3已完成 4已取消
PageNo int //页码
PageSize int //数据数量
}
type SubOrder struct {
OrderId string `json:"orderId"` //子订单ID
Status int `json:"status"` //子订单状态 0待派单 1待服务 2服务中 3已完成 4已取消
UserPetInfo UserPetInfo `json:"userPetInfo"` //用户宠物信息
TotalAmount int `json:"totalAmount"` //总金额
PayAmount string `json:"payAmount"` //实际支付金额
DiscountAmount string `json:"discountAmount"` //折扣金额
Discount float64 `json:"discount"` //用户折扣
Goods []models.Goods `json:"goods"` //商品信息
}
type OrderDetail struct {
OrderId string `json:"orderId"` //主订单号
Status int `json:"status"` //主订单状态 0待派单 1待服务 2服务中 3已完成 4已取消
ServiceTime string `json:"serviceTime"` //服务时间
ServiceAddr models.UserServiceAddr `json:"serviceAddr"` //服务地址信息
ServiceRemark string `json:"serviceRemark"` //服务备注
CreateTime string `json:"createTime"` //创建时间
SubOrderList []SubOrder `json:"subOrderList"` //子订单列表
ServiceCar *models.ServiceCar `json:"serviceCar"` //服务车辆 只有派单状态未1的时候才会存在
PayStatus int `json:"payStatus"` //支付状态 0未支付 1已支付
DispatchStatus int `json:"dispatchStatus"` //派单状态 0未派单 1已派单
Discount float64 `json:"discount"` //用户折扣
TotalAmount int `json:"totalAmount"` //总金额
DiscountAmount string `json:"discountAmount"` //折扣金额
Uid int64 `json:"uid"` //用户ID
}
type OrderListResponse struct {
OrderDetails []OrderDetail `json:"orderDetails"` //订单列表
PageNo int `json:"pageNo"` //页码
PageSize int `json:"pageSize"` //数据数量
}
// 订单列表
func (p DefParty) orderList() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderList", func(ctx *context.Context) {
headerBaseInfo := GetHeaderBaseInfo(ctx)
body, _ := io.ReadAll(ctx.Request().Body)
var orderListRequest OrderListRequest
json.Unmarshal(body, &orderListRequest)
if orderListRequest.PageNo == 0 {
ParamError.DefFail(ctx, orderListRequest, "页码必须>0")
return
}
var orderList []models.OrderMain
if orderListRequest.Status == 0 {
database.Instance().Model(&models.OrderMain{}).Where("uid = ?", headerBaseInfo.Uid).Offset((orderListRequest.PageNo - 1) * orderListRequest.PageSize).Limit(orderListRequest.PageSize).Order(clause.OrderByColumn{Column: clause.Column{Name: "create_time"}, Desc: true}).Find(&orderList)
} else {
database.Instance().Model(&models.OrderMain{}).Where("uid = ? and status = ?", headerBaseInfo.Uid, orderListRequest.Status).Offset((orderListRequest.PageNo - 1) * orderListRequest.PageSize).Limit(orderListRequest.PageSize).Order(clause.OrderByColumn{Column: clause.Column{Name: "create_time"}, Desc: true}).Find(&orderList)
}
var orderDetails []OrderDetail
for _, value := range orderList {
var findUserServiceAddr models.UserServiceAddr
database.Instance().Model(&models.UserServiceAddr{}).Where("id = ? and uid = ?", value.ServiceAddrId, headerBaseInfo.Uid).Find(&findUserServiceAddr)
orderDetail := OrderDetail{
OrderId: value.OrderId,
Status: value.OrderStatus,
ServiceTime: value.ServiceTime,
ServiceAddr: findUserServiceAddr,
ServiceRemark: value.ServiceRemark,
CreateTime: value.CreateTime.Format("2006-01-02 15:04:05"),
PayStatus: value.PayStatus,
DispatchStatus: value.DispatchStatus,
TotalAmount: value.TotalAmount,
DiscountAmount: strconv.FormatFloat(float64(value.PayTotalAmount)/10.0, 'f', 1, 64),
Discount: float64(value.PayDiscount / 100.0),
}
var subOrderList []SubOrder
var orderSubList []models.OrderSub
database.Instance().Model(&models.OrderSub{}).Where("main_order_id = ? ", value.OrderId).Find(&orderSubList)
for _, orderSub := range orderSubList {
var orderDetailList []models.OrderDetail
database.Instance().Model(&models.OrderDetail{}).Where("sub_order_id = ? ", orderSub.OrderId).Find(&orderDetailList)
var goods []models.Goods
for _, orderDetail := range orderDetailList {
good := GoodsMap[orderDetail.GoodsId]
goods = append(goods, good)
}
orderSub := SubOrder{
OrderId: orderSub.OrderId,
Status: orderSub.OrderStatus,
UserPetInfo: GetUserPet(value.Uid, orderSub.PetId),
TotalAmount: orderSub.TotalAmount,
Discount: float64(orderSub.Discount / 100.0),
Goods: goods,
}
if orderSub.Discount > 0 {
//orderSub.PayAmount = int32(math.Round(float64(orderSub.TotalAmount) * (orderSub.Discount / 100.0)))
//orderSub.DiscountAmount = orderSub.PayAmount
x := float64(orderSub.TotalAmount) * (orderSub.Discount / 100.0) / 10
orderSub.PayAmount = strconv.FormatFloat(x, 'f', 1, 64)
orderSub.DiscountAmount = orderSub.PayAmount
}
subOrderList = append(subOrderList, orderSub)
}
orderDetail.SubOrderList = subOrderList
orderDetails = append(orderDetails, orderDetail)
}
var orderListResponse = OrderListResponse{
OrderDetails: orderDetails,
PageNo: orderListRequest.PageNo + 1,
PageSize: orderListRequest.PageSize,
}
Success(ctx, orderListRequest, orderListResponse)
})
}}
}
type OrderCancelRequest struct {
OrderId string
}
type OrderCancelResponse struct {
OrderDetail OrderDetail `json:"orderDetail"`
}
func (p DefParty) orderCancel() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderCancel", func(ctx *context.Context) {
headerBaseInfo := GetHeaderBaseInfo(ctx)
body, _ := io.ReadAll(ctx.Request().Body)
var orderCancelRequest OrderCancelRequest
json.Unmarshal(body, &orderCancelRequest)
var orderMain models.OrderMain
database.Instance().Model(&models.OrderMain{}).Where("order_id = ?", orderCancelRequest.OrderId).Find(&orderMain)
if orderMain.Uid != headerBaseInfo.Uid {
OrderExistError.Fail(ctx, orderCancelRequest)
return
}
if orderMain.OrderStatus != 1 {
OrderError.Fail(ctx, orderCancelRequest)
return
}
if orderMain.DispatchStatus == 1 {
OrderError.Fail(ctx, orderCancelRequest)
return
}
if orderMain.PayStatus == 1 {
var userInfo models.User
database.Instance().Model(&models.User{}).Where("id = ?", orderMain.Uid).Find(&userInfo)
userInfo.Amount = userInfo.Amount + orderMain.PayTotalAmount
updateValues := map[string]interface{}{
"Amount": userInfo.Amount,
}
database.Instance().Model(&userInfo).Updates(&updateValues)
orderMain.PayTotalAmount = 0
orderMain.PayStatus = 0
}
orderMain.OrderStatus = 4
updateValues := map[string]interface{}{
"OrderStatus": orderMain.OrderStatus,
"PayStatus": orderMain.PayStatus,
"PayTotalAmount": orderMain.PayTotalAmount,
}
database.Instance().Model(&orderMain).Updates(&updateValues)
Success(ctx, orderCancelRequest, OrderCancelResponse{GetOrderDetail(orderMain.OrderId)})
})
}}
}
type TimeObject struct {
Time string `json:"time"`
Y bool `json:"y"`
}
type OrderServiceTimeRequest struct {
ServiceAddrId int64
}
type OrderServiceTimeResponse struct {
Times map[string][]TimeObject `json:"times"`
}
// 获取订单可预约时间
func (p DefParty) orderServiceTime() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderServiceTime", func(ctx *context.Context) {
headerBaseInfo := GetHeaderBaseInfo(ctx)
body, _ := io.ReadAll(ctx.Request().Body)
var orderServiceTimeRequest OrderServiceTimeRequest
json.Unmarshal(body, &orderServiceTimeRequest)
if orderServiceTimeRequest.ServiceAddrId == 0 {
ParamError.Fail(ctx, orderServiceTimeRequest)
return
}
type orderMainTmp struct {
ServiceTime string
ProjectionServiceTime int
}
var orderMainTmpList []orderMainTmp
database.Instance().Model(&models.OrderMain{}).Where("service_time >= DATE_SUB(NOW(), INTERVAL 7 DAY) and order_status != 3 and order_status != 4").Find(&orderMainTmpList)
var orderTimeMap = make(map[string]string)
var orderTimeNum = make(map[string]int)
for _, value := range orderMainTmpList {
orderTimeMap[value.ServiceTime] = value.ServiceTime
orderTimeNum[value.ServiceTime] = orderTimeNum[value.ServiceTime] + 1
if value.ProjectionServiceTime > 0 {
//计算出服务时间点之后累计延长时间
date, _ := time.Parse("2006-01-02 15:04", value.ServiceTime)
lastDate := date.Add(time.Minute * time.Duration(value.ProjectionServiceTime))
for t := date; t.Before(lastDate); t = t.Add(time.Hour) {
timeStr := t.Format("2006-01-02 15:04")
orderTimeMap[timeStr] = timeStr
orderTimeNum[timeStr] = orderTimeNum[timeStr] + 1
}
}
}
serviceTime := AddrServiceMap[orderServiceTimeRequest.ServiceAddrId]
times := strings.Split(serviceTime.Times, ",")
carNum := len(CarMap)
daysMap := utils.GetStrDays(7, 60, ReserveMap, orderTimeMap, carNum, orderTimeNum, CarServiceNum, times)
var dayHoursMap = make(map[string][]TimeObject)
for day, values := range daysMap {
key := day
for _, value := range values {
if _, ok := dayHoursMap[key]; ok {
dayHoursMap[key] = append(dayHoursMap[key], TimeObject{
Time: value.Time,
Y: value.Y,
})
} else {
dayHoursMap[key] = []TimeObject{{
Time: value.Time,
Y: value.Y,
}}
}
}
}
Success(ctx, headerBaseInfo, OrderServiceTimeResponse{dayHoursMap})
})
}}
}
type OrderEditRequest struct {
OrderId string //订单ID
Status int //订单状态 4取消
}
// 修改订单
func (p DefParty) orderEdit() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderEdit", func(ctx *context.Context) {
headerBaseInfo := GetHeaderBaseInfo(ctx)
body, _ := io.ReadAll(ctx.Request().Body)
var orderEditRequest OrderEditRequest
json.Unmarshal(body, &orderEditRequest)
var orderMain models.OrderMain
var orderSub models.OrderSub
database.Instance().Model(&models.OrderSub{}).Where("order_id = ?", orderEditRequest.OrderId).Find(&orderSub)
database.Instance().Model(&models.OrderMain{}).Where("order_id = ?", orderSub.MainOrderId).Find(&orderMain)
if orderMain.Uid != headerBaseInfo.Uid {
OrderError.Fail(ctx, orderEditRequest)
return
}
if orderSub.OrderStatus > 0 || orderEditRequest.Status == 0 {
OrderError.Fail(ctx, orderEditRequest)
return
}
orderSub.OrderStatus = orderEditRequest.Status
updateValues := map[string]interface{}{
"OrderStatus": orderSub.OrderStatus,
}
database.Instance().Model(&orderSub).Updates(&updateValues)
Success(ctx, orderEditRequest, GetOrderDetail(orderMain.OrderId))
})
}}
}
type OrderDetailRequest struct {
OrderId string
}
type OrderDetailResponse struct {
OrderDetail OrderDetail `json:"orderDetail"`
}
// 订单详情
func (p DefParty) orderDetail() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderDetail", func(ctx *context.Context) {
body, _ := io.ReadAll(ctx.Request().Body)
var orderDetailRequest OrderDetailRequest
json.Unmarshal(body, &orderDetailRequest)
orderDetail := GetOrderDetail(orderDetailRequest.OrderId)
if len(orderDetail.OrderId) == 0 {
OrderExistError.Fail(ctx, orderDetailRequest)
return
}
Success(ctx, orderDetailRequest, OrderDetailResponse{GetOrderDetail(orderDetailRequest.OrderId)})
})
}}
}
type OrderGoodsUpdateRequest struct {
OrderId string
GoodsIds []int64
}
// 修改订单商品
func (p DefParty) orderGoodsUpdate() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderGoodsUpdate", func(ctx *context.Context) {
body, _ := io.ReadAll(ctx.Request().Body)
var orderGoodsUpdateRequest OrderGoodsUpdateRequest
json.Unmarshal(body, &orderGoodsUpdateRequest)
var orderSub models.OrderSub
database.Instance().Model(&models.OrderSub{}).Where("order_id = ?", orderGoodsUpdateRequest.OrderId).Find(&orderSub)
if len(orderSub.OrderId) == 0 {
OrderExistError.Fail(ctx, orderGoodsUpdateRequest)
return
}
var orderMain models.OrderMain
database.Instance().Model(&models.OrderMain{}).Where("order_id = ?", orderSub.MainOrderId).Find(&orderMain)
var totalAmount = 0
var projectionServiceTime = 0
for _, value := range orderGoodsUpdateRequest.GoodsIds {
goods := GoodsMap[value]
totalAmount = totalAmount + int(goods.Price)
if goods.Time != "/" && len(goods.Time) > 0 {
goodsTime, _ := strconv.Atoi(goods.Time)
projectionServiceTime += goodsTime
}
}
//非当前订单
var orderSubList []models.OrderSub
database.Instance().Model(&models.OrderSub{}).Where("main_order_id = ? and order_id != ", orderMain.OrderId, orderGoodsUpdateRequest.OrderId).Find(&orderSubList)
//新价格
var newAmount = totalAmount
var allProjectionServiceTime = projectionServiceTime
for _, value := range orderSubList {
newAmount = newAmount + int(value.TotalAmount)
allProjectionServiceTime = allProjectionServiceTime + value.ProjectionServiceTime
}
//已支付
if orderMain.PayStatus == 1 {
if orderMain.PayType == 3 {
var userInfo *models.User
database.Instance().Model(&models.User{}).Where("id = ?", orderMain.Uid).Find(&userInfo)
//先退还
userInfo.Amount = userInfo.Amount + orderMain.PayTotalAmount
if userInfo.Discount > 0 {
discount := float64(userInfo.Discount)
newAmount = int(utils.RoundToOneDecimalPlace(float64(newAmount)*(discount/100.0)) * 10)
}
//余额不足
if userInfo.Amount < newAmount {
OrderUpdateBalanceNotEnough.DefFail(ctx, orderGoodsUpdateRequest, "原订单金额:"+strconv.FormatFloat(float64(orderMain.PayTotalAmount)/10, 'f', 1, 64)+" 修改后订单金额:"+strconv.FormatFloat(float64(newAmount)/10, 'f', 1, 64)+";修改服务项目后余额不足,请充值后再支付")
return
}
var originAmount = userInfo.Amount
var preAmount = orderMain.PayTotalAmount
userInfo.Amount = userInfo.Amount - newAmount
orderMain.PayTotalAmount = newAmount
updateValues := map[string]interface{}{
"Amount": userInfo.Amount,
}
database.Instance().Model(&userInfo).Updates(&updateValues)
orderMain.PayDiscount = userInfo.Discount
zap_server.ZAPLOG.Info("会员金额扣除", zap.Any("用户ID", userInfo.Id), zap.Any("订单ID", orderMain.OrderId), zap.Any("用户修改之前余额", originAmount), zap.Any("当前余额", userInfo.Amount), zap.Any("商品修改之前金额", preAmount), zap.Any("商品修改之后金额", orderMain.PayTotalAmount), zap.Any("折扣", userInfo.Discount))
}
}
database.Instance().Where("sub_order_id = ?", orderGoodsUpdateRequest.OrderId).Delete(&models.OrderDetail{})
for _, value := range orderGoodsUpdateRequest.GoodsIds {
goods := GoodsMap[value]
orderDetail := models.OrderDetail{
SubOrderId: orderGoodsUpdateRequest.OrderId,
GoodsId: goods.Id,
Amount: goods.Price,
}
database.Instance().Model(&models.OrderDetail{}).Create(&orderDetail)
}
orderSub.TotalAmount = totalAmount
orderSub.PayAmount = newAmount
orderSub.ProjectionServiceTime = projectionServiceTime
updateValues := map[string]interface{}{
"TotalAmount": orderSub.TotalAmount,
"PayAmount": orderSub.PayAmount,
"ProjectionServiceTime": orderSub.ProjectionServiceTime,
}
orderMain.ProjectionServiceTime = allProjectionServiceTime
updateValues1 := map[string]interface{}{
"PayTotalAmount": orderMain.PayTotalAmount,
"ProjectionServiceTime": orderMain.ProjectionServiceTime,
}
database.Instance().Model(&orderMain).Updates(&updateValues1)
database.Instance().Model(&orderSub).Updates(&updateValues)
Success(ctx, orderGoodsUpdateRequest, OrderDetailResponse{GetOrderDetail(orderSub.MainOrderId)})
})
}}
}
// 支付
func (p DefParty) orderPay() web_iris.Party {
return web_iris.Party{Prefix: p.Prefix, PartyFunc: func(index iris.Party) {
index.Post(OrderBase+"/orderPay", func(ctx *context.Context) {
})
}}
}