zzc 3 months ago
parent
commit
fd4ece36ee
  1. 2
      acupuncture-前台/.env.development
  2. 2
      acupuncture-前台/.env.production
  3. 4
      acupuncture-前台/.env.staging
  4. 3
      acupuncture-前台/package.json
  5. 22
      acupuncture-前台/public/index.html
  6. BIN
      acupuncture-前台/public/zj.png
  7. 8
      acupuncture-前台/src/App.vue
  8. 17
      acupuncture-前台/src/api/followupFile.js
  9. 21
      acupuncture-前台/src/api/indexCom.js
  10. BIN
      acupuncture-前台/src/assets/images/dangan_n@1x.png
  11. BIN
      acupuncture-前台/src/assets/images/dangan_s@1x.png
  12. BIN
      acupuncture-前台/src/assets/images/home_N@1x.png
  13. BIN
      acupuncture-前台/src/assets/images/home_S@1x.png
  14. BIN
      acupuncture-前台/src/assets/images/logo@1x.png
  15. BIN
      acupuncture-前台/src/assets/images/me_n@1x.png
  16. BIN
      acupuncture-前台/src/assets/images/me_s@1x.png
  17. BIN
      acupuncture-前台/src/assets/images/suifang_n@1x.png
  18. BIN
      acupuncture-前台/src/assets/images/suifang_s@1x.png
  19. BIN
      acupuncture-前台/src/assets/images/zhenliao_n@1x.png
  20. BIN
      acupuncture-前台/src/assets/images/zhenliao_s@1x.png
  21. BIN
      acupuncture-前台/src/assets/images/zj.png
  22. 4
      acupuncture-前台/src/assets/styles/common.css
  23. 4
      acupuncture-前台/src/assets/styles/element-variables.scss
  24. 66
      acupuncture-前台/src/assets/styles/sidebar.scss
  25. 34
      acupuncture-前台/src/assets/styles/variables.scss
  26. 75
      acupuncture-前台/src/components/TopNav/index.vue
  27. 28
      acupuncture-前台/src/layout/components/AppMain.vue
  28. 34
      acupuncture-前台/src/layout/components/Navbar.vue
  29. 30
      acupuncture-前台/src/layout/components/Sidebar/Item.vue
  30. 68
      acupuncture-前台/src/layout/components/Sidebar/Logo.vue
  31. 184
      acupuncture-前台/src/layout/components/Sidebar/SidebarItem.vue
  32. 38
      acupuncture-前台/src/layout/components/Sidebar/index.vue
  33. 97
      acupuncture-前台/src/layout/index.vue
  34. 5
      acupuncture-前台/src/main.js
  35. 26
      acupuncture-前台/src/router/index.js
  36. 62
      acupuncture-前台/src/store/modules/app.js
  37. 4
      acupuncture-前台/src/store/modules/permission.js
  38. 57
      acupuncture-前台/src/store/modules/settings.js
  39. 1
      acupuncture-前台/src/store/modules/user.js
  40. 33
      acupuncture-前台/src/utils/request.js
  41. BIN
      acupuncture-前台/src/views/bg.png
  42. 67
      acupuncture-前台/src/views/followFile/index.vue
  43. 267
      acupuncture-前台/src/views/followFile/subjects.vue
  44. 283
      acupuncture-前台/src/views/followFile/work.vue
  45. 27
      acupuncture-前台/src/views/index.vue
  46. 292
      acupuncture-前台/src/views/indexCom/JM.vue
  47. 344
      acupuncture-前台/src/views/indexCom/XGZL.vue
  48. 261
      acupuncture-前台/src/views/indexCom/follow.vue
  49. BIN
      acupuncture-前台/src/views/indexCom/image.png
  50. 929
      acupuncture-前台/src/views/indexCom/index.js
  51. 232
      acupuncture-前台/src/views/indexCom/patient.vue
  52. 8
      acupuncture-前台/src/views/indexCom/query.vue
  53. 91
      acupuncture-前台/src/views/login.vue
  54. 374
      acupuncture-前台/src/views/medicalFile/components/anxiety/HAMD.vue
  55. 323
      acupuncture-前台/src/views/medicalFile/components/anxiety/SAS.vue
  56. 202
      acupuncture-前台/src/views/medicalFile/components/posture/PHQ-9.vue
  57. 171
      acupuncture-前台/src/views/medicalFile/components/posture/PSQI.vue
  58. 191
      acupuncture-前台/src/views/medicalFile/components/posture/epworth.vue
  59. 1224
      acupuncture-前台/src/views/medicalFile/details.vue
  60. 733
      acupuncture-前台/src/views/medicalFile/index.vue
  61. 177
      acupuncture-前台/src/views/patientFile/index.vue
  62. 2
      acupuncture-前台/src/views/register.vue
  63. 71
      acupuncture-前台/src/views/system/user/profile/index.vue
  64. 5
      acupuncture-前台/vue.config.js
  65. 2
      acupuncture-后台/.env.development
  66. 4
      acupuncture-后台/.env.production
  67. 4
      acupuncture-后台/.env.staging
  68. 5
      acupuncture-后台/package.json
  69. 22
      acupuncture-后台/public/index.html
  70. BIN
      acupuncture-后台/public/zj.png
  71. 8
      acupuncture-后台/src/App.vue
  72. 26
      acupuncture-后台/src/api/followupFile.js
  73. 146
      acupuncture-后台/src/api/indexCom.js
  74. 14
      acupuncture-后台/src/api/medicalFile.js
  75. 106
      acupuncture-后台/src/api/member.js
  76. 8
      acupuncture-后台/src/api/patientFile.js
  77. 64
      acupuncture-后台/src/api/report.js
  78. BIN
      acupuncture-后台/src/assets/images/zj.png
  79. 2
      acupuncture-后台/src/assets/styles/common.css
  80. 4
      acupuncture-后台/src/assets/styles/element-variables.scss
  81. 32
      acupuncture-后台/src/assets/styles/variables.scss
  82. 8
      acupuncture-后台/src/layout/components/Navbar.vue
  83. 67
      acupuncture-后台/src/layout/components/Sidebar/Logo.vue
  84. 5
      acupuncture-后台/src/main.js
  85. 104
      acupuncture-后台/src/router/index.js
  86. 57
      acupuncture-后台/src/store/modules/settings.js
  87. 33
      acupuncture-后台/src/utils/request.js
  88. BIN
      acupuncture-后台/src/views/bg.png
  89. 95
      acupuncture-后台/src/views/followFile/index.vue
  90. 141
      acupuncture-后台/src/views/followFile/subjects.vue
  91. 317
      acupuncture-后台/src/views/followFile/work.vue
  92. 1176
      acupuncture-后台/src/views/index.vue
  93. 420
      acupuncture-后台/src/views/indexCom/JM.vue
  94. 388
      acupuncture-后台/src/views/indexCom/XGZL.vue
  95. 261
      acupuncture-后台/src/views/indexCom/follow.vue
  96. BIN
      acupuncture-后台/src/views/indexCom/image.png
  97. 955
      acupuncture-后台/src/views/indexCom/index.js
  98. 373
      acupuncture-后台/src/views/indexCom/patient.vue
  99. 179
      acupuncture-后台/src/views/indexCom/query.vue
  100. 91
      acupuncture-后台/src/views/login.vue

2
acupuncture-前台/.env.development

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 针灸管理系统
VUE_APP_TITLE = 朱琏针灸联盟数据系统
# 开发环境配置
ENV = 'development'

2
acupuncture-前台/.env.production

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 针灸管理系统
VUE_APP_TITLE = 朱琏针灸联盟数据系统
# 生产环境配置
NODE_ENV = 'production'

4
acupuncture-前台/.env.staging

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 针灸管理系统
VUE_APP_TITLE = 朱琏针灸联盟数据系统
BABEL_ENV = production
@ -8,5 +8,5 @@ NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 针灸管理系统/测试环境
# 朱琏针灸联盟数据系统/测试环境
VUE_APP_BASE_API = '/stage-api'

3
acupuncture-前台/package.json

@ -1,7 +1,7 @@
{
"name": "ruoyi",
"version": "3.8.9",
"description": "针灸管理系统",
"description": "朱琏针灸联盟数据系统",
"author": "若依",
"license": "MIT",
"scripts": {
@ -48,6 +48,7 @@
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"moment": "^2.30.1",
"nprogress": "0.2.0",
"quill": "2.0.2",
"screenfull": "5.0.2",

22
acupuncture-前台/public/index.html

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<link rel="icon" type="image/x-icon" href="./zj.png">
<title>
<%= webpackConfig.name %>
</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
@ -16,6 +19,7 @@
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
@ -92,6 +96,7 @@
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
@ -105,6 +110,7 @@
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
@ -118,7 +124,7 @@
top: 0;
width: 51%;
height: 100%;
background: #7171C6;
background: #70483E;
z-index: 1000;
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
@ -194,8 +200,9 @@
opacity: 0.5;
}
</style>
</head>
<body>
</head>
<body>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
@ -204,5 +211,6 @@
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
</body>
</body>
</html>

BIN
acupuncture-前台/public/zj.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

8
acupuncture-前台/src/App.vue

@ -31,6 +31,14 @@ export default {
}
</style>
<style>
.header-title {
display: -webkit-box !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.wj-uploader .el-icon-upload:before {
font-size: 100px;
}

17
acupuncture-前台/src/api/followupFile.js

@ -1,5 +1,12 @@
import request from "@/utils/request";
// 公共队列
export function commonQueue(data) {
return request({
url: "/followup/commonQueue",
method: "post",
data: data,
});
}
// 随访队列
export function followupQuery(data) {
return request({
@ -73,3 +80,11 @@ export function followPatient(data) {
data: data,
});
}
// 修改随访状态
export function followStatus(data) {
return request({
url: "/followup/status",
method: "post",
data: data,
});
}

21
acupuncture-前台/src/api/indexCom.js

@ -122,4 +122,25 @@ export function zlInfo(data) {
});
}
// 治疗类型
export function zlType(data) {
return request({
url: "/statistics/zlType",
method: "post",
data: data,
});
}
// 随访分布
export function sffb(data) {
return request({
url: "/statistics/sffb",
method: "post",
data: data,
});
}
export function sftj(data) {
return request({
url: "/statistics/sftj",
method: "post",
data: data,
});
}

BIN
acupuncture-前台/src/assets/images/dangan_n@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

BIN
acupuncture-前台/src/assets/images/dangan_s@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

BIN
acupuncture-前台/src/assets/images/home_N@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

BIN
acupuncture-前台/src/assets/images/home_S@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

BIN
acupuncture-前台/src/assets/images/logo@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1018 B

BIN
acupuncture-前台/src/assets/images/me_n@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

BIN
acupuncture-前台/src/assets/images/me_s@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

BIN
acupuncture-前台/src/assets/images/suifang_n@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

BIN
acupuncture-前台/src/assets/images/suifang_s@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

BIN
acupuncture-前台/src/assets/images/zhenliao_n@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

BIN
acupuncture-前台/src/assets/images/zhenliao_s@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 B

BIN
acupuncture-前台/src/assets/images/zj.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

4
acupuncture-前台/src/assets/styles/common.css

@ -19,7 +19,7 @@
display: none;
}
.popup >>> .el-dialog:not(.is-fullscreen) {
margin-top: 0 !important;
margin: 0 !important;
}
.popup >>> .popupAdd {
height: 58px;
@ -73,7 +73,7 @@
display: none;
}
>>>.el-dialog__body{
padding: 0px 20px 0px 20px;
padding: 20px;
}
/* .popup >>> .popupAdd2 .popupleft {
width: 55px;

4
acupuncture-前台/src/assets/styles/element-variables.scss

@ -4,7 +4,7 @@
**/
/* theme color */
$--color-primary: #1890ff;
$--color-primary: #c6a268;
$--color-success: #13ce66;
$--color-warning: #ffba00;
$--color-danger: #ff4949;
@ -20,7 +20,7 @@ $--border-color-lighter: #e6ebf5;
$--table-border: 1px solid #dfe6ec;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
$--font-path: "~element-ui/lib/theme-chalk/fonts";
@import "~element-ui/packages/theme-chalk/src/index";

66
acupuncture-前台/src/assets/styles/sidebar.scss

@ -1,18 +1,17 @@
#app {
.main-container {
height: 100%;
transition: margin-left .28s;
transition: margin-left 0.28s;
margin-left: $base-sidebar-width;
position: relative;
}
.sidebarHide {
margin-left: 0!important;
margin-left: 0 !important;
}
.sidebar-container {
-webkit-transition: width .28s;
-webkit-transition: width 0.28s;
transition: width 0.28s;
width: $base-sidebar-width !important;
background-color: $base-menu-background;
@ -24,12 +23,17 @@
left: 0;
z-index: 1001;
overflow: hidden;
-webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
box-shadow: 2px 0 6px rgba(0,21,41,.35);
-webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
// reset element-ui css
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
transition: 0s width ease-in-out, 0s padding-left ease-in-out,
0s padding-right ease-in-out;
-webkit-transition: 0s width ease-in-out, 0s padding-left ease-in-out;
-moz-transition: 0s width ease-in-out, 0s padding-left ease-in-out;
-ms-transition: 0s width ease-in-out, 0s padding-left ease-in-out;
-o-transition: 0s width ease-in-out, 0s padding-left ease-in-out;
}
.scrollbar-wrapper {
@ -70,17 +74,37 @@
width: 100% !important;
}
.el-menu-item, .el-submenu__title {
.el-menu-item,
.el-submenu__title {
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
.el-menu-item {
height: 90px;
line-height: 26px !important;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 6px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
-ms-border-radius: 6px;
-o-border-radius: 6px;
}
// menu hover
.submenu-title-noDropdown,
.el-submenu__title {
&:hover {
background-color: rgba(0, 0, 0, 0.06) !important;
background-color: rgba(0, 0, 0, 0.2) !important;
color: #fff !important;
.div-img {
display: block;
}
.div-img-gl {
display: none;
}
}
}
@ -88,7 +112,7 @@
color: $base-menu-color-active !important;
}
& .nest-menu .el-submenu>.el-submenu__title,
& .nest-menu .el-submenu > .el-submenu__title,
& .el-submenu .el-menu-item {
min-width: $base-sidebar-width !important;
@ -97,7 +121,7 @@
}
}
& .theme-dark .nest-menu .el-submenu>.el-submenu__title,
& .theme-dark .nest-menu .el-submenu > .el-submenu__title,
& .theme-dark .el-submenu .el-menu-item {
background-color: $base-sub-menu-background !important;
@ -132,20 +156,19 @@
.el-submenu {
overflow: hidden;
&>.el-submenu__title {
& > .el-submenu__title {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
.el-menu--collapse {
.el-submenu {
&>.el-submenu__title {
&>span {
& > .el-submenu__title {
& > span {
height: 0;
width: 0;
overflow: hidden;
@ -164,11 +187,11 @@
// mobile responsive
.mobile {
.main-container {
margin-left: 0px;
margin-left: $base-sidebar-width;
}
.sidebar-container {
transition: transform .28s;
transition: transform 0.28s;
width: $base-sidebar-width !important;
}
@ -182,7 +205,6 @@
}
.withoutAnimation {
.main-container,
.sidebar-container {
transition: none;
@ -192,13 +214,13 @@
// when menu collapsed
.el-menu--vertical {
&>.el-menu {
& > .el-menu {
.svg-icon {
margin-right: 16px;
}
}
.nest-menu .el-submenu>.el-submenu__title,
.nest-menu .el-submenu > .el-submenu__title,
.el-menu-item {
&:hover {
// you can use $subMenuHover
@ -207,7 +229,7 @@
}
// the scroll bar appears when the subMenu is too long
>.el-menu--popup {
> .el-menu--popup {
max-height: 100vh;
overflow-y: auto;

34
acupuncture-前台/src/assets/styles/variables.scss

@ -1,25 +1,25 @@
// base color
$blue:#324157;
$light-blue:#3A71A8;
$red:#C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow:#FEC171;
$panGreen: #30B08F;
$blue: #324157;
$light-blue: #3a71a8;
$red: #c03639;
$pink: #e65d6e;
$green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
// 默认菜单主题风格
$base-menu-color:#bfcbd9;
$base-menu-color-active:#f4f4f5;
$base-menu-background:#304156;
$base-menu-color: #c7bdb1;
$base-menu-color-active: #f4f4f5;
$base-menu-background: #70483e;
$base-logo-title-color: #ffffff;
$base-menu-light-color:rgba(0,0,0,.70);
$base-menu-light-background:#ffffff;
$base-menu-light-color: rgba(0, 0, 0, 0.7);
$base-menu-light-background: #ffffff;
$base-logo-light-title-color: #001529;
$base-sub-menu-background:#1f2d3d;
$base-sub-menu-hover:#001528;
$base-sub-menu-background: #5a332a;
$base-sub-menu-hover: rgba(0, 0, 0, 0.2);
// 自定义暗色菜单风格
/**
@ -36,7 +36,7 @@ $base-sub-menu-background:#000c17;
$base-sub-menu-hover:#001528;
*/
$base-sidebar-width: 200px;
$base-sidebar-width: 90px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
@ -50,5 +50,5 @@ $base-sidebar-width: 200px;
subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color
logoLightTitleColor: $base-logo-light-title-color;
}

75
acupuncture-前台/src/components/TopNav/index.vue

@ -5,25 +5,38 @@
@select="handleSelect"
>
<template v-for="(item, index) in topMenus">
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
<el-menu-item
:style="{ '--theme': theme }"
:index="item.path"
:key="index"
v-if="index < visibleNumber"
>
<svg-icon
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
:icon-class="item.meta.icon"/>
:icon-class="item.meta.icon"
/>
{{ item.meta.title }}
</el-menu-item>
</template>
<!-- 顶部菜单超出数量折叠 -->
<el-submenu :style="{'--theme': theme}" index="more" :key="visibleNumber" v-if="topMenus.length > visibleNumber">
<el-submenu
:style="{ '--theme': theme }"
index="more"
:key="visibleNumber"
v-if="topMenus.length > visibleNumber"
>
<template slot="title">更多菜单</template>
<template v-for="(item, index) in topMenus">
<el-menu-item
:index="item.path"
:key="index"
v-if="index >= visibleNumber">
v-if="index >= visibleNumber"
>
<svg-icon
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
:icon-class="item.meta.icon"/>
:icon-class="item.meta.icon"
/>
{{ item.meta.title }}
</el-menu-item>
</template>
@ -36,7 +49,7 @@ import { constantRoutes } from "@/router";
import { isHttp } from "@/utils/validate";
//
const hideList = ['/index', '/user/profile'];
const hideList = ["/index", "/user/profile"];
export default {
data() {
@ -44,7 +57,7 @@ export default {
//
visibleNumber: 5,
// index
currentIndex: undefined
currentIndex: undefined,
};
},
computed: {
@ -76,11 +89,12 @@ export default {
this.routers.map((router) => {
for (var item in router.children) {
if (router.children[item].parentPath === undefined) {
if(router.path === "/") {
if (router.path === "/") {
router.children[item].path = "/" + router.children[item].path;
} else {
if(!isHttp(router.children[item].path)) {
router.children[item].path = router.path + "/" + router.children[item].path;
if (!isHttp(router.children[item].path)) {
router.children[item].path =
router.path + "/" + router.children[item].path;
}
}
router.children[item].parentPath = router.path;
@ -94,25 +108,29 @@ export default {
activeMenu() {
const path = this.$route.path;
let activePath = path;
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
if (
path !== undefined &&
path.lastIndexOf("/") > 0 &&
hideList.indexOf(path) === -1
) {
const tmpPath = path.substring(1, path.length);
if (!this.$route.meta.link) {
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
this.$store.dispatch('app/toggleSideBarHide', false);
this.$store.dispatch("app/toggleSideBarHide", false);
}
} else if(!this.$route.children) {
} else if (!this.$route.children) {
activePath = path;
this.$store.dispatch('app/toggleSideBarHide', true);
this.$store.dispatch("app/toggleSideBarHide", true);
}
this.activeRoutes(activePath);
return activePath;
},
},
beforeMount() {
window.addEventListener('resize', this.setVisibleNumber)
window.addEventListener("resize", this.setVisibleNumber);
},
beforeDestroy() {
window.removeEventListener('resize', this.setVisibleNumber)
window.removeEventListener("resize", this.setVisibleNumber);
},
mounted() {
this.setVisibleNumber();
@ -126,24 +144,24 @@ export default {
//
handleSelect(key, keyPath) {
this.currentIndex = key;
const route = this.routers.find(item => item.path === key);
const route = this.routers.find((item) => item.path === key);
if (isHttp(key)) {
// http(s)://
window.open(key, "_blank");
} else if (!route || !route.children) {
//
const routeMenu = this.childrenMenus.find(item => item.path === key);
const routeMenu = this.childrenMenus.find((item) => item.path === key);
if (routeMenu && routeMenu.query) {
let query = JSON.parse(routeMenu.query);
this.$router.push({ path: key, query: query });
} else {
this.$router.push({ path: key });
}
this.$store.dispatch('app/toggleSideBarHide', true);
this.$store.dispatch("app/toggleSideBarHide", true);
} else {
//
this.activeRoutes(key);
this.$store.dispatch('app/toggleSideBarHide', false);
this.$store.dispatch("app/toggleSideBarHide", false);
}
},
//
@ -156,36 +174,35 @@ export default {
}
});
}
if(routes.length > 0) {
if (routes.length > 0) {
this.$store.commit("SET_SIDEBAR_ROUTERS", routes);
} else {
this.$store.dispatch('app/toggleSideBarHide', true);
}
this.$store.dispatch("app/toggleSideBarHide", true);
}
},
},
};
</script>
<style lang="scss">
.topmenu-container.el-menu--horizontal > .el-menu-item {
line-height: 26px !important;
float: left;
height: 50px !important;
line-height: 50px !important;
color: #999093 !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important;
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active,
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{"var(--theme)"} !important;
color: #303133;
}
/* submenu item */
.topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
float: left;
height: 50px !important;
line-height: 50px !important;
line-height: 26px !important;
color: #999093 !important;
padding: 0 5px !important;
margin: 0 10px !important;

28
acupuncture-前台/src/layout/components/AppMain.vue

@ -10,36 +10,36 @@
</template>
<script>
import iframeToggle from "./IframeToggle/index"
import iframeToggle from "./IframeToggle/index";
export default {
name: 'AppMain',
name: "AppMain",
components: { iframeToggle },
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
return this.$store.state.tagsView.cachedViews;
},
key() {
return this.$route.path
}
return this.$route.path;
},
},
watch: {
$route() {
this.addIframe()
}
this.addIframe();
},
},
mounted() {
this.addIframe()
this.addIframe();
},
methods: {
addIframe() {
const {name} = this.$route
const { name } = this.$route;
if (name && this.$route.meta.link) {
this.$store.dispatch('tagsView/addIframeView', this.$route)
}
this.$store.dispatch("tagsView/addIframeView", this.$route);
}
}
}
},
},
};
</script>
<style lang="scss" scoped>
@ -58,7 +58,7 @@ export default {
.hasTagsView {
.app-main {
/* 84 = navbar + tags-view = 50 + 34 */
min-height: calc(100vh - 84px);
min-height: calc(100vh - 50px);
}
.fixed-header + .app-main {

34
acupuncture-前台/src/layout/components/Navbar.vue

@ -1,6 +1,6 @@
<template>
<div class="navbar">
<hamburger
<!-- <hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@ -11,11 +11,14 @@
id="breadcrumb-container"
class="breadcrumb-container"
v-if="!topNav"
/>
/> -->
<div class="logo-title">
朱琏针灸联盟数据系统{{ userInfo.tenantName }}
</div>
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
<div class="right-menu">
<template v-if="device !== 'mobile'">
<!-- <template v-if="device !== 'mobile'">
<search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom">
@ -31,9 +34,8 @@
<el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>
</template>
<el-dropdown
</template> -->
<!-- <el-dropdown
class="avatar-container right-menu-item hover-effect"
trigger="click"
>
@ -52,7 +54,7 @@
<span>退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown> -->
</div>
</div>
</template>
@ -79,6 +81,11 @@ export default {
RuoYiGit,
RuoYiDoc,
},
data() {
return {
userInfo: {},
};
},
computed: {
...mapGetters(["sidebar", "avatar", "device"]),
setting: {
@ -116,11 +123,24 @@ export default {
.catch(() => {});
},
},
created() {
let userInfo = localStorage.getItem("user");
this.userInfo = userInfo ? JSON.parse(userInfo) : {};
console.log("this.userInfo ", this.userInfo);
},
};
</script>
<style lang="scss" scoped>
.logo-title {
font-size: 20px;
color: #70483e;
line-height: 50px;
margin-left: 20px;
font-weight: 600;
}
.navbar {
display: flex;
height: 50px;
overflow: hidden;
position: relative;

30
acupuncture-前台/src/layout/components/Sidebar/Item.vue

@ -1,33 +1,27 @@
<script>
export default {
name: 'MenuItem',
name: "MenuItem",
functional: true,
props: {
icon: {
type: String,
default: ''
default: "",
},
title: {
type: String,
default: ''
}
default: "",
},
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
}
render(h, context) {
const { icon, title } = context.props;
const vnodes = [];
if (title) {
if (title.length > 5) {
vnodes.push(<span slot='title' title={(title)}>{(title)}</span>)
} else {
vnodes.push(<span slot='title'>{(title)}</span>)
vnodes.push(<span slot="title">{title}</span>);
}
}
return vnodes
}
}
return vnodes;
},
};
</script>

68
acupuncture-前台/src/layout/components/Sidebar/Logo.vue

@ -1,45 +1,38 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<div class="sidebar-logo-container" :class="{ collapse: collapse }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
</transition>
</div>
</template>
<script>
import logoImg from '@/assets/logo/logo.png'
import variables from '@/assets/styles/variables.scss'
import logoImg from "@/assets/images/zj.png";
import variables from "@/assets/styles/variables.scss";
export default {
name: 'SidebarLogo',
name: "SidebarLogo",
props: {
collapse: {
type: Boolean,
required: true
}
required: true,
},
},
computed: {
variables() {
return variables;
},
sideTheme() {
return this.$store.state.settings.sideTheme
}
return this.$store.state.settings.sideTheme;
},
},
data() {
return {
title: process.env.VUE_APP_TITLE,
logo: logoImg
}
}
}
logo: logoImg,
};
},
};
</script>
<style lang="scss" scoped>
@ -51,37 +44,16 @@ export default {
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
margin-top: 10px;
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
background: #2b2f3a;
text-align: center;
overflow: hidden;
& .sidebar-logo-link {
height: 100%;
width: 100%;
& .sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 40px;
height: 40px;
}
&.collapse {

184
acupuncture-前台/src/layout/components/Sidebar/SidebarItem.vue

@ -1,16 +1,54 @@
<template>
<div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
<template
v-if="
hasOneShowingChild(item.children, item) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.alwaysShow
"
>
<app-link
v-if="onlyOneChild.meta"
:to="resolvePath(onlyOneChild.path, onlyOneChild.query)"
>
<el-menu-item
:index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }"
>
<div v-if="itmeIcon[onlyOneChild.meta.title]" class="div-img">
<img :src="itmeIcon[onlyOneChild.meta.title]" alt="" />
</div>
<div v-if="itmeIcon[onlyOneChild.meta.title]" class="div-img-gl">
<img :src="itmeIcon1[onlyOneChild.meta.title]" alt="" />
</div>
<item
:icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
:title="onlyOneChild.meta.title"
/>
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<el-submenu
v-else
ref="subMenu"
:index="resolvePath(item.path)"
popper-append-to-body
>
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
<div class="header">
<div v-if="itmeIcon[item.meta.title]" class="div-img">
<img :src="itmeIcon[item.meta.title]" alt="" />
</div>
<div v-if="itmeIcon1[item.meta.title]" class="div-img-gl">
<img :src="itmeIcon[item.meta.title]" alt="" />
</div>
<item
v-if="item.meta"
:icon="item.meta && item.meta.icon"
:title="item.meta.title"
/>
</div>
</template>
<sidebar-item
v-for="(child, index) in item.children"
@ -25,75 +63,151 @@
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
import path from "path";
import { isExternal } from "@/utils/validate";
import Item from "./Item";
import AppLink from "./Link";
import FixiOSBug from "./FixiOSBug";
export default {
name: 'SidebarItem',
name: "SidebarItem",
components: { Item, AppLink },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
required: true,
},
isNest: {
type: Boolean,
default: false
default: false,
},
basePath: {
type: String,
default: ''
}
default: "",
},
sideTheme: {},
},
data() {
this.onlyOneChild = null
return {}
this.onlyOneChild = null;
return {
itmeIcon: {
首页: require("@/assets/images/home_N@1x.png"),
患者档案: require("@/assets/images/dangan_n@1x.png"),
诊疗档案: require("@/assets/images/zhenliao_n@1x.png"),
随访档案: require("@/assets/images/suifang_n@1x.png"),
我的: require("@/assets/images/me_n@1x.png"),
},
itmeIcon1: {
首页: require("@/assets/images/home_S@1x.png"),
患者档案: require("@/assets/images/dangan_s@1x.png"),
诊疗档案: require("@/assets/images/zhenliao_s@1x.png"),
随访档案: require("@/assets/images/suifang_s@1x.png"),
我的: require("@/assets/images/me_s@1x.png"),
},
};
},
methods: {
hasOneShowingChild(children = [], parent) {
if (!children) {
children = [];
}
const showingChildren = children.filter(item => {
const showingChildren = children.filter((item) => {
if (item.hidden) {
return false
return false;
}
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
})
this.onlyOneChild = item;
return true;
});
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
return true;
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
this.onlyOneChild = { ...parent, path: "", noShowingChildren: true };
return true;
}
return false
return false;
},
resolvePath(routePath, routeQuery) {
if (isExternal(routePath)) {
return routePath
return routePath;
}
if (isExternal(this.basePath)) {
return this.basePath
return this.basePath;
}
if (routeQuery) {
let query = JSON.parse(routeQuery);
return { path: path.resolve(this.basePath, routePath), query: query }
return { path: path.resolve(this.basePath, routePath), query: query };
}
return path.resolve(this.basePath, routePath)
}
}
}
return path.resolve(this.basePath, routePath);
},
},
};
</script>
<style scoped>
.div-img-gl {
display: none;
}
.nest-menu .el-menu-item {
height: 40px !important;
line-height: 40px !important;
margin-bottom: 5px;
}
#app .sidebar-container .nest-menu .is-active {
background-color: #fff !important;
}
#app .sidebar-container .nest-menu .el-menu-item {
padding: 0 !important;
min-width: 60px !important;
}
#app .sidebar-container .nest-menu .is-active:hover {
color: #fff !important;
}
>>> .el-submenu__title {
padding: 0 !important;
height: 90px !important;
line-height: 26px !important;
}
>>> .el-submenu.is-active .el-submenu__title .header {
border-radius: 6px;
color: #fff;
}
>>> .el-submenu .el-submenu__title .header {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
>>> .el-submenu .el-submenu__title .el-icon-arrow-down {
display: none;
}
</style>
<style>
#app .sidebar-container .theme-dark .is-active > .el-submenu__title {
color: #70483e !important;
background-color: #70483e !important;
}
#app .sidebar-container .theme-dark .is-active {
background-color: #5a332a;
}
#app .sidebar-container .el-menu {
box-sizing: border-box;
padding: 6px !important;
}
#app .sidebar-container .el-submenu .el-menu--inline {
padding: 0px !important;
background-color: #5a332a;
}
#app .sidebar-container .el-submenu__title:hover .header {
background-color: #5a3a32 !important;
}
</style>

