【ダイエット支援】【食事管理】データ一覧処理を作成する。

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

最新ソースはこちら(gitHub)

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

今回はデータ一覧画面を作成していきます。

この画面は日付ごとにタンパク質、脂質、炭水化物、カロリーを集計して一覧表示にします。

今回の一番の肝、データを処理するリポジトリの処理。

class EatingManagementRepository
{
    private $paramNames = ['date', 'item', 'protein', 'liqid', 'carbo', 'calorie'];

    /**
     * データを取得して日毎にまとめる
     */
    public function getDailyList($user, $page = 1, $days = 10)
    {
        $dates = [];
        for($i = ($page - 1); $i < ($days * $page) ; $i++) {
            $dates[] = date('Y-m-d', strtotime('today - '.$i.' day'));
        }

        $eatings = $user->EatingManagements()
             ->whereIn(DB::raw('date_format(date, "%Y-%m-%d")'), $dates)
             ->get();

        // 日毎に集計
        $dailyDatas = [];
        foreach($eatings as $eating) {
            for($j = 2; $j < count($this->paramNames); $j++) {
                if(!array_key_exists($eating->date, $dailyDatas)) {
                    $dailyDatas[$eating->date] = [];
                }
                if(!array_key_exists($this->paramNames[$j], $dailyDatas[$eating->date])) {
                    $dailyDatas[$eating->date][$this->paramNames[$j]] = 0;
                }
                $dailyDatas[$eating->date][$this->paramNames[$j]] += $eating->{$this->paramNames[$j]};
            }
        }

        // 戻り値に変換
        $retDatas = [];
        $index = 0;
        foreach($dailyDatas as $dailykey => $dailyData) {
            $retDatas[$index][$this->paramNames[0]] = $dailykey;
            for($k = 2; $k < count($this->paramNames); $k++) {
                $retDatas[$index][$this->paramNames[$k]] = $dailyDatas[$dailykey][$this->paramNames[$k]];
            }
        }

        return $retDatas;
    }

まずはwhere inで日付指定でデータを取得するために、今日から(デフォルト)10日前までの日付を配列$datesに作成します。

>>> $dates
=> [
     "2020-07-30",
     "2020-07-29",
     "2020-07-28",
     "2020-07-27",
     "2020-07-26",
     "2020-07-25",
     "2020-07-24",
     "2020-07-23",
     "2020-07-22",
     "2020-07-21",
   ]

そして、DBにアクセスして、データを取得、結果が$eatingsに入ります。

>>> $eatings = $user->EatingManagements()->whereIn(DB::raw('date_format(date, "%Y-%m-%d")'), $dates)->get();=> Illuminate\Database\Eloquent\Collection {#3920     all: [
       App\Model\EatingManagement {#3917
         id: 1,
         date: "2020-07-30",
         item: "item1",
         protein: 10,
         liqid: 10,
         carbo: 10,
         calorie: 10,
         created_at: "2020-07-30 10:38:50",
         updated_at: "2020-07-30 10:38:50",
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3916
           user_id: 1,
           eating_management_id: 1,
         },
       },
       App\Model\EatingManagement {#3652
         id: 2,
         date: "2020-07-30",
         item: "item2",
         protein: 20,
         liqid: 20,
         carbo: 20,
         calorie: 20,
         created_at: "2020-07-30 10:39:00",
         updated_at: "2020-07-30 10:39:00",
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3915
           user_id: 1,
           eating_management_id: 2,
         },
       },
     ],
   }

このデータを日付毎に集計します。

$dailyDatasは二次元の連想配列になっていて、$dailyDatas[日付][栄養素]という感じで格納されます。

栄養素の連想配列名は定義済みの$paramNamesの値をそのまま使用します。

こうすることで、今後何かDBに修正が入ったとしても、$paramNamesのみを修正すれば良いことになります。

>>> $dailyDatas
=> [
     "2020-07-30" => [
       "protein" => 30,
       "riqid" => 0,
       "carbo" => 30,
       "calorie" => 30,
     ],
   ]

ただ、このままだと、Json化してJavascript側で処理するのに、ものすごい面倒なことになるので、扱いやすいようにデータを変換します。

具体的には、$retDatas[データ番号][項目]という形にします。

>>> $retDatas
=> [
     [
       "date" => "2020-07-30",
       "protein" => 30,
       "riqid" => 0,
       "carbo" => 30,
       "calorie" => 30,
     ],
   ]

この状態でJson化してフロントエンド側に送信します。

この処理書くの大変だったわ。

namespace App\Http\Controllers\Eating;

class ApiController extends Controller
{
    /**
     * データ一覧を取得する
     */
    public function list(Request $request)
    {
        return response()->json(['dataLists' => $this->eatingManagement->getDailyList(Auth::user(), $request->contents["page"])]);
    }
Route::post('api/eating/list', 'Eating\ApiController@list');
<script>
export default {
    created: function() {
        this.updateList();
        //this.createPagenate();
    },
    methods: {
        updateList: function() {
            this.datalists = [];
            this.contents.page = this.currentPage;
            this.param.contents = this.contents;
            var self = this;
            axios.post('api/eating/list', this.param).then(function(response){
                response.data.dataLists.forEach(element => {
                    self.datalists.push({
                        date: element.date,
                        protein: element.protein,
                        liqid: element.liqid,
                        carbo: element.carbo,
                        calorie: element.calorie
                    })
                });
            }).catch(function(error){
            });
        }

いやー未だにPHP慣れないわー。

「【ダイエット支援】【食事管理】データ一覧処理を作成する。」への1件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください