更新代码并配置依赖忽略
This commit is contained in:
parent
eea951ea09
commit
90227161a2
14
.gitignore
vendored
14
.gitignore
vendored
|
|
@ -36,6 +36,20 @@ dist/
|
|||
nbdist/
|
||||
.nb-gradle/
|
||||
|
||||
######################################################################
|
||||
# Node.js / Frontend Dependencies
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Frontend Build Output
|
||||
dist/
|
||||
*.local
|
||||
|
||||
######################################################################
|
||||
# Others
|
||||
*.log
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@
|
|||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="350">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
|
|
@ -100,6 +100,13 @@
|
|||
v-if="scope.row.status === '0' || scope.row.status === '3'"
|
||||
v-hasPermi="['psychology:assessment:edit']"
|
||||
>继续答题</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-document"
|
||||
@click="handleViewAnswers(scope.row)"
|
||||
v-if="scope.row.status === '1'"
|
||||
>查看答题</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
|
|
@ -133,12 +140,54 @@
|
|||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 答题详情对话框 -->
|
||||
<el-dialog title="答题详情" :visible.sync="answerDetailOpen" width="80%" append-to-body>
|
||||
<div v-loading="answerDetailLoading">
|
||||
<el-descriptions :column="2" border style="margin-bottom: 20px;">
|
||||
<el-descriptions-item label="测评ID">{{ currentAssessment.assessmentId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="被测评人">{{ currentAssessment.assesseeName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="量表ID">{{ currentAssessment.scaleId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="提交时间">
|
||||
<span v-if="currentAssessment.submitTime">{{ parseTime(currentAssessment.submitTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="总分">{{ currentAssessment.totalScore || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="答题数量">{{ answerDetailList.length }} 题</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-divider content-position="left">答题详情</el-divider>
|
||||
<el-table :data="answerDetailList" border style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="题目序号" prop="itemNumber" width="100" align="center" />
|
||||
<el-table-column label="题目内容" prop="itemContent" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="题目类型" prop="itemType" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.itemType === 'single'" type="primary" size="small">单选</el-tag>
|
||||
<el-tag v-else-if="scope.row.itemType === 'multiple'" type="success" size="small">多选</el-tag>
|
||||
<el-tag v-else-if="scope.row.itemType === 'matrix'" type="warning" size="small">矩阵</el-tag>
|
||||
<span v-else>{{ scope.row.itemType }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="答案" prop="answerDisplay" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="得分" prop="answerScore" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.answerScore || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="answerDetailOpen = false">关 闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listAssessment, getAssessment, delAssessment, pausedAssessmentList } from "@/api/psychology/assessment";
|
||||
import { listAssessment, getAssessment, delAssessment, pausedAssessmentList, getAssessmentAnswers, getAssessmentItems } from "@/api/psychology/assessment";
|
||||
import { listScale } from "@/api/psychology/scale";
|
||||
import { listOption } from "@/api/psychology/option";
|
||||
|
||||
export default {
|
||||
name: "Assessment",
|
||||
|
|
@ -176,7 +225,12 @@ export default {
|
|||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {}
|
||||
rules: {},
|
||||
// 答题详情对话框
|
||||
answerDetailOpen: false,
|
||||
answerDetailLoading: false,
|
||||
answerDetailList: [],
|
||||
currentAssessment: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -257,6 +311,104 @@ export default {
|
|||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 查看答题详情 */
|
||||
handleViewAnswers(row) {
|
||||
this.currentAssessment = row;
|
||||
this.answerDetailOpen = true;
|
||||
this.answerDetailLoading = true;
|
||||
this.answerDetailList = [];
|
||||
|
||||
// 并行获取题目列表和答案列表
|
||||
Promise.all([
|
||||
getAssessmentItems(row.assessmentId),
|
||||
getAssessmentAnswers(row.assessmentId)
|
||||
]).then(([itemsRes, answersRes]) => {
|
||||
const items = itemsRes.data || [];
|
||||
const answers = answersRes.data || [];
|
||||
|
||||
// 创建答案映射表(以itemId为key)
|
||||
const answerMap = {};
|
||||
answers.forEach(answer => {
|
||||
answerMap[answer.itemId] = answer;
|
||||
});
|
||||
|
||||
// 获取所有题目的选项信息
|
||||
const optionPromises = items.map(item => {
|
||||
return listOption(item.itemId).then(optionRes => {
|
||||
return {
|
||||
itemId: item.itemId,
|
||||
options: optionRes.data || []
|
||||
};
|
||||
}).catch(() => {
|
||||
return {
|
||||
itemId: item.itemId,
|
||||
options: []
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all(optionPromises).then(optionResults => {
|
||||
// 创建选项映射表
|
||||
const optionMap = {};
|
||||
optionResults.forEach(result => {
|
||||
optionMap[result.itemId] = result.options;
|
||||
});
|
||||
|
||||
// 合并题目、答案和选项信息
|
||||
this.answerDetailList = items.map(item => {
|
||||
const answer = answerMap[item.itemId] || {};
|
||||
const options = optionMap[item.itemId] || [];
|
||||
|
||||
// 格式化答案显示
|
||||
let answerDisplay = '-';
|
||||
if (answer.optionId) {
|
||||
// 单选:查找选项内容
|
||||
const option = options.find(opt => opt.optionId === answer.optionId);
|
||||
if (option) {
|
||||
answerDisplay = `${option.optionCode}. ${option.optionContent}`;
|
||||
} else {
|
||||
answerDisplay = `选项ID: ${answer.optionId}`;
|
||||
}
|
||||
} else if (answer.optionIds) {
|
||||
// 多选:查找所有选项内容
|
||||
const optionIdArray = answer.optionIds.split(',').map(id => id.trim());
|
||||
const selectedOptions = options.filter(opt => optionIdArray.includes(String(opt.optionId)));
|
||||
if (selectedOptions.length > 0) {
|
||||
answerDisplay = selectedOptions.map(opt => `${opt.optionCode}. ${opt.optionContent}`).join('; ');
|
||||
} else {
|
||||
answerDisplay = `选项IDs: ${answer.optionIds}`;
|
||||
}
|
||||
} else if (answer.answerText) {
|
||||
// 文本答案
|
||||
answerDisplay = answer.answerText;
|
||||
}
|
||||
|
||||
return {
|
||||
itemId: item.itemId,
|
||||
itemNumber: item.itemNumber,
|
||||
itemContent: item.itemContent,
|
||||
itemType: item.itemType,
|
||||
answerDisplay: answerDisplay,
|
||||
answerScore: answer.answerScore,
|
||||
answerId: answer.answerId,
|
||||
optionId: answer.optionId,
|
||||
optionIds: answer.optionIds,
|
||||
answerText: answer.answerText
|
||||
};
|
||||
});
|
||||
|
||||
this.answerDetailLoading = false;
|
||||
}).catch(error => {
|
||||
console.error('获取选项信息失败:', error);
|
||||
this.$modal.msgError("获取选项信息失败");
|
||||
this.answerDetailLoading = false;
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error('获取答题详情失败:', error);
|
||||
this.$modal.msgError("获取答题详情失败");
|
||||
this.answerDetailLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@
|
|||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 答题详情(量表类型报告) -->
|
||||
<el-divider v-if="sourceType === 'assessment' && reportForm.assessmentId" content-position="left">答题详情</el-divider>
|
||||
<div v-if="sourceType === 'assessment' && reportForm.assessmentId" class="answer-detail-section">
|
||||
<el-button type="primary" icon="el-icon-document" @click="handleViewAnswers" :loading="answerDetailLoading">
|
||||
查看答题详情
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-divider v-if="reportForm.pdfPath" content-position="left">PDF下载</el-divider>
|
||||
<div v-if="reportForm.pdfPath">
|
||||
<el-button type="primary" icon="el-icon-download" @click="handleDownloadPDF">下载PDF报告</el-button>
|
||||
|
|
@ -102,6 +110,46 @@
|
|||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 答题详情对话框 -->
|
||||
<el-dialog title="答题详情" :visible.sync="answerDetailOpen" width="80%" append-to-body>
|
||||
<div v-loading="answerDetailLoading">
|
||||
<el-descriptions :column="2" border style="margin-bottom: 20px;">
|
||||
<el-descriptions-item label="测评ID">{{ reportForm.assessmentId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="报告ID">{{ reportForm.reportId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="提交时间">
|
||||
<span v-if="assessmentInfo.submitTime">{{ parseTime(assessmentInfo.submitTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="总分">{{ assessmentInfo.totalScore || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="答题数量">{{ answerDetailList.length }} 题</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-divider content-position="left">答题详情</el-divider>
|
||||
<el-table :data="answerDetailList" border style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="题目序号" prop="itemNumber" width="100" align="center" />
|
||||
<el-table-column label="题目内容" prop="itemContent" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="题目类型" prop="itemType" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.itemType === 'single'" type="primary" size="small">单选</el-tag>
|
||||
<el-tag v-else-if="scope.row.itemType === 'multiple'" type="success" size="small">多选</el-tag>
|
||||
<el-tag v-else-if="scope.row.itemType === 'matrix'" type="warning" size="small">矩阵</el-tag>
|
||||
<span v-else>{{ scope.row.itemType }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="答案" prop="answerDisplay" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="得分" prop="answerScore" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.answerScore || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="answerDetailOpen = false">关 闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 报告编辑对话框 -->
|
||||
<el-dialog title="编辑报告" :visible.sync="editOpen" width="900px" append-to-body>
|
||||
<el-form ref="editForm" :model="editForm" :rules="editRules" label-width="100px">
|
||||
|
|
@ -133,6 +181,8 @@
|
|||
<script>
|
||||
import { getReport, getReportByAssessmentId, updateReportWithType } from "@/api/psychology/report";
|
||||
import { getQuestionnaireRankList } from "@/api/psychology/questionnaireAnswer";
|
||||
import { getAssessmentAnswers, getAssessmentItems, getAssessment } from "@/api/psychology/assessment";
|
||||
import { listOption } from "@/api/psychology/option";
|
||||
import request from '@/utils/request';
|
||||
import axios from 'axios';
|
||||
import Editor from "@/components/Editor";
|
||||
|
|
@ -161,7 +211,12 @@ export default {
|
|||
reportType: [
|
||||
{ required: true, message: "报告类型不能为空", trigger: "change" }
|
||||
]
|
||||
}
|
||||
},
|
||||
// 答题详情
|
||||
answerDetailOpen: false,
|
||||
answerDetailLoading: false,
|
||||
answerDetailList: [],
|
||||
assessmentInfo: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -444,6 +499,110 @@ export default {
|
|||
html = html.replace(/```html\s*/gi, '').replace(/```\s*/g, '');
|
||||
|
||||
return html;
|
||||
},
|
||||
/** 查看答题详情 */
|
||||
handleViewAnswers() {
|
||||
if (!this.reportForm.assessmentId) {
|
||||
this.$modal.msgWarning("无法获取测评ID");
|
||||
return;
|
||||
}
|
||||
|
||||
this.answerDetailOpen = true;
|
||||
this.answerDetailLoading = true;
|
||||
this.answerDetailList = [];
|
||||
|
||||
// 并行获取测评信息、题目列表和答案列表
|
||||
Promise.all([
|
||||
getAssessment(this.reportForm.assessmentId),
|
||||
getAssessmentItems(this.reportForm.assessmentId),
|
||||
getAssessmentAnswers(this.reportForm.assessmentId)
|
||||
]).then(([assessmentRes, itemsRes, answersRes]) => {
|
||||
this.assessmentInfo = assessmentRes.data || {};
|
||||
const items = itemsRes.data || [];
|
||||
const answers = answersRes.data || [];
|
||||
|
||||
// 创建答案映射表(以itemId为key)
|
||||
const answerMap = {};
|
||||
answers.forEach(answer => {
|
||||
answerMap[answer.itemId] = answer;
|
||||
});
|
||||
|
||||
// 获取所有题目的选项信息
|
||||
const optionPromises = items.map(item => {
|
||||
return listOption(item.itemId).then(optionRes => {
|
||||
return {
|
||||
itemId: item.itemId,
|
||||
options: optionRes.data || []
|
||||
};
|
||||
}).catch(() => {
|
||||
return {
|
||||
itemId: item.itemId,
|
||||
options: []
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all(optionPromises).then(optionResults => {
|
||||
// 创建选项映射表
|
||||
const optionMap = {};
|
||||
optionResults.forEach(result => {
|
||||
optionMap[result.itemId] = result.options;
|
||||
});
|
||||
|
||||
// 合并题目、答案和选项信息
|
||||
this.answerDetailList = items.map(item => {
|
||||
const answer = answerMap[item.itemId] || {};
|
||||
const options = optionMap[item.itemId] || [];
|
||||
|
||||
// 格式化答案显示
|
||||
let answerDisplay = '-';
|
||||
if (answer.optionId) {
|
||||
// 单选:查找选项内容
|
||||
const option = options.find(opt => opt.optionId === answer.optionId);
|
||||
if (option) {
|
||||
answerDisplay = `${option.optionCode}. ${option.optionContent}`;
|
||||
} else {
|
||||
answerDisplay = `选项ID: ${answer.optionId}`;
|
||||
}
|
||||
} else if (answer.optionIds) {
|
||||
// 多选:查找所有选项内容
|
||||
const optionIdArray = answer.optionIds.split(',').map(id => id.trim());
|
||||
const selectedOptions = options.filter(opt => optionIdArray.includes(String(opt.optionId)));
|
||||
if (selectedOptions.length > 0) {
|
||||
answerDisplay = selectedOptions.map(opt => `${opt.optionCode}. ${opt.optionContent}`).join('; ');
|
||||
} else {
|
||||
answerDisplay = `选项IDs: ${answer.optionIds}`;
|
||||
}
|
||||
} else if (answer.answerText) {
|
||||
// 文本答案
|
||||
answerDisplay = answer.answerText;
|
||||
}
|
||||
|
||||
return {
|
||||
itemId: item.itemId,
|
||||
itemNumber: item.itemNumber,
|
||||
itemContent: item.itemContent,
|
||||
itemType: item.itemType,
|
||||
answerDisplay: answerDisplay,
|
||||
answerScore: answer.answerScore,
|
||||
answerId: answer.answerId,
|
||||
optionId: answer.optionId,
|
||||
optionIds: answer.optionIds,
|
||||
answerText: answer.answerText
|
||||
};
|
||||
});
|
||||
|
||||
this.answerDetailLoading = false;
|
||||
}).catch(error => {
|
||||
console.error('获取选项信息失败:', error);
|
||||
this.$modal.msgError("获取选项信息失败");
|
||||
this.answerDetailLoading = false;
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error('获取答题详情失败:', error);
|
||||
this.$modal.msgError("获取答题详情失败");
|
||||
this.answerDetailLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -562,5 +721,13 @@ export default {
|
|||
.ai-result-content >>> br {
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
/* 答题详情区域样式 */
|
||||
.answer-detail-section {
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user