feat(settings): implement system settings
This commit is contained in:
@@ -1,12 +1,136 @@
|
||||
<script setup lang="ts">
|
||||
import PagePlaceholder from '@/components/PagePlaceholder.vue'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
import EmbedSettingsCard from './components/EmbedSettingsCard.vue'
|
||||
import SignatureSettingsCard from './components/SignatureSettingsCard.vue'
|
||||
import SmsSettingsCard from './components/SmsSettingsCard.vue'
|
||||
import TabletDevicesCard from './components/TabletDevicesCard.vue'
|
||||
import {
|
||||
defaultSmsChannel,
|
||||
mockSignatureSettings,
|
||||
mockTabletDevices,
|
||||
smsChannelOptions,
|
||||
} from './mock'
|
||||
import type { SettingToggleKey, SignatureSettings, SmsChannel, TabletDevice } from './types'
|
||||
|
||||
const loading = ref(true)
|
||||
const signatureSettings = reactive<SignatureSettings>({ ...mockSignatureSettings })
|
||||
const smsChannel = ref<SmsChannel>(defaultSmsChannel)
|
||||
const tabletDevices = ref<TabletDevice[]>([])
|
||||
|
||||
async function loadSettings() {
|
||||
loading.value = true
|
||||
await Promise.resolve()
|
||||
tabletDevices.value = mockTabletDevices.map((device) => ({ ...device }))
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
function updateLinkExpireHours(value: number) {
|
||||
signatureSettings.linkExpireHours = value
|
||||
}
|
||||
|
||||
function toggleSetting(key: SettingToggleKey) {
|
||||
signatureSettings[key] = !signatureSettings[key]
|
||||
|
||||
if (key === 'caCertificate' && signatureSettings.caCertificate) {
|
||||
ElMessage.info('已开启 CA 扩展位(当前版本未启用)')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessage.info('设置已更新')
|
||||
}
|
||||
|
||||
function updateSmsChannel(value: SmsChannel) {
|
||||
smsChannel.value = value
|
||||
}
|
||||
|
||||
function sendTestSms() {
|
||||
ElMessage.success('测试短信已发送至 138****5678')
|
||||
}
|
||||
|
||||
function reconnectDevice(device: TabletDevice) {
|
||||
if (device.status === 'connected') {
|
||||
ElMessage.success('已重新连接')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessage.info('正在重连…')
|
||||
}
|
||||
|
||||
function copyEmbedUrl() {
|
||||
ElMessage.success('原型演示:已复制嵌入 URL')
|
||||
}
|
||||
|
||||
function rotateKey() {
|
||||
ElMessage.success('原型演示:密钥轮换成功')
|
||||
}
|
||||
|
||||
onMounted(loadSettings)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PagePlaceholder
|
||||
group="管理"
|
||||
title="系统设置"
|
||||
icon="⚙"
|
||||
description="系统设置页面占位,待根据 Web 端需求实现。"
|
||||
/>
|
||||
<section class="settings-page">
|
||||
<div v-if="loading" class="loading-grid" aria-label="正在加载系统设置">
|
||||
<span v-for="index in 4" :key="index" />
|
||||
</div>
|
||||
|
||||
<div v-else class="settings-grid">
|
||||
<SignatureSettingsCard
|
||||
:settings="signatureSettings"
|
||||
@update:link-expire-hours="updateLinkExpireHours"
|
||||
@toggle="toggleSetting"
|
||||
/>
|
||||
<SmsSettingsCard
|
||||
:channel="smsChannel"
|
||||
:channel-options="smsChannelOptions"
|
||||
@update:channel="updateSmsChannel"
|
||||
@test="sendTestSms"
|
||||
/>
|
||||
<TabletDevicesCard :devices="tabletDevices" @reconnect="reconnectDevice" />
|
||||
<EmbedSettingsCard @copy="copyEmbedUrl" @rotate-key="rotateKey" />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.settings-page {
|
||||
width: 100%;
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.settings-grid,
|
||||
.loading-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.loading-grid span {
|
||||
display: block;
|
||||
height: 240px;
|
||||
background: linear-gradient(90deg, #edf3f5 25%, #f7fafb 37%, #edf3f5 63%);
|
||||
background-size: 400% 100%;
|
||||
border-radius: var(--r);
|
||||
box-shadow: var(--sh);
|
||||
animation: skeleton-shimmer 1.4s ease infinite;
|
||||
}
|
||||
|
||||
@keyframes skeleton-shimmer {
|
||||
0% {
|
||||
background-position: 100% 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -100% 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.settings-grid,
|
||||
.loading-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user