|
@@ -38,60 +38,86 @@ class executor extends EventEmitter {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- async addWatermark(image, file, student) {
|
|
|
|
|
|
+ async addWatermark(image, file, student, index) {
|
|
let fontSize = config.watermark.fontSize
|
|
let fontSize = config.watermark.fontSize
|
|
let fontFile = config.watermark.fontFile
|
|
let fontFile = config.watermark.fontFile
|
|
let color = config.watermark.color
|
|
let color = config.watermark.color
|
|
- let imgData = gm(image).font(fontFile, fontSize).fill(color)
|
|
|
|
|
|
+ let imgData = gm(image)
|
|
let size = sizeOf(image)
|
|
let size = sizeOf(image)
|
|
- //初始坐标
|
|
|
|
- let x = 30
|
|
|
|
- let y = 10
|
|
|
|
- let height = fontSize + 10
|
|
|
|
- //最大宽/高限制
|
|
|
|
- let maxX = size.width - x * 2
|
|
|
|
- //计算总分
|
|
|
|
- let totalScore = (parseFloat(student.objectiveScore) || 0) + (parseFloat(student.subjectiveScore) || 0)
|
|
|
|
- //显示总分明细
|
|
|
|
- imgData.drawText(x, y += height, '成绩明细')
|
|
|
|
- imgData.drawText(x, y += height, '总分=(客观+主观) | ' + totalScore + '=' + student.objectiveScore + '+' + student.subjectiveScore)
|
|
|
|
- //显示客观题明细
|
|
|
|
- if (student.objectiveScoreDetail && student.objectiveScoreDetail.length > 0) {
|
|
|
|
- let lines = []
|
|
|
|
- let array = []
|
|
|
|
- //前置提示文字的字符数
|
|
|
|
- let count = 10
|
|
|
|
- lines.push(array)
|
|
|
|
- for (let i = 0; i < student.objectiveScoreDetail.length; i++) {
|
|
|
|
- let detail = student.objectiveScoreDetail[i]
|
|
|
|
- let content = detail.answer + ':' + detail.score
|
|
|
|
- //超长后另起一行显示客观题
|
|
|
|
- if ((count + content.length) * fontSize * 0.7 > maxX) {
|
|
|
|
- array = []
|
|
|
|
- lines.push(array)
|
|
|
|
- count = 10
|
|
|
|
|
|
+ //添加第一页的得分明细
|
|
|
|
+ if (index == 1) {
|
|
|
|
+ //初始坐标
|
|
|
|
+ let x = 30
|
|
|
|
+ let y = 10
|
|
|
|
+ //最大宽/高限制
|
|
|
|
+ let fontSize = 30
|
|
|
|
+ let maxX = size.width / 2 - x * 2
|
|
|
|
+ let height = fontSize + 10
|
|
|
|
+ //计算总分
|
|
|
|
+ let totalScore = (parseFloat(student.objectiveScore) || 0) + (parseFloat(student.subjectiveScore) || 0)
|
|
|
|
+ //显示总分明细
|
|
|
|
+ imgData.font(fontFile, fontSize).fill(color)
|
|
|
|
+ imgData.drawText(x, y += height, '成绩明细')
|
|
|
|
+ imgData.drawText(x, y += height, '总分=(客观+主观) | ' + totalScore + '=' + student.objectiveScore + '+' + student.subjectiveScore)
|
|
|
|
+ //显示客观题明细
|
|
|
|
+ if (student.objectiveScoreDetail && student.objectiveScoreDetail.length > 0) {
|
|
|
|
+ let lines = []
|
|
|
|
+ let array = []
|
|
|
|
+ //前置提示文字的字符数
|
|
|
|
+ let count = 10
|
|
|
|
+ lines.push(array)
|
|
|
|
+ for (let i = 0; i < student.objectiveScoreDetail.length; i++) {
|
|
|
|
+ let detail = student.objectiveScoreDetail[i]
|
|
|
|
+ let content = detail.answer + ':' + detail.score
|
|
|
|
+ //超长后另起一行显示客观题
|
|
|
|
+ if ((count + content.length) * fontSize * 0.7 > maxX) {
|
|
|
|
+ array = []
|
|
|
|
+ lines.push(array)
|
|
|
|
+ count = 10
|
|
|
|
+ }
|
|
|
|
+ array.push(content)
|
|
|
|
+ count += content.length
|
|
|
|
+ }
|
|
|
|
+ //显示所有行的客观题明细
|
|
|
|
+ for (let l = 0; l < lines.length; l++) {
|
|
|
|
+ imgData.drawText(x, y += height, '客观题识别结果 | ' + lines[l].join(';'))
|
|
}
|
|
}
|
|
- array.push(content)
|
|
|
|
- count += content.length
|
|
|
|
}
|
|
}
|
|
- //显示所有行的客观题明细
|
|
|
|
- for (let l = 0; l < lines.length; l++) {
|
|
|
|
- imgData.drawText(x, y += height, '客观题识别结果 | ' + lines[l].join(';'))
|
|
|
|
|
|
+ //显示主观题明细
|
|
|
|
+ if (student.subjectiveScoreDetail && student.subjectiveScoreDetail.length > 0) {
|
|
|
|
+ let startY = y
|
|
|
|
+ imgData.drawText(x, y += height, '题号 | 分数')
|
|
|
|
+ for (let i = 0; i < student.subjectiveScoreDetail.length; i++) {
|
|
|
|
+ let detail = student.subjectiveScoreDetail[i]
|
|
|
|
+ //超过最大高度了则另起一列
|
|
|
|
+ if ((y + height + 15) > size.height) {
|
|
|
|
+ y = startY
|
|
|
|
+ x += 300
|
|
|
|
+ imgData.drawText(x, y += height, '题号 | 分数')
|
|
|
|
+ }
|
|
|
|
+ let content = detail.mainNumber + '-' + detail.subNumber + ' : ' + detail.score
|
|
|
|
+ if (detail.marker != undefined) {
|
|
|
|
+ content = content + ' ' + detail.marker.join(',')
|
|
|
|
+ }
|
|
|
|
+ imgData.drawText(x, y += height, content)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- //显示主观题明细
|
|
|
|
- if (student.subjectiveScoreDetail && student.subjectiveScoreDetail.length > 0) {
|
|
|
|
- let startY = y
|
|
|
|
- imgData.drawText(x, y += height, '题号 | 分数')
|
|
|
|
- for (let i = 0; i < student.subjectiveScoreDetail.length; i++) {
|
|
|
|
- let detail = student.subjectiveScoreDetail[i]
|
|
|
|
- //超过最大高度了则另起一列
|
|
|
|
- if ((y + height + 15) > size.height) {
|
|
|
|
- y = startY
|
|
|
|
- x += 200
|
|
|
|
- imgData.drawText(x, y += height, '题号 | 分数')
|
|
|
|
|
|
+ //显示评卷标记
|
|
|
|
+ if (student.tags != undefined && student.tags[index] != undefined) {
|
|
|
|
+ let fontSize = 60
|
|
|
|
+ let height = fontSize + 10
|
|
|
|
+ imgData.font(fontFile, fontSize).fill(color)
|
|
|
|
+ let tags = student.tags[index]
|
|
|
|
+ for (let i = 0; i < tags.length; i++) {
|
|
|
|
+ let tag = tags[i]
|
|
|
|
+ if (tag.content != undefined) {
|
|
|
|
+ let top = tag.top
|
|
|
|
+ for (let j = 0; j < tag.content.length; j++) {
|
|
|
|
+ imgData.drawText(tag.left, top, tag.content[j])
|
|
|
|
+ top += height
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- imgData.drawText(x, y += height, detail.mainNumber + '-' + detail.subNumber + ' : ' + detail.score)
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
@@ -105,7 +131,8 @@ class executor extends EventEmitter {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- async downloadFile(remoteTemplate, localTemplate, data, dir, client, bucket, watermark) {
|
|
|
|
|
|
+ async downloadFile(remoteTemplate, localTemplate, data, dir, client, bucket, index, watermark) {
|
|
|
|
+ data.index = index
|
|
let remote = mustache.render(remoteTemplate, data)
|
|
let remote = mustache.render(remoteTemplate, data)
|
|
let local = path.join(dir, mustache.render(localTemplate, data))
|
|
let local = path.join(dir, mustache.render(localTemplate, data))
|
|
mkdirp.sync(path.dirname(local))
|
|
mkdirp.sync(path.dirname(local))
|
|
@@ -133,7 +160,7 @@ class executor extends EventEmitter {
|
|
}
|
|
}
|
|
//是否需要添加分数水印
|
|
//是否需要添加分数水印
|
|
if (watermark) {
|
|
if (watermark) {
|
|
- await this.addWatermark(imgData, local, data)
|
|
|
|
|
|
+ await this.addWatermark(imgData, local, data, index)
|
|
} else {
|
|
} else {
|
|
await fs.writeFileSync(local, imgData)
|
|
await fs.writeFileSync(local, imgData)
|
|
}
|
|
}
|
|
@@ -166,7 +193,7 @@ class executor extends EventEmitter {
|
|
while (true) {
|
|
while (true) {
|
|
pageNumber++
|
|
pageNumber++
|
|
|
|
|
|
- let array = await api.getStudents(env.examId, pageNumber, 100, true, undefined, watermark === true)
|
|
|
|
|
|
+ let array = await api.getStudents(env.examId, pageNumber, 10, true, undefined, watermark === true, watermark === true)
|
|
if (array == undefined || array.length == 0) {
|
|
if (array == undefined || array.length == 0) {
|
|
break
|
|
break
|
|
}
|
|
}
|
|
@@ -179,8 +206,7 @@ class executor extends EventEmitter {
|
|
} else {
|
|
} else {
|
|
student.examId = env.examId
|
|
student.examId = env.examId
|
|
for (let i = 1; i <= student.sheetCount; i++) {
|
|
for (let i = 1; i <= student.sheetCount; i++) {
|
|
- student.index = i
|
|
|
|
- promises.push(this.downloadFile(config.imageUrl.sheet, template, student, dir, client, bucket, (i == 1 && watermark)))
|
|
|
|
|
|
+ promises.push(this.downloadFile(config.imageUrl.sheet, template, student, dir, client, bucket, i, watermark))
|
|
}
|
|
}
|
|
//等待所有图片下载完毕
|
|
//等待所有图片下载完毕
|
|
await Promise.all(promises)
|
|
await Promise.all(promises)
|
|
@@ -238,6 +264,6 @@ class executor extends EventEmitter {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-module.exports = function () {
|
|
|
|
|
|
+module.exports = function() {
|
|
return new executor()
|
|
return new executor()
|
|
}
|
|
}
|