feat: support full community post editing

This commit is contained in:
hajimi
2026-08-02 20:38:47 +08:00
parent f78580b2b9
commit 2358603eda
9 changed files with 638 additions and 72 deletions
@@ -5,11 +5,30 @@ namespace app\adminapi\validate\community;
use app\common\validate\BaseValidate;
use app\common\model\community\CommunityCategory;
use app\common\model\community\CommunityPost;
use app\common\model\community\CommunityTag;
use app\common\model\user\User;
use think\facade\Db;
class CommunityPostValidate extends BaseValidate
{
protected $rule = [
'id' => 'require|checkPost',
'origin_id' => 'max:100|checkOriginId',
'user_id' => 'require|integer|gt:0|checkUser|checkBody',
'content' => 'max:16000',
'images' => 'array|checkImages',
'post_type' => 'require|in:0,1,2',
'match_id' => 'require|integer|egt:0|checkMatch',
'tag_ids' => 'array|checkTags',
'is_paid' => 'require|in:0,1|checkPayment',
'price_points' => 'require|integer|egt:0|elt:10000',
'free_content_len' => 'require|integer|egt:0|elt:501|checkFreeContentLen',
'paid_count' => 'require|integer|egt:0|elt:4294967296',
'view_count' => 'require|integer|egt:0|elt:4294967296',
'like_count' => 'require|integer|egt:0|elt:4294967296',
'comment_count' => 'require|integer|egt:0|elt:4294967296',
'share_count' => 'require|integer|egt:0|elt:4294967296',
'ext' => 'checkExt',
'status' => 'require|in:0,1,2',
'is_top' => 'require|in:0,1',
'is_hot' => 'require|in:0,1',
@@ -17,14 +36,22 @@ class CommunityPostValidate extends BaseValidate
'sort' => 'require|integer|egt:0|elt:1000000',
'is_topic' => 'require|in:0,1',
'category_id' => 'require|integer|egt:0|checkCategory',
'content' => 'require|max:16000',
'create_time' => 'require|checkDateTime',
];
protected $message = [
'id.require' => '帖子id不能为空',
'status.require' => '状态不能为空',
'content.require' => '帖子内容不能为空',
'content.max' => '帖子内容不能超过16000个字符',
'origin_id.max' => '来源标识不能超过100个字符',
'user_id.require' => '用户ID不能为空',
'images.array' => '帖子图片格式错误',
'post_type.in' => '帖子类型错误',
'match_id.egt' => '赛事ID不能小于0',
'tag_ids.array' => '帖子标签格式错误',
'price_points.elt' => '积分价格范围为0~9999',
'free_content_len.elt' => '免费预览字数不能超过500',
'create_time.require' => '发布时间不能为空',
];
public function sceneDetail()
@@ -42,9 +69,15 @@ class CommunityPostValidate extends BaseValidate
return $this->only(['id', 'status']);
}
public function sceneEditContent()
public function sceneEdit()
{
return $this->only(['id', 'content']);
return $this->only([
'id', 'origin_id', 'user_id', 'content', 'images', 'post_type', 'category_id',
'match_id', 'tag_ids', 'is_paid', 'price_points', 'free_content_len',
'paid_count', 'view_count', 'like_count', 'comment_count', 'share_count',
'ext', 'is_top', 'is_hot', 'is_recommend', 'is_topic', 'sort', 'status',
'create_time',
]);
}
public function sceneTop()
@@ -86,14 +119,111 @@ class CommunityPostValidate extends BaseValidate
return true;
}
public function checkCategory($value)
public function checkOriginId($value, $rule, $data)
{
$originId = trim((string) $value);
if ($originId === '') {
return true;
}
$exists = Db::name('community_post')
->where('origin_id', $originId)
->where('id', '<>', (int) ($data['id'] ?? 0))
->count();
return $exists > 0 ? '来源标识已存在' : true;
}
public function checkUser($value)
{
return User::where('id', $value)->count() > 0 ? true : '用户不存在';
}
public function checkBody($value, $rule, $data)
{
if (trim((string) ($data['content'] ?? '')) === '' && empty($data['images'])) {
return '帖子内容和图片不能同时为空';
}
return true;
}
public function checkImages($value)
{
if (count($value) > 18) {
return '帖子图片最多18张';
}
foreach ($value as $image) {
if (!is_string($image) || trim($image) === '') {
return '帖子图片地址格式错误';
}
}
return true;
}
public function checkMatch($value)
{
if ((int) $value === 0) {
return true;
}
$category = CommunityCategory::where('id', $value)->where('status', 1)->findOrEmpty();
return Db::name('match')->where('id', $value)->count() > 0 ? true : '关联赛事不存在';
}
public function checkTags($value)
{
$tagIds = array_values(array_unique(array_map('intval', $value)));
if (count($tagIds) > 3) {
return '帖子标签最多选择3个';
}
if (!$tagIds) {
return true;
}
return CommunityTag::whereIn('id', $tagIds)->count() === count($tagIds)
? true
: '帖子标签不存在';
}
public function checkPayment($value, $rule, $data)
{
if ((int) $value === 1 && (int) ($data['price_points'] ?? 0) <= 0) {
return '付费帖子必须设置积分价格';
}
return true;
}
public function checkFreeContentLen($value, $rule, $data)
{
if ((int) ($data['is_paid'] ?? 0) === 1 && (int) $value < 20) {
return '付费帖子免费预览字数不能少于20';
}
return true;
}
public function checkExt($value)
{
if (is_array($value) || trim((string) $value) === '') {
return true;
}
json_decode((string) $value, true);
return json_last_error() === JSON_ERROR_NONE ? true : '扩展数据必须是有效的JSON';
}
public function checkDateTime($value)
{
return strtotime((string) $value) !== false ? true : '发布时间格式错误';
}
public function checkCategory($value, $rule, $data)
{
if ((int) $value === 0) {
return true;
}
$category = CommunityCategory::where('id', $value)->findOrEmpty();
if ($category->isEmpty()) {
return '帖子分类不存在或已禁用';
return '帖子分类不存在';
}
if ((int) $category->status !== 1) {
$currentCategoryId = (int) CommunityPost::where('id', $data['id'] ?? 0)->value('category_id');
if ($currentCategoryId !== (int) $value) {
return '帖子分类已禁用';
}
}
return true;
}