ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Web期末课程设计v1.0(五) | 闲优购系统 | 模拟网站埋点实现用户浏览记录的统计与显示

2021-12-24 11:31:51  阅读:203  来源: 互联网

标签:Web 课程设计 闲优购 uid cid 浏览 user import 记录


文章目录

以往课设记录


运行环境


  • windows10
  • IDEA专业版
  • JDK8
  • HTML5、CSS3、JavaScript
  • JQuery
  • Bootstrap5

1. 页面效果展示


1.1 显示当前位置

在这里插入图片描述

1.2 购买商品时候的询问窗口

在这里插入图片描述

确认购买后

在这里插入图片描述

1.3 显示浏览记录

在这里插入图片描述

2. 功能实现

2.1 使用Boostrap5框架的Modal实现确认购买后的弹出的窗口

Bootstrap5 modal 官方文档
在这里插入图片描述
关于modal组件的使用:

  • 一个button按钮组件负责启动一个modal模态框
    在按钮中需要设置这几个参数
参数名称描述
data-bs-toggle=modal用于指定按钮的目标为一个modal模态框
data-bs-target = #…用于指定当前按钮绑定的模态框组件的ID
  • 一个div负责显示modal模态框的内容,模态框所需的参数参考官方代码,除了id外,笔者未作修改

jsp

    <!-- Button trigger modal -->

    <button id="bt-buy" type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop" hidden>
        modal组件
    </button>
    <!-- Modal -->
    <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title text-danger" id="staticBackdropLabel">
                        <i class="bi bi-exclamation-triangle-fill"></i>
                        温馨提示
                    </h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    是否确认购买?
                </div>
                <div class="modal-footer">
                    <button id="btn-buy-cancel" type="button" class="btn btn-danger" data-bs-dismiss="modal">我再想想</button>
                    <button id="btn-buy-ok" type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modal-buy-ok">确认购买</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Modal -->
    <div class="modal fade" id="modal-buy-ok" tabindex="-1" aria-labelledby="modal-h-buy-ok" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title text-danger" id="modal-h-buy-ok">
                        <i class="bi bi-exclamation-triangle-fill"></i>
                        温馨提示
                    </h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <h5 class="display-5 text-success text-center">
                        购买成功!
                        <i class="bi bi-check-circle"></i>
                    </h5>
                </div>
            </div>
        </div>
    </div>

2.2 实现记录浏览记录

2.2.1 存储浏览记录的表、对象

关于数据表的问题,首先用户uid、商品cid必须有外键约束,即需要是用户表和商品表里真实存在的数据,其次是需关联uid、cid这两个属性,为实现浏览记录的覆盖,这两个字段不能重复出现,具体实现可以看之后的SQL语句与dao层代码。

Mysql数据表

create table user_action(
     id int primary key auto_increment,
     uid int not null,
     cid int not null,
     time timestamp(0) null default current_timestamp,
    CONSTRAINT a_cid
    FOREIGN KEY (cid) REFERENCES commodity(id),
    CONSTRAINT a_uid
    FOREIGN KEY (uid) REFERENCES user(id)
) default charset=utf8;
CREATE UNIQUE INDEX index_user_action ON user_action (uid, cid);

在这里插入图片描述
实体类 CommodityRecord.java

package com.uni.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.sql.Timestamp;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class CommodityRecord {
    private int id;
    private User user;
    private Commodity commodity;
    private Timestamp time;
}

2.2.2 浏览记录存储理念——埋点

当用户点击一个商品卡片时,会产生一个浏览记录,于是可以通过JS代码给每个商品卡片绑定一个函数。

当卡片被单击时,JS提交AJAX请求到后端,后端对操作的用户、浏览的商品存储到数据库。

那么怎么获取到请求的用户以及商品呢?

笔者采取的措施是:

  1. 在JSP页面显示商品卡片时候,通过设置data-…属性,来指定当前商品的用户id和商品id。

  2. JS代码获取用户id和商品id ,提交到Servlet,后端根据这两个ID查询到对应的数据,从而插入新的浏览记录到数据库。

不过在保存记录时,会遇到一个问题:

如果用户访问的商品记录是已经存在的,那么该如何处理?

为防止出现重复记录,即用户点击同一商品的记录都出现在数据表,这样就可能会产生许多冗余数据,其实可以给浏览记录数据表添加一个字段,用于表示浏览的次数,默认为1,不过为简化课程设计,笔者就直接采用覆盖式,将其访问时间覆盖,实现的SQL语句:

insert into user_action (uid, cid) values (?, ?) on duplicate key update time=?"

2.2.3 JS埋点

$(document).ready(function (){
    var cid = 0
    var uid = 0
    $(".card-commodity").click(function (){
       cid = $(this).data("cid")
       uid = $(this).data("uid")
        // 埋点记录
        $.ajax({
            url: '/visted?cid=' + cid + "&uid=" + uid,
            type: "GET",
            success: function (data){
            }
        });
           $("#bt-buy").click();
        });
    $(".btn-commodity-type").click(function (){
        window.location.href=$(this).attr("href");
    });
    $("#btn-buy-ok").click(function (){

        // 确认购买后,添加商品订单....
 
    });
});

