一、后端接口编写
1、需求分析
无非就是对医院模块的信息的增删改查
医院设置主要是用来保存开通医院的一些基本信息,每个医院一条信息,保存了医院编号(平台分配,全局唯一)和接口调用相关的签名key等信息,是整个流程的第一步,只有开通了医院设置信息,才可以上传医院相关信息。
我们所开发的功能就是基于单表的一个CRUD、锁定/解锁和发送签名信息这些基本功能。
2、数据库表的结构
hosname:医院名称
hoscode:医院编号(平台分配,全局唯一,api接口必填信息)
api_url:医院回调的基础url(如:预约下单,我们要调用该地址去医院下单)
sign_key:双方api接口调用的签名key,有平台生成
contacts_name:医院联系人姓名
contacts_phone:医院联系人手机
status:状态(锁定/解锁)
3、医院设置微服务模块开发
(1)搭建service_hops模块
首先在service模块下创建一个maven工程,名字为service_hosp,因为的service父模块为springboot工程,所以我们service_hops也为springboot工程(maven的依赖传递)
修改maven配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>service</artifactId>
<groupId>com.atdk</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0</version>
<artifactId>service_hosp</artifactId>
<packaging>jar</packaging>
<name>service_hosp</name>
</project>
(2)医院设置有关CURD操作
1、创建实体类
我们的所有的实体类全部建立在model模块下,进行统一的管理
2、创建mapper层接口
因为我们使用mybatis-plus 所以我们只需要我们mapper接口继承我们的BaseMapper接口即可
public interface HospitalSetMapper extends BaseMapper<HospitalSet> {
}
3、创建service层接口和实现类
同样因为我们使用了mybatis-plus,所以我们可以使用Mp提供的service操作,来完成我们操作,并且当我们使用Mp的service层操作时,我们在service接口实现类中继承ServiceImpl中把我们的mapper接口当做泛型传入,自动为我们注入了mapper接口,我们可以俺来直接使用。
具体操作如下(也可以自己手动写不使用mapper)
- 常见service层接口继承我们的mp提供的接口IService<HospitalSet>
public interface HospitalSetService extends IService<HospitalSet> {
}
- 编写我们的service接口实现类继承Mp提供的类ServiceImpl<mappe接口,实体类>
@Service
public class HospitalSetServiceImpl extends ServiceImpl<HospitalSetMapper, HospitalSet> implements HospitalSetService {
// 不需要我们手动注入mapper,mp自动帮我们注入mapper,直接调用baseMapper
}
4、创建Controller
返回json数据,使用我们的RestController注解
@Api(tags = "医院设置管理")
@RestController
@RequestMapping("/admin/hosp/hospitalSet")
// CrossOrigin 支持跨域请求
@CrossOrigin
public class HospitalSetController {
@Autowired
private HospitalSetService hospitalSetService;
}
(3)具体的业务逻辑
基本上我们可以直接调用我们Mp为我们提供号的sevice方法自动完成操作。
1、查询所有数据
/**
* 查询所有的医院设置信息
*
* @return
*/
@ApiOperation("查询所有医院设置信息")
@GetMapping("/findall")
public Result<List<HospitalSet>> findall() {
List<HospitalSet> list = hospitalSetService.list();
return Result.ok(list);
}
2、条件查询&分页查询
首先配置我们mp的分页插件
Vo类为我们的查询条件实现类,例如我们医院设置信息有两个查询条件,医院名字,医院名字,所以我们可以设置一个vo类,具有两个属性,来接收查询条件
步骤:
- 创建Page
- 构造查询条件
- 调用service查询分页数据对象
- 返回给前端
@ApiOperation("分页查询数据输入当前页,每页数量,输入查询条件")
@PostMapping("/findPage/{current}/{limit}")
public Result findPageHospSet(@PathVariable("current") long current,
@PathVariable("limit") long limit,
/**
* 获取查询的条件我们是通过JSON传输数据
* required = false表示此参数可以接收不到
*/
@RequestBody(required = false) HospitalSetQueryVo hospitalSetQueryVo) {
// 1、创键page对象,当前页,当前页面数据
Page<HospitalSet> hospitalSetPage = new Page<>(current, limit);
// 2、构造条件
QueryWrapper<HospitalSet> queryWrapper = new QueryWrapper();
// 2.1 医院名字模糊查询,编号精确查询
String hosname = hospitalSetQueryVo.getHosname();
String hoscode = hospitalSetQueryVo.getHoscode();
// 2.2 条件都不为空进行条件构造设置
if (!StringUtils.isEmpty(hosname)) {
queryWrapper.like("hosname", hospitalSetQueryVo.getHosname());
}
if (!StringUtils.isEmpty(hoscode)) {
queryWrapper.eq("hoscode", hospitalSetQueryVo.getHoscode());
}
// 3、调用service层获取分页数据
Page<HospitalSet> page = hospitalSetService.page(hospitalSetPage, queryWrapper);
return Result.ok(page);
}
3、更改状态
- 先更具更改的id查询出此id对应的数据
- 修改此数据的状态值
- 调用service层修改数据
@ApiOperation("医院锁定和解锁")
@PutMapping("/lockHospitalSet/{id}/{status}")
public Result lockHospitalSet(@PathVariable("id") Long id,
@PathVariable("status") Integer status) {
//根据id查询医院设置信息
HospitalSet hospitalSet = hospitalSetService.getById(id);
//设置状态
hospitalSet.setStatus(status);
//调用方法
hospitalSetService.updateById(hospitalSet);
return Result.ok();
}
二、前端搭建
前端使用开源项目vue-admin-template-master进行打造
vue-admin-template-master项目时vue项目,使用axios交互,使用npm构建项目,管理依赖,使用Node.js作为js运行环境
1、项目搭建
(1)项目名称
解压vue-admin-template-master.zip修改解压文件为yygh_admin
(2)修改项目的配置文件package.json
基本信息修改
{
"name": "yygh-admin",
"version": "3.8.0",
"license": "MIT",
"description": "尚医通管理平台系统",
"author": "493111402@qq.com",
...
}
如果我们需要修改部分依赖的版本号,或者是启动命令,可以在配置文件中继续修改。
(3)修改项目访问后端接口ip地址端口
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
// BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',
// 指定ip地址+端口号
BASE_API: '"http://localhost:8202"',
})
(4)修改我们项目启动的端口号
config下index.js 修改项目端口号(按需修改)
(5) 项目的目录结构
├── build // 构建脚本
├── config // 全局配置
├── node_modules // 项目依赖模块
├── src //项目源代码
├── static // 静态资源
└── package.jspon // 项目信息和依赖配置
src
├── api // 各种接口
├── assets // 图片等资源
├── components // 各种公共组件,非公共组件在各自view下维护
├── icons //svg icon
├── router // 路由表
├── store // 存储
├── styles // 各种样式
├── utils // 公共工具,非公共工具,在各自view下维护
├── views // 各种layout
├── App.vue //项目顶层组件
├── main.js //项目入口文件
└── permission.js //认证入口
(6)项目初次运行
执行命令npm install 安装我们项目依赖
执行命令npm run dev 启动项目
2、医院设置管理开发
(1)开发流程
(2) 定义医院信息设置的路由
医院设置路由有两个子路由,列表和添加,component意思是指定页面
{
path: '/hosPost',
component: Layout,
redirect: '/hosPost/list',
name: '医院设置管理',
meta: {title: '医院设置管理', icon: 'example'},
children: [
{
path: 'list',
name: '医院设置列表',
component: () => import('@/views/hospset/list'),
meta: {title: '医院设置列表', icon: 'table'}
},
{
path: 'add',
name: '医院设置添加',
component: () => import('@/views/hospset/add'),
meta: {title: '医院设置添加', icon: 'tree'},
},
(3)定义api
创建文件hospSet.js在api模块下,模仿示例写
import request from '@/utils/request'
// 调用医院后端设置接口
export default {
getHospSetList(current, limit, searchObj) {
return request({
// 后端服务接口
url: `/admin/hosp/hospitalSet/findPage/${current}/${limit}`,
method: 'post',
data: searchObj
})
}}
(4)定义页面脚本
js对象属性可以不写,在我们设置对象属性值的时候会把对象属性设置进去(因为进行双向数据绑定)
调用api方法,获取数据,或者完成对应的操作,
created中在页面渲染完成后完成操作。
<script>
import hospset from '@/api/hospset'
export default {
// 定义变量和参数
data() {
return {
current: 1,
limit: 3,
searchObj: {
// js对象属性可以不写,在我们设置对象属性值的时候会把对象属性设置进去
},
list: [],
multipleSelection: [], // 批量选择中选择的记录列表
total: 0
}
},
created() {
// 页面渲染获取数据
// 调用methods的方法获取数据
this.getList()
},
methods: {
// 复选框发生变化时调用的函数,获取选中的数据,vue-ui自动传递数据(selection代表选中的)
handleSelectionChange(selection) {
// 把选中的数据赋值给multipleSelection
// selection是我们选中数据的对象数组
this.multipleSelection = selection
// console.log(selection)
},
// 获取医院设置列表,请求接口,默认为第一页
getList(page = 1) {
this.current = page
// 发起ajax请求,接口请求地址我们在api中已经写好
hospset.getHospSetList(this.current, this.limit, this.searchObj)
.then(response => {
// 请求成功
console.log(response)
this.list = response.data.records
this.total = response.data.total
})
.catch(error => {
// 请求失败
console.log(error)
})
},
// 删除医院设置
removeDataById(id) {
// el-ui 指定写法
this.$confirm('此操作将永久删除医院是设置信息, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { // 确定执行then方法
// 调用接口
hospset.deleteHospSet(id)
.then(response => {
// 提示
this.$message({
type: 'success',
message: '删除成功!'
})
// 刷新页面
this.getList(1)
})
})
},
// 批量删除医院设置信息
removeRows() {
this.$confirm('此操作将永久删除医院是设置信息, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { // 确定执行then方法
var idList = []
// 遍历数组得到每个id值,设置到idList里面
for (let i = 0; i < this.multipleSelection.length; i++) {
// push保存数据到数组中
idList.push(this.multipleSelection[i].id)
}
// 调用接口
hospset.batchRemoveHospSet(idList)
.then(response => {
// 提示
this.$message({
type: 'success',
message: '删除成功!'
})
// 刷新页面
this.getList(1)
})
})
},
// 锁定信息,解锁
lockHostSet(id, status) {
hospset.lockOrUnLockHospSet(id, status)
.then(response => {
// 刷新数据,从新获取数据
this.getList()
})
}
}
}
</script>
三、跨域问题
解释
跨域:浏览器对于javascript的同源策略的限制 。
以下情况都属于跨域:域名不同,域名同,端口不同,二级域名不同
跨域原因说明 | 示例 |
---|---|
域名不同 | www.jd.com 与 www.taobao.com |
域名相同,端口不同 | www.jd.com:8080 与 www.jd.com:8081 |
二级域名不同 | item.jd.com 与 miaosha.jd.com |
如果域名和端口都相同,但是请求路径不同,不属于跨域,如:
www.jd.com/item
www.jd.com/goods
http和https也属于跨域
解决
spring跨域解决,在Controller加上一个注解@CrossOrgin即可解决问题