You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin预约服务应用中实现每日用户提交配额限制

解决方案:实现每日预约配额限制

要实现用户每日预约提交的配额限制,核心是在提交前检查当日已提交次数,并用事务保证操作的原子性(避免并发提交导致配额计数错误),以下是具体实现步骤:

1. 配置Firestore配额存储

在Firestore中新增一个UserQuotas集合,每个用户对应一个文档(文档ID使用用户的nama,和你现有预约数据的文档ID保持一致),文档包含3个字段:

  • dailyQuota: 整数,设置每日允许的预约上限(比如设为3)
  • todayBookings: 整数,记录用户当日已提交的预约数
  • lastResetDate: 字符串,格式为yyyy-MM-dd,记录配额上次重置的日期

2. 编写带配额检查的提交逻辑

用Firestore事务来整合「配额检查→提交预约→更新计数」的流程,确保这一系列操作不会被并发请求打断:

// 1. 格式化当前日期(用于配额重置判断)
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val today = dateFormat.format(Date())

// 2. 启动Firestore事务
database.runTransaction { transaction ->
    // 获取用户的配额文档引用
    val quotaDocRef = database.collection("UserQuotas").document(nama)
    val quotaDoc = transaction.get(quotaDocRef)

    // 初始化默认配额(如果用户是第一次提交)
    var dailyQuota = 3 // 这里可以改成你需要的每日上限
    var todayBookings = 0
    var lastResetDate = today

    if (quotaDoc.exists()) {
        dailyQuota = quotaDoc.getLong("dailyQuota")?.toInt() ?: 3
        todayBookings = quotaDoc.getLong("todayBookings")?.toInt() ?: 0
        lastResetDate = quotaDoc.getString("lastResetDate") ?: today
    }

    // 3. 重置当日配额(如果不是今天的记录)
    if (lastResetDate != today) {
        todayBookings = 0
        lastResetDate = today
    }

    // 4. 检查配额是否用尽
    if (todayBookings >= dailyQuota) {
        // 配额不足,抛出异常终止事务
        throw FirebaseFirestoreException(
            "今日预约配额已用尽,请明日再试",
            FirebaseFirestoreException.Code.ABORTED
        )
    }

    // 5. 配额充足,提交预约数据
    val Modeldatabase = ModelDatabase(platnomor, tahunkendaraan, serieskendaraan, nama, alamat, nomorhp, tanggalservice, keluhane)
    val bookingDocRef = database.collection("Data Booking").document(nama)
    transaction.set(bookingDocRef, Modeldatabase)

    // 6. 更新当日预约计数
    transaction.set(quotaDocRef, hashMapOf(
        "dailyQuota" to dailyQuota,
        "todayBookings" to (todayBookings + 1),
        "lastResetDate" to lastResetDate
    ))

    return@runTransaction null
}.addOnSuccessListener {
    // 提交成功,清空表单并提示
    pltnomor.text?.clear()
    thnkendaraan.text?.clear()
    srskendaraan.text?.clear()
    namapmlk.text?.clear()
    alamatpmlk.text?.clear()
    nohpe.text?.clear()
    tglbooking.text?.clear()
    keluhankerusakan.text?.clear()
    Toast.makeText(this, "Booking Sukses!", Toast.LENGTH_SHORT).show()
}.addOnFailureListener { e ->
    // 根据异常类型提示不同信息
    val message = if (e.message == "今日预约配额已用尽,请明日再试") {
        e.message
    } else {
        "Booking Gagal!"
    }
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

3. 额外注意事项

  • 如果需要动态调整用户的每日配额,可以直接修改UserQuotas文档里的dailyQuota字段,无需修改代码
  • 日期格式化建议用DateTimeFormatter(Android API 26+)替代SimpleDateFormat,避免线程安全问题:
    val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.getDefault())
    val today = LocalDate.now().format(dateFormatter)
    
  • 确保用户的nama是唯一标识,避免不同用户用相同名字导致配额混淆

内容的提问来源于stack exchange,提问作者sandwich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 05:55:44