尚医通 (十六)搭建平台用户系统前端环境 | 用户平台首页数据

news2024/9/29 19:31:06

目录

  • 一、服务端渲染技术NUXT
    • 1、什么是服务端渲染
    • 2、什么是NUXT
  • 二、NUXT环境初始化
    • 1、下载压缩包
    • 2、解压
    • 3、修改package.json
    • 4、修改nuxt.config.js
    • 5、在命令提示终端中进入项目目录
    • 6、安装依赖
    • 7、测试运行
    • 8、NUXT目录结构
    • 9、封装axios
    • 10、引入element-ui
  • 三、首页静态数据整合
    • 1、添加静态资源
    • 2、修改页面布局
  • 四、首页数据显示
    • 1、医院列表显示(接口)
      • 1.1 service接口与实现
      • 1.2 添加controller方法
    • 2、医院搜索(接口)
      • 2.1 service接口与实现
      • 2.2 .HospitalApiController 添加方法
    • 3、首页数据前端
      • 3.1 封装api
      • 3.2 添加组件
  • 五、医院详情
    • 1、医院详情接口
    • 2、医院详情前端
      • 2.1 封装api方法
      • 2.2 动态路由
      • 2.3 医院详情
      • 2.4 预约规则
      • 2.5 Nuxt中的两种路由总结
  • 六、点击图标回到首页

一、服务端渲染技术NUXT

1、什么是服务端渲染

服务端渲染又称SSR (Server Side Render)是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据。

服务器端渲染(SSR)的优势主要在于:更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。

如果你的应用程序初始展示 loading,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再进行页面内容的抓取。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。

另外,使用服务器端渲染,我们可以获得更快的内容到达时间(time-to-content),无需等待所有的 JavaScript 都完成下载并执行,产生更好的用户体验,对于那些「内容到达时间(time-to-content)与转化率直接相关」的应用程序而言,服务器端渲染(SSR)至关重要。

2、什么是NUXT

Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用,也可充当静态站点引擎生成静态站点应用,具有优雅的代码结构分层和热加载等特性。

官网网站:
https://zh.nuxtjs.org/

二、NUXT环境初始化

1、下载压缩包

https://github.com/nuxt-community/starter-template/archive/master.zip

2、解压

将template中的内容复制到yygh_site

3、修改package.json

name、description、author(必须修改这里,否则项目无法安装)

 "name": "yygh",
 "version": "1.0.0",
 "description": "尚医通",
 "author": "donglin",

在这里插入图片描述

4、修改nuxt.config.js

修改title: ‘{{ name }}’、content: ‘{{escape description }}’
这里的设置最后会显示在页面标题栏和meta数据中

module.exports = {
  /*
  ** Headers of the page
  */
  head: {
    title: 'yygh-site',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '尚医通' }
    ],

5、在命令提示终端中进入项目目录

6、安装依赖

npm install

在这里插入图片描述

7、测试运行

npm run dev

8、NUXT目录结构

(1)资源目录 assets
用于组织未编译的静态资源如 LESS、SASS 或 JavaScript。
(2)组件目录 components
用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目录下 Vue.js 组件,即这些组件不会像页面组件那样有 asyncData 方法的特性。
(3)布局目录 layouts
用于组织应用的布局组件。
(4)页面目录 pages
用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配置。
(5)插件目录 plugins
用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。
(6)nuxt.config.js 文件
nuxt.config.js 文件用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。

9、封装axios

(1)执行安装命令

npm install axios

(2)创建utils文件夹,创建request.js

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
// 创建axios实例
const service = axios.create({
    baseURL: 'http://localhost:8222',
    timeout: 15000 // 请求超时时间
})
// http request 拦截器
service.interceptors.request.use(
    config => {
    // token 先不处理,后续使用时在完善
    return config
},
  err => {
    return Promise.reject(err)
})
// http response 拦截器
service.interceptors.response.use(
    response => {
        if (response.data.code !== 20000) {
            Message({
                message: response.data.message,
                type: 'error',
                duration: 5 * 1000
            })
            return Promise.reject(response.data)
        } else {
            return response.data
        }
    },
    error => {
        return Promise.reject(error.response)
})
export default service

10、引入element-ui

1、下载element-ui

npm  install  element-ui

2、在plugins文件夹下创建myPlugin.js文件
在这里插入图片描述
3、在myPlugin.js文件引入element-ui

import Vue from 'vue'
import ElementUI from 'element-ui' //element-ui的全部组件
import 'element-ui/lib/theme-chalk/index.css'//element-ui的css
Vue.use(ElementUI) //使用elementUI

4、在nuxt.config.js文件中使用myPlugin.js
在build下面添加内容:

  plugins: [
    { src: '~/plugins/myPlugin.js', ssr: false }
 ],

三、首页静态数据整合

1、添加静态资源

将静态资源下面的css、images文件夹添加到assets目录
在这里插入图片描述

2、修改页面布局

2.1 提取头文件
创建layouts/myheader.vue文件
在这里插入图片描述

<template>
    <div class="header-container">
        <div class="wrapper">
            <!-- logo -->
            <div class="left-wrapper v-link selected">
                <img style="width: 50px" width="50" height="50" src="~assets/images/logo.png">
                <span class="text">尚医通 预约挂号统一平台</span>
            </div>
            <!-- 右侧 -->
            <div class="right-wrapper">
                <span class="v-link clickable">帮助中心</span>
                <span class="v-link clickable" @click="dialogUserFormVisible = true">登录/注册</span>
            </div>
        </div>
    </div>
</template>
<script>
export default {
}
</script>

2.2 提取尾文件
创建layouts/myfooter.vue文件
在这里插入图片描述

<template>
    <div class="footer-container">
      <div class="wrapper">
        <div><span class="record">ICP备donglin号</span><span
          class="phone">1909529369@qq.com</span></div>
        <div class="right"><span
          class="v-link clickable"> 联系我们 </span><span
          class="v-link clickable"> 合作伙伴 </span><span
          class="v-link clickable"> 用户协议 </span><span
          class="v-link clickable"> 隐私协议 </span></div>
      </div>
    </div>
  </template>
  
  <script>
  export default {
  
  }
  </script>

2.3 修改默认布局页面
修改layouts/default.vue文件

<template>
  <div class="app-container">
    <div id="main">
      <!-- 公共头 -->
      <myheader/>
      <div class="main-container">
        <el-scrollbar class='page-component__scroll'>
          <!-- 内容区域 -->
          <nuxt/>
        </el-scrollbar>
      </div>
      <!-- 公共底 -->
      <myfooter/>
    </div>
  </div>
</template>
<script>
import '~/assets/css/app.css'
import '~/assets/css/chunk.css'
import '~/assets/css/iconfont.css'
import '~/assets/css/main.css'

import myheader from './myheader'
import myfooter from './myfooter'

export default {

  components: {
    myheader,myfooter
  },

  mounted() {
    window.document.getElementById("__nuxt").classList.add("app-container")
    window.document.getElementById("__layout").classList.add("app-container")
  }
}
</script>

2.4 修改pages/index.vue页面

<template>
  <div class="home page-component">
    <el-carousel indicator-position="outside">
      <el-carousel-item v-for="item in 1" :key="item">
        <img src="~assets/images/web-banner1.png" alt="">
      </el-carousel-item>
    </el-carousel>
    <!-- 搜索 -->
    <div class="search-container">
    <div class="search-wrapper">
    <div class="hospital-search">
      <el-autocomplete
      class="search-input"
      prefix-icon="el-icon-search"
      v-model="state"
      :fetch-suggestions="querySearchAsync"
      placeholder="点击输入医院名称"
      @select="handleSelect"
      >
        <span slot="suffix" class="search-btn v-link highlight clickable selected">搜索 </span>
      </el-autocomplete>
    </div>
    </div>
    </div>
    <!-- bottom -->
    <div class="bottom">
    <div class="left">
    <div class="home-filter-wrapper">
    <div class="title"> 医院</div>
    <div>
      <div class="filter-wrapper">
        <span
        class="label">等级:</span>
        <div class="condition-wrapper"><span
        class="item v-link highlight clickable selected">
                                                    全部 </span><span
        class="item v-link clickable">
                                                    三级医院 </span><span
        class="item v-link clickable">
                                                    二级医院 </span><span
        class="item v-link clickable">
                                                    一级医院 </span></div>
      </div>
    <div class="filter-wrapper">
      <span
      class="label">地区:</span>
      <div class="condition-wrapper"><span
      class="item v-link highlight clickable selected">
                                                  全部 </span><span
      class="item v-link clickable">
                                                  东城区 </span><span
      class="item v-link clickable">
                                                  西城区 </span><span
      class="item v-link clickable">
                                                  朝阳区 </span><span
      class="item v-link clickable">
                                                  丰台区 </span><span
      class="item v-link clickable">
                                                  石景山区 </span><span
      class="item v-link clickable">
                                                  海淀区 </span><span
      class="item v-link clickable">
                                                  门头沟区 </span><span
      class="item v-link clickable">
                                                  房山区 </span><span
      class="item v-link clickable">
                                                  通州区 </span><span
      class="item v-link clickable">
                                                  顺义区 </span><span
      class="item v-link clickable">
                                                  昌平区 </span><span
      class="item v-link clickable">
                                                  大兴区 </span><span
      class="item v-link clickable">
                                                  怀柔区 </span><span
      class="item v-link clickable">
                                                  平谷区 </span><span
      class="item v-link clickable">
                                                  密云区 </span><span
      class="item v-link clickable">
                                                  延庆区 </span></div>
      </div>
    </div>
    </div>
    <div class="v-scroll-list hospital-list">
    <div class="v-card clickable list-item">
    <div class="">
      <div
      class="hospital-list-item hos-item" index="0">
      <div class="wrapper">
      <div class="hospital-title"> 北京协和医院
      </div>
      <div class="bottom-container">
      <div
      class="icon-wrapper"><span
      class="iconfont"></span>
                            三级甲等
      </div>
    <div
    class="icon-wrapper"><span
    class="iconfont"></span>
                          每天8:30放号
    </div>
    </div>
    </div>
    <img
    src="images/23176337663806575.png"
    alt="北京协和医院" class="hospital-img"></div>
    </div>
    </div>
      <div class="v-card clickable list-item space">
      <div class="">
      <div
      class="hospital-list-item hos-item" index="0">
      <div class="wrapper">
      <div class="hospital-title"> 北京协和医院
      </div>
      <div class="bottom-container">
      <div
      class="icon-wrapper"><span
      class="iconfont"></span>
                            三级甲等
      </div>
    <div
    class="icon-wrapper"><span
    class="iconfont"></span>
                          每天8:30放号
    </div>
    </div>
    </div>
    <img
    src="images/23176337663806575.png"
    alt="北京协和医院" class="hospital-img"></div>
    </div>
    </div>
    <div class="v-card clickable list-item">
    <div class="">
    <div class="hospital-list-item hos-item" index="0">
      <div class="wrapper">
      <div class="hospital-title"> 北京协和医院
      </div>
      <div class="bottom-container">
      <div
      class="icon-wrapper"><span
      class="iconfont"></span>
                            三级甲等
      </div>
      <div
      class="icon-wrapper"><span
      class="iconfont"></span>
                            每天8:30放号
      </div>
    </div>
    </div>
    <img
    src="images/23176337663806575.png"
    alt="北京协和医院" class="hospital-img"></div>
    </div>
    </div>
    </div>
    </div>
    <div class="right">
      <div class="common-dept">
      <div class="header-wrapper">
      <div class="title"> 常见科室</div>
      <div class="all-wrapper"><span>全部</span>
      <span class="iconfont icon"></span>
      </div>
      </div>
      <div class="content-wrapper">
      <span class="item v-link clickable dark">神经内科 </span>
      <span class="item v-link clickable dark">消化内科 </span>
      <span class="item v-link clickable dark">呼吸内科 </span>
      <span class="item v-link clickable dark">内科 </span>
      <span class="item v-link clickable dark">神经外科 </span>
      <span class="item v-link clickable dark">妇科 </span>
      <span class="item v-link clickable dark"> 产科 </span>
      <span class="item v-link clickable dark">儿科 </span>
      </div>
    </div>
    <div class="space">
      <div class="header-wrapper">
      <div class="title-wrapper">
      <div class="icon-wrapper"><span
      class="iconfont title-icon"></span>
      </div>
      <span class="title">平台公告</span>
      </div>
      <div class="all-wrapper">
      <span>全部</span>
      <span class="iconfont icon"></span>
      </div>
      </div>
      <div class="content-wrapper">
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark">关于延长北京大学国际医院放假的通知 </span>
      </div>
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark">北京中医药大学东方医院部分科室医生门诊医 </span>
      </div>
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark"> 武警总医院号源暂停更新通知 </span>
      </div>
      </div>
    </div>
    <div class="suspend-notice-list space">
    <div class="header-wrapper">
    <div class="title-wrapper">
      <div class="icon-wrapper">
      <span class="iconfont title-icon"></span>
      </div>
      <span class="title">停诊公告</span>
      </div>
      <div class="all-wrapper">
      <span>全部</span>
      <span class="iconfont icon"></span>
      </div>
      </div>
      <div class="content-wrapper">
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark"> 中国人民解放军总医院第六医学中心(原海军总医院)呼吸内科门诊停诊公告 </span>
      </div>
      <div class="notice-wrapper">
      <div class="point"></div>
    <span class="notice v-link clickable dark"> 首都医科大学附属北京潞河医院老年医学科门诊停诊公告 </span>
    </div>
      <div class="notice-wrapper">
        <div class="point"></div>
        <span class="notice v-link clickable dark">中日友好医院中西医结合心内科门诊停诊公告 </span>
      </div>
    </div>
    </div>
    </div>
    </div>
  </div>
