# ClassWrong.md #
## 1. 错题列表
*D:\wamp\www\ketang.test\weike\protected\controllers\ClassWrongController.php*
```
/**
* 错题列表
* TODO 未实现区分快捷试卷, 未实现小题型ID
* @throws Exception
* @author wuzhc 2018-02-06
*/
public function actionGetLists()
{
$userID = $this->getSession()->fdUserID;
$classID = RequestUtils::getNormalRequest('classID');
$subjectID = RequestUtils::getNormalRequest('subjectID');
$aliasID = RequestUtils::getNormalRequest('aliasID'); // 小题型ID
$begin = RequestUtils::getNormalRequest('begin'); // 单位毫秒
$end = RequestUtils::getNormalRequest('end'); // 单位毫秒
$len = RequestUtils::getNormalRequest('len', 10);
$start = RequestUtils::getNormalRequest('start', 0);
$sort = RequestUtils::getNormalRequest('sort', 'date_desc');
$totalInit = RequestUtils::getNormalRequest('totalInit', 0);
if (!$classID || !$subjectID) {
throw new Exception('参数错误');
}
$classIDs = $this->getClassIDs();
if ($classID) {
if (!in_array($classID, $classIDs)) {
ResponseUtils::json(null, 1, '非本人班级不能查看');
}
}
// 条件
$args = array(
'begin' => $begin,
'end' => $end,
'classID' => $classID,
'subjectID' => $subjectID,
// 'alias' => $aliasID,
'right' => WK::EXER_RECORD_WRONG, // 错题
'scene' => array_keys($this->scene),
);
// 总数
$total = null;
if ($totalInit == 1) {
$total = V2WrongService::factory()->getWrongTotalFromMongo($args);
if ($total == 0) {
ResponseUtils::json(array(
'data' => array(
'list' => array(),
'total' => 0
)
));
}
}
// 列表
$args = array_merge($args, array(
'len' => $len,
'start' => $start,
'sort' => $sort,
));
$res = V2WrongService::factory()->getWrongsFromMongo($args);
if (!$res['result']) {
ResponseUtils::json(array('data' => array()));
}
$data = array();
foreach ($res['result'] as $r) {
/** @var Exercise $exercise */
$exercise = Exercise::model()->with('diff')->findByPk($r['exid']);
if (!$exercise) {
continue;
}
$temp = array();
$temp['id'] = $exercise->id;
$temp['cid'] = $exercise->fdContentID;
$temp['date'] = date('Y-m-d H:i:s', $r['date']->sec);
$temp['errorNum'] = $r['count'];
$temp['typeID'] = $exercise->fdExerciseTypeID;
$temp['alias'] = Yii::app()->params['EXERCISETYPEALIAS'][$exercise->fdAlias];
$temp['diff'] = $exercise->diff->fdValue;
$temp['text'] = $exercise->fdText;
$temp['isFavorite'] = V2ContentService::factory()
->handelFavorite(WK::FAVOR_CHECK, WK::QUESBANK_TYPEID, $exercise->id, $userID) ? 1 : 0;
$data['list'][] = $temp;
}
ResponseUtils::json(array('data' => $data, 'total' => $total));
}
```
## 2. 总数
*D:\wamp\www\ketang.test\weike\protected\service\service2\V2WrongService.php*
```
/**
* 从mongo获取错题总数
* @param $args
* @author wuzhc 2018-01-16
* @return bool
*/
public function getWrongTotalFromMongo($args)
{
$query = array();
// 学校
if ($args['schoolID']) {
$query['school'] = (int)$args['schoolID'];
}
// 班级
if (!empty($args['classID'])) {
if (is_numeric($args['classID'])) {
$query['class'] = (int)$args['classID'];
} elseif (is_array($args['classID'])) {
$query['class'] = array('$in' => $args['classID']);
}
}
// 场景
if (!empty($args['scene'])) {
if (is_numeric($args['scene'])) {
$query['scene'] = (int)$args['scene'];
} elseif (is_array($args['scene'])) {
$query['scene'] = array('$in' => $args['scene']);
}
}
// tag
if (!empty($args['tagID'])) {
$query['tags.tv'] = (int)$args['tagID'];
}
if (!empty($args['tagType'])) {
$query['tags.tid'] = (int)$args['tagType'];
}
// 正确或错误
if (isset($args['right'])) {
$query['right'] = (int)$args['right'];
}
// 科目
if (!empty($args['subjectID'])) {
$query['subject'] = (int)$args['subjectID'];
}
// 年级
if (!empty($args['gradeID'])) {
$query['grade'] = (int)$args['gradeID'];
}
// 时间
if ($args['begin'] && $args['end']) {
$query['date'] = array(
'$gte' => new MongoDate($args['begin'] / 1000),
'$lte' => new MongoDate($args['end'] / 1000),
);
}
// 是否为快捷试卷
if (is_numeric($args['isQuickExam'])) {
$query['isQuickExam'] = (int)$args['isQuickExam'];
}
// 题目小题型 todo 类型不一致,暂时用in解决,后期应该统一为int类型
if ($args['exerAlias']) {
$query['exerAlias'] = array(
'$in' => array((string)$args['exerAlias'], (int)$args['exerAlias'])
);
}
/** @var EMongoClient $mongo */
$mongo = Yii::app()->mongodb;
$collection = $mongo->selectCollection('exer_record');
$res = $collection->aggregate(array(
array('$match' => $query),
array('$group' => array('_id' => '$exid')),
array('$group' => array('_id' => '', 'total' => array('$sum' => 1))),
));
return $res['result'] ? $res['result'][0]['total'] : 0;
}
```
## 3. 列表
```
/**
* 从mongo获取错题列表
* @param $args
* @return array
* @author wuzhc 2017-11-01
*/
public function getWrongsFromMongo($args)
{
/** @var EMongoClient $mongo */
$mongo = Yii::app()->mongodb;
$collection = $mongo->selectCollection('exer_record');
// 管道
$pipeline = array();
// 学校
if ($args['schoolID']) {
$match['$match']['school'] = (int)$args['schoolID'];
}
// 班级
if (!empty($args['classID'])) {
if (is_numeric($args['classID'])) {
$match['$match']['class'] = (int)$args['classID'];
} elseif (is_array($args['classID'])) {
$match['$match']['class'] = array('$in' => $args['classID']);
}
}
// 场景
if (!empty($args['scene'])) {
if (is_numeric($args['scene'])) {
$match['$match']['scene'] = (int)$args['scene'];
} elseif (is_array($args['scene'])) {
$match['$match']['scene'] = array('$in' => $args['scene']);
}
}
// tag
if (!empty($args['tagID'])) {
$match['$match']['tags.tv'] = (int)$args['tagID'];
}
if (!empty($args['tagType'])) {
$match['$match']['tags.tid'] = (int)$args['tagType'];
}
// 正确或错误
if (isset($args['right'])) {
$match['$match']['right'] = (int)$args['right'];
}
// 科目
if (!empty($args['subjectID'])) {
$match['$match']['subject'] = (int)$args['subjectID'];
}
// 年级
if (!empty($args['gradeID'])) {
$match['$match']['grade'] = (int)$args['gradeID'];
}
// 时间
if ($args['begin'] && $args['end']) {
$match['$match']['date'] = array(
'$gte' => new MongoDate($args['begin'] / 1000),
'$lte' => new MongoDate($args['end'] / 1000),
);
}
// 是否为快捷试卷
if (is_numeric($args['isQuickExam'])) {
$match['$match']['isQuickExam'] = (int)$args['isQuickExam'];
}
// 题目小题型 todo 类型不一致,暂时用in解决,后期应该统一为int类型
if ($args['exerAlias']) {
$match['$match']['exerAlias'] = array(
'$in' => array((string)$args['exerAlias'], (int)$args['exerAlias'])
);
}
if (!empty($match)) {
array_push($pipeline, $match);
}
$group['$group'] = array(
'_id' => array(
'exid' => '$exid',
),
'count' => array(
'$sum' => 1
),
'date' => array(
'$max' => '$date'
),
'aeid' => array(
'$max' => '$aeid'
),
'grade' => array(
'$addToSet' => '$grade'
),
'subject' => array(
'$addToSet' => '$subject'
),
);
array_push($pipeline, $group);
$project['$project'] = array(
'exid' => '$_id.exid',
'grade' => '$grade',
'date' => '$date',
'count' => '$count',
'subject' => '$subject',
'aeid' => '$aeid'
);
array_push($pipeline, $project);
if (!empty($args['sort'])) { // 格式errors_desc或error_asc
list($field, $mode) = explode('_', $args['sort'], 2);
if ($field == 'errors') { // 按错题数量排序
$sort['$sort'] = array(
'count' => strcasecmp($mode, 'desc') ? 1 : -1,
'_id' => -1
);
} elseif ($field == 'date') { // 按最近错题时间排序
$sort['$sort'] = array(
'date' => strcasecmp($mode, 'desc') ? 1 : -1,
'_id' => -1
);
}
if (isset($sort)) {
array_push($pipeline, $sort);
}
}
if (!empty($args['start'])) {
$skip['$skip'] = (int)$args['start'];
array_push($pipeline, $skip);
}
if (!empty($args['len'])) {
$limit['$limit'] = (int)$args['len'];
array_push($pipeline, $limit);
}
return $collection->aggregate($pipeline);
}
```
- 说明
- 开发任务
- 星课-真光
- 课表
- Excel Down
- 调课
- 课表修改
- 课表代码分析
- 课堂
- 课堂:应用商店通信管理协议
- 教师账号强制绑定手机或邮箱
- 强制绑定手机和修改密码的规则
- 学堂
- 课程学习:讨论功能
- 后台:课程讨论管理
- 课程直播接口
- 学习统计功能(旧版)
- 学习统计功能(新版)
- 同步课程统计功能
- 同步课程编辑-新增视频
- 第三方接口
- 学科网
- 安徽第三方
- 大赛
- 管控系统
- 日志管理
- 设备日志
- 平板接口
- 渝教
- 教学总结
- 空白目录
- Yii 1.1
- 学堂架构
- Yii 1.1一些方法的解读
- MVCS结构
- 基础使用语法
- 创建1个新模块
- 关联模型
- CDbCriteria
- 学生-课堂记录
- 学生端页面展示
- 教师端页面展示
- 编辑课程文档
- SQL
- 课堂项目运行入口
- 上传资源示意图
- 行为
- PHPStorm
- 源码阅读
- 会诊答卷页面
- 考点练习
- 资源首页
- 同步课程
- 同步课程:章节信息
- 升学复习
- 统计图-范例
- 模块
- 非法词
- 服务层
- MongoDB类
- 学堂作答记录从Mongo新集合获取数据
- MongoYii
- 错题集
- 小技巧
- 完善资料
- 邮件发送
- K12
- JSpang视频课程
- MongoDB
- 创业
- 项目
- 包包