寒假学习springboot开发的过程

@    跟着视频学习,刚开始就是跟着视频敲代码,然后再改改,不懂的地方语法什么的在网上搜索。不可能自己从头到尾完全独立的开发一个网站,现阶段第一次做项目,不可能自己造轮子。

Controller层调用Service层,Service层调用Dao层


目录

debug:

MD5加密登录:

spring + vue 如何连接前后端



debug:

1.

        login.html里面的login不亮,我以为是没成功调用,问群里面的兄弟后,告诉我login(){alert("111)},然后看会不会弹窗,结果有弹窗,但是会显示系统错误,然后没有跳转login的登陆界面。自己查资料查了两天都不会弄。最后在淘宝花了50块找大佬远程解决了。                                        首先笔记本上报错是因为数据库没连好,yml文件里面不应该是空的。还要在MySQLworkbench里面输入一句话,IDEA里面数据库文件的密码应该换成我自己的。                             然后,login的问题并不是前端的问题,是后端错了。少了AdminInfo 和Account初始化,大佬说是打断点看出来的。

2.

安装vue的bug:

环境变量的“;”是中文的,造成cmd里面输入vue 显示vue不是内部命令。

解决方法:把";"换成英文符号。有一个技巧,因为环境变量里面符号很多肉眼一个个找很麻烦,把环境变量复制到记事本中,使用记事本的“全部替换”功能。


MD5加密登录:

1.调用hutool包

2.新增用户时自动赋值的密码通过MD5加密后保存到数据库

3.登录时将输入的密码通过MD5加密后与数据库的值比较

数据库中的数据


spring + vue 如何连接前后端

vue前端增加一个网址后要新建一个路由。


给项目添加权限管理功能

V-if

总结:角色权限控制就一个role 搞定!!

注册页改造

1.注册页跳转到登录

        RegisterView.vue

<div style="text-align:center">
  已有账号?<a href="javascript:void(0)" style="text-decoration: none "@click="navLogin()">点击登录</a>
 </div>
navLogin(){
      this.$router.push("/login");
    }

2.注册的时候,支持选择角色

 <el-form-item>
     <el-select v-model="admin.role" placeholder="请选择" style="width: 80%">
        <el-option label="教练" value="ROLE_COACH"></el-option>
        <el-option label="学员" value="ROLE_STUDENT"></el-option>
     </el-select>
</el-form-item>

文件上传和下载功能

@FileController

@RestController
@RequestMapping("/files")
public class FileController {

    // 文件上传存储路径
    private static final String filePath = System.getProperty("user.dir") + "/file/";

    /**
     * 文件上传
     */
    @PostMapping("/upload")
    public Result upload(MultipartFile file) {
        synchronized (FileController.class) {
            String flag = System.currentTimeMillis() + "";
            String fileName = file.getOriginalFilename();
            try {
                if (!FileUtil.isDirectory(filePath)) {
                    FileUtil.mkdir(filePath);
                }
                // 文件存储形式:时间戳-文件名
                FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName);
                System.out.println(fileName + "--上传成功");
                Thread.sleep(1L);
            } catch (Exception e) {
                System.err.println(fileName + "--文件上传失败");
            }
            return Result.success(flag);
        }
    }


    /**
     * 获取文件
     */
    @GetMapping("/{flag}")
    public void avatarPath(@PathVariable String flag, HttpServletResponse response) {
        if (!FileUtil.isDirectory(filePath)) {
            FileUtil.mkdir(filePath);
        }
        OutputStream os;
        List<String> fileNames = FileUtil.listFileNames(filePath);
        String avatar = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");
        try {
            if (StrUtil.isNotEmpty(avatar)) {
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(avatar, "UTF-8"));
                response.setContentType("application/octet-stream");
                byte[] bytes = FileUtil.readBytes(filePath + avatar);
                os = response.getOutputStream();
                os.write(bytes);
                os.flush();
                os.close();
            }
        } catch (Exception e) {
            System.out.println("文件下载失败");
        }
    }

}

 遇到跨域问题加一个配置文件

@Configuration
public class CORSFilter {
    @Bean
    public CorsFilter corsFilter(){
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsFilter(source);
    }
}

 下载图片( 加个点击事件@clidk="down(scope.row.image)" )

down(flag) {
    location.href =  'http://localhost:8080/api/files/' + flag 
}

预约功能优化

实先同一个课程一名用户只能预约一次

点击预约后,后台根据对应的预约人和预约课程查reserve数据库表,若能查到则显示“已经预约过该课程”

Lesson lesson = lessonDao.selectByPrimaryKey(reserve.getLessonId());
Reserve reserve1=reserveDao.selectByUserIdAndLessonId(reserve.getUserId(),reserve.getLessonId()); 

        if (lesson.getNumber() == 0) {
            return Result.error("课程已被预定完");
        }

        // 2.判断该用户是否选过该课程,如果选过了,就提示用户不能重复选课

        else if (ObjectUtil.isNotEmpty(reserve1)) {
            throw new CustomException("已经预约过此课程。");
        }

Dao层 

 @Select("select * from reserve where userId = #{userId} and lessonId = #{lessonId}")
    Reserve selectByUserIdAndLessonId(@Param("userId") Integer userId,@Param("lessonId") Integer lessonId);

个人中心页面

要求进入个人中心页面时,自动加载当时的个人信息(把user的信息传给form,因为调用时使用form.name等form的方法调用)。

