SpringBootWebProject小型项目——学生管理系统完整搭建

简介: SpringBootWebProject小型项目——学生管理系统完整搭建

前言

距离本学期结束就要去实习的时间已经很短了,那么在这里我帮助大家完整的回忆一下SpringBoot的完整操作,为了更加直接体现完整的过程我会使用层叠法来完成这个系列文章,会从最新版本idea社区版本的下载开始,直至我们代码开发的整个阶段,可以将接口完全搞出来,跨域后让前端的项目可以解析,完成整个开发的闭环操作,准备工作的孩子们可以持续的跟着看看,应该会给你提供比较大的帮助。

声明:由于刚毕业的还比不可能上来就上大的微服务架构,所以这里不提供springcloud内容,当然我会在下一个系列中将本次学到的整个springboot融入到springcloud中。

系统与开发环境

系统:Windows 11 家庭中文版

idea:官网2024年1月最新社区版本:ideaIC-2024.1

数据库:阿里云RDS for MySQL 5.7

基础idea环境搭建


基础maven配置(外部独立maven)


基础maven默认配置(默认maven)


基础springboot框架搭建(API接口)


基础框架下载地址


Vue脚手架搭建


SpringBootWebProject小型项目——完整搭建正文

项目概述

【学生】管理系统,为了方便学生们练手所搞的一个项目,包含了基本的接口增删改查,查询方式包含单个查询,模糊查询,筛选查询,页面采用的是vue脚手架搭建的,为了操作方便功能都放在一个页面了,但是路由操作我留了,学起来也方便快捷,希望本项目能为大家提供一定的价值,如果能帮助到你免费的赞赞、收藏、评论多点一点啊。

数据库创建——DDL+DML一键运行即可

数据库创建utf8的编码格式

DDL+DML

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
  `createDate` datetime DEFAULT NULL COMMENT '创建时间',
  `userName` varchar(20) DEFAULT NULL COMMENT '姓名',
  `pwd` varchar(36) DEFAULT NULL COMMENT '密码',
  `phone` varchar(11) DEFAULT NULL COMMENT '手机号',
  `age` tinyint(3) unsigned DEFAULT NULL COMMENT '年龄',
  `sex` char(2) DEFAULT NULL COMMENT '性别',
  `introduce` varchar(255) DEFAULT NULL COMMENT '简介',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
insert into student values(0,'2024-02-25 10:10:10','盘古',
'123456','15612345678',255,'神','开天辟地第一人。');
insert into student values(0,'2024-02-25 10:10:10','女娲',
'123456','15612345678',200,'女','多次造人最终成功。');
insert into student values(0,'2024-02-25 10:10:10','伏羲',
'123456','15612345678',215,'神','先天八卦');
insert into student values(0,'2024-02-25 10:10:10','神农',
'123456','15612345678',155,'男','尝百草,死与断肠草下。');
insert into student values(0,'2024-02-25 10:10:10','嫘祖',
'123456','15612345678',115,'神','教会百姓养蚕织布');
insert into student values(0,'2024-02-25 10:10:10','蚩尤',
'123456','15612345678',155,'男','锻造大神,坐下食铁巨兽。');
insert into student (userName,age,introduce) values('仓颉',125,'中国象形文字');

模型创建

创建位置:

跟着数据库的列自己来创建就可以了,需求是:

1、基本属性声明

2、Getter与Setter

3、toString()

package com.item.model;
 
public class Student {
    public int id;
    public String createDate;
    public String userName;
    public String pwd;
    public String phone;
    public int age;
    public char sex;
    public String introduce;
 
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", createDate='" + createDate + '\'' +
                ", userName='" + userName + '\'' +
                ", pwd='" + pwd + '\'' +
                ", phone='" + phone + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", introduce='" + introduce + '\'' +
                '}';
    }
 
    public String getCreateDate() {
        return createDate;
    }
 
    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getUserName() {
        return userName;
    }
 
    public void setUserName(String userName) {
        this.userName = userName;
    }
 
    public String getPwd() {
        return pwd;
    }
 
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
 
    public String getPhone() {
        return phone;
    }
 
    public void setPhone(String phone) {
        this.phone = phone;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public char getSex() {
        return sex;
    }
 
    public void setSex(char sex) {
        this.sex = sex;
    }
 
    public String getIntroduce() {
        return introduce;
    }
 
    public void setIntroduce(String introduce) {
        this.introduce = introduce;
    }
 
}

dao层接口

创建位置:

代码内容:

package com.item.dao;
 
import com.item.model.Student;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
 
import java.util.List;
 
@Repository
public interface StudentMapper {
    /**
     * 查询所有
     * @return
     */
    List<Student> GetInfo();
 
    /**
     * 通过用户名模糊查询
     * @param userName
     * @return
     */
    List<Student> SelectName(@Param("userName") String userName);
 
    /**
     * 精准查询
     * @param id
     * @return
     */
    Student SelectById(@Param("id") int id);
 
    /**
     * 添加信息
     * @param userName
     * @param pwd
     * @param phone
     * @param age
     * @param sex
     * @param introduce
     * @return
     */
    int AddInfo(
            @Param("userName") String userName,
            @Param("pwd") String pwd,
            @Param("phone") String phone,
            @Param("age") int age,
            @Param("sex") char sex,
            @Param("introduce") String introduce
    );
 
    /**
     * 修改信息
     * @param id
     * @param pwd
     * @param introduce
     * @return
     */
    int UpdateInfo(
            @Param("id") int id,
            @Param("pwd") String pwd,
            @Param("introduce") String introduce
    );
 
    /**
     * 根据id删除操作
     * @param id
     * @return
     */
    int DeleteById(@Param("id") int id);
 
}

mapper对应dao层实现

创建位置:

代码内容:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.item.dao.StudentMapper">
    <!-- 用作基础查询测试 -->
    <select id="GetInfo" resultType="Student">
        select * from student
    </select>
    <!-- 用做传递参数测试·支持空查询,返回所有信息 -->
    <select id="SelectName" resultType="Student">
        select * from student where userName like "%${userName}%"
    </select>
    <!-- id精准查询 -->
    <select id="SelectById" resultType="Student">
        select * from student where id=#{id}
    </select>
    <!-- 增加 -->
    <insert id="AddInfo">
        insert into student values(0,now(),"${userName}","${pwd}","${phone}",${age},"${sex}","${introduce}");
    </insert>
    <!-- 修改 -->
    <update id="UpdateInfo">
        update student set pwd="${pwd}",introduce="${introduce}" where id=#{id}
    </update>
    <!-- 删除 -->
    <delete id="DeleteById">
        delete from student where id=#{id}
    </delete>
</mapper>

service层接口

创建地址:

代码内容:

package com.item.service;
 
 
import com.item.model.Student;
 
import java.util.List;
 
public interface StudentService {
    /**
     * 查询所有
     *
     * @return
     */
    List<Student> GetInfo();
 
    /**
     * 通过用户名模糊查询
     *
     * @param userName
     * @return
     */
    List<Student> SelectName(String userName);
 
    /**
     * 精准查询
     *
     * @param id
     * @return
     */
    Student SelectById(int id);
 
    /**
     * 添加信息
     *
     * @param userName
     * @param pwd
     * @param phone
     * @param age
     * @param sex
     * @param introduce
     * @return
     */
    int AddInfo(
            String userName,
            String pwd,
            String phone,
            int age,
            char sex,
            String introduce
    );
 
    /**
     * 修改信息
     *
     * @param id
     * @param pwd
     * @param introduce
     * @return
     */
    int UpdateInfo(
            int id,
            String pwd,
            String introduce
    );
 
    /**
     * 根据id删除操作
     *
     * @param id
     * @return
     */
    int DeleteById(int id);
}

service实现层代码

创建位置:

代码内容:

package com.item.serviceimpl;
 
import com.item.model.Student;
import com.item.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.item.dao.StudentMapper;
 
import java.util.List;
 
@Service
public class StudentServiceImpl implements StudentService {
 
    @Autowired
    private StudentMapper studentMapper;
 
    @Override
    public List<Student> GetInfo() {
        return studentMapper.GetInfo();
    }
 
    @Override
    public List<Student> SelectName(String userName) {
        return studentMapper.SelectName(userName);
    }
 
    @Override
    public Student SelectById(int id) {
        return studentMapper.SelectById(id);
    }
 
    @Override
    public int AddInfo(String userName, String pwd, String phone, int age, char sex, String introduce) {
        return studentMapper.AddInfo(userName, pwd, phone, age, sex, introduce);
    }
 
    @Override
    public int UpdateInfo(int id, String pwd, String introduce) {
        return studentMapper.UpdateInfo(id, pwd, introduce);
    }
 
    @Override
    public int DeleteById(int id) {
        return studentMapper.DeleteById(id);
    }
}

controller接口撰写

创建位置:

编码内容:

package com.item.controller;
 
import com.item.model.Student;
import com.item.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
 
import java.util.HashMap;
import java.util.List;
 
