「技術」カテゴリーアーカイブ

【SocialDog】みなさん、ツイッターの管理ってどうしていますか?

自分のTwitterアカウントもフォロワー数2300とありがたい数字になっているのですが、

いま、問題が発生しておりまして、

もっとフォロワーを増やしたいのですが、これ以上フォローできない、という事態に陥ってまして、

というのも、ツイッターの制限で、フォロワー数が一定以上いかないと、フォロー数が5000で制限されてしまうのです。

これを解決するためには、昔フォローしたけど見る価値のないアカウントのフォロー解除を行わなければなりません。

ここでいう、見る価値のないアカウントというのは、しばらくツイートしていない、いわゆる休眠アカウントと呼ばれるアカウントです。

でも、それを区別するのは、いつものツイッタークライアントでは非常に難しい。

というわけで、ツイッター管理ツールというのが必要になるわけです。

オイラが検索して見つけたのは、SocialDogというツイッター管理ツール。

本来、企業のツイッターアカウントを管理するためのツールなのですが、一般ユーザーでも機能制限付きで無料で使用できます。

便利なのがフォロー管理という機能で、この画面で、相互フォローしているアカウント、フォローしているけどフォローバックされていないアカウント(片思いアカウント)、フォローしていないフォロワー(ファンアカウント)がリスト化して表示されているのです。

便利なのが、休眠アカウントをリスト表示してくれる機能。

もちろんこの画面からフォロー解除することもできます。

こういったツールってホント便利ですよね。

Twitterアカウントがあれば簡単にアカウント登録できるのも嬉しいですよね。

こういう情報、もっとたくさんの人に伝われ。

バナークリックで応援よろしくお願いします。

シャオミ、日本上陸

こちらの記事でも書きましたが、

大方、予想通りでした。

Mi Note 10とMi Note 10 Proを日本市場に投入です。

購入はAmazonで購入できます。

通常とProの違いは主にメモリの容量とストレージの容量ですね。

ミドルレンジでこの価格でこの容量はかなりお得感があります。

ちなみに残念ながらFelica(おサイフケータイ)には対応していないようです。

バナークリックで応援よろしくお願いします。

【Laravel】【ホテル予約管理】部屋を増設する

次の課題は「部屋を増設し、部屋別に管理を行う」というものでした。

今までは部屋は一つの前提で作ってきたので、これを改造する必要があります。

たぶん、テーブルはこんな感じで大丈夫だと思う。

どうせ集計時に全部結合されるんだから。

データベースの作成。マイグレーションを追加します。

class CreateRoomTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('rooms', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('price');
            $table->timestamps();
            $table->engine = 'InnoDB';
            $table->charset = 'utf8mb4';
            $table->collation = 'utf8mb4_unicode_ci';
        });
        Schema::create('reserve_management_room', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('reserve_management_id')
                  ->foreign('reserve_management_id')
                  ->references('id')->on('reserve_managements')
                  ->onDelete('cascade');
            $table->integer('room_id')
                  ->foreign('room_id')
                  ->references('id')->on('rooms')
                  ->onDelete('cascade');
            $table->timestamps();
            $table->engine = 'InnoDB';
            $table->charset = 'utf8mb4';
            $table->collation = 'utf8mb4_unicode_ci';
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('reserve_management_room');
        Schema::dropIfExists('rooms');
    }
}

このテーブルに対するCURD機能を作成します。

ここらへんは予約一覧がすでに出来上がっているので、これをベースにすれば簡単に出来上がります。

モデル

class Room extends Model
{
    protected $table = 'rooms';

    public function reserveManagement()
    {
        return $this->belongsToMany('App\Model\ReserveManagement');
    }
}

リポジトリ

class RoomRepository
{
    private $paramNames = ['name', 'price'];

    /**
     * 部屋一覧を取得する
     * 
     * @return Room[]
     */
    public function getList()
    {
        return Room::get();
    }

    /**
     * 部屋を登録する
     * 
     * @return void
     */
    public function add($param)
    {
        $model = new Room;
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
    }

    /**
     * 予約を更新する
     * 
     * @return void
     */
    public function updateById($id, $param)
    {
        $model = $this->getItemById($id);
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
    }

    /**
     * 予約を削除する
     * 
     * @return void
     */
    public function deleteById($id)
    {
        $model = $this->getItemById($id);
        $model->delete();
    }

    /**
     * IDから部屋情報を1件取得する
     * 
     * @return Room
     */
    public function getItemById($id)
    {
        return Room::where(['id' => $id])->first();
    }

    public function getParam()
    {
        return $this->paramNames;
    }

}

リクエスト

class RoomRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|string',
            'price' => 'required|numeric',
        ];
    }
}

コントローラー

class RoomController extends Controller
{
    protected $room;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->room = new RoomRepository();
    }

    /**
     * 部屋一覧の表示
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('room.index', ['roomLists' => $this->room->getList()]);
    }

    /**
     * 入力フォーム
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('room.create');
    }

    /**
     * 登録処理
     */
    public function store(RoomRequest $request)
    {
        $param = $this->room->getParam();
        $this->room->add([
            $param[0] => $request->name,
            $param[1] => $request->price,
        ]);
        return redirect('room');
    }

    /**
     * 編集処理
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        return view('room.edit', ['item' => $this->room->getItemById($id)]);
    }

    /**
     * 更新処理
     */
    public function update(RoomRequest $request)
    {
        $param = $this->room->getParam();
        $this->room->updateById($request->id,
        [
            $param[0] => $request->name,
            $param[1] => $request->price,
        ]);
        return redirect('room');
    }

    /**
     * 削除確認
     *
     * @return \Illuminate\Http\Response
     */
    public function conform($id)
    {
        return view('room.conform', ['item' => $this->room->getItemById($id)]);
    }

    /**
     * 削除処理
     */
    public function delete(Request $request)
    {
        $this->room->deleteById($request->id);
        return redirect('room');
    }

}

ルーティング

Route::get('/room', 'RoomController@index');
Route::get('/room/create', 'RoomController@create');
Route::post('/room', 'RoomController@store');
Route::get('/room/{id}/edit', 'RoomController@edit');
Route::post('/room/update', 'RoomController@update');
Route::get('/room/{id}/conform', 'RoomController@conform');
Route::post('/room/delete', 'RoomController@delete');

とりあえずこれでOKかと。

次回は予約登録時に部屋を指定する仕組みを作成します。

バナークリックで応援よろしくお願いします。

【自作PC】グラボが届きました。

ついに届きました。

待ちに待ったグラフィックボード、SAPPHIRE PULSE RADEON RX 570 8G GDDR5!

特に必須というわけではないのですが、

なぜなら、今使用しているRyzen 5 3400Gはグラフィックスチップを搭載しています。

インテル系のCPUを使用している場合はグラボが無くても、内蔵のグラフィックスチップで画面表示できますが、AMDのCPUは基本グラフィックスチップを搭載していないので、グラボは必須になります。

グラボを購入した目的は、今後CPUをパワーアップをするに当たり、グラフィックスチップが搭載されていないCPUかもしれないというのもあって、グラボの購入を決定しました。

まぁ、今後PCをさらにパワーアップさせるための足がかりです。

また、このパーツを選んだ理由は、

今使用しているグラフィックスのメモリは2GBなのに対して、今回選択した物は8GB。

そのスペックに対して14000円台とグラボにしてはお手軽価格で、価格.comでも評価は高いです。

それでは開封。

ファン付きのグラボって本格っぽいよね。

HDMTが二つと、DPが二つ使えます。

ここにグラボ用の電源を繋げます。

ローエンドのグラボではマザーからの電力で十分ですが、ミドルエンド以上になると、別途電源ユニットから電源を貰わないと動かすことができません。

それだけ電気を使うのですね。

当然、消費電力をまかなえるように電源ユニットを用意しなければなりません。

