From 23efd2b07a59c73b437a6a4307aa63e6398beed7 Mon Sep 17 00:00:00 2001 From: chengxl Date: Wed, 16 Apr 2025 16:43:31 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E4=BA=BA=E5=AE=A1=E6=A0=B8=E6=95=B0=E9=87=8F(=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=9C=88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Reviewer.php | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/application/api/controller/Reviewer.php b/application/api/controller/Reviewer.php index 420381d..c684770 100644 --- a/application/api/controller/Reviewer.php +++ b/application/api/controller/Reviewer.php @@ -922,6 +922,9 @@ class Reviewer extends Base //文章是从初始状态到其他状态,增加审稿人成功审核次数 if ($art_rev_info['state'] == 0) { $this->user_obj->where('user_id', $art_rev_info['reviewer_id'])->setInc('rs_num'); + //更新审核数量 chengxl 20250409 start + $this->reviewNum($art_rev_info['reviewer_id']); + //更新审核数量 chengxl 20250409 end } //添加文章状态信息 @@ -2049,6 +2052,31 @@ class Reviewer extends Base return ROOT_PATH . 'public' . DS . 'reviewerZS' . DS . $art_rev_id . '.jpg'; } + /** + * 更新审核人审核数量(两个月) + * @param reviewer_id 审核人ID + * @param + */ + private function reviewNum($reviewer_id = 0){ + + //两个月之前日期时间戳 + $sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-2 month'))); + //获取该文章审核人的信息 + $aWhere = [ + 'reviewer_id'=>$reviewer_id, + 'ctime'=>['>',$sDate], + 'state'=>['in',[1,2,3]] + ]; + $iCount = Db::name('article_reviewer')->where($aWhere)->count(); + + //统计数量 + return Db::name('user') + ->where('user_id', $reviewer_id) + ->limit(1) + ->update([ + 'review_num' => $iCount, + ]); + } /** * 生成pdf感谢reviewer */ From fb371c1c84e680675580dad00d91131f628a22da Mon Sep 17 00:00:00 2001 From: chengxl Date: Wed, 16 Apr 2025 16:44:55 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=AE=A1=E7=A8=BF=E4=BA=BA=E6=8E=A8=E8=8D=90=E5=AE=A1=E7=A8=BF?= =?UTF-8?q?=E4=BA=BA=E9=BB=91=E5=90=8D=E5=8D=95=E5=8A=9F=E8=83=BD=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Black.php | 92 ++++++++ application/api/controller/Crontask.php | 280 +++++++++++++++++++++++ application/api/controller/Recommend.php | 119 ++++++++++ 3 files changed, 491 insertions(+) create mode 100644 application/api/controller/Black.php create mode 100644 application/api/controller/Crontask.php create mode 100644 application/api/controller/Recommend.php diff --git a/application/api/controller/Black.php b/application/api/controller/Black.php new file mode 100644 index 0000000..6906c36 --- /dev/null +++ b/application/api/controller/Black.php @@ -0,0 +1,92 @@ +request->post(); + $rule = new Validate([ + 'reviewer_id' => 'require' + ]); + if (!$rule->check($aParam)) { + return jsonError($rule->getError()); + } + //查询审核人是否存在 + $aUser = Db::name('user')->where(['user_id' => $aParam['reviewer_id'],'is_reviewer' => 1])->column('user_id'); + if(empty($aUser)){ + return jsonError('Reviewer does not exist'); + } + + //判断是否添加该审稿人 + $aBlack = Db::name('user_reviewer_black')->field('reviewer_black_id')->where(['reviewer_id'=>$aParam['reviewer_id'],'state' => 1])->find(); + if(!empty($aBlack)){ + return jsonError('The reviewer has been marked as a bad reviewer and there is no need to repeat the process'); + } + //组装数据入库 + $aParam['create_time'] = time(); + $aParam['reason'] = empty($aParam['reason']) ? '' : addslashes(htmlspecialchars(trim($aParam['reason']))); + $aParam['state'] = 1; + + $result = Db::name('user_reviewer_black')->insert($aParam); + if(!$result){ + return jsonError('Failed to add bad reviewers'); + } + return jsonSuccess([]); + } + /** + * @title 更新审稿人状态 + * @param reviewer_id 审稿人ID + * + */ + public function updateReviewer(){ + + $aParam = $this->request->post(); + $rule = new Validate([ + 'reviewer_id' => 'require' + ]); + if (!$rule->check($aParam)) { + return jsonError($rule->getError()); + } + //查询审核人是否存在 + $aUser = Db::name('user')->where(['user_id' => $aParam['reviewer_id'],'is_reviewer' => 1])->column('user_id'); + if(empty($aUser)){ + return jsonError('Reviewer does not exist'); + } + + //判断是否添加该审稿人 + $aBlack = Db::name('user_reviewer_black')->field('reviewer_black_id')->where(['reviewer_id'=>$aParam['reviewer_id'],'state' => 1])->find(); + if(empty($aBlack)){ + return jsonError('Reviewer not marked as a bad reviewer, please confirm'); + } + //组装数据更新数据库 + $aUpdate = ['state' => 2,'update_time' => time()]; + $result = Db::name('user_reviewer_black')->where('reviewer_black_id',$aBlack['reviewer_black_id'])->update($aUpdate); + if(!$result){ + return jsonError('Failed to remove the bad reviewer tag'); + } + return jsonSuccess([]); + } +} diff --git a/application/api/controller/Crontask.php b/application/api/controller/Crontask.php new file mode 100644 index 0000000..0ffeeb4 --- /dev/null +++ b/application/api/controller/Crontask.php @@ -0,0 +1,280 @@ +['in',[3,5]] + ]; + $iCount = Db::name('article')->field('article_id,state')->where($aWhere)->count(); + if(empty($iCount)){ + $this->showMessage('未查询到满足要求的审稿人数据',2); + exit; + } + $iSize = 1000; + $iDealNum = ceil($iCount/$iSize); + + //数据处理 + Db::startTrans(); + for ($iPage=1; $iPage <= $iDealNum; $iPage++) { + echo '======='.$iPage.'========='."\n"; + $iStart = ($iPage - 1) * $iSize; + $aArticle = Db::name('article')->field('article_id,state')->where($aWhere)->limit($iStart,$iSize)->select(); + if(empty($aArticle)){ + continue; + } + //获取该文章审核人的信息 + $aWhere = [ + 'article_id'=>['in',array_column($aArticle, 'article_id')], + 'state'=>['in',[2,3]] + ]; + $aReviewer = Db::name('article_reviewer')->field('article_id,reviewer_id,state')->where($aWhere)->order('article_id asc')->select(); + if(empty($aReviewer)){ + continue; + } + //查询审核人信息 + $aUserId = array_keys($aReviewer); + $aUser = Db::name('user')->field('user_id,rs_num,right_times,error_times')->whereIn('user_id',$aUserId)->select(); + if(empty($aUser)){ + continue; + } + $aUser = array_column($aUser, null,'user_id'); + + //处理数据并组装数据 + $aArticleState = array_column($aArticle, 'state','article_id'); + $aCase = ['right_times' => '', 'right_rate' => '','error_times' => '', 'error_rate' => '']; + $aToState = [2 => 3,3 => 5];//文章3拒稿5录用 审稿人2拒稿3通过 + foreach ($aReviewer as $key => $item) { + //文章状态 + $iArticleState = empty($aArticleState[$item['article_id']]) ? 0 : $aArticleState[$item['article_id']]; + if(empty($iArticleState)){ + continue; + } + if(empty($aToState[$item['state']])){ + continue; + } + $aUserInfo = $aUser[$item['reviewer_id']] ?? []; + if(empty($aUserInfo)){ + continue; + } + if($iArticleState == $aToState[$item['state']]){ + + $iTimes = $aUserInfo['right_times']+1; + $iRightNum = empty($aUserInfo['rs_num']) ? 0 : round($iTimes/$aUserInfo['rs_num']/100,2); + + $aCase['right_times'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['right_times'] .= "'{$iTimes}' "; + $aCase['right_rate'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['right_rate'] .= "'{$iRightNum}' "; + + } + if($iArticleState != $item['state']){ + $iErrorTimes = $aUserInfo['error_times']+1; + $iErrorNum = empty($aUserInfo['rs_num']) ? 0 : round($iErrorTimes/$aUserInfo['rs_num']/100,2); + $aCase['error_times'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['error_times'] .= "'{$iErrorTimes}' "; + $aCase['error_rate'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['error_rate'] .= "'{$iErrorNum}' "; + + } + $aId[] = $item['reviewer_id']; + } + + //更新数据库 + foreach ($aCase as $key => $value) { + if(empty($value)){ + continue; + } + $aUpdate[$key] = Db::raw('CASE user_id '.$value.'END'); + } + if(empty($aUpdate) || empty($aId)){ + $this->showMessage('未查询到满足要求的审稿人数据4',2); + return false; + } + $result = Db::name('user') + ->where('user_id', 'IN', $aId) + ->limit(count($aId)) + ->update($aUpdate); + echo '---------'.$iPage.'--------'."\n"; + } + Db::commit(); + $this->showMessage('审稿人质量数据处理完成',1); + } + /** + * 批量处理审稿人活跃度/疲劳度[近两个月] + * + * @return void + */ + public function reviewerActivity(){ + $sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-2 month'))); + //获取该文章审核人的信息 + $aWhere = [ + 'ctime'=>['>',$sDate], + 'state'=>['in',[1,2,3]] + ]; + $aReviewer = Db::name('article_reviewer')->field('reviewer_id,count(article_id) as review_num ')->where($aWhere)->order('reviewer_id asc')->group('reviewer_id')->select(); + + //查询审稿人数量不为0的审稿信息 + $aUserWhere = [ + // 'is_reviewer' => 1, + 'review_num' => ['>',0] + ]; + $aUser = Db::name('user')->field('user_id,review_num')->where($aUserWhere)->select(); + if(empty($aReviewer) && empty($aUser)){ + $this->showMessage('未查询到待处理的审稿人数据',2); + exit; + } + $aUser = empty($aUser) ? [] : array_column($aUser, null,'user_id'); + if(!empty($aReviewer)){ + $aChunk = array_chunk($aReviewer, 100); + Db::startTrans(); + foreach ($aChunk as $key => $item) { //数据分片操作 + //需要更新的用户ID + $aUpdateId = []; + //SQL拼接 + $aCase['review_num'] = 'CASE user_id '; + foreach ($item as $key => $value) { + //用户ID + $iUserId = $value['reviewer_id']; + + //拼接更新语句 + if(empty($aUser[$iUserId])){ + //更新数量 + $aCase['review_num'] .= "WHEN {$iUserId} THEN "; + $aCase['review_num'] .= "'{$value['review_num']}' "; + $aUpdateId[] = $iUserId; + continue; + } + //审核数量无变化,跳过更新 + if($aUser[$iUserId]['review_num'] == $value['review_num']){ + unset($aUser[$iUserId]); + continue; + } + //审核数量有,变化更新数量 + $aCase['review_num'] .= "WHEN {$iUserId} THEN "; + $aCase['review_num'] .= "'{$value['review_num']}' "; + $aUpdateId[] = $iUserId; + unset($aUser[$iUserId]); + } + //SQL拼接最后结尾 + $aCase['review_num'] .= 'END'; + //执行更新 + if(empty($aUpdateId)){ + continue; + } + $result = Db::name('user') + ->where(['user_id' => ['in',$aUpdateId]]) + ->update([ + 'review_num' => Db::raw($aCase['review_num']), + ]); + } + Db::commit(); + // $this->showMessage('更新审稿人审核数量成功',1); + } + if(!empty($aUser)){ + $aChunk = array_chunk($aUser, 100); + Db::startTrans(); + foreach ($aChunk as $key => $item) { //数据分片操作 + $aUserId = array_column($item, 'user_id'); + if(empty($aUserId)){ + continue; + } + $result = Db::name('user')->where(['is_reviewer' => 1,'user_id' => ['in',$aUserId]]) + ->limit(count($aUserId)) + ->update([ + 'review_num' => 0, + ]); + // if(!$result){ + // $this->showMessage('清空审稿人审核数量失败:'.Db::getLastSql(),2); + // } + + } + Db::commit(); + // $this->showMessage('清空审稿人审核数量成功:'.Db::getLastSql(),1); + } + $this->showMessage('批量更新审稿人审核数量成功',1); + } + + /** + * @title 审稿人拒绝审稿[超过七日默认自动拒绝审稿] + * + */ + public function refuseReviewArticle(){ + $sDate = strtotime(date('Y-m-d 00:00:00', strtotime('-7 day'))); + //获取该文章审核人的信息 + $aWhere = [ + 'ctime'=>['<',$sDate], + 'state'=> 5 + ]; + + //统计每个审稿人未审稿的数量 + $aReviewerNum = Db::name('article_reviewer')->field('reviewer_id,count(art_rev_id) as num')->where($aWhere)->group('reviewer_id')->order('reviewer_id asc')->select(); + if(empty($aReviewerNum)){ + $this->showMessage('未查询到需要超过七日的稿件',2); + exit; + } + + //更新超过七日未审核的数据 + Db::startTrans(); + //更新审稿人未审稿的数量 + $aChunkReviewerNum = array_chunk($aReviewerNum, 100); + foreach ($aChunkReviewerNum as $key => $value) { + $aId = array_column($value, 'reviewer_id'); + if(empty($aId)){ + continue; + } + $aWhere['reviewer_id']=['in',$aId]; + $iCount = array_sum(array_column($value, 'num')); + Db::name('article_reviewer')->where($aWhere)->limit($iCount)->update(['state' => 4]); + + $aCase['review_num'] = 'CASE user_id '; + foreach ($value as $key => $item) { + //审核数量有,变化更新数量 + $aCase['review_num'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['review_num'] .= Db::raw("review_num + {$item['num']}")." "; + $aUpdateId[] = $item['reviewer_id']; + } + //SQL拼接最后结尾 + $aCase['review_num'] .= 'END'; + //执行更新 + $result = Db::name('user') + ->where(['user_id' => ['in',$aUpdateId]]) + ->update([ + 'rd_num' => Db::raw($aCase['review_num']), + ]); + } + Db::commit(); + + $this->showMessage('批量更新超过七日未审稿的状态成功',2); + + } + + /** + * + * 格式化信息输出 + * + * @access public + * @return void + * @author huangpu + * @date 2018.09.28 + * @param $[message] [<显示信息>] + * @param $[status] [<输出信息1成功,2失败>] + */ + private function showMessage($message, $status = 1) { + if ($status == 1) { + echo "[SUCCESS]"; + } else { + echo "[ERROR]"; + } + echo date("Y-m-d H:i:s") . " " . $message . "\n"; + } +} diff --git a/application/api/controller/Recommend.php b/application/api/controller/Recommend.php new file mode 100644 index 0000000..58d57a9 --- /dev/null +++ b/application/api/controller/Recommend.php @@ -0,0 +1,119 @@ +request->post(); + //分页 + $iSize = empty($aParam['size']) ? 10 : $aParam['size']; + $iPage = empty($aParam['page']) ? 1 : $aParam['page']; + $limit_start = ($iPage - 1) * $iSize; + + if(empty($aParam['article_id'])){ + exit(json_encode(array('status' => 2,'msg' => 'Please select an article' ))); + } + + //查询文章 + $aArticle = Db::table('t_major_to_article')->field('article_id')->where('article_id',$aParam['article_id'])->find(); + if(empty($aArticle)){ + exit(json_encode(array('status' => 3,'msg' => 'No articles requiring review were found' ))); + } + //查询文章领域 + $aMajorId = Db::table('t_major_to_article')->where('article_id',$aArticle['article_id'])->column('major_id'); + if(empty($aMajorId)){ + exit(json_encode(array('status' => 4,'msg' => 'No field found for the article' ))); + } + + // //根据文章领域获取满足该领域父类 + // $aMajorId = Db::table('t_major')->field('major_id,major_title,pid')->whereIn('major_id', $aMajorArticle)->where('pid != 1')->select(); + $aParentId = Db::table('t_major')->where(['major_id' => ['in',$aMajorId]])->column('major_id,pid'); + $aMajorId = $this->getChildIds(array_values($aParentId)); + + //数据处理拼接父类ID为1的领域 + foreach ($aParentId as $key => $value) { + if(in_array($value, [0,1])){ + array_push($aMajorId,$key); + continue; + } + } + //查询所属该领域的审稿人 + if(empty($aMajorId)){ + exit(json_encode(array('status' => 5,'msg' => 'No reviewers in the field of the article were found' ))); + } + $aMajorUser = Db::name('major_to_user')->whereIn('major_id', $aMajorId)->where('state',0)->order('major_id asc')->column('user_id'); + if(empty($aMajorUser)){ + exit(json_encode(array('status' => 6,'msg' => 'No reviewers in the field of the article were found' ))); + } + $aMajorUser = array_unique($aMajorUser); + + //查询审稿人是否为劣迹审稿人 + $aBlack = Db::name('user_reviewer_black')->whereIn('reviewer_id', $aMajorUser)->where('state',1)->column('reviewer_id'); + if(!empty($aBlack)){ + $aMajorUser = array_diff($aMajorUser, $aBlack); + } + + //查用户信息 + $aWhere = ['user_id' => ['in',$aMajorUser],'state' => 0,'is_reviewer' => 1]; + //统计数量 + $iCount = Db::table('t_user')->where($aWhere)->count(); + if(empty($iCount)){ + exit(json_encode(array('status' => 1,'msg' => '','data' => ['total' => 0,'lists' => []]))); + } + $sOrder = 'review_num asc,right_rate desc'; + $aUser = Db::table('t_user')->field('user_id,account,realname,rs_num,right_times,error_times,right_rate,error_rate,review_num')->where($aWhere)->order($sOrder)->limit($limit_start, $iSize)->select(); + //查询审稿人详细信息 + $aUserId = array_column($aUser, 'user_id'); + $aInfo = Db::name('user_reviewer_info')->field('reviewer_id,technical,country,introduction,company,field')->whereIn('reviewer_id',$aUserId)->select(); + $aInfo = empty($aInfo) ? [] : array_column($aInfo, null,'reviewer_id'); + + foreach ($aUser as $key => $value) { + $value += empty($aInfo[$value['user_id']]) ? [] : $aInfo[$value['user_id']]; + $aUser[$key] = $value; + } + exit(json_encode(array('status' => 1,'msg' => '','data' => ['total' => $iCount,'lists' => $aUser]))); +// + + } + + /** + * 递归获取某个分类下的所有子分类ID + * @param int $parentId 父级ID + * @param array &$result 结果存储 + */ + private function getChildIds($parentId, &$result = []) { + + $parentId = array_unique(array_diff($parentId, [1])); + $children = Db::table('t_major')->whereIn('pid', $parentId)->where('major_state',0)->order('major_id asc')->column('major_id'); + $result = array_merge($result,$children); + if (!empty($children)) { + $this->getChildIds($children, $result); // 递归查询子级 + } + return $result ?? []; + } + + +} From 3651ac9f90b8dd5854e65c2d451032b79474d5a2 Mon Sep 17 00:00:00 2001 From: chengxl Date: Thu, 17 Apr 2025 22:06:40 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Crontask.php | 146 +++++++++++++++--------- 1 file changed, 91 insertions(+), 55 deletions(-) diff --git a/application/api/controller/Crontask.php b/application/api/controller/Crontask.php index 0ffeeb4..c14dc2d 100644 --- a/application/api/controller/Crontask.php +++ b/application/api/controller/Crontask.php @@ -12,10 +12,10 @@ class Crontask extends Controller public function reviewerQuality() { //查询文章状态 - $aWhere = [ + $aParam = [ 'state'=>['in',[3,5]] ]; - $iCount = Db::name('article')->field('article_id,state')->where($aWhere)->count(); + $iCount = Db::name('article')->field('article_id,state')->where($aParam)->count(); if(empty($iCount)){ $this->showMessage('未查询到满足要求的审稿人数据',2); exit; @@ -24,36 +24,38 @@ class Crontask extends Controller $iDealNum = ceil($iCount/$iSize); //数据处理 - Db::startTrans(); + $aUpdate = []; for ($iPage=1; $iPage <= $iDealNum; $iPage++) { - echo '======='.$iPage.'========='."\n"; $iStart = ($iPage - 1) * $iSize; - $aArticle = Db::name('article')->field('article_id,state')->where($aWhere)->limit($iStart,$iSize)->select(); - if(empty($aArticle)){ + $aArticleState = Db::name('article')->where($aParam)->limit($iStart,$iSize)->column('article_id,state'); + if(empty($aArticleState)){ continue; } //获取该文章审核人的信息 $aWhere = [ - 'article_id'=>['in',array_column($aArticle, 'article_id')], - 'state'=>['in',[2,3]] + 'article_id'=>['in',array_keys($aArticleState)], + 'state'=>['in',[1,2,3]] ]; - $aReviewer = Db::name('article_reviewer')->field('article_id,reviewer_id,state')->where($aWhere)->order('article_id asc')->select(); + $aReviewer = Db::name('article_reviewer')->field('article_id,reviewer_id,state')->where($aWhere)->order('article_id asc,reviewer_id asc')->select(); if(empty($aReviewer)){ continue; } //查询审核人信息 - $aUserId = array_keys($aReviewer); - $aUser = Db::name('user')->field('user_id,rs_num,right_times,error_times')->whereIn('user_id',$aUserId)->select(); + $aUserId = array_column($aReviewer,'reviewer_id'); + $aUser = Db::name('user')->field('user_id,rs_num,right_times,error_times')->whereIn('user_id',$aUserId)->order('user_id asc')->select(); if(empty($aUser)){ continue; } $aUser = array_column($aUser, null,'user_id'); //处理数据并组装数据 - $aArticleState = array_column($aArticle, 'state','article_id'); $aCase = ['right_times' => '', 'right_rate' => '','error_times' => '', 'error_rate' => '']; $aToState = [2 => 3,3 => 5];//文章3拒稿5录用 审稿人2拒稿3通过 + $aId = []; foreach ($aReviewer as $key => $item) { + //审核次数+1; + $aUpdate[$item['reviewer_id']]['reviewer_id'] = $item['reviewer_id'] ; + $aUpdate[$item['reviewer_id']]['rs_num'] = empty($aUpdate[$item['reviewer_id']]['rs_num']) ? 1 : $aUpdate[$item['reviewer_id']]['rs_num']+1 ; //文章状态 $iArticleState = empty($aArticleState[$item['article_id']]) ? 0 : $aArticleState[$item['article_id']]; if(empty($iArticleState)){ @@ -62,49 +64,65 @@ class Crontask extends Controller if(empty($aToState[$item['state']])){ continue; } - $aUserInfo = $aUser[$item['reviewer_id']] ?? []; - if(empty($aUserInfo)){ - continue; - } + if($iArticleState == $aToState[$item['state']]){ - - $iTimes = $aUserInfo['right_times']+1; - $iRightNum = empty($aUserInfo['rs_num']) ? 0 : round($iTimes/$aUserInfo['rs_num']/100,2); - - $aCase['right_times'] .= "WHEN {$item['reviewer_id']} THEN "; - $aCase['right_times'] .= "'{$iTimes}' "; - $aCase['right_rate'] .= "WHEN {$item['reviewer_id']} THEN "; - $aCase['right_rate'] .= "'{$iRightNum}' "; + $aUpdate[$item['reviewer_id']]['right_times'] = empty($aUpdate[$item['reviewer_id']]['right_times']) ? 1 : $aUpdate[$item['reviewer_id']]['right_times']+1 ; } if($iArticleState != $item['state']){ - $iErrorTimes = $aUserInfo['error_times']+1; - $iErrorNum = empty($aUserInfo['rs_num']) ? 0 : round($iErrorTimes/$aUserInfo['rs_num']/100,2); - $aCase['error_times'] .= "WHEN {$item['reviewer_id']} THEN "; - $aCase['error_times'] .= "'{$iErrorTimes}' "; - $aCase['error_rate'] .= "WHEN {$item['reviewer_id']} THEN "; - $aCase['error_rate'] .= "'{$iErrorNum}' "; + $aUpdate[$item['reviewer_id']]['error_times'] = empty($aUpdate[$item['reviewer_id']]['error_times']) ? 1 : $aUpdate[$item['reviewer_id']]['error_times']+1 ; } - $aId[] = $item['reviewer_id']; } + } + $aChunk = array_chunk($aUpdate, $iSize); + Db::startTrans(); + foreach ($aChunk as $key => $value) { + $aCase = ['right_times' => '', 'right_rate' => '','error_times' => '', 'error_rate' => '','rs_num' => '']; + foreach ($value as $item) { + + //正确数 + $iRsNum = empty($item['rs_num']) ? 0 : $item['rs_num']; + $iRightTimes = empty($item['right_times']) ? 0 : $item['right_times']; + $iRightRate = empty($iRightTimes) ? 0 : round($iRightTimes/$iRsNum,2); + $aCase['right_times'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['right_times'] .= "'{$iRightTimes}' "; + $aCase['right_rate'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['right_rate'] .= "'{$iRightRate}' "; + //错误数 + $iErrorTimes = empty($item['error_times']) ? 0 : $item['error_times']; + $iErrorRate = empty($iErrorTimes) ? 0 : round($iErrorTimes/$iRsNum,2); + $aCase['error_times'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['error_times'] .= "'{$iErrorTimes}' "; + $aCase['error_rate'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['error_rate'] .= "'{$iErrorRate}' "; + + //审核数量 + $aCase['rs_num'] .= "WHEN {$item['reviewer_id']} THEN "; + $aCase['rs_num'] .= "'{$iRsNum}' "; + } + $aId = array_column($value, 'reviewer_id'); //更新数据库 - foreach ($aCase as $key => $value) { + foreach ($aCase as $kk => $value) { if(empty($value)){ continue; } - $aUpdate[$key] = Db::raw('CASE user_id '.$value.'END'); + $aUpdateCase[$kk] = Db::raw('CASE user_id '.$value.'END'); } - if(empty($aUpdate) || empty($aId)){ - $this->showMessage('未查询到满足要求的审稿人数据4',2); - return false; + if(empty($aUpdateCase) || empty($aId)){ + $this->showMessage('未查询到满足要求的审稿人数据['.$key.']'."\n",2); + continue; } $result = Db::name('user') ->where('user_id', 'IN', $aId) ->limit(count($aId)) - ->update($aUpdate); - echo '---------'.$iPage.'--------'."\n"; + ->update($aUpdateCase); + if ($result === false) { + $this->showMessage('审稿人质量数据处理失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); + }else{ + $this->showMessage('审稿人质量数据处理成功['.$key.']执行SQL条数:'.$result."\n",1); + } } Db::commit(); $this->showMessage('审稿人质量数据处理完成',1); @@ -176,9 +194,13 @@ class Crontask extends Controller ->update([ 'review_num' => Db::raw($aCase['review_num']), ]); + if ($result === false) { + $this->showMessage('更新审稿人审核数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); + }else{ + $this->showMessage('更新审稿人审核数量成功['.$key.']执行SQL条数:'.$result."\n",1); + } } - Db::commit(); - // $this->showMessage('更新审稿人审核数量成功',1); + Db::commit(); } if(!empty($aUser)){ $aChunk = array_chunk($aUser, 100); @@ -193,15 +215,16 @@ class Crontask extends Controller ->update([ 'review_num' => 0, ]); - // if(!$result){ - // $this->showMessage('清空审稿人审核数量失败:'.Db::getLastSql(),2); - // } + if ($result === false) { + $this->showMessage('清空审稿人审核数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); + }else{ + $this->showMessage('清空审稿人审核数量成功['.$key.']执行SQL条数:'.$result."\n",1); + } } Db::commit(); - // $this->showMessage('清空审稿人审核数量成功:'.Db::getLastSql(),1); } - $this->showMessage('批量更新审稿人审核数量成功',1); + $this->showMessage('批量更新审稿人审核数量成功'."\n",1); } /** @@ -226,7 +249,7 @@ class Crontask extends Controller //更新超过七日未审核的数据 Db::startTrans(); //更新审稿人未审稿的数量 - $aChunkReviewerNum = array_chunk($aReviewerNum, 100); + $aChunkReviewerNum = array_chunk($aReviewerNum, 500); foreach ($aChunkReviewerNum as $key => $value) { $aId = array_column($value, 'reviewer_id'); if(empty($aId)){ @@ -234,30 +257,43 @@ class Crontask extends Controller } $aWhere['reviewer_id']=['in',$aId]; $iCount = array_sum(array_column($value, 'num')); - Db::name('article_reviewer')->where($aWhere)->limit($iCount)->update(['state' => 4]); - - $aCase['review_num'] = 'CASE user_id '; + $iResult = Db::name('article_reviewer')->where($aWhere)->limit($iCount)->update(['state' => 4]); + if ($iResult === false) { + $this->showMessage('更新审稿人审稿状态失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); + }else{ + $this->showMessage('更新审稿人审稿状态成功['.$key.']执行SQL条数:'.$iResult."\n",1); + } + $aCase = $aUpdateId = []; + $sRdNum = ''; foreach ($value as $key => $item) { + if($item['reviewer_id'] <=0){ + continue; + } //审核数量有,变化更新数量 - $aCase['review_num'] .= "WHEN {$item['reviewer_id']} THEN "; - $aCase['review_num'] .= Db::raw("review_num + {$item['num']}")." "; + $sRdNum .= "WHEN {$item['reviewer_id']} THEN "; + $sRdNum .= Db::raw("rd_num + {$item['num']}")." "; $aUpdateId[] = $item['reviewer_id']; } //SQL拼接最后结尾 - $aCase['review_num'] .= 'END'; + $aCase['rd_num'] ='CASE user_id '.$sRdNum.'END'; //执行更新 $result = Db::name('user') ->where(['user_id' => ['in',$aUpdateId]]) + ->limit(count($aUpdateId)) ->update([ - 'rd_num' => Db::raw($aCase['review_num']), - ]); + 'rd_num' => Db::raw($aCase['rd_num']), + ]); + if ($result === false) { + $this->showMessage('更新用户拒绝审稿数量失败['.$key.']执行SQL:'.Db::getLastSql()."\n",2); + }else{ + $this->showMessage('更新用户拒绝审稿数量成功['.$key.']执行SQL条数:'.$result."\n",1); + } } Db::commit(); $this->showMessage('批量更新超过七日未审稿的状态成功',2); } - /** * * 格式化信息输出 From d39d5312c7ab1372e574296bdec63cb9271e80f2 Mon Sep 17 00:00:00 2001 From: chengxl Date: Thu, 17 Apr 2025 22:07:52 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E7=94=A8=E4=BA=8E=E5=AD=98=E6=94=BE?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1shell=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/command/refuseReviewArticle.sh | 24 ++++++++++++++++++++++ application/command/reviewerActivity.sh | 23 +++++++++++++++++++++ application/command/reviewerQuality.sh | 24 ++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100755 application/command/refuseReviewArticle.sh create mode 100755 application/command/reviewerActivity.sh create mode 100755 application/command/reviewerQuality.sh diff --git a/application/command/refuseReviewArticle.sh b/application/command/refuseReviewArticle.sh new file mode 100755 index 0000000..a81b69f --- /dev/null +++ b/application/command/refuseReviewArticle.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# refuseReviewArticle.sh +# 审稿人拒绝审稿[超过七日默认自动拒绝审稿] +# 读取文章审核表【article_reviewer】状态state=5 并且 ctime < strtotime('-7 day')的数据 +# 更新文章审核表【article_reviewer】状态state=4过期 +# 更新用户表【t_user】rd_num 审稿失败次数 +# 此文件需要在crontab中配置每天【凌晨1点】运行一次 +# @author chengxiaoling +# @date 2025-04-17 + +# 基础配置 +DOMAIN="http://zmzm.tougao.dev.com/" # 项目域名 +ROUTE="/api/Crontask/refuseReviewArticle" # 控制器路由 +BASE_PATH=$(cd `dirname $0`; pwd) +# 如果日志目录不存在则创建 +logDir=${BASE_PATH}/log/$(date "+%Y")/$(date "+%m") +if [ ! -d $logDir ];then + mkdir -p $logDir +fi + +# 执行请求并记录日志 +curl "${DOMAIN}${ROUTE}" >> ${logDir}/refuseReviewArticle_$(date "+%Y%m%d").log 2>&1 +# 添加时间戳 +echo "[$(date '+%Y-%m-%d %H:%M:%S')] 定时任务已执行" >> ${logDir}/refuseReviewArticle_$(date "+%Y%m%d").log \ No newline at end of file diff --git a/application/command/reviewerActivity.sh b/application/command/reviewerActivity.sh new file mode 100755 index 0000000..f4bdd1a --- /dev/null +++ b/application/command/reviewerActivity.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# reviewerActivity.sh +# 批量处理审稿人活跃度/疲劳度[近两个月] +# 读取文章审核表【article_reviewer】状态state in [[1,2,3] 并且 ctime > strtotime('-2 month')的数据 +# 更新用户表【t_user】review_num 审核数量【近两个月】 +# 此文件需要在crontab中配置每天【凌晨2点】运行一次 +# @author chengxiaoling +# @date 2025-04-17 + +# 基础配置 +DOMAIN="http://zmzm.tougao.dev.com/" # 项目域名 +ROUTE="/api/Crontask/reviewerActivity" # 控制器路由 +BASE_PATH=$(cd `dirname $0`; pwd) +# 如果日志目录不存在则创建 +logDir=${BASE_PATH}/log/$(date "+%Y")/$(date "+%m") +if [ ! -d $logDir ];then + mkdir -p $logDir +fi + +# 执行请求并记录日志 +curl "${DOMAIN}${ROUTE}" >> ${logDir}/reviewerActivity_$(date "+%Y%m%d").log 2>&1 +# 添加时间戳 +echo "[$(date '+%Y-%m-%d %H:%M:%S')] 定时任务已执行" >> ${logDir}/reviewerActivity_$(date "+%Y%m%d").log \ No newline at end of file diff --git a/application/command/reviewerQuality.sh b/application/command/reviewerQuality.sh new file mode 100755 index 0000000..57271a0 --- /dev/null +++ b/application/command/reviewerQuality.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# reviewerQuality.sh +# 批量处理审稿人审稿质量 +# 读取文章表【article】状态state in [3,5]的数据 +# 读取文章审核表【t_article_reviewer】状态state in [2,3]的数据 +# 判断状态是否一致 更新用户表【t_user】rd_num 审稿right_times error_times right_rate error_rate +# 此文件需要在上线执行一次就可以 +# @author chengxiaoling +# @date 2025-04-17 + +# 基础配置 +DOMAIN="http://zmzm.tougao.dev.com/" # 项目域名 +ROUTE="/api/Crontask/reviewerQuality" # 控制器路由 +BASE_PATH=$(cd `dirname $0`; pwd) +# 如果日志目录不存在则创建 +logDir=${BASE_PATH}/log/$(date "+%Y")/$(date "+%m") +if [ ! -d $logDir ];then + mkdir -p $logDir +fi + +# 执行请求并记录日志 +curl "${DOMAIN}${ROUTE}" >> ${logDir}/reviewerQuality_$(date "+%Y%m%d").log 2>&1 +# 添加时间戳 +echo "[$(date '+%Y-%m-%d %H:%M:%S')] 定时任务已执行" >> ${logDir}/reviewerQuality_$(date "+%Y%m%d").log \ No newline at end of file From 0e94e742c4d8087941c72d5a039ff3d44c4e2faf Mon Sep 17 00:00:00 2001 From: chengxl Date: Fri, 18 Apr 2025 11:50:18 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=8E=A8=E8=8D=90=E5=AE=A1=E7=A8=BF?= =?UTF-8?q?=E4=BA=BA=E8=BF=94=E5=9B=9E=E5=AD=97=E6=AE=B5=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Recommend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/api/controller/Recommend.php b/application/api/controller/Recommend.php index 58d57a9..9f27dcf 100644 --- a/application/api/controller/Recommend.php +++ b/application/api/controller/Recommend.php @@ -84,7 +84,7 @@ class Recommend extends Base exit(json_encode(array('status' => 1,'msg' => '','data' => ['total' => 0,'lists' => []]))); } $sOrder = 'review_num asc,right_rate desc'; - $aUser = Db::table('t_user')->field('user_id,account,realname,rs_num,right_times,error_times,right_rate,error_rate,review_num')->where($aWhere)->order($sOrder)->limit($limit_start, $iSize)->select(); + $aUser = Db::table('t_user')->field('user_id,account,email,realname,rs_num,right_times,error_times,right_rate,error_rate,review_num')->where($aWhere)->order($sOrder)->limit($limit_start, $iSize)->select(); //查询审稿人详细信息 $aUserId = array_column($aUser, 'user_id'); $aInfo = Db::name('user_reviewer_info')->field('reviewer_id,technical,country,introduction,company,field')->whereIn('reviewer_id',$aUserId)->select(); From 84cc4478b3de21f8ddbbd41ac05632e1194f6760 Mon Sep 17 00:00:00 2001 From: chengxl Date: Fri, 18 Apr 2025 11:52:14 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E4=B9=8B=E5=90=8E=E7=BB=9F=E8=AE=A1=E5=AE=A1=E7=A8=BF=E4=BA=BA?= =?UTF-8?q?=E7=9A=84=E5=AE=A1=E7=A8=BF=E8=B4=A8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Article.php | 83 +++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/application/api/controller/Article.php b/application/api/controller/Article.php index 7a5a23a..f726739 100644 --- a/application/api/controller/Article.php +++ b/application/api/controller/Article.php @@ -298,7 +298,6 @@ class Article extends Base //接受参数 $data = $this->request->post(); - if (isset($data['sn']) && trim($data['sn']) != "") { $where["t_article.accept_sn"] = trim($data['sn']); $sn_info = $this->article_obj->where('accept_sn', trim($data['sn']))->find(); @@ -1196,6 +1195,7 @@ class Article extends Base */ public function editArticleEditor() { + //接受参数,查询信息 $data = $this->request->post(); $where_editor['account'] = $data['editname']; @@ -1608,6 +1608,9 @@ class Article extends Base //增加usermsg add_usermsg($article_info['user_id'], 'Your manuscript has new process: ' . $article_info['title'], '/articleDetail?id=' . $article_info['article_id']); + //重新计算审稿人的审稿质量 chengxiaoling start 0416 + $this->reviewQuality($article_info['article_id']); + //重新计算审稿人的审稿质量 chengxiaoling end 0416 return json(['code' => 0]); } @@ -4312,4 +4315,82 @@ class Article extends Base $total = mb_strlen($filteredStr, 'UTF-8'); return $total >= $num; } + /** + * 审稿人审稿质量 + * @param $article_id 文章ID + * @return void + */ + private function reviewQuality($article_id = ''){ + $article_id = empty($article_id) ? $this->request->post('article_id') : $article_id; + if(empty($article_id)){ + return json(['status' => 2,'msg' => '请选择要查询的文章']); + } + //查询文章状态 + $aWhere = [ + 'article_id'=>$article_id, + 'state'=>['in',[3,5]] + ]; + $aArticle = Db::name('article')->field('article_id,state')->where($aWhere)->find(); + + if(empty($aArticle)){ + return json(['status' => 1,'msg' => '暂无数据']); + } + //获取该文章审核人的信息 + $aWhere = [ + 'article_id'=>$aArticle['article_id'], + 'state'=>['in',[2,3]] + ]; + $aReviewer = Db::name('article_reviewer')->where($aWhere)->column('reviewer_id,state'); + if(empty($aReviewer)){ + return json(['status' => 1,'msg' => '未查询到审核人信息']); + } + + //查询审核人信息 + $aUserId = array_keys($aReviewer); + $aUser = Db::name('user')->field('user_id,rs_num,rigxht_times,error_times')->whereIn('user_id',$aUserId)->select(); + if(empty($aUser)){ + return json(['status' => 1,'msg' => '未查询到审核人信息']); + } + //处理数据并组装数据 + $aCase = ['right_times' => '', 'right_rate' => '','error_times' => '', 'error_rate' => '']; + $aToState = [2 => 3,3 => 5];//文章3拒稿5录用 审稿人2拒稿3通过 + foreach ($aUser as $key => $value) { + $iState = empty($aReviewer[$value['user_id']]) ? 0 : $aReviewer[$value['user_id']]; + if(empty($iState)){ + continue; + } + if(empty($aToState[$iState])){ + continue; + } + if($aArticle['state'] == $aToState[$iState]){ + $iTimes = $value['right_times']+1; + $iRightNum = empty($value['rs_num']) ? 0 : round($iTimes/$value['rs_num'],2); + $aCase['right_times'] .= "WHEN {$value['user_id']} THEN "; + $aCase['right_times'] .= "'{$iTimes}' "; + $aCase['right_rate'] .= "WHEN {$value['user_id']} THEN "; + $aCase['right_rate'] .= "'{$iRightNum}' "; + } + if($aArticle['state'] != $aToState[$iState]){ + $iErrorTimes = $value['error_times']+1; + $iErrorNum = empty($value['rs_num']) ? 0 : round($iErrorTimes/$value['rs_num'],2); + $aCase['error_times'] .= "WHEN {$value['user_id']} THEN "; + $aCase['error_times'] .= "'{$iErrorTimes}' "; + $aCase['error_rate'] .= "WHEN {$value['user_id']} THEN "; + $aCase['error_rate'] .= "'{$iErrorNum}' "; + } + $aId[] = $value['user_id']; + } + //更新数据库 + foreach ($aCase as $key => $value) { + if(empty($value)){ + continue; + } + $aUpdate[$key] = Db::raw('CASE user_id '.$value.'END'); + } + if(empty($aUpdate) || empty($aId)){ + return json(['status' => 1,'msg' => '未查询到审核人信息']); + } + Db::name('user')->where('user_id', 'IN', $aId)->limit(count($aId))->update($aUpdate); + return json(['status' => 1,'msg' => '执行成功']); + } } From 9c80535505ebb25c3813dafb92868a53358894b7 Mon Sep 17 00:00:00 2001 From: chengxl Date: Fri, 18 Apr 2025 13:28:29 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=8E=A8=E8=8D=90=E5=AE=A1=E7=A8=BF?= =?UTF-8?q?=E4=BA=BA=E5=A2=9E=E5=8A=A0=E6=90=9C=E7=B4=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Recommend.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/application/api/controller/Recommend.php b/application/api/controller/Recommend.php index 9f27dcf..f78a8c2 100644 --- a/application/api/controller/Recommend.php +++ b/application/api/controller/Recommend.php @@ -76,8 +76,23 @@ class Recommend extends Base $aMajorUser = array_diff($aMajorUser, $aBlack); } + //条件拼接 + $aWhere = ['state' => 0,'is_reviewer' => 1]; + if(!empty($aParam['email'])){//根据邮箱搜索 + $aWhere['email'] = ['like',"%" . $aParam["email"] . "%"]; + } + if(!empty($aParam['field'])){//根据领域搜索 + $aReviewerWhere['reviewer_id'] = ['in',$aMajorUser]; + $aReviewerWhere['field'] = ['like',"%" . $aParam["field"] . "%"]; + $aReviewerInfo = Db::name('user_reviewer_info')->where($aReviewerWhere)->column('reviewer_id'); + if(empty($aReviewerInfo)){ + exit(json_encode(array('status' => 1,'msg' => '','data' => ['total' => 0,'lists' => []]))); + } + $aMajorUser = array_intersect($aMajorUser,$aReviewerInfo); + } + //查用户信息 - $aWhere = ['user_id' => ['in',$aMajorUser],'state' => 0,'is_reviewer' => 1]; + $aWhere['user_id'] = ['in',$aMajorUser]; //统计数量 $iCount = Db::table('t_user')->where($aWhere)->count(); if(empty($iCount)){