Files
questionnaire_nodejs/servers/sql.js
2018-05-27 19:18:12 +08:00

330 lines
12 KiB
JavaScript

let mongoose = require('mongoose');
let csv = require('fast-csv');
let fs = require('fs');
let Schema = mongoose.Schema;
let admin = new Schema({
user_name: String,
password: String,
activity_list: [{ type: mongoose.Schema.ObjectId, ref: "activity" }]
})
let user = new Schema({
student_id: String,
name: String,
school: String,
user_class: String,
telephone: String,
user_ip: String,
test_list: [{ type: mongoose.Schema.ObjectId, ref: "test_paper" }],
});
let activity = new Schema({
name: String,
strat_time: Date,
end_time: Date,
question_num: Number,
question_list: [{ type: mongoose.Schema.ObjectId, ref: "question" }],
time_lim: Number,
contestant_paper_list: [{ type: mongoose.Schema.ObjectId, ref: "test_paper" }],
})
let question = new Schema({
type: Number,
problem: String,
answer: [{
content: String,
price: Number,
try_user_list: [{ type: mongoose.Schema.ObjectId, ref: "user" }],
}]
})
let test_paper = new Schema({
user_id: { type: mongoose.Schema.ObjectId, ref: "user" },
activity: { type: mongoose.Schema.ObjectId, ref: "activity" },
question_list: [{ type: mongoose.Schema.ObjectId, ref: "question" }],
answer: [String],
time_start: Date,
time_end: Date,
fraction: Number,
})
admin.static.is_login_in = function (user_name, password) {
return new Promise((rec, rej) => {
this.findOne({ user_name: user_name }).populate('activity_list').exec((err, rew) => {
if (err) console.log(err);
if (rew && password == rew.password) {
let out = [];
for (it of rew.activity_list) {
out.push({
activity_id: it._id,
name: it.name,
num: it.contestant_paper_list.length
})
}
rec(out);
} else {
rec(false);
}
})
})
}
admin.static.add_activity = function (user_id, activity_id) {
return new Promise((rec, rej) => {
this.findById(user_id).exec(async (err, rew) => {
if (err) console.log(err);
rew.activity_list.push(activity_id);
await rew.save();
let out = [];
for (it of rew.activity_list) {
out.push({
activity_id: it._id,
name: it.name,
num: it.contestant_paper_list.length
})
}
rec(out);
})
})
}
user.statics.init_user = function (user) {
return new Promise((rec, rej) => {
this.findOne({ telephone: user.telephone }, async (err, rew) => {
if (err) console.log(err);
if (rew) {
rew.name = post.name;
rew.student_id = post.student_id;
rew.school = post.school;
rew.user_class = post.user_class;
await rew.save();
rec(rew._id);
return;
}
let a_user = new this(user);
await a_user.save();
rec(a_user._id);
})
})
}
user.static.add_test = function (user_id, test_id) {
this.findById(user_id).exec(async (err, rew) => {
if (err) console.log(err);
rew.test_list.push(test_id);
await rew.save();
rec(rew);
})
}
activity.static.add_test = function (activity_id, test_id) {
this.findById(activity_id).exec(async (err, rew) => {
if (err) console.log(err);
rew.contestant_paper_list.push(test_id);
await rew.save();
rec(rew);
})
}
activity.static.get_tital = function (activity_id) {
return new Promise((rec, rej) => {
this.findById(activity_id, (err, rew) => {
if (err) console.log(err);
if (rew) {
rec(rew.name);
} else {
rec('NULL');
}
})
})
}
activity.static.get_paper = function (activity_id, no_time_lim = false) {
return new Promise((rec, rej) => {
this.findById(activity_id).populate('question_list').exec((err, rew) => {
if (err) console.log(err);
let now = new Date();
if ((now < rew.end_time && now > rew.strat_time) || no_time_lim) {
let question_list = rew.question_list;
while (question_list.length > rew.question_num) {
question_list.splice(Math.floor(Math.random() * (question_list.length)), 1);
}
for (it of question_list) {
for (at in it.answer) {
it.answer[a].num = at + it.answer.length * Math.floor(Math.random() * 5000);
delete it.answer[a].price;
delete it.answer[a].try_user_list;
}
it.question_id = it._id;
}
rec({
time_lim: rew.time_lim,
paper_id: rew._id,
question_list: question_list
});
} else {
rec('time_err');
}
})
})
}
activity.static.is_time_out = function (activity_id, strat_time, end_time) {
return new Promise((rec, rej) => {
this.findById(activity_id).exec((err, rew) => {
if (err) console.log(err);
let use_time = end_time - strat_time / 1000;
if (rew.time_lim - use_time > -20) {
rec(false);
} else {
rec(true);
}
})
})
}
activity.static.new_a_activity = function (question_db, post, file) {
return new Promise((rec, rej) => {
let a_activity = new this({
name: post.name,
strat_time: new Date(post.strat_time),
end_time: new Date(post.end_time),
question_num: post.question_num,
question_list: [],
time_lim: post.time_lim,
contestant_paper_list: [],
})
let promise_list = [];
fs.createReadStream(file.path)
.pipe(csv())
.on("data", (data) => {
if (data[3] != "A选项的分值") {
let out = { answer: [] };
for (key in data) {
if (data[key] === '') {
if (key == 0) {
out.type = Number(data[key]);
} else if (key == 1) {
out.problem = data[key];
} else {
if (key % 2 == 0) {
out.answer.push({ content: data[key], price: 0, try_user_list: [] });
} else {
out.answer[parseInt(key / 2) - 1].price = Number(data[key]);
}
}
}
}
promise_list.push(question_db.add_question(out));
}
})
.on("end", async () => {
a_activity.question_list = await Promise.all(promise_list);
await a_activity.save();
rec(a_activity._id);
});
})
}
// name student_id school user_class telephone fraction
activity.static.get_fraction_out_put = function (test_db, activity_id) {
return new Promise((rec, rej) => {
this.findById(activity_id).exec(async (err, rew) => {
if (err) console.log(err);
let promise_list = [];
for (i of rew.contestant_paper_list) {
promise_list.push(test_db.get_list_adout_fraction_csv(i));
}
let out_put = await Promise.all(promise_list);
out_put.unshift("name,student_id,school,user,class,telephone,fraction");
let random = new Promise((rec, rej) => {
require('crypto').randomBytes(32, function (ex, buf) {
var token = buf.toString('hex');
rec(token);
});
})
let fileData = Buffer.from(out_put.join('\n'));
let path = '/tmp/' + (await random()) + '.csv'
let wstream = fs.createWriteStream(path);
wstream.on('open', () => {
const blockSize = 128;
const nbBlocks = Math.ceil(fileData.length / (blockSize));
for (let i = 0; i < nbBlocks; i += 1) {
const currentBlock = fileData.slice(
blockSize * i,
Math.min(blockSize * (i + 1), fileData.length),
);
wstream.write(currentBlock);
}
wstream.end();
});
wstream.on('finish', () => {rec(path);});
})
})
}
test_paper.static.get_list_adout_fraction_csv = function (test_id) {
return new Promise((rec, rej) => {
this.findById(test_id).populate("user_id").exec((err, rew) => {
if (err) console.log(err);
let out = [
rew.user_id.name,
rew.user_id.student_id,
rew.user_id.school,
rew.user_id.user_class,
rew.user_id.telephone,
rew.fraction
];
rec(out.join(','));
})
})
}
test_paper.static.log_in = function (question_db, activity_id, user_id, strat_time, end_time, post) {
return new Promise((rec, rej) => {
this.findOne({ user_id: user_id, activity: activity_id }).exec(async (err, rew) => {
if (err) console.log(err);
if (rew) {
rec("had");
} else {
let a_test_paper = new this({
user_id: user_id,
activity: activity_id,
question_list: [],
answer: [],
time_start: strat_time,
time_end: end_time,
fraction: 0
})
let promise_list = [];
for (a in post) {
promise_list.push(question_db.get_in_it(a, post[a], user_id));
a_test_paper.answer.push(post[a]);
a_test_paper.problem.push(a);
}
let fraction_list = await Promise.all(promise_list);
a_test_paper.fraction = eval(fraction_list.join("+"));
await a_test_paper.save();
rec(a_test_paper._id);
}
})
})
}
question.static.get_in_it = function (question_id, answer_num, user_id) {
return new Promise((rec, rej) => {
this.findById(question_id).exec((err, rew) => {
if (err) console.log(err);
if (rew.answer[answer_num % rew.answer.length].try_user_list.indexOf(user_id) == -1) {
rew.answer[answer_num % rew.answer.length].try_user_list.push(user_id);
}
rec(rew.answer[answer_num % rew.answer.length].price);
})
})
}
question.static.add_question = function (in_question) {
let a_new_question = new this(in_question);
return new Promise(async (rec, rej) => {
await a_new_question.save();
rec(a_new_question._id);
})
}
mongoose.connect("mongodb://127.0.0.1:27017/question", { config: { autoIndex: false } });
let admin_db = mongoose.model('admin', admin);
let user_db = mongoose.model('user', user);
let activity_db = mongoose.model('activity', activity);
let question_db = mongoose.model('question', question);
let test_paper_db = mongoose.model('test_paper', test_paper);
let cookie_db = mongoose.model('cookie', cookie);
module.exports = {
admin: admin_db,
user: user_db,
activity: activity_db,
question: question_db,
test_paper: test_paper_db,
cookie: cookie_db,
}