```
feat(iOS): 更新MNN后端模型配置优化性能 将MNN主模型从Qwen3.5-4B(~2.64GiB)降级为Qwen3.5-2B(~1.1GiB),因为4B版本 实测运行过慢,影响用户体验。iPhone17+/SME2设备使用2B模型,保留MLX 兜底方案用于模拟器和备用场景,确保AI推理性能和存储效率的平衡。 ```
This commit is contained in:
34
康康/DesignSystem/AIDisclaimer.swift
Normal file
34
康康/DesignSystem/AIDisclaimer.swift
Normal file
@@ -0,0 +1,34 @@
|
||||
import SwiftUI
|
||||
|
||||
/// 全 App 统一的 AI 免责声明(上架合规:医疗类内容必须声明不做诊断)。
|
||||
/// 任何展示 AI 生成的归纳/解读/建议文本的地方,都应在结果末尾附上 `AIDisclaimerFooter`;
|
||||
/// 离开 App 的文本(复制/分享)用 `AIDisclaimer.appended(to:)` 把声明带上。
|
||||
enum AIDisclaimer {
|
||||
/// 面向用户展示的完整声明文本。
|
||||
static let text =
|
||||
"本内容由本机本地 AI 依据你录入的健康记录自动归纳整理,仅供个人健康管理与就医沟通参考," +
|
||||
"不构成医学诊断、治疗建议或专业医疗意见;具体健康问题请咨询执业医师。"
|
||||
|
||||
/// 复制/分享时把声明追加到正文末尾(分隔线 + 声明),让文本离开 App 也带着免责。
|
||||
static func appended(to body: String) -> String {
|
||||
let trimmed = body.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return "\(trimmed)\n\n———\n\(text)"
|
||||
}
|
||||
}
|
||||
|
||||
/// AI 结果下方的免责声明脚注:小字、弱色、信息图标。放在任何 AI 生成文本块末尾。
|
||||
struct AIDisclaimerFooter: View {
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: 6) {
|
||||
Image(systemName: "info.circle")
|
||||
.font(.tjScaled( 10))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
Text(AIDisclaimer.text)
|
||||
.font(.tjScaled( 10))
|
||||
.lineSpacing(2)
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}
|
||||
45
康康/DesignSystem/AIFlowBar.swift
Normal file
45
康康/DesignSystem/AIFlowBar.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
import SwiftUI
|
||||
|
||||
/// Apple Intelligence 式多彩流光线:蓝→紫→粉→橙→青,横向无缝循环流动。
|
||||
/// 全 App「AI 计算中」时刻的统一视觉点缀(日记 AI 辅助、身体档案报告生成/检索等待)。
|
||||
///
|
||||
/// 注意:这条线的颜色是刻意走出 `Tj.Palette` 单色系统的 AI 高光点缀(应产品要求的
|
||||
/// Apple 风格),仅此组件如此;其余 UI 仍严格守 §9 单色 token。
|
||||
struct AIFlowBar: View {
|
||||
var height: CGFloat = 3
|
||||
/// 流动一整圈的秒数,越小越快。
|
||||
var cycle: Double = 1.0
|
||||
|
||||
@State private var phase: CGFloat = 0
|
||||
|
||||
/// 颜色重复一遍:offset 走完一个整段时首尾同色,循环无缝。
|
||||
private static let flow: [Color] = {
|
||||
let base: [Color] = [
|
||||
Color(red: 0.35, green: 0.47, blue: 0.98), // 蓝
|
||||
Color(red: 0.62, green: 0.36, blue: 0.92), // 紫
|
||||
Color(red: 0.96, green: 0.40, blue: 0.62), // 粉
|
||||
Color(red: 1.00, green: 0.55, blue: 0.30), // 橙
|
||||
Color(red: 0.30, green: 0.80, blue: 0.92), // 青
|
||||
]
|
||||
return base + base
|
||||
}()
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geo in
|
||||
let w = geo.size.width
|
||||
Capsule()
|
||||
.fill(LinearGradient(colors: Self.flow,
|
||||
startPoint: .leading, endPoint: .trailing))
|
||||
.frame(width: w * 2)
|
||||
.offset(x: phase)
|
||||
.onAppear {
|
||||
phase = 0
|
||||
withAnimation(.linear(duration: cycle).repeatForever(autoreverses: false)) {
|
||||
phase = -w
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(height: height)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user