SpringBoot项目--电脑商城【确认订单】

news2024/11/27 3:49:10

1.持久层[Mapper]

1.1规划需要执行的SQL语句

用户在购物车列表页中通过随机勾选相关的商品,在点击"结算"按钮后跳转到"确认订单页",在这个页面中需要展示用户在上个页面所勾选的"购物车列表页"中对应的数据.说白了也就是列表展示,且展示的内容还是来自于购物车表.但是用户勾选了哪些商品呢,所以"购物车列表页"需要将用户勾选的商品id传递给"确认订单页"

所以在持久层需要完成“根据若干个不确定的id值,查询购物车数据表,显示购物车中的数据信息”。则需要执行的SQL语句大致是。

select
    cid,
    uid,
    pid,
    t_cart.price,
    t_cart.num,
    title,
    t_product.price as realPrice,
    image
from t_cart
left join t_product on t_cart.pid = t_product.id
where
	cid in (?,?,?)
order by
	t_cart.created_time desc

注意where cid in (?,?,?),这里是需要传入cid的集合

1.2 设计接口和抽象方法

在CartMapper接口中添加findVOByCids抽象方法

List<CartVO> findVOByCids(Integer[] cids);

1.3配置映射

1.在CartMapper.xml文件中添加SQL语句的映射配置

<select id="findVOByCids" resultType="com.cy.store.vo.CartVO">
    select
        cid,
        uid,
        pid,
        t_cart.price,
        t_cart.num,
        title,
        t_product.price as realPrice,
        image
    from t_cart
    left join t_product on t_cart.pid = t_product.id
    where
        cid in (
            <foreach collection="array" item="cid" separator=",">
                #{cid}
            </foreach>
            )
    order by
    	t_cart.created_time desc
</select>

foreach循环就是一个for循环

  • collection标识循环的是list集合还是数组,如果是list集合就用collection=“list”
  • item用来接收每次循环获取的值
  • separator标识循环出来的值中间用什么隔开,且最后循环出来的值后面不加

1.4 单元测试

@Test
public void findVOByCids() {
    Integer[] cids = {1, 2, 6, 8, 100};//可以写表中不存在的,无非就是查不到数据,并不会报错
    List<CartVO> list = cartMapper.findVOByCids(cids);
    for (CartVO item : list) {
        System.out.println(item);
    }
}

2.业务层[Service]

2.1规划异常

查询语句,没有需要规划的异常,在业务层判断这几条购物车商品的数据归属是否正确,如果不正确也不需要抛出异常,直接从查询到的数据中移除该商品就行了

2.2设计接口和抽象方法及实现

1.在ICartService接口中添加getVOByCids()抽象方法

List<CartVO> getVOByCids(Integer uid, Integer[] cids);//uid是为了判断数据归属是否正确

2.在CartServiceImpl类中重写业务接口中的抽象方法

@Override
public List<CartVO> getVOByCids(Integer uid, Integer[] cids) {
    List<CartVO> list = cartMapper.findVOByCids(cids);

    //可以使用for遍历,这里玩个新的,用迭代器遍历
    Iterator<CartVO> it = list.iterator();
    while (it.hasNext()) {

        //指向的是该元素之前,所以需要next得到该元素
        CartVO cart = it.next();

        if (!cart.getUid().equals(uid)) {
            /**
             * 不能用list.remove(cart)
             * 在迭代器进行遍历的时候不能使用集合的移除
             * 方法,需要用迭代器特有的移除方法
             */
            it.remove();
        }
    }
    return list;
}

2.3单元测试

业务层只是调用持久层获取数据并判断归属是否正确,这里不再测试

3.控制层[Controller]

3.1处理异常

业务层没有抛出异常,所以不需要处理异常

3.2设计请求

  • /carts/list
  • GET
  • Integer[] cids, HttpSession session
  • JsonResult<List<CartVO>>

3.3处理请求

1.在CartController类中添加处理请求的getVOByCids()方法。

@RequestMapping("list")
public JsonResult<List<CartVO>> findVOByCids(Integer[] cids, HttpSession session) {
    List<CartVO> data = cartService.getVOByCids(getUidFromSession(session), cids);
    return new JsonResult<>(OK, data);
}

4.确定订单--前端页面

4.1显示勾选的购物车数据

1.检查cart.html页面,里面form标签的action="orderConfirm.html"属性(规定表单数据提交到哪里)和结算按钮的类型"type=submit"是必不可少的,这样点击"结算"时才能将数据传给"确认订单页"并在"确认订单页"展示选中的商品数据

