Browse Source

feature: knowledge base & surplus switch

Tokumeikoi 4 years ago
parent
commit
9041ee2a37

+ 2 - 1
app/Http/Controllers/Admin/ConfigController.php

@@ -68,7 +68,8 @@ class ConfigController extends Controller
                 'subscribe' => [
                     'plan_change_enable' => (int)config('v2board.plan_change_enable', 1),
                     'reset_traffic_method' => (int)config('v2board.reset_traffic_method', 0),
-                    'renew_reset_traffic_enable' => (int)config('v2board.renew_reset_traffic_enable', 0)
+                    'renew_reset_traffic_enable' => (int)config('v2board.renew_reset_traffic_enable', 0),
+                    'surplus_enable' => (int)config('v2board.surplus_enable', 1)
                 ],
                 'pay' => [
                     // alipay

+ 109 - 0
app/Http/Controllers/Admin/KnowledgeController.php

@@ -0,0 +1,109 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Http\Requests\Admin\KnowledgeSave;
+use App\Http\Requests\Admin\KnowledgeSort;
+use App\Models\Knowledge;
+use Illuminate\Http\Request;
+use App\Http\Controllers\Controller;
+use Illuminate\Support\Facades\DB;
+
+class KnowledgeController extends Controller
+{
+    public function fetch(Request $request)
+    {
+        if ($request->input('id')) {
+            $knowledge = Knowledge::find($request->input('id'))->toArray();
+            if (!$knowledge) abort(500, '知识不存在');
+            return response([
+                'data' => $knowledge
+            ]);
+        }
+        return response([
+            'data' => Knowledge::select(['title', 'id', 'updated_at', 'category', 'show'])
+                ->orderBy('sort', 'ASC')
+                ->get()
+        ]);
+    }
+
+    public function getCategory(Request $request)
+    {
+        return response([
+            'data' => array_keys(Knowledge::get()->groupBy('category')->toArray())
+        ]);
+    }
+
+    public function save(KnowledgeSave $request)
+    {
+        $params = $request->validated();
+
+        if (!$request->input('id')) {
+            if (!Knowledge::create($params)) {
+                abort(500, '创建失败');
+            }
+        } else {
+            try {
+                Knowledge::find($request->input('id'))->update($params);
+            } catch (\Exception $e) {
+                abort(500, '保存失败');
+            }
+        }
+
+        return response([
+            'data' => true
+        ]);
+    }
+
+    public function show(Request $request)
+    {
+        if (empty($request->input('id'))) {
+            abort(500, '参数有误');
+        }
+        $knowledge = Knowledge::find($request->input('id'));
+        if (!$knowledge) {
+            abort(500, '知识不存在');
+        }
+        $knowledge->show = $knowledge->show ? 0 : 1;
+        if (!$knowledge->save()) {
+            abort(500, '保存失败');
+        }
+
+        return response([
+            'data' => true
+        ]);
+    }
+
+    public function sort(KnowledgeSort $request)
+    {
+        DB::beginTransaction();
+        foreach ($request->input('knowledge_ids') as $k => $v) {
+            if (!Knowledge::find($v)->update(['sort' => $k + 1])) {
+                DB::rollBack();
+                abort(500, '保存失败');
+            }
+        }
+        DB::commit();
+        return response([
+            'data' => true
+        ]);
+    }
+
+    public function drop(Request $request)
+    {
+        if (empty($request->input('id'))) {
+            abort(500, '参数有误');
+        }
+        $knowledge = Knowledge::find($request->input('id'));
+        if (!$knowledge) {
+            abort(500, '知识不存在');
+        }
+        if (!$knowledge->delete()) {
+            abort(500, '删除失败');
+        }
+
+        return response([
+            'data' => true
+        ]);
+    }
+}

+ 0 - 93
app/Http/Controllers/Admin/TutorialController.php

@@ -1,93 +0,0 @@
-<?php
-
-namespace App\Http\Controllers\Admin;
-
-use App\Http\Requests\Admin\TutorialSave;
-use App\Http\Requests\Admin\TutorialSort;
-use Illuminate\Http\Request;
-use App\Http\Controllers\Controller;
-use App\Models\Tutorial;
-use Illuminate\Support\Facades\DB;
-
-class TutorialController extends Controller
-{
-    public function fetch(Request $request)
-    {
-        return response([
-            'data' => Tutorial::orderBy('sort', 'ASC')->get()
-        ]);
-    }
-
-    public function save(TutorialSave $request)
-    {
-        $params = $request->validated();
-
-        if (!$request->input('id')) {
-            if (!Tutorial::create($params)) {
-                abort(500, '创建失败');
-            }
-        } else {
-            try {
-                Tutorial::find($request->input('id'))->update($params);
-            } catch (\Exception $e) {
-                abort(500, '保存失败');
-            }
-        }
-
-        return response([
-            'data' => true
-        ]);
-    }
-
-    public function show(Request $request)
-    {
-        if (empty($request->input('id'))) {
-            abort(500, '参数有误');
-        }
-        $tutorial = Tutorial::find($request->input('id'));
-        if (!$tutorial) {
-            abort(500, '教程不存在');
-        }
-        $tutorial->show = $tutorial->show ? 0 : 1;
-        if (!$tutorial->save()) {
-            abort(500, '保存失败');
-        }
-
-        return response([
-            'data' => true
-        ]);
-    }
-
-    public function sort(TutorialSort $request)
-    {
-        DB::beginTransaction();
-        foreach ($request->input('tutorial_ids') as $k => $v) {
-            if (!Tutorial::find($v)->update(['sort' => $k + 1])) {
-                DB::rollBack();
-                abort(500, '保存失败');
-            }
-        }
-        DB::commit();
-        return response([
-            'data' => true
-        ]);
-    }
-
-    public function drop(Request $request)
-    {
-        if (empty($request->input('id'))) {
-            abort(500, '参数有误');
-        }
-        $tutorial = Tutorial::find($request->input('id'));
-        if (!$tutorial) {
-            abort(500, '教程不存在');
-        }
-        if (!$tutorial->delete()) {
-            abort(500, '删除失败');
-        }
-
-        return response([
-            'data' => true
-        ]);
-    }
-}

+ 43 - 0
app/Http/Controllers/User/KnowledgeController.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Http\Controllers\User;
+
+use App\Http\Controllers\Controller;
+use App\Models\User;
+use App\Services\UserService;
+use Illuminate\Http\Request;
+use App\Models\Knowledge;
+
+class KnowledgeController extends Controller
+{
+    public function fetch(Request $request)
+    {
+        if ($request->input('id')) {
+            $knowledge = Knowledge::where('id', $request->input('id'))
+                ->where('show', 1)
+                ->first()
+                ->toArray();
+            if (!$knowledge) abort(500, '知识不存在');
+            $user = User::find($request->session()->get('id'));
+            $userService = new UserService();
+            $appleId = $userService->isAvailable($user) ? config('v2board.apple_id') : '没有有效订阅无法使用本站提供的AppleID';
+            $appleIdPassword = $userService->isAvailable($user) ? config('v2board.apple_id_password') : '没有有效订阅无法使用本站提供的AppleID';
+            $subscribeUrl = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token'];
+            $knowledge['body'] = str_replace('{{appleId}}', $appleId, $knowledge['body']);
+            $knowledge['body'] = str_replace('{{appleIdPassword}}', $appleIdPassword, $knowledge['body']);
+            $knowledge['body'] = str_replace('{{subscribeUrl}}', $subscribeUrl, $knowledge['body']);
+            return response([
+                'data' => $knowledge
+            ]);
+        }
+        $knowledges = Knowledge::select(['id', 'category', 'title', 'updated_at'])
+            ->where('language', $request->input('language'))
+            ->where('show', 1)
+            ->orderBy('sort', 'ASC')
+            ->get()
+            ->groupBy('category');
+        return response([
+            'data' => $knowledges
+        ]);
+    }
+}

+ 0 - 82
app/Http/Controllers/User/TutorialController.php

@@ -1,82 +0,0 @@
-<?php
-
-namespace App\Http\Controllers\User;
-
-use App\Http\Controllers\Controller;
-use Illuminate\Http\Request;
-use App\Models\User;
-use App\Models\Tutorial;
-use Illuminate\Support\Facades\DB;
-
-class TutorialController extends Controller
-{
-    public function getSubscribeUrl(Request $request)
-    {
-        $user = User::find($request->session()->get('id'));
-        return response([
-            'data' => [
-                'subscribe_url' => config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token']
-            ]
-        ]);
-    }
-
-    public function getAppleID(Request $request)
-    {
-        $user = User::find($request->session()->get('id'));
-        if ($user->expired_at < time()) {
-            return response([
-                'data' => [
-                ]
-            ]);
-        }
-        return response([
-            'data' => [
-                'apple_id' => config('v2board.apple_id'),
-                'apple_id_password' => config('v2board.apple_id_password')
-            ]
-        ]);
-    }
-
-    public function fetch(Request $request)
-    {
-        if ($request->input('id')) {
-            $tutorial = Tutorial::where('show', 1)
-                ->where('id', $request->input('id'))
-                ->first();
-            if (!$tutorial) {
-                abort(500, '教程不存在');
-            }
-            return response([
-                'data' => $tutorial
-            ]);
-        }
-        $tutorial = Tutorial::select(['id', 'category_id', 'title'])
-            ->where('show', 1)
-            ->orderBy('sort', 'ASC')
-            ->get()
-            ->groupBy('category_id');
-        $user = User::find($request->session()->get('id'));
-        $response = [
-            'data' => [
-                'tutorials' => $tutorial,
-                'safe_area_var' => [
-                    'subscribe_url' => config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token'],
-                    'app_name' => config('v2board.app_name', 'V2board'),
-                    'apple_id' => $user->expired_at > time() || $user->expired_at === NULL ? config('v2board.apple_id', '本站暂无提供AppleID信息') : '账号过期或未订阅',
-                    'apple_id_password' => $user->expired_at > time() || $user->expired_at === NULL ? config('v2board.apple_id_password', '本站暂无提供AppleID信息') : '账号过期或未订阅'
-                ]
-            ]
-        ];
-        // fuck support shadowrocket urlsafeb64 subscribe
-        $response['data']['safe_area_var']['b64_subscribe_url'] = str_replace(
-            array('+', '/', '='),
-            array('-', '_', ''),
-            base64_encode($response['data']['safe_area_var']['subscribe_url'])
-        );
-        // end
-        // fuck support surge urlencode subscribe
-        $response['data']['safe_area_var']['ue_subscribe_url'] = urlencode($response['data']['safe_area_var']['subscribe_url']);
-        // end
-        return response($response);
-    }
-}

+ 1 - 0
app/Http/Requests/Admin/ConfigSave.php

@@ -42,6 +42,7 @@ class ConfigSave extends FormRequest
             'plan_change_enable' => 'in:0,1',
             'reset_traffic_method' => 'in:0,1',
             'renew_reset_traffic_enable' => 'in:0,1',
+            'surplus_enable' => 'in:0,1',
             // server
             'server_token' => 'nullable|min:16',
             'server_license' => 'nullable',

+ 29 - 0
app/Http/Requests/Admin/KnowledgeCategorySave.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Requests\Admin;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class KnowledgeCategorySave extends FormRequest
+{
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        return [
+            'name' => 'required',
+            'language' => 'required'
+        ];
+    }
+
+    public function messages()
+    {
+        return [
+            'name.required' => '分类名称不能为空',
+            'language.required' => '分类语言不能为空'
+        ];
+    }
+}

