550 lines
16 KiB
PHP
550 lines
16 KiB
PHP
@extends('layouts.site')
|
|
|
|
@section('page_class', 'page-tools page-detail')
|
|
@section('title', $item->seo_title ?: $item->name.' - AI工具详情')
|
|
@section('meta_description', $item->seo_description ?: $item->summary)
|
|
@section('canonical', $item->canonical_url ?: route('tools.show', $item->slug))
|
|
|
|
@section('head')
|
|
<style>
|
|
.tool-show-shell {
|
|
display: grid;
|
|
grid-template-columns: 210px minmax(0, 1fr) 320px;
|
|
gap: var(--page-section-gap);
|
|
align-items: start;
|
|
}
|
|
|
|
.tool-show-left,
|
|
.tool-show-right {
|
|
position: sticky;
|
|
top: 84px;
|
|
align-self: start;
|
|
}
|
|
|
|
.tool-show-nav {
|
|
border: 1px solid var(--line);
|
|
border-radius: 12px;
|
|
background: var(--bg-surface);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: .62rem .54rem;
|
|
display: grid;
|
|
gap: .3rem;
|
|
}
|
|
|
|
.tool-show-nav-title {
|
|
margin: 0;
|
|
padding: .1rem .24rem .45rem;
|
|
border-bottom: 1px solid var(--line);
|
|
color: var(--text-muted);
|
|
font-size: .76rem;
|
|
letter-spacing: .06em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.tool-show-nav-link {
|
|
display: grid;
|
|
grid-template-columns: 1rem minmax(0, 1fr);
|
|
gap: .44rem;
|
|
align-items: center;
|
|
border: 1px solid transparent;
|
|
border-radius: .6rem;
|
|
padding: .42rem .46rem;
|
|
color: #4e6288;
|
|
text-decoration: none;
|
|
font-size: .82rem;
|
|
transition: .16s ease;
|
|
}
|
|
|
|
.tool-show-nav-link:hover {
|
|
border-color: var(--line-strong);
|
|
background: var(--brand-soft);
|
|
color: #223b67;
|
|
}
|
|
|
|
.tool-show-nav-link i {
|
|
color: #6f83aa;
|
|
text-align: center;
|
|
font-size: .82rem;
|
|
}
|
|
|
|
.tool-main {
|
|
min-width: 0;
|
|
}
|
|
|
|
.tool-hero {
|
|
border: 1px solid var(--line);
|
|
border-radius: 12px;
|
|
background:
|
|
linear-gradient(160deg, color-mix(in srgb, #eff4ff 88%, #fff) 0, color-mix(in srgb, #f6f9ff 86%, #fff) 100%);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: .98rem;
|
|
margin-bottom: .72rem;
|
|
}
|
|
|
|
.tool-hero-inner {
|
|
display: grid;
|
|
grid-template-columns: 108px minmax(0, 1fr) auto;
|
|
gap: .88rem;
|
|
align-items: start;
|
|
}
|
|
|
|
.tool-logo {
|
|
width: 108px;
|
|
height: 108px;
|
|
border-radius: 14px;
|
|
border: 1px solid var(--line);
|
|
background: #fff;
|
|
box-shadow: 0 10px 22px rgba(28, 48, 93, .1);
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.tool-logo img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.tool-logo-fallback {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-family: "Outfit", "Noto Sans SC", sans-serif;
|
|
font-size: 1.6rem;
|
|
font-weight: 800;
|
|
color: #405c94;
|
|
background: linear-gradient(160deg, #eef3ff 0, #e2ebff 100%);
|
|
}
|
|
|
|
.tool-name {
|
|
margin: .08rem 0 .28rem;
|
|
font-family: "Outfit", "Noto Sans SC", sans-serif;
|
|
font-size: clamp(1.55rem, 2.8vw, 2.1rem);
|
|
font-weight: 800;
|
|
letter-spacing: .01em;
|
|
line-height: 1.2;
|
|
color: #1d2f52;
|
|
}
|
|
|
|
.tool-summary {
|
|
margin: 0;
|
|
color: #53678f;
|
|
font-size: .96rem;
|
|
line-height: 1.75;
|
|
}
|
|
|
|
.tool-meta-chips {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: .44rem;
|
|
margin-bottom: .4rem;
|
|
}
|
|
|
|
.tool-meta-chips span {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: .28rem;
|
|
border: 1px solid color-mix(in srgb, var(--line) 92%, #fff);
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, .86);
|
|
padding: .14rem .56rem;
|
|
color: #64799f;
|
|
font-size: .74rem;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.tool-hero-actions {
|
|
min-width: 168px;
|
|
display: grid;
|
|
gap: .44rem;
|
|
}
|
|
|
|
.tool-hero-actions .btn {
|
|
border-radius: 999px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tool-card {
|
|
border: 1px solid var(--line);
|
|
border-radius: 12px;
|
|
background: var(--bg-surface);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: .96rem;
|
|
margin-bottom: .72rem;
|
|
}
|
|
|
|
.tool-card-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: .5rem;
|
|
margin-bottom: .56rem;
|
|
}
|
|
|
|
.tool-card-title {
|
|
margin: 0;
|
|
font-family: "Outfit", "Noto Sans SC", sans-serif;
|
|
font-size: .98rem;
|
|
font-weight: 700;
|
|
color: #2b4068;
|
|
}
|
|
|
|
.tool-card-sub {
|
|
color: #7a8db0;
|
|
font-size: .78rem;
|
|
}
|
|
|
|
.tool-capability-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
gap: .48rem;
|
|
}
|
|
|
|
.tool-capability-item {
|
|
border: 1px solid color-mix(in srgb, var(--line) 90%, #fff);
|
|
border-radius: .74rem;
|
|
background: color-mix(in srgb, var(--bg-soft) 70%, #fff);
|
|
padding: .5rem .56rem;
|
|
color: #556a92;
|
|
font-size: .82rem;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.tool-scenario-list {
|
|
margin: 0;
|
|
padding-left: 1.15rem;
|
|
color: #314a74;
|
|
line-height: 1.82;
|
|
font-size: .95rem;
|
|
}
|
|
|
|
.tool-scenario-list li + li {
|
|
margin-top: .3rem;
|
|
}
|
|
|
|
.tool-related-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: .56rem;
|
|
}
|
|
|
|
.tool-related-item {
|
|
border: 1px solid var(--line);
|
|
border-radius: .78rem;
|
|
background: #fff;
|
|
padding: .66rem .7rem;
|
|
transition: .16s ease;
|
|
}
|
|
|
|
.tool-related-item:hover {
|
|
transform: translateY(-2px);
|
|
border-color: color-mix(in srgb, var(--brand) 35%, var(--line));
|
|
box-shadow: 0 10px 20px rgba(29, 53, 116, .1);
|
|
}
|
|
|
|
.tool-related-item a {
|
|
color: #23406e;
|
|
text-decoration: none;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.tool-related-item p {
|
|
margin: .34rem 0 .42rem;
|
|
color: #687d9f;
|
|
font-size: .82rem;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.tool-right-card {
|
|
border: 1px solid var(--line);
|
|
border-radius: 12px;
|
|
background: var(--bg-surface);
|
|
box-shadow: var(--shadow-sm);
|
|
padding: .8rem .82rem;
|
|
margin-bottom: .62rem;
|
|
}
|
|
|
|
.tool-right-title {
|
|
margin: 0 0 .48rem;
|
|
font-family: "Outfit", "Noto Sans SC", sans-serif;
|
|
font-size: .92rem;
|
|
font-weight: 700;
|
|
color: #2a426d;
|
|
}
|
|
|
|
.tool-info-list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
font-size: .82rem;
|
|
}
|
|
|
|
.tool-info-list li {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: .5rem;
|
|
padding: .34rem 0;
|
|
border-bottom: 1px dashed var(--line);
|
|
color: #5e739a;
|
|
}
|
|
|
|
.tool-info-list li:last-child {
|
|
border-bottom: 0;
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.tool-info-list strong {
|
|
color: #22395f;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.tool-right-list {
|
|
display: grid;
|
|
gap: .42rem;
|
|
}
|
|
|
|
.tool-right-list article {
|
|
border: 1px solid var(--line);
|
|
border-radius: .7rem;
|
|
background: #fff;
|
|
padding: .5rem .56rem;
|
|
}
|
|
|
|
.tool-right-list a {
|
|
color: #2a4270;
|
|
text-decoration: none;
|
|
font-size: .84rem;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.tool-right-list div {
|
|
margin-top: .18rem;
|
|
color: #7a8eb0;
|
|
font-size: .74rem;
|
|
}
|
|
|
|
@media (max-width: 1280px) {
|
|
.tool-show-shell {
|
|
grid-template-columns: 190px minmax(0, 1fr) 290px;
|
|
}
|
|
|
|
.tool-capability-grid {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (max-width: 991.98px) {
|
|
.tool-show-shell {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.tool-show-left,
|
|
.tool-show-right {
|
|
position: static;
|
|
}
|
|
|
|
.tool-show-nav {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.tool-show-nav-title {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.tool-hero-inner {
|
|
grid-template-columns: 90px minmax(0, 1fr);
|
|
}
|
|
|
|
.tool-logo {
|
|
width: 90px;
|
|
height: 90px;
|
|
}
|
|
|
|
.tool-hero-actions {
|
|
grid-column: 1 / -1;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (max-width: 575.98px) {
|
|
.tool-show-nav {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.tool-hero-inner {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.tool-logo {
|
|
width: 76px;
|
|
height: 76px;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.tool-hero-actions {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.tool-related-grid,
|
|
.tool-capability-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
<script type="application/ld+json">
|
|
{!! json_encode([
|
|
'@context' => 'https://schema.org',
|
|
'@type' => 'SoftwareApplication',
|
|
'name' => $item->name,
|
|
'description' => $item->summary,
|
|
'url' => $item->official_url,
|
|
'applicationCategory' => $item->category?->name,
|
|
], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT) !!}
|
|
</script>
|
|
@endsection
|
|
|
|
@section('content')
|
|
@php
|
|
$name = trim((string) ($item->h1 ?: $item->name));
|
|
$logoText = mb_strtoupper(mb_substr($item->name ?: 'AI', 0, 2));
|
|
@endphp
|
|
|
|
@if($showRiskNotice)
|
|
<div class="alert alert-warning mb-2" role="alert">
|
|
免责声明:涉及医疗、法律、投资等高风险场景的内容仅供学习参考,不构成专业建议。
|
|
</div>
|
|
@endif
|
|
|
|
<div class="tool-show-shell">
|
|
<aside class="tool-show-left" aria-label="页面目录">
|
|
<nav class="tool-show-nav">
|
|
<p class="tool-show-nav-title">Tool Detail</p>
|
|
<a class="tool-show-nav-link" href="#overview"><i class="bi bi-grid-1x2"></i><span>概览</span></a>
|
|
<a class="tool-show-nav-link" href="#details"><i class="bi bi-file-text"></i><span>详细介绍</span></a>
|
|
<a class="tool-show-nav-link" href="#highlights"><i class="bi bi-stars"></i><span>功能亮点</span></a>
|
|
<!-- <a class="tool-show-nav-link" href="#scenarios"><i class="bi bi-check2-square"></i><span>适用建议</span></a> -->
|
|
@if($relatedTools->isNotEmpty())
|
|
<a class="tool-show-nav-link" href="#related"><i class="bi bi-diagram-3"></i><span>同类推荐</span></a>
|
|
@endif
|
|
</nav>
|
|
</aside>
|
|
|
|
<main class="tool-main">
|
|
<section class="tool-hero" id="overview">
|
|
<div class="tool-hero-inner">
|
|
<div class="tool-logo">
|
|
@if(!empty($item->logo_url))
|
|
<img src="{{ $item->logo_url }}" alt="{{ $item->name }} Logo" loading="lazy">
|
|
@else
|
|
<span class="tool-logo-fallback">{{ $logoText }}</span>
|
|
@endif
|
|
</div>
|
|
|
|
<div>
|
|
<div class="tool-meta-chips">
|
|
<span><i class="bi bi-grid"></i>{{ $item->category?->name ?? 'AI 工具' }}</span>
|
|
<span><i class="bi bi-wallet2"></i>{{ $item->pricing_type }}</span>
|
|
<span><i class="bi bi-plug"></i>{{ $item->has_api ? '支持 API' : '无 API' }}</span>
|
|
<span><i class="bi bi-shield-check"></i>{{ $item->source_level?->label() ?? '未知来源' }}</span>
|
|
</div>
|
|
<h1 class="tool-name">{{ $name }}</h1>
|
|
<p class="tool-summary">{{ $item->summary }}</p>
|
|
</div>
|
|
|
|
<div class="tool-hero-actions">
|
|
<a class="btn btn-primary" href="{{ $item->official_url }}" target="_blank" rel="nofollow noopener">访问官网</a>
|
|
@if($item->alternative)
|
|
<a class="btn btn-outline-primary" href="{{ route('tools.show', $item->alternative->slug) }}">查看替代工具</a>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="tool-card" id="details">
|
|
<div class="tool-card-head">
|
|
<h2 class="tool-card-title">工具详细介绍</h2>
|
|
<span class="tool-card-sub">更新于 {{ $item->updated_at?->format('Y-m-d') ?? '-' }}</span>
|
|
</div>
|
|
<div class="md-content detail-content">
|
|
@if(trim((string) $item->description) !== '')
|
|
{!! $descriptionHtml !!}
|
|
@else
|
|
<p>{{ $item->summary }}</p>
|
|
@endif
|
|
</div>
|
|
</section>
|
|
|
|
<section class="tool-card" id="highlights">
|
|
<div class="tool-card-head">
|
|
<h2 class="tool-card-title">功能亮点</h2>
|
|
<span class="tool-card-sub">基于内容自动提取</span>
|
|
</div>
|
|
@if(!empty($capabilityTags))
|
|
<div class="tool-capability-grid">
|
|
@foreach($capabilityTags as $tag)
|
|
<div class="tool-capability-item">{{ $tag }}</div>
|
|
@endforeach
|
|
</div>
|
|
@else
|
|
<p class="text-muted-soft small mb-0">暂无可展示的功能标签。</p>
|
|
@endif
|
|
</section>
|
|
|
|
|
|
|
|
@if($relatedTools->isNotEmpty())
|
|
<section class="tool-card mb-0" id="related">
|
|
<div class="tool-card-head">
|
|
<h2 class="tool-card-title">同类工具推荐</h2>
|
|
<span class="tool-card-sub">按最近发布排序</span>
|
|
</div>
|
|
<div class="tool-related-grid">
|
|
@foreach($relatedTools as $tool)
|
|
<article class="tool-related-item">
|
|
<a href="{{ route('tools.show', $tool->slug) }}">{{ $tool->name }}</a>
|
|
<p class="line-clamp-2">{{ $tool->summary }}</p>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<span class="chip">{{ $tool->pricing_type }}</span>
|
|
<span class="chip">{{ $tool->has_api ? 'API' : 'No API' }}</span>
|
|
</div>
|
|
</article>
|
|
@endforeach
|
|
</div>
|
|
</section>
|
|
@endif
|
|
</main>
|
|
|
|
<aside class="tool-show-right">
|
|
<section class="tool-right-card">
|
|
<h3 class="tool-right-title">基础信息</h3>
|
|
<ul class="tool-info-list">
|
|
<li><span>价格模式</span><strong>{{ $item->pricing_type }}</strong></li>
|
|
<li><span>API 支持</span><strong>{{ $item->has_api ? '支持' : '不支持' }}</strong></li>
|
|
<li><span>适用平台</span><strong>{{ $item->platform ?: '未提供' }}</strong></li>
|
|
<li><span>支持语言</span><strong>{{ $item->language ?: '未提供' }}</strong></li>
|
|
<li><span>最后校验</span><strong>{{ $item->last_verified_at?->format('Y-m-d') ?? '未记录' }}</strong></li>
|
|
<li><span>状态</span><strong>{{ $item->is_stale ? '可能过期' : '有效' }}</strong></li>
|
|
</ul>
|
|
</section>
|
|
|
|
@if($latestTools->isNotEmpty())
|
|
<section class="tool-right-card">
|
|
<h3 class="tool-right-title">最新收录</h3>
|
|
<div class="tool-right-list">
|
|
@foreach($latestTools->take(6) as $tool)
|
|
<article>
|
|
<a href="{{ route('tools.show', $tool->slug) }}">{{ $tool->name }}</a>
|
|
<div>{{ $tool->category?->name ?? '未分类' }}</div>
|
|
</article>
|
|
@endforeach
|
|
</div>
|
|
</section>
|
|
@endif
|
|
</aside>
|
|
</div>
|
|
@endsection
|