EricYH Huang пре 3 година
родитељ
комит
0ea11719b0
100 измењених фајлова са 20483 додато и 0 уклоњено
  1. 19
    0
      .env
  2. 3
    0
      .gitattributes
  3. 9
    0
      .gitignore
  4. 26
    0
      app/Console/Commands/Lion.php
  5. 54
    0
      app/Console/Commands/QRGen.php
  6. 26
    0
      app/Console/Commands/Xml.php
  7. 43
    0
      app/Console/Kernel.php
  8. 65
    0
      app/Exceptions/Handler.php
  9. 70
    0
      app/FunMenu.php
  10. 15
    0
      app/FunMenuDetail.php
  11. 201
    0
      app/FunUserGroups.php
  12. 10
    0
      app/Functions.php
  13. 173
    0
      app/Http/Controllers/Api/GeneralInnerServiceController.php
  14. 32
    0
      app/Http/Controllers/Auth/ForgotPasswordController.php
  15. 39
    0
      app/Http/Controllers/Auth/LoginController.php
  16. 71
    0
      app/Http/Controllers/Auth/RegisterController.php
  17. 39
    0
      app/Http/Controllers/Auth/ResetPasswordController.php
  18. 202
    0
      app/Http/Controllers/Backend/DataManagement/UrlManagementController.php
  19. 533
    0
      app/Http/Controllers/Backend/EcManagement/ProductManagementController.php
  20. 105
    0
      app/Http/Controllers/Backend/FunmenusController.php
  21. 108
    0
      app/Http/Controllers/Backend/FunmenusDetailController.php
  22. 17
    0
      app/Http/Controllers/Backend/IndexController.php
  23. 35
    0
      app/Http/Controllers/Backend/PasswordController.php
  24. 118
    0
      app/Http/Controllers/Backend/UsergroupsController.php
  25. 76
    0
      app/Http/Controllers/Backend/UsersController.php
  26. 116
    0
      app/Http/Controllers/Backend/ZooManagement/TigerManagementController.php
  27. 13
    0
      app/Http/Controllers/Controller.php
  28. 28
    0
      app/Http/Controllers/HomeController.php
  29. 60
    0
      app/Http/Kernel.php
  30. 17
    0
      app/Http/Middleware/EncryptCookies.php
  31. 26
    0
      app/Http/Middleware/RedirectIfAuthenticated.php
  32. 18
    0
      app/Http/Middleware/TrimStrings.php
  33. 23
    0
      app/Http/Middleware/TrustProxies.php
  34. 18
    0
      app/Http/Middleware/VerifyCsrfToken.php
  35. 20
    0
      app/Http/Services/Api/GeneralInnerServiceService.php
  36. 303
    0
      app/Http/Services/Backend/DataManagement/UrlManagementService.php
  37. 295
    0
      app/Http/Services/Backend/EcManagement/ProductManagementService.php
  38. 108
    0
      app/Http/Services/Backend/ZooManagement/TigerManagementService.php
  39. 57
    0
      app/Http/Services/CheckParamService.php
  40. 31
    0
      app/Http/Services/ConstDef/GeneralConst.php
  41. 35
    0
      app/Http/ViewComposers/LeftMenuComposer.php
  42. 13
    0
      app/Models/DataManagement/UrlManagement.php
  43. 13
    0
      app/Models/DataManagement/UrlManagementVisit.php
  44. 13
    0
      app/Models/EcManagement/ProductManagement.php
  45. 13
    0
      app/Models/ZooManagement/TigerManagement.php
  46. 30
    0
      app/Providers/AppServiceProvider.php
  47. 30
    0
      app/Providers/AuthServiceProvider.php
  48. 21
    0
      app/Providers/BroadcastServiceProvider.php
  49. 34
    0
      app/Providers/ComposerServiceProvider.php
  50. 32
    0
      app/Providers/EventServiceProvider.php
  51. 73
    0
      app/Providers/RouteServiceProvider.php
  52. 32
    0
      app/User.php
  53. 51
    0
      artisan
  54. 64
    0
      bootstrap/app.php
  55. 17
    0
      bootstrap/autoload.php
  56. 2
    0
      bootstrap/cache/.gitignore
  57. 62
    0
      composer.json
  58. 5016
    0
      composer.lock
  59. 235
    0
      config/app.php
  60. 102
    0
      config/auth.php
  61. 58
    0
      config/broadcasting.php
  62. 91
    0
      config/cache.php
  63. 108
    0
      config/database.php
  64. 68
    0
      config/filesystems.php
  65. 20
    0
      config/image.php
  66. 123
    0
      config/mail.php
  67. 85
    0
      config/queue.php
  68. 38
    0
      config/services.php
  69. 179
    0
      config/session.php
  70. 33
    0
      config/view.php
  71. 1
    0
      database/.gitignore
  72. 24
    0
      database/factories/ModelFactory.php
  73. 35
    0
      database/migrations/2014_10_12_000000_create_users_table.php
  74. 32
    0
      database/migrations/2014_10_12_100000_create_password_resets_table.php
  75. 35
    0
      database/migrations/2016_02_23_075631_create_functions_table.php
  76. 34
    0
      database/migrations/2016_02_23_080148_create_funmenu_table.php
  77. 35
    0
      database/migrations/2016_02_23_080344_create_funmenudetail_table.php
  78. 35
    0
      database/migrations/2016_02_23_080520_create_funusergroups_table.php
  79. 16
    0
      database/seeds/DatabaseSeeder.php
  80. 19
    0
      package.json
  81. 31
    0
      phpunit.xml
  82. 30
    0
      public/.htaccess
  83. 394
    0
      public/assets/css/animate.delay.css
  84. 1
    0
      public/assets/css/animate.min.css
  85. 5
    0
      public/assets/css/bootstrap-clockpicker.min.css
  86. 337
    0
      public/assets/css/bootstrap-datetimepicker.css
  87. 663
    0
      public/assets/css/bootstrap-editable.css
  88. 1310
    0
      public/assets/css/bootstrap-override.css
  89. 476
    0
      public/assets/css/bootstrap-theme.css
  90. 1
    0
      public/assets/css/bootstrap-theme.css.map
  91. 5
    0
      public/assets/css/bootstrap-theme.min.css
  92. 10
    0
      public/assets/css/bootstrap-timepicker.min.css
  93. 98
    0
      public/assets/css/bootstrap-wysihtml5.css
  94. 6585
    0
      public/assets/css/bootstrap.css
  95. 1
    0
      public/assets/css/bootstrap.css.map
  96. 5
    0
      public/assets/css/bootstrap.min.css
  97. 264
    0
      public/assets/css/codemirror/codemirror.css
  98. 13
    0
      public/assets/css/codemirror/index.html
  99. 75
    0
      public/assets/css/codemirror/theme/ambiance.css
  100. 0
    0
      public/assets/css/codemirror/theme/index.html

+ 19
- 0
.env Прегледај датотеку

@@ -0,0 +1,19 @@
1
+APP_ENV=dev                                                 # 本範例用在開發環境上所以指定為 dev ,但實際情況會用在預設的線上環境需要指定 pro
2
+APP_KEY=base64:MtT8zoZvIJxglLOMY75wXScbK3rRcxPMHYQoiIvaGRQ= # 在下過 php artisan key:generate 指令後,此行會更新,需要同步到所有相關設定檔
3
+APP_DEBUG=true                                              # dev 環境建議開啟,pro 環境建議關閉
4
+APP_LOG_LEVEL=debug                                         # dev 環境建議指定 debug ,pro 環境建議指定 info
5
+APP_URL=http://ringeProject.ogilvy.com.tw                   # 建議使用 xxx.ogilvy.com.tw 的命名方式(另有教學會指定讓該網址生效),避免開發環境太多臨時專案都用 localhost 產生衝突
6
+APP_NAME=ringeProject                                       # 可填寫程式資料夾的名字,不會被網頁的任何地方顯示
7
+ORL_URL=https://xx.tw/                                      # 短網址代表號
8
+
9
+DB_CONNECTION=mysql                                         # 此行基本上不需要改,用 mysql/maria 都適用
10
+DB_HOST=127.0.0.1                                           # 若按照教學進行則可指定本機,不然可視當前環境另外指定
11
+DB_PORT=3307                                                # mysql 預設的 port 可不用修改
12
+DB_DATABASE=ringeProject                                    # 指定連接的資料庫名稱,可視環境修改
13
+DB_USERNAME=ringeProject                                    # mysql 帳號
14
+DB_PASSWORD=ringeProject                                    # mysql 密碼
15
+
16
+BROADCAST_DRIVER=log                                        # 不需修改或視情況修改
17
+CACHE_DRIVER=file                                           # 不需修改或視情況修改
18
+SESSION_DRIVER=file                                         # 不需修改或視情況修改
19
+QUEUE_DRIVER=sync                                           # 不需修改或視情況修改

+ 3
- 0
.gitattributes Прегледај датотеку

@@ -0,0 +1,3 @@
1
+* text=auto
2
+*.css linguist-vendored
3
+*.scss linguist-vendored

+ 9
- 0
.gitignore Прегледај датотеку

@@ -0,0 +1,9 @@
1
+/node_modules
2
+/public/storage
3
+/public/hot
4
+/storage/*.key
5
+/vendor
6
+/.idea
7
+Homestead.json
8
+Homestead.yaml
9
+.env.*

+ 26
- 0
app/Console/Commands/Lion.php Прегледај датотеку

@@ -0,0 +1,26 @@
1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use Illuminate\Console\Command;
6
+
7
+class Lion extends Command
8
+{
9
+    
10
+    protected $signature   = 'zoo:lion';
11
+    protected $description = 'lion eat tiger';
12
+    
13
+    public function __construct()
14
+    {
15
+        parent::__construct();
16
+    }
17
+    
18
+    /**
19
+     * 脚本入口
20
+     */
21
+    public function handle()
22
+    {
23
+        echo "I am Lion\n";
24
+    }
25
+    
26
+}

+ 54
- 0
app/Console/Commands/QRGen.php Прегледај датотеку

@@ -0,0 +1,54 @@
1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use App\Http\Services\ConstDef\GeneralConst;
6
+use chillerlan\QRCode\QRCode;
7
+use chillerlan\QRCode\QROptions;
8
+use Illuminate\Console\Command;
9
+
10
+class QRGen extends Command
11
+{
12
+    
13
+    protected $signature   = 'qr:gen {--src= : csv path} {--dst= : folder path}';
14
+    protected $description = 'batch generate qrcode';
15
+    
16
+    public function __construct()
17
+    {
18
+        parent::__construct();
19
+    }
20
+    
21
+    /**
22
+     * 脚本入口
23
+     */
24
+    public function handle()
25
+    {
26
+        $src = $this->option('src');
27
+        $dst = $this->option('dst');
28
+        $cnt = [];
29
+        if (($handle = fopen($src, "r")) !== false) {
30
+            while (($data = fgetcsv($handle, 2000, ",")) !== false) {
31
+                // 變數整理
32
+                $folder_name = $data[0] ?? '未命名';
33
+                $url = $data[1] ?? 'https://www.google.com';
34
+                $path = $dst . '/' . $folder_name;
35
+                // 創建資料夾
36
+                if (!file_exists($path)) mkdir($path, 0777, true);
37
+                // 檔名生成
38
+                $cnt[ $folder_name ] = (!isset($cnt[ $folder_name ])) ? 1 : $cnt[ $folder_name ] + 1;
39
+                $file_name = $folder_name . str_pad($cnt[ $folder_name ], 6, '0', STR_PAD_LEFT) . '.png';
40
+                // QRCODE 檔案生成
41
+                $options = new QROptions([
42
+                    'version'     => 5,
43
+                    'outputType'  => QRCode::OUTPUT_IMAGE_PNG,
44
+                    'imageBase64' => false,
45
+                ]);
46
+                $myfile = fopen($path . '/' . $file_name, "w");
47
+                fwrite($myfile, (new QRCode($options))->render($url));
48
+                fclose($myfile);
49
+            }
50
+            fclose($handle);
51
+        }
52
+    }
53
+    
54
+}

+ 26
- 0
app/Console/Commands/Xml.php Прегледај датотеку

@@ -0,0 +1,26 @@
1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use App\Http\Controllers\Backend\EcManagement\ProductManagementController;
6
+use Illuminate\Console\Command;
7
+
8
+class Xml extends Command
9
+{
10
+    
11
+    protected $signature   = 'ec:xml';
12
+    protected $description = 'xml generation';
13
+    
14
+    public function __construct()
15
+    {
16
+        parent::__construct();
17
+    }
18
+    
19
+    /**
20
+     * 脚本入口
21
+     */
22
+    public function handle()
23
+    {
24
+    }
25
+    
26
+}

+ 43
- 0
app/Console/Kernel.php Прегледај датотеку

@@ -0,0 +1,43 @@
1
+<?php
2
+
3
+namespace App\Console;
4
+
5
+use Illuminate\Console\Scheduling\Schedule;
6
+use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
7
+use App\Http\Controllers\Backend\EcManagement\ProductManagementController;
8
+use Redis;
9
+
10
+class Kernel extends ConsoleKernel
11
+{
12
+    /**
13
+     * The Artisan commands provided by your application.
14
+     *
15
+     * @var array
16
+     */
17
+    protected $commands = [
18
+        // 腳本入口
19
+        Commands\Lion::class,
20
+        Commands\QRGen::class,
21
+    ];
22
+    
23
+    /**
24
+     * Define the application's command schedule.
25
+     *
26
+     * @param \Illuminate\Console\Scheduling\Schedule $schedule
27
+     *
28
+     * @return void
29
+     */
30
+    protected function schedule(Schedule $schedule)
31
+    {
32
+    }
33
+    
34
+    /**
35
+     * Register the Closure based commands for the application.
36
+     *
37
+     * @return void
38
+     */
39
+    protected function commands()
40
+    {
41
+        require base_path('routes/console.php');
42
+    }
43
+}

+ 65
- 0
app/Exceptions/Handler.php Прегледај датотеку

@@ -0,0 +1,65 @@
1
+<?php
2
+
3
+namespace App\Exceptions;
4
+
5
+use Exception;
6
+use Illuminate\Auth\AuthenticationException;
7
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
8
+
9
+class Handler extends ExceptionHandler
10
+{
11
+    /**
12
+     * A list of the exception types that should not be reported.
13
+     *
14
+     * @var array
15
+     */
16
+    protected $dontReport = [
17
+        \Illuminate\Auth\AuthenticationException::class,
18
+        \Illuminate\Auth\Access\AuthorizationException::class,
19
+        \Symfony\Component\HttpKernel\Exception\HttpException::class,
20
+        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
21
+        \Illuminate\Session\TokenMismatchException::class,
22
+        \Illuminate\Validation\ValidationException::class,
23
+    ];
24
+
25
+    /**
26
+     * Report or log an exception.
27
+     *
28
+     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
29
+     *
30
+     * @param  \Exception  $exception
31
+     * @return void
32
+     */
33
+    public function report(Exception $exception)
34
+    {
35
+        parent::report($exception);
36
+    }
37
+
38
+    /**
39
+     * Render an exception into an HTTP response.
40
+     *
41
+     * @param  \Illuminate\Http\Request  $request
42
+     * @param  \Exception  $exception
43
+     * @return \Illuminate\Http\Response
44
+     */
45
+    public function render($request, Exception $exception)
46
+    {
47
+        return parent::render($request, $exception);
48
+    }
49
+
50
+    /**
51
+     * Convert an authentication exception into an unauthenticated response.
52
+     *
53
+     * @param  \Illuminate\Http\Request  $request
54
+     * @param  \Illuminate\Auth\AuthenticationException  $exception
55
+     * @return \Illuminate\Http\Response
56
+     */
57
+    protected function unauthenticated($request, AuthenticationException $exception)
58
+    {
59
+        if ($request->expectsJson()) {
60
+            return response()->json(['error' => 'Unauthenticated.'], 401);
61
+        }
62
+
63
+        return redirect()->guest(route('login'));
64
+    }
65
+}

+ 70
- 0
app/FunMenu.php Прегледај датотеку

@@ -0,0 +1,70 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use App\User;
6
+use Illuminate\Database\Eloquent\Model;
7
+use DB;
8
+
9
+class FunMenu extends Model
10
+{
11
+    protected $table = 'funmenu';
12
+
13
+    public function leftmenu($user_id)
14
+    {
15
+        $sql = "
16
+				SELECT
17
+                    `icon` as `icon`,
18
+					`MenuName` as `menuname`,
19
+					GROUP_CONCAT(`FunName` ORDER BY `FunMenuDetailCOrder` SEPARATOR ',') AS `submenuname`,
20
+					GROUP_CONCAT(`FunLink` ORDER BY `FunMenuDetailCOrder` SEPARATOR ',') AS `submenulink`
21
+				FROM
22
+					(
23
+						SELECT
24
+							*
25
+						FROM
26
+							`v_leftmenu`
27
+						WHERE
28
+							`FunId` IN (
29
+								SELECT
30
+									`Id`
31
+								FROM
32
+									`functions` AS `Functions_1`
33
+								WHERE
34
+									INSTR(
35
+										CONCAT(
36
+											',',
37
+											(
38
+												SELECT
39
+													GROUP_CONCAT(`FunList` SEPARATOR '') AS `submenuname`
40
+												FROM
41
+													`funusergroups`
42
+												WHERE
43
+													    CONCAT(',', `UsrList`, ',') LIKE CONCAT('%,', '".$user_id."', ',%')
44
+													AND `Valid` = 1
45
+												GROUP BY
46
+													`Valid`
47
+											),
48
+											','
49
+										),
50
+										CONCAT(
51
+											',',
52
+											`Id`,
53
+											','
54
+										)
55
+									) > 0
56
+							)
57
+					) A
58
+				GROUP BY
59
+					`menuname`
60
+				ORDER BY
61
+					`FunMenuCorder`
62
+				LIMIT
63
+					0, 30
64
+				;
65
+			";
66
+
67
+        $result = DB::select($sql);
68
+        return $result;
69
+    }
70
+}

+ 15
- 0
app/FunMenuDetail.php Прегледај датотеку

@@ -0,0 +1,15 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class FunMenuDetail extends Model
8
+{
9
+    protected $table = 'funmenudetail';
10
+
11
+    public function getFunctions()
12
+    {
13
+        return $this->hasMany('App\Functions');
14
+    }
15
+}

+ 201
- 0
app/FunUserGroups.php Прегледај датотеку

@@ -0,0 +1,201 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+use DB;
7
+
8
+class FunUserGroups extends Model
9
+{
10
+    protected $table = 'funusergroups';
11
+    
12
+    public function selectedUsrList($id)
13
+    {
14
+        $sql = "
15
+				SELECT 
16
+					* 
17
+				FROM 
18
+					`users`
19
+				WHERE 
20
+					`id` IN (
21
+						SELECT 
22
+							`id` 
23
+						FROM 
24
+							`users` 
25
+						AS 
26
+							`Funusers_1`
27
+						WHERE 
28
+							INSTR(
29
+								CONCAT(
30
+									',', 
31
+									(
32
+										SELECT 
33
+											`UsrList` 
34
+										FROM 
35
+											`funusergroups` 
36
+										WHERE 
37
+											`id`=".$id."
38
+									), 
39
+									','
40
+								), 
41
+								CONCAT(
42
+									',', 
43
+									`id`, 
44
+									',' 
45
+								)
46
+							) > 0 
47
+					)
48
+				;
49
+			";
50
+        $result = DB::select($sql);
51
+        return $result;
52
+    }
53
+    
54
+    public function unseletedUsrList($id)
55
+    {
56
+        $sql = "
57
+				SELECT 
58
+					* 
59
+				FROM 
60
+					`users`
61
+				WHERE 
62
+					`id` Not IN (
63
+						SELECT 
64
+							`id` 
65
+						FROM 
66
+							`users` 
67
+						AS 
68
+							`Funusers_1`
69
+						WHERE 
70
+							INSTR(
71
+								CONCAT(
72
+									',', 
73
+									(
74
+										SELECT 
75
+											`UsrList` 
76
+										FROM 
77
+											`funusergroups` 
78
+										WHERE 
79
+											`id`=".$id."
80
+									), 
81
+									','
82
+								), 
83
+								CONCAT(
84
+									',', 
85
+									`id`, 
86
+									','
87
+								)
88
+							) > 0 
89
+					)
90
+				;
91
+			";
92
+        $result = DB::select($sql);
93
+        return $result;
94
+    }
95
+    
96
+    public function unseletedFunList($id)
97
+    {
98
+        $sql = "
99
+				SELECT 
100
+					* 
101
+				FROM 
102
+					`functions`
103
+				WHERE 
104
+					`id` Not IN (
105
+						SELECT 
106
+							`id` 
107
+						FROM 
108
+							`functions` 
109
+						AS 
110
+							`Functions_1`
111
+						WHERE 
112
+							INSTR(
113
+								CONCAT(
114
+									',', 
115
+									(
116
+										SELECT 
117
+											`FunList` 
118
+										FROM 
119
+											`funusergroups` 
120
+										WHERE 
121
+											`id`=".$id."
122
+									), 
123
+									','
124
+								), 
125
+								CONCAT(
126
+									',', 
127
+									`id`, 
128
+									','
129
+								)
130
+							) > 0 
131
+					)
132
+				;
133
+			";
134
+        $result = DB::select($sql);
135
+        return $result;
136
+    }
137
+    
138
+    public function seletedFunList($id)
139
+    {
140
+        $sql = "
141
+				SELECT 
142
+					* 
143
+				FROM 
144
+					`functions`
145
+				WHERE 
146
+					`id` IN (
147
+						SELECT 
148
+							`id` 
149
+						FROM 
150
+							`functions` 
151
+						AS 
152
+							`Functions_1`
153
+						WHERE 
154
+							INSTR(
155
+								CONCAT(
156
+									',', 
157
+									(
158
+										SELECT 
159
+											`FunList` 
160
+										FROM 
161
+											`funusergroups` 
162
+										WHERE 
163
+											`id`=".$id."
164
+										-- ;
165
+									), 
166
+									','
167
+								), 
168
+								CONCAT(
169
+									',', 
170
+									`id`, 
171
+									',' 
172
+								)
173
+							) > 0 
174
+					)
175
+				;
176
+			";
177
+        $result = DB::select($sql);
178
+        return $result;
179
+    }
180
+    
181
+    public function operData($id)
182
+    {
183
+        $sql = "
184
+			SELECT
185
+				`id`,
186
+				`Name`,
187
+				`Valid`,
188
+				`created_at`,
189
+				`updated_at`,
190
+				
191
+                `Oid`
192
+			FROM
193
+				`funusergroups`
194
+			WHERE
195
+				`id`='".$id."'
196
+			;
197
+		";
198
+        $result = DB::select($sql);
199
+        return $result;
200
+    }
201
+}

+ 10
- 0
app/Functions.php Прегледај датотеку

@@ -0,0 +1,10 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class Functions extends Model
8
+{
9
+    protected $table = 'functions';
10
+}

+ 173
- 0
app/Http/Controllers/Api/GeneralInnerServiceController.php Прегледај датотеку

@@ -0,0 +1,173 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Api;
4
+
5
+use chillerlan\QRCode\QRCode;
6
+use chillerlan\QRCode\QROptions;
7
+use Illuminate\Http\Request;
8
+use App\Http\Services\Api\GeneralInnerServiceService;
9
+use App\Http\Services\Backend\DataManagement\UrlManagementService;
10
+use App\Http\Controllers\Controller;
11
+use App\Http\Services\ConstDef\GeneralConst;
12
+use App\Http\Services\CheckParamService;
13
+
14
+class GeneralInnerServiceController extends Controller
15
+{
16
+    
17
+    private $apicode;
18
+    private $oid;
19
+    private $generalInnerServiceSv;
20
+    private $urlManagementSv;
21
+    private $checkParamSv;
22
+    
23
+    public function __construct(Request $request)
24
+    {
25
+        $this->generalInnerServiceSv = new GeneralInnerServiceService();
26
+        $this->urlManagementSv = new UrlManagementService();
27
+        $this->checkParamSv = new CheckParamService();
28
+        // 鑒權
29
+        $this->oid = $this->generalInnerServiceSv->validate($request->header('userToken'));
30
+        $this->apicode = ($this->oid == 0) ? GeneralConst::API_TOKEN_ERR : GeneralConst::API_OK;
31
+    }
32
+    
33
+    public function store(Request $request)
34
+    {
35
+        // 鑒權
36
+        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
37
+        // 參數設置
38
+        $urlid = '';
39
+        $mode = $request->mode;
40
+        $id = ($request->mode == 'insert') ? '' : $request->serno; // 只有更新用的到
41
+        $title = $request->title;
42
+        $url = ($request->mode == 'insert') ? $request->url : ''; // 只有新增用的到
43
+        $memo = $request->memo;
44
+        $valid = GeneralConst::URL_OK; // 預設都可用
45
+        // 參數驗證
46
+        if (!in_array($mode, ['insert', 'update'])) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
47
+        if ($mode == 'update') {
48
+            if (!$this->checkParamSv->isnum($id)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
49
+        }
50
+        if ($title != filter_var($title, FILTER_SANITIZE_SPECIAL_CHARS)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
51
+        if (!$this->checkParamSv->LenMToN($title, 1, 20)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
52
+        if ($mode == 'insert') {
53
+            if (filter_var($url, FILTER_VALIDATE_URL) === false) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
54
+            if (!$this->checkParamSv->LenMToN($url, 1, 1024)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
55
+        }
56
+        if ($memo != filter_var($memo, FILTER_SANITIZE_SPECIAL_CHARS)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
57
+        if (!$this->checkParamSv->LenMToN($memo, 0, 20)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
58
+        // 服務層
59
+        if ($mode == "insert") {
60
+            \Log::info('start getCode');
61
+            $code = $this->urlManagementSv->getCode();
62
+            \Log::info($code);
63
+            // 新增模式
64
+            $urlid = $this->urlManagementSv->insertUrl($title, $url, $code, $memo, $valid, $this->oid);
65
+        } else {
66
+            // 編輯模式
67
+            $this->urlManagementSv->modifyUrl($id, $title, $url, $memo, $valid);
68
+        }
69
+        
70
+        // 返回
71
+        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $urlid], JSON_NUMERIC_CHECK), true);
72
+    }
73
+    
74
+    public function fetch(Request $request)
75
+    {
76
+        // 鑒權
77
+        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
78
+        // 服務層
79
+        $recordsTotal = 0;
80
+        $result = $this->urlManagementSv->getUrls(
81
+            $recordsTotal,
82
+            1,
83
+            'asc',
84
+            0,
85
+            1048576, // 由於不分頁,內部單一用戶或事業體不可能用到百萬等級,所以不想額外做功能
86
+            '',
87
+            '',
88
+            '',
89
+            "1900-01-01",
90
+            "2050-12-31",
91
+            GeneralConst::URL_OK, // 只有返回有效的
92
+            $this->oid
93
+        );
94
+        // 整理返回資料
95
+        $data = array();
96
+        for ($i = 0; $i < count($result); $i++) {
97
+            $data[] = [
98
+                'id'     => $result[ $i ]["serno"],
99
+                'code'   => $result[ $i ]["api_code"],
100
+                'url'    => env('ORL_URL') . $result[ $i ]["api_code"],
101
+                'pv'     => $result[ $i ]["pv"],
102
+                'qrcode' => $result[ $i ]["api_qrcode"],
103
+            ];
104
+        }
105
+        
106
+        
107
+        // 返回
108
+        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $data], JSON_NUMERIC_CHECK), true);
109
+    }
110
+
111
+    public function fetchById(Request $request)
112
+    {
113
+        // 鑒權
114
+        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
115
+        // 服務層
116
+        $orlId = $request->input('orlId');
117
+        $result = $this->urlManagementSv->getUrlById($orlId, $this->oid);
118
+        // 整理返回資料
119
+        $data = [];
120
+        if (!empty($result)) {
121
+            $data = [
122
+                'id'      => $result["serno"],
123
+                'url'     => $result["code"],
124
+                'origUrl' => $result["url"],
125
+                'title'   => $result["title"],
126
+            ];
127
+        }
128
+
129
+        // 返回
130
+        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $data], JSON_NUMERIC_CHECK), true);
131
+    }
132
+    
133
+    public function dateseg(Request $request)
134
+    {
135
+        // 鑒權
136
+        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
137
+        // 服務層
138
+        $result = $this->urlManagementSv->getDateseg($this->oid);
139
+        // 整理返回資料
140
+        $data = array();
141
+        $tmp = '';
142
+        for ($i = 0; $i < count($result); $i++) {
143
+            if ($tmp != $result[ $i ]["code"]) {
144
+                $tmp = $result[ $i ]["code"];
145
+            }
146
+            $data[ $tmp ][] = [
147
+                'date' => $result[ $i ]["date"],
148
+                'cnt'  => $result[ $i ]["cnt"],
149
+            ];
150
+        }
151
+        
152
+        // 返回
153
+        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $data], JSON_NUMERIC_CHECK), true);
154
+    }
155
+    
156
+    public function qrcode($code)
157
+    {
158
+        header("Cache-Control: no-cache, must-revalidate");
159
+        header("Pragma: no-cache");
160
+        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
161
+        header('Content-Description: File Transfer');
162
+        header('Content-Disposition: attachment; filename="' . $code . '.png"');
163
+        header('Content-Transfer-Encoding: binary');
164
+        header('Content-type: image/png');
165
+        $options = new QROptions([
166
+            'version'     => 2,
167
+            'outputType'  => QRCode::OUTPUT_IMAGE_PNG,
168
+            'imageBase64' => false,
169
+        ]);
170
+        echo (new QRCode($options))->render(env('ORL_URL') . $code);
171
+    }
172
+    
173
+}

+ 32
- 0
app/Http/Controllers/Auth/ForgotPasswordController.php Прегледај датотеку

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
7
+
8
+class ForgotPasswordController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Password Reset Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller is responsible for handling password reset emails and
16
+    | includes a trait which assists in sending these notifications from
17
+    | your application to your users. Feel free to explore this trait.
18
+    |
19
+    */
20
+
21
+    use SendsPasswordResetEmails;
22
+
23
+    /**
24
+     * Create a new controller instance.
25
+     *
26
+     * @return void
27
+     */
28
+    public function __construct()
29
+    {
30
+        $this->middleware('guest');
31
+    }
32
+}

+ 39
- 0
app/Http/Controllers/Auth/LoginController.php Прегледај датотеку

@@ -0,0 +1,39 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\AuthenticatesUsers;
7
+
8
+class LoginController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Login Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller handles authenticating users for the application and
16
+    | redirecting them to your home screen. The controller uses a trait
17
+    | to conveniently provide its functionality to your applications.
18
+    |
19
+    */
20
+
21
+    use AuthenticatesUsers;
22
+
23
+    /**
24
+     * Where to redirect users after login.
25
+     *
26
+     * @var string
27
+     */
28
+    protected $redirectTo = '/backend';
29
+
30
+    /**
31
+     * Create a new controller instance.
32
+     *
33
+     * @return void
34
+     */
35
+    public function __construct()
36
+    {
37
+        $this->middleware('guest', ['except' => 'logout']);
38
+    }
39
+}

+ 71
- 0
app/Http/Controllers/Auth/RegisterController.php Прегледај датотеку

@@ -0,0 +1,71 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\User;
6
+use App\Http\Controllers\Controller;
7
+use Illuminate\Support\Facades\Validator;
8
+use Illuminate\Foundation\Auth\RegistersUsers;
9
+
10
+class RegisterController extends Controller
11
+{
12
+    /*
13
+    |--------------------------------------------------------------------------
14
+    | Register Controller
15
+    |--------------------------------------------------------------------------
16
+    |
17
+    | This controller handles the registration of new users as well as their
18
+    | validation and creation. By default this controller uses a trait to
19
+    | provide this functionality without requiring any additional code.
20
+    |
21
+    */
22
+
23
+    use RegistersUsers;
24
+
25
+    /**
26
+     * Where to redirect users after registration.
27
+     *
28
+     * @var string
29
+     */
30
+    protected $redirectTo = '/backend';
31
+
32
+    /**
33
+     * Create a new controller instance.
34
+     *
35
+     * @return void
36
+     */
37
+    public function __construct()
38
+    {
39
+        $this->middleware('guest');
40
+    }
41
+
42
+    /**
43
+     * Get a validator for an incoming registration request.
44
+     *
45
+     * @param  array  $data
46
+     * @return \Illuminate\Contracts\Validation\Validator
47
+     */
48
+    protected function validator(array $data)
49
+    {
50
+        return Validator::make($data, [
51
+            'name' => 'required|max:255',
52
+            'email' => 'required|email|max:255|unique:users',
53
+            'password' => 'required|min:6|confirmed',
54
+        ]);
55
+    }
56
+
57
+    /**
58
+     * Create a new user instance after a valid registration.
59
+     *
60
+     * @param  array  $data
61
+     * @return User
62
+     */
63
+    protected function create(array $data)
64
+    {
65
+        return User::create([
66
+            'name' => $data['name'],
67
+            'email' => $data['email'],
68
+            'password' => bcrypt($data['password']),
69
+        ]);
70
+    }
71
+}

+ 39
- 0
app/Http/Controllers/Auth/ResetPasswordController.php Прегледај датотеку

@@ -0,0 +1,39 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\ResetsPasswords;
7
+
8
+class ResetPasswordController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Password Reset Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller is responsible for handling password reset requests
16
+    | and uses a simple trait to include this behavior. You're free to
17
+    | explore this trait and override any methods you wish to tweak.
18
+    |
19
+    */
20
+
21
+    use ResetsPasswords;
22
+
23
+    /**
24
+     * Where to redirect users after resetting their password.
25
+     *
26
+     * @var string
27
+     */
28
+    protected $redirectTo = '/backend';
29
+
30
+    /**
31
+     * Create a new controller instance.
32
+     *
33
+     * @return void
34
+     */
35
+    public function __construct()
36
+    {
37
+        $this->middleware('guest');
38
+    }
39
+}

