苍穹外卖系统07

这篇具有很好参考价值的文章主要介绍了苍穹外卖系统07。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

哈喽!大家好,我是旷世奇才李先生
文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】更有我为大家准备的福利哟,回复【项目】获取我为大家准备的项目

最近打算把我手里之前做的项目分享给大家,这个苍穹外卖系统是跟着B站上的一个视频做的
大家可以根据视频自己学习一下,或者直接拿我做好的项目直接去用也可以。

相关阅读

  • 面试官:Zookeeper是什么,它有什么特性与使用场景?
  • 面试官:Redis如何实现持久化的、主从哨兵又是什么?

一、后台管理系统前端页面

1、登录密码加密

使用spring自带的加密工具类进行md5加密

password = DigestUtils.md5DigestAsHex(password.getBytes());

2、Swagger引入

首先引入依赖

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

然后配置基础信息,以及要扫描的controller包位置

package com.sky.config;

import com.sky.interceptor.JwtTokenAdminInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;

    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/employee/login");
    }

    /**
     * 通过knife4j生成接口文档
     * @return
     */
    @Bean
    public Docket docket() {
        log.info("准备生成接口文档...");
        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;
    }

    /**
     * 设置静态资源映射
     * @param registry
     */
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始设置静态资源映射...");
        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}


然后访问页面

http://localhost:8080/doc.html

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

3、Swagger常用注解

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

4、对象属性拷贝

//对象属性拷贝,DTO的属性名和实体类的属性名相同
        BeanUtils.copyProperties(employeeDTO,employee);

5、SQL异常处理(新增相同用户名员工异常捕获)

 /**
     * @Description: 处理SQL异常
     * @Author: KSQC
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        //Duplicate entry 'zhangsan' for key 'idx_username'
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + "已存在";
            return Result.error(msg);
        }else {
            return Result.error("未知错误");
        }
    }

6、ThreadLocal用来存储用户的信息,用于新增用户时将添加人属性赋值

首先创建一个工具类

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();
    }

}

登录的时候将用户信息放入ThreadLocal中

//将用户id放入线程中去
            BaseContext.setCurrentId(empId);

新增用户的时候将添加人信息赋值

        //设置当前记录创建人id和修改人id
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());

7、分页查询员工

首先引入依赖pagehelper,这是mybatis提供的分页插件

            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper}</version>
            </dependency>

然后进行分页查询代码开发

 /**
     * @Description: 分页查询
     * @Author: KSQC
     */
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        //开始分页查询,传入参数为第几页和每页展示多少行。
        PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());

        //普通正常查询,因为PageHelper会将分页信息存入当前线程,会在正常查询时进行拼接。
        Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);

        //将PageResult需要的属性获取出来进行返回。
        long total = page.getTotal();
        List<Employee> records = page.getResult();

        return new PageResult(total,records);
    }

8、日期格式化处理

第一种方法:直接在属性上加注解

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

第二种方法:配置全局消息转换器

  /**
     * @Description: 扩展SpringMVC框架的消息转化器
     * @Author: KSQC
     */
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转化器加入容器中
        converters.add(0,converter);
    }

转换器实体类如下:

package com.sky.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);
    }
}

9、公共字段代码填充(通过AOP和反射将公共字段进行填充)

package com.sky.aspect;/**
 * @Author: KSQC
 * @Description: ${description}
 * @Date: 2023/8/8 21:08
 */

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @Description 自定义切面,实现公共字段自动填充处理逻辑
 * @Author LiShiQi
 * @Date 2023/8/8 21:08
 * @Version 1.0
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    /**
     *  切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}

    /**
     *  前置通知,在通知中进行公共字段的赋值
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        log.info("开始进行公共字段自动填充...");

        //获取到当前被拦截的方法上的数据库操作类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
        OperationType operationType = autoFill.value();

        //获取到当前被拦截的方法的参数--实体对象
        Object[] args = joinPoint.getArgs();
        if(args == null || args.length == 0){
            return;
        }

        Object entity = args[0];

        //准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();


        //根据当前不同的操作类型,为对应的属性通过反射来赋值
        if(operationType == OperationType.INSERT){
            //为4个公共字段赋值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setCreateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }else if(operationType == OperationType.UPDATE){
            //为2个公共字段赋值

            try {
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

}

10、使用阿里云来存储图片

配置阿里云地址等相关参数

  alioss:
    endpoint: oss-cn-beijing.aliyuncs.com
    access-key-id: LTAI5tPeFLzsPPT8gG3LPW64
    access-key-secret: U6k1brOZ8gaOIXv3nXbulGTUzy6Pd7
    bucket-name: sky-itcast

新建一个阿里云配置类

package com.sky.config;

import com.sky.properties.AliOssProperties;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: KSQC
 * @Description: 配置类,用于创建AliOssUtil对象
 * @Date: 2023/8/9 9:40
 */
