Files
one-pipe-system/src/views/settings/wechat-config/index.vue
2026-04-08 19:31:22 +08:00

1068 lines
36 KiB
Vue

<template>
<ArtTableFullScreen>
<div class="wechat-config-page" id="table-full-screen">
<!-- 搜索栏 -->
<ArtSearchBar
v-model:filter="searchForm"
:items="searchFormItems"
label-width="100"
:show-expand="false"
@reset="handleReset"
@search="handleSearch"
></ArtSearchBar>
<ElCard shadow="never" class="art-table-card">
<!-- 表格头部 -->
<ArtTableHeader
:columnList="columnOptions"
v-model:columns="columnChecks"
@refresh="handleRefresh"
>
<template #left>
<ElButton type="primary" @click="showCreateDialog" v-if="hasAuth('wechat_config:create')">新增支付配置</ElButton>
</template>
</ArtTableHeader>
<!-- 表格 -->
<ArtTable
ref="tableRef"
row-key="id"
:loading="loading"
:data="configList"
:currentPage="pagination.page"
:pageSize="pagination.page_size"
:total="pagination.total"
:marginTop="10"
:actions="getActions"
:actionsWidth="120"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
<template #default>
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
<!-- 创建/编辑对话框 -->
<ElDialog
v-model="dialogVisible"
:title="dialogType === 'add' ? '新增支付配置' : '编辑支付配置'"
width="900px"
:close-on-click-modal="false"
@closed="handleDialogClosed"
>
<ElForm
ref="formRef"
:model="form"
:rules="rules"
label-width="140px"
class="config-form"
>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="配置名称" prop="name">
<ElInput v-model="form.name" placeholder="请输入配置名称" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="支付渠道类型" prop="provider_type">
<ElSelect
v-model="form.provider_type"
placeholder="请选择支付渠道类型"
style="width: 100%"
@change="handleProviderTypeChange"
>
<ElOption label="微信直连" value="wechat" />
<ElOption label="微信直连V2" value="wechat_v2" />
<ElOption label="富友支付" value="fuiou" />
</ElSelect>
</ElFormItem>
</ElCol>
</ElRow>
<ElFormItem label="配置描述" prop="description">
<ElInput
v-model="form.description"
type="textarea"
:rows="2"
placeholder="请输入配置描述"
/>
</ElFormItem>
<!-- 微信相关配置 -->
<template v-if="form.provider_type === 'wechat' || form.provider_type === 'wechat_v2'">
<ElDivider content-position="left">
<span class="divider-title">小程序配置</span>
</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="小程序AppID" prop="miniapp_app_id">
<ElInput v-model="form.miniapp_app_id" placeholder="请输入小程序AppID" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="小程序AppSecret" prop="miniapp_app_secret">
<ElInput
v-model="form.miniapp_app_secret"
type="password"
show-password
placeholder="请输入小程序AppSecret"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElDivider content-position="left">
<span class="divider-title">公众号配置</span>
</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="公众号AppID" prop="oa_app_id">
<ElInput v-model="form.oa_app_id" placeholder="请输入公众号AppID" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="公众号AppSecret" prop="oa_app_secret">
<ElInput
v-model="form.oa_app_secret"
type="password"
show-password
placeholder="请输入公众号AppSecret"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="公众号Token" prop="oa_token">
<ElInput
v-model="form.oa_token"
type="password"
show-password
placeholder="请输入公众号Token"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="公众号AES Key" prop="oa_aes_key">
<ElInput
v-model="form.oa_aes_key"
type="password"
show-password
placeholder="请输入公众号AES加密Key"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElFormItem label="OAuth回调地址" prop="oa_oauth_redirect_url">
<ElInput v-model="form.oa_oauth_redirect_url" placeholder="请输入OAuth回调地址" />
</ElFormItem>
<ElDivider content-position="left">
<span class="divider-title">微信支付配置</span>
</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="微信商户号" prop="wx_mch_id">
<ElInput v-model="form.wx_mch_id" placeholder="请输入微信商户号" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="证书序列号" prop="wx_serial_no">
<ElInput v-model="form.wx_serial_no" placeholder="请输入微信证书序列号" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="APIv2密钥" prop="wx_api_v2_key">
<ElInput
v-model="form.wx_api_v2_key"
type="password"
show-password
placeholder="请输入微信APIv2密钥"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="APIv3密钥" prop="wx_api_v3_key">
<ElInput
v-model="form.wx_api_v3_key"
type="password"
show-password
placeholder="请输入微信APIv3密钥"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElFormItem label="支付回调地址" prop="wx_notify_url">
<ElInput v-model="form.wx_notify_url" placeholder="请输入微信支付回调地址" />
</ElFormItem>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="支付证书" prop="wx_cert_content">
<ElInput
v-model="form.wx_cert_content"
type="textarea"
:rows="3"
placeholder="请粘贴PEM格式证书内容"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="支付密钥" prop="wx_key_content">
<ElInput
v-model="form.wx_key_content"
type="textarea"
:rows="3"
placeholder="请粘贴PEM格式密钥内容"
/>
</ElFormItem>
</ElCol>
</ElRow>
</template>
<!-- 富友支付配置 -->
<template v-if="form.provider_type === 'fuiou'">
<ElDivider content-position="left">小程序配置</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="小程序AppID" prop="miniapp_app_id">
<ElInput v-model="form.miniapp_app_id" placeholder="请输入小程序AppID" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="小程序AppSecret" prop="miniapp_app_secret">
<ElInput
v-model="form.miniapp_app_secret"
type="password"
show-password
placeholder="请输入小程序AppSecret"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElDivider content-position="left">
<span class="divider-title">公众号配置</span>
</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="公众号AppID" prop="oa_app_id">
<ElInput v-model="form.oa_app_id" placeholder="请输入公众号AppID" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="公众号AppSecret" prop="oa_app_secret">
<ElInput
v-model="form.oa_app_secret"
type="password"
show-password
placeholder="请输入公众号AppSecret"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="公众号Token" prop="oa_token">
<ElInput
v-model="form.oa_token"
type="password"
show-password
placeholder="请输入公众号Token"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="公众号AES Key" prop="oa_aes_key">
<ElInput
v-model="form.oa_aes_key"
type="password"
show-password
placeholder="请输入公众号AES加密Key"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElFormItem label="OAuth回调地址" prop="oa_oauth_redirect_url">
<ElInput v-model="form.oa_oauth_redirect_url" placeholder="请输入OAuth回调地址" />
</ElFormItem>
<ElDivider content-position="left">
<span class="divider-title">微信支付配置</span>
</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="微信商户号" prop="wx_mch_id">
<ElInput v-model="form.wx_mch_id" placeholder="请输入微信商户号" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="证书序列号" prop="wx_serial_no">
<ElInput v-model="form.wx_serial_no" placeholder="请输入微信证书序列号" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="APIv2密钥" prop="wx_api_v2_key">
<ElInput
v-model="form.wx_api_v2_key"
type="password"
show-password
placeholder="请输入微信APIv2密钥"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="APIv3密钥" prop="wx_api_v3_key">
<ElInput
v-model="form.wx_api_v3_key"
type="password"
show-password
placeholder="请输入微信APIv3密钥"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElFormItem label="支付回调地址" prop="wx_notify_url">
<ElInput v-model="form.wx_notify_url" placeholder="请输入微信支付回调地址" />
</ElFormItem>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="支付证书" prop="wx_cert_content">
<ElInput
v-model="form.wx_cert_content"
type="textarea"
:rows="3"
placeholder="请粘贴PEM格式证书内容"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="支付密钥" prop="wx_key_content">
<ElInput
v-model="form.wx_key_content"
type="textarea"
:rows="3"
placeholder="请粘贴PEM格式密钥内容"
/>
</ElFormItem>
</ElCol>
</ElRow>
<ElDivider content-position="left">
<span class="divider-title">富友支付配置</span>
</ElDivider>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="富友API地址" prop="fy_api_url">
<ElInput v-model="form.fy_api_url" placeholder="请输入富友API地址" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="富友机构号" prop="fy_ins_cd">
<ElInput v-model="form.fy_ins_cd" placeholder="请输入富友机构号" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="富友商户号" prop="fy_mchnt_cd">
<ElInput v-model="form.fy_mchnt_cd" placeholder="请输入富友商户号" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="富友终端号" prop="fy_term_id">
<ElInput v-model="form.fy_term_id" placeholder="请输入富友终端号" />
</ElFormItem>
</ElCol>
</ElRow>
<ElFormItem label="支付回调地址" prop="fy_notify_url">
<ElInput v-model="form.fy_notify_url" placeholder="请输入富友支付回调地址" />
</ElFormItem>
<ElRow :gutter="20">
<ElCol :span="12">
<ElFormItem label="富友私钥" prop="fy_private_key">
<ElInput
v-model="form.fy_private_key"
type="textarea"
:rows="3"
placeholder="请粘贴PEM格式私钥内容"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="富友公钥" prop="fy_public_key">
<ElInput
v-model="form.fy_public_key"
type="textarea"
:rows="3"
placeholder="请粘贴PEM格式公钥内容"
/>
</ElFormItem>
</ElCol>
</ElRow>
</template>
</ElForm>
<template #footer>
<div class="dialog-footer">
<ElButton @click="dialogVisible = false">取消</ElButton>
<ElButton type="primary" @click="handleSubmit" :loading="submitLoading">
提交
</ElButton>
</div>
</template>
</ElDialog>
</ElCard>
</div>
</ArtTableFullScreen>
</template>
<script setup lang="ts">
import { h, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { WechatConfigService } from '@/api/modules'
import { ElMessage, ElMessageBox, ElSwitch, ElButton } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import type {
WechatConfig,
WechatConfigQueryParams,
PaymentProviderType,
CreateWechatConfigRequest,
UpdateWechatConfigRequest
} from '@/types/api'
import type { SearchFormItem } from '@/types'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import { formatDateTime } from '@/utils/business/format'
import { RoutesAlias } from '@/router/routesAlias'
defineOptions({ name: 'WechatConfigList' })
const { hasAuth } = useAuth()
const router = useRouter()
const loading = ref(false)
const submitLoading = ref(false)
const tableRef = ref()
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
// 搜索表单初始值
const initialSearchState = {
provider_type: undefined as PaymentProviderType | undefined,
is_active: undefined as number | undefined
}
// 搜索表单
const searchForm = reactive({ ...initialSearchState })
// 搜索表单配置
const searchFormItems: SearchFormItem[] = [
{
label: '支付渠道类型',
prop: 'provider_type',
type: 'select',
placeholder: '请选择支付渠道类型',
options: [
{ label: '微信直连', value: 'wechat' },
{ label: '微信直连V2', value: 'wechat_v2' },
{ label: '富友支付', value: 'fuiou' }
],
config: {
clearable: true
}
},
{
label: '激活状态',
prop: 'is_active',
type: 'select',
placeholder: '请选择激活状态',
options: [
{ label: '已激活', value: 1 },
{ label: '未激活', value: 0 }
],
config: {
clearable: true
}
}
]
// 分页
const pagination = reactive({
page: 1,
page_size: 20,
total: 0
})
// 列配置
const columnOptions = [
{ label: '配置名称', prop: 'name' },
{ label: '配置描述', prop: 'description' },
{ label: '支付渠道类型', prop: 'provider_type' },
{ label: '激活状态', prop: 'is_active' },
{ label: '商户号', prop: 'merchant_id' },
{ label: '小程序AppID', prop: 'miniapp_app_id' },
{ label: '公众号AppID', prop: 'oa_app_id' },
{ label: '支付回调地址', prop: 'notify_url' },
{ label: '创建时间', prop: 'created_at' },
{ label: '更新时间', prop: 'updated_at' }
]
// URL格式验证规则
const urlValidator = (_rule: any, value: any, callback: any) => {
if (!value) {
callback()
return
}
const urlPattern = /^(https?:\/\/)[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?$/
if (!urlPattern.test(value)) {
callback(new Error('请输入正确的URL格式(http://或https://)'))
} else {
callback()
}
}
// 静态验证规则 - 只有配置名称和支付渠道类型是必填的
const rules = reactive<FormRules>({
name: [{ required: true, message: '请输入配置名称', trigger: 'blur' }],
provider_type: [{ required: true, message: '请选择支付渠道类型', trigger: 'change' }],
// 其他字段都是可选的,只验证URL格式
oa_oauth_redirect_url: [{ validator: urlValidator, trigger: 'blur' }],
wx_notify_url: [{ validator: urlValidator, trigger: 'blur' }],
fy_api_url: [{ validator: urlValidator, trigger: 'blur' }],
fy_notify_url: [{ validator: urlValidator, trigger: 'blur' }]
})
const form = reactive({
id: 0,
name: '',
provider_type: 'wechat' as PaymentProviderType,
description: '',
miniapp_app_id: '',
miniapp_app_secret: '',
oa_app_id: '',
oa_app_secret: '',
oa_token: '',
oa_aes_key: '',
oa_oauth_redirect_url: '',
wx_mch_id: '',
wx_api_v2_key: '',
wx_api_v3_key: '',
wx_notify_url: '',
wx_serial_no: '',
wx_cert_content: '',
wx_key_content: '',
fy_api_url: '',
fy_ins_cd: '',
fy_mchnt_cd: '',
fy_term_id: '',
fy_notify_url: '',
fy_private_key: '',
fy_public_key: ''
})
// 重置表单数据
const resetForm = () => {
form.id = 0
form.name = ''
form.provider_type = 'wechat'
form.description = ''
form.miniapp_app_id = ''
form.miniapp_app_secret = ''
form.oa_app_id = ''
form.oa_app_secret = ''
form.oa_token = ''
form.oa_aes_key = ''
form.oa_oauth_redirect_url = ''
form.wx_mch_id = ''
form.wx_api_v2_key = ''
form.wx_api_v3_key = ''
form.wx_notify_url = ''
form.wx_serial_no = ''
form.wx_cert_content = ''
form.wx_key_content = ''
form.fy_api_url = ''
form.fy_ins_cd = ''
form.fy_mchnt_cd = ''
form.fy_term_id = ''
form.fy_notify_url = ''
form.fy_private_key = ''
form.fy_public_key = ''
}
const configList = ref<WechatConfig[]>([])
// 获取支付渠道类型文本
const getProviderTypeText = (type: PaymentProviderType): string => {
const typeMap: Record<PaymentProviderType, string> = {
wechat: '微信直连',
wechat_v2: '微信直连V2',
fuiou: '富友支付'
}
return typeMap[type] || type
}
// 获取商户号
const getMerchantId = (row: WechatConfig): string => {
if (row.provider_type === 'wechat' || row.provider_type === 'wechat_v2') {
return row.wx_mch_id || '-'
}
if (row.provider_type === 'fuiou') {
return row.fy_mchnt_cd || '-'
}
return '-'
}
// 获取支付回调地址
const getNotifyUrl = (row: WechatConfig): string => {
if (row.provider_type === 'wechat' || row.provider_type === 'wechat_v2') {
return row.wx_notify_url || '-'
}
if (row.provider_type === 'fuiou') {
return row.fy_notify_url || '-'
}
return '-'
}
// 动态列配置
const { columnChecks, columns } = useCheckedColumns(() => [
{
prop: 'name',
label: '配置名称',
minWidth: 160,
showOverflowTooltip: true,
formatter: (row: WechatConfig) => {
return h(
'span',
{
style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
onClick: (e: MouseEvent) => {
e.stopPropagation()
handleNameClick(row)
}
},
row.name
)
}
},
{
prop: 'description',
label: '配置描述',
minWidth: 180,
showOverflowTooltip: true,
formatter: (row: WechatConfig) => row.description || '-'
},
{
prop: 'provider_type',
label: '支付渠道类型',
width: 130,
formatter: (row: WechatConfig) => getProviderTypeText(row.provider_type)
},
{
prop: 'is_active',
label: '激活状态',
width: 100,
formatter: (row: WechatConfig) => {
return h(ElSwitch, {
modelValue: row.is_active,
activeText: '已激活',
inactiveText: '未激活',
inlinePrompt: true,
disabled: !hasAuth('wechat_config:status'),
'onUpdate:modelValue': (val) => handleStatusChange(row, val)
})
}
},
{
prop: 'merchant_id',
label: '商户号',
width: 150,
showOverflowTooltip: true,
formatter: (row: WechatConfig) => getMerchantId(row)
},
{
prop: 'miniapp_app_id',
label: '小程序AppID',
width: 160,
showOverflowTooltip: true,
formatter: (row: WechatConfig) => row.miniapp_app_id || '-'
},
{
prop: 'oa_app_id',
label: '公众号AppID',
width: 160,
showOverflowTooltip: true,
formatter: (row: WechatConfig) => row.oa_app_id || '-'
},
{
prop: 'notify_url',
label: '支付回调地址',
minWidth: 200,
showOverflowTooltip: true,
formatter: (row: WechatConfig) => getNotifyUrl(row)
},
{
prop: 'created_at',
label: '创建时间',
width: 180,
formatter: (row: WechatConfig) => formatDateTime(row.created_at)
},
{
prop: 'updated_at',
label: '更新时间',
width: 180,
formatter: (row: WechatConfig) => formatDateTime(row.updated_at)
}
])
onMounted(() => {
getTableData()
})
// 获取配置列表
const getTableData = async () => {
loading.value = true
try {
const params: WechatConfigQueryParams = {
page: pagination.page,
page_size: pagination.page_size,
provider_type: searchForm.provider_type,
is_active: searchForm.is_active !== undefined ? searchForm.is_active === 1 : undefined
}
const res = await WechatConfigService.getWechatConfigs(params)
if (res.code === 0) {
configList.value = res.data.items || []
pagination.total = res.data.total || 0
}
} catch (error) {
console.error(error)
} finally {
loading.value = false
}
}
// 重置搜索
const handleReset = () => {
Object.assign(searchForm, { ...initialSearchState })
pagination.page = 1
getTableData()
}
// 搜索
const handleSearch = () => {
pagination.page = 1
getTableData()
}
// 刷新表格
const handleRefresh = () => {
getTableData()
}
// 处理表格分页变化
const handleSizeChange = (newPageSize: number) => {
pagination.page_size = newPageSize
getTableData()
}
const handleCurrentChange = (newCurrentPage: number) => {
pagination.page = newCurrentPage
getTableData()
}
// 显示创建对话框
const showCreateDialog = () => {
resetForm()
dialogType.value = 'add'
dialogVisible.value = true
nextTick(() => {
formRef.value?.clearValidate()
})
}
// 处理敏感字段值 - 如果是***或[已配置]等特殊值,转换为空字符串
const processSensitiveField = (value: string | undefined | null): string => {
if (!value || value === '***' || value.includes('[已配置]') || value.includes('[未配置]')) {
return ''
}
return value
}
// 显示编辑对话框
const showEditDialog = async (row: WechatConfig) => {
// 先调用详情接口获取完整数据
try {
const res = await WechatConfigService.getWechatConfigById(row.id)
if (res.code === 0 && res.data) {
const detail = res.data
// 赋值表单数据
Object.assign(form, {
id: detail.id,
name: detail.name,
provider_type: detail.provider_type,
description: detail.description || '',
miniapp_app_id: detail.miniapp_app_id || '',
miniapp_app_secret: processSensitiveField(detail.miniapp_app_secret),
oa_app_id: detail.oa_app_id || '',
oa_app_secret: processSensitiveField(detail.oa_app_secret),
oa_token: processSensitiveField(detail.oa_token),
oa_aes_key: processSensitiveField(detail.oa_aes_key),
oa_oauth_redirect_url: detail.oa_oauth_redirect_url || '',
wx_mch_id: detail.wx_mch_id || '',
wx_api_v2_key: processSensitiveField(detail.wx_api_v2_key),
wx_api_v3_key: processSensitiveField(detail.wx_api_v3_key),
wx_notify_url: detail.wx_notify_url || '',
wx_serial_no: detail.wx_serial_no || '',
wx_cert_content: processSensitiveField(detail.wx_cert_content),
wx_key_content: processSensitiveField(detail.wx_key_content),
fy_api_url: detail.fy_api_url || '',
fy_ins_cd: detail.fy_ins_cd || '',
fy_mchnt_cd: detail.fy_mchnt_cd || '',
fy_term_id: detail.fy_term_id || '',
fy_notify_url: detail.fy_notify_url || '',
fy_private_key: processSensitiveField(detail.fy_private_key),
fy_public_key: processSensitiveField(detail.fy_public_key)
})
dialogType.value = 'edit'
dialogVisible.value = true
await nextTick(() => {
formRef.value?.clearValidate()
})
}
} catch (error) {
console.error('获取详情失败:', error)
ElMessage.error('获取配置详情失败')
}
}
// 处理支付渠道类型变化
const handleProviderTypeChange = () => {
// 清除验证状态
nextTick(() => {
formRef.value?.clearValidate()
})
}
// 对话框关闭后的清理
const handleDialogClosed = () => {
// 不调用resetFields,因为会把数据也重置了
// 只需要什么都不做,下次打开时会重新赋值
}
// 提交表单
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid) => {
if (valid) {
submitLoading.value = true
try {
if (dialogType.value === 'add') {
const data: CreateWechatConfigRequest = {
name: form.name,
provider_type: form.provider_type,
description: form.description || undefined,
miniapp_app_id: form.miniapp_app_id || undefined,
miniapp_app_secret: form.miniapp_app_secret || undefined,
oa_app_id: form.oa_app_id || undefined,
oa_app_secret: form.oa_app_secret || undefined,
oa_token: form.oa_token || undefined,
oa_aes_key: form.oa_aes_key || undefined,
oa_oauth_redirect_url: form.oa_oauth_redirect_url || undefined,
wx_mch_id: form.wx_mch_id || undefined,
wx_api_v2_key: form.wx_api_v2_key || undefined,
wx_api_v3_key: form.wx_api_v3_key || undefined,
wx_notify_url: form.wx_notify_url || undefined,
wx_serial_no: form.wx_serial_no || undefined,
wx_cert_content: form.wx_cert_content || undefined,
wx_key_content: form.wx_key_content || undefined,
fy_api_url: form.fy_api_url || undefined,
fy_ins_cd: form.fy_ins_cd || undefined,
fy_mchnt_cd: form.fy_mchnt_cd || undefined,
fy_term_id: form.fy_term_id || undefined,
fy_notify_url: form.fy_notify_url || undefined,
fy_private_key: form.fy_private_key || undefined,
fy_public_key: form.fy_public_key || undefined
}
await WechatConfigService.createWechatConfig(data)
ElMessage.success('创建成功')
} else {
const data: UpdateWechatConfigRequest = {
name: form.name,
description: form.description || undefined
}
// 只有填写了新值才更新敏感字段
if (form.miniapp_app_secret) data.miniapp_app_secret = form.miniapp_app_secret
if (form.oa_app_secret) data.oa_app_secret = form.oa_app_secret
if (form.oa_token) data.oa_token = form.oa_token
if (form.oa_aes_key) data.oa_aes_key = form.oa_aes_key
if (form.wx_api_v2_key) data.wx_api_v2_key = form.wx_api_v2_key
if (form.wx_api_v3_key) data.wx_api_v3_key = form.wx_api_v3_key
if (form.wx_cert_content) data.wx_cert_content = form.wx_cert_content
if (form.wx_key_content) data.wx_key_content = form.wx_key_content
if (form.fy_private_key) data.fy_private_key = form.fy_private_key
if (form.fy_public_key) data.fy_public_key = form.fy_public_key
// 非敏感字段总是更新
if (form.miniapp_app_id) data.miniapp_app_id = form.miniapp_app_id
if (form.oa_app_id) data.oa_app_id = form.oa_app_id
if (form.oa_oauth_redirect_url) data.oa_oauth_redirect_url = form.oa_oauth_redirect_url
if (form.wx_mch_id) data.wx_mch_id = form.wx_mch_id
if (form.wx_notify_url) data.wx_notify_url = form.wx_notify_url
if (form.wx_serial_no) data.wx_serial_no = form.wx_serial_no
if (form.fy_api_url) data.fy_api_url = form.fy_api_url
if (form.fy_ins_cd) data.fy_ins_cd = form.fy_ins_cd
if (form.fy_mchnt_cd) data.fy_mchnt_cd = form.fy_mchnt_cd
if (form.fy_term_id) data.fy_term_id = form.fy_term_id
if (form.fy_notify_url) data.fy_notify_url = form.fy_notify_url
await WechatConfigService.updateWechatConfig(form.id, data)
ElMessage.success('更新成功')
}
dialogVisible.value = false
await getTableData()
} catch (error) {
console.error(error)
} finally {
submitLoading.value = false
}
}
})
}
// 激活/停用状态切换
const handleStatusChange = async (row: WechatConfig, newStatus: string | number | boolean) => {
if (!hasAuth('wechat_config:status')) {
ElMessage.warning('您没有修改激活状态的权限')
return
}
const newBoolStatus = Boolean(newStatus)
const oldStatus = row.is_active
row.is_active = newBoolStatus
try {
if (newBoolStatus) {
await WechatConfigService.activateWechatConfig(row.id)
ElMessage.success('激活成功')
} else {
await WechatConfigService.deactivateWechatConfig(row.id)
ElMessage.success('停用成功')
}
await getTableData()
} catch (error) {
row.is_active = oldStatus
console.error(error)
}
}
// 删除配置
const handleDelete = async (row: WechatConfig) => {
try {
await ElMessageBox.confirm(`确定要删除支付配置"${row.name}"吗?`, '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await WechatConfigService.deleteWechatConfig(row.id)
ElMessage.success('删除成功')
await getTableData()
} catch (error) {
if (error !== 'cancel') {
console.error(error)
}
}
}
// 查看详情
const handleViewDetail = (row: WechatConfig) => {
router.push({
path: `${RoutesAlias.WechatConfig}/detail/${row.id}`
})
}
// 处理名称点击
const handleNameClick = (row: WechatConfig) => {
if (hasAuth('wechat_config:detail')) {
handleViewDetail(row)
} else {
ElMessage.warning('您没有查看详情的权限')
}
}
// 获取操作按钮
const getActions = (row: WechatConfig) => {
const actions: any[] = []
if (hasAuth('wechat_config:edit')) {
actions.push({
label: '编辑',
handler: () => showEditDialog(row),
type: 'primary'
})
}
if (hasAuth('wechat_config:delete')) {
actions.push({
label: '删除',
handler: () => handleDelete(row),
type: 'danger'
})
}
return actions
}
</script>
<style scoped lang="scss">
.wechat-config-page {
height: 100%;
}
.config-form {
max-height: 600px;
padding-right: 10px;
overflow-y: auto;
.divider-title {
font-size: 14px;
font-weight: 600;
color: var(--el-text-color-primary);
}
:deep(.el-divider) {
margin: 24px 0 20px;
}
:deep(.el-form-item) {
margin-bottom: 18px;
}
:deep(.el-input__wrapper) {
transition: all 0.3s ease;
}
:deep(.el-textarea__inner) {
transition: all 0.3s ease;
}
}
// 优化滚动条样式
.config-form::-webkit-scrollbar {
width: 6px;
}
.config-form::-webkit-scrollbar-thumb {
background-color: var(--el-border-color-darker);
border-radius: 3px;
}
.config-form::-webkit-scrollbar-track {
background-color: var(--el-fill-color-lighter);
}
</style>