瑞吉外卖实操笔记五----店铺营业状态设置与用户端微信登录实现

店铺营业状态设置与用户端微信登录实现

一.店铺营业状态设置

  由于店铺营业状态可以算是一个单独的内容,没有必要为其单独设置一个表,因此将营业状态单独设置到redis缓存中。
  设置营业店铺状态只需要一个获取状态的接口即可;

@RestController("userShopController")
@RequestMapping("/user/shop")
@Api(tags = "客户端店铺相关接口")
@Slf4j
public class ShopController {@Autowiredprivate RedisTemplate redisTemplate;/*** 用户端获取店铺营业状态* @return*/@GetMapping("/status")public Result<Integer> getStatus(){//获取到的店铺营业状态可能为空;此时应该设置为营业,并且默认加入到redis中;Integer status = (Integer) redisTemplate.opsForValue().get("SHOP_STATUS");if(status==null){redisTemplate.opsForValue().set("SHOP_STATUS", ShopConstant.SHOP_TRADE);status=ShopConstant.SHOP_TRADE;}log.info("获取店铺营业状态为{}",status==ShopConstant.SHOP_TRADE?"营业中":"打烊中");return Result.success(status);}}

二.微信登陆

微信登录流程:

  1.小程序调用wx.login()获取code(授权码);调用直接获取,不必经过开发者服务器
  2.小程序调用wx.request()发送code,发送给开发者服务器;一个授权码只能使用一次;
  3.开发者服务器调用微信接口服务,传递appid+appsecret+code参数;
  4.微信接口服务返回session_key和openid(微信用户的唯一标识);
  5.由于后续小程序还有其他业务请求开发者服务器,因此应该将自定义登陆状态(token)与openid,session_key关联
  6.开发者服务器将jwt-token返回给小程序;
  7.小程序将自定义登录状态jwt-token存入storage;
  8.小程序发起业务请求,携带jwt-token;
  9.开发者服务器通过jwt-token查询openid,session_key;
  10.开发者服务器返回业务数据;

/*
controller层代码
*/
@RestController
@RequestMapping("/user/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate JwtProperties jwtProperties;@PostMapping("/login")public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){//userLoginDTO中仅仅包含授权码codelog.info("微信登录:{}",userLoginDTO);//微信登录,业务层返回登陆/注册的用户对象;User user=userService.wxlogin(userLoginDTO);//为微信用户设置JWT令牌;并将令牌返回给用户端;Map<String,Object> claims=new HashMap<>();claims.put(JwtClaimsConstant.USER_ID,user.getId());String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);UserLoginVO userLoginVO=UserLoginVO.builder().id(user.getId()).openid(user.getOpenid()).token(token).build();return Result.success(userLoginVO);}
}
/*
service层代码
*/
/**
* 微信登录返回User对象* @param userLoginDTO* @return*/
@Override
public User wxlogin(UserLoginDTO userLoginDTO) {
//根据传递过来的code调用getOpenId请求微信接口服务获得对应的openid;String openid = this.getOpenId(userLoginDTO.getCode());//判断openid是否为空,如果为空表示登录失败,抛出业务异常;if(openid==null){throw new LoginFailedException(MessageConstant.LOGIN_FAILED);}//判断当前用户是否为新的用户;插叙当前openId对应的用户是否已经存在User user = userMapper.getByOpenId(openid);//如果查询不对应的用户(user为Null),说明是新用户,自动完成注册;if(user==null){user = User.builder().openid(openid).createTime(LocalDateTime.now()).build();//将该用户插入(完成注册);userMapper.insert(user);}//返回这个用户对象;return user;
}private String getOpenId(String code){//调用微信接口服务,获得当前用户openId;Map<String ,String> map=new HashMap<>();map.put("appId",weChatProperties.getAppid());map.put("secret",weChatProperties.getSecret());map.put("js_code", code);map.put("grant_type","authorization_code");String json = HttpClientUtil.doGet(WX_LOGIN, map);JSONObject jsonObject= JSON.parseObject(json);String openid = jsonObject.getString("openid");return openid;
}
/*
mapper层代码
*/
@Select("select * from user where openid=#{openId}")
User getByOpenId(String openId);

另外,同样应该对大部分请求进行拦截,拦截器代码与管理端大概一致;

/*** jwt令牌校验的拦截器*/
@Component
@Slf4j
public class WechatTokenUserInterceptor implements HandlerInterceptor {@Autowiredprivate JwtProperties jwtProperties;/*** 校验jwt** @param request* @param response* @param handler* @return* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断当前拦截到的是Controller的方法还是其他资源if (!(handler instanceof HandlerMethod)) {//当前拦截到的不是动态方法,直接放行return true;}try {String token = request.getHeader(jwtProperties.getUserTokenName());Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);//一个小bug,解析出来的载荷中的有数字的部分都是Integer,然而设置的时候不一定是数据部分,所以//可以先转换为String,再按照需要转换为其他类型;Long userId=Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());//取出id之后,将id存放在该线程的内存空间之中,由于这是同一个请求时同一个线程,所以后续Controller与Service//可以单独取出该线程使用;BaseContext.setCurrentId(userId);log.info("解析到的员工ID为:{}",userId);if(userId!=null){//如果有登录数据,代表一登录,放行return true;}else{//否则,发送未认证错误信息response.setStatus(401);return false;}} catch (NumberFormatException e) {throw new LoginFailedException(MessageConstant.LOGIN_FAILED);}}
}

在配置类中进行配置

/*** 带有“###”为新增配置*/
/*** 配置类,注册web层相关组件*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {@Autowiredprivate JwtTokenAdminInterceptor jwtTokenAdminInterceptor;// ###新增配置@Autowiredprivate WechatTokenUserInterceptor wechatTokenUserInterceptor;/*** 注册自定义拦截器** @param registry*/protected void addInterceptors(InterceptorRegistry registry) {log.info("开始注册自定义拦截器...");registry.addInterceptor(jwtTokenAdminInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/employee/login","/admin/employee/logout");// ###新增配置registry.addInterceptor(wechatTokenUserInterceptor).addPathPatterns("/user/**").excludePathPatterns("/user/user/login","/user/shop/status");}/*** 通过knife4j生成接口文档* @return*/@Beanpublic Docket docket() {ApiInfo apiInfo = new ApiInfoBuilder().title("苍穹外卖项目接口文档").version("2.0").description("苍穹外卖项目接口文档").build();Docket docket = new Docket(DocumentationType.SWAGGER_2).groupName("管理端接口").apiInfo(apiInfo).select().apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin")).paths(PathSelectors.any()).build();return docket;}@Beanpublic Docket docketUser() {ApiInfo apiInfo = new ApiInfoBuilder().title("苍穹外卖项目接口文档").version("2.0").description("苍穹外卖项目接口文档").build();Docket docket = new Docket(DocumentationType.SWAGGER_2).groupName("用户端接口").apiInfo(apiInfo).select().apis(RequestHandlerSelectors.basePackage("com.sky.controller.user")).paths(PathSelectors.any()).build();return docket;}/*** 设置静态资源映射* @param registry*/protected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}/*** 扩展Spring MVC的消息转化器,统一对后端返回给前端的数据进行处理;* @param converters*/@Overrideprotected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {log.info("扩展消息转换器......");//创建一个消息转换器对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();//为消息转换器设置对象转换器,可以将Java对象序列化为JSON;converter.setObjectMapper(new JacksonObjectMapper());//将自己的消息转换器加入容器之中;并设置优先使用自己的消息转换器;converters.add(0,converter);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/677995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSP-202009-2-风险人群筛查

CSP-202009-2-风险人群筛查 解题思路 检查是否经过高危区 (x > x1) && (x < x2) && (y > y1) && (y < y2) 检查坐标是否在高危区域内&#xff0c; !isPassed 确保仅在第一次经过高危区域时增加 pass 计数。如果条件成立&#xff0c;表示…

C#系列-C#访问MongoDB+redis+kafka(7)

目录 一、 C#中访问MongoDB. 二、 C#访问redis. 三、 C#访问kafka. C#中访问MongoDB 在C#中访问MongoDB&#xff0c;你通常会使用MongoDB官方提供的MongoDB C#/.NET Driver。这个驱动提供了丰富的API来执行CRUD&#xff08;创建、读取、更新、删除&#x…

Cpp-3

文件和流 /*1.文件操作这需要用到 C 中另一个标准库 fstream2.对于标准库 fstream ,它定义了三个新的数据类型:数据类型 描述ofstream 表示输出文件流&#xff0c;用于创建文件并向文件写入信息ifstream 表示输入文件流&#xff0c;用于从文件读取信息fstrea…

java设计模式之中介者模式

中介者模式&#xff08;Mediator Pattern&#xff09; 基本介绍 中介者模式&#xff0c;用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用&#xff0c;从而使其解耦松散。而且可以独立地改变它们之间的交互。中介者模式属于行为型模式。比如MVC模…

C#,欧拉常数(Euler Constant)的算法与源代码

1 欧拉常数 欧拉常数最先由瑞士数学家莱昂哈德 欧拉 (Leonhard Euler) 在1735年发表的文章《De Progressionibus harmonicus observationes》中定义。欧拉曾经使用γ作为它的符号&#xff0c;并计算出了它的前6位&#xff0c;1761年他又将该值计算到了16位 。 欧拉常数最先由瑞…

Sql Server数据库软件里如何查看当前Sql Server服务运行的状态?

有时候我们会遇到sql server服务停止的情况&#xff0c;这可能会导致数据库无法正常访问和操作。 查看当前Sql Server服务运行的状态&#xff1a; 可以通过以下代码来检查服务状态&#xff1a; --检查sql server服务状态&#xff1a;EXEC xp_servicecontrol querystate, MSSQ…

2/10 BFS初探

其实在我看来解决全排列问题&#xff0c;核心还是顺序&#xff0c;想清楚结束条件&#xff0c;然后输出&#xff0c;以n3为例 #include<iostream> using namespace std; const int N 10; int path[N];//保存序列 int state[N];//数字是否被用过 int n; void dfs(int u) …

ubuntu彻底卸载cuda 重新安装cuda

sudo apt-get --purge remove "*cublas*" "*cufft*" "*curand*" \"*cusolver*" "*cusparse*" "*npp*" "*nvjpeg*" "cuda*" "nsight*" cuda10以上 cd /usr/local/cuda-xx.x/bin/ s…

Mac电脑清空特别大型旧文件如何一键清理?

在我们的数字生活中&#xff0c;Mac电脑常常承载着大量个人资料和重要文件。但当我们决定把自己的Mac送给亲人或朋友使用时&#xff0c;面临的首要任务便是彻底且高效地清空所有个人数据&#xff0c;以保证隐私安全。传统的删除方法虽然简单&#xff0c;但往往不能彻底清除所有…

问题:2、计算机网络的目标是实现________。 #媒体#知识分享

问题&#xff1a;2、计算机网络的目标是实现________。 A&#xff0e;数据处理 B&#xff0e;信息传输与数据处理 C&#xff0e;资源共享与信息传输 D&#xff0e;文献查询 参考答案如图所示

Windows系统的高效又炫酷的快捷键

Windows系统的高效又炫酷的快捷键 在Windows系统中&#xff0c;快捷键是一种提高工作效率的重要工具。掌握一些常用的快捷键可以让我们在操作电脑时更加得心应手。下面&#xff0c;我将为您介绍一些Windows系统中的高效又炫酷的快捷键&#xff0c;帮助您更好地使用电脑…

数据备份和恢复

数据备份和恢复 什么情况下会用到数据备份呢 数据丢失的场景 人为误操作造成的某些数据被误操作 软件BUG造成数据部分或者全部丢失 硬件故障造成数据库部分或全部丢失 安全漏洞被入侵数据恶意破坏 非数据丢失场景 基于某个时间点的数据恢复 开发测试环境数据库搭建 相同数据库的…

c语言中的隐式类型转换

数据类型转化 我们在实际编程中&#xff0c;不管你是有意的还是无意的&#xff0c;有时候都会让两个不同类型的数据参与运算&#xff0c;编译器为了能够生成CPU可以正常 执行的指令&#xff0c;往往会对数据做类型转换&#xff0c;将两个不同类型的数据转换成同一种数据类型。…

《CSS 简易速速上手小册》第1章:CSS 基础入门(2024 最新版)

文章目录 1.1 CSS 语法和选择器&#xff1a;挑选你的画笔1.1.1 基础知识1.1.2 重点案例&#xff1a;创建一个响应式导航菜单1.1.3 拓展案例 1&#xff1a;为特定链接添加图标1.1.4 拓展案例 2&#xff1a;创建一个简单的问答折叠面板 1.2 盒模型的基础&#xff1a;构建你的乐高…

Redis -- 渐进式遍历

家&#xff0c;是心的方向。不论走多远&#xff0c;总有一盏灯为你留着。桌上的碗筷多了几双&#xff0c;笑声也多了几分温暖。家人团聚&#xff0c;是最美的风景线。时间&#xff1a;2024年 2月 8日 12:51:20 目录 前言 语法 示例 前言 试想一个场景,那就是在key非常多的…

【docker】docker-compose.yml 语法详解

文章目录 一、相关文章二、基本概念三、Docker Compose语法介绍1、version2、Servicesimagebuildportsnetworksvolumesenvironmentdeploydepends\_oncommandrestart 3、networks 使用docker 网络驱动类型 4、volumes 使用 四、和环境变量文件.env结合使用五、使用示例1、基本使…

STL演讲比赛流程管理系统

很难,一边看视频&#xff0c;一边思考了好多天 speaker.h #pragma once//防止头文件重复包含 #include<iostream> using namespace std;//设计选手类 class Speaker{public:string m_Name;//姓名 double m_Score[2];//double带了浮点,防止重复 2代表可能有人是两轮…

字节跳动官方出品AI,白嫖使用GPT4!

关注我&#xff0c;紧跟本系列专栏文章&#xff0c;咱们下篇再续&#xff01; 作者简介&#xff1a;魔都技术专家兼架构&#xff0c;多家大厂后端一线研发经验&#xff0c;各大技术社区头部专家博主&#xff0c;编程严选网创始人。具有丰富的引领团队经验&#xff0c;深厚业务架…

《CSS 简易速速上手小册》第8章:CSS 性能优化和可访问性(2024 最新版)

文章目录 8.1 CSS 文件的组织和管理8.1.1 基础知识8.1.2 重点案例&#xff1a;项目样式表结构8.1.3 拓展案例 1&#xff1a;使用BEM命名规范8.1.4 拓展案例 2&#xff1a;利用 Sass 混入创建响应式工具类 8.2 提高网页加载速度的技巧8.2.1 基础知识8.2.2 重点案例&#xff1a;图…

alist基本用法@文档阅读@挂载网盘@网盘webdav挂载

文章目录 alist官网alist网站风格说明alist软件版本 安装和启动使用必看文档&#x1f47a;alist for android版本启动alist网页挂载阿里云盘open获取阿里云令牌 主页检查挂载情况 常用页面以配置挂载列表管理配置页面 FAQ可能遇到的错误检查服务重启前后alist的动作(自动挂载)a…