+ 202
- 0
app/Http/Controllers/Backend/DataManagement/UrlManagementController.php Прегледај датотеку

@@ -0,0 +1,202 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend\DataManagement;
4
+
5
+use App\Http\Services\CheckParamService;
6
+use Illuminate\Http\Request;
7
+use App\Http\Services\Backend\DataManagement\UrlManagementService;
8
+use App\Http\Controllers\Controller;
9
+use App\Http\Services\ConstDef\GeneralConst;
10
+use chillerlan\QRCode\QRCode;
11
+use chillerlan\QRCode\QROptions;
12
+
13
+class UrlManagementController extends Controller
14
+{
15
+    
16
+    // 相關私有服務層調用器宣告
17
+    private $urlManagementSv;
18
+    private $checkParamSv;
19
+    
20
+    public function __construct()
21
+    {
22
+        // 建構服務層調用器
23
+        $this->urlManagementSv = new UrlManagementService();
24
+        $this->checkParamSv = new CheckParamService();
25
+        // 時區調整
26
+        date_default_timezone_set("Asia/Taipei");
27
+    }
28
+    
29
+    public function index(Request $request)
30
+    {
31
+        // 渲染
32
+        return view('admin.DataManagement.UrlManagement', [
33
+            'titles' => $this->urlManagementSv->getTitles($request->user()->id),
34
+            'valids' => $this->urlManagementSv->getValids(),
35
+        ]);
36
+    }
37
+    
38
+    public function grid(Request $request)
39
+    {
40
+        // 取得參數
41
+        $param = $_GET;
42
+        if ($param == null) exit();
43
+        $draw = $param["draw"]; //客戶端傳來的查詢次數,無條件回傳用以核對
44
+        $orderColumn = $param["order"][0]["column"] + 1; //前端從 0 開始送,但 mysql 從 1 開始算
45
+        $orderDir = $param["order"][0]["dir"];
46
+        $start = $param["start"];   // 頁碼
47
+        $length = $param["length"]; // 一頁多大
48
+        $searchValue = $param["search"]["value"];
49
+        //客製化搜尋欄位
50
+        $title = $param["columns"][1]["search"]["value"];
51
+        $memo = $param["columns"][2]["search"]["value"];
52
+        $createDate = explode("\n", $param["columns"][3]["search"]["value"]);
53
+        $createDateStart = $createDate[0] ?? null;
54
+        $createDateFinal = $createDate[1] ?? null;
55
+        $valid = $param["columns"][4]["search"]["value"];
56
+        // 驗證
57
+        if ($title != filter_var($title, FILTER_SANITIZE_SPECIAL_CHARS)) $title = "___CANNOT_FIND_STRING___";
58
+        if (!$this->checkParamSv->LenMToN($title, 0, 20)) $title = "___CANNOT_FIND_STRING___";
59
+        if ($memo != filter_var($memo, FILTER_SANITIZE_SPECIAL_CHARS)) $memo = "___CANNOT_FIND_STRING___";
60
+        if (!$this->checkParamSv->LenMToN($memo, 0, 20)) $memo = "___CANNOT_FIND_STRING___";
61
+        if ($createDateStart == "") $createDateStart = "1900-01-01";
62
+        if ($createDateFinal == "") $createDateFinal = "2050-12-31";
63
+        if (!$this->checkParamSv->validateDate($createDateStart, 'Y-m-d')) $createDateStart = "1900-01-01";
64
+        if (!$this->checkParamSv->validateDate($createDateFinal, 'Y-m-d')) $createDateFinal = "2050-12-31";
65
+        if (!isset(GeneralConst::$urlMap[ $valid ])) $valid = GeneralConst::URL_OK;
66
+        //資料庫
67
+        $recordsTotal = 0;
68
+        $result = $this->urlManagementSv->getUrls(
69
+            $recordsTotal,
70
+            $orderColumn,
71
+            $orderDir,
72
+            $start,
73
+            $length,
74
+            $searchValue,
75
+            $title,
76
+            $memo,
77
+            $createDateStart,
78
+            $createDateFinal,
79
+            $valid,
80
+            $request->user()->id
81
+        );
82
+        // 整理返回資料
83
+        $data = array();
84
+        for ($i = 0; $i < count($result); $i++) {
85
+            $data[] = array(
86
+                //一般資料
87
+                $result[ $i ]["serno"],
88
+                $result[ $i ]["title"],
89
+                $result[ $i ]["url"],
90
+                $result[ $i ]["code"],
91
+                $result[ $i ]["memo"],
92
+                $result[ $i ]["pv"],
93
+                $result[ $i ]["valid"],
94
+                $result[ $i ]["edit"],
95
+                $result[ $i ]["qrcode"],
96
+            );
97
+        }
98
+        $json = array(
99
+            "draw"            => $draw,
100
+            "recordsTotal"    => $recordsTotal,
101
+            "recordsFiltered" => $recordsTotal, //其實還是填入所有筆數,本次筆數可從陣列取得
102
+            "data"            => $data,
103
+        );
104
+        
105
+        // 返回
106
+        return json_decode(json_encode($json, JSON_NUMERIC_CHECK), true);
107
+    }
108
+    
109
+    public function qrcode($code)
110
+    {
111
+        header("Cache-Control: no-cache, must-revalidate");
112
+        header("Pragma: no-cache");
113
+        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
114
+        header('Content-Description: File Transfer');
115
+        header('Content-Disposition: attachment; filename="' . $code . '.png"');
116
+        header('Content-Transfer-Encoding: binary');
117
+        header('Content-type: image/png');
118
+        $options = new QROptions([
119
+            'version'     => 2,
120
+            'outputType'  => QRCode::OUTPUT_IMAGE_PNG,
121
+            'imageBase64' => false,
122
+        ]);
123
+        echo (new QRCode($options))->render(env('ORL_URL') . $code);
124
+    }
125
+    
126
+    public function create(Request $request)
127
+    {
128
+        // 服務層取得資料(以及實現各種業務上的邏輯)
129
+        $titles = $this->urlManagementSv->getTitles($request->user()->id);
130
+        
131
+        // 渲染
132
+        return view('admin.DataManagement.UrlManagementEdit', [
133
+            'titles'   => $titles,
134
+            'operdata' => "",
135
+        ]);
136
+    }
137
+    
138
+    public function edit($id, Request $request)
139
+    {
140
+        // 取得參數與驗證
141
+        // 服務層取得資料(以及實現各種業務上的邏輯)
142
+        $operdata = $this->urlManagementSv->getUrlById($id, $request->user()->id);
143
+        $titles = $this->urlManagementSv->getTitles($request->user()->id);
144
+        
145
+        // 渲染
146
+        return view('admin.DataManagement.UrlManagementEdit', [
147
+            'titles'   => $titles,
148
+            'operdata' => $operdata,
149
+        ]);
150
+    }
151
+    
152
+    public function store(Request $request)
153
+    {
154
+        // 取得參數與驗證
155
+        $mode = $request->mode;
156
+        $id = ($request->mode == 'insert') ? '' : $request->serno;
157
+        $title = $request->title;
158
+        $url = $request->url;
159
+        $memo = $request->memo;
160
+        $valid = ($request->valid == 'on') ? GeneralConst::URL_OK : GeneralConst::URL_NO;
161
+        // 服務層設置(以及實現各種業務上的邏輯)
162
+        if ($mode == "insert") {
163
+            $code = $this->urlManagementSv->getCode();
164
+            // 新增模式
165
+            $id = $this->urlManagementSv->insertUrl($title, $url, $code, $memo, $valid, $request->user()->id);
166
+        } else {
167
+            // 編輯模式
168
+            $this->urlManagementSv->modifyUrl($id, $title, $url, $memo, $valid);
169
+        }
170
+        
171
+        // 跳轉
172
+        return redirect('/backend/dataManagement/urlManagement');
173
+    }
174
+    
175
+    public function export(Request $request)
176
+    {
177
+        // 取得參數
178
+        $param = $_POST;
179
+        if ($param == null) exit();
180
+        // 驗證
181
+        if ($param['title'] != filter_var($param['title'], FILTER_SANITIZE_SPECIAL_CHARS)) $param['title'] = "___CANNOT_FIND_STRING___";
182
+        if (!$this->checkParamSv->LenMToN($param['title'], 0, 20)) $param['title'] = "___CANNOT_FIND_STRING___";
183
+        if ($param['memo'] != filter_var($param['memo'], FILTER_SANITIZE_SPECIAL_CHARS)) $param['memo'] = "___CANNOT_FIND_STRING___";
184
+        if (!$this->checkParamSv->LenMToN($param['memo'], 0, 20)) $param['memo'] = "___CANNOT_FIND_STRING___";
185
+        if ($param['createDateStart'] == "") $param['createDateStart'] = "1900-01-01";
186
+        if ($param['createDateFinal'] == "") $param['createDateFinal'] = "2050-12-31";
187
+        if (!$this->checkParamSv->validateDate($param['createDateStart'], 'Y-m-d')) $param['createDateStart'] = "1900-01-01";
188
+        if (!$this->checkParamSv->validateDate($param['createDateFinal'], 'Y-m-d')) $param['createDateFinal'] = "2050-12-31";
189
+        if (!isset(GeneralConst::$urlMap[ $param['valid'] ])) $param['valid'] = GeneralConst::URL_OK;
190
+        // 製作
191
+        $title = [
192
+            '網址',
193
+            '短網址',
194
+            '備註',
195
+            '有效否',
196
+            '造訪次',
197
+        ];
198
+        $urls = $this->urlManagementSv->getExportUrls($param, $request->user()->id);
199
+        $this->urlManagementSv->downloadExcel($title, $urls, date("YmdHis") . '-REPORT');
200
+    }
201
+    
202
+}

+ 533
- 0
app/Http/Controllers/Backend/EcManagement/ProductManagementController.php Прегледај датотеку

@@ -0,0 +1,533 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend\EcManagement;
4
+
5
+use App\Http\Services\CheckParamService;
6
+use Illuminate\Http\Request;
7
+use App\Http\Services\Backend\EcManagement\ProductManagementService;
8
+use App\Http\Controllers\Controller;
9
+use App\Http\Services\ConstDef\GeneralConst;
10
+use Redis;
11
+use Aws\S3\S3Client;
12
+
13
+class ProductManagementController extends Controller
14
+{
15
+    
16
+    // 相關私有服務層調用器宣告
17
+    private $productManagementSv;
18
+    private $checkParamSv;
19
+    private $s3Client;
20
+    
21
+    public function __construct()
22
+    {
23
+        // 建構服務層調用器
24
+        $this->productManagementSv = new ProductManagementService();
25
+        $this->checkParamSv = new CheckParamService();
26
+        $this->s3Client = new S3Client([
27
+            'credentials' => [
28
+                'key'    => env('AWS_S3_KEY'),
29
+                'secret' => env('AWS_S3_SECRET'),
30
+            ],
31
+            'region'      => env('AWS_S3_REGION'),
32
+            'version'     => 'latest',
33
+        ]);
34
+        // 時區調整
35
+        date_default_timezone_set("Asia/Taipei");
36
+    }
37
+    
38
+    /**
39
+     * 列表頁
40
+     *   本端點非 API,直接渲染到 view
41
+     * @return array:          返回渲染頁
42
+     */
43
+    public function index()
44
+    {
45
+        // 渲染
46
+        return view('admin.EcManagement.ProductManagement', [
47
+            'can_step_0' => (Redis::get('TLW_0_MAN') || Redis::get('TLW_0_STOP')) ? false : true,
48
+            'can_step_2' => (Redis::get('TLW_2_CSV')) ? false : true,
49
+            'step_2_s3'  => env("AWS_S3_BUCKET"),
50
+            'step_2_env' => env("APP_ENV"),
51
+            'brands'     => $this->productManagementSv->getBrands(),
52
+            'batchs'     => $this->productManagementSv->getBatchs(),
53
+            'mstatuss'   => $this->productManagementSv->getMStatuss(),
54
+        ]);
55
+    }
56
+    
57
+    /**
58
+     * 列表API
59
+     *   接收搜尋參數與分頁等信息,返回JSON
60
+     * @return string:         返回JSON
61
+     */
62
+    public function grid()
63
+    {
64
+        // 取得參數
65
+        $param = $_GET;
66
+        if ($param == null) exit();
67
+        $draw = $param["draw"]; //客戶端傳來的查詢次數,無條件回傳用以核對
68
+        $orderColumn = $param["order"][0]["column"] + 1; //前端從 0 開始送,但 mysql 從 1 開始算
69
+        $orderDir = $param["order"][0]["dir"];
70
+        $start = $param["start"];   // 頁碼
71
+        $length = $param["length"]; // 一頁多大
72
+        $searchValue = $param["search"]["value"];
73
+        //客製化搜尋欄位
74
+        $brand_no = $param["columns"][1]["search"]["value"];
75
+        $batch_no = $param["columns"][2]["search"]["value"];
76
+        $g_title = $param["columns"][3]["search"]["value"];
77
+        $g_description = $param["columns"][4]["search"]["value"];
78
+        $m_comment = $param["columns"][5]["search"]["value"];
79
+        $m_status = $param["columns"][6]["search"]["value"];
80
+        // 驗證
81
+        if ($g_title != filter_var($g_title, FILTER_SANITIZE_SPECIAL_CHARS)) $g_title = "___CANNOT_FIND_STRING___";
82
+        if (!$this->checkParamSv->LenMToN($g_title, 0, 50)) $g_title = "___CANNOT_FIND_STRING___";
83
+        if ($g_description != filter_var($g_description, FILTER_SANITIZE_SPECIAL_CHARS)) $g_description = "___CANNOT_FIND_STRING___";
84
+        if (!$this->checkParamSv->LenMToN($g_description, 0, 50)) $g_description = "___CANNOT_FIND_STRING___";
85
+        if ($m_comment != filter_var($m_comment, FILTER_SANITIZE_SPECIAL_CHARS)) $m_comment = "___CANNOT_FIND_STRING___";
86
+        if (!$this->checkParamSv->LenMToN($m_comment, 0, 50)) $m_comment = "___CANNOT_FIND_STRING___";
87
+        //資料庫
88
+        $recordsTotal = 0;
89
+        $result = $this->productManagementSv->getProdocts(
90
+            $recordsTotal,
91
+            $orderColumn,
92
+            $orderDir,
93
+            $start,
94
+            $length,
95
+            $searchValue,
96
+            $brand_no,
97
+            $batch_no,
98
+            $g_title,
99
+            $g_description,
100
+            $m_comment,
101
+            $m_status
102
+        );
103
+        // 整理返回資料
104
+        $data = array();
105
+        for ($i = 0; $i < count($result); $i++) {
106
+            $data[] = array(
107
+                //一般資料
108
+                $result[ $i ]["serno"],
109
+                $result[ $i ]["g_id"],
110
+                $result[ $i ]["g_title"],
111
+                $result[ $i ]["g_description"],
112
+                $result[ $i ]["g_image_link"],
113
+                $result[ $i ]["g_price"],
114
+                $result[ $i ]["g_sale_price"],
115
+                $result[ $i ]["m_status"],
116
+                $result[ $i ]["m_comment"],
117
+            );
118
+        }
119
+        $json = array(
120
+            "draw"            => $draw,
121
+            "recordsTotal"    => $recordsTotal,
122
+            "recordsFiltered" => $recordsTotal, //其實還是填入所有筆數,本次筆數可從陣列取得
123
+            "data"            => $data,
124
+        );
125
+        
126
+        // 返回
127
+        return json_decode(json_encode($json, JSON_NUMERIC_CHECK), true);
128
+    }
129
+    
130
+    public function manualXml()
131
+    {
132
+        Redis::set('TLW_0_MAN', 'true');
133
+        
134
+        return $this->manualXmlStatus();
135
+    }
136
+    
137
+    public function manualXmlStatus()
138
+    {
139
+        $json = [
140
+            'can_step_0' => (Redis::get('TLW_0_MAN') || Redis::get('TLW_0_STOP')) ? false : true,
141
+        ];
142
+        
143
+        return json_decode(json_encode($json, JSON_NUMERIC_CHECK), true);
144
+    }
145
+    
146
+    public function importCsv(Request $request)
147
+    {
148
+        // 上傳錯誤偵測(沒有包含檔案格式)
149
+        switch ($_FILES['csv']['error']) {
150
+            case UPLOAD_ERR_OK:
151
+                break;
152
+            case UPLOAD_ERR_NO_FILE:
153
+                return json_decode(json_encode(['code' => 0, 'err' => '檔案大小錯誤'], JSON_NUMERIC_CHECK), true);
154
+            case UPLOAD_ERR_INI_SIZE:
155
+            case UPLOAD_ERR_FORM_SIZE:
156
+                return json_decode(json_encode(['code' => 1, 'err' => '檔案太大'], JSON_NUMERIC_CHECK), true);
157
+            default:
158
+                return json_decode(json_encode(['code' => 1, 'err' => '系統錯誤'], JSON_NUMERIC_CHECK), true);
159
+        }
160
+        if ($_FILES['csv']['size'] > 100 * 1024 * 1024) {
161
+            return json_decode(json_encode(['code' => 1, 'err' => '檔案最大100MB'], JSON_NUMERIC_CHECK), true);
162
+        }
163
+        // 路徑命名
164
+        $path = '/tmp/tlwcsv/';
165
+        if (!file_exists($path)) mkdir($path, 0777, true);
166
+        chmod($path, 0777);
167
+        $date = date('Y-m-d');
168
+        if (!file_exists($path . 'tempImportCsv')) mkdir($path . 'tempImportCsv', 0777, true);
169
+        chmod($path . 'tempImportCsv', 0777);
170
+        if (!file_exists($path . 'tempImportCsv/' . $date)) mkdir($path . 'tempImportCsv/' . $date, 0777, true);
171
+        chmod($path . 'tempImportCsv/' . $date, 0777);
172
+        // 保存文件
173
+        $time = time();
174
+        move_uploaded_file($_FILES['csv']['tmp_name'], $path . 'tempImportCsv/' . $date . '/' . $time . '.csv');
175
+        chmod($path . 'tempImportCsv/' . $date . '/' . $time . '.csv', 0777);
176
+        // 異步處裡文件
177
+        Redis::set('TLW_2_CSV', $path . 'tempImportCsv/' . $date . '/' . $time . '.csv' . '|' . $_POST['brand_no'] . '|' . $_POST['batch_no']);
178
+        
179
+        return json_decode(json_encode($_FILES, JSON_NUMERIC_CHECK), true);
180
+    }
181
+    
182
+    public function importCsvStatus()
183
+    {
184
+        $json = [
185
+            'can_step_2' => (Redis::get('TLW_2_CSV') || Redis::get('TLW_2_MAN')) ? false : true,
186
+        ];
187
+        
188
+        return json_decode(json_encode($json, JSON_NUMERIC_CHECK), true);
189
+    }
190
+    
191
+    public function importCsvHandle($info)
192
+    {
193
+        // 上鎖
194
+        Redis::set('TLW_2_MAN', 'true');
195
+        // 剖析資訊
196
+        $info = explode('|', $info);
197
+        $csv = $info[0];
198
+        $brand_no = $info[1];
199
+        $batch_no = $info[2];
200
+        // 更新產品訊息
201
+        $fileR = fopen($csv, "r");
202
+        while (!feof($fileR)) {
203
+            $line = fgets($fileR);
204
+            $cell = str_getcsv($line, ',', '"');
205
+            if ($cell[0] != 'Item ID') {
206
+                $g_id = $cell[0];
207
+                $m_comment = $cell[4] ?? '';
208
+                $m_status = $cell[5] ?? '';
209
+                switch ($m_status) {
210
+                    case GeneralConst::$mStatusMap[ GeneralConst::MSTATUS_WARNING ]['BNAME']:
211
+                        $detail = $this->productManagementSv->getProductDetail($brand_no, $batch_no, $g_id);
212
+                        $comment = (strpos($detail['m_comment'], $m_comment . ' / ') !== false) ? $detail['m_comment'] : $detail['m_comment'] . $m_comment . ' / ';
213
+                        if ($detail['m_status'] == GeneralConst::MSTATUS_DISAPPROVED) {
214
+                            // 原本是錯誤,但目前讀取到警告,就依然要保持錯誤狀態
215
+                            $this->productManagementSv->updateProduct($brand_no, $batch_no, $g_id, GeneralConst::MSTATUS_DISAPPROVED, $comment);
216
+                        } else {
217
+                            // 原本是正常或警告,目前讀取到警告,就要將狀態設為警告
218
+                            $this->productManagementSv->updateProduct($brand_no, $batch_no, $g_id, GeneralConst::MSTATUS_WARNING, $comment);
219
+                        }
220
+                        break;
221
+                    case GeneralConst::$mStatusMap[ GeneralConst::MSTATUS_DISAPPROVED ]['BNAME']:
222
+                        $detail = $this->productManagementSv->getProductDetail($brand_no, $batch_no, $g_id);
223
+                        $comment = (strpos($detail['m_comment'], $m_comment . ' / ') !== false) ? $detail['m_comment'] : $detail['m_comment'] . $m_comment . ' / ';
224
+                        // 原本不管是甚麼,目前讀取到錯誤,就要將狀態設為錯誤
225
+                        $this->productManagementSv->updateProduct($brand_no, $batch_no, $g_id, GeneralConst::MSTATUS_DISAPPROVED, $comment);
226
+                        break;
227
+                }
228
+            }
229
+        }
230
+        fclose($fileR);
231
+        // 刪除檔案(權限問題無法刪除)
232
+        unlink($csv);
233
+    }
234
+    
235
+    public function manualEndpoint()
236
+    {
237
+        $param = $_GET;
238
+        Redis::set('TLW_4_MAN', $param['brand_no'] . '|' . $param['batch_no']);
239
+        
240
+        return $this->manualEndpointStatus();
241
+    }
242
+    
243
+    public function manualEndpointStatus()
244
+    {
245
+        $json = [
246
+            'can_step_4' => (Redis::get('TLW_4_MAN') || Redis::get('TLW_4_STOP')) ? false : true,
247
+        ];
248
+        
249
+        return json_decode(json_encode($json, JSON_NUMERIC_CHECK), true);
250
+    }
251
+    
252
+    public function exportCsv(Request $request)
253
+    {
254
+        $title = [
255
+            '系統號',
256
+            '商品號',
257
+            '品名',
258
+            '描述',
259
+            '網頁',
260
+            '圖片路徑',
261
+            '定價',
262
+            '售價',
263
+            '掃描結果',
264
+            '掃描問題',
265
+        ];
266
+        $products = $this->productManagementSv->getExportProdocts($request);
267
+        $this->productManagementSv->downloadExcel($title, $products, date("YmdHis") . '-REPORT-' . GeneralConst::$brandMap[ $request->brand_no ]['LB']);
268
+    }
269
+    
270
+    // XML轉換腳本
271
+    public function xml()
272
+    {
273
+        // 防重鎖
274
+        if (!Redis::get('TLW_0_XML')) {
275
+            Redis::set('TLW_0_XML', 'true');
276
+            Redis::expire('TLW_0_XML', 1200); // 20 分鐘
277
+            // 產生批次號
278
+            $batch_no = date("Y-m-d H:i:s");
279
+            $batch_no_digit = date("YmdHis");
280
+            // 產生刪除批次號
281
+            $del_batch_no = date('Y-m-d', strtotime(date("Y-m-d H:i:s") . "-14 days"));
282
+            $del_batch_no_digit = date('Ymd', strtotime(date("Y-m-d") . "-14 days"));
283
+            // 逐一品牌處理
284
+            foreach (GeneralConst::$brandMap as $k => $v) {
285
+                for ($i = 1; $i <= 14; $i++) {
286
+                }
287
+                // 載入品牌原始 XML
288
+                $original = simplexml_load_file($v['URL']);
289
+                // 開始寫入檔案
290
+                $path = '/tmp/tlw/' . env('APP_ENV') . '/' . $v['LB'] . '/';
291
+                if (!file_exists($path)) mkdir($path, 0777, true);
292
+                $fileW = fopen($path . $batch_no_digit . '.xml', "w");
293
+                fwrite($fileW, '<?xml version="1.0" encoding="UTF-8"?><rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"><channel><title>特力屋</title><link>' . $v['URL'] . '</link><description></description>' . "\n");
294
+                // 原始商品逐筆處裡(保留符號已被CDATA處理)
295
+                // 注意可能出現相同品牌之中有相同 g_id 的現象,但由於不影響資料流程所以不處理
296
+                $data = [];
297
+                foreach ($original->Product as $p) {
298
+                    // custom_label_1 為客戶系統自定義欄位,Y代表可讓GMC上架,N代表不可讓GM上架
299
+                    if ((string)$p->custom_label_1 == GeneralConst::PUBLISH_YES) {
300
+                        // XML
301
+                        fwrite($fileW, '<item>' . "\n");
302
+                        fwrite($fileW, '<g:id>' . (string)$p->SKU . '</g:id>' . "\n");
303
+                        fwrite($fileW, '<g:title><![CDATA[' . (string)$p->Name . ']]></g:title>' . "\n");
304
+                        fwrite($fileW, '<g:description><![CDATA[' . (string)$p->Description . ']]></g:description>' . "\n");
305
+                        fwrite($fileW, '<g:link><![CDATA[' . (string)$p->URL . ']]></g:link>' . "\n");
306
+                        fwrite($fileW, '<g:image_link><![CDATA[' . (string)$p->LargeImage . ']]></g:image_link>' . "\n");
307
+                        fwrite($fileW, '<g:condition>' . (string)$p->Condition . '</g:condition>' . "\n");
308
+                        fwrite($fileW, '<g:availability>' . (string)'in stock' . '</g:availability>' . "\n");
309
+                        fwrite($fileW, '<g:price>' . (string)$p->Price . ' TWD' . '</g:price>' . "\n");
310
+                        fwrite($fileW, '<g:sale_price>' . (string)$p->SalePrice . ' TWD' . '</g:sale_price>' . "\n");
311
+                        fwrite($fileW, '<g:brand><![CDATA[' . (string)'特力屋' . ']]></g:brand>' . "\n");
312
+                        fwrite($fileW, '<g:google_product_category>' . (string)'' . '</g:google_product_category>' . "\n");
313
+                        fwrite($fileW, '<g:product_type><![CDATA[' . (string)$p->Category . ']]></g:product_type>' . "\n");
314
+                        fwrite($fileW, '<g:custom_label_0><![CDATA[' . (string)$p->custom_label_0 . ']]></g:custom_label_0>' . "\n");
315
+                        fwrite($fileW, '</item>' . "\n");
316
+                        // 資料庫(保留符號已被框架處理)
317
+                        $data[] = [
318
+                            'brand_no'         => $k,
319
+                            'batch_no'         => $batch_no,
320
+                            'g_id'             => (string)$p->SKU,
321
+                            'g_title'          => (string)$p->Name,
322
+                            'g_description'    => (string)$p->Description,
323
+                            'g_link'           => (string)$p->URL,
324
+                            'g_image_link'     => (string)$p->LargeImage,
325
+                            'g_price'          => (string)$p->Price . ' TWD',
326
+                            'g_sale_price'     => (string)$p->SalePrice . ' TWD',
327
+                            'g_product_type'   => (string)$p->Category,
328
+                            'g_custom_label_0' => (string)$p->custom_label_0,
329
+                        ];
330
+                        if (count($data) >= 100) {
331
+                            $this->productManagementSv->insertProduct($data);
332
+                            $data = [];
333
+                        }
334
+                    }
335
+                }
336
+                fwrite($fileW, '</channel><Updated>' . $batch_no . '</Updated></rss>' . "\n");
337
+                $this->productManagementSv->insertProduct($data);
338
+                // 結束寫入檔案
339
+                fclose($fileW);
340
+                // 檔案上傳至 S3
341
+                $fileR = fopen($path . $batch_no_digit . '.xml', "r");
342
+                $file_name = env('APP_ENV') . '/' . $v['LB'] . '/' . $batch_no_digit . '.xml';
343
+                $this->s3Client->putObject([
344
+                    'ACL'         => 'public-read',
345
+                    'Body'        => $fileR,
346
+                    'Bucket'      => env('AWS_S3_BUCKET'),
347
+                    'ContentType' => 'application/xml',
348
+                    'Key'         => $file_name,
349
+                ]);
350
+                fclose($fileR);
351
+                // 刪除寫入的檔案
352
+                unlink($path . $batch_no_digit . '.xml');
353
+                // 刪除舊資料(XML)
354
+                $objects = $this->s3Client->listObjects([
355
+                    'Bucket' => env('AWS_S3_BUCKET'),
356
+                    'Prefix' => env('APP_ENV') . '/' . $v['LB'] . '/' . $del_batch_no_digit,
357
+                ]);
358
+                foreach ($objects['Contents'] ?? [] as $object) {
359
+                    $tmpkey = $object['Key'] ?? null;
360
+                    if ($tmpkey) {
361
+                        $this->s3Client->deleteObjects([
362
+                            'Bucket' => env('AWS_S3_BUCKET'),
363
+                            'Delete' => ['Objects' => [['Key' => $tmpkey]]],
364
+                        ]);
365
+                    }
366
+                }
367
+            }
368
+            // 刪除舊資料(SQL)
369
+            $this->productManagementSv->deleteProductByBatchNo($del_batch_no);
370
+            Redis::del('TLW_0_XML');
371
+        }
372
+    }
373
+    
374
+    // XML轉換腳本(特力屋新版)
375
+    public function xmlG()
376
+    {
377
+        // 防重鎖
378
+        if (!Redis::get('TLW_0_XML')) {
379
+            Redis::set('TLW_0_XML', 'true');
380
+            Redis::expire('TLW_0_XML', 1200); // 20 分鐘
381
+            // 產生批次號
382
+            $batch_no = date("Y-m-d H:i:s");
383
+            $batch_no_digit = date("YmdHis");
384
+            // 產生刪除批次號
385
+            $del_batch_no = date('Y-m-d', strtotime(date("Y-m-d H:i:s") . "-14 days"));
386
+            $del_batch_no_digit = date('Ymd', strtotime(date("Y-m-d") . "-14 days"));
387
+            // 逐一品牌處理
388
+            foreach (GeneralConst::$brandMap as $k => $v) {
389
+                for ($i = 1; $i <= 14; $i++) {
390
+                }
391
+                // 載入品牌原始 XML
392
+                $original = simplexml_load_file($v['URLG']); // [新舊版本差異]來源修改
393
+                // 開始寫入檔案
394
+                $path = '/tmp/tlw/' . env('APP_ENV') . '/' . $v['LB'] . '/';
395
+                if (!file_exists($path)) mkdir($path, 0777, true);
396
+                $fileW = fopen($path . $batch_no_digit . '.xml', "w");
397
+                fwrite($fileW, '<?xml version="1.0" encoding="UTF-8"?><rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"><channel><title>特力屋</title><link>' . $v['URL'] . '</link><description></description>' . "\n");
398
+                // 原始商品逐筆處裡(保留符號已被CDATA處理)
399
+                // 注意可能出現相同品牌之中有相同 g_id 的現象,但由於不影響資料流程所以不處理
400
+                $data = [];
401
+                foreach ($original->channel->item as $p) { // [新舊版本差異]解析層級修改
402
+                    // custom_label_1 為客戶系統自定義欄位,Y代表可讓GMC上架,N代表不可讓GM上架
403
+                    if ((string)$p->custom_label_1 == GeneralConst::PUBLISH_YES) {
404
+                        // XML
405
+                        fwrite($fileW, '<item>' . "\n");
406
+                        fwrite($fileW, '<g:id>' . (string)$p->children('g', true)->id . '</g:id>' . "\n");
407
+                        fwrite($fileW, '<g:title><![CDATA[' . (string)$p->children('g', true)->title . ']]></g:title>' . "\n");
408
+                        fwrite($fileW, '<g:description><![CDATA[' . (string)$p->children('g', true)->description . ']]></g:description>' . "\n");
409
+                        fwrite($fileW, '<g:link><![CDATA[' . (string)$p->children('g', true)->link . ']]></g:link>' . "\n");
410
+                        fwrite($fileW, '<g:image_link><![CDATA[' . (string)$p->children('g', true)->image_link . ']]></g:image_link>' . "\n");
411
+                        fwrite($fileW, '<g:condition>' . (string)$p->children('g', true)->condition . '</g:condition>' . "\n");
412
+                        fwrite($fileW, '<g:availability>' . (string)$p->children('g', true)->availability . '</g:availability>' . "\n");
413
+                        fwrite($fileW, '<g:price>' . (string)$p->children('g', true)->price . '</g:price>' . "\n");
414
+                        fwrite($fileW, '<g:sale_price>' . (string)$p->children('g', true)->sale_price . '</g:sale_price>' . "\n");
415
+                        fwrite($fileW, '<g:brand><![CDATA[' . (string)$p->children('g', true)->brand . ']]></g:brand>' . "\n");
416
+                        fwrite($fileW, '<g:google_product_category>' . (string)'' . '</g:google_product_category>' . "\n");
417
+                        fwrite($fileW, '<g:product_type><![CDATA[' . (string)$p->children('g', true)->product_type . ']]></g:product_type>' . "\n");
418
+                        fwrite($fileW, '<g:custom_label_0><![CDATA[' . (string)$p->custom_label_0 . ']]></g:custom_label_0>' . "\n");
419
+                        fwrite($fileW, '</item>' . "\n");
420
+                        // 資料庫(保留符號已被框架處理)
421
+                        $data[] = [
422
+                            'brand_no'         => $k,
423
+                            'batch_no'         => $batch_no,
424
+                            'g_id'             => (string)$p->children('g', true)->id,
425
+                            'g_title'          => (string)$p->children('g', true)->title,
426
+                            'g_description'    => (string)$p->children('g', true)->description,
427
+                            'g_link'           => (string)$p->children('g', true)->link,
428
+                            'g_image_link'     => (string)$p->children('g', true)->image_link,
429
+                            'g_price'          => (string)$p->children('g', true)->price,
430
+                            'g_sale_price'     => (string)$p->children('g', true)->sale_price,
431
+                            'g_product_type'   => (string)$p->children('g', true)->product_type,
432
+                            'g_custom_label_0' => (string)$p->custom_label_0,
433
+                        ];
434
+                        if (count($data) >= 100) {
435
+                            $this->productManagementSv->insertProduct($data);
436
+                            $data = [];
437
+                        }
438
+                    }
439
+                }
440
+                fwrite($fileW, '</channel><Updated>' . $batch_no . '</Updated></rss>' . "\n");
441
+                $this->productManagementSv->insertProduct($data);
442
+                // 結束寫入檔案
443
+                fclose($fileW);
444
+                // 檔案上傳至 S3
445
+                $fileR = fopen($path . $batch_no_digit . '.xml', "r");
446
+                $file_name = env('APP_ENV') . '/' . $v['LB'] . '/' . $batch_no_digit . '.xml';
447
+                $this->s3Client->putObject([
448
+                    'ACL'         => 'public-read',
449
+                    'Body'        => $fileR,
450
+                    'Bucket'      => env('AWS_S3_BUCKET'),
451
+                    'ContentType' => 'application/xml',
452
+                    'Key'         => $file_name,
453
+                ]);
454
+                fclose($fileR);
455
+                // 刪除寫入的檔案
456
+                unlink($path . $batch_no_digit . '.xml');
457
+                // 刪除舊資料(XML)
458
+                $objects = $this->s3Client->listObjects([
459
+                    'Bucket' => env('AWS_S3_BUCKET'),
460
+                    'Prefix' => env('APP_ENV') . '/' . $v['LB'] . '/' . $del_batch_no_digit,
461
+                ]);
462
+                foreach ($objects['Contents'] ?? [] as $object) {
463
+                    $tmpkey = $object['Key'] ?? null;
464
+                    if ($tmpkey) {
465
+                        $this->s3Client->deleteObjects([
466
+                            'Bucket' => env('AWS_S3_BUCKET'),
467
+                            'Delete' => ['Objects' => [['Key' => $tmpkey]]],
468
+                        ]);
469
+                    }
470
+                }
471
+            }
472
+            // 刪除舊資料(SQL)
473
+            $this->productManagementSv->deleteProductByBatchNo($del_batch_no);
474
+            Redis::del('TLW_0_XML');
475
+        }
476
+    }
477
+    
478
+    // 更新動態饋給
479
+    public function endpoint()
480
+    {
481
+        // 防重鎖
482
+        if (!Redis::get('TLW_4_XML')) {
483
+            Redis::set('TLW_4_XML', 'true');
484
+            Redis::expire('TLW_4_XML', 1200); // 20 分鐘
485
+            // 取出資料
486
+            $info = explode('|', Redis::get('TLW_4_MAN'));
487
+            $brand_no = $info[0];
488
+            $batch_no = $info[1];
489
+            $products = $this->productManagementSv->getEndpointProdocts($brand_no, $batch_no);
490
+            // 拼裝XML
491
+            // 開始寫入檔案
492
+            $path = '/tmp/tlwendpoint/' . env('APP_ENV') . '/' . GeneralConst::$brandMap[ $brand_no ]['LB'] . '/';
493
+            if (!file_exists($path)) mkdir($path, 0777, true);
494
+            $fileW = fopen($path . 'FINAL.xml', "w");
495
+            fwrite($fileW, '<?xml version="1.0" encoding="UTF-8"?><rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"><channel><title>特力屋</title><link>' . GeneralConst::$brandMap[ $brand_no ]['URL'] . '</link><description></description>' . "\n");
496
+            foreach ($products as $p) {
497
+                fwrite($fileW, '<item>' . "\n");
498
+                fwrite($fileW, '<g:id>' . (string)$p['g_id'] . '</g:id>' . "\n");
499
+                fwrite($fileW, '<g:title><![CDATA[' . (string)$p['g_title'] . ']]></g:title>' . "\n");
500
+                fwrite($fileW, '<g:description><![CDATA[' . (string)$p['g_description'] . ']]></g:description>' . "\n");
501
+                fwrite($fileW, '<g:link><![CDATA[' . (string)$p['g_link'] . ']]></g:link>' . "\n");
502
+                fwrite($fileW, '<g:image_link><![CDATA[' . (string)$p['g_image_link'] . ']]></g:image_link>' . "\n");
503
+                fwrite($fileW, '<g:condition>' . (string)$p['g_condition'] . '</g:condition>' . "\n");
504
+                fwrite($fileW, '<g:availability>' . (string)$p['g_availability'] . '</g:availability>' . "\n");
505
+                fwrite($fileW, '<g:price>' . (string)$p['g_price'] . '</g:price>' . "\n");
506
+                fwrite($fileW, '<g:sale_price>' . (string)$p['g_sale_price'] . '</g:sale_price>' . "\n");
507
+                fwrite($fileW, '<g:brand><![CDATA[' . (string)$p['g_brand'] . ']]></g:brand>' . "\n");
508
+                fwrite($fileW, '<g:google_product_category>' . (string)$p['g_google_product_category'] . '</g:google_product_category>' . "\n");
509
+                fwrite($fileW, '<g:product_type><![CDATA[' . (string)$p['g_product_type'] . ']]></g:product_type>' . "\n");
510
+                fwrite($fileW, '<g:custom_label_0><![CDATA[' . (string)$p['g_custom_label_0'] . ']]></g:custom_label_0>' . "\n");
511
+                fwrite($fileW, '</item>' . "\n");
512
+            }
513
+            fwrite($fileW, '</channel><Updated>' . $batch_no . '</Updated></rss>' . "\n");
514
+            // 結束寫入檔案
515
+            fclose($fileW);
516
+            // 上傳至S3取代
517
+            $fileR = fopen($path . 'FINAL.xml', "r");
518
+            $file_name = env('APP_ENV') . '/' . GeneralConst::$brandMap[ $brand_no ]['LB'] . '/FINAL.xml';
519
+            $this->s3Client->putObject([
520
+                'ACL'         => 'public-read',
521
+                'Body'        => $fileR,
522
+                'Bucket'      => env('AWS_S3_BUCKET'),
523
+                'ContentType' => 'application/xml',
524
+                'Key'         => $file_name,
525
+            ]);
526
+            fclose($fileR);
527
+            // 刪除檔案
528
+            unlink($path . 'FINAL.xml');
529
+            Redis::del('TLW_4_XML');
530
+        }
531
+    }
532
+    
533
+}

