001 侧边栏 地址增删改查 默认地址代码没完善

user_index.html




<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>水果商城 - 个人中心</title>
    <link rel="stylesheet" href="myaccount_style.css">
    <script src="../common/jquery-3.3.1.min.js"></script>
    <script src="myaccount_scripts.js"></script>
</head>


<!-- <header>
    <nav class="main-nav">
        <ul>
            <li><a href="#" data-page="my_coupons">我的优惠券</a></li>
            <li><a href="#" data-page="my_addresses" class="active">我的地址</a></li>

        </ul>
    </nav>
</header>  -->









<main>
    <aside>
        <!-- 侧边栏导航 -->
        <nav>
            <ul>
                <li><a href="#" data-page="my_coupons">我的优惠券</a></li>
                <li><a href="#" data-page="my_addresses">我的地址</a></li>

                <!-- 其他侧边栏链接 -->
            </ul>
        </nav>



    </aside>

    <div id="content-area">

        <!-- 内容将通过JavaScript加载 -->


    </div>





    <button id="addNewAddressBtn" class="add-address-btn" >添加新地址</button>


    <!-- 添加新地址的表单(放在内容区域下方以避免重复ID问题)
    <form id="newAddressForm" style="display: none;">
         表单内容 ... -->
    <!-- <input type="text" placeholder="接收人姓名" required>
   其他表单字段 ... -->
    <!-- <input type="submit" value="保存">
    <button type="button" class="cancel-new-address-btn">取消</button>
</form>   -->


    <div id="content-area-address">

        <form id="newAddressForm" style="display: none;">



            <!-- 用户ID(隐藏字段) -->
            <input type="hidden" id="userId" name="userId" value=""> <!-- 这里的值应该由后台设置 -->

            <!-- 收件地址ID(隐藏字段),对于新地址可能是空的或自动生成 -->
            <input type="hidden" id="receiveAddressId" name="receiveAddressId" value=""> <!-- 这里的值可能是空的,或者由后台在编辑地址时提供 -->


            <!-- 收件人姓名 -->
            <div class="form-group">
                <label for="receiverName">收件人姓名:</label>
                <input type="text" id="receiverName" name="receiverName" placeholder="请输入收件人姓名" required>
            </div>

            <!-- 收件人电话号码 -->
            <div class="form-group">
                <label for="receiverPhone">收件人电话号码:</label>
                <input type="tel" id="receiverPhone" name="receiverPhone" placeholder="请输入收件人电话号码" required>
            </div>

            <!-- 省份(这里假设使用下拉选择) -->
            <div class="form-group">
                <label for="receiverProvince">省份:</label>
                <select id="receiverProvince" name="receiverProvince" required>
                    <!-- 这里应该动态生成省份选项 -->
                    <option value="">请选择</option>
                    <!-- <option value="province1">省份1</option> -->
                    <!-- ... -->
                </select>
            </div>

            <!-- 城市(同样假设使用下拉选择) -->
            <div class="form-group">
                <label for="receiverCity">城市:</label>
                <select id="receiverCity" name="receiverCity" required>
                    <!-- 这里应该根据选择的省份动态生成城市选项 -->
                    <option value="">请选择</option>
                    <!-- <option value="city1">城市1</option> -->
                    <!-- ... -->
                </select>
            </div>

            <!-- 县区(假设使用下拉选择) -->
            <div class="form-group">
                <label for="receiverArea">县区:</label>
                <select id="receiverArea" name="receiverArea" required disabled>
                    <!-- 这里应该根据选择的城市动态生成县区选项 -->
                    <option value="">请选择</option>
                    <!-- <option value="area1">县区1</option> -->
                    <!-- ... -->
                </select>
            </div>



            <!-- 街道 -->
            <div class="form-group">
                <label for="receiverStreet">街道:</label>
                <select id="receiverStreet" name="receiverStreet" required disabled>
                    <option value="">请选择</option>
                    <!-- 街道选项将根据县区动态生成 -->
                </select>
            </div>

            <!-- 详细地址 -->
            <div class="form-group">
                <label for="receiverDetail">详细地址:</label>
                <textarea id="receiverDetail" name="receiverDetail" placeholder="请输入详细地址" required></textarea>
            </div>
            <!-- ... -->

            <!-- 是否是默认收件地址(使用单选按钮) -->
            <div class="form-group">
                <label>
                    <input type="radio" id="isDefaultYes" name="isDefault" value="1">
                    是默认收件地址
                </label>
                <label>
                    <input type="radio" id="isDefaultNo" name="isDefault" value="0" checked>
                    不是默认收件地址
                </label>
            </div>

            <!-- 其他字段,如other1, other2,可以根据需要添加 -->
            <!-- ... -->

            <!-- 提交和取消按钮 -->
            <div class="form-actions">
                <input type="submit" value="保存">
                <button type="button" class="cancel-new-address-btn">取消</button>
            </div>
        </form>
    </div>



    <div id="content-area-review">

    </div>



</main>



<!-- 隐藏的模板数据 -->
<div id="my_coupons-list-template" style="display: none;">
    <div class="content-block coupon-list">
        <h2>我的优惠券列表</h2>
        <!-- 优惠券列表内容(模拟数据) -->
        <div class="coupon-item"><p>优惠券1</p></div>
        <div class="coupon-item"><p>优惠券2</p></div>
    </div>
</div>

<div id="my_addresses-list-template" style="display: none;">
    <div class="content-block address-list">
        <h2>我的地址列表</h2>
        <div class="address-item">
            <p>地址1</p>
            <button class="edit-btn">修改</button>
            <button class="delete-btn">删除</button>
            <!-- 其他地址详情 -->
        </div>

        <!-- ... 其他地址项 ... -->
    </div>
</div>












</body>




</html>


myaccount_style.css



/* 基本样式 */
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

header {
  background-color: #f2f2f2;
  padding: 15px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
}


main {
  display: flex;
  margin-top: 20px; /* 保持一定间距 */
}




aside {
  width: 20%; /* 根据需要调整宽度 */
  background-color: #fff;
  border-right: 1px solid #ddd; /* 添加右侧边框 */
  box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
  padding: 20px;
}


/* .header-info {  
  display: flex;  
  align-items: center;  
}  

.avatar {  
  width: 40px;  
  height: 40px;  
  border-radius: 50%;  
  margin-right: 10px;  
}  

.username, .user-level {  
  margin-right: 10px;  
}   */

nav ul {
  list-style: none;
  padding: 0;

}

/* 导航链接样式 */
/* nav ul li {  
  margin-bottom: 10px;    
}   */


nav ul li a {

  display: block;
  padding: 10px;
  text-decoration: none;
  color: #333;
  transition: background-color 0.3s ease;
  border-radius: 5px; /* 添加圆角 */

}



nav ul li a.active,

nav ul li a:hover {
  color: #fff; /* 激活或悬停时的链接颜色 */
  background-color: #f00; /* 替换为您的品牌颜色 */
  /* border-bottom-color: transparent; /* 移除底部边框 */
}



