SpringBoot+Vue项目流浪狗领养管理系统的设计与实现

news2025/8/7 5:57:39

文末获取源码

开发语言:Java

使用框架:spring boot

前端技术:JavaScript、Vue 、css3

开发工具:IDEA/MyEclipse/Eclipse、Visual Studio Code

数据库:MySQL 5.7/8.0

数据库管理工具:phpstudy/Navicat

JDK版本:jdk1.8

Maven:apache-maven 3.8.1-bin

目录

一、前言介绍 

二、功能需求分析

2.1用户功能

2.2管理员功能

三、前台用户功能

3.1用户首页模块

3.2交流中心模块

3.3宠物知识模块 

3.4领养信息模块

3.5领养详情

四、管理员功能模块

4.1用户管理模块

4.2宠物知识管理模块 

4.3领养信息管理模块 

4.4领养记录管理模块

4.5回访记录管理模块 

五、部分核心代码

5.1领养记录管理的关键代码 

5.2登录界面关键代码

5.3用户注册关键代码


一、前言介绍 

本系统前端部分基于MVVM模式进行开发,采用B/S模式,后端部分基于Java的springboot框架进行开发。

前端部分:前端框架采用了比较流行的渐进式JavaScript框架Vue.js。使用Vue-Router和Vuex实现动态路由和全局状态管理,Ajax实现前后端通信,Element UI组件库,使页面快速成型,项目前端通过栅格布局实现响应式,可适应PC端、平板端、手机端等不同屏幕大小尺寸的完美布局展示。

后端部分:采用springboot作为开发框架,同时集成MyBatis、Redis等相关技术。

本文以springboot为开发技术,实现了一个流浪狗领养管理。流浪狗领养管理的主要使用者分为用户、管理员;管理员功能包括有:首页、领养信息、领养记录、回访记录、分类管理;前台首页功能包括有:首页、交流中心、公告消息、宠物知识、领养信息等功能。通过这些功能模块的设计,基本上实现了整个流浪狗领养管理的过程。

二、功能需求分析

流浪狗领养管理系统主要是为了更加地完善流浪狗领养情况,对用户的信息、领养信息、领养记录、回访记录、分类管理等提供了方便的机制。本系统有多类使用者,分别是管理员和普通用户。以下是从这两种用户的角度分别介绍本系统所要实现的功能。

2.1用户功能

注册:首先检查用户名和邮箱是否存在,如不存在即可进行注册,并将用户输入的密码进行MD5加密,注册成功后提示注册成功,并将用户信息保存到数据库中。

登录:使用流浪狗领养管理系统前是需要用户登录个人账号。

宠物知识:用户进行宠物知识的阅览,查看管理员发布的宠物知识信息。

交流中心:用户在交流论坛这一菜单下对用户在线交流的查看、同时也可以发布、评论。

领养信息:用户对宠物信息的查询,包括标题名称、宠物状态、宠物名称、宠物性别。

2.2管理员功能

用户管理:对用户进行管理,用户的注册,包括用户昵称、用户名、用户的宠物信息(宠物状态、宠物名称、宠物性别等)用户的账号信息:

领养记录管理:对领养记录进行维护管理。

宠物信息管理:对宠物信息进行维护管理。

回访记录管理:对宠物的回访记录信息进行维护管理。

三、前台用户功能

3.1用户首页模块

3.2交流中心模块

3.3宠物知识模块 

3.4领养信息模块

3.5领养详情

四、管理员功能模块

4.1用户管理模块

4.2宠物知识管理模块 

4.3领养信息管理模块 

4.4领养记录管理模块

4.5回访记录管理模块 

五、部分核心代码

5.1领养记录管理的关键代码 

  @PostMapping("/add")

    @Transactional

    public Map<String, Object> add(HttpServletRequest request) throws IOException {

        service.insert(service.readBody(request.getReader()));

        return success(1);

    }

    @Transactional

    public Map<String, Object> addMap(Map<String,Object> map){

        service.insert(map);

        return success(1);

}

    public Map<String,Object> readBody(BufferedReader reader){

        BufferedReader br = null;

        StringBuilder sb = new StringBuilder("");

        try{

            br = reader;

            String str;

            while ((str = br.readLine()) != null){

                sb.append(str);

            }

            br.close();

            String json = sb.toString();

            return JSONObject.parseObject(json, Map.class);

        }catch (IOException e){

            e.printStackTrace();

        }finally{

            if (null != br){

                try{

                    br.close();

                }catch (IOException e){

                    e.printStackTrace();

                }

            }

        }

        return null;

}

    public void insert(Map<String,Object> body){

        StringBuffer sql = new StringBuffer("INSERT INTO ");

        sql.append("`").append(table).append("`").append(" (");

        for (Map.Entry<String,Object> entry:body.entrySet()){

            sql.append("`"+humpToLine(entry.getKey())+"`").append(",");

        }

        sql.deleteCharAt(sql.length()-1);

        sql.append(") VALUES (");

        for (Map.Entry<String,Object> entry:body.entrySet()){

            Object value = entry.getValue();

            if (value instanceof String){

                sql.append("'").append(entry.getValue()).append("'").append(",");

            }else {

                sql.append(entry.getValue()).append(",");

            }

        }

        sql.deleteCharAt(sql.length() - 1);

        sql.append(")");

        log.info("[{}] - 插入操作:{}",table,sql);

        Query query = runCountSql(sql.toString());

        query.executeUpdate();

    }

