diff --git a/.env.example b/.env.example index 7492cb47c4d4eecd3dd2f38e62725384d20ef4e1..06f5f51dcec6ada03a4188f442e2e23bbbae979a 100644 --- a/.env.example +++ b/.env.example @@ -10,9 +10,9 @@ LOG_LEVEL=debug DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=laravel +DB_DATABASE=blog-community DB_USERNAME=root -DB_PASSWORD= +DB_PASSWORD=root DB_PREFIX=cnpscy_ BROADCAST_DRIVER=log diff --git a/README.en.md b/README.en.md index 62789d64c825d5e4912c1fcaa660a892972baa8c..3fd2a1e50dea0714faf957c72c7285fe92e6ff89 100644 --- a/README.en.md +++ b/README.en.md @@ -8,9 +8,21 @@ Software architecture description #### Installation -1. xxxx -2. xxxx -3. xxxx +###### 安装Vue +* 安装 npm 包:`npm install` +* 热更新vue项目:`npm run watch-poll` + + - vue无法执行:可尝试: + - npm rebuild node-sass + +###### PHP设置 +* 命令行:`composer install` +* 命令行:`cp .env.example .env` +* 命令行,生成 APP_KEY:`php artisan key:generate` +* 命令行,JWT的key:`php artisan jwt:secret` +* 导入根目录sql:`blog-community.sql` +* 任务调度:`php artisan schedule:run` + #### Instructions diff --git a/README.md b/README.md index 0767045c0b6d49d9d10872842e97b4ec0cacd64a..68963b699a4dd1d58259d6e9b411ffd80dd97795 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,21 @@ #### 安装教程 -1. xxxx -2. xxxx -3. xxxx +###### 安装Vue +* 安装 npm 包:`npm install` +* 热更新vue项目:`npm run watch-poll` + + - vue无法执行:可尝试: + - npm rebuild node-sass + +###### PHP设置 +* 命令行:`composer install` +* 命令行:`cp .env.example .env` +* 命令行,生成 APP_KEY:`php artisan key:generate` +* 命令行,JWT的key:`php artisan jwt:secret` +* 导入根目录sql:`blog-community.sql` +* 任务调度:`php artisan schedule:run` + #### 使用说明 diff --git a/app/Modules/Admin/Console/AutoTableBuild.php b/app/Console/Commands/AutoTableBuild.php similarity index 93% rename from app/Modules/Admin/Console/AutoTableBuild.php rename to app/Console/Commands/AutoTableBuild.php index 7c9b0c835fc30c08eaf632e267d5a8c4b5d21246..85ae842f61e2b1974422cf28f2c5b75ad19dda52 100644 --- a/app/Modules/Admin/Console/AutoTableBuild.php +++ b/app/Console/Commands/AutoTableBuild.php @@ -1,12 +1,13 @@ roles; - $rabc = $menu_lists = []; - foreach ($roles as $key => $role) { - $menus = $role->{$with_func}->toArray(); - $rabc[$role->role_id] = array_flip(array_unique(array_column($menus, 'menu_url'))); - $menu_lists = array_merge($menu_lists, $menus); - } - return ['rabc' => $rabc, 'menu' => $menu_lists]; -} - function get_request_post() { return request()->isMethod('post'); @@ -47,156 +34,12 @@ function modifyEnv(array $data) File::put($envPath, $content); } -/*************** 缓存函数 开始 ***************/ - -/** - * [set_cache] - * - * @param [type] $key [description] - * @param [type] $data [description] - * @param [type] $minutes [description]$minutes = 7*24*60*60 - * - * @author :cnpscy <[2278757482@qq.com]> - * @chineseAnnotation :设置缓存 - * @englishAnnotation : - */ -function set_cache($key, $data, $minutes = 1 * 60) -{ - return \Cache::put($key, $data, $minutes); -} - -/** - * [get_cache] - * - * @param [type] $key [description] - * - * @return [type] [description] - * @author :cnpscy <[2278757482@qq.com]> - * @chineseAnnotation :获取缓存的数据 - * @englishAnnotation : - */ -function get_cache($key) -{ - return \Cache::get($key) ?? ''; -} - -/** - * [has_cache] - * - * @param [type] $key [description] - * - * @return boolean [description] - * @author :cnpscy <[2278757482@qq.com]> - * @chineseAnnotation :是否存在该key的缓存 - * @englishAnnotation : - */ -function has_cache($key) -{ - return \Cache::has($key) ? true : false; -} - -/** - * [del_cache] - * - * @param [type] $key [description] - * - * @return [type] [description] - * @author :cnpscy <[2278757482@qq.com]> - * @chineseAnnotation :删除缓存 - * @englishAnnotation : - */ -function del_cache($key) -{ - return \Cache::forget($key) ?? false; -} - -/*************** 缓存函数 结束 ***************/ - - -/** - * [logs_data] - * - * @param [type] $data [description] - * - * @return [type] [description] - * @author :cnpscy <[2278757482@qq.com]> - * @chineseAnnotation :日志数据的过滤 - * @englishAnnotation : - */ -function logs_data($data, $ip_agent) -{ - $data['data'] = json_encode(request()->all()); - $data['action'] = request()->route()->getActionName(); - $data['description'] = $data['description'] ?? ''; - $data['add_time'] = $data['add_time'] ?? time(); - $data['ip'] = $ip_agent['ip'] ?? get_ip(); - $data['browser_type'] = $ip_agent['agent'] ?? $_SERVER['HTTP_USER_AGENT']; - return $data; -} - -/** - * 刷新用户权限、角色 - * 多角色管理 - */ -if (!function_exists('setAdminRabc')) { - function setAdminRabc() - { - $admin = auth('admin')->user(); - $roles = $menus = []; - $rolesResources = $admin->roles()->orderBy('role_id', 'ASC')->get(); - foreach ($rolesResources as $key => $roleResources) { - if ($key == 0) $role_id = $roleResources->role_id; - $roles[$roleResources->role_id] = $roleResources; - $menus[$roleResources->role_id] = array_filter($roleResources->left_menus()->get()->pluck('api_url')->toArray()); - } - - //默认使用第一个角色 - if (empty($admin->use_role)) \App\Models\BasicAdmin\Admin::where('admin_id', $admin->admin_id)->update(['use_role' => $role_id]); - - // 缓存用户权限 - cache()->forever('admin_rabc_' . $admin->admin_id, [ - 'roles' => $roles, - 'menus' => $menus - ]); - } -} - -/** - * 获取当前用户-当前角色-权限 - */ -if (!function_exists('getAdminRabc')) { - function getAdminRabc() - { - $admin = auth('admin')->user(); - $key = 'admin_rabc_' . $admin->admin_id; - if (cache()->has($key)) { - $admin_rabc = cache($key); - return [ - 'roles' => empty($admin->use_role) ? [] : $admin_rabc['roles'][$admin->use_role], - 'menus' => empty($admin->use_role) ? [] : $admin_rabc['menus'][$admin->use_role], - ]; - } - setAdminRabc(); - return cache($key); - } -} - - -function getWebUserHome(int $user_id = 0) -{ - return url('user/' . $user_id); -} function route_class() { return str_replace('.', '-', Route::currentRouteName()); } -function category_nav_active($category_id) -{ - return active_class((if_route('categories.show') && if_route_param('category', $category_id))); -} - function make_excerpt($value, $length = 200) { $excerpt = trim(preg_replace('/\r\n|\r|\n+/', ' ', strip_tags($value))); @@ -238,49 +81,11 @@ function model_plural_name($model) return Str::plural($snake_case_name); } -function get_web_admin_url(string $method, string $controller = '', int $is_compel = 0): string -{ - if (empty($method)) return ''; - $prefix = ltrim(request()->route()->getPrefix(), '/'); - // 如果后台访问地址对不上,关闭下行的注释 - // $prefix = str_replace(head(explode('/', $prefix)), cnpscy_config('web_admin_prefix'), $prefix); - if (empty($controller) && $is_compel == 0) { - $url = $prefix . '/' . ltrim($method, '/'); - } else { - $url = str_replace(last(explode('/', $prefix)), $controller, $prefix) . (empty($controller) ? '' : '/') . ltrim($method, '/'); - } - return url($url); -} - -function get_api_admin_url(string $method, string $controller = '', int $is_compel = 0) -{ - if (empty($method)) return ''; - $prefix = ltrim(request()->route()->getPrefix(), '/'); - $prefix = str_replace(head(explode('/', $prefix)), cnpscy_config('api_admin_prefix'), $prefix); - if (empty($controller) && $is_compel == 0) { - $url = 'api/' . $prefix . '/' . ltrim($method, '/'); - } else { - $url = 'api/' . str_replace(last(explode('/', $prefix)), $controller, $prefix) . (empty($controller) ? '' : '/') . ltrim($method, '/'); - } - return url($url); -} - -function get_model_url(string $method, string $controller = '', int $is_compel = 0) -{ - if (empty($method)) return url('/'); - $prefix = ltrim(request()->route()->getPrefix(), '/'); - if (empty($controller) && $is_compel == 0) { - $url = $prefix . '/' . ltrim($method, '/'); - } else { - $url = str_replace(last(explode('/', $prefix)), $controller, $prefix) . (empty($controller) ? '' : '/') . $method; - } - return url($url); -} function getControllerAndFunction() { $action = \Route::current()->getActionName(); - list($class, $method) = explode('@', $action); + [$class, $method] = explode('@', $action); $class = substr(strrchr($class, '\\'), 1); return ['controller' => $class, 'method' => $method]; } @@ -290,3 +95,19 @@ function getControllerRoutePrefix() $controller = getControllerAndFunction()['controller'] ?? ''; return strtolower(str_replace('Controller', '', $controller)); } + +/** + * 获取资源文件下的所有文件名称 + * + * @param string $path + * + * @return array|bool + */ +function getViewsByResource(string $path) +{ + $files = get_dir_files($path, ['layouts', '.gitkeep']); + foreach ($files as &$file){ + $file = str_replace('.blade.php', '', $file); + } + return $files; +} diff --git a/app/Helper/functions.php b/app/Helper/functions.php index 6148d071c022f5dce40e21b59f025a8c806bd91d..ff6f17a98fe5fa61830e34539f32e703b37fa6b5 100644 --- a/app/Helper/functions.php +++ b/app/Helper/functions.php @@ -1,5 +1,46 @@ $area_name, - 'key' => MyC('common_lbsamap_apikey'), - 'output' => 'JSON', - ], false); - if ( $res['status'] == 1 ) return empty($res['geocodes']) ? '' : $res['geocodes'][0]['location']; - return ''; -} - /** * 倒计时 转化成 天-时分秒 展示 * @@ -3298,13 +3320,6 @@ function countdownConversionTime($time) return $day . $hour . ':' . $minute . ':' . $second . ''; } -if ( !function_exists('returnLastPage') ) { - function returnLastPage() - { - echo ''; - } -} - if ( !function_exists('array_key_first') ) { /** * Gets the first key of an array diff --git a/app/Http/Middleware/ConvertEmptyStringsToNull.php b/app/Http/Middleware/ConvertEmptyStringsToNull.php index 386c627cefbe52a9b0b37813c14ce682d7f2b59a..d8a54b15098fb3ba77a7f088787f12a4e18d95fa 100644 --- a/app/Http/Middleware/ConvertEmptyStringsToNull.php +++ b/app/Http/Middleware/ConvertEmptyStringsToNull.php @@ -24,7 +24,7 @@ class ConvertEmptyStringsToNull ){ // 希望在POST、PUT时,新增与更新数据时,移除[空字符串自动转换为null的中间件]效果。 }else{ - (new \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull)->handle($request, $next); + return (new \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull)->handle($request, $next); } return $next($request); diff --git a/app/Models/Article/Article.php b/app/Models/Article/Article.php index 765c3859583865beb80d0cd670dd09afb10e357d..d5363b4413ccc2e46474f683b3bc18b47dae287c 100644 --- a/app/Models/Article/Article.php +++ b/app/Models/Article/Article.php @@ -2,24 +2,83 @@ namespace App\Models\Article; +use App\Constants\CacheKeys; +use App\Models\Bbs\Menu; use App\Models\Model; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Storage; class Article extends Model { protected $primaryKey = 'article_id'; - protected $is_delete = 0; + protected $is_delete = 0; + /** + * 只查询 启用 的作用域 + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeCheck($query) + { + return $query->where('is_check', 1); + } + + /** + * 获取文章的图片 + * + * @param $key + * + * @return string + */ public function getArticleCoverAttribute($key) { - if (empty($key)) return $key; + if ( empty($key) ) return $key; return Storage::url($key); } + /** + * 设置文章的图片 + * + * @param $key + */ public function setArticleCoverAttribute($key) { - if (!empty($key)) { - $this->attributes['article_cover'] = str_replace(Storage::url('/'), '', $key); + if ( !empty($this->attributes['article_images']) ) { + $this->attributes['article_cover'] = str_replace(Storage::url('/'), '', current(explode(',', $this->attributes['article_images']))); + }else{ + $this->attributes['article_cover'] = ''; + } + } + + /** + * 获取多图,自动转成数组 + * + * @param $key + * @return false|string[] + */ + public function getArticleImagesAttribute($key) + { + if ( empty($key) ) return []; + $imgs = explode(',', $key); + foreach ($imgs as &$img){ + $img = Storage::url($img); + } + return $imgs; + } + + /** + * 设置文章的图片 + * + * @param $key + */ + public function setArticleImagesAttribute($key) + { + if ( !empty($key) ) { + foreach ($key as &$value){ + $value = str_replace(Storage::url('/'), '', $value); + } + $this->attributes['article_images'] = implode(',', $key); } } @@ -30,6 +89,41 @@ class Article extends Model public function labels() { - return $this->belongsToMany(ArticleLabel::class, ArticleWithLabel::class, 'article_id' , 'label_id' , 'article_id', 'label_id')->withPivot(['article_id', 'label_id']); + return $this->belongsToMany(ArticleLabel::class, ArticleWithLabel::class, 'article_id', 'label_id', 'article_id', 'label_id')->withPivot([ + 'article_id', + 'label_id', + ]); + } + + public function content() + { + $primaryKey = $this->getKeyName(); + return $this->hasOne(ArticleContent::class, $primaryKey, $primaryKey); + } + + public function menu() + { + return $this->belongsTo(Menu::class, 'menu_id', 'menu_id'); + } + + /** + * 获取有效文章总量的统计 + * + * @param bool $force_update 是否强制更新缓存 + * + * @return int + */ + public function cacheStatistics(bool $force_update = false) : int + { + $cache_key = CacheKeys::CACHE_ARTICLE_COUNT; + // 强制更新缓存 + if ($force_update){ + // 删除缓存key + Cache::forget($cache_key); + } + $articles_count = Cache::remember($cache_key, CacheKeys::KEY_DEFAULT_TIMEOUT, function() { + return $this->check()->count(); + }); + return $articles_count; } } diff --git a/app/Models/Article/ArticleCategory.php b/app/Models/Article/ArticleCategory.php index b774f9497f1ded9ce64f6246ef3e4b62faea7b98..07ca4b9e0cd0677529633d756b6305a58c00b296 100644 --- a/app/Models/Article/ArticleCategory.php +++ b/app/Models/Article/ArticleCategory.php @@ -2,6 +2,7 @@ namespace App\Models\Article; +use App\Constants\CacheKeys; use App\Models\Model; use Illuminate\Support\Facades\Cache; @@ -36,7 +37,7 @@ class ArticleCategory extends Model */ private function getCache(string $get_type = '') { - return Cache::remember($this->cache_key, 3600, function() use ($get_type) { + return Cache::remember($this->cache_key, CacheKeys::KEY_DEFAULT_TIMEOUT, function() use ($get_type) { $all = $this->orderBy('category_sort', 'ASC')->get()->toArray(); $tree = list_to_tree($all, $this->getKeyName()); return compact('all', 'tree'); diff --git a/app/Models/Article/ArticleContent.php b/app/Models/Article/ArticleContent.php new file mode 100644 index 0000000000000000000000000000000000000000..c6f5f8ecf3e4eaa0c3ac8de0296e680110e6fc0a --- /dev/null +++ b/app/Models/Article/ArticleContent.php @@ -0,0 +1,11 @@ +belongsToMany(Article::class, + ArticleWithLabel::class, + 'label_id', + 'article_id', + 'label_id', + 'article_id') + ->withPivot([ + 'article_id', + 'label_id', + ]); + } + + /** + * 标签缓存数据 + * + * @return mixed + */ + public static function getLabelsByCache() + { + return Cache::remember(CacheKeys::CACHE_WEB_LABELS, CacheKeys::KEY_DEFAULT_TIMEOUT, function() { + return self::get(); + }); + } } diff --git a/app/Models/Bbs/Menu.php b/app/Models/Bbs/Menu.php new file mode 100644 index 0000000000000000000000000000000000000000..7564fa99788b4feccce137f5cc809ef6c530602b --- /dev/null +++ b/app/Models/Bbs/Menu.php @@ -0,0 +1,101 @@ +orderBy('menu_sort', 'ASC')->get()->toArray(); + }); + return $is_tree == true ? list_to_tree($menus) : $menus; + } + + public function getAllMenus() + { + return $this->orderBy('menu_sort', 'ASC')->get(); + } + + public function getSelectLists() + { + return list_to_tree($this->orderBy('menu_sort', 'ASC')->get()->toArray()); + } + + public function getMenusByIds(array $menu_ids) + { + return $this->whereIn('menu_id', $menu_ids) + ->orderBy('menu_sort', 'ASC') + ->get(); + } + + public function getMenuByUrl(string $menu_url) + { + return $this->where('menu_url', $menu_url)->first(); + } + + /** + * 获取指定菜单的所有子分类Id + * + * @param int $parent_id + * @param array $all + * @return array|int[] + */ + public static function getMenusChilds($parent_id = 0, $all = []): array + { + $arrIds = [$parent_id]; + empty($menus) && $menus = array_column(self::getMenusByWeb(false), null, 'menu_id'); + foreach ($menus as $key => $item) { + if ($item['parent_id'] == $parent_id) { + unset($all[$key]); + $subIds = self::getMenusChilds($item['menu_id'], $menus); + !empty($subIds) && $arrIds = array_merge($arrIds, $subIds); + } + } + return $arrIds; + } + + /** + * 通过菜单Id获取所有上级菜单 + * + * @param int $menu_id + * @param bool $has_self + * @param array $list_menus + * @param array $cache_menus + * + * @return array + */ + public static function getLocation(int $menu_id = 0, bool $has_self = true, $list_menus = [], $cache_menus = [], $self_id = 0): array + { + if (!$has_self && $self_id == 0) $self_id = $menu_id; + $cache_menus || $cache_menus = array_column(self::getMenusByWeb(false), null, 'menu_id'); + if ($menu_id && $localtion_menu = $cache_menus[$menu_id]) { + $list_menus[$menu_id] = $localtion_menu; + $list_menus = self::getLocation($localtion_menu['parent_id'], $has_self, $list_menus, $cache_menus, $self_id); + } + if (!$has_self) unset($list_menus[$self_id]); + ksort($list_menus); + $list_menus = array_values($list_menus); + return $list_menus; + } +} diff --git a/app/Models/Log/WebLog.php b/app/Models/Log/WebLog.php new file mode 100644 index 0000000000000000000000000000000000000000..7eea16d0ffbdd1e8c107d825a77a53dea3bb3886 --- /dev/null +++ b/app/Models/Log/WebLog.php @@ -0,0 +1,16 @@ +attributes['banner_cover'] = str_replace(Storage::url('/'), '', $key); } } + + /** + * 前端:获取Banner + * + * @param bool $force_update 是否强制更新缓存 + * + * @return mixed + */ + public static function getBannersByWeb(bool $force_update = false) + { + $cache_key = CacheKeys::CACHE_WEB_BANNERS; + // 强制更新缓存 + if ( $force_update ) { + // 删除缓存key + Cache::forget($cache_key); + } + $banners = Cache::remember($cache_key, CacheKeys::KEY_DEFAULT_TIMEOUT, function() { + return self::where('is_check', 1)->orderBy('banner_sort', 'ASC')->limit(20)->get(); + }); + return $banners; + } } diff --git a/app/Models/System/Friendlink.php b/app/Models/System/Friendlink.php index 1ff3a86eae9ac3dc6c42ed6ab4b8ebfd339c004b..365e5d70b35e3785df8a3c622d5befc91755ad1b 100644 --- a/app/Models/System/Friendlink.php +++ b/app/Models/System/Friendlink.php @@ -2,7 +2,9 @@ namespace App\Models\System; +use App\Constants\CacheKeys; use App\Models\Model; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Storage; class Friendlink extends Model @@ -22,4 +24,25 @@ class Friendlink extends Model $this->attributes['link_cover'] = str_replace(Storage::url('/'), '', $key); } } + + /** + * 前端:获取友情链接 + * + * @param bool $force_update 是否强制更新缓存 + * + * @return mixed + */ + public static function getFriendlinksByWeb(bool $force_update = false) + { + $cache_key = CacheKeys::CACHE_WEB_FRIENDLINKS; + // 强制更新缓存 + if ( $force_update ) { + // 删除缓存key + Cache::forget($cache_key); + } + $banners = Cache::remember($cache_key, CacheKeys::KEY_DEFAULT_TIMEOUT, function() { + return self::where('is_check', 1)->orderBy('link_sort', 'ASC')->get(); + }); + return $banners; + } } diff --git a/app/Modules/Admin/Http/Controllers/Bbs/MenuController.php b/app/Modules/Admin/Http/Controllers/Bbs/MenuController.php new file mode 100644 index 0000000000000000000000000000000000000000..b3a4b879b551264f8f8d735b516ee9e05e2b6cad --- /dev/null +++ b/app/Modules/Admin/Http/Controllers/Bbs/MenuController.php @@ -0,0 +1,37 @@ +service = $menuService; + } + + public function create(MenuRequest $request) + { + return $this->createService($request); + } + + public function update(MenuRequest $request) + { + return $this->updateService($request); + } + + public function getTplTypeAndViews(Request $request) + { + // 获取所有视图文件列表 + $view_lists = getViewsByResource(config('modules.paths.modules') . '/Bbs/Resources/views'); + + return $this->successJson([ + 'menu_type_list' => cnpscy_config('menu_type_list'), + 'view_lists' => $view_lists, + ]); + } +} diff --git a/app/Modules/Admin/Http/Controllers/UploadController.php b/app/Modules/Admin/Http/Controllers/UploadController.php index 5277dc1110d46c53bb99f80ce692b5aa81b8ebc9..a359a2c728f741a130415a6bd730f28ffbe2cf1d 100644 --- a/app/Modules/Admin/Http/Controllers/UploadController.php +++ b/app/Modules/Admin/Http/Controllers/UploadController.php @@ -28,4 +28,25 @@ class UploadController extends BaseController return $this->successJson($path, '上传成功', ['path_url' => Storage::url($path)]); } + + /** + * 批量上传图片 + * + * @param Request $request + * @param string $file + * @return \Illuminate\Http\JsonResponse + */ + public function files(Request $request, $file = 'files') + { + if (empty($request->file($file))){ + return $this->errorJson('请上传文件!'); + } + foreach ($request->file($file) as $file){ + $path[] = Storage::url($file->storePublicly( + date('Ym'), + config('filesystems') + )); + } + return $this->successJson($path, '上传成功!'); + } } diff --git a/app/Modules/Admin/Http/Requests/Article/ArticleRequest.php b/app/Modules/Admin/Http/Requests/Article/ArticleRequest.php index abeee690d0ac734818ff6ada2ccc15d38fd0c103..d772b991a304587dc01fd6496989a6c0eb1951c8 100644 --- a/app/Modules/Admin/Http/Requests/Article/ArticleRequest.php +++ b/app/Modules/Admin/Http/Requests/Article/ArticleRequest.php @@ -25,10 +25,7 @@ class ArticleRequest extends BaseRequest 'max:256', 'unique:' . $this->instance->getTable() . ',article_title' . $this->validate_id, ], - 'category_id' => [ - 'required', - ], - 'article_cover' => [ + 'menu_id' => [ 'required', ], ]; @@ -40,8 +37,7 @@ class ArticleRequest extends BaseRequest 'article_title.required' => '请输入文章标题!', 'article_title.max' => '标题字数不可超过 256!', 'article_title.unique' => '文章标题已存在,请更换!', - 'category_id.required' => '请选择文章分类!', - 'article_cover.required' => '请上传封面!', + 'menu_id.required' => '请选择所属栏目!', ]; } } diff --git a/app/Modules/Admin/Http/Requests/Bbs/MenuRequest.php b/app/Modules/Admin/Http/Requests/Bbs/MenuRequest.php new file mode 100644 index 0000000000000000000000000000000000000000..78471946cbd81fa7bb494dfea7d376aa2cd999f4 --- /dev/null +++ b/app/Modules/Admin/Http/Requests/Bbs/MenuRequest.php @@ -0,0 +1,37 @@ +instance = Menu::getInstance(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'menu_name' => [ + 'required', + 'max:256', + 'unique:' . $this->instance->getTable() . ',menu_name' . $this->validate_id + ], + ]; + } + + public function messages() + { + return [ + 'menu_name.required' => '请输入菜单名称!', + ]; + } +} diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/api.iml b/app/Modules/Admin/Resources/vue-element-admin/api/.idea/api.iml deleted file mode 100644 index d6ebd4805981b8400db3e3291c74a743fef9a824..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/api.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/misc.xml b/app/Modules/Admin/Resources/vue-element-admin/api/.idea/misc.xml deleted file mode 100644 index 7e5bdf89fec4690a0218e8d99983b379c8218059..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/modules.xml b/app/Modules/Admin/Resources/vue-element-admin/api/.idea/modules.xml deleted file mode 100644 index d50cf45fff2a9543c62b951c0f04316cf6df042a..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/vcs.xml b/app/Modules/Admin/Resources/vue-element-admin/api/.idea/vcs.xml deleted file mode 100644 index 821e530ddc3b630be065c610c6d0f2f9dfba9472..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/workspace.xml b/app/Modules/Admin/Resources/vue-element-admin/api/.idea/workspace.xml deleted file mode 100644 index 4b8a53ee641cc2abdd751d3ebf4564f11c2c9ddf..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Resources/vue-element-admin/api/.idea/workspace.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1610455420023 - - - - - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/common.js b/app/Modules/Admin/Resources/vue-element-admin/api/common.js index 7f287edce0f7eff0f3a14c7a4a4486b256e459d9..ed70617adb0d5858ca44993440306f4796358549 100644 --- a/app/Modules/Admin/Resources/vue-element-admin/api/common.js +++ b/app/Modules/Admin/Resources/vue-element-admin/api/common.js @@ -1,4 +1,6 @@ import request from '@/utils/request' +import axios from "axios"; +import {getToken} from '@/utils/auth'; export function getUploadUrl() { return process.env.VUE_APP_BASE_API + '/upload_file' @@ -8,6 +10,28 @@ export function getBatchUploadUrl() { return process.env.VUE_APP_BASE_API + '/upload_files' } +export function uploads(formData, url, headers) { + return request({ + url: getBatchUploadUrl(), + method: 'post', + data:formData, + }); + + axios.post(url || getBatchUploadUrl(), + formData, + headers || { + headers: { + 'Content-Type': 'multipart/form-data', + 'Authorization': getToken(), + } + } + ).then( res => { + console.log(res) + }).catch( res => { + console.log(res) + }) +} + export function getMonthLists() { return request({ url: '/get_month_lists', diff --git a/app/Modules/Admin/Resources/vue-element-admin/api/menus.js b/app/Modules/Admin/Resources/vue-element-admin/api/menus.js new file mode 100644 index 0000000000000000000000000000000000000000..1446d826cb75377670bef2f6f016c4aaa77e5ed8 --- /dev/null +++ b/app/Modules/Admin/Resources/vue-element-admin/api/menus.js @@ -0,0 +1,55 @@ +import request from '@/utils/request' + +export function getMenusSelect() { + return request({ + url: '/menus/getSelectLists', + method: 'get' + }) +} +export function getList(params) { + return request({ + url: 'menus', + method: 'get', + params + }) +} + +export function getTplTypeAndViews() { + return request({ + url: 'menus/getTplTypeAndViews', + method: 'get' + }) +} + + +export function create(data) { + return request({ + url: '/menus/create', + method: 'post', + data + }) +} + +export function update(data) { + return request({ + url: `/menus/update`, + method: 'put', + data + }) +} + +export function setDel(data) { + return request({ + url: `/menus/delete`, + method: 'delete', + data + }) +} + +export function changeFiledStatus(data) { + return request({ + url: `/menus/changeFiledStatus`, + method: 'put', + data + }) +} diff --git a/app/Modules/Admin/Resources/vue-element-admin/components/Uploads/image/batchUploads.vue b/app/Modules/Admin/Resources/vue-element-admin/components/Uploads/image/batchUploads.vue new file mode 100644 index 0000000000000000000000000000000000000000..7d836645106e96398e5607a1bbdb62f62835f3e9 --- /dev/null +++ b/app/Modules/Admin/Resources/vue-element-admin/components/Uploads/image/batchUploads.vue @@ -0,0 +1,194 @@ + + + + + diff --git a/app/Modules/Admin/Resources/vue-element-admin/styles/common.scss b/app/Modules/Admin/Resources/vue-element-admin/styles/common.scss index 3230876cec142d5a876f1df7173e172529e5e25a..7b540a0902b82867a0f6b5c3d93a4331c3413383 100644 --- a/app/Modules/Admin/Resources/vue-element-admin/styles/common.scss +++ b/app/Modules/Admin/Resources/vue-element-admin/styles/common.scss @@ -11,6 +11,16 @@ .margin-buttom-10{ margin-bottom: 10px!important; } +.margin-top-20{ + margin-top: 20px; +} + +.upload-demo .el-upload--picture-card{ + line-height:0px; +} +.width-800-px{ + width: 800px; +} // 表单 下拉框 100%宽度占比 diff --git a/app/Modules/Admin/Resources/vue-element-admin/views/articles/components/ArticleDetail.vue b/app/Modules/Admin/Resources/vue-element-admin/views/articles/components/ArticleDetail.vue index 02b3e2dfbc38eb636712891e3cda0bf35326fe0f..03eace4cb53c63096d3e54821a6d9ad1947f2061 100644 --- a/app/Modules/Admin/Resources/vue-element-admin/views/articles/components/ArticleDetail.vue +++ b/app/Modules/Admin/Resources/vue-element-admin/views/articles/components/ArticleDetail.vue @@ -15,20 +15,20 @@ - + - + @@ -47,32 +47,27 @@ - - - - + - 文章封面 - - - + +
将文件拖到此处,或点击上传
+ + + 开始上传
@@ -132,27 +127,28 @@ + + diff --git a/app/Modules/Admin/Resources/vue-element-admin/views/menus/index.vue b/app/Modules/Admin/Resources/vue-element-admin/views/menus/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..0c51eaf3f8d6026b48ea0069a779d9c676e1c3da --- /dev/null +++ b/app/Modules/Admin/Resources/vue-element-admin/views/menus/index.vue @@ -0,0 +1,195 @@ + + + diff --git a/app/Modules/Admin/Routes/web.php b/app/Modules/Admin/Routes/web.php index 3f409a1db9ef47421a12c95f165637d57e0a4bd5..177aa74e731935bcf638bd28e6c7662028ac126d 100644 --- a/app/Modules/Admin/Routes/web.php +++ b/app/Modules/Admin/Routes/web.php @@ -47,6 +47,8 @@ Route::prefix('admin') Route::get('get_month_lists', 'IndexController@getMonthList'); // 文件上传 Route::post('upload_file', 'UploadController@file'); + // 多图批量上传 + Route::post('upload_files', 'UploadController@files'); // 权限中间件 Route::middleware([CheckRabc::class])->group(function () { @@ -161,6 +163,17 @@ Route::prefix('admin') Route::delete('/delete', 'Article\ArticleController@delete'); Route::put('/changeFiledStatus', 'Article\ArticleController@changeFiledStatus'); }); + + // Bbs菜单栏目管理 + Route::prefix('menus')->group(function() { + Route::get('/', 'Bbs\MenuController@index'); + Route::post('/create', 'Bbs\MenuController@create'); + Route::put('/update', 'Bbs\MenuController@update'); + Route::delete('/delete', 'Bbs\MenuController@delete'); + Route::get('/getSelectLists', 'Bbs\MenuController@getSelectLists')->withoutMiddleware([CheckRabc::class]); + Route::put('/changeFiledStatus', 'Bbs\MenuController@changeFiledStatus'); + Route::get('/getTplTypeAndViews', 'Bbs\MenuController@getTplTypeAndViews')->withoutMiddleware([CheckRabc::class]); + }); }); }); }); diff --git a/app/Modules/Admin/Services/.idea/Services.iml b/app/Modules/Admin/Services/.idea/Services.iml deleted file mode 100644 index d6ebd4805981b8400db3e3291c74a743fef9a824..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Services/.idea/Services.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Services/.idea/misc.xml b/app/Modules/Admin/Services/.idea/misc.xml deleted file mode 100644 index 7e5bdf89fec4690a0218e8d99983b379c8218059..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Services/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Services/.idea/modules.xml b/app/Modules/Admin/Services/.idea/modules.xml deleted file mode 100644 index 3c4934d5e608cece09dc38e1bf67e87d84f913f8..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Services/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Services/.idea/vcs.xml b/app/Modules/Admin/Services/.idea/vcs.xml deleted file mode 100644 index 4fce1d86b49521afe1cee4ed1c13b6396ebbc6f3..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Services/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Services/.idea/workspace.xml b/app/Modules/Admin/Services/.idea/workspace.xml deleted file mode 100644 index 006bf1907e970bc03db0695cb909f2ca9e5eb0d8..0000000000000000000000000000000000000000 --- a/app/Modules/Admin/Services/.idea/workspace.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1607869134694 - - - - - - - - - - - - \ No newline at end of file diff --git a/app/Modules/Admin/Services/AdminMenuService.php b/app/Modules/Admin/Services/AdminMenuService.php index 2ce6e6207afc6f5528c3871b1633e54a615b3366..249157181f1a49d6ba668df6a334b3641bcf6d4e 100644 --- a/app/Modules/Admin/Services/AdminMenuService.php +++ b/app/Modules/Admin/Services/AdminMenuService.php @@ -19,7 +19,7 @@ class AdminMenuService extends BaseService */ public function lists(array $params) : array { - $lists = $this->model->with($this->with)->orderBy('menu_sort', 'ASC')->get(); + $lists = $this->model->orderBy('menu_sort', 'ASC')->get(); return list_to_tree($lists->toArray()); } diff --git a/app/Modules/Admin/Services/ArticleService.php b/app/Modules/Admin/Services/ArticleService.php index 41a45af77b5c5399c0c00b817ef4ecb6e6785d91..df41adeeb5206585158942e813a1726d11d2a02a 100644 --- a/app/Modules/Admin/Services/ArticleService.php +++ b/app/Modules/Admin/Services/ArticleService.php @@ -13,7 +13,7 @@ class ArticleService extends BaseService public function __construct(Article $article) { $this->model = $article; - $this->with = ['category']; + $this->with = ['menu']; $this->detailWith = ['labels']; } @@ -59,6 +59,16 @@ class ArticleService extends BaseService try{ parent::create($params); // TODO: Change the autogenerated stub + // 新增文章内容 + $ip_agent = get_client_info(); + $this->detail->content()->create([ + 'article_id' => $this->detail->article_id, + 'article_content' => $params['article_content'] ?? '', + 'created_ip' => $ip_agent['ip'] ?? get_ip(), + 'browser_type' => $ip_agent['agent'] ?? $_SERVER['HTTP_USER_AGENT'], + ]); + + // 设置文章标签 $this->setArticleLabels($params); DB::commit(); @@ -75,6 +85,10 @@ class ArticleService extends BaseService try{ parent::update($params); // TODO: Change the autogenerated stub + // 更新文章内容 + $this->detail->content()->where('article_id', $this->detail->article_id)->update(['article_content' => $params['article_content'] ?? '']); + + // 设置文章标签 $this->setArticleLabels($params); DB::commit(); diff --git a/app/Modules/Admin/Services/MenuService.php b/app/Modules/Admin/Services/MenuService.php new file mode 100644 index 0000000000000000000000000000000000000000..62fc4f95811a20b1b2b1471b9d602162e0e2df3f --- /dev/null +++ b/app/Modules/Admin/Services/MenuService.php @@ -0,0 +1,31 @@ +model = $menu; + } + + /** + * 菜单列表 + * + * @param array $params + * @return array + */ + public function lists(array $params) : array + { + $lists = $this->model->orderBy('menu_sort', 'ASC')->get(); + + return list_to_tree($lists->toArray()); + } + + public function getSelectLists($request) + { + return $this->model->getSelectLists(); + } +} diff --git a/app/Modules/Bbs/Http/Controllers/BbsController.php b/app/Modules/Bbs/Http/Controllers/BbsController.php index 1527f5a2ab9eab29998da7cfd5f71d5617154b1d..be9c1820825dc68a1b8eb014cdcf4dd28c5e2c8f 100644 --- a/app/Modules/Bbs/Http/Controllers/BbsController.php +++ b/app/Modules/Bbs/Http/Controllers/BbsController.php @@ -2,78 +2,180 @@ namespace App\Modules\Bbs\Http\Controllers; +use App\Exceptions\InvalidRequestException; +use App\Models\Article\Article; +use App\Models\Article\ArticleLabel; +use App\Models\Bbs\Menu; +use App\Models\System\Banner; +use App\Models\System\Friendlink; use Illuminate\Contracts\Support\Renderable; -use Illuminate\Http\Request; use Illuminate\Routing\Controller; class BbsController extends Controller { - /** - * Display a listing of the resource. - * @return Renderable - */ - public function index() - { - return view('bbs::index'); - } + protected $article_instance; - /** - * Show the form for creating a new resource. - * @return Renderable - */ - public function create() + public function __construct() { - return view('bbs::create'); + $menus = Menu::getMenusByWeb(); + + $this->article_instance = Article::getInstance(); + // 随机文章 + $rand_articles = $this->article_instance->check()->where('article_images', '<>', '')->orderByRaw("RAND()")->limit(6)->get(); + // 最新文章 + $new_articles = $this->article_instance->check()->orderBy('created_time', 'DESC')->limit(5)->get(); + + view()->share([ + 'menus' => $menus, + 'rand_articles' => $rand_articles, + 'new_articles' => $new_articles, + ]); } /** - * Store a newly created resource in storage. - * @param Request $request + * Display a listing of the resource. + * * @return Renderable */ - public function store(Request $request) + public function index() { - // + // Banner + $banners = Banner::getBannersByWeb(); + + // 文章总量 + $articles_count = $this->article_instance->cacheStatistics(); + + // 文章分页 + $articles = $this->article_instance->check()->with([ + 'labels', + 'menu', + ])->where('is_public', 1)->orderBy('article_sort', 'ASC')->orderBy('set_top', 'DESC')->orderBy('is_recommend', 'DESC')->orderBy('created_time', 'DESC')->paginate(15); + + // 友情链接 + $friendlinks = Friendlink::getFriendlinksByWeb(); + + return view('bbs::index', compact('articles_count', 'banners', 'articles', 'friendlinks')); } /** * Show the specified resource. - * @param int $id + * + * @param int $id + * * @return Renderable */ - public function show($id) + public function label($label_id) { - return view('bbs::show'); + $lists = ArticleLabel::getInstance()->detail($label_id)->articles()->check()->with([ + 'labels', + 'menu', + ])->where('is_public', 1)->paginate(15); + return view('bbs::label-articles', compact('lists')); } /** - * Show the form for editing the specified resource. - * @param int $id - * @return Renderable + * + * @param int $article_id + * + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + * @throws \App\Exceptions\InvalidRequestException */ - public function edit($id) + public function detail(int $article_id) { - return view('bbs::edit'); - } + $article_instance = Article::check(); + $article = $article_instance->select('article_id', 'menu_id', 'article_title', 'article_keywords', 'article_description', 'read_num', 'created_time')->where('article_id', $article_id)->with([ + 'labels', + 'content', + 'menu', + ])->first(); + if ( !$article ) { + throw new InvalidRequestException('NOT FOUND ARTICLE!', 404); + } - /** - * Update the specified resource in storage. - * @param Request $request - * @param int $id - * @return Renderable - */ - public function update(Request $request, $id) - { - // + // 阅读量自增 + $article->increment('read_num'); + + $web_title = $article->article_title; + $web_keywords = $article->article_keywords; + $web_description = $article->article_description; + + // 当前URL + $current_url = url()->current(); + + // 随机获取三条相关文章 + $relation_articles = $article_instance->select('article_id', 'article_title', 'article_description', 'article_images', 'created_time')->whereIn('menu_id', Menu::getMenusChilds($article->menu_id))->orderByRaw("RAND()")->limit(3)->get(); + + // 获取当前位置 + $location_menus = Menu::getInstance()->getLocation((int)$article->menu_id); + + // 标签列表 + $labels = ArticleLabel::getLabelsByCache(); + + // 打赏 + $alipay_image_code = cnpscy_config('alipay_image_code'); + $wechat_image_code = cnpscy_config('wechat_image_code'); + $qq_image_code = cnpscy_config('qq_image_code'); + + return view('bbs::detail', compact('article', 'web_title', 'web_keywords', 'web_description', 'current_url', 'relation_articles', 'location_menus', 'labels', 'alipay_image_code', 'wechat_image_code', 'qq_image_code')); } /** - * Remove the specified resource from storage. - * @param int $id - * @return Renderable + * 前端的自定义菜单路由 + * + * @param $menu_url + * + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View */ - public function destroy($id) + public function menuUrl($menu_url, Article $article) { - // + $menu = Menu::getInstance()->getMenuByUrl($menu_url); + if ( !$menu ) { + throw new InvalidRequestException('NOT FOUND!', 404); + } + $lists = []; + if ( $menu->menu_tpltype == 1 ) { // 不直接发布内容,用于跳转页面 + return redirect('Location: ' . $menu->menu_url); + } elseif ( $menu->menu_tpltype == 2 ) { // 文章列表页 + $lists = $article::check() // 审核 + ->where('is_public', '<>', 0) //0:秘密;1.公开;2.密码访问 + ->whereIn('menu_id', Menu::getMenusChilds($menu->menu_id)) //栏目筛选 + // 排序 + ->orderBy('set_top', 'DESC')->orderBy('is_recommend', 'DESC')->orderBy('article_sort', 'ASC')->orderBy('article_id', 'DESC')->with([ + 'labels', + 'menu' => function($query) { + $query->select([ + 'menu_id', + 'menu_name', + 'menu_url', + ]); + }, + ])->select([ + 'article_id', + 'menu_id', + 'article_title', + 'article_description', + 'article_images', + 'article_link', + 'article_origin', + 'created_time', + 'is_recommend', + 'set_top', + 'read_num', + ]) + //每页的数量 + ->paginate(15); + } elseif ( $menu->menu_tpltype == 3 ) { // 单页面模式 + + } + + // Title 标题 + $web_title = $menu->menu_name; + + // 获取当前位置 + $location_menus = Menu::getInstance()->getLocation((int)$menu->menu_id, false); + + return view('bbs::' . $menu->menu_listtpl, compact('lists', 'menu', 'web_title'))->with('location_menus', $location_menus) //当前页面的位置 + ->with('web_keywords', empty($menu->menu_keywords) ? cnpscy_config('site_web_keywords') : $menu->menu_keywords)//Head的关键字 + ->with('web_description', empty($menu->menu_description) ? cnpscy_config('site_web_description') : $menu->menu_description); //Head的描述 } } diff --git a/app/Modules/Bbs/Http/Middleware/RecordWebLog.php b/app/Modules/Bbs/Http/Middleware/RecordWebLog.php new file mode 100644 index 0000000000000000000000000000000000000000..eadbf1519471a3c42c652ce1aaa688995d9cf519 --- /dev/null +++ b/app/Modules/Bbs/Http/Middleware/RecordWebLog.php @@ -0,0 +1,43 @@ + json_encode($request->all()), + 'created_ip' => $ip_agent['ip'] ?? get_ip(), + 'browser_type' => $ip_agent['agent'] ?? $_SERVER['HTTP_USER_AGENT'], + 'created_time' => time(), + 'log_action' => request()->route()->getActionName(), + 'log_method' => request()->getMethod(), + 'log_duration' => microtime(true) - LARAVEL_START, + 'request_url' => URL::previous() ?? get_request_url(), + 'this_url' => URL::full() ?? get_this_url(), + ] + ); + } + + return $next($request); + } +} diff --git a/app/Modules/Bbs/Resources/views/articles.blade.php b/app/Modules/Bbs/Resources/views/articles.blade.php new file mode 100644 index 0000000000000000000000000000000000000000..a55204b4dc516d4fdf59a612d4546578a38a5f9a --- /dev/null +++ b/app/Modules/Bbs/Resources/views/articles.blade.php @@ -0,0 +1,58 @@ +@extends('bbs::layouts.master') + +@section('content') +
+
+
+ +
+ 广告位置:还没想好放什么…… +
+ + +
+