/* 地址项样式 */
.address-item {

  border: 1px solid #ddd; /* 添加边框 */
  border-radius: 5px; /* 添加圆角 */
  padding: 10px; /* 增加内边距 */
  margin-bottom: 20px; /* 增加间距 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); /* 添加阴影效果 */
  transition: all 0.3s ease; /* 添加过渡效果 */

  /*position: relative;*/ /* 为绝对定位的子元素设置参考点 */
}


.address-item button {
  /*margin-left: 10px;*/ /* 按钮与地址信息之间留点间距 */
  padding: 5px 10px; /* 调整按钮的内边距 */
  font-size: 12px; /* 调整按钮上的字体大小 */
  margin-right: 5px; /* 如果需要,调整按钮之间的水平间距 */
}


.address-item:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 鼠标悬停时增加阴影效果 */
  transform: translateY(-2px); /* 轻微上移,增加立体感 */
}

/* 编辑表单样式 */
.edit-form {
  display: none; /* 默认隐藏编辑表单 */
  margin-top: 10px; /* 与地址项保持一定间距 */
  padding: 10px; /* 为表单内容添加内边距 */
  border: 1px solid #ccc; /* 添加边框 */
  border-radius: 5px; /* 添加圆角 */
  background-color: #f5f5f5; /* 设置背景色 */
  position: absolute; /* 绝对定位以确保它不会干扰其他地址项 */
  width: 100%; /* 与父元素(.address-item)相同宽度 */
  z-index: 10; /* 提高层级,确保在其他元素之上 */
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
}


/* 编辑表单中的输入和按钮样式 */
.edit-form input[type="text"] {
  width: 100%; /* 占据整个表单宽度 */
  padding: 5px; /* 添加内边距 */
  margin-bottom: 10px; /* 与按钮保持间距 */
}


.edit-form button {
  padding: 5px 10px; /* 添加内边距 */
  margin-right: 5px; /* 如果需要,与其他按钮保持间距 */
  background-color: #4CAF50; /* 绿色背景 */
  border: none; /* 移除边框 */
  color: white; /* 白色文本 */
  cursor: pointer; /* 鼠标悬停时变为手形图标 */
}


/* 编辑表单中的取消按钮样式 */
/* 特别注意:.cancel-new-address-btn的样式 */
.edit-form .cancel-new-address-btn {
  padding: 5px 10px;
  margin-right: 5px;

  background-color: #f44336; /* 红色背景,以示与保存按钮区别 */
  border: none;
  color: white;
  cursor: pointer;
  /* 其他样式可以保持与.edit-form button一致,或者根据需要调整 */
}



/* Content 区域样式增强 */
#content-area {
  /* ... 保持不变 ... */
  padding: 30px; /* 增加内边距,使内容区域更加宽敞 */
}






#content-area div {
  display: none; /* 初始隐藏所有内容区域 */
}

#content-area div.active {
  display: block; /*显示当前激活的内容区域   */
}


/* 去除激活状态时的透明底部边框(如果需要的话)   */
nav ul li a.active {
  border-bottom-color: #f00; /* 无需透明 */
}





/* 其他样式... */
/* 底部导航样式 */
/* footer nav ul {  
  background-color: #f2f2f2; /* 浅灰色背景,与头部不同 */
/* }   */


#addNewAddressBtn {
  margin-top: 20px; /* 与地址列表保持间距 */
}



/* 地址列表标题样式 */
.address-list h2 {
  font-size: 18px; /* 调整字体大小 */
  font-weight: bold; /* 加粗字体 */
  color: #333; /* 设置字体颜色 */
  margin-bottom: 20px; /* 增加底部间距,与地址项分开 */
  text-align: left; /* 文本左对齐,或根据需要调整 */
}

/* 如果需要背景色或边框 */
.address-list {
  background-color: #fff; /* 设置背景色(如果需要) */
  border: 1px solid #ddd; /* 添加边框(如果需要) */
  padding: 10px; /* 添加内边距,使内容与边框有些距离 */
}





/* 添加新地址按钮样式 */
.add-address-btn {

  /* 让按钮变小 */
  padding: 5px 10px; /* 减少内边距 */
  font-size: 14px; /* 减小字体大小 */


  /* 将按钮放置在右上角 */
  position: absolute; /* 使用绝对定位 */
  top: 20px; /* 距离顶部一定距离 */
  right: 20px; /* 距离右侧一定距离 */
  z-index: 10; /* 提高层级,确保在其他元素之上 */


  display: inline-block; /* 让按钮表现为行内块元素 */
  color: white; /* 字体颜色 */


  background-color: #4CAF50; /* 背景颜色,这里使用了绿色 */
  border: none; /* 移除边框 */
  border-radius: 5px; /* 圆角 */
  cursor: pointer; /* 鼠标悬停时变为手形图标 */
  transition: background-color 0.3s ease; /* 背景色过渡效果 */
}

.add-address-btn:hover {
  background-color: #45a049; /* 鼠标悬停时的背景颜色 */
}

/* 如果按钮是激活状态(例如正在加载数据),可以添加额外的样式 */
.add-address-btn.active {
  opacity: 0.6; /* 降低透明度表示按钮处于非交互状态 */
  cursor: not-allowed; /* 更改鼠标图标为禁止状态 */
}



/* 添加新地址表单样式 */
#newAddressForm {
  background-color: #fff; /* 白色背景 */
  border: 1px solid #ccc; /* 边框 */
  border-radius: 5px; /* 圆角 */
  padding: 20px; /* 内边距 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 阴影效果 */
  margin-top: 20px; /* 与其他元素间距 */
  width: 100%; /* 宽度占满容器 */
  max-width: 600px; /* 最大宽度限制,防止表单过宽 */
}

#newAddressForm label {
  display: block; /* 块级元素,独占一行 */
  margin-bottom: 10px; /* 与输入框间距 */
  font-weight: bold; /* 加粗 */
}

#newAddressForm input[type="text"],
#newAddressForm input[type="tel"],
#newAddressForm textarea {
  width: 100%; /* 宽度占满容器 */
  padding: 10px; /* 内边距 */
  border: 1px solid #ddd; /* 边框 */
  border-radius: 4px; /* 圆角 */
  box-sizing: border-box; /* 包括内边距和边框在内,宽度占满容器 */
}

#newAddressForm textarea {
  height: 100px; /* 高度 */
  resize: vertical; /* 允许垂直调整大小 */
}

#newAddressForm select {
  width: 100%; /* 宽度占满容器 */
  padding: 10px; /* 内边距 */
  border: 1px solid #ddd; /* 边框 */
  border-radius: 4px; /* 圆角 */
}

#newAddressForm .form-group {
  margin-bottom: 20px; /* 表单项之间的间距 */
}

#newAddressForm .form-actions {
  text-align: right; /* 右对齐按钮 */
  margin-top: 20px; /* 与表单项间距 */
}

#newAddressForm .form-actions button {
  padding: 10px 20px; /* 内边距 */
  margin-left: 10px; /* 与前一个按钮间距 */
  border: none; /* 无边框 */
  border-radius: 4px; /* 圆角 */
  cursor: pointer; /* 鼠标悬停时变为手形图标 */
}

