数据结构优化

This commit is contained in:
李琦
2026-01-20 08:58:44 +08:00
parent 34fe612aab
commit e7839795fb
10 changed files with 190 additions and 180 deletions

View File

@@ -24,7 +24,7 @@
<Footer v-if="!isAdminOrLogin" />
<!-- Snippet Modal (Hide on Admin & Login) -->
<SnippetModal v-if="!isAdminOrLogin" />
<!-- SnippetModal is managed by Snippets.vue page, not here -->
<!-- Inquiry Modal (Hide on Admin & Login) -->
<InquiryModal v-if="!isAdminOrLogin" />

View File

@@ -26,7 +26,7 @@
<div class="flex items-center gap-4">
<CustomSelect
v-model="selectedLanguage"
:options="languageOptions.filter(opt => !opt.disabled)"
:options="languageOptions"
@update:modelValue="handleLanguageChange"
placeholder="选择语言"
style="width: 180px; font-family: monospace; font-size: 0.75rem;"
@@ -449,13 +449,15 @@ const getConsoleTemplate = (jsCode: string) => {
`
}
let runTimer: ReturnType<typeof setTimeout> | null = null
const handleCodeChange = () => {
highlightCode()
// 对于非 Web 语言(如 Python/React不自动运行等待用户点击 Run
if (['html', 'css', 'javascript'].includes(selectedLanguage.value)) {
// Debounce auto-run for lightweight languages
clearTimeout(window.runTimer)
window.runTimer = setTimeout(() => runCode(), 1000)
if (runTimer) clearTimeout(runTimer)
runTimer = setTimeout(() => runCode(), 1000)
}
}

View File

@@ -1,12 +1,14 @@
<template>
<footer class="py-8 text-center border-t border-white/5 relative z-10">
<div class="flex justify-center items-center gap-4 mb-4">
<a @click="window.open('admin.html', '_blank')" class="text-xs text-art-muted/30 hover:text-art-accent cursor-pointer">管理入口</a>
<a @click="openAdmin" class="text-xs text-art-muted/30 hover:text-art-accent cursor-pointer">管理入口</a>
</div>
<p class="text-art-muted text-xs font-mono tracking-widest opacity-50">&copy; 2024 年糕崽崽. 保留所有权利.</p>
</footer>
</template>
<script setup lang="ts">
// Footer组件的逻辑可以在这里添加
const openAdmin = () => {
window.open('admin.html', '_blank')
}
</script>

View File

@@ -6,7 +6,7 @@
<a @click="navigate('/works')" class="font-serif text-3xl italic text-white hover:text-art-accent cursor-pointer">作品</a>
<a @click="navigate('/snippets')" class="font-serif text-3xl italic text-white hover:text-art-accent cursor-pointer">代码</a>
<a @click="navigate('/about')" class="font-serif text-3xl italic text-white hover:text-art-accent cursor-pointer">关于</a>
<a @click="window.open('admin.html', '_blank')" class="font-mono text-sm text-art-muted mt-8">管理入口</a>
<a @click="openAdmin" class="font-mono text-sm text-art-muted mt-8">管理入口</a>
</div>
</template>
@@ -30,6 +30,10 @@ const navigate = (target: string) => {
toggleMobileMenu()
}
const openAdmin = () => {
window.open('admin.html', '_blank')
}
const refreshIcons = () => {
if ((window as any).lucide) {
(window as any).lucide.createIcons()

View File

@@ -75,7 +75,7 @@
</template>
<script setup lang="ts">
import { ref, watch, onMounted, computed, nextTick } from 'vue'
import { ref, watch, computed, nextTick } from 'vue'
import hljs from 'highlight.js'
const props = defineProps<{
@@ -90,7 +90,6 @@ const emit = defineEmits(['close'])
const isAnimating = ref(true)
const mouseX = ref(0)
const mouseY = ref(0)
const containerRect = ref<DOMRect | null>(null)
const codeBlock = ref<HTMLElement | null>(null)
const languageClass = computed(() => {

View File

@@ -178,7 +178,7 @@ const closeDropdown = (e: MouseEvent) => {
}
const handleChangePassword = () => {
toast.showToast('功能开发中...', 'info')
toast.showToast('功能开发中...', 'success')
isUserDropdownOpen.value = false
}

View File

@@ -17,7 +17,7 @@ export const useInteractions = () => {
const initTiltEffect = () => {
const tiltCards = document.querySelectorAll('.tilt-card')
tiltCards.forEach(card => {
card.addEventListener('mousemove', (e) => {
card.addEventListener('mousemove', (e: MouseEvent) => {
const cardRect = card.getBoundingClientRect()
const x = e.clientX - cardRect.left
const y = e.clientY - cardRect.top
@@ -25,8 +25,9 @@ export const useInteractions = () => {
const xPercent = (x / cardRect.width) * 100
const yPercent = (y / cardRect.height) * 100
card.style.setProperty('--mouse-x', `${xPercent}%`)
card.style.setProperty('--mouse-y', `${yPercent}%`)
const htmlCard = card as HTMLElement
htmlCard.style.setProperty('--mouse-x', `${xPercent}%`)
htmlCard.style.setProperty('--mouse-y', `${yPercent}%`)
})
})
}

View File

@@ -17,16 +17,17 @@
/>
</div>
<!-- 描述字段 -->
<!-- Slug 字段 -->
<div class="form-group">
<label for="description" class="form-label">描述</label>
<textarea
id="description"
v-model="tagForm.description"
<label for="slug" class="form-label">别名 (Slug)</label>
<input
type="text"
id="slug"
v-model="tagForm.slug"
class="form-input"
placeholder="请输入标签描述"
rows="3"
></textarea>
placeholder="请输入标签别名用于URLvue-3"
required
/>
</div>
<!-- 表单按钮 -->
@@ -59,7 +60,7 @@ const isEdit = computed(() => !!route.params.id)
// 标签表单数据
const tagForm = ref({
name: '',
description: ''
slug: ''
})
// 获取标签详情
@@ -71,7 +72,7 @@ const fetchTagDetail = async () => {
const tag = await adminGetTag(tagId)
tagForm.value = {
name: tag.name,
description: tag.description
slug: tag.slug
}
} catch (error: any) {
console.error('Failed to fetch tag detail:', error)

View File

@@ -6,4 +6,5 @@ declare interface Window {
closeSnippet?: () => void
openInquiry?: () => void
closeInquiry?: () => void
open?: (url?: string, target?: string, features?: string) => Window | null
}

View File

@@ -1,176 +1,176 @@
-- 修改oss_configs表结构将access_key和secret_key改为VARCHAR(255)并设置默认值
ALTER TABLE `oss_configs`
MODIFY COLUMN `access_key` VARCHAR(255) NOT NULL DEFAULT '',
MODIFY COLUMN `secret_key` VARCHAR(255) NOT NULL DEFAULT '';
-- 修改oss_configs表结构将access_key和secret_key改为VARCHAR(255)并设置默认值
ALTER TABLE `oss_configs`
MODIFY COLUMN `access_key` VARCHAR(255) NOT NULL DEFAULT '',
MODIFY COLUMN `secret_key` VARCHAR(255) NOT NULL DEFAULT '';
-- 添加阿里云OSS专用字段使用存储过程安全添加如果已存在则跳过
SET @dbname = DATABASE();
SET @tablename = 'oss_configs';
SET @preparedStatement = (SELECT IF(
-- 添加阿里云OSS专用字段使用存储过程安全添加如果已存在则跳过
SET @dbname = DATABASE();
SET @tablename = 'oss_configs';
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'oss_access_key_id') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `oss_access_key_id` VARCHAR(255) NOT NULL DEFAULT '' AFTER `secret_key`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'oss_access_key_secret') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `oss_access_key_secret` VARCHAR(255) NOT NULL DEFAULT '' AFTER `oss_access_key_id`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'oss_endpoint') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `oss_endpoint` VARCHAR(255) NOT NULL DEFAULT '' AFTER `oss_access_key_secret`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'oss_bucket') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `oss_bucket` VARCHAR(255) NOT NULL DEFAULT '' AFTER `oss_endpoint`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'oss_domain') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `oss_domain` VARCHAR(255) NOT NULL DEFAULT '' AFTER `oss_bucket`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
-- 添加腾讯云COS专用字段
SET @preparedStatement = (SELECT IF(
-- 添加腾讯云COS专用字段
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qcloud_secret_id') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qcloud_secret_id` VARCHAR(255) NOT NULL DEFAULT '' AFTER `oss_domain`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qcloud_secret_key') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qcloud_secret_key` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qcloud_secret_id`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qcloud_region') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qcloud_region` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qcloud_secret_key`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qcloud_bucket') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qcloud_bucket` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qcloud_region`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qcloud_domain') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qcloud_domain` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qcloud_bucket`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
-- 添加七牛云专用字段
SET @preparedStatement = (SELECT IF(
-- 添加七牛云专用字段
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qiniu_access_key') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qiniu_access_key` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qcloud_domain`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qiniu_secret_key') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qiniu_secret_key` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qiniu_access_key`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qiniu_bucket') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qiniu_bucket` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qiniu_secret_key`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qiniu_region') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qiniu_region` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qiniu_bucket`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
SET @preparedStatement = (SELECT IF(
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'qiniu_domain') > 0,
'SELECT 1',
'ALTER TABLE `oss_configs` ADD COLUMN `qiniu_domain` VARCHAR(255) NOT NULL DEFAULT '' AFTER `qiniu_region`'
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
));
PREPARE alterIfNotExists FROM @preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
-- 插入默认OSS配置如果不存在
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '本地存储', 'local', '', '', '', '', '', 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '本地存储' AND `storage_type` = 'local' AND `deleted_at` = 0);
-- 插入默认OSS配置如果不存在
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '本地存储', 'local', '', '', '', '', '', 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '本地存储' AND `storage_type` = 'local' AND `deleted_at` = 0);
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '阿里云OSS', 'aliyun', '', '', '', '', '', 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '阿里云OSS' AND `storage_type` = 'aliyun' AND `deleted_at` = 0);
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '阿里云OSS', 'aliyun', '', '', '', '', '', 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '阿里云OSS' AND `storage_type` = 'aliyun' AND `deleted_at` = 0);
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '腾讯云COS', 'qcloud', '', '', '', '', '', 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '腾讯云COS' AND `storage_type` = 'qcloud' AND `deleted_at` = 0);
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '腾讯云COS', 'qcloud', '', '', '', '', '', 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '腾讯云COS' AND `storage_type` = 'qcloud' AND `deleted_at` = 0);
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '七牛云', 'qiniu', '', '', '', '', '', 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '七牛云' AND `storage_type` = 'qiniu' AND `deleted_at` = 0);
INSERT INTO `oss_configs` (`name`, `storage_type`, `access_key`, `secret_key`, `bucket`, `region`, `domain`, `is_active`, `deleted_at`, `created_at`, `updated_at`)
SELECT '七牛云', 'qiniu', '', '', '', '', '', 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
WHERE NOT EXISTS (SELECT 1 FROM `oss_configs` WHERE `name` = '七牛云' AND `storage_type` = 'qiniu' AND `deleted_at` = 0);