laravel8 实现签到功能案例

2023-11-12

本文是个案例

先来数据库


//用户表
CREATE TABLE `users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '123456@qq.com',
  `email_verified_at` timestamp NULL DEFAULT NULL,
  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `days` int(11) DEFAULT NULL,
  `scores` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
//积分表
CREATE TABLE `sign_detailed` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(11) DEFAULT NULL COMMENT '用户id',
  `type` tinyint(4) DEFAULT NULL COMMENT '获取积分的类型',
  `fid` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '积分来源',
  `score` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '获取到的积分',
  `time` datetime DEFAULT NULL COMMENT '时间',
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
//签到表
CREATE TABLE `sign_records` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userid` int(10) NOT NULL COMMENT '用户id',
  `ymd` date NOT NULL COMMENT '签到时间',
  `updated_at` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL COMMENT '签到具体时间',
  PRIMARY KEY (`id`,`userid`,`ymd`),
  UNIQUE KEY `唯一` (`userid`,`ymd`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
//积分
CREATE TABLE `sign_rule` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `day` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '签到天数',
  `number` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '积分',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
//注意模型要写上   protected $guarded = [];

1.wxml

<view class='signIn'>
    <view class='sign-com'>
        <view class='thead'>
            <view class='tt'>已连续签到</view>
            <view class='mm'><label class='n'>{{signNum}}</label>天</view>
            <view class='pp'>你的积分为{{ score}}</view>
        </view>
        <view class='modle'>
            <view class='mol'>
                <view class='mol-line'></view>
                <view class='mol-ites'>
                    <view class="ite {{signNum>=min?'hover':''}}" data-n='{{min}}'>
                        <label class='n'>+{{min<7?1:3}}</label>
                    </view>
                    <view class="ite {{signNum>=min+1?'hover':''}}" data-n='{{min+1}}'>
                        <label class='n'>+{{min+1<7?1:3}}</label>
                    </view>
                    <view class="ite {{signNum>=min+2?'hover':''}}" data-n='{{min+2}}'>
                        <label class='n'>+{{min+2<7?1:3}}</label>
                    </view>
                    <view class="ite {{signNum>=min+3?'hover':''}}" data-n='{{min+3}}'>
                        <label class='n'>+{{min+3<7?1:3}}</label>
                    </view>
                    <view class="ite {{signNum>=min+4?'hover':''}}" data-n='{{min+4}}'>
                        <label class='n'>+{{min+4<7?1:3}}</label>
                    </view>
                    <view class="ite {{signNum>=min+5?'hover':''}}" data-n='{{min+5}}'>
                        <label class='n'>+{{min+5<7?1:3}}</label>
                    </view>
                    <view class="ite {{signNum>=min+6?'hover':''}}" data-n='{{max}}'>
                        <label class='n'>+{{min+6<7?1:3}}</label>
                    </view>
                </view>
            </view>
            <view class='moday'>
                <label class='dd'>{{min}}天</label>
                <label class='dd'>{{min+1}}天</label>
                <label class='dd'>{{min+2}}天</label>
                <label class='dd'>{{min+3}}天</label>
                <label class='dd'>{{min+4}}天</label>
                <label class='dd'>{{min+5}}天</label>
                <label class='dd'>{{max}}天</label>
            </view>
        </view>
        <view class='the-btn'>
            <button type='button' class='btn' bindtap='bindSignIn' data-num="{{signNum}}" disabled='{{signState}}' data-min="{{min}}" data-max="{{max}}" data-be="{{be}}">签到</button>
        </view>
    </view>
</view>
<view class='explax'>
    <view class=''>日期开始:{{min}} </view>
    <view class=''>日期结束:{{max}} </view>
    <view class=''>签到数:{{signNum}}天</view>
    <view class=''>您的积分为:{{score}}</view>
</view>

 2.wxss

.signIn {
    width: 100%;
    height: auto;
}
 
.sign-com {
    width: 100%;
    height: auto;
    padding: 0 30rpx;
    box-sizing: border-box;
    overflow: hidden;
}
 
.sign-com .thead {
    width: 100%;
    text-align: center;
    padding: 50rpx 0 35rpx;
}
 
.sign-com .thead .tt {
    font-size: 24rpx;
}
 
.sign-com .thead .mm {
    margin-top: 10rpx;
    font-size: 24rpx;
}
 
.sign-com .thead .mm .n {
    font-size: 66rpx;
    margin-right: 25rpx;
}
 
.sign-com .thead .pp {
    color: #999;
    font-size: 24rpx;
    margin-top: 10rpx;
}
 
.sign-com .modle {
    width: 100%;
    height: 100rpx;
    margin-top: 10rpx;
}
 
.sign-com .modle .mol {
    width: 100%;
    height: 52rpx;
    position: relative;
}
 
.sign-com .mol-line {
    width: 100%;
    height: 4rpx;
    background-color: #e6e6e6;
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
}
 
.sign-com .mol-ites {
    width: 100%;
    height: 100%;
    position: absolute;
}
 
.mol-ites .ite {
    width: 52rpx;
    height: 52rpx;
    border-radius: 50%;
    border: 1px solid #f5f5f5;
    background-color: #fff;
    box-sizing: border-box;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
}
 
.mol-ites .ite .n {
    width: 44rpx;
    height: 44rpx;
    line-height: 44rpx;
    text-align: center;
    border-radius: 50%;
    background-color: #f5f5f5;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    font-size: 22rpx;
}
 
.mol-ites .ite::after {
    content: "";
    width: 80rpx;
    height: 4rpx;
    background-color: transparent;
    position: absolute;
    left: 52rpx;
    top: 50%;
    margin-top: -2rpx;
    z-index: 2;
}
 
.mol-ites .ite:last-of-type::after {
    width: 0;
}
 
.mol-ites .ite:nth-of-type(2) {
    left: 107rpx;
}
 
.mol-ites .ite:nth-of-type(3) {
    left: 214rpx;
}
 
.mol-ites .ite:nth-of-type(4) {
    left: 321rpx;
}
 
.mol-ites .ite:nth-of-type(5) {
    left: 428rpx;
}
 
.mol-ites .ite:nth-of-type(6) {
    left: 535rpx;
}
 
.mol-ites .ite:nth-of-type(7) {
    left: 642rpx;
}
 
.mol-ites .ite.hover {
    border-color: #ff614a;
}
 
.mol-ites .ite.hover .n {
    background-color: #ff614a;
    color: #fff;
}
 
.mol-ites .ite.hover::after {
    background-color: #ff614a;
}
 
.moday {
    width: 100%;
    height: 40rpx;
    overflow: hidden;
    position: relative;
    margin-top: 20rpx;
}
 
.moday .dd {
    width: 52rpx;
    height: 40rpx;
    line-height: 1;
    text-align: center;
    font-size: 22rpx;
    position: absolute;
    left: 0;
    bottom: 0;
}
 
.moday .dd:nth-of-type(2) {
    left: 107rpx;
}
 
.moday .dd:nth-of-type(3) {
    left: 214rpx;
}
 
.moday .dd:nth-of-type(4) {
    left: 321rpx;
}
 
.moday .dd:nth-of-type(5) {
    left: 428rpx;
}
 
.moday .dd:nth-of-type(6) {
    left: 535rpx;
}
 
.moday .dd:nth-of-type(7) {
    left: 642rpx;
}
 
.the-btn {
    margin: 50rpx 0;
}
 
.the-btn .btn {
    background-color: #ff614a;
    color: #fff;
}
 
.the-btn.signed .btn {
    background-color: rgba(153, 153, 153, 0.61);
}
 
.explax {
    padding: 0 30rpx;
    font-size: 28rpx;
    color: #666;
}

3.js


const app = getApp();
 
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
    //签到模块
    signNum: 0,  //签到数
    signState: false, //签到状态
    integral: '',
    min: 1,  //默认值日期第一天1
    max: 7,  //默认值日期最后一天7
    score:"0"
  },
 
  //签到
  bindSignIn(e) {
    //  获取token
    var token = wx.getStorageSync('token');
    let that = this;
    //  用户id
    wx.request({
      url: '*******************',//请求路径
      data: {},
      header:{"Authorization":"Bearer "+token},
      success(res) {
        //   console.log(res.data.data);
        if (res.data.code == 200) {
          wx.showToast({
            title: res.data.msg,
          })
          that.setData({
            signNum:res.data.data.days,
            score:res.data.data.score,
            signState:true
          })
        }
        if (res.data.code == 500) {
          wx.showToast({
            title: '网络异常',
          })
        }
        if (res.data.code == 501) {
          wx.showToast({
            title: '签到失败',
          })
        }
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var token = wx.getStorageSync('token');
    let that = this;
    //  用户id
    wx.request({
      url: '*******************', //仅为示例,并非真实的接口地址
      data: {},
      header:{"Authorization":"Bearer "+token},
      success(res) {
        if (res.data.code == 200) {
          that.setData({
            signNum:res.data.data.days,
            score:res.data.data.score,
          })
          
        }
      }
    })
  },
})

4.后端代码段

public function signin(){
        $userId =1;
        $user = \App\Models\Login::where('id',$userId)->first();
        $day = $user->days;
        //获取当前的时间
        $yearMonthDay = date('Y-m-d',time());
        $has =  Records::where('userid',$userId)->where('ymd',$yearMonthDay)->first();
        if($has)
        {
            return ['code'=>200,'msg'=>'已签到','data'=>[]];
        }
        //开启事务
        DB::beginTransaction();
        try {
            //将用户id 和 当前签到天数添加到表里面
            $sign = Records::create(['userid'=>$userId,'ymd'=>$yearMonthDay]);
            $signId = $sign->id;
            //获取用户上次签到时间
            $lastSignDayObj = Records::select('ymd')->where('userid',$userId)->where('id','<',$signId)->orderBy('id','desc')->limit(1)->first();
            //根据上次的签到时间来判断是 断签 ,还是连续签到 ,还是第一次签到
            if (empty($lastSignDayObj)){
                //不存在 表示第一次签到
                $days = 1;
                $number = Rule::select('number')->where('day',$days)->first();
                if ($number){
                    $score = $number->number;
                    //存在
                }else{
                    //不存在
                    $score = 7;
                }
                $status = '第一次签到,获得积分'.$score;
            }else{
                $lastSignDay = $lastSignDayObj->ymd;
                //存在  将当前天数的时间戳 和 上次签到的时间戳作比较
                $time = strtotime($yearMonthDay) - strtotime($lastSignDay);
                if ($time >= 24*3600 && $time < 48*3600){
                    //表示连续签到 签到天数加一
                    $days = $day +1;
                    $number = Rule::select('number')->where('day',$days)->first();
                    if ($number){
                        $score = $number->number;
                    }else{
                        //不存在
                        $score = 7;
                    }
                    $status = '连续签到'.$days.'天,获得积分'.$score;
                }else if ($time >= 48*3600){
                    //表示断签 和 第一次签到是一样的
                    $days = 1;
                    $number = Rule::select('number')->where('day',$days)->first();
                    if ($number){
                        $score = $number->number;
                        //存在
                    }else{
                        //不存在
                        $score = 7;
                    }
                    $status = '断签后第一次签到,获得积分'.$score;
                }else{
                    return ['code'=>500,'msg'=>'网路错误'];
                }
            }
            //记录用户的积分明细
            Detailed::create(['userid'=>$userId,'score'=>$score,'type'=>1,'fid'=>$signId.'订单号']);
            //求用户的积分余额
            $scores = Detailed::where('userid',$userId)->sum('score');
//            dd($days,$scores);
            //更改用户的连续签到天数 和 积分
            \App\Models\Login::where('id',$userId)->update(['days'=>$days,'scores'=>$scores]);
            //事务提交
            DB::commit();
            return ['code'=>200,'msg'=>'签到成功','data'=>
                ['score'=>$scores,'status'=>$status,'days'=>$days]];
        }catch (\Exception $e){
            //事务回滚
            DB::rollBack();
            return ['code'=>501,'msg'=>'签到失败'];
        }
    }

        //页面初始化
        public function signinin()
        {
            //用户ID
            $uid =1;
            $data = \App\Models\Login::where('id',$uid)->first();
            return ['code'=>200,'msg'=>'签到成功','data'=>$data];
        }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

laravel8 实现签到功能案例 的相关文章

  • Laravel 5 文件下载无效

    使用时Response download下载文件时 我注意到图像和其他二进制文件传输不正确 改变Content Typeheader 没有改变任何东西 也没有明确禁止缓存或强制内容的长度 造成这个问题的原因可能是什么 这个问题的解决方案可以
  • Laravel - 检查 @yield 是否为空

    如果 yield 有内容 是否可以检查刀片视图 我正在尝试在视图中分配页面标题 section title hi world 所以我想检查主布局视图 类似 对于现在 2018 年以上 查看的人 您可以使用 hasSection name y
  • Laravel 5.3 如何在通知电子邮件中显示用户名

    我正在尝试在通知电子邮件中添加用户的名字 目前 Laravel 通知电子邮件的开头如下 Hello 我想将其更改为 Hello Donald 现在 我有这样的设置 此示例适用于密码重置通知电子邮件 用户型号 public function
  • Laravel 在公共文件夹中下载 pdf

    我在公共 下载中有一个pdf文件 我只想链接到它并下载它或在浏览器中打开它 我尝试击打http localhost 8000 downloads brochure pdf在浏览器中 但我只是看到一个没有错误的白屏 在 Chrome DevT
  • 模型在自身内部调用自己是一种不好的做法吗?

    这是一个在 Laravel 中使用 Eloquent 的示例 假设我正在开发 CMS 控制器获取路由并通过路由查找页面 该模型提供了一个静态函数 该函数使用路由来找出它正在查找的行的 id 那么模型使用本身执行数据库查询并返回结果 控制器代
  • Mongodb 数据库上的 SASL 身份验证失败

    我在尝试使用 PHP Mongodb 驱动程序连接到 Mongodb 时遇到问题 实际上我有一个名为 LRS 的数据库 它有一个名为 juano 的用户 在我的设置文件中带有密码 12345 我确信我编写了正确的配置 但是当我在 Larav
  • 作曲家 | laravel 5 - 更新依赖项但框架本身

    我正在为我的项目使用 Laravel 5 的预测试版 我发现 Laravel 5 的应用程序框架在 github 存储库中发生了更改 并且由于它是开发版本 因此预计会经常更改 我的问题是 我可以使用 Composer 只更新特定的依赖项而不
  • 基于“属于”关系的雄辩的 where 条件

    假设我有以下模型 class Movie extends Eloquent public function director return this gt belongsTo Director 现在我想使用基于directors 表中的列的
  • Laravel 5 Auth 注销不起作用

    当我使用内置身份验证并尝试在以下位置注销用户时 auth logout 它没有像希望的那样工作 它似乎让用户保持登录状态 但是当我清除浏览器缓存时 我可以看到实际上已经将用户注销了 我在页面上没有收到任何错误 在日志文件中也没有收到任何错误
  • updateExistingPivot() 不起作用

    我正在尝试像这样更新数据透视表 public function updatePermission id permissionId permissionValue Input get value user User find id perms
  • 使用 JWT 创建 PostMan GET 请求

    我是 PostMan 的新手 通常我使用curl 这是获得 JTW 的一个 curl X POST H X Requested With XMLHttpRequest H Content Type application json H Ca
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 如何在laravel中注册后自动登录

    我在 laravel 中注册用户时遇到问题 user假设是包含所有数组元素的数组 同时自动登录以下代码结果false 数据库中保存的密码是hash make password user id this gt user model gt ad
  • AWS-PHP-SDK / SNS 直接寻址返回错误

    您好 我正在使用 Laravel 4 设置来利用 AWS SNS 向我的 iOS 设备发送推送消息 从 AWS 控制台向我的设备发布命令效果很好 然后我尝试从 PHP sns AWS get sns sns gt publish array
  • Laravel Vue 组件只能传递数字?

    在我的 UserMenu vue 中我写道 export default props nameVal data return 并在blade php中
  • 雄辩的第一个 where 子句

    我想知道 Laravel 如何实现雄辩的语法 以便可以静态调用第一个 where 子句User where User where id 23 gt where email email gt first 他们有吗public static f
  • Laravel 搜索关系

    我有两个相关的模型 我正在尝试在产品中进行搜索 并且仅显示实际搜索结果 而不是找到该产品的类别的所有产品 我不想搜索任何类别 因为无论搜索什么或找到什么 类别都会始终显示 Example I have the following categ
  • Laravel - 记录“找不到路线”

    当找不到路线时 我没有看到任何日志输出 我在开发模式下运行 laravel 当遇到不存在的路线时 我会看到此错误 message exception Symfony Component HttpKernel Exception NotFou
  • 如何从 Laravel 中的表中选择所有列名称?

    我试图从表中获取所有列名Teller 功能 public function getTableColumns tables return DB select DB raw SELECT COLUMN NAME DATA TYPE COLUMN
  • 在 apache docker 容器中运行虚拟主机

    我在同一个 apache 容器中有两个 php 应用程序 我试图在端口上运行其中一个应用程序 因为它需要通过根域而不是子文件夹进行访问 我想在端口 8060 上运行应用程序 我尝试使用 apache 虚拟主机执行此操作 但它不会加载页面 h

随机推荐