</template>
<script>
export default {
}
</script>

启动项目:npm run dev
访问项目:http://localhost:3000/

四、首页数据显示

1、医院列表显示(接口)

1.1 service接口与实现

在管理平台 医院分页列表时已经提供,目前我们可以直接使用

1.2 添加controller方法

创建HospitalApiController

@Api(tags = "医院显示接口")
@RestController
@RequestMapping("/user/hosp/hospital")
public class UserHospitalController {

    @Autowired
    private HospitalService hospitalService;

    @GetMapping("/list")
    public R getHospitalList(HospitalQueryVo hospitalQueryVo){
        Page<Hospital> page = hospitalService.getHospitalPage(1, 100, hospitalQueryVo);
        return R.ok().data("list",page.getContent());
    }
}

2、医院搜索(接口)

2.1 service接口与实现

在HospitalService添加接口和实现

    /**
     * 根据医院名称获取医院列表
     */
    List<Hospital> findByHosnameLike(String name);
        
    @Override
    public List<Hospital> findByHosnameLike(String name) {
        return hospitalRepository.findHospitalByHosnameLike(name);
    }

在HospitalRepository类添加方法

    List<Hospital> findByHosnameLike(String name);

2.2 .HospitalApiController 添加方法

    @ApiOperation(value = "根据医院名称获取医院列表")
    @GetMapping("/{name}")
    public R findByHosnameLike(@PathVariable String name){
        List<Hospital> list = hospitalService.findByHosnameLike(name);
        return R.ok().data("list",list);
    }

3、首页数据前端

3.1 封装api

(1)创建api文件夹,创建/api/hospital.js

import request from '@/utils/request'

const api_name = `/user/hosp/hospital`

export default {
    getHospitalList(searchObj) {
        return request({
            url: `${api_name}/list`,
            method: 'get',
            params:searchObj
        })
    },
    getByHosname(name) {
        return request({
            url: `${api_name}/${name}`,
            method: 'get'
        })
    }
}

(2)创建/api/yygh/dict.js

import request from '@/utils/request'

const api_name = '/admin/cmn'

export default {
    getChildList(pid) {
        return request({
            url: `${api_name}/childList/${pid}`,
            method: 'get'
        })
    },

}

3.2 添加组件

(1)修改pages/index.vue组件

