商城源码-6

思考并回答以下问题:

订单

router

router/mall/mall_order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package mall

import (
"github.com/gin-gonic/gin"
v1 "main.go/api/v1"
"main.go/middleware"
)

type MallOrderRouter struct {
}

func (m *MallOrderRouter) InitMallOrderRouter(Router *gin.RouterGroup) {
mallOrderRouter := Router.Group("v1").Use(middleware.UserJWTAuth())

var mallOrderRouterApi = v1.ApiGroupApp.MallApiGroup.MallOrderApi
{
mallOrderRouter.GET("/paySuccess", mallOrderRouterApi.PaySuccess) //模拟支付成功回调的接口
mallOrderRouter.PUT("/order/:orderNo/finish", mallOrderRouterApi.FinishOrder) //确认收货接口
mallOrderRouter.PUT("/order/:orderNo/cancel", mallOrderRouterApi.CancelOrder) //取消订单接口
mallOrderRouter.GET("/order/:orderNo", mallOrderRouterApi.OrderDetailPage) //订单详情接口
mallOrderRouter.GET("/order", mallOrderRouterApi.OrderList) //订单列表接口
mallOrderRouter.POST("/saveOrder", mallOrderRouterApi.SaveOrder)

}
}

model

model/mall/request/mall_order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package request

type PaySuccessParams struct {
OrderNo string `json:"orderNo"`
PayType int `json:"payType"`
}

type OrderSearchParams struct {
Status string `form:"status"`
PageNumber int `form:"pageNumber"`
}

type SaveOrderParam struct {
CartItemIds []int `json:"cartItemIds"`
AddressId int `json:"addressId"`
}

model/mall/response/mall_order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package response

import "main.go/model/common"

type MallOrderResponse struct {
OrderId int `json:"orderId"`
OrderNo string `json:"orderNo"`
TotalPrice int `json:"totalPrice"`
PayType int `json:"payType"`
OrderStatus int `json:"orderStatus"`
OrderStatusString string `json:"orderStatusString"`
CreateTime common.JSONTime `json:"createTime"`
NewBeeMallOrderItemVOS []NewBeeMallOrderItemVO `json:"newBeeMallOrderItemVOS"`
}

type NewBeeMallOrderItemVO struct {
GoodsId int `json:"goodsId"`
GoodsName string `json:"goodsName"`
GoodsCount int `json:"goodsCount"`
GoodsCoverImg string `json:"goodsCoverImg"`
SellingPrice int `json:"sellingPrice"`
}

type MallOrderDetailVO struct {
OrderNo string `json:"orderNo"`
TotalPrice int `json:"totalPrice"`
PayStatus int `json:"payStatus"`
PayType int `json:"payType"`
PayTypeString string `json:"payTypeString"`
PayTime common.JSONTime `json:"payTime"`
OrderStatus int `json:"orderStatus"`
OrderStatusString string `json:"orderStatusString"`
CreateTime common.JSONTime `json:"createTime"`
NewBeeMallOrderItemVOS []NewBeeMallOrderItemVO `json:"newBeeMallOrderItemVOS"`
}

model/manage/manage_order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package manage

import (
"main.go/model/common"
)

type MallOrder struct {
OrderId int `json:"orderId" form:"orderId" gorm:"primarykey;AUTO_INCREMENT"`
OrderNo string `json:"orderNo" form:"orderNo" gorm:"column:order_no;comment:订单号;type:varchar(20);"`
UserId int `json:"userId" form:"userId" gorm:"column:user_id;comment:用户主键id;type:bigint"`
TotalPrice int `json:"totalPrice" form:"totalPrice" gorm:"column:total_price;comment:订单总价;type:int"`
PayStatus int `json:"payStatus" form:"payStatus" gorm:"column:pay_status;comment:支付状态:0.未支付,1.支付成功,-1:支付失败;type:tinyint"`
PayType int `json:"payType" form:"payType" gorm:"column:pay_type;comment:0.无 1.支付宝支付 2.微信支付;type:tinyint"`
PayTime common.JSONTime `json:"payTime" form:"payTime" gorm:"column:pay_time;comment:支付时间;type:datetime"`
OrderStatus int `json:"orderStatus" form:"orderStatus" gorm:"column:order_status;comment:订单状态:0.待支付 1.已支付 2.配货完成 3:出库成功 4.交易成功 -1.手动关闭 -2.超时关闭 -3.商家关闭;type:tinyint"`
ExtraInfo string `json:"extraInfo" form:"extraInfo" gorm:"column:extra_info;comment:订单body;type:varchar(100);"`
IsDeleted int `json:"isDeleted" form:"isDeleted" gorm:"column:is_deleted;comment:删除标识字段(0-未删除 1-已删除);type:tinyint"`
CreateTime common.JSONTime `json:"createTime" form:"createTime" gorm:"column:create_time;comment:创建时间;type:datetime"`
UpdateTime common.JSONTime `json:"updateTime" form:"updateTime" gorm:"column:update_time;comment:最新修改时间;type:datetime"`
}

