<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */


namespace app\api\logic;

use app\common\enum\ArticleEnum;
use app\common\enum\DefaultEnum;
use app\common\enum\NoticeEnum;
use app\common\enum\PayEnum;
use app\common\logic\BaseLogic;
use app\common\model\Article;
use app\common\model\Topic;
use app\common\model\TopicArticle;
use app\common\model\ArticleOrder;
use app\common\model\ArticleComment;
use app\common\model\ArticleDraft;
use app\common\model\ArticleVisit;
use app\common\model\UserCollect;
use app\common\model\UserFollow;
use app\common\service\ConfigService;
use app\common\service\FileService;
use KubAT\PhpSimple\HtmlDomParser;
use app\common\service\security\Driver as SecurityDriver;

use think\facade\Log;

class ArticleLogic extends BaseLogic
{
    /**
     * @notes 获取帖子详情
     * @param $params
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function detail($params,$userId = 0)
    {

        // 增加浏览记录
        self::visit($params['id'],$userId);
        $with = ['vipLevel'];
        if(isPluginInstalled('chatgroup')){
            $with[]='chatGroup';
        }
        $article = Article::with($with)
        ->find($params['id']);

        if(!$article){
            throw new \Exception('找不到内容或已删除');
        }
        $vipLevel = $article->vipLevel;
        // dd($vipLevel->toArray());

        $user = \app\common\model\User::with('vipInfo')->find($userId);
        if($vipLevel){
           
            // 判断vip是否到期
            if($user->vip_expire_time < time()){
                throw new \Exception('没有vip或到期');
            };
            // 判断我是否有vip权限
            if($user->vipInfo->rank < $vipLevel->rank){
                throw new \Exception('vip等级不够');
            };
        }

        // 增加浏览量
        $article->visit = $article->visit + 1;
        $article->save();
        
        $with = ['vote','circle','subCategory','user' => function($query){
            $query->with('user_level');
        }];
        if(isActivePluginByPluginName('shop')){
            $with[]='goods';
        }
        $data = Article::with($with)->append(['comment_num' ,'collect_num' ,'zan_num'])->find($params['id'])->toArray();

        // 查询地区
        if(!empty($data['region_ids'])){
            $region_ids_arr = explode(',',$data['region_ids']);
            // dd($region_ids_arr);
            $data ['region_info']=\app\common\model\Region::where('id','in',$region_ids_arr)->select()->toArray();
        }
        
        $data['vote_target']=0;

        $data['create_time'] = formatTime($data['create_time']);
       

        $data['video_cover'] = $data['video_cover'] ? FileService::getFileUrl($data['video_cover']) : '';
        $data['video']       = $data['video'] ? FileService::getFileUrl($data['video']) : '';

        // 查询出@的好友用户信息
        if(!empty($data['user_ids'])){
            $user_ids_arr = explode(',',$data['user_ids']);
            foreach($user_ids_arr as $v){
                $data['users'][] = \app\common\model\User::field('id,nickname,avatar')->find($v);
            }
        }

        if($data['only_look_user_ids'] || $data['disable_look_user_ids'] || $data['only_look_user_level'] || $data['only_look_follow']){
            if(!$user){
                throw new \think\Exception('此内容需要登录后可见');
            }
        };

        $not_money=[
            'house',
            'hire',
        ];
        
        if($userId) {
            

            // 阅读权限
            if($article->user_id != $userId){
                // 仅用户可见
                if($data['only_look_user_ids']){
                    $user_ids_arr = explode(',',$data['only_look_user_ids']);
                    if(!in_array($userId,$user_ids_arr)){
                        throw new \think\Exception('此内容仅指定用户可见');
                    }
                }

                // 不给哪些用户看
                if($data['disable_look_user_ids']){
                    $user_ids_arr = explode(',',$data['disable_look_user_ids']);
                    if(in_array($userId,$user_ids_arr)){
                        throw new \think\Exception('别想了，您无权查看此内容');
                    }
                }

                // 仅达到等级后可见
                if($data['only_look_user_level'] && $user['level'] < $data['only_look_user_level']){
                    throw new \think\Exception('您等级太低了，不能查看此内容');
                }

                // 仅关注可见
                if($data['only_look_follow']){
                    // dd($article->user_id);
                    $user_ids_arr = \app\common\model\UserFollow::where('follow_user_id',$article->user_id)
                    ->select()
                    ->column('user_id');
                    if(!in_array($userId,$user_ids_arr)){
                        throw new \think\Exception('关注作者后可访问');
                    }
                }

                // 回复可见指定内容
                if(!empty($data['reply_visible_content'])){
                    $count = \app\common\model\ArticleComment::where('user_id',$userId)->count();
                    if($count<=0){
                        $data['reply_visible_content']='回复后可见';
                    }
                }
            }

            if(!empty($data['vote'])){
                foreach($data['vote'] as &$v){
                    foreach($v['options'] as &$o){
                        $res=\app\common\model\VoteLog::where([
                            ['user_id','=',$userId],
                            ['vote_options_id','=',$o['id']],
                        ])->find();
                         if($res){
                            $o['is_select']=1;
                        }else{
                            $o['is_select']=0;
                        }
                    } 
                }
            }
            
            //是否点赞过
            $isAan = UserCollect::where([ 'type' => 2, 'aid' => $data['id'], 'user_id' => $userId])->value('id');
            $data['is_zan'] = $isAan ? 1 : 0;


            //是否收藏过
            $isCollect = UserCollect::where([ 'type' => 1, 'aid' => $data['id'], 'user_id' => $userId])->value('id');
            $data['is_collect'] = $isCollect ? 1 : 0;

            //是否关注过改帖子用户
            $isFollow = UserFollow::where([ 'follow_user_id' => $data['user_id'], 'user_id' => $userId])->value('id');
            $data['is_follow'] = $isFollow ? 1 : 0;

            // 'file'  => $params['file'] ?? '',//附件
            // 'cloud_url'  => $params['cloud_url'] ?? '',//网盘url
            // 'cloud_password'  => $params['cloud_password'] ?? '',
            // 'free_image_count'  => $params['free_image_count'] ?? 0,
            // 'free_vip'  => $params['free_vip'] ?? 0,
            // 'free_word_count'  => $params['free_word_count'] ?? 0,
            // 'free_video_time'  => $params['free_video_time'] ?? 0,

            // 判断是否付费内容 并且部分模板不需要付费
            if( $data['pay_money']  > 0){

                // if(isset($data['circle']['template']) && !in_array($data['circle']['template'],$not_money))
               
                // 判断是否会员免费
                if($data['free_vip']==1 && $user->vip_expire_time > time() || $article->user_id == $userId){
                    // 会员免费
                    // todo。。。j计算分成给发布者
                }else{
                    // 判断该用户是否已经付费 
                    $order = ArticleOrder::where([ 'pay_status' => PayEnum::ISPAID, 'article_id' => $data['id'], 'user_id' => $userId])->count();
                    if( !$order){

                        if(isset($data['circle']['template']) && in_array($data['circle']['template'],$not_money)){
                            // 部分模板免截取
                        }else{
                            // dd(2);
                            // 截取部分内容
                            // $data['content']= substr(ArticleLogic::cuttingPayContent($data['content']),0,$data['free_word_count']);
                            $data['content']= substr($data['content'],0,$data['free_word_count']);
                            $data['image'] = isset($data['image'][0])&&$data['free_image_count']>0?array_slice($data['image'],0,$data['free_image_count']):[];
                        }
                        
                        
                        $data['is_pay'] = 0;
                        // $data['video'] = '';
                        $data['file'] = '';
                        $data['cloud_url'] = '';
                        $data['cloud_password'] = '';
                    } else {
                        $data['is_pay'] = 1;
                    }
                }
                
                
            }
        } elseif(isset($data['circle']['template']) && !in_array($data['circle']['template'],$not_money)) {

            // 判断是否付费内容 ，阅读权限
            // !$data['only_look_user_ids'] || !$data['disable_look_user_ids'] || !$data['only_look_user_level'] || !$data['only_look_follow']
            if( $data['pay_money']  > 0  || !empty($data['only_look_user_ids']) || !empty($data['disable_look_user_ids']) || !empty($data['only_look_user_level']) || !empty($data['only_look_follow'])){
                $data['is_pay'] = 0;
                // 截取部分内容
                $data['content']= ArticleLogic::cuttingPayContent($data['content']);
                $data['title'] = '请登录后阅读更多内容...';
                $data['image'] = [];
                $data['file'] = '';
                $data['cloud_url'] = '';
                $data['cloud_password'] = '';
            }

            if(!empty($data['reply_visible_content'])){
                $data['reply_visible_content']='回复后可见';
            }

        }

        $data['topic'] = \app\common\model\Topic::where('id','in',$data['topic_ids'])->select()->toArray();

        // 帖子字段
        if(isActivePluginByPluginName('field')){
            $data['field'] = \think\facade\Db::table(config('database.connections.mysql.prefix').'article_field')
            ->where('article_id',$data['id'])
            ->alias('a')
            ->join('circle_field c', 'a.field_id = c.id')
            ->field('a.value as article_value,a.*, c.*')
            ->select()
            ->toArray();
        }

        return $data;

    }

    /**
     * @notes 发布新帖子
     * @param $params
     */
    public static function add($params,$userId)
    {
        $content = $params['content'];
        // 解析 是否有 #话题
        $topic_id = 0;
        $images   = [];
        $userIds = [];
        $topicIds= [];
        if(isset($params['image']) && !empty($params['image']) ){
            foreach($params['image'] as $img){
                $images[] = FileService::setFileUrl($img);
            }

            $limit_image = \app\common\service\ConfigService::get('article','max_image',0);

            if(count($params['image'])>$limit_image){
                throw new \think\Exception('图片最多上传'.$limit_image.'张');
            }
        }

        // 发帖需要付费判断
        $release_pay = 2;//无需支付
        if(isset($params['circle_id'])){
            $circle = \app\common\model\Circle::find($params['circle_id'])->toArray();

            // 圈子发帖次数限制
            if($circle['send_limit_day'] >0){
                $send_circle_count = \app\common\model\Article::where([
                    ['user_id','=',$userId],
                    ['circle_id','=',$circle['id']],
                    ['create_time','>',time() - 60*60*24]
                ])->count();
                if($send_circle_count > $circle['send_limit_day']){
                    throw new \think\Exception('当前圈子每天只可发布'.$circle['send_limit_day'].'次，请明天再来');
                }
            }
            
            if($circle['release_price'] > 0){
                $release_pay = 0;
            };

        }

        if(isset($params['topic']) && !empty($params['topic'])  && isset($params['topic'][0]) ){
            foreach($params['topic'] as $val){
                if( $val['id'] == 0){
                    $topic = Topic::insertGetId([
                        'name' => $val['name']
                    ]);
                    $topicIds[] = $topic;
                }else{
                    $topicIds[] = $val['id'];
                }
            }
        }
        
        // 判断是否有 @ 人员 或者 #话题参数
        // if(isset($content['delta']) &&  isset($content['delta']['ops']) ){
        //     $ops = $content['delta']['ops'];
        //     foreach( $ops as $op){
        //         if( !isset($op['attributes'] )  || !isset($op['attributes']['link'] ) ){
        //             continue;
        //         }
        //         if( !isset($op['insert'] ) ){
        //             continue;
        //         }
        //         if( strpos($op['insert'] ,'@')  === 0  ){
        //             $userIds[] = $op['attributes']['link'] ;
        //         } elseif(  strpos($op['insert'] ,'#') === 0 ){
        //         }
        //     }
        // }

        // @用户
        $user_ids = '';
        if(isset($params['user_ids'])){
            $user_ids = implode(',',$params['user_ids']);
        };

        // 选择了地区库
        $region_ids = '';
        if(isset($params['region_ids']) && is_array($params['region_ids'])){
            $region_ids = implode(',',$params['region_ids']);
            $region_ids = ','.$region_ids.',';
        };



        $config = [
            'is_open' => ConfigService::get('security', 'is_open', 0),
            'default' => ConfigService::get('security', 'default'),
            'engine'  => ConfigService::get('security'),
        ];  

        // $status = ArticleEnum::STATUS_ERROR;
        $status = 0;//待审核
        if(ConfigService::get('article', 'send_examine',0) == 0){//不需要审核
            $status = 1;
        };
        // if( $config['is_open'] ){
        //     $SecurityDriver = new SecurityDriver($config);
        //     // 审核全部
        //     if (!$SecurityDriver->all([
        //         'text' => $content['html'],
        //         'img'  => $images
        //     ])) {
        //         throw new \Exception("内容审核失败:存在非法内容" . $SecurityDriver->getError());
        //     }
        //     $status = ArticleEnum::STATUS_SUCCESS;
        // }

        $ip = $_SERVER['REMOTE_ADDR'];
        $ip_address = '';
        try {
            // 初始化，指定QQWry.dat文件路径
            $qqwry = new \app\common\service\QQWry('qqwry.dat');
            // 获取客户端IP
            $ip = $_SERVER['REMOTE_ADDR'];
            // 查询IP地理位置
            $location = $qqwry->getLocation($ip);
            $ip_address = $location['country'];
            
        } catch (\Exception $e) {
            echo "发生错误: " . $e->getMessage();
        }

        $pinyin = new \Overtrue\Pinyin\Pinyin();



        
        $data = [
            'ip'=>$ip,
            'ip_address'=>$ip_address,
            'user_id'  => $userId,
            'image'    => count($images)? implode(",",$images):'',
            // 'title'    => $params['title'] || !empty($params['title']) ? $params['title'] : mb_substr($params['content']['text'],0,6,'UTF8'),
            'title'    => $params['title']??'',
            'content'  => $content['text'] ?? '',
            'goods_id' => $params['goods_id'] ?? '',
            'price' => $params['price'] ?? 0,
            'sort'     => $params['sort'] ?? DefaultEnum::SORT,
            'status'   => $status,
            'region'   => $params['region'] ?? '',
            'video'    => isset($params['video']) ? $params['video'] : '',
            'video_cover' => isset($params['videoTmp'])  ? FileService::setFileUrl($params['videoTmp']) : '',
            'pay_money'   => isset($params['pay_money']) ? $params['pay_money'] : 0,
            'topic_ids'   => implode(",",$topicIds),
            // 'user_ids'    => implode(",",$userIds),
            'user_ids'=>$user_ids,
            'circle_id'   => isset($params['circle_id']) && isset($params['circle_id'])  ? $params['circle_id'] :0 ,
            'sub_category_id'   => isset($params['sub_category_id']) && isset($params['sub_category_id'])  ? $params['sub_category_id'] :0 ,
            'is_open'     => intval($params['is_open']) ?? 1 ,
            'create_time' => time(),
            'type'        => isset($params['video'])  && $params['video'] ? ArticleEnum::TYPE_VIDEO : ArticleEnum::TYPE_ARTICLE,
            'release_pay' =>$release_pay,
            'file'  => $params['file'] ?? '',//附件
            'cloud_url'  => $params['cloud_url'] ?? '',//网盘url
            'cloud_password'  => $params['cloud_password'] ?? '',
            'free_image_count'  => $params['free_image_count'] ?? 0,
            'free_vip'  => $params['free_vip'] ?? 0,
            'free_word_count'  => $params['free_word_count'] ?? 0,
            'free_video_time'  => $params['free_video_time'] ?? 0,
            'mp3'  => $params['mp3'] ?? '',
            'chat_group_id'  => $params['chat_group_id'] ?? '',

            'city'  =>isset($params['city'])  ? $params['city']  : '',
            'province'  => isset($params['province'])  ? $params['province']  : '',
            'area'  => isset($params['area'])  ? $params['area']  : '',
            'city_json'  => isset($params['city_json'])  ? \json_encode($params['city_json'])  : '',
            'latitude'    => isset($params['latitude'])  ? $params['latitude']  : '',
            'longitude'   => isset($params['longitude']) ? $params['longitude'] : '',

            'label'  => isset($params['label']) ? $params['label'] : '',

            'only_look_user_ids'  => isset($params['only_look_user_ids']) ? $params['only_look_user_ids'] : '',
            'disable_look_user_ids'  => isset($params['disable_look_user_ids']) ? $params['disable_look_user_ids'] : '',
            'only_look_user_level'  => isset($params['only_look_user_level']) ? $params['only_look_user_level'] : '',
            'only_look_follow'  => isset($params['only_look_follow']) ? $params['only_look_follow'] : 0,

            'terminal' => isset($params['terminal']) ? $params['terminal'] : 0,

            'reply_only_visible_author' => isset($params['reply_only_visible_author']) ? $params['reply_only_visible_author'] : 0,

            'region_ids'=>$region_ids,

            'contact_name'=>isset($params['contact_name'])?$params['contact_name']:'',
            'contact_phone'=>isset($params['contact_phone'])?$params['contact_phone']:'',

            'contact_wechat'=>isset($params['contact_wechat'])?$params['contact_wechat']:'',

        ];

        // 领取红包的条件
        // if(isset($params['red'])){
        //     $data['red_open_method']=$params['red']['red_open_method'];
        //     if(isset($params['red']['red_read_time'])){
        //         $data['red_read_time']=$params['red']['red_read_time'];
        //     }
        // }
        
       if(isset($params['red'])){
            // 检查红包功能是否开启
            \app\api\logic\ArticleRedLogic::checkRedOpen();
            
            $data['red_open_method']=$params['red']['red_open_method'];
            if(isset($params['red']['red_read_time'])){
                $data['red_read_time']=$params['red']['red_read_time'];
            }
        }

        $data['title_pinyin']    = $pinyin->permalink( $data['title'],'');
        $data['content_pinyin']  = $pinyin->permalink($data['content'],'');
        
        \think\facade\Db::startTrans();
        try{

            // 添加文章
            $article = Article::create($data);
            // 如有投票添加投票
            if(isset($params['vote']) && !empty($params['vote'])){
                foreach($params['vote'] as $v){
                    // 添加帖子组
                    $vote = \app\common\model\Vote::create([
                        'article_id'=>$article->id,
                        'title'=>$v['title'],
                        'type'=>$v['type'],
                    ]);
                    
                    // 添加选项
                    $options = [];
                    foreach($v['options'] as $o){
                        $options[]=[
                            'vote_id'=>$vote->id,
                            'name'=>$o['name']
                        ];
                    }
                    \app\common\model\VoteOptions::insertAll($options);
                }
            }

            // @通知用户
            if(isset($params['user_ids'])){
                foreach($params['user_ids'] as $uid){
                    // @通知
                    event('Notice', [
                        'scene_id' => NoticeEnum::ARTICLE_COMMENT_NOTICE,
                        'params' => [
                            'user_id'    => $uid,  //通知谁
                            'article_id' => $article->id,//回复的帖子,
                            'fans_id'    => $userId,//评论者
                            'content'=>"对方@了您",
                            // 'content_id'    => $resData->id
                        ]
                    ]);
                }
            };

            //发对应的红包
            // if(isset($params['red'])){
            //     (new \app\api\controller\Trade())->article_send_red($article->id);
            // }
            

            // 参与话题
            if( $topicIds ){
                // 添加关联话题
                $topicDatas = [];
                foreach( $topicIds as $tid){
                    $val = [];
                    $val['a_id'] = $article->id;
                    $val['topic_id'] = $tid;
                    $val['create_time'] = time();
                    $topicDatas[] = $val;
                }
                TopicArticle::insertAll($topicDatas);
            }
            
            // 1. 增加经验值 (user_integral)
            $sendGetExperience = (int)ConfigService::get('article', 'send_get_experience_globle', 0);
            if ($sendGetExperience <= 0) {
                // 如果全局配置没拿到底，尝试拿 article 分组下的另一个配置
                $sendGetExperience = (int)ConfigService::get('article', 'send_get_experience', 0);
            }

            if ($sendGetExperience > 0) {
                \app\common\model\User::where(['id' => $userId])->inc('user_integral', $sendGetExperience)->update();
                \think\facade\Log::record("ArticleAddIntegral - UserID:{$userId}, AddExperience:{$sendGetExperience}");
            }

            // 2. 增加金币 (user_money)
            $sendGetIntegral = (int)ConfigService::get('article', 'send_get_integral', 0);
            if ($sendGetIntegral > 0) {
                \app\common\model\User::where(['id' => $userId])->inc('user_money', $sendGetIntegral)->update();
                \think\facade\Log::record("ArticleAddMoney - UserID:{$userId}, AddMoney:{$sendGetIntegral}");
            }

            // 3. 根据最新的积分更新等级
            \app\common\logic\UserLogic::updateLevelByExperience($userId);

            // dd($params);
            // 有安装字段插件
            if(isset($params['field']) && !empty($params['field']) && isActivePluginByPluginName('field')){
                self::addField($article->id,$params['field']);
            }

            \think\facade\Db::commit();

            return $article;
        }catch(\Exception $e){
            \think\facade\Db::rollback();
            throw new \think\Exception($e->getMessage());
            // throw new \think\Exception('添加失败');
        }

        // $article = \think\facade\Db::transaction(function() use ($data,$params){
        //     // 添加文章
        //     $article = Article::create($data);
        //     // 如有投票添加投票
        //     if(isset($params['vote']) && !empty($params['vote'])){
        //         foreach($params['vote'] as $v){
        //             // 添加帖子组
        //             $vote = \app\common\model\Vote::create([
        //                 'article_id'=>$article->id,
        //                 'title'=>$v['title']
        //             ]);
                    
        //             // 添加选项
        //             $options = [];
        //             foreach($v['options'] as $o){
        //                 $options[]=[
        //                     'vote_id'=>$vote->id,
        //                     'name'=>$o['name']
        //                 ];
        //             }
        //             \app\common\model\VoteOptions::insertAll($options);
        //         }
        //     }
        //     return $article;
        // });
        
        // 参与话题
        if( $topicIds ){
            // 添加关联话题
            $topicDatas = [];
            foreach( $topicIds as $tid){
                $val = [];
                $val['a_id'] = $article->id;
                $val['topic_id'] = $tid;
                $val['create_time'] = time();
                $topicDatas[] = $val;
            }
            TopicArticle::insertAll($topicDatas);
        }

        return $article;
    }