<template>
  <div class="home page-component">
    <el-carousel indicator-position="outside">
      <el-carousel-item v-for="item in 2" :key="item">
        <img src="~assets/images/web-banner1.png" alt="">
      </el-carousel-item>
    </el-carousel>
    <!-- 搜索 -->
    <div class="search-container">
    <div class="search-wrapper">
    <div class="hospital-search">
      <el-autocomplete
      class="search-input"
      prefix-icon="el-icon-search"
      v-model="hosname"
      :fetch-suggestions="querySearchAsync"
      placeholder="点击输入医院名称"
      @select="handleSelect"
      >
        <span slot="suffix" class="search-btn v-link highlight clickable selected">搜索 </span>
      </el-autocomplete>
    </div>
    </div>
    </div>
    <!-- bottom -->
    <div class="bottom">
    <div class="left">
    <div class="home-filter-wrapper">
    <div class="title"> 医院</div>
    <div>
      <div class="filter-wrapper">
        <span
        class="label">等级:</span>
        <div class="condition-wrapper">
          <span class="item v-link clickable" 
            :class="hostypeActiveIndex == index ? 'selected' : ''"
             v-for="(item,index) in hostypeList" :key="item.id" 
             @click="hostypeSelect(item.value, index)">{{ item.name }}</span>
       </div>
      </div>
    <div class="filter-wrapper">
      <span
      class="label">地区:</span>
      <div class="condition-wrapper">
        <span class="item v-link clickable"
          :class="provinceActiveIndex == index ? 'selected' : ''"
          v-for="(item,index) in districtList" :key="item.id"
          @click="districtSelect(item.value, index)">{{ item.name }}</span>
      </div>
      </div>
    </div>
    </div>
    <div class="v-scroll-list hospital-list">
      <div class="v-card clickable list-item" v-for="item in list" :key="item.id">
        <div class="">
          <div class="hospital-list-item hos-item" index="0" @click="show(item.hoscode)">
            <div class="wrapper">
            <div class="hospital-title"> {{ item.hosname }}</div>
            <div class="bottom-container">
            <div class="icon-wrapper">
              <span class="iconfont"></span>{{ item.param.hostypeString }}
            </div>
          <div class="icon-wrapper">
          <span class="iconfont"></span>每天{{ item.bookingRule.releaseTime }}放号
          </div>
          </div>
          </div>
          <img :src="'data:image/jpeg;base64,'+item.logoData"
           :alt="item.hosname"
           class="hospital-img">
      </div>
    </div>
    </div>
    </div>
    </div>
    <div class="right">
      <div class="common-dept">
      <div class="header-wrapper">
      <div class="title"> 常见科室</div>
      <div class="all-wrapper"><span>全部</span>
      <span class="iconfont icon"></span>
      </div>
      </div>
      <div class="content-wrapper">
      <span class="item v-link clickable dark">神经内科 </span>
      <span class="item v-link clickable dark">消化内科 </span>
      <span class="item v-link clickable dark">呼吸内科 </span>
      <span class="item v-link clickable dark">内科 </span>
      <span class="item v-link clickable dark">神经外科 </span>
      <span class="item v-link clickable dark">妇科 </span>
      <span class="item v-link clickable dark"> 产科 </span>
      <span class="item v-link clickable dark">儿科 </span>
      </div>
    </div>
    <div class="space">
      <div class="header-wrapper">
      <div class="title-wrapper">
      <div class="icon-wrapper"><span
      class="iconfont title-icon"></span>
      </div>
      <span class="title">平台公告</span>
      </div>
      <div class="all-wrapper">
      <span>全部</span>
      <span class="iconfont icon"></span>
      </div>
      </div>
      <div class="content-wrapper">
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark">关于延长北京大学国际医院放假的通知 </span>
      </div>
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark">北京中医药大学东方医院部分科室医生门诊医 </span>
      </div>
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark"> 武警总医院号源暂停更新通知 </span>
      </div>
      </div>
    </div>
    <div class="suspend-notice-list space">
    <div class="header-wrapper">
    <div class="title-wrapper">
      <div class="icon-wrapper">
      <span class="iconfont title-icon"></span>
      </div>
      <span class="title">停诊公告</span>
      </div>
      <div class="all-wrapper">
      <span>全部</span>
      <span class="iconfont icon"></span>
      </div>
      </div>
      <div class="content-wrapper">
      <div class="notice-wrapper">
      <div class="point"></div>
      <span class="notice v-link clickable dark"> 中国人民解放军总医院第六医学中心(原海军总医院)呼吸内科门诊停诊公告 </span>
      </div>
      <div class="notice-wrapper">
      <div class="point"></div>
    <span class="notice v-link clickable dark"> 首都医科大学附属北京潞河医院老年医学科门诊停诊公告 </span>
    </div>
      <div class="notice-wrapper">
        <div class="point"></div>
        <span class="notice v-link clickable dark">中日友好医院中西医结合心内科门诊停诊公告 </span>
      </div>
    </div>
    </div>
    </div>
    </div>
  </div>
</template>
<script>

import hospApi from '@/api/hospital.js'
import dictApi from '@/api/dict.js'

export default {
  //服务端渲染异步,显示医院列表:该方法类似于vue对象的created钩子函数,只不过asyncData是在create钩子函数执行之前执行,而且只会执行一次
  asyncData({ params, error }) { //在这个方法中不能使用this关键字
    //调用
    return hospApi.getHospitalList(null)
      .then(response => {
        return {
          list: response.data.list,
        }
      })
    },
  data() {
    return {
      searchObj: {},
      page: 1,
      limit: 10,

      hosname: '', //医院名称
      hostypeList: [], //医院等级集合
      districtList: [], //地区集合

      hostypeActiveIndex: 0,
      provinceActiveIndex: 0
    }
  },
  created() {
    this.init()
  },
  methods:{
    //查询医院等级列表 和 所有地区列表
    init() {
      //查询医院等级列表
      dictApi.getChildList('10000')
        .then(response => {
          //hostypeList清空
          this.hostypeList = []
          //向hostypeList添加全部值
          this.hostypeList.push({"name":"全部","value":""})
          //把接口返回数据,添加到hostypeList
          for(var i=0;i<response.data.items.length;i++) {
              this.hostypeList.push(response.data.items[i])
          }
      })

      //查询地区数据
      dictApi.getChildList('110100')
        .then(response => {
          this.districtList = []
          this.districtList.push({"name":"全部","value":""})
          for(let i in response.data.items) {
            this.districtList.push(response.data.items[i])
          }
        })
    },

    //查询医院列表
    getList() {
      hospApi.getHospitalList(this.searchObj)
        .then(response => {
          for(let i in response.data.list) {
            this.list.push(response.data.list[i])
          }
         // this.page = response.data.pages.totalPages
        })
    },

    //根据医院等级查询
    hostypeSelect(hostype,index) {
      //准备数据
      this.list = []
      this.page = 1
      this.hostypeActiveIndex = index
      this.searchObj.hostype = hostype
      //调用查询医院列表方法
      this.getList()
    },

    //根据地区查询医院
    districtSelect(districtCode, index) {
      this.list = []
      this.page = 1
      this.provinceActiveIndex = index
      this.searchObj.districtCode = districtCode
      this.getList();
    },

    //在输入框输入值,弹出下拉框,显示相关内容
    querySearchAsync(queryString, cb) {
      this.searchObj = []
      if(queryString == '') return
      hospApi.getByHosname(queryString).then(response => {
        for (let i = 0, len = response.data.list.length; i <len; i++) {
          response.data.list[i].value = response.data.list[i].hosname
        }
        cb(response.data.list)
      })
    },

    //在下拉框选择某一个内容,执行下面方法,跳转到详情页面中
    handleSelect(item) {
      window.location.href = '/hospital/' + item.hoscode
    },

    //点击某个医院名称,跳转到详情页面中
    show(hoscode) {
      window.location.href = '/hospital/' + hoscode
    }
  }
}
</script>

五、医院详情

1、医院详情接口

需要获取医院信息(医院基本信息、预约信息)和科室信息
(1)添加service接口与实现
在HospitalService添加

    /**
     * 医院预约挂号详情
     */
    Hospital getHospitalDetail(String hoscode);

    //实现方法
    @Override
    public Hospital getHospitalDetail(String hoscode) {
        Hospital hospital = hospitalRepository.findByHoscode(hoscode);
        this.packageHospital(hospital);
        return hospital;
    }

(2)HospitalApiController添加方法

    @Autowired
    private DepartmentService departmentService;

    @ApiOperation(value = "获取科室列表")
    @GetMapping("/department/{hoscode}")
    public R findAll(@PathVariable String hoscode) {
        List<DepartmentVo> list = departmentService.getDeptList(hoscode);
        return R.ok().data("list",list);
    }

    @ApiOperation(value = "医院预约挂号详情")
    @GetMapping("/detail/{hoscode}")
    public R getHospitalDetail(@PathVariable String hoscode) {
        Hospital hospital= hospitalService.getHospitalDetail(hoscode);
        return R.ok().data("hospital",hospital);
    }

2、医院详情前端

2.1 封装api方法

在hospital.js定义方法

    getHospitalDetail(hoscode) {
        return request({
            url: `${api_name}/detail/${hoscode}`,
            method: 'get'
        })
    },
    findDepartment(hoscode) {
        return request({
            url: `${api_name}/department/${hoscode}`,
            method: 'get'
        })
    }

2.2 动态路由

(1)创建方式
如果我们需要根据id查询一条记录,就需要使用动态路由。NUXT的动态路由是以下划线开头的vue文件,参数名为下划线后边的文件名
因为你要点不同的医院hoscode不一样,所以需要动态路由
在这里插入图片描述

(2)创建/pages/hospital/_hoscode.vue组件
在这里插入图片描述

<template>
    <!-- header -->
        <div class="nav-container page-component">
            <!--左侧导航 #start -->
            <div class="nav left-nav">
                <div class="nav-item selected">
                    <span class="v-link selected dark" 
                        :onclick="'javascript:window.location=\'/hospital/'+hospital.hoscode+'\''">预约挂号 </span>
                </div>
                    <div class="nav-item ">
                        <span class="v-link clickable dark" :onclick="'javascript:window.location=\'/hospital/detail/'+hospital.hoscode+'\''"> 医院详情 </span>
                    </div>
                    <div class="nav-item">
                        <span class="v-link clickable dark" :onclick="'javascript:window.location=\'/hospital/notice/'+hospital.hoscode+'\''"> 预约须知 </span>
                    </div>
                    <div class="nav-item "><span
                        class="v-link clickable dark"> 停诊信息 </span>
                    </div>
                    <div class="nav-item "><span
                        class="v-link clickable dark"> 查询/取消 </span>
                    </div>
            </div>
            <!-- 左侧导航 #end -->
            <!-- 右侧内容 #start -->
            <div class="page-container">
                <div class="hospital-home">
                    <div class="common-header">
                        <div class="title-wrapper"><span
                            class="hospital-title">{{ hospital.hosname }}</span>
                            <div class="icon-wrapper">
                                <span class="iconfont"></span>{{ hospital.param.hostypeString }}
                            </div>
                        </div>
                    </div>
                    <div class="info-wrapper">
                        <img class="hospital-img" :src="'data:image/jpeg;base64,'+hospital.logoData" :alt="hospital.hosname">
                    <div class="content-wrapper">
                    <div> 挂号规则</div>
                        <div class="line">
                            <div><span class="label">预约周期:</span><span>{{ bookingRule.cycle }}</span></div>
                            <div class="space"><span class="label">放号时间:</span><span>{{ bookingRule.releaseTime }}</span></div>
                            <div class="space"><span class="label">停挂时间:</span><span>{{ bookingRule.stopTime }}</span></div>
                        </div>
                        <div class="line"><span class="label">退号时间:</span>
                            <span v-if="bookingRule.quitDay == -1">就诊前一工作日{{ bookingRule.quitTime }}前取消</span>
                            <span v-if="bookingRule.quitDay == 0">就诊前当天{{ bookingRule.quitTime }}前取消</span>
                        </div>
                        <div style="margin-top:20px"> 医院预约规则</div>
                        <div class="rule-wrapper">
                            <ol>
                            <li v-for="item in bookingRule.rule" :key="item">{{ item }}</li>
                            </ol>
                        </div>
                    </div>
                    </div>
                    <div class="title select-title"> 选择科室</div>
                    <div class="select-dept-wrapper">
                        <div class="department-wrapper">
                        <div class="hospital-department">
                            <div class="dept-list-wrapper el-scrollbar" style="height: 100%;">
                                <div class="dept-list el-scrollbar__wrap" style="margin-bottom: -17px; margin-right: -17px;">
                                    <div class="el-scrollbar__view">
                                        <div class="sub-item" v-for="(item,index) in departmentVoList" :key="item.id" :class="index == activeIndex ? 'selected' : ''" @click="move(index,item.depcode)"> {{ item.depname }}</div>
                                    </div>
                                </div>
                                <div class="el-scrollbar__bar is-horizontal">
                                    <div class="el-scrollbar__thumb" style="transform: translateX(0%);"></div>
                                </div>
                                <div class="el-scrollbar__bar is-vertical">
                                    <div class="el-scrollbar__thumb" style="transform: translateY(0%); height: 91.4761%;"></div>
                                </div>
                            </div>
                        </div>
                        </div>
                        <div class="sub-dept-container">
                            <div v-for="(item,index) in departmentVoList" :key="item.id" :class="index == 0 ? 'selected' : ''" class="sub-dept-wrapper" :id="item.depcode">
                                <div class="sub-title">
                                    <div class="block selected"></div>{{ item.depname }}
                                </div>
                                <div class="sub-item-wrapper">
                                    <div v-for="it in item.children" :key="it.id" class="sub-item" @click="schedule(it.depcode)"><span class="v-link clickable">{{ it.depname }} </span></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        <!-- 右侧内容 #end -->
        </div>
        <!-- footer -->
    </template>
    
    <script>
    import '~/assets/css/hospital_personal.css'
    import '~/assets/css/hospital.css'
    
    import hospitalApi from '@/api/hospital'
    
    export default {
      data() {
        return {
          hoscode: null,
          activeIndex: 0,
    
          hospital: {
            param: {}
          },
          bookingRule : {},
          departmentVoList : []
        }
      },
      created() {
        this.hoscode = this.$route.params.hoscode
        this.init()
      },
      methods: {
        init() {
            //根据医院编号查询医院详情信息
          hospitalApi.getHospitalDetail(this.hoscode).then(response => {
            this.hospital = response.data.hospital
            this.bookingRule = response.data.hospital.bookingRule
          })
    
          //根据医院编号查询当前医院底下所有的科室信息
          hospitalApi.findDepartment(this.hoscode).then(response => {
            this.departmentVoList = response.data.list
          })
        },
        schedule(depcode) {
          window.location.href = '/hospital/schedule?hoscode=' + this.hoscode + "&depcode="+ depcode
        }
      }
    }
    </script>

