背景和需求分析
随着社会的在新时代下的飞跃发展,尤其是奥运会和冬奥会的成功举办,全民健身的热潮兴起,在平时紧张的工作,学习之余,重视身体,重视身材,重视 健康的需求越来越强烈,那么设计一款针对广大运动爱好者的小程序,使运动爱好者和体育场馆之间能有效的衔接,合理的规划时间和场地,节省双方来往成本的 需求痛点是成立的。
好的场馆预约系统包括场馆动态,运动常识,羽毛球场地预约,足球场地预约,篮球场地预约,健身房预约,乒乓球场地预约,游泳场地预约,网球场地预约等,可以按照业者的实际情况进行取舍或者增添场馆类型,既适用于大型综合性文体中心,也适合单一性运动场馆(如羽毛球馆,健身房,乒乓球馆等)。
该系统基于MVC架构,采用基于微信小程序平台开发,校园用户操作轻松快捷:无需下载安装APP。
功能分解

数据字典

需要克服的技术难点
本预约小程序采用腾讯云开发技术,云开发提供了一个 JSON 数据库,顾名思义,数据库中的每条记录都是一个 JSON 格式的对象。
一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。
其主要特性:
安全性:对于数据库而言,数据安全是第一位的; 易用性:与小程序的特征类似,“开箱即用,用完即走”,简单上手,免运维; 低成本:按量收费,精细化成本控制; 高性能:Nosql,支持高并发读写; 灵活性:无固定的数据库表模式(no-schema),支持弹性伸缩; 在云开发控制台有个高级操作,这里可以执行开发者输入的脚本,比如清空集合,根据某个条件删除集合内部分数据,查询集合等等
1. 清空操作
db.collection('t_user')
.where({
_id: _.exists(true)
})
.remove()2. 删除操作
db.collection('t_user')
.where({
USER_ENROLL: 1990
})
.remove()
3. 查询操作
db.collection('t_user')
.where({
USER_NAME: '覃建平'
})
.get()
db.collection('t_user')
.where({
USER_INVITE_ID: ''
})
.field({
USER_INVITE_ID:true
})
.skip(0)
.limit(10)
.get()
4. 去掉某个字段
db.collection('t_user').where({_id:_.neq(1)})
.update({
data: {
USER_VIP_MONEY:_.remove(),
USER_VIP_RETURN_MONEY:_.remove(),
USER_VIP_LEAVE_MONEY:_.remove(),
}
})
5 更新或者新增某个字段
db.collection('t_user').where({_id:_.neq(1)})
.update({
data: {
USER_VIP_MONEY: 1111,
}
}
6 复杂的多条件查询
async getUserList(userId, {
search,
sortType,
sortVal,
orderBy,
whereEx,
page,
size,
oldTotal = 0
}) {
orderBy = orderBy || {
USER_LOGIN_TIME: 'desc'
};
let fields = FILEDS_USER_BASE;
let where = {};
where.and = {
USER_OPEN_SET: ['>', 0],
USER_STATUS: [
['>=', UserModel.STATUS.COMM],
['<=', UserModel.STATUS.VIP]
],
_pid: this.getProjectId()
};
if (util.isDefined(search) && search) {
where.or = [{
USER_NAME: ['like', search]
},
{
USER_ITEM: ['like', search]
},
{
USER_COMPANY: ['like', search]
},
{
USER_TRADE: ['like', search]
},
{
USER_TRADE_EX: ['like', search]
},
];
} else if (sortType && util.isDefined(sortVal)) {
let user = {};
switch (sortType) {
case 'companyDef':
where.and.USER_COMPANY_DEF = sortVal;
break;
case 'trade':
where.and.USER_TRADE = ['like', sortVal]
break;
case 'workStatus':
where.and.USER_WORK_STATUS = sortVal;
break;
case 'same_enroll':
user = await UserModel.getOne({
USER_MINI_OPENID: userId
});
if (!user) break;
where.and.USER_ENROLL = user.USER_ENROLL;
break;
case 'same_item':
user = await UserModel.getOne({
USER_MINI_OPENID: userId
});
if (!user) break;
where.and.USER_ITEM = user.USER_ITEM;
break;
case 'same_trade':
user = await UserModel.getOne({
USER_MINI_OPENID: userId
});
if (!user) break;
let trade = user.USER_TRADE;
if (trade.includes('-')) trade = trade.split('-')[0];
where.and.USER_TRADE = ['like', trade];
break;
case 'same_city':
user = await UserModel.getOne({
USER_MINI_OPENID: userId
});
if (!user) break;
where.and.USER_CITY = user.USER_CITY;
break;
case 'enroll':
switch (sortVal) {
case 1940:
where.and.USER_ENROLL = ['<', 1950];
break;
case 1950:
where.and.USER_ENROLL = [
['>=', 1950],
['<=', 1959]
];
break;
case 1960:
where.and.USER_ENROLL = [
['>=', 1960],
['<=', 1969]
];
break;
case 1970:
where.and.USER_ENROLL = [
['>=', 1970],
['<=', 1979]
];
break;
case 1980:
where.and.USER_ENROLL = [
['>=', 1980],
['<=', 1989]
];
break;
case 1990:
where.and.USER_ENROLL = [
['>=', 1990],
['<=', 1999]
];
break;
case 2000:
where.and.USER_ENROLL = [
['>=', 2000],
['<=', 2009]
];
break;
case 2010:
where.and.USER_ENROLL = ['>=', 2010];
break;
}
break;
case 'sort':
if (sortVal == 'new') {
orderBy = {
'USER_LOGIN_TIME': 'desc'
};
}
if (sortVal == 'last') {
orderBy = {
'USER_LOGIN_TIME': 'desc',
'USER_ADD_TIME': 'desc'
};
}
if (sortVal == 'enroll') {
orderBy = {
'USER_ENROLL': 'asc',
'USER_LOGIN_TIME': 'desc'
};
}
if (sortVal == 'info') {
orderBy = {
'USER_INFO_CNT': 'desc',
'USER_LOGIN_TIME': 'desc'
};
}
if (sortVal == 'album') {
orderBy = {
'USER_ALBUM_CNT': 'desc',
'USER_LOGIN_TIME': 'desc'
};
}
if (sortVal == 'meet') {
orderBy = {
'USER_MEET_CNT': 'desc',
'USER_LOGIN_TIME': 'desc'
};
}
if (sortVal == 'login_cnt') {
orderBy = {
'USER_LOGIN_CNT': 'desc',
'USER_LOGIN_TIME': 'desc'
};
}
break;
}
}
let result = await UserModel.getList(where, fields, orderBy, page, size, true, oldTotal, false);
return result;
}
界面设计 
     
后台界面设计
      Git开源代码
|