        /**
     * @notes 修改帖子
     * @param $params
     */
    public static function update($params,$userId)
    {
        $content = $params['content'];
        // 解析 是否有 #话题
        $topic_id = 0;
        $images   = [];
        $userIds = [];
        $topicIds= [];
        if(isset($params['image']) && !empty($params['image']) ){
            foreach($params['image'] as $img){
                $images[] = FileService::setFileUrl($img);
            }
        }

        if(isset($params['topic']) && !empty($params['topic'])  && isset($params['topic'][0]) ){
            foreach($params['topic'] as $val){
                if( $val['id'] == 0){
                    $topic = Topic::insertGetId([
                        'name' => $val['name']
                    ]);
                    $topicIds[] = $topic;
                }else{
                    $topicIds[] = $val['id'];
                }
            }
        }
        
        // 判断是否有 @ 人员 或者 #话题参数
        // if(isset($content['delta']) &&  isset($content['delta']['ops']) ){
        //     $ops = $content['delta']['ops'];
        //     foreach( $ops as $op){
        //         if( !isset($op['attributes'] )  || !isset($op['attributes']['link'] ) ){
        //             continue;
        //         }
        //         if( !isset($op['insert'] ) ){
        //             continue;
        //         }
        //         if( strpos($op['insert'] ,'@')  === 0  ){
        //             $userIds[] = $op['attributes']['link'] ;
        //         } elseif(  strpos($op['insert'] ,'#') === 0 ){

        //         }
        //     }
        // }
        $config = [
            'is_open' => ConfigService::get('security', 'is_open', 0),
            'default' => ConfigService::get('security', 'default'),
            'engine'  => ConfigService::get('security'),
        ];  

        $status = 0;//待审核
        if(ConfigService::get('article', 'send_examine',0) == 0){//不需要审核
            $status = 1;
        };

        $ip = $_SERVER['REMOTE_ADDR'];
        $ip_address = '';
        try {
            // 初始化，指定QQWry.dat文件路径
            $qqwry = new \app\common\service\QQWry('qqwry.dat');
            // 获取客户端IP
            $ip = $_SERVER['REMOTE_ADDR'];
            // 查询IP地理位置
            $location = $qqwry->getLocation($ip);
            $ip_address = $location['country'];
            
        } catch (\Exception $e) {
            echo "发生错误: " . $e->getMessage();
        }
        

        $pinyin = new \Overtrue\Pinyin\Pinyin();
        // dd($params['city_json']);
        $data = [
            'ip'=>$ip,
            'ip_address'=>$ip_address,
            'user_id'  => $userId,
            'image'    => count($images)? implode(",",$images):'',
            // 'title'    => $params['title'] || !empty($params['title']) ? $params['title'] : mb_substr($params['content']['text'],0,6,'UTF8'),
            'title'    =>isset($params['title'])?$params['title']:'',
            // 'content'  => $content['text'] ?? '',
            'content'  => $params['content']['text'] ?? '',
            'goods_id' => $params['goods_id'] ?? '',
            // 'price' => $params['price'] ?? 0,
            'sort'     => $params['sort'] ?? DefaultEnum::SORT,
            'status'   => $status,
            'region'   => $params['region'] ?? '',
            'video'    => isset($params['video']) ? $params['video'] : '',
            'video_cover' => isset($params['videoTmp'])  ? FileService::setFileUrl($params['videoTmp']) : '',
            // 'pay_money'   => isset($params['pay_money']) ? $params['pay_money'] : 0,
            'pay_money'   => isset($params['pay_money']) ? $params['pay_money'] : 0,
            'topic_ids'   => implode(",",$topicIds),
            'user_ids'    => implode(",",$userIds),
            // 'circle_id'   => isset($params['circle_id']) && isset($params['circle_id'])  ? $params['circle_id'] :0 ,
            // 'sub_category_id'   => isset($params['sub_category_id']) && isset($params['sub_category_id'])  ? $params['sub_category_id'] :0 ,
            'is_open'     => $params['is_open'] ?? ArticleEnum::OPEN ,
            'create_time' => time(),
            'type'        => isset($params['video'])  && $params['video'] ? ArticleEnum::TYPE_VIDEO : ArticleEnum::TYPE_ARTICLE,
            // 'release_pay' =>$release_pay,
            'file'  => $params['file'] ?? '',//附件
            'cloud_url'  => $params['cloud_url'] ?? '',//网盘url
            'cloud_password'  => $params['cloud_password'] ?? '',
            'free_image_count'  => $params['free_image_count'] ?? 0,
            'free_vip'  => $params['free_vip'] ?? 0,
            'free_word_count'  => $params['free_word_count'] ?? 0,
            'free_video_time'  => $params['free_video_time'] ?? 0,
            'mp3'  => $params['mp3'] ?? '',
            'chat_group_id'  => $params['chat_group_id'] ?? '',

            'city'  =>isset($params['city'])  ? $params['city']  : '',
            'province'  => isset($params['province'])  ? $params['province']  : '',
            'area'  => isset($params['area'])  ? $params['area']  : '',
            'city_json'  => isset($params['city_json'])  ? $params['city_json']  : '{}',
            'latitude'    => isset($params['latitude'])  ? $params['latitude']  : '',
            'longitude'   => isset($params['longitude']) ? $params['longitude'] : '',

            'label'  => isset($params['label']) ? $params['label'] : '',

            'reply_only_visible_author' => isset($params['reply_only_visible_author']) ? $params['reply_only_visible_author'] : 0,

            
            'contact_name'=>isset($params['contact_name'])?$params['contact_name']:'',
            'contact_phone'=>isset($params['contact_phone'])?$params['contact_phone']:'',
            'contact_wechat'=>isset($params['contact_wechat'])?$params['contact_wechat']:'',

        ];

        $data['title_pinyin']    = $pinyin->permalink($data['title'],'');
        $data['content_pinyin']  = $pinyin->permalink($data['content'],'');

        \think\facade\Db::startTrans();
        try{

            // 修改文章
            $article = Article::where('id',$params['id'])->update($data);

            // 如有投票修改投票内容
            if(isset($params['vote']) && !empty($params['vote'])){
                foreach($params['vote'] as $v){
                    // 修改投票
                    \app\common\model\Vote::where('id',$v['id'])->update([
                        'title'=>$v['title'],
                        'type'=>$v['type'],
                        'article_id'=>$params['id'],
                    ]);
                    foreach($v['options'] as $v2){
                        // 修改投票选项
                        \app\common\model\VoteOptions::where('id',$v2['id'])->update([
                            'name'=>$v2['name']
                        ]);
                    }
                }
            }

            // // 添加帖子组
            // $vote = \app\common\model\Vote::create([
            //     'article_id'=>$article->id,
            //     'title'=>$v['title']
            // ]);
            
            // // 添加选项
            // $options = [];
            // foreach($v['options'] as $o){
            //     $options[]=[
            //         'vote_id'=>$vote->id,
            //         'name'=>$o['name']
            //     ];
            // }
            // \app\common\model\VoteOptions::insertAll($options);

            // 参与话题
            // if($topicIds ){
            //     // 添加关联话题
            //     $topicDatas = [];
            //     foreach( $topicIds as $tid){
            //         $val = [];
            //         $val['a_id'] = $article->id;
            //         $val['topic_id'] = $tid;
            //         $val['create_time'] = time();
            //         $topicDatas[] = $val;
            //     }
            //     TopicArticle::insertAll($topicDatas);
            // }

            // 有安装字段插件
            if(isset($params['field']) && !empty($params['field']) && isActivePluginByPluginName('field')){
                $search_field_values = '';
                foreach($params['field'] as $v){
                    // 修改字段
                    $field = \app\common\model\ArticleField::where('id',$v['article_field_id'])->find();
                    if($field){
                        $field->value = $v['article_value'];
                        $field->save();
                    }else{
                        throw new \think\Exception("字段id不存在");
                    }

                    // dd($field);
                    // 用于搜索的
                    if (empty(($search_field_values))) {
                        $search_field_values = ',' . $v['article_value'] . ',';
                    } else {
                        $search_field_values .= $v['article_value'] . ',';
                    }

                }

                 // 并存入article下field_values字段用于搜索
                \app\common\model\Article::update([
                    'field_values' => $search_field_values,
                ], ['id' => $params['id']]);

            }

            \think\facade\Db::commit();

            return $article;
        }catch(\Exception $e){
            \think\facade\Db::rollback();
            throw new \think\Exception($e->getMessage());
            // throw new \think\Exception('添加失败');
        }

        // $article = \think\facade\Db::transaction(function() use ($data,$params){
        //     // 添加文章
        //     $article = Article::create($data);
        //     // 如有投票添加投票
        //     if(isset($params['vote']) && !empty($params['vote'])){
        //         foreach($params['vote'] as $v){
        //             // 添加帖子组
        //             $vote = \app\common\model\Vote::create([
        //                 'article_id'=>$article->id,
        //                 'title'=>$v['title']
        //             ]);
                    
        //             // 添加选项
        //             $options = [];
        //             foreach($v['options'] as $o){
        //                 $options[]=[
        //                     'vote_id'=>$vote->id,
        //                     'name'=>$o['name']
        //                 ];
        //             }
        //             \app\common\model\VoteOptions::insertAll($options);
        //         }
        //     }
        //     return $article;
        // });
        


        
        // 参与话题
        // if( $topicIds ){
        //     // 添加关联话题
        //     $topicDatas = [];
        //     foreach( $topicIds as $tid){
        //         $val = [];
        //         $val['a_id'] = $article->id;
        //         $val['topic_id'] = $tid;
        //         $val['create_time'] = time();
        //         $topicDatas[] = $val;
        //     }
        //     TopicArticle::insertAll($topicDatas);
        // }

        // return $article;
    }

