From e65359433dceef1d19827978caadde7319d865a5 Mon Sep 17 00:00:00 2001
From: wangjinlei <751475802@qq.com>
Date: Thu, 13 Nov 2025 13:15:42 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B0=8Fbug=E4=BF=AE=E5=A4=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/api/controller/Order.php | 97 +++++--
application/api/controller/Preaccept.php | 41 ++-
application/api/controller/Production.php | 332 ++++++++++++++++++++++
3 files changed, 433 insertions(+), 37 deletions(-)
diff --git a/application/api/controller/Order.php b/application/api/controller/Order.php
index e25246f..b3613c7 100644
--- a/application/api/controller/Order.php
+++ b/application/api/controller/Order.php
@@ -81,26 +81,87 @@ class Order extends base{
if(!$rule->check($data)){
return jsonError($rule->getError());
}
- $time = time();
$param = "pi=616562&ms=".$data['ms'];
-
- $hmac = hash_hmac('sha512', $time."paystation".$param, Env::get("paystation.hmac"));
- $url = "https://payments.paystation.co.nz/lookup?".$param."&pstn_HMAC=".$hmac."&pstn_HMACTimestamp=".$time;
+ $url = "https://payments.paystation.co.nz/lookup?".$param;
$res = myGet($url);
return jsonSuccess($res);
}
- public function testtest(){
+ public function testPaystationLookup1(){
+
$data = $this->request->post();
$rule = new Validate([
- "id"=>"require"
+ "transaction_id"=>"require"
]);
if(!$rule->check($data)){
return jsonError($rule->getError());
}
- $res = paystationLookup($data['id']);
- return jsonSuccess(object_to_array(json_decode($res)));
+// $accessToken = createPayStationToken();
+// $curl = curl_init();
+// curl_setopt_array($curl, array(
+// CURLOPT_URL => 'https://api.paystation.co.nz/v1/transactions/'.$data['transaction_id'],
+// CURLOPT_RETURNTRANSFER => true,
+// CURLOPT_ENCODING => '',
+// CURLOPT_MAXREDIRS => 10,
+// CURLOPT_TIMEOUT => 0,
+// CURLOPT_FOLLOWLOCATION => true,
+// CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+// CURLOPT_CUSTOMREQUEST => 'GET',
+// CURLOPT_HTTPHEADER => array(
+// 'Content-Type: application/json',
+// 'Authorization: Bearer '.$accessToken
+// )
+// ));
+// $response = curl_exec($curl);
+// curl_close($curl);
+ $response = paystationLookup($data['transaction_id']);
+
+ $res = object_to_array(json_decode($response));
+ return jsonSuccess($res);
+ }
+
+ public function testPays(){
+ $data = $this->request->post();
+ $rule = new Validate([
+ "ms"=>"require"
+ ]);
+ if(!$rule->check($data)){
+ return jsonError($rule->getError());
+ }
+
+ $url = "https://payments.paystation.co.nz/lookup/";
+ $time = time();
+ $params = [
+ "pi" => "616562",
+ "ms" => $data['ms'],
+ "pstn_HMACTimestamp" => $time
+ ];
+ $secret_key = Env::get("paystation.hmac");// 使用提供的HMAC认证密钥
+// function calculate_hmac($key, $message) {
+// return hash_hmac('sha256', $message, $key);
+// }
+ $query_string = http_build_query($params);
+ $hmac_signature = hash_hmac('sha256', $time."paystation".$query_string,$secret_key);
+ $params["pstn_HMAC"] = $hmac_signature;
+ $url_with_params = $url . '?' . http_build_query($params);
+
+ echo $url_with_params;
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url_with_params);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $response = curl_exec($ch);
+ if(curl_errno($ch)) {
+ echo 'Error:' . curl_error($ch);
+ } else {
+ echo "Response: " . $response;
+ }
+ curl_close($ch);
+
+ return jsonSuccess($response);
+
+
}
@@ -263,12 +324,6 @@ class Order extends base{
return jsonSuccess($frag);
}
- public function myPrin(){
- echo prin(600);
- }
-
-
-
private function creatPaystation($article_id){
$article_info = $this->article_obj->where("article_id",$article_id)->find();
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
@@ -377,20 +432,6 @@ class Order extends base{
return jsonSuccess([]);
}
- public function mytest(){
- $data = $this->request->post();
- $rule = new Validate([
- "order_id"=>"require"
- ]);
- if(!$rule->check($data)){
- return jsonError($rule->getError());
- }
- $info = $this->order_obj->where("order_id",$data['order_id'])->find();
- $re = $this->getOrderStatus($info['paypal_order_id']);
- return jsonSuccess($re);
- }
-
-
private function getOrderStatus($orderId){
$client = $this->createClient();
return $client->getOrdersController()->ordersGet(["id"=>$orderId]);
diff --git a/application/api/controller/Preaccept.php b/application/api/controller/Preaccept.php
index 9f08e11..0d13b83 100644
--- a/application/api/controller/Preaccept.php
+++ b/application/api/controller/Preaccept.php
@@ -733,7 +733,14 @@ class Preaccept extends Base
}
-
+ /**预接收前对文章的支付信息,审核以及相关操作
+ * @return \think\response\Json
+ * @throws \think\Exception
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ * @throws \think\exception\PDOException
+ */
public function getPreacceptPayment(){
$data = $this->request->post();
$rule = new Validate([
@@ -744,28 +751,44 @@ class Preaccept extends Base
}
$article_info = $this->article_obj->where("article_id",$data['article_id'])->find();
$journal_info = $this->journal_obj->where("journal_id",$article_info['journal_id'])->find();
- if(intval($journal_info['fee'])==0||$article_info['ctime']<1735660800){
+ if(intval($journal_info['fee'])==0||$article_info['ctime']<1735660800){//非收费期刊的文章直接返回
$re['state'] = 1;
$re['order'] = null;
$re["fee"] = 0;
return jsonSuccess($re);
}
$order_info = $this->order_obj->where("article_id",$article_info['article_id'])->find();
- if($order_info['pay_type']==2){
+ if($order_info==null){
+ $re['state'] = 0;
+ $re['order'] = null;
+ $re["fee"] = 0;
+ return jsonSuccess($re);
+ }
+// if($order_info['pay_type']==2){
$paystation = $this->paystation_obj->where("ps_id",$order_info['ps_id'])->find();
+ $order_info['paystation'] = $paystation;
if($order_info['state']==0){
$res = object_to_array(json_decode(paystationLookup($paystation['transaction_id'])));
if(isset($res['result']['success'])&&$res['result']['success']){
$this->article_obj->where("article_id",$order_info['article_id'])->update(['is_buy'=>1]);
$this->order_obj->where("order_id",$order_info['order_id'])->update(['state'=>1]);
+ $re['state'] = 1;
+ $re['fee'] = $journal_info['fee'];
+ $re['order'] = $order_info;
+ return jsonSuccess($re);
+ }else{
+ $re['state'] = 0;
+ $re['fee'] = $journal_info['fee'];
+ $re['order'] = $order_info;
+ return jsonSuccess($re);
}
+ }else{
+ $re['state'] = 1;
+ $re['fee'] = $journal_info['fee'];
+ $re['order'] = $order_info;
+ return jsonSuccess($re);
}
- $order_info['paystation'] = $paystation;
- }
- $re['state'] = $order_info?$order_info['state']:$article_info['is_buy'];
- $re['fee'] = $journal_info['fee'];
- $re['order'] = $order_info;
- return jsonSuccess($re);
+// }
}
diff --git a/application/api/controller/Production.php b/application/api/controller/Production.php
index 83fe7d2..036d26e 100644
--- a/application/api/controller/Production.php
+++ b/application/api/controller/Production.php
@@ -1247,6 +1247,338 @@ class Production extends Base
// return jsonSuccess([]);
// }
+/**
+ * 生成LaTeX文档并转换为PDF
+ * @return \think\response\Json
+ */
+public function generateLatexPdf()
+{
+ $data = $this->request->post();
+ $rule = new Validate([
+ 'p_article_id' => 'require|number'
+ ]);
+
+ if (!$rule->check($data)) {
+ return jsonError($rule->getError());
+ }
+
+ try {
+ // 获取文章信息
+ $p_info = $this->production_article_obj->where('p_article_id', $data['p_article_id'])->find();
+ if (!$p_info) {
+ return jsonError('文章实例不存在');
+ }
+
+ // 获取作者信息
+ $authors = $this->production_article_author_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
+
+ // 获取机构信息
+ $organs = $this->production_article_organ_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
+
+ // 获取正文内容
+ $main_contents = $this->production_article_main_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('p_main_id')->select();
+
+ // 获取参考文献
+ $references = $this->production_article_refer_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('index')->select();
+
+ // 构建LaTeX内容
+ $latex_content = $this->buildLatexContent($p_info, $authors, $organs, $main_contents, $references);
+
+ // 创建临时目录
+ $temp_dir = ROOT_PATH . 'public' . DS . 'temp_latex' . DS;
+ if (!is_dir($temp_dir)) {
+ mkdir($temp_dir, 0755, true);
+ }
+
+ // 生成唯一的文件名
+ $filename = 'article_' . $p_info['p_article_id'] . '_' . time();
+ $tex_file = $temp_dir . $filename . '.tex';
+ $pdf_file = $temp_dir . $filename . '.pdf';
+
+ // 写入LaTeX文件
+ file_put_contents($tex_file, $latex_content);
+
+ // 执行LaTeX编译命令生成PDF
+ $command = sprintf(
+ 'cd %s && pdflatex -interaction=nonstopmode -output-directory=%s %s',
+ escapeshellarg($temp_dir),
+ escapeshellarg($temp_dir),
+ escapeshellarg($tex_file)
+ );
+
+ // 执行命令
+ $output = [];
+ $return_var = 0;
+ exec($command, $output, $return_var);
+
+ // 检查PDF是否生成成功
+ if (!file_exists($pdf_file) || filesize($pdf_file) == 0) {
+ return jsonError('PDF生成失败,请检查LaTeX内容或系统环境');
+ }
+
+ // 移动PDF到正式目录
+ $pdf_dir = ROOT_PATH . 'public' . DS . 'latex_pdfs' . DS;
+ if (!is_dir($pdf_dir)) {
+ mkdir($pdf_dir, 0755, true);
+ }
+
+ $final_pdf_path = $pdf_dir . $filename . '.pdf';
+ rename($pdf_file, $final_pdf_path);
+
+ // 清理临时文件
+ if (file_exists($tex_file)) {
+ unlink($tex_file);
+ }
+
+ // 清理辅助文件(.aux, .log等)
+ $aux_file = $temp_dir . $filename . '.aux';
+ $log_file = $temp_dir . $filename . '.log';
+ if (file_exists($aux_file)) unlink($aux_file);
+ if (file_exists($log_file)) unlink($log_file);
+
+ // 返回PDF路径
+ $relative_path = 'latex_pdfs/' . $filename . '.pdf';
+ return jsonSuccess([
+ 'pdf_url' => $relative_path,
+ 'message' => 'PDF生成成功'
+ ]);
+
+ } catch (\Exception $e) {
+ return jsonError('生成过程中发生错误: ' . $e->getMessage());
+ }
+}
+
+/**
+ * 构建LaTeX文档内容
+ * @param $p_info
+ * @param $authors
+ * @param $organs
+ * @param $main_contents
+ * @param $references
+ * @return string
+ */
+private function buildLatexContent($p_info, $authors, $organs, $main_contents, $references)
+{
+ // 构建机构映射
+ $organ_map = [];
+ foreach ($organs as $index => $organ) {
+ $organ_map[$organ['p_article_organ_id']] = $index + 1;
+ }
+
+ // LaTeX文档开始
+ $latex = '\documentclass[twocolumn]{article}' . "\n";
+ $latex .= '\usepackage[utf8]{inputenc}' . "\n";
+ $latex .= '\usepackage[T1]{fontenc}' . "\n";
+ $latex .= '\usepackage{geometry}' . "\n";
+ $latex .= '\usepackage{graphicx}' . "\n";
+ $latex .= '\usepackage{amsmath}' . "\n";
+ $latex .= '\usepackage{amsfonts}' . "\n";
+ $latex .= '\usepackage{amssymb}' . "\n";
+ $latex .= '\usepackage{setspace}' . "\n";
+ $latex .= '\usepackage{titlesec}' . "\n";
+ $latex .= '\usepackage{hyperref}' . "\n";
+ $latex .= '\usepackage{caption}' . "\n";
+ $latex .= '\usepackage{multicol}' . "\n";
+ $latex .= '\usepackage{abstract}' . "\n";
+
+ $latex .= '\geometry{left=1.5cm,right=1.5cm,top=2.5cm,bottom=2.5cm}' . "\n";
+ $latex .= '\setstretch{1.5}' . "\n";
+
+ $latex .= '\title{' . $this->escapeLatexText($p_info['title']) . '}' . "\n";
+
+ // 处理作者和机构
+ if (!empty($authors)) {
+ $author_text = '';
+ $affiliations = [];
+
+ foreach ($authors as $author) {
+ if ($author_text !== '') {
+ $author_text .= ', ';
+ }
+ $author_text .= $this->escapeLatexText($author['first_name'] . ' ' . $author['last_name']);
+
+ // 获取作者的机构
+ $author_organs = $this->production_article_author_to_organ_obj
+ ->where('p_article_author_id', $author['p_article_author_id'])
+ ->where('state', 0)
+ ->select();
+
+ foreach ($author_organs as $ao) {
+ if (isset($organ_map[$ao['p_article_organ_id']])) {
+ $author_text .= '$^{' . $organ_map[$ao['p_article_organ_id']] . '}$';
+ }
+ }
+
+ if ($author['is_report'] == 1) {
+ $author_text .= '$^{*}$';
+ }
+ }
+
+ $latex .= '\author{' . $author_text . "\n";
+
+ // 添加机构信息
+ foreach ($organs as $index => $organ) {
+ $latex .= '\\\\$' . ($index + 1) . '$ ' . $this->escapeLatexText($organ['organ_name']) . "\n";
+ }
+ if (!empty($authors)) {
+ // 查找通讯作者
+ $corresponding_authors = array_filter($authors, function($author) {
+ return $author['is_report'] == 1;
+ });
+
+ if (!empty($corresponding_authors)) {
+ $corr_author = reset($corresponding_authors);
+ $latex .= '\\\\$*$ Corresponding author: ' .
+ $this->escapeLatexText($corr_author['email']) . "\n";
+ }
+ }
+
+ $latex .= '}' . "\n";
+ }
+
+ $latex .= '\date{}' . "\n";
+ $latex .= '\begin{document}' . "\n";
+ $latex .= '\maketitle' . "\n";
+
+ // 摘要
+ if (!empty($p_info['abstract'])) {
+ $latex .= '\begin{abstract}' . "\n";
+ $latex .= $this->escapeLatexText($p_info['abstract']) . "\n";
+ $latex .= '\end{abstract}' . "\n";
+ }
+
+ // 关键词
+ if (!empty($p_info['keywords'])) {
+ $latex .= '\textbf{Keywords:} ' . $this->escapeLatexText($p_info['keywords']) . "\n";
+ $latex .= '\sectionbreak' . "\n";
+ }
+
+ // 正文内容
+ $in_section = false;
+ $section_count = 0;
+
+ foreach ($main_contents as $content) {
+ $text = trim($content['content']);
+
+ // 跳过空内容
+ if (empty($text)) {
+ continue;
+ }
+
+ // 检查是否是标题
+ $clean_text = strip_tags($text);
+ $lower_text = strtolower($clean_text);
+
+ // 判断是否为章节标题
+ if (stripos($lower_text, 'introduction') === 0 ||
+ stripos($lower_text, 'methods') === 0 ||
+ stripos($lower_text, 'results') === 0 ||
+ stripos($lower_text, 'discussion') === 0 ||
+ stripos($lower_text, 'conclusion') === 0 ||
+ stripos($lower_text, 'references') === 0) {
+
+ // 结束前一节
+ if ($in_section) {
+ $latex .= "\n" . '\sectionbreak' . "\n";
+ }
+
+ // 开始新节
+ $section_count++;
+ $section_title = $this->escapeLatexText($clean_text);
+ $latex .= '\section{' . $section_title . '}' . "\n";
+ $in_section = true;
+ }
+ // 检查是否是图片或表格占位符
+ else if (preg_match('/]*imageId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $img_matches)) {
+ $image_id = $img_matches[1];
+ // 这里可以添加图片处理逻辑
+ $latex .= '% 图片插入位置 (ID: ' . $image_id . ')' . "\n";
+ $latex .= '\begin{figure}[htbp]' . "\n";
+ $latex .= '\centering' . "\n";
+ $latex .= '\includegraphics[width=0.8\textwidth]{image_' . $image_id . '}' . "\n";
+ $latex .= '\caption{图片说明}' . "\n";
+ $latex .= '\end{figure}' . "\n";
+ }
+ else if (preg_match('/