优化ctms-api语法、修复已知BUG;

主要修复ctms-api、dacms对PHP新版本的支持问题
This commit is contained in:
2025-07-13 19:37:42 +08:00
parent 65bbd06981
commit 037f274ec5
413 changed files with 107271 additions and 72326 deletions
@@ -0,0 +1,345 @@
<?php
# @Author: 嗨噜客(三亚) <fm453>
# @Date: 2022-04-15 20:22:03
# @Email: fm453@lukegzs.com
# @Last modified by: fm453
# @Last modified time: 2024-08-09T08:59:44+08:00
# @Copyright: www.hiluker.cn
//前端普通用户入口
namespace api\controllers\client\v1;
use Yii;
use common\models\Fans;
//‘from’字段为ctms的数据
use addons\models\AcFansExt;
use common\models\CSms;
use common\models\CVcode;
class FansController extends Common
{
public function beforeAction($action)
{
if (!$this->pid) {
$this->result('您正使用本系统内部接口,禁止非法链接使用!');
}
return parent::beforeAction($action);
}
public function actionIndex()
{
$apis = [
'login' => '账号密码登陆',
'loginSms' => '手机验证码登陆',
'detail' => '个人资料',
'register' => '用户注册',
'auth' => '授权登陆'
];
$this->result('您正使用CMTS-CLIENT系统用户管理接口!', $apis, 200);
}
public function actionLogin()
{
$pid = $this->pid;
$post = $this->postdata;
$username = $post['username'] ?? NULL;
$passwd = $post['passwd'] ?? NULL;
$return = [];
if (!$username && !$passwd) {
$this->result('登陆参数错误!', NULL, 400);
}
if (!$username) {
$this->result('请输入您的账号!', NULL, 400);
}
if (!$passwd) {
$this->result('请输入您的密码!', NULL, 400);
}
$username = trim(htmlspecialchars_decode($username));
$passwd = trim(htmlspecialchars_decode($passwd));
if (!$username) {
$this->result('输入错误,请检查您的账号!', NULL, 400);
}
if (!$passwd) {
$this->result('输入有误,请检查您的密码!', NULL, 400);
}
$model = new Fans();
$from = Yii::$app->params['fansFrom']; //指定fans数据的from字段指定ctms,表示该项目的专有数据
$condition = '(`mobile` = :username OR `email` = :username) AND `from` = :from';
$args = [':username' => $username, ':from' => $from];
$user = $model->find()->where($condition, $args)->one();
if (!$user) {
$this->result('查无此人!', NULL, 404);
}
if ($user->status != Fans::STATUS_ACTIVE) {
$this->result('账户异常,禁止登陆!', NULL, 403);
}
//安全校验,登陆密码
$isPwdRight = $user->validatePassword($passwd);
if (!$isPwdRight) {
$this->result('密码错误,禁止登陆!', NULL, 400);
}
//校验结束
$_user = $this->fansLogin($user, TRUE);
$this->result('登陆成功!', ['user' => $_user], 200);
}
public function actionLoginSms()
{
$pid = $this->pid;
$post = $this->postdata;
$mobile = $post['mobile'] ?? NULL;
$vcode = $post['vcode'] ?? NULL;
$return = [];
if (!$mobile && !$vcode) {
$this->result('登陆参数错误!', NULL, 400);
}
if (!$mobile) {
$this->result('请输入您的手机号!', NULL, 400);
}
if (!$vcode) {
$this->result('请输入手机验证码!', NULL, 400);
}
$mobile = trim(htmlspecialchars_decode($mobile));
//验证手机号
$isPhone = preg_match('/^1\d{10}$/', $mobile) ? TRUE : FALSE;
if (!$isPhone) {
$this->result('手机号不正确,请检查');
}
$vcode = trim(htmlspecialchars_decode($vcode));
//验证手机验证码
$vcodeModel = new CVcode();
$where = [];
$where['mobile'] = $mobile;
$where['deleted'] = 0;
$where['code'] = $vcode;
$where['type'] = 'login';
$res = $vcodeModel->find()->where($where)->one();
if (!$res) {
$this->result('验证码校验失败');
}
if (($this->timetamp - $res->create_at) > 300) {
// 超时5分钟
$this->result('验证码已失效,请重新获取');
}
$model = new Fans();
$from = Yii::$app->params['fansFrom']; //指定fans数据的from字段指定ctms,表示该项目的专有数据
$condition = '`mobile` = :username AND `from` = :from';
$args = [':username' => $mobile, ':from' => $from];
$user = $model->find()->where($condition, $args)->one();
$hasExt = TRUE;
if (!$user) {
$hasExt = FALSE;
$userModel = clone $model;
$user = $this->fansAdd(['mobile' => $mobile, 'from' => $from], $userModel);
} else if ($user->status != Fans::STATUS_ACTIVE) {
$this->result('账户异常,禁止登陆!', NULL, 403);
}
//校验结束
$_user = $this->fansLogin($user, $hasExt);
$this->result('登陆成功!', ['user' => $_user], 200);
}
public function actionAuth()
{
$pid = $this->pid;
$post = $this->postdata;
$openplat = $post['from'] ?? 'uni-app'; //归属的开放平台,默认标记为了uni-app
$mobile = isset($post['mobile']) ? trim(htmlspecialchars_decode($post['mobile'])) : '';
$openid = isset($post['openid']) ? trim(htmlspecialchars_decode($post['openid'])) : '';
$return = [];
if (!$mobile) {
$this->result('未提供授权手机号!');
}
if (!$openid) {
$this->result('未提供授权用户身份ID!');
}
$model = new Fans();
$userModel = clone $model;
$from = Yii::$app->params['fansFrom']; //指定fans数据的from字段指定ctms,表示该项目的专有数据
$user = $model->findOne(['mobile' => $mobile, 'from' => $from]);
//扩展用户信息
$AcFansExt = new AcFansExt();
$Ext = clone $AcFansExt; //用于更新openid
$Ext2 = clone $AcFansExt; //用于更新来源归属的开放平台openplat
$hasExt = TRUE;
if (!$user) {
$hasExt = FALSE;
//自动注册一个新用户
$user = $this->fansAdd(['mobile' => $mobile, 'from' => $from], $userModel);
// 添加扩展信息
$Ext->pid = $this->pid;
$Ext->mid = $user->id;
$Ext->mobile = $mobile;
$Ext->key = 'openid';
$Ext->value = $openid;
$Ext->deleted = 0;
$Ext->save();
$Ext2->pid = $this->pid;
$Ext2->mid = $user->id;
$Ext2->mobile = $mobile;
$Ext2->key = 'openplat';
$Ext2->value = $openplat;
$Ext2->deleted = 0;
$Ext2->save();
} else {
//所有该用户已设置过的openid值添加一次被删除标记
$condition = '`mid` = :mid AND `mobile` = :mobile AND `pid` = :pid AND `deleted` = :deleted AND `key` = :key AND `value` != :value';
$args = [':mid' => $user->id, ':mobile' => $user->mobile, ':pid' => $pid, ':deleted' => 0, ':value' => $openid, ':key' => 'openid'];
$AcFansExt->updateAllCounters(
['deleted' => 1],
$condition,
$args
);
$condition = '`mid` = :mid AND `mobile` = :mobile AND `pid` = :pid AND `key` = :key AND `value` = :value';
$args = [':mid' => $user->id, ':mobile' => $user->mobile, ':pid' => $pid, ':key' => 'openid', ':value' => $openid];
$userExt = $Ext->find()->where($condition, $args)->one();
if ($userExt) {
$userExt->deleted = 0;
$userExt->save();
} else {
$Ext->pid = $this->pid;
$Ext->mid = $user->id;
$Ext->mobile = $mobile;
$Ext->key = 'openid';
$Ext->value = $openid;
$Ext->deleted = 0;
$Ext->save();
}
$args = [':mid' => $user->id, ':mobile' => $user->mobile, ':pid' => $pid, ':key' => 'openplat', ':value' => $openplat];
$userExt2 = $Ext2->find()->where($condition, $args)->one();
if ($userExt2) {
$userExt2->deleted = 0;
$userExt2->save();
} else {
$Ext2->pid = $this->pid;
$Ext2->mid = $user->id;
$Ext2->mobile = $mobile;
$Ext2->key = 'openplat';
$Ext2->value = $openplat;
$Ext2->deleted = 0;
$Ext2->save();
}
}
// 登陆用户
$_user = $this->fansLogin($user, $hasExt);
$this->result('登陆成功!', ['user' => $_user], 200);
}
public function actionRegister()
{
$pid = $this->pid;
$post = $this->postdata;
$mobile = isset($post['mobile']) ? trim(htmlspecialchars_decode($post['mobile'])) : '';
$vcode = isset($post['vcode']) ? trim(htmlspecialchars_decode($post['vcode'])) : '';
$password = isset($post['passwd']) ? trim(htmlspecialchars_decode($post['passwd'])) : '';
$username = isset($post['username']) ? trim(htmlspecialchars_decode($post['username'])) : '';
$email = isset($post['email']) ? trim(htmlspecialchars_decode($post['email'])) : '';
$return = [];
if (!$mobile) {
$this->result('未填写手机号!');
}
if (!$vcode) {
$this->result('未填写手机验证码!');
}
//验证短信码
$model = new Fans();
$userModel = clone $model;
$from = Yii::$app->params['fansFrom']; //指定fans数据的from字段指定ctms,表示该项目的专有数据
$user = $model->findOne(['mobile' => $mobile, 'from' => $from]);
//扩展用户信息
$AcFansExt = new AcFansExt();
$Ext = clone $AcFansExt;
if (!$user) {
//自动注册一个新用户
$userModel->mobile = $mobile;
$userModel->email = $mobile . '@hiluker.com';
$userModel->setPassword(Yii::$app->params['defaultFansPassword']);
$userModel->generateAuthKey();
$userModel->created_at = time();
$userModel->from = $from;
$userModel->save();
$user = $userModel;
}
$_user = $this->fansLogin($user, TRUE);
$this->result('登陆成功!', ['user' => $_user], 200);
}
/**
* 添加一个新用户
* @param $data 用户数据
* @return void
*/
private function fansAdd($data, $userModel)
{
$mobile = $data['mobile'];
$from = $data['from'] ?? Yii::$app->params['fansFrom'];
$userModel->mobile = $mobile;
$userModel->email = $mobile . '@hiluker.com';
$userModel->setPassword(Yii::$app->params['defaultFansPassword']);
$userModel->generateAuthKey();
$userModel->created_at = time();
$userModel->from = $from;
$userModel->save();
return $userModel;
}
/**
* @param $user 用户实例
* @param $hasExt 有否扩展
* @return void
*/
private function fansLogin($user, $hasExt = FALSE)
{
// 使用指定用户名获取用户身份实例
$identity = $user;
// 登录用户,有效期30d
$duration = 3600 * 24 * 30;
$_login = Yii::$app->user->login($identity, $duration);
if (!$_login) {
$this->result('登陆失败!', NULL, 400);
}
//登陆成功,返回用户信息
$_user = ['id' => $user->id, 'username' => $user->mobile, 'mobile' => $user->mobile];
if ($hasExt) {
//查询关联用户的在当前系统中的扩展信息
$AcUserExt = new AcFansExt();
$exts = $AcUserExt->find()->where(['mid' => $user->id, 'mobile' => $user->mobile, 'pid' => $this->pid, 'deleted' => 0])->all();
if ($exts) {
foreach ($exts as $ext) {
$_user[$ext['key']] = $ext['value'];
}
}
}
//生成token(用户数据,是否强制更新,过期时间
$isLong = $this->postdata['isLong'] || FALSE;
$expire = $isLong ? '+1 Month' : FALSE;
$_user = $this->fansToken($_user, $refresh = TRUE, $expire);
return $_user;
}
}