Compare commits
No commits in common. "6faaa7984bbac901f7214132b899c4554a54c31b" and "bacbe1871c9b5df04a3fa1ad9db6068cd2a25501" have entirely different histories.
6faaa7984b
...
bacbe1871c
112
.qoder/repowiki/knowledge/zh/_index.yaml
Normal file
@ -0,0 +1,112 @@
|
||||
# 知识卡导出索引文件
|
||||
schema_version: 1
|
||||
locale: zh-CN
|
||||
branch: Q0DeR-MaG1C-BrAnCh-Fo2-NoN-GiT-Or-No-C0MmIt
|
||||
exported_at: "2026-06-12T08:09:05Z"
|
||||
modules:
|
||||
"":
|
||||
dir_name: 网盘管理跨端应用
|
||||
title: 网盘管理跨端应用
|
||||
scope:
|
||||
- vue\.gitignore
|
||||
- vue\.vscode\extensions.json
|
||||
- vue\APK_BUILD_OPTIONS.md
|
||||
- vue\APP_GUIDE.md
|
||||
- vue\PACKAGING_SUMMARY.md
|
||||
- vue\README.md
|
||||
- vue\android\.gitignore
|
||||
- vue\android\app\.gitignore
|
||||
- vue\android\app\build.gradle
|
||||
- vue\android\app\capacitor.build.gradle
|
||||
- vue\android\app\proguard-rules.pro
|
||||
- vue\android\app\src\androidTest\java\com\getcapacitor\myapp\ExampleInstrumentedTest.java
|
||||
- vue\android\app\src\main\AndroidManifest.xml
|
||||
- vue\android\app\src\main\assets\capacitor.config.json
|
||||
- vue\android\app\src\main\assets\capacitor.plugins.json
|
||||
- vue\android\app\src\main\assets\public\assets\index-DrjxTYTT.css
|
||||
- vue\android\app\src\main\assets\public\assets\index-xOoYtVTp.js
|
||||
- vue\android\app\src\main\assets\public\cordova.js
|
||||
- vue\android\app\src\main\assets\public\cordova_plugins.js
|
||||
- vue\android\app\src\main\assets\public\index.html
|
||||
- vue\android\app\src\main\assets\public\logo.png
|
||||
- vue\android\app\src\main\assets\public\vite.svg
|
||||
- vue\android\app\src\main\java\com\wangpan\app\MainActivity.java
|
||||
- vue\android\app\src\main\res\drawable-land-hdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-mdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-xhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-xxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-xxxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-hdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-mdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-xhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-xxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-xxxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-v24\ic_launcher_foreground.xml
|
||||
- vue\android\app\src\main\res\drawable\ic_launcher_background.xml
|
||||
- vue\android\app\src\main\res\drawable\splash.png
|
||||
- vue\android\app\src\main\res\layout\activity_main.xml
|
||||
- vue\android\app\src\main\res\mipmap-anydpi-v26\ic_launcher.xml
|
||||
- vue\android\app\src\main\res\mipmap-anydpi-v26\ic_launcher_round.xml
|
||||
- vue\android\app\src\main\res\mipmap-hdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-hdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-hdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-mdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-mdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-mdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-xhdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-xhdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-xhdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-xxhdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-xxhdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-xxhdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-xxxhdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-xxxhdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-xxxhdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\values\ic_launcher_background.xml
|
||||
- vue\android\app\src\main\res\values\strings.xml
|
||||
- vue\android\app\src\main\res\values\styles.xml
|
||||
- vue\android\app\src\main\res\xml\config.xml
|
||||
- vue\android\app\src\main\res\xml\file_paths.xml
|
||||
- vue\android\app\src\test\java\com\getcapacitor\myapp\ExampleUnitTest.java
|
||||
- vue\android\build.gradle
|
||||
- vue\android\capacitor-cordova-android-plugins\build.gradle
|
||||
- vue\android\capacitor-cordova-android-plugins\cordova.variables.gradle
|
||||
- vue\android\capacitor-cordova-android-plugins\src\main\AndroidManifest.xml
|
||||
- vue\android\capacitor-cordova-android-plugins\src\main\java\.gitkeep
|
||||
- vue\android\capacitor-cordova-android-plugins\src\main\res\.gitkeep
|
||||
- vue\android\capacitor.settings.gradle
|
||||
- vue\android\gradle.properties
|
||||
- vue\android\gradle\wrapper\gradle-wrapper.jar
|
||||
- vue\android\gradle\wrapper\gradle-wrapper.properties
|
||||
- vue\android\gradlew
|
||||
- vue\android\gradlew.bat
|
||||
- vue\android\settings.gradle
|
||||
- vue\android\variables.gradle
|
||||
- vue\build-apk.bat
|
||||
- vue\capacitor.config.json
|
||||
- vue\index.html
|
||||
- vue\package-lock.json
|
||||
- vue\package.json
|
||||
- vue\public\logo.png
|
||||
- vue\public\vite.svg
|
||||
- vue\src\App.vue
|
||||
- vue\src\api\index.js
|
||||
- vue\src\assets\vue.svg
|
||||
- vue\src\components\DriveManageDialog.vue
|
||||
- vue\src\components\FolderTree.vue
|
||||
- vue\src\components\LoginView.vue
|
||||
- vue\src\components\PosterCard.vue
|
||||
- vue\src\components\RecordDialog.vue
|
||||
- vue\src\components\SimpleDialog.vue
|
||||
- vue\src\components\TreeNode.vue
|
||||
- vue\src\components\UserManageDialog.vue
|
||||
- vue\src\main.js
|
||||
- vue\src\style.css
|
||||
- vue\src\utils\captcha.js
|
||||
- vue\src\utils\data.js
|
||||
- vue\src\utils\storage.js
|
||||
- vue\vite.config.js
|
||||
source_files: []
|
||||
children: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
105
.qoder/repowiki/knowledge/zh/网盘管理跨端应用/_module.yaml
Normal file
@ -0,0 +1,105 @@
|
||||
schema_version: 1
|
||||
module_path: ""
|
||||
title: 网盘管理跨端应用
|
||||
scope:
|
||||
- vue\.gitignore
|
||||
- vue\.vscode\extensions.json
|
||||
- vue\APK_BUILD_OPTIONS.md
|
||||
- vue\APP_GUIDE.md
|
||||
- vue\PACKAGING_SUMMARY.md
|
||||
- vue\README.md
|
||||
- vue\android\.gitignore
|
||||
- vue\android\app\.gitignore
|
||||
- vue\android\app\build.gradle
|
||||
- vue\android\app\capacitor.build.gradle
|
||||
- vue\android\app\proguard-rules.pro
|
||||
- vue\android\app\src\androidTest\java\com\getcapacitor\myapp\ExampleInstrumentedTest.java
|
||||
- vue\android\app\src\main\AndroidManifest.xml
|
||||
- vue\android\app\src\main\assets\capacitor.config.json
|
||||
- vue\android\app\src\main\assets\capacitor.plugins.json
|
||||
- vue\android\app\src\main\assets\public\assets\index-DrjxTYTT.css
|
||||
- vue\android\app\src\main\assets\public\assets\index-xOoYtVTp.js
|
||||
- vue\android\app\src\main\assets\public\cordova.js
|
||||
- vue\android\app\src\main\assets\public\cordova_plugins.js
|
||||
- vue\android\app\src\main\assets\public\index.html
|
||||
- vue\android\app\src\main\assets\public\logo.png
|
||||
- vue\android\app\src\main\assets\public\vite.svg
|
||||
- vue\android\app\src\main\java\com\wangpan\app\MainActivity.java
|
||||
- vue\android\app\src\main\res\drawable-land-hdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-mdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-xhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-xxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-land-xxxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-hdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-mdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-xhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-xxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-port-xxxhdpi\splash.png
|
||||
- vue\android\app\src\main\res\drawable-v24\ic_launcher_foreground.xml
|
||||
- vue\android\app\src\main\res\drawable\ic_launcher_background.xml
|
||||
- vue\android\app\src\main\res\drawable\splash.png
|
||||
- vue\android\app\src\main\res\layout\activity_main.xml
|
||||
- vue\android\app\src\main\res\mipmap-anydpi-v26\ic_launcher.xml
|
||||
- vue\android\app\src\main\res\mipmap-anydpi-v26\ic_launcher_round.xml
|
||||
- vue\android\app\src\main\res\mipmap-hdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-hdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-hdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-mdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-mdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-mdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-xhdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-xhdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-xhdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-xxhdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-xxhdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-xxhdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\mipmap-xxxhdpi\ic_launcher.png
|
||||
- vue\android\app\src\main\res\mipmap-xxxhdpi\ic_launcher_foreground.png
|
||||
- vue\android\app\src\main\res\mipmap-xxxhdpi\ic_launcher_round.png
|
||||
- vue\android\app\src\main\res\values\ic_launcher_background.xml
|
||||
- vue\android\app\src\main\res\values\strings.xml
|
||||
- vue\android\app\src\main\res\values\styles.xml
|
||||
- vue\android\app\src\main\res\xml\config.xml
|
||||
- vue\android\app\src\main\res\xml\file_paths.xml
|
||||
- vue\android\app\src\test\java\com\getcapacitor\myapp\ExampleUnitTest.java
|
||||
- vue\android\build.gradle
|
||||
- vue\android\capacitor-cordova-android-plugins\build.gradle
|
||||
- vue\android\capacitor-cordova-android-plugins\cordova.variables.gradle
|
||||
- vue\android\capacitor-cordova-android-plugins\src\main\AndroidManifest.xml
|
||||
- vue\android\capacitor-cordova-android-plugins\src\main\java\.gitkeep
|
||||
- vue\android\capacitor-cordova-android-plugins\src\main\res\.gitkeep
|
||||
- vue\android\capacitor.settings.gradle
|
||||
- vue\android\gradle.properties
|
||||
- vue\android\gradle\wrapper\gradle-wrapper.jar
|
||||
- vue\android\gradle\wrapper\gradle-wrapper.properties
|
||||
- vue\android\gradlew
|
||||
- vue\android\gradlew.bat
|
||||
- vue\android\settings.gradle
|
||||
- vue\android\variables.gradle
|
||||
- vue\build-apk.bat
|
||||
- vue\capacitor.config.json
|
||||
- vue\index.html
|
||||
- vue\package-lock.json
|
||||
- vue\package.json
|
||||
- vue\public\logo.png
|
||||
- vue\public\vite.svg
|
||||
- vue\src\App.vue
|
||||
- vue\src\api\index.js
|
||||
- vue\src\assets\vue.svg
|
||||
- vue\src\components\DriveManageDialog.vue
|
||||
- vue\src\components\FolderTree.vue
|
||||
- vue\src\components\LoginView.vue
|
||||
- vue\src\components\PosterCard.vue
|
||||
- vue\src\components\RecordDialog.vue
|
||||
- vue\src\components\SimpleDialog.vue
|
||||
- vue\src\components\TreeNode.vue
|
||||
- vue\src\components\UserManageDialog.vue
|
||||
- vue\src\main.js
|
||||
- vue\src\style.css
|
||||
- vue\src\utils\captcha.js
|
||||
- vue\src\utils\data.js
|
||||
- vue\src\utils\storage.js
|
||||
- vue\vite.config.js
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
1
.qoder/repowiki/knowledge/zh/网盘管理跨端应用/技术栈.md
Normal file
@ -0,0 +1 @@
|
||||
Vue 3.5, Vite 7, Capacitor 8, Android Gradle Plugin
|
||||
4
.qoder/repowiki/knowledge/zh/网盘管理跨端应用/架构设计.md
Normal file
@ -0,0 +1,4 @@
|
||||
- **前端架构**:采用 Vite + Vue 3 (Composition API) 技术栈,通过 `src/api/index.js` 封装 RESTful 请求并处理 Token 鉴权。
|
||||
- **跨端桥接**:利用 Capacitor 8 将 Web 应用(`dist` 目录)嵌入原生 Android Shell (`BridgeActivity`),实现从 Web 到 Native 的无缝转换。
|
||||
- **配置管理**:通过 `capacitor.config.json` 定义应用 ID、启动屏及状态栏样式,并通过 `vite.config.js` 代理后端 API 请求。
|
||||
- **构建流程**:遵循“Vite 构建 Web -> Cap sync 同步资源 -> Gradle 编译 APK”的标准化流水线,由 `build-apk.bat` 脚本自动化执行。
|
||||
1
.qoder/repowiki/knowledge/zh/网盘管理跨端应用/概述.md
Normal file
@ -0,0 +1 @@
|
||||
基于 Vue 3 与 Capacitor 构建的网盘资源管理与海报展示跨端应用,支持 Android APK 打包。
|
||||
1
.qoder/repowiki/knowledge/zh/网盘管理跨端应用/特殊配置与命令.md
Normal file
@ -0,0 +1 @@
|
||||
- **APK 打包**:运行根目录下的 `build-apk.bat` 脚本,自动完成 Web 资源构建、Capacitor 同步并唤起 Android Studio 进行最终编译。
|
||||
2
.qoder/repowiki/knowledge/zh/网盘管理跨端应用/编码规范.md
Normal file
@ -0,0 +1,2 @@
|
||||
- API 模块统一在 `src/api/index.js` 中导出,使用自定义 `request` 包装器处理全局认证头与 401/403 状态分发。
|
||||
- 组件采用 `<script setup>` 语法糖编写,逻辑复用通过 `src/utils` 下的纯函数(如 `data.js`, `storage.js`)实现。
|
||||
BIN
create_icons.py
20
gen_icons.js
@ -1,20 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const iconsDir = path.join(__dirname, 'public', 'icons');
|
||||
if (!fs.existsSync(iconsDir)) fs.mkdirSync(iconsDir, { recursive: true });
|
||||
const icons = {
|
||||
home: { path: 'M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M9 22v-10l6 6v-10', label: 'Home' },
|
||||
search: { d: 'circle cx=11 cy=11 r=8 line x1=21 y1=21 x2=16.65 y2=16.65', label: 'Search' },
|
||||
user: { d: 'path d=M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2 circle cx=12 cy=7 r=4', label: 'User' },
|
||||
folder: { d: 'path d=M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z', fill: true, label: 'Folder' },
|
||||
file: { d: 'path d=M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z polyline points=14 2 14 8 20 8', label: 'File' },
|
||||
settings: { d: 'circle cx=12 cy=12 r=3 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 0', label: 'Settings' },
|
||||
close: { d: 'line x1=18 y1=6 x2=6 y2=18 line x1=6 y1=6 x2=18 y2=18', label: 'Close' },
|
||||
check: { d: 'polyline points=20 6 9 17 4 12', color: '#22c55e', label: 'Check' },
|
||||
delete: { d: 'polyline points=3 6 5 6 21 6 path d=M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2', color: '#ef4444', label: 'Delete' },
|
||||
add: { d: 'circle cx=12 cy=12 r=10 line x1=12 y1=8 x2=12 y2=16 line x1=8 y1=12 x2=16 y2=12', label: 'Add' },
|
||||
download: { d: 'path d=M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 polyline points=7 10 12 15 17 10 line x1=12 y1=15 x2=12 y2=3', label: 'Download' },
|
||||
upload: { d: 'path d=M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 polyline points=17 8 12 3 7 8 line x1=12 y1=3 x2=12 y2=15', label: 'Upload' },
|
||||
share: { d: 'circle cx=18 cy=5 r=3 circle cx=6 cy=12 r=3 circle cx=18 cy=19 r=3 line x1=8.59 y1=13.51 x2=15.42 y2=17.49 line x1=15.41 y1=6.51 x2=8.59 y2=10.49', label: 'Share' },
|
||||
favorite: { d: 'path d=M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z', fill: true, label: 'Favorite' },
|
||||
cloud: { d: 'path d=M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z', label: 'Cloud' },
|
||||
175
gen_icons.py
@ -1,175 +0,0 @@
|
||||
# Icon Generator Script
|
||||
import os
|
||||
|
||||
icons_dir = 'public/icons'
|
||||
os.makedirs(icons_dir, exist_ok=True)
|
||||
|
||||
# Color scheme
|
||||
PRIMARY_COLOR = '#6366f1'
|
||||
SUCCESS_COLOR = '#22c55e'
|
||||
DANGER_COLOR = '#ef4444'
|
||||
|
||||
def create_svg(filename, elements, color=PRIMARY_COLOR, fill=False):
|
||||
"""Create an SVG icon file"""
|
||||
fill_attr = 'fill "{}"'.format(color) if fill else 'fill="none"'
|
||||
svg_content = '''<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" {} stroke="{}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
{}
|
||||
</svg>'''.format(fill_attr, color, '\n'.join(elements))
|
||||
|
||||
filepath = os.path.join(icons_dir, filename)
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(svg_content)
|
||||
print(f'Created: {filename}')
|
||||
|
||||
# Home icon
|
||||
create_svg('home.svg', [
|
||||
'<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>',
|
||||
'<polyline points="9 22 9 12 15 12 15 22"/>'
|
||||
])
|
||||
|
||||
# Search icon
|
||||
create_svg('search.svg', [
|
||||
'<circle cx="11" cy="11" r="8"/>',
|
||||
'<line x1="21" y1="21" x2="16.65" y2="16.65"/>'
|
||||
])
|
||||
|
||||
# Settings icon
|
||||
create_svg('settings.svg', [
|
||||
'<circle cx="12" cy="12" r="3"/>',
|
||||
'<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"/>'
|
||||
])
|
||||
|
||||
# User icon
|
||||
create_svg('user.svg', [
|
||||
'<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>',
|
||||
'<circle cx="12" cy="7" r="4"/>'
|
||||
])
|
||||
|
||||
# Folder icon (filled)
|
||||
create_svg('folder.svg', [
|
||||
'<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>'
|
||||
], fill=True)
|
||||
|
||||
# File icon
|
||||
create_svg('file.svg', [
|
||||
'<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>',
|
||||
'<polyline points="14 2 14 8 20 8"/>'
|
||||
])
|
||||
|
||||
# Download icon
|
||||
create_svg('download.svg', [
|
||||
'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>',
|
||||
'<polyline points="7 10 12 15 17 10"/>',
|
||||
'<line x1="12" y1="15" x2="12" y2="3"/>'
|
||||
])
|
||||
|
||||
# Upload icon
|
||||
create_svg('upload.svg', [
|
||||
'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>',
|
||||
'<polyline points="17 8 12 3 7 8"/>',
|
||||
'<line x1="12" y1="3" x2="12" y2="15"/>'
|
||||
])
|
||||
|
||||
# Share icon
|
||||
create_svg('share.svg', [
|
||||
'<circle cx="18" cy="5" r="3"/>',
|
||||
'<circle cx="6" cy="12" r="3"/>',
|
||||
'<circle cx="18" cy="19" r="3"/>',
|
||||
'<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/>',
|
||||
'<line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>'
|
||||
])
|
||||
|
||||
# Favorite/Like icon (filled)
|
||||
create_svg('favorite.svg', [
|
||||
'<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>'
|
||||
], fill=True)
|
||||
|
||||
# Delete icon
|
||||
create_svg('delete.svg', [
|
||||
'<polyline points="3 6 5 6 21 6"/>',
|
||||
'<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>'
|
||||
], color=DANGER_COLOR)
|
||||
|
||||
# Edit icon
|
||||
create_svg('edit.svg', [
|
||||
'<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>',
|
||||
'<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>'
|
||||
])
|
||||
|
||||
# Add icon
|
||||
create_svg('add.svg', [
|
||||
'<circle cx="12" cy="12" r="10"/>',
|
||||
'<line x1="12" y1="8" x2="12" y2="16"/>',
|
||||
'<line x1="8" y1="12" x2="16" y2="12"/>'
|
||||
])
|
||||
|
||||
# Back/Arrow Left icon
|
||||
create_svg('back.svg', [
|
||||
'<line x1="19" y1="12" x2="5" y2="12"/>',
|
||||
'<polyline points="12 19 5 12 12 5"/>'
|
||||
])
|
||||
|
||||
# More/Options icon (three dots)
|
||||
create_svg('more.svg', [
|
||||
'<circle cx="12" cy="12" r="1"/>',
|
||||
'<circle cx="19" cy="12" r="1"/>',
|
||||
'<circle cx="5" cy="12" r="1"/>'
|
||||
], fill=True)
|
||||
|
||||
# Cloud icon
|
||||
create_svg('cloud.svg', [
|
||||
'<path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z"/>'
|
||||
])
|
||||
|
||||
# Drive/Server icon
|
||||
create_svg('drive.svg', [
|
||||
'<rect x="2" y="6" width="20" height="12" rx="2"/>',
|
||||
'<circle cx="12" cy="12" r="2"/>',
|
||||
'<path d="M6 12h.01 M18 12h.01"/>'
|
||||
])
|
||||
|
||||
# Log/File Text icon
|
||||
create_svg('log.svg', [
|
||||
'<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>',
|
||||
'<polyline points="14 2 14 8 20 8"/>',
|
||||
'<line x1="16" y1="13" x2="8" y2="13"/>',
|
||||
'<line x1="16" y1="17" x2="8" y2="17"/>',
|
||||
'<polyline points="10 9 9 9 8 9"/>'
|
||||
])
|
||||
|
||||
# Close icon
|
||||
create_svg('close.svg', [
|
||||
'<line x1="18" y1="6" x2="6" y2="18"/>',
|
||||
'<line x1="6" y1="6" x2="18" y2="18"/>'
|
||||
])
|
||||
|
||||
# Check/Verify icon
|
||||
create_svg('check.svg', [
|
||||
'<polyline points="20 6 9 17 4 12"/>'
|
||||
], color=SUCCESS_COLOR)
|
||||
|
||||
# Play icon
|
||||
create_svg('play.svg', [
|
||||
'<polygon points="5 3 19 12 5 21 5 3"/>'
|
||||
], fill=True)
|
||||
|
||||
# Pause icon
|
||||
create_svg('pause.svg', [
|
||||
'<rect x="6" y="4" width="4" height="16"/>',
|
||||
'<rect x="14" y="4" width="4" height="16"/>'
|
||||
])
|
||||
|
||||
# Eye icon
|
||||
create_svg('eye.svg', [
|
||||
'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>',
|
||||
'<circle cx="12" cy="12" r="3"/>'
|
||||
])
|
||||
|
||||
# Eye Off icon
|
||||
create_svg('eye-off.svg', [
|
||||
'<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>',
|
||||
'<line x1="1" y1="1" x2="23" y2="23"/>'
|
||||
])
|
||||
|
||||
print(f'\nTotal icons created: {len(os.listdir(icons_dir)) - 1}') # Exclude test.txt
|
||||
print('Icon generation complete!')
|
||||
@ -1,8 +0,0 @@
|
||||
<!-- 添加文件图标:文档+加号 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" 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"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<!-- 加号(青绿色) -->
|
||||
<line x1="12" y1="13" x2="12" y2="19" stroke="#2dd4bf" stroke-width="2"/>
|
||||
<line x1="9" y1="16" x2="15" y2="16" stroke="#2dd4bf" stroke-width="2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 525 B |
@ -1,7 +0,0 @@
|
||||
<!-- 添加文件夹图标:文件夹+加号 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<!-- 加号(青绿色) -->
|
||||
<line x1="12" y1="11" x2="12" y2="17" stroke="#2dd4bf" stroke-width="2"/>
|
||||
<line x1="9" y1="14" x2="15" y2="14" stroke="#2dd4bf" stroke-width="2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 510 B |
@ -1,10 +0,0 @@
|
||||
<!-- 批量删除图标:垃圾桶+列表 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
|
||||
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
||||
<!-- 列表线(青绿色) -->
|
||||
<line x1="10" y1="11" x2="10" y2="17" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="14" y1="11" x2="14" y2="17" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="9" y1="9" x2="15" y2="9" stroke="#2dd4bf" stroke-width="1"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 628 B |
@ -1,13 +0,0 @@
|
||||
<!-- 批量刮削图标:电影+列表 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="6" width="18" height="14" rx="1"/>
|
||||
<path d="M3 10h18"/>
|
||||
<path d="M7 6V3"/>
|
||||
<path d="M12 6V3"/>
|
||||
<path d="M17 6V3"/>
|
||||
<!-- 场记板条纹(青绿色) -->
|
||||
<line x1="5" y1="8" x2="7" y2="8" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="9" y1="8" x2="11" y2="8" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="13" y1="8" x2="15" y2="8" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="17" y1="8" x2="19" y2="8" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 713 B |
@ -1,8 +0,0 @@
|
||||
<!-- 主演图标:面具/戏剧 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 12c0-5 4-9 10-9s10 4 10 9"/>
|
||||
<path d="M2 12c0 3 2 5 4 5s3-2 4-5"/>
|
||||
<path d="M14 12c1 3 2 5 4 5s4-2 4-5"/>
|
||||
<!-- 面具高亮(青绿色) -->
|
||||
<path d="M2 12c0 3 2 5 4 5s3-2 4-5" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 492 B |
@ -1,5 +0,0 @@
|
||||
<!-- 多选图标:复选框+对勾 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="3" width="18" height="18" rx="3"/>
|
||||
<path d="M7 12l3.5 3.5L17 9" stroke="#2dd4bf" stroke-width="2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 346 B |
@ -1,7 +0,0 @@
|
||||
<!-- 关闭图标:X -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"/>
|
||||
<line x1="6" y1="6" x2="18" y2="18"/>
|
||||
<!-- 关闭线高亮(青绿色) -->
|
||||
<line x1="18" y1="6" x2="6" y2="18" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 410 B |
@ -1,10 +0,0 @@
|
||||
<!-- 删除图标:垃圾桶 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
|
||||
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
||||
<line x1="10" y1="11" x2="10" y2="17"/>
|
||||
<line x1="14" y1="11" x2="14" y2="17"/>
|
||||
<!-- 桶身高亮(青绿色) -->
|
||||
<path d="M9 6v12a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1V6" stroke="#2dd4bf" stroke-width="0.8" opacity="0.3"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 577 B |
@ -1,7 +0,0 @@
|
||||
<!-- 简介图标:打开的书 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
|
||||
<!-- 书页高亮(青绿色) -->
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.3" opacity="0.15"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 495 B |
@ -1,10 +0,0 @@
|
||||
<!-- 详情图标:文档+放大镜 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" 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"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<line x1="8" y1="13" x2="16" y2="13"/>
|
||||
<line x1="8" y1="17" x2="12" y2="17"/>
|
||||
<!-- 放大镜(青绿色) -->
|
||||
<circle cx="17" cy="17" r="3" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="19.5" y1="19.5" x2="22" y2="22" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 608 B |
@ -1,7 +0,0 @@
|
||||
<!-- 编辑图标:铅笔 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
<!-- 铅笔尖高亮(青绿色) -->
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4z" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 529 B |
@ -1,8 +0,0 @@
|
||||
<!-- 导出图标:上传箭头 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="17 8 12 3 7 8"/>
|
||||
<line x1="12" y1="3" x2="12" y2="15"/>
|
||||
<!-- 箭头高亮(青绿色) -->
|
||||
<polyline points="17 8 12 3 7 8" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 469 B |
@ -1,7 +0,0 @@
|
||||
<!-- 隐藏图标:眼睛+斜线 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
|
||||
<line x1="1" y1="1" x2="23" y2="23"/>
|
||||
<!-- 斜线高亮(青绿色) -->
|
||||
<line x1="1" y1="1" x2="23" y2="23" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 574 B |
@ -1,7 +0,0 @@
|
||||
<!-- 显示图标:眼睛 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<!-- 眼睛高亮(青绿色) -->
|
||||
<circle cx="12" cy="12" r="1.5" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 436 B |
@ -1,9 +0,0 @@
|
||||
<!-- 失败图标:叉号圆圈 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<line x1="9" y1="9" x2="15" y2="15"/>
|
||||
<line x1="15" y1="9" x2="9" y2="15"/>
|
||||
<!-- 叉号高亮(青绿色) -->
|
||||
<line x1="9" y1="9" x2="15" y2="15" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="15" y1="9" x2="9" y2="15" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 528 B |
@ -1,9 +0,0 @@
|
||||
<!-- 文件图标:文档 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" 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"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<line x1="8" y1="13" x2="16" y2="13"/>
|
||||
<line x1="8" y1="17" x2="13" y2="17"/>
|
||||
<!-- 文件折角高亮(青绿色) -->
|
||||
<polyline points="14 2 14 8 20 8" stroke="#2dd4bf" stroke-width="1" opacity="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 541 B |
@ -1,7 +0,0 @@
|
||||
<!-- 打开的文件夹图标 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<path d="M2 10h20"/>
|
||||
<!-- 文件夹内部高亮(青绿色) -->
|
||||
<path d="M4 10h16v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-7z" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.3" opacity="0.15"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 506 B |
@ -1,7 +0,0 @@
|
||||
<!-- 刷新文件夹图标:文件夹+刷新箭头 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<!-- 刷新箭头(青绿色) -->
|
||||
<path d="M14 13a3 3 0 1 1-1-2.2L14 12" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<polyline points="12 10 14 12 16 10" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 527 B |
@ -1,6 +0,0 @@
|
||||
<!-- 文件夹图标:关闭状态 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<!-- 文件夹标签高亮(青绿色) -->
|
||||
<path d="M4 5h5l2 3h9" stroke="#2dd4bf" stroke-width="1" opacity="0.4"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 439 B |
@ -1,8 +0,0 @@
|
||||
<!-- 网络图标:地球 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<line x1="2" y1="12" x2="22" y2="12"/>
|
||||
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
|
||||
<!-- 地球高亮(青绿色) -->
|
||||
<path d="M12 2a15.3 15.3 0 0 1 4 10" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 514 B |
@ -1,8 +0,0 @@
|
||||
<!-- 信息图标:圆圈i -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<line x1="12" y1="16" x2="12" y2="12"/>
|
||||
<line x1="12" y1="8" x2="12.01" y2="8"/>
|
||||
<!-- 信息符号高亮(青绿色) -->
|
||||
<line x1="12" y1="16" x2="12" y2="12" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 461 B |
@ -1,7 +0,0 @@
|
||||
<!-- 链接图标:链条 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
||||
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
||||
<!-- 链条连接处高亮(青绿色) -->
|
||||
<path d="M10 13a5 5 0 0 0 2 1.5" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 487 B |
@ -1,10 +0,0 @@
|
||||
<!-- 日志图标:剪贴板 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
|
||||
<rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>
|
||||
<line x1="8" y1="10" x2="16" y2="10"/>
|
||||
<line x1="8" y1="14" x2="16" y2="14"/>
|
||||
<line x1="8" y1="18" x2="12" y2="18"/>
|
||||
<!-- 日志条目高亮(青绿色) -->
|
||||
<line x1="8" y1="10" x2="11" y2="10" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 609 B |
@ -1,8 +0,0 @@
|
||||
<!-- 退出图标:门+箭头 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
|
||||
<polyline points="16 17 21 12 16 7"/>
|
||||
<line x1="21" y1="12" x2="9" y2="12"/>
|
||||
<!-- 箭头高亮(青绿色) -->
|
||||
<polyline points="16 17 21 12 16 7" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 471 B |
@ -1,11 +0,0 @@
|
||||
<!-- 电影图标:场记板 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="6" width="18" height="14" rx="1"/>
|
||||
<path d="M3 10h18"/>
|
||||
<path d="M7 6V3"/>
|
||||
<path d="M12 6V3"/>
|
||||
<path d="M17 6V3"/>
|
||||
<!-- 场记板条纹高亮(青绿色) -->
|
||||
<line x1="5" y1="8" x2="7" y2="8" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<line x1="9" y1="8" x2="11" y2="8" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 557 B |
@ -1,10 +0,0 @@
|
||||
<!-- 内外网切换图标:双向箭头 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="4" y1="8" x2="20" y2="8"/>
|
||||
<polyline points="16 4 20 8 16 12"/>
|
||||
<line x1="20" y1="16" x2="4" y2="16"/>
|
||||
<polyline points="8 12 4 16 8 20"/>
|
||||
<!-- 箭头高亮(青绿色) -->
|
||||
<polyline points="16 4 20 8 16 12" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
<polyline points="8 12 4 16 8 20" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 577 B |
@ -1,154 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>图标预览 - 网盘管理系统</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: #f5f7fa;
|
||||
padding: 32px;
|
||||
color: #374151;
|
||||
}
|
||||
h1 { text-align: center; font-size: 22px; font-weight: 700; margin-bottom: 8px; }
|
||||
.subtitle { text-align: center; font-size: 13px; color: #94a3b8; margin-bottom: 32px; }
|
||||
.section-title {
|
||||
font-size: 15px; font-weight: 600; color: #64748b; margin: 28px 0 12px;
|
||||
padding-bottom: 8px; border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
.icon-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
|
||||
gap: 14px;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.icon-card {
|
||||
display: flex; flex-direction: column; align-items: center; gap: 8px;
|
||||
padding: 16px 8px 12px; background: #fff; border-radius: 12px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.06); transition: all 0.2s;
|
||||
}
|
||||
.icon-card:hover { box-shadow: 0 4px 16px rgba(45,212,191,0.15); transform: translateY(-2px); }
|
||||
.icon-card img { width: 40px; height: 40px; object-fit: contain; }
|
||||
.icon-card span { font-size: 11px; color: #64748b; text-align: center; white-space: nowrap; }
|
||||
.style-info {
|
||||
max-width: 960px; margin: 32px auto 0; padding: 20px 24px;
|
||||
background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.06);
|
||||
font-size: 13px; line-height: 1.8; color: #64748b;
|
||||
}
|
||||
.style-info strong { color: #374151; }
|
||||
.color-dot { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: middle; margin-right: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>网盘管理系统 - 统一风格图标集</h1>
|
||||
<p class="subtitle">深色描边 + 青绿色点缀 · 简约立体风格 · 根据代码实际使用场景生成</p>
|
||||
|
||||
<div class="section-title">顶部导航栏</div>
|
||||
<div class="icon-grid" id="grid-topbar"></div>
|
||||
|
||||
<div class="section-title">用户菜单</div>
|
||||
<div class="icon-grid" id="grid-user"></div>
|
||||
|
||||
<div class="section-title">网盘与文件管理</div>
|
||||
<div class="icon-grid" id="grid-drive"></div>
|
||||
|
||||
<div class="section-title">刮削与日志</div>
|
||||
<div class="icon-grid" id="grid-scrape"></div>
|
||||
|
||||
<div class="section-title">海报详情</div>
|
||||
<div class="icon-grid" id="grid-poster"></div>
|
||||
|
||||
<div class="section-title">设置与绑定</div>
|
||||
<div class="icon-grid" id="grid-settings"></div>
|
||||
|
||||
<div class="section-title">状态与提示</div>
|
||||
<div class="icon-grid" id="grid-status"></div>
|
||||
|
||||
<div class="style-info">
|
||||
<strong>设计规范:</strong><br/>
|
||||
• 主色(描边):<span class="color-dot" style="background:#374151"></span>#374151 深灰色<br/>
|
||||
• 点缀色(高亮):<span class="color-dot" style="background:#2dd4bf"></span>#2dd4bf 青绿色<br/>
|
||||
• 尺寸:viewBox 24×24,显示 48×48px<br/>
|
||||
• 风格:线条描边 + 局部色块填充,简约立体感<br/>
|
||||
• 格式:SVG 矢量图,可无损缩放<br/>
|
||||
• 用途:替换代码中现有的 emoji 图标,实现视觉统一
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const iconGroups = {
|
||||
'grid-topbar': [
|
||||
{ file: 'search.svg', name: '搜索' },
|
||||
{ file: 'settings.svg', name: '设置' },
|
||||
{ file: 'globe.svg', name: '外网' },
|
||||
{ file: 'network.svg', name: '内外网切换' },
|
||||
{ file: 'user.svg', name: '用户' },
|
||||
{ file: 'switch-view.svg', name: '切换视图' },
|
||||
],
|
||||
'grid-user': [
|
||||
{ file: 'movie.svg', name: '海报展示' },
|
||||
{ file: 'log.svg', name: '控制台' },
|
||||
{ file: 'settings.svg', name: 'TMDB配置' },
|
||||
{ file: 'tools.svg', name: '设置' },
|
||||
{ file: 'export.svg', name: '导出数据' },
|
||||
{ file: 'refresh.svg', name: '恢复数据' },
|
||||
{ file: 'logout.svg', name: '退出登录' },
|
||||
],
|
||||
'grid-drive': [
|
||||
{ file: 'folder.svg', name: '文件夹' },
|
||||
{ file: 'folder-open.svg', name: '打开文件夹' },
|
||||
{ file: 'file.svg', name: '文件' },
|
||||
{ file: 'add-folder.svg', name: '添加文件夹' },
|
||||
{ file: 'add-file.svg', name: '添加文件' },
|
||||
{ file: 'folder-refresh.svg', name: '刷新文件夹' },
|
||||
{ file: 'checkbox.svg', name: '多选' },
|
||||
{ file: 'batch-delete.svg', name: '批量删除' },
|
||||
{ file: 'delete.svg', name: '删除' },
|
||||
{ file: 'edit.svg', name: '编辑' },
|
||||
],
|
||||
'grid-scrape': [
|
||||
{ file: 'scrape.svg', name: '刮削' },
|
||||
{ file: 'batch-scrape.svg', name: '批量刮削' },
|
||||
{ file: 'sync.svg', name: '同步' },
|
||||
{ file: 'log.svg', name: '刮削日志' },
|
||||
],
|
||||
'grid-poster': [
|
||||
{ file: 'movie.svg', name: '电影' },
|
||||
{ file: 'cast.svg', name: '主演' },
|
||||
{ file: 'tag.svg', name: '标签' },
|
||||
{ file: 'detail.svg', name: '查看详情' },
|
||||
{ file: 'description.svg', name: '简介' },
|
||||
],
|
||||
'grid-settings': [
|
||||
{ file: 'link.svg', name: '绑定链接' },
|
||||
{ file: 'globe.svg', name: 'OpenList地址' },
|
||||
{ file: 'user.svg', name: '账号' },
|
||||
{ file: 'eye.svg', name: '显示密码' },
|
||||
{ file: 'eye-off.svg', name: '隐藏密码' },
|
||||
],
|
||||
'grid-status': [
|
||||
{ file: 'success.svg', name: '成功' },
|
||||
{ file: 'fail.svg', name: '失败' },
|
||||
{ file: 'warning.svg', name: '警告' },
|
||||
{ file: 'info.svg', name: '信息' },
|
||||
{ file: 'sparkle.svg', name: '提示' },
|
||||
{ file: 'save.svg', name: '保存' },
|
||||
{ file: 'close.svg', name: '关闭' },
|
||||
],
|
||||
};
|
||||
|
||||
Object.entries(iconGroups).forEach(([gridId, icons]) => {
|
||||
const grid = document.getElementById(gridId);
|
||||
if (!grid) return;
|
||||
icons.forEach(icon => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'icon-card';
|
||||
card.innerHTML = `<img src="${icon.file}" alt="${icon.name}" /><span>${icon.name}</span>`;
|
||||
grid.appendChild(card);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,9 +0,0 @@
|
||||
<!-- 刷新图标:循环箭头 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 2v6h-6"/>
|
||||
<path d="M3 12a9 9 0 0 1 15-6.7L21 8"/>
|
||||
<path d="M3 22v-6h6"/>
|
||||
<path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>
|
||||
<!-- 箭头高亮(青绿色) -->
|
||||
<path d="M21 2v6h-6" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 458 B |
@ -1,8 +0,0 @@
|
||||
<!-- 保存图标:软盘 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
||||
<polyline points="17 21 17 13 7 13 7 21"/>
|
||||
<polyline points="7 3 7 8 15 8"/>
|
||||
<!-- 软盘标签高亮(青绿色) -->
|
||||
<rect x="9" y="15" width="6" height="4" rx="0.5" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 525 B |
@ -1,11 +0,0 @@
|
||||
<!-- 刮削图标:电影+刷新 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="6" width="18" height="14" rx="1"/>
|
||||
<path d="M3 10h18"/>
|
||||
<path d="M7 6V3"/>
|
||||
<path d="M12 6V3"/>
|
||||
<path d="M17 6V3"/>
|
||||
<!-- 刷新箭头(青绿色) -->
|
||||
<path d="M14 13a3 3 0 1 1-1-2.2L14 12" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
<polyline points="12 10 14 12 16 10" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 559 B |
@ -1,7 +0,0 @@
|
||||
<!-- 搜索图标:放大镜 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="10.5" cy="10.5" r="6.5"/>
|
||||
<line x1="15.5" y1="15.5" x2="21" y2="21"/>
|
||||
<!-- 镜片反光(青绿色) -->
|
||||
<path d="M7 7.5a5 5 0 0 1 3-1" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 416 B |
@ -1,7 +0,0 @@
|
||||
<!-- 设置图标:齿轮 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.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-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
||||
<!-- 齿轮中心高亮(青绿色) -->
|
||||
<circle cx="12" cy="12" r="1.5" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1012 B |
@ -1,6 +0,0 @@
|
||||
<!-- 提示图标:星星/闪光 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 2l2.4 7.2L22 12l-7.6 2.8L12 22l-2.4-7.2L2 12l7.6-2.8z"/>
|
||||
<!-- 星星高亮(青绿色) -->
|
||||
<path d="M12 2l2.4 7.2L22 12l-7.6 2.8L12 22z" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 450 B |
@ -1,5 +0,0 @@
|
||||
<!-- 成功图标:对勾圆圈 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<path d="M8 12l3 3 5-6" stroke="#2dd4bf" stroke-width="2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 319 B |
@ -1,10 +0,0 @@
|
||||
<!-- 切换视图图标:⇄ 双向切换 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="17 1 21 5 17 9"/>
|
||||
<path d="M3 11V9a4 4 0 0 1 4-4h14"/>
|
||||
<polyline points="7 23 3 19 7 15"/>
|
||||
<path d="M21 13v2a4 4 0 0 1-4 4H3"/>
|
||||
<!-- 箭头高亮(青绿色) -->
|
||||
<polyline points="17 1 21 5 17 9" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
<polyline points="7 23 3 19 7 15" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 574 B |
@ -1,7 +0,0 @@
|
||||
<!-- 同步图标:云端同步 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 12a9 9 0 1 1-6.219-8.56"/>
|
||||
<polyline points="21 3 21 9 15 9"/>
|
||||
<!-- 同步箭头高亮(青绿色) -->
|
||||
<polyline points="21 3 21 9 15 9" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 422 B |
@ -1,7 +0,0 @@
|
||||
<!-- 标签图标 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/>
|
||||
<line x1="7" y1="7" x2="7.01" y2="7"/>
|
||||
<!-- 标签孔高亮(青绿色) -->
|
||||
<circle cx="7" cy="7" r="1" fill="#2dd4bf" stroke="#2dd4bf" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 467 B |
@ -1,6 +0,0 @@
|
||||
<!-- 工具图标:扳手 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
||||
<!-- 扳手头部高亮(青绿色) -->
|
||||
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 513 B |
@ -1,7 +0,0 @@
|
||||
<!-- 用户图标:人物轮廓 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
<!-- 头像高亮(青绿色) -->
|
||||
<path d="M10 5.5a3 3 0 0 1 2-1" stroke="#2dd4bf" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 423 B |
@ -1,8 +0,0 @@
|
||||
<!-- 警告图标:三角感叹号 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
||||
<line x1="12" y1="9" x2="12" y2="13"/>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
||||
<!-- 感叹号高亮(青绿色) -->
|
||||
<line x1="12" y1="9" x2="12" y2="13" stroke="#2dd4bf" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 4.5 MiB |
@ -1,363 +0,0 @@
|
||||
<!--
|
||||
统一图标组件 - 支持白天/黑夜两种主题
|
||||
用法: <AppIcon name="search" size="20" />
|
||||
|
||||
主题颜色通过 CSS 变量自动适配:
|
||||
- 白天模式: 描边 #374151, 点缀 #0f766e (品牌青)
|
||||
- 黑夜模式: 描边 #94a3b8, 点缀 #38bdf8 (品牌蓝)
|
||||
-->
|
||||
<template>
|
||||
<span class="app-icon" :style="{ width: size + 'px', height: size + 'px' }">
|
||||
<!-- 搜索 -->
|
||||
<svg v-if="name === 'search'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="10.5" cy="10.5" r="6.5"/>
|
||||
<line x1="15.5" y1="15.5" x2="21" y2="21"/>
|
||||
<path d="M7 7.5a5 5 0 0 1 3-1" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 设置/齿轮 -->
|
||||
<svg v-else-if="name === 'settings'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.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-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
||||
<circle cx="12" cy="12" r="1.5" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 文件夹(关闭) -->
|
||||
<svg v-else-if="name === 'folder'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<path d="M4 5h5l2 3h9" stroke="var(--icon-accent)" stroke-width="1" opacity="0.4"/>
|
||||
</svg>
|
||||
|
||||
<!-- 文件夹(打开) -->
|
||||
<svg v-else-if="name === 'folder-open'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<path d="M2 10h20"/>
|
||||
<path d="M4 10h16v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-7z" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.3" opacity="0.15"/>
|
||||
</svg>
|
||||
|
||||
<!-- 用户 -->
|
||||
<svg v-else-if="name === 'user'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
<path d="M10 5.5a3 3 0 0 1 2-1" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 成功/对勾 -->
|
||||
<svg v-else-if="name === 'success'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<path d="M8 12l3 3 5-6" stroke="var(--icon-accent)" stroke-width="2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 删除/垃圾桶 -->
|
||||
<svg v-else-if="name === 'delete'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
|
||||
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
||||
<line x1="10" y1="11" x2="10" y2="17"/>
|
||||
<line x1="14" y1="11" x2="14" y2="17"/>
|
||||
<path d="M9 6v12a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1V6" stroke="var(--icon-accent)" stroke-width="0.8" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 刷新 -->
|
||||
<svg v-else-if="name === 'refresh'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 2v6h-6"/>
|
||||
<path d="M3 12a9 9 0 0 1 15-6.7L21 8"/>
|
||||
<path d="M3 22v-6h6"/>
|
||||
<path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>
|
||||
<path d="M21 2v6h-6" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 电影/场记板 -->
|
||||
<svg v-else-if="name === 'movie'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="6" width="18" height="14" rx="1"/>
|
||||
<path d="M3 10h18"/>
|
||||
<path d="M7 6V3"/>
|
||||
<path d="M12 6V3"/>
|
||||
<path d="M17 6V3"/>
|
||||
<line x1="5" y1="8" x2="7" y2="8" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="9" y1="8" x2="11" y2="8" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 日志/剪贴板 -->
|
||||
<svg v-else-if="name === 'log'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
|
||||
<rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>
|
||||
<line x1="8" y1="10" x2="16" y2="10"/>
|
||||
<line x1="8" y1="14" x2="16" y2="14"/>
|
||||
<line x1="8" y1="18" x2="12" y2="18"/>
|
||||
<line x1="8" y1="10" x2="11" y2="10" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 工具/扳手 -->
|
||||
<svg v-else-if="name === 'tools'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
||||
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 导出/上传 -->
|
||||
<svg v-else-if="name === 'export'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="17 8 12 3 7 8"/>
|
||||
<line x1="12" y1="3" x2="12" y2="15"/>
|
||||
<polyline points="17 8 12 3 7 8" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<svg v-else-if="name === 'logout'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
|
||||
<polyline points="16 17 21 12 16 7"/>
|
||||
<line x1="21" y1="12" x2="9" y2="12"/>
|
||||
<polyline points="16 17 21 12 16 7" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 提示/闪光 -->
|
||||
<svg v-else-if="name === 'sparkle'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 2l2.4 7.2L22 12l-7.6 2.8L12 22l-2.4-7.2L2 12l7.6-2.8z"/>
|
||||
<path d="M12 2l2.4 7.2L22 12l-7.6 2.8L12 22z" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 保存/软盘 -->
|
||||
<svg v-else-if="name === 'save'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
||||
<polyline points="17 21 17 13 7 13 7 21"/>
|
||||
<polyline points="7 3 7 8 15 8"/>
|
||||
<rect x="9" y="15" width="6" height="4" rx="0.5" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 链接 -->
|
||||
<svg v-else-if="name === 'link'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
||||
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
||||
<path d="M10 13a5 5 0 0 0 2 1.5" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 地球/网络 -->
|
||||
<svg v-else-if="name === 'globe'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<line x1="2" y1="12" x2="22" y2="12"/>
|
||||
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
|
||||
<path d="M12 2a15.3 15.3 0 0 1 4 10" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 眼睛(显示) -->
|
||||
<svg v-else-if="name === 'eye'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<circle cx="12" cy="12" r="1.5" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 眼睛关闭(隐藏) -->
|
||||
<svg v-else-if="name === 'eye-off'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
|
||||
<line x1="1" y1="1" x2="23" y2="23" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 多选/复选框 -->
|
||||
<svg v-else-if="name === 'checkbox'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="3" width="18" height="18" rx="3"/>
|
||||
<path d="M7 12l3.5 3.5L17 9" stroke="var(--icon-accent)" stroke-width="2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 警告 -->
|
||||
<svg v-else-if="name === 'warning'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
||||
<line x1="12" y1="9" x2="12" y2="13" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
||||
</svg>
|
||||
|
||||
<!-- 文件/文档 -->
|
||||
<svg v-else-if="name === 'file'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" 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"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<line x1="8" y1="13" x2="16" y2="13"/>
|
||||
<line x1="8" y1="17" x2="13" y2="17"/>
|
||||
<polyline points="14 2 14 8 20 8" stroke="var(--icon-accent)" stroke-width="1" opacity="0.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 信息 -->
|
||||
<svg v-else-if="name === 'info'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<line x1="12" y1="16" x2="12" y2="12" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="12" y1="8" x2="12.01" y2="8"/>
|
||||
</svg>
|
||||
|
||||
<!-- 内外网切换 -->
|
||||
<svg v-else-if="name === 'network'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="4" y1="8" x2="20" y2="8"/>
|
||||
<polyline points="16 4 20 8 16 12" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
<line x1="20" y1="16" x2="4" y2="16"/>
|
||||
<polyline points="8 12 4 16 8 20" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 标签 -->
|
||||
<svg v-else-if="name === 'tag'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/>
|
||||
<circle cx="7" cy="7" r="1" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 主演/面具 -->
|
||||
<svg v-else-if="name === 'cast'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 12c0-5 4-9 10-9s10 4 10 9"/>
|
||||
<path d="M2 12c0 3 2 5 4 5s3-2 4-5"/>
|
||||
<path d="M14 12c1 3 2 5 4 5s4-2 4-5"/>
|
||||
<path d="M2 12c0 3 2 5 4 5s3-2 4-5" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 详情 -->
|
||||
<svg v-else-if="name === 'detail'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" 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"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<line x1="8" y1="13" x2="16" y2="13"/>
|
||||
<line x1="8" y1="17" x2="12" y2="17"/>
|
||||
<circle cx="17" cy="17" r="3" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="19.5" y1="19.5" x2="22" y2="22" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 简介/书本 -->
|
||||
<svg v-else-if="name === 'description'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.3" opacity="0.15"/>
|
||||
</svg>
|
||||
|
||||
<!-- 编辑/铅笔 -->
|
||||
<svg v-else-if="name === 'edit'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4z" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 同步 -->
|
||||
<svg v-else-if="name === 'sync'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 12a9 9 0 1 1-6.219-8.56"/>
|
||||
<polyline points="21 3 21 9 15 9" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 失败/叉号 -->
|
||||
<svg v-else-if="name === 'fail'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<line x1="9" y1="9" x2="15" y2="15" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="15" y1="9" x2="9" y2="15" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 关闭/X -->
|
||||
<svg v-else-if="name === 'close'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
<line x1="6" y1="6" x2="18" y2="18"/>
|
||||
</svg>
|
||||
|
||||
<!-- 太阳(白天模式) -->
|
||||
<svg v-else-if="name === 'sun'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="5"/>
|
||||
<line x1="12" y1="1" x2="12" y2="3"/>
|
||||
<line x1="12" y1="21" x2="12" y2="23"/>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
|
||||
<line x1="1" y1="12" x2="3" y2="12"/>
|
||||
<line x1="21" y1="12" x2="23" y2="12"/>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
|
||||
<circle cx="12" cy="12" r="2.5" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.5" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 月亮(黑夜模式) -->
|
||||
<svg v-else-if="name === 'moon'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
||||
<path d="M21 12.79A9 9 0 0 1 12 21" fill="var(--icon-accent)" stroke="var(--icon-accent)" stroke-width="0.3" opacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 添加文件夹 -->
|
||||
<svg v-else-if="name === 'add-folder'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
<line x1="12" y1="11" x2="12" y2="17" stroke="var(--icon-accent)" stroke-width="2"/>
|
||||
<line x1="9" y1="14" x2="15" y2="14" stroke="var(--icon-accent)" stroke-width="2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 添加文件 -->
|
||||
<svg v-else-if="name === 'add-file'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" 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"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<line x1="12" y1="13" x2="12" y2="19" stroke="var(--icon-accent)" stroke-width="2"/>
|
||||
<line x1="9" y1="16" x2="15" y2="16" stroke="var(--icon-accent)" stroke-width="2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 批量删除 -->
|
||||
<svg v-else-if="name === 'batch-delete'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
|
||||
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
||||
<line x1="10" y1="11" x2="10" y2="17" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="14" y1="11" x2="14" y2="17" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="9" y1="9" x2="15" y2="9" stroke="var(--icon-accent)" stroke-width="1"/>
|
||||
</svg>
|
||||
|
||||
<!-- 批量刮削 -->
|
||||
<svg v-else-if="name === 'batch-scrape'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="6" width="18" height="14" rx="1"/>
|
||||
<path d="M3 10h18"/>
|
||||
<path d="M7 6V3"/><path d="M12 6V3"/><path d="M17 6V3"/>
|
||||
<line x1="5" y1="8" x2="7" y2="8" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="9" y1="8" x2="11" y2="8" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="13" y1="8" x2="15" y2="8" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<line x1="17" y1="8" x2="19" y2="8" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 刮削 -->
|
||||
<svg v-else-if="name === 'scrape'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="6" width="18" height="14" rx="1"/>
|
||||
<path d="M3 10h18"/>
|
||||
<path d="M7 6V3"/><path d="M12 6V3"/><path d="M17 6V3"/>
|
||||
<path d="M14 13a3 3 0 1 1-1-2.2L14 12" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
<polyline points="12 10 14 12 16 10" stroke="var(--icon-accent)" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- 切换视图 -->
|
||||
<svg v-else-if="name === 'switch-view'" viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="17 1 21 5 17 9" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
<path d="M3 11V9a4 4 0 0 1 4-4h14"/>
|
||||
<polyline points="7 23 3 19 7 15" stroke="var(--icon-accent)" stroke-width="1.2"/>
|
||||
<path d="M21 13v2a4 4 0 0 1-4 4H3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 默认占位 -->
|
||||
<svg v-else viewBox="0 0 24 24" fill="none" stroke="var(--icon-stroke)" stroke-width="1.5">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
/**
|
||||
* AppIcon 组件属性
|
||||
* @prop {string} name - 图标名称
|
||||
* @prop {number|string} size - 图标尺寸,默认 20
|
||||
*/
|
||||
defineProps({
|
||||
name: { type: String, default: '' },
|
||||
size: { type: [Number, String], default: 20 },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*
|
||||
* 图标容器 - 使用 CSS 变量实现主题自适应
|
||||
* 白天模式: --ink=#172033, --brand=#0f766e
|
||||
* 黑夜模式: --ink=#e2e8f0, --brand=#38bdf8
|
||||
*/
|
||||
.app-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* 主色(描边): 继承当前文本颜色 */
|
||||
--icon-stroke: var(--ink);
|
||||
/* 点缀色(高亮): 继承品牌色 */
|
||||
--icon-accent: var(--brand);
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.app-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -1,155 +0,0 @@
|
||||
<template>
|
||||
<div class="folder-tree">
|
||||
<!-- 多选模式工具栏 -->
|
||||
<div v-if="multiSelectMode" class="multi-select-toolbar">
|
||||
<span class="multi-select-toolbar__count">已选择 {{ selectedIds.size }} 项</span>
|
||||
<button type="button" class="multi-select-toolbar__btn multi-select-toolbar__btn--danger" @click="handleBatchDelete">
|
||||
<AppIcon name="batch-delete" :size="16" /> 批量删除
|
||||
</button>
|
||||
<button type="button" class="multi-select-toolbar__btn" @click="exitMultiSelect">
|
||||
<AppIcon name="close" :size="16" /> 退出多选
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 根节点列表 -->
|
||||
<div v-for="node in treeData" :key="node.id" class="tree-node">
|
||||
<TreeNode
|
||||
:node="node"
|
||||
:depth="0"
|
||||
:expanded-folder-ids="expandedFolderIds"
|
||||
:selected-ids="selectedIds"
|
||||
:multi-select-mode="multiSelectMode"
|
||||
@toggle-select="handleToggleSelect"
|
||||
@add-folder="handleAddFolder"
|
||||
@add-file="handleAddFile"
|
||||
@expand="handleExpand"
|
||||
@edit="handleEdit"
|
||||
@delete="handleDelete"
|
||||
@scrape-status="handleScrapeStatus"
|
||||
@rescrape="handleRescrape"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import TreeNode from './TreeNode.vue'
|
||||
|
||||
const props = defineProps({
|
||||
treeData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
expandedFolderIds: {
|
||||
type: Set,
|
||||
default: () => new Set(),
|
||||
},
|
||||
multiSelectMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
selectedIds: {
|
||||
type: Set,
|
||||
default: () => new Set(),
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['add-folder', 'add-file', 'expand', 'edit', 'delete', 'toggle-select', 'batch-delete', 'toggle-multi-select-exit', 'scrape-status', 'rescrape'])
|
||||
|
||||
function handleAddFolder(parentId) {
|
||||
emit('add-folder', parentId)
|
||||
}
|
||||
|
||||
function handleAddFile(parentId) {
|
||||
emit('add-file', parentId)
|
||||
}
|
||||
|
||||
function handleEdit(node) {
|
||||
emit('edit', node)
|
||||
}
|
||||
|
||||
function handleExpand(node) {
|
||||
emit('expand', node)
|
||||
}
|
||||
|
||||
function handleDelete(node) {
|
||||
emit('delete', node)
|
||||
}
|
||||
|
||||
function handleScrapeStatus(node) {
|
||||
emit('scrape-status', node)
|
||||
}
|
||||
|
||||
function handleRescrape(node) {
|
||||
emit('rescrape', node)
|
||||
}
|
||||
|
||||
function handleToggleSelect(nodeId) {
|
||||
emit('toggle-select', nodeId)
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
emit('batch-delete', props.selectedIds)
|
||||
}
|
||||
|
||||
function exitMultiSelect() {
|
||||
emit('toggle-multi-select-exit')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.folder-tree {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.tree-node {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 多选模式工具栏样式 */
|
||||
.multi-select-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 16px;
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(139, 92, 246, 0.08));
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.multi-select-toolbar__count {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #6366f1;
|
||||
}
|
||||
|
||||
.multi-select-toolbar__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 6px 12px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
color: #6366f1;
|
||||
}
|
||||
|
||||
.multi-select-toolbar__btn:hover {
|
||||
background: rgba(99, 102, 241, 0.2);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.multi-select-toolbar__btn--danger {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.multi-select-toolbar__btn--danger:hover {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
</style>
|
||||
@ -1,152 +0,0 @@
|
||||
<template>
|
||||
<article class="poster-card" :class="{ 'is-readonly': readonly }" @click="handleClick">
|
||||
<div class="poster-thumb">
|
||||
<img :src="posterImageUrl" :alt="item.title" loading="lazy" />
|
||||
<span class="score-badge">{{ displayScore }}</span>
|
||||
</div>
|
||||
|
||||
<div class="poster-body">
|
||||
<div class="poster-meta-row">
|
||||
<span class="poster-time">{{ displayFormattedDate }}</span>
|
||||
</div>
|
||||
<h3>{{ item.title }}</h3>
|
||||
<p v-if="item.originalName">{{ item.originalName }}</p>
|
||||
|
||||
<!-- 导演和主演 -->
|
||||
<div v-if="item.directors" class="poster-director">
|
||||
<AppIcon name="movie" :size="14" /> {{ item.directors }}
|
||||
</div>
|
||||
<div v-if="item.casts" class="poster-casts">
|
||||
<AppIcon name="cast" :size="14" /> {{ item.casts }}
|
||||
</div>
|
||||
|
||||
<!-- 简介按钮(点击打开弹窗) -->
|
||||
<div v-if="item.description" class="poster-description">
|
||||
<button
|
||||
type="button"
|
||||
class="description-toggle"
|
||||
@click.stop="showDescriptionDialog = true"
|
||||
>
|
||||
<AppIcon name="detail" :size="14" /> 查看详情
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tag-list">
|
||||
<span v-for="tag in displayTags" :key="tag">{{ tag }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 简介弹窗 -->
|
||||
<Teleport to="body">
|
||||
<Transition name="dialog-fade">
|
||||
<div v-if="showDescriptionDialog" class="description-overlay" @click.self="showDescriptionDialog = false">
|
||||
<div class="description-dialog">
|
||||
<div class="description-dialog__header">
|
||||
<h3>{{ item.title }} - 详情</h3>
|
||||
<button type="button" class="description-dialog__close" @click="showDescriptionDialog = false">✕</button>
|
||||
</div>
|
||||
<div class="description-dialog__body">
|
||||
<!-- 基本信息 -->
|
||||
<div v-if="item.description" class="detail-section">
|
||||
<h4><AppIcon name="description" :size="16" /> 简介</h4>
|
||||
<p class="detail-text">{{ item.description }}</p>
|
||||
</div>
|
||||
<div v-if="item.directors" class="detail-section">
|
||||
<h4><AppIcon name="movie" :size="16" /> 导演</h4>
|
||||
<p class="detail-text">{{ item.directors }}</p>
|
||||
</div>
|
||||
<div v-if="item.casts" class="detail-section">
|
||||
<h4><AppIcon name="cast" :size="16" /> 主演</h4>
|
||||
<p class="detail-text">{{ item.casts }}</p>
|
||||
</div>
|
||||
<div v-if="item.tags" class="detail-section">
|
||||
<h4><AppIcon name="tag" :size="16" /> 标签</h4>
|
||||
<div class="detail-tags">
|
||||
<span v-for="tag in displayTags" :key="tag" class="detail-tag">{{ tag }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.score || item.rating" class="detail-section">
|
||||
<h4><AppIcon name="sparkle" :size="16" /> 评分</h4>
|
||||
<p class="detail-text">{{ displayScore }}</p>
|
||||
</div>
|
||||
<div v-if="item.category" class="detail-section">
|
||||
<h4><AppIcon name="folder-open" :size="16" /> 分类</h4>
|
||||
<p class="detail-text">{{ item.category }}</p>
|
||||
</div>
|
||||
<div v-if="item.status" class="detail-section">
|
||||
<h4><AppIcon name="info" :size="16" /> 状态</h4>
|
||||
<p class="detail-text">{{ displayStatus }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import AppIcon from './AppIcon.vue'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['edit'])
|
||||
|
||||
// 简介弹窗显示状态
|
||||
const showDescriptionDialog = ref(false)
|
||||
|
||||
// 显示海报图片 URL
|
||||
const posterImageUrl = computed(() => {
|
||||
// 兼容多种字段名:poster, posterUrl, backdropUrl
|
||||
return props.item.poster || props.item.posterUrl || props.item.backdropUrl || ''
|
||||
})
|
||||
|
||||
// 显示评分
|
||||
const displayScore = computed(() => {
|
||||
const score = props.item.score ?? props.item.rating ?? 0
|
||||
return score ? `${score}` : '暂无评分'
|
||||
})
|
||||
|
||||
// 格式化日期时间,将 ISO 8601 格式转换为友好格式
|
||||
const displayFormattedDate = computed(() => {
|
||||
const raw = props.item.updatedAt || props.item.updateTime || props.item.createTime || ''
|
||||
if (!raw) return ''
|
||||
|
||||
// 去掉 T 字符,将 2026-06-26T15:55:42 转换为 2026-06-26 15:55:42
|
||||
let formatted = raw.replace('T', ' ')
|
||||
|
||||
// 如果有毫秒和时区信息(如 .000Z 或 +08:00),去掉
|
||||
formatted = formatted.replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, '')
|
||||
|
||||
return formatted
|
||||
})
|
||||
|
||||
// 显示状态(用于弹窗)
|
||||
const displayStatus = computed(() => {
|
||||
return props.item.status || '正常'
|
||||
})
|
||||
|
||||
// 显示标签(兼容字符串和数组格式)
|
||||
const displayTags = computed(() => {
|
||||
const tags = props.item.tags
|
||||
if (Array.isArray(tags)) return tags
|
||||
if (typeof tags === 'string' && tags.trim()) return tags.split(',').map(t => t.trim())
|
||||
return []
|
||||
})
|
||||
|
||||
function handleClick() {
|
||||
if (!props.readonly) {
|
||||
emit('edit', props.item)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,837 +0,0 @@
|
||||
<template>
|
||||
<div class="settings-view">
|
||||
<div class="settings-header">
|
||||
<p>配置 OpenList 后端接口,绑定您的云盘账户</p>
|
||||
</div>
|
||||
|
||||
<!-- 加载状态:等待后端返回数据 -->
|
||||
<div v-if="loading" class="loading-container">
|
||||
<div class="loading-spinner-icon"></div>
|
||||
<p class="loading-text">正在加载绑定信息...</p>
|
||||
</div>
|
||||
|
||||
<!-- 数据加载完成后显示内容 -->
|
||||
<div v-else class="settings-card">
|
||||
<!-- 已绑定信息(顶部展示) -->
|
||||
<Transition name="fade">
|
||||
<div v-if="boundInfo" class="bound-info">
|
||||
<div class="bound-info__header">
|
||||
<span class="bound-info__icon"><AppIcon name="success" :size="18" /></span>
|
||||
<span class="bound-info__text">已绑定 OpenList</span>
|
||||
</div>
|
||||
<div class="bound-info__details">
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">地址:</span>
|
||||
<span class="bound-info__value">{{ boundInfo.url }}</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">账号:</span>
|
||||
<span class="bound-info__value">{{ boundInfo.username }}</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">存储ID:</span>
|
||||
<span class="bound-info__value">{{ boundInfo.storageId || '-' }}</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">挂载路径:</span>
|
||||
<span class="bound-info__value">{{ boundInfo.mountPath || '-' }}</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">状态:</span>
|
||||
<span class="bound-info__value" :class="{ 'status-active': boundInfo.status === 'active' }">{{ boundInfo.status === 'active' ? '正常' : (boundInfo.status || '-') }}</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">Token有效:</span>
|
||||
<span class="bound-info__value">
|
||||
<AppIcon :name="boundInfo.tokenValid ? 'success' : 'fail'" :size="14" />
|
||||
{{ boundInfo.tokenValid ? '是' : '否' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="bound-info__item" v-if="boundInfo.connectMessage">
|
||||
<span class="bound-info__label">连接状态:</span>
|
||||
<span class="bound-info__value connect-message" :class="{ 'connect-ok': boundInfo.connected === true, 'connect-error': boundInfo.connected === false }">
|
||||
<AppIcon :name="boundInfo.connected ? 'success' : 'fail'" :size="14" /> {{ boundInfo.connectMessage }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">创建时间:</span>
|
||||
<span class="bound-info__value">{{ formatTime(boundInfo.createTime) }}</span>
|
||||
</div>
|
||||
<div class="bound-info__item">
|
||||
<span class="bound-info__label">更新时间:</span>
|
||||
<span class="bound-info__value">{{ formatTime(boundInfo.updateTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-unbind"
|
||||
@click="handleUnbind"
|
||||
>
|
||||
<AppIcon name="delete" :size="16" /> 解除绑定
|
||||
</button>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<h3 class="settings-card__title">
|
||||
<span class="settings-card__icon"><AppIcon name="link" :size="20" /></span>
|
||||
OpenList 绑定
|
||||
</h3>
|
||||
|
||||
<form class="settings-form" @submit.prevent="handleBind">
|
||||
<!-- OpenList 地址 -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="openlist-url">
|
||||
<span class="form-label__icon"><AppIcon name="globe" :size="16" /></span>
|
||||
<span class="form-label__text">OpenList 地址</span>
|
||||
</label>
|
||||
<input
|
||||
id="openlist-url"
|
||||
v-model="formData.url"
|
||||
type="url"
|
||||
class="form-input"
|
||||
placeholder="例如:https://olist.example.com 或 http://localhost:5575"
|
||||
required
|
||||
autocomplete="off"
|
||||
readonly
|
||||
onfocus="this.removeAttribute('readonly')"
|
||||
/>
|
||||
<span class="form-help">请填写 OpenList 服务的完整访问地址,包含协议头</span>
|
||||
</div>
|
||||
|
||||
<!-- 账号 -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="openlist-username">
|
||||
<span class="form-label__icon"><AppIcon name="user" :size="16" /></span>
|
||||
<span class="form-label__text">账号</span>
|
||||
</label>
|
||||
<input
|
||||
id="openlist-username"
|
||||
v-model="formData.username"
|
||||
type="text"
|
||||
class="form-input"
|
||||
placeholder="请输入 OpenList 用户名"
|
||||
required
|
||||
autocomplete="off"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 密码 -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="openlist-password">
|
||||
<span class="form-label__icon"><AppIcon name="save" :size="16" /></span>
|
||||
<span class="form-label__text">密码</span>
|
||||
</label>
|
||||
<div class="password-input-wrapper">
|
||||
<input
|
||||
id="openlist-password"
|
||||
v-model="formData.password"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
class="form-input"
|
||||
placeholder="请输入 OpenList 密码"
|
||||
required
|
||||
autocomplete="off"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="password-toggle"
|
||||
@click="showPassword = !showPassword"
|
||||
:title="showPassword ? '隐藏密码' : '显示密码'"
|
||||
>
|
||||
<AppIcon :name="showPassword ? 'eye-off' : 'eye'" :size="18" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 绑定按钮 -->
|
||||
<div class="form-actions">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn-bind"
|
||||
:disabled="binding"
|
||||
:class="{ 'btn-bind--loading': binding }"
|
||||
>
|
||||
<span v-if="!binding"><AppIcon name="link" :size="16" /> 绑定 OpenList</span>
|
||||
<span v-else class="loading-spinner"><AppIcon name="sync" :size="16" /> 绑定中...</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-reset"
|
||||
@click="resetForm"
|
||||
:disabled="binding"
|
||||
>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- 绑定状态提示 -->
|
||||
<Transition name="fade">
|
||||
<div v-if="bindStatus" class="bind-status" :class="`bind-status--${bindStatus.type}`">
|
||||
<span class="bind-status__icon"><AppIcon v-if="bindStatus.iconName" :name="bindStatus.iconName" :size="18" /></span>
|
||||
<span class="bind-status__text">{{ bindStatus.message }}</span>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { bindOpenList, unbindOpenList, getOpenListInfo } from '../api'
|
||||
import AppIcon from './AppIcon.vue'
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
url: '',
|
||||
username: '',
|
||||
password: '',
|
||||
})
|
||||
|
||||
// 状态控制
|
||||
const loading = ref(true)
|
||||
const binding = ref(false)
|
||||
const showPassword = ref(false)
|
||||
const bindStatus = ref(null)
|
||||
const boundInfo = ref(null)
|
||||
|
||||
/**
|
||||
* 加载已绑定的 OpenList 信息
|
||||
* 后端返回格式:
|
||||
* - 未绑定或报错:返回错误信息
|
||||
* - 已绑定:返回 { code: 200, data: { id, openlistUrl, openlistUsername, storageId, mountPath, status, tokenValid, connected, connectMessage, createTime, updateTime } }
|
||||
*/
|
||||
async function loadBoundInfo() {
|
||||
loading.value = true
|
||||
try {
|
||||
const result = await getOpenListInfo()
|
||||
// result 可能为 null(未绑定)或 { code: 200, data: {...} }
|
||||
if (result?.data) {
|
||||
const d = result.data
|
||||
boundInfo.value = {
|
||||
id: d.id,
|
||||
url: d.openlistUrl || '',
|
||||
username: d.openlistUsername || '',
|
||||
storageId: d.storageId || '',
|
||||
mountPath: d.mountPath || '',
|
||||
status: d.status || '',
|
||||
tokenValid: d.tokenValid,
|
||||
connected: d.connected,
|
||||
connectMessage: d.connectMessage || '',
|
||||
createTime: d.createTime || '',
|
||||
updateTime: d.updateTime || '',
|
||||
}
|
||||
bindStatus.value = null // 清除之前的错误信息
|
||||
} else {
|
||||
// 返回 null 或未绑定,清空已绑定信息
|
||||
boundInfo.value = null
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('加载绑定信息失败:', err)
|
||||
boundInfo.value = null
|
||||
// 显示后端返回的错误信息
|
||||
const errorMsg = err?.payload?.message || err?.message || '加载绑定信息失败'
|
||||
setBindStatus('error', errorMsg)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理绑定表单提交
|
||||
*/
|
||||
async function handleBind() {
|
||||
if (!formData.url || !formData.username || !formData.password) {
|
||||
setBindStatus('error', '请填写所有必填字段')
|
||||
return
|
||||
}
|
||||
|
||||
// 验证 URL 格式
|
||||
try {
|
||||
new URL(formData.url)
|
||||
} catch {
|
||||
setBindStatus('error', '请输入有效的 URL 地址(需包含协议头,如 https://)')
|
||||
return
|
||||
}
|
||||
|
||||
binding.value = true
|
||||
setBindStatus(null, '')
|
||||
|
||||
try {
|
||||
const result = await bindOpenList({
|
||||
url: formData.url,
|
||||
username: formData.username,
|
||||
password: formData.password,
|
||||
})
|
||||
|
||||
if (result?.code === 200) {
|
||||
setBindStatus('success', '绑定成功!')
|
||||
boundInfo.value = {
|
||||
url: formData.url,
|
||||
username: formData.username,
|
||||
boundAt: new Date().toLocaleString('zh-CN'),
|
||||
}
|
||||
// 清空密码字段
|
||||
formData.password = ''
|
||||
// 重新加载绑定信息
|
||||
await loadBoundInfo()
|
||||
} else {
|
||||
setBindStatus('error', result?.message || '绑定失败,请稍后重试')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('绑定 OpenList 失败:', err)
|
||||
const errorMsg = err?.message || err?.payload?.message || '网络错误,请检查后端连接'
|
||||
setBindStatus('error', errorMsg)
|
||||
} finally {
|
||||
binding.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理解除绑定
|
||||
*/
|
||||
async function handleUnbind() {
|
||||
if (!confirm('确定要解除 OpenList 绑定吗?')) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await unbindOpenList()
|
||||
if (result?.code === 200) {
|
||||
setBindStatus('success', '已解除绑定')
|
||||
boundInfo.value = null
|
||||
resetForm()
|
||||
setTimeout(() => {
|
||||
setBindStatus(null, '')
|
||||
}, 3000)
|
||||
} else {
|
||||
setBindStatus('error', result?.message || '解除绑定失败')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('解除绑定失败:', err)
|
||||
setBindStatus('error', err?.message || '网络错误')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
function resetForm() {
|
||||
formData.url = ''
|
||||
formData.username = ''
|
||||
formData.password = ''
|
||||
setBindStatus(null, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
*/
|
||||
function formatTime(timeStr) {
|
||||
if (!timeStr) return '-'
|
||||
try {
|
||||
const date = new Date(timeStr)
|
||||
return date.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
})
|
||||
} catch {
|
||||
return timeStr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置绑定状态提示
|
||||
*/
|
||||
function setBindStatus(type, message, autoClear = true) {
|
||||
if (!type) {
|
||||
bindStatus.value = null
|
||||
return
|
||||
}
|
||||
|
||||
const iconNames = {
|
||||
success: 'success',
|
||||
error: 'fail',
|
||||
warning: 'warning',
|
||||
info: 'info',
|
||||
}
|
||||
|
||||
bindStatus.value = {
|
||||
type,
|
||||
message,
|
||||
iconName: iconNames[type] || '',
|
||||
}
|
||||
|
||||
// 3秒后自动清除(仅用于非错误类型的临时提示)
|
||||
if (autoClear && type !== 'error') {
|
||||
setTimeout(() => {
|
||||
bindStatus.value = null
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时加载已绑定信息
|
||||
onMounted(() => {
|
||||
loadBoundInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.settings-view {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.settings-header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.settings-header h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.settings-header p {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 卡片样式 */
|
||||
.settings-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.settings-card__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin: 0 0 24px 0;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.settings-card__icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.form-label__icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 10px 14px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 8px;
|
||||
outline: none;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.15);
|
||||
}
|
||||
|
||||
.form-input::placeholder {
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.form-help {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 密码输入框 */
|
||||
.password-input-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.password-input-wrapper .form-input {
|
||||
padding-right: 44px;
|
||||
}
|
||||
|
||||
.password-toggle {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.password-toggle:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 按钮组 */
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 28px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.btn-bind {
|
||||
flex: 1;
|
||||
padding: 12px 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #409eff, #337ecc);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
.btn-bind:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, #66b1ff, #409eff);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
|
||||
.btn-bind:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.btn-bind:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-bind--loading {
|
||||
background: linear-gradient(135deg, #909399, #69696d);
|
||||
}
|
||||
|
||||
.btn-reset {
|
||||
padding: 12px 24px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.btn-reset:hover:not(:disabled) {
|
||||
color: #409eff;
|
||||
border-color: #409eff;
|
||||
background: #ecf5ff;
|
||||
}
|
||||
|
||||
.btn-reset:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* 状态提示 */
|
||||
.bind-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
margin-top: 20px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.bind-status--success {
|
||||
background: #f0f9ff;
|
||||
border: 1px solid #b3e19c;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.bind-status--error {
|
||||
background: #fef0f0;
|
||||
border: 1px solid #fbc4c4;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.bind-status__icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 已绑定信息 */
|
||||
.bound-info {
|
||||
margin-top: 20px;
|
||||
padding: 16px;
|
||||
background: #f0f9ff;
|
||||
border: 1px solid #b3e19c;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.bound-info__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #67c23a;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.bound-info__details {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.bound-info__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.bound-info__label {
|
||||
color: #999;
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
.bound-info__value {
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* 连接状态样式 */
|
||||
.connect-message {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.connect-ok {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.connect-error {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
color: #67c23a;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.btn-unbind {
|
||||
width: 100%;
|
||||
padding: 8px 16px;
|
||||
font-size: 13px;
|
||||
color: #f56c6c;
|
||||
background: #fff;
|
||||
border: 1px solid #fbc4c4;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-unbind:hover {
|
||||
background: #fef0f0;
|
||||
border-color: #f56c6c;
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
.loading-spinner {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
/* 加载容器 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 24px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.loading-spinner-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: 3px solid #e5e7eb;
|
||||
border-top-color: #3b82f6;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 过渡动画 */
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 深色模式适配 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.settings-header h2 {
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.settings-header p {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.settings-card {
|
||||
background: #2a2a2a;
|
||||
border-color: #3a3a3a;
|
||||
}
|
||||
|
||||
.settings-card__title {
|
||||
color: #e5e5e5;
|
||||
border-bottom-color: #3a3a3a;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
background: #1a1a1a;
|
||||
border-color: #3a3a3a;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
|
||||
.form-input:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
|
||||
.form-input::placeholder {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.password-toggle:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.btn-reset {
|
||||
color: #ccc;
|
||||
background: #333;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
.btn-reset:hover:not(:disabled) {
|
||||
color: #409eff;
|
||||
border-color: #409eff;
|
||||
background: #1a2a3a;
|
||||
}
|
||||
|
||||
.bound-info {
|
||||
background: #1a2a3a;
|
||||
border-color: #2a4a5a;
|
||||
}
|
||||
|
||||
.bound-info__item {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.bound-info__value {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.btn-unbind {
|
||||
color: #f56c6c;
|
||||
background: #2a1a1a;
|
||||
border-color: #4a2a2a;
|
||||
}
|
||||
|
||||
.btn-unbind:hover {
|
||||
background: #3a1a1a;
|
||||
border-color: #f56c6c;
|
||||
}
|
||||
|
||||
.loading-spinner-icon {
|
||||
border-color: #374151;
|
||||
border-top-color: #60a5fa;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: #9ca3af;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式 */
|
||||
@media (max-width: 600px) {
|
||||
.settings-view {
|
||||
padding: 16px 12px;
|
||||
}
|
||||
|
||||
.settings-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.btn-bind,
|
||||
.btn-reset {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
6798
src/style.css
0
.gitignore → vue/.gitignore
vendored
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |