校园商铺1.0版本

cd4356
GitHub项目地址https://github.com/CD4356/o2o



项目核心技术栈

  • 前端:前端UI库SUI Mobile, Ajax,jQuery
  • 后端:SSM框架,Kaptcha验证码组件,Thumbnailator图片开源工具
  • 数据库:MySQL
  • 缓存:Redis


项目核心功能模块

  • 前台展示系统

    • 注册,登录登出
    • 首页模板数据填充开发
    • 店铺列表页开发
    • 店铺详情页开发
    • 商品详情页开发
    • 消费记录页开发
    • 我的积分,积分兑换
    • 密码修改,账号绑定
    • 顾客信息展示
    • 组合搜索功能开发
  • 商家管理系统

    • 商户入驻申请
    • 店铺列表页开发(一个商家可以注册多家店铺)
    • 店铺编辑页开发(店铺注册、店铺信息修改)
    • 商品类别管理
    • 商品列表页开发(编辑、上下架、前台预览)
    • 商品编辑页开发(添加商品、修改商品信息)
    • 权限验证
  • 超级管理员系统

    • 头条管理
    • 店铺类别管理
    • 区域信息管理
    • 新店铺审核列表
    • 入驻商家信息管理
    • 用户管理(普通用户、商家)
    • 权限验证


开发环境

  • idea 2018.12
  • jdk 1.8
  • mysql 5.7.17
  • maven 3.3.9
  • tomcat 9.0.16

不一定要一致,你的机器上原本测试能用即可



友情提示SUI Mobile 是一套基于 Framework7 开发的UI库。它非常轻量、精美,只需要引入我们的CDN文件就可以使用。但由于项目开发团队的核心成员已经离开阿里,项目没有得到更新、无人维护,里面有很多坑。所以使用时要注意哦,别挖坑把队友都给埋了哈!!!


前台展示系统Git图:

cd4356


店家管理系统Git图:

  

cd4356


由于内容过多,所以不会全部展示,下面主要介绍项目中使用到的组件和工具,以及一些可能会忽略的细节。


Kaptcha验证码组件

kaptcha是一款非常实用的验证码生成工具,在没有手机短信验证的前提下,使用kaptcha将是一个很好的选择。kaptcha可以通过配置生成多样化的验证码,验证码以图片形式存在,无法进行黏贴复制的哦!
在账号注册,店铺注册和修改、商品注册和修改等都需要用到验证码哈!!

1、pom.xml文件中引入Kaptcha依赖

<!--验证码-->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

2、web.xml文件中对验证码相关属性进行配置

<!-- 验证码相关属性的配置 -->
<servlet>
    <servlet-name>Kaptcha</servlet-name>
    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
    <!-- 定义 Kaptcha 的样式 -->
    <!-- 是否有边框 -->
    <init-param>
        <param-name>kaptcha.border</param-name>
        <param-value>no</param-value>
    </init-param>
    <!-- 字体颜色 -->
    <init-param>
        <param-name>kaptcha.textproducer.font.color</param-name>
        <param-value>red</param-value>
    </init-param>
    <!-- 图片宽度 -->
    <init-param>
        <param-name>kaptcha.image.width</param-name>
        <param-value>135</param-value>
    </init-param>
    <!-- 图片高度 -->
    <init-param>
        <param-name>kaptcha.image.height</param-name>
        <param-value>50</param-value>
    </init-param>
    <!-- 使用哪些字符生成验证码 -->
    <init-param>
        <param-name>kaptcha.textproducer.char.string</param-name>
        <param-value>ACDEFHKPRSTWX3456975</param-value>
    </init-param>
    <!-- 字体大小 -->
    <init-param>
        <param-name>kaptcha.textproducer.font.size</param-name>
        <param-value>43</param-value>
    </init-param>
    <!-- 干扰线的颜色 -->
    <init-param>
        <param-name>kaptcha.noise.color</param-name>
        <param-value>black</param-value>
    </init-param>
    <!-- 字符个数 -->
    <init-param>
        <param-name>kaptcha.textproducer.char.length</param-name>
        <param-value>4</param-value>
    </init-param>
    <!-- 字体 -->
    <init-param>
        <param-name>kaptcha.textproducer.font.names</param-name>
        <param-value>Arial</param-value> <!--Arial是宋体字-->
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>Kaptcha</servlet-name>
    <!-- 外部访问路径,即当访问/Kaptcha这个url时使用这个servlet处理 -->
    <url-pattern>/Kaptcha</url-pattern>