+ 105
- 0
app/Http/Controllers/Backend/FunmenusController.php Прегледај датотеку

@@ -0,0 +1,105 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\Http\Requests;
8
+use App\Http\Controllers\Controller;
9
+use App\FunMenu;
10
+use App\FunMenuDetail;
11
+use Redirect;
12
+use Session;
13
+use Validator;
14
+
15
+class FunmenusController extends Controller
16
+{
17
+    public function index()
18
+    {
19
+        $tables = FunMenu::All();
20
+
21
+        return view('admin.funmenus', [
22
+            'tables' => $tables,
23
+        ]);
24
+    }
25
+
26
+    public function create()
27
+    {
28
+        return view('admin.funmenusedit', [
29
+            'datas' => "",
30
+        ]);
31
+    }
32
+
33
+    public function edit($id)
34
+    {
35
+        $datas = FunMenu::find($id);
36
+        return view('admin.funmenusedit', [
37
+            'datas' => $datas,
38
+        ]);
39
+    }
40
+
41
+    public function store(Request $request)
42
+    {
43
+        $validator = Validator::make($request->all(), [
44
+            'MenuName' => 'required|max:255',
45
+            'Corder' => 'required'
46
+
47
+        ]);
48
+        if ($validator->fails()) {
49
+            return Redirect::back()
50
+            ->withErrors($validator);
51
+        }
52
+        else
53
+        {
54
+            if ($request->mode == "insert")
55
+            {
56
+                $funmenu = new FunMenu;
57
+                $funmenu->icon = $request->icon;
58
+                $funmenu->MenuName = $request->MenuName;
59
+                $funmenu->Valid = ($request->Valid == "on") ? 1 : 0;
60
+                $funmenu->Corder = $request->Corder;
61
+                $funmenu->Oid = $request->user()->id;
62
+                $funmenu->save();
63
+            }
64
+            else
65
+            {
66
+                $funmenu = FunMenu::find($request->id);
67
+                $funmenu->icon = $request->icon;
68
+                $funmenu->MenuName = $request->MenuName;
69
+                $funmenu->Valid = ($request->Valid == "on") ? 1 : 0;
70
+                $funmenu->Corder = $request->Corder;
71
+                $funmenu->Oid = $request->user()->id;
72
+                $funmenu->save();
73
+            }
74
+        }
75
+
76
+        return Redirect::back();
77
+    }
78
+
79
+    public function delete($id)
80
+    {
81
+        if ($id == 1)
82
+        {
83
+            Session::flash('msg', 'This can not be delete!!');
84
+        }
85
+        else
86
+        {
87
+            $funmenudetails = FunMenuDetail::where('FunMenuId', '=', $id);
88
+
89
+            if ($funmenudetails->count() > 0)
90
+            {
91
+                Session::flash('msg', 'Must delete functions first!!');
92
+            }
93
+            else
94
+            {
95
+                $funmenu = FunMenu::find($id);
96
+                $funmenu->delete();
97
+
98
+
99
+                $funmenudetails->delete();
100
+            }
101
+        }
102
+
103
+        return Redirect::back();
104
+    }
105
+}

+ 108
- 0
app/Http/Controllers/Backend/FunmenusDetailController.php Прегледај датотеку

@@ -0,0 +1,108 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\Http\Requests;
8
+use App\Http\Controllers\Controller;
9
+use App\FunMenu;
10
+use App\FunMenuDetail;
11
+use App\Functions;
12
+use Redirect;
13
+use Session;
14
+
15
+class FunmenusDetailController extends Controller
16
+{
17
+    public function index($menuid)
18
+    {
19
+        $parentname = FunMenu::select('MenuName')->where('id', '=', $menuid)->get();
20
+        $funmenus = FunMenuDetail::select('FunId')->where('FunMenuId', '=', $menuid)->get();
21
+        $tables = Functions::whereIn('id', $funmenus)->get();
22
+
23
+        return view('admin.funmenusdetail', [
24
+            'parentname' => $parentname,
25
+            'tables' => $tables,
26
+            'id' => $menuid,
27
+        ]);
28
+    }
29
+
30
+    public function create($menuid)
31
+    {
32
+        return view('admin.funmenusdetailedit', [
33
+            'datas' => "",
34
+            'datas2' => "",
35
+            'id' => $menuid,
36
+        ]);
37
+    }
38
+
39
+    public function edit($menuid, $id)
40
+    {
41
+        $datas = Functions::find($id);
42
+        $datas2 = FunMenuDetail::select('id','Corder')->where('FunMenuId', '=', $menuid)->where('FunId', '=', $id)->get();
43
+
44
+        return view('admin.funmenusdetailedit', [
45
+            'datas' => $datas,
46
+            'datas2' => $datas2[0],
47
+            'id' => $menuid,
48
+        ]);
49
+    }
50
+
51
+    public function store(Request $request, $menuid)
52
+    {
53
+        if ($request->mode == "insert")
54
+        {
55
+            $function = new Functions;
56
+            $function->FunName = $request->FunName;
57
+            $function->FunLink = $request->FunLink;
58
+            $function->FunDesc = $request->FunDesc;
59
+            $function->Valid = ($request->Valid == "on") ? 1 : 0;
60
+            $function->Oid = $request->user()->id;
61
+            $function->save();
62
+
63
+            $functiondetail = new FunMenuDetail;
64
+            $functiondetail->FunMenuId = $menuid;
65
+            $functiondetail->FunId = $function->id;
66
+            $functiondetail->Valid = ($request->Valid == "on") ? 1 : 0;
67
+            $functiondetail->Corder = $request->Corder;
68
+            $functiondetail->Oid = $request->user()->id;
69
+            $functiondetail->save();
70
+        }
71
+        else
72
+        {
73
+            $function = Functions::find($request->id);
74
+            $function->FunName = $request->FunName;
75
+            $function->FunLink = $request->FunLink;
76
+            $function->FunDesc = $request->FunDesc;
77
+            $function->Valid = ($request->Valid == "on") ? 1 : 0;
78
+            $function->Oid = $request->user()->id;
79
+            $function->save();
80
+
81
+            $functiondetail = FunMenuDetail::find($request->detailid);
82
+            $functiondetail->Valid = ($request->Valid == "on") ? 1 : 0;
83
+            $functiondetail->Corder = $request->Corder;
84
+            $functiondetail->Oid = $request->user()->id;
85
+            $functiondetail->save();
86
+        }
87
+
88
+        return Redirect::back();
89
+    }
90
+
91
+    public function delete($menuid, $id)
92
+    {
93
+        if ($menuid == 1)
94
+        {
95
+            Session::flash('msg', 'This can not be delete!!');
96
+        }
97
+        else
98
+        {
99
+            $function = Functions::find($id);
100
+            $function->delete();
101
+
102
+            $funmenudetail = FunMenuDetail::where('FunId', '=', $id);
103
+            $funmenudetail->delete();
104
+        }
105
+
106
+        return Redirect::back();
107
+    }
108
+}

+ 17
- 0
app/Http/Controllers/Backend/IndexController.php Прегледај датотеку

@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\FunMenu;
8
+use App\Http\Requests;
9
+use App\Http\Controllers\Controller;
10
+
11
+class IndexController extends Controller
12
+{
13
+    public function index()
14
+    {
15
+        return view('admin.index');
16
+    }
17
+}

+ 35
- 0
app/Http/Controllers/Backend/PasswordController.php Прегледај датотеку

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\User;
8
+use App\FunMenu;
9
+use App\Http\Requests;
10
+use App\Http\Controllers\Controller;
11
+use Session;
12
+use Redirect;
13
+
14
+class PasswordController extends Controller
15
+{
16
+    public function index()
17
+    {
18
+        return view('admin.password');
19
+    }
20
+
21
+    public function update(Request $request)
22
+    {
23
+        $this->validate($request, [
24
+            'qpwd1' => 'required|max:255',
25
+        ]);
26
+
27
+        $user = User::find($request->user()->id);
28
+        $user->password = bcrypt($request->qpwd1);
29
+        $user->save();
30
+
31
+        Session::flash('msg', 'Update Success!');
32
+
33
+        return Redirect::back();
34
+    }
35
+}

+ 118
- 0
app/Http/Controllers/Backend/UsergroupsController.php Прегледај датотеку

@@ -0,0 +1,118 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\FunMenu;
8
+use App\FunUserGroups;
9
+use App\Http\Requests;
10
+use App\Http\Controllers\Controller;
11
+use Redirect;
12
+
13
+class UsergroupsController extends Controller
14
+{
15
+    public function index()
16
+    {
17
+        $tables = FunUserGroups::all();
18
+
19
+        return view('admin.usergroups', [
20
+            'tables' => $tables,
21
+        ]);
22
+    }
23
+
24
+    public function delete(Request $request, FunUserGroups $id)
25
+    {
26
+        if($id->id == 1)
27
+        {
28
+            return Redirect::back()->withErrors("Admin group can not be delete!");
29
+        }
30
+        else
31
+        {
32
+            $id->delete();
33
+        }
34
+        return Redirect::back();
35
+    }
36
+
37
+    public function create(Request $request)
38
+    {
39
+        $user_name = $request->user()->name;
40
+        $user_id = $request->user()->id;
41
+
42
+        $funmenu = new FunMenu;
43
+        $result = $funmenu->leftmenu($user_id);
44
+
45
+        $usergroup = new FunUserGroups;
46
+        $seleted_usrlist = $usergroup->selectedUsrList(9999);
47
+        $unseleted_usrlist = $usergroup->unseletedUsrList(9999);
48
+        $seleted_funlist = $usergroup->seletedFunList(9999);
49
+        $unseleted_funlist = $usergroup->unseletedFunList(9999);
50
+
51
+        return view('admin.usergroupsedit', [
52
+            'leftmenu' => $result,
53
+            'username' => $user_name,
54
+            'seleted_usrlist' => $seleted_usrlist,
55
+            'unseleted_usrlist' => $unseleted_usrlist,
56
+            'seleted_funlist' => $seleted_funlist,
57
+            'unseleted_funlist' => $unseleted_funlist,
58
+            'operdata' => "",
59
+
60
+        ]);
61
+    }
62
+
63
+    public function edit(Request $request, $id)
64
+    {
65
+        $user_name = $request->user()->name;
66
+        $user_id = $request->user()->id;
67
+        $fun_id = $id;
68
+
69
+        $funmenu = new FunMenu;
70
+        $result = $funmenu->leftmenu($user_id);
71
+
72
+        $usergroup = new FunUserGroups;
73
+        $seleted_usrlist = $usergroup->selectedUsrList($fun_id);
74
+        $unseleted_usrlist = $usergroup->unseletedUsrList($fun_id);
75
+        $seleted_funlist = $usergroup->seletedFunList($fun_id);
76
+        $unseleted_funlist = $usergroup->unseletedFunList($fun_id);
77
+        $operdata = $usergroup->operData($fun_id);
78
+
79
+        return view('admin.usergroupsedit', [
80
+            'leftmenu' => $result,
81
+            'username' => $user_name,
82
+            'seleted_usrlist' => $seleted_usrlist,
83
+            'unseleted_usrlist' => $unseleted_usrlist,
84
+            'seleted_funlist' => $seleted_funlist,
85
+            'unseleted_funlist' => $unseleted_funlist,
86
+            'operdata' => $operdata,
87
+
88
+        ]);
89
+    }
90
+
91
+    public function store(Request $request)
92
+    {
93
+        if ($request->mode == "insert")
94
+        {
95
+            $usergroup = new FunUserGroups;
96
+            $usergroup->Name = $request->Name;
97
+            $usergroup->FunList = $request->hidfunlist;
98
+            $usergroup->UsrList = $request->hidusrlist;
99
+            $usergroup->Valid = ($request->Valid == "on") ? 1 : 0;
100
+            $usergroup->Oid = $request->user()->id;
101
+            $usergroup->save();
102
+
103
+            return redirect('/backend/Usergroups');
104
+        }
105
+        else
106
+        {
107
+            $usergroup = FunUserGroups::find($request->id);
108
+            $usergroup->Name = $request->Name;
109
+            $usergroup->FunList = $request->hidfunlist;
110
+            $usergroup->UsrList = $request->hidusrlist;
111
+            $usergroup->Valid = ($request->Valid == "on") ? 1 : 0;
112
+            $usergroup->Oid = $request->user()->id;
113
+            $usergroup->save();
114
+
115
+            return redirect('/backend/Usergroups');
116
+        }
117
+    }
118
+}

+ 76
- 0
app/Http/Controllers/Backend/UsersController.php Прегледај датотеку

@@ -0,0 +1,76 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\FunMenu;
8
+use App\User;
9
+use App\Http\Requests;
10
+use App\Http\Controllers\Controller;
11
+use Redirect;
12
+
13
+class UsersController extends Controller
14
+{
15
+    public function index()
16
+    {
17
+        $tables = User::all();
18
+        
19
+        return view('admin.users', [
20
+            'tables' => $tables,
21
+        ]);
22
+    }
23
+    
24
+    public function create(Request $request)
25
+    {
26
+        return view('admin.usersedit', [
27
+            'operdata' => "",
28
+        ]);
29
+    }
30
+    
31
+    public function edit($id)
32
+    {
33
+        $usr_id = $id;
34
+        $operdata = User::find($usr_id);
35
+        
36
+        return view('admin.usersedit', [
37
+            'operdata' => $operdata,
38
+        ]);
39
+    }
40
+    
41
+    public function store(Request $request)
42
+    {
43
+        //$role = \App\Role::where('name', 'admin')->first();
44
+        
45
+        if ($request->mode == "insert") {
46
+            $user = new User;
47
+            $user->name = $request->name;
48
+            $user->email = $request->email;
49
+            $user->password = bcrypt($request->password);
50
+            $user->save();
51
+            
52
+            //$user->attachRole($role);
53
+            return redirect('/backend/Users');
54
+        } else {
55
+            $user = User::find($request->id);
56
+            $user->name = $request->name;
57
+            if ($request->password != "") {
58
+                $user->password = bcrypt($request->password);
59
+            }
60
+            $user->save();
61
+            
62
+            return redirect('/backend/Users');
63
+        }
64
+    }
65
+    
66
+    public function delete(Request $request, User $id)
67
+    {
68
+        if ($id->email == "admin@gmail.com") {
69
+            return Redirect::back()->withErrors("Administrator can not be delete!");
70
+        } else {
71
+            $id->delete();
72
+        }
73
+        
74
+        return Redirect::back();
75
+    }
76
+}

+ 116
- 0
app/Http/Controllers/Backend/ZooManagement/TigerManagementController.php Прегледај датотеку

@@ -0,0 +1,116 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend\ZooManagement;
4
+
5
+use Illuminate\Http\Request;
6
+use App\Http\Services\Backend\ZooManagement\TigerManagementService;
7
+use App\Http\Controllers\Controller;
8
+
9
+class TigerManagementController extends Controller
10
+{
11
+    
12
+    // 相關私有服務層調用器宣告
13
+    private $tigerManagementSv;
14
+    
15
+    public function __construct()
16
+    {
17
+        // 建構服務層調用器
18
+        $this->tigerManagementSv = new TigerManagementService();
19
+    }
20
+    
21
+    /**
22
+     * 列表頁
23
+     *   本端點非 API,於 controller 取列表值後,存於變量渲染到 view
24
+     *   排序、分頁均未實現
25
+     * @return array:          返回渲染頁
26
+     */
27
+    public function index()
28
+    {
29
+        // 取得參數與驗證
30
+        // 服務層取得資料(以及實現各種業務上的邏輯)
31
+        $tigers = $this->tigerManagementSv->getTigers();
32
+        
33
+        // 渲染
34
+        return view('admin.ZooManagement.TigerManagement', [
35
+            'operdata' => $tigers,
36
+        ]);
37
+    }
38
+    
39
+    /**
40
+     * 新增老虎頁面
41
+     *   本端點非 API,直接到 view
42
+     * @return array:          返回渲染頁
43
+     */
44
+    public function create()
45
+    {
46
+        // 渲染
47
+        return view('admin.ZooManagement.TigerManagementEdit', [
48
+            'operdata' => "",
49
+        ]);
50
+    }
51
+    
52
+    /**
53
+     * 編輯老虎頁面
54
+     *   本端點非 API,依照變量取得資料後,渲染到 view
55
+     *
56
+     * @param  integer $id :    老虎的自增量
57
+     *
58
+     * @return array:          返回渲染頁
59
+     */
60
+    public function edit($id)
61
+    {
62
+        // 取得參數與驗證
63
+        // 服務層取得資料(以及實現各種業務上的邏輯)
64
+        $tiger = $this->tigerManagementSv->getTigerById($id);
65
+        
66
+        // 渲染
67
+        return view('admin.ZooManagement.TigerManagementEdit', [
68
+            'operdata' => $tiger,
69
+        ]);
70
+    }
71
+    
72
+    /**
73
+     * 新增或編輯老虎的端點
74
+     *   本端點非 API,依照參數新增或修改資料後,跳轉到既有的 view
75
+     *
76
+     * @param  Request $request :  整包參數
77
+     *
78
+     * @return array:             返回跳轉渲染頁的資訊
79
+     */
80
+    public function store(Request $request)
81
+    {
82
+        // 取得參數與驗證
83
+        $mode = $request->mode;
84
+        $id = ($request->mode == 'insert') ? '' : $request->id;
85
+        $tigerName = $request->tigerName;
86
+        // 服務層設置(以及實現各種業務上的邏輯)
87
+        if ($mode == "insert") {
88
+            // 新增模式
89
+            $this->tigerManagementSv->insertTiger($tigerName);
90
+        } else {
91
+            // 編輯模式
92
+            $this->tigerManagementSv->modifyTiger($id, $tigerName);
93
+        }
94
+        
95
+        // 跳轉
96
+        return redirect('/backend/zooManagement/tigerManagement');
97
+    }
98
+    
99
+    /**
100
+     * 刪除老虎的端點
101
+     *   本端點非 API,依照參數刪除資料後,跳轉到既有的 view
102
+     *
103
+     * @param  integer $id :    老虎的自增量
104
+     *
105
+     * @return array:           返回跳轉渲染頁的資訊
106
+     */
107
+    public function delete($id)
108
+    {
109
+        // 取得參數與驗證
110
+        // 服務層取得資料(以及實現各種業務上的邏輯)
111
+        $this->tigerManagementSv->deleteTigerById($id);
112
+    
113
+        // 跳轉
114
+        return Redirect::back();
115
+    }
116
+}

+ 13
- 0
app/Http/Controllers/Controller.php Прегледај датотеку

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use Illuminate\Foundation\Bus\DispatchesJobs;
6
+use Illuminate\Routing\Controller as BaseController;
7
+use Illuminate\Foundation\Validation\ValidatesRequests;
8
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
9
+
10
+class Controller extends BaseController
11
+{
12
+    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
13
+}

+ 28
- 0
app/Http/Controllers/HomeController.php Прегледај датотеку

@@ -0,0 +1,28 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+class HomeController extends Controller
8
+{
9
+    /**
10
+     * Create a new controller instance.
11
+     *
12
+     * @return void
13
+     */
14
+    public function __construct()
15
+    {
16
+        $this->middleware('auth');
17
+    }
18
+
19
+    /**
20
+     * Show the application dashboard.
21
+     *
22
+     * @return \Illuminate\Http\Response
23
+     */
24
+    public function index()
25
+    {
26
+        return view('home');
27
+    }
28
+}

+ 60
- 0
app/Http/Kernel.php Прегледај датотеку

@@ -0,0 +1,60 @@
1
+<?php
2
+
3
+namespace App\Http;
4
+
5
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
6
+
7
+class Kernel extends HttpKernel
8
+{
9
+    /**
10
+     * The application's global HTTP middleware stack.
11
+     *
12
+     * These middleware are run during every request to your application.
13
+     *
14
+     * @var array
15
+     */
16
+    protected $middleware = [
17
+        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
18
+        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
19
+        \App\Http\Middleware\TrimStrings::class,
20
+        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
21
+    ];
22
+
23
+    /**
24
+     * The application's route middleware groups.
25
+     *
26
+     * @var array
27
+     */
28
+    protected $middlewareGroups = [
29
+        'web' => [
30
+            \App\Http\Middleware\EncryptCookies::class,
31
+            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
32
+            \Illuminate\Session\Middleware\StartSession::class,
33
+            // \Illuminate\Session\Middleware\AuthenticateSession::class,
34
+            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
35
+            \App\Http\Middleware\VerifyCsrfToken::class,
36
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
37
+        ],
38
+
39
+        'api' => [
40
+            'throttle:60,1',
41
+            'bindings',
42
+        ],
43
+    ];
44
+
45
+    /**
46
+     * The application's route middleware.
47
+     *
48
+     * These middleware may be assigned to groups or used individually.
49
+     *
50
+     * @var array
51
+     */
52
+    protected $routeMiddleware = [
53
+        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
54
+        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
55
+        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
56
+        'can' => \Illuminate\Auth\Middleware\Authorize::class,
57
+        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
58
+        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
59
+    ];
60
+}

+ 17
- 0
app/Http/Middleware/EncryptCookies.php Прегледај датотеку

@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
6
+
7
+class EncryptCookies extends BaseEncrypter
8
+{
9
+    /**
10
+     * The names of the cookies that should not be encrypted.
11
+     *
12
+     * @var array
13
+     */
14
+    protected $except = [
15
+        //
16
+    ];
17
+}

+ 26
- 0
app/Http/Middleware/RedirectIfAuthenticated.php Прегледај датотеку

@@ -0,0 +1,26 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Closure;
6
+use Illuminate\Support\Facades\Auth;
7
+
8
+class RedirectIfAuthenticated
9
+{
10
+    /**
11
+     * Handle an incoming request.
12
+     *
13
+     * @param  \Illuminate\Http\Request  $request
14
+     * @param  \Closure  $next
15
+     * @param  string|null  $guard
16
+     * @return mixed
17
+     */
18
+    public function handle($request, Closure $next, $guard = null)
19
+    {
20
+        if (Auth::guard($guard)->check()) {
21
+            return redirect('/backend');
22
+        }
23
+
24
+        return $next($request);
25
+    }
26
+}

+ 18
- 0
app/Http/Middleware/TrimStrings.php Прегледај датотеку

@@ -0,0 +1,18 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Foundation\Http\Middleware\TrimStrings as BaseTrimmer;
6
+
7
+class TrimStrings extends BaseTrimmer
8
+{
9
+    /**
10
+     * The names of the attributes that should not be trimmed.
11
+     *
12
+     * @var array
13
+     */
14
+    protected $except = [
15
+        'password',
16
+        'password_confirmation',
17
+    ];
18
+}

+ 23
- 0
app/Http/Middleware/TrustProxies.php Прегледај датотеку

@@ -0,0 +1,23 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Http\Request;
6
+use Fideloper\Proxy\TrustProxies as Middleware;
7
+
8
+class TrustProxies extends Middleware
9
+{
10
+    /**
11
+     * The trusted proxies for this application.
12
+     *
13
+     * @var array|string
14
+     */
15
+    protected $proxies = '*';
16
+    
17
+    /**
18
+     * The headers that should be used to detect proxies.
19
+     *
20
+     * @var int
21
+     */
22
+    protected $headers = Request::HEADER_X_FORWARDED_ALL;
23
+}

+ 18
- 0
app/Http/Middleware/VerifyCsrfToken.php Прегледај датотеку

@@ -0,0 +1,18 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
6
+
7
+class VerifyCsrfToken extends BaseVerifier
8
+{
9
+    /**
10
+     * The URIs that should be excluded from CSRF verification.
11
+     *
12
+     * @var array
13
+     */
14
+    protected $except = [
15
+        'backend/*',
16
+        'api/*'
17
+    ];
18
+}

+ 20
- 0
app/Http/Services/Api/GeneralInnerServiceService.php Прегледај датотеку

@@ -0,0 +1,20 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Api;
4
+
5
+
6
+class GeneralInnerServiceService
7
+{
8
+    
9
+    public function __construct()
10
+    {
11
+    }
12
+    
13
+    public function validate($token)
14
+    {
15
+        $res = \DB::select(\DB::raw("SELECT id as oid from users where password='" . $token . "'"));
16
+    
17
+        return $res[0]->oid ?? 0;
18
+    }
19
+    
20
+}

+ 303
- 0
app/Http/Services/Backend/DataManagement/UrlManagementService.php Прегледај датотеку

