手把手教你写项目之游戏陪玩app全栈开发---第五章:后端API(下):陪玩师列表?不,是“人才市场”

阅读前请先下载项目源码,边读边看源码以加深理解和实操,
源码地址已放于文章末尾!

效果预览:
在这里插入图片描述

在这里插入图片描述

第五章:后端API(下):陪玩师列表?不,是“人才市场”

哟,各位“攻城狮”,欢迎回到API的“施工现场”!

上一章,我们解决了用户的“户口”问题(注册),还画了一张关于Token认证的“草图”。今天,咱们就要把这张“草图”变成现实,彻底搞定用户登录,并颁发那张至关重要的“赛博通行证”。

然后,我们将乘胜追击,开发一个让无数玩家心动的核心接口——获取陪玩师列表。这可不是一个简单的列表,这简直就是一个琳琅满目的“人才市场”,是咱们App流量的发动机!

一、登录接口:核验身份,颁发Token

咱们先来把上一章留下的“坑”填上。用户登录的逻辑,其实就是注册的“逆操作”:用户提供“身份证”(手机号)和“口令”(密码),我们去数据库里核对,信息无误就放行。

1. 代码位置

文件路径: /application/api/controller/User.php (没错,还是老地方)

2. 代码片段

// 文件路径:/application/api/controller/User.php

// ...

use app\common\library\Token;

class User extends Api
{
    // ...

    /**
     * 会员登录
     */
    public function login()
    {
        // 接收前端传来的手机号和密码
        $mobile = $this->request->request('mobile');
        $password = $this->request->request('password');

        if (!$mobile || !$password) {
            $this->error('参数不完整');
        }

        // 1. 根据手机号查找用户
        $user = Db::name('user')->where('mobile', $mobile)->find();
        if (!$user) {
            $this->error('用户不存在');
        }

        // 2. 验证密码
        $encrypt_password = md5(md5($password) . $user['salt']); // 用同样的方式加密前端传来的密码
        if ($encrypt_password != $user['password']) {
            $this->error('密码不正确');
        }

        // 3. 登录成功,生成Token
        $token = Random::uuid(); // 生成一个唯一的Token字符串
        Token::set($token, $user['id'], 2592000); // 将Token与用户ID关联,并设置有效期(这里是30天)

        // 4. 返回给前端的数据
        $ret = [
            'token' => $token,
            'userinfo' => [
                'id'       => $user['id'],
                'nickname' => $user['nickname'],
                'avatar'   => $user['avatar'],
                // ... 其他需要返回的用户信息
            ]
        ];

        $this->success('登录成功', $ret);
    }
    
    // ...
}

3. 结构化分析

这段代码的“宏观”作用是:核实用户身份,并在身份无误后,生成一个有时效性的身份凭证(Token)返回给前端。它是整个App认证体系的核心,所有需要登录才能访问的接口,都依赖于它生成的Token。

4. 逐行/逐块详解

  • $user = Db::name('user')->where('mobile', $mobile)->find();: 这次不是 insert 了,而是 find。根据 where 条件(mobile 等于用户输入的手机号)去 fa_user 表里查找一条记录。
  • $encrypt_password = md5(md5($password) . $user['salt']);: 登录验证的核心! 我们从数据库里取出了该用户的 salt(盐),和用户本次输入的密码 password 进行拼接,再用和注册时完全相同的加密算法进行加密。
  • if ($encrypt_password != $user['password']): 将我们刚刚计算出的加密密码,与数据库中存储的 password 字段进行比对。如果一致,证明密码正确;如果不一致,直接返回错误。这就是“加盐加密”的好处,全程我们都不需要知道用户的原始密码是什么。
  • $token = Random::uuid();: 生成一个UUID(通用唯一识别码),它是一个几乎不会重复的长字符串,非常适合用来做Token。
  • Token::set($token, $user['id'], 2592000);: 这是调用了项目封装好的 Token 处理类。这个方法做了两件事:
    1. $token$user['id'] 这对“钥匙”和“门牌号”的映射关系存起来(通常是存在Redis缓存或数据库里)。
    2. 给这个映射关系设置一个有效期,单位是秒。2592000 秒正好是30天。
  • $ret = [...]: 准备一个数组,把生成的 token 和一些常用的用户信息打包在一起,方便前端接收后直接使用。
  • $this->success('登录成功', $ret);: 将打包好的数据返回给前端。