#newAddressForm .form-actions .save-btn {
  background-color: #4CAF50; /* 绿色背景 */
  color: #fff; /* 白色文本 */
}

#newAddressForm .form-actions .cancel-btn {
  background-color: #f44336; /* 红色背景 */
  color: #fff; /* 白色文本 */
}














/* 响应式设计 */
@media (max-width: 768px) {
  aside, #content-area {
    width: 100%; /* 小屏幕上侧边栏和内容区域占满全宽 */
    border-right: none; /* 移除右侧边框 */
  }
  main {
    flex-direction: column; /* 改为垂直排列 */
  }
  aside {
    margin-bottom: 20px; /* 与内容区域保持一定间距 */
  }

  .add-address-btn {
    /* 在小屏幕上可能需要调整位置或大小 */
    top: 10px;
    right: 10px;
    padding: 3px 8px;
    font-size: 12px;
  }


  /* 在小屏幕上,可能需要减少内边距、字体大小等 */
  .address-list h2 {
    font-size: 16px;
  }
  .address-item {
    margin-bottom: 10px;
  }

}






myaccount_scripts.js




$(document).ready(function() {
    var currentPage = '未赋值'; // 假设页面加载时默认显示“我的地址”页面





    var provinces = [
        {
            name: '省份1',
            cities: [
                { name: '城市1', areas: [{ name: '县区1', streets: ['街道1-1', '街道1-2'] }, { name: '县区2', streets: ['街道2-1', '街道2-2'] }] },
                // ... 更多城市和县区
            ]
        },
        {
            name: '省份2',
            cities: [
                { name: '城市3', areas: [{ name: '县区3', streets: ['街道3-1', '街道3-2'] }] },
                // ... 更多城市和县区
            ]
        },
        // ... 添加更多省份和城市
    ];

    // 初始化省份下拉列表
    function initProvinceSelect() {
        var $provinceSelect = $('#receiverProvince');
        $provinceSelect.empty();
        $provinceSelect.append($('<option>').val('').text('请选择'));
        $.each(provinces, function(index, province) {
            $provinceSelect.append($('<option>').val(province.name).text(province.name));
        });
    }

    // 根据选择的省份初始化城市下拉列表
    function initCitySelect(provinceName) {
        var $citySelect = $('#receiverCity');
        $citySelect.empty();
        $citySelect.append($('<option>').val('').text('请选择'));

        var $areaSelect = $('#receiverArea');
        $areaSelect.empty().append($('<option>').val('').text('请选择'));
        $areaSelect.prop('disabled', true);

        var $streetSelect = $('#receiverStreet');
        $streetSelect.empty().append($('<option>').val('').text('请选择'));
        $streetSelect.prop('disabled', true);

        $.each(provinces, function(index, province) {
            if (province.name === provinceName) {
                $.each(province.cities, function(cityIndex, city) {
                    $citySelect.append($('<option>').val(city.name).text(city.name));
                });
                return false; // 找到匹配的省份后退出循环
            }
        });
    }

    // 根据选择的城市初始化县区下拉列表
    function initAreaSelect(cityName) {
        var $areaSelect = $('#receiverArea');
        $areaSelect.empty();
        $areaSelect.append($('<option>').val('').text('请选择'));

        var $streetSelect = $('#receiverStreet');
        $streetSelect.empty().append($('<option>').val('').text('请选择'));
        $streetSelect.prop('disabled', true);

        $.each(provinces, function(index, province) {
            $.each(province.cities, function(cityIndex, city) {
                if (city.name === cityName) {
                    $.each(city.areas, function(areaIndex, area) {
                        $areaSelect.append($('<option>').val(area.name).text(area.name));
                    });
                    $areaSelect.prop('disabled', false);
                    return false; // 找到匹配的城市后退出循环
                }
            });
        });
    }

    // 根据选择的县区初始化街道下拉列表
    function initStreetSelect(areaName) {
        var $streetSelect = $('#receiverStreet');
        $streetSelect.empty();
        $streetSelect.append($('<option>').val('').text('请选择'));

        $.each(provinces, function(index, province) {
            $.each(province.cities, function(cityIndex, city) {
                $.each(city.areas, function(areaIndex, area) {
                    if (area.name === areaName) {
                        $.each(area.streets, function(streetIndex, street) {
                            $streetSelect.append($('<option>').val(street).text(street));
                        });
                        $streetSelect.prop('disabled', false);
                        return false; // 找到匹配的县区后退出循环
                    }
                });
                if (!$streetSelect.prop('disabled')) return false; // 如果已经找到匹配的县区,则退出城市循环
            });
        });
    }

    // 绑定省份下拉列表的change事件
    $('#receiverProvince').on('change', function() {
        var selectedProvince = $(this).val();
        if (selectedProvince) {
            initCitySelect(selectedProvince);
        }
    });

    // 绑定城市下拉列表的change事件
    $('#receiverCity').on('change', function() {
        var selectedCity = $(this).val();
        if (selectedCity) {
            initAreaSelect(selectedCity);
        }
    });

    // 绑定县区下拉列表的change事件
    $('#receiverArea').on('change', function() {
        var selectedArea = $(this).val();
        if (selectedArea) {
            initStreetSelect(selectedArea);
        }
    });









    // 页面加载时默认加载地址列表


    // 绑定导航链接的点击事件
    $('nav ul li a').on('click', function(e) {
        e.preventDefault();


        var page = $(this).data('page');

        // 显示或隐藏添加新地址按钮和表单
        // $('#addNewAddressBtn, #newAddressForm').toggle(page === 'my_addresses');
        // 只针对表单进行显示与隐藏的控制
        console.log("变量"+currentPage);
        console.log("传入的"+page);

        // 如果点击的页面与当前页面不同,则加载新页面内容
        if ((page !== currentPage) || page == '未赋值') {
            loadContent(page);
            currentPage = page; // 更新当前页面变量
        }

        $('#addNewAddressBtn').toggle(page === 'my_addresses');


        //这行代码会在每次点击导航链接时检查当前页面是否是“我的地址”页面。如果是,则显示添加新地址按钮和表单;否则,隐藏它们。这样就确保了在不同页面之间切换时,表单和按钮的显示状态是正确的。


// 如果只有一个元素,则不执行任何操作


    });

    // 加载内容函数(使用局部变量来存储地址列表,以便在后续添加新地址)
    //var addressesListHtml = $('#my_addresses-list-template').html(); // 初始地址列表HTML
    function loadContent(page) {

        console.log("加载");









        // 移除之前所有导航链接的active类
        $('nav ul li a').removeClass('active');

        // 为当前点击的导航链接添加active类
        $('nav ul li a[data-page="' + page + '"]').addClass('active');





        // 根据页面加载不同的内容
        if (page === 'my_addresses') {
            $('#content-area-address').show();





            let token = localStorage.getItem("token");

            $.ajax({
                url: 'http://localhost:8080/fshop/receiverAddress', // 假设的地址列表API端点
                headers:{'token': token},
                type: 'GET',
                dataType: 'json',
                success: function(addresses) {
                    console.log(addresses.data);

                    var addressListHtml = '<div class="address-list active">';
                    $.each(addresses.data, function(index, address) {
                        addressListHtml += '<div class="address-item active" data-address-id="' + address.receiveAddressId + '" data-user-id="' + address.userId + '">' +
                            '<p><strong>姓名:</strong> ' + address.receiverName + '</p>' +
                            '<p><strong>电话:</strong> ' + address.receiverPhone + '</p>' +
                            '<p><strong>省份:</strong> ' + address.receiverProvince + '</p>' +
                            '<p><strong>城市:</strong> ' + address.receiverCity + '</p>' +
                            '<p><strong>县区:</strong> ' + address.receiverArea + '</p>' +
                            '<p><strong>街道:</strong> ' + address.receiverStreet + '</p>' +
                            '<p><strong>详细地址:</strong> ' + address.receiverDetail + '</p>' +
                            '<button class="edit-btn">修改</button>' +
                            '<button class="delete-btn">删除</button>' +
                            '</div>';
                    });
                    addressListHtml += '</div>';



                    $('#content-area').html(addressListHtml); // 将地址列表HTML插入到内容区域
                    $('#addNewAddressBtn').show(); // 显示添加新地址按钮


                },
                error: function(jqXHR, textStatus, errorThrown) {
                    alert('加载地址列表失败!错误: ' + textStatus + ', 详细信息: ' + errorThrown);
                    // 可能还需要一些错误处理逻辑,比如显示一个空列表或加载指示器
                }
            });





        } else if (page === 'my_coupons') {
            // 加载优惠券页面内容(如果有的话)
            // 这里可以是从模板加载,或者从服务器请求数据后加载
            // 例如:$('#content-area').html($('#my_coupons-list-template').html());
            // 但由于我们只想清空内容区域,所以这里简单清空即可
            //$('#content-area-coupon').empty();
            $('#content-area').text('我的优惠券页面');
            $('#content-area-address').hide();


        }

        // 注意:这里不需要再次为.save-edit-btn和.cancel-edit-btn绑定事件,因为它们只在页面加载时绑定一次



        // 移除之前所有content-block的active类
        $('#content-area .content-block').removeClass('active');

        $('#content-area .content-block').addClass('active');


        $('#content-area .address-item').addClass('active');





    }

    // 绑定添加新地址相关事件(只需在页面加载时绑定一次)
    function bindAddNewAddressEvents() {
        $('#addNewAddressBtn').on('click', function() {

            // 隐藏表单(如果之前显示过)
            //   $('#newAddressForm').hide().removeData('edit-mode'); // 确保表单不处于编辑模式


            // 将表单插入到地址列表的末尾,并显示它
            // $('#newAddressForm').appendTo('.address-list').show().find('input[type="text"]').val('');




            // 确保表单在点击时显示
            $('#newAddressForm').show().find('input[type="text"]').val(''); // 显示表单并清空输入框


            // 移除表单的编辑模式数据(如果有的话)
            $('#newAddressForm').removeData('edit-mode'); // 确保表单不处于编辑模式


            //$('#newAddressForm').toggle();
            // $('#newAddressForm').show().find('input[type="text"]').val(''); // 显示表单并清空输入框
            // 设置一个标志来表示不是编辑模式(如果需要的话,但在这个例子中可能不是必需的)
            // 默认情况下,我们假设不是编辑模式,所以不需要显式设置标志
            // 如果需要的话,可以在这里设置 $('#newAddressForm').data('edit-mode', false);
        });






        $('#newAddressForm').on('submit', function(e) {
            e.preventDefault();




                // 收集表单数据
                var formData = {
                    userId: $('#userId').val(),
                    receiverName: $('#receiverName').val(),
                    receiverPhone: $('#receiverPhone').val(),
                    receiverProvince: $('#receiverProvince').val(),
                    receiverCity: $('#receiverCity').val(),
                    receiverArea: $('#receiverArea').val(),
                    receiverStreet: $('#receiverStreet').val(),
                    receiverDetail: $('#receiverDetail').val(),
                    isDefault: $('input[name="isDefault"]:checked').val()
                };



                // 确保所有必填字段都已填写
                if (!receiverName || !receiverPhone || !receiverProvince || !receiverCity || !receiverArea || !receiverStreet) {
                    alert('请填写所有必填字段!');
                    return;
                }

                let token = localStorage.getItem("token");

                // 发送AJAX POST请求到服务器
                $.ajax({
                    url: 'http://localhost:8080/fshop/receiverAddress/saveAddr', // 假设的地址添加API端点
                    contentType: 'application/json; charset=utf-8', // 设置请求体的内容类型为 JSON
                    headers:{'token': token},
                    type: 'POST',
                    data: JSON.stringify(formData),
                    dataType: 'json',
                    success: function(response) {
                        console.log(response);
                        if (response.code == 1) {
                            console.log("成功"+response.data);
                            // 构建新的地址项HTML字符串
                            var newAddressHtml = createAddressItemHtml(response.data); // 假设这是一个辅助函数

                            // 将新地址添加到列表中
                            $('#content-area .address-list').append(newAddressHtml);
                            // 隐藏表单
                            $('#newAddressForm').hide();
                            // 显示成功消息(如果需要)
                            alert('地址添加成功!');
                        } else {
                            console.log("失败"+response.data);
                            // 处理添加失败的情况(比如显示错误消息)
                            alert('地址添加失败:' + response.message);
                        }
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        // 处理AJAX请求失败的情况
                        alert('添加地址时发生错误:' + textStatus + ', 详细信息: ' + errorThrown);
                    }
                });






        });


        $('#newAddressForm').on('click', '.cancel-new-address-btn', function() {
            $('#newAddressForm').hide(); // 隐藏表单
        });


    }




    // 辅助函数,用于从响应数据中创建地址项HTML
    function createAddressItemHtml(addressData) {
        return '<div class="address-item active" data-address-id="' + addressData.receiveAddressId + '" data-user-id="' + addressData.userId + '">' +
            '<p><strong>姓名:</strong> ' + addressData.receiverName + '</p>' +
            '<p><strong>电话:</strong> ' + addressData.receiverPhone + '</p>' +
            '<p><strong>省份:</strong> ' + addressData.receiverProvince + '</p>' +
            '<p><strong>城市:</strong> ' + addressData.receiverCity + '</p>' +
            '<p><strong>县区:</strong> ' + addressData.receiverArea
            + '</p>' +
            '<p><strong>街道:</strong> ' + addressData.receiverStreet + '</p>' +
            '<p><strong>详细地址:</strong> ' + addressData.receiverDetail + '</p>' +
            '<button class="edit-btn">修改</button>' +
            '<button class="delete-btn">删除</button>' +
            '</div>';
    }








    // 绑定编辑地址事件
    function bindEditAddressEvents() {
        // 使用事件委托绑定.edit-btn的点击事件,这样即使后续添加了新的地址项,事件依然有效
            // 在页面加载时一次性绑定编辑按钮的点击事件
            $('#content-area').on('click', '.edit-btn', function() {
                var addressItem = $(this).closest('.address-item');
                var addressId = addressItem.data('address-id'); // 获取地址ID

                // 构建编辑地址的URL,并携带addressId作为查询参数
                var editUrl = 'address_edit.html?addressId=' + addressId;

                // 重定向到编辑页面,传递地址ID作为参数
                window.location.href = editUrl;

                // 注意:这里不会进行AJAX调用,因为我们要跳转到另一个页面
            });


    }

    // 绑定删除地址事件
    function bindDeleteAddressEvents() {
        $('#content-area').on('click', '.delete-btn', function() {
            var addressItem = $(this).closest('.address-item');
            var addressId = addressItem.data('address-id'); // 假设每个地址项都有一个data-address-id属性来存储地址ID

            if (confirm('确定要删除这个地址吗?')) { // 添加确认对话框
                $.ajax({
                    url: 'http://localhost:8080/fshop/receiverAddress/' + addressId, // 假设的地址删除API端点,需要地址ID作为参数
                    headers: { 'token': localStorage.getItem("token") }, // 添加身份验证token(如果需要)
                    type: 'DELETE', // 使用DELETE请求来删除资源
                    dataType: 'json',
                    success: function(response) {
                        if (response.code == 1) {
                            addressItem.remove(); // 从DOM中删除地址项
                            alert('地址删除成功!');
                        } else {
                            alert('地址删除失败:' + response.message);
                        }
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        alert('删除地址时发生错误:' + textStatus + ', 详细信息: ' + errorThrown);
                    }
                });
            }
        });
    }



    loadContent('my_addresses');
    initProvinceSelect(); // 初始化省份下拉列表
    bindAddNewAddressEvents();
    bindEditAddressEvents();
    bindDeleteAddressEvents();









});











