基于SpringBoot+shiro+Vue前后端完全分离的简易教务系统
实战—基于SpringBoot+shiro+Vue前后端完全分离的简易教务系统总体流程 (1)需求分析
(2)系统设计
(3)功能开发
(4)项目部署
(5)总结
技术选型与工具技术选型
前端:Vue 、 Element UI 、 Vue router 、 Vuex 、axios
后端:SpringBoot 、Mybatis plus 、 shiro
数据库:MySQL
版本管理:git
项目管理:Maven
工具
集成开发环境:IDEA
数据库操作工具:Navicat
服务器操作工具:Xshell 7、Xftp 7
需求分析
数据库设计概念设计
逻辑设计
课程(课程id、课程代码、课程名称、课程类别、学院id、教师id、是否为本学期课程、课程学期id、课程学期名、上课时间、上课地点、教学班号、学分、平时成绩占比、最终成绩占比)其中学院id、教师id为外键
用户(用户id、用户名、密码、盐值、姓名、学院id、性别、电话、班级)其中学院id为外键
角色(角色id、角色名称)
权限(权限id、权 ...
Shiro——安全权限框架
Shiro安全权限框架Shiro 简介简介
Apache Shiro 是Java的一个安全(权限)框架。
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。
Shiro 可以完成:认证、授权、加密、会话管理、与Web集成、缓存等。
下载:http://shiro.apache.org/
功能简介
Authentication:身份认证/登录,验证用户是不是拥有相应的身份。
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能进行什么操作,如:验证某个用户是否拥有某个角色,或者细粒度的验证某个用户对某个资源是否具有某个权限。
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE环境,也可以是Web环境的。
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储。
Web Support:Web支持,可以非常容易的集成到Web 环境。
Caching:缓存,比如用户登 ...
Maven知识详解
Maven 导言:生产环境下开发不再是一个项目一个工程,而是每一个模块创建一个工程,而多个模块整合在一起就需要使用到像 Maven 这样的构建工具。
Why真的需要吗 Maven 是干什么用的? 即使不使用 Maven 我们仍然可以进行 B/S 结构项目的开发。从表述层、业务逻辑层到持久化层再到数据库都有成熟的解决方案——不使用 Maven 我们一样可以开发项目啊?
这里给大家纠正一个误区,Maven 并不是直接用来辅助编码的,它战斗的岗位并不是以上各层。所以我们有必要通过企业开发中的实际需求来看一看哪些方面是我们现有技术的不足。
目前的技术在开发中存在的问题
一个项目就是一个工程
如果项目非常庞大,就不适合用package来划分模块。必须将项目拆分成多个工程协同开发。多个模块工程中有的是 Java 工程,有的是 Web 工程。所以,最好是每一个模块对应一个工程,利于分工协作。
项目中需要的jar包必须手动“复制”、“粘贴”到WEB/lib目录下
同样的jar包文件重复出现在不同的项目工程中,一方面浪 ...
L11-验证JS-SDK
L11-验证JS-SDK生成JS-SDK使用的签名1、创建一个Wechat实例对象
在wechat.js中抛出Wechat,暴露出来
在app.js中引入Wechat模块
2、index.js中添加url
3、生成JS-SDK使用的签名
a、组合参与签名的四个参数:jsapi_ticket(临时票据)、noncestr(随机字符串)、timestamp(时间戳)、url(当前服务器地址)
b、将其进行字典序排序,以”&”拼接在一起
c、进行sha1加密,最终生成signature
4、将签名渲染到界面上
使用JS-SDK1、绑定域名
在接口测试号页面上填写js安全域名接口
去掉http协议,将后面的内容配置进去
2、引入js文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/ ...
L10-获取JS-SDK
L10-获取JS-SDK获取JS-SDK1、用户访问服务器上一个节点时,我们返回一个页面给用户,需要设置一个路由
下载ejs,终端输入npm i ejs
配置模版资源目录(app.js)
app.set('views', './views');
配置模版引擎(app.js)
app.set('view engine', 'ejs');
新建一个views文件夹,里面新建一个search.html,改为search.ejs
页面路由
2、访问测试
运行app.js,在浏览器输入内网穿透过的地址(或者是映射到的本地端口号),后加“/search”
3、使用微信给我们提供的开发工具——JS-SDK
微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验 ...
L09-实现自定义菜单
L09-实现自定义菜单
自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单
一级菜单最多4个汉字,二级菜单最多8个汉字,多出来的部分将会以“…”代替
创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果
自定义菜单接口可实现多种类型按钮,如下:
接口调用请求说明:http请求方式:POST(请使用https协议)https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
click和view的请求示例:
返回结果
删除接口
使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单。另请注意,在个性化菜单时,调用此接口会删除默认菜单及全部个性化菜单。
请求说明:http请求方式:GET https://api.weixin.qq.com/cg ...
L08-定义模版文件并完整回复用户消息
L08-定义模版文件并完整回复用户消息1、定义回复用户消息的模版文件
在wechat文件夹里定义一个template.js的文件
我们可以把消息回复放在这里面,例如这么做:
但这样做,存在很多重复性的代码
我们可以将公共部分拿出去,然后进行字符串的拼接
最后记得在auth.js中引入该模块
2、新建一个reply.js模块,来处理用户发送发送的消息类型和内容,以决定返回不同的内容给用户
其余类型可自行查阅微信开发者文档进行查阅
3、关键要点!
options是一个对象
向reply中传入message对象,拿到里面的一些共有属性,判断完成后将content赋值给options里的content
接着将options传入template,使其转化为xml格式(回复的消息必须是xml格式),返回replyMessage
最后执行res.send(replyMessage);
4、测试
重启服务器,在测试号中发送1进行测试,结果如下:
L07-简单的自动回复
L07-简单的自动回复(回复文本消息,图片、语音、视频等其余类型类似)
当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。
一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:
A、开发者在5秒内未回复任何内容
B、开发者回复了异常数据,比如JSON数据等
1、编写简单的消息匹配回复
2、测试
重启服务器
在微信公众号里,发送1或者2进行测试,结果如下:
L06-获取用户发送的消息
L06-获取用户发送的消息1、精简auth.js
将以上代码转化为:
2、将signature比对放到GET请求下
3、POST请求下验证消息是否来自服务器
4、测试
重启服务器
打开接口测试号,发送一条消息,观察控制台是否打印消息
openid是用户微信的id,每个用户都不一样
如果开发者服务器没有返回响应为微信服务器,微信服务器会发送三次请求过来,可以先用res.end(‘’);返回(后续再删掉)
5、接受请求体中的数据(流式数据)
编写一个getUserDataAsync()方法
使用async函数来接收这个流式数据
6、测试接收结果
重启服务器
在测试号发送一条消息,观察控制台
<ToUserName>:开发者id
<FromUserName>:用户openid
<CreateTime>:发送的时间戳
<MsgType>:发送的消息类型
<Content>:发送的内容
<MsgId>:消息id ...
L05-FetchAccessToken方法
L05-FetchAccessToken方法1、用fetchAccessToken方法封装
2、使用async和await来处理异步问题,减少多次回调
await只有在async中才能使用
3、优化
将resolve(res);改写为return Promise.resolve(res);
目的:为了接下来可以继续写.then()
将access_token挂载到this上
另一个小优化