700 lines
23 KiB
Vue
700 lines
23 KiB
Vue
<!--
|
||
=============================================================================
|
||
企微IT智能服务台 — 外部系统集成配置页
|
||
=============================================================================
|
||
说明:显示6个外部系统的连接状态和配置入口
|
||
- Dify AI / RAGFlow:可配置(API URL + Key)— url_key 模式
|
||
- 火绒安全:可配置(AccessKey ID + Secret + Base URL)— access_key 模式
|
||
- 联软LV7000:可配置(API账号 + 密码 + Base URL)— account_password 模式
|
||
- 数据平台 / 北森 eHR:显示状态 + 占位
|
||
-->
|
||
<template>
|
||
<div class="integrations-page">
|
||
<!-- 页面标题 -->
|
||
<div class="page-title">外部系统集成</div>
|
||
<div class="page-desc">管理后台管「配置和参数」,Dify 网页管「Workflow 逻辑」,两者边界明确。</div>
|
||
|
||
<!-- 加载状态 -->
|
||
<div v-if="loading" class="loading-state">
|
||
<el-skeleton :rows="6" animated />
|
||
</div>
|
||
|
||
<!-- 集成系统卡片网格 -->
|
||
<div v-else class="integration-grid">
|
||
<IntegrationCard
|
||
v-for="item in integrations"
|
||
:key="item.id"
|
||
:integration="item"
|
||
:icon="getIntegrationIcon(item.id)"
|
||
:icon-bg="getIntegrationIconBg(item.id)"
|
||
:icon-color="getIntegrationIconColor(item.id)"
|
||
@configure="handleConfigure"
|
||
@test="handleTest"
|
||
@view="handleView"
|
||
/>
|
||
</div>
|
||
|
||
<!-- ================================================================ -->
|
||
<!-- 配置对话框 — url_key 模式(Dify / RAGFlow) -->
|
||
<!-- ================================================================ -->
|
||
<el-dialog
|
||
v-if="configuringIntegration?.config_type === 'url_key'"
|
||
v-model="configDialogVisible"
|
||
:title="'配置集成 — ' + configuringIntegration?.name"
|
||
width="480px"
|
||
destroy-on-close
|
||
>
|
||
<el-form label-position="top">
|
||
<el-form-item label="API URL">
|
||
<el-input
|
||
v-model="urlKeyForm.apiUrl"
|
||
placeholder="https://api.dify.ai/v1"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="API Key">
|
||
<el-input
|
||
v-model="urlKeyForm.apiKey"
|
||
type="password"
|
||
placeholder="输入 API Key"
|
||
show-password
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<el-button @click="configDialogVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="handleUrlKeySave">保存配置</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- ================================================================ -->
|
||
<!-- 配置对话框 — access_key 模式(火绒安全) -->
|
||
<!-- ================================================================ -->
|
||
<el-dialog
|
||
v-if="configuringIntegration?.config_type === 'access_key'"
|
||
v-model="configDialogVisible"
|
||
:title="'配置集成 — ' + configuringIntegration?.name"
|
||
width="520px"
|
||
destroy-on-close
|
||
>
|
||
<el-form label-position="top">
|
||
<el-form-item label="Base URL(内网地址)">
|
||
<el-input
|
||
v-model="accessKeyForm.baseUrl"
|
||
placeholder="http://huorong.oa.servyou-it.com:8080"
|
||
/>
|
||
<div class="form-hint">火绒终端安全管理系统的内网API地址</div>
|
||
</el-form-item>
|
||
<el-form-item label="AccessKey ID">
|
||
<el-input
|
||
v-model="accessKeyForm.accessKeyId"
|
||
placeholder="输入 AccessKey ID"
|
||
/>
|
||
<div class="form-hint">在火绒管理后台 → 系统设置 → API管理 中创建</div>
|
||
</el-form-item>
|
||
<el-form-item label="AccessKey Secret">
|
||
<el-input
|
||
v-model="accessKeyForm.accessKeySecret"
|
||
type="password"
|
||
placeholder="输入 AccessKey Secret"
|
||
show-password
|
||
/>
|
||
<div class="form-hint">Secret 仅在创建时显示一次,请妥善保管</div>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<el-button @click="configDialogVisible = false">取消</el-button>
|
||
<el-button
|
||
:loading="testingConnection"
|
||
@click="handleTestHuorongConnection"
|
||
>
|
||
{{ testingConnection ? '测试中...' : '测试连接' }}
|
||
</el-button>
|
||
<el-button type="primary" @click="handleAccessKeySave">保存配置</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- ================================================================ -->
|
||
<!-- 配置对话框 — account_password 模式(联软LV7000) -->
|
||
<!-- ================================================================ -->
|
||
<el-dialog
|
||
v-if="configuringIntegration?.config_type === 'account_password'"
|
||
v-model="configDialogVisible"
|
||
:title="'配置集成 — ' + configuringIntegration?.name"
|
||
width="520px"
|
||
destroy-on-close
|
||
>
|
||
<el-form label-position="top">
|
||
<el-form-item label="Base URL(内网地址)">
|
||
<el-input
|
||
v-model="accountPasswordForm.baseUrl"
|
||
placeholder="http://192.168.x.x:30098"
|
||
/>
|
||
<div class="form-hint">联软LV7000终端安全管理系统的内网API地址,默认端口30098</div>
|
||
</el-form-item>
|
||
<el-form-item label="API 账号">
|
||
<el-input
|
||
v-model="accountPasswordForm.apiAccount"
|
||
placeholder="输入API账号"
|
||
/>
|
||
<div class="form-hint">在联软管理后台 → 系统设置 → API管理 中创建</div>
|
||
</el-form-item>
|
||
<el-form-item label="API 密码">
|
||
<el-input
|
||
v-model="accountPasswordForm.apiPassword"
|
||
type="password"
|
||
placeholder="输入API密码"
|
||
show-password
|
||
/>
|
||
<div class="form-hint">与API账号配套的密码,仅在创建时显示</div>
|
||
</el-form-item>
|
||
<el-form-item label="验证密钥(可选)">
|
||
<el-input
|
||
v-model="accountPasswordForm.validateKey"
|
||
placeholder="输入验证密钥(如需要)"
|
||
/>
|
||
<div class="form-hint">部分联软版本需要额外的验证密钥,无则留空</div>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<el-button @click="configDialogVisible = false">取消</el-button>
|
||
<el-button
|
||
:loading="testingConnection"
|
||
@click="handleTestLianruanConnection"
|
||
>
|
||
{{ testingConnection ? '测试中...' : '测试连接' }}
|
||
</el-button>
|
||
<el-button type="primary" @click="handleAccountPasswordSave">保存配置</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- ================================================================ -->
|
||
<!-- 联软连接测试结果对话框 -->
|
||
<!-- ================================================================ -->
|
||
<el-dialog
|
||
v-model="testResultVisible"
|
||
title="连接测试结果"
|
||
width="420px"
|
||
>
|
||
<div v-if="testResult" class="test-result">
|
||
<el-result
|
||
:icon="testResult.success ? 'success' : 'error'"
|
||
:title="testResult.success ? '连接成功' : '连接失败'"
|
||
:sub-title="testResult.message"
|
||
/>
|
||
<div v-if="testResult.success && testResult.total_terminals" class="test-detail">
|
||
检测到 <strong>{{ testResult.total_terminals }}</strong> 个终端
|
||
</div>
|
||
<!-- 失败时显示调试提示 -->
|
||
<div v-if="!testResult.success && testResult.debug_hint" class="test-debug-hint">
|
||
<el-icon><WarningFilled /></el-icon>
|
||
<span>{{ testResult.debug_hint }}</span>
|
||
</div>
|
||
<!-- 显示凭据摘要 -->
|
||
<div v-if="testResult.debug" class="test-debug-info">
|
||
<div>Base URL: {{ testResult.debug.base_url }}</div>
|
||
<div>AccessKey ID: {{ testResult.debug.access_key_id }}</div>
|
||
<div>Secret 长度: {{ testResult.debug.key_length }} 字符</div>
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<el-button type="primary" @click="testResultVisible = false">确定</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
// ==========================================================================
|
||
// 依赖导入
|
||
// ==========================================================================
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import { WarningFilled } from '@element-plus/icons-vue'
|
||
import IntegrationCard from '@/components/IntegrationCard.vue'
|
||
import { getIntegrations, updateIntegration, testHuorongConnection, testLianruanConnection, testRagflowConnection } from '@/api/admin'
|
||
import type { Integration } from '@/types'
|
||
|
||
// ==========================================================================
|
||
// 状态
|
||
// ==========================================================================
|
||
const loading = ref<boolean>(false)
|
||
const integrations = ref<Integration[]>([])
|
||
|
||
// ==========================================================================
|
||
// 配置对话框 — 通用状态
|
||
// ==========================================================================
|
||
const configDialogVisible = ref<boolean>(false)
|
||
const configuringIntegration = ref<Integration | null>(null)
|
||
|
||
// url_key 模式表单(Dify / RAGFlow)
|
||
const urlKeyForm = reactive({
|
||
apiUrl: '',
|
||
apiKey: '',
|
||
})
|
||
|
||
// access_key 模式表单(火绒安全)
|
||
const accessKeyForm = reactive({
|
||
baseUrl: '',
|
||
accessKeyId: '',
|
||
accessKeySecret: '',
|
||
})
|
||
|
||
// account_password 模式表单(联软LV7000)
|
||
const accountPasswordForm = reactive({
|
||
baseUrl: '',
|
||
apiAccount: '',
|
||
apiPassword: '',
|
||
validateKey: '',
|
||
})
|
||
|
||
// 火绒连接测试
|
||
const testingConnection = ref<boolean>(false)
|
||
const testResultVisible = ref<boolean>(false)
|
||
const testResult = ref<{ success: boolean; message: string; total_terminals?: number; debug_hint?: string; debug?: Record<string, unknown> } | null>(null)
|
||
|
||
// ==========================================================================
|
||
// 初始化
|
||
// ==========================================================================
|
||
onMounted(async () => {
|
||
loading.value = true
|
||
try {
|
||
const response = await getIntegrations()
|
||
integrations.value = response.data.data.items
|
||
} catch {
|
||
// 使用默认 demo 数据
|
||
integrations.value = getDefaultIntegrations()
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
})
|
||
|
||
// ==========================================================================
|
||
// 默认集成数据(API 不可用时的 fallback)
|
||
// ==========================================================================
|
||
function getDefaultIntegrations(): Integration[] {
|
||
return [
|
||
{
|
||
id: 'dify',
|
||
name: 'Dify AI',
|
||
status: 'connected',
|
||
configurable: true,
|
||
config_type: 'url_key',
|
||
config: { api_url: 'https://api.dify.ai/v1', api_key_set: true },
|
||
},
|
||
{
|
||
id: 'ragflow',
|
||
name: 'RAGFlow',
|
||
status: 'partial',
|
||
configurable: true,
|
||
config_type: 'url_key',
|
||
config: { api_url: '', api_key_set: false },
|
||
},
|
||
{
|
||
id: 'data_platform',
|
||
name: '数据平台',
|
||
status: 'disconnected',
|
||
configurable: false,
|
||
config: null,
|
||
},
|
||
{
|
||
id: 'beisen',
|
||
name: '北森 eHR',
|
||
status: 'disconnected',
|
||
configurable: false,
|
||
config: null,
|
||
},
|
||
{
|
||
id: 'huorong',
|
||
name: '火绒安全',
|
||
status: 'disconnected',
|
||
configurable: true,
|
||
config_type: 'access_key',
|
||
config: { api_url: '', api_key_set: false, access_key_id_set: false, access_key_secret_set: false, base_url: null },
|
||
},
|
||
{
|
||
id: 'lianruan',
|
||
name: '联软LV7000',
|
||
status: 'disconnected',
|
||
configurable: true,
|
||
config_type: 'account_password',
|
||
config: { api_url: '', api_account_set: false, api_password_set: false, base_url: null },
|
||
},
|
||
]
|
||
}
|
||
|
||
// ==========================================================================
|
||
// 集成系统图标映射
|
||
// ==========================================================================
|
||
const iconMap: Record<string, { icon: string; bg: string; color: string }> = {
|
||
dify: { icon: 'Cpu', bg: 'var(--accent-light)', color: 'var(--accent)' },
|
||
ragflow: { icon: 'Coin', bg: 'var(--success-bg)', color: 'var(--success)' },
|
||
data_platform: { icon: 'TrendCharts', bg: 'var(--warning-bg)', color: 'var(--warning)' },
|
||
beisen: { icon: 'Avatar', bg: 'rgba(139,92,246,0.12)', color: '#8b5cf6' },
|
||
huorong: { icon: 'WarningFilled', bg: 'var(--danger-bg)', color: 'var(--danger)' },
|
||
lianruan: { icon: 'Monitor', bg: 'rgba(236,72,153,0.12)', color: '#ec4899' },
|
||
}
|
||
|
||
function getIntegrationIcon(id: string): string {
|
||
return iconMap[id]?.icon || 'Setting'
|
||
}
|
||
|
||
function getIntegrationIconBg(id: string): string {
|
||
return iconMap[id]?.bg || 'var(--accent-light)'
|
||
}
|
||
|
||
function getIntegrationIconColor(id: string): string {
|
||
return iconMap[id]?.color || 'var(--accent)'
|
||
}
|
||
|
||
// ==========================================================================
|
||
// 操作处理
|
||
// ==========================================================================
|
||
|
||
/** 打开配置对话框(根据 config_type 显示不同表单) */
|
||
function handleConfigure(integration: Integration): void {
|
||
configuringIntegration.value = integration
|
||
const config = integration.config as Record<string, unknown> | null
|
||
|
||
if (integration.config_type === 'access_key') {
|
||
// 火绒模式:填充 access_key 表单
|
||
accessKeyForm.baseUrl = (config?.base_url as string) || (config?.api_url as string) || ''
|
||
accessKeyForm.accessKeyId = ''
|
||
accessKeyForm.accessKeySecret = ''
|
||
} else if (integration.config_type === 'account_password') {
|
||
// 联软模式:填充 account_password 表单
|
||
accountPasswordForm.baseUrl = (config?.base_url as string) || (config?.api_url as string) || ''
|
||
accountPasswordForm.apiAccount = ''
|
||
accountPasswordForm.apiPassword = ''
|
||
accountPasswordForm.validateKey = ''
|
||
} else {
|
||
// 默认 url_key 模式(Dify / RAGFlow)
|
||
urlKeyForm.apiUrl = (config?.api_url as string) || ''
|
||
urlKeyForm.apiKey = ''
|
||
}
|
||
|
||
configDialogVisible.value = true
|
||
}
|
||
|
||
/** 保存 url_key 模式配置(Dify / RAGFlow) */
|
||
async function handleUrlKeySave(): Promise<void> {
|
||
if (!configuringIntegration.value) return
|
||
try {
|
||
await updateIntegration(configuringIntegration.value.id, {
|
||
api_url: urlKeyForm.apiUrl,
|
||
api_key: urlKeyForm.apiKey || undefined,
|
||
})
|
||
ElMessage.success('配置已保存')
|
||
|
||
// 更新本地数据
|
||
const idx = integrations.value.findIndex((i) => i.id === configuringIntegration.value!.id)
|
||
if (idx >= 0) {
|
||
integrations.value[idx] = {
|
||
...integrations.value[idx],
|
||
status: urlKeyForm.apiUrl ? 'connected' : 'partial',
|
||
config: {
|
||
api_url: urlKeyForm.apiUrl,
|
||
api_key_set: !!urlKeyForm.apiKey,
|
||
},
|
||
}
|
||
}
|
||
configDialogVisible.value = false
|
||
} catch {
|
||
ElMessage.error('保存配置失败')
|
||
}
|
||
}
|
||
|
||
/** 保存 access_key 模式配置(火绒安全) */
|
||
async function handleAccessKeySave(): Promise<void> {
|
||
if (!configuringIntegration.value) return
|
||
|
||
// 校验必填项
|
||
if (!accessKeyForm.baseUrl) {
|
||
ElMessage.warning('请填写 Base URL')
|
||
return
|
||
}
|
||
if (!accessKeyForm.accessKeyId) {
|
||
ElMessage.warning('请填写 AccessKey ID')
|
||
return
|
||
}
|
||
if (!accessKeyForm.accessKeySecret) {
|
||
ElMessage.warning('请填写 AccessKey Secret')
|
||
return
|
||
}
|
||
|
||
try {
|
||
await updateIntegration(configuringIntegration.value.id, {
|
||
access_key_id: accessKeyForm.accessKeyId,
|
||
access_key_secret: accessKeyForm.accessKeySecret,
|
||
base_url: accessKeyForm.baseUrl,
|
||
})
|
||
ElMessage.success('配置已保存')
|
||
|
||
// 更新本地数据(标记为已配置,但不一定连接成功)
|
||
const idx = integrations.value.findIndex((i) => i.id === configuringIntegration.value!.id)
|
||
if (idx >= 0) {
|
||
integrations.value[idx] = {
|
||
...integrations.value[idx],
|
||
status: 'partial', // 需要测试连接才能确认 connected
|
||
config: {
|
||
api_url: accessKeyForm.baseUrl,
|
||
api_key_set: true,
|
||
access_key_id_set: true,
|
||
access_key_secret_set: true,
|
||
base_url: accessKeyForm.baseUrl,
|
||
},
|
||
}
|
||
}
|
||
configDialogVisible.value = false
|
||
// 提示用户测试连接
|
||
ElMessage.info('请在集成管理页点击"测试连接"验证凭据是否正确')
|
||
} catch {
|
||
ElMessage.error('保存配置失败')
|
||
}
|
||
}
|
||
|
||
/** 保存 account_password 模式配置(联软LV7000) */
|
||
async function handleAccountPasswordSave(): Promise<void> {
|
||
if (!configuringIntegration.value) return
|
||
|
||
// 校验必填项
|
||
if (!accountPasswordForm.baseUrl) {
|
||
ElMessage.warning('请填写 Base URL')
|
||
return
|
||
}
|
||
if (!accountPasswordForm.apiAccount) {
|
||
ElMessage.warning('请填写 API 账号')
|
||
return
|
||
}
|
||
if (!accountPasswordForm.apiPassword) {
|
||
ElMessage.warning('请填写 API 密码')
|
||
return
|
||
}
|
||
|
||
try {
|
||
await updateIntegration(configuringIntegration.value.id, {
|
||
api_account: accountPasswordForm.apiAccount,
|
||
api_password: accountPasswordForm.apiPassword,
|
||
base_url: accountPasswordForm.baseUrl,
|
||
validate_key: accountPasswordForm.validateKey || undefined,
|
||
})
|
||
ElMessage.success('配置已保存')
|
||
|
||
// 更新本地数据
|
||
const idx = integrations.value.findIndex((i) => i.id === configuringIntegration.value!.id)
|
||
if (idx >= 0) {
|
||
integrations.value[idx] = {
|
||
...integrations.value[idx],
|
||
status: 'connected',
|
||
config: {
|
||
api_url: accountPasswordForm.baseUrl,
|
||
api_account_set: true,
|
||
api_password_set: true,
|
||
base_url: accountPasswordForm.baseUrl,
|
||
},
|
||
}
|
||
}
|
||
configDialogVisible.value = false
|
||
} catch {
|
||
ElMessage.error('保存配置失败')
|
||
}
|
||
}
|
||
|
||
/** 测试联软API连接 */
|
||
async function handleTestLianruanConnection(): Promise<void> {
|
||
// 先保存配置再测试,确保使用最新配置
|
||
if (!accountPasswordForm.baseUrl || !accountPasswordForm.apiAccount || !accountPasswordForm.apiPassword) {
|
||
ElMessage.warning('请先填写完整配置')
|
||
return
|
||
}
|
||
|
||
testingConnection.value = true
|
||
try {
|
||
// 先保存配置
|
||
await updateIntegration(configuringIntegration.value!.id, {
|
||
api_account: accountPasswordForm.apiAccount,
|
||
api_password: accountPasswordForm.apiPassword,
|
||
base_url: accountPasswordForm.baseUrl,
|
||
validate_key: accountPasswordForm.validateKey || undefined,
|
||
})
|
||
|
||
// 再测试连接
|
||
const response = await testLianruanConnection()
|
||
testResult.value = response.data.data
|
||
testResultVisible.value = true
|
||
|
||
// 如果测试成功,更新本地状态
|
||
if (testResult.value?.success) {
|
||
const idx = integrations.value.findIndex((i) => i.id === configuringIntegration.value!.id)
|
||
if (idx >= 0) {
|
||
integrations.value[idx] = {
|
||
...integrations.value[idx],
|
||
status: 'connected',
|
||
config: {
|
||
api_url: accountPasswordForm.baseUrl,
|
||
api_account_set: true,
|
||
api_password_set: true,
|
||
base_url: accountPasswordForm.baseUrl,
|
||
},
|
||
}
|
||
}
|
||
}
|
||
} catch {
|
||
testResult.value = { success: false, message: '请求失败,请检查网络连接' }
|
||
testResultVisible.value = true
|
||
} finally {
|
||
testingConnection.value = false
|
||
}
|
||
}
|
||
|
||
/** 测试火绒API连接 */
|
||
async function handleTestHuorongConnection(): Promise<void> {
|
||
// 先保存配置再测试,确保使用最新配置
|
||
if (!accessKeyForm.baseUrl || !accessKeyForm.accessKeyId || !accessKeyForm.accessKeySecret) {
|
||
ElMessage.warning('请先填写完整配置')
|
||
return
|
||
}
|
||
|
||
testingConnection.value = true
|
||
try {
|
||
// 先保存配置
|
||
await updateIntegration(configuringIntegration.value!.id, {
|
||
access_key_id: accessKeyForm.accessKeyId,
|
||
access_key_secret: accessKeyForm.accessKeySecret,
|
||
base_url: accessKeyForm.baseUrl,
|
||
})
|
||
|
||
// 再测试连接
|
||
const response = await testHuorongConnection()
|
||
testResult.value = response.data.data
|
||
testResultVisible.value = true
|
||
|
||
// 如果测试成功,更新本地状态
|
||
if (testResult.value?.success) {
|
||
const idx = integrations.value.findIndex((i) => i.id === configuringIntegration.value!.id)
|
||
if (idx >= 0) {
|
||
integrations.value[idx] = {
|
||
...integrations.value[idx],
|
||
status: 'connected',
|
||
config: {
|
||
api_url: accessKeyForm.baseUrl,
|
||
api_key_set: true,
|
||
access_key_id_set: true,
|
||
access_key_secret_set: true,
|
||
base_url: accessKeyForm.baseUrl,
|
||
},
|
||
}
|
||
}
|
||
}
|
||
} catch {
|
||
testResult.value = { success: false, message: '请求失败,请检查网络连接' }
|
||
testResultVisible.value = true
|
||
} finally {
|
||
testingConnection.value = false
|
||
}
|
||
}
|
||
|
||
/** 测试连接(通用,非火绒/联软) */
|
||
async function handleTest(integration: Integration): Promise<void> {
|
||
if (integration.id === 'huorong' || integration.id === 'lianruan') {
|
||
// 火绒/联软的测试在配置对话框中完成
|
||
return
|
||
}
|
||
|
||
if (integration.id === 'ragflow') {
|
||
// RAGFlow 测试连接
|
||
testingConnection.value = true
|
||
try {
|
||
const response = await testRagflowConnection()
|
||
testResult.value = response.data.data
|
||
testResultVisible.value = true
|
||
|
||
// 如果测试成功,更新本地状态
|
||
if (testResult.value?.success) {
|
||
const idx = integrations.value.findIndex((i) => i.id === integration.id)
|
||
if (idx >= 0) {
|
||
integrations.value[idx] = {
|
||
...integrations.value[idx],
|
||
status: 'connected',
|
||
}
|
||
}
|
||
}
|
||
} catch {
|
||
testResult.value = { success: false, message: '请求失败,请检查网络连接' }
|
||
testResultVisible.value = true
|
||
} finally {
|
||
testingConnection.value = false
|
||
}
|
||
return
|
||
}
|
||
|
||
ElMessage.info(`正在测试 ${integration.name} 连接...`)
|
||
}
|
||
|
||
/** 查看详情 */
|
||
function handleView(integration: Integration): void {
|
||
ElMessage.info(`${integration.name} — 暂无更多配置信息`)
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 页面 */
|
||
.integrations-page {
|
||
/* 样式使用全局 .integration-grid */
|
||
}
|
||
|
||
/* 加载状态 */
|
||
.loading-state {
|
||
padding: 24px 0;
|
||
}
|
||
|
||
/* 表单提示 */
|
||
.form-hint {
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
margin-top: 4px;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/* 测试结果 */
|
||
.test-result {
|
||
text-align: center;
|
||
}
|
||
|
||
.test-detail {
|
||
margin-top: 8px;
|
||
font-size: 14px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* 调试提示 */
|
||
.test-debug-hint {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 6px;
|
||
margin-top: 12px;
|
||
padding: 10px 12px;
|
||
background: rgba(245, 158, 11, 0.08);
|
||
border: 1px solid rgba(245, 158, 11, 0.2);
|
||
border-radius: 6px;
|
||
font-size: 12px;
|
||
color: #d97706;
|
||
text-align: left;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.test-debug-info {
|
||
margin-top: 8px;
|
||
padding: 8px 12px;
|
||
background: var(--bg-tertiary);
|
||
border-radius: 6px;
|
||
font-size: 11px;
|
||
color: var(--text-muted);
|
||
text-align: left;
|
||
font-family: monospace;
|
||
line-height: 1.6;
|
||
}
|
||
</style>
|