    /**
     * 添加字段
     */
    public static function addField($article_id,$field)
    {
        $search_field_values = '';
        foreach ($field as $v) {
            if(empty($v)){
                continue;
            }
            // 查询字段信息
            $field_data = \app\common\model\CircleField::find($v['field_id']);
            if(!$field_data){
                throw new \think\Exception("字段不存在");
            }
            if ($field_data->is_search == 1) {
                // 如果有 , 符合则转义转化
                if (empty(($search_field_values))) {
                    $search_field_values = ',' . $v['value'] . ',';
                } else {
                    $search_field_values .= $v['value'] . ',';
                }
            }
            $data[] = [
                'article_id' => $article_id,
                'field_id' => $v['field_id'],
                'value' => $v['value']
            ];
            
        }
        
        // dd(2);

        // 并存入article下field_values字段用于搜索
        \app\common\model\Article::update([
            'field_values' => $search_field_values,
        ], ['id' => $article_id]);
        // dd($data);
        // 给文章添加字段
        $res = \think\facade\Db::name('article_field')
            ->replace(true)
            ->insertAll($data);
    }


    

    /**
     * @notes  删除
     * @param $params
     */
    public static function delete($params ,$userId)
    {
        $where = [
            'id' => $params['id'],
            'user_id' => $userId
        ];
        $article = Article::where($where)->findOrEmpty();
        if($article->isEmpty()){
            return true;
        }

        Article::destroy(['user_id' => $userId, 'id' => $params['id']]);
    }


