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

文章目录

    • user_index.html
    • myaccount_style.css
    • myaccount_scripts.js
    • address_edit.html
    • ReceiverAddress
    • ReceiverAddressController
    • ReceiverAddressServiceImpl
    • IReceiverAddressService
    • R
    • FshopAppApplication
    • ServletInitializer
    • pom.xml
    • ReceiverAddressMapper.xml
    • ReceiverAddressMapper.java

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(); // 初始地址列表HTMLfunction 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', // 设置请求体的内容类型为 JSONheaders:{'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(); // 隐藏表单});}// 辅助函数,用于从响应数据中创建地址项HTMLfunction 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属性来存储地址IDif (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(); // 初始化省份下拉列表});// 获取地址IDvar 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', // 设置请求体的内容类型为 JSONheaders:{'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){//获取tokenString token = request.getHeader("token");log.info("根据id查询地址的token:{}",token);//检查tokenif (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 返回地址信息*/@Overridepublic 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*/@Overridepublic 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*/@Overridepublic R<ReceiverAddress> saveAddr(ReceiverAddress receiverAddress, String token) {//查询用户idLoginUserDto 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*/@Overridepublic R<ReceiverAddress> updateAddr(ReceiverAddress receiverAddress, String token) {//查询用户idLoginUserDto 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错误,未登录");}@Overridepublic R<ReceiverAddress> deleteByAddrId(@PathVariable("addrId") Integer addrId,String token){//查询用户idLoginUserDto 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;// 成功值,默认为1private static final int SUCCESS_CODE = 1;// 失败值,默认为0private 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());}@Overridepublic 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 {@Overrideprotected 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> {}

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

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

相关文章

文件存储解决方案-阿里云OSS

文章目录 1.菜单分级显示问题1.问题引出1.苹果灯&#xff0c;放到节能灯下面也就是id大于1272.查看菜单&#xff0c;并没有出现苹果灯3.放到灯具下面id42&#xff0c;就可以显示 2.问题分析和解决1.判断可能出现问题的位置2.找到递归返回树形菜单数据的位置3.这里出现问题的原因…

Golang 的 unmarshal 踩坑指南

文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 & 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面 笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例…

算法学习笔记(5.0)-基于比较的高效排序算法-归并排序

##时间复杂度O(nlogn) 目录 ##时间复杂度O(nlogn) ##递归实现归并排序 ##原理 ##图例 ##代码实现 ##非递归实现归并排序 ##释 #代码实现 ##递归实现归并排序 ##原理 是一种基于分治策略的基础排序算法。 1.划分阶段&#xff1a;通过不断递归地将数组从中点处分开&…

Java 开发 框架安全:Spring 命令执行漏洞.(CVE-2022-22965)

什么叫 Spring 框架. Spring 框架是一个用于构建企业级应用程序的开源框架。它提供了一种全面的编程和配置模型&#xff0c;可以简化应用程序的开发过程。Spring 框架的核心特性包括依赖注入&#xff08;Dependency Injection&#xff09;、面向切面编程&#xff08;Aspect-Or…

【SpringBoot笔记43】SpringBoot应用程序集成spring-boot-admin监控工具

这篇文章,主要介绍SpringBoot应用程序如何集成spring-boot-admin监控工具。 目录 一、spring-boot-admin监控工具 1.1、创建admin-client客户端 (1)引入依赖

DeepSpeed

文章目录 一、关于 DeepSpeed1、DeepSpeed 是什么2、深度学习训练和推理的极致速度和规模3、DeepSpeed 的四大创新支柱1&#xff09;DeepSpeed 训练2&#xff09;DeepSpeed 推理3&#xff09;DeepSpeed 压缩4&#xff09;DeepSpeed4Science 4、DeepSpeed 软件套件DeepSpeed 库推…

React 第二十七章 Hook useCallback

useCallback 是 React 提供的一个 Hook 函数&#xff0c;用于优化性能。它的作用是返回一个记忆化的函数&#xff0c;当依赖发生变化时&#xff0c;才会重新创建并返回新的函数。 在 React 中&#xff0c;当一个组件重新渲染时&#xff0c;所有的函数都会被重新创建。这可能会…

青少年软件编程(Python)等级考试试卷(五级)2024年3月

2024.03 电子学会 青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;五级&#xff09; 一、单选题 1.以下代码的输出结果是? ) nums list(range(100, 201)) print(nums[::10]) A.[100,110,120,130,140,150,160,170,180,190,200] B.[100,101,1…

