|
|
@@ -0,0 +1,247 @@
|
|
|
+<template>
|
|
|
+ <div class="p-2">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>支付宝支付配置</span>
|
|
|
+ <el-button type="primary" @click="handleSave" :loading="saving">保存配置</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-form :model="form" label-width="140px" v-loading="loading">
|
|
|
+ <el-form-item label="支付宝应用ID">
|
|
|
+ <el-input v-model="form.appId" placeholder="请输入支付宝应用ID (AppID)" style="width: 500px" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="应用私钥">
|
|
|
+ <el-input
|
|
|
+ v-model="form.appPrivateKey"
|
|
|
+ type="textarea"
|
|
|
+ :rows="4"
|
|
|
+ placeholder="请输入支付宝应用私钥"
|
|
|
+ style="width: 500px"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="应用公钥">
|
|
|
+ <div>
|
|
|
+ <el-input v-model="form.appPublicKeyPath" style="width: 500px; margin-bottom: 10px;" />
|
|
|
+ <el-upload
|
|
|
+ action="#"
|
|
|
+ :auto-upload="false"
|
|
|
+ :show-file-list="false"
|
|
|
+ accept=".crt,.txt,.pem"
|
|
|
+ :on-change="handleAppPublicKeyChange"
|
|
|
+ >
|
|
|
+ <el-button type="primary">上传应用公钥文件</el-button>
|
|
|
+ </el-upload>
|
|
|
+ <div class="tip-text">支付宝应用公钥文件 (appCertPublicKey_*.crt),在支付宝开放平台下载</div>
|
|
|
+ <div v-if="form.appPublicKeyUploaded" class="success-text">✓ 应用公钥已上传</div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="支付宝公钥">
|
|
|
+ <div>
|
|
|
+ <el-input v-model="form.alipayPublicKeyPath" style="width: 500px; margin-bottom: 10px;" />
|
|
|
+ <el-upload
|
|
|
+ action="#"
|
|
|
+ :auto-upload="false"
|
|
|
+ :show-file-list="false"
|
|
|
+ accept=".crt,.txt,.pem"
|
|
|
+ :on-change="handleAlipayPublicKeyChange"
|
|
|
+ >
|
|
|
+ <el-button type="primary">上传支付宝公钥文件</el-button>
|
|
|
+ </el-upload>
|
|
|
+ <div class="tip-text">支付宝公钥文件 (alipayCertPublicKey_RSA2.crt),在支付宝开放平台下载</div>
|
|
|
+ <div v-if="form.alipayPublicKeyUploaded" class="success-text">✓ 支付宝公钥已上传</div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="支付宝根证书">
|
|
|
+ <div>
|
|
|
+ <el-input v-model="form.alipayRootCertPath" style="width: 500px; margin-bottom: 10px;" />
|
|
|
+ <el-upload
|
|
|
+ action="#"
|
|
|
+ :auto-upload="false"
|
|
|
+ :show-file-list="false"
|
|
|
+ accept=".crt,.pem"
|
|
|
+ :on-change="handleAlipayRootCertChange"
|
|
|
+ >
|
|
|
+ <el-button type="primary">上传支付宝根证书</el-button>
|
|
|
+ </el-upload>
|
|
|
+ <div class="tip-text">支付宝根证书文件 (alipayRootCert.crt),在支付宝开放平台下载</div>
|
|
|
+ <div v-if="form.alipayRootCertUploaded" class="success-text">✓ 支付宝根证书已上传</div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
+import request from '@/utils/request'
|
|
|
+
|
|
|
+// 状态控制
|
|
|
+const loading = ref(false)
|
|
|
+const saving = ref(false)
|
|
|
+
|
|
|
+// 文件上传的暂存状态
|
|
|
+const appPublicKeyFile = ref<File | null>(null)
|
|
|
+const alipayPublicKeyFile = ref<File | null>(null)
|
|
|
+const alipayRootCertFile = ref<File | null>(null)
|
|
|
+
|
|
|
+// 表单数据
|
|
|
+const form = ref({
|
|
|
+ appId: '',
|
|
|
+ appPrivateKey: '',
|
|
|
+ appPublicKeyPath: '',
|
|
|
+ alipayPublicKeyPath: '',
|
|
|
+ alipayRootCertPath: '',
|
|
|
+ appPublicKeyUploaded: false,
|
|
|
+ alipayPublicKeyUploaded: false,
|
|
|
+ alipayRootCertUploaded: false
|
|
|
+})
|
|
|
+
|
|
|
+// 处理应用公钥选择
|
|
|
+const handleAppPublicKeyChange = (file: any) => {
|
|
|
+ appPublicKeyFile.value = file.raw
|
|
|
+ ElMessage.success('应用公钥文件已选择,保存时将一并上传')
|
|
|
+}
|
|
|
+
|
|
|
+// 处理支付宝公钥选择
|
|
|
+const handleAlipayPublicKeyChange = (file: any) => {
|
|
|
+ alipayPublicKeyFile.value = file.raw
|
|
|
+ ElMessage.success('支付宝公钥文件已选择,保存时将一并上传')
|
|
|
+}
|
|
|
+
|
|
|
+// 处理支付宝根证书选择
|
|
|
+const handleAlipayRootCertChange = (file: any) => {
|
|
|
+ alipayRootCertFile.value = file.raw
|
|
|
+ ElMessage.success('支付宝根证书文件已选择,保存时将一并上传')
|
|
|
+}
|
|
|
+
|
|
|
+// 获取配置信息
|
|
|
+const getConfig = async () => {
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ // 调用后端的获取支付宝配置接口
|
|
|
+ const res = await request.get('/miniapp/paymentConfig/alipay')
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+ form.value.appId = res.data.appId || ''
|
|
|
+ form.value.appPrivateKey = res.data.appPrivateKey || ''
|
|
|
+ form.value.appPublicKeyPath = res.data.appPublicKeyPath || ''
|
|
|
+ form.value.alipayPublicKeyPath = res.data.alipayPublicKeyPath || ''
|
|
|
+ form.value.alipayRootCertPath = res.data.alipayRootCertPath || ''
|
|
|
+ form.value.appPublicKeyUploaded = res.data.appPublicKeyUploaded || false
|
|
|
+ form.value.alipayPublicKeyUploaded = res.data.alipayPublicKeyUploaded || false
|
|
|
+ form.value.alipayRootCertUploaded = res.data.alipayRootCertUploaded || false
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('获取支付宝配置失败', e)
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 保存配置
|
|
|
+const handleSave = async () => {
|
|
|
+ saving.value = true
|
|
|
+ try {
|
|
|
+ // 1. 上传应用公钥
|
|
|
+ if (appPublicKeyFile.value) {
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', appPublicKeyFile.value)
|
|
|
+ const uploadRes = await request.post('/miniapp/paymentConfig/uploadAlipayAppPublicKey', formData, {
|
|
|
+ headers: { 'Content-Type': 'multipart/form-data' }
|
|
|
+ })
|
|
|
+ if (uploadRes.code !== 200) {
|
|
|
+ ElMessage.error('应用公钥上传失败:' + uploadRes.msg)
|
|
|
+ saving.value = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ form.value.appPublicKeyUploaded = true
|
|
|
+ form.value.appPublicKeyPath = uploadRes.data
|
|
|
+ appPublicKeyFile.value = null
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 上传支付宝公钥
|
|
|
+ if (alipayPublicKeyFile.value) {
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', alipayPublicKeyFile.value)
|
|
|
+ const uploadRes = await request.post('/miniapp/paymentConfig/uploadAlipayPublicKey', formData, {
|
|
|
+ headers: { 'Content-Type': 'multipart/form-data' }
|
|
|
+ })
|
|
|
+ if (uploadRes.code !== 200) {
|
|
|
+ ElMessage.error('支付宝公钥上传失败:' + uploadRes.msg)
|
|
|
+ saving.value = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ form.value.alipayPublicKeyUploaded = true
|
|
|
+ form.value.alipayPublicKeyPath = uploadRes.data
|
|
|
+ alipayPublicKeyFile.value = null
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 上传支付宝根证书
|
|
|
+ if (alipayRootCertFile.value) {
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', alipayRootCertFile.value)
|
|
|
+ const uploadRes = await request.post('/miniapp/paymentConfig/uploadAlipayRootCert', formData, {
|
|
|
+ headers: { 'Content-Type': 'multipart/form-data' }
|
|
|
+ })
|
|
|
+ if (uploadRes.code !== 200) {
|
|
|
+ ElMessage.error('支付宝根证书上传失败:' + uploadRes.msg)
|
|
|
+ saving.value = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ form.value.alipayRootCertUploaded = true
|
|
|
+ form.value.alipayRootCertPath = uploadRes.data
|
|
|
+ alipayRootCertFile.value = null
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 保存文本配置
|
|
|
+ const res = await request.put('/miniapp/paymentConfig/alipay', {
|
|
|
+ appId: form.value.appId,
|
|
|
+ appPrivateKey: form.value.appPrivateKey,
|
|
|
+ appPublicKeyPath: form.value.appPublicKeyPath,
|
|
|
+ alipayPublicKeyPath: form.value.alipayPublicKeyPath,
|
|
|
+ alipayRootCertPath: form.value.alipayRootCertPath
|
|
|
+ })
|
|
|
+
|
|
|
+ if (res.code === 200) {
|
|
|
+ ElMessage.success('保存成功')
|
|
|
+ getConfig() // 重新获取最新配置
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg || '保存失败')
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ ElMessage.error('保存失败')
|
|
|
+ } finally {
|
|
|
+ saving.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getConfig()
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.tip-text {
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 4px;
|
|
|
+}
|
|
|
+.success-text {
|
|
|
+ color: #67c23a;
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 4px;
|
|
|
+}
|
|
|
+</style>
|