mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-08-01 20:39:06 +08:00
去除user全文索引相关
This commit is contained in:
parent
93ec72faf6
commit
b79d6e5588
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,7 +5,6 @@
|
|||||||
/config/xs.course.ini
|
/config/xs.course.ini
|
||||||
/config/xs.article.ini
|
/config/xs.article.ini
|
||||||
/config/xs.question.ini
|
/config/xs.question.ini
|
||||||
/config/xs.user.ini
|
|
||||||
/config/alipay/*.crt
|
/config/alipay/*.crt
|
||||||
/config/wxpay/*.pem
|
/config/wxpay/*.pem
|
||||||
/db/migrations/schema.php
|
/db/migrations/schema.php
|
||||||
|
@ -106,9 +106,6 @@ class CleanDemoDataTask extends Task
|
|||||||
|
|
||||||
$questionIndexTask = new QuestionIndexTask();
|
$questionIndexTask = new QuestionIndexTask();
|
||||||
$questionIndexTask->cleanAction();
|
$questionIndexTask->cleanAction();
|
||||||
|
|
||||||
$userIndexTask = new UserIndexTask();
|
|
||||||
$userIndexTask->cleanAction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isDemoEnv()
|
protected function isDemoEnv()
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Console\Tasks;
|
|
||||||
|
|
||||||
use App\Repos\User as UserRepo;
|
|
||||||
use App\Services\Search\UserDocument;
|
|
||||||
use App\Services\Search\UserSearcher;
|
|
||||||
use App\Services\Sync\UserIndex as UserIndexSync;
|
|
||||||
|
|
||||||
class SyncUserIndexTask extends Task
|
|
||||||
{
|
|
||||||
|
|
||||||
public function mainAction()
|
|
||||||
{
|
|
||||||
$redis = $this->getRedis();
|
|
||||||
|
|
||||||
$key = $this->getSyncKey();
|
|
||||||
|
|
||||||
$userIds = $redis->sRandMember($key, 1000);
|
|
||||||
|
|
||||||
if (!$userIds) return;
|
|
||||||
|
|
||||||
$userRepo = new UserRepo();
|
|
||||||
|
|
||||||
$users = $userRepo->findByIds($userIds);
|
|
||||||
|
|
||||||
if ($users->count() == 0) return;
|
|
||||||
|
|
||||||
$document = new UserDocument();
|
|
||||||
|
|
||||||
$handler = new UserSearcher();
|
|
||||||
|
|
||||||
$index = $handler->getXS()->getIndex();
|
|
||||||
|
|
||||||
$index->openBuffer();
|
|
||||||
|
|
||||||
foreach ($users as $user) {
|
|
||||||
|
|
||||||
$doc = $document->setDocument($user);
|
|
||||||
|
|
||||||
if ($user->deleted == 0) {
|
|
||||||
$index->update($doc);
|
|
||||||
} else {
|
|
||||||
$index->del($user->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$index->closeBuffer();
|
|
||||||
|
|
||||||
$redis->sRem($key, ...$userIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getSyncKey()
|
|
||||||
{
|
|
||||||
$sync = new UserIndexSync();
|
|
||||||
|
|
||||||
return $sync->getSyncKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Console\Tasks;
|
|
||||||
|
|
||||||
use App\Models\User as UserModel;
|
|
||||||
use App\Repos\User as UserRepo;
|
|
||||||
use App\Services\Search\UserDocument;
|
|
||||||
use App\Services\Search\UserSearcher;
|
|
||||||
use Phalcon\Mvc\Model\Resultset;
|
|
||||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
|
||||||
|
|
||||||
class UserIndexTask extends Task
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索测试
|
|
||||||
*
|
|
||||||
* @command: php console.php user_index search {query}
|
|
||||||
* @param array $params
|
|
||||||
* @throws \XSException
|
|
||||||
*/
|
|
||||||
public function searchAction($params)
|
|
||||||
{
|
|
||||||
$query = $params[0] ?? null;
|
|
||||||
|
|
||||||
if (!$query) {
|
|
||||||
exit('please special a query word' . PHP_EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->searchUsers($query);
|
|
||||||
|
|
||||||
var_export($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空索引
|
|
||||||
*
|
|
||||||
* @command: php console.php user_index clean
|
|
||||||
*/
|
|
||||||
public function cleanAction()
|
|
||||||
{
|
|
||||||
$this->cleanUserIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重建索引
|
|
||||||
*
|
|
||||||
* @command: php console.php user_index rebuild
|
|
||||||
*/
|
|
||||||
public function rebuildAction()
|
|
||||||
{
|
|
||||||
$this->rebuildUserIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空索引
|
|
||||||
*/
|
|
||||||
protected function cleanUserIndex()
|
|
||||||
{
|
|
||||||
$handler = new UserSearcher();
|
|
||||||
|
|
||||||
$index = $handler->getXS()->getIndex();
|
|
||||||
|
|
||||||
echo '------ start clean user index ------' . PHP_EOL;
|
|
||||||
|
|
||||||
$index->clean();
|
|
||||||
|
|
||||||
echo '------ end clean user index ------' . PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重建索引
|
|
||||||
*/
|
|
||||||
protected function rebuildUserIndex()
|
|
||||||
{
|
|
||||||
$limit = 1000;
|
|
||||||
|
|
||||||
$totalCount = $this->countUsers();
|
|
||||||
|
|
||||||
if ($totalCount == 0) return;
|
|
||||||
|
|
||||||
$page = ceil($totalCount / $limit);
|
|
||||||
|
|
||||||
$handler = new UserSearcher();
|
|
||||||
|
|
||||||
$documenter = new UserDocument();
|
|
||||||
|
|
||||||
$index = $handler->getXS()->getIndex();
|
|
||||||
|
|
||||||
echo '------ start rebuild user index ------' . PHP_EOL;
|
|
||||||
|
|
||||||
$index->beginRebuild();
|
|
||||||
|
|
||||||
for ($i = 0; $i < $page; $i++) {
|
|
||||||
|
|
||||||
$offset = $i * $limit;
|
|
||||||
|
|
||||||
$users = $this->findUsers($limit, $offset);
|
|
||||||
|
|
||||||
if ($users->count() == 0) break;
|
|
||||||
|
|
||||||
foreach ($users as $user) {
|
|
||||||
$document = $documenter->setDocument($user);
|
|
||||||
$index->add($document);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "------ fetch users: {$limit},{$offset} ------" . PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$index->endRebuild();
|
|
||||||
|
|
||||||
echo '------ end rebuild user index ------' . PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索课程
|
|
||||||
*
|
|
||||||
* @param string $query
|
|
||||||
* @return array
|
|
||||||
* @throws \XSException
|
|
||||||
*/
|
|
||||||
protected function searchUsers($query)
|
|
||||||
{
|
|
||||||
$handler = new UserSearcher();
|
|
||||||
|
|
||||||
return $handler->search($query);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $limit
|
|
||||||
* @param int $offset
|
|
||||||
* @return ResultsetInterface|Resultset|UserModel[]
|
|
||||||
*/
|
|
||||||
protected function findUsers($limit, $offset)
|
|
||||||
{
|
|
||||||
return UserModel::query()
|
|
||||||
->where('deleted = 0')
|
|
||||||
->limit($limit, $offset)
|
|
||||||
->execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function countUsers()
|
|
||||||
{
|
|
||||||
$userRepo = new UserRepo();
|
|
||||||
|
|
||||||
return $userRepo->countUsers();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -9,9 +9,7 @@ namespace App\Http\Api\Controllers;
|
|||||||
|
|
||||||
use App\Services\Logic\Search\Article as ArticleSearch;
|
use App\Services\Logic\Search\Article as ArticleSearch;
|
||||||
use App\Services\Logic\Search\Course as CourseSearch;
|
use App\Services\Logic\Search\Course as CourseSearch;
|
||||||
use App\Services\Logic\Search\Group as GroupSearch;
|
|
||||||
use App\Services\Logic\Search\Question as QuestionSearch;
|
use App\Services\Logic\Search\Question as QuestionSearch;
|
||||||
use App\Services\Logic\Search\User as UserSearch;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/api/search")
|
* @RoutePrefix("/api/search")
|
||||||
@ -46,7 +44,7 @@ class SearchController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return ArticleSearch|QuestionSearch|CourseSearch|GroupSearch|UserSearch
|
* @return ArticleSearch|QuestionSearch|CourseSearch
|
||||||
*/
|
*/
|
||||||
protected function getSearchService($type)
|
protected function getSearchService($type)
|
||||||
{
|
{
|
||||||
@ -57,12 +55,6 @@ class SearchController extends Controller
|
|||||||
case 'question':
|
case 'question':
|
||||||
$service = new QuestionSearch();
|
$service = new QuestionSearch();
|
||||||
break;
|
break;
|
||||||
case 'group':
|
|
||||||
$service = new GroupSearch();
|
|
||||||
break;
|
|
||||||
case 'user':
|
|
||||||
$service = new UserSearch();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
$service = new CourseSearch();
|
$service = new CourseSearch();
|
||||||
break;
|
break;
|
||||||
|
@ -9,9 +9,7 @@ namespace App\Http\Home\Controllers;
|
|||||||
|
|
||||||
use App\Services\Logic\Search\Article as ArticleSearchService;
|
use App\Services\Logic\Search\Article as ArticleSearchService;
|
||||||
use App\Services\Logic\Search\Course as CourseSearchService;
|
use App\Services\Logic\Search\Course as CourseSearchService;
|
||||||
use App\Services\Logic\Search\Group as GroupSearchService;
|
|
||||||
use App\Services\Logic\Search\Question as QuestionSearchService;
|
use App\Services\Logic\Search\Question as QuestionSearchService;
|
||||||
use App\Services\Logic\Search\User as UserSearchService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/search")
|
* @RoutePrefix("/search")
|
||||||
@ -48,7 +46,7 @@ class SearchController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return ArticleSearchService|QuestionSearchService|CourseSearchService|GroupSearchService|UserSearchService
|
* @return ArticleSearchService|QuestionSearchService|CourseSearchService
|
||||||
*/
|
*/
|
||||||
protected function getSearchService($type)
|
protected function getSearchService($type)
|
||||||
{
|
{
|
||||||
@ -59,12 +57,6 @@ class SearchController extends Controller
|
|||||||
case 'question':
|
case 'question':
|
||||||
$service = new QuestionSearchService();
|
$service = new QuestionSearchService();
|
||||||
break;
|
break;
|
||||||
case 'group':
|
|
||||||
$service = new GroupSearchService();
|
|
||||||
break;
|
|
||||||
case 'user':
|
|
||||||
$service = new UserSearchService();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
$service = new CourseSearchService();
|
$service = new CourseSearchService();
|
||||||
break;
|
break;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{{ partial('macros/course') }}
|
{{ partial('macros/course') }}
|
||||||
|
|
||||||
{% set types = {'course':'课程','article':'专栏','question':'问答','user':'用户'} %}
|
{% set types = {'course':'课程','article':'专栏','question':'问答'} %}
|
||||||
{% set type = request.get('type','trim','course') %}
|
{% set type = request.get('type','trim','course') %}
|
||||||
{% set query = request.get('query','striptags','') %}
|
{% set query = request.get('query','striptags','') %}
|
||||||
|
|
||||||
@ -39,10 +39,6 @@
|
|||||||
<div class="layui-tab-item layui-show">
|
<div class="layui-tab-item layui-show">
|
||||||
{{ partial('search/question') }}
|
{{ partial('search/question') }}
|
||||||
</div>
|
</div>
|
||||||
{% elseif type == 'user' %}
|
|
||||||
<div class="layui-tab-item layui-show">
|
|
||||||
{{ partial('search/user') }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
{{ partial('macros/user') }}
|
|
||||||
|
|
||||||
{% if pager.total_pages > 0 %}
|
|
||||||
<div class="search-user-list">
|
|
||||||
{% for item in pager.items %}
|
|
||||||
{% set user_url = url({'for':'home.user.show','id':item.id}) %}
|
|
||||||
{% set item.about = item.about|default('这个家伙真懒,什么也没有留下!') %}
|
|
||||||
<div class="search-user-card">
|
|
||||||
<div class="avatar">
|
|
||||||
<a href="{{ user_url }}" target="_blank">
|
|
||||||
<img src="{{ item.avatar }}!avatar_160" alt="{{ item.name }}">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="info">
|
|
||||||
<div class="name">
|
|
||||||
<a href="{{ user_url }}" target="_blank">{{ item.name }}</a>
|
|
||||||
</div>
|
|
||||||
<div class="about">{{ item.about }}</div>
|
|
||||||
<div class="meta">
|
|
||||||
<span>性别:{{ gender_info(item.gender) }}</span>
|
|
||||||
<span>地区:{{ item.area }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
{{ partial('search/empty') }}
|
|
||||||
{% endif %}
|
|
@ -9,7 +9,6 @@ namespace App\Models;
|
|||||||
|
|
||||||
use App\Caches\MaxUserId as MaxUserIdCache;
|
use App\Caches\MaxUserId as MaxUserIdCache;
|
||||||
use App\Caches\User as UserCache;
|
use App\Caches\User as UserCache;
|
||||||
use App\Services\Sync\UserIndex as UserIndexSync;
|
|
||||||
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
||||||
use Phalcon\Text;
|
use Phalcon\Text;
|
||||||
|
|
||||||
@ -216,11 +215,6 @@ class User extends Model
|
|||||||
|
|
||||||
public function beforeUpdate()
|
public function beforeUpdate()
|
||||||
{
|
{
|
||||||
if (time() - $this->update_time > 3 * 3600) {
|
|
||||||
$sync = new UserIndexSync();
|
|
||||||
$sync->addItem($this->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->update_time = time();
|
$this->update_time = time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Services\Logic\Search;
|
|
||||||
|
|
||||||
use App\Library\Paginator\Adapter\XunSearch as XunSearchPaginator;
|
|
||||||
use App\Library\Paginator\Query as PagerQuery;
|
|
||||||
use App\Services\Search\GroupSearcher as GroupSearcherService;
|
|
||||||
use Phalcon\Text;
|
|
||||||
|
|
||||||
class Group extends Handler
|
|
||||||
{
|
|
||||||
|
|
||||||
public function search()
|
|
||||||
{
|
|
||||||
$pagerQuery = new PagerQuery();
|
|
||||||
|
|
||||||
$params = $pagerQuery->getParams();
|
|
||||||
$page = $pagerQuery->getPage();
|
|
||||||
$limit = $pagerQuery->getLimit();
|
|
||||||
|
|
||||||
$searcher = new GroupSearcherService();
|
|
||||||
|
|
||||||
$paginator = new XunSearchPaginator([
|
|
||||||
'xs' => $searcher->getXS(),
|
|
||||||
'highlight' => $searcher->getHighlightFields(),
|
|
||||||
'query' => $params['query'],
|
|
||||||
'page' => $page,
|
|
||||||
'limit' => $limit,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$pager = $paginator->getPaginate();
|
|
||||||
|
|
||||||
return $this->handleGroups($pager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHotQuery($limit = 10, $type = 'total')
|
|
||||||
{
|
|
||||||
$searcher = new GroupSearcherService();
|
|
||||||
|
|
||||||
return $searcher->getHotQuery($limit, $type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRelatedQuery($query, $limit = 10)
|
|
||||||
{
|
|
||||||
$searcher = new GroupSearcherService();
|
|
||||||
|
|
||||||
return $searcher->getRelatedQuery($query, $limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleGroups($pager)
|
|
||||||
{
|
|
||||||
if ($pager->total_items == 0) {
|
|
||||||
return $pager;
|
|
||||||
}
|
|
||||||
|
|
||||||
$items = [];
|
|
||||||
|
|
||||||
$baseUrl = kg_cos_url();
|
|
||||||
|
|
||||||
foreach ($pager->items as $item) {
|
|
||||||
|
|
||||||
$owner = json_decode($item['owner'], true);
|
|
||||||
|
|
||||||
if (!empty($item['avatar']) && !Text::startsWith($item['avatar'], 'http')) {
|
|
||||||
$item['avatar'] = $baseUrl . $item['avatar'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$items[] = [
|
|
||||||
'id' => (int)$item['id'],
|
|
||||||
'type' => (int)$item['type'],
|
|
||||||
'name' => (string)$item['name'],
|
|
||||||
'avatar' => (string)$item['avatar'],
|
|
||||||
'about' => (string)$item['about'],
|
|
||||||
'user_count' => (int)$item['user_count'],
|
|
||||||
'msg_count' => (int)$item['msg_count'],
|
|
||||||
'owner' => $owner,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$pager->items = $items;
|
|
||||||
|
|
||||||
return $pager;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Services\Logic\Search;
|
|
||||||
|
|
||||||
use App\Library\Paginator\Adapter\XunSearch as XunSearchPaginator;
|
|
||||||
use App\Library\Paginator\Query as PagerQuery;
|
|
||||||
use App\Services\Search\UserSearcher as UserSearcherService;
|
|
||||||
|
|
||||||
class User extends Handler
|
|
||||||
{
|
|
||||||
|
|
||||||
public function search()
|
|
||||||
{
|
|
||||||
$pagerQuery = new PagerQuery();
|
|
||||||
|
|
||||||
$params = $pagerQuery->getParams();
|
|
||||||
$page = $pagerQuery->getPage();
|
|
||||||
$limit = $pagerQuery->getLimit();
|
|
||||||
|
|
||||||
$searcher = new UserSearcherService();
|
|
||||||
|
|
||||||
$paginator = new XunSearchPaginator([
|
|
||||||
'xs' => $searcher->getXS(),
|
|
||||||
'highlight' => $searcher->getHighlightFields(),
|
|
||||||
'query' => $params['query'],
|
|
||||||
'page' => $page,
|
|
||||||
'limit' => $limit,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$pager = $paginator->getPaginate();
|
|
||||||
|
|
||||||
return $this->handleUsers($pager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHotQuery($limit = 10, $type = 'total')
|
|
||||||
{
|
|
||||||
$searcher = new UserSearcherService();
|
|
||||||
|
|
||||||
return $searcher->getHotQuery($limit, $type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRelatedQuery($query, $limit = 10)
|
|
||||||
{
|
|
||||||
$searcher = new UserSearcherService();
|
|
||||||
|
|
||||||
return $searcher->getRelatedQuery($query, $limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleUsers($pager)
|
|
||||||
{
|
|
||||||
if ($pager->total_items == 0) {
|
|
||||||
return $pager;
|
|
||||||
}
|
|
||||||
|
|
||||||
$items = [];
|
|
||||||
|
|
||||||
$baseUrl = kg_cos_url();
|
|
||||||
|
|
||||||
foreach ($pager->items as $item) {
|
|
||||||
|
|
||||||
$item['avatar'] = $baseUrl . $item['avatar'];
|
|
||||||
|
|
||||||
$items[] = [
|
|
||||||
'id' => (int)$item['id'],
|
|
||||||
'name' => (string)$item['name'],
|
|
||||||
'avatar' => (string)$item['avatar'],
|
|
||||||
'title' => (string)$item['title'],
|
|
||||||
'about' => (string)$item['about'],
|
|
||||||
'vip' => (int)$item['vip'],
|
|
||||||
'gender' => (int)$item['gender'],
|
|
||||||
'area' => (string)$item['area'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$pager->items = $items;
|
|
||||||
|
|
||||||
return $pager;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Services\Search;
|
|
||||||
|
|
||||||
use App\Models\User as UserModel;
|
|
||||||
use Phalcon\Di\Injectable;
|
|
||||||
|
|
||||||
class UserDocument extends Injectable
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置文档
|
|
||||||
*
|
|
||||||
* @param UserModel $user
|
|
||||||
* @return \XSDocument
|
|
||||||
*/
|
|
||||||
public function setDocument(UserModel $user)
|
|
||||||
{
|
|
||||||
$doc = new \XSDocument();
|
|
||||||
|
|
||||||
$data = $this->formatDocument($user);
|
|
||||||
|
|
||||||
$doc->setFields($data);
|
|
||||||
|
|
||||||
return $doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化文档
|
|
||||||
*
|
|
||||||
* @param UserModel $user
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function formatDocument(UserModel $user)
|
|
||||||
{
|
|
||||||
$user->avatar = UserModel::getAvatarPath($user->avatar);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => $user->id,
|
|
||||||
'name' => $user->name,
|
|
||||||
'title' => $user->title,
|
|
||||||
'avatar' => $user->avatar,
|
|
||||||
'about' => $user->about,
|
|
||||||
'gender' => $user->gender,
|
|
||||||
'area' => $user->area,
|
|
||||||
'vip' => $user->vip,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Services\Search;
|
|
||||||
|
|
||||||
class UserSearcher extends Searcher
|
|
||||||
{
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->xs = $this->getXS();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getXS()
|
|
||||||
{
|
|
||||||
$filename = config_path('xs.user.ini');
|
|
||||||
|
|
||||||
return new \XS($filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHighlightFields()
|
|
||||||
{
|
|
||||||
return ['name', 'about'];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Services\Sync;
|
|
||||||
|
|
||||||
use App\Services\Service;
|
|
||||||
|
|
||||||
class UserIndex extends Service
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
protected $lifetime = 86400;
|
|
||||||
|
|
||||||
public function addItem($userId)
|
|
||||||
{
|
|
||||||
$redis = $this->getRedis();
|
|
||||||
|
|
||||||
$key = $this->getSyncKey();
|
|
||||||
|
|
||||||
$redis->sAdd($key, $userId);
|
|
||||||
|
|
||||||
if ($redis->sCard($key) == 1) {
|
|
||||||
$redis->expire($key, $this->lifetime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSyncKey()
|
|
||||||
{
|
|
||||||
return 'sync_user_index';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
project.name = user
|
|
||||||
project.default_charset = UTF-8
|
|
||||||
|
|
||||||
server.index = xunsearch:8383
|
|
||||||
server.search = xunsearch:8384
|
|
||||||
|
|
||||||
[id]
|
|
||||||
type = id
|
|
||||||
|
|
||||||
[name]
|
|
||||||
type = title
|
|
||||||
|
|
||||||
[avatar]
|
|
||||||
type = string
|
|
||||||
|
|
||||||
[title]
|
|
||||||
type = string
|
|
||||||
|
|
||||||
[about]
|
|
||||||
type = body
|
|
||||||
|
|
||||||
[area]
|
|
||||||
type = string
|
|
||||||
index = self
|
|
||||||
|
|
||||||
[gender]
|
|
||||||
type = string
|
|
||||||
index = self
|
|
||||||
tokenizer = full
|
|
||||||
|
|
||||||
[vip]
|
|
||||||
type = string
|
|
@ -353,16 +353,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card,
|
.search-course-card,
|
||||||
.search-article-card,
|
.search-article-card {
|
||||||
.search-user-card {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
border-bottom: 1px solid #f6f6f6;
|
border-bottom: 1px solid #f6f6f6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card:last-child,
|
.search-course-card:last-child {
|
||||||
.search-user-card:last-child {
|
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
border: none;
|
border: none;
|
||||||
@ -374,8 +372,7 @@
|
|||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card .cover img,
|
.search-course-card .cover img {
|
||||||
.search-user-card .avatar img {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -384,14 +381,12 @@
|
|||||||
width: 500px;
|
width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card .title,
|
.search-course-card .title {
|
||||||
.search-user-card .name {
|
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card .summary,
|
.search-course-card .summary {
|
||||||
.search-user-card .about {
|
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
max-height: 4.5em;
|
max-height: 4.5em;
|
||||||
@ -401,41 +396,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card .meta,
|
.search-course-card .meta,
|
||||||
.search-user-card .meta,
|
|
||||||
.search-article-card .meta,
|
.search-article-card .meta,
|
||||||
.search-question-card .meta {
|
.search-question-card .meta {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card .meta span,
|
.search-course-card .meta span,
|
||||||
.search-user-card .meta span,
|
|
||||||
.search-article-card .meta span,
|
.search-article-card .meta span,
|
||||||
.search-question-card .meta span {
|
.search-question-card .meta span {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-course-card em,
|
.search-course-card em,
|
||||||
.search-user-card em,
|
|
||||||
.search-article-card em,
|
.search-article-card em,
|
||||||
.search-question-card em {
|
.search-question-card em {
|
||||||
color: red;
|
color: red;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-user-card .avatar {
|
|
||||||
width: 90px;
|
|
||||||
height: 90px;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-user-card .avatar img {
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-user-card .info {
|
|
||||||
width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.query-badge {
|
.query-badge {
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user