MeterController.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Exports\BasicExport;
  4. use App\Http\Logics\Admin\MeterLogic;
  5. use App\Http\Models\Article;
  6. use App\Http\Models\Asset;
  7. use App\Http\Models\Feedback;
  8. use App\Http\Models\LinkTaskDetail;
  9. use App\Http\Models\Product;
  10. use App\Http\Models\Role;
  11. use App\Http\Models\ServiceFeedback;
  12. use App\Http\Models\Site;
  13. use App\Http\Models\SocialPublish;
  14. use App\Http\Models\UrlCheck;
  15. use App\Http\Requests\Meter\ServiceFeedbackRequest;
  16. use Illuminate\Database\Eloquent\Builder;
  17. use Illuminate\Http\Request;
  18. use App\Http\Controllers\Controller;
  19. use Illuminate\Support\Facades\Auth;
  20. use Illuminate\Support\Facades\Cache;
  21. use Illuminate\Support\Facades\DB;
  22. use Illuminate\Support\Facades\Log;
  23. use App\Http\Traits\HasSites;
  24. /**
  25. * 控制台
  26. * Class MeterController
  27. * @package App\Http\Controllers\Admin
  28. */
  29. class MeterController extends Controller
  30. {
  31. use HasSites;
  32. protected $logic;
  33. public function __construct(MeterLogic $logic)
  34. {
  35. $this->logic = $logic;
  36. }
  37. //总控制台
  38. public function index()
  39. {
  40. $userSites = $this->userSites();
  41. $validSiteIds = $userSites->pluck('id')->toArray();
  42. $validOldSiteIds = array_filter(array_column($userSites->toArray(), 'id'));
  43. $data = [];
  44. $rankDatabase = DB::connection('rank');
  45. $cacheKey = sprintf('index_%s_%s', date('Ym'), auth()->id());
  46. $cacheContent = Cache::get($cacheKey);
  47. if ($cacheContent) {
  48. $data = $cacheContent;
  49. goto render;
  50. }
  51. //关键词排名急剧下降
  52. $data['keyDropSites'] = $this->logic->indexDropKeywordSites($rankDatabase, $validSiteIds);
  53. //关键词达标项目
  54. $data['reachSites'] = $this->logic->indexReachSites($validSiteIds);
  55. //建站完成的
  56. $data['buildDoneSites'] = $this->logic->indexBuildDoneSites($validSiteIds);
  57. //证书过期项目
  58. $data['certExpiredSites'] = $this->logic->indexCertExpiredSites($validSiteIds);
  59. //域名过期项目
  60. $data['domainExpiredSites'] = $this->logic->indexDomainExpiredSites($validSiteIds);
  61. //月均流量 100 300 500 1000
  62. $data['masterMeterTraffics'] = $this->logic->indexMasterMeterTraffics($rankDatabase, $validSiteIds);
  63. //关键词总量
  64. $data['keywordTotal'] = $this->logic->indexKeywordTotal($rankDatabase, $validOldSiteIds);
  65. //项目类型数据
  66. $data['siteStatus'] = $this->logic->indexSiteStatus($validSiteIds);
  67. //公司类型统计
  68. $data['nature'] = $this->logic->indexNature($validSiteIds);
  69. //根据公司行业
  70. $data['business'] = $this->logic->indexBusiness($validSiteIds);
  71. //渠道销售占比
  72. $data['sales'] = $this->logic->indexSales($validSiteIds);
  73. //最新5个项目列表
  74. $data['last5Sites'] = $this->logic->indexLast5Sites($rankDatabase, $validSiteIds);
  75. //外链库折线图
  76. $data['linksLine'] = $this->logic->indexLinksLine();
  77. Cache::put($cacheKey, $data, new \DateTime(date('Y-m-t 23:59:59')));
  78. render:
  79. //流程过期提醒
  80. $data['expireSiteProcessList'] = $this->logic->indexExpireSiteProcessList($validSiteIds);
  81. $data['indexCustomerLog'] = $this->logic->indexCustomerLog($validSiteIds);
  82. //网址异常的
  83. $data['urlFailed'] = $urlFailed = UrlCheck::query()->whereIn('site_id', $validSiteIds)->get();
  84. return view('admin/meter/index', $data);
  85. }
  86. protected function lastSixMonths()
  87. {
  88. $sixMonth = [];
  89. for ($i = 0; $i < 6; $i++) {
  90. $sixMonth[] = date("Y-m", strtotime("first day of -$i month"));
  91. }
  92. return $sixMonth;
  93. }
  94. //强制删除缓存
  95. public function forgetCache(Request $request)
  96. {
  97. $which = $request->input('which');
  98. $siteId = $request->input('siteId');
  99. if ($which == 'index') {
  100. $cacheKey = sprintf('index_%s_%s', date('Ym'), auth()->id());
  101. } elseif ($which == 'single') {
  102. $cacheKey = sprintf('single_%s_site_id%s', date('Ym'), $siteId);
  103. } else {
  104. return response()->json(['message' => '参数错误'], 422);
  105. }
  106. Cache::forget($cacheKey);
  107. return response()->json(['message' => '操作成功']);
  108. }
  109. //针对单个站点的控制台
  110. public function singleSite(Request $request)
  111. {
  112. $siteId = $request->input('siteId');
  113. if (!$siteId) {
  114. $singleSite = $this->logic->getSingleSite();
  115. $siteId = $singleSite->id ?? 0;
  116. }
  117. $data = [];
  118. $site = Site::query()->withCount(['articles'])->with(['server', 'users'])->where(['id' => $siteId])->first();
  119. if (!$site) {
  120. return view('admin/errors/tips', [
  121. 'tips' => '项目站点信息不存在'
  122. ]);
  123. }
  124. if (!$site->database) {
  125. return view('admin/errors/tips', [
  126. 'tips' => '项目数据库未分配'
  127. ]);
  128. }
  129. if (!$site->server) {
  130. return view('admin/errors/tips', [
  131. 'tips' => '服务器未分配'
  132. ]);
  133. }
  134. $data['site'] = $site;
  135. $config = [
  136. 'connection_name' => sprintf('connection_name_%s', $siteId),
  137. 'host' => $site->server->server_ip,
  138. 'port' => '3306',
  139. 'database' => $site->database,
  140. 'username' => $site->server->mysql_user_name,
  141. 'password' => $site->server->mysql_passwd,
  142. ];
  143. config_connection($config);
  144. $masterDatabase = DB::connection($config['connection_name']);
  145. $rankDatabase = DB::connection('rank');
  146. try {
  147. //检测是否有此数据库
  148. $result = $masterDatabase->select(sprintf("show databases like '%s'", $site->database));
  149. if (!$result) {
  150. return view('admin/errors/tips', [
  151. 'tips' => $site->cn_title . '项目数据库不存在'
  152. ]);
  153. }
  154. } catch (\Throwable $throwable) {
  155. Log::warning(var_export($throwable->getMessage(), 1));
  156. return view('admin/errors/tips', [
  157. 'tips' => $site->cn_title . '项目数据库信息连接失败'
  158. ]);
  159. }
  160. $site->linkDetailsCount = LinkTaskDetail::query()->selectRaw('link_id')
  161. ->where([
  162. 'redundant_site_id' => $siteId,
  163. 'enable' => 1,
  164. 'status' => 5
  165. ])->groupBy('link_id')->get()->count();
  166. $cacheKey = sprintf('single_%s_site_id%s', date('Ym'), $siteId);
  167. $cacheContent = Cache::get($cacheKey);
  168. if ($cacheContent) {
  169. $data = $cacheContent;
  170. goto render;
  171. }
  172. //月报记录
  173. $historyFlowYm = $rankDatabase->table('report_flow')
  174. ->select(['flow_ym', 'project_id'])
  175. ->where('project_id', $site->old_id)->orderByDesc('flow_ym')
  176. ->limit(6)
  177. ->get();
  178. $data['historyFlowYm'] = $historyFlowYm;
  179. //项目概况 引用修改
  180. $this->logic->singleSiteProfile($rankDatabase, $site);
  181. //网页浏览量 访问量
  182. $data['pvUvData'] = $this->logic->singlePvUvcData($masterDatabase);
  183. //首页关键词数
  184. $data['topKeywordData'] = $this->logic->singleTopKeywordData($rankDatabase, $site->old_id);
  185. //询盘
  186. $data['inquireTotalData'] = $masterDatabase->table('user_msg')
  187. ->where([['is_delete', '=', 0]])->count();
  188. $data['inquireData'] = $this->logic->singleInquireData($masterDatabase);
  189. //网页数
  190. $data['pageCountData'] = $this->logic->singlePageCount($masterDatabase);
  191. //关键词达标率
  192. $data['topKeywordRate'] = [
  193. 'goal' => $site->keyword_goal,
  194. 'last1Reach' => $data['topKeywordData']['top10']['last1'],
  195. 'last2Reach' => $data['topKeywordData']['top10']['last2']['val'],
  196. 'last3Reach' => $data['topKeywordData']['top10']['last3']['val'],
  197. ];
  198. //网站展示量
  199. $data['webmasterEffectImpressionsTotal'] = $rankDatabase->table('webmaster_effect')->selectRaw('ym,SUM(clicks) as clicks,SUM(impressions) AS impressions')
  200. ->where(['project_id' => $site->old_id])->first()->impressions ?? 0;
  201. $data['webmasterEffect'] = $this->logic->singleWebmasterEffectData($rankDatabase, $site->old_id);
  202. //文章达标率
  203. $data['articleRate'] = $this->logic->singleArticleRate($site);
  204. //外链达标率
  205. $data['linkRate'] = $this->logic->singleLinkRate($site);
  206. //我的文章
  207. $data['myArticles'] = $this->logic->singleMyArticles($siteId);
  208. //我的外链任务
  209. $data['myLinkTasks'] = $this->logic->singleMyLinksTasks($siteId);
  210. //流量折线图
  211. $data['trafficLine'] = $this->logic->singleTrafficLine($masterDatabase);
  212. //询盘折线图
  213. $data['inquireLine'] = $this->logic->singleInquireLine($masterDatabase);
  214. //关键词折线图
  215. $data['keywordLine'] = $this->logic->singleKeywordLine($rankDatabase, $site->old_id);
  216. //引擎力学堂
  217. $data['assets'] = Asset::query()->with('assetType')->get();;
  218. //客服人员
  219. $data['serverUsers'] = $site->users->where('role_id', Role::TYPE_SERVER);
  220. //引擎力产品推荐
  221. $data['products'] = Product::query()->where(['status' => 1])->get();
  222. Cache::put($cacheKey, $data, new \DateTime(date('Y-m-t 23:59:59')));
  223. render:
  224. if (!$site->reach_at) {
  225. $data['reachDaysData'] = '未达标';
  226. } else {
  227. $diffDatetime = date_diff(date_create($site->reach_at), date_create());
  228. $data['reachDaysData']=$diffDatetime->days>=0? abs($diffDatetime->days).'天':"未达标";
  229. }
  230. //关键词达标
  231. $data['reachDays'] = $this->logic->singleReachDays($site);
  232. //建站完成的
  233. $data['buildDone'] = $this->logic->singleBuildDone($siteId);
  234. ////网址异常
  235. $data['urlFailed'] = $this->logic->singleUrlFailed($siteId);
  236. //关键词排名急剧下降
  237. //询盘
  238. $data['inquireTotalData'] = $masterDatabase->table('user_msg')
  239. ->where([['is_delete', '=', 0]])->count();
  240. $data['inquireData'] = $this->logic->singleInquireData($masterDatabase);
  241. //证书过期项目
  242. $data['isCertExpired'] = $site->cert_expired_date ? (strtotime($site->cert_expired_date) < strtotime('+1 month')) : 0;
  243. //域名过期项目 domain_expired_date
  244. $data['isDomainExpired'] = $site->cert_expired_date ? (strtotime($site->domain_expired_date) < strtotime('+1 month')) : 0;
  245. $data['keywordLessVal'] = $this->logic->singleKeywordLessVal($rankDatabase, $site->old_id);
  246. return view('admin/meter/single', $data);
  247. }
  248. public function serviceFeedback(ServiceFeedbackRequest $request)
  249. {
  250. $validated = $request->validated();
  251. $site = Site::query()->select(['cn_title', 'domain'])->where(['id' => $validated['site_id']])->first();
  252. if (!$site) {
  253. return response()->json(['message' => '项目信息不存在'], 422);
  254. }
  255. $validated['creator_id'] = Auth::id();
  256. $validated = $validated + $site->toArray();
  257. ServiceFeedback::query()->create($validated);
  258. return response()->json(['message' => '操作成功']);
  259. }
  260. //客户总控台 投诉表单
  261. public function feedback(Request $request)
  262. {
  263. $content = trim($request->input('content'));
  264. $faq = trim($request->input('faq'));
  265. if (!$content) {
  266. return response()->json(['message' => '请填写内容'], 422);
  267. }
  268. if (mb_strlen($content) > 2000) {
  269. return response()->json(['message' => '内容不能超过两千字'], 422);
  270. }
  271. Feedback::query()->create([
  272. 'site_id' => $request->input('siteId'),
  273. 'content' => $content,
  274. 'faq' => $faq,
  275. 'creator_id' => Auth::id()
  276. ]);
  277. return response()->json(['message' => '操作成功']);
  278. }
  279. //达标项目导出
  280. public function exportReachSitesExcel()
  281. {
  282. $userSites = $this->userSites();
  283. $validSiteIds = $userSites->pluck('id')->toArray();
  284. $siteRecords = $this->logic->indexReachSites($validSiteIds);
  285. $dataList[] = ['域名', '项目名称', '达标日期', '分数', '尾款'];
  286. foreach ($siteRecords as $site) {
  287. $sitesProcess = $site->sitesProcess->first();
  288. $dataList[] = [
  289. 'domain' => $site->domain,
  290. 'cn_title' => $site->cn_title,
  291. 'reach_at' => $site->reach_at,
  292. 'score' => $sitesProcess->evaluate['score'] ?? '',
  293. 'reach_payment' => $site->sitePayment->reach ?? ''
  294. ];
  295. }
  296. return (new BasicExport($dataList))->download(sprintf('达标项目列表%s.xls', date('YmdHis')));
  297. }
  298. //建站项目导出
  299. public function exportBuildSitesExcel()
  300. {
  301. $userSites = $this->userSites();
  302. $validSiteIds = $userSites->pluck('id')->toArray();
  303. $siteRecords = $this->logic->indexBuildDoneSites($validSiteIds);
  304. $dataList[] = ['域名', '项目名称', '达标日期', '分数', '中期款'];
  305. foreach ($siteRecords as $site) {
  306. $sitesProcess = $site->sitesProcess->first();
  307. $dataList[] = [
  308. 'domain' => $site->domain,
  309. 'cn_title' => $site->cn_title,
  310. 'reach_at' => $site->reach_at,
  311. 'score' => $sitesProcess->evaluate['score'] ?? '',
  312. 'done_payment' => $site->sitePayment->done ?? ''
  313. ];
  314. }
  315. return (new BasicExport($dataList))->download(sprintf('建站完成项目列表%s.xls', date('YmdHis')));
  316. }
  317. protected function getTime($dateRange)
  318. {
  319. if (!$dateRange) {
  320. return null;
  321. }
  322. $startDate = substr($dateRange, 0, 10);
  323. $endDate = substr($dateRange, -10, -1);
  324. return [
  325. ['reach_at', '>=', sprintf('%s 00:00:00', $startDate)],
  326. ['reach_at', '<=', sprintf('%s 23:59:59', $endDate)]
  327. ];
  328. }
  329. //筛选达标站点
  330. public function filterReachSites(Request $request)
  331. {
  332. $dateRangeFilter = $this->getTime($request->input('dateRange'));
  333. $userSites = $this->userSites();
  334. $validSiteIds = $userSites->pluck('id')->toArray();
  335. $siteRecords = $this->logic->indexReachSites($validSiteIds, $dateRangeFilter);
  336. $dataList = [];
  337. foreach ($siteRecords as $site) {
  338. $sitesProcess = $site->sitesProcess->first();
  339. $dataList[] = [
  340. 'domain' => $site->domain,
  341. 'cn_title' => $site->cn_title,
  342. 'reach_at' => $site->reach_at,
  343. 'score' => $sitesProcess->evaluate['score'] ?? '',
  344. 'reach_payment' => $site->sitePayment->reach ?? ''
  345. ];
  346. }
  347. return response()->json(['data' => $dataList]);
  348. }
  349. //筛选建站站点
  350. public function filterBuildSites(Request $request)
  351. {
  352. $dateRangeFilter = $this->getTime($request->input('dateRange'));
  353. $userSites = $this->userSites();
  354. $validSiteIds = $userSites->pluck('id')->toArray();
  355. $siteRecords = $this->logic->indexBuildDoneSites($validSiteIds, $dateRangeFilter);
  356. $dataList = [];
  357. foreach ($siteRecords as $site) {
  358. $sitesProcess = $site->sitesProcess->first();
  359. $dataList[] = [
  360. 'domain' => $site->domain,
  361. 'cn_title' => $site->cn_title,
  362. 'reach_at' => $site->reach_at,
  363. 'score' => $sitesProcess->evaluate['score'] ?? '',
  364. 'done_payment' => $site->sitePayment->done ?? ''
  365. ];
  366. }
  367. return response()->json(['data' => $dataList]);
  368. }
  369. //品宣仪表
  370. public function propaganda(Request $request)
  371. {
  372. if (!$request->ajax()) {
  373. return view('admin/meter/propaganda');
  374. }
  375. $keyword = $request->input('keyword');
  376. if ($status = $request->input('status')) {
  377. $condition['status'] = $status;
  378. }
  379. $builder = Site::query()->withCount([
  380. // 'renewHistory',
  381. 'socialPublish' => function (Builder $query) {
  382. $query->whereNull('social_sync_at');
  383. },
  384. 'socialPublish as socialPublishFailCount' => function (Builder $query) {
  385. $query->whereJsonContains('result_status', ['pin' => SocialPublish::STATUS_FAILURE])
  386. ->orWhereJsonContains('result_status', ['facebook' => SocialPublish::STATUS_FAILURE])
  387. ->orWhereJsonContains('result_status', ['twitter' => SocialPublish::STATUS_FAILURE]);
  388. },
  389. 'articles as month_articles_count' => function (Builder $query) {
  390. $query->where('created_at', '>', date('Y-m-01 00:00:00'));
  391. }, 'articles as no_sync_articles_count' => function (Builder $query) {
  392. $query->whereNull('sync_at');
  393. },
  394. 'articles as weekArticlesCount' => function (Builder $query) {
  395. $query->where('created_at', '>', date('Y-m-d H:i:s', strtotime('-2 week')));
  396. },
  397. 'articles as monthArticlesCount' => function (Builder $query) {
  398. $query->where('created_at', '>', date('Y-m-d H:i:s', strtotime('-1 month')));
  399. },
  400. 'linkDetails' => function (Builder $query) {
  401. $query->where([['enable', '=', 1], ['status', '=', 5]]);
  402. },
  403. 'linkDetails as month_link_details_count' => function (Builder $query) {
  404. $query->where([['enable', '=', 1], ['status', '=', 5]])->where('created_at', '>', date('Y-m-01 00:00:00'));;
  405. },
  406. 'linkUrls' => function (Builder $query) {
  407. $query->where('link_tasks_detail.enable', 1)
  408. ->where('link_tasks_detail.status', 5)
  409. ->where('link_tasks_url.status', 5);
  410. },
  411. 'linkUrls as month_link_urls_count' => function (Builder $query) {
  412. $query->where('link_tasks_detail.enable', 1)
  413. ->where('link_tasks_detail.status', 5)
  414. ->where('link_tasks_url.status', 5)
  415. ->where('link_tasks_url.created_at', '>', date('Y-m-01 00:00:00'));
  416. },
  417. 'linkUrls as lastMonthLinkUrlsCount' => function (Builder $query) {
  418. $query->where('link_tasks_url.created_at', '>', date('Y-m-d H:i:s', strtotime('-1 month')));
  419. }
  420. ])->with(['users', 'renewHistory'])->whereIn('status', [2, 3])->where($condition ?? [])->where(function (Builder $builder) use ($keyword) {
  421. if ($keyword) {
  422. $builder->where('domain', 'like', '%' . $keyword . '%')
  423. ->orWhere('cn_title', 'like', '%' . $keyword . '%');
  424. }
  425. });
  426. $sortName = $request->input('sortName');
  427. $sortOrder = $request->input('sortOrder');
  428. if ($sortName == 'statusTitle') {
  429. $builder->orderBy('status', $sortOrder);
  430. }
  431. $records = $builder->orderByDesc('id')
  432. ->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE);
  433. $items = $records->items();
  434. $oldIds = array_filter(array_column($items, 'old_id'));
  435. $rankConnection = DB::connection('rank');
  436. $lastListReportMap = $rankConnection->table('project_listreport')->whereIn('project_id', $oldIds)->where([
  437. 'ym' => date('Ym', strtotime('first day of -1 month'))
  438. ])->get()->keyBy('project_id')->toArray();
  439. $last2ListReportMap = $rankConnection->table('project_listreport')->whereIn('project_id', $oldIds)->where([
  440. 'ym' => date('Ym', strtotime('first day of -2 month'))
  441. ])->get()->keyBy('project_id')->toArray();
  442. array_walk($items, function ($item) use (&$lastListReportMap, &$last2ListReportMap) {
  443. $lastRenew = $item->renewHistory->last();
  444. //唉。
  445. if ($lastRenew) {
  446. $publishArticleCount = Article::query()->where([
  447. ['site_id', '=', $item->id],
  448. ['created_at', '>', $lastRenew->created_at]
  449. ])->count();
  450. } else {
  451. $publishArticleCount = Article::query()->where([
  452. ['site_id', '=', $item->id]
  453. ])->count();
  454. }
  455. $item->managers_title = implode('-', $item->users->where('role_id', Role::TYPE_MANAGER)->pluck('nickname')->toArray());
  456. $item->statusTitle = Site::STATUS_MAP[$item->status] ?? '';
  457. if ($item->old_id) {
  458. if (empty($lastListReportMap[$item->old_id])) {
  459. $item->traffic = '-';
  460. } else {
  461. $last2Traffic = $last2ListReportMap[$item->old_id]->traffic ?? 0;
  462. $lastTraffic = $lastListReportMap[$item->old_id]->traffic;
  463. $isIncrease = ($lastTraffic - $last2Traffic) > 0;
  464. $item->traffic = sprintf('<span class="%s" title="%s">%s</span>', $isIncrease, $last2Traffic, $lastTraffic);
  465. }
  466. } else {
  467. $item->traffic = '未关联';
  468. }
  469. $item->online_date = $item->online_at ? date('Y-m-d', strtotime($item->online_at)) : '';
  470. //期数
  471. $item->renew_count = $item->renewHistory->count() + 1;
  472. if ($item->socialPublishFailCount > 0) {
  473. $failSocialClass = 'socialFail';
  474. }
  475. $item->social_queue_count = sprintf(
  476. '<div class="%s">%s|%s</div>',
  477. ($failSocialClass ?? ''),
  478. $item->social_publish_count,
  479. $item->socialPublishFailCount
  480. );
  481. if ($item->article_goal <= $publishArticleCount) {
  482. $articleReachClass = 'reachGoal';
  483. }
  484. $item->article_goal_text = sprintf('<div class="%s">%s</div>', ($articleReachClass ?? ''), $item->article_goal);
  485. if ($item->link_goal <= $item->link_urls_count) {
  486. $linkReachClass = 'reachGoal';
  487. }
  488. $item->link_goal_text = sprintf('<div class="%s">%s</div>', ($linkReachClass ?? ''), $item->link_goal);
  489. if ($item->status == 2 && $item->weekArticlesCount < 1) {//实时期
  490. $articleClass = 'articleUnUpdate';
  491. }
  492. if ($item->status == 3 && $item->monthArticlesCount < 1) {//服务期
  493. $articleClass = 'articleUnUpdate';
  494. }
  495. //外链一个月没更新
  496. if ($item->lastMonthLinkUrlsCount < 1) {
  497. $linkClass = 'linkUnUpdate';
  498. }
  499. $item->articles_count_mul = sprintf(
  500. '<div class="%s">%s<b>|</b><span style="color: red">%s</span><b>|</b>%s</div>',
  501. ($articleClass ?? ''),
  502. $publishArticleCount, $item->month_articles_count, $item->no_sync_articles_count
  503. );
  504. $item->link_details_count_mul = sprintf('%s|%s', $item->link_details_count, $item->month_link_details_count);
  505. $item->link_urls_count_mul = sprintf('<div class="%s">%s|%s<div>', ($linkClass ?? ''), $item->link_urls_count, $item->month_link_urls_count);
  506. });
  507. return response()->json([
  508. 'rows' => $items,
  509. 'total' => $records->total()
  510. ]);
  511. }
  512. }