@Configuration
@Slf4j
public class OssConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
        log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
        return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(),
                aliOssProperties.getAccessKeySecret(),
                aliOssProperties.getBucketName());

    }
}

调用工具类上传图片到阿里云,返回图片地址用于前端展示

//文件的请求路径
            String filePath = aliOssUtil.upload(file.getBytes(),objectName);

11、使用redis来做店铺状态功能

在spring下配置redis

 # redis 配置
  redis:
    # 地址
    host: localhost
    # 端口,默认为6379
    port: 6379
    # 数据库索引
    database: 0
    # 密码
    password: 123456
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池的最大数据库连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms

创建一个RedisConfiguration类

package com.sky.config;/**
 * @Author: KSQC
 * @Description: ${description}
 * @Date: 2023/8/9 15:21
 */

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @Description
 * @Author LiShiQi
 * @Date 2023/8/9 15:21
 * @Version 1.0
 */
@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;
    }
}

设置店铺状态

 /**
     * @Description: 设置店铺的营业状态
     * @Author: KSQC
     */
    @PutMapping("/{status}")
    @ApiOperation("设置店铺的营业状态")
    public Result setStatus(@PathVariable Integer status){
        log.info("设置店铺的营业状态为:{}",status == 1 ? "营业中" : "打烊中");
        redisTemplate.opsForValue().set(KEY,status);

        return Result.success();
    }

12、使用Sping-Cache来缓存套餐数据

首先引入依赖,除了引入spring-cache依赖还需要引入redis依赖,因为spring-cache底层是需要使用到一个缓存中间件的,可支持多种中间件,目前我们使用redis作为缓存中间件。

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

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

常用的注解,当我们引入完依赖后,就可以使用注解的方式来进行缓存操作。

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

首先启动类开启注解功能

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

然后找到我们需要缓存的查询方法加上注解,这里会将“setmealCache”作为前缀,然后加上我们的分类id一起作为key,然后将查询出来的数据作为value,放入redis中, 当我们第二次查询的时候这个时候redis中有数据,直接就会返回我们redis中的数据就不再去查询数据库,大大减轻了我们数据库的压力。

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

新增套餐的时候清除缓存,因为新增加了套餐页面上要展示出来,但是缓存中是旧数据,所以我们要清理缓存,然后再重新查询数据库,重新缓存。这里我们根据分类id进行清理,在哪个分类下新增套餐,就将哪个分类缓存清理。

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

批量删除套餐的时候我们进行批量清理,将所有前缀为“setmealCache”的全部清理。

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

12、使用Sping-Task来执行定时任务

这个task的依赖在context包里包含了,所以我们不需要额外引入依赖了。

我们需要先在启动类上添加注解"@EnableScheduling"

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

然后在需要定时执行的方法上添加注解,并写上执行时间,这里使用cron语法,不会的可以百度查询一下。

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

13、使用WebSocket实现下单提醒与催单提醒

首先引入依赖

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

新建一个WebSocketConfiguration配置类

package com.sky.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * WebSocket配置类,用于注册WebSocket的Bean
 */
@Configuration
public class WebSocketConfiguration {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

然后建立一个WebSocketServer功能类

package com.sky.websocket;

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * WebSocket服务
 */
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端:" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message) {
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

然后我们在具体业务代码中去调用方法向前端发送消息,例如下单成功后发送消息。

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

        //通过websocket向客户端浏览器推送消息 type orderId content
        Map map = new HashMap();
        map.put("type",1); // 1表示来单提醒 2表示客户催单
        map.put("orderId",ordersDB.getId());
        map.put("content","订单号:" + outTradeNo);