38
acupuncture-前台/src/layout/components/Sidebar/index.vue

@ -1,12 +1,28 @@
<template>
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<div
:class="{ 'has-logo': showLogo }"
:style="{
backgroundColor:
settings.sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground,
}"
>
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
:background-color="
settings.sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground
"
:text-color="
settings.sideTheme === 'theme-dark'
? variables.menuColor
: variables.menuLightColor
"
:unique-opened="true"
:active-text-color="settings.theme"
:collapse-transition="false"
@ -51,7 +67,19 @@ export default {
},
isCollapse() {
return !this.sidebar.opened;
}
}
},
},
};
</script>
<style scoped>
>>> .is-active {
border-radius: 6px;
background-color: #fff !important;
}
>>> .is-active .div-img {
display: none;
}
>>> .is-active .div-img-gl {
display: block;
}
</style>

97
acupuncture-前台/src/layout/index.vue

@ -1,72 +1,83 @@
<template>
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
<div :class="{'fixed-header':fixedHeader}">
<navbar/>
<tags-view v-if="needTagsView"/>
<div
:class="classObj"
class="app-wrapper"
:style="{ '--current-color': theme }"
>
<!-- <div
v-if="device === 'mobile' && sidebar.opened"
class="drawer-bg"
@click="handleClickOutside"
/> -->
<sidebar v-if="!sidebar.hide" class="sidebar-container" />
<div
:class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }"
class="main-container"
>
<div :class="{ 'fixed-header': fixedHeader }">
<navbar />
<!-- <tags-view v-if="needTagsView"/> -->
</div>
<app-main/>
<app-main />
<right-panel>
<settings/>
<settings />
</right-panel>
</div>
</div>
</template>
<script>
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
import variables from '@/assets/styles/variables.scss'
import RightPanel from "@/components/RightPanel";
import { AppMain, Navbar, Settings, Sidebar, TagsView } from "./components";
import ResizeMixin from "./mixin/ResizeHandler";
import { mapState } from "vuex";
import variables from "@/assets/styles/variables.scss";
export default {
name: 'Layout',
name: "Layout",
components: {
AppMain,
Navbar,
RightPanel,
Settings,
Sidebar,
TagsView
TagsView,
},
mixins: [ResizeMixin],
computed: {
...mapState({
theme: state => state.settings.theme,
sideTheme: state => state.settings.sideTheme,
sidebar: state => state.app.sidebar,
device: state => state.app.device,
needTagsView: state => state.settings.tagsView,
fixedHeader: state => state.settings.fixedHeader
theme: (state) => state.settings.theme,
sideTheme: (state) => state.settings.sideTheme,
sidebar: (state) => state.app.sidebar,
device: (state) => state.app.device,
needTagsView: (state) => state.settings.tagsView,
fixedHeader: (state) => state.settings.fixedHeader,
}),
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
mobile: this.device === "mobile",
};
},
variables() {
return variables;
}
},
},
methods: {
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
}
this.$store.dispatch("app/closeSideBar", { withoutAnimation: false });
},
},
};
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/mixin.scss";
@import "~@/assets/styles/variables.scss";
@import "~@/assets/styles/mixin.scss";
@import "~@/assets/styles/variables.scss";
.app-wrapper {
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
@ -76,9 +87,9 @@ export default {
position: fixed;
top: 0;
}
}
}
.drawer-bg {
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
@ -86,26 +97,26 @@ export default {
height: 100%;
position: absolute;
z-index: 999;
}
}
.fixed-header {
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$base-sidebar-width});
transition: width 0.28s;
}
}
.hideSidebar .fixed-header {
.hideSidebar .fixed-header {
width: calc(100% - 54px);
}
}
.sidebarHide .fixed-header {
.sidebarHide .fixed-header {
width: 100%;
}
}
.mobile .fixed-header {
.mobile .fixed-header {
width: 100%;
}
}
</style>

5
acupuncture-前台/src/main.js

@ -12,7 +12,8 @@ import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
import { download, download1} from '@/utils/request'
import moment from 'moment';
import './assets/icons' // icon
import './permission' // permission control
@ -47,7 +48,9 @@ Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.download1 = download1
Vue.prototype.handleTree = handleTree
Vue.prototype.$moment = moment
// 全局组件挂载
Vue.component('DictTag', DictTag)

26
acupuncture-前台/src/router/index.js

@ -77,13 +77,13 @@ export const constantRoutes = [
{
path: "/patientFile",
component: Layout,
redirect: "index",
redirect: "patientFile",
children: [
{
path: "/patientIndex",
component: () => import("@/views/patientFile/index"),
name: "Index",
meta: { title: "患者档案", icon: "dashboard", },
name: "patientIndex",
meta: { title: "患者档案", icon: "dashboard" },
},
],
},
@ -96,13 +96,20 @@ export const constantRoutes = [
path: "/medicalIndex",
component: () => import("@/views/medicalFile/index"),
name: "medicalIndex",
meta: { title: "诊疗档案", icon: "dashboard", },
meta: { title: "诊疗档案", icon: "dashboard" },
},
{
path: "/medicalDetails",
component: () => import("@/views/medicalFile/details"),
name: "medicalDetails",
hidden: true,
meta: { title: "诊疗信息", icon: "dashboard" },
},
],
},
{
path: "/followFile",
meta: { title: "随访档案", icon: "dashboard", },
meta: { title: "随访档案", icon: "dashboard" },
component: Layout,
redirect: "followFile",
children: [
@ -110,33 +117,32 @@ export const constantRoutes = [
path: "/followIndex",
component: () => import("@/views/followFile/index"),
name: "followIndex",
meta: { title: "随访队列", icon: "dashboard", },
meta: { title: "随访队列", icon: "dashboard" },
},
{
path: "/followSubjects",
component: () => import("@/views/followFile/subjects"),
name: "followSubjects",
meta: { title: "随访对象", icon: "dashboard", },
meta: { title: "随访对象", icon: "dashboard" },
},
{
path: "/followWork",
component: () => import("@/views/followFile/work"),
name: "followWork",
meta: { title: "随访工单", icon: "dashboard", },
meta: { title: "随访工单", icon: "dashboard" },
},
],
},
{
path: "/user",
component: Layout,
hidden: true,
redirect: "noredirect",
children: [
{
path: "profile",
component: () => import("@/views/system/user/profile/index"),
name: "Profile",
meta: { title: "个人中心", icon: "user" },
meta: { title: "我的", icon: "user" },
},
],
},

62
acupuncture-前台/src/store/modules/app.js

@ -1,66 +1,68 @@
import Cookies from 'js-cookie'
import Cookies from "js-cookie";
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
opened: Cookies.get("sidebarStatus")
? !!+Cookies.get("sidebarStatus")
: true,
withoutAnimation: false,
hide: false
hide: false,
},
device: 'desktop',
size: Cookies.get('size') || 'medium'
}
device: "desktop",
size: Cookies.get("size") || "medium",
};
const mutations = {
TOGGLE_SIDEBAR: state => {
TOGGLE_SIDEBAR: (state) => {
if (state.sidebar.hide) {
return false;
return true;
}
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
state.sidebar.opened = true;
state.sidebar.withoutAnimation = true;
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
Cookies.set("sidebarStatus", 1);
} else {
Cookies.set('sidebarStatus', 0)
Cookies.set("sidebarStatus", 1);
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
Cookies.set("sidebarStatus", 1);
state.sidebar.opened = true;
state.sidebar.withoutAnimation = false;
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
state.device = device;
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
state.size = size;
Cookies.set("size", size);
},
SET_SIDEBAR_HIDE: (state, status) => {
state.sidebar.hide = status
}
}
state.sidebar.hide = status;
},
};
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
commit("TOGGLE_SIDEBAR");
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
commit("CLOSE_SIDEBAR", withoutAnimation);
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
commit("TOGGLE_DEVICE", device);
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
commit("SET_SIZE", size);
},
toggleSideBarHide({ commit }, status) {
commit('SET_SIDEBAR_HIDE', status)
}
}
commit("SET_SIDEBAR_HIDE", status);
},
};
export default {
namespaced: true,
state,
mutations,
actions
}
actions,
};

4
acupuncture-前台/src/store/modules/permission.js

@ -34,8 +34,8 @@ const permission = {
return new Promise((resolve) => {
// 向后端请求路由数据
getRouters().then((res) => {
const sdata = JSON.parse(JSON.stringify(res.data));
const rdata = JSON.parse(JSON.stringify(res.data));
const sdata = JSON.parse(JSON.stringify([]));
const rdata = JSON.parse(JSON.stringify([]));
const sidebarRoutes = filterAsyncRouter(sdata);
const rewriteRoutes = filterAsyncRouter(rdata, false, true);
const asyncRoutes = filterDynamicRoutes(dynamicRoutes);

57
acupuncture-前台/src/store/modules/settings.js

@ -1,42 +1,59 @@
import defaultSettings from '@/settings'
import defaultSettings from "@/settings";
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const {
sideTheme,
showSettings,
topNav,
tagsView,
fixedHeader,
sidebarLogo,
dynamicTitle,
} = defaultSettings;
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const storageSetting = JSON.parse(localStorage.getItem("layout-setting")) || "";
const state = {
title: '',
theme: storageSetting.theme || '#409EFF',
title: "",
theme: "#70483E",
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings,
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
}
tagsView:
storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader:
storageSetting.fixedHeader === undefined
? fixedHeader
: storageSetting.fixedHeader,
sidebarLogo:
storageSetting.sidebarLogo === undefined
? sidebarLogo
: storageSetting.sidebarLogo,
dynamicTitle:
storageSetting.dynamicTitle === undefined
? dynamicTitle
: storageSetting.dynamicTitle,
};
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
state[key] = value;
}
}
}
},
};
const actions = {
// 修改布局设置
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
commit("CHANGE_SETTING", data);
},
// 设置网页标题
setTitle({ commit }, title) {
state.title = title
}
}
state.title = title;
},
};
export default {
namespaced: true,
state,
mutations,
actions
}
actions,
};

1
acupuncture-前台/src/store/modules/user.js

