评论

基于微信小程序的竞赛答题小程序开发笔记(一)

中小学学科答题小程序,适合各中小学校方,老师或者家长。通过互动和参与式学习,小程序能够通过游戏化元素提升学习的积极性和参与度,从而提升学习效率,促进学生自主学习

# 开发背景调研

中小学学科答题小程序,适合各中小学校方,老师或者家长。通过互动和参与式学习,小程序能够通过游戏化元素提升学习的积极性和参与度,从而提升学习效率,促进学生自主学习


# 功能规划

- 分类题库:按照学科(数学、语文、英语等)和知识点进行分类,方便用户选择。

- 随机抽题:用户可以选择特定学科,系统随机生成题目。

- 答题竞赛: 模拟真实竞赛或考试环境,可以设置每场的时间。

- 解析详解:每道题目提供详细的解答和解析,帮助用户理解解题思路。

- 排行榜:展示用户的积分排名,促进比赛竞争。

- 后台-题库管理:支持直接录入,或者通过Excel导入题库(每次5000条)

- 后台-答题参数设置:可以设置竞赛开始状态,每次答题数目,每次答题时长限制,每天可参与答题竞赛次数等参数


# 概要设计

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0a18b997b1bf4ca9b4d935f434a4213b.png)


# 数据库设计


```

AnswerModel.DB_STRUCTURE = {

_pid: 'string|true',

ANSWER_ID: 'string|true',


ANSWER_USER_ID: 'string|true',

ANSWER_TYPE: 'int|true|default=0|comment=类型 0=测试,1=正式',


ANSWER_CATE_ID: 'string|true|default=0|comment=分类',

ANSWER_CATE_NAME: 'string|false|comment=分类冗余', 


ANSWER_DAY: 'string|true',


ANSWER_START: 'int|true|default=0',

ANSWER_END: 'int|true|default=0',

ANSWER_DURATION: 'string|false',


ANSWER_PER: 'int|true|default=0',

ANSWER_SCORE: 'int|true|default=0',

ANSWER_CNT: 'int|true|default=0',

ANSWER_SUCC_CNT: 'int|true|default=0',


ANSWER_LIST: 'array|true|default=[]',


ANSWER_ADD_TIME: 'int|true',

ANSWER_EDIT_TIME: 'int|true',

ANSWER_ADD_IP: 'string|false',

ANSWER_EDIT_IP: 'string|false',

};


QuestionModel.DB_STRUCTURE = {

_pid: 'string|true',

QUESTION_ID: 'string|true',


QUESTION_TITLE: 'string|true|comment=题目',

QUESTION_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中',


QUESTION_CATE_ID: 'string|true|default=0|comment=分类',

QUESTION_CATE_NAME: 'string|false|comment=分类冗余', 


QUESTION_ORDER: 'int|true|default=9999',


QUESTION_FORMS: 'array|true|default=[]',

QUESTION_OBJ: 'object|true|default={}', 


QUESTION_ADD_TIME: 'int|true',

QUESTION_EDIT_TIME: 'int|true',

QUESTION_ADD_IP: 'string|false',

QUESTION_EDIT_IP: 'string|false',

};

```

# 难点与实现


