# 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
- 創業
- 項目
- 包包