取り付けました。

ネジが合っているかどうかわかりません。

しかし、電源を入れたときに、グラボのファンがグラボの下のケーブルに干渉して、ガガガガと音がしていたので、

干渉しないように結束バンドでまとめました。

今のところ、問題無いように動いています。

グラボを増設したらどれだけスペックアップしたか見てみたいでしょ。

ということで、ベンチマークソフトを動かしました。

使用するソフトと条件は、前回こちらで実施したものと同じです。

やはり全体的にスコアが上がっています。

特にFF14が「やや快適」から「非常に快適」になり、

FF15が「動作困難」から「やや快適」になりました。

やったぁ。

これで、いつでも第3世代Ryzenを迎えられる準備ができました。

バナークリックで応援よろしくお願いします。

【Laravel】ホテル予約管理システム完成

もう少しで完成だから、もうちょっとやって終わろうと思ったら、ガッツリ書き換えることになるというプログラマーあるある。

やっぱり、チェックしたかどうかも管理するべきだろう(もはや仕様変更レベル)と思いました。

データベースに、「チェックしたかどうか」を格納するカラムを追加します。

マイグレーションファイルを作成し、マイグレートします。

class AddSubmit extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('reserve_managements', function (Blueprint $table) {
            $table->boolean('lodging');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('reserve_managements', function (Blueprint $table) {
            $table->dropColumn('lodging');
        });
    }
}

ちょっと名前がいろいろとアレだけど、あとから直すの面倒くさいので、そのまま使用する。(ちゃんと前もって設計しなさい、という話。)

予約一覧にチェックしたらポチるボタンを設置。

                    <table class="management">
                        <tr>
                            <th class="name">名前</th>
                            <th class="address">住所</th>
                            <th class="phone">電話番号</th>
                            <th class="num">人数</th>
                            <th class="date">宿泊日</th>
                            <th class="num">宿泊日数</th>
                            <th class="command">編集</th>
                            <th class="command">削除</th>
                            <th class="command">宿泊</th>
                        </tr>
                    @foreach ($registerLists as $list)
                        <tr>
                            <td class="name">{{ $list->name }}</td>
                            <td class="address">{{ $list->address }}</td>
                            <td class="phone">{{ $list->phone }}</td>
                            <td class="num">{{ $list->num }}</td>
                            <td class="date">{{ $list->start_day }}</td>
                            <td class="num">{{ $list->days }}</td>
                            <td class="command">{{ Html::link('/management/'.$list->id.'/edit', '編集') }}</td>
                            <td class="command">{{ Html::link('/management/'.$list->id.'/conform', '削除') }}</td>
                            <td class="command">
                            {!! Form::open(['url' => action('RegisterManagementController@lodging')]) !!}
                            {!! Form::hidden('id', $list->id) !!}
                            {!! Form::submit('宿泊') !!}
                            {!! Form::close() !!}
                            </td>
                        </tr>
                    @endforeach
                    </table>

ポチったらPOSTでid番号を受け取り、追加したカラムをtrueに変更して予約一覧へリダイレクト。

    /**
     * 宿泊処理確認
     *
     * @return \Illuminate\Http\Response
     */
    public function lodging(Request $request)
    {
        $this->registerManagement->lodging($request->id);
        return redirect('management');
    }
    /**
     * 宿泊処理を行う
     */
    public function lodging($id)
    {
        $model = $this->getItemById($id);
        $model->lodging = true;
        $model->save();
    }

