dever 5 years ago
commit
3f178634c5
9 changed files with 1520 additions and 0 deletions
  1. 88 0
      database/cate.php
  2. 236 0
      database/exam.php
  3. 195 0
      database/info.php
  4. 105 0
      database/level.php
  5. 99 0
      database/ranking.php
  6. 197 0
      database/user.php
  7. 114 0
      database/user_answer.php
  8. 8 0
      index.php
  9. 478 0
      src/Api.php

+ 88 - 0
database/cate.php

@@ -0,0 +1,88 @@
+<?php
+
+return array
+(
+	# 表名
+	'name' => 'cate',
+	# 显示给用户看的名称
+	'lang' => '分类管理',
+	'order' => 1,
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			'list'		=> true,
+		),
+		
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-80',
+			'name' 		=> '名称',
+			'default' 	=> '',
+			'desc' 		=> '名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'reorder'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '排序(数值越大越靠前)',
+			'default' 	=> '1',
+			'desc' 		=> '请输入排序',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'search'	=> 'order',
+			'list_name' => '排序',
+			'list'		=> true,
+			'order'		=> 'desc',
+			'edit'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+	
+	# 管理功能
+	'manage' => array
+	(
+
+	),
+
+	# 默认值
+	'default' => array
+	(
+		'col' => 'name,reorder,state,cdate',
+		'value' => array
+		(
+			'"默认分类",10,1,' . time(),
+		),
+	),
+);

+ 236 - 0
database/exam.php

@@ -0,0 +1,236 @@
+<?php
+
+$type = array
+(
+	1 => '开始答题时随机抽取',
+	2 => '每次答题时随机抽取',
+	3 => '指定题目ID',
+	4 => '按照难度随机抽取',
+);
+
+$continue = array
+(
+	1 => '答错之后继续答题',
+	2 => '答错之后停止答题',
+);
+
+$cate = function()
+{
+	$array = array();
+	$cate = Dever::load('question/cate-state');
+	if($cate)
+	{
+		$array += $cate;
+	}
+	return $array;
+};
+
+return array
+(
+	# 表名
+	'name' => 'exam',
+	# 显示给用户看的名称
+	'lang' => '测试规则设置',
+	# 是否显示在后台菜单
+	'order' => 200,
+
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '标题',
+			'default' 	=> '',
+			'desc' 		=> '标题',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'desc'		=> array
+		(
+			'type' 		=> 'varchar-500',
+			'name' 		=> '描述',
+			'default' 	=> '',
+			'desc' 		=> '描述',
+			'match' 	=> 'is_string',
+			'update'	=> 'textarea',
+			'search'	=> 'fulltext',
+			//'list'		=> true,
+		),
+
+		'pic'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '测试图',
+			'default' 	=> '',
+			'desc' 		=> '测试图',
+			'match' 	=> 'option',
+			'update'	=> 'image',
+			'key' 		=> '1',
+			'place'		=> '150',
+		),
+
+		'cate_id'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '分类',
+			'default' 	=> '',
+			'desc' 		=> '请选择分类',
+			'match' 	=> 'is_string',
+			'update'	=> 'checkbox',
+			'option'	=> $cate,
+			//'search_parent' => 'info_id',//根据哪个字段来确定本搜索选项的内容
+			'list'		=> '{cate_id} > 0 ? Dever::load("question/cate-one#name", {cate_id}) : "未知"',
+		),
+
+		'type'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '题目抽取方式',
+			'default' 	=> '2',
+			'desc' 		=> '题目抽取方式',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'radio',
+			'option'	=> $type,
+			'control'	=> 'type',
+		),
+
+		'level_ids'		=> array
+		(
+			'type' 		=> 'varchar-300',
+			'name' 		=> '难度数量设置-多个用半角逗号隔开,如3,3,4,则简单选出3个,普通选出3个,困难选出4个,以此类推',
+			'default' 	=> '',
+			'desc' 		=> '描述',
+			'match' 	=> 'is_string',
+			'update'	=> 'textarea',
+			'search'	=> 'fulltext',
+			//'list'		=> true,
+			'show'		=> 'type=4',
+		),
+
+		'info_ids'		=> array
+		(
+			'type' 		=> 'varchar-300',
+			'name' 		=> '题库ID列表-多个请用换行',
+			'default' 	=> '',
+			'desc' 		=> '题库ID列表',
+			'match' 	=> 'option',
+			'update'	=> 'textarea',
+			//'list'		=> true,
+			'show'		=> 'type=3',
+		),
+
+		'continue'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '持续答题规则',
+			'default' 	=> '2',
+			'desc' 		=> '持续答题规则',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'radio',
+			'option'	=> $continue,
+		),
+
+		'num'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '题目数量',
+			'default' 	=> '10',
+			'desc' 		=> '题目数量',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+		'content'		=> array
+		(
+			'type' 		=> 'text-1000',
+			'name' 		=> '结果设置',
+			'default' 	=> '',
+			'desc' 		=> '结果设置',
+			'match' 	=> 'is_string',
+			'update'	=> array
+			(
+				array
+				(
+					'col'		=> 'score',
+					'name' 		=> '结果分数-答对题目的总分数,区间用~隔开,如20~40,代表大于等于20小于等于40',
+					'default' 	=> '0',
+					'desc' 		=> '选项分数',
+					'match' 	=> 'is_string',
+					'update'	=> 'text',
+				),
+
+				array
+				(
+					'col'		=> 'title',
+					'name' 		=> '结果标题',
+					'default' 	=> '',
+					'desc' 		=> '结果标题',
+					'match' 	=> 'is_string',
+					'update'	=> 'text',
+				),
+
+				array
+				(
+					'col'		=> 'pic',
+					'name' 		=> '结果图片',
+					'default' 	=> '',
+					'desc' 		=> '结果图片',
+					'match' 	=> 'is_string',
+					'update'	=> 'image',
+					'key' 		=> 'Eself999',
+				),
+
+				array
+				(
+					'col' 		=> 'info',
+					'name' 		=> '结果描述',
+					'default' 	=> '',
+					'desc' 		=> '结果描述',
+					'match' 	=> 'is_string',
+					'update'	=> 'editor',
+				),
+			),
+		),
+		
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		
+	),
+);

