参考文献格式

This commit is contained in:
wangjinlei
2026-08-05 18:36:17 +08:00
parent 2db6f170fe
commit d72b16d9e8
7 changed files with 563 additions and 112 deletions

View File

@@ -1,8 +1,6 @@
<?php
namespace app\common;
use think\Db;
use think\Env;
use app\common\CrossrefService;
class ProductionArticleRefer
{
@@ -87,60 +85,56 @@ class ProductionArticleRefer
}
//开始用crossref接口的方式处理数据
$doiNorm = preg_replace('#^https?://(dx\.)?doi\.org/#i', '', $aRefer['refer_doi']);
$doiNorm = trim($doiNorm, " \t\n\r\0\x0B/");
//开始用 PubMed(优先)+Crossref(补全) 的方式处理数据
$oMeta = new ReferenceMetadataService();
$doiNorm = $oMeta->normalizeDoi($aRefer['refer_doi']);
$svc = new CrossrefService([
'mailto' => trim((string)Env::get('crossref_mailto', '')),
]);
$summary = $svc->fetchWorkSummary($doiNorm);
if ($summary !== null && !empty($summary['doi'])) {
$title = trim((string)($summary['title'] ?? ''));
$jouraRaw = trim((string)($summary['joura'] ?? ''));
// 姓全写 + 名首字母,超过 3 个作者取前 3 个 + et al
$authorCitation = $svc->getAuthorsCitation($summary['raw'] ?? [], 3);
// 元数据仍是中文时放弃本路径,改走下方 citation.doi.org(lang=en-US) 取英文著录
$meta = $oMeta->fetchByDoi($doiNorm);
if ($meta !== null && !$meta['has_cjk'] && trim((string)$meta['title']) !== '') {
$title = trim((string)$meta['title']);
$authorCitation = trim((string)$meta['author']);
// 英文优先兜底:若 CrossRef 结果的标题/期刊/作者仍含中日韩字符,
// 说明该 DOI 元数据是中文,放弃 CrossRef 路径,改走下方 citation.doi.org(lang=en-US)
$hasCjk = $svc->hasCjk($title) || $svc->hasCjk($jouraRaw) || $svc->hasCjk($authorCitation);
if (!$hasCjk) {
$update_a = [];
$dateno = trim((string)($summary['dateno'] ?? ''));
$doilink = trim((string)($summary['doilink'] ?? ''));
$update_a['title'] = $title;
$update_a['author'] = $authorCitation !== '' ? $authorCitation . '.' : '';
$update_a['joura'] = $jouraRaw;
$update_a['dateno'] = $dateno;
// CrossRef 的 type 最权威,据此确定参考文献类型,未命中回退 journal
$crossrefType = isset($summary['raw']['type']) ? $summary['raw']['type'] : '';
$mappedType = (new ReferenceTypeClassifier())->mapCrossrefType($crossrefType);
$update_a['refer_type'] = $mappedType !== '' ? $mappedType : "journal";
$update_a['is_ja'] = 1;
$update_a['doilink'] = $doilink;
$update_a['cs'] = 1;
$update_a['update_time'] = time();
$update_a['is_deal'] = 1;
$update_a = [];
$update_a['title'] = $title;
$update_a['author'] = $authorCitation !== '' ? $authorCitation . '.' : '';
$update_a['joura'] = trim((string)$meta['joura']);
$update_a['dateno'] = trim((string)$meta['dateno']);
$update_a['refer_type'] = $meta['type'] !== '' ? $meta['type'] : "journal";
$update_a['is_ja'] = 1;
$update_a['doilink'] = trim((string)$meta['doilink']);
$update_a['cs'] = 1;
$update_a['update_time'] = time();
$update_a['is_deal'] = 1;
try {
(new ReferenceReferAuthorService())->syncFromWorkSummary(
try {
$oReferAuthor = new ReferenceReferAuthorService();
if (is_array($meta['crossref_summary'])) {
// Crossref 带 ORCID作者明细优先用它
$oReferAuthor->syncFromWorkSummary(
$iPReferId,
$iPArticleId,
$doiNorm,
$summary
$meta['crossref_summary']
);
} catch (\Throwable $e) {
\think\Log::error(
'ProductionArticleRefer sync refer authors failed p_refer_id='
. $iPReferId . ' ' . $e->getMessage()
} else {
$oReferAuthor->syncFromReferAuthorField(
$iPReferId,
$iPArticleId,
$authorCitation
);
}
Db::name('production_article_refer')->where(['p_refer_id' => $iPReferId])->limit(1)->update($update_a);
return json_encode(['status' => 1,'msg' => 'Update successful']);
} catch (\Throwable $e) {
\think\Log::error(
'ProductionArticleRefer sync refer authors failed p_refer_id='
. $iPReferId . ' ' . $e->getMessage()
);
}
Db::name('production_article_refer')->where(['p_refer_id' => $iPReferId])->limit(1)->update($update_a);
return json_encode(['status' => 1,'msg' => 'Update successful']);
}
//结束---用crossref接口的方式处理数据
//结束---用 PubMed+Crossref 的方式处理数据