基于JavaSpringBoot+Vue+uniapp实现微信掌上图书小程序

news2024/11/19 20:28:40

最近开发了一个基于JavaSpringBoot+Vue+uniapp实现微信掌上图书小程序,系统非常的nice。

文章目录

  • 1,系统技术简介
    • 1.1 Mysql数据库
    • 1.2SpringBoot框架
  • 2,系统功能介绍
    • 2.1 系统前台功能
    • 2.2 系统后台管理
    • 2.3 流程图和结构功能图
  • 3,系统界面演示
  • 4,系统核心代码演示

1,系统技术简介

1.1 Mysql数据库

目前世界上的数据数不胜数,而且更新迭代的速度非常的快,最为世界上最出名的两款关系型数据库MySQL和Oracle,由于Oracle数据库需要付费而且安装Oracle的成本比较高,越来越多的开发人员喜欢使用MySQL数据库进行工程中数据的存储,而且MySQl是一款可以免费试用的数据库,使用它不用担心版权的问题。部署起来也非常的方便,相比较于Oracle的部署时间简直不到Oracle部署的五分之一。正是由于MySQL种种优越的特性本系统开发所选择的数据库便是MySQL数据库,MySQL数据库部署之后不会占用非常对的内存与硬盘,但是MySQL的访问速度却非常的快,在多线程访问的情况下依旧可以保证其优越的性能,充分发挥计算机的CPU性能,不会进行一点的浪费。

1.2SpringBoot框架

后台开发框架选择的是SpringBoot框架,本框架是通过Spring4.0发展而来的,使用SpringBoot框架进行后台代码的开发可以显著地提升代码的开发效率,同时使用其依赖大于配置的思想,减少了传统的Spring框架非常多的配置文件与配置依赖。使用Springboot开发让系统后台变得更加简单,比如代码运行不需要安装Tomcat便可以完成程序的启动调试;让部署变得简单,使用SpringBoot开发的工程部署只需要几jdk便可以完成程序的启动;简化配置,在开发过程中不需要配置各种依赖各种注入,让开发人员更加注重于代码的编写,SpringBoot的种种优点促使本系统使用该框架进行开发。

2,系统功能介绍

2.1 系统前台功能

(1)首页展示:用户可以在首页进行图书种类的搜索(图书名、分类等),用户也可以进行注册(账号、密码、个人基本信息)和登录(注册成功后输入账号、密码)操作。
(2)图书展示:在进入系统主页面后,用户可以浏览主页面图书信息,首页为图书资讯推荐图书等,可以查看图书分类,查看图书基本信息,比如:图书封面、图书详情等。
(3)图书搜索:经过大体浏览首页之后,用户可以根据自己的喜好和需求输入图书名称或者关键词进行图书的检索。
(4)加入购物车:用户可以将自己所需要下单的图书加入购物车,也可对购物车中的图书进行查看、修改、删除等操作。
(5)我的订单:用户购买后可以查看我的订单,待支付、待发货、待收货、已完成的订单信息。
(6)图书资讯:用户可以登陆网上书城查看资讯信息。

2.2 系统后台管理

(1)管理员注册、登录。
(2)用户管理:管理员对用户的信息进行管理。
(3)图书管理:对图书进行分类管理、对图书的基本信息(名称、价格、图片、内容)进行增加、删除、修改,查看等操作。
(4)订单管理:对下单的信息进行更新管理、订单跟踪、发货管理等。
(5)图书资讯管理:对于小程序首页图书资讯进行管理,链接图书详情。

2.3 流程图和结构功能图

业务流程图是一种描述商 城内的管理信息流向,作业顺序和业务关系的流程图表。分析人员可以通过流程图分析出业务流程的不合理流向,及时发现和处理流程中的错误和潜在缺陷,调整和消除不合理的流程模块。功能结构图是对掌上书城微信小程序功能的分析,对功能列表结构进行详细描述,对其轮廓的逐步分解,从上到下绘制出来的结构图。

在这里插入图片描述

3,系统界面演示

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4,系统核心代码演示

package com.project.demo.controller;

import com.project.demo.entity.AccessToken;
import com.project.demo.service.AccessTokenService;

import com.project.demo.controller.base.BaseController;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

/**
 * 临时访问牌(AccessToken)表控制层
 *
 */
@RestController
@RequestMapping("access_token")
public class AccessTokenController extends BaseController<AccessToken, AccessTokenService> {
    /**
     * 服务对象
     */
    @Autowired
    public AccessTokenController(AccessTokenService service) {
        setService(service);
    }

}



package com.project.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.project.demo.entity.AccessToken;
import com.project.demo.entity.User;
import com.project.demo.entity.UserGroup;
import com.project.demo.service.AccessTokenService;
import com.project.demo.service.UserGroupService;
import com.project.demo.service.UserService;

import com.project.demo.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

/**
 * 用户账户:用于保存用户登录信息(User)表控制层
 */
@Slf4j
@RestController
@RequestMapping("user")
public class UserController extends BaseController<User, UserService> {
    /**
     * 服务对象
     */
    @Autowired
    public UserController(UserService service) {
        setService(service);
    }

    /**
     * Token服务
     */
    @Autowired
    private AccessTokenService tokenService;

    @Autowired
    private UserGroupService userGroupService;

    /**
     * 注册
     * @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);
    }

    /**
     * 找回密码
     * @param form
     * @return
     */
    @PostMapping("forget_password")
    public Map<String, Object> forgetPassword(@RequestBody User form,HttpServletRequest request) {
        JSONObject ret = new JSONObject();
        String username = form.getUsername();
        String code = form.getCode();
        String password = form.getPassword();
        // 判断条件
        if(code == null || code.length() == 0){
            return error(30000, "验证码不能为空");
        }
        if(username == null || username.length() == 0){
            return error(30000, "用户名不能为空");
        }
        if(password == null || password.length() == 0){
            return error(30000, "密码不能为空");
        }

        // 查询用户
        Map<String, String> query = new HashMap<>();
        query.put("username",username);
        Query select = service.select(query, service.readConfig(request));
        List list = select.getResultList();
        if (list.size() > 0) {
            User o = (User) list.get(0);
            JSONObject query2 = new JSONObject();
            JSONObject form2 = new JSONObject();
            // 修改用户密码
            query2.put("user_id",o.getUserId());
            form2.put("password",service.encryption(password));
            service.update(query, service.readConfig(request), form2);
            return success(1);
        }
        return error(70000,"用户不存在");
    }

    /**
     * 登录
     * @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, "账号或密码不正确");
        }
    }

    /**
     * 修改密码
     * @param data
     * @param request
     * @return
     */
    @PostMapping("change_password")
    public Map<String, Object> change_password(@RequestBody Map<String, String> data, HttpServletRequest request){
        // 根据Token获取UserId
        String token = request.getHeader("x-auth-token");
        Integer userId = tokenGetUserId(token);
        // 根据UserId和旧密码获取用户
        Map<String, String> query = new HashMap<>();
        String o_password = data.get("o_password");
        query.put("user_id" ,String.valueOf(userId));
        query.put("password" ,service.encryption(o_password));
        Query ret = service.count(query, service.readConfig(request));
        List list = ret.getResultList();
        Object s = list.get(0);
        int count = Integer.parseInt(list.get(0).toString());
        if(count > 0){
            // 修改密码
            Map<String,Object> form = new HashMap<>();
            form.put("password",service.encryption(data.get("password")));
            service.update(query,service.readConfig(request),form);
            return success(1);
        }
        return error(10000,"密码修改失败!");
    }

    /**
     * 登录态
     * @param request
     * @return
     */
    @GetMapping("state")
    public Map<String, Object> state(HttpServletRequest request) {
        JSONObject ret = new JSONObject();
        // 获取状态
        String token = request.getHeader("x-auth-token");

        // 根据登录态获取用户ID
        Integer userId = tokenGetUserId(token);

        log.info("[返回userId] {}",userId);
        if(userId == null || userId == 0){
            return error(10000,"用户未登录!");
        }

        // 根据用户ID获取用户
        Map<String,String> query = new HashMap<>();
        query.put("user_id" ,String.valueOf(userId));

        // 根据用户ID获取
        Query select = service.select(query,service.readConfig(request));
        List resultList = select.getResultList();
        if (resultList.size() > 0) {
            JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(resultList.get(0)));
            user.put("token",token);
            ret.put("obj",user);
            return success(ret);
        } else {
            return error(10000,"用户未登录!");
        }
    }

    /**
     * 登录态
     * @param request
     * @return
     */
    @GetMapping("quit")
    public Map<String, Object> quit(HttpServletRequest request) {
        String token = request.getHeader("x-auth-token");
        JSONObject ret = new JSONObject();
        Map<String, String> query = new HashMap<>(16);
        query.put("token", token);
        try{
            tokenService.delete(query,service.readConfig(request));
        }catch (Exception e){
            e.printStackTrace();
        }
        return success("退出登录成功!");
    }

    /**
     * 获取登录用户ID
     * @param token
     * @return
     */
    public Integer tokenGetUserId(String token) {
        log.info("[获取的token] {}",token);
        // 根据登录态获取用户ID
        if(token == null || "".equals(token)){
            return 0;
        }
        Map<String, String> query = new HashMap<>(16);
        query.put("token", token);
        AccessToken byToken = tokenService.findOne(query);
        if(byToken == null){
            return 0;
        }
        return byToken.getUser_id();
    }

    /**
     * 重写add
     * @return
     */
    @PostMapping("/add")
    @Transactional
    public Map<String, Object> add(HttpServletRequest request) throws IOException {
        Map<String,Object> map = service.readBody(request.getReader());
        map.put("password",service.encryption(String.valueOf(map.get("password"))));
        service.insert(map);
        return success(1);
    }

}

package com.project.demo.controller;

import com.project.demo.entity.OrdinaryUsers;
import com.project.demo.service.OrdinaryUsersService;
import com.project.demo.controller.base.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 普通用户:(OrdinaryUsers)表控制层
 *
 */
@RestController
@RequestMapping("/ordinary_users")
public class OrdinaryUsersController extends BaseController<OrdinaryUsers, OrdinaryUsersService> {

    /**
     * 普通用户对象
     */
    @Autowired
    public OrdinaryUsersController(OrdinaryUsersService service) {
        setService(service);
    }

    @PostMapping("/add")
    @Transactional
    public Map<String, Object> add(HttpServletRequest request) throws IOException {
        Map<String,Object> paramMap = service.readBody(request.getReader());
        this.addMap(paramMap);
        return success(1);
    }

}


好了,整理结束,小伙伴们点赞、收藏、评论,一键三连走起呀,下期见~~

最后,我更新了大量的资料,都分享下,点击下面的,回复:项目大全

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

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

相关文章

HydroD 实用教程(八)频域水动力分析

目 录 一、前言二、前处理三、定义/提交作业3.1 创建分析作业3.2 定义分析工况3.3 配置分析选项3.4 设置输出文件3.5 提交求解计算 四、输出文件4.1 Hydrodynamic Results Interface File4.2 Loads Interface File4.3 Analysis Control Data File for Structural Analysis4.4 W…

导线舞动的防范措施

输电线路导线舞动在线监测装置 一、产品描述&#xff1a; 导线舞动幅度过大会导致铁塔等设施发生形变&#xff0c;严重的可能会发生铁塔坍塌&#xff0c;倒塔挂线&#xff0c;进而导致电力系统瘫痪&#xff0c;威胁到电力供应系统的稳定性&#xff0c;电力供应系统的稳定需要保…

SCSI介绍和SCSI命令承载于各类总线的方式

