From ce796e2fd70697902dd1ae3cbcc2135e205d1d48 Mon Sep 17 00:00:00 2001 From: yinsx Date: Fri, 23 Jan 2026 16:56:28 +0800 Subject: [PATCH] 1 --- app/src/components/GridCanvas/index.vue | 19 ++++++-- app/src/components/IconCard/index.vue | 37 +++++++++++---- app/src/components/TheContextMenu/index.vue | 23 ++++++++- app/src/components/WidgetCard/index.vue | 52 +++++++++++++++------ app/src/config/theme.ts | 2 +- app/src/store/useLayoutStore.ts | 24 +++++++++- app/src/styles/global.scss | 6 ++- 7 files changed, 131 insertions(+), 32 deletions(-) diff --git a/app/src/components/GridCanvas/index.vue b/app/src/components/GridCanvas/index.vue index 58d97c4..9fc0465 100644 --- a/app/src/components/GridCanvas/index.vue +++ b/app/src/components/GridCanvas/index.vue @@ -8,6 +8,7 @@ import IconCard from '@/components/IconCard/index.vue'; import WidgetCard from '@/components/WidgetCard/index.vue'; type GridItemType = 'icon' | 'widget'; +type GridItemSize = '1x1' | '1x2' | '2x1' | '2x2' | '2x4'; interface Icon { id: string; @@ -15,9 +16,10 @@ interface Icon { url: string; img?: string; bgColor?: string; + size?: GridItemSize; } -type WidgetSize = '1x1' | '1x2' | '2x1' | '2x2' | '2x4'; +type WidgetSize = GridItemSize; interface Widget { id: string; component: string; @@ -217,7 +219,7 @@ onMounted(async () => { dragEnabled: true, dragStartPredicate: { distance: 5, - delay: 150, + delay: 0, }, dragSort: true, layout: { @@ -255,8 +257,15 @@ watch( watch( () => widgetsStore.widgets.map(widget => widget.size).join('|'), - () => { - refreshLayout(); + async () => { + await refreshLayout(); + } +); + +watch( + () => layoutStore.icons.map(icon => icon.size ?? '1x1').join('|'), + async () => { + await refreshLayout(); } ); @@ -277,7 +286,7 @@ onUnmounted(() => { v-for="item in orderedItems" :key="`${item.type}-${item.id}`" class="grid-item" - :class="item.type === 'widget' ? `size-${item.widget.size}` : 'size-1x1'" + :class="`size-${item.type === 'widget' ? item.widget.size : (item.icon.size ?? '1x1')}`" :data-id="item.id" :data-type="item.type" > diff --git a/app/src/components/IconCard/index.vue b/app/src/components/IconCard/index.vue index ad7a6fa..87fa552 100644 --- a/app/src/components/IconCard/index.vue +++ b/app/src/components/IconCard/index.vue @@ -2,6 +2,7 @@ @@ -14,10 +15,13 @@ diff --git a/app/src/config/theme.ts b/app/src/config/theme.ts index 192cf06..c576894 100644 --- a/app/src/config/theme.ts +++ b/app/src/config/theme.ts @@ -2,7 +2,7 @@ export const themeConfig = { // 圆角配置,统一控制卡片与胶囊样式。 radius: { // 小圆角(像素)。 - sm: 8, + sm: 12, // 中圆角(像素)。 md: 16, // 大圆角(像素)。 diff --git a/app/src/store/useLayoutStore.ts b/app/src/store/useLayoutStore.ts index 82a5861..2d44154 100644 --- a/app/src/store/useLayoutStore.ts +++ b/app/src/store/useLayoutStore.ts @@ -1,10 +1,13 @@ import { defineStore } from 'pinia'; +type IconSize = '1x1' | '1x2' | '2x1' | '2x2' | '2x4'; + // 模拟数据(来自截图参考) interface Icon { id: string; name: string; url: string; + size?: IconSize; img?: string; // 可选:用于图片图标(如徽标) bgColor?: string; // 可选:纯色背景 } @@ -45,9 +48,21 @@ const defaultIcons: Icon[] = [ const savedIcons = localStorage.getItem('itab_icons'); +const normalizeIcons = (icons: Icon[]): Icon[] => + icons.map(icon => ({ ...icon, size: icon.size ?? '1x1' })); + +const loadIcons = (): Icon[] => { + if (!savedIcons) return normalizeIcons(defaultIcons); + try { + return normalizeIcons(JSON.parse(savedIcons) as Icon[]); + } catch { + return normalizeIcons(defaultIcons); + } +}; + export const useLayoutStore = defineStore('layout', { state: (): LayoutState => ({ - icons: savedIcons ? JSON.parse(savedIcons) : defaultIcons, + icons: loadIcons(), dragState: { isDragging: false, itemId: null, @@ -91,6 +106,13 @@ export const useLayoutStore = defineStore('layout', { this.icons = ordered; localStorage.setItem('itab_icons', JSON.stringify(this.icons)); }, + updateIconSize(iconId: string, newSize: IconSize) { + const icon = this.icons.find(item => item.id === iconId); + if (icon) { + icon.size = newSize; + localStorage.setItem('itab_icons', JSON.stringify(this.icons)); + } + }, deleteIcon(itemId: string) { const index = this.icons.findIndex(p => p.id === itemId); if (index !== -1) { diff --git a/app/src/styles/global.scss b/app/src/styles/global.scss index d249e56..f17d364 100644 --- a/app/src/styles/global.scss +++ b/app/src/styles/global.scss @@ -26,7 +26,11 @@ body { #app { width: 100%; height: 100%; - background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%); + background-color: $color-background; + background-image: url('/bg.png'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; } // 滚动条样式