dever 5 years ago
parent
commit
d2da466369
6 changed files with 312 additions and 68 deletions
  1. 2 1
      database/exam.php
  2. 3 2
      database/info.php
  3. 32 7
      database/ranking.php
  4. 3 1
      database/user.php
  5. 17 0
      database/user_answer.php
  6. 255 57
      src/Api.php

+ 2 - 1
database/exam.php

@@ -312,7 +312,7 @@ return array
 					'desc' 		=> '结果图片',
 					'match' 	=> 'is_string',
 					'update'	=> 'image',
-					'key' 		=> 'Eself999',
+					'key' 		=> '1',
 				),
 
 				array
@@ -323,6 +323,7 @@ return array
 					'desc' 		=> '结果描述',
 					'match' 	=> 'is_string',
 					'update'	=> 'editor',
+					'key' 		=> '1',
 				),
 			),
 		),

+ 3 - 2
database/info.php

@@ -183,12 +183,13 @@ return array
 			'option' => array
 			(
 				'cate_id' => array('yes', 'in'),
-				'ids' => array('yes', 'in'),
+				'ids' => array('yes-id', 'in'),
 				'level_id' => 'yes',
+				'idno' => array('yes-id', 'notin'),
 				'state' => 1,
 			),
 			'type' => 'all',
-			'limit' => '0,10000',
+			//'limit' => '0,100000',
 			'col' => '*|id',
 		),
 	)

+ 32 - 7
database/ranking.php

@@ -18,7 +18,9 @@ return array
 			'default' 	=> '',
 			'desc' 		=> '',
 			'match' 	=> 'is_numeric',
-			'list'		=> true,
+			//'order'		=> 'desc',
+			'list_name'	=> '排名',
+			'list'		=> '{r}',
 		),
 
 		'user_id'		=> array
@@ -31,6 +33,18 @@ return array
 			//'list'		=> true,
 		),
 
+		/*
+		'exam_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '活动',
+			'default' 	=> '1',
+			'desc' 		=> '活动id',
+			'match' 	=> 'is_numeric',
+			'list'		=> '{exam_id} > 0 ? Dever::load("question/exam-one#name", {exam_id}) : "未知"',
+		),
+		*/
+
 		'uid'		=> array
 		(
 			'type' 		=> 'int-11',
@@ -38,7 +52,7 @@ return array
 			'default' 	=> '',
 			'desc' 		=> '用户',
 			'match' 	=> 'is_numeric',
-			'list'		=> true,
+			'list'		=> '{uid} > 0 ? Dever::load("passport/user-one#name", {uid}) : "匿名用户"',
 		),
 
 		'score'		=> array
@@ -49,6 +63,7 @@ return array
 			'desc' 		=> '本次分数',
 			'match' 	=> 'is_numeric',
 			'update'	=> 'text',
+			//'search'	=> 'order',
 			'order'		=> 'desc',
 			'list'		=> true,
 		),
@@ -56,9 +71,9 @@ return array
 		'times'		=> array
 		(
 			'type' 		=> 'int-11',
-			'name' 		=> '本次答题次数',
+			'name' 		=> '答题次数',
 			'default' 	=> '0',
-			'desc' 		=> '本次答题次数',
+			'desc' 		=> '答题次数',
 			'match' 	=> 'is_string',
 			'update'	=> 'text',
 			'list'		=> true,
@@ -80,20 +95,30 @@ return array
 			'match' 	=> array('is_numeric', time()),
 			'desc' 		=> '',
 			'search'	=> 'date',
-			'order'		=> 'desc',
 			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
 		),
 	),
 
 	'manage' => array
 	(
-		'insert' => false,
+		//'insert' => false,
 		'edit' => false,
 		'delete' => false,
 	),
 
 	'request' => array
 	(
-		
+		# 获取最新一条的用户信息
+		'getTotal' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'exam_id' => 'yes',
+				'score' => array('yes', '<'),
+				'state' => 1,
+			),
+			'type' => 'count',
+		),
 	)
 );

+ 3 - 1
database/user.php