QML笔记八

QML与C交互 QML中调用C功能、使用QML或者Quick中的C接口、使用C实现自定义的QML对象 注&#xff1a; 只有QObject的派生类才能与QML交互 QML引擎集成Qt元对象系统&#xff0c;QObject的派生子类的属性、方法、信号都可以在QML中访问 C类可以被注册为一个QML实例 C类可以被注册为…

【Web后端】请求头

1、简介 请求头&#xff08;Request Headers&#xff09;是在HTTP协议中&#xff0c;客户端&#xff08;如浏览器或应用程序&#xff09;向服务器发送请求时附带的元数据。包含了关于请求的额外信息&#xff0c;有助于客户端与服务器之间的有效通信。请求头中的信息可以让服务…

.[sqlback@memeware.net].2700勒索病毒数据怎么处理|数据解密恢复

导言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全问题愈发严峻&#xff0c;其中勒索病毒成为了企业和个人用户面临的重要威胁之一。.[sqlbackmemeware.net].2700勒索病毒作为其中的佼佼者&#xff0c;以其独特的攻击方式和强大的破坏力&#xff0c;引起了广泛关注…

【Go语言入门学习笔记】Part1.梦开始的地方

一、前言 经过一系列的学习&#xff0c;终于有时间来学习一些新的语言&#xff0c;Go语言在现在还是比较时髦的&#xff0c;多一个技能总比不多的好&#xff0c;故有时间来学一下。 二、配置环境 按照网络中已有的配置方法配置好&#xff0c;本人采用了Jetbrain的Goland&#…

DTC 2024回顾丨zData X 多元数据库一体机:开创多元数据库时代部署新范式

导语 在2024“数据技术嘉年华”上&#xff0c;云和恩墨数据库一体机产品总经理刘宇在“数据库极致特性”专题论坛发表了题为《打造多元数据库部署新范式&#xff0c;引领一体化资源池创新之路》的演讲。他深入分析了国产数据库面临的挑战&#xff0c;并详细介绍了云和恩墨如何利…

5.10.1 Pre-Trained Image Processing Transformer

研究了低级计算机视觉任务&#xff08;例如去噪、超分辨率和去雨&#xff09;并开发了一种新的预训练模型&#xff0c;即图像处理变压器&#xff08;IPT&#xff09;。利用著名的 ImageNet 基准来生成大量损坏的图像对。 IPT 模型是在这些具有多头和多尾的图像上进行训练的。此…

Megatron-lm、DeepSpeed

1、为了训练更多的数据、更大的模型&#xff0c;提出了并行训练框架。 2、并行的方式&#xff1a;数据并行、模型并行&#xff08;张量并行、流水线并行&#xff09;。 3、Megatron-LM 综合应用了数据并行&#xff08;Data Parallelism&#xff09;&#xff0c;张量并行&…

内网安全工具之ADExplorer的使用

ADExplorer是域内一款信息查询工具&#xff0c;它是独立的可执行文件&#xff0c;无需安装。它能够列出域组织架构、用户账号、计算机账号登&#xff0c;可以帮助寻找特权用户和数据库服务器等敏感目标。 下载地址&#xff1a;http://live.sysinternals.com/ 连接 下载了ADE…

第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组 拼数字

//bfs只能过40%。 #include<bits/stdc.h> using namespace std; #define int long long int a,b,c,dp[2028]; struct s {int x,y,z;string m; }; map<vector<int>,int>k; signed main() {ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>a…

Java入门基础学习笔记24——While循环和do-while循环

1、While循环&#xff1a; 例1&#xff1a; package cn.ensource.loop;public class WhileDemo3 {public static void main(String[] args) {// 目标&#xff1a;掌握while循环的书写格式&#xff0c;以及理解其执行流程// 需求&#xff1a;打印多行Hello Worldint i 0;while…

EFCore_创建项目

添加依赖 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.Tools(Migration工具) 根据使用的DB添加对应依赖&#xff1a; SQL Server&#xff1a;Microsoft.EntityFrameworkCore.SqlServer 添加该依赖时可不添加Microsoft.EntityFrameworkCore&#xff0c;该依…

电工能混到这份上

最近看到某电工师傅发了一篇帖子&#xff0c;大致内容是他在处理一个简单故障的时候居然花了很长的时间。我们一起来看看他遇到的是什么故障吧! plc 控制的一台设备&#xff0c;行走部分靠 2 个脚踏开关控制&#xff08;内部开关量控制方向&#xff0c;电位器控制速度&#xff…