export default {
  data() {
    return {
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
      tableData: [],
      form: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
    }
  },

但是有一个问题,用户点击确定修改后,因为表外调用的是user.name所以表外的名字没有改。所以我让用户修改完信息后需要重新登录。

邮箱发送找回密码功能

<el-form-item>
          <el-button style="width: 80%; margin-top: 10px" type="primary" @click="sendemail()">找回密码</el-button>
        </el-form-item>
sendemail() {
      if(!this.admin.email){
        this.$message.warning("请输入邮箱账号");
        return;
      }

// 判断邮箱格式是否正确
      if(!/^\w+((.\w+)|(-\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/.test(this.admin.email)) {
        this.$message.warning("请输入正确邮箱");
        return;
      }
      request.get("/admin/email/" + this.admin.email).then(res => {
        if (res.code === '0') {
          this.$message.success("发送成功");
        } else{
          this.$message.error(res.msg);
        }

      })
    },

(有一个bug,要是写成this.request.get来请求就会不成功)

@admincontroller

@GetMapping("/email/{email}")
    public Result sendEmail(@PathVariable String email) {
        if(StrUtil.isBlank(email)) {
            throw new CustomException("请输入邮箱");
        }
        adminService.sendEmail(email);
        return Result.success();
    }

 @adminservice

@Value("${spring.mail.username}")
    private String from;
@Autowired
    JavaMailSender javaMailSender;
    public void sendEmail(String email) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(email);
        message.setSubject("验证一下能不能使用");
        message.setText("测试邮箱内容");
        javaMailSender.send(message);
    }

application.yml

  mail:
    protocol: smtps
    host: smtp.163.com
    username: 18020106701@163.com
    password: KPTHLJVWPYUFMLYD
    port: 465
    default-encoding: UTF-8

password是在网易云163邮箱里面获得

点开启服务,发送短信验证码开启后获得Password

评论功能

comment表

createtime 要设置CURRENT_TIMESTAMP,自动生成时间

 前端写评论弹框界面

<el-dialog title="评论" :visible.sync="viewFormVisible" width="60%">
      <el-input type="textarea" placeholder="请输入评论" v-model="comment.content"></el-input>
      <div style="text-align: right; margin: 10px 0 ">
        <el-button type="primary" @click="sub()">提交</el-button>
      </div>
      <div style="margin: 20px 0">
        <div style="margin: 10px 0 ;font-size: 20px ;padding: 10px 0; border-bottom: 1px solid #ccc;text-align: left">评论列表</div>
      </div>
      <div style="margin: 20px 0; text-align: left">
        <div style="padding: 10px 0; display: flex" v-for="item in comments" :key="item.id">
          <div>
            <el-image
                style="width: 50px; height: 50px; border-radius: 50%"
                :src=" 'http://localhost:8080/api/files/' + item.useravatar "
                :preview-src-list="['http://localhost:8080/api/files/' + item.useravatar ]">
            </el-image>
          </div>
          <div style="flex: 1; margin-left: 15px">
            <div>{{item.username}}</div>
            <div style="margin-top: 10px">{{item.content}}</div>
          </div>
        </div>
      </div>
    </el-dialog>
export default {
  data() {
    return {
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
      params: {
        name:'',
        phone:'',
        pageNum: 1,
        pageSize: 5,
      },
      tableData: [],
      total: 0,
      dialogFormVisible: false,
      editVisible: false,
      viewFormVisible: false,
      form: {},
//coments是后台根据该Foreign_id查到的所有评论内容和评论人用户名头像
      comments: [],
//comment将内容传到后台
      comment: {
        content:'',
      }
    }
  },

 注意:

this.load(this.comment.foreign_id)这样才能正确传输foreign_id。刚开始写错了,后台会拿不到数据。

view(row) {
      this.viewFormVisible = true;
      this.comment = {
        content: ''
      }
      this.comment.foreign_id = row.id;
      this.load(this.comment.foreign_id);
    },

//加载出对应帖子id的评论
    load(id) {
        request.get("/comment/" + id).then( res =>{
          this.comments = res.data;
      })
    },

//把comment里面的数据传给后台
    sub(){
      this.comment.user_id = this.user.id
      this.comment.username = this.user.name
      this.comment.useravatar = this.user.avatar
      request.post("/comment",JSON.stringify(this.comment)).then( res => {
        if(res.code === '0'){
          this.$message.success("成功")
        } else{
          this.$message.error(res.data)
        }
      })
    },

@comment.entity 

@Table(name="comment")
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String content;
    private String username;
    private Integer user_id;
    private Integer foreign_id;
    private String target;
    private String useravatar;
    @JsonFormat(pattern = "yyyy-mm-dd HH:mm:ss")
    private LocalDateTime createtime;
}

 @CommentController

@RestController
@RequestMapping("/comment")
public class CommentController {

    @Resource
    CommentService commentService;

    @Resource
    CommentDao commentDao;

    @PostMapping
    public Result save(@RequestBody Comment comment) {
        if(comment.getId() == null ){
            commentService.add(comment);
        } else {
            commentService.update(comment);
        }
        return Result.success();
    }

//根据帖子的id查找评论
    @GetMapping("/{id}")
    public Result list(@PathVariable("id") Integer foreign_id){
        List<Comment> comments = commentDao.findAllByForeign_Id(foreign_id);
        return Result.success(comments) ;
    }

}

@CommentService 

@Service
public class CommentService {
    @Resource
    private CommentDao commentDao;


    public void add(Comment comment) {
        commentDao.insertSelective(comment);
    }

    public void update(Comment comment) {
        commentDao.updateByPrimaryKeySelective(comment);
    }

    public void delete(Integer id) {
        commentDao.deleteByPrimaryKey(id);
    }
}

@CommentDao 

public interface CommentDao extends Mapper<Comment> {

    @Select("select * from comment where foreign_id = #{foreign_id}")
    List<Comment> findAllByForeign_Id(@Param("foreign_id") Integer foreignId);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值