@@ -40,7 +40,7 @@ return array
 			'match' 	=> 'is_string',
 			'update'	=> 'text',
 			'search'	=> 'fulltext',
-			'list'		=> true,
+			'list'		=> '{uid} > 0 ? Dever::load("passport/user-one#name", {uid}) : "匿名用户"',
 		),
 
 		'exam_id'		=> array
@@ -96,6 +96,7 @@ return array
 			'list'		=> true,
 		),
 
+		/*
 		'user_info_ids'		=> array
 		(
 			'type' 		=> 'varchar-300',
@@ -106,6 +107,7 @@ return array
 			'update'	=> 'textarea',
 			//'list'		=> true,
 		),
+		*/
 
 		'index'		=> array
 		(

+ 17 - 0
database/user_answer.php

@@ -111,4 +111,21 @@ return array
 	(
 		
 	),
+
+	'request' => array
+	(
+		'getAll' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'uid' => 'yes',
+				'info_id' => 'yes',
+				'user_id' => 'yes',
+				'state' => 1,
+			),
+			'type' => 'all',
+			'col' => 'info_id,uid,user_id,id|info_id',
+		),
+	)
 );

+ 255 - 57
src/Api.php

@@ -10,6 +10,8 @@ class Api
 	private $exam = array();
 	private $question = array();
 	private $user = array();
+	private $redis;
+	private $rank = DEVER_PROJECT . '_score';
 
 	/**
 	 * 获取某个答题规则的数据接口 api.get?id=1
@@ -50,9 +52,24 @@ class Api
 			$result['question'] = $this->getQuestionInfo();
 		}
 
+		$result['exam']['continue_num'] = $this->getOverContinueNum();
+
+		unset($result['exam']['level_ids']);
+
 		return $result;
 	}
 
+	private function getOverContinueNum()
+	{
+		$continue = $this->getContinueNum();
+
+		if ($continue['id'] > 0) {
+			$this->exam['continue_num'] = $this->exam['continue_num'] - $continue['num'];
+		}
+
+		return $this->exam['continue_num'];
+	}
+
 	/**
 	 * 获取用户信息接口 api.getUserInfo?uid=1
 	 *
@@ -60,15 +77,106 @@ class Api
 	 */
 	public function getUserInfo()
 	{
-		$this->getUser();
-		$this->result();
+		$this->getUser(true);
+
+		if ($this->user['uid'] > 0) {
+			$info = Dever::db('question/ranking')->one(array('uid' => $this->user['uid']));
+			$this->user['ranking_score'] = $this->user['score'];
+			if ($info) {
+				$this->user['ranking_score'] = $info['score'];
+			}
+
+			$this->result();
+
+			
+			$result['user'] = $this->user;
+			
+			$where['score'] = $this->user['score'];
+			$result['total'] = Dever::db('question/ranking')->getTotal($where);
+		} else {
+			$this->user['ranking_score'] = $this->user['score'];
+			$result['user'] = $this->user;
+			$result['total'] = 0;
+		}
 
 		$result['exam'] = $this->exam;
-		$result['user'] = $this->user;
-		
+
+		return $result;
+	}
+
+	/**
+	 * 排行榜接口
+	 *
+	 * @return mixed
+	 */
+	public function ranking()
+	{
+		$uid = Dever::input('uid');
+		$this->redis();
+		$result = array();
+		if ($this->redis) {
+			$ranking = $this->redis->zRevRange($this->rank, 0, 7, true);
+			
+			$rank = -1;
+			$data = array();
+			if ($ranking) {
+				$i = 0;
+				foreach ($ranking as $k => $v) {
+					if ($k) {
+						$data[$i] = Dever::db('passport/user')->one($k);
+						$data[$i]['score'] = $v;
+						$data[$i]['rank'] = $i;
+						# 这个用户是不是自己
+						$data[$i]['my'] = 2;
+						if ($k == $uid) {
+							$data[$i]['my'] = 1;
+							$rank = $i;
+						}
+						$i++;
+					}
+				}
+			}
+
+			$result['list'] = $data;
+
+			if ($uid) {
+				if ($rank < 0) {
+					# 获取当前用户的排名
+					$rank = $this->redis->zRevRank($this->rank, $uid);
+				}
+
+				$user = Dever::db('passport/user')->one($uid); 
+				$ranking = Dever::db('question/ranking')->one(array('option_uid' => $uid));
+				$user['score'] = $ranking['score'];
+
+				$result['user'] = $user;
+				$result['user']['rank'] = $rank;
+			}
+		}
+
 		return $result;
 	}
 
