7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【第六回】コロナ禍だから何かできることをー 自宅療養者連絡ツール ー

Last updated at Posted at 2021-10-07

前回までのあらすじ

【第五回】コロナ禍だから何かできることを

実装イメージ図

LINEを利用して保健所の担当者の負担を軽減するとともに、自宅療養者はいつでもつながっている安心感を持たせるためのツールイメージです。
メイン.00_00_51_12.Still002.jpg

ユーザー登録の仕組みを作ろう

システム構成-ユーザー登録.jpg

今回はLIFFで表示する画面の開発部分です

初期表示の処理

1.LINE IDを渡して、データベースに存在するかチェックをする。
2.存在した場合は、「すでに登録されています」と表示。
3.存在しない場合は、「連絡を受けたユーザーIDを入力してください。」として、登録フォームを表示する。

ユーザー登録の処理

1.入力項目のチェックを行う。
2.エラーがなければ、LINE IDと入力されたユーザーIDをデータベースへ登録する。
3.「登録しました」と返す。
4.LIFFの画面を閉じる。

システム構成ーユーザー登録フロー.jpg

登録画面 登録済画面
ユーザー登録.png 登録済画面.png

参考資料

LIFFアプリを開発する
LIFFアプリを開く

以下、ソースコードはこちら

index.php
<?php
    header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
    header( 'Last-Modified: '.gmdate( 'D, d M Y H:i:s' ).' GMT' );
?>
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="Pragma" content="no-cache">
        <meta http-equiv="Cache-Control" content="no-cache">
        <title>ユーザー登録</title>
        <style>
        *{
            margin: 0;
            padding: 0;
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            font-size:120%;
        }
        :focus {
            outline: none;
        }
        a{
            text-decoration: none;            
        }
        #container{
            width:80%;
            margin:0 auto;
        }
        #title{
            position:fixed;
            height:10%;
            left:0;
            right:0;
            top:0;
            text-align:center;
        }
        #user_id{
            position:fixed;
            height:10%;
            width:80%;
            left:10%;
            right:10%;
            top:20%;
        }
        #message{
            position:fixed;
            bottom:20%;
            left:10%;
            right:10%;
            width:80%;
            top:40%;
            height:30%;
            color:#f00;
        }
        #submit{
            position: fixed;
            bottom: 10%;
            height:10%;
            width:80%;
            left:10%;
            right:10%;
        }
        #loading{
            position: fixed;
            height:100%;
            width:100%;
            top:0;
            bottom: 0%;
            left:0%;
            right:0%;
            z-index:999;
            background-color:#fff;
            text-align:center;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        </style>
        <!-- jQuery読み込み -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> 
        <script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2.1/sdk.js"></script>
        <script>
        $(function() {
            // LIFFの初期化を行う
            $('#log').append('START<br>');
            liff.init({
                liffId: "自分のLIFF ID(URLから『https://liff.line.me/』を除いた文字列)を入力する"
            }).then(() => { // 初期化完了. 以降はLIFF SDKの各種メソッドを利用できる
                $('#log').append('GET<br>');
                // 利用者のLINEアカウントのプロフィール名を取得
                liff.getProfile().then(function(profile) {
                    // ユーザーID
                    const line_id = profile.userId;
                    // プロフィール名
                    const name = profile.displayName;
                    // HTMLに挿入
                    $("#line_id").val(line_id);
                    $('#log').append('liff.getProfile()=' + JSON.stringify(profile) + '<br>');
                    get_profile(line_id);
                    $('#log').append('END<br>');
                }).catch(function(error) {
                    $('#log').append('ERROR<br>');
                });
            })
            function get_profile(line_id){
                $('#log').append('get_profile START<br>');
                try {
                    $.ajax({
                        type            : 'POST'
                        ,url            : 'ajax_line.php'
                        ,dataType       : 'json'
                        ,data           : {
                             mode           : 'get'
                            ,line_id        : line_id
                         }
                        ,cache          : false
                    }).done(function(data, textStatus, jqXHR){
                        //エラーメッセージが存在しない場合は再描画
                        if(data['error']==""){
                            if(data['status']=="NA"){
                                $("#loading").hide();
                            }else{
                                $("#load_error").text("すでに登録されています");
                                setTimeout(function(){
                                    liff.closeWindow();
                                },2000);
                            }
                        }else{
                            $("#load_error").text(data['error']);
                        }
                    }).fail(function(XMLHttpRequest, textStatus, errorThrown){
                        $('#log').append('ERROR<br>');
                        $("#load_error").text("データを取得できません");
                    });
                }catch(e){
                    $('#log').append('ERROR<br>');
                    $("#load_error").text(e.message);
                }
                $('#log').append('get_profile END<br>');
            }
            function set_profile(){
                var user_id = $("#user_id").val();
                var line_id = $("#line_id").val();
                $('#log').append('set_profile START<br>');
                try {
                    $.ajax({
                        type            : 'POST'
                        ,url            : 'ajax_line.php'
                        ,dataType       : 'json'
                        ,data           : {
                             mode           : 'set'
                            ,user_id        : user_id
                            ,line_id        : line_id
                         }
                        ,cache          : false
                    }).done(function(data, textStatus, jqXHR){
                        //エラーメッセージが存在しない場合は再描画
                        if(data['error']==""){
                            $("#message").text("登録しました");
                            setTimeout(function(){
                                liff.closeWindow();
                            },2000);
                        }else{
                            $("#message").text(data['error']);
                        }
                    }).fail(function(XMLHttpRequest, textStatus, errorThrown){
                        $("#message").text("データを取得できません");
                    });
                }catch(e){
                    $("#message").text(e.message);
                }
                $('#log').append('set_profile END<br>');
            }
            //登録ボタン押下処理
            $("body").on({
                "click" : function(){
                    set_profile();
                }
            }, "#submit")
        });
        </script>
    </head>
    <body>
        <div id="container">
            <h1 id="title">連絡を受けたユーザーIDを入力してください。</h1>
            <input type="text" id="user_id">
            <input type="hidden" id="line_id">
            <input type="button" id="submit" value="登録">
        </div>
        <div id="message"></div>
        <div id="log" style="display:none;width:96%;height:100px;"></div>
        <div id="loading"><p id="load_error">now loading...</p></div>
    </body>
