本文记录在发布文章时,可以添加自己创建的面试官和面试记录到文章中这一功能的实现。
前端
首先是在原本的界面的底部添加了两个多选框(后期需要美化调整)
实现的代码:
<el-col style="margin-top: 1rem;">
<el-select
style="width: 100%; margin-bottom: 1rem;"
v-model="selectedInterviewers"
multiple
filterable
placeholder="请选择面试官"
:loading="interviewersLoading">
<el-option
v-for="item in interviewersList"
:key="item.interviewerId"
:label="item.name"
:value="item.interviewerId">
<span>{{ item.name }}</span>
</el-option>
</el-select>
<el-select
style="width: 100%; margin-bottom: 1rem;"
v-model="selectedInterviews"
multiple
filterable
placeholder="请选择面试记录"
:loading="interviewsLoading">
<el-option
v-for="item in interviewsList"
:key="item.chatId"
:label="item.topic"
:value="item.chatId">
<span>{{ item.topic }}</span>
<!-- <span style="float: right; color: #8492a6; font-size: 13px">{{ item.topic }}</span> -->
</el-option>
</el-select>
</el-col>
然后是前端脚本,添加以下函数:
getInterviewers
用来获取该用户创建的所有面试官。getInterviews
用来获取该用户创建的所有面试记录。
其次,在创建文章和保存文章时,也添加了两个列表分别存储面试官ID和面试记录ID。
// 获取用户创建的面试官列表
async getInterviewers() {
let _ts = this;
_ts.interviewersLoading = true;
try {
const res = await _ts.$axios.$get('/api/share/getUserInterviewers');
if (res) {
_ts.$set(_ts, 'interviewersList', res);
console.log(res);
}
} catch (err) {
_ts.$message.error('获取面试官列表失败');
} finally {
_ts.interviewersLoading = false;
}
},
// 获取用户创建的面试记录列表
async getInterviews() {
let _ts = this;
_ts.interviewsLoading = true;
try {
const res = await _ts.$axios.$get('/api/share/getUserChatRecords');
if (res) {
_ts.$set(_ts, 'interviewsList', res);
console.log(res);
}
} catch (err) {
_ts.$message.error('获取面试记录列表失败');
} finally {
_ts.interviewsLoading = false;
}
}
后端接口
getUserInterviewers
用来获取该用户创建的所有面试官。/getUserChatRecords
用来获取该用户创建的所有面试记录。
@GetMapping("/getUserInterviewers")
public GlobalResult getUserInterviewers() {
Long idUser = UserUtils.getCurrentUserByToken().getIdUser();
List<Interviewer> interviewers = interviewerService.findInterviewers().stream()
.filter(interviewer -> interviewer.getUserId() != null && interviewer.getUserId().equals(idUser))
.collect(Collectors.toList());
return GlobalResultGenerator.genSuccessResult(interviewers);
}
@GetMapping("/getUserChatRecords")
public GlobalResult getUserChatRecords() {
Long idUser = UserUtils.getCurrentUserByToken().getIdUser();
// 1. 查询用户的所有面试官
List<Interviewer> interviewers = interviewerService.findInterviewers();
// 2. 收集所有面试记录
List<ChatRecords> allRecords = new ArrayList<>();
for (Interviewer interviewer : interviewers) {
ChatRecords query = new ChatRecords();
query.setUserId(idUser);
query.setInterviewerId(interviewer.getInterviewerId());
allRecords.addAll(chatService.getChatRecords(query));
}
return GlobalResultGenerator.genSuccessResult(allRecords);
}
问题记录
- 前端发送的 JSON 中:
"chatRecordsList": [248], // 数字数组
"interviewerList": ["680c96954b1d8a29c9e78e97"] // 字符串数组
- 后端 DTO 期望:
private List<ChatRecordsDto> chatRecordsList; // 需要对象而非数字
private List<Interviewer> interviewerList; // 需要对象而非字符串
- FastJSON 无法直接将
248
或字符串 ID 转换为ChatRecordsDto
/Interviewer
对象。
解决方案
调整前端 JSON 结构
后端需要完整的对象而非 ID,前端发送嵌套对象:
{
"chatRecordsList": [{"id": 248}], // 匹配 ChatRecordsDto 结构
"interviewerList": [{"id": "680c96954b1d8a29c9e78e97"}] // 匹配 Interviewer 结构
}
具体修改:
let article = {
idArticle: _ts.idArticle,
articleTitle: _ts.articleTitle,
articleContent: articleContent,
articleContentHtml: articleContentHtml,
articleTags: _ts.articleTags.join(","),
articleStatus: 0,
interviewerList: _ts.selectedInterviewers.map(id => ({
interviewerId: id,
name: null,
userId: null,
knowledgeBaseId: null,
customPrompt: null,
settingsList: null
})),
chatRecordsList: _ts.selectedInterviews.map(id => {
const interview = _ts.interviewsList.find(item => item.chatId === id);
return {
interviewer: {
interviewerId: interview ? interview.interviewerId : null,
name: null,
userId: null,
knowledgeBaseId: null,
customPrompt: null,
settingsList: null
},
branch: null,
chatId: id,
userId: null,
interviewerId: interview ? interview.interviewerId : null,
createdAt: null,
updatedAt: null,
topic: null,
};
})
};