pet-house/business/api/order.go

383 lines
14 KiB
Go

package api
import (
"encoding/json"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"go.uber.org/zap"
"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"
"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"`
}
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[userServiceAddr.AreaId]
if serviceAddr.Id == 0 {
ServiceAddrNotExistError.Fail(ctx, nil)
return
}
haveReserve := checkOrderServiceTime(orderCreateRequest.ServiceTime)
if haveReserve {
OrderCreateError.DefFail(ctx, orderCreateRequest, "当前时间点不可预约")
return
}
orderLock.Lock()
orderId := NextId.Generate().String()
orderMain := models.OrderMain{
OrderId: orderId,
Uid: headerBaseInfo.Uid,
Status: 0,
ServiceTime: orderCreateRequest.ServiceTime,
ServiceAddrId: orderCreateRequest.ServiceAddrId,
ServiceRemark: "",
}
var orderSubList []models.OrderSub
var orderSubDetailList []models.OrderDetail
for _, value := range orderCreateRequest.PetGoodsInfos {
subOrderId := NextId.Generate().String()
var totalAmount int32 = 0
for _, value := range value.GoodsIds {
goods := GoodsMap[value]
totalAmount = totalAmount + goods.Price
orderSubDetailList = append(orderSubDetailList, models.OrderDetail{SubOrderId: subOrderId, GoodsId: value, Amount: goods.Price})
}
orderSub := models.OrderSub{
OrderId: subOrderId,
MainOrderId: orderMain.OrderId,
Status: 1,
PetId: value.PetId,
PayType: 1,
Discount: 100,
TotalAmount: totalAmount,
PayAmount: 0,
}
orderSubList = append(orderSubList, orderSub)
}
tx := database.Instance().Begin()
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 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))
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.Status,
ServiceTime: orderMain.ServiceTime,
ServiceAddr: findUserServiceAddr,
ServiceRemark: orderMain.ServiceRemark,
CreateTime: orderMain.CreateTime.String(),
}
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)
}
orderSub := SubOrder{
OrderId: orderSub.OrderId,
Status: orderSub.Status,
UserPetInfo: GetUserPet(orderMain.Uid, orderSub.PetId),
TotalAmount: orderSub.TotalAmount,
PayAmount: orderSub.PayAmount,
Goods: goods,
}
subOrderList = append(subOrderList, orderSub)
}
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.CreateTime = time.DateTime
orderDetail.SubOrderList = subOrderList
return orderDetail
}
func checkOrderServiceTime(serviceTime string) bool {
type orderMainTmp struct {
ServiceTime string
}
var orderMainTmpList []orderMainTmp
database.Instance().Model(&models.OrderMain{}).Where("service_time = ?", 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 int32 `json:"totalAmount"` //总金额 单位:分
PayAmount int32 `json:"payAmount"` //实际支付金额 单位:分
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 2 3的时候才会存在
}
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).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).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)
orderListResponse := OrderDetail{
OrderId: value.OrderId,
Status: value.Status,
ServiceTime: value.ServiceTime,
ServiceAddr: findUserServiceAddr,
ServiceRemark: value.ServiceRemark,
CreateTime: value.CreateTime.String(),
}
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.Status,
UserPetInfo: GetUserPet(headerBaseInfo.Uid, orderSub.PetId),
TotalAmount: orderSub.TotalAmount,
PayAmount: orderSub.PayAmount,
Goods: goods,
}
subOrderList = append(subOrderList, orderSub)
}
orderListResponse.SubOrderList = subOrderList
orderDetails = append(orderDetails, orderListResponse)
}
var orderListResponse = OrderListResponse{
OrderDetails: orderDetails,
PageNo: orderListRequest.PageNo + 1,
PageSize: orderListRequest.PageSize,
}
Success(ctx, orderListRequest, orderListResponse)
})
}}
}
type TimeObject struct {
Time string `json:"time"`
Y bool `json:"y"`
}
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)
type orderMainTmp struct {
ServiceTime string
}
var orderMainTmpList []orderMainTmp
database.Instance().Model(&models.OrderMain{}).Where("service_time >= DATE_SUB(NOW(), INTERVAL 7 DAY) and status != 3 and status != 5").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
}
carNum := len(CarMap)
daysMap := utils.GetStrDays(7, 60, ReserveMap, orderTimeMap, carNum, orderTimeNum, CarServiceNum)
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.Status > 0 || orderEditRequest.Status == 0 {
OrderError.Fail(ctx, orderEditRequest)
return
}
orderSub.Status = orderEditRequest.Status
updateValues := map[string]interface{}{
"Status": orderSub.Status,
}
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)})
})
}}
}
// 支付
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) {
})
}}
}