5.2登录界面关键代码

   * 登录

     * @param data

     * @param httpServletRequest

     * @return

     */

    @PostMapping("login")

    public Map<String, Object> login(@RequestBody Map<String, String> data, HttpServletRequest httpServletRequest) {

        log.info("[执行登录接口]");

        String username = data.get("username");

        String email = data.get("email");

        String phone = data.get("phone");

        String password = data.get("password");

        List resultList = null;

        Map<String, String> map = new HashMap<>();

        if(username != null && "".equals(username) == false){

            map.put("username", username);

            resultList = service.select(map, new HashMap<>()).getResultList();

        }

        else if(email != null && "".equals(email) == false){

            map.put("email", email);

            resultList = service.select(map, new HashMap<>()).getResultList();

        }

        else if(phone != null && "".equals(phone) == false){

            map.put("phone", phone);

            resultList = service.select(map, new HashMap<>()).getResultList();

        }else{

            return error(30000, "账号或密码不能为空");

        }

        if (resultList == null || password == null) {

            return error(30000, "账号或密码不能为空");

        }

        //判断是否有这个用户

        if (resultList.size()<=0){

            return error(30000,"用户不存在");

        }

        User byUsername = (User) resultList.get(0);

        Map<String, String> groupMap = new HashMap<>();

        groupMap.put("name",byUsername.getUserGroup());

        List groupList = userGroupService.select(groupMap, new HashMap<>()).getResultList();

        if (groupList.size()<1){

            return error(30000,"用户组不存在");

        }

        UserGroup userGroup = (UserGroup) groupList.get(0);

        //查询用户审核状态

        if (!StringUtils.isEmpty(userGroup.getSourceTable())){

            String sql = "select examine_state from "+ userGroup.getSourceTable() +" WHERE user_id = " + byUsername.getUserId();

            String res = String.valueOf(service.runCountSql(sql).getSingleResult());

            if (res==null){

                return error(30000,"用户不存在");

            }

            if (!res.equals("已通过")){

                return error(30000,"该用户审核未通过");

            }

        }

        //查询用户状态

        if (byUsername.getState()!=1){

            return error(30000,"用户非可用状态,不能登录");

        }

        String md5password = service.encryption(password);

        if (byUsername.getPassword().equals(md5password)) {

            // 存储Token到数据库

            AccessToken accessToken = new AccessToken();

            accessToken.setToken(UUID.randomUUID().toString().replaceAll("-", ""));

            accessToken.setUser_id(byUsername.getUserId());

            tokenService.save(accessToken);

            // 返回用户信息

            JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(byUsername));

            user.put("token", accessToken.getToken());

            JSONObject ret = new JSONObject();

            ret.put("obj",user);

            return success(ret);

        } else {

            return error(30000, "账号或密码不正确");

        }

}

5.3用户注册关键代码

/**

     * 注册

     * @param user

     * @return

     */

    @PostMapping("register")

    public Map<String, Object> signUp(@RequestBody User user) {

        // 查询用户

        Map<String, String> query = new HashMap<>();

        query.put("username",user.getUsername());

        List list = service.select(query, new HashMap<>()).getResultList();

        if (list.size()>0){

            return error(30000, "用户已存在");

        }

        user.setUserId(null);

        user.setPassword(service.encryption(user.getPassword()));

        service.save(user);

        return success(1);

}

