709 lines
21 KiB
Vue
709 lines
21 KiB
Vue
<template>
|
||
<view class="settings-page" :class="`theme-${themeMode}`">
|
||
<view class="page-accent"></view>
|
||
|
||
<view class="settings-card">
|
||
<view class="card-header">
|
||
<text class="card-title">基础配置</text>
|
||
<text class="card-subtitle">扫码与反馈</text>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="selectScanInterval">
|
||
<view class="setting-main">
|
||
<text class="setting-label">连续扫码时间间隔</text>
|
||
</view>
|
||
<view class="setting-right interval-right">
|
||
<view class="value-line">
|
||
<text class="setting-value">{{ settings.scanInterval }}s</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="selectScanRegionPreset">
|
||
<view class="setting-main">
|
||
<text class="setting-label">有效识别区域</text>
|
||
<text class="setting-desc">{{ scanRegionSummary }}</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ scanRegionPresetLabel }}</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view v-if="settings.scanRegionPreset === 'barcode'" class="setting-row tappable" @tap="selectScanRegionPosition">
|
||
<view class="setting-main">
|
||
<text class="setting-label">横向条码框位置</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ scanRegionPositionLabel }}</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view v-if="settings.scanRegionPreset === 'barcode'" class="setting-row tappable" @tap="selectScanRegionHeight">
|
||
<view class="setting-main">
|
||
<text class="setting-label">扫描框高度</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ scanRegionHeightLabel }}</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view v-if="settings.scanRegionPreset === 'barcode' && settings.scanRegionPosition === 'custom'" class="setting-row tappable" @tap="adjustCustomScanRegion">
|
||
<view class="setting-main">
|
||
<text class="setting-label">自定义条码框位置</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ regionPercent(settings.scanRegion.centerY) }}%</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-row">
|
||
<view class="setting-main">
|
||
<text class="setting-label">成功提示音</text>
|
||
</view>
|
||
<u-switch v-model="settings.successSound" active-color="#2f6cf6" />
|
||
</view>
|
||
|
||
<view class="setting-row">
|
||
<view class="setting-main">
|
||
<text class="setting-label">失败提示音</text>
|
||
</view>
|
||
<u-switch v-model="settings.failSound" active-color="#ef4f4f" />
|
||
</view>
|
||
|
||
<view class="setting-row">
|
||
<view class="setting-main">
|
||
<text class="setting-label">震动反馈</text>
|
||
</view>
|
||
<u-switch v-model="settings.vibration" active-color="#35bfa3" />
|
||
</view>
|
||
|
||
<view class="setting-row">
|
||
<view class="setting-main">
|
||
<text class="setting-label">PDA 模式</text>
|
||
</view>
|
||
<u-switch v-model="settings.pdaMode" active-color="#1677ff" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="settings-card">
|
||
<view class="card-header">
|
||
<text class="card-title">识别处理</text>
|
||
<text class="card-subtitle">扫码识别与界面偏好</text>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="selectTheme">
|
||
<view class="setting-main">
|
||
<text class="setting-label">主题模式</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ settings.theme === 'light' ? '浅色' : '深色' }}</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="selectLanguage">
|
||
<view class="setting-main">
|
||
<text class="setting-label">语言</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ settings.language === 'zh' ? '中文' : 'EN' }}</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-row">
|
||
<view class="setting-main">
|
||
<text class="setting-label">自动保存草稿</text>
|
||
</view>
|
||
<u-switch v-model="settings.autoSave" active-color="#2f6cf6" />
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="selectUploadMode">
|
||
<view class="setting-main">
|
||
<text class="setting-label">图片上传方式</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ settings.uploadMode === 'wifi' ? '仅 Wi-Fi' : '任意网络' }}</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="settings-card">
|
||
<view class="card-header">
|
||
<text class="card-title">软件维护</text>
|
||
<text class="card-subtitle">本地与维护</text>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="selectCacheDays">
|
||
<view class="setting-main">
|
||
<text class="setting-label">历史缓存保留</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ settings.cacheDays }} 天</text>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="checkForUpdate">
|
||
<view class="setting-main">
|
||
<text class="setting-label">检查更新</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">v{{ currentVersion }}</text>
|
||
<u-icon name="arrow-right" color="#c1c7d0" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="clearBusinessCache">
|
||
<view class="setting-main">
|
||
<text class="setting-label">清理缓存</text>
|
||
</view>
|
||
<u-icon name="arrow-right" color="#c1c7d0" size="24" />
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="resetSettings">
|
||
<view class="setting-main">
|
||
<text class="setting-label">恢复默认设置</text>
|
||
</view>
|
||
<u-icon name="arrow-right" color="#c1c7d0" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="settings-card">
|
||
<view class="card-header">
|
||
<text class="card-title">帮助与支持</text>
|
||
<text class="card-subtitle">问题反馈与应用信息</text>
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="goFeedback">
|
||
<view class="setting-main">
|
||
<text class="setting-label">问题反馈</text>
|
||
</view>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
|
||
<view class="setting-row tappable" @tap="goAbout">
|
||
<view class="setting-main">
|
||
<text class="setting-label">关于我们</text>
|
||
</view>
|
||
<u-icon name="arrow-right" color="#d0d6e2" size="24" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="footer-tip">设置会自动保存在本机,切换账号后设置相互独立</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
compareVersions,
|
||
getCurrentAppVersion,
|
||
getLatestRelease,
|
||
getReleaseUpdateInfo
|
||
} from '@/api/app-update.js'
|
||
import { applyAppTheme } from '@/utils/theme.js'
|
||
import { getScanappSettings, getScanappSettingsStorageKey } from '@/utils/scan-settings.js'
|
||
|
||
export default {
|
||
data() {
|
||
const defaultSettings = {
|
||
scanInterval: 1,
|
||
successSound: true,
|
||
failSound: true,
|
||
vibration: true,
|
||
pdaMode: false,
|
||
theme: 'light',
|
||
language: 'zh',
|
||
autoSave: true,
|
||
cacheDays: 30,
|
||
uploadMode: 'wifi',
|
||
scanRegionPreset: 'fullscreen',
|
||
scanRegionPosition: 'middle',
|
||
scanRegionHeight: 'medium',
|
||
scanRegion: { fullScreen: true }
|
||
}
|
||
return {
|
||
settingsStorageKey: getScanappSettingsStorageKey(),
|
||
isLoadingSettings: true,
|
||
intervalOptions: [0.3, 0.5, 1, 1.5, 2, 3, 5],
|
||
cacheDayOptions: [7, 15, 30, 60, 90],
|
||
scanRegionPresets: [
|
||
{ key: 'fullscreen', label: '全屏识别', description: '整画面均可识别,不显示扫描框' },
|
||
{ key: 'qrcode', label: '二维码正方形框', description: '适合二维码与方形标签' },
|
||
{ key: 'barcode', label: '横向条码框', description: '适合商品条码,可调整位置和高度' }
|
||
],
|
||
scanRegionPositions: [
|
||
{ key: 'top', label: '上方', centerY: 0.28 },
|
||
{ key: 'middle', label: '居中', centerY: 0.5 },
|
||
{ key: 'bottom', label: '下方', centerY: 0.72 },
|
||
{ key: 'custom', label: '自定义' }
|
||
],
|
||
scanRegionHeights: [
|
||
{ key: 'medium', label: '中(24%)', height: 0.24 },
|
||
{ key: 'large', label: '大(32%)', height: 0.32 },
|
||
{ key: 'xlarge', label: '特大(40%)', height: 0.4 }
|
||
],
|
||
defaultSettings,
|
||
settings: { ...defaultSettings, scanRegion: { ...defaultSettings.scanRegion } },
|
||
checkingUpdate: false,
|
||
currentVersion: getCurrentAppVersion()
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.settingsStorageKey = getScanappSettingsStorageKey()
|
||
this.loadSettings()
|
||
this.isLoadingSettings = false
|
||
},
|
||
watch: {
|
||
settings: {
|
||
deep: true,
|
||
handler() {
|
||
if (this.isLoadingSettings) return
|
||
this.saveSettings()
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
loadSettings() {
|
||
const savedSettings = getScanappSettings()
|
||
if (savedSettings && typeof savedSettings === 'object') {
|
||
const preset = savedSettings.scanRegionPreset || (savedSettings.scanRegion?.fullScreen ? 'fullscreen' : 'barcode')
|
||
const savedRegion = savedSettings.scanRegion || {}
|
||
let scanRegion = { ...this.defaultSettings.scanRegion }
|
||
if (preset === 'fullscreen') {
|
||
scanRegion = { fullScreen: true }
|
||
} else if (preset === 'qrcode') {
|
||
scanRegion = { width: 0.74, height: 0.74, centerX: 0.5, centerY: 0.5 }
|
||
} else {
|
||
scanRegion = {
|
||
width: Number(savedRegion.width) || 0.96,
|
||
height: Number(savedRegion.height) || 0.24,
|
||
centerX: Number.isFinite(Number(savedRegion.centerX)) ? Number(savedRegion.centerX) : 0.5,
|
||
centerY: Number.isFinite(Number(savedRegion.centerY)) ? Number(savedRegion.centerY) : 0.5
|
||
}
|
||
}
|
||
this.settings = {
|
||
...this.defaultSettings,
|
||
...savedSettings,
|
||
scanRegionPreset: preset,
|
||
scanRegion
|
||
}
|
||
}
|
||
applyAppTheme(this.settings.theme)
|
||
},
|
||
saveSettings() {
|
||
uni.setStorageSync(this.settingsStorageKey, { ...this.settings })
|
||
},
|
||
checkForUpdate() {
|
||
if (this.checkingUpdate) return
|
||
this.checkingUpdate = true
|
||
uni.showLoading({ title: '正在检查更新', mask: true })
|
||
getLatestRelease()
|
||
.then((release) => {
|
||
const currentVersion = getCurrentAppVersion()
|
||
const updateInfo = getReleaseUpdateInfo(release)
|
||
if (compareVersions(updateInfo.latestVersion, currentVersion) <= 0) {
|
||
uni.showModal({
|
||
title: '检查更新',
|
||
content: `当前版本 v${currentVersion},已是最新版本`,
|
||
showCancel: false,
|
||
confirmText: '知道了'
|
||
})
|
||
return
|
||
}
|
||
const content = `发现新版本 v${updateInfo.latestVersion}\n\n${updateInfo.updateNote}${updateInfo.apkUrl ? '\n\n是否立即下载并安装?' : '\n\n更新包暂未发布,请稍后再试。'}`
|
||
uni.showModal({
|
||
title: '发现新版本',
|
||
content,
|
||
confirmText: updateInfo.apkUrl ? '立即更新' : '知道了',
|
||
showCancel: Boolean(updateInfo.apkUrl),
|
||
cancelText: '暂不更新',
|
||
success: (modalResult) => {
|
||
if (modalResult.confirm && updateInfo.apkUrl) {
|
||
this.downloadAndInstallApk(updateInfo.apkUrl)
|
||
}
|
||
}
|
||
})
|
||
})
|
||
.catch((error) => {
|
||
uni.showModal({
|
||
title: '检查更新失败',
|
||
content: error.message || '无法获取最新版本信息,请稍后重试',
|
||
showCancel: false,
|
||
confirmText: '知道了'
|
||
})
|
||
})
|
||
.finally(() => {
|
||
this.checkingUpdate = false
|
||
uni.hideLoading()
|
||
})
|
||
},
|
||
downloadAndInstallApk(downloadUrl) {
|
||
// #ifdef APP-PLUS
|
||
if (!downloadUrl) return
|
||
uni.showLoading({ title: '正在下载更新包', mask: true })
|
||
uni.downloadFile({
|
||
url: downloadUrl,
|
||
success: (result) => {
|
||
if (result.statusCode !== 200) {
|
||
uni.showToast({ title: '更新包下载失败', icon: 'none' })
|
||
return
|
||
}
|
||
plus.runtime.install(result.tempFilePath, {}, () => {}, (error) => {
|
||
uni.showModal({ title: '安装失败', content: error.message || '请允许安装未知来源应用后重试', showCancel: false })
|
||
})
|
||
},
|
||
fail: () => uni.showToast({ title: '更新包下载失败,请检查网络', icon: 'none' }),
|
||
complete: () => uni.hideLoading()
|
||
})
|
||
// #endif
|
||
// #ifndef APP-PLUS
|
||
this.openReleasePage(downloadUrl)
|
||
// #endif
|
||
},
|
||
openReleasePage(url) {
|
||
const releaseUrl = url || 'https://gitee.com/li-hua-88/scanapp/releases/latest'
|
||
// #ifdef APP-PLUS
|
||
plus.runtime.openURL(releaseUrl)
|
||
// #endif
|
||
// #ifndef APP-PLUS
|
||
window.location.href = releaseUrl
|
||
// #endif
|
||
},
|
||
clearBusinessCache() {
|
||
uni.showModal({
|
||
title: '清理缓存',
|
||
content: '将清理扫码业务缓存,保留登录状态和当前设置,是否继续?',
|
||
confirmText: '清理',
|
||
confirmColor: '#1677ff',
|
||
success: (res) => {
|
||
if (!res.confirm) return
|
||
const protectedKeys = new Set(['scanapp_token', 'scanapp_refresh_token', 'scanapp_user'])
|
||
const storageInfo = uni.getStorageInfoSync()
|
||
;(storageInfo.keys || []).forEach((key) => {
|
||
const isSettingsKey = key === 'scanapp_settings' || key.indexOf('scanapp_settings_') === 0
|
||
if (key.indexOf('scanapp_') === 0 && !protectedKeys.has(key) && !isSettingsKey) {
|
||
uni.removeStorageSync(key)
|
||
}
|
||
})
|
||
uni.showToast({ title: '缓存已清理', icon: 'success' })
|
||
}
|
||
})
|
||
},
|
||
resetSettings() {
|
||
uni.showModal({
|
||
title: '恢复默认设置',
|
||
content: '所有设置项将恢复为默认值,是否继续?',
|
||
confirmText: '恢复',
|
||
confirmColor: '#1677ff',
|
||
success: (res) => {
|
||
if (!res.confirm) return
|
||
this.settings = { ...this.defaultSettings, scanRegion: { ...this.defaultSettings.scanRegion } }
|
||
this.saveSettings()
|
||
applyAppTheme(this.settings.theme)
|
||
uni.showToast({ title: '已恢复默认设置', icon: 'success' })
|
||
}
|
||
})
|
||
},
|
||
selectScanInterval() {
|
||
this.showSettingOptions('连续扫码时间间隔', this.intervalOptions.map((item) => `${item}S`), (index) => {
|
||
this.settings.scanInterval = this.intervalOptions[index]
|
||
})
|
||
},
|
||
selectScanRegionPreset() {
|
||
this.showSettingOptions('有效识别区域', this.scanRegionPresets.map((item) => item.label), (index) => {
|
||
const preset = this.scanRegionPresets[index]
|
||
if (!preset) return
|
||
this.settings.scanRegionPreset = preset.key
|
||
if (preset.key === 'fullscreen') {
|
||
this.settings.scanRegion = { fullScreen: true }
|
||
return
|
||
}
|
||
if (preset.key === 'qrcode') {
|
||
this.settings.scanRegion = { width: 0.74, height: 0.74, centerX: 0.5, centerY: 0.5 }
|
||
return
|
||
}
|
||
const position = this.scanRegionPositions.find((item) => item.key === this.settings.scanRegionPosition) || this.scanRegionPositions[1]
|
||
const height = this.scanRegionHeights.find((item) => item.key === this.settings.scanRegionHeight) || this.scanRegionHeights[0]
|
||
this.settings.scanRegion = { width: 0.96, height: height.height, centerX: 0.5, centerY: position.centerY || 0.5 }
|
||
})
|
||
},
|
||
selectScanRegionPosition() {
|
||
this.showSettingOptions('横向条码框位置', this.scanRegionPositions.map((item) => item.label), (index) => {
|
||
const position = this.scanRegionPositions[index]
|
||
if (!position) return
|
||
this.settings.scanRegionPosition = position.key
|
||
if (position.key !== 'custom') this.settings.scanRegion.centerY = position.centerY
|
||
})
|
||
},
|
||
selectScanRegionHeight() {
|
||
this.showSettingOptions('扫描框高度', this.scanRegionHeights.map((item) => item.label), (index) => {
|
||
const height = this.scanRegionHeights[index]
|
||
if (!height) return
|
||
this.settings.scanRegionHeight = height.key
|
||
this.settings.scanRegion.height = height.height
|
||
const minCenterY = height.height / 2
|
||
this.settings.scanRegion.centerY = Math.max(minCenterY, Math.min(1 - minCenterY, Number(this.settings.scanRegion.centerY || 0.5)))
|
||
})
|
||
},
|
||
adjustCustomScanRegion() {
|
||
this.showSettingOptions('调整自定义位置', ['上移 5%', '下移 5%'], (index) => {
|
||
const delta = index === 0 ? -0.05 : 0.05
|
||
const height = Number(this.settings.scanRegion.height || 0.24)
|
||
const minCenterY = height / 2
|
||
const maxCenterY = 1 - minCenterY
|
||
this.settings.scanRegion.centerY = Math.max(minCenterY, Math.min(maxCenterY, Number((Number(this.settings.scanRegion.centerY || 0.5) + delta).toFixed(2))))
|
||
})
|
||
},
|
||
regionPercent(value) {
|
||
return Math.round(Number(value || 0) * 100)
|
||
},
|
||
selectTheme() {
|
||
this.showSettingOptions('主题模式', ['浅色模式', '深色模式'], (index) => {
|
||
this.settings.theme = index === 0 ? 'light' : 'dark'
|
||
applyAppTheme(this.settings.theme)
|
||
})
|
||
},
|
||
selectLanguage() {
|
||
this.showSettingOptions('语言', ['简体中文', 'English'], (index) => {
|
||
this.settings.language = index === 0 ? 'zh' : 'en'
|
||
})
|
||
},
|
||
selectUploadMode() {
|
||
this.showSettingOptions('图片上传方式', ['仅 Wi-Fi', '任意网络'], (index) => {
|
||
this.settings.uploadMode = index === 0 ? 'wifi' : 'all'
|
||
})
|
||
},
|
||
selectCacheDays() {
|
||
this.showSettingOptions('历史缓存保留', this.cacheDayOptions.map((item) => `${item} 天`), (index) => {
|
||
this.settings.cacheDays = this.cacheDayOptions[index]
|
||
})
|
||
},
|
||
showSettingOptions(title, itemList, onSelect) {
|
||
uni.showActionSheet({
|
||
title,
|
||
itemList,
|
||
success: (res) => onSelect(res.tapIndex)
|
||
})
|
||
},
|
||
goFeedback() {
|
||
uni.navigateTo({
|
||
url: '/pages/settings/feedback'
|
||
})
|
||
},
|
||
goAbout() {
|
||
uni.navigateTo({
|
||
url: '/pages/settings/about'
|
||
})
|
||
},
|
||
toggleAutoSave() {
|
||
this.settings.autoSave = !this.settings.autoSave
|
||
},
|
||
showMockToast(title) {
|
||
uni.showToast({ title, icon: 'none' })
|
||
}
|
||
},
|
||
computed: {
|
||
scanRegionPresetLabel() {
|
||
return this.scanRegionPresets.find((item) => item.key === this.settings.scanRegionPreset)?.label || '横向条码框'
|
||
},
|
||
scanRegionPositionLabel() {
|
||
return this.scanRegionPositions.find((item) => item.key === this.settings.scanRegionPosition)?.label || '居中'
|
||
},
|
||
scanRegionHeightLabel() {
|
||
return this.scanRegionHeights.find((item) => item.key === this.settings.scanRegionHeight)?.label || '中(24%)'
|
||
},
|
||
scanRegionSummary() {
|
||
if (this.settings.scanRegionPreset === 'fullscreen') return '整画面识别,不显示扫描框'
|
||
const region = this.settings.scanRegion || {}
|
||
return `宽 ${this.regionPercent(region.width)}% · 高 ${this.regionPercent(region.height)}% · 中心 ${this.regionPercent(region.centerX)}%, ${this.regionPercent(region.centerY)}%`
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.settings-page {
|
||
min-height: 100vh;
|
||
padding: 0 22rpx 40rpx;
|
||
box-sizing: border-box;
|
||
background: linear-gradient(180deg, #eaf2ff 0%, #f6f8fd 18%, #f4f7fb 100%);
|
||
}
|
||
|
||
.page-accent {
|
||
height: 10rpx;
|
||
margin: 0 -22rpx 18rpx;
|
||
background: linear-gradient(90deg, #2f6cf6 0%, #35bfa3 100%);
|
||
}
|
||
|
||
.settings-card {
|
||
margin-top: 18rpx;
|
||
padding: 30rpx 26rpx;
|
||
border-radius: 30rpx;
|
||
background: #ffffff;
|
||
box-shadow: 0 14rpx 32rpx rgba(24, 37, 68, 0.06);
|
||
}
|
||
|
||
.card-header {
|
||
margin-bottom: 14rpx;
|
||
}
|
||
|
||
.card-title {
|
||
display: block;
|
||
color: #8a94a6;
|
||
font-size: 24rpx;
|
||
font-weight: 700;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.card-subtitle {
|
||
display: block;
|
||
margin-top: 6rpx;
|
||
color: #c1c7d0;
|
||
font-size: 18rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.setting-row,
|
||
.action-list .setting-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 18rpx;
|
||
padding: 20rpx 0;
|
||
border-bottom: 1rpx solid #eef1f6;
|
||
}
|
||
|
||
.setting-row:last-child,
|
||
.action-list .setting-row:last-child {
|
||
padding-bottom: 0;
|
||
border-bottom: 0;
|
||
}
|
||
|
||
.setting-main {
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.setting-label {
|
||
display: block;
|
||
color: #17233d;
|
||
font-size: 26rpx;
|
||
font-weight: 700;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.setting-desc {
|
||
display: block;
|
||
margin-top: 10rpx;
|
||
color: #8f98a8;
|
||
font-size: 18rpx;
|
||
line-height: 1.45;
|
||
}
|
||
|
||
.setting-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10rpx;
|
||
flex: none;
|
||
}
|
||
|
||
.setting-row :deep(.u-switch) {
|
||
transform: scale(0.82);
|
||
transform-origin: right center;
|
||
}
|
||
|
||
.value-line {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
}
|
||
|
||
.setting-value {
|
||
color: #5f6b7a;
|
||
font-size: 22rpx;
|
||
font-weight: 700;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.tappable {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.footer-tip {
|
||
margin-top: 18rpx;
|
||
padding: 0 8rpx;
|
||
color: #9aa4b4;
|
||
font-size: 18rpx;
|
||
line-height: 1.45;
|
||
text-align: center;
|
||
}
|
||
|
||
.theme-dark {
|
||
background: #151923;
|
||
}
|
||
|
||
.theme-dark .settings-card {
|
||
background: #222936;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.theme-dark .card-title,
|
||
.theme-dark .setting-desc,
|
||
.theme-dark .footer-tip {
|
||
color: #aeb9ca;
|
||
}
|
||
|
||
.theme-dark .card-subtitle {
|
||
color: #718096;
|
||
}
|
||
|
||
.theme-dark .setting-label {
|
||
color: #f2f5fa;
|
||
}
|
||
|
||
.theme-dark .setting-value {
|
||
color: #c6d0df;
|
||
}
|
||
|
||
.theme-dark .setting-row,
|
||
.theme-dark .action-list .setting-row {
|
||
border-bottom-color: #343e4d;
|
||
}
|
||
.theme-dark.settings-page {
|
||
background: #151923;
|
||
}
|
||
|
||
.theme-dark .settings-card {
|
||
border-color: #364152;
|
||
background: #222936;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.theme-dark .card-title,
|
||
.theme-dark .setting-label {
|
||
color: #f2f5fa;
|
||
}
|
||
|
||
.theme-dark .card-subtitle,
|
||
.theme-dark .setting-desc,
|
||
.theme-dark .footer-tip {
|
||
color: #aeb9ca;
|
||
}
|
||
|
||
.theme-dark .setting-value {
|
||
color: #d7deea;
|
||
}
|
||
|
||
.theme-dark .setting-row,
|
||
.theme-dark .action-list .setting-row {
|
||
border-color: #364152;
|
||
}
|
||
</style>
|