init
This commit is contained in:
commit
db843337ce
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# CakePHP 3
|
||||
|
||||
/vendor/*
|
||||
/config/app.php
|
||||
/tmp/*
|
||||
/logs/*
|
||||
|
||||
# CakePHP 2
|
||||
|
||||
/app/tmp/*
|
||||
/app/Config/core.php
|
||||
/app/Config/database.php
|
||||
/vendors/*
|
||||
.idea
|
20
LICENSE
Normal file
20
LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 轶哥
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
447
api.php
Normal file
447
api.php
Normal file
@ -0,0 +1,447 @@
|
||||
<?php
|
||||
error_reporting(0);
|
||||
require_once 'config.php';
|
||||
require_once 'medoo.php';
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
$database = new Medoo($DBCONFIG);
|
||||
|
||||
$redis = new Redis();
|
||||
$redis->connect($REDISCONFIG['host'], $REDISCONFIG['port'], $REDISCONFIG['database']);
|
||||
$redis->auth($REDISCONFIG['password']);
|
||||
|
||||
header('Access-Control-Allow-Headers: Authorization, DNT, User-Agent, Keep-Alive, Origin, X-Requested-With, Content-Type, Accept, x-clientid');
|
||||
header('Access-Control-Allow-Methods: PUT, POST, GET, DELETE, OPTIONS');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
function action_login($database, $redis)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, 'https://login.yige.ink/info?token=' . $_ENV['API_TOKEN'] . '&code=' . $_GET['code']);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$output = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$output_array = json_decode($output, true);
|
||||
|
||||
$output_array['privilege'] = json_encode($output_array['privilege']);
|
||||
|
||||
$row = $database->select('userinfo', '*', [
|
||||
'openid' => $output_array['openid'],
|
||||
]);
|
||||
|
||||
if (sizeof($row) != 0) {
|
||||
$database->update('userinfo', $output_array, [
|
||||
'openid' => $output_array['openid'],
|
||||
]);
|
||||
|
||||
$output_array['openid'] = null;
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'id' => $row[0]['id'],
|
||||
'userinfo' => $output_array
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
$database->insert('userinfo', $output_array);
|
||||
|
||||
$output_array['openid'] = null;
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'id' => $database->id(),
|
||||
'userinfo' => $output_array
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function action_listUser($database, $redis)
|
||||
{
|
||||
$row = $database->select('userinfo', '*');
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'list' => $row,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function action_getUserInfo($database, $redis)
|
||||
{
|
||||
$row = $database->select('userinfo', '*', [
|
||||
'id' => $_POST['id'],
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'userinfo' => $row[0]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function action_setRealName($database, $redis)
|
||||
{
|
||||
$database->update('userinfo', [
|
||||
'realname' => $_POST['realname']
|
||||
], [
|
||||
'id' => $_POST['id'],
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
function handleRow($row)
|
||||
{
|
||||
foreach ($row as $ro => $val) {
|
||||
if (is_numeric($ro)) {
|
||||
unset($row[$ro]);
|
||||
}
|
||||
}
|
||||
if ($row['isAnswer'] == '1') {
|
||||
$row['isAnswer'] = '有';
|
||||
} else {
|
||||
$row['isAnswer'] = '无';
|
||||
}
|
||||
|
||||
$row['passPercent'] = round((float)$row['passPercent'] * 100, 2) . '%';
|
||||
|
||||
if ($row['difficulty'] == '1') {
|
||||
$row['difficulty'] = '简单';
|
||||
} else if ($row['difficulty'] == '2') {
|
||||
$row['difficulty'] = '中等';
|
||||
} else if ($row['difficulty'] == '3') {
|
||||
$row['difficulty'] = '困难';
|
||||
}
|
||||
|
||||
unset($row['type']);
|
||||
|
||||
return array_values($row);
|
||||
}
|
||||
|
||||
function handleSortRows($rows)
|
||||
{
|
||||
uksort($rows, function ($a, $b) {
|
||||
return (int)$a['no'] - (int)$b['no'];
|
||||
});
|
||||
}
|
||||
|
||||
function action_getProblemsetList($database, $redis)
|
||||
{
|
||||
// $rowAll = $database->debug()->select('problemset', [
|
||||
// "[>]record" => [
|
||||
// "id" => "problemset_id",
|
||||
// $_GET['user_id'] => "user_id"
|
||||
// ],
|
||||
// ], [
|
||||
// 'record.is_pass',
|
||||
// 'problemset.id',
|
||||
// 'problemset.no',
|
||||
// 'problemset.name',
|
||||
// 'problemset.language',
|
||||
// 'problemset.type',
|
||||
// 'problemset.isAnswer',
|
||||
// 'problemset.passPercent',
|
||||
// 'problemset.difficulty',
|
||||
// ], [
|
||||
// "ORDER" => "no"
|
||||
// ]);
|
||||
|
||||
$rowAll = $database->query("SELECT
|
||||
`record`.`is_pass`,
|
||||
`problemset`.`id`,
|
||||
`problemset`.`no`,
|
||||
`problemset`.`name`,
|
||||
`problemset`.`language`,
|
||||
`problemset`.`type`,
|
||||
`problemset`.`isAnswer`,
|
||||
`problemset`.`passPercent`,
|
||||
`problemset`.`difficulty`
|
||||
FROM
|
||||
`problemset`
|
||||
LEFT JOIN `record` ON `problemset`.`id` = `record`.`problemset_id` AND `record`.`user_id` = " . $_GET['user_id'] . " ORDER BY
|
||||
`no`")->fetchAll();
|
||||
|
||||
$rowStage = [];
|
||||
$rowChallenge = [];
|
||||
|
||||
foreach ($rowAll as $row)
|
||||
if ($row['type'] == '1')
|
||||
array_push($rowStage, handleRow($row));
|
||||
else
|
||||
array_push($rowChallenge, handleRow($row));
|
||||
|
||||
|
||||
handleSortRows($rowStage);
|
||||
|
||||
handleSortRows($rowChallenge);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'stage' => $rowStage,
|
||||
'challenge' => $rowChallenge,
|
||||
'test' => $database->log()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function action_editProblemset($database, $redis)
|
||||
{
|
||||
$datas = $_POST;
|
||||
|
||||
$database->update('problemset', $datas, [
|
||||
'id' => $_GET['id']
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
function action_addProblemset($database, $redis)
|
||||
{
|
||||
$datas = $_POST;
|
||||
|
||||
$datas['no'] = $redis->incr("ids_" . $datas['type']);
|
||||
|
||||
$database->insert('problemset', $datas);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'id' => $database->id(),
|
||||
'no' => $datas['no']
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function action_getProblemset($database, $redis)
|
||||
{
|
||||
if (isset($_GET['id'])) {
|
||||
$row = $database->select('problemset', '*', [
|
||||
'id' => $_GET['id']
|
||||
]);
|
||||
if (sizeof($row) > 0) {
|
||||
$row = $row[0];
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => $row
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'status' => 2,
|
||||
'msg' => '没有找到此题目信息'
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode([
|
||||
'status' => 0,
|
||||
'msg' => '缺少必须参数'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function action_saveTestCode($database, $redis)
|
||||
{
|
||||
$datas = $_POST;
|
||||
|
||||
$redis->set('testCode_' . $datas['user_id'], $datas['code']);
|
||||
|
||||
// if ($database->has("test_record", [
|
||||
// 'user_id' => $datas['user_id']
|
||||
// ])) {
|
||||
// $database->update("test_record", [
|
||||
// 'code' => $datas['code']
|
||||
// ], [
|
||||
// 'user_id' => $datas['user_id']
|
||||
// ]);
|
||||
// } else {
|
||||
// $database->insert('test_record', $datas);
|
||||
// }
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
function action_getTestCode($database, $redis)
|
||||
{
|
||||
$datas = $_POST;
|
||||
|
||||
// $row = $database->select("test_record", ["code"], [
|
||||
// 'user_id' => $datas['user_id']
|
||||
// ]);
|
||||
|
||||
$res = $redis->get('testCode_' . $datas['user_id']);
|
||||
|
||||
if ($res == null || $res == "") {
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'code' => '<?php
|
||||
echo "Hello World!";'
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'code' => $res
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function addCredit($database, $problemsetId, $userId)
|
||||
{
|
||||
$problemsetRow = $database->select("problemset", ['id', 'isCredit', 'credit', 'type', 'no'], [
|
||||
'id' => $problemsetId
|
||||
]);
|
||||
|
||||
if ($problemsetRow[0]['isCredit'] == '1') {
|
||||
$userinfoRow = $database->select("userinfo", ['id', "credit"], [
|
||||
'id' => $userId
|
||||
]);
|
||||
|
||||
$oldCredit = $userinfoRow[0]['credit'];
|
||||
|
||||
$addCredit = $problemsetRow[0]['credit'];
|
||||
|
||||
$newCredit = (int)$oldCredit + (int)$addCredit;
|
||||
|
||||
if (!$database->has("credit_flow", [ // 限制一道题只能获得一次积分
|
||||
'problemset_id' => $problemsetId
|
||||
])) {
|
||||
$theType = '闯关模式';
|
||||
if ($problemsetRow[0]['type'] == '2') {
|
||||
$theType = '挑战赛';
|
||||
}
|
||||
|
||||
$log = $theType . '第' . $problemsetRow[0]['no'] . '题得分';
|
||||
|
||||
$database->insert('credit_flow', [ // 写入积分变动日志
|
||||
'log' => $log,
|
||||
'user_id' => $userId,
|
||||
'problemset_id' => $problemsetId,
|
||||
'income' => $addCredit,
|
||||
'credit' => $newCredit
|
||||
]);
|
||||
|
||||
$database->update('userinfo', [
|
||||
'credit' => $newCredit
|
||||
], [
|
||||
'id' => $userId
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function action_addRecord($database, $redis)
|
||||
{
|
||||
$datas = $_POST;
|
||||
|
||||
$row = $database->select("record", ['is_pass'], [
|
||||
'user_id' => $datas['user_id'],
|
||||
'problemset_id' => $datas['problemset_id']
|
||||
]);
|
||||
|
||||
if (sizeof($row) != 0) {
|
||||
if ($datas['is_pass'] == '1' || $row[0]['is_pass'] != '1') {
|
||||
$database->update('record', $datas, [
|
||||
'user_id' => $datas['user_id'],
|
||||
'problemset_id' => $datas['problemset_id']
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$database->insert('record', $datas);
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1
|
||||
]);
|
||||
|
||||
fastcgi_finish_request();
|
||||
|
||||
// 异步
|
||||
|
||||
if ($datas['is_pass'] == '1') { // 增加积分
|
||||
addCredit($database, $datas['problemset_id'], $datas['user_id']);
|
||||
}
|
||||
}
|
||||
|
||||
function action_getRecord($database, $redis)
|
||||
{
|
||||
$datas = $_POST;
|
||||
|
||||
$row = $database->select("record", ['code'], [
|
||||
'user_id' => $datas['user_id'],
|
||||
'problemset_id' => $datas['problemset_id']
|
||||
]);
|
||||
|
||||
if (sizeof($row) != 0) {
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'code' => $row[0]['code']
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'status' => 2
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function action_getNextNo($database, $redis)
|
||||
{
|
||||
$no = (int)$_GET['no'] + 1;
|
||||
|
||||
$row = $database->select("problemset", ["id"], [
|
||||
'no' => $no,
|
||||
'type' => $_GET['type']
|
||||
]);
|
||||
|
||||
if (sizeof($row) != 0) {
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'id' => $row[0]['id']
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'id' => 0
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function action_getMyRecordCount($database, $redis)
|
||||
{
|
||||
$Allcount = $database->count("problemset", [
|
||||
"type" => "1"
|
||||
]);
|
||||
|
||||
$passCount = $database->count("record", [
|
||||
'user_id' => $_GET['user_id'],
|
||||
'is_pass' => '1'
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 1,
|
||||
'result' => [
|
||||
'all' => $Allcount,
|
||||
'pass' => $passCount
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
if (isset($_GET['action'])) {
|
||||
$action = "action_" . $_GET['action'];
|
||||
$action($database, $redis);
|
||||
} else {
|
||||
echo json_encode(['err' => '非法访问']);
|
||||
}
|
17
config.php
Normal file
17
config.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
$DBCONFIG = [
|
||||
'database_type' => 'mysql',
|
||||
'database_name' => $_ENV['MYSQL_DBNAME'],
|
||||
'server' => $_ENV['MYSQL_HOST'],
|
||||
'username' => $_ENV['MYSQL_USERNAME'],
|
||||
'password' => $_ENV['MYSQL_PASSWORD'],
|
||||
'charset' => 'utf8mb4',
|
||||
'port' => $_ENV['MYSQL_PORT'],
|
||||
];
|
||||
|
||||
$REDISCONFIG = [
|
||||
'host' => $_ENV['REDIS_HOST'],
|
||||
'port' => $_ENV['REDIS_PORT'],
|
||||
'password' => $_ENV['REDIS_PASSWORD'],
|
||||
'database' => 0
|
||||
];
|
281
css/common.css
Normal file
281
css/common.css
Normal file
@ -0,0 +1,281 @@
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: rgb(61, 146, 201);
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9999999;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#loading img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 16px;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.pure-menu-selected .pure-menu-link, .pure-menu-selected .pure-menu-link:visited {
|
||||
background-color: #373C5A;
|
||||
color: #adbdad;
|
||||
}
|
||||
|
||||
.pure-menu-heading {
|
||||
color: #d7d9dc;
|
||||
}
|
||||
|
||||
.pure-menu-link {
|
||||
color: #adbdad;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
/* LAYOUT CSS */
|
||||
.pure-img-responsive {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#layout {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
top: auto;
|
||||
padding: 0.5em 1em;
|
||||
margin: 0 0;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
background-color: #252A3A;
|
||||
}
|
||||
|
||||
.header .pure-menu {
|
||||
border-bottom-color: black;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.userinfo {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 50px;
|
||||
}
|
||||
|
||||
#leftPane {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#rightPane {
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#avator img {
|
||||
margin-top: 5px;
|
||||
width: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#logout {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 1em;
|
||||
}
|
||||
|
||||
#avator {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#nickname {
|
||||
color: #888;
|
||||
line-height: 50px;
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#realname {
|
||||
color: #888;
|
||||
line-height: 50px;
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#container {
|
||||
width: 100%;
|
||||
min-height: 300px;
|
||||
min-width: 300px;
|
||||
border: 1px solid #eeeeee;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding: 1em 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
color: #ccc;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.footer .pure-menu a:hover,
|
||||
.footer .pure-menu a:focus {
|
||||
background: none;
|
||||
}
|
||||
|
||||
#out {
|
||||
margin-top: 0;
|
||||
border: 1px solid #eeeeee;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#run {
|
||||
margin-top: 10px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#testRun {
|
||||
margin-top: 10px;
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.auto {
|
||||
line-height: 60px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
background: #fff;
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#rightPane code {
|
||||
color: #888;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
/* index.php */
|
||||
|
||||
.index-main {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.index-main-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.horizontal {
|
||||
list-style: none outside none;
|
||||
margin: 15px 0;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.horizontal li {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.horizontal .active .pure-button {
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, .15) inset, 0 0 6px rgba(0, 0, 0, .2) inset;
|
||||
}
|
||||
|
||||
.admin {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#describeView, #answerView, #resultView {
|
||||
height: 100%;
|
||||
padding-bottom: 110px;
|
||||
}
|
||||
|
||||
#describeView .cont, #answerView .cont {
|
||||
border: 1px solid #eeeeee;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#resultView .cont {
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.testCase {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.testCaseContent, .expectedResultContent {
|
||||
border: 1px solid #eeeeee;
|
||||
padding: 5px 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.expectedResult {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.resultContent {
|
||||
height: 100%;
|
||||
border: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
#rightPane .cont pre code {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.dataTable td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dataTable .table-pname {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.myCredit {
|
||||
position: absolute;
|
||||
right: 50px;
|
||||
top: 63px;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
.myRecord {
|
||||
position: absolute;
|
||||
right: 150px;
|
||||
top: 63px;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
.dataTable .table-is-pass {
|
||||
text-align: right;
|
||||
}
|
82
css/jquery.splitter.css
Normal file
82
css/jquery.splitter.css
Normal file
@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* StyleSheet for JQuery splitter Plugin version 0.27.1
|
||||
* Copyright (C) 2010-2018 Jakub T. Jankiewicz <https://jcubic.pl/me>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.splitter_panel {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.splitter_panel .vsplitter {
|
||||
background-color: #f5f5f5;
|
||||
cursor: col-resize;
|
||||
z-index: 900;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.splitter_panel .vsplitter:hover {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
.splitter_panel .hsplitter {
|
||||
background-color: #5F5F5F;
|
||||
cursor: row-resize;
|
||||
z-index: 800;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.splitter_panel .vsplitter.splitter-invisible,
|
||||
.splitter_panel .hsplitter.splitter-invisible {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.splitter_panel .vsplitter, .splitter_panel .left_panel, .splitter_panel .right_panel,
|
||||
.splitter_panel .hsplitter, .splitter_panel .top_panel, .splitter_panel .bottom_panel {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.splitter_panel .vsplitter, .splitter_panel .left_panel, .splitter_panel .right_panel {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.splitter_panel .hsplitter, .splitter_panel .top_panel, .splitter_panel .bottom_panel {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.splitter_panel .top_panel, .splitter_panel .left_panel, .splitter_panel .vsplitter {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.splitter_panel .top_panel, .splitter_panel .bottom_panel, .splitter_panel .left_panel, .splitter_panel .hsplitter {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.splitter_panel .bottom_panel {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.splitter_panel .right_panel {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.splitterMask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
}
|
91
db.sql
Normal file
91
db.sql
Normal file
@ -0,0 +1,91 @@
|
||||
-- 开饭平台用户信息:
|
||||
-- openid 普通用户的标识,对当前开发者帐号唯一
|
||||
-- nickname 普通用户昵称
|
||||
-- sex 普通用户性别,1为男性,2为女性
|
||||
-- province 普通用户个人资料填写的省份
|
||||
-- city 普通用户个人资料填写的城市
|
||||
-- country 国家,如中国为CN
|
||||
-- headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
|
||||
-- privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
|
||||
-- unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
|
||||
-- 开放平台用户
|
||||
CREATE TABLE `userinfo`(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`openid` VARCHAR(64) NULL DEFAULT '' COMMENT '微信openid',
|
||||
`nickname` VARCHAR(128) NULL COMMENT '用户昵称',
|
||||
`realname` VARCHAR(20) NULL COMMENT '真实姓名',
|
||||
`sex` TINYINT(1) NULL COMMENT '用户性别,1男性,2女性',
|
||||
`language` VARCHAR(16) NULL COMMENT '语言',
|
||||
`province` VARCHAR(16) NULL COMMENT '用户个人资料填写的省份',
|
||||
`city` VARCHAR(16) NULL COMMENT '普通用户个人资料填写的城市',
|
||||
`country` VARCHAR(32) NULL COMMENT '国家,如中国为CN',
|
||||
`headimgurl` VARCHAR(256) NULL COMMENT '用户头像',
|
||||
`privilege` TEXT NULL COMMENT '用户特权信息,json 数组',
|
||||
`unionid` VARCHAR(128) NULL COMMENT '微信开放平台用户唯一标识',
|
||||
`admin` TINYINT(1) NULL DEFAULT 0 COMMENT '是否是管理员,1是,0不是',
|
||||
`credit` VARCHAR(128) NULL COMMENT '积分',
|
||||
`created_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
-- 题目
|
||||
CREATE TABLE `problemset`(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`no` BIGINT UNSIGNED NOT NULL,
|
||||
`type` VARCHAR(12) NULL COMMENT '分类',
|
||||
`name` VARCHAR(128) NULL COMMENT '题名',
|
||||
`isAnswer` VARCHAR(12) NULL COMMENT '是否有解答,1有,其余无',
|
||||
`language` VARCHAR(16) NULL COMMENT '编程语言',
|
||||
`passPercent` VARCHAR(16) NULL COMMENT '通过率',
|
||||
`difficulty` VARCHAR(16) NULL COMMENT '难度',
|
||||
`tag` VARCHAR(255) NULL COMMENT '标签',
|
||||
`mark` VARCHAR(256) NULL COMMENT '备注',
|
||||
`describe` LONGTEXT NULL COMMENT '题目描述',
|
||||
`answer` LONGTEXT NULL COMMENT '解答',
|
||||
`phpCode` LONGTEXT NULL COMMENT 'PHP代码',
|
||||
`javascriptCode` LONGTEXT NULL COMMENT 'Javascript代码',
|
||||
`phpUnitCode` LONGTEXT NULL COMMENT 'PHP测试代码',
|
||||
`testCase` LONGTEXT NULL COMMENT '测试用例',
|
||||
`expectedResult` LONGTEXT NULL COMMENT '预期结果',
|
||||
`credit` DECIMAL(8, 2) NULL COMMENT '积分',
|
||||
`isCredit` VARCHAR(5) NULL DEFAULT '0' COMMENT '是否积分,1是,0不是',
|
||||
`created_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
-- 做题记录
|
||||
CREATE TABLE `record`(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` BIGINT UNSIGNED NOT NULL,
|
||||
`problemset_id` BIGINT UNSIGNED NOT NULL,
|
||||
`type` VARCHAR(12) NULL COMMENT '分类',
|
||||
`code` LONGTEXT NULL COMMENT '代码',
|
||||
`is_pass` VARCHAR(5) NULL DEFAULT '0' COMMENT '是否通过测试,1是,0不是',
|
||||
`created_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
-- -- 在线测试的记录
|
||||
-- CREATE TABLE `test_record`(
|
||||
-- `user_id` BIGINT UNSIGNED NOT NULL,
|
||||
-- `code` LONGTEXT NULL COMMENT '代码',
|
||||
-- `created_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
-- `updated_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
-- PRIMARY KEY(`user_id`)
|
||||
-- );
|
||||
|
||||
-- 积分变动(流水)
|
||||
CREATE TABLE `credit_flow`(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` BIGINT UNSIGNED NOT NULL,
|
||||
`problemset_id` BIGINT UNSIGNED NOT NULL,
|
||||
`log` VARCHAR(256) NULL COMMENT '事由',
|
||||
`income` DECIMAL(8) NOT NULL COMMENT '动账',
|
||||
`credit` DECIMAL(8) NOT NULL COMMENT '当时总积分',
|
||||
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
28
footer.php
Normal file
28
footer.php
Normal file
@ -0,0 +1,28 @@
|
||||
</div>
|
||||
|
||||
<script src="/js/uniter.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT"
|
||||
src="https://lib.baomitu.com/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-RnOqe29SFv+Lre8BvIid2hveg/hFrUKA+uLJCbdL0EyEd6DzesjrF3dIhHh2EHsq"
|
||||
src="https://lib.baomitu.com/jquery.tabslet.js/1.7.3/jquery.tabslet.min.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-rgWRqC0OFPisxlUvl332tiM/qmaNxnlY46eksSZD84t+s2vZlqGeHrncwIRX7CGp"
|
||||
src="https://lib.baomitu.com/datatables/1.10.19/js/jquery.dataTables.min.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-83rBTICYr+FwAC+A5t0ZYsWjTcPXibCe/NBSFLAgMPkwHBvIi02EcE9OShMsGCi3"
|
||||
src="https://lib.baomitu.com/simplemde/1.11.2/simplemde.min.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-KpuxVjTC2hfOkg5KV3jSdx1eA6xy0PGS0wNfDrwf4sZBnZdzlIsnkH+LzLkavmH7"
|
||||
src="https://lib.baomitu.com/showdown/1.9.0/showdown.min.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-BlPof9RtjBqeJFskKv3sK3dh4Wk70iKlpIe92FeVN+6qxaGUOUu+mZNpALZ+K7ya"
|
||||
src="https://lib.baomitu.com/highlight.js/9.13.1/highlight.min.js"></script>
|
||||
<script crossorigin="anonymous" integrity="sha384-heo+KfbBN7U3Mb1E3ZDC1aW97zVBWyXmxIr/HQIgGrtBAUaHD1lBFq4Jlfq86SJe"
|
||||
src="https://lib.baomitu.com/monaco-editor/0.15.6/min/vs/loader.js"></script>
|
||||
<script src="/js/jquery.splitter.js"></script>
|
||||
<script src="/js/common.js"></script>
|
||||
<script src="/js<?php
|
||||
if ($nowURL != '/') {
|
||||
echo substr($nowURL, 0, strlen($nowURL) - 4);
|
||||
} else {
|
||||
echo 'index';
|
||||
}
|
||||
?>.js"></script>
|
||||
</body>
|
||||
</html>
|
66
header.php
Normal file
66
header.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
//获得当前的脚本网址
|
||||
function GetCurUrl()
|
||||
{
|
||||
return $_SERVER["PHP_SELF"];
|
||||
}
|
||||
|
||||
$nowURL = GetCurUrl();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>在线PHP练习</title>
|
||||
<link crossorigin="anonymous" integrity="sha384-9Z9AuAj0Xi0z7WFOSgjjow8EnNY9wPNp925TVLlAyWhvZPsf5Ks23Ex0mxIrWJzJ"
|
||||
href="https://lib.baomitu.com/normalize/8.0.1/normalize.min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-GQvMoYnQA47ImcAuL/b527e+tU96IK4h/WH1i8Y2oWVSzAne5jXEPr79FFDjbP2O"
|
||||
href="https://lib.baomitu.com/pure/1.0.0/base-min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-b92sF+wDNTHrfEtRaYo+EpcA8FUyHOSXrdxKc9XB9kaaX1rSQAgMevW6cYeE5Bdv"
|
||||
href="https://lib.baomitu.com/pure/1.0.0/grids-responsive-min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-T7EqrTLlfKxgBXvvj/5Lz2LDKWPwLFsdS/T4MmXC+EjrRKTH9FWtGOn+JHoKWzSJ"
|
||||
href="https://lib.baomitu.com/pure/1.0.0/menus-min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-FmOvPjY6YwQXYea5Ja+3CH7+feIm/+HpUXtRUh8g0F7ybli4aDV//h1GzWLDpwHO"
|
||||
href="https://lib.baomitu.com/pure/1.0.0/forms-min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-fCgQlRnjKz+VWhXVjN344OnXNV9kmKYH2rCqLz4TmMne2vnO1ykQU4Cz1llu+ud8"
|
||||
href="https://lib.baomitu.com/pure/1.0.0/buttons-min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-MIf4KOt3X2OQ4tRxVM7Ygl5hNkkyYabJ8zm0m+TDRw9NYmAkEXXFpst8PVbF2s/9"
|
||||
href="https://lib.baomitu.com/pure/1.0.0/tables-min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-rQdIropf4eQBEB9SkNB4xxukYHlkyXJfKYkpVNUQOLizz+d2q0wo7zjVA2XcYSij"
|
||||
href="https://lib.baomitu.com/simplemde/1.11.2/simplemde.min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-HNGokaYN28H3qifBLVX5/ob64kuuYiIeQfo/b+M/hzijJeueJbsVEAvglj1qvfuY"
|
||||
href="https://lib.baomitu.com/highlight.js/9.13.1/styles/vs.min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" integrity="sha384-1UXhfqyOyO+W+XsGhiIFwwD3hsaHRz2XDGMle3b8bXPH5+cMsXVShDoHA3AH/y/p"
|
||||
href="https://lib.baomitu.com/datatables/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet">
|
||||
<link href="/css/jquery.splitter.css" rel="stylesheet">
|
||||
<link href="/css/common.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="loading">
|
||||
<img src="/loading.gif">
|
||||
</div>
|
||||
<div id="layout" class="pure-g">
|
||||
<div class="header">
|
||||
<div class="pure-menu pure-menu-horizontal">
|
||||
<span class="pure-menu-heading">PHP练习</span>
|
||||
<?php include('menu.php'); ?>
|
||||
</div>
|
||||
|
||||
<div class="userinfo">
|
||||
<div id="avator"></div>
|
||||
<div id="nickname"></div>
|
||||
<div id="realname"></div>
|
||||
</div>
|
||||
|
||||
<div id="logout">
|
||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" width="25" height="25">
|
||||
<path fill="#d7d9dc"
|
||||
d="M835.669333 554.666667h-473.173333A42.453333 42.453333 0 0 1 320 512a42.666667 42.666667 0 0 1 42.474667-42.666667h473.173333l-161.813333-161.834666a42.666667 42.666667 0 0 1 60.330666-60.330667l234.666667 234.666667a42.666667 42.666667 0 0 1 0 60.330666l-234.666667 234.666667a42.666667 42.666667 0 0 1-60.330666-60.330667L835.669333 554.666667zM554.666667 42.666667a42.666667 42.666667 0 1 1 0 85.333333H149.525333C137.578667 128 128 137.578667 128 149.482667v725.034666C128 886.4 137.6 896 149.525333 896H554.666667a42.666667 42.666667 0 1 1 0 85.333333H149.525333A106.816 106.816 0 0 1 42.666667 874.517333V149.482667A106.773333 106.773333 0 0 1 149.525333 42.666667H554.666667z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
24
index.php
Normal file
24
index.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php include('header.php'); ?>
|
||||
<div class="myRecord"><button class="pure-button" id="myRecordButton">我的学习统计</button></div>
|
||||
<div class="myCredit"></div>
|
||||
<div class='tabs tabs_default'>
|
||||
<ul class='horizontal'>
|
||||
<li><a class="pure-button" href="#stage">闯关模式</a></li>
|
||||
<li><a class="pure-button" href="#challenge">挑战赛</a></li>
|
||||
<li><a class="pure-button admin" target="_blank" href="/page/user.php">用户管理</a></li>
|
||||
<li><a class="pure-button pure-button-primary admin" target="_blank" href="/page/edit.php">添加新题目</a></li>
|
||||
</ul>
|
||||
<div id='stage'>
|
||||
<div class="index-main">
|
||||
<table id="stage-table" class="stripe">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id='challenge'>
|
||||
<div class="index-main">
|
||||
<table id="challenge-table" class="stripe">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include('footer.php'); ?>
|
147
js/common.js
Normal file
147
js/common.js
Normal file
@ -0,0 +1,147 @@
|
||||
require.config({paths: {'vs': 'https://lib.baomitu.com/monaco-editor/0.15.6/min/vs'}});
|
||||
|
||||
// Before loading vs/editor/editor.main, define a global MonacoEnvironment that overwrites
|
||||
// the default worker url location (used when creating WebWorkers). The problem here is that
|
||||
// HTML5 does not allow cross-domain web workers, so we need to proxy the instantiation of
|
||||
// a web worker through a same-domain script
|
||||
window.MonacoEnvironment = {
|
||||
getWorkerUrl: function (workerId, label) {
|
||||
return '/js/monaco-editor-worker-loader-proxy.js';
|
||||
}
|
||||
};
|
||||
|
||||
window.isAdmin = false;
|
||||
|
||||
function getNowDate() {
|
||||
var date = new Date();
|
||||
var sign1 = "-";
|
||||
var sign2 = ":";
|
||||
var year = date.getFullYear() // 年
|
||||
var month = date.getMonth() + 1; // 月
|
||||
var day = date.getDate(); // 日
|
||||
var hour = date.getHours(); // 时
|
||||
var minutes = date.getMinutes(); // 分
|
||||
var seconds = date.getSeconds() //秒
|
||||
var weekArr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'];
|
||||
var week = weekArr[date.getDay()];
|
||||
// 给一位数数据前面加 “0”
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (day >= 0 && day <= 9) {
|
||||
day = "0" + day;
|
||||
}
|
||||
if (hour >= 0 && hour <= 9) {
|
||||
hour = "0" + hour;
|
||||
}
|
||||
if (minutes >= 0 && minutes <= 9) {
|
||||
minutes = "0" + minutes;
|
||||
}
|
||||
if (seconds >= 0 && seconds <= 9) {
|
||||
seconds = "0" + seconds;
|
||||
}
|
||||
return year + sign1 + month + sign1 + day + " " + hour + sign2 + minutes + sign2 + seconds + " " + week;
|
||||
}
|
||||
|
||||
function GetQueryString(name) {
|
||||
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
|
||||
var r = window.location.search.substr(1).match(reg);
|
||||
if (r!=null) return unescape(r[2]); return '';
|
||||
}
|
||||
|
||||
$(function () {
|
||||
var id = window.localStorage.id;
|
||||
|
||||
if (!id) {
|
||||
window.location.href = '/login.html'
|
||||
}
|
||||
|
||||
var setRealName = function (id, realname) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=setRealName",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
id: id,
|
||||
realname: realname
|
||||
},
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
console.log('保存真实姓名成功!')
|
||||
} else {
|
||||
alert('很抱歉,保存真实姓名失败,请稍后刷新重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!')
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
function loadImage(url, callback) {
|
||||
var img = new Image(); //创建一个Image对象,实现图片的预下载
|
||||
img.crossOrigin = "Anonymous";
|
||||
img.src = url;
|
||||
img.onload = function () { //图片下载完毕时异步调用callback函数
|
||||
callback.call(img);//将回调函数的this替换为Image对象
|
||||
};
|
||||
}
|
||||
|
||||
var getUserInfo = function (id) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=getUserInfo",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
if (!r.result.userinfo) {
|
||||
window.location.href = "login.html"
|
||||
}
|
||||
if (!r.result.userinfo.realname) {
|
||||
var name = prompt("请输入你的真实姓名,方便大家进行沟通", "");
|
||||
if (name != null && name !== "") {
|
||||
r.result.userinfo.realname = name;
|
||||
setRealName(id, name)
|
||||
}
|
||||
}
|
||||
|
||||
window.isAdmin = r.result.userinfo.admin === '1';
|
||||
window.credit = r.result.userinfo.credit;
|
||||
|
||||
if ($('.myCredit')) $('.myCredit').text('经验:' + window.credit);
|
||||
|
||||
loadImage(r.result.userinfo.headimgurl.replace('http://', 'https://'), function () {
|
||||
$('#avator').append(this)
|
||||
});
|
||||
|
||||
$('#realname').text(r.result.userinfo.realname);
|
||||
$('#nickname').text('(' + r.result.userinfo.nickname + ')');
|
||||
|
||||
if (window.isAdmin) {
|
||||
$('.admin').css('display', 'block')
|
||||
}
|
||||
} else {
|
||||
alert('很抱歉,获取用户信息失败,请稍后刷新重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!')
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
$('#logout').click(function () {
|
||||
window.localStorage.removeItem('id');
|
||||
window.location.href = "/login.html"
|
||||
});
|
||||
|
||||
getUserInfo(id);
|
||||
|
||||
});
|
187
js/index.js
Normal file
187
js/index.js
Normal file
@ -0,0 +1,187 @@
|
||||
$(function () {
|
||||
var language = {
|
||||
"sProcessing": "处理中...",
|
||||
"sLengthMenu": "显示 _MENU_ 项结果",
|
||||
"sZeroRecords": "没有匹配结果",
|
||||
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
|
||||
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
|
||||
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "搜索:",
|
||||
"sUrl": "",
|
||||
"sEmptyTable": "表中数据为空",
|
||||
"sLoadingRecords": "载入中...",
|
||||
"sInfoThousands": ",",
|
||||
"oPaginate": {
|
||||
"sFirst": "首页",
|
||||
"sPrevious": "上页",
|
||||
"sNext": "下页",
|
||||
"sLast": "末页"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": 以升序排列此列",
|
||||
"sSortDescending": ": 以降序排列此列"
|
||||
}
|
||||
};
|
||||
|
||||
var tableInit = function (r) {
|
||||
$('#stage-table').DataTable({
|
||||
language: language,
|
||||
data: r.result.stage,
|
||||
columns: [
|
||||
{title: ""},
|
||||
{title: "ID"},
|
||||
{title: "No"},
|
||||
{title: "题名"},
|
||||
{title: "编程语言"},
|
||||
{title: "解答"},
|
||||
{title: "通过率"},
|
||||
{title: "难度"},
|
||||
{title: "管理"}
|
||||
],
|
||||
"order": [[2, "asc"]],
|
||||
columnDefs: [
|
||||
{
|
||||
"targets": 0,
|
||||
"orderable": false,
|
||||
"className": "table-is-pass",
|
||||
"render": function (data, type, row) {
|
||||
if (data === '1') {
|
||||
return '<svg viewBox="0 0 1397 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="27" height="20"><path d="M1396.363636 121.018182c0 0-223.418182 74.472727-484.072727 372.363636-242.036364 269.963636-297.890909 381.672727-390.981818 530.618182C512 1014.690909 372.363636 744.727273 0 549.236364l195.490909-186.181818c0 0 176.872727 121.018182 297.890909 344.436364 0 0 307.2-474.763636 902.981818-707.490909L1396.363636 121.018182 1396.363636 121.018182zM1396.363636 121.018182" fill="#1afa29"></path></svg>';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": 1,
|
||||
"data": null,
|
||||
"visible": false,
|
||||
"orderable": false
|
||||
},
|
||||
{
|
||||
"targets": 3,
|
||||
"className": "table-pname",
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/page/run.php?id=' + row[1] + '" target="_blank">' + data + '</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": -1,
|
||||
"data": null,
|
||||
"visible": window.isAdmin,
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/page/edit.php?id=' + row[1] + '" target="_blank" class="pure-button" style="font-size: 70%;">编辑</a>';
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
$('#challenge-table').DataTable({
|
||||
language: language,
|
||||
data: r.result.challenge,
|
||||
columns: [
|
||||
{title: ""},
|
||||
{title: "ID"},
|
||||
{title: "No"},
|
||||
{title: "题名"},
|
||||
{title: "编程语言"},
|
||||
{title: "解答"},
|
||||
{title: "通过率"},
|
||||
{title: "难度"},
|
||||
{title: "管理"}
|
||||
],
|
||||
"order": [[2, "asc"]],
|
||||
columnDefs: [
|
||||
{
|
||||
"targets": 0,
|
||||
"orderable": false,
|
||||
"render": function (data, type, row) {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": 1,
|
||||
"data": null,
|
||||
"visible": false,
|
||||
"orderable": false
|
||||
},
|
||||
{
|
||||
"targets": 3,
|
||||
"className": "table-pname",
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/page/run.php?id=' + row[1] + '" target="_blank">' + data + '</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": -1,
|
||||
"data": null,
|
||||
"visible": window.isAdmin,
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/page/edit.php?id=' + row[1] + '" target="_blank" class="pure-button" style="font-size: 70%;">编辑</a>';
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
$('.tabs').tabslet({
|
||||
controls: {
|
||||
prev: '.prevTab',
|
||||
next: '.nextTab'
|
||||
}
|
||||
});
|
||||
$('#loading').hide();
|
||||
};
|
||||
|
||||
var checkAdmin = function (r) {
|
||||
if (window.isAdmin !== null) {
|
||||
tableInit(r);
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
checkAdmin(r)
|
||||
}, 50);
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api.php?action=getProblemsetList&user_id=" + window.localStorage.id,
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
checkAdmin(r)
|
||||
} else {
|
||||
alert('很抱歉,获取数据失败,请稍后刷新重试。');
|
||||
$('#loading').hide();
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!');
|
||||
$('#loading').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('#myRecordButton').click(function() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api.php?action=getMyRecordCount&user_id=" + window.localStorage.id,
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
if (r.result.all === r.result.pass) {
|
||||
alert('恭喜您!已完成全部 ' + r.result.all + ' 道闯关题!');
|
||||
} else {
|
||||
alert('闯关题共有 ' + r.result.all + ' 道,您已经完成 ' + r.result.pass + '道。');
|
||||
}
|
||||
} else {
|
||||
alert('很抱歉,获取数据失败,请稍后刷新重试。');
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
351
js/jquery.splitter.js
Normal file
351
js/jquery.splitter.js
Normal file
@ -0,0 +1,351 @@
|
||||
/*!
|
||||
* JQuery Spliter Plugin version 0.27.1
|
||||
* Copyright (C) 2010-2018 Jakub T. Jankiewicz <https://jcubic.pl/me>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
(function($, undefined) {
|
||||
var count = 0;
|
||||
var splitter_id = null;
|
||||
var splitters = [];
|
||||
var current_splitter = null;
|
||||
$.fn.split = function(options) {
|
||||
var data = this.data('splitter');
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
var panel_1;
|
||||
var panel_2;
|
||||
var settings = $.extend({
|
||||
limit: 100,
|
||||
orientation: 'horizontal',
|
||||
position: '50%',
|
||||
invisible: false,
|
||||
onDragStart: $.noop,
|
||||
onDragEnd: $.noop,
|
||||
onDrag: $.noop,
|
||||
percent: false
|
||||
}, options || {});
|
||||
this.settings = settings;
|
||||
var cls;
|
||||
var children = this.children();
|
||||
if (settings.orientation == 'vertical') {
|
||||
panel_1 = children.first().addClass('left_panel');
|
||||
panel_2 = panel_1.next().addClass('right_panel');
|
||||
cls = 'vsplitter';
|
||||
} else if (settings.orientation == 'horizontal') {
|
||||
panel_1 = children.first().addClass('top_panel');
|
||||
panel_2 = panel_1.next().addClass('bottom_panel');
|
||||
cls = 'hsplitter';
|
||||
}
|
||||
if (settings.invisible) {
|
||||
cls += ' splitter-invisible';
|
||||
}
|
||||
var width = this.width();
|
||||
var height = this.height();
|
||||
var id = count++;
|
||||
this.addClass('splitter_panel');
|
||||
var splitter = $('<div/>').addClass(cls).bind('mouseenter touchstart', function() {
|
||||
splitter_id = id;
|
||||
}).bind('mouseleave touchend', function() {
|
||||
splitter_id = null;
|
||||
}).insertAfter(panel_1);
|
||||
var position;
|
||||
|
||||
function get_position(position) {
|
||||
if (typeof position === 'number') {
|
||||
return position;
|
||||
} else if (typeof position === 'string') {
|
||||
var match = position.match(/^([0-9\.]+)(px|%)$/);
|
||||
if (match) {
|
||||
if (match[2] == 'px') {
|
||||
return +match[1];
|
||||
} else {
|
||||
if (settings.orientation == 'vertical') {
|
||||
return (width * +match[1]) / 100;
|
||||
} else if (settings.orientation == 'horizontal') {
|
||||
return (height * +match[1]) / 100;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//throw position + ' is invalid value';
|
||||
}
|
||||
} else {
|
||||
//throw 'position have invalid type';
|
||||
}
|
||||
}
|
||||
|
||||
function set_limit(limit) {
|
||||
if(!isNaN(parseFloat(limit)) && isFinite(limit)){
|
||||
return {
|
||||
leftUpper: limit,
|
||||
rightBottom: limit
|
||||
};
|
||||
}
|
||||
return limit;
|
||||
}
|
||||
|
||||
var self = $.extend(this, {
|
||||
refresh: function() {
|
||||
var new_width = this.width();
|
||||
var new_height = this.height();
|
||||
if (width != new_width || height != new_height) {
|
||||
width = this.width();
|
||||
height = this.height();
|
||||
self.position(position);
|
||||
}
|
||||
},
|
||||
option: function(name, value) {
|
||||
if (name === 'position') {
|
||||
return self.position(value);
|
||||
} else if (typeof value === 'undefined') {
|
||||
return settings[name];
|
||||
} else {
|
||||
settings[name] = value;
|
||||
}
|
||||
return self;
|
||||
},
|
||||
position: (function() {
|
||||
if (settings.orientation == 'vertical') {
|
||||
return function(n, silent) {
|
||||
if (n === undefined) {
|
||||
return position;
|
||||
} else {
|
||||
position = get_position(n);
|
||||
var sw = splitter.width();
|
||||
var sw2 = sw/2, pw;
|
||||
var width = self.width();
|
||||
if (settings.invisible) {
|
||||
pw = panel_1.width(position).outerWidth();
|
||||
panel_2.width(width - pw - 27); // 特殊处理
|
||||
splitter.css('left', pw - sw2);
|
||||
} else {
|
||||
if (settings.percent) {
|
||||
var w1 = (position - sw2) / width * 100;
|
||||
pw = panel_1.css('width', w1 + '%').outerWidth();
|
||||
panel_2.css('width', (width-pw-sw) / width * 100 + '%');
|
||||
splitter.css('left', (pw / width * 100) + '%');
|
||||
} else {
|
||||
pw = panel_1.css('width', position - sw2).outerWidth();
|
||||
panel_2.width(width - pw - sw - 20); // 特殊处理
|
||||
splitter.css('left', pw);
|
||||
}
|
||||
}
|
||||
panel_1.find('.splitter_panel').eq(0).height(self.height());
|
||||
panel_2.find('.splitter_panel').eq(0).height(self.height());
|
||||
}
|
||||
if (!silent) {
|
||||
self.trigger('splitter.resize');
|
||||
self.find('.splitter_panel').trigger('splitter.resize');
|
||||
}
|
||||
return self;
|
||||
};
|
||||
} else if (settings.orientation == 'horizontal') {
|
||||
return function(n, silent) {
|
||||
if (n === undefined) {
|
||||
return position;
|
||||
} else {
|
||||
position = get_position(n);
|
||||
var sw = splitter.height();
|
||||
var sw2 = sw / 2, pw;
|
||||
var height = self.height();
|
||||
if (settings.invisible) {
|
||||
pw = panel_1.height(position).outerHeight();
|
||||
panel_2.height(height - pw);
|
||||
splitter.css('top', pw - sw2);
|
||||
} else if (settings.percent) {
|
||||
var h1 = (position - sw2) / height * 100;
|
||||
pw = panel_1.css('height', h1 + '%').outerHeight();
|
||||
panel_2.css('height', ((height - pw - sw) / height * 100) + '%');
|
||||
splitter.css('top', (pw / height * 100) + '%');
|
||||
} else {
|
||||
pw = panel_1.height(position - sw2).outerHeight();
|
||||
panel_2.height(height - pw - sw);
|
||||
splitter.css('top', pw);
|
||||
}
|
||||
}
|
||||
if (!silent) {
|
||||
self.trigger('splitter.resize');
|
||||
self.find('.splitter_panel').trigger('splitter.resize');
|
||||
}
|
||||
return self;
|
||||
};
|
||||
} else {
|
||||
return $.noop;
|
||||
}
|
||||
})(),
|
||||
orientation: settings.orientation,
|
||||
limit: set_limit(settings.limit),
|
||||
isActive: function() {
|
||||
return splitter_id === id;
|
||||
},
|
||||
destroy: function() {
|
||||
self.removeClass('splitter_panel');
|
||||
splitter.unbind('mouseenter');
|
||||
splitter.unbind('mouseleave');
|
||||
splitter.unbind('touchstart');
|
||||
splitter.unbind('touchmove');
|
||||
splitter.unbind('touchend');
|
||||
splitter.unbind('touchleave');
|
||||
splitter.unbind('touchcancel');
|
||||
if (settings.orientation == 'vertical') {
|
||||
panel_1.removeClass('left_panel');
|
||||
panel_2.removeClass('right_panel');
|
||||
} else if (settings.orientation == 'horizontal') {
|
||||
panel_1.removeClass('top_panel');
|
||||
panel_2.removeClass('bottom_panel');
|
||||
}
|
||||
self.unbind('splitter.resize');
|
||||
self.trigger('splitter.resize');
|
||||
self.find('.splitter_panel').trigger('splitter.resize');
|
||||
splitters[id] = null;
|
||||
count--;
|
||||
splitter.remove();
|
||||
self.removeData('splitter');
|
||||
var not_null = false;
|
||||
for (var i=splitters.length; i--;) {
|
||||
if (splitters[i] !== null) {
|
||||
not_null = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//remove document events when no splitters
|
||||
if (!not_null) {
|
||||
$(document.documentElement).unbind('.splitter');
|
||||
$(window).unbind('resize.splitter');
|
||||
splitters = [];
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
self.bind('splitter.resize', function(e) {
|
||||
var pos = self.position();
|
||||
if (self.orientation == 'vertical' &&
|
||||
pos > self.width()) {
|
||||
pos = self.width() - self.limit.rightBottom-1;
|
||||
} else if (self.orientation == 'horizontal' &&
|
||||
pos > self.height()) {
|
||||
pos = self.height() - self.limit.rightBottom-1;
|
||||
}
|
||||
if (pos < self.limit.leftUpper) {
|
||||
pos = self.limit.leftUpper + 1;
|
||||
}
|
||||
e.stopPropagation();
|
||||
self.position(pos, true);
|
||||
});
|
||||
//inital position of splitter
|
||||
var pos;
|
||||
if (settings.orientation == 'vertical') {
|
||||
if (pos > width-settings.limit.rightBottom) {
|
||||
pos = width-settings.limit.rightBottom;
|
||||
} else {
|
||||
pos = get_position(settings.position);
|
||||
}
|
||||
} else if (settings.orientation == 'horizontal') {
|
||||
//position = height/2;
|
||||
if (pos > height-settings.limit.rightBottom) {
|
||||
pos = height-settings.limit.rightBottom;
|
||||
} else {
|
||||
pos = get_position(settings.position);
|
||||
}
|
||||
}
|
||||
if (pos < settings.limit.leftUpper) {
|
||||
pos = settings.limit.leftUpper;
|
||||
}
|
||||
self.position(pos, true);
|
||||
var parent = this.closest('.splitter_panel');
|
||||
if (parent.length) {
|
||||
this.height(parent.height());
|
||||
}
|
||||
// bind events to document if no splitters
|
||||
if (splitters.filter(Boolean).length === 0) {
|
||||
$(window).bind('resize.splitter', function() {
|
||||
$.each(splitters, function(i, splitter) {
|
||||
if (splitter) {
|
||||
splitter.refresh();
|
||||
}
|
||||
});
|
||||
});
|
||||
$(document.documentElement).on('mousedown.splitter touchstart.splitter', function(e) {
|
||||
if (splitter_id !== null) {
|
||||
e.preventDefault();
|
||||
current_splitter = splitters[splitter_id];
|
||||
setTimeout(function() {
|
||||
$('<div class="splitterMask"></div>').
|
||||
css('cursor', current_splitter.children().eq(1).css('cursor')).
|
||||
insertAfter(current_splitter);
|
||||
});
|
||||
current_splitter.settings.onDragStart(e);
|
||||
}
|
||||
}).bind('mouseup.splitter touchend.splitter touchleave.splitter touchcancel.splitter', function(e) {
|
||||
if (current_splitter) {
|
||||
setTimeout(function() {
|
||||
$('.splitterMask').remove();
|
||||
});
|
||||
current_splitter.settings.onDragEnd(e);
|
||||
current_splitter = null;
|
||||
}
|
||||
}).bind('mousemove.splitter touchmove.splitter', function(e) {
|
||||
if (current_splitter !== null) {
|
||||
var leftUpperLimit = current_splitter.limit.leftUpper;
|
||||
var rightBottomLimit = current_splitter.limit.rightBottom;
|
||||
var offset = current_splitter.offset();
|
||||
if (current_splitter.orientation == 'vertical') {
|
||||
var pageX = e.pageX;
|
||||
if(e.originalEvent && e.originalEvent.changedTouches){
|
||||
pageX = e.originalEvent.changedTouches[0].pageX;
|
||||
}
|
||||
var x = pageX - offset.left;
|
||||
if (x <= current_splitter.limit.leftUpper) {
|
||||
x = current_splitter.limit.leftUpper + 1;
|
||||
} else if (x >= current_splitter.width() - rightBottomLimit) {
|
||||
x = current_splitter.width() - rightBottomLimit - 1;
|
||||
}
|
||||
if (x > current_splitter.limit.leftUpper &&
|
||||
x < current_splitter.width()-rightBottomLimit) {
|
||||
current_splitter.position(x, true);
|
||||
current_splitter.trigger('splitter.resize');
|
||||
current_splitter.find('.splitter_panel').
|
||||
trigger('splitter.resize');
|
||||
//e.preventDefault();
|
||||
}
|
||||
} else if (current_splitter.orientation == 'horizontal') {
|
||||
var pageY = e.pageY;
|
||||
if(e.originalEvent && e.originalEvent.changedTouches){
|
||||
pageY = e.originalEvent.changedTouches[0].pageY;
|
||||
}
|
||||
var y = pageY-offset.top;
|
||||
if (y <= current_splitter.limit.leftUpper) {
|
||||
y = current_splitter.limit.leftUpper + 1;
|
||||
} else if (y >= current_splitter.height() - rightBottomLimit) {
|
||||
y = current_splitter.height() - rightBottomLimit - 1;
|
||||
}
|
||||
if (y > current_splitter.limit.leftUpper &&
|
||||
y < current_splitter.height()-rightBottomLimit) {
|
||||
current_splitter.position(y, true);
|
||||
current_splitter.trigger('splitter.resize');
|
||||
current_splitter.find('.splitter_panel').
|
||||
trigger('splitter.resize');
|
||||
//e.preventDefault();
|
||||
}
|
||||
}
|
||||
current_splitter.settings.onDrag(e);
|
||||
}
|
||||
});//*/
|
||||
}
|
||||
splitters[id] = self;
|
||||
self.data('splitter', self);
|
||||
return self;
|
||||
};
|
||||
})(jQuery);
|
4
js/monaco-editor-worker-loader-proxy.js
Normal file
4
js/monaco-editor-worker-loader-proxy.js
Normal file
@ -0,0 +1,4 @@
|
||||
self.MonacoEnvironment = {
|
||||
baseUrl: 'https://lib.baomitu.com/monaco-editor/0.15.6/min/'
|
||||
};
|
||||
importScripts('https://lib.baomitu.com/monaco-editor/0.15.6/min/vs/base/worker/workerMain.js');
|
329
js/page/edit.js
Normal file
329
js/page/edit.js
Normal file
@ -0,0 +1,329 @@
|
||||
$(function () {
|
||||
var jsCode = `'use strict';
|
||||
|
||||
var phpEngine = uniter.createEngine('PHP');
|
||||
|
||||
phpEngine.expose({
|
||||
pass: function () {
|
||||
pass();
|
||||
return '测试通过';
|
||||
},
|
||||
}, 'r');
|
||||
|
||||
phpEngine.getStdout().on('data', function (data) {
|
||||
print(data);
|
||||
});
|
||||
|
||||
phpEngine.getStderr().on('data', function (data) {
|
||||
print(data);
|
||||
});
|
||||
|
||||
phpEngine.execute(phpCode).fail(function (error) {
|
||||
// print(error.toString());
|
||||
});
|
||||
`;
|
||||
|
||||
var testCode = `<?php
|
||||
$pass = 1;
|
||||
|
||||
$m =
|
||||
if ($m != ) {
|
||||
$pass = 0;
|
||||
echo "测试用例:<br>";
|
||||
echo "输出结果:" . $m . "<br>";
|
||||
}
|
||||
|
||||
if ($pass) {
|
||||
echo $r->pass();
|
||||
} else {
|
||||
echo "<br>测试不通过";
|
||||
}`;
|
||||
|
||||
require(["vs/editor/editor.main"], function () {
|
||||
window.editor = monaco.editor.create(document.getElementById('phpContainer'), {
|
||||
value: [
|
||||
'<?php',
|
||||
'\tfunction sum($a, $b) {',
|
||||
'\t\treturn $a + $b;',
|
||||
'\t}',
|
||||
'',
|
||||
'// --------- 测试区域',
|
||||
''
|
||||
].join('\n'),
|
||||
language: 'php'
|
||||
});
|
||||
|
||||
window.jsEditor = monaco.editor.create(document.getElementById('jsContainer'), {
|
||||
value: jsCode,
|
||||
language: 'javascript'
|
||||
});
|
||||
|
||||
window.testEditor = monaco.editor.create(document.getElementById('testContainer'), {
|
||||
value: testCode,
|
||||
language: 'php'
|
||||
});
|
||||
|
||||
function execMain() {
|
||||
var javascriptCode = window.jsEditor.getValue(),
|
||||
phpCode = window.editor.getValue(),
|
||||
resultIframe = document.getElementById('result'),
|
||||
resultDocument = resultIframe.contentWindow.document,
|
||||
resultBody;
|
||||
|
||||
function clear() {
|
||||
resultBody.innerHTML = '';
|
||||
}
|
||||
|
||||
function print(html) {
|
||||
resultBody.insertAdjacentHTML('beforeEnd', html);
|
||||
}
|
||||
|
||||
function pass() {
|
||||
console.log('pass')
|
||||
}
|
||||
|
||||
function printText(text) {
|
||||
resultBody.appendChild(document.createTextNode(text));
|
||||
}
|
||||
|
||||
// Ensure the document has a body for IE9
|
||||
resultDocument.write('<body></body>');
|
||||
resultDocument.close();
|
||||
resultBody = resultDocument.body;
|
||||
|
||||
clear();
|
||||
|
||||
try {
|
||||
/*jshint evil: true */
|
||||
new Function('phpCode, print, resultBody, pass', javascriptCode)(phpCode, print, resultBody, pass);
|
||||
} catch (error) {
|
||||
printText('<JavaScript error> ' + error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function runUnit() {
|
||||
var javascriptCode = window.jsEditor.getValue(),
|
||||
phpCode = window.editor.getValue(),
|
||||
testCode = window.testEditor.getValue(),
|
||||
resultIframe = document.getElementById('result'),
|
||||
resultDocument = resultIframe.contentWindow.document,
|
||||
resultBody;
|
||||
|
||||
if (phpCode.indexOf('// --------- 测试区域') !== -1) {
|
||||
phpCode = phpCode.substring(0, phpCode.lastIndexOf('// --------- 测试区域')) + testCode.replace('<?php', '');
|
||||
} else {
|
||||
phpCode = phpCode + testCode.replace('<?php', '');
|
||||
}
|
||||
|
||||
|
||||
function clear() {
|
||||
resultBody.innerHTML = '';
|
||||
}
|
||||
|
||||
function print(html) {
|
||||
resultBody.insertAdjacentHTML('beforeEnd', html);
|
||||
}
|
||||
|
||||
function pass() {
|
||||
console.log('测试通过')
|
||||
}
|
||||
|
||||
function printText(text) {
|
||||
resultBody.appendChild(document.createTextNode(text));
|
||||
}
|
||||
|
||||
// Ensure the document has a body for IE9
|
||||
resultDocument.write('<body></body>');
|
||||
resultDocument.close();
|
||||
resultBody = resultDocument.body;
|
||||
|
||||
clear();
|
||||
|
||||
try {
|
||||
/*jshint evil: true */
|
||||
new Function('phpCode, print, resultBody, pass', javascriptCode)(phpCode, print, resultBody, pass);
|
||||
} catch (error) {
|
||||
printText('<JavaScript error> ' + error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
$('#runMain').click(function () {
|
||||
execMain()
|
||||
});
|
||||
|
||||
$('#runUnit').click(function () {
|
||||
runUnit()
|
||||
});
|
||||
|
||||
var contentHeight = window.document.body.clientHeight - 50;
|
||||
|
||||
$('#phpContainer').css('height', contentHeight - 70);
|
||||
$('#jsContainer').css('height', contentHeight - 70);
|
||||
$('#testContainer').css('height', contentHeight - 70);
|
||||
|
||||
$('#article').css('height', contentHeight + 30);
|
||||
|
||||
window.editor.layout();
|
||||
window.jsEditor.layout();
|
||||
window.testEditor.layout();
|
||||
|
||||
|
||||
window.onresize = function () {
|
||||
window.editor.layout();
|
||||
window.jsEditor.layout();
|
||||
window.testEditor.layout();
|
||||
};
|
||||
|
||||
var describe = new SimpleMDE({ element: $("#describe")[0] });
|
||||
var answer = new SimpleMDE({ element: $("#answer")[0] });
|
||||
var testCase = new SimpleMDE({ element: $("#testCase")[0] });
|
||||
var expectedResult = new SimpleMDE({ element: $("#expectedResult")[0] });
|
||||
|
||||
$('#submitForm').click(function () {
|
||||
|
||||
// 李永升:你应该适配一下,大于1时直接加百分号,小于1时乘以100再加百分号
|
||||
var passPercent = $('#passPercent').val();
|
||||
if (passPercent > 1) {
|
||||
passPercent = passPercent / 100
|
||||
}
|
||||
$('#passPercent').val(passPercent);
|
||||
|
||||
var postData = $('#edit-form').serializeArray();
|
||||
|
||||
var javascriptCode = window.jsEditor.getValue(),
|
||||
phpUnitCode = window.testEditor.getValue(),
|
||||
phpCode = window.editor.getValue();
|
||||
|
||||
postData.push({
|
||||
name: 'javascriptCode',
|
||||
value: javascriptCode
|
||||
});
|
||||
|
||||
postData.push({
|
||||
name: 'phpUnitCode',
|
||||
value: phpUnitCode
|
||||
});
|
||||
|
||||
postData.push({
|
||||
name: 'phpCode',
|
||||
value: phpCode
|
||||
});
|
||||
|
||||
postData.push({
|
||||
name: 'describe',
|
||||
value: describe.value()
|
||||
});
|
||||
|
||||
postData.push({
|
||||
name: 'answer',
|
||||
value: answer.value()
|
||||
});
|
||||
|
||||
postData.push({
|
||||
name: 'testCase',
|
||||
value: testCase.value()
|
||||
});
|
||||
|
||||
postData.push({
|
||||
name: 'expectedResult',
|
||||
value: expectedResult.value()
|
||||
});
|
||||
|
||||
if (GetQueryString('id')) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=editProblemset&id=" + GetQueryString('id'),
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: postData,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
window.location.href = '/index.php'
|
||||
} else {
|
||||
alert('很抱歉,保存失败,请稍后刷新重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=addProblemset",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: postData,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
window.location.href = '/index.php'
|
||||
} else {
|
||||
alert('很抱歉,新增题目失败,请稍后刷新重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!')
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
if (GetQueryString('id')) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api.php?action=getProblemset&id=" + GetQueryString('id'),
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
$('#type').val(r.result.type);
|
||||
$('#name').val(r.result.name);
|
||||
$('#isAnswer').val(r.result.isAnswer);
|
||||
$('#language').val(r.result.language);
|
||||
$('#difficulty').val(r.result.difficulty);
|
||||
$('#isCredit').val(r.result.isCredit);
|
||||
$('#passPercent').val(r.result.passPercent);
|
||||
$('#tag').val(r.result.tag);
|
||||
$('#credit').val(r.result.credit);
|
||||
$('#mark').val(r.result.mark);
|
||||
|
||||
describe.value(r.result.describe);
|
||||
answer.value(r.result.answer);
|
||||
testCase.value(r.result.testCase);
|
||||
expectedResult.value(r.result.expectedResult);
|
||||
|
||||
window.editor.setValue(r.result.phpCode);
|
||||
window.testEditor.setValue(r.result.phpUnitCode);
|
||||
window.jsEditor.setValue(r.result.javascriptCode);
|
||||
|
||||
$('.tabs').tabslet({
|
||||
controls: {
|
||||
prev: '.prevTab',
|
||||
next: '.nextTab'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('很抱歉,获取数据失败,请稍后刷新重试。')
|
||||
}
|
||||
|
||||
$('#loading').hide();
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!');
|
||||
$('#loading').hide();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$('#loading').hide();
|
||||
$('.tabs').tabslet({
|
||||
controls: {
|
||||
prev: '.prevTab',
|
||||
next: '.nextTab'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
304
js/page/run.js
Normal file
304
js/page/run.js
Normal file
@ -0,0 +1,304 @@
|
||||
$(function () {
|
||||
var converter = new showdown.Converter();
|
||||
|
||||
var phpUnitCode = "";
|
||||
var javascriptCode = "";
|
||||
var theType = "";
|
||||
var no = "";
|
||||
var isLoading = false;
|
||||
|
||||
require(["vs/editor/editor.main"], function () {
|
||||
window.editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: [
|
||||
'<?php',
|
||||
'\techo "Hello world!";'
|
||||
].join('\n'),
|
||||
language: 'php'
|
||||
});
|
||||
|
||||
function run (phpCode, oldCode) {
|
||||
var resultIframe = document.getElementById('result');
|
||||
var resultDocument = resultIframe.contentWindow.document;
|
||||
var resultBody = null;
|
||||
|
||||
var clear = function () {
|
||||
resultBody.innerHTML = '';
|
||||
};
|
||||
|
||||
var print = function (html) {
|
||||
// outExeTime();
|
||||
resultBody.insertAdjacentHTML('beforeEnd', html);
|
||||
};
|
||||
|
||||
var pass = function () {
|
||||
console.log('测试通过');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=addRecord",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
user_id: window.localStorage.id,
|
||||
problemset_id: GetQueryString('id'),
|
||||
type: theType,
|
||||
code: oldCode,
|
||||
is_pass: '1'
|
||||
},
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
console.log('测试通过的结果保存成功');
|
||||
if (confirm("测试通过,进入下一题?")) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api.php?action=getNextNo&no=" + no + "&type=" + theType,
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
if (r.id > 0) {
|
||||
window.location.href = '/page/run.php?id=' + r.id;
|
||||
} else if (r.id == 0){
|
||||
alert('恭喜你!已经做完最后一题!');
|
||||
window.location.href = '/index.php';
|
||||
} else {
|
||||
window.location.href = '/index.php';
|
||||
}
|
||||
} else {
|
||||
alert('很抱歉,获取下一题数据失败,请重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请重试!');
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
alert('很抱歉,保存数据失败,请重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请重试!');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var printText = function (text) {
|
||||
resultBody.appendChild(document.createTextNode(text));
|
||||
};
|
||||
|
||||
// Ensure the document has a body for IE9
|
||||
resultDocument.write('<body></body>');
|
||||
resultDocument.close();
|
||||
resultBody = resultDocument.body;
|
||||
|
||||
clear();
|
||||
|
||||
try {
|
||||
/*jshint evil: true */
|
||||
new Function('phpCode, print, resultBody, pass', javascriptCode)(phpCode, print, resultBody, pass);
|
||||
} catch (error) {
|
||||
printText('<JavaScript error> ' + error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function exec(test) {
|
||||
// var start = (new Date()).getTime()
|
||||
|
||||
var phpCode = window.editor.getValue();
|
||||
var oldCode = phpCode;
|
||||
|
||||
if (!test) {
|
||||
if (isLoading) return;
|
||||
isLoading = true;
|
||||
if (phpCode.indexOf('// --------- 测试区域') !== -1) {
|
||||
phpCode = phpCode.substring(0, phpCode.lastIndexOf('// --------- 测试区域')) + phpUnitCode.replace('<?php', '');
|
||||
} else {
|
||||
phpCode = phpCode + phpUnitCode.replace('<?php', '');
|
||||
}
|
||||
|
||||
// 每次提交都记录数据, 需要成功返回后再执行,确保数据一致性
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=addRecord",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
user_id: window.localStorage.id,
|
||||
problemset_id: GetQueryString('id'),
|
||||
type: theType,
|
||||
code: oldCode,
|
||||
is_pass: '0'
|
||||
},
|
||||
success: function () {
|
||||
run(phpCode, oldCode);
|
||||
isLoading = false;
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请重试!');
|
||||
isLoading = false;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
run(phpCode, oldCode)
|
||||
}
|
||||
}
|
||||
|
||||
$('#testRun').click(function () {
|
||||
$('.tabs').trigger('show', '#resultView');
|
||||
exec(true);
|
||||
});
|
||||
|
||||
$('#run').click(function () {
|
||||
$('.tabs').trigger('show', '#resultView');
|
||||
exec(false);
|
||||
});
|
||||
|
||||
var contentHeight = window.document.body.clientHeight - 50;
|
||||
|
||||
$('#container').css('height', contentHeight - 70);
|
||||
|
||||
var splitter = $('#content').height(contentHeight).split({
|
||||
orientation: 'vertical',
|
||||
limit: 10,
|
||||
position: '40%', // if there is no percentage it interpret it as pixels
|
||||
onDrag: function (event) {
|
||||
console.log(splitter.position());
|
||||
window.editor.layout();
|
||||
}
|
||||
});
|
||||
|
||||
if (!localStorage.auto) {
|
||||
localStorage.auto = '1';
|
||||
}
|
||||
|
||||
window.auto = localStorage.auto;
|
||||
|
||||
window.editor.onDidChangeModelContent(function () {
|
||||
if (window.auto === '1') {
|
||||
exec(true)
|
||||
}
|
||||
});
|
||||
|
||||
window.editor.layout();
|
||||
|
||||
if (window.auto === '1') {
|
||||
$("#auto").prop("checked", 'true');
|
||||
exec(true);
|
||||
} else {
|
||||
$("#auto").prop("checked", 'false')
|
||||
}
|
||||
|
||||
$("#auto").click(function () {
|
||||
if ($(this).prop("checked")) {
|
||||
window.auto = '1';
|
||||
localStorage.auto = '1'
|
||||
} else {
|
||||
window.auto = '2';
|
||||
localStorage.auto = '2'
|
||||
}
|
||||
});
|
||||
|
||||
if (GetQueryString('id')) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api.php?action=getProblemset&id=" + GetQueryString('id'),
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
|
||||
var typeStr = '挑战赛';
|
||||
|
||||
if (r.result.type === '1') {
|
||||
typeStr = '闯关模式'
|
||||
}
|
||||
|
||||
var difficultyStr = '困难';
|
||||
|
||||
if (r.result.difficulty === '1') {
|
||||
difficultyStr = '简单'
|
||||
} else if (r.result.difficulty === '2') {
|
||||
difficultyStr = '中等'
|
||||
}
|
||||
|
||||
$(document).attr('title', r.result.name + ' - ' + typeStr);
|
||||
|
||||
$('#describeView .cont').html('<h3 style="font-weight: 600">' + r.result.name + '(' + difficultyStr + ')' + ' - ' + typeStr + '</h3>' + converter.makeHtml(r.result.describe));
|
||||
$('#answerView .cont').html(converter.makeHtml(r.result.answer));
|
||||
|
||||
if (r.result.isAnswer !== '1') {
|
||||
$('#answerViewButton').hide();
|
||||
}
|
||||
|
||||
window.editor.setValue(r.result.phpCode);
|
||||
|
||||
phpUnitCode = r.result.phpUnitCode;
|
||||
javascriptCode = r.result.javascriptCode;
|
||||
|
||||
var testCase = r.result.testCase;
|
||||
var expectedResult = r.result.expectedResult;
|
||||
|
||||
$('.testCaseContent').html(converter.makeHtml(testCase));
|
||||
$('.expectedResultContent').html(converter.makeHtml(expectedResult));
|
||||
|
||||
$('#rightPane pre code').each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
|
||||
theType = r.result.type;
|
||||
no = r.result.no;
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=getRecord",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
user_id: window.localStorage.id,
|
||||
problemset_id: GetQueryString('id'),
|
||||
},
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
window.editor.setValue(r.code);
|
||||
}
|
||||
|
||||
$('.tabs').tabslet({
|
||||
controls: {
|
||||
prev: '.prevTab',
|
||||
next: '.nextTab'
|
||||
}
|
||||
});
|
||||
$('#loading').hide();
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!');
|
||||
$('#loading').hide();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('很抱歉,获取数据失败,请稍后刷新重试。')
|
||||
}
|
||||
|
||||
$('#loading').hide();
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!');
|
||||
$('#loading').hide();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$('#loading').hide();
|
||||
$('.tabs').tabslet({
|
||||
controls: {
|
||||
prev: '.prevTab',
|
||||
next: '.nextTab'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
153
js/page/test.js
Normal file
153
js/page/test.js
Normal file
@ -0,0 +1,153 @@
|
||||
$(function () {
|
||||
|
||||
var saveTestCode = function (code) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=saveTestCode",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
user_id: window.localStorage.id,
|
||||
code: code
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
require(["vs/editor/editor.main"], function () {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=getTestCode",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
data: {
|
||||
user_id: window.localStorage.id,
|
||||
},
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
window.editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: r.code,
|
||||
language: 'php'
|
||||
});
|
||||
|
||||
function exec() {
|
||||
// var start = (new Date()).getTime()
|
||||
|
||||
var javascriptCode = `'use strict';
|
||||
|
||||
var phpEngine = uniter.createEngine('PHP');
|
||||
|
||||
phpEngine.getStdout().on('data', function (data) {
|
||||
print(data);
|
||||
});
|
||||
|
||||
phpEngine.getStderr().on('data', function (data) {
|
||||
print(data);
|
||||
});
|
||||
|
||||
phpEngine.execute(phpCode).fail(function (error) {
|
||||
// print(error.toString());
|
||||
});
|
||||
`,
|
||||
phpCode = window.editor.getValue(),
|
||||
resultIframe = document.getElementById('result'),
|
||||
resultDocument = resultIframe.contentWindow.document,
|
||||
resultBody;
|
||||
|
||||
saveTestCode(phpCode);
|
||||
|
||||
function clear() {
|
||||
resultBody.innerHTML = '';
|
||||
}
|
||||
|
||||
function print(html) {
|
||||
// outExeTime();
|
||||
resultBody.insertAdjacentHTML('beforeEnd', html);
|
||||
}
|
||||
|
||||
function printText(text) {
|
||||
resultBody.appendChild(document.createTextNode(text));
|
||||
}
|
||||
|
||||
// function outExeTime () {
|
||||
// // var execTimeString = getNowDate() + '执行结果(' + ((new Date()).getTime() - start) + 'ms)';
|
||||
// // var headerHtml = '<span style="color: #888;font-weight: 300;font-size: 10px;">' + execTimeString + ':</span><br>'
|
||||
// // $('#out').html(headerHtml)
|
||||
// }
|
||||
|
||||
// Ensure the document has a body for IE9
|
||||
resultDocument.write('<body></body>');
|
||||
resultDocument.close();
|
||||
resultBody = resultDocument.body;
|
||||
|
||||
clear();
|
||||
|
||||
try {
|
||||
/*jshint evil: true */
|
||||
new Function('phpCode, print, resultBody', javascriptCode)(phpCode, print, resultBody);
|
||||
} catch (error) {
|
||||
printText('<JavaScript error> ' + error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
$('#run').click(function () {
|
||||
exec()
|
||||
});
|
||||
|
||||
var contentHeight = window.document.body.clientHeight - 50;
|
||||
|
||||
$('#container').css('height', contentHeight - 70);
|
||||
|
||||
var splitter = $('#content').height(contentHeight).split({
|
||||
orientation: 'vertical',
|
||||
limit: 10,
|
||||
position: '40%', // if there is no percentage it interpret it as pixels
|
||||
onDrag: function (event) {
|
||||
console.log(splitter.position());
|
||||
window.editor.layout();
|
||||
}
|
||||
});
|
||||
|
||||
if (!localStorage.auto) {
|
||||
localStorage.auto = '1';
|
||||
}
|
||||
|
||||
window.auto = localStorage.auto;
|
||||
|
||||
window.editor.onDidChangeModelContent(function () {
|
||||
if (window.auto === '1') {
|
||||
exec()
|
||||
}
|
||||
});
|
||||
|
||||
window.editor.layout();
|
||||
|
||||
if (window.auto === '1') {
|
||||
$("#auto").prop("checked", 'true')
|
||||
exec()
|
||||
} else {
|
||||
$("#auto").prop("checked", 'false')
|
||||
}
|
||||
|
||||
$("#auto").click(function () {
|
||||
if ($(this).prop("checked")) {
|
||||
window.auto = '1';
|
||||
localStorage.auto = '1'
|
||||
} else {
|
||||
window.auto = '2';
|
||||
localStorage.auto = '2'
|
||||
}
|
||||
});
|
||||
|
||||
$('#loading').hide();
|
||||
} else {
|
||||
alert('很抱歉,获取已保存的代码失败,请稍后刷新重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!')
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
3
js/page/user.js
Normal file
3
js/page/user.js
Normal file
@ -0,0 +1,3 @@
|
||||
$(function () {
|
||||
$('#loading').hide();
|
||||
});
|
3
js/page/userinfo.js
Normal file
3
js/page/userinfo.js
Normal file
@ -0,0 +1,3 @@
|
||||
$(function () {
|
||||
$('#loading').hide();
|
||||
});
|
15
js/uniter.js
Normal file
15
js/uniter.js
Normal file
File diff suppressed because one or more lines are too long
BIN
loading.gif
Normal file
BIN
loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
230
login.html
Normal file
230
login.html
Normal file
@ -0,0 +1,230 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>微信扫码登陆</title>
|
||||
<style>
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
background: #092756;
|
||||
background: -moz-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, .4) 10%, rgba(138, 114, 76, 0) 40%), -moz-linear-gradient(top, rgba(57, 173, 219, .25) 0%, rgba(42, 60, 87, .4) 100%), -moz-linear-gradient(-45deg, #670d10 0%, #092756 100%);
|
||||
background: -webkit-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, .4) 10%, rgba(138, 114, 76, 0) 40%), -webkit-linear-gradient(top, rgba(57, 173, 219, .25) 0%, rgba(42, 60, 87, .4) 100%), -webkit-linear-gradient(-45deg, #670d10 0%, #092756 100%);
|
||||
background: -o-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, .4) 10%, rgba(138, 114, 76, 0) 40%), -o-linear-gradient(top, rgba(57, 173, 219, .25) 0%, rgba(42, 60, 87, .4) 100%), -o-linear-gradient(-45deg, #670d10 0%, #092756 100%);
|
||||
background: -ms-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, .4) 10%, rgba(138, 114, 76, 0) 40%), -ms-linear-gradient(top, rgba(57, 173, 219, .25) 0%, rgba(42, 60, 87, .4) 100%), -ms-linear-gradient(-45deg, #670d10 0%, #092756 100%);
|
||||
background: -webkit-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, .4) 10%, rgba(138, 114, 76, 0) 40%), linear-gradient(to bottom, rgba(57, 173, 219, .25) 0%, rgba(42, 60, 87, .4) 100%), linear-gradient(135deg, #670d10 0%, #092756 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3E1D6D', endColorstr='#092756', GradientType=1);
|
||||
}
|
||||
|
||||
.login {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -150px 0 0 -150px;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#qrcode {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
display: none;
|
||||
box-shadow: 0 0 22px rgba(81, 81, 81, 0.8);
|
||||
}
|
||||
|
||||
.loading {
|
||||
width: 150px;
|
||||
height: 15px;
|
||||
margin: 0 auto;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.loading span {
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
height: 100%;
|
||||
margin-right: 5px;
|
||||
background: lightgreen;
|
||||
-webkit-transform-origin: right bottom;
|
||||
-webkit-animation: load 1s ease infinite;
|
||||
}
|
||||
|
||||
.loading span:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
@-webkit-keyframes load {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading span:nth-child(1) {
|
||||
-webkit-animation-delay: 0.13s;
|
||||
}
|
||||
|
||||
.loading span:nth-child(2) {
|
||||
-webkit-animation-delay: 0.26s;
|
||||
}
|
||||
|
||||
.loading span:nth-child(3) {
|
||||
-webkit-animation-delay: 0.39s;
|
||||
}
|
||||
|
||||
.loading span:nth-child(4) {
|
||||
-webkit-animation-delay: 0.52s;
|
||||
}
|
||||
|
||||
.loading span:nth-child(5) {
|
||||
-webkit-animation-delay: 0.65s;
|
||||
}
|
||||
|
||||
#code {
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="login">
|
||||
<div class="loading">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 id="code"></h1>
|
||||
<script crossorigin="anonymous" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT"
|
||||
src="https://lib.baomitu.com/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var login = function (code) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api.php?action=login&code=" + code,
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (r) {
|
||||
if (r.status === 1) {
|
||||
window.localStorage.id = r.result.id
|
||||
window.localStorage.userinfo = JSON.stringify(r.result.userinfo)
|
||||
$('#code').text('登陆成功')
|
||||
window.location.href = "/index.php"
|
||||
} else {
|
||||
alert('很抱歉,登陆失败,请稍后刷新重试。')
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('很抱歉,出错了,请稍后刷新重试!')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var getCode = function (uuid, last) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "https://apio.xyz/weixin-login-php/weixin.php?uuid=" + uuid + (last ? '&last=' + last : ''),
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (data) {
|
||||
if (data.status === 405) {
|
||||
$('#code').text('扫码成功,正在登陆...')
|
||||
login(data.result.code)
|
||||
} else if (data.status === 404) {
|
||||
$('#code').text(data.msg.title + ', ' + data.msg.content)
|
||||
getCode(uuid, data.result.wxErrCode)
|
||||
} else if (data.status === 403) {
|
||||
$('#code').text(data.msg.title + ', ' + data.msg.content)
|
||||
getCode(uuid, data.result.wxErrCode)
|
||||
} else if (data.status === 500) {
|
||||
getUUID()
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
getCode(uuid)
|
||||
}, 2000)
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
setTimeout(function () {
|
||||
getCode(uuid)
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadImage(url, callback) {
|
||||
var img = new Image(); //创建一个Image对象,实现图片的预下载
|
||||
img.src = url;
|
||||
img.onload = function () { //图片下载完毕时异步调用callback函数
|
||||
callback.call(img); //将回调函数的this替换为Image对象
|
||||
};
|
||||
};
|
||||
|
||||
var getUUID = function (uuid) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "https://apio.xyz/weixin-login-php/weixin.php?appid=wx2d1d6aa2f86768d7&redirect_uri=https://wyr.me/login",
|
||||
dataType: "json",
|
||||
cache: !1,
|
||||
timeout: 6e4,
|
||||
success: function (data) {
|
||||
if (data.status === 1) {
|
||||
var uuid = data.result.wxUUID
|
||||
loadImage(data.result.imgData, function () {
|
||||
$('.loading').hide()
|
||||
this.id = 'qrcode'
|
||||
$('.login').append(this)
|
||||
$('#qrcode').show()
|
||||
})
|
||||
getCode(uuid)
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 2000)
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getUUID()
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
7
menu.php
Normal file
7
menu.php
Normal file
@ -0,0 +1,7 @@
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-item <?php if ($nowURL == '/' || $nowURL == '/index.php') echo 'pure-menu-selected'; ?>"><a href="/" class="pure-menu-link">题库</a></li>
|
||||
<li class="pure-menu-item <?php if ($nowURL == '/page/test.php') echo 'pure-menu-selected'; ?>"><a href="/page/test.php" class="pure-menu-link">在线测试</a></li>
|
||||
<li class="pure-menu-item"><a href="http://php.net/manual/zh/" class="pure-menu-link" target="_blank">PHP官方文档</a></li>
|
||||
<li class="pure-menu-item"><a href="http://www.w3school.com.cn/php/index.asp" class="pure-menu-link" target="_blank">w3school</a></li>
|
||||
<li class="pure-menu-item"><a href="http://www.runoob.com/php/php-tutorial.html" class="pure-menu-link" target="_blank">PHP教程</a></li>
|
||||
</ul>
|
214
page/edit.php
Normal file
214
page/edit.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php include('../header.php'); ?>
|
||||
<div class='edit-main'>
|
||||
<style type="text/css">
|
||||
.edit-main {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
article {
|
||||
margin: 0 auto;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
article > heading {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
|
||||
margin: 1.5em 0;
|
||||
padding-bottom: 1.5em;
|
||||
|
||||
display: block;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
article > heading h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.contain-floats::after {
|
||||
display: block;
|
||||
content: " ";
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.panes {
|
||||
margin-left: -30%;
|
||||
margin-right: -30%;
|
||||
}
|
||||
|
||||
.panes section {
|
||||
float: left;
|
||||
width: 33.33%;
|
||||
height: 30em;
|
||||
}
|
||||
|
||||
.result {
|
||||
display: block;
|
||||
margin-right: 1em;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.result {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#jsContainer, #phpContainer, #testContainer {
|
||||
margin: 5px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
#phpContainer {
|
||||
margin: 5px 4px 5px 4px;
|
||||
}
|
||||
|
||||
.edit-form label {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.button-control {
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
<form class="pure-form pure-form-stacked edit-form" id="edit-form">
|
||||
<fieldset>
|
||||
<legend><h1><?php if (isset($_GET['id'])) {
|
||||
echo '编辑';
|
||||
} else {
|
||||
echo '添加';
|
||||
} ?>题目</h1></legend>
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-6">
|
||||
<label for="type">分类</label>
|
||||
<select id="type" name="type">
|
||||
<option value="1">闯关模式</option>
|
||||
<option value="2">挑战赛</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-lg-1-6">
|
||||
<label for="isAnswer" class="pure-checkbox">
|
||||
是否有解答
|
||||
</label>
|
||||
<select id="isAnswer" name="isAnswer">
|
||||
<option value="1">是</option>
|
||||
<option value="0">否</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-lg-1-6">
|
||||
<label for="difficulty">难度</label>
|
||||
<select id="difficulty" name="difficulty">
|
||||
<option value="1">简单</option>
|
||||
<option value="2">中等</option>
|
||||
<option value="3">困难</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-lg-1-6">
|
||||
<label for="isCredit">是否有积分</label>
|
||||
<select id="isCredit" name="isCredit">
|
||||
<option value="1">有</option>
|
||||
<option value="0">没有</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-lg-1-6">
|
||||
<label for="language">编程语言</label>
|
||||
<select id="language" name="language">
|
||||
<option value="PHP">PHP</option>
|
||||
<option value="HTML">HTML</option>
|
||||
<option value="JAVA">JAVA</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<label for="name">名称</label>
|
||||
<input id="name" name="name" class="pure-input-3-4" type="text">
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-4">
|
||||
<label for="passPercent">通过率</label>
|
||||
<input id="passPercent" name="passPercent" class="pure-input-1" type="text">
|
||||
</div>
|
||||
|
||||
<div class="pure-u-lg-1-4">
|
||||
<label for="tag">标签</label>
|
||||
<input id="tag" name="tag" class="pure-input-1" type="text">
|
||||
</div>
|
||||
|
||||
<div class="pure-u-lg-1-4">
|
||||
<label for="credit">积分</label>
|
||||
<input id="credit" name="credit" type="text" value="0" class="pure-input-1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="mark">备注</label>
|
||||
<textarea id="mark" name="mark" class="pure-input-1"></textarea>
|
||||
|
||||
<div class='tabs tabs_default'>
|
||||
<ul class='horizontal' style="margin-top: 10px;margin-bottom: 20px">
|
||||
<li><a class="pure-button" href="#describeEdit">题目描述</a></li>
|
||||
<li><a class="pure-button" href="#answerEdit">解答</a></li>
|
||||
<li><a class="pure-button admin" href="#testCaseEdit">测试用例</a></li>
|
||||
<li><a class="pure-button admin" href="#expectedResultEdit">预期结果</a></li>
|
||||
</ul>
|
||||
<div id='describeEdit'>
|
||||
<textarea id='describe' class="pure-input-1"></textarea>
|
||||
</div>
|
||||
<div id='answerEdit'>
|
||||
<textarea id='answer' class="pure-input-1"></textarea>
|
||||
</div>
|
||||
|
||||
<div id='testCaseEdit'>
|
||||
<textarea id="testCase" class="pure-input-1"></textarea>
|
||||
</div>
|
||||
|
||||
<div id="expectedResultEdit">
|
||||
<textarea id="expectedResult" class="pure-input-1"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article id="article">
|
||||
<div class="panes contain-floats">
|
||||
<section>
|
||||
<heading>
|
||||
<h1>JavaScript</h1>
|
||||
</heading>
|
||||
|
||||
<div id="jsContainer"></div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<heading>
|
||||
<h1>PHP 主程序</h1>
|
||||
</heading>
|
||||
|
||||
<div id="phpContainer"></div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<heading>
|
||||
<h1>PHP 测试用例</h1>
|
||||
</heading>
|
||||
|
||||
<div id="testContainer"></div>
|
||||
</section>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="button-control">
|
||||
<div class="pure-button" id="runMain">运行主程序</div>
|
||||
<div class="pure-button" id="runUnit">运行测试用例</div>
|
||||
</div>
|
||||
<div id="out">
|
||||
<iframe class="result" id="result"></iframe>
|
||||
</div>
|
||||
|
||||
<button type="button" id="submitForm" style="margin-top: 20px" class="pure-button pure-button-primary">保存</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<?php include('../footer.php'); ?>
|
48
page/run.php
Normal file
48
page/run.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php include('../header.php'); ?>
|
||||
<div class="content" id="content">
|
||||
<div id="leftPane">
|
||||
<div id="container"></div>
|
||||
<div class="control">
|
||||
<div class="pure-button pure-button-primary" id="run">提交</div>
|
||||
<div class="pure-button" id="testRun">执行代码</div>
|
||||
<label for="auto" class="pure-checkbox auto">
|
||||
<input id="auto" type="checkbox"> 自动执行代码
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rightPane">
|
||||
<div class='tabs tabs_default' style="height: 100%">
|
||||
<ul class='horizontal' style="margin-top: 10px;margin-bottom: 20px">
|
||||
<li><a class="pure-button" href="#describeView">题目描述</a></li>
|
||||
<li><a class="pure-button" href="#answerView" id="answerViewButton">解答</a></li>
|
||||
<li><a class="pure-button" href="#resultView">运行结果</a></li>
|
||||
</ul>
|
||||
<div id='describeView'>
|
||||
<div class="cont"></div>
|
||||
</div>
|
||||
<div id='answerView'>
|
||||
<div class="cont"></div>
|
||||
</div>
|
||||
|
||||
<div id='resultView'>
|
||||
<div class="cont">
|
||||
<div class="testCase">
|
||||
<h4 style="font-weight: 500;margin: 4px 0;">输入:</h4>
|
||||
<div class="testCaseContent"></div>
|
||||
</div>
|
||||
<div class="expectedResult" style="margin-top: 10px;">
|
||||
<h4 style="font-weight: 500;margin: 4px 0;">预期结果:</h4>
|
||||
<div class="expectedResultContent"></div>
|
||||
</div>
|
||||
<div class="resultArea" style="margin-top: 10px;">
|
||||
<h4 style="font-weight: 500;margin: 4px 0;">输出:</h4>
|
||||
<div class="resultContent">
|
||||
<iframe class="result" id="result"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include('../footer.php'); ?>
|
18
page/test.php
Normal file
18
page/test.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php include('../header.php'); ?>
|
||||
<div class="content" id="content">
|
||||
<div id="leftPane">
|
||||
<div id="container"></div>
|
||||
<div class="control">
|
||||
<div class="pure-button pure-button-primary" id="run">执行代码</div>
|
||||
<label for="auto" class="pure-checkbox auto">
|
||||
<input id="auto" type="checkbox"> 自动
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rightPane">
|
||||
<div id="out">
|
||||
<iframe class="result" id="result"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include('../footer.php'); ?>
|
61
page/user.php
Normal file
61
page/user.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php include('../header.php'); ?>
|
||||
<?php
|
||||
//error_reporting(0);
|
||||
require_once '../config.php';
|
||||
require_once '../medoo.php';
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
$database = new Medoo($DBCONFIG);
|
||||
|
||||
$Allcount = $database->count("problemset", [
|
||||
"type" => "1"
|
||||
]);
|
||||
|
||||
$rows = $database->select('userinfo', '*', [
|
||||
"ORDER" => [
|
||||
"id" => "DESC"
|
||||
]
|
||||
]);
|
||||
?>
|
||||
<div class="user" style="padding: 10px">
|
||||
<table class="pure-table" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>头像</th>
|
||||
<th>用户昵称</th>
|
||||
<th>真实姓名</th>
|
||||
<th>用户性别</th>
|
||||
<th>进度</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($rows as $inx => $row) { ?>
|
||||
<tr class="<?php if ($inx % 2) echo 'pure-table-odd'; ?>">
|
||||
<td><?php echo $row['id'] ?></td>
|
||||
<td><img src="<?php echo $row['headimgurl']; ?>" width="50"/></td>
|
||||
<td><?php echo $row['nickname']; ?></td>
|
||||
<td><?php echo $row['realname']; ?></td>
|
||||
<td><?php if ($row['sex'] == '1') {
|
||||
echo '男';
|
||||
} else {
|
||||
echo '女';
|
||||
} ?></td>
|
||||
<td><?php
|
||||
$passCount = $database->count("record", [
|
||||
'user_id' => $row['id'],
|
||||
'is_pass' => '1'
|
||||
]);
|
||||
|
||||
echo $passCount . '/' . $Allcount;
|
||||
?></td>
|
||||
<td><a href="/page/userinfo.php?id=<?php echo $row['id']; ?>" target="_blank">查看详情</a></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php include('../footer.php'); ?>
|
49
page/userinfo.php
Normal file
49
page/userinfo.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php include('../header.php'); ?>
|
||||
<?php
|
||||
//error_reporting(0);
|
||||
require_once '../config.php';
|
||||
require_once '../medoo.php';
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
$database = new Medoo($DBCONFIG);
|
||||
|
||||
$rows = $database->query("SELECT
|
||||
`record`.`is_pass`,
|
||||
`problemset`.`id`,
|
||||
`problemset`.`no`,
|
||||
`problemset`.`name`,
|
||||
`problemset`.`language`,
|
||||
`problemset`.`type`,
|
||||
`problemset`.`isAnswer`,
|
||||
`problemset`.`passPercent`,
|
||||
`problemset`.`difficulty`
|
||||
FROM
|
||||
`problemset`
|
||||
LEFT JOIN `record` ON `problemset`.`id` = `record`.`problemset_id` AND `record`.`user_id` = " . $_GET['id'] . " WHERE `problemset`.`type` = '1' ORDER BY
|
||||
`no`")->fetchAll();
|
||||
?>
|
||||
<div class="user" style="padding: 10px">
|
||||
<table class="pure-table" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>题目</th>
|
||||
<th>做题状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($rows as $inx => $row) { ?>
|
||||
<tr class="<?php if ($inx % 2) echo 'pure-table-odd'; ?>">
|
||||
<td><?php echo $row['no'] ?></td>
|
||||
<td><?php echo $row['name']; ?></td>
|
||||
<td><?php if ($row['is_pass'] == '1') {
|
||||
echo '<svg viewBox="0 0 1397 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="27" height="20"><path d="M1396.363636 121.018182c0 0-223.418182 74.472727-484.072727 372.363636-242.036364 269.963636-297.890909 381.672727-390.981818 530.618182C512 1014.690909 372.363636 744.727273 0 549.236364l195.490909-186.181818c0 0 176.872727 121.018182 297.890909 344.436364 0 0 307.2-474.763636 902.981818-707.490909L1396.363636 121.018182 1396.363636 121.018182zM1396.363636 121.018182" fill="#1afa29"></path></svg>';
|
||||
} ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php include('../footer.php'); ?>
|
0
run/.gitkeep
Normal file
0
run/.gitkeep
Normal file
Loading…
Reference in New Issue
Block a user