Ch10-2 : Setting

[Setting]
這個小節,我們會根據上一個小節的資料表(Tables)設計,製做出對的網頁。為了畫面美觀,以及個人前端設計能力不足,無法設計出美觀畫面,我選擇別人免費上傳的HTML5的免費樣版與Form表單設計,再微調成我想要的畫面。若想要參閱其它相關網頁資料,可以參考Reference的網址查看。

這章節,需要大量引用到相關許多cssJavaScript,請參閱我GIT HUB上,Tag是Ch10的檔案內容,方便您參考與使用。

這段落會先介紹整個網站檔案相關擺放的目錄,後面會有幾個小段落,介紹我怎麼在組合這些東西,來完成註冊、認證、重發認證信的功能。


Resource
我們的免費樣版使用的是html5up.net上所提供的TXT樣式,下載回來的資源,裡面有cssjs檔案,首先我們要把相關的資源,放到相關的目錄下,協助我們開發網頁。
參考 : https://github.com/loveu8/playMyBtaisMariaDB/tree/Ch10/public

public                    
 └ stylesheets 
    └ font-awesome.min.css      <-主要引用Google Fonts線上字元設定,若想要修改設定,可以參考Google Fonts
       loginSignup.css           <-註冊與表單的樣式檔
       main.css                  <-全網共用的樣式檔,若是頁面引用進來後,畫面主要風格都會變成main.css所影響
       normalize.css             <-保持各種瀏覽器的一致性的樣式檔
    └images
      └highlight.png            <-頁面上需要背景圖
        overlay.png
 └ javascripts
    └jquery-3.1.0.min.js        <-JQuery函式庫
      jquery.dropotron.min.js    <-下拉浮動選單
      loginSignup.js             <-註冊與登入JS檔案
      main.js                    <-main.caa載入後,main.js協助畫面上的調整
      skel-viewport.min.js       <- Skel 模組
      skel.min.js
       util.js                    <-免費樣式有引用該JS函式,用途是前端呼叫後端程式(DWR),但之後不會使用到它
 └ fonts   
    └ fontawesome-webfont.ttf   <-字型檔
       fontawesome-webfont.woff
       fontawesome-webfont.woff2


Html
我會把檔案全部放在app/views/web/這個目錄下。至於網頁內容,會在後面三個小節才會詳細補充與說明。
參考 : https://github.com/loveu8/playMyBtaisMariaDB/tree/Ch10/app/views/web

app
└ views
  └ web
     headerLibs.scala.html  <- Header區域,要引用的css與js檔案,我集中擺放成為一個頁面
     headerNav.scala.html   <- 上方Header的選單區域,因為會在許多頁面使用到,特別獨立出來
     index.scala.html       <- 我們網站的主要頁面
    └ loginSignup               
       checkMemberAuth.scala.html    <-檢查會員認證信的頁面
       login.scala.html              <-登入頁面(該章節尚未使用到)
       loginSignupLibs.scala.html    <-登入與注冊頁面,引用的資源
       resendAuthEmail.scala.html    <-重發認證信
       signup.scala.html             <-註冊頁面
       signupOk.scala.html           <-註冊成功頁面


app/controller,在這個目錄下新增WebController.java,來寫出我們網站需要的相關服務。
參考 : https://github.com/loveu8/playMyBtaisMariaDB/blob/Ch10/app/controllers/WebController.java

package controllers;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;

import play.Logger;
import play.data.FormFactory;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Result;
import pojo.web.Member;
import pojo.web.MemberToken;
import pojo.web.MemberLoginStatus;
import pojo.web.MemberStatus;
import pojo.web.MemberTokenType;
import pojo.web.email.Email;
import pojo.web.signup.request.SignupRequest;
import pojo.web.signup.verific.VerificFormMessage;
import services.WebService;
import utils.signup.Utils_Signup;
import views.html.web.index;
import views.html.web.loginSignup.*;
import utils.mail.Utils_Email;
import utils.signup.*;

public class WebController extends Controller {

  // 首頁
  public Result index() {
    return ok(index.render());
  }

  // 登入
  public Result login() {
    return ok(login.render());
  }

  // 註冊頁面
  public Result signup() {
    // 清除暫存錯誤訊息
    // flash().clear();
    return ok(signup.render());
  }


