Day114.尚医通:用户认证、阿里云OSS、就诊人管理

目录

一、阿里云对象存储OSS

二、整合对象存储OSS 

1、项目搭建

2、接口开发

三、用户认证

1、接口实现

2、前端实现

四、就诊人管理-接口实现

五、就诊人管理-前端实现

1、实现查询页面

2、就诊人添加与修改

3、就诊人详情与删除


一、阿里云对象存储OSS

1. 开通服务

2. 创建Bucket

 

3. 上传文件

  

4. 查看文档: 

二、整合对象存储OSS 

1、项目搭建

新建项目 OSS

<dependencies>
    <!-- 阿里云oss依赖 -->
    <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
    </dependency>

    <!-- 日期工具栏依赖 -->
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
    </dependency>
</dependencies>
#服务端口
server.port=8205
#服务名
spring.application.name=service-oss

#环境设置:dev、test、prod
spring.profiles.active=dev

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#阿里云 OSS
#不同的服务器,地址不同
aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
aliyun.oss.file.keyid=LTAI5t7uFu3NsrFbAA3jYoFv
aliyun.oss.file.keysecret=DSAnOc8ZAZ8rwaedcWG6E1egbdTYqU
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=guli-file-test11

别忘了配置网关

#设置路由id
spring.cloud.gateway.routes[5].id=service-oss
#设置路由的uri
spring.cloud.gateway.routes[5].uri=lb://service-oss
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[5].predicates= Path=/*/oss/**

工具类

//常量类,读取配置文件application.properties中的配置
@Component
//@PropertySource("classpath:application.properties")
public class ConstantPropertiesUtil implements InitializingBean {

	@Value("${aliyun.oss.file.endpoint}")
	private String endpoint;

	@Value("${aliyun.oss.file.keyid}")
	private String keyId;

	@Value("${aliyun.oss.file.keysecret}")
	private String keySecret;

	@Value("${aliyun.oss.file.bucketname}")
	private String bucketName;

	public static String END_POINT;
	public static String ACCESS_KEY_ID;
	public static String ACCESS_KEY_SECRET;
	public static String BUCKET_NAME;

	@Override
	public void afterPropertiesSet() throws Exception {
		END_POINT = endpoint;
		ACCESS_KEY_ID = keyId;
		ACCESS_KEY_SECRET = keySecret;
		BUCKET_NAME = bucketName;
	}
}

2、接口开发

1. 分析接口

*参数:file

*返回值:url 

2. 实现 controller

@Api(description="阿里云文件管理")
@RestController
@RequestMapping("/admin/oss/file")
public class FileUploadController {

    @Autowired
    private FileService fileService;

    @ApiOperation(value = "文件上传")
    @PostMapping("upload")
    public R upload(@RequestParam("file") MultipartFile file) {
        String url = fileService.upload(file);
        return R.ok().data("url",url);
    }

}

3. 实现service

@Service
public class FileServiceImpl implements FileService {

    //文件上传至阿里云
    @Override
    public String upload(MultipartFile file) {
        //1.获取参数
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = ConstantPropertiesUtil.END_POINT;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = ConstantPropertiesUtil.ACCESS_KEY_ID;
        String accessKeySecret = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
        // 填写Bucket名称,例如examplebucket。
        String bucketName = ConstantPropertiesUtil.BUCKET_NAME;

        //2.创建客户端对象
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {

            //3.准备文件参数
            InputStream inputStream = file.getInputStream();
            String fileName = file.getOriginalFilename();
            //3.2 保证文件名不重复 uuid + fileName.jpg
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            fileName = uuid+fileName;
            //3.3 根据日期创建路径 2022/07/30+fileName(便于维护)
            String path = new DateTime().toString("yyyy/MM/dd");
            fileName = path+"/"+fileName;

            //4.上传文件
            ossClient.putObject(bucketName,fileName,inputStream);

            //5.获取文件url
            //https://guli-file-test11.oss-cn-beijing.aliyuncs.com/test.jpg
            String url = "https://" + bucketName + "." + endpoint + "/" + fileName;
            
            return url;
        } catch (IOException e) {
            e.printStackTrace();
            throw new YyghException(20001,"上传文件失败");
        }finally {
            //6.关闭客户端
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

测试 

三、用户认证

用户登录成功后都要进行身份认证,认证通过后才可以预约挂号

认证过程:用户填写信息(姓名、证件类型、证件号码和证件照片)==> 平台审批

用户认证设计接口:

1. 提交认证

2. 上传证件图片

3. 获取提交认证信息

1、接口实现

1. 分析接口

(1). 提交认证接口

*参数:UserAuthVo、请求对象(存入主键id)

*返回值:R.ok()

(2).  查询认证接口

*参数:请求对象

*返回值:userInfo

2. 添加工具类

在common_utils添加工具类

//获取当前用户信息工具类
public class AuthContextHolder {
    //获取当前用户id
    public static Long getUserId(HttpServletRequest request) {
        //从header获取token
        String token = request.getHeader("token");
        //jwt从token获取userid
        Long userId = JwtHelper.getUserId(token);
        return userId;
    }
    //获取当前用户名称
    public static String getUserName(HttpServletRequest request) {
        //从header获取token
        String token = request.getHeader("token");
        //jwt从token获取userid
        String userName = JwtHelper.getUserName(token);
        return userName;
    }
}

3. 实现 controller

UserInfoApiController 添加方法

    @ApiOperation(value = "用户认证提交接口")
    @PostMapping("auth/userAuth")
    public R userAuth(@RequestBody UserAuthVo userAuthVo, HttpServletRequest request) {
        //1.取出用户id
        Long userId = AuthContextHolder.getUserId(request);
        //2.更新用户认证信息
        userInfoService.userAuth(userId,userAuthVo);
        return R.ok();
    }

    @ApiOperation(value = "根据用户id获取用户认证信息")
    @GetMapping("auth/getUserInfo")
    public R getUserInfo(HttpServletRequest request) {
        Long userId = AuthContextHolder.getUserId(request);
        UserInfo userInfo = userInfoService.getUserInfo(userId);
        return R.ok().data("userInfo",userInfo);
    }

4. 实现 service

    //用户认证提交
    @Override
    public void userAuth(Long userId, UserAuthVo userAuthVo) {
        //1.根据用户userId查询用户信息
        UserInfo userInfo = baseMapper.selectById(userId);
        if(userInfo==null){
            throw new YyghException(20001,"用户信息有误");
        }
        //2.更新认证信息
        BeanUtils.copyProperties(userAuthVo,userInfo);
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus()); //状态值 0未认证 1认证中 2已认证 -1失败
        baseMapper.updateById(userInfo);
    }

    //根据用户id获取用户认证信息
    @Override
    public UserInfo getUserInfo(Long userId) {
        //1.根据用户userId查询用户信息
        UserInfo userInfo = baseMapper.selectById(userId);
        if(userInfo==null){
            throw new YyghException(20001,"用户信息有误");
        }
        //2.翻译相关字段
        userInfo = this.packUserInfo(userInfo);
        return userInfo;
    }

    //翻译相关字段(认证状态)
    private UserInfo  packUserInfo(UserInfo userInfo){
        String statusNameByStatus = AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus());
        userInfo.getParam().put("authStatusString",statusNameByStatus);
        return userInfo;
    }

2、前端实现

1.确认入口,创建页面

2. API接口

    //根据用户id获取用户认证信息
    getUserInfo() {
        return request({
            url: `${api_name}/auth/getUserInfo`,
            method: `get`
        })
    },
    //用户认证提交接口
    saveUserAuah(userAuah) {
        return request({
             url: `${api_name}/auth/userAuth`,
             method: 'post',
             data: userAuah
        })
    }

3. 工具类 request.js  改造 request拦截器 (每次发送请求时拦截)

import cookie from 'js-cookie'

...

// http request 拦截器
service.interceptors.request.use(
    config => {
        // 判断cookie里token是否有值,存入头信息
        if (cookie.get('token')) {
            config.headers['token'] = cookie.get('token')
        }

        return config
    },
    err => {
        return Promise.reject(err)
    })

4. 添加页面元素

<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='/user'">实名认证 </span>
            </div>
            <div class="nav-item">
                <span class="v-link selected dark" onclick="javascript:window.location='/order'"> 挂号订单 </span>
            </div>
            <div class="nav-item ">
                <span class="v-link clickable dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </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>
                <div class="title"> 实名认证</div>
                <div class="status-bar">
                    <div class="status-wrapper"><span class="iconfont"></span>{{ userInfo.param.authStatusString }}
                    </div>
                </div>
                <div class="tips"><span class="iconfont"></span>
                    完成实名认证后才能添加就诊人,正常进行挂号,为了不影响后续步骤,建议提前实名认证。
                </div>
                <div class="form-wrapper" v-if="userInfo.authStatus == 0">
                    <div>
                        <el-form :model="userAuah" label-width="110px" label-position="left">
                            <el-form-item prop="name" label="姓名:" class="form-normal">
                                <div class="name-input">
                                    <el-input v-model="userAuah.name" placeholder="请输入联系人姓名全称" class="input v-input" />
                                </div>
                            </el-form-item>
                            <el-form-item prop="certificatesType" label="证件类型:">
                                <el-select v-model="userAuah.certificatesType" placeholder="请选择证件类型"
                                    class="v-select patient-select">
                                    <el-option v-for="item in certificatesTypeList" :key="item.value" :label="item.name"
                                        :value="item.name">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item prop="certificatesNo" label="证件号码:">
                                <el-input v-model="userAuah.certificatesNo" placeholder="请输入联系人证件号码"
                                    class="input v-input" />
                            </el-form-item>
                            <el-form-item prop="name" label="上传证件:">
                                <div class="upload-wrapper">
                                    <div class="avatar-uploader">
                                        <el-upload class="avatar-uploader" :action="fileUrl" :show-file-list="false"
                                            :on-success="onUploadSuccess">
                                            <div class="upload-inner-wrapper">
                                                <img v-if="userAuah.certificatesUrl" :src="userAuah.certificatesUrl"
                                                    class="avatar">
                                                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                                                <div v-if="!userAuah.certificatesUrl" class="text"> 上传证件合照</div>
                                            </div>
                                        </el-upload>
                                    </div>
                                    <img src="//img.114yygh.com/static/web/auth_example.png" class="example">
                                </div>
                            </el-form-item>
                        </el-form>
                        <div class="bottom-wrapper">
                            <div class="button-wrapper">
                                <div class="v-button" @click="saveUserAuah()">{{ submitBnt }}</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="context-container" v-if="userInfo.authStatus != 0">
                    <div>
                        <el-form :model="formData" label-width="110px" label-position="right">
                            <el-form-item prop="name" label="姓名:" class="form-normal">
                                <div class="name-input">
                                    {{ userInfo.name }}
                                </div>
                            </el-form-item>
                            <el-form-item prop="name" label="证件类型:">
                                {{ userInfo.certificatesType }}
                            </el-form-item>
                            <el-form-item prop="name" label="证件号码:">
                                {{ userInfo.certificatesNo }}
                            </el-form-item>
                        </el-form>
                    </div>
                </div>
            </div>
        </div><!-- 右侧内容 #end -->
        <!-- 登录弹出框 -->
    </div>
    <!-- footer -->
</template>

5. 实现JS、添加CSS

<script>
    import '~/assets/css/hospital_personal.css'
    import '~/assets/css/hospital.css'
    import '~/assets/css/personal.css'
    import userInfoApi from '@/api/userinfo'
    import dictApi from '@/api/dict'

    const defaultForm = {
        name: "",
        certificatesType: "",
        certificatesNo: "",
        certificatesUrl: ""
    };
    export default {
        data() {
            return {
                userAuah: defaultForm,
                certificatesTypeList: [],
                fileUrl: "http://localhost:8222/admin/oss/file/upload",
                userInfo: {
                    param: {}
                },
                submitBnt: "提交"
            };
        },
        created() {
            //调用初始化方法
            this.init()
        },
        methods: {
            //初始化
            init() {
                //查询用户状态
                this.getUserInfo()
                //初始化证件类型集合
                this.getDict()
            },
            //查询用户状态
            getUserInfo() {
                userInfoApi.getUserInfo().then(response => {
                    this.userInfo = response.data.userInfo
                })
            },
            //查询证件类型集合
            getDict() {
                dictApi.findByDictCode("CertificatesType")
                    .then(response => {
                        this.certificatesTypeList = response.data.list
                    })
            },
            //上传后实现的方法
            onUploadSuccess(response, file) {
                if (response.code !== 20000) {
                    this.$message.error("上传失败")
                    return
                }
                // 填充上传文件列表
                this.userAuah.certificatesUrl = file.response.data.url
            },
            //认证信息提交
            saveUserAuah() {
                if (this.submitBnt == '正在提交...') {
                    this.$message.info('重复提交')
                    return
                }
                this.submitBnt = '正在提交...'

                userInfoApi.saveUserAuah(this.userAuah)
                    .then(response => {
                        this.$message.success("提交成功")
                        //更新页面
                        window.location.reload()
                    }).catch(e => {
                        this.submitBnt = '提交'
                    })
            }
        }
    };
</script>
<style>
    .header-wrapper .title {
        font-size: 16px;
        margin-top: 0;
    }

    .content-wrapper {
        margin-left: 0;
    }

    .patient-card .el-card__header .detail {
        font-size: 14px;
    }

    .page-container .title {
        letter-spacing: 1px;
        font-weight: 700;
        color: #333;
        font-size: 16px;
        margin-top: 0;
        margin-bottom: 20px;
    }

    .page-container .tips {
        width: 100%;
        padding-left: 0;
    }

    .page-container .form-wrapper {
        padding-left: 92px;
        width: 580px;
    }

    .form-normal {
        height: 40px;
    }

    .bottom-wrapper {
        width: 100%;
        padding: 0;
        margin-top: 0;
    }
</style>

6. 改造预约挂号  _hoscode.vue JS方法,做准备

  //注意引入cookie
  import cookie from "js-cookie";
    
...

      //预约挂号页面跳转
      schedule(depcode) {
        //1.判断用户是否登录
        if (!cookie.get('token')) {
          loginEvent.$emit('loginDialogEvent')
        }
        //2.判断用户认证审核是否通过 2:认证成功
        userInfoApi.getUserInfo().then(response => {
          let authStatus = response.data.userInfo.authStatus
          // 状态为2认证通过
          if (!authStatus || authStatus != 2) {
            window.location.href = '/user'
            return
          }
        })

        //?传参 还是静态请求
        //   window.location.href =
        //     "/hospital/schedule?hoscode=" + this.hoscode + "&depcode=" + depcode;
      }

预请求问题:会加载两次,导致报错 

解决方案:页面加载完成后再执行数据初始化方法 

四、就诊人管理-接口实现

1. 挂号流程分析

2. 需求确认

预约下单需要选择就诊人,因此我们要实现就诊人管理,就诊人管理其实就是要实现一个完整的增删改查

3. 准备工作

(1). userService 引入依赖

    <dependency>
        <groupId>com.atguigu</groupId>
        <artifactId>service_cmn_client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

(2). 确认实体

 

(3). 创建相关接口、类

4. 实现查询接口 controller

*参数:request

*返回值:List

@Api(tags = "就诊人管理接口")
@RestController
@RequestMapping("/api/user/patient")
public class PatientApiController {
    @Autowired
    private PatientService patientService;

    //获取就诊人列表
    @GetMapping("auth/findAll")
    public R findAll(HttpServletRequest request) {
        //1.取出用户id
        Long userId = AuthContextHolder.getUserId(request);
        //2.调用接口获取就诊人列表
        List<Patient> list = patientService.findAllUserId(userId);
        return R.ok().data("list",list);
    }
    //添加就诊人
    @PostMapping("auth/save")
    public R savePatient(@RequestBody Patient patient, HttpServletRequest request) {
        //1.取出用户id
        Long userId = AuthContextHolder.getUserId(request);
        //2.用户id存入就诊人信息
        patient.setUserId(userId);
        patientService.save(patient);
        return R.ok();
    }
    //根据id获取就诊人信息
    @GetMapping("auth/get/{id}")
    public R getPatient(@PathVariable Long id) {
        Patient patient = patientService.getPatientId(id);
        return R.ok().data("patient",patient);
    }
    //修改就诊人
    @PostMapping("auth/update")
    public R updatePatient(@RequestBody Patient patient) {
        patientService.updateById(patient);
        return R.ok();
    }
    //删除就诊人
    @DeleteMapping("auth/remove/{id}")
    public R removePatient(@PathVariable Long id) {
        patientService.removeById(id);
        return R.ok();
    }
}

5. service

@Service
public class PatientServiceImpl extends
        ServiceImpl<PatientMapper, Patient> implements PatientService {
    @Autowired
    private DictFeignClient dictFeignClient;

    //获取就诊人列表
    @Override
    public List<Patient> findAllUserId(Long userId) {
        //1.查询就诊人列表
        QueryWrapper<Patient> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        List<Patient> patientList = baseMapper.selectList(wrapper);
        //2.翻译字段
        patientList.stream().forEach(item -> {
            //其他参数封装
            this.packPatient(item);
        });
        return patientList;
    }
    //根据id获取就诊人信息
    @Override
    public Patient getPatientId(Long id) {
        Patient patient = this.packPatient(baseMapper.selectById(id));
        return patient;
    }
    //翻译字段
    private Patient packPatient(Patient patient) {
        //根据证件类型编码,获取证件类型具体指
        String certificatesTypeString =
                dictFeignClient.getName(DictEnum.CERTIFICATES_TYPE.getDictCode(), patient.getCertificatesType());//联系人证件
        //联系人证件类型
        String contactsCertificatesTypeString =
                dictFeignClient.getName(DictEnum.CERTIFICATES_TYPE.getDictCode(),patient.getContactsCertificatesType());
        //省
        String provinceString = dictFeignClient.getName(patient.getProvinceCode());
        //市
        String cityString = dictFeignClient.getName(patient.getCityCode());
        //区
        String districtString = dictFeignClient.getName(patient.getDistrictCode());
        patient.getParam().put("certificatesTypeString", certificatesTypeString);
        patient.getParam().put("contactsCertificatesTypeString", contactsCertificatesTypeString);
        patient.getParam().put("provinceString", provinceString);
        patient.getParam().put("cityString", cityString);
        patient.getParam().put("districtString", districtString);
        patient.getParam().put("fullAddress", provinceString + cityString + districtString + patient.getAddress());
        return patient;
    }

}

6. 测试

五、就诊人管理-前端实现

1、实现查询页面

1. 确认入口,创建文件


2. API  新建 patient.js

import request from '@/utils/request'

const api_name = `/api/user/patient`

export default {
    //就诊人列表
    findList() {
        return request({
            url: `${api_name}/auth/findAll`,
            method: `get`
        })
    },
    //根据id查询就诊人信息
    getById(id) {
        return request({
            url: `${api_name}/auth/get/${id}`,
            method: 'get'
        })
},
    //添加就诊人信息
    save(patient) {
        return request({
            url: `${api_name}/auth/save`,
            method: 'post',
            data: patient
        })
    },
    //修改就诊人信息
    updateById(patient) {
        return request({
            url: `${api_name}/auth/update`,
            method: 'post',
            data: patient
        })
    },
    //删除就诊人信息
    removeById(id) {
        return request({
            url: `${api_name}/auth/remove/${id}`,
            method: 'delete'
        })
    }
}

3. 添加页面

<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='/user'">实名认证 </span>
            </div>
            <div class="nav-item ">
                <span class="v-link clickable dark" onclick="javascript:window.location='/order'"> 挂号订单 </span>
            </div>
            <div class="nav-item selected">
                <span class="v-link selected dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </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="personal-patient">
                <div class="header-wrapper">
                    <div class="title"> 就诊人管理</div>
                </div>
                <div class="content-wrapper">
                    <el-card class="patient-card" shadow="always" v-for="item in patientList" :key="item.id">
                        <div slot="header" class="clearfix">
                            <div>
                                <span class="name">{{ item.name }}</span>
                                <span>{{ item.certificatesNo }} {{ item.param.certificatesTypeString }}</span>
                                <div class="detail" @click="show(item.id)"> 查看详情 <span class="iconfont"></span></div>
                            </div>
                        </div>
                        <div class="card SELF_PAY_CARD">
                            <div class="info">
                                <span class="type">{{ item.isInsure == 0 ? '自费' : '医保'}}</span>
                                <span class="card-no">{{ item.certificatesNo }}</span>
                                <span class="card-view">{{ item.param.certificatesTypeString }}</span>
                            </div>
                            <span class="operate"></span>
                        </div>
                        <div class="card">
                            <div class="text bind-card"></div>
                        </div>
                    </el-card>
                    <div class="item-add-wrapper v-card clickable" @click="add()">
                        <div class="">
                            <div>+ 添加就诊人</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- 右侧内容 #end -->
    </div>
    <!-- footer -->
</template>

4. 实现JS、添加CSS

<script>
    import '~/assets/css/hospital_personal.css'
    import '~/assets/css/hospital.css'
    import '~/assets/css/personal.css'

    import patientApi from '@/api/patient'

    export default {

        data() {
            return {
                patientList: []
            }
        },
        created() {
            //初始化查询
            this.getPatientList();
        },
        methods: {
            //初始化查询
            getPatientList() {
                patientApi.findList().then(response => {
                    this.patientList = response.data.list
                })
            },
            add() {
                window.location.href = '/patient/add'
            },
            show(id) {
                window.location.href = '/patient/show?id=' + id
            }
        }
    };
</script>
<style>
    .header-wrapper .title {
        font-size: 16px;
        margin-top: 0;
    }

    .content-wrapper {
        margin-left: 0;
    }

    .patient-card .el-card__header .detail {
        font-size: 14px;
    }
</style>

2、就诊人添加与修改

1. 确认入口,新增页面


2. 添加页面元素

<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='/user'">实名认证 </span>
            </div>
            <div class="nav-item ">
                <span class="v-link clickable dark" onclick="javascript:window.location='/order'"> 挂号订单 </span>
            </div>
            <div class="nav-item selected">
                <span class="v-link selected dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </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="personal-patient">
                <div class="header-wrapper">
                    <div class="title"> 添加就诊人</div>
                </div>
                <div>
                    <div class="sub-title">
                        <div class="block"></div>
                        就诊人信息
                    </div>
                    <div class="content-wrapper">
                        <el-form :model="patient" label-width="110px" label-position="left" ref="patient"
                            :rules="validateRules">
                            <el-form-item prop="name" label="姓名:">
                                <el-input v-model="patient.name" placeholder="请输入真实姓名全称" class="input v-input" />
                            </el-form-item>
                            <el-form-item prop="certificatesType" label="证件类型:">
                                <el-select v-model="patient.certificatesType" placeholder="请选择证件类型"
                                    class="v-select patient-select">
                                    <el-option v-for="item in certificatesTypeList" :key="item.value" :label="item.name"
                                        :value="item.value">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item prop="certificatesNo" label="证件号码:">
                                <el-input v-model="patient.certificatesNo" placeholder="请输入证件号码"
                                    class="input v-input" />
                            </el-form-item>
                            <el-form-item prop="sex" label="性别:">
                                <el-radio-group v-model="patient.sex">
                                    <el-radio :label="1">男</el-radio>
                                    <el-radio :label="0">女</el-radio>
                                </el-radio-group>
                            </el-form-item>
                            <el-form-item prop="birthdate" label="出生日期:">
                                <el-date-picker v-model="patient.birthdate" class="v-date-picker" type="date"
                                    placeholder="选择日期">
                                </el-date-picker>
                            </el-form-item>
                            <el-form-item prop="phone" label="手机号码:">
                                <el-input v-model="patient.phone" placeholder="请输入手机号码" maxlength="11"
                                    class="input v-input" />
                            </el-form-item>
                        </el-form>
                    </div>
                    <div class="sub-title">
                        <div class="block"></div>
                        建档信息(完善后部分医院首次就诊不排队建档)
                    </div>
                    <div class="content-wrapper">
                        <el-form :model="patient" label-width="110px" label-position="left" ref="patient"
                            :rules="validateRules">
                            <el-form-item prop="isMarry" label="婚姻状况:">
                                <el-radio-group v-model="patient.isMarry">
                                    <el-radio :label="0">未婚</el-radio>
                                    <el-radio :label="1">已婚</el-radio>
                                </el-radio-group>
                            </el-form-item>
                            <el-form-item prop="isInsure" label="自费/医保:">
                                <el-radio-group v-model="patient.isInsure">
                                    <el-radio :label="0">自费</el-radio>
                                    <el-radio :label="1">医保</el-radio>
                                </el-radio-group>
                            </el-form-item>
                            <el-form-item prop="addressSelected" label="当前住址:">
                                <el-cascader ref="selectedShow" v-model="patient.addressSelected" class="v-address"
                                    :props="props"></el-cascader>
                            </el-form-item>
                            <el-form-item prop="address" label="详细地址:">
                                <el-input v-model="patient.address" placeholder="应公安机关要求,请填写现真实住址"
                                    class="input v-input" />
                            </el-form-item>
                        </el-form>
                    </div>
                    <div class="sub-title">
                        <div class="block"></div>
                        联系人信息(选填)
                    </div>
                    <div class="content-wrapper">
                        <el-form :model="patient" label-width="110px" label-position="left">
                            <el-form-item prop="contactsName" label="姓名:">
                                <el-input v-model="patient.contactsName" placeholder="请输入联系人姓名全称"
                                    class="input v-input" />
                            </el-form-item>
                            <el-form-item prop="contactsCertificatesType" label="证件类型:">
                                <el-select v-model="patient.contactsCertificatesType" placeholder="请选择证件类型"
                                    class="v-select patient-select">
                                    <el-option v-for="item in certificatesTypeList" :key="item.value" :label="item.name"
                                        :value="item.value">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item prop="contactsCertificatesNo" label="证件号码:">
                                <el-input v-model="patient.contactsCertificatesNo" placeholder="请输入联系人证件号码"
                                    class="input v-input" />
                            </el-form-item>
                            <el-form-item prop="contactsPhone" label="手机号码:">
                                <el-input v-model="patient.contactsPhone" placeholder="请输入联系人手机号码"
                                    class="input v-input" />
                            </el-form-item>
                        </el-form>
                    </div>
                </div>
                <div class="bottom-wrapper">
                    <div class="button-wrapper">
                        <div class="v-button" @click="saveOrUpdate()">{{ submitBnt }}</div>
                    </div>
                </div>
            </div>
        </div>
        <!-- 右侧内容 #end -->
    </div>
    <!-- footer -->
</template>

refs,element 唯一标签,用于获取指定元素

3. 实现JS、添加CSS

<script>
    import '~/assets/css/hospital_personal.css'
    import '~/assets/css/hospital.css'
    import '~/assets/css/personal.css'

    import dictApi from '@/api/dict'
    import patientApi from '@/api/patient'

    const defaultForm = {
        name: '',
        certificatesType: '',
        certificatesNo: '',
        sex: 1,
        birthdate: '',
        phone: '',
        isMarry: 0,
        isInsure: 0,
        provinceCode: '',
        cityCode: '',
        districtCode: '',
        addressSelected: null,
        address: '',
        contactsName: '',
        contactsCertificatesType: '',
        contactsCertificatesNo: '',
        contactsPhone: '',
        param: {}
    }
    export default {
        data() {
            return {
                patient: defaultForm,
                certificatesTypeList: [],
                props: {
                    lazy: true,
                    async lazyLoad(node, resolve) {
                        const { level } = node
                        //异步获取省市区
                        dictApi.findChildData(level ? node.value : '86').then(response => {
                            let list = response.data.list
                            let provinceList = list.map((item, i) => {
                                return {
                                    value: item.id,
                                    label: item.name,
                                    leaf: node.level == 2 ? true : false,//可控制显示几级
                                }
                            })
                            resolve && resolve(provinceList)
                        })
                    }
                },
                submitBnt: '保存',
                validateRules: {
                    name: [{ required: true, trigger: 'blur', message: '必须输入' }],
                    certificatesType: [{ required: true, trigger: 'blur', message: '必须输入' }],
                    certificatesNo: [{ required: true, trigger: 'blur', message: '必须输入' }],
                    birthdate: [{ required: true, trigger: 'blur', message: '必须输入' }],
                    phone: [{ required: true, trigger: 'blur', message: '必须输入' }],
                    addressSelected: [{ required: true, trigger: 'blur', message: '必须输入' }],
                    address: [{ required: true, trigger: 'blur', message: '必须输入' }]
                }
            }
        },
        created() {
            //初始化方法
            this.init();
        },
        mounted() {
            //判断新增还是修改,新增没有id传参
            if (this.$route.query.id) {
                //如果修改,回显下拉列选
                setTimeout(() => {
                    this.$refs.selectedShow.presentText
                        = this.patient.param.provinceString
                        + '/' + this.patient.param.cityString
                        + '/' + this.patient.param.districtString //"北京市/市辖区/西城区";// 首次手动复制
                    // this.$refs.selectedShow.value = '110000/110100/110102';
                }, 1000)//延迟执行,等待页面加载完成
            }
        },
        methods: {
            //初始化方法 判断修改还是新增
            init() {
                if (this.$route.query.id) {
                    //修改
                    const id = this.$route.query.id
                    this.fetchDataById(id)
                } else {
                    //新增
                    // 对象拓展运算符:拷贝对象,而不是赋值对象的引用
                    this.patient = { ...defaultForm }
                }
                this.getDict()
            },
            //修改的数据回显
            fetchDataById(id) {
                patientApi.getById(id).then(response => {
                    this.patient = response.data.patient
                    //添加默认值  this.$refs.selectedShow.value = '110000/110100/110102';
                    this.patient.addressSelected = [
                        this.patient.provinceCode,
                        this.patient.cityCode,
                        this.patient.districtCode]
                })
            },
            //查询数据字典,进行翻译
            getDict() {
                dictApi.findByDictCode("CertificatesType").then(response => {
                    this.certificatesTypeList = response.data.list
                })
            },
            //新增或者修改
            saveOrUpdate() {
                this.$refs.patient.validate(valid => {
                    if (valid) {
                        //地址处理
                        if (this.patient.addressSelected.length == 3) {
                            this.patient.provinceCode = this.patient.addressSelected[0]
                            this.patient.cityCode = this.patient.addressSelected[1]
                            this.patient.districtCode = this.patient.addressSelected[2]
                        }
                        if (!this.patient.id) {
                            this.saveData()
                        } else {
                            this.updateData()
                        }
                    }
                })
            },
            // 新增
            saveData() {
                if (this.submitBnt == '正在提交...') {
                    this.$message.info('重复提交')
                    return
                }
                this.submitBnt = '正在提交...'
                patientApi.save(this.patient).then(response => {
                    this.$message.success("提交成功")
                    //跳转回列表页面
                    window.location.href = '/patient'
                }).catch(e => {
                    this.submitBnt = '保存'
                })
            },
            // 根据id更新记录
            updateData() {
                if (this.submitBnt == '正在提交...') {
                    this.$message.info('重复提交')
                    return
                }
                this.submitBnt = '正在提交...'
                patientApi.updateById(this.patient).then(response => {
                    this.$message.success("提交成功")
                    window.location.href = '/patient'
                }).catch(e => {
                    this.submitBnt = '保存'
                })
            }
        }
    }
</script>
<style>
    .header-wrapper .title {
        font-size: 16px;
        margin-top: 0;
    }

    .sub-title {
        margin-top: 0;
    }

    .bottom-wrapper {
        padding: 0;
        margin: 0;
    }

    .bottom-wrapper .button-wrapper {
        margin-top: 0;
    }
</style>

3、就诊人详情与删除

1. 确认入口


2. 创建patient/show.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='/user'">实名认证 </span>
            </div>
            <div class="nav-item ">
                <span class="v-link clickable dark" onclick="javascript:window.location='/order'"> 挂号订单 </span>
            </div>
            <div class="nav-item selected">
                <span class="v-link selected dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </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="personal-patient">
                <div class="title" style="margin-top: 0px;font-size: 16px;"> 就诊人详情</div>
                <div>
                    <div class="sub-title">
                        <div class="block"></div>
                        就诊人信息
                    </div>
                    <div class="content-wrapper">
                        <el-form :model="patient" label-width="110px" label-position="left">
                            <el-form-item label="姓名:">
                                <div class=""><span>{{ patient.name }}</span></div>
                            </el-form-item>
                            <el-form-item label="证件类型:">
                                <div class=""><span>{{ patient.param.certificatesTypeString }}</span></div>
                            </el-form-item>
                            <el-form-item label="证件号码:">
                                <div class=""><span>{{ patient.certificatesNo }} </span></div>
                            </el-form-item>
                            <el-form-item label="性别:">
                                <div class=""><span>{{ patient.sex == 1 ? '男' : '女' }} </span></div>
                            </el-form-item>
                            <el-form-item label="出生日期:">
                                <div class=""><span>{{ patient.birthdate }} </span></div>
                            </el-form-item>
                            <el-form-item label="手机号码:">
                                <div class=""><span>{{ patient.phone }} </span></div>
                            </el-form-item>
                            <el-form-item label="婚姻状况:">
                                <div class=""><span>{{ patient.isMarry == 1 ? '已婚' : '未婚' }} </span></div>
                            </el-form-item>
                            <el-form-item label="当前住址:">
                                <div class=""><span>{{ patient.param.provinceString }}/{{ patient.param.cityString }}/{{
                                        patient.param.districtString }} </span></div>
                            </el-form-item>
                            <el-form-item label="详细地址:">
                                <div class=""><span>{{ patient.address }} </span></div>
                            </el-form-item>
                            <br />
                            <el-form-item>
                                <el-button class="v-button" type="primary" @click="remove()">删除就诊人</el-button>
                                <el-button class="v-button" type="primary white" @click="edit()">修改就诊人</el-button>
                            </el-form-item>
                        </el-form>
                    </div>
                </div>
            </div>
        </div><!-- 右侧内容 #end -->
    </div><!-- footer -->
</template>

3. JS、CSS实现,确认API接口方法

<script>
    import '~/assets/css/hospital_personal.css'
    import '~/assets/css/hospital.css'
    import '~/assets/css/personal.css'

    import patientApi from '@/api/patient'
    export default {
        data() {
            return {
                patient: {
                    param: {}
                }
            }
        },
        created() {
            this.fetchDataById();
        },
        methods: {
            fetchDataById() {
                patientApi.getById(this.$route.query.id).then(response => {
                    this.patient = response.data.patient
                })
            },
            remove() {
                patientApi.removeById(this.patient.id).then(response => {
                    this.$message.success('删除成功')
                    window.location.href = '/patient'
                })
            },
            edit() {
                window.location.href = '/patient/add?id=' + this.patient.id
            }
        }
    }
</script>
<style>
    .info-wrapper {
        padding-left: 0;
        padding-top: 0;
    }

    .content-wrapper {
        color: #333;
        font-size: 14px;
        padding-bottom: 0;
    }

    .el-form-item {
        margin-bottom: 5px;
    }

    .bottom-wrapper {
        width: 100%;
    }

    .button-wrapper {
        margin: 0;
    }

    .bottom-wrapper .button-wrapper {
        margin-top: 0;
    }
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值