@@ -0,0 +1,303 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Backend\DataManagement;
4
+
5
+use App\Http\Services\ConstDef\GeneralConst;
6
+use App\Models\DataManagement\UrlManagement;
7
+use App\Models\DataManagement\UrlManagementVisit;
8
+use PhpOffice\PhpSpreadsheet\IOFactory;
9
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
10
+
11
+class UrlManagementService
12
+{
13
+    
14
+    // 相關私有 model 調用器宣告
15
+    private $urlManagementDb;
16
+    private $urlManagementVisitDb;
17
+    
18
+    public function __construct()
19
+    {
20
+        // 建構 model 調用器
21
+        $this->urlManagementDb = new UrlManagement();
22
+        $this->urlManagementVisitDb = new UrlManagementVisit();
23
+    }
24
+    
25
+    public function getTitles($oid)
26
+    {
27
+        $ret = $this->urlManagementDb
28
+            ->select([
29
+                'title',
30
+            ]);
31
+        // 權限判斷
32
+        if ($oid != GeneralConst::ID_ADMIN) {
33
+            $ret = $ret
34
+                ->where('oid', '=', $oid);
35
+        }
36
+        $ret = $ret
37
+            ->groupBy('title')
38
+            ->orderBy('serno', 'desc')
39
+            ->get()
40
+            ->toArray();
41
+        
42
+        return $ret;
43
+    }
44
+    
45
+    public function getValids()
46
+    {
47
+        $valids = [];
48
+        foreach (GeneralConst::$urlMap as $k => $v) {
49
+            $valids[] = [
50
+                'id'   => $k,
51
+                'text' => $v,
52
+            ];
53
+        }
54
+        
55
+        return $valids;
56
+    }
57
+    
58
+    public function getUrls(
59
+        &$cnt = 0,
60
+        $orderColumn,
61
+        $orderDir,
62
+        $start,
63
+        $length,
64
+        $searchValue,
65
+        $title,
66
+        $memo,
67
+        $createDateStart,
68
+        $createDateFinal,
69
+        $valid,
70
+        $oid
71
+    )
72
+    {
73
+        // 選欄位
74
+        $validStr = '';
75
+        foreach (GeneralConst::$urlMap as $k => $v) {
76
+            $validStr .= ' when \'' . $k . '\' then \'' . $v . '\'';
77
+        }
78
+        
79
+        $urls = $this->urlManagementDb
80
+            ->select([
81
+                'dataManagement_urlManagement.serno',
82
+                'title',
83
+                \DB::raw("concat('<button class=\"btn btn-xs\" id=\"url_copy_', dataManagement_urlManagement.serno, '\" url=\"', url, '\">複製網址</button>') as url"),
84
+                \DB::raw("concat('<button class=\"btn btn-xs\" id=\"url_copy_', dataManagement_urlManagement.serno, '\" url=\"" . env('ORL_URL') . "', dataManagement_urlManagement.code, '\">', dataManagement_urlManagement.code, '</button>') as code"),
85
+                'memo',
86
+                \DB::raw("ifnull(uv_count, 0) as pv"),
87
+                \DB::raw("(case valid $validStr end) as valid"),
88
+                \DB::raw('concat(\'<a class="btn btn-success btn-xs" href="urlManagement/edit/\', dataManagement_urlManagement.serno, \'"><span class="glyphicon glyphicon-pencil"></span></a>\') as edit'),
89
+                \DB::raw("concat('<img src=\"urlManagement/qrcode/', dataManagement_urlManagement.code, '\" width=\"70\"/>') as qrcode"),
90
+                \DB::raw("dataManagement_urlManagement.code as api_code"),
91
+                \DB::raw("concat('" . env('APP_URL') . "/api/inner/qrcode/', dataManagement_urlManagement.code) as api_qrcode"),
92
+            ])
93
+            ->leftjoin(\DB::raw("(select v.code, count(*) as uv_count from dataManagement_urlManagement_visit as v where (cdate >= '" . $createDateStart . " 00:00:00' and cdate <= '" . $createDateFinal . " 23:59:59') group by v.code) as uv"), 'dataManagement_urlManagement.code', '=', 'uv.code');
94
+        // 過濾搜尋條件
95
+        $urls = $urls
96
+            ->where('title', 'LIKE', '%' . $title . '%')
97
+            ->where('memo', 'LIKE', '%' . $memo . '%');
98
+        if ($valid != GeneralConst::URL_ALL) {
99
+            $urls = $urls->where('valid', '=', $valid);
100
+        }
101
+        // 權限判斷
102
+        if ($oid != GeneralConst::ID_ADMIN) {
103
+            $urls = $urls->where('oid', '=', $oid);
104
+        }
105
+        // 取總筆數
106
+        $cnt = $urls->count();
107
+        // 排序
108
+        $urls = $urls
109
+            ->orderByRaw((int)$orderColumn . ' ' . $orderDir);
110
+        // 彙整
111
+        $urls = $urls
112
+            ->groupby('dataManagement_urlManagement.code');
113
+        // 分頁
114
+        $urls = $urls
115
+            ->skip($start)->take($length);
116
+        // 實際取資料
117
+        $urls = $urls
118
+            ->get()
119
+            ->toArray();
120
+        
121
+        // 整理返回值並返回
122
+        return $urls;
123
+    }
124
+    
125
+    public function getDateseg($oid)
126
+    {
127
+        // 取得所有 code
128
+        $codes = $this->urlManagementDb->select(['code']);
129
+        if ($oid != GeneralConst::ID_ADMIN) {
130
+            $codes = $codes->where('oid', '=', $oid);
131
+        }
132
+        $codes = array_map('current', $codes->get()->toArray());
133
+        // 取得依照時間切分的資料
134
+        $datesegs = $this->urlManagementVisitDb->select([
135
+            'code',
136
+            \DB::raw("left(cdate, 10) as date"),
137
+            \DB::raw("count(*) as cnt"),
138
+        ]);
139
+        if ($oid != GeneralConst::ID_ADMIN) {
140
+            $datesegs = $datesegs->whereIn('code', $codes);
141
+        }
142
+        $datesegs = $datesegs
143
+            ->groupby('code', \DB::raw("left(cdate, 10)"))
144
+            ->orderByRaw(\DB::raw("code asc, left(cdate, 10) asc"))
145
+            ->get()->toArray();
146
+        
147
+        // 整理返回值並返回
148
+        return $datesegs;
149
+    }
150
+    
151
+    public function getUrlById($id, $oid)
152
+    {
153
+        // 取得參數
154
+        // 調用資料庫(或者其他業務邏輯)
155
+        $url = $this->urlManagementDb
156
+            ->select([
157
+                'serno',
158
+                'title',
159
+                'url',
160
+                \DB::raw("concat('" . env('ORL_URL') . "', code, '') as code"),
161
+                'memo',
162
+                'valid',
163
+            ]);
164
+        // 權限判斷
165
+        if ($oid != GeneralConst::ID_ADMIN) {
166
+            $url = $url
167
+                ->where('oid', '=', $oid);
168
+        }
169
+        $url = $url
170
+            ->where('serno', $id)
171
+            ->first();
172
+        if (is_null($url)) {
173
+            return [];
174
+        }
175
+        $url = $url->toArray();
176
+        
177
+        // 整理返回值並返回
178
+        return $url;
179
+    }
180
+    
181
+    public function insertUrl($title, $url, $code, $memo, $valid, $oid)
182
+    {
183
+        // 取得參數
184
+        // 調用資料庫(或者其他業務邏輯)
185
+        $this->urlManagementDb
186
+            ->insert([
187
+                'title' => $title,
188
+                'url'   => $url,
189
+                'code'  => $code,
190
+                'memo'  => $memo,
191
+                'valid' => $valid,
192
+                'oid'   => $oid,
193
+            ]);
194
+        $id = \DB::getPdo()->lastInsertId();
195
+        
196
+        // 整理返回值並返回
197
+        return $id;
198
+    }
199
+    
200
+    public function getCode()
201
+    {
202
+        // 調用資料庫(或者其他業務邏輯)
203
+        $code = \DB::select(\DB::raw("SELECT fn_GetCodeNew('34679ACDEFGHJKLMNPQRTUVWXY', '!!!!!') as code"));
204
+        
205
+        // 整理返回值並返回
206
+        return $code[0]->code;
207
+    }
208
+    
209
+    public function modifyUrl($id, $title, $url, $memo, $valid)
210
+    {
211
+        // 取得參數
212
+        // 調用資料庫(或者其他業務邏輯)
213
+        $res = $this->urlManagementDb
214
+            ->where('serno', $id)
215
+            ->update([
216
+                'title' => $title,
217
+                // 'url'   => $url, // 收參數是為求程式碼一致性,但業務邏輯不需更改網址
218
+                'memo'  => $memo,
219
+                'valid' => $valid,
220
+            ]);
221
+        
222
+        // 整理返回值並返回
223
+        return $res;
224
+    }
225
+    
226
+    public function getExportUrls($param, $oid)
227
+    {
228
+        // 選欄位
229
+        $validStr = '';
230
+        foreach (GeneralConst::$urlMap as $k => $v) {
231
+            $validStr .= ' when \'' . $k . '\' then \'' . $v . '\'';
232
+        }
233
+        
234
+        $urls = $this->urlManagementDb
235
+            ->select([
236
+                \DB::raw("concat(url) as url"),
237
+                \DB::raw("concat('" . env('ORL_URL') . "', dataManagement_urlManagement.code) as code"),
238
+                'memo',
239
+                \DB::raw("(case valid $validStr end) as valid"),
240
+                \DB::raw("ifnull(uv_count, 0) as pv"),
241
+            ])
242
+            ->leftjoin(\DB::raw("(select v.code, count(*) as uv_count from dataManagement_urlManagement_visit as v where (cdate >= '" . $param['createDateStart'] . " 00:00:00' and cdate <= '" . $param['createDateFinal'] . " 23:59:59') group by v.code) as uv"), 'dataManagement_urlManagement.code', '=', 'uv.code');
243
+        // 過濾搜尋條件
244
+        $urls = $urls
245
+            ->where('title', 'LIKE', '%' . $param['title'] . '%')
246
+            ->where('memo', 'LIKE', '%' . $param['memo'] . '%');
247
+        if ($param['valid'] != GeneralConst::URL_ALL) {
248
+            $urls = $urls->where('valid', '=', $param['valid']);
249
+        }
250
+        // 權限判斷
251
+        if ($oid != GeneralConst::ID_ADMIN) {
252
+            $urls = $urls->where('oid', '=', $oid);
253
+        }
254
+        // 彙整
255
+        $urls = $urls
256
+            ->groupby('dataManagement_urlManagement.code');
257
+        // 實際取資料
258
+        $urls = $urls
259
+            ->get()
260
+            ->toArray();
261
+        
262
+        // 整理返回值並返回
263
+        return $urls;
264
+    }
265
+    
266
+    public function downloadExcel($titles = [], $datas = [], $fileName = 'simple')
267
+    {
268
+        $spreadsheet = new Spreadsheet();
269
+        ini_set('memory_limit', '1024M');
270
+        ini_set("max_execution_time", "600");
271
+        $spreadsheet->getActiveSheet()
272
+            ->fromArray(
273
+                $titles, // The data to set
274
+                null, // Array values with this value will not be set
275
+                'A1' // Top left coordinate of the worksheet range where we want to set these values (default is A1)
276
+            );
277
+        
278
+        $spreadsheet->getActiveSheet()
279
+            ->fromArray(
280
+                $datas, // The data to set
281
+                null, // Array values with this value will not be set
282
+                'A2' // Top left coordinate of the worksheet range where we want to set these values (default is A1)
283
+            );
284
+        
285
+        // Redirect output to a client’s web browser (Xlsx)
286
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
287
+        header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
288
+        header('Cache-Control: max-age=0');
289
+        // If you're serving to IE 9, then the following may be needed
290
+        header('Cache-Control: max-age=1');
291
+        
292
+        // If you're serving to IE over SSL, then the following may be needed
293
+        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
294
+        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
295
+        header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
296
+        header('Pragma: public'); // HTTP/1.0
297
+        
298
+        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
299
+        $writer->save('php://output');
300
+        exit;
301
+    }
302
+    
303
+}

+ 295
- 0
app/Http/Services/Backend/EcManagement/ProductManagementService.php Прегледај датотеку

@@ -0,0 +1,295 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Backend\EcManagement;
4
+
5
+use App\Http\Services\ConstDef\GeneralConst;
6
+use App\Models\EcManagement\ProductManagement;
7
+use PhpOffice\PhpSpreadsheet\IOFactory;
8
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
9
+use Redis;
10
+
11
+class ProductManagementService
12
+{
13
+    
14
+    // 相關私有 model 調用器宣告
15
+    private $productManagementDb;
16
+    
17
+    public function __construct()
18
+    {
19
+        // 建構 model 調用器
20
+        $this->productManagementDb = new ProductManagement();
21
+    }
22
+    
23
+    public function insertProduct($data)
24
+    {
25
+        // 取得參數
26
+        // 調用資料庫(或者其他業務邏輯)
27
+        $res = $this->productManagementDb->insert($data);
28
+        
29
+        // 整理返回值並返回
30
+        return $res;
31
+    }
32
+    
33
+    public function deleteProductByBatchNo($del_batch_no)
34
+    {
35
+        // 取得參數
36
+        // 調用資料庫(或者其他業務邏輯)
37
+        $this->productManagementDb
38
+            ->where('batch_no', '<=', $del_batch_no . ' 23:59:59')
39
+            ->delete();
40
+        
41
+        // 整理返回值並返回
42
+        return true;
43
+    }
44
+    
45
+    public function getProductDetail($brand_no, $batch_no, $g_id)
46
+    {
47
+        // 取得參數
48
+        // 調用資料庫(或者其他業務邏輯)
49
+        $res = $this->productManagementDb
50
+            ->select([
51
+                'm_status',
52
+                'm_comment',
53
+            ])
54
+            ->where('brand_no', $brand_no)
55
+            ->where('batch_no', $batch_no)
56
+            ->where('g_id', (int)$g_id)
57
+            ->get()
58
+            ->toArray();
59
+        
60
+        // 整理返回值並返回
61
+        return $res[0] ?? [
62
+                'm_status'  => '',
63
+                'm_comment' => '',
64
+            ];
65
+    }
66
+    
67
+    public function updateProduct($brand_no, $batch_no, $g_id, $m_status, $m_comment)
68
+    {
69
+        // 取得參數
70
+        // 調用資料庫(或者其他業務邏輯)
71
+        $this->productManagementDb
72
+            ->where('brand_no', $brand_no)
73
+            ->where('batch_no', $batch_no)
74
+            ->where('g_id', (int)$g_id)
75
+            ->update([
76
+                'm_status'  => $m_status,
77
+                'm_comment' => $m_comment,
78
+            ]);
79
+        
80
+        // 整理返回值並返回
81
+        return true;
82
+    }
83
+    
84
+    public function getProdocts(
85
+        &$cnt = 0,
86
+        $orderColumn,
87
+        $orderDir,
88
+        $start,
89
+        $length,
90
+        $searchValue,
91
+        $brand_no,
92
+        $batch_no,
93
+        $g_title,
94
+        $g_description,
95
+        $m_comment,
96
+        $m_status
97
+    )
98
+    {
99
+        // 調用資料庫(或者其他業務邏輯)
100
+        // 選欄位
101
+        // 選欄位
102
+        $mStatusStr = '';
103
+        foreach (GeneralConst::$mStatusMap as $k => $v) {
104
+            $mStatusStr .= ' when \'' . $k . '\' then \'' . $v['ANAME'] . '\'';
105
+        }
106
+        
107
+        $products = $this->productManagementDb
108
+            ->select([
109
+                'serno',
110
+                'g_id',
111
+                \DB::raw('concat(\'<a href="\', g_link, \'" target="_blank">\', g_title, \'</a>\') as g_title'),
112
+                \DB::raw('concat(\'<button type="button" class="btn btn-outline-success btn-sm" data-toggle="popover" title="\', g_title, \'" data-content="\', g_description, \'">\', left(g_description, 10), \' ... </button>\') as g_description'),
113
+                \DB::raw('concat(\'<img src="\', g_image_link, \'" width="100" height="100">\') as g_image_link'),
114
+                'g_price',
115
+                'g_sale_price',
116
+                \DB::raw("(case m_status $mStatusStr end) as m_status"),
117
+                'm_comment',
118
+            ]);
119
+        // 過濾搜尋條件
120
+        $products = $products
121
+            ->where('brand_no', '=', $brand_no)
122
+            ->where('batch_no', '=', $batch_no)
123
+            ->where('g_title', 'LIKE', '%' . $g_title . '%')
124
+            ->where('g_description', 'LIKE', '%' . $g_description . '%')
125
+            ->where('m_comment', 'LIKE', '%' . $m_comment . '%')
126
+            ->where('m_status', '=', $m_status);
127
+        // 取總筆數
128
+        $cnt = $products->count();
129
+        // 排序
130
+        $products = $products
131
+            ->orderByRaw((int)$orderColumn . ' ' . $orderDir);
132
+        // 分頁
133
+        $products = $products
134
+            ->skip($start)->take($length);
135
+        // 實際取資料
136
+        $result = $products
137
+            ->get()
138
+            ->toArray();
139
+        
140
+        // 整理返回值並返回
141
+        return $result;
142
+    }
143
+    
144
+    public function getEndpointProdocts($brand_no, $batch_no)
145
+    {
146
+        $products = $this->productManagementDb
147
+            ->select([
148
+                'g_id',
149
+                'g_title',
150
+                'g_description',
151
+                'g_link',
152
+                'g_image_link',
153
+                'g_condition',
154
+                'g_availability',
155
+                'g_price',
156
+                'g_sale_price',
157
+                'g_brand',
158
+                'g_google_product_category',
159
+                'g_product_type',
160
+                'g_custom_label_0',
161
+            ]);
162
+        // 過濾搜尋條件
163
+        $products = $products
164
+            ->where('brand_no', '=', $brand_no)
165
+            ->where('batch_no', '=', $batch_no)
166
+            ->whereIn('m_status', [GeneralConst::MSTATUS_PASS, GeneralConst::MSTATUS_WARNING]);
167
+        // 實際取資料
168
+        $result = $products
169
+            ->get()
170
+            ->toArray();
171
+        
172
+        // 整理返回值並返回
173
+        return $result;
174
+    }
175
+    
176
+    public function getExportProdocts($param)
177
+    {
178
+        // 調用資料庫(或者其他業務邏輯)
179
+        // 選欄位
180
+        $mStatusStr = '';
181
+        foreach (GeneralConst::$mStatusMap as $k => $v) {
182
+            $mStatusStr .= ' when \'' . $k . '\' then \'' . $v['ANAME'] . '\'';
183
+        }
184
+        $brand_no = $param['brand_no'] ?? '';
185
+        $batch_no = $param['batch_no'] ?? '';
186
+        $products = $this->productManagementDb
187
+            ->select([
188
+                'serno',
189
+                'g_id',
190
+                'g_title',
191
+                'g_description',
192
+                'g_link',
193
+                'g_image_link',
194
+                'g_price',
195
+                'g_sale_price',
196
+                \DB::raw("(case m_status $mStatusStr end) as m_status"),
197
+                'm_comment',
198
+            ]);
199
+        // 過濾搜尋條件
200
+        $products = $products
201
+            ->where('brand_no', '=', $brand_no)
202
+            ->where('batch_no', '=', $batch_no)
203
+            ->whereIn('m_status', [GeneralConst::MSTATUS_WARNING, GeneralConst::MSTATUS_DISAPPROVED]);
204
+        $products = $products
205
+            ->get()
206
+            ->toArray();
207
+        
208
+        // 整理返回值並返回
209
+        return $products;
210
+    }
211
+    
212
+    public function downloadExcel($titles = [], $datas = [], $fileName = 'simple')
213
+    {
214
+        $spreadsheet = new Spreadsheet();
215
+        ini_set('memory_limit', '1024M');
216
+        ini_set("max_execution_time", "600");
217
+        $spreadsheet->getActiveSheet()
218
+            ->fromArray(
219
+                $titles, // The data to set
220
+                null, // Array values with this value will not be set
221
+                'A1' // Top left coordinate of the worksheet range where we want to set these values (default is A1)
222
+            );
223
+        
224
+        $spreadsheet->getActiveSheet()
225
+            ->fromArray(
226
+                $datas, // The data to set
227
+                null, // Array values with this value will not be set
228
+                'A2' // Top left coordinate of the worksheet range where we want to set these values (default is A1)
229
+            );
230
+        
231
+        // Redirect output to a client’s web browser (Xlsx)
232
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
233
+        header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
234
+        header('Cache-Control: max-age=0');
235
+        // If you're serving to IE 9, then the following may be needed
236
+        header('Cache-Control: max-age=1');
237
+        
238
+        // If you're serving to IE over SSL, then the following may be needed
239
+        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
240
+        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
241
+        header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
242
+        header('Pragma: public'); // HTTP/1.0
243
+        
244
+        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
245
+        $writer->save('php://output');
246
+        exit;
247
+    }
248
+    
249
+    public function getBrands()
250
+    {
251
+        $brands = [];
252
+        foreach (GeneralConst::$brandMap as $k => $v) {
253
+            $brands[] = [
254
+                'id'         => $k,
255
+                'brandName'  => $v['NS'],
256
+                'brandLabel' => $v['LB'],
257
+            ];
258
+        }
259
+        
260
+        return $brands;
261
+    }
262
+    
263
+    public function getBatchs()
264
+    {
265
+        $ret = $this->productManagementDb
266
+            ->select([
267
+                'batch_no',
268
+                \DB::raw("max(m_status) as m_status"),
269
+            ])
270
+            ->groupBy('batch_no')
271
+            ->orderBy('batch_no', 'desc')
272
+            ->get()
273
+            ->toArray();
274
+        // 正在抓的批次號需要去除
275
+        if (Redis::get('TLW_0_XML')) {
276
+            array_shift($ret);
277
+        }
278
+        
279
+        return $ret;
280
+    }
281
+    
282
+    public function getMStatuss()
283
+    {
284
+        $mstatuss = [];
285
+        foreach (GeneralConst::$mStatusMap as $k => $v) {
286
+            $mstatuss[] = [
287
+                'id'          => $k,
288
+                'mstatusName' => $v['ANAME'],
289
+            ];
290
+        }
291
+        
292
+        return $mstatuss;
293
+    }
294
+    
295
+}

+ 108
- 0
app/Http/Services/Backend/ZooManagement/TigerManagementService.php Прегледај датотеку

@@ -0,0 +1,108 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Backend\ZooManagement;
4
+
5
+use App\Models\ZooManagement\TigerManagement;
6
+
7
+class TigerManagementService
8
+{
9
+    
10
+    // 相關私有 model 調用器宣告
11
+    private $tigerManagementDb;
12
+    
13
+    public function __construct()
14
+    {
15
+        // 建構 model 調用器
16
+        $this->tigerManagementDb = new TigerManagement();
17
+    }
18
+    
19
+    /**
20
+     * 取得老虎資訊的列表
21
+     *   排序、分頁均未實現
22
+     * @return array:     返回老虎列表的陣列
23
+     */
24
+    public function getTigers()
25
+    {
26
+        // 取得參數
27
+        // 調用資料庫(或者其他業務邏輯)
28
+        $tigers = $this->tigerManagementDb->select(['id', 'tigerName'])->get()->toArray();
29
+        
30
+        // 整理返回值並返回
31
+        return $tigers;
32
+    }
33
+    
34
+    /**
35
+     * 取得單一老虎資訊
36
+     *
37
+     * @param  integer $id : 老虎的自增量
38
+     *
39
+     * @return array:       返回老虎資訊的陣列
40
+     */
41
+    public function getTigerById($id)
42
+    {
43
+        // 取得參數
44
+        // 調用資料庫(或者其他業務邏輯)
45
+        $tigers = $this->tigerManagementDb->select(['id', 'tigerName'])->where('id', $id)->first()->toArray();
46
+        
47
+        // 整理返回值並返回
48
+        return $tigers;
49
+    }
50
+    
51
+    /**
52
+     * 新增老虎
53
+     *
54
+     * @param  string $tigerName : 老虎名字
55
+     *
56
+     * @return bool:               返回新增的操作結果
57
+     */
58
+    public function insertTiger($tigerName)
59
+    {
60
+        // 取得參數
61
+        // 調用資料庫(或者其他業務邏輯)
62
+        $res = $this->tigerManagementDb
63
+            ->insert(['tigerName' => $tigerName]);
64
+        
65
+        // 整理返回值並返回
66
+        return $res;
67
+    }
68
+    
69
+    /**
70
+     * 修改老虎
71
+     *
72
+     * @param  integer $id :        老虎的自增量
73
+     * @param  string  $tigerName : 老虎名字
74
+     *
75
+     * @return bool:                返回修改的操作結果
76
+     */
77
+    public function modifyTiger($id, $tigerName)
78
+    {
79
+        // 取得參數
80
+        // 調用資料庫(或者其他業務邏輯)
81
+        $res = $this->tigerManagementDb
82
+            ->where('id', $id)
83
+            ->update(['tigerName' => $tigerName]);
84
+        
85
+        // 整理返回值並返回
86
+        return $res;
87
+    }
88
+    
89
+    /**
90
+     * 刪除老虎
91
+     *
92
+     * @param  integer $id : 老虎的自增量
93
+     *
94
+     * @return bool:         返回刪除的操作結果
95
+     */
96
+    public function deleteTigerById($id)
97
+    {
98
+        // 取得參數
99
+        // 調用資料庫(或者其他業務邏輯)
100
+        $res = $this->tigerManagementDb
101
+            ->where('id', $id)
102
+            ->delete();
103
+    
104
+        // 整理返回值並返回
105
+        return $res;
106
+    }
107
+    
108
+}

+ 57
- 0
app/Http/Services/CheckParamService.php Прегледај датотеку

@@ -0,0 +1,57 @@
1
+<?php
2
+
3
+namespace App\Http\Services;
4
+
5
+use DateTime;
6
+
7
+class CheckParamService
8
+{
9
+    
10
+    public function __construct()
11
+    {
12
+    }
13
+    
14
+    public function LenMToN($str, $m, $n)
15
+    {
16
+        if (mb_strlen($str) >= $m && mb_strlen($str) <= $n) {
17
+            return true;
18
+        } else {
19
+            return false;
20
+        }
21
+    }
22
+    
23
+    public function isascii($str)
24
+    {
25
+        if (mb_detect_encoding($str) == "ASCII") {
26
+            return true;
27
+        } else {
28
+            return false;
29
+        }
30
+    }
31
+    
32
+    public function isengnum($str)
33
+    {
34
+        return (preg_match("/^[a-zA-Z0-9]+$/", $str) == 1);
35
+    }
36
+    
37
+    public function isnum($str)
38
+    {
39
+        return (preg_match("/^[0-9]+$/", $str) == 1);
40
+    }
41
+    
42
+    public function validateDate($date, $format = 'Y-m-d H:i:s')
43
+    {
44
+        $d = DateTime::createFromFormat($format, $date);
45
+        
46
+        return $d && $d->format($format) == $date;
47
+    }
48
+    
49
+    public function RemoveChars($str, $chars)
50
+    {
51
+        $chars = str_split($chars, 1);
52
+        for ($i = 0; $i < count($chars); $i++) $str = str_replace($chars[ $i ], "", $str);
53
+        
54
+        return $str;
55
+    }
56
+    
57
+}

+ 31
- 0
app/Http/Services/ConstDef/GeneralConst.php Прегледај датотеку

@@ -0,0 +1,31 @@
1
+<?php
2
+
3
+namespace App\Http\Services\ConstDef;
4
+
5
+class GeneralConst
6
+{
7
+    
8
+    // 特殊帳號
9
+    const ID_ADMIN = 1;
10
+    
11
+    // 網址狀態
12
+    const URL_ALL = 0;
13
+    const URL_OK  = 1;
14
+    const URL_NO  = 2;
15
+    public static $urlMap = array(
16
+        self::URL_ALL => '全部',
17
+        self::URL_OK  => '有效',
18
+        self::URL_NO  => '無效',
19
+    );
20
+    
21
+    // API 狀態碼
22
+    const API_OK        = 0;
23
+    const API_TOKEN_ERR = 1;
24
+    const API_PARAM_ERR = 11;
25
+    public static $apiMap = array(
26
+        self::API_OK        => '成功',
27
+        self::API_TOKEN_ERR => 'TOKEN 錯誤',
28
+        self::API_PARAM_ERR => '參數錯誤',
29
+    );
30
+    
31
+}

+ 35
- 0
app/Http/ViewComposers/LeftMenuComposer.php Прегледај датотеку

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+namespace App\Http\ViewComposers;
4
+
5
+use Illuminate\Http\Request;
6
+use Illuminate\View\View;
7
+use App\FunMenu;
8
+use Auth;
9
+
10
+class LeftMenuComposer {
11
+
12
+    protected $user_id;
13
+    protected $user_name;
14
+
15
+    public function __construct()
16
+    {
17
+        if (Auth::check()) {
18
+            // 這個使用者已經登入...
19
+            $user = Auth::user();
20
+
21
+            $this->user_id = $user->id;
22
+            $this->user_name = $user->name;
23
+        } else {
24
+            $this->user_id = 0;
25
+            $this->user_name = "Guest";
26
+        }
27
+    }
28
+
29
+    public function compose(View $view)
30
+    {
31
+        $funmenu = new FunMenu;
32
+        $result = $funmenu->leftmenu($this->user_id);
33
+        $view->with(['leftmenu' => $result, 'username' => $this->user_name]);
34
+    }
35
+}

+ 13
- 0
app/Models/DataManagement/UrlManagement.php Прегледај датотеку

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Models\DataManagement;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class UrlManagement extends Model
8
+{
9
+    protected $connection = 'mysql';                         // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'dataManagement_urlManagement'; // 表名需符合命名規範
11
+    protected $primaryKey = 'serno';                            // PK 的欄位名稱
12
+    public    $timestamps = false;                           // 保持 false
13
+}

+ 13
- 0
app/Models/DataManagement/UrlManagementVisit.php Прегледај датотеку

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Models\DataManagement;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class UrlManagementVisit extends Model
8
+{
9
+    protected $connection = 'mysql';                         // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'dataManagement_urlManagement_visit'; // 表名需符合命名規範
11
+    protected $primaryKey = 'serno';                            // PK 的欄位名稱
12
+    public    $timestamps = false;                           // 保持 false
13
+}

+ 13
- 0
app/Models/EcManagement/ProductManagement.php Прегледај датотеку

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Models\EcManagement;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class ProductManagement extends Model
8
+{
9
+    protected $connection = 'mysql';                         // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'ecManagement_productManagement'; // 表名需符合命名規範
11
+    protected $primaryKey = 'serno';                            // PK 的欄位名稱
12
+    public    $timestamps = false;                           // 保持 false
13
+}

+ 13
- 0
app/Models/ZooManagement/TigerManagement.php Прегледај датотеку

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Models\ZooManagement;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class TigerManagement extends Model
8
+{
9
+    protected $connection = 'mysql';                         // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'zooManagement_tigerManagement'; // 表名需符合命名規範
11
+    protected $primaryKey = 'id';                            // PK 的欄位名稱
12
+    public    $timestamps = false;                           // 保持 false
13
+}

+ 30
- 0
app/Providers/AppServiceProvider.php Прегледај датотеку

@@ -0,0 +1,30 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\ServiceProvider;
6
+use Illuminate\Support\Facades\Schema;
7
+
8
+class AppServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * Bootstrap any application services.
12
+     *
13
+     * @return void
14
+     */
15
+    public function boot()
16
+    {
17
+        //
18
+		Schema::defaultStringLength(191);
19
+    }
20
+
21
+    /**
22
+     * Register any application services.
23
+     *
24
+     * @return void
25
+     */
26
+    public function register()
27
+    {
28
+        //
29
+    }
30
+}

+ 30
- 0
app/Providers/AuthServiceProvider.php Прегледај датотеку

@@ -0,0 +1,30 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\Facades\Gate;
6
+use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
7
+
8
+class AuthServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * The policy mappings for the application.
12
+     *
13
+     * @var array
14
+     */
15
+    protected $policies = [
16
+        'App\Model' => 'App\Policies\ModelPolicy',
17
+    ];
18
+
19
+    /**
20
+     * Register any authentication / authorization services.
21
+     *
22
+     * @return void
23
+     */
24
+    public function boot()
25
+    {
26
+        $this->registerPolicies();
27
+
28
+        //
29
+    }
30
+}

+ 21
- 0
app/Providers/BroadcastServiceProvider.php Прегледај датотеку

@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\ServiceProvider;
6
+use Illuminate\Support\Facades\Broadcast;
7
+
8
+class BroadcastServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * Bootstrap any application services.
12
+     *
13
+     * @return void
14
+     */
15
+    public function boot()
16
+    {
17
+        Broadcast::routes();
18
+
19
+        require base_path('routes/channels.php');
20
+    }
21
+}

+ 34
- 0
app/Providers/ComposerServiceProvider.php Прегледај датотеку

@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use View;
6
+use Illuminate\Support\ServiceProvider;
7
+use Illuminate\Http\Request;
8
+
9
+class ComposerServiceProvider extends ServiceProvider
10
+{
11
+    /**
12
+     * Bootstrap the application services.
13
+     *
14
+     * @return void
15
+     */
16
+    public function boot()
17
+    {
18
+        //
19
+        //dd('something2');
20
+        View::composer(['admin.index', 'admin.uc.leftmenu', 'admin.uc.header'], 'App\Http\ViewComposers\LeftMenuComposer');
21
+        //view()->composer(['admin.index', 'admin.uc.leftmenu', 'admin.uc.header'], 'App\Http\ViewComposers\LeftMenuComposer');
22
+        //$this->app['view']->composer(['admin.index', 'admin.uc.leftmenu', 'admin.uc.header'], 'App\Http\ViewComposers\LeftMenuComposer');
23
+    }
24
+
25
+    /**
26
+     * Register the application services.
27
+     *
28
+     * @return void
29
+     */
30
+    public function register()
31
+    {
32
+        //
33
+    }
34
+}

+ 32
- 0
app/Providers/EventServiceProvider.php Прегледај датотеку

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\Facades\Event;
6
+use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
7
+
8
+class EventServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * The event listener mappings for the application.
12
+     *
13
+     * @var array
14
+     */
15
+    protected $listen = [
16
+        'App\Events\SomeEvent' => [
17
+            'App\Listeners\EventListener',
18
+        ],
19
+    ];
20
+
21
+    /**
22
+     * Register any events for your application.
23
+     *
24
+     * @return void
25
+     */
26
+    public function boot()
27
+    {
28
+        parent::boot();
29
+
30
+        //
31
+    }
32
+}

+ 73
- 0
app/Providers/RouteServiceProvider.php Прегледај датотеку

@@ -0,0 +1,73 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\Facades\Route;
6
+use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
7
+
8
+class RouteServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * This namespace is applied to your controller routes.
12
+     *
13
+     * In addition, it is set as the URL generator's root namespace.
14
+     *
15
+     * @var string
16
+     */
17
+    protected $namespace = 'App\Http\Controllers';
18
+
19
+    /**
20
+     * Define your route model bindings, pattern filters, etc.
21
+     *
22
+     * @return void
23
+     */
24
+    public function boot()
25
+    {
26
+        //
27
+
28
+        parent::boot();
29
+    }
30
+
31
+    /**
32
+     * Define the routes for the application.
33
+     *
34
+     * @return void
35
+     */
36
+    public function map()
37
+    {
38
+        $this->mapApiRoutes();
39
+
40
+        $this->mapWebRoutes();
41
+
42
+        //
43
+    }
44
+
45
+    /**
46
+     * Define the "web" routes for the application.
47
+     *
48
+     * These routes all receive session state, CSRF protection, etc.
49
+     *
50
+     * @return void
51
+     */
52
+    protected function mapWebRoutes()
53
+    {
54
+        Route::middleware('web')
55
+             ->namespace($this->namespace)
56
+             ->group(base_path('routes/web.php'));
57
+    }
58
+
59
+    /**
60
+     * Define the "api" routes for the application.
61
+     *
62
+     * These routes are typically stateless.
63
+     *
64
+     * @return void
65
+     */
66
+    protected function mapApiRoutes()
67
+    {
68
+        Route::prefix('api')
69
+             ->middleware('api')
70
+             ->namespace($this->namespace)
71
+             ->group(base_path('routes/api.php'));
72
+    }
73
+}

+ 32
- 0
app/User.php Прегледај датотеку

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Notifications\Notifiable;
6
+use Illuminate\Foundation\Auth\User as Authenticatable;
7
+
8
+class User extends Authenticatable
9
+{
10
+    use Notifiable;
11
+
12
+    /**
13
+     * The attributes that are mass assignable.
14
+     *
15
+     * @var array
16
+     */
17
+    protected $fillable = [
18
+        'name',
19
+        'email',
20
+        'password',
21
+    ];
22
+
23
+    /**
24
+     * The attributes that should be hidden for arrays.
25
+     *
26
+     * @var array
27
+     */
28
+    protected $hidden = [
29
+        'password',
30
+        'remember_token',
31
+    ];
32
+}

