logic = $logic; } /** * 外链库案例列表 */ public function infoIndex(Request $request ) { if ($keyword = $request->input('keyword')) { $condition[] = ['link_url', '=',$keyword]; } if (!$request->ajax()) { $list = LinkTaskDetail::query() ->selectRaw("link_type,count(id) as count")->groupBy('link_type')->get(); foreach ($list as $value){ $value['cn_title'] = LinkStatistical::query() ->where('site_id','=',$value['redundant_site_id']) ->value('cn_title'); } $businesses = Business::query()->get(); return view('admin/link/info', [ 'list' => $list ]); } $link = LinkTaskDetail::query(); $records = $link->where($condition ?? [])->orderByDesc('id') ->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); foreach ($items as $value){ $value['cn_title'] = LinkStatistical::query() ->where('site_id','=',$value['redundant_site_id']) ->value('cn_title'); } $businesses = Business::query()->pluck('title', 'id'); array_walk($items, function ($item) use ($businesses) { if ($item->big_ball == 0) { $item->bigBall = '否'; } else { $item->bigBall = '是'; } $business = explode(',', $item->business_ids); $list = []; foreach ($business as $value) { $list[] = $businesses[$value] ?? ''; } if (!empty($list)) { $item->business = implode(',', $list); } else { $item->business = ''; } }); return response()->json([ 'rows' => $items, 'total' => $records->total() ]); } public function externalInfoExport(Request $request) { $link = LinkTaskDetail::query(); $request = $request->all(); if (!empty($request['keyword'])) { $link->where('link_url', '=', $request['keyword']); } $data = []; $list = $link->orderBy('id', 'desc')->get(); foreach ($list as $value) { $cn_title = LinkStatistical::query() ->where('site_id','=',$value->redundant_site_id) ->value('cn_title'); $list = []; $data[] = [ 'link_type' => $value->link_type ?? '', 'cn_title'=>$cn_title, 'link_url' => $value->link_url, 'username' => $value->username, 'email' => $value->email, 'password' => $value->password, 'url ' => $value->url, 'created_at' => $value->created_at, ]; } array_unshift($data, ['外链类型','项目名称', '平台链接', '用户名', '邮箱', ' 密码', 'profile演示地址', '创建时间']); return (new BasicExport($data))->download(sprintf('外链%s.xls', date('YmdHis'))); } /** * 外链库案例列表 */ public function caseIndex(Request $request) { if (!$request->ajax()) { $list = LinkCase::query() ->selectRaw("type,count(id) as count")->groupBy('type')->get(); foreach ($list as $value) { $value->type = LinkCase::TYPES[$value['type']] ?? ''; } $businesses = Business::query()->get(); return view('admin/link/case', [ 'businesses' => $businesses, 'list' => $list ]); } $link = LinkCase::query(); if ($keyword = $request->input('keyword')) { $condition[] = ['url', 'like', '%' . $keyword . '%']; } if ($type = $request->input('type')) { $condition[] = ['type', '=', $type]; } if ($businessIds = $request->input('business_ids')) { $link->whereRaw('FIND_IN_SET(?,business_ids)', [$businessIds]); } $records = $link->where($condition ?? [])->orderByDesc('id') ->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); $businesses = Business::query()->pluck('title', 'id'); array_walk($items, function ($item) use ($businesses) { $item->typeTitle = Link::TYPES[$item->type] ?? ''; if ($item->big_ball == 0) { $item->bigBall = '否'; } else { $item->bigBall = '是'; } $business = explode(',', $item->business_ids); $list = []; foreach ($business as $value) { $list[] = $businesses[$value] ?? ''; } if (!empty($list)) { $item->business = implode(',', $list); } else { $item->business = ''; } }); return response()->json([ 'rows' => $items, 'total' => $records->total() ]); } /** * 外链库案例save */ public function caseSave(CaseSaveRequest $request, $id) { if (!$request->ajax()) { $businesses = Business::query()->get(); return view('admin/link/case_save', [ 'data' => LinkCase::query()->find($id), 'typeList' => LinkCase::TYPES ]); } LinkCase::query()->updateOrCreate(['id' => $id], $request->validated()); return response()->json(['message' => '操作成功']); } /************ * 外链库案例删除 * @param Request $request * @return JsonResponse */ public function batchCaseDelete(Request $request) { $ids = $request->input('ids'); if (!is_array($ids)) return response()->json(['message' => '删除时参数传递错误'], 422); LinkCase::destroy($ids); return response()->json(['message' => '操作成功']); } /************ * 外链库案例导入 * @param Request $request * @return JsonResponse */ public function externalCaseImport(Request $request) { set_time_limit(0); if (!$request->input('excel_path')) { return response()->json(['message' => '请先上传excel文件'], 422); } try { Excel::import(new ExternalCaseImport(), $request->input('excel_path'), 'public'); } catch (\Throwable $throwable) { Log::error(var_export($throwable->getMessage(), 1)); return response()->json(['message' => '导入失败'], 400); } return response()->json(['message' => '操作成功']); } /** * 外链库管理列表 * @param Request $request * @return Factory|JsonResponse|View */ public function index(Request $request) { if (!$request->ajax()) { $list = Link::query() ->where('tag', '!=', '放弃') ->selectRaw("type,count(id) as count")->groupBy('type')->get(); foreach ($list as $value) { $value->type = Link::TYPES[$value['type']] ?? ''; } $businesses = Business::query()->get(); return view('admin/link/index', [ 'businesses' => $businesses, 'list' => $list ]); } $link = Link::query(); if ($keyword = $request->input('keyword')) { $condition[] = ['url', 'like', '%' . $keyword . '%']; } if ($type = $request->input('type')) { $condition[] = ['type', '=', $type]; } if ($businessIds = $request->input('business_ids')) { $link->whereRaw('FIND_IN_SET(?,business_ids)', [$businessIds]); } $records = $link->where($condition ?? [])->orderByDesc('id') ->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); $businesses = Business::query()->pluck('title', 'id'); array_walk($items, function ($item) use ($businesses) { $item->typeTitle = Link::TYPES[$item->type] ?? ''; if ($item->big_ball == 0) { $item->bigBall = '否'; } else { $item->bigBall = '是'; } $business = explode(',', $item->business_ids); $list = []; foreach ($business as $value) { $list[] = $businesses[$value] ?? ''; } if (!empty($list)) { $item->business = implode(',', $list); } else { $item->business = ''; } }); return response()->json([ 'rows' => $items, 'total' => $records->total() ]); } /** * 外链库管理列表导出 * @param Request $request * @return Factory|JsonResponse|View */ public function externalCaseExport(Request $request) { $link = LinkCase::query(); $request = $request->all(); if (!empty($request['type'])) { $link->where('type', $request['type']); } if (!empty($request['keyword'])) { $link->where('url', 'like', '%' . $request['keyword'] . '%'); } $data = []; $list = $link->orderBy('id', 'desc')->get(); foreach ($list as $value) { $list = []; $data[] = [ 'typeTitle' => LinkCase::TYPES[$value->type] ?? '', 'url' => $value->url, 'username_history' => $value->username_history, 'email_history' => $value->email_history, 'password_history' => $value->password_history, 'url_history' => $value->url_history, 'created_at' => $value->created_at, ]; } array_unshift($data, ['外链类型', '平台链接', '用户名', '邮箱', ' 密码', 'profile演示地址', '创建时间']); return (new BasicExport($data))->download(sprintf('外链案例%s.xls', date('YmdHis'))); } //外链注意事项 public function notice(Request $request) { if (!$request->ajax()) { $data = ArticleLinkNotice::query()->where(['type' => 'link'])->first(); return view('admin/link/notice', [ 'data' => $data ?? '' ]); } ArticleLinkNotice::query()->where(['type' => 'link'])->update([ 'content' => $request->input('content') ]); return response()->json(['message' => '操作成功']); } public function save(SaveRequest $request, $id) { if (!$request->ajax()) { $businesses = Business::query()->get(); return view('admin/link/save', [ 'data' => Link::query()->find($id), 'typeList' => Link::TYPES, 'businesses' => $businesses ]); } Link::query()->updateOrCreate(['id' => $id], $request->validated()); return response()->json(['message' => '操作成功']); } public function batchDelete(Request $request) { $ids = $request->input('ids'); if (!is_array($ids)) return response()->json(['message' => '删除时参数传递错误'], 422); Link::destroy($ids); return response()->json(['message' => '操作成功']); } //外链统计 public function linkCount(Request $request, $id) { if (!$request->ajax()) { return view( 'admin/link/link_count_for_site', ['siteId' => $id] ); } $detailRecords = LinkTaskDetail::query()->selectRaw('link_id,any_value(id) as id') ->when($request->input('keyword'), function (Builder $builder, $keyword) { $linkIds = Link::query()->where('url', 'like', '%' . $keyword . '%')->pluck('id')->toArray(); $builder->whereIn('link_id', $linkIds); }) ->where([ 'redundant_site_id' => $id, 'enable' => 1, 'status' => 5 ])->groupBy('link_id')->orderByDesc('id')->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $detailIds = array_column($detailRecords->items(), 'id'); $records = $builder = LinkTaskDetail::query()->with(['linkTask', 'link']) ->withCount('urls')->whereIn('id', $detailIds)->orderByDesc('id')->get()->toArray(); $linkTypes = Link::TYPES; array_walk($records, function (&$item) use (&$linkTypes) { $item['task_title'] = $item['link_task']['title'] ?? ''; $item['link_url_source'] = $item['link']['url'] ?? ''; $item['link_type_source'] = $linkTypes[($item['link']['type'] ?? 0)] ?? ''; }); return response()->json([ 'rows' => $records, 'total' => $detailRecords->total() ]); } /** * 客户界面的外链统计 * @param Request $request * @return Factory|JsonResponse|View */ public function customerLinkCount(Request $request) { $oneSite = $this->hasUserOneSite(); if (!$oneSite) { return view('admin/errors/tips'); } if (!$request->ajax()) { return view( 'admin/link/customer_link_count', ['siteId' => $oneSite->id] ); } $detailRecords = LinkTaskDetail::query()->selectRaw('link_id,any_value(id) as id') ->when($request->input('keyword'), function (\Illuminate\Database\Eloquent\Builder $builder, $keyword) { $linkIds = Link::query()->where('url', 'like', '%' . $keyword . '%')->pluck('id')->toArray(); $builder->whereIn('link_id', $linkIds); }) ->where([ 'redundant_site_id' => $oneSite->id, 'enable' => 1, 'status' => 5 ]) // ->whereNotExists(function (Builder $builder) { // $builder->select(DB::raw(1))->from('link_tasks') // ->whereRaw('link_tasks_detail.task_id=link_tasks.id AND (link_tasks.status in (4) OR link_tasks.deleted_at is not null)'); // }) ->groupBy('link_id')->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $detailIds = array_column($detailRecords->items(), 'id'); $records = $builder = LinkTaskDetail::query()->with(['linkTask', 'link']) ->withCount('urls')->whereIn('id', $detailIds)->get()->toArray(); $linkTypes = Link::TYPES; array_walk($records, function (&$item) use (&$linkTypes) { $item['task_title'] = $item['link_task']['title'] ?? ''; $item['link_url_source'] = $item['link']['url'] ?? ''; $item['link_type_source'] = $linkTypes[($item['link']['type'] ?? 0)] ?? ''; }); return response()->json([ 'rows' => $records, 'total' => $detailRecords->total() ]); } //外链统计导出 public function linkCountExport(Request $request, $siteId) { $detailRecords = LinkTaskDetail::query()->selectRaw('link_id,any_value(id) as id') ->when($request->input('keyword'), function (\Illuminate\Database\Eloquent\Builder $builder, $keyword) { $linkIds = Link::query()->where('url', 'like', '%' . $keyword . '%')->pluck('id')->toArray(); $builder->whereIn('link_id', $linkIds); }) ->where([ 'redundant_site_id' => $siteId, 'enable' => 1, 'status' => 5 ]) // ->whereNotExists(function (Builder $builder) { // $builder->select(DB::raw(1))->from('link_tasks') // ->whereRaw('link_tasks_detail.task_id=link_tasks.id AND (link_tasks.status in (4) OR link_tasks.deleted_at is not null)'); // }) ->groupBy('link_id')->get()->toArray(); $detailIds = array_column($detailRecords, 'id'); $records = $builder = LinkTaskDetail::query()->with(['linkTask', 'link'])->whereIn('id', $detailIds)->get()->toArray(); $results = []; $linkTypes = Link::TYPES; array_walk($records, function ($item) use (&$results, &$linkTypes) { $results[] = [ 'task_title' => $item['link_task']['title'] ?? '', 'link_type' => $linkTypes[($item['link']['type'] ?? 0)] ?? '', 'link_url' => $item['link']['url'] ?? '', 'username' => $item['username'], 'password' => $item['password'], 'email' => $item['email'], 'url' => $item['url'], 'created_at' => (string)$item['created_at'], ]; }); array_unshift($results, ['关联外链标题', '类型', '平台链接', '用户名', '邮箱', '密码', 'profile演示地址', '创建时间']); return (new LinkCountExport($results))->download(sprintf('外链统计%s.xls', date('YmdHis'))); } protected function getLinkUrlTime($dateRange) { if (!$dateRange) { return []; } $startDate = substr($dateRange, 0, 10); $endDate = substr($dateRange, -10); return [ ['created_at', '>=', sprintf('%s 00:00:00', $startDate)], ['created_at', '<=', sprintf('%s 23:59:59', $endDate)] ]; } public function linkUrl(Request $request, $siteId) { if (!$request->ajax()) { return view( 'admin/link/link_url_for_site', ['siteId' => $siteId] ); } $dateRange = $request->input('date_range'); $linkCondition = $this->getLinkUrlTime($dateRange); $condition[] = ['redundant_site_id', '=', $siteId]; $condition[] = ['enable', '=', 1]; $condition[] = ['status', '=', 5]; $detailIds = LinkTaskDetail::query()->where($condition)->pluck('id')->toArray(); $builder = LinkTaskUrl::query()->with(['linkDetails'])->whereIn('link_tasks_detail_id', $detailIds)->where($linkCondition)->where(['status' => 5]); $records = $builder->orderBy('id', 'desc')->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); $idMapLink = Link::query()->select(['type', 'url', 'id']) ->get()->keyBy('id')->toArray(); array_walk($items, function ($item) use (&$idMapLink) { if (!empty($item->linkDetails->link_id)) { $item->link_url = sprintf('%s【%s】', $idMapLink[$item->linkDetails->link_id]['url'], Link::TYPES[$idMapLink[$item->linkDetails->link_id]['type']]); } else { $item->link_url = ''; } $item->profile_url = $item->linkDetails->url ?? ''; $item->detail_username = $item->linkDetails->username ?? ''; $item->detail_email = $item->linkDetails->email ?? ''; $item->detail_password = $item->linkDetails->password ?? ''; }); return response()->json([ 'rows' => $items, 'total' => $records->total() ]); } //客户界面 link-url public function customerLinkUrl(Request $request) { $oneSite = $this->hasUserOneSite(); if (!$oneSite) { return view('admin/errors/tips'); } if (!$request->ajax()) { return view( 'admin/link/customer_link_url', ['siteId' => $oneSite->id] ); } $dateRange = $request->input('date_range'); $condition = $this->getLinkUrlTime($dateRange); $condition[] = ['redundant_site_id', '=', $oneSite->id]; $condition[] = ['enable', '=', 1]; $condition[] = ['status', '=', 5]; $detailIds = LinkTaskDetail::query()->where($condition)->pluck('id')->toArray(); $builder = LinkTaskUrl::query()->with(['linkDetails'])->whereIn('link_tasks_detail_id', $detailIds)->where(['status' => 5]); $records = $builder->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); $idMapLink = Link::query()->select(['type', 'url', 'id'])->get()->keyBy('id')->toArray(); array_walk($items, function ($item) use (&$idMapLink) { if (!empty($item->linkDetails->link_id)) { $item->link_url = sprintf('%s【%s】', $idMapLink[$item->linkDetails->link_id]['url'], Link::TYPES[$idMapLink[$item->linkDetails->link_id]['type']]); } else { $item->link_url = ''; } $item->profile_url = $item->linkDetails->url ?? ''; $item->detail_username = $item->linkDetails->username ?? ''; $item->detail_email = $item->linkDetails->email ?? ''; $item->detail_password = $item->linkDetails->password ?? ''; }); return response()->json([ 'rows' => $items, 'total' => $records->total() ]); } //导出外链url public function linkUrlExport(Request $request, $siteId) { $dateRange = $request->input('date_range'); $linkCondition = $this->getLinkUrlTime($dateRange); $condition[] = ['redundant_site_id', '=', $siteId]; $condition[] = ['enable', '=', 1]; $condition[] = ['status', '=', 5]; $detailIds = LinkTaskDetail::query()->where($condition)->pluck('id')->toArray(); $builder = LinkTaskUrl::query()->with(['linkDetails']) ->whereIn('link_tasks_detail_id', $detailIds)->where($linkCondition)->where(['status' => 5]) ->orderBy('id', 'desc'); $records = $builder->get(); $results = []; foreach ($records as $inx => $item) { if (!empty($item->linkDetails->link_id)) { $results[$inx][] = $item->link_url = sprintf( '%s【%s】', $item->linkDetails->link_url ?? '', $item->linkDetails->link_type ?? '' ); } else { $results[][$inx] = ''; } $results[$inx][] = $item->linkDetails->username ?? ''; $results[$inx][] = $item->linkDetails->email ?? ''; $results[$inx][] = $item->linkDetails->password ?? ''; $results[$inx][] = $item->linkDetails->url ?? ''; $results[$inx][] = $item->url ?? ''; $results[$inx][] = $item->created_at; } array_unshift($results, ['平台链接', '用户名', '邮箱', '密码', 'profile演示地址', '外链地址', '创建时间']); return (new BasicExport($results))->download(sprintf('外链地址%s.xls', date('YmdHis'))); } //删除 link-detail public function linkDetailDel(Request $request) { $ids = $request->input('ids'); LinkTaskDetail::query()->whereIn('id', $ids)->update(['enable' => 0]); return response()->json(['message' => '操作成功']); } public function linkCountSave(LinkCountSaveRequest $request, $linkDetailId) { $siteId = $request->input('siteId'); $allLinks = Link::all(); if (!$request->ajax()) { return view('admin/link/link_count_save', [ 'allLinks' => $allLinks, 'data' => LinkTaskDetail::query()->find($linkDetailId), 'siteId' => $siteId ]); } $validated = $request->validated(); $exists = LinkTaskDetail::query()->where(['redundant_site_id' => $siteId, 'link_id' => $validated['link_id'], 'enable' => 1])->select(['id'])->first(); if ($exists && $exists->id != $linkDetailId) { return response()->json(['message' => '外链类型已存在'], 400); } $validated['redundant_site_id'] = $siteId; $link = Link::query()->where(['id' => $validated['link_id']])->first(); $validated['link_type'] = Link::TYPES[($link->type ?? 0)] ?? ''; $validated['link_url'] = $link->url ?? ''; $validated['enable'] = 1; $validated['status'] = 5; $validated['created_at'] = empty($validated['created_at']) ? date('Y-m-d H:i:s') : $validated['created_at']; LinkTaskDetail::query()->updateOrCreate(['id' => $linkDetailId], $validated); return response()->json(['message' => '操作成功']); } /** * 外链任务列表 * @param Request $request * @return Factory|JsonResponse|View */ public function taskIndex(Request $request) { if (!$request->ajax()) { return view('admin/link/task'); } $records = $this->logic->taskFilters($request->input())->with(['worker', 'site', 'score'])->with('linkDetails')->with('linkUrls') ->orderByDesc('id')->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); array_walk($items, function ($item) { $item->typeTitle = $item->type_title; $item->worker_name = $item->worker->username ?? ''; $item->site_title = $item->site->cn_title ?? ''; $item->status_title = $item->status_with_css; $item->totalScore = $item->score->total ?? ''; $totalUrls = 0; $detailIdList = $item->linkUrls->groupBy('link_tasks_detail_id')->toArray(); foreach ($item->linkDetails as $detail) { if (empty($detailIdList[$detail->id])) { continue; } if ($detail->link_type == '一次性') { $totalUrls += (count($detailIdList[$detail->id]) * 2); } elseif ($detail->link_type == '书签') { $totalUrls += (count($detailIdList[$detail->id]) * 0.5); } else { $totalUrls += count($detailIdList[$detail->id]); } } $item->linkUrlsCount = $totalUrls; if ($item->release_at && $item->release_at > date('Y-m-d H:i:s')) { $item->un_release_at = $item->release_at; } }); return response()->json(['rows' => $items, 'total' => $records->total()]); } public function optimizePage(Request $request) { $siteId = $request->input('siteId'); $data = SiteOptimizePage::query()->where(['site_id' => $siteId])->get()->toArray(); return response()->json(['data' => $data]); } //任务保存 public function taskSave(TaskSaveRequest $request, $id) { if (!$request->ajax()) { if ($id > 0) { //编辑 $link = LinkTask::query()->where(['id' => $id])->first(); if (!$link) { return response()->json(['message' => '外链任务信息不存在'], 400); } $linkIds = LinkTaskDetail::query()->where('task_id', $id)->pluck('link_id')->toArray(); $linkIdsStr = json_encode($linkIds); $selectedLinkTypeList = Link::query()->whereIn('id', $linkIds)->get(); $optimizePageList = SiteOptimizePage::query()->where(['site_id' => $link->site_id])->get()->toArray(); } $siteId = $request->input('siteId'); if ($siteId && !isset($optimizePageList)) { $optimizePageList = SiteOptimizePage::query()->where(['site_id' => $siteId])->get()->toArray(); } return view('admin/link/task_save', [ 'sites' => $this->userSites(), 'workers' => User::query()->whereIn('role_id', [Role::TYPE_LINK_PART_CHONGQING, Role::TYPE_LINK_PART])->get(), 'data' => $link ?? null, 'siteId' => $request->input('siteId'), //为了项目外链管理 默认选中当前项目 'linkIdsStr' => $linkIdsStr ?? '', 'selectedLinkType' => Link::query()->get()->groupBy('type'), 'typeList' => Link::TYPES, 'selectedLinkTypeList' => $selectedLinkTypeList ?? [], 'optimizePageList' => $optimizePageList ?? [] ]); } $validated = $request->validated(); if ($id > 0 && !is_array($validated['link']['link_ids'] ?? null)) { return response()->json(['message' => '修改时请选择外链库'], 400); } if (!is_array($validated['link']['link_ids'] ?? null) && !is_array($validated['link']['link_ids_with_time'] ?? null)) { return response()->json(['message' => '至少选择一种外链方式'], 400); } if ($validated['link']['link_ids_with_time'] && $id == 0) { $groupId = 0; foreach ($validated['link']['link_ids_with_time'] as $item) { $this->logic->taskSave($id, $validated['task'], $item['link_ids'], $groupId, $item['release_at']); } } else { $groupId = -1; $this->logic->taskSave($id, $validated['task'], $validated['link']['link_ids'], $groupId); } return response()->json(['message' => '操作成功']); } //添加外链任务时 的 任务选择 public function linkChose(Request $request, $taskId) { $linkIds = $request->input('linkIds'); $records = Link::query()->get()->groupBy('type'); if ($taskId) { $hasLinkIds = []; $task = LinkTask::query()->where(['id' => $taskId])->first(); if ($task) { $hasLinkIds = $task->links->pluck('id')->toArray(); } } else { $hasLinkIds = $linkIds ?? []; } $siteId = $request->input('siteId'); if ($siteId) { $linkHad = Link::query()->whereExists(function (\Illuminate\Database\Query\Builder $query) use ($siteId) { $query->select(DB::raw(1)) ->from('link_tasks_detail') ->whereRaw('links.id = link_tasks_detail.link_id and link_tasks_detail.redundant_site_id=' . $siteId); })->pluck('id')->toArray(); } return view('admin/link/chose', [ 'typeList' => Link::TYPES, 'typeLinks' => $records, 'hasLinkIds' => $hasLinkIds, 'task' => $task ?? null, 'linkHad' => $linkHad ?? [] ]); } //任务批量删除 public function batchTaskDelete(Request $request) { $ids = $request->input('ids'); if (!is_array($ids)) return response()->json(['message' => '删除时参数传递错误'], 422); LinkTask::destroy($ids); return response()->json(['message' => '操作成功']); } /** * 外链任务大厅 * @param Request $request * @return Factory|JsonResponse|View */ public function hall(Request $request) { if (!$request->ajax()) { return view('admin/link/hall', [ 'notice' => ArticleLinkNotice::query()->where(['type' => 'link'])->first() ]); } $builder = LinkTask::query()->with(['site', 'worker']); $status = $request->input('status'); if ($status != 6) { $condition[] = ['status', '=', $status]; } if ($status != 1) { $condition[] = ['worker_id', '=', Auth::id()]; } if ($keyword = $request->input('keyword')) { $condition[] = ['title', 'like', '%' . $keyword . '%']; } $builder->where($condition ?? []) ->where(function (Builder $b) { $b->where('release_at', '<', date('Y-m-d H:i:s'))->orWhereNull('release_at'); }); if ($status == 2) { $noticeGroupIds = LinkTask::query()->where(['worker_id' => Auth::id()]) ->where([ ['release_at', '<', date('Y-m-d H:i:s', strtotime('+2 day'))], ['release_at', '>', date('Y-m-d H:i:s')], ['status', '=', 1] ])->pluck('group_id')->toArray(); $noticeGroupIds = $noticeGroupIds ? $noticeGroupIds : [-1]; $raw = sprintf('(CASE WHEN group_id in (%s) THEN 1 ELSE 0 END) AS flag,link_tasks.*', implode(',', $noticeGroupIds)); $builder->selectRaw($raw)->orderByDesc('flag'); } if ($status == 6) { //筛选和用户相关的项目 $siteIds = DB::table('user_has_sites')->where('user_id', Auth::id())->pluck('site_id'); $builder->whereIn('site_id', $siteIds); } $tasks = $builder->orderByDesc('id') ->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $tasks->items(); array_walk($items, function ($item) { $item->status_title = $item->status_with_css; $item->site_title = $item->site->cn_title ?? ''; $item->worker_name = $item->worker->username ?? ''; }); return response()->json([ 'rows' => $items, 'total' => $tasks->total() ]); } //兼职外链导入 public function hallWorkerImport(Request $request) { set_time_limit(0); $taskId = $request->input('taskId'); if (!$request->input('excel_path')) { return response()->json(['message' => '请先上传excel文件'], 422); } if (!$taskId) { return response()->json(['message' => '参数错误'], 422); } $details = LinkTaskDetail::query()->where(['task_id' => $taskId])->get(); if ($details->isEmpty()) { return response()->json(['message' => '外链统计信息不存在'], 422); } try { Excel::import(new LinkHallWorker($taskId), $request->input('excel_path'), 'public'); } catch (\Throwable $throwable) { Log::error(var_export($throwable->getMessage(), 1)); return response()->json(['message' => '导入失败'], 400); } return response()->json(['message' => '操作成功']); } //兼职外链导出 public function hallWorkerExport(Request $request) { $taskId = $request->input('taskId'); $records = []; $details = LinkTaskDetail::query()->with(['urls', 'link'])->where(['task_id' => $taskId])->get(); $linkTypes = Link::TYPES; foreach ($details as $detail) { $showUrl = []; foreach ($detail->urls as $url) { $showUrl[] = $url->url; } $records[] = [ // 'link_type' => $detail->link_type, 'link_type' => $linkTypes[($detail->link->type ?? 0)] ?? '', // 'link_url' => $detail->link_url, 'link_url' => $detail->link->url ?? '', 'link_remark' => $detail->link->remark ?? '', 'username' => $detail->username, 'email' => $detail->email, 'password' => $detail->password, 'url' => $detail->url, 'show_url' => implode("\n", $showUrl), 'remark' => $detail->remark ]; } array_unshift($records, ['平台类型', '平台链接', '链接备注', '用户名', '注册邮箱', '密码', 'profile演示地址', '页面演示地址', '备注']); return (new LinkHallExport($records))->download(sprintf('兼职外链%s.xlsx', date('YmdHis')), \Maatwebsite\Excel\Excel::XLSX); } /*** * 外链任务认领 * @param $linkTaskId * @return \Illuminate\Http\JsonResponse */ public function linkTaskClaim($linkTaskId) { $record = LinkTask::query()->where(['id' => $linkTaskId])->first(); if (!$record) { return response()->json(['message' => '数据不存在'], 400); } if ($record->status != 1) { return response()->json(['message' => '该任务状态已被他人认领'], 400); } $record->status = 2; //任务中 $record->worker_id = Auth::id(); $record->save(); if (!empty($record->group_id)) { //查询是否是分组的 $groupLinkTaskList = LinkTask::query()->where(['group_id' => $record->group_id])->get(); //将分组中其他未认领的 也分配到当前用户 foreach ($groupLinkTaskList as $item) { if ($item->status == 1) { $item->status = 2; $item->worker_id = Auth::id(); $item->save(); } } } return response()->json(['message' => '操作成功']); } //释放任务 public function linkTaskRelease($linkTaskId) { $record = LinkTask::query()->where(['id' => $linkTaskId])->first(); if (!$record) { return response()->json(['message' => '数据不存在'], 400); } if (!in_array($record->status, [2, 4])) { return response()->json(['message' => '该任务状态已变化,任务释放失败'], 400); } //LinkTaskDetail::query()->where(['task_id'=>$record->id])->delete(); //删除之前人做的信息 $record->worker_id = 0; $record->status = 1;//待分配 $record->save(); return response()->json(['message' => '操作成功']); } /** * 项目信息展示 * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function hallShow($id) { $record = LinkTask::query()->with('site')->where(['id' => $id])->first(); if ($record) { $optimize_page_ids = json_decode($record->optimize_page_ids, true); $optimize_page_ids = is_array($optimize_page_ids) ? $optimize_page_ids : []; $optimizePageList = SiteOptimizePage::query()->whereIn('id', $optimize_page_ids)->get()->toArray(); } $condition = ['site_id' => $record->site_id ?? 0]; return view('admin/link/hall_show', [ 'data' => $record, 'keywordData' => SiteInfo::query()->where($condition)->first(), 'optimizePageList' => $optimizePageList ?? [], 'enterpriseData' => SiteEnterprise::query()->with('business')->where($condition)->first(), 'marketerData' => SiteMarketer::query()->where($condition)->first(), 'snsData' => SiteSns::query()->where($condition)->first(), 'businesses' => Business::all(), 'natures' => Site::NATURE_TYPE, 'link_remark' => LinkNote::query()->where($condition)->first(), 'business_license' => Site::query()->where('id', $record->site_id)->value('business_license_business_scope') ?? '' ]); } /** * 兼职人员保存页面渲染 * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View */ public function hallSave($id) { $record = LinkTask::query()->with('links')->where(['id' => $id])->first(); if (!$record) { return view('admin/errors/tips', [ 'tips' => '数据不存在' ]); } $linkTaskDetailIds = []; foreach ($record->links as $link) { $linkTaskDetailIds[] = $link->pivot->id; } $idMapUrls = LinkTaskUrl::query()->whereIn('link_tasks_detail_id', $linkTaskDetailIds) ->get()->groupBy('link_tasks_detail_id')->toArray(); return view('admin/link/hall_save', [ 'data' => $record, 'linkTypes' => Link::TYPES, 'idMapUrls' => $idMapUrls ?? [] ]); } /** * 兼职人员保存 * @param WorkerSaveRequest $request * @param $id * @return \Illuminate\Http\JsonResponse */ public function workerSave(WorkerSaveRequest $request, $id) { $record = LinkTaskDetail::query()->where(['id' => $id])->first(); if (!$record) return response()->json(['message' => '数据不存在'], 422); $validated = $request->validated(); $record->update($validated['link_tasks_detail']); return $this->logic->syncLinkTasksUrl($validated['link_tasks_url']['show_urls'] ?? [], $record->id); } /** * 用户提交审核 * @param $id * @return \Illuminate\Http\JsonResponse */ public function submitAudit($id) { $record = LinkTask::query()->where(['id' => $id])->first(); if (!$record) { return response()->json(['message' => '数据不存在'], 422); } if (!in_array($record->status, [2, 4])) { return response()->json(['message' => '只有待审核与审核失败才可提交审核'], 400); } $detailRecords = LinkTaskDetail::query()->where(['task_id' => $record->id])->get(); foreach ($detailRecords as $detailRecord) { if (empty($detailRecord->url)) { return response()->json(['message' => '请先完善信息'], 400); } } $record->status = 3; //初次审核时间 if (empty($record->first_audit_at)) { $record->first_audit_at = date('Y-m-d H:i:s'); } $record->save(); return response()->json(['message' => '操作成功']); } /** * 404检测 * @param $taskId * @return \Illuminate\Http\JsonResponse */ public function check404($taskId) { $detailIds = LinkTaskDetail::query()->where(['task_id' => $taskId])->pluck('id'); $taskUrls = LinkTaskUrl::query()->whereIn('link_tasks_detail_id', $detailIds)->get(); $client = new Client([ 'verify' => false, 'timeout' => 10 ]); //并发请求链接地址 $requests = function () use ($client, $taskUrls) { foreach ($taskUrls as $item) { if (empty($item->url)) continue; yield new \GuzzleHttp\Psr7\Request('GET', $item->url); } }; $result = []; $pool = new Pool($client, $requests(), [ 'concurrency' => 5, //同时并发抓取几个 'fulfilled' => function (Response $response, $index) use (&$result) { $result[$index] = 5; //成功 }, 'rejected' => function (\Throwable $throwable, $index) use (&$result) { $result[$index] = 4; //失败的 }, ]); $promise = $pool->promise(); $promise->wait(); foreach ($taskUrls as $key => &$item) { $item->valid_status = $result[$key]; $item->save(); } return response()->json(['message' => '操作成功']); } //更新任务url public function updateTaskUrl(Request $request, $urlId) { $url = $request->input('url'); LinkTaskUrl::query()->where(['id' => $urlId])->update(['url' => $url]); return response()->json(['message' => '操作成功']); } /** * 项目详情外链任务页面渲染 * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function taskIndexForSite($id) { return view('admin/link/task_for_site', [ 'siteId' => $id ]); } /** * 链接审核通过 * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function urlPass(Request $request) { $urlIds = $request->input('urlIds'); $taskDetailId = LinkTaskUrl::query()->whereIn('id', $urlIds)->pluck('link_tasks_detail_id'); $taskId = LinkTaskDetail::query()->whereIn('id', $taskDetailId)->pluck('task_id'); $linkReviewDate = LinkTask::query()->whereIn('id', $taskId)->first(); LinkTaskUrl::query()->whereIn('id', $urlIds)->update([ 'audit_at' => date('Y-m-d H:i:s'), 'status' => 5, 'audit_reason' => '', 'created_at' => $linkReviewDate->link_review_at ?? date('Y-m-d H:i:s'), ]); return response()->json(['message' => '操作成功']); } /** * 链接审核不通过 * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function urlPassFail(Request $request) { LinkTaskUrl::query()->whereIn('id', $request->input('urlIds'))->update([ 'audit_at' => date('Y-m-d H:i:s'), 'status' => 4, 'audit_reason' => $request->input('audit_reason') ]); return response()->json(['message' => '操作成功']); } /** * 外链任务详情 * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function taskDetail($id) { $record = LinkTask::query()->with(['site', 'worker', 'links'])->where(['id' => $id])->first(); $linkTaskDetailIds = []; foreach ($record->links as $link) { $linkTaskDetailIds[] = $link->pivot->id; } $taskUrls = LinkTaskUrl::query()->whereIn('link_tasks_detail_id', $linkTaskDetailIds) ->get(); $idMapUrls = $taskUrls->groupBy('link_tasks_detail_id')->toArray(); return view('admin/link/task_detail_for_site', [ 'data' => $record, 'idMapUrls' => $idMapUrls, 'taskUrls' => $taskUrls, 'taskScore' => LinkTaskScore::query()->where(['task_id' => $id])->first() ]); } /** * 外链任务审核通过 * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function taskPass(Request $request) { $task = LinkTask::query()->where(['status' => 3, 'id' => $request->input('taskId')])->first(); if (!$task) { return response()->json(['message' => '该任务不处于待审核状态或不存在'], 400); } $taskDetailRecords = LinkTaskDetail::query()->with(['urls', 'link'])->where(['task_id' => $task->id])->get(); foreach ($taskDetailRecords as $detailRecord) { foreach ($detailRecord->urls as $item) { if ($item->status == 3) { return response()->json(['message' => '请先审核完演示地址'], 400); } } } $task->update(['status' => 5, 'audit_at' => date('Y-m-d H:i:s')]); LinkTaskDetail::query()->where(['task_id' => $task->id])->update(['status' => 5]); return response()->json(['message' => '操作成功']); } /** * 外链任务审核失败 * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function taskPassFail(Request $request) { $task = LinkTask::query()->where(['status' => 3, 'id' => $request->input('taskId')])->first(); if (!$task) { return response()->json(['message' => '该任务不处于待审核状态或不存在'], 400); } $taskDetailRecords = LinkTaskDetail::query()->with(['urls'])->where(['task_id' => $task->id])->get(); foreach ($taskDetailRecords as $detailRecord) { foreach ($detailRecord->urls as $item) { if ($item->status == 3) { return response()->json(['message' => '请先审核完演示地址'], 400); } } } $task->update(['status' => 4, 'audit_at' => date('Y-m-d H:i:s'), 'audit_reason' => $request->input('audit_reason')]); LinkTaskDetail::query()->where(['task_id' => $task->id])->update(['status' => 4]); return response()->json(['message' => '操作成功']); } /** * 任务结算列表 * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View */ public function calc(Request $request) { if (!$request->ajax()) { return view('admin/link/calc'); } // 注意 group_concat长度限制 $records = $this->logic->calcFilter($request->input())//查询已审核的并按照兼职人员分组 ->where(['status' => 5])->selectRaw('worker_id,GROUP_CONCAT(id) as task_ids') ->groupBy('worker_id')->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); //一次性注册任务每条演示地址记为2条计算、书签每条记为0.5条 //我也不想foreach套sql 计划赶不上变化 $result = []; foreach ($items as $inx => $item) { $taskIds = explode(',', $item->task_ids); $taskDetailList = LinkTaskDetail::query()->select(['link_type', 'id'])->whereIn('task_id', $taskIds)->where(['status' => 5])->get(); $taskScoreList = LinkTaskScore::query()->whereIn('task_id', $taskIds)->get(); $totalScore = 0; foreach ($taskScoreList as $taskScore) { $totalScore += intval($taskScore->total); } //质量平均分 if ($taskScoreList->count() > 0) { $avgScore = $totalScore / $taskScoreList->count(); } else { $avgScore = 0; } $once = []; $bookmark = []; $other = []; foreach ($taskDetailList as $detailItem) { if ($detailItem->link_type == "一次性") { $once[] = $detailItem->id; } elseif ($detailItem->link_type == "书签") { $bookmark[] = $detailItem->id; } else { $other[] = $detailItem->id; } } $onceNum = LinkTaskUrl::query()->whereIn('link_tasks_detail_id', $once)->where(['status' => 5])->count(); $bookmarkNum = LinkTaskUrl::query()->whereIn('link_tasks_detail_id', $bookmark)->where(['status' => 5])->count(); $otherNum = LinkTaskUrl::query()->whereIn('link_tasks_detail_id', $other)->where(['status' => 5])->count(); $urlNum = $onceNum * 2 + $bookmarkNum * 0.5 + $otherNum; $result[$inx]['url_num'] = $urlNum; $result[$inx]['amount'] = $urlNum; $result[$inx]['username'] = $item->worker->username ?? ''; $result[$inx]['user_id'] = $item->worker->id ?? ''; $result[$inx]['avgScore'] = round($avgScore, 2); $result[$inx]['task_ids'] = $taskIds; } return response()->json([ 'rows' => array_values($result), 'total' => $records->total() ]); } //结算历史 public function calcHistory(Request $request) { $user = Auth::user(); // $filters[] = ['status', '=', 6]; if (empty($user->is_super)) { $filters[] = ['user_id', '=', Auth::id()]; } if (!$request->ajax()) { // $taskUrlCount = LinkTask::query()->with(['worker'])->where($filters)->sum('settle_amount'); return view('/admin/link/calc_history', [ // 'totalAmount' => $taskUrlCount * 1 ]); } $inputs = $request->input(); if (!empty($inputs['keyword'])) { $filters[] = ['username', 'like', '%' . $request->input('keyword') . '%']; } !empty($inputs['start_at']) && $filters[] = ['audit_at', '>=', $inputs['start_at']]; !empty($inputs['end_at']) && $filters[] = ['audit_at', '<=', $inputs['end_at']]; $records = LinkCalc::query()->where($filters ?? [])->paginate($request->input('pageSize') ?? TABLE_PAGE_SIZE); $items = $records->items(); $result = []; $totalAmount = 0; $totalLinkNum = 0; foreach ($items as $key => $item) { $result[$key]['amount'] = $item->amount; $result[$key]['link_num'] = $item->url_num; $result[$key]['username'] = $item->username; $result[$key]['settle_at'] = $item->settle_at; $totalAmount = bcadd($totalAmount, intval($item->settle_amount), 2); $totalLinkNum += intval($item->url_num); } return response()->json([ 'rows' => array_values($result), 'total' => $records->total(), 'totalAmount' => $totalAmount, 'totalLinkNum' => $totalLinkNum ]); } /** * 任务结算 * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function settle(Request $request) { $dataList = $request->input('dataList'); foreach ($dataList as $data) { LinkTask::query()->whereIn('id', $data['task_ids'])->update([ 'status' => 6 ]); LinkCalc::query()->create([ 'user_id' => $data['user_id'], 'username' => $data['username'], 'task_ids' => json_encode($data['task_ids']), 'amount' => $data['amount'], 'url_num' => $data['url_num'], 'settle_at' => date('Y-m-d H:i:s') ]); } return response()->json(['message' => '操作成功']); } //导入外链 public function linkImport(Request $request, $siteId) { set_time_limit(0); if (!$request->input('excel_path')) { return response()->json(['message' => '请先上传excel文件'], 422); } try { Excel::import(new LinkImport($siteId), $request->input('excel_path'), 'public'); } catch (\Throwable $throwable) { Log::error(var_export($throwable->getMessage(), 1)); return response()->json(['message' => '导入失败'], 400); } return response()->json(['message' => '操作成功']); } //任务评分 public function taskScore(TaskScoreRequest $request, $taskId) { $validated = $request->validated(); $taskScore = LinkTaskScore::query()->where(['task_id' => $taskId])->first(); if ($taskScore) { $taskScore->update($validated); } else { $validated['task_id'] = $taskId; LinkTaskScore::query()->create($validated); } return response()->json(['message' => '操作成功']); } //外链备注 public function siteLinkNote(Request $request, $siteId) { if (!$request->ajax()) { $note = LinkNote::query()->where(['site_id' => $siteId])->first(); return view('admin.link.note', [ 'siteId' => $siteId, 'data' => $note, ]); } $content = $request->input('content'); $note = LinkNote::query()->where(['site_id' => $siteId])->first(); if ($note) { $note->update(['content' => $content]); } else { LinkNote::query()->create([ 'site_id' => $siteId, 'content' => $content, ]); } return response()->json(['message' => '操作成功']); } public function externalChainLibraryImport(Request $request) { set_time_limit(0); if (!$request->input('excel_path')) { return response()->json(['message' => '请先上传excel文件'], 422); } try { Excel::import(new ExternalChainLibraryImport(), $request->input('excel_path'), 'public'); } catch (\Throwable $throwable) { Log::error(var_export($throwable->getMessage(), 1)); return response()->json(['message' => '导入失败'], 400); } return response()->json(['message' => '操作成功']); } public function externalChainLibraryExport(Request $request) { $link = Link::query(); $request = $request->all(); if (!empty($request['type'])) { $link->where('type', $request['type']); } if (!empty($request['business_ids'])) { $link->whereRaw('FIND_IN_SET(?,business_ids)', [$request['business_ids']]); } if (!empty($request['keyword'])) { $link->where('url', 'like', '%' . $request['keyword'] . '%'); } $businesses = Business::query()->pluck('title', 'id'); $data = []; $list = $link->orderBy('id', 'desc')->get(); $type = [0 => '否', 1 => '是']; foreach ($list as $value) { $value->bigBall = $type[$value->big_ball] ?? ''; $business = explode(',', $value->business_ids); $list = []; foreach ($business as $item) { $list[] = $businesses[$item] ?? ''; } if (!empty($list)) { $value->business = implode(',', $list); } else { $value->business = ''; } $data[] = [ 'typeTitle' => Link::TYPES[$value->type] ?? '', 'tag' => $value->tag, 'url' => $value->url, 'business' => $value->business, 'authority_score' => $value->authority_score, 'spam_score' => $value->spam_score, 'bigBall' => $value->bigBall, 'remark' => $value->remark, 'created_at' => $value->created_at, ]; } array_unshift($data, ['外链类型', '标签', '平台链接', '行业', 'Authority Score', 'Spam Score', '锚文本', '备注', '创建时间']); return (new BasicExport($data))->download(sprintf('外链列表%s.xls', date('YmdHis'))); } }