Browse Source

储值卡统计

gorden 3 months ago
parent
commit
c8d7caa61a

+ 9 - 0
app/admin/controller/coupon/CardMainController.php

@@ -141,6 +141,14 @@ class CardMainController extends Curd
         if (!$cardMainId) {
             return json_fail('参数异常');
         }
+        $main = CardMain::with('category')->where('card_main_id', $cardMainId)->first();
+        if ($main->card_main_valid_mode == 'DAYS') {
+            $main->valid_term = $main->card_main_valid_days ? $main->card_main_valid_days . '天' : 0;
+        } elseif ($main->card_main_valid_mode == 'LONG') {
+            $main->valid_term = '长期有效';
+        } elseif ($main->card_main_valid_mode == 'DATE') {
+            $main->valid_term = date('Y/m/d', strtotime($main->card_main_valid_begin)) . '-' . date('Y/m/d', strtotime($main->card_main_valid_end));
+        }
         // 发行记录
         $cardIssue = CardIssue::where('join_issue_card_main_id', $cardMainId)->orderBy('card_issue_addtimes', 'DESC')->get()->toArray();
 
@@ -169,6 +177,7 @@ class CardMainController extends Curd
         ];
 
         $data = [
+            'main' => $main,
             'issue' => $cardIssue,
             'statistics' => $statistics
         ];

+ 271 - 3
app/admin/controller/finance/CardController.php

@@ -11,8 +11,276 @@ use support\Request;
 
 class CardController
 {
-
     public function list(Request $request)
+    {
+        $page = $request->get('page', 1);
+        $pageSize = $request->get('pageSize', 20);
+        $times = $request->get('times', [date('Y-m-01 00:00:00'), date('Y-m-d 23:59:59')]);
+        $times[0] = strtotime($times[0]);
+        $times[1] = strtotime(date('Y-m-d 23:59:59', strtotime($times[1])));
+        $name = $request->get('card_main_name');
+        $cardMain = CardMain::when(!empty($name), function ($query) use ($name) {
+            $query->where('card_main_name', 'like', '%' . $name . '%');
+        })->get()
+            ->toArray();
+        $cardIds = array_column($cardMain, 'card_main_id');
+        $cardAmount = array_column($cardMain, 'card_main_amount', 'card_main_id');
+        $cardName = array_column($cardMain, 'card_main_name', 'card_main_id');
+
+        $cardStatus = [
+            'issue' => 'ISSUE',
+            'add' => 'ADD',
+            'waiting' => 'WAITING',
+            'pending' => 'PENDING',
+            'used' => 'USED',
+            'done' => 'DONE',
+            'expired' => 'EXPIRED',
+            'paused' => 'PAUSED'
+        ];
+        $data = [];
+        foreach ($cardStatus as $key => $status) {
+            $cards = Card::when(!empty($cardIds), function ($query) use ($cardIds) {
+                $query->whereIn('join_card_main_id', $cardIds);
+            })->when($status == 'ISSUE', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.issue_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.issue_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.issue_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'ADD', function ($query) use ($times) {
+                $query->whereBetween('card_addtimes', $times)
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(card_addtimes),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'WAITING', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(card_assign_datetime) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(card_assign_datetime) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(card_assign_datetime)),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'PENDING', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.buy_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.buy_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.buy_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'USED', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.used_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.used_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.used_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'DONE', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.done_time'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.done_time'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.done_time' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'EXPIRED', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.expired_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.expired_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.expired_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'PAUSED', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.paused_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.paused_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.paused_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->selectRaw('count(card_id) as total,join_card_main_id')
+                ->groupBy('join_card_main_id', 'group_by_time')
+                ->get()
+                ->toArray();
+            $data[$key] = $cards;
+        }
+        $start = new \DateTime(date('Y-m-d', $times[0]));
+        $end = new \DateTime(date('Y-m-d 23:59:59', $times[1]));
+
+        // 创建一个 DateInterval,设置为一天
+        $interval = new \DateInterval('P1D');
+        // 创建一个日期范围对象,用于迭代所有日期
+        $dateRange = new \DatePeriod($start, $interval, $end);
+        $rows = [];
+        $statistics = [
+            'issue' => ['total' => 0, 'amount' => 0],
+            'add' => ['total' => 0, 'amount' => 0],
+            'waiting' => ['total' => 0, 'amount' => 0],
+            'pending' => ['total' => 0, 'amount' => 0],
+            'used' => ['total' => 0, 'amount' => 0],
+            'done' => ['total' => 0, 'amount' => 0],
+            'expired' => ['total' => 0, 'amount' => 0],
+            'paused' => ['total' => 0, 'amount' => 0],
+        ];
+        foreach ($dateRange as $date) {
+            $dayDate = $date->format('Y-m-d');
+            foreach ($data as $key => $datum) {
+                if (!empty($datum)) {
+                    foreach ($datum as $item) {
+                        if ($item['group_by_time'] == $dayDate) {
+                            $dateKey = $dayDate . '_' . $item['join_card_main_id'];
+                            $total = $item['total'];
+                            $statistics[$key]['total'] += $total;
+                            $mainAmount = $cardAmount[$item['join_card_main_id']] ?? 0;
+                            $amount = $total * $mainAmount;
+                            $statistics[$key]['amount'] += $amount;
+                            if (!empty($rows[$dateKey]) && !empty($rows[$dateKey][$key]) && !empty($rows[$dateKey][$key]['total'])) {
+                                $total = $rows[$dateKey][$key]['total'] + $total;
+                                $amount = $rows[$dateKey][$key]['amount'] + $amount;
+                            }
+                            $rows[$dateKey]['key'] = strtotime($dayDate) . '_' . $item['join_card_main_id'];
+                            $rows[$dateKey]['date'] = $dayDate;
+                            $rows[$dateKey]['card_main_id'] = $item['join_card_main_id'];
+                            $rows[$dateKey]['card_main_name'] = $cardName[$item['join_card_main_id']] ?? '';
+                            $rows[$dateKey]['card_main_amount'] = $mainAmount;
+                            $rows[$dateKey][$key] = [
+                                'total' => $total,
+                                'amount' => $amount
+                            ];
+                        }
+                    }
+                }
+            }
+        }
+
+        $rows = array_reverse($rows);
+        $rowsCount = count($rows);
+        $start = $pageSize * ($page - 1);
+        $data = array_slice($rows, $start, $pageSize);
+
+        return json_success('success', [
+            'total' => $rowsCount,
+            'rows' => array_values($data),
+            'page' => $page,
+            'pageSize' => $pageSize,
+            'statistics' => $statistics
+        ]);
+    }
+
+    public function exportCard(Request $request)
+    {
+        $times = $request->get('times', [date('Y-m-01 00:00:00'), date('Y-m-d 23:59:59')]);
+        $times[0] = strtotime($times[0]);
+        $times[1] = strtotime(date('Y-m-d 23:59:59', strtotime($times[1])));
+        $name = $request->get('card_main_name');
+        $keys = $request->get('keys', []);
+        $cardMain = CardMain::when(!empty($name), function ($query) use ($name) {
+            $query->where('card_main_name', 'like', '%' . $name . '%');
+        })->get()
+            ->toArray();
+        $cardIds = array_column($cardMain, 'card_main_id');
+        $cardAmount = array_column($cardMain, 'card_main_amount', 'card_main_id');
+        $cardName = array_column($cardMain, 'card_main_name', 'card_main_id');
+
+        $cardStatus = [
+            'issue' => 'ISSUE',
+            'add' => 'ADD',
+            'waiting' => 'WAITING',
+            'pending' => 'PENDING',
+            'used' => 'USED',
+            'done' => 'DONE',
+            'expired' => 'EXPIRED',
+            'paused' => 'PAUSED'
+        ];
+        $data = [];
+        foreach ($cardStatus as $key => $status) {
+            $cards = Card::when(!empty($cardIds), function ($query) use ($cardIds) {
+                $query->whereIn('join_card_main_id', $cardIds);
+            })->when($status == 'ISSUE', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.issue_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.issue_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.issue_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'ADD', function ($query) use ($times) {
+                $query->whereBetween('card_addtimes', $times)
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(card_addtimes),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'WAITING', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(card_assign_datetime) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(card_assign_datetime) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(card_assign_datetime)),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'PENDING', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.buy_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.buy_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.buy_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'USED', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.used_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.used_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.used_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'DONE', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.done_time'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.done_time'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.done_time' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'EXPIRED', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.expired_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.expired_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.expired_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->when($status == 'PAUSED', function ($query) use ($times) {
+                $query->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.paused_datetime'))) as SIGNED) >= {$times[0]}")
+                    ->whereRaw("CAST(UNIX_TIMESTAMP(JSON_UNQUOTE(JSON_EXTRACT(card_extend_json,'$.paused_datetime'))) as SIGNED) <= {$times[1]}")
+                    ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP( JSON_UNQUOTE( JSON_EXTRACT( card_extend_json, '$.paused_datetime' )))),'%Y-%m-%d') AS group_by_time");
+            })->selectRaw('count(card_id) as total,join_card_main_id')
+                ->groupBy('join_card_main_id', 'group_by_time')
+                ->get()
+                ->toArray();
+            $data[$key] = $cards;
+        }
+        $start = new \DateTime(date('Y-m-d', $times[0]));
+        $end = new \DateTime(date('Y-m-d 23:59:59', $times[1]));
+
+        // 创建一个 DateInterval,设置为一天
+        $interval = new \DateInterval('P1D');
+        // 创建一个日期范围对象,用于迭代所有日期
+        $dateRange = new \DatePeriod($start, $interval, $end);
+        $rows = [];
+        $statistics = [
+            'issue' => ['total' => 0, 'amount' => 0],
+            'add' => ['total' => 0, 'amount' => 0],
+            'waiting' => ['total' => 0, 'amount' => 0],
+            'pending' => ['total' => 0, 'amount' => 0],
+            'used' => ['total' => 0, 'amount' => 0],
+            'done' => ['total' => 0, 'amount' => 0],
+            'expired' => ['total' => 0, 'amount' => 0],
+            'paused' => ['total' => 0, 'amount' => 0],
+        ];
+        foreach ($dateRange as $date) {
+            $dayDate = $date->format('Y-m-d');
+            foreach ($data as $key => $datum) {
+                if (!empty($datum)) {
+                    foreach ($datum as $item) {
+                        if ($item['group_by_time'] == $dayDate) {
+                            // 有选择,过滤
+                            if (!empty($keys) && !in_array(strtotime($dayDate) . '_' . $item['join_card_main_id'], $keys)) {
+                                continue;
+                            }
+                            $dateKey = $dayDate . '_' . $item['join_card_main_id'];
+                            $total = $item['total'];
+                            $statistics[$key]['total'] += $total;
+                            $mainAmount = $cardAmount[$item['join_card_main_id']] ?? 0;
+                            $amount = $total * $mainAmount;
+                            $statistics[$key]['amount'] += $amount;
+                            if (!empty($rows[$dateKey]) && !empty($rows[$dateKey][$key]) && !empty($rows[$dateKey][$key]['total'])) {
+                                $total = $rows[$dateKey][$key]['total'] + $total;
+                                $amount = $rows[$dateKey][$key]['amount'] + $amount;
+                            }
+                            $rows[$dateKey]['date'] = $dayDate;
+                            $rows[$dateKey]['card_main_id'] = $item['join_card_main_id'];
+                            $rows[$dateKey]['card_main_name'] = $cardName[$item['join_card_main_id']] ?? '';
+                            $rows[$dateKey]['card_main_amount'] = $mainAmount;
+                            $rows[$dateKey][$key] = [
+                                'total' => $total,
+                                'amount' => $amount
+                            ];
+                        }
+                    }
+                }
+            }
+        }
+
+        $rows = array_reverse($rows);
+        $exportData = [];
+        foreach ($rows as $row) {
+            $exportData[] = [
+                'date' => $row['date'],
+                'card_main_name' => $row['card_main_name'],
+                'card_main_amount' => $row['card_main_amount'],
+                'issue' => isset($row['issue']) ? $row['issue']['total'] . '张 (¥' . sprintf('%.2f', $row['issue']['amount']) . ')' : '--',
+                'add' => isset($row['add']) ? $row['add']['total'] . '张 (¥' . sprintf('%.2f', $row['add']['amount']) . ')' : '--',
+                'waiting' => isset($row['waiting']) ? $row['waiting']['total'] . '张 (¥' . sprintf('%.2f', $row['waiting']['amount']) . ')' : '--',
+                'pending' => isset($row['pending']) ? $row['pending']['total'] . '张 (¥' . sprintf('%.2f', $row['pending']['amount']) . ')' : '--',
+                'used' => isset($row['used']) ? $row['used']['total'] . '张 (¥' . sprintf('%.2f', $row['used']['amount']) . ')' : '--',
+                'done' => isset($row['done']) ? $row['done']['total'] . '张 (¥' . sprintf('%.2f', $row['done']['amount']) . ')' : '--',
+                'expired' => isset($row['expired']) ? $row['expired']['total'] . '张 (¥' . sprintf('%.2f', $row['expired']['amount']) . ')' : '--',
+                'paused' => isset($row['paused']) ? $row['paused']['total'] . '张 (¥' . sprintf('%.2f', $row['paused']['amount']) . ')' : '--'
+            ];
+        }
+
+        return json_success('success', $exportData);
+    }
+
+    public function listOld(Request $request)
     {
         $page = $request->get('page', 1);
         $pageSize = $request->get('pageSize', 20);
@@ -33,7 +301,7 @@ class CardController
             $query->whereBetween('card_main_addtimes', $addtimes);
         });
         $total = $cardMain->count();
