[golang gin框架] 30.Gin 商城项目- 购物车商品确认页面以及收货地址的增删改查

news2024/10/6 20:40:43

一.界面展示

  1. 购物车页面

增加功能: 展示用户加入的购物车数据,并点击‘去结算’按钮, 判断是否选中商品
  1. 确认订单页面

展示 选中的购物车商品数据(商品标题,图片,数量等)以及 结算的数据(总的价格,总的数量等)
展示 展示收货地址列表修改单个收货地址内容(该操作会涉及到模态框知识)增加收货地址(该操作会涉及到模态框知识)修改默认收货地址

二.代码展示

  1. 操作步骤说明

(1). 选中购物车商品, 点击 ‘去结算’进入 ‘确认订单’页面
点击 ‘去结算’时会 判断是否选中商品
在进入‘确认订单’页面之前,会通过 中间件判断用户 是否登录
没有登录:跳转到登录页面,登录成功后返回(在这个过程中会把缓存中的 购物车数据同步更新到数据库中,以后用户就可以从数据库中获取对应的购物车数据啦,该逻辑自己去实现,本次没有讲解)
登录了:直接进入‘确认订单’页面
(2).‘确认订单’页面逻辑
1). 获取用户的收货地址
a. 展示收货地址列表
b. 新增收货地址
c. 修改收货地址
d. 修改默认地址
e.删除收货地址(该操作在后续的个人管理->收货地址管理里面实现)
2).获取选中的商品,并展示对应的信息
  1. 相关数据表