2.3 医院详情

在这里插入图片描述

创建/pages/hospital/detail/_hoscode.vue组件

<template>
    <!-- header -->
    <div class="nav-container page-component">
      <!--左侧导航 #start -->
      <div class="nav left-nav">
        <div class="nav-item ">
          <span class="v-link clickable dark" :onclick="'javascript:window.location=\'/hospital/'+hospital.hoscode+'\''">预约挂号 </span>
        </div>
        <div class="nav-item selected">
          <span class="v-link selected dark" :onclick="'javascript:window.location=\'/hospital/detail/'+hospital.hoscode+'\''"> 医院详情 </span>
        </div>
        <div class="nav-item">
          <span class="v-link clickable dark" :onclick="'javascript:window.location=\'/hospital/notice/'+hospital.hoscode+'\''"> 预约须知 </span>
        </div>
        <div class="nav-item "><span
          class="v-link clickable dark"> 停诊信息 </span>
        </div>
        <div class="nav-item "><span
          class="v-link clickable dark"> 查询/取消 </span>
        </div>
      </div>
      <!-- 左侧导航 #end -->
  
      <!-- 右侧内容 #start -->
      <div class="page-container">
        <div class="hospital-detail">
          <div class="common-header">
            <div class="title-wrapper"><span class="hospital-title">{{ hospital.hosname }}</span>
              <div class="icon-wrapper"><span class="iconfont"></span> {{ hospital.param.hostypeString }}</div>
            </div>
          </div>
          <div class="info-wrapper"><img :src="'data:image/jpeg;base64,'+hospital.logoData" :alt="hospital.hosname" style="width: 80px; height: 80px;">
            <div class="content-wrapper">
              <div></div>
              <div></div>
              <div></div>
              <div>
                <div class="icon-text-wrapper"><span class="iconfont prefix-icon"></span>
                  <span class="text"><p>{{ hospital.route }}</p>
                </span><span class="iconfont right-icon"></span></div>
              </div>
            </div>
          </div>
          <div class="title mt40"> 医院介绍</div>
          <div class="detail-content mt40"><p>{{ hospital.intro }}</p></div>
        </div>
      </div>
      <!-- 右侧内容 #end -->
    </div>
    <!-- footer -->
  </template>
  
  <script>
  import '~/assets/css/hospital_personal.css'
  import '~/assets/css/hospital.css'
  
  import hospitalApi from '@/api/hospital'
  export default {
    data() {
      return {
        hoscode: null,
        hospital: {
          param: {}
        }
      }
    },
  
    created() {
      this.hoscode = this.$route.params.hoscode
  
      this.init()
    },
  
    methods: {
      init() {
        hospitalApi.getHospitalDetail(this.hoscode).then(response => {
          this.hospital = response.data.hospital
        })
  
      }
    }
  }
  </script>
  <style>
    .hospital-detail .info-wrapper {
      width: 100%;
      padding-left: 0;
      padding-top: 0;
      margin-top: 0;
      flex-direction: inherit;
    }
  
    .hospital-detail .info-wrapper .text {
      font-size: 14px;
  
    }
  
    .hospital-detail .content-wrapper p {
      text-indent: 0;
    }
  </style>

2.4 预约规则

在这里插入图片描述

创建/pages/hospital/notice/_hoscode.vue组件

