diff --git a/application/api/controller/Article.php b/application/api/controller/Article.php index 7b4207a..779061c 100644 --- a/application/api/controller/Article.php +++ b/application/api/controller/Article.php @@ -794,12 +794,34 @@ class Article extends Base $authors = $this->article_obj->field("t_article_author.*")->join("t_article_author", "t_article_author.article_id = t_article.article_id", "left") ->where("t_article.user_id", $data['user_id'])->where("t_article_author.state", 0) ->order("t_article_author.email,t_article_author.art_aut_id")->select(); + //查询作者机构 20251031 start $cache_author = []; - foreach ($authors as $k => $v) { - if (!isset($v['email']) || $v['email'] == "") { - continue; + if(!empty($authors)){ + //查询作者机构 + $aAutId = array_column($authors, 'art_aut_id'); + $aWhere = ['art_aut_id' => ['in',$aAutId],'state' => 0]; + $aAuthorOrganId = Db::name('article_author_organ')->field('art_aut_id,organ_id')->where($aWhere)->select(); + if(!empty($aAuthorOrganId)){ + //查询机构名称 + $aOragnId = array_unique(array_column($aAuthorOrganId, 'organ_id')); + $aWhere = ['state' => 0,'organ_id' => ['in',$aOragnId]]; + $aOragn = Db::name('article_organ')->where($aWhere)->column('organ_id,organ_name'); + $aAuthorOrgan = []; + foreach ($aAuthorOrganId as $key => $value) { + if(empty($aOragn[$value['organ_id']])){ + continue; + } + $aAuthorOrgan[$value['art_aut_id']][] = ['organ_id' => $value['organ_id'],'organ_name' => $aOragn[$value['organ_id']]]; + } + } + foreach ($authors as $key => $value) { + if (empty($value['email'])) { + continue; + } + $value['organ_id'] = empty($aAuthorOrgan[$value['art_aut_id']]) ? [] : array_column($aAuthorOrgan[$value['art_aut_id']], 'organ_id'); + $value['organ_name'] = empty($aAuthorOrgan[$value['art_aut_id']]) ? [] : array_column($aAuthorOrgan[$value['art_aut_id']], 'organ_name'); + $cache_author[$value['email']][] = $value; } - $cache_author[$v['email']][] = $v; } $authors = []; foreach ($cache_author as $k => $v) { @@ -828,6 +850,8 @@ class Article extends Base $c['address'] = $value['address']; } } + $c['organ_id'] = empty($value['organ_id']) ? [] : $value['organ_id']; + $c['organ_name'] = empty($value['organ_name']) ? [] : $value['organ_name']; $authors[] = $c; } $re['authors'] = $authors; @@ -861,27 +885,27 @@ class Article extends Base $c['email'] = $v['email']; $cl = $this->article_author_obj->where("email", $v['email'])->where('state', 0)->select(); foreach ($cl as $value) { - if ($value['firstname'] != "") { - $c['firstname'] = $value['firstname']; - } - if ($value['lastname'] != "") { - $c['lastname'] = $value['lastname']; - } - if ($value['company'] != "") { - $c['company'] = $value['company']; - } - if ($value['department'] != "") { - $c['department'] = $value['department']; - } - if ($value['author_title'] != "") { - $c['author_title'] = $value['author_title']; - } - if ($value['country'] != "") { - $c['country'] = $value['country']; - } - if ($value['address'] != "") { - $c['address'] = $value['address']; - } + // if ($value['firstname'] != "") { + $c['firstname'] = empty($value['firstname']) ? '' : $value['firstname']; + // } + // if ($value['lastname'] != "") { + $c['lastname'] = empty($value['lastname']) ? '' : $value['lastname']; + // } + // if ($value['company'] != "") { + $c['company'] = empty($value['company']) ? '' : $value['company']; + // } + // if ($value['department'] != "") { + $c['department'] = empty($value['department']) ? '' : $value['department']; + // } + // if ($value['author_title'] != "") { + $c['author_title'] = empty($value['author_title']) ? '' : $value['author_title']; + // } + // if ($value['country'] != "") { + $c['country'] = empty($value['country']) ? '' : $value['country']; + // } + // if ($value['address'] != "") { + $c['address'] = empty($value['address']) ? '' : $value['address']; + // } } $authors[] = $c; } @@ -2960,7 +2984,8 @@ class Article extends Base "email" => "require", "country" => "require", "isSuper" => "require", - "isReport" => "require" + "isReport" => "require", + 'organ' => "require" ]); if (!$rule->check($data)) { return jsonError($rule->getError()); @@ -2978,7 +3003,68 @@ class Article extends Base $insert['company'] = isset($data['company']) ? trim($data['company']) : ""; $insert['department'] = isset($data['department']) ? trim($data['department']) : ""; $insert['address'] = isset($data['address']) ? trim($data['address']) : ""; - $this->article_author_obj->insert($insert); + //新增修改orcid chengxiaoling 20251029 start + $insert['orcid'] = isset($data['orcid']) ? trim($data['orcid']) : ""; + //新增修改orcid chengxiaoling 20251029 end + + //处理作者绑定机构 chengxiaoling 251031 start + $aOrgrnId = empty($data['organ']) ? '' : $data['organ']; + if(!empty($aOrgrnId) && is_string($aOrgrnId)){ + $aOrgrnId = explode(',', $aOrgrnId); + } + Db::startTrans(); + $iId = $this->article_author_obj->insertGetId($insert); + if(empty($iId)){ + return jsonError('Adding author failed'); + } + if(!empty($aOrgrnId)){ + //查询机构 + $aWhere = ['organ_id' => ['in',$aOrgrnId],'state' => 0]; + $aOrgan = Db::name('article_organ')->field('organ_id,article_id,organ_name')->where($aWhere)->select(); + if(!empty($aOrgan)){ + //获取最大sort值 + $aMaxSort = Db::name('article_organ')->field('max(sort) as sort')->where(['article_id' => $data['article_id']])->find(); + $iSort = empty($aMaxSort['sort']) ? 0 : $aMaxSort['sort']; + + //处理数据 + $aOrgrnIdData = $aCompanyName = []; + foreach ($aOrgan as $key => $value) { + if($value['article_id'] == $data['article_id']){ + $aOrgrnIdData[] = $value['organ_id']; + $aCompanyName[] = $value['organ_name']; + }else{ + $iSort ++; + $aAdd = ['article_id' => $data['article_id'],'organ_name' =>$value['organ_name'],'create_time' => time(),'sort' => $iSort]; + $iOrganId = DB::name('article_organ')->insertGetId($aAdd); + if(empty($iOrganId)){ + continue; + } + $aOrgrnIdData[] = $iOrganId; + $aCompanyName[] = $value['organ_name']; + } + + } + } + if(!empty($aOrgrnIdData)){ + foreach ($aOrgrnIdData as $key => $value) { + $aInsert[] = ['article_id' => $data['article_id'],'art_aut_id' => $iId,'organ_id' => $value,'create_time' => time()]; + } + } + + } + if(!empty($aInsert)){ + $result = Db::name('article_author_organ')->insertAll($aInsert); + if($result === false){ + return jsonError('Failed to add author institution'); + } + } + if(!empty($aCompanyName) && !empty($iId)){ + $aWhere = ['art_aut_id' => $iId]; + $sCompany = implode('/', array_unique($aCompanyName)); + $update_company_result = Db::name('article_author')->where($aWhere)->limit(1)->update(['company' => $sCompany]); + } + Db::commit(); + //处理作者绑定机构 chengxiaoling 251031 end return jsonSuccess([]); } @@ -2994,7 +3080,8 @@ class Article extends Base "country" => "require", "isSuper" => "require", "isReport" => "require", - "title" => "require" + "title" => "require", + 'organ' => "require" ]); if (!$rule->check($data)) { return jsonError($rule->getError()); @@ -3010,7 +3097,62 @@ class Article extends Base $insert['company'] = isset($data['company']) ? trim($data['company']) : ""; $insert['department'] = isset($data['department']) ? trim($data['department']) : ""; $insert['address'] = isset($data['address']) ? trim($data['address']) : ""; - $this->article_author_obj->where("art_aut_id", $data['art_aut_id'])->update($insert); + //新增修改orcid chengxiaoling 20251029 start + $insert['orcid'] = isset($data['orcid']) ? trim($data['orcid']) : ""; + //新增修改orcid chengxiaoling 20251029 end + + //处理作者绑定机构 chengxiaoling 251031 start + $aOrgrnId = empty($data['organ']) ? '' : $data['organ']; + if(!empty($aOrgrnId) && is_string($aOrgrnId)){ + $aOrgrnId = explode(',', $aOrgrnId); + //查询作者机构 + $aWhere = ['art_aut_id' => $data['art_aut_id'],'state' => 0]; + $aAuthorOrganId = Db::name('article_author_organ')->where($aWhere)->column('organ_id'); + //新增 + $aInsert = array_diff($aOrgrnId, $aAuthorOrganId); + //删除 + $aDelete = array_diff($aAuthorOrganId, $aOrgrnId); + } + Db::startTrans(); + if(!empty($aInsert)){ + foreach ($aInsert as $key => $value) { + $aInsertData[] = ['article_id' => $data['article_id'],'art_aut_id' => $data['art_aut_id'],'organ_id' => $value,'create_time' => time()]; + } + if(!empty($aInsertData)){ + $result = Db::name('article_author_organ')->insertAll($aInsertData); + if($result === false){ + return jsonError('Failed to add author institution'); + } + } + } + if(!empty($aDelete)){ + $aWhere = ['organ_id' => ['in',$aDelete],'state' => 0]; + $aUpdate = ['state' => 1,'update_time' => time()]; + $author_organ_result = Db::name('article_author_organ')->where($aWhere)->limit(count($aDelete))->update($aUpdate); + if($author_organ_result === false){ + return json_encode(['status' => 3,'msg' => 'Failed to unbind the relationship between the institution and the author']); + } + } + + //获取机构名称 + $aWhere = ['art_aut_id' => $data['art_aut_id'],'state' => 0]; + if(!empty($aDelete)){ + $aWhere['organ_id'] =['not in',$aDelete]; + } + $aOrganIdList = Db::name('article_author_organ')->where($aWhere)->column('organ_id'); + $insert['company'] = ''; + if(!empty($aOrganIdList)){ + $aWhere = ['organ_id' => ['in',$aOrganIdList],'state' => 0]; + $aOrganName = Db::name('article_organ')->where($aWhere)->column('organ_name'); + if(!empty($aOrganName) && !empty($data['art_aut_id'])){ + $sCompany = implode('/', array_unique($aOrganName)); + $insert['company'] = $sCompany; + } + } + + $update_company_result = $this->article_author_obj->where("art_aut_id", $data['art_aut_id'])->limit(1)->update($insert); + Db::commit(); + //处理作者绑定机构 chengxiaoling 251031 end return jsonSuccess([]); } @@ -3027,6 +3169,34 @@ class Article extends Base return jsonError($rule->getError()); } $authors = $this->article_author_obj->where("article_id", $data["article_id"])->where("state", 0)->order("sort")->select(); + //查询作者机构 20251031 start + if(!empty($authors)){ + //查询作者机构 + $aAutId = array_column($authors, 'art_aut_id'); + $aWhere = ['art_aut_id' => ['in',$aAutId],'state' => 0]; + if($aAuthorOrganId = Db::name('article_author_organ')->field('art_aut_id,organ_id')->where($aWhere)->select()){ + //查询机构名称 + $aOragnId = array_unique(array_column($aAuthorOrganId, 'organ_id')); + $aWhere = ['article_id' => $data['article_id'],'state' => 0,'organ_id' => ['in',$aOragnId]]; + $aOragn = Db::name('article_organ')->where($aWhere)->column('organ_id,organ_name'); + } + + if(!empty($aAuthorOrganId)){ + $aAuthorOrgan = []; + foreach ($aAuthorOrganId as $key => $value) { + if(empty($aOragn[$value['organ_id']])){ + continue; + } + $aAuthorOrgan[$value['art_aut_id']][] = ['organ_id' => $value['organ_id'],'organ_name' => empty($aOragn[$value['organ_id']]) ? '' : $aOragn[$value['organ_id']]]; + + } + } + foreach ($authors as $key => $value) { + $authors[$key]['organ_id'] = empty($aAuthorOrgan[$value['art_aut_id']]) ? [] : array_unique(array_column($aAuthorOrgan[$value['art_aut_id']], 'organ_id')); + $authors[$key]['organ_name'] = empty($aAuthorOrgan[$value['art_aut_id']]) ? [] : array_column($aAuthorOrgan[$value['art_aut_id']], 'organ_name'); + } + } + //查询作者机构 20251031 end $re['authors'] = $authors; return jsonSuccess($re); } @@ -3147,15 +3317,42 @@ class Article extends Base } $authors = $this->article_author_obj->where('article_id', $data['article_id'])->where('state', 0)->select(); $files = $this->article_file_obj->where('article_id', $data['article_id'])->where('state', 0)->select(); + + //推荐记录 + $aWhere = ['urr_state' => 0,'article_id' => $data['article_id']]; + $aUserRecommend = Db::name('user_reviewer_recommend')->where($aWhere)->column('reviewer_id,urr_id'); + if(!empty($aUserRecommend)){ + //获取基本信息 + $aUserId = array_keys($aUserRecommend); + $aWhere = ['user_id' => ['in',$aUserId],'state' => 0]; + $aUser = Db::name('user')->field('user_id,account,email,realname')->where($aWhere)->select(); + if(!empty($aUser)){ + $aWhere = ['reviewer_id' => ['in',$aUserId],'state' => 0]; + $aReviewer = Db::name('user_reviewer_info')->field('reviewer_id,country,major,company,department')->where($aWhere)->select(); + $aReviewer = array_column($aReviewer, null,'reviewer_id'); + foreach ($aUser as $key => $value) { + $value['country'] = empty($aReviewer[$value['user_id']]['country']) ? '' : $aReviewer[$value['user_id']]['country']; + $value['major'] = empty($aReviewer[$value['user_id']]['major']) ? '' : $aReviewer[$value['user_id']]['major']; + $value['p_major'] = ''; + if(!empty($value['major'])){ + $value['p_major'] = empty($this->getMajorShuList($value['major'])) ? '' : trim($this->getMajorShuList($value['major']),','); + } + $value['urr_id'] = empty($aUserRecommend[$value['user_id']]) ? 0 : $aUserRecommend[$value['user_id']]; + $value['company'] = empty($aReviewer[$value['user_id']]['company']) ? '' : $aReviewer[$value['user_id']]['company']; + $value['department'] = empty($aReviewer[$value['user_id']]['department']) ? '' : $aReviewer[$value['user_id']]['department']; + $aUser[$key] = $value; + } + } + } $re['base'] = $base; $re['authors'] = $authors; $re['files'] = $files; $re['major'] = $major; $re['majors'] = $majors; + $re['reviewer'] = empty($aUser) ? [] : $aUser; return jsonSuccess($re); } - public function changeJournal() { $data = $this->request->post(); @@ -3200,6 +3397,14 @@ class Article extends Base } //判断简介字符串长度是否不低于200 chengxiaoling 20250327 end + //判断伦理 + if(!empty($data['approval']) && $data['approval'] == 1 && empty($data['approval_file'])){ + return jsonError("Ethics documents not uploaded"); + } + if(isset($aArticle['approval']) && $aArticle['approval'] == 0 && empty($aArticle['approval_content'])){ + return jsonError("Please explain the lack of ethical recognition"); + } + $user_info = $this->user_obj->where('user_id', $data['user_id'])->find(); $journal_info = $this->journal_obj->where('journal_id', $data['journal'])->find(); @@ -3232,19 +3437,16 @@ class Article extends Base if (isset($data['approval']) && $data['approval'] == 1) { $inset_data['approval'] = 1; $inset_data['approval_file'] = isset($data["approval_file"]) ? $data["approval_file"] : ''; + $inset_data['approval_content'] = ''; } else { $inset_data["approval"] = 0; $inset_data['approval_content'] = isset($data["approval_content"]) ? $data["approval_content"] : ''; + $inset_data['approval_file'] = ''; } $inset_data['ctime'] = time(); $inset_data['state'] = -1; - //新增字段是否使用AI及使用说明 chengxiaoling 20250725 start - $inset_data['is_use_ai'] = empty($data['is_use_ai']) ? 2 : $data['is_use_ai']; //是否使用AI1是2否 - $inset_data['use_ai_explain'] = isset($data['use_ai_explain']) ? $data['use_ai_explain'] : ''; - //新增字段是否使用AI及使用说明 chengxiaoling 20250725 end - $article_id = $this->article_obj->insertGetId($inset_data); } else { @@ -3254,6 +3456,14 @@ class Article extends Base // return json(['code' => 1, 'msg' => 'Warning: you are re-submitting the article!']); // } // } + //查询manuscirpt文件是否上传 + $aWhere = ['article_id' => $data['article_id'],'state' => 0,'type_name' => 'manuscirpt']; + $aFile = Db::name('article_file')->where($aWhere)->order('ctime desc')->find(); + if(empty($aFile)){ + $iFirstStatus = 2; + $sFirstMsg = 'Step 1: The manuscirpt file has not been uploaded'; + } + $up['user_id'] = $user_info['user_id']; $up['journal_id'] = $data['journal']; $up['editor_id'] = $journal_info['editor_id']; @@ -3268,16 +3478,13 @@ class Article extends Base if (isset($data['approval']) && $data['approval'] == 1) { $up['approval'] = 1; $up['approval_file'] = isset($data["approval_file"]) ? $data["approval_file"] : ''; + $up['approval_content'] = ''; } else { $up["approval"] = 0; $up['approval_content'] = isset($data["approval_content"]) ? $data["approval_content"] : '';//trim($data['approval_content']); + $up['approval_file'] = ''; } - //新增字段是否使用AI及使用说明 chengxiaoling 20250725 start - $up['is_use_ai'] = empty($data['is_use_ai']) ? 2 : $data['is_use_ai']; //是否使用AI1是2否 - $up['use_ai_explain'] = isset($data['use_ai_explain']) ? $data['use_ai_explain'] : '';//使用AI说明 - //新增字段是否使用AI及使用说明 chengxiaoling 20250725 end - $this->article_obj->where('article_id', $article_id)->update($up); } //注释文章筛选领域添加修改为AI推荐领域,在第四步可以查看修改 chengxiaoling 20250722 @@ -3451,8 +3658,8 @@ class Article extends Base /** * 添加文章最终 */ - public function addArticlePart4() - { + public function addArticlePart4(){ + $data = $this->request->post(); $rule = new Validate([ 'article_id' => 'require', @@ -3461,6 +3668,20 @@ class Article extends Base if (!$rule->check($data)) { return jsonError($rule->getError()); } + + //验证文章领域 + $sMajorData = empty($data['major']) ? '' : $data['major'];//文章领域 + if(empty($sMajorData)){ + return jsonError('Please select the field of the article'); + } + //判断是否转投 + if (!isset($data['istransfer'])) { + return jsonError('Please choose to transfer to a journal'); + } + if(isset($data['istransfer']) && $data['istransfer'] == 'true' && empty($data['checkedjours'])){ + return jsonError('Please choose whether to transfer or not'); + } + $article_info = $this->article_obj->where('article_id', $data['article_id'])->find(); $journal_info = $this->journal_obj->where('journal_id', $article_info['journal_id'])->find(); $user_res = $this->user_obj->where('user_id', $article_info['user_id'])->find(); @@ -3595,11 +3816,26 @@ class Article extends Base if (isset($data['code']) && $data['code'] != '') { $update_l['code'] = trim($data['code']); } + + //新增保存字段 chengxiaoling 20251031 start + if (isset($data['istransfer']) && $data['istransfer'] == true) { + $update_l['is_transfer'] = 1; + } + if (isset($data['istransfer']) && $data['istransfer'] == false) { + $update_l['is_transfer'] = 0; + } + if (isset($data['is_become_reviewer'])) { + $update_l['is_become_reviewer'] = $data['is_become_reviewer']; + } + if (isset($data['is_agree'])) { + $update_l['is_agree'] = $data['is_agree']; + } + //新增保存字段 chengxiaoling 20251031 end + $this->article_obj->where('article_id', $data['article_id'])->update($update_l); $this->ai_scor($data['article_id']); //判断是否有文章领域 进行更新操作 chengxiaoling 20250722 start - $sMajorData = empty($data['article_field']) ? '' : $data['article_field'];//文章领域 $iArticleId = empty($data['article_id']) ? 0 : $data['article_id'];//文章ID if(!empty($sMajorData) && !empty($iArticleId)){ $this->updateArticleField(['article_id' => $iArticleId,'article_field' => $sMajorData]); @@ -3614,10 +3850,10 @@ class Article extends Base return json(['code' => 0]); } - // public function ffff(){ - // $data = $this->request->post(); - // $this->ai_scor($data['article_id']); - // } + public function ffff(){ + $data = $this->request->post(); + $this->ai_scor($data['article_id']); + } /** @@ -4087,9 +4323,11 @@ class Article extends Base $uri = $this->user_reviewer_info_obj->where('reviewer_id', $reviewer_info['user_id'])->where('state', 0)->find(); if ($uri == null) { //添加审稿人信息 $insert_reviewer_info['reviewer_id'] = $reviewer_info['user_id']; - $insert_reviewer_info['major'] = $reivewe['major']; + $insert_reviewer_info['major'] = empty($reivewe['major']) ? '' : $reivewe['major']; // $insert_reviewer_info['cmajor'] = $reivewe['cmajor']; - $insert_reviewer_info['country'] = $reivewe['country']; + $insert_reviewer_info['country'] = empty($reivewe['country']) ? '' : $reivewe['country']; + $insert_reviewer_info['company'] = empty($reivewe['company']) ? '' : $reivewe['company']; + $insert_reviewer_info['department'] = empty($reivewe['department']) ? '' : $reivewe['department']; $insert_reviewer_info['test_from'] = "addRecommentReviewer"; $res2 = $this->user_reviewer_info_obj->insert($insert_reviewer_info); } @@ -4102,12 +4340,16 @@ class Article extends Base } //添加推荐审稿人信息 - $insert_recommend['reviewer_id'] = $reviewer_info['user_id']; - $insert_recommend['article_id'] = $article_id; - $insert_recommend['recommend_user_id'] = $user_id; - $insert_recommend['urr_ctime'] = time(); - $res_recommend = $this->user_reviewer_recommend_obj->insert($insert_recommend); - + $aWhere = ['urr_state' => 0,'article_id' => $article_id,'reviewer_id' => $reviewer_info['user_id']]; + $aUserRecommend = Db::name('user_reviewer_recommend')->where($aWhere)->count(); + $res_recommend = true; + if(empty($aUserRecommend)){ + $insert_recommend['reviewer_id'] = $reviewer_info['user_id']; + $insert_recommend['article_id'] = $article_id; + $insert_recommend['recommend_user_id'] = $user_id; + $insert_recommend['urr_ctime'] = time(); + $res_recommend = $this->user_reviewer_recommend_obj->insert($insert_recommend); + } if ($res2 && $res3 && $res_recommend) { return true; } else { @@ -4298,6 +4540,19 @@ class Article extends Base } $where['state'] = 0; $list = $this->journal_obj->where($where)->select(); + + //获取期刊封面 chengxiaoling 20251027 start + if(!empty($list)){ + $aParam = ['issn' => array_column($list, 'issn')]; + $sUrl = 'http://journalapi.tmrjournals.com/public/index.php/'; + $sUrl = $sUrl."api/Supplementary/getJournal"; + $aResult = object_to_array(json_decode(myPost1($sUrl,$aParam),true)); + $aResult = empty($aResult['data']) ? [] : array_column($aResult['data'], 'icon','issn'); + foreach ($list as $key => $value) { + $list[$key]['journal_icon'] = empty($aResult[$value['issn']]) ? '' : $aResult[$value['issn']]; + } + } + //获取期刊封面 chengxiaoling 20251027 end return json($list); } @@ -4982,4 +5237,784 @@ class Article extends Base return ['status' => $iIsSuccess,'msg' => $sMsg]; } + + /** + * 添加文章文件信息 + * @param article_id + * @param + */ + public function addArticlePart3($aParam = []){ + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + + //必填值验证 + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select an article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + //获取文章信息 + $aArticle = $this->getArticleInfo($aParam); + $iStatus = empty($aArticle['status']) ? 0 : $aArticle['status']; + if($iStatus != 1){ + return json_encode($aArticle); + } + $aArticle = empty($aArticle['data']) ? [] : $aArticle['data']; + + //是否使用AI + $iIsUserAi = empty($aParam['is_use_ai']) ? 3 : $aParam['is_use_ai']; //是否使用AI1是2否 + if($iIsUserAi == 3){ + return json_encode(['status' => 5,'msg' => 'Please check whether to use AI technology']); + } + $sUseAiExplain = empty($aParam['use_ai_explain']) ? '' : $aParam['use_ai_explain']; + if($iIsUserAi == 1 && empty($sUseAiExplain)){ + return json_encode(['status' => 6,'msg' => 'Please enter supplementary instructions']); + } + //是否上传图片版权声明1是2否 + $iIsFigureCopyright = empty($aParam['is_figure_copyright']) ? 3 : $aParam['is_figure_copyright']; + if($iIsFigureCopyright == 3){ + return json_encode(['status' => 7,'msg' => 'Please check whether to upload the figure copyright statement']); + } + $aWhere = ['article_id' => $iArticleId,'state' => 0,'type_name' => 'figurecopyright']; + $aFileId = Db::name('article_file')->where($aWhere)->column('file_id'); + if($iIsFigureCopyright == 1){//是 + if(empty($aFileId)){ + return json_encode(['status' => 8,'msg' =>'Please upload the figure copyright declaration file']); + } + } + + Db::startTrans(); + if($iIsFigureCopyright == 2 && !empty($aFileId)){ + $aWhere = ['article_id' => $iArticleId,'file_id' => ['in',$aFileId],'state' => 0,'type_name' => 'figurecopyright']; + $file_result = Db::name('article_file')->where($aWhere)->limit(count($aFileId))->update(['state' => 1]); + if($file_result === false){ + return json_encode(['status' => 9,'msg' =>'figure copyright declaration File deletion failed']); + } + } + $aUpdate = ['is_use_ai' => $iIsUserAi,'use_ai_explain' => $sUseAiExplain,'is_figure_copyright' => $iIsFigureCopyright]; + //更新文章内容 + $aWhere = ['article_id' => $iArticleId,'state' => ['in',[-1,3]]]; + $result = Db::name('article')->where($aWhere)->limit(1)->update($aUpdate); + if($result === false){ + return json_encode(['status' => 10,'msg' =>'Failed to save article content']); + } + Db::commit(); + + return json_encode(['status' => 1,'msg' =>'The content of the article has been successfully saved']); + } + + /** + * 按步骤获取文章的状态 + */ + public function getArticleState(){ + + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + //获取文章信息 + $aArticle = $this->getArticleInfo($aParam); + $iStatus = empty($aArticle['status']) ? 0 : $aArticle['status']; + if($iStatus != 1){ + return json_encode($aArticle); + } + $aArticle = empty($aArticle['data']) ? [] : $aArticle['data']; + + //定义返回内容 + $aData = ['first' => 2,'second' => 2,'three' => 2,'four' => 2]; + //第一步验证 + $aFirst = ['title','type','abstrart','journal_id']; + $iFirstStatus = 1; + $sFirstMsg = $sSecondMsg = $sThreeMsg = $sFourMsg = ''; + foreach ($aFirst as $key => $value) { + if(empty($aArticle[$value])){ + $iFirstStatus = 2; + $sFirstMsg = 'Step 1: Required fields incomplete'; + break; + } + } + + //判断伦理 + if(!empty($aArticle['approval']) && $aArticle['approval'] == 1 && empty($aArticle['approval_file'])){ + $iFirstStatus = 2; + $sFirstMsg = 'Step 1: Ethics documents not uploaded'; + } + if(isset($aArticle['approval']) && $aArticle['approval'] == 0 && empty($aArticle['approval_content'])){ + $iFirstStatus = 2; + $sFirstMsg = 'Step 1: Please explain the lack of ethical recognition'; + } + + //查询manuscirpt文件是否上传 + if($iFirstStatus == 1){ + $aWhere = ['article_id' => $iArticleId,'state' => 0,'type_name' => 'manuscirpt']; + $aFile = Db::name('article_file')->where($aWhere)->order('ctime desc')->find(); + if(empty($aFile)){ + $iFirstStatus = 2; + $sFirstMsg = 'Step 1: The manuscirpt file has not been uploaded'; + } + } + + //第二步 查询作者 + $iSecondStatus = 1; + $is_super = $is_report = 2; + // if($iFirstStatus == 1){ + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aAuthorData = DB::name('article_author')->where($aWhere)->select(); + if(empty($aAuthorData)){ + $iSecondStatus = 2; + } + if(!empty($aAuthorData)){ + foreach ($aAuthorData as $key => $value) { + if(empty($value['email']) || empty($value['author_title']) || empty($value['company']) || empty($value['firstname'])){ + $iSecondStatus = 2; + break; + } + if($value['is_report'] == 1){ + if(empty($value['address'])){ + $is_report = 2; + break; + }else{ + $is_report = 1; + } + } + if($value['is_super'] == 1){ + $is_super = 1; + } + } + + } + // } + if($iSecondStatus == 2){ + $sSecondMsg = 'Step 2: The author\'s required information is incomplete'; + } + if($iSecondStatus == 1){ + if($is_super == 2){ + $sSecondMsg = 'Step 2: Please select the first author'; + $iSecondStatus = 2; + } + if($is_report == 2){ + $sSecondMsg = empty($sSecondMsg) ? 'Step 2: Please select the first author' : 'Step 2: Please select the corresponding/first author'; + $iSecondStatus = 2; + } + } + + //第三步 + $iThreeStatus = 1; + $sThreeMsg = ''; + // if($iSecondStatus == 1){ + if($aArticle['is_use_ai'] == 3){//验证是否使用AI + $sThreeMsg = 'Step 3: Please check whether to use AI technology'; + $iThreeStatus = 2; + } + if($aArticle['is_use_ai'] == 1 && empty($aArticle['use_ai_explain'])){//验证是否填写AI说明 + $sThreeMsg = 'Step 3: Please enter supplementary instructions'; + $iThreeStatus = 2; + } + if($aArticle['is_figure_copyright'] == 3){//验证是否上传版权声明 + $sThreeMsg = 'Step 3: Please check whether to upload the figure copyright statement'; + $iThreeStatus = 2; + } + if($aArticle['is_figure_copyright'] == 1){//验证是否上传版权声明 + $aWhere = ['article_id' => $iArticleId,'state' => 0,'type_name' => 'figurecopyright']; + $aFile = Db::name('article_file')->where($aWhere)->order('ctime desc')->find(); + if(empty($aFile)){ + $sThreeMsg = 'Step 3: Please upload the figure copyright declaration file'; + $iThreeStatus = 2; + + } + } + // } + //第四步 + $iFourStatus = 1; + $sFourMsg = ''; + // if($iThreeStatus == 1){ + if($aArticle['is_transfer'] == 3){//是否转投 + $sFourMsg = 'Step 4: Please choose whether to transfer or not'; + $iFourStatus = 2; + } + + if($iFourStatus == 1 && $aArticle['is_transfer'] == 1){//查询转投期刊 + $aWhere = ['state' => 0, 'article_id' => $iArticleId]; + $iCount = Db::name('article_transfer')->where($aWhere)->count(); + if(empty($iCount)){ + $sFourMsg = 'Step 4: Please choose to transfer to a journal'; + $iFourStatus = 2; + } + } + //查询文章领域 + if($iFourStatus == 1){ + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aMajor = DB::name('major_to_article')->where($aWhere)->select(); + if(empty($aMajor)){ + $sFourMsg = 'Step 4: Please select the field of the article'; + $iFourStatus = 2; + } + } + if($iFourStatus == 1){//查询是否推荐审稿人 + $aWhere = ['urr_state' => 0,'article_id' => $iArticleId]; + $aUserRecommend = Db::name('user_reviewer_recommend')->where($aWhere)->column('reviewer_id'); + if(empty($aUserRecommend)){ + $sFourMsg = 'Step 4: Please recommend reviewers'; + $iFourStatus = 2; + } + if(!empty($aUserRecommend)){ + //获取基本信息 + $aWhere = ['user_id' => ['in',$aUserRecommend],'state' => 0]; + $aUser = Db::name('user')->field('user_id,account,email,realname')->where($aWhere)->select(); + if(empty($aUser)){ + $sFourMsg = 'Step 4: Recommended reviewer does not exist'; + $iFourStatus = 2; + } + if(!empty($aUser)){ + $aWhere = ['reviewer_id' => ['in',$aUserRecommend],'state' => 0]; + $aReviewer = Db::name('user_reviewer_info')->field('reviewer_id,country,major,company,department')->where($aWhere)->select(); + $aReviewer = array_column($aReviewer, null,'reviewer_id'); + if(empty($aReviewer)){ + $sFourMsg = 'Step 4: Recommended reviewer\'s detailed information does not exist'; + $iFourStatus = 2; + } + if(!empty($aReviewer)){ + foreach ($aUser as $key => $value) { + if(empty($value['email']) || empty($value['realname'])){ + $sFourMsg = 'The Reviewer\'s required information is incomplete'; + $iFourStatus = 2; + break; + } + $value['major'] = empty($aReviewer[$value['user_id']]['major']) ? '' : $aReviewer[$value['user_id']]['major']; + if(empty($value['major'])){ + $sFourMsg = 'The Reviewer\'s required information is incomplete'; + $iFourStatus = 2; + break; + } + $value['company'] = empty($aReviewer[$value['user_id']]['company']) ? '' : $aReviewer[$value['user_id']]['company']; + if(empty($value['company'])){ + $sFourMsg = 'The Reviewer\'s required information is incomplete'; + $iFourStatus = 2; + break; + } + $value['department'] = empty($aReviewer[$value['user_id']]['department']) ? '' : $aReviewer[$value['user_id']]['department']; + if(empty($value['department'])){ + $sFourMsg = 'The Reviewer\'s required information is incomplete'; + $iFourStatus = 2; + break; + } + $value['country'] = empty($aReviewer[$value['user_id']]['country']) ? '' : $aReviewer[$value['user_id']]['country']; + $value['urr_id'] = empty($aUserRecommend[$value['user_id']]) ? 0 : $aUserRecommend[$value['user_id']]; + $aUser[$key] = $value; + } + } + } + } + } + + // } + + //数据处理 + $aData['first'] = $iFirstStatus; + $aData['second'] = $iSecondStatus; + $aData['three'] = $iThreeStatus; + $aData['four'] = $iFourStatus; + $aData['first_msg'] = $sFirstMsg; + $aData['second_msg'] = $sSecondMsg; + $aData['three_msg'] = $sThreeMsg; + $aData['four_msg'] = $sFourMsg; + + //判断当前未完成的步骤 + foreach ($aData as $key => $value) { + if($value == 2){ + $current = $key; + break; + } + } + $aData['current_step'] = empty($current) ? '' : $current; + return json_encode(['status' => 1,'msg' => 'success','data' => $aData]); + } + + /** + * 文章暂存 + */ + public function addArticleStaging() + { + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + $iJournalId = empty($aParam['journal']) ? 0 : $aParam['journal']; + if(!empty($iJournalId)){ + $aParam['journal_id'] = $iJournalId; + } + if(empty($iArticleId)){ + $sTitle = empty($aParam['title']) ? '' : $aParam['title']; + // if(empty($iJournalId)){ + // return json_encode(['status' => 2,'msg' => 'Please select a journal']); + // } + $aArticleInsert = ['journal_id' => $iJournalId,'title' => $sTitle,'state' => -1,'user_id' => $iUserId]; + $aArticleInsert['is_use_ai'] = 3; + $aArticleInsert['is_figure_copyright'] = 3; + $aArticleInsert['is_transfer'] = 3; + $aArticleInsert['is_become_reviewer'] = 3; + $iArticleId = Db::name('article')->insertGetId($aArticleInsert); + $aParam['article_id'] = $iArticleId; + } + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select a article']); + } + //获取文章信息 + $aArticle = $this->getArticleInfo($aParam); + $iStatus = empty($aArticle['status']) ? 0 : $aArticle['status']; + if($iStatus != 1){ + return json_encode($aArticle); + } + $aArticle = empty($aArticle['data']) ? [] : $aArticle['data']; + + //定义更新数组 + $aUpdate = []; + // //摘要 + // $abstrart = empty($aParam['abstrart']) ? '' : $aParam['abstrart']; + // if(!empty($abstrart)){//判断简介字符串长度是否不低于200 + // if(!$this->checkMinChars($abstrart, 200)){ + // return json_encode(['status' => 3,'msg' => 'The abstract should not be less than 200 Chinese characters or English words!']); + // } + // $aUpdate['abstrart'] = $abstrart; + // } + //是否转投 + $istransfer = isset($aParam['istransfer']) ? $aParam['istransfer'] : '' ; + if($istransfer == true){ + $aParam['is_transfer'] = 1; + } + if($istransfer == false){ + $aParam['is_transfer'] = 2; + } + //是否成为审稿人 + $becomeRev = isset($aParam['becomeRev']) ? $aParam['becomeRev'] : ''; + if($becomeRev == true){ + $aParam['is_become_reviewer'] = 1; + } + if($becomeRev == false){ + $aParam['is_become_reviewer'] = 2; + } + $aField = ['is_use_ai','use_ai_explain','is_figure_copyright','is_transfer','is_become_reviewer','approval','approval_file','approval_content','code','is_transfer','is_become_reviewer','is_agree','title','abstrart','keywords','topics','fund','type','journal_id'];//,'title','abstrart','keywords','topics','fund','type' + $sMsg = ''; + $iIsUpdate = 1; + foreach ($aField as $key => $value) { + $sValue = isset($aParam[$value]) ? $aParam[$value] : -2 ; + if($sValue == -2){ + continue; + } + if($value == 'is_use_ai' && $sValue == 0){ + $aUpdate['is_use_ai'] = 3; + continue; + } + if($value == 'is_figure_copyright' && $sValue == 0){ + $aUpdate['is_figure_copyright'] = 3; + continue; + } + // if($value == 'is_use_ai'){ + // if(!in_array($sValue, [1,2])){ + // $sMsg = 'Please check whether to use AI technology'; + // $iIsUpdate = 2; + // break; + // } + // // if($sValue == 1 && empty($aParam['use_ai_explain'])){ + // // $sMsg = 'Please enter supplementary instructions'; + // // $iIsUpdate = 3; + // // break; + // // } + // } + // if($value == 'is_figure_copyright'){ + // if(!in_array($sValue, [1,2])){ + // $sMsg = 'Please check whether to upload the figure copyright statement'; + // break; + // } + // // if($sValue == 1){ + // // $sMsg = 'Please enter supplementary instructions'; + // // $iIsUpdate = 4; + // // break; + // // } + // } + // $iIsUpdate = 1; + $aUpdate[$value] = trim($aParam[$value]); + } + //获取期刊编辑 + //期刊ID + if(!empty($iJournalId)){ + //查询期刊信息 + $aJournalWhere = ['journal_id' => $iJournalId,'state' => 0]; + $aJournal = DB::name('journal')->field('editor_id')->where($aJournalWhere)->find(); + $aUpdate['editor_id'] = empty($aJournal['editor_id']) ? 0 : $aJournal['editor_id']; + } + //数据处理 + // if($iIsUpdate == 4){ + // $aWhere = ['article_id' => $iArticleId,'state' => 0,'type_name' => 'figurecopyright']; + // $aFile = Db::name('article_file')->where($aWhere)->order('ctime desc')->find(); + // if(empty($aFile)){ + // $sSecondMsg = 'Step 3: Please upload the figure copyright declaration file'; + // $iThreeStatus = 2; + // return json_encode(['status' => 4,'msg' => 'Please upload the figure copyright declaration file']); + // } + // } + if($iIsUpdate != 1){ + return json_encode(['status' => 5,'msg' => $sMsg]); + } + + //参数判空 + $sMajorData = empty($aParam['major']) ? '' : $aParam['major'];//文章领域 + // if(empty($sMajorData) && empty($aUpdate)){ + // return json_encode(['status' => 6,'msg' => 'Update data to empty']); + // } + + //文章领域处理 + $aMajorInsert = $aMajorDelete = []; + if(!empty($sMajorData)){ + $aField = explode(',', $sMajorData); + $aWhere = ['state' => 0, 'article_id' => $iArticleId]; + $aArticleMajor = Db::name('major_to_article')->where($aWhere)->order('major_id asc')->column('major_id'); + //新增 + $aInsert = array_diff($aField, $aArticleMajor); + //删除 + $aMajorDelete = array_diff($aArticleMajor, $aField); + //数据处理 + if (!empty($aInsert)) {//新增 + foreach ($aInsert as $key => $value) { + $aMajorInsert[] = ['major_id' => $value, 'article_id' => $iArticleId, 'ctime' => time(), 'state' => 0]; + } + } + } + + //转投信息 + $aTransferJournalId = empty($aParam['checkedjours']) ? [] : $aParam['checkedjours']; + if(!empty($aTransferJournalId) && is_string($aTransferJournalId)){ + $aTransferJournalId = explode(',', $aTransferJournalId); + } + $aJournalInsert = $aJournalDelete = []; + if(!empty($aTransferJournalId)){ + //查询转投期刊ID + $aWhere = ['state' => 0, 'article_id' => $iArticleId]; + $aTransferJournal = Db::name('article_transfer')->where($aWhere)->order('journal_id asc')->column('journal_id'); + //新增 + $aInsert = array_diff($aTransferJournalId, $aTransferJournal); + //删除 + $aJournalDelete = array_diff($aTransferJournal, $aTransferJournalId); + if (!empty($aInsert)) {//新增 + foreach ($aInsert as $key => $value) { + $aJournalInsert[] = ['journal_id' => $value, 'article_id' => $iArticleId, 'ctime' => time(), 'state' => 0]; + } + } + } + + //推荐审稿人 + $aReviewer = isset($aParam['reviewers']) ? $aParam['reviewers'] : []; +// $json = '{ +// "article_id": "5997", +// "user_id": "54", +// "major": "52,55,56", +// "checkedjours": [], +// "istransfer": false, +// "becomeRev": false, +// "reviewers": [ + +// { +// "realname": "77777", +// "email": "752204719@qq.com", +// "country": "Afghanistan", +// "company": "11111", +// "department": "33333333", +// "major_all": [ +// 167, +// 171, +// 173 +// ], +// "major": 173 +// }, +// { +// "realname": "8888", +// "email": "752204716@qq.com", +// "country": "Albania", +// "major_all": [ +// 167, +// 171, +// 173 +// ], +// "major": 173 +// } +// ], +// "code": "777777777898" +// }'; +// $aReviewer = json_decode($json,true); +// $aReviewer = $aReviewer['reviewers']; + if(!empty($aReviewer)){ + + //根据用户邮箱查询是否注册 + $aEmail = array_unique(array_column($aReviewer, 'email')); + $aWhere = ['email' => ['in',$aEmail],'state' => 0]; + $aUserDataResult = Db::name('user')->field('user_id,account,email,realname')->where($aWhere)->select(); + if(empty($aUserDataResult)){ + $aUserDataResult = []; + } + $aUserData = empty($aUserDataResult) ? [] : array_column($aUserDataResult, null,'email'); + + //数据处理 + $aUserInsert = $aUserRecommendDelete = []; + foreach ($aReviewer as $key => $value) { + $sEmail = empty($value['email']) ? '' : $value['email']; + if(empty($sEmail)){ + continue; + } + if(!empty($aUserData[$sEmail])){ + continue; + } + $aUserInsert = ['account' => $value['email'],'password' => md5('123456qwe'),'email' => $sEmail,'realname' => empty($value['realname']) ? '' : $value['realname'],'ctime' => time()]; + $iId = Db::name('user')->insertGetId($aUserInsert); + if(empty($iId)){ + continue; + } + $aUserInsert['user_id'] = $iId; + $aUserDataResult[] = $aUserInsert; + } + if(!empty($aUserDataResult)){ + + //查询期刊标题 + $iJournalId = empty($aArticle['journal_id']) ? 0 : $aArticle['journal_id']; + $aWhere = ['journal_id' => $iJournalId,'state' => 0]; + $aJournal = Db::name('journal')->field('title')->where($aWhere)->find(); + + //用户信息 + $aUserDataResult = array_column($aUserDataResult, null,'user_id'); + $aUserData = empty($aUserDataResult) ? [] : array_column($aUserDataResult, 'user_id','email'); + //获取期刊审稿人 + $aReviewerId = array_column($aUserDataResult, 'user_id'); + $aWhere = ['reviewer_id' => ['in',$aReviewerId],'state' => 0]; + $aReviewerToJournal = Db::name('reviewer_to_journal')->where($aWhere)->select(); + $aReviewerToJournal = empty($aReviewerToJournal) ? [] : array_column($aReviewerToJournal, null,'reviewer_id'); + + //获取审稿人资料 + $aReviewerInfo = Db::name('user_reviewer_info')->field('reviewer_info_id,reviewer_id')->where($aWhere)->select(); + $aReviewerInfo = empty($aReviewerInfo) ? [] : array_column($aReviewerInfo, 'reviewer_info_id','reviewer_id'); + + //推荐记录 + $aWhere = ['reviewer_id' => ['in',$aReviewerId],'urr_state' => 0,'article_id' => $iArticleId]; + $aUserRecommend = Db::name('user_reviewer_recommend')->where($aWhere)->column('reviewer_id'); + + $aReviewerInfoAll = $aReviewerToJournalAll = $aInsertRecommend = []; + foreach ($aReviewer as $key => $value) { + $sEmail = empty($value['email']) ? '' : $value['email']; + if(empty($sEmail)){ + continue; + } + $iReviewerUserId = empty($aUserData[$sEmail]) ? 0 : $aUserData[$sEmail]; + if(empty($iReviewerUserId)){ + continue; + } + //审稿人的详细信息 + $insert_reviewer_info = ['reviewer_id' => $iReviewerUserId,'major' => empty($value['major']) ? '' : $value['major'], 'country' => empty($value['country']) ? '' : $value['country'],'test_from' => 'addRecommentReviewer','company' => empty($value['company']) ? '' : $value['company'],'department' => empty($value['department']) ? '' : $value['department']]; + if(!empty($aReviewerInfo[$iReviewerUserId])){ + $insert_reviewer_info['reviewer_info_id'] = $aReviewerInfo[$iReviewerUserId]; + } + $aReviewerInfoAll[] = $insert_reviewer_info; + //期刊审稿人 + $reviewer_to_journal = ['reviewer_id' => $iReviewerUserId,'journal_id' => $iJournalId, 'account' => empty($aUserDataResult[$iReviewerUserId]['account']) ? '' : $aUserDataResult[$iReviewerUserId]['account'],'journal_title' => empty($aJournal['title']) ? '' : $aJournal['title'],'ctime' => time()]; + if(!empty($aReviewerToJournal[$iReviewerUserId])){ + $reviewer_to_journal['rtj_id'] = $aReviewerToJournal[$iReviewerUserId]['rtj_id']; + } + $aReviewerToJournalAll[] = $reviewer_to_journal; + + if(in_array($iReviewerUserId, $aUserRecommend)){ + continue; + } + //添加推荐审稿人信息 + $aInsertRecommend[] = ['reviewer_id' => $iReviewerUserId,'article_id' => $iArticleId,'recommend_user_id' => $iUserId,'urr_ctime' => time()]; + } + + //判读是否有删除 + $aUserRecommendId = array_column($aUserDataResult, 'user_id'); + //删除 + $aWhere = ['urr_state' => 0,'article_id' => $iArticleId]; + $aUserRecommend = Db::name('user_reviewer_recommend')->where($aWhere)->column('reviewer_id'); + $aUserRecommendDelete = array_diff($aUserRecommend,$aUserRecommendId); + } + } + Db::startTrans(); + if(!empty($aMajorInsert)){//新增领域 + $add_result = Db::name('major_to_article')->insertAll($aMajorInsert); + } + if(!empty($aMajorDelete)){//删除领域 + $aWhere = ['article_id' => $iArticleId, 'state' => 0, 'major_id' => ['in', $aMajorDelete]]; + $delete_result = Db::name('major_to_article')->where($aWhere)->limit(count($aMajorDelete))->update(['state' => 1, 'ctime' => time()]); + } + if(!empty($aJournalInsert)){//新增转投期刊 + $add_journal_result = Db::name('article_transfer')->insertAll($aJournalInsert); + } + if(!empty($aJournalDelete)){//删除转投期刊 + $aWhere = ['article_id' => $iArticleId, 'state' => 0, 'journal_id' => ['in', $aJournalDelete]]; + $delete_journal_result = Db::name('article_transfer')->where($aWhere)->limit(count($aJournalDelete))->delete(); + } + //更新数据 + if(!empty($aUpdate)){//更新文章主表数据 + //数据更新 + $aWhere = ['article_id' => $iArticleId,'state' => ['in',[-1,3]]]; + $result = Db::name('article')->where($aWhere)->limit(1)->update($aUpdate); + if($result === false){ + return json_encode(['status' => 7,'msg' =>'Failed to save article content']); + } + } + //更新审稿人数据 + if(!empty($aReviewerInfoAll)){ + $oUserReviewerInfo = new \app\common\UserReviewerInfo(); + $sReviewerInfoAll = $oUserReviewerInfo->saveAll($aReviewerInfoAll); + } + if(!empty($aReviewerToJournalAll)){ + $oReviewerTojournal = new \app\common\ReviewerToJournal(); + $sReviewerTojournal = $oReviewerTojournal->saveAll($aReviewerToJournalAll); + } + if(!empty($aInsertRecommend)){ + $sInsertRecommend = Db::name('user_reviewer_recommend')->insertAll($aInsertRecommend); + } + if(!empty($aUserRecommendDelete)){ + $aWhere = ['urr_state' => 0,'article_id' => $iArticleId,'reviewer_id' => ['in',$aUserRecommendDelete]]; + $sDelete = Db::name('user_reviewer_recommend')->where($aWhere)->limit(count($aUserRecommendDelete))->delete(); + } + Db::commit(); + + return json_encode(['status' => 1,'msg' =>'The content of the article has been successfully saved','data' => ['article_id' => $iArticleId]]); + } + /** + * 文章信息获取 + */ + private function getArticleInfo($aParam = []){ + //获取参数 + $aParam = empty($aParam) ? [] : $aParam; + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return ['status' => 2,'msg' => 'Please select the article']; + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return ['status' => 2,'msg' => 'Please select author']; + } + //查询文章 + $aWhere = ['article_id' => $iArticleId]; + $aArticle = Db::name('article')->field('article_id,title,type,abstrart,journal_id,state,user_id,is_use_ai,use_ai_explain,is_figure_copyright,is_transfer,approval,approval_content,approval_file')->where($aWhere)->find(); + if(empty($aArticle)){ + return ['status' => 7,'msg' => 'The article does not exist']; + } + if($aArticle['state'] != -1 && $aArticle['state'] != 3){ + return ['status' => 8,'msg' => 'Article cannot be edited']; + } + if($aArticle['user_id'] != $iUserId){ + return ['status' => 9,'msg' => 'The article does not belong to the current author']; + } + return ['status' => 1,'msg' => 'success','data' => $aArticle]; + } + + /** + * 添加图片版权声明文件 + */ + public function addFigureCopyright($aParam = []){ + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + //文件地址 + $sUrl = empty($aParam['url']) ? '' : $aParam['url']; + if(empty($sUrl)){ + return json_encode(['status' => 2,'msg' => 'Please choose to upload the file']); + } + //文件地址 + $sTypeName = empty($aParam['type']) ? '' : $aParam['type']; + if(empty($sTypeName)){ + return json_encode(['status' => 2,'msg' => 'Please select the type of file to upload']); + } + + //文件地址 + $aArticleUpdate = []; + if($sTypeName == 'figurecopyright'){ + $is_figure_copyright = empty($aParam['is_figure_copyright']) ? 3 : $aParam['is_figure_copyright']; + if($is_figure_copyright != 1){ + return json_encode(['status' => 2,'msg' => 'Please check whether to upload the figure copyright statement']); + } + $aArticleUpdate['is_figure_copyright'] = 1; + } + + + //获取文章信息 + $aArticle = $this->getArticleInfo($aParam); + $iStatus = empty($aArticle['status']) ? 0 : $aArticle['status']; + if($iStatus != 1){ + return json_encode($aArticle); + } + + //验证文件是否上传 + $aWhere = ['file_url' => $sUrl,'state' => 0]; + $result = Db::name('article_file')->where($aWhere)->find(); + if(!empty($result)){ + return json_encode(['status' => 1,'msg' => 'Duplicate upload','data' => $result]); + } + //获取作者信息 + $aWhere = ['user_id' => $iUserId,'state' => 0]; + $aUser = Db::name('user')->field('account')->where($aWhere)->find(); + + Db::startTrans(); + $aInsert['article_id'] = $iArticleId; + $aInsert['user_id'] = $iUserId; + $aInsert['username'] = empty($aUser['account']) ? '' : $aUser['account']; + $aInsert['file_url'] = $sUrl; + $aInsert['type_name'] = $sTypeName; + $aInsert['ctime'] = time(); + $result = Db::name('article_file')->insertGetId($aInsert); + //更新文章内容 + if(!empty($aArticleUpdate)){ + $aWhere = ['article_id' => $iArticleId,'state' => ['in',[-1,3]]]; + $update_result = Db::name('article')->where($aWhere)->limit(1)->update($aArticleUpdate); + } + Db::commit(); + + return json_encode(['status' => 1,'msg' => 'success','data' => ['file_id' => $result]]); + } + + /** + * 获取领域树 + */ + private function getMajorShuList($major) + { + $major_obj = Db::name('major'); + if ($major == 0) { + return; + } + $res = $major_obj->where('major_id', $major)->find(); + if ($res['pid'] == 0) { + return $res['major_id']; + } + + $p = self::getMajorShuList($res['pid']); + return $p . ',' . $res['major_id']; + } } diff --git a/application/api/controller/Contribute.php b/application/api/controller/Contribute.php new file mode 100644 index 0000000..7241510 --- /dev/null +++ b/application/api/controller/Contribute.php @@ -0,0 +1,359 @@ +request->post() : $aParam; + + //必填值验证 + $sFileUrl = empty($aParam['file_url']) ? '' : $aParam['file_url']; + $sOriginalFileUrl = $sFileUrl; + if(empty($sFileUrl)){ + return json_encode(['status' => 2,'msg' => 'Please upload the submission file']); + } + // //文章类型 + // $sType = empty($aParam['type']) ? '' : $aParam['type']; + // if(empty($sType)){ + // return json_encode(['status' => 2,'msg' => 'Please select the article type']); + // } + // //期刊ID + // $iJournalId = empty($aParam['journal_id']) ? '' : $aParam['journal_id']; + // if(empty($iJournalId)){ + // return json_encode(['status' => 2,'msg' => 'Please select the journal to which you belong']); + // } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + + //判断文件是否执行 + $sFileUrl = rtrim(ROOT_PATH,'/').'/public/'.ltrim(ltrim($sFileUrl,'/'),'public'); + if (!file_exists($sFileUrl)) { + return json_encode(['status' => 3, 'msg' => 'The uploaded file does not exist']); + } + if (!is_readable($sFileUrl)) { + return json_encode(['status' => 4, 'msg' => 'The uploaded file is unreadable']); + } + //文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + $aWhere = []; + if(!empty($iArticleId)){//更新文章内容 + $aWhere['article_id'] = $iArticleId; + $aArticle = Db::name('article')->field('state,user_id,manuscirpt_url')->where($aWhere)->find(); + if(empty($aArticle)){ + return json_encode(['status' => 7,'msg' => 'The article does not exist']); + } + if($aArticle['state'] != -1 && $aArticle['state'] != 3){ + return json_encode(['status' => 8,'msg' => 'Article cannot be edited']); + } + if($aArticle['user_id'] != $iUserId){ + return json_encode(['status' => 9,'msg' => 'Not modified by the author themselves']); + } + if($aArticle['manuscirpt_url'] == trim($sOriginalFileUrl,'/')){ + return json_encode(['status' => 9,'msg' => 'The content of the article has not changed']); + } + $aWhere['article_id'] = ['<>',$iArticleId]; + } + //获取数据 + $aDealData = json_decode(ArticleParserService::uploadAndParse($sFileUrl),true); + $iStatus = empty($aDealData['status']) ? 0 : $aDealData['status']; + $sMsg = empty($aDealData['msg']) ? 'fail' : $aDealData['msg']; + if($iStatus != 1){ + return json_encode(['status' => 5, 'msg' => $sMsg]); + } + $aData = empty($aDealData['data']) ? '' : $aDealData['data']; + if(empty($aData['title'])){ + return json_encode(['status' => 6,'msg' => 'The article title is empty']); + } + //查询标题是否存在 + $aWhere += ['title' => trim($aData['title']),'state' => ['<>',3]]; + $aArticle = Db::name('article')->field('article_id')->where($aWhere)->find(); + if(!empty($aArticle)){ + return json_encode(['code' => 7, 'msg' => 'Warning: you are re-submitting the article!']); + } + + //数据入库 + $aData += $aParam; + $result = $this->_addData($aData); + return $result; + } + + /** + * 组装数据插入相关数据表 + * @param array $aParam + */ + private function _addData($aParam = []){ + if(empty($aParam)){ + return json_encode(['status' => 2,'msg' => 'Data is empty']); + } + + //获取文章ID + $iUpdateArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(!empty($iUpdateArticleId)){ + $aWhere = ['article_id' => $iUpdateArticleId]; + $aArticle = Db::name('article')->field('title,keywords,abstrart,fund,journal_id')->where($aWhere)->find(); + } + //插入基础表 t_article + $aInsert = []; + //标题 + if(empty($aArticle['title'])){ + $sTitile = empty($aParam['title']) ? '' : $aParam['title']; + if(!empty($sTitile)){ + $aInsert['title'] = $sTitile; + } + } + + //关键词 + if(empty($aArticle['keywords'])){ + $sKeyWords = empty($aParam['keywords']) ? '' : $aParam['keywords']; + if(!empty($sKeyWords)){ + $aInsert['keywords'] = is_array($sKeyWords) ? implode(',', $sKeyWords) : $sKeyWords; + } + } + //摘要 + if(empty($aArticle['abstrart'])){ + $sAbstrart = empty($aParam['abstrart']) ? '' : $aParam['abstrart']; + if(!empty($sAbstrart)){ + $aInsert['abstrart'] = $sAbstrart; + } + } + //基金 + if(empty($aArticle['fund'])){ + $sFund = empty($aParam['fund']) ? '' : $aParam['fund']; + if(!empty($sAbstrart)){ + $aInsert['fund'] = $sFund; + } + } + //期刊ID + $iJournalId = empty($aParam['journal_id']) ? 0 : $aParam['journal_id']; + if(!empty($iJournalId)){ + $aInsert['journal_id'] = $iJournalId; + //查询期刊信息 + $aJournalWhere = ['journal_id' => $iJournalId,'state' => 0]; + $aJournal = DB::name('journal')->field('editor_id')->where($aJournalWhere)->find(); + $aInsert['editor_id'] = empty($aJournal['editor_id']) ? 0 : $aJournal['editor_id']; + } + //类型 + $sType = empty($aParam['type']) ? '' : $aParam['type']; + if(!empty($sType)){ + $aInsert['type'] = $sType; + } + //上传文件地址 + $sFileUrl = empty($aParam['file_url']) ? '' : $aParam['file_url']; + if(!empty($sFileUrl)){ + $aInsert['manuscirpt_url'] = trim(trim($sFileUrl,'/'),'public/'); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? 0 : $aParam['user_id']; + if(!empty($iUserId)){ + $aInsert['user_id'] = $iUserId; + //查询用户信息 + $aUser = Db::name('user')->field('account')->where(['user_id' => $iUserId,'state' => 0])->find(); + } + Db::startTrans(); + //插入article + if(empty($aArticle) && !empty($aInsert)){//新插入 + $aInsert['ctime'] = time(); + $aInsert['state'] = -1; + $aInsert['is_use_ai'] = 3; + $aInsert['is_figure_copyright'] = 3; + $aInsert['is_transfer'] = 3; + $aInsert['is_become_reviewer'] = 3; + $iArticleId = Db::name('article')->insertGetId($aInsert); + if(empty($iArticleId)){ + return json_encode(['status' => 3,'msg' => 'Article added successfully']); + } + //获取accept_sn并更新 + $sAcceptSn = $this->getArticleAcceptSn(['article_id' => $iArticleId]); + if(!empty($sAcceptSn)){ + $aWhere = ['article_id' => $iArticleId]; + $aUpdate = ['accept_sn' => $sAcceptSn]; + $update_result = Db::name('article')->where($aWhere)->limit(1)->update($aUpdate); + } + } + if(!empty($aArticle) && !empty($aInsert)){//更新 + $aWhere = ['article_id' => $iUpdateArticleId,'state' => ['in',[-1,3]]]; + $update_result = Db::name('article')->where($aWhere)->limit(1)->update($aInsert); + if($update_result === false){ + return json_encode(['status' => 3,'msg' => 'Article update failed']); + } + //更新作者为逻辑删除 + $aWhere['state'] = 0; + $update_author_result = DB::name('article_author')->where($aWhere)->update(['state' => 1]); + if($update_author_result === false){ + return json_encode(['status' => 4,'msg' => 'Article author update failed']); + } + } + + //作者单位 + $iArticleId = empty($iArticleId) ? $iUpdateArticleId : $iArticleId; + $aCompany = empty($aParam['company']) ? [] : $aParam['company']; + + if(!empty($aCompany)){ + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aOrgan = Db::name('article_organ')->field('organ_id,organ_name,sort')->where($aWhere)->select(); + $aOrganName = empty($aOrgan) ? [] : array_column($aOrgan, 'organ_name'); + $iMaxSort = empty($aOrgan) ? 0 : max(array_column($aOrgan, 'sort')); + //查询文章 + $aCompanyInsert = $aSort = []; + foreach ($aCompany as $key => $value) { + if(empty($value)){ + continue; + } + $sName = trim(trim(trim($value,'*'),'#')); + if(in_array($sName, $aOrganName)){ + continue; + } + if(empty($iMaxSort)){ + $iSort = $key; + $aSort[$key] = $key; + }else{ + $iMaxSort++; + $iSort = $iMaxSort; + $aSort[$key] = $iMaxSort; + } + $aCompanyInsert[] = ['article_id' => $iArticleId,'organ_name' =>$sName,'create_time' => time(),'sort' => $iSort]; + } + } + if(!empty($aCompanyInsert)){ + $company_result = Db::name('article_organ')->insertAll($aCompanyInsert); + if(empty($company_result)){ + return json_encode(['status' => 3,'msg' => 'Article institution insertion failed']); + } + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aCompanyData = Db::name('article_organ')->where($aWhere)->column('sort,organ_id'); + } + //处理作者 + $aAuthorData = $aAuthorOrgn = []; + if(!empty($aParam['author'])){ + $aAuthor = $aParam['author']; + //通讯作者 + $aCorresponding = empty($aParam['corresponding']) ? [] : array_column($aParam['corresponding'], null,'name'); + //查询文章作者 + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aAuthorList = Db::name('article_author')->field('art_aut_id,firstname')->where($aWhere)->select(); + $aAuthorNameList = empty($aAuthorList) ? [] : array_column($aAuthorList, 'firstname'); + foreach ($aAuthor as $key => $value) { + if(empty($iArticleId)){ + break; + } + //处理作者机构单位关联 + if(!empty($value['company_id'])){ + foreach ($value['company_id'] as $k => $v) { + $iNewSort = empty($aSort[$v]) ? $v : $aSort[$v]; + $iOrgnId = empty($aCompanyData[$iNewSort]) ? 0 : $aCompanyData[$iNewSort]; + if(empty($iOrgnId)){ + continue; + } + $aAuthorOrgn[] = ['article_id' => $iArticleId,'organ_id' => $iOrgnId,'art_aut_id' => $value['name']]; + } + } + $value['firstname'] = empty($value['name']) ? '' : trim($value['name']); + //已添加 + if(!empty($value['firstname']) && in_array($value['firstname'], $aAuthorList)){ + continue; + } + $value['email'] = empty($aCorresponding[$value['name']]['email']) ? '' : $aCorresponding[$value['name']]['email']; + $value['article_id'] = $iArticleId; + unset($value['name'],$value['company_id']); + $aAuthorData[$key] = $value; + } + } + if(!empty($aAuthorData)){ + $author_result = DB::name('article_author')->insertAll($aAuthorData); + if(empty($author_result)){ + return json_encode(['status' => 3,'msg' => 'Adding article author failed']); + } + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aAuthorResult = DB::name('article_author')->where($aWhere)->select(); + } + + //作者所属机构 + $aAuthorOrgnInsert = []; + if(!empty($aAuthorOrgn)){ + //查询文章作者所属机构 + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aAuthorOrganList = Db::name('article_author_organ')->field('art_aut_id,organ_id')->where($aWhere)->select(); + $aAuthorOrganIdList = []; + if(!empty($aAuthorOrganList)){ + foreach ($aAuthorOrganList as $key => $value) { + $aAuthorOrganIdList[$value['art_aut_id']][] = $value['organ_id']; + } + } + $aAuthorName = empty($aAuthorResult) ? [] : array_column($aAuthorResult, 'art_aut_id','firstname'); + foreach ($aAuthorOrgn as $key => $value) { + if(empty($value['art_aut_id'])){ + continue; + } + $iAuthorId = empty($aAuthorName[$value['art_aut_id']]) ? 0 : $aAuthorName[$value['art_aut_id']]; + if(empty($iAuthorId)){ + continue; + } + if(!empty($aAuthorOrganIdList[$iAuthorId]) && in_array($value['organ_id'], $aAuthorOrganIdList[$iAuthorId])){ + continue; + } + $value['art_aut_id'] = $iAuthorId; + $aAuthorOrgnInsert[] = $value; + } + } + if(!empty($aAuthorOrgnInsert)){ + $author_orgn_result = DB::name('article_author_organ')->insertAll($aAuthorOrgnInsert); + if(empty($author_orgn_result)){ + return json_encode(['status' => 3,'msg' => 'Adding article author orgn failed']); + } + } + // //处理上传文件 + // if(!empty($sFileUrl) && !empty($iUserId)){ + // $aInsertFile['article_id'] = $iArticleId; + // $aInsertFile['user_id'] = $iUserId; + // $aInsertFile['username'] = empty($aUser['account']) ? '' : $aUser['account']; + // $aInsertFile['file_url'] = trim($sFileUrl,'/'); + // $aInsertFile['type_name'] = 'manuscirpt'; + // $aInsertFile['ctime'] = time(); + // $iFileId = Db::name('article_file')->insertGetId($aInsertFile); + // } + + Db::commit(); + $aInsert['article_id'] = $iArticleId; + return json_encode(['status' => 1,'msg' => 'Successfully added article','article' => $aInsert]); + } + + /** + * 生成文章sn号 + */ + private function getArticleAcceptSn($aParam = [],$sFlag = 'Draft') + { + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return ''; + } + $sDate = date('Y'); + $sType = $sDate; + return $sFlag.$sType.str_pad($iArticleId,6,'0',STR_PAD_LEFT).rand(100,999); + } +} diff --git a/application/api/controller/Finalreview.php b/application/api/controller/Finalreview.php index ff7c965..33a31b6 100644 --- a/application/api/controller/Finalreview.php +++ b/application/api/controller/Finalreview.php @@ -1054,12 +1054,12 @@ class Finalreview extends Base } //查询文章审稿记录 $aWhere = ['article_id' => $iArticleId,'state' => ['between',[1,3]]]; - $aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,state,ctime')->where($aWhere)->select(); + $aArticleReviewer = Db::name('article_reviewer')->field('art_rev_id,state,ctime,reviewer_id')->where($aWhere)->select(); if(!empty($aArticleReviewer)){ $aArtRevId = array_column($aArticleReviewer, 'art_rev_id'); $aWhere = ['art_rev_id' => ['in',$aArtRevId],'state' => 0]; //查询初审问卷 - $aQuestion = Db::name('article_reviewer_question')->field('art_rev_id,ctime,score,rated')->where($aWhere)->order('ctime asc')->select(); + $aQuestion = Db::name('article_reviewer_question')->field('art_rev_id,ctime,score,rated,recommend')->where($aWhere)->order('ctime asc')->select(); $aQuestion = empty($aQuestion) ? [] : array_column($aQuestion, null,'art_rev_id'); //查询复审 @@ -1071,12 +1071,20 @@ class Finalreview extends Base $aReviewerRepeatLists[$value['art_rev_id']][] = $value; } } + + //查询作者信息 + $aUserId = array_unique(array_column($aArticleReviewer, 'reviewer_id')); + $aWhere = ['user_id' => ['in',$aUserId],'state' => 0]; + $aUser = Db::name('user')->where($aWhere)->column('user_id,realname'); + foreach ($aArticleReviewer as $key => $value) { $aQuestionData = empty($aQuestion[$value['art_rev_id']]) ? [] : $aQuestion[$value['art_rev_id']]; $value['ctime'] = empty($aQuestionData['ctime']) ? $value['ctime'] : $aQuestionData['ctime']; $value['score'] = empty($aQuestionData['score']) ? 0 : $aQuestionData['score']; $value['repeat'] = empty($aReviewerRepeatLists[$value['art_rev_id']]) ? [] : $aReviewerRepeatLists[$value['art_rev_id']]; $value['rated'] = empty($aQuestionData['rated']) ? 0 : $aQuestionData['rated']; + $value['realname'] = empty($aUser[$value['reviewer_id']]) ? '' : $aUser[$value['reviewer_id']]; + $value['recommend'] = empty($aQuestionData['recommend']) ? 0 : $aQuestionData['recommend']; $aArticleReviewer[$key] = $value; } } diff --git a/application/api/controller/Organ.php b/application/api/controller/Organ.php new file mode 100644 index 0000000..3c37dba --- /dev/null +++ b/application/api/controller/Organ.php @@ -0,0 +1,218 @@ +request->post() : $aParam; + + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? 0 : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + $aWhere = ['article_id' => $iArticleId,'user_id' => $iUserId,'state' => ['in',[-1,3]]]; + $aArticle = Db::name('article')->field('article_id')->where($aWhere)->find(); + if(empty($aArticle)){ + return json_encode(['status' => 2,'msg' => 'The article does not exist']); + } + if(empty($aArticle)){ + return json_encode(['status' => 2,'msg' => 'The article does not exist']); + } + //查询文章机构 + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aOragn = Db::name('article_organ')->field('organ_id,article_id,organ_name,sort')->where($aWhere)->select(); + return json_encode(['status' => 1,'data' => $aOragn]); + } + /** + * 添加文章机构 + * @param file_url 文件地址 + */ + public function add(){ + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + //机构名称 + $sOrganName = empty($aParam['organ_name']) ? '' : $aParam['organ_name']; + if(empty($sOrganName)){ + return json_encode(['status' => 2,'msg' => 'Please enter the name of the institution']); + } + + $aWhere = ['article_id' => $iArticleId,'user_id' => $iUserId,'state' => ['in',[-1,3]]]; + $aArticle = Db::name('article')->field('article_id')->where($aWhere)->find(); + if(empty($aArticle)){ + return json_encode(['status' => 2,'msg' => 'The article does not exist']); + } + //查询文章机构 + $aWhere = ['article_id' => $iArticleId,'state' => 0,'organ_name' => trim($sOrganName)]; + $aOragn = Db::name('article_organ')->field('organ_id,article_id,organ_name,sort')->where($aWhere)->find(); + if(!empty($aOragn)){ + return json_encode(['status' => 1,'msg' => 'Article organization already exists','data' => $aOragn]); + } + + //插入机构表 + $aWhere = ['article_id' => $iArticleId,'state' => 0]; + $aOragn = Db::name('article_organ')->field('max(sort) as sort')->where($aWhere)->find(); + $iSort = empty($aOragn['sort']) ? 0 : $aOragn['sort']; + $iSort += 1; + $aInsert = ['article_id' => $iArticleId,'organ_name' => $sOrganName,'create_time' => time(),'sort' => $iSort]; + $iId = Db::name('article_organ')->insertGetId($aInsert); + if(empty($iId)){ + return json_encode(['status' => 3,'msg' => 'Failed to add article organization']); + } + $aInsert['organ_id'] = $iId; + return json_encode(['status' => 1,'msg' => 'success','data' => $aInsert]); + } + /** + * 修改文章机构 + * @param file_url 文件地址 + */ + public function modify(){ + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + + //机构名称 + $sOrganName = empty($aParam['organ_name']) ? '' : $aParam['organ_name']; + if(empty($sOrganName)){ + return json_encode(['status' => 2,'msg' => 'Please enter the name of the institution']); + } + + //获取机构ID + $iOrganId = empty($aParam['organ_id']) ? 0 : $aParam['organ_id']; + if(empty($iOrganId)){ + return json_encode(['status' => 2,'msg' => 'Please select the institution to modify']); + } + + //查询文章 + $aWhere = ['article_id' => $iArticleId,'user_id' => $iUserId,'state' => ['in',[-1,3]]]; + $aArticle = Db::name('article')->field('article_id')->where($aWhere)->find(); + if(empty($aArticle)){ + return json_encode(['status' => 2,'msg' => 'The article does not exist']); + } + //查询文章机构 + $aWhere = ['article_id' => $iArticleId,'state' => 0,'organ_id' => $iOrganId]; + $aOragn = Db::name('article_organ')->field('organ_id,article_id,organ_name,sort')->where($aWhere)->find(); + if(empty($aOragn)){ + return json_encode(['status' => 3,'msg' => 'Article organization does not exist','data' => $aOragn]); + } + //查询是否有重名 + $aWhere = ['article_id' => $iArticleId,'state' => 0,'organ_id' => ['<>',$iOrganId],'organ_name' => trim($sOrganName)]; + $aOragn = Db::name('article_organ')->field('organ_id')->where($aWhere)->find(); + if(!empty($aOragn)){ + return json_encode(['status' => 1,'msg' => 'Article organization already exists','data' => $aOragn]); + } + + //更新机构 + $aWhere = ['organ_id' => $iOrganId]; + $aUpdate = ['organ_name' => $sOrganName,'update_time' => time()]; + $result = Db::name('article_organ')->where($aWhere)->limit(1)->update($aUpdate); + if($result === false){ + return json_encode(['status' => 3,'msg' => 'Failed to update article organization']); + } + return json_encode(['status' => 1,'msg' => 'success']); + } + /** + * 删除文章机构 + * @param file_url 文件地址 + */ + public function remove(){ + //获取参数 + $aParam = empty($aParam) ? $this->request->post() : $aParam; + + //获取文章ID + $iArticleId = empty($aParam['article_id']) ? 0 : $aParam['article_id']; + if(empty($iArticleId)){ + return json_encode(['status' => 2,'msg' => 'Please select the article']); + } + //用户ID + $iUserId = empty($aParam['user_id']) ? '' : $aParam['user_id']; + if(empty($iUserId)){ + return json_encode(['status' => 2,'msg' => 'Please select author']); + } + + //获取机构ID + $iOrganId = empty($aParam['organ_id']) ? 0 : $aParam['organ_id']; + if(empty($iOrganId)){ + return json_encode(['status' => 2,'msg' => 'Please select the institution to modify']); + } + + //查询文章 + $aWhere = ['article_id' => $iArticleId,'user_id' => $iUserId,'state' => ['in',[-1,3]]]; + $aArticle = Db::name('article')->field('article_id')->where($aWhere)->find(); + if(empty($aArticle)){ + return json_encode(['status' => 2,'msg' => 'The article does not exist']); + } + //查询文章机构 + $aWhere = ['article_id' => $iArticleId,'state' => 0,'organ_id' => $iOrganId]; + $aOragn = Db::name('article_organ')->field('organ_id,article_id,organ_name,sort')->where($aWhere)->find(); + if(empty($aOragn)){ + return json_encode(['status' => 3,'msg' => 'Article organization does not exist','data' => $aOragn]); + } + + //作者关联的机构 + $aWhere = ['organ_id' => $iOrganId,'article_id' => $iArticleId,'state' => 0]; + $aId = Db::name('article_author_organ')->where($aWhere)->column('id'); + + //删除机构 + Db::startTrans(); + //更新机构状态 + $aWhere = ['organ_id' => $iOrganId]; + $aUpdate = ['state' => 1,'update_time' => time()]; + $result = Db::name('article_organ')->where($aWhere)->limit(1)->update($aUpdate); + if($result === false){ + return json_encode(['status' => 3,'msg' => 'Failed to update article organization']); + } + //更新作者关联的机构 + if(!empty($aId)){ + $aWhere = ['id' => ['in',$aId],'state' => 0]; + $aUpdate = ['state' => 1,'update_time' => time()]; + $author_organ_result = Db::name('article_author_organ')->where($aWhere)->limit(count($aId))->update($aUpdate); + if($author_organ_result === false){ + return json_encode(['status' => 3,'msg' => 'Failed to unbind the relationship between the institution and the author']); + } + } + Db::commit(); + return json_encode(['status' => 1,'msg' => 'success']); + } +} diff --git a/application/api/controller/Reviewer.php b/application/api/controller/Reviewer.php index 70663c7..08d1bff 100644 --- a/application/api/controller/Reviewer.php +++ b/application/api/controller/Reviewer.php @@ -617,7 +617,7 @@ class Reviewer extends Base $data = $this->request->post(); //查询实例数据 - $res = $this->article_reviewer_obj->field('t_journal.*,t_article_reviewer.*,t_article.abstrart,t_article.title article_title,t_article.type atype,t_article.state astate,t_article.accept_sn accept_sn,t_user.account account') + $res = $this->article_reviewer_obj->field('t_journal.*,t_article_reviewer.*,t_article.abstrart,t_article.title article_title,t_article.type atype,t_article.state astate,t_article.accept_sn accept_sn,t_user.account account,t_user.email as user_email') ->join('t_article', 't_article.article_id = t_article_reviewer.article_id', 'LEFT') ->join('t_user', 't_user.user_id = t_article_reviewer.reviewer_id', 'LEFT') ->join('t_journal', 't_journal.journal_id = t_article.journal_id', 'left') diff --git a/application/api/controller/Ucenter.php b/application/api/controller/Ucenter.php index 6ba6e8f..915bc16 100644 --- a/application/api/controller/Ucenter.php +++ b/application/api/controller/Ucenter.php @@ -198,6 +198,8 @@ class Ucenter extends Base{ //发送邮件给编辑 $vv = "Dear editor,

"; $vv .= "Please check the new application for Young Scientist Board Member for ".$journal_info['title']." Journal."; + $sUserEmail = empty($user_info['email']) ? '' : $user_info['email']; + $vv .= "
please check applied email:".$sUserEmail; $mai['email'] = $editor_info['email']; $mai['title'] = $journal_info['title']; $mai['content'] = $vv; diff --git a/application/api/controller/User.php b/application/api/controller/User.php index 92485b2..674a3ac 100644 --- a/application/api/controller/User.php +++ b/application/api/controller/User.php @@ -1083,7 +1083,7 @@ class User extends Base ->join("t_journal",'t_journal.journal_id = t_apply_yboard.journal_id','left') ->join("t_user","t_user.user_id = t_apply_yboard.user_id",'left') ->join("t_user_reviewer_info","t_user_reviewer_info.reviewer_id = t_user.user_id",'left') - ->where('t_apply_yboard.journal_id','in',$ids)->where('t_apply_yboard.state',0)->select(); + ->where('t_apply_yboard.journal_id','in',$ids)->where('t_apply_yboard.state',0)->order('t_apply_yboard.ctime desc')->select(); foreach($list as $k => $v){//补充简历信息 $cac = $this->user_cv_obj->where('user_id',$v['user_id'])->where('state',0)->select(); $list[$k]['cvs'] = $cac; diff --git a/application/api/controller/Web.php b/application/api/controller/Web.php index eafe438..44a6536 100644 --- a/application/api/controller/Web.php +++ b/application/api/controller/Web.php @@ -407,7 +407,7 @@ class Web extends Base { $ca_board = []; $boards = $this->board_to_journal_obj - ->field("t_board_to_journal.*,t_board_group.group_name,t_user.account,t_user.email,t_user.realname,t_user.icon,t_user.google_index,t_user.google_time,t_user.wos_index,t_user.wos_time,t_user_reviewer_info.*") + ->field("t_board_to_journal.btj_id,t_board_to_journal.user_id,t_board_to_journal.board_group_id,t_board_to_journal.journal_id,t_board_to_journal.type,t_board_to_journal.research_areas,t_board_to_journal.realname as board_realname,t_board_to_journal.email as board_email,t_board_to_journal.website as board_website,t_board_to_journal.affiliation as board_affiliation,t_board_to_journal.icon as board_icon,t_board_to_journal.technical as board_technical,t_board_to_journal.remark,t_board_to_journal.state,t_board_group.group_name,t_user.account,t_user.email,t_user.realname,t_user.icon,t_user.google_index,t_user.google_time,t_user.wos_index,t_user.wos_time,t_user_reviewer_info.*") ->join("t_board_group", "t_board_group.board_group_id = t_board_to_journal.board_group_id", "left") ->join("t_user", "t_user.user_id = t_board_to_journal.user_id", "left") ->join("t_user_reviewer_info", "t_user_reviewer_info.reviewer_id=t_board_to_journal.user_id", "left") @@ -415,7 +415,6 @@ class Web extends Base ->where('t_board_to_journal.state', 0) ->order("t_board_group.board_group_id asc,t_user.realname") ->select(); - foreach ($boards as $val) { if ($aar) { $article1 = $this->article_obj->where('user_id', $val['user_id'])->where('journal_id', $val['journal_id'])->where('state', 5)->where('ctime', ">", strtotime("-1 year"))->select(); @@ -431,6 +430,15 @@ class Web extends Base $val['reviewes'] = $reviewes; } + //编委数据隔离加默认数据 chengxiaoling 20251022 start + $val['realname'] = empty($val['board_realname']) ? $val['realname'] : $val['board_realname']; + $val['email'] = empty($val['board_email']) ? $val['email'] : $val['board_email']; + $val['technical'] = empty($val['board_technical']) ? $val['technical'] : $val['board_technical']; + $val['website'] = empty($val['board_website']) ? $val['website'] : $val['board_website']; + $val['icon'] = empty($val['board_icon']) ? $val['icon'] : $val['board_icon']; + $val['company'] = empty($val['board_affiliation']) ? $val['company'] : $val['board_affiliation']; + //编委数据隔离加默认数据 chengxiaoling 20251022 end + if ($val['type'] == 0) {//主编 $ca_board['main'][] = $val; } elseif ($val['type'] == 1) {//副主编 diff --git a/application/common/Aireview.php b/application/common/Aireview.php index 41b2271..d18aea0 100644 --- a/application/common/Aireview.php +++ b/application/common/Aireview.php @@ -46,7 +46,7 @@ class Aireview $iLogId = empty($aAiReview['id']) ? 0 : $aAiReview['id']; //新增 if(empty($iLogId)){ - $aInsert['create_time'] = date('Y-m-d H:i:s'); + $aInsert['create_time'] = time(); $aInsert['content'] = $iArticleId; $iLogId = Db::name('article_ai_review')->insertGetId($aInsert); if(empty($iLogId)){ @@ -57,7 +57,7 @@ class Aireview } if(!empty($iLogId)){ $aWhere = ['id' => $iLogId]; - $aInsert['update_time'] = date('Y-m-d H:i:s'); + $aInsert['update_time'] = time(); if(!Db::name('article_ai_review')->where($aWhere)->limit(1)->update($aInsert)){ $aResult = ['status' => 5,'msg' => 'Failed to add AI audit content']; } @@ -81,6 +81,21 @@ class Aireview //查询文章审核内容 $aWhere = ['article_id' => $aParam['article_id']]; $aAiReview = Db::name('article_ai_review')->where($aWhere)->find(); + if(!empty($aAiReview)){ + $sCreateTime = empty($aAiReview['create_time']) ? '' : $aAiReview['create_time']; + if(!empty($sCreateTime)){ + $aAiReview['create_time'] = strtotime($sCreateTime) !== false ? $sCreateTime : date('Y-m-d H:i:s',$sCreateTime); + }else{ + $aAiReview['create_time'] = ''; + } + + $sUpdateTime = empty($aAiReview['update_time']) ? '' : $aAiReview['update_time']; + if(!empty($sUpdateTime)){ + $aAiReview['update_time'] = strtotime($sUpdateTime) !== false ? $sUpdateTime : date('Y-m-d H:i:s',$sUpdateTime); + }else{ + $aAiReview['update_time'] = ''; + } + } return ['status' => 1,'msg' => 'Successfully obtained article review content','data' => $aAiReview]; } diff --git a/application/common/ArticleParserService.php b/application/common/ArticleParserService.php new file mode 100644 index 0000000..7cd305e --- /dev/null +++ b/application/common/ArticleParserService.php @@ -0,0 +1,764 @@ +setReadDataOnly(false); + Settings::setCompatibility(false); + Settings::setOutputEscapingEnabled(true); // 避免XML转义冲突 + + $doc = $reader->load($filePath); + $sectionCount = count($doc->getSections()); + // $this->log("✅ 文档直接加载成功,节数量:{$sectionCount}"); + $this->phpWord = $reader->load($filePath); + $this->sections = $this->phpWord->getSections(); + + } catch (\Exception $e) { + return json(['status' => 'error', 'msg' => $e->getMessage()]); + } + } + + // 上传并解析文档的入口方法 + public static function uploadAndParse($sFileUrl){ + //必填值验证 + if(empty($sFileUrl)){ + return json_encode(['status' => 2,'msg' => 'Please upload the submission file']); + } + + //判断文件是否执行 + if (!file_exists($sFileUrl)) { + return json_encode(['status' => 3, 'msg' => 'The uploaded file does not exist']); + } + if (!is_readable($sFileUrl)) { + return json_encode(['status' => 4, 'msg' => 'The uploaded file is unreadable']); + } + + // 解析文档 + $oDealFile = new self($sFileUrl); + //获取标题 + $sTitle = $oDealFile->getTitle(); + if(empty($sTitle)){ + return json_encode(['status' => 5, 'msg' => 'Article title retrieval failed']); + } + //获取作者 + $aParam = ['title' => $sTitle]; + $aAuthor = $oDealFile->getAuthors($aParam); + $aAuthorData = empty($aAuthor['author']) ? [] : $aAuthor['author'];//所有作者信息 + $aAuthorReportData = empty($aAuthor['report']) ? [] : $aAuthor['report'];//通讯作者信息 + $aParam['author'] = $aAuthorData; + $aParam['report'] = $aAuthorReportData; + //获取机构 + $aCompany = $oDealFile->getCompany($aParam); + $aParam['company'] = $aCompany; + //获取通讯作者信息 + $aParam['corresponding'] = $oDealFile->getCorrespondingAuthors($aParam); + //keywords 和 摘要 + $aContent = $oDealFile->extractFromWord(); + $aParam += empty($aContent['data']) ? [] : $aContent['data']; + return json_encode(['status' => 1,'msg' => 'success','data' => $aParam]); + } + + // 提取文章标题 + private function getTitle(){ + $title = ''; + $maxLength = 0; + + foreach ($this->sections as $section) { + foreach ($section->getElements() as $element) { + $text = $this->getTextFromElement($element); + $length = mb_strlen(trim($text)); + if ($length > $maxLength && $length > 10) { // 标题通常较长 + $title = trim($text); + $maxLength = $length; + break 2; // 取第一个最长段落作为标题 + } + } + } + return $title; + } + // 提取作者 + // private function getAuthors($aParam = []) { + // $title = empty($aParam['title']) ? $this->getTitle() : $aParam['title']; + // $sAuthorContent = $this->getNextParagraphAfterText($title); + // if (empty($sAuthorContent)) { + // return ['author' => [], 'report' => []]; + // } + + // //编码修复 + // $possibleEncodings = [ + // 'Windows-1252', 'UTF-8', 'GBK', 'GB2312', + // 'Latin-1', 'ISO-8859-1', 'CP1252' + // ]; + // $encodedContent = @mb_convert_encoding($sAuthorContent, 'UTF-8', implode(',', $possibleEncodings)); + // $sAuthorContent = $encodedContent ?: $sAuthorContent; + + // //清理不可见字符 + // $sAuthorContent = preg_replace('/[\x00-\x1F\x7F\x{200B}-\x{200F}]/u', '', $sAuthorContent); + + // //修复特殊符号乱码 + // $symbolMap = [ + // '†' => '†', 'â ' => '†', 'â' => '†', '?†' => '†', + // ':' => ':', ',' => ',', '—' => '-', + // '啊' => '' // 针对性移除异常字符“啊”(若为固定乱码) + // ]; + // $sAuthorContent = strtr($sAuthorContent, $symbolMap); + + // //格式标准化 + // $sAuthorContent = str_replace([',', ';', ';', '、'], ',', $sAuthorContent); // 统一分隔符 + // $sAuthorContent = preg_replace('/\s+and\s+/i', ', ', $sAuthorContent); // and转逗号 + // $sAuthorContent = preg_replace('/\s+/', ' ', $sAuthorContent); // 合并多余空格 + // $sAuthorContent = trim($sAuthorContent); + + // // 处理作者 + // $content = mb_convert_encoding($sAuthorContent, 'UTF-8', 'auto'); // 确保编码正确 + // $content = str_replace("\xC2\xA0", ' ', $content); // 替换非-breaking空格为普通空格 + // $content = preg_replace('/(\d+)\s*([*#†])/', '$1$2', $content); // 合并"1 *"为"1*"、"1 #"为"1#" + // $content = preg_replace('/,†/', ',†', $content); // 保留"1,†"格式(防止被拆分) + // //标记上标内的逗号+空格(多编号) + // $tempStr = preg_replace('/(\d+)\s*,\s*(\d+)/', '$1$2', $content); + // // 原有步骤2:正则匹配(扩展上标符号支持,保持原有逻辑) + // $pattern = '/ + // ([A-Za-z\s\.\-]+?) # 姓名(支持缩写、空格) + // \s* # 姓名与上标间空格 + // ( # 上标组(扩展符号支持) + // \d+ # 起始数字 + // (?:[†#*,]|\d+)* # 允许:†#*符号、逗号、+数字(兼容1,†、1,*等) + // ) + // \s*,? # 作者间逗号(可选) + // (?=\s|$) # 确保后面是空格或结尾 + // /ux'; + + // preg_match_all($pattern, $tempStr, $matches); + // $authorList = []; + // if(!empty($matches[1])){ + // foreach ($matches[1] as $i => $name) { + // $name = trim($name); + // $superscript = trim($matches[2][$i]); + // $superscript = str_replace('', ',', $superscript); // 恢复多编号逗号 + // $superscript = preg_replace('/,$/', '', $superscript); // 清理末尾逗号 + // // 修复符号与数字间的空格(如原始"1 *"被误处理为"1*"的情况,保持原样) + // $superscript = preg_replace('/(\d)([*#†])/', '$1$2', $superscript); + // if (!empty($name)) { + // $authorList[] = [ + // 'name' => $name, + // 'superscript' => $superscript + // ]; + // } + // } + // }else { + // // 按“两个或多个连续空格”拆分(姓名之间的分隔) + // $authorList = array_filter( + // array_map('trim', + // preg_split('/(,\p{Z}*|\p{Z}{2,})/u', $sAuthorContent) + // ) + // ); + // } + + + // // //处理作者 + // // $authorList = []; + // // // 新正则:匹配“姓名+上标”整体,允许上标含逗号(如1,†) + // // // 逻辑:姓名以字母/中文开头,上标以数字开头、以符号/数字结尾 + // // // if (preg_match_all('/([A-Za-z\x{4e00}-\x{9fa5}][A-Za-z\s·\-\'\x{4e00}-\x{9fa5}]*)\s*([\d,†#*]+)/u', $sAuthorContent, $matches)) { + // // if(preg_match_all('/([A-Za-z\x{4e00}-\x{9fa5}][A-Za-z\s·\-\'\x{4e00}-\x{9fa5}]*)\s*(\d[\d,†#\s*]*)/u', $sAuthorContent, $matches)){ + // // for ($i = 0; $i < count($matches[1]); $i++) { + // // $authorList[] = trim($matches[1][$i] . $matches[2][$i]); + // // } + // // } else { + // // // 按“两个或多个连续空格”拆分(姓名之间的分隔) + // // $authorList = array_filter( + // // array_map('trim', + // // preg_split('/(,\p{Z}*|\p{Z}{2,})/u', $sAuthorContent) + // // ) + // // ); + // // } + // $aAuthorData = []; + // $aReport = []; + // $namePattern = '/ + // (?:[A-Za-z\s·\-\']+| # 英文姓名(支持空格、连字符) + // [\x{4e00}-\x{9fa5}]+| # 中文姓名 + // [\x{1800}-\x{18AF}]+| # 蒙古文姓名 + // [A-Z]\.) # 单字母缩写(如 J.) + // /ux'; + // var_dump($authorList);exit; + // foreach ($authorList as $authorStr) { + // if (empty($authorStr)) continue; + // var_dump($authorList);exit; + // //分离姓名与上标(支持上标含逗号,如1,†) + // $superscript = ''; + // // 新正则:匹配以数字开头、含逗号/符号的完整上标(如1,†、2*#) + // $authorStr = trim(trim($authorStr,','),' '); + // // if (preg_match('/([\d,†#*]+)$/u', $authorStr, $supMatch)) { + // // if(preg_match('/\s*([\d,†#* ]+)$/u', $authorStr, $supMatch)){ + // // if (preg_match('/.*?\s*([\d,†#* ]+)$/u', $authorStr, $supMatch)) { + // // if (preg_match('/.*?\s*([\d,\x{2020}#* ]+?)\s*$/u', $authorStr, $supMatch)) { + // // if (preg_match('/^(.+?)\D*?(\d[\d,#*†,\s]*)$/u', $authorStr, $supMatch)) { + // // $superscript = $supMatch[1]; + // // // 移除上标,保留纯姓名(避免残留符号) + // // $nameStr = trim(preg_replace('/' . preg_quote($superscript, '/') . '$/', '', $authorStr)); + // // } else { + // // $nameStr = $authorStr; + // // } + // $pattern = '/^(.+?)\s*(\d[\d,#*†\s]*?)\s*$/u'; + // if (preg_match($pattern, $authorStr, $supMatch)) { + // $nameStr = empty($supMatch[1]) ? '' : trim($supMatch[1]); // 姓名部分:"Liguo Zhang" + // $superscript = empty($supMatch[2]) ? $nameStr : $nameStr.trim($supMatch[2]); // 上标部分:"1 + // // echo "姓名: $nameStr, 上标: $superscript\n"; + // } else { + // $nameStr = $authorStr; + // } + // //验证姓名合法性(过滤无效内容) + // if (!preg_match($namePattern, $nameStr)) { + // continue; + // } + // //解析上标信息(正确识别1,†中的机构编号和符号) + // $companyId = ''; + // $isSuper = 0; + // $isReport = 0; + // if (!empty($superscript)) { + // // 提取机构编号(忽略上标中的逗号,如1,† → 提取1) + // if (preg_match('/(\d+)/', $superscript, $numMatch)) { + // $companyId = $numMatch[1]; + // } + // // 识别特殊符号(#为超级作者,*†为通讯作者) + // $isSuper = strpos($superscript, '#') !== false ? 1 : 0; + // $isReport = (strpos($superscript, '*') !== false || strpos($superscript, '†') !== false) ? 1 : 0; + // } + // if (preg_match("/^([A-Za-z\s'\.-]+)/u", $nameStr, $match)) { + // $nameStr = trim($match[1]); + // } + // $aAuthorData[] = [ + // 'name' => $nameStr, + // 'company_id' => $companyId, + // 'is_super' => $isSuper, + // 'is_report' => $isReport + // ]; + // if ($isReport) { + // $aReport[] = $nameStr; + // } + // } + // var_dump($aAuthorData);exit; + // return ['author' => $aAuthorData,'report' => array_unique($aReport)]; + // } + private function getAuthors($aParam = []) { + $title = empty($aParam['title']) ? $this->getTitle() : $aParam['title']; + $sAuthorContent = $this->getNextParagraphAfterText($title); + if (empty($sAuthorContent)) { + return ['author' => [], 'report' => []]; + } + + //编码修复 + $possibleEncodings = [ + 'Windows-1252', 'UTF-8', 'GBK', 'GB2312', + 'Latin-1', 'ISO-8859-1', 'CP1252' + ]; + $encodedContent = @mb_convert_encoding($sAuthorContent, 'UTF-8', implode(',', $possibleEncodings)); + $sAuthorContent = $encodedContent ?: $sAuthorContent; + + //清理不可见字符 + $sAuthorContent = preg_replace('/[\x00-\x1F\x7F\x{200B}-\x{200F}]/u', '', $sAuthorContent); + + //修复特殊符号乱码 + $symbolMap = [ + '†' => '†', 'â ' => '†', 'â' => '†', '?†' => '†', + ':' => ':', ',' => ',', '—' => '-', + '啊' => '' // 针对性移除异常字符“啊”(若为固定乱码) + ]; + $sAuthorContent = strtr($sAuthorContent, $symbolMap); + + //格式标准化 + $sAuthorContent = str_replace([',', ';', ';', '、'], ',', $sAuthorContent); // 统一分隔符 + $sAuthorContent = preg_replace('/\s+and\s+/i', ', ', $sAuthorContent); // and转逗号 + $sAuthorContent = preg_replace('/\s+/', ' ', $sAuthorContent); // 合并多余空格 + $sAuthorContent = trim($sAuthorContent); + + // 处理作者 + $content = mb_convert_encoding($sAuthorContent, 'UTF-8', 'auto'); // 确保编码正确 + $content = str_replace("\xC2\xA0", ' ', $content); // 替换非-breaking空格为普通空格 + $content = preg_replace('/(\d+)\s*([*#†])/', '$1$2', $content); // 合并"1 *"为"1*"、"1 #"为"1#" + $content = preg_replace('/,†/', ',†', $content); // 保留"1,†"格式(防止被拆分) + //标记上标内的逗号+空格(多编号) + $tempStr = preg_replace('/(\d+)\s*,\s*(\d+)/', '$1$2', $content); + // 原有步骤2:正则匹配(扩展上标符号支持,保持原有逻辑) + $pattern = '/ + ([A-Za-z\s\.\-]+?) # 姓名(支持缩写、空格) + \s* # 姓名与上标间空格 + ( # 上标组(扩展符号支持) + \d+ # 起始数字 + (?:[†#*,]|\d+)* # 允许:†#*符号、逗号、+数字(兼容1,†、1,*等) + ) + \s*,? # 作者间逗号(可选) + (?=\s|$) # 确保后面是空格或结尾 + /ux'; + + preg_match_all($pattern, $tempStr, $matches); + $authorList = []; + if(!empty($matches[1])){ + foreach ($matches[1] as $i => $name) { + $name = trim($name); + $superscript = trim($matches[2][$i]); + $superscript = str_replace('', ',', $superscript); // 恢复多编号逗号 + $superscript = preg_replace('/,$/', '', $superscript); // 清理末尾逗号 + // 修复符号与数字间的空格(如原始"1 *"被误处理为"1*"的情况,保持原样) + $superscript = preg_replace('/(\d)([*#†])/', '$1$2', $superscript); + if (!empty($name)) { + $authorList[] = [ + 'name' => $name, + 'superscript' => $superscript + ]; + } + } + }else { + // 按“两个或多个连续空格”拆分(姓名之间的分隔) + $authorList = array_filter( + array_map('trim', + preg_split('/(,\p{Z}*|\p{Z}{2,})/u', $sAuthorContent) + ) + ); + } + + + // //处理作者 + $aAuthorData = []; + $aReport = []; + $namePattern = '/ + (?:[A-Za-z\s·\-\']+| # 英文姓名(支持空格、连字符) + [\x{4e00}-\x{9fa5}]+| # 中文姓名 + [\x{1800}-\x{18AF}]+| # 蒙古文姓名 + [A-Z]\.) # 单字母缩写(如 J.) + /ux'; + + foreach ($authorList as $authorStr){ + if (empty($authorStr)) continue; + + //获取下标 + $superscript = empty($authorStr['superscript']) ? $authorStr : $authorStr['superscript']; + $nameStr = empty($authorStr['name']) ? $authorStr : $authorStr['name']; + + $companyId = []; + $isSuper = 0; + $isReport = 0; + if (!empty($superscript)) { + // 提取机构编号(忽略上标中的逗号,如1,† → 提取1) + preg_match_all('/\d+/', $superscript, $numMatch); + // 识别特殊符号(#为超级作者,*†为通讯作者) + $isSuper = strpos($superscript, '#') !== false ? 1 : 0; + $isReport = (strpos($superscript, '*') !== false || strpos($superscript, '†') !== false) ? 1 : 0; + } + if (preg_match("/^([A-Za-z\s'\.-]+)/u", $nameStr, $match)) { + $nameStr = trim($match[1]); + } + $aAuthorData[] = [ + 'name' => $nameStr, + 'company_id' => empty($numMatch[0]) ? [] : $numMatch[0], + 'is_super' => $isSuper, + 'is_report' => $isReport + ]; + if ($isReport) { + $aReport[] = $nameStr; + } + } + return ['author' => $aAuthorData,'report' => array_unique($aReport)]; + } + + // 获取机构 + private function getCompany($aParam = []){ + //获取标题 + $title = empty($aParam['title']) ? $this->getTitle() : $aParam['title']; + //获取标题下的作者 + $sAuthorContent = empty($aParam['authors']) ? $this->getNextParagraphAfterText($title) : $aParam['authors']; + //获取作者结构 + $sCompany = $this->getContentAfterText($sAuthorContent); + if(empty($sCompany)){ + return []; + } + //编码修复 + $possibleEncodings = [ + 'Windows-1252', 'UTF-8', 'GBK', 'GB2312', + 'Latin-1', 'ISO-8859-1', 'CP1252' + ]; + $encodedContent = @mb_convert_encoding($sCompany, 'UTF-8', implode(',', $possibleEncodings)); + $sCompany = $encodedContent ?: $sCompany; + //按行拆分,保留数字开头的行 + $sCompany = str_replace(["\r\n", "\r"], "\n", $sCompany); + $aCompanyLines = explode("\n", $sCompany); + $aCompanyLines = array_filter(array_map('trim', $aCompanyLines), function($line) { + return preg_match('/^\d+/', $line); // 仅保留数字开头的行 + }); + + $aCompany = []; + foreach ($aCompanyLines as $line) { + if (preg_match('/^(\d+)\s*(.+)$/', $line, $match)) { + if(empty($match[1]) || empty($match[2])){ + continue; + } + $aCompany[$match[1]] = ltrim(trim(ltrim($match[2]),'.'),' '); + } + } + return $aCompany; + } + + // 提取通讯作者(含E-mail、地址、电话) + private function getCorrespondingAuthors($aParam = []){ + $aCorrespondingAuthor = empty($aParam['report']) ? [] : $aParam['report']; + if(empty($aCorrespondingAuthor)){ + return []; + } + + // 获取标题 + $title = empty($aParam['title']) ? $this->getTitle() : $aParam['title']; + $sAuthorContent = $this->getNextParagraphAfterText($title); + $sCompany = $this->getNextParagraphAfterText($sAuthorContent); // 直接取机构所在段落的原始文本 + if (empty($sCompany)) { + // 备选方案:若机构段落获取失败,用解析后的机构名称拼接 + $aCompany = $this->getCompany($aParam); + $sCompany = implode(' ', array_values($aCompany)); + } + + // 获取机构后的完整内容 + $corrText = $this->getContentAfterText($sCompany); + //编码修复 + $possibleEncodings = [ + 'Windows-1252', 'UTF-8', 'GBK', 'GB2312', + 'Latin-1', 'ISO-8859-1', 'CP1252' + ]; + $encodedContent = @mb_convert_encoding($corrText, 'UTF-8', implode(',', $possibleEncodings)); + $corrText = $encodedContent ?: $corrText; + // // 调试 + // file_put_contents(ROOT_PATH . 'runtime/corr_text_raw.log', $corrText); + + //清理文本 + $corrText = str_replace([':', '@'], [':', '@'], $corrText); + $corrText = preg_replace('/\s+/', ' ', $corrText); // 统一空格 + $corrText = str_replace(' ', ' ', $corrText); // 去除多余空格 + + //按"*"分割通讯作者 + $corrBlocks = preg_split('/\s*\*\s*/', $corrText); + $corrBlocks = array_filter(array_map('trim', $corrBlocks)); + + $aCorresponding = []; + foreach ($corrBlocks as $block) { + //匹配通讯作者姓名 + $sName = $this->matchCorrespondingName($block, $aCorrespondingAuthor); + if (empty($sName)) { + continue; + } + preg_match('/(E[\s-]*mail|邮箱)[\s:]*([^\s]+@[^\s]+)/i', $block, $email); + preg_match('/(Postal[\s-]*address|地址)[\s:]*([^,;]+)/i', $block, $address); + preg_match('/(Tel|电话)[\s:]*([^\s]+)/i', $block, $tel); + + $aCorresponding[] = [ + 'name' => $sName, + 'email' => isset($email[2]) ? trim($email[2]) : '', + 'postal_address' => isset($address[2]) ? trim($address[2]) : '', + 'tel' => isset($tel[2]) ? trim($tel[2]) : '' + ]; + } + return $aCorresponding; + } + + //匹配通讯作者姓名 + private function matchCorrespondingName($block, $corrNames) + { + $blockLower = strtolower($block); + foreach ($corrNames as $name) { + if (strpos($blockLower, strtolower($name)) !== false) { + return $name; + } + $nameParts = explode(' ', $name); + if (count($nameParts) >= 2) { + $reversedName = implode(' ', array_reverse($nameParts)); + if (strpos($blockLower, strtolower($reversedName)) !== false) { + return $name; + } + } + } + return ''; + } + + // 获取目标文本的下一个段落 + private function getNextParagraphAfterText($targetText){ + + $found = false; + foreach ($this->sections as $section) { + foreach ($section->getElements() as $element) { + $text = $this->getTextFromElement($element); + if(empty($text)){ + continue; + } + if ($found) { + return $text; + } + if (stripos($text, $targetText) !== false) { + $found = true; + } + } + } + return ''; + } + + // 获取目标文本后的所有内容 + private function getContentAfterText($targetText){ + $found = false; + $content = []; + $stopKeywords = ['关键词', 'Key words', '摘要', 'Abstract']; + $maxLines = 200; + $lineNumber = 0; + foreach ($this->sections as $section) { + + foreach ($section->getElements() as $element) { + + $lineNumber++; + if (count($content) >= $maxLines) break; + + $text = $this->getTextFromElement($element,$lineNumber); + $text = trim($text); + if (empty($text)) continue; + if (!$found) { + // 移除所有非字母数字字符后匹配 + $cleanTarget = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($targetText)); + $cleanText = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($text)); + // 只要目标文本的50%以上能匹配即可 + if (strlen($cleanTarget) > 0 && similar_text($cleanText, $cleanTarget) / strlen($cleanTarget) > 0.5) { + $found = true; + } + continue; + } + + // 检查停止关键词 + $shouldStop = false; + foreach ($stopKeywords as $kw) { + if (stripos($text, $kw) !== false) { + $shouldStop = true; + break; + } + } + if ($shouldStop) break; + + $content[] = $text; + } + if (count($content) >= $maxLines || (isset($shouldStop) && $shouldStop)) break; + } + return implode("\n", $content); + } + + // 统一提取元素文本 + private function getTextFromElement($element,$lineNumber = 0){ + $text = ''; + // 处理PreserveText元素 + if ($element instanceof \PhpOffice\PhpWord\Element\PreserveText) { + // 通过反射获取私有属性 text + $reflection = new \ReflectionClass($element); + $property = $reflection->getProperty('text'); + $property->setAccessible(true); + $textParts = $property->getValue($element); + foreach ($textParts as $part) { + if (strpos($part, 'HYPERLINK') !== false) { + // 解码 HTML 实体(" -> ") + $decoded = html_entity_decode($part); + // 提取 mailto: 后的邮箱 + if (preg_match('/mailto:([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/i', $decoded, $match)) { + $text .= $match[1] . ' '; + } + } else { + // 普通文本直接拼接 + $text .= $part; + } + } + return $text; + } + // 处理表格和单元格(E-mail可能在表格中) + if ($element instanceof \PhpOffice\PhpWord\Element\Table) { + foreach ($element->getRows() as $row) { + foreach ($row->getCells() as $cell) { + $text .= $this->getTextFromElement($cell); + } + } + return $text; + } + if ($element instanceof \PhpOffice\PhpWord\Element\Cell) { + foreach ($element->getElements() as $child) { + $text .= $this->getTextFromElement($child); + } + return $text; + } + + //处理嵌套元素(递归提取所有子元素) + if (method_exists($element, 'getElements')) { + foreach ($element->getElements() as $child) { + $text .= $this->getTextFromElement($child); + } + } + + //处理文本元素(包括带格式的文本) + if ($element instanceof \PhpOffice\PhpWord\Element\Text) { + $text .= $element->getText(); + } + + //处理超链接(优先提取链接目标,可能是邮箱) + if ($element instanceof \PhpOffice\PhpWord\Element\Link) { + $target = $element->getTarget(); + if (strpos($target, 'mailto:') === 0) { + $text .= str_replace('mailto:', '', $target) . ' '; // 剥离mailto:前缀 + } + $text .= $element->getText() . ' '; + } + + //处理字段和注释(可能包含隐藏邮箱) + if ($element instanceof \PhpOffice\PhpWord\Element\Field) { + $text .= $element->getContent() . ' '; + } + if ($element instanceof \PhpOffice\PhpWord\Element\Note) { + $text .= $element->getContent() . ' '; + } + //清理所有不可见字符(关键:移除格式干扰) + $text = preg_replace('/[\x00-\x1F\x7F-\x9F]/', ' ', $text); // 移除控制字符 + $text = str_replace(["\t", "\r", "\n"], ' ', $text); // 统一空白字符 + $text = preg_replace('/\s+/', ' ', $text); // 合并多个空格 + + return $text; + } + + /** + * 从 Word 文档提取摘要和关键词 + * @return array 提取结果 + */ + public function extractFromWord() { + $sContent = ''; + //文本处理 + $sFundContent = ''; + foreach ($this->sections as $section) { + foreach ($section->getElements() as $element) { + $textContent = $this->getTextFromElement($element); + if(empty($textContent)){ + continue; + } + //编码修复 + $possibleEncodings = [ + 'Windows-1252', 'UTF-8', 'GBK', 'GB2312', + 'Latin-1', 'ISO-8859-1', 'CP1252' + ]; + $sContent .= @mb_convert_encoding($textContent, 'UTF-8', implode(',', $possibleEncodings)); + if(stripos($textContent, 'Keywords:') !== false){ + $sContent .= "Keywords-End-Flag"; + } + if(empty($sFundContent)){ + $aFund = $this->getMatchedFundPhrases($sContent); + if(!empty($aFund[0])){ + $position = stripos($sContent, $aFund[0]); + $sFundContent = substr($sContent, $position); + $sFundContent = trim(str_ireplace($aFund[0], '', $sFundContent)); + if (preg_match('/^(.*?)Peer review/', $sFundContent, $matches)) { + $sFundContent = $matches[1]; // 提取匹配到的前置内容 + } + } + } + $sContent .= "\n"; + } + } + // 2. 基础文本清理(合并多余空格,保留有效换行) + $textContent = preg_replace('/(\S)\s+/', '$1 ', $sContent); + $textContent = trim($textContent); + + // 3. 提取摘要 + $abstract = ''; + $abstractPattern = '/Abstract\s*([\s\S]*?)(?=Keywords:|$)/i'; + if (preg_match($abstractPattern, $textContent, $abstractMatches)) { + $abstract = trim($abstractMatches[1]); + $abstract = preg_replace('/\n+/', ' ', $abstract); + } + // 4. 提取关键词(核心:仅保留两种强制匹配逻辑) + $keywords = []; + // $keywordPattern = '/Keywords:\s*([\s\S]*?)(?=\s*\d+\.|[;,]\s*[\r\n]+\s*[\r\n]+|(?i)\bintroduction|abbreviations\b|$)/i'; + $keywordPattern = '/Keywords:\s*(.*?)\s*Keywords-End-Flag/s'; + if (preg_match($keywordPattern, $textContent, $keywordMatches)) { + $keywordStr = trim($keywordMatches[1]); + + // 清理关键词列表格式(去除换行、末尾多余符号) + $keywordStr = preg_replace('/\n+/', ' ', $keywordStr); + $keywordStr = rtrim($keywordStr, ';,. '); // 去除末尾分号、逗号等 + $keywordStr = trim($keywordStr); + + // 分割并过滤有效关键词 + $keywords = preg_split('/[,;]\s*/', $keywordStr); + $keywords = array_filter(array_map('trim', $keywords), function($item) { + return !empty($item) && !ctype_space($item); + }); + } + return [ + 'status' => 1, + 'msg' => '提取成功', + 'data' => [ + 'abstrart' => $abstract, + 'keywords' => $keywords, + 'fund' => $sFundContent + ] + ]; + } + private function getMatchedFundPhrases($content = '') { + if (empty($content)) { + return []; + } + + // 基金支持词组列表 + $fundPhrases = [ + 'Supported by', 'Funded by', 'Sponsored by', 'Supported in part by', + 'Funding was provided by', 'Funded in part by' + ]; + + // 1. 转义词组中的特殊字符,使用 # 作为分隔符 + $escapedPhrases = array_map(function($phrase) { + return preg_quote($phrase, '#'); + }, $fundPhrases); + + // 2. 拼接为正则模式:匹配任意一个词组(保留原始词组的捕获) + $pattern = '#('.implode('|', $escapedPhrases).')#i'; + // 注意:此处用 () 捕获分组,而非 (?:),用于提取匹配到的具体词组 + + // 3. 全局匹配所有符合的词组 + preg_match_all($pattern, $content, $matches); + + // 4. 处理结果:去重、保留原始词组格式(忽略大小写导致的变体) + $matched = []; + if (!empty($matches[1])) { + // 遍历匹配到的结果(可能包含大小写变体,如 'funded by') + foreach ($matches[1] as $match) { + // 与原始词组列表比对,找到完全匹配的原始词组(忽略大小写) + foreach ($fundPhrases as $original) { + if (strcasecmp($match, $original) === 0) { + $matched[] = $original; + break; // 找到后跳出内层循环,避免重复 + } + } + } + // 去重并保持原始顺序 + $matched = array_values(array_unique($matched)); + } + + return $matched; + } + //日志打印 + private function log($msg){ + // echo date('[Y-m-d H:i:s] ') . $msg . "\n"; + } +} \ No newline at end of file diff --git a/application/common/ReviewerToJournal.php b/application/common/ReviewerToJournal.php new file mode 100644 index 0000000..41fa8e0 --- /dev/null +++ b/application/common/ReviewerToJournal.php @@ -0,0 +1,13 @@ +