黄金点游戏bs架构(四)——基本实现

黄金点游戏bs架构——基本实现

1.设计框架Review

​ 首先,由于本次实现与前一次进行较大重整,我们先来看一下最初的设计思路和框架,因为现在的设计回归了最初的设计方案,和最初设计方案契合度较高。

用例分析
  • 用户进入网站主界面,会看到前几轮的黄金点

  • 用户尝试登记自己的点数,被要求登录账号

  • 登录账号页面可以点击链接进行注册

  • 注册界面要求输入用户名、电子邮箱(用于找回密码)密码和确认密码

  • 登录界面要求输入用户名和密码

  • 登录后回到主页,但此登记点数不会弹出登录提示,而是会显示登记成功或者已经登记过了

  • 满人后计算得分、将比赛记入历史,进入下一轮比赛

前端设计 后端设计
1.index.html主页 1.数据库
· 当没有登录时提供登录、注册按钮
· 当登录时提供用户主页、退出登录按钮
· 显示最近比赛信息
· 进行投票
· 用户-密码sha256哈希码
· 场次-黄金点
· 场次-用户-登记数字-时间
2.login.html登录界面 2.Redis
· 当有登录时重定向到用户主页
· 当没有登录时提供用户名框、密码框,将信息加密后发给服务器
· submits:当前场次的 用户-登记数字-时间
· sessions:session-user
3.register.html注册界面 3.服务
· 当有登录时重定向到用户主页
· 当没有登录时提供用户名框、密码框,将信息加密后发给服务器
· register 根据用户名和密码进行注册
· login 根据用户名和密码登录并生成session,销毁过期session
4.home.html用户主页 4.接口(均返回简单文本或json对象)
· 当没有登录时重定向到登录界面
· 当登录时提供用户分值、最近用户历史的展示 提供主页、退出登录按钮
· 进行投票
· login?username=***?password=*** 返回登录结果和临时token
· register?username=***?password=***返回注册结果
· vote?token=***返回时间
· usercredit?token=***返回用户积分
· userhistory?token=***返回用户历史记录
· history?page=*** 从最近开始分页,返回历史记录
2.前端设计图样展示

​ 因此,根据上述设计框架,对前端进行重新设计,得到如下符合要求的界面,且看图样展示。上次开发使用的模板是Metronic 4.5版本,而这次升级了页面造型,采用Metronic 7.10来实现。新的模板带来新的问题,如注册登录的传值都采用FormValidation这个插件进行,所以实现起来比较陌生。

  • index.html主页

    • 下图为未登录时的初始界面,未登录时不展现输入投票数字的选框,但是显示最近比赛的信息,点击登录会跳转至登录注册页面进行登录。

    • 下图是登陆完成后的页面,主页其他都未变,除了参与比赛的界面展现投票选框和当前参与该轮黄金点游戏的玩家人数。

  • login.html登录界面

    • 登录界面与注册界面合并至同一个html文件中编写,点击注册一个可以跳转到注册界面,点击忘记密码可以跳转到密码找回界面。

    • 下图为注册界面,选框对空置进行检测,如果未填完,不允许跳转。

    • 忘记密码界面如下,需要输入注册时的电子邮箱来获取重置密码的验证码。

  • home.html用户主页

    • 用户页面显示用户的信息,历史积分与历史参与游戏的记录。
3.后端代码展示
核心代码

GameLogicService.java

package com.foolriver.goldenpoint.service;

import com.foolriver.goldenpoint.model.RoundRecord;
import com.foolriver.goldenpoint.model.SubmitRecord;
import com.foolriver.goldenpoint.model.UserRecord;
import com.foolriver.goldenpoint.repository.RoundRecordRepositoy;
import com.foolriver.goldenpoint.repository.SessionRecordRepository;
import com.foolriver.goldenpoint.repository.SubmitRecordRepository;
import com.foolriver.goldenpoint.repository.UserRecordRepository;
import lombok.Getter;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.LinkedList;
import java.util.List;

@Service
public class GameLogicService {
    @Resource
    SessionRecordRepository sessionRecordRepository;
    @Resource
    RoundRecordRepositoy roundRecordRepositoy;
    @Resource
    SubmitRecordRepository submitRecordRepository;
    @Resource
    UserRecordRepository userRecordRepository;

    @Getter
    static int personCount=0;
    @Getter
    static String currentRoundId=null;

