4进货+后台事务

news2025/1/7 18:21:33

一: 添加页面

        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();
            //补0
            month=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);
        //将转化后的对象传给service
        service.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
    @Override
    public 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
     */
    @Override
    public int billsListAdd(Connection conn, BillsVo billsVo) {
        //定义sql
        String sql="INSERT INTO t_bills(" +
                "bills_code," +
                "supplier_id," +
                "warehouse_id," +
                "warehouse_addr," +
                "user_id," +
                "bills_person," +
                "bills_phone," +
                "bills_amount," +
                "bills_del" +
                ")VALUES(?,?,?,?,?,?,?,?,?)";
        //打印sql
        System.out.println(sql);
        //执行sql
        return 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
     */
    @Override
    public void addGoodsBills(Connection conn, Integer goodsId, int billsId, Integer gbNum, BigDecimal gbOutlay) {
        //定义sql
        String sql="INSERT INTO t_goods_bills(goods_id,bills_id,gb_num,gb_outlay)VALUES(?,?,?,?)\n";
        //打印sql
        System.out.println(sql);
        //执行sql
        baseUpdate(conn,sql,goodsId,billsId,gbNum,gbOutlay);
    }

        3.更新库存数量

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

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

                

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

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

相关文章

xinput1_3.dll丢失修复方法。方法1-方法6

总结 xinput1_3.dll的核心作用 xinput1_3.dll作为Microsoft DirectX库的关键组件&#xff0c;对于游戏控制器的支持起着至关重要的作用。它不仅提供了设备兼容性、多控制器管理和反馈机制等核心功能&#xff0c;还通过XInput API简化了开发人员对控制器状态的检索和设备特性的…

【C++】P2550 [AHOI2001] 彩票摇奖

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式&#xff1a;输出格式&#xff1a;输入输出样例&#xff1a; &#x1f4af;题解思路1. 问题解析 &#x1f4af;我的实现实现逻辑问题分析 &#x1f4af;老…

01:C语言的本质

C语言的本质 1、ARM架构与汇编2、局部变量初始化与空间分配2.1、局部变量的初始化2.1、局部变量数组初始化 3、全局变量/静态变量初始化化与空间分配4、堆空间 1、ARM架构与汇编 ARM简要架构如下&#xff1a;CPU&#xff0c;ARM(能读能写)&#xff0c;Flash&#xff08;能读&a…

8086汇编(16位汇编)学习笔记10.寄存器总结

8086汇编(16位汇编)学习笔记10.寄存器总结-C/C基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net 寄存器 8086CPU有14个寄存器 它们的名称为&#xff1a; AX、BX、CX、DX、SI、DI、SP、BP、 IP**、CS、DS、ES、**SS、PSW。 8086CPU所有的寄存器都是16位的&#…

如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库教程

简介 本教程将向你介绍如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库。 Apache Cassandra 是一个分布式的 NoSQL 数据库&#xff0c;旨在处理跨多个普通服务器的大量数据&#xff0c;并提供高可用性&#xff0c;没有单点故障。Apache Cassandra 是一个高度可扩展的分布…

uni-app:实现普通选择器,时间选择器,日期选择器,多列选择器

效果 选择前效果 1、时间选择器 2、日期选择器 3、普通选择器 4、多列选择器 选择后效果 代码 <template><!-- 时间选择器 --><view class"line"><view classitem1><view classleft>时间</view><view class"right&quo…

centos,789使用mamba快速安装R及语言包devtools

如何进入R语言运行环境请参考&#xff1a;Centos7_miniconda_devtools安装_R语言入门之R包的安装_r语言devtools包怎么安装-CSDN博客 在R里面使用安装devtools经常遇到依赖问题&#xff0c;排除过程过于费时&#xff0c;使用conda安装包等待时间长等。下面演示centos,789都是一…

STM32第十一课:STM32-基于标准库的42步进电机的简单IO控制(附电机教程,看到即赚到)

一&#xff1a;步进电机简介 步进电机又称为脉冲电机&#xff0c;简而言之&#xff0c;就是一步一步前进的电机。基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩&#xff0c;步进电机的角位移量与输入的脉冲个数严格成正…

kafka使用以及基于zookeeper集群搭建集群环境

一、环境介绍 zookeeper下载地址&#xff1a;https://zookeeper.apache.org/releases.html kafka下载地址&#xff1a;https://kafka.apache.org/downloads 192.168.142.129 apache-zookeeper-3.8.4-bin.tar.gz kafka_2.13-3.6.0.tgz 192.168.142.130 apache-zookee…

JSON结构快捷转XML结构API集成指南

JSON结构快捷转XML结构API集成指南 引言 在当今的软件开发世界中&#xff0c;数据交换格式的选择对于系统的互操作性和效率至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是两种广泛使用的数据表…

Android14 CTS-R6和GTS-12-R2不能同时测试的解决方法

背景 Android14 CTS r6和GTS 12-r1之后&#xff0c;tf-console默认会带起OLC Server&#xff0c;看起来olc server可能是想适配ATS(android-test-station)&#xff0c;一种网页版可视化、可配置的跑XTS的方式。这种网页版ATS对测试人员是比较友好的&#xff0c;网页上简单配置下…

BurpSuite工具安装

BurpSuite介绍&#xff1a; BurpSuite是由PortSwigger开发的一款集成化的Web应用安全检测工具&#xff0c;广泛应用于Web应用的漏洞扫描和攻击模拟&#xff0c;主要用于抓包该包(消息拦截与构造) 一、Burp suite安装 windows系统需要提前配置好java环境&#xff0c;前面博客…

Win11+WLS Ubuntu 鸿蒙开发环境搭建(一)

参考文章 Windows11安装linux子系统 WSL子系统迁移、备份与导入全攻略 如何扩展 WSL 2 虚拟硬盘的大小 Win10安装的WSL子系统占用磁盘空间过大如何释放 《Ubuntu — 调整文件系统大小命令resize2fs》 penHarmony南向开发笔记&#xff08;一&#xff09;开发环境搭建 一&a…

flink cdc oceanbase(binlog模式)

接上文&#xff1a;一文说清flink从编码到部署上线 环境&#xff1a;①操作系统&#xff1a;阿里龙蜥 7.9&#xff08;平替CentOS7.9&#xff09;&#xff1b;②CPU&#xff1a;x86&#xff1b;③用户&#xff1a;root。 预研初衷&#xff1a;现在很多项目有国产化的要求&#…

和为0的四元组-蛮力枚举(C语言实现)

目录 一、问题描述 二、蛮力枚举思路 1.初始化&#xff1a; 2.遍历所有可能的四元组&#xff1a; 3.检查和&#xff1a; 4.避免重复&#xff1a; 5.更新计数器&#xff1a; 三、代码实现 四、运行结果 五、 算法复杂度分析 一、问题描述 给定一个整数数组 nums&…

某xx到家app逆向

去官网下载app即可 https://www.dongjiaotn.com/#/home查壳 360的壳子 直接脱壳即可 抓包 请求地址 https://api.gateway.znjztfn.cn/server/user/index 请求参数 {"lng": "xxxx","lat": "xxxx","city_id": "1376&…

docker搭建gitlab和jenkins

搭建gitlab 搭建gitlab首先需要一个gitlab的镜像 其次最好为他设置一个单独的目录 然后编写一个docker-compose文件 version: 3.1 services:gitlab:image: gitlab_zh:latest //此处为你的镜像名称container_name: gitlab //容器名称restart: always …

嵌入式linux中socket控制与实现

一、概述 1、首先网络,一看到这个词,我们就会想到IP地址和端口号,那IP地址和端口各有什么作用呢? (1)IP地址如身份证一样,是标识的电脑的,一台电脑只有一个IP地址。 (2)端口提供了一种访问通道,服务器一般都是通过知名端口号来识别某个服务。例如,对于每个TCP/IP实…

推荐系统重排:MMR 多样性算法

和谐共存&#xff1a;相关性与多样性在MMR中共舞 推荐系统【多样性算法】系列文章&#xff08;置顶&#xff09; 1.推荐系统重排&#xff1a;MMR 多样性算法 2.推荐系统重排&#xff1a;DPP 多样性算法 引言 在信息检索和推荐系统中&#xff0c;提供既与用户查询高度相关的文…

概述(讲讲python基本语法和第三方库)

我是北子&#xff0c;这是我自己写的python教程&#xff0c;主要是记录自己的学习成果方便自己日后复习&#xff0c; 我先学了C/C&#xff0c;所以这套教程中可能会将很多概念和C/C去对比&#xff0c;所以该教程大概不适合零基础的人。 it seems that python nowadays 只在人工…