+ 195 - 0
database/info.php

@@ -0,0 +1,195 @@
+<?php
+
+$cate = function()
+{
+	$array = array();
+	$cate = Dever::load('question/cate-state');
+	if($cate)
+	{
+		$array += $cate;
+	}
+	return $array;
+};
+
+$level = function()
+{
+	$array = array();
+	$cate = Dever::load('question/level-state');
+	if($cate)
+	{
+		$array += $cate;
+	}
+	return $array;
+};
+
+return array
+(
+	# 表名
+	'name' => 'info',
+	# 显示给用户看的名称
+	'lang' => '题库列表',
+	# 是否显示在后台菜单
+	'order' => 100,
+
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '标题',
+			'default' 	=> '',
+			'desc' 		=> '标题',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'level_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '难度',
+			'default' 	=> '1',
+			'desc' 		=> '难度',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'select',
+			'option'	=> $level,
+			'search'	=> 'select',
+			'list'		=> '{level_id} > 0 ? Dever::load("question/level-one#name", {level_id}) : "未知"',
+		),
+
+		'cate_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '分类',
+			'default' 	=> '1',
+			'desc' 		=> '请选择分类',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'select',
+			'option'	=> $cate,
+			'search'	=> 'select',
+			//'search_parent' => 'info_id',//根据哪个字段来确定本搜索选项的内容
+			'list'		=> '{cate_id} > 0 ? Dever::load("question/cate-one#name", {cate_id}) : "未知"',
+		),
+
+		'pic'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '背景图',
+			'default' 	=> '',
+			'desc' 		=> '背景图',
+			'match' 	=> 'option',
+			'update'	=> 'image',
+			'key' 		=> '1',
+			'place'		=> '150',
+		),
+
+		'content'		=> array
+		(
+			'type' 		=> 'text-255',
+			'name' 		=> '选项设置',
+			'default' 	=> '',
+			'desc' 		=> '选项设置',
+			'match' 	=> 'is_string',
+			'update'	=> array
+			(
+				array
+				(
+					'col'		=> 'score',
+					'name' 		=> '选项分数-0为错误选项,大于1则为正确选项',
+					'default' 	=> '0',
+					'desc' 		=> '选项分数',
+					'match' 	=> 'is_string',
+					'update'	=> 'text',
+				),
+
+				array
+				(
+					'col'		=> 'title',
+					'name' 		=> '选项标题',
+					'default' 	=> '',
+					'desc' 		=> '请输入选项标题',
+					'match' 	=> 'is_string',
+					'update'	=> 'text',
+				),
+				
+				array
+				(
+					'col'		=> 'pic',
+					'name' 		=> '选项图片',
+					'default' 	=> '',
+					'desc' 		=> '选项图片',
+					'match' 	=> 'is_string',
+					'update'	=> 'image',
+					'key' 		=> '1',
+				),
+
+				array
+				(
+					'col' 		=> 'info',
+					'name' 		=> '描述',
+					'default' 	=> '',
+					'desc' 		=> '请输入描述',
+					'match' 	=> 'is_string',
+					'update'	=> 'textarea',
+				),
+			),
+		),
+		
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		
+	),
+
+	'request' => array
+	(
+		'getAll' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'cate_id' => array('yes', 'in'),
+				'ids' => array('yes', 'in'),
+				'level_id' => 'yes',
+				'state' => 1,
+			),
+			'type' => 'all',
+			'limit' => '0,10000',
+			'col' => '*|id',
+		),
+	)
+);

