format:format and fix code

This commit is contained in:
jiangrui
2025-02-24 15:22:43 +08:00
parent c784b562c4
commit f5106e782a
46 changed files with 2055 additions and 1172 deletions

View File

@@ -12,15 +12,15 @@
@close="handleClose"
>
<template v-for="menu in menuList">
<el-sub-menu :index="menu.index" v-if="menu.children">
<el-sub-menu v-if="menu.children" :key="menu.index" :index="menu.index">
<template #title>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{ menu.title }}</span>
</template>
<el-menu-item
v-for="child in menu.children"
:index="child.index"
:key="child.index"
:index="child.index"
@click="handleMenuClick(child)"
>
{{ child.title }}
@@ -28,9 +28,10 @@
</el-sub-menu>
<el-menu-item
v-else
:key="menu.router"
:index="menu.index"
@click="handleMenuClick(menu)"
:disabled="menu.disabled"
@click="handleMenuClick(menu)"
>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{ menu.title }}</span>
@@ -41,115 +42,108 @@
</template>
<script lang="ts" setup>
import { Search, Film, Setting } from "@element-plus/icons-vue";
import logo from "@/assets/images/logo.png";
import { useRouter, useRoute } from "vue-router";
import { computed } from "vue";
const router = useRouter();
const route = useRoute();
interface MenuItem {
index: string;
title: string;
icon?: any;
router?: string;
children?: MenuItem[];
disabled?: boolean;
import { Search, Film, Setting } from "@element-plus/icons-vue";
import logo from "@/assets/images/logo.png";
import { useRouter, useRoute } from "vue-router";
import { computed } from "vue";
const router = useRouter();
const route = useRoute();
interface MenuItem {
index: string;
title: string;
icon?: typeof Search | typeof Film | typeof Setting;
router?: string;
children?: MenuItem[];
disabled?: boolean;
}
const menuList: MenuItem[] = [
{
index: "2",
title: "资源搜索",
icon: Search,
router: "/",
},
{
index: "1",
title: "豆瓣榜单",
icon: Film,
children: [
{
index: "1-1",
title: "热门电影",
router: "/douban?type=movie",
},
{
index: "1-2",
title: "热门电视剧",
router: "/douban?type=tv",
},
{
index: "1-3",
title: "最新电影",
router: "/douban?type=movie&tag=最新",
},
{
index: "1-4",
title: "热门综艺",
router: "/douban?type=tv&tag=综艺",
},
],
},
{
index: "3",
title: "设置",
icon: Setting,
router: "/setting",
disabled: false,
},
];
const currentMenu = computed(() => {
return menuList
.reduce((pre: MenuItem[], cur: MenuItem) => {
if (!cur.children) {
pre.push(cur);
} else {
pre.push(...cur.children);
}
return pre;
}, [])
.find((x) => x.router === decodeURIComponent(route.fullPath));
});
const currentMenuOpen = computed(() => {
if (currentMenu.value && currentMenu.value.index.length > 1) {
return [currentMenu.value.index.split("-")[0]];
} else {
return [];
}
const menuList: MenuItem[] = [
{
index: "2",
title: "资源搜索",
icon: Search,
router: "/",
},
{
index: "1",
title: "豆瓣榜单",
icon: Film,
children: [
{
index: "1-1",
title: "热门电影",
router: "/douban?type=movie",
},
{
index: "1-2",
title: "热门电视剧",
router: "/douban?type=tv",
},
{
index: "1-3",
title: "最新电影",
router: "/douban?type=movie&tag=最新",
},
{
index: "1-4",
title: "热门综艺",
router: "/douban?type=tv&tag=综艺",
},
],
},
{
index: "3",
title: "设置",
icon: Setting,
router: "/setting",
disabled: false,
},
];
const currentMenu = computed(() => {
console.log("route", decodeURIComponent(route.fullPath));
return menuList
.reduce((pre: MenuItem[], cur: MenuItem) => {
if (!cur.children) {
pre.push(cur);
} else {
pre.push(...cur.children);
}
return pre;
}, [])
.find((x) => x.router === decodeURIComponent(route.fullPath));
});
const currentMenuOpen = computed(() => {
if (currentMenu.value && currentMenu.value.index.length > 1) {
console.log([currentMenu.value.index.split("-")[0]]);
return [currentMenu.value.index.split("-")[0]];
} else {
return [];
}
});
const handleOpen = (key: string, keyPath: string[]) => {
console.log(key, keyPath);
};
const handleClose = (key: string, keyPath: string[]) => {
console.log(key, keyPath);
};
const handleMenuClick = (menu: any) => {
console.log(menu);
if (menu.router) {
router.push(menu.router);
}
};
});
const handleOpen = (_key: string, _keyPath: string[]): void => {};
const handleClose = (_key: string, _keyPath: string[]): void => {};
const handleMenuClick = (menu: MenuItem): void => {
if (menu.router) {
router.push(menu.router);
}
};
</script>
<style lang="scss" scoped>
.el-menu-vertical {
width: 100%;
height: 100vh;
.el-menu-vertical {
width: 100%;
height: 100vh;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 0;
.logo-img {
width: 30px;
height: 30px;
margin-right: 15px;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 0;
.logo-img {
width: 30px;
height: 30px;
margin-right: 15px;
}
.logo-text {
font-size: 20px;
}
.logo-text {
font-size: 20px;
}
}
</style>

View File

@@ -11,8 +11,8 @@
node-key="cid"
:load="loadNode"
lazy
@node-click="handleNodeClick"
highlight-current
@node-click="handleNodeClick"
>
<template #default="{ node }">
<span class="folder-node">
@@ -25,107 +25,107 @@
</template>
<script setup lang="ts">
import { ref, defineProps } from "vue";
import { cloud115Api } from "@/api/cloud115";
import { quarkApi } from "@/api/quark";
import type { TreeInstance } from "element-plus";
import type { Folder } from "@/types";
import { type RequestResult } from "@/types/response";
import { ElMessage } from "element-plus";
import { ref, defineProps } from "vue";
import { cloud115Api } from "@/api/cloud115";
import { quarkApi } from "@/api/quark";
import type { TreeInstance } from "element-plus";
import type { Folder } from "@/types";
import { type RequestResult } from "@/types/response";
import { ElMessage } from "element-plus";
const props = defineProps({
cloudType: {
type: String,
required: true,
},
});
const props = defineProps({
cloudType: {
type: String,
required: true,
},
});
const treeRef = ref<TreeInstance>();
const folders = ref<Folder[]>([]);
const selectedFolder = ref<Folder | null>(null);
const emit = defineEmits<{
(e: "select", folderId: string): void;
(e: "close"): void;
}>();
const treeRef = ref<TreeInstance>();
const folders = ref<Folder[]>([]);
const selectedFolder = ref<Folder | null>(null);
const emit = defineEmits<{
(e: "select", folderId: string): void;
(e: "close"): void;
}>();
const defaultProps = {
label: "name",
children: "children",
isLeaf: "leaf",
};
const defaultProps = {
label: "name",
children: "children",
isLeaf: "leaf",
};
const cloudTypeApiMap = {
pan115: cloud115Api,
quark: quarkApi,
};
const cloudTypeApiMap = {
pan115: cloud115Api,
quark: quarkApi,
};
const loadNode = async (node: any, resolve: (list: Folder[]) => void) => {
const api = cloudTypeApiMap[props.cloudType as keyof typeof cloudTypeApiMap];
try {
let res: RequestResult<Folder[]> = { code: 0, data: [] as Folder[], message: "" };
if (node.level === 0) {
if (api.getFolderList) {
// 使用类型保护检查方法是否存在
res = await api.getFolderList();
}
} else {
if (api.getFolderList) {
// 使用类型保护检查方法是否存在
res = await api.getFolderList(node.data.cid);
}
const loadNode = async (node: any, resolve: (list: Folder[]) => void) => {
const api = cloudTypeApiMap[props.cloudType as keyof typeof cloudTypeApiMap];
try {
let res: RequestResult<Folder[]> = { code: 0, data: [] as Folder[], message: "" };
if (node.level === 0) {
if (api.getFolderList) {
// 使用类型保护检查方法是否存在
res = await api.getFolderList();
}
if (res?.code === 0) {
resolve(res.data.length ? res.data : []);
} else {
throw new Error(res.message);
} else {
if (api.getFolderList) {
// 使用类型保护检查方法是否存在
res = await api.getFolderList(node.data.cid);
}
} catch (error) {
ElMessage.error(error instanceof Error ? `${error.message}` : "获取目录失败");
// 关闭模态框
emit("close");
resolve([]);
}
};
if (res?.code === 0) {
resolve(res.data.length ? res.data : []);
} else {
throw new Error(res.message);
}
} catch (error) {
ElMessage.error(error instanceof Error ? `${error.message}` : "获取目录失败");
// 关闭模态框
emit("close");
resolve([]);
}
};
const handleNodeClick = (data: Folder) => {
selectedFolder.value = {
...data,
path: data.path ? [...data.path, data] : [data],
};
emit("select", data.cid);
const handleNodeClick = (data: Folder) => {
selectedFolder.value = {
...data,
path: data.path ? [...data.path, data] : [data],
};
emit("select", data.cid);
};
</script>
<style scoped>
.folder-select {
min-height: 300px;
max-height: 500px;
overflow-y: auto;
}
.folder-select {
min-height: 300px;
max-height: 500px;
overflow-y: auto;
}
.folder-node {
display: flex;
align-items: center;
gap: 8px;
}
.folder-node {
display: flex;
align-items: center;
gap: 8px;
}
.folder-path {
color: #999;
font-size: 12px;
margin-left: 8px;
}
.folder-path {
color: #999;
font-size: 12px;
margin-left: 8px;
}
:deep(.el-tree-node__content) {
height: 32px;
}
.folder-select-header {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 10px;
font-size: 14px;
padding: 5px 10px;
border: 1px solid #e5e6e8;
border-radius: 8px;
}
:deep(.el-tree-node__content) {
height: 32px;
}
.folder-select-header {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 10px;
font-size: 14px;
padding: 5px 10px;
border: 1px solid #e5e6e8;
border-radius: 8px;
}
</style>

View File

@@ -10,7 +10,7 @@
><ArrowDown
/></el-icon>
</div>
<div class="card-item-list" v-show="group.displayList">
<div v-show="group.displayList" class="card-item-list">
<div v-for="resource in group.list" :key="resource.messageId" class="card-item-content">
<el-card class="card-item">
<el-image
@@ -28,12 +28,12 @@
><div class="item-name">{{ resource.title }}</div></el-link
>
<div class="item-description" v-html="resource.content"></div>
<div class="tags-list" v-if="resource.tags && resource.tags.length">
<div v-if="resource.tags && resource.tags.length" class="tags-list">
<span>标签</span>
<el-tag
v-for="item in resource.tags"
class="resource_tag"
:key="item"
class="resource_tag"
@click="searchMovieforTag(item)"
>
{{ item }}
@@ -54,7 +54,7 @@
</el-card>
</div>
</div>
<div class="load-more" v-show="group.displayList">
<div v-show="group.displayList" class="load-more">
<el-button @click="handleLoadMore(group.id)"> 加载更多 </el-button>
</div>
</div>
@@ -62,128 +62,128 @@
</template>
<script setup lang="ts">
import { useResourceStore } from "@/stores/resource";
import { computed } from "vue";
import type { ResourceItem, TagColor } from "@/types";
import { useResourceStore } from "@/stores/resource";
import { computed } from "vue";
import type { ResourceItem, TagColor } from "@/types";
const store = useResourceStore();
const store = useResourceStore();
const location = computed(() => window.location);
const location = computed(() => window.location);
const emit = defineEmits(["save", "loadMore", "searchMovieforTag"]);
const emit = defineEmits(["save", "loadMore", "searchMovieforTag"]);
const handleSave = (resource: ResourceItem) => {
emit("save", resource);
};
const handleSave = (resource: ResourceItem) => {
emit("save", resource);
};
const searchMovieforTag = (tag: string) => {
emit("searchMovieforTag", tag);
};
const searchMovieforTag = (tag: string) => {
emit("searchMovieforTag", tag);
};
const handleLoadMore = (channelId: string) => {
emit("loadMore", channelId);
};
const handleLoadMore = (channelId: string) => {
emit("loadMore", channelId);
};
</script>
<style scoped>
.resource-list {
margin-bottom: 30px;
padding: 20px;
border-radius: 15px;
background-color: var(--theme-other_background);
&:last-child {
margin-bottom: 0;
}
.resource-list {
margin-bottom: 30px;
padding: 20px;
border-radius: 15px;
background-color: var(--theme-other_background);
&:last-child {
margin-bottom: 0;
}
.card-item-list {
display: grid;
grid-template-columns: repeat(auto-fill, 220px);
grid-row-gap: 30px;
justify-content: space-between;
margin-top: 20px;
/* grid-column-gap: auto-fill; */
/* flex-wrap: wrap; */
}
.card-item-list {
display: grid;
grid-template-columns: repeat(auto-fill, 220px);
grid-row-gap: 30px;
justify-content: space-between;
margin-top: 20px;
/* grid-column-gap: auto-fill; */
/* flex-wrap: wrap; */
}
.card-item-content {
/* height: 520px; */
}
.channel-logo {
height: 40px;
width: 40px;
border-radius: 50%;
overflow: hidden;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-right: 10px;
}
.load-more {
margin-top: 40px;
width: 100%;
text-align: center;
}
.card-item {
max-width: 480px;
height: 100%;
border-radius: 20px;
}
.card-item-image {
border-radius: 20px;
width: 100%;
height: 220px;
}
.item-name,
.item-description {
max-width: 100%;
margin: 15px 0;
-webkit-box-orient: vertical;
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
white-space: all;
}
.item-description {
-webkit-line-clamp: 4;
margin-top: 0;
height: 100px;
}
.item-name {
height: 58px;
font-size: 18px;
}
.tags-list {
display: flex;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
height: 58px;
overflow: hidden;
}
.resource_tag {
cursor: pointer;
margin-right: 10px;
margin-bottom: 5px;
}
.group-header {
height: 50px;
line-height: 50px;
text-align: left;
padding: 0 15px;
font-size: 20px;
display: flex;
align-items: center;
justify-content: space-between;
/* text-align: center; */
.el-link {
font-size: 22px;
}
.card-item-content {
/* height: 520px; */
}
.channel-logo {
height: 40px;
width: 40px;
border-radius: 50%;
overflow: hidden;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-right: 10px;
}
.load-more {
margin-top: 40px;
width: 100%;
text-align: center;
}
.card-item {
max-width: 480px;
height: 100%;
border-radius: 20px;
}
.card-item-image {
border-radius: 20px;
width: 100%;
height: 220px;
}
.item-name,
.item-description {
max-width: 100%;
margin: 15px 0;
-webkit-box-orient: vertical;
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
white-space: all;
}
.item-description {
-webkit-line-clamp: 4;
margin-top: 0;
height: 100px;
}
.item-name {
height: 58px;
font-size: 18px;
}
.tags-list {
display: flex;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
height: 58px;
overflow: hidden;
}
.resource_tag {
.header-icon {
cursor: pointer;
margin-right: 10px;
margin-bottom: 5px;
}
.group-header {
width: 50px;
height: 50px;
line-height: 50px;
text-align: left;
padding: 0 15px;
font-size: 20px;
display: flex;
align-items: center;
justify-content: space-between;
/* text-align: center; */
.el-link {
font-size: 22px;
}
.header-icon {
cursor: pointer;
width: 50px;
height: 50px;
}
}
.item-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.item-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>

View File

@@ -13,8 +13,8 @@
<el-table-column label="图片" width="180">
<template #default="{ row }">
<el-image
class="table-item-image"
v-if="row.image"
class="table-item-image"
:src="`/tele-images/?url=${encodeURIComponent(row.image as string)}`"
hide-on-click-modal
:preview-src-list="[
@@ -42,17 +42,17 @@
</el-table-column>
<el-table-column prop="title" label="描述">
<template #default="{ row }">
<div v-html="row.content" class="item-description"></div>
<div class="item-description" v-html="row.content"></div>
</template>
</el-table-column>
<el-table-column prop="tags" label="标签">
<template #default="{ row }">
<div class="tags-list" v-if="row.tags.length > 0">
<div v-if="row.tags.length > 0" class="tags-list">
<span>标签</span>
<el-tag
v-for="item in row.tags"
class="resource_tag"
:key="item"
class="resource_tag"
@click="searchMovieforTag(item)"
>
{{ item }}
@@ -102,96 +102,97 @@
</template>
<script setup lang="ts">
import { useResourceStore } from "@/stores/resource";
import type { Resource, TagColor } from "@/types";
import { computed } from "vue";
import { useResourceStore } from "@/stores/resource";
import type { Resource, TagColor } from "@/types";
import { computed } from "vue";
const store = useResourceStore();
const store = useResourceStore();
const emit = defineEmits(["save", "loadMore", "searchMovieforTag"]);
const emit = defineEmits(["save", "loadMore", "searchMovieforTag"]);
const location = computed(() => window.location);
const location = computed(() => window.location);
const handleSave = (resource: Resource) => {
emit("save", resource);
};
const handleSave = (resource: Resource) => {
emit("save", resource);
};
// 添加加载更多处理函数
const handleLoadMore = (channelId: string) => {
emit("loadMore", channelId);
};
// 添加加载更多处理函数
const handleLoadMore = (channelId: string) => {
emit("loadMore", channelId);
};
const searchMovieforTag = (tag: string) => {
emit("searchMovieforTag", tag);
};
const searchMovieforTag = (tag: string) => {
emit("searchMovieforTag", tag);
};
</script>
<style scoped>
.resource-list-table {
border-radius: 15px;
}
.resource-list-table {
border-radius: 15px;
}
.group-header {
display: flex;
align-items: center;
gap: 8px;
}
.channel-logo {
width: 20px;
height: 20px;
margin-right: 10px;
border-radius: 50%;
overflow: hidden;
}
.group-header {
display: flex;
align-items: center;
gap: 8px;
}
.channel-logo {
width: 20px;
height: 20px;
margin-right: 10px;
border-radius: 50%;
overflow: hidden;
}
.table-item-image {
border-radius: 20px;
width: 100%;
height: 220px;
}
.table-item-image {
border-radius: 20px;
width: 100%;
height: 220px;
}
.item-count {
color: #909399;
font-size: 0.9em;
}
.tags-list {
display: flex;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
}
.resource_tag {
cursor: pointer;
margin-right: 10px;
margin-bottom: 5px;
}
.item-description {
max-width: 100%;
margin: 15px 0;
-webkit-box-orient: vertical;
display: -webkit-box;
-webkit-line-clamp: 4;
overflow: hidden;
white-space: all;
}
.item-count {
color: #909399;
font-size: 0.9em;
}
.tags-list {
display: flex;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
}
.resource_tag {
cursor: pointer;
margin-right: 10px;
margin-bottom: 5px;
}
.item-description {
max-width: 100%;
margin: 15px 0;
-webkit-box-orient: vertical;
display: -webkit-box;
line-clamp: 4;
-webkit-line-clamp: 4;
overflow: hidden;
white-space: all;
}
:deep(.el-table__expand-column) {
.cell {
padding: 0 !important;
}
:deep(.el-table__expand-column) {
.cell {
padding: 0 !important;
}
}
:deep(.el-table__expanded-cell) {
padding: 20px !important;
}
:deep(.el-table__expanded-cell) {
padding: 20px !important;
}
:deep(.el-table__expand-icon) {
height: 23px;
line-height: 23px;
}
.load-more {
display: flex;
justify-content: center;
padding: 16px 0;
}
:deep(.el-table__expand-icon) {
height: 23px;
line-height: 23px;
}
.load-more {
display: flex;
justify-content: center;
padding: 16px 0;
}
</style>