Browse Source

feat:给普通提交增加匿名提交功能。

pull/21/head
zjz1993 5 years ago
parent
commit
53b628e935
  1. 3
      libs/submissions_process.js
  2. 5
      models-built/judge_state.js
  3. 2
      models-built/judge_state.js.map
  4. 4
      models-built/user.js
  5. 2
      models-built/user.js.map
  6. 4
      models/judge_state.ts
  7. 3
      models/user.ts
  8. 9
      modules/api.js
  9. 10
      modules/index.js
  10. 8
      modules/problem.js
  11. 10
      modules/submission.js
  12. 13
      modules/user.js
  13. 18
      views/problem.ejs
  14. 6
      views/submissions_item.ejs
  15. 4
      views/user_edit.ejs

3
libs/submissions_process.js

@ -14,7 +14,8 @@ const getSubmissionInfo = (s, displayConfig) => {
submitTime: syzoj.utils.formatDate(s.submit_time), submitTime: syzoj.utils.formatDate(s.submit_time),
isPractice: s.is_practice, isPractice: s.is_practice,
c_id: s.c_id, c_id: s.c_id,
is_share: s.is_share || false is_share: s.is_share || false,
is_anonymous: s.is_anonymous
} }
}; };

5
models-built/judge_state.js

@ -372,6 +372,11 @@ var JudgeState = /** @class */ (function (_super) {
TypeORM.Column({ nullable: true, type: "boolean" }), TypeORM.Column({ nullable: true, type: "boolean" }),
__metadata("design:type", Boolean) __metadata("design:type", Boolean)
], JudgeState.prototype, "is_share"); ], JudgeState.prototype, "is_share");
__decorate([
TypeORM.Index(),
TypeORM.Column({ nullable: true, type: "boolean", "default": 0 }),
__metadata("design:type", Boolean)
], JudgeState.prototype, "is_anonymous");
JudgeState = __decorate([ JudgeState = __decorate([
TypeORM.Entity(), TypeORM.Entity(),
TypeORM.Index(['type', 'type_info']), TypeORM.Index(['type', 'type_info']),

2
models-built/judge_state.js.map

File diff suppressed because one or more lines are too long

4
models-built/user.js

@ -360,6 +360,10 @@ var User = /** @class */ (function (_super) {
TypeORM.Column({ nullable: true, type: "varchar", length: 80 }), TypeORM.Column({ nullable: true, type: "varchar", length: 80 }),
__metadata("design:type", String) __metadata("design:type", String)
], User.prototype, "username"); ], User.prototype, "username");
__decorate([
TypeORM.Column({ nullable: true, type: "varchar", length: 60, "default": '' }),
__metadata("design:type", String)
], User.prototype, "anonymous_name");
__decorate([ __decorate([
TypeORM.Column({ nullable: true, type: "varchar", length: 120 }), TypeORM.Column({ nullable: true, type: "varchar", length: 120 }),
__metadata("design:type", String) __metadata("design:type", String)

2
models-built/user.js.map

File diff suppressed because one or more lines are too long

4
models/judge_state.ts

@ -106,6 +106,10 @@ export default class JudgeState extends Model {
@TypeORM.Column({ nullable: true, type: "boolean" }) @TypeORM.Column({ nullable: true, type: "boolean" })
is_share:boolean; is_share:boolean;
@TypeORM.Index()
@TypeORM.Column({ nullable: true, type: "boolean", default: 0 })
is_anonymous:boolean;
user?: User; user?: User;
problem?: Problem; problem?: Problem;

3
models/user.ts

@ -18,6 +18,9 @@ export default class User extends Model {
@TypeORM.Column({ nullable: true, type: "varchar", length: 80 }) @TypeORM.Column({ nullable: true, type: "varchar", length: 80 })
username: string; username: string;
@TypeORM.Column({ nullable: true, type: "varchar", length: 60 , default: ''})
anonymous_name: string;
@TypeORM.Column({ nullable: true, type: "varchar", length: 120 }) @TypeORM.Column({ nullable: true, type: "varchar", length: 120 })
email: string; email: string;

9
modules/api.js

@ -20,6 +20,12 @@ app.post('/api/login', async (req, res) => {
else { else {
req.session.user_id = user.id; req.session.user_id = user.id;
setLoginCookie(user.username, user.password, res); setLoginCookie(user.username, user.password, res);
const userQuery = await User.createQueryBuilder();
const userId = user.id;
const userInfo = await userQuery.where("id = :id", { id:userId }).getOne();
if (!userInfo.anonymous_name || userInfo.anonymous_name.length === 0){
await userQuery.update(User).set({anonymous_name: require('randomstring').generate(6)}).where("id = :id", { id:userId }).execute();
}
res.send({ error_code: 1 }); res.send({ error_code: 1 });
} }
} catch (e) { } catch (e) {
@ -129,7 +135,8 @@ app.post('/api/sign_up', async (req, res) => {
email: req.body.email, email: req.body.email,
is_show: syzoj.config.default.user.show, is_show: syzoj.config.default.user.show,
rating: syzoj.config.default.user.rating, rating: syzoj.config.default.user.rating,
register_time: parseInt((new Date()).getTime() / 1000) register_time: parseInt((new Date()).getTime() / 1000),
anonymous_name: require('randomstring').generate(6)
}); });
await user.save(); await user.save();

10
modules/index.js

@ -40,7 +40,15 @@ app.get('/', async (req, res) => {
title: problem.title, title: problem.title,
time: timeAgo.format(new Date(problem.publicize_time)), time: timeAgo.format(new Date(problem.publicize_time)),
})); }));
// 增加匿名用户名后用户的第一次登陆
if (res.locals.user){
const userQuery = await User.createQueryBuilder();
const userId = res.locals.user.id;
const userInfo = await userQuery.where("id = :id", { id:userId }).getOne();
if (!userInfo.anonymous_name || userInfo.anonymous_name.length === 0){
await userQuery.update(User).set({anonymous_name: require('randomstring').generate(6)}).where("id = :id", { id:userId }).execute();
}
}
res.render('index', { res.render('index', {
ranklist: ranklist, ranklist: ranklist,
notices: notices, notices: notices,

8
modules/problem.js

@ -669,7 +669,7 @@ app.post('/problem/:id/submit', app.multer.fields([{ name: 'answer', maxCount: 1
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.findById(id); let problem = await Problem.findById(id);
const curUser = res.locals.user; const curUser = res.locals.user;
const is_anonymous = req.body.is_anonymous ? 1 : 0;
if (!problem) throw new ErrorMessage('无此题目。'); if (!problem) throw new ErrorMessage('无此题目。');
if (problem.type !== 'submit-answer' && !syzoj.config.enabled_languages.includes(req.body.language)) throw new ErrorMessage('不支持该语言。'); if (problem.type !== 'submit-answer' && !syzoj.config.enabled_languages.includes(req.body.language)) throw new ErrorMessage('不支持该语言。');
if (!curUser) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': syzoj.utils.makeUrl(['problem', id]) }) }); if (!curUser) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': syzoj.utils.makeUrl(['problem', id]) }) });
@ -704,7 +704,8 @@ app.post('/problem/:id/submit', app.multer.fields([{ name: 'answer', maxCount: 1
language: null, language: null,
user_id: curUser.id, user_id: curUser.id,
problem_id: id, problem_id: id,
is_public: problem.is_public is_public: problem.is_public,
is_anonymous
}); });
} else { } else {
let code; let code;
@ -725,7 +726,8 @@ app.post('/problem/:id/submit', app.multer.fields([{ name: 'answer', maxCount: 1
language: req.body.language, language: req.body.language,
user_id: curUser.id, user_id: curUser.id,
problem_id: id, problem_id: id,
is_public: problem.is_public is_public: problem.is_public,
is_anonymous
}); });
} }

10
modules/submission.js

@ -140,6 +140,9 @@ app.get('/submissions', async (req, res) => {
info.isPractice = true; info.isPractice = true;
info.c_id = practiceInfo.c_id; info.c_id = practiceInfo.c_id;
} }
let userQuery = await User.createQueryBuilder();
const userInfo = await userQuery.where("id = :id", { id:x.user_id }).getOne();
info.anonymous_name = userInfo.anonymous_name
return { return {
info, info,
token: (x.pending && x.task_id != null) ? jwt.sign({ token: (x.pending && x.task_id != null) ? jwt.sign({
@ -286,8 +289,13 @@ app.get('/submission/:id', async (req, res) => {
} else { } else {
judge.code = "作者没有开放此题代码,请联系作者分享。"; judge.code = "作者没有开放此题代码,请联系作者分享。";
} }
let info = getSubmissionInfo(judge, currentConfig);
let userQuery = await User.createQueryBuilder();
const userInfo = await userQuery.where("id = :id", { id:judge.user_id }).getOne();
console.log(userInfo);
info.anonymous_name = userInfo.anonymous_name
res.render('submission', { res.render('submission', {
info: getSubmissionInfo(judge, currentConfig), info,
roughResult: getRoughResult(judge, currentConfig, false), roughResult: getRoughResult(judge, currentConfig, false),
code: judge.code, code: judge.code,
formattedCode: judge.formattedCode ? judge.formattedCode.toString("utf8") : null, formattedCode: judge.formattedCode ? judge.formattedCode.toString("utf8") : null,

13
modules/user.js

@ -125,20 +125,22 @@ app.get('/user/:id', async (req, res) => {
app.get('/user/:id/edit', async (req, res) => { app.get('/user/:id/edit', async (req, res) => {
try { try {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let user = await User.findById(id); let userQuery = await User.createQueryBuilder();
if (!user) throw new ErrorMessage('无此用户。'); const userInfo = await userQuery.where("id = :id", { id }).getOne();
if (!userInfo) throw new ErrorMessage('无此用户。');
let allowedEdit = await user.isAllowedEditBy(res.locals.user); let allowedEdit = await userInfo.isAllowedEditBy(res.locals.user);
if (!allowedEdit) { if (!allowedEdit) {
throw new ErrorMessage('您没有权限进行此操作。'); throw new ErrorMessage('您没有权限进行此操作。');
} }
user.privileges = await user.getPrivileges(); userInfo.privileges = await userInfo.getPrivileges();
console.log(userInfo);
res.locals.user.allowedManage = await res.locals.user.hasPrivilege('manage_user'); res.locals.user.allowedManage = await res.locals.user.hasPrivilege('manage_user');
res.render('user_edit', { res.render('user_edit', {
edited_user: user, edited_user: userInfo,
error_info: null error_info: null
}); });
} catch (e) { } catch (e) {
@ -190,6 +192,7 @@ app.post('/user/:id/edit', async (req, res) => {
} }
user.information = req.body.information; user.information = req.body.information;
user.anonymous_name = req.body.anonymous_name || '';
user.sex = req.body.sex; user.sex = req.body.sex;
user.public_email = (req.body.public_email === 'on'); user.public_email = (req.body.public_email === 'on');
user.prefer_formatted_code = (req.body.prefer_formatted_code === 'on'); user.prefer_formatted_code = (req.body.prefer_formatted_code === 'on');

18
views/problem.ejs

@ -293,7 +293,15 @@ if (contest) {
</div> </div>
</div> </div>
</div> </div>
<div class="ui center aligned vertical segment" style="padding-bottom: 0; "><button type="submit" class="ui labeled icon button"><i class="ui edit icon"></i>提交</button></div> <div class="ui center aligned vertical segment" style="padding-bottom: 0; ">
<button type="submit" class="ui labeled icon button"><i class="ui edit icon"></i>提交</button>
<% if (!contest) {%>
<div class="ui toggle chekbox">
<input type="checkbox" name="is_anonymous">
<label>是否匿名提交</label>
</div>
<% } %>
</div>
<% } else { %> <% } else { %>
<input name="language" type="hidden" id="form"> <input name="language" type="hidden" id="form">
<input name="code" type="hidden"> <input name="code" type="hidden">
@ -329,7 +337,13 @@ if (contest) {
</div> </div>
</div> </div>
<div class="ui center aligned vertical segment" style="padding-bottom: 0; "> <div class="ui center aligned vertical segment" style="padding-bottom: 0; ">
<button type="submit" class="ui labeled icon button"><i class="ui edit icon"></i>提交</button> <button type="submit" class="ui labeled icon button"><i class="ui edit icon"></i>提交</button>
<% if (!contest) {%>
<div class="ui toggle chekbox">
<input type="checkbox" name="is_anonymous">
<label>是否匿名提交</label>
</div>
<% } %>
</div> </div>
<% } %> <% } %>
</form> </form>

6
views/submissions_item.ejs

@ -120,7 +120,11 @@
<% } %> <% } %>
{{ formatSize(data.info.codeSize, 1) }} {{ formatSize(data.info.codeSize, 1) }}
</td> </td>
<td><a :href="userLink">{{ data.info.user }}</a></td>
<td v-if="data.info.is_anonymous">{{ data.info.anonymous_name }}</td>
<td v-else>
<a :href="userLink">{{ data.info.user }}</a>
</td>
<td>{{ data.info.submitTime }}</td> <td>{{ data.info.submitTime }}</td>
<td v-if="showRejudge"> <td v-if="showRejudge">
<a id="rejudge-button" <a id="rejudge-button"

4
views/user_edit.ejs

@ -22,6 +22,10 @@
<% } %> <% } %>
> >
</div> </div>
<div class="field">
<label for="username">匿名名称</label>
<input type="text" id="anonymous_name" name="anonymous_name" value="<%= edited_user.anonymous_name %>">
</div>
<div class="field"> <div class="field">
<label for="sex">性别</label> <label for="sex">性别</label>
<select class="ui dropdown" name="sex"> <select class="ui dropdown" name="sex">

Loading…
Cancel
Save