@Api("接口声明")
@RestController
@CrossOrigin
public class StudentController {
    @Autowired
    private StudentService studentService;
 
    /**
     * 获取所有信息
     * @return
     */
    @GetMapping("/GetInfoApi")
    @ApiOperation(value = "获取信息", notes = "没啥留言的")
    public Object GetInfoApi() {
        List<Student> list = studentService.GetInfo();
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("state", true);
        map.put("msg", "成功");
        map.put("result", list);
        return map;
    }
 
    /**
     * 根据用户昵称获取信息
     * @param userName
     * @return
     */
    @GetMapping("/GetName")
    @ApiOperation(value = "获取信息", notes = "没啥留言的")
    @ApiImplicitParams({@ApiImplicitParam(name = "userName", required = true, paramType = "query", dataType = "String", value = "通过昵称模糊查询")})
    public Object GetName(String userName) {
        List<Student> list = studentService.SelectName(userName);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("state", true);
        map.put("msg", "成功");
        map.put("result", list);
        return map;
    }
 
    /**
     * 添加信息
     * @param userName
     * @param pwd
     * @param phone
     * @param age
     * @param sex
     * @param introduce
     * @return
     */
    @PostMapping(value = "/AddInfoApi")
    @ApiOperation(value = "添加", notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", required = true, paramType = "query", dataType = "String", value = "用户名"),
            @ApiImplicitParam(name = "pwd", required = true, paramType = "query", dataType = "String", value = "密码"),
            @ApiImplicitParam(name = "phone", required = true, paramType = "query", dataType = "String", value = "手机号"),
            @ApiImplicitParam(name = "age", required = true, paramType = "query", dataType = "int", value = "年龄"),
            @ApiImplicitParam(name = "sex", required = true, paramType = "query", dataType = "char", value = "性别"),
            @ApiImplicitParam(name = "introduce", required = true, paramType = "query", dataType = "String", value = "简介")
    })
    public Object AddInfoApi(String userName, String pwd, String phone, int age, char sex, String introduce) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(pwd) || StringUtils.isEmpty(introduce)) {
            map.put("state", false);
            map.put("msg", "参数不润许为空");
            map.put("result", "");
            return map;
        }
        studentService.AddInfo(userName, pwd, phone, age, sex, introduce);
        map.put("state", true);
        map.put("msg", "成功");
        map.put("result", "");
        return map;
    }
 
    /**
     * 单个查询
     * @param id
     * @return
     */
    @GetMapping("/SelectById")
    @ApiOperation(value = "id查询", notes = "没啥留言的")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", required = true, paramType = "query", dataType = "int", value = "编号")})
    public Object SelectById(String id) {
        Student student = studentService.SelectById(Integer.parseInt(id));
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("state", true);
        map.put("msg", "成功");
        map.put("result", student);
        return map;
    }
 
    /**
     * 修改信息
     * @param id
     * @param pwd
     * @param introduce
     * @return
     */
    @PostMapping(value = "/UpdateInfoApi")
    @ApiOperation(value = "修改", notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, paramType = "query", dataType = "int", value = "编号",defaultValue = "0"),
            @ApiImplicitParam(name = "pwd", required = true, paramType = "query", dataType = "String", value = "密码"),
            @ApiImplicitParam(name = "introduce", required = true, paramType = "query", dataType = "String", value = "简介")
    })
    public Object UpdateInfoApi(int id, String pwd, String introduce) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        Student student = studentService.SelectById(id);
        if(student==null||StringUtils.isEmpty(pwd)||StringUtils.isEmpty(introduce)){
            map.put("state", false);
            map.put("msg", "错误");
            map.put("result", "信息为空配或id不存在");
            return map;
        }
        studentService.UpdateInfo(id, pwd, introduce);
        map.put("state", true);
        map.put("msg", "成功");
        map.put("result", "");
        return map;
    }
 
    /**
     * 删除api
     * @param id
     * @return
     */
    @PostMapping(value = "/DeleteById")
    @ApiOperation(value = "根据id删除", notes = "输入id就行删除。")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", required = true, paramType = "query", dataType = "int", value = "编号")})
    public Object DeleteById(String id) {
        studentService.DeleteById(Integer.parseInt(id));
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("state", true);
        map.put("msg", "成功");
        map.put("result", "");
        return map;
    }
}

swagger接口访问测试

可以看到我们在controller中创建的接口都在了。

前端调用代码——vue脚手架——2.9.6

一定要提前安装好node.js配置好vue啊。

npm install vue -g
npm install vue-router -g
npm install vue-cli -g
npm install -g @vue/cli-init
vue -v