  @Inject
  // 相依性注入Play的formFactory,可參考reference介紹
  FormFactory formFactory;

  @Inject
  private WebService webService;

  /**
   * <pre>
   * 進行註冊
   * 
   * Step 1 : 取得表單註冊資料,若錯誤,回到註冊頁面,警告錯誤訊息。
   * Step 2 : 進行表單驗證,是否正確。若錯誤,回到註冊頁面顯示錯誤訊息。
   * Step 3 : 檢核通過,新增會員資料,且尚未認證。
   * Step 4 : 註冊新增成功,新增認證連結資料。
   * Step 5 : 新增會員記錄檔。
   * Step 6 : 進行寄送認證信動作。
   * Step 7 : 以上都順利完成,導入成功註冊頁面。
   * 
   * </pre>
   */
  public Result goToSignup() {

    // 清除暫存錯誤訊息
    flash().clear();

    // Step 1
    SignupRequest request = this.getSignupRequest();
    if (request == null) {
      flash().put("errorForm","註冊資料錯誤,請重新嘗試!!");
      return ok(signup.render());
    }

    // Step 2
    Map<String, VerificFormMessage> verificInfo = this.checkSingupRequest(request);
    for (String key : verificInfo.keySet()) {
      // 發現驗證沒過,放入錯誤訊息
      if (!"200".equals(verificInfo.get(key).getStatus())) {
        flash().put(key, verificInfo.get(key).getStatusDesc());
      }
    }
    if(!flash().isEmpty()){
      return ok(signup.render());
    }

    try {
      // Step 3
      int isSignupOk = webService.signupNewMember(request);
      if(isSignupOk == 0){
        flash().put("signupError", "註冊會員失敗,請重新註冊,謝謝。");
        return ok(signup.render());
      }

      // Step 4
      Utils_Signup utils_Signup = new Utils_Signup();
      Member newMember = webService.findMemberByEmail(request.getEmail());
      String signupAuthString = utils_Signup.genSignupAuthString(newMember.getEmail());

      Map<String , String> memberToken = new HashMap<String , String>();
      memberToken.put("memberNo", newMember.getMemberNo());
      memberToken.put("tokenString", signupAuthString);
      memberToken.put("type", MemberTokenType.Signup.toString());
      int isSingAuthStringOk = webService.genSignupAuthData(memberToken);

      // Step 5
      Map<String , String> memberLoginData 
          = utils_Signup.genMemberLoginData(newMember.getMemberNo() ,
                                            "PC" , 
                                            request().remoteAddress() , 
                                            MemberLoginStatus.S1.getStatus());
      int isMemberLoginLogOk = webService.genMemberLoginLog(memberLoginData);

      // Step 6
      Utils_Email utils_Email = new Utils_Email();
      Email email = utils_Email.genSinupAuthEmail(newMember, signupAuthString);
      boolean isSeadMailOk = utils_Email.sendMail(email);

      // Step 7
      if(isSingAuthStringOk > 0 && isMemberLoginLogOk > 0 && isSeadMailOk ){
        return ok(signupOk.render());
      } else {
        flash().put("signupError", "Opss...寄送認證信件發生錯誤,請使用重發認證信功能,完成認證動作,謝謝。");
        return ok(signup.render());
      }
    } catch (Exception e) {
      e.printStackTrace();
      flash().put("signupError", "註冊會員失敗,請重新註冊,謝謝。");
      return ok(signup.render());
    }
  }


  // Step 1 : 取得註冊資訊請求
  private SignupRequest getSignupRequest() {
    SignupRequest request = null;
    try {
      request = formFactory.form(SignupRequest.class).bindFromRequest().get();
      Logger.info("before , new member request data = " + Json.toJson(request));
    } catch (Exception e) {
      Logger.error("表單內容非註冊資訊,轉換類別錯誤,回傳空物件");
    }
    return request;
  }


  // Step 2 : 檢查註冊資訊
  private Map<String, VerificFormMessage> checkSingupRequest(SignupRequest request) {

    boolean isRegEmail = true;
    boolean isUsedUsername = true;
    try{
      isRegEmail = webService.checkMemberByEmail(request.getEmail());
      isUsedUsername = webService.checkMemberByUsername(request.getUsername());
    } catch(Exception e){
      e.printStackTrace();
    }
    Map<String, VerificFormMessage> verificInfo 
        = new Utils_Signup().checkSingupRequest(request , isRegEmail , isUsedUsername);
    Logger.info("verificInfo = " + Json.toJson(verificInfo));
    return verificInfo;
  }