// TableName MallOrder 表名
func (MallOrder) TableName() string {
return "tb_newbee_mall_order"
}

api

api/v1/mall/mall_order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package mall

import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"main.go/global"
"main.go/model/common/response"
mallReq "main.go/model/mall/request"
"main.go/utils"
"strconv"
)

type MallOrderApi struct {
}

func (m *MallOrderApi) SaveOrder(c *gin.Context) {
var saveOrderParam mallReq.SaveOrderParam
_ = c.ShouldBindJSON(&saveOrderParam)
if err := utils.Verify(saveOrderParam, utils.SaveOrderParamVerify); err != nil {
response.FailWithMessage(err.Error(), c)
}
token := c.GetHeader("token")

priceTotal := 0
err, itemsForSave := mallShopCartService.GetCartItemsForSettle(token, saveOrderParam.CartItemIds)
if len(itemsForSave) < 1 {
response.FailWithMessage("无数据:"+err.Error(), c)
} else {
//总价
for _, newBeeMallShoppingCartItemVO := range itemsForSave {
priceTotal = priceTotal + newBeeMallShoppingCartItemVO.GoodsCount*newBeeMallShoppingCartItemVO.SellingPrice
}
if priceTotal < 1 {
response.FailWithMessage("价格异常", c)
}
_, userAddress := mallUserAddressService.GetMallUserDefaultAddress(token)
if err, saveOrderResult := mallOrderService.SaveOrder(token, userAddress, itemsForSave); err != nil {
global.GVA_LOG.Error("生成订单失败", zap.Error(err))
response.FailWithMessage("生成订单失败:"+err.Error(), c)
} else {
response.OkWithData(saveOrderResult, c)
}
}
}

func (m *MallOrderApi) PaySuccess(c *gin.Context) {
orderNo := c.Query("orderNo")
payType, _ := strconv.Atoi(c.Query("payType"))
if err := mallOrderService.PaySuccess(orderNo, payType); err != nil {
global.GVA_LOG.Error("订单支付失败", zap.Error(err))
response.FailWithMessage("订单支付失败:"+err.Error(), c)
}
response.OkWithMessage("订单支付成功", c)
}

func (m *MallOrderApi) FinishOrder(c *gin.Context) {
orderNo := c.Param("orderNo")
token := c.GetHeader("token")
if err := mallOrderService.FinishOrder(token, orderNo); err != nil {
global.GVA_LOG.Error("订单签收失败", zap.Error(err))
response.FailWithMessage("订单签收失败:"+err.Error(), c)
}
response.OkWithMessage("订单签收成功", c)

}

func (m *MallOrderApi) CancelOrder(c *gin.Context) {
orderNo := c.Param("orderNo")
token := c.GetHeader("token")
if err := mallOrderService.CancelOrder(token, orderNo); err != nil {
global.GVA_LOG.Error("订单签收失败", zap.Error(err))
response.FailWithMessage("订单签收失败:"+err.Error(), c)
}
response.OkWithMessage("订单签收成功", c)

}
func (m *MallOrderApi) OrderDetailPage(c *gin.Context) {
orderNo := c.Param("orderNo")
token := c.GetHeader("token")
if err, orderDetail := mallOrderService.GetOrderDetailByOrderNo(token, orderNo); err != nil {
global.GVA_LOG.Error("查询订单详情接口", zap.Error(err))
response.FailWithMessage("查询订单详情接口:"+err.Error(), c)
} else {
response.OkWithData(orderDetail, c)
}
}