+ 105 - 0
database/level.php

@@ -0,0 +1,105 @@
+<?php
+
+return array
+(
+	# 表名
+	'name' => 'level',
+	# 显示给用户看的名称
+	'lang' => '难度设置',
+	'order' => 2,
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			'list'		=> true,
+		),
+		
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-80',
+			'name' 		=> '难度名称',
+			'default' 	=> '',
+			'desc' 		=> '难度名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'reorder'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '排序(数值越大越靠前)',
+			'default' 	=> '1',
+			'desc' 		=> '请输入排序',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'search'	=> 'order',
+			'list_name' => '排序',
+			'list'		=> true,
+			'order'		=> 'desc',
+			'edit'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+	
+	# 管理功能
+	'manage' => array
+	(
+
+	),
+
+	# 默认值
+	'default' => array
+	(
+		'col' => 'name,reorder,state,cdate',
+		'value' => array
+		(
+			'"简单",10,1,' . time(),
+			'"普通",9,1,' . time(),
+			'"困难",8,1,' . time(),
+		),
+	),
+
+	'request' => array
+	(
+		'getAll' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'state' => 1,
+			),
+			'order' => array('reorder' => 'desc', 'id' => 'desc'),
+			'type' => 'all',
+			'col' => '*',
+		),
+	)
+);

+ 99 - 0
database/ranking.php

@@ -0,0 +1,99 @@
+<?php
+return array
+(
+	# 表名
+	'name' => 'ranking',
+	# 显示给用户看的名称
+	'lang' => '排行榜',
+	# 是否显示在后台菜单
+	'order' => 1,
+
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'list'		=> true,
+		),
+
+		'user_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户参与id',
+			'default' 	=> '',
+			'desc' 		=> '用户参与id',
+			'match' 	=> 'is_numeric',
+			//'list'		=> true,
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '用户',
+			'match' 	=> 'is_numeric',
+			'list'		=> true,
+		),
+
+		'score'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '本次分数',
+			'default' 	=> '0',
+			'desc' 		=> '本次分数',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'text',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'times'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '本次答题次数',
+			'default' 	=> '0',
+			'desc' 		=> '本次答题次数',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+		
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			'search'	=> 'date',
+			'order'		=> 'desc',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+		'delete' => false,
+	),
+
+	'request' => array
+	(
+		
+	)
+);

+ 197 - 0
database/user.php

