竞赛信息管理系统——SSM

news2024/9/22 21:25:30

目录

一、项目简介

二、前置配置

1、创建数据库 

2、编写application.yml文件 

三、公共基础类 

1、自定义登录拦截器类

2、自定义拦截规则 

3、统一数据返回类

4、统一异常处理类 

5、工具类 

a、密码工具类

b、时间工具类 

6、全局变量 

四、用户模块 

1、定义用户实体类

2、编写UserMapper接口 

3、编写UserMapper.xml文件 

4、定义UserService类 

5、UserController处理请求

a、用户登录 

b、用户注册 

c、用户注销 

五、竞赛信息模块 

1、定义竞赛信息实体类

2、实现CompetitionMapper接口文件

3、编写CompetitionMapper.xml文件 

4、定义CompetitionService类 

6、CompetitionController处理请求 

a、添加竞赛信息 

b、修改竞赛信息 

c、删除单条竞赛信息 

d、删除多条竞赛信息 

e、查询并分页展示所有的竞赛信息 

六、效果展示 


一、项目简介

竞赛信息管理系统,针对竞赛信息管理的需求,面向对竞赛管理的管理员用户,基于B/S体系架构,后端采用SpringBoot技术,前端使用BootStrap框架,实现对竞赛信息进行增删改查功能,管理员也具有注册、登录以及注销功能。

二、前置配置

1、创建数据库 

在数据库中设计两张表,分别表示用户表以及管理员表。

-- 创建competition数据库
drop database if exists competition;
create database competition character set 'utf8mb4';
use competition;
-- 创建竞赛信息表
create table competition_info
(
    competition_id int primary key auto_increment,
    competition_name varchar(100) unique ,
    competition_description varchar(100) not null,
    publication_date datetime not null,
    submission_deadline datetime not null,
    sponsor varchar(100) not null,
    venue varchar(100) not null
)default charset='utf8mb4';
-- 创建管理员表
create table user
(
    uid int primary key auto_increment,
    username varchar(50) unique ,
    password varchar(65) not null
)default charset='utf8mb4';

2、编写application.yml文件 

# 配置数据库的连接字符串
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1/competition?characterEncoding=utf8
    username: root
    password: gsy20021014
    driver-class-name: com.mysql.cj.jdbc.Driver
# 设置 Mybatis 的 xml 保存路径
mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置打印 MyBatis 执行的 SQL
logging:
  level:
    com:
      demo:
        usermanager: debug

三、公共基础类 

1、自定义登录拦截器类

根据session会话信息来判断用户是否登录,用户访问页面时如果不是登录状态,就会将用户跳转到登录页面,让用户登录之后在进行操作。

@Component
public class LoginIntercept implements HandlerInterceptor {
    /*
    true:已将登录状态
    false:未登录状态
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        if(session != null && session.getAttribute(ConstVariable.USER_SESSION_KEY) != null){
            //表示已经在登录状态
            return true;
        }
        //未在登录状态,跳转到登录页面
        response.sendRedirect("/login.html");
        return false;
    }
}

2、自定义拦截规则 

除了与登录有关的接口活或页面以及注册相关的不被拦截之外,别的都要被拦截。

@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Autowired
    private  LoginIntercept loginIntercept;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        System.out.println(registry.addInterceptor(loginIntercept).
                addPathPatterns("/**").
                excludePathPatterns("/css/**").
                excludePathPatterns("/js/**").
                excludePathPatterns("/images/**").
                excludePathPatterns("/login").
                excludePathPatterns("/adduser").
                excludePathPatterns("/**/login.html")
                .excludePathPatterns("/**/addUser.html")
        );
    }
}

3、统一数据返回类

需要实现ResponseBodyAdvice接口,supports方法表示是否支持使用下面自定义的数据返回,beforeBodyWrite方法来自定义数据返回的格式。

public class MyResponseAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        HashMap<String,Object> res = new HashMap<>();
        res.put("state",1);
        res.put("msg","");
        res.put("data",body);
        return res;
    }
}

4、统一异常处理类 

对异常返回的格式进行了统一处理。

@RestControllerAdvice
public class MyExceptionAdvice {
    @ExceptionHandler(Exception.class)
    public Object exceptionAdvice(Exception e){
        Map<String,Object> res = new HashMap<>();
        res.put("state:",-1);
        res.put("errorMessage",e.getMessage());
        res.put("data","");
        return res;
    }
}

5、工具类 

a、密码工具类

对用户的密码使用md5和加盐的形式进行加密。

md5:是将任意长度的输入通过一个算法然后生成一个128位的输出,通常情况下是用32位的16进制来表示,其加密是不可逆的即加密之后不能通过加密的数据来推测出未加密的密码。

加盐:由于md5对于同一个密码加密的结果是固定的,风险较大,就需要使用到加盐,也就是给原密码加上一个随机数,之间再加上#是为了方便解密。