func (m *MallOrderApi) OrderList(c *gin.Context) {
token := c.GetHeader("token")
pageNumber, _ := strconv.Atoi(c.Query("pageNumber"))
status := c.Query("status")
if pageNumber <= 0 {
pageNumber = 1
}
if err, list, total := mallOrderService.MallOrderListBySearch(token, pageNumber, status); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败"+err.Error(), c)
} else if len(list) < 1 {
// 前端项目这里有一个取数逻辑,如果数组为空,数组需要为[] 不能是Null
response.OkWithDetailed(response.PageResult{
List: make([]interface{}, 0),
TotalCount: total,
CurrPage: pageNumber,
PageSize: 5,
}, "SUCCESS", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
TotalCount: total,
CurrPage: pageNumber,
PageSize: 5,
}, "SUCCESS", c)
}

}

service

service/mall/mall_order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
package mall

import (
"errors"
"github.com/jinzhu/copier"
"main.go/global"
"main.go/model/common"
"main.go/model/common/enum"
"main.go/model/mall"
mallRes "main.go/model/mall/response"
"main.go/model/manage"
manageReq "main.go/model/manage/request"
"main.go/utils"
"time"
)

type MallOrderService struct {
}

// SaveOrder 保存订单
func (m *MallOrderService) SaveOrder(token string, userAddress mall.MallUserAddress, myShoppingCartItems []mallRes.CartItemResponse) (err error, orderNo string) {
var userToken mall.MallUserToken
err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
if err != nil {
return errors.New("不存在的用户"), orderNo
}
var itemIdList []int
var goodsIds []int
for _, cartItem := range myShoppingCartItems {
itemIdList = append(itemIdList, cartItem.CartItemId)
goodsIds = append(goodsIds, cartItem.GoodsId)
}
var newBeeMallGoods []manage.MallGoodsInfo
global.GVA_DB.Where("goods_id in ? ", goodsIds).Find(&newBeeMallGoods)
//检查是否包含已下架商品
for _, mallGoods := range newBeeMallGoods {
if mallGoods.GoodsSellStatus != enum.GOODS_UNDER.Code() {
return errors.New("已下架,无法生成订单"), orderNo
}
}
newBeeMallGoodsMap := make(map[int]manage.MallGoodsInfo)
for _, mallGoods := range newBeeMallGoods {
newBeeMallGoodsMap[mallGoods.GoodsId] = mallGoods
}
//判断商品库存
for _, shoppingCartItemVO := range myShoppingCartItems {
//查出的商品中不存在购物车中的这条关联商品数据,直接返回错误提醒
if _, ok := newBeeMallGoodsMap[shoppingCartItemVO.GoodsId]; !ok {
return errors.New("购物车数据异常!"), orderNo
}
if shoppingCartItemVO.GoodsCount > newBeeMallGoodsMap[shoppingCartItemVO.GoodsId].StockNum {
return errors.New("库存不足!"), orderNo
}
}
//删除购物项
if len(itemIdList) > 0 && len(goodsIds) > 0 {
if err = global.GVA_DB.Where("cart_item_id in ?", itemIdList).Updates(mall.MallShoppingCartItem{IsDeleted: 1}).Error; err == nil {
var stockNumDTOS []manageReq.StockNumDTO
copier.Copy(&stockNumDTOS, &myShoppingCartItems)
for _, stockNumDTO := range stockNumDTOS {
var goodsInfo manage.MallGoodsInfo
global.GVA_DB.Where("goods_id =?", stockNumDTO.GoodsId).First(&goodsInfo)
if err = global.GVA_DB.Where("goods_id =? and stock_num>= ? and goods_sell_status = 0", stockNumDTO.GoodsId, stockNumDTO.GoodsCount).Updates(manage.MallGoodsInfo{StockNum: goodsInfo.StockNum - stockNumDTO.GoodsCount}).Error; err != nil {
return errors.New("库存不足!"), orderNo
}
}
//生成订单号
orderNo = utils.GenOrderNo()
priceTotal := 0
//保存订单
var newBeeMallOrder manage.MallOrder
newBeeMallOrder.OrderNo = orderNo
newBeeMallOrder.UserId = userToken.UserId
//总价
for _, newBeeMallShoppingCartItemVO := range myShoppingCartItems {
priceTotal = priceTotal + newBeeMallShoppingCartItemVO.GoodsCount*newBeeMallShoppingCartItemVO.SellingPrice
}
if priceTotal < 1 {
return errors.New("订单价格异常!"), orderNo
}
newBeeMallOrder.CreateTime = common.JSONTime{Time: time.Now()}
newBeeMallOrder.UpdateTime = common.JSONTime{Time: time.Now()}
newBeeMallOrder.TotalPrice = priceTotal
newBeeMallOrder.ExtraInfo = ""
//生成订单项并保存订单项纪录
if err = global.GVA_DB.Save(&newBeeMallOrder).Error; err != nil {
return errors.New("订单入库失败!"), orderNo
}
//生成订单收货地址快照,并保存至数据库
var newBeeMallOrderAddress mall.MallOrderAddress
copier.Copy(&newBeeMallOrderAddress, &userAddress)
newBeeMallOrderAddress.OrderId = newBeeMallOrder.OrderId
//生成所有的订单项快照,并保存至数据库
var newBeeMallOrderItems []manage.MallOrderItem
for _, newBeeMallShoppingCartItemVO := range myShoppingCartItems {
var newBeeMallOrderItem manage.MallOrderItem
copier.Copy(&newBeeMallOrderItem, &newBeeMallShoppingCartItemVO)
newBeeMallOrderItem.OrderId = newBeeMallOrder.OrderId
newBeeMallOrderItem.CreateTime = common.JSONTime{Time: time.Now()}
newBeeMallOrderItems = append(newBeeMallOrderItems, newBeeMallOrderItem)
}
if err = global.GVA_DB.Save(&newBeeMallOrderItems).Error; err != nil {
return err, orderNo
}
}
}
return
}

// PaySuccess 支付订单
func (m *MallOrderService) PaySuccess(orderNo string, payType int) (err error) {
var mallOrder manage.MallOrder
err = global.GVA_DB.Where("order_no = ? and is_deleted=0 ", orderNo).First(&mallOrder).Error
if mallOrder != (manage.MallOrder{}) {
if mallOrder.OrderStatus != 0 {
return errors.New("订单状态异常!")
}
mallOrder.OrderStatus = enum.ORDER_PAID.Code()
mallOrder.PayType = payType
mallOrder.PayStatus = 1
mallOrder.PayTime = common.JSONTime{time.Now()}
mallOrder.UpdateTime = common.JSONTime{time.Now()}
err = global.GVA_DB.Save(&mallOrder).Error
}
return
}

// FinishOrder 完结订单
func (m *MallOrderService) FinishOrder(token string, orderNo string) (err error) {
var userToken mall.MallUserToken
err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
if err != nil {
return errors.New("不存在的用户")
}
var mallOrder manage.MallOrder
if err = global.GVA_DB.Where("order_no=? and is_deleted = 0", orderNo).First(&mallOrder).Error; err != nil {
return errors.New("未查询到记录!")
}
if mallOrder.UserId != userToken.UserId {
return errors.New("禁止该操作!")
}
mallOrder.OrderStatus = enum.ORDER_SUCCESS.Code()
mallOrder.UpdateTime = common.JSONTime{time.Now()}
err = global.GVA_DB.Save(&mallOrder).Error
return
}

// CancelOrder 关闭订单
func (m *MallOrderService) CancelOrder(token string, orderNo string) (err error) {
var userToken mall.MallUserToken
err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
if err != nil {
return errors.New("不存在的用户")
}
var mallOrder manage.MallOrder
if err = global.GVA_DB.Where("order_no=? and is_deleted = 0", orderNo).First(&mallOrder).Error; err != nil {
return errors.New("未查询到记录!")
}
if mallOrder.UserId != userToken.UserId {
return errors.New("禁止该操作!")
}
if utils.NumsInList(mallOrder.OrderStatus, []int{enum.ORDER_SUCCESS.Code(),
enum.ORDER_CLOSED_BY_MALLUSER.Code(), enum.ORDER_CLOSED_BY_EXPIRED.Code(), enum.ORDER_CLOSED_BY_JUDGE.Code()}) {
return errors.New("订单状态异常!")
}
mallOrder.OrderStatus = enum.ORDER_CLOSED_BY_MALLUSER.Code()
mallOrder.UpdateTime = common.JSONTime{time.Now()}
err = global.GVA_DB.Save(&mallOrder).Error
return
}

// GetOrderDetailByOrderNo 获取订单详情
func (m *MallOrderService) GetOrderDetailByOrderNo(token string, orderNo string) (err error, orderDetail mallRes.MallOrderDetailVO) {
var userToken mall.MallUserToken
err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
if err != nil {
return errors.New("不存在的用户"), orderDetail
}
var mallOrder manage.MallOrder
if err = global.GVA_DB.Where("order_no=? and is_deleted = 0", orderNo).First(&mallOrder).Error; err != nil {
return errors.New("未查询到记录!"), orderDetail
}
if mallOrder.UserId != userToken.UserId {
return errors.New("禁止该操作!"), orderDetail
}
var orderItems []manage.MallOrderItem
err = global.GVA_DB.Where("order_id = ?", mallOrder.OrderId).Find(&orderItems).Error
if len(orderItems) <= 0 {
return errors.New("订单项不存在!"), orderDetail
}

var newBeeMallOrderItemVOS []mallRes.NewBeeMallOrderItemVO
copier.Copy(&newBeeMallOrderItemVOS, &orderItems)
copier.Copy(&orderDetail, &mallOrder)
// 订单状态前端显示为中文
_, OrderStatusStr := enum.GetNewBeeMallOrderStatusEnumByStatus(orderDetail.OrderStatus)
_, payTapStr := enum.GetNewBeeMallOrderStatusEnumByStatus(orderDetail.PayType)
orderDetail.OrderStatusString = OrderStatusStr
orderDetail.PayTypeString = payTapStr
orderDetail.NewBeeMallOrderItemVOS = newBeeMallOrderItemVOS

return
}

// MallOrderListBySearch 搜索订单
func (m *MallOrderService) MallOrderListBySearch(token string, pageNumber int, status string) (err error, list []mallRes.MallOrderResponse, total int64) {
var userToken mall.MallUserToken
err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
if err != nil {
return errors.New("不存在的用户"), list, total
}
// 根据搜索条件查询
var newBeeMallOrders []manage.MallOrder
db := global.GVA_DB.Model(&newBeeMallOrders)

if status != "" {
db.Where("order_status = ?", status)
}
err = db.Where("user_id =? and is_deleted=0 ", userToken.UserId).Count(&total).Error
//这里前段没有做滚动加载,直接显示全部订单
//limit := 5
offset := 5 * (pageNumber - 1)
err = db.Offset(offset).Order(" order_id desc").Find(&newBeeMallOrders).Error

var orderListVOS []mallRes.MallOrderResponse
if total > 0 {
//数据转换 将实体类转成vo
copier.Copy(&orderListVOS, &newBeeMallOrders)
//设置订单状态中文显示值
for _, newBeeMallOrderListVO := range orderListVOS {
_, statusStr := enum.GetNewBeeMallOrderStatusEnumByStatus(newBeeMallOrderListVO.OrderStatus)
newBeeMallOrderListVO.OrderStatusString = statusStr
}
// 返回订单id
var orderIds []int
for _, order := range newBeeMallOrders {
orderIds = append(orderIds, order.OrderId)
}
//获取OrderItem
var orderItems []manage.MallOrderItem
if len(orderIds) > 0 {
global.GVA_DB.Where("order_id in ?", orderIds).Find(&orderItems)
itemByOrderIdMap := make(map[int][]manage.MallOrderItem)
for _, orderItem := range orderItems {
itemByOrderIdMap[orderItem.OrderId] = []manage.MallOrderItem{}
}
for k, v := range itemByOrderIdMap {
for _, orderItem := range orderItems {
if k == orderItem.OrderId {
v = append(v, orderItem)
}
itemByOrderIdMap[k] = v
}
}
//封装每个订单列表对象的订单项数据
for _, newBeeMallOrderListVO := range orderListVOS {
if _, ok := itemByOrderIdMap[newBeeMallOrderListVO.OrderId]; ok {
orderItemListTemp := itemByOrderIdMap[newBeeMallOrderListVO.OrderId]
var newBeeMallOrderItemVOS []mallRes.NewBeeMallOrderItemVO
copier.Copy(&newBeeMallOrderItemVOS, &orderItemListTemp)
newBeeMallOrderListVO.NewBeeMallOrderItemVOS = newBeeMallOrderItemVOS
_, OrderStatusStr := enum.GetNewBeeMallOrderStatusEnumByStatus(newBeeMallOrderListVO.OrderStatus)
newBeeMallOrderListVO.OrderStatusString = OrderStatusStr
list = append(list, newBeeMallOrderListVO)
}
}
}
}
return err, list, total
}

0%