@@ -0,0 +1,197 @@
+<?php
+
+$status = array
+(
+	1 => '未开始',
+	2 => '正在答题',
+	3 => '中止答题',//也算完成
+	4 => '完成答题',
+);
+
+return array
+(
+	# 表名
+	'name' => 'user',
+	# 显示给用户看的名称
+	'lang' => '用户参与表',
+	# 是否显示在后台菜单
+	'menu' => false,
+
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '用户id',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'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}) : "未知"',
+		),
+
+		'info_ids'		=> array
+		(
+			'type' 		=> 'varchar-300',
+			'name' 		=> '题库ID列表',
+			'default' 	=> '',
+			'desc' 		=> '题库ID列表',
+			'match' 	=> 'option',
+			'update'	=> 'textarea',
+			//'list'		=> true,
+		),
+
+		'score'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '当前得分',
+			'default' 	=> '0',
+			'desc' 		=> '当前得分',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+
+		'num'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '题目数量',
+			'default' 	=> '0',
+			'desc' 		=> '题目数量',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+		'times'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '答题次数',
+			'default' 	=> '0',
+			'desc' 		=> '答题次数',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+
+		'user_info_ids'		=> array
+		(
+			'type' 		=> 'varchar-300',
+			'name' 		=> '答过的题目id列表',
+			'default' 	=> '',
+			'desc' 		=> '答过的题目id列表',
+			'match' 	=> 'option',
+			'update'	=> 'textarea',
+			//'list'		=> true,
+		),
+
+		'index'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '答题进度',
+			'default' 	=> '0',
+			'desc' 		=> '答题进度',
+			'match' 	=> 'option',
+			'update'	=> 'textarea',
+			'list'		=> true,
+		),
+
+		'status'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '答题状态',
+			'default' 	=> '1',
+			'desc' 		=> '答题状态',
+			'match' 	=> 'is_numeric',
+			//'update'	=> 'radio',
+			'option'	=> $status,
+			'control'	=> 'type',
+			'list'		=> true,
+		),
+
+		
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+		'delete' => false,
+	),
+
+	'request' => array
+	(
+		# 获取已完成记录
+		'getFinish' => array
+		(
+			# 匹配的正则或函数 选填项
+			'where' => array
+			(
+				'status' => array('yes', '>='),
+				'exam_id' => 'yes',
+				'uid' => 'yes',
+				'state' => 1,
+			),
+			'type' => 'one',
+			'order' => array('times' => 'desc', 'id' => 'desc'),
+			'col' => 'times',
+		),
+
+		# 获取未完成记录
+		'getUnFinish' => array
+		(
+			# 匹配的正则或函数 选填项
+			'where' => array
+			(
+				'status' => array('yes', '<'),
+				'exam_id' => 'yes',
+				'uid' => 'yes',
+				'state' => 1,
+			),
+			'type' => 'one',
+			'col' => '*',
+		),
+	)
+);

+ 114 - 0
database/user_answer.php

@@ -0,0 +1,114 @@
+<?php
+return array
+(
+	# 表名
+	'name' => 'user_answer',
+	# 显示给用户看的名称
+	'lang' => '用户答题记录',
+	# 是否显示在后台菜单
+	'menu' => false,
+
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '用户',
+			'match' 	=> 'is_numeric',
+			'list'		=> true,
+		),
+
+		'user_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户参与id',
+			'default' 	=> '',
+			'desc' 		=> '用户参与id',
+			'match' 	=> 'is_numeric',
+			//'list'		=> true,
+		),
+
+		'info_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '题目id',
+			'default' 	=> '',
+			'desc' 		=> '题目id',
+			'match' 	=> 'is_numeric',
+			'list'		=> true,
+		),
+
+		'score'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '本题得分',
+			'default' 	=> '0',
+			'desc' 		=> '本题得分',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+
+		'option'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '选择的选项',
+			'default' 	=> '0',
+			'desc' 		=> '选择的选项',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'text',
+			//'list'		=> true,
+		),
+
+		'option_name'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '选项的选项标题',
+			'default' 	=> '',
+			'desc' 		=> '选项的选项标题',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+		
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		
+	),
+);

+ 8 - 0
index.php