@ -57,6 +57,7 @@ const user = {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.user
localStorage.setItem("user", JSON.stringify(user))
let avatar = user.avatar || ""
if (!isHttp(avatar)) {
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar

33
acupuncture-前台/src/utils/request.js

@ -148,5 +148,38 @@ export function download(url, params, filename, config) {
downloadLoadingInstance.close();
})
}
// 通用下载方法
export function download1(url, params, filename, config) {
downloadLoadingInstance = Loading.service({
text: "正在下载数据,请稍候",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
return service
.post(url, params, {
headers: { "Content-Type": "application/json;charset=utf-8" },
responseType: "blob",
})
.then(async (data) => {
const isBlob = blobValidate(data);
if (isBlob) {
const blob = new Blob([data]);
saveAs(blob, filename);
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg =
errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
Message.error(errMsg);
}
downloadLoadingInstance.close();
})
.catch((r) => {
console.error(r);
Message.error("下载文件出现错误,请联系管理员!");
downloadLoadingInstance.close();
});
}
export default service

BIN
acupuncture-前台/src/views/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 KiB

67
acupuncture-前台/src/views/followFile/index.vue

@ -70,6 +70,7 @@
align="center"
prop="name"
min-width="130"
fixed
/>
<el-table-column
label="随访方式"
@ -110,6 +111,20 @@
show-overflow-tooltip
min-width="100"
/>
<el-table-column
label="临近提醒时间(天)"
align="center"
prop="remindTime"
show-overflow-tooltip
min-width="130"
/>
<el-table-column
label="窗口期"
align="center"
prop="followWindowAdys"
show-overflow-tooltip
min-width="100"
/>
<el-table-column
label="状态"
align="center"
@ -118,14 +133,27 @@
min-width="100"
>
<template slot-scope="scope">
<span v-if="scope.row.status == 0" style="color: red">禁用</span>
<span v-if="scope.row.status == 1" style="color: green">启用</span>
<span v-if="scope.row.status == 0" style="color: #f56c6c">禁用</span>
<span v-else style="color: #67c23a">启用</span>
</template>
</el-table-column>
<el-table-column
label="类型"
align="center"
show-overflow-tooltip
min-width="100"
>
<template slot-scope="scope">
<span v-if="scope.row.type == 1">公共队列</span>
<span v-else-if="scope.row.status == 1" style="color: #67c23a"
>本院队列</span
>
</template>
</el-table-column>
<el-table-column
label="创建人/创建时间"
align="center"
min-width="130"
min-width="140"
fixed="right"
>
<template slot-scope="scope">
@ -142,6 +170,7 @@
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
:disabled="scope.row.type == 1"
>修改</el-button
>
<el-button
@ -149,6 +178,7 @@
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
:disabled="scope.row.type == 1"
>删除</el-button
>
</template>
@ -176,7 +206,7 @@
ref="form"
:model="form"
:rules="rules"
label-width="90px"
label-width="130px"
>
<el-form-item label="队列名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
@ -212,6 +242,12 @@
<el-form-item label="总月数" prop="followupMonth">
<el-input v-model="form.followupMonth" placeholder="请输入" />
</el-form-item>
<el-form-item label="临近提醒时间(天)" prop="remindTime">
<el-input v-model="form.remindTime" placeholder="请输入" />
</el-form-item>
<el-form-item label="窗口期" prop="followWindowAdys">
<el-input v-model="form.followWindowAdys" placeholder="请输入" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio :label="1">启用</el-radio>
@ -247,6 +283,7 @@ import {
followupAdd,
followupUpd,
followupDel,
commonQueue,
} from "@/api/followupFile";
export default {
name: "Notice",
@ -274,12 +311,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -317,6 +359,18 @@ export default {
frequency: [
{ required: true, message: "随访频次不能为空", trigger: "blur" },
],
followupMonth: [
{ required: true, message: "总月数不能为空", trigger: "blur" },
],
followWindowAdys: [
{ required: true, message: "窗口期不能为空", trigger: "blur" },
],
remindTime: [
{ required: true, message: "临近提醒时间不能为空", trigger: "blur" },
],
frequency: [
{ required: true, message: "随访频次不能为空", trigger: "blur" },
],
status: [{ required: true, message: "状态不能为空", trigger: "blur" }],
},
};
@ -334,11 +388,16 @@ export default {
crontabFill(value) {
this.form.frequency = value;
},
/** 查询公告列表 */
getList() {
this.loading = true;
followupQuery(this.queryParams).then((res) => {
let commonQueue = JSON.parse(localStorage.getItem("commonQueue"));
this.listDat = res.data.list;
commonQueue?.forEach((i) => {
this.listDat.unshift(i);
});
this.total = res.data.total;
this.loading = false;
});

267
acupuncture-前台/src/views/followFile/subjects.vue

@ -1,32 +1,20 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="68px">
<el-form-item label="随访队列" prop="queueId">
<el-select v-model="queryParams.param.queueId" placeholder="请选择">
<el-option
v-for="item in followupList"
:key="item.id"
:label="item.name"
:value="item.id"
>
<el-select v-model="queryParams.param.queueId" clearable placeholder="请选择">
<el-option v-for="item in followupList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="" prop="queueId">
<el-checkbox-group v-model="haveQueue">
<el-checkbox >未参加队列人员</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<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>
@ -34,103 +22,42 @@
</el-form>
<el-row :gutter="10" class="mb8">
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="listDat"
@selection-change="handleSelectionChange"
max-height="600"
>
<el-table v-loading="loading" :data="listDat" @selection-change="handleSelectionChange" max-height="600">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="姓名" align="center" prop="name" width="100" />
<el-table-column
label="性别"
align="center"
prop="gender"
show-overflow-tooltip
width="100"
>
<el-table-column label="姓名" align="center" prop="name" width="100" fixed />
<el-table-column fixed label="性别" align="center" prop="gender" show-overflow-tooltip min-width="100">
<template slot-scope="scope">
<span v-if="scope.row.gender == 0"></span>
<span v-if="scope.row.gender == 1"></span>
</template>
</el-table-column>
<el-table-column
label="出生日期"
align="center"
prop="birthDate"
show-overflow-tooltip
width="150"
>
<el-table-column fixed label="出生日期" align="center" prop="birthDate" show-overflow-tooltip min-width="150">
<template slot-scope="scope">
{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}
</template>
</el-table-column>
<el-table-column
label="民族"
align="center"
prop="ethnicity"
show-overflow-tooltip
width="100"
/>
<el-table-column
label="受教育年限"
align="center"
prop="educationYears"
show-overflow-tooltip
width="100"
/>
<el-table-column
label="手机号码"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
/>
<el-table-column
label="证件类型"
align="center"
prop="idCardType"
show-overflow-tooltip
width="200"
>
<el-table-column label="民族" align="center" prop="ethnicity" show-overflow-tooltip min-width="100" />
<el-table-column label="受教育年限" align="center" prop="educationYears" show-overflow-tooltip min-width="100" />
<el-table-column label="手机号码" align="center" prop="phone" show-overflow-tooltip min-width="150" />
<el-table-column label="证件类型" align="center" prop="idCardType" show-overflow-tooltip min-width="200">
<template slot-scope="scope">
{{ idCardTypeValue[scope.row.idCardType] }}
</template>
</el-table-column>
<el-table-column
label="证件号码"
align="center"
prop="idCard"
show-overflow-tooltip
width="180"
/>
<el-table-column
fixed="right"
label="随访队列"
align="center"
prop="queueList"
show-overflow-tooltip
width="180"
>
<el-table-column label="证件号码" align="center" prop="idCard" show-overflow-tooltip min-width="180" />
<el-table-column fixed="right" label="随访队列" align="center" prop="queueList" show-overflow-tooltip
min-width="180">
<template slot-scope="scope">
<div v-if="scope.row.queueList && scope.row.queueList.length">
{{ scope.row.queueList.map((i) => i.queueName).join(",") }}
</div>
</template>
</el-table-column>
<el-table-column
label="创建人/创建时间"
align="center"
width="130"
fixed="right"
>
<el-table-column label="创建人/创建时间" align="center" width="140" fixed="right">
<template slot-scope="scope">
<div>{{ scope.row.createBy }}</div>
<span>{{
@ -140,62 +67,25 @@
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="200">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>队列管理</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-tickets"
@click="handlePatient(scope.row)"
>患者档案</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-notebook-2"
@click="handleMedical(scope.row)"
>诊疗档案</el-button
>
<el-button size="mini" type="text" icon="el-icon-edit"
@click="handleUpdate(scope.row)">队列管理</el-button>
<el-button size="mini" type="text" icon="el-icon-tickets"
@click="handlePatient(scope.row)">患者档案</el-button>
<el-button size="mini" type="text" icon="el-icon-notebook-2"
@click="handleMedical(scope.row)">诊疗档案</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"
/>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改公告对话框 -->
<el-dialog
class="popup"
:title="title"
:visible.sync="open"
width="780px"
append-to-body
>
<el-form
class="formStep"
ref="form"
:model="form"
:rules="rules"
label-width="90px"
>
<el-dialog class="popup" :title="title" :visible.sync="open" width="780px" append-to-body>
<el-form class="formStep" ref="form" :model="form" :rules="rules" label-width="90px">
<el-form-item label="随访队列" prop="queueIdList">
<el-select v-model="form.queueIdList" multiple placeholder="请选择">
<el-option
v-for="item in followupList"
:key="item.id"
:label="item.name"
:value="item.id"
>
<el-option v-for="item in followupList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
@ -209,14 +99,17 @@
</template>
<script>
import { queryPatient, followupQuery, updPatient } from "@/api/followupFile";
export default {
import {
queryPatient,
followupQuery,
updPatient
} from "@/api/followupFile";
export default {
name: "Notice",
data() {
return {
fileList: [],
idCardType: [
{
idCardType: [{
label: "身份证",
value: 0,
},
@ -232,12 +125,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -253,17 +151,22 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 10,
param: {},
param: {
queueId: ''
},
},
haveQueue:'',
formDisabled: false,
importform: {},
//
form: {},
//
rules: {
queueIdList: [
{ required: true, message: "随访队列不能为空", trigger: "change" },
],
queueIdList: [{
required: true,
message: "随访队列不能为空",
trigger: "change"
}, ],
},
followupList: [], // 访
};
@ -277,9 +180,15 @@ export default {
getFollowupQuery() {
followupQuery({
pageNum: -1,
param: {},
param: {
status: 1
},
}).then((res) => {
this.followupList = res.data.list;
let commonQueue = JSON.parse(localStorage.getItem('commonQueue'))
commonQueue?.forEach(i => {
this.followupList.unshift(i)
})
});
},
@ -304,12 +213,21 @@ export default {
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.param.haveQueue = ''
if(this.haveQueue){
this.queryParams.param.haveQueue = 0
}
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams = {
param: {
queueId: ''
},
},
this.haveQueue = ''
this.handleQuery();
},
//
@ -322,7 +240,7 @@ export default {
handleUpdate(row) {
this.open = true;
this.title = "队列管理";
let queueList = row.queueList.map((item) => item.queueId);
let queueList = row.queueList?.map((item) => item.queueId) || [];
this.form = JSON.parse(
JSON.stringify({
...row,
@ -332,11 +250,19 @@ export default {
);
},
/** 跳转患者档案 */
handlePatient(row) {},
handlePatient(row) {
this.$router.push({
path: `/patientIndex?idCard=${row.idCard}`
})
},
/** 诊疗档案 */
handleMedical(row) {},
handleMedical(row) {
this.$router.push({
path: `/medicalIndex?idCard=${row.idCard}`
})
},
/** 提交按钮 */
submitForm: function () {
submitForm: function() {
this.$refs["form"].validate((valid) => {
if (valid) {
updPatient(this.form).then((response) => {
@ -353,8 +279,10 @@ export default {
const idList = row.id ? [row.id] : this.ids;
this.$modal
.confirm("是否确认删除当前选择的数据?")
.then(function () {
return patientDel({ idList: idList });
.then(function() {
return patientDel({
idList: idList
});
})
.then(() => {
this.getList();
@ -365,8 +293,7 @@ export default {
/** 导出按钮操作 */
handleExport() {
this.download(
"system/user/export",
{
"system/user/export", {
...this.queryParams.params,
},
`患者档案.xlsx`
@ -378,20 +305,22 @@ export default {
this.upload.open = true;
},
},
};
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.form-item-age {
.form-item-age {
display: flex;
align-items: center;
}
.form-item-age span {
}
.form-item-age span {
margin: 0 10px;
}
.form-item-age >>> .el-input {
}
.form-item-age>>>.el-input {
width: 100px;
}
}
</style>
<!-- >>> .el-input__inner {
padding: 0 15px !important;

283
acupuncture-前台/src/views/followFile/work.vue

@ -1,6 +1,51 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="" prop="keywords">
<el-input
style="width: 300px"
placeholder="姓名、全拼、简拼、手机号码、证件号码"
v-model="queryParams.param.keywords"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="childStatus">
<el-select
v-model="queryParams.param.childStatus"
clearable
placeholder="请选择"
>
<el-option
v-for="item in childStatusList[queryParams.param.status]"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</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>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
@ -19,30 +64,33 @@
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="工单id"
fixed
show-overflow-tooltip
align="center"
prop=""
width="100"
prop="id"
min-width="200"
/>
<el-table-column
fixed
label="随访队列"
show-overflow-tooltip
align=""
prop="name"
width="100"
align="center"
prop="queueName"
min-width="150"
/>
<el-table-column
fixed
label="患者姓名"
align="center"
prop="name"
width="100"
min-width="100"
/>
<el-table-column
label="性别"
align="center"
prop="gender"
show-overflow-tooltip
width="100"
min-width="60"
>
<template slot-scope="scope">
<span v-if="scope.row.gender == 0"></span>
@ -55,43 +103,53 @@
align="center"
prop="age"
show-overflow-tooltip
width="150"
min-width="60"
/>
<el-table-column
label="证件号码"
align="center"
prop="idCard"
show-overflow-tooltip
width="180"
min-width="180"
/>
<el-table-column
label="手机号码"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column
label="随访序号"
label="随访次数"
align="center"
prop="phone"
prop="times"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column
label="开始时间"
align="center"
prop="startTime"
show-overflow-tooltip
width="150"
/>
min-width="150"
>
<template slot-scope="scope">
<span>{{
parseTime(scope.row.startTime, "{y}-{m}-{d} {h}:{i}")
}}</span>
</template>
</el-table-column>
<el-table-column
label="结束时间"
align="center"
prop="endTime"
show-overflow-tooltip
width="150"
/>
min-width="150"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, "{y}-{m}-{d} {h}:{i}") }}</span>
</template>
</el-table-column>
<!--待随访 随访状态待随访/即将超期/超期 -->
<!--已随访 随访状态已随访/超随访期 -->
<!--待随访 随访状态待随访 -->
@ -100,47 +158,63 @@
align="center"
prop="phone"
show-overflow-tooltip
width="150"
min-width="150"
fixed="right"
>
<template slot-scope="scope">
{{ status[scope.row.status] }}
<span :class="classStatus[scope.row.status]">{{
status[scope.row.status]
}}</span>
</template>
</el-table-column>
<!-- <el-table-column
label="失访状态"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
/> -->
<el-table-column
v-if="queryParams.param.status == 2"
label="失访原因"
align="center"
prop="reason"
show-overflow-tooltip
width="150"
width="200"
/>
<el-table-column fixed="right" label="操作" align="center" width="150">
<el-table-column fixed="right" label="操作" align="center" width="180">
<template slot-scope="scope">
<!-- :disabled="scope.row.status !== '0'" -->
<!-- 待随访 -->
<div v-if="queryParams.param.status == 0">
<el-button
:disabled="scope.row.status !== '0'"
size="mini"
type="text"
icon="el-icon-s-check"
@click="handleFollow(scope.row)"
>
随访
随访
</el-button>
<el-button
:disabled="scope.row.status !== '0'"
size="mini"
type="text"
icon="el-icon-s-release"
@click="handleLossFollow(scope.row)"
>
失访
标记失访
</el-button>
</div>
<!-- 随访 -->
<el-button
v-if="queryParams.param.status == 1"
size="mini"
type="text"
icon="el-icon-s-check"
@click="handleDetails(scope.row)"
>
查看详情
</el-button>
<!-- 失访 -->
<el-button
v-if="queryParams.param.status == 2"
size="mini"
type="text"
icon="el-icon-s-check"
@click="handleBeFollow(scope.row)"
>
标记待随访
</el-button>
</template>
</el-table-column>
@ -157,7 +231,7 @@
<!-- 失访 -->
<el-dialog
class="popup"
title="失访"
title="标记失访"
:visible.sync="open"
width="780px"
append-to-body
@ -169,9 +243,9 @@
:rules="rules"
label-width="90px"
>
<el-form-item label="随访次数" prop="times">
<!-- <el-form-item label="随访次数" prop="times">
<el-input v-model="form.times" placeholder="请输入" />
</el-form-item>
</el-form-item> -->
<el-form-item label="失访原因" prop="reason">
<el-select v-model="form.reason" placeholder="请选择">
<el-option-group
@ -211,10 +285,15 @@
label-width="90px"
>
<el-form-item label="随访人" prop="followuper">
<el-input v-model="form.followuper" placeholder="请输入" />
<el-input
:disabled="open1Disabled"
v-model="form.followuper"
placeholder="请输入"
/>
</el-form-item>
<el-form-item label="随访时间" prop="followupTime">
<el-date-picker
:disabled="open1Disabled"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="form.followupTime"
@ -223,15 +302,22 @@
>
</el-date-picker>
</el-form-item>
<el-form-item label="随访次数" prop="times">
<!-- <el-form-item label="随访次数" prop="times">
<el-input v-model="form.times" placeholder="请输入" />
</el-form-item>
</el-form-item> -->
<el-form-item label="随访内容" prop="followupText">
<el-input v-model="form.followupText" placeholder="请输入" />
<el-input
:disabled="open1Disabled"
type="textarea"
v-model="form.followupText"
placeholder="请输入"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm1"> </el-button>
<el-button type="primary" @click="submitForm1" v-if="!open1Disabled"
> </el-button
>
<el-button @click="open1 = false"> </el-button>
</div>
</el-dialog>
@ -239,7 +325,12 @@
</template>
<script>
import { queryTask, updStatus, followPatient } from "@/api/followupFile";
import {
queryTask,
updStatus,
followPatient,
followStatus,
} from "@/api/followupFile";
export default {
name: "Notice",
data() {
@ -303,6 +394,29 @@ export default {
4: "超期未随访",
5: "超期已随访",
},
classStatus: {
3: "status3",
4: "status4",
5: "status4",
},
childStatusList: {
0: [
{
label: "即将超期",
value: 1,
},
{
label: "超期未随访",
value: 2,
},
],
1: [
{
label: "超期已随访",
value: 2,
},
],
},
idCardType: [
{
label: "身份证",
@ -320,12 +434,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -337,6 +456,7 @@ export default {
title: "", //
open: false, //
open1: false, //
open1Disabled: false,
importOpen: false, //
//
queryParams: {
@ -344,6 +464,8 @@ export default {
pageSize: 10,
param: {
status: "0",
childStatus: "",
keywords: "",
},
},
formDisabled: false,
@ -353,29 +475,52 @@ export default {
//
rules: {
followuper: [
{ required: true, message: "随访人不能为空", trigger: "blur" },
{
required: true,
message: "随访人不能为空",
trigger: "blur",
},
],
followupTime: [
{ required: true, message: "随访时间不能为空", trigger: "change" },
{
required: true,
message: "随访时间不能为空",
trigger: "change",
},
],
followupText: [
{ required: true, message: "随访内容不能为空", trigger: "blur" },
{
required: true,
message: "随访内容不能为空",
trigger: "blur",
},
],
times: [
{ required: true, message: "随访次数不能为空", trigger: "blur" },
{
required: true,
message: "随访次数不能为空",
trigger: "blur",
},
],
reason: [
{ required: true, message: "失访原因不能为空", trigger: "change" },
{
required: true,
message: "失访原因不能为空",
trigger: "change",
},
],
},
};
},
created() {
let idCard = this.$route.query.idCard;
this.queryParams.param.keywords = idCard || "";
this.getList();
},
methods: {
handleClick(tab, event) {
this.queryParams.param.childStatus = "";
this.getList();
},
/** 查询公告列表 */
@ -404,7 +549,8 @@ export default {
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams.param.keywords = "";
this.queryParams.param.childStatus = "";
this.handleQuery();
},
//
@ -421,6 +567,7 @@ export default {
/** 随访 */
handleFollow(row) {
this.open1 = true;
this.open1Disabled = false;
this.form = {
id: row.id,
followuper: "",
@ -429,12 +576,36 @@ export default {
followupText: "",
};
},
/** 失访 */
/** 标记失访 */
handleLossFollow(row) {
this.open = true;
this.form = JSON.parse(JSON.stringify(row));
this.form.status = 2;
},
handleDetails(row) {
this.open1 = true;
this.open1Disabled = true;
this.form = JSON.parse(JSON.stringify(row));
},
// 访
handleBeFollow(row) {
let data = {
id: row.id,
status: 0,
};
this.$modal
.confirm(`是否确认将该患者(${row.name})标记为待随访?`)
.then(function () {
return followStatus(data);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("操作成功");
})
.catch((err) => {
console.log("err", err);
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
@ -485,7 +656,9 @@ export default {
this.$modal
.confirm("是否确认删除当前选择的数据?")
.then(function () {
return patientDel({ idList: idList });
return patientDel({
idList: idList,
});
})
.then(() => {
this.getList();
@ -513,13 +686,21 @@ export default {
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.status3 {
color: orange;
}
.status4 {
color: red;
}
.form-item-age {
display: flex;
align-items: center;
}
.form-item-age span {
margin: 0 10px;
}
.form-item-age >>> .el-input {
width: 100px;
}

27
acupuncture-前台/src/views/index.vue

@ -4,7 +4,6 @@
<div>
<el-card shadow="always">
<search
@radio-change="radioChange"
@picker-change="pickerChage"
title="患者信息统计"
type="1"
@ -15,7 +14,6 @@
<div>
<el-card shadow="always">
<search
@radio-change="radioChange"
@picker-change="pickerChage"
title="诊疗信息统计"
type="2"
@ -23,17 +21,22 @@
</el-card>
<JM ref="JM"></JM>
</div>
<!-- <div>
<div>
<el-card shadow="always">
<search
@radio-change="radioChange"
@picker-change="pickerChage"
title="血管内治疗统计"
title="治疗类型统计"
type="3"
></search>
</el-card>
<XGZL ref="XGZL"></XGZL>
</div> -->
</div>
<div>
<el-card shadow="always">
<search @picker-change="pickerChage" title="随访统计" type="4"></search>
</el-card>
<follow ref="follow"></follow>
</div>
</div>
</template>
@ -43,6 +46,7 @@ import search from "@/views/indexCom/query";
import patient from "@/views/indexCom/patient";
import JM from "@/views/indexCom/JM";
import XGZL from "@/views/indexCom/XGZL";
import follow from "@/views/indexCom/follow";
export default {
name: "Index",
components: {
@ -50,6 +54,7 @@ export default {
patient,
JM,
XGZL,
follow,
},
data() {
return {};
@ -69,9 +74,11 @@ export default {
},
methods: {
resize() {
console.log(111);
// this.$refs.patient.getRenew();
// this.$refs.JM.getRenew();
// this.$refs.XGZL.getRenew();
// this.$refs.follow.getRenew();
},
//
radioChange(_data, _type, _timeType) {
@ -92,6 +99,9 @@ export default {
if (_type == 3) {
this.$refs.XGZL.statistics(_data, param);
}
if (_type == 4) {
this.$refs.follow.statistics(_data, param);
}
},
},
directives: {
@ -102,6 +112,7 @@ export default {
// elbinding
let width = "",
height = "";
function isReize() {
const style = document.defaultView.getComputedStyle(el);
if (width !== style.width) {
@ -124,6 +135,7 @@ export default {
background: #f3f5f9;
min-height: 100vh;
}
.home {
blockquote {
padding: 10px 20px;
@ -131,12 +143,14 @@ export default {
font-size: 17.5px;
border-left: 5px solid #eee;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.col-item {
margin-bottom: 20px;
}
@ -190,6 +204,7 @@ export default {
>>> .el-card {
margin-bottom: 16px;
}
>>> .el-card__body {
padding: 10px 20px;
}

292
acupuncture-前台/src/views/indexCom/JM.vue

@ -13,22 +13,17 @@
</div>
</el-card>
</div>
<div style="flex: 1">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">体系分布</span>
<div class="dis">
</div>
<span class="header-title">体型分布</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="system" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
@ -40,21 +35,42 @@
</div>
</el-card>
</div>
<div style="flex: 1">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">体态评估TAPS</span>
<div class="dis">
</div>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="posture" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">失眠评估PHQ-9</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="agrypnia" style="width: 100%"></div>
</div>
<div class="app-container">
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">焦虑HAMD-24</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="anxiety" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
<!-- <div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
@ -71,8 +87,7 @@
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">焦虑HAMD-24</span>
<div class="dis">
</div>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="anxiety" style="width: 100%"></div>
@ -80,24 +95,24 @@
</el-card>
</div>
</div>
</div>
</div> -->
</div>
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import {
zlInfo
} from "@/api/indexCom.js";
import {
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { zlInfo } from "@/api/indexCom.js";
import {
diagnoseEcharts,
systemEcharts,
physiqueEcharts,
postureEcharts
} from "./index";
export default {
postureEcharts,
agrypniaEcharts,
anxietyEcharts,
} from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
@ -109,35 +124,37 @@
endTime: "",
},
},
loading: false,
diagnoseValue: null, //
systemValue: null, //
physiqueValue: null, //
postureValue:null, //
postureValue: null, //
agrypniaValue: null, //
anxietyValue: null, //
//
systemObj: {
"yxfpz": "隐形肥胖型", //
"zfgdx": "脂肪过多型", //
"fpx": "肥胖型", //
"jrbzx": "肌肉不足型", //
"jkjcx": "健康匀称型", //
"czjrx": "超重肌肉型", //
"xsx": "消瘦型", //
"dzfx": "低脂肪型", //
"ydyx": "运动员型", //
yxfpz: "隐形肥胖型", //
zfgdx: "脂肪过多型", //
fpx: "肥胖型", //
jrbzx: "肌肉不足型", //
jkjcx: "健康匀称型", //
czjrx: "超重肌肉型", //
xsx: "消瘦型", //
dzfx: "低脂肪型", //
ydyx: "运动员型", //
},
//
physiqueObj: {
"phz": "平和质", //
"qxz": "气虚质", //
"yangxz": "阳虚质", //
"yinxz": "阴虚质", //
"tsz": "痰湿质", //湿
"srz": "湿热质", //湿
"xyz": "血瘀质", //
"qyz": "气郁质", //
"tlz": "特禀质", //
phz: "平和质", //
qxz: "气虚质", //
yangxz: "阳虚质", //
yinxz: "阴虚质", //
tsz: "痰湿质", //湿
srz: "湿热质", //湿
xyz: "血瘀质", //
qyz: "气郁质", //
tlz: "特禀质", //
},
};
},
@ -155,60 +172,73 @@
async getData() {
try {
await zlInfo(this.queryParams).then((res) => {
const {
jlfb,
smfb,
sort,
ttfb,
txfb,
zytz
} = res.data
const { jlfb, smfb, sort, ttfb, txfb, zytz } = res.data;
//
this.diagnoseValue = sort.sort((a, b) => a.total - b.total)
this.handleDiagnose()
this.diagnoseValue = sort?.sort((a, b) => a.total - b.total);
this.handleDiagnose();
//
this.systemValue = []
delete txfb.total
this.systemValue = [];
delete txfb?.total;
for (let key in txfb) {
let data = {
name: this.systemObj[key],
value: txfb[key]
}
this.systemValue.push(data)
value: txfb[key] || 0,
};
this.systemValue.push(data);
}
this.handleSystem()
this.handleSystem();
//
this.physiqueValue = []
delete zytz.total
this.physiqueValue = [];
delete zytz?.total;
for (let key in zytz) {
let data = {
name: this.physiqueObj[key],
value: zytz[key],
}
this.physiqueValue.push(data)
value: zytz[key] || 0,
};
this.physiqueValue.push(data);
}
this.handlePhysique()
this.handlePhysique();
//
this.postureValue = [{
value: ttfb.score1,
name: "1分"
},{
value: ttfb.score2,
name: "2分"
},{
value: ttfb.score3,
name: "3分"
},{
value: ttfb.score4,
name: "4分"
},{
value: ttfb.score5,
name: "5分"
}]
this.handlePosture()
});
this.postureValue = [
{
value: ttfb?.score1 || 0,
name: "1分",
},
{
value: ttfb?.score2 || 0,
name: "2分",
},
{
value: ttfb?.score3 || 0,
name: "3分",
},
{
value: ttfb?.score4 || 0,
name: "4分",
},
{
value: ttfb?.score5 || 0,
name: "5分",
},
];
this.handlePosture();
// PHQ-9
this.agrypniaValue = [];
for (let key in smfb) {
this.agrypniaValue.push(smfb[key]);
}
this.handleAgrypnia();
//
this.anxietyValue = [];
for (let key in jlfb) {
this.anxietyValue.push(jlfb[key]);
}
this.handleAnxiety();
this.loading = false;
} catch (e) {}
});
} catch (e) {
console.log("诊疗信息", e);
}
},
//
handleDiagnose() {
@ -216,7 +246,7 @@
return item.total;
});
diagnoseEcharts.yAxis.data = this.diagnoseValue?.map((item) => {
return item.type;
return item.diseaseName;
});
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("diagnose"), null, {
@ -263,7 +293,7 @@
},
//
handlePosture() {
postureEcharts.series[0].data = this.postureValue
postureEcharts.series[0].data = this.postureValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("posture"), null, {
height: 300,
@ -282,81 +312,109 @@
endTime: _data[1] + " " + "23:59:59",
};
},
//
handleAgrypnia() {
agrypniaEcharts.series[0].data = this.agrypniaValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("agrypnia"), null, {
height: 300,
});
myChart.setOption(agrypniaEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleAnxiety() {
anxietyEcharts.series[0].data = this.anxietyValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("anxiety"), null, {
height: 300,
});
myChart.setOption(anxietyEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
getRenew() {
this.Linepatient();
this.columnar();
this.handleDiagnose();
this.handleSystem();
this.handlePhysique();
this.handlePosture();
this.handleAgrypnia();
this.handleAnxiety();
},
},
};
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
>>>.el-card__body {
>>> .el-card__body {
padding: 10px 0 !important;
}
}
.dis {
.dis {
display: flex;
}
}
.header-title {
.header-title {
font-size: 18px;
}
}
.title-box {
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
}
.dian-box {
.dian-box {
align-items: center;
}
}
.dian {
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
}
.title-box {
.title-box {
justify-content: space-between;
}
}
.>>>.el-radio--small.is-bordered {
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
}
>>>.el-radio__input {
>>> .el-radio__input {
display: none;
}
}
>>>.el-radio__label {
>>> .el-radio__label {
padding-left: 5px;
}
}
.app-container {
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
}
.title {
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
}
.title-bor {
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
}
</style>

344
acupuncture-前台/src/views/indexCom/XGZL.vue

@ -1,87 +1,139 @@
<template>
<div>
<div class="app-container">
<!-- 静脉溶栓 数据对比 -->
<div class="dis" style="width: 100%">
<div style="flex: 1">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">血管内治疗率 </span>
<span class="header-title">治疗类型分布</span>
<div class="dis">
<div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #c6a268"></span>
中西医结合
</div>
<span class="dian" style="background: #d8d8d8"></span>
纯中医
</div>
</div>
</div>
<!-- 统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="XGZL" style="width: 100%"></div>
<div id="healType" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-left: 20px">
<!-- <div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">数据对比</span>
<div class="dis">
<div class="dian-box dis">
<span class="dian" style="background: #00d1a1"></span>
桥接治疗人数
<span class="header-title">病种方法分布</span>
<div class="dis"></div>
</div>
<div class="dian-box dis">
<span class="dian" style="background: #4f8bff"></span>
非桥接治疗人数
<div style="height: 300px" v-loading="loading">
<div id="diseaseMethod" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1;">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">病种穴位分布</span>
<div class="dis">
</div>
</div>
<!-- 统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="SJDB" style="width: 100%"></div>
<div id="acupoint" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
<!-- DNT分布 sICH发生率 -->
<div class="dis" style="width: 100%">
<div style="flex: 1">
</div> -->
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">DPT</span>
<span class="header-title">治疗效果</span>
<div class="dis">
<div class="dian-box dis">
<span class="dian" style="background: #00d1a1"></span> 60 min
<div class="dian-box dis">
<span class="dian" style="background: #c6a268"></span>
治愈
</div>
<div class="dian-box dis">
<span class="dian" style="background: #ffcd6c"></span> 90 min
<span class="dian" style="background: #906c4a"></span>
显效
</div>
<div class="dian-box dis">
<span class="dian" style="background: #a794fe"></span> >90 min
<span class="dian" style="background: #70483e"></span>
好转
</div>
<div class="dian-box dis">
<span class="dian" style="background: #c7bdb1"></span>
无效
</div>
</div>
</div>
</div>
<!-- 统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="DPT" style="width: 100%"></div>
<div id="effect" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-left: 20px">
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">诊疗费用分布</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="cost" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
<!-- <div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">PRT</span>
<span class="header-title">治疗效果</span>
<div class="dis">
<div class="dian-box dis">
<span class="dian" style="background: #a794fe"></span> 60 min
<div class="dian-box dis">
<span class="dian" style="background: #5C7BD9"></span>
治愈
</div>
<div class="dian-box dis">
<span class="dian" style="background: #4f8bff"></span> 90 min
<span class="dian" style="background: #91CC75"></span>
显效
</div>
<div class="dian-box dis">
<span class="dian" style="background: #ffcd6c"></span> >90 min
<span class="dian" style="background: #FAC858"></span>
好转
</div>
<div class="dian-box dis">
<span class="dian" style="background: #EE6666"></span>
无效
</div>
</div>
</div>
</div>
<!-- 统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="RPT" style="width: 100%"></div>
<div id="effect" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">诊疗费用分布</span>
<div class="dis">
</div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="cost" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div> -->
</div>
</template>
@ -89,35 +141,41 @@
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { zlType } from "@/api/indexCom.js";
import {
queryDptResult,
queryRptResult,
dataComparison,
queryXgzlLv,
} from "@/api/indexCom.js";
import { XGZL, XGSJDB, DPT, RPT } from "./index";
healTypeEcharts,
diseaseMethodEcharts,
effectEcharts,
costEcharts,
} from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
data() {
return {
loading: false,
DPTvalue: null,
RPTvalue: null,
SJDBvalue: null,
XGZLvalue: null,
queryParams: {
param: {
timeType: 4,
startTime: "",
endTime: "",
},
},
loading: false,
healTypeValue: null, //
diseaseMethod: null, //
effectValue: null, //
costValue: null, //
effectObj: {
zy: "治愈", //
xx: "显效", //
hz: "好转", //
wx: "无效", //
},
};
},
created() {
// this.getData();
// this.Linepatient();
this.getData();
},
methods: {
statistics(_data, _type) {
@ -125,123 +183,117 @@ export default {
this.loading = true;
this.getData(); //
},
//
//
async getData() {
try {
// /DNT
await queryDptResult(this.queryParams).then((res) => {
this.DPTvalue = res.data;
console.log("this.DPTvalue: ", this.DPTvalue);
this.DPT();
});
//RPT
await queryRptResult(this.queryParams).then((res) => {
this.RPTvalue = res.data;
this.RPT();
});
//
// await dataComparison(this.queryParams).then((res) => {
// console.log("dataComparison: ", dataComparison);
// this.SJDBvalue = res.date;
// this.SJDB();
// });
await dataComparison(this.queryParams).then((res) => {
console.log("res1111: ", res);
this.SJDBvalue = res.data;
this.SJDB();
});
await queryXgzlLv(this.queryParams).then((res) => {
this.XGZLvalue = res.data;
this.XGZL();
});
await zlType(this.queryParams).then((res) => {
const { bzfffb, bzxwfb, zlfy, zllxtj, zlxwfb } = res.data;
//
this.healTypeValue = [
{
value: zllxtj?.zxyjh || 0,
name: "中西医结合",
},
{
value: zllxtj?.czy || 0,
name: "纯中医",
},
];
this.handleHealType();
//
// let diseaseMethod = []
// let index = 0
// for(let i in bzfffb){
// for(let k in bzfffb[i]){
// console.log(bzfffb[i][k])
// }
// index ++
// }
// this.handleDiseaseMethod()
//
this.effectValue = [
{
name: "治愈",
value: zlxwfb?.zy || 0,
},
{
name: "显效",
value: zlxwfb?.xx || 0,
},
{
name: "好转",
value: zlxwfb?.hz || 0,
},
{
name: "无效",
value: zlxwfb?.wx || 0,
},
];
this.handleEffect();
//
this.costValue = [
zlfy?.score1 || 0,
zlfy?.score2 || 0,
zlfy?.score3 || 0,
zlfy?.score4 || 0,
zlfy?.score5 || 0,
];
this.handleCost();
this.loading = false;
});
} catch (e) {
console.log(e, "e");
console.log("治疗类型", e);
}
},
//
SJDB(_statData) {
XGSJDB.series[0].data = this.SJDBvalue?.map((item) => {
return item.qiaojie; //
});
XGSJDB.series[1].data = this.SJDBvalue?.map((item) => {
return item.falseQiaojie; //
});
XGSJDB.xAxis[0].data = this.SJDBvalue?.map((item) => {
return item.date; //X
});
//
handleHealType() {
healTypeEcharts.series[0].data = this.healTypeValue;
this.$nextTick(() => {
// domecharts
var myChart = echarts.init(document.getElementById("SJDB"), null, {
var myChart = echarts.init(document.getElementById("healType"), null, {
height: 300,
});
myChart.setOption(XGSJDB, true);
myChart.setOption(healTypeEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
XGZL() {
XGZL.series[0].data = this.XGZLvalue?.map((item) => {
return item.decimal; //
});
XGZL.xAxis.data = this.XGZLvalue?.map((item) => {
return item.date; //X
});
//
handleDiseaseMethod() {
// diseaseMethodEcharts.series[0].data = this.diseaseMethod
this.$nextTick(() => {
// domecharts
var myChart = echarts.init(document.getElementById("XGZL"), null, {
var myChart = echarts.init(
document.getElementById("diseaseMethod"),
null,
{
height: 300,
});
myChart.setOption(XGZL, true);
}
);
myChart.setOption(diseaseMethodEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
// DPT
DPT() {
DPT.series[0].data = this.DPTvalue?.map((item) => {
return item.dy60; //<= 60
});
DPT.series[1].data = this.DPTvalue?.map((item) => {
return item.dy90; //<= 90
});
DPT.series[2].data = this.DPTvalue?.map((item) => {
return item.other; //<= 90
});
DPT.xAxis[0].data = this.DPTvalue?.map((item) => {
return item.date; //X
});
//
handleEffect() {
effectEcharts.series[0].data = this.effectValue;
this.$nextTick(() => {
// domecharts
var myChart = echarts.init(document.getElementById("DPT"), null, {
var myChart = echarts.init(document.getElementById("effect"), null, {
height: 300,
});
myChart.setOption(DPT, true);
myChart.setOption(effectEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
// RPT
RPT(_statData) {
RPT.series[0].data = this.RPTvalue?.map((item) => {
return item.dy60; //<= 60
});
RPT.series[1].data = this.RPTvalue?.map((item) => {
return item.dy90; //<= 90
});
RPT.series[2].data = this.RPTvalue?.map((item) => {
return item.other; //> 90
});
RPT.xAxis[0].data = this.RPTvalue?.map((item) => {
return item.date; //X
});
//
handleCost() {
costEcharts.series[0].data = this.costValue;
this.$nextTick(() => {
// domecharts
var myChart = echarts.init(document.getElementById("RPT"), null, {
var myChart = echarts.init(document.getElementById("cost"), null, {
height: 300,
});
myChart.setOption(RPT, true);
myChart.setOption(costEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
@ -251,17 +303,15 @@ export default {
_data[0] = this.$moment(_data[0]).format("YYYY-MM-DD");
_data[1] = this.$moment(_data[1]).format("YYYY-MM-DD");
this.queryParams.param = {
timeType: _type,
startTime: _data[0] + " " + "00:00:00",
endTime: _data[1] + " " + "23:59:59",
};
},
//
getRenew() {
this.SJDB(); //
this.XGZL(); //
this.DPT();
this.RPT();
this.handleHealType();
this.handleEffect();
this.handleCost();
},
},
};
@ -271,19 +321,24 @@ export default {
>>> .el-card__body {
padding: 10px 0 !important;
}
.dis {
display: flex;
}
.header-title {
font-size: 18px;
}
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
.dian-box {
align-items: center;
}
.dian {
display: inline-block;
width: 16px;
@ -291,28 +346,37 @@ export default {
border-radius: 50%;
margin: 0 10px;
}
.title-box {
justify-content: space-between;
}
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;

261
acupuncture-前台/src/views/indexCom/follow.vue

@ -0,0 +1,261 @@
<template>
<div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">随访队列分布</span>
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="follow" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">失访原因分布</span>
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="lossFollow" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { sffb, sftj } from "@/api/indexCom.js";
import { followEcharts, lossFollowEcharts } from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
data() {
return {
loading: false,
followValue: [], //
lossFollowValue: [], //
queryParams: {
param: {
startTime: "",
endTime: "",
},
},
};
},
created() {
// this.Linepatient()
this.getData();
},
methods: {
statistics(_data, _type) {
this.initial(_data, _type); //
this.loading = true;
this.getData(); //
},
//
async getData() {
try {
this.followValue = {};
await sffb(this.queryParams).then((res) => {
res.data.forEach((i) => {
let data = [i.dsf, i.ljsf, i.cqsf, i.zc];
this.followValue[i.queueName] = data;
});
this.handleFollow();
});
await sftj(this.queryParams).then((res) => {
this.lossFollowValue = res.data;
this.handleLossFollow();
});
this.loading = false;
} catch (e) {
console.log("随访", e);
}
},
//
handleFollow() {
followEcharts.series = [];
let colorArr = [
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
];
let index = 0;
for (let key in this.followValue) {
let series = {
name: key,
data: this.followValue[key],
type: "bar",
barMaxWidth: 24, //
color: colorArr[index],
};
followEcharts.series.push(series);
index++;
}
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("follow"), null, {
height: 300,
});
myChart.setOption(followEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
// 访
handleLossFollow() {
lossFollowEcharts.series[0].data = this.lossFollowValue?.map((item) => {
return item.num;
});
lossFollowEcharts.xAxis.data = this.lossFollowValue?.map((item) => {
return item.reason;
});
this.$nextTick(() => {
var myChart = echarts.init(
document.getElementById("lossFollow"),
null,
{
height: 300,
}
);
myChart.setOption(lossFollowEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
initial(_data, _type) {
_data[0] = this.$moment(_data[0]).format("YYYY-MM-DD");
_data[1] = this.$moment(_data[1]).format("YYYY-MM-DD");
this.queryParams.param = {
startTime: _data[0] + " " + "00:00:00",
endTime: _data[1] + " " + "23:59:59",
};
},
//
getRenew() {
this.handleFollow();
this.handleLossFollow();
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
>>> .el-card__body {
padding: 10px 0 !important;
}
.dis {
display: flex;
}
.header-title {
font-size: 18px;
}
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
.dian-box {
align-items: center;
}
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
.title-box {
justify-content: space-between;
}
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
</style>

BIN
acupuncture-前台/src/views/indexCom/image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

929
acupuncture-前台/src/views/indexCom/index.js

File diff suppressed because it is too large

232
acupuncture-前台/src/views/indexCom/patient.vue

@ -9,22 +9,42 @@
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="patienty" style="width: 100%"></div>
<div
style="
height: 300px;
display: flex;
align-items: center;
justify-content: center;
"
v-loading="loading"
>
<div class="div-hz">
<div class="div-hz-icon">
<img src="./image.png" alt="" width="60px" height="60px" />
</div>
<div class="div-hz-num">
<div class="">
{{ HZXXvalue[0].value || 0 }}<span></span>
</div>
<div class="hz-num-title">患者总数</div>
</div>
</div>
<!-- <div id="patienty" style="width: 100%"></div> -->
</div>
</el-card>
</div>
<div style="flex: 1">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">性别数量</span>
<div class="dis">
<div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #4f8bff"></span>
<span class="dian" style="background: #70483e"></span>
</div>
<span class="dian" style="background: #fe4943"></span>
<span class="dian" style="background: #c7bdb1"></span>
</div>
</div>
@ -35,10 +55,6 @@
</div>
</el-card>
</div>
</div>
</div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
@ -78,21 +94,12 @@
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import {
patientTotal,
queryByDatePatient
} from "@/api/indexCom.js";
import {
HZXX,
HZXXSJFX,
gende,
ageEcharts,
diseaseEcharts
} from "./index";
export default {
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { patientTotal, queryByDatePatient } from "@/api/indexCom.js";
import { HZXX, HZXXSJFX, gende, ageEcharts, diseaseEcharts } from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
@ -110,25 +117,25 @@
},
},
jwbzObj: {
"gxy": "高血压", //
"nxgb": "脑血管病", //
"exzl": "恶性肿瘤", //
"gxb": "冠心病", //
"jsjb": "精神疾病", //
"whsezcky": "胃和十二指肠溃疡", //
"fpz": "肥胖症", //
"gzssz": "骨质疏松症", //
"ycxXtxjb": "遗传性、先天性疾病", //
"tnb": "糖尿病", //尿
"mxfxjb": "慢性肺系疾病", //
"gzxz": "高脂血症", //
"gzjb": "肝脏疾病", //
"gmxjb": "过敏性疾病", //
"gjy": "关节炎", //
"tf": "痛风", //
"sySb": "肾炎、肾病", //
"other": "其他" //
}
gxy: "高血压", //
nxgb: "脑血管病", //
exzl: "恶性肿瘤", //
gxb: "冠心病", //
jsjb: "精神疾病", //
whsezcky: "胃和十二指肠溃疡", //
fpz: "肥胖症", //
gzssz: "骨质疏松症", //
ycxXtxjb: "遗传性、先天性疾病", //
tnb: "糖尿病", //尿
mxfxjb: "慢性肺系疾病", //
gzxz: "高脂血症", //
gzjb: "肝脏疾病", //
gmxjb: "过敏性疾病", //
gjy: "关节炎", //
tf: "痛风", //
sySb: "肾炎、肾病", //
other: "其他", //
},
};
},
created() {
@ -146,42 +153,52 @@
try {
await patientTotal(this.queryParams).then((res) => {
//
this.HZXXvalue = [{
this.HZXXvalue = [
{
value: res.data.totalPatients,
name: "患者总数"
}, ];
name: "患者总数",
},
];
//
this.gendeValue = [{
value: res.data.totalPatients,
name: "男"
this.gendeValue = [
{
value: res.data.gender.male,
name: "男",
},
{
value: res.data.totalPatients,
name: "女"
}
value: res.data.gender.female,
name: "女",
},
];
//
let ageValue = res.data.age
this.ageValue = [ageValue.num1, ageValue.num2, ageValue.num2, ageValue.num4, ageValue
.num5, ageValue.num6
]
let ageValue = res.data.age || {};
this.ageValue = [
ageValue.num1 || 0,
ageValue.num2 || 0,
ageValue.num3 || 0,
ageValue.num4 || 0,
ageValue.num5 || 0,
ageValue.num6 || 0,
];
//
let diseaseValue = res.data.jwbz
this.diseaseValue = []
let diseaseValue = res.data.jwbz || {};
this.diseaseValue = [];
for (let key in diseaseValue) {
let data = {
name: this.jwbzObj[key],
value: diseaseValue[key]
}
this.diseaseValue.push(data)
value: diseaseValue[key] || 0,
};
this.diseaseValue.push(data);
}
this.Linepatient(); //
// this.Linepatient(); //
this.handleAge(); //
this.columnar(); //
this.handleDisease(); //
});
this.loading = false;
} catch (e) {}
} catch (e) {
console.log("患者统计", e);
}
},
//
@ -211,7 +228,7 @@
},
//
handleAge() {
ageEcharts.series[0].data = this.ageValue
ageEcharts.series[0].data = this.ageValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("age"), null, {
height: 300,
@ -249,79 +266,108 @@
},
//
getRenew() {
// this.Linepatient();
// this.columnar();
this.Linepatient(); //
this.handleAge(); //
this.columnar(); //
this.handleDisease(); //
},
},
};
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
>>>.el-card__body {
.div-hz {
background: #c6a268;
width: 80%;
height: 70%;
border-radius: 10px;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 24px;
}
.div-hz-icon {
flex: 1;
}
.div-hz-num {
flex: 1;
font-size: 50px;
color: #ffffff;
text-align: right;
}
.div-hz-num span {
font-size: 24px;
color: #ffffff;
}
.hz-num-title {
font-size: 22px;
color: #ffffff;
}
>>> .el-card__body {
padding: 10px 0 !important;
}
}
.dis {
.dis {
display: flex;
}
}
.header-title {
.header-title {
font-size: 18px;
}
}
.title-box {
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
}
.dian-box {
.dian-box {
align-items: center;
}
}
.dian {
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
}
.title-box {
.title-box {
justify-content: space-between;
}
}
.>>>.el-radio--small.is-bordered {
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
}
>>>.el-radio__input {
>>> .el-radio__input {
display: none;
}
}
>>>.el-radio__label {
>>> .el-radio__label {
padding-left: 5px;
}
}
.app-container {
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
}
.title {
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
}
.title-bor {
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
}
</style>

8
acupuncture-前台/src/views/indexCom/query.vue

@ -6,7 +6,7 @@
</div>
<div>
<div>
<el-radio-group
<!-- <el-radio-group
v-model="radioValue"
size="small"
style="height: 36px"
@ -16,11 +16,7 @@
<el-radio label="1" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="2" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="3" border style="margin: 0 20px 0 0"></el-radio>
<!-- <el-radio label="4" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="4" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="1" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="1" border style="margin: 0 20px 0 0"></el-radio> -->
</el-radio-group>
</el-radio-group> -->
<el-date-picker
v-model="pickerValue"
type="daterange"

91
acupuncture-前台/src/views/login.vue

@ -1,12 +1,18 @@
<template>
<div class="login">
<div class="login-left"></div>
<div class="login-right">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<h3 class="title">针灸后台管理系统</h3>
<h3 class="title">
登录到
<br />
朱琏针灸联盟数据系统
</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
@ -56,7 +62,7 @@
</el-form-item>
<el-checkbox
v-model="loginForm.rememberMe"
style="margin: 0px 0px 25px 0px"
style="margin: 0px 0px 25px 0px; color: #fff"
>记住密码</el-checkbox
>
<el-form-item style="width: 100%">
@ -77,9 +83,6 @@
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
@ -88,27 +91,41 @@
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
import { commonQueue } from "@/api/followupFile";
export default {
name: "Login",
data() {
return {
codeUrl: "",
loginForm: {
username: "admin",
password: "admin123",
username: "",
password: "",
rememberMe: false,
code: "",
uuid: "",
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" },
{
required: true,
trigger: "blur",
message: "请输入您的账号",
},
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" },
{
required: true,
trigger: "blur",
message: "请输入您的密码",
},
],
code: [
{
required: true,
trigger: "change",
message: "请输入验证码",
},
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }],
},
loading: false,
//
@ -157,7 +174,9 @@ export default {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("username", this.loginForm.username, {
expires: 30,
});
Cookies.set("password", encrypt(this.loginForm.password), {
expires: 30,
});
@ -172,7 +191,12 @@ export default {
this.$store
.dispatch("Login", this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
this.$router
.push({
path: this.redirect || "/",
})
.catch(() => {});
this.getCommonQueue();
})
.catch(() => {
this.loading = false;
@ -183,6 +207,20 @@ export default {
}
});
},
//
getCommonQueue() {
commonQueue({
pageNum: -1,
param: {
status: 1,
},
}).then((res) => {
res.data.list.forEach((i) => {
i.type = 1;
});
localStorage.setItem("commonQueue", JSON.stringify(res.data.list));
});
},
},
};
</script>
@ -193,46 +231,64 @@ export default {
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-image: url("./bg.png");
background-size: cover;
display: flex;
.login-left {
flex: 1.5;
}
.login-right {
flex: 1;
}
}
.title {
font-size: 26 px;
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
text-align: left;
color: #fff;
line-height: 28px;
}
.login-form {
border-radius: 6px;
background: #ffffff;
// background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
@ -245,6 +301,7 @@ export default {
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}

374
acupuncture-前台/src/views/medicalFile/components/anxiety/HAMD.vue

@ -0,0 +1,374 @@
<template>
<div>
<!--
1 抑郁情绪 01只在问到时才诉述2在访谈中自发地表达3从表情姿势声音中流露4几乎完全表现为这种情绪
2 有罪感 01责备自己感到连累他人2认为自己犯了罪3认为疾病是惩罚4罪恶妄想伴有幻觉
3 自杀 01觉得活着没有意义2希望死去3有自杀念头4有自杀行为
4 入睡困难 01有时入睡困难2每晚入睡困难
5 睡眠不深 01睡眠浅多恶梦2半夜醒来
6 早醒 01早醒但能重新入睡2早醒后无法重新入睡
7 工作和兴趣 0无困难1提问时才诉述2自发表达对活动失去兴趣3病室劳动或娱乐不满3小时4停止工作或无法完成日常事务
8 迟缓 01提问时才诉述2自发表达迟缓3明显迟缓4完全迟缓
9 激越 01有些心神不宁2明显心神不宁3不能静坐4严重激越
10 精神性焦虑 01问时诉述2自发表达3明显忧虑4明显惊恐
11 躯体性焦虑 01轻度2中度3重度4严重影响生活
12 胃肠道症状 01食欲减退2进食需他人催促3需用泻药或助消化药
13 全身症状 01轻度2明显
14 性症状 01轻度2重度3不适合或不能肯定
15 疑病 01对身体过分关注2反复考虑健康问题3有疑病妄想4伴有幻觉的疑病妄想
16 体重减轻 01可能有体重减轻2肯定体重减轻
17 自知力 0知道自己有病1归咎于其他原因2完全否认有病
18 认知障碍 01轻度2中度3重度4极重度
19 日夜变化 01有日夜变化
20 人格解体 01轻度2中度3重度4极重度
21 偏执症状 01轻度2中度3重度4极重度
22 强迫症状 01轻度2中度3重度4极重度
23 躯体化症状 01轻度2中度3重度4极重度
24 社交退缩 01轻度2中度3重度4极重度
-->
<div>
<div
class="item-container"
v-for="(item, index) in questions"
:key="index"
>
<div class="item-title">{{ item.index }}. {{ item.question }}</div>
<div class="item-radio-box">
<el-radio-group v-model="form[`topic${item.index}`]">
<el-radio
v-for="(criteria, index) in item.criteria"
:key="index"
:label="criteria.value"
>{{ criteria.label }}
</el-radio>
</el-radio-group>
</div>
</div>
<div class="submit-box">
<el-button type="primary" class="submit-box-but" @click="submitForm"
>提交</el-button
>
</div>
</div>
</div>
</template>
<script>
export default {
name: "phq",
props: ["scaleCode"],
data() {
return {
form: {},
questions: [
{
index: 1,
question: "抑郁情绪",
criteria: [
{ label: "无", value: 0 },
{ label: "只在问到时才诉述", value: 1 },
{ label: "在访谈中自发地表达", value: 2 },
{ label: "从表情、姿势、声音中流露", value: 3 },
{ label: "几乎完全表现为这种情绪", value: 4 },
],
},
{
index: 2,
question: "有罪感",
criteria: [
{ label: "无", value: 0 },
{ label: "责备自己,感到连累他人", value: 1 },
{ label: "认为自己犯了罪", value: 2 },
{ label: "认为疾病是惩罚", value: 3 },
{ label: "罪恶妄想伴有幻觉", value: 4 },
],
},
{
index: 3,
question: "自杀",
criteria: [
{ label: "无", value: 0 },
{ label: "觉得活着没有意义", value: 1 },
{ label: "希望死去", value: 2 },
{ label: "有自杀念头", value: 3 },
{ label: "有自杀行为", value: 4 },
],
},
{
index: 4,
question: "入睡困难",
criteria: [
{ label: "无", value: 0 },
{ label: "有时入睡困难", value: 1 },
{ label: "每晚入睡困难", value: 2 },
],
},
{
index: 5,
question: "睡眠不深",
criteria: [
{ label: "无", value: 0 },
{ label: "睡眠浅多恶梦", value: 1 },
{ label: "半夜醒来", value: 2 },
],
},
{
index: 6,
question: "早醒",
criteria: [
{ label: "无", value: 0 },
{ label: "早醒但能重新入睡", value: 1 },
{ label: "早醒后无法重新入睡", value: 2 },
],
},
{
index: 7,
question: "工作和兴趣",
criteria: [
{ label: "无困难", value: 0 },
{ label: "提问时才诉述", value: 1 },
{ label: "自发表达对活动失去兴趣", value: 2 },
{ label: "病室劳动或娱乐不满3小时", value: 3 },
{ label: "停止工作或无法完成日常事务", value: 4 },
],
},
{
index: 8,
question: "迟缓",
criteria: [
{ label: "无", value: 0 },
{ label: "提问时才诉述", value: 1 },
{ label: "自发表达迟缓", value: 2 },
{ label: "明显迟缓", value: 3 },
{ label: "完全迟缓", value: 4 },
],
},
{
index: 9,
question: "激越",
criteria: [
{ label: "无", value: 0 },
{ label: "有些心神不宁", value: 1 },
{ label: "明显心神不宁", value: 2 },
{ label: "不能静坐", value: 3 },
{ label: "严重激越", value: 4 },
],
},
{
index: 10,
question: "精神性焦虑",
criteria: [
{ label: "无", value: 0 },
{ label: "问时诉述", value: 1 },
{ label: "自发表达", value: 2 },
{ label: "明显忧虑", value: 3 },
{ label: "明显惊恐", value: 4 },
],
},
{
index: 11,
question: "躯体性焦虑",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "严重影响生活", value: 4 },
],
},
{
index: 12,
question: "胃肠道症状",
criteria: [
{ label: "无", value: 0 },
{ label: "食欲减退", value: 1 },
{ label: "进食需他人催促", value: 2 },
{ label: "需用泻药或助消化药", value: 3 },
],
},
{
index: 13,
question: "全身症状",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "明显", value: 2 },
],
},
{
index: 14,
question: "性症状",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "重度", value: 2 },
{ label: "不适合或不能肯定", value: 3 },
],
},
{
index: 15,
question: "疑病",
criteria: [
{ label: "无", value: 0 },
{ label: "对身体过分关注", value: 1 },
{ label: "反复考虑健康问题", value: 2 },
{ label: "有疑病妄想", value: 3 },
{ label: "伴有幻觉的疑病妄想", value: 4 },
],
},
{
index: 16,
question: "体重减轻",
criteria: [
{ label: "无", value: 0 },
{ label: "可能有体重减轻", value: 1 },
{ label: "肯定体重减轻", value: 2 },
],
},
{
index: 17,
question: "自知力",
criteria: [
{ label: "知道自己有病", value: 0 },
{ label: "归咎于其他原因", value: 1 },
{ label: "完全否认有病", value: 2 },
],
},
{
index: 18,
question: "认知障碍",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "极重度", value: 4 },
],
},
{
index: 19,
question: "日夜变化",
criteria: [
{ label: "无", value: 0 },
{ label: "有日夜变化", value: 1 },
],
},
{
index: 20,
question: "人格解体",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "极重度", value: 4 },
],
},
{
index: 21,
question: "偏执症状",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "极重度", value: 4 },
],
},
{
index: 22,
question: "强迫症状",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "极重度", value: 4 },
],
},
{
index: 23,
question: "躯体化症状",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "极重度", value: 4 },
],
},
{
index: 24,
question: "社交退缩",
criteria: [
{ label: "无", value: 0 },
{ label: "轻度", value: 1 },
{ label: "中度", value: 2 },
{ label: "重度", value: 3 },
{ label: "极重度", value: 4 },
],
},
],
scaleData: {},
};
},
created() {
this.treatmentId = this.$route.query.treatmentId; // id
let scaleData = localStorage.getItem("scaleData"); //
// scaleData
this.scaleData = scaleData
? JSON.parse(scaleData)
: {
[this.treatmentId]: {},
};
// scaleData[this.treatmentId]
if (!this.scaleData[this.treatmentId]) {
this.scaleData[this.treatmentId] = {};
}
this.form = this.scaleData[this.treatmentId][this.scaleCode] || {}; // form
},
methods: {
submitForm() {
let score = 0;
// , topic${i}
for (let i = 1; i <= 24; i++) {
if (this.form[`topic${i}`] !== undefined) {
score += this.form[`topic${i}`];
}
}
//
this.scaleData[this.treatmentId][this.scaleCode] = this.form;
localStorage.setItem("scaleData", JSON.stringify(this.scaleData));
//
this.$emit("getScaleResult", score, this.scaleCode);
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.item-title {
font-size: 20px;
font-weight: bold;
color: #3d3d3d;
line-height: 26px;
}
.item-radio-box {
margin: 16px 0px;
}
>>> .el-radio__label {
font-size: 18px;
color: #555555;
line-height: 20px;
}
.submit-box {
display: flex;
justify-content: center;
align-items: center;
.submit-box-but {
width: 200px;
}
}
</style>

323
acupuncture-前台/src/views/medicalFile/components/anxiety/SAS.vue

@ -0,0 +1,323 @@
<template>
<div>
<!--
1 我觉得比平常容易紧张和着急焦虑 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
2 我无缘无故地感到害怕害怕 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
3 我容易心里烦乱或觉得惊恐惊恐 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
4 我觉得我可能将要发疯发疯感 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
5 我觉得一切都很好也不会发生什么不幸不幸预感 4没有或很少时间3小部分时间2相当多时间1绝大部分或全部时间
6 我手脚发抖打颤手足颤抖 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
7 我因为头痛头颈痛和背痛而苦恼躯体疼痛 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
8 我感觉容易衰弱和疲乏乏力 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
9 我觉得心平气和并且容易安静坐着静坐不能 4没有或很少时间3小部分时间2相当多时间1绝大部分或全部时间
10 我觉得心跳得很快心悸 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
11 我因为一阵阵头晕而苦恼头晕 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
12 我有晕倒发作或觉得要晕倒似的晕厥感 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
13 我呼气吸气都感到很容易呼吸困难 4没有或很少时间3小部分时间2相当多时间1绝大部分或全部时间
14 我手脚麻木和刺痛手足刺痛 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
15 我因为胃痛和消化不良而苦恼胃痛消化不良 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
16 我常常要小便尿意频数 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
17 我的手常常是干燥温暖的多汗 4没有或很少时间3小部分时间2相当多时间1绝大部分或全部时间
18 我脸红发热面部潮红 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
19 我容易入睡并且一夜睡得很好睡眠障碍 4没有或很少时间3小部分时间2相当多时间1绝大部分或全部时间
20 我做噩梦噩梦 1没有或很少时间2小部分时间3相当多时间4绝大部分或全部时间
-->
<div>
<div
class="item-container"
v-for="(item, index) in questions"
:key="index"
>
<div class="item-title">{{ item.index }}. {{ item.question }}</div>
<div class="item-radio-box">
<el-radio-group v-model="form[`topic${item.index}`]">
<el-radio
v-for="(criteria, index) in item.criteria"
:key="index"
:label="criteria.value"
>{{ criteria.label }}
</el-radio>
</el-radio-group>
</div>
</div>
<div class="submit-box">
<el-button type="primary" class="submit-box-but" @click="submitForm"
>提交</el-button
>
</div>
</div>
</div>
</template>
<script>
export default {
name: "phq",
props: ["scaleCode"],
data() {
return {
form: {},
questions: [
{
index: 1,
question: "我觉得比平常容易紧张和着急(焦虑)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 2,
question: "我无缘无故地感到害怕(害怕)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 3,
question: "我容易心里烦乱或觉得惊恐(惊恐)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 4,
question: "我觉得我可能将要发疯(发疯感)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 5,
question: "我觉得一切都很好,也不会发生什么不幸(不幸预感)",
criteria: [
{ label: "没有或很少时间", value: 4 },
{ label: "小部分时间", value: 3 },
{ label: "相当多时间", value: 2 },
{ label: "绝大部分或全部时间", value: 1 },
],
},
{
index: 6,
question: "我手脚发抖打颤(手足颤抖)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 7,
question: "我因为头痛、头颈痛和背痛而苦恼(躯体疼痛)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 8,
question: "我感觉容易衰弱和疲乏(乏力)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 9,
question: "我觉得心平气和,并且容易安静坐着(静坐不能)",
criteria: [
{ label: "没有或很少时间", value: 4 },
{ label: "小部分时间", value: 3 },
{ label: "相当多时间", value: 2 },
{ label: "绝大部分或全部时间", value: 1 },
],
},
{
index: 10,
question: "我觉得心跳得很快(心悸)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 11,
question: "我因为一阵阵头晕而苦恼(头晕)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 12,
question: "我有晕倒发作或觉得要晕倒似的(晕厥感)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 13,
question: "我呼气、吸气都感到很容易(呼吸困难)",
criteria: [
{ label: "没有或很少时间", value: 4 },
{ label: "小部分时间", value: 3 },
{ label: "相当多时间", value: 2 },
{ label: "绝大部分或全部时间", value: 1 },
],
},
{
index: 14,
question: "我手脚麻木和刺痛(手足刺痛)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 15,
question: "我因为胃痛和消化不良而苦恼(胃痛,消化不良)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 16,
question: "我常常要小便(尿意频数)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 17,
question: "我的手常常是干燥温暖的(多汗)",
criteria: [
{ label: "没有或很少时间", value: 4 },
{ label: "小部分时间", value: 3 },
{ label: "相当多时间", value: 2 },
{ label: "绝大部分或全部时间", value: 1 },
],
},
{
index: 18,
question: "我脸红发热(面部潮红)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
{
index: 19,
question: "我容易入睡,并且一夜睡得很好(睡眠障碍)",
criteria: [
{ label: "没有或很少时间", value: 4 },
{ label: "小部分时间", value: 3 },
{ label: "相当多时间", value: 2 },
{ label: "绝大部分或全部时间", value: 1 },
],
},
{
index: 20,
question: "我做噩梦(噩梦)",
criteria: [
{ label: "没有或很少时间", value: 1 },
{ label: "小部分时间", value: 2 },
{ label: "相当多时间", value: 3 },
{ label: "绝大部分或全部时间", value: 4 },
],
},
],
scaleData: {},
};
},
created() {
this.treatmentId = this.$route.query.treatmentId; // id
let scaleData = localStorage.getItem("scaleData"); //
// scaleData
this.scaleData = scaleData
? JSON.parse(scaleData)
: {
[this.treatmentId]: {},
};
// scaleData[this.treatmentId]
if (!this.scaleData[this.treatmentId]) {
this.scaleData[this.treatmentId] = {};
}
this.form = this.scaleData[this.treatmentId][this.scaleCode] || {}; // form
},
methods: {
submitForm() {
let score = 0;
// , topic${i}
for (let i = 1; i <= 20; i++) {
if (this.form[`topic${i}`] !== undefined) {
score += this.form[`topic${i}`];
}
}
//
this.scaleData[this.treatmentId][this.scaleCode] = this.form;
localStorage.setItem("scaleData", JSON.stringify(this.scaleData));
//
this.$emit("getScaleResult", score, this.scaleCode);
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.item-title {
font-size: 20px;
font-weight: bold;
color: #3d3d3d;
line-height: 26px;
}
.item-radio-box {
margin: 16px 0px;
}
>>> .el-radio__label {
font-size: 18px;
color: #555555;
line-height: 20px;
}
.submit-box {
display: flex;
justify-content: center;
align-items: center;
.submit-box-but {
width: 200px;
}
}
</style>

202
acupuncture-前台/src/views/medicalFile/components/posture/PHQ-9.vue

@ -0,0 +1,202 @@
<template>
<div>
<!--
分值范围
评分方法每个条目根据症状频率评分0分表示完全没有1分表示有几天2分表示七天以上3分表示接近每天总分范围为0~27
分值意义
0~4无或极轻微的抑郁症状
5~9轻度抑郁
10~14中度抑郁
15~19中重度抑郁
20~27重度抑郁
-->
<div>
<div
class="item-container"
v-for="(item, index) in questions"
:key="index"
>
<div class="item-title">{{ item.index }}. {{ item.question }}</div>
<div class="item-radio-box">
<el-radio-group v-model="form[`topic${item.index}`]">
<el-radio
v-for="(criteria, index) in item.criteria"
:key="index"
:label="criteria.value"
>{{ criteria.label }}
</el-radio>
</el-radio-group>
</div>
</div>
<div class="submit-box">
<el-button class="submit-box-but" type="primary" @click="submitForm"
>提交</el-button
>
</div>
</div>
</div>
</template>
<script>
export default {
name: "PHQ9",
props: ["scaleCode"],
data() {
return {
form: {},
questions: [
{
index: 1,
question: "做任何事都觉得沉闷或者根本不想做任何事",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 2,
question: "情绪低落、忧郁或绝望",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 3,
question: "难于入睡、半夜会醒,或相反,睡觉时间过多",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 4,
question: "觉得疲倦或没有精力",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 5,
question: "胃口不好或饮食过量",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 6,
question: "觉得自己做得不好、对自己失望或有负家人期望",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 7,
question: "难于集中精神做事,例如看报纸或看电视",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 8,
question:
"其它人可能会注意到您在动或说话的时候比平时慢;或者相反,您坐立不安,比起平时有多余的身体动作",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
{
index: 9,
question: "想到自己不如死了算了,或者有自残的念头",
criteria: [
{ label: "完全没有", value: 0 },
{ label: "有几天", value: 1 },
{ label: "七天以上", value: 2 },
{ label: "接近每天", value: 3 },
],
},
],
scaleData: {},
};
},
created() {
this.treatmentId = this.$route.query.treatmentId; // id
let scaleData = localStorage.getItem("scaleData"); //
// scaleData
this.scaleData = scaleData
? JSON.parse(scaleData)
: {
[this.treatmentId]: {},
};
// scaleData[this.treatmentId]
if (!this.scaleData[this.treatmentId]) {
this.scaleData[this.treatmentId] = {};
}
this.form = this.scaleData[this.treatmentId][this.scaleCode] || {}; // form
},
methods: {
submitForm() {
let score = 0;
// , topic${i}
for (let i = 1; i <= 9; i++) {
if (this.form[`topic${i}`] !== undefined) {
score += this.form[`topic${i}`];
}
}
//
this.scaleData[this.treatmentId][this.scaleCode] = this.form;
localStorage.setItem("scaleData", JSON.stringify(this.scaleData));
//
this.$emit("getScaleResult", score, this.scaleCode);
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.item-title {
font-size: 20px;
font-weight: bold;
color: #3d3d3d;
line-height: 26px;
}
.item-radio-box {
margin: 16px 0px;
}
>>> .el-radio__label {
font-size: 18px;
color: #555555;
line-height: 20px;
}
.submit-box {
display: flex;
justify-content: center;
align-items: center;
.submit-box-but {
width: 200px;
}
}
</style>

171
acupuncture-前台/src/views/medicalFile/components/posture/PSQI.vue

@ -0,0 +1,171 @@
<template>
<div>
<div>
<div
class="item-container"
v-for="(item, index) in questions"
:key="index"
>
<div class="item-title">{{ item.index }}. {{ item.question }}</div>
<div class="item-radio-box">
<el-radio-group v-model="form[`topic${item.index}`]">
<el-radio
v-for="(criteria, index) in item.criteria"
:key="index"
:label="criteria.value"
>{{ criteria.label }}
</el-radio>
</el-radio-group>
</div>
</div>
<div class="submit-box">
<el-button class="submit-box-but" type="primary" @click="submitForm"
>提交</el-button
>
</div>
</div>
</div>
</template>
<script>
export default {
name: "PHQ9",
props: ["scaleCode"],
data() {
return {
form: {},
questions: [
{
index: 1,
question: "睡眠质量-总体评价睡眠质量",
criteria: [
{ label: "很好", value: 0 },
{ label: "较好", value: 1 },
{ label: "较差", value: 2 },
{ label: "很差", value: 3 },
],
},
{
index: 2,
question: "入睡时间-从上床到入睡的时间",
criteria: [
{ label: "≤15分钟", value: 0 },
{ label: "16~30分钟", value: 1 },
{ label: "31~60分钟", value: 2 },
{ label: "≥60分钟", value: 3 },
],
},
{
index: 3,
question: "睡眠时间-每晚实际睡眠时间",
criteria: [
{ label: ">7小时", value: 0 },
{ label: "6~7小时", value: 1 },
{ label: "5~6小时", value: 2 },
{ label: "<5小时", value: 3 },
],
},
{
index: 4,
question: "睡眠效率-睡眠时间与床上时间的比例",
criteria: [
{ label: ">85%", value: 0 },
{ label: "75%~84%", value: 1 },
{ label: "65%~74%", value: 2 },
{ label: "<65%", value: 3 },
],
},
{
index: 5,
question: "睡眠障碍-夜间醒来、呼吸困难、噩梦等",
criteria: [
{ label: "每项无", value: 0 },
{ label: "<1次/周", value: 1 },
{ label: "1~2次/周", value: 2 },
{ label: "≥3次/周", value: 3 },
],
},
{
index: 6,
question: "催眠药物-使用催眠药物的频率",
criteria: [
{ label: "无", value: 0 },
{ label: "<1次/周", value: 1 },
{ label: "1~2次/周", value: 2 },
{ label: "≥3次/周", value: 3 },
],
},
{
index: 7,
question: "日间功能障碍-白天困倦、注意力不集中等",
criteria: [
{ label: "无", value: 0 },
{ label: "<1次/周", value: 1 },
{ label: "1~2次/周", value: 2 },
{ label: "≥3次/周", value: 3 },
],
},
],
scaleData: {},
};
},
created() {
this.treatmentId = this.$route.query.treatmentId; // id
let scaleData = localStorage.getItem("scaleData"); //
// scaleData
this.scaleData = scaleData
? JSON.parse(scaleData)
: {
[this.treatmentId]: {},
};
// scaleData[this.treatmentId]
if (!this.scaleData[this.treatmentId]) {
this.scaleData[this.treatmentId] = {};
}
this.form = this.scaleData[this.treatmentId][this.scaleCode] || {}; // form
},
methods: {
submitForm() {
let score = 0;
// , topic${i}
for (let i = 1; i <= 7; i++) {
if (this.form[`topic${i}`] !== undefined) {
score += this.form[`topic${i}`];
}
}
//
this.scaleData[this.treatmentId][this.scaleCode] = this.form;
localStorage.setItem("scaleData", JSON.stringify(this.scaleData));
//
this.$emit("getScaleResult", score, this.scaleCode);
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.item-title {
font-size: 20px;
font-weight: bold;
color: #3d3d3d;
line-height: 26px;
}
.item-radio-box {
margin: 16px 0px;
}
>>> .el-radio__label {
font-size: 18px;
color: #555555;
line-height: 20px;
}
.submit-box {
display: flex;
justify-content: center;
align-items: center;
.submit-box-but {
width: 200px;
}
}
</style>

191
acupuncture-前台/src/views/medicalFile/components/posture/epworth.vue

@ -0,0 +1,191 @@
<template>
<div>
<!--
1 坐着阅读书刊 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
2 看电视 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
3 在公共场所坐着不活动如剧院或会议 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
4 作为乘客在车内乘坐一小时以上 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
5 午间静卧休息 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
6 坐着和别人交谈 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
7 午餐后静坐不饮酒 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
8 坐在车内当车辆因交通拥堵而停下时 0从不打瞌睡1轻度可能2中度可能3很可能打瞌睡
-->
<div>
<div
class="item-container"
v-for="(item, index) in questions"
:key="index"
>
<div class="item-title">{{ item.index }}. {{ item.question }}</div>
<div class="item-radio-box">
<el-radio-group v-model="form[`topic${item.index}`]">
<el-radio
v-for="(criteria, index) in item.criteria"
:key="index"
:label="criteria.value"
>{{ criteria.label }}
</el-radio>
</el-radio-group>
</div>
</div>
<div class="submit-box">
<el-button class="submit-box-but" type="primary" @click="submitForm"
>提交</el-button
>
</div>
</div>
</div>
</template>
<script>
export default {
name: "phq",
props: ["scaleCode"],
data() {
return {
form: {},
questions: [
{
index: 1,
question: "坐着阅读书刊",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 2,
question: "看电视",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 3,
question: "在公共场所坐着不活动(如剧院或会议)",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 4,
question: "作为乘客在车内乘坐一小时以上",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 5,
question: "午间静卧休息",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 6,
question: "坐着和别人交谈",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 7,
question: "午餐后静坐(不饮酒)",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
{
index: 8,
question: "坐在车内,当车辆因交通拥堵而停下时",
criteria: [
{ label: "从不打瞌睡", value: 0 },
{ label: "轻度可能", value: 1 },
{ label: "中度可能", value: 2 },
{ label: "很可能打瞌睡", value: 3 },
],
},
],
scaleData: {},
};
},
created() {
this.treatmentId = this.$route.query.treatmentId; // id
let scaleData = localStorage.getItem("scaleData"); //
// scaleData
this.scaleData = scaleData
? JSON.parse(scaleData)
: {
[this.treatmentId]: {},
};
// scaleData[this.treatmentId]
if (!this.scaleData[this.treatmentId]) {
this.scaleData[this.treatmentId] = {};
}
this.form = this.scaleData[this.treatmentId][this.scaleCode] || {}; // form
},
methods: {
submitForm() {
let score = 0;
// , topic${i}
for (let i = 1; i <= 8; i++) {
if (this.form[`topic${i}`] !== undefined) {
score += this.form[`topic${i}`];
}
}
//
this.scaleData[this.treatmentId][this.scaleCode] = this.form;
localStorage.setItem("scaleData", JSON.stringify(this.scaleData));
//
this.$emit("getScaleResult", score, this.scaleCode);
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.item-title {
font-size: 20px;
font-weight: bold;
color: #3d3d3d;
line-height: 26px;
}
.item-radio-box {
margin: 16px 0px;
}
>>> .el-radio__label {
font-size: 18px;
color: #555555;
line-height: 20px;
}
.submit-box {
display: flex;
justify-content: center;
align-items: center;
.submit-box-but {
width: 200px;
}
}
</style>

1224
acupuncture-前台/src/views/medicalFile/details.vue

File diff suppressed because it is too large

733
acupuncture-前台/src/views/medicalFile/index.vue

File diff suppressed because it is too large

177
acupuncture-前台/src/views/patientFile/index.vue

@ -10,8 +10,9 @@
>
<el-form-item label="" prop="noticeTitle">
<el-input
style="width: 300px"
v-model="queryParams.param.keywords"
placeholder="支持姓名、全拼、简拼、手机号、证件号码"
placeholder="支持姓名、全拼、简拼、手机号、证件号码"
clearable
@keyup.enter.native="handleQuery"
/>
@ -33,7 +34,7 @@
/>
</div>
</el-form-item>
<el-form-item label="建档组织" prop="tenantId">
<!-- <el-form-item label="建档组织" prop="tenantId">
<el-select
v-model="queryParams.param.tenantId"
placeholder="请选择"
@ -41,7 +42,7 @@
>
<el-option label="dict.label" value="dict.value" />
</el-select>
</el-form-item>
</el-form-item> -->
<el-form-item label="数据来源" prop="sourceId">
<el-select
v-model="queryParams.param.sourceId"
@ -95,8 +96,7 @@
plain
icon="el-icon-bottom"
size="mini"
:disabled="multiple"
@click="handleDelete"
@click="handleDownload"
>下载模版</el-button
>
</el-col>
@ -133,13 +133,20 @@
max-height="600"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="姓名" align="center" prop="name" width="100" />
<el-table-column
label="姓名"
align="center"
prop="name"
min-width="100"
fixed
/>
<el-table-column
label="性别"
align="center"
prop="gender"
show-overflow-tooltip
width="100"
min-width="100"
fixed
>
<template slot-scope="scope">
<span v-if="scope.row.gender == 0"></span>
@ -152,35 +159,36 @@
align="center"
prop="birthDate"
show-overflow-tooltip
width="150"
min-width="150"
fixed
/>
<el-table-column
label="民族"
align="center"
prop="ethnicity"
show-overflow-tooltip
width="100"
min-width="100"
/>
<el-table-column
label="受教育年限"
align="center"
prop="educationYears"
show-overflow-tooltip
width="100"
min-width="100"
/>
<el-table-column
label="手机号码"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column
label="证件类型"
align="center"
prop="idCardType"
show-overflow-tooltip
width="200"
min-width="200"
>
<template slot-scope="scope">
{{ idCardTypeValue[scope.row.idCardType] }}
@ -191,7 +199,7 @@
align="center"
prop="idCard"
show-overflow-tooltip
width="180"
min-width="180"
/>
<el-table-column
@ -199,16 +207,16 @@
align="center"
prop="createBy"
show-overflow-tooltip
width="100"
min-width="100"
/>
<el-table-column
label="建档组织(医院名称)"
align="center"
prop="organization"
prop="tenantName"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column label="建档日期" align="center" width="130">
<el-table-column label="建档日期" align="center" min-width="140">
<template slot-scope="scope">
<span>{{
parseTime(scope.row.createTime, "{y}-{m}-{d} {h}:{i}")
@ -221,12 +229,12 @@
align="center"
prop="source"
show-overflow-tooltip
width="100"
min-width="100"
>
<template slot-scope="scope">
<span v-if="scope.row.gender == 0">筛查</span>
<span v-if="scope.row.gender == 1">录入</span>
<span v-if="scope.row.gender == 2">HIS</span>
<span v-if="scope.row.source == 0">筛查</span>
<span v-if="scope.row.source == 1">录入</span>
<span v-if="scope.row.source == 2">HIS</span>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="150">
@ -255,8 +263,8 @@
<el-button
size="mini"
type="text"
icon="el-icon-notebook-2"
@click="handleDelete(scope.row)"
icon="el-icon-notebook-1"
@click="handleArchives(scope.row)"
>诊疗档案</el-button
>
</template>
@ -284,7 +292,7 @@
ref="form"
:model="form"
:rules="rules"
label-width="90px"
label-width="100px"
>
<el-form-item label="姓名" prop="name">
<el-input
@ -299,7 +307,7 @@
<el-radio :label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="出生年月" prop="birthDate">
<el-form-item label="出生日期" prop="birthDate">
<el-date-picker
:disabled="formDisabled"
format="yyyy-MM-dd"
@ -353,7 +361,7 @@
:disabled="formDisabled"
/>
</el-form-item>
<el-form-item label="现病史" prop="currentIllnessHistory">
<el-form-item label="现病史" prop="">
<el-checkbox-group
v-model="form.currentIllnessHistory"
:disabled="formDisabled"
@ -362,7 +370,7 @@
</el-checkbox>
</el-checkbox-group>
<el-input
v-model="form.currentIllnessHistoryQT"
v-model="form.currentIllnessHistoryQt"
placeholder="其他"
:disabled="formDisabled"
/>
@ -380,7 +388,7 @@
width="640px"
append-to-body
>
<el-form ref="form" :model="importform">
<el-form ref="importform" :model="importform">
<el-form-item prop="accessUrl">
<el-upload
:limit="1"
@ -422,7 +430,8 @@ export default {
Authorization: "Bearer " + getToken(),
deptId: localStorage.getItem("hospitalId"),
},
uploadFileUrl1: process.env.VUE_APP_BASE_API + "/pms/importTjbgZip", //
uploadFileUrl1:
process.env.VUE_APP_API_QZURL + "/acupuncture/patient/import", //
fileList: [],
//
medicalHistory: [
@ -462,12 +471,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -499,22 +513,65 @@ export default {
//
rules: {
name: [
{ required: true, message: "患者姓名不能为空", trigger: "blur" },
{
required: true,
message: "患者姓名不能为空",
trigger: "blur",
},
],
gender: [
{ required: true, message: "性别不能为空", trigger: "change" },
{
required: true,
message: "性别不能为空",
trigger: "change",
},
],
birthDate: [
{
required: true,
message: "出生日期不能为空",
trigger: "change",
},
],
phone: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
required: true,
message: "手机号码不能为空",
trigger: "blur",
},
{
pattern: /^1[3456789]\d{9}$/,
message: "手机号码格式不正确",
trigger: "blur",
},
],
ethnicity: [
{ required: true, message: "民族不能为空", trigger: "blur" },
{
required: true,
message: "民族不能为空",
trigger: "blur",
},
],
idCardType: [
{ required: true, message: "证件类型不能为空", trigger: "blur" },
{
required: true,
message: "证件类型不能为空",
trigger: "blur",
},
],
idCard: [
{ required: true, message: "证件号码不能为空", trigger: "blur" },
{
required: true,
message: "证件号码不能为空",
trigger: "blur",
},
],
educationYears: [
{
required: true,
message: "受教育年限不能为空",
trigger: "blur",
},
],
currentIllnessHistory: [
{
@ -527,13 +584,15 @@ export default {
};
},
created() {
let idCard = this.$route.query.idCard;
this.queryParams.param.keywords = idCard || "";
this.getList();
},
methods: {
// - pdg
handleUploadPdfAdd1(res) {
if (res.code == 200) {
this.physicaOpen = false;
this.importOpen = false;
this.getList();
this.$modal.msgSuccess("导入成功");
} else {
@ -584,8 +643,9 @@ export default {
phone: "", //
idCardType: "", //
idCard: "", //
source: 1,
currentIllnessHistory: [], //
currentIllnessHistoryQT: "", //
currentIllnessHistoryQt: "", //
};
this.resetForm("form");
},
@ -596,6 +656,14 @@ export default {
},
/** 重置按钮操作 */
resetQuery() {
this.queryParams.param = {
keywords: "", //
startAge: "", //
endAge: "", //
tenantId: "", //
createBy: "", //
sourceId: "", //
};
this.handleQuery();
},
//
@ -619,7 +687,7 @@ export default {
this.form = JSON.parse(JSON.stringify(row));
//
this.form.currentIllnessHistory =
this.form.currentIllnessHistory.split(",");
this.form.currentIllnessHistory?.split(",") || [];
},
/** 详情按钮操作 */
handleDetails(row) {
@ -627,6 +695,15 @@ export default {
this.title = "患者档案详情";
this.formDisabled = true;
this.form = JSON.parse(JSON.stringify(row));
//
this.form.currentIllnessHistory =
this.form.currentIllnessHistory?.split(",") || [];
},
/** 诊疗档案 */
handleArchives(row) {
this.$router.push({
path: `/medicalIndex?idCard=${row.idCard}`,
});
},
/** 提交按钮 */
submitForm: function () {
@ -655,7 +732,9 @@ export default {
this.$modal
.confirm("是否确认删除当前选择的数据?")
.then(function () {
return patientDel({ idList: idList });
return patientDel({
idList: idList,
});
})
.then(() => {
this.getList();
@ -665,18 +744,28 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
this.download(
"system/user/export",
this.download1(
"/patient/export",
{
...this.queryParams.params,
},
`患者档案.xlsx`
);
},
/** 下载按钮操作 */
handleDownload() {
window.open(
`${process.env.VUE_APP_API_QZURL}/acupuncture/profile/PatientTemplate.xlsx`
);
// this.download1(
// "/patient/export", {},
// `.xlsx`
// );
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "用户导入";
this.upload.open = true;
this.fileList = [];
this.importOpen = true;
},
},
};
@ -687,9 +776,11 @@ export default {
display: flex;
align-items: center;
}
.form-item-age span {
margin: 0 10px;
}
.form-item-age >>> .el-input {
width: 100px;
}

2
acupuncture-前台/src/views/register.vue

@ -6,7 +6,7 @@
:rules="registerRules"
class="register-form"
>
<h3 class="title">针灸后台管理系统</h3>
<h3 class="title">朱琏针灸联盟数据系统</h3>
<el-form-item prop="username">
<el-input
v-model="registerForm.username"

71
acupuncture-前台/src/views/system/user/profile/index.vue

@ -1,14 +1,18 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<el-card class="box-card">
<el-col :span="6" :xs="24" style="height: 400px; border-radius: 4px">
<el-card style="height: 410px" class="box-card">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div>
<div class="text-center">
<userAvatar />
<img
src="@/assets/images/zj.png"
alt=""
style="border-radius: 50%"
/>
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
@ -17,40 +21,42 @@
</li>
<li class="list-group-item">
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ user.phonenumber }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ user.email }}</div>
<div class="pull-right">{{ userInfo.tenantPhone }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>
<div class="pull-right">
{{ userInfo.tenantName }}
</div>
</li>
<li class="list-group-item">
<!-- <li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色
<div class="pull-right">{{ roleGroup }}</div>
</li>
<li class="list-group-item">
</li> -->
<!-- <li class="list-group-item">
<svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ user.createTime }}</div>
</li>
</li> -->
</ul>
<el-button
type="primary"
size="mini"
@click="logout"
style="width: 100%; height: 48px; font-size: 16px"
>
退出登录
</el-button>
</div>
</el-card>
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<el-card style="height: 410px">
<div slot="header" class="clearfix">
<span>基本资料</span>
<span>修改密码</span>
</div>
<el-tabs v-model="activeTab">
<el-tab-pane label="基本资料" name="userinfo">
<userInfo :user="user" />
</el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd">
<resetPwd />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
@ -70,22 +76,39 @@ export default {
data() {
return {
user: {},
userInfo: {},
roleGroup: {},
postGroup: {},
activeTab: "userinfo"
activeTab: "resetPwd",
};
},
created() {
let userInfo = localStorage.getItem("user");
this.userInfo = userInfo ? JSON.parse(userInfo) : {};
this.getUser();
},
methods: {
async logout() {
this.$confirm("确定注销并退出系统吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$store.dispatch("LogOut").then(() => {
location.href = process.env.VUE_APP_PUBLIC_PATH;
});
})
.catch(() => {});
},
getUser() {
getUserProfile().then(response => {
getUserProfile().then((response) => {
this.user = response.data;
this.roleGroup = response.roleGroup;
this.postGroup = response.postGroup;
});
}
}
},
},
};
</script>

5
acupuncture-前台/vue.config.js

@ -7,7 +7,7 @@ function resolve(dir) {
const CompressionPlugin = require("compression-webpack-plugin");
const name = process.env.VUE_APP_TITLE || "针灸管理系统"; // 网页标题
const name = process.env.VUE_APP_TITLE || "朱琏针灸联盟数据系统"; // 网页标题
const port = process.env.port || process.env.npm_config_port || 80; // 端口
@ -18,7 +18,8 @@ module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
publicPath: process.env.NODE_ENV === "production" ? "/acupunctureClient/" : "/",
publicPath:
process.env.NODE_ENV === "production" ? "/acupunctureClient/" : "/",
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
outputDir: "dist",
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)

2
acupuncture-后台/.env.development

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 针灸管理系统
VUE_APP_TITLE = 朱琏针灸联盟数据系统
# 开发环境配置
ENV = 'development'

4
acupuncture-后台/.env.production

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 针灸管理系统
VUE_APP_TITLE = 朱琏针灸联盟数据系统
# 生产环境配置
NODE_ENV = 'production'
@ -8,4 +8,4 @@ VUE_APP_BASE_API = 'https://test.tall.wiki/acupuncture'
VUE_APP_API_QZURL = 'https://test.tall.wiki/'
# 访问路径
VUE_APP_PUBLIC_PATH = '/acupunctureClient/'
VUE_APP_PUBLIC_PATH = '/acupunctureAdmin/'

4
acupuncture-后台/.env.staging

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 针灸管理系统
VUE_APP_TITLE = 朱琏针灸联盟数据系统
BABEL_ENV = production
@ -8,5 +8,5 @@ NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 针灸管理系统/测试环境
# 朱琏针灸联盟数据系统/测试环境
VUE_APP_BASE_API = '/stage-api'

5
acupuncture-后台/package.json

@ -1,7 +1,7 @@
{
"name": "ruoyi",
"version": "3.8.9",
"description": "针灸管理系统",
"description": "朱琏针灸联盟数据系统",
"author": "若依",
"license": "MIT",
"scripts": {
@ -40,7 +40,7 @@
"axios": "0.28.1",
"clipboard": "2.0.8",
"core-js": "3.37.1",
"echarts": "5.4.0",
"echarts": "^5.4.0",
"element-ui": "^2.15.14",
"file-saver": "2.0.5",
"fuse.js": "6.4.3",
@ -48,6 +48,7 @@
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"moment": "^2.30.1",
"nprogress": "0.2.0",
"quill": "2.0.2",
"screenfull": "5.0.2",

22
acupuncture-后台/public/index.html

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<link rel="icon" type="image/x-icon" href="./zj.png">
<title>
<%= webpackConfig.name %>
</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
@ -16,6 +19,7 @@
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
@ -92,6 +96,7 @@
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
@ -105,6 +110,7 @@
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
@ -118,7 +124,7 @@
top: 0;
width: 51%;
height: 100%;
background: #7171C6;
background: #70483E;
z-index: 1000;
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
@ -194,8 +200,9 @@
opacity: 0.5;
}
</style>
</head>
<body>
</head>
<body>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
@ -204,5 +211,6 @@
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
</body>
</body>
</html>

BIN
acupuncture-后台/public/zj.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

8
acupuncture-后台/src/App.vue

@ -31,6 +31,14 @@ export default {
}
</style>
<style>
.header-title {
display: -webkit-box !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.wj-uploader .el-icon-upload:before {
font-size: 100px;
}

26
acupuncture-后台/src/api/followupFile.js

@ -3,7 +3,7 @@ import request from "@/utils/request";
// 随访队列
export function followupQuery(data) {
return request({
url: "/followup/query",
url: "/admin/followup/query",
method: "post",
data: data,
});
@ -11,7 +11,7 @@ export function followupQuery(data) {
// 新增随访队列
export function followupAdd(data) {
return request({
url: "/followup/add",
url: "/admin/followup/add",
method: "post",
data: data,
});
@ -19,7 +19,7 @@ export function followupAdd(data) {
// 新增随访队列
export function followupUpd(data) {
return request({
url: "/followup/upd",
url: "/admin/followup/upd",
method: "post",
data: data,
});
@ -27,7 +27,7 @@ export function followupUpd(data) {
// 新增随访队列
export function followupDel(data) {
return request({
url: "/followup/del",
url: "/admin/followup/del",
method: "post",
data: data,
});
@ -36,7 +36,7 @@ export function followupDel(data) {
// 查看随访对象
export function queryPatient(data) {
return request({
url: "/followup/queryPatient",
url: "/admin/followup/queryPatient",
method: "post",
data: data,
});
@ -44,7 +44,7 @@ export function queryPatient(data) {
// 修改随访对象 队列信息
export function updPatient(data) {
return request({
url: "/followup/updPatient",
url: "/admin/followup/updPatient",
method: "post",
data: data,
});
@ -52,7 +52,7 @@ export function updPatient(data) {
// 随访工单
export function queryTask(data) {
return request({
url: "/followup/queryTask",
url: "/admin/followup/queryTask",
method: "post",
data: data,
});
@ -60,7 +60,7 @@ export function queryTask(data) {
// 失访
export function updStatus(data) {
return request({
url: "/followup/updStatus",
url: "/admin/followup/updStatus",
method: "post",
data: data,
});
@ -68,7 +68,15 @@ export function updStatus(data) {
// 患者随访
export function followPatient(data) {
return request({
url: "/followup/followPatient",
url: "/admin/followup/followPatient",
method: "post",
data: data,
});
}
// 修改随访状态
export function followStatus(data) {
return request({
url: "/admin/followup/status",
method: "post",
data: data,
});

146
acupuncture-后台/src/api/indexCom.js

@ -0,0 +1,146 @@
import request from "@/utils/request";
// 患者统计 - 饼状
export function queryPatient(data) {
return request({
url: "/admin/qualityControl/home/queryPatient",
method: "post",
data: data,
});
}
// 患者统计 - 柱状图
export function queryByDatePatient(data) {
return request({
url: "/admin/qualityControl/home/queryByDatePatient",
method: "post",
data: data,
});
}
// 静脉溶栓率 - 统计
export function queryJmrs(data) {
return request({
url: "/admin/qualityControl/home/queryJmrs",
method: "post",
data: data,
});
}
// 静脉溶栓率 - 数据对比
// 静脉溶栓率 - DNT
export function queryDntResult(data) {
return request({
url: "/admin/qualityControl/home/queryDntResult",
method: "post",
data: data,
});
}
// 静脉溶栓率 - Sich
export function querySichResult(data) {
return request({
url: "/admin/qualityControl/home/querySichResult",
method: "post",
data: data,
});
}
// 血管治疗 - DPT
export function queryDptResult(data) {
return request({
url: "/admin/qualityControl/home/queryDptResult",
method: "post",
data: data,
});
}
// 血管治疗 - Rpt
export function queryRptResult(data) {
return request({
url: "/admin/qualityControl/home/queryRptResult",
method: "post",
data: data,
});
}
// 血管治疗 - SJDB
// export function selectXgzl(data) {
// return request({
// url: "/qualityControl/home/selectXgzl",
// method: "post",
// data: data,
// });
// }
export function dataComparison(data) {
return request({
url: "/admin/qualityControl/home/selectXgzl",
method: "post",
data: data,
});
}
// 血管治疗统计
export function queryXgzlLv(data) {
return request({
url: "/admin/qualityControl/home/queryXgzlLv",
method: "post",
data: data,
});
}
// 大屏急救数量统计
export function queryPatientList(data) {
return request({
url: "/admin/qualityControl/home/queryPatientList",
method: "post",
data: data,
});
}
// 大屏急救时长分析
export function queryFirstAidTime(data) {
return request({
url: "/admin/qualityControl/home/queryFirstAidTime",
method: "post",
data: data,
});
}
// 大屏智慧平车面板数据
export function queryData(data) {
return request({
url: "/admin/qualityControl/home/queryData",
method: "post",
data: data,
});
}
// 患者信息
export function patientTotal(data) {
return request({
url: "/admin/statistics/patientTotal",
method: "post",
data: data,
});
}
// 诊疗信息
export function zlInfo(data) {
return request({
url: "/admin/statistics/zlInfo",
method: "post",
data: data,
});
}
// 治疗类型
export function zlType(data) {
return request({
url: "/admin/statistics/zlType",
method: "post",
data: data,
});
}
// 随访分布
export function sffb(data) {
return request({
url: "/admin/statistics/sffb",
method: "post",
data: data,
});
}
export function sftj(data) {
return request({
url: "/admin/statistics/sftj",
method: "post",
data: data,
});
}

14
acupuncture-后台/src/api/medicalFile.js

@ -3,7 +3,7 @@ import request from "@/utils/request";
// 获取列表
export function treatmentQuery(data) {
return request({
url: "/treatment/list",
url: "/admin/treatment/list",
method: "post",
data: data,
});
@ -11,7 +11,7 @@ export function treatmentQuery(data) {
// 添加患者档案
export function treatmentAdd(data) {
return request({
url: "/treatment/add",
url: "/admin/treatment/add",
method: "post",
data: data,
});
@ -19,7 +19,7 @@ export function treatmentAdd(data) {
// 修改患者档案
export function treatmentUpd(data) {
return request({
url: "/treatment/upd",
url: "/admin/treatment/upd",
method: "post",
data: data,
});
@ -27,7 +27,7 @@ export function treatmentUpd(data) {
// 删除患者档案
export function treatmentDel(data) {
return request({
url: "/treatment/del",
url: "/admin/treatment/del",
method: "post",
data: data,
});
@ -35,14 +35,14 @@ export function treatmentDel(data) {
// 档案详情
export function queryRecord(data) {
return request({
url: "/treatment/queryRecord",
url: "/admin/treatment/queryRecord",
method: "post",
data: data,
});
}// 档案详情
export function saveAidRecord(data) {
return request({
url: "/treatment/saveAidRecord",
url: "/admin/treatment/saveAidRecord",
method: "post",
data: data,
});
@ -51,7 +51,7 @@ export function saveAidRecord(data) {
export function queueAdd(data) {
return request({
url: "/patientQueueRelation/add",
url: "/admin/patientQueueRelation/add",
method: "post",
data: data,
});

106
acupuncture-后台/src/api/member.js

@ -0,0 +1,106 @@
import request from "@/utils/request";
// 获取租户列表
export function tenantsList(data) {
return request({
url: "/tenants/list",
method: "post",
data: data,
});
}
// 新增租户
export function tenantsAdd(data) {
return request({
url: "/tenants/add",
method: "post",
data: data,
});
}
// 修改租户
export function tenantsUpd(data) {
return request({
url: "/tenants/upd",
method: "post",
data: data,
});
}
// 删除租户
export function tenantsDel(data) {
return request({
url: "/tenants/del",
method: "post",
data: data,
});
}
// ------ 数据源 ------
// 获取数据源列表
export function dataSourcesList(data) {
return request({
url: "/dataSources/list",
method: "post",
data: data,
});
}// 新增数据源
export function dataSourcesAdd(data) {
return request({
url: "/dataSources/add",
method: "post",
data: data,
});
}
// 修改数据源
export function dataSourcesUpd(data) {
return request({
url: "/dataSources/upd",
method: "post",
data: data,
});
}
// 删除数据源
export function dataSourcesDel(data) {
return request({
url: "/dataSources/del",
method: "post",
data: data,
});
}
// ------ 用户 ------
export function tenantUsersList(data) {
return request({
url: "/tenantUsers/list",
method: "post",
data: data,
});
}// 新增数据源
export function tenantUsersAdd(data) {
return request({
url: "/tenantUsers/add",
method: "post",
data: data,
});
}
// 修改数据源
export function tenantUsersUpd(data) {
return request({
url: "/tenantUsers/upd",
method: "post",
data: data,
});
}
// 删除数据源
export function tenantUsersDel(data) {
return request({
url: "/tenantUsers/del",
method: "post",
data: data,
});
}
//
export function resetPwd(data) {
return request({
url: "/web/resetPwd",
method: "put",
data: data,
});
}

8
acupuncture-后台/src/api/patientFile.js

@ -3,7 +3,7 @@ import request from "@/utils/request";
// 获取列表
export function queryPatient(data) {
return request({
url: "/patient/list",
url: "/admin/patient/list",
method: "post",
data: data,
});
@ -11,7 +11,7 @@ export function queryPatient(data) {
// 添加患者档案
export function patientAdd(data) {
return request({
url: "/patient/add",
url: "/admin/patient/add",
method: "post",
data: data,
});
@ -19,7 +19,7 @@ export function patientAdd(data) {
// 修改患者档案
export function patientUpd(data) {
return request({
url: "/patient/upd",
url: "/admin/patient/upd",
method: "post",
data: data,
});
@ -27,7 +27,7 @@ export function patientUpd(data) {
// 删除患者档案
export function patientDel(data) {
return request({
url: "/patient/del",
url: "/admin/patient/del",
method: "post",
data: data,
});

64
acupuncture-后台/src/api/report.js

@ -0,0 +1,64 @@
import request from "@/utils/request";
// ------ 上报类型 ------
// 查询类型
export function reportList(data) {
return request({
url: "/report/list",
method: "post",
data: data,
});
}
export function reportAdd(data) {
return request({
url: "/report/add",
method: "post",
data: data,
});
}
export function reportUpd(data) {
return request({
url: "/report/upd",
method: "post",
data: data,
});
}
export function reportDel(data) {
return request({
url: "/report/del",
method: "post",
data: data,
});
}
// ------ 上报管理 ------
export function managerQuery(data) {
return request({
url: "/report/queryManager",
method: "post",
data: data,
});
}
export function managerAdd(data) {
return request({
url: "/report/addManager",
method: "post",
data: data,
});
}
export function managerUpd(data) {
return request({
url: "/report/updManager",
method: "post",
data: data,
});
}
export function managerDel(data) {
return request({
url: "/report/delManager",
method: "post",
data: data,
});
}

BIN
acupuncture-后台/src/assets/images/zj.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

2
acupuncture-后台/src/assets/styles/common.css

@ -73,7 +73,7 @@
display: none;
}
>>>.el-dialog__body{
padding: 0px 20px 0px 20px;
padding: 20px;
}
/* .popup >>> .popupAdd2 .popupleft {
width: 55px;

4
acupuncture-后台/src/assets/styles/element-variables.scss

@ -4,7 +4,7 @@
**/
/* theme color */
$--color-primary: #1890ff;
$--color-primary: #c6a268;
$--color-success: #13ce66;
$--color-warning: #ffba00;
$--color-danger: #ff4949;
@ -20,7 +20,7 @@ $--border-color-lighter: #e6ebf5;
$--table-border: 1px solid #dfe6ec;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
$--font-path: "~element-ui/lib/theme-chalk/fonts";
@import "~element-ui/packages/theme-chalk/src/index";

32
acupuncture-后台/src/assets/styles/variables.scss

@ -1,25 +1,25 @@
// base color
$blue:#324157;
$light-blue:#3A71A8;
$red:#C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow:#FEC171;
$panGreen: #30B08F;
$blue: #324157;
$light-blue: #3a71a8;
$red: #c03639;
$pink: #e65d6e;
$green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
// 默认菜单主题风格
$base-menu-color:#bfcbd9;
$base-menu-color-active:#f4f4f5;
$base-menu-background:#304156;
$base-menu-color: #fff;
$base-menu-color-active: #f4f4f5;
$base-menu-background: #70483e;
$base-logo-title-color: #ffffff;
$base-menu-light-color:rgba(0,0,0,.70);
$base-menu-light-background:#ffffff;
$base-menu-light-color: rgba(0, 0, 0, 0.7);
$base-menu-light-background: #ffffff;
$base-logo-light-title-color: #001529;
$base-sub-menu-background:#1f2d3d;
$base-sub-menu-hover:#001528;
$base-sub-menu-background: #70483e;
$base-sub-menu-hover: #69443a;
// 自定义暗色菜单风格
/**
@ -50,5 +50,5 @@ $base-sidebar-width: 200px;
subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color
logoLightTitleColor: $base-logo-light-title-color;
}

8
acupuncture-后台/src/layout/components/Navbar.vue

@ -15,7 +15,7 @@
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
<div class="right-menu">
<template v-if="device !== 'mobile'">
<!-- <template v-if="device !== 'mobile'">
<search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom">
@ -31,7 +31,7 @@
<el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>
</template>
</template> -->
<el-dropdown
class="avatar-container right-menu-item hover-effect"
@ -45,9 +45,9 @@
<router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
<el-dropdown-item @click.native="setting = true">
<!-- <el-dropdown-item @click.native="setting = true">
<span>布局设置</span>
</el-dropdown-item>
</el-dropdown-item> -->
<el-dropdown-item divided @click.native="logout">
<span>退出登录</span>
</el-dropdown-item>

67
acupuncture-后台/src/layout/components/Sidebar/Logo.vue

@ -1,45 +1,80 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<div
class="sidebar-logo-container"
:class="{ collapse: collapse }"
:style="{
backgroundColor:
sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground,
}"
>
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<router-link
v-if="collapse"
key="collapse"
class="sidebar-logo-link"
to="/"
>
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
<h1
v-else
class="sidebar-title"
:style="{
color:
sideTheme === 'theme-dark'
? variables.logoTitleColor
: variables.logoLightTitleColor,
}"
>
{{ title }}
</h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
<h1
class="sidebar-title"
:style="{
color:
sideTheme === 'theme-dark'
? variables.logoTitleColor
: variables.logoLightTitleColor,
}"
>
{{ title }}
</h1>
</router-link>
</transition>
</div>
</template>
<script>
import logoImg from '@/assets/logo/logo.png'
import variables from '@/assets/styles/variables.scss'
import logoImg from "@/assets/images/zj.png";
import variables from "@/assets/styles/variables.scss";
export default {
name: 'SidebarLogo',
name: "SidebarLogo",
props: {
collapse: {
type: Boolean,
required: true
}
required: true,
},
},
computed: {
variables() {
return variables;
},
sideTheme() {
return this.$store.state.settings.sideTheme
}
return this.$store.state.settings.sideTheme;
},
},
data() {
return {
title: process.env.VUE_APP_TITLE,
logo: logoImg
}
}
}
logo: logoImg,
};
},
};
</script>
<style lang="scss" scoped>
@ -69,7 +104,7 @@ export default {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
margin-right: 2px;
}
& .sidebar-title {

5
acupuncture-后台/src/main.js

@ -12,7 +12,8 @@ import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
import { download, download1} from '@/utils/request'
import moment from 'moment';
import './assets/icons' // icon
import './permission' // permission control
@ -47,7 +48,9 @@ Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.download1 = download1
Vue.prototype.handleTree = handleTree
Vue.prototype.$moment = moment
// 全局组件挂载
Vue.component('DictTag', DictTag)

104
acupuncture-后台/src/router/index.js

@ -74,58 +74,58 @@ export const constantRoutes = [
},
],
},
{
path: "/patientFile",
component: Layout,
redirect: "index",
children: [
{
path: "/patientIndex",
component: () => import("@/views/patientFile/index"),
name: "Index",
meta: { title: "患者档案", icon: "dashboard", },
},
],
},
{
path: "/medicalFile",
component: Layout,
redirect: "medicalFile",
children: [
{
path: "/medicalIndex",
component: () => import("@/views/medicalFile/index"),
name: "medicalIndex",
meta: { title: "诊疗档案", icon: "dashboard", },
},
],
},
{
path: "/followFile",
meta: { title: "随访档案", icon: "dashboard", },
component: Layout,
redirect: "followFile",
children: [
{
path: "/followIndex",
component: () => import("@/views/followFile/index"),
name: "followIndex",
meta: { title: "随访队列", icon: "dashboard", },
},
{
path: "/followSubjects",
component: () => import("@/views/followFile/subjects"),
name: "followSubjects",
meta: { title: "随访对象", icon: "dashboard", },
},
{
path: "/followWork",
component: () => import("@/views/followFile/work"),
name: "followWork",
meta: { title: "随访工单", icon: "dashboard", },
},
],
},
// {
// path: "/patientFile",
// component: Layout,
// redirect: "patientFile",
// children: [
// {
// path: "/patientIndex",
// component: () => import("@/views/patientFile/index"),
// name: "patientIndex",
// meta: { title: "患者档案", icon: "dashboard", },
// },
// ],
// },
// {
// path: "/medicalFile",
// component: Layout,
// redirect: "medicalFile",
// children: [
// {
// path: "/medicalIndex",
// component: () => import("@/views/medicalFile/index"),
// name: "medicalIndex",
// meta: { title: "诊疗档案", icon: "dashboard", },
// },
// ],
// },
// {
// path: "/followFile",
// meta: { title: "随访档案", icon: "dashboard", },
// component: Layout,
// redirect: "followFile",
// children: [
// {
// path: "/followIndex",
// component: () => import("@/views/followFile/index"),
// name: "followIndex",
// meta: { title: "随访队列", icon: "dashboard", },
// },
// {
// path: "/followSubjects",
// component: () => import("@/views/followFile/subjects"),
// name: "followSubjects",
// meta: { title: "随访对象", icon: "dashboard", },
// },
// {
// path: "/followWork",
// component: () => import("@/views/followFile/work"),
// name: "followWork",
// meta: { title: "随访工单", icon: "dashboard", },
// },
// ],
// },
{
path: "/user",
component: Layout,

57
acupuncture-后台/src/store/modules/settings.js

@ -1,42 +1,59 @@
import defaultSettings from '@/settings'
import defaultSettings from "@/settings";
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const {
sideTheme,
showSettings,
topNav,
tagsView,
fixedHeader,
sidebarLogo,
dynamicTitle,
} = defaultSettings;
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const storageSetting = JSON.parse(localStorage.getItem("layout-setting")) || "";
const state = {
title: '',
theme: storageSetting.theme || '#409EFF',
title: "",
theme: storageSetting.theme || "#C6A268",
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings,
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
}
tagsView:
storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader:
storageSetting.fixedHeader === undefined
? fixedHeader
: storageSetting.fixedHeader,
sidebarLogo:
storageSetting.sidebarLogo === undefined
? sidebarLogo
: storageSetting.sidebarLogo,
dynamicTitle:
storageSetting.dynamicTitle === undefined
? dynamicTitle
: storageSetting.dynamicTitle,
};
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
state[key] = value;
}
}
}
},
};
const actions = {
// 修改布局设置
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
commit("CHANGE_SETTING", data);
},
// 设置网页标题
setTitle({ commit }, title) {
state.title = title
}
}
state.title = title;
},
};
export default {
namespaced: true,
state,
mutations,
actions
}
actions,
};

33
acupuncture-后台/src/utils/request.js

@ -148,5 +148,38 @@ export function download(url, params, filename, config) {
downloadLoadingInstance.close();
})
}
// 通用下载方法
export function download1(url, params, filename, config) {
downloadLoadingInstance = Loading.service({
text: "正在下载数据,请稍候",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
return service
.post(url, params, {
headers: { "Content-Type": "application/json;charset=utf-8" },
responseType: "blob",
})
.then(async (data) => {
const isBlob = blobValidate(data);
if (isBlob) {
const blob = new Blob([data]);
saveAs(blob, filename);
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg =
errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
Message.error(errMsg);
}
downloadLoadingInstance.close();
})
.catch((r) => {
console.error(r);
Message.error("下载文件出现错误,请联系管理员!");
downloadLoadingInstance.close();
});
}
export default service

BIN
acupuncture-后台/src/views/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

95
acupuncture-后台/src/views/followFile/index.vue

@ -16,6 +16,21 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="组织" prop="tenantId">
<el-select
v-model="queryParams.param.tenantId"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="(item, index) in tenantsListData"
:label="item.name"
:value="item.id"
:key="index"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@ -70,6 +85,7 @@
align="center"
prop="name"
min-width="130"
fixed
/>
<el-table-column
label="随访方式"
@ -111,23 +127,47 @@
min-width="100"
/>
<el-table-column
label="状态"
label="临近提醒时间(天)"
align="center"
prop="status"
prop="remindTime"
show-overflow-tooltip
min-width="130"
/>
<el-table-column
label="窗口期"
align="center"
prop="followWindowAdys"
show-overflow-tooltip
min-width="100"
/>
<el-table-column
fixed="right"
label="组织"
align="center"
show-overflow-tooltip
min-width="130"
>
<template slot-scope="scope">
<span v-if="scope.row.status == 0" style="color: red">禁用</span>
<span v-if="scope.row.status == 1" style="color: green">启用</span>
<span v-if="scope.row.type == 0">公共队列</span>
<span v-else-if="scope.row.type == 1">{{
scope.row.tenantName
}}</span>
</template>
</el-table-column>
<el-table-column
label="创建人/创建时间"
label="状态"
align="center"
min-width="130"
prop="status"
show-overflow-tooltip
min-width="80"
fixed="right"
>
<template slot-scope="scope">
<span v-if="scope.row.status == 0" style="color: #f56c6c">禁用</span>
<span v-else style="color: #67c23a">启用</span>
</template>
</el-table-column>
<el-table-column label="创建人/创建时间" align="center" min-width="140">
<template slot-scope="scope">
<div>{{ scope.row.createBy }}</div>
<span>{{
@ -142,6 +182,7 @@
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
:disabled="scope.row.type != 0"
>修改</el-button
>
<el-button
@ -149,6 +190,7 @@
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
:disabled="scope.row.type != 0"
>删除</el-button
>
</template>
@ -176,7 +218,7 @@
ref="form"
:model="form"
:rules="rules"
label-width="90px"
label-width="130px"
>
<el-form-item label="队列名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
@ -212,6 +254,12 @@
<el-form-item label="总月数" prop="followupMonth">
<el-input v-model="form.followupMonth" placeholder="请输入" />
</el-form-item>
<el-form-item label="临近提醒时间(天)" prop="remindTime">
<el-input v-model="form.remindTime" placeholder="请输入" />
</el-form-item>
<el-form-item label="窗口期" prop="followWindowAdys">
<el-input v-model="form.followWindowAdys" placeholder="请输入" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio :label="1">启用</el-radio>
@ -247,12 +295,15 @@ import {
followupAdd,
followupUpd,
followupDel,
commonQueue,
} from "@/api/followupFile";
import { tenantsList } from "@/api/member";
export default {
name: "Notice",
components: { Crontab },
data() {
return {
tenantsListData: [], //
// Cron
openCron: false,
//
@ -274,12 +325,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -296,6 +352,7 @@ export default {
pageNum: 1,
pageSize: 10,
param: {
tenantId: "", // id
name: "", //
},
},
@ -317,14 +374,36 @@ export default {
frequency: [
{ required: true, message: "随访频次不能为空", trigger: "blur" },
],
followupMonth: [
{ required: true, message: "总月数不能为空", trigger: "blur" },
],
followWindowAdys: [
{ required: true, message: "窗口期不能为空", trigger: "blur" },
],
remindTime: [
{ required: true, message: "临近提醒时间不能为空", trigger: "blur" },
],
frequency: [
{ required: true, message: "随访频次不能为空", trigger: "blur" },
],
status: [{ required: true, message: "状态不能为空", trigger: "blur" }],
},
};
},
created() {
this.getList();
this.getTenantsList(); //
},
methods: {
//
getTenantsList() {
tenantsList({
pageNum: -1,
param: {},
}).then((res) => {
this.tenantsListData = res.data.list;
});
},
/** cron表达式按钮操作 */
handleShowCron() {
this.expression = this.form.cronExpression;
@ -334,6 +413,7 @@ export default {
crontabFill(value) {
this.form.frequency = value;
},
/** 查询公告列表 */
getList() {
this.loading = true;
@ -372,6 +452,7 @@ export default {
pageSize: 10,
param: {
name: "",
tenantId: "",
},
};
this.handleQuery();

141
acupuncture-后台/src/views/followFile/subjects.vue

@ -9,7 +9,11 @@
label-width="68px"
>
<el-form-item label="随访队列" prop="queueId">
<el-select v-model="queryParams.param.queueId" placeholder="请选择">
<el-select
v-model="queryParams.param.queueId"
clearable
placeholder="请选择"
>
<el-option
v-for="item in followupList"
:key="item.id"
@ -19,6 +23,26 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item label="组织" prop="tenantId">
<el-select
v-model="queryParams.param.tenantId"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="(item, index) in tenantsListData"
:label="item.name"
:value="item.id"
:key="index"
/>
</el-select>
</el-form-item>
<el-form-item label="" prop="queueId">
<el-checkbox-group v-model="haveQueue">
<el-checkbox>未参加队列人员</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@ -32,7 +56,6 @@
</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<right-toolbar
:showSearch.sync="showSearch"
@ -47,13 +70,20 @@
max-height="600"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="姓名" align="center" prop="name" width="100" />
<el-table-column
label="姓名"
align="center"
prop="name"
width="100"
fixed
/>
<el-table-column
fixed
label="性别"
align="center"
prop="gender"
show-overflow-tooltip
width="100"
min-width="100"
>
<template slot-scope="scope">
<span v-if="scope.row.gender == 0"></span>
@ -62,11 +92,12 @@
</el-table-column>
<el-table-column
fixed
label="出生日期"
align="center"
prop="birthDate"
show-overflow-tooltip
width="150"
min-width="150"
>
<template slot-scope="scope">
{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}
@ -77,28 +108,28 @@
align="center"
prop="ethnicity"
show-overflow-tooltip
width="100"
min-width="100"
/>
<el-table-column
label="受教育年限"
align="center"
prop="educationYears"
show-overflow-tooltip
width="100"
min-width="100"
/>
<el-table-column
label="手机号码"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column
label="证件类型"
align="center"
prop="idCardType"
show-overflow-tooltip
width="200"
min-width="200"
>
<template slot-scope="scope">
{{ idCardTypeValue[scope.row.idCardType] }}
@ -109,7 +140,7 @@
align="center"
prop="idCard"
show-overflow-tooltip
width="180"
min-width="180"
/>
<el-table-column
fixed="right"
@ -117,7 +148,7 @@
align="center"
prop="queueList"
show-overflow-tooltip
width="180"
min-width="180"
>
<template slot-scope="scope">
<div v-if="scope.row.queueList && scope.row.queueList.length">
@ -125,10 +156,18 @@
</div>
</template>
</el-table-column>
<el-table-column
fixed="right"
prop="tenantName"
label="组织"
align="center"
show-overflow-tooltip
min-width="150"
/>
<el-table-column
label="创建人/创建时间"
align="center"
width="130"
width="140"
fixed="right"
>
<template slot-scope="scope">
@ -140,13 +179,8 @@
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="200">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>队列管理</el-button
>
<!-- <el-button size="mini" type="text" icon="el-icon-edit"
@click="handleUpdate(scope.row)">队列管理</el-button> -->
<el-button
size="mini"
type="text"
@ -210,6 +244,7 @@
<script>
import { queryPatient, followupQuery, updPatient } from "@/api/followupFile";
import { tenantsList } from "@/api/member";
export default {
name: "Notice",
data() {
@ -232,12 +267,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -249,12 +289,17 @@ export default {
title: "", //
open: false, //
importOpen: false, //
tenantsListData: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
param: {},
param: {
tenantId: "",
queueId: "",
},
},
haveQueue: "",
formDisabled: false,
importform: {},
//
@ -262,7 +307,11 @@ export default {
//
rules: {
queueIdList: [
{ required: true, message: "随访队列不能为空", trigger: "change" },
{
required: true,
message: "随访队列不能为空",
trigger: "change",
},
],
},
followupList: [], // 访
@ -271,15 +320,31 @@ export default {
created() {
this.getList();
this.getFollowupQuery();
this.getTenantsList(); //
},
methods: {
//
getTenantsList() {
tenantsList({
pageNum: -1,
param: {},
}).then((res) => {
this.tenantsListData = res.data.list;
});
},
// 访
getFollowupQuery() {
followupQuery({
pageNum: -1,
param: {},
param: {
status: 1,
},
}).then((res) => {
this.followupList = res.data.list;
let commonQueue = JSON.parse(localStorage.getItem("commonQueue"));
commonQueue?.forEach((i) => {
this.followupList.unshift(i);
});
});
},
@ -304,12 +369,22 @@ export default {
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.param.haveQueue = "";
if (this.haveQueue) {
this.queryParams.param.haveQueue = 0;
}
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams = {
param: {
tenantId: "",
queueId: "",
},
};
this.haveQueue = "";
this.handleQuery();
},
//
@ -322,7 +397,7 @@ export default {
handleUpdate(row) {
this.open = true;
this.title = "队列管理";
let queueList = row.queueList.map((item) => item.queueId);
let queueList = row.queueList?.map((item) => item.queueId) || [];
this.form = JSON.parse(
JSON.stringify({
...row,
@ -332,9 +407,17 @@ export default {
);
},
/** 跳转患者档案 */
handlePatient(row) {},
handlePatient(row) {
this.$router.push({
path: `/patientFile/index?idCard=${row.idCard}`,
});
},
/** 诊疗档案 */
handleMedical(row) {},
handleMedical(row) {
this.$router.push({
path: `/medicalFile/index?idCard=${row.idCard}`,
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
@ -354,7 +437,9 @@ export default {
this.$modal
.confirm("是否确认删除当前选择的数据?")
.then(function () {
return patientDel({ idList: idList });
return patientDel({
idList: idList,
});
})
.then(() => {
this.getList();
@ -386,9 +471,11 @@ export default {
display: flex;
align-items: center;
}
.form-item-age span {
margin: 0 10px;
}
.form-item-age >>> .el-input {
width: 100px;
}

317
acupuncture-后台/src/views/followFile/work.vue

@ -1,6 +1,66 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="" prop="keywords">
<el-input
style="width: 300px"
placeholder="姓名、全拼、简拼、手机号码、证件号码"
v-model="queryParams.param.keywords"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="childStatus">
<el-select
v-model="queryParams.param.childStatus"
clearable
placeholder="请选择"
>
<el-option
v-for="item in childStatusList[queryParams.param.status]"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="组织" prop="tenantId">
<el-select
v-model="queryParams.param.tenantId"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="(item, index) in tenantsListData"
:label="item.name"
:value="item.id"
:key="index"
/>
</el-select>
</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>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
@ -19,30 +79,33 @@
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="工单id"
fixed
show-overflow-tooltip
align="center"
prop=""
width="100"
prop="id"
min-width="200"
/>
<el-table-column
fixed
label="随访队列"
show-overflow-tooltip
align=""
prop="name"
width="100"
align="center"
prop="queueName"
min-width="150"
/>
<el-table-column
fixed
label="患者姓名"
align="center"
prop="name"
width="100"
min-width="100"
/>
<el-table-column
label="性别"
align="center"
prop="gender"
show-overflow-tooltip
width="100"
min-width="60"
>
<template slot-scope="scope">
<span v-if="scope.row.gender == 0"></span>
@ -55,43 +118,53 @@
align="center"
prop="age"
show-overflow-tooltip
width="150"
min-width="60"
/>
<el-table-column
label="证件号码"
align="center"
prop="idCard"
show-overflow-tooltip
width="180"
min-width="180"
/>
<el-table-column
label="手机号码"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column
label="随访序号"
label="随访次数"
align="center"
prop="phone"
prop="times"
show-overflow-tooltip
width="150"
min-width="150"
/>
<el-table-column
label="开始时间"
align="center"
prop="startTime"
show-overflow-tooltip
width="150"
/>
min-width="150"
>
<template slot-scope="scope">
<span>{{
parseTime(scope.row.startTime, "{y}-{m}-{d} {h}:{i}")
}}</span>
</template>
</el-table-column>
<el-table-column
label="结束时间"
align="center"
prop="endTime"
show-overflow-tooltip
width="150"
/>
min-width="150"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, "{y}-{m}-{d} {h}:{i}") }}</span>
</template>
</el-table-column>
<!--待随访 随访状态待随访/即将超期/超期 -->
<!--已随访 随访状态已随访/超随访期 -->
<!--待随访 随访状态待随访 -->
@ -100,48 +173,59 @@
align="center"
prop="phone"
show-overflow-tooltip
width="150"
min-width="100"
fixed="right"
>
<template slot-scope="scope">
{{ status[scope.row.status] }}
<span :class="classStatus[scope.row.status]">{{
status[scope.row.status]
}}</span>
</template>
</el-table-column>
<!-- <el-table-column
label="失访状态"
<el-table-column
fixed="right"
prop="tenantName"
label="组织"
align="center"
prop="phone"
show-overflow-tooltip
width="150"
/> -->
min-width="150"
/>
<el-table-column
v-if="queryParams.param.status == 2"
label="失访原因"
align="center"
prop="reason"
show-overflow-tooltip
width="150"
width="200"
/>
<el-table-column fixed="right" label="操作" align="center" width="150">
<el-table-column fixed="right" label="操作" align="center" width="100">
<template slot-scope="scope">
<!-- :disabled="scope.row.status !== '0'" -->
<el-button
:disabled="scope.row.status !== '0'"
size="mini"
type="text"
icon="el-icon-s-check"
@click="handleFollow(scope.row)"
>
访
<!-- 待随访 -->
<!-- <div v-if="queryParams.param.status == 0">
<el-button size="mini" type="text" icon="el-icon-s-check"
@click="handleFollow(scope.row)">
去随访
</el-button>
<el-button size="mini" type="text" icon="el-icon-s-release"
@click="handleLossFollow(scope.row)">
标记失访
</el-button>
</div> -->
<!-- 随访 -->
<el-button
:disabled="scope.row.status !== '0'"
v-if="queryParams.param.status == 1"
size="mini"
type="text"
icon="el-icon-s-release"
@click="handleLossFollow(scope.row)"
icon="el-icon-s-check"
@click="handleDetails(scope.row)"
>
失访
查看详情
</el-button>
<!-- 失访 -->
<!-- <el-button v-if="queryParams.param.status == 2" size="mini" type="text" icon="el-icon-s-check"
@click="handleBeFollow(scope.row)">
标记待随访
</el-button> -->
</template>
</el-table-column>
</el-table>
@ -157,7 +241,7 @@
<!-- 失访 -->
<el-dialog
class="popup"
title="失访"
title="标记失访"
:visible.sync="open"
width="780px"
append-to-body
@ -169,9 +253,6 @@
:rules="rules"
label-width="90px"
>
<el-form-item label="随访次数" prop="times">
<el-input v-model="form.times" placeholder="请输入" />
</el-form-item>
<el-form-item label="失访原因" prop="reason">
<el-select v-model="form.reason" placeholder="请选择">
<el-option-group
@ -211,10 +292,15 @@
label-width="90px"
>
<el-form-item label="随访人" prop="followuper">
<el-input v-model="form.followuper" placeholder="请输入" />
<el-input
:disabled="open1Disabled"
v-model="form.followuper"
placeholder="请输入"
/>
</el-form-item>
<el-form-item label="随访时间" prop="followupTime">
<el-date-picker
:disabled="open1Disabled"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="form.followupTime"
@ -223,15 +309,19 @@
>
</el-date-picker>
</el-form-item>
<el-form-item label="随访次数" prop="times">
<el-input v-model="form.times" placeholder="请输入" />
</el-form-item>
<el-form-item label="随访内容" prop="followupText">
<el-input v-model="form.followupText" placeholder="请输入" />
<el-input
:disabled="open1Disabled"
type="textarea"
v-model="form.followupText"
placeholder="请输入"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm1"> </el-button>
<el-button type="primary" @click="submitForm1" v-if="!open1Disabled"
> </el-button
>
<el-button @click="open1 = false"> </el-button>
</div>
</el-dialog>
@ -239,7 +329,13 @@
</template>
<script>
import { queryTask, updStatus, followPatient } from "@/api/followupFile";
import {
queryTask,
updStatus,
followPatient,
followStatus,
} from "@/api/followupFile";
import { tenantsList } from "@/api/member";
export default {
name: "Notice",
data() {
@ -303,6 +399,29 @@ export default {
4: "超期未随访",
5: "超期已随访",
},
classStatus: {
3: "status3",
4: "status4",
5: "status4",
},
childStatusList: {
0: [
{
label: "即将超期",
value: 1,
},
{
label: "超期未随访",
value: 2,
},
],
1: [
{
label: "超期已随访",
value: 2,
},
],
},
idCardType: [
{
label: "身份证",
@ -320,12 +439,17 @@ export default {
label: "台湾居民来往大陆通行证",
value: 3,
},
{
label: "其他",
value: 4,
},
],
idCardTypeValue: {
0: "身份证",
1: "护照或外国人永居证",
2: "港澳居民来往内地通行",
3: "台湾居民来往大陆通行证",
4: "其他",
},
loading: false, //
ids: [], //
@ -337,6 +461,7 @@ export default {
title: "", //
open: false, //
open1: false, //
open1Disabled: false,
importOpen: false, //
//
queryParams: {
@ -344,8 +469,12 @@ export default {
pageSize: 10,
param: {
status: "0",
childStatus: "",
keywords: "",
tenantId: "",
},
},
tenantsListData: [], //
formDisabled: false,
importform: {},
//
@ -353,29 +482,62 @@ export default {
//
rules: {
followuper: [
{ required: true, message: "随访人不能为空", trigger: "blur" },
{
required: true,
message: "随访人不能为空",
trigger: "blur",
},
],
followupTime: [
{ required: true, message: "随访时间不能为空", trigger: "change" },
{
required: true,
message: "随访时间不能为空",
trigger: "change",
},
],
followupText: [
{ required: true, message: "随访内容不能为空", trigger: "blur" },
{
required: true,
message: "随访内容不能为空",
trigger: "blur",
},
],
times: [
{ required: true, message: "随访次数不能为空", trigger: "blur" },
{
required: true,
message: "随访次数不能为空",
trigger: "blur",
},
],
reason: [
{ required: true, message: "失访原因不能为空", trigger: "change" },
{
required: true,
message: "失访原因不能为空",
trigger: "change",
},
],
},
};
},
created() {
let idCard = this.$route.query.idCard;
this.queryParams.param.keywords = idCard || "";
this.getList();
this.getTenantsList(); //
},
methods: {
//
getTenantsList() {
tenantsList({
pageNum: -1,
param: {},
}).then((res) => {
this.tenantsListData = res.data.list;
});
},
handleClick(tab, event) {
this.queryParams.param.childStatus = "";
this.getList();
},
/** 查询公告列表 */
@ -404,7 +566,9 @@ export default {
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams.param.keywords = "";
this.queryParams.param.childStatus = "";
this.queryParams.param.tenantId = "";
this.handleQuery();
},
//
@ -421,6 +585,7 @@ export default {
/** 随访 */
handleFollow(row) {
this.open1 = true;
this.open1Disabled = false;
this.form = {
id: row.id,
followuper: "",
@ -429,12 +594,36 @@ export default {
followupText: "",
};
},
/** 失访 */
/** 标记失访 */
handleLossFollow(row) {
this.open = true;
this.form = JSON.parse(JSON.stringify(row));
this.form.status = 2;
},
handleDetails(row) {
this.open1 = true;
this.open1Disabled = true;
this.form = JSON.parse(JSON.stringify(row));
},
// 访
handleBeFollow(row) {
let data = {
id: row.id,
status: 0,
};
this.$modal
.confirm(`是否确认将该患者(${row.name})标记为待随访?`)
.then(function () {
return followStatus(data);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("操作成功");
})
.catch((err) => {
console.log("err", err);
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs["form"].validate((valid) => {
@ -485,7 +674,9 @@ export default {
this.$modal
.confirm("是否确认删除当前选择的数据?")
.then(function () {
return patientDel({ idList: idList });
return patientDel({
idList: idList,
});
})
.then(() => {
this.getList();
@ -513,13 +704,21 @@ export default {
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.status3 {
color: orange;
}
.status4 {
color: red;
}
.form-item-age {
display: flex;
align-items: center;
}
.form-item-age span {
margin: 0 10px;
}
.form-item-age >>> .el-input {
width: 100px;
}

1176
acupuncture-后台/src/views/index.vue

File diff suppressed because it is too large

420
acupuncture-后台/src/views/indexCom/JM.vue

@ -0,0 +1,420 @@
<template>
<div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">病种排名</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="diagnose" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">体型分布</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="system" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">体质分布</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="physique" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">体态评估TAPS</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="posture" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">失眠评估PHQ-9</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="agrypnia" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">焦虑HAMD-24</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="anxiety" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
<!-- <div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">失眠评估PHQ-9</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="agrypnia" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">焦虑HAMD-24</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="anxiety" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div> -->
</div>
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { zlInfo } from "@/api/indexCom.js";
import {
diagnoseEcharts,
systemEcharts,
physiqueEcharts,
postureEcharts,
agrypniaEcharts,
anxietyEcharts,
} from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
data() {
return {
queryParams: {
param: {
startTime: "",
endTime: "",
},
},
loading: false,
diagnoseValue: null, //
systemValue: null, //
physiqueValue: null, //
postureValue: null, //
agrypniaValue: null, //
anxietyValue: null, //
//
systemObj: {
yxfpz: "隐形肥胖型", //
zfgdx: "脂肪过多型", //
fpx: "肥胖型", //
jrbzx: "肌肉不足型", //
jkjcx: "健康匀称型", //
czjrx: "超重肌肉型", //
xsx: "消瘦型", //
dzfx: "低脂肪型", //
ydyx: "运动员型", //
},
//
physiqueObj: {
phz: "平和质", //
qxz: "气虚质", //
yangxz: "阳虚质", //
yinxz: "阴虚质", //
tsz: "痰湿质", //湿
srz: "湿热质", //湿
xyz: "血瘀质", //
qyz: "气郁质", //
tlz: "特禀质", //
},
};
},
created() {
// this.Linepatient();
this.getData();
},
methods: {
statistics(_data, _type) {
this.initial(_data, _type); //
this.loading = true;
this.getData(); //
},
//
async getData() {
try {
await zlInfo(this.queryParams).then((res) => {
const { jlfb, smfb, sort, ttfb, txfb, zytz } = res.data;
//
this.diagnoseValue = sort?.sort((a, b) => a.total - b.total);
this.handleDiagnose();
//
this.systemValue = [];
delete txfb?.total;
for (let key in txfb) {
let data = {
name: this.systemObj[key],
value: txfb[key] || 0,
};
this.systemValue.push(data);
}
this.handleSystem();
//
this.physiqueValue = [];
delete zytz?.total;
for (let key in zytz) {
let data = {
name: this.physiqueObj[key],
value: zytz[key] || 0,
};
this.physiqueValue.push(data);
}
this.handlePhysique();
//
this.postureValue = [
{
value: ttfb?.score1 || 0,
name: "1分",
},
{
value: ttfb?.score2 || 0,
name: "2分",
},
{
value: ttfb?.score3 || 0,
name: "3分",
},
{
value: ttfb?.score4 || 0,
name: "4分",
},
{
value: ttfb?.score5 || 0,
name: "5分",
},
];
this.handlePosture();
// PHQ-9
this.agrypniaValue = [];
for (let key in smfb) {
this.agrypniaValue.push(smfb[key]);
}
this.handleAgrypnia();
//
this.anxietyValue = [];
for (let key in jlfb) {
this.anxietyValue.push(jlfb[key]);
}
this.handleAnxiety();
this.loading = false;
});
} catch (e) {
console.log("诊疗信息", e);
}
},
//
handleDiagnose() {
diagnoseEcharts.series[0].data = this.diagnoseValue?.map((item) => {
return item.total;
});
diagnoseEcharts.yAxis.data = this.diagnoseValue?.map((item) => {
return item.diseaseName;
});
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("diagnose"), null, {
height: 300,
});
myChart.setOption(diagnoseEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleSystem() {
systemEcharts.series[0].data = this.systemValue?.map((item) => {
return item.value;
});
systemEcharts.xAxis.data = this.systemValue?.map((item) => {
return item.name;
});
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("system"), null, {
height: 300,
});
myChart.setOption(systemEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handlePhysique() {
physiqueEcharts.series[0].data = this.physiqueValue?.map((item) => {
return item.value;
});
physiqueEcharts.xAxis.data = this.physiqueValue?.map((item) => {
return item.name;
});
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("physique"), null, {
height: 300,
});
myChart.setOption(physiqueEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handlePosture() {
postureEcharts.series[0].data = this.postureValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("posture"), null, {
height: 300,
});
myChart.setOption(postureEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
initial(_data, _type) {
_data[0] = this.$moment(_data[0]).format("YYYY-MM-DD");
_data[1] = this.$moment(_data[1]).format("YYYY-MM-DD");
this.queryParams.param = {
startTime: _data[0] + " " + "00:00:00",
endTime: _data[1] + " " + "23:59:59",
};
},
//
handleAgrypnia() {
agrypniaEcharts.series[0].data = this.agrypniaValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("agrypnia"), null, {
height: 300,
});
myChart.setOption(agrypniaEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleAnxiety() {
anxietyEcharts.series[0].data = this.anxietyValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("anxiety"), null, {
height: 300,
});
myChart.setOption(anxietyEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
getRenew() {
this.handleDiagnose();
this.handleSystem();
this.handlePhysique();
this.handlePosture();
this.handleAgrypnia();
this.handleAnxiety();
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
>>> .el-card__body {
padding: 10px 0 !important;
}
.dis {
display: flex;
}
.header-title {
font-size: 18px;
}
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
.dian-box {
align-items: center;
}
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
.title-box {
justify-content: space-between;
}
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
</style>

388
acupuncture-后台/src/views/indexCom/XGZL.vue

@ -0,0 +1,388 @@
<template>
<div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">治疗类型分布</span>
<div class="dis">
<div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #c6a268"></span>
中西医结合
</div>
<span class="dian" style="background: #d8d8d8"></span>
纯中医
</div>
</div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="healType" style="width: 100%"></div>
</div>
</el-card>
</div>
<!-- <div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">病种方法分布</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="diseaseMethod" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1;">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">病种穴位分布</span>
<div class="dis">
</div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="acupoint" style="width: 100%"></div>
</div>
</el-card>
</div> -->
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">治疗效果</span>
<div class="dis">
<div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #c6a268"></span>
治愈
</div>
<div class="dian-box dis">
<span class="dian" style="background: #906c4a"></span>
显效
</div>
<div class="dian-box dis">
<span class="dian" style="background: #70483e"></span>
好转
</div>
<div class="dian-box dis">
<span class="dian" style="background: #c7bdb1"></span>
无效
</div>
</div>
</div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="effect" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">诊疗费用分布</span>
<div class="dis"></div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="cost" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
<!-- <div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">治疗效果</span>
<div class="dis">
<div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #5C7BD9"></span>
治愈
</div>
<div class="dian-box dis">
<span class="dian" style="background: #91CC75"></span>
显效
</div>
<div class="dian-box dis">
<span class="dian" style="background: #FAC858"></span>
好转
</div>
<div class="dian-box dis">
<span class="dian" style="background: #EE6666"></span>
无效
</div>
</div>
</div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="effect" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">诊疗费用分布</span>
<div class="dis">
</div>
</div>
<div style="height: 300px" v-loading="loading">
<div id="cost" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div> -->
</div>
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { zlType } from "@/api/indexCom.js";
import {
healTypeEcharts,
diseaseMethodEcharts,
effectEcharts,
costEcharts,
} from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
data() {
return {
queryParams: {
param: {
startTime: "",
endTime: "",
},
},
loading: false,
healTypeValue: null, //
diseaseMethod: null, //
effectValue: null, //
costValue: null, //
effectObj: {
zy: "治愈", //
xx: "显效", //
hz: "好转", //
wx: "无效", //
},
};
},
created() {
// this.Linepatient();
this.getData();
},
methods: {
statistics(_data, _type) {
this.initial(_data, _type); //
this.loading = true;
this.getData(); //
},
//
async getData() {
try {
await zlType(this.queryParams).then((res) => {
const { bzfffb, bzxwfb, zlfy, zllxtj, zlxwfb } = res.data;
//
this.healTypeValue = [
{
value: zllxtj?.zxyjh || 0,
name: "中西医结合",
},
{
value: zllxtj?.czy || 0,
name: "纯中医",
},
];
this.handleHealType();
//
// let diseaseMethod = []
// let index = 0
// for(let i in bzfffb){
// for(let k in bzfffb[i]){
// console.log(bzfffb[i][k])
// }
// index ++
// }
// this.handleDiseaseMethod()
//
this.effectValue = [
{
name: "治愈",
value: zlxwfb?.zy || 0,
},
{
name: "显效",
value: zlxwfb?.xx || 0,
},
{
name: "好转",
value: zlxwfb?.hz || 0,
},
{
name: "无效",
value: zlxwfb?.wx || 0,
},
];
this.handleEffect();
//
this.costValue = [
zlfy?.score1 || 0,
zlfy?.score2 || 0,
zlfy?.score3 || 0,
zlfy?.score4 || 0,
zlfy?.score5 || 0,
];
this.handleCost();
this.loading = false;
});
} catch (e) {
console.log("治疗类型", e);
}
},
//
handleHealType() {
healTypeEcharts.series[0].data = this.healTypeValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("healType"), null, {
height: 300,
});
myChart.setOption(healTypeEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleDiseaseMethod() {
// diseaseMethodEcharts.series[0].data = this.diseaseMethod
this.$nextTick(() => {
var myChart = echarts.init(
document.getElementById("diseaseMethod"),
null,
{
height: 300,
}
);
myChart.setOption(diseaseMethodEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleEffect() {
effectEcharts.series[0].data = this.effectValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("effect"), null, {
height: 300,
});
myChart.setOption(effectEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleCost() {
costEcharts.series[0].data = this.costValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("cost"), null, {
height: 300,
});
myChart.setOption(costEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
initial(_data, _type) {
_data[0] = this.$moment(_data[0]).format("YYYY-MM-DD");
_data[1] = this.$moment(_data[1]).format("YYYY-MM-DD");
this.queryParams.param = {
startTime: _data[0] + " " + "00:00:00",
endTime: _data[1] + " " + "23:59:59",
};
},
//
getRenew() {
this.handleHealType();
this.handleEffect();
this.handleCost();
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
>>> .el-card__body {
padding: 10px 0 !important;
}
.dis {
display: flex;
}
.header-title {
font-size: 18px;
}
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
.dian-box {
align-items: center;
}
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
.title-box {
justify-content: space-between;
}
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
</style>

261
acupuncture-后台/src/views/indexCom/follow.vue

@ -0,0 +1,261 @@
<template>
<div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">随访队列分布</span>
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="follow" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">失访原因分布</span>
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="lossFollow" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { sffb, sftj } from "@/api/indexCom.js";
import { followEcharts, lossFollowEcharts } from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
data() {
return {
loading: false,
followValue: [], //
lossFollowValue: [], //
queryParams: {
param: {
startTime: "",
endTime: "",
},
},
};
},
created() {
// this.Linepatient()
this.getData();
},
methods: {
statistics(_data, _type) {
this.initial(_data, _type); //
this.loading = true;
this.getData(); //
},
//
async getData() {
try {
this.followValue = {};
await sffb(this.queryParams).then((res) => {
res.data.forEach((i) => {
let data = [i.dsf, i.ljsf, i.cqsf, i.zc];
this.followValue[i.queueName] = data;
});
this.handleFollow();
});
await sftj(this.queryParams).then((res) => {
this.lossFollowValue = res.data;
this.handleLossFollow();
});
this.loading = false;
} catch (e) {
console.log("随访", e);
}
},
//
handleFollow() {
followEcharts.series = [];
let colorArr = [
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
"#C7BDB1",
"#C6A268",
"#906C4A",
"#70483E",
"#582518",
];
let index = 0;
for (let key in this.followValue) {
let series = {
name: key,
data: this.followValue[key],
type: "bar",
barMaxWidth: 24, //
color: colorArr[index],
};
followEcharts.series.push(series);
index++;
}
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("follow"), null, {
height: 300,
});
myChart.setOption(followEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
// 访
handleLossFollow() {
lossFollowEcharts.series[0].data = this.lossFollowValue?.map((item) => {
return item.num;
});
lossFollowEcharts.xAxis.data = this.lossFollowValue?.map((item) => {
return item.reason;
});
this.$nextTick(() => {
var myChart = echarts.init(
document.getElementById("lossFollow"),
null,
{
height: 300,
}
);
myChart.setOption(lossFollowEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
initial(_data, _type) {
_data[0] = this.$moment(_data[0]).format("YYYY-MM-DD");
_data[1] = this.$moment(_data[1]).format("YYYY-MM-DD");
this.queryParams.param = {
startTime: _data[0] + " " + "00:00:00",
endTime: _data[1] + " " + "23:59:59",
};
},
//
getRenew() {
this.handleFollow();
this.handleLossFollow();
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
>>> .el-card__body {
padding: 10px 0 !important;
}
.dis {
display: flex;
}
.header-title {
font-size: 18px;
}
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
.dian-box {
align-items: center;
}
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
.title-box {
justify-content: space-between;
}
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
</style>

BIN
acupuncture-后台/src/views/indexCom/image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

955
acupuncture-后台/src/views/indexCom/index.js

@ -0,0 +1,955 @@
import * as echarts from "echarts";
// -------- 患者信息统计 --------
// 患者总数
export const HZXX = {
tooltip: {
trigger: "item",
},
title: {
text: "100",
left: "center",
top: "40%",
textStyle: {
textAlign: "center",
color: "#393D4E",
fontSize: 40,
fontWeight: 600,
},
},
grid: {
top: "0%",
left: "0",
right: "0%",
bottom: "0%",
containLabel: true,
},
color: ["#C6A268"],
graphic: {
type: "text",
left: "center",
top: "56%",
style: {
text: "患者总数",
color: "#70798C",
textAlign: "center",
fill: "#999999",
fontSize: 18,
width: "50px",
},
},
series: [
{
type: "pie",
radius: ["60%", "80%"],
avoidLabelOverlap: false,
label: {
show: false,
position: "center",
},
labelLine: {
show: false,
},
data: [],
},
],
};
// 患者性别
export const gende = {
tooltip: {
trigger: "item",
},
title: {
text: "",
left: "center",
top: "40%",
textStyle: {
textAlign: "center",
color: "#393D4E",
fontSize: 40,
fontWeight: 600,
},
},
grid: {
top: "0%",
left: "0",
right: "0%",
bottom: "0%",
containLabel: true,
},
color: ["#70483E", "#C7BDB1"],
series: [
{
type: "pie",
radius: "80%",
avoidLabelOverlap: false,
label: {
show: false,
position: "center",
normal: {
show: true,
position: "inner",
formatter: "{b}:{c}个",
textStyle: {
color: "#fff",
},
},
},
labelLine: {
show: false,
},
data: [],
},
],
};
// 年龄分布
export const ageEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["<40岁", "41-50岁", "51-60岁", "61-70岁", "71-80岁", ">80岁"],
},
grid: {
top: "12%",
left: "4%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#C6A268",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// color: function (params) {
// var colorList = [
// "#C6A268",
// ];
// return colorList[params.dataIndex];
// },
// },
// },
},
],
};
// 病种分布
export const diseaseEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["<40岁", "41-50岁", "51-60岁", "61-70岁", "71-80岁", ">80岁"],
},
grid: {
top: "12%",
left: "6%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 30],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#70483E",
},
],
};
// -------- 诊疗信息统计 --------
// 病种排名
export const diagnoseEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "value",
minInterval: 1,
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
grid: {
top: "4%",
left: "4%",
right: "6%",
bottom: "0%",
containLabel: true,
},
yAxis: {
type: "category",
data: [],
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#906C4A",
},
],
};
// 体型
export const systemEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: [],
},
grid: {
top: "12%",
left: "6%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 34],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#C6A268",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// },
// },
},
],
};
// 体质
export const physiqueEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: [],
},
grid: {
top: "12%",
left: "4%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#70483E",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// },
// },
},
],
};
// 体态
export const postureEcharts = {
tooltip: {
trigger: "item",
},
title: {
text: "",
left: "center",
top: "40%",
textStyle: {
textAlign: "center",
color: "#393D4E",
fontSize: 40,
fontWeight: 600,
},
},
grid: {
top: "0%",
left: "0",
right: "0%",
bottom: "0%",
containLabel: true,
},
color: ["#C7BDB1", "#C6A268", "#906C4A", "#70483E", "#582518"],
series: [
{
type: "pie",
radius: "80%",
avoidLabelOverlap: false,
label: {
show: false,
position: "center",
normal: {
show: true,
position: "inner",
formatter: "{b}:{c}个",
textStyle: {
color: "#fff",
},
},
},
labelLine: {
show: false,
},
data: [],
},
],
};
// 失眠评估
export const agrypniaEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["0~4分", "5~9分", "10~14分", "15~19分", "20~27分"],
},
grid: {
top: "12%",
left: "5%",
right: "5%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#C6A268",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// },
// },
},
],
};
// 焦虑度
export const anxietyEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["<8分", "8~20分", "21~35分", ">35分"],
},
grid: {
top: "12%",
left: "5%",
right: "5%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#70483E",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// },
// },
},
],
};
// -------- 治疗类型 --------
// 治疗类型
export const healTypeEcharts = {
tooltip: {
trigger: "item",
},
title: {
text: "",
left: "center",
top: "40%",
textStyle: {
textAlign: "center",
color: "#393D4E",
fontSize: 40,
fontWeight: 600,
},
},
grid: {
top: "0%",
left: "0",
right: "0%",
bottom: "0%",
containLabel: true,
},
color: ["#C6A268", "#D8D8D8"],
series: [
{
type: "pie",
radius: "80%",
avoidLabelOverlap: false,
label: {
show: false,
position: "center",
normal: {
show: true,
position: "inner",
formatter: "{b}:{c}个",
textStyle: {
color: "#fff",
},
},
},
labelLine: {
show: false,
},
data: [],
},
],
};
// 病种方法
export const diseaseMethodEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["肥胖症", "失眠症", "其他"],
},
grid: {
top: "12%",
left: "5%",
right: "2%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量1:",
data: [1, 2],
type: "bar",
barMaxWidth: 24, //柱图宽度
itemStyle: {
normal: {
//这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
barBorderRadius: [50, 50, 0, 0],
},
},
},
{
name: "数量2:",
data: [1, 3],
type: "bar",
barMaxWidth: 24, //柱图宽度
itemStyle: {
normal: {
//这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
barBorderRadius: [50, 50, 0, 0],
},
},
},
],
};
// 治疗效果
export const effectEcharts = {
tooltip: {
trigger: "item",
},
title: {
text: "",
left: "center",
top: "40%",
textStyle: {
textAlign: "center",
color: "#393D4E",
fontSize: 40,
fontWeight: 600,
},
},
grid: {
top: "0%",
left: "0",
right: "0%",
bottom: "0%",
containLabel: true,
},
color: ["#C6A268", "#906C4A", "#70483E", "#C7BDB1"],
series: [
{
type: "pie",
radius: "80%",
avoidLabelOverlap: false,
label: {
show: false,
position: "center",
normal: {
show: true,
position: "inner",
formatter: "{b}:{c}个",
textStyle: {
color: "#fff",
},
},
},
labelLine: {
show: false,
},
data: [],
},
],
};
// 诊疗费用
export const costEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["<300元", "300 ~ 900元", "900 ~ 2000元", "2000 ~ 5000元", ">5000元"],
},
grid: {
top: "12%",
left: "4%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#C6A268",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// },
// },
},
],
};
// -------- 随访 --------
export const followEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: ["待随访", "临近随访", "超期随访", "正常随访"],
},
grid: {
top: "12%",
left: "4%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [],
};
// 失访原因
export const lossFollowEcharts = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
formatter: function (params) {
let res1 = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res1 +=
"<br/>" +
`<span style="background:${params[i].color};width:12px;display:inline-block;height:12px;border-radius:50%;margin-right:5px;"></span>` +
params[i].seriesName +
" : " +
params[i].value +
"个";
}
return res1;
},
},
xAxis: {
type: "category",
data: [],
},
grid: {
top: "12%",
left: "4%",
right: "4%",
bottom: "0%",
containLabel: true,
},
yAxis: {
name: "数量( 个 )",
type: "value",
minInterval: 1,
nameTextStyle: {
padding: [0, 0, 0, 20],
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
},
},
},
series: [
{
name: "数量:",
data: [],
type: "bar",
barMaxWidth: 24, //柱图宽度
color: "#70483E",
// itemStyle: {
// normal: {
// //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
// barBorderRadius: [50, 50, 0, 0],
// },
// },
},
],
};

373
acupuncture-后台/src/views/indexCom/patient.vue

@ -0,0 +1,373 @@
<template>
<div>
<div class="app-container">
<div class="dis" style="width: 100%">
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">患者总数</span>
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div
style="
height: 300px;
display: flex;
align-items: center;
justify-content: center;
"
v-loading="loading"
>
<div class="div-hz">
<div class="div-hz-icon">
<img src="./image.png" alt="" width="60px" height="60px" />
</div>
<div class="div-hz-num">
<div class="">
{{ HZXXvalue[0].value || 0 }}<span></span>
</div>
<div class="hz-num-title">患者总数</div>
</div>
</div>
<!-- <div id="patienty" style="width: 100%"></div> -->
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">性别数量</span>
<div class="dis">
<div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #70483e"></span>
</div>
<span class="dian" style="background: #c7bdb1"></span>
</div>
</div>
</div>
<!-- 性别统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="gender" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1; margin-right: 20px">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">年龄分布</span>
<div class="dis"></div>
</div>
<!-- 患者总数统计图 -->
<div style="height: 300px" v-loading="loading">
<div id="age" style="width: 100%"></div>
</div>
</el-card>
</div>
<div style="flex: 1">
<el-card shadow="always">
<div class="dis title-box">
<span class="header-title">既往病种分布</span>
<div class="dis">
<!-- <div class="dian-box dis">
<div class="dian-box dis">
<span class="dian" style="background: #4f8bff"></span>
</div>
<span class="dian" style="background: #ffcd6c"></span>
</div> -->
</div>
</div>
<!-- 既往病种分布 -->
<div style="height: 300px" v-loading="loading">
<div id="disease" style="width: 100%"></div>
</div>
</el-card>
</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";
import { patientTotal, queryByDatePatient } from "@/api/indexCom.js";
import { HZXX, HZXXSJFX, gende, ageEcharts, diseaseEcharts } from "./index";
export default {
name: "Post",
props: ["title"],
mixins: [resize],
data() {
return {
loading: false,
HZXXvalue: null, //
gendeValue: null, //
ageValue: null, //
diseaseValue: null, //
queryParams: {
param: {
startTime: "",
endTime: "",
},
},
jwbzObj: {
gxy: "高血压", //
nxgb: "脑血管病", //
exzl: "恶性肿瘤", //
gxb: "冠心病", //
jsjb: "精神疾病", //
whsezcky: "胃和十二指肠溃疡", //
fpz: "肥胖症", //
gzssz: "骨质疏松症", //
ycxXtxjb: "遗传性、先天性疾病", //
tnb: "糖尿病", //尿
mxfxjb: "慢性肺系疾病", //
gzxz: "高脂血症", //
gzjb: "肝脏疾病", //
gmxjb: "过敏性疾病", //
gjy: "关节炎", //
tf: "痛风", //
sySb: "肾炎、肾病", //
other: "其他", //
},
};
},
created() {
// this.Linepatient()
this.getData();
},
methods: {
statistics(_data, _type) {
this.initial(_data, _type); //
this.loading = true;
this.getData(); //
},
//
async getData() {
try {
await patientTotal(this.queryParams).then((res) => {
//
this.HZXXvalue = [
{
value: res.data.totalPatients,
name: "患者总数",
},
];
//
this.gendeValue = [
{
value: res.data.gender.male,
name: "男",
},
{
value: res.data.gender.female,
name: "女",
},
];
//
let ageValue = res.data.age || {};
this.ageValue = [
ageValue.num1 || 0,
ageValue.num2 || 0,
ageValue.num3 || 0,
ageValue.num4 || 0,
ageValue.num5 || 0,
ageValue.num6 || 0,
];
//
let diseaseValue = res.data.jwbz || {};
this.diseaseValue = [];
for (let key in diseaseValue) {
let data = {
name: this.jwbzObj[key],
value: diseaseValue[key] || 0,
};
this.diseaseValue.push(data);
}
// this.Linepatient(); //
this.handleAge(); //
this.columnar(); //
this.handleDisease(); //
});
this.loading = false;
} catch (e) {
console.log("患者统计", e);
}
},
//
Linepatient() {
HZXX.title.text = this.HZXXvalue[0].value;
HZXX.series[0].data = this.HZXXvalue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("patienty"), null, {
height: 300,
});
myChart.setOption(HZXX, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
columnar() {
gende.series[0].data = this.gendeValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("gender"), null, {
height: 300,
});
myChart.setOption(gende, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleAge() {
ageEcharts.series[0].data = this.ageValue;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("age"), null, {
height: 300,
});
myChart.setOption(ageEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
handleDisease() {
diseaseEcharts.series[0].data = this.diseaseValue?.map((item) => {
return item.value;
});
diseaseEcharts.xAxis.data = this.diseaseValue?.map((item) => {
return item.name;
});
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById("disease"), null, {
height: 300,
});
myChart.setOption(diseaseEcharts, true);
myChart.resize();
window.onresize = myChart.resize;
});
},
//
initial(_data, _type) {
_data[0] = this.$moment(_data[0]).format("YYYY-MM-DD");
_data[1] = this.$moment(_data[1]).format("YYYY-MM-DD");
this.queryParams.param = {
startTime: _data[0] + " " + "00:00:00",
endTime: _data[1] + " " + "23:59:59",
};
},
//
getRenew() {
this.Linepatient(); //
this.handleAge(); //
this.columnar(); //
this.handleDisease(); //
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
.div-hz {
background: #c6a268;
width: 80%;
height: 70%;
border-radius: 10px;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 24px;
}
.div-hz-icon {
flex: 1;
}
.div-hz-num {
flex: 1;
font-size: 50px;
color: #ffffff;
text-align: right;
}
.div-hz-num span {
font-size: 24px;
color: #ffffff;
}
.hz-num-title {
font-size: 22px;
color: #ffffff;
}
>>> .el-card__body {
padding: 10px 0 !important;
}
.dis {
display: flex;
}
.header-title {
font-size: 18px;
}
.title-box {
padding: 10px 20px;
border-bottom: 1px solid #dfe6ec;
}
.dian-box {
align-items: center;
}
.dian {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin: 0 10px;
}
.title-box {
justify-content: space-between;
}
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
</style>

179
acupuncture-后台/src/views/indexCom/query.vue

@ -0,0 +1,179 @@
<template>
<div class="app-container">
<div class="title1">
<span class="title-bor"></span>
{{ title }}
</div>
<div>
<div>
<!-- <el-radio-group
v-model="radioValue"
size="small"
style="height: 36px"
@change="radioChange"
>
<el-radio label="0" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="1" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="2" border style="margin: 0 20px 0 0"></el-radio>
<el-radio label="3" border style="margin: 0 20px 0 0"></el-radio>
</el-radio-group> -->
<el-date-picker
v-model="pickerValue"
type="daterange"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="pickerChage"
>
</el-date-picker>
</div>
</div>
</div>
</template>
<script>
// import { deviceType } from "./index.js";
// this.$store.commit('headerFun', data)
export default {
name: "Post",
props: ["title", "type"],
data() {
return {
radioValue: "1",
radioTime: [],
pickerValue: null,
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
created() {
console.log(this.pickerValue, 222);
},
methods: {
radioChange() {
const start = new Date();
const end = new Date();
this.timeType = 4;
if (this.radioValue == 0) {
this.timeType = 4;
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
this.radioTime = [start, end];
}
if (this.radioValue == 1) {
this.timeType = 4;
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
this.radioTime = [start, end];
}
if (this.radioValue == 2) {
this.timeType = 1;
const now = new Date(); //
const nowYear = now.getFullYear(); //
const nowMonth = now.getMonth(); //
const nowDay = now.getDate(); //
const nowDayOfWeek = now.getDay(); //
const jd = Math.ceil((nowMonth + 1) / 3); //
const startDate = new Date(nowYear, (jd - 1) * 3, 1);
const endDate = new Date(nowYear, jd * 3, 0);
this.radioTime = [startDate, endDate];
}
if (this.radioValue == 3) {
this.timeType = 1;
end.setTime(start.getTime());
start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
this.radioTime = [start, end];
}
this.$emit(
"radio-change",
this.pickerValue || this.radioTime,
this.type,
this.timeType
);
},
pickerChage() {
if (!this.pickerValue) {
this.radioChange();
}
console.log(this.pickerValue, 111);
this.radioTime = [];
this.timeType = 4;
if (this.radioValue == 0) {
this.timeType = 4;
}
if (this.radioValue == 1) {
this.timeType = 4;
}
if (this.radioValue == 2) {
this.timeType = 1;
}
if (this.radioValue == 3) {
this.timeType = 1;
}
this.$emit("picker-change", this.pickerValue, this.type, this.timeType);
},
},
};
</script>
<style scoped src="@/assets/styles/common.css"></style>
<style scoped>
. >>> .el-radio--small.is-bordered {
margin-right: 20px !important;
margin-left: 0 !important;
}
>>> .el-radio__input {
display: none;
}
>>> .el-radio__label {
padding-left: 5px;
}
.app-container {
padding: 0;
display: flex;
justify-content: space-between;
}
.title1 {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
}
.title-bor {
display: inline-block;
height: 20px;
width: 6px;
background: #4f8bff;
margin-right: 10px;
border-radius: 8px;
}
</style>

91
acupuncture-后台/src/views/login.vue

@ -1,12 +1,18 @@
<template>
<div class="login">
<div class="login-left"></div>
<div class="login-right">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<h3 class="title">针灸后台管理系统</h3>
<h3 class="title">
登录到
<br />
朱琏针灸联盟数据系统
</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
@ -56,7 +62,7 @@
</el-form-item>
<el-checkbox
v-model="loginForm.rememberMe"
style="margin: 0px 0px 25px 0px"
style="margin: 0px 0px 25px 0px; color: #fff"
>记住密码</el-checkbox
>
<el-form-item style="width: 100%">
@ -77,9 +83,6 @@
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
@ -88,27 +91,41 @@
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
import { commonQueue } from "@/api/followupFile";
export default {
name: "Login",
data() {
return {
codeUrl: "",
loginForm: {
username: "admin",
password: "admin123",
username: "",
password: "",
rememberMe: false,
code: "",
uuid: "",
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" },
{
required: true,
trigger: "blur",
message: "请输入您的账号",
},
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" },
{
required: true,
trigger: "blur",
message: "请输入您的密码",
},
],
code: [
{
required: true,
trigger: "change",
message: "请输入验证码",
},
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }],
},
loading: false,
//
@ -157,7 +174,9 @@ export default {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("username", this.loginForm.username, {
expires: 30,
});
Cookies.set("password", encrypt(this.loginForm.password), {
expires: 30,
});
@ -172,7 +191,12 @@ export default {
this.$store
.dispatch("Login", this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
this.$router
.push({
path: this.redirect || "/",
})
.catch(() => {});
this.getCommonQueue();
})
.catch(() => {
this.loading = false;
@ -183,6 +207,20 @@ export default {
}
});
},
//
getCommonQueue() {
commonQueue({
pageNum: -1,
param: {
status: 1,
},
}).then((res) => {
res.data.list.forEach((i) => {
i.type = 1;
});
localStorage.setItem("commonQueue", JSON.stringify(res.data.list));
});
},
},
};
</script>
@ -193,46 +231,64 @@ export default {
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-image: url("./bg.png");
background-size: cover;
display: flex;
.login-left {
flex: 1.5;
}
.login-right {
flex: 1;
}
}
.title {
font-size: 26 px;
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
text-align: left;
color: #fff;
line-height: 28px;
}
.login-form {
border-radius: 6px;
background: #ffffff;
// background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
@ -245,6 +301,7 @@ export default {
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save