This commit is contained in:
2025-01-02 10:56:43 +08:00
25 changed files with 2509 additions and 254 deletions

BIN
src/assets/img/paypal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
src/assets/img/success.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/assets/img/zhifubao.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -191,6 +191,7 @@ export default {
index: '1',
title: this.$t('sidebar.author'),
subs: [
{
index: 'articleList',
title: this.$t('sidebar.author1')
@@ -202,7 +203,10 @@ export default {
{
index: 'articleAdd',
title: this.$t('sidebar.author2')
}
} , {
index: 'orderListAuthor',
title: this.$t('sidebar.author4')
},
]
}
// ,{

View File

@@ -10,6 +10,7 @@ const baseUrl = '/';
// const baseUrl = '/api';
//本地(正式环境 )
// const mediaUrl = 'https://submission.tmrjournals.com/public/';
@@ -28,5 +29,6 @@ export default {
baseUrl,
mediaUrl,
};
</script>

View File

@@ -149,6 +149,7 @@ const en = {
author: 'Author',
author1: 'My manuscripts',
author2: 'Submit manuscript',
author4: 'Order List',
author3: 'Manuscripts in Draft',
editor: 'Editor',
editor1: 'Paper Editing System',
@@ -374,6 +375,25 @@ const en = {
reContent:'Are you sure you want to restore this content?',
uploadImageInfo:'Figures can only upload files in JPG, JPEG, and PNG formats!'
},
pendingPayment:{
title:'Title',
journal:'Journal',
Paymentamount:'Payment Amount',
Paymentstatus:'Payment Status',
subtotal:'Subtotal',
payment:'Online Payment',
payDetail:'Payment Details',
total:'Total price',
youhui:'Discount',
submitOrder:'Submit Order',
state0:'Obligation',
state1:'Payment successful',
state2:'Cancelled',
paymentmethod:'Payment Method',
Disbursements:'Disbursements',
Confirmorderinformation:'Confirm order information',
orderDetail:'Order information',
}
}

View File

@@ -143,6 +143,7 @@ const zh = {
author1: '我的稿件',
author2: '新增稿件',
author3: '草稿箱',
author4: '订单列表',
editor: '编辑',
editor1: '待审稿件',
editormanage: '编辑管理',
@@ -367,6 +368,25 @@ const zh = {
reContent:'确定要恢复这条内容吗?',
uploadImageInfo:'Figures 只能上传 JPG、JPEG 和 PNG 格式的文件'
},
pendingPayment:{
title:'Title',
journal:'期刊',
Paymentamount:'缴费金额',
Paymentstatus:'缴费状态',
subtotal:'小计',
payment:'在线缴费',
payDetail:'付款详情',
total:'总价',
youhui:'优惠',
submitOrder:'提交订单',
state0:'待付款',
state1:'已缴费',
state2:'已取消',
paymentmethod:'付款方式',
Disbursements:'已付款',
Confirmorderinformation:'确认订单信息',
orderDetail:'订单信息',
}
}

View File

@@ -1,5 +1,6 @@
<template>
<div class="container" >
<el-row :gutter="20" >
<el-alert v-if="alertShow"
:title="'Dear '+ user_name + ' Congratulations! , The information will be hidden after ' + hideSec + ' seconds'"
@@ -12,6 +13,7 @@
</el-col>
</el-row>
<!-- 内容 -->
<el-row :gutter="20" class="content_box mt20">
<!-- 文章引用 -->
<el-col :class="['item', 'borderBottom', Ainfo.refer_state.state? 'passborder' : 'notPassborder']">
@@ -19,6 +21,19 @@
<span v-if="Ainfo.refer_state.state" class="el-icon-check pass status"> Complete</span>
<span v-else class="el-icon-pie-chart notPass status"> Pending</span>
</h5>
<div class="con">
<h4>Manuscript payment </h4>
<p class="mt10"><common-paypal-button style="width: 150px;"
:amount="40.00"
:orderId="4477"
@payment-success="handlePaymentSuccess"
@payment-error="handlePaymentError"
/></p>
</div>
<div class="con">
<h4>HTML Proofread </h4>

View File

@@ -107,15 +107,17 @@
"
>
<i class="el-icon-s-grid" style="color: #fff"></i> {{ $t('articleListEditor.JournalInstallment') }}
</p> <p
</p>
<p
@click="
openJournal({
...scope.row
})
"
style=" background-color: #c2d4ff;
style="
background-color: #c2d4ff;
color: #4665b0;
cursor: pointer;
padding: 2px 2px;
font-weight: bold;
@@ -125,7 +127,6 @@
>
<i class="el-icon-connection" style="color: #4665b0"></i> {{ $t('menu.ClassificationmanagementInfo') }}
</p>
<p
@click="
@@ -144,13 +145,23 @@
<el-dialog :title="$t('GroupClassification.edit')" :visible.sync="editDialogVisible" width="600px" :before-close="handleEditClose">
<el-form ref="detail_form" :model="detailForm" :rules="rules" label-width="165px">
<el-form-item label="Journal :">
<p style="display: flex;align-items: center;justify-content: space-between;">
<p style="display: flex; align-items: center; justify-content: space-between">
<span>{{ detailForm.title }}</span>
<span style="border-radius: 4px;padding: 0 4px;line-height: 24px;height: 24px;box-sizing: border-box;border: 1px solid rgb(0, 102, 153) !important; color: rgb(0, 102, 153);font-size: 12px">
{{ getCycle(currentJournal.cycle) }}
</span>
<span
style="
border-radius: 4px;
padding: 0 4px;
line-height: 24px;
height: 24px;
box-sizing: border-box;
border: 1px solid rgb(0, 102, 153) !important;
color: rgb(0, 102, 153);
font-size: 12px;
"
>
{{ getCycle(currentJournal.cycle) }}
</span>
</p>
</el-form-item>
<!-- <el-form-item label="Cover Image :" prop="image">
<el-upload class="avatar-uploader" ref="upIconIMg"
@@ -177,6 +188,10 @@
<el-input-number v-model="detailForm.kfen" :min="0" v-if="source == 'all'"></el-input-number>
<span v-else>{{ detailForm.kfen }}</span>
</el-form-item>
<el-form-item label="Fee :" prop="fee">
<el-input-number v-model="detailForm.fee" :min="0" v-if="source == 'all'"></el-input-number>
<span v-else>{{ detailForm.fee }}</span>
</el-form-item>
<!-- 简介 -->
<el-form-item label="Introduction :" prop="scope">
<el-input type="textarea" rows="5" v-model="detailForm.scope"></el-input>
@@ -188,7 +203,7 @@
</span>
</el-dialog>
<el-drawer
append-to-body
append-to-body
destroy-on-close
:title="$t('GroupClassification.Journal') + ' : ' + currentJournal.title"
:visible.sync="drawer"
@@ -207,10 +222,14 @@
:before-close="handleCloseJournalInstallment"
size="90%"
>
<commonJournalInstallment ref="commonJournalInstallmentRef" :journal="currentJournal" :urlList="urlList"></commonJournalInstallment>
<commonJournalInstallment
ref="commonJournalInstallmentRef"
:journal="currentJournal"
:urlList="urlList"
></commonJournalInstallment>
</el-drawer>
<el-drawer
append-to-body
append-to-body
destroy-on-close
:title="$t('GroupClassification.Journal') + ' : ' + currentJournal.title"
:visible.sync="drawerAgreement"
@@ -519,16 +538,15 @@ export default {
});
},
openJournalInstallment(data) {
// this.$router.push({
// path: '/JournalInstallment',
// query: {
// journal_id: data.journal_id
// }
// this.$router.push({
// path: '/JournalInstallment',
// query: {
// journal_id: data.journal_id
// }
// })
// })
var that = this;
var that = this;
this.currentJournal = data;
this.drawerJournalInstallment = true;
this.$nextTick(() => {
@@ -545,6 +563,7 @@ export default {
email: data.email,
epassword: data.epassword,
kfen: data.kfen,
fee: data.fee,
scope: data.scope
};
this.editDialogVisible = true;

View File

@@ -0,0 +1,39 @@
<template>
<div>
<el-table :data="articles" style="width: 100%">
<el-table-column prop="id" label="稿件ID" width="100"></el-table-column>
<el-table-column prop="title" label="稿件标题"></el-table-column>
<el-table-column prop="author" label="作者"></el-table-column>
<el-table-column prop="amount" label="缴费金额" width="120"></el-table-column>
<el-table-column prop="status" label="缴费状态" width="120"></el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button @click="payArticle(scope.row)" type="primary" size="small">缴费</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
articles: [
{ id: 1, title: '稿件1', author: '作者1', amount: 100, status: '未缴费' },
{ id: 2, title: '稿件2', author: '作者2', amount: 200, status: '未缴费' },
{ id: 3, title: '稿件3', author: '作者3', amount: 300, status: '未缴费' },
// 更多稿件数据...
]
};
},
methods: {
payArticle(article) {
// 在这里实现缴费逻辑例如调用后端API进行缴费
// 缴费成功后更新article.status为'已缴费'
article.status = '已缴费';
this.$message.success(`已成功为稿件 ${article.title} 缴费`);
}
}
};
</script>

View File

@@ -1,5 +1,7 @@
<template>
<div>
<div class="tab_post">
<div v-for="(item, index) in tabsList" @click="jumpTab(index, item)" :class="tabName == item.refName ? 'P_style' : ''">
<h5>

View File