スケジュール一覧にもチェックしたかどうかを表示します。

                    <table class="schedule">
                        <tr>
                            <th class="date">日時</th>
                            <th class="name">名前</th>
                            <th class="lodging">宿泊状況</th>
                        </tr>
                    @foreach ($Lists as $list)
                        <tr>
                            <td class="date">{{ $list['day'] }}</td>
                            <td class="name">{{ $list['name'] }}</td>
                            @if ($list['lodging'])
                                <td class="lodging">チェック</td>
                            @else
                                <td class="lodging">未チェック</td>
                            @endif
                        </tr>
                    @endforeach
                    </table>
    /**
     * スケジュール一覧を取得する
     */
    public function getSchedule()
    {
        $lists = array();
        $index = 0;
        $models = ReserveDayList::orderBy('day')
                                    ->get();
        foreach($models as $model)
        {
            $lists[$index] = array(
                                'day' => $model->day,
                                'name' => $model->reserveManagements()->first()->name,
                                'lodging' => $model->reserveManagements()->first()->lodging
                            );
            $index++;
        }
        return $lists;
    }

    /**
     * 月別スケジュール一覧を取得する
     */
    public function getScheduleByMonth($year, $month)
    {
        $lists = array();
        $index = 0;
        $models = ReserveDayList::where('day', '>=', date('Y-m-d', strtotime('first day of '.$year.'-'.$month)))
                                ->where('day', '<=', date('Y-m-d', strtotime('last day of '.$year.'-'.$month)))
                                ->orderBy('day')
                                ->get();
        foreach($models as $model)
        {
            $lists[$index] = array(
                                'day' => $model->day,
                                'name' => $model->reserveManagements()->first()->name,
                                'lodging' => $model->reserveManagements()->first()->lodging
                                );
            $index++;
        }
        return $lists;
    }

集計も、チェック済みのものだけ集計対象にします。

テーブルを結合して、チェック済みの日数を数えます。

    /**
     * 月毎に集計する
     */
    public function countByMonthly()
    {
        return ReserveDayList::select(DB::raw('DATE_FORMAT(day, "%Y-%m") as yearmonth'), DB::raw('count(*) as count'), DB::raw('count(*) * 2000 as total'))
                                ->leftJoin('reserve_day_list_reserve_management', 'reserve_day_lists.id', '=', 'reserve_day_list_reserve_management.reserve_day_list_id')
                                ->leftJoin('reserve_managements', 'reserve_day_list_reserve_management.reserve_management_id', '=', 'reserve_managements.id')
                                ->where('reserve_managements.lodging', true)
                                ->groupby('yearmonth')
                                ->get();
    }

leftJoinが記載が汚いかもしれないけど、これはLaravelであるがゆえの運命。仕方がない。

これで本当に完成。提出してきます。

最終ソースはこちら

https://github.com/takishita2nd/hotel-mng

バナークリックで応援よろしくおねがいします。

【Laravel】月毎に売上の集計を行う

前回までの状況はこちら

最新ソースはこちら

https://github.com/takishita2nd/hotel-mng

月毎に集計を行います。

このときのデータベースの操作が大変で・・・

    /**
     * 月毎に集計する
     */
    public function countByMonthly()
    {
        return ReserveDayList::select(DB::raw('DATE_FORMAT(day, "%Y-%m") as yearmonth'), DB::raw('count(*) as count'), DB::raw('count(*) * 2000 as total'))
                                ->groupby('yearmonth')
                                ->get();
    }

リポジトリはこれでなんとかできました。

select文でdayカラムをYYYY-mmのフォーマットで出力(このカラム名をyearmonthとする)。

yearmonthごとにgroupByでグループ分けし、count(*)で集計を行います。

もっとうまい方法があるかもしれませんが、迷ったらDB::raw()を使ったほうがいいかもしれません。

でも、これができれば完成したも同然。

簡単すぎるので、コードは省略。

あとは最後の微調整で完成ですね。

バナークリックで応援よろしくお願いします。

【Laravel】月ごとにデータをフィルタさせる

前回までの状況はこちら。

最新ソースはこちら。

https://github.com/takishita2nd/hotel-mng

一通りデータの登録はできましたが、このままデータが増えると1画面に大量のデータが表示されることになります。

なので、一覧のデータを月毎にフィルタ表示させたいと思います。

まず、Viewを修正。