  // test signupOk
  public Result signupOk(){
    return ok(signupOk.render());
  }


  /**
   * <pre>
   * 檢查註冊認證信連結
   * 
   * Step1   : 檢查認證是否存在。
   * Step2   : 檢查會員是否已經認證過。
   * Step3   : 檢查連結是否使用過。
   * Step4   : 檢查是否有逾期。
   * Step5   : 檢查通過,開始更新與新增相關表單。
   * Step5.1 : 更新會員認證表單
   * Step5.2 : 更新會員表單
   * Step5.3 : 新增會員紀錄表單
   * 
   * </pre>
   */
  public Result authMember(String auth){

    // 清除暫存錯誤訊息
    flash().clear();

    // Step 1
    MemberToken memberToken = null ;
    try{
     memberToken = webService.getMemberTokenData(auth , MemberTokenType.Signup.toString());
    } catch(Exception e){
      e.printStackTrace();
    }

    if(memberToken == null){
      flash().put("authError", "認證連結有誤,請重新點選信中認證連結,或使用重發認證信,謝謝。");
      play.Logger.warn("memberToken  = " + Json.toJson(memberToken));
      return ok(checkMemberAuth.render());
    }

    // Step 2
    Member member = null;
    try{
      // 認證連結有資料,使用會員編號,查詢會員資料。
     member = webService.findMemberByMemberNo(memberToken.getMemberNo());
    } catch(Exception e){
      e.printStackTrace();
      flash().put("authError", "系統忙碌中,請稍後再次嘗試!");
      return ok(checkMemberAuth.render());
    }

    if(!MemberStatus.S1.getStatus().equals(member.getStatus())){
      flash().put("authError", "您的帳號,已經認證成功,不需再認證,謝謝。");
      play.Logger.warn("member      = " + Json.toJson(member));
      return ok(checkMemberAuth.render());
    }

    // Step 3
    boolean isUse       = memberToken.getIsUse(); // 認證字串是否使用過
    if (isUse){
      flash().put("authError", "該連結已成功認證,不需要再次認證,謝謝。");
      return ok(checkMemberAuth.render());
    } 

    // Step 4
    long    dbTime      = Long.parseLong(memberToken.getDbTime());       // 資料庫時間
    long    expiryDate  = Long.parseLong(memberToken.getExpiryDate());   // 逾期時間
    if(dbTime > expiryDate){
      flash().put("authError", "認證時間已經逾期,請重新使用重發認證信功能謝謝。");
      play.Logger.warn("dbTime      = " + dbTime);
      play.Logger.warn("expiryDate  = " + expiryDate);
      return ok(checkMemberAuth.render());
    } 

    // Step 5
    try{
      int isUpdateMemberTokenOk = webService.updateMemberToken(member.getMemberNo());
      int isUpdateMemberMainOk = webService.updateMemberToAuthOk(member.getMemberNo());
      int isGenMemberChangeLogOk = webService.genMemberChangeLog(member);
      play.Logger.info("isUpdateMemberAuthOk  = " + isUpdateMemberTokenOk);
      play.Logger.info("isUpdateMemberMainOk  = " + isUpdateMemberMainOk);
      play.Logger.info("isGenMemberChangeLogOk = " + isGenMemberChangeLogOk);
    } catch(Exception e){
      e.printStackTrace();
    }
    return ok(checkMemberAuth.render());
  }


  /**
   *  重發認證信頁面
   */
  public Result resendAuthEmail(){
    return ok(resendAuthEmail.render());
  }


