参考文献格式--book

This commit is contained in:
wangjinlei
2026-08-07 15:26:09 +08:00
parent 32b3233378
commit 175d2edc55
2 changed files with 796 additions and 6 deletions

View File

@@ -21,10 +21,14 @@ class ReferenceDispatchService
/** @var ReferenceMetadataService */
private $metadata;
/** @var BookMetadataService */
private $bookMetadata;
public function __construct()
{
$this->classifier = new ReferenceTypeClassifier(['use_llm' => true]);
$this->metadata = new ReferenceMetadataService();
$this->bookMetadata = new BookMetadataService();
}
/**
@@ -185,18 +189,24 @@ class ReferenceDispatchService
$update['title'] = trim((string)$meta['title']);
$update['joura'] = !empty($raw) ? $this->extractBookPublisher($raw, $summary) : '';
$update['dateno'] = !empty($raw) ? $this->extractBookDateno($raw) : '';
$isbn = !empty($raw) ? $this->extractIsbnFromRaw($raw) : '';
if ($isbn === '' && !empty($refer['refer_doi'])) {
$doi = $this->normalizeDoi($refer['refer_doi']);
$isbn = $doi !== '' ? 'https://doi.org/' . $doi : '';
}
$update['isbn'] = $isbn;
$update['isbn'] = !empty($raw) ? $this->extractIsbnFromRaw($raw) : '';
$update['is_ja'] = 1;
} else {
$parsed = $this->parseBookFromContent($content);
$update = array_merge($update, $parsed);
}
// 图书绝大多数没有 DOICrossref 和原文都给不出 ISBN按书目信息去外部书目库反查
if (trim((string)($update['isbn'] ?? '')) === '') {
$update = array_merge($update, $this->lookupBookIsbn($content, $update));
}
// 反查不到时退回 DOI 链接,保持 isbn 字段"可点开验证"的既有语义
if (trim((string)($update['isbn'] ?? '')) === '' && !empty($refer['refer_doi'])) {
$doi = $this->normalizeDoi($refer['refer_doi']);
$update['isbn'] = $doi !== '' ? 'https://doi.org/' . $doi : '';
}
$hasCore = trim((string)($update['author'] ?? '')) !== ''
&& trim((string)($update['title'] ?? '')) !== '';
$update['cs'] = $hasCore ? 1 : 0;
@@ -207,6 +217,43 @@ class ReferenceDispatchService
Db::name('production_article_refer')->where('p_refer_id', $pReferId)->update($update);
}
/**
* 按书名/作者/年份/版次反查 ISBN顺带补齐缺失的出版社与出版年
*
* @return array 只包含需要覆盖的字段
*/
private function lookupBookIsbn($content, array $update)
{
$known = [
'title' => (string)($update['title'] ?? ''),
'author' => (string)($update['author'] ?? ''),
'publisher' => (string)($update['joura'] ?? ''),
'year' => preg_match('/\b(19|20)\d{2}\b/', (string)($update['dateno'] ?? ''), $m) ? $m[0] : '',
];
try {
$hints = $this->bookMetadata->extractHints($content, $known);
$found = $this->bookMetadata->resolve($hints);
} catch (\Exception $e) {
\think\Log::write('book isbn lookup failed: ' . $e->getMessage(), 'error');
return [];
}
if (trim((string)$found['isbn']) === '') {
return [];
}
$patch = ['isbn' => trim((string)$found['isbn'])];
if (trim((string)($update['joura'] ?? '')) === '' && trim((string)$found['publisher']) !== '') {
$patch['joura'] = trim((string)$found['publisher']);
}
if (trim((string)($update['dateno'] ?? '')) === '' && trim((string)$found['year']) !== '') {
$patch['dateno'] = trim((string)$found['year']);
}
return $patch;
}
private function extractBookPublisher(array $raw, array $summary)
{
$publisher = trim((string)($raw['publisher'] ?? ''));