+ 51
- 0
artisan Прегледај датотеку

@@ -0,0 +1,51 @@
1
+#!/usr/bin/env php
2
+<?php
3
+
4
+/*
5
+|--------------------------------------------------------------------------
6
+| Register The Auto Loader
7
+|--------------------------------------------------------------------------
8
+|
9
+| Composer provides a convenient, automatically generated class loader
10
+| for our application. We just need to utilize it! We'll require it
11
+| into the script here so that we do not have to worry about the
12
+| loading of any our classes "manually". Feels great to relax.
13
+|
14
+*/
15
+
16
+require __DIR__.'/bootstrap/autoload.php';
17
+
18
+$app = require_once __DIR__.'/bootstrap/app.php';
19
+
20
+/*
21
+|--------------------------------------------------------------------------
22
+| Run The Artisan Application
23
+|--------------------------------------------------------------------------
24
+|
25
+| When we run the console application, the current CLI command will be
26
+| executed in this console and the response sent back to a terminal
27
+| or another output device for the developers. Here goes nothing!
28
+|
29
+*/
30
+
31
+$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
32
+
33
+$status = $kernel->handle(
34
+    $input = new Symfony\Component\Console\Input\ArgvInput,
35
+    new Symfony\Component\Console\Output\ConsoleOutput
36
+);
37
+
38
+/*
39
+|--------------------------------------------------------------------------
40
+| Shutdown The Application
41
+|--------------------------------------------------------------------------
42
+|
43
+| Once Artisan has finished running. We will fire off the shutdown events
44
+| so that any final work may be done by the application before we shut
45
+| down the process. This is the last thing to happen to the request.
46
+|
47
+*/
48
+
49
+$kernel->terminate($input, $status);
50
+
51
+exit($status);

+ 64
- 0
bootstrap/app.php Прегледај датотеку

@@ -0,0 +1,64 @@
1
+<?php
2
+
3
+/*
4
+|--------------------------------------------------------------------------
5
+| Create The Application
6
+|--------------------------------------------------------------------------
7
+|
8
+| The first thing we will do is create a new Laravel application instance
9
+| which serves as the "glue" for all the components of Laravel, and is
10
+| the IoC container for the system binding all of the various parts.
11
+|
12
+*/
13
+
14
+$app = new Illuminate\Foundation\Application(
15
+    realpath(__DIR__.'/../')
16
+);
17
+
18
+/*
19
+|--------------------------------------------------------------------------
20
+| Bind Important Interfaces
21
+|--------------------------------------------------------------------------
22
+|
23
+| Next, we need to bind some important interfaces into the container so
24
+| we will be able to resolve them when needed. The kernels serve the
25
+| incoming requests to this application from both the web and CLI.
26
+|
27
+*/
28
+
29
+$app->singleton(
30
+    Illuminate\Contracts\Http\Kernel::class,
31
+    App\Http\Kernel::class
32
+);
33
+
34
+$app->singleton(
35
+    Illuminate\Contracts\Console\Kernel::class,
36
+    App\Console\Kernel::class
37
+);
38
+
39
+$app->singleton(
40
+    Illuminate\Contracts\Debug\ExceptionHandler::class,
41
+    App\Exceptions\Handler::class
42
+);
43
+
44
+/*
45
+|--------------------------------------------------------------------------
46
+| Return The Application
47
+|--------------------------------------------------------------------------
48
+|
49
+| This script returns the application instance. The instance is given to
50
+| the calling script so we can separate the building of the instances
51
+| from the actual running of the application and sending responses.
52
+|
53
+*/
54
+
55
+// 環境偵測(需要事先在 php.ini 中做好相關設定,若線上環境不支援修改則直接套用預設的 .env)
56
+$ore = 'dev';
57
+$compare = __DIR__;
58
+$ore = (str_replace('www', '', $compare) != $compare) ? 'pro' : $ore;
59
+if(!defined('APP_MODE')){
60
+    define('APP_MODE', $ore);
61
+}
62
+$app->loadEnvironmentFrom('.env.'.$ore);
63
+
64
+return $app;

+ 17
- 0
bootstrap/autoload.php Прегледај датотеку

@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+define('LARAVEL_START', microtime(true));
4
+
5
+/*
6
+|--------------------------------------------------------------------------
7
+| Register The Composer Auto Loader
8
+|--------------------------------------------------------------------------
9
+|
10
+| Composer provides a convenient, automatically generated class loader
11
+| for our application. We just need to utilize it! We'll require it
12
+| into the script here so that we do not have to worry about the
13
+| loading of any our classes "manually". Feels great to relax.
14
+|
15
+*/
16
+
17
+require __DIR__.'/../vendor/autoload.php';

+ 2
- 0
bootstrap/cache/.gitignore Прегледај датотеку

@@ -0,0 +1,2 @@
1
+*
2
+!.gitignore

+ 62
- 0
composer.json Прегледај датотеку

@@ -0,0 +1,62 @@
1
+{
2
+    "name": "laravel/laravel",
3
+    "description": "The Laravel Framework.",
4
+    "keywords": ["framework", "laravel"],
5
+    "license": "MIT",
6
+    "type": "project",
7
+    "require": {
8
+        "php": ">=5.6.4",
9
+        "aws/aws-sdk-php-laravel": "~3.0",
10
+        "chillerlan/php-qrcode": "^3.3",
11
+        "fideloper/proxy": "^4.4",
12
+        "intervention/image": "^2.3",
13
+        "laravel/framework": "5.5.*",
14
+        "laravel/tinker": "~1.0",
15
+        "league/flysystem-aws-s3-v3": "~1.0",
16
+        "phpoffice/phpspreadsheet": "^1.14",
17
+        "predis/predis": "^1.1"
18
+    },
19
+    "require-dev": {
20
+        "fzaninotto/faker": "~1.4",
21
+        "mockery/mockery": "0.9.*",
22
+        "phpunit/phpunit": "~6.0",
23
+		"filp/whoops": "~2.0"
24
+    },
25
+    "autoload": {
26
+        "classmap": [
27
+            "database"
28
+        ],
29
+        "psr-4": {
30
+            "App\\": "app/"
31
+        }
32
+    },
33
+    "autoload-dev": {
34
+        "psr-4": {
35
+            "Tests\\": "tests/"
36
+        }
37
+    },
38
+    "scripts": {
39
+        "post-root-package-install": [
40
+            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
41
+        ],
42
+        "post-create-project-cmd": [
43
+            "php artisan key:generate"
44
+        ],
45
+        "post-install-cmd": [
46
+            "Illuminate\\Foundation\\ComposerScripts::postInstall",
47
+            "php artisan optimize"
48
+        ],
49
+        "post-update-cmd": [
50
+            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
51
+            "php artisan optimize"
52
+        ],
53
+		"post-autoload-dump": [
54
+			"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
55
+			"@php artisan package:discover"
56
+		]
57
+    },
58
+    "config": {
59
+        "preferred-install": "dist",
60
+        "sort-packages": true
61
+    }
62
+}

+ 5016
- 0
composer.lock
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 235
- 0
config/app.php Прегледај датотеку

@@ -0,0 +1,235 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Application Name
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This value is the name of your application. This value is used when the
11
+    | framework needs to place the application's name in a notification or
12
+    | any other location as required by the application or its packages.
13
+    */
14
+
15
+    'name' => 'Laravel',
16
+
17
+    /*
18
+    |--------------------------------------------------------------------------
19
+    | Application Environment
20
+    |--------------------------------------------------------------------------
21
+    |
22
+    | This value determines the "environment" your application is currently
23
+    | running in. This may determine how you prefer to configure various
24
+    | services your application utilizes. Set this in your ".env" file.
25
+    |
26
+    */
27
+
28
+    'env' => env('APP_ENV', 'production'),
29
+
30
+    /*
31
+    |--------------------------------------------------------------------------
32
+    | Application Debug Mode
33
+    |--------------------------------------------------------------------------
34
+    |
35
+    | When your application is in debug mode, detailed error messages with
36
+    | stack traces will be shown on every error that occurs within your
37
+    | application. If disabled, a simple generic error page is shown.
38
+    |
39
+    */
40
+
41
+    'debug' => env('APP_DEBUG', false),
42
+
43
+    /*
44
+    |--------------------------------------------------------------------------
45
+    | Application URL
46
+    |--------------------------------------------------------------------------
47
+    |
48
+    | This URL is used by the console to properly generate URLs when using
49
+    | the Artisan command line tool. You should set this to the root of
50
+    | your application so that it is used when running Artisan tasks.
51
+    |
52
+    */
53
+
54
+    'url' => env('APP_URL', 'http://localhost'),
55
+
56
+    /*
57
+    |--------------------------------------------------------------------------
58
+    | Application Timezone
59
+    |--------------------------------------------------------------------------
60
+    |
61
+    | Here you may specify the default timezone for your application, which
62
+    | will be used by the PHP date and date-time functions. We have gone
63
+    | ahead and set this to a sensible default for you out of the box.
64
+    |
65
+    */
66
+
67
+    'timezone' => 'UTC',
68
+
69
+    /*
70
+    |--------------------------------------------------------------------------
71
+    | Application Locale Configuration
72
+    |--------------------------------------------------------------------------
73
+    |
74
+    | The application locale determines the default locale that will be used
75
+    | by the translation service provider. You are free to set this value
76
+    | to any of the locales which will be supported by the application.
77
+    |
78
+    */
79
+
80
+    'locale' => 'en',
81
+
82
+    /*
83
+    |--------------------------------------------------------------------------
84
+    | Application Fallback Locale
85
+    |--------------------------------------------------------------------------
86
+    |
87
+    | The fallback locale determines the locale to use when the current one
88
+    | is not available. You may change the value to correspond to any of
89
+    | the language folders that are provided through your application.
90
+    |
91
+    */
92
+
93
+    'fallback_locale' => 'en',
94
+
95
+    /*
96
+    |--------------------------------------------------------------------------
97
+    | Encryption Key
98
+    |--------------------------------------------------------------------------
99
+    |
100
+    | This key is used by the Illuminate encrypter service and should be set
101
+    | to a random, 32 character string, otherwise these encrypted strings
102
+    | will not be safe. Please do this before deploying an application!
103
+    |
104
+    */
105
+
106
+    'key' => env('APP_KEY'),
107
+
108
+    'cipher' => 'AES-256-CBC',
109
+
110
+    /*
111
+    |--------------------------------------------------------------------------
112
+    | Logging Configuration
113
+    |--------------------------------------------------------------------------
114
+    |
115
+    | Here you may configure the log settings for your application. Out of
116
+    | the box, Laravel uses the Monolog PHP logging library. This gives
117
+    | you a variety of powerful log handlers / formatters to utilize.
118
+    |
119
+    | Available Settings: "single", "daily", "syslog", "errorlog"
120
+    |
121
+    */
122
+
123
+    'log' => env('APP_LOG', 'single'),
124
+
125
+    'log_level' => env('APP_LOG_LEVEL', 'debug'),
126
+
127
+    /*
128
+    |--------------------------------------------------------------------------
129
+    | Autoloaded Service Providers
130
+    |--------------------------------------------------------------------------
131
+    |
132
+    | The service providers listed here will be automatically loaded on the
133
+    | request to your application. Feel free to add your own services to
134
+    | this array to grant expanded functionality to your applications.
135
+    |
136
+    */
137
+
138
+    'providers' => [
139
+
140
+        /*
141
+         * Laravel Framework Service Providers...
142
+         */
143
+        Illuminate\Auth\AuthServiceProvider::class,
144
+        Illuminate\Broadcasting\BroadcastServiceProvider::class,
145
+        Illuminate\Bus\BusServiceProvider::class,
146
+        Illuminate\Cache\CacheServiceProvider::class,
147
+        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
148
+        Illuminate\Cookie\CookieServiceProvider::class,
149
+        Illuminate\Database\DatabaseServiceProvider::class,
150
+        Illuminate\Encryption\EncryptionServiceProvider::class,
151
+        Illuminate\Filesystem\FilesystemServiceProvider::class,
152
+        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
153
+        Illuminate\Hashing\HashServiceProvider::class,
154
+        Illuminate\Mail\MailServiceProvider::class,
155
+        Illuminate\Notifications\NotificationServiceProvider::class,
156
+        Illuminate\Pagination\PaginationServiceProvider::class,
157
+        Illuminate\Pipeline\PipelineServiceProvider::class,
158
+        Illuminate\Queue\QueueServiceProvider::class,
159
+        Illuminate\Redis\RedisServiceProvider::class,
160
+        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
161
+        Illuminate\Session\SessionServiceProvider::class,
162
+        Illuminate\Translation\TranslationServiceProvider::class,
163
+        Illuminate\Validation\ValidationServiceProvider::class,
164
+        Illuminate\View\ViewServiceProvider::class,
165
+
166
+        /*
167
+         * Package Service Providers...
168
+         */
169
+        Laravel\Tinker\TinkerServiceProvider::class,
170
+
171
+        /*
172
+         * Application Service Providers...
173
+         */
174
+        App\Providers\AppServiceProvider::class,
175
+        App\Providers\AuthServiceProvider::class,
176
+        // App\Providers\BroadcastServiceProvider::class,
177
+        App\Providers\EventServiceProvider::class,
178
+        App\Providers\RouteServiceProvider::class,
179
+
180
+        App\Providers\ComposerServiceProvider::class,
181
+        Intervention\Image\ImageServiceProvider::class,
182
+
183
+    ],
184
+
185
+    /*
186
+    |--------------------------------------------------------------------------
187
+    | Class Aliases
188
+    |--------------------------------------------------------------------------
189
+    |
190
+    | This array of class aliases will be registered when this application
191
+    | is started. However, feel free to register as many as you wish as
192
+    | the aliases are "lazy" loaded so they don't hinder performance.
193
+    |
194
+    */
195
+
196
+    'aliases' => [
197
+
198
+        'App' => Illuminate\Support\Facades\App::class,
199
+        'Artisan' => Illuminate\Support\Facades\Artisan::class,
200
+        'Auth' => Illuminate\Support\Facades\Auth::class,
201
+        'Blade' => Illuminate\Support\Facades\Blade::class,
202
+        'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
203
+        'Bus' => Illuminate\Support\Facades\Bus::class,
204
+        'Cache' => Illuminate\Support\Facades\Cache::class,
205
+        'Config' => Illuminate\Support\Facades\Config::class,
206
+        'Cookie' => Illuminate\Support\Facades\Cookie::class,
207
+        'Crypt' => Illuminate\Support\Facades\Crypt::class,
208
+        'DB' => Illuminate\Support\Facades\DB::class,
209
+        'Eloquent' => Illuminate\Database\Eloquent\Model::class,
210
+        'Event' => Illuminate\Support\Facades\Event::class,
211
+        'File' => Illuminate\Support\Facades\File::class,
212
+        'Gate' => Illuminate\Support\Facades\Gate::class,
213
+        'Hash' => Illuminate\Support\Facades\Hash::class,
214
+        'Lang' => Illuminate\Support\Facades\Lang::class,
215
+        'Log' => Illuminate\Support\Facades\Log::class,
216
+        'Mail' => Illuminate\Support\Facades\Mail::class,
217
+        'Notification' => Illuminate\Support\Facades\Notification::class,
218
+        'Password' => Illuminate\Support\Facades\Password::class,
219
+        'Queue' => Illuminate\Support\Facades\Queue::class,
220
+        'Redirect' => Illuminate\Support\Facades\Redirect::class,
221
+        'Redis' => Illuminate\Support\Facades\Redis::class,
222
+        'Request' => Illuminate\Support\Facades\Request::class,
223
+        'Response' => Illuminate\Support\Facades\Response::class,
224
+        'Route' => Illuminate\Support\Facades\Route::class,
225
+        'Schema' => Illuminate\Support\Facades\Schema::class,
226
+        'Session' => Illuminate\Support\Facades\Session::class,
227
+        'Storage' => Illuminate\Support\Facades\Storage::class,
228
+        'URL' => Illuminate\Support\Facades\URL::class,
229
+        'Validator' => Illuminate\Support\Facades\Validator::class,
230
+        'View' => Illuminate\Support\Facades\View::class,
231
+        'Image' => Intervention\Image\Facades\Image::class,
232
+
233
+    ],
234
+
235
+];

+ 102
- 0
config/auth.php Прегледај датотеку

@@ -0,0 +1,102 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Authentication Defaults
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default authentication "guard" and password
11
+    | reset options for your application. You may change these defaults
12
+    | as required, but they're a perfect start for most applications.
13
+    |
14
+    */
15
+
16
+    'defaults' => [
17
+        'guard' => 'web',
18
+        'passwords' => 'users',
19
+    ],
20
+
21
+    /*
22
+    |--------------------------------------------------------------------------
23
+    | Authentication Guards
24
+    |--------------------------------------------------------------------------
25
+    |
26
+    | Next, you may define every authentication guard for your application.
27
+    | Of course, a great default configuration has been defined for you
28
+    | here which uses session storage and the Eloquent user provider.
29
+    |
30
+    | All authentication drivers have a user provider. This defines how the
31
+    | users are actually retrieved out of your database or other storage
32
+    | mechanisms used by this application to persist your user's data.
33
+    |
34
+    | Supported: "session", "token"
35
+    |
36
+    */
37
+
38
+    'guards' => [
39
+        'web' => [
40
+            'driver' => 'session',
41
+            'provider' => 'users',
42
+        ],
43
+
44
+        'api' => [
45
+            'driver' => 'token',
46
+            'provider' => 'users',
47
+        ],
48
+    ],
49
+
50
+    /*
51
+    |--------------------------------------------------------------------------
52
+    | User Providers
53
+    |--------------------------------------------------------------------------
54
+    |
55
+    | All authentication drivers have a user provider. This defines how the
56
+    | users are actually retrieved out of your database or other storage
57
+    | mechanisms used by this application to persist your user's data.
58
+    |
59
+    | If you have multiple user tables or models you may configure multiple
60
+    | sources which represent each model / table. These sources may then
61
+    | be assigned to any extra authentication guards you have defined.
62
+    |
63
+    | Supported: "database", "eloquent"
64
+    |
65
+    */
66
+
67
+    'providers' => [
68
+        'users' => [
69
+            'driver' => 'eloquent',
70
+            'model' => App\User::class,
71
+        ],
72
+
73
+        // 'users' => [
74
+        //     'driver' => 'database',
75
+        //     'table' => 'users',
76
+        // ],
77
+    ],
78
+
79
+    /*
80
+    |--------------------------------------------------------------------------
81
+    | Resetting Passwords
82
+    |--------------------------------------------------------------------------
83
+    |
84
+    | You may specify multiple password reset configurations if you have more
85
+    | than one user table or model in the application and you want to have
86
+    | separate password reset settings based on the specific user types.
87
+    |
88
+    | The expire time is the number of minutes that the reset token should be
89
+    | considered valid. This security feature keeps tokens short-lived so
90
+    | they have less time to be guessed. You may change this as needed.
91
+    |
92
+    */
93
+
94
+    'passwords' => [
95
+        'users' => [
96
+            'provider' => 'users',
97
+            'table' => 'password_resets',
98
+            'expire' => 60,
99
+        ],
100
+    ],
101
+
102
+];

+ 58
- 0
config/broadcasting.php Прегледај датотеку

@@ -0,0 +1,58 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Broadcaster
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default broadcaster that will be used by the
11
+    | framework when an event needs to be broadcast. You may set this to
12
+    | any of the connections defined in the "connections" array below.
13
+    |
14
+    | Supported: "pusher", "redis", "log", "null"
15
+    |
16
+    */
17
+
18
+    'default' => env('BROADCAST_DRIVER', 'null'),
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Broadcast Connections
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | Here you may define all of the broadcast connections that will be used
26
+    | to broadcast events to other systems or over websockets. Samples of
27
+    | each available type of connection are provided inside this array.
28
+    |
29
+    */
30
+
31
+    'connections' => [
32
+
33
+        'pusher' => [
34
+            'driver' => 'pusher',
35
+            'key' => env('PUSHER_APP_KEY'),
36
+            'secret' => env('PUSHER_APP_SECRET'),
37
+            'app_id' => env('PUSHER_APP_ID'),
38
+            'options' => [
39
+                //
40
+            ],
41
+        ],
42
+
43
+        'redis' => [
44
+            'driver' => 'redis',
45
+            'connection' => 'default',
46
+        ],
47
+
48
+        'log' => [
49
+            'driver' => 'log',
50
+        ],
51
+
52
+        'null' => [
53
+            'driver' => 'null',
54
+        ],
55
+
56
+    ],
57
+
58
+];

+ 91
- 0
config/cache.php Прегледај датотеку

@@ -0,0 +1,91 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Cache Store
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default cache connection that gets used while
11
+    | using this caching library. This connection is used when another is
12
+    | not explicitly specified when executing a given caching function.
13
+    |
14
+    | Supported: "apc", "array", "database", "file", "memcached", "redis"
15
+    |
16
+    */
17
+
18
+    'default' => env('CACHE_DRIVER', 'file'),
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Cache Stores
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | Here you may define all of the cache "stores" for your application as
26
+    | well as their drivers. You may even define multiple stores for the
27
+    | same cache driver to group types of items stored in your caches.
28
+    |
29
+    */
30
+
31
+    'stores' => [
32
+
33
+        'apc' => [
34
+            'driver' => 'apc',
35
+        ],
36
+
37
+        'array' => [
38
+            'driver' => 'array',
39
+        ],
40
+
41
+        'database' => [
42
+            'driver' => 'database',
43
+            'table' => 'cache',
44
+            'connection' => null,
45
+        ],
46
+
47
+        'file' => [
48
+            'driver' => 'file',
49
+            'path' => storage_path('framework/cache/data'),
50
+        ],
51
+
52
+        'memcached' => [
53
+            'driver' => 'memcached',
54
+            'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
55
+            'sasl' => [
56
+                env('MEMCACHED_USERNAME'),
57
+                env('MEMCACHED_PASSWORD'),
58
+            ],
59
+            'options' => [
60
+                // Memcached::OPT_CONNECT_TIMEOUT  => 2000,
61
+            ],
62
+            'servers' => [
63
+                [
64
+                    'host' => env('MEMCACHED_HOST', '127.0.0.1'),
65
+                    'port' => env('MEMCACHED_PORT', 11211),
66
+                    'weight' => 100,
67
+                ],
68
+            ],
69
+        ],
70
+
71
+        'redis' => [
72
+            'driver' => 'redis',
73
+            'connection' => 'default',
74
+        ],
75
+
76
+    ],
77
+
78
+    /*
79
+    |--------------------------------------------------------------------------
80
+    | Cache Key Prefix
81
+    |--------------------------------------------------------------------------
82
+    |
83
+    | When utilizing a RAM based store such as APC or Memcached, there might
84
+    | be other applications utilizing the same cache. So, we'll specify a
85
+    | value to get prefixed to all our keys so we can avoid collisions.
86
+    |
87
+    */
88
+
89
+    'prefix' => 'laravel',
90
+
91
+];

+ 108
- 0
config/database.php Прегледај датотеку

@@ -0,0 +1,108 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Database Connection Name
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Here you may specify which of the database connections below you wish
11
+    | to use as your default connection for all database work. Of course
12
+    | you may use many connections at once using the Database library.
13
+    |
14
+    */
15
+
16
+    'default' => env('DB_CONNECTION', 'mysql'),
17
+
18
+    /*
19
+    |--------------------------------------------------------------------------
20
+    | Database Connections
21
+    |--------------------------------------------------------------------------
22
+    |
23
+    | Here are each of the database connections setup for your application.
24
+    | Of course, examples of configuring each database platform that is
25
+    | supported by Laravel is shown below to make development simple.
26
+    |
27
+    |
28
+    | All database work in Laravel is done through the PHP PDO facilities
29
+    | so make sure you have the driver for your particular database of
30
+    | choice installed on your machine before you begin development.
31
+    |
32
+    */
33
+
34
+    'connections' => [
35
+
36
+        'sqlite' => [
37
+            'driver' => 'sqlite',
38
+            'database' => env('DB_DATABASE', database_path('database.sqlite')),
39
+            'prefix' => '',
40
+        ],
41
+
42
+        'mysql' => [
43
+            'driver' => 'mysql',
44
+            'host' => env('DB_HOST', '127.0.0.1'),
45
+            'port' => env('DB_PORT', '3306'),
46
+            'database' => env('DB_DATABASE', 'forge'),
47
+            'username' => env('DB_USERNAME', 'forge'),
48
+            'password' => env('DB_PASSWORD', ''),
49
+            'charset' => 'utf8mb4',
50
+            'collation' => 'utf8mb4_unicode_ci',
51
+            'prefix' => '',
52
+            'strict' => false, # 設置 false 避免後台選單的複合 SQL 造成 only_full_group_by 權限問題
53
+            'engine' => null,
54
+        ],
55
+
56
+        'pgsql' => [
57
+            'driver' => 'pgsql',
58
+            'host' => env('DB_HOST', '127.0.0.1'),
59
+            'port' => env('DB_PORT', '5432'),
60
+            'database' => env('DB_DATABASE', 'forge'),
61
+            'username' => env('DB_USERNAME', 'forge'),
62
+            'password' => env('DB_PASSWORD', ''),
63
+            'charset' => 'utf8',
64
+            'prefix' => '',
65
+            'schema' => 'public',
66
+            'sslmode' => 'prefer',
67
+        ],
68
+
69
+    ],
70
+
71
+    /*
72
+    |--------------------------------------------------------------------------
73
+    | Migration Repository Table
74
+    |--------------------------------------------------------------------------
75
+    |
76
+    | This table keeps track of all the migrations that have already run for
77
+    | your application. Using this information, we can determine which of
78
+    | the migrations on disk haven't actually been run in the database.
79
+    |
80
+    */
81
+
82
+    'migrations' => 'migrations',
83
+
84
+    /*
85
+    |--------------------------------------------------------------------------
86
+    | Redis Databases
87
+    |--------------------------------------------------------------------------
88
+    |
89
+    | Redis is an open source, fast, and advanced key-value store that also
90
+    | provides a richer set of commands than a typical key-value systems
91
+    | such as APC or Memcached. Laravel makes it easy to dig right in.
92
+    |
93
+    */
94
+
95
+    'redis' => [
96
+
97
+        'client' => 'predis',
98
+
99
+        'default' => [
100
+            'host' => env('REDIS_HOST', '127.0.0.1'),
101
+            'password' => env('REDIS_PASSWORD', null),
102
+            'port' => env('REDIS_PORT', 6379),
103
+            'database' => 0,
104
+        ],
105
+
106
+    ],
107
+
108
+];

+ 68
- 0
config/filesystems.php Прегледај датотеку

@@ -0,0 +1,68 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Filesystem Disk
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Here you may specify the default filesystem disk that should be used
11
+    | by the framework. The "local" disk, as well as a variety of cloud
12
+    | based disks are available to your application. Just store away!
13
+    |
14
+    */
15
+
16
+    'default' => 'local',
17
+
18
+    /*
19
+    |--------------------------------------------------------------------------
20
+    | Default Cloud Filesystem Disk
21
+    |--------------------------------------------------------------------------
22
+    |
23
+    | Many applications store files both locally and in the cloud. For this
24
+    | reason, you may specify a default "cloud" driver here. This driver
25
+    | will be bound as the Cloud disk implementation in the container.
26
+    |
27
+    */
28
+
29
+    'cloud' => 's3',
30
+
31
+    /*
32
+    |--------------------------------------------------------------------------
33
+    | Filesystem Disks
34
+    |--------------------------------------------------------------------------
35
+    |
36
+    | Here you may configure as many filesystem "disks" as you wish, and you
37
+    | may even configure multiple disks of the same driver. Defaults have
38
+    | been setup for each driver as an example of the required options.
39
+    |
40
+    | Supported Drivers: "local", "ftp", "s3", "rackspace"
41
+    |
42
+    */
43
+
44
+    'disks' => [
45
+
46
+        'local' => [
47
+            'driver' => 'local',
48
+            'root' => storage_path('app'),
49
+        ],
50
+
51
+        'public' => [
52
+            'driver' => 'local',
53
+            'root' => storage_path('app/public'),
54
+            'url' => env('APP_URL').'/storage',
55
+            'visibility' => 'public',
56
+        ],
57
+
58
+        's3' => [
59
+            'driver' => 's3',
60
+            'key' => env('AWS_KEY'),
61
+            'secret' => env('AWS_SECRET'),
62
+            'region' => env('AWS_REGION'),
63
+            'bucket' => env('AWS_BUCKET'),
64
+        ],
65
+
66
+    ],
67
+
68
+];

+ 20
- 0
config/image.php Прегледај датотеку

@@ -0,0 +1,20 @@
1
+<?php
2
+
3
+return array(
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Image Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Intervention Image supports "GD Library" and "Imagick" to process images
11
+    | internally. You may choose one of them according to your PHP
12
+    | configuration. By default PHP's "GD Library" implementation is used.
13
+    |
14
+    | Supported: "gd", "imagick"
15
+    |
16
+    */
17
+
18
+    'driver' => 'gd'
19
+
20
+);

+ 123
- 0
config/mail.php Прегледај датотеку

@@ -0,0 +1,123 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Mail Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Laravel supports both SMTP and PHP's "mail" function as drivers for the
11
+    | sending of e-mail. You may specify which one you're using throughout
12
+    | your application here. By default, Laravel is setup for SMTP mail.
13
+    |
14
+    | Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
15
+    |            "sparkpost", "log", "array"
16
+    |
17
+    */
18
+
19
+    'driver' => env('MAIL_DRIVER', 'smtp'),
20
+
21
+    /*
22
+    |--------------------------------------------------------------------------
23
+    | SMTP Host Address
24
+    |--------------------------------------------------------------------------
25
+    |
26
+    | Here you may provide the host address of the SMTP server used by your
27
+    | applications. A default option is provided that is compatible with
28
+    | the Mailgun mail service which will provide reliable deliveries.
29
+    |
30
+    */
31
+
32
+    'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
33
+
34
+    /*
35
+    |--------------------------------------------------------------------------
36
+    | SMTP Host Port
37
+    |--------------------------------------------------------------------------
38
+    |
39
+    | This is the SMTP port used by your application to deliver e-mails to
40
+    | users of the application. Like the host we have set this value to
41
+    | stay compatible with the Mailgun e-mail application by default.
42
+    |
43
+    */
44
+
45
+    'port' => env('MAIL_PORT', 587),
46
+
47
+    /*
48
+    |--------------------------------------------------------------------------
49
+    | Global "From" Address
50
+    |--------------------------------------------------------------------------
51
+    |
52
+    | You may wish for all e-mails sent by your application to be sent from
53
+    | the same address. Here, you may specify a name and address that is
54
+    | used globally for all e-mails that are sent by your application.
55
+    |
56
+    */
57
+
58
+    'from' => [
59
+        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
60
+        'name' => env('MAIL_FROM_NAME', 'Example'),
61
+    ],
62
+
63
+    /*
64
+    |--------------------------------------------------------------------------
65
+    | E-Mail Encryption Protocol
66
+    |--------------------------------------------------------------------------
67
+    |
68
+    | Here you may specify the encryption protocol that should be used when
69
+    | the application send e-mail messages. A sensible default using the
70
+    | transport layer security protocol should provide great security.
71
+    |
72
+    */
73
+
74
+    'encryption' => env('MAIL_ENCRYPTION', 'tls'),
75
+
76
+    /*
77
+    |--------------------------------------------------------------------------
78
+    | SMTP Server Username
79
+    |--------------------------------------------------------------------------
80
+    |
81
+    | If your SMTP server requires a username for authentication, you should
82
+    | set it here. This will get used to authenticate with your server on
83
+    | connection. You may also set the "password" value below this one.
84
+    |
85
+    */
86
+
87
+    'username' => env('MAIL_USERNAME'),
88
+
89
+    'password' => env('MAIL_PASSWORD'),
90
+
91
+    /*
92
+    |--------------------------------------------------------------------------
93
+    | Sendmail System Path
94
+    |--------------------------------------------------------------------------
95
+    |
96
+    | When using the "sendmail" driver to send e-mails, we will need to know
97
+    | the path to where Sendmail lives on this server. A default path has
98
+    | been provided here, which will work well on most of your systems.
99
+    |
100
+    */
101
+
102
+    'sendmail' => '/usr/sbin/sendmail -bs',
103
+
104
+    /*
105
+    |--------------------------------------------------------------------------
106
+    | Markdown Mail Settings
107
+    |--------------------------------------------------------------------------
108
+    |
109
+    | If you are using Markdown based email rendering, you may configure your
110
+    | theme and component paths here, allowing you to customize the design
111
+    | of the emails. Or, you may simply stick with the Laravel defaults!
112
+    |
113
+    */
114
+
115
+    'markdown' => [
116
+        'theme' => 'default',
117
+
118
+        'paths' => [
119
+            resource_path('views/vendor/mail'),
120
+        ],
121
+    ],
122
+
123
+];

+ 85
- 0
config/queue.php Прегледај датотеку

