当前位置:首页 > 技术 > 正文内容

美食网站基于SpringBoot+Vue+UniApp的开发实现

访客 技术 2026年7月12日 1

技术架构概述

本项目采用SpringBoot作为后端框架,Vue用于前端交互,UniApp实现跨平台支持,结合MyBatis-Plus完成数据持久化操作。

后端框架:SpringBoot

SpringBoot内置了嵌入式服务器(如Tomcat、Jetty等),通过自动配置功能简化了依赖管理。开发者无需手动配置每个组件,即可快速搭建高效的应用程序。此外,Spring Boot还集成了Spring Data、Spring Security和Spring Cloud等插件,增强了系统的扩展性和安全性。

前端框架:Vue

Vue的核心特性包括响应式数据绑定、虚拟DOM和组件化开发。这些特性使得开发者可以专注于业务逻辑处理,而无需关心UI的手动更新。当数据发生变化时,Vue会自动触发视图更新,从而提升了开发效率和代码可维护性。

持久层框架:MyBatis-Plus

MyBatis-Plus是MyBatis的增强工具,提供了丰富的API和注解支持,极大减少了手写SQL的工作量。它支持多种数据库(如MySQL、Oracle等),并具备分页查询、动态条件构造、乐观锁控制等功能,帮助开发者更高效地完成数据访问层的开发。

系统测试方案

为确保系统的稳定性和功能性,我们从多个角度对系统进行了全面测试。

登录功能测试

以下是针对登录模块设计的测试用例:

输入数据预期结果实际结果结果分析
用户名:admin 密码:123456 验证码:正确成功登录成功登录符合预期
用户名:admin 密码:错误密码 验证码:正确提示密码错误提示密码错误符合预期
用户名:admin 密码:123456 验证码:错误提示验证码错误提示验证码错误符合预期
用户名:空 密码:123456 验证码:正确提示用户名不能为空提示用户名不能为空符合预期
用户名:admin 密码:空 验证码:正确提示密码不能为空提示密码不能为空符合预期

用户管理功能测试

以下是针对用户管理模块设计的测试用例:

输入数据预期结果实际结果结果分析
填写完整用户信息添加成功,用户显示在列表中添加成功,用户显示在列表中符合预期
修改现有用户信息修改成功,用户信息更新修改成功,用户信息更新符合预期
删除用户系统询问是否确认删除,删除后用户不在列表中系统询问是否确认删除,删除后用户不在列表中符合预期
不填写用户名尝试添加提示用户名不能为空提示用户名不能为空符合预期
添加已存在的用户名提示用户名重复提示用户名重复符合预期

代码示例

登录接口实现


@RestController
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/login")
    public Result login(@RequestParam String username, 
                        @RequestParam String password, 
                        @RequestParam String captcha,
                        HttpServletRequest request) {
        User user = userService.findByUsername(username);
        if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
            return Result.fail("用户名或密码错误");
        }
        String token = jwtService.generateToken(user.getId(), user.getRole());
        return Result.success().addData("token", token);
    }
}

Token生成逻辑


@Service
public class JwtService {

    public String generateToken(Long userId, String role) {
        Calendar expiration = Calendar.getInstance();
        expiration.add(Calendar.HOUR_OF_DAY, 1);
        Map claims = new HashMap<>();
        claims.put("userId", userId);
        claims.put("role", role);
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(expiration.getTime())
                .signWith(SignatureAlgorithm.HS256, "secretKey")
                .compact();
    }
}

权限拦截器


@Component
public class AuthInterceptor implements HandlerInterceptor {

    private static final String AUTH_HEADER = "Authorization";

    @Autowired
    private JwtService jwtService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod method = (HandlerMethod) handler;
        if (method.getMethodAnnotation(IgnoreAuth.class) != null) {
            return true;
        }

        String authHeader = request.getHeader(AUTH_HEADER);
        if (StringUtils.isBlank(authHeader) || !authHeader.startsWith("Bearer ")) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }

        String token = authHeader.substring(7);
        try {
            Claims claims = jwtService.parseToken(token);
            request.setAttribute("userId", claims.get("userId"));
            request.setAttribute("role", claims.get("role"));
            return true;
        } catch (Exception e) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
    }
}

数据库结构


-- 用户Token表结构
DROP TABLE IF EXISTS `user_token`;
CREATE TABLE `user_token` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_id` bigint NOT NULL COMMENT '用户ID',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `role` varchar(50) DEFAULT NULL COMMENT '角色',
  `token` varchar(200) NOT NULL COMMENT 'Token值',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `expires_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '过期时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户Token表';

-- 示例数据
INSERT INTO `user_token` VALUES (1, 1, 'admin', '管理员', 'abc123def456ghi789', '2023-03-01 10:00:00', '2023-03-02 10:00:00');
标签: springbootVue

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。