概要设计
打卡是一种习惯的养成,是当下最风行、最受欢迎的工具,利用塌景宽泛多样; 各个人为了促活会定期发展一些闯关打卡流动;找一群气味相投的人,一起去打卡
功能定位:集学习、趣味、生存、静止于一身的打卡小程序
用户群:面向学校学生、学生家长、老师、各种趣味个人(跑步,静止,体育,艺术等)
次要模块:打卡我的项目列表,打卡排行,每日动静,后盾打卡项目管理,后盾打卡记录治理,后盾打卡记录导出等性能
性能布局
数据字典
EnrollModel.DB_STRUCTURE = {
_pid: 'string|true',
ENROLL_ID: 'string|true',
ENROLL_TITLE: 'string|true|comment= 题目',
ENROLL_STATUS: 'int|true|default=1|comment= 状态 0= 未启用,1= 应用中',
ENROLL_CATE_ID: 'string|true|default=0|comment= 分类',
ENROLL_CATE_NAME: 'string|false|comment= 分类冗余',
ENROLL_START: 'int|false|comment= 开始工夫',
ENROLL_END: 'int|false|comment= 完结工夫',
ENROLL_DAY_CNT: 'int|false|comment= 继续天数',
ENROLL_ORDER: 'int|true|default=9999',
ENROLL_VOUCH: 'int|true|default=0',
ENROLL_FORMS: 'array|true|default=[]',
ENROLL_OBJ: 'object|true|default={}',
ENROLL_JOIN_FORMS: 'array|true|default=[]',
ENROLL_QR: 'string|false',
ENROLL_VIEW_CNT: 'int|true|default=0',
ENROLL_JOIN_CNT: 'int|true|default=0',
ENROLL_USER_CNT: 'int|true|default=0',
ENROLL_USER_LIST: 'array|true|default=[]|comment={name,id,pic}',
ENROLL_ADD_TIME: 'int|true',
ENROLL_EDIT_TIME: 'int|true',
ENROLL_ADD_IP: 'string|false',
ENROLL_EDIT_IP: 'string|false',
};
EnrollJoinModel.DB_STRUCTURE = {
_pid: 'string|true',
ENROLL_JOIN_ID: 'string|true',
ENROLL_JOIN_ENROLL_ID: 'string|true|comment= 打卡 PK',
ENROLL_JOIN_USER_ID: 'string|true|comment= 用户 ID',
ENROLL_JOIN_DAY: 'string|true|comment= 日期',
ENROLL_JOIN_FORMS: 'array|true|default=[]|comment= 表单',
ENROLL_JOIN_STATUS: 'int|true|default=1|comment= 状态 1= 胜利',
ENROLL_JOIN_ADD_TIME: 'int|true',
ENROLL_JOIN_EDIT_TIME: 'int|true',
ENROLL_JOIN_ADD_IP: 'string|false',
ENROLL_JOIN_EDIT_IP: 'string|false',
};
外围难点
// 获取以后打卡状态
getJoinStatusDesc(enroll) {
let timestamp = this._timestamp;
if (enroll.ENROLL_STATUS == 0)
return '已进行';
else if (enroll.ENROLL_START > timestamp)
return '未开始';
else if (enroll.ENROLL_END <= timestamp)
return '已完结';
else
return '进行中';
}
// 获取某日动静
async getEnrollJoinByDay(enrollId, day = '') {if (!day) day = timeUtil.time('Y-M-D');
let where = {
ENROLL_JOIN_ENROLL_ID: enrollId,
ENROLL_JOIN_DAY: day,
ENROLL_JOIN_STATUS: EnrollJoinModel.STATUS.SUCC
}
let joinParams = {
from: UserModel.CL,
localField: 'ENROLL_JOIN_USER_ID',
foreignField: 'USER_MINI_OPENID',
as: 'user',
};
let orderBy = {ENROLL_JOIN_ADD_TIME: 'desc'}
let list = await EnrollJoinModel.getListJoin(joinParams, where, 'user.USER_NAME,user.USER_PIC', orderBy, 1, 100, false, 0);
return list.list;
}
// 获取某流动排行
async getEnrollUserRank(enrollId) {
let where = {ENROLL_USER_ENROLL_ID: enrollId}
let joinParams = {
from: UserModel.CL,
localField: 'ENROLL_USER_MINI_OPENID',
foreignField: 'USER_MINI_OPENID',
as: 'user',
};
let orderBy = {ENROLL_USER_JOIN_CNT: 'desc'}
let fields = 'ENROLL_USER_JOIN_CNT,ENROLL_USER_LAST_DAY,user.USER_NAME,user.USER_PIC';
let list = await EnrollUserModel.getListJoin(joinParams, where, fields, orderBy, 1, 100, false, 0);
return list.list;
}
/** 浏览信息 */
async viewEnroll(userId, id) {
let fields = '*';
let where = {
_id: id,
ENROLL_STATUS: EnrollModel.STATUS.COMM
}
let enroll = await EnrollModel.getOne(where, fields);
if (!enroll) return null;
EnrollModel.inc(id, 'ENROLL_VIEW_CNT', 1);
// 判断用户今日是否有打卡
let whereJoin = {
ENROLL_JOIN_USER_ID: userId,
ENROLL_JOIN_ENROLL_ID: id,
ENROLL_JOIN_DAY: timeUtil.time('Y-M-D'),
ENROLL_JOIN_STATUS: EnrollJoinModel.STATUS.SUCC
}
let enrollJoin = await EnrollJoinModel.getOne(whereJoin);
if (enrollJoin) {enroll.myEnrollJoinId = enrollJoin._id;}
else {enroll.myEnrollJoinId = '';}
// 某日打卡列表
enroll.activity = await this.getEnrollJoinByDay(id);
// 打卡日期数组
let dayList = [];
let start = timeUtil.timestamp2Time(enroll.ENROLL_START, 'Y-M-D');
start = timeUtil.time2Timestamp(start);
let today = timeUtil.time2Timestamp(timeUtil.time('Y-M-D'));
for (let k = start; k <= today;) {let month = timeUtil.timestamp2Time(k, 'M 月');
if (month.startsWith('0')) month = month.substring(1);
let date = timeUtil.timestamp2Time(k, 'D');
let day = timeUtil.timestamp2Time(k, 'Y-M-D');
dayList.push({month, date, day});
k = k + 86400 * 1000;
}
enroll.dayList = dayList;
// 排行榜
let rankList = await this.getEnrollUserRank(id);
enroll.rankList = rankList;
return enroll;
}
/** 获得分页列表 */
async getEnrollList({
search, // 搜寻条件
sortType, // 搜寻菜单
sortVal, // 搜寻菜单
orderBy, // 排序
page,
size,
isTotal = true,
oldTotal
}) {
orderBy = orderBy || {
'ENROLL_ORDER': 'asc',
'ENROLL_ADD_TIME': 'desc'
};
let fields = 'ENROLL_USER_LIST,ENROLL_JOIN_CNT,ENROLL_OBJ,ENROLL_USER_CNT,ENROLL_TITLE,ENROLL_START,ENROLL_END,ENROLL_ORDER,ENROLL_STATUS,ENROLL_CATE_NAME,ENROLL_OBJ';
let where = {};
where.and = {_pid: this.getProjectId() // 简单的查问在此处标注 PID
};
where.and.ENROLL_STATUS = EnrollModel.STATUS.COMM; // 状态
if (util.isDefined(search) && search) {
where.or = [{ENROLL_TITLE: ['like', search]
},];
} else if (sortType && util.isDefined(sortVal)) {
// 搜寻菜单
switch (sortType) {
case 'cateId': {if (sortVal) where.and.ENROLL_CATE_ID = String(sortVal);
break;
}
case 'sort': {orderBy = this.fmtOrderBySort(sortVal, 'ENROLL_ADD_TIME');
break;
}
}
}
return await EnrollModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);
}
用户打卡 UI 设计
后盾零碎 UI 设计
源码
gitee 源码地址