文件
fenleixinxi/application/admin/view/index/login.html
MiAn 5b616634ab feat: 重构运营看板,新增多维度数据展示与交互功能
新增同城便民生活服务平台标识,重构看板为业务总览与运营看板
新增待办督办中心、营收构成分析、热门分类与区域排行等模块
新增近7/14/30天多时段趋势切换,支持发布量/订单额/用户/曝光量指标切换
新增平台商业与生态资产统计模块,新增待办预警与空状态提示
新增趋势数据汇总与明细表联动,优化响应式布局与交互样式
新增商家管理、举报投诉等语言翻译项,新增登录推荐图
2026-10-30 17:39:15 +08:00

1228 行
44 KiB
HTML
可执行文件

<!DOCTYPE html>
<html lang="zh-cn">
<head>
{include file="common/meta" /}
<title>山间小仓 · 同城农品供求信息发布与管理后台</title>
<style type="text/css">
:root {
--primary: #006948;
--primary-hover: #00855d;
--primary-active: #00563a;
--primary-light: #e6f7f0;
--primary-fixed: #85f8c4;
--on-primary: #ffffff;
--secondary-container: #c4f5de;
--on-secondary-container: #00533a;
--amber-start: #ffddb8;
--amber-mid: #ffc885;
--amber-end: #ffb95f;
--amber-text: #2a1700;
--amber-sub: #653e00;
--bg-canvas: #ffffff;
--bg-input: #f8fafc;
--bg-input-hover: #f1f5f9;
--border-line: #e2e8f0;
--border-line-hover: #cbd5e1;
--text-heading: #0b1c30;
--text-body: #334155;
--text-muted: #64748b;
--text-placeholder: #94a3b8;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 20px;
--radius-full: 9999px;
--shadow-card: 0 20px 45px -15px rgba(0, 30, 20, 0.25);
--shadow-btn: 0 10px 22px -5px rgba(0, 105, 72, 0.38);
}
/* 基础层样式重置与抗锯齿优化 */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
min-height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
background: var(--bg-canvas);
color: var(--text-body);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
/* 主视口双栏布局 */
.login-wrap {
display: flex;
min-height: 100vh;
width: 100%;
}
/* ================= 左侧沉浸式农业生态展屏 ================= */
.hero-panel {
position: relative;
flex: 0 0 54%;
width: 54%;
min-height: 100vh;
background: var(--primary);
padding: 48px 56px 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
color: #ffffff;
user-select: none;
}
/* 柔和环境光晕 */
.ambient-glow-top {
position: absolute;
top: -120px;
right: -120px;
width: 480px;
height: 480px;
border-radius: 50%;
background: rgba(0, 133, 93, 0.45);
filter: blur(80px);
pointer-events: none;
}
.ambient-glow-bottom {
position: absolute;
bottom: 20px;
left: -80px;
width: 380px;
height: 380px;
border-radius: 50%;
background: rgba(133, 248, 196, 0.16);
filter: blur(70px);
pointer-events: none;
}
/* 中部 Bento 堆叠展区 */
.bento-stage {
position: relative;
z-index: 2;
max-width: 580px;
width: 100%;
margin: auto;
padding: 10px 0;
}
/* 装饰手绘涂鸦星线 */
.accent-sparkle {
position: absolute;
top: -10px;
left: -12px;
width: 42px;
height: 42px;
color: rgba(133, 248, 196, 0.85);
pointer-events: none;
}
.bento-stack {
position: relative;
}
/* Card 1: 核心数据走势看板 */
.card-analytics {
position: relative;
z-index: 1;
width: 82%;
background: #ffffff;
color: var(--text-heading);
border-radius: var(--radius-xl);
padding: 24px 24px 28px;
box-shadow: var(--shadow-card);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card-analytics:hover {
transform: translateY(-2px);
box-shadow: 0 25px 50px -15px rgba(0, 30, 20, 0.35);
}
.analytics-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 12px;
}
.analytics-meta-title {
font-size: 13px;
color: var(--text-muted);
font-weight: 500;
}
.analytics-num-row {
display: flex;
align-items: baseline;
gap: 10px;
margin-top: 4px;
}
.analytics-main-val {
font-size: 32px;
font-weight: 700;
color: var(--text-heading);
line-height: 1.1;
letter-spacing: -0.02em;
}
.analytics-badge-inc {
display: inline-flex;
align-items: center;
gap: 3px;
padding: 2px 8px;
border-radius: var(--radius-full);
background: var(--primary-fixed);
color: #002114;
font-size: 11.5px;
font-weight: 700;
}
.analytics-date-filter {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 5px 10px;
border-radius: var(--radius-sm);
background: #f1f5f9;
color: var(--text-heading);
font-size: 11.5px;
font-weight: 600;
}
.analytics-date-filter svg {
width: 13px;
height: 13px;
color: var(--primary);
}
/* SVG 走势图表容器 */
.chart-box {
position: relative;
width: 100%;
height: 105px;
margin-top: 6px;
}
.chart-box svg {
width: 100%;
height: 100%;
overflow: visible;
}
.chart-tooltip-floating {
position: absolute;
top: 0;
left: 58%;
transform: translateX(-50%);
background: #ffffff;
border-radius: var(--radius-sm);
padding: 4px 10px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
text-align: center;
white-space: nowrap;
pointer-events: none;
border: 1px solid rgba(0, 105, 72, 0.08);
}
.tooltip-title {
display: block;
font-size: 11.5px;
font-weight: 700;
color: var(--primary);
line-height: 1.3;
}
.tooltip-sub {
display: block;
font-size: 10px;
color: var(--text-muted);
line-height: 1.2;
}
.chart-axis-months {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 8px;
font-size: 11px;
color: var(--text-muted);
}
.chart-axis-months span.active {
font-weight: 700;
color: var(--primary);
}
/* Card 2: 黄金推荐农品展示卡片 */
.card-showcase {
position: absolute;
z-index: 3;
top: 12px;
right: -10px;
width: 47%;
background: linear-gradient(135deg, var(--amber-start) 0%, var(--amber-mid) 50%, var(--amber-end) 100%);
border-radius: var(--radius-xl);
padding: 16px;
box-shadow: 0 25px 45px -10px rgba(0, 0, 0, 0.3);
color: var(--amber-text);
transform: rotate(2.5deg);
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease;
}
.card-showcase:hover {
transform: rotate(0deg) scale(1.02);
box-shadow: 0 30px 50px -10px rgba(0, 0, 0, 0.36);
}
.showcase-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.showcase-tag {
font-size: 11px;
font-weight: 800;
letter-spacing: 0.05em;
color: var(--amber-sub);
}
.showcase-badge-pill {
padding: 2px 7px;
border-radius: var(--radius-full);
background: var(--amber-text);
color: var(--amber-start);
font-size: 9.5px;
font-weight: 700;
}
.showcase-img-wrap {
position: relative;
width: 100%;
height: 130px;
border-radius: var(--radius-md);
overflow: hidden;
margin-bottom: 10px;
background: #e2e8f0;
}
.showcase-img-wrap img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.showcase-img-cover {
position: absolute;
inset: 0;
background: linear-gradient(180deg, transparent 40%, rgba(0, 0, 0, 0.75) 100%);
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 8px 10px;
color: #ffffff;
}
.cover-title {
font-size: 13px;
font-weight: 700;
line-height: 1.3;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.cover-desc {
font-size: 10px;
color: rgba(255, 255, 255, 0.85);
line-height: 1.2;
margin-top: 2px;
}
.showcase-foot {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
}
.trace-badge {
display: flex;
align-items: center;
gap: 4px;
font-size: 10.5px;
font-weight: 700;
color: var(--amber-text);
}
.trace-badge svg {
width: 14px;
height: 14px;
color: var(--amber-sub);
}
.spec-pill {
padding: 3px 7px;
border-radius: var(--radius-sm);
background: rgba(101, 62, 0, 0.12);
color: var(--amber-sub);
font-size: 10px;
font-weight: 700;
white-space: nowrap;
}
/* Card 3: 分类分布小卡片 */
.card-distribution {
position: relative;
z-index: 2;
width: 63%;
margin-top: -12px;
margin-left: 18px;
background: #ffffff;
color: var(--text-heading);
border-radius: var(--radius-xl);
padding: 16px 20px;
box-shadow: 0 16px 36px -10px rgba(0, 30, 20, 0.22);
transition: transform 0.25s ease;
}
.card-distribution:hover {
transform: translateY(-2px);
}
.dist-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.dist-title {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: 700;
color: var(--text-heading);
}
.dist-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--primary);
}
.dist-tab-group {
display: flex;
gap: 4px;
font-size: 10.5px;
}
.dist-tab {
padding: 2px 7px;
border-radius: 4px;
color: var(--text-muted);
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.dist-tab.active {
background: var(--primary-fixed);
color: #002114;
font-weight: 700;
}
.dist-item {
margin-bottom: 9px;
}
.dist-item:last-child {
margin-bottom: 0;
}
.dist-item-label {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
margin-bottom: 4px;
}
.dist-name {
color: var(--text-muted);
}
.dist-val {
font-weight: 700;
color: var(--text-heading);
}
.progress-track {
width: 100%;
height: 6px;
border-radius: 999px;
background: #edf2f7;
overflow: hidden;
}
.progress-bar {
height: 100%;
border-radius: 999px;
transition: width 0.6s ease;
}
/* 手绘粉笔线条 */
.chalk-wave {
position: absolute;
right: 20px;
bottom: -20px;
width: 120px;
height: 20px;
color: rgba(255, 255, 255, 0.45);
pointer-events: none;
}
/* 底部大标语与轮播指示器 */
.hero-foot {
position: relative;
z-index: 2;
text-align: center;
max-width: 520px;
margin: 0 auto;
padding-top: 14px;
}
.hero-main-title {
font-size: 28px;
line-height: 1.35;
font-weight: 800;
letter-spacing: -0.01em;
color: #ffffff;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
}
.hero-sub-title {
font-size: 14px;
line-height: 1.7;
color: rgba(255, 255, 255, 0.86);
margin-top: 8px;
max-width: 450px;
margin-left: auto;
margin-right: auto;
}
.hero-dots {
display: flex;
align-items: center;
justify-content: center;
gap: 7px;
margin-top: 18px;
}
.hero-dot {
height: 7px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.35);
transition: all 0.25s ease;
cursor: pointer;
border: none;
padding: 0;
}
.hero-dot.active {
width: 26px;
background: #ffffff;
}
.hero-dot:not(.active) {
width: 7px;
}
.hero-dot:hover:not(.active) {
background: rgba(255, 255, 255, 0.65);
}
/* ================= 右侧登录交互表单区 ================= */
.auth-panel {
position: relative;
flex: 0 0 46%;
width: 46%;
min-height: 100vh;
background: #ffffff;
padding: 44px 64px 32px;
display: flex;
flex-direction: column;
justify-content: space-between;
z-index: 10;
}
/* 顶部品牌 Logo Header */
.auth-brand-head {
display: flex;
align-items: center;
gap: 12px;
user-select: none;
}
.brand-icon-box {
width: 40px;
height: 40px;
border-radius: var(--radius-md);
background: var(--primary);
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
box-shadow: 0 4px 12px rgba(0, 105, 72, 0.25);
}
.brand-icon-box svg {
width: 23px;
height: 23px;
}
.brand-title-wrap {
display: flex;
align-items: center;
gap: 8px;
}
.brand-name {
font-size: 22px;
font-weight: 700;
color: var(--text-heading);
letter-spacing: -0.01em;
}
.brand-badge {
font-size: 11.5px;
font-weight: 600;
padding: 3px 9px;
border-radius: var(--radius-full);
background: var(--secondary-container);
color: var(--on-secondary-container);
}
/* 表单居中容器 */
.auth-center-box {
width: 100%;
max-width: 420px;
margin: 40px auto;
}
/* 表单引导语 */
.auth-heading-wrap {
margin-bottom: 26px;
}
.auth-main-title {
font-size: 26px;
font-weight: 800;
color: var(--text-heading);
letter-spacing: -0.01em;
line-height: 1.25;
}
.auth-sub-desc {
font-size: 13.5px;
color: var(--text-muted);
margin-top: 6px;
line-height: 1.5;
}
/* 错误提示框 */
#errtips {
margin-bottom: 18px;
padding: 10px 14px;
border-radius: var(--radius-sm);
background: #fff1f0;
border: 1px solid #ffccc7;
color: #cf1322;
font-size: 13px;
display: none;
align-items: center;
gap: 8px;
animation: shake 0.3s ease-in-out;
}
#errtips:not(:empty) {
display: flex;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
20%, 60% { transform: translateX(-4px); }
40%, 80% { transform: translateX(4px); }
}
/* 表单控件项 */
.form-row {
margin-bottom: 16px;
position: relative;
}
.input-group-modern {
position: relative;
display: flex;
align-items: center;
width: 100%;
}
.input-left-icon {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
color: var(--text-placeholder);
pointer-events: none;
z-index: 2;
transition: color 0.2s ease;
}
.form-input-modern {
width: 100%;
height: 50px;
padding: 0 16px 0 46px;
background: var(--bg-input) !important;
border: 1.5px solid transparent !important;
border-radius: var(--radius-md) !important;
font-size: 14px !important;
color: var(--text-heading) !important;
outline: none !important;
box-shadow: none !important;
transition: all 0.2s ease !important;
}
.form-input-modern::placeholder {
color: var(--text-placeholder);
font-size: 13.5px;
}
.form-input-modern:hover {
background: var(--bg-input-hover) !important;
}
.form-input-modern:focus {
background: #ffffff !important;
border-color: var(--primary) !important;
box-shadow: 0 0 0 3.5px rgba(0, 105, 72, 0.12) !important;
}
.input-group-modern:focus-within .input-left-icon {
color: var(--primary);
}
/* 校验失败红色警示态 */
.form-input-modern.n-invalid,
.has-error .form-input-modern {
border-color: #e05b52 !important;
box-shadow: 0 0 0 3.5px rgba(224, 91, 82, 0.12) !important;
}
/* 密码切换小眼睛按钮 */
.pwd-eye-btn {
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
background: transparent;
border: none;
padding: 4px;
color: var(--text-placeholder);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
transition: color 0.15s;
}
.pwd-eye-btn:hover {
color: var(--primary);
}
.pwd-eye-btn svg {
width: 20px;
height: 20px;
}
/* 验证码行 */
.captcha-flex-row {
display: flex;
align-items: center;
gap: 12px;
}
.captcha-flex-row .input-group-modern {
flex: 1;
}
.captcha-img-box {
position: relative;
height: 50px;
min-width: 135px;
padding: 0 10px;
background: var(--bg-input);
border: 1.5px solid var(--border-line);
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
overflow: hidden;
transition: all 0.2s ease;
user-select: none;
}
.captcha-img-box:hover {
background: #f1f5f9;
border-color: var(--primary);
}
.captcha-img-box img {
height: 38px;
width: auto;
display: block;
}
.captcha-refresh-icon {
width: 15px;
height: 15px;
color: var(--text-placeholder);
transition: transform 0.3s ease, color 0.2s ease;
flex-shrink: 0;
}
.captcha-img-box:hover .captcha-refresh-icon {
color: var(--primary);
transform: rotate(180deg);
}
/* 记住我与忘记密码 */
.auth-actions-row {
display: flex;
align-items: center;
justify-content: space-between;
margin: 4px 0 22px;
}
.checkbox-label {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 13.5px;
color: var(--text-body);
cursor: pointer;
user-select: none;
margin: 0;
font-weight: 400;
}
.checkbox-label input[type="checkbox"] {
width: 17px;
height: 17px;
border-radius: 4px;
accent-color: var(--primary);
cursor: pointer;
}
.forgot-link {
font-size: 13px;
font-weight: 600;
color: var(--primary);
text-decoration: none;
transition: color 0.15s;
}
.forgot-link:hover {
color: var(--primary-hover);
text-decoration: underline;
}
/* 登录提交大按钮 */
.btn-submit-login {
width: 100%;
height: 50px;
border: none;
border-radius: var(--radius-md);
background: var(--primary);
color: #ffffff !important;
font-size: 15px;
font-weight: 700;
letter-spacing: 0.02em;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
box-shadow: var(--shadow-btn);
cursor: pointer;
transition: all 0.2s ease;
}
.btn-submit-login:hover {
background: var(--primary-hover);
box-shadow: 0 14px 26px -5px rgba(0, 105, 72, 0.45);
transform: translateY(-1px);
}
.btn-submit-login:active {
transform: scale(0.99);
background: var(--primary-active);
}
.btn-submit-login svg {
width: 18px;
height: 18px;
transition: transform 0.2s ease;
}
.btn-submit-login:hover svg {
transform: translateX(3px);
}
/* 页脚版权 */
.auth-footer {
font-size: 12.5px;
color: var(--text-placeholder);
line-height: 1.6;
user-select: none;
}
/* ================= 移动与平板端响应式适配 ================= */
@media (max-width: 1080px) {
.hero-panel {
display: none;
}
.auth-panel {
flex: 0 0 100%;
width: 100%;
padding: 40px 24px 28px;
}
.auth-center-box {
max-width: 440px;
margin: 32px auto;
}
}
@media (max-width: 480px) {
.auth-panel {
padding: 24px 16px 20px;
}
.auth-main-title {
font-size: 22px;
}
.captcha-flex-row {
flex-direction: column;
align-items: stretch;
}
.captcha-img-box {
height: 46px;
}
}
</style>
</head>
<body>
<div class="login-wrap">
<!-- ===== 左侧沉浸式农业生态展屏 ===== -->
<aside class="hero-panel">
<!-- 环形背景柔光 -->
<div class="ambient-glow-top"></div>
<div class="ambient-glow-bottom"></div>
<!-- 中部 Bento 堆叠展区 -->
<div class="bento-stage">
<!-- 矢量手绘突起装饰线 -->
<svg class="accent-sparkle" viewBox="0 0 40 40" fill="none">
<path d="M6 10L14 16M2 24H12M8 34L15 27" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
</svg>
<div class="bento-stack">
<!-- Card 1: 核心数据走势看板 -->
<div class="card-analytics">
<div class="analytics-head">
<div>
<div class="analytics-meta-title">今日有效供求发布量 (条)</div>
<div class="analytics-num-row">
<span class="analytics-main-val">56,345.98</span>
<span class="analytics-badge-inc">
<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline>
<polyline points="17 6 23 6 23 12"></polyline>
</svg>
+23.5%
</span>
</div>
</div>
<div class="analytics-date-filter">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
<line x1="16" y1="2" x2="16" y2="6"></line>
<line x1="8" y1="2" x2="8" y2="6"></line>
<line x1="3" y1="10" x2="21" y2="10"></line>
</svg>
<span>最近7个月</span>
</div>
</div>
<!-- SVG 走势图表 -->
<div class="chart-box">
<svg viewBox="0 0 380 90" fill="none">
<line x1="0" y1="20" x2="380" y2="20" stroke="#f1f5f9" stroke-width="1"></line>
<line x1="0" y1="50" x2="380" y2="50" stroke="#f1f5f9" stroke-width="1"></line>
<line x1="0" y1="80" x2="380" y2="80" stroke="#f1f5f9" stroke-width="1"></line>
<!-- 黄色平滑走势曲线 -->
<path d="M10 70 C 60 70, 90 35, 150 45 C 210 55, 270 20, 320 40 C 350 50, 370 25, 375 22" fill="none" stroke="#ffb95f" stroke-width="2.5" stroke-linecap="round"></path>
<!-- 翡翠绿主峰曲线 -->
<path d="M10 55 C 70 55, 110 68, 160 50 C 210 32, 260 62, 300 28 C 340 -2, 365 30, 375 18" fill="none" stroke="#006948" stroke-width="3" stroke-linecap="round"></path>
<!-- 4月高亮区块与圆点 -->
<rect x="258" y="15" width="28" height="65" rx="6" fill="#85f8c4" fill-opacity="0.38"></rect>
<circle cx="272" cy="38" r="4.5" fill="#006948"></circle>
</svg>
<!-- 悬浮数据气泡 -->
<div class="chart-tooltip-floating">
<span class="tooltip-title">四月 (供求峰值)</span>
<span class="tooltip-sub">产销对接意向</span>
</div>
</div>
<!-- 月份横轴刻度 -->
<div class="chart-axis-months">
<span>一月</span>
<span>二月</span>
<span>三月</span>
<span class="active">四月 (供求峰值)</span>
<span>五月</span>
<span>六月</span>
</div>
</div>
<!-- Card 2: 黄金推荐农品展示卡片 -->
<div class="card-showcase">
<div class="showcase-header">
<span class="showcase-tag">2025 推荐农品</span>
<span class="showcase-badge-pill">最新供应发布</span>
</div>
<div class="showcase-img-wrap">
<img src="__CDN__/assets/img/login-recommend.jpg" alt="径山高山富硒草莓">
<div class="showcase-img-cover">
<div class="cover-title">径山高山富硒草莓</div>
<div class="cover-desc">余杭农科直供基地 · 晨采现发</div>
</div>
</div>
<div class="showcase-foot">
<div class="trace-badge">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg>
<span>产地溯源凭证已核实</span>
</div>
<span class="spec-pill">余杭现货 · 支持看样</span>
</div>
</div>
<!-- Card 3: 分类分布小卡片 -->
<div class="card-distribution">
<div class="dist-head">
<div class="dist-title">
<span class="dist-dot"></span>
<span>发布分类分布</span>
</div>
<div class="dist-tab-group">
<span class="dist-tab active">本月</span>
<span class="dist-tab">本周</span>
</div>
</div>
<div class="dist-item">
<div class="dist-item-label">
<span class="dist-name">时令果蔬供给信息 (65%)</span>
<span class="dist-val">48,345 条</span>
</div>
<div class="progress-track">
<div class="progress-bar" style="width: 65%; background: var(--primary);"></div>
</div>
</div>
<div class="dist-item">
<div class="dist-item-label">
<span class="dist-name">生鲜采购寻源需求 (25%)</span>
<span class="dist-val">18,200 条</span>
</div>
<div class="progress-track">
<div class="progress-bar" style="width: 25%; background: var(--amber-end);"></div>
</div>
</div>
<div class="dist-item">
<div class="dist-item-label">
<span class="dist-name">农技与设施农品发布 (10%)</span>
<span class="dist-val">6,840 条</span>
</div>
<div class="progress-track">
<div class="progress-bar" style="width: 10%; background: #7bd8b1;"></div>
</div>
</div>
</div>
<!-- 手绘粉笔线条 -->
<svg class="chalk-wave" viewBox="0 0 140 20" fill="none">
<path d="M4 14C35 4 80 18 136 6M10 18C45 10 95 14 128 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
</svg>
</div>
</div>
<!-- 底部大标题与指示器 -->
<div class="hero-foot">
<h1 class="hero-main-title">汇聚源头农品信息<br>赋能同城产销撮合对接</h1>
<p class="hero-sub-title">一站式同城涉农信息发布中台,连通种植基地与采购需求,让优质农品供应与求购信息精准透明触达。</p>
<div class="hero-dots">
<button type="button" class="hero-dot active" aria-label="第1屏"></button>
<button type="button" class="hero-dot" aria-label="第2屏"></button>
<button type="button" class="hero-dot" aria-label="第3屏"></button>
</div>
</div>
</aside>
<!-- ===== 右侧登录表单区 ===== -->
<main class="auth-panel">
<!-- 品牌 LOGO 顶栏 -->
<header class="auth-brand-head">
<div class="brand-icon-box">
<!-- 生态叶片矢量图标 -->
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
<path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z"></path>
<path d="M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12"></path>
</svg>
</div>
<div class="brand-title-wrap">
<span class="brand-name">山间小仓</span>
<span class="brand-badge">发布中心</span>
</div>
</header>
<!-- 表单垂直居中主体 -->
<div class="auth-center-box">
<!-- 标题引导语 -->
<div class="auth-heading-wrap">
<h2 class="auth-main-title">登录您的账号</h2>
<p class="auth-sub-desc">山间小仓 · 同城农品供求信息发布与管理后台</p>
</div>
<!-- FastAdmin 表单开始 -->
<form action="" method="post" id="login-form">
<!--@AdminLoginFormBegin-->
<div id="errtips"></div>
{:token()}
<!-- 账号输入 -->
<div class="form-row">
<div class="input-group-modern">
<!-- 工牌/用户矢量图标 -->
<svg class="input-left-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path>
<circle cx="9" cy="7" r="4"></circle>
<path d="M22 21v-2a4 4 0 0 0-3-3.87"></path>
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
</svg>
<input type="text"
class="form-control form-input-modern"
id="pd-form-username"
name="username"
placeholder="请输入管理员账号"
autocomplete="off"
value=""
data-rule="{:__('Username')}:required;username"/>
</div>
</div>
<!-- 密码输入 -->
<div class="form-row">
<div class="input-group-modern">
<!-- 锁矢量图标 -->
<svg class="input-left-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>
<input type="password"
class="form-control form-input-modern"
id="pd-form-password"
name="password"
placeholder="请输入登录密码"
autocomplete="off"
value=""
data-rule="{:__('Password')}:required;password"/>
<!-- 切换密码明文/密文小眼睛 -->
<button type="button" class="pwd-eye-btn" id="toggle-pwd-btn" aria-label="切换密码可见性" title="切换密码可见性">
<svg id="eye-icon-off" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path>
<line x1="1" y1="1" x2="23" y2="23"></line>
</svg>
<svg id="eye-icon-on" style="display: none;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
<circle cx="12" cy="12" r="3"></circle>
</svg>
</button>
</div>
</div>
<!-- 验证码输入 -->
<!--@CaptchaBegin-->
{if $Think.config.fastadmin.login_captcha}
<div class="form-row">
<div class="captcha-flex-row">
<div class="input-group-modern">
<!-- 盾牌安全图标 -->
<svg class="input-left-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg>
<input type="text"
name="captcha"
id="pd-form-captcha"
class="form-control form-input-modern"
placeholder="请输入4位验证码"
maxlength="4"
data-rule="{:__('Captcha')}:required;length({$Think.config.captcha.length|htmlentities})"
autocomplete="off"/>
</div>
<div class="captcha-img-box input-group-addon" id="captcha-box" title="点击刷新验证码">
<img src="{:rtrim('__PUBLIC__', '/')}/index.php?s=/captcha"
alt="验证码"
id="captcha-img"
onclick="this.src = '{:rtrim('__PUBLIC__', '/')}/index.php?s=/captcha&r=' + Math.random();"/>
<svg class="captcha-refresh-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<polyline points="23 4 23 10 17 10"></polyline>
<polyline points="1 20 1 14 7 14"></polyline>
<path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
</svg>
</div>
</div>
</div>
{/if}
<!--@CaptchaEnd-->
<!-- 记住我与忘记密码 -->
<div class="auth-actions-row">
{if $keeyloginhours>0}
<label class="checkbox-label" for="keeplogin" title="{:__('The duration of the session is %s hours', $keeyloginhours)}">
<input type="checkbox" name="keeplogin" id="keeplogin" value="1" checked/>
<span>记住我</span>
</label>
{else}
<div></div>
{/if}
<a href="javascript:void(0);" class="forgot-link" id="btn-forgot-pwd">忘记密码?</a>
</div>
<!-- 提交登录按钮 -->
<button type="submit" class="btn btn-submit-login">
<span>立即安全登录</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<line x1="5" y1="12" x2="19" y2="12"></line>
<polyline points="12 5 19 12 12 19"></polyline>
</svg>
</button>
<!--@AdminLoginFormEnd-->
</form>
</div>
<!-- 页脚版权 -->
<footer class="auth-footer">
<div>© {:date('Y')} 山间小仓数字农品信息发布网 · 同城分类管理中台</div>
</footer>
</main>
</div>
{include file="common/script" /}
<script>
/**
* 绑定登录页前端交互行为
* 包括密码可见性切换、验证码刷新与管理员联系提示
*/
(function initLoginInteractions() {
// 密码明密文切换逻辑
var pwdInput = document.getElementById('pd-form-password');
var toggleBtn = document.getElementById('toggle-pwd-btn');
var eyeOff = document.getElementById('eye-icon-off');
var eyeOn = document.getElementById('eye-icon-on');
if (toggleBtn && pwdInput) {
toggleBtn.addEventListener('click', function (e) {
e.preventDefault();
var isPassword = pwdInput.type === 'password';
pwdInput.type = isPassword ? 'text' : 'password';
if (eyeOff && eyeOn) {
eyeOff.style.display = isPassword ? 'none' : 'block';
eyeOn.style.display = isPassword ? 'block' : 'none';
}
});
}
// 验证码容器点击刷新逻辑
var captchaBox = document.getElementById('captcha-box');
var captchaImg = document.getElementById('captcha-img');
if (captchaBox && captchaImg) {
captchaBox.addEventListener('click', function () {
captchaImg.src = '{:rtrim("__PUBLIC__", "/")}/index.php?s=/captcha&r=' + Math.random();
});
}
// 忘记密码弹窗指引
var forgotBtn = document.getElementById('btn-forgot-pwd');
if (forgotBtn) {
forgotBtn.addEventListener('click', function () {
if (window.Layer) {
Layer.alert('如需找回或重置管理后台登录密码,请联系系统超级管理员进行身份核验与重置。', {
title: '找回密码指引',
icon: 0,
btn: ['我知道了']
});
} else {
alert('如需找回或重置管理后台登录密码,请联系系统超级管理员进行身份核验与重置。');
}
});
}
// 轮播圆点高亮切换
var dots = document.querySelectorAll('.hero-dot');
dots.forEach(function (dot) {
dot.addEventListener('click', function () {
dots.forEach(function (d) { d.classList.remove('active'); });
dot.classList.add('active');
});
});
})();
</script>
</body>
</html>