确认订单页面
确认订单页面相关逻辑见 golang gin框架] 30.Gin 商城项目- 购物车商品确认页面以及收货地址的增删改查
点击 '去支付'按钮逻辑:
(1).判断用户是否存在地址,不存在则新增并设置为默认地址
(2).点击'去支付',请求提交订单执行结算操作:
订单执行结算操作步骤:
1).防止重复提交订单
2).获取用户信息 ,获取用户的收货地址信息
3).获取购买商品的信息
4).把订单信息放在订单表,把商品信息放在订单商品表
5).删除购物车里面的选中数据
6).跳转到支付页面


去支付页面
展示支付商品相关数据:
订单数据,订单详情数据

数据表
增加订单数据表,订单商品数据表
-- ----------------------------
-- Table structure for order
-- ----------------------------
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (`id` int(0) NOT NULL AUTO_INCREMENT,`uid` int(0) NULL DEFAULT NULL,`order_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`all_price` decimal(10, 2) NULL DEFAULT NULL,`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`zipcode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`pay_status` tinyint(1) NULL DEFAULT NULL,`pay_type` tinyint(1) NULL DEFAULT NULL,`order_status` tinyint(1) NULL DEFAULT NULL,`add_time` int(0) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 62 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for order_item
-- ----------------------------
DROP TABLE IF EXISTS `order_item`;
CREATE TABLE `order_item` (`id` int(0) NOT NULL AUTO_INCREMENT,`order_id` int(0) NULL DEFAULT NULL,`uid` int(0) NULL DEFAULT NULL,`product_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`product_id` int(0) NULL DEFAULT NULL,`product_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`product_price` decimal(10, 2) NULL DEFAULT NULL,`product_num` int(0) NULL DEFAULT NULL,`goods_version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`goods_color` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`add_time` int(0) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 83 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
数据模型
order.go
package models//订单表相关结构体type Order struct {Id intOrderId string //订单号Uid int //用户idAllPrice float64 //订单总价Phone string //收货人手机号Name string //收货人姓名Address string //收货地址PayStatus int // 支付状态: 0 表示未支付, 1 已经支付PayType int // 支付类型: 0 alipay, 1 wechatOrderStatus int // 订单状态: 0 已下单 ,1 已付款,2 已配货,3、发货, 4 交易成功, 5 退货, 6 取消AddTime int //订单生成时间
}func (Order) TableName() string {return "order"
}
orderItem.go
package models//订单商品数据相关结构体type OrderItem struct {Id intOrderId int //订单号Uid int //用户idProductTitle string //商品名称ProductId int //商品idProductImg string //商品图片ProductPrice float64 //商品单价ProductNum int //购买数量GoodsVersion string //商品版本GoodsColor string //商品颜色AddTime int //增加订单商品时间
}func (OrderItem) TableName() string {return "order_item"
}
路由
增加以下路由到routers/frontendRouters.go中
//购物车:确认选中商品页面:增加一个中间件:判断用户权限
defaultRouters.GET("/buy/checkout", middlewares.InitUserAuthMiddleware, frontend.BuyController{}.Checkout)
//提交订单执行结算
defaultRouters.POST("/buy/doCheckout", middlewares.InitUserAuthMiddleware, frontend.BuyController{}.DoCheckout)
//支付:去结支付页面
defaultRouters.GET("/buy/pay", middlewares.InitUserAuthMiddleware, frontend.BuyController{}.Pay)
tools.go工具类
增加 获取订单编号的方法
//生成随机数
func GetRandomNum() string {var str stringfor i := 0; i < 4; i++ {current := rand.Intn(10)str += strconv.Itoa(current)}return str
}// 获取订单编号
func GetOrderId() string {// 2022020312233temp := "20060102150405"return time.Now().Format(temp) + GetRandomNum()
}
控制器方法代码
在controllers/BuyControllers.go中完善以及增加相关方法:
完善方法:
确认订单页面方法-Checkout:
生成签名: 进入'订单结算页面'时,防止重复提交订单
增加方法:
提交订单执行结算方法-DoCheckout:
1.防止重复提交订单
2.获取用户信息 ,获取用户的收货地址信息
3.获取购买商品的信息
4.把订单信息放在订单表,把商品信息放在订单商品表
5.删除购物车里面的选中数据
6.跳转到支付页面
支付(去支付页面)方法-Pay:
获取订单相关信息,并渲染到对应的html页面
package frontend//购买商品相关控制器import ("fmt""github.com/gin-contrib/sessions""github.com/gin-gonic/gin""goshop/models""net/http"
)type BuyController struct {BaseController
}//确认订单页面
func (con BuyController) Checkout(c *gin.Context) {//获取购物车中选择的商品cartList := []models.Cart{}models.Cookie.Get(c, "cartList", &cartList)//选中的商品orderList := []models.Cart{}//总价格var allPrice float64//总数量var allNum int//循环购物车,并获取选中的商品信息for i := 0; i < len(cartList); i++ {if cartList[i].Checked {allPrice += cartList[i].Price * float64(cartList[i].Num)orderList = append(orderList, cartList[i])allNum += cartList[i].Num}}//获取当前用户的收货地址//获取用户user := models.User{}models.Cookie.Get(c, "user", &user)addressList := []models.Address{}fmt.Println(user)//通过用户id获取收货地址列表models.DB.Where("uid = ?", user.Id).Order("id desc").Find(&addressList)//生成签名: 进入'订单结算页面'时,防止重复提交订单orderSign := models.Md5(models.GetRandomNum())session := sessions.Default(c)session.Set("orderSign", orderSign)session.Save()//判断orderList数据是否存在if len(orderList) == 0 { //不存在,则跳转到购物车页面c.Redirect(http.StatusFound, "/cart")return}con.Render(c, "frontend/buy/checkout.html", gin.H{"orderList": orderList,"allPrice": allPrice,"allNum": allNum,"addressList": addressList,"orderSign": orderSign,})
}/*
提交订单执行结算1.防止重复提交订单2.获取用户信息 ,获取用户的收货地址信息3.获取购买商品的信息4.把订单信息放在订单表,把商品信息放在订单商品表5.删除购物车里面的选中数据6.跳转到支付页面
*/
func (con BuyController) DoCheckout(c *gin.Context) {//1.防止重复提交订单//获取签名orderSignClient := c.PostForm("orderSign")session := sessions.Default(c)//获取session中保存的签名orderSignSession := session.Get("orderSign")//进行类型断言,转换成string类型orderSignServer, ok := orderSignSession.(string)if !ok { //转换失败或者没有签名,则跳转到 '购物车' 页面c.Redirect(http.StatusFound, "/cart")return}//判断传入的签名和session中保存的签名是否一致,一致:说明是上一步传过来的,不一致:说明不是上一步传过来的,跳转到购物车页面if orderSignClient != orderSignServer {c.Redirect(http.StatusFound, "/cart")return}//判断完毕后,删除签名session.Delete("orderSign")session.Save()// 2.获取用户信息,获取用户的收货地址信息user := models.User{}models.Cookie.Get(c, "user", &user)//定义用户默认收货地址结构体addressResult := []models.Address{}models.DB.Where("uid = ? AND default_address = 1", user.Id).Find(&addressResult)//判断是否存在默认收货地址,如果不存在,则跳转到'确认订单'页面if len(addressResult) == 0 {c.Redirect(http.StatusFound, "/buy/checkout")return}// 3.获取购买商品的信息:可以从cookie中获取,如果创建了购物车数据表,也可以从购物车数据表中获取//目前从cookie中获取选中的商品cartList := []models.Cart{}models.Cookie.Get(c, "cartList", &cartList)//定义选中商品结构体orderList := []models.Cart{}var allPrice float64//循环购物车中商品,把选中的商品放入orderList结构体中for i := 0; i < len(cartList); i++ {if cartList[i].Checked {allPrice += cartList[i].Price * float64(cartList[i].Num)orderList = append(orderList, cartList[i])}}// 4.把订单信息放在订单表,把商品信息放在商品表order := models.Order{OrderId: models.GetOrderId(),Uid: user.Id,AllPrice: allPrice,Phone: addressResult[0].Phone,Name: addressResult[0].Name,Address: addressResult[0].Address,PayStatus: 0,PayType: 0,OrderStatus: 0,AddTime: int(models.GetUnix()),}err := models.DB.Create(&order).Error//增加数据成功以后可以通过order.Idif err == nil {// 把商品信息放在商品订单表for i := 0; i < len(orderList); i++ {orderItem := models.OrderItem{OrderId: order.Id,Uid: user.Id,ProductTitle: orderList[i].Title,ProductId: orderList[i].Id,ProductImg: orderList[i].GoodsImg,ProductPrice: orderList[i].Price,ProductNum: orderList[i].Num,GoodsVersion: orderList[i].GoodsVersion,GoodsColor: orderList[i].GoodsColor,}models.DB.Create(&orderItem)}}// 5.删除购物车里面的选中数据noSelectCartList := []models.Cart{}for i := 0; i < len(cartList); i++ {if !cartList[i].Checked {noSelectCartList = append(noSelectCartList, cartList[i])}}models.Cookie.Set(c, "cartList", noSelectCartList)//跳转到'去支付'页面c.Redirect(http.StatusFound, "/buy/pay?orderId="+models.String(order.Id))
}//支付:去支付页面
func (con BuyController) Pay(c *gin.Context) {//获取订单idorderId, err := models.Int(c.Query("orderId"))if err != nil { // 订单id类型错误c.Redirect(http.StatusFound, "/cart")}//获取用户信息user := models.User{}models.Cookie.Get(c, "user", &user)//获取订单信息order := models.Order{}models.DB.Where("id = ?", orderId).Find(&order)if order.Uid != user.Id { //订单信息错误c.Redirect(http.StatusFound, "/cart")return}//获取订单对应的商品orderItems := []models.OrderItem{}models.DB.Where("order_id = ?", orderId).Find(&orderItems)//渲染页面con.Render(c, "frontend/buy/pay.html", gin.H{"order": order,"orderItems": orderItems,})
}
html以及js代码
确认订单页面html-frontend/buy/checkout.html
判断用户是否存在地址,不存在则新增并设置为默认地址
确认订单js
增加提交判断方法onSubmit: 是否存在默认收货地址; 在app中引入,其他js见 golang gin框架] 30.Gin 商城项目- 购物车商品确认页面以及收货地址的增删改查,代码如下
init: function () {this.addAddress();this.changeDefaultAddress();this.editAddress();this.onSubmit();},
onSubmit: function () {$("#checkoutForm").submit(function () {//判断收货地址是否选中var addressCount = $("#addressList .address-item.selected").length;if (addressCount > 0) {return true;}alert('请选择收货地址');return false;})},
去支付页面html
在templates/frontend/buy下增加pay.html页面,展示订单相关信息
[上一节][golang gin框架] 30.Gin 商城项目- 购物车商品确认页面以及收货地址的增删改查
[下一节][golang gin框架] 32.Gin 商城项目- 支付宝支付操作相关功能讲解