+ 28 - 0
app/Http/Requests/Admin/KnowledgeCategorySort.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Requests\Admin;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class KnowledgeCategorySort extends FormRequest
+{
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        return [
+            'knowledge_category_ids' => 'required|array'
+        ];
+    }
+
+    public function messages()
+    {
+        return [
+            'knowledge_category_ids.required' => '分类不能为空',
+            'knowledge_category_ids.array' => '分类格式有误'
+        ];
+    }
+}

+ 7 - 7
app/Http/Requests/Admin/TutorialSave.php → app/Http/Requests/Admin/KnowledgeSave.php

@@ -4,7 +4,7 @@ namespace App\Http\Requests\Admin;
 
 use Illuminate\Foundation\Http\FormRequest;
 
-class TutorialSave extends FormRequest
+class KnowledgeSave extends FormRequest
 {
     /**
      * Get the validation rules that apply to the request.
@@ -14,10 +14,10 @@ class TutorialSave extends FormRequest
     public function rules()
     {
         return [
+            'category' => 'required',
+            'language' => 'required',
             'title' => 'required',
-            // 1:windows 2:macos 3:ios 4:android 5:linux 6:router
-            'category_id' => 'required|in:1,2,3,4,5,6',
-            'steps' => 'required'
+            'body' => 'required'
         ];
     }
 
@@ -25,9 +25,9 @@ class TutorialSave extends FormRequest
     {
         return [
             'title.required' => '标题不能为空',
-            'category_id.required' => '分类不能为空',
-            'category_id.in' => '分类格式不正确',
-            'steps.required' => '教程步骤不能为空'
+            'category.required' => '分类不能为空',
+            'body.required' => '内容不能为空',
+            'language.required' => '语言不能为空'
         ];
     }
 }

+ 4 - 4
app/Http/Requests/Admin/TutorialSort.php → app/Http/Requests/Admin/KnowledgeSort.php

@@ -4,7 +4,7 @@ namespace App\Http\Requests\Admin;
 
 use Illuminate\Foundation\Http\FormRequest;
 
-class TutorialSort extends FormRequest
+class KnowledgeSort extends FormRequest
 {
     /**
      * Get the validation rules that apply to the request.
@@ -14,15 +14,15 @@ class TutorialSort extends FormRequest
     public function rules()
     {
         return [
-            'tutorial_ids' => 'required|array'
+            'knowledge_ids' => 'required|array'
         ];
     }
 
     public function messages()
     {
         return [
-            'tutorial_ids.required' => '教程ID不能为空',
-            'tutorial_ids.array' => '教程ID格式有误'
+            'knowledge_ids.required' => '知识ID不能为空',
+            'knowledge_ids.array' => '知识ID格式有误'
         ];
     }
 }

+ 7 - 6
app/Http/Routes/AdminRoute.php

@@ -86,12 +86,13 @@ class AdminRoute
             $router->get ('/coupon/fetch', 'Admin\\CouponController@fetch');
             $router->post('/coupon/save', 'Admin\\CouponController@save');
             $router->post('/coupon/drop', 'Admin\\CouponController@drop');
-            // Tutorial
-            $router->get ('/tutorial/fetch', 'Admin\\TutorialController@fetch');
-            $router->post('/tutorial/save', 'Admin\\TutorialController@save');
-            $router->post('/tutorial/show', 'Admin\\TutorialController@show');
-            $router->post('/tutorial/drop', 'Admin\\TutorialController@drop');
-            $router->post('/tutorial/sort', 'Admin\\TutorialController@sort');
+            // Knowledge
+            $router->get ('/knowledge/fetch', 'Admin\\KnowledgeController@fetch');
+            $router->get ('/knowledge/getCategory', 'Admin\\KnowledgeController@getCategory');
+            $router->post('/knowledge/save', 'Admin\\KnowledgeController@save');
+            $router->post('/knowledge/show', 'Admin\\KnowledgeController@show');
+            $router->post('/knowledge/drop', 'Admin\\KnowledgeController@drop');
+            $router->post('/knowledge/sort', 'Admin\\KnowledgeController@sort');
         });
     }
 }

+ 3 - 4
app/Http/Routes/UserRoute.php

@@ -34,10 +34,6 @@ class UserRoute
             $router->get ('/invite/save', 'User\\InviteController@save');
             $router->get ('/invite/fetch', 'User\\InviteController@fetch');
             $router->get ('/invite/details', 'User\\InviteController@details');
-            // Tutorial
-            $router->get ('/tutorial/getSubscribeUrl', 'User\\TutorialController@getSubscribeUrl');
-            $router->get ('/tutorial/getAppleID', 'User\\TutorialController@getAppleID');
-            $router->get ('/tutorial/fetch', 'User\\TutorialController@fetch');
             // Notice
             $router->get ('/notice/fetch', 'User\\NoticeController@fetch');
             // Ticket
@@ -55,6 +51,9 @@ class UserRoute
             $router->get ('/telegram/getBotInfo', 'User\\TelegramController@getBotInfo');
             // Comm
             $router->get ('/comm/config', 'User\\CommController@config');
+            // Knowledge
+            $router->get ('/knowledge/fetch', 'User\\KnowledgeController@fetch');
+            $router->get ('/knowledge/getCategory', 'User\\KnowledgeController@getCategory');
         });
     }
 }

+ 12 - 0
app/Models/Knowledge.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Knowledge extends Model
+{
+    protected $table = 'v2_knowledge';
+    protected $dateFormat = 'U';
+    protected $guarded = ['id'];
+}

+ 1 - 1
app/Services/OrderService.php

@@ -98,7 +98,7 @@ class OrderService
         } else if ($user->plan_id !== NULL && $order->plan_id !== $user->plan_id && ($user->expired_at > time() || $user->expired_at === NULL)) {
             if (!(int)config('v2board.plan_change_enable', 1)) abort(500, '目前不允许更改订阅,请联系客服或提交工单操作');
             $order->type = 3;
-            $this->getSurplusValue($user, $order);
+            if ((int)config('v2board.surplus_enable', 1)) $this->getSurplusValue($user, $order);
             if ($order->surplus_amount >= $order->total_amount) {
                 $order->refund_amount = $order->surplus_amount - $order->total_amount;
                 $order->total_amount = 0;

+ 16 - 15
database/install.sql

@@ -49,6 +49,21 @@ CREATE TABLE `v2_invite_code` (
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
+DROP TABLE IF EXISTS `v2_knowledge`;
+CREATE TABLE `v2_knowledge` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `language` char(5) NOT NULL COMMENT '語言',
+  `category` varchar(255) NOT NULL COMMENT '分類名',
+  `title` varchar(255) NOT NULL COMMENT '標題',
+  `body` text NOT NULL COMMENT '內容',
+  `sort` int(11) DEFAULT NULL COMMENT '排序',
+  `show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '顯示',
+  `created_at` int(11) NOT NULL COMMENT '創建時間',
+  `updated_at` int(11) NOT NULL COMMENT '更新時間',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知識庫';
+
+
 DROP TABLE IF EXISTS `v2_mail_log`;
 CREATE TABLE `v2_mail_log` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
@@ -257,20 +272,6 @@ CREATE TABLE `v2_ticket_message` (
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
-DROP TABLE IF EXISTS `v2_tutorial`;
-CREATE TABLE `v2_tutorial` (
-  `id` int(11) NOT NULL AUTO_INCREMENT,
-  `category_id` int(11) NOT NULL,
-  `title` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
-  `steps` text,
-  `show` tinyint(1) NOT NULL DEFAULT '0',
-  `sort` int(11) DEFAULT NULL,
-  `created_at` int(11) NOT NULL,
-  `updated_at` int(11) NOT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-
 DROP TABLE IF EXISTS `v2_user`;
 CREATE TABLE `v2_user` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
@@ -309,4 +310,4 @@ CREATE TABLE `v2_user` (
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
--- 2020-09-29 09:05:00
+-- 2020-10-17 18:49:28

+ 12 - 0
database/update.sql

@@ -327,3 +327,15 @@ CREATE TABLE `v2_server_shadowsocks` (
 
 ALTER TABLE `v2_coupon`
 CHANGE `code` `code` varchar(255) COLLATE 'utf8_general_ci' NOT NULL AFTER `id`;
+
+CREATE TABLE `v2_knowledge` (
+  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  `language` char(5) NOT NULL COMMENT '語言',
+  `category` varchar(255) NOT NULL COMMENT '分類名',
+  `title` varchar(255) NOT NULL COMMENT '標題',
+  `body` text NOT NULL COMMENT '內容',
+  `sort` int(11) NULL COMMENT '排序',
+  `show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '顯示',
+  `created_at` int(11) NOT NULL COMMENT '創建時間',
+  `updated_at` int(11) NOT NULL COMMENT '更新時間'
+) COMMENT='知識庫' COLLATE 'utf8mb4_general_ci';