first commit
This commit is contained in:
51
src/App.vue
Normal file
51
src/App.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="min-h-screen flex flex-col">
|
||||
<header class="bg-white shadow-sm dark:bg-gray-800">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<h1 class="text-2xl font-bold text-primary-600">{{ siteName }}</h1>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<button @click="toggleDarkMode" class="p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">
|
||||
<svg v-if="isDark" class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
<svg v-else class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="flex-grow">
|
||||
<router-view />
|
||||
</main>
|
||||
|
||||
<footer class="bg-white dark:bg-gray-800">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||
<p class="text-center text-gray-500 dark:text-gray-400">
|
||||
© {{ new Date().getFullYear() }} {{ siteName }}. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
|
||||
const siteName = '绝绝子网盘搜索'
|
||||
const isDark = useDark()
|
||||
const toggleDarkMode = useToggle(isDark)
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化主题
|
||||
if (localStorage.getItem('darkMode') === 'true') {
|
||||
document.documentElement.classList.add('dark')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
35
src/assets/main.css
Normal file
35
src/assets/main.css
Normal file
@@ -0,0 +1,35 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
html {
|
||||
@apply antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-gray-50 text-gray-900 dark:bg-gray-900 dark:text-gray-100;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply px-4 py-2 rounded-md font-medium transition-colors duration-200;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@apply bg-primary-600 text-white hover:bg-primary-700;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600;
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent dark:bg-gray-800 dark:border-gray-700;
|
||||
}
|
||||
|
||||
.card {
|
||||
@apply bg-white rounded-lg shadow-md p-6 dark:bg-gray-800;
|
||||
}
|
||||
}
|
||||
13
src/config/index.js
Normal file
13
src/config/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const config = {
|
||||
// 网站配置
|
||||
siteName: '绝绝子网盘搜索',
|
||||
siteDescription: '专注于收录全网云盘资源,支持七大网盘搜索',
|
||||
siteKeywords: '网盘搜索,百度网盘搜索,阿里云盘搜索,夸克网盘搜索,资源搜索',
|
||||
|
||||
// API配置
|
||||
api: {
|
||||
search: '/opensearch.php',
|
||||
data: '/opendata.php',
|
||||
dataEntry: '/opendataentry.php'
|
||||
}
|
||||
}
|
||||
12
src/main.js
Normal file
12
src/main.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import './assets/main.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
41
src/router/index.js
Normal file
41
src/router/index.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Home from '../views/Home.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Home',
|
||||
component: Home,
|
||||
meta: {
|
||||
title: '绝绝子网盘搜索 - 专注网盘资源搜索'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'About',
|
||||
component: () => import('../views/About.vue'),
|
||||
meta: {
|
||||
title: '关于我们 - 绝绝子网盘搜索'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
} else {
|
||||
return { top: 0 }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 设置页面标题
|
||||
router.beforeEach((to, from, next) => {
|
||||
document.title = to.meta.title || '绝绝子网盘搜索'
|
||||
next()
|
||||
})
|
||||
|
||||
export default router
|
||||
44
src/utils/axios.js
Normal file
44
src/utils/axios.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import axios from 'axios'
|
||||
import { config } from '../config'
|
||||
|
||||
// 创建 axios 实例
|
||||
const instance = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
instance.interceptors.request.use(
|
||||
config => {
|
||||
// 添加时间戳防止缓存
|
||||
if (config.method === 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
_t: new Date().getTime()
|
||||
}
|
||||
}
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
console.error('Request error:', error)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
instance.interceptors.response.use(
|
||||
response => {
|
||||
return response
|
||||
},
|
||||
error => {
|
||||
console.error('Response error:', error)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default instance
|
||||
55
src/views/About.vue
Normal file
55
src/views/About.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="card">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-6">关于我们</h1>
|
||||
|
||||
<div class="prose dark:prose-invert max-w-none">
|
||||
<p class="mb-4">
|
||||
绝绝子网盘搜索是一个专注于网盘资源搜索的平台,致力于为用户提供快速、准确的网盘资源搜索服务。
|
||||
</p>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-8 mb-4">支持网盘</h2>
|
||||
<ul class="list-disc pl-6 mb-6">
|
||||
<li>阿里云盘</li>
|
||||
<li>夸克网盘</li>
|
||||
<li>百度网盘</li>
|
||||
<li>迅雷网盘</li>
|
||||
<li>天翼云盘</li>
|
||||
<li>蓝奏云</li>
|
||||
<li>其他主流网盘</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-8 mb-4">使用说明</h2>
|
||||
<ol class="list-decimal pl-6 mb-6">
|
||||
<li>在搜索框输入关键词</li>
|
||||
<li>点击搜索按钮或按回车键</li>
|
||||
<li>查看搜索结果</li>
|
||||
<li>点击"查看资源"按钮访问网盘链接</li>
|
||||
</ol>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-8 mb-4">注意事项</h2>
|
||||
<ul class="list-disc pl-6 mb-6">
|
||||
<li>请遵守相关法律法规,合理使用搜索服务</li>
|
||||
<li>部分资源可能需要提取码,请仔细查看</li>
|
||||
<li>资源链接有效性由资源提供者负责</li>
|
||||
<li>如发现违规内容,请联系我们处理</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-8 mb-4">联系我们</h2>
|
||||
<p class="mb-4">
|
||||
如果您有任何问题或建议,欢迎通过以下方式联系我们:
|
||||
</p>
|
||||
<ul class="list-disc pl-6">
|
||||
<li>邮箱:support@juejuezi.cc</li>
|
||||
<li>反馈:通过网站底部的反馈按钮</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 页面逻辑
|
||||
</script>
|
||||
228
src/views/Home.vue
Normal file
228
src/views/Home.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<!-- Logo 和标题区域 -->
|
||||
<div class="text-center mb-12">
|
||||
<div class="flex items-center justify-center mb-6">
|
||||
<svg class="w-12 h-12 text-primary-600 mr-4" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 6.5C4 5.67157 4.67157 5 5.5 5H18.5C19.3284 5 20 5.67157 20 6.5V17.5C20 18.3284 19.3284 19 18.5 19H5.5C4.67157 19 4 18.3284 4 17.5V6.5Z" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M8 12H16M8 15H13" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M8 9H16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<h1 class="text-4xl md:text-5xl font-bold bg-gradient-to-r from-primary-600 to-primary-400 bg-clip-text text-transparent">
|
||||
{{ config.siteName }}
|
||||
</h1>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-2">
|
||||
{{ config.siteDescription }}
|
||||
</p>
|
||||
<p class="text-sm text-gray-500">
|
||||
已收录 10000000+ 网盘资源免费分享
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 搜索框区域 -->
|
||||
<div class="card mb-8 border-2 border-primary-100">
|
||||
<div class="relative">
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
class="input pr-24 text-lg h-14"
|
||||
placeholder="输入关键词搜索资源..."
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<button
|
||||
@click="handleSearch"
|
||||
class="absolute right-2 top-1/2 transform -translate-y-1/2 btn btn-primary h-10 flex items-center"
|
||||
:disabled="loading"
|
||||
>
|
||||
<svg v-if="loading" class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
<span>{{ loading ? '搜索中' : '搜索' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 快捷分类标签 -->
|
||||
<div class="mb-8">
|
||||
<div class="flex flex-wrap gap-2 justify-center">
|
||||
<button
|
||||
v-for="tag in quickTags"
|
||||
:key="tag"
|
||||
@click="quickSearch(tag)"
|
||||
class="px-3 py-1 rounded-full text-sm bg-gray-100 hover:bg-primary-100 text-gray-600 hover:text-primary-600 transition-colors duration-200"
|
||||
>
|
||||
{{ tag }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 错误提示 -->
|
||||
<div v-if="error" class="card mb-8 bg-red-50">
|
||||
<div class="text-red-600">
|
||||
{{ error }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 加载动画 -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="inline-flex items-center px-4 py-2 font-semibold leading-6 text-primary-600 transition ease-in-out duration-150 cursor-not-allowed">
|
||||
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
正在搜索中...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 搜索结果 -->
|
||||
<div v-else-if="searchResults.length > 0" class="space-y-4">
|
||||
<div
|
||||
v-for="(result, index) in searchResults"
|
||||
:key="index"
|
||||
class="card hover:shadow-lg transition-shadow duration-200 border border-gray-100"
|
||||
>
|
||||
<div class="cursor-pointer" @click="toggleExpand(index)">
|
||||
<h3 class="text-base md:text-lg font-semibold text-gray-900"
|
||||
:class="{ 'line-clamp-2': !expandedItems[index] }">
|
||||
{{ removeEmoji(result.ScrName) }}
|
||||
</h3>
|
||||
<div v-if="!expandedItems[index] && isLongText(removeEmoji(result.ScrName))"
|
||||
class="text-primary-600 text-sm mt-1 hover:text-primary-700">
|
||||
点击展开全文
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-2 md:gap-4 text-sm text-gray-500 my-4">
|
||||
<span class="flex items-center">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
{{ formatTime(result.addtime) }}
|
||||
</span>
|
||||
<span class="flex items-center">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
|
||||
</svg>
|
||||
{{ result.Scrurlname }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-3 md:gap-4">
|
||||
<a
|
||||
:href="result.Scrurl"
|
||||
target="_blank"
|
||||
class="btn btn-primary flex items-center text-sm md:text-base"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
查看资源
|
||||
</a>
|
||||
<span v-if="result.Scrpass" class="flex items-center text-sm text-gray-500">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
|
||||
</svg>
|
||||
提取码: {{ result.Scrpass }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 无搜索结果 -->
|
||||
<div v-else-if="searched" class="text-center py-12">
|
||||
<div class="inline-block">
|
||||
<svg class="w-16 h-16 text-gray-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<p class="text-gray-500 text-lg">未找到相关资源,换个关键词试试?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import http from '../utils/axios'
|
||||
import { config } from '../config'
|
||||
|
||||
const searchQuery = ref('')
|
||||
const searchResults = ref([])
|
||||
const loading = ref(false)
|
||||
const searched = ref(false)
|
||||
const error = ref('')
|
||||
const expandedItems = reactive({})
|
||||
|
||||
// 快捷搜索标签
|
||||
const quickTags = [
|
||||
'电影', '音乐', '小说', '动漫',
|
||||
'软件', '教程', '设计', '游戏'
|
||||
]
|
||||
|
||||
// 移除 emoji 标签
|
||||
const removeEmoji = (text) => {
|
||||
if (!text) return ''
|
||||
// 使用正则表达式移除所有 [@emoji=xxx] 格式的内容
|
||||
return text.replace(/\[@emoji=[^\]]*\]/g, '')
|
||||
}
|
||||
|
||||
const handleSearch = async () => {
|
||||
if (!searchQuery.value.trim()) return
|
||||
|
||||
loading.value = true
|
||||
searched.value = true
|
||||
searchResults.value = []
|
||||
error.value = ''
|
||||
// 重置展开状态
|
||||
Object.keys(expandedItems).forEach(key => delete expandedItems[key])
|
||||
|
||||
try {
|
||||
const response = await http.get(config.api.search, {
|
||||
params: {
|
||||
wd: searchQuery.value
|
||||
}
|
||||
})
|
||||
|
||||
if (response.data.code === 0) {
|
||||
searchResults.value = response.data.Data || []
|
||||
} else {
|
||||
error.value = response.data.msg || '搜索失败,请稍后重试'
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('搜索出错:', err)
|
||||
error.value = err.response?.data?.message || '搜索出错,请稍后重试'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const quickSearch = (tag) => {
|
||||
searchQuery.value = tag
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
const formatTime = (timestamp) => {
|
||||
const date = new Date(parseInt(timestamp))
|
||||
return date.toLocaleString()
|
||||
}
|
||||
|
||||
const toggleExpand = (index) => {
|
||||
expandedItems[index] = !expandedItems[index]
|
||||
}
|
||||
|
||||
const isLongText = (text) => {
|
||||
return text && text.length > 50
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.line-clamp-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user