chore: init saasshop repo + sql migrations runner + gitee go

This commit is contained in:
萝卜
2026-03-10 11:31:02 +00:00
commit 50f15cdea8
210 changed files with 29534 additions and 0 deletions

25
public/.htaccess Normal file
View File

@@ -0,0 +1,25 @@
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Handle X-XSRF-Token Header
RewriteCond %{HTTP:x-xsrf-token} .
RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

133
public/css/admin-base.css Normal file
View File

@@ -0,0 +1,133 @@
body{
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
color:#e5e7eb;
margin:0;
}
a{color:#60a5fa;text-decoration:none;}
a:hover{text-decoration:underline;}
.layout{display:grid;min-height:100vh;}
.sidebar{padding:24px;}
.sidebar-title,.sidebar-brand{margin-top:0;}
.sidebar a,
.sidebar-link{display:block;color:#cbd5e1;text-decoration:none;padding:10px 12px;border-radius:10px;margin-bottom:8px;}
.sidebar a:hover,
.sidebar-link:hover{text-decoration:none;}
.group-title{font-size:12px;color:#64748b;text-transform:uppercase;letter-spacing:.08em;margin:18px 0 8px;}
.sidebar-logout,.logout-form{margin-top:18px;}
.content{padding:28px;}
.top{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:20px;}
.page-title{margin:0;}
.card{border:1px solid #334155;border-radius:14px;padding:16px;}
.card + .card{margin-top:20px;}
.card-spaced{margin-bottom:20px;}
.grid{display:grid;gap:16px;}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;}
.grid-5{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;}
.grid-6{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;}
.grid-align-end{align-items:end;}
.two-col{display:grid;grid-template-columns:1.3fr 1fr;gap:16px;}
.span-2{grid-column:span 2;}
.span-3{grid-column:span 3;}
.num{font-size:28px;font-weight:700;}
.num-md{font-size:20px;font-weight:700;}
.num-sm{font-size:18px;font-weight:700;}
/* 兼容:早期页面使用 metric-number 作为指标数字样式 */
.metric-number{font-size:28px;font-weight:700;}
.text-md{font-size:16px;display:block;}
.muted{color:#94a3b8;}
.muted-tight{margin-top:0;}
.muted-xs{margin-top:6px;font-size:12px;}
.badge{display:inline-block;padding:4px 10px;border-radius:999px;font-size:12px;margin-top:8px;}
table{width:100%;border-collapse:collapse;}
th,td{padding:10px;border-bottom:1px solid #334155;text-align:left;vertical-align:top;}
input,select,button,textarea,
.form-grid input,
.form-grid select,
.login-form input,
.login-form button{
padding:10px 12px;
border-radius:10px;
border:1px solid #475569;
background:#0f172a;
color:#fff;
box-sizing:border-box;
}
button{cursor:pointer;}
textarea.w-full,input.w-full{width:100%;}
input.w-140{width:140px;}
input.w-90{width:90px;}
.block{display:block;}
.inline{display:inline;}
.inline-form{display:inline;}
.mb-0{margin-bottom:0;}
.mb-6{margin-bottom:6px;}
.mb-8{margin-bottom:8px;}
.mb-10{margin-bottom:10px;}
.mb-12{margin-bottom:12px;}
.mb-16{margin-bottom:16px;}
.mb-20{margin-bottom:20px;}
.mt-0{margin-top:0;}
.mt-6{margin-top:6px;}
.mt-8{margin-top:8px;}
.mt-10{margin-top:10px;}
.mt-12{margin-top:12px;}
.mt-16{margin-top:16px;}
.my-16{margin:16px 0;}
.my-20{margin:20px 0;}
.list-indent,.ml-18{margin:8px 0 0 18px;}
.flash{background:#052e16;color:#bbf7d0;padding:12px 14px;border-radius:10px;margin-bottom:16px;}
.warning{background:#78350f;color:#fde68a;padding:12px 14px;border-radius:10px;margin-bottom:16px;}
.error-box{background:#7f1d1d;color:#fecaca;padding:12px 14px;border-radius:10px;margin-bottom:16px;}
.error,.error-inline{color:#fca5a5;margin-top:10px;}
.filter-error{margin-bottom:12px;padding:12px;border:1px solid #fecaca;background:#fef2f2;color:#991b1b;border-radius:8px;}
.actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;}
.actions-spread{display:flex;justify-content:space-between;gap:12px;align-items:flex-start;flex-wrap:wrap;}
.inline-links,.card-link-list{display:flex;gap:8px;flex-wrap:wrap;}
.focus-box,.nav-box,.profile-box{padding:12px;border:1px solid #334155;border-radius:8px;}
.summary-box,.stat-box,.status-card,.status-link{padding:12px;border:1px solid #334155;border-radius:8px;}
.status-card,.status-link{color:inherit;text-decoration:none;display:block;}
.status-card:hover,.status-link:hover{text-decoration:none;}
.pagination-wrap{margin-top:16px;}
.text-center,.table-empty{text-align:center;}
.section-dark{background:#0f172a;}
.stat-box-light,.status-link-light{padding:12px;border:1px solid #e5e7eb;border-radius:8px;}
.status-link-light{color:inherit;text-decoration:none;display:block;}
.is-active-dark,.status-card-active{background:#1e293b;border-color:#60a5fa;}
.is-active-light{background:#f5faff;border-color:#93c5fd;}
.result-warning{color:#f59e0b;}
.result-success{color:#22c55e;}
.info-warning{margin-bottom:12px;padding:10px 12px;border:1px solid #f59e0b;border-radius:8px;color:#f59e0b;}
.helper-text{margin:12px 0 0;}
.login-page{display:flex;align-items:center;justify-content:center;min-height:100vh;}
.card-login,.login-card{width:420px;border-radius:18px;padding:28px;}
.login-form input,
.login-form button{width:100%;padding:12px;margin-top:10px;}
@media (max-width: 1200px){
.grid,.grid-3,.grid-4,.grid-5,.grid-6{grid-template-columns:repeat(2,1fr);}
.two-col{grid-template-columns:1fr;}
}
@media (max-width: 768px){
.layout{grid-template-columns:1fr !important;}
.sidebar{border-right:none !important;border-bottom:1px solid #22384f;}
.content{padding:16px;}
.top,.actions-spread{flex-direction:column;}
.grid,.grid-3,.grid-4,.grid-5,.grid-6{grid-template-columns:1fr;}
}

View File

@@ -0,0 +1,14 @@
/*
* SaaSShop Admin Components
* 说明用于承接 Blade 中零散的 inline style便于后续统一美化与治理
*/
.form-inline-row{
display:flex;
align-items:center;
gap:8px;
}
.text-danger{
color:#b42318;
}

1
public/css/admin.css Normal file
View File

@@ -0,0 +1 @@
body{background:#020617}a{color:#60a5fa}.layout{grid-template-columns:260px 1fr}.sidebar{background:#0f172a;border-right:1px solid #1e293b}.sidebar a:hover{background:#1e293b}.card{background:#111827}.grid{grid-template-columns:repeat(5,1fr)}.badge{background:#1d4ed8;color:#dbeafe}.danger{background:#7f1d1d;color:#fecaca}.button-danger{background:#7f1d1d;color:#fecaca}.card-login{background:#111827;border:1px solid #334155}

View File

@@ -0,0 +1 @@
body{background:#0f172a}a{color:#60a5fa}.layout{grid-template-columns:240px 1fr}.sidebar{background:#111827;border-right:1px solid #1f2937}.sidebar a:hover{background:#1f2937}.card{background:#111827}.grid{grid-template-columns:repeat(4,1fr)}.badge{background:#065f46;color:#d1fae5}.card-login{background:#111827;border:1px solid #334155}

View File

@@ -0,0 +1 @@
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;margin:0}.dark-page{background:#0b1020;color:#e5e7eb;padding:32px}.public-wrap{max-width:1100px;margin:0 auto;background:#111827;border:1px solid #263042;border-radius:18px;padding:28px}.public-wrap-narrow{max-width:980px}.muted{color:#94a3b8}.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:20px}.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:20px}.platforms{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;margin-top:20px}.card{background:#0f172a;border:1px solid #1e293b;border-radius:14px;padding:16px}.mt-20{margin-top:20px}.tag{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;background:#1e293b;color:#cbd5e1;margin-left:8px}code{background:#020617;padding:2px 6px;border-radius:6px}ul{line-height:1.8}.ok{color:#22c55e}.bad{color:#ef4444}.pc-body,.h5-body{background:#f8fafc;color:#0f172a}.pc-top{background:#0f172a;color:#fff;padding:16px 32px}.pc-wrap{max-width:1180px;margin:0 auto;padding:24px}.pc-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}.shop-card{background:#fff;border:1px solid #e2e8f0;border-radius:14px;padding:16px;box-shadow:0 4px 14px rgba(15,23,42,.04)}.h5-header{background:#111827;color:#fff;padding:14px 16px;font-size:18px}.h5-wrap{padding:16px}.h5-card{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:14px;margin-bottom:12px}.price{color:#dc2626;font-weight:700;font-size:20px}.price-sm{color:#dc2626;font-size:18px;font-weight:700}a{color:#2563eb;text-decoration:none}

View File

@@ -0,0 +1 @@
body{background:#0b1220}a{color:#7dd3fc}.layout{grid-template-columns:240px 1fr}.sidebar{background:#102033;border-right:1px solid #22384f}.sidebar-link{color:#d0deea}.sidebar-link:hover{background:#19314a}.sidebar-brand{margin-top:0}.card{background:#111827}.card-dark{background:#0f172a}.card-dashed{border-style:dashed}.grid{grid-template-columns:repeat(5,1fr)}.badge-scope{background:#0c4a6e;color:#bae6fd}.badge-success{background:#dcfce7;color:#166534}.badge-info{background:#dbeafe;color:#1d4ed8}.focus-box,.nav-box,.profile-box{padding:12px;border:1px solid #334155;border-radius:8px}.login-page{background:#031525}.login-card{background:#102033;border:1px solid #2f4a68}.login-form input,.login-form button{border:1px solid #4c6a88;background:#0b1827}.login-form button{background:#0ea5e9;border:none}

0
public/favicon.ico Normal file
View File

20
public/index.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
// Determine if the application is in maintenance mode...
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
require $maintenance;
}
// Register the Composer autoloader...
require __DIR__.'/../vendor/autoload.php';
// Bootstrap Laravel and handle the request...
/** @var Application $app */
$app = require_once __DIR__.'/../bootstrap/app.php';
$app->handleRequest(Request::capture());

2
public/robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: