大更新,1投稿系统参考文献的类型增加功能,,,2官网数据库功能

This commit is contained in:
wangjinlei
2026-07-08 11:15:44 +08:00
parent 186126a726
commit 05af67bc1a
22 changed files with 1634 additions and 81 deletions

View File

@@ -0,0 +1,162 @@
<?php
namespace app\master\service;
use think\Db;
/**
* 文章 JATS XML 生成器
* 逻辑迁移自 Datebase::xmlCreateForArticle保持输出完全一致供 Scopus / EBSCO 推送复用。
*/
class XmlBuilder
{
/**
* 为文章生成 XML 文件并返回文件绝对路径(已存在则直接返回)
* @param int $article_id
* @return string
*/
public static function forArticle($article_id)
{
$article_obj = Db::name('article');
$journal_obj = Db::name('journal');
$journal_stage_obj = Db::name('journal_stage');
$article_author_obj = Db::name('article_author');
$article_organ_obj = Db::name('article_organ');
$article_author_to_organ_obj = Db::name('article_author_to_organ');
$article_info = $article_obj->where("article_id", $article_id)->find();
$journal_info = $journal_obj->where("journal_id", $article_info['journal_id'])->find();
$file = ROOT_PATH . "public/articleXML/" . substr($article_info['doi'], strpos($article_info['doi'], "/") + 1) . ".xml";
if (is_file($file)) {
return $file;
}
$xml = new \SimpleXMLElement('<article/>');
// 设置命名空间
$xml->addAttribute('xmlns:mml', 'http://www.w3.org/1998/Math/MathML');
$xml->addAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
$xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$xml->addAttribute('article-type', $article_info['type']);
// 创建 <front> 元素
$front = $xml->addChild('front');
// 创建 <journal-meta> 元素并添加子元素
$journalMeta = $front->addChild('journal-meta');
$journalMeta->addChild('journal-id', $journal_info['usx']);
$journalTitleGroup = $journalMeta->addChild('journal-title-group');
$journalTitleGroup->addChild('journal-title', $journal_info['title'])->addAttribute('xml:lang', 'en');
$journalTitleGroup->addChild('abbrev-journal-title', $journal_info['jabbr']);
$journalMeta->addChild('issn', $journal_info['issn'])->addAttribute('pub-type', 'ppub');
$publisher = $journalMeta->addChild('publisher');
$publisher->addChild('publisher-name', 'TMR publisher group');
$publisher->addChild('publisher-name', 'TMR')->addAttribute('specific-use', 'short-name');
// 创建 <article-meta> 元素并添加子元素
$articleMeta = $front->addChild('article-meta');
$articleMeta->addChild('article-id', $article_info['article_id']);
$articleMeta->addChild('article-id', $article_info['doi'])->addAttribute('pub-id-type', 'doi');
$articleCategories = $articleMeta->addChild('article-categories');
$subjGroup = $articleCategories->addChild('subj-group');
$subjGroup->addChild('subject', 'subject')->addAttribute('xml:lang', 'en');
$articleTypeGroup = $articleCategories->addChild('subj-group');
$articleTypeGroup->addAttribute('id', 'article-type');
$articleTypeGroup->addChild('subject', $article_info['type'])->addAttribute('xml:lang', 'en');
// 添加 <title-group> 元素
$titleGroup = $articleMeta->addChild('title-group');
$titleGroup->addChild('article-title', $article_info['title'])->addAttribute('xml:lang', 'en');
$transTitleGroup = $titleGroup->addChild('trans-title-group');
$transTitleGroup->addAttribute('xml:lang', 'en');
$transTitleGroup->addChild('trans-title', $article_info['title'])->addAttribute('xml:lang', 'en');
// 添加 <contrib-group> 和相关的 <contrib> 元素
$contribGroup = $articleMeta->addChild('contrib-group');
$authors = $article_author_obj->where("article_id", $article_id)->where("state", 0)->select();
$organs = $article_organ_obj->where("article_id", $article_id)->select();
$os = [];
foreach ($organs as $k => $v) {
$os[$v['article_organ_id']] = $k + 1;
}
foreach ($authors as $v) {
$contrib_cache = $contribGroup->addChild('contrib');
$contrib_cache->addAttribute('contrib-type', 'author');
$nameAlternatives_cache = $contrib_cache->addChild('name-alternatives');
$name_cache = $nameAlternatives_cache->addChild("name");
$name_cache->addAttribute("name-style", "western");
$name_cache->addAttribute("specific-use", "en");
$name_cache->addAttribute("xml:lang", "en");
$name_cache->addChild("surname", $v['first_name']);
$name_cache->addChild("given-names", $v['last_name']);
$l_c = $article_author_to_organ_obj->where("article_id", $article_id)->where("article_author_id", $v['article_author_id'])->where("state", 0)->select();
foreach ($l_c as $val) {
$xref_cache = $contrib_cache->addChild("xref");
$xref_cache->addAttribute("rid", "aff" . $os[$val['article_organ_id']]);
$xref_cache->addAttribute("xml:base", "aff");
$xref_cache->addAttribute("xml:lang", "en");
$xref_cache->addChild("sup", $os[$val['article_organ_id']]);
}
}
foreach ($organs as $v) {
$affAl_cache = $contribGroup->addChild("aff-alternatives");
$affAl_cache->addAttribute("id", "aff" . $os[$v['article_organ_id']]);
$aff_cache = $affAl_cache->addChild("aff");
$aff_cache->addAttribute("xml:lang", "en");
$aff_cache->addChild("label", htmlspecialchars($os[$v['article_organ_id']] . " " . $v['organ_name']));
$ins_cache = $aff_cache->addChild("institution ", htmlspecialchars($v['organ_name']));
$ins_cache->addAttribute("content-type", 'orgname');
}
// pub-date
$stage_info = $journal_stage_obj->where("journal_stage_id", $article_info['journal_stage_id'])->find();
if ($article_info['pub_date'] != "") {
$pubDate = $articleMeta->addChild("pub_date");
$pub_date_list = explode(" ", $article_info['pub_date']);
$pubDate->addChild("year", $pub_date_list[2]);
$pubDate->addChild("month", $pub_date_list[1]);
}
$vol = $articleMeta->addChild("volume", $stage_info['stage_vol']);
$vol->addAttribute("content-type", "Vol.");
$issue = $articleMeta->addChild("issue", $article_info['npp']);
$issue->addAttribute("content-type", "No.");
// abstract
$abstract = $articleMeta->addChild("abstract");
$abstract->addAttribute("xml:lang", "en");
$abs_p = $abstract->addChild("p", htmlspecialchars($article_info['abstract'], ENT_QUOTES | ENT_XML1, 'UTF-8'));
$abs_p->addAttribute("indent", "0mm");
// keywords
$kwd = $articleMeta->addChild("kwd-group");
$kwd->addAttribute("kwd-group-type", "inspec");
$kwd->addAttribute("xml:lang", "en");
$keywords_list = explode(";", $article_info['keywords']);
foreach ($keywords_list as $v) {
if ($v == "") {
continue;
}
$kwd->addChild("kwd", trim($v));
}
// notes
$notes = $front->addChild("notes");
$notes_p = $notes->addChild("p");
$notes_p->addAttribute("ontent-type", "qrcode");
$notes_p->addAttribute("xml:specific-use", "website");
$url = "https://www.tmrjournals.com/article.html?J_num=" . $journal_info['journal_id'] . "&a_id=" . $article_info['article_id'];
$notes_p_uri = $notes_p->addChild("uri", htmlspecialchars($url));
$notes_p_uri->addAttribute("xlink:href", htmlspecialchars($url));
$notes_p1 = $notes->addChild("p");
$notes_p1->addAttribute("xml:specific-use", "crossmark");
$notes_p1_uri = $notes_p1->addChild("uri");
$notes_p1_uri->addAttribute("xlink:href", "http://crossmark.crossref.org/dialog/?doi=" . $article_info['doi']);
$x = $xml->asXML();
file_put_contents($file, $x);
return $file;
}
}