address_edit.html



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>




    <script src="../common/jquery-3.3.1.min.js"></script>

    <script>
        function getQueryParam(name) {
            var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
                results = regex.exec(window.location.href);
            if (!results) return null;
            if (!results[2]) return '';
            return decodeURIComponent(results[2].replace(/\+/g, " "));
        }

        // 使用方式
        var addressId = getQueryParam('addressId');
        console.log(addressId); // 输出地址ID的值
    </script>


    <style>
        /* 基本表单样式 */
        #newAddressForm {
            max-width: 600px;
            margin: 0 auto; /* 水平居中 */
            padding: 20px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        /* 表单项样式 */
        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            display: block;
            font-weight: bold;
            margin-bottom: 5px;
        }

        .form-group input[type="text"],
        .form-group input[type="tel"],
        .form-group textarea {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box; /* 包括内边距和边框在内,宽度占满容器 */
        }

        /* 下拉列表样式 */
        .form-group select {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        /* 单选按钮样式 */
        .form-group input[type="radio"] {
            margin-right: 5px;
        }

        /* 提交和取消按钮样式 */
        .form-actions {
            text-align: right; /* 右对齐按钮 */
            margin-top: 20px;
        }

        .form-actions input[type="button"],
        .form-actions button {
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .form-actions input[type="button"]:hover,
        .form-actions button:hover {
            background-color: #ddd; /* 鼠标悬停时背景色变浅 */
        }

        /* 保存按钮样式 */
        #submitBtn {
            background-color: #4CAF50; /* 绿色背景 */
            color: white; /* 白色文本 */
        }

        /* 取消按钮样式 */
        .cancel-new-address-btn {
            background-color: #f44336; /* 红色背景 */
            color: white; /* 白色文本 */
        }

        /* 加载指示器样式(如果需要的话) */
        #loading-indicator {
            text-align: center;
            padding: 10px;
            background-color: rgba(255, 255, 255, 0.8);
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 9999; /* 确保在其他元素之上 */
        }
    </style>
