Kaynağa Gözat

feat(points): 添加积分管理功能- 新增积分管理相关的路由、控制器、模型和视图组件- 实现积分记录列表、用户列表、积分统计等功能
- 添加手动调整积分和导出积分记录的功能
- 优化用户选择和积分搜索的交互体验

runphp 6 ay önce
ebeveyn
işleme
a9b21a29d3

+ 32 - 0
route/admin.php

@@ -0,0 +1,32 @@
+<?php
+declare(strict_types=1);
+
+use think\facade\Route;
+use SixShop\Points\Controller\{UserPointController, UserPointLogController};
+use SixShop\System\Middleware\MacroPageMiddleware;
+
+// 后台管理API路由
+// 路由前缀: /admin/points
+
+Route::resource('user_point', UserPointController::class)->middleware([
+    MacroPageMiddleware::class,
+    'auth'
+])->option([
+    'name' => 'points:user_point',
+    'description' => '用户积分',
+]);
+
+Route::group('user_point_log', function () {
+    Route::get('user', [UserPointLogController::class, 'user'])->middleware([
+        MacroPageMiddleware::class,
+    ])->option([
+        'name' => 'points:user_point_log:user',
+        'description' => '积分记录用户列表',
+    ]);
+    Route::resource('', UserPointLogController::class)->middleware([
+        MacroPageMiddleware::class,
+    ])->option([
+        'name' => 'points:user_point_log',
+        'description' => '积分记录',
+    ]);
+})->middleware(['auth']);

+ 20 - 0
src/Controller/UserPointController.php

@@ -0,0 +1,20 @@
+<?php
+declare(strict_types=1);
+namespace SixShop\Points\Controller;
+
+use SixShop\Core\Request;
+use SixShop\Points\Entity\UserPointEntity;
+use think\Response;
+use function SixShop\Core\page_response;
+
+class UserPointController
+{
+    public function index(Request $request, UserPointEntity $entity): Response
+    {
+        $params = $request->get([
+            'keyword/s',
+        ]);
+        $paginate = $entity->getUserList($params, $request->pageAndLimit());
+        return page_response($paginate);
+    }
+}

+ 24 - 0
src/Controller/UserPointLogController.php

@@ -0,0 +1,24 @@
+<?php
+declare(strict_types=1);
+
+namespace SixShop\Points\Controller;
+
+use SixShop\Core\Request;
+use SixShop\Points\Entity\UserPointLogEntity;
+use think\Response;
+use function SixShop\Core\page_response;
+use function SixShop\Core\success_response;
+
+class UserPointLogController
+{
+    public function index(Request $request, UserPointLogEntity $entity): Response
+    {
+        $params = $request->get([
+           'user_id/d',
+           'create_time/a',
+        ]);
+        $paginate = $entity->getList($params, $request->pageAndLimit());
+        $stats = $entity->getStats($params);
+        return page_response($paginate, $stats);
+    }
+}

+ 14 - 0
src/Entity/UserPointEntity.php

@@ -5,6 +5,8 @@ namespace SixShop\Points\Entity;
 use SixShop\Core\Entity\BaseEntity;
 use SixShop\Points\Enum\UserPointTypeEnum;
 use SixShop\Points\Model\UserPointLogModel;
+use think\db\Query;
+use think\Paginator;
 
 class UserPointEntity extends BaseEntity
 {
@@ -42,4 +44,16 @@ class UserPointEntity extends BaseEntity
         ]);
         return $userPoint;
     }
+
+    public function getUserList(array $params, array $pageAndLimit): Paginator
+    {
+        return $this->alias('l')
+            ->leftJoin('user u', 'u.id = l.user_id')
+            ->withSearch(['keyword' =>function (Query $query, string $keyword){
+                $keyword && $query->where('u.nickname|u.mobile|u.id', 'like', $keyword);
+            }], $params)
+            ->group('l.user_id')
+            ->field( ['u.id', 'u.avatar', 'u.nickname', 'u.mobile', 'l.point', 'l.update_time'])
+            ->paginate($pageAndLimit);
+    }
 }

+ 23 - 1
src/Entity/UserPointLogEntity.php

@@ -1,10 +1,32 @@
 <?php
 declare(strict_types=1);
+
 namespace SixShop\Points\Entity;
 
 use SixShop\Core\Entity\BaseEntity;
+use SixShop\Points\Model\UserPointLogModel;
+use think\Paginator;
 
+/**
+ * @mixin UserPointLogModel
+ */
 class UserPointLogEntity extends BaseEntity
 {
+    public function getList(array $params, array $pageAndLimit): Paginator
+    {
+        return $this->withSearch(['user_id', 'create_time'], $params)
+            ->withJoin(['user' => ['nickname']])
+            ->order('id', 'desc')
+            ->paginate($pageAndLimit);
+    }
 
-}          
+    public function getStats(array $params)
+    {
+        return $this->withSearch(['user_id', 'create_time'], $params)->field(
+            [
+                'SUM(CASE WHEN point > 0 THEN point ELSE 0 END) AS positive_total',
+                'SUM(CASE WHEN point < 0 THEN point ELSE 0 END) AS negative_total',
+            ]
+        )->select()->first();
+    }
+}

+ 16 - 0
src/Model/UserPointLogModel.php

@@ -2,8 +2,11 @@
 declare(strict_types=1);
 namespace SixShop\Points\Model;
 
+use app\model\User;
 use SixShop\Points\Enum\UserPointTypeEnum;
+use think\db\Query;
 use think\Model;
+use think\model\relation\BelongsTo;
 
 class UserPointLogModel extends Model
 {
@@ -16,4 +19,17 @@ class UserPointLogModel extends Model
             ]
         ];
     }
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'user_id', 'id');
+    }
+    public function searchUserIdAttr(Query $query, $value, $data)
+    {
+        $value > 0 && $query->where('user_id', $value);
+    }
+
+    public function searchCreateTimeAttr(Query $query, $value, $data)
+    {
+        $value && $query->whereBetweenTime('create_time', $value[0], $value[1]);
+    }
 }