389 lines
14 KiB
PHP
389 lines
14 KiB
PHP
<?php
|
||
|
||
namespace app\czg\app\controller;
|
||
|
||
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddShortUrlResponseBody\data;
|
||
use app\api\model\Msg;
|
||
use app\api\model\TbUser;
|
||
use app\api\model\UserInfo;
|
||
use app\common\library\DatabaseRoute;
|
||
use app\common\model\BaseModel;
|
||
use app\common\model\SysUser;
|
||
use app\exception\SysException;
|
||
use app\utils\AliUtils;
|
||
use app\utils\RedisUtils;
|
||
use think\facade\Db;
|
||
use Throwable;
|
||
use ba\Captcha;
|
||
use ba\ClickCaptcha;
|
||
use think\facade\Config;
|
||
use app\common\facade\Token;
|
||
use app\common\controller\Frontend;
|
||
use app\api\validate\User as UserValidate;
|
||
|
||
class UserController extends Frontend
|
||
{
|
||
protected array $noNeedLogin = ['checkIn', 'logout', 'realNameAuth', 'selectNewApp'];
|
||
|
||
public function initialize(): void
|
||
{
|
||
parent::initialize();
|
||
}
|
||
|
||
|
||
public function test()
|
||
{
|
||
p($this->auth->user_id);
|
||
// Db::connect(DatabaseRoute::getConnection('course_collect', ['user_id' => 10]))
|
||
// ->name('course_collect')
|
||
// ->where('user_id', 10)
|
||
// ->find();
|
||
|
||
// 查询
|
||
// $user = new SysUser();
|
||
// // 查询或者删除前设置分库连接
|
||
// $user->setConnection($user::findbefore($user, ['user_id' => 1072634324253292306]));
|
||
// $user = $user->where(['user_id' => 1072634324253292306]);
|
||
//// $res = $user->delete();
|
||
// $data = $user->find();
|
||
// p($data);
|
||
|
||
|
||
|
||
// SysUser::update(['username' => 99999], ['user_id' => 130677]);
|
||
// SysUser::create([
|
||
// 'user_id' => rand(000000, 999999),
|
||
// 'username' => '哎呀' . rand(000000, 999999),
|
||
// ]);
|
||
|
||
}
|
||
|
||
|
||
|
||
public function bindAlipay()
|
||
{
|
||
$get = $this->request->param();
|
||
$user = $this->auth->getUser();
|
||
// 获取请求参数
|
||
$userId = $user['user_id'];
|
||
$zhiFuBao = $get['zhiFuBao'] ?? null;
|
||
$certName = $get['certName'] ?? null;
|
||
|
||
// 验证参数不能为空
|
||
if (empty($zhiFuBao) || empty($certName)) {
|
||
$this->error("支付宝账号或姓名不能为空");
|
||
}
|
||
|
||
// 包含*号直接返回成功(业务特殊处理)
|
||
if (str_contains($zhiFuBao, '*') || str_contains($certName, '*')) {
|
||
$this->success();
|
||
}
|
||
|
||
$slave_db = Db::connect(DatabaseRoute::getConnection('tb_user', ['user_id' => $userId]));
|
||
// 查询用户信息
|
||
$userEntity = $slave_db->name('tb_user')
|
||
->where('user_id', $userId)
|
||
->find();
|
||
|
||
// 检查是否与原有信息一致
|
||
if ($zhiFuBao == $userEntity['zhi_fu_bao'] && $certName == $userEntity['zhi_fu_bao_name']) {
|
||
$this->success();
|
||
}
|
||
|
||
// 检查支付宝账号是否已被其他用户绑定
|
||
$count = $slave_db->name('tb_user')
|
||
->where('user_id', '<>', $userId)
|
||
->where('zhi_fu_bao_name', $certName)
|
||
->where('zhi_fu_bao', $zhiFuBao)
|
||
->count();
|
||
|
||
if ($count > 0) {
|
||
$this->error("支付宝信息修改失败: 此支付宝账号已被绑定");
|
||
}
|
||
|
||
// 检查实名认证信息是否匹配
|
||
$userInfo = $slave_db->name('user_info')
|
||
->where('user_id', $userId)
|
||
->find();
|
||
|
||
if ($userInfo) {
|
||
if (!empty($userInfo['cert_name']) && $certName != $userInfo['cert_name']) {
|
||
$this->error("支付宝信息修改失败: 姓名与实名认证信息不相符");
|
||
}
|
||
}
|
||
|
||
// 获取配置的限制次数
|
||
$limitConfig = Db::name('common_info')
|
||
->where('type', 924)
|
||
->value('value');
|
||
|
||
// 获取当前时间戳(秒)
|
||
$currentTime = time();
|
||
// 获取本月最后一天的日期(如:2024-08-31)
|
||
$lastDayOfMonth = date('Y-m-t');
|
||
// 拼接本月最后一刻的时间(23:59:59)
|
||
$endOfMonth = $lastDayOfMonth . ' 23:59:59';
|
||
// 转换为时间戳
|
||
$endTime = strtotime($endOfMonth);
|
||
// 计算剩余秒数(若当前时间已过本月最后一刻,返回0)
|
||
$remainingSeconds = max(0, $endTime - $currentTime);
|
||
|
||
// 检查支付宝账号每月绑定次数限制
|
||
if (!\app\common\model\Common::isAccessAllowed($zhiFuBao, $certName, (int)$limitConfig, $remainingSeconds, true)) {
|
||
$this->error("支付宝信息修改失败: 相同支付宝账号每月可绑定次数已用完");
|
||
}
|
||
|
||
// 检查用户每月修改次数限制
|
||
$updateLimitConfig = Db::name('common_info')
|
||
->where('id', 925)
|
||
->value('value');
|
||
|
||
if (!\app\common\model\Common::isAccessAllowed((string)$userId, "updateZFB", (int)$updateLimitConfig, $remainingSeconds)) {
|
||
$this->error("支付宝信息修改失败: 每月可修改次数已用完,请联系管理员");
|
||
}
|
||
|
||
// 更新用户支付宝信息
|
||
$master_db = Db::connect(DatabaseRoute::getConnection('tb_user', ['user_id' => $userId], true));
|
||
$master_db->name('tb_user')
|
||
->where('user_id', $userId)
|
||
->update([
|
||
'zhi_fu_bao' => $zhiFuBao,
|
||
'zhi_fu_bao_name' => $certName,
|
||
// 可添加更新时间字段
|
||
'update_time' => date('Y-m-d H:i:s')
|
||
]);
|
||
$this->success('ok', 1);
|
||
}
|
||
|
||
|
||
|
||
|
||
public function updatePhone()
|
||
{
|
||
$user_id = $this->auth->user_id;
|
||
$post = $this->request->post();
|
||
if(empty($post['phone']) || empty($post['msg'])) {
|
||
$this->error('参数不正常');
|
||
}
|
||
|
||
// 验证码
|
||
if(Msg::checkCode($post['phone'], $post['msg'])) {
|
||
$user = TbUser::GetByusername($post['phone']);
|
||
if($user) {
|
||
$this->error('手机号已经存在');
|
||
}
|
||
$db = DatabaseRoute::getDb('tb_user', $user_id, true)->where(['user_id' => $user_id])->update(['phone' => $post['phone']]);
|
||
if($db) {
|
||
$this->success('操作成功');
|
||
}else {
|
||
$this->error('操作失败');
|
||
}
|
||
}else {
|
||
$this->error('验证码错误');
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 会员签入(登录和注册)
|
||
* @throws Throwable
|
||
*/
|
||
public function checkIn(): void
|
||
{
|
||
$openMemberCenter = Config::get('buildadmin.open_member_center');
|
||
if (!$openMemberCenter) {
|
||
$this->error(__('Member center disabled'));
|
||
}
|
||
|
||
// 检查登录态
|
||
if ($this->auth->isLogin()) {
|
||
$this->success(__('You have already logged in. There is no need to log in again~'), [
|
||
'type' => $this->auth::LOGGED_IN
|
||
], $this->auth::LOGIN_RESPONSE_CODE);
|
||
}
|
||
|
||
$userLoginCaptchaSwitch = Config::get('buildadmin.user_login_captcha');
|
||
|
||
if ($this->request->isPost()) {
|
||
$params = $this->request->post(['tab', 'email', 'mobile', 'username', 'password', 'keep', 'captcha', 'captchaId', 'captchaInfo', 'registerType']);
|
||
|
||
// 提前检查 tab ,然后将以 tab 值作为数据验证场景
|
||
if (!in_array($params['tab'] ?? '', ['login', 'register'])) {
|
||
$this->error(__('Unknown operation'));
|
||
}
|
||
|
||
$validate = new UserValidate();
|
||
try {
|
||
$validate->scene($params['tab'])->check($params);
|
||
} catch (Throwable $e) {
|
||
$this->error($e->getMessage());
|
||
}
|
||
|
||
if ($params['tab'] == 'login') {
|
||
if ($userLoginCaptchaSwitch) {
|
||
$captchaObj = new ClickCaptcha();
|
||
if (!$captchaObj->check($params['captchaId'], $params['captchaInfo'])) {
|
||
$this->error(__('Captcha error'));
|
||
}
|
||
}
|
||
$res = $this->auth->login($params['username'], $params['password'], !empty($params['keep']));
|
||
} elseif ($params['tab'] == 'register') {
|
||
$captchaObj = new Captcha();
|
||
if (!$captchaObj->check($params['captcha'], $params[$params['registerType']] . 'user_register')) {
|
||
$this->error(__('Please enter the correct verification code'));
|
||
}
|
||
$res = $this->auth->register($params['username'], $params['password'], $params['mobile'], $params['email']);
|
||
}
|
||
|
||
if (isset($res) && $res === true) {
|
||
$this->success(__('Login succeeded!'), [
|
||
'userInfo' => $this->auth->getUserInfo(),
|
||
'routePath' => '/user'
|
||
]);
|
||
} else {
|
||
$msg = $this->auth->getError();
|
||
$msg = $msg ?: __('Check in failed, please try again or contact the website administrator~');
|
||
$this->error($msg);
|
||
}
|
||
}
|
||
|
||
$this->success('', [
|
||
'userLoginCaptchaSwitch' => $userLoginCaptchaSwitch,
|
||
'accountVerificationType' => get_account_verification_type()
|
||
]);
|
||
}
|
||
|
||
public function logout(): void
|
||
{
|
||
if ($this->request->isPost()) {
|
||
$refreshToken = $this->request->post('refreshToken', '');
|
||
if ($refreshToken) Token::delete((string)$refreshToken);
|
||
$this->auth->logout();
|
||
$this->success();
|
||
}
|
||
}
|
||
|
||
public function selectNewApp()
|
||
{
|
||
$this->n_success(['data' => apiconvertToCamelCase(Db::connect(get_slave_connect_name())->name('app')->order('version', 'desc')->select()->toArray())]);
|
||
}
|
||
|
||
/**
|
||
* 实名接口
|
||
*/
|
||
public function realNameAuth()
|
||
{
|
||
$params = $this->request->post();
|
||
// (new UserValidate())->scene('realName')->check($params);
|
||
$params['certNum'] = trim($params['certNum']);
|
||
$params['certName'] = trim($params['certName']);
|
||
$userId = $this->getUserId();
|
||
$regex = '/^[0-9Xx*]+$/';
|
||
if (!preg_match($regex, $params['certNum'])) {
|
||
$this->success();
|
||
}
|
||
|
||
$count = DatabaseRoute::getDb('user_info', $userId)->where([
|
||
'cert_name' => $params['certName'],
|
||
'cert_no' => $params['certNum'],
|
||
])->count();
|
||
if ($count) {
|
||
$this->error('已完成实名认证,无需重复操作');
|
||
}
|
||
|
||
$count = DatabaseRoute::getAllDbData('tb_user', function ($query) use ($params) {
|
||
return $query->where([
|
||
'cert_name' => $params['certName'],
|
||
'cert_no' => $params['certNum'],
|
||
]);
|
||
})->count();
|
||
if ($count >= 3) {
|
||
$this->error('实名认证失败: 1个身份证号码最多绑定3个账号');
|
||
}
|
||
|
||
RedisUtils::checkRealCount($userId);
|
||
|
||
$resp = AliUtils::verify($params['certName'], $params['certNum'], $params['accountNo'], $params['mobile']);
|
||
$userInfo = UserInfo::getByUserIdOrSave($userId);
|
||
$userInfo['cert_name'] = $params['certName'];
|
||
$userInfo['cert_no'] = $params['certNum'];
|
||
$userInfo['account_no'] = $params['accountNo'];
|
||
$userInfo['mobile'] = $params['mobile'];
|
||
$userInfo['bank_name'] = $resp['bankName'];
|
||
$userInfo['province'] = $params['province'] ?? '';
|
||
$userInfo['city'] = $params['city'] ?? '';
|
||
$userInfo['bank_branch'] = $params['bankBranch'];
|
||
$userInfo['resp_json'] = $resp['respJson'];
|
||
$userInfo['update_time'] = getNormalDate();
|
||
DatabaseRoute::getDb('user_info', $userId, true, true)->update($userInfo);
|
||
|
||
RedisUtils::setRealCount($userId);
|
||
|
||
// 校验实名黑名单
|
||
$count = Db::name('tb_user_blacklist')->where([
|
||
'id_card_no' => $params['certNum']
|
||
])->count();
|
||
if ($count) {
|
||
DatabaseRoute::getDb('tb_user', $userId, true, true)->update([
|
||
'status' => 0,
|
||
'plat_form' => '异常行为用户:实名信息异常 在黑名单'
|
||
]);
|
||
throw new SysException("异常行为: 您的实名信息存在异常行为");
|
||
}
|
||
|
||
$this->successWithData(1);
|
||
}
|
||
|
||
public function selectUserById()
|
||
{
|
||
$user = $this->auth->getUser();
|
||
// 获取用户详情
|
||
$userInfo = DatabaseRoute::getDb('user_info', $user['user_id'])->find();
|
||
$userInfo['resp_json'] = null; // 移除敏感字段
|
||
|
||
// 对用户详情中的敏感信息进行脱敏
|
||
if (!empty($userInfo['account_no'])) {
|
||
$userInfo['account_no'] = bankCard($userInfo['account_no']);
|
||
}
|
||
|
||
if (!empty($userInfo['mobile'])) {
|
||
$userInfo['mobile'] = maskPhoneNumber($userInfo['mobile']);
|
||
}
|
||
|
||
if (!empty($userInfo['cert_no'])) {
|
||
$userInfo['cert_no'] = idCardNum($userInfo['cert_no'], 3, 2);
|
||
}
|
||
|
||
// 对支付宝信息进行脱敏
|
||
if (!empty($user['zhi_fu_bao'])) {
|
||
if (filter_var($user['zhi_fu_bao'], FILTER_VALIDATE_EMAIL)) {
|
||
$user['zhi_fu_bao'] = email($user['zhi_fu_bao']);
|
||
} else {
|
||
$user['zhi_fu_bao'] = maskPhoneNumber($user['zhi_fu_bao']);
|
||
}
|
||
}
|
||
|
||
// 合并用户信息和用户详情
|
||
$map = array_merge($user, $userInfo);
|
||
$map['user_id'] = (string)$map['user_id']; // 确保用户ID为字符串类型
|
||
|
||
// 如果支付宝姓名为空,使用实名认证姓名
|
||
if (empty($user['zhi_fu_bao_name']) && !empty($userInfo['cert_name'])) {
|
||
$map['zhi_fu_bao_name'] = $userInfo['cert_name'];
|
||
}
|
||
$this->success('ok', convertToCamelCase($map));
|
||
}
|
||
|
||
public function updateUsers()
|
||
{
|
||
$post = $this->request->post();
|
||
$user = $this->auth->getUser();
|
||
$db_name = Db::connect(DatabaseRoute::getConnection('tb_user', ['user_id' => $user['user_id']], true));
|
||
$db_name->name('tb_user')->where(['user_id' => $user['user_id']])->update(['user_name' => $post['userName'], 'avatar' => $post['avatar']]);
|
||
$this->success('ok');
|
||
}
|
||
|
||
} |