统一全部表单控件尺寸与外观;删除下载地址字段
用户:「输入框、按钮、下拉框特别丑,一点设计感都没有,高度太随意,
全面检查一下。还有那个下载链接要它干什么?」
一、表单控件(这是主要工作量)
原来样式散在 6 处(.field / .filter-row / .filters / .mail-test / .admin 各一套),
padding 有 8/9/12px 三种,select 与 input 高度不等,并排放参差不齐。
改成一套体系:
- CSS 变量统一尺度:--ctl-h 38px / --ctl-h-sm 32px / --ctl-h-lg 42px,
统一圆角 9px、统一左右内边距 12px、统一边框与阴影
- 高度用「固定 height + line-height 居中」而不是 padding 撑
- 🔴 选择器必须**宽松**(按 type 通吃,不用 .field 之类限定)。
第一版限制了容器,导致后台零散布局里的裸 select/input 只有 19/21px,
和旁边 38px 按钮并排,正是用户说的高度随意。
放开后实测:19px → 38px,全部一致
- 下拉框自绘箭头(内联 SVG),不再用各平台不一的原生箭头,右侧留 34px
- 搜索框加左侧放大镜图标,并去掉 Chrome 自带清除按钮
- 聚焦统一 brand 光晕,悬停边框加深
- 按钮也改固定 height(原来 padding 撑出 38.3px,与输入框差 0.3px)
- .btn.sm 必须显式改 height,否则 padding 被 height 吃掉、小按钮还是 38px
文件选择按钮:原生控件重做成真按钮
<label class=file-btn> 包住 input[type=file]
input 用 clip 视觉隐藏(不能用 display:none,那样点不到也聚焦不了)
按钮内显示「选择图片」+ 图标 + 选中后的文件名
二、删除「下载地址」字段
它唯一用途:状态改为「已解决」时把邮件按钮换成「下载最新版本」。
收益小、维护成本高(每个软件都要填一条 URL)。
- 后台表单项删除
- mailer 里对应的判断分支也删掉,按钮统一「查看详情」
- ⚠️ 数据库 download_url 列**保留不删**:删列不可逆,万一要恢复还得迁一次
验证(用控件总览测试页 + 真实页面实测):
10 类控件高度全部 38px(文本/数字/下拉/搜索/文件按钮/主按钮/小按钮…),
文本域 110px,同一行垂直中心完全一致(935.3)
裸 select/input 从 19/21px 修正到 38px
下拉箭头 SVG 生效、右内边距 34px;搜索框放大镜生效、左内边距 36px
真实三个页面(提交页/列表页/详情页)逐一检查:
没有 checkbox/radio/file 被误改,所有可见控件高度收敛为 38(文本域 110)
下载地址字段:admin.php 输出与源码中均无 download_url 表单项
5 个路由 200
This commit is contained in:
+19
-5
@@ -993,21 +993,29 @@
|
||||
var wrap = input.closest('.icon-up');
|
||||
if (!wrap) { return; }
|
||||
var prev = wrap.querySelector('.icon-prev');
|
||||
// 按钮上的文件名(可选,新样式才有)
|
||||
var nameEl = wrap.querySelector('[data-file-name]');
|
||||
|
||||
// 状态条:放在文件输入框下面,比页面顶部的提示显眼得多
|
||||
/* 状态条插在**整个文件按钮之后**(不是 input 之后)。
|
||||
* input 现在被包在 <label class="file-btn"> 里,如果插到 input.nextSibling
|
||||
* 会跑到 label 内部,跟按钮文字挤在一起。 */
|
||||
var btn = input.closest('.file-btn') || input;
|
||||
var tip = document.createElement('span');
|
||||
tip.className = 'icon-up-tip';
|
||||
tip.setAttribute('role', 'status');
|
||||
input.parentNode.insertBefore(tip, input.nextSibling);
|
||||
if (btn.parentNode) { btn.parentNode.insertBefore(tip, btn.nextSibling); }
|
||||
|
||||
function setTip(msg, kind) {
|
||||
tip.textContent = msg || '';
|
||||
tip.className = 'icon-up-tip' + (kind ? ' is-' + kind : '');
|
||||
}
|
||||
function setName(txt) {
|
||||
if (nameEl) { nameEl.textContent = txt || ''; }
|
||||
}
|
||||
|
||||
input.addEventListener('change', function () {
|
||||
var f = this.files && this.files[0];
|
||||
if (!f) { setTip(''); return; }
|
||||
if (!f) { setTip(''); setName(''); return; }
|
||||
|
||||
var KB = Math.round(f.size / 1024);
|
||||
var sizeTxt = KB >= 1024 ? (KB / 1024).toFixed(1) + ' MB' : KB + ' KB';
|
||||
@@ -1016,17 +1024,20 @@
|
||||
var okType = /^image\/(png|jpeg|webp)$/.test(f.type);
|
||||
if (!okType) {
|
||||
setTip('✕ 只能选 PNG / JPG / WEBP 图片,当前是「' + (f.type || '未知类型') + '」', 'err');
|
||||
setName('');
|
||||
this.value = '';
|
||||
return;
|
||||
}
|
||||
// ② 大小(后端限 2MB)
|
||||
if (f.size > 2 * 1024 * 1024) {
|
||||
setTip('✕ 图片 ' + sizeTxt + ',超过 2 MB 上限,请压缩后再传', 'err');
|
||||
setName('');
|
||||
this.value = '';
|
||||
return;
|
||||
}
|
||||
if (f.size <= 0) {
|
||||
setTip('✕ 这是个空文件', 'err');
|
||||
setName('');
|
||||
this.value = '';
|
||||
return;
|
||||
}
|
||||
@@ -1038,6 +1049,7 @@
|
||||
img.onload = function () {
|
||||
if (img.width < 32 || img.height < 32) {
|
||||
setTip('✕ 图片只有 ' + img.width + '×' + img.height + ',至少 32×32', 'err');
|
||||
setName('');
|
||||
input.value = '';
|
||||
return;
|
||||
}
|
||||
@@ -1050,16 +1062,18 @@
|
||||
prev.appendChild(el);
|
||||
}
|
||||
var warn = (img.width !== img.height) ? ' ⚠ 不是正方形,显示时会被裁切' : '';
|
||||
setTip('✓ 已选择:' + f.name + '(' + img.width + '×' + img.height + ',' + sizeTxt + ')'
|
||||
setName(f.name);
|
||||
setTip('✓ ' + img.width + '×' + img.height + ',' + sizeTxt
|
||||
+ warn + ' 保存后生效', 'ok');
|
||||
};
|
||||
img.onerror = function () {
|
||||
setTip('✕ 这张图读不出来,可能已损坏', 'err');
|
||||
setName('');
|
||||
input.value = '';
|
||||
};
|
||||
img.src = ev.target.result;
|
||||
};
|
||||
fr.onerror = function () { setTip('✕ 读取文件失败', 'err'); };
|
||||
fr.onerror = function () { setTip('✕ 读取文件失败', 'err'); setName(''); };
|
||||
fr.readAsDataURL(f);
|
||||
});
|
||||
})(inputs[i]);
|
||||
|
||||
+197
-26
@@ -6,6 +6,21 @@
|
||||
--icon-mark:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAADsOAAA7DgHMtqGDAAADj0lEQVR4nO1b205TQRTdGB/UB78B0BdfRNA3NUT/QPHMHIgaP0BeMPqoog8mJqDyCfoBImJnDuCFyEWhIGiUegONimkFodYEaqpj9qEEwZbS0zOXXlaykqZNO2uvM9M9Z8/ZABkhysBy9gLhl4Dwh0B5CAj7CZQLo4iaCJtwNRLWDITVZI4tY+CMAOGvtQfnnSGwnWNuLFmBBnYAZU8NCMAvDoLlVGwseCtwAAgLGyDaZ7IZsJ3D6wdP+CEg7Jd+sdIYBytQm+bKOxVAecQAkfJngsV3rolelBXYms/EgdV/jJRTA0SpJeF1K1c/v1OdRwPYxFL8dtc+7WJ00Q5U4/S/rF2INrKLkNzeiqIkYfcBCHujXYg+hgAoixkgRBNZDHL5gU22IxraxsXdkYiYnlsUid9/hGzgGDhWRzAi6tvGXQ05mQAev1jZ2CtGp6JCN0Ymo64WpQZUNvaKSDQuTEE4GhcVXk0AD9PehCu/FsH3UW/LAbL8Aq55U2HfGJNvQOdoRJiKO8GwfAO+zi0KU/Hl+6J8AxIKUp1XoDbpBqTCp9kFsftsf/aDe2TVuX7xeXYhpRYtBrR0TikLfpmt9z6YY8DQu3mx5XiXsuC3nuh2054xBiBwe9rzYkZ0P5dLHGO9P2JtBpiCkgG0NANEQaTBbSe7xdWOyfxYAi2S0uD2Uz35YcCQpDRoXRvLDwNkpMEnb+c9bbu1GWAKSgbQ0gwQUpdAIsW69JoGNzc4oq71mW+32Epuh6dT7MNzTYNY2fUDeIss3YCOYMTXNIjV3NhCwhcDbg8pKInVpymKekmDj17O+hY8gl5XUBTdZDu+TVk/MayqLA7JgxE8jDAFqKX8tKKDEfhn7aaryqi+8p5PhWgOBiwvBzyMwHo8lqRVHY7iWO3DYXfNazscBQ88cyuUMcCmmyFlekC1Acgr7env8fEz1XpA+YDJ88WP31bq+vga39OhBbQMmtwG72p67BJf69IB2gY2haBbgG4C5T+0i9BFwqNQlI/JrnpclrIHxf6gZLN2Ifp4Hg2oKd4ZwKuSzRI8VHzBs1crDRPYWqZbkGragSNrWmb4oHZRysj6/u8lpKy8aJqmsC8yTc9grdtapl2kNMaBsoMZeged/QXbOIl9kRuC5fYQDhRQ8H3uEs8OArvJ6tztovYAckh1lB2FnGEHqt0GI9w6uoaY2GXCYkvt86iRXwDL2bOR0P4Cy8Hrhv+SooQAAAAASUVORK5CYII=");
|
||||
--ok:#0f9d58; --ok-soft:#e9f7ef; --warn:#b7791f; --warn-soft:#fff8e6;
|
||||
--danger:#d93025; --danger-soft:#fdecea; --shadow:0 1px 3px rgba(16,24,40,.06);
|
||||
/* ── 表单控件尺度(2026-11-04 统一)──
|
||||
* 用户:「输入框、下拉框高度太随意,一点设计感都没有。」
|
||||
* 之前 padding 有 8px/9px/12px 三种,select 和 input 高度还不一样,
|
||||
* 并排放在一起参差不齐。现在只保留三档,全部按高度对齐:
|
||||
* --ctl-h-sm 32px 表格内 / 紧凑行
|
||||
* --ctl-h 38px 常规表单(默认)
|
||||
* --ctl-h-lg 42px 主要操作区
|
||||
* 高度用固定值 + line-height 居中的方式,而不是靠 padding 撑,
|
||||
* 这样 input / select / button 放同一行时基线必然一致。 */
|
||||
--ctl-h-sm:32px; --ctl-h:38px; --ctl-h-lg:42px;
|
||||
--ctl-r:9px; /* 统一圆角 */
|
||||
--ctl-px:12px; /* 统一左右内边距 */
|
||||
--ctl-bd:1px solid var(--line-strong);
|
||||
--ctl-shadow:0 1px 2px rgba(16,24,40,.04);
|
||||
--ctl-shadow-focus:0 0 0 3px var(--brand-soft);
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
html{-webkit-text-size-adjust:100%}
|
||||
@@ -181,10 +196,19 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.foot-line .dot{padding:0}
|
||||
|
||||
/* ---------- 按钮 ---------- */
|
||||
/* 按钮高度与输入框严格一致(--ctl-h)。
|
||||
* 🔴 原来靠 padding:8px + line-height:1.4 撑,算出来 38.3px,
|
||||
* 而输入框是固定 38px —— 并排时差 0.3px,放大看会有轻微的错位感。
|
||||
* 改成固定 height + inline-flex 垂直居中,与控件完全同高。 */
|
||||
.btn{
|
||||
display:inline-block; border:1px solid var(--line-strong); background:var(--card);
|
||||
color:var(--fg); border-radius:9px; padding:8px 16px; font-size:14.5px;
|
||||
cursor:pointer; line-height:1.4; font-family:inherit;
|
||||
display:inline-flex; align-items:center; justify-content:center;
|
||||
height:var(--ctl-h); padding:0 16px;
|
||||
border:1px solid var(--line-strong); background:var(--card);
|
||||
color:var(--fg); border-radius:var(--ctl-r);
|
||||
font-size:14.5px; line-height:1;
|
||||
cursor:pointer; font-family:inherit; white-space:nowrap;
|
||||
box-shadow:var(--ctl-shadow);
|
||||
transition:border-color .12s, background .12s, color .12s;
|
||||
}
|
||||
.btn:hover{border-color:var(--brand); color:var(--brand); text-decoration:none}
|
||||
.btn.primary{background:var(--brand); border-color:var(--brand); color:#fff; font-weight:600}
|
||||
@@ -361,8 +385,10 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
width:100%; height:100%; display:flex; align-items:center; justify-content:center;
|
||||
color:#fff; font-size:24px; font-weight:600;
|
||||
}
|
||||
.icon-up-main{flex:1; min-width:220px; display:flex; flex-direction:column}
|
||||
.icon-up-main input[type=file]{font-size:13.5px; max-width:100%}
|
||||
.icon-up-main{flex:1; min-width:220px; display:flex; flex-direction:column; align-items:flex-start}
|
||||
/* ⚠️ 不要在这里给 input[type=file] 设任何样式 ——
|
||||
* 它已被 .file-btn 视觉隐藏(clip),设 max-width/font-size 之类
|
||||
* 会把它从"视觉隐藏"变成"露出一个小方块",反而破坏新按钮外观。 */
|
||||
/* 上传状态提示:选中文件后立刻告诉用户「选到了什么、合不合格」。
|
||||
* 用户 2026-11-04:「上传的图标没有显示,也没有成功/失败提示。」 */
|
||||
.icon-up-tip{
|
||||
@@ -469,7 +495,7 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
font-family:ui-monospace,Menlo,Consolas,monospace; font-size:13px;
|
||||
text-transform:uppercase; background:var(--card); color:var(--fg);
|
||||
}
|
||||
.cp-ok{flex:none; padding:6px 14px !important; font-size:13px !important}
|
||||
.cp-ok{flex:none; height:32px !important; padding:0 14px !important; font-size:13px !important}
|
||||
.color-presets{display:flex; gap:6px; flex-wrap:wrap}
|
||||
.color-preset{
|
||||
width:26px; height:26px; border-radius:50%; border:2px solid transparent;
|
||||
@@ -486,8 +512,7 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
}
|
||||
.mail-test input[type=email]{
|
||||
flex:1 1 220px; min-width:180px;
|
||||
border:1px solid var(--line-strong); border-radius:9px; padding:8px 10px;
|
||||
font-size:14px; background:var(--card); color:var(--fg); font-family:inherit;
|
||||
/* 边框/高度/圆角统一在「统一表单控件」段里定义,这里只管宽度 */
|
||||
}
|
||||
.mail-test-out{flex:1 1 100%; font-size:13px; line-height:1.6}
|
||||
.mail-test-out.ok{color:var(--ok)}
|
||||
@@ -538,7 +563,9 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.tax-note{margin-top:5px; font-size:13px; color:var(--muted); line-height:1.5}
|
||||
.tax-acts{display:flex; flex-wrap:wrap; gap:6px; align-items:center}
|
||||
.inline-form{display:inline}
|
||||
.btn.sm{padding:5px 11px; font-size:13px; border-radius:8px}
|
||||
/* 小号按钮:基类是固定 height,这里必须显式改 height 而不是改 padding,
|
||||
* 否则 padding 会被 height 吃掉、按钮还是 38px 高。 */
|
||||
.btn.sm{height:var(--ctl-h-sm); padding:0 11px; font-size:13px; border-radius:8px}
|
||||
.btn.danger{border-color:#e0b4b4; color:#b4242c}
|
||||
.btn.danger:hover{background:#fdf2f2; border-color:#b4242c}
|
||||
.tax-form-box{
|
||||
@@ -571,12 +598,8 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
}
|
||||
.chip:hover{border-color:var(--brand); color:var(--brand); text-decoration:none}
|
||||
.chip.on{background:var(--brand); border-color:var(--brand); color:#fff; font-weight:600}
|
||||
.filter-row{display:flex; flex-wrap:wrap; gap:8px}
|
||||
.filter-row select,.filter-row input[type=search]{
|
||||
border:1px solid var(--line-strong); border-radius:9px; padding:8px 10px;
|
||||
font-size:14px; background:var(--card); color:var(--fg); font-family:inherit;
|
||||
}
|
||||
.filter-row input[type=search]{flex:1; min-width:160px}
|
||||
.filter-row{display:flex; flex-wrap:wrap; gap:9px; align-items:center}
|
||||
/* 控件的具体样式统一在上面的「统一表单控件」段里定义(避免多处覆盖打架) */
|
||||
|
||||
/* ---------- 列表 ---------- */
|
||||
.list{display:flex; flex-direction:column; gap:12px}
|
||||
@@ -741,7 +764,149 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.reply-body{word-break:break-word; line-height:1.8}
|
||||
|
||||
/* ---------- 表单 ---------- */
|
||||
/* 提交页容器。
|
||||
/* ══════════════════════════════════════════════════════════════
|
||||
* 统一表单控件(2026-11-04 重做)
|
||||
*
|
||||
* 用户:「输入框、下拉框、选择图片那个按钮、排序输入框、前端筛选的
|
||||
* 输入框下拉框,都特别丑,一点设计感都没有。高度太随意。」
|
||||
*
|
||||
* 之前的问题:
|
||||
* ① 样式散落在 5-6 处(.field / .filter-row / .filters / .admin 各自一套)
|
||||
* ② padding 有 8px / 9px / 12px 三种,select 与 input 高度不等,
|
||||
* 并排放一起参差不齐
|
||||
* ③ select 用浏览器默认箭头,各平台样式不一,还贴边
|
||||
* ④ file input 完全是原始外观
|
||||
*
|
||||
* 现在:一套基类 .ctl + 统一变量,所有控件高度/圆角/边框/聚焦环一致。
|
||||
* 高度用「固定 height + line-height 居中」而不是 padding 撑,
|
||||
* 保证 input / select / button 同行时基线必然对齐。
|
||||
* ══════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* --- 基类:所有文本类控件 ---
|
||||
* 🔴 选择器要**宽松**。之前限定在 .field / .filters 里面,
|
||||
* 结果任何不在这些容器里的控件(后台零散布局里的 select、input)
|
||||
* 都退化成浏览器默认外观,高度只有 19~21px,跟旁边 38px 的按钮并排
|
||||
* 参差不齐 —— 这正是用户说的"高度太随意"。
|
||||
* 现在按 type 通吃,再用 :not() 排除掉不该套的(checkbox/radio/color/file/range)。 */
|
||||
input[type=text]:not(.cp-hex),
|
||||
input[type=email],
|
||||
input[type=tel],
|
||||
input[type=password],
|
||||
input[type=url],
|
||||
input[type=number],
|
||||
input[type=search],
|
||||
select,
|
||||
textarea:not(.cp-hex){
|
||||
height:var(--ctl-h);
|
||||
padding:0 var(--ctl-px);
|
||||
border:var(--ctl-bd);
|
||||
border-radius:var(--ctl-r);
|
||||
background:var(--card);
|
||||
color:var(--fg);
|
||||
font-family:inherit;
|
||||
font-size:14.5px;
|
||||
line-height:calc(var(--ctl-h) - 2px); /* 减掉上下边框,垂直居中 */
|
||||
box-shadow:var(--ctl-shadow);
|
||||
transition:border-color .12s, box-shadow .12s;
|
||||
-webkit-appearance:none;
|
||||
appearance:none;
|
||||
}
|
||||
/* 文本域不能用固定高度 */
|
||||
textarea{height:auto; min-height:110px; padding:9px var(--ctl-px); line-height:1.7; resize:vertical}
|
||||
/* 数字框保留原生上下箭头(用户要改排序,有箭头更直观) */
|
||||
input[type=number]{-moz-appearance:auto; appearance:auto; -webkit-appearance:auto}
|
||||
|
||||
/* --- 聚焦态:统一一圈柔和的 brand 光晕 --- */
|
||||
input[type=text]:focus, input[type=email]:focus, input[type=tel]:focus,
|
||||
input[type=password]:focus, input[type=url]:focus, input[type=number]:focus,
|
||||
input[type=search]:focus, select:focus, textarea:focus{
|
||||
outline:none;
|
||||
border-color:var(--brand);
|
||||
box-shadow:var(--ctl-shadow-focus);
|
||||
}
|
||||
|
||||
/* --- 悬停:边框略深,给出可交互暗示 --- */
|
||||
input[type=text]:hover:not(:focus), input[type=email]:hover:not(:focus),
|
||||
input[type=tel]:hover:not(:focus), input[type=password]:hover:not(:focus),
|
||||
input[type=url]:hover:not(:focus), input[type=number]:hover:not(:focus),
|
||||
input[type=search]:hover:not(:focus), select:hover:not(:focus),
|
||||
textarea:hover:not(:focus){
|
||||
border-color:#c3c9d1;
|
||||
}
|
||||
|
||||
/* --- 下拉框:自绘箭头 ---
|
||||
* 原生箭头各平台差异大且贴边。这里用内联 SVG 画一个 12px 的 V 形,
|
||||
* 右侧留 34px 空间,再给 padding-right 避开它。
|
||||
* ⚠️ 背景必须同时写 background-color 和 background-image,
|
||||
* 否则 -webkit-appearance:none 后底色会丢失。 */
|
||||
.field select,
|
||||
.filter-row select,
|
||||
.filters select,
|
||||
select{
|
||||
padding-right:34px;
|
||||
background-color:var(--card);
|
||||
background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%236b7280' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||||
background-repeat:no-repeat;
|
||||
background-position:right 12px center;
|
||||
cursor:pointer;
|
||||
}
|
||||
select:hover{
|
||||
background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%231f2329' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* --- 搜索框:左侧放大镜图标 --- */
|
||||
.filter-row input[type=search]{flex:1; min-width:170px; padding-left:36px;
|
||||
background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 15 15'%3E%3Ccircle cx='6.2' cy='6.2' r='4.6' fill='none' stroke='%236b7280' stroke-width='1.5'/%3E%3Cpath d='M9.8 9.8 13.4 13.4' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
|
||||
background-repeat:no-repeat;
|
||||
background-position:12px center;
|
||||
}
|
||||
/* 去掉 Chrome 自带的搜索框清除按钮(和我们的图标风格不搭) */
|
||||
.filter-row input[type=search]::-webkit-search-decoration,
|
||||
.filter-row input[type=search]::-webkit-search-cancel-button{
|
||||
-webkit-appearance:none; appearance:none;
|
||||
}
|
||||
|
||||
/* --- 文件选择按钮:把原生丑控件重做成一个真正的按钮 ---
|
||||
* 用户:「选择图片那个按钮太丑。」
|
||||
* 做法:隐藏原生 input(但不能 display:none,否则不可点/不可聚焦),
|
||||
* 用 <label class="file-btn"> 包一个自绘按钮,点击穿透到 input。 */
|
||||
.file-btn{
|
||||
display:inline-flex; align-items:center; gap:9px;
|
||||
height:var(--ctl-h); padding:0 14px 0 12px;
|
||||
border:var(--ctl-bd); border-radius:var(--ctl-r);
|
||||
background:var(--card); color:var(--fg);
|
||||
font-size:14px; font-weight:600; cursor:pointer;
|
||||
box-shadow:var(--ctl-shadow);
|
||||
transition:border-color .12s, background .12s;
|
||||
max-width:100%;
|
||||
}
|
||||
.file-btn:hover{border-color:var(--brand); background:var(--brand-soft); color:var(--brand)}
|
||||
.file-btn:active{transform:translateY(.5px)}
|
||||
.file-btn-ic{
|
||||
width:17px; height:17px; flex:none;
|
||||
background:currentColor;
|
||||
-webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 3v10M6 9l4 4 4-4M4 16h12' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
|
||||
mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 3v10M6 9l4 4 4-4M4 16h12' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
|
||||
}
|
||||
.file-btn-name{
|
||||
font-weight:400; color:var(--muted); font-size:13px;
|
||||
overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:190px;
|
||||
}
|
||||
/* 原生 input 视觉隐藏,但仍可点击/可聚焦(不能用 display:none) */
|
||||
.file-btn input[type=file]{
|
||||
position:absolute; width:1px; height:1px; opacity:0;
|
||||
overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap;
|
||||
}
|
||||
|
||||
/* --- 数字框 + 前后缀,让「排序」这种小输入看起来有设计感 --- */
|
||||
.num-wrap{display:inline-flex; align-items:center; gap:0; position:relative}
|
||||
.num-wrap .num-suffix{
|
||||
position:absolute; right:12px; font-size:12.5px; color:var(--muted);
|
||||
pointer-events:none;
|
||||
}
|
||||
.num-wrap input[type=number]{padding-right:44px}
|
||||
|
||||
/* ---------- 提交页容器 */
|
||||
* 🔴 原来只有 max-width:640px,**没有居中** —— 在 880px 的内容区里,
|
||||
* 表单贴左边、右侧空出 240px 白,看起来像"页面缺了一块"。
|
||||
* 用户 2026-11-03 指出这一点。现在:加 margin 居中,宽度放到 720px,
|
||||
@@ -818,16 +983,22 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
||||
.field > span{display:block; font-size:14px; font-weight:600; margin-bottom:6px}
|
||||
.field .req{color:var(--danger)}
|
||||
.field .hint{font-style:normal; font-weight:400; font-size:12.5px; color:var(--muted); margin-left:6px}
|
||||
.field input[type=text],.field input[type=email],.field input[type=tel],
|
||||
.field input[type=password],.field textarea,.field select{
|
||||
width:100%; border:1px solid var(--line-strong); border-radius:9px;
|
||||
padding:9px 12px; font-size:15px; font-family:inherit; background:var(--card);
|
||||
color:var(--fg); line-height:1.6;
|
||||
}
|
||||
.field textarea{resize:vertical; min-height:110px}
|
||||
.field input:focus,.field textarea:focus,.field select:focus{
|
||||
outline:none; border-color:var(--brand); box-shadow:0 0 0 3px var(--brand-soft);
|
||||
}
|
||||
/* 控件的边框/高度/圆角/聚焦态统一在上方「统一表单控件」段里定义。
|
||||
* 这里只保留 .field 的宽度约束 —— 表单里的控件一律占满整行。 */
|
||||
.field > input[type=text],
|
||||
.field > input[type=email],
|
||||
.field > input[type=tel],
|
||||
.field > input[type=password],
|
||||
.field > input[type=url],
|
||||
.field > input[type=number],
|
||||
.field > input[type=search],
|
||||
.field > select,
|
||||
.field > textarea{width:100%}
|
||||
/* 短小的数字类字段(如「排序」)不该铺满整行 —— 收窄到 140px,
|
||||
* 视觉上更像"一个小参数"而不是"一个大输入框"。 */
|
||||
.field-narrow{max-width:140px}
|
||||
.field-narrow > input{width:100% !important}
|
||||
@media (max-width:560px){ .field-narrow{max-width:none} }
|
||||
.row2{display:grid; grid-template-columns:1fr 1fr; gap:14px}
|
||||
@media (max-width:560px){ .row2{grid-template-columns:1fr} }
|
||||
|
||||
|
||||
+27
-10
@@ -510,10 +510,19 @@ function fb_admin_taxonomy_page($pdo, $editSw, $editCat) {
|
||||
}
|
||||
echo ' </div>';
|
||||
echo ' <div class="icon-up-main">';
|
||||
echo ' <input type="file" name="icon_file" accept="image/png,image/jpeg,image/webp" id="iconFile' . ($esw ? (int)$esw['id'] : 'new') . '">';
|
||||
echo ' <i class="hint" style="margin-top:4px">建议 256×256 或 512×512 的方形图;带透明背景的 PNG 效果最好。</i>';
|
||||
/* 文件选择按钮重做成真按钮(用户:原生那个太丑)。
|
||||
* <label class="file-btn"> 包住 input[type=file],点 label 就等于点 input;
|
||||
* input 用 clip 视觉隐藏但仍可聚焦(不能用 display:none,那样点不到)。 */
|
||||
$ficonFileId = 'iconFile' . ($esw ? (int)$esw['id'] : 'new');
|
||||
echo ' <label class="file-btn" for="' . $ficonFileId . '">'
|
||||
. '<span class="file-btn-ic" aria-hidden="true"></span>'
|
||||
. '<span class="file-btn-txt">选择图片</span>'
|
||||
. '<span class="file-btn-name" data-file-name></span>'
|
||||
. '<input type="file" name="icon_file" accept="image/png,image/jpeg,image/webp" id="' . $ficonFileId . '">'
|
||||
. '</label>';
|
||||
echo ' <i class="hint" style="margin-top:6px">建议 256×256 或 512×512 的方形图;带透明背景的 PNG 效果最好。</i>';
|
||||
if ($curIconUrl !== '') {
|
||||
echo ' <label class="check" style="margin-top:6px"><input type="checkbox" name="icon_clear" value="1"> 移除当前图片,改用下面的字符图标</label>';
|
||||
echo ' <label class="check" style="margin-top:8px"><input type="checkbox" name="icon_clear" value="1"> 移除当前图片,改用下面的字符图标</label>';
|
||||
}
|
||||
echo ' </div>';
|
||||
echo ' </div>';
|
||||
@@ -529,11 +538,17 @@ function fb_admin_taxonomy_page($pdo, $editSw, $editCat) {
|
||||
}
|
||||
echo '</span></label>';
|
||||
|
||||
// 下载地址:状态改成「已解决」时,邮件里会给用户一个去下新版的按钮
|
||||
echo ' <label class="field"><span>下载地址<i class="hint">可留空。填了之后「已解决」的通知邮件里会多一个「下载最新版」按钮</i></span>'
|
||||
. '<input type="url" name="download_url" maxlength="300" value="'
|
||||
. e($esw ? (string)(isset($esw['download_url']) ? $esw['download_url'] : '') : '')
|
||||
. '" placeholder="https://..."></label>';
|
||||
/* ── 「下载地址」字段已删除 ──
|
||||
* 用户 2026-11-04:「有个什么下载链接,这个东西不要,要它干什么?」
|
||||
*
|
||||
* 它原本的唯一用途:当反馈状态改成「已解决」时,把通知邮件里的按钮
|
||||
* 从「查看详情」换成「下载最新版本」。属于可有可无的小功能,
|
||||
* 却要求管理员为每个软件再维护一条 URL —— 收益远小于维护成本。
|
||||
*
|
||||
* ⚠️ 数据库的 download_url 列**保留不删**:
|
||||
* ① 删列会让历史数据不可逆丢失;
|
||||
* ② 万一以后想恢复,不用再走一次迁移。
|
||||
* 只是前台表单不再暴露,mailer 里也已改为始终用「查看详情」。 */
|
||||
|
||||
// 主题色:前台按软件换色,用短链接进不同软件一眼就能区分
|
||||
$curColor = $esw ? fb_color_norm((string)$esw['color']) : '';
|
||||
@@ -577,8 +592,10 @@ function fb_admin_taxonomy_page($pdo, $editSw, $editCat) {
|
||||
echo ' </div>';
|
||||
echo ' </div>';
|
||||
if ($esw) {
|
||||
echo ' <label class="field"><span>排序<i class="hint">数字小的排前面</i></span>'
|
||||
. '<input type="number" name="sort_order" value="' . (int)$esw['sort_order'] . '"></label>';
|
||||
/* 排序是 1-2 位的小整数,占满整行很难看 —— 收窄成定宽。
|
||||
* 用 .field-narrow 限制宽度,而不是让它跟着 .field 铺满。 */
|
||||
echo ' <label class="field field-narrow"><span>排序<i class="hint">数字小的排前面,同级按名称排</i></span>'
|
||||
. '<input type="number" name="sort_order" min="0" max="999" value="' . (int)$esw['sort_order'] . '"></label>';
|
||||
echo ' <button class="btn primary" name="act" value="sw_edit" type="submit">保存</button> '
|
||||
. '<a class="btn" href="admin.php?tab=taxonomy">取消</a>';
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ if (!defined('FB_ROOT')) {
|
||||
define('FB_ROOT', dirname(__DIR__));
|
||||
// 静态资源版本号:改 assets/ 下的 css/js 后把这个数字 +1,
|
||||
// 让浏览器与 CDN 缓存失效。全站只此一处,别再往页面里写死数字。
|
||||
if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 45); }
|
||||
if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 47); }
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
|
||||
+6
-9
@@ -997,17 +997,14 @@ if (!function_exists('fb_notify_render')) {
|
||||
$blocks[] = ['type' => 'callout', 'tone' => $meta['tone'], 'text' => $meta['tip']];
|
||||
}
|
||||
|
||||
/* 「已解决」要真的推用户一把去验证:
|
||||
* 软件配了下载地址就给一个下载按钮 —— 只说「修好了」用户不知道去哪拿新版本。 */
|
||||
$dlUrl = $sw ? trim((string)(isset($sw['download_url']) ? $sw['download_url'] : '')) : '';
|
||||
/* 「已解决」时给用户一个按钮去验证。
|
||||
*
|
||||
* ⚠️ 2026-11-04:后台的「下载地址」字段已删除,
|
||||
* 所以这里不再判断 $sw['download_url'] —— 那个值只可能是历史遗留。
|
||||
* 按钮统一为「查看详情」,不再有「下载最新版本」分支。
|
||||
* 想要恢复的话:后台加回字段 + 这里加回判断即可。 */
|
||||
$btnText = '查看详情';
|
||||
$btnUrl = $url;
|
||||
if ($newKey === 'resolved' && $dlUrl !== '') {
|
||||
$blocks[] = ['type' => 'callout', 'tone' => 'ok',
|
||||
'text' => '新版本已经发布,建议下载最新版后验证一下。'];
|
||||
$btnText = '下载最新版本';
|
||||
$btnUrl = $dlUrl;
|
||||
}
|
||||
|
||||
$layout = [
|
||||
'software' => $sw,
|
||||
|
||||
Reference in New Issue
Block a user