<template>
    <!-- header -->
    <div class="nav-container page-component">
      <!--左侧导航 #start -->
      <div class="nav left-nav">
        <div class="nav-item ">
          <span class="v-link clickable dark" :onclick="'javascript:window.location=\'/hospital/'+hospital.hoscode+'\''">预约挂号 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark" :onclick="'javascript:window.location=\'/hospital/detail/'+hospital.hoscode+'\''"> 医院详情 </span>
        </div>
        <div class="nav-item selected">
          <span class="v-link selected dark" :onclick="'javascript:window.location=\'/hospital/notice/'+hospital.hoscode+'\''"> 预约须知 </span>
        </div>
        <div class="nav-item "><span
          class="v-link clickable dark"> 停诊信息 </span>
        </div>
        <div class="nav-item "><span
          class="v-link clickable dark"> 查询/取消 </span>
        </div>
      </div>
      <!-- 左侧导航 #end -->
  
      <!-- 右侧内容 #start -->
      <div class="page-container">
        <div class="hospital-notice">
          <div class="content"><h2>{{ hospital.hosname }}预约挂号须知</h2>
            <p>为方便您早日就医康复,请您认真阅读预约挂号须知:</p>
            <h4 id="一、预约实名制:">一、预约实名制:</h4>
            <p>统一平台电话预约和网上预约挂号均采取实名制注册预约,请您如实提供就诊人员的真实姓名、有效证件号(身份证、护照)、性别、手机号码、社保卡号等基本信息。</p>
            <h4 id="二、预约挂号:">二、预约挂号:</h4>
            <p>按照北京市卫健委统一平台要求,预约挂号规则如下:</p>
            <ul>
              <li>在同一自然日,同一医院,同一科室,同一就诊单元,同一就诊人,可以预约最多1个号源;</li>
              <li>在同一自然周,同一就诊人,可以预约最多8个号源;</li>
              <li>在同一自然月,同一就诊人,可以预约最多12个号源;</li>
              <li>在同一自然季度,同一就诊人,可以预约最多24个号源。</li>
            </ul>
            <h4 id="三、取消预约:">三、取消预约:</h4>
            <p>已完成预约的号源,如需办理退号,至少在就诊前一工作日14:00前通过网站、微信公众号、114电话等平台预约渠道进行取消预约。</p>
            <h4 id="四、爽约处理:">四、爽约处理:</h4>
            <p>如预约成功后患者未能按时就诊且不办理取消预约号视为爽约,同一患者在自然年内爽约规则如下:</p>
            <ul>
              <li>累计爽约3次,自3次爽约日起,90天内不允许通过114平台进行预约挂号;</li>
              <li>累计爽约6次,自6次爽约日起,180天内不允许通过114平台进行预约挂号。</li>
            </ul>
          </div>
  
        </div>
      </div>
      <!-- 右侧内容 #end -->
    </div>
    <!-- footer -->
  </template>
  
  <script>
  
  import '~/assets/css/hospital_personal.css'
  import '~/assets/css/hospital.css'
  
  import hospitalApi from '@/api/hospital'
  export default {
    data() {
      return {
        hoscode: null,
        hospital: {
          param: {}
        }
      }
    },
  
    created() {
      this.hoscode = this.$route.params.hoscode
  
      this.init()
    },
  
    methods: {
      init() {
        hospitalApi.getHospitalDetail(this.hoscode).then(response => {
          this.hospital = response.data.hospital
        })
      }
    }
  }
  </script>
  <style>
    .hospital-detail .info-wrapper {
      width: 100%;
      padding-left: 0;
      padding-top: 0;
      margin-top: 0;
      flex-direction: inherit;
    }
  
    .hospital-detail .info-wrapper .text {
      font-size: 14px;
  
    }
  
    .hospital-detail .content-wrapper p {
      text-indent: 0;
    }
  </style>

2.5 Nuxt中的两种路由总结

在这里插入图片描述

六、点击图标回到首页

在这里插入图片描述
在layouts下的myheader.vue进行修改
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker镜像发布到阿里云和私有库

目录 一、Docker镜像 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;Docker镜像加载原理 &#xff08;三&#xff09;镜像分层结构优势 &#xff08;四&#xff09;重点理解 &#xff08;五&#xff09;docker commit操作实例 &#xff08;六&#xff09;总…

如何解决nas无公网问题,实现kodbox可道云内网映射外网访问

目前&#xff0c;市面上有很多NAS产品&#xff0c;如群晖、威联通以及华硕NAS等&#xff0c;它们都自带提供了一些基础的文件管理功能&#xff0c;有的也可以直接在NAS上使用文件管理的应用程序。 kodbox可道云是一个基于 Web 技术的私有云和在线文件管理系统&#xff0c;有着…

考了PMP证后工资大概是多少 ?(含pmp资料)

这个岗位的不同还有每个公司的薪资也是不一样的&#xff0c;具体的数字肯定是没有的&#xff0c;但大概的比例还是有的&#xff0c;据PMI调查&#xff0c;在获得PMP证书的人当中&#xff0c;在PMP认证一年后&#xff0c;年薪有所增长的比例为66%&#xff0c;上涨幅度主要集中在…

抓包工具Charles(二)-移动端APP抓包(设置手机代理、安装证书)

安装好Charles之后&#xff0c;还只能捕获电脑的接口请求想要抓取移动设备的APP还需要设置代理、安装证书。 文章目录一、抓包原理二、手机设置网络代理1、 查看电脑的IP地址&#xff08;local IP address&#xff09;2、设置手机网络代理&#xff08;1&#xff09;iOS设备&…

美团:某动态线程池框架是官方开源的么?

大家好&#xff0c;我是马称。 最近&#xff0c;有很多同学在微信上问我这么一个问题&#xff1a; Hippo4j 动态线程池框架是美团开源的么&#xff1f; 类似于这样的问题还挺多&#xff0c;在这里统一回复下&#xff1a; 美团官方并没有开源任何关于动态线程池的框架。 美…

【深度学习】多分类问题和多标签分类问题

