Sprint Essay 2
I. Project Burn-up ChartII. Latest Running Gif of the Project Module1. The background management interface and air quality entry module are displayedIII. The Development Team Conducts Code Checks2. Th
·
FZU Meteorological Bureau —— EE308FZ_Fifth Assignment_Alpha Sprint_Sprint Essay 2
| Assignment 5 | Alpha Sprint |
|---|---|
| Course | EE308FZ — Software Engineering |
| Class Link | 2501_MU_SE_FZU |
| Requirements | Fifth Assignment——Alpha Sprint |
| Team Name | FZU Meteorological Bureau |
| Objective | Sprint Essay 2_Day3-Day4 (12.14-12.15) |
| Other Reference | 1. JavaScript Style guide 2. The Art of Construction 3. Vue Guide 4. Springboot Construction Guide |
Catalog
I. Project Burn-up Chart
II. Latest Running Gif of the Project Module
1. The background management interface and air quality entry module are displayed
III. The Development Team Conducts Code Checks
2. The front end of the background management interface
3. Air quality Front-end management module
4. Air quality backend interface
IV. Evaluation of Teammates
I. Project Burn-up Chart

II. Latest Running Gif of the Project Module
- Our user interface design team and front-end development team have developed the air quality display component and some back-end management modules, including the design of the data visualization module and dynamic data presentation logic, which are consistent with the overall interface style of the system.
- Our back-end development team has completed API integration and adaptation, including interface authentication, data format conversion, and handling of abnormal data (such as API timeouts and data return errors), reducing repeated API calls and improving data response speed.
- Our test optimization team has completed the testing of the front-end management module and the air quality detection interface, but found that there are still problems with manual air quality entry. We hope to solve them throughout the Alpha sprint stage.
1. The background management interface and air quality entry module are displayed
- Background management interface and air quality manual video entry
2025-12-14 18-42-22
- Backend database field storage
/*Table structure for table `air_quality` */
DROP TABLE IF EXISTS `air_quality`;
CREATE TABLE `air_quality` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`city_name` varchar(50) NOT NULL COMMENT '城市名称',
`province` varchar(50) NOT NULL COMMENT '省份',
`aqi` int NOT NULL COMMENT 'AQI指数',
`air_quality_level` varchar(20) NOT NULL COMMENT '空气质量等级(优/良/轻度污染/中度污染/重度污染/严重污染)',
`primary_pollutant` varchar(50) NOT NULL COMMENT '首要污染物',
`pm25` decimal(5,2) NOT NULL COMMENT 'PM2.5浓度(μg/m³)',
`pm10` decimal(5,2) NOT NULL COMMENT 'PM10浓度(μg/m³)',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*Data for the table `air_quality` */
insert into `air_quality`(`id`,`city_name`,`province`,`aqi`,`air_quality_level`,`primary_pollutant`,`pm25`,`pm10`,`update_time`,`create_time`) values
(1,'北京','北京市',45,'优','PM2.5',32.00,56.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(2,'上海','上海市',68,'良','PM10',48.00,72.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(3,'深圳','广东省',35,'优','O₃',22.00,38.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(4,'成都','四川省',85,'良','PM2.5',62.00,98.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(5,'杭州','浙江省',52,'良','PM2.5',36.00,58.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(6,'西安','陕西省',120,'轻度污染','PM10',88.00,135.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(7,'厦门','福建省',28,'优','O₃',18.00,32.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(8,'武汉','湖北省',78,'良','PM2.5',56.00,84.00,'2025-11-20 21:36:52','2025-11-04 14:55:54'),
(9,'1','1',1,'优','1',1.00,1.00,'2025-11-20 21:36:52','2025-11-20 21:14:28');
- We found that the field still doesn’t show up on the frontend when the database already exists, which is an issue that needs to be addressed.

III. The Development Team Conducts Code Checks


2. The front end of the background management interface
code
<template>
<div>
<!-- 后台菜单管理-->
<div style="margin: 10px 0">
<el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search" v-model="name"></el-input>
<!-- <el-input style="width: 200px" placeholder="请输入邮箱" suffix-icon="el-icon-message" class="ml-5" v-model="email"></el-input>-->
<!-- <el-input style="width: 200px" placeholder="请输入地址" suffix-icon="el-icon-position" class="ml-5" v-model="address"></el-input>-->
<el-button class="ml-5" type="primary" @click="load">搜索</el-button>
<el-button type="warning" @click="reset">重置</el-button>
</div>
<div style="margin: 10px 0">
<el-button type="primary" @click="handleAdd(null)">新增 <i class="el-icon-circle-plus-outline"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确定'
cancel-button-text='我再想想'
icon="el-icon-info"
icon-color="red"
title="您确定批量删除这些数据吗?"
@confirm="delBatch"
>
<el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
<!-- <el-upload action="http://localhost:9090/user/import" :show-file-list="false" accept="xlsx" :on-success="handleExcelImportSuccess" style="display: inline-block">-->
<!-- <el-button type="primary" class="ml-5">导入 <i class="el-icon-bottom"></i></el-button>-->
<!-- </el-upload>-->
<!-- <el-button type="primary" @click="exp" class="ml-5">导出 <i class="el-icon-top"></i></el-button>-->
</div>
<el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
row-key="id" default-expand-all @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" label="ID" width="80"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="path" label="路径"></el-table-column>
<el-table-column prop="pagePath" label="页面路径"></el-table-column>
<el-table-column label="图标" class-name="fontSize18" align="center" label-class-name="fontSize12">
<template slot-scope="scope">
<span :class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column prop="description" label="描述"></el-table-column>
<el-table-column prop="sortNum" label="顺序"></el-table-column>
<el-table-column label="操作" width="300" align="center">
<template slot-scope="scope">
<el-button type="primary" @click="handleAdd(scope.row.id)" v-if="!scope.row.pid && !scope.row.path">新增子菜单 <i class="el-icon-plus"></i></el-button>
<el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确定'
cancel-button-text='我再想想'
icon="el-icon-info"
icon-color="red"
title="您确定删除吗?"
@confirm="del(scope.row.id)"
>
<el-button type="danger" slot="reference">删除 <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-dialog title="菜单信息" :visible.sync="dialogFormVisible" width="30%" >
<el-form label-width="80px" size="small">
<el-form-item label="名称">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="路径">
<el-input v-model="form.path" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="页面路径">
<el-input v-model="form.pagePath" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="图标">
<el-select clearable v-model="form.icon" placeholder="请选择" style="width: 100%">
<el-option v-for="item in options" :key="item.name" :label="item.name" :value="item.value">
<i :class="item.value" /> {{ item.name }}
</el-option>
</el-select>
</el-form-item>
<el-form-item label="顺序">
<el-input v-model="form.sortNum" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="form.description" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {serverIp} from "../../public/config";
export default {
name: "Menu",
data() {
return {
tableData: [],
total: 0,
pageNum: 1,
pageSize: 10,
name: "",
form: {},
dialogFormVisible: false,
multipleSelection: [],
options: []
}
},
created() {
this.load()
},
methods: {
load() {
this.request.get("/menu", {
params: {
name: this.name,
}
}).then(res => {
this.tableData = res.data
})
// 请求图标的数据
this.request.get("/menu/icons").then(res => {
this.options = res.data
})
},
save() {
this.request.post("/menu", this.form).then(res => {
if (res.code === '200') {
this.$message.success("保存成功")
this.dialogFormVisible = false
this.load()
} else {
this.$message.error("保存失败")
}
})
},
handleAdd(pid) {
this.dialogFormVisible = true
this.form = {}
if (pid) {
this.form.pid = pid
}
},
handleEdit(row) {
this.form = JSON.parse(JSON.stringify(row))
this.dialogFormVisible = true
},
del(id) {
this.request.delete("/menu/" + id).then(res => {
if (res.code === '200') {
this.$message.success("删除成功")
this.load()
} else {
this.$message.error("删除失败")
}
})
},
handleSelectionChange(val) {
console.log(val)
this.multipleSelection = val
},
delBatch() {
let ids = this.multipleSelection.map(v => v.id) // [{}, {}, {}] => [1,2,3]
this.request.post("/menu/del/batch", ids).then(res => {
if (res.code === '200') {
this.$message.success("批量删除成功")
this.load()
} else {
this.$message.error("批量删除失败")
}
})
},
reset() {
this.name = ""
this.load()
},
handleSizeChange(pageSize) {
console.log(pageSize)
this.pageSize = pageSize
this.load()
},
handleCurrentChange(pageNum) {
console.log(pageNum)
this.pageNum = pageNum
this.load()
},
exp() {
window.open(`http://${serverIp}:9090/role/export`)
},
handleExcelImportSuccess() {
this.$message.success("导入成功")
this.load()
}
}
}
</script>
<style scoped>
.headerBg {
background: #eee!important;
}
.fontSize18{
font-size: 18px;
}
.fontSize12{
font-size: 12px;
}
</style>
3. Air quality Front-end management module
code
<template>
<div>
<!-- 搜索区域 -->
<div style="margin: 10px 0">
<el-input style="width: 200px" placeholder="请输入城市名称" suffix-icon="el-icon-search" v-model="searchForm.cityName"></el-input>
<el-input style="width: 200px" placeholder="请输入省份" v-model="searchForm.province" class="ml-5"></el-input>
<el-select style="width: 200px" placeholder="请选择质量等级" v-model="searchForm.airQualityLevel" class="ml-5" clearable>
<el-option label="优" value="优"></el-option>
<el-option label="良" value="良"></el-option>
<el-option label="轻度污染" value="轻度污染"></el-option>
<el-option label="中度污染" value="中度污染"></el-option>
<el-option label="重度污染" value="重度污染"></el-option>
<el-option label="严重污染" value="严重污染"></el-option>
</el-select>
<el-button class="ml-5" type="primary" @click="load">搜索</el-button>
<el-button type="warning" @click="reset">重置</el-button>
</div>
<!-- 操作按钮区域 -->
<div style="margin: 10px 0">
<el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确定'
cancel-button-text='我再想想'
icon="el-icon-info"
icon-color="red"
title="您确定批量删除这些数据吗?"
@confirm="delBatch"
>
<el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
</div>
<!-- 数据表格 -->
<el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" label="ID" width="80" sortable></el-table-column>
<el-table-column prop="cityName" label="城市名称" width="120"></el-table-column>
<el-table-column prop="province" label="省份" width="120"></el-table-column>
<el-table-column prop="aqi" label="AQI指数" width="100" sortable></el-table-column>
<el-table-column prop="airQualityLevel" label="质量等级" width="120">
<template slot-scope="scope">
<el-tag :type="getLevelType(scope.row.airQualityLevel)">{{ scope.row.airQualityLevel }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="primaryPollutant" label="主要污染物" width="150"></el-table-column>
<el-table-column prop="pm25" label="PM2.5" width="100" sortable></el-table-column>
<el-table-column prop="pm10" label="PM10" width="100" sortable></el-table-column>
<el-table-column prop="updateTime" label="更新时间" width="180"></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确定'
cancel-button-text='我再想想'
icon="el-icon-info"
icon-color="red"
title="您确定删除吗?"
@confirm="del(scope.row.id)"
>
<el-button type="danger" slot="reference">删除 <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<div style="padding: 10px 0">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[5, 10, 15, 20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible" width="40%" :close-on-click-modal="false">
<el-form label-width="120px" size="small" style="width: 85%;" :model="form" :rules="rules" ref="ruleForm">
<el-form-item prop="cityName" label="城市名称">
<el-input v-model="form.cityName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item prop="province" label="省份">
<el-input v-model="form.province" autocomplete="off"></el-input>
</el-form-item>
<el-form-item prop="aqi" label="AQI指数">
<el-input-number v-model="form.aqi" :min="0" :max="500" controls-position="right" style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item prop="airQualityLevel" label="质量等级">
<el-select v-model="form.airQualityLevel" placeholder="请选择质量等级" style="width: 100%">
<el-option label="优" value="优"></el-option>
<el-option label="良" value="良"></el-option>
<el-option label="轻度污染" value="轻度污染"></el-option>
<el-option label="中度污染" value="中度污染"></el-option>
<el-option label="重度污染" value="重度污染"></el-option>
<el-option label="严重污染" value="严重污染"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="primaryPollutant" label="主要污染物">
<el-input v-model="form.primaryPollutant" autocomplete="off"></el-input>
</el-form-item>
<el-form-item prop="pm25" label="PM2.5浓度">
<el-input-number v-model="form.pm25" :min="0" :max="500" :step="0.1" controls-position="right" style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item prop="pm10" label="PM10浓度">
<el-input-number v-model="form.pm10" :min="0" :max="600" :step="0.1" controls-position="right" style="width: 100%"></el-input-number>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "AirQuality",
data() {
return {
tableData: [],
total: 0,
pageNum: 1,
pageSize: 10,
searchForm: {
cityName: "",
province: "",
airQualityLevel: ""
},
form: {},
dialogFormVisible: false,
multipleSelection: [],
dialogTitle: "新增空气质量数据",
rules: {
cityName: [
{ required: true, message: '请输入城市名称', trigger: 'blur' }
],
province: [
{ required: true, message: '请输入省份', trigger: 'blur' }
],
aqi: [
{ required: true, message: '请输入AQI指数', trigger: 'blur' },
{ type: 'number', min: 0, max: 500, message: 'AQI指数应在0-500之间', trigger: 'blur' }
],
airQualityLevel: [
{ required: true, message: '请选择空气质量等级', trigger: 'change' }
]
}
}
},
created() {
this.load()
},
methods: {
// 加载数据
load() {
this.request.get("/airQuality/page", {
params: {
pageNum: this.pageNum,
pageSize: this.pageSize,
cityName: this.searchForm.cityName,
province: this.searchForm.province,
airQualityLevel: this.searchForm.airQualityLevel
}
}).then(res => {
this.tableData = res.data.records
this.total = res.data.total
})
},
// 保存数据(新增或编辑)
save() {
this.$refs['ruleForm'].validate((valid) => {
if (valid) {
// 根据是否有id判断是新增还是编辑
const requestMethod = this.form.id ? this.request.put : this.request.post;
const successMessage = this.form.id ? "更新成功" : "新增成功";
requestMethod("/airQuality", this.form).then(res => {
if (res.code === '200') {
this.$message.success(successMessage)
this.dialogFormVisible = false
this.load()
} else {
this.$message.error(res.msg)
}
})
}
})
},
// 新增数据
handleAdd() {
this.dialogTitle = "新增空气质量数据"
this.dialogFormVisible = true
this.form = {}
},
// 编辑数据
handleEdit(row) {
this.dialogTitle = "编辑空气质量数据"
this.form = JSON.parse(JSON.stringify(row))
this.dialogFormVisible = true
},
// 删除单条数据
del(id) {
this.request.delete("/airQuality/" + id).then(res => {
if (res.code === '200') {
this.$message.success("删除成功")
this.load()
} else {
this.$message.error("删除失败")
}
})
},
// 处理表格多选
handleSelectionChange(val) {
this.multipleSelection = val
},
// 批量删除
delBatch() {
if (!this.multipleSelection.length) {
this.$message.error("请选择需要删除的数据")
return
}
let ids = this.multipleSelection.map(v => v.id)
this.request.post("/airQuality/del/batch", ids).then(res => {
if (res.code === '200') {
this.$message.success("批量删除成功")
this.load()
} else {
this.$message.error("批量删除失败")
}
})
},
// 重置搜索条件
reset() {
this.searchForm = {
cityName: "",
province: "",
airQualityLevel: ""
}
this.load()
},
// 分页大小改变
handleSizeChange(pageSize) {
this.pageSize = pageSize
this.load()
},
// 当前页码改变
handleCurrentChange(pageNum) {
this.pageNum = pageNum
this.load()
},
// 导出数据
exp() {
window.open("http://localhost:9090/airQuality/export")
},
// 根据空气质量等级返回对应的标签类型
getLevelType(level) {
switch(level) {
case '优': return 'success'
case '良': return 'primary'
case '轻度污染': return 'warning'
case '中度污染': return 'warning'
case '重度污染': return 'danger'
case '严重污染': return 'danger'
default: return 'info'
}
}
}
}
</script>
<style scoped>
.headerBg {
background: #eee!important;
}
.ml-5 {
margin-left: 5px;
}
</style>
4. Air quality detection module display code
- Backend Controller layer (core: interface entrance)
package com.chen.springboot.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chen.springboot.common.Result;
import com.chen.springboot.common.util.SensitivewordFilter;
import com.chen.springboot.entity.Activity;
import com.chen.springboot.entity.Follow;
import com.chen.springboot.service.IActivityService;
import com.chen.springboot.service.IFollowService;
import com.chen.springboot.utils.Date2Util;
import com.chen.springboot.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
* 前端控制器
* </p>
*
* @author
* @since 2025-11-04
*/
@RestController
@RequestMapping("/activity")
public class
ActivityController {
@Resource
private IActivityService activityService;
@Autowired
private SensitivewordFilter sensitivewordFilter;
@Resource
private IFollowService followService;
// 新增或者更新
@PostMapping
public Result save(@RequestBody Activity articles) {
if (articles.getId() == null) { // 新增
articles.setTime(DateUtil.now()); // new Date()
articles.setUsername(TokenUtils.getCurrentUser().getUsername());//填入当前登录用户的昵称
articles.setUserId(TokenUtils.getCurrentUser().getId());//填入当前登录用户的id
articles.setUserAvatar(TokenUtils.getCurrentUser().getAvatarUrl()); //填入当前登录用户的头像
}
articles.setSurplusNum(articles.getActivityNum());
String content = articles.getContent();
String title = articles.getTitle();
String wordsContent = sensitivewordFilter.filterSensitiveWords(content);
articles.setContent(wordsContent);
String wordsTitle = sensitivewordFilter.filterSensitiveWords(title);
articles.setTitle(wordsTitle);
articles.setSurplusNum(articles.getActivityNum());
activityService.saveOrUpdate(articles);
return Result.success();
}
//删除
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
activityService.removeById(id);
return Result.success();
}
//批量删除
@PostMapping("/del/batch")
public Result deleteBatch(@RequestBody List<Integer> ids) {
activityService.removeByIds(ids);
return Result.success();
}
@GetMapping("/exame")
public Result exame(
@RequestParam Long id,
@RequestParam Integer status) {
Activity activity = new Activity();
activity.setId(id);
activity.setStatus(status);
//验证时间,时间超过了报名时间就不能再审核了
Activity activity1 = activityService.getById(id);
String nowTime = DateUtil.now();
String signEndTime = activity1.getSignEndTime();
//报名时间超过了,也不能报名
int compare = Date2Util.compareDate(nowTime, signEndTime);
if(compare == 1){
activity.setStatus(3);
}
activityService.updateById(activity);
return Result.success();
}
//查询所有
@GetMapping
public Result findAll() {
return Result.success(activityService.list());
}
//通过id查询
@GetMapping("/{id}")
public Result findOne(@PathVariable Integer id) {
return Result.success(activityService.getById(id));
}
//后台:分页查询和按照文章名查询
@GetMapping("/page")
public Result findPage(@RequestParam (defaultValue = "") String title,
@RequestParam (defaultValue = "") String category,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id"); //按照id倒序排序
if (StrUtil.isNotBlank(title)) { // 标题模糊查询
queryWrapper.like("title", title);
}
if (StrUtil.isNotBlank(category)) { //分类模糊查询
queryWrapper.like("category ", category);
}
//queryWrapper.eq("status",1);
return Result.success(activityService.page(new Page<>(pageNum, pageSize), queryWrapper));
}
//首页:论坛,可以添加关注
@GetMapping("/homepage")
public Result findPage2(@RequestParam (defaultValue = "") String title,
@RequestParam (defaultValue = "") String category,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id"); //按照id倒序排序
if (StrUtil.isNotBlank(title)) { //标题模糊查询
queryWrapper.like("title", title);
}
if (StrUtil.isNotBlank(category)) { //分类模糊查询
queryWrapper.like("category ", category);
}
queryWrapper.eq("status",1);
Page<Activity> page = activityService.page(new Page<>(pageNum, pageSize), queryWrapper);
return Result.success(page);
}
//我发布的帖子
@GetMapping("/selfpage")
public Result selfpage(@RequestParam (defaultValue = "") String title,
@RequestParam (defaultValue = "") String category,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
String username = TokenUtils.getCurrentUser().getUsername();
QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
queryWrapper.orderByDesc("id"); //按照id倒序排序
if (StrUtil.isNotBlank(title)) { // 标题模糊查询
queryWrapper.like("title", title);
}
if (StrUtil.isNotBlank(category)) { //分类模糊查询
queryWrapper.like("category ", category);
}
return Result.success(activityService.page(new Page<>(pageNum, pageSize), queryWrapper));
}
//计算点赞数和阅读书
@PutMapping ("/count")
public Result count() {
List<Activity> list = activityService.list();
Map<String, List<Activity>> collect = list.stream().collect(Collectors.groupingBy(Activity::getUsername));
Map<String, Integer> goodCount = new HashMap<>(); //点赞
Map<String, Integer> readCount = new HashMap<>(); //阅读
for (Map.Entry<String, List<Activity>> entry : collect.entrySet()) {
int praiseSum = entry.getValue().stream().mapToInt(Activity::getGoodCount).sum();
int readSum = entry.getValue().stream().mapToInt(Activity::getReadCount).sum();
goodCount.put(entry.getKey(), praiseSum);
readCount.put(entry.getKey(), readSum);
}
Map<String, Object> res = new HashMap<>();
res.put("goodCount",goodCount);
res.put("readCount", readCount);
return Result.success(res);
}
//按照阅读数、点赞数、和时间 降序排序 分页进行查询
@GetMapping("/read")
public Result findReadPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<Activity> queryWrapperRead = new QueryWrapper<>();
queryWrapperRead.orderByDesc("read_count"); //按照阅读数倒序排序
return Result.success(activityService.page(new Page<>(pageNum, pageSize), queryWrapperRead));
}
@GetMapping("/good")
public Result findGoodPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<Activity> queryWrapperGood = new QueryWrapper<>();
queryWrapperGood.orderByDesc("good_count"); //按照点赞数倒序排序
return Result.success(activityService.page(new Page<>(pageNum, pageSize), queryWrapperGood));
}
@GetMapping("/date")
public Result findDatePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<Activity> queryWrapperTime = new QueryWrapper<>();
queryWrapperTime.orderByDesc("time"); //按照发布时间倒序排序
return Result.success(activityService.page(new Page<>(pageNum, pageSize), queryWrapperTime));
}
}
- Service layer (core: business logic)
package com.chen.springboot.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chen.springboot.entity.Activity;
import com.chen.springboot.entity.AirQuality;
/**
* <p>
* 服务类
* </p>
*
* @author
* @since 2025-11-04
*/
public interface IAirQualityService extends IService<AirQuality> {
}
IV. Evaluation of Teammates
| 学号 | 姓名 | 职责 | 贡献 |
|---|---|---|---|
| 832301213 | Chen Ye | Responsible for the overall planning, schedule management and team coordination of the project; Lead the writing, integration and finalization of all project documents | 10% |
| 832301102 | Wang Jiarui | Responsible for front-end routing design and control logic implementation | 8% |
| 832301118 | Li Yifei | up the scaffolding and development environment for the Vue project | 8% |
| 832301208 | Zhang Shimin | Responsible for page component development and style implementation; Customize system themes and layouts; Complete user interaction features | 8% |
| 832301113 | Sun Chenen | Build a Spring Boot multi-module project architecture | 8% |
| 832301214 | Chen Xueting | Implement the user login authentication module to complete the permission menu management function | 8% |
| 832301205 | Zhang Zhikai | Complete the development of core CRUD functions in the business; Write unit test cases; Ensure code quality | 8% |
| 832301109 | Liu Zhongbo | Integrated Redis caching capabilities; Realize file upload and download services; Optimize thread pool configuration | 8% |
| 832301210 | Chen Hongyu | Execution functional test cases; track and validate bug fixes; Write test reports | 8% |
| 832301228 | Lin Juntian | Conduct system performance testing; organize user acceptance tests; Collect user feedback | 8% |
| 832301115 | Li Yuxin | Design database table structure; Maintain a data dictionary | 8% |
| 832301225 | Lin Qixuan | Optimize database index configuration; Build a master-slave replication architecture; Develop a data backup strategy | 10% |
更多推荐


所有评论(0)