no message

This commit is contained in:
hajimi
2026-06-11 12:15:29 +08:00
parent 10ebe39c30
commit 96efa1d905
5859 changed files with 815501 additions and 5 deletions
@@ -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);
}
}
}