<?php
namespace App\Services;
use App\Enums\AdminActionTypeEnum;
use App\Enums\ArticleTypeEnum;
use App\Enums\IdentityVisibilityEnum;
use App\Enums\UserIdentityEnum;
use App\Exceptions\ApiException;
use App\Format\ArticleFormat;
use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Storage;
class ArticleService
{
const ONLY_ONE = [
ArticleTypeEnum::ArticleTypeCompanyScore,
ArticleTypeEnum::ArticleTypeScore,
ArticleTypeEnum::ArticleTypePromise,
];
protected $zhanXinPublicArticleService;
protected $adminAuthService;
public function __construct(ZhanXinPublicArticleService $zhanXinPublicArticleService, AdminAuthService $adminAuthService)
{
$this->zhanXinPublicArticleService = $zhanXinPublicArticleService;
$this->adminAuthService = $adminAuthService;
}
public function getArticleListByType(int $type, $page = 1, $pageSize = 10, string $orderColumn = '', string $orderType = '', array $search = [])
{
if ($type == ArticleTypeEnum::ArticleTypeZhanXin) {
return $this->zhanXinPublicArticleService->getZhanxinArticlesList($page, $pageSize);
}
$builder = Article::query()->select('id', 'title', 'created_at', 'cover_url', 'push_time', 'identity_visibility', 'source')
->where('type', $type);
if ($type == ArticleTypeEnum::ArticleTypeDangZheng) {
$builder = $this->typeDangZheng($builder);
}
if (isset($search['start_date'], $search['end_date'])) {
$builder->where('push_time', '>=', strtotime($search['start_date']));
if (strlen($search['end_date']) > 10) {
$builder->where('push_time', '<=', strtotime($search['end_date']));
} else {
$builder->where('push_time', '<=', strtotime($search['end_date']) + (24 * 3600));
}
}
if (isset($search['start_date']) && ! isset($search['end_date'])) {
$builder->where('push_time', '>=', strtotime($search['start_date']));
}
if (! isset($search['start_date']) && isset($search['end_date'])) {
if (strlen($search['end_date']) > 10) {
$builder->where('push_time', '<=', strtotime($search['end_date']));
} else {
$builder->where('push_time', '<=', strtotime($search['end_date']) + (24 * 3600));
}
}
if (isset($search['title']) && strlen($search['title']) > 0) {
$builder->where('title', 'like', '%' . $search['title'] . '%');
}
if (strlen($orderColumn) > 0 && strlen($orderType) > 0) {
$builder->orderBy($orderColumn, $orderType);
}
$count = $builder->count();
$lists = $builder
->orderBy('created_at', 'desc')
->skip(($page - 1) * $pageSize)
->take($pageSize)
->get();
return [
'list' => $lists,
'count' => $count,
'page' => $page,
'page_size' => $pageSize,
];
}
public function getArticleDeatil($id)
{
$article = Article::query()->find($id);
if (empty($article)) {
return [];
}
$type = $article->type;
if (! in_array($type, config('public_article_type'))) {
$userId = request('user_id');
$token = request('token');
if (! $userId || ! $token) {
throw new ApiException('用户未登陆', config('error_code.no_login'));
}
$userService = new UserService();
if (! $userService->checkLogin($userId, $token)) {
throw new ApiException('用户未登陆', config('error_code.no_login'));
}
}
return $article->toArray();
}
public function searchArtices(string $title, int $page, int $pageSize)
{
$title = urldecode($title);
$builder = Article::query()->where('title', 'like', '%' . $title . '%');
$count = $builder->count();
$list = $builder
->select('title', 'push_time', 'type', 'cover_url', 'id', 'content')
->orderByDesc('push_time')->skip(($page - 1) * $pageSize)->take($pageSize)->get();
return [
'page' => $page,
'page_size' => $pageSize,
'count' => $count,
'list' => $list,
];
}
public function findVillagePromise()
{
return Article::query()->where('type', ArticleTypeEnum::ArticleTypePromise)->first();
}
public function findScore()
{
return Article::query()->where('type', ArticleTypeEnum::ArticleTypeScore)->first();
}
public function findCompanyScore()
{
return Article::query()->where('type', ArticleTypeEnum::ArticleTypeCompanyScore)->first();
}
public function create(ArticleFormat $articleFormat)
{
if (in_array($articleFormat->getType(), self::ONLY_ONE)) {
if (Article::query()->where('type', $articleFormat->getType())->exists()) {
throw new ApiException(sprintf('%s 只能有一篇, 不能重复创建', ArticleTypeEnum::desc($articleFormat->getType())), 1);
}
}
adminLog(new Article(), AdminActionTypeEnum::CREATE, '创建文章-' . ArticleTypeEnum::desc($articleFormat->getType()));
Article::query()->create($articleFormat->toArrayNotNull());
return true;
}
public function update(ArticleFormat $articleFormat)
{
$id = $articleFormat->getId();
$article = Article::query()->find($id);
$article->update($articleFormat->toArray());
return true;
}
public function delete(int $id)
{
adminLog(new Article(), AdminActionTypeEnum::DELETE, '删除文章');
Article::query()->find($id)->delete();
return true;
}
public function getArticleType(int $id)
{
$article = Article::query()->select('type')->where('id', $id)->first();
if (empty($article)) {
throw new ApiException('文章不存在', 1);
}
return $article->type;
}
public function checkArticleTypeAuth(int $userId, string $action, int $type): bool
{
$userAuthActions = $this->adminAuthService->getUserRoleActions($userId)->toArray();
$userAuthActionsMap = array_column($userAuthActions, null, 'action_desc');
$auths = config('article_auth');
foreach ($auths as $auth) {
if ($auth['type'] == $type && $auth['action'] == $action) {
if (isset($userAuthActionsMap[$auth['action_desc']])) {
return true;
}
return false;
}
}
return false;
}
public function download(int $id)
{
$article = Article::query()->find($id);
if (empty($article)) {
throw new ApiException('文章不存在', 1);
}
$name = date('Y-m-d-H:i:s', time()) . $article->title;
$fileName = 'temp/download/' . $name . '.doc';
$content = '<html
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<meta charset="UTF-8" />' . $article->content . '</html>';
Storage::put($fileName, $content);
return $fileName;
}
private function typeDangZheng(Builder $builder)
{
$userId = request()->input('user_id', null);
if (empty($userId)) {
$builder->where('identity_visibility', IdentityVisibilityEnum::ALL);
return $builder;
}
$user = User::query()->select('identity')->find($userId);
if (empty($user)) {
$builder->where('identity_visibility', IdentityVisibilityEnum::ALL);
return $builder;
}
if ($user->identity == UserIdentityEnum::FLOW_USER) {
$builder->whereIn('identity_visibility', [IdentityVisibilityEnum::FLOW_USER, IdentityVisibilityEnum::ALL]);
return $builder;
}
$builder->whereIn('identity_visibility', [IdentityVisibilityEnum::ALL, IdentityVisibilityEnum::NOT_FLOW]);
return $builder;
}
private function checkArticleOperate(int $userId, int $type, string $action)
{
$userAuthActions = $this->adminAuthService->getUserRoleActions($userId)->toArray();
$userAuthActionsMap = array_column($userAuthActions, null, 'action_desc');
$auths = config('article_auth');
foreach ($auths as $auth) {
if ($auth['type'] == $type && $auth['action'] == $action) {
if (isset($userAuthActionsMap[$auth['action_desc']])) {
return true;
}
throw new ApiException('无权限', 1);
}
}
throw new ApiException('系统错误', 1);
}
}