@@ -0,0 +1,85 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Queue Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Laravel's queue API supports an assortment of back-ends via a single
11
+    | API, giving you convenient access to each back-end using the same
12
+    | syntax for each one. Here you may set the default queue driver.
13
+    |
14
+    | Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null"
15
+    |
16
+    */
17
+
18
+    'default' => env('QUEUE_DRIVER', 'sync'),
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Queue Connections
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | Here you may configure the connection information for each server that
26
+    | is used by your application. A default configuration has been added
27
+    | for each back-end shipped with Laravel. You are free to add more.
28
+    |
29
+    */
30
+
31
+    'connections' => [
32
+
33
+        'sync' => [
34
+            'driver' => 'sync',
35
+        ],
36
+
37
+        'database' => [
38
+            'driver' => 'database',
39
+            'table' => 'jobs',
40
+            'queue' => 'default',
41
+            'retry_after' => 90,
42
+        ],
43
+
44
+        'beanstalkd' => [
45
+            'driver' => 'beanstalkd',
46
+            'host' => 'localhost',
47
+            'queue' => 'default',
48
+            'retry_after' => 90,
49
+        ],
50
+
51
+        'sqs' => [
52
+            'driver' => 'sqs',
53
+            'key' => 'your-public-key',
54
+            'secret' => 'your-secret-key',
55
+            'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id',
56
+            'queue' => 'your-queue-name',
57
+            'region' => 'us-east-1',
58
+        ],
59
+
60
+        'redis' => [
61
+            'driver' => 'redis',
62
+            'connection' => 'default',
63
+            'queue' => 'default',
64
+            'retry_after' => 90,
65
+        ],
66
+
67
+    ],
68
+
69
+    /*
70
+    |--------------------------------------------------------------------------
71
+    | Failed Queue Jobs
72
+    |--------------------------------------------------------------------------
73
+    |
74
+    | These options configure the behavior of failed queue job logging so you
75
+    | can control which database and table are used to store the jobs that
76
+    | have failed. You may change them to any database / table you wish.
77
+    |
78
+    */
79
+
80
+    'failed' => [
81
+        'database' => env('DB_CONNECTION', 'mysql'),
82
+        'table' => 'failed_jobs',
83
+    ],
84
+
85
+];

+ 38
- 0
config/services.php Прегледај датотеку

@@ -0,0 +1,38 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Third Party Services
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This file is for storing the credentials for third party services such
11
+    | as Stripe, Mailgun, SparkPost and others. This file provides a sane
12
+    | default location for this type of information, allowing packages
13
+    | to have a conventional place to find your various credentials.
14
+    |
15
+    */
16
+
17
+    'mailgun' => [
18
+        'domain' => env('MAILGUN_DOMAIN'),
19
+        'secret' => env('MAILGUN_SECRET'),
20
+    ],
21
+
22
+    'ses' => [
23
+        'key' => env('SES_KEY'),
24
+        'secret' => env('SES_SECRET'),
25
+        'region' => 'us-east-1',
26
+    ],
27
+
28
+    'sparkpost' => [
29
+        'secret' => env('SPARKPOST_SECRET'),
30
+    ],
31
+
32
+    'stripe' => [
33
+        'model' => App\User::class,
34
+        'key' => env('STRIPE_KEY'),
35
+        'secret' => env('STRIPE_SECRET'),
36
+    ],
37
+
38
+];

+ 179
- 0
config/session.php Прегледај датотеку

@@ -0,0 +1,179 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Session Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default session "driver" that will be used on
11
+    | requests. By default, we will use the lightweight native driver but
12
+    | you may specify any of the other wonderful drivers provided here.
13
+    |
14
+    | Supported: "file", "cookie", "database", "apc",
15
+    |            "memcached", "redis", "array"
16
+    |
17
+    */
18
+
19
+    'driver' => env('SESSION_DRIVER', 'file'),
20
+
21
+    /*
22
+    |--------------------------------------------------------------------------
23
+    | Session Lifetime
24
+    |--------------------------------------------------------------------------
25
+    |
26
+    | Here you may specify the number of minutes that you wish the session
27
+    | to be allowed to remain idle before it expires. If you want them
28
+    | to immediately expire on the browser closing, set that option.
29
+    |
30
+    */
31
+
32
+    'lifetime' => 120,
33
+
34
+    'expire_on_close' => false,
35
+
36
+    /*
37
+    |--------------------------------------------------------------------------
38
+    | Session Encryption
39
+    |--------------------------------------------------------------------------
40
+    |
41
+    | This option allows you to easily specify that all of your session data
42
+    | should be encrypted before it is stored. All encryption will be run
43
+    | automatically by Laravel and you can use the Session like normal.
44
+    |
45
+    */
46
+
47
+    'encrypt' => false,
48
+
49
+    /*
50
+    |--------------------------------------------------------------------------
51
+    | Session File Location
52
+    |--------------------------------------------------------------------------
53
+    |
54
+    | When using the native session driver, we need a location where session
55
+    | files may be stored. A default has been set for you but a different
56
+    | location may be specified. This is only needed for file sessions.
57
+    |
58
+    */
59
+
60
+    'files' => storage_path('framework/sessions'),
61
+
62
+    /*
63
+    |--------------------------------------------------------------------------
64
+    | Session Database Connection
65
+    |--------------------------------------------------------------------------
66
+    |
67
+    | When using the "database" or "redis" session drivers, you may specify a
68
+    | connection that should be used to manage these sessions. This should
69
+    | correspond to a connection in your database configuration options.
70
+    |
71
+    */
72
+
73
+    'connection' => null,
74
+
75
+    /*
76
+    |--------------------------------------------------------------------------
77
+    | Session Database Table
78
+    |--------------------------------------------------------------------------
79
+    |
80
+    | When using the "database" session driver, you may specify the table we
81
+    | should use to manage the sessions. Of course, a sensible default is
82
+    | provided for you; however, you are free to change this as needed.
83
+    |
84
+    */
85
+
86
+    'table' => 'sessions',
87
+
88
+    /*
89
+    |--------------------------------------------------------------------------
90
+    | Session Cache Store
91
+    |--------------------------------------------------------------------------
92
+    |
93
+    | When using the "apc" or "memcached" session drivers, you may specify a
94
+    | cache store that should be used for these sessions. This value must
95
+    | correspond with one of the application's configured cache stores.
96
+    |
97
+    */
98
+
99
+    'store' => null,
100
+
101
+    /*
102
+    |--------------------------------------------------------------------------
103
+    | Session Sweeping Lottery
104
+    |--------------------------------------------------------------------------
105
+    |
106
+    | Some session drivers must manually sweep their storage location to get
107
+    | rid of old sessions from storage. Here are the chances that it will
108
+    | happen on a given request. By default, the odds are 2 out of 100.
109
+    |
110
+    */
111
+
112
+    'lottery' => [2, 100],
113
+
114
+    /*
115
+    |--------------------------------------------------------------------------
116
+    | Session Cookie Name
117
+    |--------------------------------------------------------------------------
118
+    |
119
+    | Here you may change the name of the cookie used to identify a session
120
+    | instance by ID. The name specified here will get used every time a
121
+    | new session cookie is created by the framework for every driver.
122
+    |
123
+    */
124
+
125
+    'cookie' => 'laravel_session',
126
+
127
+    /*
128
+    |--------------------------------------------------------------------------
129
+    | Session Cookie Path
130
+    |--------------------------------------------------------------------------
131
+    |
132
+    | The session cookie path determines the path for which the cookie will
133
+    | be regarded as available. Typically, this will be the root path of
134
+    | your application but you are free to change this when necessary.
135
+    |
136
+    */
137
+
138
+    'path' => '/',
139
+
140
+    /*
141
+    |--------------------------------------------------------------------------
142
+    | Session Cookie Domain
143
+    |--------------------------------------------------------------------------
144
+    |
145
+    | Here you may change the domain of the cookie used to identify a session
146
+    | in your application. This will determine which domains the cookie is
147
+    | available to in your application. A sensible default has been set.
148
+    |
149
+    */
150
+
151
+    'domain' => env('SESSION_DOMAIN', null),
152
+
153
+    /*
154
+    |--------------------------------------------------------------------------
155
+    | HTTPS Only Cookies
156
+    |--------------------------------------------------------------------------
157
+    |
158
+    | By setting this option to true, session cookies will only be sent back
159
+    | to the server if the browser has a HTTPS connection. This will keep
160
+    | the cookie from being sent to you if it can not be done securely.
161
+    |
162
+    */
163
+
164
+    'secure' => env('SESSION_SECURE_COOKIE', false),
165
+
166
+    /*
167
+    |--------------------------------------------------------------------------
168
+    | HTTP Access Only
169
+    |--------------------------------------------------------------------------
170
+    |
171
+    | Setting this value to true will prevent JavaScript from accessing the
172
+    | value of the cookie and the cookie will only be accessible through
173
+    | the HTTP protocol. You are free to modify this option if needed.
174
+    |
175
+    */
176
+
177
+    'http_only' => true,
178
+
179
+];

+ 33
- 0
config/view.php Прегледај датотеку

@@ -0,0 +1,33 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | View Storage Paths
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Most templating systems load templates from disk. Here you may specify
11
+    | an array of paths that should be checked for your views. Of course
12
+    | the usual Laravel view path has already been registered for you.
13
+    |
14
+    */
15
+
16
+    'paths' => [
17
+        resource_path('views'),
18
+    ],
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Compiled View Path
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | This option determines where all the compiled Blade templates will be
26
+    | stored for your application. Typically, this is within the storage
27
+    | directory. However, as usual, you are free to change this value.
28
+    |
29
+    */
30
+
31
+    'compiled' => realpath(storage_path('framework/views')),
32
+
33
+];

+ 1
- 0
database/.gitignore Прегледај датотеку

@@ -0,0 +1 @@
1
+*.sqlite

+ 24
- 0
database/factories/ModelFactory.php Прегледај датотеку

@@ -0,0 +1,24 @@
1
+<?php
2
+
3
+/*
4
+|--------------------------------------------------------------------------
5
+| Model Factories
6
+|--------------------------------------------------------------------------
7
+|
8
+| Here you may define all of your model factories. Model factories give
9
+| you a convenient way to create models for testing and seeding your
10
+| database. Just tell the factory how a default model should look.
11
+|
12
+*/
13
+
14
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
15
+$factory->define(App\User::class, function (Faker\Generator $faker) {
16
+    static $password;
17
+
18
+    return [
19
+        'name' => $faker->name,
20
+        'email' => $faker->unique()->safeEmail,
21
+        'password' => $password ?: $password = bcrypt('secret'),
22
+        'remember_token' => str_random(10),
23
+    ];
24
+});

+ 35
- 0
database/migrations/2014_10_12_000000_create_users_table.php Прегледај датотеку

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Support\Facades\Schema;
4
+use Illuminate\Database\Schema\Blueprint;
5
+use Illuminate\Database\Migrations\Migration;
6
+
7
+class CreateUsersTable extends Migration
8
+{
9
+    /**
10
+     * Run the migrations.
11
+     *
12
+     * @return void
13
+     */
14
+    public function up()
15
+    {
16
+        Schema::create('users', function (Blueprint $table) {
17
+            $table->increments('id');
18
+            $table->string('name');
19
+            $table->string('email')->unique();
20
+            $table->string('password');
21
+            $table->rememberToken();
22
+            $table->timestamps();
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::dropIfExists('users');
34
+    }
35
+}

+ 32
- 0
database/migrations/2014_10_12_100000_create_password_resets_table.php Прегледај датотеку

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+use Illuminate\Support\Facades\Schema;
4
+use Illuminate\Database\Schema\Blueprint;
5
+use Illuminate\Database\Migrations\Migration;
6
+
7
+class CreatePasswordResetsTable extends Migration
8
+{
9
+    /**
10
+     * Run the migrations.
11
+     *
12
+     * @return void
13
+     */
14
+    public function up()
15
+    {
16
+        Schema::create('password_resets', function (Blueprint $table) {
17
+            $table->string('email')->index();
18
+            $table->string('token')->index();
19
+            $table->timestamp('created_at')->nullable();
20
+        });
21
+    }
22
+
23
+    /**
24
+     * Reverse the migrations.
25
+     *
26
+     * @return void
27
+     */
28
+    public function down()
29
+    {
30
+        Schema::dropIfExists('password_resets');
31
+    }
32
+}

+ 35
- 0
database/migrations/2016_02_23_075631_create_functions_table.php Прегледај датотеку

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunctionsTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('functions', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->string('FunName');
18
+            $table->string('FunLink');
19
+            $table->string('FunDesc');
20
+            $table->integer('Valid');
21
+            $table->timestamps();
22
+            $table->integer('Oid');
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::drop('functions');
34
+    }
35
+}

+ 34
- 0
database/migrations/2016_02_23_080148_create_funmenu_table.php Прегледај датотеку

@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunmenuTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('funmenu', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->string('MenuName');
18
+            $table->integer('Valid');
19
+            $table->integer('Corder');
20
+            $table->timestamps();
21
+            $table->integer('Oid');
22
+        });
23
+    }
24
+
25
+    /**
26
+     * Reverse the migrations.
27
+     *
28
+     * @return void
29
+     */
30
+    public function down()
31
+    {
32
+        Schema::drop('funmenu');
33
+    }
34
+}

+ 35
- 0
database/migrations/2016_02_23_080344_create_funmenudetail_table.php Прегледај датотеку

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunmenudetailTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('funmenudetail', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->integer('FunMenuId');
18
+            $table->integer('FunId');
19
+            $table->integer('Valid');
20
+            $table->integer('Corder');
21
+            $table->timestamps();
22
+            $table->integer('Oid');
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::drop('funmenudetail');
34
+    }
35
+}

+ 35
- 0
database/migrations/2016_02_23_080520_create_funusergroups_table.php Прегледај датотеку

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunusergroupsTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('funusergroups', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->string('Name');
18
+            $table->string('FunList');
19
+            $table->string('UsrList');
20
+            $table->integer('Valid');
21
+            $table->timestamps();
22
+            $table->integer('Oid');
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::drop('funusergroups');
34
+    }
35
+}

+ 16
- 0
database/seeds/DatabaseSeeder.php Прегледај датотеку

@@ -0,0 +1,16 @@
1
+<?php
2
+
3
+use Illuminate\Database\Seeder;
4
+
5
+class DatabaseSeeder extends Seeder
6
+{
7
+    /**
8
+     * Run the database seeds.
9
+     *
10
+     * @return void
11
+     */
12
+    public function run()
13
+    {
14
+        // $this->call(UsersTableSeeder::class);
15
+    }
16
+}

+ 19
- 0
package.json Прегледај датотеку

@@ -0,0 +1,19 @@
1
+{
2
+  "private": true,
3
+  "scripts": {
4
+    "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
5
+    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6
+    "watch-poll": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
7
+    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
8
+    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
9
+  },
10
+  "devDependencies": {
11
+    "axios": "^0.15.3",
12
+    "bootstrap-sass": "^3.3.7",
13
+    "cross-env": "^3.2.3",
14
+    "jquery": "^3.1.1",
15
+    "laravel-mix": "^0.8.3",
16
+    "lodash": "^4.17.4",
17
+    "vue": "^2.1.10"
18
+  }
19
+}

+ 31
- 0
phpunit.xml Прегледај датотеку

@@ -0,0 +1,31 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<phpunit backupGlobals="false"
3
+         backupStaticAttributes="false"
4
+         bootstrap="bootstrap/autoload.php"
5
+         colors="true"
6
+         convertErrorsToExceptions="true"
7
+         convertNoticesToExceptions="true"
8
+         convertWarningsToExceptions="true"
9
+         processIsolation="false"
10
+         stopOnFailure="false">
11
+    <testsuites>
12
+        <testsuite name="Feature Tests">
13
+            <directory suffix="Test.php">./tests/Feature</directory>
14
+        </testsuite>
15
+
16
+        <testsuite name="Unit Tests">
17
+            <directory suffix="Test.php">./tests/Unit</directory>
18
+        </testsuite>
19
+    </testsuites>
20
+    <filter>
21
+        <whitelist processUncoveredFilesFromWhitelist="true">
22
+            <directory suffix=".php">./app</directory>
23
+        </whitelist>
24
+    </filter>
25
+    <php>
26
+        <env name="APP_ENV" value="testing"/>
27
+        <env name="CACHE_DRIVER" value="array"/>
28
+        <env name="SESSION_DRIVER" value="array"/>
29
+        <env name="QUEUE_DRIVER" value="sync"/>
30
+    </php>
31
+</phpunit>

+ 30
- 0
public/.htaccess Прегледај датотеку

@@ -0,0 +1,30 @@
1
+<IfModule mod_rewrite.c>
2
+    <IfModule mod_negotiation.c>
3
+        Options -MultiViews
4
+    </IfModule>
5
+
6
+    RewriteEngine On
7
+
8
+    # Redirect Trailing Slashes If Not A Folder...
9
+    RewriteCond %{REQUEST_FILENAME} !-d
10
+    RewriteRule ^(.*)/$ /$1 [L,R=301]
11
+
12
+    # Handle Front Controller...
13
+    RewriteCond %{REQUEST_FILENAME} !-d
14
+    RewriteCond %{REQUEST_FILENAME} !-f
15
+    RewriteRule ^ index.php [L]
16
+
17
+    # Handle Authorization Header
18
+    RewriteCond %{HTTP:Authorization} .
19
+    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
20
+</IfModule>
21
+
22
+<IfModule mod_headers.c>
23
+<FilesMatch "\.(svg|ttf|otf|eot|woff|woff2)$">
24
+    Header set Access-Control-Allow-Origin "*"
25
+</FilesMatch>
26
+</IfModule>
27
+
28
+php_value upload_max_filesize 100M
29
+php_value post_max_size 100M
30
+php_value memory_limit 1024M

+ 394
- 0
public/assets/css/animate.delay.css Прегледај датотеку

@@ -0,0 +1,394 @@
1
+.animate0 {
2
+   	-webkit-animation-duration: .8s;
3
+	-webkit-animation-delay: 0s;
4
+	-webkit-animation-timing-function: ease;
5
+	-webkit-animation-fill-mode: both;
6
+	-moz-animation-duration: .8s;
7
+	-moz-animation-delay: 0s;
8
+	-moz-animation-timing-function: ease;
9
+	-moz-animation-fill-mode: both;
10
+	-ms-animation-duration: .8s;
11
+	-ms-animation-delay: 0s;
12
+	-ms-animation-timing-function: ease;
13
+	-ms-animation-fill-mode: both;
14
+	animation-duration: .8s;
15
+	animation-delay: 0s;
16
+	animation-timing-function: ease;
17
+	animation-fill-mode: both;	          
18
+}         
19
+
20
+.animate1{
21
+   	-webkit-animation-duration: .8s;
22
+	-webkit-animation-delay: .2s;
23
+	-webkit-animation-timing-function: ease;
24
+	-webkit-animation-fill-mode: both;
25
+	-moz-animation-duration: .8s;
26
+	-moz-animation-delay: .2s;
27
+	-moz-animation-timing-function: ease;
28
+	-moz-animation-fill-mode: both;
29
+	-ms-animation-duration: .8s;
30
+	-ms-animation-delay: .2s;
31
+	-ms-animation-timing-function: ease;
32
+	-ms-animation-fill-mode: both;
33
+	animation-duration: .8s;
34
+	animation-delay: .2s;
35
+	animation-timing-function: ease;
36
+	animation-fill-mode: both;	          
37
+} 
38
+
39
+.animate2{
40
+   	-webkit-animation-duration: .8s;
41
+	-webkit-animation-delay: .4s;
42
+	-webkit-animation-timing-function: ease;
43
+	-webkit-animation-fill-mode: both;
44
+	-moz-animation-duration: .8s;
45
+	-moz-animation-delay: .4s;
46
+	-moz-animation-timing-function: ease;
47
+	-moz-animation-fill-mode: both;
48
+	-ms-animation-duration: .8s;
49
+	-ms-animation-delay: .4s;
50
+	-ms-animation-timing-function: ease;
51
+	-ms-animation-fill-mode: both;
52
+	animation-duration: .8s;
53
+	animation-delay: .4s;
54
+	animation-timing-function: ease;
55
+	animation-fill-mode: both;	          
56
+} 
57
+
58
+.animate3{
59
+   	-webkit-animation-duration: .8s;
60
+	-webkit-animation-delay: .6s;
61
+	-webkit-animation-timing-function: ease;
62
+	-webkit-animation-fill-mode: both;
63
+	-moz-animation-duration: .8s;
64
+	-moz-animation-delay: .6s;
65
+	-moz-animation-timing-function: ease;
66
+	-moz-animation-fill-mode: both;
67
+	-ms-animation-duration: .8s;
68
+	-ms-animation-delay: .6s;
69
+	-ms-animation-timing-function: ease;
70
+	-ms-animation-fill-mode: both;
71
+	animation-duration: .8s;
72
+	animation-delay: .6s;
73
+	animation-timing-function: ease;
74
+	animation-fill-mode: both;	          
75
+}   
76
+
77
+.animate4{
78
+   	-webkit-animation-duration: .8s;
79
+	-webkit-animation-delay: .8s;
80
+	-webkit-animation-timing-function: ease;
81
+	-webkit-animation-fill-mode: both;
82
+	-moz-animation-duration: .8s;
83
+	-moz-animation-delay: .8s;
84
+	-moz-animation-timing-function: ease;
85
+	-moz-animation-fill-mode: both;
86
+	-ms-animation-duration: .8s;
87
+	-ms-animation-delay: .8s;
88
+	-ms-animation-timing-function: ease;
89
+	-ms-animation-fill-mode: both;
90
+	animation-duration: .8s;
91
+	animation-delay: .8s;
92
+	animation-timing-function: ease;
93
+	animation-fill-mode: both;	          
94
+}  
95
+
96
+.animate5{
97
+   	-webkit-animation-duration: .8s;
98
+	-webkit-animation-delay: 1s;
99
+	-webkit-animation-timing-function: ease;
100
+	-webkit-animation-fill-mode: both;
101
+	-moz-animation-duration: .8s;
102
+	-moz-animation-delay: 1s;
103
+	-moz-animation-timing-function: ease;
104
+	-moz-animation-fill-mode: both;
105
+	-ms-animation-duration: .8s;
106
+	-ms-animation-delay: 1s;
107
+	-ms-animation-timing-function: ease;
108
+	-ms-animation-fill-mode: both;
109
+	animation-duration: .8s;
110
+	animation-delay: 1s;
111
+	animation-timing-function: ease;
112
+	animation-fill-mode: both;	          
113
+}    
114
+.animate6{
115
+   	-webkit-animation-duration: .8s;
116
+	-webkit-animation-delay: 1.2s;
117
+	-webkit-animation-timing-function: ease;
118
+	-webkit-animation-fill-mode: both;
119
+	-moz-animation-duration: .8s;
120
+	-moz-animation-delay: 1.2s;
121
+	-moz-animation-timing-function: ease;
122
+	-moz-animation-fill-mode: both;
123
+	-ms-animation-duration: .8s;
124
+	-ms-animation-delay: 1.2s;
125
+	-ms-animation-timing-function: ease;
126
+	-ms-animation-fill-mode: both;
127
+	animation-duration: .8s;
128
+	animation-delay: 1.2s;
129
+	animation-timing-function: ease;
130
+	animation-fill-mode: both;	          
131
+}    
132
+.animate7{
133
+   	-webkit-animation-duration: .8s;
134
+	-webkit-animation-delay: 1.4s;
135
+	-webkit-animation-timing-function: ease;
136
+	-webkit-animation-fill-mode: both;
137
+	-moz-animation-duration: .8s;
138
+	-moz-animation-delay: 1.4s;
139
+	-moz-animation-timing-function: ease;
140
+	-moz-animation-fill-mode: both;
141
+	-ms-animation-duration: .8s;
142
+	-ms-animation-delay: 1.4s;
143
+	-ms-animation-timing-function: ease;
144
+	-ms-animation-fill-mode: both;
145
+	animation-duration: .8s;
146
+	animation-delay: 1.4s;
147
+	animation-timing-function: ease;
148
+	animation-fill-mode: both;	          
149
+}
150
+
151
+.animate8{
152
+   	-webkit-animation-duration: .8s;
153
+	-webkit-animation-delay: 1.8s;
154
+	-webkit-animation-timing-function: ease;
155
+	-webkit-animation-fill-mode: both;
156
+	-moz-animation-duration: .8s;
157
+	-moz-animation-delay: 1.8s;
158
+	-moz-animation-timing-function: ease;
159
+	-moz-animation-fill-mode: both;
160
+	-ms-animation-duration: .8s;
161
+	-ms-animation-delay: 1.8s;
162
+	-ms-animation-timing-function: ease;
163
+	-ms-animation-fill-mode: both;
164
+	animation-duration: .8s;
165
+	animation-delay: 1.8s;
166
+	animation-timing-function: ease;
167
+	animation-fill-mode: both;	          
168
+}
169
+
170
+.animate9{
171
+   	-webkit-animation-duration: .8s;
172
+	-webkit-animation-delay: 1.8s;
173
+	-webkit-animation-timing-function: ease;
174
+	-webkit-animation-fill-mode: both;
175
+	-moz-animation-duration: .8s;
176
+	-moz-animation-delay: 1.8s;
177
+	-moz-animation-timing-function: ease;
178
+	-moz-animation-fill-mode: both;
179
+	-ms-animation-duration: .8s;
180
+	-ms-animation-delay: 1.8s;
181
+	-ms-animation-timing-function: ease;
182
+	-ms-animation-fill-mode: both;
183
+	animation-duration: .8s;
184
+	animation-delay: 1.8s;
185
+	animation-timing-function: ease;
186
+	animation-fill-mode: both;	          
187
+}
188
+
189
+.animate10{
190
+   	-webkit-animation-duration: .8s;
191
+	-webkit-animation-delay: 2.0s;
192
+	-webkit-animation-timing-function: ease;
193
+	-webkit-animation-fill-mode: both;
194
+	-moz-animation-duration: .8s;
195
+	-moz-animation-delay: 2.0s;
196
+	-moz-animation-timing-function: ease;
197
+	-moz-animation-fill-mode: both;
198
+	-ms-animation-duration: .8s;
199
+	-ms-animation-delay: 2.0s;
200
+	-ms-animation-timing-function: ease;
201
+	-ms-animation-fill-mode: both;
202
+	animation-duration: .8s;
203
+	animation-delay: 2.0s;
204
+	animation-timing-function: ease;
205
+	animation-fill-mode: both;	          
206
+}   
207
+
208
+.animate11{
209
+   	-webkit-animation-duration: .8s;
210
+	-webkit-animation-delay: 2.2s;
211
+	-webkit-animation-timing-function: ease;
212
+	-webkit-animation-fill-mode: both;
213
+	-moz-animation-duration: .8s;
214
+	-moz-animation-delay: 2.2s;
215
+	-moz-animation-timing-function: ease;
216
+	-moz-animation-fill-mode: both;
217
+	-ms-animation-duration: .8s;
218
+	-ms-animation-delay: 2.2s;
219
+	-ms-animation-timing-function: ease;
220
+	-ms-animation-fill-mode: both;
221
+	animation-duration: .8s;
222
+	animation-delay: 2.2s;
223
+	animation-timing-function: ease;
224
+	animation-fill-mode: both;	          
225
+}
226
+
227
+.animate12{
228
+   	-webkit-animation-duration: .8s;
229
+	-webkit-animation-delay: 2.4s;
230
+	-webkit-animation-timing-function: ease;
231
+	-webkit-animation-fill-mode: both;
232
+	-moz-animation-duration: .8s;
233
+	-moz-animation-delay: 2.4s;
234
+	-moz-animation-timing-function: ease;
235
+	-moz-animation-fill-mode: both;
236
+	-ms-animation-duration: .8s;
237
+	-ms-animation-delay: 2.4s;
238
+	-ms-animation-timing-function: ease;
239
+	-ms-animation-fill-mode: both;
240
+	animation-duration: .8s;
241
+	animation-delay: 2.4s;
242
+	animation-timing-function: ease;
243
+	animation-fill-mode: both;	          
244
+} 
245
+
246
+.animate13{
247
+   	-webkit-animation-duration: .8s;
248
+	-webkit-animation-delay: 2.8s;
249
+	-webkit-animation-timing-function: ease;
250
+	-webkit-animation-fill-mode: both;
251
+	-moz-animation-duration: .8s;
252
+	-moz-animation-delay: 2.8s;
253
+	-moz-animation-timing-function: ease;
254
+	-moz-animation-fill-mode: both;
255
+	-ms-animation-duration: .8s;
256
+	-ms-animation-delay: 2.8s;
257
+	-ms-animation-timing-function: ease;
258
+	-ms-animation-fill-mode: both;
259
+	animation-duration: .8s;
260
+	animation-delay: 2.8s;
261
+	animation-timing-function: ease;
262
+	animation-fill-mode: both;	          
263
+}
264
+
265
+.animate14{
266
+   	-webkit-animation-duration: .8s;
267
+	-webkit-animation-delay: 2.8s;
268
+	-webkit-animation-timing-function: ease;
269
+	-webkit-animation-fill-mode: both;
270
+	-moz-animation-duration: .8s;
271
+	-moz-animation-delay: 2.8s;
272
+	-moz-animation-timing-function: ease;
273
+	-moz-animation-fill-mode: both;
274
+	-ms-animation-duration: .8s;
275
+	-ms-animation-delay: 2.8s;
276
+	-ms-animation-timing-function: ease;
277
+	-ms-animation-fill-mode: both;
278
+	animation-duration: .8s;
279
+	animation-delay: 2.8s;
280
+	animation-timing-function: ease;
281
+	animation-fill-mode: both;	          
282
+}  
283
+
284
+.animate15{
285
+   	-webkit-animation-duration: .8s;
286
+	-webkit-animation-delay: 3.0s;
287
+	-webkit-animation-timing-function: ease;
288
+	-webkit-animation-fill-mode: both;
289
+	-moz-animation-duration: .8s;
290
+	-moz-animation-delay: 3.0s;
291
+	-moz-animation-timing-function: ease;
292
+	-moz-animation-fill-mode: both;
293
+	-ms-animation-duration: .8s;
294
+	-ms-animation-delay: 3.0s;
295
+	-ms-animation-timing-function: ease;
296
+	-ms-animation-fill-mode: both;
297
+	animation-duration: .8s;
298
+	animation-delay: 3.0s;
299
+	animation-timing-function: ease;
300
+	animation-fill-mode: both;	          
301
+}
302
+
303
+.animate16{
304
+   	-webkit-animation-duration: .8s;
305
+	-webkit-animation-delay: 3.2s;
306
+	-webkit-animation-timing-function: ease;
307
+	-webkit-animation-fill-mode: both;
308
+	-moz-animation-duration: .8s;
309
+	-moz-animation-delay: 3.2s;
310
+	-moz-animation-timing-function: ease;
311
+	-moz-animation-fill-mode: both;
312
+	-ms-animation-duration: .8s;
313
+	-ms-animation-delay: 3.2s;
314
+	-ms-animation-timing-function: ease;
315
+	-ms-animation-fill-mode: both;
316
+	animation-duration: .8s;
317
+	animation-delay: 3.2s;
318
+	animation-timing-function: ease;
319
+	animation-fill-mode: both;	          
320
+}
321
+
322
+.animate17{
323
+   	-webkit-animation-duration: .8s;
324
+	-webkit-animation-delay: 3.4s;
325
+	-webkit-animation-timing-function: ease;
326
+	-webkit-animation-fill-mode: both;
327
+	-moz-animation-duration: .8s;
328
+	-moz-animation-delay: 3.4s;
329
+	-moz-animation-timing-function: ease;
330
+	-moz-animation-fill-mode: both;
331
+	-ms-animation-duration: .8s;
332
+	-ms-animation-delay: 3.4s;
333
+	-ms-animation-timing-function: ease;
334
+	-ms-animation-fill-mode: both;
335
+	animation-duration: .8s;
336
+	animation-delay: 3.4s;
337
+	animation-timing-function: ease;
338
+	animation-fill-mode: both;	          
339
+}
340
+.animate18{
341
+   	-webkit-animation-duration: .8s;
342
+	-webkit-animation-delay: 3.6s;
343
+	-webkit-animation-timing-function: ease;
344
+	-webkit-animation-fill-mode: both;
345
+	-moz-animation-duration: .8s;
346
+	-moz-animation-delay: 3.6s;
347
+	-moz-animation-timing-function: ease;
348
+	-moz-animation-fill-mode: both;
349
+	-ms-animation-duration: .8s;
350
+	-ms-animation-delay: 3.6s;
351
+	-ms-animation-timing-function: ease;
352
+	-ms-animation-fill-mode: both;
353
+	animation-duration: .8s;
354
+	animation-delay: 3.6s;
355
+	animation-timing-function: ease;
356
+	animation-fill-mode: both;	          
357
+}
358
+.animate19{
359
+   	-webkit-animation-duration: .8s;
360
+	-webkit-animation-delay: 3.8s;
361
+	-webkit-animation-timing-function: ease;
362
+	-webkit-animation-fill-mode: both;
363
+	-moz-animation-duration: .8s;
364
+	-moz-animation-delay: 3.8s;
365
+	-moz-animation-timing-function: ease;
366
+	-moz-animation-fill-mode: both;
367
+	-ms-animation-duration: .8s;
368
+	-ms-animation-delay: 3.8s;
369
+	-ms-animation-timing-function: ease;
370
+	-ms-animation-fill-mode: both;
371
+	animation-duration: .8s;
372
+	animation-delay: 3.8s;
373
+	animation-timing-function: ease;
374
+	animation-fill-mode: both;	          
375
+}
376
+
377
+.animate20{
378
+   	-webkit-animation-duration: .8s;
379
+	-webkit-animation-delay: 4.0s;
380
+	-webkit-animation-timing-function: ease;
381
+	-webkit-animation-fill-mode: both;
382
+	-moz-animation-duration: .8s;
383
+	-moz-animation-delay: 4.0s;
384
+	-moz-animation-timing-function: ease;
385
+	-moz-animation-fill-mode: both;
386
+	-ms-animation-duration: .8s;
387
+	-ms-animation-delay: 4.0s;
388
+	-ms-animation-timing-function: ease;
389
+	-ms-animation-fill-mode: both;
390
+	animation-duration: .8s;
391
+	animation-delay: 4.0s;
392
+	animation-timing-function: ease;
393
+	animation-fill-mode: both;	          
394
+}

+ 1
- 0
public/assets/css/animate.min.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 5
- 0
public/assets/css/bootstrap-clockpicker.min.css Прегледај датотеку