public class PasswordUtil {
    /*加密操作*/
    public static String encryption(String password){
        String salt = IdUtil.simpleUUID();//生成随机的32位盐值
        String midpwd = SecureUtil.md5(salt+password);
        return salt+"#"+midpwd;//方便解密
    }
    /*解密:判断密码是否相同,并不能得到解密后的密码*/
    public static boolean decrypt(String password,String truePassword){
        if(StringUtils.hasLength(password) && StringUtils.hasLength(truePassword)){
            if(truePassword.length() == 65 && truePassword.contains("#")){
                String[] pwd = truePassword.split("#");
                String salt = pwd[0];//得到盐值
                String midPassword = pwd[1];//得到盐值+密码使用md5加密后的密码
                password = SecureUtil.md5(salt+password);
                if(password.equals(midPassword)){
                    return true;
                }
            }
        }
        return false;
    }

b、时间工具类 

由于竞赛信息需要用到发布时间以及截止时间,就使用SimpleDateFormat对时间格式进行统一处理。

public class DateUtil {
    public static boolean isValid(String dateStr) {
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setLenient(false);
        try {
            sdf.parse(dateStr);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }

}

6、全局变量 

存放session用户的id。

public class ConstVariable {
    //表示session用户的id
    public static final String USER_SESSION_KEY = "user_session_key";
}

四、用户模块 

1、定义用户实体类

@Data
public class User {
    private int uid;
    private String username;
    private String password;
}

2、编写UserMapper接口 

@Mapper
public interface UserMapper {
    //根据用户名获取用户信息
    User getUserByName(@Param("username") String username);
    //添加用户,返回受影响的函数
    int addUser(User user);
    //删除用户,返回受影响的行数
    int deleteUser(@Param("uid") Integer uid);
}

3、编写UserMapper.xml文件 

编写对用户表进行操作的sql语句。

<?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.example.competition.mapper.UserMapper">
    <insert id="addUser">
        insert into user(username,password) values(#{username},#{password});
    </insert>
    <delete id="deleteUser">
        delete from user where uid=#{uid}
    </delete>

    <select id="getUserByName" resultType="com.example.competition.bean.User">
        select * from user where username=#{username}
    </select>
</mapper>

4、定义UserService类 

由于接口层一次性只处理一个sql操作,当某一个功能想要完成两个甚至以上的操作的时候就需要使用service层将这些sql操作给封装起来然后再供控制层调用。

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public User getUserByName(String name) {
        return userMapper.getUserByName(name);
    }
    public int addUser(User user){
        return userMapper.addUser(user);
    }
    public int deleteUser(Integer uid){
        return userMapper.deleteUser(uid);
    }
}

5、UserController处理请求

首先将UserService注入进来。

@Autowired
    private UserService userService;

a、用户登录 

对接口传入的密码和用户名进行判空操作,然后根据用户名得到用户信息,得到数据库中的用户密码与传入的密码进行解密对比,如果一致则登录成功,存储用户的session会话信息,否则登录失败。

//用户登录方法
    @RequestMapping("/login")
    public boolean login(HttpServletRequest request, String username, String password){
        if(StringUtils.hasLength(username) && StringUtils.hasLength(password)){
            User user = userService.getUserByName(username);
            //对数据库中的密码和传入的密码进行解密对比
            if(PasswordUtil.decrypt(password,user.getPassword())){
                if(user != null && user.getUid() > 0){
                    //存储session会话信息
                    HttpSession session = request.getSession(true);
                    session.setAttribute(ConstVariable.USER_SESSION_KEY,user);
                    return true;
                }
            }
        }
        return false;
    }

前端代码实现:

