加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
readme.md~ 15.68 KB
一键复制 编辑 原始数据 按行查看 历史
LucasBelieve 提交于 2021-09-23 15:07 . 增加云效使用说明
# feignGET转为了POST
https://blog.csdn.net/qq_34129814/article/details/107935091
## 流程图的画法
https://zhuanlan.zhihu.com/p/67533900
## vue脚手架SPA项目的登录页面分离及登录拦截实现
vue-router跳转及登录问题
需求:
- 项目启动时的进入登录页,无导航条 https://www.jianshu.com/p/6f40ec034c5a
- 登录成功后自动跳转到首页 https://blog.csdn.net/qq_30114149/article/details/78416457
- 如果没有登录不论输入任何路径都跳转到登录页
需要用到的知识点:
- 子路由 children)
- 编程跳转页面(this.$router.push()
- 路由守卫(router.beforeEach())
App.vue只放router-view
```vue
<template>
<div id="app">
<router-view />
</div>
</template>
```
路由配置里默认跳转到 /login 1)处
```javascript
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Product from '../views/Product.vue'
import Login from '@/views/Login.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
//(1)
redirect:'/login'
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/home',
name: 'Home',
component: Home,
//(2) 设置子路由
children:[
{
path: '/product',
name: 'Product',
component: Product
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
},
]
const router = new VueRouter({
routes
})
export default router
```
编写登录逻辑,登录成功后在localStorage中存储一个登录标记,并跳转,
```vue
<template>
<form>
<h2>登录</h2>
<input type='button' @click='login' value='登录'>
</form>
</template>
<script>
export default {
name:"Login",
methods:{
login(){
//登录成功后设置一个标记
//localStorage是一个htmlapi,可以在本地存储信息
localStorage.setItem("isLogin",true);
this.$message.success('登录成功');
this.$router.push('/home')
}
}
}
</script>
```
Home页面存在一个子路由,有router-view,配置见上面路由配置(2)处
```
<template>
<div class="home">
<el-menu router :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="/home">首页</el-menu-item>
<el-menu-item index="/about">关于</el-menu-item>
<el-menu-item index="/product">商品</el-menu-item>
<el-menu-item @click='logout'>登出</el-menu-item>
</el-menu>
<el-main>
<router-view />
<HelloWorld/>
</el-main>
</div>
</template>
<script>
// @ <=> /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
data(){
return {
activeIndex:'/home',
}
},
components: {
HelloWorld
},
methods:{
logout(){
//登出操作:1)清理登录标记 2) 跳转到login
localStorage.setItem('isLogin',false);
this.$router.push('/login');
},
handleSelect(){}
}
}
</script>
没有登录不能访问的逻辑在main.js中,使用的是vue-router的导航守卫功能
//路由守卫,在跳转前检查是否登录,如果没有登录则跳转到登录
//详见 https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
router.beforeEach((to, from, next) => {
let isAuthenticated = localStorage.getItem('isLogin')=='true';
console.log(to.path !== '/login' && !isAuthenticated)
if (to.path !== '/login' && !isAuthenticated) {
alert('您还没有登录,请先登录');
console.log('未登录,跳转登录页')
next({
path:'/login'
})
} else {
next()
}
});
```
具体代码请见 [vue-login](vue-login)
## ElementUI上传多个文件的DEMO
代码在:
front 是前端项目 代码在HelloWorld.vue
src 是后端代码 主要是controller中的UploadController
运作模式是,前端默认会自动上传到action指定的路径,成功后回调on-success指定的函数
源码参考 [multi-files-upload](multi-files-upload)
前端:[HelloWorld.vue](multi-files-upload/front/src/components/HelloWorld.vue)
后端:[UploadController](multi-files-upload/src/main/java/com/woniuxy/multifilesupload/controller/UploadController.java)
## 发送任意短信内容
国内短信有内容限制,可以使用国外的[twilio](https://twilio.com)试用(可以发大概50条短信),缺点是界面全英文
1. 参考 http://uuxn.com/twilio-toll-free-sms 注册账号
2. 试用模式下,twilio只能给验证过的手机号发短信,比如你自己的,在页面右端有个 [verified numbers](https://www.twilio.com/console/phone-numbers/verified). 的链接,点击可以添加手机号,添加时会发验证码验证
3. 以下是封装的工具类,请注意替换关键信息
```java
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
/**
*
* 使用twilio发送短信
*/
public class SmsUtil {
// 从这里 twilio.com/user/account 找以下内容
public static final String ACCOUNT_SID = "你的SID";
public static final String AUTH_TOKEN = "你的验证token";
//twilio的个人页面上获取的trail number +12077460991
public static final String TRIAL_PHONE_NUMBER="你的试用手机号";
public void send(String to,String text){
Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Message message = Message.creator(new PhoneNumber(to),
new PhoneNumber(TRIAL_PHONE_NUMBER),
text).create();
}
}
```
## controller层打印日志
参考[WebLogAspect.java](./WebLogAspect.java) ,代码依赖于AOP所以使用时需要
1)在pom中加入
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
```
2)在Application启动类上加注解`@EnableAspectJAutoProxy`
## 跨域访问时session失效
前后端分离后,前端和后端运行在不同的域(ip+端口不同,生产是域名不同)下,而 浏览器因为安全限制无法获得跨域的cookie
临时解决方案,前后端设置放行跨域cookie;真正的解决方案是通过JWT保持登录信息,session中保存的信息放到redis中;
临时解决方案具体做法:
1. 前端:每次ajax请求时设置一个`withCredentials` 的头,axios用法
```javascript
send2() {
axios.defaults.withCredentials = true;//☆这句设置头
//发送请求
axios.get("http://localhost:8080/testSession2")
.then(resp => {
console.log(resp);
this.remoteValue=resp.data.data;
}).catch(err => {
console.log(err);
})
}
```
2. 后端:新建一个webmvc配置类,配置cors跨域配置
```java
package com.woniuxy.sessiontest.config;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowedMethods("POST","GET")
.allowCredentials(true)
.allowedOrigins("*");
}
}
```
3.此外,需要关闭chrome的一些特性
注意,chrome版本80之后默认开启了sameSite属性,导致cookie仍然无法获取,测试环境下建议:
chrome://flags/
下的 SameSite by default cookies 设置为Disabled
Cookies without SameSite must be secure 设置为Disabled
源码参考:
前端:[Home.vue](sessiontest/sessiontest-front/src/views/Home.vue)
后端参考:[WebConfig.java](sessiontest/src/main/java/com/woniuxy/sessiontest/config/WebConfig.java)
参考: https://www.jianshu.com/p/13d53acc124f
## 好用的工具类推荐
hutool: https://gitee.com/loolly/hutool [文档]( https://www.hutool.cn/docs/index.html#/ )
guava: http://ifeve.com/google-guava/
apache-commons: https://blog.csdn.net/leaderway/article/details/52387925
## maven私服使用方式
参见:[maven私服使用方式](./maven-private-repo.md)
## Excel文件导出使用哪个库?
POI支持比较全
JXL比较简便好用,建议使用JXL
## uniapp支付宝SDK支付失败问题
支付宝的沙箱账号不支持在sdk支付,uniapp无法突破
可以使用这个插件
https://ext.dcloud.net.cn/plugin?id=1728
## Jackson日期时间少了几个小时问题
jackson反序列化是默认使用的是默认时区,
```java
public final static String DEFAULT_TIMEZONE = "##default";
```
解决方案,
可以在每个字段加
```java
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
```
但太累了,建议在application.properties中配置一下,全局有效,不需要每个字段配置@DateTimeFormat
spring.jackson.date-format=yyyy-MM-dd HH:mm
spring.jackson.time-zone=GMT+8
## 根据视频教程,访问elasticsearch时报类型错误
因为视频教程使用的es版本与 最新的spring-boot-starter-data-elasticsearch版本不一致。降低版本实现。
```xml
<properties>
<java.version>1.8</java.version>
<!-- 覆盖父pom变量-->
<elasticsearch.version>6.8.4</elasticsearch.version>
</properties>
<dependencies>
<!-- 直接添加依赖,覆盖父pom里版本-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
....
```
## vuepost请求参数,后端获取不到问题
因为vueaxios默认发送的是json格式,可以有两个方式解决,
1)在接受时使用 对参数使用 @RequestBody 提供一个对象接受所有参数
2)在发送的js代码中使用 qs 序列化一下
https://blog.csdn.net/weixin_41829196/article/details/85986331
### 移动端API请求在服务端无法得到用户信息
现象:登录后,App发送的请求,Controller处理时,从shirosubject得到Usernull
错误原因:app无法存储cookie,无法提供sessionId,服务端的session关联不到,直接出错。
解决方案:使用JWT登录成功后返回token,在APP端存储下来(uniapp有存储的[API](https://uniapp.dcloud.io/api/storage/storage?id=setstorage)
参考:https://learnku.com/articles/43682
## 数据库设计注意点
1. 一对多或者多对一,关联存在多一方;多对多建关联表。
2. 一对一考虑能不能合并,根据业务判断;
3. 适当冗余,例如购物车可以冗余商品图片和名字,不用再关联查询商品表
4. 考虑加索引
5. 考虑支付退款等资金流程的表设计
6. 考虑接入各种API时的数据异常处理,比如,通知结果存储,操作失败后的重试等
## 验证码
免费体验2万次验证量 https://open.captcha.qq.com/product.html?ADTAG=capt.head
## 客服机器人
https://cloud.tencent.com/solution/service
## 微信开发
微信开发SDK https://github.com/foxinmy/weixin4j
## 内容审核
https://www.qiniu.com/products/censor
## 全文搜索
推荐[elasticsearch](https://www.elastic.co/cn/) 数据同步用logstash
## 图片上传
场景:上传头像,然后在页面上显示出来
问题:上传到哪个位置?如何在页面上显示出来?
错误解决方案:上传到项目目录下,直接可以显示。问题在于部署环节,项目文件会覆盖,比如第一次部署过后,上传数据在该项目文件夹下,第二次部署时覆盖,则之前上传的数据丢失了。
正解:
1. <del>使用图床,直接上传到公开的图床,比如https://sm.ms</del>
2. 使用Nginx,将图片上传至某个目录(如,d://upload/),然后通过Nginx将该目录代理成网络路径,直接可以通过完整的路径访问该图片,假设ng运行在8000端口,图片名为abc.jpg,则经过配置,可以使用http://localhost:8000/abc.jpg访问到这张图片
3. 使用oss服务器,<del>专门用来存储小对象的,不过貌似得花钱,[参看阿里云](https://cn.aliyun.com/product/oss)</del> 比如七牛云(免费每月10G流量)
具体参看:[七牛云上传文件](./qiniu.md) ,例子参看[demo](./devsuggestions)
[注册链接](https://portal.qiniu.com/signup?code=1h5npa9r5az4i)
## 分布式定时任务 详细请参考[定时任务章节](./定时任务.md)
方案1.
spring提供的定时任务注解,操作简单,参考[文章](http://www.ityouknow.com/springboot/2016/12/02/spring-boot-scheduler.html)
优势:集成简单
缺陷: 分布式环境下会出现并发问题,重复执行,比如同一个应用部署了两台机器时,会出现同时在800执行一个定时任务,那么就会执行两次定时,这时就需要调度。粗糙的解决方案是加锁,同时只允许一个执行,代码再进行一个状态判断,就不会造成反复执行,可以使用redis或者数据库都可以加锁。
方案2.
较为简单的场景,比如订单过期取消,可以使用rabbitmq的死信队列实现,[参考文章](https://www.jianshu.com/p/986ee5eb78bc)
或者 使用redis[key过期事件驱动](https://www.cnblogs.com/owenma/p/10419896.html)
优势:实现较为简单
缺陷:应用场景有限
方案3.
xxl分布式定时任务中间件 [仓库地址](https://gitee.com/xuxueli0323/xxl-job) 细节待研究
优势:生产级,成熟,功能丰富
缺陷:需要独立部署,有一定学习成本
## 推送
uniapppush功能
```
1. 开通个推、各厂商推送,获得id等配置信息
2. 开通unipush https://ask.dcloud.net.cn/article/35622
3. 服务端推给个推
http://docs.getui.com/getui/server/java/summary/
https://www.dcloud.io/docs/a/unipush/java.pdf
4. 客户端接入 https://ask.dcloud.net.cn/article/35726
```
## 即时聊天
方案1.websocket或者轮询 手动实现,UI可以参考[这个uniapp模板](https://ext.dcloud.net.cn/plugin?id=324)
缺陷:所有功能手动实现,很多细节处理不好
方案2.环信IM等第三方即时通信服务(李丰弟在尝试集成,已经完成接入)
缺陷:初期学习成本较高
## 提交多个参数
提交的参数是一个集合,比如一天安排多个景点,则景点名字相同,都需要提交到后台。
参考 https://gitee.com/maizdotme/dev-suggestions/blob/master/devsuggestions/src/main/resources/static/batchAdd.html
解决方案
1.使用[]语法,springMVC会自动映射,参考 https://blog.csdn.net/u011781521/article/details/77586688
2.使用json传递数据,springMVC通过@RequestBody自动映射 参考https://blog.csdn.net/achenyuan/article/details/81114517
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化