@@ -0,0 +1,8 @@
+<?php
+
+define('DEVER_APP_NAME', 'question');
+define('DEVER_APP_LANG', '题库管理');
+define('DEVER_APP_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+define('DEVER_MANAGE_ORDER', 2);
+define('DEVER_MANAGE_ICON', 'glyphicon glyphicon-tree-deciduous');
+include(DEVER_APP_PATH . '../boot.php');

+ 478 - 0
src/Api.php

@@ -0,0 +1,478 @@
+<?php
+
+namespace Question\Src;
+
+use Dever;
+
+class Api
+{
+	private $hidden = true;
+	private $exam = array();
+	private $question = array();
+	private $user = array();
+
+	/**
+	 * 获取某个答题规则的数据接口 api.get?id=1
+	 *
+	 * @return mixed
+	 */
+	public function get()
+	{
+		$result = array();
+		$id = Dever::input('id');
+		if ($id <= 0 || !$id) {
+			Dever::alert('规则不存在');
+		}
+
+		$this->exam = Dever::db('question/exam')->one($id);
+
+		if (!$this->exam) {
+			 Dever::alert('规则不存在');
+		}
+
+		$question = array();
+		if ($this->exam['type'] == 1) {
+			# 首次抽取题目,题目保存在user表中,user表保存答题进度
+			$question = $this->getQuestion($this->exam['cate_id'], $this->exam['num']);
+		} elseif ($this->exam['type'] == 3) {
+			# 固定id得到题目,题目保存在user表中,user表保存答题进度
+			$question = $this->getQuestion($this->exam['cate_id'], 0, $this->exam['info_ids']);
+		}
+
+		$this->initUser($question);
+
+		$result['exam'] = $this->exam;
+		$result['user'] = $this->user;
+
+		$yes = Dever::input('yes', 1);
+		# 未完成,并且设置了yes==1,则立即开始答题
+		if ($yes == 1 && $this->user && $this->user['status'] < 3) {
+			$result['question'] = $this->getQuestionInfo();
+		}
+
+		return $result;
+	}
+
+	/**
+	 * 从某个活动中抽取题目并保存下来
+	 * $category 分类id
+	 * $num 取多少题
+	 * $ids 题目id
+	 * $index 当前是第几题
+	 * $level_ids 难度数量
+	 *
+	 * @return mixed
+	 */
+	private function getQuestion($category, $num, $ids = false, $index = 0, $level_ids = false)
+	{
+		$where = array();
+		$where['cate_id'] = $category;
+		if ($ids) {
+			$where['ids'] = $ids;
+		}
+
+		if ($level_ids) {
+			# 如果有难度
+			$level = explode(',', $level_ids);
+			$level_data = Dever::db('question/level')->getAll();
+			$index = $index + 1;
+			$level_info = array();
+			$i = 1;
+			foreach ($level as $k => $v) {
+				$start = $i;
+				$end = $v;
+				$i = $end + $i;
+				$end = $start + $end - 1;
+				if ($index >= $start && $index <= $end) {
+					if (isset($level_data[$k])) {
+						$level_info = $level_data[$k];
+					}
+					
+					break;
+				}
+			}
+
+			if (isset($level_info)) {
+				$where['level_id'] = $level_info['id'];
+			} else {
+				Dever::alert('难度获取失败');
+			}
+		}
+
+		$data = Dever::db('question/info')->getAll($where);
+
+		$question_id = Dever::input('question_id');
+
+		if ($question_id > 0) {
+			if (isset($data[$question_id])) {
+				return array($data[$question_id]);
+			} else {
+				Dever::alert('错误的题目信息');
+			}
+		}
+
+		$result = array();
+		if ($data && $num) {
+			$count = count($data);
+			if ($num > $count) {
+				$num = $count;
+			}
+			$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;
+	}
+
+
+	/**
+	 * 初始化用户信息
+	 *
+	 * @return mixed
+	 */
+	private function initUser($question = array())
+	{
+		if (!$this->exam) {
+			Dever::alert('规则不存在');
+		}
+		$uid = $this->getUid();
+
+		# 获取当前最新的一条已完成记录
+		if ($this->exam['continue'] == 1) {
+			# 答错可以继续答题 则答完所有题才算完成
+			$where['where_status'] = 4;
+		} elseif ($this->exam['continue'] == 2) {
+			# 答错不可以继续答题 则错误也算完成
+			$where['where_status'] = 3;
+		}
+		$where['where_uid'] = $uid;
+		$where['where_exam_id'] = $this->exam['id'];
+		# 获取已完成记录
+		$finish = Dever::db('question/user')->getFinish($where);
+
+		if ($this->exam['continue'] == 2 && $finish && $finish['status'] == 3) {
+			# 最新一次如果是错误的,则停止继续
+			$this->user = $finish;
+			return;
+		}
+
+		# 获取正在进行中的记录
+		$this->user = Dever::db('question/user')->getUnFinish($where);
+
+		$times = 1;
+		if($finish) {
+			$times = $finish['times'] + 1;
+		}
+
+		if (!$this->user) {
+			$insert = array();
+			$insert['num'] = $this->exam['num'];
+			if ($question) {
+				$question = array_keys($question);
+				$insert['num'] = count($question);
+				$insert['info_ids'] = implode(',', $question);
+			}
+			$insert['uid'] = $uid;
+			$insert['exam_id'] = $this->exam['id'];
+			$insert['index'] = 0;
+			$insert['score'] = 0;
+			$insert['status'] = 1;
+			# 检查答题次数 第一次
+			$insert['times'] = $times;
+			$id = Dever::db('question/user')->insert($insert);
+			$this->user = Dever::db('question/user')->one($id);
+		} else {
+			$id = $this->user['id'];
+		}
+
+		if ($this->user['status'] >= 3) {
+			$this->exam['content'] = Dever::array_decode($this->exam['content']);
+			$this->exam['result'] = array();
+			foreach ($this->exam['content'] as $k => $v) {
+				if (strstr($v['score'], '~')) {
+					$temp = explode('~', $v['score']);
+					if ($this->user['score'] >= $temp[0] && $this->user['score'] <= $temp[1]) {
+						unset($v['score']);
+						$this->exam['result'] = $v;
+						break;
+					}
+				} else {
+					if ($this->user['score'] == $v['score']) {
+						unset($v['score']);
+						$this->exam['result'] = $v;
+						break;
+					}
+				}
+			}
+
+			unset($this->exam['content']);
+		} else {
+			unset($this->exam['content']);
+		}
+	}
+
+	/**
+	 * 获取用户id
+	 *
+	 * @return mixed
+	 */
+	private function getUid()
+	{
+		$id = Dever::input('uid');
+		if (!$id) {
+			$save = new \Dever\Session\Oper(DEVER_PROJECT, 'cookie');
+
+			$id = $save->get('uid');
+			if (!$id) {
+				$id = Dever::id();
+				$save->add('uid', $id);
+			}
+		}
+		
+
+		return $id;
+	}
+
+	/**
+	 * 获取题目接口:api.getInfo?user_data_id=1&uid=1
+	 *
+	 * @return mixed
+	 */
+	public function getInfo()
+	{
+		$this->getUser();
+
+		$this->exam = Dever::db('question/exam')->one($this->user['exam_id']);
+
+		return $this->getQuestionInfo();
+	}
+
+	private function getUser()
+	{
+		$uid = $this->getUid();
+
+		$id = Dever::input('user_data_id');
+
+		$this->user = Dever::db('question/user')->one($id);
+
+		if (!$this->user) {
+			Dever::alert('错误的用户信息');
+		}
+
+		if ($this->user && $uid != $this->user['uid']) {
+			Dever::alert('错误的用户信息');
+		}
+	}
+
+
+	/**
+	 * 获取题目
+	 *
+	 * @return mixed
+	 */
+	private function getQuestionInfo()
+	{
+		if ($this->user && $this->exam) {
+			# 验证是否答完
+			if ($this->user['status'] == 4) {
+				Dever::alert('已经答完所有题目');
+			}
+			# 验证是否答错
+			if ($this->exam['continue'] == 2 && $this->user['status'] == 3) {
+				Dever::alert('不能继续答题');
+			}
+
+			# 进行中
+			Dever::db('question/user')->update(array('where_id' => $this->user['id'], 'status' => 2));
+
+			if ($this->exam['type'] == 1 && $this->user['info_ids']) {
+				$question = explode(",", $this->user['info_ids']);
+			} elseif ($this->exam['type'] == 2) {
+				# 随机抽取
+				$data = $this->getQuestion($this->exam['cate_id'], 1, false, $this->user['index']);
+				$question[$this->user['index']] = $data[0];
+			} elseif ($this->exam['type'] == 3 && $this->exam['info_ids']) {
+				# 固定的
+				$question = explode("\r\n", $this->exam['info_ids']);
+			} elseif ($this->exam['type'] == 4) {
+				# 随机抽取并且按照难度抽取
+				$data = $this->getQuestion($this->exam['cate_id'], 1, false, $this->user['index'], $this->exam['level_ids']);
+				$question[$this->user['index']] = $data[0];
+			} else {
+				Dever::alert('错误的题目类型');
+			}
+		}
+
+		if (isset($question[$this->user['index']])) {
+			$data = $question[$this->user['index']];
+			if (!is_array($data)) {
+				$data = Dever::db('question/info')->one($data);
+			}
+			$data['index'] = $this->user['index'];
+			$data['num'] = $this->user['num'];
+
+			$data['content'] = Dever::array_decode($data['content']);
+			if ($this->hidden == true) {
+				foreach ($data['content'] as $k => $v) {
+					unset($data['content'][$k]['score']);
+				}
+			} else {
+				$data['user_info_ids'] = $this->user['user_info_ids'];
+				$data['score'] = $this->user['score'];
+				$data['total'] = $this->exam['num'];
+			}
+			$data['user_data_id'] = $this->user['id'];
+			
+			return $data;
+		}
+
+		Dever::alert('错误的题目信息');
+	}
+
+	/**
+	 * 开始答题接口: api.submit?question_id=1&option=0&user_data_id=1&uid=1&next=1 获取下一题的信息
+	 * 返回参数:status 2为进行中 3答题错误 4答题正确
+	 *
+	 * @return mixed
+	 */
+	public function submit()
+	{
+		$id = Dever::input('user_data_id');
+		if (!$id) {
+			Dever::alert('错误的用户信息');
+		}
+
+		$question_id = Dever::input('question_id');
+		if (!$question_id) {
+			Dever::alert('错误的题目信息');
+		}
+		$option = Dever::input('option', 0);
+
+		$one['user_id'] = $id;
+		$one['uid'] = Dever::input('uid');
+		$one['info_id'] = Dever::input('question_id');
+		$one = Dever::db('question/user_answer')->one($one);
+		if ($one) {
+			$this->user = Dever::db('question/user')->one($id);
+			$update['status'] = $this->user['status'];
+		} else {
+
+			$this->hidden = false;
+			$data = $this->getInfo();
+			
+			if (!isset($data['content'][$option])) {
+				Dever::alert('错误的选项信息');
+			}
+
+			$update['user_info_ids'] = $data['user_info_ids'];
+			if ($update['user_info_ids']) {
+				$update['user_info_ids'] = explode(',', $update['user_info_ids']);
+				$update['user_info_ids'][] = $data['id'];
+				$update['user_info_ids'] = implode(',', $update['user_info_ids']);
+			} else {
+				$update['user_info_ids'] = $data['id'];
+			}
+
+			$update['score'] = $data['score'] + $data['content'][$option]['score'];
+			$update['index'] = $data['index'] + 1;
+			$update['where_id'] = $data['user_data_id'];
+
+			$update['status'] = 2;
+
+			if ($update['index'] >= $data['num']) {
+				# 答题完成
+				$update['status'] = 4;
+				# 将当前分数同步到排行榜中去
+				$this->setRanking($update['score']);
+			}
+			if ($this->exam['continue'] == 2 && $data['content'][$option]['score'] == 0) {
+				#答题错误
+				$update['status'] = 3;
+				# 将当前分数同步到排行榜中去
+				$this->setRanking($update['score']);
+			}
+			
+			Dever::db('question/user')->update($update);
+
+			$insert['user_id'] = $data['user_data_id'];
+			$insert['info_id'] = $data['id'];
+			$insert['score'] = $data['content'][$option]['score'];
+			$insert['option'] = $option;
+			$insert['uid'] = $this->user['uid'];
+			$insert['option_name'] = $data['content'][$option]['title'];
+			Dever::db('question/user_answer')->insert($insert);
+		}
+
+		$result = array();
+		$result['status'] = $update['status'];
+		$result['question_id'] = $question_id;
+		$result['option'] = $option;
+		$result['user_data_id'] = $id;
+
+		return $result;
+	}
+
+	private function setRanking($score)
+	{
+		$ranking = Dever::db('question/ranking')->one(array
+		(
+			'uid' => $this->user['uid'],
+			'exam_id' => $this->user['exam_id'],
+		));
+
+		if ($ranking) {
+			if ($ranking['score'] < $score) {
+				$update['uid'] = $this->user['uid'];
+				$update['exam_id'] = $this->user['exam_id'];
+				$update['score'] = $score;
+				$update['times'] =  $this->user['times'];
+				$update['where_id'] = $ranking['id'];
+				Dever::db('question/ranking')->update($update);
+			}
+			
+		} else {
+			$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);
+		}
+	}
+
+	/**
+	 * 复活接口 把当前的status状态值为2即可
+	 *
+	 * @return mixed
+	 */
+	public function continue()
+	{
+		$this->getUser();
+		$update['where_id'] = $this->user['id'];
+		$update['status'] = 2;
+		Dever::db('question/user')->update($update);
+
+		return true;
+	}
+
+	/**
+	 * 重新挑战接口,重新开始,当前结束
+	 *
+	 * @return mixed
+	 */
+	public function reset()
+	{
+		$this->getUser();
+		$update['where_id'] = $this->user['id'];
+		$update['status'] = 4;
+		Dever::db('question/user')->update($update);
+
+		return true;
+	}
+}