二、“人才市场”接口:筛选并展示陪玩师

搞定了登录,我们就可以开始做点有意思的事了。比如,把所有“身怀绝技”的陪玩师都展示出来,供玩家“挑选”。

这个接口的逻辑很简单:去用户表里,把所有用户组ID (group_id) 是“陪玩师”的用户都捞出来,再加点分页和排序,返回给前端。

1. 代码位置

文件路径: /application/api/controller/Clerk.php (为了职责分离,我们新建一个控制器)

2. 代码片段

// 文件路径:/application/api/controller/Clerk.php

<?php
namespace app\api\controller;

use app\common\controller\Api;
use think\Db;

class Clerk extends Api
{
    /**
     * 获取陪玩师列表
     */
    public function getClerkList()
    {
        // 接收前端传来的分页参数
        $page = $this->request->request('page', 1); // 当前页码,默认为1
        $pageSize = $this->request->request('pageSize', 10); // 每页数量,默认为10

        // 筛选条件:用户组ID为2(假设2代表陪玩师)
        $where = [
            'group_id' => 2,
            'status'   => 'normal' // 只显示状态正常的用户
        ];

        $list = Db::name('user')
            ->where($where)
            ->field('id, nickname, avatar, gender, age, bio') // 只查询需要的字段
            ->order('level desc, score desc') // 按等级和评分排序
            ->page($page, $pageSize)
            ->select();

        // 此处还可以补充逻辑,比如计算每个陪玩师的接单数、好评率等

        $this->success('获取成功', $list);
    }
}

3. 结构化分析

这个接口是App的核心展示功能之一。它负责根据特定条件(陪玩师身份),从用户数据中筛选出一部分人,并以列表的形式(支持分页和排序)提供给前端。前端拿到这个列表数据后,就可以循环渲染出我们看到的陪玩师卡片了。

4. 逐行/逐块详解

  • class Clerk extends Api: 新建一个 Clerk 控制器,专门用来处理和陪玩师相关的业务逻辑,这样代码结构更清晰。
  • $page = $this->request->request('page', 1);: 获取分页参数 page,如果前端没传,就默认为第 1 页。
  • $where = [...]: 定义查询条件。'group_id' => 2 是核心,它精准地把我们的查询范围限定在了“陪玩师”这个群体里。
  • Db::name('user')->where($where): 链式操作的开始,指定查询 fa_user 表,并应用我们的筛选条件。
  • ->field('id, nickname, avatar, gender, age, bio'): 性能优化的好习惯! 不要无脑地用 * 查询所有字段。只选择前端真实需要的字段,可以减少数据传输量和数据库的查询压力。bio 可能是个人简介(biography)的缩写。
  • ->order('level desc, score desc'): 排序。desc 代表降序。这里是先按等级从高到低排,等级相同的再按评分从高到低排。
  • ->page($page, $pageSize): 分页的核心! ThinkPHP框架内置了非常方便的分页功能。只要告诉它当前页码和每页数量,它就会自动计算 LIMITOFFSET,从数据库里取出对应区间的数据。
  • ->select();: 链式操作的结束,执行查询,并返回一个包含多条记录的数组。

三、总结

今天我们完成了后端API开发的第二部分,也是非常核心的一部分。我们不仅用代码实现了上一章构思的登录认证流程,还学会了如何编写一个带筛选、排序、分页功能的复杂列表查询接口。

到目前为止,我们后端的“交通枢纽”已经初具规模了:

  • 我们有了“海关”(注册、登录),可以管理人员进出。
  • 我们有了“安检系统”(Token认证),可以确保内部安全。
  • 我们有了第一条“公交线路”(获取陪玩师列表),可以对外提供服务了。

在接下来的 《前端初体验(uni-app):让你的代码“一键三连”,跨平台运行》 中,我们将暂时离开后端,切换到前端的“施工现场”,看看如何利用我们今天写的API,把数据真真切切地展示在手机屏幕上。

准备好迎接前端的奇妙世界了吗?我们下回分解!

源码下载地址:
https://thmail.lanzouu.com/iveW134b31qj

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

THMAIL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值