山大软院创新项目实训(二)

目录

一、个人成果总结

二、主要功能点实现

1.注册

2.个人信息

3.个人头像上传

4.邮箱格式限制

5.密码限制

6.前端友好提示

三、后续任务


 

一、个人成果总结

这段时间我主要负责并完成了注册、个人信息等界面的前后端+mysql数据库设计和实现,同时实现了头像上传、数据格式限制等功能。

二、主要功能点实现

1.注册

界面展示:

ac0067197bc24521acfce93a1438af4f.png

数据库设计:

01ca5dc36c044fcca7f36449a2b73df8.png

其中设置用户名username唯一。

后端接口逻辑:

@ApiOperation("输入用户名密码邮箱和用户类型注册")
    @PostMapping("/register")
    public Result register(@RequestBody UserDTO userDTO) {
        String username = userDTO.getUsername();
        String password = userDTO.getPassword();
        String email = userDTO.getEmail();
        //判断参数格式
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password) || StrUtil.isBlank(email)) {
            return Result.error(Constants.CODE_400, "参数错误,部分参数为空");
        }
        if (!StringUtil.checkEmail(email)){
            return Result.error(Constants.CODE_600,"邮箱格式错误");
        }
        if ( !StringUtil.checkPassword(password) ) {
            // 密码格式校验
            return Result.error(Constants.CODE_400,"密码格式为:长度为6-18,只有数字和字母且至少包含1个字母");
        }
        return Result.success(userService.register(userDTO));
    }

前端界面设计:

rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 6, max: 18, message: '长度为6-18,只有数字和字母且至少包含1个字母', trigger: 'blur' }
        ],
        confirmPassword: [
          { required: true, message: '请确认密码', trigger: 'blur' },
          { min: 6, max: 18, message: '长度为6-18,只有数字和字母且至少包含1个字母', trigger: 'blur' }
        ],
        email: [
          {required: true, message: '请输入邮箱', trigger: 'blur'},
          {min: 6, max: 20, message: '请输入正确的邮箱格式', trigger: 'blur'}
        ]
      }

为了让系统有更好的交互性,这里做了详细的提示信息,同时通过设计“确认密码”的方式,进一步加强了用户信息的安全性。

2.个人信息

界面展示:

采用element-plus提供的el-form框架,

4b013543e01a4f98ae68fe9beba29ba0.png

通过右上角下拉框“个人信息”进入个人信息界面,路由:

{
        path: '/person',
        name: 'Person',
        component: () => import("@/views/Person"),
        meta: { isStu: true, title:'主页' },
},

在数据库表中加入以下字段:

33039f8ed8904757bcb6998e635b562d.png

后端分页查找某个用户的信息:

@ApiOperation("(分页查询)(有改动)根据username查找某个学生信息")
    @GetMapping("/page")
    public Result findStudentByStudentNumOrStudentName(@RequestParam Integer pageNum,
                                                       @RequestParam Integer pageSize,
                                                       @RequestParam(defaultValue = "") String studentname
                                                       ) {
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(studentname)) {

            queryWrapper.like("studentname", studentname);

        }
        queryWrapper.orderByAsc("id");
        return Result.success(studentService.page(new Page<>(pageNum, pageSize), queryWrapper));
    }

由于前面将username设为主键,所以这里直接根据它进行搜索即可;

保存用户信息:

@PostMapping//保存一个用户的信息
    public Result save(@RequestBody Student student) {
        if (student.getPhoneNumber()!=null){
            if (!StringUtil.checkPhone(student.getPhoneNumber())){
                return Result.error(Constants.CODE_400,"电话号码格式错误");
            }
        }
        if(student.getBirthday()!=null){
            String birthday = student.getBirthday();
            DateTime datetime = DateUtil.parse(birthday);
            student.setBirthday(datetime.toDateStr());
        }
        studentService.saveOrUpdate(student);
        return Result.success();
    }

这里对手机号码的格式进行了限制,同时将前端返回的生日设成数据库所需格式。

3.个人头像上传

前端上传用户头像:

 <!--上传头像 -->
      <el-upload
          class="avatar-uploader"
          :action="'/api/file/uploadphoto'"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
      >
        <img v-if="user.headPortrait" :src="user.headPortrait" class="avatar">
        <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
      </el-upload>

这里设置一个上传头像的“钩子”,上传后便会调用后端接口,同时通过handleAvatarSuccess函数更新用户头像的url:

