mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-08-01 04:18:09 +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.article.ini
|
||||
/config/xs.question.ini
|
||||
/config/xs.user.ini
|
||||
/config/alipay/*.crt
|
||||
/config/wxpay/*.pem
|
||||
/db/migrations/schema.php
|
||||
|
@ -106,9 +106,6 @@ class CleanDemoDataTask extends Task
|
||||
|
||||
$questionIndexTask = new QuestionIndexTask();
|
||||
$questionIndexTask->cleanAction();
|
||||
|
||||
$userIndexTask = new UserIndexTask();
|
||||
$userIndexTask->cleanAction();
|
||||
}
|
||||
|
||||
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\Course as CourseSearch;
|
||||
use App\Services\Logic\Search\Group as GroupSearch;
|
||||
use App\Services\Logic\Search\Question as QuestionSearch;
|
||||
use App\Services\Logic\Search\User as UserSearch;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/api/search")
|
||||
@ -46,7 +44,7 @@ class SearchController extends Controller
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return ArticleSearch|QuestionSearch|CourseSearch|GroupSearch|UserSearch
|
||||
* @return ArticleSearch|QuestionSearch|CourseSearch
|
||||
*/
|
||||
protected function getSearchService($type)
|
||||
{
|
||||
@ -57,12 +55,6 @@ class SearchController extends Controller
|
||||
case 'question':
|
||||
$service = new QuestionSearch();
|
||||
break;
|
||||
case 'group':
|
||||
$service = new GroupSearch();
|
||||
break;
|
||||
case 'user':
|
||||
$service = new UserSearch();
|
||||
break;
|
||||
default:
|
||||
$service = new CourseSearch();
|
||||
break;
|
||||
|
@ -9,9 +9,7 @@ namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Services\Logic\Search\Article as ArticleSearchService;
|
||||
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\User as UserSearchService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/search")
|
||||
@ -48,7 +46,7 @@ class SearchController extends Controller
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return ArticleSearchService|QuestionSearchService|CourseSearchService|GroupSearchService|UserSearchService
|
||||
* @return ArticleSearchService|QuestionSearchService|CourseSearchService
|
||||
*/
|
||||
protected function getSearchService($type)
|
||||
{
|
||||
@ -59,12 +57,6 @@ class SearchController extends Controller
|
||||
case 'question':
|
||||
$service = new QuestionSearchService();
|
||||
break;
|
||||
case 'group':
|
||||
$service = new GroupSearchService();
|
||||
break;
|
||||
case 'user':
|
||||
$service = new UserSearchService();
|
||||
break;
|
||||
default:
|
||||
$service = new CourseSearchService();
|
||||
break;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
{{ partial('macros/course') }}
|
||||
|
||||
{% set types = {'course':'课程','article':'专栏','question':'问答','user':'用户'} %}
|
||||
{% set types = {'course':'课程','article':'专栏','question':'问答'} %}
|
||||
{% set type = request.get('type','trim','course') %}
|
||||
{% set query = request.get('query','striptags','') %}
|
||||
|
||||
@ -39,10 +39,6 @@
|
||||
<div class="layui-tab-item layui-show">
|
||||
{{ partial('search/question') }}
|
||||
</div>
|
||||
{% elseif type == 'user' %}
|
||||
<div class="layui-tab-item layui-show">
|
||||
{{ partial('search/user') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</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\User as UserCache;
|
||||
use App\Services\Sync\UserIndex as UserIndexSync;
|
||||
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
||||
use Phalcon\Text;
|
||||
|
||||
@ -216,11 +215,6 @@ class User extends Model
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (time() - $this->update_time > 3 * 3600) {
|
||||
$sync = new UserIndexSync();
|
||||
$sync->addItem($this->id);
|
||||
}
|
||||
|
||||
$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-article-card,
|
||||
.search-user-card {
|
||||
.search-article-card {
|
||||
display: flex;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
}
|
||||
|
||||
.search-course-card:last-child,
|
||||
.search-user-card:last-child {
|
||||
.search-course-card:last-child {
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
border: none;
|
||||
@ -374,8 +372,7 @@
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.search-course-card .cover img,
|
||||
.search-user-card .avatar img {
|
||||
.search-course-card .cover img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -384,14 +381,12 @@
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.search-course-card .title,
|
||||
.search-user-card .name {
|
||||
.search-course-card .title {
|
||||
margin-bottom: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.search-course-card .summary,
|
||||
.search-user-card .about {
|
||||
.search-course-card .summary {
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.5em;
|
||||
max-height: 4.5em;
|
||||
@ -401,41 +396,24 @@
|
||||
}
|
||||
|
||||
.search-course-card .meta,
|
||||
.search-user-card .meta,
|
||||
.search-article-card .meta,
|
||||
.search-question-card .meta {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.search-course-card .meta span,
|
||||
.search-user-card .meta span,
|
||||
.search-article-card .meta span,
|
||||
.search-question-card .meta span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.search-course-card em,
|
||||
.search-user-card em,
|
||||
.search-article-card em,
|
||||
.search-question-card em {
|
||||
color: red;
|
||||
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 {
|
||||
padding: 2px 5px;
|
||||
margin-right: 5px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user