coupon-admin/app/controller/api/User.php

354 lines
15 KiB
PHP

<?php
namespace app\controller\api;
use app\exception\RepositoryException;
use app\model\Account;
use app\model\Business;
use app\repository\AccountRepository;
use app\repository\BusinessRepository;
use app\repository\CouponRepository;
use app\service\File;
use app\service\Jwt;
use app\service\Tool;
use app\service\wx\WechatApplets;
use app\validate\User as UserValidate;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Exception;
use think\exception\ValidateException;
use think\facade\Config;
use think\response\Json;
/**
* 用户相关
*
* Class User
* @package app\controller\api
*/
class User extends Base
{
protected $noNeedLogin = [
'login','checkNewAccount',"decodeMobile"
];
/**
* 登录 成功返回token及用户信息
*
* @return Json
* @throws InvalidConfigException
*/
public function login(): Json
{
$params = [
'code' => $this->request->param('code', ''),
'nick_name' => filterEmoji($this->request->param('nickName', '')),
'avatar_url' => $this->request->param('avatarUrl', ''),
'gender' => $this->request->param('gender/d', 0),
//'real_name' => $this->request->param('real_name/s', '',"trim"),
'mobile' => $this->request->param('mobile/s', ''),
'lat' => $this->request->param('lat/f', 0),
'lng' => $this->request->param('lng/f', 0),
];
$validate = new UserValidate();
if (!$validate->scene('wx_applets')->check($params)) {
return $this->json(4000, $validate->getError());
}
$minApp = WechatApplets::getInstance();
$jsCode = $params['code'];
$wxUser = $minApp->auth->session($jsCode);
if (isset($wxUser['errcode']) && $wxUser['errcode'] != 0) {
return $this->json(4001, $wxUser['errcode'].';'.$wxUser['errmsg'] ?? '登录失败');
}
// $wxUser success has [session_key, openid, unionid]
// 有效期2小时
$wxUser['expire_time'] = time() + 7200;
$wxUser['session_key'] = $wxUser['session_key'] ?? '';
$openID = $wxUser['openid'] ?? '';
if (empty($openID)) {
return $this->json(4002, '登录失败');
}
try {
$repo = AccountRepository::getInstance();
$account = $repo->findByOpenID($openID);
$nowDate = date('Y-m-d H:i:s');
if (!$account) {
//if(empty($params['real_name'])){
// return $this->json(4001, '真实姓名不能为空');
//}
if(!is_mobile($params['mobile'])){
return $this->json(4001, '手机号格式错误');
}
// 自动注册
$account = $repo->create([
'user_code' => createUuid(), // 用户UUID
'open_id' => $openID,
'create_time' => $nowDate,
'login_time' => $nowDate,
'type' => Account::type_consumer, // 默认为普通消费者
'nick_name' => $params['nick_name'] ?: generateDefaultNickName(),
'avatar_url' => $params['avatar_url'] ?: Account::DEFAULT_AVATAR,
'gender' => $params['gender'],
//'real_name' => $params['real_name'],
'mobile' => $params['mobile'],
'lat' => $params['lat'],
'lng' => $params['lng'],
]);
} else {
$updateData = [
'login_time' => $nowDate,
'lat' => empty($account->lat)?$params['lat'] :$account->lat,//如果之前的位置信息是空的
'lng' => empty($account->lng)?$params['lng'] :$account->lng,//如果之前的位置信息是空的
'mobile' => (!is_mobile($account->mobile))?$params['mobile']:$account->mobile,//如果之前的电话信息是空的
//'real_name' => empty($account->real_name)?$params['real_name']:$account->real_name,//如果之前的电话信息是空的
];
// 更新资料
$modifyStringList = ['nick_name', 'avatar_url'];
foreach ($modifyStringList as $modifyKey) {
if (isset($params[$modifyKey]) && !empty($params[$modifyKey])) {
$updateData[$modifyKey] = $params[$modifyKey];
}
}
$repo->update($updateData, ['id' => $account['id']]);
$account = $repo->findById($account['id']);
}
} catch (RepositoryException | Exception $e) {
return $this->json(4003, '登录失败!'.$e->getMessage());
}
$account = $account->toArray();
$account['avatar_url'] = File::convertCompleteFileUrl($account['avatar_url']);
$jwtData = [
'user_id' => $account['id'],
'user_code' => $account['user_code'],
'open_id' => $openID,
'session_key' => $wxUser['session_key'],
'expire_time' => $wxUser['expire_time'],
];
$data = [
'avatar' => File::convertCompleteFileUrl($account['avatar_url']),
'nickName' => $account['nick_name'],
'token' => Jwt::generate($jwtData),
'userType' => $account['type'],
'userTypeDes' => Account::accountTypeDescList()[$account['type']] ?? '游客',
];
return $this->json(0, 'success', $data);
}
/*
* 获取个人中心资料
*/
public function getUserCenterInfo()
{
$accountId = $this->request->user['user_id'] ?? 0;
try {
$accountRepo = AccountRepository::getInstance();
$couponRepo = CouponRepository::getInstance();
$busRepo = BusinessRepository::getInstance();
$account = $accountRepo->findById($accountId, [], function ($q) {
return $q->with(['business', 'parent']);
});
if (empty($account)) {
throw new ValidateException('用户无效!');
}
if ( in_array($account['type'],[Account::type_business,Account::type_staff]) ) {
// 商家用户
if (empty($account['business'])) {
throw new ValidateException('用户无效!没有相关的商户信息记录');
}
$businessModel = $account->business["model"];
// 指定时间段内发布的签到券个数
$TimeListModeReleaseCount = BusinessRepository::getInstance()
->getTimeListModeReleaseCount($account->business["code"],$account->business["time_limit_start"],$account->business["time_limit_end"]);
if($account->business["model"] == Business::model_time_limit){
//如果到了时间 或者发布数量到达规定 更改商家模式
if( strtotime($account->business["time_limit_end"] ) < time()
||
($TimeListModeReleaseCount >= $account->business["time_limit_release_count"])
){
$businessModel = Business::model_ordinary;
$account->business->save(["model"=> Business::model_ordinary]);
}
}
// 指定时间段内发布的签到券个数
$TimeListModeReleaseCount = BusinessRepository::getInstance()
->getTimeListModeReleaseCount($account->business["code"],$account->business["time_limit_start"],$account->business["time_limit_end"]);
$businessRes = [
'avatar' => File::convertCompleteFileUrl($account['avatar_url']),
'nickName' => $account['nick_name'],
'user_code' => $account['user_code'],
'userType' => $account['type'],
'userTypeDes' => Account::accountTypeDescList()[$account['type']] ?? '游客',
'couponCount' => 0,
'business' => [
'code' => $account['business']['code'],
'businessName' => $account['business']['business_name'],
'state' => $account['business']['state'],
'reason' => $account['business']['reason'],
'balance' => $account['business']['balance'],
'enable' => $account['business']['enable'],
'model' => $businessModel,
'time_limit_end' => $account['business']['time_limit_end'],
'time_limit_release_count' => $account['business']['time_limit_release_count'] - $TimeListModeReleaseCount,
// 商家优惠卷情况统计
'couponCountList' => $busRepo->getCountBusinessOnShelf($account['business']['code'], 29),
],
"alertMoney"=>config("wechat.balance") ?? 300,
"redPrice"=>CouponRepository::getInstance()->getUserRedPrice( $account['user_code']),
];
return $this->json(0, 'success', $businessRes);
} else {
// 用户领取的优惠卷总数量
$couponCount = $couponRepo->getModel()::getCountByWhere(['consumer_code' => $account['user_code']]);
$personalRes = [
'avatar' => File::convertCompleteFileUrl($account['avatar_url']),
'nickName' => $account['nick_name'],
'user_code' => $account['user_code'],
'userType' => $account['type'],
'userTypeDes' => Account::accountTypeDescList()[$account['type']] ?? '游客',
'couponCount' => $couponCount,
"alertMoney" => config("wechat.balance")?? 300,
"redPrice" => CouponRepository::getInstance()->getUserRedPrice( $account['user_code']),
];
// if ($account['type'] == Account::type_staff) {
// // 员工
// $businessCode = $account['parent']['business_code'] ?? '';
// if (!empty($businessCode)) {
// $business = $busRepo->findOneByWhere(['code' => $businessCode]);
// if ($business) {
// $personalRes['business'] = [
// 'code' => $business['code'],
// 'businessName' => $business['business_name'],
// 'state' => $business['state'],
// 'reason' => $business['reason'],
// 'balance' => $business['balance'],
// 'enable' => $business['enable'],
// ];
// }
// }
//
// $personalRes['parent'] = [];
// if (!empty($account['parent'])) {
// $personalRes['parent'] = [
// 'avatar' => File::convertCompleteFileUrl($account['parent']['avatar_url']),
// 'nickName' => $account['parent']['nick_name'],
// 'userType' => $account['parent']['type'],
// 'userTypeDes' => Account::accountTypeDescList()[$account['parent']['type']] ?? '',
// 'couponCount' => 0,
// 'businessCode' => $account['parent']['business_code'],
// ];
// }
//
// }
$personalRes['business'] =[
"state" => Business::state_consumer,//未认证
"reason" => "",//未认证
];
if(!empty($account['business'])) {
// 商户认证记录
$personalRes['business']["state"] = $account['business']['state'];
$personalRes['business']["reason"] = $account['business']['reason'];
}
$personalRes['refundCustomerService'] = config("wechat.refundCustomerService")?? '';
return $this->json(0, 'success', $personalRes);
}
} catch (ValidateException $e) {
return $this->json(4001, $e->getError());
} catch (Exception $e) {
return $this->json(5001, '服务器繁忙!获取用户个人信息失败');
}
}
//检查是新用户还是老用户
public function checkNewAccount()
{
Config::load('extra/wechat', 'wechat');
$config = config('wechat');
$code = $this->request->param('code/s');
$appId = $config["applets_appId"]??'';//appid
$appSecret = $config["applets_appSecret"]??'';//appsecret
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='
. $appId
. '&secret='
. $appSecret
. '&js_code='
. $code
. '&grant_type=authorization_code';
$data = json_decode(Tool::httpRequest($url, "get"), true);
//返回状态
if (isset($data["openid"])) {
$account = AccountRepository::getInstance()->findByOpenID($data["openid"]);
if(empty($account)){
return $this->json(0, "success",[
"showMobile"=>true,
"showRealName"=>true,
"session_key"=>$data["session_key"]]);
}
return $this->json(0, "success",[
"showMobile"=>is_mobile($account->mobile)?false:true,
//"showRealName"=>(!empty($account->real_name))?false:true,
"session_key"=>$data["session_key"]
]);
}
return $this->json(5001, "获取登录状态失败", ["showMobile"=>true,
"showRealName"=>true,
"session_key"=>'']);
}
/**
* 解密手机号
* */
public function decodeMobile()
{
$params = input('post.');
$rules = [
'encryptedData|加密数据' => 'require',
'iv|IV' => 'require',
'session_key|会话标识' => 'require',
];
$validate = $this->validateByApi($params, $rules);
if ($validate !== true) {
return $validate;
}
// 解密手机相关数据
$minApp = WechatApplets::getInstance();
$sessionKey = $params['session_key'] ?? '';
$decryptData = $minApp->encryptor->decryptData($sessionKey, $params['iv'], $params['encryptedData']);
$phone = $decryptData['phoneNumber'] ?? ''; // 通过iv和加密数据 解密出手机号
if ($phone) {
return $this->json(0,"success",["mobile"=>$phone]);
}
return $this->json(5001,"获取手机号失败");
}
/**
* 静默登录
* */
}