Files
erp_sb/electron-vue-template/src/renderer/components/common/SettingsDialog.vue
2025-09-30 17:16:11 +08:00

333 lines
7.1 KiB
Vue

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import {
getSettings,
saveSettings,
savePlatformSettings,
type Platform,
type PlatformExportSettings
} from '../../utils/settings'
interface Props {
modelValue: boolean
}
interface Emits {
(e: 'update:modelValue', value: boolean): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
// 平台配置
const platforms = [
{ key: 'amazon' as Platform, name: 'Amazon', icon: '🛒', color: '#FF9900' },
{ key: 'rakuten' as Platform, name: 'Rakuten', icon: '🛍️', color: '#BF0000' },
{ key: 'zebra' as Platform, name: 'Zebra', icon: '🦓', color: '#34495E' }
]
// 设置项
const platformSettings = ref<Record<Platform, PlatformExportSettings>>({
amazon: { exportPath: '' },
rakuten: { exportPath: '' },
zebra: { exportPath: '' }
})
const activeTab = ref<Platform>('amazon')
const show = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
})
// 选择导出路径
async function selectExportPath(platform: Platform) {
const result = await (window as any).electronAPI.showOpenDialog({
title: `选择${platforms.find(p => p.key === platform)?.name}默认导出路径`,
properties: ['openDirectory'],
defaultPath: platformSettings.value[platform].exportPath
})
if (!result.canceled && result.filePaths?.length > 0) {
platformSettings.value[platform].exportPath = result.filePaths[0]
}
}
// 保存设置
function saveAllSettings() {
Object.keys(platformSettings.value).forEach(platformKey => {
const platform = platformKey as Platform
const platformConfig = platformSettings.value[platform]
savePlatformSettings(platform, platformConfig)
})
ElMessage({ message: '设置已保存', type: 'success' })
show.value = false
}
// 加载设置
function loadAllSettings() {
const settings = getSettings()
platformSettings.value = {
amazon: { ...settings.platforms.amazon },
rakuten: { ...settings.platforms.rakuten },
zebra: { ...settings.platforms.zebra }
}
}
// 重置单个平台设置
function resetPlatformSettings(platform: Platform) {
platformSettings.value[platform] = {
exportPath: ''
}
}
// 重置所有设置
function resetAllSettings() {
platforms.forEach(platform => {
resetPlatformSettings(platform.key)
})
}
onMounted(() => {
loadAllSettings()
})
</script>
<template>
<el-dialog
v-model="show"
title="应用设置"
width="480px"
:close-on-click-modal="false"
class="settings-dialog">
<div class="settings-content">
<!-- 平台选择标签 -->
<div class="platform-tabs">
<div
v-for="platform in platforms"
:key="platform.key"
:class="['platform-tab', { active: activeTab === platform.key }]"
@click="activeTab = platform.key"
:style="{ '--platform-color': platform.color }">
<span class="platform-icon">{{ platform.icon }}</span>
<span class="platform-name">{{ platform.name }}</span>
</div>
</div>
<!-- 当前平台设置 -->
<div class="setting-section">
<div class="section-title">
<span class="title-icon">📁</span>
<span>{{ platforms.find(p => p.key === activeTab)?.name }} 导出设置</span>
</div>
<div class="setting-item">
<div class="setting-label">默认导出路径</div>
<div class="setting-desc">设置 {{ platforms.find(p => p.key === activeTab)?.name }} Excel文件的默认保存位置</div>
<div class="path-input-group">
<el-input
v-model="platformSettings[activeTab].exportPath"
placeholder="留空时自动弹出保存对话框"
readonly
class="path-input">
<template #suffix>
<el-button
size="small"
type="primary"
@click="selectExportPath(activeTab)"
class="select-btn">
浏览
</el-button>
</template>
</el-input>
</div>
</div>
<div class="setting-actions">
<el-button
size="small"
@click="resetPlatformSettings(activeTab)">
重置此平台
</el-button>
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="resetAllSettings">重置全部</el-button>
<el-button @click="show = false">取消</el-button>
<el-button type="primary" @click="saveAllSettings">保存设置</el-button>
</div>
</template>
</el-dialog>
</template>
<style scoped>
.settings-dialog :deep(.el-dialog__body) {
padding: 0 20px 20px 20px;
}
.settings-content {
max-height: 500px;
overflow-y: auto;
}
.platform-tabs {
display: flex;
gap: 8px;
margin-bottom: 20px;
padding: 4px;
background: #F8F9FA;
border-radius: 8px;
}
.platform-tab {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
background: transparent;
color: #606266;
font-size: 13px;
}
.platform-tab:hover {
background: rgba(255, 255, 255, 0.8);
color: var(--platform-color);
}
.platform-tab.active {
background: #fff;
color: var(--platform-color);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
font-weight: 500;
}
.platform-icon {
font-size: 16px;
}
.platform-name {
font-size: 12px;
}
.setting-section {
margin-bottom: 24px;
}
.section-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid #EBEEF5;
}
.title-icon {
font-size: 18px;
}
.setting-item {
margin-bottom: 20px;
}
.setting-row {
display: flex;
align-items: center;
justify-content: space-between;
}
.setting-info {
flex: 1;
}
.setting-label {
font-size: 14px;
font-weight: 500;
color: #303133;
margin-bottom: 4px;
}
.setting-desc {
font-size: 12px;
color: #909399;
line-height: 1.4;
}
.path-input-group {
margin-top: 8px;
}
.path-input {
width: 100%;
}
.path-input :deep(.el-input__wrapper) {
padding-right: 80px;
}
.select-btn {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
height: 24px;
padding: 0 12px;
font-size: 12px;
}
.info-content {
background: #F8F9FA;
border-radius: 6px;
padding: 12px;
font-size: 13px;
color: #606266;
line-height: 1.5;
}
.info-content p {
margin: 0 0 6px 0;
}
.info-content p:last-child {
margin-bottom: 0;
}
.setting-actions {
margin-top: 16px;
padding-top: 12px;
border-top: 1px solid #EBEEF5;
}
.settings-dialog :deep(.el-dialog__header) {
text-align: center;
padding-right: 40px; /* 为右侧关闭按钮留出空间 */
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
}
</style>
<script lang="ts">
export default {
name: 'SettingsDialog'
}
</script>