Skip to content

Instantly share code, notes, and snippets.

@jyxjjj
Created June 11, 2026 09:51
Show Gist options
  • Select an option

  • Save jyxjjj/75c9a22725b5b88820fa2104a706f813 to your computer and use it in GitHub Desktop.

Select an option

Save jyxjjj/75c9a22725b5b88820fa2104a706f813 to your computer and use it in GitHub Desktop.
Salary Per Second
import Combine
import SwiftUI
struct ContentView: View {
@State private var salary = "20000"
@State private var days = "21"
@State private var hours = "8"
@State private var startedAt: Date?
@State private var now = Date()
@State private var showSummary = false
@State private var finalEarned = 0.0
@State private var finalAverage = 0.0
@FocusState private var focusedField: Field?
private let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
private var monthSalary: Double { Double(salary) ?? 0 }
private var workDays: Double { Double(days) ?? 0 }
private var workHours: Double { Double(hours) ?? 0 }
private var daySalary: Double { workDays > 0 ? monthSalary / workDays : 0 }
private var planSeconds: Double { workHours * 3600 }
private var elapsed: Double {
guard let startedAt else { return 0 }
return max(0, now.timeIntervalSince(startedAt))
}
private var earned: Double {
guard planSeconds > 0 else { return 0 }
return daySalary * min(elapsed, planSeconds) / planSeconds
}
private var average: Double {
guard elapsed > 0 else { return planSeconds > 0 ? daySalary / planSeconds : 0 }
return earned / elapsed
}
private var canStart: Bool { monthSalary > 0 && workDays > 0 && workHours > 0 }
private enum Field { case salary, days, hours }
var body: some View {
ZStack {
VStack(spacing: 8) {
TextField("请输入税前月薪", text: $salary)
.focused($focusedField, equals: .salary)
TextField("本月上班天数", text: $days)
.focused($focusedField, equals: .days)
TextField("每日工作小时数", text: $hours)
.focused($focusedField, equals: .hours)
Button(startedAt == nil ? "上班打卡" : "下班打卡") {
startedAt == nil ? start() : stop()
}
.controlSize(.large)
.disabled(startedAt == nil && !canStart)
Text("今日已赚金额:\(money(earned))")
Text("秒均金额:\(money(average))")
}
.disabled(showSummary)
if showSummary {
VStack(spacing: 10) {
Text("恭喜你")
Text("今天赚了 \(money(finalEarned))")
Text("平均每秒 \(money(finalAverage))")
Button("返回") {
showSummary = false
}
.controlSize(.large)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.background)
.zIndex(1)
}
}
.textFieldStyle(.roundedBorder)
.controlSize(.small)
.font(.system(size: 16))
.frame(width: 220)
.padding(10)
.onReceive(timer) { date in
if startedAt != nil { now = date }
}
}
private func start() {
now = Date()
startedAt = now
focusedField = nil
showSummary = false
}
private func stop() {
focusedField = nil
now = Date()
finalEarned = earned
finalAverage = average
startedAt = nil
showSummary = true
}
private func money(_ value: Double) -> String {
"¥" + value.formatted(.number.precision(.fractionLength(4)))
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment