举例:获取文章列表,类似CSDN首页,加载
link->getArticleList
显示pagesize条articles
js控制滚动,符合加载条件时,ajax请求,到service,从当前page,加载pagesize条
service返回数据,js接受到的数据,显示在页面上
代码实例:
<?php
namespace App\Http\Controllers\Web;
use Illuminate\Http\Request;
use App\Models\Article;
use App\Models\User;
use App\Models\Comment;
use App\Models\UserArticle;
use App\Contracts\Editor\Renderer;
use Auth;
class ArticleController extends BaseController
{
public function __construct()
{
$this->middleware('auth', ['except' => ['showList', 'detail']]);
}
public function showList(Request $request)
{
$params = [
'page' => 1,
'page_size' => config('config.default_page_size', 20),
];
$articleDao = new Article();
$articles = $articleDao->getArticles($params);
$cdn = app('cdn');
$imageDimension = config('config.article_cover_image_size', [
'width' => 160,
'height' => 120,
]);
$articleIds = [];
foreach ($articles as $article) {
$articleIds[] = $article['article_id'];
if (count($article->medias)) {
$media = $article->medias[0];
$article['cover_media'] = $media['cdn_path'] ? $cdn->getCdnMogr2Resource($media['cdn_path'], $imageDimension) : '';
}
if (count($article->user)) {
$user = $article->user;
$article['user_avatar'] = $user['avatar'] ? $cdn->getCdnMogr2Resource($user['avatar'], ['width' => 20, 'height' => 20]) : '';
}
}
$user = Auth::user();
if ($user && $articleIds) {
$userArticleDao = new UserArticle();
$userArticles = $userArticleDao->getUserArticles($user->user_id, $articleIds);
$userArticleIds = $userArticles->pluck('article_id')->all();
foreach ($articles as $article) {
$article['is_favorite'] = in_array($article['article_id'], $userArticleIds);
}
}
$data = [
'articles' => $articles,
];
return response()->view('article.list', $data);
}
public function detail(Renderer $renderer, $articleId)
{
$article = Article::find($articleId);
if (!$article || $article->is_deleted) {
abort(404);
}
$user = Auth::user();
$articleDao = new Article();
$articleDao->updateArticleViewCount(($user ? $user['user_id'] : null), $articleId);
$article['content'] = $renderer->render($article['content']);
if ($user) {
$isFavorited = UserArticle::where([
'user_id' => $user->user_id,
'article_id' => $article['article_id'],
])->exists();
$article['is_favorite'] = $isFavorited;
}
$commentDao = new Comment;
$comments = $commentDao->getApprovedList([
'article_id' => $articleId,
]);
$data = [
'article' => $article,
'comments' => $comments
];
return view('article.detail', $data);
}
public function getEdit(Request $request, Renderer $renderer)
{
$user = Auth::user();
$articleId = $request->input('article_id');
if ($articleId) {
$article = Article::where([
'article_id' => $articleId,
'user_id' => $user->user_id,
'is_deleted' => 0,
])->first();
} else {
$article = new Article();
$article->title = '';
$article->user_id = $user['user_id'];
$article->is_active = 1;
$article->is_deleted = 0;
$article->review_count = 0;
$article->favorited_count = 0;
}
if (!isset($article)) {
abort(404);
}
$article['content'] = $renderer->render($article['content']);
$data = [
'user' => \Auth::user(),
'article' => $article,
];
return view('article.edit', $data);
}
}
requirejs(['../config'], function () {
require(['jquery', 'underscore', 'util', 'layzr', 'article_favorite'], function ($, _, util, Layzr) {
$(function () {
var pageSize = 20,
page = 1,
hasMore = true,
container = $('.main-content'),
listTemplate = _.template($('#article-list-template').html()),
isLoading = false,
$window = $(window),
layzr = new Layzr();
function renderArticles(articles) {
if (articles && articles.length <= 0) {
return false;
}
contentContainer = container.find('.article-row');
contentContainer.append(listTemplate({
articles: articles
}));
}
function loadMore(params) {
isLoading = true;
$.ajax({
url: '/service/article/list',
type: 'GET',
data: params,
}).done(function (response) {
if (response.status === 'SUCCESS') {
hasMore = response.body.hasMore;
renderArticles(response.body.articles);
layzr.updateSelector();
layzr.update();
}
}).always(function () {
isLoading = false;
});
}
$window.on('scroll', function () {
if (!hasMore || isLoading) {
return;
}
if ($window.height() + $window.scrollTop() + 300 >= $(document).height()) {
loadMore({
page: ++page
});
}
});
util.initGotoTop();
});
});
});
<?php
namespace App\Http\Controllers\Web\Service;
use App\Http\Controllers\Web\BaseController;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Article;
use App\Models\Media;
use App\Models\UserArticle;
use App\Models\ArticleMedia;
use Auth;
class ArticleController extends BaseController
{
public function __construct()
{
$this->middleware('auth', [
'except' => ['getList'],
]);
}
public function getList(Request $request)
{
$params = [
'page' => $request->input('page', 1),
'page_size' => $request->input('page_size', config('config.default_page_size', 20)),
];
$articleDao = new Article();
$articles = $articleDao->getArticles($params);
$cdn = app('cdn');
$imageDimension = config('config.article_cover_image_size', [
'width' => 160,
'height' => 120,
]);
$articleIds = $articles->pluck('article_id')->all();
$user = Auth::user();
if ($user && $articleIds) {
$userArticleDao = new UserArticle();
$userArticles = $userArticleDao->getUserArticles($user->user_id, $articleIds);
$userArticleIds = $userArticles->pluck('article_id')->all();
foreach ($articles as $article) {
$article['is_favorite'] = in_array($article['article_id'], $userArticleIds);
}
}
foreach ($articles as $article) {
$coverMedia = '';
if (count($article->medias)) {
$media = $article->medias[0];
$article['cover_media'] = $media['cdn_path'] ? $cdn->getResourceUrl($media['cdn_path'], $imageDimension) : '';
}
if (count($article->user)) {
$user = $article->user;
$article['user_avatar'] = $user['avatar'] ? $cdn->getCdnMogr2Resource($user['avatar'], ['width' => 20, 'height' => 20]) : '';
}
$article['article_url'] = route('article_detail', ['articleId' => $article['article_id']]);
$article['user_url'] = route('user_home', ['userId' => $article['user_id']]);
$article['user_name'] = $article['user_id'] ? $article->user->getDisplayName() : '系统';
}
$data = [
'hasMore' => count($articles) == $params['page_size'],
'articles' => $articles,
];
return response()->json(format_json_success($data));
}
public function postFavorite(Request $request)
{
$this->validate($request, [
'article_id' => 'required|integer',
]);
$user = Auth::user();
$userId = $user->user_id;
if ($articleId = $request->input('article_id')) {
$article = Article::actived()->find($articleId);
}
if (!isset($article)) {
return response()->json(format_json_failed('invalid_parameter'));
}
if ($article['user_id'] == $userId) {
return response()->json([
'status' => 'SELF_ARTICLE'
]);
}
$userArticle = UserArticle::firstOrNew([
'user_id' => $userId,
'article_id' => $articleId,
]);
$favoritedCount = $article['favorited_count'];
if (!isset($userArticle['created'])) {
$userArticle['created'] = now();
$userArticle->save();
$favoritedCount++;
$article->increment('favorited_count', 1);
}
$data = [
'favorited_count' => $favoritedCount,
];
return response()->json(format_json_success($data));
}
public function postUnfavorite(Request $request)
{
$this->validate($request, [
'article_id' => 'required|integer',
]);
$user = Auth::user();
$userId = $user->user_id;
if ($articleId = $request->input('article_id')) {
$article = Article::actived()->find($articleId);
}
if (!isset($article)) {
return response()->json(format_json_failed('invalid_parameter'));
}
$result = UserArticle::where([
'user_id' => $userId,
'article_id' => $articleId,
])->delete();
$favoritedCount = $article['favorited_count'];
if ($result) {
$favoritedCount--;
try {
$article->decrement('favorited_count', 1);
} catch (\Exception $e) {
// empty
}
}
$data = [
'favorited_count' => $favoritedCount < 0 ? 0 : $favoritedCount,
];
return response()->json(format_json_success($data));
}
public function postDelete(Request $request)
{
$this->validate($request, [
'article_id' => 'required|integer',
]);
$articleId = $request->input('article_id');
$article = Article::find($articleId);
if (!isset($article)) {
return response()->json(format_json_failed('invalid_parameter'));
}
$article['is_deleted'] = 1;
$article->save();
return response()->json(format_json_success());
}
public function postSaveMedia(Request $request)
{
$this->validate($request, [
'type' => 'required|in:' . join(',', [Media::TYPE_IMAGE, Media::TYPE_VIDEO]),
'path' => 'required',
]);
$type = $request->input('type');
$path = $request->input('path');
$now = now();
$media = Media::firstOrNew(['cdn_path' => $path]);
if (!$media->media_id) {
$media['type'] = $type;
$media['cdn_path'] = $path;
$media['user_id'] = 0;
$media['created'] = $now;
$media->save();
}
if ($media->media_id) {
$articleId = $request->input('article_id');
$article = Article::find($articleId);
if ($article) {
$articleMedia = ArticleMedia::firstOrNew([
'article_id' => $articleId,
'media_id' => $media->media_id,
]);
$articleMedia['created'] = data_get($articleMedia, 'created', $now);
$articleMedia->save();
}
$response = format_json_success([
'media_id' => $media->media_id,
]);
} else {
$response = format_json_failed('request_failed');
}
return response()->json($response);
}
public function postSave(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
'title' => 'required|string|max:120',
'article_id' => 'exists:article,article_id,is_deleted,0',
]);
$articleId = $request->input('article_id');
$userId = $request->input('user_id');
if ($articleId) {
$article = Article::find($articleId);
} else {
$article = new Article();
$article->user_id = $userId;
$article->is_active = 1;
$article->is_deleted = 0;
$article->review_count = 0;
$article->favorited_count = 0;
}
$article->title = $request->input('title');
$content = $request->input('content');
$article->content = $content;
$blocks = @json_decode($content, true);
$mediaIds = [];
$textContent = [];
if ($blocks) {
foreach ($blocks as $block) {
$blockType = array_get($block, 'type');
if (in_array($blockType, ['image', 'video'])
&& ($mediaId = array_get($block, 'mediaId'))
) {
$mediaIds[] = $mediaId;
}
if ($blockType == 'text') {
$blockContent = str_replace(' ', ' ', array_get($block, 'content'));
$blockContent = strip_tags(html_entity_decode($blockContent));
$blockContent = trim($blockContent);
if ($blockContent !== '') {
$textContent[] = $blockContent;
}
}
}
}
if (count($textContent)) {
$article->text_content = join("\n", $textContent);
// TODO $article->preview_content = '';
}
$datas = [
'media_ids' => $mediaIds,
];
$result = $article->updateWithCallback(function ($article) use ($datas, $request) {
$now = now();
$articleId = $article->article_id;
$mediaIds = array_get($datas, 'media_ids', []);
$oldMediaIds = [];
$removeMediaIds = [];
$articleMedias = ArticleMedia::where('article_id', $articleId)->get();
foreach ($articleMedias as $articleMedia) {
if (!in_array($articleMedia->media_id, $mediaIds)) {
$removeMediaIds[] = $articleMedia->media_id;
} else {
$oldMediaIds[] = $articleMedia->media_id;
}
}
if ($removeMediaIds) {
ArticleMedia::where('article_id', $articleId)
->whereIn('media_id', $removeMediaIds)
->delete();
}
$newMediaIds = array_diff($mediaIds, $oldMediaIds);
if ($newMediaIds) {
foreach ($newMediaIds as $mediaId) {
$articleMedia = new ArticleMedia([
'article_id' => $articleId,
'media_id' => $mediaId,
'is_cover' => 0,
'created' => $now,
]);
$articleMedia->save();
}
}
});
if ($result) {
$response = format_json_success();
} else {
$response = format_json_failed('request_failed');
}
return response()->json($response);
}
}
@extends('layout.app')
@section('lib_styles')
@parent
@stop
@section('stylesheets')
@parent
<link href="{{ asset('/static/css/article/list.css') }}" rel="stylesheet" />
@endsection
@section('scripts')
<script type="text/javascript" src="{{ asset('static/libs/require.js') }}"
data-main="{{ asset('static/js/article/list') }}"></script>
@stop
@section('content')
<div class="container">
<div class="row padding-row list-container article-view">
<div class="col-sm-12">
<div class="main-content clearfix">
<?php $currentUserId = Auth::user() ? Auth::user()->user_id : null ?>
@if (count($articles))
<div class="row article-row">
@foreach ($articles as $article)
<div class="col-xs-6 col-sm-6 article-item">
<div class="article-wrapper">
<div class="image-col">
<div class="article-image layzr-bg-image">
<a class="image-link" href="{{ url('article/' . $article['article_id']) }}">
<div class="img"
@if ($article['cover_media'])
data-layzr="{{ $article['cover_media'] }}"
data-layzr-bg
@else
id="default-image"
style="background-image: url({{ asset('/static/image/hero_image_1407x685.png') }})"
@endif
></div>
<div class="loading"></div>
</a>
</div>
</div>
<div class="article-info">
<div class="name-group tag-left">
<p class="article-name ellipsis" title="{{ $article['title'] }}">
<a href="{{ url('article/' . $article['article_id']) }}">{{ $article['title'] }}</a>
</p>
<p class="article-user ellipsis" title="{{ $article['user_id'] ? $article->user->getDisplayName() : '系统'}}">
<a href="{{ url('user/' . $article->user['user_id']) }}">
@if ($article['user_id'])
<img class="user-avator" src="{{ $article['user_avatar'] }}" />
@endif
</a>
@if ($article['user_id'])
<a href="{{ url('user/' . $article->user['user_id']) }}">
{{ $article->user->getDisplayName() }}</a>
@else
系统
@endif
<span>{{ $article['created'] }}</span>
</p>
<p>{{ $article['text_content'] }}</p>
</div>
<p class="article-stats favorite-container" data-article-id="{{ $article['article_id'] }}">
<span class="favorite-icon glyphicon {{ $article['is_favorite'] ? 'article-heart js-remove-favorite' : 'article-heart-empty js-add-favorite' }} {{ $article['user_id'] == $currentUserId ? 'default-cursor' : '' }}"
title="{{ $article['is_favorite'] ? '取消收藏' : '收藏' }}"></span>
<span class="ellipsis favorite-num" title="{{ $article['favorited_count'] }}">{{ $article['favorited_count'] }}</span>
</p>
</div>
</div>
</div>
@endforeach
</div>
@else
<p class="text-center">还没有发布任何物品,赶紧去发布吧!</p>
@endif
</div>
</div>
</div>
</div>
<script id="article-list-template" type="text/template">
<% _.each(articles, function (article) { %>
<div class="col-xs-6 col-sm-6 article-item">
<div class="article-wrapper">
<div class="image-col">
<div class="article-image layzr-bg-image">
<a class="image-link" href="<%- article['article_url'] %>">
<div class="img"
<% if (article['cover_media']) { %>
data-layzr="<%- article['cover_media'] %>"
data-layzr-bg
<% } else { %>
id="default-image"
style="background-image: url({{ asset('/static/image/hero_image_1407x685.png') }})"
<% } %>
></div>
<div class="loading"></div>
</a>
</div>
</div>
<div class="article-info">
<div class="name-group tag-left">
<p class="article-name ellipsis" title="<%- article.title %>">
<a href="<%- article['article_url'] %>"><%- article.title %></a>
</p>
<p class="article-user ellipsis" title="<%- article.user_name %>">
<% if (article.user_id != 0) { %>
<a href="<%- article['user_url'] %>">
<img class="user-avator" src="<%- article['user_avatar'] %>" />
</a>
<% } %>
<% if (article.user_id != 0) { %>
<a href="<%- article['user_url'] %>"><%- article.user_name %></a>
<% } else { %>
系统
<% } %>
<span><%- article.created %></span>
</p>
<p><%- article['text_content'] %></p>
</div>
<p class="article-stats favorite-container" data-article-id="<%- article['article_id'] %>">
<span class="favorite-icon glyphicon <%= article['is_favorite'] ? 'article-heart js-remove-favorite' : 'article-heart-empty js-add-favorite' %> <%= (article.user_id == '{{ $currentUserId }}') ? 'default-cursor' : '' %>"></span>
<span class="ellipsis favorite-num" title="<%- article['favorited_count'] %>"><%- article['favorited_count'] %></span>
</p>
</div>
</div>
</div>
<% }); %>
</script>
@endsection
link->getArticleList
显示pagesize条articles
js控制滚动,符合加载条件时,ajax请求,到service,从当前page,加载pagesize条
service返回数据,js接受到的数据,显示在页面上
代码实例:
<?php
namespace App\Http\Controllers\Web;
use Illuminate\Http\Request;
use App\Models\Article;
use App\Models\User;
use App\Models\Comment;
use App\Models\UserArticle;
use App\Contracts\Editor\Renderer;
use Auth;
class ArticleController extends BaseController
{
public function __construct()
{
$this->middleware('auth', ['except' => ['showList', 'detail']]);
}
public function showList(Request $request)
{
$params = [
'page' => 1,
'page_size' => config('config.default_page_size', 20),
];
$articleDao = new Article();
$articles = $articleDao->getArticles($params);
$cdn = app('cdn');
$imageDimension = config('config.article_cover_image_size', [
'width' => 160,
'height' => 120,
]);
$articleIds = [];
foreach ($articles as $article) {
$articleIds[] = $article['article_id'];
if (count($article->medias)) {
$media = $article->medias[0];
$article['cover_media'] = $media['cdn_path'] ? $cdn->getCdnMogr2Resource($media['cdn_path'], $imageDimension) : '';
}
if (count($article->user)) {
$user = $article->user;
$article['user_avatar'] = $user['avatar'] ? $cdn->getCdnMogr2Resource($user['avatar'], ['width' => 20, 'height' => 20]) : '';
}
}
$user = Auth::user();
if ($user && $articleIds) {
$userArticleDao = new UserArticle();
$userArticles = $userArticleDao->getUserArticles($user->user_id, $articleIds);
$userArticleIds = $userArticles->pluck('article_id')->all();
foreach ($articles as $article) {
$article['is_favorite'] = in_array($article['article_id'], $userArticleIds);
}
}
$data = [
'articles' => $articles,
];
return response()->view('article.list', $data);
}
public function detail(Renderer $renderer, $articleId)
{
$article = Article::find($articleId);
if (!$article || $article->is_deleted) {
abort(404);
}
$user = Auth::user();
$articleDao = new Article();
$articleDao->updateArticleViewCount(($user ? $user['user_id'] : null), $articleId);
$article['content'] = $renderer->render($article['content']);
if ($user) {
$isFavorited = UserArticle::where([
'user_id' => $user->user_id,
'article_id' => $article['article_id'],
])->exists();
$article['is_favorite'] = $isFavorited;
}
$commentDao = new Comment;
$comments = $commentDao->getApprovedList([
'article_id' => $articleId,
]);
$data = [
'article' => $article,
'comments' => $comments
];
return view('article.detail', $data);
}
public function getEdit(Request $request, Renderer $renderer)
{
$user = Auth::user();
$articleId = $request->input('article_id');
if ($articleId) {
$article = Article::where([
'article_id' => $articleId,
'user_id' => $user->user_id,
'is_deleted' => 0,
])->first();
} else {
$article = new Article();
$article->title = '';
$article->user_id = $user['user_id'];
$article->is_active = 1;
$article->is_deleted = 0;
$article->review_count = 0;
$article->favorited_count = 0;
}
if (!isset($article)) {
abort(404);
}
$article['content'] = $renderer->render($article['content']);
$data = [
'user' => \Auth::user(),
'article' => $article,
];
return view('article.edit', $data);
}
}
requirejs(['../config'], function () {
require(['jquery', 'underscore', 'util', 'layzr', 'article_favorite'], function ($, _, util, Layzr) {
$(function () {
var pageSize = 20,
page = 1,
hasMore = true,
container = $('.main-content'),
listTemplate = _.template($('#article-list-template').html()),
isLoading = false,
$window = $(window),
layzr = new Layzr();
function renderArticles(articles) {
if (articles && articles.length <= 0) {
return false;
}
contentContainer = container.find('.article-row');
contentContainer.append(listTemplate({
articles: articles
}));
}
function loadMore(params) {
isLoading = true;
$.ajax({
url: '/service/article/list',
type: 'GET',
data: params,
}).done(function (response) {
if (response.status === 'SUCCESS') {
hasMore = response.body.hasMore;
renderArticles(response.body.articles);
layzr.updateSelector();
layzr.update();
}
}).always(function () {
isLoading = false;
});
}
$window.on('scroll', function () {
if (!hasMore || isLoading) {
return;
}
if ($window.height() + $window.scrollTop() + 300 >= $(document).height()) {
loadMore({
page: ++page
});
}
});
util.initGotoTop();
});
});
});
<?php
namespace App\Http\Controllers\Web\Service;
use App\Http\Controllers\Web\BaseController;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Article;
use App\Models\Media;
use App\Models\UserArticle;
use App\Models\ArticleMedia;
use Auth;
class ArticleController extends BaseController
{
public function __construct()
{
$this->middleware('auth', [
'except' => ['getList'],
]);
}
public function getList(Request $request)
{
$params = [
'page' => $request->input('page', 1),
'page_size' => $request->input('page_size', config('config.default_page_size', 20)),
];
$articleDao = new Article();
$articles = $articleDao->getArticles($params);
$cdn = app('cdn');
$imageDimension = config('config.article_cover_image_size', [
'width' => 160,
'height' => 120,
]);
$articleIds = $articles->pluck('article_id')->all();
$user = Auth::user();
if ($user && $articleIds) {
$userArticleDao = new UserArticle();
$userArticles = $userArticleDao->getUserArticles($user->user_id, $articleIds);
$userArticleIds = $userArticles->pluck('article_id')->all();
foreach ($articles as $article) {
$article['is_favorite'] = in_array($article['article_id'], $userArticleIds);
}
}
foreach ($articles as $article) {
$coverMedia = '';
if (count($article->medias)) {
$media = $article->medias[0];
$article['cover_media'] = $media['cdn_path'] ? $cdn->getResourceUrl($media['cdn_path'], $imageDimension) : '';
}
if (count($article->user)) {
$user = $article->user;
$article['user_avatar'] = $user['avatar'] ? $cdn->getCdnMogr2Resource($user['avatar'], ['width' => 20, 'height' => 20]) : '';
}
$article['article_url'] = route('article_detail', ['articleId' => $article['article_id']]);
$article['user_url'] = route('user_home', ['userId' => $article['user_id']]);
$article['user_name'] = $article['user_id'] ? $article->user->getDisplayName() : '系统';
}
$data = [
'hasMore' => count($articles) == $params['page_size'],
'articles' => $articles,
];
return response()->json(format_json_success($data));
}
public function postFavorite(Request $request)
{
$this->validate($request, [
'article_id' => 'required|integer',
]);
$user = Auth::user();
$userId = $user->user_id;
if ($articleId = $request->input('article_id')) {
$article = Article::actived()->find($articleId);
}
if (!isset($article)) {
return response()->json(format_json_failed('invalid_parameter'));
}
if ($article['user_id'] == $userId) {
return response()->json([
'status' => 'SELF_ARTICLE'
]);
}
$userArticle = UserArticle::firstOrNew([
'user_id' => $userId,
'article_id' => $articleId,
]);
$favoritedCount = $article['favorited_count'];
if (!isset($userArticle['created'])) {
$userArticle['created'] = now();
$userArticle->save();
$favoritedCount++;
$article->increment('favorited_count', 1);
}
$data = [
'favorited_count' => $favoritedCount,
];
return response()->json(format_json_success($data));
}
public function postUnfavorite(Request $request)
{
$this->validate($request, [
'article_id' => 'required|integer',
]);
$user = Auth::user();
$userId = $user->user_id;
if ($articleId = $request->input('article_id')) {
$article = Article::actived()->find($articleId);
}
if (!isset($article)) {
return response()->json(format_json_failed('invalid_parameter'));
}
$result = UserArticle::where([
'user_id' => $userId,
'article_id' => $articleId,
])->delete();
$favoritedCount = $article['favorited_count'];
if ($result) {
$favoritedCount--;
try {
$article->decrement('favorited_count', 1);
} catch (\Exception $e) {
// empty
}
}
$data = [
'favorited_count' => $favoritedCount < 0 ? 0 : $favoritedCount,
];
return response()->json(format_json_success($data));
}
public function postDelete(Request $request)
{
$this->validate($request, [
'article_id' => 'required|integer',
]);
$articleId = $request->input('article_id');
$article = Article::find($articleId);
if (!isset($article)) {
return response()->json(format_json_failed('invalid_parameter'));
}
$article['is_deleted'] = 1;
$article->save();
return response()->json(format_json_success());
}
public function postSaveMedia(Request $request)
{
$this->validate($request, [
'type' => 'required|in:' . join(',', [Media::TYPE_IMAGE, Media::TYPE_VIDEO]),
'path' => 'required',
]);
$type = $request->input('type');
$path = $request->input('path');
$now = now();
$media = Media::firstOrNew(['cdn_path' => $path]);
if (!$media->media_id) {
$media['type'] = $type;
$media['cdn_path'] = $path;
$media['user_id'] = 0;
$media['created'] = $now;
$media->save();
}
if ($media->media_id) {
$articleId = $request->input('article_id');
$article = Article::find($articleId);
if ($article) {
$articleMedia = ArticleMedia::firstOrNew([
'article_id' => $articleId,
'media_id' => $media->media_id,
]);
$articleMedia['created'] = data_get($articleMedia, 'created', $now);
$articleMedia->save();
}
$response = format_json_success([
'media_id' => $media->media_id,
]);
} else {
$response = format_json_failed('request_failed');
}
return response()->json($response);
}
public function postSave(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
'title' => 'required|string|max:120',
'article_id' => 'exists:article,article_id,is_deleted,0',
]);
$articleId = $request->input('article_id');
$userId = $request->input('user_id');
if ($articleId) {
$article = Article::find($articleId);
} else {
$article = new Article();
$article->user_id = $userId;
$article->is_active = 1;
$article->is_deleted = 0;
$article->review_count = 0;
$article->favorited_count = 0;
}
$article->title = $request->input('title');
$content = $request->input('content');
$article->content = $content;
$blocks = @json_decode($content, true);
$mediaIds = [];
$textContent = [];
if ($blocks) {
foreach ($blocks as $block) {
$blockType = array_get($block, 'type');
if (in_array($blockType, ['image', 'video'])
&& ($mediaId = array_get($block, 'mediaId'))
) {
$mediaIds[] = $mediaId;
}
if ($blockType == 'text') {
$blockContent = str_replace(' ', ' ', array_get($block, 'content'));
$blockContent = strip_tags(html_entity_decode($blockContent));
$blockContent = trim($blockContent);
if ($blockContent !== '') {
$textContent[] = $blockContent;
}
}
}
}
if (count($textContent)) {
$article->text_content = join("\n", $textContent);
// TODO $article->preview_content = '';
}
$datas = [
'media_ids' => $mediaIds,
];
$result = $article->updateWithCallback(function ($article) use ($datas, $request) {
$now = now();
$articleId = $article->article_id;
$mediaIds = array_get($datas, 'media_ids', []);
$oldMediaIds = [];
$removeMediaIds = [];
$articleMedias = ArticleMedia::where('article_id', $articleId)->get();
foreach ($articleMedias as $articleMedia) {
if (!in_array($articleMedia->media_id, $mediaIds)) {
$removeMediaIds[] = $articleMedia->media_id;
} else {
$oldMediaIds[] = $articleMedia->media_id;
}
}
if ($removeMediaIds) {
ArticleMedia::where('article_id', $articleId)
->whereIn('media_id', $removeMediaIds)
->delete();
}
$newMediaIds = array_diff($mediaIds, $oldMediaIds);
if ($newMediaIds) {
foreach ($newMediaIds as $mediaId) {
$articleMedia = new ArticleMedia([
'article_id' => $articleId,
'media_id' => $mediaId,
'is_cover' => 0,
'created' => $now,
]);
$articleMedia->save();
}
}
});
if ($result) {
$response = format_json_success();
} else {
$response = format_json_failed('request_failed');
}
return response()->json($response);
}
}
@extends('layout.app')
@section('lib_styles')
@parent
@stop
@section('stylesheets')
@parent
<link href="{{ asset('/static/css/article/list.css') }}" rel="stylesheet" />
@endsection
@section('scripts')
<script type="text/javascript" src="{{ asset('static/libs/require.js') }}"
data-main="{{ asset('static/js/article/list') }}"></script>
@stop
@section('content')
<div class="container">
<div class="row padding-row list-container article-view">
<div class="col-sm-12">
<div class="main-content clearfix">
<?php $currentUserId = Auth::user() ? Auth::user()->user_id : null ?>
@if (count($articles))
<div class="row article-row">
@foreach ($articles as $article)
<div class="col-xs-6 col-sm-6 article-item">
<div class="article-wrapper">
<div class="image-col">
<div class="article-image layzr-bg-image">
<a class="image-link" href="{{ url('article/' . $article['article_id']) }}">
<div class="img"
@if ($article['cover_media'])
data-layzr="{{ $article['cover_media'] }}"
data-layzr-bg
@else
id="default-image"
style="background-image: url({{ asset('/static/image/hero_image_1407x685.png') }})"
@endif
></div>
<div class="loading"></div>
</a>
</div>
</div>
<div class="article-info">
<div class="name-group tag-left">
<p class="article-name ellipsis" title="{{ $article['title'] }}">
<a href="{{ url('article/' . $article['article_id']) }}">{{ $article['title'] }}</a>
</p>
<p class="article-user ellipsis" title="{{ $article['user_id'] ? $article->user->getDisplayName() : '系统'}}">
<a href="{{ url('user/' . $article->user['user_id']) }}">
@if ($article['user_id'])
<img class="user-avator" src="{{ $article['user_avatar'] }}" />
@endif
</a>
@if ($article['user_id'])
<a href="{{ url('user/' . $article->user['user_id']) }}">
{{ $article->user->getDisplayName() }}</a>
@else
系统
@endif
<span>{{ $article['created'] }}</span>
</p>
<p>{{ $article['text_content'] }}</p>
</div>
<p class="article-stats favorite-container" data-article-id="{{ $article['article_id'] }}">
<span class="favorite-icon glyphicon {{ $article['is_favorite'] ? 'article-heart js-remove-favorite' : 'article-heart-empty js-add-favorite' }} {{ $article['user_id'] == $currentUserId ? 'default-cursor' : '' }}"
title="{{ $article['is_favorite'] ? '取消收藏' : '收藏' }}"></span>
<span class="ellipsis favorite-num" title="{{ $article['favorited_count'] }}">{{ $article['favorited_count'] }}</span>
</p>
</div>
</div>
</div>
@endforeach
</div>
@else
<p class="text-center">还没有发布任何物品,赶紧去发布吧!</p>
@endif
</div>
</div>
</div>
</div>
<script id="article-list-template" type="text/template">
<% _.each(articles, function (article) { %>
<div class="col-xs-6 col-sm-6 article-item">
<div class="article-wrapper">
<div class="image-col">
<div class="article-image layzr-bg-image">
<a class="image-link" href="<%- article['article_url'] %>">
<div class="img"
<% if (article['cover_media']) { %>
data-layzr="<%- article['cover_media'] %>"
data-layzr-bg
<% } else { %>
id="default-image"
style="background-image: url({{ asset('/static/image/hero_image_1407x685.png') }})"
<% } %>
></div>
<div class="loading"></div>
</a>
</div>
</div>
<div class="article-info">
<div class="name-group tag-left">
<p class="article-name ellipsis" title="<%- article.title %>">
<a href="<%- article['article_url'] %>"><%- article.title %></a>
</p>
<p class="article-user ellipsis" title="<%- article.user_name %>">
<% if (article.user_id != 0) { %>
<a href="<%- article['user_url'] %>">
<img class="user-avator" src="<%- article['user_avatar'] %>" />
</a>
<% } %>
<% if (article.user_id != 0) { %>
<a href="<%- article['user_url'] %>"><%- article.user_name %></a>
<% } else { %>
系统
<% } %>
<span><%- article.created %></span>
</p>
<p><%- article['text_content'] %></p>
</div>
<p class="article-stats favorite-container" data-article-id="<%- article['article_id'] %>">
<span class="favorite-icon glyphicon <%= article['is_favorite'] ? 'article-heart js-remove-favorite' : 'article-heart-empty js-add-favorite' %> <%= (article.user_id == '{{ $currentUserId }}') ? 'default-cursor' : '' %>"></span>
<span class="ellipsis favorite-num" title="<%- article['favorited_count'] %>"><%- article['favorited_count'] %></span>
</p>
</div>
</div>
</div>
<% }); %>
</script>
@endsection