|
1 | 1 | <template> |
2 | | - <div id="app" :class="{ 'sidebar-collapsed': sidebarCollapsed }"> |
| 2 | + <div |
| 3 | + id="app" |
| 4 | + :class="{ 'sidebar-collapsed': sidebarCollapsed }" |
| 5 | + > |
3 | 6 | <!-- 侧边栏 Sidebar --> |
4 | | - <aside class="layout-sidebar" :class="{ collapsed: sidebarCollapsed }"> |
| 7 | + <aside |
| 8 | + class="layout-sidebar" |
| 9 | + :class="{ collapsed: sidebarCollapsed }" |
| 10 | + > |
5 | 11 | <div class="logo-area"> |
6 | | - <img src="/logo-banner.png" alt="渲染AI" class="logo-icon" /> |
| 12 | + <img |
| 13 | + src="/logo-banner.png" |
| 14 | + alt="渲染AI" |
| 15 | + class="logo-icon" |
| 16 | + /> |
7 | 17 | </div> |
8 | 18 |
|
9 | 19 | <nav class="nav-menu"> |
10 | | - <RouterLink to="/" class="nav-item" active-class="active" exact> |
11 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg> |
| 20 | + <RouterLink |
| 21 | + to="/" |
| 22 | + class="nav-item" |
| 23 | + active-class="active" |
| 24 | + exact |
| 25 | + > |
| 26 | + <svg |
| 27 | + width="20" |
| 28 | + height="20" |
| 29 | + viewBox="0 0 24 24" |
| 30 | + fill="none" |
| 31 | + stroke="currentColor" |
| 32 | + stroke-width="2" |
| 33 | + stroke-linecap="round" |
| 34 | + stroke-linejoin="round" |
| 35 | + > |
| 36 | + <path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path> |
| 37 | + <polyline points="9 22 9 12 15 12 15 22"></polyline> |
| 38 | + </svg> |
12 | 39 | <span class="nav-text">首页</span> |
13 | 40 | </RouterLink> |
14 | | - <RouterLink to="/redbook" class="nav-item" active-class="active"> |
15 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg> |
| 41 | + <RouterLink |
| 42 | + to="/redbook" |
| 43 | + class="nav-item" |
| 44 | + active-class="active" |
| 45 | + > |
| 46 | + <svg |
| 47 | + width="20" |
| 48 | + height="20" |
| 49 | + viewBox="0 0 24 24" |
| 50 | + fill="none" |
| 51 | + stroke="currentColor" |
| 52 | + stroke-width="2" |
| 53 | + stroke-linecap="round" |
| 54 | + stroke-linejoin="round" |
| 55 | + > |
| 56 | + <rect |
| 57 | + x="3" |
| 58 | + y="3" |
| 59 | + width="18" |
| 60 | + height="18" |
| 61 | + rx="2" |
| 62 | + ry="2" |
| 63 | + ></rect> |
| 64 | + <circle |
| 65 | + cx="8.5" |
| 66 | + cy="8.5" |
| 67 | + r="1.5" |
| 68 | + ></circle> |
| 69 | + <polyline points="21 15 16 10 5 21"></polyline> |
| 70 | + </svg> |
16 | 71 | <span class="nav-text">小红书图文</span> |
17 | 72 | </RouterLink> |
18 | | - <RouterLink to="/templates" class="nav-item" active-class="active"> |
19 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 7h-9"></path><path d="M14 17H5"></path><circle cx="17" cy="17" r="3"></circle><circle cx="7" cy="7" r="3"></circle></svg> |
| 73 | + <RouterLink |
| 74 | + to="/templates" |
| 75 | + class="nav-item" |
| 76 | + active-class="active" |
| 77 | + > |
| 78 | + <svg |
| 79 | + width="20" |
| 80 | + height="20" |
| 81 | + viewBox="0 0 24 24" |
| 82 | + fill="none" |
| 83 | + stroke="currentColor" |
| 84 | + stroke-width="2" |
| 85 | + stroke-linecap="round" |
| 86 | + stroke-linejoin="round" |
| 87 | + > |
| 88 | + <path d="M20 7h-9"></path> |
| 89 | + <path d="M14 17H5"></path> |
| 90 | + <circle |
| 91 | + cx="17" |
| 92 | + cy="17" |
| 93 | + r="3" |
| 94 | + ></circle> |
| 95 | + <circle |
| 96 | + cx="7" |
| 97 | + cy="7" |
| 98 | + r="3" |
| 99 | + ></circle> |
| 100 | + </svg> |
20 | 101 | <span class="nav-text">模板市集</span> |
21 | 102 | </RouterLink> |
22 | | - <RouterLink to="/concept" class="nav-item" active-class="active"> |
23 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><circle cx="4" cy="6" r="2"></circle><circle cx="20" cy="6" r="2"></circle><line x1="6" y1="6" x2="9.5" y2="10"></line><line x1="18" y1="6" x2="14.5" y2="10"></line></svg> |
| 103 | + <RouterLink |
| 104 | + to="/concept" |
| 105 | + class="nav-item" |
| 106 | + active-class="active" |
| 107 | + > |
| 108 | + <svg |
| 109 | + width="20" |
| 110 | + height="20" |
| 111 | + viewBox="0 0 24 24" |
| 112 | + fill="none" |
| 113 | + stroke="currentColor" |
| 114 | + stroke-width="2" |
| 115 | + stroke-linecap="round" |
| 116 | + stroke-linejoin="round" |
| 117 | + > |
| 118 | + <circle |
| 119 | + cx="12" |
| 120 | + cy="12" |
| 121 | + r="3" |
| 122 | + ></circle> |
| 123 | + <circle |
| 124 | + cx="4" |
| 125 | + cy="6" |
| 126 | + r="2" |
| 127 | + ></circle> |
| 128 | + <circle |
| 129 | + cx="20" |
| 130 | + cy="6" |
| 131 | + r="2" |
| 132 | + ></circle> |
| 133 | + <line |
| 134 | + x1="6" |
| 135 | + y1="6" |
| 136 | + x2="9.5" |
| 137 | + y2="10" |
| 138 | + ></line> |
| 139 | + <line |
| 140 | + x1="18" |
| 141 | + y1="6" |
| 142 | + x2="14.5" |
| 143 | + y2="10" |
| 144 | + ></line> |
| 145 | + </svg> |
24 | 146 | <span class="nav-text">概念可视化</span> |
25 | 147 | </RouterLink> |
26 | 148 | <div class="nav-divider"></div> |
27 | | - <RouterLink to="/history" class="nav-item" active-class="active"> |
28 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line></svg> |
| 149 | + <RouterLink |
| 150 | + to="/history" |
| 151 | + class="nav-item" |
| 152 | + active-class="active" |
| 153 | + > |
| 154 | + <svg |
| 155 | + width="20" |
| 156 | + height="20" |
| 157 | + viewBox="0 0 24 24" |
| 158 | + fill="none" |
| 159 | + stroke="currentColor" |
| 160 | + stroke-width="2" |
| 161 | + stroke-linecap="round" |
| 162 | + stroke-linejoin="round" |
| 163 | + > |
| 164 | + <path |
| 165 | + d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" |
| 166 | + ></path> |
| 167 | + <polyline points="14 2 14 8 20 8"></polyline> |
| 168 | + <line |
| 169 | + x1="16" |
| 170 | + y1="13" |
| 171 | + x2="8" |
| 172 | + y2="13" |
| 173 | + ></line> |
| 174 | + <line |
| 175 | + x1="16" |
| 176 | + y1="17" |
| 177 | + x2="8" |
| 178 | + y2="17" |
| 179 | + ></line> |
| 180 | + </svg> |
29 | 181 | <span class="nav-text">历史记录</span> |
30 | 182 | </RouterLink> |
31 | | - <RouterLink to="/knowledge" class="nav-item" active-class="active"> |
32 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg> |
| 183 | + <RouterLink |
| 184 | + to="/knowledge" |
| 185 | + class="nav-item" |
| 186 | + active-class="active" |
| 187 | + > |
| 188 | + <svg |
| 189 | + width="20" |
| 190 | + height="20" |
| 191 | + viewBox="0 0 24 24" |
| 192 | + fill="none" |
| 193 | + stroke="currentColor" |
| 194 | + stroke-width="2" |
| 195 | + stroke-linecap="round" |
| 196 | + stroke-linejoin="round" |
| 197 | + > |
| 198 | + <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path> |
| 199 | + <path |
| 200 | + d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" |
| 201 | + ></path> |
| 202 | + </svg> |
33 | 203 | <span class="nav-text">知识库</span> |
34 | 204 | </RouterLink> |
35 | | - <RouterLink to="/settings" class="nav-item" active-class="active"> |
36 | | - <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg> |
| 205 | + <RouterLink |
| 206 | + to="/settings" |
| 207 | + class="nav-item" |
| 208 | + active-class="active" |
| 209 | + > |
| 210 | + <svg |
| 211 | + width="20" |
| 212 | + height="20" |
| 213 | + viewBox="0 0 24 24" |
| 214 | + fill="none" |
| 215 | + stroke="currentColor" |
| 216 | + stroke-width="2" |
| 217 | + stroke-linecap="round" |
| 218 | + stroke-linejoin="round" |
| 219 | + > |
| 220 | + <circle |
| 221 | + cx="12" |
| 222 | + cy="12" |
| 223 | + r="3" |
| 224 | + ></circle> |
| 225 | + <path |
| 226 | + d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" |
| 227 | + ></path> |
| 228 | + </svg> |
37 | 229 | <span class="nav-text">系统设置</span> |
38 | 230 | </RouterLink> |
39 | 231 | </nav> |
40 | 232 |
|
41 | 233 | <!-- 折叠按钮 --> |
42 | | - <button class="collapse-btn" @click="toggleSidebar" :title="sidebarCollapsed ? '展开侧边栏' : '收起侧边栏'"> |
43 | | - <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
44 | | - <polyline v-if="sidebarCollapsed" points="9 18 15 12 9 6"></polyline> |
45 | | - <polyline v-else points="15 18 9 12 15 6"></polyline> |
| 234 | + <button |
| 235 | + class="collapse-btn" |
| 236 | + @click="toggleSidebar" |
| 237 | + :title="sidebarCollapsed ? '展开侧边栏' : '收起侧边栏'" |
| 238 | + > |
| 239 | + <svg |
| 240 | + width="16" |
| 241 | + height="16" |
| 242 | + viewBox="0 0 24 24" |
| 243 | + fill="none" |
| 244 | + stroke="currentColor" |
| 245 | + stroke-width="2" |
| 246 | + stroke-linecap="round" |
| 247 | + stroke-linejoin="round" |
| 248 | + > |
| 249 | + <polyline |
| 250 | + v-if="sidebarCollapsed" |
| 251 | + points="9 18 15 12 9 6" |
| 252 | + ></polyline> |
| 253 | + <polyline |
| 254 | + v-else |
| 255 | + points="15 18 9 12 15 6" |
| 256 | + ></polyline> |
46 | 257 | </svg> |
47 | 258 | </button> |
48 | 259 |
|
49 | 260 | <div class="sidebar-footer"> |
50 | 261 | <div class="brand-badge"> |
51 | 262 | <div class="brand-icon">R</div> |
52 | | - <div class="brand-info" v-show="!sidebarCollapsed"> |
| 263 | + <div |
| 264 | + class="brand-info" |
| 265 | + v-show="!sidebarCollapsed" |
| 266 | + > |
53 | 267 | <div class="brand-name">渲染AI</div> |
54 | 268 | <div class="brand-sub">RenderAI</div> |
55 | 269 | </div> |
|
63 | 277 | <component :is="Component" /> |
64 | 278 |
|
65 | 279 | <!-- 全局页脚版权信息(首页除外) --> |
66 | | - <footer v-if="route.path !== '/'" class="global-footer"> |
| 280 | + <footer |
| 281 | + v-if="route.path !== '/'" |
| 282 | + class="global-footer" |
| 283 | + > |
67 | 284 | <div class="footer-content"> |
68 | | - <div class="footer-tip"> |
69 | | - 渲染AI - AI驱动的图文创作工具 |
70 | | - </div> |
71 | | - <div class="footer-text"> |
72 | | - © 2025 渲染AI (RenderAI) |
73 | | - </div> |
| 285 | + <div class="footer-tip">渲染AI - AI驱动的图文创作工具</div> |
| 286 | + <div class="footer-text">© 2025 渲染AI (RenderAI)</div> |
74 | 287 | <div class="footer-license"> |
75 | | - Licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noopener noreferrer">CC BY-NC-SA 4.0</a> |
| 288 | + Licensed under |
| 289 | + <a |
| 290 | + href="https://creativecommons.org/licenses/by-nc-sa/4.0/" |
| 291 | + target="_blank" |
| 292 | + rel="noopener noreferrer" |
| 293 | + >CC BY-NC-SA 4.0</a |
| 294 | + > |
76 | 295 | </div> |
77 | 296 | </div> |
78 | 297 | </footer> |
|
82 | 301 | </template> |
83 | 302 |
|
84 | 303 | <script setup lang="ts"> |
85 | | -import { RouterView, RouterLink } from 'vue-router' |
86 | | -import { ref, onMounted } from 'vue' |
87 | | -import { setupAutoSave } from './stores/generator' |
| 304 | +import { RouterView, RouterLink } from "vue-router"; |
| 305 | +import { ref, onMounted } from "vue"; |
| 306 | +import { setupAutoSave } from "./stores/generator"; |
| 307 | +import { useTheme } from "./composables/useTheme"; |
88 | 308 |
|
89 | 309 | // 侧边栏折叠状态 |
90 | | -const sidebarCollapsed = ref(false) |
| 310 | +const sidebarCollapsed = ref(false); |
91 | 311 |
|
92 | 312 | // 切换侧边栏折叠状态 |
93 | 313 | const toggleSidebar = () => { |
94 | | - sidebarCollapsed.value = !sidebarCollapsed.value |
| 314 | + sidebarCollapsed.value = !sidebarCollapsed.value; |
95 | 315 | // 保存状态到 localStorage |
96 | | - localStorage.setItem('sidebarCollapsed', String(sidebarCollapsed.value)) |
97 | | -} |
| 316 | + localStorage.setItem("sidebarCollapsed", String(sidebarCollapsed.value)); |
| 317 | +}; |
98 | 318 |
|
99 | 319 | // 启用自动保存到 localStorage |
100 | 320 | onMounted(() => { |
101 | | - setupAutoSave() |
| 321 | + setupAutoSave(); |
| 322 | + // 初始化主题 |
| 323 | + useTheme(); |
102 | 324 | // 恢复侧边栏状态 |
103 | | - const saved = localStorage.getItem('sidebarCollapsed') |
104 | | - if (saved === 'true') { |
105 | | - sidebarCollapsed.value = true |
| 325 | + const saved = localStorage.getItem("sidebarCollapsed"); |
| 326 | + if (saved === "true") { |
| 327 | + sidebarCollapsed.value = true; |
106 | 328 | } |
107 | | -}) |
| 329 | +}); |
108 | 330 | </script> |
0 commit comments