目录
一、阿里云对象存储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>