Browse Source

统计分析

whszxyjhyy
lzp 1 month ago
parent
commit
a2290a34f2
  1. 11
      web_admin/src/api/visiting.js
  2. 135
      web_admin/src/assets/styles/common.css
  3. 26
      web_admin/src/router/index.js
  4. 175
      web_admin/src/views/his/Evaluation/ReportDetail/scaleDetail.vue
  5. 641
      web_admin/src/views/his/Evaluation/ReportDetail/scaleTable.vue
  6. 340
      web_admin/src/views/his/Evaluation/index.vue
  7. 2
      web_admin/src/views/his/Patient/index.vue
  8. 17
      web_admin/src/views/index.js
  9. 1
      web_admin/src/views/index.vue
  10. 1004
      web_admin/src/views/statistics/index.vue
  11. 1726
      web_admin/src/views/visiting/config.js
  12. 861
      web_admin/src/views/visiting/index.vue

11
web_admin/src/api/visiting.js

@ -0,0 +1,11 @@
import request from "@/utils/request";
//防治计划
// 查询
export function queryPatientJzList(data) {
return request({
url: "/pms/queryPatientJzList",
method: "post",
data: data,
});
}

135
web_admin/src/assets/styles/common.css

@ -0,0 +1,135 @@
.popup {
display: flex;
justify-content: center;
align-items: center;
}
.popup >>> .el-dialog {
max-height: 86vh;
/* margin-top: 0 !important; */
overflow: auto;
border-radius: 6px;
}
>>>.el-dialog__header{
padding-bottom: 20px;
}
.popup >>> .el-dialog::-webkit-scrollbar {
display: none;
}
.popup >>> .el-dialog::-webkit-scrollbar {
display: none;
}
.popup >>> .el-dialog:not(.is-fullscreen) {
margin-top: 0 !important;
}
.popup >>> .popupAdd {
height: 58px;
font-size: 14px;
line-height: 58px;
display: flex;
margin-bottom: 20px;
margin-top: 20px;
align-items: center;
}
.popup >>> .popupAdd2 {
padding-left: 1px;
/* background-image: url(../images/addlog.png); */
background-repeat: no-repeat;
}
.popup >>> .popupAdd3 {
margin-top: 20px;
padding-left: 1px;
/* background-image: url(../images/tj.png); */
}
.popup .popupbox {
width: 650px;
height: 600px;
/* background-image: url(../images/solid.png); */
}
/* .popup >>> .popupAdd .popupleft {
font-size: 14px;
position: relative;
z-index: 2;
width: 68px;
height: 62px;
line-height: 62px;
text-align: center;
background-image: url(../images/addlog.png);
background-size: 100% 100%;
} */
.formStep >>> .el-icon-delete {
font-size: 20px;
}
.popup >>> .popupAdd .popupRight {
width: 100%;
margin-left: -20px;
height: 50px;
margin-top: 1px;
padding-left: 30px;
line-height: 50px;
font-size: 18px;
}
.inner::-webkit-scrollbar {
display: none;
}
>>>.el-dialog__body{
padding: 0px 20px 0px 20px;
}
/* .popup >>> .popupAdd2 .popupleft {
width: 55px;
} */
.formStep .el-button {
width: 68px;
height: 32px;
line-height: 32px;
background-size: 100% 100%;
border: none;
padding: 0;
opacity: 0.87;
}
.popup .el-button:hover {
opacity: 1;
}
.popup .popuButbox > div {
display: flex;
justify-content: center;
}
.formStep >>> .el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #67defc;
border-color: #67defc;
}
.formStep >>> .is-checked .el-checkbox__label {
color: #67defc;
}
.formStep .formStep_StepBox {
display: flex;
}
.formStep .StepBox {
width: 620px;
}
.formStep >>> .el-input__inner,
.formStep >>> .el-textarea__inner {
/* color: #fff; */
background: rgba(0, 0, 0, 0);
}
.formStep >>> .el-textarea__inner {
/* color: rgb(191, 203, 217); */
}
.formStep >>> .vue-treeselect__single-value {
color: rgb(191, 203, 217);
}
.formStep >>> .el-input__inner::input-placeholder {
color: #a8c9f0;
}
.formStep >>> .el-input--medium .el-input__inner,
.formStep >>> .el-textarea__inner,
.formStep >>> .el-select,
.formStep >>> .el-input-number--medium,
.formStep >>> .el-date-editor.el-input,
.formStep >>> .el-cascader--medium,
.formStep >>> .el-autocomplete {
width: 100% !important;
text-align: left;
}

26
web_admin/src/router/index.js

