Bladeren bron

Merge branch 'dev1.0' of http://123.207.73.252:3000/lsw/hospital into dev1.0

Ciallo 8 maanden geleden
bovenliggende
commit
82ad5c70b3
43 gewijzigde bestanden met toevoegingen van 850 en 395 verwijderingen
  1. 1 1
      admin-ui/src/App.vue
  2. BIN
      admin-ui/src/assets/images/login-background.jpg
  3. BIN
      admin-ui/src/assets/images/profile.jpg
  4. 87 0
      admin-ui/src/assets/styles/extend.scss
  5. 5 7
      admin-ui/src/assets/styles/ruoyi.scss
  6. 3 3
      admin-ui/src/layout/components/Navbar.vue
  7. 2 0
      admin-ui/src/store/getters.js
  8. 6 0
      admin-ui/src/store/modules/user.js
  9. 184 101
      admin-ui/src/views/index.vue
  10. 1 1
      admin-ui/src/views/login.vue
  11. 1 1
      admin-ui/src/views/system/user/profile/index.vue
  12. 14 12
      admin-ui/src/views/system/user/profile/userAvatar.vue
  13. 6 10
      admin-ui/src/views/system/user/profile/userInfo.vue
  14. 70 22
      admin-ui/src/views/work/follow/record/edit.vue
  15. 28 23
      admin-ui/src/views/work/follow/record/index.vue
  16. 4 1
      admin-ui/src/views/work/follow/template/index.vue
  17. 56 0
      admin-ui/src/views/work/introduction/agreement.vue
  18. 33 31
      admin-ui/src/views/work/introduction/index.vue
  19. 0 46
      admin-ui/src/views/work/patient/check/checkAPI.js
  20. 25 7
      admin-ui/src/views/work/patient/check/checkProjectDetailReport.vue
  21. 5 3
      admin-ui/src/views/work/patient/check/checkReportItem.vue
  22. 29 32
      admin-ui/src/views/work/patient/check/index.vue
  23. 1 1
      admin-ui/src/views/work/patient/index.vue
  24. 47 20
      admin-ui/src/views/work/patient/search.vue
  25. 1 1
      app/App.vue
  26. 25 0
      app/common/common.scss
  27. 8 1
      app/pages.json
  28. 4 3
      app/pages/follow/detail.vue
  29. 19 26
      app/pages/follow/index.vue
  30. 85 0
      app/pages/follow/remind.vue
  31. 8 8
      app/pages/index/index.vue
  32. 21 14
      app/pages/user/index.vue
  33. 5 1
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
  34. 1 1
      ruoyi-admin/src/main/java/com/ruoyi/web/work/api/Api_FollowController.java
  35. 5 6
      ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/FollowRecordController.java
  36. 28 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/IndexController.java
  37. 2 5
      ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/FollowRecord.java
  38. 4 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/mapper/UserMapper.java
  39. 5 2
      ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/FollowRecordServiceImpl.java
  40. 9 2
      ruoyi-admin/src/main/resources/mapper/work/FollowRecordMapper.xml
  41. 9 0
      ruoyi-admin/src/main/resources/mapper/work/UserMapper.xml
  42. 1 1
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  43. 2 2
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

+ 1 - 1
admin-ui/src/App.vue

@@ -21,7 +21,7 @@ export default  {
 /**挂载iconfont字体图标*/
 @font-face {
 	font-family: 'iconfont';
-	src: url('https://at.alicdn.com/t/c/font_4225786_b254k34xnod.ttf?t=1693273272349') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4620946_iqtdfey33er.ttf?t=1722870966842') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

BIN
admin-ui/src/assets/images/login-background.jpg


BIN
admin-ui/src/assets/images/profile.jpg


+ 87 - 0
admin-ui/src/assets/styles/extend.scss

@@ -149,6 +149,9 @@
 .el-steps--horizontal {
   margin-top: 10px;
 }
+.el-textarea.is-disabled .el-textarea__inner {
+  color: #808080 !important;
+}
 .logItem {
   padding-bottom: 8px;
 }
@@ -199,6 +202,31 @@
   padding: 80px 35px 90px 35px;
   margin: 0 auto;
   margin-top: -10px;
+  .message-bubble-received {
+    background: #dcf8c6;
+    border-radius: 10px;
+    padding: 10px;
+    max-width: 80%;
+    word-wrap: break-word;
+    position: relative;
+    margin-left: 10px;
+    float: left;
+    clear: both;
+    font-size: 14px;
+    margin-top: 20px;
+    color: #262626;
+
+    &::before {
+      content: '';
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-style: solid;
+      border-width: 0 10px 10px 10px;
+      border-color: transparent transparent #dcf8c6 transparent;
+      left: -10px;
+    }
+  }
 }
 .guise-mobile-2 {
   left: 20%;
@@ -217,6 +245,28 @@
     background-color: #ddd;
     border-radius: 5px;
   }
+
+  .js {
+    margin-top: 5px;
+    .head {
+      text-align: center;
+      img {
+        width: 100px;
+        height: 140px;
+        border-radius: 5px;
+      }
+    }
+    .name {
+      margin-bottom: 10px;
+      text-align: center;
+      font-weight: bold;
+      font-size: 16px;
+      margin-top: 10px;
+    }
+    .introduce {
+      font-size: 14px;
+    }
+  }
 }
 .mbg {
   background-color: #f1f1f1;
@@ -350,6 +400,7 @@
         border-radius: 3px;
         float: left;
         color: #656363;
+        line-height: 14px;
         &.active {
           background-color: #4581fb;
           color: white;
@@ -361,5 +412,41 @@
     width: 100%;
     background-color: #4581fb;
     border: 0px;
+    margin-top: 10px;
+  }
+}
+.cards {
+  border-radius: 10px;
+  border: 1px solid #1890ff;
+  padding: 20px;
+  overflow: hidden;
+  .avatar {
+    width: 120px;
+    height: 160px;
+    border-radius: 5px;
+    float: left;
+  }
+  .con {
+    padding-left: 15px;
+    float: left;
+    .title {
+      font-weight: bold;
+      font-size: 17px;
+    }
+    .desc {
+      font-size: 17px;
+      padding-top: 5px;
+    }
+    .ntc {
+      font-size: 12px;
+      padding-top: 10px;
+      color: #7b7b7b;
+    }
+    .edit {
+      margin-top: 15px;
+      a {
+        color: white !important;
+      }
+    }
   }
 }

+ 5 - 7
admin-ui/src/assets/styles/ruoyi.scss