上一章——激活函数 文章目录什么是多分类问题Softmax贝叶斯公式softmax的损失函数多标签分类问题什么是多分类问题 在之前的课程中&#xff0c;我们学习了二分问题&#xff0c;二分问题中的所有数据会被分类为0和1&#xff08;或者Ture和False&#xff09;两种输出标签。但是…

Java_小项目书城

1.概述 书城的基本功能&#xff1a; 展示书籍上新书籍下架书籍退出应用 书城项目所涉及到的知识点&#xff1a; 用户交互–键盘录入分支结构&#xff0c;循环结构面向对象的思维&#xff0c;封装对象集合的使用 2.菜单的编写 这部分代码就是读取用户键盘的录入&#xff0…

Qt线程池

目录1、线程池是什么&#xff1f;2、Qt线程池2.1、用法例程2.2、线程池对性能的提升2.3、运行算法单线程写法线程池写法1、线程池是什么&#xff1f; 线程池是一种线程使用模式&#xff0c;它管理着一组可重用的线程&#xff0c;可以处理分配过来的可并发执行的任务。 线程池设…

2023最新一线大厂Java八股文强势开源,整整8w字,711页内容

前言 大家都知道每年的3月和4月都是互联网大厂疯狂招人的黄金期&#xff0c;也就是程序员的黄金跳槽期&#xff0c;所以被称为金三银四。 无论你是刚出校园大门的菜鸟&#xff0c;还是对跳槽蓄谋已久的老手&#xff0c;都会在这个时候找到新工作和迎来晋升涨薪的最佳时机。 而…

1.InfluxDB简介与安装

InfluxDB简介 InfluxDB是一个时序性数据库&#xff0c;适用场景数据分析&#xff0c;IoT设备数据采集&#xff0c;监控告警等。InfluxDB是采用GO语言编写&#xff0c;底层提供了大量的HTTP协议的API 其他语言的SDK都采用访问HTTP接口的形式对InfluxDB进行操作 InfluxDB官方一…

WPF学习:Slider — 冒泡显示值

想做一个下图所示的Slider&#xff0c;以冒泡的方式显示其Value值&#xff0c;该怎么做呢&#xff1f; 功能要求&#xff0c;当鼠标放在滑块上的时候&#xff0c;冒“泡”显示值&#xff1b;当滑块移动的时候&#xff0c;“泡”跟随移动。 看似简单的功能&#xff0c;但要完美…

扬帆优配“数字经济+实体经济”融合发展,行业增长空间大!

组织以为&#xff0c;数字经济已经逐步成为工业商场和资本商场的共同主题。 2月16日&#xff0c;国家发改委在《求是》杂志发表文章《努力推进经济完成质的有效提升和量的合理增加》。文章指出要加速开展数字经济&#xff0c;加速实施“东数西算”等重大工程&#xff0c;推进数…

计算机网络笔记(四)—— 数据链路层

点对点协议PPP 目前使用最广泛的点对点数据链路层协议 由以下三个部分构成&#xff1a; PPP工作状态 媒体接入控制 主要解决共享信道的协调问题 静态划分信道 复用&#xff1a;通过一条物理线路同时传输多路用户的信号 频分复用&#xff08;FDM&#xff09;&#xff1a;占用…

DataEase 制作数据可视化大屏经验分享

前言 DataEase 简介 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务的改进与优化。DataEase 支持丰富的数据源连接&#xff0c;能够通过拖拉拽方式快速制作图表&#xff0c;并可以方便地与他人分享。 更多详细介…

ChatGPT及相关产品体验与研究

ChatGPT及相关产品体验与研究 我的Github博客仓库链接&#xff1a;ChatGPT及相关产品体验与研究 - Github 一、ChatGPT介绍 1. ChatGPT概述 一句话描述ChatGPT&#xff1a;一个能够通过对话得到你想要的答案的聊天机器人。 ChatGPT 是由 OpenAI 开发的一种基于深度学习的自然…

SPI简介与实例分析

SPI简介 SPI 协议是由Motorola提出的通讯协议 (Serial Peripheral Interface) &#xff0c;是一种高速全双工的串行通信总线。 SPI 通讯使用 3 条总线 &#xff1a;SCK、 MOSI、 MISO &#xff0c;以及若干片选线(SS、CS、NSS)。 主机要和哪个从机通信&#xff0c;就把对应的…

看板项目管理使用指南

作为一种项目管理方法&#xff0c;看板涉及创建列出任务详细信息的可视化卡片&#xff0c;并将它们组织到代表生产过程不同阶段的白板列表中。 今天&#xff0c;看板已经从工厂的白板发展到了我们电脑屏幕上的数字看板应用程序形式。现在的看板项目管理方法可帮助团队管理编辑…

CentOS Stream 8配置DNS

1&#xff1a;用CentOS搭建DNS的目的是想解析一台下载服务器&#xff0c;IP地址172.18.0.58&#xff0c;现在是用IP地址方的式访问&#xff0c;想搭建DNS服务器用域名的方式访问。 使用下面的命令查看一下当前系统的Bind版本。 yum info bind 版本是9.11.36.我的CentOS是最小…

KDGK-703S便携式综合校验仪(毫伏发生器)

一、产品简介 KDGK-703S便携式综合校验仪&#xff08;毫伏发生器&#xff09;是一种集数显式电压、电流、频率标准信号源、Pt100 铂电阻温度模拟标准信号源、数字式电压、电流、频率测量功能于一体的高精度、高分辨率、多用途的自动化仪表校准仪器。 它具有信号输出和测试功能&…

有关eclipse的使用tips

一、alt/键 会产生单词提示&#xff0c;可以提高编程速度。例如不需要辛辛苦苦的打出&#xff1a;System.out.println();整句&#xff0c;只需要在eclipse中输入syso&#xff0c;然后按住ALT/就会出来System.out.println();在alt键/不管用的情况下&#xff0c;可使用以下方法来…