feat: rank community recommendation feed
This commit is contained in:
@@ -30,6 +30,11 @@ export function communityPostSetRecommend(params: any) {
|
|||||||
return request.post({ url: '/community.communityPost/setRecommend', params })
|
return request.post({ url: '/community.communityPost/setRecommend', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 帖子推荐流排序
|
||||||
|
export function communityPostSetSort(params: any) {
|
||||||
|
return request.post({ url: '/community.communityPost/setSort', params })
|
||||||
|
}
|
||||||
|
|
||||||
// 帖子设话题
|
// 帖子设话题
|
||||||
export function communityPostSetTopic(params: any) {
|
export function communityPostSetTopic(params: any) {
|
||||||
return request.post({ url: '/community.communityPost/setTopic', params })
|
return request.post({ url: '/community.communityPost/setTopic', params })
|
||||||
|
|||||||
@@ -103,6 +103,12 @@
|
|||||||
:active-value="1" :inactive-value="0" @change="handleSetRecommend($event, row.id)" />
|
:active-value="1" :inactive-value="0" @change="handleSetRecommend($event, row.id)" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="排序" min-width="130">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input-number v-perms="['community.communityPost/setSort']" v-model="row.sort" :min="0"
|
||||||
|
:max="999999" :controls="false" class="!w-[100px]" @change="handleSetSort($event, row.id)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="热门" min-width="70">
|
<el-table-column label="热门" min-width="70">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-switch v-perms="['community.communityPost/setHot']" v-model="row.is_hot" :active-value="1"
|
<el-switch v-perms="['community.communityPost/setHot']" v-model="row.is_hot" :active-value="1"
|
||||||
@@ -183,6 +189,7 @@
|
|||||||
<el-descriptions-item label="置顶">{{ detailData.is_top ? '是' : '否' }}</el-descriptions-item>
|
<el-descriptions-item label="置顶">{{ detailData.is_top ? '是' : '否' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="分类">{{ detailData.category_name || '未分类' }}</el-descriptions-item>
|
<el-descriptions-item label="分类">{{ detailData.category_name || '未分类' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="推荐">{{ detailData.is_recommend ? '是' : '否' }}</el-descriptions-item>
|
<el-descriptions-item label="推荐">{{ detailData.is_recommend ? '是' : '否' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="排序">{{ detailData.sort || 0 }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="热门">{{ detailData.is_hot ? '是' : '否' }}</el-descriptions-item>
|
<el-descriptions-item label="热门">{{ detailData.is_hot ? '是' : '否' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="话题">{{ detailData.is_topic ? '是' : '否' }}</el-descriptions-item>
|
<el-descriptions-item label="话题">{{ detailData.is_topic ? '是' : '否' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="更新时间">{{ detailData.update_time || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="更新时间">{{ detailData.update_time || '-' }}</el-descriptions-item>
|
||||||
@@ -202,6 +209,7 @@ import {
|
|||||||
communityPostSetTop,
|
communityPostSetTop,
|
||||||
communityPostSetHot,
|
communityPostSetHot,
|
||||||
communityPostSetRecommend,
|
communityPostSetRecommend,
|
||||||
|
communityPostSetSort,
|
||||||
communityPostSetTopic,
|
communityPostSetTopic,
|
||||||
communityPostSetCategory,
|
communityPostSetCategory,
|
||||||
communityCategoryAll,
|
communityCategoryAll,
|
||||||
@@ -259,6 +267,15 @@ const handleSetRecommend = async (is_recommend: any, id: number) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSetSort = async (sort: any, id: number) => {
|
||||||
|
try {
|
||||||
|
await communityPostSetSort({ id, sort: Number(sort) || 0 })
|
||||||
|
getLists()
|
||||||
|
} catch (error) {
|
||||||
|
getLists()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleSetTopic = async (is_topic: any, id: number) => {
|
const handleSetTopic = async (is_topic: any, id: number) => {
|
||||||
try {
|
try {
|
||||||
await communityPostSetTopic({ id, is_topic })
|
await communityPostSetTopic({ id, is_topic })
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
SET @has_post_sort = (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM `information_schema`.`columns`
|
||||||
|
WHERE `table_schema` = DATABASE()
|
||||||
|
AND `table_name` = 'la_community_post'
|
||||||
|
AND `column_name` = 'sort'
|
||||||
|
);
|
||||||
|
SET @sql = IF(
|
||||||
|
@has_post_sort = 0,
|
||||||
|
'ALTER TABLE `la_community_post` ADD COLUMN `sort` int unsigned NOT NULL DEFAULT 0 COMMENT ''推荐流排序值,越大越靠前'' AFTER `is_topic`',
|
||||||
|
'SELECT ''la_community_post.sort already exists'''
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @has_recommend_sort_index = (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM `information_schema`.`statistics`
|
||||||
|
WHERE `table_schema` = DATABASE()
|
||||||
|
AND `table_name` = 'la_community_post'
|
||||||
|
AND `index_name` = 'idx_status_recommend_sort'
|
||||||
|
);
|
||||||
|
SET @sql = IF(
|
||||||
|
@has_recommend_sort_index = 0,
|
||||||
|
'ALTER TABLE `la_community_post` ADD INDEX `idx_status_recommend_sort` (`status`, `is_recommend`, `sort`, `create_time`)',
|
||||||
|
'SELECT ''la_community_post.idx_status_recommend_sort already exists'''
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @post_menu_id = COALESCE(
|
||||||
|
(SELECT `id` FROM `la_system_menu` WHERE `perms` = 'community.communityPost/lists' LIMIT 1),
|
||||||
|
(SELECT `id` FROM `la_system_menu` WHERE `component` = 'community/post/index' LIMIT 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO `la_system_menu`
|
||||||
|
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
|
||||||
|
SELECT @post_menu_id, 'A', '设置排序', '', 0, 'community.communityPost/setSort', '', '', '', '', 0, 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||||
|
WHERE @post_menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM `la_system_menu` WHERE `perms` = 'community.communityPost/setSort'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO `la_system_role_menu` (`role_id`, `menu_id`)
|
||||||
|
SELECT 1, menu.`id`
|
||||||
|
FROM `la_system_menu` menu
|
||||||
|
WHERE menu.`perms` = 'community.communityPost/setSort'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM `la_system_role_menu` role_menu
|
||||||
|
WHERE role_menu.`role_id` = 1
|
||||||
|
AND role_menu.`menu_id` = menu.`id`
|
||||||
|
);
|
||||||
@@ -372,6 +372,7 @@ CREATE TABLE `la_community_post` (
|
|||||||
`is_hot` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '0否1热门',
|
`is_hot` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '0否1热门',
|
||||||
`is_recommend` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否推荐 0否 1是',
|
`is_recommend` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否推荐 0否 1是',
|
||||||
`is_topic` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否话题 0否 1是',
|
`is_topic` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否话题 0否 1是',
|
||||||
|
`sort` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '推荐流排序值,越大越靠前',
|
||||||
`status` tinyint UNSIGNED NOT NULL DEFAULT 1 COMMENT '0待审核1正常2隐藏',
|
`status` tinyint UNSIGNED NOT NULL DEFAULT 1 COMMENT '0待审核1正常2隐藏',
|
||||||
`create_time` int UNSIGNED NOT NULL DEFAULT 0,
|
`create_time` int UNSIGNED NOT NULL DEFAULT 0,
|
||||||
`update_time` int UNSIGNED NOT NULL DEFAULT 0,
|
`update_time` int UNSIGNED NOT NULL DEFAULT 0,
|
||||||
@@ -383,6 +384,7 @@ CREATE TABLE `la_community_post` (
|
|||||||
INDEX `idx_category`(`category_id` ASC) USING BTREE,
|
INDEX `idx_category`(`category_id` ASC) USING BTREE,
|
||||||
INDEX `idx_status`(`status` ASC) USING BTREE,
|
INDEX `idx_status`(`status` ASC) USING BTREE,
|
||||||
INDEX `idx_status_recommend`(`status` ASC, `is_recommend` ASC, `create_time` ASC) USING BTREE,
|
INDEX `idx_status_recommend`(`status` ASC, `is_recommend` ASC, `create_time` ASC) USING BTREE,
|
||||||
|
INDEX `idx_status_recommend_sort`(`status` ASC, `is_recommend` ASC, `sort` ASC, `create_time` ASC) USING BTREE,
|
||||||
INDEX `idx_status_hot`(`status` ASC, `is_hot` ASC, `create_time` ASC) USING BTREE,
|
INDEX `idx_status_hot`(`status` ASC, `is_hot` ASC, `create_time` ASC) USING BTREE,
|
||||||
INDEX `idx_status_topic`(`status` ASC, `is_topic` ASC, `create_time` ASC) USING BTREE,
|
INDEX `idx_status_topic`(`status` ASC, `is_topic` ASC, `create_time` ASC) USING BTREE,
|
||||||
INDEX `idx_create`(`create_time` ASC) USING BTREE
|
INDEX `idx_create`(`create_time` ASC) USING BTREE
|
||||||
|
|||||||
@@ -61,6 +61,16 @@ class CommunityPostController extends BaseAdminController
|
|||||||
return $this->fail(CommunityPostLogic::getError());
|
return $this->fail(CommunityPostLogic::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setSort()
|
||||||
|
{
|
||||||
|
$params = (new CommunityPostValidate())->post()->goCheck('sort');
|
||||||
|
$result = CommunityPostLogic::setSort($params);
|
||||||
|
if (true === $result) {
|
||||||
|
return $this->success('设置成功', [], 1, 1);
|
||||||
|
}
|
||||||
|
return $this->fail(CommunityPostLogic::getError());
|
||||||
|
}
|
||||||
|
|
||||||
public function setTopic()
|
public function setTopic()
|
||||||
{
|
{
|
||||||
$params = (new CommunityPostValidate())->post()->goCheck('topic');
|
$params = (new CommunityPostValidate())->post()->goCheck('topic');
|
||||||
|
|||||||
@@ -92,6 +92,20 @@ class CommunityPostLogic extends BaseLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function setSort(array $params): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
CommunityPost::update([
|
||||||
|
'id' => $params['id'],
|
||||||
|
'sort' => (int) $params['sort'],
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
self::setError($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function setTopic(array $params): bool
|
public static function setTopic(array $params): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class CommunityPostValidate extends BaseValidate
|
|||||||
'is_top' => 'require|in:0,1',
|
'is_top' => 'require|in:0,1',
|
||||||
'is_hot' => 'require|in:0,1',
|
'is_hot' => 'require|in:0,1',
|
||||||
'is_recommend' => 'require|in:0,1',
|
'is_recommend' => 'require|in:0,1',
|
||||||
|
'sort' => 'require|integer|egt:0|elt:1000000',
|
||||||
'is_topic' => 'require|in:0,1',
|
'is_topic' => 'require|in:0,1',
|
||||||
'category_id' => 'require|integer|egt:0|checkCategory',
|
'category_id' => 'require|integer|egt:0|checkCategory',
|
||||||
];
|
];
|
||||||
@@ -53,6 +54,11 @@ class CommunityPostValidate extends BaseValidate
|
|||||||
return $this->only(['id', 'is_recommend']);
|
return $this->only(['id', 'is_recommend']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sceneSort()
|
||||||
|
{
|
||||||
|
return $this->only(['id', 'sort']);
|
||||||
|
}
|
||||||
|
|
||||||
public function sceneTopic()
|
public function sceneTopic()
|
||||||
{
|
{
|
||||||
return $this->only(['id', 'is_topic']);
|
return $this->only(['id', 'is_topic']);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use app\common\model\community\CommunityLike;
|
|||||||
class CommunityPostLists extends BaseApiDataLists
|
class CommunityPostLists extends BaseApiDataLists
|
||||||
{
|
{
|
||||||
private const LIUHE_TAGS = ['旧澳六合', '新澳六合'];
|
private const LIUHE_TAGS = ['旧澳六合', '新澳六合'];
|
||||||
|
private const FEED_RECOMMEND = 'recommend';
|
||||||
|
|
||||||
private function buildQuery()
|
private function buildQuery()
|
||||||
{
|
{
|
||||||
@@ -94,8 +95,8 @@ class CommunityPostLists extends BaseApiDataLists
|
|||||||
public function lists(): array
|
public function lists(): array
|
||||||
{
|
{
|
||||||
$list = $this->buildQuery()
|
$list = $this->buildQuery()
|
||||||
->field('id,origin_id,user_id,content,images,ext,post_type,category_id,match_id,is_paid,price_points,paid_count,view_count,like_count,comment_count,share_count,is_top,is_hot,is_recommend,is_topic,create_time')
|
->field('id,origin_id,user_id,content,images,ext,post_type,category_id,match_id,is_paid,price_points,paid_count,view_count,like_count,comment_count,share_count,is_top,is_hot,is_recommend,is_topic,sort,create_time')
|
||||||
->orderRaw('is_top DESC, is_hot DESC, create_time DESC')
|
->orderRaw($this->getOrderSql())
|
||||||
->limit($this->limitOffset, $this->limitLength)
|
->limit($this->limitOffset, $this->limitLength)
|
||||||
->select()
|
->select()
|
||||||
->toArray();
|
->toArray();
|
||||||
@@ -214,6 +215,15 @@ class CommunityPostLists extends BaseApiDataLists
|
|||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getOrderSql(): string
|
||||||
|
{
|
||||||
|
if (($this->params['feed'] ?? '') === self::FEED_RECOMMEND) {
|
||||||
|
return 'is_recommend DESC, sort DESC, create_time DESC, id DESC';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'is_top DESC, is_hot DESC, create_time DESC, id DESC';
|
||||||
|
}
|
||||||
|
|
||||||
public function count(): int
|
public function count(): int
|
||||||
{
|
{
|
||||||
return $this->buildQuery()->count();
|
return $this->buildQuery()->count();
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ const fetchPosts = async (reset = false) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const params: Record<string, any> = { page_no: page.value, page_size: pageSize }
|
const params: Record<string, any> = { page_no: page.value, page_size: pageSize }
|
||||||
if (activeFeed.value === 'recommend') params.is_recommend = 1
|
if (activeFeed.value === 'recommend') params.feed = 'recommend'
|
||||||
if (activeFeed.value === 'follow') params.follow = 1
|
if (activeFeed.value === 'follow') params.follow = 1
|
||||||
if (activeFeed.value === 'hot') params.is_hot = 1
|
if (activeFeed.value === 'hot') params.is_hot = 1
|
||||||
if (activeFeed.value === 'topic') params.is_topic = 1
|
if (activeFeed.value === 'topic') params.is_topic = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user