    /**
     * @notes 帖子置顶
     * @param $params
     */
    public static function handleTop($params , $userId = 0)
    {
        $where = [
            'id' => $params['id'],
            'user_id' => $userId
        ];
        $article = Article::where($where)->findOrEmpty();
        
        if($article->isEmpty()){
            return true;
        }

        // // 置顶时，当前用户其他置顶帖子 去掉,仅保留一个置顶
        // if( $params['is_top'] == 1){

        //     $where['is_top'] = 1;
        //     Article::update(['is_top' => 0],$where);
        // }

        $article->user_id = $userId;
        $article->is_top  = $params['is_top'];
        $article->save();

        

        return true;
    }

    /**
     * @notes 关注 取关帖子
     * @param $params
     */
    public static function handleArticleCollect($params , $userId = 0)
    {
        $where =[];
        $where['user_id'] = $userId;
        $where['type'] = $params['type'];
        $where['aid']  = $params['id'];
  
        if( $params['type'] == 3){
            $where['comments_id']  = $params['comments_id'];
        }
        
        //加入
        if($params['is_collect']){

            $collect = UserCollect::where($where)->findOrEmpty();
            if(!$collect->isEmpty()){
                return true;
            }
            $collect->user_id = $userId;
            $collect->aid  =  $params['id'];
            $collect->type =  $params['type'];
            $collect->comments_id = isset($params['comments_id']) ? $params['comments_id'] : 0;
            $collect->save();

            $postUserId = Article::where(['id' => $params['id']])->value('user_id');
            if( $postUserId  !=  $userId){
                // type=1 收藏 2=点赞
                // 消息通知
                event('Notice', [
                    'scene_id' => NoticeEnum::ARTICLE_COLLECT_NOTICE,
                    'params' => [
                        'user_id'    => $postUserId,  //帖子对应的发布者ID
                        'article_id' => $params['id'],   //回复的帖子,
                        'fans_id'    => $userId,
                        'content_id'    =>$collect->comments_id,
                        'type'=>$params['type'],
                    ]
                ]);
            }

            if( $params['type'] == 3){
                try{
                    \app\common\model\ArticleComment::where('id',$params['comments_id'])->inc('star_num',1)->update();

                    $comment = \app\common\model\ArticleComment::find($params['comments_id']);
                    $article = \app\common\model\Article::find($comment->aid);
                    if($article->user_id == $userId){
                        // 判断作者赞过 is_author_star
                        \app\common\model\ArticleComment::where('id',$params['comments_id'])->update(['is_author_star'=>1]);
                    }
                }catch(\Exception $e){}
            }

            return true;
        }

        if( $params['type'] == 3){
            try{
                \app\common\model\ArticleComment::where('id',$params['comments_id'])->dec('star_num',1)->update();

                $comment = \app\common\model\ArticleComment::find($params['comments_id']);
                $article = \app\common\model\Article::find($comment->aid);
                if($article->user_id == $userId){
                    // 判断作者赞过 is_author_star
                    \app\common\model\ArticleComment::where('id',$params['comments_id'])->update(['is_author_star'=>0]);
                }

            }catch(\Exception $e){
                
            }
        }

        
        //取消删除
        UserCollect::destroy($where);
        return true;
    }


