docs: README 跟上授权延长与通道组,截图和动图改为一条命令重新生成

README
- 申请延长写清规则:授权有效期间也可申请,有效的从原到期时间顺延、已结束的从批准时起算,
  被撤销的不能延长;批准延长时通道会开到授权结束(与最长开启时长的关系)
- 修正通道组「一起开关」与「可以单独开关」的矛盾:闲置按整组计算,每个地址仍可单独开关
- 时长选项用界面上的「通道开启期间」;快速开始按实际流程写(保存后自动弹出邀请设置)
- 新增同事端申请延长的三张截图;流程图补上 30 分钟、自定义与 2 小时内可申请延长

截图与动图
- 授权管理、编辑通道、邀请文案、授权成功页、网页面板(含通道组)更新为当前界面
- 离屏渲染时控件按激活状态绘制,开关不再显示成灰色
- 新增 make readme-images:App 离屏渲染、动图合成、授权页与网页面板的无头 Chrome 截图一次完成,
  写入 docs/images;授权页 HTML 由服务端测试用模拟状态生成,网页面板用本机模拟 API

界面
- 计时文字第二个单位补零(27分05秒),卡片上的徽标不再随秒数左右跳动;App 与网页面板一致
- 待审批与延长申请的时间格式统一为不带秒;App 预览的分享文案补上延长提示
This commit is contained in:
DeepFal committed 2026-10-14 14:51:07 +08:00
1 parent 6f2a1472b6
commit 3272e66247
26 files changed
+392 -37

No files matched your search

+5 -3
View File
@@ -397,10 +397,11 @@ func formatSecondsToDuration(_ totalSec: Int64) -> String {
let hours = totalSec / 3600
let mins = (totalSec % 3600) / 60
let secs = totalSec % 60
// 第二个单位补零,计时跳动时文字宽度不变
if hours > 0 {
return "\(hours)小时\(mins)分"
return "\(hours)小时" + String(format: "%02d分", mins)
} else if mins > 0 {
return "\(mins)分\(secs)秒"
return "\(mins)分" + String(format: "%02d秒", secs)
} else {
return "\(secs)秒"
}
@@ -1557,6 +1558,7 @@ class PortRelayViewModel: ObservableObject {
lines.append("请在 \(fmt.string(from: deadline)) 前用浏览器打开下面的链接,\(action)(访问有效期:\(leaseDurationTitle(leaseDuration))):")
lines.append(link)
lines.append("此链接仅限 1 台设备使用,请勿转发。")
lines.append("授权结束后 2 小时内,可以重新打开此链接申请延长。")
let text = lines.joined(separator: "\n")
return (InviteShareResp(invite: InviteItem(code: "k7m2xq9fpa", note: note, created_at: "", expires_at: "", max_uses: maxUses, lease_duration: leaseDuration, require_approval: requireApproval, uses: nil), link: link, share_text: text), nil)
}
@@ -3702,7 +3704,7 @@ struct ClientDetailsSheet: View {
.font(.system(size: 12, design: .monospaced))
.foregroundColor(.accentColor)
}
Text(verbatim: "申请于 \(formatDateTimeShort(r.at)) · 批准后可访问 \(leaseDurationTitle(invites.first { $0.code == r.invite }?.lease_duration))")
Text(verbatim: "申请于 \(formatClock(r.at)) · 批准后可访问 \(leaseDurationTitle(invites.first { $0.code == r.invite }?.lease_duration))")
.font(.system(size: 11))
.foregroundColor(.secondary)
.lineLimit(1)