</servlet-mapping>

3、在html中添加验证码控件,并设置点击更新验证码的设置

<!-- 验证码 kaptcha -->
<div class="item-inner">
    <div class="item-title label">验证码</div>
    <input type="text" id="j_captcha" placeholder="验证码">
    <div class="item-input">
        <img id="captcha_img" alt="点击更换" title="点击更换"
             onclick="changeVerifyCode(this)" src="../Kaptcha"/>
    </div>
</div>

4、在共有js文件common.js中,定义点击更新验证码的方法

function changeVerifyCode(img) {
    img.src = "../Kaptcha?" + Math.floor(Math.random() * 100);
}

5、获取前端数据,并传输至后端

$(function () {

    $('#submit').click(function() {
        // 获取输入的帐号
        var username = $('#username').val();
        // 获取输入的密码
        var password = $('#password').val();
        // 获取表单输入的验证码
        var verifyCode = $('#j_captcha').val();
        // 判断输入的验证码是否为空
        if(!verifyCode){
            $.toast('请输入验证码!');
            return;
        }

        // 访问后台,绑定帐号
        $.ajax({
            url: '/o2o/local/account_bind', //请求地址
            type: "post", //指定Ajax请求方式
            data: {
                username : username,
                password : password,
                verifyCode : verifyCode
            }, //传输至后台的数据(json对象)
            dataType: 'json', //指定服务器返回的数据类型
            success: function(data) {
            	//判断请求是否成功处理
                if (data.success) {
                	//toast是一种轻量的提示,在页面中间显示,并且会在2秒(默认值,可修改)之后自动消失
                    $.toast('绑定成功!');
                    window.location.href = '/o2o/shop_admin/shop_list';
                } else {
                    $.toast('绑定失败!' + data.errMsg);
                    $('#captcha_img').click(); //绑定失败则刷新验证码
                }
            }
        });
    });

});

6、后端对应的路由方法接收数据,并进行处理

@RequestMapping("/account_bind")
@ResponseBody //@ResponseBody注解会将这个方法的返回值转换为JSON类型数据,返回到response中,可以抽象理解成response.getWriter.write(JSON.toJSONString(map));
private Map<String,Object> addLocalAccount(HttpServletRequest request){
    Map<String,Object> map = new HashMap<String, Object>();
    //验证码校验
    if(!VerifyCodeUtil.checkVerifyCode(request)){
        map.put("success",false);
        map.put("errorMsg","验证码错误!");
        return map;
    }
    map.put("success",true);
    return map;
}

7、后端处理验证码的方法(该方法封装在VerifyCodeUtil 工具类中)

import com.google.code.kaptcha.Constants;

import javax.servlet.http.HttpServletRequest;

public class VerifyCodeUtil {

    public static boolean checkVerifyCode(HttpServletRequest request){
        //获取生产的验证码
        String verifyCodeGenerated = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        //获取实际提交的验证码
        String verifyCodeActual = HttpServletRequestUtil.getString(request,"verifyCode");
        //判断实际提交的验证码是否与生产的验证码是否一致
        if(verifyCodeActual == null && !verifyCodeActual.equals(verifyCodeGenerated)){
            return false;
        }
        return true;
    }
}

Ok,至此验证码的内容已完成。



commons-fileupload文件上传组件 和 Thumbnailator图片开源工具

1) 考虑到该项目会产生大量图片(用户头像,店铺图片,商品图片,商品详情图等),所以使用图片开源工具Thumbnailator,对图片进行压缩。此外,Thumbnailator还支持图片按比例缩放,生成水印,旋转等处理操作

2) 考虑到在Windows和Linux系统上运行,所以图片使用相对路径来保存

3) 用户头像,店铺类别图,店铺图、商品图和商品详情图分别保存在不同的文件夹中

4)配置虚拟路径,让图片能正常在前端展示


1、pom.xml文件中引入Commons文件上传组件 和 Thumbnailator图片开源工具

<!--commons文件上传组件-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

<!--缩略图 ~ 图片处理-->
<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.8</version>
</dependency>

2、PathUtil工具类中,定义图片保存的子路径的方法

public class PathUtil {

    //获取当前操作系统的文件分隔符
    private static String separator = System.getProperty("file.separator");
    //也可通过下面语句获取当前操作系统的文件分隔符
    //private static String separator2 = File.separator;

    /**
     * 获取文件保存的根目录路径
     *
     * @return
     */
    public static String getImgBasePath(){
        //获取当前操作系统名称
        String os = System.getProperty("os.name");

        String basePath = "";

        //判断当前操作系统是Windows还是Linux
        if(os.toLowerCase().startsWith("win")){
            basePath = "D:/idea/java_workspace/image";
        }else {
            basePath = "home/shop/image";
        }
        //由于Windows和Linux操作系统的文件分隔符不一样,所以将'/'分隔符替换成当前操作系统的文件分隔符
        basePath = basePath.replace("/",separator);
        return basePath;
    }


    /**
     * 获取店铺图片保存的相对目录路径
     *
     * @param shopId
     * @return
     */
    public static String getShopImagePath(Long shopId){
        //生成对应的图片保存路径
        String imagePath = "/upload/shop/"+ shopId +"/";
        //将路径分隔符‘/’替换成当前操作系统的分隔符
        //return imagePath.replace("/",separator);
        return imagePath;
    }


    /**
     * 获取头像保存的相对目录路径
     *
     * @param username
     * @return
     */
    public static String getLocalImagePath(String username){
        //生成对应的图片保存路径
        String imagePath = "/upload/local/"+ username +"/";
        return imagePath;
    }
}

3、ImageUtil工具类中,通过Thumbnailator图片开源工具压缩图片,并输出到指定路径中。

public class ImageUtil {

    //类路径资源目录
    private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    //时间格式
    private static SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
    //随机类
    private static Random random = new Random();

    /**
     * 将CommonsMultiFile转化成File
     *
     * @param file
     * @return
     */
    public static File transferCommonsMultipartFileToFile(CommonsMultipartFile file){
        //创建File文件对象 (file的getOriginalFilename()方法用于获取文件的原文件名)
        File newFile = new File(file.getOriginalFilename());
        try {
            //将CommonsMultipartFile转换成File(即将传入的文件流写入到指定的文件对象中)
            file.transferTo(newFile);
        } catch (IOException e) {
            throw new RuntimeException("文件流写入失败:" + e.getMessage());
        }
        return newFile;
    }


    /**
     * 生成不带水印缩略图,并返回新生产图片的相对路径
     *
     * @param uploadFile 缩略图(包含图片流和图片名)
     * @param targetAddr 图片存储相对路径/目标路径
     * @return
     */
    public static String thumbnail(MultipartFile uploadFile, String targetAddr){
        //获取文件随机名称
        String realFileName = getRandomFileName();
        // 获取上传文件的原文件名
        String fileName = uploadFile.getOriginalFilename();
        // 获取上传文件的后缀名
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        //如果目标路径不存在,则自动创建
        makeDirsPath(targetAddr);
        //拼接文件存储的相对路径(带文件名)
        String relativeAddr = targetAddr + realFileName + suffix;
        //生成新的文件,并保存到指定路径中
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
        //调用thumbnails生成带有水印的缩略图
        try {
            //生成带水印的缩略图
            Thumbnails.of(uploadFile.getInputStream())
                    .size(200,200)
                    .outputQuality(0.8f)
                    .toFile(dest);
        } catch (IOException e) {
            throw new RuntimeException("缩略图创建失败:" + e.getMessage());
        }

        //返回文件保存的相对路径地址
        return relativeAddr;
    }


    /**
     * 生成带水印缩略图,并返回新生产图片的相对路径
     *
     * @param thumbnail 缩略图(包含图片流和图片名)
     * @param targetAddr 图片存储相对路径/目标路径
     * @return
     */
    public static String generateThumbnail(ImageHolder thumbnail, String targetAddr){
        //获取文件随机名称
        String realFileName = getRandomFileName();
        //获取文件扩展名(后缀名)
        String extension = getFileExtension(thumbnail.getImageName());
        //如果目标路径不存在,则自动创建
        makeDirsPath(targetAddr);
        //拼接文件存储的相对路径(带文件名)
        String relativeAddr = targetAddr + realFileName + extension;
        //生成新的文件,并保存到指定路径中
        File dest = new File(PathUtil.getImgBasePath()+relativeAddr);
        //调用thumbnails生成带有水印的缩略图
        try {
            //生成带水印的缩略图
            Thumbnails.of(thumbnail.getImage())
                      .size(200,200)
                      .watermark(Positions.BOTTOM_RIGHT,ImageIO.read(new File(basePath + "/watermark.jpg")),0.8f)
                      .outputQuality(0.8f)
                      .toFile(dest);
        } catch (IOException e) {
            throw new RuntimeException("缩略图创建失败:" + e.getMessage());
        }

        //返回文件保存的相对路径地址
        return relativeAddr;
    }


    /**
     * 生成带水印商品详情图缩略图,并返回新生产图片的相对值路径
     *
     * @param thumbnail 缩略图(包含图片流和图片名)
     * @param targetAddr 图片存储相对路径/目标路径
     * @return
     */
    public static String generateNormalThumbnail(ImageHolder thumbnail, String targetAddr){
        //获取文件随机名称
        String realFileName = getRandomFileName();
        //获取文件扩展名(后缀名)
        String extension = getFileExtension(thumbnail.getImageName());
        //如果目标路径不存在,则自动创建
        makeDirsPath(targetAddr);
        //拼接文件存储的相对路径(带文件名)
        String relativeAddr = targetAddr + realFileName + extension;
        //生成新的文件对象,并保存到指定路径中
        File dest = new File(PathUtil.getImgBasePath()+relativeAddr);
        try {
            //生成带水印的缩略图
            Thumbnails.of(thumbnail.getImage())
                    .size(337,640)
                    .watermark(Positions.BOTTOM_RIGHT,ImageIO.read(new File(basePath + "/watermark.jpg")),0.8f)
                    .outputQuality(0.9f)
                    .toFile(dest);
        } catch (IOException e) {
            throw new RuntimeException("缩略图创建失败:" + e.getMessage());
        }
        //返回文件保存的相对路径地址
        return relativeAddr;
    }



    /**
     * 创建目标路径所涉及到的目录, 如 D:/tmp/one/two/xxx.jpg , 那么/tmp/one/two这三个文件夹都得自动创建
     *
     * @param targetAddress 图片存储的相对路径
     */
    private static void makeDirsPath(String targetAddress) {
        //获取文件全路径 ~ ~ 全路径 = 根路径 + 相对路径 (不包括文件名)
        String fileParentPath = PathUtil.getImgBasePath() + targetAddress;
        //获取文件全路径目录
        File dirPath = new File(fileParentPath);
        //判断目录是否存在,不存在就创建该目录 (mkdir用于创建单级目录, mkdirs用于创建多级目录)
        if(!dirPath.exists()){
            dirPath.mkdirs();
        }
    }

    /**
     * 生产随机文件名 ~ ~ 当前的(年月日时分秒 +5位随机数)
     *
     * @return
     */
    public static String getRandomFileName() {
        //获取10000~99999之间的5位随机数
        int randomNumber = random.nextInt(99999) + 10000;
        //获取当前时间,并按指定时间格式返回
        String nowTime = format.format(new Date());
        String randomFileName = nowTime + randomNumber;
        return randomFileName;
    }

    /**
     * 获取文件扩展名
     *
     * @param filename
     * @return
     */
    private static String getFileExtension(String filename) {
        //获取原始文件扩展名
        String fileExtension = filename.substring(filename.lastIndexOf("."));
        return fileExtension;
    }



    /**
     * 删除存储在磁盘中的指定图片
     *
     * imgAddr是文件的路径或目录的路径
     *      如果imgAddr是文件路径则删除该文件
     *      如果imgAddr是目录路径则删除该目录下的所有文件
     * @param imgAddr
     */
    public static void deleteFileOrPath(String imgAddr){
        //获取指定文件对象 (文件的绝对路径=PathUtil.getImgBasePath() + imgAddr,即根路径+相对路径)
        File fileOrPath = new File(PathUtil.getImgBasePath() + imgAddr);
        //判断该文件对象是否存在
        if(fileOrPath.exists()){
            //判断fileOrPath文件对象是文件还是目录
            if(fileOrPath.isDirectory()){
                //获取文件列表
                File files[] = fileOrPath.listFiles();
                for(int i=0;i<files.length;i++){
                    //删除文件
                    files[i].delete();
                }
            }
            //不是文件就是目录,是文件则直接删除,是目录则删除里面文件后顺便将目录删除,(删除目录必须保证目录为空的)
            fileOrPath.delete();
        }
    }

}

