提交
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
"
|
||||
:visible.sync="dialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
:wrapperClosable="false"
|
||||
:wrapperClosable="true"
|
||||
:before-close="handleClose"
|
||||
custom-class="yianDrawer"
|
||||
size="1200px"
|
||||
>
|
||||
@@ -60,23 +61,34 @@
|
||||
<div
|
||||
v-for="(v, i) in messageList"
|
||||
class="wordItem"
|
||||
@click="insertMessage(v)"
|
||||
@click="insertMessage(v.text, v.images ? v.images : [])"
|
||||
style="width: 32%;margin-right: 15px;margin-bottom: 10px;cursor: pointer;"
|
||||
>
|
||||
<div
|
||||
style="border: 1px solid #bbb;border-radius: 8px;height: 88px;overflow: hidden;"
|
||||
style="border: 1px solid #bbb;border-radius: 8px;height: 110px;overflow: hidden;"
|
||||
>
|
||||
<p
|
||||
style="font-weight: bold;margin-bottom:2px;margin-top: -1px;background-color: #f0f0f0;color: #333;padding: 2px 10px 2px 2px;"
|
||||
>
|
||||
【医案 {{ numberToChineseLower(i + 1) }}】
|
||||
<el-button
|
||||
@click.stop="
|
||||
analyzingMessage(v.text, v.images ? v.images : [])
|
||||
"
|
||||
size="mini"
|
||||
type=""
|
||||
plain
|
||||
style="margin-left: 10px; padding: 2px;float: right;color: rgb(23, 129, 255);"
|
||||
>解析医案</el-button
|
||||
>
|
||||
<el-button
|
||||
@click.stop="insertMessage(v.text, v.images ? v.images : [])"
|
||||
size="mini"
|
||||
type=""
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
style="margin-left: 10px; padding: 2px;float: right;"
|
||||
>快速填入</el-button
|
||||
>选择</el-button
|
||||
>
|
||||
</p>
|
||||
<div
|
||||
@@ -89,7 +101,16 @@
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-word; /* 可选:精确限制高度,兼容性更好 */"
|
||||
>
|
||||
{{ v }}
|
||||
{{ v.text }}
|
||||
</div>
|
||||
|
||||
<div v-if="v.images" style="padding:0px 10px 0;">
|
||||
<img
|
||||
v-for="(img, i) in v.images"
|
||||
:key="i"
|
||||
:src="img"
|
||||
style="width:30px;height: 30px; margin: 4px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -157,7 +178,7 @@
|
||||
v-if="tishi"
|
||||
:title="
|
||||
loading
|
||||
? '解析预计耗时约50秒,请耐心等待'
|
||||
? '解析预计耗时约50秒,请耐心等待,也可在草稿箱中查看内容'
|
||||
: '好的,结合您的医案,下面是解析后的结果。5秒后自动关闭'
|
||||
"
|
||||
:type="loading ? 'warning' : 'success'"
|
||||
@@ -243,7 +264,10 @@
|
||||
>
|
||||
</div>
|
||||
<template
|
||||
v-if="type == 'detail' && currentNode.data.id == 'wait'"
|
||||
v-if="
|
||||
(type == 'detail' && currentNode.data.id == 'wait') ||
|
||||
currentNode.data.id == 'caogao'
|
||||
"
|
||||
style="display:flex;align-items:center;justify-content:space-between"
|
||||
>
|
||||
<!-- <el-form-item
|
||||
@@ -273,7 +297,6 @@
|
||||
<div>
|
||||
<el-cascader
|
||||
size="mini"
|
||||
:disabled="isEdit"
|
||||
style="width: 100%;"
|
||||
:show-all-levels="false"
|
||||
v-model="addCertificateForm.labelId"
|
||||
@@ -281,7 +304,9 @@
|
||||
value: 'id',
|
||||
label: 'title'
|
||||
}"
|
||||
filterable
|
||||
:options="cateOptions"
|
||||
@change="selectLabelId"
|
||||
placeholder="医案分类"
|
||||
></el-cascader></div
|
||||
></el-form-item>
|
||||
@@ -330,7 +355,6 @@
|
||||
<el-form-item
|
||||
label="医案详情:"
|
||||
label-width="110px"
|
||||
|
||||
class="form_item"
|
||||
>
|
||||
<div style="padding-top: 15px;">
|
||||
@@ -377,7 +401,6 @@
|
||||
|
||||
<el-form-item
|
||||
label="上传图片:"
|
||||
|
||||
label-width="110px"
|
||||
class="form_item custom-upload-box"
|
||||
v-if="dialogVisible"
|
||||
@@ -438,23 +461,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-upload>
|
||||
<template v-if="addCertificateForm.img !== ''&&type == 'detail'">
|
||||
<el-image
|
||||
v-if="
|
||||
|
||||
fileList.length > 0
|
||||
|
||||
"
|
||||
:key="index"
|
||||
class="el-upload-list__item-thumbnail"
|
||||
v-for="(item, index) in addCertificateForm.img.split(',')"
|
||||
style="width: 60px;height: 60px;border-radius: 6px;margin: 0 8px 8px 0;"
|
||||
:src="item"
|
||||
:preview-src-list="addCertificateForm.img.split(',')"
|
||||
<template
|
||||
v-if="addCertificateForm.img !== '' && type == 'detail'"
|
||||
>
|
||||
</el-image>
|
||||
<el-image
|
||||
v-if="fileList.length > 0"
|
||||
:key="index"
|
||||
class="el-upload-list__item-thumbnail"
|
||||
v-for="(item, index) in addCertificateForm.img.split(',')"
|
||||
style="width: 60px;height: 60px;border-radius: 6px;margin: 0 8px 8px 0;"
|
||||
:src="item"
|
||||
:preview-src-list="addCertificateForm.img.split(',')"
|
||||
>
|
||||
</el-image>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- <div class="flexBox" style="width:100%;justify-content: space-between;">
|
||||
<div class="" style="display:flex">
|
||||
@@ -613,10 +633,13 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
isShowWord: false,
|
||||
imagePreviews: false,
|
||||
record: {},
|
||||
loading: false,
|
||||
tishi: false,
|
||||
message: "",
|
||||
currentMedicalWordImageList: [],
|
||||
currentMedicalWordImageStr: "",
|
||||
messageList: [],
|
||||
showMessages: false,
|
||||
editableMap: {}, // 存储每个字段的内部可编辑内容
|
||||
@@ -684,6 +707,7 @@ export default {
|
||||
addForm: {},
|
||||
audioFileList: [],
|
||||
isFresh: false,
|
||||
pollInterval: null,
|
||||
type: "",
|
||||
detailContent: "",
|
||||
medicalId: "",
|
||||
@@ -698,6 +722,7 @@ export default {
|
||||
commonShopTable,
|
||||
quillEditor
|
||||
},
|
||||
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
@@ -712,6 +737,30 @@ export default {
|
||||
// this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
selectLabelId(value) {
|
||||
// value 是选中的 id 数组
|
||||
const getTitle = (options, valuePath) => {
|
||||
let currentOptions = options;
|
||||
let labels = [];
|
||||
|
||||
for (let val of valuePath) {
|
||||
const selected = currentOptions.find(item => item.id === val);
|
||||
if (selected) {
|
||||
labels.push(selected.title);
|
||||
currentOptions = selected.children || [];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
};
|
||||
|
||||
// 获取选中的 title 路径
|
||||
const titles = getTitle(this.cateOptions, value);
|
||||
console.log("当前选中的 title 是:", titles[titles.length - 1]); // 如果只要最后一级
|
||||
this.addCertificateForm.labelTitle = titles[titles.length - 1];
|
||||
},
|
||||
numberToChineseLower(n) {
|
||||
const cnNums = [
|
||||
"零",
|
||||
@@ -743,10 +792,20 @@ export default {
|
||||
result = result.replace(/^一十/, "十"); // 10-19 处理为 十一、十二...
|
||||
return result;
|
||||
},
|
||||
insertMessage(data) {
|
||||
insertMessage(data, images) {
|
||||
this.message = "";
|
||||
this.currentMedicalWordImageList = [];
|
||||
this.currentMedicalWordImageStr = "";
|
||||
this.message = data;
|
||||
if (images.length > 0) {
|
||||
this.currentMedicalWordImageList = [...images];
|
||||
}
|
||||
console.log("this.message at line 650:", this.message);
|
||||
},
|
||||
async analyzingMessage(data, images) {
|
||||
await this.insertMessage(data, images);
|
||||
await this.submit()
|
||||
},
|
||||
// 点击按钮触发上传
|
||||
triggerUpload() {
|
||||
this.messageList = [];
|
||||
@@ -756,19 +815,22 @@ export default {
|
||||
|
||||
// 处理上传文件
|
||||
handleUpload(event) {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'word文件识别中',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
|
||||
this.$commonJS.handleUpload(event, arr => {
|
||||
console.log("content at line 618:", arr);
|
||||
// const text = html
|
||||
// .replace(/<[^>]+>/g, '') // 清除所有 HTML 标签
|
||||
// .replace(/ /g, ' ') // 替换空格实体
|
||||
// .replace(/</g, '<') // 还原小于号
|
||||
// .replace(/>/g, '>') // 还原大于号
|
||||
// .replace(/&/g, '&') // 还原 &
|
||||
// .replace(/\r?\n\s*\r?\n/g, '\n') // 去掉多余空行
|
||||
|
||||
|
||||
this.messageList = arr;
|
||||
|
||||
// document.getElementById("result").innerHTML = content
|
||||
|
||||
loading.close();
|
||||
}).catch(()=>{
|
||||
loading.close();
|
||||
});
|
||||
},
|
||||
beforeClose() {
|
||||
@@ -887,6 +949,8 @@ export default {
|
||||
init(type, data) {
|
||||
this.showMessages = false;
|
||||
this.messageList = [];
|
||||
this.currentMedicalWordImageList = [];
|
||||
this.currentMedicalWordImageStr = "";
|
||||
this.message = "";
|
||||
this.tishi = false;
|
||||
this.loading = false;
|
||||
@@ -900,10 +964,11 @@ export default {
|
||||
chiefComplaint: "<h1>主诉</h1>",
|
||||
historyOfPresentIllness: "<h1>现病史</h1>",
|
||||
pastHistory: "<h1>既往史</h1>",
|
||||
personalAndFamilyHistory: "<h1>家族史</h1>",
|
||||
personalAndFamilyHistory: "<h1>个人史与家族史</h1>",
|
||||
physicaExamination: "<h1>体格检查</h1>",
|
||||
diagnosis: "<h1>诊断</h1>",
|
||||
treatmentPlan: "<h1>治疗和后续治疗</h1>"
|
||||
treatmentPlan: "<h1>治疗和后续治疗</h1>",
|
||||
treatmentPlan: "<h1>其他</h1>"
|
||||
};
|
||||
this.isEdit = type == "edit" || type == "add" ? true : false;
|
||||
if (type == "add") {
|
||||
@@ -1047,35 +1112,96 @@ export default {
|
||||
this.reviewType = type;
|
||||
this.dialogMarkVisible = true;
|
||||
},
|
||||
async uploadImage(base64Images) {
|
||||
const uploadTasks = base64Images.map((base64, index) => {
|
||||
const formData = new FormData();
|
||||
const blob = this.$commonJS.base64ToBlob(base64);
|
||||
formData.append("file", blob, `image-${index + 1}.png`);
|
||||
|
||||
submit() {
|
||||
return fetch(this.baseUrl + "/oss/fileoss", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
console.log(`✅ 第 ${index + 1} 张上传完成`, data);
|
||||
if (data.code === 0 && data.url) {
|
||||
return data.url;
|
||||
} else {
|
||||
console.warn(`❌ 第 ${index + 1} 张上传失败`);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(`❌ 第 ${index + 1} 张上传失败`, err);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
// 🚀 等待所有任务并发完成
|
||||
const results = await Promise.all(uploadTasks);
|
||||
const urlList = results.filter(Boolean); // 去掉失败的 null
|
||||
|
||||
const urlString = urlList.join(",");
|
||||
console.log("✅ 所有上传完成,URL 字符串:", urlString);
|
||||
|
||||
return urlString;
|
||||
},
|
||||
|
||||
async submit() {
|
||||
//没有次数的时候要求购买vip
|
||||
if (!this.message) {
|
||||
this.$message.error("请输入医案详情");
|
||||
return;
|
||||
}
|
||||
this.createChat()
|
||||
|
||||
if (this.currentMedicalWordImageList.length > 0) {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'loading',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
this.currentMedicalWordImageStr = await this.uploadImage(
|
||||
this.currentMedicalWordImageList
|
||||
);
|
||||
console.log(
|
||||
"this.currentMedicalWordImageStr at line 1139:",
|
||||
this.currentMedicalWordImageStr
|
||||
);
|
||||
loading.close();
|
||||
}
|
||||
|
||||
await this.createChat();
|
||||
|
||||
//创建对话 获取sessionId
|
||||
|
||||
},
|
||||
//创建新对话
|
||||
createChat() {
|
||||
this.loading = true;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/common/medicalRecords/medicalRecordsSplit"),
|
||||
method: "post",
|
||||
data: this.$http.adornData({
|
||||
userId: "1",
|
||||
message: this.message
|
||||
userId: "12301",
|
||||
message: this.message,
|
||||
img: this.currentMedicalWordImageStr
|
||||
})
|
||||
}).then(res => {
|
||||
console.log("res at line 872:", res);
|
||||
if (res.data.code == 0) {
|
||||
this.medicalId = res.data.data;
|
||||
})
|
||||
.then(res => {
|
||||
console.log("res at line 872:", res);
|
||||
if (res.data.code == 0) {
|
||||
this.medicalId = res.data.data;
|
||||
|
||||
this.sendQuestion();
|
||||
}
|
||||
});
|
||||
this.sendQuestion();
|
||||
} else {
|
||||
this.loading = false;
|
||||
this.$message.error("请重新解析");
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
this.$message.error("请重新解析");
|
||||
});
|
||||
},
|
||||
|
||||
//交谈请求,获取回答
|
||||
@@ -1085,7 +1211,6 @@ export default {
|
||||
|
||||
this.showMessages = true;
|
||||
|
||||
this.loading = true;
|
||||
var that = this;
|
||||
//展示提示语
|
||||
this.tishi = true;
|
||||
@@ -1094,14 +1219,15 @@ export default {
|
||||
const poll = () => {
|
||||
this.getMedicalDetail(() => {
|
||||
// 停止轮询
|
||||
clearInterval(pollInterval);
|
||||
clearInterval(this.pollInterval);
|
||||
this.pollInterval = null;
|
||||
setTimeout(() => {
|
||||
this.tishi = false;
|
||||
}, 5000);
|
||||
});
|
||||
};
|
||||
// 每5秒发送一次请求,直到收到正确的响应
|
||||
const pollInterval = setInterval(poll, 5000);
|
||||
this.pollInterval = setInterval(poll, 5000);
|
||||
|
||||
//调用后端 SSE 接口,发送问题并接收实时回答
|
||||
// this.startSSE(params);
|
||||
@@ -1119,6 +1245,18 @@ export default {
|
||||
})
|
||||
|
||||
.then(res => {
|
||||
if (
|
||||
res.data.code == 0 &&
|
||||
res.data.medicalRecords != null &&
|
||||
res.data.medicalRecords.delFlag == -1
|
||||
) {
|
||||
this.$message.error("此医案解析失败,请重新解析");
|
||||
this.showMessages = true;
|
||||
if (fn) {
|
||||
fn();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
res.data.code == 0 &&
|
||||
res.data.medicalRecords != null &&
|
||||
@@ -1163,6 +1301,22 @@ export default {
|
||||
// this.$refs.commonMedicalDetail.initRecordData(this.medicalRecords);
|
||||
// that.initRecordData();
|
||||
console.log("at line 558:", this.record);
|
||||
this.addCertificateForm.id = data.id;
|
||||
this.addCertificateForm.img = data.img;
|
||||
if (this.addCertificateForm.img) {
|
||||
this.fileList = this.addCertificateForm.img
|
||||
.split(",")
|
||||
.map((image, i) => ({
|
||||
uid: i, // 假设 id 是唯一标识符
|
||||
name: i, // 文件名
|
||||
status: "done", // 状态
|
||||
url: image // 文件 URL
|
||||
}));
|
||||
console.log("this.fileList at line 308:", this.fileList);
|
||||
this.addCertificateForm.imageList = this.addCertificateForm.img.split(
|
||||
","
|
||||
);
|
||||
}
|
||||
this.$forceUpdate();
|
||||
|
||||
// 滚动到最底部锚点
|
||||
@@ -1192,6 +1346,7 @@ export default {
|
||||
this.$message.error("请选择用户");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.editableMap.chiefComplaint == "") {
|
||||
const titleHtml = this.getTitleHtml(
|
||||
this.record["chiefComplaint"]
|
||||
@@ -1220,6 +1375,49 @@ export default {
|
||||
this.$message.error("请输入 " + titleHtml);
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
["妇科", "儿科"].includes(this.currentNode.data.title) ||
|
||||
["妇科", "儿科"].includes(this.addCertificateForm.labelTitle)
|
||||
) {
|
||||
if (
|
||||
this.currentNode.data.title == "妇科" ||
|
||||
this.addCertificateForm.labelTitle == "妇科"
|
||||
) {
|
||||
const value = this.editableMap["personalAndFamilyHistory"] || "";
|
||||
const hasKeywords =
|
||||
value.includes("月经") && value.includes("婚育");
|
||||
|
||||
if (!hasKeywords) {
|
||||
// 包含“月经”或“婚育”
|
||||
console.log("包含月经或婚育相关内容");
|
||||
const titleHtml = this.getTitleHtml(
|
||||
this.record["personalAndFamilyHistory"]
|
||||
).replace(/<[^>]*>/g, "");
|
||||
this.$message.error(
|
||||
"请在 " + titleHtml + " 中输入月经或婚育相关内容"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (
|
||||
this.currentNode.data.title == "儿科" ||
|
||||
this.addCertificateForm.labelTitle == "儿科"
|
||||
) {
|
||||
const value = this.editableMap["pastHistory"] || "";
|
||||
const hasKeywords = value.includes("疫苗");
|
||||
if (!hasKeywords) {
|
||||
// 包含“月经”或“婚育”
|
||||
console.log("疫苗");
|
||||
const titleHtml = this.getTitleHtml(
|
||||
this.record["pastHistory"]
|
||||
).replace(/<[^>]*>/g, "");
|
||||
this.$message.error(
|
||||
"请在 " + titleHtml + " 中输入疫苗接种相关内容"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
var recordData = { ...this.record };
|
||||
for (const key in recordData) {
|
||||
const titleHtml = this.getTitleHtml(recordData[key]);
|
||||
@@ -1234,29 +1432,52 @@ export default {
|
||||
userId: this.addCertificateForm.userId,
|
||||
...recordData
|
||||
};
|
||||
|
||||
if (this.currentNode.data.id == "caogao") {
|
||||
const label = this.addCertificateForm.labelId;
|
||||
console.log(
|
||||
"this.addCertificateForm at line 1286:",
|
||||
this.addCertificateForm
|
||||
);
|
||||
const value = Array.isArray(label)
|
||||
? label[label.length - 1]
|
||||
: label;
|
||||
console.log("value at line 1289:", value);
|
||||
if (!value) {
|
||||
this.$message.error("请选择医案分类");
|
||||
return false;
|
||||
}
|
||||
data = {
|
||||
...this.addCertificateForm,
|
||||
...data,
|
||||
labelId: value,
|
||||
state: 3
|
||||
};
|
||||
console.log("data at line 1288:", data);
|
||||
} else {
|
||||
if (this.type == "edit") {
|
||||
data = {
|
||||
...data,
|
||||
data: this.addCertificateForm.data
|
||||
? this.addCertificateForm.data
|
||||
: "",
|
||||
id: this.addCertificateForm.id
|
||||
};
|
||||
} else {
|
||||
data = {
|
||||
...data,
|
||||
labelId: this.labelId
|
||||
};
|
||||
}
|
||||
}
|
||||
// if(this.record.)
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
this.type == "edit"
|
||||
this.type == "edit" || this.currentNode.data.id == "caogao"
|
||||
? "/master/medicalRecords/editMedicalRecords"
|
||||
: "/master/medicalRecords/addMedicalRecords"
|
||||
),
|
||||
method: "post",
|
||||
data: this.$http.adornData(
|
||||
this.type == "edit"
|
||||
? {
|
||||
...data,
|
||||
data: this.addCertificateForm.data
|
||||
? this.addCertificateForm.data
|
||||
: "",
|
||||
id: this.addCertificateForm.id
|
||||
}
|
||||
: {
|
||||
...data,
|
||||
labelId: this.labelId
|
||||
}
|
||||
)
|
||||
data: this.$http.adornData({ ...data })
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
@@ -1315,7 +1536,14 @@ export default {
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
// 图片预览逻辑
|
||||
},
|
||||
handleClose(done) {
|
||||
done();
|
||||
this.$emit("refresh");
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.pollInterval);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user