</head>
<body>


<!-- 加载指示器(可选) -->
<div id="loading-indicator" style="display: none;">加载中...</div>



<form id="newAddressForm" style="display: none;">



    <!-- 用户ID(隐藏字段) -->
    <input type="hidden" id="userId" name="userId" value=""> <!-- 这里的值应该由后台设置 -->

    <!-- 收件地址ID(隐藏字段),对于新地址可能是空的或自动生成 -->
    <input type="hidden" id="receiveAddressId" name="receiveAddressId" value=""> <!-- 这里的值可能是空的,或者由后台在编辑地址时提供 -->


    <!-- 收件人姓名 -->
    <div class="form-group">
        <label for="receiverName">收件人姓名:</label>
        <input type="text" id="receiverName" name="receiverName" placeholder="请输入收件人姓名" required>
    </div>

    <!-- 收件人电话号码 -->
    <div class="form-group">
        <label for="receiverPhone">收件人电话号码:</label>
        <input type="tel" id="receiverPhone" name="receiverPhone" placeholder="请输入收件人电话号码" required>
    </div>

    <!-- 省份(这里假设使用下拉选择) -->
    <div class="form-group">
        <label for="receiverProvince">省份:</label>
        <select id="receiverProvince" name="receiverProvince" required>
            <!-- 这里应该动态生成省份选项 -->
            <option value="">请选择</option>
            <!-- <option value="province1">省份1</option> -->
            <!-- ... -->
        </select>
    </div>

    <!-- 城市(同样假设使用下拉选择) -->
    <div class="form-group">
        <label for="receiverCity">城市:</label>
        <select id="receiverCity" name="receiverCity" required>
            <!-- 这里应该根据选择的省份动态生成城市选项 -->
            <option value="">请选择</option>
            <!-- <option value="city1">城市1</option> -->
            <!-- ... -->
        </select>
    </div>

    <!-- 县区(假设使用下拉选择) -->
    <div class="form-group">
        <label for="receiverArea">县区:</label>
        <select id="receiverArea" name="receiverArea" required disabled>
            <!-- 这里应该根据选择的城市动态生成县区选项 -->
            <option value="">请选择</option>
            <!-- <option value="area1">县区1</option> -->
            <!-- ... -->
        </select>
    </div>



    <!-- 街道 -->
    <div class="form-group">
        <label for="receiverStreet">街道:</label>
        <select id="receiverStreet" name="receiverStreet" required disabled>
            <option value="">请选择</option>
            <!-- 街道选项将根据县区动态生成 -->
        </select>
    </div>

    <!-- 详细地址 -->
    <div class="form-group">
        <label for="receiverDetail">详细地址:</label>
        <textarea id="receiverDetail" name="receiverDetail" placeholder="请输入详细地址" required></textarea>
    </div>
    <!-- ... -->

    <!-- 是否是默认收件地址(使用单选按钮) -->
    <div class="form-group">
        <label>
            <input type="radio" id="isDefaultYes" name="isDefault" value="1">
            是默认收件地址
        </label>
        <label>
            <input type="radio" id="isDefaultNo" name="isDefault" value="0" checked>
            不是默认收件地址
        </label>
    </div>

    <!-- 其他字段,如other1, other2,可以根据需要添加 -->
    <!-- ... -->

    <!-- 提交和取消按钮 -->
    <div class="form-actions">
        <input type="button" id="submitBtn" value="保存">
        <button type="button" id="cancelBtn" class="cancel-new-address-btn">取消</button>
    </div>