2、在html中添加文件上传控件,并设置只能上传图片

<div class="content">
   <form>
       <div class="list-block">
           <ul>
               <!-- 用户名 Text -->
               <li>
                   <div class="item-content">
                       <div class="item-media">
                           <i class="icon icon-form-email"></i>
                       </div>
                       <div class="item-inner">
                           <div class="item-input">
                               <input type="text" id="username" placeholder="用户名">
                           </div>
                       </div>
                   </div>
               </li>

               <!-- 密码 password -->
               <li>
                   <div class="item-content">
                       <div class="item-media">
                           <i class="icon icon-form-email"></i>
                       </div>
                       <div class="item-inner">
                           <div class="item-input">
                               <input type="password" id="pwd" placeholder="密码">
                           </div>
                       </div>
                   </div>
               </li>

               <!-- 用户头像缩略图 -->
               <li>
                   <div class="item-content">
                       <div class="item-media">
                           <i class="icon icon-form-email"></i>
                       </div>
                       <div class="item-content">
                           <div class="item-inner">
                               <div class="item-title label">头像</div>
                               <div class="item-input">
                                   <!-- accept="image/*"规定只能上传图片 -->
                                   <input type="file" accept="image/*" id="upload_file">
                               </div>
                           </div>
                       </div>
                   </div>
               </li>

               <!-- captcha验证码 -->
               <li>
                   <div class="item-content">
                       <div class="item-media">
                           <i class="icon icon-form-email"></i>
                       </div>
                       <div class="item-inner">
                           <label for="j_captcha" class="item-title label">验证码</label>
                           <input id="j_captcha" name="j_captcha" type="text"
                                  class="form-control in" placeholder="验证码" />
                           <div class="item-input">
                               <img id="captcha_img" alt="点击更换" title="点击更换"
                                    onclick="changeVerifyCode(this)" src="../Kaptcha" />
                           </div>
                       </div>
                   </div>
               </li>
           </ul>
       </div>

       <div class="content-block">
           <div class="row">
               <div class="col-50">
                   <a href="#" class="button button-big button-fill button-danger" id="clear">重置</a>
               </div>
               <div class="col-50">
                   <a href="#" class="button button-big button-fill button-success" id="submit">注册</a>
               </div>
           </div>
       </div>
       <input type="reset" style="display: none">
   </form>
</div>
$(function () {
    // 账号注册Url
    var registerUrl = '/o2o/local/register';

    $('#submit').click(function () {

        // 定义表单对象,用于接收前端数据以提交给后端
        var formData = new FormData();

        // 创建person对象
        var person = {};
        // 获取表单里的数据,并填充进person对象对应的属性里
        person.name = $('#username').val();
        person.pwd = $('#pwd').val();
        // 将person对象转化成json字符串,并保存到formDate表单对象中名为personStr的Key里
        formData.append('personStr',JSON.stringify(person));

        // 获取上传的图片文件流
        var uploadFile = $('#upload_file')[0].files[0];
        // 将图片流添加进表单对象里
        formData.append('uploadFile',uploadFile);

        // 获取表单输入的验证码
        var verifyCode = $('#j_captcha').val();
        // 判断输入的验证码是否为空
        if(!verifyCode){
            $.toast('请输入验证码!');
            return;
        }
        // 将验证码保存到ormDate表单对象中名为verifyCode的Key里
        formData.append('verifyCode',verifyCode);

        /**
         * 发送ajax,将数据提交至后台处理相关操作
         */
        $.ajax({
            url : registerUrl,
            type: 'post',
            data: formData,
            dataType: 'json', //指定服务器返回的数据类型
            processData: false, //必须参数(默认为true),因为data值是FormData对象,告诉jQuery不要将data处理转化为查询字符串(URL参数)
            /*必须参数(默认为true),data默认以查询字符串形式传输(如id=1&pwd=1),这种传数据的格式,无法传输复杂的数据(如文件、数组)
              把contentType 改成 false 就会改掉之前默认的数据格式,在上传文件时就不会报错了
             */
            contentType: false,
            cache: false, //不从浏览器中加载请求信息
            //判断是否成功返回数据(即是否成功将数据提交给后台)
            success: function(data){
                if(data.success){
                    //toast是一种轻量的提示,在页面中间显示,并且会在2秒(默认值,可修改)之后自动消失。
                    $.toast('注册成功!');
                    window.location.href = '/o2o/local/to_login';
                }else{
                    $.toast(data.errorMsg);
                }
                //进行提交后,不管成功还是失败,都对验证码进行更新
                $('#captcha_img').click();
            }
        });
    });

    //点击重置按钮,清空表单内容  参考:https://blog.csdn.net/qq_34578253/article/details/71108155
    $('#clear').click(function () {
        $("input[type=reset]").trigger("click");//通过trigger()方法触发reset按钮
    });

});