创建vue项目

vue init webpack springbootvuedemo1

启动项目

启动完毕效果,访问地址:http://localhost:8080/#/

axios安装

由于我们要请求api接口,故而需要axios,这里我就不改版本了,现在都是3.0的vue了,正常版本会报错,所以我这里用的是1.5.0的版本。

npm install axios@1.5.0 --save

不安装就会报错。

如果是之前安装过的需要降低一下版本,修改【package.json】文件中的【dependencies】下【axios】的值为【^1.5.0】,再使用命令安装即可。

安装完毕后重新启动即可。

项目编码

在项目下的【src】->【App.vue】中粘贴以下代码:

<template>
  <div id="App">
    <link
      rel="stylesheet"
      href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
    />
 
    <div class="input-group">
      <span class="input-group-addon">昵称搜索:</span>
      <input
        type="text"
        v-model="selectKey"
        placeholder="请输入搜索昵称关键字"
        class="form-control"
      />
    </div>
    <table class="table table-bordered table-hover">
      <tr class="info">
        <th>编号</th>
        <th>创建时间</th>
        <th>用户名</th>
        <th>密码</th>
        <th>手机号</th>
        <th>年龄</th>
        <th>性别</th>
        <th>简介</th>
        <th>操作</th>
      </tr>
      <tr v-for="item in newlist" v-bind:key="item.id">
        <td>{{ item.id }}</td>
        <td>{{ item.createDate }}</td>
        <td>{{ item.userName }}</td>
        <td>{{ item.pwd }}</td>
        <td>{{ item.phone }}</td>
        <td>{{ item.age }}</td>
        <td>{{ item.sex }}</td>
        <td>{{ item.introduce }}</td>
        <td>
          <button v-on:click="del(item.id)" class="btn btn-info">删除</button>
          <button v-on:click="SetInfo(item)" class="btn btn-info">修改</button>
        </td>
      </tr>
    </table>
    <hr />
    <div id="group-all">
      <div class="group-left">
        <div class="input-group">
          <span class="input-group-addon">姓名:</span>
          <input type="text" v-model="userName_a" class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">密码:</span>
          <input type="text" v-model="pwd_a" class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">手机号:</span>
          <input type="text" v-model="phone_a" class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">年龄:</span>
          <input type="text" v-model="age_a" class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">性别:</span>
          <input type="text" v-model="sex_a" class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">简介:</span>
          <input type="text" v-model="introduce_a" class="form-control" />
        </div>
        <button v-on:click="AddInfo()" class="btn btn-info btn-block">
          添加数据
        </button>
      </div>
      <div class="group-right">
        <div class="input-group">
          <span class="input-group-addon">编号:</span>
          <input type="text" v-model="id" disabled class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">创建时间:</span>
          <input
            type="text"
            v-model="createDate"
            disabled
            class="form-control"
          />
        </div>
        <div class="input-group">
          <span class="input-group-addon">姓名:</span>
          <input type="text" v-model="userName" class="form-control" disabled />
        </div>
        <div class="input-group">
          <span class="input-group-addon">密码:</span>
          <input type="text" v-model="pwd" class="form-control" />
        </div>
        <div class="input-group">
          <span class="input-group-addon">手机号:</span>
          <input type="text" v-model="phone" class="form-control" disabled />
        </div>
        <div class="input-group">
          <span class="input-group-addon">年龄:</span>
          <input type="text" v-model="age" class="form-control" disabled />
        </div>
        <div class="input-group">
          <span class="input-group-addon">性别:</span>
          <input type="text" v-model="sex" class="form-control" disabled />
        </div>
        <div class="input-group">
          <span class="input-group-addon">简介:</span>
          <input type="text" v-model="introduce" class="form-control" />
        </div>
        <button v-on:click="Setting()" class="btn btn-info btn-block">
          修改数据
        </button>
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
 