    /**
     * 帖子回复评论
     */
    public static function commentsReply($params , int $userId = 0){

        $ip = $_SERVER['REMOTE_ADDR'];
        $ip_address = '';
        try {
            // 初始化，指定QQWry.dat文件路径
            $qqwry = new \app\common\service\QQWry('qqwry.dat');
            // 获取客户端IP
            $ip = $_SERVER['REMOTE_ADDR'];
            // 查询IP地理位置
            $location = $qqwry->getLocation($ip);
            $ip_address = $location['country'];
            
        } catch (\Exception $e) {
            echo "发生错误: " . $e->getMessage();
        }
        
        $content = $params['data'];
        $data = [
            'ip'=>$_SERVER['REMOTE_ADDR'],
            'ip_address'=>$ip_address,
            'aid'           => $params['article_id'],
            'pid'           => isset($params['pid'])  ? $params['pid'] : 0,
            'reply_user_id'           => isset($params['reply_user_id'])  ? $params['reply_user_id'] : 0,
            'user_id'       => $userId,
            'comment'       => $content['text'],
            'content'       => $content['html'],
            'status'        => 1,
            'topic_id'      => '',
            'msg_user_ids'  => isset($params['msg_user_ids'])?$params['msg_user_ids']:'',//@某某
            'goods_id'  => isset($params['goods_id'])?$params['msg_user_ids']:null,//自营商城商品id
        ];

        if($data['pid'] == 0){
            $floor = 1;

            $floor_res = \app\common\model\ArticleComment::where([
                ['aid','=',$data['aid']],
                ['user_id','=',$userId],
            ])->find();
            
            if($floor_res && $floor_res->floor){
                $floor = $floor_res->floor;
            }else{
                $floor_res = \app\common\model\ArticleComment::where([
                    ['aid','=',$data['aid']],
                ])
                ->order('floor','desc')
                ->find();

                if($floor_res && $floor_res->floor){
                    $floor+=$floor_res->floor;
                };
            }

            $data['floor'] = $floor;
        }

        
        
        $resData = ArticleComment::create($data);

        $postUserId = Article::where(['id' => $params['article_id']])->value('user_id');

        // 回复类型，通知被回复者
        $repy_user_id = 0;
        if(!empty($data['pid']) && $data['pid'] >0){
            $repy_user_id = ArticleComment::find($data['pid'])->user_id;
            // 回复某条评论，判断为回复类型
            event('Notice', [
                'scene_id' => NoticeEnum::ARTICLE_COMMENT_NOTICE,
                'params' => [
                    'user_id'    => $repy_user_id,  //帖子对应的发布者ID
                    'article_id' => $params['article_id'],   //回复的帖子,
                    'fans_id'    => $userId,//评论者
                    'content'=>$content['text'],
                    'content_id'    => $resData->id
                ]
            ]);
        };

        if(!empty($data['msg_user_ids'])){
            // @通知
            $user_ids_arr = explode(',',$data['msg_user_ids']);
            foreach($user_ids_arr as $v){
                event('Notice', [
                    'scene_id' => NoticeEnum::ARTICLE_COMMENT_NOTICE,
                    'params' => [
                        'user_id'    => $v,  //通知谁
                        'article_id' => $params['article_id'],//回复的帖子,
                        'fans_id'    => $userId,//评论者
                        'content'=>$content['text'],
                        'content_id'    => $resData->id
                    ]
                ]);
            }
        }

        // 通知发帖者，排除发帖者回复自己不通知自己
        if( $postUserId  !=  $userId){
            event('Notice', [
                'scene_id' => NoticeEnum::ARTICLE_COMMENT_NOTICE,
                'params' => [
                    'user_id'    => $postUserId,  //帖子对应的发布者ID
                    'article_id' => $params['article_id'],   //回复的帖子,
                    'fans_id'    => $userId,
                    'content'=>$content['text'],
                    'content_id'    => $resData->id
                ]
            ]);
        }
        

        return true;
    }



