<template>
|
<div class="merge-questionnaire-container">
|
<div class="merge-header">
|
<h3>合并编辑问卷 (共 {{ services.length }} 个未完成服务)</h3>
|
<el-tag
|
v-for="service in services"
|
:key="service.id"
|
type="info"
|
style="margin-right: 10px"
|
>
|
{{ service.taskName }} ({{ service.sendname }})
|
</el-tag>
|
</div>
|
|
<div class="merge-content">
|
<div class="question-list">
|
<div
|
v-for="(question, index) in mergedQuestions"
|
:key="question.uniqueKey"
|
class="question-item"
|
>
|
<!-- 题目展示 - 与父组件保持一致 -->
|
<div
|
:class="
|
question.isabnormal ? 'scriptTopic-isabnormal' : 'scriptTopic-dev'
|
"
|
>
|
<div class="dev-text">
|
{{ index + 1 }}、[{{
|
getQuestionType(question.scriptType)
|
}}]<span> {{ question.scriptContent }}</span>
|
</div>
|
|
<!-- 单选 -->
|
<div class="dev-xx" v-if="question.scriptType == 1">
|
<el-radio-group
|
v-model="question.mergedResult"
|
@change="
|
handleOptionChange(
|
$event,
|
index,
|
question.svyLibTemplateTargetoptions,
|
question
|
)
|
"
|
>11
|
<el-radio
|
v-for="(
|
option, optIndex
|
) in question.svyLibTemplateTargetoptions"
|
:key="optIndex"
|
:label="option.optioncontent"
|
:class="option.isabnormal ? 'red-star' : ''"
|
>
|
{{ option.optioncontent }}
|
</el-radio>
|
</el-radio-group>
|
</div>
|
|
<!-- 多选 -->
|
<div class="dev-xx" v-if="question.scriptType == 2">
|
<el-checkbox-group
|
v-model="question.mergedResult"
|
@change="updateScore($event, index, question.options, question)"
|
>
|
<el-checkbox
|
v-for="(option, optIndex) in question.options"
|
:key="optIndex"
|
:label="option.optioncontent"
|
:class="option.isabnormal ? 'red-star' : ''"
|
>
|
{{ option.optioncontent }}
|
</el-checkbox>
|
</el-checkbox-group>
|
</div>
|
|
<!-- 填空 -->
|
<div class="dev-xx" v-if="question.scriptType == 4">
|
<el-input
|
type="textarea"
|
:rows="2"
|
placeholder="请输入答案"
|
v-model="question.mergedResult"
|
clearable
|
/>
|
</div>
|
|
<!-- 附加输入框 -->
|
<div v-if="question.showAppendInput" class="append-input-container">
|
<el-input
|
type="textarea"
|
:rows="2"
|
placeholder="请输入具体信息"
|
v-model="question.answerps"
|
clearable
|
/>
|
</div>
|
|
<!-- 提示信息 -->
|
<div v-show="question.prompt">
|
<el-alert :title="question.prompt" type="warning" />
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<div class="merge-footer">
|
<el-button @click="handleCancel">取消</el-button>
|
<el-button type="primary" @click="handleSave" :loading="isSaving"
|
>保存到所有问卷</el-button
|
>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import {
|
getsearchrResults,
|
serviceSubtaskDetailedit,
|
serviceSubtaskDetailadd,
|
Editsingletaskson,
|
getTaskservelist,
|
alterpatient,
|
} from "@/api/AiCentre/index";
|
|
export default {
|
props: {
|
selectedServices: {
|
type: Array,
|
required: true,
|
},
|
patid: {
|
type: [String, Number],
|
required: true,
|
},
|
},
|
data() {
|
return {
|
services: [],
|
mergedQuestions: [], // 合并后的问题数据
|
isSaving: false,
|
};
|
},
|
created() {
|
this.loadServicesData();
|
},
|
methods: {
|
getQuestionType(type) {
|
const types = { 1: "单选", 2: "多选", 4: "问答" };
|
return types[type] || "未知";
|
},
|
|
async loadServicesData() {
|
this.services = this.selectedServices;
|
|
const loading = this.$loading({
|
lock: true,
|
text: "正在加载未完成问卷数据...",
|
spinner: "el-icon-loading",
|
background: "rgba(0, 0, 0, 0.7)",
|
});
|
|
try {
|
// 只加载未完成的服务问卷数据
|
const requests = this.services.map((service) =>
|
getsearchrResults({
|
taskid: service.taskid,
|
patid: this.patid,
|
subId: service.id,
|
isFinish: false, // 确保只获取未完成的问卷
|
})
|
);
|
|
const responses = await Promise.all(requests);
|
|
// 合并所有问题,去重
|
const allQuestions = [];
|
const questionMap = {};
|
|
responses.forEach((response, index) => {
|
if (response.code == 200 && response.data.scriptResult) {
|
response.data.scriptResult.forEach((q) => {
|
const key = `${q.scriptContent}_${q.scriptType}`;
|
if (!questionMap[key]) {
|
questionMap[key] = {
|
...q,
|
uniqueKey: key,
|
mergedResult: q.scriptType == 2 ? [] : null,
|
originalServices: [], // 记录原始服务ID
|
};
|
allQuestions.push(questionMap[key]);
|
}
|
questionMap[key].originalServices.push(this.services[index].id);
|
});
|
}
|
});
|
|
// 初始化合并结果
|
this.mergedQuestions = allQuestions.map((q) => ({
|
...q,
|
mergedResult: q.scriptType == 2 ? [] : q.scriptResult || null,
|
}));
|
console.log(this.mergedQuestions);
|
} catch (error) {
|
this.$message.error("加载问卷数据失败: " + error.message);
|
} finally {
|
loading.close();
|
}
|
},
|
|
// 处理选项变化 (与父组件保持一致)
|
handleOptionChange(selectedOption, questionIndex, options, question) {
|
const selectedOptionObj = options.find(
|
(item) => item.optioncontent == selectedOption
|
);
|
|
// 设置异常状态
|
question.isabnormal = !!selectedOptionObj?.isabnormal;
|
|
// 处理附加输入框显示
|
question.showAppendInput = selectedOptionObj?.appendflag == 1;
|
if (!question.showAppendInput) {
|
question.answerps = "";
|
}
|
|
this.$forceUpdate();
|
},
|
|
// 更新多选分数 (与父组件保持一致)
|
updateScore(selectedValues, questionIndex, options, question) {
|
const abnormalOptions = options.filter((opt) => opt.isabnormal);
|
question.isabnormal = abnormalOptions.some((opt) =>
|
selectedValues.includes(opt.optioncontent)
|
);
|
this.$forceUpdate();
|
},
|
|
handleCancel() {
|
this.$emit("cancel");
|
},
|
|
async handleSave() {
|
this.isSaving = true;
|
|
try {
|
const saveResults = [];
|
const updateServicePromises = [];
|
|
// 1. 保存所有问卷问题
|
for (const service of this.services) {
|
const serviceId = service.id;
|
const questionsToSave = this.mergedQuestions
|
.filter((q) => q.originalServices.includes(serviceId))
|
.map((question) => ({
|
scriptid: question.id,
|
scriptResultId: question.scriptResultId,
|
scriptType: question.scriptType,
|
questiontext: question.scriptContent,
|
asrtext:
|
question.scriptType == 2
|
? question.mergedResult.join("&")
|
: question.mergedResult,
|
answerps: question.answerps || null,
|
isabnormal: question.isabnormal || false,
|
}));
|
|
// 保存问题数据
|
for (const question of questionsToSave) {
|
const saveData = {
|
taskid: service.taskid,
|
patid: this.patid,
|
subId: serviceId,
|
...question,
|
};
|
|
if (saveData.isabnormal) {
|
saveData.excep = 1;
|
}
|
|
try {
|
const response = question.scriptResultId
|
? await serviceSubtaskDetailedit(saveData)
|
: await serviceSubtaskDetailadd(saveData);
|
|
saveResults.push({
|
serviceId,
|
success: response.code === 200,
|
message:
|
response.message ||
|
(response.code === 200 ? "保存成功" : "保存失败"),
|
});
|
} catch (error) {
|
saveResults.push({
|
serviceId,
|
success: false,
|
message: error.message || "保存失败",
|
});
|
}
|
}
|
|
// 2. 更新服务状态为已完成 (sendstate = 6)
|
updateServicePromises.push(this.updateServiceStatus(serviceId));
|
}
|
|
// 等待所有服务状态更新完成
|
const updateResults = await Promise.all(updateServicePromises);
|
updateResults.forEach((result) => {
|
if (!result.success) {
|
saveResults.push({
|
serviceId: result.serviceId,
|
success: false,
|
message: result.message || "服务状态更新失败",
|
});
|
}
|
});
|
|
// 统计结果
|
const successCount = saveResults.filter((r) => r.success).length;
|
const totalCount = saveResults.length;
|
|
// 通知父组件
|
this.$emit("save", {
|
successCount,
|
totalCount,
|
results: saveResults,
|
});
|
|
if (successCount === totalCount) {
|
this.$message.success("所有问卷和服务状态更新成功");
|
} else {
|
this.$message.warning(
|
`成功保存 ${successCount} 项,失败 ${totalCount - successCount} 项`
|
);
|
}
|
} catch (error) {
|
this.$message.error("保存过程中发生错误: " + error.message);
|
} finally {
|
this.isSaving = false;
|
}
|
},
|
// 新增方法:更新服务状态
|
async updateServiceStatus(serviceId) {
|
try {
|
// 获取服务当前数据
|
const res = await getTaskservelist({
|
patid: this.patid,
|
subId: serviceId,
|
});
|
|
if (res.code === 200) {
|
const serviceData = res.rows[0].serviceSubtaskList.find(
|
(item) => item.id === serviceId
|
);
|
|
if (serviceData) {
|
// 更新服务状态为已完成 (sendstate = 6)
|
const updateRes = await Editsingletaskson({
|
...serviceData,
|
sendstate: 6, // 设置为已完成状态
|
remark: "通过合并编辑完成", // 可选:添加备注
|
});
|
|
return {
|
serviceId,
|
success: updateRes.code === 200,
|
message: updateRes.message || "服务状态更新成功",
|
};
|
}
|
}
|
return {
|
serviceId,
|
success: false,
|
message: "获取服务数据失败",
|
};
|
} catch (error) {
|
return {
|
serviceId,
|
success: false,
|
message: error.message || "更新服务状态失败",
|
};
|
}
|
},
|
},
|
};
|
</script>
|
|
<style scoped>
|
.merge-questionnaire-container {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
padding: 20px;
|
}
|
|
.merge-header {
|
margin-bottom: 20px;
|
}
|
|
.merge-content {
|
flex: 1;
|
overflow-y: auto;
|
}
|
|
.question-list {
|
padding: 10px;
|
}
|
|
/* 与父组件一致的题目样式 */
|
.scriptTopic-dev {
|
margin-bottom: 20px;
|
padding: 15px;
|
border: 1px solid #ebeef5;
|
border-radius: 4px;
|
}
|
|
.scriptTopic-isabnormal {
|
margin-bottom: 20px;
|
padding: 15px;
|
border: 1px solid #f56c6c;
|
border-radius: 4px;
|
background-color: #fff6f6;
|
}
|
|
.dev-text {
|
font-size: 16px;
|
margin-bottom: 15px;
|
color: #333;
|
}
|
|
.dev-xx {
|
margin-left: 20px;
|
}
|
|
.append-input-container {
|
margin-top: 15px;
|
}
|
|
.red-star {
|
color: #f56c6c;
|
}
|
|
.merge-footer {
|
margin-top: 20px;
|
text-align: right;
|
padding-top: 15px;
|
border-top: 1px solid #ebeef5;
|
}
|
</style>
|