+ + + +

+
+ + + @if(!empty($lists)) + @foreach($lists as $article) + @include('bbs::render.article') + @endforeach + + + @if($lists->lastPage() > 1) +
+ +
+ @endif + + @endif +
+
+ +
+@endsection diff --git a/app/Modules/Bbs/Resources/views/detail.blade.php b/app/Modules/Bbs/Resources/views/detail.blade.php new file mode 100644 index 0000000000000000000000000000000000000000..4ad5aca8870225bc630b5bb55651baecfc252533 --- /dev/null +++ b/app/Modules/Bbs/Resources/views/detail.blade.php @@ -0,0 +1,240 @@ +@extends('bbs::layouts.master') + +@section('title', $web_title) + +@section('content') +
+
+
+ +
+
+
+ +

{{ $article->article_title }}

+
    +
  • 内容
  • +
  • 相关
  • +
+
+ +
+ + @if($article->content && strip_tags($article->content->article_content) != $article->content->article_content) + {!! $article->content->article_content !!} + @else + + @endif + + +
+ + +
+
+ + +
+ @if(count($article->labels)) +

+ 本文标签: + @foreach($article->labels as $label) + {{ $label->label_name }} + @endforeach +

+ @endif +

+ + 版权声明:若无特殊注明,本文皆为《{{ cnpscy_config('site_web_author') }}》原创,转载请保留文章出处。 +

