From cce281497b4037da3bcc62a8938b3e4124e5184e Mon Sep 17 00:00:00 2001 From: zhangzijienbplus <17738440858@163.com> Date: Mon, 10 Nov 2025 15:18:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(client):=20=E6=B7=BB=E5=8A=A0=E5=93=81?= =?UTF-8?q?=E7=89=8Clogo=E5=8A=9F=E8=83=BD=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在客户端账户实体中新增brandLogo字段用于存储品牌logo URL - 实现品牌logo的上传、获取和删除接口 - 在Vue前端中集成品牌logo的展示和管理功能- 添加品牌logo的缓存机制提升访问性能 - 在设置对话框中增加品牌logo配置界面 - 实现品牌logo的预览、上传和删除操作 - 添加VIP权限控制确保只有VIP用户可使用该功能 - 增加品牌logo变更事件监听以实时更新界面显示- 更新数据库映射文件以支持brand_logo字段的读写- 在登录成功后异步加载品牌logo配置信息- 调整UI布局以适配品牌logo展示区域- 添加品牌logo相关的样式定义和响应式处理 - 实现品牌logo上传的文件类型和大小校验- 增加品牌logo删除确认提示增强用户体验 - 在App.vue中添加品牌logo的全局状态管理和展示逻辑- 优化品牌logo加载失败时的容错处理 - 完善品牌logo功能的相关错误处理和日志记录 --- electron-vue-template/img.png | Bin 0 -> 49117 bytes .../public/icon/vipExclusive.png | Bin 0 -> 2246 bytes electron-vue-template/src/renderer/App.vue | 168 +++++++--- .../src/renderer/api/splash.ts | 18 + .../renderer/components/auth/LoginDialog.vue | 19 +- .../components/common/SettingsDialog.vue | 312 +++++++++++++----- .../monitor/ClientAccountController.java | 70 +++- .../ruoyi/system/domain/ClientAccount.java | 13 + .../mapper/system/ClientAccountMapper.xml | 6 +- 9 files changed, 485 insertions(+), 121 deletions(-) create mode 100644 electron-vue-template/img.png create mode 100644 electron-vue-template/public/icon/vipExclusive.png diff --git a/electron-vue-template/img.png b/electron-vue-template/img.png new file mode 100644 index 0000000000000000000000000000000000000000..4ed51e3c191e23b1d362fb8bb8f1e795d3ca3da4 GIT binary patch literal 49117 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 UIVuvEHvj+t07*qoM6N<$f``^SfdBvi literal 0 HcmV?d00001 diff --git a/electron-vue-template/src/renderer/App.vue b/electron-vue-template/src/renderer/App.vue index 3675586..fb548f8 100644 --- a/electron-vue-template/src/renderer/App.vue +++ b/electron-vue-template/src/renderer/App.vue @@ -5,6 +5,7 @@ import zhCn from 'element-plus/es/locale/lang/zh-cn' import 'element-plus/dist/index.css' import {authApi} from './api/auth' import {deviceApi, type DeviceItem, type DeviceQuota} from './api/device' +import {splashApi} from './api/splash' import {getOrCreateDeviceId} from './utils/deviceId' import {getToken, setToken, removeToken, getUsernameFromToken, getClientIdFromToken} from './utils/token' import {CONFIG} from './api/http' @@ -61,12 +62,12 @@ const vipExpireTime = ref(null) const deviceTrialExpired = ref(false) const accountType = ref('trial') const vipStatus = computed(() => { - if (!vipExpireTime.value) return { isVip: false, daysLeft: 0, hoursLeft: 0, status: 'expired', expiredType: 'account' } - + if (!vipExpireTime.value) return {isVip: false, daysLeft: 0, hoursLeft: 0, status: 'expired', expiredType: 'account'} + const now = new Date() const expire = new Date(vipExpireTime.value) const msLeft = expire.getTime() - now.getTime() - + // 精确判断:当前时间 >= 过期时间,则已过期(与后端逻辑一致) if (msLeft <= 0) { const accountExpired = true @@ -75,22 +76,22 @@ const vipStatus = computed(() => { if (deviceExpired && accountExpired) expiredType = 'both' else if (accountExpired) expiredType = 'account' else if (deviceExpired) expiredType = 'device' - - return { isVip: false, daysLeft: 0, hoursLeft: 0, status: 'expired', expiredType } + + return {isVip: false, daysLeft: 0, hoursLeft: 0, status: 'expired', expiredType} } - + const hoursLeft = Math.floor(msLeft / (1000 * 60 * 60)) const daysLeft = Math.floor(msLeft / (1000 * 60 * 60 * 24)) - + let expiredType: 'device' | 'account' | 'both' | 'subscribe' = 'subscribe' if (accountType.value === 'trial' && deviceTrialExpired.value) { expiredType = 'device' // 试用账号且设备过期 } - - if (daysLeft === 0) return { isVip: true, daysLeft, hoursLeft, status: 'warning', expiredType } - if (daysLeft <= 7) return { isVip: true, daysLeft, hoursLeft, status: 'warning', expiredType } - if (daysLeft <= 30) return { isVip: true, daysLeft, hoursLeft, status: 'normal', expiredType } - return { isVip: true, daysLeft, hoursLeft, status: 'active', expiredType } + + if (daysLeft === 0) return {isVip: true, daysLeft, hoursLeft, status: 'warning', expiredType} + if (daysLeft <= 7) return {isVip: true, daysLeft, hoursLeft, status: 'warning', expiredType} + if (daysLeft <= 30) return {isVip: true, daysLeft, hoursLeft, status: 'normal', expiredType} + return {isVip: true, daysLeft, hoursLeft, status: 'active', expiredType} }) // 功能可用性(账号VIP + 设备试用期) @@ -118,6 +119,9 @@ const showAccountManager = ref(false) // 当前版本 const currentVersion = ref('') +// 品牌logo +const brandLogoUrl = ref('') + // 菜单配置 - 复刻ERP客户端格式 const menuConfig = [ {key: 'rakuten', name: 'Rakuten', index: 'rakuten', icon: 'R', iconImage: rakutenIcon}, @@ -198,19 +202,25 @@ function handleMenuSelect(key: string) { addToHistory(key) } -async function handleLoginSuccess(data: { token: string; permissions?: string; expireTime?: string; accountType?: string; deviceTrialExpired?: boolean }) { +async function handleLoginSuccess(data: { + token: string; + permissions?: string; + expireTime?: string; + accountType?: string; + deviceTrialExpired?: boolean +}) { try { setToken(data.token) isAuthenticated.value = true showAuthDialog.value = false showRegDialog.value = false - + currentUsername.value = getUsernameFromToken(data.token) userPermissions.value = data.permissions || '' vipExpireTime.value = data.expireTime ? new Date(data.expireTime) : null accountType.value = data.accountType || 'trial' deviceTrialExpired.value = data.deviceTrialExpired || false - + const deviceId = await getOrCreateDeviceId() await deviceApi.register({ username: currentUsername.value, @@ -218,7 +228,7 @@ async function handleLoginSuccess(data: { token: string; permissions?: string; e os: navigator.platform }) SSEManager.connect() - + // 同步当前账号的设置到 Electron 主进程 syncSettingsToElectron() @@ -231,7 +241,7 @@ async function handleLoginSuccess(data: { token: string; permissions?: string; e isAuthenticated.value = false showAuthDialog.value = true removeToken() - + } } @@ -251,7 +261,7 @@ function clearLocalAuth() { async function logout() { try { const deviceId = getClientIdFromToken() - if (deviceId) await deviceApi.offline({ deviceId, username: currentUsername.value }) + if (deviceId) await deviceApi.offline({deviceId, username: currentUsername.value}) } catch (error) { console.warn('离线通知失败:', error) } @@ -270,7 +280,8 @@ async function handleUserClick() { cancelButtonText: '取消' }) await logout() - } catch {} + } catch { + } } function showRegisterDialog() { @@ -280,7 +291,7 @@ function showRegisterDialog() { function backToLogin() { showRegDialog.value = false - + showAuthDialog.value = true } @@ -300,13 +311,13 @@ async function checkAuth() { userPermissions.value = res.data.permissions || '' deviceTrialExpired.value = res.data.deviceTrialExpired || false accountType.value = res.data.accountType || 'trial' - + if (res.data.expireTime) { vipExpireTime.value = new Date(res.data.expireTime) } - + SSEManager.connect() - + // 同步当前账号的设置到 Electron 主进程 syncSettingsToElectron() } catch { @@ -322,7 +333,7 @@ async function refreshVipStatus() { try { const token = getToken() if (!token) return false - + const res = await authApi.verifyToken(token) deviceTrialExpired.value = res.data.deviceTrialExpired || false accountType.value = res.data.accountType || 'trial' @@ -346,10 +357,10 @@ async function syncSettingsToElectron() { try { const username = getUsernameFromToken() const settings = getSettings(username) - + // 同步关闭行为 await (window as any).electronAPI.setCloseAction(settings.closeAction || 'quit') - + // 同步启动配置 await (window as any).electronAPI.setLaunchConfig({ autoLaunch: settings.autoLaunch || false, @@ -360,6 +371,19 @@ async function syncSettingsToElectron() { } } +// 加载品牌logo +async function loadBrandLogo() { + try { + const username = getUsernameFromToken() + if (!username) return + + const res = await splashApi.getBrandLogo(username) + brandLogoUrl.value = res.data.url + } catch (error) { + brandLogoUrl.value = '' + } +} + // 提供给子组件使用 provide('refreshVipStatus', refreshVipStatus) provide('vipStatus', vipStatus) @@ -518,24 +542,32 @@ async function confirmRemoveDevice(row: DeviceItem) { onMounted(async () => { showContent() await checkAuth() - + // 检查是否有待安装的更新 await checkPendingUpdate() - + // 加载当前版本 try { currentVersion.value = await (window as any).electronAPI.getJarVersion() } catch (error) { console.warn('获取当前版本失败:', error) } - + + // 加载品牌logo + loadBrandLogo() + + // 监听品牌logo变化 + window.addEventListener('brandLogoChanged', (e: any) => { + brandLogoUrl.value = e.detail + }) + // 全局阻止文件拖拽到窗口(避免意外打开文件) // 只在指定的 dropzone 区域处理拖拽上传 document.addEventListener('dragover', (e) => { e.preventDefault() e.stopPropagation() }, false) - + document.addEventListener('drop', (e) => { e.preventDefault() e.stopPropagation() @@ -584,6 +616,12 @@ onUnmounted(() => {

logo
+ + +
+ +
+ -
+
- 有效期至:{{ new Date(vipExpireTime).toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' }) }} + 有效期至:{{ + new Date(vipExpireTime).toLocaleDateString('zh-CN', { + year: 'numeric', + month: 'long', + day: 'numeric' + }) + }}
@@ -672,16 +717,20 @@ onUnmounted(() => { @back-to-login="backToLogin"/> - + - + - + - + { @@ -829,6 +880,24 @@ onUnmounted(() => { text-align: left; } +/* 品牌logo区域 */ +.brand-logo-section { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 48px; + margin-bottom: 12px; + padding: 0 4px; + box-sizing: border-box; +} + +.brand-logo { + max-width: 100%; + max-height: 100%; + object-fit: contain; +} + .menu { list-style: none; padding: 0; @@ -952,6 +1021,7 @@ onUnmounted(() => { font-size: 13px; color: #606266; } + .device-dialog-header { display: flex; flex-direction: column; @@ -959,31 +1029,45 @@ onUnmounted(() => { padding: 12px 0 4px 0; margin-left: 40px; } + .device-dialog :deep(.el-dialog__header) { text-align: center; } -.device-dialog :deep(.el-dialog__body) { padding-top: 0; } + +.device-dialog :deep(.el-dialog__body) { + padding-top: 0; +} + .device-illustration { width: 180px; height: auto; object-fit: contain; margin-bottom: 8px; } + .device-title { font-size: 18px; font-weight: 600; color: #303133; margin-bottom: 6px; } -.device-count { color: #909399; font-weight: 500; } -.device-subtitle { font-size: 12px; color: #909399; } + +.device-count { + color: #909399; + font-weight: 500; +} + +.device-subtitle { + font-size: 12px; + color: #909399; +} /* 浮动版本信息 */ .version-info { position: fixed; right: 10px; bottom: 10px; - background: rgba(255,255,255,0.9); + background: rgba(255, 255, 255, 0.9); padding: 5px 10px; border-radius: 4px; font-size: 12px; diff --git a/electron-vue-template/src/renderer/api/splash.ts b/electron-vue-template/src/renderer/api/splash.ts index 13ff308..6acfec2 100644 --- a/electron-vue-template/src/renderer/api/splash.ts +++ b/electron-vue-template/src/renderer/api/splash.ts @@ -27,6 +27,24 @@ export const splashApi = { // 删除自定义开屏图片(恢复默认) async deleteSplashImage(username: string) { return http.post<{ data: string }>(`/monitor/account/splash-image/delete?username=${username}`) + }, + + // 上传品牌logo + async uploadBrandLogo(file: File, username: string) { + const formData = new FormData() + formData.append('file', file) + formData.append('username', username) + return http.upload<{ data: { url: string; fileName: string } }>('/monitor/account/brand-logo/upload', formData) + }, + + // 获取当前用户的品牌logo + async getBrandLogo(username: string) { + return http.get<{ data: { url: string } }>('/monitor/account/brand-logo', { username }) + }, + + // 删除品牌logo + async deleteBrandLogo(username: string) { + return http.post<{ data: string }>(`/monitor/account/brand-logo/delete?username=${username}`) } } diff --git a/electron-vue-template/src/renderer/components/auth/LoginDialog.vue b/electron-vue-template/src/renderer/components/auth/LoginDialog.vue index 02b9a33..7ec5f07 100644 --- a/electron-vue-template/src/renderer/components/auth/LoginDialog.vue +++ b/electron-vue-template/src/renderer/components/auth/LoginDialog.vue @@ -35,16 +35,17 @@ async function handleAuth() { try { // 获取或生成设备ID const deviceId = await getOrCreateDeviceId() - + // 登录 const loginRes: any = await authApi.login({ ...authForm.value, clientId: deviceId }) - // 保存开屏图片配置(不阻塞登录) + // 保存开屏图片配置和品牌logo(不阻塞登录) saveSplashConfigInBackground(authForm.value.username) - + saveBrandLogoInBackground(authForm.value.username) + emit('loginSuccess', { token: loginRes.data.accessToken || loginRes.data.token, permissions: loginRes.data.permissions, @@ -90,6 +91,18 @@ async function saveSplashConfigInBackground(username: string) { console.error('[开屏图片] 保存配置失败:', error) } } + +// 保存品牌logo配置 +async function saveBrandLogoInBackground(username: string) { + try { + const res = await splashApi.getBrandLogo(username) + const url = res?.data?.url || '' + // 触发App.vue加载品牌logo + window.dispatchEvent(new CustomEvent('brandLogoChanged', { detail: url })) + } catch (error) { + console.error('[品牌logo] 加载配置失败:', error) + } +} @@ -940,9 +1066,21 @@ onMounted(() => { font-weight: 600; color: #1F2937; text-align: left; +} + +.section-title-row { + display: flex; + align-items: center; + gap: 8px; margin-bottom: 8px; } +.vip-exclusive-logo { + width: 60px; + height: auto; + vertical-align: middle; +} + .section-header .section-title { margin-bottom: 0; } @@ -1100,6 +1238,53 @@ onMounted(() => { margin-top: 8px; } +/* 图片预览容器 */ +.image-preview-wrapper { + position: relative; + width: 75%; +} + +.preview-image { + width: 100%; + height: 100%; + object-fit: contain; +} + +.image-buttons { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: flex; + gap: 8px; + opacity: 0; + transition: opacity 0.2s ease; +} + +.image-preview-wrapper:hover .image-buttons { + opacity: 1; +} + +.img-btn { + padding: 6px 14px; + background: rgba(0, 0, 0, 0.6); + border: none; + border-radius: 4px; + color: #fff; + font-size: 12px; + cursor: pointer; + transition: background 0.2s ease; +} + +.img-btn:hover:not(:disabled) { + background: rgba(0, 0, 0, 0.8); +} + +.img-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + .feedback-form :deep(.el-textarea__inner) { border-color: #E5E6EB; border-radius: 6px; @@ -1312,22 +1497,7 @@ onMounted(() => { color: #1F2937; } -/* 开屏图片样式 */ -.splash-preview-container { - width: 100%; - height: 180px; - border-radius: 6px; - overflow: hidden; - border: 1px solid #E5E6EB; - background: #F8F9FA; -} - -.splash-preview-image { - width: 100%; - height: 100%; - object-fit: contain; -} - +/* 占位符 */ .splash-placeholder { width: 100%; height: 180px; @@ -1350,12 +1520,6 @@ onMounted(() => { font-size: 13px; color: #86909C; } - -.splash-actions { - display: flex; - align-items: center; - gap: 8px; -}