@ -92,19 +92,19 @@ export const constantRoutes = [
},
],
},
// {
// path: "/statistics",
// component: Layout,
// redirect: "statistics",
// children: [
// {
// path: "statistics",
// component: () => import("@/views/statistics/index.vue"),
// name: "statistics",
// meta: { title: "统计分析", icon: "dashboard", affix: true },
// },
// ],
// },
{
path: "/statistics",
component: Layout,
redirect: "statistics",
children: [
{
path: "statistics",
component: () => import("@/views/statistics/index.vue"),
name: "statistics",
meta: { title: "统计分析", icon: "dashboard", affix: true },
},
],
},
{
path: "/user",
component: Layout,

175
web_admin/src/views/his/Evaluation/ReportDetail/scaleDetail.vue

@ -46,16 +46,12 @@
"
>
<img
:src="apiUrl + proxyUrl + item.questionName"
:src="apiUrl + item.questionName"
class="reverse"
v-if="item.type === 5"
width="100"
/>
<img
:src="apiUrl + proxyUrl + item.questionName"
v-else
width="100"
/>
<img :src="apiUrl + item.questionName" v-else width="100" />
</td>
<td
colspan="2"
@ -67,18 +63,16 @@
</td>
<td colspan="2" v-else>
<div class="audio-box">
<!-- <div class="audio-bg" v-if="duration === ''">
<img
class="ml-4 pb-1"
src="../../../assets/ht/loading.gif"
style="width:20px;height:20px;"
/>
</div>-->
<div @click="playAudio('audioBtn')" class="audio-bg">
<div
@click="
playAudio('test' + item.questionId, item, 'audioBtn')
"
class="audio-bg"
>
<img
class="pl-4 pb-1"
src="../../../../assets/ht/play.gif"
v-if="paused"
v-if="item.audioBtn"
/>
<img
class="pl-4 pb-1"
@ -88,46 +82,100 @@
<span class="white--text">{{ duration }}</span>
</div>
<audio
:src="apiUrl + proxyUrl + item.questionName"
:src="apiUrl + item.questionName"
@canplay="getDuration"
controls="controls"
id="audioBtn"
:id="'test' + item.questionId"
ref="audio"
></audio>
</div>
</td>
<!-- 录音 -->
<td class="text-center" style="width: 200px">
<div class="audio-box" v-if="item.recordingPath">
<div @click="playAudio('audioBtn')" class="audio-bg">
<!-- {{ item.recordingShow }} -->
<div v-if="item.recordingPath" class="audio-box">
<div
@click="
playAudio(
'ly' + item.questionId,
item,
'recordingShow'
)
"
class="audio-bg d-flex justify-left"
>
<img
class="pl-4 pb-1"
class="pl-4"
src="../../../../assets/ht/play.gif"
v-if="paused"
v-if="item.recordingShow"
/>
<img
class="pl-4 pb-1"
class="pl-4"
src="../../../../assets/ht/pause.png"
v-else
/>
<span class="white--text">{{ duration }}</span>
</div>
<audio
:src="apiUrl + item.recordingPath"
@canplay="getDuration"
controls="controls"
id="audioBtn"
:id="'ly' + item.questionId"
ref="audio"
></audio>
</div>
</td>
<!-- 答案 -->
<td class="text-center">
<!-- CDR 第三题特殊处理 -->
<div
v-if="$route.query.evaluationCode == 'CDR3' && index == 2"
>
<div>
<span
v-for="(ans, a) in item.answers"
:key="0 + 0 + `${a}`"
v-show="ans.optionName == 'one'"
>
{{ ans.answer }}
</span>
</div>
<diV>
<span
v-for="(ans, a) in item.answers"
:key="0 + 0 + `${a}`"
v-show="ans.optionName == 'two'"
>
{{ ans.answer }}
</span>
</diV>
<div>
<span
v-for="(ans, a) in item.answers"
:key="0 + 0 + `${a}`"
v-show="ans.optionName == 'three'"
>
{{ ans.answer }}
</span>
</div>
</div>
<div v-else>
<span
:key="0 + 0 + `${a}`"
class="mr-3"
v-for="(ans, a) in item.answers"
>{{ ans.answer }}
</span>
</div>
<span
:key="0 + 0 + `${a}`"
class="mr-3"
v-for="(ans, a) in item.answers"
>{{ ans.answer }}</span
v-for="(ans, a) in item.recordDescList"
>
<span v-if="item.recordDescList.length > 1"
>{{ ans.recordName }}</span
>
{{ ans.answer }}</span
>
<div
@ -145,7 +193,16 @@
v-if="item.operateType === 3 || item.operateType === 6"
width="150"
/>
<img
:src="item.otherValueList[1]"
class="reverse"
v-else-if="
$route.query.evaluationCode == 'ADAS-Cog 14' &&
item.otherValueList &&
item.otherValueList[1]
"
width="200"
/>
<img
:src="item.otherValue"
class="reverse"
@ -154,7 +211,7 @@
/>
<br />
<!-- 还原绘图 -->
<el-button
<a-button
@click="
openCanvas(
item.questionId,
@ -167,25 +224,34 @@
v-if="item.otherValue"
>
原帧还原
</el-button>
<el-button
</a-button>
<a-button
@click="openAnswerDetailPic(item.otherValue)"
type="primary"
v-if="item.otherValue"
>查看图片</el-button
>查看图片</a-button
>
</div>
<div class="text-center" v-else-if="item.operateType === 1">
<div
class="text-center"
v-else-if="item.operateType === 1 && item.otherValue"
>
<div class="fill-width d-flex flex-column align-center">
<div class="audio-box">
<div
@click="playAudio(item.questionId)"
@click="
playAudio(
'answer' + item.questionId,
item,
'questionShow'
)
"
class="audio-bg d-flex justify-left"
>
<img
class="pl-4"
src="../../../../assets/ht/play.gif"
v-if="pausedA"
v-if="item.questionShow"
/>
<img
class="pl-4"
@ -195,10 +261,10 @@
<!-- <span class="white--text">{{ duration }}</span> -->
</div>
<audio
:src="item.otherValue"
:src="apiUrl + item.otherValue"
@canplay="getDuration"
controls="controls"
:id="item.questionId"
:id="'answer' + item.questionId"
ref="audio"
></audio>
</div>
@ -213,26 +279,11 @@
</div>
<div class="pa-8" v-else>暂无</div>
</div>
<el-dialog
title="原帧还原"
style="z-index: 9999"
:visible.sync="showDetailReduceCanvas"
width="1400px"
append-to-body
>
<AnswerDetailReduceCanvas v-if="showDetailReduceCanvas" />
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="showDetailReduceCanvas = false">
</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { mapState, mapActions, mapMutations, mapGetters } from "vuex";
// import { REPORTS } from "@/api/api-ht";
let { apiUrl, proxyUrl } = require("@/config/settings");
import { queryReportAnswer } from "@/api/his/evaluation";
import AnswerDetailReduceCanvas from "./AnswerDetailReduceCanvas";
@ -398,7 +449,7 @@ td {
}
table tr:nth-child(odd) {
background: #f0f6fa;
background: #eef8f8;
}
table tr:nth-child(even) {
@ -406,11 +457,10 @@ table tr:nth-child(even) {
}
.table-title {
background: #e7f1ff !important;
background: #d5f7eb !important;
}
.audio-box {
width: 220px;
height: 32px;
overflow: hidden;
}
@ -421,26 +471,29 @@ audio {
}
.audio-bg {
background: url("../../../../assets/ht/audio.png") left center no-repeat;
background-size: contain;
background: #b1e9d5;
width: 100%;
height: 32px;
line-height: 32px;
cursor: pointer;
text-align: left;
}
.audio-bg span {
font-size: 16px;
}
</style>
<style scoped>
<style lang="less" scoped>
.div-Back {
font-size: 18px;
margin-bottom: 16px;
color: #1a1a1a;
span {
margin-left: 10px;
}
}
.div-Back span {
margin-left: 10px;
td {
min-width: 200px;
}
</style>
<style>
@ -450,7 +503,7 @@ audio {
background: rgba(0, 0, 0, 0);
}
.ant-steps-item-process .ant-steps-item-icon {
background: #10b984;
border-color: #10b984;
background: #d5f7eb;
border-color: #d5f7eb;
}
</style>

641
web_admin/src/views/his/Evaluation/ReportDetail/scaleTable.vue

@ -3,40 +3,53 @@
<div class="box-card" v-if="scaleData">
<div class="card-header">
<div class="card-header-left">
<div style="font-size: 24px; font-weight: bold; color: #222">
{{ scaleData.name }}
</div>
<div
class="div-details"
style="cursor: pointer"
@click="routerJump(scaleData.code)"
v-if="scaleData.score && scaleData.subReport.length"
>
<h1>{{ scaleData.name }}</h1>
<!-- v-if="scaleData.code == 'HZ2'" -->
<div class="div-details" @click="routerJump(scaleData.code)">
查看详情
</div>
<div
class="div-details"
style="cursor: pointer"
@click="handleRecords(scaleData)"
v-if="scaleData.score && scaleData.subReport.length"
>
质控记录
</div>
<!-- <div
class="div-details"
@click="routerJump(scaleData.code)"
v-else-if="
scaleData.score && scaleData.subReport.length
"
>
查看详情
</div> -->
</div>
<div class="card-header-right">
<div
class="card-header-right"
v-if="
[
'MMSE',
'MoCA',
'ADL',
'(MOCA量表)',
'YYLC',
'BNT',
'BNT-15',
'AVLT',
'AVLT-H',
'LBD',
'SZGD',
'DST',
'ADAS-Cog 14',
].includes(scaleData.code)
"
>
<div
class="div-derive cardRig-but"
@click="handleCodeExport(scaleData)"
>
<i class="el-icon-upload2"></i>导出
</div>
<div class="div-print cardRig-but" @click="handlePrinting(scaleData)">
<div class="div-print cardRig-but" @click="handleCodeExport(scaleData,true)">
<i class="el-icon-printer"></i> 打印
</div>
</div>
</div>
<!-- MMSE 分数 -->
<div class="div-numbox" v-if="scaleData.code == 'MMSE'">
<el-row style="display: flex; flex-wrap: wrap">
<el-col
@ -68,7 +81,7 @@
</div>
</div>
<!-- MoCA -->
<div class="div-numbox" v-if="scaleData.code == 'MoCA'">
<div class="div-numbox" v-else-if="scaleData.code == 'MoCA'">
<el-row style="display: flex; flex-wrap: wrap">
<el-col
:span="6"
@ -88,8 +101,14 @@
margin-right: 16px;
"
>
<div>分类提示 </div>
<div>多选提示 </div>
<div>
分类提示
{{ getScore(row, "FLTS").score || 0 }}
</div>
<div>
多选提示
{{ getScore(row, "DXTS").score || 0 }}
</div>
</div>
</div>
{{ row.score }}
@ -112,7 +131,7 @@
</div>
</div>
<!-- 立方体组合测验 -->
<div class="div-numbox" v-if="scaleData.code == 'LFT'">
<div class="div-numbox" v-else-if="scaleData.code == 'LFT'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -128,7 +147,7 @@
</div>
</div>
<!-- 立方体组合测验 -->
<div class="div-numbox" v-if="scaleData.code == 'HZ2'">
<div class="div-numbox" v-else-if="scaleData.code == 'HZ2'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -138,7 +157,7 @@
</el-row>
</div>
<!-- ADL -->
<div class="div-numbox" v-if="scaleData.code == 'ADL'">
<div class="div-numbox" v-else-if="scaleData.code == 'ADL'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -152,7 +171,7 @@
</div>
</div>
<!-- SZFHJC 数字符号测验-->
<div class="div-numbox" v-if="scaleData.code == 'SZFHJC'">
<div class="div-numbox" v-else-if="scaleData.code == 'SZFHJC'">
<el-row>
<el-col :span="6" style="width: 50%; border-right: none">
<div class="col-header col-item">正确符号总数</div>
@ -167,7 +186,7 @@
</el-row>
</div>
<!-- SCWT Stroop色词测验-->
<div class="div-numbox" v-if="scaleData.code == 'SCWT'">
<div class="div-numbox" v-else-if="scaleData.code == 'SCWT'">
<el-row>
<el-col :span="6" style="width: 33.33%">
<div class="col-header col-item">
@ -199,7 +218,7 @@
</el-row>
</div>
<!--LBD 线方向判断-->
<div class="div-numbox" v-if="scaleData.code == 'LBD'">
<div class="div-numbox" v-else-if="scaleData.code == 'LBD'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -211,7 +230,7 @@
</el-row>
</div>
<!-- CDR -->
<div class="div-numbox" v-if="scaleData.code == 'CDR'">
<div class="div-numbox" v-else-if="scaleData.code == 'CDR'">
<el-row>
<el-col :span="6" style="width: 33.33%; border-right: none">
<div class="col-header col-item"></div>
@ -254,17 +273,15 @@
</el-row>
</div>
<!-- NP 数字化复杂图形测试量表 -->
<div class="ant-table-body pb-4" v-if="scaleData.code == 'NP'">
<div class="ant-table-body pb-4" v-else-if="scaleData.code == 'NP'">
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.score }}/{{
scaleData.totalScore - 0 > 0 ? scaleData.totalScore : ""
}}
{{ scaleData.name }}{{ scaleData.score }}
</div>
</el-col>
</div>
<!-- HAMA -->
<div class="div-numbox" v-if="scaleData.code == 'HAMA'">
<div class="div-numbox" v-else-if="scaleData.code == 'HAMA'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -278,7 +295,7 @@
</div>
</div>
<!--HAMD -->
<div class="div-numbox" v-if="scaleData.code == 'HAMD'">
<div class="div-numbox" v-else-if="scaleData.code == 'HAMD'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -292,7 +309,7 @@
</div>
</div>
<!--Rey(24) -->
<div class="div-numbox" v-if="scaleData.code == 'Rey'">
<div class="div-numbox" v-else-if="scaleData.code == 'Rey'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -302,7 +319,7 @@
</el-row>
</div>
<!--Rey(24) -->
<div class="div-numbox" v-if="scaleData.code == 'MINI'">
<div class="div-numbox" v-else-if="scaleData.code == 'MINI'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -318,7 +335,11 @@
</div>
</div>
<!--DST -->
<div class="div-numbox" v-if="scaleData.code == 'DST'">
<div
class="div-numbox"
v-else-if="scaleData.code == 'DST'"
style="border-top: 1px solid #e1e9f1"
>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div
@ -350,7 +371,7 @@
</el-row>
</div>
<!-- mini-cog 不太明确 -->
<div class="div-numbox" v-if="scaleData.code == 'PJS'">
<div class="div-numbox" v-else-if="scaleData.code == 'PJS'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
@ -366,13 +387,11 @@
</div>
</div>
<!-- AD8 -->
<div class="div-numbox" v-if="scaleData.code == 'AD8'">
<div class="div-numbox" v-else-if="scaleData.code == 'AD8'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.name }}{{
scaleData.totalScore - 0 > 0 ? scaleData.totalScore : ""
}}
{{ scaleData.name }}{{ scaleData.score }}
</div>
</el-col>
</el-row>
@ -382,13 +401,11 @@
</div>
</div>
<!-- HIS -->
<div class="div-numbox" v-if="scaleData.code == 'HIS'">
<div class="div-numbox" v-else-if="scaleData.code == 'HIS'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.name }}{{
scaleData.totalScore - 0 > 0 ? scaleData.totalScore : ""
}}
{{ scaleData.name }}{{ scaleData.score }}
</div>
</el-col>
</el-row>
@ -398,13 +415,11 @@
</div>
</div>
<!-- GDS-15 -->
<div class="div-numbox" v-if="scaleData.code == 'GDS-15'">
<div class="div-numbox" v-else-if="scaleData.code == 'GDS-15'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.name }}{{
scaleData.totalScore - 0 > 0 ? scaleData.totalScore : ""
}}
{{ scaleData.name }}{{ scaleData.score }}
</div>
</el-col>
</el-row>
@ -415,7 +430,7 @@
</div>
<!-- 临床记忆检测-AVLT -->
<div class="div-numbox" v-if="scaleData.code == 'AVLT'">
<div class="div-numbox" v-else-if="scaleData.code == 'AVLT'">
<el-row>
<el-col :span="6" style="width: 33.33%; border-right: none">
<div class="col-header col-item"></div>
@ -469,19 +484,6 @@
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
{{ getScore(scaleData, "XSJY").name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "XSJY").score }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "XSJY").remark }}
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
@ -495,19 +497,6 @@
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
{{ getScore(scaleData, "ZR").name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "ZR").score }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "ZR").remark }}
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
@ -521,9 +510,41 @@
</div>
</el-col>
</el-row>
<!--
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
{{ getScore(scaleData, 'XSHY').name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, 'XSHY').score }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, 'XSHY').remark }}
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
{{ getScore(scaleData, 'CSYCZR').name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, 'CSYCZR').score }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, 'CSYCZR').remark }}
</div>
</el-col>
</el-row> -->
</div>
<!-- CDR -->
<div class="div-numbox" v-if="scaleData.code == 'TMT'">
<div
class="div-numbox"
v-else-if="scaleData.code == 'CTT'"
style="border-top: 1px solid #e1e9f1; border-left: 1px solid #e1e9f1"
>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div
@ -532,32 +553,90 @@
>
{{ getScore(scaleData, "ASJCS").name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "ASJCS").score }}
<div
class="col-num col-item"
style="flex: 1; flex-direction: column"
>
<!-- 完成时间 -->
<div class="ctt-table">
完成时间
{{ getScore(scaleData, "ASJCS").score }}
</div>
<!-- 错误数-->
<div class="ctt-table" style="border: none">
错误数
{{
getScore(scaleData, "ASJCS").recordDescMap.CTT_A_ERROR_NUMBER
}}
</div>
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "ASJCS").remark }}
<div
class="col-num col-item"
style="flex: 1; flex-direction: column"
>
<!-- 完成时间提示语 -->
<div class="ctt-table">
{{ getScore(scaleData, "ASJCS").remark }}
</div>
<!-- 错误数提示语 -->
<div class="ctt-table" style="border: none">
{{ "错误数(0-25;88=不适用)" }}
</div>
</div>
</el-col>
</el-row>
<!-- B -->
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-header col-item" style="flex: 1">
{{ getScore(scaleData, "BSJCS").name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "BSJCS").score }}
<div
class="col-num col-item"
style="flex: 1; flex-direction: column"
>
<!-- 完成时间 -->
<div class="ctt-table">
完成时间
{{ getScore(scaleData, "BSJCS").score }}
</div>
<!-- 错误数-->
<div class="ctt-table" style="border: none">
错误数
{{
getScore(scaleData, "BSJCS").recordDescMap.CTT_B_ERROR_NUMBER
}}
</div>
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "BSJCS").remark }}
<div
class="col-num col-item"
style="flex: 1; flex-direction: column"
>
<!-- 完成时间提示语 -->
<div class="ctt-table">
{{ getScore(scaleData, "BSJCS").remark }}
</div>
<!-- 错误数提示语 -->
<div class="ctt-table" style="border: none">
{{ "错误数(0-25;88=不适用)" }}
</div>
</div>
</el-col>
</el-row>
</div>
<!-- BNT -->
<div class="div-numbox" v-if="scaleData.code == 'BNT'">
<div class="div-numbox" v-else-if="scaleData.code == 'BNT'">
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<el-col
:span="6"
style="
width: 100%;
display: flex;
border-top: 1px solid #e1e9f1;
border-left: 1px solid #e1e9f1;
"
>
<div class="col-num col-item col-header" style="flex: 1">
{{ scaleData.name }}
</div>
@ -571,14 +650,28 @@
</el-row>
</div>
<!-- NPI -->
<div class="div-numbox" v-if="scaleData.code == 'NPI'">
<div
class="div-numbox"
v-else-if="scaleData.code == 'NPI'"
style="border-top: 1px solid #e1e9f1"
>
<el-row>
<!-- <el-col :span="6" style="width: 100%; display: flex">
<div
class="col-num col-item col-header"
style="flex: 1"
>
总分{{ scaleData.score }}
</div>
</el-col> -->
</el-row>
<el-row>
<el-col :span="6" style="width: 100%; display: flex">
<div class="col-num col-item col-header" style="flex: 1">
{{ getScore(scaleData, "carer").name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "carer").score }}
{{ getScore(scaleData, "carer").score }}
</div>
</el-col>
</el-row>
@ -588,7 +681,7 @@
{{ getScore(scaleData, "result").name }}
</div>
<div class="col-num col-item" style="flex: 1">
{{ getScore(scaleData, "result").score }}
{{ getScore(scaleData, "result").score }}
</div>
</el-col>
</el-row>
@ -597,51 +690,155 @@
{{ scaleData.description }}
</div>
</div>
<div class="div-numbox" v-else-if="scaleData.code == 'SE-ADL'">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.name }} {{ scaleData.score }}%
</div>
<!-- MMSE 提示语 -->
<div class="col-tips" v-if="scaleData.description">
{{ scaleData.description }}
</div>
</el-col>
</el-row>
</div>
<div class="div-numbox" v-else-if="scaleData.code == '3DCAM'">
<div v-if="scaleData.subReport && scaleData.subReport.length">
<el-row style="display: flex; flex-wrap: wrap">
<el-col
:span="6"
v-for="(row, roInd) in scaleData.subReport"
:key="roInd"
>
<div class="col-header col-item">{{ row.name }}</div>
<div class="col-num col-item">
<span v-if="row.name != '是否存在谵妄'">
{{ row.score == 0 ? "阴性" : "阳性" }}
</span>
<span v-else>
<!-- 0 ? "否(阴)" : "是(阳)" -->
{{ row.score == 0 ? "否" : "是" }}
</span>
</div>
</el-col>
</el-row>
<!-- MMSE 提示语 -->
<div class="col-tips" v-if="scaleData.description">
{{ scaleData.description }}
</div>
</div>
<!-- 图表 -->
<div style="height: 200px; margin-top: 20px">
<p style="font-size: 20px; color: #3d3d3d">既往结果</p>
<div :id="'numbers' + index" style="height: 90%; width: 100%"></div>
<el-row v-else>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.name }} {{ scaleData.score }}
</div>
<!-- MMSE 提示语 -->
<div class="col-tips" v-if="scaleData.description">
{{ scaleData.description }}
</div>
</el-col>
</el-row>
</div>
<!-- <div class="div-numbox">
<el-row>
<el-col :span="6" style="width: 100%; border-right: none">
<div
class="col-header col-item"
style="border-right: none"
>
{{ scaleData.name }}{{
scaleData.totalScore - 0 > 0
? scaleData.totalScore
: ''
}}
</div>
</el-col>
</el-row>
<div class="col-tips">
{{ scaleData.description }}
</div>
</div> -->
<el-dialog
title="医生签名"
:visible.sync="open"
width="50%"
append-to-body
class="popup"
<!-- 没有特殊处理就用通用模板 -->
<div class="div-numbox" v-else>
<div v-if="scaleData.subReport && scaleData.subReport.length">
<el-row style="display: flex; flex-wrap: wrap">
<el-col
:span="6"
v-for="(row, roInd) in scaleData.subReport"
:key="roInd"
>
<div class="col-header col-item">
{{ row.name }}
</div>
<div class="col-num col-item">
{{ row.score }}
<span v-show="row.totalScore - 0 > 0">/</span>
{{ row.totalScore - 0 > 0 ? row.totalScore : "" }}
</div>
</el-col>
<el-col :span="6" v-if="scaleData.code != 'SDCP'">
<div class="col-header col-item">总分</div>
<div class="col-num col-item">
{{ scaleData.score }}
<span v-show="scaleData.totalScore - 0 > 0">/</span>
{{ scaleData.totalScore - 0 > 0 ? scaleData.totalScore : "" }}
</div>
</el-col>
</el-row>
<!-- MMSE 提示语 -->
<div class="col-tips" v-if="scaleData.description">
{{ scaleData.description }}
</div>
</div>
<el-row v-else>
<el-col :span="6" style="width: 100%; border-right: none">
<div class="col-header col-item" style="border-right: none">
{{ scaleData.name }} {{ scaleData.score }}
</div>
<!-- MMSE 提示语 -->
<div class="col-tips" v-if="scaleData.description">
{{ scaleData.description }}
</div>
</el-col>
</el-row>
</div>
<!-- 雷达图 -->
<div
style="
margin-top: 20px;
border-bottom: 1px solid #e1e9f1;
height: 440px;
"
v-if="['MoCA', 'MoCA-B'].includes(scaleData.code)"
>
<signatureVue
v-if="open"
ref="closeDialog1"
@close="closeDialog1"
@handleSing="handleSing"
<div
style="
display: flex;
justify-content: space-between;
align-items: center;
"
>
</signatureVue>
</el-dialog>
<p style="font-size: 20px; color: #3d3d3d">认知域指数</p>
</div>
<div
style="
width: 450px;
height: 400px;
margin: auto;
padding-bottom: 20px;
"
id="radar-box"
>
<p
class="moca-p"
style="text-align: center; margin-bottom: 10px; color: #000"
>
<span v-for="(item, index) in macaTime" :key="index">
<i :style="{ background: colorArr[index] }"></i>
{{ item }}
</span>
</p>
<div :id="'radar' + index" style="height: 340px; width: 100%"></div>
<!-- <div style="background: #f6f6f6; height: 20px"></div> -->
</div>
</div>
<!-- 折线图 -->
<div
style="height: 200px; margin-top: 20px"
v-if="['MMSE', 'MoCA', 'ADL'].includes(scaleData.code)"
>
<p style="font-size: 20px; color: #3d3d3d">既往结果</p>
<div :id="'numbers' + index" style="height: 90%; width: 100%"></div>
</div>
<iframe
:src="reportPath"
frameborder="0"
id="codePartIframe"
v-show="false"
:id="'codePartIframe' + timestamp"
style="display: none"
></iframe>
</div>
<el-dialog
@ -658,6 +855,7 @@
:visible.sync="showBigImg"
width="1400px"
append-to-body
class="popup"
>
<img :src="bigImgUrl" alt="" />
<span slot="footer" class="dialog-footer">
@ -692,6 +890,7 @@ import { codeExport } from "@/api/his/evaluation";
import { uploadfile } from "@/api/his/upload";
import { addSign } from "@/api/his/evaluation";
let { apiUrl, proxyUrl } = require("@/config/settings");
import * as echarts from "echarts";
export default {
name: "FirstPage",
@ -703,8 +902,26 @@ export default {
signData: {},
codeItme: {},
open: false,
openDetails: false,
reportPath: "",
timestamp: "",
radarMaxNum: {
jiYi: 15,
zhiXing: 13,
kongJian: 7,
yuYan: 6,
zhuYi: 18,
dingXiang: 6,
},
radarMaxNum1: {
jiyi: 15, //
zhixingli: 12, //
kongJian: 7, //
yuYan: 6, //
zhuYi: 13, //
dingXiang: 6, //
},
colorArr: ["#588E31", "#2E54A1", "#C65F10"],
macaTime: [],
query: {},
bigImgUrl: "", // url
showBigImg: false, //
@ -714,10 +931,12 @@ export default {
qualityId: null,
scaleCode: null,
},
openDetails: false, //
};
},
mounted() {
this.getScanData();
this.getradar();
},
created() {
console.log("scaleData: ", this.scaleData, this.index);
@ -743,31 +962,28 @@ export default {
},
//
showImg(pic) {
console.log('pic',pic)
this.bigImgUrl = pic;
this.showBigImg = true;
},
// code
async handleCodeExport(_item, _signId) {
async handleCodeExport(_item, _type) {
this.timestamp = new Date().getTime();
let params = {
evaluationId: this.reportDetail1.patient.id,
reportId: this.reportDetail1.patient.id,
scaleCode: _item.code || this.codeItme.code,
signId: _signId || this.signData.signId,
};
const res = await codeExport(params);
const { code, msg, data } = res;
if (code === 200) {
console.log("data: ", data);
//
if (!this.open) {
if (!_type) {
//
console.log(
"apiUrl + proxyUrl + data.path: ",
apiUrl + proxyUrl + data.path
);
window.open(apiUrl + proxyUrl + data.path);
console.log("apiUrl + data.path: ", apiUrl + data.path);
window.open(apiUrl + data.path);
} else {
this.handleInvoke("https://test.tall.wiki/ruisiAdmin" + data.path);
this.handleInvoke(apiUrl + data.path);
this.open = false;
}
// this.$forceUpdate();
@ -775,35 +991,22 @@ export default {
this.$message.error(msg);
}
},
//
handlePrinting(_item) {
if (JSON.parse(localStorage.getItem("isAndroid"))) {
this.$message.error("平板暂不支持打印功能,请在电脑端访问打印");
return;
}
this.open = true;
this.codeItme = _item;
},
//
handleInvoke(_path) {
this.reportPath = _path;
window.open(_path);
// try {
// this.reportPath = _path;
// console.log("this.reportPath11: ", this.reportPath);
// var iframe = document.getElementById("codePartIframe");
// console.log("iframe: ", iframe);
// iframe.onload = () => {
// iframe.contentWindow.print();
// };
// } catch (error) {
// console.log("error: ", error);
// }
try {
this.reportPath = _path;
console.log("this.reportPath11: ", this.reportPath);
var iframe = document.getElementById("codePartIframe"+ this.timestamp);
iframe.onload = () => {
iframe.contentWindow.print();
};
} catch (error) {
console.log("error: ", error);
}
},
//
handleSing(_singData) {
console.log(111111111111, this.codeItme);
// code
if (this.codeItme) {
this.handleCodeExport(this.codeItme, _singData.signId);
@ -824,10 +1027,10 @@ export default {
//
if (!this.open) {
//
window.open(apiUrl + proxyUrl + data.path);
window.open(apiUrl + data.path);
} else {
this.open = false;
this.handleInvoke("https://test.tall.wiki/ruisiAdmin" + data.path);
this.handleInvoke(apiUrl + data.path);
}
this.$forceUpdate();
} else {
@ -971,6 +1174,7 @@ export default {
// });
this.$nextTick(() => {
// domecharts
console.log('"numbers" + this.index', "numbers" + this.index);
var myChart = echarts.init(
document.getElementById("numbers" + this.index),
null
@ -980,6 +1184,108 @@ export default {
window.onresize = myChart.resize;
});
},
//
getradar() {
// let scoreDistributions = this.scaleData.scoreDistributions.filter(
// (item) =>
// item.evaluationId == this.$route.query.evaluationId ||
// this.createId
// );
let scoreDistributions = this.scaleData.scoreDistributions;
let indicator = [];
let radarMaxNum =
this.scaleData.code == "MoCA" ? this.radarMaxNum : this.radarMaxNum1;
console.log(this.scaleData.code, radarMaxNum);
scoreDistributions[0].cognitiveDomainList.forEach((item) => {
indicator.push({
name: item.cognitiveDomainName,
max: radarMaxNum[item.cognitiveDomain],
axisLabel: {
fontSize: 20,
color: "#838D9E",
},
});
});
let seriesData = [];
scoreDistributions.forEach((item, index) => {
let data = {
value: [],
name: item.day,
itemStyle: {
color: this.colorArr[index],
},
};
this.macaTime.push(item.day);
item.cognitiveDomainList.forEach((row) => {
data.value.push(row.score);
});
seriesData.push(data);
});
console.log("seriesData", seriesData, indicator);
let data = {
radar: {
radius: 110, //
startAngle: 90,
indicator: indicator,
name: {
textStyle: {
padding: [8, 8], // padding
color: "#000",
fontSize: 15,
},
},
splitLine: {
show: true,
lineStyle: {
color: "#1F4E79",
width: 2,
type: "dotted",
},
},
},
series: [
{
type: "radar",
itemStyle: {
normal: {
lineStyle: {
width: 3, //线
},
},
},
label: {
width: 5,
show: true,
formatter: function (params) {
return params.value;
},
textStyle: {
color: "#000", //
fontSize: 20, //
// fontWeight: 'bold', //
// fontStyle: 'italic', //
// fontFamily: 'Arial', //
},
},
data: [...seriesData],
},
],
};
this.$nextTick(() => {
// domecharts
var myChart = echarts.init(
document.getElementById("radar" + this.index),
null
);
myChart.setOption(data, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
// 6
firstMocaData() {
let result = null;
@ -1015,6 +1321,7 @@ export default {
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
/deep/.el-col-6 {
flex: 1;

340
web_admin/src/views/his/Evaluation/index.vue

@ -6,68 +6,37 @@
:inline="true"
label-width="68px"
>
<el-form-item label="关键字" prop="param.searchValue">
<el-form-item>
<el-input
v-model="queryParams.param.searchValue"
placeholder="用户名|手机号|身份证号"
placeholder="拼音首字母/全拼/姓名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="测评师" prop="param.testerName">
<div style="width: 215px">
<el-input
v-model="queryParams.param.testerName"
placeholder="测评师"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</div>
></el-input>
</el-form-item>
<!-- <el-form-item label="医院" prop="param.hospitalId">
<el-select
v-model="queryParams.hospitalId"
placeholder="请选择医院"
size="small"
<el-form-item label="评估师">
<el-input
v-model="queryParams.param.testerName"
placeholder="请输入"
clearable
>
<el-option label="医院1" value="0"></el-option>
<el-option label="医院2" value="1"></el-option>
<el-option label="医院3" value="2"></el-option>
</el-select>
></el-input>
</el-form-item>
<el-form-item label="科室" prop="departmentsId">
<div style="width: 215px">
<el-input
v-model="queryParams.departmentsId"
placeholder="科室"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</div>
</el-form-item> -->
<el-form-item label="测评状态" prop="param.completeStatus">
<el-form-item label="状态">
<el-select
v-model="queryParams.param.completeStatus"
placeholder="请选择测评状态"
size="small"
placeholder="请选择"
clearable
>
<el-option label="未完成" :value="0"></el-option>
<el-option label="完成" :value="1"></el-option>
<el-option label="终止" :value="2"></el-option>
<el-option label="已完成" :value="1"></el-option>
<el-option label="结束评估" :value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="测评时间" prop="param.beginTime">
<el-form-item label="测评时间" prop="param.time">
<el-date-picker
v-model="queryParams.param.time"
type="datetimerange"
type="daterange"
size="small"
value-format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
@ -99,7 +68,7 @@
>删除
</el-button>
</el-col> -->
<el-col :span="1.5" v-hasPermi="['tms:evaluation:report']">
<!-- <el-col :span="1.5" v-hasPermi="['tms:evaluation:report']">
<el-button
type="primary"
plain
@ -109,18 +78,7 @@
@click="handleReport"
>查看测评报告
</el-button>
</el-col>
<el-col :span="1.5" v-hasPermi="['tms:evaluation:import']">
<el-button
type="warning"
plain
icon="el-icon-upload2"
size="mini"
:loading="exportLoading"
@click="handleImport"
>导入
</el-button>
</el-col>
</el-col> -->
<el-col :span="1.5" v-hasPermi="['tms:evaluation:export']">
<el-button
type="warning"
@ -150,109 +108,99 @@
row-key="evaluationId"
@selection-change="handleSelectionChange"
>
<el-table-column prop="name" label="姓名" align="center" width="120">
</el-table-column>
<el-table-column label="性别" width="100" align="center">
<template slot-scope="scope">
<span v-if="scope.row.sex - 0 == 0"></span>
<span v-if="scope.row.sex - 0 == 1"></span>
</template>
</el-table-column>
<el-table-column
type="selection"
width="55"
fixed
align="center"
:reserve-selection="true"
/>
<el-table-column label="序号" align="center" key="index" type="index" />
<el-table-column
label="测评ID"
align="center"
prop="evaluationId"
key="evaluationId"
></el-table-column>
<!-- <el-table-column
label="医院名称"
align="center"
prop="evaluationId"
key="evaluationId"
width="300"
></el-table-column> -->
<!-- <el-table-column
label="科室"
align="center"
prop="evaluationId"
key="evaluationId"
width="100"
></el-table-column> -->
<el-table-column
label="开单医生"
align="center"
prop="doctorName"
key="doctorName"
width="120"
></el-table-column>
<el-table-column
label="测评师"
label="就诊号"
align="center"
prop="testerName"
key="testerName"
width="120"
></el-table-column>
width="160"
show-overflow-tooltip
>
<template slot-scope="scope">
{{ scope.row.outpatientNo || "-" }}
<span v-if="scope.row.admissionCount">
{{ scope.row.admissionCount }}
</span>
</template>
</el-table-column>
<el-table-column
label="患者姓名"
prop="department"
label="就诊科室"
align="center"
prop="name"
key="name"
width="100"
></el-table-column>
show-overflow-tooltip
>
<template slot-scope="scope">
{{ scope.row.department || "-" }}
</template>
</el-table-column>
<el-table-column
label="性别"
prop="doctor"
label="就诊/主治医生"
align="center"
prop="sex"
key="sex"
width="80"
width="140"
show-overflow-tooltip
>
<template slot-scope="scope">
{{ scope.row.sex == 0 ? "男" : "女" }}
{{ scope.row.doctor || "-" }}
</template>
</el-table-column>
<!-- <el-table-column
label="身份证"
align="center"
prop="idCard"
key="idCard"
width="280"
></el-table-column> -->
<el-table-column
label="测评状态"
prop="versionName"
label="评估版本"
align="center"
prop="completeStatus"
key="completeStatus"
width="240"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-tag v-if="scope.row.completeStatus == 0" type="info"
>未完成</el-tag
>
<el-tag v-if="scope.row.completeStatus == 1" type="success"
>完成</el-tag
>
<el-tag v-if="scope.row.completeStatus == 2" type="danger"
>中止</el-tag
>
{{ scope.row.versionName || "-" }}
</template>
</el-table-column>
<el-table-column
label="测评时间"
prop="testerName"
label="评估师"
align="center"
width="150"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="scaleNames"
label="评估量表"
align="center"
min-width="200"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="evaluationTime"
key="evaluationTime"
label="评估时间"
align="center"
width="200"
></el-table-column>
<el-table-column label="操作" align="center" width="280">
fixed="right"
>
</el-table-column>
<el-table-column
label="评估状态"
align="center"
width="150"
fixed="right"
>
<template slot-scope="scope">
<span :class="`completeStatus-${scope.row.completeStatus}`">
{{ completeStatus[scope.row.completeStatus] }}
</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit-outline"
@click="handleInformed(scope.row)"
v-hasPermi="['tms:evaluation:informed']"
>
查看知情同意
</el-button>
<el-button
size="mini"
type="text"
@ -262,15 +210,6 @@
>
查看测评报告
</el-button>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['tms:evaluation:remove']"
>
删除
</el-button> -->
</template>
</el-table-column>
</el-table>
@ -320,6 +259,65 @@
<el-button @click="codeShow = false"> </el-button>
</div>
</el-dialog>
<el-dialog
class="popup"
title="报告单"
:visible.sync="reportHistoryShow"
width="1400px"
append-to-body
>
<div v-if="reportDetail1">
<el-card
class="box-card"
v-for="(item, index) in reportDetail1.scores"
:key="index"
>
<!-- MMSE 分数 统计图-->
<scaleTable
:reportDetail1="reportDetail1"
:scaleData="item"
:index="index"
/>
<!-- 初步印象 -->
<!-- <div style="margin-top: 20px">
<div class="card-header" style="margin-bottom: 10px">
<div class="card-header-left">
<h1 style="line-height: 44px">初步印象</h1>
</div>
<div
class="div-edit"
@click="handleEdit(item)"
v-if="item.isEdit && !leftShow"
>
<a-icon type="edit" style="color: #10b77f; font-size: 22px" />
</div>
<div v-if="!item.isEdit">
<a-icon
type="check-circle"
style="font-size: 40px; color: #10b984"
@click="handleSubmit(item)"
/>
</div>
</div>
<a-textarea
:disabled="item.isEdit"
style="
background: #f6f6f6 !important;
font-size: 16px;
padding: 10px !important;
line-height: 30px;
"
v-model="item.impression"
:auto-size="{ minRows: 3, maxRows: 5 }"
/>
</div> -->
</el-card>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="reportHistoryShow = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
@ -331,6 +329,7 @@ import {
updateScaleInitialImpression,
exportReport,
} from "@/api/his/evaluation";
import scaleTable from "./ReportDetail/scaleTable.vue";
import { getScaleList } from "@/api/his/scale";
export default {
@ -338,6 +337,11 @@ export default {
components: { scaleTable },
data() {
return {
completeStatus: {
0: "未完成 ",
1: "完成",
2: "结束评估",
},
//
rules: {
scaleCodes: [
@ -355,14 +359,11 @@ export default {
queryParams: {
param: {
beginTime: "",
// departmentsId: null,
endTime: "",
// hospitalId: null,
scaleCode: "",
searchValue: "",
testerName: "",
patientId: "",
completeStatus: "",
showType: 1,
},
pageNum: 1,
pageSize: 10,
@ -383,7 +384,7 @@ export default {
//
reportHistoryShow: false,
//
reportDetail: null,
reportDetail1: null,
isEdit: false,
scaleList: [],
};
@ -431,13 +432,11 @@ export default {
this.queryParams = {
param: {
beginTime: "",
// departmentsId: null,
endTime: "",
// hospitalId: null,
scaleCode: "",
searchValue: "",
testerName: "",
patientId: "",
completeStatus: "",
showType: 1,
},
};
this.handleQuery();
@ -470,8 +469,8 @@ export default {
};
queryReportDetail(param).then((res) => {
console.log("res: ", res);
this.reportDetail = res.data;
this.reportDetail.evaluationId = param.evaluationId;
this.reportDetail1 = res.data;
this.reportDetail1.evaluationId = param.evaluationId;
this.reportHistoryShow = true;
});
},
@ -498,10 +497,10 @@ export default {
},
//
async handleSubmit(item) {
console.log("item: ", item, this.reportDetail.patient.id);
console.log("item: ", item, this.reportDetail1.patient.id);
let params = {
initialImpression: item.impression,
reportId: this.reportDetail.patient.id,
reportId: this.reportDetail1.patient.id,
scaleCode: item.code,
};
updateScaleInitialImpression(params).then((res) => {
@ -595,7 +594,21 @@ export default {
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.box-card {
margin-bottom: 20px;
}
.completeStatus-0 {
color: #ff4d4f;
}
.completeStatus-1 {
color: #10b984;
}
.completeStatus-2 {
color: #ffc107;
}
.reportPatientInfo {
border-radius: 4px;
background: #fff;
@ -638,6 +651,11 @@ export default {
justify-content: center;
cursor: pointer;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-header-left,
.card-header-right {
display: flex;

2
web_admin/src/views/his/Patient/index.vue

@ -394,6 +394,7 @@
prop="createBy"
key="createBy"
fixed="right"
width="100"
></el-table-column>
<el-table-column
label="创建时间"
@ -401,6 +402,7 @@
prop="createTime"
key="createTime"
fixed="right"
width="200"
></el-table-column>
<!-- <el-table-column
label="操作"

17
web_admin/src/views/index.js

@ -105,7 +105,24 @@ export function xyYjStatistics(data) {
data: data,
});
}
// 版本统计
export function versionStatistics(data) {
return request({
url: "/homePage/versionStatistics",
method: "post",
data: data,
});
}
// 工作量统计
export function userStatistics(data) {
return request({
url: "/homePage/userStatistics",
method: "post",
data: data,
});
}
// ——————————
// 性别分布
export let sexDistribution = {
tooltip: {

1
web_admin/src/views/index.vue

@ -732,6 +732,7 @@ export default {
.header-right-button-group {
display: flex;
.header-right-button {
cursor: pointer;
width: 90px;
height: 40px;
background: #2087f0;

1004
web_admin/src/views/statistics/index.vue

File diff suppressed because it is too large

1726
web_admin/src/views/visiting/config.js

File diff suppressed because it is too large

861
web_admin/src/views/visiting/index.vue

@ -0,0 +1,861 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
label-width="68px"
>
<el-form-item label="关键字" prop="param.searchValue">
<el-input
v-model="queryParams.param.searchValue"
placeholder="姓名|手机号|身份证号等"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="医院" prop="param.hospital">
<el-select
v-model="queryParams.param.hospitalId"
clearable
placeholder="所属医院"
>
<el-option
v-for="item in hospitalList"
:key="item.id"
:label="item.hospitalName"
:value="item.id"
></el-option>
</el-select>
</el-form-item> -->
<el-form-item label="时间范围" prop="param.time">
<el-date-picker
v-model="queryParams.param.time"
type="daterange"
size="small"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
>
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5" v-hasPermi="['tms:patient:add']">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<!-- <el-col :span="1.5" v-hasPermi="['tms:patient:remove']">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除
</el-button>
</el-col> -->
<!-- <el-col :span="1.5" v-hasPermi="['tms:patient:import']">
<el-button
type="warning"
plain
icon="el-icon-upload2"
size="mini"
:loading="exportLoading"
@click="handlePhysicalReport"
>导入体检报告
</el-button>
</el-col>
-->
<el-col :span="1.5" v-hasPermi="['tms:patient:export']">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出
</el-button>
</el-col>
<!-- <el-col :span="1.5" v-hasPermi="['tms:patient:import']">
<el-button
type="warning"
plain
icon="el-icon-upload2"
size="mini"
:loading="exportLoading"
@click="handleReport"
>导入体检报告
</el-button>
</el-col> -->
</el-row>
<el-table
v-loading="loading"
:data="patientList"
row-key="patientId"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" fixed align="center" />
<el-table-column
label="序号"
align="center"
key="index"
type="index"
fixed
/>
<el-table-column
label="姓名"
align="center"
prop="patientName"
key="patientName"
width="120"
fixed
></el-table-column>
<el-table-column
label="性别"
align="center"
prop="sex"
key="sex"
width="120"
>
<template slot-scope="scope">
{{ scope.row.sex == 0 ? "男" : "女" }}
</template>
</el-table-column>
<el-table-column
label="出生日期"
align="left"
prop="birthday"
key="birthday"
></el-table-column>
<el-table-column
label="受教育程度"
align="center"
prop="educationalStatus"
key="educationalStatus"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.educationalStatus"
placeholder="-"
>
<el-option
v-for="item in educationalStates"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
label="职业类型"
align="center"
prop="career"
key="career"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.career"
placeholder="-"
>
<el-option
v-for="item in careers"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
label="婚姻状况"
align="center"
prop="maritalStatus"
key="maritalStatus"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.maritalStatus"
placeholder="-"
>
<el-option
v-for="item in maritalStates"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
label="居住状态"
align="center"
prop="dwellingState"
key="dwellingState"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.dwellingState"
placeholder="-"
>
<el-option
v-for="item in dwellingStates"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
label="民族"
align="center"
prop="nation"
key="nation"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.nation"
placeholder="-"
>
<el-option
v-for="(status, index) in nationList"
:key="index"
:value="status.name"
:label="status.name"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
label="籍贯"
align="center"
prop="nativePlace"
key="nativePlace"
width="120"
></el-table-column>
<el-table-column
label="现住址"
align="center"
prop="address"
key="address"
width="200"
></el-table-column>
<el-table-column
label="联系人名称"
align="center"
prop="contactName"
key="contactName"
width="120"
></el-table-column>
<!-- <el-table-column
label="联系人电话"
align="center"
prop="contactMobile"
key="contactMobile"
width="120"
></el-table-column> -->
<el-table-column
label="与联系人关系"
align="center"
prop="contactRelation"
key="contactRelation"
width="120"
></el-table-column>
<el-table-column
label="信仰"
align="center"
prop="belief"
key="belief"
width="120"
></el-table-column>
<el-table-column
label="爱好"
align="center"
prop="hobby"
key="hobby"
width="120"
></el-table-column>
<el-table-column
label="ABO血型"
align="center"
prop="aboBloodType"
key="aboBloodType"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.aboBloodType"
placeholder="-"
>
<el-option
v-for="item in ABOBloodTypes"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
label="Rh血型"
align="center"
prop="rhBloodType"
key="rhBloodType"
width="120"
>
<template slot-scope="scope">
<el-select
class="table-select"
v-model="scope.row.rhBloodType"
placeholder="-"
>
<el-option
v-for="item in RHBloodTypes"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</template>
</el-table-column>
<!-- <el-table-column
label="身份证号"
align="center"
prop="idCard"
key="idCard"
width="200"
></el-table-column>
<el-table-column
label="联系方式"
align="center"
prop="phone"
key="phone"
width="200"
></el-table-column> -->
<el-table-column
label="医院名称"
align="left"
prop="hospitalName"
key="hospitalName"
></el-table-column>
<el-table-column
label="测评次数"
align="center"
prop="evaluationCount"
key="evaluationCount"
></el-table-column>
<el-table-column
label="上次测评"
align="center"
prop="lastEvaluationTime"
key="lastEvaluationTime"
width="200"
fixed="right"
></el-table-column>
<el-table-column
label="创建人"
align="center"
prop="createBy"
key="createBy"
fixed="right"
></el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
key="createTime"
fixed="right"
></el-table-column>
<!-- <el-table-column
label="操作"
align="center"
prop="department"
key="department"
width="200"
fixed="right"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleRecord(scope.row)"
v-hasPermi="['tms:patient:record']"
>
查看测评记录
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleEdit(scope.row.patientId)"
v-hasPermi="['tms:patient:edit']"
>
修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
style="color: red"
@click="handleDelete(scope.row)"
v-hasPermi="['tms:patient:remove']"
>
删除
</el-button>
</template>
</el-table-column> -->
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 导入患者信息 医科大学流调-->
<el-dialog
title="导入患者信息(医科大学流调)"
:visible.sync="open"
width="640px"
append-to-body
>
<el-form ref="form" :model="form">
<el-form-item prop="accessUrl">
<el-upload
:limit="1"
class="avatar-uploader wj-uploader"
:headers="headers"
:action="uploadFileUrl"
accept=".xlsx, .xls"
:before-upload="handleBeforePdfUpload"
:show-file-list="true"
:on-success="handleUploadPdfAdd"
:file-list="fileList"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
</el-upload>
</el-form-item>
</el-form>
</el-dialog>
<!--导入患者信息 殷家堡 -->
<el-dialog
title="导入患者信息(殷家堡)"
:visible.sync="yjbOpen"
width="640px"
append-to-body
>
<el-form ref="form" :model="form">
<el-form-item prop="accessUrl">
<el-upload
:limit="1"
class="avatar-uploader wj-uploader"
:headers="headers"
:action="uploadFileUrl2"
accept=".xlsx, .xls"
:before-upload="handleBeforePdfUpload"
:show-file-list="true"
:on-success="handleUploadPdfAdd"
:file-list="fileList"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
</el-upload>
</el-form-item>
</el-form>
</el-dialog>
<!-- 导入患者信息 -->
<el-dialog
title="导入体检报告"
:visible.sync="physicaOpen"
width="640px"
append-to-body
>
<el-form ref="form" :model="form">
<el-form-item prop="accessUrl">
<el-upload
:limit="1"
class="avatar-uploader wj-uploader"
:headers="headers"
:action="uploadFileUrl1"
accept=".zip"
:before-upload="handleBeforePdfUpload1"
:on-success="handleUploadPdfAdd1"
:file-list="fileList"
:show-file-list="true"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
</el-upload>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import { getToken } from "@/utils/auth";
import { mapMutations } from "vuex";
import { getHosList } from "@/api/his/hospital";
import { patientList, delPatient } from "@/api/his/patient";
import { queryPatientJzList } from "@/api/visiting";
import {
base as baseConfig,
maritalStates,
educationalStates,
dwellingStates,
independentLivingSkills,
careers,
handednesss,
socialActives,
gender,
idCardTypes,
ABOBloodTypes,
RHBloodTypes,
nationList,
} from "./config";
export default {
name: "Patient",
data() {
return {
baseConfig,
maritalStates,
educationalStates,
dwellingStates,
independentLivingSkills,
careers,
handednesss,
socialActives,
gender,
idCardTypes,
ABOBloodTypes,
RHBloodTypes,
nationList,
yjbOpen: false,
physicaOpen: false,
open: false,
form: {},
headers: {
Authorization: "Bearer " + getToken(),
deptId: localStorage.getItem("hospitalId"),
},
fileList: [],
uploadFileUrl: process.env.VUE_APP_BASE_API + "/pms/importPatient", //
uploadFileUrl1: process.env.VUE_APP_BASE_API + "/pms/importTjbgZip", //
uploadFileUrl2: process.env.VUE_APP_BASE_API + "/pms/importPatientYjb", //
//
queryParams: {
param: {
searchValue: null,
hospitalId: null,
time: null,
},
pageNum: 1,
pageSize: 10,
},
patientList: [], //
total: 0, //
loading: false, //
//
chooseData: [],
// id
ids: [],
//
single: true,
//
multiple: true,
//
exportLoading: false,
//
hospitalList: [],
};
},
created() {
this.getList();
this.getHospitalList();
},
methods: {
...mapMutations("patient", ["SET_PATIENT_ID"]),
//
handleReport() {
this.open = true;
this.fileList = [];
},
//
handleReport1() {
this.yjbOpen = true;
this.fileList = [];
},
handlePhysicalReport() {
this.fileList = [];
this.physicaOpen = true;
},
// - pdg
handleUploadPdfAdd1(res) {
if (res.code == 200) {
this.physicaOpen = false;
this.getList();
this.$modal.msgSuccess("导入成功");
} else {
this.$message.error(res.msg || "导入失败");
this.fileList = [];
}
},
// -
handleBeforeUpload1(file) {
const isLt2M = file.size / 1024 / 1024 < 100;
//
if (!isLt2M) {
this.$message.error("上传文件大小不能超过 100MB!");
}
return isLt2M;
},
// -
handleBeforePdfUpload1(file) {
const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
const whiteList = ["zip"];
if (whiteList.indexOf(fileSuffix) === -1) {
this.$message.error("上传文件只能是 zip");
return false;
}
},
// - pdg
handleUploadPdfAdd(res) {
if (res.code == 200) {
this.open = false;
this.yjbOpen = false;
this.getList();
this.$modal.msgSuccess("导入成功");
} else {
this.$message.error(res.msg || "导入失败");
this.fileList = [];
}
},
// -
handleBeforeUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 100;
//
if (!isLt2M) {
this.$message.error("上传文件大小不能超过 100MB!");
}
return isLt2M;
},
// -
handleBeforePdfUpload(file) {
const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
const whiteList = ["xlsx", "xls"];
if (whiteList.indexOf(fileSuffix) === -1) {
this.$message.error("上传文件只能是 xlsx,xls");
return false;
}
},
//
getHospitalList() {
const queryParams = {
param: {
searchValue: "",
informedConsent: null,
},
pageNum: 1,
pageSize: 100,
};
getHosList(queryParams).then((res) => {
this.hospitalList = [...res.data];
// this.total = res.data.length;
});
},
/** 搜索按钮操作----- */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 查询患者列表 */
getList() {
this.loading = true;
if (this.queryParams.param.time?.length) {
this.queryParams.param.beginTime = this.queryParams.param.time[0];
this.queryParams.param.endTime = this.queryParams.param.time[1];
}
queryPatientJzList(this.queryParams).then((res) => {
const { code, msg, data } = res;
if (code === 200) {
this.total = data.total;
this.patientList = [...data.list];
this.loading = false;
}
});
},
/** 重置按钮操作----- */
resetQuery() {
this.resetForm("queryForm");
this.queryParams = {
param: {
searchValue: null,
hospital: null,
time: null,
},
pageNum: 1,
pageSize: 10,
};
this.getList();
},
// -----
handleSelectionChange(selection) {
this.chooseData = [...selection];
this.ids = selection.map((item) => item.patientId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
//
handleAdd() {
//
this.SET_PATIENT_ID(null);
this.$router.push("/patient/info");
},
//
handleEdit(id) {
//
const patientId = id || this.ids[0];
this.SET_PATIENT_ID(patientId);
this.$router.push({ path: "/patient/info" });
},
//
handleDelete(row) {
const patientIds = row.patientId ? [row.patientId] : this.ids;
this.$modal
.confirm("是否确认删除当前选择的患者数据?")
.then(function () {
return delPatient({ param: { ids: patientIds } });
// return true;
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
//
handleRecord(row) {
const patientId = row.patientId;
this.$router.push({ path: "/evaluation/index", query: { patientId } });
},
//
handleImport() {
this.$message.warning("导入");
},
//
handleExport() {
if (this.queryParams.param.time?.length) {
this.queryParams.param.beginTime = this.queryParams.param.time[0];
this.queryParams.param.endTime = this.queryParams.param.time[1];
}
this.download1(
"/pms/exportPatient",
{
...this.queryParams,
},
`患者数据导出${new Date().getTime()}.xlsx`
);
},
},
};
</script>
<style scoped>
.table-select {
/* 禁止点击 */
pointer-events: none;
}
.table-select >>> .el-input__inner {
border: none !important;
padding: 0 !important;
background: rgba(0, 0, 0, 0);
text-align: center;
}
.table-select >>> input::placeholder {
color: #606266 !important;
}
.table-select >>> .el-select__caret {
display: none;
}
.wj-uploader .el-icon-upload:before {
font-size: 100px;
}
.wj-uploader .el-upload {
display: flex;
align-content: center;
justify-content: center;
flex-wrap: wrap;
}
.wj-uploader .el-upload__text {
line-height: 20px;
width: 100% !important;
}
.avatar-uploader {
height: 180px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9 !important;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 100% !important;
height: 180px !important;
line-height: 150px;
}
.el-upload-dragger,
.el-upload {
width: 100% !important;
}
.el-upload-list__item {
transition: none !important;
}
.el-upload-list__item:first-child {
margin-top: 0;
}
</style>
Loading…
Cancel
Save