</html>
<!-- liff.closeWindow() -->
ajax_line.php
<?php

require_once("./config.php");

//JSからのデータを受け取る
$mode = filter_input(INPUT_POST, 'mode');           // $_POST['mode']とも書ける
$line_id = filter_input(INPUT_POST, 'line_id');     // $_POST['line_id']とも書ける
$user_id = filter_input(INPUT_POST, 'user_id');     // $_POST['user_id']とも書ける
$error_message = "";
//DB接続
if($error_message == ""){
    try{
        $dbh = new PDO(DATABASE_URL, DATABASE_USER, DATABASE_PASS);
        // 静的プレースホルダを指定
        $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        // エラー発生時に例外を投げる
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }catch(PDOException $ex){
        $error_message = "接続エラー";
    }
}
//ユーザー情報取得
if($error_message == ""){
    try{
        $SQL =
        <<<EOM
            SELECT
                USER_ID,
                USER_NAME
            FROM
                LINE_USER
            WHERE
                LINE_ID     = ?
        EOM;
        $stmt = $dbh->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
        $stmt->bindParam(1, $line_id, PDO::PARAM_STR);
        $stmt->execute();
    }catch(PDOException $ex){
        $error_message = "ユーザー情報取得エラー";
    }
}
//データ取得
if($error_message == ""){
    if($stmt->rowCount() > 0){
        $row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT);
        $user_id = $row[0];
        $user_name = $row[1];
    }
}
// 更新処理の時はユーザーIDがあるかチェックする
if($error_message == "" && $mode == "set"){
    if ($user_id==""){
        $error_message = "ユーザーIDが入力されていません";
    }else{
        try{
            $SQL =
            <<<EOM
                SELECT
                    USER_ID,
                    USER_NAME
                FROM
                    LINE_USER
                WHERE
                    USER_ID     = ?
            EOM;
            $stmt = $dbh->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
            $stmt->bindParam(1, $user_id, PDO::PARAM_STR);
            $stmt->execute();
        }catch(PDOException $ex){
            $error_message = "ユーザー情報取得エラー";
        }
        //データ取得
        if($error_message == ""){
            if($stmt->rowCount()==0){
                $error_message = "ユーザーIDが登録されていません";
            }
        }
    }
}

//アクション
if($error_message == ""){
    if($mode == "get"){
        if ($user_id==""){
            $status = "NA";
        }
    }elseif($mode == "set"){
        //トランザクション処理を開始
        $dbh->beginTransaction();
        try {
            $SQL =
            <<<EOM
                UPDATE LINE_USER
                SET
                     LAST_ACCESS = NOW()
                    ,LINE_ID     = :line_id
                WHERE
                    USER_ID     = :user_id
            EOM;
            $stmt = $dbh->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
            $stmt->bindParam(':user_id', $user_id, PDO::PARAM_STR);
            $stmt->bindParam(':line_id', $line_id, PDO::PARAM_STR);
            $stmt->execute();

            //コミット
            $dbh->commit();
        }catch(Exception $ex){
            //ロールバック
            $dbh->rollback();
            $error_message = "登録に失敗しました";
        }
    }else{
        $error_message = "予期しないエラーが発生しました";
    }
}
$list = array(
    "error" => $error_message,
    "status" => $status
);

//JSONデータを出力
header("Content-Type: application/json; charset=UTF-8"); //ヘッダー情報の明記。必須。
echo json_encode($list);
exit; //処理の終了
?>
config.php
<?php

define("DATABASE_URL", 'mysql:host=アドレス;dbname=データベース名;charset=utf8');
define("DATABASE_USER", '接続ユーザー名');
define("DATABASE_PASS", '接続パスワード');

?>

コロナ禍だから何かできることをー 自宅療養者連絡ツール ー

【第一回】実装イメージ図と動画
【第二回】LINEからデータを取得して返すまでの流れ
【第三回】LINEからデータベースまでの流れ
【第四回】データベースへの更新までの流れ
【第五回】ユーザー登録の仕組み-LINEbotの設定部分
->>【第六回】ユーザー登録の仕組みLIFFで表示する画面の開発
【第七回】データベースの構造
【第八回】WEB画面上でできる機能
【第九回】まとめ

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?