2.2.4 Servlet 处理埋点请求

Action层

package com.uni.action;

import com.uni.entity.User;
import com.uni.service.Service;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "UserVistedAction", urlPatterns = "/visted")
public class UserVistedAction extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int cid = Integer.parseInt(req.getParameter("cid"));
        int uid = Integer.parseInt(req.getParameter("uid"));
        User user = (User) req.getSession().getAttribute("userInfo");
        // 当用户访问非自己发布商品时,进行埋点记录
        if(user.getId() != uid)
            Service.commodity.insertAction(user.getId(), cid);
        resp.getWriter().write("埋点完毕!");
    }
}

Dao层

public boolean insertAction(int uid, int cid) {
     Connection connection = DruidUtil.getConnection();
     String sql = "insert into user_action (uid, cid) values (?, ?) on duplicate key update time=?";
     boolean ok = false;
     try{
         PreparedStatement pstmt = connection.prepareStatement(sql);
         pstmt.setInt(1, uid);
         pstmt.setInt(2, cid);
         pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
         ok = pstmt.execute();
         DruidUtil.release(connection, pstmt, null);
     } catch (SQLException throwables) {
         throwables.printStackTrace();
     }
     return ok;
 }

2.3.5 JSP页面

<c:forEach items="${sessionScope.commodityInfo}" var="cd">
      <div class="col-3 mb-5">
          <div class="card-commodity" data-uid="${cd.uid}" data-cid="${cd.id}">
              <img src="${cd.img}" class="card-img-top">
              <div class="card-body">

                  <h5 class="card-title text-center">¥${cd.price}</h5>
                  <h6>商品名称: <span>${cd.name}</span></h6>
                  <h6 class="card-text" href="#">商品类型: ${cd.typeName}</h6>
                  <a class="card-text" href="#">商品描述: ${cd.info}</a>
                  <p>商家: <a href="#">${cd.userName}</a></p>
              </div>
          </div>
      </div>
  </c:forEach>

2.3 显示浏览记录


在记录用户浏览记录后,用户在个人信息页面可以查询到自己的浏览记录,和记录类似,同样是操作数据表。
在这里插入图片描述

2.3.1 Servlet层

package com.uni.action;

import com.uni.entity.CommodityRecord;
import com.uni.entity.User;
import com.uni.service.Service;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

@WebServlet(name ="UserHistoryAction", urlPatterns = "/history")
public class UserHistoryAction extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        HttpSession session = req.getSession();
        User user =(User) session.getAttribute("userInfo");
        List<CommodityRecord> commodityRecords = Service.user.queryHistory(user);
        session.setAttribute("commodityRecords", commodityRecords);
        resp.sendRedirect("card_user_info.jsp");
    }
}

2.3.2 JSP页面 JSTL应用

<h3 class="h-title-black">
	<i class="bi bi-clock-history"></i>
	浏览记录 共${sessionScope.commodityRecords.size()}条
	<c:if test="${not empty sessionScope.historyPageNow && sessionScope.commodityRecords.size() > 0}">
		[${sessionScope.historyPageNow},${sessionScope.historyPageNow+1}] 条
	</c:if>
</h3>
<div class="row row-cols-1 row-cols-md-2 g-4">
	<c:set var="pageNow" scope="page" value="${sessionScope.historyPageNow}"></c:set>
	<c:forEach items="${sessionScope.commodityRecords}" begin="${pageNow}" end="${pageNow + 1}" var="cr" varStatus="index">
		<c:if test="${index.index <= sessionScope.commodityRecords.size()}">
			<div class="card-commodity-row">
				<div class="card-commodity" data-uid="${cr.user.id}" data-cid="${cr.commodity.id}">
					<img src="${cr.commodity.img}" class="card-img-top">
					<div class="card-body">
						<h5 class="card-title text-center">¥${cr.commodity.price}</h5>
						<h6>商品名称: <span>${cr.commodity.name}</span></h6>
						<h6 class="card-text" href="#">商品类型: ${cr.commodity.typeName}</h6>
						<a class="card-text" href="#">商品描述: ${cr.commodity.info}</a>
						<p>商家: <a href="#">${cr.user.name}</a></p>
					</div>
					<div class="card-footer">
						<small class="text-muted">上次浏览日期:  ${fn:replace(cr.time, ".0", "")}</small>
					</div>
				</div>
			</div>
		</c:if>
	</c:forEach>
</div>

3. 总结


至此,已完成了浏览信息的记录与显示,接下来的阶段就是商品订单信息的添加,其实在整个过程中,笔者做了许多简化工作,目前发现的最大问题就是dao层冗余代码过多,比如要查询一个商品记录,就需要在dao层接口定义一个新的方法,然后impl类实现,接着service层又要声明一个方法,Impl类调用dao层接口实现类的方法。总的来说比较繁琐…

标签:Web,课程设计,闲优购,uid,cid,浏览,user,import,记录
来源: https://blog.csdn.net/Unirithe/article/details/122121845

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有