export default {
  name: "App",
  data: function () {
    return {
      list: [],
      selectKey: "",
      id: "",
      createDate: "",
      userName: "",
      pwd: "",
      phone: "",
      age: 0,
      sex: "",
      introduce: "",
      userName_a: "",
      pwd_a: "",
      phone_a: "",
      age_a: 0,
      sex_a: "",
      introduce_a: "",
    };
  },
  created: function () {
    var _this = this;
    var url = "http://127.0.0.1:8088/MyAPI/GetInfoApi";
    axios.get(url).then(function (res) {
      _this.list = res.data.result;
    });
  },
  computed: {
    //过滤数据
    newlist: function () {
      var _this = this;
      return _this.list.filter(function (o) {
        return o.userName.indexOf(_this.selectKey) != -1;
      });
    },
  },
  methods: {
    //方法集合
    del: function (o) {
      if (confirm("是否删除此行")) {
        var url = "http://127.0.0.1:8088/MyAPI/DeleteById?id=" + o;
        axios.post(url).then(function (response) {
          alert(response.data.msg);
          location.reload();
        });
      }
    },
    SetInfo: function (item) {
      //修改1
      this.id = item.id;
      this.createDate = item.createDate;
      this.userName = item.userName;
      this.pwd = item.pwd;
      this.phone = item.phone;
      this.age = item.age;
      this.sex = item.sex;
      this.introduce = item.introduce;
    },
    AddInfo: function () {
      var url =
        "http://127.0.0.1:8088/MyAPI/AddInfoApi?userName=" +
        this.userName_a +
        "&pwd=" +
        this.pwd_a +
        "&phone=" +
        this.phone_a +
        "&age=" +
        this.age_a +
        "&sex=" +
        this.sex_a +
        "&introduce=" +
        this.introduce_a;
      console.log(url);
      axios.post(url).then(function (retult) {
        alert(retult.data.msg);
        if (retult.data.state) {
          location.reload();
        }
      });
    },
    Setting: function () {
      //修改2
      var url =
        "http://127.0.0.1:8088/MyAPI/UpdateInfoApi?id=" +
        this.id +
        "&pwd=" +
        this.pwd +
        "&introduce=" +
        this.introduce;
      axios.post(url).then(function (retult) {
        alert(retult.data.msg);
        if (retult.data.state) {
          location.reload();
        }
      });
    },
  },
};
</script>
<style>
* {
  padding: 0px;
  margin: 0px;
  box-sizing: border-box;
}
table {
  width: 85%;
  border: 1px solid black;
  margin: 20px auto;
}
td {
  border: 1px solid black;
}
#group-all {
  width: 100%;
}
.group-left {
  float: left;
  width: 50%;
}
.group-right {
  float: right;
  width: 50%;
}
</style>

效果演示:

SpringBootWebProject小型项目——学生管理系统完整搭建

总结

本项目可以从环境到编码让学生们可以彻彻底底的练习一下自己对springboot的熟练程度,其中各个注解也能当做面试题来背诵,我虽然没有写对应的论文文档,但是只要有点心,稍微改一改,或者加上其它的文章一起搞一搞一篇考试的一些内容还是可以搞出来的,祝大家学业顺利。




相关文章
|
17天前
|
前端开发 JavaScript Java
计算机Java项目|图书大厦图书管理系统的设计与实现
计算机Java项目|图书大厦图书管理系统的设计与实现
|
17天前
|
前端开发 JavaScript Java
计算机Java项目|基于Web的足球青训俱乐部管理后台系统的设计与开发
计算机Java项目|基于Web的足球青训俱乐部管理后台系统的设计与开发
|
2月前
|
网络协议 Java 网络安全
基于Jeecgboot前后端分离的流程管理平台演示系统安装(一)
基于Jeecgboot前后端分离的流程管理平台演示系统安装(一)
21 1
|
2月前
|
资源调度 前端开发 Java
基于Jeecgboot前后端分离的流程管理平台演示系统安装(二)
基于Jeecgboot前后端分离的流程管理平台演示系统安装(二)
22 1
|
2月前
|
安全 测试技术 数据库
图书馆信息管理系统(项目需求和计划、项目设计)(上)
图书馆信息管理系统(项目需求和计划、项目设计)(上)
215 1
|
2月前
|
存储 编解码 测试技术
图书馆信息管理系统(项目需求和计划、项目设计)(下)
图书馆信息管理系统(项目需求和计划、项目设计)(下)
238 1
|
2月前
|
资源调度 前端开发 jenkins
基于Jeecgboot前后端分离的流程管理平台演示系统安装(四)
基于Jeecgboot前后端分离的流程管理平台演示系统安装(四)
22 1
|
2月前
|
前端开发 jenkins Java
基于Jeecgboot前后端分离的流程管理平台演示系统安装(三)
基于Jeecgboot前后端分离的流程管理平台演示系统安装(三)
19 1
|
2月前
|
jenkins 持续交付
基于Jeecgboot前后端分离的流程管理平台演示系统安装(五)
基于Jeecgboot前后端分离的流程管理平台演示系统安装(五)
17 0
基于Jeecgboot前后端分离的流程管理平台演示系统安装(五)
|
2月前
小型项目——扫雷游戏(模块化实现)
小型项目——扫雷游戏(模块化实现)
24 0