</form>

</body>





<script>


    $(document).ready(function() {
        // 显示加载指示器
        $('#loading-indicator').show();


    var provinces = [
        {
            name: '省份1',
            cities: [
                { name: '城市1', areas: [{ name: '县区1', streets: ['街道1-1', '街道1-2'] }, { name: '县区2', streets: ['街道2-1', '街道2-2'] }] },
                // ... 更多城市和县区
            ]
        },
        {
            name: '省份2',
            cities: [
                { name: '城市3', areas: [{ name: '县区3', streets: ['街道3-1', '街道3-2'] }] },
                // ... 更多城市和县区
            ]
        },
        {
            name: '江苏省',
            cities: [
                { name: '宿迁市', areas: [{ name: '灌南县', streets: ['五老村街道', '五老村街道3'] },{ name: '2县', streets: ['2街道', '3街道'] }] },
                // ... 更多城市和县区
            ]
        }


        // ... 添加更多省份和城市
    ];

    // 初始化省份下拉列表
    function initProvinceSelect() {
        var $provinceSelect = $('#receiverProvince');
        $provinceSelect.empty();
        $provinceSelect.append($('<option>').val('').text('请选择'));
        $.each(provinces, function(index, province) {
            $provinceSelect.append($('<option>').val(province.name).text(province.name));
        });
    }

    // 根据选择的省份初始化城市下拉列表
    function initCitySelect(provinceName) {
        var $citySelect = $('#receiverCity');
        $citySelect.empty();
        $citySelect.append($('<option>').val('').text('请选择'));

        var $areaSelect = $('#receiverArea');
        $areaSelect.empty().append($('<option>').val('').text('请选择'));
        $areaSelect.prop('disabled', true);

        var $streetSelect = $('#receiverStreet');
        $streetSelect.empty().append($('<option>').val('').text('请选择'));
        $streetSelect.prop('disabled', true);

        $.each(provinces, function(index, province) {
            if (province.name === provinceName) {
                $.each(province.cities, function(cityIndex, city) {
                    $citySelect.append($('<option>').val(city.name).text(city.name));
                });
                return false; // 找到匹配的省份后退出循环
            }
        });
    }

    // 根据选择的城市初始化县区下拉列表
    function initAreaSelect(cityName) {
        var $areaSelect = $('#receiverArea');
        $areaSelect.empty();
        $areaSelect.append($('<option>').val('').text('请选择'));

        var $streetSelect = $('#receiverStreet');
        $streetSelect.empty().append($('<option>').val('').text('请选择'));
        $streetSelect.prop('disabled', true);

        $.each(provinces, function(index, province) {
            $.each(province.cities, function(cityIndex, city) {
                if (city.name === cityName) {
                    $.each(city.areas, function(areaIndex, area) {
                        $areaSelect.append($('<option>').val(area.name).text(area.name));
                    });
                    $areaSelect.prop('disabled', false);
                    return false; // 找到匹配的城市后退出循环
                }
            });
        });
    }

    // 根据选择的县区初始化街道下拉列表
    function initStreetSelect(areaName) {
        var $streetSelect = $('#receiverStreet');
        $streetSelect.empty();
        $streetSelect.append($('<option>').val('').text('请选择'));

        $.each(provinces, function(index, province) {
            $.each(province.cities, function(cityIndex, city) {
                $.each(city.areas, function(areaIndex, area) {
                    if (area.name === areaName) {
                        $.each(area.streets, function(streetIndex, street) {
                            $streetSelect.append($('<option>').val(street).text(street));
                        });
                        $streetSelect.prop('disabled', false);
                        return false; // 找到匹配的县区后退出循环
                    }
                });
                if (!$streetSelect.prop('disabled')) return false; // 如果已经找到匹配的县区,则退出城市循环
            });
        });
    }

    // 绑定省份下拉列表的change事件
    $('#receiverProvince').on('change', function() {
        var selectedProvince = $(this).val();
        if (selectedProvince) {
            initCitySelect(selectedProvince);
        }
    });

    // 绑定城市下拉列表的change事件
    $('#receiverCity').on('change', function() {
        var selectedCity = $(this).val();
        if (selectedCity) {
            initAreaSelect(selectedCity);
        }
    });

    // 绑定县区下拉列表的change事件
    $('#receiverArea').on('change', function() {
        var selectedArea = $(this).val();
        if (selectedArea) {
            initStreetSelect(selectedArea);
        }
    });

    initProvinceSelect(); // 初始化省份下拉列表


    });


















    // 获取地址ID
    var addressId = getQueryParam('addressId');
    if (addressId) {
        // 发送AJAX请求获取地址详情
        $.ajax({
            url: 'http://localhost:8080/fshop/receiverAddress/' + addressId, // 假设的API端点
            headers: { 'token': localStorage.getItem("token") },
            type: 'GET',
            dataType: 'json',
            success: function(address) {
                let addressData = address.data;
                // 隐藏加载指示器
                $('#loading-indicator').hide();

                // 更新表单字段
                $('#receiveAddressId').val(addressData.receiveAddressId); // 如果需要显示这个ID
                $('#userId').val(addressData.userId); // 假设后台已经提供了这个值
                $('#receiverName').val(addressData.receiverName);
                $('#receiverPhone').val(addressData.receiverPhone);


                // 假设你已经从某处获得了要选中的省份的值
                //var selectedProvince = addressData.receiverProvince;
                // 使用jQuery选择器找到对应的<option>并设置selected属性
                //$('#receiverProvince option[value="' + selectedProvince + '"]').prop('selected', true);

                // 设置省份下拉列表的选中项
                $('#receiverProvince').val(addressData.receiverProvince).trigger('change'); // 触发change事件以更新城市列表



                // 注意:由于城市、县区、街道的更新依赖于之前的change事件,这里不需要立即设置它们的值
                // 因为change事件的监听器会处理这些更新


                $('#receiverDetail').val(addressData.receiverDetail);

                var defaultValueFromBackend = addressData.isDefault;

                // 设置默认收件地址单选按钮
                if (defaultValueFromBackend === 1) {
                    $('#isDefaultYes').prop('checked', true);
                } else if (defaultValueFromBackend === 0) {
                    $('#isDefaultNo').prop('checked', true);
                }










                // 显示表单
                $('#newAddressForm').show();
            },
            error: function(jqXHR, textStatus, errorThrown) {
                // 隐藏加载指示器
                $('#loading-indicator').hide();

                // 显示错误信息或执行其他错误处理逻辑
                alert('获取地址详情失败:' + textStatus);
            }
        });
    }





    // ... 省略其他代码 ...

    // 绑定保存按钮的点击事件
    $('#submitBtn').on('click', function(event) {
        // 阻止表单的默认提交行为
        event.preventDefault(); // 注意这里需要传入 event 参数,例如 function(event) {...}

        // 收集表单数据
        var formData = {
            userId: $('#userId').val(),
            receiveAddressId: $('#receiveAddressId').val(),
            receiverName: $('#receiverName').val(),
            receiverPhone: $('#receiverPhone').val(),
            receiverProvince: $('#receiverProvince').val(),
            receiverCity: $('#receiverCity').val(),
            receiverArea: $('#receiverArea').val(),
            receiverStreet: $('#receiverStreet').val(),
            receiverDetail: $('#receiverDetail').val(),
            isDefault: $('input[name="isDefault"]:checked').val()
        };

        // 发送 AJAX POST 请求到服务器
        $.ajax({
            url: 'http://localhost:8080/fshop/receiverAddress/updateAddr', // 保存地址的API端点
            contentType: 'application/json; charset=utf-8', // 设置请求体的内容类型为 JSON
            headers:{'token': localStorage.getItem("token")},
            type: 'POST',
            data: JSON.stringify(formData),
            headers: { 'token': localStorage.getItem("token") }, // 身份验证token(如果需要)
            dataType: 'json',
            success: function(response) {
                console.log(response);
                if (response.code == 1 ) { // 假设后端返回的成功状态码是 1 或者有 success 字段为 true
                    // 提交成功,跳转到另一个页面
                    window.location.href = 'user_index.html';
                } else {
                    // 处理提交失败的情况(比如显示错误消息)
                    alert('地址保存失败:' + response.message);
                }
            },
            error: function(jqXHR, textStatus, errorThrown) {
                // 处理 AJAX 请求失败的情况
                alert('保存地址时发生错误:' + textStatus + ', 详细信息: ' + errorThrown);
            }
        });
    });

    // ... 省略其他代码 ...




    $('#cancelBtn').on('click', function(event) {
        event.preventDefault();
        window.location.href = 'user_index.html';
    });






