初始化
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
{{-- 说明:以下文案为示例(以本项目身份「深圳市云创芯电子有限公司 / CloudChip」填充)。
|
||||
替换为贵司真实信息即可,公司名同时可在后台 Setting(site_name)或 .env 的 APP_NAME 调整。 --}}
|
||||
|
||||
@section('title', '关于我们 - ' . App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'))
|
||||
@section('description', '了解深圳市云创芯电子有限公司(TypeC 产品顾问):专注多口 TypeC 接口 IC 与快充协议芯片的设计、量产与技术支持。')
|
||||
|
||||
@section('content')
|
||||
{{-- Hero:简约大气,大量留白 + 单一主色 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 pt-14 lg:pt-20 pb-6">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<p class="text-sm font-medium tracking-wide text-primary">关于我们</p>
|
||||
<h1 class="mt-3 max-w-3xl text-3xl font-bold leading-tight tracking-tight text-fg sm:text-4xl lg:text-5xl">
|
||||
以芯片之力,连接更高效的充电世界
|
||||
</h1>
|
||||
<p class="mt-5 max-w-2xl text-base text-muted lg:text-lg">
|
||||
深圳市云创芯电子有限公司(TypeC 产品顾问)是一家专注于接口控制与电源管理芯片的半导体方案商,致力于为充电与外设厂商提供稳定、易集成、可量产的芯片与技术服务。
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 公司简介 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-3">
|
||||
<div class="lg:col-span-1">
|
||||
<h2 class="text-xl font-bold tracking-tight text-fg">公司简介</h2>
|
||||
<p class="mt-3 text-sm text-muted">我们是谁,以及我们坚持的事。</p>
|
||||
</div>
|
||||
<div class="lg:col-span-2 space-y-4 text-[15px] leading-7 text-fg/90">
|
||||
<p>
|
||||
深圳市云创芯电子有限公司(CloudChip)成立于专注电源与接口协议的芯片赛道,核心团队来自芯片设计、协议栈与量产工程领域。我们围绕多口 PD 电源及其信号智能控制、协议转换与同步整流等关键环节,提供从选型、评估到量产导入的全流程支持。
|
||||
</p>
|
||||
<p>
|
||||
我们相信,一颗好芯片的价值不止于参数,更在于能否被工程师轻松集成、在产线上稳定出货。因此,我们把「易用性」与「可靠性」放在与性能同等重要的位置,并以完善的文档、参考设计与技术支持降低客户的研发门槛。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 核心能力 --}}
|
||||
<section class="border-t border-line bg-surface px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="max-w-2xl">
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">核心能力</h2>
|
||||
<p class="mt-2 text-sm text-muted">覆盖芯片设计、协议支持、量产与服务的完整闭环。</p>
|
||||
</div>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-card">
|
||||
<span class="inline-flex h-11 w-11 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="box" :size="24" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">芯片设计</h3>
|
||||
<p class="mt-2 text-sm text-muted">自研接口与电源管理 IP,覆盖多口 PD 电源及其信号智能控制与同步整流。</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-card">
|
||||
<span class="inline-flex h-11 w-11 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="book" :size="24" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">协议栈</h3>
|
||||
<p class="mt-2 text-sm text-muted">支持 PD3.X / PPS / SPRS 等快充协议,提供完整参考设计。</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-card">
|
||||
<span class="inline-flex h-11 w-11 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="check" :size="24" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">量产交付</h3>
|
||||
<p class="mt-2 text-sm text-muted">面向充电与外设厂商出货,建立稳定的质量与供货体系。</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-card">
|
||||
<span class="inline-flex h-11 w-11 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="chat" :size="24" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">技术支持</h3>
|
||||
<p class="mt-2 text-sm text-muted">应用工程师协助方案评估、调试与量产导入。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 发展历程 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">发展历程</h2>
|
||||
<p class="mt-2 text-sm text-muted">关键节点的持续积累。</p>
|
||||
<ol class="mt-8 space-y-6 border-l-2 border-line pl-6">
|
||||
<li>
|
||||
<p class="text-sm font-semibold text-primary">起步</p>
|
||||
<p class="mt-1 text-[15px] text-fg/90">聚焦多口 TypeC 接口 IC,完成首颗协议转换芯片流片与验证。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p class="text-sm font-semibold text-primary">产品化</p>
|
||||
<p class="mt-1 text-[15px] text-fg/90">建立完整选型矩阵与参考设计,进入充电与外设客户量产导入。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p class="text-sm font-semibold text-primary">平台化</p>
|
||||
<p class="mt-1 text-[15px] text-fg/90">搭建技术文档、术语库与论坛,形成面向工程师的开放支持体系。</p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 资质与价值观 --}}
|
||||
<section class="border-t border-line bg-surface px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">资质与合规</h2>
|
||||
<ul class="mt-6 space-y-3 text-[15px] text-fg/90">
|
||||
<li class="flex items-start gap-3"><x-icon name="check" :size="20" class="mt-0.5 shrink-0 text-primary" /><span>产品通过相关可靠性与环境测试,满足量产导入要求。</span></li>
|
||||
<li class="flex items-start gap-3"><x-icon name="check" :size="20" class="mt-0.5 shrink-0 text-primary" /><span>完整的文档、规格书与参考设计交付体系。</span></li>
|
||||
<li class="flex items-start gap-3"><x-icon name="check" :size="20" class="mt-0.5 shrink-0 text-primary" /><span>规范的供应链与质量管控流程。</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">我们的价值观</h2>
|
||||
<div class="mt-6 grid gap-4 sm:grid-cols-2">
|
||||
<div class="rounded-xl border border-line bg-surface p-5 shadow-card">
|
||||
<h3 class="font-semibold text-fg">可靠优先</h3>
|
||||
<p class="mt-1 text-sm text-muted">把稳定性放在第一位,让客户用得安心。</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-line bg-surface p-5 shadow-card">
|
||||
<h3 class="font-semibold text-fg">工程师视角</h3>
|
||||
<p class="mt-1 text-sm text-muted">从集成与调试的真实痛点出发做产品。</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-line bg-surface p-5 shadow-card">
|
||||
<h3 class="font-semibold text-fg">开放协作</h3>
|
||||
<p class="mt-1 text-sm text-muted">以文档与社区降低技术门槛。</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-line bg-surface p-5 shadow-card">
|
||||
<h3 class="font-semibold text-fg">长期主义</h3>
|
||||
<p class="mt-1 text-sm text-muted">与客户共同成长,而非一锤子买卖。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- CTA --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 pb-16">
|
||||
<div class="max-w-8xl mx-auto rounded-2xl bg-primary px-6 py-10 text-center sm:px-10">
|
||||
<h2 class="text-xl font-bold tracking-tight text-white sm:text-2xl">想了解我们的芯片与方案?</h2>
|
||||
<p class="mt-2 text-sm text-white/85">无论是选型、样品还是技术合作,我们都乐于沟通。</p>
|
||||
<a href="{{ url('/contact') }}" class="mt-6 inline-flex items-center gap-2 rounded-lg bg-surface px-6 py-3 text-sm font-semibold text-primary transition hover:bg-surface/90">
|
||||
联系我们 <x-icon name="arrow" :size="18" />
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,84 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php $editing = isset($article) && $article; @endphp
|
||||
|
||||
@section('title', $editing ? '编辑文章' : '新建文章')
|
||||
@section('page-title', $editing ? '编辑文章' : '新建文章')
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $editing ? route('admin.articles.update', $article) : route('admin.articles.store') }}" class="form-card">
|
||||
@csrf
|
||||
@if ($editing) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>标题</label>
|
||||
<input name="title" class="input" value="{{ old('title', $article?->title ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Slug</label>
|
||||
<input name="slug" class="input" value="{{ old('slug', $article?->slug ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>分类</label>
|
||||
<select name="category_id" class="select">
|
||||
<option value="">无分类</option>
|
||||
@foreach ($categories as $c)
|
||||
<option value="{{ $c->id }}" @selected(old('category_id', $article?->category_id) == $c->id)>{{ $c->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>作者</label>
|
||||
<input name="author" class="input" value="{{ old('author', $article?->author ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>摘要</label>
|
||||
<input name="summary" class="input" value="{{ old('summary', $article?->summary ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>正文(富文本)</label>
|
||||
<x-rich-editor name="body" :value="old('body', $article?->body ?? '')" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>封面图(可选,支持上传)</label>
|
||||
<input type="file" id="cover-file" accept="image/*" style="margin-bottom:8px;">
|
||||
<div style="display:flex; gap:8px; align-items:center;">
|
||||
<input name="cover" id="cover-url" class="input" style="flex:1;" value="{{ old('cover', $article?->cover ?? '') }}" placeholder="图片地址(可上传或粘贴 URL)">
|
||||
<button type="button" class="btn" onclick="uploadFile('cover')">上传</button>
|
||||
</div>
|
||||
<p class="form-hint">仅「专题报道」版式会使用封面图。支持 jpg/png/gif/webp,单张 ≤ 5MB。</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>状态</label>
|
||||
<select name="status" class="select">
|
||||
<option value="approved" @selected(old('status', $article?->status ?? 'approved') === 'approved')>已发布</option>
|
||||
<option value="draft" @selected(old('status', $article?->status ?? '') === 'draft')>草稿</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>版式模板</label>
|
||||
<select name="template" class="select">
|
||||
@foreach (App\Models\Article::TEMPLATES as $key => $label)
|
||||
<option value="{{ $key }}" @selected(old('template', $article?->template ?? 'standard') === $key)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>SEO 标题(留空则使用文章标题)</label>
|
||||
<input name="seo_title" class="input" value="{{ old('seo_title', $article?->seo_title ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>SEO 描述(留空则使用摘要)</label>
|
||||
<input name="seo_description" class="input" value="{{ old('seo_description', $article?->seo_description ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>发布时间</label>
|
||||
<input type="date" name="published_at" class="input" value="{{ old('published_at', $article?->published_at?->format('Y-m-d')) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.articles.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,39 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '文章管理')
|
||||
@section('page-title', '文章管理')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.articles.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建文章</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>标题</th><th>分类</th><th>状态</th><th>发布时间</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($articles as $a)
|
||||
<tr>
|
||||
<td>{{ $a->title }}</td>
|
||||
<td>{{ $a->category?->name ?: '-' }}</td>
|
||||
<td>
|
||||
@if ($a->status === 'approved') 已发布
|
||||
@elseif ($a->status === 'pending') <span class="text-warning">待审</span>
|
||||
@elseif ($a->status === 'rejected') <span class="text-danger">已驳回</span>
|
||||
@else 草稿
|
||||
@endif
|
||||
</td>
|
||||
<td class="muted">{{ $a->published_at?->format('Y-m-d') ?: '-' }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.articles.edit', $a) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.articles.destroy', $a) }}" onsubmit="return confirm('确认删除该文章?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="muted">暂无文章。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $articles->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,38 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php $editing = isset($category) && $category; @endphp
|
||||
|
||||
@section('title', $editing ? '编辑分类' : '新建分类')
|
||||
@section('page-title', $editing ? '编辑分类' : '新建分类')
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $editing ? route('admin.categories.update', $category) : route('admin.categories.store') }}" class="form-card">
|
||||
@csrf
|
||||
@if ($editing) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>名称</label>
|
||||
<input name="name" class="input" value="{{ old('name', $category?->name ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Slug</label>
|
||||
<input name="slug" class="input" value="{{ old('slug', $category?->slug ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>类型</label>
|
||||
<select name="type" class="select">
|
||||
<option value="product" @selected(old('type', $category?->type ?? 'product') === 'product')>产品</option>
|
||||
<option value="article" @selected(old('type', $category?->type ?? '') === 'article')>文章</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>排序</label>
|
||||
<input type="number" name="sort" class="input" value="{{ old('sort', $category?->sort ?? 0) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.categories.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,32 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '分类管理')
|
||||
@section('page-title', '分类管理')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.categories.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建分类</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>名称</th><th>类型</th><th>排序</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($categories as $c)
|
||||
<tr>
|
||||
<td>{{ $c->name }} <span class="muted">/ {{ $c->slug }}</span></td>
|
||||
<td>{{ $c->type === 'product' ? '产品' : '文章' }}</td>
|
||||
<td>{{ $c->sort }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.categories.edit', $c) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.categories.destroy', $c) }}" onsubmit="return confirm('确认删除该分类?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="muted">暂无分类。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $categories->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,30 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '留言管理')
|
||||
@section('page-title', '留言管理')
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>姓名</th><th>邮箱</th><th>主题</th><th>时间</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($messages as $m)
|
||||
<tr>
|
||||
<td>{{ $m->name }}</td>
|
||||
<td>{{ $m->email }}</td>
|
||||
<td>{{ $m->subject }}</td>
|
||||
<td class="muted">{{ $m->created_at->format('Y-m-d') }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.contacts.show', $m) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.contacts.destroy', $m) }}" onsubmit="return confirm('确认删除该留言?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="muted">暂无留言。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $messages->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,24 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '留言详情')
|
||||
@section('page-title', '留言详情')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.contacts.index') }}" class="btn btn-sm">← 返回列表</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<p><strong>姓名:</strong>{{ $contactMessage->name }}</p>
|
||||
<p><strong>邮箱:</strong>{{ $contactMessage->email }}</p>
|
||||
<p><strong>电话:</strong>{{ $contactMessage->phone ?: '-' }}</p>
|
||||
<p><strong>主题:</strong>{{ $contactMessage->subject }}</p>
|
||||
<p><strong>时间:</strong>{{ $contactMessage->created_at->format('Y-m-d H:i') }}</p>
|
||||
<hr>
|
||||
<p class="prose">{{ nl2br(e($contactMessage->message)) }}</p>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('admin.contacts.destroy', $contactMessage) }}" onsubmit="return confirm('确认删除该留言?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-danger">删除留言</button>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,41 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '仪表盘')
|
||||
@section('page-title', '仪表盘')
|
||||
|
||||
@section('content')
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['products'] }}</span><span class="stat-label">产品</span></div>
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['articles'] }}</span><span class="stat-label">文章</span></div>
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['categories'] }}</span><span class="stat-label">分类</span></div>
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['glossary'] }}</span><span class="stat-label">术语</span></div>
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['threads'] }}</span><span class="stat-label">论坛帖</span></div>
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['users'] }}</span><span class="stat-label">用户</span></div>
|
||||
<div class="stat-card"><span class="stat-num">{{ $stats['messages'] }}</span><span class="stat-label">留言</span></div>
|
||||
</div>
|
||||
|
||||
<div class="admin-cols">
|
||||
<div class="card">
|
||||
<h2>最新留言</h2>
|
||||
@forelse ($recentMessages as $m)
|
||||
<div class="mini-row">
|
||||
<div><strong>{{ $m->name }}</strong> <span class="muted">{{ $m->email }}</span></div>
|
||||
<div class="muted">{{ Str::limit($m->message, 60) }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="muted">暂无留言。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>最新帖子</h2>
|
||||
@forelse ($recentThreads as $t)
|
||||
<div class="mini-row">
|
||||
<div><strong>{{ $t->title }}</strong></div>
|
||||
<div class="muted">{{ $t->user->name ?? '匿名' }} · {{ $t->board->name ?? '' }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="muted">暂无帖子。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,56 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '数据库管理')
|
||||
@section('page-title', '数据库管理')
|
||||
|
||||
@section('content')
|
||||
<div class="card mb-6">
|
||||
<h2>数据库信息</h2>
|
||||
<div class="kv">
|
||||
<div><span class="muted">连接</span><strong>{{ $connection }}</strong></div>
|
||||
<div><span class="muted">数据库</span><strong>{{ $dbName }}</strong></div>
|
||||
<div><span class="muted">已执行迁移</span><strong>{{ count($done) }}</strong></div>
|
||||
<div><span class="muted">待执行迁移</span><strong class="@if(count($pending) > 0) text-warning @endif">{{ count($pending) }}</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-cols">
|
||||
<div class="card">
|
||||
<h2>数据库升级</h2>
|
||||
@if (count($pending) === 0)
|
||||
<p class="muted">没有待执行的迁移,数据库已是最新。</p>
|
||||
@else
|
||||
<p class="muted">检测到 {{ count($pending) }} 个待执行迁移:</p>
|
||||
<ul class="mig-list">
|
||||
@foreach ($pending as $m)
|
||||
<li><x-icon name="arrow" :size="16"/> {{ $m }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
<form method="POST" action="{{ route('admin.database.upgrade') }}" class="mt-4">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-primary">执行升级(migrate)</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>已执行迁移({{ count($done) }})</h2>
|
||||
@if (count($done) === 0)
|
||||
<p class="muted">暂无已执行的迁移。</p>
|
||||
@else
|
||||
<ul class="mig-list done">
|
||||
@foreach ($done as $m)
|
||||
<li><x-icon name="check" :size="16"/> {{ $m }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (session('migrate_output'))
|
||||
<div class="card mt-6">
|
||||
<h2>本次升级输出</h2>
|
||||
<pre class="mig-output">{{ session('migrate_output') }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -0,0 +1,35 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php $editing = isset($board) && $board; @endphp
|
||||
|
||||
@section('title', $editing ? '编辑版块' : '新建版块')
|
||||
@section('page-title', $editing ? '编辑版块' : '新建版块')
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $editing ? route('admin.forum.boards.update', $board) : route('admin.forum.boards.store') }}" class="form-card">
|
||||
@csrf
|
||||
@if ($editing) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>名称</label>
|
||||
<input name="name" class="input" value="{{ old('name', $board?->name ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Slug</label>
|
||||
<input name="slug" class="input" value="{{ old('slug', $board?->slug ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>描述</label>
|
||||
<textarea name="description" class="textarea">{{ old('description', $board?->description ?? '') }}</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>排序</label>
|
||||
<input type="number" name="sort" class="input" value="{{ old('sort', $board?->sort ?? 0) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.forum.boards.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,32 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '论坛版块')
|
||||
@section('page-title', '论坛版块')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.forum.boards.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建版块</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>名称</th><th>Slug</th><th>排序</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($boards as $b)
|
||||
<tr>
|
||||
<td>{{ $b->name }}</td>
|
||||
<td class="muted">{{ $b->slug }}</td>
|
||||
<td>{{ $b->sort }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.forum.boards.edit', $b) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.forum.boards.destroy', $b) }}" onsubmit="return confirm('确认删除该版块?帖子将一并删除。')">
|
||||
@csrf @method('DELETE')<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button></form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="muted">暂无版块。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $boards->links('pagination::bootstrap-5') }}
|
||||
|
||||
<p style="margin-top:16px;"><a href="{{ route('admin.forum.threads.index') }}" class="btn btn-sm">查看全部帖子 →</a></p>
|
||||
@endsection
|
||||
@@ -0,0 +1,31 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '论坛帖子')
|
||||
@section('page-title', '论坛帖子')
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>标题</th><th>版块</th><th>作者</th><th>时间</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($threads as $t)
|
||||
<tr>
|
||||
<td>
|
||||
@if ($t->is_pinned)<x-icon name="pin" :size="14"/> @endif
|
||||
{{ $t->title }}
|
||||
</td>
|
||||
<td>{{ $t->board?->name ?: '-' }}</td>
|
||||
<td>{{ $t->user?->name ?: '匿名' }}</td>
|
||||
<td class="muted">{{ $t->created_at->format('Y-m-d') }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('forum.thread', $t) }}" class="btn btn-sm" target="_blank"><x-icon name="arrow" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.forum.threads.destroy', $t) }}" onsubmit="return confirm('确认删除该帖子?')">
|
||||
@csrf @method('DELETE')<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button></form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="muted">暂无帖子。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $threads->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,39 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php $editing = isset($term) && $term; @endphp
|
||||
|
||||
@section('title', $editing ? '编辑术语' : '新建术语')
|
||||
@section('page-title', $editing ? '编辑术语' : '新建术语')
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $editing ? route('admin.glossary.update', $term) : route('admin.glossary.store') }}" class="form-card">
|
||||
@csrf
|
||||
@if ($editing) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>术语</label>
|
||||
<input name="term" class="input" value="{{ old('term', $term?->term ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Slug</label>
|
||||
<input name="slug" class="input" value="{{ old('slug', $term?->slug ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>分类</label>
|
||||
<input name="category" class="input" value="{{ old('category', $term?->category ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>定义</label>
|
||||
<textarea name="definition" class="textarea" required>{{ old('definition', $term?->definition ?? '') }}</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>别名(逗号分隔)</label>
|
||||
<input name="aliases" class="input" value="{{ old('aliases', $term?->aliases ?? '') }}">
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.glossary.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,31 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '术语库管理')
|
||||
@section('page-title', '术语库管理')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.glossary.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建术语</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>术语</th><th>分类</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($terms as $t)
|
||||
<tr>
|
||||
<td>{{ $t->term }} <span class="muted">/ {{ $t->slug }}</span></td>
|
||||
<td>{{ $t->category ?: '-' }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.glossary.edit', $t) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.glossary.destroy', $t) }}" onsubmit="return confirm('确认删除该术语?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="3" class="muted">暂无术语。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $terms->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,65 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php
|
||||
$isEdit = isset($slide) && $slide;
|
||||
@endphp
|
||||
|
||||
@section('title', $isEdit ? '编辑轮播项' : '新建轮播项')
|
||||
@section('page-title', $isEdit ? '编辑轮播项' : '新建轮播项')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.hero-slides.index') }}" class="btn btn-sm">返回列表</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $isEdit ? route('admin.hero-slides.update', $slide) : route('admin.hero-slides.store') }}">
|
||||
@csrf
|
||||
@if ($isEdit) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>标题(后台标识 / 无障碍标题)*</label>
|
||||
<input name="title" class="input" value="{{ old('title', $slide->title ?? '') }}" maxlength="120" required>
|
||||
<p class="form-hint">仅用于后台识别与该区块的无障碍标题,不会作为大字标题显示(大字标题请在下方正文内排版)。</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Hero 正文(富文本)</label>
|
||||
<x-rich-editor name="content" :value="old('content', $slide->content ?? '')" />
|
||||
<p class="form-hint">使用富文本编辑主标题、副标题与说明文字;支持加粗、列表、引用、插入图片等。</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>主按钮文字</label>
|
||||
<input name="cta_text" class="input" value="{{ old('cta_text', $slide->cta_text ?? '') }}" maxlength="80" placeholder="例如:获取选型支持">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>主按钮链接</label>
|
||||
<input name="cta_url" class="input" value="{{ old('cta_url', $slide->cta_url ?? '') }}" maxlength="255" placeholder="/contact">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>次按钮文字</label>
|
||||
<input name="cta2_text" class="input" value="{{ old('cta2_text', $slide->cta2_text ?? '') }}" maxlength="80" placeholder="例如:浏览全部产品">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>次按钮链接</label>
|
||||
<input name="cta2_url" class="input" value="{{ old('cta2_url', $slide->cta2_url ?? '') }}" maxlength="255" placeholder="/products">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>排序</label>
|
||||
<input name="sort_order" type="number" class="input" value="{{ old('sort_order', $slide->sort_order ?? 0) }}" style="max-width:160px">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="inline-flex items-center gap-2">
|
||||
<input type="checkbox" name="is_active" value="1" {{ old('is_active', $slide->is_active ?? true) ? 'checked' : '' }}>
|
||||
启用该项
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.hero-slides.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,70 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '首页 Hero 轮播')
|
||||
@section('page-title', '首页 Hero 轮播')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.hero-slides.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建轮播项</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="panel" style="margin-bottom:20px;padding:16px 18px;border:1px solid var(--color-border);border-radius:var(--radius-lg);background:var(--color-surface-2)">
|
||||
<div class="flex items-center justify-between flex-wrap gap-3">
|
||||
<div>
|
||||
<div class="font-semibold text-fg">Hero 显示模式</div>
|
||||
<div class="form-hint">轮播:启用项自动切换播放;独立单图:仅展示第一条启用项(不轮播)。</div>
|
||||
</div>
|
||||
<form method="POST" action="{{ route('admin.hero.mode') }}" class="flex gap-2">
|
||||
@csrf
|
||||
<button type="submit" name="hero_mode" value="carousel" class="btn btn-sm {{ $mode === 'carousel' ? 'btn-primary' : '' }}">轮播</button>
|
||||
<button type="submit" name="hero_mode" value="single" class="btn btn-sm {{ $mode === 'single' ? 'btn-primary' : '' }}">独立单图</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90px">排序</th>
|
||||
<th style="width:90px">启用</th>
|
||||
<th>标题(后台标识)</th>
|
||||
<th class="col-op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($slides as $slide)
|
||||
<tr>
|
||||
<td class="row-actions">
|
||||
<form method="POST" action="{{ route('admin.hero-slides.move', $slide) }}" class="inline">
|
||||
@csrf
|
||||
<input type="hidden" name="direction" value="up">
|
||||
<button class="btn btn-sm" title="上移" {{ $loop->first ? 'disabled' : '' }}><x-icon name="up" :size="16"/></button>
|
||||
</form>
|
||||
<form method="POST" action="{{ route('admin.hero-slides.move', $slide) }}" class="inline">
|
||||
@csrf
|
||||
<input type="hidden" name="direction" value="down">
|
||||
<button class="btn btn-sm" title="下移" {{ $loop->last ? 'disabled' : '' }}><x-icon name="down" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<form method="POST" action="{{ route('admin.hero-slides.toggle', $slide) }}" class="inline">
|
||||
@csrf
|
||||
<button class="btn btn-sm {{ $slide->is_active ? 'btn-primary' : '' }}" title="{{ $slide->is_active ? '点击停用' : '点击启用' }}">
|
||||
{{ $slide->is_active ? '启用中' : '已停用' }}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>{{ $slide->title }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.hero-slides.edit', $slide) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.hero-slides.destroy', $slide) }}" class="inline" onsubmit="return confirm('确认删除该轮播项?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="muted">暂无轮播项,请点击右上角「新建轮播项」。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
@endsection
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>@yield('title', '管理后台') - 云创芯</title>
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}?v={{ filemtime(public_path('css/app.css')) }}">
|
||||
</head>
|
||||
<body class="admin-body">
|
||||
<div class="admin-shell">
|
||||
<aside class="admin-side">
|
||||
<div class="admin-brand"><img src="{{ asset('images/logo-dark.png') }}" alt="logo" class="brand-logo" width="40" height="24"> 云创芯电子后台</div>
|
||||
<nav class="admin-nav">
|
||||
@canPerm('dashboard.view')<a href="{{ route('admin.dashboard') }}" class="@if(request()->routeIs('admin.dashboard')) active @endif"><x-icon name="grid" :size="18"/> 仪表盘</a>@endcanPerm
|
||||
@canPerm('products.view')<a href="{{ route('admin.products.index') }}" class="@if(request()->routeIs('admin.products.*')) active @endif"><x-icon name="box" :size="18"/> 产品</a>@endcanPerm
|
||||
@canPerm('categories.view')<a href="{{ route('admin.categories.index') }}" class="@if(request()->routeIs('admin.categories.*')) active @endif"><x-icon name="tag" :size="18"/> 分类</a>@endcanPerm
|
||||
@canPerm('articles.view')<a href="{{ route('admin.articles.index') }}" class="@if(request()->routeIs('admin.articles.*')) active @endif"><x-icon name="doc" :size="18"/> 文章</a>@endcanPerm
|
||||
@if (auth()->user()->canPerm('articles.moderate') || auth()->user()->canPerm('forum.moderate'))<a href="{{ route('admin.moderation.index') }}" class="@if(request()->routeIs('admin.moderation.*')) active @endif"><x-icon name="check" :size="18"/> 审核队列</a>@endif
|
||||
@canPerm('glossary.view')<a href="{{ route('admin.glossary.index') }}" class="@if(request()->routeIs('admin.glossary.*')) active @endif"><x-icon name="book" :size="18"/> 术语库</a>@endcanPerm
|
||||
@canPerm('forum.view')<a href="{{ route('admin.forum.boards.index') }}" class="@if(request()->routeIs('admin.forum.*')) active @endif"><x-icon name="chat" :size="18"/> 论坛</a>@endcanPerm
|
||||
@canPerm('contacts.view')<a href="{{ route('admin.contacts.index') }}" class="@if(request()->routeIs('admin.contacts.*')) active @endif"><x-icon name="mail" :size="18"/> 留言</a>@endcanPerm
|
||||
@canPerm('users.view')<a href="{{ route('admin.users.index') }}" class="@if(request()->routeIs('admin.users.*')) active @endif"><x-icon name="users" :size="18"/> 用户</a>@endcanPerm
|
||||
@canPerm('settings.view')<a href="{{ route('admin.settings') }}" class="@if(request()->routeIs('admin.settings')) active @endif"><x-icon name="settings" :size="18"/> 站点设置</a>@endcanPerm
|
||||
@canPerm('appearance.view')<a href="{{ route('admin.hero-slides.index') }}" class="@if(request()->routeIs('admin.hero-slides.*')) active @endif"><x-icon name="layers" :size="18"/> 首页轮播</a>@endcanPerm
|
||||
@canPerm('appearance.view')<a href="{{ route('admin.menus.index') }}" class="@if(request()->routeIs('admin.menus.*')) active @endif"><x-icon name="menu" :size="18"/> 导航菜单</a>@endcanPerm
|
||||
@canPerm('settings.update')<a href="{{ route('admin.database') }}" class="@if(request()->routeIs('admin.database*')) active @endif"><x-icon name="database" :size="18"/> 数据库</a>@endcanPerm
|
||||
</nav>
|
||||
<div class="admin-foot">
|
||||
<a href="{{ url('/') }}" target="_blank"><x-icon name="arrow" :size="16"/> 访问前台</a>
|
||||
<a href="{{ route('auth.settings') }}"><x-icon name="lock" :size="16"/> 修改密码</a>
|
||||
<form method="POST" action="{{ url('/logout') }}">@csrf<button type="submit" class="btn-link">退出登录</button></form>
|
||||
</div>
|
||||
</aside>
|
||||
<main class="admin-main">
|
||||
<div class="admin-topbar">
|
||||
<h1>@yield('page-title', '管理后台')</h1>
|
||||
<div class="admin-actions">@yield('actions')</div>
|
||||
</div>
|
||||
@if (session('success'))<div class="alert alert-success"><x-icon name="check" :size="18"/> {{ session('success') }}</div>@endif
|
||||
@if ($errors->any())<div class="alert alert-danger"><x-icon name="alert" :size="18"/> 表单填写有误,请检查后重试。</div>@endif
|
||||
@yield('content')
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,47 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php
|
||||
$isEdit = isset($menu) && $menu;
|
||||
@endphp
|
||||
|
||||
@section('title', $isEdit ? '编辑菜单' : '新建菜单')
|
||||
@section('page-title', $isEdit ? '编辑菜单' : '新建菜单')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.menus.index') }}" class="btn btn-sm">返回列表</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $isEdit ? route('admin.menus.update', $menu) : route('admin.menus.store') }}">
|
||||
@csrf
|
||||
@if ($isEdit) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>菜单文字 *</label>
|
||||
<input name="label" class="input" value="{{ old('label', $menu->label ?? '') }}" placeholder="例如:产品服务" maxlength="60" required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>链接地址 *</label>
|
||||
<input name="url" class="input" value="{{ old('url', $menu->url ?? '') }}" placeholder="站内路径如 /products 或完整外链 https://..." maxlength="255" required>
|
||||
<p class="form-hint">站内页面填写相对路径(以 / 开头),外链填写完整 https:// 地址。</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>排序</label>
|
||||
<input name="sort_order" type="number" class="input" value="{{ old('sort_order', $menu->sort_order ?? 0) }}" style="max-width:160px">
|
||||
<p class="form-hint">数字越小越靠前,相同则按添加先后排列。</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="inline-flex items-center gap-2">
|
||||
<input type="checkbox" name="is_visible" value="1" {{ old('is_visible', $menu->is_visible ?? true) ? 'checked' : '' }}>
|
||||
在前台显示
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.menus.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,60 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '导航菜单管理')
|
||||
@section('page-title', '导航菜单管理')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.menus.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建菜单</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<p class="form-hint mb-4">管理前台顶部导航菜单:可新增、编辑、删除,一键显示/隐藏,并通过上下移调整顺序。排序越小越靠前。</p>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90px">排序</th>
|
||||
<th style="width:90px">显示</th>
|
||||
<th>菜单文字</th>
|
||||
<th>链接</th>
|
||||
<th class="col-op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($menus as $menu)
|
||||
<tr>
|
||||
<td class="row-actions">
|
||||
<form method="POST" action="{{ route('admin.menus.move', $menu) }}" class="inline">
|
||||
@csrf
|
||||
<input type="hidden" name="direction" value="up">
|
||||
<button class="btn btn-sm" title="上移" {{ $loop->first ? 'disabled' : '' }}><x-icon name="up" :size="16"/></button>
|
||||
</form>
|
||||
<form method="POST" action="{{ route('admin.menus.move', $menu) }}" class="inline">
|
||||
@csrf
|
||||
<input type="hidden" name="direction" value="down">
|
||||
<button class="btn btn-sm" title="下移" {{ $loop->last ? 'disabled' : '' }}><x-icon name="down" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<form method="POST" action="{{ route('admin.menus.toggle', $menu) }}" class="inline">
|
||||
@csrf
|
||||
<button class="btn btn-sm {{ $menu->is_visible ? 'btn-primary' : '' }}" title="{{ $menu->is_visible ? '点击隐藏' : '点击显示' }}">
|
||||
{{ $menu->is_visible ? '显示中' : '已隐藏' }}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>{{ $menu->label }}</td>
|
||||
<td><code class="muted">{{ $menu->url }}</code></td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.menus.edit', $menu) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.menus.destroy', $menu) }}" class="inline" onsubmit="return confirm('确认删除该菜单项?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="muted">暂无菜单项,请点击右上角「新建菜单」。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
@endsection
|
||||
@@ -0,0 +1,103 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '审核队列')
|
||||
@section('page-title', '审核队列')
|
||||
|
||||
@section('actions')
|
||||
@if ($canArticles)
|
||||
<a href="{{ route('admin.moderation.index', ['tab' => 'articles']) }}" class="btn btn-sm @if($tab === 'articles') btn-primary @endif">文章投稿</a>
|
||||
@endif
|
||||
@if ($canForum)
|
||||
<a href="{{ route('admin.moderation.index', ['tab' => 'threads']) }}" class="btn btn-sm @if($tab === 'threads') btn-primary @endif">论坛帖子</a>
|
||||
<a href="{{ route('admin.moderation.index', ['tab' => 'replies']) }}" class="btn btn-sm @if($tab === 'replies') btn-primary @endif">回复</a>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@if ($tab === 'articles' && $articles)
|
||||
@if ($articles->isEmpty())
|
||||
<p class="muted">暂无待审文章。</p>
|
||||
@else
|
||||
<table class="data-table">
|
||||
<thead><tr><th>标题</th><th>投稿人</th><th>分类</th><th>摘要</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($articles as $a)
|
||||
<tr>
|
||||
<td>{{ $a->title }}</td>
|
||||
<td>{{ $a->user?->name ?? '管理员' }}</td>
|
||||
<td>{{ $a->category?->name ?: '-' }}</td>
|
||||
<td class="muted">{{ Str::limit(strip_tags($a->summary ?: $a->body), 40) }}</td>
|
||||
<td class="row-actions">
|
||||
<form method="POST" action="{{ route('admin.moderation.articles.approve', $a) }}" style="display:inline">
|
||||
@csrf<button class="btn btn-sm btn-primary">通过</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ route('admin.moderation.articles.reject', $a) }}" style="display:inline">
|
||||
@csrf<button class="btn btn-sm btn-danger">驳回</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $articles->links('pagination::bootstrap-5') }}
|
||||
@endif
|
||||
|
||||
@elseif ($tab === 'threads' && $threads)
|
||||
@if ($threads->isEmpty())
|
||||
<p class="muted">暂无待审帖子。</p>
|
||||
@else
|
||||
<table class="data-table">
|
||||
<thead><tr><th>标题</th><th>作者</th><th>板块</th><th>内容</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($threads as $t)
|
||||
<tr>
|
||||
<td>{{ $t->title }}</td>
|
||||
<td>{{ $t->user?->name ?? '-' }}</td>
|
||||
<td>{{ $t->board?->name ?: '-' }}</td>
|
||||
<td class="muted">{{ Str::limit(strip_tags($t->body), 40) }}</td>
|
||||
<td class="row-actions">
|
||||
<form method="POST" action="{{ route('admin.moderation.threads.approve', $t) }}" style="display:inline">
|
||||
@csrf<button class="btn btn-sm btn-primary">通过</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ route('admin.moderation.threads.reject', $t) }}" style="display:inline">
|
||||
@csrf<button class="btn btn-sm btn-danger">驳回</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $threads->links('pagination::bootstrap-5') }}
|
||||
@endif
|
||||
|
||||
@elseif ($tab === 'replies' && $replies)
|
||||
@if ($replies->isEmpty())
|
||||
<p class="muted">暂无待审回复。</p>
|
||||
@else
|
||||
<table class="data-table">
|
||||
<thead><tr><th>回复内容</th><th>作者</th><th>所属帖子</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($replies as $r)
|
||||
<tr>
|
||||
<td class="muted">{{ Str::limit(strip_tags($r->body), 60) }}</td>
|
||||
<td>{{ $r->user?->name ?? '-' }}</td>
|
||||
<td>{{ $r->thread?->title ?: '-' }}</td>
|
||||
<td class="row-actions">
|
||||
<form method="POST" action="{{ route('admin.moderation.replies.approve', $r) }}" style="display:inline">
|
||||
@csrf<button class="btn btn-sm btn-primary">通过</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ route('admin.moderation.replies.reject', $r) }}" style="display:inline">
|
||||
@csrf<button class="btn btn-sm btn-danger">驳回</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $replies->links('pagination::bootstrap-5') }}
|
||||
@endif
|
||||
|
||||
@else
|
||||
<p class="muted">暂无待审内容。</p>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -0,0 +1,68 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@php $editing = isset($product) && $product; @endphp
|
||||
|
||||
@section('title', $editing ? '编辑产品' : '新建产品')
|
||||
@section('page-title', $editing ? '编辑产品' : '新建产品')
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ $editing ? route('admin.products.update', $product) : route('admin.products.store') }}" class="form-card">
|
||||
@csrf
|
||||
@if ($editing) @method('PUT') @endif
|
||||
|
||||
<div class="field">
|
||||
<label>名称</label>
|
||||
<input name="name" class="input" value="{{ old('name', $product?->name ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Slug</label>
|
||||
<input name="slug" class="input" value="{{ old('slug', $product?->slug ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>型号</label>
|
||||
<input name="model" class="input" value="{{ old('model', $product?->model ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>分类</label>
|
||||
<select name="category_id" class="select">
|
||||
<option value="">无分类</option>
|
||||
@foreach ($categories as $c)
|
||||
<option value="{{ $c->id }}" @selected(old('category_id', $product?->category_id) == $c->id)>{{ $c->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>简介</label>
|
||||
<input name="summary" class="input" value="{{ old('summary', $product?->summary ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>描述</label>
|
||||
<textarea name="description" class="textarea">{{ old('description', $product?->description ?? '') }}</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>规格参数</label>
|
||||
<textarea name="specs" class="textarea">{{ old('specs', $product?->specs ?? '') }}</textarea>
|
||||
<p class="form-hint">每行一个参数,或自由文本。</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>封面图 URL</label>
|
||||
<input name="cover" class="input" value="{{ old('cover', $product?->cover ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>状态</label>
|
||||
<select name="status" class="select">
|
||||
<option value="published" @selected(old('status', $product?->status ?? 'published') === 'published')>已发布</option>
|
||||
<option value="draft" @selected(old('status', $product?->status ?? '') === 'draft')>草稿</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>排序</label>
|
||||
<input type="number" name="sort" class="input" value="{{ old('sort', $product?->sort ?? 0) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存</button>
|
||||
<a href="{{ route('admin.products.index') }}" class="btn">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
@@ -0,0 +1,33 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '产品管理')
|
||||
@section('page-title', '产品管理')
|
||||
@section('actions')
|
||||
<a href="{{ route('admin.products.create') }}" class="btn btn-primary btn-sm"><x-icon name="plus" :size="16"/> 新建产品</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<table class="data-table">
|
||||
<thead><tr><th>名称</th><th>型号</th><th>分类</th><th>状态</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($products as $p)
|
||||
<tr>
|
||||
<td>{{ $p->name }}</td>
|
||||
<td class="muted">{{ $p->model ?: '-' }}</td>
|
||||
<td>{{ $p->category?->name ?: '-' }}</td>
|
||||
<td>{{ $p->status === 'published' ? '已发布' : '草稿' }}</td>
|
||||
<td class="row-actions">
|
||||
<a href="{{ route('admin.products.edit', $p) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/></a>
|
||||
<form method="POST" action="{{ route('admin.products.destroy', $p) }}" onsubmit="return confirm('确认删除该产品?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="muted">暂无产品。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $products->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,105 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '站点设置')
|
||||
@section('page-title', '站点设置')
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ route('admin.settings.update') }}" class="form-card">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="field">
|
||||
<label>站点名称</label>
|
||||
<input name="site_name" class="input" value="{{ old('site_name', $settings['site_name'] ?? '') }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>站点描述(默认 description)</label>
|
||||
<input name="site_description" id="site_description" class="input" value="{{ old('site_description', $settings['site_description'] ?? '') }}">
|
||||
<p class="form-hint">搜索结果摘要,建议 ≤ 160 字符(超出会被截断)。<span class="char-count" id="cnt-site_description">0 / 160</span></p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>SEO 默认标题</label>
|
||||
<input name="seo_title_default" id="seo_title_default" class="input" value="{{ old('seo_title_default', $settings['seo_title_default'] ?? '') }}">
|
||||
<p class="form-hint">浏览器标签与搜索结果标题,建议 ≤ 60 字符(超出会被截断)。<span class="char-count" id="cnt-seo_title_default">0 / 60</span></p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>SEO 默认描述</label>
|
||||
<input name="seo_description_default" id="seo_description_default" class="input" value="{{ old('seo_description_default', $settings['seo_description_default'] ?? '') }}">
|
||||
<p class="form-hint">全站默认 meta description,建议 ≤ 160 字符。<span class="char-count" id="cnt-seo_description_default">0 / 160</span></p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>ICP 备案号</label>
|
||||
<input name="icp_no" class="input" value="{{ old('icp_no', $settings['icp_no'] ?? '') }}" placeholder="粤ICP备xxxxx号-x">
|
||||
<p class="form-hint">工信部备案号,将链接至 https://beian.miit.gov.cn/</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>公安网备号(联网备案)</label>
|
||||
<input name="security_filing_no" class="input" value="{{ old('security_filing_no', $settings['security_filing_no'] ?? '') }}" placeholder="粤公网安备XXXXXXXXXXXX号">
|
||||
<p class="form-hint">按公安局要求悬挂联网备案号,格式「X公网安备XXXXXXXXXXXX号」,将链接至 https://beian.mps.gov.cn/</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Logo 地址(站内横版展示)</label>
|
||||
<input name="logo_url" class="input" value="{{ old('logo_url', $settings['logo_url'] ?? '') }}" placeholder="/images/logo-dark.png">
|
||||
<p class="form-hint">建议用 PNG,高度 56px(2x 高清屏适配),置于 public/images/ 下。</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>主题配色(前台)</label>
|
||||
@php
|
||||
$themeSwatches = ['azure' => '#4a8af4', 'slate' => '#6e8cb0', 'indigo' => '#7b7ef0', 'teal' => '#2bb6a4', 'amber' => '#e8a13c'];
|
||||
$themeLabels = ['azure' => '沉稳蓝(默认)', 'slate' => '沉静灰蓝', 'indigo' => '蓝紫', 'teal' => '青绿', 'amber' => '暖琥珀'];
|
||||
$currentTheme = $settings['theme'] ?? 'azure';
|
||||
@endphp
|
||||
<div class="theme-options">
|
||||
@foreach ($themeSwatches as $key => $color)
|
||||
<label class="theme-opt @if($currentTheme === $key) active @endif">
|
||||
<input type="radio" name="theme" value="{{ $key }}" @if($currentTheme === $key) checked @endif>
|
||||
<span class="theme-swatch" style="background: {{ $color }};"></span>
|
||||
<span class="theme-label">{{ $themeLabels[$key] }}</span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
<p class="form-hint">切换后前台主色与辉光(Hero 极光、按钮、卡片高亮)整体跟随变化,保存并刷新即生效。</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Favicon 地址(浏览器标签图标)</label>
|
||||
<input name="favicon_url" class="input" value="{{ old('favicon_url', $settings['favicon_url'] ?? '') }}" placeholder="/images/ccc-icon.ico">
|
||||
<p class="form-hint">建议用方形 ICO 或 32×32 PNG。</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>联系邮箱</label>
|
||||
<input name="contact_email" class="input" value="{{ old('contact_email', $settings['contact_email'] ?? '') }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>页脚自定义内容(富文本)</label>
|
||||
<x-rich-editor name="footer_content" :value="old('footer_content', $settings['footer_content'] ?? '')" />
|
||||
<p class="form-hint">支持标题、列表、链接、图片等,用于自由排版页脚信息(如友情链接、资质说明、客服二维码)。留空则前台页脚不显示该区块。</p>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary">保存设置</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var limits = {
|
||||
'seo_title_default': 60,
|
||||
'seo_description_default': 160,
|
||||
'site_description': 160
|
||||
};
|
||||
Object.keys(limits).forEach(function (id) {
|
||||
var el = document.getElementById(id);
|
||||
var cnt = document.getElementById('cnt-' + id);
|
||||
if (!el || !cnt) return;
|
||||
var max = limits[id];
|
||||
function update() {
|
||||
var len = (el.value || '').length;
|
||||
cnt.textContent = len + ' / ' + max;
|
||||
cnt.classList.toggle('over', len > max);
|
||||
}
|
||||
el.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,87 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '新建用户')
|
||||
@section('page-title', '新建用户')
|
||||
|
||||
@section('content')
|
||||
<div class="card" style="max-width: 760px;">
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('admin.users.store') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">姓名</label>
|
||||
<input type="text" name="name" value="{{ old('name') }}" class="input" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">邮箱(登录账号)</label>
|
||||
<input type="email" name="email" value="{{ old('email') }}" class="input" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">初始密码</label>
|
||||
<input type="password" name="password" class="input" required autocomplete="new-password">
|
||||
<p class="role-hint">至少 8 位。创建后可在用户编辑页随时重置。</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">角色</label>
|
||||
<select name="role" id="role-select" class="input">
|
||||
@foreach ($roles as $key => $cfg)
|
||||
<option value="{{ $key }}"
|
||||
{{ old('role', 'staff') === $key ? 'selected' : '' }}
|
||||
@if ($key === 'super_admin' && ! auth()->user()->isSuperAdmin()) disabled @endif>
|
||||
{{ $cfg['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p class="role-hint">
|
||||
@if (! auth()->user()->isSuperAdmin())
|
||||
只能创建权限低于自身的角色;超级管理员角色仅限超级管理员创建。
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- 内部员工:细粒度勾选 --}}
|
||||
<div id="perm-section" class="perm-group" @if (old('role', 'staff') !== 'staff') style="display:none;" @endif>
|
||||
<div class="perm-group-title">内部员工权限分配</div>
|
||||
<p class="role-hint">勾选该员工可执行的权限点,未勾选则无对应后台访问权。</p>
|
||||
@foreach ($groups as $gKey => $gLabel)
|
||||
<div class="perm-group" style="margin-bottom: var(--space-3);">
|
||||
<div class="perm-group-title">{{ $gLabel }}</div>
|
||||
<div class="perm-list">
|
||||
@foreach ($permissions as $permKey => $permCfg)
|
||||
@if ($permCfg['group'] === $gKey)
|
||||
<label class="perm-item">
|
||||
<input type="checkbox" name="permissions[]" value="{{ $permKey }}"
|
||||
{{ in_array($permKey, old('permissions', []), true) ? 'checked' : '' }}>
|
||||
{{ $permCfg['label'] }}
|
||||
</label>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="row-actions" style="margin-top: var(--space-5);">
|
||||
<button type="submit" class="btn btn-primary">创建用户</button>
|
||||
<a href="{{ route('admin.users.index') }}" class="btn">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var sel = document.getElementById('role-select');
|
||||
var sec = document.getElementById('perm-section');
|
||||
function sync() {
|
||||
sec.style.display = (sel.value === 'staff') ? '' : 'none';
|
||||
}
|
||||
sel.addEventListener('change', sync);
|
||||
sync();
|
||||
})();
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,143 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '编辑用户 - ' . $user->name)
|
||||
@section('page-title', '编辑用户:' . $user->name)
|
||||
|
||||
@section('content')
|
||||
<div class="card" style="max-width: 760px;">
|
||||
<div class="card-body">
|
||||
<div class="muted" style="margin-bottom: var(--space-4);">
|
||||
邮箱:{{ $user->email }}
|
||||
@if ($user->id === request()->user()->id)
|
||||
<span class="badge badge-role-user">当前账号</span>
|
||||
@endif
|
||||
<span class="badge badge-role-{{ $user->role }}">{{ $user->roleLabel() }}</span>
|
||||
</div>
|
||||
|
||||
@if (! $canManage)
|
||||
<div class="alert alert-warning">您的权限不高于该用户,无法修改其角色、权限或密码。</div>
|
||||
@endif
|
||||
|
||||
{{-- 角色 / 权限(仅具备分配权限且层级更高者可改) --}}
|
||||
@if ($canManage && auth()->user()->canPerm('users.assign_role'))
|
||||
<form method="POST" action="{{ route('admin.users.update', $user) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">角色</label>
|
||||
<select name="role" id="role-select" class="input">
|
||||
@foreach ($roles as $key => $cfg)
|
||||
<option value="{{ $key }}"
|
||||
{{ $user->role === $key ? 'selected' : '' }}
|
||||
@if ($key === 'super_admin' && ! request()->user()->isSuperAdmin()) disabled @endif>
|
||||
{{ $cfg['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p class="role-hint">
|
||||
@if (! request()->user()->isSuperAdmin())
|
||||
超级管理员角色仅限超级管理员分配;您只能分配权限低于自身的角色。
|
||||
@else
|
||||
不同角色拥有不同的后台视图与权限,下方将实时显示该角色的默认权限。
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- 各角色默认权限(只读,前端按所选角色切换显隐) --}}
|
||||
<div id="role-defaults">
|
||||
@foreach ($roles as $key => $cfg)
|
||||
<div class="perm-group role-default" data-role="{{ $key }}"
|
||||
style="background: var(--color-surface); {{ $user->role === $key ? '' : 'display:none;' }}">
|
||||
<div class="perm-group-title">{{ $cfg['label'] }} · 默认权限</div>
|
||||
<div class="perm-list">
|
||||
@if (($cfg['permissions'] ?? []) === ['*'])
|
||||
<div class="perm-item"><x-icon name="lock" :size="16"/> 全部权限(超级管理员)</div>
|
||||
@elseif (empty($cfg['permissions'] ?? []))
|
||||
<div class="perm-item muted">无(注册用户 / 待分配)</div>
|
||||
@else
|
||||
@foreach ($cfg['permissions'] as $p)
|
||||
<div class="perm-item"><x-icon name="check" :size="16"/> {{ $permissions[$p]['label'] ?? $p }}</div>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
{{-- 内部员工:细粒度勾选 --}}
|
||||
<div id="perm-section" class="perm-group" @if ($user->role !== 'staff') style="display:none;" @endif>
|
||||
<div class="perm-group-title">内部员工权限分配</div>
|
||||
<p class="role-hint">勾选该员工可执行的权限点,未勾选则无对应后台访问权。</p>
|
||||
@foreach ($groups as $gKey => $gLabel)
|
||||
<div class="perm-group" style="margin-bottom: var(--space-3);">
|
||||
<div class="perm-group-title">{{ $gLabel }}</div>
|
||||
<div class="perm-list">
|
||||
@foreach ($permissions as $permKey => $permCfg)
|
||||
@if ($permCfg['group'] === $gKey)
|
||||
<label class="perm-item">
|
||||
<input type="checkbox" name="permissions[]" value="{{ $permKey }}"
|
||||
{{ in_array($permKey, $userPerms, true) ? 'checked' : '' }}>
|
||||
{{ $permCfg['label'] }}
|
||||
</label>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="row-actions" style="margin-top: var(--space-5);">
|
||||
<button type="submit" class="btn btn-primary">保存角色与权限</button>
|
||||
<a href="{{ route('admin.users.index') }}" class="btn">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
{{-- 重置密码(仅具备重置权限且层级更高者可操作) --}}
|
||||
@if ($canManage && auth()->user()->canPerm('users.reset_password'))
|
||||
<hr style="margin: var(--space-6) 0; border-color: var(--color-border);">
|
||||
<div id="reset-password" class="perm-group">
|
||||
<div class="perm-group-title">重置密码</div>
|
||||
<p class="role-hint">可指定一个新密码,或留空由系统生成 12 位随机密码(生成后请妥善告知用户)。</p>
|
||||
<form method="POST" action="{{ route('admin.users.reset-password', $user) }}" class="space-y-4">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label class="form-label">新密码(可选)</label>
|
||||
<input type="password" name="password" class="input" autocomplete="new-password" placeholder="留空则生成随机密码">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">确认新密码</label>
|
||||
<input type="password" name="password_confirmation" class="input" autocomplete="new-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">重置密码</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($canManage && auth()->user()->canPerm('users.assign_role'))
|
||||
<script>
|
||||
(function () {
|
||||
var sel = document.getElementById('role-select');
|
||||
var defaults = document.querySelectorAll('#role-defaults .role-default');
|
||||
var sec = document.getElementById('perm-section');
|
||||
function sync() {
|
||||
var v = sel.value;
|
||||
if (v === 'staff') {
|
||||
sec.style.display = '';
|
||||
defaults.forEach(function (el) { el.style.display = 'none'; });
|
||||
} else {
|
||||
sec.style.display = 'none';
|
||||
defaults.forEach(function (el) {
|
||||
el.style.display = (el.getAttribute('data-role') === v) ? '' : 'none';
|
||||
});
|
||||
}
|
||||
}
|
||||
sel.addEventListener('change', sync);
|
||||
sync();
|
||||
})();
|
||||
</script>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -0,0 +1,58 @@
|
||||
@extends('admin.layout')
|
||||
|
||||
@section('title', '用户管理')
|
||||
@section('page-title', '用户管理')
|
||||
|
||||
@section('actions')
|
||||
@canPerm('users.create')
|
||||
<a href="{{ route('admin.users.create') }}" class="btn btn-primary"><x-icon name="plus" :size="16"/> 新建用户</a>
|
||||
@endcanPerm
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form method="GET" class="filter-bar">
|
||||
<input type="text" name="q" value="{{ $q }}" class="input" placeholder="搜索姓名、邮箱...">
|
||||
<button type="submit" class="btn btn-primary">查询</button>
|
||||
</form>
|
||||
|
||||
<table class="data-table" style="margin-top:16px;">
|
||||
<thead><tr><th>姓名</th><th>邮箱</th><th>角色</th><th>积分 / 等级</th><th class="col-op">操作</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($users as $u)
|
||||
@php
|
||||
$me = auth()->user();
|
||||
$canManage = $me->isSuperAdmin() || $me->roleLevel() > $u->roleLevel();
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $u->name }}</td>
|
||||
<td>{{ $u->email }}</td>
|
||||
<td>
|
||||
<span class="badge badge-role-{{ $u->role }}">{{ $u->roleLabel() }}</span>
|
||||
@if ($u->id === $me->id)<span class="muted">(当前)</span>@endif
|
||||
</td>
|
||||
<td class="muted">{{ $u->points ?? 0 }} · L{{ $u->level() }}</td>
|
||||
<td class="row-actions">
|
||||
@if ($canManage)
|
||||
@canPerm('users.assign_role')
|
||||
<a href="{{ route('admin.users.edit', $u) }}" class="btn btn-sm"><x-icon name="edit" :size="16"/> 角色/权限</a>
|
||||
@endcanPerm
|
||||
@canPerm('users.reset_password')
|
||||
<a href="{{ route('admin.users.edit', $u) }}#reset-password" class="btn btn-sm"><x-icon name="lock" :size="16"/> 重置密码</a>
|
||||
@endcanPerm
|
||||
@else
|
||||
<span class="muted">无权操作</span>
|
||||
@endif
|
||||
@canPerm('users.delete')
|
||||
@if ($canManage && $u->id !== $me->id)
|
||||
<form method="POST" action="{{ route('admin.users.destroy', $u) }}" onsubmit="return confirm('确认删除该用户?')">@csrf @method('DELETE')<button class="btn btn-sm btn-danger"><x-icon name="trash" :size="16"/></button></form>
|
||||
@endif
|
||||
@endcanPerm
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="muted">暂无用户。</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $users->links('pagination::bootstrap-5') }}
|
||||
@endsection
|
||||
@@ -0,0 +1,59 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '技术文章 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">技术文章</h1>
|
||||
<p class="mt-2 text-sm text-muted">设计指南、应用笔记与行业方案解读。</p>
|
||||
</div>
|
||||
|
||||
<form method="GET" class="flex flex-wrap items-end gap-3">
|
||||
<div class="min-w-[220px] flex-1">
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">搜索</label>
|
||||
<div class="relative">
|
||||
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted">
|
||||
<x-icon name="search" :size="18" />
|
||||
</span>
|
||||
<input type="text" name="q" value="{{ $q }}" placeholder="搜索标题、摘要..." class="w-full rounded-lg border border-line bg-surface py-2.5 pl-10 pr-3 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full sm:w-56">
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">分类</label>
|
||||
<select name="category" onchange="this.form.submit()" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
<option value="">全部分类</option>
|
||||
@foreach ($categories as $c)
|
||||
<option value="{{ $c->id }}" @selected((int) $categoryId === $c->id)>{{ $c->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="search" :size="18" /> 查询
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-8 space-y-4">
|
||||
@forelse ($articles as $article)
|
||||
<a href="{{ route('articles.show', $article->slug) }}" class="group flex items-center justify-between gap-4 rounded-lg border border-line bg-surface p-5 shadow-soft transition hover:border-primary hover:shadow-card">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-fg transition group-hover:text-primary">{{ $article->title }}</h3>
|
||||
<p class="mt-1 line-clamp-2 text-sm text-muted">{{ $article->summary ?: Str::limit(strip_tags($article->body), 120) }}</p>
|
||||
<p class="mt-2 text-xs text-muted">{{ $article->published_at?->format('Y-m-d') }} · {{ $article->author ?: '云创芯' }}</p>
|
||||
</div>
|
||||
<span class="shrink-0 text-muted transition group-hover:text-primary">
|
||||
<x-icon name="arrow" :size="20" />
|
||||
</span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">暂无文章。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-8">
|
||||
{{ $articles->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,61 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '我的投稿')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-4xl">
|
||||
<div class="mb-6 flex flex-wrap items-center justify-between gap-3">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">我的投稿</h1>
|
||||
<a href="{{ route('articles.submit') }}" class="inline-flex items-center gap-1.5 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="plus" :size="16" /> 新投稿
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@if ($articles->isEmpty())
|
||||
<div class="rounded-lg border border-line bg-surface p-8 text-center shadow-soft">
|
||||
<p class="text-sm text-muted">你还没有投稿。</p>
|
||||
<a href="{{ route('articles.submit') }}" class="mt-3 inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">去投稿 →</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="overflow-hidden rounded-lg border border-line bg-surface shadow-soft">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="bg-surface-2 text-xs font-semibold text-muted">
|
||||
<tr>
|
||||
<th class="px-4 py-3">标题</th>
|
||||
<th class="px-4 py-3">状态</th>
|
||||
<th class="px-4 py-3">提交时间</th>
|
||||
<th class="px-4 py-3 text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-line">
|
||||
@foreach ($articles as $a)
|
||||
<tr class="transition hover:bg-surface">
|
||||
<td class="px-4 py-3 font-medium text-fg">{{ $a->title }}</td>
|
||||
<td class="px-4 py-3">
|
||||
@if ($a->status === 'approved')
|
||||
<span class="inline-flex items-center rounded-full bg-success-soft px-2.5 py-0.5 text-xs font-medium text-success">已发布</span>
|
||||
@elseif ($a->status === 'pending')
|
||||
<span class="inline-flex items-center rounded-full bg-warning-soft px-2.5 py-0.5 text-xs font-medium text-warning">待审</span>
|
||||
@elseif ($a->status === 'rejected')
|
||||
<span class="inline-flex items-center rounded-full bg-danger-soft px-2.5 py-0.5 text-xs font-medium text-danger">已驳回</span>
|
||||
@else
|
||||
<span class="inline-flex items-center rounded-full bg-surface-2 px-2.5 py-0.5 text-xs font-medium text-muted">草稿</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-muted">{{ $a->created_at?->format('Y-m-d H:i') }}</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<a href="{{ route('articles.show', $a->slug) }}" class="inline-flex items-center gap-1 rounded-lg border border-line px-3 py-1.5 text-xs font-medium text-fg transition hover:bg-surface-2 hover:text-primary">查看</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
{{ $articles->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,58 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@php $siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'); @endphp
|
||||
@section('title', $article->seoTitle() . ' - ' . $siteName)
|
||||
@section('description', $article->seoDescription())
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ url('/') }}" class="hover:text-primary">首页</a>
|
||||
<span>/</span>
|
||||
<a href="{{ route('articles.index') }}" class="hover:text-primary">技术文章</a>
|
||||
<span>/</span>
|
||||
<span class="text-fg">{{ $article->title }}</span>
|
||||
</nav>
|
||||
|
||||
@if ($article->template === 'feature' && $article->cover)
|
||||
<div class="mb-6 overflow-hidden rounded-lg border border-line">
|
||||
<img src="{{ $article->cover }}" alt="{{ $article->title }}" class="max-h-96 w-full object-cover">
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<article class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $article->title }}</h1>
|
||||
<p class="mt-3 text-sm text-muted">
|
||||
{{ $article->published_at?->format('Y-m-d') }} · {{ $article->author ?: '云创芯' }}
|
||||
@if ($article->template === 'tech') <span class="ml-2 rounded bg-primary-soft px-2 py-0.5 text-xs font-medium text-primary">技术文档</span> @endif
|
||||
@if ($article->template === 'feature') <span class="ml-2 rounded bg-primary-soft px-2 py-0.5 text-xs font-medium text-primary">专题报道</span> @endif
|
||||
</p>
|
||||
@if ($article->category)
|
||||
<p class="mt-2 text-sm text-muted">分类:{{ $article->category->name }}</p>
|
||||
@endif
|
||||
@if ($article->template === 'feature' && $article->summary)
|
||||
<p class="lead mt-5 text-base text-muted">{{ $article->summary }}</p>
|
||||
@elseif ($article->summary)
|
||||
<p class="mt-5 text-base text-muted">{{ $article->summary }}</p>
|
||||
@endif
|
||||
@if ($article->body)
|
||||
<div class="prose mt-6 text-fg">
|
||||
{{-- 旧文(纯文本)用 nl2br 换行,新文(Quill HTML)安全渲染(已过 Purifier) --}}
|
||||
@if (preg_match('/<[a-z][a-z0-9]*[\s>]/i', $article->body))
|
||||
{!! $article->body !!}
|
||||
@else
|
||||
{!! nl2br(e($article->body)) !!}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</article>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('articles.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">
|
||||
<x-icon name="arrow" :size="16" class="rotate-180" /> 返回文章列表
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,67 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '投稿文章')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">投稿文章</h1>
|
||||
<p class="mt-2 text-sm text-muted">提交后由管理员审核,审核通过前仅你自己可见。</p>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('articles.submit.store') }}" class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
@csrf
|
||||
<div class="space-y-5">
|
||||
<div>
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">标题</label>
|
||||
<input name="title" value="{{ old('title') }}" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">分类</label>
|
||||
<select name="category_id" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
<option value="">无分类</option>
|
||||
@foreach ($categories as $c)
|
||||
<option value="{{ $c->id }}" @selected(old('category_id') == $c->id)>{{ $c->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">摘要</label>
|
||||
<input name="summary" value="{{ old('summary') }}" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">正文</label>
|
||||
<x-rich-editor name="body" :value="old('body')" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">版式模板</label>
|
||||
<select name="template" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
@foreach (App\Models\Article::TEMPLATES as $key => $label)
|
||||
<option value="{{ $key }}" @selected(old('template', 'standard') === $key)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">封面图(可选,支持上传)</label>
|
||||
<input type="file" id="cover-file" accept="image/*" class="mb-2 block w-full text-sm">
|
||||
<div class="flex items-center gap-3">
|
||||
<input name="cover" id="cover-url" value="{{ old('cover') }}" placeholder="https://..." class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
<button type="button" class="inline-flex items-center justify-center rounded-lg border border-line bg-surface px-5 py-2.5 text-sm font-semibold text-fg transition hover:bg-surface-2" onclick="uploadFile('cover')">上传</button>
|
||||
</div>
|
||||
<p class="mt-1.5 text-xs text-muted">仅「专题报道」版式会使用封面图。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex items-center gap-3 border-t border-line pt-6">
|
||||
<button type="submit" class="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="send" :size="18" /> 提交投稿
|
||||
</button>
|
||||
<a href="{{ route('articles.index') }}" class="inline-flex items-center justify-center rounded-lg border border-line bg-surface px-5 py-2.5 text-sm font-semibold text-fg transition hover:bg-surface-2">
|
||||
取消
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,51 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '管理后台登录 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-md">
|
||||
<div class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<div class="mb-6 flex items-center gap-3">
|
||||
<span class="inline-flex h-11 w-11 items-center justify-center rounded-lg bg-primary-soft text-primary">
|
||||
<x-icon name="lock" :size="24" />
|
||||
</span>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg">管理后台登录</h1>
|
||||
<p class="text-sm text-muted">仅限具备后台权限的账户使用。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ url('/admin/login') }}" class="space-y-5">
|
||||
@csrf
|
||||
<div>
|
||||
<label for="email" class="mb-1.5 block text-sm font-medium text-fg">邮箱</label>
|
||||
<input id="email" name="email" type="email" value="{{ old('email') }}" required autofocus class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="mb-1.5 block text-sm font-medium text-fg">密码</label>
|
||||
<input id="password" name="password" type="password" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="captcha" class="mb-1.5 block text-sm font-medium text-fg">图形验证码</label>
|
||||
<div class="flex items-center gap-3">
|
||||
<input id="captcha" name="captcha" type="text" required autocomplete="off" maxlength="4" class="w-36 rounded-lg border border-line bg-surface px-3 py-2.5 text-sm uppercase tracking-widest text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
<img src="{{ url('/captcha') }}?r={{ time() }}" alt="图形验证码" title="看不清?点击刷新" id="captcha-img" onclick="this.src='{{ url('/captcha') }}?r='+Date.now()" class="h-11 cursor-pointer rounded-lg border border-line">
|
||||
</div>
|
||||
<p class="mt-1.5 text-xs text-muted">看不清?点击图片可刷新。连续输错 5 次将临时锁定 10 分钟。</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="checkbox" id="remember" name="remember" class="h-4 w-4 rounded border-line accent-primary">
|
||||
<label for="remember" class="text-sm text-fg">记住我</label>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="lock" :size="20" class="text-white" /> 进入后台
|
||||
</button>
|
||||
<p class="text-center text-sm text-muted">
|
||||
<a href="{{ url('/') }}" class="font-medium text-primary hover:text-primary-hover">返回网站首页</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,44 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '登录 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-md">
|
||||
<div class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg">登录</h1>
|
||||
<p class="mt-2 text-sm text-muted">欢迎回来,请登录您的账户。</p>
|
||||
|
||||
<form method="POST" action="{{ url('/login') }}" class="mt-6 space-y-5">
|
||||
@csrf
|
||||
<div>
|
||||
<label for="email" class="mb-1.5 block text-sm font-medium text-fg">邮箱</label>
|
||||
<input id="email" name="email" type="email" value="{{ old('email') }}" required autofocus class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="mb-1.5 block text-sm font-medium text-fg">密码</label>
|
||||
<input id="password" name="password" type="password" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="captcha" class="mb-1.5 block text-sm font-medium text-fg">图形验证码</label>
|
||||
<div class="flex items-center gap-3">
|
||||
<input id="captcha" name="captcha" type="text" required autocomplete="off" maxlength="4" class="w-36 rounded-lg border border-line bg-surface px-3 py-2.5 text-sm uppercase tracking-widest text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
<img src="{{ url('/captcha') }}?r={{ time() }}" alt="图形验证码" title="看不清?点击刷新" id="captcha-img" onclick="this.src='{{ url('/captcha') }}?r='+Date.now()" class="h-11 cursor-pointer rounded-lg border border-line">
|
||||
</div>
|
||||
<p class="mt-1.5 text-xs text-muted">看不清?点击图片可刷新。连续输错 5 次将临时锁定 10 分钟。</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="checkbox" id="remember" name="remember" class="h-4 w-4 rounded border-line accent-primary">
|
||||
<label for="remember" class="text-sm text-fg">记住我</label>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
登录
|
||||
</button>
|
||||
<p class="text-center text-sm text-muted">
|
||||
还没有账号?<a href="{{ url('/register') }}" class="font-medium text-primary hover:text-primary-hover">立即注册</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,56 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '注册 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-md">
|
||||
<div class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg">注册</h1>
|
||||
<p class="mt-2 text-sm text-muted">创建账户,参与论坛交流并投稿技术文章。</p>
|
||||
|
||||
<form method="POST" action="{{ url('/register') }}" class="mt-6 space-y-5">
|
||||
@csrf
|
||||
<div>
|
||||
<label for="name" class="mb-1.5 block text-sm font-medium text-fg">姓名</label>
|
||||
<input id="name" name="name" type="text" value="{{ old('name') }}" maxlength="40" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="mb-1.5 block text-sm font-medium text-fg">邮箱</label>
|
||||
<input id="email" name="email" type="email" value="{{ old('email') }}" maxlength="120" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="real_name" class="mb-1.5 block text-sm font-medium text-fg">真实姓名(选填)</label>
|
||||
<input id="real_name" name="real_name" type="text" value="{{ old('real_name') }}" maxlength="40" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="phone" class="mb-1.5 block text-sm font-medium text-fg">手机号(选填)</label>
|
||||
<input id="phone" name="phone" type="tel" value="{{ old('phone') }}" maxlength="30" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="company" class="mb-1.5 block text-sm font-medium text-fg">公司名称(选填)</label>
|
||||
<input id="company" name="company" type="text" value="{{ old('company') }}" maxlength="120" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="industry" class="mb-1.5 block text-sm font-medium text-fg">行业/领域(选填)</label>
|
||||
<input id="industry" name="industry" type="text" value="{{ old('industry') }}" maxlength="60" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="mb-1.5 block text-sm font-medium text-fg">密码(至少 8 位)</label>
|
||||
<input id="password" name="password" type="password" required autocomplete="new-password" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password_confirmation" class="mb-1.5 block text-sm font-medium text-fg">确认密码</label>
|
||||
<input id="password_confirmation" name="password_confirmation" type="password" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<button type="submit" class="inline-flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
注册
|
||||
</button>
|
||||
<p class="text-center text-sm text-muted">
|
||||
已有账号?<a href="{{ url('/login') }}" class="font-medium text-primary hover:text-primary-hover">去登录</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,50 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@php $siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'); @endphp
|
||||
|
||||
@section('title', '账户设置 - ' . $siteName)
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-2xl space-y-6">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">账户设置</h1>
|
||||
|
||||
<div class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h2 class="text-lg font-semibold text-fg">修改密码</h2>
|
||||
<form method="POST" action="{{ route('auth.settings.password') }}" class="mt-5 space-y-5">
|
||||
@csrf
|
||||
<div>
|
||||
<label for="current_password" class="mb-1.5 block text-sm font-medium text-fg">当前密码</label>
|
||||
<input id="current_password" type="password" name="current_password" autocomplete="current-password" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="mb-1.5 block text-sm font-medium text-fg">新密码</label>
|
||||
<input id="password" type="password" name="password" autocomplete="new-password" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="password_confirmation" class="mb-1.5 block text-sm font-medium text-fg">确认新密码</label>
|
||||
<input id="password_confirmation" type="password" name="password_confirmation" autocomplete="new-password" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
保存修改
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h2 class="text-lg font-semibold text-fg">我的等级 <x-level-badge :user="Auth::user()" /></h2>
|
||||
@php $progress = Auth::user()->levelProgress(); @endphp
|
||||
<p class="mt-3 text-sm text-fg">当前等级:<strong>L{{ $progress['level'] }} {{ Auth::user()->levelName() }}</strong></p>
|
||||
<p class="mt-1 text-sm text-muted">积分:{{ $progress['current'] }}</p>
|
||||
<div class="mt-2 h-2 w-full overflow-hidden rounded-full bg-surface-2">
|
||||
<div class="h-full rounded-full bg-primary" style="width:{{ $progress['percent'] }}%"></div>
|
||||
</div>
|
||||
@if ($progress['next'])
|
||||
<p class="mt-2 text-sm text-muted">距下一等级(L{{ $progress['level'] + 1 }})还需 {{ $progress['next'] - $progress['current'] }} 积分</p>
|
||||
@else
|
||||
<p class="mt-2 text-sm text-muted">已达到最高等级</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,46 @@
|
||||
@props(['name', 'size' => 20, 'class' => ''])
|
||||
|
||||
@php
|
||||
$icons = [
|
||||
'home' => '<path d="M3 11.5 12 4l9 7.5"/><path d="M5 10v10h14V10"/>',
|
||||
'user' => '<circle cx="12" cy="8" r="4"/><path d="M4 20a8 8 0 0 1 16 0"/>',
|
||||
'mail' => '<rect x="3" y="6" width="18" height="12" rx="2"/><path d="M3 7l9 6 9-6"/>',
|
||||
'phone' => '<path d="M5 4h4l2 5-3 2a12 12 0 0 0 5 5l2-3 5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z"/>',
|
||||
'search' => '<circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/>',
|
||||
'send' => '<path d="M3 11l18-8-8 18-2-8z"/>',
|
||||
'check' => '<path d="M5 13l4 4 10-10"/>',
|
||||
'alert' => '<path d="M10.3 4.3 2.5 18a2 2 0 0 0 1.7 3h15.6a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',
|
||||
'arrow' => '<path d="M5 12h14"/><path d="M13 6l6 6-6 6"/>',
|
||||
'shield' => '<path d="M12 3v18"/><path d="M5 7l7-4 7 4v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z"/>',
|
||||
'menu' => '<path d="M4 7h16"/><path d="M4 12h16"/><path d="M4 17h16"/>',
|
||||
'close' => '<path d="M6 6l12 12"/><path d="M18 6 6 18"/>',
|
||||
'box' => '<path d="M3 7l9-4 9 4v10l-9 4-9-4z"/><path d="M3 7l9 4 9-4"/><path d="M12 11v10"/>',
|
||||
'doc' => '<path d="M6 3h8l4 4v14H6z"/><path d="M14 3v4h4"/><path d="M9 12h6"/><path d="M9 16h6"/>',
|
||||
'book' => '<path d="M5 4h11a2 2 0 0 1 2 2v14H7a2 2 0 0 1-2-2z"/><path d="M5 4v14"/>',
|
||||
'chat' => '<path d="M4 5h16v11H9l-5 4z"/>',
|
||||
'pin' => '<path d="M12 21s7-6 7-11a7 7 0 1 0-14 0c0 5 7 11 7 11z"/><circle cx="12" cy="10" r="2.5"/>',
|
||||
'lock' => '<rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/>',
|
||||
'grid' => '<rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/>',
|
||||
'tag' => '<path d="M3 12V4h8l9 9-8 8z"/><circle cx="8" cy="8" r="1.5"/>',
|
||||
'users' => '<circle cx="9" cy="8" r="3.5"/><path d="M3 20a6 6 0 0 1 12 0"/><path d="M16 4a3.5 3.5 0 0 1 0 7"/><path d="M17 14a6 6 0 0 1 4 6"/>',
|
||||
'plus' => '<path d="M12 5v14"/><path d="M5 12h14"/>',
|
||||
'edit' => '<path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M14 5l4 4"/>',
|
||||
'trash' => '<path d="M4 7h16"/><path d="M9 7V4h6v3"/><path d="M6 7l1 13h10l1-13"/>',
|
||||
'settings' => '<circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M19.1 4.9 17 7M7 17l-2.1 2.1"/>',
|
||||
'database' => '<ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v14c0 1.7 3.6 3 8 3s8-1.3 8-3V5"/><path d="M4 12c0 1.7 3.6 3 8 3s8-1.3 8-3"/>',
|
||||
'compass' => '<circle cx="12" cy="12" r="9"/><path d="M15 9l-2.5 5L7 16.5 9.5 11z"/>',
|
||||
'newspaper' => '<path d="M4 4h13v16H6a2 2 0 0 1-2-2z"/><path d="M17 8h3v10a2 2 0 0 1-2 2"/><path d="M7 8h7M7 12h7M7 16h5"/>',
|
||||
'zap' => '<path d="M13 2 4 14h7l-1 8 9-12h-7z"/>',
|
||||
'cpu' => '<rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3"/>',
|
||||
'layers' => '<path d="M12 3 3 8l9 5 9-5z"/><path d="M3 13l9 5 9-5"/>',
|
||||
'globe' => '<circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3a14 14 0 0 1 0 18 14 14 0 0 1 0-18z"/>',
|
||||
'link' => '<path d="M9 12h6"/><path d="M10 8H7a4 4 0 0 0 0 8h3"/><path d="M14 8h3a4 4 0 0 1 0 8h-3"/>',
|
||||
'arrowUpRight' => '<path d="M7 17 17 7"/><path d="M8 7h9v9"/>',
|
||||
'wechat' => '<path d="M8 4C4.5 4 2 6.4 2 9.2c0 1.6.9 3 2.3 4L4 16l3.2-1.6c.6.2 1.3.3 2 .3"/><path d="M21 13.5c0-2.1-2-3.8-4.4-3.8s-4.4 1.7-4.4 3.8 2 3.8 4.4 3.8c.5 0 1-.1 1.5-.2L20 18l-.5-1.5c1.1-.7 1.5-1.7 1.5-3z"/>',
|
||||
'weibo' => '<circle cx="9" cy="14" r="5"/><path d="M16 6a4 4 0 0 1 4 4"/><path d="M15.5 3.5a6 6 0 0 1 6 6"/>',
|
||||
'linkedin' => '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M7 10v7M7 7v.01M11 17v-4a2 2 0 0 1 4 0v4M11 10v7"/>',
|
||||
];
|
||||
$paths = $icons[$name] ?? $icons['home'];
|
||||
@endphp
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="{{ $size }}" height="{{ $size }}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="{{ $class }}" aria-hidden="true" role="img">{!! $paths !!}</svg>
|
||||
@@ -0,0 +1,8 @@
|
||||
@props(['user' => null])
|
||||
|
||||
@if ($user)
|
||||
@php $l = $user->level(); @endphp
|
||||
<span class="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-semibold @if($l <= 1) bg-surface-2 text-muted @elseif($l === 2) bg-info-soft text-info @elseif($l === 3) bg-primary-soft text-primary @elseif($l === 4) bg-warning-soft text-warning @else bg-danger-soft text-danger @endif" title="会员等级 L{{ $l }}">
|
||||
L{{ $l }} {{ $user->levelName() }}
|
||||
</span>
|
||||
@endif
|
||||
@@ -0,0 +1,95 @@
|
||||
@props(['name' => 'body', 'value' => ''])
|
||||
|
||||
{{-- Quill 富文本编辑器(本地化,零构建,不依赖外部 CDN)。提交前把 HTML 同步进隐藏 textarea。 --}}
|
||||
<link rel="stylesheet" href="{{ asset('vendor/quill/quill.snow.css') }}">
|
||||
<div class="rich-editor">
|
||||
<div id="quill-{{ $name }}"></div>
|
||||
</div>
|
||||
<textarea name="{{ $name }}" id="quill-input-{{ $name }}" hidden>{{ $value }}</textarea>
|
||||
|
||||
<script src="{{ asset('vendor/quill/quill.js') }}"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var FIELD = '{{ $name }}';
|
||||
var input = document.getElementById('quill-input-' + FIELD);
|
||||
if (typeof Quill === 'undefined' || !input) return;
|
||||
|
||||
var quill = new Quill('#quill-' + FIELD, {
|
||||
theme: 'snow',
|
||||
placeholder: '在此撰写文章正文,支持标题、列表、引用、代码与插入图片…',
|
||||
modules: {
|
||||
toolbar: {
|
||||
container: [
|
||||
[{ header: [1, 2, 3, false] }],
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['clean']
|
||||
],
|
||||
handlers: { image: imageHandler }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quill.root.innerHTML = input.value || '';
|
||||
|
||||
var form = input.closest('form');
|
||||
if (form) {
|
||||
form.addEventListener('submit', function () {
|
||||
input.value = quill.root.innerHTML;
|
||||
});
|
||||
}
|
||||
|
||||
function imageHandler() {
|
||||
var fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = 'image/*';
|
||||
fileInput.click();
|
||||
fileInput.onchange = function () {
|
||||
if (!fileInput.files.length) return;
|
||||
var fd = new FormData();
|
||||
fd.append('file', fileInput.files[0]);
|
||||
var token = (document.querySelector('input[name=_token]') || {}).value || '';
|
||||
fetch('{{ route('upload') }}', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-TOKEN': token },
|
||||
body: fd
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
if (d.url) {
|
||||
var range = quill.getSelection(true);
|
||||
quill.insertEmbed(range.index, 'image', d.url, 'user');
|
||||
} else if (d.errors && d.errors.file) {
|
||||
alert(d.errors.file[0]);
|
||||
} else {
|
||||
alert('图片上传失败,请重试');
|
||||
}
|
||||
})
|
||||
.catch(function () { alert('图片上传失败,请重试'); });
|
||||
};
|
||||
}
|
||||
|
||||
// 通用文件上传(封面图等),供表单内上传按钮 onclick="uploadFile('cover')" 调用
|
||||
window.uploadFile = function (field) {
|
||||
var fileInput = document.getElementById(field + '-file');
|
||||
if (!fileInput || !fileInput.files.length) { alert('请先选择文件'); return; }
|
||||
var fd = new FormData();
|
||||
fd.append('file', fileInput.files[0]);
|
||||
var token = (document.querySelector('input[name=_token]') || {}).value || '';
|
||||
fetch('{{ route('upload') }}', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-TOKEN': token },
|
||||
body: fd
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
if (d.url) { document.getElementById(field + '-url').value = d.url; }
|
||||
else if (d.errors && d.errors.file) { alert(d.errors.file[0]); }
|
||||
else { alert('上传失败,请重试'); }
|
||||
})
|
||||
.catch(function () { alert('上传失败,请重试'); });
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
@@ -0,0 +1,136 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '联系我们 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
{{-- Hero --}}
|
||||
<section class="hero-aurora relative">
|
||||
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-16 lg:py-24">
|
||||
<div class="reveal max-w-2xl">
|
||||
<span class="eyebrow">联系我们</span>
|
||||
<h1 class="mt-4 text-3xl font-extrabold tracking-tight gradient-text sm:text-4xl lg:text-5xl">携手共创 TypeC 快速充电未来</h1>
|
||||
<p class="mt-4 text-base leading-relaxed text-muted">无论是方案选型、样品申请还是技术合作,留下联系方式,我们的方案团队将在 1 个工作日内与你对接。</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 联络方式 + 表单 --}}
|
||||
<section class="section px-4 sm:px-6 lg:px-8 -mt-10 lg:-mt-16">
|
||||
<div class="mx-auto max-w-6xl">
|
||||
<div class="grid gap-8 lg:grid-cols-5">
|
||||
<!-- 左栏:联络方式 -->
|
||||
<div class="reveal lg:col-span-2 glow-card rounded-2xl p-6 sm:p-8">
|
||||
<h2 class="text-lg font-semibold text-fg">我们的联络方式</h2>
|
||||
<p class="mt-1 text-sm text-muted">深圳市云创芯电子有限公司 · 专注于多口 TypeC 接口 IC。</p>
|
||||
|
||||
<ul class="mt-6 space-y-5">
|
||||
<li class="flex items-start gap-3">
|
||||
<x-icon name="box" :size="22" class="mt-0.5 shrink-0 text-primary" />
|
||||
<div>
|
||||
<p class="text-sm font-medium text-muted">公司名称</p>
|
||||
<p class="text-base font-semibold text-fg">深圳市云创芯电子有限公司</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<x-icon name="mail" :size="22" class="mt-0.5 shrink-0 text-primary" />
|
||||
<div>
|
||||
<p class="text-sm font-medium text-muted">电子邮箱</p>
|
||||
<a href="mailto:service@51chip.net" class="text-base font-semibold text-fg transition-colors hover:text-primary">service@51chip.net</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<x-icon name="phone" :size="22" class="mt-0.5 shrink-0 text-primary" />
|
||||
<div>
|
||||
<p class="text-sm font-medium text-muted">联系电话</p>
|
||||
<a href="tel:13510116819" class="text-base font-semibold text-fg transition-colors hover:text-primary">13510116819</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<x-icon name="pin" :size="22" class="mt-0.5 shrink-0 text-primary" />
|
||||
<div>
|
||||
<p class="text-sm font-medium text-muted">地址</p>
|
||||
<p class="text-base font-semibold text-fg">深圳市南山区科技园</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 右栏:留言表单(服务端渲染,无需 JS 即可提交) -->
|
||||
<div class="reveal lg:col-span-3 glow-card rounded-2xl p-6 sm:p-8">
|
||||
<h2 class="text-lg font-semibold text-fg">商务合作表单</h2>
|
||||
<p class="mt-1 text-sm text-muted">提交后我们会在 1 个工作日内回复。</p>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="mt-6 rounded-lg border border-success bg-success-soft px-4 py-3 text-sm text-success">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ url('/contact') }}" class="mt-6 space-y-4" novalidate>
|
||||
@csrf
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label for="name" class="mb-1.5 block text-sm font-medium text-fg">姓名 <span class="text-danger">*</span></label>
|
||||
<input id="name" name="name" type="text" maxlength="40" value="{{ old('name') }}" required
|
||||
class="w-full rounded-lg border {{ $errors->has('name') ? 'border-danger' : 'border-line' }} bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
@error('name')
|
||||
<p class="mt-1 text-sm text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label for="company" class="mb-1.5 block text-sm font-medium text-fg">公司</label>
|
||||
<input id="company" name="company" type="text" maxlength="120" value="{{ old('company') }}"
|
||||
class="w-full rounded-lg border {{ $errors->has('company') ? 'border-danger' : 'border-line' }} bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
@error('company')
|
||||
<p class="mt-1 text-sm text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label for="phone" class="mb-1.5 block text-sm font-medium text-fg">电话</label>
|
||||
<input id="phone" name="phone" type="text" maxlength="20" value="{{ old('phone') }}"
|
||||
class="w-full rounded-lg border {{ $errors->has('phone') ? 'border-danger' : 'border-line' }} bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
@error('phone')
|
||||
<p class="mt-1 text-sm text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="mb-1.5 block text-sm font-medium text-fg">邮箱 <span class="text-danger">*</span></label>
|
||||
<input id="email" name="email" type="email" maxlength="120" value="{{ old('email') }}" required
|
||||
class="w-full rounded-lg border {{ $errors->has('email') ? 'border-danger' : 'border-line' }} bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
@error('email')
|
||||
<p class="mt-1 text-sm text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="subject" class="mb-1.5 block text-sm font-medium text-fg">主题 <span class="text-danger">*</span></label>
|
||||
<input id="subject" name="subject" type="text" maxlength="80" value="{{ old('subject') }}" required
|
||||
class="w-full rounded-lg border {{ $errors->has('subject') ? 'border-danger' : 'border-line' }} bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
@error('subject')
|
||||
<p class="mt-1 text-sm text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="message" class="mb-1.5 block text-sm font-medium text-fg">需求描述 <span class="text-danger">*</span></label>
|
||||
<textarea id="message" name="message" maxlength="1000" rows="4" required
|
||||
class="w-full rounded-lg border {{ $errors->has('message') ? 'border-danger' : 'border-line' }} bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">{{ old('message') }}</textarea>
|
||||
@error('message')
|
||||
<p class="mt-1 text-sm text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<button type="submit" class="cta-glow inline-flex w-full items-center justify-center gap-2 rounded-lg px-5 py-3 text-sm font-semibold">
|
||||
提交需求 <x-icon name="send" :size="18" />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,75 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $board->name . ' - 论坛')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-5xl">
|
||||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ route('forum.index') }}" class="hover:text-primary">论坛</a>
|
||||
<span>/</span>
|
||||
<span class="text-fg">{{ $board->name }}</span>
|
||||
</nav>
|
||||
|
||||
<div class="mb-6 flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $board->name }}</h1>
|
||||
<p class="mt-2 text-sm text-muted">{{ $board->description }}</p>
|
||||
</div>
|
||||
@auth
|
||||
<a href="#new-thread" class="inline-flex items-center gap-1.5 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="plus" :size="16" /> 发起帖子
|
||||
</a>
|
||||
@else
|
||||
<a href="{{ route('login') }}" class="inline-flex items-center gap-1.5 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
登录后发帖
|
||||
</a>
|
||||
@endauth
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
@forelse ($threads as $thread)
|
||||
<a href="{{ route('forum.thread', $thread) }}" class="group flex items-center justify-between gap-4 rounded-lg border border-line bg-surface p-5 shadow-soft transition hover:border-primary hover:shadow-card">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-fg transition group-hover:text-primary">
|
||||
@if ($thread->is_pinned)<x-icon name="pin" :size="14" class="text-warning" /> @endif
|
||||
{{ $thread->title }}
|
||||
</h3>
|
||||
<p class="mt-1 text-xs text-muted">{{ $thread->user->name }} · {{ $thread->created_at->format('Y-m-d') }} · {{ $thread->views }} 浏览</p>
|
||||
</div>
|
||||
<span class="shrink-0 text-muted transition group-hover:text-primary">
|
||||
<x-icon name="arrow" :size="20" />
|
||||
</span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">该版块还没有帖子。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-8">
|
||||
{{ $threads->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
|
||||
@auth
|
||||
<div id="new-thread" class="mt-8 rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h2 class="text-lg font-semibold text-fg">发起新帖</h2>
|
||||
<form method="POST" action="{{ route('forum.threads.store') }}" class="mt-5 space-y-5">
|
||||
@csrf
|
||||
<input type="hidden" name="board_id" value="{{ $board->id }}">
|
||||
<div>
|
||||
<label for="title" class="mb-1.5 block text-sm font-medium text-fg">标题</label>
|
||||
<input id="title" type="text" name="title" maxlength="120" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<div>
|
||||
<label for="body" class="mb-1.5 block text-sm font-medium text-fg">内容</label>
|
||||
<textarea id="body" name="body" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="send" :size="18" /> 发布
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endauth
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,44 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '技术论坛 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">技术论坛</h1>
|
||||
<p class="mt-2 text-sm text-muted">与工程师交流选型、调试与量产经验。</p>
|
||||
</div>
|
||||
|
||||
@guest
|
||||
<div class="mb-8 flex flex-col gap-4 rounded-lg border border-line bg-surface p-5 shadow-soft sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="inline-flex h-11 w-11 items-center justify-center rounded-lg bg-primary-soft text-primary">
|
||||
<x-icon name="chat" :size="24" />
|
||||
</span>
|
||||
<p class="text-lg text-fg">登录后即可参与版块讨论、发帖与回复。</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ url('/login') }}" class="inline-flex items-center justify-center rounded-lg border border-line px-6 py-2.5 text-lg font-semibold text-fg transition hover:border-primary hover:text-primary">登录</a>
|
||||
<a href="{{ url('/register') }}" class="inline-flex items-center justify-center rounded-lg bg-primary px-6 py-2.5 text-lg font-semibold text-white transition hover:bg-primary-hover">注册</a>
|
||||
</div>
|
||||
</div>
|
||||
@endguest
|
||||
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@forelse ($boards as $board)
|
||||
<a href="{{ route('forum.board', $board->slug) }}" class="group flex flex-col rounded-lg border border-line bg-surface p-6 shadow-soft transition hover:-translate-y-0.5 hover:border-primary hover:shadow-card">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary">
|
||||
<x-icon name="chat" :size="22" />
|
||||
</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $board->name }}</h3>
|
||||
<p class="mt-2 line-clamp-2 text-sm text-muted">{{ $board->description }}</p>
|
||||
<p class="mt-4 text-xs text-muted">{{ $board->threads_count }} 个帖子</p>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">版块即将开放,敬请期待。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,68 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $thread->title . ' - 论坛')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ route('forum.index') }}" class="hover:text-primary">论坛</a>
|
||||
<span>/</span>
|
||||
<a href="{{ route('forum.board', $thread->board->slug) }}" class="hover:text-primary">{{ $thread->board->name }}</a>
|
||||
<span>/</span>
|
||||
<span class="text-fg">{{ $thread->title }}</span>
|
||||
</nav>
|
||||
|
||||
<article class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $thread->title }}</h1>
|
||||
<p class="mt-3 text-xs text-muted">{{ $thread->user?->name }} · {{ $thread->created_at->format('Y-m-d H:i') }} · {{ $thread->views }} 浏览 <x-level-badge :user="$thread->user" /></p>
|
||||
<div class="prose mt-5 text-fg">
|
||||
{!! nl2br(e($thread->body)) !!}
|
||||
</div>
|
||||
@if ($thread->is_locked)
|
||||
<p class="mt-4 flex items-center gap-2 rounded-lg border border-danger bg-danger-soft px-4 py-3 text-sm text-danger">
|
||||
<x-icon name="lock" :size="16" /> 该帖子已锁定,无法回复。
|
||||
</p>
|
||||
@endif
|
||||
</article>
|
||||
|
||||
<h2 class="mb-4 mt-10 text-lg font-semibold text-fg">回复({{ $replies->total() }})</h2>
|
||||
<div class="space-y-4">
|
||||
@forelse ($replies as $reply)
|
||||
<div class="rounded-lg border border-line bg-surface p-5 shadow-soft">
|
||||
<div class="text-xs text-muted">{{ $reply->user?->name }} · {{ $reply->created_at->format('Y-m-d H:i') }} <x-level-badge :user="$reply->user" /></div>
|
||||
<div class="prose mt-2 text-fg">
|
||||
{!! nl2br(e($reply->body)) !!}
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-muted">还没有回复。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-8">
|
||||
{{ $replies->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
|
||||
@auth
|
||||
@unless ($thread->is_locked)
|
||||
<div class="mt-8 rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h3 class="text-lg font-semibold text-fg">发表回复</h3>
|
||||
<form method="POST" action="{{ route('forum.replies.store', $thread) }}" class="mt-5 space-y-5">
|
||||
@csrf
|
||||
<div>
|
||||
<label for="reply-body" class="mb-1.5 block text-sm font-medium text-fg">内容</label>
|
||||
<textarea id="reply-body" name="body" required class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="send" :size="18" /> 回复
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endunless
|
||||
@else
|
||||
<p class="mt-8 text-sm text-muted"><a href="{{ route('login') }}" class="font-medium text-primary hover:text-primary-hover">登录</a> 后参与回复。</p>
|
||||
@endauth
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,49 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '术语库 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">术语库</h1>
|
||||
<p class="mt-2 text-sm text-muted">PD / PHY / 快充协议关键术语速查。</p>
|
||||
</div>
|
||||
|
||||
<form method="GET" class="flex flex-wrap items-end gap-3">
|
||||
<div class="min-w-[220px] flex-1">
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">搜索</label>
|
||||
<div class="relative">
|
||||
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted">
|
||||
<x-icon name="search" :size="18" />
|
||||
</span>
|
||||
<input type="text" name="q" value="{{ $q }}" placeholder="搜索术语、定义..." class="w-full rounded-lg border border-line bg-surface py-2.5 pl-10 pr-3 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="search" :size="18" /> 查询
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-8 space-y-4">
|
||||
@forelse ($terms as $term)
|
||||
<a href="{{ route('glossary.show', $term->slug) }}" class="group flex items-center justify-between gap-4 rounded-lg border border-line bg-surface p-5 shadow-soft transition hover:border-primary hover:shadow-card">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-fg transition group-hover:text-primary">{{ $term->term }}</h3>
|
||||
<p class="mt-1 line-clamp-2 text-sm text-muted">{{ Str::limit($term->definition, 90) }}</p>
|
||||
</div>
|
||||
<span class="shrink-0 text-muted transition group-hover:text-primary">
|
||||
<x-icon name="arrow" :size="20" />
|
||||
</span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">没有匹配的术语。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-8">
|
||||
{{ $terms->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,36 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $glossaryTerm->term . ' - 云创芯术语库')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ url('/') }}" class="hover:text-primary">首页</a>
|
||||
<span>/</span>
|
||||
<a href="{{ route('glossary.index') }}" class="hover:text-primary">术语库</a>
|
||||
<span>/</span>
|
||||
<span class="text-fg">{{ $glossaryTerm->term }}</span>
|
||||
</nav>
|
||||
|
||||
<article class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $glossaryTerm->term }}</h1>
|
||||
@if ($glossaryTerm->category)
|
||||
<p class="mt-2 text-sm text-muted">分类:{{ $glossaryTerm->category }}</p>
|
||||
@endif
|
||||
<div class="prose mt-5 text-fg">
|
||||
{!! nl2br(e($glossaryTerm->definition)) !!}
|
||||
</div>
|
||||
@if ($glossaryTerm->aliases)
|
||||
<p class="mt-4 text-sm text-muted">别名:{{ $glossaryTerm->aliases }}</p>
|
||||
@endif
|
||||
</article>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('glossary.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">
|
||||
<x-icon name="arrow" :size="16" class="rotate-180" /> 返回术语库
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,235 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
{{-- Hero:由后台「首页轮播」管理(富文本 + 双 CTA);mode=carousel 轮播,mode=single 独立单图 --}}
|
||||
<section class="relative overflow-hidden bg-gradient-to-br from-primary to-primary-hover text-white">
|
||||
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-20 lg:py-28">
|
||||
@if ($heroSlides->isEmpty())
|
||||
<p class="text-white/80">尚未配置首页轮播内容,请到后台「首页轮播」添加。</p>
|
||||
@elseif ($heroMode === 'single')
|
||||
@include('partials.hero-slide', ['slide' => $heroSlides->first()])
|
||||
@else
|
||||
<div class="hero-carousel" data-hero>
|
||||
<div class="hero-track">
|
||||
@foreach ($heroSlides as $slide)
|
||||
<div class="hero-slide @if ($loop->first) is-active @endif" data-index="{{ $loop->index }}">
|
||||
@include('partials.hero-slide', ['slide' => $slide])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@if ($heroSlides->count() > 1)
|
||||
<button type="button" class="hero-arrow hero-prev" aria-label="上一条" data-prev>‹</button>
|
||||
<button type="button" class="hero-arrow hero-next" aria-label="下一条" data-next>›</button>
|
||||
<div class="hero-dots">
|
||||
@foreach ($heroSlides as $slide)
|
||||
<button type="button" class="hero-dot @if ($loop->first) is-active @endif" data-dot="{{ $loop->index }}" aria-label="第 {{ $loop->index + 1 }} 条"></button>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 核心产品 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">核心产品</h2>
|
||||
<p class="mt-1 text-sm text-muted">覆盖多口 TypeC 接口、协议转换与同步整流控制芯片</p>
|
||||
</div>
|
||||
<a href="{{ url('/products') }}" class="text-sm font-medium text-primary hover:underline">查看全部产品 →</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@forelse ($products as $product)
|
||||
<a href="{{ route('products.show', $product->slug) }}" class="group flex flex-col rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-block w-fit rounded bg-primary-soft px-2 py-1 font-mono text-xs font-medium text-primary">{{ $product->model ?: $product->slug }}</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $product->name }}</h3>
|
||||
<p class="mt-2 line-clamp-3 text-sm text-muted">{{ $product->summary ?: Str::limit(strip_tags($product->description), 90) }}</p>
|
||||
<span class="mt-4 inline-flex items-center gap-1 text-sm font-medium text-primary">
|
||||
查看详情 <x-icon name="arrow" :size="16" />
|
||||
</span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">产品正在整理中,敬请期待。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 解决方案 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">解决方案</h2>
|
||||
<p class="mt-1 text-sm text-muted">覆盖 30W–140W 多功率段与多场景的快充参考设计</p>
|
||||
</div>
|
||||
<a href="{{ url('/solutions') }}" class="text-sm font-medium text-primary hover:underline">查看全部方案 →</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
@forelse ($solutions as $solution)
|
||||
<a href="{{ route('solutions.show', $solution->slug) }}" class="group flex flex-col rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-block w-fit rounded bg-primary-soft px-2 py-1 font-mono text-xs font-medium text-primary">{{ $solution->power }}</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $solution->name }}</h3>
|
||||
<p class="mt-2 line-clamp-3 text-sm text-muted">{{ $solution->summary }}</p>
|
||||
<span class="mt-4 inline-flex items-center gap-1 text-sm font-medium text-primary">
|
||||
查看详情 <x-icon name="arrow" :size="16" />
|
||||
</span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">方案正在整理中,敬请期待。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 技术文章 --}}
|
||||
@if ($articles->isNotEmpty())
|
||||
<section class="border-t border-line bg-surface px-4 py-14 sm:px-6 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">技术文章</h2>
|
||||
<p class="mt-1 text-sm text-muted">设计指南、应用笔记与行业方案解读</p>
|
||||
</div>
|
||||
<a href="{{ url('/articles') }}" class="text-sm font-medium text-primary hover:underline">浏览全部文章 →</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@foreach ($articles as $article)
|
||||
<a href="{{ route('articles.show', $article->slug) }}" class="group flex flex-col rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary">
|
||||
<x-icon name="doc" :size="22" />
|
||||
</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $article->title }}</h3>
|
||||
<p class="mt-2 line-clamp-3 text-sm text-muted">{{ $article->summary ?: Str::limit(strip_tags($article->body), 90) }}</p>
|
||||
<span class="mt-4 text-xs text-muted">{{ $article->published_at?->format('Y-m-d') }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
{{-- 新闻动态 --}}
|
||||
@if ($news->isNotEmpty())
|
||||
<section class="border-t border-line bg-surface px-4 py-14 sm:px-6 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">新闻动态</h2>
|
||||
<p class="mt-1 text-sm text-muted">行业资讯、公司动态与展会活动</p>
|
||||
</div>
|
||||
<a href="{{ url('/news') }}" class="text-sm font-medium text-primary hover:underline">浏览全部新闻 →</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@foreach ($news as $item)
|
||||
<a href="{{ route('news.show', $item->slug) }}" class="group flex flex-col rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-block w-fit rounded bg-primary-soft px-2 py-1 font-mono text-xs font-medium text-primary">{{ $item->categoryLabel() }}</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $item->title }}</h3>
|
||||
<p class="mt-2 line-clamp-3 text-sm text-muted">{{ $item->summary }}</p>
|
||||
<span class="mt-4 text-xs text-muted">{{ $item->published_at?->format('Y-m-d') }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
{{-- 能力与资源 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<h2 class="text-2xl font-bold tracking-tight text-fg">能力与资源</h2>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<a href="{{ url('/products') }}" class="group rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="box" :size="22" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">产品中心</h3>
|
||||
<p class="mt-1 text-sm text-muted">多口 TypeC 接口IC 完整选型。</p>
|
||||
</a>
|
||||
<a href="{{ url('/articles') }}" class="group rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="doc" :size="22" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">技术文章</h3>
|
||||
<p class="mt-1 text-sm text-muted">设计指南、应用笔记与方案解读。</p>
|
||||
</a>
|
||||
<a href="{{ url('/glossary') }}" class="group rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="book" :size="22" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">术语库</h3>
|
||||
<p class="mt-1 text-sm text-muted">PD / PHY / 快充协议关键术语速查。</p>
|
||||
</a>
|
||||
<a href="{{ url('/forum') }}" class="group rounded-xl border border-line bg-surface p-6 shadow-card transition hover:-translate-y-0.5 hover:shadow-lg">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="chat" :size="22" /></span>
|
||||
<h3 class="mt-4 font-semibold text-fg">技术论坛</h3>
|
||||
<p class="mt-1 text-sm text-muted">与工程师交流选型、调试与量产经验。</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- CTA 条 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 pb-16">
|
||||
<div class="max-w-8xl mx-auto rounded-2xl bg-surface-2 px-6 py-10 text-center sm:px-10">
|
||||
<h2 class="text-xl font-bold tracking-tight text-fg sm:text-2xl">需要选型支持或样品申请?</h2>
|
||||
<p class="mt-2 text-sm text-muted">我们的应用工程师可协助您完成方案评估与量产导入。</p>
|
||||
<a href="{{ url('/contact') }}" class="mt-6 inline-flex items-center gap-2 rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
联系我们 <x-icon name="arrow" :size="18" />
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var carousels = document.querySelectorAll('[data-hero]');
|
||||
carousels.forEach(function (root) {
|
||||
var slides = Array.prototype.slice.call(root.querySelectorAll('.hero-slide'));
|
||||
var dots = Array.prototype.slice.call(root.querySelectorAll('.hero-dot'));
|
||||
if (slides.length < 2) return;
|
||||
|
||||
var current = 0;
|
||||
var timer = null;
|
||||
var INTERVAL = 6000;
|
||||
|
||||
function show(index) {
|
||||
current = (index + slides.length) % slides.length;
|
||||
slides.forEach(function (s, i) {
|
||||
s.classList.toggle('is-active', i === current);
|
||||
});
|
||||
dots.forEach(function (d, i) {
|
||||
d.classList.toggle('is-active', i === current);
|
||||
});
|
||||
}
|
||||
|
||||
function next() { show(current + 1); }
|
||||
function prev() { show(current - 1); }
|
||||
|
||||
function start() {
|
||||
stop();
|
||||
timer = setInterval(next, INTERVAL);
|
||||
}
|
||||
function stop() {
|
||||
if (timer) { clearInterval(timer); timer = null; }
|
||||
}
|
||||
|
||||
root.querySelector('[data-next]').addEventListener('click', function () { next(); start(); });
|
||||
root.querySelector('[data-prev]').addEventListener('click', function () { prev(); start(); });
|
||||
dots.forEach(function (d) {
|
||||
d.addEventListener('click', function () {
|
||||
show(parseInt(d.getAttribute('data-dot'), 10));
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
root.addEventListener('mouseenter', stop);
|
||||
root.addEventListener('mouseleave', start);
|
||||
|
||||
show(0);
|
||||
start();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,299 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
@php
|
||||
$siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司');
|
||||
$seoTitleDefault = App\Models\Setting::get('seo_title_default', $siteName . ' - 多口 TypeC 接口IC');
|
||||
$seoDescDefault = App\Models\Setting::get('seo_description_default', '深圳市云创芯电子有限公司提供多口 TypeC 接口IC。');
|
||||
$logoUrl = '/images/logo-dark.png'; // 固定品牌 logo,直接指向深色版,不依赖数据库设置(避免服务器库未同步导致回退旧 logo)
|
||||
$faviconUrl = App\Models\Setting::get('favicon_url', '/images/ccc-icon.ico');
|
||||
$icpNo = App\Models\Setting::get('icp_no', '');
|
||||
$securityFilingNo = App\Models\Setting::get('security_filing_no', '粤公网安备44030002015390号');
|
||||
|
||||
// 主题配色:后台「站点设置」可切换;默认 azure(沉稳蓝)
|
||||
$themes = [
|
||||
'azure' => ['primary' => '#4a8af4', 'hover' => '#76a9f7', 'accent' => '#6fa8f7', 'info' => '#4a8af4', 'rgb' => '74,138,244'],
|
||||
'slate' => ['primary' => '#6e8cb0', 'hover' => '#8aa6c6', 'accent' => '#7d98ba', 'info' => '#6e8cb0', 'rgb' => '110,140,176'],
|
||||
'indigo' => ['primary' => '#7b7ef0', 'hover' => '#9b9df6', 'accent' => '#8f86f2', 'info' => '#7b7ef0', 'rgb' => '123,126,240'],
|
||||
'teal' => ['primary' => '#2bb6a4', 'hover' => '#4fd0bd', 'accent' => '#34c0ad', 'info' => '#2bb6a4', 'rgb' => '43,182,164'],
|
||||
'amber' => ['primary' => '#e8a13c', 'hover' => '#f2b765', 'accent' => '#ecae52', 'info' => '#e8a13c', 'rgb' => '232,161,60'],
|
||||
];
|
||||
$themeKey = App\Models\Setting::get('theme', 'azure');
|
||||
$theme = $themes[$themeKey] ?? $themes['azure'];
|
||||
@endphp
|
||||
<title>@yield('title', $seoTitleDefault)</title>
|
||||
<meta name="description" content="@yield('description', $seoDescDefault)">
|
||||
<link rel="canonical" href="{{ url()->current() }}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:site_name" content="{{ $siteName }}">
|
||||
<meta property="og:title" content="@yield('title', $seoTitleDefault)">
|
||||
<meta property="og:description" content="@yield('description', $seoDescDefault)">
|
||||
<meta property="og:url" content="{{ url()->current() }}">
|
||||
<meta property="og:image" content="{{ asset($logoUrl) }}">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="@yield('title', $seoTitleDefault)">
|
||||
<meta name="twitter:description" content="@yield('description', $seoDescDefault)">
|
||||
<meta name="twitter:image" content="{{ asset($logoUrl) }}">
|
||||
<link rel="icon" href="{{ asset($faviconUrl) }}" sizes="any">
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}?v={{ filemtime(public_path('css/app.css')) }}">
|
||||
<!-- 主题配色覆盖:由后台「站点设置 → 主题」选择,注入后覆盖 app.css 默认 :root 变量(主色 + 光晕同步联动) -->
|
||||
<style id="theme-override">
|
||||
:root {
|
||||
--color-primary: {{ $theme['primary'] }};
|
||||
--color-primary-hover: {{ $theme['hover'] }};
|
||||
--color-accent: {{ $theme['accent'] }};
|
||||
--color-info: {{ $theme['info'] }};
|
||||
--glow-color: {{ $theme['rgb'] }};
|
||||
}
|
||||
</style>
|
||||
<!-- Tailwind Play CDN(零构建);颜色全部映射到 :root CSS 变量,源码不硬编码颜色 -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'var(--color-primary)',
|
||||
'primary-hover': 'var(--color-primary-hover)',
|
||||
'primary-soft': 'var(--color-primary-soft)',
|
||||
surface: 'var(--color-surface)',
|
||||
'surface-2': 'var(--color-surface-2)',
|
||||
line: 'var(--color-border)',
|
||||
fg: 'var(--color-text)',
|
||||
muted: 'var(--color-text-muted)',
|
||||
danger: 'var(--color-danger)',
|
||||
'danger-hover': 'var(--color-danger-hover)',
|
||||
'danger-soft': 'var(--color-danger-soft)',
|
||||
success: 'var(--color-success)',
|
||||
'success-soft': 'var(--color-success-soft)',
|
||||
warning: 'var(--color-warning)',
|
||||
'warning-soft': 'var(--color-warning-soft)',
|
||||
info: 'var(--color-info)',
|
||||
'info-soft': 'var(--color-info-soft)',
|
||||
bg: 'var(--color-bg)',
|
||||
accent: 'var(--color-accent)',
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'Noto Sans SC', 'system-ui', '-apple-system', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'PingFang SC', 'Microsoft YaHei', 'sans-serif'],
|
||||
},
|
||||
borderRadius: {
|
||||
sm: 'var(--radius-sm)',
|
||||
DEFAULT: 'var(--radius)',
|
||||
lg: 'var(--radius-lg)',
|
||||
},
|
||||
boxShadow: {
|
||||
soft: '0 1px 2px rgba(15, 23, 42, 0.06)',
|
||||
card: '0 4px 14px rgba(15, 23, 42, 0.08)',
|
||||
},
|
||||
maxWidth: {
|
||||
'8xl': '80rem',
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="{{ asset('js/vendor/vue.global.prod.js') }}" defer></script>
|
||||
<script src="{{ asset('js/app.js') }}?v={{ filemtime(public_path('js/app.js')) }}" defer></script>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@@context": "https://schema.org",
|
||||
"@@type": "Organization",
|
||||
"name": {!! json_encode($siteName, JSON_UNESCAPED_UNICODE) !!},
|
||||
"url": {!! json_encode(url('/'), JSON_UNESCAPED_UNICODE) !!},
|
||||
"logo": {!! json_encode(asset($logoUrl), JSON_UNESCAPED_UNICODE) !!},
|
||||
"description": {!! json_encode($seoDescDefault, JSON_UNESCAPED_UNICODE) !!}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="font-sans text-fg bg-surface antialiased">
|
||||
|
||||
@php
|
||||
// 前台顶部导航菜单(后台「导航菜单」可全权管理:显示/隐藏 + 排序)
|
||||
$navMenus = \App\Models\NavigationMenu::visible()->ordered()->get();
|
||||
@endphp
|
||||
|
||||
<!-- 顶部导航:TI 企业蓝风格,sticky + 留白 + 清晰层级 -->
|
||||
<header class="sticky top-0 z-50 bg-surface/90 backdrop-blur border-b border-line">
|
||||
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between h-14 lg:h-[68px]">
|
||||
<a class="flex items-center gap-3 shrink-0" href="{{ url('/') }}" aria-label="{{ $siteName }}">
|
||||
<img src="{{ asset($logoUrl) }}" alt="{{ $siteName }}" class="h-12 w-auto lg:h-14 drop-shadow-sm">
|
||||
</a>
|
||||
|
||||
<nav class="hidden lg:flex items-center gap-7">
|
||||
@foreach ($navMenus as $m)
|
||||
<a href="{{ Str::startsWith($m->url, ['http://', 'https://']) ? $m->url : url($m->url) }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">{{ $m->label }}</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
|
||||
<div class="hidden lg:flex items-center gap-5">
|
||||
<!-- 全站搜索 -->
|
||||
<form action="{{ url('/search') }}" method="GET" class="relative">
|
||||
<x-icon name="search" :size="20" class="absolute left-3 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
|
||||
<input type="search" name="q" value="{{ request('q', '') }}" placeholder="搜索产品、文章、术语…" class="w-56 rounded-lg border border-line bg-surface-2 pl-10 pr-3 py-2.5 text-lg text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</form>
|
||||
|
||||
@auth
|
||||
@if (Auth::user()->role !== 'user')
|
||||
<a href="{{ url('/admin') }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">后台</a>
|
||||
@endif
|
||||
<a href="{{ route('articles.submit') }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">投稿</a>
|
||||
<x-level-badge :user="Auth::user()" />
|
||||
<span class="text-lg lg:text-xl text-muted">{{ Auth::user()->name }}</span>
|
||||
<a href="{{ route('auth.settings') }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">设置</a>
|
||||
<form method="POST" action="{{ url('/logout') }}" class="inline">
|
||||
@csrf
|
||||
<button type="submit" class="text-lg lg:text-xl font-medium text-muted hover:text-danger transition-colors">退出</button>
|
||||
</form>
|
||||
@endauth
|
||||
</div>
|
||||
|
||||
<!-- 移动端菜单按钮 -->
|
||||
<button id="nav-toggle" type="button" class="lg:hidden inline-flex items-center justify-center p-2 rounded-lg text-muted hover:bg-surface-2" aria-label="菜单">
|
||||
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 移动端展开菜单 -->
|
||||
<div id="nav-menu" class="lg:hidden hidden border-t border-line bg-surface">
|
||||
<div class="max-w-8xl mx-auto px-4 py-3 space-y-1">
|
||||
<form action="{{ url('/search') }}" method="GET" class="relative mb-2">
|
||||
<x-icon name="search" :size="20" class="absolute left-3 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
|
||||
<input type="search" name="q" value="{{ request('q', '') }}" placeholder="搜索产品、文章、术语…" class="w-full rounded-lg border border-line bg-surface-2 pl-10 pr-3 py-2.5 text-lg text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</form>
|
||||
@foreach ($navMenus as $m)
|
||||
<a href="{{ Str::startsWith($m->url, ['http://', 'https://']) ? $m->url : url($m->url) }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">{{ $m->label }}</a>
|
||||
@endforeach
|
||||
@auth
|
||||
@if (Auth::user()->role !== 'user')
|
||||
<a href="{{ url('/admin') }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">后台</a>
|
||||
@endif
|
||||
<a href="{{ route('articles.submit') }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">投稿</a>
|
||||
<div class="px-3 py-2.5"><x-level-badge :user="Auth::user()" /></div>
|
||||
<a href="{{ route('auth.settings') }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">设置</a>
|
||||
<form method="POST" action="{{ url('/logout') }}" class="block">
|
||||
@csrf
|
||||
<button type="submit" class="w-full text-left px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-danger">退出({{ Auth::user()->name }})</button>
|
||||
</form>
|
||||
@endauth
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="min-h-[60vh]">
|
||||
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
@if (session('success'))
|
||||
<div class="flex items-center gap-2 my-6 rounded-lg border border-success/30 bg-success-soft px-4 py-3 text-sm text-success">
|
||||
<x-icon name="check" :size="18" />
|
||||
<span>{{ session('success') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if ($errors?->any())
|
||||
<div class="flex items-center gap-2 my-6 rounded-lg border border-danger/30 bg-danger-soft px-4 py-3 text-sm text-danger">
|
||||
<x-icon name="alert" :size="18" />
|
||||
<span>{{ $errors->first() ?: '表单填写有误,请检查后重试。' }}</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@yield('content')
|
||||
</main>
|
||||
|
||||
<footer class="mt-16 border-t border-line bg-surface">
|
||||
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="grid gap-8 md:grid-cols-4">
|
||||
<div class="md:col-span-2">
|
||||
<div class="flex items-center gap-3 mb-3">
|
||||
<img src="{{ asset($logoUrl) }}" alt="{{ $siteName }}" class="h-12 w-auto drop-shadow-sm">
|
||||
</div>
|
||||
<p class="text-sm text-muted max-w-md">TypeC 产品顾问|多口 TypeC 接口IC 方案提供商,专注协议转换与同步整流控制芯片,面向充电与外设厂商。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold text-fg mb-3">产品与资源</h4>
|
||||
<ul class="space-y-2 text-sm text-muted">
|
||||
<li><a href="{{ url('/products') }}" class="hover:text-primary transition-colors">产品中心</a></li>
|
||||
<li><a href="{{ url('/solutions') }}" class="hover:text-primary transition-colors">解决方案</a></li>
|
||||
<li><a href="{{ url('/about') }}" class="hover:text-primary transition-colors">关于我们</a></li>
|
||||
<li><a href="{{ url('/articles') }}" class="hover:text-primary transition-colors">技术文章</a></li>
|
||||
<li><a href="{{ url('/news') }}" class="hover:text-primary transition-colors">新闻动态</a></li>
|
||||
<li><a href="{{ url('/glossary') }}" class="hover:text-primary transition-colors">术语库</a></li>
|
||||
<li><a href="{{ url('/forum') }}" class="hover:text-primary transition-colors">技术论坛</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold text-fg mb-3">联系我们</h4>
|
||||
<ul class="space-y-2.5 text-sm text-muted">
|
||||
<li class="flex items-start gap-2">
|
||||
<x-icon name="box" :size="16" class="mt-0.5 shrink-0 text-muted" />
|
||||
<span>深圳市云创芯电子有限公司</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<x-icon name="mail" :size="16" class="shrink-0 text-muted" />
|
||||
<a href="mailto:service@51chip.net" class="hover:text-primary transition-colors">service@51chip.net</a>
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<x-icon name="phone" :size="16" class="shrink-0 text-muted" />
|
||||
<a href="tel:13510116819" class="hover:text-primary transition-colors">13510116819</a>
|
||||
</li>
|
||||
<li><a href="{{ url('/contact') }}" class="hover:text-primary transition-colors">更多联络方式</a></li>
|
||||
@auth
|
||||
@if (Auth::user()->role !== 'user')
|
||||
<li><a href="{{ url('/admin') }}" class="hover:text-primary transition-colors">管理后台</a></li>
|
||||
@endif
|
||||
@endauth
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@php $footerContent = App\Models\Setting::get('footer_content'); @endphp
|
||||
@if ($footerContent)
|
||||
<div class="mt-8 footer-rich">
|
||||
{!! \Purifier::clean($footerContent, 'article') !!}
|
||||
</div>
|
||||
@endif
|
||||
<div class="mt-8 pt-6 border-t border-line text-sm text-muted">
|
||||
<p class="flex flex-wrap items-center gap-x-3 gap-y-1">
|
||||
<span>© {{ date('Y') }} {{ $siteName }}. 保留所有权利。</span>
|
||||
<a href="{{ url('/sitemap') }}" class="hover:text-primary transition-colors">网站地图</a>
|
||||
@if ($icpNo)
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener noreferrer" class="icp-link">{{ $icpNo }}</a>
|
||||
@endif
|
||||
@php
|
||||
// 公安网备号:优先取后台「站点设置」值,缺省内置粤公网安备44030002015390号
|
||||
$secRaw = trim($securityFilingNo);
|
||||
if ($secRaw === '') {
|
||||
$secRaw = '粤公网安备44030002015390号';
|
||||
}
|
||||
// 提取数字编号,用于公安网备核验深链
|
||||
preg_match('/\d{6,}/', $secRaw, $secMatch);
|
||||
$secCode = $secMatch[0] ?? '44030002015390';
|
||||
// 规范显示文案:缺「粤公网安备」前缀时自动补上并加「号」
|
||||
if (!preg_match('/粤公网安备/', $secRaw)) {
|
||||
$secRaw = '粤公网安备' . preg_replace('/\D/', '', $secRaw) . '号';
|
||||
}
|
||||
@endphp
|
||||
<a href="https://beian.mps.gov.cn/#/query/webSearch?code={{ $secCode }}" target="_blank" rel="nofollow noopener noreferrer" class="icp-link inline-flex items-center gap-1">
|
||||
<img src="{{ asset('images/gongan_badge.png') }}" width="16" height="17" alt="公安网备" loading="lazy" class="inline-block align-middle" onerror="this.onerror=null;this.outerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 24 24"><path d="M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z" fill="#1a3a8f" stroke="#d4af37" stroke-width="1"/><polygon points="12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5" fill="#ffffff"/></svg>'">
|
||||
{{ $secRaw }}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById('nav-toggle');
|
||||
var menu = document.getElementById('nav-menu');
|
||||
if (btn && menu) {
|
||||
btn.addEventListener('click', function () {
|
||||
menu.classList.toggle('hidden');
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,43 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '新闻动态 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="hero-aurora">
|
||||
<div class="hero-grid"></div>
|
||||
<div class="relative max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-16 lg:py-24">
|
||||
<p class="eyebrow">NEWS</p>
|
||||
<h1 class="mt-3 text-3xl font-bold tracking-tight text-fg sm:text-4xl lg:text-5xl gradient-text">新闻动态</h1>
|
||||
<p class="mt-4 max-w-2xl text-base text-muted">行业资讯、公司动态与展会活动,第一时间了解深圳市云创芯电子有限公司与 TypeC 快速充电生态。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-12 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="filter-bar mb-8">
|
||||
<a href="{{ url('/news') }}" class="btn btn-sm @if(!$category) btn-primary @endif">全部</a>
|
||||
@foreach (App\Models\News::CATEGORIES as $k => $v)
|
||||
<a href="{{ url('/news?category=' . $k) }}" class="btn btn-sm @if($category === $k) btn-primary @endif">{{ $v }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@forelse ($news as $n)
|
||||
<a href="{{ route('news.show', $n->slug) }}" class="group glow-card rounded-xl border border-line bg-surface p-6 transition">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="badge badge-primary">{{ $n->categoryLabel() }}</span>
|
||||
<span class="text-xs text-muted">{{ $n->published_at?->format('Y-m-d') }}</span>
|
||||
</div>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $n->title }}</h3>
|
||||
<p class="mt-2 line-clamp-3 text-sm text-muted">{{ $n->summary }}</p>
|
||||
<span class="mt-4 inline-flex items-center gap-1 text-sm font-medium text-primary">阅读全文 <x-icon name="arrow" :size="16" /></span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">暂无新闻。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-8">{{ $news->links('pagination::bootstrap-5') }}</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,35 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@php $siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'); @endphp
|
||||
@section('title', $news->seoTitle() . ' - ' . $siteName)
|
||||
@section('description', $news->seoDescription())
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ url('/') }}" class="hover:text-primary">首页</a><span>/</span>
|
||||
<a href="{{ route('news.index') }}" class="hover:text-primary">新闻动态</a><span>/</span>
|
||||
<span class="text-fg">{{ $news->title }}</span>
|
||||
</nav>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="badge badge-primary">{{ $news->categoryLabel() }}</span>
|
||||
<span class="text-sm text-muted">{{ $news->published_at?->format('Y-m-d') }}</span>
|
||||
</div>
|
||||
<h1 class="mt-3 text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $news->title }}</h1>
|
||||
@if ($news->summary)<p class="lead mt-4 text-base text-muted">{{ $news->summary }}</p>@endif
|
||||
@if ($news->body)
|
||||
<div class="prose mt-6 text-fg">
|
||||
@if (preg_match('/<[a-z][a-z0-9]*[\s>]/i', $news->body))
|
||||
{!! $news->body !!}
|
||||
@else
|
||||
{!! nl2br(e($news->body)) !!}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('news.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover"><x-icon name="arrow" :size="16" class="rotate-180" /> 返回新闻列表</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,28 @@
|
||||
@php
|
||||
$ctaHref = $slide->cta_url
|
||||
? (Str::startsWith($slide->cta_url, ['http://', 'https://']) ? $slide->cta_url : url($slide->cta_url))
|
||||
: null;
|
||||
$cta2Href = $slide->cta2_url
|
||||
? (Str::startsWith($slide->cta2_url, ['http://', 'https://']) ? $slide->cta2_url : url($slide->cta2_url))
|
||||
: null;
|
||||
@endphp
|
||||
|
||||
<div class="hero-slide-inner">
|
||||
<div class="hero-slide-content rich-content rich-content--on-dark">
|
||||
{!! \Purifier::clean($slide->content, 'article') !!}
|
||||
</div>
|
||||
|
||||
@if ($ctaHref)
|
||||
<div class="mt-8 flex flex-wrap justify-center gap-4">
|
||||
<a href="{{ $ctaHref }}" class="inline-flex items-center gap-2 rounded-lg bg-surface px-5 py-3 text-sm font-semibold text-primary transition hover:bg-surface/90">
|
||||
{{ $slide->cta_text }}
|
||||
<x-icon name="arrow" :size="18" />
|
||||
</a>
|
||||
@if ($cta2Href)
|
||||
<a href="{{ $cta2Href }}" class="inline-flex items-center gap-2 rounded-lg border border-white/40 px-5 py-3 text-sm font-semibold text-white transition hover:bg-surface/10">
|
||||
{{ $slide->cta2_text }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@@ -0,0 +1,57 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '产品中心 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">产品中心</h1>
|
||||
<p class="mt-2 text-sm text-muted">多口 TypeC 接口 IC、协议转换与同步整流控制芯片完整选型。</p>
|
||||
</div>
|
||||
|
||||
<form method="GET" class="flex flex-wrap items-end gap-3">
|
||||
<div class="min-w-[220px] flex-1">
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">搜索</label>
|
||||
<div class="relative">
|
||||
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted">
|
||||
<x-icon name="search" :size="18" />
|
||||
</span>
|
||||
<input type="text" name="q" value="{{ $q }}" placeholder="搜索名称、型号..." class="w-full rounded-lg border border-line bg-surface py-2.5 pl-10 pr-3 text-sm text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full sm:w-56">
|
||||
<label class="mb-1.5 block text-sm font-medium text-fg">分类</label>
|
||||
<select name="category" onchange="this.form.submit()" class="w-full rounded-lg border border-line bg-surface px-3 py-2.5 text-sm text-fg focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
<option value="">全部分类</option>
|
||||
@foreach ($categories as $c)
|
||||
<option value="{{ $c->id }}" @selected((int) $categoryId === $c->id)>{{ $c->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-primary-hover">
|
||||
<x-icon name="search" :size="18" /> 查询
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@forelse ($products as $product)
|
||||
<a href="{{ route('products.show', $product->slug) }}" class="group flex flex-col rounded-lg border border-line bg-surface p-6 shadow-soft transition hover:-translate-y-0.5 hover:border-primary hover:shadow-card">
|
||||
<span class="inline-block w-fit rounded bg-primary-soft px-2 py-1 font-mono text-xs font-medium text-primary">{{ $product->model ?: $product->slug }}</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $product->name }}</h3>
|
||||
<p class="mt-2 line-clamp-3 text-sm text-muted">{{ $product->summary ?: Str::limit(strip_tags($product->description), 90) }}</p>
|
||||
<span class="mt-4 inline-flex items-center gap-1 text-sm font-medium text-primary">
|
||||
查看详情 <x-icon name="arrow" :size="16" />
|
||||
</span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">没有匹配的产品,换个关键词试试。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-8">
|
||||
{{ $products->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,45 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@php $siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'); @endphp
|
||||
@section('title', $product->seoTitle() . ' - ' . $siteName)
|
||||
@section('description', $product->seoDescription())
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-5xl">
|
||||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ url('/') }}" class="hover:text-primary">首页</a>
|
||||
<span>/</span>
|
||||
<a href="{{ route('products.index') }}" class="hover:text-primary">产品中心</a>
|
||||
<span>/</span>
|
||||
<span class="text-fg">{{ $product->name }}</span>
|
||||
</nav>
|
||||
|
||||
<article class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||||
<span class="inline-block rounded bg-primary-soft px-2 py-1 font-mono text-xs font-medium text-primary">{{ $product->model ?: $product->slug }}</span>
|
||||
<h1 class="mt-4 text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $product->name }}</h1>
|
||||
@if ($product->category)
|
||||
<p class="mt-2 text-sm text-muted">分类:{{ $product->category->name }}</p>
|
||||
@endif
|
||||
@if ($product->summary)
|
||||
<p class="mt-4 text-base text-muted">{{ $product->summary }}</p>
|
||||
@endif
|
||||
@if ($product->description)
|
||||
<div class="prose mt-6 text-fg">
|
||||
{!! nl2br(e($product->description)) !!}
|
||||
</div>
|
||||
@endif
|
||||
@if ($product->specs)
|
||||
<h2 class="mt-8 text-lg font-semibold text-fg">规格参数</h2>
|
||||
<pre class="mt-3 overflow-x-auto rounded-lg border border-line bg-surface-2 p-4 font-mono text-sm text-fg">{{ $product->specs }}</pre>
|
||||
@endif
|
||||
</article>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('products.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">
|
||||
<x-icon name="arrow" :size="16" class="rotate-180" /> 返回产品中心
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,107 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '全站搜索 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||||
<div class="mx-auto max-w-5xl">
|
||||
<h1 class="text-3xl font-bold tracking-tight text-fg">全站搜索</h1>
|
||||
|
||||
<form action="{{ url('/search') }}" method="GET" class="mt-6 flex flex-col gap-3 sm:flex-row">
|
||||
<div class="relative flex-1">
|
||||
<x-icon name="search" :size="22" class="absolute left-4 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
|
||||
<input type="search" name="q" value="{{ $q }}" placeholder="搜索产品、文章、术语、论坛…" class="w-full rounded-lg border border-line bg-surface pl-12 pr-4 py-3.5 text-lg text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
|
||||
</div>
|
||||
<button type="submit" class="inline-flex items-center justify-center rounded-lg bg-primary px-8 py-3.5 text-lg font-semibold text-white transition hover:bg-primary-hover">搜索</button>
|
||||
</form>
|
||||
|
||||
@if ($q === '')
|
||||
<p class="mt-8 text-base text-muted">输入关键词,跨「产品 / 文章 / 术语库 / 技术论坛」检索全站内容。</p>
|
||||
@else
|
||||
<p class="mt-8 text-base text-muted">“<span class="font-medium text-fg">{{ $q }}</span>” 共找到 <span class="font-medium text-fg">{{ $total }}</span> 条结果。</p>
|
||||
|
||||
@if ($total === 0)
|
||||
<div class="mt-6 rounded-lg border border-line bg-surface p-10 text-center">
|
||||
<p class="text-lg text-muted">没有匹配的内容,换个关键词试试。</p>
|
||||
</div>
|
||||
@else
|
||||
@if ($results['articles']->isNotEmpty())
|
||||
<div class="mt-10">
|
||||
<h2 class="flex items-center gap-2 text-xl font-semibold text-fg">
|
||||
<x-icon name="doc" :size="24" class="text-primary" /> 文章
|
||||
</h2>
|
||||
<ul class="mt-4 space-y-3">
|
||||
@foreach ($results['articles'] as $article)
|
||||
<li>
|
||||
<a href="{{ route('articles.show', $article->slug) }}" class="block rounded-lg border border-line bg-surface p-5 transition hover:border-primary hover:shadow-card">
|
||||
<h3 class="text-lg font-semibold text-fg">{{ $article->title }}</h3>
|
||||
@if ($article->summary)
|
||||
<p class="mt-1.5 line-clamp-2 text-base text-muted">{{ Str::limit($article->summary, 120) }}</p>
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($results['products']->isNotEmpty())
|
||||
<div class="mt-10">
|
||||
<h2 class="flex items-center gap-2 text-xl font-semibold text-fg">
|
||||
<x-icon name="box" :size="24" class="text-primary" /> 产品
|
||||
</h2>
|
||||
<ul class="mt-4 space-y-3">
|
||||
@foreach ($results['products'] as $product)
|
||||
<li>
|
||||
<a href="{{ route('products.show', $product->slug) }}" class="block rounded-lg border border-line bg-surface p-5 transition hover:border-primary hover:shadow-card">
|
||||
<h3 class="text-lg font-semibold text-fg">{{ $product->name }}</h3>
|
||||
@if ($product->summary)
|
||||
<p class="mt-1.5 line-clamp-2 text-base text-muted">{{ Str::limit($product->summary, 120) }}</p>
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($results['glossary']->isNotEmpty())
|
||||
<div class="mt-10">
|
||||
<h2 class="flex items-center gap-2 text-xl font-semibold text-fg">
|
||||
<x-icon name="book" :size="24" class="text-primary" /> 术语库
|
||||
</h2>
|
||||
<ul class="mt-4 space-y-3">
|
||||
@foreach ($results['glossary'] as $term)
|
||||
<li>
|
||||
<a href="{{ route('glossary.show', $term->slug) }}" class="block rounded-lg border border-line bg-surface p-5 transition hover:border-primary hover:shadow-card">
|
||||
<h3 class="text-lg font-semibold text-fg">{{ $term->term }}</h3>
|
||||
<p class="mt-1.5 line-clamp-2 text-base text-muted">{{ Str::limit($term->definition, 120) }}</p>
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($results['threads']->isNotEmpty())
|
||||
<div class="mt-10">
|
||||
<h2 class="flex items-center gap-2 text-xl font-semibold text-fg">
|
||||
<x-icon name="chat" :size="24" class="text-primary" /> 技术论坛
|
||||
</h2>
|
||||
<ul class="mt-4 space-y-3">
|
||||
@foreach ($results['threads'] as $thread)
|
||||
<li>
|
||||
<a href="{{ route('forum.thread', $thread) }}" class="block rounded-lg border border-line bg-surface p-5 transition hover:border-primary hover:shadow-card">
|
||||
<h3 class="text-lg font-semibold text-fg">{{ $thread->title }}</h3>
|
||||
<p class="mt-1.5 line-clamp-2 text-base text-muted">{{ Str::limit($thread->body, 120) }}</p>
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,131 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '网站地图 - ' . App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'))
|
||||
@section('description', '网站地图:汇总本站全部主要页面与内容入口,便于浏览与检索。')
|
||||
|
||||
@section('content')
|
||||
{{-- Hero --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 pt-14 lg:pt-20 pb-6">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<p class="text-sm font-medium tracking-wide text-primary">网站地图</p>
|
||||
<h1 class="mt-3 max-w-3xl text-3xl font-bold leading-tight tracking-tight text-fg sm:text-4xl lg:text-5xl">
|
||||
全站页面与内容导航
|
||||
</h1>
|
||||
<p class="mt-5 max-w-2xl text-base text-muted lg:text-lg">
|
||||
这里汇总了本站的主要页面与内容入口。需要提交给搜索引擎的机读版本,请使用
|
||||
<a href="{{ url('/sitemap.xml') }}" class="text-primary hover:underline">sitemap.xml</a>。
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 核心页面 --}}
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-3">
|
||||
<div class="lg:col-span-1">
|
||||
<h2 class="text-xl font-bold tracking-tight text-fg">核心页面</h2>
|
||||
<p class="mt-3 text-sm text-muted">企业官网的主要栏目。</p>
|
||||
</div>
|
||||
<div class="lg:col-span-2">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<a href="{{ url('/') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">首页</p>
|
||||
<p class="mt-1 text-sm text-muted">企业概览与核心优势。</p>
|
||||
</a>
|
||||
<a href="{{ url('/about') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">关于我们</p>
|
||||
<p class="mt-1 text-sm text-muted">公司简介、能力与价值观。</p>
|
||||
</a>
|
||||
<a href="{{ url('/products') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">产品服务</p>
|
||||
<p class="mt-1 text-sm text-muted">芯片产品中心与方案。</p>
|
||||
</a>
|
||||
<a href="{{ url('/contact') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">联系我们</p>
|
||||
<p class="mt-1 text-sm text-muted">商务合作与技术支持。</p>
|
||||
</a>
|
||||
<a href="{{ url('/articles') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">技术文章</p>
|
||||
<p class="mt-1 text-sm text-muted">设计笔记与应用指南。</p>
|
||||
</a>
|
||||
<a href="{{ url('/glossary') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">术语库</p>
|
||||
<p class="mt-1 text-sm text-muted">接口与快充专业术语。</p>
|
||||
</a>
|
||||
<a href="{{ url('/forum') }}" class="group rounded-2xl border border-line bg-surface p-5 transition-colors hover:border-primary/40 hover:bg-surface-2">
|
||||
<p class="text-base font-semibold text-fg group-hover:text-primary">技术论坛</p>
|
||||
<p class="mt-1 text-sm text-muted">工程师交流与答疑。</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- 产品中心 --}}
|
||||
@if ($products->isNotEmpty())
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-10 bg-surface">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-3">
|
||||
<div class="lg:col-span-1">
|
||||
<h2 class="text-xl font-bold tracking-tight text-fg">产品中心</h2>
|
||||
<p class="mt-3 text-sm text-muted">共 {{ $products->count() }} 款已发布产品。</p>
|
||||
</div>
|
||||
<div class="lg:col-span-2">
|
||||
<ul class="divide-y divide-line rounded-2xl border border-line bg-surface">
|
||||
@foreach ($products as $p)
|
||||
<li>
|
||||
<a href="{{ route('products.show', $p->slug) }}" class="flex items-center justify-between gap-4 px-5 py-3.5 transition-colors hover:bg-surface-2">
|
||||
<span class="text-[15px] font-medium text-fg">{{ $p->name }}</span>
|
||||
<span class="text-sm text-muted">{{ $p->model ?: '查看详情' }} →</span>
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
{{-- 技术文章 --}}
|
||||
@if ($articles->isNotEmpty())
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-3">
|
||||
<div class="lg:col-span-1">
|
||||
<h2 class="text-xl font-bold tracking-tight text-fg">技术文章</h2>
|
||||
<p class="mt-3 text-sm text-muted">共 {{ $articles->count() }} 篇已发布文章。</p>
|
||||
</div>
|
||||
<div class="lg:col-span-2">
|
||||
<ul class="divide-y divide-line rounded-2xl border border-line bg-surface">
|
||||
@foreach ($articles as $a)
|
||||
<li>
|
||||
<a href="{{ route('articles.show', $a->slug) }}" class="flex items-center justify-between gap-4 px-5 py-3.5 transition-colors hover:bg-surface-2">
|
||||
<span class="text-[15px] font-medium text-fg">{{ $a->title }}</span>
|
||||
<span class="shrink-0 text-sm text-muted">→</span>
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
{{-- 术语库 --}}
|
||||
@if ($terms->isNotEmpty())
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-10 bg-surface">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-3">
|
||||
<div class="lg:col-span-1">
|
||||
<h2 class="text-xl font-bold tracking-tight text-fg">术语库</h2>
|
||||
<p class="mt-3 text-sm text-muted">共 {{ $terms->count() }} 条术语。</p>
|
||||
</div>
|
||||
<div class="lg:col-span-2">
|
||||
<div class="flex flex-wrap gap-2.5">
|
||||
@foreach ($terms as $g)
|
||||
<a href="{{ route('glossary.show', $g->slug) }}" class="rounded-full border border-line bg-surface px-4 py-1.5 text-sm text-fg transition-colors hover:border-primary/40 hover:text-primary">
|
||||
{{ $g->term }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
@endsection
|
||||
@@ -0,0 +1,61 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '解决方案 - 深圳市云创芯电子有限公司')
|
||||
|
||||
@section('content')
|
||||
<section class="hero-aurora">
|
||||
<div class="hero-grid"></div>
|
||||
<div class="relative max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-16 lg:py-24">
|
||||
<p class="eyebrow">SOLUTIONS</p>
|
||||
<h1 class="mt-3 max-w-3xl text-3xl font-bold tracking-tight text-fg sm:text-4xl lg:text-5xl gradient-text">TypeC 快速充电解决方案</h1>
|
||||
<p class="mt-4 max-w-2xl text-base text-muted lg:text-lg">覆盖 22W–140W 多功率段,面向充电器、移动电源、车充与扩展坞场景,提供从协议芯片到高集成 SoC 的参考设计与选型支持。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-12 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto">
|
||||
<form method="GET" class="filter-bar mb-8">
|
||||
<select name="power" onchange="this.form.submit()" class="select">
|
||||
<option value="">全部功率段</option>
|
||||
@foreach (App\Models\Solution::POWER_SEGMENTS as $k => $v)
|
||||
<option value="{{ $k }}" @selected($power === $k)>{{ $v }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="application" onchange="this.form.submit()" class="select">
|
||||
<option value="">全部应用场景</option>
|
||||
@foreach (App\Models\Solution::APPLICATIONS as $k => $v)
|
||||
<option value="{{ $k }}" @selected($application === $k)>{{ $v }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="platform" onchange="this.form.submit()" class="select">
|
||||
<option value="">全部芯片平台</option>
|
||||
@foreach (App\Models\Solution::CHIP_PLATFORMS as $k => $v)
|
||||
<option value="{{ $k }}" @selected($platform === $k)>{{ $v }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<a href="{{ url('/solutions') }}" class="btn btn-sm">重置</a>
|
||||
</form>
|
||||
|
||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@forelse ($solutions as $s)
|
||||
<a href="{{ route('solutions.show', $s->slug) }}" class="group glow-card rounded-xl border border-line bg-surface p-6 transition">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="inline-flex h-10 w-10 items-center justify-center rounded-lg bg-primary-soft text-primary"><x-icon name="compass" :size="22" /></span>
|
||||
@if ($s->power)<span class="badge badge-primary">{{ $s->power }}</span>@endif
|
||||
</div>
|
||||
<h3 class="mt-4 text-lg font-semibold text-fg transition group-hover:text-primary">{{ $s->name }}</h3>
|
||||
<p class="mt-2 text-sm text-muted">{{ $s->summary }}</p>
|
||||
<div class="mt-4 flex flex-wrap gap-2 text-xs">
|
||||
<span class="badge">{{ $s->powerSegmentLabel() }}</span>
|
||||
<span class="badge">{{ $s->applicationLabel() }}</span>
|
||||
<span class="badge">{{ $s->chipPlatformLabel() }}</span>
|
||||
</div>
|
||||
<span class="mt-4 inline-flex items-center gap-1 text-sm font-medium text-primary">查看详情 <x-icon name="arrow" :size="16" /></span>
|
||||
</a>
|
||||
@empty
|
||||
<p class="text-sm text-muted">暂无匹配的解决方案。</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@@ -0,0 +1,56 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@php $siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'); @endphp
|
||||
@section('title', $solution->seoTitle() . ' - ' . $siteName)
|
||||
@section('description', $solution->seoDescription())
|
||||
|
||||
@section('content')
|
||||
<section class="hero-aurora">
|
||||
<div class="hero-grid"></div>
|
||||
<div class="relative max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-14 lg:py-20">
|
||||
<nav class="mb-5 flex items-center gap-1.5 text-sm text-muted">
|
||||
<a href="{{ url('/') }}" class="hover:text-primary">首页</a><span>/</span>
|
||||
<a href="{{ route('solutions.index') }}" class="hover:text-primary">解决方案</a><span>/</span>
|
||||
<span class="text-fg">{{ $solution->name }}</span>
|
||||
</nav>
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
@if ($solution->power)<span class="badge badge-primary">{{ $solution->power }}</span>@endif
|
||||
<span class="badge">{{ $solution->powerSegmentLabel() }}</span>
|
||||
<span class="badge">{{ $solution->applicationLabel() }}</span>
|
||||
<span class="badge">{{ $solution->chipPlatformLabel() }}</span>
|
||||
</div>
|
||||
<h1 class="mt-4 max-w-3xl text-3xl font-bold tracking-tight text-fg sm:text-4xl gradient-text">{{ $solution->name }}</h1>
|
||||
<p class="mt-4 max-w-2xl text-base text-muted">{{ $solution->summary }}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="px-4 sm:px-6 lg:px-8 py-12 lg:py-16">
|
||||
<div class="max-w-8xl mx-auto grid gap-10 lg:grid-cols-3">
|
||||
<div class="lg:col-span-2 space-y-6">
|
||||
@if ($solution->description)
|
||||
<div class="prose text-fg">{!! nl2br(e($solution->description)) !!}</div>
|
||||
@endif
|
||||
|
||||
@if ($solution->advantagesList())
|
||||
<h2 class="text-xl font-bold text-fg">方案优势</h2>
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
@foreach ($solution->advantagesList() as $a)
|
||||
<div class="flex items-start gap-3 rounded-lg border border-line bg-surface p-4">
|
||||
<x-icon name="check" :size="20" class="mt-0.5 shrink-0 text-primary" />
|
||||
<span class="text-sm text-fg">{{ $a }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<aside class="lg:col-span-1">
|
||||
<div class="glass rounded-2xl p-6 lg:sticky lg:top-24">
|
||||
<h3 class="text-lg font-semibold text-fg">获取方案详情</h3>
|
||||
<p class="mt-2 text-sm text-muted">留下需求,我们的应用工程师将为您提供完整参考设计与选型支持。</p>
|
||||
<a href="{{ url('/contact') }}?subject={{ urlencode($solution->name) }}" class="cta-glow mt-5 w-full justify-center rounded-lg px-5 py-3 text-sm font-semibold">联系获取方案 <x-icon name="arrow" :size="18" /></a>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user