1. SCSI协议简介 小型计算机系统接口(SCSI&#xff0c;Small Computer System Interface&#xff09;是一种用于计算机及其周边设备之间&#xff08;硬盘、软驱、光驱、打印机、扫描仪等&#xff09;系统级接口的独立处理器标准。虽然名字里面带个接口&#xff0c;但实际上是一…

文本三剑客-Sed

sed工作原理 sed的特点&#xff1a; sed基本语法 模式空间中的编辑操作---地址定界 常用编辑命令 增添&#xff08;a&#xff09; 追加&#xff08;i&#xff09; 删除&#xff08;d&#xff09; 读入文件&#xff08;r&#xff09; 固定长度替换&#xff08;y&#xff0…

ChatGPT:你真的了解网络安全吗?浅谈网络安全攻击防御进行时之网络攻击新威胁

ChatGPT&#xff1a;你真的了解网络安全吗&#xff1f;浅谈网络安全攻击防御进行时 网络攻击新威胁1) 人工智能的应用2) 5G和物联网的崛起3) 云安全4) 社交工程的威胁 ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国…

Netlogo学习笔记

第一行&#xff1a;国际惯例咕咕咕。 第二行&#xff1a;人工势场这个概念好神奇&#xff08;虽然我觉得就是强行捏了一个高大上的词 第三行&#xff1a;希望全天下的软件都能把要用的东西集成成库&#xff0c;然后只需要无脑点点就可以了&#xff08;我本人&#xff1a;又懒…

day14 HTTPServlet

HTTP协议 含义&#xff1a;是TCP、IP协议之上的应用层协议 作用&#xff1a;规定浏览器和服务器数据之间的交互格式 注意&#xff1a;该协议的端口为80&#xff0c;Tomcat是8080 http的特点 1.无状态&#xff0c;无记忆 2.“1.0”版本需要多次请求和响应&#xff0c;1.1一…

CentOS 7 离线安装MySQL

MySQL下载官网&#xff1a; https://downloads.mysql.com/archives/community/ 文章使用的MySQL版本下载地址&#xff1a; https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz 一、卸载旧的mysql 1、删除MySQL的安装文件 [rootwww ~]# …

软件设计师 计算机网络

名字带IP AP的都是网络层 所有带T的除了TFTP其他都是TCP&#xff0c;所有不带T的除了POP3其他都是UDP​ **物理层的互联设备有中继器和集线器&#xff0c;集线器是一种特殊的多路多端口中继器 网络层&#xff1a;路由器 物理层&#xff1a;中继器 数据链路层&#xff1a;网桥…

推动解决新能源电车充电不便的难题

安科瑞虞佳豪 新一轮科技革命和产业变革的蓬勃发展&#xff0c;加速了汽车与能源、交通、信息通信等领域的深度融合&#xff0c;汽车产业朝着电动化、智能化、网联化方向前行&#xff0c;新能源汽车产业迎来了前所未有的发展机遇。花生好车紧跟发展潮流和趋势&#xff0c;大力…

数据结构:二叉树的顺序结构--堆

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下栈和队列方面的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通…

代码随想录算法训练营day50 | 123.买卖股票的最佳时机III,188.买卖股票的最佳时机IV

代码随想录算法训练营day50 | 123.买卖股票的最佳时机III&#xff0c;188.买卖股票的最佳时机IV 123.买卖股票的最佳时机III解法一&#xff1a;动态规划 188.买卖股票的最佳时机IV解法一&#xff1a;动态规划 总结 123.买卖股票的最佳时机III 教程视频&#xff1a;https://www…

【NovelAI 小说SD批量生成 视频克隆】环境配置和使用方法

【样品】《我在东北立堂口》图生图半自动版SD一键成片 操作步骤&环境配置地址&#xff1a; 【NovelAI】月产10000全自动批量原创小说短视频支持文生图和视频克隆 该文章面向购买脚本的付费用户&#xff0c;提供所有问题以及解决办法。使用 notepad 打开对应的文件即可&…

光敏晶体管(ALS-PT19-315C/L177/TR8) 光照度和电压,电流关系分析.

背景 当我们使用光敏晶体管进行,测算光照度时,大多使用ADC电路测到电压. 那么怎么根据这个电压计算出对应具体的光照度呢? 下面将以 ALS-PT19-315C/L177/TR8 型号的 光敏晶体管为例,来进行分析介绍,并给出 如何根据最大光照度范围 选定合适的电阻和电容. 1,直接看数据手册给…

如何快速录制电脑屏幕?教您一键录屏的3种方法!

案例&#xff1a;如何快速录制电脑屏幕&#xff1f; 【打开录屏工具录制电脑屏幕&#xff0c;需要耗费一定的时间。有没有方法可以快速打开电脑录屏工具&#xff0c;实现一键录屏&#xff1f;】 随着互联网的发展和普及&#xff0c;电脑屏幕录制已经成为了一项必要的工作技能…

R语言实践——rWCVP入门

rWCVP入门 介绍1. 访问到WCVP1.1 方法一1.2 方法二&#xff08;谨慎&#xff09; 2. WCVP数据筛选2.1 关于按分类单元筛选的说明2.2 关于按分布区域筛选的说明 笔者实践 介绍 世界维管植物名录&#xff08;WCVP&#xff09;是维管植物物种的全球共识。它提供了科学已知的> …

Flink用户自定义连接器(Table API Connectors)学习总结

文章目录 前言背景官网文档概述元数据解析器运行时的实现 自定义扩展点工厂类Source扩展Sink和编码与解码 自定义flink-http-connectorSQL示例具体代码pom依赖HttpTableFactoryHttpTableSourceHttpSourceFunctionHttpClientUtil 最后参考资料 前言 结合官网文档和自定义实现一…

Leetcode | 1534 统计好三元组

1534 统计好三元组 文章目录 [1534 统计好三元组](https://leetcode.cn/problems/count-good-triplets/description/)题目解法1 暴力穷举解法2 枚举优化 题目 给你一个整数数组 arr &#xff0c;以及 a、b 、c 三个整数。请你统计其中好三元组的数量。 如果三元组 (arr[i], a…

怎么把录音转文字?推荐你这三款工具

随着科技不断发展&#xff0c;录音转文字的技术也逐渐被广泛应用于各种场景中。其中最常见的一种就是会议记录。在日常工作中&#xff0c;会议是企业和组织中必不可少的一个环节&#xff0c;但在会议过程中的录音和记录往往需要花费大量的时间和精力。这个时候&#xff0c;我们…

【AI聊天丨 ChatGPT应用案例一】— 仅用30分钟,ChatGPT帮你完成专利交底书!

Hi&#xff0c;大家好&#xff0c;我是零点壹客&#xff0c;今天主要也是想和大家一起唠唠ChatGPT&#xff0c; 尤其这两个月&#xff0c;ChatGPT出奇的火&#xff0c;想必各位圈友们或多或少的都已经有些了解。 ChatGPT的出现很大程度上已经改变了我们的工作方式&#xff0c;尤…