+	/**
+	 * 定时更新所有排行榜数据接口 可以将这个放到cron中,定时执行 question/api.upRanking
+	 *
+	 * @return mixed
+	 */
+	public function upRanking()
+	{
+		$this->redis();
+		if ($this->redis) {
+			$data = Dever::db('question/ranking')->state();
+		
+			if ($data) {
+				foreach ($data as $k => $v) {
+					$this->redis->zAdd($this->rank, $v['score'], $v['uid']);
+				}
+			}
+		}
+		return true;
+	}
+
 	/**
 	 * 从某个活动中抽取题目并保存下来
 	 * $category 分类id
@@ -91,10 +199,10 @@ class Api
 			$where['level_id'] = $this->getLevel($level_ids, $index);
 		}
 
-		$data = Dever::db('question/info')->getAll($where);
-
 		$question_id = Dever::input('question_id');
 
+		$data = Dever::db('question/info')->getAll($where);
+
 		if ($question_id > 0) {
 			if (isset($data[$question_id])) {
 				return array($data[$question_id]);
@@ -105,19 +213,39 @@ class Api
 
 		$result = array();
 		if ($data && $num) {
-			$count = count($data);
-			if ($num > $count) {
-				$num = $count;
+			$result = $this->getQuestionOne($question_id, $data, $num);
+		}
+
+		return $result;
+	}
+
+	private function getQuestionOne($question_id, $data, $num)
+	{
+		$one['user_id'] = $this->user['id'];
+		$one['uid'] = Dever::input('uid');
+		if (!$question_id && $num == 1) {
+			$answer = Dever::db('question/user_answer')->getAll($one);
+			# 去除已经答过的题
+			if ($answer) {
+				$data = array_diff_key($data, $answer);
 			}
-			$keys = array_rand($data, $num);
+		}
 
-			if (is_array($keys)) {
-				foreach ($keys as $k => $v) {
-					$result[$v] = $data[$v];
-				}
-			} else {
-				$result[0] = $data[$keys];
+		$count = count($data);
+		if ($num > $count) {
+			$num = $count;
+		}
+
+		$result = array();
+
+		$keys = array_rand($data, $num);
+
+		if (is_array($keys)) {
+			foreach ($keys as $k => $v) {
+				$result[$v] = $data[$v];
 			}
+		} else {
+			$result[0] = $data[$keys];
 		}
 
 		return $result;
@@ -215,6 +343,12 @@ class Api
 
 		$times = 1;
 		if($finish) {
+			if ($this->user && $finish['times'] >= $this->user['times']) {
+				$update['where_id'] = $this->user['id'];
+				$update['status'] = 3;
+				Dever::db('question/user')->update($update);
+				return $this->initUser($question);
+			}
 			$times = $finish['times'] + 1;
 		}
 
@@ -265,6 +399,14 @@ class Api
 				}
 			}
 
+			if (isset($this->exam['result']['info']) && $this->exam['result']['info']) {
+				$this->exam['result']['info_text'] = strip_tags($this->exam['result']['info']);
+			}
+
+			if (isset($this->exam['result']['pic']) && $this->exam['result']['pic']) {
+				$this->exam['result']['pic_https'] = str_replace('http://' , 'https://', $this->exam['result']['pic']);
+			}
+
 			unset($this->exam['content']);
 		} else {
 			unset($this->exam['content']);
@@ -310,14 +452,20 @@ class Api
 	 *
 	 * @return mixed
 	 */