@@ -56,7 +56,9 @@
<el-badge is-dot :hidden="item.editor_act==1?false:true">
{{item.title}}
</el-badge>
</p>
<p style="margin-bottom: 8px;">
<font style="color: #666b7a;">ID : </font>
{{item.accept_sn}}
@@ -75,12 +77,15 @@
</font>
<b style="font-weight: normal;margin: 0 0 0 5px;">{{item.ctime}}</b>
</p>
<div class="man_state" :style="item.state,'3' | stateChange">
<b :style="item.state,'4' | stateChange">
{{item.state,'tst' | stateChange}}
</b>
</div>
<div class="man_btn">
<span @click="esy_mtps(item.article_id)">
<i class="el-icon-collection"></i>Manuscript Tracking
</span>
@@ -100,7 +105,18 @@
<!-- </el-badge> -->
</span>
</span>
</div>
<el-button v-if="item.state == 6&&item.is_buy==0" size="mini" type="primary" style="position: absolute;top: 38%;right: 10px;background: #ff5000 !important;border-color: #ff5000 !important;" @click="goOrderConfirmation(item)">Payment</el-button>
<el-button v-if="item.is_buy==1" size="mini" type="text" style="position: absolute;top: 38%;right: 10px;color: #ff5000 !important;">{{ $t('pendingPayment.state1') }}</el-button>
<!-- v-if="item.state == 6&&item.is_buy==0" -->
<!-- <common-paypal-button
:amount="item.article_id"
:orderId="item.article_id"
@payment-success="handlePaymentSuccess"
@payment-error="handlePaymentError"
/> -->
</div>
<div class="man_progess" v-if="item.state==4" :style="item.state,'2' | stateChange">
@@ -530,6 +546,22 @@
});
},
goOrderConfirmation(data){
this.$router.push({
path: '/OrderConfirmation',
query: {
id: data.article_id
}
});
},
goOrderConfirmationDetail(data){
this.$router.push({
path: '/OrderDetail',
query: {
id: data.article_id
}
});
},
// 点击稿件内容文件
esy_deta(e) {
this.$api

View File

@@ -0,0 +1,800 @@
<template>
<div class="order-confirmation-box">
<div id="paypal-container" style="display: none">
<div id="paypal-payment-button" style="width: 100%; height: 50px"></div>
</div>
<div class="order-confirmation">
<el-descriptions :title="$t('pendingPayment.Confirmorderinformation')" column="2">
<el-descriptions-item label="ID">{{ articleInfo.accept_sn }}</el-descriptions-item>
<el-descriptions-item :label=" $t('pendingPayment.journal')">{{ journalInfo.title }} </el-descriptions-item>
<el-descriptions-item :span="2" style="width: 100%;" :label="$t('pendingPayment.title')"><p>{{ articleInfo.title }}</p></el-descriptions-item>
</el-descriptions>
</div>
<div
id="settlementContainer"
class="trade-container type-of-affix-right-panel-to-bottom bg-white overflow-hidden flex-col rounded-t-16"
>
<div class="SettlementHeader">
<div class="title1">{{ $t('pendingPayment.payDetail') }}</div>
</div>
<div class="settlementPanelContainer">
<div class="priceWrap">
<div class="priceLine priceLine_total">
<div class="priceTotal_title">{{ $t('pendingPayment.total') }}</div>
<div class="priceRight">
<div class="trade-price-container price">
<span class="trade-price-symbol priceTotal_unit">$</span>
<span class="trade-price-integer priceTotal_num">{{ formatAmount(total) }}</span>
</div>
</div>
</div>
<div class="priceLine priceLine_total">
<div class="priceTotal_title" style="font-weight: 400">{{ $t('pendingPayment.youhui') }}</div>
<div class="priceRight" style="font-weight: 400; color: #7c889c">
<div class="trade-price-container price">
<span class="trade-price-symbol priceTotal_unit" style="font-weight: 400; color: #7c889c">$</span>
<span class="trade-price-integer priceTotal_num" style="font-weight: 400; color: #7c889c">0</span>
</div>
</div>
</div>
<div id="paymentCard" class="trade-container type-of-normal rounded-8 mx-16 bg-gray mt-24 mb-24 pb-20 pt-20">
<div class="SettlementOption">
<div class="title">
<label class="ant-checkbox-wrapper">
<span>
<div class="option">
<img
src="https://img.alicdn.com/imgextra/i2/O1CN01Ao5ka31RmZsasktnV_!!6000000002154-2-tps-88-88.png"
class="optionIcon"
/>
<div class="titleArea">
<div class="clamp-wrap clamp-ellipsis optionTitle" style="-webkit-line-clamp: unset">
{{ $t('pendingPayment.paymentmethod') }}
</div>
<div
class="clamp-wrap clamp-ellipsis optionSubTitle"
style="-webkit-line-clamp: unset"
></div>
</div>
</div>
</span>
</label>
</div>
<div class="SettlementInstallmentOptionArea">
<div class="optionArea">
<div
class="installmentOption"
:class="selectedPaymentMethod == 'PayPal' ? 'isSelect' : ''"
@click="selectPaymentMethod('PayPal')"
>
<div
class="ant-row trade-layout-row"
style="height: 100%; align-items: center; justify-content: flex-start"
>
<div class="trade-layout-leaf">
<div class="iconWrapper">
<img src="@/assets/img/paypal.png" class="icon" />
</div>
</div>
<div
class="ant-col trade-layout-col"
style="width: 74%; align-items: flex-start; justify-content: flex-start"
>
<div class="trade-layout-leaf" style="width: 100%">
<div class="clamp-wrap clamp-ellipsis mainTitle" style="-webkit-line-clamp: unset">
PayPal
</div>
</div>
</div>
<div v-if="selectedPaymentMethod === 'PayPal'" class="checkmark"></div>
</div>
</div>
<!-- <div
class="installmentOption"
:class="selectedPaymentMethod == 'Alipay' ? 'isSelect' : ''"
@click="selectPaymentMethod('Alipay')"
>
<div
class="ant-row trade-layout-row"
style="height: 100%; align-items: center; justify-content: flex-start"
>
<div class="trade-layout-leaf">
<div class="iconWrapper">
<img src="@/assets/img/zhifubao.png" class="icon" />
</div>
</div>
<div
class="ant-col trade-layout-col"
style="width: 74%; align-items: flex-start; justify-content: flex-start"
>
<div class="trade-layout-leaf" style="width: 100%">
<div class="clamp-wrap clamp-ellipsis mainTitle" style="-webkit-line-clamp: unset">
支付宝
</div>
</div>
</div>
<div v-if="selectedPaymentMethod === 'Alipay'" class="checkmark"></div>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="SettlementSubmit">
<div class="price">
<p class="title2">{{ $t('pendingPayment.Disbursements') }}</p>
<div class="totalPrice">
<div class="trade-price-container">
<span class="trade-price-symbol totalPrice_unit"><span class="currency">$</span></span>
<span class="trade-price-integer totalPrice_num">{{ formatAmount(total) }}</span>
</div>
</div>
</div>
<div class="btnBox">
<div class="btn" @click="submit">{{ $t('pendingPayment.submitOrder') }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
orderInfo: {},
articleInfo: {},
journalInfo: {},
total: '',
selectedPaymentMethod: 'PayPal', // 默认选中 PayPal
articleId: this.$route.query.id,
urlList: {
detail: 'api/Order/preOrderDetail',
createdOrder: 'api/Order/creatArticleOrder',
completeOrder: 'api/Order/completeOrder',
},
orderId: '1234567890', // 订单号
orderItems: [], // 订单明细
totalAmount: '130.00', // 订单总价
needInvoice: false, // 是否需要发票
invoiceTitle: '', // 发票抬头
invoiceContent: '' // 发票内容
};
},
methods: {
submit() {
// 假设 PayPal 按钮的容器有 id="paypal-button-container"
const paypalButtonContainer = document.getElementById('paypal-container');
// 删除所有 PayPal 按钮
if (paypalButtonContainer) {
paypalButtonContainer.innerHTML = '';
paypalButtonContainer.innerHTML = '<div id="paypal-payment-button"></div>';
}
if (process.env.NODE_ENV === 'development') {
console.log('当前是开发环境');
} else if (process.env.NODE_ENV === 'production') {
console.log('当前是生产环境');
} else if (process.env.NODE_ENV === 'test') {
console.log('当前是测试环境');
}
if (this.selectedPaymentMethod == 'PayPal') {
this.getPayPal();
}
},
getPayPal(id) {
var that = this;
window.paypal
.Buttons({
style: {
layout: 'horizontal', // 水平布局
shape: 'rect', // 矩形形状
label: 'paypal', // 显示 PayPal 标签
tagline: false, // 隐藏标语
color: 'blue', // 按钮颜色为蓝色
size: 'small' // 按钮大小为大
},
onInit: () => {
// 支付按钮加载完成 通知原生关闭loading
console.log('--------1.支付按钮加载完成 关闭loading--------');
// 自动点击 执行支付
console.log('--------2.自动点击 执行支付--------');
// 如果按钮获取到 就 自动执行点击 否则显示按钮
const paypalButton = window.frames[1].document.querySelector('.paypal-button');
if (paypalButton) paypalButton.click();
else {
document.querySelector('#paypal-container').style.display = 'block';
// document.querySelector('#loading').style.display = 'none';
}
},
createOrder: (data, actions) => {
return this.$api
.post(this.urlList.createdOrder, {
article_id: this.articleId
})
.then((res) => {
console.log('res at line 222:', res);
that.orderInfo=res.data.detail
document.querySelector('#paypal-container').style.display = 'none';
return res.data.paypal.jsonResponse.id;
});
},
onApprove(data, actions) {
return actions.order.capture().then((details) => {
console.log('details at line 232:', details.id)
const loading = that.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
setTimeout(() => {
loading.close();
that.$router.replace({ name: 'OrderConfirmation' });
// 跳转到新的路由
that.$api
.post(that.urlList.completeOrder, {
order_id: that.orderInfo.order_id
})
.then((res) => {
});
that.$router.push({
path: '/success',
query: {
id: that.articleId
}
});
}, 500);
});
},
onError(error) {
console.error('支付失败:', error);
that.$message.error('Payment error, please contact the journal editor!');
}
})
.render('#paypal-payment-button')
.then(() => {})
.catch((err) => {
console.error('Error rendering PayPal button:', err);
});
document.querySelector('.paypal-overlay').addEventListener('click', function (event) {
event.stopPropagation();
});
},
getDetail() {
this.$api
.post(this.urlList.detail, {
article_id: this.articleId
})
.then((res) => {
console.log('res at line 191:', res);
if (res.code == 0) {
this.articleInfo = res.data.article_detail;
this.journalInfo = res.data.journal_detail;
// this.orderItems = [
// {
// ...this.articleInfo,
// fee: this.journalInfo.fee,
// journal: this.journalInfo.title
// }
// ];
this.total = this.journalInfo.fee;
}
});
},
formatAmount(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
selectPaymentMethod(method) {
console.log('method at line 191:', method);
this.selectedPaymentMethod = method;
this.$forceUpdate();
},
payWithAlipay() {
// 实现支付宝支付逻辑
alert('使用支付宝支付');
},
payWithPayPal() {
// 实现PayPal支付逻辑
alert('使用PayPal支付');
}
},
created() {
this.getDetail();
},
activated() {
this.getDetail();
}
};
</script>
<style scoped>
.order-confirmation {
text-align: left;
padding: 20px;
background-color: #fff;
/* border: 1px solid #ccc; */
border-radius: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
/* margin: 20px auto; */
margin-top: 20;
box-sizing: border-box;
}
h3 {
margin-bottom: 20px;
}
.order-confirmation-box {
width: 1040px;
margin: 0 auto;
height: 100%;
padding-top: 20px;
box-sizing: border-box;
/* background-color: #f3f6f8; */
}
.orderHeader {
align-items: center;
background-color: #f3f6f8;
border-radius: 8px;
color: #11192d;
display: flex;
flex-direction: row;
font-size: 14px;
height: 48px;
padding: 0 16px;
text-align: center;
}
.grey {
width: 100%;
overflow: hidden;
padding: 20px;
box-sizing: border-box;
background-color: #f3f6f8;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
::v-deep .el-table th {
background-color: #f3f6f8 !important;
color: #11192d !important;
}
::v-deep .el-table {
border-top-left-radius: 8px !important;
border-top-right-radius: 8px !important;
}
.price-24 {
font-size: 30px;
height: 30px;
line-height: 34px;
}
.trade-price-container {
float: right;
font-weight: bold;
/* width: 100%; */
/* align-items: flex-end; */
display: flex;
flex-direction: row;
align-items: center;
}
.trade-price-label,
.trade-price-symbol {
color: #ff5000;
font-size: 16px;
height: 16px;
line-height: 16px;
}
.trade-price-symbol {
/* font-family: AlibabaSans102v1TaoBao-Bold */
}
.trade-price-decimal,
.trade-price-integer,
.trade-price-point {
color: #ff5000;
/* font-family: AlibabaSans102v1TaoBao-Bold; */
font-size: 26px;
height: 26px;
line-height: 26px;
}
.super-text,
.trade-tips {
color: #50607a;
font-size: 12px;
}
#settlementContainer {
background-image: linear-gradient(180deg, #ffebe0, #fff 100px);
}
.rounded-t-16 {
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
.bg-white {
background-color: #fff;
margin-top: 20px;
}
.SettlementHeader {
align-items: center;
display: flex;
flex-direction: row;
margin-bottom: 2px;
padding: 24px 16px;
}
.title1 {
color: #11192d;
font-size: 16px;
font-weight: 600;
height: 16px;
line-height: 16px;
margin-right: 8px;
}
.goodNum {
align-items: baseline;
color: #11192d;
display: flex;
flex-direction: row;
font-size: 14px;
font-weight: 400;
line-height: 16px;
}
.goodNum p {
color: #11192d;
font-size: 18px;
font-weight: 600;
line-height: 16px;
margin: 0 2px;
text-align: center;
}
.priceWrap {
padding: 0 16px;
}
.priceWrap .priceLine {
align-items: center;
display: flex;
justify-content: space-between;
margin-bottom: 12px;
}
.priceWrap .priceLine .priceTotal_title {
color: #11192d;
font-size: 14px;
font-weight: 600;
}
.priceWrap .priceLine .priceRight {
align-items: flex-end;
display: flex;
flex-direction: row;
padding-right: 16px;
position: relative;
}
.priceWrap .priceLine .priceRight img {
height: 8px;
position: absolute;
right: 0;
top: 6px;
width: 8px;
}
.priceWrap .priceLine .priceRight img.arrow_up {
transform: rotate(180deg);
}
.priceWrap .priceLine .priceRight .price {
align-items: baseline;
}
.priceWrap .priceLine_total {
margin-bottom: 16px;
}
.priceWrap .priceTotal_unit {
color: #11192d;
font-size: 12px;
font-weight: 700;
line-height: 14px;
margin-right: 2px;
}
.priceWrap .priceTotal_num {
color: #11192d;
font-size: 18px;
font-weight: 700;
line-height: 18px;
}
.priceWrap .pricePromotion_pre {
color: #ff5000;
font-size: 14px;
font-weight: 600;
line-height: 14px;
}
.priceWrap .pricePromotion_unit {
color: #ff5000;
font-size: 12px;
font-weight: 700;
line-height: 14px;
margin: 0 2px 0 4px;
}
.priceWrap .pricePromotion_num {
color: #ff5000;
font-size: 18px;
font-weight: 700;
line-height: 18px;
}
.rounded-8 {
border-radius: 8px;
}
.SettlementOption--Qu5uk29m {
margin-bottom: 16px;
}
.SettlementOption--Qu5uk29m:last-child {
margin-bottom: 0;
}
.option {
align-items: center;
display: flex;
flex-direction: row;
white-space: nowrap;
word-break: keep-all;
}
.optionIcon {
height: 16px;
margin-right: 8px;
width: 16px;
}
.titleArea {
display: flex;
flex-direction: column;
overflow: hidden;
}
.optionArea {
-moz-column-gap: 8px;
column-gap: 8px;
display: flex;
flex-wrap: wrap;
margin-top: 20px;
}
.optionSubTitle {
color: #7c889c;
font-size: 12px;
}
.optionTitle {
color: #11192d;
font-size: 14px;
font-weight: 600;
line-height: 14px;
}
.bg-gray {
background-color: #f3f6f8;
}
.pb-20 {
padding-bottom: 20px;
}
.installmentOption {
background-color: #fff;
border-radius: 4px;
cursor: pointer;
height: 30px;
margin-bottom: 8px;
padding: 9px 16px;
width: calc(25% - 36px);
position: relative;
}
.trade-layout-row {
display: flex;
flex-direction: row;
}
.trade-layout-col {
display: flex;
flex-direction: column;
}
.icon {
height: 16px;
margin-right: 8px;
width: 16px;
}
.iconWrapper {
align-items: center;
display: flex;
height: 100%;
}
.title {
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 16px 12px;
}
.title .ant-checkbox-wrapper {
flex-grow: 1;
overflow: hidden;
}
.title .ant-checkbox + span {
overflow: hidden;
width: 100%;
}
.title .ant-checkbox {
top: 0;
}
.SettlementInstallmentOptionArea,
.SettlementInstallmentOptionAreaExpanded {
cursor: pointer;
display: flex;
flex-direction: column;
padding: 0 16px;
}
.pt-20 {
padding-top: 20px;
}
.settlementPanelContainer {
border-bottom: 1px solid #f0f3f5;
padding-bottom: 24px;
}
.SettlementSubmit {
align-items: center;
background-color: #fff;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
box-shadow: 0 -1px 0 0 #f0f3f5;
box-sizing: border-box;
display: flex;
height: 80px;
padding: 16px;
}
.SettlementSubmit,
.SettlementSubmit .price {
justify-content: space-between;
}
.SettlementSubmit .title2 {
color: #11192d;
font-size: 14px;
font-weight: 400;
height: 14px;
line-height: 14px;
}
.SettlementSubmit .totalPrice {
align-items: flex-end;
display: flex;
height: 38px;
}
.SettlementSubmit .totalPrice_unit {
color: #ff5000;
font-size: 14px;
}
.SettlementSubmit .totalPrice_num {
color: #ff5000;
font-size: 24px;
line-height: 24px;
}
.SettlementSubmit .btnBox {
align-items: center;
display: flex;
}
.SettlementSubmit .back {
background-color: #fff;
border: 1px solid #e5e8ec;
border-radius: 8px;
color: #7c889c;
cursor: pointer;
flex: 0 0 56px;
font-size: 16px;
font-weight: 600;
height: 46px;
line-height: 46px;
position: relative;
text-align: center;
transition: all 0.3s ease;
width: 56px;
}
.SettlementSubmit .back:hover:after {
background-color: rgba(0, 0, 0, 0.03);
border-radius: 8px;
content: ' ';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
}
.SettlementSubmit .btn {
background-color: #ff5000;
border-radius: 8px;
color: #fff;
cursor: pointer;
flex: 0 0 160px;
font-size: 16px;
font-weight: 600;
height: 48px;
line-height: 48px;
margin-left: 12px;
position: relative;
text-align: center;
transition: all 0.3s ease;
width: 160px;
}
.SettlementSubmit .btn:hover:after {
background-color: rgba(0, 0, 0, 0.03);
border-radius: 8px;
content: ' ';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
}
.btn_disabled {
color: hsla(0, 0%, 100%, 0.5) !important;
pointer-events: none !important;
}
.btn_loading {
background-color: #f5f5f5;
}
.checkmark {
position: absolute;
right: 5px;
top: 16px;
font-size: 20px;
color: #ff5000;
}
.isSelect {
border: 0.5px solid #ff5000;
}
.tableInfo{
font-size: 14px;
}
</style>

View File

@@ -0,0 +1,800 @@
<template>
<div class="order-confirmation-box">
<div id="paypal-container" style="display: none">
<div id="paypal-payment-button" style="width: 100%; height: 50px"></div>
</div>
<div class="order-confirmation">
<el-descriptions :title="$t('pendingPayment.orderDetail')" column="2">
<el-descriptions-item label="ID">{{ articleInfo.accept_sn }}</el-descriptions-item>
<el-descriptions-item :label=" $t('pendingPayment.journal')">{{ journalInfo.title }} </el-descriptions-item>
<el-descriptions-item :span="2" style="width: 100%;" :label="$t('pendingPayment.title')"><p>{{ articleInfo.title }}</p></el-descriptions-item>
</el-descriptions>
</div>
<div
id="settlementContainer"
class="trade-container type-of-affix-right-panel-to-bottom bg-white overflow-hidden flex-col rounded-t-16"
>
<div class="SettlementHeader">
<div class="title1">{{ $t('pendingPayment.payDetail') }}</div>
</div>
<div class="settlementPanelContainer">
<div class="priceWrap">
<div class="priceLine priceLine_total">
<div class="priceTotal_title">{{ $t('pendingPayment.total') }}</div>
<div class="priceRight">
<div class="trade-price-container price">
<span class="trade-price-symbol priceTotal_unit"><span class="currency">$</span></span>
<span class="trade-price-integer priceTotal_num">{{ formatAmount(total) }}</span>
</div>
</div>
</div>
<div class="priceLine priceLine_total">
<div class="priceTotal_title" style="font-weight: 400">{{ $t('pendingPayment.youhui') }}</div>
<div class="priceRight" style="font-weight: 400; color: #7c889c">
<div class="trade-price-container price">
<span class="trade-price-symbol priceTotal_unit" style="font-weight: 400; color: #7c889c">$</span>
<span class="trade-price-integer priceTotal_num" style="font-weight: 400; color: #7c889c">0</span>
</div>
</div>
</div>
<div id="paymentCard" class="trade-container type-of-normal rounded-8 mx-16 bg-gray mt-24 mb-24 pb-20 pt-20">
<div class="SettlementOption">
<div class="title">
<label class="ant-checkbox-wrapper">
<span>
<div class="option">
<img
src="https://img.alicdn.com/imgextra/i2/O1CN01Ao5ka31RmZsasktnV_!!6000000002154-2-tps-88-88.png"
class="optionIcon"
/>
<div class="titleArea">
<div class="clamp-wrap clamp-ellipsis optionTitle" style="-webkit-line-clamp: unset">
{{ $t('pendingPayment.paymentmethod') }}
</div>
<div
class="clamp-wrap clamp-ellipsis optionSubTitle"
style="-webkit-line-clamp: unset"
></div>
</div>
</div>
</span>
</label>
</div>
<div class="SettlementInstallmentOptionArea">
<div class="optionArea">
<div
class="installmentOption"
:class="selectedPaymentMethod == 'PayPal' ? 'isSelect' : ''"
@click="selectPaymentMethod('PayPal')"
>
<div
class="ant-row trade-layout-row"
style="height: 100%; align-items: center; justify-content: flex-start"
>
<div class="trade-layout-leaf">
<div class="iconWrapper">
<img src="@/assets/img/paypal.png" class="icon" />
</div>
</div>
<div
class="ant-col trade-layout-col"
style="width: 74%; align-items: flex-start; justify-content: flex-start"
>
<div class="trade-layout-leaf" style="width: 100%">
<div class="clamp-wrap clamp-ellipsis mainTitle" style="-webkit-line-clamp: unset">
PayPal
</div>
</div>
</div>
<div v-if="selectedPaymentMethod === 'PayPal'" class="checkmark"></div>
</div>
</div>
<!-- <div
class="installmentOption"
:class="selectedPaymentMethod == 'Alipay' ? 'isSelect' : ''"
@click="selectPaymentMethod('Alipay')"
>
<div
class="ant-row trade-layout-row"
style="height: 100%; align-items: center; justify-content: flex-start"
>
<div class="trade-layout-leaf">
<div class="iconWrapper">
<img src="@/assets/img/zhifubao.png" class="icon" />
</div>
</div>
<div
class="ant-col trade-layout-col"
style="width: 74%; align-items: flex-start; justify-content: flex-start"
>
<div class="trade-layout-leaf" style="width: 100%">
<div class="clamp-wrap clamp-ellipsis mainTitle" style="-webkit-line-clamp: unset">
支付宝
</div>
</div>
</div>
<div v-if="selectedPaymentMethod === 'Alipay'" class="checkmark"></div>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="SettlementSubmit">
<div class="price">
<p class="title2">{{ $t('pendingPayment.Disbursements') }}</p>
<div class="totalPrice">
<div class="trade-price-container">
<span class="trade-price-symbol totalPrice_unit"><span class="currency">$</span></span>
<span class="trade-price-integer totalPrice_num">{{ formatAmount(total) }}</span>
</div>
</div>
</div>
<div class="btnBox">
<div class="btn">{{ $t('pendingPayment.submitOrder') }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
orderInfo: {},
articleInfo: {},
journalInfo: {},
total: '',
selectedPaymentMethod: 'PayPal', // 默认选中 PayPal
articleId: this.$route.query.id,
urlList: {
detail: 'api/Order/preOrderDetail',
createdOrder: 'api/Order/creatArticleOrder',
completeOrder: 'api/Order/completeOrder',
},
orderId: '1234567890', // 订单号
orderItems: [], // 订单明细
totalAmount: '130.00', // 订单总价
needInvoice: false, // 是否需要发票
invoiceTitle: '', // 发票抬头
invoiceContent: '' // 发票内容
};
},
methods: {
submit() {
// 假设 PayPal 按钮的容器有 id="paypal-button-container"
const paypalButtonContainer = document.getElementById('paypal-container');
// 删除所有 PayPal 按钮
if (paypalButtonContainer) {
paypalButtonContainer.innerHTML = '';
paypalButtonContainer.innerHTML = '<div id="paypal-payment-button"></div>';
}
if (process.env.NODE_ENV === 'development') {
console.log('当前是开发环境');
} else if (process.env.NODE_ENV === 'production') {
console.log('当前是生产环境');
} else if (process.env.NODE_ENV === 'test') {
console.log('当前是测试环境');
}
if (this.selectedPaymentMethod == 'PayPal') {
this.getPayPal();
}
},
getPayPal(id) {
var that = this;
window.paypal
.Buttons({
style: {
layout: 'horizontal', // 水平布局
shape: 'rect', // 矩形形状
label: 'paypal', // 显示 PayPal 标签
tagline: false, // 隐藏标语
color: 'blue', // 按钮颜色为蓝色
size: 'small' // 按钮大小为大
},
onInit: () => {
// 支付按钮加载完成 通知原生关闭loading
console.log('--------1.支付按钮加载完成 关闭loading--------');
// 自动点击 执行支付
console.log('--------2.自动点击 执行支付--------');
// 如果按钮获取到 就 自动执行点击 否则显示按钮
const paypalButton = window.frames[1].document.querySelector('.paypal-button');
if (paypalButton) paypalButton.click();
else {
document.querySelector('#paypal-container').style.display = 'block';
// document.querySelector('#loading').style.display = 'none';
}
},
createOrder: (data, actions) => {
return this.$api
.post(this.urlList.createdOrder, {
article_id: this.articleId
})
.then((res) => {
console.log('res at line 222:', res);
that.orderInfo=res.data.detail
document.querySelector('#paypal-container').style.display = 'none';
return res.data.paypal.jsonResponse.id;
});
},
onApprove(data, actions) {
return actions.order.capture().then((details) => {
console.log('details at line 232:', details.id)
const loading = that.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
setTimeout(() => {
loading.close();
that.$router.replace({ name: 'OrderConfirmation' });
// 跳转到新的路由
that.$api
.post(that.urlList.completeOrder, {
order_id: that.orderInfo.order_id
})
.then((res) => {
});
that.$router.push({
path: '/success',
query: {
id: that.articleId
}
});
}, 500);
});
},
onError(error) {
console.error('支付失败:', error);
that.$message.error('Payment error, please contact the journal editor!');
}
})
.render('#paypal-payment-button')
.then(() => {})
.catch((err) => {
console.error('Error rendering PayPal button:', err);
});
document.querySelector('.paypal-overlay').addEventListener('click', function (event) {
event.stopPropagation();
});
},
getDetail() {
this.$api
.post(this.urlList.detail, {
article_id: this.articleId
})
.then((res) => {
console.log('res at line 191:', res);
if (res.code == 0) {
this.articleInfo = res.data.article_detail;
this.journalInfo = res.data.journal_detail;
// this.orderItems = [
// {
// ...this.articleInfo,
// fee: this.journalInfo.fee,
// journal: this.journalInfo.title
// }
// ];
this.total = this.journalInfo.fee;
}
});
},
formatAmount(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
selectPaymentMethod(method) {
console.log('method at line 191:', method);
this.selectedPaymentMethod = method;
this.$forceUpdate();
},
payWithAlipay() {
// 实现支付宝支付逻辑
alert('使用支付宝支付');
},
payWithPayPal() {
// 实现PayPal支付逻辑
alert('使用PayPal支付');
}
},
created() {
this.getDetail();
},
activated() {
this.getDetail();
}
};
</script>
<style scoped>
.order-confirmation {
text-align: left;
padding: 20px;
background-color: #fff;
/* border: 1px solid #ccc; */
border-radius: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
/* margin: 20px auto; */
margin-top: 20;
box-sizing: border-box;
}
h3 {
margin-bottom: 20px;
}
.order-confirmation-box {
width: 1040px;
margin: 0 auto;
height: 100%;
padding-top: 20px;
box-sizing: border-box;
/* background-color: #f3f6f8; */
}
.orderHeader {
align-items: center;
background-color: #f3f6f8;
border-radius: 8px;
color: #11192d;
display: flex;
flex-direction: row;
font-size: 14px;
height: 48px;
padding: 0 16px;
text-align: center;
}
.grey {
width: 100%;
overflow: hidden;
padding: 20px;
box-sizing: border-box;
background-color: #f3f6f8;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
::v-deep .el-table th {
background-color: #f3f6f8 !important;
color: #11192d !important;
}
::v-deep .el-table {
border-top-left-radius: 8px !important;
border-top-right-radius: 8px !important;
}
.price-24 {
font-size: 30px;
height: 30px;
line-height: 34px;
}
.trade-price-container {
float: right;
font-weight: bold;
/* width: 100%; */
/* align-items: flex-end; */
display: flex;
flex-direction: row;
align-items: center;
}
.trade-price-label,
.trade-price-symbol {
color: #ff5000;
font-size: 16px;
height: 16px;
line-height: 16px;
}
.trade-price-symbol {
/* font-family: AlibabaSans102v1TaoBao-Bold */
}
.trade-price-decimal,
.trade-price-integer,
.trade-price-point {
color: #ff5000;
/* font-family: AlibabaSans102v1TaoBao-Bold; */
font-size: 26px;
height: 26px;
line-height: 26px;
}
.super-text,
.trade-tips {
color: #50607a;
font-size: 12px;
}
#settlementContainer {
background-image: linear-gradient(180deg, #ffebe0, #fff 100px);
}
.rounded-t-16 {
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
.bg-white {
background-color: #fff;
margin-top: 20px;
}
.SettlementHeader {
align-items: center;
display: flex;
flex-direction: row;
margin-bottom: 2px;
padding: 24px 16px;
}
.title1 {
color: #11192d;
font-size: 16px;
font-weight: 600;
height: 16px;
line-height: 16px;
margin-right: 8px;
}
.goodNum {
align-items: baseline;
color: #11192d;
display: flex;
flex-direction: row;
font-size: 14px;
font-weight: 400;
line-height: 16px;
}
.goodNum p {
color: #11192d;
font-size: 18px;
font-weight: 600;
line-height: 16px;
margin: 0 2px;
text-align: center;
}
.priceWrap {
padding: 0 16px;
}
.priceWrap .priceLine {
align-items: center;
display: flex;
justify-content: space-between;
margin-bottom: 12px;
}
.priceWrap .priceLine .priceTotal_title {
color: #11192d;
font-size: 14px;
font-weight: 600;
}
.priceWrap .priceLine .priceRight {
align-items: flex-end;
display: flex;
flex-direction: row;
padding-right: 16px;
position: relative;
}
.priceWrap .priceLine .priceRight img {
height: 8px;
position: absolute;
right: 0;
top: 6px;
width: 8px;
}
.priceWrap .priceLine .priceRight img.arrow_up {
transform: rotate(180deg);
}
.priceWrap .priceLine .priceRight .price {
align-items: baseline;
}
.priceWrap .priceLine_total {
margin-bottom: 16px;
}
.priceWrap .priceTotal_unit {
color: #11192d;
font-size: 12px;
font-weight: 700;
line-height: 14px;
margin-right: 2px;
}
.priceWrap .priceTotal_num {
color: #11192d;
font-size: 18px;
font-weight: 700;
line-height: 18px;
}
.priceWrap .pricePromotion_pre {
color: #ff5000;
font-size: 14px;
font-weight: 600;
line-height: 14px;
}
.priceWrap .pricePromotion_unit {
color: #ff5000;
font-size: 12px;
font-weight: 700;
line-height: 14px;
margin: 0 2px 0 4px;
}
.priceWrap .pricePromotion_num {
color: #ff5000;
font-size: 18px;
font-weight: 700;
line-height: 18px;
}
.rounded-8 {
border-radius: 8px;
}
.SettlementOption--Qu5uk29m {
margin-bottom: 16px;
}
.SettlementOption--Qu5uk29m:last-child {
margin-bottom: 0;
}
.option {
align-items: center;
display: flex;
flex-direction: row;
white-space: nowrap;
word-break: keep-all;
}
.optionIcon {
height: 16px;
margin-right: 8px;
width: 16px;
}
.titleArea {
display: flex;
flex-direction: column;
overflow: hidden;
}
.optionArea {
-moz-column-gap: 8px;
column-gap: 8px;
display: flex;
flex-wrap: wrap;
margin-top: 20px;
}
.optionSubTitle {
color: #7c889c;
font-size: 12px;
}
.optionTitle {
color: #11192d;
font-size: 14px;
font-weight: 600;
line-height: 14px;
}
.bg-gray {
background-color: #f3f6f8;
}
.pb-20 {
padding-bottom: 20px;
}
.installmentOption {
background-color: #fff;
border-radius: 4px;
cursor: pointer;
height: 30px;
margin-bottom: 8px;
padding: 9px 16px;
width: calc(25% - 36px);
position: relative;
}
.trade-layout-row {
display: flex;
flex-direction: row;
}
.trade-layout-col {
display: flex;
flex-direction: column;
}
.icon {
height: 16px;
margin-right: 8px;
width: 16px;
}
.iconWrapper {
align-items: center;
display: flex;
height: 100%;
}
.title {
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 16px 12px;
}
.title .ant-checkbox-wrapper {
flex-grow: 1;
overflow: hidden;
}
.title .ant-checkbox + span {
overflow: hidden;
width: 100%;
}
.title .ant-checkbox {
top: 0;
}
.SettlementInstallmentOptionArea,
.SettlementInstallmentOptionAreaExpanded {
cursor: pointer;
display: flex;
flex-direction: column;
padding: 0 16px;
}
.pt-20 {
padding-top: 20px;
}
.settlementPanelContainer {
border-bottom: 1px solid #f0f3f5;
padding-bottom: 24px;
}
.SettlementSubmit {
align-items: center;
background-color: #fff;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
box-shadow: 0 -1px 0 0 #f0f3f5;
box-sizing: border-box;
display: flex;
height: 80px;
padding: 16px;
}
.SettlementSubmit,
.SettlementSubmit .price {
justify-content: space-between;
}
.SettlementSubmit .title2 {
color: #11192d;
font-size: 14px;
font-weight: 400;
height: 14px;
line-height: 14px;
}
.SettlementSubmit .totalPrice {
align-items: flex-end;
display: flex;
height: 38px;
}
.SettlementSubmit .totalPrice_unit {
color: #ff5000;
font-size: 14px;
}
.SettlementSubmit .totalPrice_num {
color: #ff5000;
font-size: 24px;
line-height: 24px;
}
.SettlementSubmit .btnBox {
align-items: center;
display: flex;
}
.SettlementSubmit .back {
background-color: #fff;
border: 1px solid #e5e8ec;
border-radius: 8px;
color: #7c889c;
cursor: pointer;
flex: 0 0 56px;
font-size: 16px;
font-weight: 600;
height: 46px;
line-height: 46px;
position: relative;
text-align: center;
transition: all 0.3s ease;
width: 56px;
}
.SettlementSubmit .back:hover:after {
background-color: rgba(0, 0, 0, 0.03);
border-radius: 8px;
content: ' ';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
}
.SettlementSubmit .btn {
background-color: #ff5000;
border-radius: 8px;
color: #fff;
cursor: pointer;
flex: 0 0 160px;
font-size: 16px;
font-weight: 600;
height: 48px;
line-height: 48px;
margin-left: 12px;
position: relative;
text-align: center;
transition: all 0.3s ease;
width: 160px;
}
.SettlementSubmit .btn:hover:after {
background-color: rgba(0, 0, 0, 0.03);
border-radius: 8px;
content: ' ';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
}
.btn_disabled {
color: hsla(0, 0%, 100%, 0.5) !important;
pointer-events: none !important;
}
.btn_loading {
background-color: #f5f5f5;
}
.checkmark {
position: absolute;
right: 5px;
top: 16px;
font-size: 20px;
color: #ff5000;
}
.isSelect {
border: 0.5px solid #ff5000;
}
.tableInfo{
font-size: 14px;
}
</style>

View File

@@ -0,0 +1,84 @@
<template>
<div ref="paypalButtonContainer"></div>
</template>
<script>
import { defineComponent, onMounted, ref } from "vue";
export default defineComponent({
name: "PayPalButton",
props: {
amount: {
type: String,
required: true,
},
clientId: {
type: String,
required: true,
},
},
setup(props) {
const paypalButtonContainer = ref(null);
// 动态加载 PayPal SDK
onMounted(() => {
if (!window.paypal) {
const script = document.createElement("script");
script.src = `https://www.paypal.com/sdk/js?client-id=${props.clientId}`;
script.async = true;
script.onload = () => renderPayPalButton();
document.body.appendChild(script);
} else {
renderPayPalButton();
}
});
// 渲染 PayPal 按钮
const renderPayPalButton = () => {
window.paypal.Buttons({
style: {
layout: 'horizontal',
shape: 'rect',
label: 'paypal',
tagline: false
},
createOrder(data, actions) {
// return actions.order.create({
// purchase_units: [
// {
// amount: {
// value: props.amount, // 订单金额
// },
// },
// ],
// });
return '6VT20279NK3463528'
},
onApprove(data, actions) {
return actions.order.capture().then((details) => {
console.log("支付成功!", details);
alert(`支付成功!支付者:${details.payer.name.given_name}`);
});
},
onError(error) {
console.error("支付失败:", error);
alert("支付失败,请重试!");
},
}).render(paypalButtonContainer.value);
};
return {
paypalButtonContainer,
};
},
});
</script>
<style scoped>
/* Add custom styles for the PayPal button if needed */
</style>

View File

@@ -0,0 +1,69 @@
<template>
<!-- 动态生成一个唯一的ID以确保每个PayPal按钮都有一个独立的容器 -->
<div >
<div :id="'paypal-button-container-' + orderId" ref="paypalButtonContainer"></div>
</div>
</template>
<script>
import { defineComponent, onMounted, ref, watch } from 'vue';
export default defineComponent({
name: 'PayPalButton',
props: {
amount: {
type: String,
required: true
},
clientId: {
type: String,
required: true,
default:'ATqBigrhcNdqR8J83aDjTOoJHsAVz0U45JRY4H0stcEcv0mQrMDHQmyrydQInYd1w4lJ1ee3Wsblm2WP'
},
orderId: {
// type: String,
// required: true
}
},
mounted() {
this.getPayPal();
},
methods: {
getPayPal() {
var that = this;
window.paypal
.Buttons({
style: {
layout: 'horizontal', // 水平布局
shape: 'rect', // 矩形形状
label: 'paypal', // 显示 PayPal 标签
tagline: false, // 隐藏标语
color: 'blue', // 按钮颜色为蓝色
size: 'small' // 按钮大小为大
},
createOrder: (data, actions) => {
return '6XN58648LW618025W';
},
onApprove(data, actions) {
return actions.order.capture().then((details) => {
console.log('支付成功!', details);
that.$emit('payment-success', details); // 触发成功事件
});
},
onError(error) {
console.error('支付失败:', error);
that.$emit('payment-error', error); // 触发失败事件
}
})
.render('#paypal-button-container-' + that.orderId);
}
}
});
</script>
<style scoped>
/* 可以添加自定义样式 */
</style>

View File

@@ -0,0 +1,60 @@
<template>
<div>
<el-table :data="list" style="width: 100%">
<slot name="tableItem"></slot>
<el-table-column prop="id" label="ID" width="100"></el-table-column>
<el-table-column prop="title" :label="$t('pendingPayment.title')"></el-table-column>
<el-table-column prop="author" :label="$t('pendingPayment.journal')"></el-table-column>
<el-table-column prop="amount" :label="$t('pendingPayment.Paymentamount')" width="140">
<template slot-scope="scope">
{{ formatAmount(scope.row.amount) }}
</template>
</el-table-column>
<el-table-column prop="status" :label="$t('pendingPayment.Paymentstatus')" width="140"></el-table-column>
<el-table-column label="" width="140">
<template slot-scope="scope">
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
components: {
},
props: {
list: {
type: Array,
default: () => []
}
},
data() {
return {};
},
methods: {
handlePaymentSuccess(payment) {
// Handle payment success
console.log('Payment successful!', payment);
},
handlePaymentError(error) {
// Handle payment error
console.error('Payment error:', error);
},
formatAmount(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
payArticle(article) {
// 在这里实现缴费逻辑例如调用后端API进行缴费
// 缴费成功后更新article.status为'已缴费'
article.status = '已缴费';
this.$message.success(`已成功为稿件 ${article.title} 缴费`);
}
}
};
</script>

View File

@@ -0,0 +1,118 @@
<template>
<div class="success-box" v-if="articleInfo.accept_sn">
<div class="payment-success">
<div style="display: flex; align-items: center;margin-bottom: 10px;">
<h2 style="margin: 0 auto;display: flex; align-items: center">
<img src="@/assets/img/success.png" alt="" style="margin-right: 20px; width: 128px; height: 128px" />Payment Successful
</h2>
</div>
<p>Thank you for your payment. Your order has been successfully processed.</p>
<p>
Article ID:
<span style="color: #333; font-weight: 600"> {{ articleInfo.accept_sn }}</span>
</p>
<p>
Total Amount: <span style="color: #ff5000"><span class="currency">$</span></span
><span style="color: #ff5000; font-size: 24px; line-height: 24px">{{ formatAmount(total) }}</span>
</p>
<!-- <p>Payment Method: {{ paymentMethod }}</p> -->
<p>You will receive an email confirmation shortly.</p>
<button @click="goBack">Back to Order List</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
urlList: {
detail: 'api/Order/preOrderDetail',
createdOrder: 'api/Order/creatArticleOrder'
},
articleInfo: {},
journalInfo: {},
total: '',
articleId: this.$route.query.id
};
},
created() {
this.getDetail();
},
methods: {
formatAmount(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
getDetail() {
this.$api
.post(this.urlList.detail, {
article_id: this.articleId
})
.then((res) => {
console.log('res at line 191:', res);
if (res.code == 0) {
this.articleInfo = res.data.article_detail;
this.journalInfo = res.data.journal_detail;
this.total = this.journalInfo.fee;
}
});
},
goBack() {
this.$router.replace({ name: 'success' });
// 跳转到新的路由
this.$router.push({
path: '/orderListAuthor'
});
}
}
};
</script>
<style scoped>
.payment-success {
margin-top: 40px;
margin: 0 auto;
text-align: center;
padding: 20px;
background-color: #fff;
border: 1px solid #c3e6cb;
border-radius: 16px;
color: #155724;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
width: 600px;
}
h2 {
margin-bottom: 20px;
}
p {
margin-bottom: 10px;
}
button {
padding: 10px 20px;
background-color: #00c286;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
margin-top: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* 按钮添加阴影效果 */
}
button:hover {
background-color: #00c286;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); /* 按钮悬停时的阴影效果 */
}
.success-box {
display: flex;
align-items: center;
/* justify-content: center; */
width: 100%;
height: 100%;
}
</style>

View File

@@ -249,7 +249,7 @@ export default {
isShowEditComment() {
if (localStorage.getItem('U_role')) {
var identity = localStorage.getItem('U_role');
if (identity.includes('editor')) {
this.isEditComment = true;
} else {
@@ -386,256 +386,254 @@ export default {
content_css: 'default',
setup(ed) {
if(!_this.readonly){
ed.on('click', function (e) {
// 判断点击的是否是目标元素
const target = e.target;
console.log('target at line 351:', target);
if (target.classList.contains('isRemarkIcon')) {
_this.$emit('onComment', target.getAttribute('main-id'));
}
});
// // 添加批注按钮
ed.ui.registry.addButton('addImageButton', {
text: 'Add Figure',
icon: 'comment',
onAction: function () {
_this.$emit('add', img);
// const selection = ed.selection;
// const selectedNode = selection.getNode(); // 获取选中的节点
// console.log('selectedNode at line 333:', selectedNode);
// if (selectedNode) {
// const comment = prompt('Enter your comment:');
// if (comment) {
// const dataId = selectedNode.getAttribute('main-id');
// _this.comments.push({ text: comment, time: new Date().getTime(), mId: dataId });
// }
// } else {
// alert('Please select some text to comment on.');
// }
}
});
ed.on('dragstart', (e) => {
// 阻止拖动事件
e.preventDefault();
});
// 监听焦点变化并高亮当前选中的元素
ed.on('focus', function () {
if (!isDeleting) {
// 处理正常的焦点逻辑
ed.getBody().style.outline = 'none'; // 当编辑器获取焦点时,移除焦点框
if (!_this.readonly) {
ed.on('click', function (e) {
// 判断点击的是否是目标元素
const target = e.target;
console.log('target at line 351:', target);
if (target.classList.contains('isRemarkIcon')) {
_this.$emit('onComment', target.getAttribute('main-id'));
}
});
// // 添加批注按钮
ed.ui.registry.addButton('addImageButton', {
text: 'Add Figure',
icon: 'comment',
onAction: function () {
_this.$emit('add', img);
// const selection = ed.selection;
// const selectedNode = selection.getNode(); // 获取选中的节点
// console.log('selectedNode at line 333:', selectedNode);
// if (selectedNode) {
// const comment = prompt('Enter your comment:');
// if (comment) {
// const dataId = selectedNode.getAttribute('main-id');
// _this.comments.push({ text: comment, time: new Date().getTime(), mId: dataId });
// }
// } else {
// alert('Please select some text to comment on.');
// }
}
});
ed.on('dragstart', (e) => {
// 阻止拖动事件
e.preventDefault();
});
// 监听焦点变化并高亮当前选中的元素
ed.on('focus', function () {
if (!isDeleting) {
// 处理正常的焦点逻辑
ed.getBody().style.outline = 'none'; // 当编辑器获取焦点时,移除焦点框
_this.updateCurrentTag(ed);
}
});
// 监听焦点变化并高亮当前选中的元素
ed.on('selectionChange', function () {
_this.updateCurrentTag(ed);
}
});
// 监听焦点变化并高亮当前选中的元素
ed.on('selectionChange', function () {
_this.updateCurrentTag(ed);
});
});
ed.on('mouseup', function () {
_this.updateCurrentTag(ed);
});
ed.on('blur', function () {
console.log('_this.lastPTag at line 367:', _this.lastTag);
if (_this.lastTag) {
_this.lastTag.style.backgroundColor = ''; // 清除之前的高亮
_this.lastTag.style.border = '';
_this.lastTag = null;
}
if (wordButtonContainer) {
wordButtonContainer.remove();
wordButtonContainer = null;
}
});
ed.on('drop', (event, index) => {
console.log('event at line 375:', event);
const selection = ed.selection;
const selectedNode = selection.getNode(); // 获取选中的节点
console.log('1899', selectedNode); // 查看光标位置的节点类型
// 向上遍历直到找到带有 main-id 属性的节点
const findParentWithMainId = (node) => {
while (node) {
if (node.hasAttribute && node.classList.contains('pMain')) {
return node; // 找到并返回该节点
}
node = node.parentNode; // 向上遍历父节点
}
return null; // 如果没有找到,返回 null
};
// 查找选中节点的父节点,直到找到带有 main-id 属性的节点
const nodeWithMainId = findParentWithMainId(selectedNode);
console.log('at line 395:', nodeWithMainId);
const dataId = nodeWithMainId.getAttribute('main-id');
event.preventDefault();
hideDeleteButton();
// 获取拖动的数据
_this.$emit('onDrop', event, dataId); // 阻止默认的行为
// 在编辑器中插入数据
// const content = <div class="dropped-item">${itemData}</div>;
// ed.insertContent(content); // 插入文本或HTML
});
// 方法:更新当前选中的 p 标签的样式
_this.updateCurrentTag = function (ed) {
var selection = ed.selection;
var node = selection.getNode();
// 向上查找包含的节点直到找到合适的标签
if (node && !node.classList.contains('pMain')) {
node = node.closest('.pMain'); // 向上找到最近的包含 'aa' 类的标签
}
if (node && node.classList.contains('pMain')) {
// 清除上一个高亮的节点样式
if (_this.lastTag && _this.lastTag !== node) {
_this.lastTag.style.backgroundColor = ''; // 清除上一个高亮的标签样式
ed.on('mouseup', function () {
_this.updateCurrentTag(ed);
});
ed.on('blur', function () {
console.log('_this.lastPTag at line 367:', _this.lastTag);
if (_this.lastTag) {
_this.lastTag.style.backgroundColor = ''; // 清除之前的高亮
_this.lastTag.style.border = '';
_this.lastTag = null;
}
if (wordButtonContainer) {
wordButtonContainer.remove();
wordButtonContainer = null;
}
});
ed.on('drop', (event, index) => {
console.log('event at line 375:', event);
// 设置当前节点的背景色和边框
node.style.backgroundColor = 'rgb(0 102 153 / 10%)';
node.style.border = '2px dashed rgb(0 102 153 / 50%)';
const selection = ed.selection;
const selectedNode = selection.getNode(); // 获取选中的节点
console.log('1899', selectedNode); // 查看光标位置的节点类型
// 更新选中的节点
var currentNode = node;
// 向上遍历直到找到带有 main-id 属性的节点
const findParentWithMainId = (node) => {
while (node) {
if (node.hasAttribute && node.classList.contains('pMain')) {
return node; // 找到并返回该节点
}
node = node.parentNode; // 向上遍历父节点
}
return null; // 如果没有找到,返回 null
};
// 显示删除按钮
showDeleteButton(currentNode);
// 更新 lastTag
_this.lastTag = node;
} else {
// 如果没有找到包含 'aa' 类的节点,隐藏删除按钮
// 查找选中节点的父节点,直到找到带有 main-id 属性的节点
const nodeWithMainId = findParentWithMainId(selectedNode);
console.log('at line 395:', nodeWithMainId);
const dataId = nodeWithMainId.getAttribute('main-id');
event.preventDefault();
hideDeleteButton();
}
};
function hideDeleteButton() {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
}
function showDeleteButton(paragraph) {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 如果已有按钮容器,移除
}
// 获取 <p> 标签的位置信息
const paragraphRect = paragraph.getBoundingClientRect();
const iframe = ed.getDoc().defaultView.frameElement;
const iframeRect = iframe.getBoundingClientRect();
var left = 0;
if (_this.isEditComment) {
left = 100;
} else {
left = 80;
}
// 创建按钮容器 div
wordButtonContainer = document.createElement('div');
wordButtonContainer.style.position = 'absolute';
wordButtonContainer.style.top = `${iframeRect.top + paragraphRect.top + window.scrollY - 20}px`; // 确保按钮容器位于 <p> 标签旁边
wordButtonContainer.style.left = `${iframeRect.left + paragraphRect.left + paragraphRect.width - left}px`;
wordButtonContainer.style.zIndex = '9999'; // 设置更高的值
wordButtonContainer.style.display = 'flex'; // 使用 flex 布局将按钮水平排列
wordButtonContainer.style.alignItems = 'center'; // 垂直居中
// 创建删除按钮
const deleteButton = document.createElement('button');
deleteButton.style.backgroundColor = 'red';
deleteButton.style.color = 'white';
deleteButton.style.border = 'none';
deleteButton.style.borderRadius = '50%';
deleteButton.style.padding = '5px';
deleteButton.style.cursor = 'pointer';
deleteButton.style.marginLeft = '10px'; // 给批注按钮添加间距
const deleteIcon = document.createElement('i');
deleteIcon.classList.add('el-icon-delete'); // 使用 Element UI 删除图标
deleteIcon.style.fontSize = '20px';
deleteIcon.style.color = '#fff'; // 设置图标颜色
deleteButton.appendChild(deleteIcon);
deleteButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
_this.$emit('onDelete', paragraph.getAttribute('main-id'));
// 获取拖动的数据
_this.$emit('onDrop', event, dataId); // 阻止默认的行为
// 在编辑器中插入数据
// const content = <div class="dropped-item">${itemData}</div>;
// ed.insertContent(content); // 插入文本或HTML
});
// 方法:更新当前选中的 p 标签的样式
_this.updateCurrentTag = function (ed) {
var selection = ed.selection;
var node = selection.getNode();
// 创建批注按钮
const editButton = document.createElement('button');
editButton.style.backgroundColor = 'rgb(19, 188, 32)';
editButton.style.color = 'white';
editButton.style.border = 'none';
editButton.style.borderRadius = '50%';
editButton.style.padding = '5px';
editButton.style.marginLeft = '10px'; // 给批注按钮添加间距
editButton.style.cursor = 'pointer';
const editIcon = document.createElement('i');
editIcon.classList.add('el-icon-edit'); // 使用 Element UI 批注图标
editIcon.style.fontSize = '20px';
editIcon.style.color = '#fff'; // 设置图标颜色
editButton.appendChild(editIcon);
editButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// 触发批注事件
_this.$emit('onEdit', paragraph.getAttribute('main-id'));
});
// 将按钮添加到容器中
wordButtonContainer.appendChild(editButton);
wordButtonContainer.appendChild(deleteButton);
if (_this.isEditComment) {
// 创建批注按钮
const commentButton = document.createElement('button');
commentButton.style.backgroundColor = '#2b81ef';
commentButton.style.color = 'white';
commentButton.style.border = 'none';
commentButton.style.borderRadius = '50%';
commentButton.style.padding = '5px';
commentButton.style.marginLeft = '10px'; // 给批注按钮添加间距
commentButton.style.cursor = 'pointer';
const commentIcon = document.createElement('i');
commentIcon.classList.add('el-icon-chat-dot-square'); // 使用 Element UI 批注图标
commentIcon.style.fontSize = '20px';
commentIcon.style.color = '#fff'; // 设置图标颜色
commentButton.appendChild(commentIcon);
commentButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// 触发批注事件
_this.$emit('onAddComment', paragraph.getAttribute('main-id'));
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
// 向上查找包含的节点直到找到合适的标签
if (node && !node.classList.contains('pMain')) {
node = node.closest('.pMain'); // 向上找到最近的包含 'aa' 类的标签
}
});
wordButtonContainer.appendChild(commentButton);
}
if (node && node.classList.contains('pMain')) {
// 清除上一个高亮的节点样式
if (_this.lastTag && _this.lastTag !== node) {
_this.lastTag.style.backgroundColor = ''; // 清除上一个高亮的标签样式
_this.lastTag.style.border = '';
}
wordButtonContainer.classList.add('wordButtonContainer'); // 给按钮
// 将容器添加到页面中
document.body.appendChild(wordButtonContainer);
}
ed.on('mousedown', function (e) {
// 检查点击的位置是否是删除按钮或选中的 <p> 标签
if (!currentParagraph || (e.target !== wordButtonContainer && !currentParagraph.contains(e.target))) {
// 设置当前节点的背景色和边框
node.style.backgroundColor = 'rgb(0 102 153 / 10%)';
node.style.border = '2px dashed rgb(0 102 153 / 50%)';
// 更新选中的节点
var currentNode = node;
// 显示删除按钮
showDeleteButton(currentNode);
// 更新 lastTag
_this.lastTag = node;
} else {
// 如果没有找到包含 'aa' 类的节点,隐藏删除按钮
hideDeleteButton();
}
};
function hideDeleteButton() {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
}
});
function showDeleteButton(paragraph) {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 如果已有按钮容器,移除
}
// 获取 <p> 标签的位置信息
const paragraphRect = paragraph.getBoundingClientRect();
const iframe = ed.getDoc().defaultView.frameElement;
const iframeRect = iframe.getBoundingClientRect();
var left = 0;
if (_this.isEditComment) {
left = 100;
} else {
left = 80;
}
// 创建按钮容器 div
wordButtonContainer = document.createElement('div');
wordButtonContainer.style.position = 'absolute';
wordButtonContainer.style.top = `${iframeRect.top + paragraphRect.top + window.scrollY - 20}px`; // 确保按钮容器位于 <p> 标签旁边
wordButtonContainer.style.left = `${iframeRect.left + paragraphRect.left + paragraphRect.width - left}px`;
wordButtonContainer.style.zIndex = '9999'; // 设置更高的值
wordButtonContainer.style.display = 'flex'; // 使用 flex 布局将按钮水平排列
wordButtonContainer.style.alignItems = 'center'; // 垂直居中
// 创建删除按钮
const deleteButton = document.createElement('button');
deleteButton.style.backgroundColor = 'red';
deleteButton.style.color = 'white';
deleteButton.style.border = 'none';
deleteButton.style.borderRadius = '50%';
deleteButton.style.padding = '5px';
deleteButton.style.cursor = 'pointer';
deleteButton.style.marginLeft = '10px'; // 给批注按钮添加间距
const deleteIcon = document.createElement('i');
deleteIcon.classList.add('el-icon-delete'); // 使用 Element UI 删除图标
deleteIcon.style.fontSize = '20px';
deleteIcon.style.color = '#fff'; // 设置图标颜色
deleteButton.appendChild(deleteIcon);
deleteButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
_this.$emit('onDelete', paragraph.getAttribute('main-id'));
});
// 创建批注按钮
const editButton = document.createElement('button');
editButton.style.backgroundColor = 'rgb(19, 188, 32)';
editButton.style.color = 'white';
editButton.style.border = 'none';
editButton.style.borderRadius = '50%';
editButton.style.padding = '5px';
editButton.style.marginLeft = '10px'; // 给批注按钮添加间距
editButton.style.cursor = 'pointer';
const editIcon = document.createElement('i');
editIcon.classList.add('el-icon-edit'); // 使用 Element UI 批注图标
editIcon.style.fontSize = '20px';
editIcon.style.color = '#fff'; // 设置图标颜色
editButton.appendChild(editIcon);
editButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// 触发批注事件
_this.$emit('onEdit', paragraph.getAttribute('main-id'));
});
// 将按钮添加到容器中
wordButtonContainer.appendChild(editButton);
wordButtonContainer.appendChild(deleteButton);
if (_this.isEditComment) {
// 创建批注按钮
const commentButton = document.createElement('button');
commentButton.style.backgroundColor = '#2b81ef';
commentButton.style.color = 'white';
commentButton.style.border = 'none';
commentButton.style.borderRadius = '50%';
commentButton.style.padding = '5px';
commentButton.style.marginLeft = '10px'; // 给批注按钮添加间距
commentButton.style.cursor = 'pointer';
const commentIcon = document.createElement('i');
commentIcon.classList.add('el-icon-chat-dot-square'); // 使用 Element UI 批注图标
commentIcon.style.fontSize = '20px';
commentIcon.style.color = '#fff'; // 设置图标颜色
commentButton.appendChild(commentIcon);
commentButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// 触发批注事件
_this.$emit('onAddComment', paragraph.getAttribute('main-id'));
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
});
wordButtonContainer.appendChild(commentButton);
}
wordButtonContainer.classList.add('wordButtonContainer'); // 给按钮
// 将容器添加到页面中
document.body.appendChild(wordButtonContainer);
}
ed.on('mousedown', function (e) {
// 检查点击的位置是否是删除按钮或选中的 <p> 标签
if (!currentParagraph || (e.target !== wordButtonContainer && !currentParagraph.contains(e.target))) {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
}
});
}
},
init_instance_callback: (editor) => {

View File

@@ -0,0 +1,119 @@
<template>
<div>
<el-select v-model="state" @change="getList" placeholder="Please select status"
style="margin-bottom:10px;width: 200px;">
<!-- <el-option :key="0" label="All status" :value="0"></el-option> -->
<el-option :key="1" :label="$t('pendingPayment.state0')" :value="0"></el-option>
<el-option :key="1" :label="$t('pendingPayment.state1')" :value="1"></el-option>
<el-option :key="2" :label="$t('pendingPayment.state2')" :value="2"></el-option>
</el-select>
<el-table :data="orderList" style="width: 100%">
<el-table-column prop="id" label="ID" width="300"><template slot-scope="scope">
<p><span>ID</span>{{ scope.row.article_detail.accept_sn }}</p>
<p><span>{{ $t('pendingPayment.journal') }}</span>{{ scope.row.journal_detail.title }}</p>
</template></el-table-column>
<el-table-column prop="title" :label="$t('pendingPayment.title')"><template slot-scope="scope">
{{ scope.row.article_detail.title }}
</template>
</el-table-column>
<el-table-column prop="real_fee" :label="$t('pendingPayment.Paymentamount')" width="140">
<template slot-scope="scope">
<span class="currency">$</span> {{ formatAmount(scope.row.real_fee) }}
</template>
</el-table-column>
<el-table-column prop="status" :label="$t('pendingPayment.Paymentstatus')" width="140">
<template slot-scope="scope">
<span v-if="scope.row.state==0" style="color: #ff5000;">{{ $t('pendingPayment.state0') }}</span>
<span v-if="scope.row.state==1" style="color: #00c286;">{{ $t('pendingPayment.state1') }}</span>
<span v-if="scope.row.state==2" style="color: #b0b0b0;">{{ $t('pendingPayment.state2') }}</span>
</template>
</el-table-column>
<el-table-column label="" width="140">
<template slot-scope="scope">
<el-button size="mini" style="background: #ff5000 !important;border-color: #ff5000 !important;" type="primary" v-if="scope.row.state==0" @click="goOrderConfirmation(scope.row)">Payment</el-button>
<!-- <el-button size="mini" type="primary" v-if="scope.row.state==1" @click="goOrderDetail(scope.row)">Detail</el-button> -->
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import PendingPayment from '@/components/page/components/pendingPayment/index.vue';
export default {
components: {
PendingPayment
},
data() {
return {
state:0,
user_id: localStorage.getItem('U_id'),
urlList: {
list:'api/Order/getUserOrder'
},
orderList: [
// 更多稿件数据...
]
};
},
methods: {
goOrderConfirmation(data){
this.$router.push({
path: '/OrderConfirmation',
query: {
id: data.article_id
}
});
},
goOrderDetail(data){
this.$router.push({
path: '/OrderDetail',
query: {
id: data.article_id
}
});
},
formatAmount(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
getList(){
this.$api
.post(this.urlList.list, {
user_id: this.user_id,
state:this.state
})
.then((res) => {
console.log('res at line 191:', res);
if (res.code == 0) {
this.orderList = res.data.list;
}
});
},
payArticle(article) {
// 在这里实现缴费逻辑例如调用后端API进行缴费
// 缴费成功后更新article.status为'已缴费'
article.status = '已缴费';
this.$message.success(`已成功为稿件 ${article.title} 缴费`);
}
},
created(){
this.getList()
},
activated(){
this.getList()
},
};
</script>
<style scoped>
.currency {
font-weight: bold;
/* margin-right: 5px; */
}</style>

View File

@@ -695,6 +695,15 @@
</div>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="User Order">
<PendingPayment ref="PendingPayment" :list="orderList">
<template slot="tableItem">
</template>
</PendingPayment>
</el-tab-pane> -->
</el-tabs>
</div>
@@ -1101,9 +1110,13 @@
</template>
<script>
import PendingPayment from '@/components/page/components/pendingPayment/index.vue';
export default {
data() {
return {
orderList:[ { id: 1, title: '稿件1', author: '作者1', amount: 100, status: '未缴费',orderId:'6VT20279NK3463528' },
{ id: 2, title: '稿件2', author: '作者2', amount: 200, status: '未缴费',orderId:'6VT20279NK3463528' },
{ id: 3, title: '稿件3', author: '作者3', amount: 300, status: '未缴费' ,orderId:'6VT20279NK3463528' },],
citeLoading: false,
wosLoading: false,
authorList: [],
@@ -1357,6 +1370,9 @@ export default {
}
};
},
components: {
PendingPayment
},
mounted() {},
created() {
this.getSelectData();

View File

@@ -73,6 +73,8 @@ Vue.component("Editor", Editor);
import commonTable from '@/components/page/components/table/table.vue'
Vue.component('common-table', commonTable);
import commonPayPalButton from '@/components/page/components/pendingPayment/PayPalButton.vue'
Vue.component('common-paypal-button', commonPayPalButton);
import commonTiff from '@/components/page/components/table/tiff.vue'
Vue.component('common-tiff', commonTiff);
import commonContent from '@/components/page/components/table/content.vue'

View File

@@ -319,6 +319,41 @@ export default new Router({
title: 'Submit manuscript'
}
},
{
path: '/PendingPaymentEditor',
component: () => import('../components/page/PendingPaymentEditor.vue'),
meta: {
title: 'Pending Payment'
}
},
{
path: '/OrderConfirmation',
component: () => import('../components/page/components/pendingPayment/OrderConfirmation.vue'),
meta: {
title: 'Order Confirmation'
}
},
{
path: '/OrderDetail',
component: () => import('../components/page/components/pendingPayment/OrderDetail.vue'),
meta: {
title: 'Order Detail'
}
},
{
path: '/success',
component: () => import('../components/page/components/pendingPayment/success.vue'),
meta: {
title: 'Success'
}
},
{
path: '/orderListAuthor',
component: () => import('../components/page/orderListAuthor.vue'),
meta: {
title: 'Order List'
}
},
{
path: '/articleReviewer',
component: () => import('../components/page/articleReviewer.vue'),