```

class QuestionService extends BaseProjectService {


async getAnswerDetail(id) {

return await AnswerModel.getOne(id);

}


async delAnswer(userId, id) {

return await AnswerModel.del({ ANSWER_USER_ID: userId, _id: id });

}


// 得分统计

async statAnswer(userId) { 

let where = {

ANSWER_USER_ID: userId,

ANSWER_TYPE: 1

}

let cnt = await AnswerModel.count(where);

let score = await AnswerModel.sum(where, 'ANSWER_SCORE');


let data = {

USER_ANSWER_CNT: cnt,

USER_ANSWER_SCORE: score

}

await UserModel.edit({ USER_MINI_OPENID: userId }, data);

}


// 每日可答题次数校验

async isAnswerTimes(userId, cateId) {

let dayCnt = 100;

let setup = await setupUtil.get('answer');

if (setup) {

setup = dataUtil.dbForms2Obj(setup);

dayCnt = Number(setup.daycnt);


if (setup.open != true) {

return '竞赛尚未开始!';

}

}


let where = {

ANSWER_CATE_ID: String(cateId),

ANSWER_USER_ID: userId,

ANSWER_TYPE: 1,

ANSWER_DAY: timeUtil.time('Y-M-D')

}

let cnt = await AnswerModel.count(where);

if (cnt >= dayCnt) {

return '每日竞赛答题最多' + dayCnt + '次,请明日再来!';

}


return '';

}


async saveMyAnswer(userId,

) { 

 

}


// 随机N条记录,生成本次题库

async genQuestion(userId, type, cateId) { 


return { questionList: [], maxTime:10 };

}



async getMyAnswerList(userId, {

search, // 搜索条件

sortType, // 搜索菜单

sortVal, // 搜索菜单

orderBy, // 排序 

page,

size,

isTotal = true,

oldTotal

}) {


orderBy = orderBy || {

'ANSWER_ADD_TIME': 'desc'

};

let fields = 'ANSWER_SCORE,ANSWER_CATE_NAME,ANSWER_TYPE,ANSWER_ADD_TIME,ANSWER_CNT,ANSWER_PER,ANSWER_SUCC_CNT,ANSWER_DURATION,ANSWER_START,ANSWER_END';


let where = {};

where.and = {

ANSWER_USER_ID: userId,

_pid: this.getProjectId() //复杂的查询在此处标注PID

};


if (util.isDefined(search) && search) {

where.or = [


];

} else if (sortType && util.isDefined(sortVal)) {

// 搜索菜单

switch (sortType) {

case 'type': {

where.and.ANSWER_TYPE = Number(sortVal);

break;

}

case 'cateId': {

where.and.ANSWER_CATE_ID = String(sortVal);

break;

}

case 'sort': {

orderBy = this.fmtOrderBySort(sortVal, 'ANSWER_ADD_TIME');

break;

}

}

}


return await AnswerModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);

}



async getScoreRankList({

search, // 搜索条件

sortType, // 搜索菜单

sortVal, // 搜索菜单

orderBy, // 排序 

page,

size,

isTotal = true,

oldTotal

}) {


orderBy = {

'USER_ANSWER_SCORE': 'desc'

};

let fields = 'USER_NAME,USER_ANSWER_SCORE';


let where = {};

where.and = {

_pid: this.getProjectId() //复杂的查询在此处标注PID

};


if (util.isDefined(search) && search) {

where.or = [


];

} else if (sortType && util.isDefined(sortVal)) {

// 搜索菜单

switch (sortType) {

case 'sort': {

orderBy = this.fmtOrderBySort(sortVal, 'ANSWER_ADD_TIME');

break;

}

}

}


return await UserModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);

}


}


```

# UI设计

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/083ab2c170f843ae9fefc833d578ea85.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/563a40a0859d4120a1000a880656dc86.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/544ec69b88fe4314a16e35fa8d9144cf.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6ed6b0f6704e4909971e847320c5c161.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/be1a4c6599e2466d827464336cfe2639.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/946c4c5c9d934f83babd153e7862941f.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/52911b7601f9477a91ce23f8f5d11102.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3cde181e030c48828f2c82e8495a4f6c.png)

# 后台管理系统设计

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/4a321f3967134450ae70de6ce03637ac.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/9fd31a6928e443bfb5129986bf91b969.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/954d95a78392400285a464bd98c2ebba.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/9bd2f3198ed04f39b7e8fd1d5349ac5a.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/72f1e04b599a40d3a8231d798b637d4e.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/331e814679ff435292dd25eb1cdce42c.png)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2748ec285d0b4386b8548d6818b8f9b7.png)

# git代码

[git代码网址](https://gitee.com/DoAmber/MidAnswer)

点赞 0
收藏
评论

1 个评论

登录 后发表内容