@@ -0,0 +1,5 @@
1
+/*!
2
+ * ClockPicker v0.0.7 for Bootstrap (http://weareoutman.github.io/clockpicker/)
3
+ * Copyright 2014 Wang Shenwei.
4
+ * Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/master/LICENSE)
5
+ */.clockpicker .input-group-addon{cursor:pointer}.clockpicker-moving{cursor:move}.clockpicker-align-left.popover>.arrow{left:25px}.clockpicker-align-top.popover>.arrow{top:17px}.clockpicker-align-right.popover>.arrow{left:auto;right:25px}.clockpicker-align-bottom.popover>.arrow{top:auto;bottom:6px}.clockpicker-popover .popover-title{background-color:#fff;color:#999;font-size:24px;font-weight:700;line-height:30px;text-align:center}.clockpicker-popover .popover-title span{cursor:pointer}.clockpicker-popover .popover-content{background-color:#f8f8f8;padding:12px}.popover-content:last-child{border-bottom-left-radius:5px;border-bottom-right-radius:5px}.clockpicker-plate{background-color:#fff;border:1px solid #ccc;border-radius:50%;width:200px;height:200px;overflow:visible;position:relative;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.clockpicker-canvas,.clockpicker-dial{width:200px;height:200px;position:absolute;left:-1px;top:-1px}.clockpicker-minutes{visibility:hidden}.clockpicker-tick{border-radius:50%;color:#666;line-height:26px;text-align:center;width:26px;height:26px;position:absolute;cursor:pointer}.clockpicker-tick.active,.clockpicker-tick:hover{background-color:#c0e5f7;background-color:rgba(0,149,221,.25)}.clockpicker-button{background-image:none;background-color:#fff;border-width:1px 0 0;border-top-left-radius:0;border-top-right-radius:0;margin:0;padding:10px 0}.clockpicker-button:hover{background-image:none;background-color:#ebebeb}.clockpicker-button:focus{outline:0!important}.clockpicker-dial{-webkit-transition:-webkit-transform 350ms,opacity 350ms;-moz-transition:-moz-transform 350ms,opacity 350ms;-ms-transition:-ms-transform 350ms,opacity 350ms;-o-transition:-o-transform 350ms,opacity 350ms;transition:transform 350ms,opacity 350ms}.clockpicker-dial-out{opacity:0}.clockpicker-hours.clockpicker-dial-out{-webkit-transform:scale(1.2,1.2);-moz-transform:scale(1.2,1.2);-ms-transform:scale(1.2,1.2);-o-transform:scale(1.2,1.2);transform:scale(1.2,1.2)}.clockpicker-minutes.clockpicker-dial-out{-webkit-transform:scale(.8,.8);-moz-transform:scale(.8,.8);-ms-transform:scale(.8,.8);-o-transform:scale(.8,.8);transform:scale(.8,.8)}.clockpicker-canvas{-webkit-transition:opacity 175ms;-moz-transition:opacity 175ms;-ms-transition:opacity 175ms;-o-transition:opacity 175ms;transition:opacity 175ms}.clockpicker-canvas-out{opacity:.25}.clockpicker-canvas-bearing,.clockpicker-canvas-fg{stroke:none;fill:#0095dd}.clockpicker-canvas-bg{stroke:none;fill:#c0e5f7}.clockpicker-canvas-bg-trans{fill:rgba(0,149,221,.25)}.clockpicker-canvas line{stroke:#0095dd;stroke-width:1;stroke-linecap:round}.clockpicker-button.am-button{margin:1px;padding:5px;border:1px solid rgba(0,0,0,.2);border-radius:4px}.clockpicker-button.pm-button{margin:1px 1px 1px 136px;padding:5px;border:1px solid rgba(0,0,0,.2);border-radius:4px}

+ 337
- 0
public/assets/css/bootstrap-datetimepicker.css Прегледај датотеку

@@ -0,0 +1,337 @@
1
+.bootstrap-datetimepicker-widget.dropdown-menu {
2
+  margin: 2px 0;
3
+  padding: 4px;
4
+  width: 19em;
5
+}
6
+@media (min-width: 768px) {
7
+  .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
8
+    width: 38em;
9
+  }
10
+}
11
+@media (min-width: 992px) {
12
+  .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
13
+    width: 38em;
14
+  }
15
+}
16
+@media (min-width: 1200px) {
17
+  .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
18
+    width: 38em;
19
+  }
20
+}
21
+.bootstrap-datetimepicker-widget.dropdown-menu:before,
22
+.bootstrap-datetimepicker-widget.dropdown-menu:after {
23
+  content: '';
24
+  display: inline-block;
25
+  position: absolute;
26
+}
27
+.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
28
+  border-left: 7px solid transparent;
29
+  border-right: 7px solid transparent;
30
+  border-bottom: 7px solid #ccc;
31
+  border-bottom-color: rgba(0, 0, 0, 0.2);
32
+  top: -7px;
33
+  left: 7px;
34
+}
35
+.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
36
+  border-left: 6px solid transparent;
37
+  border-right: 6px solid transparent;
38
+  border-bottom: 6px solid white;
39
+  top: -6px;
40
+  left: 8px;
41
+}
42
+.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
43
+  border-left: 7px solid transparent;
44
+  border-right: 7px solid transparent;
45
+  border-top: 7px solid #ccc;
46
+  border-top-color: rgba(0, 0, 0, 0.2);
47
+  bottom: -7px;
48
+  left: 6px;
49
+}
50
+.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
51
+  border-left: 6px solid transparent;
52
+  border-right: 6px solid transparent;
53
+  border-top: 6px solid white;
54
+  bottom: -6px;
55
+  left: 7px;
56
+}
57
+.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
58
+  left: auto;
59
+  right: 6px;
60
+}
61
+.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
62
+  left: auto;
63
+  right: 7px;
64
+}
65
+.bootstrap-datetimepicker-widget .list-unstyled {
66
+  margin: 0;
67
+}
68
+.bootstrap-datetimepicker-widget a[data-action] {
69
+  padding: 6px 0;
70
+}
71
+.bootstrap-datetimepicker-widget a[data-action]:active {
72
+  box-shadow: none;
73
+}
74
+.bootstrap-datetimepicker-widget .timepicker-hour,
75
+.bootstrap-datetimepicker-widget .timepicker-minute,
76
+.bootstrap-datetimepicker-widget .timepicker-second {
77
+  width: 54px;
78
+  font-weight: bold;
79
+  font-size: 1.2em;
80
+  margin: 0;
81
+}
82
+.bootstrap-datetimepicker-widget button[data-action] {
83
+  padding: 6px;
84
+}
85
+.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
86
+  position: absolute;
87
+  width: 1px;
88
+  height: 1px;
89
+  margin: -1px;
90
+  padding: 0;
91
+  overflow: hidden;
92
+  clip: rect(0, 0, 0, 0);
93
+  border: 0;
94
+  content: "Increment Hours";
95
+}
96
+.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
97
+  position: absolute;
98
+  width: 1px;
99
+  height: 1px;
100
+  margin: -1px;
101
+  padding: 0;
102
+  overflow: hidden;
103
+  clip: rect(0, 0, 0, 0);
104
+  border: 0;
105
+  content: "Increment Minutes";
106
+}
107
+.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
108
+  position: absolute;
109
+  width: 1px;
110
+  height: 1px;
111
+  margin: -1px;
112
+  padding: 0;
113
+  overflow: hidden;
114
+  clip: rect(0, 0, 0, 0);
115
+  border: 0;
116
+  content: "Decrement Hours";
117
+}
118
+.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
119
+  position: absolute;
120
+  width: 1px;
121
+  height: 1px;
122
+  margin: -1px;
123
+  padding: 0;
124
+  overflow: hidden;
125
+  clip: rect(0, 0, 0, 0);
126
+  border: 0;
127
+  content: "Decrement Minutes";
128
+}
129
+.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
130
+  position: absolute;
131
+  width: 1px;
132
+  height: 1px;
133
+  margin: -1px;
134
+  padding: 0;
135
+  overflow: hidden;
136
+  clip: rect(0, 0, 0, 0);
137
+  border: 0;
138
+  content: "Show Hours";
139
+}
140
+.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
141
+  position: absolute;
142
+  width: 1px;
143
+  height: 1px;
144
+  margin: -1px;
145
+  padding: 0;
146
+  overflow: hidden;
147
+  clip: rect(0, 0, 0, 0);
148
+  border: 0;
149
+  content: "Show Minutes";
150
+}
151
+.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
152
+  position: absolute;
153
+  width: 1px;
154
+  height: 1px;
155
+  margin: -1px;
156
+  padding: 0;
157
+  overflow: hidden;
158
+  clip: rect(0, 0, 0, 0);
159
+  border: 0;
160
+  content: "Toggle AM/PM";
161
+}
162
+.bootstrap-datetimepicker-widget .picker-switch {
163
+  text-align: center;
164
+}
165
+.bootstrap-datetimepicker-widget .picker-switch::after {
166
+  position: absolute;
167
+  width: 1px;
168
+  height: 1px;
169
+  margin: -1px;
170
+  padding: 0;
171
+  overflow: hidden;
172
+  clip: rect(0, 0, 0, 0);
173
+  border: 0;
174
+  content: "Toggle Date and Time Screens";
175
+}
176
+.bootstrap-datetimepicker-widget .picker-switch td {
177
+  padding: 0;
178
+  margin: 0;
179
+  height: auto;
180
+  width: auto;
181
+  line-height: inherit;
182
+}
183
+.bootstrap-datetimepicker-widget .picker-switch td span {
184
+  line-height: 2.5;
185
+  height: 2.5em;
186
+  width: 100%;
187
+}
188
+.bootstrap-datetimepicker-widget table {
189
+  width: 100%;
190
+  margin: 0;
191
+}
192
+.bootstrap-datetimepicker-widget td,
193
+.bootstrap-datetimepicker-widget th {
194
+  text-align: center;
195
+  border-radius: 4px;
196
+}
197
+.bootstrap-datetimepicker-widget th {
198
+  height: 20px;
199
+  line-height: 20px;
200
+  width: 20px;
201
+}
202
+.bootstrap-datetimepicker-widget th.picker-switch {
203
+  width: 145px;
204
+}
205
+.bootstrap-datetimepicker-widget th.disabled,
206
+.bootstrap-datetimepicker-widget th.disabled:hover {
207
+  background: none;
208
+  color: #777777;
209
+  cursor: not-allowed;
210
+}
211
+.bootstrap-datetimepicker-widget th.prev::after {
212
+  position: absolute;
213
+  width: 1px;
214
+  height: 1px;
215
+  margin: -1px;
216
+  padding: 0;
217
+  overflow: hidden;
218
+  clip: rect(0, 0, 0, 0);
219
+  border: 0;
220
+  background:
221
+  content: "Previous Month";
222
+}
223
+.bootstrap-datetimepicker-widget th.next::after {
224
+  position: absolute;
225
+  width: 1px;
226
+  height: 1px;
227
+  margin: -1px;
228
+  padding: 0;
229
+  overflow: hidden;
230
+  clip: rect(0, 0, 0, 0);
231
+  border: 0;
232
+  content: "Next Month";
233
+}
234
+.bootstrap-datetimepicker-widget thead tr:first-child th {
235
+  cursor: pointer;
236
+}
237
+.bootstrap-datetimepicker-widget thead tr:first-child th:hover {
238
+  background: #eeeeee;
239
+}
240
+.bootstrap-datetimepicker-widget td {
241
+  height: 54px;
242
+  line-height: 54px;
243
+  width: 54px;
244
+}
245
+.bootstrap-datetimepicker-widget td.cw {
246
+  font-size: .8em;
247
+  height: 20px;
248
+  line-height: 20px;
249
+  color: #777777;
250
+}
251
+.bootstrap-datetimepicker-widget td.day {
252
+  height: 20px;
253
+  line-height: 20px;
254
+  width: 20px;
255
+}
256
+.bootstrap-datetimepicker-widget td.day:hover,
257
+.bootstrap-datetimepicker-widget td.hour:hover,
258
+.bootstrap-datetimepicker-widget td.minute:hover,
259
+.bootstrap-datetimepicker-widget td.second:hover {
260
+  background: #eeeeee;
261
+  cursor: pointer;
262
+}
263
+.bootstrap-datetimepicker-widget td.old,
264
+.bootstrap-datetimepicker-widget td.new {
265
+  color: #777777;
266
+}
267
+.bootstrap-datetimepicker-widget td.today {
268
+  position: relative;
269
+}
270
+.bootstrap-datetimepicker-widget td.today:before {
271
+  content: '';
272
+  display: inline-block;
273
+  border-left: 7px solid transparent;
274
+  border-bottom: 7px solid #428bca;
275
+  border-top-color: rgba(0, 0, 0, 0.2);
276
+  position: absolute;
277
+  bottom: 4px;
278
+  right: 4px;
279
+}
280
+.bootstrap-datetimepicker-widget td.active,
281
+.bootstrap-datetimepicker-widget td.active:hover {
282
+  background-color: #428bca;
283
+  color: #ffffff;
284
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
285
+}
286
+.bootstrap-datetimepicker-widget td.active.today:before {
287
+  border-bottom-color: #fff;
288
+}
289
+.bootstrap-datetimepicker-widget td.disabled,
290
+.bootstrap-datetimepicker-widget td.disabled:hover {
291
+  background: none;
292
+  color: #777777;
293
+  cursor: not-allowed;
294
+}
295
+.bootstrap-datetimepicker-widget td span {
296
+  display: inline-block;
297
+  width: 54px;
298
+  height: 54px;
299
+  line-height: 54px;
300
+  margin: 2px 1.5px;
301
+  cursor: pointer;
302
+  border-radius: 4px;
303
+}
304
+.bootstrap-datetimepicker-widget td span:hover {
305
+  background: #eeeeee;
306
+}
307
+.bootstrap-datetimepicker-widget td span.active {
308
+  background-color: #428bca;
309
+  color: #ffffff;
310
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
311
+}
312
+.bootstrap-datetimepicker-widget td span.old {
313
+  color: #777777;
314
+}
315
+.bootstrap-datetimepicker-widget td span.disabled,
316
+.bootstrap-datetimepicker-widget td span.disabled:hover {
317
+  background: none;
318
+  color: #777777;
319
+  cursor: not-allowed;
320
+}
321
+.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
322
+  height: 27px;
323
+  line-height: 27px;
324
+}
325
+.input-group.date .input-group-addon {
326
+  cursor: pointer;
327
+}
328
+.sr-only {
329
+  position: absolute;
330
+  width: 1px;
331
+  height: 1px;
332
+  margin: -1px;
333
+  padding: 0;
334
+  overflow: hidden;
335
+  clip: rect(0, 0, 0, 0);
336
+  border: 0;
337
+}

+ 663
- 0
public/assets/css/bootstrap-editable.css Прегледај датотеку

