修改添加题目功能
This commit is contained in:
parent
6f71d177fc
commit
81109dca7e
8
.env
8
.env
@ -1,14 +1,14 @@
|
|||||||
APP_DEBUG = false
|
APP_DEBUG = true
|
||||||
|
|
||||||
[APP]
|
[APP]
|
||||||
DEFAULT_TIMEZONE = Asia/Shanghai
|
DEFAULT_TIMEZONE = Asia/Shanghai
|
||||||
|
|
||||||
[DATABASE]
|
[DATABASE]
|
||||||
TYPE = mysql
|
TYPE = mysql
|
||||||
HOSTNAME = 127.0.0.1
|
HOSTNAME = 192.168.31.201
|
||||||
DATABASE = ruankao
|
DATABASE = ruankao
|
||||||
USERNAME = ruankao
|
USERNAME = root
|
||||||
PASSWORD = 123456
|
PASSWORD = 920103
|
||||||
HOSTPORT = 3306
|
HOSTPORT = 3306
|
||||||
CHARSET = utf8
|
CHARSET = utf8
|
||||||
DEBUG = true
|
DEBUG = true
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@
|
|||||||
runtime
|
runtime
|
||||||
*.log
|
*.log
|
||||||
config/database.php
|
config/database.php
|
||||||
|
.env
|
||||||
@ -92,21 +92,6 @@ class TkController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//递归构建树形结构
|
|
||||||
private function buildTree($item, $list)
|
|
||||||
{
|
|
||||||
$item['children'] = [];
|
|
||||||
foreach ($list as $child) {
|
|
||||||
if ($child['parent_id'] == $item['id']) {
|
|
||||||
// 添加层级关系标识
|
|
||||||
$child['isLeaf'] = ($child['level'] == max(array_column($list, 'level')));
|
|
||||||
$item['children'][] = $this->buildTree($child, $list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $item;
|
|
||||||
}
|
|
||||||
|
|
||||||
//题目分类增加
|
//题目分类增加
|
||||||
public function categoryadd()
|
public function categoryadd()
|
||||||
{
|
{
|
||||||
@ -162,7 +147,7 @@ class TkController extends BaseController
|
|||||||
|
|
||||||
// 分类筛选
|
// 分类筛选
|
||||||
if (!empty($params['category'])) {
|
if (!empty($params['category'])) {
|
||||||
$cateInfo = TkSubjects::where('name', $params['category'])
|
$cateInfo = TkQuestions::where('name', $params['category'])
|
||||||
->where('delete_time', null)
|
->where('delete_time', null)
|
||||||
->where('status', 1)
|
->where('status', 1)
|
||||||
->field('id')
|
->field('id')
|
||||||
@ -190,7 +175,7 @@ class TkController extends BaseController
|
|||||||
->select()
|
->select()
|
||||||
->each(function ($item) {
|
->each(function ($item) {
|
||||||
// 获取分类信息
|
// 获取分类信息
|
||||||
$cateInfo = TkSubjects::where('id', (int) $item['cate'])
|
$cateInfo = TkQuestions::where('id', (int) $item['cate'])
|
||||||
->field('name, icon')
|
->field('name, icon')
|
||||||
->find();
|
->find();
|
||||||
if ($cateInfo) {
|
if ($cateInfo) {
|
||||||
@ -210,44 +195,69 @@ class TkController extends BaseController
|
|||||||
'data' => $lists
|
'data' => $lists
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$allCategories = TkSubjects::where('delete_time', null)
|
// $allCategories = TkQuestions::where('delete_time', null)
|
||||||
->where('status', 1)
|
// ->where('status', 1)
|
||||||
->field('id, name, cid, icon')
|
// ->field('id, name, cid, icon')
|
||||||
->order('sort asc, id asc')
|
// ->order('sort asc, id asc')
|
||||||
->select()
|
// ->select()
|
||||||
->toArray();
|
// ->toArray();
|
||||||
|
|
||||||
$categories = $this->buildParentChild($allCategories);
|
// $categories = $this->buildParentChild($allCategories);
|
||||||
|
|
||||||
View::assign([
|
// View::assign([
|
||||||
'categories' => $categories
|
// 'categories' => $categories
|
||||||
]);
|
// ]);
|
||||||
return View::fetch();
|
return View::fetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建父子结构
|
//题目添加
|
||||||
private function buildParentChild($lists)
|
public function topicadd()
|
||||||
{
|
{
|
||||||
$tree = [];
|
if ($this->request->isPost()) {
|
||||||
foreach ($lists as $item) {
|
$params = $this->request->post();
|
||||||
if ($item['cid'] == 0) {
|
|
||||||
// 顶级分类
|
// 数据验证
|
||||||
$tree[] = $item;
|
$validate = new \think\Validate([
|
||||||
} else {
|
'question_type' => 'require|number|between:1,6',
|
||||||
// 子分类
|
'subject_id' => 'require|number',
|
||||||
foreach ($tree as &$parent) {
|
'knowledge_point_id' => 'number',
|
||||||
if ($parent['id'] == $item['cid']) {
|
'difficulty' => 'number|between:1,5',
|
||||||
if (!isset($parent['children'])) {
|
'content' => 'require',
|
||||||
$parent['children'] = [];
|
'analysis' => 'require',
|
||||||
}
|
'answer' => 'require'
|
||||||
$parent['children'][] = $item;
|
]);
|
||||||
break;
|
|
||||||
}
|
if (!$validate->check($params)) {
|
||||||
}
|
return json(['code' => 1, 'msg' => $validate->getError()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理数据
|
||||||
|
$data = [
|
||||||
|
'question_type' => (int)$params['question_type'],
|
||||||
|
'subject_id' => (int)$params['subject_id'],
|
||||||
|
'knowledge_point_id' => isset($params['knowledge_point_id']) ? (int)$params['knowledge_point_id'] : null,
|
||||||
|
'difficulty' => isset($params['difficulty']) ? (int)$params['difficulty'] : 3,
|
||||||
|
'content' => $params['content'],
|
||||||
|
'analysis' => $params['analysis'],
|
||||||
|
'answer' => $params['answer'],
|
||||||
|
'created_by' => $this->getUserId(), // 假设有获取当前用户ID的方法
|
||||||
|
'created_time' => date('Y-m-d H:i:s'),
|
||||||
|
'updated_by' => $this->getUserId(),
|
||||||
|
'updated_time' => date('Y-m-d H:i:s')
|
||||||
|
];
|
||||||
|
|
||||||
|
// 保存数据
|
||||||
|
$result = \think\facade\Db::name('questions')->insert($data);
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
return json(['code' => 0, 'msg' => '添加成功']);
|
||||||
|
} else {
|
||||||
|
return json(['code' => 1, 'msg' => '添加失败']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return View::fetch();
|
||||||
}
|
}
|
||||||
return $tree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6,8 +6,9 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
|
<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
|
||||||
<link rel="stylesheet" type="text/css" href="__CSS__/moban.css" media="all"/>
|
<link rel="stylesheet" type="text/css" href="/static/css/moban.css" media="all"/>
|
||||||
<link rel="stylesheet" type="text/css" href="__CSS__/wangeditor.css" media="all"/>
|
<link rel="stylesheet" type="text/css" href="/static/css/wangeditor.css" media="all"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css" media="all"/>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
|
.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
|
||||||
.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
|
.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
|
||||||
@ -79,6 +80,7 @@
|
|||||||
.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
|
.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript" src="/static/layui/layui.js"></script>
|
<script type="text/javascript" src="/static/layui/layui.js"></script>
|
||||||
|
<script type="text/javascript" src="/static/js/bootstrap.bundle.min.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
layui.use(['layer','form','table','laydate','element','upload'],function(){
|
layui.use(['layer','form','table','laydate','element','upload'],function(){
|
||||||
layer = layui.layer; // layui 弹框
|
layer = layui.layer; // layui 弹框
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
</body>
|
|
||||||
</html>
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// 显示图片
|
// 显示图片
|
||||||
function show_img(obj){
|
function show_img(obj){
|
||||||
@ -27,4 +26,6 @@
|
|||||||
function deleteImage(path,obj){
|
function deleteImage(path,obj){
|
||||||
$(obj).closest('.upload_pic_li').remove();
|
$(obj).closest('.upload_pic_li').remove();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -3,7 +3,7 @@
|
|||||||
<div class="layui-container" style="margin-top:30px;">
|
<div class="layui-container" style="margin-top:30px;">
|
||||||
<div class="layui-row">
|
<div class="layui-row">
|
||||||
<div class="layui-col-md12">
|
<div class="layui-col-md12">
|
||||||
<button class="layui-btn layui-btn-normal" id="addCategoryBtn">新增科目</button>
|
<button class="layui-btn layui-btn-normal mb-3" id="addCategoryBtn">新增科目</button>
|
||||||
<table class="layui-hide" id="categoryTable" lay-filter="categoryTableFilter"></table>
|
<table class="layui-hide" id="categoryTable" lay-filter="categoryTableFilter"></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
482
app/admin/view/tk/topicadd.php
Normal file
482
app/admin/view/tk/topicadd.php
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
{include file="public/header" /}
|
||||||
|
<div class="config-container">
|
||||||
|
|
||||||
|
<form class="layui-form" action="" method="post">
|
||||||
|
<div class="form-container">
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">题目类型</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select name="type" lay-verify="required" lay-filter="questionType">
|
||||||
|
<option value="">请选择题目类型</option>
|
||||||
|
<option value="1">单选题</option>
|
||||||
|
<option value="2">多选题</option>
|
||||||
|
<option value="3">判断题</option>
|
||||||
|
<option value="4">填空题</option>
|
||||||
|
<option value="5">简答题</option>
|
||||||
|
<option value="6">编程题</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">题目年份</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="year" placeholder="请输入题目年份" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 题目内容 -->
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">题目内容</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div id="toolbar-container"></div>
|
||||||
|
<div id="editor-container" style="border:1px solid #ccc; min-height:200px;"></div>
|
||||||
|
<input type="hidden" name="content" id="content-hidden">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 单选题表单 -->
|
||||||
|
<div id="single_choice" class="question-type-form" style="display:none">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项A</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[A]" lay-verify="required" placeholder="请输入选项A内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项B</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[B]" lay-verify="required" placeholder="请输入选项B内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项C</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[C]" placeholder="请输入选项C内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项D</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[D]" placeholder="请输入选项D内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">正确答案</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select name="correct_answer" lay-verify="required" disabled>
|
||||||
|
<option value="A">A</option>
|
||||||
|
<option value="B">B</option>
|
||||||
|
<option value="C">C</option>
|
||||||
|
<option value="D">D</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 多选题表单 -->
|
||||||
|
<div id="multiple_choice" class="question-type-form" style="display:none">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项A</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[A]" lay-verify="required" placeholder="请输入选项A内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项B</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[B]" lay-verify="required" placeholder="请输入选项B内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项C</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[C]" placeholder="请输入选项C内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">选项D</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="options[D]" placeholder="请输入选项D内容" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">正确答案</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select name="correct_answer" lay-verify="required" multiple disabled>
|
||||||
|
<option value="A">A</option>
|
||||||
|
<option value="B">B</option>
|
||||||
|
<option value="C">C</option>
|
||||||
|
<option value="D">D</option>
|
||||||
|
</select>
|
||||||
|
<div class="layui-form-mid layui-word-aux">按住Ctrl键可多选</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 判断题表单 -->
|
||||||
|
<div id="true_false" class="question-type-form" style="display:none">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">正确答案</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select name="correct_answer" lay-verify="required" disabled>
|
||||||
|
<option value="1">正确</option>
|
||||||
|
<option value="0">错误</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 填空题表单 -->
|
||||||
|
<div id="fill_blank" class="question-type-form" style="display:none">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">正确答案</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="correct_answer" lay-verify="required" placeholder="请输入正确答案,多个答案用逗号分隔" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 简答题表单 -->
|
||||||
|
<div id="short_answer" class="question-type-form" style="display:none">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">参考答案</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea name="correct_answer" lay-verify="required" placeholder="请输入参考答案" class="layui-textarea" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 编程题表单 -->
|
||||||
|
<div id="programming" class="question-type-form" style="display:none">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">编程语言</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select name="language" lay-verify="required" disabled>
|
||||||
|
<option value="php">PHP</option>
|
||||||
|
<option value="java">Java</option>
|
||||||
|
<option value="python">Python</option>
|
||||||
|
<option value="javascript">JavaScript</option>
|
||||||
|
<option value="c">C</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">参考答案</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea name="correct_answer" lay-verify="required" placeholder="请输入参考答案代码" class="layui-textarea" style="height:300px;" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">测试用例</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea name="test_case" placeholder="请输入测试用例,多个测试用例用换行分隔" class="layui-textarea" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item" style="margin-top: 80px;">
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit lay-filter="formSubmit">立即提交</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/js/wangeditor.js"></script>
|
||||||
|
<script>
|
||||||
|
layui.use(['form', 'layer', 'upload', 'element'], function () {
|
||||||
|
var form = layui.form;
|
||||||
|
var layer = layui.layer;
|
||||||
|
var $ = layui.$;
|
||||||
|
var upload = layui.upload;
|
||||||
|
var element = layui.element;
|
||||||
|
|
||||||
|
// 格式化文件大小
|
||||||
|
function formatFileSize(bytes) {
|
||||||
|
if (bytes === 0) return '0 B';
|
||||||
|
const k = 1024;
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 图标上传
|
||||||
|
var iconUpload = upload.render({
|
||||||
|
elem: '#upload-btn',
|
||||||
|
url: '{:url("index/upload_img")}',
|
||||||
|
before: function (obj) {
|
||||||
|
obj.preview(function (index, file, result) {
|
||||||
|
$('#upload-img').attr('src', result);
|
||||||
|
});
|
||||||
|
element.progress('icon-progress', '0%');
|
||||||
|
layer.msg('图标上传中', { icon: 16, time: 0 });
|
||||||
|
},
|
||||||
|
done: function (res) {
|
||||||
|
if (res.code > 0) {
|
||||||
|
return layer.msg('图标上传失败');
|
||||||
|
}
|
||||||
|
$('#icon').val(res.data);
|
||||||
|
$('#upload-text').html('');
|
||||||
|
layer.msg('图标上传成功', { icon: 1 });
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
var demoText = $('#upload-text');
|
||||||
|
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
|
||||||
|
demoText.find('.demo-reload').on('click', function () {
|
||||||
|
iconUpload.upload();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
progress: function (n, elem, e) {
|
||||||
|
element.progress('icon-progress', n + '%');
|
||||||
|
if (n == 100) {
|
||||||
|
layer.msg('图标上传完毕', { icon: 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 文件上传
|
||||||
|
var fileUpload = upload.render({
|
||||||
|
elem: '#ID-upload-demo-drag',
|
||||||
|
url: '{:url("index/upload_file")}',
|
||||||
|
accept: 'file',
|
||||||
|
exts: 'doc|docx|xls|xlsx|ppt|pptx|pdf|txt|zip|rar|7z',
|
||||||
|
before: function (obj) {
|
||||||
|
obj.preview(function (index, file, result) {
|
||||||
|
$('#ID-upload-demo-preview').show();
|
||||||
|
$('.file-name').text(file.name);
|
||||||
|
$('.file-size').text(formatFileSize(file.size));
|
||||||
|
});
|
||||||
|
element.progress('file-progress', '0%');
|
||||||
|
layer.msg('文件上传中', { icon: 16, time: 0 });
|
||||||
|
},
|
||||||
|
done: function (res) {
|
||||||
|
if (res.code > 0) {
|
||||||
|
return layer.msg('文件上传失败');
|
||||||
|
}
|
||||||
|
$('#file').val(res.data.src);
|
||||||
|
$('input[name="fileurl"]').val(res.data.src);
|
||||||
|
layer.msg('文件上传成功', { icon: 1 });
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
layer.msg('文件上传失败', { icon: 2 });
|
||||||
|
},
|
||||||
|
progress: function (n, elem, e) {
|
||||||
|
element.progress('file-progress', n + '%');
|
||||||
|
if (n == 100) {
|
||||||
|
layer.msg('文件上传完毕', { icon: 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 多图片上传
|
||||||
|
var uploadInst = upload.render({
|
||||||
|
elem: '#imageUpload',
|
||||||
|
url: '{:url("index/upload_img")}',
|
||||||
|
multiple: true,
|
||||||
|
accept: 'images',
|
||||||
|
before: function (obj) {
|
||||||
|
obj.preview(function (index, file, result) {
|
||||||
|
$('#imagePreview').append('<div class="layui-upload-img-item" style="display: inline-block; margin-right: 10px;"><img src="' + result + '" alt="' + file.name + '" style="width: 100px; height: 100px; object-fit: cover;"><p>' + file.name + '</p><button type="button" class="layui-btn layui-btn-xs layui-btn-danger delete-image" style="position: absolute; top: 0; right: 0;">删除</button></div>');
|
||||||
|
});
|
||||||
|
element.progress('image-progress', '0%');
|
||||||
|
layer.msg('图片上传中', { icon: 16, time: 0 });
|
||||||
|
},
|
||||||
|
done: function (res) {
|
||||||
|
if (res.code > 0) {
|
||||||
|
return layer.msg('图片上传失败');
|
||||||
|
}
|
||||||
|
var images = $('#images').val();
|
||||||
|
images = images ? images + ',' + res.data : res.data;
|
||||||
|
$('#images').val(images);
|
||||||
|
layer.msg('图片上传成功', { icon: 1 });
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
var demoText = $('#imagePreview');
|
||||||
|
demoText.append('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
|
||||||
|
demoText.find('.demo-reload').on('click', function () {
|
||||||
|
uploadInst.upload();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
progress: function (n, elem, e) {
|
||||||
|
element.progress('image-progress', n + '%');
|
||||||
|
if (n == 100) {
|
||||||
|
layer.msg('图片上传完毕', { icon: 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 只保留题目类型切换逻辑
|
||||||
|
// 初始化所有题型表单为隐藏并禁用
|
||||||
|
$('.question-type-form').hide().find('input,select,textarea').prop('disabled', true);
|
||||||
|
|
||||||
|
// 监听题目类型选择变化
|
||||||
|
form.on('select(questionType)', function (data) {
|
||||||
|
var type = data.value;
|
||||||
|
// 隐藏所有题目类型表单并禁用其输入
|
||||||
|
$('.question-type-form').hide().find('input,select,textarea').prop('disabled', true).val('');
|
||||||
|
// 根据选择的类型显示对应的表单并启用其输入
|
||||||
|
var showId = '';
|
||||||
|
switch(type) {
|
||||||
|
case '1': showId = '#single_choice'; break;
|
||||||
|
case '2': showId = '#multiple_choice'; break;
|
||||||
|
case '3': showId = '#true_false'; break;
|
||||||
|
case '4': showId = '#fill_blank'; break;
|
||||||
|
case '5': showId = '#short_answer'; break;
|
||||||
|
case '6': showId = '#programming'; break;
|
||||||
|
}
|
||||||
|
if(showId) {
|
||||||
|
$(showId).show().find('input,select,textarea').prop('disabled', false);
|
||||||
|
}
|
||||||
|
form.render(); // 重新渲染表单
|
||||||
|
});
|
||||||
|
|
||||||
|
// 默认选中单选题并触发事件
|
||||||
|
$('select[name="type"]').val('1');
|
||||||
|
form.render('select');
|
||||||
|
// 触发layui select事件
|
||||||
|
form.on('select(questionType)', function (data) {
|
||||||
|
var type = data.value;
|
||||||
|
// 隐藏所有题目类型表单并禁用其输入
|
||||||
|
$('.question-type-form').hide().find('input,select,textarea').prop('disabled', true).val('');
|
||||||
|
// 根据选择的类型显示对应的表单并启用其输入
|
||||||
|
var showId = '';
|
||||||
|
switch(type) {
|
||||||
|
case '1': showId = '#single_choice'; break;
|
||||||
|
case '2': showId = '#multiple_choice'; break;
|
||||||
|
case '3': showId = '#true_false'; break;
|
||||||
|
case '4': showId = '#fill_blank'; break;
|
||||||
|
case '5': showId = '#short_answer'; break;
|
||||||
|
case '6': showId = '#programming'; break;
|
||||||
|
}
|
||||||
|
if(showId) {
|
||||||
|
$(showId).show().find('input,select,textarea').prop('disabled', false);
|
||||||
|
}
|
||||||
|
form.render(); // 重新渲染表单
|
||||||
|
});
|
||||||
|
// 主动触发一次select事件,确保单选题表单显示
|
||||||
|
form.render('select');
|
||||||
|
$('select[name="type"]').next().find('dl dd[lay-value="1"]').click();
|
||||||
|
|
||||||
|
// 配置 wangeditor 编辑器
|
||||||
|
const { createEditor, createToolbar } = window.wangEditor;
|
||||||
|
const editorConfig = {
|
||||||
|
MENU_CONF: {},
|
||||||
|
placeholder: '请输入内容...',
|
||||||
|
onChange(editor) {
|
||||||
|
const html = editor.getHtml();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
editorConfig.MENU_CONF['uploadImage'] = {
|
||||||
|
server: '{:url("index/upload_img")}',
|
||||||
|
fieldName: 'file',
|
||||||
|
maxFileSize: 50 * 1024 * 1024,
|
||||||
|
maxNumberOfFiles: 10,
|
||||||
|
allowedFileTypes: ['image/*'],
|
||||||
|
meta: { token: 'xxx' },
|
||||||
|
metaWithUrl: true,
|
||||||
|
headers: { Accept: 'text/x-json' },
|
||||||
|
timeout: 30 * 1000,
|
||||||
|
onBeforeUpload(file) {
|
||||||
|
console.log('准备上传图片', file);
|
||||||
|
return file;
|
||||||
|
},
|
||||||
|
onProgress(progress) {
|
||||||
|
console.log('上传进度', progress);
|
||||||
|
},
|
||||||
|
onSuccess(file, res) {
|
||||||
|
console.log('上传成功', file, res);
|
||||||
|
},
|
||||||
|
onFailed(file, res) {
|
||||||
|
layer.msg('上传失败:' + res.msg, { icon: 2 });
|
||||||
|
console.log('上传失败', file, res);
|
||||||
|
},
|
||||||
|
onError(file, err, res) {
|
||||||
|
layer.msg('上传出错:' + err.message, { icon: 2 });
|
||||||
|
console.error('上传出错', file, err, res);
|
||||||
|
},
|
||||||
|
customInsert(res, insertFn) {
|
||||||
|
if (res.code === 0 && res.url) {
|
||||||
|
let imageUrl = res.url;
|
||||||
|
if (!imageUrl.startsWith('http')) {
|
||||||
|
imageUrl = 'https://' + imageUrl;
|
||||||
|
}
|
||||||
|
imageUrl = imageUrl.replace(/^https?:\/\/[^\/]+\/admin\/resources\//, 'https://www.yunzer.cn/');
|
||||||
|
insertFn(imageUrl);
|
||||||
|
} else {
|
||||||
|
layer.msg('图片上传失败:' + (res.msg || '未知错误'), { icon: 2 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const editor = createEditor({
|
||||||
|
selector: '#editor-container',
|
||||||
|
html: '<p><br></p>',
|
||||||
|
config: editorConfig,
|
||||||
|
mode: 'default',
|
||||||
|
});
|
||||||
|
const toolbar = createToolbar({
|
||||||
|
editor,
|
||||||
|
selector: '#toolbar-container',
|
||||||
|
config: {},
|
||||||
|
mode: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单提交
|
||||||
|
form.on('submit(formSubmit)', function (data) {
|
||||||
|
var content = editor.getHtml();
|
||||||
|
if (!content || content === '<p><br></p>') {
|
||||||
|
layer.msg('请输入文章内容', { icon: 2 });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$('#content-hidden').val(content); // 同步内容到隐藏input
|
||||||
|
var loadIndex = layer.load(2);
|
||||||
|
data.field.content = content;
|
||||||
|
$.ajax({
|
||||||
|
url: '{:url("resources/add")}',
|
||||||
|
type: 'POST',
|
||||||
|
data: data.field,
|
||||||
|
success: function (res) {
|
||||||
|
layer.close(loadIndex);
|
||||||
|
if (res.code == 0) {
|
||||||
|
layer.msg(res.msg, { icon: 1 });
|
||||||
|
setTimeout(function () {
|
||||||
|
window.location.href = '{:url("resources/lists")}';
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
layer.msg(res.msg, { icon: 2 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
//返回题目列表
|
||||||
|
function goBack() {
|
||||||
|
window.location.href = '{:url("resources/lists")}';
|
||||||
|
}
|
||||||
|
}); // <-- 这里闭合layui.use的function
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.form-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-label {
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-left {
|
||||||
|
width: 35%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-right {
|
||||||
|
width: 65%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
204
app/admin/view/tk/topiclist.php
Normal file
204
app/admin/view/tk/topiclist.php
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
{include file="public/header" /}
|
||||||
|
<div class="config-container">
|
||||||
|
<!-- 页面头部样式 -->
|
||||||
|
<div class="config-header" style="display: flex;flex-direction: column;flex-wrap: wrap;align-items: flex-start;">
|
||||||
|
<div class="maintitle">
|
||||||
|
<i class="layui-icon layui-icon-form"></i>
|
||||||
|
<span>题目列表</span>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex;align-items: flex-start;flex-direction: column;gap: 15px;margin-bottom: 10px;">
|
||||||
|
<div class="shaixuan">
|
||||||
|
<label>筛选:</label>
|
||||||
|
<div class="layui-form" style="display: flex; gap: 10px;">
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input type="text" id="nameSearch" placeholder="搜索题目内容" class="layui-input">
|
||||||
|
</div>
|
||||||
|
<button type="button" class="layui-btn layui-btn-normal" onclick="doSearch()">
|
||||||
|
<i class="layui-icon layui-icon-search"></i>搜索
|
||||||
|
</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary layui-border-blue" onclick="doRefresh()">
|
||||||
|
<i class="layui-icon layui-icon-refresh"></i>重置
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="layui-btn layui-btn-normal" onclick="add()">
|
||||||
|
<i class="layui-icon layui-icon-add-1"></i>添加题目
|
||||||
|
</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary layui-border-blue" onclick="refresh()">
|
||||||
|
<i class="layui-icon layui-icon-refresh"></i>刷新
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="topicTable" lay-filter="topicTable"></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="questionTypeTemplate">
|
||||||
|
{{#
|
||||||
|
var typeText = '';
|
||||||
|
switch(d.question_type){
|
||||||
|
case 1: typeText = '单选'; break;
|
||||||
|
case 2: typeText = '多选'; break;
|
||||||
|
case 3: typeText = '判断'; break;
|
||||||
|
case 4: typeText = '填空'; break;
|
||||||
|
case 5: typeText = '简答'; break;
|
||||||
|
case 6: typeText = '编程'; break;
|
||||||
|
default: typeText = '未知';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{{ typeText }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="difficultyTemplate">
|
||||||
|
{{#
|
||||||
|
var stars = '';
|
||||||
|
for(var i=1; i<=5; i++){
|
||||||
|
stars += i <= d.difficulty ? '★' : '☆';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{{ stars }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="operationBar">
|
||||||
|
<button type="button" class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">
|
||||||
|
<i class="layui-icon layui-icon-edit"></i>编辑
|
||||||
|
</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" lay-event="del">
|
||||||
|
<i class="layui-icon layui-icon-delete"></i>删除
|
||||||
|
</button>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
layui.use(['layer', 'form', 'table'], function () {
|
||||||
|
var layer = layui.layer;
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var form = layui.form;
|
||||||
|
var table = layui.table;
|
||||||
|
|
||||||
|
// 初始化表格
|
||||||
|
table.render({
|
||||||
|
elem: '#resourceTable',
|
||||||
|
url: '/admin/resources/lists',
|
||||||
|
method: 'get',
|
||||||
|
cols: [[
|
||||||
|
{ field: 'id', title: 'ID' },
|
||||||
|
{ field: 'question_type', title: '题型' },
|
||||||
|
{ field: 'subject_id', title: '科目' },
|
||||||
|
{ field: 'knowledge_point_id', title: '知识点' },
|
||||||
|
{ field: 'difficulty', title: '难度' },
|
||||||
|
{ field: 'is_deleted', title: '状态' },
|
||||||
|
{ title: '操作', toolbar: '#operationBar' }
|
||||||
|
]],
|
||||||
|
page: true,
|
||||||
|
limit: 10,
|
||||||
|
limits: [10, 50, 100],
|
||||||
|
//height: 'full-220'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听工具条事件
|
||||||
|
table.on('tool(topicTable)', function (obj) {
|
||||||
|
var data = obj.data;
|
||||||
|
if (obj.event === 'edit') {
|
||||||
|
edit(data.id);
|
||||||
|
} else if (obj.event === 'del') {
|
||||||
|
del(data.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听分类筛选变化
|
||||||
|
form.on('select(categoryFilter)', function (data) {
|
||||||
|
filterByCategory(data.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function filterByCategory(categoryId) {
|
||||||
|
reloadTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSearch() {
|
||||||
|
var nameKeyword = $('#nameSearch').val().trim();
|
||||||
|
|
||||||
|
if (!nameKeyword && !$('#categoryFilter').val()) {
|
||||||
|
layer.msg('请输入搜索条件', { icon: 0 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
function doRefresh() {
|
||||||
|
// 清空搜索条件
|
||||||
|
$('#nameSearch').val('');
|
||||||
|
$('#categoryFilter').val('');
|
||||||
|
layui.form.render('select'); // 重新渲染select
|
||||||
|
|
||||||
|
// 重新加载表格,不带任何筛选条件
|
||||||
|
layui.table.reload('topicTable', {
|
||||||
|
where: {},
|
||||||
|
page: {
|
||||||
|
curr: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.msg('已重置', { icon: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadTable() {
|
||||||
|
var categoryId = $('#categoryFilter').val();
|
||||||
|
var categoryName = '';
|
||||||
|
if (categoryId) {
|
||||||
|
var selectedOption = $('#categoryFilter option[value="' + categoryId + '"]');
|
||||||
|
if (selectedOption.length > 0) {
|
||||||
|
categoryName = selectedOption.text().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var nameKeyword = $('#nameSearch').val().trim();
|
||||||
|
|
||||||
|
layui.table.reload('topicTable', {
|
||||||
|
where: {
|
||||||
|
category: categoryName,
|
||||||
|
name: nameKeyword
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
curr: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function add() {
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: '添加题目',
|
||||||
|
area: ['800px', '700px'], // 宽度800px,高度100%
|
||||||
|
shadeClose: true, // 点击遮罩关闭
|
||||||
|
content: '/admin/tk/topicadd'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit(id) {
|
||||||
|
window.location.href = '/admin/tk/topicedit?id=' + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function del(id) {
|
||||||
|
layer.confirm('确定要删除该题目吗?', {
|
||||||
|
btn: ['确定', '取消']
|
||||||
|
}, function () {
|
||||||
|
$.post('/admin/tk/topicdelete', { id: id }, function (res) {
|
||||||
|
if (res.code == 0) {
|
||||||
|
layer.msg(res.msg, { icon: 1 });
|
||||||
|
setTimeout(function () {
|
||||||
|
layui.table.reload('topicTable');
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
layer.msg(res.msg, { icon: 2 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
layui.table.reload('topicTable');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
19780
public/static/css/bootstrap.min.css
vendored
19780
public/static/css/bootstrap.min.css
vendored
File diff suppressed because it is too large
Load Diff
2732
public/static/js/bootstrap.bundle.js
vendored
2732
public/static/js/bootstrap.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
7687
public/static/js/bootstrap.bundle.min.js
vendored
7687
public/static/js/bootstrap.bundle.min.js
vendored
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user