Files
taimed/pages/medicalRecords/medical.vue
liuyuan 565f61f29c tijiao
2025-07-24 17:48:32 +08:00

1866 lines
44 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view
class="content"
:class="`${options.type == 'detail' ? 'content_detail' : ''}`"
>
<z-nav-bar
:title="options.navTitle"
bgColor="#5188e5"
fontColor="#fff"
v-if="options.type != 'detail' && !options.page"
>
</z-nav-bar>
<z-nav-bar
:title="options.navTitle"
bgColor="#5188e5"
fontColor="#fff"
v-else-if="options.page == 'talents'"
>
</z-nav-bar>
<z-nav-bar
:title="options.navTitle"
bgColor="#fff"
fontColor="#000"
v-if="options.type == 'detail' && !options.page"
>
</z-nav-bar>
<view class="home_wrap home_wrap_analysis" v-if="!showMessages">
<view class="home_form" style="position: relative">
<view
class="form_item"
style="
display: flex;
align-items: flex-start;
justify-content: space-between;
"
>
<!-- <text>医案信息</text> -->
<!-- 固定标题和输入框部分 -->
<view class="analysis_box">
<view class="analysis_title">
<image
src="../../static/icon/icon_analysis.png"
style="
width: 50rpx;
height: 50rpx;
margin-right: 10rpx;
margin-top: 10rpx;
"
></image>
智能分析医案
</view>
<!-- 固定的输入框部分 -->
<view style="height: calc(100% - 120rpx)">
<textarea
v-model="formData.message"
maxlength="-1"
style="
min-height: calc(85vh - 360rpx) !important;
width: 100%;
max-height: calc(85vh - 360rpx) !important;
"
auto-height
placeholder="请输入医案到此处,将自动解析医案信息
例:
基本信息太湖65岁
首诊2023-04-26
主诉:发现...."
placeholder-class="custom-placeholder"
></textarea>
</view>
</view>
<view class="submit_btn" @click="submit">解析医案</view>
</view>
</view>
<!-- 搜索结果列表 -->
<scroll-view
scroll-y
class="result-list"
v-if="searchResultStatus && searchResults.length > 0"
>
<view
v-for="item in searchResults"
:key="item.id"
@click="selectItem(item)"
class="result-item"
>
{{ item.name }}
</view>
</scroll-view>
</view>
<view
class="message_wrap"
:class="`${options.type == 'detail' ? 'message_wrap_detail' : ''}`"
:style="`top: 1px;height:${
options.statusId == 1 || options.statusId == 3 ? '92vh' : '85vh'
}`"
v-if="showMessages"
>
<text class="message_title" v-if="tishi">{{
loading
? "解析预计耗时约50秒,请稍后查看草稿箱中的内容"
: "好的结合您的医案下面是解析后的结果"
}}</text>
<!-- 显示聊天记录 -->
<medicalDetail
:loading="loading"
:type="options.type"
:page="options.page ? options.page : ''"
:statusId="options.statusId"
:medicalRecords="medicalRecords"
@editableMap="updateEditableMap"
@formData="updateMedicalForm"
@record="updateRecord"
@fileList1="updateFileList1"
ref="commonMedicalDetail"
></medicalDetail>
<view
class="footer_box"
v-if="!loading && ['add', 'edit'].includes(options.type)"
>
<template v-if="options.statusId == 0 || !options.statusId">
<view class="footer_item">
<view class="button savebutton" @click="handleSubmit('save')"
>暂存草稿箱</view
>
</view>
<view class="footer_item"
><view class="button" @click="handleSubmit('submit')"
>提交审核</view
></view
>
</template>
</view>
<view
class="footer_box"
v-if="
!loading && ['detail'].includes(options.type) && options.statusId == 2
"
>
<template>
<view class="footer_item">
<view
class="button savebutton"
style="background-color: #fff; font-size: 30rpx"
@click="handleSubmit('save', 1)"
>修改医案</view
>
</view>
<!-- <view class="footer_item"
></view
> -->
</template>
</view>
</view>
<!-- <z-navigation></z-navigation> -->
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
import { mapState, mapMutations } from "vuex";
import medicalDetail from "./medicalDetail.vue";
import qs from "qs";
export default {
components: {
medicalDetail,
},
data() {
return {
options: {},
fileList1: [],
containerHeight: null,
formData: {
message: "",
},
medicalForm: {},
chatId: null, //选择助手的id
chatName: "",
chatAssistants: [],
activeIndex: null,
sessionId: "", //对话id
medicalId: "", //医案id
eventSource: null,
showMessages: false,
loading: true,
question: "", //传递的问题
messages: [],
record: [],
previousAnswer: null, //存储上一条回答内容
question_send: "",
pauseStatus: false, //暂停操作
record_list: [], //对话列表
null_text: "",
activeRecord: null,
tishi: false, //提示语
folderList: [], //病历夹列表
folderName: "", //病历夹名称
chatAssistantName: "",
patientName: "",
pageData: {},
pageType: "", //从患者列表过来的type
isChecked: true,
medicalRecords: [], //模糊已选项
selectedItems: [], //模糊已选项
selectedId: [],
searchResults: [], //模糊搜索结果
searchResultStatus: false,
vipCount: null,
vipText: "",
vipStatus: null,
freeCount: null,
freeText: "",
freeStatus: null,
flag: null,
scrollIntoView: "",
recordData: {},
editableMap: {},
isRefreshing: false, //刷新状态
};
},
computed: {
...mapState(["userInfo"]),
},
async onLoad(options) {
this.options = options;
this.medicalId = options.id;
if (this.options.type == "add") {
this.showMessages = false;
this.loading = true;
} else {
this.showMessages = true;
this.loading = true;
await this.getMedicalDetail(() => {
this.medicalForm = { ...this.medicalRecords };
console.log("this.medicalForm at line 193:", this.medicalForm);
if (this.medicalRecords.img) {
this.$refs.commonMedicalDetail.fileList1 = this.medicalRecords.img
.split(",")
.map((image, i) => ({
uid: i, // 假设 id 是唯一标识符
name: i, // 文件名
status: "done", // 状态
url: image, // 文件 URL
}));
}
});
// this.tishi=true
}
uni.hideTabBar();
uni.removeStorageSync("homeParams");
//获取设备信息
const systemInfo = uni.getSystemInfoSync();
this.containerHeight = systemInfo.windowHeight; //获取设备的窗口高度
// this.sendQuestion();
},
onShow() {
// console.log('进入到onShow方法')
// this.activeRecord = null;
// this.getRecordsData();
// this.getUserAiVipCount(); //更新次数
// //我的-会话记录跳转来的
// this.pageData = uni.getStorageSync('homeParams').data;
// this.pageType = uni.getStorageSync('homeParams').type;
// let index = uni.getStorageSync('homeParams').index;
// if(this.pageData&&!this.pageType){
// this.clickRecord(this.pageData, index);
// }
},
async onPullDownRefresh() {
this.isRefreshing = true;
console.log("下拉刷新");
setTimeout(async() => {
if (this.options.type == "add") {
this.showMessages = false;
this.loading = true;
} else {
this.showMessages = true;
this.loading = true;
await this.getMedicalDetail(() => {
this.medicalForm = { ...this.medicalRecords };
console.log("this.medicalForm at line 193:", this.medicalForm);
if (this.medicalRecords.img) {
this.$refs.commonMedicalDetail.fileList1 = this.medicalRecords.img
.split(",")
.map((image, i) => ({
uid: i, // 假设 id 是唯一标识符
name: i, // 文件名
status: "done", // 状态
url: image, // 文件 URL
}));
}
});
// this.tishi=true
}
uni.stopPullDownRefresh();
this.isRefreshing = false;
console.log("下拉刷新已停止");
}, 800);
},
methods: {
//更新子组件内容
updateEditableMap(val) {
this.editableMap = val;
},
updateMedicalForm(val) {
console.log("val at line 232:", val);
this.medicalForm = val;
},
updateRecord(val) {
this.record = val;
},
updateFileList1(val) {
this.fileList1 = val;
},
handleSubmit(type, isNewSave) {
console.log(
"this.editableMap at line 243:",
this.editableMap,
this.medicalForm
);
if (!this.medicalForm.title) {
this.$commonJS.showToast("请输入医案标题");
return;
}
if (!this.medicalForm.labelId) {
this.$commonJS.showToast("请选择医案分类");
return;
}
if (type == "submit") {
if (this.editableMap.chiefComplaint == "") {
const titleHtml = this.getTitleHtml(
this.record["chiefComplaint"]
).replace(/<[^>]*>/g, "");
this.$commonJS.showToast("请输入 " + titleHtml);
return false;
}
if (this.editableMap.historyOfPresentIllness == "") {
const titleHtml = this.getTitleHtml(
this.record["historyOfPresentIllness"]
).replace(/<[^>]*>/g, "");
this.$commonJS.showToast("请输入 " + titleHtml);
return false;
}
if (this.editableMap.physicaExamination == "") {
const titleHtml = this.getTitleHtml(
this.record["physicaExamination"]
).replace(/<[^>]*>/g, "");
this.$commonJS.showToast("请输入 " + titleHtml);
return false;
}
if (this.editableMap.treatmentPlan == "") {
const titleHtml = this.getTitleHtml(
this.record["treatmentPlan"]
).replace(/<[^>]*>/g, "");
this.$commonJS.showToast("请输入 " + titleHtml);
return false;
}
}
var recordData = { ...this.record };
for (const key in recordData) {
const titleHtml = this.getTitleHtml(recordData[key]);
recordData[key] = titleHtml + this.editableMap[key];
}
var data = {
img:
this.fileList1.length > 0
? this.fileList1.map((e) => e.url).toString()
: "",
title: this.medicalForm.title ? this.medicalForm.title : "",
labelId: this.medicalForm.labelId ? this.medicalForm.labelId : "",
labelTitle: this.medicalForm.labelTitle
? this.medicalForm.labelTitle
: "",
state: type == "submit" ? 1 : 0,
...recordData,
};
if (this.medicalId) {
data.id = this.medicalId;
}
this.$http
.request({
url: "common/medicalRecords/saveMedicalRecords",
method: "POST",
data: {
...data,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
console.log("res.code at line 434:", res.code);
if (isNewSave == 1) {
uni.redirectTo({
url: `/pages/medicalRecords/medical?navTitle=编辑医案&title=编辑医案&id=${this.medicalId}&type=edit&statusId=0`,
});
} else {
uni.redirectTo({
url: "/pages/medicalRecords/index",
});
}
} else {
this.$commonJS.showToast(res.msg);
}
})
.catch((err) => {});
},
// 判断内容是否为空或无效
getTitleHtml(html, key) {
const str = [
"chiefComplaint",
"historyOfPresentIllness",
"physicaExamination",
"treatmentPlan",
].includes(key)
? `<span style="color:#F56C6C;margin-right:4px">*</span>`
: "";
// Regular expression to capture the first <h1> element in the HTML
const h1Match = html.match(/<h1[^>]*>(.*?)<\/h1>/);
if (h1Match) {
// If an <h1> is found, return it with the prepended star if needed
return `<h1>${str}${h1Match[1]}</h1>`;
} else {
// If no <h1> is found, return an empty <h1>
return "<h1></h1>";
}
},
async checkPermision() {
var result = await permission.premissionCheck("CAMERA_EXTERNAL_STORAGE");
if (result != 1) {
return false;
}
},
clickCourseInfo(val) {
console.log(val);
this.formData.labelId = val.id;
this.formData.labelTitle = val.title;
this.$forceUpdate();
},
//设置滚动到最底部
scrollToBottom() {
this.scrollIntoView = "";
setTimeout(() => {
this.scrollIntoView = "bottom-anchor";
}, 50);
},
//基因
handleInput(val) {
let name = val.detail.value;
this.getGenes(name);
},
//模糊搜索选中
selectItem(item) {
if (!this.selectedItems.some((i) => i.id === item.id)) {
this.selectedItems.push(item.name);
this.selectedId.push(item.id);
}
this.formData.genetic = "";
this.searchResultStatus = false;
console.log(this.selectedItems);
console.log(this.selectedId);
},
//删除标签
removeTag(index) {
this.selectedItems.splice(index, 1);
this.selectedId.splice(index, 1);
console.log(this.selectedItems);
console.log(this.selectedId);
},
//基因模糊查询列表
getGenes(name) {
this.$http
.request({
url: "taihumed/precisionMedicine/getPrecisionMedicineGenes",
method: "POST",
data: { name: name },
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
if (res.genes && res.genes.length > 0) {
this.searchResults = res.genes;
this.searchResultStatus = true;
} else {
this.searchResults = "";
this.searchResultStatus = false;
}
}
});
},
//勾选
toggleCheck() {
this.isChecked = !this.isChecked;
},
//获取病症种类数据
//获取对话记录数据
getRecordsData() {
this.record_list = [];
this.$http
.request({
url: "common/ragFlowApi/getChats",
method: "POST",
data: {
chatId: "",
sessionId: "",
page: 1,
pageSize: 300,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
console.log("请求最新列表");
if (res.list && res.list.length > 0) {
this.record_list = res.list;
//患者列表跳转来的
const index = res.list.findIndex(
(item) =>
item.chatAssistantId === this.pageData.chatAssistantId &&
item.chatId === this.pageData.chatId
);
if (this.pageType && this.pageType == "patient") {
this.clickRecord(this.pageData, index);
}
} else {
this.record_list = [];
this.null_text = "暂无数据";
}
}
})
.catch((e) => {
console.log(e);
});
},
//请求问答剩余次数
getUserAiVipCount() {
this.$http
.request({
url: "taihumed/aiVip/getUserAiVip",
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
this.flag = res.flag; //0-免费次数1-可升级
if (res.aiVipLog && res.aiVipLog.surplusCount >= 0) {
this.vipCount = res.aiVipLog.surplusCount;
this.vipText = "问答剩余:";
this.vipStatus = true;
}
if (res.freeCount >= 0) {
this.freeStatus = true;
this.freeCount = res.freeCount;
this.freeText = "赠送[全科医生]免费问答:";
} else {
this.freeStatus = false;
this.freeCount = null;
}
}
})
.catch((e) => {
uni.setStorageSync("guidePages", 2);
});
},
//点击每个记录
clickRecord(item, index) {
//重新定义id
this.chatId = item.chatAssistantId;
this.sessionId = item.chatId;
//助手类型
this.chatName = item.chatAssistantName;
this.patientName = item.patientName;
console.log("我是:" + this.patientName);
uni.setStorageSync("homeParams", { data: item, index: index });
this.activeRecord = index;
this.messages = [];
this.showMessages = true;
//请求病历夹接口
this.getRecordFolderList();
//如果正在回答的时候切换需要中断回答
this.closeWebSocket();
uni.showLoading({
title: "加载中",
});
this.$http
.request({
url: "common/ragFlowApi/getChats",
method: "POST",
data: {
chatId: item.chatAssistantId,
sessionId: item.chatId,
page: 1,
pageSize: 300,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
uni.hideLoading();
if (res.list && res.list.length > 0) {
this.messages = res.list.map((item) => {
let content = item.content.replace(/##\d+$$/g, "");
content = item.content.replace(/<\/?think>/g, "");
content = content.replace(
/\*\*(.*?)\*\*/g,
'<b class="bold-text">$1</b>'
);
content = content.replace(
/\*(.*?)\*/g,
'<span class="red-text">$1</span>'
);
content = content.replace(/\n\n/g, "\n");
content = content.replace(/\n/g, "<br>");
//content = content.replace(/^#{3,4}.*(\r?\n)?/gm, '');
return {
...item,
type: item.type === 1 ? "answer" : "question",
content: content,
};
});
//滚动到最底部锚点
this.$nextTick(() => {
this.scrollToBottom();
});
}
this.tishi = false; //提示语不用展示
this.$refs.drawer.close();
}
});
},
//选中科目类别
clickAssistants(item, index) {
this.activeIndex = index;
this.chatId = item.id;
this.chatName = item.name;
},
//提交
submit() {
let content = "";
let confirmText = "确定";
//没有次数的时候要求购买vip
if (!this.formData.message) {
this.$commonJS.showToast("请输入医案详情");
return;
}
//创建对话 获取sessionId
this.createChat();
},
//创建新对话
createChat() {
this.$http
.request({
url: "common/medicalRecords/medicalRecordsSplit",
method: "POST",
data: {
message: this.formData.message,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
this.medicalId = res.data;
this.sendQuestion();
}
});
},
//交谈请求,获取回答
sendQuestion() {
//清空消息记录
this.messages = [];
this.showMessages = true;
this.pauseStatus = true;
this.loading = true;
var that = this;
//展示提示语
this.tishi = true;
const poll = () => {
this.getMedicalDetail(() => {
// 停止轮询
clearInterval(pollInterval);
});
};
// 每5秒发送一次请求直到收到正确的响应
const pollInterval = setInterval(poll, 5000);
//调用后端 SSE 接口,发送问题并接收实时回答
// this.startSSE(params);
},
getMedicalDetail(fn) {
//清空消息记录
this.$http
.request({
url: "common/medicalRecords/medicalRecordsQuerySplit",
method: "POST",
data: {
id: this.medicalId,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (
res.code == 0 &&
res.medicalRecords != null &&
res.medicalRecords.data != ""
) {
console.log(res, "999999");
this.pauseStatus = false;
this.loading = false;
this.medicalRecords = res.medicalRecords;
if (this.medicalRecords.state || this.medicalRecords.state == 0) {
this.options.statusId = this.medicalRecords.state;
}
// this.$refs.commonMedicalDetail.initRecordData(this.medicalRecords);
// that.initRecordData();
console.log("at line 558:", this.record);
this.$forceUpdate();
// 滚动到最底部锚点
// that.$nextTick(() => {
// that.scrollToBottom();
// });
// 停止轮询
if (fn) {
fn();
}
}
})
.catch((error) => {
console.log("请求出错:", error);
});
//调用后端 SSE 接口,发送问题并接收实时回答
// this.startSSE(params);
},
//开始监听 SSE 数据
startSSE(params) {
const queryString = qs.stringify(params);
var data = {};
this.eventSource = uni.connectSocket({
url: this.$baseUrl + `websocket`,
success: () => {
console.log("WebSocket连接中...");
$http
.request({
url: `common/ragFlowApi/chatToAssistantStream?${queryString}`,
method: "GET",
data,
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
console.log("请求成功");
})
.catch((e) => {
console.log("失败");
});
},
fail: (err) => {
console.error("连接失败", err);
uni.showToast({ title: "连接失败", icon: "error" });
},
});
// 监听服务器发送的消息
uni.onSocketMessage((event) => {
try {
const message = JSON.parse(event.data);
if (message.data === true) {
console.log("回答已结束");
this.pauseStatus = false;
this.loading = false;
//获取最近的会话记录数据
this.getRecordsData();
setTimeout(() => {
this.closeWebSocket();
}, 200);
return;
}
const answer = message.data.answer.replace(/##\d+$$/g, "");
console.log(message.data.answer);
let newAnswer = ""; //初始化 newAnswer 变量
if (this.previousAnswer === null) {
console.log("第一次进来");
//如果没有包含上一条的内容,则直接显示当前 answer
newAnswer = answer;
this.messages.push({ content: newAnswer, type: "answer" });
this.previousAnswer = newAnswer;
} else {
//只显示新增的部分
newAnswer = answer.replace(this.previousAnswer, "");
newAnswer = newAnswer.replace(
/\*\*(.*?)\*\*/g,
'<b class="bold-text">$1</b>'
);
newAnswer = newAnswer.replace(
/\*(.*?)\*/g,
'<span class="red-text">$1</span>'
);
newAnswer = newAnswer.replace(/\n\n/g, "\n");
newAnswer = newAnswer.replace(/\n/g, "<br>");
newAnswer = newAnswer
.replace(/####([\s\S]*?)$/gm, "<h4>$1</h4>")
.replace(/###([\s\S]*?)$/gm, "<h3>$1</h3>");
this.messages.push({ content: newAnswer, type: "answer" });
this.previousAnswer = answer;
}
//滚动到最底部锚点
this.$nextTick(() => {
this.scrollToBottom();
});
} catch (error) {
this.loading = false;
this.closeWebSocket();
}
});
//监听WebSocket连接打开
uni.onSocketOpen(() => {
console.log("WebSocket已连接");
});
//监听WebSocket错误
uni.onSocketError((err) => {
console.error("WebSocket连接错误", err);
});
//监听WebSocket关闭
uni.onSocketClose((res) => {
console.log("WebSocket 已关闭", res);
});
},
//回答界面的提交
sendAgain() {
console.log("这是再一次提问");
if (!this.pauseStatus) {
if (!this.question_send) {
this.$commonJS.showToast("请输入发送内容");
return;
}
const params = {
chatId: this.chatId,
chatName: this.chatName,
question: this.question_send,
sessionId: this.sessionId,
sessionName: this.question_send.slice(0, 15),
patientName: this.formData.name,
};
this.messages.push({
content: `${this.question_send}`,
type: "question",
});
//滚动到最底部锚点
this.$nextTick(() => {
this.scrollToBottom();
});
this.loading = true;
this.question_send = "";
this.pauseStatus = true;
this.previousAnswer = null;
//调用后端 SSE 接口,发送问题并接收实时回答
this.startSSE(params);
} else {
console.log("不能点击了");
}
},
//点击左侧弹窗
openDrawer() {
this.$refs.drawer.open();
},
//点击新会话
showMode() {
this.showMessages = false;
this.messages = [];
this.formData = {
diagnosis: "",
illness: "",
symptoms: "",
genetic: "",
name: "",
};
this.chatId = null;
this.activeIndex = null;
this.activeRecord = null;
this.patientName = "";
this.selectedItems = [];
this.searchResultStatus = false;
//中断
this.closeWebSocket();
this.previousAnswer = null;
this.pauseStatus = false;
//把缓存清除
uni.removeStorageSync("homeParams");
//剩余次数
this.getUserAiVipCount();
},
//问答界面点击创建病历夹
clickFolder() {
if (this.pauseStatus) {
this.$commonJS.showToast("正在回答中,请稍候");
return;
}
if (this.folderList.length == 0) {
uni.showModal({
title: "提示",
content: "您还没有病历夹,确定创建新的病历夹吗?",
confirmText: "确定",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
this.$refs.add_folder.open("center");
} else if (res.cancel) {
console.log("取消创建病历夹");
}
},
});
} else {
this.$refs.popup.open("center");
}
},
//获取病历夹列表
getRecordFolderList() {
this.$http
.request({
url: "taihumed/aiRecordFolder/getRecordFolders",
method: "POST",
data: {
assistantId: this.chatId,
chatId: this.sessionId,
folderName: "",
patientName: "",
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
if (res.list && res.list.length > 0) {
this.folderList = res.list;
}
}
})
.catch((e) => {
console.log(e);
});
},
//点击创建病历夹
createFolder() {
this.$refs.popup.close();
this.$refs.add_folder.open();
this.folderName = "";
this.isChecked = true;
},
//创建病历夹
addRecordFolder() {
if (!this.folderName) {
this.$commonJS.showToast("请输入病历夹名称");
return;
}
if (!this.isChecked) {
uni.showLoading({
title: "正在创建中",
});
}
this.$http
.request({
url: "taihumed/aiRecordFolder/addRecordFolder",
method: "POST",
data: {
folderName: this.folderName,
sort: 0,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
if (res.code == 0) {
uni.hideLoading();
//如果把当前对话放入病历夹
if (this.isChecked) {
let id = res.aiRecordFolder.id;
this.addRecordFolderChat(id);
} else {
uni.showToast({
title: "创建成功",
icon: "success",
});
this.$refs.add_folder.close();
this.getRecordFolderList(); //刷新列表数据
}
}
});
},
//询问是否加入
askJoin(data) {
if (data.here == 1) {
this.$commonJS.showToast("不可重复加入病历夹");
return;
}
this.$refs.popup.close();
uni.showModal({
title: "提示",
content: "确定加入[" + data.folderName + "]病历夹吗?",
confirmText: "确定",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
this.addRecordFolderChat(data.id, "0");
} else if (res.cancel) {
console.log("取消加入病历夹");
}
},
});
},
//对话记录加入病历夹
addRecordFolderChat(id, type) {
let text1 = "";
let text2 = "";
let patientName = "";
if (type == "0") {
text1 = "正在加入该病历夹";
text2 = "加入成功";
} else {
text1 = "正在创建中";
text2 = "创建成功";
}
uni.showLoading({
title: text1,
});
//患者名字
if (this.formData.name) {
patientName = this.formData.name;
} else {
patientName = this.patientName;
}
this.$http
.request({
url: "taihumed/aiRecordFolder/addRecordFolderChat",
method: "POST",
data: {
folderId: id,
patientName: patientName,
chatAssistantId: this.chatId,
chatId: this.sessionId,
},
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
uni.hideLoading();
uni.showToast({
title: text2,
icon: "success",
});
this.$refs.add_folder.close();
this.$refs.popup.close();
this.getRecordFolderList(); //刷新列表数据
});
},
//关闭进程和监听
closeWebSocket() {
if (this.eventSource) {
// 关闭连接并移除监听
this.eventSource.close({
success: () => {
console.log("WebSocket 已关闭-closeWebSocket");
uni.offSocketMessage(); //移除消息监听
},
});
this.eventSource = null;
this.loading = false;
this.pauseStatus = false;
}
},
},
onHide() {
this.closeWebSocket();
},
onUnload() {
this.closeWebSocket();
},
};
</script>
<style lang="scss" scoped>
@import "@/static/mixin.scss";
.content {
background: linear-gradient(to bottom, #d8e6ff 0%, #d8e6ff57 90%, #fff 98%);
}
.home_top {
width: 100%;
background: #fff;
position: fixed;
top: 0;
left: 0;
padding: 90rpx 50rpx 30rpx;
text-align: center;
box-sizing: border-box;
z-index: 999;
.home_top_icon {
position: absolute;
left: 40rpx;
top: 85rpx;
display: flex;
align-items: center;
.home_top_left,
.home_top_right {
width: 60rpx;
height: 60rpx;
padding: 10rpx;
box-sizing: border-box;
}
.home_top_right {
margin-left: 30rpx;
}
}
text {
font-size: 43rpx;
line-height: 44rpx;
font-weight: bold;
color: $themeColor;
}
.home_top_folder {
padding: 12rpx;
position: absolute;
right: 40rpx;
top: 75rpx;
image {
width: 50rpx;
height: 50rpx;
}
}
}
.home_wrap {
margin: 0rpx 30rpx 0;
// padding-bottom: 300rpx;
overflow: hidden;
.home_logo {
padding-top: 40rpx;
image {
display: block;
width: 130rpx;
height: 130rpx;
margin: 0 auto;
}
.logo_main {
text-align: center;
display: block;
padding-top: 30rpx;
font-size: 35rpx;
color: $themeColor;
line-height: 46rpx;
}
.logo_con {
display: block;
width: 510rpx;
margin: 30rpx auto;
font-size: 28rpx;
color: #303030;
line-height: 40rpx;
text-indent: 2em;
}
}
}
.home_form {
margin-top: 60rpx;
padding-bottom: 80rpx;
position: relative;
.form_item {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 30rpx;
text {
line-height: 68rpx;
font-size: 30rpx;
color: #fff;
background: $themeBgColor;
text-align: center;
border-radius: 20rpx;
padding: 0 25rpx;
border: 1rpx solid $themeBgColor;
box-sizing: border-box;
}
textarea,
input,
.form_item_customize {
display: inline-block;
width: calc(100% - 200rpx);
height: 70rpx;
line-height: 35rpx;
padding: 17rpx 30rpx;
font-size: 28rpx;
color: #303030;
border-radius: 50rpx;
border: 1rpx solid #777778;
box-sizing: border-box;
resize: none;
max-height: 200rpx;
overflow-y: scroll;
}
}
}
.custom-placeholder {
font-size: 28rpx;
color: #8b8c90 !important;
}
.submit_form {
width: 100%;
height: 90px;
background: #fff;
position: fixed;
left: 0;
bottom: 120rpx;
padding: 0 50rpx;
z-index: 999;
}
.submit_form_2 {
height: 135rpx;
padding: 30rpx;
.assistants_list {
textarea,
input {
width: calc(100% - 65px);
font-size: 26rpx;
line-height: 34rpx;
border-radius: 50rpx;
padding: 22rpx 30rpx;
color: #303030;
background: #f3f4f6;
max-height: 72rpx;
overflow: hidden;
}
}
.submit_btn {
top: 42rpx;
}
}
.assistants_list {
display: flex;
align-items: center;
flex-wrap: wrap;
.assistants_item {
display: flex;
align-items: center;
width: 217rpx;
margin-top: 30rpx;
image {
width: 38rpx;
height: 38rpx;
}
text {
padding-left: 10rpx;
display: inline-block;
font-size: 28rpx;
color: #606061;
}
.assistants_img_1 {
display: block;
}
.assistants_img_2 {
display: none;
}
}
}
.submit_btn {
position: absolute;
right: 0rpx;
bottom: 10rpx;
image {
width: 55rpx;
height: 55rpx;
}
}
.active {
text {
color: $themeBgColor;
}
.assistants_img_1 {
display: none !important;
}
.assistants_img_2 {
display: block !important;
}
}
.message_wrap {
position: relative;
width: 100%;
// background: #fff;
z-index: 99;
padding: 0 30rpx;
height: 85vh;
}
.message_title {
text-align: center;
font-size: 30rpx;
color: #333;
line-height: 50rpx;
display: block;
font-weight: bold;
padding: 10rpx 0;
}
.message-container-block {
padding-top: 20rpx;
padding-bottom: 80px;
font-size: 30rpx;
}
.message-container {
display: inline;
line-height: 48rpx;
}
/* 自定义的loading效果 */
.loading-spinner {
margin-top: 10rpx;
border: 2px solid #f3f3f3;
/* 灰色背景 */
border-top: 2px solid #3498db;
/* 蓝色顶部 */
border-radius: 50%;
width: 16px;
height: 16px;
animation: spin 1s linear infinite;
/* 旋转动画 */
}
/* 旋转动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.bold-text {
display: block;
font-weight: bold;
font-size: 28rpx;
/* 增大字号 */
}
h3 {
font-size: 36rpx;
font-weight: bold;
}
h3 {
font-size: 32rpx;
}
.red-text {
color: red;
font-size: 28rpx;
/* 增大字号 */
}
.message-right {
display: block;
text-align: right;
margin: 30rpx 0;
text {
display: inline-block;
padding: 20rpx;
line-height: 38rpx;
background-color: rgba(81, 136, 229, 0.2);
border-radius: 15rpx;
color: #333;
font-size: 28rpx;
text-align: left;
}
}
.drawer-content {
height: 100vh;
display: flex;
flex-direction: column;
}
.list_content {
padding: 70rpx 20rpx 30rpx;
overflow-y: auto;
}
.list_item {
padding: 18rpx 10rpx;
}
.text_item {
display: block;
width: 100%;
font-size: 30rpx;
line-height: 40rpx;
padding: 0 10rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.null_text {
display: block;
text-align: center;
font-size: 30rpx;
color: #999;
padding-top: 150rpx;
}
.active_item {
background: #d8e6ff;
border-radius: 15rpx;
text {
color: #5188e5;
}
}
.folder_popup {
z-index: 9999;
.popup-content {
padding: 30rpx;
width: 550rpx;
background: #fff;
border-radius: 10rpx;
.popup-top {
padding: 15rpx;
display: flex;
align-items: center;
background: #5188e5;
border-radius: 10rpx;
color: #fff;
font-size: 28rpx;
line-height: 45rpx;
.uni-icons {
margin-right: 2rpx;
}
}
.popup-list {
.item-list {
padding: 15rpx;
background: #d8e6ff;
border-radius: 10rpx;
font-size: 28rpx;
line-height: 45rpx;
color: #5188e5;
margin-top: 15rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
text {
position: absolute;
right: 20rpx;
top: 12rpx;
font-size: 22rpx;
line-height: 45rpx;
color: #ff7800;
}
}
.popup-scroll {
max-height: 330rpx;
}
}
}
}
.add_folder_name {
font-size: 30rpx;
line-height: 45rpx;
color: #5188e5;
}
.add_folder_input {
margin-top: 20rpx;
input {
height: 70rpx;
line-height: 70rpx;
padding: 0 20rpx;
font-size: 26rpx;
color: #303030;
border-radius: 10rpx;
border: 1rpx solid #ddd;
box-sizing: border-box;
}
.custom-placeholder {
font-size: 26rpx;
}
}
.add_folder_btn {
width: 50%;
margin: 25rpx auto 0;
background: #5188e5;
border-radius: 50rpx;
font-size: 26rpx;
color: #fff;
line-height: 70rpx;
}
.checkbox-item {
display: flex;
align-items: center;
margin-top: 20rpx;
checkbox {
transform: scale(0.55);
/deep/.uni-checkbox-input {
border: 1rpx solid $themeColor;
margin-right: 0;
}
}
text {
color: #666;
font-size: 26rpx;
margin-left: -5rpx;
}
}
//基因模糊
.tags-block {
width: calc(100% - 255rpx);
line-height: 46rpx;
padding: 12rpx 20rpx;
border-radius: 50rpx;
border: 1rpx solid #777778;
box-sizing: border-box;
input {
border: none !important;
padding: 5rpx 10rpx !important;
height: 50rpx !important;
}
}
.tags-container {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.tag {
margin: 5rpx;
display: flex;
align-items: center;
background-color: #d8e6ff;
border-radius: 20rpx;
color: $themeColor;
padding: 0 15rpx;
font-size: 24rpx;
line-height: 38rpx;
}
.tag-close {
font-size: 24rpx;
font-weight: bold;
padding-left: 10rpx;
}
.result-list {
background: #fff;
width: calc(100% - 200rpx);
max-height: 325rpx;
border: 1px solid #eee;
border-radius: 10rpx;
margin-top: -30rpx;
float: right;
}
.result-item {
padding: 18rpx 20rpx;
border-bottom: 1px solid #f5f5f5;
font-size: 26rpx;
line-height: 30rpx;
}
.result-item:last-child {
border-bottom: 0;
}
.vip_count {
font-size: 26rpx;
color: red;
text-indent: 0;
text {
display: block;
}
}
.vip_count_block {
display: inline-block;
text-indent: 0;
padding-top: 10rpx;
}
.aiFlag {
position: absolute;
bottom: 55px;
left: 20px;
width: calc(100% - 40px);
font-size: 11px;
line-height: 16px;
color: #f69e12;
z-index: 999;
background: rgba(254, 243, 225, 0.8);
border: 1px solid #f2d7aa;
padding: 5px;
border-radius: 6px;
}
.in {
border: 1rpx solid #eeeeee;
border-radius: 8rpx;
width: calc(100% - 200rpx);
}
.shangpin_editor {
width: 100%;
}
/deep/.h1_box {
height: 24px;
margin-top: 40rpx;
h1 {
margin: 0 !important;
font-size: 20px;
line-height: 24px;
}
}
#editor {
height: 300px;
border: 1px solid #ccc;
}
.ql-container {
height: auto;
min-height: auto;
}
.editor-wrapper {
// background-color: #f0f0f080;
padding: 20rpx;
box-sizing: border-box;
border-radius: 20rpx;
border: 0.5px solid #777778;
}
.footer_box {
background: #fff;
padding-top: 10rpx;
height: 100rpx;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
z-index: 502;
box-sizing: content-box;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
box-shadow: 0 1px 15px rgba(0, 0, 0, 0.1);
}
.footer_bg {
background-color: #fff;
box-shadow: 0 0px 10px 1px #0000001a;
}
.footer_item {
position: relative;
flex: 1;
.button {
width: 88%;
background-color: #1985fd;
margin: auto auto;
margin-top: 10rpx;
border-radius: 50px;
line-height: 40px;
height: 40px;
text-align: center;
color: #fff;
font-weight: bold;
}
.savebutton {
background-color: #e4f0ff;
color: #1985fd;
}
}
/deep/.u-upload__button {
background-color: #fff;
.uicon-camera-fill {
color: #5188e5 !important;
}
}
.analysis_box {
padding-bottom: 40px;
width: 100%;
background-color: #fff;
border: 4rpx solid #188bff !important;
border-radius: 20rpx;
height: 84vh;
border-radius: 10px;
box-sizing: border-box !important;
uni-textarea {
border: none !important;
}
.analysis_title {
display: flex;
align-items: center;
padding: 18rpx 32rpx 0 16rpx;
color: #1781ff;
font-size: 18px;
font-weight: 700;
}
}
/deep/.home_wrap_analysis {
height: 89vh;
.home_form {
padding-bottom: 0px;
}
.form_item {
margin-bottom: 0 !important;
textarea {
// padding-top: 20rpx;
// height: 80vh !important;
}
.uni-textarea-wrapper {
// height: 100% !important;
}
}
.submit_btn {
padding: 0 40rpx;
position: absolute;
right: 24rpx;
bottom: 24rpx;
background-color: #1985fd;
margin: auto auto;
margin-top: 10rpx;
border-radius: 20rpx;
line-height: 62rpx;
height: 62rpx;
text-align: center;
color: #fff;
// font-weight: bold;
}
}
.content_detail {
background: #fff;
}
.message_wrap_detail {
padding: 0;
}
</style>