+

+ 本文链接:{{ $article->article_title }} - {{ $current_url }} +

+
+ + + @if(!empty($relation_articles)) + + @endif + + + +
+
+ +
+@endsection + +@section('script') + +@include('bbs::layouts.markdown') + + + +@endsection diff --git a/app/Modules/Bbs/Resources/views/index.blade.php b/app/Modules/Bbs/Resources/views/index.blade.php index 8994db66990d0cc7991794a682d3c30bbf30c528..4f9dfdcc4ef3981a565d0ac4102c12230fa3e451 100644 --- a/app/Modules/Bbs/Resources/views/index.blade.php +++ b/app/Modules/Bbs/Resources/views/index.blade.php @@ -1,2547 +1,259 @@ - - - - - - - - - - - - - - - - - - - - Finally-EMLOG_FLY主题VIP版本演示站点! - - - - - - - - - - - - - -
-
-
-
- - -
-
-
    -
  • - - -
  • -
  • -
  • -
-
-
-
-
- - - - -
-
-
- -

相册图库

-

相册图库介绍

- 点击进入 -
-
-
-
- -

音乐收藏

-

音乐点播页面

- 点击进入 -
-
-
-
- -

文章归档

-

所有文章都搁着

- 点击进入 -
-
-
-
- -

站长工具

-

网络收集的软件

- 点击进入 -
-
-
-
- -

留言互动

-

不要打广告哦

- 点击进入 -
-
-
-
- -

我的邻居

-

我的小伙们

- 点击进入 -
-
-
- - - -
-
- - - -
-
- - -
+
+ @endif + + + + + -
此文为网友投稿骗子QQ: 4068504本人被骗320r因为购买网站源码被骗死全家的玩意.千万不要和他交易!!!
-
- -
-
-
+ @include('bbs::layouts.excerpt-list') -
-
- -
- -
- -
-
-
-
-
- - - - - - -
-

升级了Emlog6.0.1

+ + + +
+ 广告位置:还没想好放什么…… +
+ + + + @if(!empty($articles)) + @foreach($articles as $article) + @include('bbs::render.article') + @endforeach + + @if($articles->lastPage() > 1) +
+ - -
- +
+ @endif + + @endif -
-
+
+ 广告位置:还没想好放什么…… +
-
升级EM     刚才准备更新模板,想着把两个版本都适配一下EM6特别版和兼容PHP7...
-
- -
-
-
+ + @include('bbs::layouts.cms') + -
- -
-
- -
- - - - - - - - -
- -
+
-
-