【项目】【抽奖系统】活动列表展示

目录

  • 一、简介
  • 二、参数列表
  • 三、接口规范
  • [四、Controller 层](#四、Controller 层)
    • [4.1 FindActivityListResult:Controller层返回值](#4.1 FindActivityListResult:Controller层返回值)
    • [4.2 convertTOFindActivityListResult:将service返回值转换为Controller层](#4.2 convertTOFindActivityListResult:将service返回值转换为Controller层)
    • [4.3 新增错误码](#4.3 新增错误码)
  • 五、service层
    • [5.1 创建接口](#5.1 创建接口)
    • [5.2 实现接口](#5.2 实现接口)
    • [5.3 service层返回数据](#5.3 service层返回数据)
  • 六、dao层
  • 七、测试
  • 八、前端

一、简介

时序图:

二、参数列表

参数名 描述 类型 默认值 条件
currentPage 当前页数 Integer 非必须
pageSize 一页数据数量 Integer 非必须

三、接口规范

java 复制代码
[请求] /activity/find-list?currentPage=1&pageSize=10 GET
[响应] 
{
 "code": 200,
"data": {
	 "total": 10,
		 "records": [
			 {
				 "activityId": 23,
				 "activityName": "抽奖测试",
				 "description": "年会抽奖活动",
				 "valid": true
			 },
			 {
				 "activityId": 22,
				 "activityName": "抽奖测试",
				 "description": "年会抽奖活动",
				 "valid": true
			 },
			 {
				  "activityId": 21,
				 "activityName": "节⽇抽奖",
				 "description": "⽐特年会抽奖活动",
				 "valid": true
			 }
		 ]
	 },
 "msg": ""
}

四、Controller 层

com/yj/lottery_system/controller 包下 ActivityController类中:

  • 调用前面奖品列表展示的PageParam 分页查询的参数,作为参数
  • 调用service层,
  • convertTOFindActivityListResult:将service返回值转换为Controller层
  • 返回
java 复制代码
    @RequestMapping(" /activity/find-list")
    public CommonResult<FindActivityListResult> findActivityList(PageParam param) {
        //日志打印
        log.info("findActivityList PageParam: {}", JacksonUtil.writeValueAsString(param));
        //调用service服务
        return CommonResult.success(convertTOFindActivityListResult( activityService.findActivityList(param)));
    }

4.1 FindActivityListResult:Controller层返回值

com.yj.lottery_system.controller.result 包下:

  • 根据接口规范中的响应数据返回:activityId,activityName,description,valid四个属性
java 复制代码
package com.yj.lottery_system.controller.result;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class FindActivityListResult implements Serializable {
    //活动总数
    private Integer total;
    //当前页活动列表
    private List<FindActivityListResult.ActivityInfo> records;
    @Data
    public static class  ActivityInfo implements Serializable {
        //活动id
        private Long activityId;

        //活动名
        private String activityName;

        //活动描述
        private String description;

        //活动是否结束
        private Boolean valid;


    }
}

4.2 convertTOFindActivityListResult:将service返回值转换为Controller层

com/yj/lottery_system/controller 包下 ActivityController类中:

  • 非空判断
  • 将service层返回值一一赋值给Controller层返回数据
java 复制代码
private FindActivityListResult convertTOFindActivityListResult(PageListDTO<ActivityDTO> activityList) {
        if(null == activityList) {
            throw new ControllerException(ControllerErrorCodeConstants.FIND_ACTIVITY_LIST_ERROR);
        }
        FindActivityListResult findActivityListResult = new FindActivityListResult();
        findActivityListResult.setTotal(activityList.getTotal());
        findActivityListResult.setRecords(activityList.getRecords().stream()
                .map( activityDTO -> {
                    FindActivityListResult.ActivityInfo activityInfo = new FindActivityListResult.ActivityInfo();
                    activityInfo.setActivityId(activityDTO.getActivityId());
                    activityInfo.setActivityName(activityDTO.getActivityName());
                    activityInfo.setDescription(activityDTO.getDescription());
                    activityInfo.setValid(activityDTO.valid());
                    return activityInfo;
                }).collect(Collectors.toList())
        );
        return findActivityListResult;
    }

4.3 新增错误码

com/yj/lottery_system/common/errorcode 包下:ControllerErrorCodeConstants类中:

java 复制代码
    ErrorCode FIND_ACTIVITY_LIST_ERROR = new ErrorCode(301,"查询活动列表失败");

五、service层

5.1 创建接口

com/yj/lottery_system/service 包下:IActivityService接口类中:

java 复制代码
    /**
     * 分页获取活动列表
     * @param param
     * @return
     */
    PageListDTO<ActivityDTO> findActivityList(PageParam param);

5.2 实现接口

com/yj/lottery_system/service/impl 包下 ActivityServiceImpl类中:

  • 调用dao获取活动总数
  • 调用dao获取当前页活动列表
  • 将dao层返回数据,一一赋值给service返回数据
  • 返回
java 复制代码
    /**
     * 分页获取活动基本信息列表
     * @param param
     * @return
     */
    @Override
    public PageListDTO<ActivityDTO> findActivityList(PageParam param) {
        //获取总量
        int total = activityMapper.count();
        //获取当前页活动列表
        int offset = (param.getCurrentPage() - 1) * param.getPageSize();
        List<ActivityDO> activityDOList = activityMapper.selectActivityList(offset,param.getPageSize());
        List<ActivityDTO> activityDTOList = activityDOList.stream()
                .map(activityDO -> {
                    ActivityDTO activityDTO = new ActivityDTO();
                    activityDTO.setActivityId(activityDO.getId());
                    activityDTO.setActivityName(activityDO.getActivityName());
                    activityDTO.setDescription(activityDO.getDescription());
                    activityDTO.setStatus(ActivityStatusEnum.forName(activityDO.getStatus()));

                    return activityDTO;
                }).collect(Collectors.toList());
        
        return new PageListDTO<>(total,activityDTOList);
    }

5.3 service层返回数据

com.yj.lottery_system.service.dto包下:

  • 根据返回值,设置四个属性
  • 并且与controller层对应,提供判断活动状态的 valid 方法。
java 复制代码
package com.yj.lottery_system.service.dto;

import com.yj.lottery_system.service.enums.ActivityStatusEnum;
import lombok.Data;

import java.io.Serializable;
@Data
public class ActivityDTO implements Serializable {
    //活动id
    private Long activityId;

    //活动名
    private String activityName;

    //活动描述
    private String description;

    //活动状态
    private ActivityStatusEnum status;

    //活动是否结束
    public Boolean valid() {
        return status.equals(ActivityStatusEnum.RUNNING);
    }
}

六、dao层

com/yj/lottery_system/dao/mapper 包下 ActivityMapper:

java 复制代码
    /**
     * 查询活动总数
     * @return
     */
    @Select("select count(1) from activity")
    int count();

    /**
     * 查询当前页面的奖品列表
     * @param offset
     * @param pageSize
     * @return
     */
    @Select("select * from activity order by id desc limit ${offset}, #{pageSize}")
    List<ActivityDO> selectActivityList(@Param("offset") Integer offset,
                                        @Param("pageSize") Integer pageSize);

七、测试

八、前端

static/activities-list.html:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>活动列表</title>
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/bootstrap/4.5.2/css/bootstrap.min.css">
  <link rel="stylesheet" href="./css/base.css">
  <style>
    body {
      font-family: Arial, sans-serif;
      background-color: #f2f2f2;
    }
    .activity-list {
      padding:0 30px;
    }
    #activities{
      height: calc(100vh - 134px);
      overflow-y: auto;
      padding-right: 10px;
    }
    .activity-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      background-color: #f7f7f7;
      padding: 24px;
      border-radius: 4px;
      overflow: hidden;
      margin-bottom: 10px;
      border-radius: 8px;
      padding-bottom: 12px;
    }
    .activity-info{
      width: calc(100% - 120px);
    }
    .activity-info h4{
      width: 100%;
      font-weight: 600;
      font-size: 15px;
      color: #000000;
      margin-bottom: 4px;
    }
    .activity-info p{
      font-weight: 400;
      font-size: 14px;
      color: #666666;
      margin: 0;
      line-height: 28px;
    }
    .active a{
      font-weight: 400;
      font-size: 15px;
      color: red;
      margin-bottom: 0;
      display: block;
      width: 250px;
    }
    .inactive a{
      font-weight: 400;
      font-size: 15px;
      color: gray;
      margin-bottom: 0;
      display: block;
      width: 250px;
    }
    .pagination {
      display: flex;
      justify-content: flex-end;
      margin-top: 18px;
      padding-right: 16px;
    }
    .pagination button {
      margin: 0 5px; /* 按钮之间的间距保持不变 */
      border-radius: 5px; /* 设置圆角为20像素,可以根据需要调整 */
      border: 1px solid #007bff;
      background-color: #fff;
      padding: 0px 8px; /* 可以添加一些内边距,使按钮看起来更饱满 */
      cursor: pointer; /* 将鼠标光标改为指针形状,提升用户体验 */
      font-size: 13px;
    }
    .pagination span{
      margin: 0 10px;
      font-size: 14px;
    }
    .pagination input{
      width: 80px;
      text-align: center;
    }
    .activity-list h2 {
      font-weight: 600;
      font-size: 18px;
      color: #000000;
      height: 70px;
      display: flex;
      align-items: center;
      margin-bottom: 0;
    }
  </style>
</head>
<body style="background-color: white">
<div class="activity-list">
  <h2>活动列表</h2>
  <div id="activities">
    <!-- 活动列表将动态插入这里 -->
  </div>
  <div class="pagination">
    <button class="btn-outline-primary" onclick="fetchActivities(1)">首页</button>
    <button class="btn-outline-primary" onclick="previousPage()">上一页</button>
    <span>第 <input type="number" id="pageInput" min="1" value="1" /> 页</span>
    <button class="btn-outline-primary" onclick="nextPage()">下一页</button>
    <button class="btn-outline-primary" onclick="fetchActivities(totalPages)">尾页</button>
  </div>
</div>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="./js/toastr.min.js"></script>
<script>
    var currentPage = 1;
    var pageSize = 10;
    var totalPages;
    var userToken = localStorage.getItem("user_token");

    // 发送AJAX请求的函数
    function fetchActivities(page) {
      // 如果页码小于1,则重置为1
      if (page < 1) {
        page = 1;
      }
      // 更新当前页码
      currentPage = page;
      // 构建要发送的数据对象
      var dataToSend = {
        currentPage: currentPage,
        pageSize: pageSize
      };
      // 发送AJAX请求
      $.ajax({
          url: '/activity/find-list',
          type: 'GET',
          data: dataToSend, // 将分页参数作为请求数据发送
          dataType: 'json',
          headers: {
            // jwt
            "user_token": userToken
          },
          success: function(result) {
            if (result.code != 200) {
                alert("查询活动列表失败!" + result.msg);
            } else {
                var activities = result.data.records; // 假设返回的数据中活动列表字段为 'records'
                var activitiesHtml = '';
                var listContainer = document.getElementById('activities');
                // 在添加新内容前,先清空listContainer
                listContainer.innerHTML = '';
                activities.forEach(function(activity) {
                  var url = 'draw.html?activityName='+ encodeURIComponent(activity.activityName)
                          +'&activityId=' + encodeURIComponent(activity.activityId)
                          +'&valid=' + encodeURIComponent(activity.valid);
                  var linkTextActive = `<a href="${url}" target="_blank">活动进行中,去抽奖</a>`;
                  var linkTextInactive = `<a href="${url}" target="_blank">活动已完成,查看中奖名单</a>`;
                  var validClass = activity.valid ? 'active' : 'inactive';
                  var link = activity.valid ? linkTextActive : linkTextInactive;
                  activitiesHtml += `
                      <div class="activity-item">
                        <div class="activity-info">
                          <h4>${activity.activityName}</h4>
                          <p>${activity.description}</p>
                        </div>
                        <div class="${validClass}">
                          <p>${link}</p>
                        </div>
                      </div>
                    `;
                });
                $('#activities').html(activitiesHtml);
                // 更新分页控件的总页数
                totalPages = Math.ceil(result.data.total / pageSize);
                // 更新输入框的值
                $('#pageInput').val(currentPage);
              } // else end
          },
        error:function(err){
          console.log(err);
          if(err!=null && err.status==401){
            alert("用户未登录, 即将跳转到登录页!");
            // 跳转登录页
            window.location.href = "/blogin.html";
            window.parent.location.href = "/blogin.html";//让父页面一起跳转
          }
        }
      });
    }


    function previousPage() {
      if (currentPage > 1) {
        fetchActivities(currentPage - 1);
      } else {
        alert("已经是第一页");
      }
    }

    function nextPage() {
      if (currentPage < totalPages) {
        fetchActivities(currentPage + 1);
      } else {
        alert("已经是最后一页");
      }
    }

    $(document).ready(function() {
      fetchActivities(1);
    });

    // 绑定输入框回车事件
    $('#pageInput').on('keypress', function(e) {
      if (e.key === 'Enter') {
        var page = parseInt(this.value);
        if(page > totalPages){
          page = totalPages
          $('#pageInput').val(totalPages);
        }
        if (!isNaN(page) && page >= 1 && page <= totalPages) {
          fetchActivities(page);
        }
      }
    });

</script>
</body>
</html>
相关推荐
吴声子夜歌15 小时前
Java数据结构与算法——基本数学问题
java·开发语言·windows
这儿有一堆花19 小时前
用原生脚本编写无害恶作剧
windows
因我你好久不见19 小时前
Windows部署springboot jar支持开机自启动
windows·spring boot·jar
夜流冰19 小时前
Excel - MS Support for Excel: 2 Collaborate
数据库·windows·excel
林瞅瞅20 小时前
PowerShell 启动卡顿?内存飙升?原来是 800MB 的历史记录在作祟!
windows
Shepherd061920 小时前
【Windows Server 实战】WAC 反向代理配置
windows
云小逸20 小时前
【windows系统编程】第一章 Windows 系统核心架构与基础概念
windows·架构
怣疯knight1 天前
Docker Desktop 4.55.0版本安装成功教程
windows·docker
liulilittle1 天前
VEthernet 框架实现 tun2socks 的技术原理
网络·windows·c#·信息与通信·通信
独钓寒江雨1 天前
win11在安全模式下删除360tray.exe
windows·电脑