no message
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\lists\community;
|
||||
|
||||
use app\api\lists\BaseApiDataLists;
|
||||
use app\common\model\community\CommunityPost;
|
||||
use app\common\model\community\CommunityFollow;
|
||||
use app\common\model\community\CommunityTag;
|
||||
use app\common\model\user\User;
|
||||
use app\common\enum\user\AccountLogEnum;
|
||||
use app\common\service\ai\AiService;
|
||||
use app\common\service\VipService;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use app\common\model\community\CommunityLike;
|
||||
|
||||
class CommunityPostLists extends BaseApiDataLists
|
||||
{
|
||||
private const LIUHE_TAGS = ['旧澳六合', '新澳六合'];
|
||||
|
||||
private function buildQuery()
|
||||
{
|
||||
$query = CommunityPost::where($this->queryWhere());
|
||||
$trumpTagId = (int) CommunityTag::where('name', '特朗普')->value('id');
|
||||
if ($trumpTagId > 0) {
|
||||
$query->whereRaw(
|
||||
"NOT (id IN (SELECT post_id FROM la_community_post_tag WHERE tag_id = {$trumpTagId})" .
|
||||
" AND TRIM(IFNULL(content, '')) = ''" .
|
||||
" AND IFNULL(images, '[]') <> '[]')"
|
||||
);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function queryWhere(): array
|
||||
{
|
||||
$where = [['status', '=', 1]];
|
||||
|
||||
if (!empty($this->params['post_type'])) {
|
||||
$where[] = ['post_type', '=', $this->params['post_type']];
|
||||
}
|
||||
if (!empty($this->params['user_id'])) {
|
||||
$where[] = ['user_id', '=', $this->params['user_id']];
|
||||
}
|
||||
if (!empty($this->params['follow']) && $this->userId) {
|
||||
$followUserIds = CommunityFollow::where('user_id', $this->userId)
|
||||
->column('follow_user_id');
|
||||
if ($followUserIds) {
|
||||
$where[] = ['user_id', 'in', $followUserIds];
|
||||
} else {
|
||||
$where[] = ['id', '=', 0];
|
||||
}
|
||||
}
|
||||
if (!empty($this->params['tag_id'])) {
|
||||
$postIds = Db::name('community_post_tag')
|
||||
->where('tag_id', $this->params['tag_id'])
|
||||
->column('post_id');
|
||||
if ($postIds) {
|
||||
$where[] = ['id', 'in', $postIds];
|
||||
} else {
|
||||
$where[] = ['id', '=', 0];
|
||||
}
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
|
||||
private function isLiuhePost(array $tags, array $ext = []): bool
|
||||
{
|
||||
foreach (self::LIUHE_TAGS as $tag) {
|
||||
if (in_array($tag, $tags, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$lotteryKey = (string) ($ext['lottery_key'] ?? '');
|
||||
return in_array($lotteryKey, ['a6', 'xa6'], true);
|
||||
}
|
||||
|
||||
private function getLiuheAnalysisContent(array $ext): string
|
||||
{
|
||||
if (($ext['lottery_analysis_source'] ?? '') !== 'image_only') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (string) ($ext['lottery_analysis_content'] ?? '');
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$list = $this->buildQuery()
|
||||
->field('id,origin_id,user_id,content,images,ext,post_type,match_id,is_paid,price_points,paid_count,view_count,like_count,comment_count,share_count,is_top,is_hot,is_recommend,create_time')
|
||||
->orderRaw('is_top DESC, is_hot DESC, create_time DESC')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
// 批量预加载:用户、标签、翻译状态
|
||||
$postIds = array_column($list, 'id');
|
||||
$userIds = array_unique(array_column($list, 'user_id'));
|
||||
|
||||
// 批量查询用户 → id 为 key
|
||||
$userMap = [];
|
||||
if ($userIds) {
|
||||
$users = User::field('id,sn,nickname,avatar,sex')->whereIn('id', $userIds)->select()->toArray();
|
||||
foreach ($users as $u) {
|
||||
$userMap[$u['id']] = $u;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量查询帖子标签 → post_id => [tag_name, ...]
|
||||
$tagMap = [];
|
||||
if ($postIds) {
|
||||
$postTags = Db::name('community_post_tag')->whereIn('post_id', $postIds)->select()->toArray();
|
||||
$tagIdsByPost = [];
|
||||
foreach ($postTags as $pt) {
|
||||
$tagIdsByPost[$pt['post_id']][] = $pt['tag_id'];
|
||||
}
|
||||
$allTagIds = array_unique(array_column($postTags, 'tag_id'));
|
||||
$tagNames = $allTagIds ? CommunityTag::whereIn('id', $allTagIds)->column('name', 'id') : [];
|
||||
foreach ($tagIdsByPost as $pid => $tids) {
|
||||
$tagMap[$pid] = array_values(array_intersect_key($tagNames, array_flip($tids)));
|
||||
}
|
||||
}
|
||||
|
||||
// 已付费翻译的帖子ID集合(带缓存)
|
||||
$translatedPostIds = [];
|
||||
if ($this->userId) {
|
||||
$translatedPostIds = self::getUserTranslatedPostIds($this->userId);
|
||||
}
|
||||
|
||||
// 批量查询已购买的付费帖子ID
|
||||
$purchasedPostIds = [];
|
||||
if ($this->userId && $postIds) {
|
||||
$purchasedPostIds = Db::name('user_account_log')
|
||||
->where('user_id', $this->userId)
|
||||
->where('change_type', AccountLogEnum::UP_DEC_PURCHASE_POST)
|
||||
->whereIn('relation_id', $postIds)
|
||||
->column('relation_id');
|
||||
}
|
||||
|
||||
// VIP权益:解锁帖子免费、翻译免费
|
||||
$vipUnlockFree = $this->userId ? VipService::hasUnlockFree($this->userId) : false;
|
||||
$vipTranslateFree = $this->userId ? VipService::hasTranslateFree($this->userId) : false;
|
||||
|
||||
foreach ($list as &$item) {
|
||||
$ext = $item['ext'] ?? '';
|
||||
$ext = $ext ? (is_string($ext) ? json_decode($ext, true) : $ext) : [];
|
||||
|
||||
// 判断是否已解锁(自己发的 或 已购买 或 VIP解锁免费)
|
||||
$item['is_unlocked'] = 0;
|
||||
if ($item['is_paid']) {
|
||||
if ($item['user_id'] == $this->userId || in_array($item['id'], $purchasedPostIds) || $vipUnlockFree) {
|
||||
$item['is_unlocked'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 付费帖子:未解锁 → 截断内容并隐藏全文
|
||||
if ($item['is_paid'] && !$item['is_unlocked']) {
|
||||
$item['content_short'] = mb_substr($item['content'], 0, 20) . '...';
|
||||
$item['content'] = $item['content_short'];
|
||||
} elseif (mb_strlen($item['content']) > 120) {
|
||||
$item['content_short'] = mb_substr($item['content'], 0, 120) . '...';
|
||||
} else {
|
||||
$item['content_short'] = $item['content'];
|
||||
}
|
||||
|
||||
$item['user'] = $userMap[$item['user_id']] ?? null;
|
||||
$item['tags'] = $tagMap[$item['id']] ?? [];
|
||||
$item['source_url'] = $ext['url'] ?? '';
|
||||
$item['is_liked'] = false;
|
||||
if ($this->userId) {
|
||||
$item['is_liked'] = CommunityLike::where([
|
||||
'user_id' => $this->userId,
|
||||
'target_id' => $item['id'],
|
||||
'target_type' => 1
|
||||
])->count() > 0;
|
||||
}
|
||||
|
||||
$item['translated_content'] = '';
|
||||
$isTrumpPost = in_array('特朗普', $item['tags']);
|
||||
$isLiuhePost = $this->isLiuhePost($item['tags'], $ext);
|
||||
if ($isTrumpPost) {
|
||||
if (empty($ext['translated_content']) && !empty($item['content'])) {
|
||||
$result = AiService::translateCommunityPost($item['content']);
|
||||
if (!empty($result['success']) && !empty($result['content'])) {
|
||||
$ext['translated_content'] = trim($result['content']);
|
||||
CommunityPost::where('id', $item['id'])->update([
|
||||
'ext' => json_encode($ext, JSON_UNESCAPED_UNICODE),
|
||||
'update_time' => time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
$item['translated_content'] = $ext['translated_content'] ?? '';
|
||||
} elseif ((!empty($item['origin_id']) || $isLiuhePost) && (in_array($item['id'], $translatedPostIds) || $vipTranslateFree)) {
|
||||
$item['translated_content'] = $isLiuhePost
|
||||
? $this->getLiuheAnalysisContent($ext)
|
||||
: (string) ($ext['translated_content'] ?? '');
|
||||
}
|
||||
unset($item['ext']);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->buildQuery()->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户已付费翻译的帖子ID集合(优先缓存)
|
||||
*/
|
||||
public static function getUserTranslatedPostIds(int $userId): array
|
||||
{
|
||||
$cacheKey = 'translate_paid:' . $userId;
|
||||
$postIds = Cache::get($cacheKey);
|
||||
if ($postIds !== null) {
|
||||
return $postIds;
|
||||
}
|
||||
|
||||
$remarks = Db::name('user_account_log')
|
||||
->where('user_id', $userId)
|
||||
->where('change_type', AccountLogEnum::UP_DEC_TRANSLATE_POST)
|
||||
->column('remark');
|
||||
|
||||
$postIds = [];
|
||||
foreach ($remarks as $remark) {
|
||||
if (preg_match('/(?:翻译|分析)帖子#(\d+)/', $remark, $m)) {
|
||||
$postIds[] = (int) $m[1];
|
||||
}
|
||||
}
|
||||
|
||||
Cache::set($cacheKey, $postIds, 3600);
|
||||
return $postIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译扣分后刷新缓存:追加新帖子ID
|
||||
*/
|
||||
public static function refreshTranslateCache(int $userId, int $postId): void
|
||||
{
|
||||
$cacheKey = 'translate_paid:' . $userId;
|
||||
$postIds = Cache::get($cacheKey);
|
||||
if (is_array($postIds)) {
|
||||
if (!in_array($postId, $postIds)) {
|
||||
$postIds[] = $postId;
|
||||
Cache::set($cacheKey, $postIds, 3600);
|
||||
}
|
||||
} else {
|
||||
Cache::delete($cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user