大更新,1投稿系统参考文献的类型增加功能,,,2官网数据库功能
This commit is contained in:
53
application/master/service/push/AbstractPusher.php
Normal file
53
application/master/service/push/AbstractPusher.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 推送器基类:提供数据表句柄、凭证读取等公共能力
|
||||
*/
|
||||
abstract class AbstractPusher implements PusherInterface
|
||||
{
|
||||
protected $journal_obj;
|
||||
protected $journal_stage_obj;
|
||||
protected $article_obj;
|
||||
protected $article_author_obj;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->journal_obj = Db::name('journal');
|
||||
$this->journal_stage_obj = Db::name('journal_stage');
|
||||
$this->article_obj = Db::name('article');
|
||||
$this->article_author_obj = Db::name('article_author');
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取某个数据库的凭证配置
|
||||
* @param string $key credentials.<key>
|
||||
* @return array
|
||||
*/
|
||||
protected function cred($key)
|
||||
{
|
||||
$all = config('dbpush.credentials');
|
||||
return isset($all[$key]) ? $all[$key] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取顶层 dbpush 配置项
|
||||
*/
|
||||
protected function conf($key, $default = null)
|
||||
{
|
||||
$val = config('dbpush.' . $key);
|
||||
return $val === null ? $default : $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组合文章作者名(逗号分隔)
|
||||
*/
|
||||
protected function getAuthorNames($articleId)
|
||||
{
|
||||
$list = $this->article_author_obj->where('article_id', $articleId)->where('state', 0)->column('author_name');
|
||||
return implode(', ', $list);
|
||||
}
|
||||
}
|
||||
146
application/master/service/push/CnkiPusher.php
Normal file
146
application/master/service/push/CnkiPusher.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
/**
|
||||
* CNKI 中国知网 推送器
|
||||
* 生成整期 Excel 并打包 zip,通过 FTP 上传到知网。
|
||||
* 逻辑迁移自 Datebase::createFtpFileInfo / createZip / sendFtp。
|
||||
*/
|
||||
class CnkiPusher extends AbstractPusher
|
||||
{
|
||||
public function code()
|
||||
{
|
||||
return 'cnki';
|
||||
}
|
||||
|
||||
public function label()
|
||||
{
|
||||
return 'CNKI 中国知网';
|
||||
}
|
||||
|
||||
public function pushStage($journal_stage_id, array $options = [])
|
||||
{
|
||||
$stage_info = $this->journal_stage_obj->where("journal_stage_id", $journal_stage_id)->find();
|
||||
$journalInfo = $this->journal_obj->where('journal_id', $stage_info['journal_id'])->find();
|
||||
$articles = $this->article_obj->where(['journal_stage_id' => $journal_stage_id, 'state' => 0])
|
||||
->field('title as articleTitle,abbr as author,pub_date as date,keywords as keyWords,doi,abstract,file_pdf as pdf,article_id,journal_id')
|
||||
->select();
|
||||
|
||||
foreach ($articles as $k => $v) {
|
||||
$articles[$k]['abstract'] = strip_tags($v['abstract']);
|
||||
$articles[$k]['journalTitle'] = $journalInfo['title'];
|
||||
$articles[$k]['issn'] = $journalInfo['issn'];
|
||||
$articles[$k]['vol'] = $stage_info['stage_vol'];
|
||||
$articles[$k]['issue'] = $stage_info['stage_no'];
|
||||
$articles[$k]['pdf'] = 'https://www.tmrjournals.com/public/articlePDF/' . $v['pdf'];
|
||||
$articles[$k]['linkToAbstract'] = 'https://www.tmrjournals.com/article.html?J_num=' . $v['journal_id'] . '&a_id=' . $v['article_id'];
|
||||
$articles[$k]['publisher'] = 'TMR publishing group';
|
||||
$articles[$k]['reference'] = '';
|
||||
$articles[$k]['eissn'] = '';
|
||||
}
|
||||
$baseDir = ROOT_PATH . 'public' . DS . 'ftpFile' . DS;
|
||||
$outfileTitle = $journalInfo['title'] . "-" . $stage_info['stage_vol'] . "卷" . $stage_info['stage_no'] . "期";
|
||||
|
||||
$res = $this->createZip($articles, $baseDir, $outfileTitle);
|
||||
$resJosn = json_decode($res, true);
|
||||
if ($resJosn['code'] != 0) {
|
||||
throw new \Exception('CNKI zip 生成失败: ' . $resJosn['msg']);
|
||||
}
|
||||
$url = $baseDir . $outfileTitle . ".zip";
|
||||
$this->sendFtp($url, $outfileTitle);
|
||||
|
||||
return PushResult::success('CNKI zip 已生成并上传');
|
||||
}
|
||||
|
||||
private function createZip($articles, $baseDir, $outfileTitle)
|
||||
{
|
||||
Vendor('PHPExcel.PHPExcel');
|
||||
Vendor('PHPExcel.PHPExcel.Worksheet.Drawing');
|
||||
Vendor('PHPExcel.PHPExcel.Writer.Excel2007');
|
||||
$objExcel = new \PHPExcel();
|
||||
$objWriter = \PHPExcel_IOFactory::createWriter($objExcel, 'Excel2007');
|
||||
|
||||
$objActSheet = $objExcel->getActiveSheet();
|
||||
$letter = explode(',', "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O");
|
||||
$arrHeader = array('Article Title', 'Author', 'Publishing Date', 'Key Words', 'Journal Title', 'ISSN', 'EISSN', 'Volume', 'Issue', 'Link to Full-Text Articles (PDF)', 'Abstract', 'DOI', 'Link to Abstract', 'Publisher', 'Reference');
|
||||
$lenth = count($arrHeader);
|
||||
for ($i = 0; $i < $lenth; $i++) {
|
||||
$objActSheet->setCellValue("$letter[$i]1", "$arrHeader[$i]");
|
||||
$objActSheet->getRowDimension('1')->setRowHeight(25);
|
||||
}
|
||||
foreach ($articles as $k => $v) {
|
||||
$k += 2;
|
||||
$objActSheet->setCellValue('A' . $k, $v['articleTitle']);
|
||||
$objActSheet->setCellValue('B' . $k, $v['author']);
|
||||
$objActSheet->setCellValue('C' . $k, $v['date']);
|
||||
$objActSheet->setCellValue('D' . $k, $v['keyWords']);
|
||||
$objActSheet->setCellValue('E' . $k, $v['journalTitle']);
|
||||
$objActSheet->setCellValue('F' . $k, $v['issn']);
|
||||
$objActSheet->setCellValue('G' . $k, $v['eissn']);
|
||||
$objActSheet->setCellValue('H' . $k, $v['vol']);
|
||||
$objActSheet->setCellValue('I' . $k, $v['issue']);
|
||||
$objActSheet->setCellValue('J' . $k, $v['pdf']);
|
||||
$objActSheet->setCellValue('K' . $k, $v['abstract']);
|
||||
$objActSheet->setCellValue('L' . $k, $v['doi']);
|
||||
$objActSheet->setCellValue('M' . $k, $v['linkToAbstract']);
|
||||
$objActSheet->setCellValue('N' . $k, $v['publisher']);
|
||||
$objActSheet->setCellValue('O' . $k, $v['reference']);
|
||||
$objActSheet->getRowDimension($k)->setRowHeight(25);
|
||||
}
|
||||
$width = array(10, 15, 20, 25, 30);
|
||||
$objActSheet->getColumnDimension('A')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('B')->setWidth($width[2]);
|
||||
$objActSheet->getColumnDimension('C')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('D')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('E')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('F')->setWidth($width[2]);
|
||||
$objActSheet->getColumnDimension('G')->setWidth($width[3]);
|
||||
$objActSheet->getColumnDimension('H')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('I')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('J')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('K')->setWidth($width[3]);
|
||||
$objActSheet->getColumnDimension('L')->setWidth($width[3]);
|
||||
$objActSheet->getColumnDimension('M')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('N')->setWidth($width[2]);
|
||||
$objActSheet->getColumnDimension('O')->setWidth($width[1]);
|
||||
if (!is_dir($baseDir)) {
|
||||
@mkdir($baseDir, 0777, true);
|
||||
}
|
||||
$objWriter->save($baseDir . $outfileTitle . ".xlsx");
|
||||
|
||||
$path = $baseDir . $outfileTitle . ".xlsx";
|
||||
$fileName = $outfileTitle . ".zip";
|
||||
$zip = new \ZipArchive;
|
||||
$zip->open($baseDir . $fileName, \ZipArchive::CREATE);
|
||||
$zip->addFile($path, basename($path));
|
||||
$zip->close();
|
||||
unlink($baseDir . $outfileTitle . ".xlsx");
|
||||
|
||||
if (!file_exists($baseDir . $fileName)) {
|
||||
return json_encode(['code' => 1, 'msg' => '无法找到文件']);
|
||||
}
|
||||
return json_encode(['code' => 0, 'msg' => '成功', 'data' => $baseDir . $fileName]);
|
||||
}
|
||||
|
||||
private function sendFtp($url, $title)
|
||||
{
|
||||
$cred = $this->cred('cnki');
|
||||
$con = ftp_connect($cred['host'], $cred['port']);
|
||||
if (!$con) {
|
||||
throw new \Exception('CNKI FTP 连接失败');
|
||||
}
|
||||
$res = ftp_login($con, $cred['user'], $cred['pass']);
|
||||
if (!$res) {
|
||||
ftp_close($con);
|
||||
throw new \Exception('CNKI FTP 登录失败');
|
||||
}
|
||||
$name = iconv("UTF-8", "GBK", $title . '.zip');
|
||||
ftp_pasv($con, true);
|
||||
$data = ftp_put($con, '/' . $name, $url, FTP_BINARY);
|
||||
ftp_close($con);
|
||||
if (!$data) {
|
||||
throw new \Exception('CNKI FTP 上传失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
62
application/master/service/push/EbscoPusher.php
Normal file
62
application/master/service/push/EbscoPusher.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
use app\master\service\XmlBuilder;
|
||||
|
||||
/**
|
||||
* EBSCO 推送器
|
||||
* 为每篇文章生成 XML,连同 PDF 通过 FTP 上传到 EBSCO。
|
||||
* 逻辑迁移自 Datebase::pushXmlToEp / pushFtpForEp。
|
||||
*/
|
||||
class EbscoPusher extends AbstractPusher
|
||||
{
|
||||
public function code()
|
||||
{
|
||||
return 'ebsco';
|
||||
}
|
||||
|
||||
public function label()
|
||||
{
|
||||
return 'EBSCO';
|
||||
}
|
||||
|
||||
public function pushStage($stage_id, array $options = [])
|
||||
{
|
||||
$stage_info = $this->journal_stage_obj->where("journal_stage_id", $stage_id)->find();
|
||||
$list = $this->article_obj->where("journal_stage_id", $stage_id)->select();
|
||||
$journal_info = $this->journal_obj->where("journal_id", $stage_info['journal_id'])->find();
|
||||
$count = 0;
|
||||
foreach ($list as $v) {
|
||||
$local_file = XmlBuilder::forArticle($v['article_id']);
|
||||
$file = substr($v['doi'], strpos($v['doi'], "/") + 1) . ".xml";
|
||||
$remote_file = "/" . $journal_info['title'] . "/" . $stage_info['stage_year'] . "v" . $stage_info['stage_vol'] . "n" . $stage_info['stage_no'] . "-" . $file;
|
||||
$this->pushFtp($remote_file, $local_file);
|
||||
$localPdf = ROOT_PATH . "public/articlePDF/" . $v['file_pdf'];
|
||||
$remotePdf = "/" . $journal_info['title'] . "/" . $stage_info['stage_year'] . "v" . $stage_info['stage_vol'] . "n" . $stage_info['stage_no'] . "-" . substr($v['doi'], strpos($v['doi'], "/") + 1) . ".pdf";
|
||||
$this->pushFtp($remotePdf, $localPdf);
|
||||
$count++;
|
||||
}
|
||||
return PushResult::success("EBSCO 已上传 {$count} 篇文章的 XML/PDF");
|
||||
}
|
||||
|
||||
private function pushFtp($remote_file, $local_file)
|
||||
{
|
||||
$cred = $this->cred('ebsco');
|
||||
$con = ftp_connect($cred['host'], $cred['port']);
|
||||
if (!$con) {
|
||||
throw new \Exception('EBSCO FTP 连接失败');
|
||||
}
|
||||
$res = ftp_login($con, $cred['user'], $cred['pass']);
|
||||
if (!$res) {
|
||||
ftp_close($con);
|
||||
throw new \Exception('EBSCO FTP 登录失败');
|
||||
}
|
||||
ftp_pasv($con, true);
|
||||
$data = ftp_put($con, $remote_file, $local_file, FTP_BINARY);
|
||||
ftp_close($con);
|
||||
if (!$data) {
|
||||
throw new \Exception('EBSCO FTP 上传失败: ' . $remote_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
106
application/master/service/push/EmailDataPusher.php
Normal file
106
application/master/service/push/EmailDataPusher.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
use think\Queue;
|
||||
|
||||
/**
|
||||
* 邮件送交推送器(通用数据库 / 万方等)
|
||||
* 打包整期 docx + PDF + 封面 zip,作为附件发邮件给数据库收件人。
|
||||
* 逻辑迁移自 Datebase::dataPush 的邮件部分 + createEmailFile。
|
||||
*/
|
||||
class EmailDataPusher extends AbstractPusher
|
||||
{
|
||||
public function code()
|
||||
{
|
||||
return 'email_data';
|
||||
}
|
||||
|
||||
public function label()
|
||||
{
|
||||
return '数据库邮件送交';
|
||||
}
|
||||
|
||||
public function pushStage($journal_stage_id, array $options = [])
|
||||
{
|
||||
$stage_info = $this->journal_stage_obj->where("journal_stage_id", $journal_stage_id)->find();
|
||||
$journal_info = $this->journal_obj->where("journal_id", $stage_info["journal_id"])->find();
|
||||
|
||||
// 幂等构建整期附件 zip
|
||||
$zipfile = ROOT_PATH . "public/dataFile/" . $journal_stage_id . '/' . $journal_stage_id . '.zip';
|
||||
if (!file_exists($zipfile)) {
|
||||
$this->buildIssueZip($journal_stage_id, $stage_info, $journal_info);
|
||||
}
|
||||
|
||||
// 收件人:渠道配置优先,否则用默认通用收件人
|
||||
$recipients = !empty($options['recipients']) ? $options['recipients'] : $this->conf('data_recipients', []);
|
||||
if (empty($recipients)) {
|
||||
return PushResult::fail('未配置收件人');
|
||||
}
|
||||
|
||||
$tt = "Dear Database,<br><br>";
|
||||
$tt .= "Please find the PDF files in attachment of published issue (Vol. " . $stage_info['stage_vol'] . ", No." . $stage_info['stage_no'] . ") of " . $journal_info['title'] . ".<br><br>";
|
||||
$tt .= "Yours Sincerely<br>";
|
||||
$tt .= "Dan Chen<br>";
|
||||
$tt .= "Manager<br>";
|
||||
$tt .= "TMR Publishing Group | Editorial Office | New Zealand<br>";
|
||||
$tt .= "Telephone: +64 02108293806<br>";
|
||||
$tt .= "Email: publisher@tmrjournals.com<br>";
|
||||
$tt .= "Website:www.tmrjournals.com";
|
||||
|
||||
foreach ($recipients as $v) {
|
||||
$cdata['email'] = $v;
|
||||
$cdata['title'] = "Data submitted-TMR Publishing Group";
|
||||
$cdata["fromname"] = "Data submitted-TMR Publishing Group";
|
||||
$cdata["content"] = $tt;
|
||||
$cdata["temail"] = $journal_info['email'];
|
||||
$cdata["tpassword"] = $journal_info['epassword'];
|
||||
$cdata["fj"] = $zipfile;
|
||||
Queue::push('app\api\job\mail@puchAndFJ', $cdata, "mail");
|
||||
}
|
||||
|
||||
return PushResult::success('已向 ' . count($recipients) . ' 个收件人加入邮件队列');
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建整期 zip(Contents.docx + 各文章 PDF + 封面)
|
||||
*/
|
||||
private function buildIssueZip($journal_stage_id, $stage_info, $journal_info)
|
||||
{
|
||||
$ts_base_url = $this->conf('ts_base_url');
|
||||
$pdfBase = $this->conf('article_pdf');
|
||||
$publicBase = $this->conf('public_base');
|
||||
|
||||
$url = $ts_base_url . "api/dataApi/createTemplate";
|
||||
$re['issue'] = $stage_info['issue_date'] . ", Volume " . $stage_info['stage_vol'] . " Issue " . $stage_info["stage_no"];
|
||||
$adate = [];
|
||||
$alist = $this->article_obj->where("journal_stage_id", $journal_stage_id)->where("state", 0)->orderRaw("npp + 0")->select();
|
||||
foreach ($alist as $v) {
|
||||
$cache["type"] = $v["type"];
|
||||
$cache["no"] = $v["npp"];
|
||||
$cache["title"] = $v["title"];
|
||||
$cache["author"] = $this->getAuthorNames($v['article_id']);
|
||||
$adate[] = $cache;
|
||||
}
|
||||
$re["date_list"] = json_encode($adate);
|
||||
$res = myPost($url, $re);
|
||||
$r = object_to_array(json_decode($res));
|
||||
$file = $r['data']["file"];
|
||||
|
||||
$base_dir = ROOT_PATH . "public/dataFile/" . $stage_info["journal_stage_id"];
|
||||
if (!is_dir($base_dir)) {
|
||||
@mkdir($base_dir, 0777, true);
|
||||
}
|
||||
$zip = new \ZipArchive;
|
||||
$zip->open($base_dir . '/' . $stage_info["journal_stage_id"] . '.zip', \ZipArchive::CREATE);
|
||||
copy($ts_base_url . 'upload/' . $file, $base_dir . '/' . $stage_info["journal_stage_id"] . ".docx");
|
||||
$zip->addFile($base_dir . '/' . $stage_info["journal_stage_id"] . ".docx", "Contents.docx");
|
||||
foreach ($alist as $v) {
|
||||
copy($pdfBase . $v['file_pdf'], $base_dir . '/' . $v["npp"] . ".pdf");
|
||||
$zip->addFile($base_dir . '/' . $v["npp"] . ".pdf", $v["npp"] . ".pdf");
|
||||
}
|
||||
copy($publicBase . $stage_info["stage_icon"], $base_dir . "/journal.jpg");
|
||||
$zip->addFile($base_dir . "/journal.jpg", "journal.jpg");
|
||||
$zip->close();
|
||||
}
|
||||
}
|
||||
158
application/master/service/push/PorticoPusher.php
Normal file
158
application/master/service/push/PorticoPusher.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
use think\Queue;
|
||||
use sftp\Sftp;
|
||||
|
||||
/**
|
||||
* Portico 推送器
|
||||
* 生成 Excel(SPREADSHEET) + 下载 PDF,随后通过队列 SFTP 上传到 Portico。
|
||||
* 逻辑迁移自 Datebase::bf_db_push / push_sftp。
|
||||
*/
|
||||
class PorticoPusher extends AbstractPusher
|
||||
{
|
||||
public function code()
|
||||
{
|
||||
return 'portico';
|
||||
}
|
||||
|
||||
public function label()
|
||||
{
|
||||
return 'Portico';
|
||||
}
|
||||
|
||||
public function pushStage($stage, array $options = [])
|
||||
{
|
||||
Vendor('PHPExcel.PHPExcel');
|
||||
Vendor('PHPExcel.PHPExcel.Worksheet.Drawing');
|
||||
Vendor('PHPExcel.PHPExcel.Writer.Excel2007');
|
||||
|
||||
$pdfBase = $this->conf('article_pdf');
|
||||
$subBase = $this->conf('article_sub');
|
||||
|
||||
$baseDir = ROOT_PATH . 'public' . DS . 'davExcel' . DS . $stage . DS;
|
||||
if (!is_dir($baseDir)) {
|
||||
@mkdir($baseDir, 0777, true);
|
||||
}
|
||||
$objExcel = new \PHPExcel();
|
||||
$objWriter = \PHPExcel_IOFactory::createWriter($objExcel, 'Excel2007');
|
||||
|
||||
$objActSheet = $objExcel->getActiveSheet();
|
||||
$letter = explode(',', "A,B,C,D,E,F,G,H,I,J,K,L,M,N");
|
||||
$arrHeader = array('Journal Title', 'Journal P-ISSN', 'Journal E-ISSN', 'Article DOI/ID', 'PDF File Name', 'Article Title', 'Authors', 'Publication Date', 'Volume', 'Issue', 'Supplement', 'First Page', 'Last Page', 'Copyright Statement');
|
||||
$lenth = count($arrHeader);
|
||||
for ($i = 0; $i < $lenth; $i++) {
|
||||
$objActSheet->setCellValue("$letter[$i]1", "$arrHeader[$i]");
|
||||
$objActSheet->getRowDimension('1')->setRowHeight(25);
|
||||
}
|
||||
|
||||
$stage_info = $this->journal_stage_obj->where('journal_stage_id', $stage)->find();
|
||||
$journal_info = $this->journal_obj->where('journal_id', $stage_info['journal_id'])->find();
|
||||
$articles = $this->article_obj
|
||||
->field('j_article.*,j_journal.title journalTitle,j_journal.issn')
|
||||
->join("j_journal", "j_article.journal_id = j_journal.journal_id", 'left')
|
||||
->where('j_article.journal_stage_id', $stage)
|
||||
->where('j_article.state', 0)
|
||||
->select();
|
||||
|
||||
foreach ($articles as $k => $v) {
|
||||
$k += 2;
|
||||
$objActSheet->setCellValue('A' . $k, choiseti1($v['article_id'], $v['journalTitle']));
|
||||
$objActSheet->setCellValue('B' . $k, $v['issn']);
|
||||
$objActSheet->setCellValue('C' . $k, '');
|
||||
$objActSheet->setCellValue('D' . $k, $v['doi']);
|
||||
$fpdf = explode("/", $v['file_pdf']);
|
||||
$objActSheet->setCellValue('E' . $k, $fpdf[1]);
|
||||
copy($pdfBase . $v['file_pdf'], $baseDir . $fpdf[1]);
|
||||
$objActSheet->setCellValue('F' . $k, $v['title']);
|
||||
|
||||
$cache_author = $this->article_author_obj->where('article_id', $v['article_id'])->where('state', 0)->column('author_name');
|
||||
$objActSheet->setCellValue('G' . $k, implode(",", $cache_author));
|
||||
$objActSheet->setCellValue('H' . $k, $v['pub_date']);
|
||||
$objActSheet->setCellValue('I' . $k, $stage_info['stage_vol']);
|
||||
if (($journal_info['journal_id'] == 2 && $stage_info['stage_year'] >= 2022) || ($journal_info['journal_id'] == 3 && $stage_info['stage_year'] >= 2022) || ($journal_info['journal_id'] == 17 && $stage_info['stage_year'] >= 2019)) {
|
||||
$objActSheet->setCellValue('J' . $k, '');
|
||||
} else {
|
||||
$objActSheet->setCellValue('J' . $k, $stage_info['issue_date']);
|
||||
}
|
||||
|
||||
if ($v['file_sub'] != '') {
|
||||
$spdf = explode("/", $v['file_sub']);
|
||||
copy($subBase . $v['file_sub'], $baseDir . $spdf[1]);
|
||||
$objActSheet->setCellValue('K' . $k, $spdf[1]);
|
||||
} else {
|
||||
$objActSheet->setCellValue('K' . $k, '');
|
||||
}
|
||||
|
||||
$npp = trim($v['npp']);
|
||||
$npp = str_replace('–', '-', $npp);
|
||||
$npp = str_replace("—", '-', $npp);
|
||||
if (strpos($npp, '-') == false) {
|
||||
$objActSheet->setCellValue('L' . $k, '');
|
||||
$objActSheet->setCellValue('M' . $k, '');
|
||||
} else {
|
||||
$cc = explode('-', trim($npp));
|
||||
$objActSheet->setCellValue('L' . $k, $cc[0]);
|
||||
$objActSheet->setCellValue('M' . $k, $cc[1]);
|
||||
}
|
||||
$objActSheet->setCellValue('N' . $k, "© " . $stage_info['stage_year'] . " By Author(s). Published by TMR Publishing Group Limited. This is an open access article under the CC-BY license. (http://creativecommons.org/licenses/BY/4.0/)");
|
||||
$objActSheet->getRowDimension($k)->setRowHeight(25);
|
||||
}
|
||||
$width = array(10, 15, 20, 25, 30);
|
||||
$objActSheet->getColumnDimension('A')->setWidth($width[2]);
|
||||
$objActSheet->getColumnDimension('B')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('C')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('D')->setWidth($width[2]);
|
||||
$objActSheet->getColumnDimension('E')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('F')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('G')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('H')->setWidth($width[2]);
|
||||
$objActSheet->getColumnDimension('I')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('J')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('K')->setWidth($width[4]);
|
||||
$objActSheet->getColumnDimension('L')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('M')->setWidth($width[1]);
|
||||
$objActSheet->getColumnDimension('N')->setWidth($width[4]);
|
||||
|
||||
$outfileTitle = $stage_info['journal_stage_id'] . "dav";
|
||||
$objWriter->save($baseDir . $outfileTitle . ".xlsx");
|
||||
|
||||
$this->pushSftp($stage, $stage_info, $journal_info);
|
||||
|
||||
return PushResult::success('Portico 文件已生成并加入 SFTP 上传队列');
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建远程目录并将目录内文件通过队列上传到 Portico SFTP
|
||||
*/
|
||||
private function pushSftp($stage, $stage_info, $journal_info)
|
||||
{
|
||||
$cred = $this->cred('portico');
|
||||
// 连接 sftp 服务器,确保远程目录存在
|
||||
$config['host'] = $cred['host'];
|
||||
$config['port'] = $cred['port'];
|
||||
$config['username'] = $cred['user'];
|
||||
$config['password'] = $cred['pass'];
|
||||
$sftp_obj = new Sftp($config);
|
||||
|
||||
$j_base = $sftp_obj->ssh2_dir_exits("/SPREADSHEET/" . $journal_info['issn']);
|
||||
if (!$j_base) {
|
||||
$sftp_obj->ssh2_sftp_mchkdir("/SPREADSHEET/" . $journal_info['issn']);
|
||||
}
|
||||
$m_base = $sftp_obj->ssh2_dir_exits("/SPREADSHEET/" . $journal_info['issn'] . '/' . $stage_info['stage_year'] . '-' . $stage_info['stage_vol'] . '-' . $stage_info['stage_no']);
|
||||
if (!$m_base) {
|
||||
$sftp_obj->ssh2_sftp_mchkdir("/SPREADSHEET/" . $journal_info['issn'] . '/' . $stage_info['stage_year'] . '-' . $stage_info['stage_vol'] . '-' . $stage_info['stage_no']);
|
||||
}
|
||||
|
||||
$files = scandir(ROOT_PATH . 'public' . DS . 'davExcel' . DS . $stage);
|
||||
foreach ($files as $v) {
|
||||
if ($v == '.' || $v == '..') {
|
||||
continue;
|
||||
}
|
||||
$cdata['local'] = ROOT_PATH . 'public' . DS . 'davExcel' . DS . $stage . DS . $v;
|
||||
$cdata['remote'] = "/SPREADSHEET/" . $journal_info['issn'] . '/' . $stage_info['stage_year'] . '-' . $stage_info['stage_vol'] . '-' . $stage_info['stage_no'] . "/" . $v;
|
||||
Queue::push('app\api\job\mysftp@push', $cdata, "mysftp");
|
||||
}
|
||||
}
|
||||
}
|
||||
30
application/master/service/push/PushResult.php
Normal file
30
application/master/service/push/PushResult.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
/**
|
||||
* 推送结果值对象
|
||||
*/
|
||||
class PushResult
|
||||
{
|
||||
/** @var bool 是否成功 */
|
||||
public $ok;
|
||||
/** @var string 描述信息 / 失败原因 */
|
||||
public $message;
|
||||
|
||||
public function __construct($ok, $message = '')
|
||||
{
|
||||
$this->ok = (bool) $ok;
|
||||
$this->message = (string) $message;
|
||||
}
|
||||
|
||||
public static function success($message = 'success')
|
||||
{
|
||||
return new self(true, $message);
|
||||
}
|
||||
|
||||
public static function fail($message)
|
||||
{
|
||||
return new self(false, $message);
|
||||
}
|
||||
}
|
||||
30
application/master/service/push/PusherInterface.php
Normal file
30
application/master/service/push/PusherInterface.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
/**
|
||||
* 数据库推送器接口
|
||||
* 每个学术数据库(Portico / Scopus / EBSCO / CNKI / 邮件送交...)实现一个推送器。
|
||||
*/
|
||||
interface PusherInterface
|
||||
{
|
||||
/**
|
||||
* 渠道唯一标识
|
||||
* @return string
|
||||
*/
|
||||
public function code();
|
||||
|
||||
/**
|
||||
* 展示名
|
||||
* @return string
|
||||
*/
|
||||
public function label();
|
||||
|
||||
/**
|
||||
* 推送整期
|
||||
* @param int $stageId 分期id
|
||||
* @param array $options 渠道额外配置(来自 j_db_channel.config 或默认配置)
|
||||
* @return PushResult
|
||||
*/
|
||||
public function pushStage($stageId, array $options = []);
|
||||
}
|
||||
37
application/master/service/push/ScopusPusher.php
Normal file
37
application/master/service/push/ScopusPusher.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace app\master\service\push;
|
||||
|
||||
use app\master\service\XmlBuilder;
|
||||
|
||||
/**
|
||||
* Scopus (Elsevier) 推送器
|
||||
* 为每篇文章生成 XML,连同 PDF 通过 SFTP 上传到 Elsevier。
|
||||
* 逻辑迁移自 Datebase::scopusPushXML,SFTP 复用 common.php 的 pushSFTPForScopus。
|
||||
*/
|
||||
class ScopusPusher extends AbstractPusher
|
||||
{
|
||||
public function code()
|
||||
{
|
||||
return 'scopus';
|
||||
}
|
||||
|
||||
public function label()
|
||||
{
|
||||
return 'Scopus (Elsevier)';
|
||||
}
|
||||
|
||||
public function pushStage($stage_id, array $options = [])
|
||||
{
|
||||
$list = $this->article_obj->where("journal_stage_id", $stage_id)->where("state", 0)->select();
|
||||
$stage_info = $this->journal_stage_obj->where("journal_stage_id", $stage_id)->find();
|
||||
$count = 0;
|
||||
foreach ($list as $v) {
|
||||
XmlBuilder::forArticle($v['article_id']);
|
||||
$file = substr($v['doi'], strpos($v['doi'], "/") + 1) . ".xml";
|
||||
pushSFTPForScopus($file, $v['file_pdf'], $stage_info);
|
||||
$count++;
|
||||
}
|
||||
return PushResult::success("Scopus 已上传 {$count} 篇文章的 XML/PDF");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user