@@ -0,0 +1,663 @@
1
+/*! X-editable - v1.5.1 
2
+* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
3
+* http://github.com/vitalets/x-editable
4
+* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
5
+.editableform {
6
+    margin-bottom: 0; /* overwrites bootstrap margin */
7
+}
8
+
9
+.editableform .control-group {
10
+    margin-bottom: 0; /* overwrites bootstrap margin */
11
+    white-space: nowrap; /* prevent wrapping buttons on new line */
12
+    line-height: 20px; /* overwriting bootstrap line-height. See #133 */
13
+}
14
+
15
+/* 
16
+  BS3 width:1005 for inputs breaks editable form in popup 
17
+  See: https://github.com/vitalets/x-editable/issues/393
18
+*/
19
+.editableform .form-control {
20
+    width: auto;
21
+}
22
+
23
+.editable-buttons {
24
+   display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
25
+   vertical-align: top;
26
+   margin-left: 7px;
27
+   /* inline-block emulation for IE7*/
28
+   zoom: 1; 
29
+   *display: inline;
30
+}
31
+
32
+.editable-buttons.editable-buttons-bottom {
33
+   display: block; 
34
+   margin-top: 7px;
35
+   margin-left: 0;
36
+}
37
+
38
+.editable-input {
39
+    vertical-align: top; 
40
+    display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
41
+    width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
42
+    white-space: normal; /* reset white-space decalred in parent*/
43
+   /* display-inline emulation for IE7*/
44
+   zoom: 1; 
45
+   *display: inline;   
46
+}
47
+
48
+.editable-buttons .editable-cancel {
49
+   margin-left: 7px; 
50
+}
51
+
52
+/*for jquery-ui buttons need set height to look more pretty*/
53
+.editable-buttons button.ui-button-icon-only {
54
+   height: 24px; 
55
+   width: 30px;
56
+}
57
+
58
+.editableform-loading {
59
+    background: url('../images/loading.gif') center center no-repeat;  
60
+    height: 25px;
61
+    width: auto; 
62
+    min-width: 25px; 
63
+}
64
+
65
+.editable-inline .editableform-loading {
66
+    background-position: left 5px;      
67
+}
68
+
69
+ .editable-error-block {
70
+    max-width: 300px;
71
+    margin: 5px 0 0 0;
72
+    width: auto;
73
+    white-space: normal;
74
+}
75
+
76
+/*add padding for jquery ui*/
77
+.editable-error-block.ui-state-error {
78
+    padding: 3px;  
79
+}  
80
+
81
+.editable-error {
82
+   color: red;  
83
+}
84
+
85
+/* ---- For specific types ---- */
86
+
87
+.editableform .editable-date {
88
+    padding: 0; 
89
+    margin: 0;
90
+    float: left;
91
+}
92
+
93
+/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
94
+.editable-inline .add-on .icon-th {
95
+   margin-top: 3px;
96
+   margin-left: 1px; 
97
+}
98
+
99
+
100
+/* checklist vertical alignment */
101
+.editable-checklist label input[type="checkbox"], 
102
+.editable-checklist label span {
103
+    vertical-align: middle;
104
+    margin: 0;
105
+}
106
+
107
+.editable-checklist label {
108
+    white-space: nowrap; 
109
+}
110
+
111
+/* set exact width of textarea to fit buttons toolbar */
112
+.editable-wysihtml5 {
113
+    width: 566px; 
114
+    height: 250px; 
115
+}
116
+
117
+/* clear button shown as link in date inputs */
118
+.editable-clear {
119
+   clear: both;
120
+   font-size: 0.9em;
121
+   text-decoration: none;
122
+   text-align: right;
123
+}
124
+
125
+/* IOS-style clear button for text inputs */
126
+.editable-clear-x {
127
+   background: url('../images/clear.png') center center no-repeat;
128
+   display: block;
129
+   width: 13px;    
130
+   height: 13px;
131
+   position: absolute;
132
+   opacity: 0.6;
133
+   z-index: 100;
134
+   
135
+   top: 50%;
136
+   right: 6px;
137
+   margin-top: -6px;
138
+   
139
+}
140
+
141
+.editable-clear-x:hover {
142
+   opacity: 1;
143
+}
144
+
145
+.editable-pre-wrapped {
146
+   white-space: pre-wrap;
147
+}
148
+.editable-container.editable-popup {
149
+    max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
150
+}  
151
+
152
+.editable-container.popover {
153
+    width: auto; /* without this rule popover does not stretch */
154
+}
155
+
156
+.editable-container.editable-inline {
157
+    display: inline-block; 
158
+    vertical-align: middle;
159
+    width: auto;
160
+    /* inline-block emulation for IE7*/
161
+    zoom: 1; 
162
+    *display: inline;    
163
+}
164
+
165
+.editable-container.ui-widget {
166
+   font-size: inherit;  /* jqueryui widget font 1.1em too big, overwrite it */
167
+   z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
168
+}
169
+.editable-click, 
170
+a.editable-click, 
171
+a.editable-click:hover {
172
+    text-decoration: none;
173
+    border-bottom: dashed 1px #0088cc;
174
+}
175
+
176
+.editable-click.editable-disabled, 
177
+a.editable-click.editable-disabled, 
178
+a.editable-click.editable-disabled:hover {
179
+   color: #585858;  
180
+   cursor: default;
181
+   border-bottom: none;
182
+}
183
+
184
+.editable-empty, .editable-empty:hover, .editable-empty:focus{
185
+  font-style: italic; 
186
+  color: #DD1144;  
187
+  /* border-bottom: none; */
188
+  text-decoration: none;
189
+}
190
+
191
+.editable-unsaved {
192
+  font-weight: bold; 
193
+}
194
+
195
+.editable-unsaved:after {
196
+/*    content: '*'*/
197
+}
198
+
199
+.editable-bg-transition {
200
+  -webkit-transition: background-color 1400ms ease-out;
201
+  -moz-transition: background-color 1400ms ease-out;
202
+  -o-transition: background-color 1400ms ease-out;
203
+  -ms-transition: background-color 1400ms ease-out;
204
+  transition: background-color 1400ms ease-out;  
205
+}
206
+
207
+/*see https://github.com/vitalets/x-editable/issues/139 */
208
+.form-horizontal .editable
209
+{ 
210
+    padding-top: 5px;
211
+    display:inline-block;
212
+}
213
+
214
+
215
+/*!
216
+ * Datepicker for Bootstrap
217
+ *
218
+ * Copyright 2012 Stefan Petre
219
+ * Improvements by Andrew Rowls
220
+ * Licensed under the Apache License v2.0
221
+ * http://www.apache.org/licenses/LICENSE-2.0
222
+ *
223
+ */
224
+.datepicker {
225
+  padding: 4px;
226
+  -webkit-border-radius: 4px;
227
+  -moz-border-radius: 4px;
228
+  border-radius: 4px;
229
+  direction: ltr;
230
+  /*.dow {
231
+		border-top: 1px solid #ddd !important;
232
+	}*/
233
+
234
+}
235
+.datepicker-inline {
236
+  width: 220px;
237
+}
238
+.datepicker.datepicker-rtl {
239
+  direction: rtl;
240
+}
241
+.datepicker.datepicker-rtl table tr td span {
242
+  float: right;
243
+}
244
+.datepicker-dropdown {
245
+  top: 0;
246
+  left: 0;
247
+}
248
+.datepicker-dropdown:before {
249
+  content: '';
250
+  display: inline-block;
251
+  border-left: 7px solid transparent;
252
+  border-right: 7px solid transparent;
253
+  border-bottom: 7px solid #ccc;
254
+  border-bottom-color: rgba(0, 0, 0, 0.2);
255
+  position: absolute;
256
+  top: -7px;
257
+  left: 6px;
258
+}
259
+.datepicker-dropdown:after {
260
+  content: '';
261
+  display: inline-block;
262
+  border-left: 6px solid transparent;
263
+  border-right: 6px solid transparent;
264
+  border-bottom: 6px solid #ffffff;
265
+  position: absolute;
266
+  top: -6px;
267
+  left: 7px;
268
+}
269
+.datepicker > div {
270
+  display: none;
271
+}
272
+.datepicker.days div.datepicker-days {
273
+  display: block;
274
+}
275
+.datepicker.months div.datepicker-months {
276
+  display: block;
277
+}
278
+.datepicker.years div.datepicker-years {
279
+  display: block;
280
+}
281
+.datepicker table {
282
+  margin: 0;
283
+}
284
+.datepicker td,
285
+.datepicker th {
286
+  text-align: center;
287
+  width: 20px;
288
+  height: 20px;
289
+  -webkit-border-radius: 4px;
290
+  -moz-border-radius: 4px;
291
+  border-radius: 4px;
292
+  border: none;
293
+}
294
+.table-striped .datepicker table tr td,
295
+.table-striped .datepicker table tr th {
296
+  background-color: transparent;
297
+}
298
+.datepicker table tr td.day:hover {
299
+  background: #eeeeee;
300
+  cursor: pointer;
301
+}
302
+.datepicker table tr td.old,
303
+.datepicker table tr td.new {
304
+  color: #999999;
305
+}
306
+.datepicker table tr td.disabled,
307
+.datepicker table tr td.disabled:hover {
308
+  background: none;
309
+  color: #999999;
310
+  cursor: default;
311
+}
312
+.datepicker table tr td.today,
313
+.datepicker table tr td.today:hover,
314
+.datepicker table tr td.today.disabled,
315
+.datepicker table tr td.today.disabled:hover {
316
+  background-color: #fde19a;
317
+  background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
318
+  background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
319
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
320
+  background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
321
+  background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
322
+  background-image: linear-gradient(top, #fdd49a, #fdf59a);
323
+  background-repeat: repeat-x;
324
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
325
+  border-color: #fdf59a #fdf59a #fbed50;
326
+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
327
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
328
+  color: #000;
329
+}
330
+.datepicker table tr td.today:hover,
331
+.datepicker table tr td.today:hover:hover,
332
+.datepicker table tr td.today.disabled:hover,
333
+.datepicker table tr td.today.disabled:hover:hover,
334
+.datepicker table tr td.today:active,
335
+.datepicker table tr td.today:hover:active,
336
+.datepicker table tr td.today.disabled:active,
337
+.datepicker table tr td.today.disabled:hover:active,
338
+.datepicker table tr td.today.active,
339
+.datepicker table tr td.today:hover.active,
340
+.datepicker table tr td.today.disabled.active,
341
+.datepicker table tr td.today.disabled:hover.active,
342
+.datepicker table tr td.today.disabled,
343
+.datepicker table tr td.today:hover.disabled,
344
+.datepicker table tr td.today.disabled.disabled,
345
+.datepicker table tr td.today.disabled:hover.disabled,
346
+.datepicker table tr td.today[disabled],
347
+.datepicker table tr td.today:hover[disabled],
348
+.datepicker table tr td.today.disabled[disabled],
349
+.datepicker table tr td.today.disabled:hover[disabled] {
350
+  background-color: #fdf59a;
351
+}
352
+.datepicker table tr td.today:active,
353
+.datepicker table tr td.today:hover:active,
354
+.datepicker table tr td.today.disabled:active,
355
+.datepicker table tr td.today.disabled:hover:active,
356
+.datepicker table tr td.today.active,
357
+.datepicker table tr td.today:hover.active,
358
+.datepicker table tr td.today.disabled.active,
359
+.datepicker table tr td.today.disabled:hover.active {
360
+  background-color: #fbf069 \9;
361
+}
362
+.datepicker table tr td.today:hover:hover {
363
+  color: #000;
364
+}
365
+.datepicker table tr td.today.active:hover {
366
+  color: #fff;
367
+}
368
+.datepicker table tr td.range,
369
+.datepicker table tr td.range:hover,
370
+.datepicker table tr td.range.disabled,
371
+.datepicker table tr td.range.disabled:hover {
372
+  background: #eeeeee;
373
+  -webkit-border-radius: 0;
374
+  -moz-border-radius: 0;
375
+  border-radius: 0;
376
+}
377
+.datepicker table tr td.range.today,
378
+.datepicker table tr td.range.today:hover,
379
+.datepicker table tr td.range.today.disabled,
380
+.datepicker table tr td.range.today.disabled:hover {
381
+  background-color: #f3d17a;
382
+  background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
383
+  background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
384
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
385
+  background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
386
+  background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
387
+  background-image: linear-gradient(top, #f3c17a, #f3e97a);
388
+  background-repeat: repeat-x;
389
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
390
+  border-color: #f3e97a #f3e97a #edde34;
391
+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
392
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
393
+  -webkit-border-radius: 0;
394
+  -moz-border-radius: 0;
395
+  border-radius: 0;
396
+}
397
+.datepicker table tr td.range.today:hover,
398
+.datepicker table tr td.range.today:hover:hover,
399
+.datepicker table tr td.range.today.disabled:hover,
400
+.datepicker table tr td.range.today.disabled:hover:hover,
401
+.datepicker table tr td.range.today:active,
402
+.datepicker table tr td.range.today:hover:active,
403
+.datepicker table tr td.range.today.disabled:active,
404
+.datepicker table tr td.range.today.disabled:hover:active,
405
+.datepicker table tr td.range.today.active,
406
+.datepicker table tr td.range.today:hover.active,
407
+.datepicker table tr td.range.today.disabled.active,
408
+.datepicker table tr td.range.today.disabled:hover.active,
409
+.datepicker table tr td.range.today.disabled,
410
+.datepicker table tr td.range.today:hover.disabled,
411
+.datepicker table tr td.range.today.disabled.disabled,
412
+.datepicker table tr td.range.today.disabled:hover.disabled,
413
+.datepicker table tr td.range.today[disabled],
414
+.datepicker table tr td.range.today:hover[disabled],
415
+.datepicker table tr td.range.today.disabled[disabled],
416
+.datepicker table tr td.range.today.disabled:hover[disabled] {
417
+  background-color: #f3e97a;
418
+}
419
+.datepicker table tr td.range.today:active,
420
+.datepicker table tr td.range.today:hover:active,
421
+.datepicker table tr td.range.today.disabled:active,
422
+.datepicker table tr td.range.today.disabled:hover:active,
423
+.datepicker table tr td.range.today.active,
424
+.datepicker table tr td.range.today:hover.active,
425
+.datepicker table tr td.range.today.disabled.active,
426
+.datepicker table tr td.range.today.disabled:hover.active {
427
+  background-color: #efe24b \9;
428
+}
429
+.datepicker table tr td.selected,
430
+.datepicker table tr td.selected:hover,
431
+.datepicker table tr td.selected.disabled,
432
+.datepicker table tr td.selected.disabled:hover {
433
+  background-color: #9e9e9e;
434
+  background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
435
+  background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
436
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
437
+  background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
438
+  background-image: -o-linear-gradient(top, #b3b3b3, #808080);
439
+  background-image: linear-gradient(top, #b3b3b3, #808080);
440
+  background-repeat: repeat-x;
441
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
442
+  border-color: #808080 #808080 #595959;
443
+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
444
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
445
+  color: #fff;
446
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
447
+}
448
+.datepicker table tr td.selected:hover,
449
+.datepicker table tr td.selected:hover:hover,
450
+.datepicker table tr td.selected.disabled:hover,
451
+.datepicker table tr td.selected.disabled:hover:hover,
452
+.datepicker table tr td.selected:active,
453
+.datepicker table tr td.selected:hover:active,
454
+.datepicker table tr td.selected.disabled:active,
455
+.datepicker table tr td.selected.disabled:hover:active,
456
+.datepicker table tr td.selected.active,
457
+.datepicker table tr td.selected:hover.active,
458
+.datepicker table tr td.selected.disabled.active,
459
+.datepicker table tr td.selected.disabled:hover.active,
460
+.datepicker table tr td.selected.disabled,
461
+.datepicker table tr td.selected:hover.disabled,
462
+.datepicker table tr td.selected.disabled.disabled,
463
+.datepicker table tr td.selected.disabled:hover.disabled,
464
+.datepicker table tr td.selected[disabled],
465
+.datepicker table tr td.selected:hover[disabled],
466
+.datepicker table tr td.selected.disabled[disabled],
467
+.datepicker table tr td.selected.disabled:hover[disabled] {
468
+  background-color: #808080;
469
+}
470
+.datepicker table tr td.selected:active,
471
+.datepicker table tr td.selected:hover:active,
472
+.datepicker table tr td.selected.disabled:active,
473
+.datepicker table tr td.selected.disabled:hover:active,
474
+.datepicker table tr td.selected.active,
475
+.datepicker table tr td.selected:hover.active,
476
+.datepicker table tr td.selected.disabled.active,
477
+.datepicker table tr td.selected.disabled:hover.active {
478
+  background-color: #666666 \9;
479
+}
480
+.datepicker table tr td.active,
481
+.datepicker table tr td.active:hover,
482
+.datepicker table tr td.active.disabled,
483
+.datepicker table tr td.active.disabled:hover {
484
+  background-color: #006dcc;
485
+  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
486
+  background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
487
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
488
+  background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
489
+  background-image: -o-linear-gradient(top, #0088cc, #0044cc);
490
+  background-image: linear-gradient(top, #0088cc, #0044cc);
491
+  background-repeat: repeat-x;
492
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
493
+  border-color: #0044cc #0044cc #002a80;
494
+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
495
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
496
+  color: #fff;
497
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
498
+}
499
+.datepicker table tr td.active:hover,
500
+.datepicker table tr td.active:hover:hover,
501
+.datepicker table tr td.active.disabled:hover,
502
+.datepicker table tr td.active.disabled:hover:hover,
503
+.datepicker table tr td.active:active,
504
+.datepicker table tr td.active:hover:active,
505
+.datepicker table tr td.active.disabled:active,
506
+.datepicker table tr td.active.disabled:hover:active,
507
+.datepicker table tr td.active.active,
508
+.datepicker table tr td.active:hover.active,
509
+.datepicker table tr td.active.disabled.active,
510
+.datepicker table tr td.active.disabled:hover.active,
511
+.datepicker table tr td.active.disabled,
512
+.datepicker table tr td.active:hover.disabled,
513
+.datepicker table tr td.active.disabled.disabled,
514
+.datepicker table tr td.active.disabled:hover.disabled,
515
+.datepicker table tr td.active[disabled],
516
+.datepicker table tr td.active:hover[disabled],
517
+.datepicker table tr td.active.disabled[disabled],
518
+.datepicker table tr td.active.disabled:hover[disabled] {
519
+  background-color: #0044cc;
520
+}
521
+.datepicker table tr td.active:active,
522
+.datepicker table tr td.active:hover:active,
523
+.datepicker table tr td.active.disabled:active,
524
+.datepicker table tr td.active.disabled:hover:active,
525
+.datepicker table tr td.active.active,
526
+.datepicker table tr td.active:hover.active,
527
+.datepicker table tr td.active.disabled.active,
528
+.datepicker table tr td.active.disabled:hover.active {
529
+  background-color: #003399 \9;
530
+}
531
+.datepicker table tr td span {
532
+  display: block;
533
+  width: 23%;
534
+  height: 54px;
535
+  line-height: 54px;
536
+  float: left;
537
+  margin: 1%;
538
+  cursor: pointer;
539
+  -webkit-border-radius: 4px;
540
+  -moz-border-radius: 4px;
541
+  border-radius: 4px;
542
+}
543
+.datepicker table tr td span:hover {
544
+  background: #eeeeee;
545
+}
546
+.datepicker table tr td span.disabled,
547
+.datepicker table tr td span.disabled:hover {
548
+  background: none;
549
+  color: #999999;
550
+  cursor: default;
551
+}
552
+.datepicker table tr td span.active,
553
+.datepicker table tr td span.active:hover,
554
+.datepicker table tr td span.active.disabled,
555
+.datepicker table tr td span.active.disabled:hover {
556
+  background-color: #006dcc;
557
+  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
558
+  background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
559
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
560
+  background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
561
+  background-image: -o-linear-gradient(top, #0088cc, #0044cc);
562
+  background-image: linear-gradient(top, #0088cc, #0044cc);
563
+  background-repeat: repeat-x;
564
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
565
+  border-color: #0044cc #0044cc #002a80;
566
+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
567
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
568
+  color: #fff;
569
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
570
+}
571
+.datepicker table tr td span.active:hover,
572
+.datepicker table tr td span.active:hover:hover,
573
+.datepicker table tr td span.active.disabled:hover,
574
+.datepicker table tr td span.active.disabled:hover:hover,
575
+.datepicker table tr td span.active:active,
576
+.datepicker table tr td span.active:hover:active,
577
+.datepicker table tr td span.active.disabled:active,
578
+.datepicker table tr td span.active.disabled:hover:active,
579
+.datepicker table tr td span.active.active,
580
+.datepicker table tr td span.active:hover.active,
581
+.datepicker table tr td span.active.disabled.active,
582
+.datepicker table tr td span.active.disabled:hover.active,
583
+.datepicker table tr td span.active.disabled,
584
+.datepicker table tr td span.active:hover.disabled,
585
+.datepicker table tr td span.active.disabled.disabled,
586
+.datepicker table tr td span.active.disabled:hover.disabled,
587
+.datepicker table tr td span.active[disabled],
588
+.datepicker table tr td span.active:hover[disabled],
589
+.datepicker table tr td span.active.disabled[disabled],
590
+.datepicker table tr td span.active.disabled:hover[disabled] {
591
+  background-color: #0044cc;
592
+}
593
+.datepicker table tr td span.active:active,
594
+.datepicker table tr td span.active:hover:active,
595
+.datepicker table tr td span.active.disabled:active,
596
+.datepicker table tr td span.active.disabled:hover:active,
597
+.datepicker table tr td span.active.active,
598
+.datepicker table tr td span.active:hover.active,
599
+.datepicker table tr td span.active.disabled.active,
600
+.datepicker table tr td span.active.disabled:hover.active {
601
+  background-color: #003399 \9;
602
+}
603
+.datepicker table tr td span.old,
604
+.datepicker table tr td span.new {
605
+  color: #999999;
606
+}
607
+.datepicker th.datepicker-switch {
608
+  width: 145px;
609
+}
610
+.datepicker thead tr:first-child th,
611
+.datepicker tfoot tr th {
612
+  cursor: pointer;
613
+}
614
+.datepicker thead tr:first-child th:hover,
615
+.datepicker tfoot tr th:hover {
616
+  background: #eeeeee;
617
+}
618
+.datepicker .cw {
619
+  font-size: 10px;
620
+  width: 12px;
621
+  padding: 0 2px 0 5px;
622
+  vertical-align: middle;
623
+}
624
+.datepicker thead tr:first-child th.cw {
625
+  cursor: default;
626
+  background-color: transparent;
627
+}
628
+.input-append.date .add-on i,
629
+.input-prepend.date .add-on i {
630
+  display: block;
631
+  cursor: pointer;
632
+  width: 16px;
633
+  height: 16px;
634
+}
635
+.input-daterange input {
636
+  text-align: center;
637
+}
638
+.input-daterange input:first-child {
639
+  -webkit-border-radius: 3px 0 0 3px;
640
+  -moz-border-radius: 3px 0 0 3px;
641
+  border-radius: 3px 0 0 3px;
642
+}
643
+.input-daterange input:last-child {
644
+  -webkit-border-radius: 0 3px 3px 0;
645
+  -moz-border-radius: 0 3px 3px 0;
646
+  border-radius: 0 3px 3px 0;
647
+}
648
+.input-daterange .add-on {
649
+  display: inline-block;
650
+  width: auto;
651
+  min-width: 16px;
652
+  height: 18px;
653
+  padding: 4px 5px;
654
+  font-weight: normal;
655
+  line-height: 18px;
656
+  text-align: center;
657
+  text-shadow: 0 1px 0 #ffffff;
658
+  vertical-align: middle;
659
+  background-color: #eeeeee;
660
+  border: 1px solid #ccc;
661
+  margin-left: -5px;
662
+  margin-right: -5px;
663
+}

+ 1310
- 0
public/assets/css/bootstrap-override.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 476
- 0
public/assets/css/bootstrap-theme.css Прегледај датотеку

@@ -0,0 +1,476 @@
1
+/*!
2
+ * Bootstrap v3.3.4 (http://getbootstrap.com)
3
+ * Copyright 2011-2015 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+
7
+.btn-default,
8
+.btn-primary,
9
+.btn-success,
10
+.btn-info,
11
+.btn-warning,
12
+.btn-danger {
13
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
14
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
15
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
16
+}
17
+.btn-default:active,
18
+.btn-primary:active,
19
+.btn-success:active,
20
+.btn-info:active,
21
+.btn-warning:active,
22
+.btn-danger:active,
23
+.btn-default.active,
24
+.btn-primary.active,
25
+.btn-success.active,
26
+.btn-info.active,
27
+.btn-warning.active,
28
+.btn-danger.active {
29
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
30
+          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
31
+}
32
+.btn-default .badge,
33
+.btn-primary .badge,
34
+.btn-success .badge,
35
+.btn-info .badge,
36
+.btn-warning .badge,
37
+.btn-danger .badge {
38
+  text-shadow: none;
39
+}
40
+.btn:active,
41
+.btn.active {
42
+  background-image: none;
43
+}
44
+.btn-default {
45
+  text-shadow: 0 1px 0 #fff;
46
+  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
47
+  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
48
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
49
+  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
50
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
51
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
52
+  background-repeat: repeat-x;
53
+  border-color: #dbdbdb;
54
+  border-color: #ccc;
55
+}
56
+.btn-default:hover,
57
+.btn-default:focus {
58
+  background-color: #e0e0e0;
59
+  background-position: 0 -15px;
60
+}
61
+.btn-default:active,
62
+.btn-default.active {
63
+  background-color: #e0e0e0;
64
+  border-color: #dbdbdb;
65
+}
66
+.btn-default.disabled,
67
+.btn-default:disabled,
68
+.btn-default[disabled] {
69
+  background-color: #e0e0e0;
70
+  background-image: none;
71
+}
72
+.btn-primary {
73
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
74
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
75
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
76
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
77
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
78
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
79
+  background-repeat: repeat-x;
80
+  border-color: #245580;
81
+}
82
+.btn-primary:hover,
83
+.btn-primary:focus {
84
+  background-color: #265a88;
85
+  background-position: 0 -15px;
86
+}
87
+.btn-primary:active,
88
+.btn-primary.active {
89
+  background-color: #265a88;
90
+  border-color: #245580;
91
+}
92
+.btn-primary.disabled,
93
+.btn-primary:disabled,
94
+.btn-primary[disabled] {
95
+  background-color: #265a88;
96
+  background-image: none;
97
+}
98
+.btn-success {
99
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
100
+  background-image:      -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
101
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
102
+  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
103
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
104
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
105
+  background-repeat: repeat-x;
106
+  border-color: #3e8f3e;
107
+}
108
+.btn-success:hover,
109
+.btn-success:focus {
110
+  background-color: #419641;
111
+  background-position: 0 -15px;
112
+}
113
+.btn-success:active,
114
+.btn-success.active {
115
+  background-color: #419641;
116
+  border-color: #3e8f3e;
117
+}
118
+.btn-success.disabled,
119
+.btn-success:disabled,
120
+.btn-success[disabled] {
121
+  background-color: #419641;
122
+  background-image: none;
123
+}
124
+.btn-info {
125
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
126
+  background-image:      -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
127
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
128
+  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
129
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
130
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
131
+  background-repeat: repeat-x;
132
+  border-color: #28a4c9;
133
+}
134
+.btn-info:hover,
135
+.btn-info:focus {
136
+  background-color: #2aabd2;
137
+  background-position: 0 -15px;
138
+}
139
+.btn-info:active,
140
+.btn-info.active {
141
+  background-color: #2aabd2;
142
+  border-color: #28a4c9;
143
+}
144
+.btn-info.disabled,
145
+.btn-info:disabled,
146
+.btn-info[disabled] {
147
+  background-color: #2aabd2;
148
+  background-image: none;
149
+}
150
+.btn-warning {
151
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
152
+  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
153
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
154
+  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
155
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
156
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
157
+  background-repeat: repeat-x;
158
+  border-color: #e38d13;
159
+}
160
+.btn-warning:hover,
161
+.btn-warning:focus {
162
+  background-color: #eb9316;
163
+  background-position: 0 -15px;
164
+}
165
+.btn-warning:active,
166
+.btn-warning.active {
167
+  background-color: #eb9316;
168
+  border-color: #e38d13;
169
+}
170
+.btn-warning.disabled,
171
+.btn-warning:disabled,
172
+.btn-warning[disabled] {
173
+  background-color: #eb9316;
174
+  background-image: none;
175
+}
176
+.btn-danger {
177
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
178
+  background-image:      -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
179
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
180
+  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
181
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
182
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
183
+  background-repeat: repeat-x;
184
+  border-color: #b92c28;
185
+}
186
+.btn-danger:hover,
187
+.btn-danger:focus {
188
+  background-color: #c12e2a;
189
+  background-position: 0 -15px;
190
+}
191
+.btn-danger:active,
192
+.btn-danger.active {
193
+  background-color: #c12e2a;
194
+  border-color: #b92c28;
195
+}
196
+.btn-danger.disabled,
197
+.btn-danger:disabled,
198
+.btn-danger[disabled] {
199
+  background-color: #c12e2a;
200
+  background-image: none;
201
+}
202
+.thumbnail,
203
+.img-thumbnail {
204
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
205
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
206
+}
207
+.dropdown-menu > li > a:hover,
208
+.dropdown-menu > li > a:focus {
209
+  background-color: #e8e8e8;
210
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
211
+  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
212
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
213
+  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
214
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
215
+  background-repeat: repeat-x;
216
+}
217
+.dropdown-menu > .active > a,
218
+.dropdown-menu > .active > a:hover,
219
+.dropdown-menu > .active > a:focus {
220
+  background-color: #2e6da4;
221
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
222
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
223
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
224
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
225
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
226
+  background-repeat: repeat-x;
227
+}
228
+.navbar-default {
229
+  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
230
+  background-image:      -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
231
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
232
+  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
233
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
234
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
235
+  background-repeat: repeat-x;
236
+  border-radius: 4px;
237
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
238
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
239
+}
240
+.navbar-default .navbar-nav > .open > a,
241
+.navbar-default .navbar-nav > .active > a {
242
+  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
243
+  background-image:      -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
244
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
245
+  background-image:         linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
246
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
247
+  background-repeat: repeat-x;
248
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
249
+          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
250
+}
251
+.navbar-brand,
252
+.navbar-nav > li > a {
253
+  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
254
+}
255
+.navbar-inverse {
256
+  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
257
+  background-image:      -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
258
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
259
+  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
260
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
261
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
262
+  background-repeat: repeat-x;
263
+}
264
+.navbar-inverse .navbar-nav > .open > a,
265
+.navbar-inverse .navbar-nav > .active > a {
266
+  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
267
+  background-image:      -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
268
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
269
+  background-image:         linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
270
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
271
+  background-repeat: repeat-x;
272
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
273
+          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
274
+}
275
+.navbar-inverse .navbar-brand,
276
+.navbar-inverse .navbar-nav > li > a {
277
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
278
+}
279
+.navbar-static-top,
280
+.navbar-fixed-top,
281
+.navbar-fixed-bottom {
282
+  border-radius: 0;
283
+}
284
+@media (max-width: 767px) {
285
+  .navbar .navbar-nav .open .dropdown-menu > .active > a,
286
+  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
287
+  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
288
+    color: #fff;
289
+    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
290
+    background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
291
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
292
+    background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
293
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
294
+    background-repeat: repeat-x;
295
+  }
296
+}
297
+.alert {
298
+  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
299
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
300
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
301
+}
302
+.alert-success {
303
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
304
+  background-image:      -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
305
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
306
+  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
307
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
308
+  background-repeat: repeat-x;
309
+  border-color: #b2dba1;
310
+}
311
+.alert-info {
312
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
313
+  background-image:      -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
314
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
315
+  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
316
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
317
+  background-repeat: repeat-x;
318
+  border-color: #9acfea;
319
+}
320
+.alert-warning {
321
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
322
+  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
323
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
324
+  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
325
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
326
+  background-repeat: repeat-x;
327
+  border-color: #f5e79e;
328
+}
329
+.alert-danger {
330
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
331
+  background-image:      -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
332
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
333
+  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
334
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
335
+  background-repeat: repeat-x;
336
+  border-color: #dca7a7;
337
+}
338
+.progress {
339
+  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
340
+  background-image:      -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
341
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
342
+  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
343
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
344
+  background-repeat: repeat-x;
345
+}
346
+.progress-bar {
347
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
348
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #286090 100%);
349
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
350
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #286090 100%);
351
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
352
+  background-repeat: repeat-x;
353
+}
354
+.progress-bar-success {
355
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
356
+  background-image:      -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
357
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
358
+  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
359
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
360
+  background-repeat: repeat-x;
361
+}
362
+.progress-bar-info {
363
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
364
+  background-image:      -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
365
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
366
+  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
367
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
368
+  background-repeat: repeat-x;
369
+}
370
+.progress-bar-warning {
371
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
372
+  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
373
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
374
+  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
375
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
376
+  background-repeat: repeat-x;
377
+}
378
+.progress-bar-danger {
379
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
380
+  background-image:      -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
381
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
382
+  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
383
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
384
+  background-repeat: repeat-x;
385
+}
386
+.progress-bar-striped {
387
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
388
+  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
389
+  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
390
+}
391
+.list-group {
392
+  border-radius: 4px;
393
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
394
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
395
+}
396
+.list-group-item.active,
397
+.list-group-item.active:hover,
398
+.list-group-item.active:focus {
399
+  text-shadow: 0 -1px 0 #286090;
400
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
401
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
402
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
403
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
404
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
405
+  background-repeat: repeat-x;
406
+  border-color: #2b669a;
407
+}
408
+.list-group-item.active .badge,
409
+.list-group-item.active:hover .badge,
410
+.list-group-item.active:focus .badge {
411
+  text-shadow: none;
412
+}
413
+.panel {
414
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
415
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
416
+}
417
+.panel-default > .panel-heading {
418
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
419
+  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
420
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
421
+  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
422
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
423
+  background-repeat: repeat-x;
424
+}
425
+.panel-primary > .panel-heading {
426
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
427
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
428
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
429
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
430
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
431
+  background-repeat: repeat-x;
432
+}
433
+.panel-success > .panel-heading {
434
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
435
+  background-image:      -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
436
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
437
+  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
438
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
439
+  background-repeat: repeat-x;
440
+}
441
+.panel-info > .panel-heading {
442
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
443
+  background-image:      -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
444
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
445
+  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
446
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
447
+  background-repeat: repeat-x;
448
+}
449
+.panel-warning > .panel-heading {
450
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
451
+  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
452
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
453
+  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
454
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
455
+  background-repeat: repeat-x;
456
+}
457
+.panel-danger > .panel-heading {
458
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
459
+  background-image:      -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
460
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
461
+  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
462
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
463
+  background-repeat: repeat-x;
464
+}
465
+.well {
466
+  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
467
+  background-image:      -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
468
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
469
+  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
470
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
471
+  background-repeat: repeat-x;
472
+  border-color: #dcdcdc;
473
+  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
474
+          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
475
+}
476
+/*# sourceMappingURL=bootstrap-theme.css.map */

+ 1
- 0
public/assets/css/bootstrap-theme.css.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 5
- 0
public/assets/css/bootstrap-theme.min.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 10
- 0
public/assets/css/bootstrap-timepicker.min.css Прегледај датотеку

@@ -0,0 +1,10 @@
1
+/*!
2
+ * Timepicker Component for Twitter Bootstrap
3
+ *
4
+ * Copyright 2013 Joris de Wit
5
+ *
6
+ * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */.bootstrap-timepicker{position:relative}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu{left:auto;right:0}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before{left:auto;right:12px}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after{left:auto;right:13px}.bootstrap-timepicker .add-on{cursor:pointer}.bootstrap-timepicker .add-on i{display:inline-block;width:16px;height:16px}.bootstrap-timepicker-widget.dropdown-menu{padding:2px 3px 2px 2px}.bootstrap-timepicker-widget.dropdown-menu.open{display:inline-block}.bootstrap-timepicker-widget.dropdown-menu:before{border-bottom:7px solid rgba(0,0,0,0.2);border-left:7px solid transparent;border-right:7px solid transparent;content:"";display:inline-block;left:9px;position:absolute;top:-7px}.bootstrap-timepicker-widget.dropdown-menu:after{border-bottom:6px solid #fff;border-left:6px solid transparent;border-right:6px solid transparent;content:"";display:inline-block;left:10px;position:absolute;top:-6px}.bootstrap-timepicker-widget a.btn,.bootstrap-timepicker-widget input{border-radius:4px}.bootstrap-timepicker-widget table{width:100%;margin:0}.bootstrap-timepicker-widget table td{text-align:center;height:30px;margin:0;padding:2px}.bootstrap-timepicker-widget table td:not(.separator){min-width:30px}.bootstrap-timepicker-widget table td span{width:100%}.bootstrap-timepicker-widget table td a{border:1px transparent solid;width:100%;display:inline-block;margin:0;padding:8px 0;outline:0;color:#333}.bootstrap-timepicker-widget table td a:hover{text-decoration:none;background-color:#eee;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border-color:#ddd}.bootstrap-timepicker-widget table td a i{margin-top:2px}.bootstrap-timepicker-widget table td input{width:25px;margin:0;text-align:center}.bootstrap-timepicker-widget .modal-content{padding:4px}@media(min-width:767px){.bootstrap-timepicker-widget.modal{width:200px;margin-left:-100px}}@media(max-width:767px){.bootstrap-timepicker{width:100%}.bootstrap-timepicker .dropdown-menu{width:100%}}

+ 98
- 0
public/assets/css/bootstrap-wysihtml5.css Прегледај датотеку

@@ -0,0 +1,98 @@
1
+ul.wysihtml5-toolbar {
2
+	margin: 0;
3
+	padding: 0;
4
+	display: block;
5
+}
6
+
7
+ul.wysihtml5-toolbar::after {
8
+	clear: both;
9
+	display: table;
10
+	content: "";
11
+}
12
+
13
+ul.wysihtml5-toolbar > li {
14
+	float: left;
15
+	display: list-item;
16
+	list-style: none;
17
+	margin: 0 5px 10px 0;
18
+}
19
+
20
+ul.wysihtml5-toolbar a[data-wysihtml5-command=bold] {
21
+	font-weight: bold;
22
+}
23
+
24
+ul.wysihtml5-toolbar a[data-wysihtml5-command=italic] {
25
+	font-style: italic;
26
+}
27
+
28
+ul.wysihtml5-toolbar a[data-wysihtml5-command=underline] {
29
+	text-decoration: underline;
30
+}
31
+
32
+ul.wysihtml5-toolbar a.btn.wysihtml5-command-active {
33
+	background-image: none;
34
+	background-color: #fff;
35
+	outline: 0;
36
+}
37
+
38
+ul.wysihtml5-commands-disabled .dropdown-menu {
39
+	display: none !important;
40
+}
41
+
42
+ul.wysihtml5-toolbar div.wysihtml5-colors {
43
+  display:block;
44
+  width: 50px;
45
+  height: 20px;
46
+  margin-top: 2px;
47
+  margin-left: 5px;
48
+  position: absolute;
49
+  pointer-events: none;
50
+}
51
+
52
+ul.wysihtml5-toolbar a.wysihtml5-colors-title {
53
+  padding-left: 70px;
54
+}
55
+
56
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="black"] {
57
+  background: black !important;
58
+}
59
+
60
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="silver"] {
61
+  background: silver !important;
62
+}
63
+
64
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="gray"] {
65
+  background: gray !important;
66
+}
67
+
68
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="maroon"] {
69
+  background: maroon !important;
70
+}
71
+
72
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="red"] {
73
+  background: red !important;
74
+}
75
+
76
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="purple"] {
77
+  background: purple !important;
78
+}
79
+
80
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="green"] {
81
+  background: green !important;
82
+}
83
+
84
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="olive"] {
85
+  background: olive !important;
86
+}
87
+
88
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="navy"] {
89
+  background: navy !important;
90
+}
91
+
92
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="blue"] {
93
+  background: blue !important;
94
+}
95
+
96
+ul.wysihtml5-toolbar div[data-wysihtml5-command-value="orange"] {
97
+  background: orange !important;
98
+}

+ 6585
- 0
public/assets/css/bootstrap.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 0
public/assets/css/bootstrap.css.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 5
- 0
public/assets/css/bootstrap.min.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 264
- 0
public/assets/css/codemirror/codemirror.css Прегледај датотеку

@@ -0,0 +1,264 @@
1
+/* BASICS */
2
+
3
+.CodeMirror {
4
+  /* Set height, width, borders, and global font properties here */
5
+  font-family: monospace;
6
+  height: 300px;
7
+}
8
+.CodeMirror-scroll {
9
+  /* Set scrolling behaviour here */
10
+  overflow: auto;
11
+}
12
+
13
+/* PADDING */
14
+
15
+.CodeMirror-lines {
16
+  padding: 4px 0; /* Vertical padding around content */
17
+}
18
+.CodeMirror pre {
19
+  padding: 0 4px; /* Horizontal padding of content */
20
+}
21
+
22
+.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
23
+  background-color: white; /* The little square between H and V scrollbars */
24
+}
25
+
26
+/* GUTTER */
27
+
28
+.CodeMirror-gutters {
29
+  border-right: 1px solid #ddd;
30
+  background-color: #f7f7f7;
31
+  white-space: nowrap;
32
+}
33
+.CodeMirror-linenumbers {}
34
+.CodeMirror-linenumber {
35
+  padding: 0 3px 0 5px;
36
+  min-width: 20px;
37
+  text-align: right;
38
+  color: #999;
39
+  -moz-box-sizing: content-box;
40
+  box-sizing: content-box;
41
+}
42
+
43
+/* CURSOR */
44
+
45
+.CodeMirror div.CodeMirror-cursor {
46
+  border-left: 1px solid black;
47
+  z-index: 3;
48
+}
49
+/* Shown when moving in bi-directional text */
50
+.CodeMirror div.CodeMirror-secondarycursor {
51
+  border-left: 1px solid silver;
52
+}
53
+.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
54
+  width: auto;
55
+  border: 0;
56
+  background: #7e7;
57
+  z-index: 1;
58
+}
59
+/* Can style cursor different in overwrite (non-insert) mode */
60
+.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
61
+
62
+.cm-tab { display: inline-block; }
63
+
64
+.CodeMirror-ruler {
65
+  border-left: 1px solid #ccc;
66
+  position: absolute;
67
+}
68
+
69
+/* DEFAULT THEME */
70
+
71
+.cm-s-default .cm-keyword {color: #708;}
72
+.cm-s-default .cm-atom {color: #219;}
73
+.cm-s-default .cm-number {color: #164;}
74
+.cm-s-default .cm-def {color: #00f;}
75
+.cm-s-default .cm-variable {color: black;}
76
+.cm-s-default .cm-variable-2 {color: #05a;}
77
+.cm-s-default .cm-variable-3 {color: #085;}
78
+.cm-s-default .cm-property {color: black;}
79
+.cm-s-default .cm-operator {color: black;}
80
+.cm-s-default .cm-comment {color: #a50;}
81
+.cm-s-default .cm-string {color: #a11;}
82
+.cm-s-default .cm-string-2 {color: #f50;}
83
+.cm-s-default .cm-meta {color: #555;}
84
+.cm-s-default .cm-qualifier {color: #555;}
85
+.cm-s-default .cm-builtin {color: #30a;}
86
+.cm-s-default .cm-bracket {color: #997;}
87
+.cm-s-default .cm-tag {color: #170;}
88
+.cm-s-default .cm-attribute {color: #00c;}
89
+.cm-s-default .cm-header {color: blue;}
90
+.cm-s-default .cm-quote {color: #090;}
91
+.cm-s-default .cm-hr {color: #999;}
92
+.cm-s-default .cm-link {color: #00c;}
93
+
94
+.cm-negative {color: #d44;}
95
+.cm-positive {color: #292;}
96
+.cm-header, .cm-strong {font-weight: bold;}
97
+.cm-em {font-style: italic;}
98
+.cm-link {text-decoration: underline;}
99
+
100
+.cm-s-default .cm-error {color: #f00;}
101
+.cm-invalidchar {color: #f00;}
102
+
103
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
104
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
105
+.CodeMirror-activeline-background {background: #e8f2ff;}
106
+
107
+/* STOP */
108
+
109
+/* The rest of this file contains styles related to the mechanics of
110
+   the editor. You probably shouldn't touch them. */
111
+
112
+.CodeMirror {
113
+  line-height: 1;
114
+  position: relative;
115
+  overflow: hidden;
116
+  background: white;
117
+  color: black;
118
+}
119
+
120
+.CodeMirror-scroll {
121
+  /* 30px is the magic margin used to hide the element's real scrollbars */
122
+  /* See overflow: hidden in .CodeMirror */
123
+  margin-bottom: -30px; margin-right: -30px;
124
+  padding-bottom: 30px;
125
+  height: 100%;
126
+  outline: none; /* Prevent dragging from highlighting the element */
127
+  position: relative;
128
+  -moz-box-sizing: content-box;
129
+  box-sizing: content-box;
130
+}
131
+.CodeMirror-sizer {
132
+  position: relative;
133
+  border-right: 30px solid transparent;
134
+  -moz-box-sizing: content-box;
135
+  box-sizing: content-box;
136
+}
137
+
138
+/* The fake, visible scrollbars. Used to force redraw during scrolling
139
+   before actuall scrolling happens, thus preventing shaking and
140
+   flickering artifacts. */
141
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
142
+  position: absolute;
143
+  z-index: 6;
144
+  display: none;
145
+}
146
+.CodeMirror-vscrollbar {
147
+  right: 0; top: 0;
148
+  overflow-x: hidden;
149
+  overflow-y: scroll;
150
+}
151
+.CodeMirror-hscrollbar {
152
+  bottom: 0; left: 0;
153
+  overflow-y: hidden;
154
+  overflow-x: scroll;
155
+}
156
+.CodeMirror-scrollbar-filler {
157
+  right: 0; bottom: 0;
158
+}
159
+.CodeMirror-gutter-filler {
160
+  left: 0; bottom: 0;
161
+}
162
+
163
+.CodeMirror-gutters {
164
+  position: absolute; left: 0; top: 0;
165
+  padding-bottom: 30px;
166
+  z-index: 3;
167
+}
168
+.CodeMirror-gutter {
169
+  white-space: normal;
170
+  height: 100%;
171
+  -moz-box-sizing: content-box;
172
+  box-sizing: content-box;
173
+  padding-bottom: 30px;
174
+  margin-bottom: -32px;
175
+  display: inline-block;
176
+  /* Hack to make IE7 behave */
177
+  *zoom:1;
178
+  *display:inline;
179
+}
180
+.CodeMirror-gutter-elt {
181
+  position: absolute;
182
+  cursor: default;
183
+  z-index: 4;
184
+}
185
+
186
+.CodeMirror-lines {
187
+  cursor: text;
188
+}
189
+.CodeMirror pre {
190
+  /* Reset some styles that the rest of the page might have set */
191
+  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
192
+  border-width: 0;
193
+  background: transparent;
194
+  font-family: inherit;
195
+  font-size: inherit;
196
+  margin: 0;
197
+  white-space: pre;
198
+  word-wrap: normal;
199
+  line-height: inherit;
200
+  color: inherit;
201
+  z-index: 2;
202
+  position: relative;
203
+  overflow: visible;
204
+}
205
+.CodeMirror-wrap pre {
206
+  word-wrap: break-word;
207
+  white-space: pre-wrap;
208
+  word-break: normal;
209
+}
210
+
211
+.CodeMirror-linebackground {
212
+  position: absolute;
213
+  left: 0; right: 0; top: 0; bottom: 0;
214
+  z-index: 0;
215
+}
216
+
217
+.CodeMirror-linewidget {
218
+  position: relative;
219
+  z-index: 2;
220
+  overflow: auto;
221
+}
222
+
223
+.CodeMirror-widget {}
224
+
225
+.CodeMirror-wrap .CodeMirror-scroll {
226
+  overflow-x: hidden;
227
+}
228
+
229
+.CodeMirror-measure {
230
+  position: absolute;
231
+  width: 100%;
232
+  height: 0;
233
+  overflow: hidden;
234
+  visibility: hidden;
235
+}
236
+.CodeMirror-measure pre { position: static; }
237
+
238
+.CodeMirror div.CodeMirror-cursor {
239
+  position: absolute;
240
+  visibility: hidden;
241
+  border-right: none;
242
+  width: 0;
243
+}
244
+.CodeMirror-focused div.CodeMirror-cursor {
245
+  visibility: visible;
246
+}
247
+
248
+.CodeMirror-selected { background: #d9d9d9; }
249
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
250
+
251
+.cm-searching {
252
+  background: #ffa;
253
+  background: rgba(255, 255, 0, .4);
254
+}
255
+
256
+/* IE7 hack to prevent it from returning funny offsetTops on the spans */
257
+.CodeMirror span { *vertical-align: text-bottom; }
258
+
259
+@media print {
260
+  /* Hide the cursor when printing */
261
+  .CodeMirror div.CodeMirror-cursor {
262
+    visibility: hidden;
263
+  }
264
+}

+ 13
- 0
public/assets/css/codemirror/index.html Прегледај датотеку

@@ -0,0 +1,13 @@
1
+<!DOCTYPE html>
2
+
3
+<html>
4
+<head>
5
+    <title>Forbidden</title>
6
+</head>
7
+
8
+<body>
9
+
10
+<h2>Forbidden</h2>
11
+
12
+</body>
13
+</html>

+ 75
- 0
public/assets/css/codemirror/theme/ambiance.css Прегледај датотеку

@@ -0,0 +1,75 @@
1
+/* ambiance theme for codemirror */
2
+
3
+/* Color scheme */
4
+
5
+.cm-s-ambiance .cm-keyword { color: #cda869; }
6
+.cm-s-ambiance .cm-atom { color: #CF7EA9; }
7
+.cm-s-ambiance .cm-number { color: #78CF8A; }
8
+.cm-s-ambiance .cm-def { color: #aac6e3; }
9
+.cm-s-ambiance .cm-variable { color: #ffb795; }
10
+.cm-s-ambiance .cm-variable-2 { color: #eed1b3; }
11
+.cm-s-ambiance .cm-variable-3 { color: #faded3; }
12
+.cm-s-ambiance .cm-property { color: #eed1b3; }
13
+.cm-s-ambiance .cm-operator {color: #fa8d6a;}
14
+.cm-s-ambiance .cm-comment { color: #555; font-style:italic; }
15
+.cm-s-ambiance .cm-string { color: #8f9d6a; }
16
+.cm-s-ambiance .cm-string-2 { color: #9d937c; }
17
+.cm-s-ambiance .cm-meta { color: #D2A8A1; }
18
+.cm-s-ambiance .cm-qualifier { color: yellow; }
19
+.cm-s-ambiance .cm-builtin { color: #9999cc; }
20
+.cm-s-ambiance .cm-bracket { color: #24C2C7; }
21
+.cm-s-ambiance .cm-tag { color: #fee4ff }
22
+.cm-s-ambiance .cm-attribute {  color: #9B859D; }
23
+.cm-s-ambiance .cm-header {color: blue;}
24
+.cm-s-ambiance .cm-quote { color: #24C2C7; }
25
+.cm-s-ambiance .cm-hr { color: pink; }
26
+.cm-s-ambiance .cm-link { color: #F4C20B; }
27
+.cm-s-ambiance .cm-special { color: #FF9D00; }
28
+.cm-s-ambiance .cm-error { color: #AF2018; }
29
+
30
+.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; }
31
+.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; }
32
+
33
+.cm-s-ambiance .CodeMirror-selected {
34
+  background: rgba(255, 255, 255, 0.15);
35
+}
36
+.cm-s-ambiance.CodeMirror-focused .CodeMirror-selected {
37
+  background: rgba(255, 255, 255, 0.10);
38
+}
39
+
40
+/* Editor styling */
41
+
42
+.cm-s-ambiance.CodeMirror {
43
+  line-height: 1.40em;
44
+  font-family: Monaco, Menlo,"Andale Mono","lucida console","Courier New",monospace !important;
45
+  color: #E6E1DC;
46
+  background-color: #202020;
47
+  -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.5);
48
+  -moz-box-shadow: inset 0 0 5px rgba(0,0,0,0.5);
49
+  box-shadow: inset 0 0 5px rgba(0,0,0,0.5);
50
+}
51
+
52
+.cm-s-ambiance .CodeMirror-gutters {
53
+  background: #3D3D3D;
54
+  border-right: 1px solid #4D4D4D;
55
+  box-shadow: 0 10px 5px rgba(0,0,0,0.5);
56
+}
57
+
58
+.cm-s-ambiance .CodeMirror-linenumber {
59
+  text-shadow: 0px 1px 1px #4d4d4d;
60
+  color: #222;
61
+  padding: 0 5px;
62
+}
63
+
64
+.cm-s-ambiance .CodeMirror-lines .CodeMirror-cursor {
65
+  border-left: 1px solid #7991E8;
66
+}
67
+
68
+.cm-s-ambiance .CodeMirror-activeline-background {
69
+  background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031);
70
+}
71
+
72
+.cm-s-ambiance.CodeMirror,
73
+.cm-s-ambiance .CodeMirror-gutters {
74
+  background: #333;
75
+}

+ 0
- 0
public/assets/css/codemirror/theme/index.html Прегледај датотеку


Неке датотеке нису приказане због велике количине промена