fix: 病例管理页面开发

dev_531
xiangcongshuai 11 months ago
parent 1ebb244765
commit c460436aae

@ -218,3 +218,21 @@ export const deleteProcess = (data?: object) => {
params: data
});
};
/**
*/
export const queryQaRecordForFeedback = (data?: object) => {
return http.request(
"get",
"/virtual-patient/feedback/queryQaRecordForFeedback",
{
params: data
}
);
};
/**
*/
export const saveFeedback = (data?: object) => {
return http.request("post", "/virtual-patient/feedback/saveFeedback", {
data
});
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 B

@ -0,0 +1,11 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="heli-xuanzhong" clip-path="url(#clip0_542_564)">
<path id="Vector" d="M10 18.3337C12.3012 18.3337 14.3845 17.4009 15.8925 15.8929C17.4006 14.3848 18.3333 12.3015 18.3333 10.0003C18.3333 7.69916 17.4006 5.61583 15.8925 4.10777C14.3845 2.59973 12.3012 1.66699 10 1.66699C7.69884 1.66699 5.6155 2.59973 4.10745 4.10777C2.59941 5.61583 1.66667 7.69916 1.66667 10.0003C1.66667 12.3015 2.59941 14.3848 4.10745 15.8929C5.6155 17.4009 7.69884 18.3337 10 18.3337Z" stroke="#00975E" stroke-width="1.5" stroke-linejoin="round"/>
<path id="Vector_2" d="M6.66667 10L9.16667 12.5L14.1667 7.5" stroke="#00975E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_542_564">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 880 B

@ -0,0 +1,12 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="buheli-xuanzhong" clip-path="url(#clip0_542_568)">
<path id="Vector" d="M10 18.3337C14.6024 18.3337 18.3333 14.6027 18.3333 10.0003C18.3333 5.39795 14.6024 1.66699 10 1.66699C5.39762 1.66699 1.66666 5.39795 1.66666 10.0003C1.66666 14.6027 5.39762 18.3337 10 18.3337Z" stroke="#FF3429" stroke-width="1.5" stroke-linejoin="round"/>
<path id="Vector_2" d="M12.357 7.64258L7.64291 12.3566" stroke="#FF3429" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_3" d="M7.64304 7.64258L12.3571 12.3566" stroke="#FF3429" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_542_568">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 829 B

@ -0,0 +1,11 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="heli" clip-path="url(#clip0_542_573)">
<path id="Vector" d="M10 18.3337C12.3012 18.3337 14.3845 17.4009 15.8925 15.8929C17.4006 14.3848 18.3333 12.3015 18.3333 10.0003C18.3333 7.69916 17.4006 5.61583 15.8925 4.10777C14.3845 2.59973 12.3012 1.66699 10 1.66699C7.69884 1.66699 5.6155 2.59973 4.10745 4.10777C2.59941 5.61583 1.66667 7.69916 1.66667 10.0003C1.66667 12.3015 2.59941 14.3848 4.10745 15.8929C5.6155 17.4009 7.69884 18.3337 10 18.3337Z" stroke="#999999" stroke-width="1.5" stroke-linejoin="round"/>
<path id="Vector_2" d="M6.66667 10L9.16667 12.5L14.1667 7.5" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_542_573">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 870 B

@ -0,0 +1,12 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="buheli" clip-path="url(#clip0_542_577)">
<path id="Vector" d="M10 18.3337C14.6024 18.3337 18.3333 14.6027 18.3333 10.0003C18.3333 5.39795 14.6024 1.66699 10 1.66699C5.39762 1.66699 1.66666 5.39795 1.66666 10.0003C1.66666 14.6027 5.39762 18.3337 10 18.3337Z" stroke="#999999" stroke-width="1.5" stroke-linejoin="round"/>
<path id="Vector_2" d="M12.357 7.64258L7.64291 12.3566" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_3" d="M7.64304 7.64258L12.3571 12.3566" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_542_577">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 819 B

@ -95,7 +95,7 @@ export default {
{
path: "/caseManagement/edit",
name: "caseManagementEdit",
component: () => import("@/views/caseManagement/list/edit/index.vue"),
component: () => import("@/views/caseManagement/list/edit.vue"),
meta: {
title: "编辑病历",
showLink: false,

@ -1,22 +0,0 @@
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,4 +1,4 @@
<script setup lang="ts">
<!-- <script setup lang="ts">
import { nextTick, reactive, ref } from "vue";
import { FormInstance } from "element-plus";
import { message } from "@/utils/message";
@ -229,4 +229,19 @@ const save = (formEl: FormInstance | undefined) => {
}
}
}
</style>
</style> -->
<script setup lang="ts">
import { onMounted } from "vue";
import MainView from "./page/index.vue";
import { useCaseStoreHooks } from "@/store/modules/caseManagement";
onMounted(() => {
useCaseStoreHooks().changeIsEditFlag(false);
});
</script>
<template>
<div>
<MainView />
</div>
</template>

@ -0,0 +1,215 @@
<script setup lang="ts">
import { nextTick, reactive, ref } from "vue";
import { FormInstance } from "element-plus";
import { message } from "@/utils/message";
// import { useRoute } from "vue-router";
defineOptions({
name: "AddCase"
});
const isEditFlag = ref(false);
const diseaseList = ref([]);
const id = ref("");
const dialogVisible = ref(false);
const formData = reactive({
patientGender: "",
directoryDesc: "",
patientSelfDesc: "",
patientAge: "",
diseaseId: ""
});
const ruleFormRef = ref<FormInstance>();
const rules = {
patientGender: [{ required: true, message: "请选择", trigger: "change" }],
directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
};
defineExpose({
async open(item) {
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;
}
}
});
const resetForm = () => {
ruleFormRef.value.resetFields();
};
const closeDialog = () => {
dialogVisible.value = false;
isEditFlag.value = false;
resetForm();
};
const emit = defineEmits(["update"]);
const reset = () => {
ruleFormRef.value.resetFields();
};
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" });
// }
}
dialogVisible.value = false;
emit("update");
} else {
return fields;
}
});
};
</script>
<template>
<div>
<el-drawer
:size="650"
append-to-body
v-model="dialogVisible"
:show-close="false"
:with-header="false"
:before-close="closeDialog"
custom-class="AddEdit"
>
<div class="AddEdit">
<div class="header-title">
<div class="tip" />
<span>添加电子病历项</span>
</div>
<div class="line" />
<el-form
ref="ruleFormRef"
:model="formData"
:rules="rules"
label-width="80px"
>
<el-form-item label="选择类目" prop="directoryDesc">
<el-select
size="large"
filterable
clearable
v-model="formData.diseaseId"
class="form_select"
style="width: 100%"
placeholder="请选择选择类目"
>
<el-option
v-for="item in diseaseList"
:key="item.id"
:label="item.diseaseName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="名称" prop="patientGender">
<el-input size="large" v-model="formData.patientSelfDesc" />
</el-form-item>
<el-form-item label="内容" prop="patientSelfDesc">
<el-input size="large" v-model="formData.patientSelfDesc" />
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="footer_btn">
<div class="reset" @click="reset()"></div>
<div class="main" @click="save(ruleFormRef)"></div>
</div>
</template>
</el-drawer>
</div>
</template>
<style lang="scss" scoped>
.AddEdit {
:deep(.el-form-item__label) {
font-weight: 400;
color: #333;
}
.header-title {
display: flex;
align-items: center;
// border-left: 6px solid #4287ff;
font-size: 20px;
font-weight: bold;
color: #2b3f54;
.tip {
width: 6px;
height: 20px;
margin-right: 10px;
line-height: 20px;
background: #4287ff;
}
}
.line {
position: relative;
left: -20px;
width: 605px;
height: 1px;
margin: 24px 0;
background: rgb(91 139 255 / 30%);
}
.footer_btn {
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 16px;
.reset {
width: 188px;
height: 48px;
margin-right: 24px;
font-size: 16px;
font-weight: 400;
line-height: 48px;
color: #4287ff;
text-align: center;
cursor: pointer;
background: #fff;
border: 1px solid #4287ff;
border-radius: 6px;
}
.main {
width: 188px;
height: 48px;
font-size: 16px;
line-height: 48px;
color: #fff;
text-align: center;
cursor: pointer;
background: #4287ff;
border: 1px solid #4287ff;
border-radius: 6px;
}
}
}
</style>

