新增支付配置备份导入
This commit is contained in:
@@ -35,6 +35,12 @@ export interface PaymentConfigListResponse {
|
||||
page_size: number
|
||||
}
|
||||
|
||||
export interface PaymentConfigImportResult {
|
||||
total: number
|
||||
created: number
|
||||
updated: number
|
||||
}
|
||||
|
||||
export interface CreatePaymentConfigRequest {
|
||||
name: string
|
||||
provider: string
|
||||
@@ -102,6 +108,11 @@ export async function exportPaymentConfigBackup() {
|
||||
}
|
||||
}
|
||||
|
||||
export async function importPaymentConfigBackup(payload: unknown) {
|
||||
const { data } = await apiClient.post<ApiResponse<PaymentConfigImportResult>>('/admin/payment-configs/import', payload)
|
||||
return data.data
|
||||
}
|
||||
|
||||
export async function createPaymentConfig(payload: CreatePaymentConfigRequest) {
|
||||
const { data } = await apiClient.post<ApiResponse<PaymentConfig>>('/admin/payment-configs', payload)
|
||||
return data.data
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { Plus, Refresh, View, Edit, Delete, Download } from '@element-plus/icons-vue'
|
||||
import { Plus, Refresh, View, Edit, Delete, Download, Upload } from '@element-plus/icons-vue'
|
||||
|
||||
import {
|
||||
fetchPaymentConfigs,
|
||||
deletePaymentConfig,
|
||||
exportPaymentConfigBackup,
|
||||
importPaymentConfigBackup,
|
||||
type PaymentConfig,
|
||||
} from '@/features/admin/api/paymentConfig'
|
||||
import { formatDateTime } from '@/utils/time'
|
||||
@@ -19,6 +20,8 @@ const total = ref(0)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const exporting = ref(false)
|
||||
const importing = ref(false)
|
||||
const backupFileInput = ref<HTMLInputElement | null>(null)
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogMode = ref<'create' | 'edit' | 'view'>('create')
|
||||
@@ -133,6 +136,48 @@ async function handleExportBackup() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleImportBackup() {
|
||||
backupFileInput.value?.click()
|
||||
}
|
||||
|
||||
async function handleImportFile(event: Event) {
|
||||
const input = event.target as HTMLInputElement
|
||||
const file = input.files?.[0]
|
||||
input.value = ''
|
||||
if (!file) return
|
||||
|
||||
let backup: unknown
|
||||
try {
|
||||
backup = JSON.parse(await file.text())
|
||||
} catch {
|
||||
ElMessage.error('备份文件不是有效的 JSON')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'导入会按服务商和商户号新增或更新配置,并恢复备份中的启用配置。备份文件包含支付密钥明文,请确认来源可信。',
|
||||
'导入支付配置备份',
|
||||
{
|
||||
type: 'warning',
|
||||
confirmButtonText: '导入',
|
||||
cancelButtonText: '取消',
|
||||
},
|
||||
)
|
||||
|
||||
importing.value = true
|
||||
const result = await importPaymentConfigBackup(backup)
|
||||
ElMessage.success(`导入成功:新增 ${result.created} 个,更新 ${result.updated} 个`)
|
||||
await loadConfigs()
|
||||
} catch (error: any) {
|
||||
if (error !== 'cancel' && error !== 'close') {
|
||||
ElMessage.error(readError(error, '导入备份失败'))
|
||||
}
|
||||
} finally {
|
||||
importing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function downloadBlob(blob: Blob, filename: string) {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
@@ -221,10 +266,19 @@ function deleteDisabledReason(row: PaymentConfig) {
|
||||
<el-option v-for="opt in environmentOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||
</el-select>
|
||||
<el-button :icon="Refresh" @click="loadConfigs">刷新</el-button>
|
||||
<el-button :icon="Upload" :loading="importing" @click="handleImportBackup">导入备份</el-button>
|
||||
<el-button :icon="Download" :loading="exporting" @click="handleExportBackup">导出备份</el-button>
|
||||
<el-button type="primary" :icon="Plus" @click="handleCreate">新增配置</el-button>
|
||||
</div>
|
||||
|
||||
<input
|
||||
ref="backupFileInput"
|
||||
class="backup-file-input"
|
||||
type="file"
|
||||
accept="application/json,.json"
|
||||
@change="handleImportFile"
|
||||
/>
|
||||
|
||||
<el-table
|
||||
:data="filteredConfigs"
|
||||
v-loading="loading"
|
||||
@@ -356,6 +410,10 @@ function deleteDisabledReason(row: PaymentConfig) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.backup-file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.payment-config-table {
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
|
||||
Reference in New Issue
Block a user