</script>


</html>



ReceiverAddress


package com.fshop.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * <p>
 * 地址表
 * </p>
 *
 * @author dev
 * @since 2024-04-23
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("receiver_address")
public class ReceiverAddress implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 地址ID
     */
    @TableId(value = "receive_address_id", type = IdType.AUTO)
    private Integer receiveAddressId;

    /**
     * 用户ID,外键(关联用户表)
     */
    private Integer userId;

    /**
     * 收件人姓名
     */
    private String receiverName;

    /**
     * 收件人电话号码
     */
    private String receiverPhone;

    /**
     * 省份
     */
    private String receiverProvince;

    /**
     * 城市
     */
    private String receiverCity;

    /**
     * 县区
     */
    private String receiverArea;

    /**
     * 街道
     */
    private String receiverStreet;

    /**
     * 详细地址
     */
    private String receiverDetail;

    /**
     * 是否是默认收件地址,默认值0
     */
    private Byte isDefault;

    /**
     * 地址状态
     */
    private Integer status;

    /**
     * 版本
     */
    private Integer version;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    /**
     * 最近更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

    private String other1;

    private String other2;

}



ReceiverAddressController


package com.fshop.controller;

import com.fshop.common.R;
import com.fshop.common.ResponseCode;
import com.fshop.entity.ReceiverAddress;
import com.fshop.service.IReceiverAddressService;
import com.fshop.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 地址表 前端控制器

 *
 * @author dev
 * @since 2024-04-23
 */
@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/receiverAddress")
@RequiredArgsConstructor
@Slf4j
public class ReceiverAddressController {

    private final IReceiverAddressService receiverAddressService;

    /**
     * 根据用户id查询地址
     * @return
     */
    @GetMapping()
    public R<List<ReceiverAddress>> getById(HttpServletRequest request){
        //获取token
        String token = request.getHeader("token");
        log.info("根据id查询地址的token:{}",token);

        //检查token
        if (JwtUtil.checkToken(token)){
            log.info("查询地址的token正确:{}",token);
            // 查询地址调用业务
            R<List<ReceiverAddress>> listR = receiverAddressService.getById(token);
            log.info("查询地址返回的数据:{}",listR);
            return listR;
        }
        //token失效
        return R.error(ResponseCode.TOKEN_ERROR);

    }

    /**
     * 根据地址id查询地址
     * @return
     */
    @GetMapping("{addrId}")
    public R<ReceiverAddress> getByAddrId(@PathVariable("addrId") Integer addrId){
        // 查询地址调用业务
        log.info("地址id:{}",addrId);
        R<ReceiverAddress> result = receiverAddressService.getByAddrId(addrId);
        return result;

    }

    /**
     * 添加地址
     * @return
     */
    @PostMapping("/saveAddr")
    public R<ReceiverAddress> saveAddr(@RequestBody ReceiverAddress receiverAddress, HttpServletRequest request){
        // 查询地址调用业务
        log.info("地址信息:{}",receiverAddress);

        String token = request.getHeader("token");
        log.info("地址信息token:{}",token);
        if (JwtUtil.checkToken(token)){
            R<ReceiverAddress> receiverAddressR = receiverAddressService.saveAddr(receiverAddress, token);
            return receiverAddressR;
        }
        return R.error(ResponseCode.TOKEN_ERROR);

    }




    /**
     * 修改地址
     * @return
     */
    @PostMapping("/updateAddr")
    public R<ReceiverAddress> updateAddr(@RequestBody ReceiverAddress receiverAddress, HttpServletRequest request){
        // 查询地址调用业务
        //log.info("地址信息:{}",receiverAddress);

        String token = request.getHeader("token");
        //log.info("地址信息token:{}",token);
        if (JwtUtil.checkToken(token)){
            R<ReceiverAddress> receiverAddressR = receiverAddressService.updateAddr(receiverAddress, token);
            return receiverAddressR;
        }
        return R.error(ResponseCode.TOKEN_ERROR);

    }










    /**
     * 删除地址
     * @return
     */
    @DeleteMapping("{addrId}")
    public R<ReceiverAddress> deleteByAddrId(@PathVariable("addrId") Integer addrId, HttpServletRequest request){


        String token = request.getHeader("token");

        if (JwtUtil.checkToken(token)){
            R<ReceiverAddress> receiverAddressR = receiverAddressService.deleteByAddrId(addrId, token);
            return receiverAddressR;
        }
        return R.error(ResponseCode.TOKEN_ERROR);

    }








}


ReceiverAddressServiceImpl


