目录
- 一、简介
- 二、参数列表
- 三、接口规范
- [四、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>