@ -1,4 +1,24 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import { reactive, ref } from "vue";
import AddCase from "./AddCase.vue";
const AddCaseRef = ref();
const formData = reactive({
patientGender: "",
directoryDesc: "",
patientSelfDesc: "",
patientAge: "",
diseaseId: ""
});
const caseTypeList = ref([]);
const rules = {
patientGender: [{ required: true, message: "请选择", trigger: "change" }],
directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
};
const add = () => {
AddCaseRef.value.open();
};
</script>
<template>
<div class="ElectronicCase">
<div class="header">
@ -11,6 +31,75 @@
>
</div>
</div>
<el-form
ref="ruleFormRef"
:model="formData"
:rules="rules"
label-width="80px"
>
<el-row>
<el-col :span="8">
<el-form-item label="类型" prop="patientGender">
<span>在线默认</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="虚拟人" prop="patientGender">
<el-button type="primary" link> 请选择数字人 </el-button>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="病历类型" prop="patientGender">
<el-select
size="large"
filterable
clearable
v-model="formData.diseaseId"
class="form_select"
style="width: 100%"
placeholder="请选择选择类目"
>
<el-option
v-for="item in caseTypeList"
:key="item.id"
:label="item.diseaseName"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="姓名" prop="directoryDesc">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="性别" prop="directoryDesc">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="年龄" prop="directoryDesc">
<el-input
size="large"
placeholder="请输入"
v-model="formData.directoryDesc"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<AddCase ref="AddCaseRef" />
</div>
</template>
<style lang="scss" scoped>
@ -23,6 +112,7 @@
justify-content: space-between;
height: 88px;
padding: 0 40px;
margin-bottom: 24px;
border-bottom: 1px solid #d9d9d9;
.header_left {

@ -9,7 +9,6 @@ import {
import { onMounted } from "vue";
import { clearObject } from "@/utils/auth";
import { useCaseStoreHooks } from "@/store/modules/caseManagement";
import AddEdit from "./add.vue";
defineOptions({
name: "CaseManagement"
@ -24,7 +23,6 @@ const seachForm = reactive({
selfDescKeyword: ""
});
const diseaseList = ref([]);
const AddEditRef = ref();
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 10,
@ -92,7 +90,8 @@ const reset = () => {
search();
};
const add = () => {
AddEditRef.value.open();
router.push("/caseManagement/add");
useCaseStoreHooks().changeIsEditFlag(false);
};
const getDiseaseListByDropList = async () => {
const res: any = await queryDiseaseListByDropList();
@ -229,6 +228,5 @@ onMounted(() => {
</template>
</pure-table>
</div>
<AddEdit ref="AddEditRef" />
</div>
</template>

@ -1,5 +1,92 @@
<script setup lang="ts">
import titleIcon from "@/assets/newInquiry/title_icon.png";
import textIcon from "@/assets/newInquiry/text_icon.png";
import actReasonableIcon from "@/assets/svg/consultation/record/act_reasonable.svg";
import actUnreasonableIcon from "@/assets/svg/consultation/record/act_unreasonable.svg";
import reasonableIcon from "@/assets/svg/consultation/record/reasonable.svg";
import unreasonableIcon from "@/assets/svg/consultation/record/unreasonable.svg";
import { queryQaRecordForFeedback, saveFeedback } from "@/api/consultation";
import { reactive, ref } from "vue";
import { onMounted } from "vue";
import { useRoute } from "vue-router";
import { FormInstance } from "element-plus";
import { message } from "@/utils/message";
const formData = reactive({
evaluateLevel: undefined,
evaluateRemark: ""
});
const route = useRoute();
const ruleFormRef = ref<FormInstance>();
// const feedbackList = ref([
// {
// key: "1",
// name: ""
// },
// {
// key: "2",
// name: ""
// },
// {
// key: "3",
// name: ""
// }
// ]);
const dataList = ref([
// {
// feedbackType: 1,
// remark: "",
// feedback: [],
// question: "",
// anser:
// ""
// }
]);
const rules = {
evaluateLevel: [{ required: true, message: "请选择", trigger: "change" }]
};
const changeStatus = (index, val) => {
const list = [...dataList.value];
list[index].feedbackType = val;
dataList.value = list;
};
const getData = async () => {
const res: any = await queryQaRecordForFeedback({
processId: route.query.processId
});
dataList.value = res.data.qaList;
formData.evaluateLevel = res.data.evaluateLevel || "";
formData.evaluateRemark = res.data.evaluateRemark;
};
const reset = () => {
getData();
};
const save = (formEl: FormInstance | undefined) => {
formEl.validate(async (valid, fields) => {
if (valid) {
const params = {
qaList: dataList.value,
evaluateLevel: formData.evaluateLevel,
evaluateRemark: formData.evaluateRemark,
processId: route.query.processId
};
const res: any = await saveFeedback(params);
if (res.code === 200) {
message("提交成功", { type: "success" });
getData();
}
} else {
return fields;
}
});
};
const submit = () => {
console.log("1", dataList.value);
};
onMounted(() => {
getData();
});
</script>
<template>
@ -12,31 +99,278 @@ import titleIcon from "@/assets/newInquiry/title_icon.png";
<span>问诊评价</span>
</div>
</div>
<el-form
ref="ruleFormRef"
:model="formData"
class="mt-4"
:rules="rules"
label-width="90px"
>
<el-form-item label="预期结果:" prop="evaluateLevel">
<el-radio-group v-model="formData.evaluateLevel">
<el-radio :label="0" size="large">可靠</el-radio>
<el-radio :label="1" size="large">基本可靠</el-radio>
<el-radio :label="2" size="large">仅供参考</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注:" prop="evaluateRemark">
<el-input
:rows="4"
type="textarea"
:maxLength="500"
placeholder="请输入"
v-model="formData.evaluateRemark"
/>
</el-form-item>
</el-form>
</div>
<div class="main_content">
<div class="header_title">
<div class="title">
<img :src="textIcon" alt="" />
<span>临床问诊</span>
</div>
</div>
<div class="main_list">
<div class="main_item" v-for="(item, index) in dataList" :key="index">
<div class="main_item_left">
<p class="mb-1">{{ `问诊:${item.question}` }}</p>
<p>{{ `病人:${item.answer}` }}</p>
</div>
<div class="main_item_right">
<div
@click="changeStatus(index, 1)"
class="main_item_right_item"
style="margin-right: 40px"
:class="[item.feedbackType === 1 ? 'act_reasonableIcon' : '']"
>
<actReasonableIcon v-if="item.feedbackType === 1" />
<reasonableIcon v-else />
<span>合理</span>
</div>
<el-dropdown>
<div
@click="changeStatus(index, 2)"
class="main_item_right_item"
:class="[
item.feedbackType === 2 ? 'act_unreasonableIcon' : ''
]"
>
<actUnreasonableIcon v-if="item.feedbackType === 2" />
<unreasonableIcon v-else />
<span>不合理</span>
</div>
<template #dropdown>
<div class="drop_content">
<div class="title">临床问诊反馈</div>
<div class="dropdown_list">
<el-checkbox
size="large"
class="dropdown_list_item"
v-model="item.feedbackTooLong"
:true-label="1"
:false-label="0"
>回答过于冗长</el-checkbox
>
<el-checkbox
size="large"
class="dropdown_list_item"
:true-label="1"
:false-label="0"
v-model="item.feedbackError"
>答非所问</el-checkbox
>
<el-checkbox
size="large"
class="dropdown_list_item"
:true-label="1"
:false-label="0"
v-model="item.feedbackTooShort"
>内容不合理</el-checkbox
>
</div>
<el-input
v-model="item.feedbackRemark"
maxlength="20"
placeholder="请输入"
show-word-limit
type="textarea"
/>
<div class="drop_content_btn" @click="submit"></div>
</div>
</template>
</el-dropdown>
</div>
</div>
</div>
</div>
</div>
<div class="main_list">111</div>
<div class="footer_btn">
<div class="reset" @click="reset"></div>
<div class="main_btn" @click="save(ruleFormRef)"></div>
</div>
</div>
</template>
<style lang="scss" scoped>
.ConsultationRecords {
display: flex;
// display: flex;
padding: 32px;
.main {
display: flex;
flex-direction: row-reverse;
width: 100%;
margin: 16px;
.evaluate {
width: 441px;
height: calc(100vh - 250px);
padding: 24px;
margin-right: 24px;
background: #fff;
border-radius: 6px;
box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
}
.main_list {
.main_content {
flex: 1;
height: calc(100vh - 250px);
padding: 24px;
margin-right: 16px;
overflow-y: auto;
background: #fff;
border-radius: 6px;
box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
.main_list {
.main_item {
display: flex;
align-items: center;
justify-content: space-between;
height: 94px;
border-bottom: 1px solid #5b8bff;
.main_item_left {
padding-top: 24px;
font-size: 16px;
color: #2b3f54;
}
.main_item_right {
display: flex;
.main_item_right_item {
display: flex;
align-items: center;
cursor: pointer;
span {
margin-left: 8px;
font-size: 14px;
font-weight: 400;
color: #999;
}
}
.act_reasonableIcon span {
color: #00975e;
}
.act_unreasonableIcon span {
color: #ff3429;
}
}
}
}
}
}
.footer_btn {
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 16px;
margin-right: 32px;
.reset {
width: 188px;
height: 48px;
margin-right: 24px;
font-size: 16px;
font-weight: 400;
line-height: 48px;
color: #4287ff;
text-align: center;
cursor: pointer;
background: #fff;
border: 1px solid #4287ff;
border-radius: 6px;
}
.main_btn {
width: 188px;
height: 48px;
font-size: 16px;
line-height: 48px;
color: #fff;
text-align: center;
cursor: pointer;
background: #4287ff;
border: 1px solid #4287ff;
border-radius: 6px;
}
}
}
</style>
<style lang="scss">
.drop_content {
width: 240px;
height: 295px;
padding: 16px;
background: #fff;
border-radius: 8px;
box-shadow: 0 1px 8px 0 rgb(0 0 0 / 15%);
.title {
font-size: 16px;
font-weight: bold;
color: #2b3f54;
}
.dropdown_list {
display: flex;
flex-direction: column;
.dropdown_list_item {
padding: 0;
// margin-bottom: 8px;
}
.el-checkbox.el-checkbox--large .el-checkbox__inner {
width: 18px;
height: 18px;
}
.el-checkbox__inner::after {
left: 5px;
width: 5px;
height: 9px;
border-width: 2px;
}
}
.drop_content_btn {
width: 80px;
height: 32px;
margin-top: 16px;
margin-left: 60px;
font-size: 14px;
line-height: 32px;
color: #fff;
text-align: center;
cursor: pointer;
background: #4287ff;
border-radius: 6px;
}
}
</style>

@ -14,6 +14,7 @@ import {
import { getUserInfo } from "@/utils/auth";
import { useConsultationStoreHooks } from "@/store/modules/consultation";
import { creatDiagnosisProcesse } from "@/api/inquiry";
// import { message } from "@/utils/message";
import { downLoadUrl } from "@/utils/auth";
import { ElMessageBox } from "element-plus";
@ -89,12 +90,13 @@ const getDiagnoseProcessPageList = async () => {
userId: JSON.parse(userInfo).id
};
const res: any = await queryDiagnoseProcessPageList(params);
if (res?.code === 200) {
userPagination.total = res.data?.total;
caseList.value = res.data?.records;
userPagination.total = res.data.total;
caseList.value = res.data.records;
diagnoseProcessList.value = res.data.records;
userPagination.total = res.data.total;
diagnoseProcessList.value = res.data?.records;
userPagination.total = res.data?.total;
}
};
const getMedicalRecPageList = async () => {
const params = {
@ -102,11 +104,13 @@ const getMedicalRecPageList = async () => {
pageSize: casePagination.pageSize
};
const res: any = await queryMedicalRecPageList(params);
if (res?.code === 200) {
medicalRecList.value = res.data.records;
casePagination.total = res.data.total;
if (addFlag.value === true) {
caseList.value = medicalRecList.value;
}
}
};
const handleUserChange = val => {
userPagination.currentPage = val;

Loading…
Cancel
Save