环境
node
npm
yarn(取代npm)
node安装(自带npm):https://www.cnblogs.com/mumusen/p/9760732.html
yarn安装:https://www.cnblogs.com/mumusen/p/9760732.html
技术栈
vue
vue-router
vuex
antd pro :https://pro.loacg.com/docs/getting-started
springboot(kotlin)
登录
https://www.jianshu.com/p/ffe2790578fe
vue.ls
一个vue封装的本地储存的方法
https://www.jianshu.com/p/ab7f67878279
vue.config.js
https://www.jianshu.com/p/b358a91bdf2d
验证码
- 前端请求验证码:生成一个unique传递给后端
- 后端画图生成验证码,返回给前端:将{unique: versifycode }使用redis缓存
- 前端请求验证 :带着unique跟输入的verifyCode
- 后端验证:根据unique获取verifyCode,比对
antd pro访问本地springboot服务
禁用mock
Main.js中注释掉 import ‘./mock’
设置query的url ,为springboot的server地址
env.development:
1
2
3NODE_ENV=development
VUE_APP_PREVIEW=false
VUE_APP_API_BASE_URL=http://localhost:8082
修改vue.config.js
1 | devServer: { |
此时因为跨域问题会报错:
has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
后端登录逻辑
参见开发文档
正式环境配置
后端:
- mysql(使用lszy小程序的,需要导入admin_api相关的table)oss备份
- redis(使用lszy小程序的,暂时没有需要处理的)
- jenkins : 新建task(拉取代码之后,使用maven构建生成jar包,之后在容器中运行该jar包)
- 后端容器:运行服务端程序(jar)
- nginx代理(使用lszy小程序的,增加admin_api的代理)
前端:
- Node:尝试新建node镜像跟容器,完成前端项目构建
- dockerFile(nodejs,yarn)
- 启动镜像,设置挂载
- 启动之后自动执行打包命令
- nginx代理:使用lszy小程序的,增加admin_web的代理
- nginx server(前端容器):部署admin_web
- jenkins:新建task(拉取代码之后使用node容器构建,之后部署到nginx server容器)
jenkins 关联git
数据库8.0连接问题
分页(mybatis)
定义mapper
1
2
3
4
5
6
7
8
9
10
11interface UserMapper {
fun list(start: Int, pageSize: Int, phone: String?,
startTime: String?, endTime: String?, nick_name: String?,
gender: Int = 0, grade: Int = 0, provinceId: Int = 0,
cityId: Int = 0, countyId: Int = 0, schoolId: Int = 0): List<User>?
fun count(phone: String?,
startTime: String?, endTime: String?, nick_name: String?,
gender: Int = 0, grade: Int = 0, provinceId: Int = 0,
cityId: Int = 0, countyId: Int = 0, schoolId: Int = 0): Int
}定义xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.lingshiedu.lszyAdmin.mapper.UserMapper">
<select id="list" resultType="com.lingshiedu.lszyAdmin.model.User">
select
ls_user.id,
ls_user.nick_name,
ls_user.phone,
ls_user.province_id,
ls_user.city_id,
ls_user.county_id,
ls_user.school_id,
ls_user.grade_id,
ls_user.state,
ls_schools.name as school_name,
ls_user.gender,
ls_user.adv_score,
ls_user.occurrence_Time
from ls_user
INNER JOIN ls_schools ON ls_user.school_id = ls_schools.id
<where>
<if test="phone != null">
AND phone=#{phone}
</if>
<if test="nick_name != null">
AND nick_name LIKE CONCAT('%', #{nick_name}, '%')
</if>
<if test="gender != 0">
AND gender=#{gender}
</if>
<if test="grade != 0">
AND grade_id=#{grade}
</if>
<if test="startTime!=null and endTime!=null ">
occurrence_Time BETWEEN #{startTime} and #{endTime}
</if>
<if test="provinceId != 0">
AND province_id = #{provinceId}
</if>
<if test="cityId != 0">
AND city_id = #{cityId}
</if>
<if test="countyId != 0">
AND county_id = #{countyId}
</if>
<if test="schoolId != 0">
AND school_id = #{schoolId}
</if>
</where>
order by ls_user.occurrence_Time
LIMIT #{start},
#{pageSize}
</select>
<select id="count" resultType="int">
select
COUNT(*)
from ls_user
INNER JOIN ls_schools ON ls_user.school_id = ls_schools.id
<where>
<if test="phone != null">
AND phone=#{phone}
</if>
<if test="nick_name != null">
AND nick_name LIKE CONCAT('%', #{nick_name}, '%')
</if>
<if test="gender != 0">
AND gender=#{gender}
</if>
<if test="grade != 0">
AND grade_id=#{grade}
</if>
<if test="startTime!=null and endTime!=null ">
occurrence_Time BETWEEN #{startTime} and #{endTime}
</if>
<if test="provinceId != 0">
AND province_id = #{provinceId}
</if>
<if test="cityId != 0">
AND city_id = #{cityId}
</if>
<if test="countyId != 0">
AND county_id = #{countyId}
</if>
<if test="schoolId != 0">
AND school_id = #{schoolId}
</if>
</where>
</select>
</mapper>
nginx命令
nginx -s reopen #重启Nginx
nginx -s reload #重新加载Nginx配置文件,然后以优雅的方式重启Nginx
nginx -s stop #强制停止Nginx服务
nginx -s quit #优雅地停止Nginx服务(即处理完所有请求后再停止服务)
nginx -t #检测配置文件是否有语法错误,然后退出
nginx -?,-h #打开帮助信息
nginx -v #显示版本信息并退出
nginx -V #显示版本和配置选项信息,然后退出
nginx -t #检测配置文件是否有语法错误,然后退出
nginx -T #检测配置文件是否有语法错误,转储并退出
nginx -q #在检测配置文件期间屏蔽非错误信息
nginx -p prefix #设置前缀路径(默认是:/usr/share/nginx/)
nginx -c filename #设置配置文件(默认是:/etc/nginx/nginx.conf)
nginx -g directives #设置配置文件外的全局指令
killall nginx #杀死所有nginx进程
docker nginx 挂载nginx.conf文件不同步问题:
dockerfile 传参(区分正式环境跟测试环境)
arg:build过程(构建镜像过程)
- env:run过程(容器启动之后)
1 | FROM node:13.11.0 |
1 | arg设置为build(正式环境) |
后台管理员以及权限
antdesign流程:
main.js中引入router模块并设置基础路由
1
2
3
4export default new Router({
...
routes: constantRouterMap
})permission.js中添加router拦截器
- 如果有token(token使用vue.ls存放在本地)
1. 如果路由目的地是login,那么重定向到defaultPage 2. 否则,如果可达的页面为空,那么调用store中的GetAdminUserInfo,成功之后先修改store中的pages信息之后调用store中的GenerateRoutes根据服务端返回的数据更新路由。路由更新完毕之后根据路由跳转
- 如果没有token,那么跳转登录页面(在免登录名单中的不用登录)
具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar
to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`))
if (Vue.ls.get(ACCESS_TOKEN)) {
/* has token */
if (to.path === '/admin/login') {
next({ path: defaultRoutePath })
NProgress.done()
} else {
if (store.getters.pages.length === 0) {
store
.dispatch('GetAdminUserInfo')
.then(res => {
const pages = res.data.pages
store.dispatch('GenerateRoutes', { pages }).then(() => {
// 根据roles权限生成可访问的路由表
// 动态添加可访问路由表
router.addRoutes(store.getters.addRouters)
// 请求带有 redirect 重定向时,登录自动重定向到该地址
const redirect = decodeURIComponent(from.query.redirect || to.path)
if (to.path === redirect) {
// hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
next({ ...to, replace: true })
} else {
// 跳转到目的路由
next({ path: redirect })
}
})
})
} else {
next()
}
}
} else {
if (whiteList.includes(to.name)) {
// 在免登录白名单,直接进入
next()
} else {
next({ path: '/admin/login', query: { redirect: to.fullPath } })
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
})- 如果有token(token使用vue.ls存放在本地)
vue中ref使用(跟子组件通信+emit)
https://www.jianshu.com/p/623c8b009a85
后端日志(log4j2)
https://www.cnblogs.com/LemonFive/p/10737658.html
登陆服务器快捷方式
客户端
打开~/.ssh,如果没有则创建文件夹
执行ssh-keygen -t rsa
Enter file in which to save the key:输入保存私钥的文件名称(id_rsa_host)
Enter passphrase (empty for no passphrase): (可以不写)
Enter same passphrase again:(可以不写)
此时会生成:id_rsa_host文件
ssh-add ~/.ssh/id_rsa_host,通过私钥创建公钥
此时会生成:id_rsa_host.pub文件
服务端
打开~/.ssh,如果没有则创建文件夹
打开authorized_keys,将客户端第3步生成的文件中的公钥保存到此文件中,如果有多个则,换行处理
快捷连接设置
在客户端,~/.ssh下创建config文件
内容如下
Host dev
HostName hostIp
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_host
User username
完成,测试
ssh dev
回车即可