年月を指定できるようにします。

                    {!! Form::open(['url' => action('RegisterManagementController@indexToMonthly')]) !!}
                    <table>
                        <tr>
                            <td>{!! Form::selectYear('year', 2019, 2020) !!}年</td>
                            <td>{!! Form::selectMonth('month') !!}</td>
                            <td>{!! Form::submit('表示') !!}</td>
                        </tr>
                    </table>
                    {!! Form::close() !!}

本来は、Vue.jsなどを使ってフロントエンド側でうまくできるのが理想なのですが、今からVueの実装を行うのは面倒くさいので、フィルタ情報を一旦POSTで受け取り、GET+クエリパラメータの形にして、リダイレクトさせるという方法をとります。

ルートの設定。

Route::post('/management/indexToMonthly', 'RegisterManagementController@indexToMonthly');

コントローラ。まずはGETの方。

    /**
     * Show the Register.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        if(is_null($request->input('year')) || is_null($request->input('month')))
        {
            return view('register.index', ['registerLists' => $this->registerManagement->getList()]);
        }
        else
        {
            return view('register.index', ['registerLists' => $this->registerManagement->getListByMonth($request->input('year'), $request->input('month'))]);
        }
    }

GETリクエストでも引数にRequest $requestを書き足せば、クエリパラメータを取得できます。

忘れてはいけないのは、クエリパラメータがNULLだった場合。

is_null()でNULLチェックを行い、デフォルト(パラメータがない場合)の画面表示をさせるようにしましょう。

次は、POST側の処理。

    /**
     * indexの月別表示
     *
     * @return \Illuminate\Http\Response
     */
    public function indexToMonthly(Request $request)
    {
        return redirect('management?year='.$request->year.'&month='.$request->month);
    }

クエリパラメータ付きURLを作成し、リダイレクトを行っています。

これしか方法が思い浮かばなかった。

次はリポジトリ。

    /**
     * 月別予約一覧を取得する
     * 
     * @return ReserveManagement[]
     */
    public function getListByMonth($year, $month)
    {
        return ReserveManagement::where('start_day', '>=', date('Y-m-d', strtotime('first day of '.$year.'-'.$month)))
                                ->where('start_day', '<=', date('Y-m-d', strtotime('last day of '.$year.'-'.$month)))
                                ->get();
    }

whereを2つ付けることでAND条件になります。

クエリビルダー便利。

同じやり方をスケジュール一覧にも行います。

十分とは言えませんが、やりたいことはできました。

たぶん次でラスト。

月毎に売上を集計して表示させます。

バナークリックで応援よろしくおねがいします。

【Laravel】スケジュールの重複をチェックする

前回まで状況はこちら。

最新ソースコードはこちら。

https://github.com/takishita2nd/hotel-mng

今回は予約を入れたスケジュールに重複がないかを確認し、重複していたらエラー表示を行います。

まず、重複チェックを行う処理をリポジトリに作成します。

    /**
     * スケジュールの重複を確認する
     * 
     * @return boolean
     */
    public function checkSchedule($date, $num)
    {
        if(ReserveDayList::where(['day' => $date])->count() != 0)
        {
            return false;
        }
        for($i = 1; $i < $num; $i++)
        {
            if(ReserveDayList::where(['day' => date('Y-m-d', strtotime($date.'+'.$i.' day'))])->count() != 0)
            {
                return false;
            }
        }

        return true;
    }

予約を入れる日にち全てに対して、データがあるかを確認します。

データの有無は、おそらく、count()でレコード数を見るのが一番スマートなやりかたでしょう。

これを、コントローラーから呼びます。

    /**
     * 登録処理
     */
    public function store(ManagementRequest $request)
    {
        if($this->registerManagement->checkSchedule($request->start_day, $request->days) == false)
        {
            return redirect('management/create')
                        ->with(['error' => 'スケジュールが重複します'])
                        ->withInput();
        }
        $param = $this->registerManagement->getParam();
        $this->registerManagement->add([
            $param[0] => $request->name,
            $param[1] => $request->address,
            $param[2] => $request->phone,
            $param[3] => $request->num,
            $param[4] => $request->days,
            $param[5] => $request->start_day
        ]);
        return redirect('management');
    }