        String json = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(json);

下面是测试用例前端代码,前端需要启动后就与后端建立WebSocket连接,这样才能进行后续的通信。

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebSocket Demo</title>
</head>
<body>
    <input id="text" type="text" />
    <button onclick="send()">发送消息</button>
    <button onclick="closeWebSocket()">关闭连接</button>
    <div id="message">
    </div>
</body>
<script type="text/javascript">
    var websocket = null;
    var clientId = Math.random().toString(36).substr(2);

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        //连接WebSocket节点
        websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);
    }
    else{
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(){
        setMessageInnerHTML("连接成功");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
	
	//关闭连接
    function closeWebSocket() {
        websocket.close();
    }
</script>
</html>

二、微信小程序用户端页面展示

待授权页面
苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

确认授权页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖
首页

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

选择口味页

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

购物车页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

提交订单页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

点击头像页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

历史订单页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

地址管理页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

三、商家后端页面展示

工作台展示页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

数据统计页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

订单管理页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

菜品管理页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

分类管理页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

员工管理页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

店铺状态修改页面

苍穹外卖系统07,项目,java,面试,项目,苍穹外卖

四、总结

项目涉及的功能还是比较全面的,建议大家跟着视频做一遍。可以关注公众号回复【项目】领取项目,如果有用就点赞支持一下吧。

文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【项目】获取我为大家准备的项目文章来源地址https://www.toymoban.com/news/detail-640370.html

到了这里,关于苍穹外卖系统07的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【java苍穹外卖项目实战三】nginx反向代理和负载均衡

    我们思考一个问题: 前端发送的请求,是如何请求到后端服务的? 前端请求地址:http://localhost/api/employee/login 后端接口地址:http://localhost:8080/admin/employee/login 很明显,两个地址不一致,那是如何请求到后端服务的呢? 1、nginx反向代理 nginx 反向代理 ,就是将前端发送的动态

    2024年02月21日
    浏览(49)
  • Java项目-苍穹外卖-Day11-Apache ECharts数据统计

    主要是以下四项的统计,以不同形式的图形进行展示 自己去网站上看一哈,我不太懂前端 com.sky.controller.admin.ReportController com.sky.service.impl.ReportServiceImpl.java orderMapper orderMapper.xml Reportcontroller ReportServiceImpl orderMapper.xml reportController ReportServiceImpl orderMapper.xml

    2024年02月09日
    浏览(46)
  • 《苍穹外卖》电商实战项目(java)知识点整理(P1~P65)【上】

    史上最完整的《苍穹外卖》项目实操笔记,跟视频的每一P对应,全系列10万字,涵盖详细步骤与问题的解决方案。如果你操作到某一步卡壳,参考这篇,相信会带给你极大启发。 《苍穹外卖》项目实操笔记【中】:P66~P122《苍穹外卖》项目实操笔记【中】 1. nginx反向代理好处

    2024年01月24日
    浏览(46)
  • 【苍穹外卖 | 项目日记】第一天

    我打算用16天的时间写完黑马程序员的苍穹外卖项目,为了督促自己每天坚持写以及记录项目知识点,所以用这种项目日记的方式鞭策自己 目录 前言: 今日完结任务: 今日收获: 1.阅读代码框架: 2.新增员工接口: 3.分页查询接口: 4.员工状态修改接口: 杂项知识点: 总

    2024年02月08日
    浏览(43)
  • 项目实战————苍穹外卖(DAY11)

    Apache ECharts 营业额统计 用户统计 订单统计 销量排名Top10 功能实现: 数据统计 数据统计效果图: 1.1 介绍 Apache ECharts 是一款基于 Javascript 的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。 官网地址:Apache ECharts 常见效果展示: 1). 柱形图

    2024年01月20日
    浏览(49)
  • 苍穹外卖day02项目日志

    参考产品原型,设计表和接口。 1.1.1设计表 看员工管理的产品原型: 有员工姓名、账号、手机号、账号状态、最后操作时间等。 注意,操作一栏不是字段,其中的启用禁用才是。 再看添加员工的原型:  可以发现还有性别和身份证号。 不要忘了旁边: 还有密码。 总结出了

    2024年02月14日
    浏览(73)
  • 苍穹外卖-第一章项目介绍

    1)管理端功能 员工登录/退出 , 员工信息管理 , 分类管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 订单管理 ,数据统计,来单提醒。 2)用户端功能 微信登录 , 收件人地址管理 , 用户历史订单查询 , 菜品规格查询 , 购物车功能 , 下单 , 支付、分类及菜品浏览。 1)管理端 餐饮企业

    2024年02月08日
    浏览(44)
  • 基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(四)

    1.1 需求分析与设计 1.1.1 产品原型 在员工管理列表页面点击 “编辑” 按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击 “保存” 按钮完成编辑操作。 修改页面原型 : 注:点击修改时,数据应该正常回显到修改页面。 1.1.2 接口设计 根据上述原型图分

    2024年02月05日
    浏览(50)
  • 基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖集成Redis(九)

    1.1 Redis的Java客户端 Redis 的 Java 客户端很多,常用的几种: Jedis Lettuce Spring Data Redis Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。 1.2 Spring Data Redis使用方式 1.2.1 介绍 Spring Data Redis 是 Spring 的一部分

    2024年02月05日
    浏览(54)
  • 最适合新手的SpringBoot+SSM项目《苍穹外卖》实战—(二)项目概述

    黑马程序员最新Java项目实战《苍穹外卖》,最适合新手的SpringBoot+SSM的企业级Java项目实战。 《苍穹外卖》项目的定位是一款为餐饮企业(餐厅、饭店)定制的软件产品。该项目是一个在线外卖订购系统,顾客可以通过网站或者手机 App 订购餐点。该项目可以提供以下的功能:

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包