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

目录

  • 一、简介
  • 二、参数列表
  • 三、接口规范
  • [四、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>
相关推荐
晚枫~4 小时前
不同浏览器在Windows和Mac上的跨域配置方法
windows·macos
雪碧聊技术5 小时前
怎么重启电脑的网卡(Windows系统)?
windows·重启网卡
程序猿_极客7 小时前
【2025 最新】 Maven 下载安装与配置教程(超详细带图文Windows 版):从入门到实战
java·开发语言·windows·maven·maven安装
XDHCOM9 小时前
深入掌握Unicode转换方法:从基础到高级的实用技巧与应用场景
windows
q***577410 小时前
Node.JS 版本管理工具 Fnm 安装及配置(Windows)
windows·node.js
Bruce_Liuxiaowei10 小时前
HTTPHTTPS探测出网技术详解:跨平台命令与实战方法
运维·windows·安全·网络安全
njsgcs10 小时前
pyautocad获得所选圆弧的弧长总和
开发语言·windows·python
百***680418 小时前
Node.JS 版本管理工具 Fnm 安装及配置(Windows)
windows·node.js
secondyoung19 小时前
Mermaid流程图高效转换为图片方案
c语言·人工智能·windows·vscode·python·docker·流程图