@@ -309,21 +309,19 @@ h6 {
 
 /* image */
 .img-circle {
-  border-radius: 50%;
+  border-radius: 5px;
 }
 
 .img-lg {
-  width: 120px;
-  height: 120px;
+  width: 100px;
+  height: 140px;
 }
 
 .avatar-upload-preview {
   position: absolute;
-  top: 50%;
-  transform: translate(50%, -50%);
   width: 200px;
-  height: 200px;
-  border-radius: 50%;
+  height: 240px;
+  border-radius: 5px;
   box-shadow: 0 0 4px #ccc;
   overflow: hidden;
 }

+ 3 - 3
admin-ui/src/layout/components/Navbar.vue

@@ -17,7 +17,7 @@
           <img :src="avatar" class="user-avatar" />
           <div class="cons">
             <div class="nickName">{{user.nickName}}</div>
-            <div class="desc omit">{{user.deptNameStr?user.deptNameStr:'无部门'}}</div>
+            <div class="desc omit">{{user.deptNameStr?user.deptNameStr:'无科室'}}</div>
           </div>
           <i class="el-icon-caret-bottom" />
         </div>
@@ -173,9 +173,9 @@ export default {
 
         .user-avatar {
           cursor: pointer;
-          width: 40px;
+          width: 30px;
           height: 40px;
-          border-radius: 50%;
+          border-radius: 3px;
         }
         .cons {
           float: right;

+ 2 - 0
admin-ui/src/store/getters.js

@@ -9,6 +9,8 @@ const getters = {
   avatar: state => state.user.avatar,
   name: state => state.user.name,
   introduction: state => state.user.introduction,
+  introduce: state => state.user.introduce,
+  nickName:state => state.user.nickName,
   roles: state => state.user.roles,
   permissions: state => state.user.permissions,
   permission_routes: state => state.permission.routes,

+ 6 - 0
admin-ui/src/store/modules/user.js

@@ -5,7 +5,9 @@ const user = {
   state: {
     token: getToken(),
     name: '',
+    nickName:'',
     id:'',
+    introduce:'',
     avatar: '',
     roles: [],
     permissions: []
@@ -33,6 +35,9 @@ const user = {
     deptNameStr: (state, deptNameStr) => {
       state.deptNameStr = deptNameStr
     },
+    introduce: (state, introduce) => {
+      state.introduce = introduce
+    },
     deptId: (state, deptId) => {
       state.deptId = deptId
     },
@@ -81,6 +86,7 @@ const user = {
           commit('SET_nickName', user.nickName)
           commit('deptId', user.deptId);
           commit('phone', user.phonenumber);
+          commit('introduce', user.introduce);
           if(user.dept){
             commit('deptNameStr', user.dept.deptName||'')
             commit('deptId', user.dept.deptId);

+ 184 - 101
admin-ui/src/views/index.vue

@@ -1,133 +1,197 @@
 <template>
   <div class="dashboard-editor-container">
     <div class="mtitle">
-      <span style="font-size: 19px">欢迎使用,{{ user.nickName }}</span>
-      <iframe
-        allowtransparency="true"
-        frameborder="0"
-        width="180"
-        height="36"
-        scrolling="no"
-        style="padding-top: 10px"
-        src="//tianqi.2345.com/plugin/widget/index.htm?s=3&z=2&t=0&v=0&d=2&bd=0&k=&f=#545555&ltf=#545555&htf=ffffff&q=1&e=1&a=1&c=72036&w=180&h=36&align=center"
-      ></iframe>
+      <span style="font-size: 19px">欢迎使用岑溪人民医院随访系统</span>
+      <iframe allowtransparency="true" frameborder="0" width="180" height="36" scrolling="no" style="padding-top: 10px" src="//tianqi.2345.com/plugin/widget/index.htm?s=3&z=2&t=0&v=0&d=2&bd=0&k=&f=#545555&ltf=#545555&htf=ffffff&q=1&e=1&a=1&c=72036&w=180&h=36&align=center"></iframe>
     </div>
-<!--    <panel-group :cdata="data.count" />
     <div class="chart-wrapper">
-      <div class="pop" style="width: 100%">
-        <div class="out" style="margin: 0px; margin-top: 5px">
+      <!--个人形象-->
+      <div class="pop" style="width: 65%">
+        <div class="out">
           <div class="int">
             <div class="bos">
               <div class="lab">
                 <div class="bsg"></div>
-                <div class="tit">
-                  <span>本年每月捐款金额统计</span>
+                <div class="tit">个人形象</div>
+              </div>
+              <div class="cards">
+                <img :src="user.avatar" class="avatar" />
+                <div class="con">
+                  <div class="title">姓名:{{ user.nickName }}</div>
+                  <div class="desc">角色:{{ user.roleName ? user.roleName : '无角色' }}</div>
+                  <div class="desc">科室:{{ user.deptNameStr ? user.deptNameStr : '无科室' }}</div>
+                  <el-button icon="el-icon-edit" type="primary" class="edit">
+                    <router-link to="/user/profile">编辑我的形象</router-link>
+                  </el-button>
+                  <div class="ntc">只有医生才会在小程序上面展示个人形象</div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <!--数据统计-->
+        <div class="out">
+          <div class="int">
+            <div class="bos">
+              <div class="lab">
+                <div class="bsg"></div>
+                <div class="tit">数据统计</div>
+              </div>
+              <div class="yr">
+                <div class="rout" style="padding-left: 0px">
+                  <div class="rint" style="background-color: rgb(242 232 255)">
+                    <div class="icon" style="color: #8642df">&#xe6b6;</div>
+                    <div class="rcon">
+                      <div class="rtt">患者数据</div>
+                      <div class="rdesc">{{ data.count.visit || 0 }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="yr">
+                <div class="rout">
+                  <div class="rint" style="background-color: rgb(255 245 229)">
+                    <div class="icon" style="color: #fab22e">&#xe716;</div>
+                    <div class="rcon">
+                      <div class="rtt">复诊提醒</div>
+                      <div class="rdesc">{{ data.count.up || 0 }}</div>
+                    </div>
+                  </div>
                 </div>
-                <div class="years">
-                  <div class="ctype">
-                    <div class="year" :class="{ active: currentType == index }" @click="currentType = index" v-for="(item, index) in types" :key="index">{{ item.name }}</div>
+              </div>
+              <div class="yr">
+                <div class="rout">
+                  <div class="rint" style="background-color: rgb(237 246 254)">
+                    <div class="icon" style="color: #489afd">&#xe62f;</div>
+                    <div class="rcon">
+                      <div class="rtt">回访记录</div>
+                      <div class="rdesc">{{ data.count.record || 0 }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="yr">
+                <div class="rout" style="padding-right: 0px">
+                  <div class="rint" style="background-color: rgb(255 242 245)">
+                    <div class="icon" style="color: #fa5376">&#xe69a;</div>
+                    <div class="rcon">
+                      <div class="rtt">知识库</div>
+                      <div class="rdesc">{{ data.count.knowledge || 0 }}</div>
+                    </div>
                   </div>
-                  <div class="year" :class="{ active: currentYear == index }" v-for="(item, index) in data.year" :key="index" @click="selectYear(index)">{{ item.year }}年</div>
                 </div>
               </div>
-              <BarChart :chartData="chartData" :type="types[currentType].value"></BarChart>
             </div>
           </div>
         </div>
-      </div>
-      <div class="pop" style="width: 50%; margin-top: 10px">
-        <div class="out" style="margin: 0px">
+        <!--快捷菜单-->
+        <div class="out">
           <div class="int">
             <div class="bos">
               <div class="lab">
                 <div class="bsg"></div>
-                <div class="tit">捐赠项目排名</div>
+                <div class="tit">快捷菜单</div>
+              </div>
+              <div class="yr" style="width: 20%" v-for="(item, index) in menu" :key="item.id" v-hasPermi="[item.hasPermi]">
+                <router-link :to="item.url">
+                  <div class="rout">
+                    <div class="rint" style="text-align: center; cursor: pointer">
+                      <span class="icon" :style="{ float: 'none', color: item.color }" v-html="item.icon">&#xe60d;</span>
+                      <div class="ctt">{{ item.name }}</div>
+                    </div>
+                  </div>
+                </router-link>
               </div>
-              <el-table :data="rankingProject" border height="270">
-                <el-table-column label="捐赠项目" align="left" prop="projectName" />
-                <el-table-column label="累计捐赠次数" align="center" prop="nums" width="130" />
-                <el-table-column label="累计捐赠(¥)" align="center" prop="money" width="150">
-                  <template slot-scope="scope">{{ scope.row.money.toFixed(2) || 0 }} 元</template>
-                </el-table-column>
-              </el-table>
             </div>
           </div>
         </div>
       </div>
-      <div class="pop" style="width: 50%; margin-top: 10px">
-        <div class="out" style="margin: 0px; margin-left: 10px">
+      <!--手机预览-->
+      <div class="pop" style="width: 35%">
+        <div class="out">
           <div class="int">
             <div class="bos">
-              <div class="lab">
-                <div class="bsg"></div>
-                <div class="tit">捐赠金额排名</div>
+              <div class="div-mc">
+                <div class="guise-mobile">
+                  <div class="guise-mobile-show" ref="scrollbar">
+                    <div class="js">
+                      <div class="head"><img :src="user.avatar" /></div>
+                      <div class="name">{{ user.nickName }}</div>
+                      <div class="introduce" v-html="user.introduce" v-if="user.introduce"></div>
+                      <el-empty v-else description="暂无个人介绍" :image-size="80" v-else></el-empty>
+                    </div>
+                  </div>
+                </div>
               </div>
-              <el-table :data="rankingName" border height="270">
-                <el-table-column label="捐赠者(单位/个人)" align="left" prop="projectName">
-                  <template slot-scope="scope">{{ scope.row.NAME || '匿名' }}</template>
-                </el-table-column>
-                <el-table-column label="单笔捐赠(¥)" align="center" prop="money" width="150" />
-                <el-table-column label="捐赠时间" align="center" prop="create_time" width="190" />
-              </el-table>
             </div>
           </div>
         </div>
       </div>
-    </div> -->
+    </div>
   </div>
 </template>
 
 <script>
-import PanelGroup from './dashboard/PanelGroup';
-import BarChart from './dashboard/BarChart';
 import Vue from 'vue';
 export default {
   name: 'Index',
-  components: {
-    PanelGroup,
-    BarChart
-  },
+  components: {},
   data() {
     return {
       user: this.$store.state.user,
-      currentYear: 0, //当前年份
-      currentType: 0, //当前图表类型
-      types: [
-        { name: '柱状图', value: 'bar' },
-        { name: '折线图', value: 'line' }
-      ],
-      data: { count: { total: 0 }, year: [] },
-      chartData: [],
-      rankingProject: [], //捐赠项目排名
-      rankingName: [] //捐赠金额排名
+      data: { count: {} },
+      menu: [
+        {
+          icon: '&#xe6b6;',
+          color: '#607D8B',
+          name: '患者信息',
+          url: '/patient',
+          hasPermi: 'work:patient:list'
+        },
+        {
+          icon: '&#xe716;',
+          color: '#1890ff',
+          name: '复诊提醒',
+          url: '/follow/up',
+          hasPermi: 'work:up:list'
+        },
+        {
+          icon: '&#xe62f;',
+          color: '#FF5722',
+          name: '回访记录',
+          url: '/follow/record',
+          hasPermi: 'work:record:list'
+        },
+        {
+          icon: '&#xe60b;',
+          color: '#4CAF50',
+          name: '回访模板',
+          url: '/follow/template',
+          hasPermi: 'work:template:list'
+        },
+        {
+          icon: '&#xe69a;',
+          color: '#3F51B5',
+          name: '知识库',
+          url: '/knowledge',
+          hasPermi: 'work:knowledge:list'
+        }
+      ]
     };
   },
+  computed: {
+    user() {
+      return this.$store.state.user;
+    }
+  },
   created() {
-    //this.getData();
-    //this.getRanking();
+    this.getData();
   },
   methods: {
     getData() {
       this.ajax({ url: '/home/index' }).then((response) => {
         this.data = response.data;
-        this.currentYear = this.data.year.length - 1;
-        this.getRecord();
-      });
-    },
-    getRanking() {
-      this.ajax({ url: '/home/ranking' }).then((response) => {
-        this.rankingProject = response.data.rankingProject;
-        this.rankingName = response.data.rankingName;
-      });
-    },
-    getRecord() {
-      this.ajax({ url: '/home/record', data: { year: this.data.year[this.currentYear].year } }).then((response) => {
-        this.chartData = response.data;
       });
-    },
-    selectYear(index) {
-      this.currentYear = index;
-      this.getRecord();
     }
   }
 };
@@ -141,19 +205,20 @@ export default {
     margin-top: -15px;
   }
   .chart-wrapper {
-    margin-top: 8px;
+    margin-top: -15px;
     .pop {
       float: left;
       width: 33.33%;
       overflow: hidden;
       .out {
-        margin: 10px;
-        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
+        margin: 16px 10px 10px 10px;
+        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+        border-radius: 10px;
         .int {
           padding: 15px;
           background: #fff;
           overflow: hidden;
-          border-radius: 5px;
+          border-radius: 10px;
         }
       }
     }
@@ -163,24 +228,42 @@ export default {
     padding: 0px 10px 0px 10px;
     width: 100%;
     border: 0px;
-    .years {
-      float: right;
-      margin-top: -30px;
-      overflow: hidden;
-      .ctype {
-        float: left;
-        margin-right: 30px;
-      }
-      .year {
-        float: left;
-        padding: 5px 10px;
-        background-color: #f6f6f6;
-        cursor: pointer;
-        font-size: 14px;
-        color: #545555;
-        &.active {
-          background-color: rgb(64, 158, 255);
-          color: white;
+    .yr {
+      float: left;
+      width: 25%;
+      .rout {
+        padding: 6px;
+        .rint {
+          padding: 10px;
+          border-radius: 5px;
+          overflow: hidden;
+          .icon {
+            float: left;
+            font-size: 30px;
+            background-color: white;
+            border-radius: 50%;
+            padding: 10px;
+            width: 50px;
+            height: 50px;
+            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+          }
+          .rcon {
+            float: left;
+            padding-left: 12px;
+            width: calc(100% - 55px);
+            .rtt {
+              font-size: 14px;
+            }
+            .rdesc {
+              font-weight: bold;
+              padding-top: 7px;
+            }
+          }
+          .ctt {
+            color: #393939;
+            font-size: 15px;
+            padding-top: 19px;
+          }
         }
       }
     }

+ 1 - 1
admin-ui/src/views/login.vue

@@ -156,7 +156,7 @@ export default {
 	padding: 0px 30px 78px 30px;
 	background-color: #fff;
 	box-shadow: 0 6px 12px 0 rgba(0, 0, 0, 0.1);
-	border-radius: 4px;
+	border-radius: 10px;
 	position: absolute;
 	top: 20%;
 	left: 40%;

+ 1 - 1
admin-ui/src/views/system/user/profile/index.vue

@@ -24,7 +24,7 @@
                 <div class="pull-right">{{ user.email }}</div>
               </li>
               <li class="list-group-item" v-if="!user.companyId">
-                所属部门
+                所属科室
                 <div class="pull-right" v-if="user.dept">{{ user.dept.deptName }}</div>
               </li>
               <li class="list-group-item">

+ 14 - 12
admin-ui/src/views/system/user/profile/userAvatar.vue

@@ -1,9 +1,9 @@
 <template>
   <div>
     <div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
-    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened"  @close="closeDialog">
+    <el-dialog :title="title" :visible.sync="open" width="800px" :close-on-click-modal="false" append-to-body @opened="modalOpened"  @close="closeDialog">
       <el-row>
-        <el-col :xs="24" :md="12" :style="{height: '350px'}">
+        <el-col :xs="24" :md="24" :style="{height: '350px'}">
           <vue-cropper
             ref="cropper"
             :img="options.img"
@@ -13,14 +13,13 @@
             :autoCropHeight="options.autoCropHeight"
             :fixedBox="options.fixedBox"
             @realTime="realTime"
+            :fixed="options.fixed"
+            :centerBox="options.centerBox"
+            :outputSize="options.outputSize"
+            :fixedNumber="[1,1.4]"
             v-if="visible"
           />
         </el-col>
-        <el-col :xs="24" :md="12" :style="{height: '350px'}">
-          <div class="avatar-upload-preview">
-            <img :src="previews.url" :style="previews.img" />
-          </div>
-        </el-col>
       </el-row>
       <br />
       <el-row>
@@ -75,9 +74,12 @@ export default {
       options: {
         img: store.getters.avatar, //裁剪图片的地址
         autoCrop: true, // 是否默认生成截图框
-        autoCropWidth: 200, // 默认生成截图框宽度
+        autoCropWidth: 150, // 默认生成截图框宽度
         autoCropHeight: 200, // 默认生成截图框高度
-        fixedBox: true // 固定截图框大小 不允许改变
+				fixed: true, // 是否开启截图框宽高固定比例
+				full: true, //是否输出原图比例的截图
+				fixedBox: false, //固定截图框大小 不允许改变
+				centerBox: true //截图框是否被限制在图片里面
       },
       previews: {}
     };
@@ -149,7 +151,7 @@ export default {
 .user-info-head {
   position: relative;
   display: inline-block;
-  height: 120px;
+  height: 140px;
 }
 
 .user-info-head:hover:after {
@@ -167,6 +169,6 @@ export default {
   -moz-osx-font-smoothing: grayscale;
   cursor: pointer;
   line-height: 110px;
-  border-radius: 50%;
+  border-radius: 5px;
 }
-</style>
+</style>

+ 6 - 10
admin-ui/src/views/system/user/profile/userInfo.vue

@@ -9,11 +9,8 @@
     <el-form-item label="邮箱" prop="email" v-if="!user.companyId">
       <el-input v-model="user.email" maxlength="50" />
     </el-form-item>
-    <el-form-item label="性别" v-if="!user.companyId">
-      <el-radio-group v-model="user.sex">
-        <el-radio label="0">男</el-radio>
-        <el-radio label="1">女</el-radio>
-      </el-radio-group>
+    <el-form-item label="简介" prop="introduce">
+      <editor v-model="user.introduce" placeholder="请输入" :height="400"></editor>
     </el-form-item>
     <el-form-item>
       <el-button type="primary" @click="submit">保存</el-button>
@@ -24,7 +21,7 @@
 
 <script>
 import { updateUserProfile } from '@/api/system/user';
-
+import store from '@/store';
 export default {
   props: {
     user: {
@@ -37,7 +34,6 @@ export default {
       rules: {
         nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
         email: [
-          { required: true, message: '邮箱地址不能为空', trigger: 'blur' },
           {
             type: 'email',
             message: '请输入正确的邮箱地址',
@@ -60,9 +56,9 @@ export default {
         if (valid) {
           updateUserProfile(this.user).then((response) => {
             this.$modal.msgSuccess('修改成功');
-            setTimeout(() => {
-              location.reload(true);
-            }, 1000);
+            store.commit('SET_nickName', this.user.nickName);
+            store.commit('introduce', this.user.introduce);
+            this.$tab.closePage();
           });
         }
       });

+ 70 - 22
admin-ui/src/views/work/follow/record/edit.vue

@@ -1,22 +1,63 @@
 <template>
   <div class="cmain">
-    <el-form ref="form" :model="form" :rules="rules" label-width="100px">
-      <el-form-item label="所属科室" prop="deptName">
-        <el-input v-model="form.deptName" placeholder="请输入标题" disabled />
-      </el-form-item>
-      <el-form-item label="回访模板" prop="templateName">
-        <el-select v-model="form.templateName" placeholder="请选择模板" @change="change">
-          <el-option v-for="item in templateList" :key="item.title" :label="item.title" :value="item.title" clearable></el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="发送患者" prop="templateList">
-        <div class="patients">
-          <el-tag size="medium" class="patient" v-for="item in form.patientList" :key="item.name" closable @close="del(item)">{{ item.name }}</el-tag>
-          <el-button type="primary" icon="el-icon-search" @click="selectPatient()" class="btn">添加</el-button>
-        </div>
-      </el-form-item>
+    <el-form ref="form" :model="form" :rules="rules" :disabled="param.detail" label-width="100px">
+      <el-row>
+        <el-col :span="14">
+          <el-form-item label="所属科室" prop="deptName">
+            <el-input :value="$store.state.user.deptNameStr" placeholder="请输入标题" disabled />
+          </el-form-item>
+          <el-form-item label="提醒标题" prop="templateName" v-if="form.type == 0">
+            <el-input v-model="form.templateName" placeholder="请输入提醒标题, 例如:体检异常复检" clearable />
+          </el-form-item>
+          <el-form-item label="回访模板" prop="templateName" v-if="form.type == 1">
+            <el-select v-model="form.templateName" placeholder="请选择模板" @change="change">
+              <el-option v-for="item in templateList" :key="item.title" :label="item.title" :value="item.title" clearable></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="发送患者" :prop="form.id ? '' : 'patientList'">
+            <div v-if="form.id">
+              <el-tag size="medium" class="patient">{{ param.patientName }}</el-tag>
+            </div>
+            <div class="patients" v-else>
+              <el-tag size="medium" class="patient" v-for="item in form.patientList" :key="item.name" closable @close="del(item)">{{ item.name }}</el-tag>
+              <el-button type="primary" icon="el-icon-plus" @click="selectPatient()" class="btn">添加</el-button>
+            </div>
+          </el-form-item>
+          <el-form-item label="提醒内容" prop="op" v-if="form.type == 0">
+            <el-input v-model="form.op" type="textarea" placeholder="例如:根据您于本院做的体检结果异常,请到岑溪人民医院做复诊" rows="5" clearable />
+          </el-form-item>
+        </el-col>
+        <el-col :span="10">
+          <div class="div-mc">
+            <div class="guise-mobile">
+              <div class="guise-mobile-show" ref="scrollbar">
+                <div class="mttv">{{ form.templateName }}</div>
+                <div class="message-bubble-received" v-if="form.type == 0">{{ form.op }}</div>
+                <div class="items" v-for="(item, index) in op" :key="index">
+                  <div class="vtitle" style="font-weight: normal; font-size: 14px">
+                    <span class="ifnull" v-if="item.ifnull == '必填'">*</span>
+                    <span class="index">{{ index + 1 }},</span>
+                    <span class="tm">{{ item.name }} ({{ item.input }})</span>
+                  </div>
+                  <div class="mts">
+                    <input v-if="item.input == '填空'" placeholder="请输入" :disabled="true" />
+                    <textarea v-if="item.input == '多行文本'" :disabled="true" placeholder="请输入"></textarea>
+                    <input type="number" v-if="item.input == '数字'" placeholder="请输入" :disabled="true" />
+                    <div class="ops">
+                      <div v-for="(op, i) in item.selects" :key="op.name">
+                        <div class="op">{{ op.name }}</div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <el-button type="primary" class="tjiao" v-if="form.type == 1 && form.templateName != null">提交</el-button>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
     </el-form>
-    <div class="mfooter">
+    <div class="mfooter" v-if="!param.detail">
       <el-button type="primary" @click="submitForm">确 定</el-button>
       <el-button @click="$layer.close(layerid)">取 消</el-button>
     </div>
@@ -29,21 +70,30 @@ export default {
   data() {
     return {
       form: {
-        deptName: this.$store.state.user.deptNameStr,
+        op: '根据您于本院做的体检结果异常,请到岑溪人民医院做复诊',
         patientList: []
       },
       templateList: [],
+      op: [],
       rules: {
-        templateName: [{ required: true, message: '不能为空', trigger: 'blur' }]
+        templateName: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        patientList: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        op: [{ required: true, message: '不能为空', trigger: 'blur' }]
       }
     };
   },
   mounted() {
-    this.getTemplate();
+    if (this.param.type == 1) {
+      this.getTemplate();
+    }
     if (this.param.id) {
       this.ajax({ url: '/work/record/detail/' + this.param.id }).then((response) => {
         this.form = response.data;
+        this.op = JSON.parse(response.data.op);
       });
+    } else {
+      this.form.type = this.param.type;
+      this.$forceUpdate();
     }
   },
   methods: {
@@ -55,6 +105,7 @@ export default {
     change(e) {
       let item = this.templateList.filter((item) => item.title == e)[0];
       this.form.op = item.op;
+      this.op = JSON.parse(item.op);
     },
     selectPatient() {
       this.iframe({ obj: selectPatient, param: {}, title: '选择推送患者', width: '60%', height: '75%' });
@@ -89,8 +140,5 @@ export default {
   .patient {
     margin-right: 10px;
   }
-  .btn {
-    margin-left: 15px;
-  }
 }
 </style>

+ 28 - 23
admin-ui/src/views/work/follow/record/index.vue

@@ -1,14 +1,11 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
-      <el-form-item label="问题模板id" prop="templateId">
-        <el-input v-model="queryParams.templateId" placeholder="请输入问题模板id" @keyup.enter.native="handleQuery" clearable class="inp" />
+      <el-form-item label="科室" prop="deptId">
+        <dtree v-model="queryParams.deptId" @handleQuery="handleQuery" :tree="false"></dtree>
       </el-form-item>
-      <el-form-item label="患者id" prop="userId">
-        <el-input v-model="queryParams.userId" placeholder="请输入患者id" @keyup.enter.native="handleQuery" clearable class="inp" />
-      </el-form-item>
-      <el-form-item label="状态" prop="state">
-        <el-input v-model="queryParams.state" placeholder="请输入状态" @keyup.enter.native="handleQuery" clearable class="inp" />
+      <el-form-item label="患者姓名" prop="patientName">
+        <el-input v-model="queryParams.patientName" placeholder="请输入患者姓名" @keyup.enter.native="handleQuery" clearable class="inp" />
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
@@ -16,26 +13,33 @@
       </el-form-item>
     </el-form>
     <el-row :gutter="10" class="mb8">
-      <el-button type="primary" icon="el-icon-plus" :disabled="ids.length > 0" @click="op('add')" v-hasPermi="['work:record:add']">新增</el-button>
-      <el-button type="danger" icon="el-icon-delete" :disabled="ids.length == 0" @click="del" v-hasPermi="['work:record:remove']">删除{{ ids.length > 0 ? '(' + ids.length + ')' : '' }}</el-button>
+      <el-button type="primary" icon="el-icon-plus" :disabled="ids.length > 0" @click="op('add')" v-hasPermi="['work:record:add', 'work:up:add']">{{ queryParams.type == 0 ? '新增提醒' : '新增回访' }}</el-button>
+      <el-button type="danger" icon="el-icon-delete" :disabled="ids.length == 0" @click="del" v-hasPermi="['work:record:remove', 'work:up:remove']">删除{{ ids.length > 0 ? '(' + ids.length + ')' : '' }}</el-button>
     </el-row>
 
     <el-table :data="response.rows" border @selection-change="selects" height="calc(100vh - 270px)">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="回访模板" align="center" prop="templateName" />
-      <el-table-column label="患者姓名" align="center" prop="patientName" />
+      <el-table-column :label="queryParams.type == 0 ? '提醒标题' : '模板名称'" align="left" prop="templateName" />
+      <el-table-column label="患者姓名" align="center" prop="patientName" width="160" />
       <el-table-column label="状态" align="center" prop="state" width="140">
         <template slot-scope="scope">
-          <el-tag type="danger" v-if="scope.row.state == 0">待回访</el-tag>
-          <el-tag type="success" v-if="scope.row.state == 1">已回访</el-tag>
+          <div v-if="queryParams.type == 0">
+            <el-tag type="success">已推送</el-tag>
+          </div>
+          <div v-else>
+            <el-tag type="danger" v-if="scope.row.state == 0">待回访</el-tag>
+            <el-tag type="success" v-if="scope.row.state == 1">已回访</el-tag>
+          </div>
         </template>
       </el-table-column>
-      <el-table-column label="创建人" align="center" prop="createBy" width="130" />
+      <el-table-column label="创建人" align="center" prop="createBy" width="160" />
       <el-table-column label="创建时间" align="center" prop="createTime" width="160" />
       <el-table-column label="所属科室" align="center" prop="deptName" width="160" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center" width="180">
         <template slot-scope="scope">
-          <el-button size="mini" type="text" icon="el-icon-delete" @click="del(scope.row)" v-hasPermi="['work:record:remove']">删除</el-button>
+          <el-button size="mini" type="text" icon="el-icon-view" @click="op('detail', scope.row)" v-hasPermi="['work:record:list', 'work:up:list']">查看</el-button>
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="op('edit', scope.row)" v-hasPermi="['work:record:edit', 'work:up:edit']">编辑</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="del(scope.row)" v-hasPermi="['work:record:remove', 'work:up:remove']">删除</el-button>
         </template>
       </el-table-column>
       <template slot="empty">
@@ -55,17 +59,16 @@ export default {
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        templateId: null,
-        userId: null,
         state: null,
-        doctorId: null,
         deptId: null,
-        orderByColumn: 'id', //排序字段
+        patientName: null,
+        orderByColumn: 'k.id', //排序字段
         isAsc: 'desc' //排序方式
       }
     };
   },
   created() {
+    this.queryParams.type = this.$route.path == '/follow/up' ? 0 : 1;
     this.getList();
   },
   methods: {
@@ -87,11 +90,13 @@ export default {
     },
     op(tag, row) {
       if (tag == 'add') {
-        this.iframe({ obj: edit, param: {}, title: '新增', width: '45%', height: '55%' });
+        this.iframe({ obj: edit, param: { type: this.queryParams.type }, title: this.queryParams.type == 0 ? '新增提醒' : '新增回访', width: '55%', height: '77%' });
       }
       if (tag == 'edit') {
-        const id = row.id || this.ids[0];
-        this.iframe({ obj: edit, param: { id: id }, title: '编辑', width: '50%', height: '50%' });
+        this.iframe({ obj: edit, param: { id: row.id, type: this.queryParams.type, patientName: row.patientName }, title: '编辑', width: '55%', height: '77%' });
+      }
+      if (tag == 'detail') {
+        this.iframe({ obj: edit, param: { id: row.id, detail: true, patientName: row.patientName }, title: '查看详情', width: '55%', height: '77%' });
       }
     },
     del(row) {

+ 4 - 1
admin-ui/src/views/work/follow/template/index.vue

@@ -8,7 +8,10 @@
         <el-input v-model="queryParams.title" placeholder="请输入标题" @keyup.enter.native="handleQuery" clearable class="inp" />
       </el-form-item>
       <el-form-item label="状态" prop="state">
-        <el-input v-model="queryParams.state" placeholder="请输入状态" @keyup.enter.native="handleQuery" clearable class="inp" />
+        <el-select v-model="queryParams.state" placeholder="请选择状态" clearable class="se">
+          <el-option value="0" label="启用"></el-option>
+          <el-option value="1" label="停用"></el-option>
+        </el-select>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>

+ 56 - 0
admin-ui/src/views/work/introduction/agreement.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="app-container" style="overflow-y: auto">
+    <div class="cmain">
+      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+        <div class="bos">
+          <div class="lab">
+            <div class="bsg"></div>
+            <div class="tit">协议(小程序上架需要)</div>
+          </div>
+          <el-form-item label="用户协议" prop="privacy">
+            <editor v-model="form.agreement" placeholder="请输入"></editor>
+          </el-form-item>
+          <el-form-item label="隐私政策" prop="privacy">
+            <editor v-model="form.privacy" placeholder="请输入"></editor>
+          </el-form-item>
+        </div>
+      </el-form>
+      <div>
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="$layer.close(layerid)">取 消</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      form: {},
+      rules: {
+        privacy: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        agreement: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    };
+  },
+  mounted() {
+    this.ajax({ url: '/work/introduction/detail' }).then((response) => {
+      this.form = response.data;
+    });
+  },
+  methods: {
+    submitForm() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          if (this.form.id) {
+            this.ajax({ method: 'post', url: '/work/introduction/edit', data: this.form }).then((response) => {
+              this.$modal.msgSuccess('修改成功');
+            });
+          }
+        }
+      });
+    }
+  }
+};
+</script>

+ 33 - 31
admin-ui/src/views/work/introduction/index.vue

@@ -1,38 +1,40 @@
 <template>
   <div class="app-container" style="overflow-y: auto">
     <div class="cmain">
-      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
-        <div class="bos">
-          <div class="lab">
-            <div class="bsg"></div>
-            <div class="tit">医院基本信息</div>
+      <el-row>
+        <el-col :span="16">
+          <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+            <div class="bos">
+              <div class="lab">
+                <div class="bsg"></div>
+                <div class="tit">医院基本信息</div>
+              </div>
+              <el-form-item label="医院电话" prop="phone">
+                <el-input v-model="form.phone" placeholder="请输入" clearable />
+              </el-form-item>
+              <el-form-item label="医院邮箱" prop="email">
+                <el-input v-model="form.email" placeholder="请输入" clearable />
+              </el-form-item>
+              <el-form-item label="医院介绍" prop="brief">
+                <editor v-model="form.brief" placeholder="请输入"></editor>
+              </el-form-item>
+            </div>
+          </el-form>
+        </el-col>
+        <el-col :span="8">
+          <div class="div-mc">
+            <div class="guise-mobile">
+              <div class="guise-mobile-show" ref="scrollbar">
+                <div class="js">
+                  <div class="introduce" v-html="form.brief" v-if="form.brief"></div>
+                  <el-empty v-else description="暂无个人介绍" :image-size="80" v-else></el-empty>
+                </div>
+              </div>
+            </div>
           </div>
-          <el-form-item label="医院电话" prop="phone">
-            <el-input v-model="form.phone" placeholder="请输入" clearable />
-          </el-form-item>
-          <el-form-item label="医院地址" prop="address">
-            <el-input v-model="form.address" placeholder="请输入" clearable />
-          </el-form-item>
-          <el-form-item label="医院邮箱" prop="email">
-            <el-input v-model="form.email" placeholder="请输入" clearable />
-          </el-form-item>
-          <el-form-item label="医院介绍" prop="brief">
-            <editor v-model="form.brief" placeholder="请输入"></editor>
-          </el-form-item>
-        </div>
-        <div class="bos">
-          <div class="lab">
-            <div class="bsg"></div>
-            <div class="tit">协议(小程序上架需要)</div>
-          </div>
-          <el-form-item label="用户协议" prop="privacy">
-            <editor v-model="form.agreement" placeholder="请输入"></editor>
-          </el-form-item>
-          <el-form-item label="隐私政策" prop="privacy">
-            <editor v-model="form.privacy" placeholder="请输入"></editor>
-          </el-form-item>
-        </div>
-      </el-form>
+        </el-col>
+      </el-row>
+
       <div>
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="$layer.close(layerid)">取 消</el-button>

+ 0 - 46
admin-ui/src/views/work/patient/check/checkAPI.js

@@ -1,46 +0,0 @@
-import service from "@/utils/request";
-import {OBX_INIT_VALUE} from "@/views/work/patient/check/checkInitValues";
-
-/**
- * 获取患者的某一页检查项目列表
- * @param {string} patientId 患者id
- * @param {{pageNum: number, pageSize: number}} paginationQueryParam 分页查询参数
- * @return {{rows: import('index').ObxList, total: number,pages: number} }
- */
-export function getPageObxList(patientId, paginationQueryParam) {
-  /**
-   * @type {{rows: import('index').ObxList, total: number,pages: number} }
-   */
-  let result
-  service.get(`/work/result/patid/${patientId}`, (result) => {}, {
-    data: paginationQueryParam
-  }).then((response) => {
-
-    const {rows, total, pages} = response.data
-
-    result = {
-      rows,
-      total,
-      pages,
-    }
-  }).catch((error) => {
-    console.log(error)
-    result = {
-      rows: [OBX_INIT_VALUE],
-      total: 0,
-      pages: 0
-    }
-  })
-  return result
-}
-
-/**
- * 获取详细检测报告
- * @param patientId
- */
-export function getObr(patientId) {
-  service.get(`/work/request/patid/${patientId}`)
-  .then((response) => {
-    console.log(response)
-  })
-}

+ 25 - 7
admin-ui/src/views/work/patient/check/checkProjectDetailReport.vue

@@ -5,9 +5,6 @@ export default {
   name: "checkDetailReport",
   components: { CheckReportItem },
   props: {
-    /**
-     * @type {import('index').Obr}
-     */
     obr: {
       type: Object,
       required: true,
@@ -47,19 +44,39 @@ export default {
       // },
       reportItemLabelList: [
         { key: "reportNo", label: "报告单号" },
-        { key: "medTechProCode", label: "医技号" },
+        // { key: "medTechProCode", label: "医技号" },
         { key: "medTechProName", label: "医技项目名称" },
         { key: "reportClass", label: "报告单类别名称" },
-        { key: "report_complete_time", label: "报告完成时间" },
+        { key: "reportCompleteTime", label: "报告完成时间" },
         { key: "signs", label: "危机标志" },
         { key: "sampleReceivedDate", label: "样本收到日期" },
         { key: "checkpoint", label: "检查部位或样本" },
         { key: "executeDepartmentName", label: "执行科室名称" },
-        { key: "applyDoctorName", label: "申请医生" },
-        { key: "testingDoctorName", label: "检验医生信息名称" },
+        // { key: "applyDoctorName", label: "申请医生" },
+        // { key: "testingDoctorName", label: "检验医生信息名称" },
         { key: "reviewDoctorName", label: "审核医生" },
         { key: "reportDate", label: "报告单日期" },
       ],
+      /*
+      {
+    "id": 27,
+    "orcId": 27,
+    "medTechProCode": null,
+    "medTechProName": "丙型肝炎抗体测定(Anti-HCV),人免疫缺陷病毒抗体测定(Anti-HIV),梅毒螺旋体特异抗体测定",
+    "reportClass": "3",
+    "reportCompleteTime": "2024-07-23 11:43:50",
+    "signs": "0",
+    "sampleReceivedDate": "2024-07-22 09:50:34",
+    "checkpoint": "血清",
+    "executeDepartmentCode": "313",
+    "executeDepartmentName": "检验科",
+    "isFlag": "0",
+    "reviewDoctorCode": "1356",
+    "reviewDoctorName": "梁静",
+    "reportDate": "2024-07-23 11:43:50",
+    "reportNo": "3455018"
+}
+       */
     };
   },
   created() {
@@ -89,5 +106,6 @@ export default {
   justify-content: space-evenly;
 
   flex-wrap: wrap;
+  overflow: scroll;
 }
 </style>

+ 5 - 3
admin-ui/src/views/work/patient/check/checkReportItem.vue

@@ -40,10 +40,11 @@ export default {
     :style="`width: ${itemWidth};`"
   >
     <div class="check-report-item-label">
-      {{ reportLabel }}
+      <p>{{ reportLabel }}</p>
+
     </div>
     <div class="check-report-item-content">
-      {{ reportContent }}
+      <p>{{ reportContent }}</p>
     </div>
   </div>
 </template>
@@ -61,6 +62,8 @@ export default {
   margin-right: -1px;
   margin-bottom: -1px;
   box-sizing: border-box;
+
+  align-content: center;
 }
 
 .check-report-item-label {
@@ -70,7 +73,6 @@ export default {
   font-size: 14px;
   padding-left: 2%;
 
-  overflow-x: hidden;
 }
 
 .check-report-item-content {

+ 29 - 32
admin-ui/src/views/work/patient/check/index.vue

@@ -3,12 +3,12 @@ import CheckDetailReport from "@/views/work/patient/check/checkProjectDetailRepo
 
 import {
   OBR_INIT_VALUE,
-  PATIENT_INIT_VALUE,
+
 } from "@/views/work/patient/check/checkInitValues";
-import { getPageObxList } from "@/views/work/patient/check/checkAPI";
+
+import service from "@/utils/request";
 
 export default {
-  methods: { getPageObxList },
   components: { CheckDetailReport },
   name: "PatientCheck",
   props: {
@@ -28,22 +28,16 @@ export default {
   },
   data() {
     return {
-      /**
-       * 控制对话框是否显示,true是显示对话框
-       * @type {boolean}
-       */
-      dialogVisible: true,
-      reportTabDisabled: false,
+
+      testData: null,
 
       /**
        * 当前检查项目相关信息
-       * @property {import('index').Patient} patient - 当前要查看的患者
        * @property {number} obxTotal - 患者检查项目总数
        * @property {import('./index').ObxList} pageObxList - 当前要查看的患者的所有检查项目,注意是分页后的某一的结果
        * @property {import('./index').Obr} obr - 当前需要查看的详细检测报告
        */
       currentCheckInfo: {
-        patient: PATIENT_INIT_VALUE,
         obxTotal: 0,
         pageObxList: [],
         obxQueryParams: {
@@ -54,23 +48,33 @@ export default {
       },
     };
   },
-  created() {
+  watch: {
+    checkWindowShow: {
+      handler: function (newVal) {
+        // console.log(`checkWindowShow的值被设为${newVal}`)
+        if(newVal) {
 
-      if (this.$props.checkWindowShow) {
-        /**
-         * 请求结果
-         * @type {{rows: import('index').ObxList, total: number, pages: number}}
-         */
-        const { rows, total, pages } = getPageObxList(
-          this.patientInfo.id,
-          this.currentCheckInfo.obxQueryParams,
-        );
+          service.get(`work/result/list`)
+          .then(res => {
+            this.currentCheckInfo.pageObxList = res.rows
+          })
+        }
 
-        this.currentCheckInfo.pageObxList = rows;
-        this.currentCheckInfo.obxTotal = total;
       }
-
+    }
   },
+  methods: {
+    showDetailReport (obrId) {
+
+      service.get(`work/request/patid/${this.patientInfo.id}`)
+      .then(res => {
+
+
+        this.currentCheckInfo.obr = res.rows.find(item => item.id === obrId)
+        console.log(this.currentCheckInfo.obr)
+      })
+    }
+  }
 };
 </script>
 
@@ -133,7 +137,7 @@ export default {
                   <el-button
                     type="text"
                     icon="el-icon-search"
-                    @click="console.log(`查看${scope.row.obrId}`)"
+                    @click="showDetailReport(scope.row.obrId)"
                   >
                     查看详细检验报告
                   </el-button>
@@ -146,12 +150,6 @@ export default {
               :page.sync="currentCheckInfo.obxQueryParams.pageNum"
               :limit.sync="currentCheckInfo.obxQueryParams.pageSize"
               @pagination="
-                () => {
-                  this.currentCheckInfo.pageObxList = getPageObxList(
-                    patientInfo.id,
-                    currentCheckInfo.obxQueryParams,
-                  );
-                }
               "
             />
           </div>
@@ -159,7 +157,6 @@ export default {
         <el-tab-pane
           label="详细检测报告"
           name="2"
-          :disabled="reportTabDisabled"
            style="height: 400px"
         >
           <check-detail-report :obr="currentCheckInfo.obr" />

+ 1 - 1
admin-ui/src/views/work/patient/index.vue

@@ -43,11 +43,11 @@
                 查看检查项目
               </el-button>
 <!--              检测项目信息弹窗-->
-              <patient-check :check-window-show.sync="checkWindowShow" :patient-info="currentPatientInfo" />
             </template>
           </el-table-column>
         </el-table>
         <pagination v-if="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
+         <patient-check :check-window-show.sync="checkWindowShow" :patient-info="currentPatientInfo" />
       </el-col>
     </el-row>
   </div>

+ 47 - 20
admin-ui/src/views/work/patient/search.vue

@@ -4,7 +4,7 @@
       <el-col :span="5">
         <!-- 左边的导航菜单 -->
         <div class="left-body">
-          <el-menu default-active="1">
+          <el-menu :default-active="activeNow" @open="activeIndex">
             <el-menu-item index="1" @click="activePatient(1)">
               <i class="el-icon-user"></i>
               <span>患者基本信息/亲属</span>
@@ -22,7 +22,7 @@
                   <template slot="title">
                     <span>{{month}}月</span>
                   </template>
-                  <el-menu-item v-for="item in days" @click="getCard(item.id); activePatient(2); getDgList()" :key="item.id" :index="item.id">
+                  <el-menu-item v-for="item in days" @click="getCard(item.id); activePatient(2); getDgList()" :key="item.id" :index="item.id.toString()">
                     {{year}}年{{month}}月{{item.day}}日
                   </el-menu-item>
                 </el-submenu>
@@ -39,25 +39,25 @@
             <!-- 患者基本信息 -->
             <div class="patient-info">
               <el-descriptions  style="width: 69vw; margin-top: 10px" title="患者信息" :column="3" border>
-                <el-descriptions-item label="患者标识符">{{patientInfo.patientCode}}</el-descriptions-item>
-                <el-descriptions-item label="就诊卡号">{{patientInfo.cardNumber}}</el-descriptions-item>
-                <el-descriptions-item label="姓名">{{patientInfo.name}}</el-descriptions-item>
-                <el-descriptions-item label="性别">
+                <el-descriptions-item label="患者标识符" v-if="patientInfo">{{patientInfo.patientCode}}</el-descriptions-item>
+                <el-descriptions-item label="就诊卡号" v-if="patientInfo">{{patientInfo.cardNumber}}</el-descriptions-item>
+                <el-descriptions-item label="姓名" v-if="patientInfo">{{patientInfo.name}}</el-descriptions-item>
+                <el-descriptions-item label="性别" v-if="patientInfo">
                   <dict-tag :options="dict.type.patient_sex" :value="patientInfo.sex"/>
                 </el-descriptions-item>
-                <el-descriptions-item label="身份证号" prop="sfzh">{{patientInfo.sfzh}}</el-descriptions-item>
-                <el-descriptions-item label="出生时间" prop="birthDate">{{patientInfo.birthDate}}</el-descriptions-item>
-                <el-descriptions-item label="居住地址" prop="address">{{patientInfo.address}}</el-descriptions-item>
-                <el-descriptions-item label="联系电话" prop="phone">{{patientInfo.phone}}</el-descriptions-item>
-                <el-descriptions-item label="婚姻状况" prop="marital">
+                <el-descriptions-item label="身份证号" v-if="patientInfo">{{patientInfo.sfzh}}</el-descriptions-item>
+                <el-descriptions-item label="出生时间" v-if="patientInfo">{{patientInfo.birthDate}}</el-descriptions-item>
+                <el-descriptions-item label="居住地址" v-if="patientInfo">{{patientInfo.address}}</el-descriptions-item>
+                <el-descriptions-item label="联系电话" v-if="patientInfo">{{patientInfo.phone}}</el-descriptions-item>
+                <el-descriptions-item label="婚姻状况" v-if="patientInfo">
                   <dict-tag :options="dict.type.patient_marital" :value="patientInfo.marital" />
                 </el-descriptions-item>
-                <el-descriptions-item label="民族" prop="nation">{{patientInfo.nation}}</el-descriptions-item>
-                <el-descriptions-item label="职业" prop="career">{{patientInfo.career}}</el-descriptions-item>
-                <el-descriptions-item label="国籍" prop="nationality">{{patientInfo.nationality}}</el-descriptions-item>
-                <el-descriptions-item label="病历号" prop="blh">{{patientInfo.blh}}</el-descriptions-item>
-                <el-descriptions-item label="病人卡号" prop="brkh">{{patientInfo.brkh}}</el-descriptions-item>
-                <el-descriptions-item label="婴儿序号" prop="yexh">{{patientInfo.yexh}}</el-descriptions-item>
+                <el-descriptions-item label="民族" v-if="patientInfo">{{patientInfo.nation}}</el-descriptions-item>
+                <el-descriptions-item label="职业" v-if="patientInfo">{{patientInfo.career}}</el-descriptions-item>
+                <el-descriptions-item label="国籍" v-if="patientInfo">{{patientInfo.nationality}}</el-descriptions-item>
+                <el-descriptions-item label="病历号" v-if="patientInfo">{{patientInfo.blh}}</el-descriptions-item>
+                <el-descriptions-item label="病人卡号" v-if="patientInfo">{{patientInfo.brkh}}</el-descriptions-item>
+                <el-descriptions-item label="婴儿序号" v-if="patientInfo">{{patientInfo.yexh}}</el-descriptions-item>
               </el-descriptions>
             </div>
             <!-- 患者亲属 -->
@@ -128,9 +128,15 @@
 
 <script>
 export default {
+  computed: {
+    index() {
+      return index
+    }
+  },
   dicts: ['patient_category','diagnostic_type', 'diagnostic_category_code','hospital_status','discharge_method','patient_sex','patient_marital'],
   data(){
     return{
+      activeNow:'1',
       //groupDates的变量
       year:undefined,
       month:undefined,
@@ -167,15 +173,33 @@ export default {
   watch:{
   },
   created() {
+    this.getNowDg();
     this.getTime();
     this.getPatient();
-    this.activePatient(1);
     this.getNkList();
   },
   methods:{
+    activeIndex(){
+      this.activeNow = this.pvList.id.toString()
+      this.active = 2
+      this.queryParams.visitId = this.pvList.id;
+      this.getDgList()
+    },
+    /** 获取当前选中的就诊记录 */
+    getNowDg(){
+      this.get({
+        url:'work/visit/list',
+        data:{
+          cardId:this.param.cardId
+        }
+      }).then((response)=>{
+        this.pvList = response.rows[0];
+      })
+    },
     activePatient(sign) {
       if (sign === 1) {
         this.active = sign;
+        this.activeNow = '1';
       }
       if (sign === 2) {
         this.active = sign;
@@ -183,6 +207,9 @@ export default {
     },
     /** 查询某一次的就诊信息 */
     getCard(id){
+      if(id === this.pvList.id){
+        return;
+      }
       this.queryParams.visitId = id;
       this.get({
         url:'/work/visit/list',
@@ -191,6 +218,8 @@ export default {
         }
       }).then((response)=>{
         this.pvList = response.rows[0];
+        this.activeNow = this.pvList.id.toString();
+        this.getDgList();
       })
     },
     /** 查询某科室某个病人的就诊记录 */
@@ -202,9 +231,7 @@ export default {
           department:this.param.department
         }
       }).then( (response) => {
-        console.log(typeof response.rows[0].id)
         this.timeList = response.rows;
-        console.log(this.timeList)
         this.groupDates(this.timeList);
       })
     },

+ 1 - 1
app/App.vue

@@ -30,7 +30,7 @@ button::after {
 /**挂载iconfont字体图标*/
 @font-face {
 	font-family: 'iconfont';
-	src: url('https://at.alicdn.com/t/c/font_4620946_yjys6ggyf8q.ttf?t=1722229086081') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4620946_77k3uh0ak7p.ttf?t=1722848437021') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 25 - 0
app/common/common.scss

@@ -146,6 +146,7 @@
 		color: $font-c;
 		overflow: hidden;
 		border-bottom: 1px solid #f0f2f7;
+		font-size: 15px;
 		.ic {
 			display: block;
 			float: left;
@@ -352,3 +353,27 @@
 		margin-top: -5px;
 	}
 }
+.message-bubble-received {
+  background: white;
+  border-radius: 10px;
+  padding: 13px;
+  width: 85%;
+  word-wrap: break-word;
+  position: relative;
+  margin-left: 10px;
+  float: left;
+  clear: both;
+  font-size: 14px;
+  color: #262626;
+  margin-bottom: 15px;
+  &::before {
+    content: '';
+    position: absolute;
+    width: 0;
+    height: 0;
+    border-style: solid;
+    border-width: 0 10px 10px 10px;
+    border-color: transparent transparent white transparent;
+    left: -10px;
+  }
+}

+ 8 - 1
app/pages.json

@@ -44,7 +44,7 @@
 		{
 			"path": "pages/follow/detail",
 			"style": {
-				"navigationBarTitleText": "访详情"
+				"navigationBarTitleText": "访详情"
 			}
 		},
 		{
@@ -130,6 +130,13 @@
 			"style": {
 				"navigationBarTitleText": "就诊人信息"
 			}
+		},
+		{
+			"path" : "pages/follow/remind",
+			"style" : 
+			{
+				"navigationBarTitleText" : "复诊提醒"
+			}
 		}
 	],
 	"tabBar": {

+ 4 - 3
app/pages/follow/detail.vue

@@ -10,9 +10,9 @@
 				<text class="dx">({{ item.input }})</text>
 			</view>
 			<view class="mts">
-				<input v-if="item.input == '填空'" v-model="item.s_value" placeholder="请输入" :disabled="item.state != 0" />
-				<input v-if="item.input == '数字'" type="number" v-model="item.s_value" placeholder="请输入" :disabled="item.state != 0" />
-				<textarea v-if="item.input == '多行文本'" v-model="item.s_value" placeholder="请输入" :disabled="item.state != 0" />
+				<input v-if="item.input == '填空'" v-model="item.s_value" placeholder="请输入" :disabled="look" />
+				<input v-if="item.input == '数字'" type="number" v-model="item.s_value" placeholder="请输入" :disabled="look" />
+				<textarea v-if="item.input == '多行文本'" v-model="item.s_value" placeholder="请输入" :disabled="look" />
 				<view class="ops" v-if="item.input == '单选' || item.input == '多选' || item.input == '判断'">
 					<view v-for="(op, i) in item.selects" :key="op.name">
 						<view class="op" :class="{ active: op.check }" @click="check(item, op)">{{ op.name }}</view>
@@ -38,6 +38,7 @@ export default {
 			url: '/app/follow/detail/' + e.id,
 			success: (res) => {
 				this.item = res.data.data;
+				this.look = this.item.state != 0 ? true : false;
 				this.item.op = JSON.parse(this.item.op);
 			}
 		});

+ 19 - 26
app/pages/follow/index.vue

@@ -4,15 +4,15 @@
 			<u-tabs :list="tab" @click="click"></u-tabs>
 		</view>
 		<view class="list">
-			<view class="item" v-for="(item, index) in list" :key="index" @click="go('/pages/follow/detail?id=' + item.id)">
-				<view class="title omit">
-					<text class="icon" v-if="item.top === 1">&#xe61f;</text>
-					<text>{{ item.templateName }}</text>
-				</view>
-				<view class="desc">
-					<text>{{ item.state == 0 ? '待回访' : '已回访' }}</text>
-					<text>{{ item.createTime }}</text>
-				</view>
+			<view class="message-bubble-received" v-for="(item, index) in list" :key="index" @click="go('/pages/follow/detail?id=' + item.id)">
+				<view class="title">{{ item.templateName }}</view>
+				<view class="desc">尊敬的患者,为了更好的改善服务,我们向你发起了一个回访并且希望您认真填写。</view>
+				<view class="desc">{{ item.createTime }}</view>
+				<button class="btn" :style="{ backgroundColor: item.state == 0 ? '#4581fb' : '#4CAF50' }">
+					<text class="icon" v-if="item.state == 0">&#xe749;</text>
+					<text class="icon" v-else>&#xe6c6;</text>
+					<text>{{ item.state == 0 ? '去填写' : '已填写' }}</text>
+				</button>
 			</view>
 			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
 			<u-empty v-if="!loadMore && list.length == 0"></u-empty>
@@ -30,7 +30,7 @@ export default {
 				{ name: '已回访', state: 1 }
 			],
 			list: [],
-			param: { pageNum: 1, pageSize: 10 },
+			param: { pageNum: 1, pageSize: 10, type: 1 },
 			loadMore: true
 		};
 	},
@@ -43,7 +43,7 @@ export default {
 	methods: {
 		click(e) {
 			this.current = e.index;
-			this.param.type = e.dictValue;
+			this.param.state = e.state;
 			this.refresh();
 		},
 		getData() {
@@ -88,26 +88,19 @@ export default {
 <style lang="scss">
 .list {
 	padding: 10px 12px;
-	.item {
-		border-radius: 5px;
-		padding: 13px 12px 13px 12px;
-		margin-bottom: 10px;
-		overflow: hidden;
-		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-		background-color: white;
+	.message-bubble-received {
 		.title {
-			font-size: 15px;
+			font-size: 16px;
 			font-weight: bold;
-			.icon {
-				color: orangered;
-				padding-right: 3px;
-			}
 		}
 		.desc {
-			font-size: 14px;
+			font-size: 13px;
 			padding-top: 10px;
-			text {
-				padding-right: 30px;
+			color: $font-c;
+		}
+		.btn {
+			.icon {
+				padding-right: 3px;
 			}
 		}
 	}

+ 85 - 0
app/pages/follow/remind.vue

@@ -0,0 +1,85 @@
+<template>
+	<view>
+		<view class="list">
+			<view class="message-bubble-received" v-for="(item, index) in list" :key="index">
+				<view class="title">
+					<text class="icon">&#xe813;</text>
+					<text>{{ item.templateName }}</text>
+				</view>
+				<view class="desc">{{ item.op }}</view>
+				<view class="desc">{{ item.createTime }}</view>
+			</view>
+			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
+			<u-empty v-if="!loadMore && list.length == 0"></u-empty>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			list: [],
+			param: { pageNum: 1, pageSize: 10, type: 0 },
+			loadMore: true
+		};
+	},
+	onLoad(e) {
+		this.getData();
+	},
+	methods: {
+		getData() {
+			this.http.request({
+				url: '/app/follow/list',
+				data: this.param,
+				loading: 'false',
+				success: (res) => {
+					this.loadMore = res.data.pages > this.param.pageNum ? true : false;
+					this.list.push(...res.data.rows);
+				}
+			});
+		},
+		//刷新数据
+		refresh() {
+			this.loadMore = true;
+			this.param.pageNum = 1;
+			this.list = [];
+			this.getData();
+		}
+	},
+	//下拉刷新
+	onPullDownRefresh() {
+		setTimeout(() => {
+			this.refresh();
+			uni.stopPullDownRefresh();
+		}, 1000);
+	},
+	//上拉加载
+	onReachBottom() {
+		if (this.loadMore) {
+			this.param.pageNum++;
+			this.getData();
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.list {
+	padding: 10px 12px;
+	.message-bubble-received {
+		.title {
+			font-size: 16px;
+			font-weight: bold;
+			.icon {
+				padding-right: 3px;
+			}
+		}
+		.desc {
+			font-size: 13px;
+			padding-top: 10px;
+			color: $font-c;
+		}
+	}
+}
+</style>

+ 8 - 8
app/pages/index/index.vue

@@ -61,7 +61,7 @@
 			<u-scroll-list :indicator="true" indicatorColor="#e0e0e0">
 				<view class="doctor">
 					<view class="item" v-for="(item, index) in doctorList" :key="index" @click="go('/pages/news/detail?id=' + item.id)">
-						<image :src="ip + item.avatar" mode="scaleToFill" class="avatar"></image>
+						<image :src="item.avatar" mode="scaleToFill" class="avatar"></image>
 						<view class="title">{{ item.name }}</view>
 					</view>
 				</view>
@@ -99,13 +99,13 @@ export default {
 			ip: this.http.ip,
 			noticeList: ['医院开通线上小程序啦,快来体验吧', '首次使用如何绑定就诊卡'],
 			doctorList: [
-				{ name: '梁红斌', avatar: '/profile/upload/2024/07/23/blob_20240723162841A002.jpeg' },
-				{ name: '戴浩华', avatar: '/profile/upload/2024/07/23/blob_20240723153318A001.jpeg' },
-				{ name: '罗肇林', avatar: '/profile/upload/2024/07/23/blob_20240723145549A005.jpeg' },
-				{ name: '覃勇军', avatar: '/profile/upload/2024/07/23/blob_20240723144505A002.jpeg' },
-				{ name: '阿松大', avatar: '/profile/upload/2024/07/23/blob_20240723153318A001.jpeg' },
-				{ name: '阿松大', avatar: '/profile/upload/2024/07/23/blob_20240723153318A001.jpeg' },
-				{ name: '阿松大', avatar: '/profile/upload/2024/07/23/blob_20240723153318A001.jpeg' }
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' },
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' },
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' },
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' },
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' },
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' },
+				{ name: '梁红斌', avatar: 'https://chenglantimes.com/prod-api/profile/upload/2024/08/05/1722848767545.jpg' }
 			],
 			knowledgeList: []
 		};

+ 21 - 14
app/pages/user/index.vue

@@ -5,7 +5,7 @@
 			<view class="con" v-if="user.id">
 				<view class="nickName">
 					{{ user.patientName ? user.patientName : '还未绑定就诊人' }}
-					<text class="icon" v-if="user.bindUserList.length > 1" @click.stop="show = true">&#xe6a7;</text>
+					<text class="icon" v-if="user.bindUserList.length > 1" @click.stop="show = true">&#xe6a7;切换就诊人</text>
 				</view>
 				<view class="welcome">欢迎使用岑溪人民医院小程序</view>
 			</view>
@@ -16,9 +16,9 @@
 			<view class="icon edit">&#xe62b;</view>
 		</view>
 		<view class="cmd">
-			<view class="s_item" @click="go('/pages/follow/index')">
-				<text class="icon ic" style="color: #607d8b">&#xe60b;</text>
-				<text class="title">我的复诊</text>
+			<view class="s_item" @click="go('/pages/follow/remind')">
+				<text class="icon ic" style="color: #03a9f4">&#xe6a3;</text>
+				<text class="title">复诊提醒</text>
 				<text class="icon arrow">&#xe62b;</text>
 			</view>
 			<view class="s_item" @click="go('/pages/follow/index')">
@@ -27,25 +27,25 @@
 				<text class="icon arrow">&#xe62b;</text>
 			</view>
 			<view class="s_item" @click="go('/pages/visit/index')">
-				<text class="icon ic" style="color: #03a9f4">&#xe614;</text>
+				<text class="icon ic" style="color: #03a9f4">&#xe685;</text>
 				<text class="title">就诊记录</text>
 				<text class="icon arrow">&#xe62b;</text>
 			</view>
 			<view class="s_item" @click="go('/pages/detection/index')">
-				<text class="icon ic" style="color: #607d8b">&#xe615;</text>
+				<text class="icon ic" style="color: #ff9800">&#xe63a;</text>
 				<text class="title">检测报告</text>
 				<text class="icon arrow">&#xe62b;</text>
 			</view>
-			<view class="s_item" @click="go('/pages/help/my')">
+			<button class="s_item" open-type="share" @click="go('/pages/help/my')" hover-class="none">
 				<text class="icon ic" style="color: #f44336">&#xe7c4;</text>
 				<text class="title">分享应用</text>
 				<text class="icon arrow">&#xe62b;</text>
-			</view>
-			<view class="s_item" @click="go('/pages/help/my')">
+			</button>
+			<button class="s_item" open-type="feedback" @click="go('/pages/help/my')">
 				<text class="icon ic" style="color: #4caf50">&#xe62c;</text>
 				<text class="title">建议反馈</text>
 				<text class="icon arrow">&#xe62b;</text>
-			</view>
+			</button>
 			<view class="s_item" @click="go('/pages/other/setting')">
 				<text class="icon ic" style="color: #9e9e9e">&#xe60f;</text>
 				<text class="title">设置</text>
@@ -113,7 +113,7 @@ export default {
 		return {
 			title: '岑溪人民医院小程序',
 			path: '/pages/index/index',
-			imageUrl: 'https://chenglantimes.com/prod-api/profile/upload/2024/06/16/blob_20240616055022A009.jpeg',
+			imageUrl: '../../static/favicon.png',
 			success: (res) => {},
 			fail: (res) => {}
 		};
@@ -136,14 +136,16 @@ export default {
 			padding-left: 15px;
 			.nickName {
 				padding-top: 5px;
+				.icon {
+					padding-left: 6px;
+					font-size: 13px;
+					color: $main-color;
+				}
 			}
 			.welcome {
 				font-size: 14px;
 				padding-top: 5px;
 				color: #989898;
-				.icon {
-					padding-right: 3px;
-				}
 			}
 		}
 		.edit {
@@ -151,5 +153,10 @@ export default {
 			margin-top: 14px;
 		}
 	}
+	button {
+		border-radius: 0px;
+		line-height: 1;
+		font-size: 15px;
+	}
 }
 </style>

+ 5 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java

@@ -68,16 +68,20 @@ public class SysProfileController extends BaseController {
                 && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
             return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
         }
+        if (user.getIntroduce() != null) {
+            user.setBrief(StringUtils.StripHT(user.getIntroduce()));
+        }
         user.setUserId(sysUser.getUserId());
         user.setPassword(null);
         user.setAvatar(null);
         user.setDeptId(null);
-        if (userService.updateUserProfile(user) > 0) {
+        if (userService.updateUserProfile(user)) {
             // 更新缓存用户信息
             sysUser.setNickName(user.getNickName());
             sysUser.setPhonenumber(user.getPhonenumber());
             sysUser.setEmail(user.getEmail());
             sysUser.setSex(user.getSex());
+            sysUser.setIntroduce(user.getIntroduce());
             tokenService.setLoginUser(loginUser);
             return AjaxResult.success();
         }

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/api/Api_FollowController.java

@@ -27,7 +27,7 @@ public class Api_FollowController extends BaseController {
 
     @GetMapping("/list")
     public TableDataInfo list(FollowRecord followRecord) {
-        followRecord.setPatientId(getUser().getId());
+        followRecord.setPatientId(getUser().getPatientId());
         startPage();
         List<FollowRecord> list = followRecordService.selectAppList(followRecord);
         return getDataTable(list);

+ 5 - 6
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/FollowRecordController.java

@@ -33,7 +33,7 @@ public class FollowRecordController extends BaseController {
     @Autowired
     private IFollowTemplateService followTemplateService;
 
-    @PreAuthorize("@ss.hasPermi('work:record:list')")
+    @PreAuthorize("@ss.hasAnyPermi('work:record:list,work:up:list')")
     @GetMapping("/list")
     public TableDataInfo list(FollowRecord followRecord) {
         startPage();
@@ -41,7 +41,6 @@ public class FollowRecordController extends BaseController {
         return getDataTable(list);
     }
 
-    @PreAuthorize("@ss.hasPermi('work:record:query')")
     @GetMapping(value = "/detail/{id}")
     public AjaxResult detail(@PathVariable("id") Long id) {
         return AjaxResult.success(followRecordService.getById(id));
@@ -56,28 +55,28 @@ public class FollowRecordController extends BaseController {
         return getDataTable(list);
     }
 
-    @PreAuthorize("@ss.hasPermi('work:record:list')")
+    @PreAuthorize("@ss.hasAnyPermi('work:record:list,work:up:list')")
     @GetMapping("/template/list")
     public AjaxResult templateList(FollowTemplate followTemplate) {
         List<FollowTemplate> list = followTemplateService.selectList(followTemplate);
         return AjaxResult.success(list);
     }
 
-    @PreAuthorize("@ss.hasPermi('work:record:add')")
+    @PreAuthorize("@ss.hasAnyPermi('work:record:add,work:up:add')")
     @Log(title = "回访记录", businessType = BusinessType.INSERT)
     @PostMapping("/add")
     public AjaxResult add(@RequestBody FollowRecord followRecord) {
         return followRecordService.add(followRecord);
     }
 
-    @PreAuthorize("@ss.hasPermi('work:record:edit')")
+    @PreAuthorize("@ss.hasAnyPermi('work:record:edit,work:up:edit')")
     @Log(title = "回访记录", businessType = BusinessType.UPDATE)
     @PostMapping("/edit")
     public AjaxResult edit(@RequestBody FollowRecord followRecord) {
         return toAjax(followRecordService.updateById(followRecord));
     }
 
-    @PreAuthorize("@ss.hasPermi('work:record:remove')")
+    @PreAuthorize("@ss.hasAnyPermi('work:record:remove,work:up:remove')")
     @Log(title = "回访记录", businessType = BusinessType.DELETE)
     @GetMapping("/remove/{ids}")
     public AjaxResult remove(@PathVariable Long[] ids) {

+ 28 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/IndexController.java

@@ -0,0 +1,28 @@
+package com.ruoyi.web.work.controller;
+
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.web.work.mapper.UserMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 后台首页统计
+ */
+@RestController
+@RequestMapping("/home")
+public class IndexController extends BaseController {
+
+    @Autowired
+    private UserMapper userMapper;
+
+
+    @GetMapping("/index")
+    public AjaxResult index() {
+        AjaxResult result = new AjaxResult();
+        result.put("count", userMapper.statistics(getLoginUser().getUser()));
+        return AjaxResult.success(result);
+    }
+}

+ 2 - 5
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/FollowRecord.java

@@ -21,8 +21,8 @@ public class FollowRecord extends BaseData {
 
     private Long id;
 
-    @ApiModelProperty(value = "医生id")
-    private Long userId;
+    @ApiModelProperty(value = "提醒类型:0=复诊,1=回访")
+    private Integer type;
 
     @ApiModelProperty(value = "患者id")
     private Long patientId;
@@ -39,9 +39,6 @@ public class FollowRecord extends BaseData {
     @ApiModelProperty(value = "状态:0=未回访,1=已回访")
     private Integer state;
 
-    @ApiModelProperty(value = "部门ID")
-    private Long deptId;
-
     @TableField(exist = false)
     private List<Patient> patientList;
 }

+ 4 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/mapper/UserMapper.java

@@ -1,10 +1,12 @@
 package com.ruoyi.web.work.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.web.work.domain.User;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author lsw
@@ -14,4 +16,6 @@ public interface UserMapper extends BaseMapper<User> {
     List<User> selectList(User user);
 
     User selectByOpenId(@Param("openId") String openId);
+
+    Map<String, Object> statistics(SysUser sysUser);
 }

+ 5 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/FollowRecordServiceImpl.java

@@ -1,6 +1,7 @@
 package com.ruoyi.web.work.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.annotation.DataScope;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.web.work.api.util.AppUtil;
@@ -25,6 +26,7 @@ public class FollowRecordServiceImpl extends ServiceImpl<FollowRecordMapper, Fol
     @Autowired
     private FollowRecordMapper followRecordMapper;
 
+    @DataScope(deptAlias = "k")
     @Override
     public List<FollowRecord> selectList(FollowRecord followRecord) {
         return followRecordMapper.selectList(followRecord);
@@ -33,7 +35,7 @@ public class FollowRecordServiceImpl extends ServiceImpl<FollowRecordMapper, Fol
     @Override
     public AjaxResult detail(Long id) {
         FollowRecord followRecord = getById(id);
-        if (followRecord == null || !followRecord.getPatientId().equals(AppUtil.getUser().getId())) {
+        if (followRecord == null || !followRecord.getPatientId().equals(AppUtil.getUser().getPatientId())) {
             return AjaxResult.error("回访不存在或非法操作");
         }
         return AjaxResult.success(followRecord);
@@ -42,7 +44,7 @@ public class FollowRecordServiceImpl extends ServiceImpl<FollowRecordMapper, Fol
     @Override
     public AjaxResult push(FollowRecordDto dto) {
         FollowRecord followRecord = getById(dto.getId());
-        if (followRecord == null || !followRecord.getPatientId().equals(AppUtil.getUser().getId())) {
+        if (followRecord == null || !followRecord.getPatientId().equals(AppUtil.getUser().getPatientId())) {
             return AjaxResult.error("回访不存在或非法操作");
         }
         followRecord.setOp(dto.getOp());
@@ -71,6 +73,7 @@ public class FollowRecordServiceImpl extends ServiceImpl<FollowRecordMapper, Fol
         List<FollowRecord> followRecordList = new ArrayList<>();
         followRecord.getPatientList().forEach(e -> {
             FollowRecord record = new FollowRecord();
+            record.setType(followRecord.getType());
             record.setTemplateName(followRecord.getTemplateName());
             record.setOp(followRecord.getOp());
             record.setPatientId(e.getId());

+ 9 - 2
ruoyi-admin/src/main/resources/mapper/work/FollowRecordMapper.xml

@@ -17,18 +17,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         tb_follow_record k
         LEFT JOIN sys_dept d ON d.dept_id = k.dept_id
         WHERE 1=1
+            <if test="type != null "> and k.type = #{type}</if>
+            <if test="patientName != null  and patientName != ''"> AND k.patient_name like concat('%', #{patientName}, '%')</if>
             <if test="patientId != null "> AND k.patient_id = #{patientId}</if>
             <if test="userId != null "> and k.user_id = #{userId}</if>
             <if test="state != null "> and k.state = #{state}</if>
             <if test="deptId != null "> and k.dept_id = #{deptId}</if>
+            <if test="deptId != null and deptId != 0">AND (k.dept_id = #{deptId} OR k.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ))</if>
+            <!-- 数据范围过滤 -->
+            ${params.dataScope}
     </select>
 
     <select id="selectAppList" resultType="com.ruoyi.web.work.domain.FollowRecord">
-        select id,template_name,state,create_time from tb_follow_record
+        select id,template_name,op,state,create_time from tb_follow_record
         <where>
-            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="type != null "> and type = #{type}</if>
+            <if test="patientId != null "> AND patient_id = #{patientId}</if>
             <if test="state != null "> and state = #{state}</if>
         </where>
+        ORDER BY id DESC
     </select>
 
     <select id="selectVisitList" resultType="com.ruoyi.web.work.domain.vo.VisitVoList">

+ 9 - 0
ruoyi-admin/src/main/resources/mapper/work/UserMapper.xml

@@ -16,4 +16,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT * FROM tb_user WHERE open_id=#{openId}
     </select>
 
+    <!--后台首页统计-->
+    <select id="statistics" resultType="java.util.Map">
+        SELECT
+                ( SELECT COUNT( id ) FROM tb_visit WHERE doctor_code =#{userName}) AS visit,
+                ( SELECT COUNT( id ) FROM tb_follow_record WHERE user_id =#{userId} AND type = 0 ) AS up,
+                ( SELECT COUNT( id ) FROM tb_follow_record WHERE user_id =#{userId} AND type = 1 ) AS record,
+                ( SELECT COUNT( id ) FROM tb_knowledge WHERE user_id =#{userId} ) AS knowledge
+    </select>
+
 </mapper>

+ 1 - 1
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -153,7 +153,7 @@ public interface ISysUserService extends IService<SysUser> {
      * @param user 用户信息
      * @return 结果
      */
-    int updateUserProfile(SysUser user);
+    boolean updateUserProfile(SysUser user);
 
     /**
      * 修改用户头像

+ 2 - 2
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -311,8 +311,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return 结果
      */
     @Override
-    public int updateUserProfile(SysUser user) {
-        return userMapper.updateUser(user);
+    public boolean updateUserProfile(SysUser user) {
+        return updateById(user);
     }
 
     /**