/**

     * 用户ID:[0,8388607]用户获取其他与用户相关的数据

     */

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column(name = "user_id")

    private Integer userId;

    /**

     * 账户状态:[0,10](1可用|2异常|3已冻结|4已注销)

     */

    @Basic

    @Column(name = "state")

    private Integer state;

    /**

     * 所在用户组:[0,32767]决定用户身份和权限

     */

    @Basic

    @Column(name = "user_group")

    private String userGroup;

    /**

     * 上次登录时间:

     */

    @Basic

    @Column(name = "login_time")

    private Timestamp loginTime;

    /**

     * 手机号码:[0,11]用户的手机号码,用于找回密码时或登录时

     */

    @Basic

    @Column(name = "phone")

    private String phone;

    /**

     * 手机认证:[0,1](0未认证|1审核中|2已认证)

     */

    @Basic

    @Column(name = "phone_state")

    private Integer phoneState;

    /**

     * 用户名:[0,16]用户登录时所用的账户名称

     */

    @Basic

    @Column(name = "username")

    private String username;

    /**

     * 昵称:[0,16]

     */

    @Basic

    @Column(name = "nickname")

    private String nickname;

    /**

     * 密码:[0,32]用户登录所需的密码,由6-16位数字或英文组成

     */

    @Basic

    @Column(name = "password")

    private String password;

    /**

     * 邮箱:[0,64]用户的邮箱,用于找回密码时或登录时

     */

    @Basic

    @Column(name = "email")

    private String email;

    /**

     * 邮箱认证:[0,1](0未认证|1审核中|2已认证)

     */

    @Basic

    @Column(name = "email_state")

    private Integer emailState;

    /**

     * 头像地址:[0,255]

     */

    @Basic

    @Column(name = "avatar")

    private String avatar;

    /**

     * 创建时间:

     */

    @Basic

    @Column(name = "create_time")

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

    private Timestamp createTime;

    @Basic

    @Transient

    private String code;

}

 

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

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

相关文章

图像运算和图像增强十

图像运算和图像增强十 图像锐化之 Sobel、Laplacian 算子实现边缘检测 &#xff08;1&#xff09;Sobel算子(一阶微分算子) Sobel算子是一种用于边缘检测的离散微分算子&#xff0c;它结合了高斯平滑和微分求导。该算子用于计算图像明暗程度近似值&#xff0c;根据图像边缘旁…

top命令应用(查看进程实时动态信息)

记录&#xff1a;321 场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;top命令是查看进程实时动态信息工具。查看进程状态、进程使用内存状况、进程使用CPU状况、进程PID等。 版本&#xff1a; 操作系统&#xff1a;CentOS 7.9 1.top命令介绍 top命令&#xff0c;查看…

内存、指针与数组

C语言的指针可以当成一个特殊的数据类型&#xff08;像int一样的数据类型&#xff09;&#xff0c;可以说其唯一的作用就是为了存储地址&#xff0c;其他的都可以当作它的衍生用法。 指针的诸多功能都是基于其能直接操作指定内存空间存储的值&#xff0c;每个程序运行都会由操作…

git新建仓库提交项目代码+常用命令

一&#xff1a;新建仓库 输入一下仓库名称&#xff0c;归属和路径都是生成的不需要自己去编辑 点击创建就创建了一个新的仓库&#xff0c;下面就是仓库刚创建好的样子 二&#xff1a;向仓库里提交项目代码 首先打开你要提交的项目文件&#xff1a; 根据官方的提示去提交代码&…

Linux:shell编程2(内含:1.设置环境变量+2.位置参数变量+3.预定义变量+运算符+4.条件判断)

写在开头&#xff1a; 小技巧&#xff1a;除了赋值不加空格&#xff0c;其他的&#xff0c;例如是[ ] ()等都需要空格&#xff01; 1.设置环境变量&#xff1a; 注&#xff1a;类似于C语言全局变量 案例1&#xff1a;在/etc/profile文件中定义TOMCAT_HOME环境变量。 解释&…

洛谷 模拟 普及-

文章目录&#x1f4a5;前言&#x1f609;解题报告&#x1f4a5;一、快乐水&#x1f914;一、题意及思路:&#x1f60e;二、源码&#xff1a;&#x1f62e;三、代码分析&#xff1a;&#x1f4a5;二、漂亮的绝杀&#x1f914;一、题意及思路:&#x1f60e;二、源码&#xff1a;&…

小学生python游戏编程arcade----坦克大战2

小学生python游戏编程arcade----坦克大战2前言多摄象头显得分&#xff0c;title地图加载&#xff0c;精灵分层管理&#xff0c;移动精灵1、提示框制作1.1养眼绿色1.2 画距形提示框1.3 效果图1.4 提示框加提示2、子弹计数问题2.1 初始时给一定的子弹量2.2 发射子弹时进行控制2.3…

