123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- <?php
- namespace App\Services\Pair;
- use App\Services\Pair\DataModels\PairMatchDataSource;
- use Illuminate\Support\Facades\Redis;
- abstract class BasePairMatch
- {
- /** @var int 匹配期数 */
- protected $stageId;
- /** @var array 匹配结果 */
- public $matchResult = array();
- /** @var PairMatchDataSource[] 数据源 */
- protected $dataSources = array();
- /** @var PairMatchDataSource[] 垃圾桶数据源 */
- private $trashDataSources = array();
- /** @var PairMatchDataSource 基准对比源 */
- private $baseDataSource;
- /** @var string 定位缓存key */
- private $LBSCacheKey;
- /** @var array 匹配规则数组 */
- private $matchRuleFuncs = array('radius', 'age', 'height', 'gender', 'noOnce');
- public function __construct()
- {
- }
- /**
- * 加载匹配数据源
- */
- abstract public function loadMatchData();
- /**
- * 添加匹配规则
- * @param array|string $rule
- */
- protected function addMatchRule($rule)
- {
- if (is_array($rule)) {
- array_map(function ($item) {
- array_push($this->matchRuleFuncs, $item);
- }, $rule);
- } else {
- array_push($this->matchRuleFuncs, $rule);
- }
- $this->matchRuleFuncs = array_unique($this->matchRuleFuncs);
- }
- /**
- * 移除匹配规则
- * @param array|string $rule
- */
- protected function removeMatchRule($rule)
- {
- if (!is_array($rule)) {
- $rule = array($rule);
- }
- $this->matchRuleFuncs = array_diff($this->matchRuleFuncs, $rule);
- }
- /**
- * 是否匹配范围
- * @param PairMatchDataSource $dataSource
- * @return bool
- */
- public function isMatchRadius(PairMatchDataSource $dataSource): bool
- {
- if (! $this->baseDataSource->rangeUsers) {
- $this->baseDataSource->rangeUsers = Redis::geoRadius($this->LBSCacheKey, $this->baseDataSource->enrollLongitude, $this->baseDataSource->enrollLatitude, $this->baseDataSource->matchRadius, 'km');
- }
- if (! $dataSource->rangeUsers) {
- $dataSource->rangeUsers = Redis::geoRadius($this->LBSCacheKey, $dataSource->enrollLongitude, $dataSource->enrollLatitude, $dataSource->matchRadius, 'km');
- }
- if (in_array($dataSource->uid, $this->baseDataSource->rangeUsers) && in_array($this->baseDataSource->uid, $dataSource->rangeUsers)) {
- return true;
- }
- return false;
- }
- /**
- * 是否匹配年龄
- * @param PairMatchDataSource $dataSource
- * @return bool
- */
- public function isMatchAge(PairMatchDataSource $dataSource): bool
- {
- return false;
- }
- /**
- * 是否匹配身高
- * @param PairMatchDataSource $dataSource
- * @return bool
- */
- public function isMatchHeight(PairMatchDataSource $dataSource): bool
- {
- return false;
- }
- /**
- * 是否匹配性别
- * @param PairMatchDataSource $dataSource
- * @return bool
- */
- public function isMatchGender(PairMatchDataSource $dataSource): bool
- {
- if (
- $this->baseDataSource->gender == $dataSource->sexualOrientation &&
- $this->baseDataSource->sexualOrientation = $dataSource->gender
- ) {
- return true;
- } else {
- return false;
- }
- }
- /**
- * 是否匹配过
- * @param PairMatchDataSource $dataSource
- * @return bool
- */
- public function isMatchNoOnce(PairMatchDataSource $dataSource): bool
- {
- return false;
- }
- /**
- * 任务初始化
- */
- public function taskInit()
- {
- $this->LBSCacheKey = "pair:{$this->stageId}:lsb";
- }
- public function matchRules(PairMatchDataSource $dataSource): bool
- {
- $boolMatch = true;
- foreach ($this->matchRuleFuncs as $func) {
- if (method_exists($this, "isMatch" . ucfirst($func))) {
- $boolMatch = $boolMatch && $this->{"isMatch" . ucfirst($func)}($dataSource);
- } else {
- $boolMatch = $boolMatch && false;
- }
- }
- return $boolMatch;
- }
- private function match()
- {
- $this->trashDataSources = array();
- // 结束指针
- array_push($this->dataSources, null);
- $this->baseDataSource = array_shift($this->dataSources);
- while ($this->baseDataSource) {
- $dataSource = array_shift($this->dataSources);
- while ($dataSource) {
- if ($this->matchRules($dataSource)) {
- array_push($this->matchResult, [
- $this->baseDataSource,
- $dataSource
- ]);
- $this->baseDataSource = null;
- break;
- } else {
- array_push($this->dataSources, $dataSource);
- $dataSource = array_shift($this->dataSources);
- }
- }
- $this->baseDataSource && array_push($this->trashDataSources, $this->baseDataSource);
- $this->baseDataSource = array_shift($this->dataSources);
- }
- }
- /**
- * 执行任务
- * @return void
- */
- public function run()
- {
- $this->loadMatchData();
- $this->taskInit();
- $this->match();
- $this->dataSources = $this->trashDataSources;
- $this->removeMatchRule('radius');
- $this->match();
- }
- }
|