  /**
   * <pre>
   *  重發認證信檢查與寄送
   *  
   *  Step 1 : 檢查輸入的資料是否符合需要的格式
   *  Step 2 : 檢查輸入的信箱與使用名稱,是否有該會員資料
   *  Step 3 : 會員資料,檢查是否已認證
   *  Step 4 : 尚未認證,再次補寄送認證信
   * 
   * </pre>
   */
  public Result goToResendAuthEmail(){

    // 清除暫存錯誤訊息
    flash().clear();

    SignupRequest request = this.getSignupRequest();
    if(request==null){
      flash().put("error", "輸入資料錯誤,請重新嘗試!!");
      return ok(resendAuthEmail.render());
    }

    // Step 2
    Member member = null;
    String email = request.getEmail();
    String username = request.getUsername();
    try{
      member = webService.findMemberByEmailAndUserName(email, username);
    } catch(Exception e){
      e.printStackTrace();
      flash().put("error", "系統忙碌中,請稍候再嘗試,謝謝。");
      return ok(resendAuthEmail.render());
    }

    // Step 2 
    if(member == null){
      flash().put("error", "查無註冊資料,請確認資料是否填寫正確,謝謝。");
      return ok(resendAuthEmail.render());
    }

    // Step 3
    if(!MemberStatus.S1.getStatus().equals(member.getStatus())){
      flash().put("error", "您的帳號,已經認證成功,不需再重新認證,謝謝。");
      play.Logger.warn("member      = " + Json.toJson(member));
      return ok(resendAuthEmail.render());
    }

    // Step 4
    try{
      String signupAuthString = new Utils_Signup().genSignupAuthString(member.getEmail());
      Map<String , String> memberToken = new HashMap<String , String>();
      memberToken.put("memberNo", member.getMemberNo());
      memberToken.put("tokenString", signupAuthString);
      memberToken.put("type", MemberTokenType.Signup.toString());
      int isSignupAuthStringOk = webService.genSignupAuthData(memberToken);

      Utils_Email utils_Email = new Utils_Email();
      Email authMail = utils_Email.genSinupAuthEmail(member, signupAuthString);
      boolean isSeadMailOk = utils_Email.sendMail(authMail);

      play.Logger.info("isSignupAuthStringOk = " + isSignupAuthStringOk +" , isSeadMailOk = " + isSeadMailOk);
    } catch(Exception e){
      e.printStackTrace();
    }
    flash().put("ok", "已重發認證信,請至註冊信箱收取認證信,謝謝。");
    return ok(resendAuthEmail.render());
  }



}

conf
寫好Webcontroller後,我們就需要在routes寫好對應的服務。
參考 : https://github.com/loveu8/playMyBtaisMariaDB/blob/Ch10/conf/routes

...
#------------------------------------
# chapter 10 - start

# http://127.0.0.1:9000/web/index (首頁)
GET        /web/index                    controllers.WebController.index()

# http://127.0.0.1:9000/web/login (登入)
GET        /web/login                  controllers.WebController.login()

# http://127.0.0.1:9000/web/signup (註冊申請)
GET        /web/signup                  controllers.WebController.signup()

# http://127.0.0.1:9000/web/signupOk (註冊成功)
GET        /web/signupOk              controllers.WebController.signupOk()

# http://127.0.0.1:9000/web/signup (使用者註冊的檢查與申請)
POST    /web/signup                  controllers.WebController.goToSignup()

# http://127.0.0.1:9000/web/authMember (認證信檢查)
GET        /web/authMember              controllers.WebController.authMember(auth : String)

# http://127.0.0.1:9000/web/resendAuthEmail (重發認證信頁面)
GET        /web/resendAuthEmail    controllers.WebController.resendAuthEmail()

# http://127.0.0.1:9000/web/resendAuthEmail (重發認證信檢查與寄送)
POST    /web/resendAuthEmail    controllers.WebController.goToResendAuthEmail()

# chapter 10 - end
#------------------------------------



[參考畫面]
電腦版畫面

手機版畫面

[Final]
以上是目前網站的基礎樣貌,接著三個小章節,註冊、認證、與重發認證信,才會詳細說明程式的怎麼運作的。讓我們繼續往前邁進吧!!


[Reference]
makes spiffy HTML5 site templates
https://html5up.net/

40+ Beautiful CSS Sign up & Registration Form
https://www.freshdesignweb.com/css-registration-form-templates/

來,讓我們談一談 Normalize.css
http://jerryzou.com/posts/aboutNormalizeCss/

skel
https://github.com/ajlkn/skel/blob/master/docs/skel-viewport.md

前端呼叫後端程式(DWR)
http://darwinfans.blogspot.tw/2009/04/dwr.html

results matching ""

    No results matching ""