    /**
     * @notes 帖子浏览记录
     * @param $goodsId
     * @param $userId
     * @return bool
     */
    public static function visit($articleId, $userId)
    {
        if (empty($userId)) {
            $userId = 0;
        }
        $ip = request()->ip();

        // 一个帖子一个用户只生成一条记录
        $record = ArticleVisit::where([
            'ip' => $ip,
            'aid' => $articleId,
            'user_id' => $userId,
        ])
        ->whereDay('create_time')
        ->findOrEmpty();

        if (!$record->isEmpty()) {
            // 增加浏览量
            $record->visit += 1;
            $record->save();
            return true;
        }

        // 生成浏览记录
        ArticleVisit::create([
            'ip' => $ip,
            'aid' => $articleId,
            'user_id' => $userId,
            'visit' => 1
        ]);
    }


    /**
     * 添加帖子草稿
     */
    public static function addDraft($params,$userId)
    {
        $content = $params['content'];
        $images   = [];
        if( isset($params['image']) && !empty($params['image']) ){
            foreach($params['image'] as $img){
                $images[] = FileService::setFileUrl($img);
            }
        }
        $data = [
            'user_id'  => $userId,
            'image'    => count($images)? implode(",",$images):'',
            'title'    => $content['text'],
            'content'  => $content['html'] ?? '',
            'region'   => $params['region'] ?? '',
            'circle_id'   => isset($params['circle_id']) && isset($params['circle_id'])  ? $params['circle_id'] :0 ,
            'create_time' => time(),
        ];

        return ArticleDraft::create($data);
    }