2.在orderConfirm.html页面中实现自动加载从cart.html页面中传递过来的cids数据,再去请求ajax,然后将后端返回的数据填充在页面的某个区域中

3.orderConfirm.js文件中

  • $(“.link-pay”).click(……)作用:点击"在线支付"后跳转到支付页面,这个其实就是下个模块要做的"创建订单"功能,该功能需要和数据库交互,所以不是在前端实现的,所以这行代码无用
  • $(“.link-success”).click(…):在orderConfirm.html页面没有class为link-success的标签,所以这行代码不会被执行
  • 综上两条,orderConfirm.js文件在orderConfirm.html页面中无用,但存在可能会和下个模块"创建订单"功能冲突(下个模块会实现点击"创建订单"后页面跳转),所以注释掉

下面在orderConfirm.html页面编写js代码

<script type="text/javascript">
		$(document).ready(function (){
			showCartList()
		})


		function showCartList() {
			$("#cart-list").empty();
			/*
            * location.search.substr:是获取url中的数据
            * 1:表示查找?之前
            * 0:表示查找?之后【请求参数】
            *
            * 	这里要传data是因为后端接口需要传入参数,所以这里才要写
            * */
			$.ajax({
				url: "/cart/list",
				data: location.search.substr(1),
				type: "GET",
				dataType: "JSON",
				success: function(json) {
					let list = json.data;
					console.log("count=" + list.length);
					let allCount = 0;
					let allPrice = 0;
					for (let i = 0; i < list.length; i++) {
						console.log(list[i].title);
						let tr = '<tr>'
								+ '<td><img src="..#{image}collect.png" class="img-responsive" /></td>'
								+ '<td><input type="hidden" name="cid" value="#{cid}" />#{title}</td>'
								+ '<td>¥<span>#{realPrice}</span></td>'
								+ '<td>#{num}</td>'
								+ '<td>¥<span>#{totalPrice}</span></td>'
								+ '</tr>';

						tr = tr.replace(/#{cid}/g, list[i].cid);
						tr = tr.replace(/#{image}/g, list[i].image);
						tr = tr.replace(/#{title}/g, list[i].title);
						tr = tr.replace(/#{realPrice}/g, list[i].realPrice);
						tr = tr.replace(/#{num}/g, list[i].num);
						tr = tr.replace(/#{totalPrice}/g, list[i].realPrice * list[i].num);

						$("#cart-list").append(tr);

						allCount += list[i].num;
						allPrice += list[i].realPrice * list[i].num;
					}
					$("#all-count").html(allCount);
					$("#all-price").html(allPrice);
				},
				error: function() {
					alert("购物车数据加载未知异常 + 原因:" + xhr.status);
				}
			});
		}
	</script>

1.为什么点击购物车列表页面的"结算"按钮后地址栏中会请求http://localhost:8080/web/orderConfirm.html?cids=6&cids=5呢,因为该按钮有一个type=submit属性,且表单有一个action="orderConfirm.html"属性,所以点击该按钮后会携带表单中参数自动跳转

会携带哪些参数呢:把表单中有name属性的标签的value值传递出去,针对这个请求传递的是name"cids",其value值根据勾选的商品而定,可以是1或3或10

2.data: location.search.substr(1)这个API的参数为0表示截取地址栏中?后面的数据,即参数

如果这个API的参数为0则表示截取地址栏中?前面的数据,即请求地址

4.2显示选择收货地址

收货地址存放在前端的一个select下拉列表中,我们需要将查询到的当前登录用户的收货地址动态的加载到这个下拉列表中.从数据库的角度看,是一个select查询语句,在"收货地址列表展示"模块已经编写了该持久层,业务层,控制层,所以这里只需要编写对应的前端页面就可以了

1.在orderConfirm.html页面中的ready函数中添加showAddressList方法的调用,使确认订单页加载时能够自动从后端获取该用户地址填充到select控件中并将第一个地址显示出来

$(document).ready(function() {
    showCartList();
    showAddressList();
});

2.在orderConfirm.html页面中编写showAddressList方法

function showAddressList(){
			//清空select标签中的数据
			$("#address-list").empty();
			$.ajax({
				url:"/address",
				type: "GET",
				dataType:"JSON",
				success(e) {
					if(e.state==200){
						let list=e.data;
						for(let i=0;i<list.length;i++){
							/**
                                value="#{aid}"在该模块没有用,但是扔写上,只要是从数据库查到到的数据,都要让前端页
                                面的该条数据和id绑定(因为可能干别的什么时需要用到,就比如说下一个"创建订单"模块
                                就需要根据前端传给后端的aid查询用户选中的是哪一个地址然后将其加入订单表)
                     * */
							let opt='<option value="#{aid}">#{name}&nbsp;&nbsp;&nbsp;#{tag}&nbsp;&nbsp;&nbsp;#{provinceName}#{cityName}#{areaName}#{address}' +
									'&nbsp;&nbsp;&nbsp;#{phone}</option>\n';
							opt = opt.replace(/#{aid}/g, list[i].aid);
							opt = opt.replace(/#{tag}/g, list[i].tag);
							opt = opt.replace("#{name}", list[i].name);
							opt = opt.replace("#{provinceName}", list[i].provinceName);
							opt = opt.replace("#{cityName}", list[i].cityName);
							opt = opt.replace("#{areaName}", list[i].areaName);
							opt = opt.replace("#{address}", list[i].address);
							opt = opt.replace("#{phone}", list[i].phone);

							$("#address-list").append(opt)

						}
					}
				},
				error: function(xhr) {
					alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);
					location.href = "login.html";
				}
			})
		}

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

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

相关文章

solidworks底部状态栏显示不出来

如下图所示&#xff0c;solidworks主界面下面的状态栏突然不见了。 怎么调出来&#xff1f; 第一步&#xff1a;点击视图菜单&#xff0c;用户界面&#xff0c;把状态栏前的勾勾上。 第二步&#xff1a;把视图下面的触摸模式关掉&#xff0c;这一点很容易被大家忽略。

代码随想录--哈希--两个数组的交集

题意&#xff1a;给定两个数组&#xff0c;编写一个函数来计算它们的交集。 说明&#xff1a; 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。 import java.util.ArrayList; import java.util.HashMap; import java.util.List;public class SSS {public …

织密安全防线——记建行江门市分行推进反洗钱工作

建行广东省江门市分行多层次织密反洗钱防线&#xff0c;持续护航高质量发展。 健全架构 建行江门分行成立以“一把手”为组长的反洗钱工作领导小组。通过在部门、支行、网点层面分别设置反洗钱合规官、合规专员、情报专员、合规员等岗位&#xff0c;层层织密反洗钱防线。持续加…

【C++】构造函数意义 ( 构造函数显式调用与隐式调用 | 构造函数替代方案 - 初始化函数 | 初始化函数缺陷 | 默认构造函数 )

文章目录 一、构造函数意义1、类的构造函数2、构造函数显式调用与隐式调用3、构造函数替代方案 - 初始化函数4、初始化函数缺陷5、默认构造函数6、代码示例 - 初始化函数无法及时调用 一、构造函数意义 1、类的构造函数 C 提供的 构造函数 和 析构函数 作为 类实例对象的 初始化…

【性能测试】Jmeter插件之ServerAgent服务器性能监控工具的安装和使用

文章目录 安装插件安装ServerAgent 安装插件 1、在Jmeter官网&#xff1a;https://jmeter-plugins.org/wiki/PluginsManager/ 下载插件管理器Plugins-manager.jar 2、将JAR包放入到lib\ext目录下 3、重启Jmeter&#xff0c;可以在选项下看到Plugins Manager选项 4、安装…

解决golang无法下载依赖的奇葩问题

最近刚开始学习go&#xff0c;看了几个开源项目&#xff0c;遂下载好朋友的go开源项目&#xff0c;想着coding first&#xff0c;我得先跑起来&#xff0c;结果居然卡在依赖上。就像下图&#xff1a; 真的是头疼&#xff0c;反复执行 go mod tidy&#xff0c;发现本地库中也能下…

vue三个点…运算符时报错 Syntax Error: Unexpected token

出现以下问题报错&#xff1a; 解决&#xff1a; 在项目根目录新建一个名为.babelrc的文件 {"presets": ["stage-2"] }

分享一个基于微信小程序开发的高校学生毕业设计选题小程序的源码 lw 调试

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

pyechart练习三:黑色星期五用户画像

一、概述 数据集: 537577行 12列。 二、可视化 1、年龄/性别的各自用户占比 import pandas as pd from pyecharts.charts import Pie, Bar, Grid, Page, Boxplot import pyecharts.options as opts df pd.read_csv(./BlackFridaySales.csv) age_data df[Age].value_count…

简单介绍神经网络中不同优化器的数学原理及使用特性【含规律总结】

当涉及到优化器时&#xff0c;我们通常是在解决一个参数优化问题&#xff0c;也就是寻找能够使损失函数最小化的一组参数。当我们在无脑用adam时&#xff0c;有没有斟酌过用这个是否合适&#xff0c;或者说凭经验能够有目的性换用不同的优化器&#xff1f;是否用其他的优化器可…

41 个下载免费 3D 模型的最佳网站

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 1. Pikbest Pikbest是一个设计资源平台&#xff0c;提供超过3万件创意艺术品。您可以在Pikbest上找到设计模板&#xff0c;演示幻灯片&#xff0c;视频和音乐等。您可以找到不同的3D模型&#xff0c;例如婚礼装饰&…

Anaconda彻底卸载及重安装

一、彻底卸载Anaconda 1.1 先采用anaconda-clean包初步卸载 总体卸载思路&#xff1a;通过下载anaconda-clean包完成初步卸载&#xff0c;但由于在base下若下载anaconda-clean包会一直卡在Solving environment:阶段&#xff0c;因此首先要创建一个虚拟环境。具体步骤如下&…

freeRTOS系列教程之freeRTOS入门与工程实践【文档+视频教程+进阶视频教程】

《freeRTOS入门与工程实践》 前言课程内容授课方式 学前知识普及学前准备硬件准备资料准备 视频教程文档教程更好的阅读体验 前言 课程内容 嵌入式软件工程师的学习路线一般是&#xff1a;单片机->RTOS->Linux。当你掌握单片机开发后&#xff0c;如果要进一步提升编程水…

质数,思维,prime game

Prime Game - Gym 101981J - Virtual Judge (vjudge.net) Problem - 1520 (nefu.edu.cn) 解析&#xff1a; 这道题还是要考虑数的贡献 题解参考至&#xff08;【ACM-ICPC 2018 南京现场赛 】 J.Prime Game ---- 思维素数筛_WangMeow的博客-CSDN博客&#xff09; 第一个元素的…

Windows下使用Nginx反向代理访问MySQL数据库

安装Nginx 《Windows下安装Nginx》 配置13306端口访问3306端口的MySQL数据库 worker_processes 1;events {worker_connections 1024; }stream {upstream mysql {hash $remote_addr consistent;server 127.0.0.1:3306;# MySQL数据库集群#server 192.168.1.111:3306;}server…

领域驱动设计:DDD设计微服务代码模型

文章目录 DDD 分层架构微服务代码模型 只有建立了标准的微服务代码模型和代码规范后&#xff0c;我们才可以将领域对象所对应的代码对象放在合适的软件包的目录结构中。标准的代码模型可以让项目团队成员更好地理解代码&#xff0c;根据代码规范实现团队协作&#xff1b;还可以…

Linux下的编译器使用以及各个阶段的执行

程序的翻译 程序在形成可执行程序之前都经历过一系列十分复杂的过程&#xff0c;也就是我们程序的翻译&#xff0c;程序的翻译经过以下阶段&#xff1a; 预处理&#xff08;进行宏替换) 编译&#xff08;生成汇编) 汇编&#xff08;生成机器可识别代码&#xff09; 连接&#…

Linux--进程间通讯--FIFO(open打开)

1. 什么是FIFO FIFO命名管道&#xff0c;也叫有名管道&#xff0c;来区分管道pipe。管道pipe只能用于有血缘关系的进程间通信&#xff0c;但通过FIFO可以实现不相关的进程之间交换数据。FIFO是Linux基础文件类型中的一种&#xff0c;但是FIFO文件在磁盘上没有数据块&#xff0c…

快递查询、导出表格,批量操作效率更高

当我们需要查询多个快递的状态时&#xff0c;通常会感到繁琐和耗时。然而&#xff0c;现在有一种快捷的方法可以帮助我们快速批量查询快递&#xff0c;而且还可以将查询结果导出成表格&#xff0c;轻松搞定&#xff01; 首先&#xff0c;在浏览器中搜索“固乔科技”&#xff0c…

SSL证书系列--Let’s Encrypt和TrustAsia哪个好?

原文网址&#xff1a;SSL证书系列--Let’s Encrypt和TrustAsia哪个好&#xff1f;_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Let’s Encrypt和TrustAsia这两款免费SSL证书的区别。 Let’s Encrypt 简介 Let’s Encrypt是一家全球性的证书颁发机构&#xff0c;由一个非营利…