Files
water_new/modules/User/Models/Traits/JoinIdentity.php
2023-03-08 09:16:04 +08:00

248 lines
8.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Modules\User\Models\Traits;
use Carbon\Carbon;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Modules\User\Events\UserJoinIdentity;
use Modules\User\Events\UserRemoveIdentity;
use Modules\User\Events\UserUpdateIdentity;
use Modules\User\Models\Identity;
use Modules\User\Models\IdentityLog;
use Modules\User\Models\IdentityMiddle;
trait JoinIdentity
{
/**
* 用户加入身份
*
* @param int $identity_id 身份ID
* @param string $channel 加入渠道
* @param array $source 其他溯源信息
* @throws Exception
*/
public function joinIdentity(
int $identity_id = 0,
string $channel = IdentityLog::CHANNEL_AUTO,
array $source = []
) {
// 单身份,并且已经开通身份
if (config('identity.can_has_many_identity') == false && $this->identityMiddle->count() >= 1) {
//续费
if ($this->hasIdentity($identity_id)) {
$this->renewIdentity($identity_id);
} else {
//升级
self::updateIdentity($identity_id, $channel, $source);
}
} else {
$identity = Identity::find($identity_id);
if ($identity) {
//未开通此身份
if ($this->hasIdentity($identity_id) == false) {
$remark = Arr::get($source, 'remark', '加入身份');
$res = self::identityLog(0, $identity_id, $channel, $remark, $source);
if ($res) {
$serial = $source['serial'] ?? '';
if ($identity->serial_open && empty($serial)) {
$serial = self::getNewSerial($identity->serial_places);
}
$value = [];
if ($identity->years) {
$value = [
'started_at' => now(),
'ended_at' => now()->addMonths($identity->years),
];
}
$this->identityMiddle()
->updateOrCreate([
'identity_id' => $identity_id,
'serial' => $serial,
], $value);
event(new UserJoinIdentity($this, $identity));
} else {
throw new Exception('添加日志失败');
}
} else {
//已开通此身份
$this->renewIdentity($identity_id);
}
} else {
throw new Exception('身份信息不存在');
}
}
}
/**
* Notes: 续费
*
* @Author: 玄尘
* @Date : 2021/6/8 9:49
* @param int $identity_id
*/
public function renewIdentity(int $identity_id)
{
$identity = Identity::find($identity_id);
$before = $this->identityMiddle()->where('identity_id', $identity_id)->first();
//vip
if ($identity->years) {
IdentityMiddle::where('user_id', $this->id)
->where('identity_id', $identity_id)
->update([
'ended_at' => Carbon::parse($before->ended_at)->addMonths($identity->years),
]);
} else {
IdentityMiddle::where('user_id', $this->id)
->where('identity_id', $identity_id)
->update([
'started_at' => null,
'ended_at' => null,
]);
}
event(new UserJoinIdentity($this, $before->identity));
}
/**
* 用户身份调整当多身份关闭时由join触发
*
* @param int $identity_id
* @param string $channel
* @param array $source
* @throws Exception
*/
public function updateIdentity(
int $identity_id = 0,
string $channel = IdentityLog::CHANNEL_AUTO,
array $source = []
) {
$before = $this->identityMiddle()->first();
if ($this->identityMiddle()->count() > 1) {
$this->identityMiddle()->where('identity_id', '!=', $before->identity_id)->delete();
}
$identity = Identity::find($identity_id);
if ($identity) {
$remark = Arr::get($source, 'remark', '身份变更');
$res = self::identityLog($before->identity_id, $identity_id, $channel, $remark, $source);
if ($res) {
$serial = $source['serial'] ?? '';
if ($identity->serial_open && empty($serial)) {
$serial = self::getNewSerial($identity->serial_places);
}
$data = [
'identity_id' => $identity_id,
'serial' => $serial,
'started_at' => null,
'ended_at' => null,
];
if ($identity->years) {
$data['started_at'] = now();
$data['ended_at'] = now()->addMonths($identity->years);
}
IdentityMiddle::where('user_id', $this->id)
->where('identity_id', $before->identity_id)
->update($data);
event(new UserUpdateIdentity($this, $before->identity, $identity));
} else {
throw new Exception('调整身份');
}
} else {
throw new Exception('身份信息不存在');
}
}
/**
* 判断用户是否参与身份
*
* @param int $identity_id
* @return bool
*/
public function hasIdentity(int $identity_id = 0): bool
{
if ($identity_id) {
$res = $this->identityMiddle()->where('identity_id', $identity_id)->first();
return (bool) $res;
} else {
return true;
}
}
/**
* 用户移除身份
*
* @param int $identity_id 身份ID
* @param string $channel 移除渠道
* @param array $source 其他溯源信息
* @throws Exception
*/
public function removeIdentity(
int $identity_id = 0,
string $channel = IdentityLog::CHANNEL_AUTO,
array $source = []
) {
if ($this->identityMiddle()->where('identity_id', $identity_id)->first()) {
$remark = Arr::get($source, 'remark', '身份移除');
$res = self::identityLog($identity_id, 0, $channel, $remark, $source);
if ($res) {
$this->identityMiddle()->where('identity_id', $identity_id)->delete();
event(new UserRemoveIdentity($this, Identity::find($identity_id)));
} else {
throw new Exception('移除记录失败');
}
} else {
throw new Exception('用户不在身份组中');
}
}
/**
* 生成数据库中部存在的号码
*
* @return int
*/
public function getNewSerial($places = 8)
{
try {
$min = pow(10, $places - 1);
$max = 9 * $min;
$query = 'SELECT code FROM (SELECT CEILING(RAND()*'.$max.'+'.$min.') AS code FROM user_identity UNION SELECT CEILING(RAND()*'.$max.'+'.$min.') AS code) AS ss WHERE "code" NOT IN (SELECT serial FROM user_identity where serial !=null) LIMIT 1';
$res = DB::select($query);
return (int) $res[0]->code;
} catch (Exception $e) {
return '';
}
}
public function identityLog(
$before = 0,
$after = 0,
$channel = '',
$remark = '',
$source = []
): Model {
return $this->identity_logs()->create([
'before' => $before,
'after' => $after,
'channel' => $channel,
'remark' => $remark,
'source' => $source,
]);
}
}