     /**
     * @notes 获取帖子草稿详情
     * @param $params
     * @return array
     */
    public static function draftDetail($params,$userId = 0)
    {
        $data = ArticleDraft::find([
            'id' => $params['id'],
            'user_id' => $userId
        ])->toArray();

        return $data;
    }

    /**
     * @notes  删除草稿
     * @param $params
     */
    public static function delDraft($params ,$userId)
    {
        $where = [
            'id' => $params['id'],
            'user_id' => $userId
        ];
        $article = ArticleDraft::where($where)->findOrEmpty();
        if($article->isEmpty()){
            return true;
        }

        ArticleDraft::destroy(['user_id' => $userId, 'id' => $params['id']]);
    }

    /**
     * 获取付费帖 部分内容
     */
    public static function cuttingPayContent($content){

        // dd($content);die;
        $dom = new HtmlDomParser();
        $html = $dom->str_get_html($content);
        $excerpt = '';
        if($html){
            $paragraphs = $html->find('p');
            $limit = ceil(count($paragraphs) * 0.25) ;  //向上取整，防止获取不到
            foreach ($paragraphs as $index => $paragraph) {
                if ($index >= $limit) {
                    break;
                }
                $excerpt .= $paragraph->outertext; // 获取段落的 HTML
            }
        };
        

        return $excerpt;

    }


    /**
     * 添加付费订单
     */
    public static function articleOrder($params)
    {

        $article = Article::find($params['article_id']);

        $data = [
            'sn'            => generate_sn((new ArticleOrder()),'sn'),
            'terminal'      => $params['terminal'],
            'user_id'       => $params['user_id'],
            'pay_status'    => PayEnum::UNPAID,
            'pay_way'       => $params['pay_way'] ?? 2,
            'order_amount'  => $article['pay_money'],
            'article_id'    => $params['article_id'],
            'sell_user_id'    => $article['user_id'],
        ];

        $order = ArticleOrder::create($data);
        return [
            'order_id' => $order->id,
            'from' => 'article'
        ];

    }

    
    /**
     * @notes  删除评论
     * @param $params
     */
    public static function commentsDelete($params ,$userId)
    {
        $where = [
            'id' => $params['id'],
            'aid' => $params['aid'],
            'user_id' => $userId
        ];
        $article = ArticleComment::where($where)->findOrEmpty();
        if($article->isEmpty()){
            return true;
        }

        ArticleComment::destroy(['user_id' => $userId, 'id' => $params['id']]);
    }
    
}