-	private function getUser()
+	private function getUser($state = false)
 	{
 		$uid = $this->getUid();
 		//$id = Dever::input('user_data_id');
 		$this->user = Dever::db('question/user')->get(array('where_uid' => $uid));
 
 		if (!$this->user) {
-			Dever::alert('错误的用户信息');
+			if ($state == false) {
+				Dever::alert('错误的用户信息');
+			} else {
+				$this->user['id'] = -1;
+				$this->user['uid'] = -1;
+				$this->user['score'] = 0;
+			}
 		}
 
 		$this->exam = Dever::db('question/exam')->one($this->user['exam_id']);
@@ -367,6 +515,7 @@ class Api
 			if (!is_array($data)) {
 				$data = Dever::db('question/info')->one($data);
 			}
+
 			$data['index'] = $this->user['index'];
 			$data['num'] = $this->user['num'];
 
@@ -376,7 +525,7 @@ class Api
 					unset($data['content'][$k]['score']);
 				}
 			} else {
-				$data['user_info_ids'] = $this->user['user_info_ids'];
+				//$data['user_info_ids'] = $this->user['user_info_ids'];
 				$data['score'] = $this->user['score'];
 				$data['total'] = $this->exam['num'];
 			}
@@ -411,6 +560,8 @@ class Api
 		if ($one) {
 			$update['status'] = $this->user['status'];
 		} else {
+
+			/*
 			if ($this->exam['continue'] >= 2 && $this->exam['continue_times'] > 0) {
 				$cur = time();
 				# 后端超时设置
@@ -421,6 +572,7 @@ class Api
 					$option = -1;
 				}
 			}
+			*/
 
 			$this->hidden = false;
 			$data = $this->getQuestionInfo();
@@ -436,6 +588,7 @@ class Api
 				Dever::alert('错误的选项信息');
 			}
 
+			/*
 			$update['user_info_ids'] = $data['user_info_ids'];
 			if ($update['user_info_ids']) {
 				$update['user_info_ids'] = explode(',', $update['user_info_ids']);
@@ -444,6 +597,7 @@ class Api
 			} else {
 				$update['user_info_ids'] = $data['id'];
 			}
+			*/
 
 			$update['score'] = $data['score'] + $data['content'][$option]['score'];
 			$update['where_id'] = $data['user_data_id'];
@@ -490,6 +644,7 @@ class Api
 		$result['status'] = $update['status'];
 		$result['question_id'] = $question_id;
 		$result['option'] = $option;
+		$result['continue_num'] = $this->getOverContinueNum();
 		return $result;
 	}
 
@@ -505,9 +660,10 @@ class Api
 			'uid' => $this->user['uid'],
 			'exam_id' => $this->user['exam_id'],
 		));
-
+		$state = false;
 		if ($ranking) {
 			if ($ranking['score'] < $score) {
+				$state = true;
 				$update['uid'] = $this->user['uid'];
 				$update['exam_id'] = $this->user['exam_id'];
 				$update['score'] = $score;
@@ -517,12 +673,20 @@ class Api
 			}
 			
 		} else {
+			$state = true;
 			$insert['uid'] = $this->user['uid'];
 			$insert['exam_id'] = $this->user['exam_id'];
 			$insert['score'] = $score;
 			$insert['times'] = $this->user['times'];
 			Dever::db('question/ranking')->insert($insert);
 		}
+
+		if ($state == true) {
+			$this->redis();
+			if ($this->redis) {
+				$this->redis->zAdd($this->rank, $score, $this->user['uid']);
+			}
+		}
 	}
 
 	/**
@@ -530,7 +694,7 @@ class Api
 	 *
 	 * @return mixed
 	 */