    private void settleRound(){
        RoundRecord roundRecord=roundRecordRepositoy.findByUuid(currentRoundId);
        List<SubmitRecord> submitRecords=submitRecordRepository.findByRoundUuid(currentRoundId);
        roundRecord.setEndTime(new Timestamp(System.currentTimeMillis()));
        roundRecord.setPersonCount(submitRecords.size());
        double goldenPoint=0;
        for(SubmitRecord submitRecord:submitRecords){
            goldenPoint+=submitRecord.getValue();
        }
        goldenPoint/=roundRecord.getPersonCount();
        roundRecord.setGoldenPoint(goldenPoint);
        roundRecordRepositoy.save(roundRecord);

        List<SubmitRecord> submitWinners=new LinkedList<SubmitRecord>();
        List<SubmitRecord> submitLosers=new LinkedList<SubmitRecord>();
        double errorMax=0,errorMin=Double.MAX_VALUE;
        for(SubmitRecord submitRecord:submitRecords){
            if(errorMax>Math.abs(submitRecord.getValue()-goldenPoint)){
                errorMax=Math.abs(submitRecord.getValue()-goldenPoint);
                submitLosers.clear();
                submitLosers.add(submitRecord);
            }else if(errorMax==Math.abs(submitRecord.getValue()-goldenPoint)){
                submitLosers.add(submitRecord);
            }
            if(errorMin<Math.abs(submitRecord.getValue()-goldenPoint)){
                errorMin=Math.abs(submitRecord.getValue()-goldenPoint);
                submitWinners.clear();
                submitWinners.add(submitRecord);
            }else if(errorMin==Math.abs(submitRecord.getValue()-goldenPoint)){
                submitWinners.add(submitRecord);
            }
        }
        for(SubmitRecord submitWinner:submitWinners){
            UserRecord userRecord=userRecordRepository.findByUuid(submitWinner.getUserUuid());
            userRecord.setCredit(userRecord.getCredit()+1.0/ submitWinners.size());
            userRecordRepository.save(userRecord);
        }
        for(SubmitRecord submitLoser:submitLosers){
            UserRecord userRecord=userRecordRepository.findByUuid(submitLoser.getUserUuid());
            userRecord.setCredit(userRecord.getCredit()-1.0/ submitLosers.size());
            userRecordRepository.save(userRecord);
        }
        roundRecord=new RoundRecord();
        roundRecordRepositoy.save(roundRecord);

    }

    public void ifNotInitializedThenInit(){
        RoundRecord roundRecord=roundRecordRepositoy.findByGoldenPointIsNull();
        if(roundRecord==null){
            roundRecord=new RoundRecord();
        }
        roundRecordRepositoy.save(roundRecord);
        currentRoundId=roundRecord.getUuid();
    }

}

UserManageService.java

package com.foolriver.goldenpoint.service;

import com.foolriver.goldenpoint.model.SessionRecord;
import com.foolriver.goldenpoint.model.UserRecord;
import com.foolriver.goldenpoint.repository.SessionRecordRepository;
import com.foolriver.goldenpoint.repository.UserRecordRepository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class UserManageService {
    @Resource
    UserRecordRepository userRecordRepository;

    @Resource
    SessionRecordRepository sessionRecordRepository;

    public boolean register(String username, String passwordSHA256) {
        UserRecord userRecord = userRecordRepository.findByUsername(username);
        if (userRecord == null) {
            userRecord = new UserRecord();
            userRecord.setUsername(username);
            userRecord.setPasswordSHA256(passwordSHA256);
            userRecordRepository.save(userRecord);
            return true;
        }
        return false;
    }

    public String login(String username, String passwordSHA256) {
        UserRecord userRecord = userRecordRepository.findByUsername(username);
        if (userRecord != null && userRecord.getPasswordSHA256().compareTo(passwordSHA256) == 0) {
            SessionRecord sessionRecord = sessionRecordRepository.findByUserUuid(userRecord.getUuid());

            if (sessionRecord == null) {
                sessionRecord = new SessionRecord();
                sessionRecord.setUserUuid(userRecord.getUuid());
            }
            sessionRecordRepository.save(sessionRecord);
            return sessionRecord.getUuid();
        }
        return null;
    }

    public boolean isUsernameExist(String username) {
        UserRecord userRecord = userRecordRepository.findByUsername(username);
        return userRecord != null ? true : false;
    }

    public void logout(String sessionId){
        SessionRecord sessionRecord=sessionRecordRepository.findByUuid(sessionId);
        if (sessionRecord!=null){
            sessionRecordRepository.delete(sessionRecord);
        }
    }
}

4.缺陷与后续迭代
  1. 当前登录有一些问题,就是上线和下线的信息没有在js中保存,导致用户信息在一段时间中未能延续,所以后续需要添加cookie来保存用户上线和下线的信息
  2. 在输入选框中未对输入进行限制,所以容易产生bug,在后续需要添加正则表达式对其进行限制
  3. 用户密码需要采用sha256哈希码进行转换,前端还未实现该功能
posted @ 2020-11-30 14:38  该用户已住校  阅读(284)  评论(0)    收藏  举报