-        $rows = $cardMain->select('card_main_id', 'card_main_amount','card_main_name')
+        $rows = $cardMain->select('card_main_id', 'card_main_amount', 'card_main_name')
             ->orderBy('card_main_addtimes', 'DESC')
             ->forPage($page, $pageSize)
             ->get()
@@ -78,7 +346,7 @@ class CardController
             $row['used']['total'] = $usedTotal;
             $row['used']['amount'] = sprintf('%.2f', $usedTotal * $row['card_main_amount']);
             $statistics['used']['total'] += $usedTotal;
-            $statistics['used']['amount'] = sprintf('%.2f', $usedTotal * $row['card_main_amount']+$statistics['used']['amount']);
+            $statistics['used']['amount'] = sprintf('%.2f', $usedTotal * $row['card_main_amount'] + $statistics['used']['amount']);
             // 使用完成统计
             $doneTotal = Card::where('card_status', 'DONE')->where('join_card_main_id', $row['card_main_id'])->count();
             $row['done']['total'] = $doneTotal;

+ 28 - 5
app/admin/controller/member/AccountController.php

@@ -110,7 +110,7 @@ class AccountController extends Curd
             } elseif ($item['member_account_classify'] == 'CASH') {
                 $data['cash'] = $item;
             } elseif ($item['member_account_classify'] == 'CARD') {
-                if (intval($item['member_account_surplus']) == 0 && intval($item['member_account_added']) == 0){
+                if (intval($item['member_account_surplus']) == 0 && intval($item['member_account_added']) == 0) {
                     continue;
                 }
                 $data['card'][] = $item;
@@ -143,6 +143,22 @@ class AccountController extends Curd
             $account = MemberAccount::where('member_account_id', $accountId)->first();
             $account->member_account_status = $status;
             $account->save();
+            // 储值卡账户,把卡冻结掉
+            if ($account->member_account_classify == 'CARD') {
+                $card = Card::where('card_id', $account->member_account_nbr)->first();
+                $cardExtendJson = [];
+                if (!empty($card->card_extend_json)) {
+                    $cardExtendJson = json_decode($card->card_extend_json, true);
+                }
+                if ($status == 'DISABLED') {
+                    $card->card_status = 'PAUSED';
+                    $cardExtendJson['paused_datetime'] = date('Y-m-d H:i:s');
+                    $card->card_extend_json = json_encode($cardExtendJson);
+                } elseif ($status == 'ACTIVED') {
+                    $card->card_status = 'USED';
+                }
+                $card->save();
+            }
 
             _syslog("修改账户状态", '修改账户状态成功');
             return json_success('账户状态修改成功');
@@ -181,14 +197,14 @@ class AccountController extends Curd
 
         $card = Card::with([
             'main' => function ($query) {
-                $query->select('card_main_id', 'card_main_name','card_main_amount','card_main_added');
+                $query->select('card_main_id', 'card_main_name', 'card_main_amount', 'card_main_added');
             }
         ])->where('card_id', $cardId)
             ->first();
         if (!$card || empty($card->main)) {
             return json_fail("卡号不存在");
         }
-        if ($card->card_cdkey != $cardKey){
+        if ($card->card_cdkey != $cardKey) {
             return json_fail("秘钥错误,请重新输入");
         }
         if ($card->is_issue == 'N') {
@@ -228,9 +244,16 @@ class AccountController extends Curd
             // 会员绑定卡
             $card->join_card_member_id = $memberId;
             $card->join_card_member_account_id = $accountId;
-            $card->card_assign_datetime = date('Y-m-d H:i:s');
+//            $card->card_assign_datetime = date('Y-m-d H:i:s');
             $card->card_deadline_datetime = $duedate;
             $card->card_status = 'USED';
+            // 激活时间
+            $cardExtendJson = [];
+            if (!empty($card->card_extend_json)) {
+                $cardExtendJson = json_decode($card->card_extend_json, true);
+            }
+            $cardExtendJson['used_datetime'] = date('Y-m-d H:i:s');
+            $card->card_extend_json = json_encode($cardExtendJson);
             $card->save();
 
             // member_account_list 加卡充值记录
@@ -251,7 +274,7 @@ class AccountController extends Curd
             return json_success('success');
         } catch (\Exception $e) {
             Db::rollBack();
-            Log::error("储值卡绑定失败",['msg'=>$e->getMessage()]);
+            Log::error("储值卡绑定失败", ['msg' => $e->getMessage()]);
             return json_fail("绑定失败");
         }
     }

+ 101 - 0
app/admin/controller/member/MemberController.php

@@ -19,6 +19,7 @@ use app\model\Order;
 use app\model\OrderReturn;
 use app\model\OrderSheet;
 use app\model\PayDetail;
+use app\model\SysUser;
 use support\Db;
 use support\exception\BusinessException;
 use support\Log;
@@ -565,6 +566,106 @@ class MemberController
         return MemberService::update($request->post());
     }
 
+    /**
+     * @Desc 更换手机号
+     * @Author Gorden
+     * @Date 2024/11/25 15:54
+     *
+     * @param Request $request
+     * @return \support\Response
+     */
+    public function changeMobile(Request $request)
+    {
+        $memberId = $request->post('member_id');
+        $mobile = $request->post('member_mobile');
+        $ticket = $request->post('ticket');
+
+        if (!$memberId || !$mobile || !$ticket) {
+            return json_fail("参数异常");
+        }
+        if (Member::where('member_mobile', $mobile)->exists()) {
+            return json_fail("新的手机号已存在账户,无法变更,请联系管理员");
+        }
+        try {
+            $member = Member::where('member_id', $memberId)->first();
+            $oldMobile = $member->member_mobile;
+            $member->member_mobile = $mobile;
+            $memberUpdateJson = [];
+            if (!empty($member->member_update_json)) {
+                $memberUpdateJson = json_decode($member->member_update_json, true);
+            }
+            $memberUpdateJson['update'][] = [
+                'time' => date('Y-m-d H:i:s'),
+                'user_id' => JwtToken::getCurrentId(),
+                'data' => [
+                    [
+                        'field' => 'member_mobile',
+                        'old' => $oldMobile,
+                        'new' => $mobile,
+                        'media' => [
+                            'url' => str_replace(getenv("storage_domain"), '', $ticket)
+                        ]
+                    ]
+                ]
+            ];
+            $member->member_update_json = json_encode($memberUpdateJson);
+            $member->save();
+
+            return json_success("更换手机号成功");
+        } catch (\Exception $e) {
+            return json_fail("更换手机号失败");
+        }
+    }
+
+    /**
+     * @Desc 会员修改记录
+     * @Author Gorden
+     * @Date 2024/11/26 8:41
+     *
+     * @param Request $request
+     * @return \support\Response
+     */
+    public function updateLogList(Request $request)
+    {
+        $page = $request->get('page', 1);
+        $pageSize = $request->get('pageSize', 10);
+        $memberId = $request->get('member_id');
+
+        $member = Member::where('member_id', $memberId)->first();
+        $updateJson = [];
+        if (!empty($member->member_update_json)) {
+            $memberUpdateJson = json_decode($member->member_update_json, true);
+            $updateJson = $memberUpdateJson['update'] ?? [];
+        }
+        foreach ($updateJson as &$item) {
+            if (!empty($item['user_id'])) {
+                $item['user_name'] = SysUser::where('user_id', $item['user_id'])->value('user_name');
+            } else {
+                $item['user_name'] = '会员';
+            }
+            // 修改内容
+            $item['content'] = '';
+            $item['images'] = '';
+            $item['imagesOrigin'] = '';
+            foreach ($item['data'] as $datum) {
+                if ($datum['field'] == 'member_mobile') {
+                    $item['content'] = '手机号由' . $datum['old'] . '更换为' . $datum['new'] . ';';
+                    if (!empty($datum['media'])) {
+                        $item['images'] = getenv('STORAGE_DOMAIN') . $datum['media']['url'];
+                        $item['imagesOrigin'] = str_replace('/thumb', '', $item['images']);
+                    }
+                }
+            }
+            $item['content'] = rtrim($item['content'], ';');
+        }
+        $total = count($updateJson);
+        $updateJson = array_reverse($updateJson);
+        $start = ($page - 1) * $pageSize;
+        $rows = array_slice($updateJson, $start, $pageSize);
+
+        return json_success('', compact('rows', 'page', 'pageSize', 'total'));
+    }
+
     /**
      * @Desc 绑定的设备
      * @Author Gorden

+ 24 - 12
app/admin/controller/order/WholeController.php

@@ -3627,17 +3627,6 @@ class WholeController extends Curd
 
         Db::beginTransaction();
         try {
-            if (!empty($params['card_id'])) {
-                $card = Card::where('card_id', $params['card_id'])->first();
-                if (empty($card)) {
-                    throw new BusinessException("储值卡不存在");
-                }
-                if ($card->card_status != 'WAITING' || $card->is_issue != 'Y') {
-                    throw new BusinessException("储值卡状态异常");
-                }
-                $card->card_status = 'PENDING';
-                $card->save();
-            }
             $expressExtendJson = [];
             if ($params['express_type'] == '自提') {
                 $model = OrderExpress::where('join_express_order_id', $params['order_id'])->first();
@@ -3691,7 +3680,6 @@ class WholeController extends Curd
                     $model = new OrderExpress();
                 }
             }
-
             // 该订单状态
             $orderData['order_update_user_id'] = JwtToken::getCurrentId();
             $orderData['order_updatetimes'] = time();
@@ -3699,6 +3687,30 @@ class WholeController extends Curd
             // 该订单Sheet状态
             OrderSheet::where('join_sheet_order_id', $request->post('order_id'))->update($orderSheetData);
 
+            // 卡发货
+            if (!empty($params['card_id'])) {
+                $card = Card::where('card_id', $params['card_id'])->first();
+                if (empty($card)) {
+                    throw new BusinessException("储值卡不存在");
+                }
+                if ($card->card_status != 'WAITING' || $card->is_issue != 'Y') {
+                    throw new BusinessException("储值卡状态异常");
+                }
+                $order = Order::where('order_id', $request->post('order_id'))->first();
+                $card->card_status = 'PENDING';
+                // 售卖时间
+                $cardExtendJson = [];
+                if (!empty($card->card_extend_json)) {
+                    $cardExtendJson = json_decode($card->card_extend_json, true);
+                }
+                //{"buy_member": "", "buy_datetime": "", "buy_order_id": ""}
+                $cardExtendJson['buy_member'] = $order->join_order_member_id ?? '';
+                $cardExtendJson['buy_datetime'] = date('Y-m-d H:i:s');
+                $cardExtendJson['buy_order_id'] = $order->order_id ?? '';
+                $card->card_extend_json = json_encode($cardExtendJson);
+                $card->save();
+            }
+
             // 入配送记录表            
             $model->join_express_order_id = $params['order_id'];
             if (isset($params['order_express_goods'])) {

+ 32 - 0
app/admin/service/coupon/CardService.php

@@ -2,6 +2,9 @@
 
 namespace app\admin\service\coupon;
 
+use app\model\Card;
+use app\model\MemberAccount;
+use support\Log;
 use support\exception\BusinessException;
 
 class CardService
@@ -32,6 +35,35 @@ class CardService
         return $cardId;
     }
 
+    public static function checkExpired()
+    {
+        $unixTime = time();
+        $cards = Card::whereRaw("CAST(UNIX_TIMESTAMP(card_deadline_datetime) as SIGNED) <= {$unixTime}")
+            ->whereRaw("CAST(UNIX_TIMESTAMP(card_deadline_datetime) as SIGNED) > 0")
+            ->whereIn('card_status', ['INIT', 'WAITING', 'PENDING', 'USED'])
+            ->select('card_id')
+            ->get()
+            ->toArray();
+        foreach ($cards as $card) {
+            // 检查是否关联会员账户
+            $account = MemberAccount::where('member_account_nbr', $card['card_id'])->first();
+            if (!empty($account) && $account->member_account_status == 'ACTIVED') {
+                $account->member_account_status = 'EXPIRED';
+                $account->save();
+            }
+            $cardNow = Card::where('card_id', $card['card_id'])->first();
+            $cardNow->card_status = 'EXPIRED';
+            $cardExtendJson = [];
+            if (!empty($cardNow->card_extend_json)) {
+                $cardExtendJson = json_decode($cardNow->card_extend_json, true);
+            }
+            $cardExtendJson['expired_datetime'] = date('Y-m-d H:i:s');
+            $cardNow->card_extend_json = json_encode($cardExtendJson);
+            $cardNow->save();
+
+            Log::info("储值卡:【" . $card['card_id'] . '】已过期');
+        }
+    }
 
     public static $status = [
         'INIT' => '待分配',

+ 1 - 1
app/admin/service/member/MemberService.php

@@ -2233,7 +2233,7 @@ class MemberService
                     if (!empty($card->card_extend_json)){
                         $cardExtendJson = json_decode($card->card_extend_json,true);
                     }
-                    $cardExtendJson['done_datetime'] = date('Y-m-d H:i:s');
+                    $cardExtendJson['done_time'] = date('Y-m-d H:i:s');
                     $card->card_status = 'DONE';
                     $card->card_extend_json = json_encode($cardExtendJson);
                     $card->save();

+ 4 - 0
process/Task.php

@@ -4,6 +4,7 @@ namespace process;
 
 use app\admin\controller\notify\RechargeController;
 use app\admin\service\client\MessageService;
+use app\admin\service\coupon\CardService;
 use app\admin\service\coupon\CouponService;
 use app\admin\service\goods\GoodsService;
 use app\admin\service\member\MemberService;
@@ -33,6 +34,9 @@ class Task
 
             // 优惠券自动过期
             CouponService::checkCouponExpired();
+
+            // 储值卡自动过期
+            CardService::checkExpired();
         });
 
         // 每天的0点1分执行,注意这里省略了秒位

+ 3 - 0
route/admin.php

@@ -212,6 +212,7 @@ Route::group('/admin', function () {
         /* 储值卡管理 */
         Route::group('/card', function () {
             Route::get('/list', [\app\admin\controller\finance\CardController::class, 'list']);
+            Route::get('/export', [\app\admin\controller\finance\CardController::class, 'exportCard']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -825,6 +826,8 @@ Route::group('/admin', function () {
             Route::get('/statistics', [\app\admin\controller\member\MemberController::class, 'statistics']);
             Route::post('/add', [\app\admin\controller\member\MemberController::class, 'add']);
             Route::post('/update', [\app\admin\controller\member\MemberController::class, 'update']);
+            Route::post('/changeMobile', [\app\admin\controller\member\MemberController::class, 'changeMobile']);
+            Route::get('/updateLogList', [\app\admin\controller\member\MemberController::class, 'updateLogList']);
             Route::get('/exportMember', [\app\admin\controller\member\MemberController::class, 'exportMember']);
             Route::get('/fansList', [\app\admin\controller\member\MemberController::class, 'fansList']);
             Route::get('/commissionList', [\app\admin\controller\member\MemberController::class, 'commissionList']);