4进货+后台事务

一: 添加页面

        1.在列表页面写添加的按钮,跳转添加页面

/*** 给添加按钮绑定一个点击事件*/$("#billsAdd").click(function () {//跳转添加页面location.href="add.jsp";})

        2.添加页面先写,页面布局

                2.① :   页面布局该使用什么标签,用什么标签

                           单号使用 span 标签,

                           下拉框使用 select 标签

单号: <span id="billsCode"></span><br>供应商ID: <select id="supplierId"><option value="">请选择</option></select><br>进货仓库ID: <select id="warehouseId" onchange="getAddr()"><option value="">请选择</option></select><br>联系地址: <span id="warehouseAddr"></span><br><%--隐藏ID--%><input type="hidden" value="${user.userId}" id="userId">采购员: ${user.userName}<br>联系人: <input type="text" id="billsPerson"><br>联系电话: <input type="text" id="billsPho

        3.采购员/制单人使用session取的

<%--隐藏ID--%><input type="hidden" value="${user.userId}" id="userId">采购员: ${user.userName}<br>

        4.要写什么按钮,写什么按钮

<%--新增按钮--%><input type="button" value="新增" id="seek"><%--返回上一个--%><input type="button" value="返回上一页" onclick="history.back()">

       5.随机单号

                5.    ① 先写文档就绪函数
                                // 1. 调用随机数的方法
                                // 2. 调用下拉框的方法
/*** 文档就绪函数*/$(function () {//调用下拉框的方法supplierList()warehouseList()//调用随机数的方法$("#billsCode").html(getNum()).css("color","purple")})
                        ② 定义随机单号的方法
                               //1. 随机数 : Math.floor(Math.random()*(最大值-最小值+1)-最小值)
                                //2. 年月日补0 : month=month<10?'0' +month:month(月份+1)
/*** 随机数*/function getNum() {//获取随机数let number = Math.floor(Math.random()*(99999-10000+1)-10000);//固定格式输出return "E"+number}
/*** 随机单号*/function getBillsNum() {//前缀 JH+年月日随机数let number = Math.floor(Math.random()*(9999-1000-1)+1000);let date = new Date();let fullYear = date.getFullYear();let month = date.getMonth()+1;let day = date.getDate();//补0month=month<10?'0'+month:month;day=day<10?'0'+day:day;let time=`\${fullYear}\${month}\${day}`;//返回随机数return "JH"+time+number}
                        ③ 定义下拉框的方法
                                //1. ajax只有两步 : url datatype
/*** 供应商的下拉框*/function supplierList() {$.ajax({url: "/supplier/supplierList",dataType: "json",success(res) {//打印console.log(res)//循环追加数据for (let x of res) {$("#supplierId").append(`<option value="\${x.supplierId}">\${x.supplierName}</option>`)}},error() {alert("供应商下拉框展示失败")}})
                          //2. 动态下拉框

                                在id的双引号外面 写 data-address(这些写address下面也写address)

/*** 仓库下拉框*/function warehouseList() {$.ajax({url: "/warehouse/warehouseList",dataType: "json",success(res) {//打印console.log(res)//循环追加数据for (let x of res) {$("#warehouseId").append(`<option value="\${x.warehouseId}" data-address="\${x.warehouseAddr}">\${x.warehouseName}</option>`)}},error() {alert("供应商下拉框展示失败")}})}

        7.按钮的下面写小列表(商品表)

                7.① 小列表根据题给的样式写

                        (题上给的购买数量和采购金额是中间表的数据)

<%--商品列表--%><table id="table"><tr><td>商品编码</td><td>商品名称</td><td>型号规格</td><td>单位</td><td>数量</td><td>单价</td><td>购买数量</td><td>采购金额</td></tr></table>

        8.给(查询)按钮绑定一个点击事件(可以开多个脚本)

                6.① 根据题目要求写,比如(根据供应商的查询商品列表)
                6.② 获取供应商的ID
                6.③ 组装对象
                6.④ ajax

                        在ajax的成功回调函数里:

                                //1. 清空表头

                                //2. 追加表头(绑定复选框,value绑商品ID)

                                        给复选框绑定一个改变事件(用来计算最后付钱的商品)

                                //3. 追加表数据

                                //4. 商品表的最后两个数据是中间表的字段

                                        购买数量使用inp标签

                                        购买数量自己算自己的,绑定动态ID,绑定一个改变事件,用来计算购买金额(传3个参数 1.商品ID,购买数量,商品价格)

                                        购买金额使用span标签,绑定动态ID(因为金钱是算法算出来的用户不可更改)

                                //5. 在循环外追加确认按钮(结账按钮)

                                        给确认按钮绑定一个js的事件

$("#seek").click(function () {//取值let supplierId = $("#supplierId").val();//组装let obj={supplierId:supplierId}//ajax$.ajax({url: "/goods/goodsList",type:"post",data:{reqInfos:JSON.stringify(obj)},dataType: "json",success(res) {//打印console.log(res)//清空表$("#table").empty()//追加表头$("#table").append(`<tr><td><input type="checkbox" id="check" onchange="getNumMoney()"></td><td>商品编码</td><td>商品名称</td><td>型号规格</td><td>单位</td><td>数量</td><td>单价</td><td>购买数量</td><td>采购金额</td></tr>`)//追加表数据for (let x of res) {$("#table").append(`<tr><!--5个商品,结账时只要两个,获取选中的复选框的值--><td><input type="checkbox" class="ck" value="\${x.goodsId}" onchange="getNumMoney()"></td><td>\${x.goodsCode}</td><td>\${x.goodsName}</td><td>\${x.goodsModel}</td><td>\${x.goodsDept}</td><td>\${x.goodsNum}</td><td>\${x.goodsPrice}</td><td><!--购买数量 绑定动态ID, 绑定改变事件,进货3个参(主键ID,价格,数量)--><input type="text" id="gbNum\${x.goodsId}" onchange="getMoney(\${x.g0oodsId},this,\${x.goodsPrice})"></td><td><!--中间表的采购金额--><span id="gbOutlay\${x.goodsId}"></span></td></tr>`)}/*** “确认”按钮*/$("#table").append(`<tr><td colspan="100"><input type="button" value="确认" onclick="surePay()"></td></tr>`)},error() {alert("商品列表展示失败")}})})

        9.全选/全不选按钮

/*** 全选/全不选*/$(document).on("click","#check",function () {$(".ck").prop("checked",this.checked)})

        10.动态地址的2行代码

/*** 仓库动态地址*/function getAddr() {//取值let addr = $("#warehouseId option:selected").data("address")//取页面布局的详细字段 把取到的动态地址给这个字段,用spqn标签展示出来$("#warehouseAddr").html(addr).css("color","purple")}

        11.购买金额的计算

                11① : 在小列表里给中间表的字段(购买数量)绑定了改变事件,计算这个
                11② : (传3个参数 : 商品ID,购买数量,商品价格)
                11③ :  取值 : 取中间表数量的字段 上面用 this 代替传参了,取值的不用"#",直接取 
                11④ : 对购买数量判断,不能<=0 , 输入错误强制清空,return结束
                11⑤ : 购买的金额=购买数量*商品价格
                11⑥ : 算出来的钱,给购买金额(中间表的字段)用,小列表里的金额用span标签,用html显示
                11⑦ : 调用计算总额的方法
/***购买金额计算*/function getMoney(goodsId, gbNum, goodsPrice) {//取数量值let n = $(gbNum).val();//判断if (n<=0){alert("购买数量有误,重新输出")//强制清空$(gbNum).val("")//结束return}//购买金额 单价*数量let sum=n*goodsPrice//赋值 给购买金额赋值(中间表的购买金额)$("#gbOutlay"+goodsId).html(sum)//调用计算总额的方法getNumMoney()}

        12.总额计算方法

                12.① 这个计算方法 : 比如5个商品,结账的时候只要3个,支付这3个的钱
                12.② 定义sum=0;
                12.③ 获取选中的复选框(复选框的value绑定了商品id,取值时用this,返回值写商品ID就可以了)
                12.④ 获取选中的复选框的值(获取当前的复选框的值,小列表给的是span标签,用html展示)+动态id
                12.⑤ 对当前选中的复选框的钱数做累计计算
                12.⑥ 给页面布局里的总金额用span标签展示出来

/*** 总额计算*/function getNumMoney() {let sum=0;//获取选中的复选框的$(".ck:checked").each(function () {//商品ID的值let goodsId = $(this).val();//获取当前选中的复选框的值let gbOutlay = $("#gbOutlay"+goodsId).html();//累计求和sum+= +gbOutlay;//总额赋值$("#billsAmount").html(sum).css("color","purple")})}

        13.确认按钮(一对多的添加)

                13.①创建数组
                13.②取单据表的数据(页面布局的字段)
                13.③判空
                13.④取中间表的字段        
                        //1.获取复选框的值
                        //2.获取选中的复选框的值
                        //3.获取购买数量的值(小列表里中间表的购买数量的值)
                        //4.获取购买金额的值(小列表里中间表的购买金额的值)
                        //5.组装对象(3个字段 商品ID(复选框回值回出来的商品ID,购买数量,购买金额))
                        //6.添加进数组里
                        //7.1对多的数据组装(+上数组,和单据表里的数组相互对应)

                13.⑤添加的ajax 
 /*** 1对多的添加  确认按钮*/function surePay() {//创建数组let arr=[]//取值 单据表取值let billsCode = $("#billsCode").html()let supplierId = $("#supplierId").val()let warehouseId = $("#warehouseId").val()let warehouseAddr = $("#warehouseAddr").html()let userId = $("#userId").val()let billsPerson = $("#billsPerson").val()let billsPhone = $("#billsPhone").val()let billsAmount = $("#billsAmount").html()//判空if (!billsCode ||!supplierId ||!warehouseId ||!warehouseAddr ||!userId ||!billsPerson ||!billsPhone ||!billsAmount){alert("请先输入")}//中间表(结账是结选中的要买单的商品)$(".ck:checked").each(function () {//获取选中的复选框的值let goodsId = $(this).val();//购买金额  中间表的购买金额let gbNum = $("#gbNum"+goodsId).val();//购买数量let gbOutlay = $("#gbOutlay"+goodsId).html();//组装中间表的对象 (3个字段 :  商品id,购买金额,购买数量)let a={goodsId:goodsId,gbOutlay:gbOutlay,gbNum:gbNum}//添加进数组里arr.push(a)})//1对多的数据组装let obj={billsCode:billsCode,supplierId:supplierId,warehouseId:warehouseId,warehouseAddr:warehouseAddr,userId:userId,billsPerson:billsPerson,billsPhone:billsPhone,billsAmount:billsAmount,arr:arr}//添加的ajax$.ajax({url: "/bills/billsListAdd",type: "post",data: {reqInfos:JSON.stringify(obj)},dataType: "json",success(res) {console.log(res)if (res===200){alert("单据表添加成功")location.href="list.jsp"}},error() {alert("单据表添加失败")}})}

Controller层

和正常的添加Controller一样

 /*** 添加* @param req* @param resp* @throws ServletException* @throws IOException*/protected void billsListAdd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//接参String reqInfos = req.getParameter("reqInfos");//将json对象转换成java对象BillsVo billsVo = JSONObject.parseObject(reqInfos, BillsVo.class);//将转化后的对象传给serviceservice.billsListAdd(billsVo);//将处理后的结果响应给用户resp.getWriter().println(JSONObject.toJSONString(200));}

service层

        1.获取连接

        2.关闭连接

        3.捕获异常

        4.关闭自动提交,开启手动提交

        5.在finally里  //恢复自动提交   //关闭连接

        6.给单据表添加一条事务,(单据表的所有字段)

        7.获取单据表里创建的集合

        8.遍历集合

        9.在集合里面给中间表添加一条数据(参数 : 事务,中间表的所有字段)

               (单据表添加一条数据,回值回的是单据表的ID,中间表添加数据时,直接写回值的单据ID就可以了)

        10.跟新库存数量(参数是 : //事务  //中间表里商品ID  //中间表的数量)

        11.提交事务

        12.catch里回滚事务 +打印异常

/*** 添加* @param billsVo*/@SneakyThrows@Overridepublic void billsListAdd(BillsVo billsVo) {Connection conn = null;try {//获取连接conn = JDBCUtil.getConn();//关闭自动提交,开启手动提交conn.setAutoCommit(false);//给单据表添加一条事务,把事务传过去,获取ID,int billsId = billsDao.billsListAdd(conn,billsVo);//获取单表的集合ArrayList<GoodsBills> arr = billsVo.getArr();//遍历for (GoodsBills goodsBills : arr) {//(添加中间表的所有字段)billsDao.addGoodsBills(conn,goodsBills.getGoodsId(),billsId,goodsBills.getGbNum(),goodsBills.getGbOutlay());//跟新库存数量  //修改商品表(参数是 中间表里的商品ID和商品的数量 通过商品ID修改商品数量)billsDao.updGoods(conn,goodsBills.getGoodsId(),goodsBills.getGbNum());}//提交事务conn.commit();} catch (Exception e) {//回滚conn.rollback();//打印异常e.printStackTrace();} finally {//恢自动提交conn.setAutoCommit(true);//关闭连接conn.close();}}

dao层

        1.给单据表添加一条数据

                (就是正常的添加sql,执行sql是baseInserWithId,传事务,传sql,传单据表的ID(从service传过来的),添加的字段)

/*** 单据表添加一条数据* @param conn* @param billsVo* @return*/@Overridepublic int billsListAdd(Connection conn, BillsVo billsVo) {//定义sqlString sql="INSERT INTO t_bills(" +"bills_code," +"supplier_id," +"warehouse_id," +"warehouse_addr," +"user_id," +"bills_person," +"bills_phone," +"bills_amount," +"bills_del" +")VALUES(?,?,?,?,?,?,?,?,?)";//打印sqlSystem.out.println(sql);//执行sqlreturn baseInsertWithId(conn,sql,"bills_id",billsVo.getBillsCode(),billsVo.getSupplierId(),billsVo.getWarehouseId(),billsVo.getWarehouseAddr(),billsVo.getUserId(),billsVo.getBillsPerson(),billsVo.getBillsPhone(),billsVo.getBillsAmount(),billsVo.getBillsDel());}

        2.给中间表添加一条数据

                正常的添加(添加中间表的所有字段)

/*** 中间表添加一条数据* @param conn* @param goodsId* @param billsId* @param gbNum* @param gbOutlay*/@Overridepublic void addGoodsBills(Connection conn, Integer goodsId, int billsId, Integer gbNum, BigDecimal gbOutlay) {//定义sqlString sql="INSERT INTO t_goods_bills(goods_id,bills_id,gb_num,gb_outlay)VALUES(?,?,?,?)\n";//打印sqlSystem.out.println(sql);//执行sqlbaseUpdate(conn,sql,goodsId,billsId,gbNum,gbOutlay);}

        3.更新库存数量

                正常的修改语句(修改的是商品表的数量,进货是+,退货是- 修改语句不要忘记 where id=?)

/*** 更新库存* @param conn* @param goodsId* @param gbNum*/@Overridepublic void updGoods(Connection conn, Integer goodsId, Integer gbNum) {//定义sqlString sql=" UPDATE t_goods SET goods_num=goods_num+? where goods_id=? ";//打印sqlSystem.out.println(sql);//执行sqlbaseUpdate(conn,sql,gbNum,goodsId);}

                

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

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

相关文章

Nginx代理本地exe服务http为https

Nginx代理本地exe服务http为https 下载NginxNginx命令exe服务http代理为https 下载Nginx 点击下载Nginx 下载好之后是一个压缩包&#xff0c;解压放到没有中文的路径下就可以了 Nginx命令 调出cmd窗口cd到安装路径 输入&#xff1a;nginx -v 查看版本 nginx -h&#xff…

cursor 使用技巧

一、创建项目前期步骤 1.先给AI设定一个对应项目经理角色&#xff0c; 2.然后跟AI沟通项目功能&#xff0c;生成功能设计文件&#xff1a;README.md README.md项目功能 3.再让AI总结写出开发项目规则文件&#xff1a; .cursorrules 是技术栈进行限定&#xff0c;比如使用什…

创建并配置华为云虚拟私有云

目录 私有云 创建虚拟私有云 私有云 私有云是一种云计算模式&#xff0c;它将云服务部署在企业或组织内部的私有基础设施上&#xff0c;仅供该企业或组织内部使用&#xff0c;不对外提供服务.私有云的主要特点包括&#xff1a; 私密性&#xff1a;私有云的资源&#xff08;如…

【数据结构-堆】力扣2530. 执行 K 次操作后的最大分数

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。你的 起始分数 为 0 。 在一步 操作 中&#xff1a; 选出一个满足 0 < i < nums.length 的下标 i &#xff0c; 将你的 分数 增加 nums[i] &#xff0c;并且 将 nums[i] 替换为 ceil(nums[i] / 3) 。 返回在 恰好…

【SpringBoot】当 @PathVariable 遇到 /,如何处理

1. 问题复现 在解析一个 URL 时&#xff0c;我们经常会使用 PathVariable 这个注解。例如我们会经常见到如下风格的代码&#xff1a; RestController Slf4j public class HelloWorldController {RequestMapping(path "/hi1/{name}", method RequestMethod.GET)publ…

【跟着官网学技术系列之MySQL】第2天之MySQL版本:创新和 LTS

前言 在当今信息爆炸的时代&#xff0c;拥有信息检索的能力很重要。 作为一名软件工程师&#xff0c;遇到问题&#xff0c;你会怎么办&#xff1f;带着问题去搜索引擎寻找答案&#xff1f;亦或是去技术官网&#xff0c;技术社区去寻找&#xff1f; 根据个人经验&#xff0c;一…

开源存储详解-分布式存储与ceph

ceph体系结构 rados&#xff1a;reliable, autonomous, distributed object storage, rados rados采用c开发 对象存储 ceph严格意义讲只提供对象存储能力&#xff0c;ceph的块存储能力实际是基于对象存储库librados的rbd 对象存储特点 对象存储采用put/get/delete&#xf…

操作系统大题整理

专题一 程序代码题&#xff1a;程序设计与分析&#xff0c;主要考的是线程&#xff0c;多线程的并发&#xff1f; 大题第一问&#xff08;1&#xff09;操作系统的结构有哪几种常用的结构&#xff1f; 宏内核&#xff1a;宏内核是将操作系统的主要功能模块都集中在内核的一种结…

设计模式学习[14]---状态模式

文章目录 前言1.原理阐述2.引例3.状态模式对象化4.状态模式优化 总结 前言 状态模式&#xff0c;乍一听名字其实好像很好理解的样子&#xff0c;状态嘛&#xff0c;人在不同状态会有不同的行为模式。那软件的状态模式又是什么样子的&#xff1f;根据一个变量的值&#xff0c;执…

【.NET】Kafka消息队列介绍,使用Confluent.Kafka集成Kafka消息队列

一、Kafka介绍 kafka是一种高吞吐量、分布式、可扩展的消息中间件系统&#xff0c;最初由LinkedIn公司开发。随着不断的发展&#xff0c;在最新的版本中它定义为分布式的流处理平台&#xff0c;现在在大数据应用中也是十分广泛。 它可以处理大量的实时数据流&#xff0c;被广…

基于ESP32的桌面小屏幕实战[5]:PCB下单

1. 焊接调试前准备 PCB下单 点击“PCB下单” 检查一下DRC 确认无错误之后&#xff0c;确认下单 然后就会跳转到下面的网页 基本上保持默认选项即可。可以看到“焊盘喷镀”有3个选项。 在选择表面处理工艺时&#xff0c;应综合考虑产品的具体需求、环保法规以及成本等因素。例…

下载b站高清视频

需要使用的edge上的一个扩展插件&#xff0c;所以选择使用edge浏览器。 1、在edge浏览器上下载 强力视频下载合并 扩展插件 2、在edge上打开b站&#xff0c;登录自己账号&#xff08;登录后才能下载到高清&#xff01;&#xff01;&#xff09;。打开一个视频&#xff0c;选择自…

【蓝桥杯研究生组】第14届Java试题答案整理

试题链接&#xff1a;链接 A题 满足条件的答案有&#xff1a;35813116 public class TianShu {public static void main(String[] args) {int ans 0;// 2000.1.1 - 2000000.1.1// 年份是月份的倍数&#xff0c;也是日的倍数for (int year2000; year<2000000; year) {for …

从0到机器视觉工程师(二):封装调用静态库和动态库

目录 静态库 编写静态库 使用静态库 方案一 方案二 动态库 编写动态库 使用动态库 方案一 方案二 方案三 总结 静态库 静态库是在编译时将库的代码合并到最终可执行程序中的库。静态库的优势是在编译时将所有代码包含在程序中&#xff0c;可以使程序独立运行&…

【LeetCode Hot100 二分查找】搜索插入位置、搜索二维矩阵、搜索旋转排序数组、寻找两个正序数组的中位数

二分查找 搜索插入位置搜索二维矩阵在排序数组中查找元素的第一个和最后一个位置寻找旋转排序数组中的最小值搜索旋转排序数组寻找两个正序数组的中位数&#xff08;hard&#xff09; 搜索插入位置 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并…

你已经分清JAVA中JVM、JDK与JRE的作用和关系了吗?

你已经分清JAVA中JVM、JDK与JRE的作用和关系了吗&#xff1f; 一. JVM、JDK与JRE的关系二. JVM、JDK与JRE的作用2.1 什么是JVM&#xff1f;2.2 什么是JDK&#xff1f;2.3 什么是JRE&#xff1f; 前言 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有…

在不到 5 分钟的时间内将威胁情报 PDF 添加为 AI 助手的自定义知识

作者&#xff1a;来自 Elastic jamesspi 安全运营团队通常会维护威胁情报报告的存储库&#xff0c;这些报告包含由报告提供商生成的大量知识。然而&#xff0c;挑战在于&#xff0c;这些报告的内容通常以 PDF 格式存在&#xff0c;使得在处理安全事件或调查时难以检索和引用相关…

数据挖掘——朴素贝叶斯分类

数据挖掘——朴素贝叶斯分类 朴素贝叶斯分类极大后验假设独立性假设贝叶斯分类器总结 朴素贝叶斯分类 什么是分类&#xff1f; 找出描述和区分数据类或概念的模型&#xff0c;以便能够使用模型预测未知的对象的类标号 概念区分 分类与回归 分类是预测分类&#xff08;离散、…

LabVIEW在反馈控制时如何解决带约束的控制问题

在LabVIEW中&#xff0c;解决带约束的反馈控制问题通常需要使用先进的控制算法或特定的方法来满足约束条件&#xff0c;同时保证控制系统的性能和稳定性。以下是解决这类问题的一些常用方法和步骤&#xff1a; ​ 1. 定义控制问题及约束条件 确定被控对象的动态特性&#xff08…

机器人对物体重定向操作的发展简述

物体重定向操作的发展简述 前言1、手内重定向和外部重定向2、重定向原语3、重定向状态转换网络4、连续任意姿态的重定向5、利用其他环境约束重定向总结Reference 前言 对于一些特殊的任务&#xff08;如装配和打包&#xff09;&#xff0c;对物体放置的位姿由明确的要求&#…