handleAvatarSuccess(res) {
      console.log(res)
      //调用user/id接口存头像url
      if(res.code==='400'){
        this.$message.error(res.msg)
      } else{
        this.user.headPortrait=res.data;
      }
    }

后端接口设计:

这里对上传文件的类型进行了限制,后续可能会继续对图片进行大小限制/压缩处理,减轻存储压力;除此之外,通过查询数据库判断图片是否已存储,若已存储则返回对应文件md5,反之保存在相应的绝对路径下。

@PostMapping("/uploadphoto")
    public Result uploadphoto(@RequestParam MultipartFile file) throws IOException {

        //得到文件原始名
        String originalFilename = file.getOriginalFilename();
        //文件类型
        String type = FileUtil.extName(originalFilename);

        //判断文件类型是否合法
        String[] photo_type = {"bmp", "jpg", "png", "tif", "gif", "fpx", "svg", "psd", "webp", "jpeg"};
        boolean is_legal_type = false;
        for (String ps : photo_type) {
            if (ps.matches(type)) is_legal_type = true;
        //    System.out.println(ps);
        }
        if (!is_legal_type) {
            return Result.error(Constants.CODE_400, "错误图片格式");
        }

        //文件大小要不要设置图片最大规格???/压缩图片???
        long size = file.getSize();

        // 定义一个文件唯一的标识码 唯一性ID生成器:UUID
        // 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID DOT“.”
        String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + type;

        File uploadFile = new File(fileUploadPath + fileUUID);
        // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
        File parentFile = uploadFile.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }

        String url;
        // 获取文件的md5
        String md5 = SecureUtil.md5(file.getInputStream());
        // 从数据库查询是否存在相同的记录
        Files dbFiles = getFileByMd5(md5);
        if (dbFiles != null) {
            url = dbFiles.getUrl();
        } else {
            // 上传文件到磁盘
            file.transferTo(uploadFile);
            // 数据库若不存在重复文件,则不删除刚才上传的文件
            url = "http://" + serverIp + ":8088/file/" + fileUUID;//
            // 存储file数据库
            Files saveFile = new Files();
            saveFile.setName(originalFilename);
            saveFile.setType(type);
            saveFile.setSize(size / 1024); // 单位 kb
            saveFile.setUrl(url);
            saveFile.setMd5(md5);
            fileMapper.insert(saveFile);
        }

4.邮箱格式限制

 /**
     * 邮箱校验
     *
     * @param email 邮箱
     * @return true or false
     */
    public static boolean checkEmail(String email) {
        String check = "^([a-zA-Z]|[0-9])(\\w|\\-)+@[a-zA-Z0-9]+\\.([a-zA-Z]{2,4})$";
        Pattern regex = Pattern.compile(check);
        Matcher matcher = regex.matcher(email);
        return matcher.matches();
    }

这里还对邮箱的格式加了限制,控制邮箱格式为“××@××.××”,这是为了引导用户输入真实的邮箱,从而在密码丢失后以便找回账号;

5.密码限制

/**
     * 密码校验(长度 6-18,至少包含1个字母)
     * @param password
     * @return
     *
     */
    public static boolean checkPassword(String password) {
        String check = "(?=.*[a-zA-Z])[a-zA-Z0-9]{6,18}";
//        String check = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,18}$";
        Pattern regex = Pattern.compile(check);
        Matcher matcher = regex.matcher(password);
        return matcher.matches();
    }

同时用正则表达式的防止,限制密码长度为6~18位、只含字母/数字、至少含1个字母。

6.前端友好提示

rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 6, max: 18, message: '长度为6-18,只有数字和字母且至少包含1个字母', trigger: 'blur' }
        ],
        confirmPassword: [
          { required: true, message: '请确认密码', trigger: 'blur' },
          { min: 6, max: 18, message: '长度为6-18,只有数字和字母且至少包含1个字母', trigger: 'blur' }
        ],
        email: [
          {required: true, message: '请输入邮箱', trigger: 'blur'},
          {min: 6, max: 20, message: '请输入正确的邮箱格式', trigger: 'blur'}
        ]
      }

为了让系统有更好的交互性,这里做了详细的提示信息,同时通过设计“确认密码”的方式,进一步加强了用户信息的安全性。

三、后续任务

接下来的时间,我将完成日志相关的操作,包括发表日志、编辑日志、删除日志、查找日志、以及与日志编辑器有关的用操作,如添加表情、上传本地图片、设置导航栏等。

 

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值