-	public function continue()
+	public function go_continue()
 	{
 		$this->getUser();
 		# 先验证当前的状态是否是3
@@ -555,7 +719,7 @@ class Api
 	 *
 	 * @return mixed
 	 */
-	public function go_continue()
+	public function go_all_continue()
 	{
 		$this->getUser();
 		# 先验证当前的状态是否是3
@@ -583,41 +747,8 @@ class Api
 	{
 		$continue_num = $this->exam['continue_num'];
 		if ($continue_num > 0) {
-			$continue_num_user = $this->exam['continue_num_user'];
-			$continue_num_type = $this->exam['continue_num_type'];
-			$continue_num_type_times = $this->exam['continue_num_type_times'];
-
-			$where['exam_id'] = $this->user['exam_id'];
-			if ($continue_num_user == 1) {
-				$where['uid'] = $this->user['uid'];
-			} elseif ($continue_num_user == 2) {
-				$where['user_id'] = $this->user['id'];
-			}
-
-			$continue = Dever::db('question/continue')->one($where);
-
-			if ($continue) {
-				$time = time();
-				# 查看时间间隔
-				if ($continue_num_type == 1) {
-					# 按照自然天
-					$continue_num_type_times = 0;
-					$date = Dever::maketime(date('Y-m-d 00:00:00', strtotime("+1 day", $continue['cdate'])));
-					if ($time >= $date) {
-						$continue['num'] = 0;
-					}
-				} elseif ($continue_num_type == 2) {
-					# 按照小时
-					$continue_num_type_times = $continue_num_type_times * 3600;
-				} elseif ($continue_num_type == 3) {
-					# 按照天
-					$continue_num_type_times = $continue_num_type_times * 86400;
-				}
-
-				if ($continue_num_type_times > 0 && $time - $continue['cdate'] >= $continue_num_type_times) {
-					$continue['num'] = 0;
-				}
-
+			$continue = $this->getContinueNum();
+			if ($continue['id'] > 0) {
 				if ($continue['num'] < $continue_num) {
 					#可以继续复活
 					$update['where_id'] = $continue['id'];
@@ -636,6 +767,51 @@ class Api
 		}
 	}
 
+	private function getContinueNum()
+	{
+		$continue_num_user = $this->exam['continue_num_user'];
+		
+		$where['exam_id'] = $this->user['exam_id'];
+		if ($continue_num_user == 1) {
+			$where['uid'] = $this->user['uid'];
+		} elseif ($continue_num_user == 2) {
+			$where['user_id'] = $this->user['id'];
+		}
+
+		$continue = Dever::db('question/continue')->one($where);
+
+		if ($continue) {
+			$time = time();
+			$continue_num_type = $this->exam['continue_num_type'];
+			$continue_num_type_times = $this->exam['continue_num_type_times'];
+
+			# 查看时间间隔
+			if ($continue_num_type == 1) {
+				# 按照自然天
+				$continue_num_type_times = 0;
+				$date = Dever::maketime(date('Y-m-d 00:00:00', strtotime("+1 day", $continue['cdate'])));
+				if ($time >= $date) {
+					$continue['num'] = 0;
+				}
+			} elseif ($continue_num_type == 2) {
+				# 按照小时
+				$continue_num_type_times = $continue_num_type_times * 3600;
+			} elseif ($continue_num_type == 3) {
+				# 按照天
+				$continue_num_type_times = $continue_num_type_times * 86400;
+			}
+
+			if ($continue_num_type_times > 0 && $time - $continue['cdate'] >= $continue_num_type_times) {
+				$continue['num'] = 0;
+			}
+		} else {
+			$continue['id'] = 0;
+			$continue['num'] = 0;
+		}
+
+		return $continue;
+	}
+
 	/**
 	 * 重新挑战接口,重新开始,当前结束
 	 *
@@ -650,4 +826,26 @@ class Api
 
 		return true;
 	}
+
+	/**
+	 * 初始化redis
+	 *
+	 * @return mixed
+	 */
+	private function redis()
+	{
+		$this->redis = false;
+		if ($this->redis) {
+			return $this->redis;
+		}
+		$config = Dever::config('database')->redis;
+		if ($config) {
+			if (class_exists('\\Redis')) {
+				$this->redis = new \Redis;
+				$this->redis->connect($config['host'], $config['port']);
+			}
+		}
+
+		return $this->redis;
+	}
 }