Controller实现

@Service("personService")
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonDao personDao;

    /**
     * 账号注册
     *
     * @param person
     * @param multipartFile
     * @return
     */
    @Transactional
    public int addPerson(Person person, MultipartFile multipartFile) {
        //给账号信息赋初始值
        person.setCreateTime(new Date());
        person.setLastEditTime(new Date());
        person.setEnableStatus(1);
        person.setPersonType(1);
        try{
            //添加图片
            addLocalImg(person,multipartFile);
        }catch (Exception e){
            throw new RuntimeException("addLocalImg error:" + e.getMessage());
        }
        //添加账号
        int effectedNum = personDao.insertPerson(person);
        if(effectedNum <= 0){
            throw new RuntimeException("账号注册失败!");
        }
        return effectedNum;
    }


    /**
     * 添加不带水印的缩略图,并将图片保存的相对路径设置到Person对象的ProfileImg属性里
     *
     * @param person
     * @param multipartFile
     */
    private void addLocalImg(Person person, MultipartFile multipartFile){
        // 定义用户头像的相对路径
        String relativeAddress = PathUtil.getLocalImagePath(person.getName());
        // 生成不带水印的缩略图,并返回其相对路径
        String localImgAddress = ImageUtil.thumbnail(multipartFile,relativeAddress);
        // 将相对地址设置进Person实体类的属性中
        person.setProfileImg(localImgAddress);
    }

    /**
     * 修改用户信息
     *
     * @param person
     * @param multipartFile
     * @return
     */
    @Transactional
    public int modifyPerson(Person person, MultipartFile multipartFile) {
        int effectNum = 0;
        //空值判断
        if(person != null){
            if(multipartFile != null){
                try{
                    //删除原有的图片
                    ImageUtil.deleteFileOrPath(person.getProfileImg());
                }catch (Exception e){
                    throw  new RuntimeException(e.getMessage());
                }
                //添加新图片
                addLocalImg(person,multipartFile);
            }
            //修改用户信息
           effectNum = personDao.updatePerson(person);
        }
        return effectNum;
    }
}

Controller实现

@Controller
@RequestMapping("/local")
public class PersonController {

    @Autowired
    private PersonService personService;

    /**
     * 账号注册
     *
     * @param uploadFile
     * @param request
     * @return
     */
    @RequestMapping("/register")
    @ResponseBody
    private Map<String,Object> register(MultipartFile uploadFile, HttpServletRequest request){
        Map<String,Object> map = new HashMap<String, Object>();
        //验证码校验
        if(!VerifyCodeUtil.checkVerifyCode(request)){
            map.put("success",false);
            map.put("errorMsg","验证码错误!");
            return map;
        }
        //获取前端提交过来的用户名和密码信息
        String personStr = HttpServletRequestUtil.getString(request,"personStr");
        ObjectMapper objectMapper = new ObjectMapper();
        Person person = null;
        try {
            //将personStr字符串转化成Person实体类
            person = objectMapper.readValue(personStr,Person.class);
        } catch (IOException e) {
            map.put("success",false);
            map.put("errorMsg",e.getMessage());
            return map;
        }
        //添加账号信息
        int effectedNum = personService.addPerson(person,uploadFile);
        if(effectedNum <= 0){
            map.put("success",false);
            map.put("errorMsg","账号注册失败!");
            return map;
        }
        map.put("success",true);
        return map;
    }
}



Redis缓存

项目中引入了Redis缓存技术,对一些经常使用且不常更改的数据,通过Redis进行缓存,可以减轻数据库的压力(因为访问高峰期,很有可能把数据库搞崩)!


内容有时间会添加


DTO及相关枚举类


内容有时间会添加



Quartz定时任务

发布了90 篇原创文章 · 获赞 111 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_42950079/article/details/103092988