重複していたら、元の画面にリダイレクトします。

このとき、セッションにエラーメッセージも一緒に入れます。

withInput()を入れると、入力したデータもそのまま残るようになります。

次はbladeにエラーを表示するエリアを作成します。

                @if (session('error'))
                    <div class="alert alert-danger">
                        {{ session('error') }}
                    </div>
                @endif

うまくできました。

もう少しでこの課題は完成ですね。

バナークリックで応援よろしくお願いします。

【Laravel】バリデーション処理を追加する

前回までの状況はこちら。

最新ソースはこちら。

https://github.com/takishita2nd/hotel-mng

バリデーション処理とは、フォームで入力した値が、正しいかどうかを確認する処理です。

現在は入力された値がそのままデータベースに入るようになってしまっているので、パラメータチェック処理を入れて、エラーを返せるようにします。

今回は実装量が少ない方法で行きます。

以下のコマンドを入力。

$ php artisan make:request ManagementRequest

そうすると、App/Http/Request/ManagementRequest.phpが作成されます。

その内容を修正します。

class ManagementRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|string',
            'address' => 'required|string',
            'phone' => 'required|digits:11',
            'num' => 'required|numeric|digits_between:1,2',
            'days' => 'required|numeric|digits_between:1,4',
            'start_day' => 'required|date',
        ];
    }
}

authorize()の戻り値はtrueに変えます。

falseのままだとすべて認証エラーとなります。

rules()に各パラメータの確認内容を記入します。

こちらのサイトが参考になります。

https://qiita.com/fagai/items/9904409d3703ef6f79a2

あとは、コントローラーを変更します。

use App\Http\Requests\ManagementRequest;

    /**
     * 登録処理
     */
    public function store(ManagementRequest $request)


    /**
     * 更新処理
     */
    public function update(ManagementRequest $request)

確認を行うフォームのリスエスト処理の引数の型をManagementRequestに変更します。

これで、App/Http/Request/ManagementRequest.phpの内容が適用されます。

あとは、bladeにエラーを表示する領域を追加すればOK。

                @if ($errors->any())
                    <div class="alert alert-danger">
                        <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                @endif

クリックで応援よろしくお願いします。

2画面スマホLG G8X Thinqってどうなの?スペックを比較してみた!

LG G8X ThinQはLGからリリース予定の2画面スマホです。

キャリアはソフトバンクのみ。

通常は1画面ですが、アタッチメントでもう1画面増やすことができます。

この画面は製品に付属されています。

この2画面は、それぞれ独立しているため、二つのアプリを同時に扱えるというメリットがあります。

使い方次第では便利なのかもーと思います。

しかも価格も抑えめ。

スペックの比較です。

比較するのはPixel4です。

Pixel4 Pixel4 XLLG G8X ThinQ
ディスプレイ5.7インチ6.3インチ6.4インチ、6.4インチ
解像度FHD+ 19:9QHD+ 19:9FHD+ 2340×1080ドット
プロセッサSnapdragon855Snapdragon855 SDM855
メモリ6GB 6GB 6GB
ストレージ64GB/128GB 64GB/128GB 64GB
サイズ147×68.8×8.2mm160.4×75.1×8.2mm 160×76×8.4mm
2画面では
166×164×15.0mm
重さ162g193g 193g 2画面では 331g

また、おサイフケータイ、指紋認証、ワンセグ、フルセグが付いています。本体のみ防水・防塵仕様になっています。

お値段、合計55440円。

このスペックで5万円台か。どこかでコスト削っているのか?

そうだな・・・2画面あるのだから、テレビみながらツイッターできる、と言うことができるのか。

それはそれで便利かも。

別に今のPixel3に不満は無いけどね。

バナークリックで応援よろしくお願いします。