文件
yjyf/server/application/api/controller/Auth.php
linda 1d92202b1a feat: 微信授权登录 + 我的中心角色切换 + 师傅工作台全模块 + 图标美化
登录与角色:
- Auth::wxlogin 微信 code → jscode2session → 落库发 token(appid/secret 走 .env)
- 新增 fa_user_wechat 表,openid 幂等建号(CLI 已验证 is_new 1→0 不重复建号)
- Auth::switchRole 角色切换(未入驻 2001 / 审核中 2002 / 未通过 2003)
- pages/login 改为微信一键授权;pages/mine 我的中心(师傅入口 + 切换师傅端)

师傅工作台(对齐需求文档):
- pages/master/workbench 工作台:接单开关 / 待处理待验收 / 可提现 / 六宫格入口 / 信用四指标 / 技能标签
- pages/master/hall 订单大厅:类型筛选(一口价/报价) + 4 种排序 + 抢单倒计时 + 报价入口
- pages/master/quote 报价竞标:金额/说明/有效期 + 报价记录
- pages/master/wallet 钱包:可提现/今日/累计 + 账单明细 + 提现校验
- pages/master/credit 信用与申诉:五项指标 + 规则 + 申诉提交/记录
- 新增 fa_appeal 表

视觉:
- 15 个类目图标重画为双色扁平 SVG,用无头 Chrome 渲染为 192px 透明 PNG
- 首页改用 <image src=static/icons/*.png>,移除 200 行 CSS 图标数据

验证:page_flow 47 + e2e_flow 65 + phase2_verify 27 = 139 项断言全通过
2026-10-28 16:10:34 +08:00

165 行
5.4 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace app\api\controller;
use fast\Random;
use think\Db;
use think\Validate;
/**
* 登录 / 角色 / 个人信息
*/
class Auth extends Base
{
protected $noNeedLogin = ['login', 'wxlogin'];
/**
* 手机号 + 验证码登录(验证码固定 123456,联调用;接入短信后走 Sms)
* @ApiMethod (POST)
*/
public function login()
{
$mobile = $this->request->post('mobile');
$code = $this->request->post('code');
if (!$mobile || !$code) {
$this->error('请填写手机号和验证码');
}
if (!Validate::regex($mobile, "^1\d{10}$")) {
$this->error('手机号格式不正确');
}
if ($code !== '123456') {
$this->error('验证码不正确');
}
$user = \app\common\model\User::getByMobile($mobile);
if ($user) {
if ($user['status'] !== 'normal') {
$this->error('账号已被禁用');
}
$this->auth->direct($user['id']);
} else {
$ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
if (!$ret) {
$this->error($this->auth->getError() ?: '注册失败');
}
}
$this->success('登录成功', [
'token' => $this->auth->getToken(),
'expires' => 2592000,
'userinfo' => $this->profileData(),
]);
}
/**
* 我的信息(含角色与师傅状态)
*/
public function profile()
{
$this->success('', $this->profileData());
}
/**
* 组装个人信息
*/
protected function profileData()
{
$uid = $this->uid();
$user = Db::name('user')->field('id,nickname,mobile,avatar,money,score,createtime')->where('id', $uid)->find();
$master = Db::name('master')->where('user_id', $uid)->find();
$couponCount = Db::name('user_coupon')->where('user_id', $uid)->where('status', 'unused')->count();
$unread = Db::name('message')->where('receive_type', 'user')->where('receive_id', $uid)->where('is_read', 0)->count();
$masterInfo = null;
if ($master) {
$masterInfo = [
'id' => (int)$master['id'],
'realname' => $master['realname'],
'verify_status' => $master['verify_status'],
'audit_msg' => $master['audit_msg'],
'work_status' => $master['work_status'],
'level' => (int)$master['level'],
'score' => (float)$master['score'],
'order_count' => (int)$master['order_count'],
'money' => (float)$master['money'],
'can_take' => $master['verify_status'] === 'pass',
];
}
return [
'id' => (int)$user['id'],
'nickname' => $user['nickname'] ?: ('用户' . substr((string)$user['mobile'], -4)),
'mobile' => $user['mobile'],
'avatar' => $user['avatar'] ?: '',
'balance' => (float)$user['money'],
'coupon_count' => (int)$couponCount,
'unread_count' => (int)$unread,
'is_master' => $master ? true : false,
'master' => $masterInfo,
];
}
/**
* 微信授权登录(小程序 uni.login 拿到的 code)
* @ApiMethod (POST)
*/
public function wxlogin()
{
$code = trim((string)$this->request->post('code'));
$nickname = trim((string)$this->request->post('nickname'));
$avatar = trim((string)$this->request->post('avatar'));
if ($code === '') {
$this->error('缺少微信登录凭证 code');
}
$wx = \app\common\library\WxLogin::jscode2session($code);
if (isset($wx['error'])) {
$this->error($wx['error']);
}
$ret = \app\common\library\WxLogin::provision(
$wx['openid'],
isset($wx['unionid']) ? $wx['unionid'] : '',
isset($wx['session_key']) ? $wx['session_key'] : '',
$nickname,
$avatar
);
$this->auth->direct($ret['user_id']);
$this->success('登录成功', [
'token' => $this->auth->getToken(),
'expires' => 2592000,
'userinfo' => $this->profileData(),
'is_new' => $ret['is_new'],
]);
}
/**
* 切换角色(用户 / 师傅)
* @ApiMethod (POST)
*/
public function switchRole()
{
$role = $this->request->post('role', 'user');
if (!in_array($role, ['user', 'master'], true)) {
$this->error('角色参数错误');
}
if ($role === 'master') {
$master = $this->masterInfo();
if (!$master) {
$this->error('请先完成师傅入驻', ['need_apply' => 1], 2001);
}
if ($master['verify_status'] === 'pending') {
$this->error('师傅资质审核中,请耐心等待', ['verify_status' => 'pending'], 2002);
}
if ($master['verify_status'] === 'reject') {
$this->error('资质未通过:' . $master['audit_msg'], ['verify_status' => 'reject'], 2003);
}
}
$this->success('切换成功', [
'role' => $role,
'redirect' => $role === 'master' ? '/pages/master/workbench' : '/YJYF/YJYF',
]);
}
}