|
|
@ -90,9 +90,10 @@ |
|
|
style="font-size: 24px;color: red;cursor:pointer;"></i> |
|
|
style="font-size: 24px;color: red;cursor:pointer;"></i> |
|
|
</el-tooltip> |
|
|
</el-tooltip> |
|
|
</div> |
|
|
</div> |
|
|
<el-input v-show="AI.max" type="textarea" v-model="AI.diagnosis" placeholder="AI诊断内容" |
|
|
|
|
|
|
|
|
<!-- <el-input v-show="AI.max" type="textarea" v-model="AI.diagnosis" placeholder="AI诊断内容" |
|
|
:autosize="{ minRows: AIDH, maxRows: AIDH }" style="text-align: right;"> |
|
|
:autosize="{ minRows: AIDH, maxRows: AIDH }" style="text-align: right;"> |
|
|
</el-input> |
|
|
|
|
|
|
|
|
</el-input> --> |
|
|
|
|
|
<div ref="aiContent" v-html="AI.html" :style="`height:${AI.height - 42 - 48}px;overflow-y: auto;display: blockresize:vertical;padding: 5px 5px 5px 20px;line-height: 1.5;box-sizing: border-box;width: 100%;font-size: inherit;background-color: #fff;background-image: none;border: 1px solid #dcdfe6;border-radius: 4px;transition: border-color .2s cubic-bezier(.645, .045, .355, 1);`"></div> |
|
|
<div v-show="AI.max" style="text-align: right; margin-top: 10px;"> |
|
|
<div v-show="AI.max" style="text-align: right; margin-top: 10px;"> |
|
|
<el-button class="commonbutton" @click="AI.visible = false">关闭</el-button> |
|
|
<el-button class="commonbutton" @click="AI.visible = false">关闭</el-button> |
|
|
<el-button class="commonbutton" @click="btnAIdiagnosis(true)">AI重新诊断</el-button> |
|
|
<el-button class="commonbutton" @click="btnAIdiagnosis(true)">AI重新诊断</el-button> |
|
|
@ -136,6 +137,8 @@ import SumDiagnosis from "./SumDiagnosis.vue"; |
|
|
import OccDisease from "../../components/occDisease/OccDisease.vue" |
|
|
import OccDisease from "../../components/occDisease/OccDisease.vue" |
|
|
import moment from "moment"; |
|
|
import moment from "moment"; |
|
|
|
|
|
|
|
|
|
|
|
import MarkdownIt from "markdown-it"; |
|
|
|
|
|
const md = new MarkdownIt(); |
|
|
export default { |
|
|
export default { |
|
|
components: { |
|
|
components: { |
|
|
PatientRegisterList, |
|
|
PatientRegisterList, |
|
|
@ -163,7 +166,11 @@ export default { |
|
|
max: true, |
|
|
max: true, |
|
|
visible: false, |
|
|
visible: false, |
|
|
diagnosis: 'AI诊断信息', |
|
|
diagnosis: 'AI诊断信息', |
|
|
} |
|
|
|
|
|
|
|
|
rawText: "", // 原始 markdown 内容(流式累加) |
|
|
|
|
|
html: "", // 渲染后的 HTML(逐字更新) |
|
|
|
|
|
typingIndex: 0, |
|
|
|
|
|
typingTimer: null |
|
|
|
|
|
}, |
|
|
}; |
|
|
}; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
@ -458,15 +465,34 @@ export default { |
|
|
message = '性别:' + this.doctorCheck.prBase.sexName + ',年龄:' + this.doctorCheck.prBase.age + '岁,检查结果:' + message |
|
|
message = '性别:' + this.doctorCheck.prBase.sexName + ',年龄:' + this.doctorCheck.prBase.age + '岁,检查结果:' + message |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
postapi('/api/app/AIMessage/GetAIMessageResult', { message }) |
|
|
|
|
|
|
|
|
// postapi('/api/app/AIMessage/GetAIMessageResult', { message }) |
|
|
|
|
|
// .then(res => { |
|
|
|
|
|
// if (res.code > -1) { |
|
|
|
|
|
// this.AI.visible = true |
|
|
|
|
|
// this.AI.diagnosis = res.data.result |
|
|
|
|
|
// this.btnAImax(false) |
|
|
|
|
|
// } else { |
|
|
|
|
|
// this.$message.error({ showClose: true, message: res.message }) |
|
|
|
|
|
// } |
|
|
|
|
|
// }) |
|
|
|
|
|
|
|
|
|
|
|
postapi('/api/app/AiMessageWs/GetAIMessageResult', { message }) |
|
|
.then(res => { |
|
|
.then(res => { |
|
|
if (res.code > -1) { |
|
|
|
|
|
this.AI.visible = true |
|
|
|
|
|
this.AI.diagnosis = res.data.result |
|
|
|
|
|
this.btnAImax(false) |
|
|
|
|
|
} else { |
|
|
|
|
|
this.$message.error({ showClose: true, message: res.message }) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!res) return; |
|
|
|
|
|
// 移除流结束标志并去掉每行的 'data: ' 前缀 |
|
|
|
|
|
let cleaned = String(res) |
|
|
|
|
|
.replace(/data:\s*\[DONE\]/g, '') |
|
|
|
|
|
.replace(/^data:\s*/gm, '') |
|
|
|
|
|
.trim(); |
|
|
|
|
|
if (!cleaned) return; |
|
|
|
|
|
this.AI.typingIndex = 0; |
|
|
|
|
|
this.AI.visible = true; |
|
|
|
|
|
this.AI.rawText = cleaned; |
|
|
|
|
|
// 确保 typingIndex 在合理范围 |
|
|
|
|
|
if (!this.AI.typingIndex || this.AI.typingIndex < 0) this.AI.typingIndex = 0; |
|
|
|
|
|
if (this.AI.typingIndex > this.AI.rawText.length) this.AI.typingIndex = 0; |
|
|
|
|
|
this.startTyping(); |
|
|
|
|
|
this.btnAImax(false); |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
}, |
|
|
}, |
|
|
@ -481,7 +507,30 @@ export default { |
|
|
this.AI.height = 24 |
|
|
this.AI.height = 24 |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
startTyping() { |
|
|
|
|
|
if (this.AI.typingTimer) clearInterval(this.AI.typingTimer); |
|
|
|
|
|
|
|
|
|
|
|
this.AI.typingTimer = setInterval(() => { |
|
|
|
|
|
if (this.AI.typingIndex < this.AI.rawText.length) { |
|
|
|
|
|
const current = this.AI.rawText.slice(0, this.AI.typingIndex); |
|
|
|
|
|
this.AI.html = md.render(current); |
|
|
|
|
|
this.AI.typingIndex++; |
|
|
|
|
|
// 每次更新后滚动到容器底部,确保最新输出可见 |
|
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
|
try { |
|
|
|
|
|
const el = this.$refs.aiContent; |
|
|
|
|
|
if (el) { |
|
|
|
|
|
el.scrollTop = el.scrollHeight; |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
// ignore |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} else { |
|
|
|
|
|
clearInterval(this.AI.typingTimer); |
|
|
|
|
|
} |
|
|
|
|
|
}, 30); // 每 30ms 打一个字 |
|
|
|
|
|
}, |
|
|
//审核 |
|
|
//审核 |
|
|
audit() { |
|
|
audit() { |
|
|
// dataTransOpts.tableS.patient_register.summaryDoctorId |
|
|
// dataTransOpts.tableS.patient_register.summaryDoctorId |
|
|
|