 <script>
        function login(){
            //对登录名和密码进行非空校验
            var username = jQuery("#username");
            var password = jQuery("#password");
            //对首部去空格后进行非空校验
            if(jQuery.trim(username.val()) === ""){
                alert("请输入登录名");
                //清除原有数据,将光标定位到输入框起始位置
                loginname.focus();
            }
            if(jQuery.trim(password.val()) === ""){
                alert("请输入密码");
                password.focus();
            }
            jQuery.ajax({
                url:"login",
                type:"GET",
                data:{"username":username.val(),"password":password.val()},
                success:function (result){
                    if(result != null && result.data === true){
                        location.href = "list.html";
                    }else{
                        alert("用户名或密码输入错误");
                    }
                }

            });
        }
    </script>

b、用户注册 

首先对传入的用户进行判空操作,接着对用户名做唯一性校验,最后对用户密码进行加密之后再存入数据库中。

//添加用户,返回受影响的行数
    @RequestMapping("/adduser")
    public int addUser(User user){
        int res = 0;
        if(user == null){
            return res;
        }
        //对用户名做唯一性校验
        if(userService.getUserByName(user.getUsername()) != null){
            return res;
        }
        //对添加的用户的密码进行加密
        user.setPassword(PasswordUtil.encryption(user.getPassword()));
        res = userService.addUser(user);
        return res;
    }

前端代码实现: 

<script>
    //进行注册操作
    function reg(){
        var username = jQuery("#username");
        var password = jQuery("#password");
        var password2 = jQuery("#password2");
        //非空校验
        if(jQuery.trim(username.val()) === ""){
            alert("请先输入用户名");
            username.focus();
            return false;
        }

        if(jQuery.trim(password.val()) === ""){
            alert("请先输入密码");
            password.focus();
            return false;
        }
        if(jQuery.trim(password2.val()) === ""){
            alert("请先输入确认密码");
            password2.focus();
            return false;
        }
        if(password.val() !== password2.val()){
            alert("两次密码输入不一致,请重新输入");
            password.focus();
            password2.focus();
            return false;
        }
        jQuery.ajax({
            url:"adduser",
            type:"POST",
            data:{
                "username":username.val(),
                "password":password.val(),
            },
            success:function(result){
                if(result.data > 0){
                    alert("添加成功!");
                    location.href = "login.html";
                }
            }
        });
    }

</script>

c、用户注销 

获取当前用户的会话信息,拿到用户的userid,将用户从数据库中进行删除。

//删除用户,返回受影响的行数
    @RequestMapping("/deleteuser")
    public int deleteUser(HttpServletRequest request){
        HttpSession session = request.getSession(false);
        User user = (User)session.getAttribute(ConstVariable.USER_SESSION_KEY);
        if(user != null){
            return userService.deleteUser(user.getUid());
        }
        return 0;
    }

前端代码实现: 

function logout(){
        if(confirm("确认注销当前用户吗")){
            jQuery.ajax({
                url:"deleteuser",
                type:"POST",
                success : function(result) {
                    if (result != null && result.data > 0) {
                        alert("注销用户成功");
                        location.href = "login.html";
                    }else{
                        alert("注销用户失败");
                    }
                }
            })
        }
    }

五、竞赛信息模块 

1、定义竞赛信息实体类

@Data
public class Competition {
    private int competition_id;
    private String competition_name;
    private String competition_description;
    private String publication_date;
    private String submission_deadline;
    private String sponsor;
    private String venue;
}

2、实现CompetitionMapper接口文件

@Mapper
public interface CompetitionMapper {
    //添加竞赛信息
    int addCompetitionMap(Competition competition);
    //根据竞赛名称查询竞赛信息
    Competition getCompetitionByName(@Param("competition_name")String competition_name);
    //查询所有的竞赛信息
    List<Competition> getAllCompetitions();
    //删除指定id的竞赛信息,返回受影响的行数
    int deleteCompetition(@Param("competition_id")Integer competition_id);
    //删除id集合中的所有竞赛信息,返回受影响的行数
    int deleteCompetitions(@Param("competition_ids") List<Integer> competition_ids);
    //查询指定id的竞赛信息
    Competition getCompetitionById(@Param("competition_id")Integer competition_id);
    //修改竞赛信息,返回受影响的行数
    int updateCompetition(Competition competition);
    //查询指定的竞赛信息
    List<Competition> list(@Param("competition_name") String competition_name,@Param("publication_date") String publication_date,
                           @Param("submission_deadline") String submission_deadline,@Param("limit") Integer limit,@Param("offset") Integer offset);
    //查询指定竞赛信息的数目
    int getCount(@Param("competition_name") String competition_name,@Param("publication_date") String publication_date,
                 @Param("submission_deadline") String submission_deadline);

}

3、编写CompetitionMapper.xml文件 

编写sql语句对数据库中的Competition表进行相关操作。

<?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.example.competition.mapper.CompetitionMapper">
    <insert id="addCompetitionMap">
        insert into competition_info(competition_name,competition_description,publication_date,
                                     submission_deadline,sponsor,venue)
        values(#{competition_name},#{competition_description},#{publication_date},#{submission_deadline},
               #{sponsor},#{venue})
    </insert>
    <update id="updateCompetition">
        update competition_info set competition_name=#{competition_name},competition_description=#{competition_description},
                                    publication_date=#{publication_date},submission_deadline=#{submission_deadline},
                                    sponsor=#{sponsor},venue=#{venue}
        where competition_id=#{competition_id}
    </update>
    <delete id="deleteCompetition">
        delete from competition_info where competition_id=#{competition_id};
    </delete>
    <delete id="deleteCompetitions">
        delete from competition_info where competition_id in
            <foreach collection="competition_ids" item="competition_id" separator="," open="(" close=")">
                #{competition_id}
            </foreach>
    </delete>
    <select id="getCompetitionByName" resultType="com.example.competition.bean.Competition">
        select * from competition_info where competition_name=#{competition_name}
    </select>
    <select id="getAllCompetitions" resultType="com.example.competition.bean.Competition">
        select * from competition_info
    </select>
    <select id="getCompetitionById" resultType="com.example.competition.bean.Competition">
        select * from competition_info where competition_id=#{competition_id}
    </select>
    <select id="list" resultType="com.example.competition.bean.Competition">
        select * from competition_info
        <where>
            <if test="competition_name!=null">
                competition_name like concat('%',#{competition_name},'%')
            </if>
            <if test="publication_date!=null">
               and publication_date=#{publication_date}
            </if>
            <if test="submission_deadline!=null">
                and submission_deadline=#{submission_deadline}
            </if>
        </where>
        limit #{limit} offset #{offset}
    </select>
    <select id="getCount" resultType="java.lang.Integer">
        select count(*) from competition_info
        <where>
            <if test="competition_name!=null">
                competition_name like concat('%',#{competition_name},'%')
            </if>
            <if test="publication_date!=null">
                and publication_date=#{publication_date}
            </if>
            <if test="submission_deadline!=null">
                and submission_deadline=#{submission_deadline}
            </if>
        </where>
    </select>

</mapper>

4、定义CompetitionService类 

@Service
public class CompetitionService {
    @Autowired
    private CompetitionMapper competitionMapper;
    public int addCompetition(Competition competition){
        return competitionMapper.addCompetitionMap(competition);
    }
    public Competition getCompetitionByName(String competition_name) {
        return competitionMapper.getCompetitionByName(competition_name);
    }
    public List<Competition> getAllCompetitions(){
        return competitionMapper.getAllCompetitions();
    }
    public int deleteCompetition(Integer competition_id){
        return competitionMapper.deleteCompetition(competition_id);
    }
    public int deleteCompetitions(List<Integer> competition_ids){
        return competitionMapper.deleteCompetitions(competition_ids);
    }
    public Competition getCompetitionById(Integer competition_id){
        return competitionMapper.getCompetitionById(competition_id);
    }
    public int updateCompetition(Competition competition){
        return competitionMapper.updateCompetition(competition);
    }
    public List<Competition> list(String competition_name, String publication_date,
                                   String submission_deadline,Integer limit,Integer offset){
        return competitionMapper.list(competition_name, publication_date, submission_deadline, limit, offset);
    }
    public int getCount(String competition_name, String publication_date,
                        String submission_deadline){
        return competitionMapper.getCount(competition_name, publication_date, submission_deadline);
    }
}

6、CompetitionController处理请求 

首先将CompetitionService注入进来,方便后续进行调用。

@Autowired
CompetitionService competitionService;

a、添加竞赛信息 

在添加竞赛信息时,首先判断竞赛信息是否为空,接着对竞赛名称进行唯一性校验,然后对竞赛信息的时间格式进行判断,都满足后将竞赛信息添加到数据库。

//添加竞赛返回受影响的行数,如果是时间格式不符,则返回-1
    @RequestMapping("/addcompetition")
    public int addCompetition(Competition competition){
        int res = 0;
        if(competition == null){
            return res;
        }
        //确保竞赛名的唯一性
        if(competitionService.getCompetitionByName(competition.getCompetition_name()) != null){
            return res;
        }
        DateUtil.isValid(competition.getPublication_date());
        //确保插入的时间格式正确
        if( !DateUtil.isValid(competition.getPublication_date()) || !DateUtil.isValid(competition.getSubmission_deadline())){
            return -1;
        }
        res = competitionService.addCompetition(competition);
        return res;
    }

前端代码实现: 

<script>
    //进行添加操作
    function add(){
        var competition_name = jQuery("#competition_name");
        var competition_description = jQuery("#competition_description");
        var publication_date= jQuery("#publication_date");
        var submission_deadline = jQuery("#submission_deadline");
        var venue = jQuery("#venue");
        var sponsor = jQuery("#sponsor");
        //非空校验
        if(jQuery.trim(competition_name.val()) === ""){
            alert("请先输入竞赛名称");
            competition_name.focus();
            return false;
        }
        if(jQuery.trim(competition_description.val()) === ""){
            alert("请先输入竞赛描述");
            competition_description.focus();
            return false;
        }
        if(jQuery.trim(publication_date.val()) === ""){
            alert("请先输入发布时间");
            publication_data.focus();
            return false;
        }
        if(jQuery.trim(submission_deadline.val()) === ""){
            alert("请先输入截止时间");
            submission_deadline.focus();
            return false;
        }
        if(jQuery.trim(sponsor.val()) === ""){
            alert("请先输入赞助商");
            sponsor.focus();
            return false;
        }
        if(jQuery.trim(venue.val()) === ""){
            alert("请先输入地点");
            venue.focus();
            return false;
        }
        jQuery.ajax({
            url:"addcompetition",
            type:"POST",
            data:{
                "competition_name":competition_name.val(),
                "competition_description":competition_description.val(),
                "publication_date":publication_date.val(),
                "submission_deadline":submission_deadline.val(),
                "sponsor":sponsor.val(),
                "venue":venue.val()
            },
            success:function(result){
                if(result != null ){
                    if(result.data > 0){
                        alert("添加成功!");
                        if(confirm("是否继续添加?")){
                            location.href = location.href;
                        }else{
                            location.href = "list.html";
                        }
                    }else if(result.data == -1){
                        alert("时间格式输入不正确,请重新输入");
                    }else{
                        alert("添加失败")
                    }

                }
            }
        });
    }

</script>

b、修改竞赛信息 

修改竞赛信息时,竞赛名称是不能被修改的,然后对修改后的竞赛信息的时间格式进行判断,满足后数据库的竞赛格式进行修改。

 //修改竞赛信息
    @RequestMapping("/updatecompetition")
    public int updateCompetition(Competition competition){
        int res = 0;
        if(competition == null){
            return res;
        }

        DateUtil.isValid(competition.getPublication_date());
        //确保插入的时间格式正确
        if( !DateUtil.isValid(competition.getPublication_date()) || !DateUtil.isValid(competition.getSubmission_deadline())){
            return -1;
        }
        res = competitionService.updateCompetition(competition);
        return res;
    }

前端代码实现:

首先需要获取到url中的竞赛信息的竞赛编号。

 //获取到url中的指定参数
    function getParamvalue(key){
        var url = location.search;
        if(url != ""){
            url = url.substr(1);//获取到?后的字符串即查询字符串
            var kvs = url.split("&");
            for(var i = 0;i < kvs.length;i++){
                var kv = kvs[i].split("=");
                if(kv[0] == key){
                    return kv[1];
                }
            }
        }else{
            return "";
        }
    }

然后将要修改的竞赛信息展示出来。 

//将要修改的用户信息展示出来
    function getUserInfo(){
         competition_id=getParamvalue("competition_id");
        jQuery.ajax({
            url:"getcompetitionbyid",
            type:"GET",
            data:{"competition_id":competition_id,},
            success:function(result){
                if(result != null && result.data != null ){
                    var competition = result.data;
                    jQuery("#competition_name").val(competition.competition_name);
                    jQuery("#competition_description").val(competition.competition_description);
                    jQuery("#publication_date").val(competition.publication_date);
                    jQuery("#submission_deadline").val(competition.submission_deadline);
                    jQuery("#sponsor").val(competition.sponsor);
                    jQuery("#venue").val(competition.venue);
                }else{
                    alert("请求错误!")
                }
            }
        })
    }

对竞赛信息进行修改。 

function myUpdate(){
        var competition_name = jQuery("#competition_name");
        var competition_description = jQuery("#competition_description");
        var publication_date= jQuery("#publication_date");
        var submission_deadline = jQuery("#submission_deadline");
        var venue = jQuery("#venue");
        var sponsor = jQuery("#sponsor");
        //非空校验
        if(jQuery.trim(competition_name.val()) === ""){
            alert("请先输入竞赛名称");
            competition_name.focus();
            return false;
        }
        if(jQuery.trim(competition_description.val()) === ""){
            alert("请先输入竞赛描述");
            competition_description.focus();
            return false;
        }
        if(jQuery.trim(publication_date.val()) === ""){
            alert("请先输入发布时间");
            publication_data.focus();
            return false;
        }
        if(jQuery.trim(submission_deadline.val()) === ""){
            alert("请先输入截止时间");
            submission_deadline.focus();
            return false;
        }
        if(jQuery.trim(sponsor.val()) === ""){
            alert("请先输入赞助商");
            sponsor.focus();
            return false;
        }
        if(jQuery.trim(venue.val()) === ""){
            alert("请先输入地点");
            venue.focus();
            return false;
        }
        jQuery.ajax({
            url:"updatecompetition",
            type:"POST",
            data:{
                "competition_id":competition_id,
                "competition_name":competition_name.val(),
                "competition_description":competition_description.val(),
                "publication_date":publication_date.val(),
                "submission_deadline":submission_deadline.val(),
                "sponsor":sponsor.val(),
                "venue":venue.val()
            },
            success:function (result){
                if(result != null ){
                    if(result.data > 0){
                        alert("修改成功!");
                        location.href = "list.html";
                    }else if(result.data === -1){
                        alert("时间格式输入不正确,请重新输入");
                    }else{
                        alert("修改失败")
                    }

                }
            }
        })
    }

c、删除单条竞赛信息 

根据竞赛信息的id来对竞赛信息进行删除。

//删除指定id的竞赛信息
    @RequestMapping("/deletecompetition")
    public int deleteCompetition(Integer competition_id){
        int res = 0;
        if(competition_id == null || competition_id <= 0){
            return res;
        }
        res = competitionService.deleteCompetition(competition_id);
        return res;
    }

前端代码实现: 

function deleteCompetition(competition_id){
        if(confirm("确认删除本条竞赛信息吗?一旦删除,数据不可恢复!")){
            jQuery.ajax({
                url:"deletecompetition",
                type:"POST",
                data:{"competition_id":competition_id},
                success:function (result){
                    if(result != null && result.data > 0){
                        alert("删除成功");
                        //页面刷新
                        location.href = location.href;
                    }else{
                        alert("删除失败");
                    }
                }
            });
        }
    }

d、删除多条竞赛信息 

将要删除的竞赛信息的id存入一个集合中进行删除。

//删除指定id集合的竞赛信息
    @RequestMapping("/deletecompetitions")
    public int deleteCompetitions( @RequestParam List<Integer> competition_ids){
        int res = 0;
        if(competition_ids == null){
            return res;
        }
        res = competitionService.deleteCompetitions(competition_ids);
        return res;
    }

前端代码实现:

function deleteCompetitions(){
        if(confirm("确认删除所选的竞赛信息吗?一旦删除,数据不可恢复!")){
            var competition_ids ="";
            jQuery("#info").find("tr").each(function (i){
                if(jQuery(this).find("th:first").find("input").prop("checked")===true){
                    competition_ids +=jQuery(this).find("th:first").find("input").attr("id")+",";
                }
            });
            if(competition_ids !== ""){
                jQuery.ajax({
                    url:"deletecompetitions",
                    type:"POST",
                    data:{"competition_ids":competition_ids},
                    success:function (result){
                        if(result != null && result.data > 0){
                            alert("删除成功");
                            //页面刷新
                            location.href = location.href;
                        }else{
                            alert("删除失败");
                        }
                    }
                })
            }
        }
    }

e、查询并分页展示所有的竞赛信息 

可以对所有的竞赛信息进行竞赛名称、发布时间和截止时间进行查询,如果未输入任何查询信息就展示出所有的竞赛信息,默认从第一页开始,每页展示10条竞赛信息。

//分页查询竞赛信息
    @RequestMapping("/list")
    public HashMap<String,Object> list(String competition_name, String publication_date,
                                       String submission_deadline,Integer index,Integer size){
        if(index == null || index <= 0){
            index = 1;
        }
        if(size == null || size <= 0){
            size = 10;
        }
        if(!StringUtils.hasLength(competition_name)){
            competition_name = null;
        }
        if(!StringUtils.hasLength(publication_date)){
            publication_date = null;
        }
        if(!StringUtils.hasLength(submission_deadline)){
            submission_deadline = null;
        }
        int offset = (index - 1) * size;
        HashMap<String,Object> result = new HashMap<>();
        List<Competition> list = competitionService.list(competition_name,publication_date,submission_deadline,size,offset);
        int count = competitionService.getCount(competition_name,publication_date,submission_deadline);
        result.put("list",list);
        result.put("count",count);
        return result;

    }

前端代码实现: 

首先初始化页面,获取到竞赛信息,默认从第一页进行查询。

//定义全局变量
    var competition_name="";
    var publication_date="";
    var submission_deadline="";
    var pages=0;//总页数
    var count=0;//总条数
    var index=1;//当前页数
    var size=10;//每页显示的用户数目
    //获取到url中的指定参数
    function getParamvalue(key){
        var url = location.search;
        if(url !== ""){
            url = url.substr(1);//获取到?后的字符串即查询字符串
            var kvs = url.split("&");
            for(var i = 0;i < kvs.length;i++){
                var kv = kvs[i].split("=");
                if(kv[0] === key){
                    return decodeURIComponent(kv[1]);
                }
            }
        }else{
            return "";
        }
    }
    function firstPage(){
        location.href="list.html?index=1&competition_name="+competition_name+"&publication_date="+publication_date+"&submission_deadline="+submission_deadline;
    }
    function lastPage(){
        location.href="list.html?index="+pages+"&competition_name="+competition_name+"&publication_date="+publication_date+"&submission_deadline="+submission_deadline;
    }
    function nextPage(){
        if(index >= pages){
            alert("已经是最后一页了!");
        }else{
            index=parseInt(index)+1;
            location.href="list.html?index="+index+"&competition_name="+competition_name+"&publication_date="+publication_date+"&submission_deadline="+submission_deadline;
        }
    }
    function prePage(){
        if(index <=1){
            alert("已经是第一页了!");
        }else{
            index=parseInt(index)-1;
            location.href="list.html?index="+index+"&competition_name="+competition_name+"&publication_date="+publication_date+"&submission_deadline="+submission_deadline;
        }
    }
    //获取竞赛信息列表
    function getList(){
        jQuery.ajax({
            url:"list",
            type:"GET",
            data:{
                "competition_name":competition_name,
                "publication_date":publication_date,
                "submission_deadline":submission_deadline,
                "index":index,
                "size":size
            },
            success:function(result){
                if(result != null && result.data != null) {
                    var listDiv = "";
                    count = result.data.count;//获取到总的用户数
                    pages = Math.ceil(parseInt(count) / size);
                    jQuery("#pageinfo").html("共" + count + "条数据,共" + pages + "页");
                    if (result.data.list.length>0) {
                        for (var i = 0; i < result.data.list.length; i++) {
                            var competition = result.data.list[i];
                            listDiv += '<tr>';
                            listDiv += '<th>';
                            listDiv += '<input id="' + competition.competition_id+ '" type="checkbox"></th>';
                            listDiv += '<th>' + competition.competition_id + '</th>';
                            listDiv += '<th>' + competition.competition_name + '</th>';
                            listDiv += '<th>' + competition.competition_description + '</th>';
                            listDiv += '<th>' + competition.publication_date + '</th>';
                            listDiv += '<th>' + competition.submission_deadline + '</th>';
                            listDiv += '<th>' + competition.sponsor + '</th>';
                            listDiv += '<th>' + competition.venue + '</th>';
                            listDiv += '<th>';
                            listDiv += '<a class="btn btn-default btn-sm" href="update.html?competition_id=' + competition.competition_id + '">修改</a>';
                            listDiv += '<a class="btn btn-default btn-sm" href="javascript:deleteCompetition(' + competition.competition_id + ');">删除</a>';
                            listDiv += '</th></tr>';
                        }
                        jQuery("#info").html(listDiv);
                    }
                }
            }
        });
    }    
//初始化页面
    function init(){
        competition_name=getParamvalue("competition_name");
        publication_date=getParamvalue("publication_date");
        submission_deadline=getParamvalue("submission_deadline");
        index=getParamvalue("index");
        if(index == null || index === ""){
            index=1;
        }
        getList();
    }

如果要进行条件查询,先获取到查询信息,再进行分页查询。 

//查询功能
    function myQuery(){
        competition_name = jQuery.trim(jQuery("#competition_name").val());
        publication_date = jQuery.trim(jQuery("#publication_date").val());
        submission_deadline = jQuery.trim(jQuery("#submission_deadline").val());
        getList();
        firstPage();
    }

六、效果展示 

登陆页面:

注册页面: 

 

竞赛信息页面: 

添加竞赛信息页面: 

修改竞赛信息页面: 

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

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

相关文章

echarts环形图两层

1、实现效果 环形图&#xff0c;有两层环形&#xff0c;扇形之间有间隔&#xff0c;中间是标题&#xff0c;图例是自定义图片 2、实现 在template里写一个盒子放图表 <div class"chartMachineStyle" ref"chartMachine"></div>在style里设置盒…

状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

从今天起&#xff0c;我们开始学习状态模式。在实际的软件开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上来看&#xff0c;它有点像我们之前讲到的组合模式。 可以简短的回顾一下组合模式&#xff1a…

Windows cmd窗口下的代码页

查看当前的活动代码页 在cmd窗口下执行命令chcp可以查看当前的活动代码页&#xff1a; 临时修改活动代码页 在cmd窗口下执行命令chcp [nnn]&#xff0c;可以临时修改活动代码页&#xff08;窗口关闭后修改就失效了&#xff09;&#xff0c;其中[nnn]表示具体的代码页标识符…

Java 中的反射是什么?如何使用它?

Java 中的反射是什么&#xff1f;如何使用它&#xff1f; 在 Java 编程中&#xff0c;反射是一种高级的编程技术&#xff0c;可以在运行时动态地获取和操作类的信息。反射使得程序可以在运行时对类进行检查和操作&#xff0c;而不需要在编译时知道类的完整信息。这使得程序可以…

flstudio怎么保存工程文件?详解FL Studio 21保存文件的方法

FL Studio 21全称Fruity Loops Studio2023&#xff0c;这款软件也被人们亲切的称之为水果&#xff0c;它是一款功能强大的音乐创作编辑软件&#xff0c;拥有全功能的录音室&#xff0c;大混音盘以及先进的音乐制作工具&#xff0c;用户通过使用该软件&#xff0c;就可以轻松制作…

Ubuntu下搭建Redis分片集群

目录 准备实例和配置 启动分片集群 测试分片集群 分片集群需要的节点数量较多&#xff0c;搭建一个最小的分片集群&#xff0c;包含3个master节点&#xff0c;每个master包含一个slave节点&#xff0c;并且master之间通过心跳机制互相监听&#xff0c;此模式下不需要哨兵监听…

js高级进阶:promise同步编程技巧

promise是ES6引进的异步编程解决方案&#xff0c;是一个构造函数&#xff0c;可以实例化对象&#xff0c;可以解决回调地狱的问题。 首先我们看一下promise的实例化对象是什么&#xff1a; let P new Promise(function(){});//new一个promise传入一个函数console.log(P);打印结…

读发布!设计与部署稳定的分布式系统(第2版)笔记23_互联层之DNS

1. 互连层是可以真正构建高可用性的地方 1.1. 流量管理 1.2. 负载均衡 1.3. 服务发现 2. 不同规模的解决方案 2.1. 在小公司中 2.1.1. 只有少数开发人员的小企业可以直接使用DNS条目 2.1.2. 生成变更的开发人员较少&#xff0c;变更频度变低 2.1.3. 可能根本就没有独立…

高阶C语言|指针的进阶

指针的主题&#xff0c;在指针初阶阶段&#xff0c;我们知道了指针的概念&#xff1a; 1.指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 2.指针的大小是固定4/8个字节&#xff08;32为平台/64位平台&#xff09;。 3.指针是有类型&#xff0c…

java+springboot基于云的学习笔记系统设计与开发 _44va6

学习笔记系统按照权限的类型进行划分&#xff0c;分为管理员和用户共两个模块。系统实现登录、个人信息修改&#xff0c;还可以对个人中心&#xff0c;用户管理&#xff0c;笔记本管理&#xff0c;笔记分享管理&#xff0c;分享类型管理&#xff0c;学习资料管理&#xff0c;购…

Makefile:10分钟带你了解makefile

1、Makefile是什么 在Linux系统中&#xff0c;Makefile是一个脚本文件&#xff0c;通常名为Makefile或者makefile&#xff0c;它使得程序员能够快速便捷地完成调用程序、编译代码、定位故障等工作。 Makefile是一个用于自动化构建和编译程序的脚本文件。它包含了程序的所有源…

Ubuntu下配置Redis哨兵集群

目录 准备实例和配置 启动哨兵集群 测试配置 搭建一个三节点形成的Sentinel集群&#xff0c;来监管Redis主从集群。 三个sentinel哨兵实例信息如下&#xff1a; 节点IPPORTs1192.168.22.13527001s2192.168.22.13527002s3192.168.22.13527003 准备实例和配置 要在同一台虚…

01. Docker基础环境构建

目录 1、前言 2、关于Docker 2.1、几个术语 2.2、Docker容器化的价值 3、搭建基础环境 3.1、安装VMware 3.2、安装Doker 3.3、启动 3.4、验证Docker环境 4、小结 1、前言 在这里我们将学习关于Docker的一些技能知识&#xff0c;那么首先我们应该怼Docker有一个基础的…

服务器离线部署docker,镜像迁移,mysql主从搭建等服务

公司项目要上线项目&#xff0c;买了两台云服务器&#xff0c;需进行环境部署&#xff08;1台接入公网&#xff0c;一台只能局域网访问&#xff09;&#xff0c;主要部署以下内容 1、服务器之间配置ssh免密 2、离线docker部署 3、docker镜像迁移 4、redis服务 5、minio文件…

Idea配置Maven优先从本地仓库获取依赖

idea配置maven依赖优先从指定本地仓库获取 在设置中搜索 Runner ,在VM Option中设置参数-DarchetypeCataloginternal <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http…

沐风老师MaxScript快速入门教程

Maxscript是将自定义3dMax应用的更强大的方法之一。结合内置的侦听器和编辑器&#xff0c;我们在运行时操作和测试代码&#xff0c;使其成为用户试验和探索改进软件体验的强大选项。通过Maxscript&#xff0c;我们几乎可以操作软件中的每一个对象&#xff0c;包括但不限于&…

【C++】-vector的模拟实现(以及memcpy如何使用)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

Spring-MVC的注解扫描-spring17

包括我们业务层和Dao层&#xff0c;去帮助别人去扫 只扫controller下的注解

00_YS_硬件电路图

1.主控制芯片的型号 STM32F407IGT6&#xff0c;LQFP-176&#xff0c;1MB 内部 FLASH&#xff0c;192KB RAM USART3 RS485 通信&#xff0c;芯片使用 SP3072EEN; UART5 RS232 通信&#xff0c; CAN 1 路&#xff0c;型号 SN65HVD230 USB 支持 …

Python应用实例(二)数据可视化(三)

数据可视化&#xff08;三&#xff09; 1.使用Plotly模拟掷骰子1.1 安装Plotly1.2 创建Die类1.3 掷骰子1.4 分析结果1.5 绘制直方图1.6 同时掷两个骰子1.7 同时掷两个面数不同的骰子 1.使用Plotly模拟掷骰子 本节将使用Python包Plotly来生成交互式图表。需要创建在浏览器中显示…