hevc 半像素

1 分数像素精度运动估计 物体在连续帧间的运动是连续的&#xff0c;而像素本身是离散的&#xff0c;这种现象带来了一个问题&#xff0c;当前帧中图像块的最佳参考块不一定位于参考帧的证书像素点位置&#xff0c;为了更加精确的预测当前带编码的图像块&#xff0c;有必要在非整…

海运整柜出口操作流程有哪些注意事项?

货物运输时&#xff0c;海运是一种非常常见的形式&#xff0c;根据货物的不同&#xff0c;海运也有很多形式的货物装运&#xff0c;海运整柜就是其中之一。 海运整柜大致分为20GP/40/GP/40HQ。是指只有一个发货人将整箱货物运到目的港&#xff0c;比较容易竞争。发货人负责装箱…

IntentService 源码理解

一、概述 本篇文章讲解的是分析IntentService源码并使用&#xff0c;安卓API迭代更新的太快&#xff0c;IntentService已经在Android8.0 (API 26)之后就不推荐使用了&#xff0c;在Android API 30正式弃用&#xff0c;官方建议用JobIntentService 或 WorkManager替代&#xff0…

为什么要少用全局变量

为什么要少用全局变量&#xff1f;甚至有些公司禁止用全局变量。有一个说法是这样的&#xff0c;全局变量的最佳前缀是什么&#xff1f;答&#xff1a;// 接下来就粗略说说这个问题。 1、全局变量和局部变量 &#xff08;1&#xff09;全局变量&#xff1a;定义在函数外&…

RocketMQ NameServer 概览

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2022年11月18日 &#…

析构函数详解

析构函数1.概念与特性2.工作原理4.析构的顺序如果一个类中什么成员都没有&#xff0c;那么该类简称为空类。而空类中其实并不是真的什么都没有&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。构造函数&#xff1a;主要完成初始化工作析构函…

内网渗透神器CobaltStrike之配置与基础操作(一)

CobaltStrike简介 Cobalt Strike: C/S架构的商业渗透软件&#xff0c;适合多人进行团队协作&#xff0c;可模拟APT做模拟对抗&#xff0c;进行内网渗透。 Cobalt Strike 一款GUI的框架式渗透工具&#xff0c;集成了端口转发、服务扫描&#xff0c;自动化溢出&#xff0c;多模…

megahit源码迁移解析

megahit源码迁移大作业 在进行megahit源码迁移前需要清理自己的实验环境 1、链接鲲鹏服务器 2、进入源码存放地址/opt/portadv/portadmin/sourcecode 环境准备&#xff0c;清理之前实验环境后下载本次实验所需的源码 之前存在的其他文件&#xff0c;删除code 登录代码迁移工…

Python常见操作的时间复杂度

Python常见操作的时间复杂度 本文整理了Python中常见数据结构操作的时间复杂度&#xff0c;旨在帮助大家了解Python操作的性能&#xff0c;协助运行更快的代码。 文章目录标注方法List操作Set操作Deque操作标注方法 程序时间复杂度一般用"大O表示法&#xff08;Big-O no…

windows11系统WSL2安装ubuntu20.04桌面

文章目录1. MobaXterm安装2.WSL安装xfce desktop3. 连接桌面参考链接1. MobaXterm安装 这个比较简单&#xff0c;没介绍 2.WSL安装xfce desktop 安装命令 sudo apt-get install xfce4-terminal sudo apt-get install xfce4安装完之后需要稍微配置一下&#xff1a; export …

【并发编程六】c++进程通信——信号量(semaphore)

【并发编程六】c进程通信——信号量&#xff08;semaphore&#xff09;一、概述二、信号量三、原理四、过程1、进程A过程2、进程B过程五、demo1、进程A2、进程B六、输出七、windows api介绍1. 创建信号量 CreateSemaphore()2. 打开信号量 OpenSemaphore()3. 等待 WaitForSingle…

力扣LeatCode算法题第三题-无重复字符的最长子串

要求&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 我一开始采用的第一种方法是使用hashmap去比对大小&#xff0c;在idea上可以跑通程序&#xff0c;但在leatcode的编译器中&#xff0c;无法通过字符串s"" 和s"…

苹果推送和开发证书更新

1.背景 推送证书&#xff08;生产Apple Push Services和开发APNs Development iOS&#xff09;的有效期都是一年&#xff0c;将要过期的时候&#xff0c;苹果官方会发邮件提醒。 2.csr和推送证书更新 打开mac电脑&#xff0c;找到启动台-->其他&#xff0c;打开钥匙串访问。…