从 0 到 1:基于 SpringBoot 的体育场馆预约小程序开发笔记(一)
作者:CC同学
- 2024-12-29 广东
本文字数:7114 字
阅读完需:约 23 分钟
需求分析
给用户提供便捷的预约平台,方便他们查询场馆信息、选择合适时间并进行预约;主要功能包括,展示不同类型和位置的场馆,选择日期和时间,完成场馆预约,用户查看历史订单和预约状态等
功能规划
技术选型
前端基于微信小程序平台进行开发
后端基于 Java Springboot 架构开发
数据库: MySQL (8.0+)
数据库设计
CREATE TABLE `meetsport_meet` (
`MEET_ID` int NOT NULL AUTO_INCREMENT,
`MEET_TITLE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_CATE_ID` int NOT NULL DEFAULT 0,
`MEET_CATE_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`MEET_STATUS` int NOT NULL DEFAULT 1,
`MEET_ORDER` int NOT NULL DEFAULT 9999,
`MEET_VOUCH` int NOT NULL DEFAULT 0,
`MEET_DAYS` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_VIEW_CNT` int NOT NULL DEFAULT 0,
`MEET_MAX_CNT` int NOT NULL DEFAULT 0,
`MEET_FORMS` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_OBJ` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`ADD_TIME` bigint NOT NULL DEFAULT 0,
`EDIT_TIME` bigint NOT NULL DEFAULT 0,
PRIMARY KEY (`MEET_ID`) USING BTREE
)
CREATE TABLE `meetsport_meet_join` (
`MEET_JOIN_ID` int NOT NULL AUTO_INCREMENT,
`MEET_JOIN_USER_ID` int NOT NULL DEFAULT 0,
`MEET_JOIN_MEET_ID` int NOT NULL DEFAULT 0,
`MEET_JOIN_CODE` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_JOIN_IS_CHECK` int NOT NULL DEFAULT 0,
`MEET_JOIN_CHECK_TIME` bigint NOT NULL DEFAULT 0,
`MEET_JOIN_FORMS` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_JOIN_OBJ` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_JOIN_STATUS` int NOT NULL DEFAULT 0,
`MEET_JOIN_TIME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_JOIN_DAY` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`MEET_JOIN_MEET_TITLE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`ADD_TIME` bigint NOT NULL DEFAULT 0,
`EDIT_TIME` bigint NOT NULL DEFAULT 0,
PRIMARY KEY (`MEET_JOIN_ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11783 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
CREATE TABLE `meetsport_fav` (
`FAV_ID` int NOT NULL AUTO_INCREMENT,
`FAV_USER_ID` int NOT NULL DEFAULT 0,
`FAV_TITLE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`FAV_TYPE` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`FAV_OID` int NOT NULL DEFAULT 0,
`FAV_PATH` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`ADD_TIME` bigint NOT NULL DEFAULT 0,
`EDIT_TIME` bigint NOT NULL DEFAULT 0,
PRIMARY KEY (`FAV_ID`) USING BTREE
)
复制代码
核心实现
@Service("MeetSportMeetService")
public class MeetService extends BaseMyCustService {
@Resource(name = "MeetSportMeetMapper")
private MeetMapper meetMapper;
@Resource(name = "MeetSportMeetJoinMapper")
private MeetJoinMapper meetJoinMapper;
/**
* 找出未过期的日期段
*/
public List<String> calcDays(String days) {
List<String> dayList = new ArrayList();
String today = TimeHelper.time("yyyy-MM-dd");
JSONArray daysArr = JSONUtil.parseArray(days);
for (Object t : daysArr) {
JSONObject object = new JSONObject();
String day = Convert.toStr(t);
if (day.compareTo(today) < 0) continue;
dayList.add(day);
}
return dayList;
}
/**
* 预约列表
*/
@LoginIgnore
public PageResult getMeetList(PageParams pageRequest) {
Where<MeetModel> where = new Where<>();
where.eq("MEET_STATUS", MeetModel.STATUS.NORMAL);
long cateId = pageRequest.getParamLong("cateId");
if (NumberUtil.compare(cateId, 0) > 0)
where.eq("MEET_CATE_ID", cateId);
// 关键字查询
String search = pageRequest.getSearch();
if (StrUtil.isNotEmpty(search)) {
where.and(wrapper -> {
wrapper.or().like("MEET_TITLE", search);
});
}
// 条件查询
String sortType = pageRequest.getSortType();
String sortVal = pageRequest.getSortVal();
if (StrUtil.isNotEmpty(sortType) && StrUtil.isNotEmpty(sortVal)) {
switch (sortType) {
case "cateId": {
where.eq("MEET_CATE_ID", Convert.toLong(sortVal));
break;
}
case "sort": {
where.fmtOrderBySort(sortVal, "");
break;
}
}
}
// 排序
where.orderByAsc("MEET_ORDER");
where.orderByDesc("MEET_ID");
Page page = new Page(pageRequest.getPage(), pageRequest.getSize());
return meetMapper.getPageList(page, where, "MEET_DAYS,MEET_STATUS,MEET_ID,MEET_TITLE,MEET_OBJ," +
" MEET_CATE_NAME,MEET_MAX_CNT");
}
/**
* 取得我的预约详情
*/
public Map<String, Object> getMyMeetJoinDetail(long userId, long meetJoinId) {
Where<MeetJoinModel> where = new Where<>();
where.eq("MEET_JOIN_ID", meetJoinId);
where.eq("MEET_JOIN_USER_ID", userId);
Map<String, Object> ret = meetJoinMapper.getOneMap(where);
if (ObjectUtil.isEmpty(ret)) return ret;
long meetId = MapUtil.getLong(ret, "meetJoinMeetId");
ret.put("meet", meetMapper.getOneMap(meetId, "MEET_TITLE,MEET_START,MEET_END"));
return ret;
}
/**
* 我的预约预约列表
*/
@LoginIgnore
public PageResult getMyMeetJoinList(long userId, PageParams pageRequest) {
WhereJoin<MeetJoinModel> where = new WhereJoin<>();
where.leftJoin(MeetModel.class, MeetModel::getMeetId, MeetJoinModel::getMeetJoinMeetId);
where.eq("t.MEET_JOIN_USER_ID", userId);
// 关键字查询
String search = pageRequest.getSearch();
if (StrUtil.isNotEmpty(search)) {
where.and(wrapper -> {
wrapper.or().like("t.MEET_JOIN_CODE", search);
wrapper.or().like("t1.MEET_TITLE", search);
});
}
// 条件查询
String sortType = pageRequest.getSortType();
String sortVal = pageRequest.getSortVal();
if (StrUtil.isNotEmpty(sortType) && StrUtil.isNotEmpty(sortVal)) {
switch (sortType) {
case "sort": {
where.fmtOrderBySort(sortVal, "");
break;
}
}
}
// 排序
where.orderByDesc("MEET_JOIN_ID");
Page page = new Page(pageRequest.getPage(), pageRequest.getSize());
return meetJoinMapper.getPageJoinList(page, where, "t.*,t1.MEET_TITLE");
}
/**
* 单个浏览
*/
@LoginIgnore
public Map<String, Object> view(long id, long userId) {
// PV
UpdateWhere<MeetModel> uw = new UpdateWhere<>();
uw.eq("MEET_ID", id);
meetMapper.inc(uw, "MEET_VIEW_CNT");
Where<MeetModel> where = new Where<>();
where.eq("MEET_ID", id);
where.eq("MEET_STATUS", MeetModel.STATUS.NORMAL);
Map<String, Object> ret = meetMapper.getOneMap(where);
if (ObjectUtil.isNull((ret))) return null;
String today = TimeHelper.time("yyyy-MM-dd");
// 获得预约统计数据
Where<MeetJoinModel> whereGroup = new Where<MeetJoinModel>();
whereGroup.ge("MEET_JOIN_DAY", today);
whereGroup.select("MEET_JOIN_TIME,MEET_JOIN_DAY,count(0) as total ");
whereGroup.groupBy("MEET_JOIN_TIME,MEET_JOIN_DAY");
List<Map<String, Object>> listGroup = meetJoinMapper.selectMaps(whereGroup);
Map<String, Integer> statMap = new HashMap<>();
for (Map<String, Object> t : listGroup) {
String key = DigestUtil.md5Hex(t.get("MEET_JOIN_DAY").toString() + t.get("MEET_JOIN_TIME").toString());
statMap.put(key, Convert.toInt(t.get("total")));
}
JSONArray daysArr = JSONUtil.parseArray(ret.get("meetDays"));
JSONObject obj = JSONUtil.parseObj(ret.get("meetObj"));
JSONArray timesArr = obj.getJSONArray("time");
// 取得时段
List<String> timesList = new ArrayList();
for (Object t : timesArr) {
JSONObject tt = JSONUtil.parseObj(t);
timesList.add(tt.getStr("title"));
}
List<Map<String, Object>> list = new ArrayList<>();
for (Object t : daysArr) {
JSONObject object = new JSONObject();
String day = Convert.toStr(t);
if (day.compareTo(today) < 0) continue;
object.set("label", day);
JSONArray timesObjArr = new JSONArray();
for (Object tx : timesList) {
JSONObject timeObj = new JSONObject();
timeObj.set("label", Convert.toStr(tx));
String key = DigestUtil.md5Hex(Convert.toStr(t) + Convert.toStr(tx));
if (statMap.containsKey(key))
timeObj.set("cnt", Convert.toInt(statMap.get(key)));
else
timeObj.set("cnt", 0);
timesObjArr.add(timeObj);
}
object.set("times", timesObjArr);
list.add(object);
}
ret.put("meetDays", list);
return ret;
}
/**
* 预约前获取关键信息
*/
public Map<String, Object> detailForMeetJoin(long userId, long meetId, String day, String time) {
// this.checkRules(userId, meetId, day, time);
Where<MeetModel> where = new Where<>();
where.eq("MEET_ID", meetId);
where.eq("MEET_STATUS", MeetModel.STATUS.NORMAL);
Map<String, Object> ret = meetMapper.getOneMap(where, "MEET_TITLE");
if (ObjectUtil.isEmpty(ret)) throw new AppException("该预约项目不存在");
logger.info(ret.toString());
// 取出本人最近一次的填写表单
Where<MeetJoinModel> whereJoin = new Where<>();
whereJoin.eq("MEET_JOIN_USER_ID", userId);
whereJoin.orderByDesc("MEET_JOIN_ID");
Map<String, Object> retJoin = meetJoinMapper.getOneMap(whereJoin, "MEET_JOIN_FORMS");
if (ObjectUtil.isEmpty(retJoin)) {
ret.put("myForms", null);
} else {
ret.put("myForms", retJoin.get("meetJoinForms"));
}
return ret;
}
public void checkRules(long userId, long meetId, String day, String time) {
Where<MeetModel> where = new Where<>();
where.eq("MEET_ID", meetId);
where.eq("MEET_STATUS", MeetModel.STATUS.NORMAL);
MeetModel meet = meetMapper.getOne(where);
if (ObjectUtil.isEmpty(meet))
throw new AppException("该预约项目不存在或者已经停止");
// 判断是否已经约满
Where<MeetJoinModel> whereCnt = new Where<>();
whereCnt.eq("MEET_JOIN_MEET_ID", meetId);
whereCnt.eq("MEET_JOIN_DAY", day);
whereCnt.eq("MEET_JOIN_TIME", time);
long cnt = meetJoinMapper.count(whereCnt);
if (cnt >= meet.getMeetMaxCnt())
throw new AppException("该时段已经约满,请选择其他~");
// 自己是否预约
Where<MeetJoinModel> whereJoin = new Where<>();
whereJoin.eq("MEET_JOIN_USER_ID", userId);
whereJoin.eq("MEET_JOIN_MEET_ID", meetId);
whereJoin.eq("MEET_JOIN_DAY", day);
whereJoin.eq("MEET_JOIN_TIME", time);
if (meetJoinMapper.exists(whereJoin))
throw new AppException("您已经预约本时段,无须重复预约~");
}
/**
* 取消我的预约,取消即为删除记录
*/
public void cancelMyMeetJoin(long userId, long meetJoinId) {
Where<MeetJoinModel> whereJoin = new Where<>();
whereJoin.eq("MEET_JOIN_ID", meetJoinId);
whereJoin.eq("MEET_JOIN_STATUS", MeetJoinModel.STATUS.NORMAL);
MeetJoinModel meetJoin = meetJoinMapper.getOne(whereJoin);
if (ObjectUtil.isEmpty(meetJoin))
throw new AppException("未找到可取消的预约记录");
if (NumberUtil.equals(meetJoin.getMeetJoinIsCheck(), 1))
throw new AppException("该预约已经签到,无法取消");
MeetModel meet = meetMapper.getOne(meetJoin.getMeetJoinMeetId());
if (ObjectUtil.isEmpty(meet))
throw new AppException("该预约不存在,无法取消");
meetJoinMapper.delete(meetJoinId);
}
/**
* 按天获取预约项目
*/
public List<Map<String, Object>> getMeetListByDay(String day) {
Where<MeetModel> where = new Where<>();
where.eq("MEET_STATUS", MeetModel.STATUS.NORMAL);
where.like("MEET_DAYS", day);
where.orderByAsc("MEET_ORDER");
where.orderByDesc("MEET_ID");
String fields = "MEET_ID,MEET_TITLE,MEET_OBJ";
List<Map<String, Object>> list = meetMapper.getAllListMap(where, fields);
for (Map<String, Object> record : list) {
FormHelper.fmtDBObj(record, "meetObj", "cover,time");
}
return list;
}
/**
* 获取从某天开始可预约的日期
*
* @param {*} fromDay 日期 Y-M-D
*/
public JSONArray getMeetHasDaysFromDay(String fromDay) {
long start = TimeHelper.time2Timestamp(fromDay + " 00:00:00");
Where<MeetModel> where = new Where<>();
where.eq("MEET_STATUS", MeetModel.STATUS.NORMAL);
String fields = "MEET_DAYS";
Map<String, String> ret = new HashMap<>();
JSONArray arr = new JSONArray();
List<MeetModel> list = meetMapper.getAllList(where, fields);
String today = TimeHelper.time("yyyy-MM-dd");
for (MeetModel meet : list) {
JSONArray daysArr = JSONUtil.parseArray(meet.getMeetDays());
for (Object t : daysArr) {
JSONObject object = new JSONObject();
String day = Convert.toStr(t);
if (day.compareTo(today) < 0) continue;
if (!ret.containsKey(day)) {
ret.put(day, day);
arr.add(day);
}
}
}
return arr;
}
}
复制代码
UI 设计
后台管理系统
代码分享 git
划线
评论
复制
发布于: 刚刚阅读数: 5
CC同学
关注
CC同学的小程序开发笔记 2021-06-13 加入
大鹅厂的小小程序媛,vx: cclinux0730
评论