feat: 在线数字人联调

dev_病例管理
xiangcongshuai 8 months ago
parent 27df2efab9
commit d7f01f2c2b

@ -0,0 +1,31 @@
import { http } from "@/utils/http";
/** 新建病历基本信息 */
export const createMedicalRecBaseInfo = (data?: object) => {
return http.request(
"post",
"/virtual-patient-manage/medicalRecManage/createMedicalRecBaseInfo",
{
data
}
);
};
/** 修改病历状态,上线或下线病历 */
export const updateMedicalStatus = (data?: object) => {
return http.request(
"post",
"/virtual-patient-manage/medicalRecManage/updateMedicalStatus",
{
data
}
);
};
/** 查询虚拟病人电子病历信息 */
export const queryMedicalRecBaseInfo = (data?: object) => {
return http.request(
"get",
"/virtual-patient-manage/medicalRecManage/queryMedicalRecBaseInfo",
{
params: data
}
);
};

@ -0,0 +1,39 @@
import { http } from "@/utils/http";
/** 查询数字人列表 */
export const queryPageList = (data?: object) => {
return http.request("get", "/virtual-patient-manage/humanManage/list", {
params: data
});
};
/** 新增数字人 */
export const createHuman = (data?: object) => {
return http.request(
"post",
"/virtual-patient-manage/humanManage/createHuman",
{
data
}
);
};
/** 修改数字人 */
export const updateHuman = (data?: object) => {
return http.request(
"post",
"/virtual-patient-manage/humanManage/updateHuman",
{
data
}
);
};
// 删除数字人;
export const deleteHuman = (data?: object) => {
return http.request(
"delete",
"/virtual-patient-manage/humanManage/deleteHuman",
{
params: data
}
);
};

@ -0,0 +1,22 @@
export default {
path: "/digitalHuman",
redirect: "/digitalHuman/index",
meta: {
title: "数字人",
icon: "weixinFavorites",
rank: 14
},
children: [
{
path: "/digitalHuman/index",
name: "DigitalHuman",
component: () => import("@/views/digitalHuman/index.vue"),
meta: {
title: "在线数字人 ",
showLink: true,
showParent: true,
roles: ["admin", "common"]
}
}
]
} as RouteConfigsTable;

@ -1,42 +1,35 @@
<script setup lang="ts">
import { nextTick, reactive, ref } from "vue";
import { reactive, ref } from "vue";
import { FormInstance } from "element-plus";
import { message } from "@/utils/message";
import { createMedicalRecBaseInfo } from "@/api/caseManagement";
// import { useRoute } from "vue-router";
defineOptions({
name: "AddEdit"
});
const isEditFlag = ref(false);
const diseaseList = ref([]);
const id = ref("");
const dialogVisible = ref(false);
const formData = reactive({
patientName: "",
patientGender: "",
directoryDesc: "",
patientSelfDesc: "",
patientAge: "",
diseaseId: ""
});
const ruleFormRef = ref<FormInstance>();
const rules = {
patientName: [{ required: true, message: "请输入", trigger: "change" }],
patientGender: [{ required: true, message: "请选择", trigger: "change" }],
directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
patientAge: [{ required: true, message: "请输入", trigger: "change" }],
patientSelfDesc: [{ required: true, message: "请输入", trigger: "change" }],
diseaseId: [{ required: true, message: "请选择", trigger: "change" }]
};
defineExpose({
async open(item) {
async open(data) {
dialogVisible.value = true;
await nextTick();
if (item) {
for (const key in item) {
// eslint-disable-next-line no-prototype-builtins
if (formData.hasOwnProperty(key)) {
formData[key] = item[key];
}
}
isEditFlag.value = true;
id.value = item.id;
}
diseaseList.value = data;
}
});
const resetForm = () => {
@ -55,27 +48,14 @@ const reset = () => {
const save = (formEl: FormInstance | undefined) => {
formEl.validate(async (valid, fields) => {
if (valid) {
// formData.result = refWangEditor.value.valueHtml;
// const params = {
// ...formData,
// result: refWangEditor.value.valueHtml,
// diseaseId: route.query.id
// };
if (isEditFlag.value) {
// const res: any = await updateSupportInspect({
// ...params,
// id: id.value
// });
if (res.code === 200) {
message("修改成功", { type: "success" });
id.value = "";
}
} else {
// const res: any = await addSupportInspect(params);
// if (res.code === 200) {
// message("", { type: "success" });
// }
const params = {
...formData
};
const res: any = await createMedicalRecBaseInfo(params);
if (res.code === 200) {
message("新增成功", { type: "success" });
}
dialogVisible.value = false;
emit("update");
} else {
@ -106,13 +86,13 @@ const save = (formEl: FormInstance | undefined) => {
ref="ruleFormRef"
:model="formData"
:rules="rules"
label-width="80px"
label-width="90px"
>
<el-form-item label="姓名" prop="directoryDesc">
<el-form-item label="姓名" prop="patientName">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientName"
/>
</el-form-item>
<el-form-item label="性别" prop="patientGender">

@ -1,17 +1,28 @@
<script setup lang="ts">
import { reactive, ref } from "vue";
import { onMounted, reactive, ref } from "vue";
import AddCase from "./AddCase.vue";
import SelectPeople from "./SelectPeople.vue";
import { queryMedicalRecBaseInfo } from "@/api/caseManagement";
import { useRoute } from "vue-router";
const AddCaseRef = ref();
const SelectPeopleRef = ref();
const formData = reactive({
let formData = reactive({
patientName: "",
patientGender: "",
patientMarriage: "",
nativePlace: "",
directoryDesc: "",
patientSelfDesc: "",
patientBirthplace: "",
patientPhone: "",
patientPostcode: "",
patientProfession: "",
patientAge: "",
diseaseId: ""
diseaseId: "",
medicalType: ""
});
const caseTypeList = ref([]);
const route = useRoute();
const medicalTypeList = ref([]);
const rules = {
patientGender: [{ required: true, message: "请选择", trigger: "change" }],
directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
@ -22,6 +33,15 @@ const add = () => {
const openPeopleDialog = () => {
SelectPeopleRef.value.open();
};
const getDetail = async () => {
const res: any = await queryMedicalRecBaseInfo({
medicalRecId: route.query.medicalRecId
});
formData = res.data;
};
onMounted(() => {
getDetail();
});
</script>
<template>
<div class="ElectronicCase">
@ -56,18 +76,18 @@ const openPeopleDialog = () => {
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="病历类型" prop="patientGender">
<el-form-item label="病历类型" prop="medicalType">
<el-select
size="large"
filterable
clearable
v-model="formData.diseaseId"
v-model="formData.medicalType"
class="form_select"
style="width: 100%"
placeholder="请选择选择类目"
>
<el-option
v-for="item in caseTypeList"
v-for="item in medicalTypeList"
:key="item.id"
:label="item.diseaseName"
:value="item.id"
@ -78,87 +98,87 @@ const openPeopleDialog = () => {
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="姓名" prop="directoryDesc">
<el-form-item label="姓名" prop="patientName">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientName"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="性别" prop="directoryDesc">
<el-form-item label="性别" prop="patientGender">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientGender"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="年龄" prop="directoryDesc">
<el-form-item label="年龄" prop="patientAge">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientAge"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="婚姻状态" prop="directoryDesc">
<el-form-item label="婚姻状态" prop="patientMarriage">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientMarriage"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="籍贯" prop="directoryDesc">
<el-form-item label="籍贯" prop="nativePlace">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.nativePlace"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="职业" prop="directoryDesc">
<el-form-item label="职业" prop="patientProfession">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientProfession"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="出生地" prop="directoryDesc">
<el-form-item label="出生地" prop="patientBirthplace">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientBirthplace"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电话" prop="directoryDesc">
<el-form-item label="电话" prop="patientPhone">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientPhone"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="邮编" prop="directoryDesc">
<el-form-item label="邮编" prop="patientPostcode">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.patientPostcode"
/>
</el-form-item>
</el-col>

@ -10,7 +10,8 @@ import { onMounted } from "vue";
import { clearObject } from "@/utils/auth";
import { useCaseStoreHooks } from "@/store/modules/caseManagement";
import AddEdit from "./add.vue";
import { updateMedicalStatus } from "@/api/caseManagement";
import { message } from "@/utils/message";
defineOptions({
name: "CaseManagement"
});
@ -58,8 +59,10 @@ const columns: TableColumnList = [
minWidth: 150
},
{
label: "机构",
prop: "alarmTask"
label: "状态",
prop: "diagnosisPrimaryStr",
slot: "status",
minWidth: 150
},
{
label: "更新时间",
@ -92,7 +95,7 @@ const reset = () => {
search();
};
const add = () => {
AddEditRef.value.open();
AddEditRef.value.open(diseaseList.value);
};
const getDiseaseListByDropList = async () => {
const res: any = await queryDiseaseListByDropList();
@ -108,6 +111,16 @@ const getData = async () => {
dataList.value = res.data.records;
pagination.total = res.data.total;
};
const changeStatus = async item => {
const res: any = await updateMedicalStatus({
medicalRecId: item.medicalId,
status: item.medicalStatus
});
if (res.code === 200) {
message("修改成功", { type: "success" });
getData();
}
};
const openDetail = item => {
router.push({
path: "/caseManagement/detail",
@ -120,7 +133,7 @@ const handleEdit = item => {
router.push({
path: "/caseManagement/edit",
query: {
id: item.medicalId
medicalRecId: item.medicalId
}
});
};
@ -227,6 +240,14 @@ onMounted(() => {
删除
</el-button> -->
</template>
<template #status="{ row }">
<el-switch
@change="changeStatus(row)"
v-model="row.medicalStatus"
active-value="1"
inactive-value="0"
/>
</template>
</pure-table>
</div>
<AddEdit ref="AddEditRef" />

@ -5,6 +5,7 @@ import { Plus, Delete } from "@element-plus/icons-vue";
import { message } from "@/utils/message";
// import { useRoute } from "vue-router";
import { getToken } from "@/utils/auth";
import { createHuman, updateHuman } from "@/api/digitalHuman";
defineOptions({
name: "AddEdit"
});
@ -15,28 +16,30 @@ const id = ref("");
const dialogVisible = ref(false);
const formData = reactive({
iconBase64: "",
directoryDesc: ""
imageFileUrl: "",
imageName: "",
imageFileId: "",
description: ""
});
const ruleFormRef = ref<FormInstance>();
const rules = {
iconBase64: [{ required: true, message: "请选择", trigger: "change" }],
directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
imageFileUrl: [{ required: true, message: "请选择", trigger: "change" }],
imageName: [{ required: true, message: "请输入", trigger: "change" }],
description: [{ required: true, message: "请输入", trigger: "change" }]
};
const handleSuccess: UploadProps["onSuccess"] = response => {
formData.iconBase64 = `/virtual-patient-manage/fileManage/downloadFile?fileId=${response.data.id}`;
formData.imageFileId = response.data.id;
formData.imageFileUrl = `/virtual-patient-manage/fileManage/downloadFile?fileId=${response.data.id}`;
};
const handleRemove = () => {
formData.iconBase64 = "";
formData.imageFileUrl = "";
formData.imageFileId = "";
fileList.value = [];
};
const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
// png|jpg 10M
if (
rawFile.type !== "image/png" ||
rawFile.type == "image/jpg" ||
rawFile.type == "image/jpeg"
) {
const type = rawFile.type.split("/")[1];
if (!["png", "jpg", "jpeg"].includes(type)) {
ElMessage.error("上传文件格式务必PNG|JPG|JPEG");
return false;
} else if (rawFile.size / 1024 / 1024 > 10) {
@ -57,7 +60,14 @@ defineExpose({
formData[key] = item[key];
}
}
formData.imageFileUrl = `/virtual-patient-manage/fileManage/downloadFile?fileId=${formData.imageFileId}`;
isEditFlag.value = true;
fileList.value = [];
if (formData.imageFileUrl) {
fileList.value.push({
url: formData.imageFileUrl
});
}
id.value = item.id;
}
}
@ -72,44 +82,33 @@ const closeDialog = () => {
};
const emit = defineEmits(["update"]);
const reset = () => {
if (isEditFlag.value) {
ruleFormRef.value.resetFields([
"diagnosticCriteria",
"diagnosisAssessmentFlag",
"requireCheckFlag",
"expectedDiagnosisResult",
"normalResult"
]);
} else {
ruleFormRef.value.resetFields();
}
// refWangEditor.value.valueHtml = "";
ruleFormRef.value.resetFields();
fileList.value = [];
isEditFlag.value = false;
};
const save = (formEl: FormInstance | undefined) => {
formEl.validate(async (valid, fields) => {
if (valid) {
// formData.result = refWangEditor.value.valueHtml;
// const params = {
// ...formData,
// result: refWangEditor.value.valueHtml,
// diseaseId: route.query.id
// };
const params = {
...formData,
imageFileUrl: undefined
};
if (isEditFlag.value) {
// const res: any = await updateSupportInspect({
// ...params,
// id: id.value
// });
const res: any = await updateHuman({
...params,
id: id.value
});
if (res.code === 200) {
message("修改成功", { type: "success" });
id.value = "";
}
} else {
// const res: any = await addSupportInspect(params);
// if (res.code === 200) {
// message("", { type: "success" });
// }
const res: any = await createHuman(params);
if (res.code === 200) {
message("新增成功", { type: "success" });
}
}
dialogVisible.value = false;
emit("update");
@ -143,7 +142,7 @@ const save = (formEl: FormInstance | undefined) => {
:rules="rules"
label-width="120px"
>
<el-form-item label="选择数字人形象" prop="code">
<el-form-item label="选择数字人形象" prop="imageFileUrl">
<div class="upload_img">
<el-upload
:limit="1"
@ -155,7 +154,7 @@ const save = (formEl: FormInstance | undefined) => {
:file-list="fileList"
:on-success="handleSuccess"
:before-upload="beforeUpload"
:class="{ hide: formData.iconBase64 !== '' }"
:class="{ hide: formData.imageFileUrl !== '' }"
>
<el-icon><Plus /></el-icon>
@ -163,7 +162,7 @@ const save = (formEl: FormInstance | undefined) => {
<div>
<img
class="el-upload-list__item-thumbnail"
:src="formData.iconBase64"
:src="formData.imageFileUrl"
alt=""
/>
<span class="el-upload-list__item-actions">
@ -180,13 +179,22 @@ const save = (formEl: FormInstance | undefined) => {
<div class="tip">仅支持JPGPNG格式图片尺寸420*746</div>
</div>
</el-form-item>
<el-form-item label="说明 " prop="directoryDesc">
<el-form-item label="名称 " prop="imageName">
<el-input
:maxLength="10"
size="large"
placeholder="请输入"
v-model="formData.imageName"
/>
</el-form-item>
<el-form-item label="说明 " prop="description">
<el-input
:rows="4"
size="large"
:maxLength="500"
type="textarea"
placeholder="请输入"
v-model="formData.directoryDesc"
v-model="formData.description"
/>
</el-form-item>
</el-form>

@ -3,6 +3,9 @@ import { onMounted, ref } from "vue";
import AddEdit from "./addEdit.vue";
import { Edit, Delete } from "@element-plus/icons-vue";
import { downLoadUrl } from "@/utils/auth";
import moreIcon from "@/assets/svg/consultation/more.svg?component";
import { deleteHuman, queryPageList } from "@/api/digitalHuman";
import { message } from "@/utils/message";
const dataList = ref([]);
const activedId = ref("");
const AddEditRef = ref();
@ -16,20 +19,25 @@ const onMouseenter = id => {
const onMouseleave = () => {
activedId.value = "";
};
const handleCommand = async (e: any) => {
const handleCommand = async (e: any, item) => {
if (e === "edit") {
// EditMaterialsRef.value.open(0, item);
AddEditRef.value.open(item);
} else {
// const res: any = await deleteMaterial({
// id: item.id
// });
// if (res.code === 200) {
// message("", { type: "success" });
// getData();
// }
const res: any = await deleteHuman({
id: item.id
});
if (res.code === 200) {
message("删除成功", { type: "success" });
getData();
}
}
};
const getData = async () => {
const res: any = await queryPageList();
if (res.code === 200) {
dataList.value = res.data;
}
};
const getData = () => {};
onMounted(() => {
getData();
});
@ -57,10 +65,10 @@ onMounted(() => {
@mouseleave.prevent="onMouseleave()"
>
<div class="folder_img">
<img :src="downLoadUrl(item.fileResourceId)" alt="" />
<img :src="downLoadUrl(item.imageFileId)" alt="" />
</div>
<div :title="item.materialName" class="name">
{{ item.materialName }}
<div :title="item.imageName" class="name">
{{ item.imageName }}
</div>
<el-dropdown
@command="e => handleCommand(e, item)"
@ -81,7 +89,7 @@ onMounted(() => {
</el-dropdown>
</div>
</div>
<AddEdit ref="AddEditRef" />
<AddEdit @update="getData" ref="AddEditRef" />
</div>
</template>
<style lang="scss" scoped>
@ -115,8 +123,9 @@ onMounted(() => {
background: #f5f5f5;
img {
width: 130px;
height: 130px;
width: 190px;
height: 190px;
border-radius: 12px 12px 0 0;
}
}

@ -1,6 +1,5 @@
<script setup lang="ts">
import { PaginationProps } from "@pureadmin/table";
import { reactive, ref } from "vue";
import { queryPageList } from "@/api/generalRules";
import { onMounted } from "vue";
@ -22,17 +21,36 @@ const pagination = reactive<PaginationProps>({
});
const columns: TableColumnList = [
{
label: "问诊类目",
prop: "nameZhPath",
minWidth: 150
label: "用户问题",
prop: "nameZhPath"
},
{
label: "问题",
label: "回复",
prop: "description",
minWidth: 240
},
{
label: "回复",
label: "问诊类目",
prop: "defaultAnswer"
},
{
label: "病历编号",
prop: "defaultAnswer"
},
{
label: "姓名",
prop: "defaultAnswer"
},
{
label: "阈值(%",
prop: "defaultAnswer"
},
{
label: "应答状态",
slot: "statusSlot"
},
{
label: "问诊时间",
prop: "defaultAnswer"
},
{
@ -73,9 +91,7 @@ const reset = () => {
const add = () => {
AddEditRef.value.open();
};
const edit = item => {
AddEditRef.value.open(JSON.parse(JSON.stringify(item)));
};
const del = item => {};
onMounted(() => {
getData();
});
@ -125,7 +141,7 @@ onMounted(() => {
@page-size-change="handleSizeChange"
@page-current-change="handleCurrentChange"
><template #operation="{ row }">
<el-button link type="primary" @click="edit(row)"></el-button>
<el-button link type="primary" @click="del(row)"></el-button>
</template>
</pure-table>
</div>

@ -160,8 +160,8 @@ const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
// png|jpg 10M
if (
rawFile.type !== "image/png" ||
rawFile.type == "image/jpg" ||
rawFile.type == "image/jpeg"
rawFile.type !== "image/jpg" ||
rawFile.type !== "image/jpeg"
) {
ElMessage.error("上传文件格式务必PNG|JPG|JPEG");
return false;

@ -46,7 +46,7 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
proxy: {
// 类型: Record<string, string | ProxyOp 为开发服务器配置自定义代理规则
"/virtual-patient-manage/": {
target: "http://192.168.10.137:8891/",
target: "http://192.168.10.25:8891/",
changeOrigin: true,
secure: false
// eslint-disable-next-line no-shadow

Loading…
Cancel
Save