更新代码并配置依赖忽略

This commit is contained in:
green 2025-11-23 12:22:35 +08:00
parent eea951ea09
commit 90227161a2
3 changed files with 337 additions and 4 deletions

14
.gitignore vendored
View File

@ -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

View File

@ -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 || [];
// itemIdkey
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;
});
}
}
};

View File

@ -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 || [];
// itemIdkey
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>