苍穹外卖项目

1. 苍穹外卖项目介绍

1.1 项目介绍

定位:专门为餐饮企业(餐厅、饭店)定制的一款软件产品

项目架构:体现项目中的业务功能模块

1.2 产品原型

产品原型:用于展示项目的业务功能,一般由产品经理进行设计

1.3 技术选型

技术选型:展示项目中使用到的技术框架和中间件等

2. 开发环境的搭建

2.1 前端环境搭建

vue node js axios

2.2 后端环境搭建

mysql 、 springboot 、springmvc、websocket

2.2.1 使用Git进行版本控制

使用Git进行项目代码的版本控制,具体操作:

  • 创建Git本地仓库

1.使用idea点击VCS,创建本地仓库

  • 创建Git远程仓库
  • 将本地文件推送到Git远程仓库

2.3 实现登录效果

2.3.1 前后端联调

nginx 反向代理的配置方式

server{
    listen 80;
    server_name localhost;
    
    location /api/ {
        proxy_pass http://localhost:8080/admin/;#反向代理
    }
}

nginx配置负载均衡

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

server{
    listen 80;
    server_name localhost;
    
    location /api/ {
        proxy_pass http://webservers/admin/;#反向代理
    }
}

2.3.2 未完成任务的注释

TODO 注释

2.3.2 完善登录效果

密码是明文存储需要加上md5加密

// md5加密
password = DigestUtils.md5DigestAsHex(password.getBytes());

3. 导入接口文档

3.1 Swagger

介绍:使用swagger你只需要按照他的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面

Knife4j是为java MVC框架集成swagger生成api文档的增强解决方案。

3.2 使用方式

      1. 导入knife4j的mavern坐标 pom.xml

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

      2. 在配置类中加入 knife4j 相关配置 WebMvcConfiguration.java

@Bean
    public Docket docket() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

     3. 设置静态资源映射,否则接口文档页面无法访问WebMvcConfiguration.java

 protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

3.3 常用注解

通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:

注解说明
@Api用在类上,例如Controller,表示对类的说明
@ApiModel用在类上,例如entity、DTO、VO
@ApiModelProperty用在属性上,描述属性信息
@ApiOpeation用在方法上,例如Controller的方法,说明方法的用途、作用

4. 员工管理

4.1 新增员工

知识点1:对象的拷贝

//对象的拷贝
BeanUtils.copyProperties(employeeDTO,employee);

