作者堆叠 专刊

This commit is contained in:
wyn
2026-07-29 17:05:42 +08:00
parent f583f67e24
commit 1ee795b6b9
10 changed files with 2833 additions and 141 deletions

View File

@@ -10,6 +10,7 @@ use PhpOffice\PhpWord\IOFactory;
use app\common\OpenAi;
use app\common\CrossrefService;
use app\common\PubmedService;
use app\common\ArticleParserService;
/**
* @title 文章接口
@@ -1181,6 +1182,74 @@ class Article extends Base
return jsonSuccess($re);
}
/**
* @title 判断作者是否已按审稿意见修改(逐条核对最终版)
* @description 拆分审稿意见条目,结合修回稿与回复信,用 LLM 逐条判定 addressed/partial/not可缓存
* @param name:article_id type:int require:1 desc:文章id
* @param name:force type:int require:0 desc:1强制重跑忽略缓存
* @param name:mode type:string require:0 desc:full=逐条核对(默认) quick=仅时间门
*
* @url /api/Article/checkAuthorRevisedByReview
* @method POST
*/
public function checkAuthorRevisedByReview()
{
$data = $this->request->post();
$rule = new Validate([
'article_id' => 'require|number'
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
$articleId = intval($data['article_id']);
$mode = strtolower(trim((string)($data['mode'] ?? 'full')));
$force = !empty($data['force']) ? 1 : 0;
try {
$service = new \app\common\service\RevisionCommentMatchService();
if ($mode === 'quick') {
return jsonSuccess($service->quickCheck($articleId));
}
$result = $service->check($articleId, [
'force' => $force,
'use_cache' => $force ? 0 : 1,
]);
$result['mode'] = 'full';
return jsonSuccess($result);
} catch (\Exception $e) {
return jsonError($e->getMessage());
}
}
/**
* @title 获取最近一次逐条修回核对结果
* @param name:article_id type:int require:1 desc:文章id
* @url /api/Article/getRevisionCommentCheckResult
* @method POST
*/
public function getRevisionCommentCheckResult()
{
$data = $this->request->post();
$rule = new Validate([
'article_id' => 'require|number'
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
try {
$result = (new \app\common\service\RevisionCommentMatchService())
->getLatestResult(intval($data['article_id']));
if (empty($result)) {
return jsonError('暂无检测结果,请先调用 checkAuthorRevisedByReview');
}
return jsonSuccess($result);
} catch (\Exception $e) {
return jsonError($e->getMessage());
}
}
/**获取用户所投的文章
* @return \think\response\Json|void
@@ -3221,11 +3290,34 @@ class Article extends Base
}
/**
* 获取文章作者信息
* 支持 article_id查库或 file_url解析稿件不读写库
* @return void
*/
public function getAuthors()
{
$data = $this->request->post();
// 从稿件解析作者(对齐 Contribute 读取逻辑,不入库)
if (!empty($data['file_url'])) {
$sFileUrl = rtrim(ROOT_PATH, '/') . '/public/' . ltrim(ltrim($data['file_url'], '/'), 'public');
if (!file_exists($sFileUrl)) {
return jsonError('The uploaded file does not exist');
}
if (!is_readable($sFileUrl)) {
return jsonError('The uploaded file is unreadable');
}
$aDealData = json_decode(ArticleParserService::uploadAndParse($sFileUrl), true);
$iStatus = empty($aDealData['status']) ? 0 : $aDealData['status'];
if ($iStatus != 1) {
return jsonError(empty($aDealData['msg']) ? 'Content parsing failed' : $aDealData['msg']);
}
$aParseData = empty($aDealData['data']) ? [] : $aDealData['data'];
$re['authors'] = $this->buildAuthorsFromParseData($aParseData);
return jsonSuccess($re);
}
$rule = new Validate([
"article_id" => "require"
]);
@@ -3946,6 +4038,12 @@ class Article extends Base
if (isset($data['is_agree'])) {
$update_l['is_agree'] = $data['is_agree'];
}
if (isset($data['special_num'])) {
$update_l['special_num'] = intval($data['special_num']);
}
if (isset($data['special_title'])) {
$update_l['special_title'] = trim((string)$data['special_title']);
}
if(!empty($sArticleSn)){
$update_l['accept_sn'] = $sArticleSn;
@@ -5737,7 +5835,9 @@ class Article extends Base
// 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 = ['journal_id' => $iJournalId,'title' => $sTitle,'abstrart' => '','use_ai_explain' => '','state' => -1,'user_id' => $iUserId];
if(isset($aParam['special_num']))$aArticleInsert['special_num'] = $aParam['special_num'];
if(isset($aParam['special_title']))$aArticleInsert['special_title'] = $aParam['special_title'];
$aArticleInsert['is_use_ai'] = 3;
$aArticleInsert['is_figure_copyright'] = 3;
// $aArticleInsert['is_transfer'] = 3;
@@ -5785,7 +5885,7 @@ class Article extends Base
if($becomeRev == false){
$aParam['is_become_reviewer'] = 2;
}
$aField = ['is_use_ai','use_ai_explain','is_figure_copyright','is_become_reviewer','approval','approval_file','approval_content','code','is_become_reviewer','is_agree','title','abstrart','keywords','topics','fund','type','journal_id'];//,'title','abstrart','keywords','topics','fund','type','is_transfer',
$aField = ['is_use_ai','use_ai_explain','is_figure_copyright','is_become_reviewer','approval','approval_file','approval_content','code','is_become_reviewer','is_agree','title','abstrart','keywords','topics','fund','type','journal_id','special_num','special_title'];//,'title','abstrart','keywords','topics','fund','type','is_transfer',
$sMsg = '';
$iIsUpdate = 1;
foreach ($aField as $key => $value) {
@@ -6412,9 +6512,65 @@ class Article extends Base
// $update_result = Db::name('article')->where($aWhere)->limit(1)->update($aArticleUpdate);
// }
//操作日志
$aLog = ['article_id' => $iArticleId,'user_id' => $iUserId,'type' => 7,'create_time' => time(),'content' => $sUserAccount . ':Operating the article copyright statement','is_view' => 1];
$aLog = ['article_id' => $iArticleId,'user_id' => $iUserId,'type' => 7,'create_time' => time(),'update_time' => time(),'content' => $sUserAccount . ':Operating the article copyright statement','is_view' => 1];
Db::name('user_act_log')->insert($aLog);
Db::commit();
return json_encode(['status' => 1,'msg' => 'success']);
}
/**
* 修改未发表文章对应专刊(仅更新 tougao 本地 t_article
* special_num = journal_special_idspecial_title 由前端一并传入
*/
public function changeArticleSpecialForSubmit()
{
$data = $this->request->post();
$rule = new Validate([
'article_id' => 'require',
/*'journal_special_id' => 'require',
'special_title' => 'require',*/
]);
if (!$rule->check($data)) {
return jsonError($rule->getError());
}
$article_info = $this->article_obj->where('article_id', $data['article_id'])->find();
if (!$article_info) {
return jsonError('article not found');
}
$journalSpecialRaw = isset($data['journal_special_id'])&&$data['journal_special_id'] ? trim((string)$data['journal_special_id']) : '';
// journal_special_id 为空:清空专刊信息
if ($journalSpecialRaw === '') {
$update = [
'special_num' => 0,
'special_title' => '',
];
$this->article_obj->where('article_id', $data['article_id'])->update($update);
return jsonSuccess([
'article_id' => intval($data['article_id']),
'special_num' => 0,
'special_title' => '',
]);
}
// journal_special_id 有值special_title 必填
$specialTitle = isset($data['special_title']) ? trim((string)$data['special_title']) : '';
if ($specialTitle === '') {
return jsonError('special_title is required');
}
$specialId = intval($journalSpecialRaw);
$update = [
'special_num' => $specialId,
'special_title' => $specialTitle,
];
$this->article_obj->where('article_id', $data['article_id'])->update($update);
return jsonSuccess([
'article_id' => intval($data['article_id']),
'special_num' => $specialId,
'special_title' => $update['special_title'],
]);
}
}