0616项目二结束~~总总结
时间:2023-11-05 00:37:01
宠物之家项目
1.三方登录(微信)
步骤梳理
1.向后端发送前端请求,后端接收授权码,重定向扫码页面
//后端获取授权码 重定向到微信登录二维码界面
@GetMapping("/jump")
public String getWechat(){
String codeUrl = wechatProperties.getAuthorizationCodeUrl();
String state = UUID.randomUUID().toString();
codeUrl = String.format(codeUrl, wechatProperties.getAppId(), wechatProperties.getRedirectUri(),state);
return "redirect:" codeUrl;
}
2.获取code
String tokenUrl = wechatProperties.getTokenUrl();
tokenUrl=String.format(tokenUrl,wechatProperties.getAppId(),
wechatProperties.getAppSecrect(),
code);
//2.1 发送微信请求
String result = HttpUtil.sendPost(tokenUrl, null);
System.out.println(result);
WechartTokenDto wechartTokenDto = JSONObject.parseObject(result, WechartTokenDto.class);
System.out.println(wechartTokenDto);
3.根据code换token
String userInfoUrl = wechatProperties.getUserinfoUrl();
//"https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"
userInfoUrl = String.format(userInfoUrl, wechartTokenDto.getAccess_token(), wechartTokenDto.getOpenid());
String userinfoResult = HttpUtil.sendPost(userInfoUrl, null);
WechatUserInfoDto wechatUserInfoDto = JSONObject.parseObject(userinfoResult, WechatUserInfoDto.class);
4.用token获取用户信息
6.存在页看userId是否存在跳转绑定页面
WechatUser wechatUser = wechatUserList.get(0);
Long userId = wechatUser.getUserId();
//如果是空的
if(userId==null){
//跳转到绑定页面
return "redirect:http://127.0.0.1:6002/binder.html?id=" wechatUser.getId();
}else{
LoginInfo login = loginInfoMapper.selectByPrimaryKey(userId);
String token = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(token, JSONObject.toJSONString(login), 30, TimeUnit.MINUTES);
//将结果返回到前端 用map
HashMap
&nbs; map.put("token", token);
map.put("userInfo", login);
//跳转到首页
String redirectUrl = "redirect:http://localhost:6002/index.html?userInfo=%s&token=%s";
redirectUrl = String.format(redirectUrl, login.getUsername(), token);
redirectUrl = StrUtil.cleanBlank(redirectUrl);
return redirectUrl;
}
}
}
return "redirect:http://127.0.0.1:6002/index.html";
5.判断是否存在数据库,不存在跳转绑定页面
//4.根据openid看wxuser表是否存在
Example example = new Example(WechatUser.class);
example.and().andEqualTo("openid",wechatUserInfoDto.getOpenid());
List
//看是否第一次登录
if(CollectionUtils.isEmpty(wechatUserList)){
//如果为空 说明第一次登录 先把数据信息存入表
WechatUser wechatUser = new WechatUser();
wechatUser.setHeadimgurl(wechatUserInfoDto.getHeadimgurl());
wechatUser.setOpenid(wechatUserInfoDto.getOpenid());
wechatUser.setNickname(wechatUserInfoDto.getNickname());
wechatUser.setUnionid(wechatUserInfoDto.getUnionid());
wechatUserMapper.insert(wechatUser);
//跳转到绑定页面
return "redirect:http://127.0.0.1:6002/binder.html?id="+wechatUser.getId();
微信参数实体类
@Data
@Component
@ConfigurationProperties("pethome.wechart")
public class WechatProperties {
private String authorizationCodeUrl;
private String userinfoUrl;
private String refreshTokenUrl;
private String appId;
private String appSecrect;
private String redirectUri;
private String tokenUrl;
}
yml配置
pethome:
wechart:
#获取授权码URL
authorization-code-url: "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect"
#获取Token的URL
token-url: "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
#获取用户信息 URL
userinfo-url: "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"
#刷新Token的 URL
refresh-token-url: "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"
# 应用ID
app-id: "wxd853562a0548a7d0"
# 应用秘钥
app-secrect: "4a5d5615f93f24bdba2ba8534642dbb6"
# 授权码回调接口,对应我们平台的controller
redirect-uri: "http://bugtracker.itsource.cn/wechat/callback"
2.三方支付(支付宝)
前置条件
1.拉起支付页面工具类
public JSONResult createPayUrl(AlipayBean alipayBean, Long userId) {
System.out.println("发起支付,入参:" + alipayBean.toString());
try {
// 1. 设置参数
Factory.setOptions(alipayInfo.getOptions());
// 2. 发起API调用
AlipayTradePagePayResponse response = Factory.Payment.Page()
.pay(alipayBean.getSubject(), alipayBean.getOutTradeNo(), alipayBean.getTotalAmount(), alipayInfo.getReturnUrl());
// 3. 处理响应或异常
if (ResponseChecker.success(response)) {
System.out.println("发起支付调用成功,响应结果:" + response.getBody());
return JSONResult.success(response.getBody());
} else {
return JSONResult.error("发起支付调用失败,响应结果:" + response.getBody());
}
} catch (Exception e) {
return JSONResult.error("发起支付失败:" + e.getLocalizedMessage());
}
}
2.订单页面参数设置
@Data
@ToString
public class AlipayBean {
/** 订单号 */
private String outTradeNo;
/** 订单支付金额,单位:元 */
private String totalAmount;
/** 订单标题 */
private String subject;
}
3.支付宝返回的表单,yml里面的参数实体类
@Component
@ConfigurationProperties(prefix = "alibabapay.params")
@Data
public class AlipayParams {
private String appId;
private String protocol;
private String gatewayHost;
private String alibabaPublicKey;
private String merchantPrivateKey;
private String signType;
private String notifyUrl;
private String returnUrl;
public Config getOptions() {
Config config = new Config();
config.protocol = protocol;
config.gatewayHost = gatewayHost;
config.signType = signType;
config.appId = appId;
//应用私钥
config.merchantPrivateKey = merchantPrivateKey;
//支付宝公钥
config.alipayPublicKey = alibabaPublicKey;
//可设置异步通知接收服务地址(可选)
config.notifyUrl = notifyUrl;
return config;
}
}
4.yml配置
# 关于支付的相关配置参数
alibabapay:
params:
#应用ID
app-id: "2021000120615953"
#协议
protocol: "https"
#网关地址
gateway-host: "openapi.alipaydev.com"
#支付宝公钥
alibaba-public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtLTf1fyuhjU0YpMwzkSbs/jB9UoWBiQgw4tkCPSeBbyj6wAPUqs2Rar4Z2R+06SRL0aarm6xzP+p2nGgHwYRNmLjbM8qntlef6/36xN/px7YEXwT9vdPAP77NbE5+UsFTzhyasZRgeWqCdSzL3Cq0ISGXOE+4kxChIwvctcvCLyWJ9529ICijIQ81MTyAVMz70x5/ZPSHKKz5CHDe7BSc7PpknpumewDLrqv+Lsol6vC0VfO8ilqSFha9DK2kzLN/Mjtix1P9m+M4HArEoivBhxAXvIlHQypkHmCbtahAKf5c17Y79DZxUGpBH/LOIf9x1TbtNBvm9XZrXd62k5BqQIDAQAB"
#商户私钥
merchant-private-key: "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCLHcjkKIu1XHQjH0Uenie6cQO5Zamb/sjaTVhL1jYohvprTjOXmif3CrRng9rWFamfZxaXzGvc87RPW2Pv8kt9HVxlyckKb5l6By2APOw9aL3vpwUBvinCNCZGAgPgKacZMfJL78TLTpTOWfKRR8nZ2WmfXcbGmMWSXb/3MQN+kgJ10juJgB4Tkp8UUGhLqGwRwRfJzpX5GSBiSoDhvhSGeYyGF461g/kGKQU33qCOVwZpxnRHa2xLBkUFoSBH2LW2d5r+auaE9uOERni5J1fAxdrjVV2Hu32PSTK6VcSoV8lxh1P7WUWm6Fdg2q2NXE6Jlo9/8ga81zqi5vv6HU1bAgMBAAECggEAdi8rh4lahwywLVZXZhd+MMnqHArd+ISPJcYniOXGxM9G1vpsohJ4eUtCz94Yf1+P5rexXexwhhkTyYcec64nq3bSFDdE7/S3Mg/++77GA7WEBqChhEWFPFMJYNg9aqZ4KtNfwFtFmGJ90IBhrkKKnOQy8wy73ePTlPDIMLwW9+LV3DNoi5nXuIcz3QONDeFmr61R2OQ+xB+N02Tyt7FcKJ19u5u1yfcrP1q5DL3l6ieMdRtBBfPI0Drg0Uc9UBtMra/izlrdY2zXb1hHnoIKyta2ETwAjosCkog969Bx15/G/YneAyZZDNO/OXCMo5z5kn8n2+3ltOMHHSIfQxkvgQKBgQDevdMKTTgTSTwGFJwmOjPJQ5rmDECPwcRa0wLfCRQ8RnXpXE9sLPE9ghyVHKT0JF+OPSaw1/wTP7r0a6Dffux87Y/zp5gvitAn3rZng5iSK4q41EhqnGmUE/rGG8FvJHSTJf/geCwTca5fh7T/rzLHKoJ/JhECl99+rfIbJTQjawKBgQCf427nFT4KOkvMt2z/WnYH+bOkIRoLjFQxTjuFPl8eQoIJH8UTTA8FWT21ZFa9PhOKzXI2+BWxH7qxV+r2Ilxflm8u149wAoJsSKpatbAhD7J+Z+ls6762+ESVGarDy0dA0+JnAEczoL4+fKd7Ml9R//gm9Y9r04+PqvpNVvDp0QKBgF7t8fKzBFIb5SwGPqKALa/6Uxr2X9Gk2GWJBvE9clVaBkjFocfNw6bePAZE5fxzQBJj94hpFLKzd59R+4clFe8MZEyIwfCJLbvATGcDi9PIIOAzAQYG0Wxds4QZMjCHDfPkvw/Qx6Al1BY8xSQva+m8MU+1ToyXY5Ye1k9BZN4vAoGALLbWFRoDt6iF+kJx4RfTWneinYwEVKZyBTfzvVesEjJXW2XfH35t1PkYINpmx5XMsUyzXFwU9OwCsgX8V8lUPAc+IMN4AcMx5kaMHcIh950ENgWpaiSjuVfFFk2PTCJVUvPupQ+W2gFiMud5jyKPNcd4Bq015tnLlEokpexig4ECgYBV2LW2qD2NaHAxDHVh7R7LrGm3DZsB7848Lwrfx9dUrK8gsmmhwud7D62RkFpPigqhvKeYBgBxbyb735FZ4erwYve5LwuLnwImkP774CqxNdKVWBPnHfFwrroJ2UuCGiwDFG5n7wDuK9XNiFc+IkABZR9FAYl4FFi2DNGK0B0Z0w=="
#签名方式
sign-type: "RSA2"
#异步回调,用户不可见,用户完成支付之后,支付宝会调用这个地址,告知我们支付结果
notify-url: "http://hdcwzp.natappfree.cc/payPro/alipay/notify"
#同步回调,用户可见,用户支付完成之后,页面跳转到这里这个地址,是我们系统的一个地址
return-url: "http://hdcwzp.natappfree.cc/payPro/alipay/return"
步骤
1.用户点击提交订单,后台校验参数
2.入参校验,通过订单id查看宠物id是否存在,再查看用户id是否存在
3.验证通过后,把订单入库,订单库存-1
//1.2根据宠物id拿到宠物信息,订单信息存入orderAdopt表
Pet pet = petMapper.selectByPrimaryKey(petId);
Integer miaoshaId = pet.getMiaoshashop();
if(miaoshaId==1){
return JSONResult.error("此宠物为秒杀商品,请需要秒杀的时候再来");
}
OrderAdopt orderinfo = new OrderAdopt();//创建订单实例,给orderAdopt表赋值
orderinfo.setCreateTime(new Date());//创建时间
orderinfo.setState(0);//修改状态 状态(0:待支付;1:支付成功;2:支付失败)
orderinfo.setPrice(pet.getSaleprice());//商品售价
String orderSn = MyUtil.getOrderSn();
orderinfo.setOrderSn(orderSn);//订单编号 ~随机数
orderinfo.setUserinfoId(currentId);//用户id
// orderinfo.setLastPayTime(new Date());//支付时间
orderinfo.setShopId(pet.getShopId());//商品id
orderinfo.setPetId(pet.getId());//宠物id
orderinfo.setPaySn("支付中");//支付说明
UserAddress userAddress = orderAdopt.getUserAddress();//获取用户的收获地址对象
orderinfo.setAddressId(userAddress.getId());
Date date = TimeUtil.addMin(1);
orderinfo.setLastConfirmTime(date);//最后支付时间设置为30分钟
orderinfo.setDigest(pet.getName());//宠物名
orderAdoptMapper.insert(orderinfo);
4.再把收货地址信息入库
//1.4把收获地址存入t_order_address表;
OrderAddress orderAddress = new OrderAddress();
orderAddress.setOrder_sn(orderSn);//订单号
orderAddress.setCreate_time(new Date());//创建时间
orderAddress.setPhone(userAddress.getPhone());//手机号
orderAddress.setAddress(userAddress.getAddress());//详细地址
orderAddress.setContacts(userAddress.getContacts());//联系人
orderAddress.setArea_code(userAddress.getAreaCode());//所在街道
orderAddress.setEmail(userAddress.getEmail());//邮箱
orderAddress.setFull_address(userAddress.getFullAddress());//全地址
orderAddress.setPhone_back(userAddress.getPhoneBack());//备用手机号
orderAddress.setPost_code(userAddress.getPostCode());//邮编
orderAddress.setTel(userAddress.getTel());//固定电话
orderAddressMapper.insert(orderAddress);//收货地址信息入库
4.通过quartz定时器,设置最后确认时间
Map map = new HashMap();
map.put("orderAdoptId",orderinfo.getId());
//超时订单关闭
QuartzUtils.addJob(scheduler,"超时关单",PrintTimeJob.class,map, QuartzJobInfo.setFireDate(date));
5.拉起支付页面
//2.拉起订单支付页面
alipayParams.setNotifyUrl("http://hdcwzp.natappfree.cc/pay/alipay/notify");
alipayParams.setReturnUrl("http://hdcwzp.natappfree.cc/pay/alipay/return");
AlipayBean alipayBean = new AlipayBean();//支付页面显示的参数
alipayBean.setSubject("购买商品名:" + pet.getName() + ";需支付金额:"+orderinfo.getPrice().toString());
alipayBean.setTotalAmount(orderinfo.getPrice().toString());//宠物售价
alipayBean.setOutTradeNo(orderSn);//订单编号 ~随机数
return alipayService.createPayUrl(alipayBean,currentId);//拉起支付页面
6.回调接口
异步回调
处理回调结果,处理业务
一共会发7次请求,返回结果必须为success
业务步骤
1.通过支付宝返回的表单,进行验签操作,验证订单号,订单价格,订单名称
2.验证通过后,.修改状态
3.返回“success”
必须返回success这七个字符
同步回调
显示回调结果,不处理业务
进行验签操作
验证异步处理的状态,返回给用户展示
3.邮件发送(qq邮箱)
使用步骤
前置条件
到qq邮箱里开启授权码,到yml里配置密钥
mail:
host: smtp.qq.com # 设置邮箱主机(服务商),这里使用QQ邮件服务器
username: 1160097325@qq.com # 设置用户名
password: fumwomjttocxbaee # 设置密码,该处的密码是QQ邮箱开启SMTP的授权码而非QQ密码
properties:
mail:
smtp:
auth: true # 必须进行授权认证,它的目的就是阻止他人任意乱发邮件
starttls: #SMTP加密方式:连接到一个TLS保护连接
enable: true
required: true
1.导入依赖
2.注入对象
JavaMailSender
3.调用方法
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
//发送人
simpleMailMessage.setFrom(username);
//发送的标题
simpleMailMessage.setSubject(subject);
//发送的内容
simpleMailMessage.setText(context);
//发送的收件人
simpleMailMessage.setTo(to);
————————————————
4.短信发送(网建短信通)
使用步骤
1.导入依赖
2.网建短信通 进入网站查看Java API说明
https://www.smschinese.com.cn/Login.shtml
3.导入工具包,修改用户名和密钥可直接使用
@Slf4j
public class HttpUtil {
//发送post请求
public static String sendPost(String url, Map
try {
//创建http客户端
HttpClient client = new HttpClient();
//创建post请求,指定请求地址
PostMethod post = new PostMethod(url);
//设置请求头
post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码
//添加参数:循环map,把map中的数据变成List
Set
List
for(String key: keys){
String value = params.get(key);
paramList.add(new NameValuePair(key, value));
}
//把list变成数组
NameValuePair[] data = paramList.toArray(new NameValuePair[]{}) ;
post.setRequestBody(data);
//执行请求
client.executeMethod(post);
//获取结果
String result = new String(post.getResponseBodyAsString().getBytes("utf-8"));
//打印返回消息状态
log.info("HttpUtil#sendPost: 网络请求结果{}",result);
//释放连接
post.releaseConnection();
return result;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMobileCode(String mobile, String text){
Map
param.put("Uid",“”);//注册时填写的用户名
param.put("Key", "");//秘钥
param.put("smsMob", mobile);
param.put("smsText", text);
String result = HttpUtil.sendPost("http://utf8.api.smschinese.cn/", param);
}
}
5.Git工具
1.git的优势
1.可以实现多人合作
2.可以管理项目迭代
3.代码方便储存,电脑关闭也不会丢失
4.查看历史代码,代码还原
2.git的使用
1.先把代码从中央仓库clone到本地仓库
2.把代码add到缓冲区
3.commit到本地仓库
4.push到中央仓库
3.git在工作中的使用
1.把中央仓库代码clone到本地仓库
2.每天早上来pall拉一下最新的代码
3.每天晚上收工时commit&push提交一下代码
4.有冲突问题时事先协商解决
6.Redis(非关系型数据库)
概念:Redis是非关系型数据库,存储形式存在内存中,存储方式为(key,value).
优点
1.数据储存在内存中,读取速度快,性能高
2.储存方式多种多样
list
String
set
zset
hash
一般常见的分为此五种,还有很多数据结构
3.解决并发能力强
应用场景
1.消息订阅
2.缓存
3.队列
4.定时器
5.去重
6.设置有效期应用
7.Quarzt定时器框架的使用
概念
quarzt是一共完全由Java开发的定时器框架,轻量易用
缺点,无法处理高并发
适用场景一般分为
适用场景: 1.定时发邮件;
2.定时发报表;
3.定时关闭支付订单;
4.一系列定时操作都可以完成,功能强大;
组成部分分为
trigger触发器
jobDetail任务详情
job类实现job接口
jobDataMap:存放job参数
scheduler容器
使用步骤配置
动态配置job参数类
public static void addJob(Scheduler sched, String jobName, Class cls, Object params,
String time) {
try {
//--------------------------创建 JobDetail 工作详情---------------------------------
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);// 任务名,任务组,任务执行类
//Job的数据 map
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("params", params);
//根据传入的job的类,创建一个 JobDetail,并指定 JobKey,并把数据map设置给job
JobDetail jobDetail = newJob(cls).withIdentity(jobKey).setJobData(jobDataMap).build();
//--------------------------创建 Trigger 触发器---------------------------------
//创建触发器的 key,相当于触发器的ID
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
//创建触发器,设置触发器key,并关联一个 cronSchedule(基于表达式的时间规则)
Trigger trigger = newTrigger().withIdentity(triggerKey).withSchedule(cronSchedule(time)).build();
//把工作详情和触发器设置到 schedule 调度容器中
sched.scheduleJob(jobDetail, trigger);
//启动
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
关闭定时器任务
public static void removeJob(Scheduler sched, String jobName) {
try {
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
sched.pauseTrigger(triggerKey);// 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
boolean b = sched.deleteJob(jobKey);// 删除任务
System.out.println(b);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
配置将时间转weicorn表达式的类
//把时间变成时间表达式,在 fireDate 时间到的时候执行
public static String setFireDate(Date fireDate) {
//this.fireDate = fireDate;
String[] cronArr = new String[7];
for (int i = 0; i < cronArr.length; i++) {
cronArr[i] = "";
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(fireDate);
int second = calendar.get(Calendar.SECOND);
int minute = calendar.get(Calendar.MINUTE);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int month = calendar.get(Calendar.MONTH) + 1;
int year = calendar.get(Calendar.YEAR);
cronArr[0] = second + "";
cronArr[1] = minute + "";
cronArr[2] = hour + "";
cronArr[3] = day + "";
cronArr[4] = month + "";
cronArr[5] = "?";
cronArr[6] = year + "";
String cron = StringUtils.join(cronArr," ").trim();
System.out.println("cron==========" + cron);
//this.setCronj(cron);
return cron;
}
————————————————
版权声明:本文为CSDN博主「生活可真难啊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_67574688/article/details/125251271
持久化的设置
yml配置
quartz:
job-store-type: jdbc #持久化到数据库
properties:
org:
quartz:
datasource:
driver-class-name: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/pethome-quartz?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
scheduler:
instancName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate说明支持集群
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 1000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 20
threadPriority: 5
多数据源的配置类
@Configuration
public class QuartzDataSourceConfig {
//主数据源
@Bean
@Primary //主数据库,指向pethome
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}
//为quartz创建一个自己数据源
@Bean
@QuartzDataSource //quartz数据源
@ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
public DataSource quartzDataSource(){
return DataSourceBuilder.create().build();
}
}
8.登录功能的实现
步骤
1.首先入参校验
//入参校验
if (!StrUtil.isNotEmpty(loginInfo.getUsername())) {
return JSONResult.success("账号不能为空");
}
if (!StrUtil.isNotEmpty(loginInfo.getPassword())) {
return JSONResult.success("密码不能为空");
}
2.拿到账号,把账号拿去和数据库对比,看账号是否存在
3.账号存在,再比对密码是否正确
//校验账号 ,通过账号拿到密码
Example example = new Example(LoginInfo.class);
example.and().andEqualTo("username", loginInfo.getUsername());
List
if(CollectionUtils.isEmpty(infoList)){
return JSONResult.error("账号错误之");
}
LoginInfo login = infoList.get(0);
//比对密码 存入redis
String password = login.getPassword();
String infoPassword = loginInfo.getPassword();
if (!infoPassword.equals(password)) {
return JSONResult.error("密码错误,请重新输入");
}
4.密码正确.把登录信息存入redis
String token = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(token, JSONObject.toJSONString(login), 30, TimeUnit.MINUTES);
5.把token和登录信息封装成map返回给前端
//返回结果给前端 用map
HashMap
map.put("token", token);
map.put("userInfo", login);
return JSONResult.success(map);
8.扩展功能
1.接口防刷
2.权限管理
自定义注解+拦截器实现
知识点笔记积累
1.resultful风格:是一种面向资源的架构风格
优点
1.本身就是http,无状态,不用担心访问两次上下文.
2.透明性,暴露资源存在
3.充分利用http协议本身
2.swaggerUI风格
概念
是一个规范和完整的框架,用于生成可描述和可视化resultful风格的web服务
优点
1.接口文档自动生成
2.接口功能测试
3.线程里的start方法
可以用join方法解决抢占线程问题
4.注解@Autowired和@Resources的区别
@Autowired是由spring提供的
@Autowired是按类型自动注入
@Resource是由jdk提供的
@Resource是按名称自动注入
5.String.format
用来拼接占位符
定时器实现超时关单
/**
* @author wujiangbo
* @date 2022-06-12 15:13
*/
public class PrintTimeJob implements Job {
@Autowired
private OrderAdoptMapper orderAdoptMapper;
@Autowired
private PetMapper petMapper;
@Autowired
private Scheduler scheduler;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
//通过key获取value
Map map = (HashMap)jobDataMap.get("params");
//在通过value的key获取value
Long orderAdoptId = (Long)map.get("orderAdoptId");
System.out.println("订单id"+orderAdoptId);
//查询当前订单,获取当前状态
OrderAdopt orderAdopt = orderAdoptMapper.selectByPrimaryKey(orderAdoptId);
if(orderAdopt==null){
System.out.println("订单不存在");
}
//判断当前状态是否为待支付 状态(0:待支付;1:支付成功;2:支付失败)
if(orderAdopt.getState()==0){
//修改状态为支付失败
orderAdopt.setState(2);
orderAdoptMapper.updateByPrimaryKeySelective(orderAdopt);
System.out.println("订单修改完成");
//库存回库+1
Long petId = orderAdopt.getPetId();//获得宠物id
Pet pet = petMapper.selectByPrimaryKey(petId);//通过宠物id获得宠物对象
pet.setCount(pet.getCount()+1);
petMapper.updateByPrimaryKeySelective(pet);
System.out.println("减库存成功");
}
//关定时器
QuartzUtils.removeJob(scheduler,"超时关单");
System.out.println("关单");
}
}
Map map = new HashMap();
map.put("orderAdoptId",orderinfo.getId());
//超时订单关闭
QuartzUtils.addJob(scheduler,"超时关单",PrintTimeJob.class,map, QuartzJobInfo.setFireDate(date));
6.全局时间格式化的配置
package cn.itsource.pethome.config;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* @description: 日期时间全局格式化
* @auth: wujiangbo
* @date: 2022-03-09 17:38
*/
@JsonComponent
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
/**
* Date 类型全局时间格式化
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilder() {
return builder -> {
TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");//获取时区
DateFormat df = new SimpleDateFormat(pattern);//设置格式化模板
df.setTimeZone(tz);
builder.failOnEmptyBeans(false)
.failOnUnknownProperties(false)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.dateFormat(df);
}; }
/**
* LocalDate 类型全局时间格式化
*/
@Bean
public LocalDateTimeSerializer localDateTimeDeserializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
}
}
7.糊涂依赖和小辣椒依赖