-- ----------------------------
-- Table structure for address 用户收货地址表
-- ----------------------------
DROP TABLE IF EXISTS `address`;
CREATE TABLE `address`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `uid` int(0) NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL  comment '收件人是',
  `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL  comment '手机号',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL  comment '收件地址',
  `default_address` tinyint(1) NULL DEFAULT NULL comment '是否默认地址:0 否, 1 是',
  `add_time` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 46 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of address
-- ----------------------------
INSERT INTO `address` VALUES (42, 12, '李四', '15201686411', '北京市 海淀区 西二旗 xxx好11', 0, 0);
INSERT INTO `address` VALUES (43, 12, '张三', '15201686412', '深圳市   宝安区  xxx 2222222', 1, 0);
INSERT INTO `address` VALUES (44, 12, '王五', '15201686412', '上海市 xxx11 222 111', 0, 0);
INSERT INTO `address` VALUES (45, 12, '赵六', '15201686412', '上海市 xxx 22', 0, 0);
  1. 中间件

在middlewares下创建userAuth.go中间件,该中间件的作用:当路由引入了该中间件后,在请求对应的路由时会先执行该中间件,该中间件会判断用户是否登录,一句话来讲: 执行该中间件,只有登录了的用户才能访问该路由
package middlewares

//中间件: 作用: 在执行路由之前或者之后进行相关逻辑判断

import (
    "github.com/gin-gonic/gin"
    "goshop/models"
    "net/http"
)

func InitUserAuthMiddleware(c *gin.Context) {
    //获取Cookie里面保存的用户信息
    user := models.User{}
    isLogin := models.Cookie.Get(c, "userinfo", &user)
    if !isLogin || len(user.Phone) != 11 { // 用户没有登录或者账号不正确, 跳转到登录页面
        c.Redirect(http.StatusFound, "/pass/login")
        return
    }
}
  1. 收货地址模型

在models下创建Address.go收货地址结构体
package models

//收货地址相关

type Address struct {
    Id             int    `json:"id"`
    Uid            int    `json:"uid"`
    Phone          string `json:"phone"`
    Name           string `json:"name"`
    Address        string `json:"address"`
    DefaultAddress int    `json:"default_address"`  //默认地址:0 否, 1 是
    AddTime        int    `json:"add_time"`
}

func (Address) TableName() string {
    return "address"
}
  1. 结算页面控制器

在controllers下创建BuyController.go商品结算控制器,实现方法:
结算页面方法Checkout获取购物车中的数据; 获取当前用户的收货地址列表
package frontend

//购物车商品选中结算页面

import (
    "github.com/gin-gonic/gin"
    "goshop/models"
)

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, "userinfo", &user)
    addressList := []models.Address{}
    //通过用户id获取收货地址列表
    models.DB.Where("uid = ?", user.Id).Order("id desc").Find(&addressList)
    con.Render(c, "frontend/buy/checkout.html", gin.H{
        "orderList": orderList,
        "allPrice":    allPrice,
        "allNum":      allNum,
        "addressList": addressList,
    })
}
  1. 收货地址控制器

在controllers下创建AddressController.go收货地址控制器,实现方法:
增加收货地址AddAddress()
获取一个收货地址 :返回指定收货地址id的收货地址GetOneAddressList()
编辑收货地址EditAddress()
修改默认的收货地址ChangeDefaultAddress()
package frontend

//收货地址相关

import (
    "github.com/gin-gonic/gin"
    "goshop/models"
    "net/http"
)

type AddressController struct {
    BaseController
}

//增加收货地址
func (con AddressController) AddAddress(c *gin.Context) {
    /*
       1、获取用户信息以及 表单提交的数据
       2、判断收货地址的数量
       3、更新当前用户的所有收货地址的默认收货地址状态为0
       4、增加当前收货地址,让默认收货地址状态是1
       5、返回当前用户的所有收货地址返回
    */
    //  1、获取用户信息以及 表单提交的数据
    user := models.User{}
    models.Cookie.Get(c, "userinfo", &user)
    name := c.PostForm("name")
    phone := c.PostForm("phone")
    address := c.PostForm("address")
    // 2、判断收货地址的数量
    var addressNum int64
    models.DB.Table("address").Where("uid = ?", user.Id).Count(&addressNum)
    if addressNum > 10 {
        c.JSON(200, gin.H{
            "success": false,
            "message": "收货地址的数量超过了限制,请编辑以前的收货地址",
        })
        return
    }

    // 3、更新当前用户的所有收货地址的默认收货地址状态为0
    models.DB.Table("address").Where("uid = ?", user.Id).Updates(map[string]interface{}{"default_address": 0})

    // 4、增加当前收货地址,让默认收货地址状态是1
    addressResult := models.Address{
        Uid:            user.Id,
        Name:           name,
        Phone:          phone,
        Address:        address,
        DefaultAddress: 1,
        AddTime:        int(models.GetUnix()),
    }
    models.DB.Create(&addressResult)

    // 5、返回当前用户的所有收货地址返回
    addressList := []models.Address{}
    models.DB.Where("uid = ?", user.Id).Order("id desc").Find(&addressList)

    c.JSON(http.StatusOK, gin.H{
        "success": true,
        "result":  addressList,
    })
}

// 获取一个收货地址  返回指定收货地址id的收货地址
func (con AddressController) GetOneAddressList(c *gin.Context) {
    //1、获取addressId
    addressId, err := models.Int(c.Query("addressId"))
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "传入参数错误",
        })
        return
    }
    //2、获取用户id
    user := models.User{}
    models.Cookie.Get(c, "userinfo", &user)

    //3、查询当前addressId  userID对应的数据
    addressList := []models.Address{}
    models.DB.Where("id = ? AND uid = ?", addressId, user.Id).Find(&addressList)
    if len(addressList) > 0 {
        c.JSON(http.StatusOK, gin.H{
            "success": true,
            "result":  addressList[0],
        })
    } else {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "传入参数错误",
        })
        return
    }
}

// 编辑收货地址
func (con AddressController) EditAddress(c *gin.Context) {
    /*
       1、获取用户信息以及 表单修改的数据
       2、更新当前用户的所有收货地址的默认收货地址状态为0
       3、修改当前收货地址,让默认收货地址状态是1
       4、查询当前用户的所有收货地址并返回
    */
    // 1、获取用户信息以及 表单修改的数据
    user := models.User{}
    models.Cookie.Get(c, "userinfo", &user)
    id, err := models.Int(c.PostForm("id"))
    name := c.PostForm("name")
    phone := c.PostForm("phone")
    address := c.PostForm("address")
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "传入参数错误",
        })
        return
    }

    // 2、更新当前用户的所有收货地址的默认收货地址状态为0
    models.DB.Table("address").Where("uid = ?", user.Id).Updates(map[string]interface{}{"default_address": 0})

    // 3、修改当前收货地址,让默认收货地址状态是1
    editAddress := models.Address{Id: id}
    models.DB.Find(&editAddress)
    editAddress.Name = name
    editAddress.Phone = phone
    editAddress.Address = address
    editAddress.DefaultAddress = 1
    models.DB.Save(&editAddress)

    // 4、返回当前用户的所有收货地址返回
    addressList := []models.Address{}
    models.DB.Where("uid = ?", user.Id).Order("id desc").Find(&addressList)
    c.JSON(http.StatusOK, gin.H{
        "success": true,
        "result":  addressList,
    })
}

// 修改默认的收货地址 
func (con AddressController) ChangeDefaultAddress(c *gin.Context) {
    /*
       1、获取当前用户收货地址id 以及用户id
       2、更新当前用户的所有收货地址的默认收货地址状态为0
       3、更新当前收货地址的默认收货地址状态为1
    */
    //1、获取当前用户收货地址id 以及用户id
    user := models.User{}
    models.Cookie.Get(c, "userinfo", &user)
    addressId, err := models.Int(c.Query("addressId"))
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "传入参数错误",
        })
        return
    }
    //2、更新当前用户的所有收货地址的默认收货地址状态为0
    models.DB.Table("address").Where("uid = ?", user.Id).Updates(map[string]interface{}{"default_address": 0})
    //3、更新当前收货地址的默认收货地址状态为1
    models.DB.Table("address").Where("uid = ? AND id = ?", user.Id, addressId).Updates(map[string]interface{}{"default_address": 1})

    c.JSON(http.StatusOK, gin.H{
        "success": true,
        "message": "修改数据成功",
    })
}
  1. 路由

增加相关路由到routers/frontendRouters.go文件中
//购物车:确认选中商品页面:增加一个中间件:判断用户权限
defaultRouters.GET("/buy/checkout", middlewares.InitUserAuthMiddleware, frontend.BuyController{}.Checkout)
//收货地址:增加收货地址
defaultRouters.POST("/address/addAddress", middlewares.InitUserAuthMiddleware, frontend.AddressController{}.AddAddress)
//收货地址:编辑收货地址
defaultRouters.POST("/address/editAddress", middlewares.InitUserAuthMiddleware, frontend.AddressController{}.EditAddress)
//收货地址:修改默认收货地址
defaultRouters.GET("/address/changeDefaultAddress", middlewares.InitUserAuthMiddleware, frontend.AddressController{}.ChangeDefaultAddress)
//收货地址:获取一个指定收货地址id的收货地址
defaultRouters.GET("/address/getOneAddressList", middlewares.InitUserAuthMiddleware, frontend.AddressController{}.GetOneAddressList)
  1. 购物车页面html,js

增加一个功能: 点击'去结算'按钮时,js判断是否选中购物车,如果选中了,则跳转到 '确认订单' 页面,没有选中则提示用户

cart.html

{{ define "frontend/cart/cart.html" }}
    {{ template "frontend/public/page_header.html" .}}
    <link rel="stylesheet" type="text/css" href="/static/frontend/css/cart.css">
    <script src="/static/frontend/js/cart.js"></script>
    <!-- start banner_x -->
    <div class="banner_x center">
        <a href="/">
            <div class="logo fl"></div>
        </a>
        <div class="wdgwc fl ml40">我的购物车</div>
        <div class="wxts fl ml20">温馨提示:产品是否购买成功,以最终下单为准哦,请尽快结算</div>
        <div class="dlzc fr">
            <ul>
                <li><a href="./login.html" target="_blank">登录</a></li>
                <li>|</li>
                <li><a href="./register.html" target="_blank">注册</a></li>
            </ul>

        </div>
        <div class="clear"></div>
    </div>
    <div class="xiantiao"></div>
    <div class="gwcxqbj">
        <div class="gwcxd center">
            <table class="table">

                <tr class="th">
                    <th>
                        <input type="checkbox" id="checkAll"/>
                        全选
                    </th>
                    <th>
                        商品名称
                    </th>
                    <th>单价</th>
                    <th>数量</th>
                    <th>小计</th>
                    <th>操作</th>
                </tr>
                {{range $key,$value := .cartList}}
                    <tr class="cart_list">
                        <td>
                            <input type="checkbox" goods_id="{{$value.Id}}"
                                   goods_color="{{$value.GoodsColor}}" {{if eq $value.Checked true}} checked {{end}} />
                        </td>
                        <td>
                            <div class="col_pic">
                                <img src="{{$value.GoodsImg | FormatImg}}"/>
                            </div>
                            <div class="col_title">
                                {{$value.Title}} -- {{$value.GoodsColor}} {{$value.GoodsVersion}}
                            </div>
                        </td>
                        <td class="price">
                            {{$value.Price}}元
                        </td>
                        <td>
                            <div class="cart_number">
                                <div class="input_left decCart" goods_id="{{$value.Id}}"
                                     goods_color="{{$value.GoodsColor}}">-
                                </div>
                                <div class="input_center">
                                    <input id="num" name="num" readonly="readonly" type="text" value="{{$value.Num}}"/>
                                </div>
                                <div class="input_right incCart" goods_id="{{$value.Id}}"
                                     goods_color="{{$value.GoodsColor}}">+
                                </div>
                           </div>
                        </td>
                        <td class="totalPrice">
                            {{ Mul $value.Price $value.Num}}元
                        </td>
                        <td>
                            <span><a href="/cart/delCart?goods_id={{$value.Id}}&goods_color={{$value.GoodsColor}}"
                                     class="delete"> 删除</a></span>
                        </td>
                    </tr>

                {{end}}
            </table>
        </div>
        <div class="jiesuandan mt20 center">
            <div class="tishi fl ml20">
                <ul>
                    <li><a href="./liebiao.html">继续购物</a></li>
                    <li>|</li>
                    <li>共<span>2</span>件商品,已选择<span>1</span>件</li>
                    <div class="clear"></div>
                </ul>
            </div>
            <div class="jiesuan fr">
                <div class="jiesuanjiage fl">合计(不含运费):<span id="allPrice">{{.allPrice}}元</span></div>
                <div class="jsanniu fr"><input class="jsan" id="checkout" type="submit" name="jiesuan"  value="去结算"/></div>
                <div class="clear"></div>
            </div>
            <div class="clear"></div>
        </div>
    </div>
    <!-- footer -->
    {{ template "frontend/public/page_footer.html" .}}
    </body>
    </html>
{{end}}

cart.js

(function ($) {
    var app = {
        init: function () {
            this.changeCartNum();
            this.deleteConfirm();
            this.initCheckBox();
            this.isCheckedAll();
            this.initChekOut();
        },
        initChekOut(){ //点击'去结算'按钮时,判断是否选中购物车,如果选中了,则跳转到 '确认订单' 页面
            $(function(){
                $("#checkout").click(function(){
                    var allPrice=parseFloat($("#allPrice").html());
                    if(allPrice==0){
                        alert('购物车没有选中去结算的商品')
                    }else{
                        location.href="/buy/checkout";
                    }
                })
            })
        },
        deleteConfirm: function () { //删除确认
            $('.delete').click(function () {
                var flag = confirm('您确定要删除吗?');
                return flag;
            })

        },
        changeCartNum() {  // 改变购物车数据
            $('.decCart').click(function () {  //减少数量
                //获取商品id,商品颜色
                var goods_id = $(this).attr("goods_id")
                var goods_color = $(this).attr("goods_color")
                var _that = this;
                //请求url
                $.get('/cart/decCart?goods_id=' + goods_id + '&goods_color=' + goods_color, function (response) {
                    if (response.success) { //改变成功
                        //更新总商品价格
                        $("#allPrice").html(response.allPrice + "元")
                        //更新对应商品数量
                        $(_that).siblings(".input_center").find("input").val(response.num)
                        //更新对应商品价格小计
                        $(_that).parent().parent().siblings(".totalPrice").html(response.currentPrice + "元")
                    }
                })
            });

            $('.incCart').click(function () {  // 增加数量
                var goods_id = $(this).attr("goods_id")
                var goods_color = $(this).attr("goods_color")
                var _that = this;
                $.get('/cart/incCart?goods_id=' + goods_id + '&goods_color=' + goods_color, function (response) {
                    console.log(response)
                    if (response.success) {
                        $("#allPrice").html(response.allPrice + "元")
                        $(_that).siblings(".input_center").find("input").val(response.num)
                        $(_that).parent().parent().siblings(".totalPrice").html(response.currentPrice + "元")
                    }
                })
            });
        },

        initCheckBox(){  //改变一个商品数据的选中状态
            //全选按钮点击
            $("#checkAll").click(function() {
                if (this.checked) {
                    $(":checkbox").prop("checked", true);
                    //让cookie中商品的checked属性都等于true
                    $.get('/cart/changeAllCart?flag=1',function(response){
                        if(response.success){
                            $("#allPrice").html(response.allPrice+"元")
                        }
                    })
                }else {
                    $(":checkbox").prop("checked", false);
                    //让cookie中商品的checked属性都等于false
                    $.get('/cart/changeAllCart?flag=0',function(response){
                        if(response.success){
                            $("#allPrice").html(response.allPrice+"元")
                        }
                    })
                }
            });

            //点击单个选择框按钮的时候触发
            var _that=this;
            $(".cart_list :checkbox").click(function() {
                _that.isCheckedAll();
                var goods_id=$(this).attr("goods_id")
                var goods_color=$(this).attr("goods_color")
                $.get('/cart/changeOneCart?goods_id='+goods_id+'&goods_color='+goods_color,function(response){
                    if(response.success){
                        $("#allPrice").html(response.allPrice+"元")
                    }
                })


            });   //注意:this指向
        },

        isCheckedAll(){   //判断全选是否选择
            var allNum = $(".cart_list :checkbox").size();//checkbox总个数
            var checkedNum = 0;
            $(".cart_list :checkbox").each(function () {
                if($(this).prop("checked")==true){
                    checkedNum++;
                }
            });
            if(allNum==checkedNum){//全选
                $("#checkAll").prop("checked",true);
            }else{//不全选
                $("#checkAll").prop("checked",false);
            }
        },
    }

    $(function () {
        app.init();
    })
})($)
  1. html,js

确认订单页面html

该页面逻辑:
实现: 展示收货地址列表修改单个收货地址内容(该操作会涉及到模态框知识)增加收货地址(该操作会涉及到模态框知识)修改默认收货地址展示选中购物车商品信息(商品图片,标题,个数,价格等,以及总的价格,个数等信息)
{{ define "frontend/buy/checkout.html" }}
{{ template "frontend/public/page_header.html" .}}
<!--end header -->
<link rel="stylesheet" href="/static/frontend/css/checkout.css" />
<link rel="stylesheet" href="/static/frontend/css/bootstrap.css" />
<script src="/static/frontend/js/bootstrap.js"></script>
<script src="/static/frontend/js/checkout.js"></script>
<!-- start banner_x -->
<div class="banner_x center clearfix mt20">
    <a href="/" target="_blank">
        <div class="logo fl"></div>
    </a>
    <div class="wdgwc fl ml40">确认订单 </div>
</div>

<div class="checkout-box">
    <div class="section section-address">
        <div class="section-header clearfix">
            <h3 class="title">收货地址</h3>
            <div class="more">
            </div>
            <div class="mitv-tips hide" style="margin-left: 0;border: none;" id="J_bigproPostTip"></div>
        </div>
        <div class="section-body clearfix" id="J_addressList">
            <!-- addresslist begin -->
            <div id="addressList">
                {{range $key,$value := .addressList}}
                <div class="address-item J_addressItem {{if eq $value.DefaultAddress 1}}selected{{end}}"
                    data-id="{{$value.Id}}">
                    <dl>
                        <dt><em class="uname">{{$value.Name}}</em> </dt>
                        <dd class="utel">{{$value.Phone}}</dd>
                        <dd class="uaddress">{{$value.Address}} </dd>
                    </dl>
                    <div class="actions">
                        <a href="javascript:void(0);" data-id="{{$value.Id}}" class="modify addressModify">修改</a>
                    </div>
                </div>
                {{end}}
            </div>
            <!-- addresslist end -->
            <div class="address-item address-item-new" id="J_newAddress" data-toggle="modal"
                data-target="#addAddressModal">
                <i class="iconfont">+</i> 添加新地址
            </div>
        </div>
    </div>
    <div class="section section-goods">
        <div class="section-header clearfix">
            <h3 class="title">商品及优惠券</h3>
            <div class="more">
                <a href="/cart" data-stat-id="4b8666e26639b521">返回购物车<i class="iconfont">></i></a>
            </div>
        </div>
        <div class="section-body">
            <ul class="goods-list" id="J_goodsList">
                {{range $key,$value := .orderList}}
                <li class="clearfix">
                    <div class="col col-img">
                        <img src="{{$value.GoodsImg | FormatImg}}" width="30" height="30" />
                    </div>
                    <div class="col col-name">
                        <a href="#" target="_blank">
                            {{$value.Title}}--{{$value.GoodsColor}} {{$value.GoodsVersion}}
                        </a>
                    </div>
                    <div class="col col-price">
                        {{$value.Price}}元 x {{$value.Num}} </div>
                    <div class="col col-status">
                        &nbsp;
                    </div>
                    <div class="col col-total">
                        {{Mul $value.Price $value.Num}}元
                    </div>
                </li>
                {{end}}
            </ul>
        </div>
    </div>
    <div class="section section-options section-payment clearfix hide">
        <div class="section-header">
            <h3 class="title">支付方式</h3>
        </div>
        <div class="section-body clearfix">
            <ul class="J_optionList options ">
                <li data-type="pay" class="J_option selected" data-value="1">
                    在线支付 <span>
                        (支持微信支付、支付宝、银联、财付通、小米钱包等) </span>
                </li>
            </ul>
        </div>
    </div>

    <div class="section section-options section-shipment clearfix">
        <div class="section-header">
            <h3 class="title">配送方式</h3>
        </div>
        <div class="section-body clearfix">
            <ul class="clearfix J_optionList options ">
                <li data-type="shipment" class="J_option selected" data-amount="0" data-value="2">
                    包邮 </li>
            </ul>
            <div class="service-self-tip" id="J_serviceSelfTip" style="display: none;"></div>
        </div>
    </div>

    <div class="section section-options section-time clearfix hide" style="display: block;">
        <div class="section-header">
            <h3 class="title">配送时间</h3>
        </div>
        <div class="section-body clearfix">
            <ul class="J_optionList options options-list clearfix">
                <!-- besttime start -->
                <li data-type="time" class="J_option selected" data-value="1">
                    不限送货时间:<span>周一至周日</span> </li>
                <li data-type="time" class="J_option " data-value="2">
                    工作日送货:<span>周一至周五</span> </li>
                <li data-type="time" class="J_option " data-value="3">
                    双休日、假日送货:<span>周六至周日</span> </li>
                <!-- besttime end -->
            </ul>
        </div>
    </div>

    <div class="section section-options section-invoice clearfix">
        <div class="section-header">
            <h3 class="title">发票</h3>
        </div>
        <div class="section-body clearfix">
            <div class="invoice-result">
                <span id="J_invoiceDesc">电子发票</span>
                <span id="J_invoiceTitle">个人</span>
                <span>商品明细</span>
                <a href="#J_modalInvoiceInfo" data-toggle="modal" id="J_invoiceModify" data-stat-id="67efe13c31710c36"
                    onclick="_msq.push(['trackEvent', '50d1f382fadafb8b-67efe13c31710c36', '#J_modalInvoiceInfo', 'pcpid', '']);">修改
                    &gt;</a>
            </div>
        </div>
    </div>

    <div class="section section-count clearfix">
        <div class="money-box" id="J_moneyBox">
            <ul>
                <li class="clearfix">
                    <label>商品件数:</label>
                    <span class="val">{{.allNum}}件</span>
                </li>
                <li class="clearfix">
                    <label>商品总价:</label>
                    <span class="val">{{.allPrice}}元</span>
                </li>
                <li class="clearfix">
                    <label>活动优惠:</label>
                    <span class="val">-0元</span>
                </li>
                <li class="clearfix">
                    <label>优惠券抵扣:</label>
                    <span class="val"><i id="J_couponVal">-0</i>元</span>
                </li>
                <li class="clearfix">
                    <label>运费:</label>
                    <span class="val"><i data-id="J_postageVal">0</i>元</span>
                </li>
                <li class="clearfix total-price">
                    <label>应付总额:</label>
                    <span class="val"><em data-id="J_totalPrice">{{.allPrice}}</em>元</span>
                </li>
            </ul>
        </div>
    </div>

    <div class="section-bar clearfix">
        <div class="fl">
            <div class="seleced-address hide" id="J_confirmAddress">
            </div>
            <div class="big-pro-tip hide J_confirmBigProTip"></div>
        </div>
        <div class="fr">
            <a href="#" class="btn btn-primary">去结算</a>
        </div>
    </div>
</div>

<!-- 收货地址增加 -->
<div class="modal fade" id="addAddressModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                        aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">增加收货地址</h4>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <input type="text" name="name" id="add_name" class="form-control" placeholder="姓名">

                </div>
                <div class="form-group">
                    <input type="text" name="phone" id="add_phone" class="form-control" placeholder="电话">
                </div>

                <div class="form-group">
                    <textarea name="address" id="add_address" class="form-control" cols="78" rows="4"
                        placeholder="详细地址"></textarea>
                </div>
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="addAddress">增加</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
            </div>
        </div>
    </div>
</div>

<!-- 收货地址修改 -->
<div class="modal fade" id="editAddressModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                        aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">修改收货地址</h4>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <input type="hidden" name="id" id="edit_id" />
                    <input type="text" name="name" id="edit_name" class="form-control" placeholder="姓名">

                </div>
                <div class="form-group">
                    <input type="text" name="phone" id="edit_phone" class="form-control" placeholder="电话">
                </div>

                <div class="form-group">
                    <textarea name="address" id="edit_address" class="form-control" cols="78" rows="4"
                        placeholder="详细地址"></textarea>
                </div>
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="editAddress">修改</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
            </div>
        </div>
    </div>
</div>
<!-- footer -->
{{ template "frontend/public/page_footer.html" .}}
</body>
</html>
{{end}}

确认订单js

增加收货地址,修改默认收货地址,编辑收货地址内容
(function ($) {
    var app = {
        init: function () {
            this.addAddress();
            this.changeDefaultAddress();
            this.editAddress();
        },
        addAddress: function () { //增加收货地址
            $("#addAddress").click(function () {
                var name = $('#add_name').val();
                var phone = $('#add_phone').val();
                var address = $('#add_address').val();
                if (name == '' || phone == "" || address == "") {
                    alert('姓名、电话、地址不能为空')
                    return false;
                }
                var reg = /^[\d]{11}$/;
                if (!reg.test(phone)) {
                    alert('手机号格式不正确');
                    return false;
                }

                $.post('/address/addAddress', { name: name, phone: phone, address: address }, function (response) {
                    if (response.success) {
                        var addressList = response.result;
                        var str = ""
                         //循环返回的收货地址列表,并拼接html后展示
                        for (var i = 0; i < addressList.length; i++) {
                            if (addressList[i].default_address) {
                                str += '<div class="address-item J_addressItem selected" data-id="' + addressList[i].id + '" data-name="' + addressList[i].name + '" data-phone="' + addressList[i].phone + '" data-address="' + addressList[i].address + '" > ';
                                str += '<dl>';
                                str += '<dt> <em class="uname">' + addressList[i].name + '</em> </dt>';
                                str += '<dd class="utel">' + addressList[i].phone + '</dd>';
                                str += '<dd class="uaddress">' + addressList[i].address + '</dd>';
                                str += '</dl>';
                                str += '<div class="actions">';
                                str += '<a href="javascript:void(0);" data-id="' + addressList[i].id + '" class="modify addressModify">修改</a>';
                                str += '</div>';
                                str += '</div>';

                            } else {
                                str += '<div class="address-item J_addressItem" data-id="' + addressList[i].id + '" data-name="' + addressList[i].name + '" data-phone="' + addressList[i].phone + '" data-address="' + addressList[i].address + '" > ';
                                str += '<dl>';
                                str += '<dt> <em class="uname">' + addressList[i].name + '</em> </dt>';
                                str += '<dd class="utel">' + addressList[i].phone + '</dd>';
                                str += '<dd class="uaddress">' + addressList[i].address + '</dd>';
                                str += '</dl>';
                                str += '<div class="actions">';
                                str += '<a href="javascript:void(0);" data-id="' + addressList[i].id + '" class="modify addressModify">修改</a>';
                                str += '</div>';
                                str += '</div>';
                            }
                        }
                        //展示收货地址列表html
                        $("#addressList").html(str)

                    } else {
                        alert(response.message)
                    }
                     
                    //隐藏模态框
                    $('#addAddressModal').modal('hide')
                });

            })
        },
        changeDefaultAddress: function () { // 修改默认收货地址
            //注意:事件委托   动态生成的dom节点默认没法直接绑定事件,这时候可以使用事件委托
            $("#addressList").on("click", ".J_addressItem", function () {
                $(this).addClass("selected").siblings().removeClass("selected");

                var addressId = $(this).attr("data-id");
                $.get("/address/changeDefaultAddress", { "addressId": addressId }, function (response) {
                    console.log(response)
                })
            })

        },
        editAddress: function () { //编辑收货地址:先从api接口获取,再修改
            //注意:事件委托 
            $("#addressList").on("click", ".addressModify", function () {
                //请求接口获取当前收货地址id对应的数据
                var addressId = $(this).attr("data-id")
                //获取收货地址并展示到模态框
                $.get("/address/getOneAddressList", { "addressId": addressId }, function (response) {                    
                    if (response.success) {
                        var addressInfo = response.result;
                        $("#edit_id").val(addressInfo.id);
                        $('#edit_name').val(addressInfo.name);
                        $('#edit_phone').val(addressInfo.phone);
                        $('#edit_address').val(addressInfo.address);
                    } else {
                        alert(response.message)
                    }
                    $('#editAddressModal').modal('show')
                })
            })
            //编辑收货地址并提交api请求
            $("#editAddress").click(function () {
                var id = $('#edit_id').val();
                var name = $('#edit_name').val();
                var phone = $('#edit_phone').val();
                var address = $('#edit_address').val();
                if (name == '' || phone == "" || address == "") {
                    alert('姓名、电话、地址不能为空')
                    return false;
                }
                var reg = /^[\d]{11}$/;
                if (!reg.test(phone)) {
                    alert('手机号格式不正确');
                    return false;
                }
                $.post('/address/editAddress', { id: id, name: name, phone: phone, address: address }, function (response) {
                    if (response.success) {
                        var addressList = response.result;
                        var str = ""
                        for (var i = 0; i < addressList.length; i++) {
                            if (addressList[i].default_address) {
                                str += '<div class="address-item J_addressItem selected" data-id="' + addressList[i].id + '" data-name="' + addressList[i].name + '" data-phone="' + addressList[i].phone + '" data-address="' + addressList[i].address + '" > ';
                                str += '<dl>';
                                str += '<dt> <em class="uname">' + addressList[i].name + '</em> </dt>';
                                str += '<dd class="utel">' + addressList[i].phone + '</dd>';
                                str += '<dd class="uaddress">' + addressList[i].address + '</dd>';
                                str += '</dl>';
                                str += '<div class="actions">';
                                str += '<a href="javascript:void(0);" data-id="' + addressList[i].id + '" class="modify addressModify">修改</a>';
                                str += '</div>';
                                str += '</div>';

                            } else {
                                str += '<div class="address-item J_addressItem" data-id="' + addressList[i].id + '" data-name="' + addressList[i].name + '" data-phone="' + addressList[i].phone + '" data-address="' + addressList[i].address + '" > ';
                                str += '<dl>';
                                str += '<dt> <em class="uname">' + addressList[i].name + '</em> </dt>';
                                str += '<dd class="utel">' + addressList[i].phone + '</dd>';
                                str += '<dd class="uaddress">' + addressList[i].address + '</dd>';
                                str += '</dl>';
                                str += '<div class="actions">';
                                str += '<a href="javascript:void(0);" data-id="' + addressList[i].id + '" class="modify addressModify">修改</a>';
                                str += '</div>';
                                str += '</div>';
                            }
                        }
                        $("#addressList").html(str)
                    } else {
                        alert(response.message)
                    }
                    $('#editAddressModal').modal('hide')
                });
            })
        },
    }
    $(function () {
        app.init();
    })
})($)

[上一节][golang gin框架] 29.Gin 商城项目-用户登录,注册操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/515606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring】初识MyBatis (二)

&#xff08;接上一篇【Spring】[初识MyBatis&#xff08;一&#xff09;]&#xff09; 目录 1.2 根据用户名模糊查询用户信息2 添加客户3 更新用户4 删除用户 1.2 根据用户名模糊查询用户信息 【示例6-2】模糊查询的实现只需要在映射文件中通过元素编写相应的SQL语句&#x…

华为手机如何进入开发者模式?连接studio真机调试

对于安卓开发者来说&#xff0c;真机调试是非常好的选择&#xff0c;对电脑配置也没有过分的要求。如果采用Android Studio自带安卓虚拟机调试&#xff0c;真的很慢&#xff0c;一点都不友好。 真机调试的步骤&#xff1a;打开设置->关于手机->版本号&#xff0c;然后连…

并发编程12:AQS

文章目录 12.1 前置知识12.2 AQS入门级别理论知识12.2.1 是什么&#xff1f;12.2.2 AQS为什么是JUC内容中最重要的基石12.2.3 能干嘛&#xff1f;12.2.4 小总结 12.3 AQS源码分析前置知识储备12.3.1 AQS内部体系架构图12.3.2 AQS内部体系架构----AQS自身12.3.1 AQS内部体系架构…

一、H3C-NE实验-抓包实验

实验一&#xff1a;抓包实验&#xff08;PING包&#xff09; 实验拓扑结构图 1. 修改设备名称 步骤1&#xff1a;启动设备 步骤2&#xff1a;在路由器1&#xff0c;进入系统视图&#xff0c;并修改设备名称为R1 步骤3&#xff1a;在路由器2&#xff0c;进入系统视图&#xf…

【Java|基础篇】类和对象

文章目录 1. 前言2. 什么是面向对象3. 类的定义4. 类的实例化5. 对象的构造及初始化6. this引用7. 总结 1. 前言 本篇文章主要讲解了下面三个问题 类的定义和实例化构造方法this关键字 2. 什么是面向对象 众所周知面向过程和面向对象是两种重要的编程思想,而Java是属于面向…

C语言函数大全-- v 开头的函数

C语言函数大全 本篇介绍C语言函数大全-- v 开头的函数 1. va_start 1.1 函数说明 函数声明函数功能void va_start(va_list ap, last_arg);用于初始化一个 va_list 类型的变量&#xff0c;使其指向可变参数列表中的第一个参数 参数&#xff1a; ap&#xff1a; 一个指向 va_…

我的创作纪念日(个人感悟)

昨天2023年5月10日是我成为创作者的第128天纪念日&#xff0c;感谢CSDN官方的纪念信让我铭记这特殊的一天。 机缘 要说与CSDN的初次相遇&#xff0c;还是2022年的高考结束完的暑假&#xff0c;当时对于大学的学习没有什么概念&#xff0c;当初的高考志愿报的有计算机相关的专…

spring集成mybatis的原理

spring是怎样和mybatis继承的&#xff1f; 在idea里点mapper.queryOne()直接跳到了接口或xml&#xff0c;它究竟是怎样利用jdbc执行的&#xff1f; 我直接调用mapper.queryOne是怎么使用的sqlsession&#xff1f;怎么去connect的&#xff1f; mybatis是怎样根据mapper找到对应的…

【Java面试】Java并发基础(1)

文章目录 1. 可见性&#xff0c;有序性&#xff0c;原子性2. java中并发和并行3. 通常线程有哪几种使用方式? 1. 可见性&#xff0c;有序性&#xff0c;原子性 可见性&#xff08;Visibility&#xff09;&#xff1a; 指一个线程修改了共享变量的值之后&#xff0c;其他线程能…

学习网络通信必备的DNS解析和Socket通信知识

OkHttp是一个开源的网络请求框架&#xff0c;由Square公司开发。它通过封装Java底层的HttpURLConnection和Okio等库&#xff0c;提供一个简单易用的API&#xff0c;让开发人员能够方便地向服务器发送HTTP/HTTPS请求&#xff0c;支持异步请求和响应回调&#xff0c;并提供丰富的…

未来已来, 新能源与IT的技术碰撞;学习Android车载开发的必然趋势

Android工程师前景 Android车载工程师扮演着关键的角色&#xff0c;他们致力于将最新的Android技术和汽车技术相结合&#xff0c;为汽车行业提供优质的产品。随着越来越多的汽车制造商投资于智能汽车技术和车联网技术&#xff0c;Android车载工程师成为了一个越来越重要的职业…

MATLAB实现二维稳态导热

MATLAB实现二维稳态导热 一、理论基础二、代码实现 一、理论基础 步骤&#xff1a; Step.1 二维模型传热控制微分方程的确定&#xff0c;具体推导可以在任何一本传热学的书中找到。 d 2 T d x 2 d 2 T d y 2 0 \frac{d^{2}T}{dx^{2}}\frac{d^{2}T}{dy^{2}}0 dx2d2T​dy2d2T…

Ansible 自动化运维工具(一)——部署以及命令行模块

文章目录 一、 ansible 的概述1、ansible简介2.、官方网站3、ansible 的特点4、ansible的工作机制5、ansible的组成模块 二、ansible部署1、Asible的安装 三、ansible 命令行模块1、command 模块2、shell 模块3、cron 模块4、user 模块5、group 模块6、copy 模块7、file 模块8、…

【ros/ros2】ros1和ros2的区别-要点记录

dds data distribution service&#xff0c;数据分发服务 rcl ros client libraries&#xff0c;ros客户端库文件 rmw ros middle ware interface&#xff0c;ros中间件接口 lcn life cycle node&#xff0c;生命周期节点&#xff0c;受控节点 lmn lifecycle manageme…

C++二叉树递归方法存入和三种递归方法读出(前序,中序,后序)

#include <stdio.h> #include <malloc.h> typedef struct op //定义子树结构 { int data; struct op *lchild; struct op *rchild; }treestruct; treestruct *createtree() //这里这种表达形式意思是bittree类型的函数 最终要返回bitt…

【Linux】版本管理器Git

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;Linux的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录 前言一、Git是什么二、Git有什么…

开源C#代码生成器,专注.NET,Sqlserver,最简单,最干净,支持自编码的开源工具,SmartSoftHelp 开发辅助优化工具

开源C#代码生成器&#xff0c;专注.NET&#xff0c;Sqlserver&#xff0c;最简单&#xff0c;最干净&#xff0c;支持自编码的开源工具&#xff0c;SmartSoftHelp 开发辅助优化工具&#xff01; 下载地址&#xff1a;https://pan.baidu.com/s/1XLL_fLxVTw4erYZLj8-MzA?pwd888…

搭建python运行环境

安装Miniconda3 清华镜像 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/ 下载 安装 next————agree————这俩选哪个都行&#xff0c;他选的第二个————安装路径———— 配置系统环境变量 Path miniconda3所在的路径 D:\Autils\miniconda3 Scri…

ChatGPT 最有可能取代哪些职业?

ChatGPT 的应用场景ChatGPT 最可能取代哪些职业&#xff1f;写在最后 ChatGPT 的应用场景 ChatGPT 的应用场景大体上可以归类为三大模块。 第一类是 代码相关 的任务场景。包含程序语言之间的相互转换&#xff08;如 python 转 java&#xff09;、程序命令的生成、代码 bug 的…

Gateway新一代网关

Gateway功能&#xff1a;路由 过滤 一、概述 官网地址 不使用网关存在的问题&#xff1a; 1、客户端需要记录不同微服务地址&#xff0c;增加客户端的复杂性 2、每个后台微服务都需要认证 3、http 发请求&#xff0c;涉及到跨域 4、后台新增微服务&#xff0c;不能动态知道地…