知识点2:插入两个相同唯一的值,全局捕获异常 handle/GlobalExceptionHandler

    /**
     * 处理sql异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }else {
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }

知识点3:动态获取用户id

ThreadLocal为每个线程提供一份存储空间,具有线程隔离效果,只有在线程内才能获取到对应的值,线程外不能访问。

controller、service、拦截器里面都是同一个。所以可以进行通信

ThreadLocal常用方法:

  • public void set(T value) 设置当前的线程局部变量的值
  • public T get()  返回当前线程所对应的线程局部变量的值
  • public void remove()  移除当前线程的局部变量值

封装一个:工具类BaseContext:

public class BaseContext {

    public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    public static void setCurrentId(Long id) {
        threadLocal.set(id);
    }

    public static Long getCurrentId() {
        return threadLocal.get();
    }

    public static void removeCurrentId() {
        threadLocal.remove();
    }

}

存储id:

BaseContext.setCurrentId(empId);

取出id:

BaseContext.setCurrentId(empId);

4.2 员工分页查询

4.2.1 分页查询:

配置配置:

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

 使用:

Page<Employee> employeePage = new Page<>(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
        LambdaQueryWrapper<Employee> employeeWrapper = new LambdaQueryWrapper<>();
        employeeWrapper.like(ObjectUtils.isNotEmpty(employeePageQueryDTO.getName()),Employee::getName,employeePageQueryDTO.getName());
        employeeService.page(employeePage,employeeWrapper);
        PageResult pageResult = new PageResult();
        BeanUtils.copyProperties(employeePage,pageResult);
        return Result.success(pageResult);

4.2.2 解决时间显示问题

方式一:在属性上加入注解,对日期格式化

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;")

方式二:在WebMvcConfiguration中扩展Spring MVC 的消息转换器,统一对日期类型进行格式化处理

第一步:在WebMvcConfiguration编写代码

 protected void extendMessageConverters(List<HttpMessageConverter<?>> converters){
        log.info("开始扩展消息转换器...");
        //创建一个消息转化器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,可以将java对象转为json字符串
        converter.setObjectMapper(new JacksonObjectMapper());
        //将我们自己的转化器放入spring MVC框架容器中
        converters.add(0,converter);
    }

第二步:新建JacksonObjectMapper工具类中

package com.takeaway.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

4.3 员工禁用

用户的id是17位但是前端long没有那么长,会导致精度丢失:

解决方法:配置confg

@Configuration
public class IdJsonConfig {
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleModule module = new SimpleModule();
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

禁用方法:

@PostMapping("/status/{status}")
    //public Result startOrStop(@PathVariable("status") Integer status,Long id){ 不一致需要写
    public Result startOrStop(@PathVariable Integer status, Long id) {

4.4  编辑员工

4.4.1 获取用户详情

    @ApiOperation("获取用户详情")
    @GetMapping("/{id}")
    public Result<Employee> getById(@PathVariable Long id){

4.4.2 编辑员工

字段设计:

    @ApiOperation("新增分类")
    @PostMapping

    @ApiOperation("分类分页查询")
    @GetMapping("/page")

    @DeleteMapping
    @ApiOperation("删除分类")

    @ApiOperation("分类禁用和启用")
    @PostMapping("/status/{status}")

    @ApiOperation("修改分类")
    @PutMapping

5. 菜品管理

5.1 公共字段填充(未实现)

业务表中的公共字段:

crate_time、update_time 自动填充

1. 自定义注解 AutoFile,用于标识需要进行公共字段自动填充的方法

2.自定义切面AutoFillAspect,统一拦截加入了AutoFil 注解的方法,通过反射为公共字段赋值

3.在mapper的方法上加入 AutoFill注解

未完成。。。

6. Redis

6.1 简介

Redis是一个基于内存的 key-value 结构数据库

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品,咨询,新闻)
  • 企业应用广泛

6.2 Redis下载与安装

6.2.1 Redis安装包分为 Windows 版和 Linux 版:

redis属于绿色健康软件:解压就可以用:

目录结构:

redis.windows.conf      Redis配置文件

redis-cli.exe                 Redis运行文件

redis-server.exe           Redis服务端

6.3 Redis的使用

第一步:启动服务端,进入redis安装目录,执行如下命令行

D:\develop\redis>redis-server.exe redis.windows.conf

出现这个就启动成功:

第二步:启动客户端,链接redis服务端

D:\develop\redis>redis-cli.exe

出现这个则成功:

或者:可以配置端口和链接主机

D:\develop\redis>redis-cli.exe -h localhost -p 6379

6.4 Redis配置密码

打开:redis.windows.conf找到requirepass解除注释,修改值为密码,就完成了

客户端链接服务器命令:

D:\develop\redis>redis-cli.exe -h localhost -p 6379 -a 123456

6.5 Redis五种常用数据类型介绍

字符串 string、哈希 hash、列表 list、集合 set、有序集合 sorted set / zset

6.6 Redis 常用命令

6.6.1 Redis 字符串类型常用命令

  • SET key value                               设置指定key的值
  • GET key                                        获取指定key的值
  • SETEX key seconds value           设置指定key的值,并将 key 的过期时间设置为 seconds 秒
  • SETNX key value                          只有在 key 不存在时设置 key 的值

6.6.2 Redis 哈希操作命令

Redis hash 是一个string 类型的 field 和 value 的映射表,hash特别适合用于存储对象,常用命令:

  • HSET key field value     将哈希表 key 中的字段 field 的值设为 value
  • HGET key field              获取存储在哈希表中指定字段的值
  • HDEL key field               删除哈希表中所有字段
  • HKEYS key                    获取哈希表中所有字段
  • HVALS key                     获取哈希表中所有值

6.6.2 Redis 列表是简单的字符串列表,按照插入顺序排序,常用命令:

  • LPUSH key value1 [value2]         将一个或多个插入到列表头部
  • LRANGE key start stop                获取列表指定范围内的元素
  • RPOP key                                     移除并获取列表最后一个元素
  • LLEN key                                       获取列表长度

6.6.3 Redis

6.7 在Java中操作Redis

6.7.1 Spring Data Redis 使用方式

        1. 导入Spring Data Redis 的maven坐标  pom.xml

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

        2. 配置Redis数据源  application.yml

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
    database: 0 #指定数据库,不同的数据中数据是相互隔离的,默认不用配置

        3.编写配置类,创建RedisTemplate对象,在config下新建RedisConfiguration.java

@Configuration
@Slf4j
public class RedisConfiguration {

//报错是编译器的原因

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        log.info("开始创建redis模块对象...");
        RedisTemplate redisTemplate = new RedisTemplate();
        //设置redis链接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

        4.通过RedisTemplate对象操作Redis

@SpringBootTest
public class SpringDataRedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate(){
        System.out.println(redisTemplate);
    }
}

6.7.1 Spring Data Redis 操作字符串

6.7.2 Spring Data Redis 操作Hash

操作都是一样的。

6.8  店铺营业状态设计

最后:

小技巧:

查询:对于查询来说,Result最好写类型,但是对于增删改来说可以用泛型

使用Builder构造类:

在类上加上@

@Builder
public class Employee implements Serializable {

使用:

Employee employee = Employee.builder()
                .id(id)
                .status(status)
                .build();

设置:请求bean名称

log.info("设置店铺营业状态:{}",status == 1?"营业中":"打样中");

配置两个文档:

@Bean
    public Docket docket1() {
        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.takeaway.controller.admin"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    @Bean
    public Docket docket2() {
        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.takeaway.controller.user"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
苍穹项目可以使用Postman进行API接口的测试和调试。Postman是一款常用的API开发工具,它可以帮助开发人员发送HTTP请求并查看响应结果,方便进行接口的测试和调试。 在苍穹项目中,可以使用Postman发送各种类型的HTTP请求,比如GET、POST、PUT、DELETE等,来模拟用户操作和测试接口功能。通过Postman,可以验证接口的正确性、查看接口返回的数据、调试接口的参数等。 为了使用Postman进行苍穹项目的接口测试,您需要以下步骤: 1. 下载并安装Postman:您可以从Postman官网(https://www.postman.com/)上下载并安装适合您的操作系统的版本。 2. 打开Postman并创建一个新的请求:打开Postman应用,在界面上选择"New"来创建一个新的请求。 3. 输入接口URL和选择请求方法:在新建请求的界面中,输入苍穹项目的接口URL,并选择适当的请求方法,比如GET或POST。 4. 添加请求参数和请求头:根据需要,您可以添加请求参数和请求头,以便于模拟不同的请求情况。 5. 发送请求并查看响应:点击发送按钮,Postman会向服务器发送请求,并在界面上显示响应结果。您可以查看接口返回的数据、响应状态码等信息。 通过以上步骤,您可以使用Postman进行苍穹项目的接口测试。这样可以帮助您确保接口的正确性和稳定性,提高项目的质量和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值