BasePairMatch.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. namespace App\Services\Pair;
  3. use App\Services\Pair\DataModels\PairMatchDataSource;
  4. use Illuminate\Support\Facades\Redis;
  5. abstract class BasePairMatch
  6. {
  7. /** @var int 匹配期数 */
  8. protected $stageId;
  9. /** @var array 匹配结果 */
  10. public $matchResult = array();
  11. /** @var PairMatchDataSource[] 数据源 */
  12. protected $dataSources = array();
  13. /** @var PairMatchDataSource[] 垃圾桶数据源 */
  14. private $trashDataSources = array();
  15. /** @var PairMatchDataSource 基准对比源 */
  16. private $baseDataSource;
  17. /** @var string 定位缓存key */
  18. private $LBSCacheKey;
  19. /** @var array 匹配规则数组 */
  20. private $matchRuleFuncs = array('radius', 'age', 'height', 'gender', 'noOnce');
  21. public function __construct()
  22. {
  23. }
  24. /**
  25. * 加载匹配数据源
  26. */
  27. abstract public function loadMatchData();
  28. /**
  29. * 添加匹配规则
  30. * @param array|string $rule
  31. */
  32. protected function addMatchRule($rule)
  33. {
  34. if (is_array($rule)) {
  35. array_map(function ($item) {
  36. array_push($this->matchRuleFuncs, $item);
  37. }, $rule);
  38. } else {
  39. array_push($this->matchRuleFuncs, $rule);
  40. }
  41. $this->matchRuleFuncs = array_unique($this->matchRuleFuncs);
  42. }
  43. /**
  44. * 移除匹配规则
  45. * @param array|string $rule
  46. */
  47. protected function removeMatchRule($rule)
  48. {
  49. if (!is_array($rule)) {
  50. $rule = array($rule);
  51. }
  52. $this->matchRuleFuncs = array_diff($this->matchRuleFuncs, $rule);
  53. }
  54. /**
  55. * 是否匹配范围
  56. * @param PairMatchDataSource $dataSource
  57. * @return bool
  58. */
  59. public function isMatchRadius(PairMatchDataSource $dataSource): bool
  60. {
  61. if (! $this->baseDataSource->rangeUsers) {
  62. $this->baseDataSource->rangeUsers = Redis::geoRadius($this->LBSCacheKey, $this->baseDataSource->enrollLongitude, $this->baseDataSource->enrollLatitude, $this->baseDataSource->matchRadius, 'km');
  63. }
  64. if (! $dataSource->rangeUsers) {
  65. $dataSource->rangeUsers = Redis::geoRadius($this->LBSCacheKey, $dataSource->enrollLongitude, $dataSource->enrollLatitude, $dataSource->matchRadius, 'km');
  66. }
  67. if (in_array($dataSource->uid, $this->baseDataSource->rangeUsers) && in_array($this->baseDataSource->uid, $dataSource->rangeUsers)) {
  68. return true;
  69. }
  70. return false;
  71. }
  72. /**
  73. * 是否匹配年龄
  74. * @param PairMatchDataSource $dataSource
  75. * @return bool
  76. */
  77. public function isMatchAge(PairMatchDataSource $dataSource): bool
  78. {
  79. return false;
  80. }
  81. /**
  82. * 是否匹配身高
  83. * @param PairMatchDataSource $dataSource
  84. * @return bool
  85. */
  86. public function isMatchHeight(PairMatchDataSource $dataSource): bool
  87. {
  88. return false;
  89. }
  90. /**
  91. * 是否匹配性别
  92. * @param PairMatchDataSource $dataSource
  93. * @return bool
  94. */
  95. public function isMatchGender(PairMatchDataSource $dataSource): bool
  96. {
  97. if (
  98. $this->baseDataSource->gender == $dataSource->sexualOrientation &&
  99. $this->baseDataSource->sexualOrientation = $dataSource->gender
  100. ) {
  101. return true;
  102. } else {
  103. return false;
  104. }
  105. }
  106. /**
  107. * 是否匹配过
  108. * @param PairMatchDataSource $dataSource
  109. * @return bool
  110. */
  111. public function isMatchNoOnce(PairMatchDataSource $dataSource): bool
  112. {
  113. return false;
  114. }
  115. /**
  116. * 任务初始化
  117. */
  118. public function taskInit()
  119. {
  120. $this->LBSCacheKey = "pair:{$this->stageId}:lsb";
  121. }
  122. public function matchRules(PairMatchDataSource $dataSource): bool
  123. {
  124. $boolMatch = true;
  125. foreach ($this->matchRuleFuncs as $func) {
  126. if (method_exists($this, "isMatch" . ucfirst($func))) {
  127. $boolMatch = $boolMatch && $this->{"isMatch" . ucfirst($func)}($dataSource);
  128. } else {
  129. $boolMatch = $boolMatch && false;
  130. }
  131. }
  132. return $boolMatch;
  133. }
  134. private function match()
  135. {
  136. $this->trashDataSources = array();
  137. // 结束指针
  138. array_push($this->dataSources, null);
  139. $this->baseDataSource = array_shift($this->dataSources);
  140. while ($this->baseDataSource) {
  141. $dataSource = array_shift($this->dataSources);
  142. while ($dataSource) {
  143. if ($this->matchRules($dataSource)) {
  144. array_push($this->matchResult, [
  145. $this->baseDataSource,
  146. $dataSource
  147. ]);
  148. $this->baseDataSource = null;
  149. break;
  150. } else {
  151. array_push($this->dataSources, $dataSource);
  152. $dataSource = array_shift($this->dataSources);
  153. }
  154. }
  155. $this->baseDataSource && array_push($this->trashDataSources, $this->baseDataSource);
  156. $this->baseDataSource = array_shift($this->dataSources);
  157. }
  158. }
  159. /**
  160. * 执行任务
  161. * @return void
  162. */
  163. public function run()
  164. {
  165. $this->loadMatchData();
  166. $this->taskInit();
  167. $this->match();
  168. $this->dataSources = $this->trashDataSources;
  169. $this->removeMatchRule('radius');
  170. $this->match();
  171. }
  172. }