package com.fshop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fshop.common.R;
import com.fshop.dto.LoginUserDto;
import com.fshop.entity.ReceiverAddress;
import com.fshop.mapper.ReceiverAddressMapper;
import com.fshop.service.IReceiverAddressService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fshop.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 地址表 服务实现类
 * </p>
 *
 * @author dev
 * @since 2024-04-23
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ReceiverAddressServiceImpl extends ServiceImpl<ReceiverAddressMapper, ReceiverAddress> implements IReceiverAddressService {

    //dao层接口
    private final ReceiverAddressMapper receiverAddressMapper;

    /**
     * 根据用户id查询地址
     * @param token 用户携带的token
     * @return 返回地址信息
     */
    @Override
    public R<List<ReceiverAddress>> getById(String token) {

        log.info("根据用户id查询地址:{}",token);
        //解析token,获取用户信息
        LoginUserDto loginUserDto = JwtUtil.parseToken(token);
        //根据id查询地址
        QueryWrapper<ReceiverAddress> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",loginUserDto.getUserId()).eq("status",1);

        List<ReceiverAddress> receiverAddresses = receiverAddressMapper.selectList(wrapper);



        log.info("根据用户id查询到的地址信息:{}",receiverAddresses);
        //返回数据
        return R.ok(receiverAddresses);
    }

    /**
     * 根据地址id查询
     * @param addrId
     * @return
     */
    @Override
    public R<ReceiverAddress> getByAddrId(Integer addrId) {
        ReceiverAddress address = receiverAddressMapper.selectById(addrId);
        if (address != null)
            return R.ok(address);
        return R.error("地址不存在");
    }

    /**
     * 添加地址
     * @param receiverAddress
     * @param token
     * @return
     */
    @Override
    public R<ReceiverAddress> saveAddr(ReceiverAddress receiverAddress, String token) {
        //查询用户id
        LoginUserDto loginUserDto = JwtUtil.parseToken(token);
        if (loginUserDto.getUserId() != null){
            //填充地址数据
            receiverAddress.setUserId(loginUserDto.getUserId());
            receiverAddress.setStatus(1);
            receiverAddress.setVersion(1);
            receiverAddress.setCreateTime(LocalDateTime.now());
            receiverAddress.setUpdateTime(LocalDateTime.now());
            Integer insert = receiverAddressMapper.insert(receiverAddress);
            if (insert > 0){
                return R.ok(receiverAddress);
            }
            return R.error("添加失败");
        }
        return R.error("token错误,未登录");

    }






    /**
     * 修改地址
     * @param receiverAddress
     * @param token
     * @return
     */
    @Override
    public R<ReceiverAddress> updateAddr(ReceiverAddress receiverAddress, String token) {
        //查询用户id
        LoginUserDto loginUserDto = JwtUtil.parseToken(token);
        if (loginUserDto.getUserId() != null && receiverAddress.getUserId().equals(loginUserDto.getUserId())){

            ReceiverAddress receiverAddress1 = receiverAddressMapper.selectById(receiverAddress.getReceiveAddressId());//
            receiverAddress.setVersion(receiverAddress1.getVersion()+1);
            receiverAddress.setUpdateTime(LocalDateTime.now());
            Integer update = receiverAddressMapper.updateById(receiverAddress);
            if (update > 0){
                return R.ok(receiverAddress);
            }
            return R.error("修改失败");
        }
        return R.error("token错误,未登录");

    }




    @Override
    public R<ReceiverAddress> deleteByAddrId(@PathVariable("addrId") Integer addrId,String token){
        //查询用户id
        LoginUserDto loginUserDto = JwtUtil.parseToken(token);
        ReceiverAddress receiverAddress = receiverAddressMapper.selectById(addrId);
        receiverAddress.setStatus(0);
        if(receiverAddress != null && receiverAddress.getUserId().equals(loginUserDto.getUserId())){

            receiverAddressMapper.updateById(receiverAddress);
            return R.ok("删除成功");
        }
        return  R.error("删除失败");




    }






}




IReceiverAddressService


package com.fshop.service;

import com.fshop.common.R;
import com.fshop.entity.ReceiverAddress;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

/**
 * <p>
 * 地址表 服务类
 * </p>
 *
 * @author dev
 * @since 2024-04-23
 */
public interface IReceiverAddressService extends IService<ReceiverAddress> {

    //根据用户id查询地址
    R<List<ReceiverAddress>> getById(String token);

    //根据地址id查询地址信息
    R<ReceiverAddress> getByAddrId(Integer addrId);
    //添加地址
    R<ReceiverAddress> saveAddr(ReceiverAddress receiverAddress, String token);


    public R<ReceiverAddress> deleteByAddrId(@PathVariable("addrId") Integer addrId, String token);


    public R<ReceiverAddress> updateAddr(ReceiverAddress receiverAddress, String token);
}



R


package com.fshop.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;

import java.io.Serializable;

// @JsonInclude 保证序列化json的时候, 如果是null的对象, key也会消失
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class R<T> implements Serializable {
    private static final long serialVersionUID = 7735505903525411467L;

    // 成功值,默认为1
    private static final int SUCCESS_CODE = 1;
    // 失败值,默认为0
    private static final int ERROR_CODE = 0;

    // 状态码
    private final int code;
    // 消息
    private String msg;
    // 返回数据
    private T data;

    private R(int code) {
        this.code = code;
    }

    private R(int code, T data) {
        this.code = code;
        this.data = data;
    }

    private R(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    private R(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> R<T> ok() {
        return new R<T>(SUCCESS_CODE, "success");
    }

    public static <T> R<T> ok(String msg) {
        return new R<T>(SUCCESS_CODE, msg);
    }

    public static <T> R<T> ok(T data) {
        return new R<T>(SUCCESS_CODE, data);
    }

    public static <T> R<T> ok(String msg, T data) {
        return new R<T>(SUCCESS_CODE, msg, data);
    }

    public static <T> R<T> error() {
        return new R<T>(ERROR_CODE, "error");
    }

    public static <T> R<T> error(String msg) {
        return new R<T>(ERROR_CODE, msg);
    }

    public static <T> R<T> error(int code, String msg) {
        return new R<T>(code, msg);
    }

    public static <T> R<T> error(ResponseCode res) {
        return new R<T>(res.getCode(), res.getMessage());
    }

    @Override
    public String toString() {
        return "R{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}


FshopAppApplication



package com.fshop;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@MapperScan("com.fshop.mapper")
public class FshopAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(FshopAppApplication.class, args);
    }

}


ServletInitializer


package com.fshop;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(FshopAppApplication.class);
    }

}



pom.xml



<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.fshop</groupId>
    <artifactId>fshop-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>fshop-app</name>
    <description>fshop-app</description>

    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>


        <!--短信-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.15</version>
        </dependency>



        <!-- SPRINGBOOT -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- JDBC -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <!-- MYBATIS PLUS -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- DRUID -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.9</version>
        </dependency>


        <!--REDIS-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <!-- ALIPAY -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.1.0</version>
        </dependency>


        <!-- LOMBOK -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- rabbitmq -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.9.10</version>
        </dependency>
         <!-- servlet -->
        <!--<dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>-->
        <!-- 牛🐎云相关依赖 -->
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>7.13.0</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.14.2</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>happy-dns-java</artifactId>
            <version>0.1.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.6</version>
            </plugin>
        </plugins>
    </build>

</project>



ReceiverAddressMapper.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fshop.mapper.ReceiverAddressMapper">

</mapper>




ReceiverAddressMapper.java


package com.fshop.mapper;

import com.fshop.entity.ReceiverAddress;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 * 地址表 Mapper 接口
 * </p>
 *
 * @author dev
 * @since 2024-04-23
 */
public interface ReceiverAddressMapper extends BaseMapper<ReceiverAddress> {

}


  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 洁 冬冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值